├── .changeset ├── README.md └── config.json ├── .eslintrc.js ├── .github └── workflows │ ├── pull_request.yml │ ├── release.yml │ ├── stale.yml │ └── sync_doc_devportal.yml ├── .gitignore ├── .husky └── pre-commit ├── .nvmrc ├── .prettierrc ├── .vscode └── notebooks │ ├── my-work.github-issues │ └── team-inbox.github-issues ├── CONTRIBUTING.md ├── README.md ├── SECURITY.md ├── SUPPORT.md ├── apps ├── docs │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── next-env.d.ts │ ├── next.config.js │ ├── package.json │ ├── pages │ │ ├── _app.mdx │ │ ├── _meta.json │ │ ├── docs │ │ │ ├── _meta.json │ │ │ ├── discover.mdx │ │ │ └── discover │ │ │ │ ├── _meta.json │ │ │ │ ├── dapp-browser.mdx │ │ │ │ ├── dapp-browser │ │ │ │ ├── _meta.json │ │ │ │ ├── dapp-customisation.mdx │ │ │ │ ├── manifest.mdx │ │ │ │ ├── migration.mdx │ │ │ │ └── plugin.mdx │ │ │ │ ├── developer-mode.mdx │ │ │ │ ├── faq.mdx │ │ │ │ ├── guidelines.mdx │ │ │ │ ├── required-skills.mdx │ │ │ │ ├── wallet-api.mdx │ │ │ │ └── wallet-api │ │ │ │ ├── _meta.json │ │ │ │ ├── appendix │ │ │ │ ├── _meta.json │ │ │ │ ├── families.mdx │ │ │ │ ├── manifest.mdx │ │ │ │ ├── migration-guide.mdx │ │ │ │ ├── transaction.mdx │ │ │ │ └── working-with-ledger-live.mdx │ │ │ │ ├── core │ │ │ │ ├── _meta.json │ │ │ │ ├── configuration.mdx │ │ │ │ ├── getting-started.mdx │ │ │ │ └── modules │ │ │ │ │ ├── _meta.json │ │ │ │ │ ├── account.mdx │ │ │ │ │ ├── bitcoin.mdx │ │ │ │ │ ├── currency.mdx │ │ │ │ │ ├── custom.mdx │ │ │ │ │ ├── device.mdx │ │ │ │ │ ├── exchange.mdx │ │ │ │ │ ├── message.mdx │ │ │ │ │ ├── storage.mdx │ │ │ │ │ ├── transaction.mdx │ │ │ │ │ └── wallet.mdx │ │ │ │ ├── examples │ │ │ │ ├── _meta.json │ │ │ │ ├── live-app-creation │ │ │ │ │ ├── _meta.json │ │ │ │ │ ├── configuration.mdx │ │ │ │ │ ├── hooking-up.mdx │ │ │ │ │ ├── manifest.mdx │ │ │ │ │ └── start.mdx │ │ │ │ ├── test-live-app │ │ │ │ │ ├── _meta.json │ │ │ │ │ ├── assets │ │ │ │ │ │ ├── 3-1-developer-mode.png │ │ │ │ │ │ ├── 3-2-dev-tools.png │ │ │ │ │ │ ├── 3-3-browse.png │ │ │ │ │ │ ├── 3-4-local-app.png │ │ │ │ │ │ └── 4-1-open-local-app.png │ │ │ │ │ ├── prerequisites.mdx │ │ │ │ │ └── testing.mdx │ │ │ │ └── use-live-app │ │ │ │ │ ├── _meta.json │ │ │ │ │ ├── assets │ │ │ │ │ ├── 3-1-developer-mode.png │ │ │ │ │ ├── 3-2-dev-tools.png │ │ │ │ │ ├── 3-3-browse.png │ │ │ │ │ ├── 3-4-local-app.png │ │ │ │ │ └── 4-1-open-local-app.png │ │ │ │ │ ├── import.mdx │ │ │ │ │ ├── interact.mdx │ │ │ │ │ ├── manifest.mdx │ │ │ │ │ └── prerequisites.mdx │ │ │ │ ├── introduction.mdx │ │ │ │ ├── react │ │ │ │ ├── _meta.json │ │ │ │ ├── configuration.mdx │ │ │ │ ├── getting-started.mdx │ │ │ │ └── hooks │ │ │ │ │ ├── _meta.json │ │ │ │ │ ├── useAccounts.mdx │ │ │ │ │ ├── useCapabilities.mdx │ │ │ │ │ ├── useCurrencies.mdx │ │ │ │ │ ├── useRequestAccount.mdx │ │ │ │ │ ├── useSignAndBroadcastTransaction.mdx │ │ │ │ │ ├── useSignMessage.mdx │ │ │ │ │ ├── useSignTransaction.mdx │ │ │ │ │ ├── useUserId.mdx │ │ │ │ │ └── useWalletInfo.mdx │ │ │ │ ├── server │ │ │ │ ├── _meta.json │ │ │ │ ├── assets │ │ │ │ │ ├── diagram-permissions-1-light.png │ │ │ │ │ ├── diagram-request-handlers-1-dark.png │ │ │ │ │ ├── diagram-request-handlers-1-light.png │ │ │ │ │ ├── diagram-request-handlers-2-light.png │ │ │ │ │ ├── diagram-transport-1-light.png │ │ │ │ │ ├── diagram-wallet-handlers-1-light.png │ │ │ │ │ └── server-rpc-node-classdiagram.png │ │ │ │ ├── extras │ │ │ │ │ ├── rpc-node.mdx │ │ │ │ │ └── rxjs.mdx │ │ │ │ ├── handlers │ │ │ │ │ ├── _meta.json │ │ │ │ │ ├── account.mdx │ │ │ │ │ ├── bitcoin.mdx │ │ │ │ │ ├── currency.mdx │ │ │ │ │ ├── device.mdx │ │ │ │ │ ├── exchange.mdx │ │ │ │ │ ├── message.mdx │ │ │ │ │ ├── storage.mdx │ │ │ │ │ ├── transaction.mdx │ │ │ │ │ └── wallet.mdx │ │ │ │ ├── index.mdx │ │ │ │ ├── usage-examples │ │ │ │ │ ├── with-constructor.mdx │ │ │ │ │ └── within-ledger-live.mdx │ │ │ │ └── wallet-api-server │ │ │ │ │ ├── _meta.json │ │ │ │ │ ├── diagrams.mdx │ │ │ │ │ ├── index.mdx │ │ │ │ │ └── react-hook.mdx │ │ │ │ └── simulator │ │ │ │ ├── _meta.json │ │ │ │ ├── configuration.mdx │ │ │ │ ├── getting-started.mdx │ │ │ │ ├── introduction.mdx │ │ │ │ └── profiles.mdx │ │ └── index.mdx │ ├── postcss.config.js │ ├── style.css │ ├── tailwind.config.js │ ├── theme.config.tsx │ └── tsconfig.json └── wallet-api-tools │ ├── .eslintrc.js │ ├── .gitignore │ ├── .prettierrc │ ├── .vscode │ └── settings.json │ ├── CHANGELOG.md │ ├── app │ ├── TopBar.tsx │ ├── head.tsx │ ├── layout.tsx │ └── page.tsx │ ├── manifest.json │ ├── next.config.js │ ├── package.json │ ├── postcss.config.js │ ├── public │ ├── favicon.ico │ ├── next.svg │ ├── thirteen.svg │ └── vercel.svg │ ├── src │ ├── CommandSelector │ │ ├── index.tsx │ │ └── style.css │ ├── Editor.tsx │ ├── Input.tsx │ ├── components │ │ ├── GroupedMessage.tsx │ │ ├── InfoMessage.tsx │ │ └── Message.tsx │ ├── helpers.ts │ └── types.ts │ ├── styles │ └── globals.css │ ├── tailwind.config.js │ └── tsconfig.json ├── examples └── client-nextjs │ ├── .eslintrc.json │ ├── .gitignore │ ├── .prettierrc │ ├── CHANGELOG.md │ ├── README.md │ ├── app │ ├── favicon.ico │ ├── globals.css │ ├── layout.tsx │ └── page.tsx │ ├── components │ ├── AccountsList.test.tsx │ └── AccountsList.tsx │ ├── jest.config.ts │ ├── jest.setup.ts │ ├── next.config.js │ ├── package.json │ ├── postcss.config.js │ ├── public │ ├── next.svg │ └── vercel.svg │ ├── tailwind.config.ts │ ├── tsconfig.json │ └── types.d.ts ├── package.json ├── packages ├── client-react │ ├── .eslintrc.js │ ├── .gitignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── prod-esm.tsconfig.json │ ├── prod.tsconfig.json │ ├── src │ │ ├── components │ │ │ ├── WalletAPIProvider │ │ │ │ ├── context.ts │ │ │ │ ├── helpers.ts │ │ │ │ ├── index.tsx │ │ │ │ └── types.ts │ │ │ └── index.ts │ │ ├── hooks │ │ │ ├── index.ts │ │ │ ├── useAccounts.ts │ │ │ ├── useCapabilities.ts │ │ │ ├── useCurrencies.ts │ │ │ ├── useRequestAccount.ts │ │ │ ├── useSignAndBroadcastTransaction.ts │ │ │ ├── useSignMessage.ts │ │ │ ├── useSignTransaction.ts │ │ │ ├── useUserId.ts │ │ │ ├── useWalletAPIClient.ts │ │ │ └── useWalletInfo.ts │ │ └── index.ts │ ├── tests │ │ └── client-react.spec.ts │ └── tsconfig.json ├── client │ ├── .eslintrc.js │ ├── .gitignore │ ├── .nycrc │ ├── CHANGELOG.md │ ├── CONTRIBUTING.md │ ├── LICENSE │ ├── README.md │ ├── jest.config.ts │ ├── package.json │ ├── prod-esm.tsconfig.json │ ├── prod.tsconfig.json │ ├── src │ │ ├── TransportWalletAPI.ts │ │ ├── WalletAPIClient.ts │ │ ├── index.ts │ │ └── modules │ │ │ ├── Account.ts │ │ │ ├── Bitcoin.ts │ │ │ ├── Currency.ts │ │ │ ├── Custom.ts │ │ │ ├── Device.ts │ │ │ ├── Exchange.ts │ │ │ ├── Message.ts │ │ │ ├── Storage.ts │ │ │ ├── Transaction.ts │ │ │ └── Wallet.ts │ ├── tests │ │ └── client.spec.ts │ └── tsconfig.json ├── core │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── jest.config.ts │ ├── package.json │ ├── prod-esm.tsconfig.json │ ├── prod.tsconfig.json │ ├── src │ │ ├── JSONRPC │ │ │ ├── RPCError.ts │ │ │ ├── RpcNode.ts │ │ │ ├── helpers.ts │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── validation.ts │ │ ├── accounts │ │ │ ├── index.ts │ │ │ ├── serializers.ts │ │ │ ├── types.ts │ │ │ └── validation.ts │ │ ├── currencies │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── validation.ts │ │ ├── errors │ │ │ ├── ServerError.ts │ │ │ ├── creators.ts │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── families │ │ │ ├── algorand │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── aptos │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── bitcoin │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── cardano │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── casper │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── celo │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── common.ts │ │ │ ├── cosmos │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── crypto_org │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── elrond │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── ethereum │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── filecoin │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── hedera │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── index.ts │ │ │ ├── internet_computer │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── near │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── neo │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── polkadot │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── ripple │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── serializer.ts │ │ │ ├── solana │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── stacks │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── stellar │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── sui │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── tezos │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── ton │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── tron │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ │ ├── types.ts │ │ │ ├── validation.ts │ │ │ └── vechain │ │ │ │ ├── serializer.ts │ │ │ │ ├── types.ts │ │ │ │ └── validation.ts │ │ ├── index.ts │ │ ├── logger │ │ │ └── index.ts │ │ ├── spec │ │ │ ├── index.ts │ │ │ ├── methods.ts │ │ │ ├── rpcHandlers │ │ │ │ ├── AppHandlers.ts │ │ │ │ └── WalletHandlers.ts │ │ │ └── types │ │ │ │ ├── AccountList.ts │ │ │ │ ├── AccountReceive.ts │ │ │ │ ├── AccountRequest.ts │ │ │ │ ├── BitcoinGetAddress.ts │ │ │ │ ├── BitcoinGetPublicKey.ts │ │ │ │ ├── BitcoinGetXPub.ts │ │ │ │ ├── CurrencyList.ts │ │ │ │ ├── CustomRequest.ts │ │ │ │ ├── Device.ts │ │ │ │ ├── DeviceClose.ts │ │ │ │ ├── DeviceExchange.ts │ │ │ │ ├── DeviceOpen.ts │ │ │ │ ├── DeviceSelect.ts │ │ │ │ ├── DeviceTransport.ts │ │ │ │ ├── ExchangeComplete.ts │ │ │ │ ├── ExchangeStart.ts │ │ │ │ ├── MessageSign.ts │ │ │ │ ├── StorageGet.ts │ │ │ │ ├── StorageSet.ts │ │ │ │ ├── TransactionSign.ts │ │ │ │ ├── TransactionSignAndBroadcast.ts │ │ │ │ ├── WalletCapabilities.ts │ │ │ │ ├── WalletInfo.ts │ │ │ │ ├── WalletUserId.ts │ │ │ │ └── index.ts │ │ ├── transports │ │ │ ├── WindowMessageTransport.ts │ │ │ ├── index.ts │ │ │ └── types.ts │ │ └── types │ │ │ └── index.ts │ ├── tests │ │ ├── serializers.spec.ts │ │ ├── ton-serializers.spec.ts │ │ └── transports │ │ │ └── windowMessageTransport.spec.ts │ └── tsconfig.json ├── eslint-config-custom │ ├── index.js │ ├── next.js │ └── package.json ├── jest-shared-config │ ├── jest-preset.js │ └── package.json ├── manifest-validator-cli │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── prod.tsconfig.json │ ├── src │ │ └── cli.ts │ └── tsconfig.json ├── manifest-validator │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── jest.config.ts │ ├── package.json │ ├── prod-esm.tsconfig.json │ ├── prod.tsconfig.json │ ├── src │ │ ├── index.ts │ │ ├── schema │ │ │ └── schema.ts │ │ └── validator.ts │ ├── tests │ │ ├── .eslintrc.js │ │ ├── manifests │ │ │ ├── dapp │ │ │ │ ├── dapp-manifest.test.json │ │ │ │ └── invalid-dapp-manifest.test.json │ │ │ ├── nativeDapp │ │ │ │ ├── invalid-nativeDapp-manifest.test.json │ │ │ │ └── nativeDapp-manifest.test.json │ │ │ └── walletApp │ │ │ │ ├── invalid-walletApp-manifest.test.json │ │ │ │ └── walletApp-manifest.test.json │ │ └── validator.test.ts │ └── tsconfig.json ├── server │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── jest.config.ts │ ├── package.json │ ├── prod-esm.tsconfig.json │ ├── prod.tsconfig.json │ ├── src │ │ ├── WalletAPIServer.ts │ │ ├── helpers.ts │ │ ├── index.ts │ │ ├── internalHandlers │ │ │ ├── account.ts │ │ │ ├── bitcoin.ts │ │ │ ├── currency.ts │ │ │ ├── custom.ts │ │ │ ├── device.ts │ │ │ ├── exchange.ts │ │ │ ├── index.ts │ │ │ ├── message.ts │ │ │ ├── storage.ts │ │ │ ├── transaction.ts │ │ │ └── wallet.ts │ │ ├── react.ts │ │ └── types.ts │ ├── tests │ │ └── server.spec.ts │ └── tsconfig.json └── simulator │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── jest.config.ts │ ├── package.json │ ├── prod-esm.tsconfig.json │ ├── prod.tsconfig.json │ ├── src │ ├── helpers.ts │ ├── index.ts │ ├── profiles │ │ ├── device │ │ │ └── index.ts │ │ ├── index.ts │ │ └── standard │ │ │ ├── accounts.json │ │ │ ├── currencies.json │ │ │ └── index.ts │ ├── test-run.ts │ ├── transport.ts │ ├── types.ts │ └── ws.ts │ ├── tests │ ├── server.spec.ts │ └── simulator.spec.ts │ └── tsconfig.json ├── patches └── @ton__core.patch ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── renovate.json ├── rfc ├── README.md └── rfc-template.md ├── spec ├── README.md ├── client │ └── README.md ├── core │ ├── README.md │ ├── errors.md │ ├── families.md │ ├── manifest.md │ └── types.md ├── rpc │ └── README.md └── server │ └── README.md ├── tsconfig.base.json └── turbo.json /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.1.1/schema.json", 3 | "changelog": [ 4 | "@changesets/changelog-github", 5 | { 6 | "repo": "LedgerHQ/wallet-api" 7 | } 8 | ], 9 | "commit": false, 10 | "fixed": [], 11 | "linked": [], 12 | "access": "public", 13 | "baseBranch": "main", 14 | "updateInternalDependencies": "patch", 15 | "ignore": [] 16 | } 17 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | // This tells ESLint to load the config from the package `@ledgerhq/eslint-config-custom` 4 | extends: ["@ledgerhq/eslint-config-custom"], 5 | }; 6 | -------------------------------------------------------------------------------- /.github/workflows/pull_request.yml: -------------------------------------------------------------------------------- 1 | name: Pull Request Checks 2 | on: pull_request 3 | 4 | jobs: 5 | checks: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v4 9 | - uses: pnpm/action-setup@v4 10 | with: 11 | run_install: false 12 | - uses: actions/setup-node@v4 13 | with: 14 | node-version: 20 15 | cache: pnpm 16 | - name: Install Dependencies 17 | run: pnpm install --frozen-lockfile 18 | - name: Format check 19 | run: pnpm format:check 20 | - name: Build 21 | run: pnpm build 22 | - name: Check for diff in docs 23 | run: git diff --exit-code || exit 1 24 | - name: Lint 25 | run: pnpm lint 26 | - name: Test 27 | run: pnpm test 28 | # - name: Uploading to codecov.io 29 | # run: npx codecov 30 | # env: 31 | # CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 32 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | concurrency: ${{ github.workflow }}-${{ github.ref }} 9 | 10 | jobs: 11 | release: 12 | name: Release 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | - uses: pnpm/action-setup@v2 17 | with: 18 | run_install: false 19 | - uses: actions/setup-node@v4 20 | with: 21 | node-version: 20 22 | cache: pnpm 23 | - name: Install Dependencies 24 | run: pnpm install --frozen-lockfile 25 | - name: Create Release Pull Request or Publish to npm 26 | id: changesets 27 | uses: changesets/action@v1 28 | with: 29 | # This expects you to have a script called release which does a build for your packages and calls changeset publish 30 | publish: pnpm publish-packages 31 | env: 32 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 33 | NPM_TOKEN: ${{ secrets.NPMJS_TOKEN }} 34 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: Tag Stale PRs and Issues 2 | on: 3 | schedule: 4 | - cron: "20 4 * * *" 5 | 6 | jobs: 7 | stale: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/stale@v9 11 | with: 12 | stale-issue-message: "This issue is stale because it has been open 30 days with no activity. Remove stale label, comment, or consider closing it." 13 | days-before-issue-stale: 30 14 | stale-pr-message: "There as been no activity on this PR for the last 14 days. Please consider closing this PR." 15 | days-before-pr-stale: 15 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | .pnp 6 | .pnp.js 7 | 8 | # testing 9 | coverage 10 | 11 | # next.js 12 | .next/ 13 | out/ 14 | build 15 | 16 | # misc 17 | .DS_Store 18 | *.pem 19 | 20 | # debug 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | .pnpm-debug.log* 25 | 26 | # local env files 27 | .env.local 28 | .env.development.local 29 | .env.test.local 30 | .env.production.local 31 | 32 | # turbo 33 | .turbo 34 | 35 | # build folder 36 | dist/ 37 | bin/ 38 | lib/ 39 | lib-es/ 40 | 41 | # eslint cache 42 | .eslintcache 43 | 44 | # ide 45 | .idea -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | pnpm lint-staged 2 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 20.11.1 -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution Guidelines 2 | 3 | 👍🎉 First off, thanks for taking the time to contribute! 🎉👍 4 | 5 | The following is a set of guidelines for contributing to this project. These are mostly guidelines, not rules. Use your best judgment, and feel free to suggest changes to this doc [here](https://github.com/LedgerHQ/wallet-api/discussions/categories/ideas). 6 | 7 | We are leveraging [GitHub Discussions](https://github.com/LedgerHQ/wallet-api/discussions) to talk about all contributions 8 | 9 | - if you think you found a bug, please take it to the [**Q&A**](https://github.com/LedgerHQ/wallet-api/discussions/categories/q-a) category with the ``bug`` label 10 | - if you want to propose an improvements, please take it to [**Ideas**](https://github.com/LedgerHQ/wallet-api/discussions/categories/ideas) category with the ``enhancement`` label 11 | - if you simply have a question, please take it to [**Q&A**](https://github.com/LedgerHQ/wallet-api/discussions/categories/q-a) category with the ``question`` label 12 | 13 | Once discussion is taken and settled, an issue and/or a PR might be created to address it. 14 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | | Version | Supported | 6 | | ------- | ------------------ | 7 | | 1.0.x | :white_check_mark: | 8 | | < 1.0 | :x: | 9 | 10 | ## Reporting a Vulnerability 11 | 12 | Security vulnerabilies are to be reported to Ledger Donjon security team: https://donjon.ledger.com/bounty/ 13 | -------------------------------------------------------------------------------- /apps/docs/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@ledgerhq/eslint-config-custom/next"], 3 | parserOptions: { 4 | project: ["./tsconfig.json"], 5 | tsconfigRootDir: __dirname, 6 | babelOptions: { 7 | presets: [require.resolve("next/babel")], // https://github.com/vercel/next.js/issues/40687#issuecomment-1264177674 8 | }, 9 | }, 10 | rules: {}, 11 | }; 12 | -------------------------------------------------------------------------------- /apps/docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @ledgerhq/wallet-api-docs 2 | 3 | ## 0.3.0 4 | 5 | ### Minor Changes 6 | 7 | - [`de70134`](https://github.com/LedgerHQ/wallet-api/commit/de70134eac5d0b68ee38debcf597da954e233aa1) Thanks [@ComradeAERGO](https://github.com/ComradeAERGO)! - Add missing link 8 | 9 | - [#237](https://github.com/LedgerHQ/wallet-api/pull/237) [`f897a3d`](https://github.com/LedgerHQ/wallet-api/commit/f897a3dd0553a02e3fd8358098de2ac9c6b7d73c) Thanks [@Justkant](https://github.com/Justkant)! - feat: add custom handlers support 10 | 11 | ## 0.2.0 12 | 13 | ### Minor Changes 14 | 15 | - [`f1b8f8c`](https://github.com/LedgerHQ/wallet-api/commit/f1b8f8c51689885cc0f9b8ff29f38c25392e095e) Thanks [@Justkant](https://github.com/Justkant)! - feat: add params to save swap history (#228) 16 | -------------------------------------------------------------------------------- /apps/docs/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /apps/docs/next.config.js: -------------------------------------------------------------------------------- 1 | const withNextra = require("nextra")({ 2 | defaultShowCopyCode: true, 3 | theme: "nextra-theme-docs", 4 | themeConfig: "./theme.config.tsx", 5 | }); 6 | 7 | module.exports = withNextra(); 8 | -------------------------------------------------------------------------------- /apps/docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ledgerhq/wallet-api-docs", 3 | "version": "0.3.0", 4 | "description": "", 5 | "private": true, 6 | "scripts": { 7 | "build": "next build", 8 | "dev": "next dev", 9 | "start": "next start", 10 | "lint": "next lint" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "dependencies": { 16 | "autoprefixer": "^10.4.17", 17 | "next": "^14.1.0", 18 | "nextra": "^2.13.3", 19 | "nextra-theme-blog": "^2.13.3", 20 | "nextra-theme-docs": "^2.13.3", 21 | "postcss": "^8.4.35", 22 | "react": "^18.2.0", 23 | "react-dom": "^18.2.0", 24 | "tailwindcss": "^3.4.1" 25 | }, 26 | "devDependencies": { 27 | "@types/node": "^20.11.19", 28 | "typescript": "^5.3.3" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /apps/docs/pages/_app.mdx: -------------------------------------------------------------------------------- 1 | import "../style.css"; 2 | 3 | export default function App({ Component, pageProps }) { 4 | return 5 | } 6 | -------------------------------------------------------------------------------- /apps/docs/pages/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "index": { 3 | "title": "Home", 4 | "theme": { 5 | "layout": "raw" 6 | }, 7 | "display": "hidden" 8 | }, 9 | "docs": { 10 | "title": "Documentation", 11 | "type": "page" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "discover": "Discover" 3 | } 4 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "guidelines": "Submission guidelines", 3 | "required-skills": "Required programming skills", 4 | "dapp-browser": "DApp Browser", 5 | "wallet-api": "Wallet API", 6 | "developer-mode": "Enabling the developer mode", 7 | "faq": "Frequently Asked Questions" 8 | } -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/dapp-browser.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: How to add a DApp with the DApp Browser? 3 | --- 4 | 5 | # How to add a DApp with the DApp Browser v3 ? 6 | 7 | To integrate a DApp with the DApp Browser, you need to: 8 | 9 | - Read the [submission guidelines](./guidelines) 10 | - Update [your DApp](./dapp-browser/dapp-customisation/) 11 | - Write a [manifest](./dapp-browser/manifest/) 12 | - Create a [DApp Plugin](./dapp-browser/plugin/) 13 | 14 | # Already using the DApp Browser ? 15 | 16 | We are in the process of deprecating the DApp Browser live-app v1 and v2. 17 | 18 | Ledger Live will now support injecting a compatible provider in the webview. 19 | 20 | You can follow our [migration documentation](./dapp-browser/migration/) to update your dApp 21 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/dapp-browser/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "dapp-customisation": "Update your DApp", 3 | "manifest": "Write and load the manifest", 4 | "plugin": "Write a plugin for clear signing", 5 | "migration": "DApp Browser migration" 6 | } 7 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/dapp-browser/plugin.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Write a plugin for clear signing 3 | --- 4 | 5 | # Write a plugin for clear signing 6 | 7 | The plugin will enable clear signing on smart contracts and ensure more security for our users. 8 | 9 | To develop a plugin, follow the documentation in [the Plugin section](/docs/device-app/introduction/plugins/) of the Developer Portal. 10 | 11 | # Reference the plugin in the manifest 12 | 13 | When the plugin is available you can add it to the manifest in the field [`dapp.nanoApp`](./manifest#here-is-the-list-of-the-mandatory-fields-required-in-your-manifest-file) 14 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/faq.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Frequently asked questions 3 | --- 4 | 5 | # Frequently Asked Questions 6 | 7 | | Question | Answer | 8 | | --------------- | -------------- | 9 | | Is there a recommended big number library? | Yes, [bignumber.js](https://www.npmjs.com/package/bignumber.js) | 10 | | What are the graphics design recommendations in terms of look/color/font? | Your app should have your own identity. Please don't use Ledger's. | 11 | | Is there a Ledger Live API to programmatically manage your accounts balances and transactions? | No, there is no such API. The APIs provided in the Live App SDK only allow you to integrate an application into the Ledger Live ecosystem. | 12 | | How is the theme passed to the Live App | We use the URL query param **theme** that can take value **dark** or **light** | 13 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/required-skills.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Required programming skills 3 | --- 4 | 5 | # Required programming skills 6 | 7 | | Development step | Required skills | 8 | |------------------------------------------|---------------------------------------------------| 9 | | Live App | JavaScript and TypeScript | 10 | | Embedded Plugin (For DApps only) | [Bolos](../device-app/bolos) and C | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: How to add a DApp with the Wallet API? 3 | --- 4 | 5 | # How to add a DApp with the Wallet API? 6 | 7 | To integrate a DApp with the Wallet API, you need to: 8 | 9 | - Read the [submission guidelines](./guidelines) 10 | - Use the [Wallet API](./wallet-api/introduction) 11 | - Write a manifest as explained in the [Wallet API documentation](./wallet-api/appendix/manifest) 12 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "introduction": "Introduction", 3 | "react": "React", 4 | "core": "Core", 5 | "simulator": "Simulator", 6 | "examples": "Examples", 7 | "appendix": "Appendix", 8 | "server": "Server" 9 | } 10 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/appendix/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest": "Manifest", 3 | "transaction": { 4 | "title": "Transaction", 5 | "theme": { 6 | "toc": true 7 | } 8 | }, 9 | "migration-guide": { 10 | "title": "Migration Guide", 11 | "theme": { 12 | "toc": true 13 | } 14 | }, 15 | "families": { 16 | "title": "Families", 17 | "theme": { 18 | "toc": true 19 | } 20 | }, 21 | "working-with-ledger-live": { 22 | "title": "Working with Ledger Live", 23 | "theme": { 24 | "toc": true 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/core/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "getting-started": { 3 | "title": "Getting Started", 4 | "theme": { 5 | "toc": true 6 | } 7 | }, 8 | "configuration": { 9 | "title": "Configuration", 10 | "theme": { 11 | "toc": true 12 | } 13 | }, 14 | "modules": "Modules" 15 | } 16 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/core/getting-started.mdx: -------------------------------------------------------------------------------- 1 | # Getting Started with Ledger's Wallet API 2 | 3 | Welcome to the getting started guide for Ledger's Wallet API. We are excited to have you onboard and look forward to 4 | seeing what you'll create. 5 | 6 | Ledger's Wallet API can be integrated with both client and server-side applications, offering you flexibility and 7 | enabling diverse use-cases. 8 | 9 | ## Installation 10 | 11 | Let's begin by installing the base package. 12 | 13 | You can use your favorite package manager, to install the `@ledgerhq/wallet-api-client` package. 14 | 15 | ```sh npm2yarn 16 | npm install @ledgerhq/wallet-api-client 17 | ``` 18 | 19 | --- 20 | 21 | Now that you've successfully installed the necessary packages, you're ready to start crafting with Ledger's Wallet 22 | API. In the next page, we'll guide you through the process of setting up and configuring the Wallet API in your 23 | application. 24 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/core/modules/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "account": { 3 | "title": "Account", 4 | "theme": { 5 | "toc": true 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/examples/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "live-app-creation": { 3 | "title": "Build a live app from scratch" 4 | }, 5 | "use-live-app": { 6 | "title": "Use your live app" 7 | }, 8 | "test-live-app": { 9 | "title": "Test your live app" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/examples/live-app-creation/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "start": "Start here", 3 | "configuration": "Configuration", 4 | "hooking-up": "Hooking up", 5 | "manifest": "Import your app in Ledger Live" 6 | } 7 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/examples/test-live-app/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "prerequisites": "Prerequisites", 3 | "testing": "Testing" 4 | } 5 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/examples/test-live-app/assets/3-1-developer-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LedgerHQ/wallet-api/e81e17f1a1e0d03aadc8224fa0be6e42340c150d/apps/docs/pages/docs/discover/wallet-api/examples/test-live-app/assets/3-1-developer-mode.png -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/examples/test-live-app/assets/3-2-dev-tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LedgerHQ/wallet-api/e81e17f1a1e0d03aadc8224fa0be6e42340c150d/apps/docs/pages/docs/discover/wallet-api/examples/test-live-app/assets/3-2-dev-tools.png -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/examples/test-live-app/assets/3-3-browse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LedgerHQ/wallet-api/e81e17f1a1e0d03aadc8224fa0be6e42340c150d/apps/docs/pages/docs/discover/wallet-api/examples/test-live-app/assets/3-3-browse.png -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/examples/test-live-app/assets/3-4-local-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LedgerHQ/wallet-api/e81e17f1a1e0d03aadc8224fa0be6e42340c150d/apps/docs/pages/docs/discover/wallet-api/examples/test-live-app/assets/3-4-local-app.png -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/examples/test-live-app/assets/4-1-open-local-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LedgerHQ/wallet-api/e81e17f1a1e0d03aadc8224fa0be6e42340c150d/apps/docs/pages/docs/discover/wallet-api/examples/test-live-app/assets/4-1-open-local-app.png -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/examples/test-live-app/prerequisites.mdx: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | 3 | This tutorial assumes that you already have your Live App using the Wallet-API package. 4 | 5 | To start we'll need at least: 6 | 7 | - To setup the simulator as shown in the [documentation](../../simulator/configuration) 8 | - And have a test environment in place like jest or vitest 9 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/examples/test-live-app/testing.mdx: -------------------------------------------------------------------------------- 1 | import { Callout } from "nextra/components"; 2 | 3 | # Automated testing 4 | 5 | 6 | Docs for this is under construction. 7 | 8 | 9 | In order to test your Live App in an automated way, you will first need to create a test file. 10 | 11 | Here is a simple example of a test file written for a Live App: 12 | 13 | ```ts 14 | describe("List accounts", () => { 15 | test("It should show the list of accounts when clicking the button", () => {}); 16 | }); 17 | ``` 18 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/examples/use-live-app/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "prerequisites": "Prerequisites", 3 | "manifest": "Create a manifest", 4 | "import": "Import your manifest", 5 | "interact": "Interact with Developer tools" 6 | } 7 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/examples/use-live-app/assets/3-1-developer-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LedgerHQ/wallet-api/e81e17f1a1e0d03aadc8224fa0be6e42340c150d/apps/docs/pages/docs/discover/wallet-api/examples/use-live-app/assets/3-1-developer-mode.png -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/examples/use-live-app/assets/3-2-dev-tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LedgerHQ/wallet-api/e81e17f1a1e0d03aadc8224fa0be6e42340c150d/apps/docs/pages/docs/discover/wallet-api/examples/use-live-app/assets/3-2-dev-tools.png -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/examples/use-live-app/assets/3-3-browse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LedgerHQ/wallet-api/e81e17f1a1e0d03aadc8224fa0be6e42340c150d/apps/docs/pages/docs/discover/wallet-api/examples/use-live-app/assets/3-3-browse.png -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/examples/use-live-app/assets/3-4-local-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LedgerHQ/wallet-api/e81e17f1a1e0d03aadc8224fa0be6e42340c150d/apps/docs/pages/docs/discover/wallet-api/examples/use-live-app/assets/3-4-local-app.png -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/examples/use-live-app/assets/4-1-open-local-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LedgerHQ/wallet-api/e81e17f1a1e0d03aadc8224fa0be6e42340c150d/apps/docs/pages/docs/discover/wallet-api/examples/use-live-app/assets/4-1-open-local-app.png -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/examples/use-live-app/import.mdx: -------------------------------------------------------------------------------- 1 | # Import your manifest in Ledger Live 2 | 3 | If not done already, you must have Ledger Live Desktop installed on your computer. Head over to the [download page](https://www.ledger.com/ledger-live/download) to get started. 4 | 5 | You also need your Ledger Device (Nano S or X) in order to access Ledger Live. 6 | 7 | In order to add a local manifest to Ledger Live and run a not yet available Live App, you must enable the Developer mode. 8 | 9 | To activate the Developer mode in Ledger Live, go to : 10 | 11 | 1. **Settings** -> **About** 12 | 2. Click ten times on the Ledger Live version. 13 | 14 | You will then see a new **Developer** section in the settings menu. 15 | 16 | ![developer-mode](./assets/3-1-developer-mode.png) 17 | 18 | Once done, make sure to turn on **Enable platform dev tools** as it will allow you to open a browser-like developer tools window to inspect your app. 19 | 20 | ![dev-tools](./assets/3-2-dev-tools.png) 21 | 22 | Then click on **Browse** next to **Add a local app** and select the manifest you created in the [previous section](./manifest.mdx). 23 | 24 | ![browse](./assets/3-3-browse.png) 25 | 26 | You will then see a new row in the menu with the name of your Live App. 27 | 28 | ![local-app](./assets/3-4-local-app.png) 29 | 30 | Now that you have added your Live App in your local Ledger Live application, it’s time to open it and test it. 31 | 32 | We’ll see this in the next section. 33 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/examples/use-live-app/interact.mdx: -------------------------------------------------------------------------------- 1 | # Interact with Developer tools 2 | 3 | Before proceeding with the following steps, make sure you have at least one Ethereum account created. Head over to [this page](https://support.ledger.com/hc/en-us/articles/4404389482641-Add-your-accounts?docs=true) for more informations regarding the procedure to add a cryptoasset account inside of Ledger Live. 4 | 5 | Now that you have added your Live App inside your local Ledger Live application and have added an Ethereum account, it’s finally time to open your Live App. 6 | 7 | To do so, click on **Open** next to your local Live App name in the developer menu. 8 | 9 | ![open-local-app](./assets/4-1-open-local-app.png) 10 | 11 | This will open your Live App inside of Ledger Live for you to interact with and test. 12 | 13 | 💡 Tips : Click on **Dev tools** in order to open a browser-like developer tools window. -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/examples/use-live-app/prerequisites.mdx: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | 3 | This tutorial assumes that you already have your dapp using the wallet-api package. 4 | 5 | To start will need at least : 6 | 7 | - a [Ledger Device](https://shop.ledger.com/pages/hardware-wallets-comparison) (Nano S or X). You will need one to access Ledger Live. 8 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/react/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "getting-started": { 3 | "title": "Getting Started", 4 | "theme": { 5 | "toc": true 6 | } 7 | }, 8 | "configuration": { 9 | "title": "Configuration", 10 | "theme": { 11 | "toc": true 12 | } 13 | }, 14 | "hooks": "Hooks" 15 | } 16 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/react/hooks/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "useAccounts": { 3 | "title": "useAccounts", 4 | "theme": { 5 | "toc": true 6 | } 7 | }, 8 | "useCurrencies": { 9 | "title": "useCurrencies", 10 | "theme": { 11 | "toc": true 12 | } 13 | }, 14 | "useCapabilities": { 15 | "title": "useCapabilities", 16 | "theme": { 17 | "toc": true 18 | } 19 | }, 20 | "useUserId": { 21 | "title": "useUserId", 22 | "theme": { 23 | "toc": true 24 | } 25 | }, 26 | "useWalletInfo": { 27 | "title": "useWalletInfo", 28 | "theme": { 29 | "toc": true 30 | } 31 | }, 32 | "useRequestAccount": { 33 | "title": "useRequestAccount", 34 | "theme": { 35 | "toc": true 36 | } 37 | }, 38 | "useSignMessage": { 39 | "title": "useSignMessage", 40 | "theme": { 41 | "toc": true 42 | } 43 | }, 44 | "useSignTransaction": { 45 | "title": "useSignTransaction", 46 | "theme": { 47 | "toc": true 48 | } 49 | }, 50 | "useSignAndBroadcastTransaction": { 51 | "title": "useSignAndBroadcastTransaction", 52 | "theme": { 53 | "toc": true 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/server/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "index": { 3 | "title": "Introduction", 4 | "theme": { 5 | "breadcrumb": false, 6 | "footer": true, 7 | "sidebar": true, 8 | "toc": true 9 | } 10 | }, 11 | "wallet-api-server": { 12 | "title": "Wallet API Server", 13 | "theme": { 14 | "toc": true 15 | } 16 | }, 17 | "usage-examples": "Usage examples", 18 | "handlers": "Handlers", 19 | "extras": "Extras" 20 | } 21 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/server/assets/diagram-permissions-1-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LedgerHQ/wallet-api/e81e17f1a1e0d03aadc8224fa0be6e42340c150d/apps/docs/pages/docs/discover/wallet-api/server/assets/diagram-permissions-1-light.png -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/server/assets/diagram-request-handlers-1-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LedgerHQ/wallet-api/e81e17f1a1e0d03aadc8224fa0be6e42340c150d/apps/docs/pages/docs/discover/wallet-api/server/assets/diagram-request-handlers-1-dark.png -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/server/assets/diagram-request-handlers-1-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LedgerHQ/wallet-api/e81e17f1a1e0d03aadc8224fa0be6e42340c150d/apps/docs/pages/docs/discover/wallet-api/server/assets/diagram-request-handlers-1-light.png -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/server/assets/diagram-request-handlers-2-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LedgerHQ/wallet-api/e81e17f1a1e0d03aadc8224fa0be6e42340c150d/apps/docs/pages/docs/discover/wallet-api/server/assets/diagram-request-handlers-2-light.png -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/server/assets/diagram-transport-1-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LedgerHQ/wallet-api/e81e17f1a1e0d03aadc8224fa0be6e42340c150d/apps/docs/pages/docs/discover/wallet-api/server/assets/diagram-transport-1-light.png -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/server/assets/diagram-wallet-handlers-1-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LedgerHQ/wallet-api/e81e17f1a1e0d03aadc8224fa0be6e42340c150d/apps/docs/pages/docs/discover/wallet-api/server/assets/diagram-wallet-handlers-1-light.png -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/server/assets/server-rpc-node-classdiagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LedgerHQ/wallet-api/e81e17f1a1e0d03aadc8224fa0be6e42340c150d/apps/docs/pages/docs/discover/wallet-api/server/assets/server-rpc-node-classdiagram.png -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/server/handlers/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "account": { 3 | "title": "Account", 4 | "theme": { 5 | "toc": true 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/server/handlers/bitcoin.mdx: -------------------------------------------------------------------------------- 1 | ## overview 2 | 3 | The Bitcoin handler allows the server to interact with Bitcoin accounts. 4 | Specifically, you can retrieve the extended public key (xPub) of a Bitcoin account. 5 | This is useful for deriving Bitcoin addresses without revealing the private key. 6 | 7 | ## request handlers: 8 | 9 | ### "bitcoin.getXPub" - Get Extended Public Key (xPub) 10 | 11 | | parameter (in req.params) | required? | note | 12 | | ------------------------- | --------- | -------------------------------------------------------------------- | 13 | | _accountId_ | ✅ | The ID of the Bitcoin account for which the xPub is to be retrieved. | 14 | 15 | | walletHandler used | note | 16 | | ------------------ | -------------------------------------------------------- | 17 | | _bitcoin.getXPub_ | Should retrieve the xPub of a particular bitcoin account | 18 | 19 | - Gets the xPub of a bitcoin account with _bitcoin.getXPub_ walletHandler 20 | - **Returns**: A promise that resolves with the xPub as a string. 21 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/server/handlers/currency.mdx: -------------------------------------------------------------------------------- 1 | ## overview 2 | 3 | The Currency handlers enables interaction with various cryptocurrencies that are supported by the connected wallet. 4 | The server can list the cryptocurrencies and apply filters by name or ticker. 5 | 6 | ## request handlers: 7 | 8 | ### "currency.list" - List Cryptocurrencies 9 | 10 | | parameter (in req.params) | required? | note | 11 | | ------------------------- | --------- | ------------------------------------------------------------------------------- | 12 | | _currencyIds_ | ❌ | An array of strings specifying the currency IDs to filter the cryptocurrencies. | 13 | 14 | - Start with all currencies (available in [context.currencies](../wallet-api-server#walletcontextcurrencies)) 15 | - Filter those against the parameter _currencyIds_ 16 | - **Returns**: A promise that resolves with an array of Currency objects. 17 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/server/handlers/wallet.mdx: -------------------------------------------------------------------------------- 1 | ## overview 2 | 3 | The Wallet handlers allows you to interact with the user's wallet. 4 | This includes retrieving the user's ID, fetching wallet information, and listing the capabilities of the wallet. 5 | 6 | ## request handlers: 7 | 8 | ### "wallet.capabilities" 9 | 10 | List the method IDs that are implemented by the wallet. (ie. the [walletHandlers](../wallet-api-server#wallethandlers) method names) 11 | 12 | - **Returns**: A promise that resolves with an array of strings representing the method IDs. 13 | 14 | ### "wallet.userId" 15 | 16 | Retrieve the user ID of the connected wallet. 17 | 18 | - Fetches the user ID stored in [walletContext.config](../wallet-api-server#walletcontextconfig) 19 | - **Returns**: A promise that resolves with the user ID as a string. 20 | 21 | ### "wallet.info" 22 | 23 | Retrieve information about the connected wallet. 24 | 25 | - Fetches the wallet info stored in [walletContext.config](../wallet-api-server#walletcontextconfig) 26 | - **Returns**: A promise that resolves with an object containing information about the connected wallet. 27 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/server/wallet-api-server/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "index": { 3 | "title": "Wallet API Server", 4 | "theme": { 5 | "sidebar": true, 6 | "toc": true 7 | } 8 | }, 9 | "diagrams": { 10 | "title": "Diagrams", 11 | "theme": { 12 | "sidebar": true, 13 | "toc": false 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/server/wallet-api-server/diagrams.mdx: -------------------------------------------------------------------------------- 1 | import { Callout } from "nextra/components"; 2 | import { Bleed } from "nextra-theme-docs"; 3 | import Image from "next/image"; 4 | 5 | ## Slideshow 6 | 7 | A slideshow introducing the different part of the server is available [here](https://link.excalidraw.com/p/readonly/cU4iVB5H8XFM7eW7S7u4) 8 | 9 | ## Diagrams 10 | 11 | 12 | Those diagrams come from this introductory 13 | [slideshow](https://link.excalidraw.com/p/readonly/cU4iVB5H8XFM7eW7S7u4) and 14 | are slightly reworked to be understood as standalone diagrams. 15 | 16 | 17 | ### 1. a basic way to allow wallet-application interaction 18 | 19 | ![diagram](../assets/diagram-request-handlers-1-light.png) 20 | 21 | ### 2. process requests with requestHandlers 22 | 23 | ![diagram](../assets/diagram-request-handlers-2-light.png) 24 | 25 | ### 3. ask wallet for data / actions with walletHandlers 26 | 27 | ![diagram](../assets/diagram-wallet-handlers-1-light.png) 28 | 29 | ### 4. handle bidirectional communication 30 | 31 | ![diagram](../assets/diagram-transport-1-light.png) 32 | 33 | ### 4. data passed from wallet to the server (accounts, currencies, config) and permissions 34 | 35 | ![diagram](../assets/diagram-permissions-1-light.png) 36 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/simulator/_meta.json: -------------------------------------------------------------------------------- 1 | {"introduction": { 2 | "title": "introduction", 3 | "theme": { 4 | "toc": true 5 | } 6 | }, 7 | 8 | "getting-started": { 9 | "title": "Getting Started", 10 | "theme": { 11 | "toc": true 12 | } 13 | }, 14 | "configuration": { 15 | "title": "Configuration", 16 | "theme": { 17 | "toc": true 18 | } 19 | }, 20 | "profiles": { 21 | "title": "Profiles", 22 | "theme": { 23 | "toc": true 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /apps/docs/pages/docs/discover/wallet-api/simulator/getting-started.mdx: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | In this guide, we will walk through how to set up the Ledger Wallet API simulator to connect the client to a mock environment, instead of the real Ledger Live environment. 4 | 5 | This is especially helpful during development and testing phases, where you might not want to perform actions on the real Ledger Live. 6 | 7 | ## Installation 8 | 9 | Let's begin by installing the base package. 10 | 11 | You can use your favorite package manager, npm, yarn or pnpm, to install the `@ledgerhq/wallet-api-simulator` package. 12 | 13 | ```sh npm2yarn 14 | npm install @ledgerhq/wallet-api-simulator 15 | ``` 16 | 17 | --- 18 | 19 | Now that you've successfully installed the necessary packages, you're ready to start crafting with Ledger's Wallet 20 | API. In the next page, we'll guide you through the process of setting up and configuring the Wallet API in your 21 | application. 22 | -------------------------------------------------------------------------------- /apps/docs/pages/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Ledger Live Apps Documentation 3 | --- 4 | 5 | export function Card({ title, description, link, icon }) { 6 | return ( 7 |
8 |
{icon}
9 |
{title}
10 |

{description}

11 | Explore 12 |
13 | ); 14 | } 15 | 16 | export function Hero() { 17 | return ( 18 |
19 |

Build Live Apps with Ledger Live

20 |

Seamlessly integrate your applications into Ledger Live with our Wallet API.

21 |
22 | ); 23 | } 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /apps/docs/postcss.config.js: -------------------------------------------------------------------------------- 1 | // If you want to use other PostCSS plugins, see the following: 2 | // https://tailwindcss.com/docs/using-with-preprocessors 3 | /** @type {import("postcss").Postcss} */ 4 | module.exports = { 5 | plugins: { 6 | tailwindcss: {}, 7 | autoprefixer: {}, 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /apps/docs/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import("tailwindcss").Config} */ 2 | module.exports = { 3 | content: ["./pages/**/*.{js,ts,jsx,tsx,mdx}", "./theme.config.tsx"], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [], 8 | darkMode: "class", 9 | }; 10 | -------------------------------------------------------------------------------- /apps/docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "parserOptions": { 3 | "project": "./tsconfig.json" 4 | }, 5 | "compilerOptions": { 6 | "baseUrl": ".", 7 | "target": "es5", 8 | "lib": [ 9 | "dom", 10 | "dom.iterable", 11 | "esnext" 12 | ], 13 | "allowJs": true, 14 | "skipLibCheck": true, 15 | "strict": false, 16 | "forceConsistentCasingInFileNames": true, 17 | "noEmit": true, 18 | "incremental": true, 19 | "esModuleInterop": true, 20 | "isolatedModules": true, 21 | "moduleResolution": "node", 22 | "jsx": "preserve", 23 | "module": "esnext", 24 | "resolveJsonModule": true, 25 | "paths": { 26 | "@components/*": [ 27 | "components/*" 28 | ] 29 | } 30 | }, 31 | "include": [ 32 | "next-env.d.ts", 33 | "**/*.ts", 34 | "**/*.tsx" 35 | ], 36 | "exclude": [ 37 | "node_modules" 38 | ] 39 | } -------------------------------------------------------------------------------- /apps/wallet-api-tools/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@ledgerhq/eslint-config-custom/next"], 3 | parserOptions: { 4 | project: ["./tsconfig.json"], 5 | tsconfigRootDir: __dirname, 6 | babelOptions: { 7 | presets: [require.resolve("next/babel")], // https://github.com/vercel/next.js/issues/40687#issuecomment-1264177674 8 | }, 9 | }, 10 | rules: { 11 | "@typescript-eslint/no-unused-vars": [ 12 | "error", 13 | { ignoreRestSiblings: true }, 14 | ], 15 | }, 16 | }; 17 | -------------------------------------------------------------------------------- /apps/wallet-api-tools/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /apps/wallet-api-tools/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["prettier-plugin-tailwindcss"] 3 | } 4 | -------------------------------------------------------------------------------- /apps/wallet-api-tools/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "../../node_modules/.pnpm/typescript@4.9.4/node_modules/typescript/lib", 3 | "typescript.enablePromptUseWorkspaceTsdk": true, 4 | "editor.quickSuggestions": { 5 | "strings": true 6 | }, 7 | "files.associations": { 8 | "*.css": "tailwindcss" 9 | } 10 | } -------------------------------------------------------------------------------- /apps/wallet-api-tools/app/head.tsx: -------------------------------------------------------------------------------- 1 | export default function Head() { 2 | return ( 3 | <> 4 | 5 | 9 | 10 | 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /apps/wallet-api-tools/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { PropsWithChildren } from "react"; 2 | import "../styles/globals.css"; 3 | import { TopBar } from "./TopBar"; 4 | import Head from "./head"; 5 | 6 | export default function RootLayout({ children }: PropsWithChildren) { 7 | return ( 8 | 9 | 10 | 11 | 12 |
{children}
13 | 14 | 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /apps/wallet-api-tools/app/page.tsx: -------------------------------------------------------------------------------- 1 | import { Suspense } from "react"; 2 | import { Editor } from "../src/Editor"; 3 | 4 | export default function Page() { 5 | return ( 6 | 7 | 8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /apps/wallet-api-tools/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "wallet-api-tools", 3 | "name": "Wallet API Tools", 4 | "url": "http://localhost:3000", 5 | "homepageUrl": "https://developers.ledger.com/", 6 | "icon": "", 7 | "platform": "all", 8 | "apiVersion": "^2.0.0", 9 | "manifestVersion": "1", 10 | "branch": "debug", 11 | "categories": ["tools"], 12 | "currencies": "*", 13 | "content": { 14 | "shortDescription": { 15 | "en": "Try out the Wallet API to test capabilities of our platform integration solution. Use at your own risk." 16 | }, 17 | "description": { 18 | "en": "Try out the Wallet API to test capabilities of our platform integration solution. Use at your own risk." 19 | } 20 | }, 21 | "permissions": [ 22 | "account.list", 23 | "account.receive", 24 | "account.request", 25 | "currency.list", 26 | "device.close", 27 | "device.exchange", 28 | "device.transport", 29 | "message.sign", 30 | "transaction.sign", 31 | "transaction.signAndBroadcast", 32 | "storage.set", 33 | "storage.get", 34 | "bitcoin.getAddress", 35 | "bitcoin.getPublicKey", 36 | "bitcoin.getXPub", 37 | "wallet.capabilities", 38 | "wallet.userId", 39 | "wallet.info" 40 | ], 41 | "domains": ["https://"] 42 | } 43 | -------------------------------------------------------------------------------- /apps/wallet-api-tools/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: false, 4 | experimental: { appDir: true, externalDir: true }, 5 | }; 6 | 7 | module.exports = nextConfig; 8 | -------------------------------------------------------------------------------- /apps/wallet-api-tools/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ledgerhq/wallet-api-tools", 3 | "version": "0.5.11", 4 | "repository": "git@github.com:LedgerHQ/wallet-api.git", 5 | "private": true, 6 | "scripts": { 7 | "dev": "next dev", 8 | "build": "next build", 9 | "start": "next start", 10 | "lint": "next lint" 11 | }, 12 | "dependencies": { 13 | "@ledgerhq/wallet-api-core": "workspace:*", 14 | "@ledgerhq/wallet-api-simulator": "workspace:*", 15 | "@next/font": "14.1.0", 16 | "@radix-ui/react-dropdown-menu": "^2.0.6", 17 | "@radix-ui/react-icons": "^1.3.0", 18 | "@tailwindcss/typography": "^0.5.10", 19 | "@types/node": "20.11.19", 20 | "@types/react": "18.2.57", 21 | "@types/react-dom": "18.2.19", 22 | "@uiw/codemirror-extensions-langs": "^4.21.22", 23 | "@uiw/react-codemirror": "^4.21.22", 24 | "bufferutil": "^4.0.8", 25 | "flowbite": "^2.3.0", 26 | "jotai": "^2.7.0", 27 | "lucide-react": "^0.359.0", 28 | "next": "^14.1.0", 29 | "react": "18.2.0", 30 | "react-dom": "18.2.0", 31 | "thememirror": "^2.0.1", 32 | "typescript": "5.3.3", 33 | "utf-8-validate": "^6.0.3", 34 | "uuid": "^9.0.1", 35 | "zod": "^3.22.4" 36 | }, 37 | "devDependencies": { 38 | "@ledgerhq/eslint-config-custom": "workspace:*", 39 | "@types/uuid": "^9.0.8", 40 | "autoprefixer": "^10.4.17", 41 | "eslint": "^8.56.0", 42 | "postcss": "^8.4.35", 43 | "postcss-import": "^16.0.1", 44 | "tailwindcss": "^3.4.1" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /apps/wallet-api-tools/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | 'postcss-import': {}, 4 | tailwindcss: {}, 5 | autoprefixer: {}, 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /apps/wallet-api-tools/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LedgerHQ/wallet-api/e81e17f1a1e0d03aadc8224fa0be6e42340c150d/apps/wallet-api-tools/public/favicon.ico -------------------------------------------------------------------------------- /apps/wallet-api-tools/public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/wallet-api-tools/public/thirteen.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/wallet-api-tools/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/wallet-api-tools/src/components/InfoMessage.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { getDate } from "../helpers"; 3 | import { MessageInfo } from "../types"; 4 | 5 | const InfoMessage = function InfoMessage({ 6 | message, 7 | }: { 8 | message: MessageInfo; 9 | }) { 10 | const color = message.type === "info" ? "yellow-300" : "red-500"; 11 | return ( 12 | <> 13 |
16 |

