diff --git a/core/src/dependencies.rs b/core/src/dependencies.rs index 73627075b..ce7991193 100644 --- a/core/src/dependencies.rs +++ b/core/src/dependencies.rs @@ -45,7 +45,7 @@ impl TS for DepInfo { "DepInfo".into() } fn inline() -> String { - "{ description: string | null, optional: boolean } & MetadataSrc".into() + "{ description: LocaleString | null, optional: boolean } & MetadataSrc".into() } fn inline_flattened() -> String { Self::inline() @@ -54,7 +54,8 @@ impl TS for DepInfo { where Self: 'static, { - v.visit::() + v.visit::(); + v.visit::(); } fn output_path() -> Option<&'static std::path::Path> { Some(Path::new("DepInfo.ts")) diff --git a/core/src/error.rs b/core/src/error.rs index 0624be4dc..55b4494b1 100644 --- a/core/src/error.rs +++ b/core/src/error.rs @@ -3,6 +3,7 @@ use std::fmt::{Debug, Display}; use axum::http::StatusCode; use axum::http::uri::InvalidUri; use color_eyre::eyre::eyre; +use imbl_value::InternedString; use num_enum::TryFromPrimitive; use patch_db::Value; use rpc_toolkit::reqwest; @@ -204,17 +205,12 @@ pub struct Error { impl Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}: {:#}", &self.kind.as_str(), self.source) + write!(f, "{}: {}", &self.kind.as_str(), self.display_src()) } } impl Debug for Error { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "{}: {:?}", - &self.kind.as_str(), - self.debug.as_ref().unwrap_or(&self.source) - ) + write!(f, "{}: {}", &self.kind.as_str(), self.display_dbg()) } } impl Error { @@ -235,8 +231,13 @@ impl Error { } pub fn clone_output(&self) -> Self { Error { - source: eyre!("{}", self.source), - debug: self.debug.as_ref().map(|e| eyre!("{e}")), + source: eyre!("{:#}", self.source), + debug: Some( + self.debug + .as_ref() + .map(|e| eyre!("{e}")) + .unwrap_or_else(|| eyre!("{:?}", self.source)), + ), kind: self.kind, info: self.info.clone(), task: None, @@ -257,6 +258,30 @@ impl Error { self.task.take(); self } + + pub fn display_src(&self) -> impl Display { + struct D<'a>(&'a Error); + impl<'a> Display for D<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:#}", self.0.source) + } + } + D(self) + } + + pub fn display_dbg(&self) -> impl Display { + struct D<'a>(&'a Error); + impl<'a> Display for D<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(debug) = &self.0.debug { + write!(f, "{}", debug) + } else { + write!(f, "{:?}", self.0.source) + } + } + } + D(self) + } } impl axum::response::IntoResponse for Error { fn into_response(self) -> axum::response::Response { @@ -433,9 +458,11 @@ impl Debug for ErrorData { impl std::error::Error for ErrorData {} impl From for ErrorData { fn from(value: Error) -> Self { + let details = value.display_src().to_string(); + let debug = value.display_dbg().to_string(); Self { - details: value.to_string(), - debug: format!("{:?}", value), + details, + debug, info: value.info, } } @@ -623,13 +650,10 @@ impl ResultExt for Result { fn with_ctx (ErrorKind, D), D: Display>(self, f: F) -> Result { self.map_err(|e| { let (kind, ctx) = f(&e); + let ctx = InternedString::from_display(&ctx); let source = e.source; - let with_ctx = format!("{ctx}: {source}"); - let source = source.wrap_err(with_ctx); - let debug = e.debug.map(|e| { - let with_ctx = format!("{ctx}: {e}"); - e.wrap_err(with_ctx) - }); + let source = source.wrap_err(ctx.clone()); + let debug = e.debug.map(|e| e.wrap_err(ctx)); Error { kind, source, diff --git a/core/src/s9pk/v2/compat.rs b/core/src/s9pk/v2/compat.rs index 592e213ca..486142031 100644 --- a/core/src/s9pk/v2/compat.rs +++ b/core/src/s9pk/v2/compat.rs @@ -206,9 +206,7 @@ impl TryFrom for Manifest { license: value.license.into(), package_repo: value.wrapper_repo, upstream_repo: value.upstream_repo, - marketing_url: Some( - value.marketing_site.unwrap_or_else(|| default_url.clone()), - ), + marketing_url: Some(value.marketing_site.unwrap_or_else(|| default_url.clone())), donation_url: value.donation_url, docs_urls: Vec::new(), description: value.description, diff --git a/core/src/service/mod.rs b/core/src/service/mod.rs index a2a8b58e0..03c910bca 100644 --- a/core/src/service/mod.rs +++ b/core/src/service/mod.rs @@ -16,7 +16,7 @@ use futures::{FutureExt, SinkExt, StreamExt, TryStreamExt}; use imbl_value::{InternedString, json}; use itertools::Itertools; use nix::sys::signal::Signal; -use persistent_container::{PersistentContainer, Subcontainer}; +use persistent_container::PersistentContainer; use rpc_toolkit::HandlerArgs; use rpc_toolkit::yajrc::RpcError; use serde::{Deserialize, Serialize}; @@ -1195,10 +1195,12 @@ pub async fn cli_attach( { Ok(a) => a, Err(e) => { + if e.kind != ErrorKind::InvalidRequest { + return Err(e); + } let prompt = e.to_string(); let options: Vec = from_value(e.info)?; let choice = choose(&prompt, &options).await?; - println!(); params["subcontainer"] = to_value(&choice.id)?; context .call_remote::(&method, params.clone()) @@ -1208,6 +1210,7 @@ pub async fn cli_attach( )?; let mut ws = context.ws_continuation(guid).await?; + print!("\r"); let (kill, thread_kill) = tokio::sync::oneshot::channel(); let (thread_send, recv) = tokio::sync::mpsc::channel(4 * CAP_1_KiB); let stdin_thread: NonDetachingJoinHandle<()> = tokio::task::spawn_blocking(move || { @@ -1236,18 +1239,6 @@ pub async fn cli_attach( let mut stderr = Some(stderr); loop { futures::select_biased! { - // signal = tokio:: => { - // let exit = exit?; - // if current_out != "exit" { - // ws.send(Message::Text("exit".into())) - // .await - // .with_kind(ErrorKind::Network)?; - // current_out = "exit"; - // } - // ws.send(Message::Binary( - // i32::to_be_bytes(exit.into_raw()).to_vec() - // )).await.with_kind(ErrorKind::Network)?; - // } input = stdin.as_mut().map_or( futures::future::Either::Left(futures::future::pending()), |s| futures::future::Either::Right(s.recv()) diff --git a/sdk/base/lib/osBindings/CheckDnsParams.ts b/sdk/base/lib/osBindings/CheckDnsParams.ts new file mode 100644 index 000000000..992d0706a --- /dev/null +++ b/sdk/base/lib/osBindings/CheckDnsParams.ts @@ -0,0 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { GatewayId } from './GatewayId' + +export type CheckDnsParams = { gateway: GatewayId } diff --git a/sdk/base/lib/osBindings/DepInfo.ts b/sdk/base/lib/osBindings/DepInfo.ts index cd8e482cc..07b0908e3 100644 --- a/sdk/base/lib/osBindings/DepInfo.ts +++ b/sdk/base/lib/osBindings/DepInfo.ts @@ -1,7 +1,8 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { LocaleString } from './LocaleString' import type { MetadataSrc } from './MetadataSrc' export type DepInfo = { - description: string | null + description: LocaleString | null optional: boolean } & MetadataSrc diff --git a/sdk/base/lib/osBindings/Manifest.ts b/sdk/base/lib/osBindings/Manifest.ts index 98af5c018..2f267f250 100644 --- a/sdk/base/lib/osBindings/Manifest.ts +++ b/sdk/base/lib/osBindings/Manifest.ts @@ -13,27 +13,26 @@ import type { VolumeId } from './VolumeId' export type Manifest = { id: PackageId - title: string version: Version satisfies: Array - releaseNotes: LocaleString canMigrateTo: string canMigrateFrom: string - license: string - wrapperRepo: string - upstreamRepo: string - supportSite: string - marketingSite: string - donationUrl: string | null - docsUrl: string | null - description: Description images: { [key: ImageId]: ImageConfig } volumes: Array - alerts: Alerts dependencies: Dependencies hardwareRequirements: HardwareRequirements - hardwareAcceleration: boolean + title: string + description: Description + releaseNotes: LocaleString gitHash: GitHash | null + license: string + packageRepo: string + upstreamRepo: string + marketingUrl: string + donationUrl: string | null + docsUrls: string[] + alerts: Alerts osVersion: string sdkVersion: string | null + hardwareAcceleration: boolean } diff --git a/sdk/base/lib/osBindings/PackageVersionInfo.ts b/sdk/base/lib/osBindings/PackageVersionInfo.ts index e3a7c28b9..60f5de9fd 100644 --- a/sdk/base/lib/osBindings/PackageVersionInfo.ts +++ b/sdk/base/lib/osBindings/PackageVersionInfo.ts @@ -11,22 +11,21 @@ import type { PackageId } from './PackageId' import type { RegistryAsset } from './RegistryAsset' export type PackageVersionInfo = { + icon: DataUrl + dependencyMetadata: { [key: PackageId]: DependencyMetadata } sourceVersion: string | null s9pks: Array<[HardwareRequirements, RegistryAsset]> title: string - icon: DataUrl description: Description releaseNotes: LocaleString gitHash: GitHash | null license: string - wrapperRepo: string + packageRepo: string upstreamRepo: string - supportSite: string - marketingSite: string + marketingUrl: string donationUrl: string | null - docsUrl: string | null + docsUrls: string[] alerts: Alerts - dependencyMetadata: { [key: PackageId]: DependencyMetadata } osVersion: string sdkVersion: string | null hardwareAcceleration: boolean diff --git a/sdk/base/lib/osBindings/index.ts b/sdk/base/lib/osBindings/index.ts index 4da98b340..c1ab84df2 100644 --- a/sdk/base/lib/osBindings/index.ts +++ b/sdk/base/lib/osBindings/index.ts @@ -56,6 +56,7 @@ export { Category } from './Category' export { Celsius } from './Celsius' export { CheckDependenciesParam } from './CheckDependenciesParam' export { CheckDependenciesResult } from './CheckDependenciesResult' +export { CheckDnsParams } from './CheckDnsParams' export { CheckPortParams } from './CheckPortParams' export { CheckPortRes } from './CheckPortRes' export { CifsAddParams } from './CifsAddParams' diff --git a/sdk/base/lib/types/ManifestTypes.ts b/sdk/base/lib/types/ManifestTypes.ts index 3173ef9c2..33b5bd7e7 100644 --- a/sdk/base/lib/types/ManifestTypes.ts +++ b/sdk/base/lib/types/ManifestTypes.ts @@ -21,22 +21,17 @@ export type SDKManifest = { * URL of the StartOS package repository * @example `https://github.com/Start9Labs/nextcloud-startos` */ - readonly wrapperRepo: string + readonly packageRepo: string /** * URL of the upstream service repository * @example `https://github.com/nextcloud/docker` */ readonly upstreamRepo: string - /** - * URL where users can get help using the upstream service - * @example `https://github.com/nextcloud/docker/issues` - */ - readonly supportSite: string /** * URL where users can learn more about the upstream service * @example `https://nextcloud.com` */ - readonly marketingSite: string + readonly marketingUrl: string /** * (optional) URL where users can donate to the upstream project * @example `https://nextcloud.com/contribute/` @@ -45,7 +40,7 @@ export type SDKManifest = { /** * URL where users can find instructions on how to use the service */ - readonly docsUrl: string + readonly docsUrls: string[] readonly description: { /** Short description to display on the marketplace list page. Max length 80 chars. */ readonly short: T.LocaleString diff --git a/sdk/package/lib/test/inputSpecBuilder.test.ts b/sdk/package/lib/test/inputSpecBuilder.test.ts index 3bbe1a048..5bf6f01cb 100644 --- a/sdk/package/lib/test/inputSpecBuilder.test.ts +++ b/sdk/package/lib/test/inputSpecBuilder.test.ts @@ -393,12 +393,11 @@ describe('values', () => { id: 'testOutput', title: '', license: '', - wrapperRepo: '', + packageRepo: '', upstreamRepo: '', - supportSite: '', - marketingSite: '', + marketingUrl: '', donationUrl: null, - docsUrl: '', + docsUrls: [], description: { short: '', long: '', diff --git a/sdk/package/lib/test/output.sdk.ts b/sdk/package/lib/test/output.sdk.ts index 17e462c81..7ebfc18ec 100644 --- a/sdk/package/lib/test/output.sdk.ts +++ b/sdk/package/lib/test/output.sdk.ts @@ -9,12 +9,11 @@ export const sdk = StartSdk.of() id: 'testOutput', title: '', license: '', - wrapperRepo: '', + packageRepo: '', upstreamRepo: '', - supportSite: '', - marketingSite: '', + marketingUrl: '', donationUrl: null, - docsUrl: '', + docsUrls: [], description: { short: '', long: '', diff --git a/web/projects/marketplace/src/pages/show/links.component.ts b/web/projects/marketplace/src/pages/show/links.component.ts index d551e897b..2454754c2 100644 --- a/web/projects/marketplace/src/pages/show/links.component.ts +++ b/web/projects/marketplace/src/pages/show/links.component.ts @@ -23,7 +23,7 @@ import { MarketplaceLinkComponent } from './link.component' class="item-pointer" /> {{ 'Links' | i18n }}
- @if (pkg().docsUrl; as docsUrl) { + @for (docsUrl of pkg().docsUrls; track $index) { } - @if (pkg().donationUrl; as donationUrl) { ({ name: 'Documentation', - value: manifest.docsUrl || NOT_PROVIDED, - }, - { - name: 'Support', - value: manifest.supportSite || NOT_PROVIDED, - }, + value: docsUrl, + })), { name: 'Marketing', - value: manifest.marketingSite || NOT_PROVIDED, + value: manifest.marketingUrl || NOT_PROVIDED, }, { name: 'Donations', diff --git a/web/projects/ui/src/app/routes/portal/routes/services/routes/outlet.component.ts b/web/projects/ui/src/app/routes/portal/routes/services/routes/outlet.component.ts index 6afbad774..497c0d551 100644 --- a/web/projects/ui/src/app/routes/portal/routes/services/routes/outlet.component.ts +++ b/web/projects/ui/src/app/routes/portal/routes/services/routes/outlet.component.ts @@ -45,37 +45,19 @@ import { getManifest } from 'src/app/utils/get-package-data' @@ -209,7 +191,6 @@ export class ServiceOutletComponent { { title: 'actions', icon: '@tui.file-terminal' }, { title: 'logs', icon: '@tui.logs' }, { title: 'about', icon: '@tui.info' }, - { title: 'Documentation', icon: '@tui.book-open-text' }, ] protected readonly service = toSignal( diff --git a/web/projects/ui/src/app/services/api/api.fixures.ts b/web/projects/ui/src/app/services/api/api.fixures.ts index 6fbe16920..baae683fc 100644 --- a/web/projects/ui/src/app/services/api/api.fixures.ts +++ b/web/projects/ui/src/app/services/api/api.fixures.ts @@ -231,12 +231,11 @@ export namespace Mock { }, releaseNotes: 'Taproot, Schnorr, and more.', license: 'MIT', - wrapperRepo: 'https://github.com/start9labs/bitcoind-wrapper', + packageRepo: 'https://github.com/start9labs/bitcoind-wrapper', upstreamRepo: 'https://github.com/bitcoin/bitcoin', - supportSite: 'https://bitcoin.org', - marketingSite: 'https://bitcoin.org', + marketingUrl: 'https://bitcoin.org', donationUrl: 'https://start9.com', - docsUrl: 'https://docs.start9.com', + docsUrls: ['https://docs.start9.com'], alerts: { install: 'Bitcoin can take over a week to sync.', uninstall: @@ -279,12 +278,11 @@ export namespace Mock { }, releaseNotes: 'Dual funded channels!', license: 'MIT', - wrapperRepo: 'https://github.com/start9labs/lnd-wrapper', + packageRepo: 'https://github.com/start9labs/lnd-wrapper', upstreamRepo: 'https://github.com/lightningnetwork/lnd', - supportSite: 'https://lightning.engineering/', - marketingSite: 'https://lightning.engineering/', + marketingUrl: 'https://lightning.engineering/', donationUrl: null, - docsUrl: 'https://docs.start9.com', + docsUrls: ['https://docs.start9.com'], alerts: { install: null, uninstall: null, @@ -339,12 +337,11 @@ export namespace Mock { }, releaseNotes: 'Even better support for Bitcoin and wallets!', license: 'MIT', - wrapperRepo: 'https://github.com/start9labs/btc-rpc-proxy-wrapper', + packageRepo: 'https://github.com/start9labs/btc-rpc-proxy-wrapper', upstreamRepo: 'https://github.com/Kixunil/btc-rpc-proxy', - supportSite: '', - marketingSite: '', + marketingUrl: '', donationUrl: 'https://start9.com', - docsUrl: 'https://docs.start9.com', + docsUrls: ['https://docs.start9.com'], alerts: { install: 'Testing install alert', uninstall: null, @@ -402,11 +399,10 @@ export namespace Mock { title: 'Bitcoin Core', description: mockDescription, license: 'mit', - wrapperRepo: 'https://github.com/start9labs/bitcoind-startos', + packageRepo: 'https://github.com/start9labs/bitcoind-startos', upstreamRepo: 'https://github.com/bitcoin/bitcoin', - supportSite: 'https://bitcoin.org', - marketingSite: 'https://bitcoin.org', - docsUrl: 'https://bitcoin.org', + marketingUrl: 'https://bitcoin.org', + docsUrls: ['https://bitcoin.org'], releaseNotes: 'Even better support for Bitcoin and wallets!', osVersion: '0.3.6', sdkVersion: '0.4.0-beta.48', @@ -444,11 +440,10 @@ export namespace Mock { long: 'Bitcoin Knots is a combined Bitcoin node and wallet. Not only is it easy to use, but it also ensures bitcoins you receive are both real bitcoins and really yours.', }, license: 'mit', - wrapperRepo: 'https://github.com/start9labs/bitcoinknots-startos', + packageRepo: 'https://github.com/start9labs/bitcoinknots-startos', upstreamRepo: 'https://github.com/bitcoinknots/bitcoin', - supportSite: 'https://bitcoinknots.org', - marketingSite: 'https://bitcoinknots.org', - docsUrl: 'https://bitcoinknots.org', + marketingUrl: 'https://bitcoinknots.org', + docsUrls: ['https://bitcoinknots.org'], releaseNotes: 'Even better support for Bitcoin and wallets!', osVersion: '0.3.6', sdkVersion: '0.4.0-beta.48', @@ -496,11 +491,10 @@ export namespace Mock { title: 'Bitcoin Core', description: mockDescription, license: 'mit', - wrapperRepo: 'https://github.com/start9labs/bitcoind-startos', + packageRepo: 'https://github.com/start9labs/bitcoind-startos', upstreamRepo: 'https://github.com/bitcoin/bitcoin', - supportSite: 'https://bitcoin.org', - marketingSite: 'https://bitcoin.org', - docsUrl: 'https://bitcoin.org', + marketingUrl: 'https://bitcoin.org', + docsUrls: ['https://bitcoin.org'], releaseNotes: 'Even better support for Bitcoin and wallets!', osVersion: '0.3.6', sdkVersion: '0.4.0-beta.48', @@ -538,11 +532,10 @@ export namespace Mock { long: 'Bitcoin Knots is a combined Bitcoin node and wallet. Not only is it easy to use, but it also ensures bitcoins you receive are both real bitcoins and really yours.', }, license: 'mit', - wrapperRepo: 'https://github.com/start9labs/bitcoinknots-startos', + packageRepo: 'https://github.com/start9labs/bitcoinknots-startos', upstreamRepo: 'https://github.com/bitcoinknots/bitcoin', - supportSite: 'https://bitcoinknots.org', - marketingSite: 'https://bitcoinknots.org', - docsUrl: 'https://bitcoinknots.org', + marketingUrl: 'https://bitcoinknots.org', + docsUrls: ['https://bitcoinknots.org'], releaseNotes: 'Even better support for Bitcoin and wallets!', osVersion: '0.3.6', sdkVersion: '0.4.0-beta.48', @@ -592,11 +585,10 @@ export namespace Mock { title: 'LND', description: mockDescription, license: 'mit', - wrapperRepo: 'https://github.com/start9labs/lnd-startos', + packageRepo: 'https://github.com/start9labs/lnd-startos', upstreamRepo: 'https://github.com/lightningnetwork/lnd', - supportSite: 'https://lightning.engineering/slack.html', - marketingSite: 'https://lightning.engineering/', - docsUrl: 'https://lightning.engineering/', + marketingUrl: 'https://lightning.engineering/', + docsUrls: ['https://lightning.engineering/'], releaseNotes: 'Upstream release to 0.17.5', osVersion: '0.3.6', sdkVersion: '0.4.0-beta.48', @@ -647,11 +639,10 @@ export namespace Mock { title: 'LND', description: mockDescription, license: 'mit', - wrapperRepo: 'https://github.com/start9labs/lnd-startos', + packageRepo: 'https://github.com/start9labs/lnd-startos', upstreamRepo: 'https://github.com/lightningnetwork/lnd', - supportSite: 'https://lightning.engineering/slack.html', - marketingSite: 'https://lightning.engineering/', - docsUrl: 'https://lightning.engineering/', + marketingUrl: 'https://lightning.engineering/', + docsUrls: ['https://lightning.engineering/'], releaseNotes: 'Upstream release to 0.17.4', osVersion: '0.3.6', sdkVersion: '0.4.0-beta.48', @@ -706,11 +697,10 @@ export namespace Mock { title: 'Bitcoin Core', description: mockDescription, license: 'mit', - wrapperRepo: 'https://github.com/start9labs/bitcoind-startos', + packageRepo: 'https://github.com/start9labs/bitcoind-startos', upstreamRepo: 'https://github.com/bitcoin/bitcoin', - supportSite: 'https://bitcoin.org', - marketingSite: 'https://bitcoin.org', - docsUrl: 'https://bitcoin.org', + marketingUrl: 'https://bitcoin.org', + docsUrls: ['https://bitcoin.org'], releaseNotes: 'Even better support for Bitcoin and wallets!', osVersion: '0.3.6', sdkVersion: '0.4.0-beta.48', @@ -748,11 +738,10 @@ export namespace Mock { long: 'Bitcoin Knots is a combined Bitcoin node and wallet. Not only is it easy to use, but it also ensures bitcoins you receive are both real bitcoins and really yours.', }, license: 'mit', - wrapperRepo: 'https://github.com/start9labs/bitcoinknots-startos', + packageRepo: 'https://github.com/start9labs/bitcoinknots-startos', upstreamRepo: 'https://github.com/bitcoinknots/bitcoin', - supportSite: 'https://bitcoinknots.org', - marketingSite: 'https://bitcoinknots.org', - docsUrl: 'https://bitcoinknots.org', + marketingUrl: 'https://bitcoinknots.org', + docsUrls: [], releaseNotes: 'Even better support for Bitcoin and wallets!', osVersion: '0.3.6', sdkVersion: '0.4.0-beta.48', @@ -800,11 +789,10 @@ export namespace Mock { title: 'LND', description: mockDescription, license: 'mit', - wrapperRepo: 'https://github.com/start9labs/lnd-startos', + packageRepo: 'https://github.com/start9labs/lnd-startos', upstreamRepo: 'https://github.com/lightningnetwork/lnd', - supportSite: 'https://lightning.engineering/slack.html', - marketingSite: 'https://lightning.engineering/', - docsUrl: 'https://lightning.engineering/', + marketingUrl: 'https://lightning.engineering/', + docsUrls: [], releaseNotes: 'Upstream release and minor fixes.', osVersion: '0.3.6', sdkVersion: '0.4.0-beta.48', @@ -855,11 +843,10 @@ export namespace Mock { title: 'Bitcoin Proxy', description: mockDescription, license: 'mit', - wrapperRepo: 'https://github.com/Start9Labs/btc-rpc-proxy-wrappers', + packageRepo: 'https://github.com/Start9Labs/btc-rpc-proxy-wrappers', upstreamRepo: 'https://github.com/Kixunil/btc-rpc-proxy', - supportSite: 'https://github.com/Kixunil/btc-rpc-proxy/issues', - docsUrl: 'https://github.com/Kixunil/btc-rpc-proxy', - marketingSite: '', + docsUrls: [], + marketingUrl: '', releaseNotes: 'Upstream release and minor fixes.', osVersion: '0.3.6', sdkVersion: '0.4.0-beta.48',