diff --git a/README.md b/README.md index fa73e26f..ac7b6b98 100644 --- a/README.md +++ b/README.md @@ -16,14 +16,18 @@ Please view the [Documentation](https://helium.github.io/helium-js/) for usage a This SDK is a collection of TypeScrypt libraries for interacting with the Helium blockchain. For additional documentation about the Helium network, visit the [Developer Site](https://docs.helium.com/). -| Package | NPM Version | What it's for | -|-------------------------------------------------------------------------------------------------|-----------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------| -| [`@helium/crypto`](https://github.com/helium/helium-js/tree/master/packages/crypto) | ![npm](https://img.shields.io/npm/v/@helium/crypto) | Cryptography utilities including keypairs, mnemonics and base58-check encoding | -| [`@helium/crypto-react-native`](https://github.com/helium/helium-js/tree/master/packages/crypto-react-native) | ![npm](https://img.shields.io/npm/v/@helium/crypto-react-native) | Cryptography utilities following the same interface as `@helium/crypto` but for React Native | -| [`@helium/transactions`](https://github.com/helium/helium-js/tree/master/packages/transactions) | ![npm](https://img.shields.io/npm/v/@helium/transactions) | Construct and serialize transaction primitives from their [protobuf](https://developers.google.com/protocol-buffers) definitions | -| [`@helium/proto`](https://github.com/helium/proto) | ![npm](https://img.shields.io/npm/v/@helium/proto) | Protobuf definitions for Helium transactions | -| [`@helium/http`](https://github.com/helium/helium-js/tree/master/packages/http) | ![npm](https://img.shields.io/npm/v/@helium/http) | An HTTP client for the blockchain REST API | -| [`@helium/currency`](https://github.com/helium/helium-js/tree/master/packages/currency) | ![npm](https://img.shields.io/npm/v/@helium/currency) | Utilities for representing amounts of the different currencies supported by Helium | +| Package | NPM Version | What it's for | +|---------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------| +| [`@helium/crypto`](https://github.com/helium/helium-js/tree/master/packages/crypto) | ![npm](https://img.shields.io/npm/v/@helium/crypto) | Cryptography utilities including keypairs, mnemonics and base58-check encoding | +| [`@helium/crypto-react-native`](https://github.com/helium/helium-js/tree/master/packages/crypto-react-native) | ![npm](https://img.shields.io/npm/v/@helium/crypto-react-native) | Cryptography utilities following the same interface as `@helium/crypto` but for React Native | +| [`@helium/transactions`](https://github.com/helium/helium-js/tree/master/packages/transactions) | ![npm](https://img.shields.io/npm/v/@helium/transactions) | Construct and serialize transaction primitives from their [protobuf](https://developers.google.com/protocol-buffers) definitions | +| [`@helium/proto`](https://github.com/helium/proto) | ![npm](https://img.shields.io/npm/v/@helium/proto) | Protobuf definitions for Helium transactions | +| [`@helium/proto-ble`](https://github.com/helium/helium-js/tree/master/packages/proto-ble) | ![npm](https://img.shields.io/npm/v/@helium/proto-ble) | Protobuf definitions for Helium Hotspot ble transactions | +| [`@helium/http`](https://github.com/helium/helium-js/tree/master/packages/http) | ![npm](https://img.shields.io/npm/v/@helium/http) | An HTTP client for the blockchain REST API | +| [`@helium/currency`](https://github.com/helium/helium-js/tree/master/packages/currency) | ![npm](https://img.shields.io/npm/v/@helium/currency) | Utilities for representing amounts of the different currencies supported by Helium | +| [`@helium/onboarding`](https://github.com/helium/helium-js/tree/master/packages/onboarding) | ![npm](https://img.shields.io/npm/v/@helium/onboarding) | An HTTP client for interfacing with an Onboarding Server | +| [`@helium/address`](https://github.com/helium/helium-js/tree/master/packages/address) | ![npm](https://img.shields.io/npm/v/@helium/address) | Utilities for Helium Addresses | +| [`@helium/wallet-link`](https://github.com/helium/helium-js/tree/master/packages/wallet-link) | ![npm](https://img.shields.io/npm/v/@helium/wallet-link) | Utilities for linking a 3rd party app to the Helium Wallet | ## Installation diff --git a/package.json b/package.json index e80f10e4..6e2530b5 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "packages/transactions/src", "packages/currency/src", "packages/address/src", + "packages/wallet-link/src", "integration_tests/tests" ], "collectCoverageFrom": [ diff --git a/packages/crypto-react-native/src/Keypair.ts b/packages/crypto-react-native/src/Keypair.ts index f8710122..b12ec1ac 100644 --- a/packages/crypto-react-native/src/Keypair.ts +++ b/packages/crypto-react-native/src/Keypair.ts @@ -61,12 +61,12 @@ export default class Keypair { return new Keypair(keypair, netType) } - async sign(message: string | Uint8Array): Promise { + async sign(message: string | Uint8Array): Promise { const messageBuffer = Buffer.from(message) const signature = await Sodium.crypto_sign_detached( messageBuffer.toString('base64'), this.privateKey.toString('base64'), ) - return Buffer.from(signature, 'base64') + return Uint8Array.from(Buffer.from(signature, 'base64')) } } diff --git a/packages/onboarding/src/index.ts b/packages/onboarding/src/index.ts index fd323b1f..48f102af 100644 --- a/packages/onboarding/src/index.ts +++ b/packages/onboarding/src/index.ts @@ -1,5 +1,5 @@ /** - * [[include:http/README.md]] + * [[include:onboarding/README.md]] * @packageDocumentation * @module onboarding */ diff --git a/packages/wallet-link/README.md b/packages/wallet-link/README.md new file mode 100644 index 00000000..8003bbdb --- /dev/null +++ b/packages/wallet-link/README.md @@ -0,0 +1,69 @@ +# `@helium/wallet-link` + +Utilities for linking a 3rd party app to the helium wallet. The link token is used for hotspot onboarding, location +assertion, and ownership transfer transaction signing with the Helium Wallet and Hotspot apps. + +## Installation + +### React Native + +```shell +$ yarn add @helium/wallet-link @helium/crypto-react-native +$ yarn add --dev patch-package postinstall-postinstall +# or +$ npm install @helium/wallet-link @helium/crypto-react-native +$ npm install --save-dev patch-package +``` + +When using this library in React Native you must patch the `@helium/crypto` calls +with `@helium/crypto-react-native`. You can do this using [patch-package](https://github.com/ds300/patch-package) +by adding the following file to your React Native root at `/patches/@wallet-link+4.4.0.patch`. + +``` +TODO: Add patch +``` + +### Browser or other JS environments + +```shell +$ yarn add @helium/wallet-link @helium/crypto +# or +$ npm install @helium/wallet-link @helium/crypto +``` + +## Usage + +```ts +// Create link to Helium app +const url = createWalletLinkUrl({ + universalLink: 'https://wallet.helium.com/', + requestAppId: 'com.maker.app', + callbackUrl: 'makerappscheme://', + appName: 'Maker App', +}) + +Linking.openURL(url) + +// parse received token +const parsed = parseWalletLinkToken(token) + +// verify token +const verified = verifyWalletLinkToken(parsed) + +// verify token with max age +const verified = verifyWalletLinkToken(parsed, { maxAgeInSeconds: 60 }) + +// Create link to update a hotspot +const updateParams = { + token, + platform: Platform.OS, + addGatewayTxn: 'your_optional_unsigned_txn', + assertLocationTxn: 'your_optional_unsigned_txn', + transferHotspotTxn: 'your_optional_unsigned_txn', +} as SignHotspotRequest + +const url = createUpdateHotspotUrl(updateParams) +Linking.openURL(url) + +// submit signed txn +``` diff --git a/packages/wallet-link/package.json b/packages/wallet-link/package.json new file mode 100644 index 00000000..d9f09863 --- /dev/null +++ b/packages/wallet-link/package.json @@ -0,0 +1,40 @@ +{ + "name": "@helium/wallet-link", + "version": "4.4.0", + "description": "Utilities for linking a 3rd party app to the helium wallet.", + "keywords": [ + "helium", + "blockchain", + "react-native" + ], + "contributors": [ + "Matt Reetz " + ], + "homepage": "https://github.com/helium/helium-js#readme", + "license": "Apache-2.0", + "main": "build/index.js", + "module": "build/index.es.js", + "files": [ + "build" + ], + "publishConfig": { + "access": "public" + }, + "scripts": { + "test": "echo \"Error: run tests from root\" && exit 1", + "clean": "rimraf build", + "build": "yarn run clean && tsc" + }, + "dependencies": { + "@helium/address": "^4.3.1", + "@helium/transactions": "^4.3.1", + "date-fns": "^2.28.0", + "query-string": "^7.1.1" + }, + "peerDependencies": { + "@helium/crypto": "^4.3.1" + }, + "devDependencies": { + "@helium/crypto": "^4.3.1" + } +} diff --git a/packages/wallet-link/src/__tests__/WalletLink.spec.ts b/packages/wallet-link/src/__tests__/WalletLink.spec.ts new file mode 100644 index 00000000..2e42085b --- /dev/null +++ b/packages/wallet-link/src/__tests__/WalletLink.spec.ts @@ -0,0 +1,156 @@ +import { Keypair } from '@helium/crypto' +import { getUnixTime } from 'date-fns' +import { + createLinkWalletCallbackUrl, + createSignHotspotCallbackUrl, + createUpdateHotspotUrl, + createWalletLinkUrl, + LinkWalletResponse, + makeAppLinkAuthToken, + parseWalletLinkToken, + SignHotspotRequest, + SignHotspotResponse, + verifyWalletLinkToken, +} from '../index' + +const createToken = async ({ + time, + signingAppId, +} : { time?: number, signingAppId?: string } = {}) => { + const keypair = await Keypair.makeRandom() + const opts = { + address: keypair.address.b58, + appName: 'tacos', + callbackUrl: 'myscheme://', + requestAppId: 'com.tacos', + signingAppId: signingAppId || 'com.burrito', + time: time || new Date().getTime(), + } + const token = await makeAppLinkAuthToken(opts, keypair) + return { token: parseWalletLinkToken(token), opts, tokenString: token } +} + +describe('wallet-link', () => { + describe('create link', () => { + it('successfully creates and parses', async () => { + const { token, opts } = await createToken() + expect(token.address).toBe(opts.address) + expect(token.signature).toBeDefined() + expect(token.appName).toBe(opts.appName) + expect(token.callbackUrl).toBe(opts.callbackUrl) + expect(token.requestAppId).toBe(opts.requestAppId) + expect(token.signingAppId).toBe(opts.signingAppId) + expect(token.time).toBe(opts.time) + }) + }) + + describe('verify link', () => { + it('validates token without opts', async () => { + const { token } = await createToken() + const verified = await verifyWalletLinkToken(token) + expect(verified).toBe(true) + }) + + it('validates token with max age', async () => { + const { token } = await createToken() + const verified = await verifyWalletLinkToken(token, { maxAgeInSeconds: 60 }) + expect(verified).toBe(true) + }) + + it('invalidates expired token', async () => { + const { token } = await createToken({ time: getUnixTime(new Date()) - 60 }) + expect(() => verifyWalletLinkToken(token, { maxAgeInSeconds: 30 })).toThrow('Token is expired') + }) + }) + + describe('create urls', () => { + it('creates wallet link url', async () => { + const params = { + requestAppId: 'testRequestAppId', + callbackUrl: 'testCallbackUrl', + appName: 'testAppName', + universalLink: 'testUniversalLink', + path: 'testPath', + } + const callbackUrl = createWalletLinkUrl(params) + expect(callbackUrl).toBe('testUniversalLinktestPath?appName=testAppName&callbackUrl=testCallbackUrl' + + '&requestAppId=testRequestAppId') + }) + + it('creates callback url', async () => { + const params: LinkWalletResponse = { + status: 'success', + token: 'testToken', + } + const callbackUrl = createLinkWalletCallbackUrl('test://', 'testAddress', params) + expect(callbackUrl).toBe('test://link_wallet/testAddress?status=success&token=testToken') + }) + + it('creates sign hotspot callback url', async () => { + const params: SignHotspotResponse = { + status: 'success', + assertTxn: 'testAssertTxn', + gatewayTxn: 'testGatewayTxn', + transferTxn: 'testTransferTxn', + gatewayAddress: 'testGatewayAddress', + } + const callbackUrl = createSignHotspotCallbackUrl('test://', params) + expect(callbackUrl).toBe('test://sign_hotspot?assertTxn=testAssertTxn&gatewayAddress=testGatewayAddress' + + '&gatewayTxn=testGatewayTxn&status=success&transferTxn=testTransferTxn') + }) + + it('creates ios update hotspot url', async () => { + const { tokenString } = await createToken({ signingAppId: 'com.helium.wallet.app' }) + const params: SignHotspotRequest = { + token: tokenString, + addGatewayTxn: 'testAddGatewayTxn', + assertLocationTxn: 'testAssertLocationTxn', + transferHotspotTxn: 'testTransferHotspotTxn', + platform: 'ios', + } + const callbackUrl = createUpdateHotspotUrl(params) + expect(callbackUrl).toBe('https://wallet.helium.com/sign_hotspot?addGatewayTxn=testAddGatewayTxn' + + `&assertLocationTxn=testAssertLocationTxn&platform=ios&token=${encodeURIComponent(tokenString)}` + + '&transferHotspotTxn=testTransferHotspotTxn') + }) + + it('creates android update hotspot url', async () => { + const { tokenString } = await createToken({ signingAppId: 'com.helium.wallet.app' }) + const params: SignHotspotRequest = { + token: tokenString, + addGatewayTxn: 'testAddGatewayTxn', + assertLocationTxn: 'testAssertLocationTxn', + transferHotspotTxn: 'testTransferHotspotTxn', + platform: 'android', + } + const callbackUrl = createUpdateHotspotUrl(params) + expect(callbackUrl).toBe('https://wallet.helium.com/sign_hotspot?addGatewayTxn=testAddGatewayTxn' + + `&assertLocationTxn=testAssertLocationTxn&platform=android&token=${encodeURIComponent(tokenString)}` + + '&transferHotspotTxn=testTransferHotspotTxn') + }) + + it('fails for invalid platform', async () => { + const { tokenString } = await createToken({ signingAppId: 'com.helium.wallet.app' }) + const params: SignHotspotRequest = { + token: tokenString, + addGatewayTxn: 'testAddGatewayTxn', + assertLocationTxn: 'testAssertLocationTxn', + transferHotspotTxn: 'testTransferHotspotTxn', + platform: 'test', + } + expect(() => createUpdateHotspotUrl(params)).toThrow("Platform 'test' is not supported") + }) + + it('fails for invalid signing app id', async () => { + const { tokenString } = await createToken() + const params: SignHotspotRequest = { + token: tokenString, + addGatewayTxn: 'testAddGatewayTxn', + assertLocationTxn: 'testAssertLocationTxn', + transferHotspotTxn: 'testTransferHotspotTxn', + platform: 'android', + } + expect(() => createUpdateHotspotUrl(params)).toThrow('Could not find delegate app') + }) + }) +}) diff --git a/packages/wallet-link/src/index.ts b/packages/wallet-link/src/index.ts new file mode 100644 index 00000000..94f5e863 --- /dev/null +++ b/packages/wallet-link/src/index.ts @@ -0,0 +1,8 @@ +/** + * [[include:wallet-link/README.md]] + * @packageDocumentation + * @module wallet-link + */ + +export * from './walletLink' +export * from './types' diff --git a/packages/wallet-link/src/types.ts b/packages/wallet-link/src/types.ts new file mode 100644 index 00000000..6a56aa77 --- /dev/null +++ b/packages/wallet-link/src/types.ts @@ -0,0 +1,69 @@ +export type LinkWalletResponse = { + status: 'success' | 'user_cancelled' + token?: string +} + +export type SignHotspotResponse = { + status: 'success' | 'token_not_found' | 'user_cancelled' | 'gateway_not_found' | 'invalid_link' + assertTxn?: string + gatewayTxn?: string + transferTxn?: string + gatewayAddress?: string +} + +export type LinkWalletRequest = { + requestAppId: string + callbackUrl: string + appName: string +} + +export type SignHotspotRequest = { + token: string + addGatewayTxn?: string + assertLocationTxn?: string + transferHotspotTxn?: string + platform: string +} + +export type Token = LinkWalletRequest & { + signingAppId: string + time: number + address: string +} + +export type TokenWithSig = Token & { + signature: string +} + +export type MakerApp = { + universalLink: string + name: string + androidPackage: string + iosBundleId: string +} + +export type DelegateApp = { + universalLink: string + name: string + androidPackage: string + iosBundleId: string + appStoreId: number +} + +const HELIUM_WALLET_APP: DelegateApp = { + universalLink: 'https://wallet.helium.com/', + name: 'helium-hnt-wallet', + androidPackage: 'com.helium.wallet.app', + iosBundleId: 'com.helium.wallet.app', + appStoreId: 1609525848, +} + +const HELIUM_HOTSPOT_APP: DelegateApp = { + universalLink: 'https://helium.com/', + name: 'helium-hotspot', + androidPackage: 'com.helium.wallet', + iosBundleId: 'com.helium.mobile.wallet', + appStoreId: 1450463605, +} + +export const DELEGATE_APPS = [HELIUM_WALLET_APP, HELIUM_HOTSPOT_APP] diff --git a/packages/wallet-link/src/walletLink.ts b/packages/wallet-link/src/walletLink.ts new file mode 100644 index 00000000..38af6ada --- /dev/null +++ b/packages/wallet-link/src/walletLink.ts @@ -0,0 +1,113 @@ +/* eslint-disable object-curly-newline */ +import Address from '@helium/address' +import { utils } from '@helium/crypto' +import queryString from 'query-string' +import { SignableKeypair } from '@helium/transactions' +import { getUnixTime } from 'date-fns' +import { + DELEGATE_APPS, + LinkWalletResponse, + SignHotspotRequest, + SignHotspotResponse, + Token, + TokenWithSig, +} from './types' + +export const makeAppLinkAuthToken = async (tokenOpts: Token, keypair: SignableKeypair) => { + const ordered = Object.keys(tokenOpts) + .sort() + .reduce( + (obj, key) => ({ + [key]: tokenOpts[key as keyof Token], + ...obj, + }), + {}, + ) + const message = JSON.stringify(ordered) + const signatureResult = await keypair.sign(message) + const signature = Buffer.from(signatureResult).toString('base64') + + const signedToken = { + ...tokenOpts, + signature, + } + return Buffer.from(JSON.stringify(signedToken)).toString('base64') +} + +export const verifyWalletLinkToken = ( + linkToken: TokenWithSig, + opts?: { maxAgeInSeconds: number }, +) => { + const { signature, ...token } = linkToken + + if (opts?.maxAgeInSeconds) { + const expiration = getUnixTime(new Date()) - opts.maxAgeInSeconds + if (linkToken.time < expiration) throw new Error('Token is expired') + } + + const ordered = Object.keys(token) + .sort() + .reduce( + (obj, key) => ({ + [key]: token[key as keyof Token], + ...obj, + }), + {}, + ) + const message = JSON.stringify(ordered) + const { publicKey } = Address.fromB58(token.address) + return utils.verify( + Uint8Array.from(Buffer.from(signature, 'base64')), + Uint8Array.from(Buffer.from(message)), + publicKey, + ) +} + +export const parseWalletLinkToken = (base64Token: string) => { + const buff = Buffer.from(base64Token, 'base64') + const container = buff.toString('utf-8') + return JSON.parse(container) as TokenWithSig +} + +export const createWalletLinkUrl = (opts: { + requestAppId: string + callbackUrl: string + appName: string + universalLink?: string + path?: string +}) => { + const { universalLink, path, ...params } = opts + const query = queryString.stringify(params) + + return `${universalLink || 'https://wallet.helium.com/'}${path || 'link_wallet'}?${query}` +} + +export const createLinkWalletCallbackUrl = ( + protocol: string, + address: string, + responseParams: LinkWalletResponse, +) => `${protocol}link_wallet/${address}?${queryString.stringify(responseParams)}` + +export const createSignHotspotCallbackUrl = ( + protocol: string, + responseParams: SignHotspotResponse, +) => `${protocol}sign_hotspot?${queryString.stringify(responseParams)}` + +export const createUpdateHotspotUrl = (opts: SignHotspotRequest) => { + if (!(opts.platform === 'android' || opts.platform === 'ios')) { + throw new Error(`Platform '${opts.platform}' is not supported`) + } + + const { signingAppId } = parseWalletLinkToken(opts.token) || { + signingAppId: '', + } + const requestApp = DELEGATE_APPS.find(({ androidPackage, iosBundleId }) => { + const id = opts.platform === 'android' ? androidPackage : iosBundleId + return id === signingAppId + }) + const universalLink = requestApp?.universalLink + if (!universalLink) throw new Error('Could not find delegate app') + + const query = queryString.stringify(opts) + return `${universalLink}sign_hotspot?${query}` +} diff --git a/packages/wallet-link/tsconfig.json b/packages/wallet-link/tsconfig.json new file mode 100644 index 00000000..5dd43feb --- /dev/null +++ b/packages/wallet-link/tsconfig.json @@ -0,0 +1,41 @@ +{ + "compilerOptions": { + "target": "es2017", + "module": "commonjs", + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "outDir": "build", + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "downlevelIteration": true, + + "moduleResolution": "node", + "baseUrl": ".", + "paths": { + "*": ["./types/*"] + }, + "esModuleInterop" : true, + + // Not using this setting because its only used to require the package.json file, and that would change the + // structure of the files in the dist directory because package.json is not located inside src. It would be nice + // to use import instead of require(), but its not worth the tradeoff of restructuring the build (for now). + // "resolveJsonModule": true, + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "__tests__", + "src/**/*.spec.ts", + "src/**/*.js" + ], + "jsdoc": { + "out": "support/jsdoc", + "access": "public" + } +} diff --git a/packages/wallet-link/yarn.lock b/packages/wallet-link/yarn.lock new file mode 100644 index 00000000..094347eb --- /dev/null +++ b/packages/wallet-link/yarn.lock @@ -0,0 +1,204 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@helium/address@^4.3.1": + version "4.3.1" + resolved "https://registry.yarnpkg.com/@helium/address/-/address-4.3.1.tgz#e82f001b438166822ce8548713549b1ff87741e8" + integrity sha512-5f24ncoR3uOQgzFEtU2+YsHZTXW3+WYEBVdMVQEc5Hkou0bOTAOjVJZNhMqpIWLRzQXto2NOrDVIWXcFqqYnkg== + dependencies: + bs58 "^5.0.0" + js-sha256 "^0.9.0" + multiformats "^9.6.4" + +"@helium/proto@^1.5.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@helium/proto/-/proto-1.6.0.tgz#b97003bbc511afec1abac7cbffc5c088e348022d" + integrity sha512-aoVjhYDcic5g+n/iwKGXmGgMruPXTffpyr2ziGjuhAvU0phPSv6gnTbyHKY7FqBCUOYX4jHzEKJgX7M27UOGGg== + dependencies: + protobufjs "^6.11.3" + +"@helium/transactions@^4.3.1": + version "4.3.1" + resolved "https://registry.yarnpkg.com/@helium/transactions/-/transactions-4.3.1.tgz#b4ad5782ad6f9d25287ba43efc4683db34d4ec25" + integrity sha512-acH0gDLrC/aTDtM4Jljd8xdQCzITWVNBsGvyTClfrS5dRos++A9wisvCx/VwUyl3w9x/NNU/+V5q8Is6fPJtJw== + dependencies: + "@helium/address" "^4.3.1" + "@helium/proto" "^1.5.0" + "@types/libsodium-wrappers" "^0.7.8" + long "^4.0.0" + path "^0.12.7" + +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== + +"@types/libsodium-wrappers@^0.7.8": + version "0.7.9" + resolved "https://registry.yarnpkg.com/@types/libsodium-wrappers/-/libsodium-wrappers-0.7.9.tgz#89c3ad2156d5143e64bce86cfeb0045a983aeccc" + integrity sha512-LisgKLlYQk19baQwjkBZZXdJL0KbeTpdEnrAfz5hQACbklCY0gVFnsKUyjfNWF1UQsCSjw93Sj5jSbiO8RPfdw== + +"@types/long@^4.0.1": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" + integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== + +"@types/node@>=13.7.0": + version "18.0.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.0.tgz#67c7b724e1bcdd7a8821ce0d5ee184d3b4dd525a" + integrity sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA== + +base-x@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-4.0.0.tgz#d0e3b7753450c73f8ad2389b5c018a4af7b2224a" + integrity sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw== + +bs58@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-5.0.0.tgz#865575b4d13c09ea2a84622df6c8cbeb54ffc279" + integrity sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ== + dependencies: + base-x "^4.0.0" + +date-fns@^2.28.0: + version "2.28.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.28.0.tgz#9570d656f5fc13143e50c975a3b6bbeb46cd08b2" + integrity sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw== + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og== + +filter-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" + integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + +js-sha256@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" + integrity sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA== + +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + +multiformats@^9.6.4: + version "9.7.0" + resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.7.0.tgz#845799e8df70fbb6b15922500e45cb87cf12f7e5" + integrity sha512-uv/tcgwk0yN4DStopnBN4GTgvaAlYdy6KnZpuzEPFOYQd71DYFJjs0MN1ERElAflrZaYyGBWXyGxL5GgrxIx0Q== + +path@^0.12.7: + version "0.12.7" + resolved "https://registry.yarnpkg.com/path/-/path-0.12.7.tgz#d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f" + integrity sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q== + dependencies: + process "^0.11.1" + util "^0.10.3" + +process@^0.11.1: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + +protobufjs@^6.11.3: + version "6.11.3" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.3.tgz#637a527205a35caa4f3e2a9a4a13ddffe0e7af74" + integrity sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.1" + "@types/node" ">=13.7.0" + long "^4.0.0" + +query-string@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.1.tgz#754620669db978625a90f635f12617c271a088e1" + integrity sha512-MplouLRDHBZSG9z7fpuAAcI7aAYjDLhtsiVZsevsfaHWDS2IDdORKbSd1kWUA+V4zyva/HZoSfpwnYMMQDhb0w== + dependencies: + decode-uri-component "^0.2.0" + filter-obj "^1.1.0" + split-on-first "^1.0.0" + strict-uri-encode "^2.0.0" + +split-on-first@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" + integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== + +strict-uri-encode@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" + integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ== + +util@^0.10.3: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== + dependencies: + inherits "2.0.3" diff --git a/typedoc.json b/typedoc.json index 43ffd5e1..1599045c 100644 --- a/typedoc.json +++ b/typedoc.json @@ -7,7 +7,8 @@ "packages/onboarding/src/index.ts", "packages/proto-ble/build/index.d.ts", "packages/transactions/src/index.ts", - "packages/address/src/index.ts" + "packages/address/src/index.ts", + "packages/wallet-link/src/index.ts" ], "exclude": ["**/*.spec.ts"], "includes": "packages",