{message.value}

17 |

{getDate(message)}

18 |
19 | 20 | ); 21 | }; 22 | 23 | export default InfoMessage; 24 | -------------------------------------------------------------------------------- /apps/wallet-api-tools/src/components/Message.tsx: -------------------------------------------------------------------------------- 1 | import React, { CSSProperties } from "react"; 2 | import CodeMirror, { Extension } from "@uiw/react-codemirror"; 3 | import { langs } from "@uiw/codemirror-extensions-langs"; 4 | import { MessageIn, MessageOut } from "../types"; 5 | 6 | type Props = { 7 | message: MessageIn | MessageOut; 8 | style?: CSSProperties; 9 | theme?: Extension; 10 | date?: string; 11 | }; 12 | 13 | const extensions = [langs.json()]; 14 | 15 | const Message = ({ message, theme, date }: Props) => { 16 | return ( 17 | <> 18 |

{date}

19 | 36 | 37 | ); 38 | }; 39 | 40 | export default Message; 41 | -------------------------------------------------------------------------------- /apps/wallet-api-tools/src/helpers.ts: -------------------------------------------------------------------------------- 1 | import { MessageIn, MessageInfo, MessageOut } from "./types"; 2 | 3 | export function getMessageStatus( 4 | message: MessageInfo | MessageIn | MessageOut, 5 | ) { 6 | switch (message.type) { 7 | case "in": 8 | return "Received on"; 9 | case "out": 10 | return "Sent on "; 11 | case "error": 12 | return "[error]"; 13 | case "info": 14 | return "[info]"; 15 | default: { 16 | return undefined; 17 | } 18 | } 19 | } 20 | 21 | export function getDate(message: MessageInfo | MessageIn | MessageOut) { 22 | try { 23 | return ( 24 | getMessageStatus(message) + 25 | " " + 26 | new Date(message.date).toDateString() + 27 | " at " + 28 | new Date(message.date).toLocaleTimeString() 29 | ); 30 | } catch (e) { 31 | console.error("message", { message, e }); 32 | return "Error: Failed to generate the date."; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /apps/wallet-api-tools/src/types.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const schemaResponse = z.object({ 4 | id: z.string().optional(), 5 | result: z.unknown().optional(), 6 | error: z.unknown().optional(), 7 | method: z.string().optional(), 8 | }); 9 | 10 | export type Response = z.infer; 11 | 12 | export type ResponseResult = Response & { 13 | jsonrpc: string; 14 | result: unknown; 15 | }; 16 | 17 | export type ResponseError = Response & { 18 | jsonrpc: string; 19 | error: unknown; 20 | }; 21 | 22 | export const schemaRequest = z.object({ 23 | method: z.string(), 24 | params: z.object({}).passthrough(), 25 | }); 26 | export type InitialRequest = z.infer; 27 | 28 | export type Request = InitialRequest & { 29 | id: string; 30 | [key: string]: unknown; 31 | }; 32 | 33 | export type MessageOut = { 34 | type: "out"; 35 | value: Request; 36 | date: Date; 37 | }; 38 | 39 | export type MessageInfo = { 40 | id: string; 41 | type: "info" | "error"; 42 | value: string; 43 | date: Date; 44 | }; 45 | 46 | export type MessageIn = { 47 | type: "in"; 48 | value: ResponseResult | ResponseError; 49 | date: Date; 50 | }; 51 | 52 | export type MessageGrouped = { 53 | type: "group"; 54 | id: string; 55 | date: Date; 56 | messages: { 57 | sent: MessageOut; 58 | received: MessageIn | undefined; 59 | }; 60 | }; 61 | -------------------------------------------------------------------------------- /apps/wallet-api-tools/styles/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /apps/wallet-api-tools/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | "./pages/**/*.{js,ts,jsx,tsx}", 5 | "./src/**/*.{js,ts,jsx,tsx}", 6 | "./app/**/*.{js,ts,jsx,tsx}", 7 | "./node_modules/flowbite/**/*.js", 8 | ], 9 | theme: { 10 | extend: {}, 11 | }, 12 | plugins: [require("flowbite/plugin"), require("@tailwindcss/typography")], 13 | }; 14 | -------------------------------------------------------------------------------- /apps/wallet-api-tools/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "target": "es5", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "allowJs": true, 7 | "skipLibCheck": true, 8 | "strict": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "noEmit": true, 11 | "esModuleInterop": true, 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "jsx": "preserve", 17 | "incremental": true, 18 | "plugins": [ 19 | { 20 | "name": "next" 21 | } 22 | ], 23 | "declaration": false, 24 | "declarationMap": false 25 | }, 26 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 27 | "exclude": ["node_modules"] 28 | } 29 | -------------------------------------------------------------------------------- /examples/client-nextjs/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": ["next/core-web-vitals"], 4 | "plugins": ["testing-library"], 5 | "overrides": [ 6 | // Only uses Testing Library lint rules in test files 7 | { 8 | "files": [ 9 | "**/__tests__/**/*.[jt]s?(x)", 10 | "**/?(*.)+(spec|test).[jt]s?(x)" 11 | ], 12 | "extends": ["plugin:testing-library/react"] 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /examples/client-nextjs/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /examples/client-nextjs/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["prettier-plugin-tailwindcss"] 3 | } 4 | -------------------------------------------------------------------------------- /examples/client-nextjs/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LedgerHQ/wallet-api/e81e17f1a1e0d03aadc8224fa0be6e42340c150d/examples/client-nextjs/app/favicon.ico -------------------------------------------------------------------------------- /examples/client-nextjs/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | :root { 6 | --foreground-rgb: 0, 0, 0; 7 | --background-start-rgb: 214, 219, 220; 8 | --background-end-rgb: 255, 255, 255; 9 | } 10 | 11 | @media (prefers-color-scheme: dark) { 12 | :root { 13 | --foreground-rgb: 255, 255, 255; 14 | --background-start-rgb: 0, 0, 0; 15 | --background-end-rgb: 0, 0, 0; 16 | } 17 | } 18 | 19 | body { 20 | color: rgb(var(--foreground-rgb)); 21 | background: linear-gradient( 22 | to bottom, 23 | transparent, 24 | rgb(var(--background-end-rgb)) 25 | ) 26 | rgb(var(--background-start-rgb)); 27 | } 28 | -------------------------------------------------------------------------------- /examples/client-nextjs/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import { Inter } from "next/font/google"; 3 | import type { PropsWithChildren } from "react"; 4 | import "./globals.css"; 5 | 6 | const inter = Inter({ subsets: ["latin"] }); 7 | 8 | export const metadata: Metadata = { 9 | title: "Create Next App", 10 | description: "Generated by create next app", 11 | }; 12 | 13 | export default function RootLayout({ children }: PropsWithChildren) { 14 | return ( 15 | 16 | {children} 17 | 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /examples/client-nextjs/app/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { WindowMessageTransport } from "@ledgerhq/wallet-api-client"; 4 | import { WalletAPIProvider } from "@ledgerhq/wallet-api-client-react"; 5 | import { 6 | getSimulatorTransport, 7 | profiles, 8 | } from "@ledgerhq/wallet-api-simulator"; 9 | import { AccountsList } from "../components/AccountsList"; 10 | 11 | const isSimulator = 12 | typeof window === "undefined" 13 | ? false 14 | : new URLSearchParams(window.location.search).get("simulator"); 15 | 16 | function getWalletAPITransport() { 17 | if (typeof window === "undefined") { 18 | return { 19 | onMessage: undefined, 20 | send: () => {}, 21 | }; 22 | } 23 | 24 | if (isSimulator) { 25 | return getSimulatorTransport(profiles.STANDARD); 26 | } 27 | 28 | const transport = new WindowMessageTransport(); 29 | transport.connect(); 30 | return transport; 31 | } 32 | 33 | const transport = getWalletAPITransport(); 34 | 35 | export default function Page() { 36 | return ( 37 | 38 | 39 | 40 | ); 41 | } 42 | -------------------------------------------------------------------------------- /examples/client-nextjs/jest.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "jest"; 2 | const nextJest = require("next/jest"); 3 | 4 | const createJestConfig = nextJest({ 5 | // Provide the path to your Next.js app to load next.config.js and .env files in your test environment 6 | dir: "./", 7 | }); 8 | 9 | // Add any custom config to be passed to Jest 10 | const customJestConfig: Config = { 11 | setupFilesAfterEnv: ["/jest.setup.ts"], 12 | testEnvironment: "jest-environment-jsdom", 13 | }; 14 | 15 | // createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async 16 | module.exports = createJestConfig(customJestConfig); 17 | -------------------------------------------------------------------------------- /examples/client-nextjs/jest.setup.ts: -------------------------------------------------------------------------------- 1 | // Learn more: https://github.com/testing-library/jest-dom 2 | import "@testing-library/jest-dom"; 3 | -------------------------------------------------------------------------------- /examples/client-nextjs/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {} 3 | 4 | module.exports = nextConfig 5 | -------------------------------------------------------------------------------- /examples/client-nextjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ledgerhq/client-nextjs", 3 | "version": "0.1.30", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint", 10 | "test": "jest" 11 | }, 12 | "dependencies": { 13 | "@ledgerhq/wallet-api-client": "workspace:*", 14 | "@ledgerhq/wallet-api-client-react": "workspace:*", 15 | "@ledgerhq/wallet-api-simulator": "workspace:*", 16 | "next": "14.1.0", 17 | "react": "^18", 18 | "react-dom": "^18" 19 | }, 20 | "devDependencies": { 21 | "@testing-library/jest-dom": "^6.4.2", 22 | "@testing-library/react": "^14.2.1", 23 | "@testing-library/user-event": "^14.5.2", 24 | "@types/jest": "^29.5.12", 25 | "@types/node": "^20.11.19", 26 | "@types/react": "^18.2.57", 27 | "@types/react-dom": "^18.2.19", 28 | "autoprefixer": "^10.4.17", 29 | "eslint": "^8.56.0", 30 | "eslint-config-next": "14.1.0", 31 | "eslint-plugin-testing-library": "^6.2.0", 32 | "jest": "^29.7.0", 33 | "jest-environment-jsdom": "^29.7.0", 34 | "postcss": "^8.4.35", 35 | "prettier": "^3.2.5", 36 | "prettier-plugin-tailwindcss": "^0.5.11", 37 | "tailwindcss": "^3.4.1", 38 | "typescript": "^5.3.3" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /examples/client-nextjs/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /examples/client-nextjs/public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/client-nextjs/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/client-nextjs/tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from 'tailwindcss' 2 | 3 | const config: Config = { 4 | content: [ 5 | './pages/**/*.{js,ts,jsx,tsx,mdx}', 6 | './components/**/*.{js,ts,jsx,tsx,mdx}', 7 | './app/**/*.{js,ts,jsx,tsx,mdx}', 8 | ], 9 | theme: { 10 | extend: { 11 | backgroundImage: { 12 | 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', 13 | 'gradient-conic': 14 | 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', 15 | }, 16 | }, 17 | }, 18 | plugins: [], 19 | } 20 | export default config 21 | -------------------------------------------------------------------------------- /examples/client-nextjs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "target": "es5", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "allowJs": true, 7 | "skipLibCheck": true, 8 | "strict": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "bundler", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true, 17 | "plugins": [ 18 | { 19 | "name": "next" 20 | } 21 | ] 22 | }, 23 | "include": [ 24 | "next-env.d.ts", 25 | "**/*.ts", 26 | "**/*.tsx", 27 | ".next/types/**/*.ts", 28 | "types.d.ts", 29 | "./jest-setup.ts" 30 | ], 31 | "exclude": ["node_modules"] 32 | } 33 | -------------------------------------------------------------------------------- /examples/client-nextjs/types.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*module.css" { 2 | const styles: { 3 | [className: string]: string; 4 | }; 5 | export default styles; 6 | } 7 | -------------------------------------------------------------------------------- /packages/client-react/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | es2021: true, 4 | node: true, 5 | browser: true, 6 | }, 7 | globals: { 8 | Atomics: "readonly", 9 | SharedArrayBuffer: "readonly", 10 | }, 11 | parserOptions: { 12 | project: true, 13 | tsconfigRootDir: __dirname, 14 | }, 15 | settings: { 16 | "import/resolver": { 17 | node: { 18 | extensions: [".ts", ".tsx"], 19 | }, 20 | }, 21 | }, 22 | rules: { 23 | "no-underscore-dangle": "off", 24 | "class-methods-use-this": "warn", 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /packages/client-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ledgerhq/wallet-api-client-react", 3 | "version": "1.4.11", 4 | "repository": "git@github.com:LedgerHQ/wallet-api.git", 5 | "license": "Apache-2.0", 6 | "main": "lib/index.js", 7 | "module": "lib-es/index.js", 8 | "types": "lib/index.d.ts", 9 | "files": [ 10 | "/lib", 11 | "/lib-es" 12 | ], 13 | "scripts": { 14 | "format:check": "prettier --check \"src\" \"tests\"", 15 | "format:fix": "prettier --write \"src\" \"tests\"", 16 | "lint": "eslint --cache --ext .ts \"src\" \"tests\"", 17 | "lint:fix": "eslint --cache --fix --ext .ts \"src\" \"tests\"", 18 | "dev": "tsc -p prod.tsconfig.json --watch", 19 | "build": "rm -rf lib/* lib-es/* && tsc -p prod.tsconfig.json && tsc -p prod-esm.tsconfig.json", 20 | "test": "jest" 21 | }, 22 | "dependencies": { 23 | "@ledgerhq/wallet-api-client": "workspace:*" 24 | }, 25 | "devDependencies": { 26 | "@ledgerhq/jest-shared-config": "workspace:*", 27 | "@types/jest": "^29.5.12", 28 | "@types/node": "^20.11.19", 29 | "@types/react": "^18.2.57", 30 | "eslint": "^8.56.0", 31 | "jest": "^29.7.0", 32 | "jest-environment-jsdom": "^29.7.0", 33 | "prettier": "^3.2.5", 34 | "react": "^18.2.0", 35 | "ts-jest": "^29.1.2", 36 | "ts-node": "^10.9.2", 37 | "typescript": "^5.3.3" 38 | }, 39 | "peerDependencies": { 40 | "react": "^16.8.0 || ^17 || ^18 || ^19" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/client-react/prod-esm.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | "module": "ESNext", 7 | "outDir": "./lib-es" 8 | }, 9 | "include": ["src/**/*"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/client-react/prod.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | "module": "commonjs", 7 | "outDir": "./lib" 8 | }, 9 | "include": ["src/**/*"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/client-react/src/components/WalletAPIProvider/context.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from "react"; 2 | import type { Loadable, WalletAPIProviderContextValue } from "./types"; 3 | 4 | function initialLoadableValue(): Loadable { 5 | return { 6 | updatedAt: null, 7 | loading: false, 8 | value: null, 9 | error: undefined, 10 | }; 11 | } 12 | 13 | export const initialContextValue: WalletAPIProviderContextValue = { 14 | client: undefined, 15 | state: { 16 | accounts: initialLoadableValue(), 17 | currencies: initialLoadableValue(), 18 | capabilities: initialLoadableValue(), 19 | walletInfo: initialLoadableValue(), 20 | userId: initialLoadableValue(), 21 | }, 22 | setState: () => { 23 | return; 24 | }, 25 | }; 26 | 27 | export const WalletAPIProviderContext = 28 | createContext(initialContextValue); 29 | -------------------------------------------------------------------------------- /packages/client-react/src/components/WalletAPIProvider/helpers.ts: -------------------------------------------------------------------------------- 1 | import type { WalletAPIProviderContextValue } from "./types"; 2 | 3 | export function updateLoadableInState< 4 | T extends keyof WalletAPIProviderContextValue["state"], 5 | >( 6 | setState: WalletAPIProviderContextValue["setState"], 7 | key: T, 8 | patch: Partial, 9 | ) { 10 | setState((oldState) => ({ 11 | ...oldState, 12 | [key]: { 13 | ...oldState[key], 14 | ...patch, 15 | }, 16 | })); 17 | } 18 | -------------------------------------------------------------------------------- /packages/client-react/src/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./WalletAPIProvider"; 2 | -------------------------------------------------------------------------------- /packages/client-react/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./useAccounts"; 2 | export * from "./useCapabilities"; 3 | export * from "./useCurrencies"; 4 | export * from "./useRequestAccount"; 5 | export * from "./useSignAndBroadcastTransaction"; 6 | export * from "./useSignMessage"; 7 | export * from "./useSignTransaction"; 8 | export * from "./useUserId"; 9 | export * from "./useWalletAPIClient"; 10 | export * from "./useWalletInfo"; 11 | -------------------------------------------------------------------------------- /packages/client-react/src/hooks/useWalletAPIClient.ts: -------------------------------------------------------------------------------- 1 | import { useContext, useMemo } from "react"; 2 | import { WalletAPIProviderContext } from "../components/WalletAPIProvider/context"; 3 | import { RegisteredClient } from "../components/WalletAPIProvider/types"; 4 | 5 | type UseWalletAPIClientReturn = { 6 | client?: RegisteredClient; 7 | }; 8 | 9 | export function useWalletAPIClient(): UseWalletAPIClientReturn { 10 | const { client } = useContext(WalletAPIProviderContext); 11 | 12 | const results = useMemo( 13 | () => ({ 14 | client, 15 | }), 16 | [client], 17 | ); 18 | 19 | return results; 20 | } 21 | -------------------------------------------------------------------------------- /packages/client-react/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./components"; 2 | export * from "./hooks"; 3 | -------------------------------------------------------------------------------- /packages/client-react/tests/client-react.spec.ts: -------------------------------------------------------------------------------- 1 | describe("Client", () => { 2 | it.todo("Should write client-react tests"); 3 | }); 4 | -------------------------------------------------------------------------------- /packages/client-react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "jsx": "react-jsx", 5 | "outDir": "./lib" 6 | }, 7 | "include": ["src/**/*", "jest.config.ts", "tests/**/*"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/client/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | es2021: true, 4 | node: true, 5 | browser: true, 6 | }, 7 | globals: { 8 | Atomics: "readonly", 9 | SharedArrayBuffer: "readonly", 10 | }, 11 | parserOptions: { 12 | project: true, 13 | tsconfigRootDir: __dirname, 14 | }, 15 | rules: { 16 | "no-underscore-dangle": "off", 17 | "class-methods-use-this": "warn", 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /packages/client/.nycrc: -------------------------------------------------------------------------------- 1 | { 2 | "all": true, 3 | "check-coverage": true, 4 | "reporter": ["lcov", "text"], 5 | "include": ["src"], 6 | "branches": 100, 7 | "lines": 100, 8 | "functions": 100, 9 | "statements": 100 10 | } -------------------------------------------------------------------------------- /packages/client/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | :+1::tada: First off, thanks for taking the time to contribute! :tada::+1: 4 | 5 | This repository hosts the Ledger Live Platform SDK. 6 | 7 | ## JavaScript styleguide 8 | 9 | - ES6+ features. 10 | - [prettier](https://prettier.io/) for formatting convention. Check `yarn format:check`. 11 | - ESLint is used to enhance code quality. Check with `yarn lint:check`. 12 | - TypeScript is used to typecheck the library. Check with `yarn build`. 13 | 14 | > NB. for the 3 points above, the best is to have integration of Prettier, 15 | > ESlint, Flowtype in your text editor (there are plugin for most editors). 16 | 17 | ## Documentation 18 | 19 | Documentation is paramount for any project, especially a public and open sourced one. 20 | 21 | To document this project, we use the popular [diataxis](https://diataxis.fr/) documentation framework. 22 | 23 | The documentation content, either generated or manually added, can be found under the [`docs`](./docs/) folder. 24 | 25 | We use [typedoc](https://typedoc.org/) to generate our _reference_ documentation, located under [`docs/reference`](./docs/reference/), don't forget to add appropriate comments to your code. 26 | -------------------------------------------------------------------------------- /packages/client/jest.config.ts: -------------------------------------------------------------------------------- 1 | import type { JestConfigWithTsJest } from "ts-jest"; 2 | 3 | const config: JestConfigWithTsJest = { 4 | preset: "@ledgerhq/jest-shared-config", 5 | }; 6 | 7 | export default config; 8 | -------------------------------------------------------------------------------- /packages/client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ledgerhq/wallet-api-client", 3 | "version": "1.9.0", 4 | "repository": "git@github.com:LedgerHQ/wallet-api.git", 5 | "license": "Apache-2.0", 6 | "main": "lib/index.js", 7 | "module": "lib-es/index.js", 8 | "types": "lib/index.d.ts", 9 | "files": [ 10 | "/lib", 11 | "/lib-es" 12 | ], 13 | "scripts": { 14 | "format:check": "prettier --check \"src\" \"tests\"", 15 | "format:fix": "prettier --write \"src\" \"tests\"", 16 | "lint": "eslint --cache --ext .ts \"src\" \"tests\"", 17 | "lint:fix": "eslint --cache --fix --ext .ts \"src\" \"tests\"", 18 | "dev": "tsc -p prod.tsconfig.json --watch", 19 | "build": "rm -rf lib/* lib-es/* && tsc -p prod.tsconfig.json && tsc -p prod-esm.tsconfig.json", 20 | "test": "jest" 21 | }, 22 | "dependencies": { 23 | "@ledgerhq/hw-transport": "^6.30.4", 24 | "@ledgerhq/wallet-api-core": "workspace:*", 25 | "bignumber.js": "^9.1.2" 26 | }, 27 | "devDependencies": { 28 | "@ledgerhq/jest-shared-config": "workspace:*", 29 | "@types/jest": "^29.5.12", 30 | "@types/node": "^20.11.19", 31 | "eslint": "^8.56.0", 32 | "jest": "^29.7.0", 33 | "jest-environment-jsdom": "^29.7.0", 34 | "prettier": "^3.2.5", 35 | "ts-jest": "^29.1.2", 36 | "ts-node": "^10.9.2", 37 | "typescript": "^5.3.3" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/client/prod-esm.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | "module": "ESNext", 7 | "outDir": "./lib-es" 8 | }, 9 | "include": ["src/**/*"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/client/prod.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | "module": "commonjs", 7 | "outDir": "./lib" 8 | }, 9 | "include": ["src/**/*"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/client/src/index.ts: -------------------------------------------------------------------------------- 1 | /* istanbul ignore file */ 2 | 3 | export * from "@ledgerhq/wallet-api-core"; 4 | export * from "./TransportWalletAPI"; 5 | export * from "./WalletAPIClient"; 6 | export * from "./modules/Custom"; 7 | -------------------------------------------------------------------------------- /packages/client/src/modules/Currency.ts: -------------------------------------------------------------------------------- 1 | import { Currency, schemaCurrencyList } from "@ledgerhq/wallet-api-core"; 2 | import type { WalletAPIClient } from "../WalletAPIClient"; 3 | 4 | export class CurrencyModule { 5 | private client: WalletAPIClient; 6 | 7 | constructor(client: WalletAPIClient) { 8 | this.client = client; 9 | } 10 | 11 | /** 12 | * List cryptocurrencies supported by the connected wallet, providing filters by name or ticker 13 | * 14 | * @param params - Filters for currencies 15 | * 16 | * @returns The list of corresponding cryptocurrencies 17 | * @throws {@link RpcError} if an error occurred on server side 18 | * 19 | * @beta Filtering not yet implemented 20 | */ 21 | async list(params?: { 22 | /** 23 | * Select a set of currencies by id. Globing is enabled 24 | */ 25 | currencyIds?: string[]; 26 | }): Promise { 27 | const listResult = await this.client.request("currency.list", { 28 | currencyIds: params?.currencyIds, 29 | }); 30 | 31 | const safeResults = schemaCurrencyList.result.parse(listResult); 32 | 33 | return safeResults.currencies; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/client/src/modules/Custom.ts: -------------------------------------------------------------------------------- 1 | import type { WalletAPIClient } from "../WalletAPIClient"; 2 | 3 | export class CustomModule { 4 | private client: WalletAPIClient; 5 | 6 | constructor(client: WalletAPIClient) { 7 | this.client = client; 8 | } 9 | 10 | /** 11 | * Let the app request a custom method. 12 | * @param method - Custom method name 13 | * @param data - Data to send 14 | * 15 | * @returns Message signed 16 | * @throws {@link RpcError} if an error occurred on server side 17 | */ 18 | protected request(method: `custom.${string}`, data: D): Promise { 19 | return this.client.request(method, data) as Promise; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/client/src/modules/Message.ts: -------------------------------------------------------------------------------- 1 | import { MessageSign, schemaMessageSign } from "@ledgerhq/wallet-api-core"; 2 | import type { WalletAPIClient } from "../WalletAPIClient"; 3 | 4 | export class MessageModule { 5 | private client: WalletAPIClient; 6 | 7 | constructor(client: WalletAPIClient) { 8 | this.client = client; 9 | } 10 | 11 | /** 12 | * Let the user sign the provided message. 13 | * In Ethereum context, this is an [EIP-191 message](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-191.md) 14 | * or an [EIP-712 message](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md) 15 | * @param accountId - Ledger Live id of the account 16 | * @param message - Message the user should sign 17 | * 18 | * @returns Message signed 19 | * @throws {@link RpcError} if an error occurred on server side 20 | */ 21 | async sign( 22 | accountId: string, 23 | message: Buffer, 24 | options?: MessageSign["params"]["options"], 25 | meta?: Record, 26 | ): Promise { 27 | const messageSignResult = await this.client.request("message.sign", { 28 | accountId, 29 | hexMessage: message.toString("hex"), 30 | options, 31 | meta, 32 | }); 33 | 34 | const safeResults = schemaMessageSign.result.parse(messageSignResult); 35 | 36 | return Buffer.from(safeResults.hexSignedMessage, "hex"); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/client/src/modules/Storage.ts: -------------------------------------------------------------------------------- 1 | import { schemaStorageGet, schemaStorageSet } from "@ledgerhq/wallet-api-core"; 2 | import type { WalletAPIClient } from "../WalletAPIClient"; 3 | 4 | export class StorageModule { 5 | private client: WalletAPIClient; 6 | 7 | constructor(client: WalletAPIClient) { 8 | this.client = client; 9 | } 10 | 11 | async get(key: string, storeId?: string): Promise { 12 | const storageGetResult = await this.client.request("storage.get", { 13 | key, 14 | storeId, 15 | }); 16 | 17 | const safeResults = schemaStorageGet.result.parse(storageGetResult); 18 | 19 | return safeResults.value; 20 | } 21 | 22 | async set(key: string, value: string, storeId?: string) { 23 | const storageSetResult = await this.client.request("storage.set", { 24 | key, 25 | value, 26 | storeId, 27 | }); 28 | 29 | const safeResults = schemaStorageSet.result.parse(storageSetResult); 30 | 31 | return safeResults; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/client/tests/client.spec.ts: -------------------------------------------------------------------------------- 1 | describe("Client", () => { 2 | it.todo("Should write client tests"); 3 | }); 4 | -------------------------------------------------------------------------------- /packages/client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "./lib" 5 | }, 6 | "include": ["src/**/*", "jest.config.ts", "tests/**/*"] 7 | } 8 | -------------------------------------------------------------------------------- /packages/core/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | es2021: true, 4 | node: true, 5 | }, 6 | parserOptions: { 7 | project: true, 8 | tsconfigRootDir: __dirname, 9 | }, 10 | rules: { 11 | "no-underscore-dangle": "off", 12 | "class-methods-use-this": "warn", 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /packages/core/jest.config.ts: -------------------------------------------------------------------------------- 1 | import type { JestConfigWithTsJest } from "ts-jest"; 2 | 3 | const config: JestConfigWithTsJest = { 4 | preset: "@ledgerhq/jest-shared-config", 5 | }; 6 | 7 | export default config; 8 | -------------------------------------------------------------------------------- /packages/core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ledgerhq/wallet-api-core", 3 | "version": "1.21.0", 4 | "license": "MIT", 5 | "main": "lib/index.js", 6 | "module": "lib-es/index.js", 7 | "types": "lib/index.d.ts", 8 | "files": [ 9 | "/lib", 10 | "/lib-es" 11 | ], 12 | "scripts": { 13 | "format:check": "prettier --check \"src\"", 14 | "format:fix": "prettier --write \"src\"", 15 | "lint": "eslint --cache --ext .ts \"src\"", 16 | "lint:fix": "eslint --cache --fix --ext .ts \"src\"", 17 | "dev": "tsc -p prod.tsconfig.json --watch", 18 | "build": "rm -rf lib/* lib-es/* && tsc -p prod.tsconfig.json && tsc -p prod-esm.tsconfig.json", 19 | "test": "jest" 20 | }, 21 | "devDependencies": { 22 | "@ledgerhq/jest-shared-config": "workspace:*", 23 | "@types/jest": "^29.5.12", 24 | "@types/node": "^20.11.19", 25 | "@types/uuid": "^9.0.8", 26 | "eslint": "^8.56.0", 27 | "jest": "^29.7.0", 28 | "jest-environment-jsdom": "^29.7.0", 29 | "ts-jest": "^29.1.2", 30 | "ts-node": "^10.9.2", 31 | "typescript": "^5.3.3" 32 | }, 33 | "dependencies": { 34 | "@ledgerhq/errors": "^6.16.2", 35 | "@stacks/transactions": "^6.13.0", 36 | "@ton/core": "^0.60.1", 37 | "bignumber.js": "^9.1.2", 38 | "thor-devkit": "^2.0.9", 39 | "uuid": "^9.0.1", 40 | "zod": "^3.22.4" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/core/prod-esm.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | "module": "ESNext", 7 | "outDir": "./lib-es" 8 | }, 9 | "include": ["src/**/*"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/core/prod.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | "module": "commonjs", 7 | "outDir": "./lib" 8 | }, 9 | "include": ["src/**/*"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/core/src/JSONRPC/RPCError.ts: -------------------------------------------------------------------------------- 1 | import type { RpcResponseError } from "./types"; 2 | 3 | export class RpcError extends Error { 4 | private readonly err: RpcResponseError; 5 | 6 | constructor(err: RpcResponseError) { 7 | super(err.message); 8 | this.err = err; 9 | } 10 | 11 | /** 12 | * Retrieve error code 13 | * @returns error code 14 | */ 15 | public getCode() { 16 | return this.err.code; 17 | } 18 | 19 | /** 20 | * Retrieve underlying data info 21 | * @returns data info 22 | */ 23 | public getData() { 24 | return this.err.data; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/core/src/JSONRPC/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./RPCError"; 2 | export * from "./types"; 3 | export * from "./validation"; 4 | export * from "./helpers"; 5 | export * from "./RpcNode"; 6 | -------------------------------------------------------------------------------- /packages/core/src/JSONRPC/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | const schemaRPCId = z.union([z.string(), z.number(), z.null()]); 4 | 5 | export const schemaRPCRequest = z 6 | .object({ 7 | jsonrpc: z.literal("2.0"), 8 | method: z.string(), 9 | params: z.any(), 10 | id: schemaRPCId.optional(), 11 | }) 12 | .strict(); 13 | 14 | export const schemaRPCResponseErrorData = z 15 | .object({ 16 | code: z.number(), 17 | message: z.string(), 18 | data: z.any().optional(), 19 | }) 20 | .strict(); 21 | 22 | export const schemaRPCResponseSuccess = z 23 | .object({ 24 | jsonrpc: z.literal("2.0"), 25 | id: schemaRPCId, 26 | result: z.object({}).passthrough().optional(), 27 | }) 28 | .strict(); 29 | 30 | export const schemaRPCResponseError = z 31 | .object({ 32 | jsonrpc: z.literal("2.0"), 33 | id: schemaRPCId, 34 | error: schemaRPCResponseErrorData, 35 | }) 36 | .strict(); 37 | 38 | export const schemaRPCResponse = z.union([ 39 | schemaRPCResponseError, 40 | schemaRPCResponseSuccess, 41 | ]); 42 | 43 | export const schemaRPCCall = z.union([schemaRPCRequest, schemaRPCResponse]); 44 | -------------------------------------------------------------------------------- /packages/core/src/accounts/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./serializers"; 2 | export * from "./types"; 3 | export * from "./validation"; 4 | -------------------------------------------------------------------------------- /packages/core/src/accounts/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const schemaRawAccount = z.object({ 4 | id: z.string(), 5 | name: z.string(), 6 | address: z.string(), 7 | currency: z.string(), 8 | balance: z.string(), 9 | spendableBalance: z.string(), 10 | blockHeight: z.union([z.number(), z.undefined()]), 11 | lastSyncDate: z.string(), 12 | parentAccountId: z.string().optional(), 13 | }); 14 | -------------------------------------------------------------------------------- /packages/core/src/currencies/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./types"; 2 | export * from "./validation"; 3 | -------------------------------------------------------------------------------- /packages/core/src/currencies/types.ts: -------------------------------------------------------------------------------- 1 | import type { z } from "zod"; 2 | import type { 3 | schemaCryptoCurrency, 4 | schemaCurrency, 5 | schemaCurrencyType, 6 | schemaERC20TokenCurrency, 7 | schemaTokenStandard, 8 | } from "./validation"; 9 | 10 | /** 11 | * Currency types 12 | */ 13 | export type CurrencyType = z.infer; 14 | 15 | /** 16 | * Token standards 17 | */ 18 | export type TokenStandard = z.infer; 19 | 20 | /** 21 | * Crypto currency model 22 | */ 23 | export type CryptoCurrency = z.infer; 24 | 25 | /** 26 | * ERC20 token currency model 27 | */ 28 | export type ERC20TokenCurrency = z.infer; 29 | 30 | export type Currency = z.infer; 31 | -------------------------------------------------------------------------------- /packages/core/src/currencies/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const schemaCurrencyType = z.enum(["CryptoCurrency", "TokenCurrency"]); 4 | export const schemaTokenStandard = z.enum(["ERC20"]); 5 | 6 | export const schemaBaseCurrency = z.object({ 7 | color: z.string(), 8 | ticker: z.string(), 9 | id: z.string(), 10 | name: z.string(), 11 | decimals: z.number(), 12 | }); 13 | 14 | export const schemaCryptoCurrency = schemaBaseCurrency.extend({ 15 | type: z.literal(schemaCurrencyType.enum.CryptoCurrency), 16 | family: z.string(), 17 | }); 18 | 19 | export const schemaTokenCurrency = schemaBaseCurrency.extend({ 20 | type: z.literal(schemaCurrencyType.enum.TokenCurrency), 21 | parent: z.string(), 22 | }); 23 | 24 | export const schemaERC20TokenCurrency = schemaTokenCurrency.extend({ 25 | standard: schemaTokenStandard, 26 | contract: z.string(), 27 | }); 28 | 29 | export const schemaCurrency = z.discriminatedUnion("type", [ 30 | schemaCryptoCurrency, 31 | schemaERC20TokenCurrency, 32 | ]); 33 | -------------------------------------------------------------------------------- /packages/core/src/errors/ServerError.ts: -------------------------------------------------------------------------------- 1 | import type { ServerErrorData } from "./types"; 2 | 3 | export class ServerError extends Error { 4 | private readonly errorData: ServerErrorData; 5 | 6 | constructor(errorData: ServerErrorData) { 7 | super(errorData.message); 8 | this.errorData = errorData; 9 | } 10 | 11 | /** 12 | * Retrieve error code 13 | * @returns error code 14 | */ 15 | public getCode(): ServerErrorData["code"] { 16 | return this.errorData.code; 17 | } 18 | 19 | /** 20 | * Retrieve underlying data info 21 | * @returns data info 22 | */ 23 | public getData(): ServerErrorData { 24 | return this.errorData; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/core/src/errors/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./types"; 2 | export * from "./creators"; 3 | export * from "./ServerError"; 4 | -------------------------------------------------------------------------------- /packages/core/src/families/algorand/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { AlgorandTransaction, RawAlgorandTransaction } from "./types"; 3 | 4 | export const serializeAlgorandTransaction = ({ 5 | family, 6 | mode, 7 | fees, 8 | assetId, 9 | memo, 10 | amount, 11 | recipient, 12 | }: AlgorandTransaction): RawAlgorandTransaction => ({ 13 | family, 14 | amount: amount.toString(), 15 | recipient, 16 | fees: fees ? fees.toString() : undefined, 17 | memo, 18 | mode, 19 | assetId, 20 | }); 21 | 22 | export const deserializeAlgorandTransaction = ({ 23 | family, 24 | mode, 25 | fees, 26 | assetId, 27 | memo, 28 | amount, 29 | recipient, 30 | }: RawAlgorandTransaction): AlgorandTransaction => ({ 31 | family, 32 | amount: new BigNumber(amount), 33 | recipient, 34 | fees: fees ? new BigNumber(fees) : undefined, 35 | memo, 36 | mode, 37 | assetId, 38 | }); 39 | -------------------------------------------------------------------------------- /packages/core/src/families/algorand/types.ts: -------------------------------------------------------------------------------- 1 | import type BigNumber from "bignumber.js"; 2 | import type { z } from "zod"; 3 | import type { TransactionCommon } from "../index"; 4 | import type { 5 | schemaAlgorandOperationMode, 6 | schemaRawAlgorandTransaction, 7 | } from "./validation"; 8 | 9 | export type AlgorandOperationMode = z.infer; 10 | 11 | export type AlgorandTransaction = TransactionCommon & { 12 | readonly family: RawAlgorandTransaction["family"]; 13 | mode: AlgorandOperationMode; 14 | fees?: BigNumber; 15 | assetId?: string; 16 | memo?: string; 17 | }; 18 | 19 | export type RawAlgorandTransaction = z.infer< 20 | typeof schemaRawAlgorandTransaction 21 | >; 22 | -------------------------------------------------------------------------------- /packages/core/src/families/algorand/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaAlgorandOperationMode = z.enum([ 5 | "send", 6 | "optIn", 7 | "claimReward", 8 | "optOut", 9 | ]); 10 | 11 | export const schemaRawAlgorandTransaction = schemaTransactionCommon.extend({ 12 | family: z.literal(schemaFamilies.enum.algorand), 13 | mode: schemaAlgorandOperationMode, 14 | fees: z.string().optional(), 15 | assetId: z.string().optional(), 16 | memo: z.string().optional(), 17 | }); 18 | -------------------------------------------------------------------------------- /packages/core/src/families/aptos/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { AptosTransaction, RawAptosTransaction } from "./types"; 3 | 4 | export const serializeAptosTransaction = ({ 5 | family, 6 | mode, 7 | fees, 8 | amount, 9 | recipient, 10 | }: AptosTransaction): RawAptosTransaction => ({ 11 | family, 12 | amount: amount.toString(), 13 | recipient, 14 | fees: fees ? fees.toString() : undefined, 15 | mode, 16 | }); 17 | 18 | export const deserializeAptosTransaction = ({ 19 | family, 20 | mode, 21 | fees, 22 | amount, 23 | recipient, 24 | }: RawAptosTransaction): AptosTransaction => ({ 25 | family, 26 | amount: new BigNumber(amount), 27 | recipient, 28 | fees: fees ? new BigNumber(fees) : undefined, 29 | mode, 30 | }); 31 | -------------------------------------------------------------------------------- /packages/core/src/families/aptos/types.ts: -------------------------------------------------------------------------------- 1 | import type BigNumber from "bignumber.js"; 2 | import type { z } from "zod"; 3 | import type { TransactionCommon } from "../index"; 4 | import type { 5 | schemaAptosOperationMode, 6 | schemaRawAptosTransaction, 7 | } from "./validation"; 8 | 9 | export type AptosOperationMode = z.infer; 10 | 11 | export type AptosTransaction = TransactionCommon & { 12 | readonly family: RawAptosTransaction["family"]; 13 | mode: AptosOperationMode; 14 | fees?: BigNumber; 15 | }; 16 | 17 | export type RawAptosTransaction = z.infer; 18 | -------------------------------------------------------------------------------- /packages/core/src/families/aptos/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaAptosOperationMode = z.enum(["send"]); 5 | 6 | export const schemaRawAptosTransaction = schemaTransactionCommon.extend({ 7 | family: z.literal(schemaFamilies.enum.aptos), 8 | mode: schemaAptosOperationMode, 9 | fees: z.string().optional(), 10 | }); 11 | -------------------------------------------------------------------------------- /packages/core/src/families/bitcoin/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { BitcoinTransaction, RawBitcoinTransaction } from "./types"; 3 | 4 | export function serializeBitcoinTransaction({ 5 | family, 6 | amount, 7 | recipient, 8 | feePerByte, 9 | opReturnData, 10 | }: BitcoinTransaction): RawBitcoinTransaction { 11 | return { 12 | family, 13 | amount: amount.toString(), 14 | recipient, 15 | feePerByte: feePerByte?.toString(), 16 | opReturnDataHex: opReturnData?.toString("hex"), 17 | }; 18 | } 19 | 20 | export function deserializeBitcoinTransaction({ 21 | family, 22 | amount, 23 | recipient, 24 | feePerByte, 25 | opReturnDataHex, 26 | }: RawBitcoinTransaction): BitcoinTransaction { 27 | return { 28 | family, 29 | amount: new BigNumber(amount), 30 | recipient, 31 | feePerByte: feePerByte ? new BigNumber(feePerByte) : undefined, 32 | opReturnData: opReturnDataHex 33 | ? Buffer.from(opReturnDataHex, "hex") 34 | : undefined, 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /packages/core/src/families/bitcoin/types.ts: -------------------------------------------------------------------------------- 1 | import type BigNumber from "bignumber.js"; 2 | import type { z } from "zod"; 3 | import type { TransactionCommon } from "../index"; 4 | import type { schemaRawBitcoinTransaction } from "./validation"; 5 | 6 | export type BitcoinTransaction = TransactionCommon & { 7 | readonly family: RawBitcoinTransaction["family"]; 8 | feePerByte?: BigNumber; 9 | opReturnData?: Buffer; 10 | }; 11 | 12 | export type RawBitcoinTransaction = z.infer; 13 | -------------------------------------------------------------------------------- /packages/core/src/families/bitcoin/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaRawBitcoinTransaction = schemaTransactionCommon.extend({ 5 | family: z.literal(schemaFamilies.enum.bitcoin), 6 | feePerByte: z.string().optional(), 7 | opReturnDataHex: z.string().max(160).optional(), 8 | }); 9 | -------------------------------------------------------------------------------- /packages/core/src/families/cardano/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { CardanoTransaction, RawCardanoTransaction } from "./types"; 3 | 4 | export function serializeCardanoTransaction({ 5 | amount, 6 | family, 7 | fees, 8 | memo, 9 | mode, 10 | recipient, 11 | }: CardanoTransaction): RawCardanoTransaction { 12 | return { 13 | amount: amount.toString(), 14 | family, 15 | fees: fees ? fees.toString() : undefined, 16 | memo, 17 | mode, 18 | recipient, 19 | }; 20 | } 21 | 22 | export function deserializeCardanoTransaction({ 23 | amount, 24 | family, 25 | fees, 26 | memo, 27 | mode, 28 | recipient, 29 | }: RawCardanoTransaction): CardanoTransaction { 30 | return { 31 | amount: new BigNumber(amount), 32 | family, 33 | fees: fees ? new BigNumber(fees) : undefined, 34 | memo, 35 | mode, 36 | recipient, 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /packages/core/src/families/cardano/types.ts: -------------------------------------------------------------------------------- 1 | import type BigNumber from "bignumber.js"; 2 | import type { z } from "zod"; 3 | import type { TransactionCommon } from "../index"; 4 | import type { schemaRawCardanoTransaction } from "./validation"; 5 | 6 | export type CardanoTransaction = TransactionCommon & { 7 | readonly family: RawCardanoTransaction["family"]; 8 | fees?: BigNumber; 9 | memo?: string; 10 | mode: string; 11 | }; 12 | 13 | export type RawCardanoTransaction = z.infer; 14 | -------------------------------------------------------------------------------- /packages/core/src/families/cardano/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaRawCardanoTransaction = schemaTransactionCommon.extend({ 5 | family: z.literal(schemaFamilies.enum.cardano), 6 | fees: z.string().optional(), 7 | mode: z.string(), 8 | memo: z.string().optional(), 9 | }); 10 | -------------------------------------------------------------------------------- /packages/core/src/families/casper/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { RawCasperTransaction, CasperTransaction } from "./types"; 3 | 4 | export const serializeCasperTransaction = ({ 5 | amount, 6 | recipient, 7 | family, 8 | fees, 9 | transferId, 10 | }: CasperTransaction): RawCasperTransaction => ({ 11 | amount: amount.toFixed(), 12 | recipient, 13 | family, 14 | fees: fees.toString(), 15 | transferId, 16 | }); 17 | 18 | export const deserializeCasperTransaction = ({ 19 | amount, 20 | recipient, 21 | family, 22 | fees, 23 | transferId, 24 | }: RawCasperTransaction): CasperTransaction => ({ 25 | amount: new BigNumber(amount), 26 | recipient, 27 | family, 28 | fees: new BigNumber(fees), 29 | transferId, 30 | }); 31 | -------------------------------------------------------------------------------- /packages/core/src/families/casper/types.ts: -------------------------------------------------------------------------------- 1 | import type { z } from "zod"; 2 | import type { TransactionCommon } from "../index"; 3 | import type { schemaRawCasperTransaction } from "./validation"; 4 | import type BigNumber from "bignumber.js"; 5 | 6 | export type CasperTransaction = TransactionCommon & { 7 | readonly family: RawCasperTransaction["family"]; 8 | fees: BigNumber; 9 | transferId?: string; 10 | }; 11 | 12 | export type RawCasperTransaction = z.infer; 13 | -------------------------------------------------------------------------------- /packages/core/src/families/casper/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaRawCasperTransaction = schemaTransactionCommon.extend({ 5 | family: z.literal(schemaFamilies.enum.casper), 6 | fees: z.string(), 7 | transferId: z.string().optional(), 8 | }); 9 | -------------------------------------------------------------------------------- /packages/core/src/families/celo/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { CeloTransaction, RawCeloTransaction } from "./types"; 3 | 4 | export function serializeCeloTransaction({ 5 | amount, 6 | family, 7 | fees = undefined, 8 | index = undefined, 9 | mode, 10 | recipient, 11 | }: CeloTransaction): RawCeloTransaction { 12 | return { 13 | amount: amount.toString(), 14 | family, 15 | fees: fees ? fees.toString() : undefined, 16 | index, 17 | mode, 18 | recipient, 19 | }; 20 | } 21 | 22 | export function deserializeCeloTransaction({ 23 | amount, 24 | family, 25 | fees = undefined, 26 | index = undefined, 27 | mode, 28 | recipient, 29 | }: RawCeloTransaction): CeloTransaction { 30 | return { 31 | amount: new BigNumber(amount), 32 | family, 33 | fees: fees ? new BigNumber(fees) : undefined, 34 | index, 35 | mode, 36 | recipient, 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /packages/core/src/families/celo/types.ts: -------------------------------------------------------------------------------- 1 | import type BigNumber from "bignumber.js"; 2 | import type { z } from "zod"; 3 | import type { TransactionCommon } from "../index"; 4 | import type { CeloOperationMode, schemaRawCeloTransaction } from "./validation"; 5 | 6 | export type CeloTransaction = TransactionCommon & { 7 | readonly family: RawCeloTransaction["family"]; 8 | fees?: BigNumber; 9 | index?: number | null; 10 | mode: CeloOperationMode; 11 | }; 12 | 13 | export type RawCeloTransaction = z.infer; 14 | -------------------------------------------------------------------------------- /packages/core/src/families/celo/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaOperationMode = z.enum([ 5 | "send", 6 | "lock", 7 | "unlock", 8 | "withdraw", 9 | "vote", 10 | "revoke", 11 | "activate", 12 | "register", 13 | ]); 14 | 15 | export const schemaRawCeloTransaction = schemaTransactionCommon.extend({ 16 | family: z.literal(schemaFamilies.enum.celo), 17 | fees: z.string().optional().nullable(), 18 | mode: schemaOperationMode, 19 | index: z.number().optional().nullable(), 20 | }); 21 | 22 | export type CeloOperationMode = z.infer; 23 | -------------------------------------------------------------------------------- /packages/core/src/families/common.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const schemaTransactionCommon = z.object({ 4 | amount: z.string(), 5 | recipient: z.string(), 6 | }); 7 | 8 | export const FAMILIES = [ 9 | "algorand", 10 | "aptos", 11 | "bitcoin", 12 | "cardano", 13 | "casper", 14 | "celo", 15 | "crypto_org", 16 | "cosmos", 17 | "elrond", 18 | "ethereum", 19 | "filecoin", 20 | "hedera", 21 | "internet_computer", 22 | "near", 23 | "neo", 24 | "polkadot", 25 | "ripple", 26 | "solana", 27 | "stacks", 28 | "stellar", 29 | "sui", 30 | "tezos", 31 | "ton", 32 | "tron", 33 | "vechain", 34 | ] as const; 35 | 36 | export const schemaFamilies = z.enum(FAMILIES); 37 | -------------------------------------------------------------------------------- /packages/core/src/families/cosmos/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { CosmosTransaction, RawCosmosTransaction } from "./types"; 3 | 4 | export const serializeCosmosTransaction = ({ 5 | amount, 6 | recipient, 7 | family, 8 | mode, 9 | fees, 10 | gas, 11 | memo, 12 | sourceValidator, 13 | validators, 14 | }: CosmosTransaction): RawCosmosTransaction => ({ 15 | amount: amount.toString(), 16 | recipient, 17 | family, 18 | mode, 19 | fees: fees ? fees.toString() : undefined, 20 | gas: gas ? gas.toString() : undefined, 21 | memo, 22 | sourceValidator: sourceValidator ?? undefined, 23 | validators: validators 24 | ? validators.map((val) => ({ 25 | ...val, 26 | amount: val.amount.toString(), 27 | })) 28 | : undefined, 29 | }); 30 | 31 | export const deserializeCosmosTransaction = ({ 32 | amount, 33 | recipient, 34 | family, 35 | mode, 36 | fees, 37 | gas, 38 | memo, 39 | sourceValidator, 40 | validators, 41 | }: RawCosmosTransaction): CosmosTransaction => ({ 42 | amount: new BigNumber(amount), 43 | recipient, 44 | family, 45 | mode, 46 | fees: fees ? new BigNumber(fees) : undefined, 47 | gas: gas ? new BigNumber(gas) : undefined, 48 | memo, 49 | sourceValidator: sourceValidator ?? undefined, 50 | validators: validators 51 | ? validators.map((val) => ({ 52 | ...val, 53 | amount: new BigNumber(val.amount), 54 | })) 55 | : undefined, 56 | }); 57 | -------------------------------------------------------------------------------- /packages/core/src/families/cosmos/types.ts: -------------------------------------------------------------------------------- 1 | import type BigNumber from "bignumber.js"; 2 | import type { z } from "zod"; 3 | import type { TransactionCommon } from "../index"; 4 | import type { 5 | schemaCosmosOperationMode, 6 | schemaRawCosmosTransaction, 7 | } from "./validation"; 8 | 9 | export type CosmosOperationMode = z.infer; 10 | 11 | export type CosmosDelegationInfo = { 12 | address: string; 13 | amount: BigNumber; 14 | }; 15 | 16 | export type CosmosTransaction = TransactionCommon & { 17 | readonly family: RawCosmosTransaction["family"]; 18 | mode: CosmosOperationMode; 19 | fees?: BigNumber; 20 | gas?: BigNumber; 21 | memo?: string; 22 | sourceValidator?: string; 23 | validators?: CosmosDelegationInfo[]; 24 | }; 25 | 26 | export type RawCosmosTransaction = z.infer; 27 | -------------------------------------------------------------------------------- /packages/core/src/families/cosmos/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaCosmosOperationMode = z.enum([ 5 | "send", 6 | "delegate", 7 | "undelegate", 8 | "redelegate", 9 | "claimReward", 10 | "claimRewardCompound", 11 | ]); 12 | 13 | const cosmosDelegationInfo = z.object({ 14 | address: z.string(), 15 | amount: z.string(), 16 | }); 17 | 18 | export const schemaRawCosmosTransaction = schemaTransactionCommon.extend({ 19 | family: z.literal(schemaFamilies.enum.cosmos), 20 | mode: schemaCosmosOperationMode, 21 | fees: z.string().optional(), 22 | gas: z.string().optional(), 23 | memo: z.string().optional(), 24 | sourceValidator: z.string().optional(), 25 | validators: z.array(cosmosDelegationInfo).optional(), 26 | }); 27 | -------------------------------------------------------------------------------- /packages/core/src/families/crypto_org/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { CryptoOrgTransaction, RawCryptoOrgTransaction } from "./types"; 3 | 4 | export const serializeCryptoOrgTransaction = ({ 5 | family, 6 | mode, 7 | fees, 8 | amount, 9 | recipient, 10 | }: CryptoOrgTransaction): RawCryptoOrgTransaction => ({ 11 | family, 12 | amount: amount.toString(), 13 | recipient, 14 | fees: fees ? fees.toString() : undefined, 15 | mode, 16 | }); 17 | 18 | export const deserializeCryptoOrgTransaction = ({ 19 | family, 20 | mode, 21 | fees, 22 | amount, 23 | recipient, 24 | }: RawCryptoOrgTransaction): CryptoOrgTransaction => ({ 25 | family, 26 | amount: new BigNumber(amount), 27 | recipient, 28 | fees: fees ? new BigNumber(fees) : undefined, 29 | mode, 30 | }); 31 | -------------------------------------------------------------------------------- /packages/core/src/families/crypto_org/types.ts: -------------------------------------------------------------------------------- 1 | import type BigNumber from "bignumber.js"; 2 | import type { z } from "zod"; 3 | import type { TransactionCommon } from "../index"; 4 | import type { schemaRawCryptoOrgTransaction } from "./validation"; 5 | 6 | export type CryptoOrgTransaction = TransactionCommon & { 7 | readonly family: RawCryptoOrgTransaction["family"]; 8 | mode: string; 9 | fees?: BigNumber; 10 | }; 11 | 12 | export type RawCryptoOrgTransaction = z.infer< 13 | typeof schemaRawCryptoOrgTransaction 14 | >; 15 | -------------------------------------------------------------------------------- /packages/core/src/families/crypto_org/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaRawCryptoOrgTransaction = schemaTransactionCommon.extend({ 5 | family: z.literal(schemaFamilies.enum.crypto_org), 6 | mode: z.string(), 7 | fees: z.string().optional(), 8 | }); 9 | -------------------------------------------------------------------------------- /packages/core/src/families/elrond/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { ElrondTransaction, RawElrondTransaction } from "./types"; 3 | 4 | export function serializeElrondTransaction({ 5 | amount, 6 | data, 7 | family, 8 | fees, 9 | gasLimit, 10 | mode, 11 | recipient, 12 | }: ElrondTransaction): RawElrondTransaction { 13 | return { 14 | family, 15 | amount: amount.toString(), 16 | recipient, 17 | mode, 18 | fees: fees ? fees.toString() : undefined, 19 | data, 20 | gasLimit, 21 | }; 22 | } 23 | 24 | export function deserializeElrondTransaction({ 25 | amount, 26 | data, 27 | family, 28 | fees, 29 | gasLimit, 30 | mode, 31 | recipient, 32 | }: RawElrondTransaction): ElrondTransaction { 33 | return { 34 | family, 35 | mode, 36 | amount: new BigNumber(amount), 37 | recipient, 38 | fees: fees ? new BigNumber(fees) : undefined, 39 | data, 40 | gasLimit, 41 | }; 42 | } 43 | -------------------------------------------------------------------------------- /packages/core/src/families/elrond/types.ts: -------------------------------------------------------------------------------- 1 | import type BigNumber from "bignumber.js"; 2 | import type { z } from "zod"; 3 | import type { TransactionCommon } from "../index"; 4 | import type { 5 | ElrondOperationMode, 6 | schemaRawElrondTransaction, 7 | } from "./validation"; 8 | 9 | export type ElrondTransaction = TransactionCommon & { 10 | readonly family: RawElrondTransaction["family"]; 11 | mode: ElrondOperationMode; 12 | data?: string; 13 | fees?: BigNumber; 14 | gasLimit: number; 15 | }; 16 | 17 | export type RawElrondTransaction = z.infer; 18 | -------------------------------------------------------------------------------- /packages/core/src/families/elrond/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaOperationMode = z.enum([ 5 | "send", 6 | "delegate", 7 | "reDelegateRewards", 8 | "unDelegate", 9 | "claimRewards", 10 | "withdraw", 11 | ]); 12 | 13 | export type ElrondOperationMode = z.infer; 14 | 15 | export const schemaRawElrondTransaction = schemaTransactionCommon.extend({ 16 | family: z.literal(schemaFamilies.enum.elrond), 17 | mode: z.union([ 18 | z.literal("send"), 19 | z.literal("delegate"), 20 | z.literal("reDelegateRewards"), 21 | z.literal("unDelegate"), 22 | z.literal("claimRewards"), 23 | z.literal("withdraw"), 24 | ]), 25 | fees: z.string().optional(), 26 | data: z.string().optional(), 27 | gasLimit: z.number(), 28 | }); 29 | -------------------------------------------------------------------------------- /packages/core/src/families/ethereum/types.ts: -------------------------------------------------------------------------------- 1 | import type BigNumber from "bignumber.js"; 2 | import type { z } from "zod"; 3 | import type { TransactionCommon } from "../index"; 4 | import type { schemaRawEthereumTransaction } from "./validation"; 5 | 6 | export type EthereumTransaction = TransactionCommon & { 7 | readonly family: RawEthereumTransaction["family"]; 8 | nonce?: number; 9 | data?: Buffer; 10 | gasPrice?: BigNumber; 11 | gasLimit?: BigNumber; 12 | maxPriorityFeePerGas?: BigNumber; 13 | maxFeePerGas?: BigNumber; 14 | }; 15 | 16 | export type RawEthereumTransaction = z.infer< 17 | typeof schemaRawEthereumTransaction 18 | >; 19 | -------------------------------------------------------------------------------- /packages/core/src/families/ethereum/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaRawEthereumTransaction = schemaTransactionCommon.extend({ 5 | family: z.literal(schemaFamilies.enum.ethereum), 6 | nonce: z.number().optional(), 7 | data: z.string().optional(), 8 | gasPrice: z.string().optional(), 9 | gasLimit: z.string().optional(), 10 | maxPriorityFeePerGas: z.string().optional(), 11 | maxFeePerGas: z.string().optional(), 12 | }); 13 | -------------------------------------------------------------------------------- /packages/core/src/families/filecoin/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { FilecoinTransaction, RawFilecoinTransaction } from "./types"; 3 | 4 | export function serializeFilecoinTransaction({ 5 | amount, 6 | data = undefined, 7 | family, 8 | method, 9 | nonce, 10 | params = undefined, 11 | gasLimit, 12 | gasFeeCap, 13 | gasPremium, 14 | recipient, 15 | version, 16 | }: FilecoinTransaction): RawFilecoinTransaction { 17 | return { 18 | amount: amount.toString(), 19 | data: data ? data.toString("hex") : undefined, 20 | family, 21 | gasLimit: gasLimit.toNumber(), 22 | gasFeeCap: gasFeeCap.toString(), 23 | gasPremium: gasPremium.toString(), 24 | method, 25 | nonce, 26 | params, 27 | recipient, 28 | version, 29 | }; 30 | } 31 | 32 | export function deserializeFilecoinTransaction({ 33 | amount, 34 | data = undefined, 35 | family, 36 | method, 37 | nonce, 38 | params = undefined, 39 | gasLimit, 40 | gasFeeCap, 41 | gasPremium, 42 | recipient, 43 | version, 44 | }: RawFilecoinTransaction): FilecoinTransaction { 45 | return { 46 | amount: new BigNumber(amount), 47 | data: data ? Buffer.from(data, "hex") : undefined, 48 | family, 49 | gasLimit: new BigNumber(gasLimit), 50 | gasFeeCap: new BigNumber(gasFeeCap), 51 | gasPremium: new BigNumber(gasPremium), 52 | nonce, 53 | method, 54 | params, 55 | recipient, 56 | version, 57 | }; 58 | } 59 | -------------------------------------------------------------------------------- /packages/core/src/families/filecoin/types.ts: -------------------------------------------------------------------------------- 1 | import type BigNumber from "bignumber.js"; 2 | import type { z } from "zod"; 3 | import type { TransactionCommon } from "../index"; 4 | import type { schemaRawFilecoinTransaction } from "./validation"; 5 | 6 | export type FilecoinTransaction = TransactionCommon & { 7 | readonly family: RawFilecoinTransaction["family"]; 8 | nonce: number; 9 | data?: Buffer; 10 | method: number; 11 | version: number; 12 | params?: string; 13 | gasLimit: BigNumber; 14 | gasFeeCap: BigNumber; 15 | gasPremium: BigNumber; 16 | }; 17 | 18 | export type RawFilecoinTransaction = z.infer< 19 | typeof schemaRawFilecoinTransaction 20 | >; 21 | -------------------------------------------------------------------------------- /packages/core/src/families/filecoin/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaRawFilecoinTransaction = schemaTransactionCommon.extend({ 5 | data: z.string().optional(), 6 | family: z.literal(schemaFamilies.enum.filecoin), 7 | gasLimit: z.number(), 8 | gasFeeCap: z.string(), 9 | gasPremium: z.string(), 10 | method: z.number(), 11 | nonce: z.number(), 12 | params: z.string().optional(), 13 | version: z.number(), 14 | }); 15 | -------------------------------------------------------------------------------- /packages/core/src/families/hedera/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { HederaTransaction, RawHederaTransaction } from "./types"; 3 | 4 | export function serializeHederaTransaction({ 5 | amount, 6 | family, 7 | memo = undefined, 8 | recipient, 9 | }: HederaTransaction): RawHederaTransaction { 10 | return { 11 | amount: amount.toString(), 12 | family, 13 | memo, 14 | recipient, 15 | }; 16 | } 17 | 18 | export function deserializeHederaTransaction({ 19 | amount, 20 | family, 21 | memo = undefined, 22 | recipient, 23 | }: RawHederaTransaction): HederaTransaction { 24 | return { 25 | amount: new BigNumber(amount), 26 | family, 27 | memo, 28 | recipient, 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /packages/core/src/families/hedera/types.ts: -------------------------------------------------------------------------------- 1 | import type { z } from "zod"; 2 | import type { TransactionCommon } from "../index"; 3 | import type { schemaRawHederaTransaction } from "./validation"; 4 | 5 | export type HederaTransaction = TransactionCommon & { 6 | readonly family: RawHederaTransaction["family"]; 7 | memo?: string; 8 | }; 9 | 10 | export type RawHederaTransaction = z.infer; 11 | -------------------------------------------------------------------------------- /packages/core/src/families/hedera/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaRawHederaTransaction = schemaTransactionCommon.extend({ 5 | family: z.literal(schemaFamilies.enum.hedera), 6 | memo: z.string().max(100).optional(), 7 | }); 8 | -------------------------------------------------------------------------------- /packages/core/src/families/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./algorand/types"; 2 | export * from "./aptos/types"; 3 | export * from "./bitcoin/types"; 4 | export * from "./cardano/types"; 5 | export * from "./casper/types"; 6 | export * from "./celo/types"; 7 | export * from "./cosmos/types"; 8 | export * from "./crypto_org/types"; 9 | export * from "./elrond/types"; 10 | export * from "./ethereum/types"; 11 | export * from "./filecoin/types"; 12 | export * from "./hedera/types"; 13 | export * from "./internet_computer/types"; 14 | export * from "./near/types"; 15 | export * from "./neo/types"; 16 | export * from "./polkadot/types"; 17 | export * from "./ripple/types"; 18 | export * from "./solana/types"; 19 | export * from "./stacks/types"; 20 | export * from "./stellar/types"; 21 | export * from "./sui/types"; 22 | export * from "./tezos/types"; 23 | export * from "./ton/types"; 24 | export * from "./tron/types"; 25 | export * from "./vechain/types"; 26 | 27 | export * from "./common"; 28 | export * from "./serializer"; 29 | export * from "./types"; 30 | export * from "./validation"; 31 | -------------------------------------------------------------------------------- /packages/core/src/families/internet_computer/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { 3 | RawInternetComputerTransaction, 4 | InternetComputerTransaction, 5 | } from "./types"; 6 | 7 | export const serializeInternetComputerTransaction = ({ 8 | amount, 9 | recipient, 10 | family, 11 | fees, 12 | memo, 13 | }: InternetComputerTransaction): RawInternetComputerTransaction => ({ 14 | amount: amount.toFixed(), 15 | recipient, 16 | family, 17 | fees: fees.toString(), 18 | memo, 19 | }); 20 | 21 | export const deserializeInternetComputerTransaction = ({ 22 | amount, 23 | recipient, 24 | family, 25 | fees, 26 | memo, 27 | }: RawInternetComputerTransaction): InternetComputerTransaction => ({ 28 | amount: new BigNumber(amount), 29 | recipient, 30 | family, 31 | fees: new BigNumber(fees), 32 | memo, 33 | }); 34 | -------------------------------------------------------------------------------- /packages/core/src/families/internet_computer/types.ts: -------------------------------------------------------------------------------- 1 | import type { z } from "zod"; 2 | import type { TransactionCommon } from "../index"; 3 | import type { schemaRawInternetComputerTransaction } from "./validation"; 4 | import type BigNumber from "bignumber.js"; 5 | 6 | export type InternetComputerTransaction = TransactionCommon & { 7 | readonly family: RawInternetComputerTransaction["family"]; 8 | fees: BigNumber; 9 | memo?: string; 10 | }; 11 | 12 | export type RawInternetComputerTransaction = z.infer< 13 | typeof schemaRawInternetComputerTransaction 14 | >; 15 | -------------------------------------------------------------------------------- /packages/core/src/families/internet_computer/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaRawInternetComputerTransaction = 5 | schemaTransactionCommon.extend({ 6 | family: z.literal(schemaFamilies.enum.internet_computer), 7 | fees: z.string(), 8 | memo: z.string().optional(), 9 | }); 10 | -------------------------------------------------------------------------------- /packages/core/src/families/near/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { RawNearTransaction, NearTransaction } from "./types"; 3 | 4 | export function serialize({ 5 | amount, 6 | recipient, 7 | family, 8 | mode, 9 | fees, 10 | }: NearTransaction): RawNearTransaction { 11 | return { 12 | amount: amount.toString(), 13 | recipient, 14 | family, 15 | mode, 16 | fees: fees?.toString(), 17 | }; 18 | } 19 | 20 | export function deserialize({ 21 | amount, 22 | recipient, 23 | family, 24 | mode, 25 | fees, 26 | }: RawNearTransaction): NearTransaction { 27 | return { 28 | amount: new BigNumber(amount), 29 | recipient, 30 | family, 31 | mode, 32 | fees: fees ? new BigNumber(fees) : undefined, 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /packages/core/src/families/near/types.ts: -------------------------------------------------------------------------------- 1 | import type BigNumber from "bignumber.js"; 2 | import type { z } from "zod"; 3 | import type { TransactionCommon } from "../index"; 4 | import type { schemaRawNearTransaction } from "./validation"; 5 | 6 | export type NearTransaction = TransactionCommon & { 7 | readonly family: RawNearTransaction["family"]; 8 | mode: string; 9 | fees?: BigNumber; 10 | }; 11 | 12 | export type RawNearTransaction = z.infer; 13 | -------------------------------------------------------------------------------- /packages/core/src/families/near/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaRawNearTransaction = schemaTransactionCommon.extend({ 5 | family: z.literal(schemaFamilies.enum.near), 6 | mode: z.string(), 7 | fees: z.string().optional(), 8 | }); 9 | -------------------------------------------------------------------------------- /packages/core/src/families/neo/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { RawNeoTransaction, NeoTransaction } from "./types"; 3 | 4 | export function serialize({ 5 | amount, 6 | recipient, 7 | family, 8 | }: NeoTransaction): RawNeoTransaction { 9 | return { 10 | amount: amount.toString(), 11 | recipient, 12 | family, 13 | }; 14 | } 15 | 16 | export function deserialize({ 17 | amount, 18 | recipient, 19 | family, 20 | }: RawNeoTransaction): NeoTransaction { 21 | return { 22 | amount: new BigNumber(amount), 23 | recipient, 24 | family, 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /packages/core/src/families/neo/types.ts: -------------------------------------------------------------------------------- 1 | import type { z } from "zod"; 2 | import type { TransactionCommon } from "../index"; 3 | import type { schemaRawNeoTransaction } from "./validation"; 4 | 5 | export type NeoTransaction = TransactionCommon & { 6 | readonly family: RawNeoTransaction["family"]; 7 | }; 8 | 9 | export type RawNeoTransaction = z.infer; 10 | -------------------------------------------------------------------------------- /packages/core/src/families/neo/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaRawNeoTransaction = schemaTransactionCommon.extend({ 5 | family: z.literal(schemaFamilies.enum.neo), 6 | }); 7 | -------------------------------------------------------------------------------- /packages/core/src/families/polkadot/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { PolkadotTransaction, RawPolkadotTransaction } from "./types"; 3 | 4 | export const serializePolkadotTransaction = ({ 5 | amount, 6 | recipient, 7 | family, 8 | mode, 9 | fee, 10 | era, 11 | validators, 12 | numOfSlashingSpans, 13 | rewardDestination, 14 | }: PolkadotTransaction): RawPolkadotTransaction => ({ 15 | amount: amount.toString(), 16 | recipient, 17 | family, 18 | mode, 19 | fee: fee ? fee.toString() : undefined, 20 | era, 21 | validators, 22 | numOfSlashingSpans, 23 | rewardDestination, 24 | }); 25 | 26 | export const deserializePolkadotTransaction = ({ 27 | amount, 28 | recipient, 29 | family, 30 | mode, 31 | fee, 32 | era, 33 | validators, 34 | numOfSlashingSpans, 35 | rewardDestination, 36 | }: RawPolkadotTransaction): PolkadotTransaction => ({ 37 | amount: new BigNumber(amount), 38 | recipient, 39 | family, 40 | mode, 41 | fee: fee ? new BigNumber(fee) : undefined, 42 | era, 43 | validators, 44 | numOfSlashingSpans, 45 | rewardDestination, 46 | }); 47 | -------------------------------------------------------------------------------- /packages/core/src/families/polkadot/types.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { z } from "zod"; 3 | import { TransactionCommon } from "../types"; 4 | import type { 5 | schemaPolkadotOperationMode, 6 | schemaPolkadotRewardDestination, 7 | schemaRawPolkadotTransaction, 8 | } from "./validation"; 9 | 10 | export type PolkadotOperationMode = z.infer; 11 | export type PolkadotRewardDestination = z.infer< 12 | typeof schemaPolkadotRewardDestination 13 | >; 14 | 15 | export type PolkadotTransaction = TransactionCommon & { 16 | readonly family: RawPolkadotTransaction["family"]; 17 | mode: PolkadotOperationMode; 18 | fee?: BigNumber; 19 | era?: number; 20 | validators?: string[]; 21 | numOfSlashingSpans?: number; 22 | rewardDestination?: PolkadotRewardDestination; 23 | }; 24 | 25 | export type RawPolkadotTransaction = z.infer< 26 | typeof schemaRawPolkadotTransaction 27 | >; 28 | -------------------------------------------------------------------------------- /packages/core/src/families/polkadot/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaPolkadotOperationMode = z.enum([ 5 | "send", 6 | "bond", 7 | "unbond", 8 | "rebond", 9 | "withdrawUnbonded", 10 | "setController", 11 | "nominate", 12 | "chill", 13 | "claimReward", 14 | ]); 15 | 16 | export const schemaPolkadotRewardDestination = z.enum([ 17 | "Staked", 18 | "Stash", 19 | "Controller", 20 | "Account", 21 | "None", 22 | ]); 23 | 24 | export const schemaRawPolkadotTransaction = schemaTransactionCommon.extend({ 25 | family: z.literal(schemaFamilies.enum.polkadot), 26 | mode: schemaPolkadotOperationMode, 27 | fee: z.string().optional(), 28 | era: z.number().optional(), 29 | validators: z.array(z.string()).optional(), 30 | rewardDestination: schemaPolkadotRewardDestination.optional(), 31 | numOfSlashingSpans: z.number().optional(), 32 | }); 33 | -------------------------------------------------------------------------------- /packages/core/src/families/ripple/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { RawRippleTransaction, RippleTransaction } from "./types"; 3 | 4 | export const serializeRippleTransaction = ({ 5 | family, 6 | fee, 7 | tag, 8 | amount, 9 | recipient, 10 | }: RippleTransaction): RawRippleTransaction => ({ 11 | family, 12 | amount: amount.toString(), 13 | recipient, 14 | fee: fee ? fee.toString() : undefined, 15 | tag, 16 | }); 17 | 18 | export const deserializeRippleTransaction = ({ 19 | family, 20 | fee, 21 | tag, 22 | amount, 23 | recipient, 24 | }: RawRippleTransaction): RippleTransaction => ({ 25 | family, 26 | amount: new BigNumber(amount), 27 | recipient, 28 | fee: fee ? new BigNumber(fee) : undefined, 29 | tag, 30 | }); 31 | -------------------------------------------------------------------------------- /packages/core/src/families/ripple/types.ts: -------------------------------------------------------------------------------- 1 | import type BigNumber from "bignumber.js"; 2 | import type { z } from "zod"; 3 | import type { TransactionCommon } from "../index"; 4 | import type { schemaRawRippleTransaction } from "./validation"; 5 | 6 | export type RippleTransaction = TransactionCommon & { 7 | readonly family: RawRippleTransaction["family"]; 8 | fee?: BigNumber; 9 | tag: number; 10 | }; 11 | 12 | export type RawRippleTransaction = z.infer; 13 | -------------------------------------------------------------------------------- /packages/core/src/families/ripple/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaRawRippleTransaction = schemaTransactionCommon.extend({ 5 | family: z.literal(schemaFamilies.enum.ripple), 6 | fee: z.string().optional(), 7 | tag: z.number(), 8 | }); 9 | -------------------------------------------------------------------------------- /packages/core/src/families/solana/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { SolanaTransaction, RawSolanaTransaction } from "./types"; 3 | 4 | export function serializeSolanaTransaction({ 5 | amount, 6 | family, 7 | model, 8 | recipient, 9 | raw, 10 | }: SolanaTransaction): RawSolanaTransaction { 11 | return { 12 | amount: amount.toString(), 13 | family, 14 | model: JSON.stringify(model), 15 | recipient, 16 | raw, 17 | }; 18 | } 19 | 20 | export function deserializeSolanaTransaction({ 21 | family, 22 | amount, 23 | model, 24 | recipient, 25 | raw, 26 | }: RawSolanaTransaction): SolanaTransaction { 27 | return { 28 | amount: new BigNumber(amount), 29 | family, 30 | // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment 31 | model: JSON.parse(model), 32 | recipient, 33 | raw, 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /packages/core/src/families/solana/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaRawSolanaTransaction = schemaTransactionCommon.extend({ 5 | family: z.literal(schemaFamilies.enum.solana), 6 | model: z.string(), 7 | raw: z.optional(z.string()), 8 | }); 9 | -------------------------------------------------------------------------------- /packages/core/src/families/stacks/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { RawStacksTransaction, StacksTransaction } from "./types"; 3 | 4 | export const serializeStacksTransaction = ({ 5 | amount, 6 | recipient, 7 | family, 8 | fee, 9 | nonce, 10 | memo, 11 | network, 12 | anchorMode, 13 | }: StacksTransaction): RawStacksTransaction => ({ 14 | amount: amount.toString(), 15 | recipient, 16 | family, 17 | fee: fee?.toString(), 18 | nonce: nonce?.toString(), 19 | memo, 20 | network, 21 | anchorMode, 22 | }); 23 | 24 | export const deserializeStacksTransaction = ({ 25 | amount, 26 | recipient, 27 | family, 28 | fee, 29 | nonce, 30 | memo, 31 | network, 32 | anchorMode, 33 | }: RawStacksTransaction): StacksTransaction => ({ 34 | amount: new BigNumber(amount), 35 | recipient, 36 | family, 37 | fee: fee ? new BigNumber(fee) : undefined, 38 | nonce: nonce ? new BigNumber(nonce) : undefined, 39 | memo, 40 | network: network === "mainnet" ? network : "testnet", 41 | anchorMode, 42 | }); 43 | -------------------------------------------------------------------------------- /packages/core/src/families/stacks/types.ts: -------------------------------------------------------------------------------- 1 | import type { z } from "zod"; 2 | import type { TransactionCommon } from "../index"; 3 | import type { schemaRawStacksTransaction } from "./validation"; 4 | import type BigNumber from "bignumber.js"; 5 | import type { AnchorMode } from "@stacks/transactions"; 6 | 7 | export type StacksNetworks = "mainnet" | "testnet"; 8 | 9 | export type StacksTransaction = TransactionCommon & { 10 | readonly family: RawStacksTransaction["family"]; 11 | fee?: BigNumber; 12 | nonce?: BigNumber; 13 | memo?: string; 14 | network: StacksNetworks; 15 | anchorMode: AnchorMode; 16 | }; 17 | 18 | export type RawStacksTransaction = z.infer; 19 | -------------------------------------------------------------------------------- /packages/core/src/families/stacks/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaRawStacksTransaction = schemaTransactionCommon.extend({ 5 | family: z.literal(schemaFamilies.enum.stacks), 6 | fee: z.string().optional(), 7 | nonce: z.string().optional(), 8 | memo: z.string().optional(), 9 | network: z.string(), 10 | anchorMode: z.number(), 11 | }); 12 | -------------------------------------------------------------------------------- /packages/core/src/families/stellar/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { RawStellarTransaction, StellarTransaction } from "./types"; 3 | 4 | export const serializeStellarTransaction = ({ 5 | amount, 6 | recipient, 7 | family, 8 | fees, 9 | memoType, 10 | memoValue, 11 | }: StellarTransaction): RawStellarTransaction => ({ 12 | amount: amount.toString(), 13 | recipient, 14 | family, 15 | fees: fees ? fees.toString() : undefined, 16 | memoType, 17 | memoValue, 18 | }); 19 | 20 | export const deserializeStellarTransaction = ({ 21 | amount, 22 | recipient, 23 | family, 24 | fees, 25 | memoType, 26 | memoValue, 27 | }: RawStellarTransaction): StellarTransaction => ({ 28 | amount: new BigNumber(amount), 29 | recipient, 30 | family, 31 | fees: fees ? new BigNumber(fees) : undefined, 32 | memoType, 33 | memoValue, 34 | }); 35 | -------------------------------------------------------------------------------- /packages/core/src/families/stellar/types.ts: -------------------------------------------------------------------------------- 1 | import type BigNumber from "bignumber.js"; 2 | import type { z } from "zod"; 3 | import type { TransactionCommon } from "../index"; 4 | import type { 5 | schemaRawStellarTransaction, 6 | stellarMemoTypeEnum, 7 | } from "./validation"; 8 | 9 | export type StellarTransaction = TransactionCommon & { 10 | readonly family: RawStellarTransaction["family"]; 11 | fees?: BigNumber; 12 | memoType?: StellarMemoType; 13 | memoValue?: string; 14 | }; 15 | 16 | export type RawStellarTransaction = z.infer; 17 | 18 | export type StellarMemoType = z.infer; 19 | -------------------------------------------------------------------------------- /packages/core/src/families/stellar/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const stellarMemoTypeEnum = z.enum([ 5 | "MEMO_TEXT", 6 | "MEMO_ID", 7 | "MEMO_HASH", 8 | "MEMO_RETURN", 9 | ]); 10 | 11 | export const schemaRawStellarTransaction = schemaTransactionCommon.extend({ 12 | family: z.literal(schemaFamilies.enum.stellar), 13 | fees: z.string().optional(), 14 | memoType: stellarMemoTypeEnum.optional(), 15 | memoValue: z.string().optional(), 16 | }); 17 | -------------------------------------------------------------------------------- /packages/core/src/families/sui/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { RawSuiTransaction, SuiTransaction } from "./types"; 3 | 4 | export function serializeSuiTransaction({ 5 | amount, 6 | recipient, 7 | family, 8 | mode, 9 | fees, 10 | }: SuiTransaction): RawSuiTransaction { 11 | return { 12 | amount: amount.toString(), 13 | recipient, 14 | family, 15 | mode, 16 | fees: fees?.toString(), 17 | }; 18 | } 19 | 20 | export function deserializeSuiTransaction({ 21 | amount, 22 | recipient, 23 | family, 24 | mode, 25 | fees, 26 | }: RawSuiTransaction): SuiTransaction { 27 | return { 28 | amount: new BigNumber(amount), 29 | recipient, 30 | family, 31 | mode, 32 | fees: fees ? new BigNumber(fees) : undefined, 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /packages/core/src/families/sui/types.ts: -------------------------------------------------------------------------------- 1 | import type BigNumber from "bignumber.js"; 2 | import type { z } from "zod"; 3 | import type { TransactionCommon } from "../index"; 4 | import type { schemaRawSuiTransaction } from "./validation"; 5 | 6 | export type SuiTransaction = TransactionCommon & { 7 | readonly family: RawSuiTransaction["family"]; 8 | mode: string; 9 | fees?: BigNumber; 10 | }; 11 | 12 | export type RawSuiTransaction = z.infer; 13 | -------------------------------------------------------------------------------- /packages/core/src/families/sui/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaRawSuiTransaction = schemaTransactionCommon.extend({ 5 | family: z.literal(schemaFamilies.enum.sui), 6 | mode: z.string(), 7 | fees: z.string().optional(), 8 | }); 9 | -------------------------------------------------------------------------------- /packages/core/src/families/tezos/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { RawTezosTransaction, TezosTransaction } from "./types"; 3 | 4 | export const serializeTezosTransaction = ({ 5 | amount, 6 | recipient, 7 | family, 8 | mode, 9 | fees, 10 | gasLimit, 11 | }: TezosTransaction): RawTezosTransaction => ({ 12 | amount: amount.toString(), 13 | recipient, 14 | family, 15 | mode, 16 | fees: fees ? fees.toString() : undefined, 17 | gasLimit: gasLimit ? gasLimit.toString() : undefined, 18 | }); 19 | 20 | export const deserializeTezosTransaction = ({ 21 | amount, 22 | recipient, 23 | family, 24 | mode, 25 | fees, 26 | gasLimit, 27 | }: RawTezosTransaction): TezosTransaction => ({ 28 | amount: new BigNumber(amount), 29 | recipient, 30 | family, 31 | mode, 32 | fees: fees ? new BigNumber(fees) : undefined, 33 | gasLimit: gasLimit ? new BigNumber(gasLimit) : undefined, 34 | }); 35 | -------------------------------------------------------------------------------- /packages/core/src/families/tezos/types.ts: -------------------------------------------------------------------------------- 1 | import type BigNumber from "bignumber.js"; 2 | import type { z } from "zod"; 3 | import type { TransactionCommon } from "../index"; 4 | import type { 5 | schemaRawTezosTransaction, 6 | schemaTezosOperationMode, 7 | } from "./validation"; 8 | 9 | export type TezosOperationMode = z.infer; 10 | 11 | export type TezosTransaction = TransactionCommon & { 12 | readonly family: RawTezosTransaction["family"]; 13 | mode: TezosOperationMode; 14 | fees?: BigNumber; 15 | gasLimit?: BigNumber; 16 | }; 17 | 18 | export type RawTezosTransaction = z.infer; 19 | -------------------------------------------------------------------------------- /packages/core/src/families/tezos/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaTezosOperationMode = z.enum([ 5 | "send", 6 | "delegate", 7 | "undelegate", 8 | ]); 9 | 10 | export const schemaRawTezosTransaction = schemaTransactionCommon.extend({ 11 | family: z.literal(schemaFamilies.enum.tezos), 12 | mode: schemaTezosOperationMode, 13 | fees: z.string().optional(), 14 | gasLimit: z.string().optional(), 15 | }); 16 | -------------------------------------------------------------------------------- /packages/core/src/families/tron/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { RawTronTransaction, TronTransaction } from "./types"; 3 | 4 | export const serializeTronTransaction = ({ 5 | amount, 6 | recipient, 7 | family, 8 | mode, 9 | resource, 10 | duration, 11 | votes, 12 | }: TronTransaction): RawTronTransaction => ({ 13 | amount: amount.toString(), 14 | recipient, 15 | family, 16 | mode, 17 | resource, 18 | duration, 19 | votes, 20 | }); 21 | 22 | export const deserializeTronTransaction = ({ 23 | amount, 24 | recipient, 25 | family, 26 | mode, 27 | resource, 28 | duration, 29 | votes, 30 | }: RawTronTransaction): TronTransaction => ({ 31 | amount: new BigNumber(amount), 32 | recipient, 33 | family, 34 | mode, 35 | resource, 36 | duration, 37 | votes, 38 | }); 39 | -------------------------------------------------------------------------------- /packages/core/src/families/tron/types.ts: -------------------------------------------------------------------------------- 1 | import type { z } from "zod"; 2 | import type { TransactionCommon } from "../index"; 3 | import type { 4 | schemaRawTronTransaction, 5 | schemaTronOperationMode, 6 | schemaTronResource, 7 | schemaTronVotes, 8 | } from "./validation"; 9 | 10 | export type TronOperationMode = z.infer; 11 | 12 | export type TronResource = z.infer; 13 | export type TronVote = z.infer; 14 | 15 | export type TronTransaction = TransactionCommon & { 16 | readonly family: RawTronTransaction["family"]; 17 | mode: TronOperationMode; 18 | resource?: TronResource; 19 | duration?: number; 20 | votes?: TronVote[]; 21 | }; 22 | 23 | export type RawTronTransaction = z.infer; 24 | -------------------------------------------------------------------------------- /packages/core/src/families/tron/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | export const schemaTronOperationMode = z.enum([ 5 | "send", 6 | "freeze", 7 | "unfreeze", 8 | "vote", 9 | "claimReward", 10 | "withdrawExpireUnfreeze", 11 | "unDelegateResource", 12 | "legacyUnfreeze", 13 | ]); 14 | 15 | export const schemaTronResource = z.enum(["BANDWIDTH", "ENERGY"]); 16 | 17 | export const schemaTronVotes = z.object({ 18 | address: z.string(), 19 | voteCount: z.number(), 20 | }); 21 | 22 | export const schemaRawTronTransaction = schemaTransactionCommon.extend({ 23 | family: z.literal(schemaFamilies.enum.tron), 24 | mode: schemaTronOperationMode, 25 | resource: schemaTronResource.optional(), 26 | duration: z.number().optional(), 27 | votes: z.array(schemaTronVotes).optional(), 28 | }); 29 | -------------------------------------------------------------------------------- /packages/core/src/families/vechain/serializer.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import type { RawVechainTransaction, VechainTransaction } from "./types"; 3 | 4 | export const serializeVechainTransaction = ({ 5 | amount, 6 | recipient, 7 | family, 8 | estimatedFees, 9 | body, 10 | }: VechainTransaction): RawVechainTransaction => ({ 11 | amount: amount.toString(), 12 | recipient, 13 | family, 14 | estimatedFees, 15 | body, 16 | }); 17 | 18 | export const deserializeVechainTransaction = ({ 19 | amount, 20 | recipient, 21 | family, 22 | estimatedFees, 23 | body, 24 | }: RawVechainTransaction): VechainTransaction => ({ 25 | amount: new BigNumber(amount), 26 | recipient, 27 | family, 28 | estimatedFees, 29 | body, 30 | }); 31 | -------------------------------------------------------------------------------- /packages/core/src/families/vechain/types.ts: -------------------------------------------------------------------------------- 1 | import type { Transaction as ThorTransaction } from "thor-devkit"; 2 | import type { z } from "zod"; 3 | import type { TransactionCommon } from "../index"; 4 | import type { schemaRawVechainTransaction } from "./validation"; 5 | 6 | export type VechainTransaction = TransactionCommon & { 7 | readonly family: RawVechainTransaction["family"]; 8 | estimatedFees: string; 9 | body: ThorTransaction.Body; 10 | }; 11 | 12 | export type RawVechainTransaction = z.infer; 13 | -------------------------------------------------------------------------------- /packages/core/src/families/vechain/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaFamilies, schemaTransactionCommon } from "../common"; 3 | 4 | // Generated from VeChain Thor Transaction types 5 | export const schemaThorTransactionClause = z.object({ 6 | to: z.string().nullable(), 7 | value: z.union([z.string(), z.number()]), 8 | data: z.string(), 9 | }); 10 | 11 | // Generated from VeChain Thor Transaction types 12 | // with Buffer type removed for `reserved.unused` 13 | export const schemaThorTransactionBody = z.object({ 14 | chainTag: z.number(), 15 | blockRef: z.string(), 16 | expiration: z.number(), 17 | clauses: z.array(schemaThorTransactionClause), 18 | gasPriceCoef: z.number(), 19 | gas: z.union([z.string(), z.number()]), 20 | dependsOn: z.string().nullable(), 21 | nonce: z.union([z.string(), z.number()]), 22 | reserved: z 23 | .object({ 24 | features: z.number().optional(), 25 | unused: z.array(z.any()).optional(), 26 | }) 27 | .optional(), 28 | }); 29 | 30 | export const schemaRawVechainTransaction = schemaTransactionCommon.extend({ 31 | family: z.literal(schemaFamilies.enum.vechain), 32 | estimatedFees: z.string(), 33 | body: schemaThorTransactionBody, 34 | }); 35 | -------------------------------------------------------------------------------- /packages/core/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./accounts"; 2 | export * from "./currencies"; 3 | export * from "./families"; 4 | export * from "./logger"; 5 | export * from "./transports"; 6 | export * from "./types"; 7 | export * from "./errors"; 8 | export * from "./JSONRPC"; 9 | export * from "./spec"; 10 | -------------------------------------------------------------------------------- /packages/core/src/logger/index.ts: -------------------------------------------------------------------------------- 1 | /* istanbul ignore file */ 2 | /* eslint-disable no-console */ 3 | /** 4 | * Use for internal usage 5 | * @ignore 6 | */ 7 | export class Logger { 8 | private prefix = ""; 9 | 10 | constructor(namespace?: string) { 11 | this.prefix = namespace ? `[${namespace}] ` : ""; 12 | } 13 | 14 | log(message: string, ...args: unknown[]): void { 15 | console.log( 16 | `%c${this.prefix}${message}`, 17 | "background: #6490f1; color: #fff", 18 | ...args, 19 | ); 20 | } 21 | 22 | warn(message: string, ...args: unknown[]): void { 23 | console.warn( 24 | `%c${this.prefix}${message}`, 25 | "background: #6490f1; color: #f80", 26 | ...args, 27 | ); 28 | } 29 | 30 | debug(message: string, ...args: unknown[]): void { 31 | console.debug( 32 | `%c${this.prefix}${message}`, 33 | "background: #6490f1; color: #777", 34 | ...args, 35 | ); 36 | } 37 | 38 | error(message: string, ...args: unknown[]): void { 39 | console.error( 40 | `%c${this.prefix}${message}`, 41 | "background: #6490f1; color: #f00", 42 | ...args, 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/core/src/spec/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./rpcHandlers/AppHandlers"; 2 | export * from "./rpcHandlers/WalletHandlers"; 3 | export * from "./types"; 4 | export * from "./methods"; 5 | -------------------------------------------------------------------------------- /packages/core/src/spec/methods.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export type MethodId = z.infer; 4 | 5 | export const schemaRPCMethod = z.enum([ 6 | "account.list", 7 | "account.receive", 8 | "account.request", 9 | "currency.list", 10 | "device.close", 11 | "device.exchange", 12 | "device.transport", 13 | "message.sign", 14 | "transaction.sign", 15 | "transaction.signAndBroadcast", 16 | "wallet.capabilities", 17 | "wallet.info", 18 | "wallet.userId", 19 | ]); 20 | -------------------------------------------------------------------------------- /packages/core/src/spec/rpcHandlers/AppHandlers.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 2 | export type UnknownCustomEvent = Record<`event.${string}`, any>; 3 | 4 | export type AppHandlers = { 5 | "event.account.updated": undefined; 6 | } & GenericCustomEvent; 7 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/AccountList.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaRawAccount } from "../../accounts"; 3 | 4 | const schemaAccountListParams = z 5 | .object({ 6 | currencyIds: z.array(z.string()).optional(), 7 | }) 8 | .optional(); 9 | 10 | const schemaAccountListResults = z.object({ 11 | rawAccounts: z.array(schemaRawAccount), 12 | }); 13 | 14 | export const schemaAccountList = { 15 | params: schemaAccountListParams, 16 | result: schemaAccountListResults, 17 | }; 18 | 19 | export type AccountList = { 20 | params: z.infer; 21 | result: z.infer; 22 | }; 23 | 24 | export type AccountListHandler = ( 25 | params: AccountList["params"], 26 | ) => AccountList["result"]; 27 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/AccountReceive.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | const schemaAccountReceiveParams = z.object({ 4 | accountId: z.string(), 5 | tokenCurrency: z.string().optional(), 6 | }); 7 | 8 | const schemaAccountReceiveResults = z.object({ 9 | address: z.string(), 10 | }); 11 | 12 | export const schemaAccountReceive = { 13 | params: schemaAccountReceiveParams, 14 | result: schemaAccountReceiveResults, 15 | }; 16 | 17 | export type AccountReceive = { 18 | params: z.infer; 19 | result: z.infer; 20 | }; 21 | 22 | export type AccountReceiveHandler = ( 23 | params: AccountReceive["params"], 24 | ) => AccountReceive["result"]; 25 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/AccountRequest.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaRawAccount } from "../../accounts"; 3 | 4 | const schemaAccountRequestParams = z.object({ 5 | currencyIds: z.array(z.string()).optional(), 6 | showAccountFilter: z.boolean().optional(), 7 | drawerConfiguration: z 8 | .object({ 9 | assets: z 10 | .object({ 11 | filter: z.string().optional(), 12 | leftElement: z.string().optional(), 13 | rightElement: z.string().optional(), 14 | }) 15 | .optional(), 16 | networks: z 17 | .object({ 18 | leftElement: z.string().optional(), 19 | rightElement: z.string().optional(), 20 | }) 21 | .optional(), 22 | }) 23 | .optional(), 24 | }); 25 | 26 | const schemaAccountRequestResults = z.object({ 27 | rawAccount: schemaRawAccount, 28 | }); 29 | 30 | export const schemaAccountRequest = { 31 | params: schemaAccountRequestParams, 32 | result: schemaAccountRequestResults, 33 | }; 34 | 35 | export type AccountRequest = { 36 | params: z.infer; 37 | result: z.infer; 38 | }; 39 | 40 | export type AccountRequestHandler = ( 41 | params: AccountRequest["params"], 42 | ) => AccountRequest["result"]; 43 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/BitcoinGetAddress.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | const schemaBitcoinGetAddressParams = z.object({ 4 | accountId: z.string(), 5 | derivationPath: z.string().optional(), 6 | }); 7 | 8 | const schemaBitcoinGetAddressResults = z.object({ 9 | address: z.string(), 10 | }); 11 | 12 | export const schemaBitcoinGetAddress = { 13 | params: schemaBitcoinGetAddressParams, 14 | result: schemaBitcoinGetAddressResults, 15 | }; 16 | 17 | export type BitcoinGetAddress = { 18 | params: z.infer; 19 | result: z.infer; 20 | }; 21 | 22 | export type BitcoinGetAddressHandler = ( 23 | params: BitcoinGetAddress["params"], 24 | ) => BitcoinGetAddress["result"]; 25 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/BitcoinGetPublicKey.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | const schemaBitcoinGetPublicKeyParams = z.object({ 4 | accountId: z.string(), 5 | derivationPath: z.string().optional(), 6 | }); 7 | 8 | const schemaBitcoinGetPublicKeyResults = z.object({ 9 | publicKey: z.string(), 10 | }); 11 | 12 | export const schemaBitcoinGetPublicKey = { 13 | params: schemaBitcoinGetPublicKeyParams, 14 | result: schemaBitcoinGetPublicKeyResults, 15 | }; 16 | 17 | export type BitcoinGetPublicKey = { 18 | params: z.infer; 19 | result: z.infer; 20 | }; 21 | 22 | export type BitcoinGetPublicKeyHandler = ( 23 | params: BitcoinGetPublicKey["params"], 24 | ) => BitcoinGetPublicKey["result"]; 25 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/BitcoinGetXPub.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | const schemaBitcoinGetXPubParams = z.object({ 4 | accountId: z.string(), 5 | }); 6 | 7 | const schemaBitcoinGetXPubResults = z.object({ 8 | xPub: z.string(), 9 | }); 10 | 11 | export const schemaBitcoinGetXPub = { 12 | params: schemaBitcoinGetXPubParams, 13 | result: schemaBitcoinGetXPubResults, 14 | }; 15 | 16 | export type BitcoinGetXPub = { 17 | params: z.infer; 18 | result: z.infer; 19 | }; 20 | 21 | export type BitcoinGetXPubHandler = ( 22 | params: BitcoinGetXPub["params"], 23 | ) => BitcoinGetXPub["result"]; 24 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/CurrencyList.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaCurrency } from "../../currencies"; 3 | 4 | const schemaCurrencyListParams = z 5 | .object({ 6 | currencyIds: z.array(z.string()).optional(), 7 | }) 8 | .optional(); 9 | 10 | const schemaCurrencyListResult = z.object({ 11 | currencies: z.array(schemaCurrency), 12 | }); 13 | 14 | export const schemaCurrencyList = { 15 | params: schemaCurrencyListParams, 16 | result: schemaCurrencyListResult, 17 | }; 18 | 19 | export type CurrencyList = { 20 | params: z.infer; 21 | result: z.infer; 22 | }; 23 | 24 | export type CurrencyListHandler = ( 25 | params: CurrencyList["params"], 26 | ) => CurrencyList["result"]; 27 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/CustomRequest.ts: -------------------------------------------------------------------------------- 1 | import { Promisable } from "../../types"; 2 | 3 | export type CustomRequestHandler = (params: P) => Promisable; 4 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/Device.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const schemaDeviceType = z.enum([ 4 | "blue", 5 | "nanoS", 6 | "nanoSP", 7 | "nanoX", 8 | "stax", 9 | "europa", 10 | ]); 11 | 12 | export type DeviceType = z.infer; 13 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/DeviceClose.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | const schemaDeviceCloseParams = z.object({ 4 | transportId: z.string(), 5 | }); 6 | 7 | const schemaDeviceCloseResults = z.object({ 8 | transportId: z.string(), 9 | }); 10 | 11 | export const schemaDeviceClose = { 12 | params: schemaDeviceCloseParams, 13 | result: schemaDeviceCloseResults, 14 | }; 15 | 16 | export type DeviceClose = { 17 | params: z.infer; 18 | result: z.infer; 19 | }; 20 | 21 | export type DeviceCloseHandler = ( 22 | params: DeviceClose["params"], 23 | ) => DeviceClose["result"]; 24 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/DeviceExchange.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | const schemaDeviceExchangeParams = z.object({ 4 | apduHex: z.string(), 5 | transportId: z.string(), 6 | }); 7 | 8 | const schemaDeviceExchangeResults = z.object({ 9 | responseHex: z.string(), 10 | }); 11 | 12 | export const schemaDeviceExchange = { 13 | params: schemaDeviceExchangeParams, 14 | result: schemaDeviceExchangeResults, 15 | }; 16 | 17 | export type DeviceExchange = { 18 | params: z.infer; 19 | result: z.infer; 20 | }; 21 | 22 | export type DeviceExchangeHandler = ( 23 | params: DeviceExchange["params"], 24 | ) => DeviceExchange["result"]; 25 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/DeviceOpen.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | const schemaDeviceOpenParams = z.object({ 4 | /** ID of the device to select */ 5 | deviceId: z.string(), 6 | }); 7 | 8 | const schemaDeviceOpenResults = z.object({ 9 | transportId: z.string(), 10 | }); 11 | 12 | export const schemaDeviceOpen = { 13 | params: schemaDeviceOpenParams, 14 | result: schemaDeviceOpenResults, 15 | }; 16 | 17 | export type DeviceOpen = { 18 | params: z.infer; 19 | result: z.infer; 20 | }; 21 | 22 | export type DeviceOpenHandler = ( 23 | params: DeviceOpen["params"], 24 | ) => DeviceOpen["result"]; 25 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/DeviceSelect.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaDeviceType } from "./Device"; 3 | 4 | const schemaDeviceSelectParams = z.object({ 5 | /** Select the BOLOS App. If undefined selects BOLOS */ 6 | appName: z.string().optional(), 7 | /** 8 | * Checks the BOLOS App version range. If undefined no checks 9 | * Can be any ranges supported here: https://github.com/npm/node-semver#ranges 10 | */ 11 | appVersionRange: z.string().optional(), 12 | /** 13 | * Checks the BOLOS Firmware version range. If undefined no checks 14 | * Can be any ranges supported here: https://github.com/npm/node-semver#ranges 15 | */ 16 | firmwareVersionRange: z.string().optional(), 17 | /** 18 | * Checks if the device is seeded. If undefined no checks 19 | */ 20 | seeded: z.boolean().optional(), 21 | /** 22 | * Checks if the device matches one of the types. If undefined no checks 23 | */ 24 | devices: schemaDeviceType.array().nonempty().optional(), 25 | }); 26 | 27 | const schemaDeviceSelectResults = z.object({ 28 | deviceId: z.string(), 29 | }); 30 | 31 | export const schemaDeviceSelect = { 32 | params: schemaDeviceSelectParams, 33 | result: schemaDeviceSelectResults, 34 | }; 35 | 36 | export type DeviceSelect = { 37 | params: z.infer; 38 | result: z.infer; 39 | }; 40 | 41 | export type DeviceSelectHandler = ( 42 | params: DeviceSelect["params"], 43 | ) => DeviceSelect["result"]; 44 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/ExchangeStart.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | const schemaExchangeType = z.enum([ 4 | "SWAP", 5 | "SELL", 6 | "FUND", 7 | "SWAP_NG", 8 | "SELL_NG", 9 | "FUND_NG", 10 | ]); 11 | 12 | const schemaExchangeStartParams = z.object({ 13 | exchangeType: schemaExchangeType, 14 | }); 15 | 16 | const schemaExchangeStartResults = z.object({ 17 | transactionId: z.string(), 18 | }); 19 | 20 | export const schemaExchangeStart = { 21 | params: schemaExchangeStartParams, 22 | result: schemaExchangeStartResults, 23 | }; 24 | 25 | export type ExchangeStart = { 26 | params: z.infer; 27 | result: z.infer; 28 | }; 29 | 30 | export type ExchangeStartHandler = ( 31 | params: ExchangeStart["params"], 32 | ) => ExchangeStart["result"]; 33 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/MessageSign.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | const schemaMessageOptions = z.object({ 4 | hwAppId: z.string().optional(), 5 | dependencies: z.array(z.string()).optional(), 6 | }); 7 | 8 | const schemaMessageSignParams = z.object({ 9 | accountId: z.string(), 10 | hexMessage: z.string(), 11 | options: schemaMessageOptions.optional(), 12 | meta: z.record(z.string(), z.unknown()).optional(), 13 | }); 14 | 15 | const schemaMessageSignResults = z.object({ 16 | hexSignedMessage: z.string(), 17 | }); 18 | 19 | export const schemaMessageSign = { 20 | params: schemaMessageSignParams, 21 | result: schemaMessageSignResults, 22 | }; 23 | 24 | export type MessageSign = { 25 | params: z.infer; 26 | result: z.infer; 27 | }; 28 | 29 | export type MessageSignHandler = ( 30 | params: MessageSign["params"], 31 | ) => MessageSign["result"]; 32 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/StorageGet.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | const schemaStorageGetParams = z.object({ 4 | key: z.string().min(1), 5 | storeId: z.string().min(1).optional(), 6 | }); 7 | 8 | const schemaStorageGetResults = z.object({ 9 | value: z.string().optional(), 10 | }); 11 | 12 | export const schemaStorageGet = { 13 | params: schemaStorageGetParams, 14 | result: schemaStorageGetResults, 15 | }; 16 | 17 | export type StorageGet = { 18 | params: z.infer; 19 | result: z.infer; 20 | }; 21 | 22 | export type StorageGetHandler = ( 23 | params: StorageGet["params"], 24 | ) => StorageGet["result"]; 25 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/StorageSet.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | const schemaStorageSetParams = z.object({ 4 | key: z.string(), 5 | value: z.string(), 6 | storeId: z.string().optional(), 7 | }); 8 | 9 | const schemaStorageSetResults = z.void().optional(); 10 | 11 | export const schemaStorageSet = { 12 | params: schemaStorageSetParams, 13 | result: schemaStorageSetResults, 14 | }; 15 | 16 | export type StorageSet = { 17 | params: z.infer; 18 | result: z.infer; 19 | }; 20 | 21 | export type StorageSetHandler = ( 22 | params: StorageSet["params"], 23 | ) => StorageSet["result"]; 24 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/TransactionSign.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaRawTransaction } from "../../families"; 3 | 4 | const schemaTransactionOptions = z.object({ 5 | hwAppId: z.string().optional(), 6 | dependencies: z.array(z.string()).optional(), 7 | }); 8 | 9 | const schemaTransactionSignParams = z.object({ 10 | accountId: z.string(), 11 | rawTransaction: schemaRawTransaction, 12 | options: schemaTransactionOptions.optional(), 13 | meta: z.record(z.string(), z.unknown()).optional(), 14 | tokenCurrency: z.string().optional(), 15 | }); 16 | 17 | const schemaTransactionSignResults = z.object({ 18 | signedTransactionHex: z.string(), 19 | }); 20 | 21 | export const schemaTransactionSign = { 22 | params: schemaTransactionSignParams, 23 | result: schemaTransactionSignResults, 24 | }; 25 | 26 | export type TransactionSign = { 27 | params: z.infer; 28 | result: z.infer; 29 | }; 30 | 31 | export type TransactionSignHandler = ( 32 | params: TransactionSign["params"], 33 | ) => TransactionSign["result"]; 34 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/TransactionSignAndBroadcast.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | import { schemaRawTransaction } from "../../families"; 3 | 4 | const schemaTransactionOptions = z.object({ 5 | hwAppId: z.string().optional(), 6 | dependencies: z.array(z.string()).optional(), 7 | }); 8 | 9 | const schemaTransactionSignAndBroadcastParams = z.object({ 10 | accountId: z.string(), 11 | rawTransaction: schemaRawTransaction, 12 | options: schemaTransactionOptions.optional(), 13 | meta: z.record(z.string(), z.unknown()).optional(), 14 | tokenCurrency: z.string().optional(), 15 | }); 16 | 17 | const schemaTransactionSignAndBroadcastResults = z.object({ 18 | transactionHash: z.string(), 19 | }); 20 | 21 | export const schemaTransactionSignAndBroadcast = { 22 | params: schemaTransactionSignAndBroadcastParams, 23 | result: schemaTransactionSignAndBroadcastResults, 24 | }; 25 | 26 | export type TransactionSignAndBroadcast = { 27 | params: z.infer; 28 | result: z.infer; 29 | }; 30 | 31 | export type TransactionSignAndBroadcastHandler = ( 32 | params: TransactionSignAndBroadcast["params"], 33 | ) => TransactionSignAndBroadcast["result"]; 34 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/WalletCapabilities.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | const schemaWalletCapabilitiesParams = z.object({}); 4 | 5 | const schemaWalletCapabilitiesResults = z.object({ 6 | methodIds: z.array(z.string()), 7 | }); 8 | 9 | export const schemaWalletCapabilities = { 10 | params: schemaWalletCapabilitiesParams, 11 | result: schemaWalletCapabilitiesResults, 12 | }; 13 | 14 | export type WalletCapabilities = { 15 | params: z.infer; 16 | result: z.infer; 17 | }; 18 | 19 | export type WalletCapabilitiesHandler = ( 20 | params: WalletCapabilities["params"], 21 | ) => WalletCapabilities["result"]; 22 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/WalletInfo.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | const schemaWalletInfoParams = z.object({}); 4 | 5 | const schemaWalletInfoResults = z.object({ 6 | tracking: z.boolean(), 7 | wallet: z.object({ 8 | name: z.string(), 9 | version: z.string(), 10 | }), 11 | }); 12 | 13 | export const schemaWalletInfo = { 14 | params: schemaWalletInfoParams, 15 | result: schemaWalletInfoResults, 16 | }; 17 | 18 | export type WalletInfo = { 19 | params: z.infer; 20 | result: z.infer; 21 | }; 22 | 23 | export type WalletInfoHandler = ( 24 | params: WalletInfo["params"], 25 | ) => WalletInfo["result"]; 26 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/WalletUserId.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | const schemaWalletUserIdParams = z.object({}); 4 | 5 | const schemaWalletUserIdResults = z.object({ 6 | userId: z.string(), 7 | }); 8 | 9 | export const schemaWalletUserId = { 10 | params: schemaWalletUserIdParams, 11 | result: schemaWalletUserIdResults, 12 | }; 13 | 14 | export type WalletUserId = { 15 | params: z.infer; 16 | result: z.infer; 17 | }; 18 | 19 | export type WalletUserIdHandler = ( 20 | params: WalletUserId["params"], 21 | ) => WalletUserId["result"]; 22 | -------------------------------------------------------------------------------- /packages/core/src/spec/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./AccountList"; 2 | export * from "./AccountReceive"; 3 | export * from "./AccountRequest"; 4 | export * from "./BitcoinGetAddress"; 5 | export * from "./BitcoinGetPublicKey"; 6 | export * from "./BitcoinGetXPub"; 7 | export * from "./CurrencyList"; 8 | export * from "./CustomRequest"; 9 | export * from "./Device"; 10 | export * from "./DeviceClose"; 11 | export * from "./DeviceExchange"; 12 | export * from "./DeviceOpen"; 13 | export * from "./DeviceSelect"; 14 | export * from "./DeviceTransport"; 15 | export * from "./ExchangeComplete"; 16 | export * from "./ExchangeStart"; 17 | export * from "./MessageSign"; 18 | export * from "./StorageGet"; 19 | export * from "./StorageSet"; 20 | export * from "./TransactionSign"; 21 | export * from "./TransactionSignAndBroadcast"; 22 | export * from "./WalletCapabilities"; 23 | export * from "./WalletInfo"; 24 | export * from "./WalletUserId"; 25 | -------------------------------------------------------------------------------- /packages/core/src/transports/index.ts: -------------------------------------------------------------------------------- 1 | /* istanbul ignore file */ 2 | export * from "./types"; 3 | export { default as WindowMessageTransport } from "./WindowMessageTransport"; 4 | -------------------------------------------------------------------------------- /packages/core/src/transports/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Simple contract for handling a Message received through a [[Transport]] protocol 3 | * 4 | * @alpha 5 | */ 6 | export type MessageHandler = (message: string) => void; 7 | 8 | /** 9 | * A transport protocol used to communicate with the Ledger Live platform 10 | * 11 | * @alpha 12 | */ 13 | export type Transport = { 14 | /** 15 | * A function to handle new messages coming from the Ledger Live platform 16 | */ 17 | onMessage: MessageHandler | undefined; 18 | /** 19 | * A function to send new messages to the Ledger Live platform 20 | */ 21 | send(message: string): void; 22 | }; 23 | -------------------------------------------------------------------------------- /packages/core/tests/transports/windowMessageTransport.spec.ts: -------------------------------------------------------------------------------- 1 | describe("windowMessageTransport", () => { 2 | it.todo("Should write transport tests"); 3 | }); 4 | -------------------------------------------------------------------------------- /packages/core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "./lib" 5 | }, 6 | "include": ["src/**/*", "jest.config.ts", "tests/**/*"] 7 | } 8 | -------------------------------------------------------------------------------- /packages/eslint-config-custom/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [ 3 | "eslint:recommended", 4 | "prettier", 5 | "turbo", 6 | "plugin:react-hooks/recommended", 7 | ], 8 | overrides: [ 9 | { 10 | files: ["**/*.{ts,tsx}"], 11 | parser: "@typescript-eslint/parser", 12 | extends: [ 13 | "plugin:@typescript-eslint/recommended-type-checked", 14 | "plugin:@typescript-eslint/stylistic-type-checked", 15 | "prettier", 16 | ], 17 | // parserOptions: { 18 | // project: ["./packages/**/tsconfig.json"], 19 | // // tsconfigRootDir: __dirname, 20 | // }, 21 | rules: { 22 | "import/prefer-default-export": "off", 23 | "no-void": "off", 24 | "@typescript-eslint/consistent-type-definitions": ["error", "type"], 25 | "@typescript-eslint/ban-ts-comment": "warn", 26 | "@typescript-eslint/no-unsafe-member-access": "warn", 27 | "@typescript-eslint/no-shadow": "warn", 28 | "@typescript-eslint/require-await": "warn", 29 | "@typescript-eslint/no-unsafe-assignment": "warn", 30 | "@typescript-eslint/no-unsafe-return": "warn", 31 | "@typescript-eslint/no-unsafe-call": "warn", 32 | "@typescript-eslint/no-unused-vars": [ 33 | "error", 34 | { argsIgnorePattern: "^_" }, 35 | ], 36 | }, 37 | }, 38 | ], 39 | }; 40 | -------------------------------------------------------------------------------- /packages/eslint-config-custom/next.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["next", "turbo", "prettier"], 3 | rules: { 4 | "@next/next/no-html-link-for-pages": "off", 5 | "react/jsx-key": "off", 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /packages/eslint-config-custom/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ledgerhq/eslint-config-custom", 3 | "private": true, 4 | "version": "0.0.0", 5 | "main": "index.js", 6 | "license": "MIT", 7 | "dependencies": { 8 | "@typescript-eslint/eslint-plugin": "^7.0.0", 9 | "@typescript-eslint/parser": "^7.0.0", 10 | "eslint": "^8.56.0", 11 | "eslint-config-next": "^14.1.0", 12 | "eslint-config-prettier": "^9.1.0", 13 | "eslint-config-turbo": "^1.12.4", 14 | "eslint-plugin-prettier": "^5.1.3", 15 | "eslint-plugin-react-hooks": "^4.6.0", 16 | "prettier": "^3.2.5", 17 | "typescript": "^5.3.3" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/jest-shared-config/jest-preset.js: -------------------------------------------------------------------------------- 1 | /** @type {import('jest').Config} */ 2 | const config = { 3 | preset: "ts-jest", 4 | transform: { 5 | "^.+\\.ts$": "ts-jest", 6 | }, 7 | }; 8 | 9 | module.exports = config; 10 | -------------------------------------------------------------------------------- /packages/jest-shared-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ledgerhq/jest-shared-config", 3 | "private": true, 4 | "version": "0.0.0", 5 | "main": "index.js", 6 | "license": "MIT", 7 | "devDependencies": { 8 | "jest": "^29.7.0" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/manifest-validator-cli/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | es2021: true, 4 | node: true, 5 | }, 6 | parserOptions: { 7 | project: true, 8 | tsconfigRootDir: __dirname, 9 | }, 10 | rules: { 11 | "no-underscore-dangle": "off", 12 | "class-methods-use-this": "warn", 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /packages/manifest-validator-cli/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Ledger 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/manifest-validator-cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ledgerhq/wallet-api-manifest-validator-cli", 3 | "version": "0.1.49", 4 | "description": "This package checks if your manifest.json file meets the requirements for Ledger wallet App manifest submission.", 5 | "license": "MIT", 6 | "files": [ 7 | "/bin" 8 | ], 9 | "scripts": { 10 | "build": "rm -rf bin/* && tsc -p prod.tsconfig.json", 11 | "format:check": "prettier --check \"src\"", 12 | "format:fix": "prettier --write \"src\"", 13 | "lint": "eslint --cache --ext .ts \"src\"", 14 | "lint:fix": "eslint --cache --fix --ext .ts \"src\"", 15 | "validate": "node bin/cli.js" 16 | }, 17 | "bin": { 18 | "validate": "bin/cli.js" 19 | }, 20 | "devDependencies": { 21 | "@types/node": "^20.11.19", 22 | "eslint": "^8.56.0", 23 | "prettier": "^3.2.5", 24 | "typescript": "^5.3.3" 25 | }, 26 | "dependencies": { 27 | "@ledgerhq/wallet-api-core": "workspace:*", 28 | "@ledgerhq/wallet-api-manifest-validator": "workspace:*", 29 | "clipanion": "4.0.0-rc.3" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/manifest-validator-cli/prod.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | "module": "commonjs", 7 | "outDir": "./bin" 8 | }, 9 | "include": ["src/**/*"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/manifest-validator-cli/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "resolveJsonModule": true, 5 | "module": "commonjs" 6 | }, 7 | "include": ["src/**/*"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/manifest-validator/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | es2021: true, 4 | node: true, 5 | }, 6 | parserOptions: { 7 | project: true, 8 | tsconfigRootDir: __dirname, 9 | }, 10 | rules: { 11 | "no-underscore-dangle": "off", 12 | "class-methods-use-this": "warn", 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /packages/manifest-validator/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Ledger 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/manifest-validator/jest.config.ts: -------------------------------------------------------------------------------- 1 | import type { JestConfigWithTsJest } from "ts-jest"; 2 | 3 | const config: JestConfigWithTsJest = { 4 | preset: "@ledgerhq/jest-shared-config", 5 | }; 6 | 7 | export default config; 8 | -------------------------------------------------------------------------------- /packages/manifest-validator/prod-esm.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | "module": "ESNext", 7 | "outDir": "./lib-es" 8 | }, 9 | "include": ["src/**/*"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/manifest-validator/prod.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | "module": "commonjs", 7 | "outDir": "./lib" 8 | }, 9 | "include": ["src/**/*"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/manifest-validator/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./validator"; 2 | -------------------------------------------------------------------------------- /packages/manifest-validator/tests/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { env: { jest: true } }; 2 | -------------------------------------------------------------------------------- /packages/manifest-validator/tests/manifests/dapp/dapp-manifest.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "alkemi", 3 | "name": "Alkemi", 4 | "url": "https://dapp-browser.apps.ledger.com", 5 | "params": { 6 | "dappUrl": "https://earn.alkemi.network/dashboard?embed=true", 7 | "nanoApp": "Alkemi", 8 | "dappName": "Alkemi", 9 | "networks": [ 10 | { 11 | "currency": "ethereum", 12 | "chainID": 1, 13 | "nodeURL": "wss://eth-mainnet.ws.alchemyapi.io/v2/xxx" 14 | } 15 | ] 16 | }, 17 | "homepageUrl": "https://earn.alkemi.network", 18 | "supportUrl": "https://earn.alkemi.network", 19 | "domains": ["https"], 20 | "branch": "stable", 21 | "icon": "https://cdn.live.ledger.com/icons/platform/alkemi.png", 22 | "platforms": ["ios"], 23 | "apiVersion": "^1.0.0 || ~0.0.1", 24 | "manifestVersion": "2", 25 | "categories": ["farm"], 26 | "currencies": ["ethereum"], 27 | "content": { 28 | "shortDescription": { 29 | "en": "Earn high yields on your assets with our professional DeFi borrowing and lending platform." 30 | }, 31 | "description": { 32 | "en": "Earn high yields on your assets with our professional DeFi borrowing and lending platform." 33 | } 34 | }, 35 | "permissions": ["test"], 36 | "visibility": "complete" 37 | } 38 | -------------------------------------------------------------------------------- /packages/manifest-validator/tests/manifests/dapp/invalid-dapp-manifest.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "alkemi", 3 | "name": "Alkemi", 4 | "url": "https://dapp-browser.apps.ledger.com", 5 | "type": "dApp", 6 | "params": { 7 | "dappUrl": "https://earn.alkemi.network/dashboard?embed=true", 8 | "nanoApp": "Alkemi", 9 | "dappName": "Alkemi", 10 | "networks": [ 11 | { 12 | "chainID": 1, 13 | "nodeURL": "wss://eth-mainnet.ws.alchemyapi.io/v2/xxx" 14 | } 15 | ] 16 | }, 17 | "homepageUrl": "https://earn.alkemi.network", 18 | "supportUrl": "https://earn.alkemi.network", 19 | "icon": "https://cdn.live.ledger.com/icons/platform/alkemi.png", 20 | "platform": "all", 21 | "apiVersion": "^1.0.0 || ~0.0.1", 22 | "version": 2, 23 | "categories": ["farm"], 24 | "currencies": ["ethereum"], 25 | "content": { 26 | "shortDescription": "Earn high yields on your assets with our professional DeFi borrowing and lending platform.", 27 | "description": "Earn high yields on your assets with our professional DeFi borrowing and lending platform." 28 | }, 29 | "permissions": ["test"] 30 | } 31 | -------------------------------------------------------------------------------- /packages/manifest-validator/tests/manifests/nativeDapp/invalid-nativeDapp-manifest.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "alkemi", 3 | "name": "Alkemi", 4 | "url": "https://dapp-browser.apps.ledger.com", 5 | "type": "webBrowserApp", 6 | "params": { 7 | "dappUrl": "https://earn.alkemi.network/dashboard?embed=true", 8 | "nanoApp": "Alkemi", 9 | "dappName": "Alkemi", 10 | "networks": [ 11 | { 12 | "currency": "ethereum", 13 | "chainID": 1, 14 | "nodeURL": "wss://eth-mainnet.ws.alchemyapi.io/v2/xxx" 15 | } 16 | ] 17 | }, 18 | "homepageUrl": "https://earn.alkemi.network", 19 | "supportUrl": "https://earn.alkemi.network", 20 | "icon": "https://cdn.live.ledger.com/icons/platform/alkemi.png", 21 | "platform": "all", 22 | "apiVersion": "^1.0.0 || ~0.0.1", 23 | "version": 2, 24 | "categories": ["farm"], 25 | "currencies": ["ethereum"], 26 | "content": { 27 | "shortDescription": "Earn high yields on your assets with our professional DeFi borrowing and lending platform.", 28 | "description": "Earn high yields on your assets with our professional DeFi borrowing and lending platform." 29 | }, 30 | "permissions": ["test"] 31 | } 32 | -------------------------------------------------------------------------------- /packages/manifest-validator/tests/manifests/nativeDapp/nativeDapp-manifest.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "alkemi", 3 | "name": "Alkemi", 4 | "url": "https://earn.alkemi.network", 5 | "dapp": { 6 | "nanoApp": "ok", 7 | "provider": "evm", 8 | "networks": [ 9 | { 10 | "currency": "ethereum", 11 | "chainID": 1, 12 | "nodeURL": "https://eth-dapps.api.live.ledger.com" 13 | }, 14 | { 15 | "currency": "bsc", 16 | "chainID": 56, 17 | "nodeURL": "https://bsc-dataseed.binance.org/" 18 | } 19 | ] 20 | }, 21 | "homepageUrl": "https://earn.alkemi.network", 22 | "supportUrl": "https://earn.alkemi.network", 23 | "domains": ["https"], 24 | "branch": "stable", 25 | "icon": "https://cdn.live.ledger.com/icons/platform/alkemi.png", 26 | "platforms": ["android", "ios", "desktop"], 27 | "apiVersion": "^1.0.0 || ~0.0.1", 28 | "manifestVersion": "2", 29 | "categories": ["farm"], 30 | "currencies": ["ethereum"], 31 | "content": { 32 | "shortDescription": { 33 | "en": "Earn high yields on your assets with our professional DeFi borrowing and lending platform." 34 | }, 35 | "description": { 36 | "en": "Earn high yields on your assets with our professional DeFi borrowing and lending platform." 37 | } 38 | }, 39 | "permissions": ["test"], 40 | "visibility": "deep" 41 | } 42 | -------------------------------------------------------------------------------- /packages/manifest-validator/tests/manifests/walletApp/invalid-walletApp-manifest.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "alkemi", 3 | "name": "Alkemi", 4 | "url": "https://dapp-browser.apps.ledger.com", 5 | "type": "walletApp", 6 | "params": { 7 | "test": { "yesy": "d" }, 8 | "oui": ["test", 1] 9 | }, 10 | "homepageUrl": "https://earn.alkemi.network", 11 | "supportUrl": "https://earn.alkemi.network", 12 | "icon": "https://cdn.live.ledger.com/icons/platform/alkemi.png", 13 | "platform": ["all"], 14 | "apiVersion": "^1.0.0 || ~0.0.1", 15 | "version": 2, 16 | "currencies": ["ethereum"], 17 | "content": { 18 | "shortDescription": "Earn high yields on your assets with our professional DeFi borrowing and lending platform.", 19 | "description": "Earn high yields on your assets with our professional DeFi borrowing and lending platform." 20 | }, 21 | "permissions": ["test"] 22 | } 23 | -------------------------------------------------------------------------------- /packages/manifest-validator/tests/manifests/walletApp/walletApp-manifest.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "alkemi", 3 | "name": "Alkemi", 4 | "url": "https://dapp-browser.apps.ledger.com", 5 | "params": { 6 | "dappUrl": "https://earn.alkemi.network", 7 | "nanoApp": "Alkemi", 8 | "dappName": "Alkemi", 9 | "networks": [ 10 | { 11 | "currency": "ethereum", 12 | "chainID": 1, 13 | "nodeURL": "https://mainnet.infura.io/v3/your-infura-key" 14 | } 15 | ] 16 | }, 17 | "homepageUrl": "https://earn.alkemi.network", 18 | "supportUrl": "https://earn.alkemi.network", 19 | "domains": ["https"], 20 | "branch": "stable", 21 | "icon": "https://cdn.live.ledger.com/icons/platform/alkemi.png", 22 | "platforms": ["android"], 23 | "apiVersion": "^1.0.0 || ~0.0.1", 24 | "manifestVersion": "2", 25 | "categories": ["farm"], 26 | "currencies": ["ethereum"], 27 | "content": { 28 | "shortDescription": { 29 | "en": "Earn high yields on your assets with our professional DeFi borrowing and lending platform." 30 | }, 31 | "description": { 32 | "en": "Earn high yields on your assets with our professional DeFi borrowing and lending platform." 33 | } 34 | }, 35 | "permissions": ["test"], 36 | "visibility": "searchable" 37 | } 38 | -------------------------------------------------------------------------------- /packages/manifest-validator/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "resolveJsonModule": true, 5 | "outDir": "./lib" 6 | }, 7 | "include": ["src/**/*", "cli/**/*", "jest.config.ts", "tests/**/*"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/server/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | es2021: true, 4 | node: true, 5 | }, 6 | parserOptions: { 7 | project: true, 8 | tsconfigRootDir: __dirname, 9 | }, 10 | rules: { 11 | "no-underscore-dangle": "off", 12 | "class-methods-use-this": "warn", 13 | "import/prefer-default-export": "off", 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /packages/server/jest.config.ts: -------------------------------------------------------------------------------- 1 | import type { JestConfigWithTsJest } from "ts-jest"; 2 | 3 | const config: JestConfigWithTsJest = { 4 | preset: "@ledgerhq/jest-shared-config", 5 | }; 6 | 7 | export default config; 8 | -------------------------------------------------------------------------------- /packages/server/prod-esm.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | "module": "ESNext", 7 | "outDir": "./lib-es" 8 | }, 9 | "include": ["src/**/*"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/server/prod.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | "module": "commonjs", 7 | "outDir": "./lib" 8 | }, 9 | "include": ["src/**/*"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/server/src/helpers.ts: -------------------------------------------------------------------------------- 1 | import type { Account, Currency } from "@ledgerhq/wallet-api-core"; 2 | import picomatch from "picomatch"; 3 | 4 | export function matchCurrencies( 5 | currencies: Currency[], 6 | patterns: string[], 7 | ): Currency[] { 8 | const matchers = patterns.reduce((filtered, pattern) => { 9 | if (pattern) { 10 | filtered.push(picomatch(pattern)); 11 | } 12 | return filtered; 13 | }, []); 14 | 15 | return currencies.filter((currency) => 16 | matchers.some((matcher) => matcher(currency.id)), 17 | ); 18 | } 19 | 20 | export function filterAccountsForCurrencies( 21 | accounts: Account[], 22 | currencies: Currency[], 23 | ): Account[] { 24 | const currencyIds = new Set(currencies.map((currency) => currency.id)); 25 | 26 | return accounts.filter((account) => currencyIds.has(account.currency)); 27 | } 28 | -------------------------------------------------------------------------------- /packages/server/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./WalletAPIServer"; 2 | export * from "./types"; 3 | -------------------------------------------------------------------------------- /packages/server/src/internalHandlers/currency.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Currency, 3 | CurrencyList, 4 | schemaCurrencyList, 5 | } from "@ledgerhq/wallet-api-core"; 6 | import { firstValueFrom } from "rxjs"; 7 | import type { RPCHandler } from "../types"; 8 | 9 | function filterCurrenciesByCurrencyIds( 10 | currencies: Currency[], 11 | currencyIds: string[], 12 | ) { 13 | const currencyIdsSet = new Set(currencyIds); 14 | 15 | return currencies.filter((currency) => currencyIdsSet.has(currency.id)); 16 | } 17 | 18 | export const list: RPCHandler = async ( 19 | req, 20 | context, 21 | ) => { 22 | const safeParams = schemaCurrencyList.params.parse(req.params); 23 | 24 | const { currencyIds } = safeParams ?? {}; 25 | 26 | const allCurrencies = await firstValueFrom(context.currencies$); 27 | 28 | return { 29 | currencies: currencyIds 30 | ? filterCurrenciesByCurrencyIds(allCurrencies, currencyIds) 31 | : allCurrencies, 32 | }; 33 | }; 34 | -------------------------------------------------------------------------------- /packages/server/src/internalHandlers/custom.ts: -------------------------------------------------------------------------------- 1 | import { CustomRequestHandler } from "@ledgerhq/wallet-api-core"; 2 | import type { RPCHandler } from "../types"; 3 | 4 | export const customWrapper: ( 5 | handler: CustomRequestHandler

, 6 | ) => RPCHandler = (handler) => (req) => { 7 | return handler(req.params); 8 | }; 9 | -------------------------------------------------------------------------------- /packages/server/src/internalHandlers/message.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createAccountNotFound, 3 | createNotImplementedByWallet, 4 | MessageSign, 5 | schemaMessageSign, 6 | ServerError, 7 | } from "@ledgerhq/wallet-api-core"; 8 | import { firstValueFrom } from "rxjs"; 9 | import type { RPCHandler } from "../types"; 10 | 11 | export const sign: RPCHandler = async ( 12 | req, 13 | context, 14 | handlers, 15 | ) => { 16 | const walletHandler = handlers["message.sign"]; 17 | 18 | if (!walletHandler) { 19 | throw new ServerError(createNotImplementedByWallet("message.sign")); 20 | } 21 | 22 | const safeParams = schemaMessageSign.params.parse(req.params); 23 | 24 | const accounts = await firstValueFrom(context.accounts$); 25 | 26 | const { accountId, hexMessage, options, meta } = safeParams; 27 | 28 | const account = accounts.find((acc) => acc.id === accountId); 29 | 30 | if (!account) { 31 | throw new ServerError(createAccountNotFound(accountId)); 32 | } 33 | 34 | const signedMessage = await walletHandler({ 35 | account, 36 | message: Buffer.from(hexMessage, "hex"), 37 | options, 38 | meta, 39 | }); 40 | 41 | return { 42 | hexSignedMessage: signedMessage.toString("hex"), 43 | }; 44 | }; 45 | -------------------------------------------------------------------------------- /packages/server/src/internalHandlers/wallet.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | MethodId, 3 | WalletCapabilities, 4 | WalletUserId, 5 | WalletInfo, 6 | } from "@ledgerhq/wallet-api-core"; 7 | import type { RPCHandler } from "../types"; 8 | 9 | export const capabilities: RPCHandler = ( 10 | _req, 11 | _context, 12 | handlers, 13 | ) => { 14 | const walletHandlerIds = Object.keys(handlers) as MethodId[]; 15 | 16 | // we add the wallet 17 | const methodIds: MethodId[] = [ 18 | ...walletHandlerIds, 19 | "account.list", 20 | "currency.list", 21 | "wallet.capabilities", 22 | "wallet.info", 23 | "wallet.userId", 24 | ]; 25 | 26 | return Promise.resolve({ 27 | methodIds, 28 | }); 29 | }; 30 | 31 | export const userId: RPCHandler = (_req, context) => 32 | Promise.resolve({ 33 | userId: context.config.userId, 34 | }); 35 | 36 | export const info: RPCHandler = (_req, context) => { 37 | const { wallet, tracking } = context.config; 38 | 39 | return Promise.resolve({ 40 | tracking, 41 | wallet, 42 | }); 43 | }; 44 | -------------------------------------------------------------------------------- /packages/server/tests/server.spec.ts: -------------------------------------------------------------------------------- 1 | describe("Server", () => { 2 | it.todo("Should write server tests"); 3 | }); 4 | -------------------------------------------------------------------------------- /packages/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "./lib" 5 | }, 6 | "include": ["src/**/*", "jest.config.ts", "tests/**/*"] 7 | } 8 | -------------------------------------------------------------------------------- /packages/simulator/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | es2021: true, 4 | node: true, 5 | }, 6 | parserOptions: { 7 | project: true, 8 | tsconfigRootDir: __dirname, 9 | }, 10 | rules: { 11 | "no-console": "off", 12 | "no-underscore-dangle": "off", 13 | "class-methods-use-this": "warn", 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /packages/simulator/jest.config.ts: -------------------------------------------------------------------------------- 1 | import path from "path"; 2 | import type { JestConfigWithTsJest } from "ts-jest"; 3 | 4 | const config: JestConfigWithTsJest = { 5 | preset: "@ledgerhq/jest-shared-config", 6 | moduleNameMapper: { 7 | "^@ledgerhq/wallet-api-(.*)$": path.join( 8 | __dirname, 9 | "../../packages/$1/src/index.ts", 10 | ), 11 | }, 12 | }; 13 | 14 | export default config; 15 | -------------------------------------------------------------------------------- /packages/simulator/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ledgerhq/wallet-api-simulator", 3 | "version": "1.2.11", 4 | "license": "MIT", 5 | "main": "lib/index.js", 6 | "module": "lib-es/index.js", 7 | "types": "lib/index.d.ts", 8 | "files": [ 9 | "/lib", 10 | "/lib-es" 11 | ], 12 | "scripts": { 13 | "format:check": "prettier --check \"src\"", 14 | "format:fix": "prettier --write \"src\"", 15 | "lint": "eslint --cache --ext .ts \"src\"", 16 | "lint:fix": "eslint --cache --fix --ext .ts \"src\"", 17 | "dev": "tsc -p prod.tsconfig.json --watch", 18 | "build": "rm -rf lib/* lib-es/* && tsc -p prod.tsconfig.json && tsc -p prod-esm.tsconfig.json", 19 | "test": "jest" 20 | }, 21 | "devDependencies": { 22 | "@ledgerhq/errors": "^6.16.2", 23 | "@ledgerhq/jest-shared-config": "workspace:*", 24 | "@types/jest": "^29.5.12", 25 | "@types/node": "^20.11.19", 26 | "@types/ws": "^8.5.10", 27 | "bignumber.js": "^9.1.2", 28 | "eslint": "^8.56.0", 29 | "jest": "^29.7.0", 30 | "jest-environment-jsdom": "^29.7.0", 31 | "ts-jest": "^29.1.2", 32 | "ts-node": "^10.9.2", 33 | "typescript": "^5.3.3" 34 | }, 35 | "dependencies": { 36 | "@ledgerhq/hw-transport": "^6.30.4", 37 | "@ledgerhq/wallet-api-client": "workspace:*", 38 | "@ledgerhq/wallet-api-core": "workspace:*", 39 | "@ledgerhq/wallet-api-server": "workspace:*", 40 | "rxjs": "^7.8.1", 41 | "ws": "^8.16.0" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/simulator/prod-esm.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | "module": "ESNext", 7 | "outDir": "./lib-es" 8 | }, 9 | "include": ["src/**/*"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/simulator/prod.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | "module": "commonjs", 7 | "outDir": "./lib" 8 | }, 9 | "include": ["src/**/*"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/simulator/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./transport"; 2 | export * from "./profiles"; 3 | -------------------------------------------------------------------------------- /packages/simulator/src/profiles/index.ts: -------------------------------------------------------------------------------- 1 | import { deviceProfile } from "./device"; 2 | import { standardProfile } from "./standard"; 3 | 4 | export const profiles = { 5 | STANDARD: standardProfile, 6 | DEVICE: deviceProfile, 7 | }; 8 | -------------------------------------------------------------------------------- /packages/simulator/src/profiles/standard/accounts.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "account-btc-1", 4 | "name": "Bitcoin 1", 5 | "address": "address", 6 | "currency": "bitcoin", 7 | "balance": "42", 8 | "spendableBalance": "42", 9 | "blockHeight": 1, 10 | "lastSyncDate": "1995-12-17T03:24:00" 11 | }, 12 | { 13 | "id": "account-eth-1", 14 | "name": "Ethereum 1", 15 | "address": "address", 16 | "currency": "ethereum", 17 | "balance": "42", 18 | "spendableBalance": "42", 19 | "blockHeight": 1, 20 | "lastSyncDate": "1995-12-17T03:24:00" 21 | } 22 | ] 23 | -------------------------------------------------------------------------------- /packages/simulator/src/profiles/standard/currencies.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "CryptoCurrency", 4 | "id": "bitcoin", 5 | "ticker": "BTC", 6 | "name": "Bitcoin", 7 | "family": "bitcoin", 8 | "color": "#ffae35", 9 | "decimals": 8 10 | }, 11 | { 12 | "type": "CryptoCurrency", 13 | "id": "ethereum", 14 | "ticker": "ETH", 15 | "name": "Ethereum", 16 | "family": "ethereum", 17 | "color": "#0ebdcd", 18 | "decimals": 18 19 | } 20 | ] 21 | -------------------------------------------------------------------------------- /packages/simulator/src/test-run.ts: -------------------------------------------------------------------------------- 1 | import { WalletAPIClient } from "@ledgerhq/wallet-api-client"; 2 | import { profiles } from "./profiles"; 3 | // import { deserializeTransaction } from "@ledgerhq/wallet-api-core"; 4 | import { getSimulatorTransport } from "./transport"; 5 | 6 | async function main() { 7 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 8 | const transport = getSimulatorTransport(profiles.STANDARD); 9 | const client = new WalletAPIClient(transport); 10 | 11 | const userId = await client.wallet.userId(); 12 | const info = await client.wallet.info(); 13 | 14 | console.log({ 15 | userId, 16 | info, 17 | }); 18 | /* transport.send( 19 | JSON.stringify({ 20 | id: "49f2b5e9-9e77-495c-8add-8542127b4a50", 21 | jsonrpc: "2.0", 22 | method: "transaction.signAndBroadcast", 23 | params: { 24 | rawTransaction: { 25 | family: "ethereum", 26 | amount: "12", 27 | recipient: "0xananas", 28 | }, 29 | }, 30 | }) 31 | ); 32 | */ 33 | } 34 | 35 | main() 36 | .then(() => console.log("done")) 37 | .catch((err) => console.log(err)); 38 | -------------------------------------------------------------------------------- /packages/simulator/src/types.ts: -------------------------------------------------------------------------------- 1 | import type { Account, Currency, Permission } from "@ledgerhq/wallet-api-core"; 2 | import type { ServerConfig, WalletHandlers } from "@ledgerhq/wallet-api-server"; 3 | 4 | export type SimulatorProfile = { 5 | config: ServerConfig; 6 | permissions: Permission; 7 | accounts: Account[]; 8 | currencies: Currency[]; 9 | methods: Partial; 10 | }; 11 | -------------------------------------------------------------------------------- /packages/simulator/src/ws.ts: -------------------------------------------------------------------------------- 1 | import { WebSocketServer } from "ws"; 2 | 3 | const wss = new WebSocketServer({ port: 8080 }); 4 | 5 | wss.on("connection", (ws) => { 6 | ws.on("message", (data) => { 7 | console.log("received: %s", data); 8 | }); 9 | 10 | ws.send("something"); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/simulator/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "resolveJsonModule": true 6 | }, 7 | "include": ["src/**/*", "jest.config.ts", "tests/**/*"] 8 | } 9 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - "packages/*" 3 | - "apps/*" 4 | - "examples/*" 5 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["config:recommended"] 4 | } 5 | -------------------------------------------------------------------------------- /rfc/rfc-template.md: -------------------------------------------------------------------------------- 1 | # RFC {RFC-NUMBER}: {TITLE} 2 | 3 | ## Changelog 4 | 5 | - {date}: {changelog} 6 | 7 | ## Abstract 8 | 9 | > A brief high-level synopsis of the topic of discussion for this RFC, ideally 10 | > just a few sentences. This should help the reader quickly decide whether the 11 | > rest of the discussion is relevant to their interest. 12 | 13 | ## Background 14 | 15 | > Any context or orientation needed for a reader to understand and participate 16 | > in the substance of the Discussion. If necessary, this section may include 17 | > links to other documentation or sources rather than restating existing 18 | > material, but should provide enough detail that the reader can tell what they 19 | > need to read to be up-to-date. 20 | 21 | ### References 22 | 23 | > Links to external materials needed to follow the discussion may be added here. 24 | > 25 | > In addition, if the discussion in a request for comments leads to any design 26 | > decisions, it may be helpful to add links to the Issue/PR here after the 27 | > discussion has settled. 28 | 29 | ## Discussion 30 | 31 | > This section contains the core of the discussion. 32 | > 33 | > There is no fixed format for this section, but ideally changes to this 34 | > section should be updated before merging to reflect any discussion that took 35 | > place on the PR that made those changes. 36 | -------------------------------------------------------------------------------- /spec/README.md: -------------------------------------------------------------------------------- 1 | # Platform API Specifications 2 | 3 | This directory hosts the canonical Markdown specifications of the Platform API. 4 | 5 | It shall be used to describe protocol semantics, namely the client-server RPC methods, types and errors. The specification includes encoding descriptions used in interprocess communication to comply with the protocol. It defines the interface between the application and the Platform API. 6 | 7 | ## Table of Contents 8 | 9 | - [Overview](#overview) 10 | - [Server](./server/README.md) 11 | - [Client](./client/README.md) 12 | - [Types](./core/types.md) 13 | - [Errors](./core/errors.md) 14 | - [Encoding](./core/encoding.md) 15 | - [Manifest](./core/manifest.md) 16 | - [Remote Procedure Calls](./rpc/README.md) 17 | 18 | ## Version 19 | 20 | This specification uses [semantic versioning](https://semver.org/) 21 | 22 | **Version: 0.1.0** 23 | 24 | ### Changelog 25 | 26 | | Version | Description | 27 | | ------- | ------------- | 28 | | 0.1.0 | Initial draft | 29 | 30 | ## Contibuting 31 | 32 | Contributions are welcome. 33 | 34 | Proposals at an early stage can first be drafted as Github issues. To progress, a proposal will often need to be written out and approved as a [Request For Comment (RFC)](../rfc/README.md). 35 | 36 | The standard language for coding is Typescript. 37 | 38 | If you find discrepancies between the spec and the code that 39 | do not have an associated issue or pull request on github, 40 | please create a new issue ! 41 | 42 | ## Overview 43 | -------------------------------------------------------------------------------- /spec/core/README.md: -------------------------------------------------------------------------------- 1 | This section describes the core types and errors of the Platform API implementation. 2 | 3 | - [Errors](./errors.md) 4 | - [Families](./families.md) 5 | - [Manifest](./manifest.md) 6 | - [Types](./types.md) 7 | -------------------------------------------------------------------------------- /spec/core/families.md: -------------------------------------------------------------------------------- 1 | # Crypto families 2 | -------------------------------------------------------------------------------- /spec/server/README.md: -------------------------------------------------------------------------------- 1 | # Server spec 2 | 3 | This file defines the Server spec of the Platform API. This is meant to be implemented by all wallets (we are talking about a wallets like Live, Vault or Connect). 4 | 5 | The Server API allows a Wallet to interact with an Application and allows it's features to be used by implementing a bi-directonnal [JSON-RPC 2.0](https://www.jsonrpc.org/specification) server and the specification of the Platform API defined [here](../rpc/README.md). 6 | 7 | The Server will allow custom UI to be used when handling RPC calls through the JSON-RPC spec of the Platform API. It will listen for a connection to a Client through a transport layer, deserialize and respond to Application requests with serialized responses or errors. 8 | 9 | ## Middlewares 10 | 11 | The Server allows for middlewares to be used. 12 | With middlewares the wallet is able to do permissions or validation across all RPC calls. 13 | 14 | ## Serialization and deserialization 15 | 16 | All [`Transaction`]()s and [`Account`]()s specific to the Wallet should be serialized before being broadcasted to the Application via RPC. 17 | 18 | Similarly, the request received from the Application, formatted as [`RawTransaction`]() and [`RawAccount`]() should be deserialized before being used by the Wallet. 19 | 20 | ## Errors 21 | 22 | The errors returned by the server are defined [here](/spec/core/errors.md). 23 | 24 | ## Methods 25 | -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/recommended/tsconfig.json", 3 | "compilerOptions": { 4 | "target": "ES2022", 5 | "moduleResolution": "Node10", 6 | "sourceMap": true, 7 | "declaration": true, 8 | "declarationMap": true, 9 | "skipLibCheck": false, 10 | "baseUrl": ".", 11 | "paths": { 12 | "@ledgerhq/wallet-api-*": ["packages/*/src/index.ts"] 13 | }, 14 | 15 | "strict": true, 16 | "allowUnusedLabels": false, 17 | "allowUnreachableCode": false, 18 | "exactOptionalPropertyTypes": false, // change that to true when moving to typia 19 | "noFallthroughCasesInSwitch": true, 20 | "noImplicitOverride": true, 21 | "noImplicitReturns": true, 22 | "noPropertyAccessFromIndexSignature": true, 23 | "noUncheckedIndexedAccess": true, 24 | "noUnusedLocals": true, 25 | "noUnusedParameters": true, 26 | 27 | "isolatedModules": true, 28 | 29 | "checkJs": true, 30 | 31 | "esModuleInterop": true, 32 | "forceConsistentCasingInFileNames": true, 33 | 34 | "lib": ["DOM", "DOM.Iterable"] 35 | }, 36 | "exclude": ["node_modules"] 37 | } 38 | --------------------------------------------------------------------------------