├── .circleci └── config.yml ├── .cspell.json ├── .eslintignore ├── .eslintrc.js ├── .flowconfig ├── .gitignore ├── .prettierignore ├── .prettierrc.js ├── CHANGELOG.md ├── LICENSE ├── README.md ├── _typedoc └── custom-theme │ ├── assets │ ├── css │ │ └── main.css │ ├── images │ │ ├── icons.png │ │ ├── icons@2x.png │ │ ├── widgets.png │ │ └── widgets@2x.png │ └── js │ │ └── main.js │ ├── layouts │ └── default.hbs │ ├── partials │ ├── analytics.hbs │ ├── breadcrumb.hbs │ ├── comment.hbs │ ├── footer.hbs │ ├── header.hbs │ ├── hierarchy.hbs │ ├── index.hbs │ ├── member.declaration.hbs │ ├── member.getterSetter.hbs │ ├── member.hbs │ ├── member.reference.hbs │ ├── member.signature.body.hbs │ ├── member.signature.title.hbs │ ├── member.signatures.hbs │ ├── member.sources.hbs │ ├── members.group.hbs │ ├── members.hbs │ ├── navigation.hbs │ ├── parameter.hbs │ ├── toc.hbs │ ├── toc.root.hbs │ ├── type.hbs │ ├── typeAndParent.hbs │ └── typeParameters.hbs │ └── templates │ ├── index.hbs │ └── reflection.hbs ├── example-node ├── index.ts └── tsconfig.json ├── package.json ├── src ├── Ada.ts ├── errors │ ├── deviceStatusError.ts │ ├── deviceUnsupported.ts │ ├── errorBase.ts │ ├── index.ts │ ├── invalidData.ts │ └── invalidDataReason.ts ├── interactions │ ├── common │ │ ├── ins.ts │ │ └── types.ts │ ├── deriveAddress.ts │ ├── deriveNativeScriptHash.ts │ ├── getExtendedPublicKeys.ts │ ├── getSerial.ts │ ├── getVersion.ts │ ├── runTests.ts │ ├── serialization │ │ ├── addressParams.ts │ │ ├── cVoteRegistration.ts │ │ ├── messageData.ts │ │ ├── nativeScript.ts │ │ ├── operationalCertificate.ts │ │ ├── poolRegistrationCertificate.ts │ │ ├── txAuxiliaryData.ts │ │ ├── txCertificate.ts │ │ ├── txInit.ts │ │ ├── txOther.ts │ │ └── txOutput.ts │ ├── showAddress.ts │ ├── signCVote.ts │ ├── signMessage.ts │ ├── signOperationalCertificate.ts │ └── signTx.ts ├── parsing │ ├── address.ts │ ├── cVote.ts │ ├── certificate.ts │ ├── constants.ts │ ├── messageData.ts │ ├── nativeScript.ts │ ├── network.ts │ ├── operationalCertificate.ts │ ├── output.ts │ ├── poolRegistration.ts │ ├── transaction.ts │ └── txAuxiliaryData.ts ├── tsconfig.json ├── types │ ├── internal.ts │ └── public.ts ├── utils.ts └── utils │ ├── address.ts │ ├── assert.ts │ ├── parse.ts │ └── serialize.ts ├── test ├── device-self-test │ └── runTestsDevice.test.ts ├── integration │ ├── __fixtures__ │ │ ├── deriveAddress.ts │ │ ├── deriveNativeScriptHash.ts │ │ ├── getExtendedPublicKey.ts │ │ ├── signCVote.ts │ │ ├── signMessage.ts │ │ ├── signOperationalCertificate.ts │ │ ├── signTx.ts │ │ ├── signTxCVote.ts │ │ ├── signTxPlutus.ts │ │ ├── signTxPoolRegistration.ts │ │ ├── signTxPoolRegistrationRejects.ts │ │ ├── signTxRejects.ts │ │ └── txElements.ts │ ├── deriveAddress.test.ts │ ├── deriveNativeScriptHash.test.ts │ ├── getExtendedPublicKey.test.ts │ ├── getSerial.test.ts │ ├── getVersion.test.ts │ ├── signCVote.test.ts │ ├── signMessage.test.ts │ ├── signOperationalCertificate.test.ts │ ├── signTx.test.ts │ ├── signTxCVote.test.ts │ └── signTxPoolRegistration.test.ts ├── test_utils.ts ├── tsconfig.json └── unit │ └── parse.test.ts ├── tsconfig.base.json ├── tsconfig.json ├── typedoc.json ├── workspace.code-workspace └── yarn.lock /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Javascript Node CircleCI 2.0 configuration file 2 | # 3 | # Check https://circleci.com/docs/2.0/language-javascript/ for more details 4 | # 5 | version: 2.1 6 | jobs: 7 | build_and_test: 8 | docker: 9 | - image: cimg/node:18.12 10 | working_directory: ~/repo 11 | steps: 12 | - checkout 13 | - run: 14 | name: Install system dependencies 15 | command: sudo apt-get update && sudo apt-get install -y libusb-1.0-0-dev libudev-dev 16 | 17 | - restore_cache: 18 | key: v2-dependencies-{{ checksum "yarn.lock" }} 19 | - run: 20 | name: Install dependencies 21 | command: yarn install 22 | - save_cache: 23 | paths: 24 | - node_modules 25 | key: v2-dependencies-{{ checksum "yarn.lock" }} 26 | 27 | - run: 28 | name: Lint 29 | command: yarn lint 30 | - run: 31 | name: Spellcheck 32 | command: yarn spell:check 33 | - run: 34 | name: Audit dependencies 35 | command: yarn audit 36 | - run: 37 | name: Build 38 | command: yarn build 39 | - run: 40 | name: Try building the example 41 | command: yarn tsc -p example-node/tsconfig.json --noEmit 42 | - run: 43 | name: Try generating the docs 44 | command: yarn typedoc 45 | - run: 46 | name: Try generating and checking flow types 47 | # piping output to cat to bypass process.stdout.columns being 0 48 | # which causes flowgen console logging to crash 49 | # see https://github.com/aws/aws-cdk/issues/2253 50 | command: | 51 | yarn build:flowtypes | cat 52 | yarn run flow 53 | 54 | update_docs: 55 | docker: 56 | - image: cimg/node:18.12 57 | working_directory: ~/repo 58 | steps: 59 | - checkout 60 | - run: 61 | name: Install system dependencies 62 | command: sudo apt-get update && sudo apt-get install -y libusb-1.0-0-dev libudev-dev 63 | - restore_cache: 64 | keys: 65 | - v2-dependencies-{{ checksum "yarn.lock" }} 66 | - run: 67 | name: Install dependencies 68 | command: yarn install 69 | - save_cache: 70 | paths: 71 | - node_modules 72 | key: v2-dependencies-{{ checksum "yarn.lock" }} 73 | 74 | - run: 75 | name: Get ledgerjs library version 76 | command: | 77 | LEDGERJS_PACKAGE_VERSION=$(cat package.json \ 78 | | grep version \ 79 | | head -1 \ 80 | | awk -F: '{ print $2 }' \ 81 | | sed 's/[",]//g') 82 | echo $LEDGERJS_PACKAGE_VERSION > ledgerjs_version.tmp 83 | - run: 84 | name: Build docs 85 | command: yarn typedoc --out docs_build/$(cat ledgerjs_version.tmp) 86 | 87 | - run: 88 | name: Generate redirect to current version of docs 89 | command: echo '
' > docs_build/index.html 90 | 91 | - add_ssh_keys: 92 | fingerprints: 93 | - e4:d2:8d:f4:aa:02:4a:ea:ed:72:00:62:1e:f7:9b:bc 94 | - run: 95 | name: Setup git 96 | command: | 97 | git config user.email "ci-build@vacuumlabs.com" 98 | git config user.name "ci-build@vacuumlabs.com" 99 | - run: 100 | name: Deploy docs 101 | command: yarn gh-pages --add --dist docs_build --message "[ci skip] Docs for v$(cat ledgerjs_version.tmp)" 102 | 103 | 104 | workflows: 105 | version: 2 106 | main_workflow: 107 | jobs: 108 | - build_and_test 109 | - update_docs: 110 | requires: 111 | - build_and_test 112 | filters: 113 | branches: 114 | only: 115 | - master 116 | -------------------------------------------------------------------------------- /.cspell.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2", 3 | "language": "en", 4 | "ignorePaths": [ 5 | ".cspell.json", 6 | "build", 7 | "node_modules", 8 | "**/*.tgz", 9 | "**/package.json", 10 | "**/tsconfig.json", 11 | ".vscode/**", 12 | "_typedoc" 13 | ], 14 | "ignoreRegExpList": [ 15 | "0x[A-Z]{7,25}", 16 | "\\S{32,}", 17 | "[A-Za-z0-9+/]+={1,2}", 18 | "deadbe[ea]f", 19 | "'[a-z0-9]{16}'" 20 | ], 21 | "words": [ 22 | "Adalite", 23 | "APDU", 24 | "argparse", 25 | "basex", 26 | "bbbc", 27 | "bech", 28 | "Benc", 29 | "bytestring", 30 | "cardano", 31 | "cbor", 32 | "CHAINCODE", 33 | "chsh", 34 | "cimg", 35 | "concats", 36 | "cryptoprovider", 37 | "cvote", 38 | "cword", 39 | "czvf", 40 | "Deregisters", 41 | "deregistration", 42 | "DEVEL", 43 | "dpkg", 44 | "DREP", 45 | "endians", 46 | "financials", 47 | "hwsfile", 48 | "insertable", 49 | "jcli", 50 | "jormungandr", 51 | "keyhash", 52 | "Kojn", 53 | "ledgerhq", 54 | "ledgerjs", 55 | "libudev", 56 | "libusb", 57 | "multiasset", 58 | "multidelegation", 59 | "nargs", 60 | "opcert", 61 | "PAYMENTADDRESS", 62 | "PAYMENTPATH", 63 | "pkey", 64 | "policyid", 65 | "ppershing", 66 | "PREPROD", 67 | "pubkey", 68 | "pubkeys", 69 | "retcode", 70 | "scripthash", 71 | "skey", 72 | "speculos", 73 | "STAKINGPATH", 74 | "Stax", 75 | "subarray", 76 | "subparser", 77 | "subparsers", 78 | "TLDR", 79 | "unfixable", 80 | "uniquifier", 81 | "uniquify", 82 | "utxo", 83 | "vacuumlabs", 84 | "vkey", 85 | "votecast", 86 | "VOTINGPURPOSE", 87 | "yoroi", 88 | "zxvf" 89 | ] 90 | } 91 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | docs_generated/ 3 | _typedoc/ 4 | node_modules/ 5 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | // copied from https://github.com/vacuumlabs/nufi and adjusted 2 | module.exports = { 3 | extends: [ 4 | 'plugin:@typescript-eslint/recommended', 5 | 'plugin:import/typescript', 6 | 'vacuumlabs', 7 | 'prettier', 8 | ], 9 | env: { 10 | "es6": true, 11 | "node": true, 12 | "mocha": true 13 | }, 14 | rules: { 15 | '@typescript-eslint/no-explicit-any': [ 16 | 'error', 17 | { 18 | ignoreRestArgs: true, 19 | }, 20 | ], 21 | '@typescript-eslint/no-var-requires': 'off', 22 | '@typescript-eslint/explicit-module-boundary-types': 'off', 23 | 24 | // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-use-before-define.md#how-to-use 25 | // note you must disable the base rule as it can report incorrect errors 26 | 'no-use-before-define': 'off', 27 | '@typescript-eslint/no-use-before-define': ['error'], 28 | 'no-unused-vars': 'off', 29 | '@typescript-eslint/no-unused-vars': ['error', {argsIgnorePattern: '^_'}], 30 | // Why detect cycles: https://spin.atomicobject.com/2018/06/25/circular-dependencies-javascript 31 | // TLDR - memory crashes, tangled architecture, unreadable code, undefined imports 32 | 'import/no-cycle': [ 33 | 'error', 34 | ], 35 | 'import/no-extraneous-dependencies': ['error'], 36 | 'no-duplicate-imports': 'off', 37 | 'import/no-duplicates': ['error'], 38 | 'spaced-comment': ['error', 'always', {block: {balanced: true}}], 39 | 'quote-props': ['error', 'consistent'], 40 | '@typescript-eslint/no-redeclare': ['error'], 41 | 42 | // redundant, suggested in https://github.com/typescript-eslint/typescript-eslint/issues/4510 43 | 'consistent-return': 'off', 44 | }, 45 | parser: '@typescript-eslint/parser', 46 | parserOptions: { 47 | ecmaVersion: 2020, 48 | sourceType: 'module', 49 | createDefaultProgram: true, 50 | }, 51 | settings: { 52 | 'import/resolver': { 53 | node: { 54 | extensions: ['.js', '.ts'], 55 | }, 56 | }, 57 | }, 58 | plugins: ['import'], 59 | } 60 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | .*/node_modules/resolve/test/resolver/malformed_package_json/package.json 3 | 4 | [include] 5 | 6 | [untyped] 7 | 8 | [libs] 9 | 10 | [lints] 11 | 12 | [options] 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | .vscode 4 | docs_generated/ 5 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .eslintrc.js 2 | README.md 3 | CHANGELOG.md 4 | docs 5 | docs_generated/ 6 | .vscode 7 | .circleci 8 | dist/ 9 | _typedoc/ 10 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | bracketSpacing: false, 3 | quoteProps: 'consistent', 4 | semi: false, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | } 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |  2 | 3 | ### @cardano-foundation/ledgerjs-hw-app-cardano 4 | 5 | JS Library for communication with Ledger Hardware Wallets. 6 | This library is compatible with the [Cardano ADA Ledger Application](https://github.com/cardano-foundation/ledger-app-cardano). 7 | 8 | Note: this project comes with both [Typescript](https://www.typescriptlang.org/) and [Flow](https://flow.org/) type definitions, but only the Typescript ones are checked for correctness. 9 | 10 | ### Example code 11 | 12 | Example code interacting with `hw-app-cardano` is provided in `example-node` directory. 13 | You can execute it with the `yarn run-example` command. 14 | 15 | ### Tests 16 | 17 | Automated tests are provided. There are two types of tests 18 | 19 | 1. `yarn test-integration`. Tests JS API and integration with the physical Ledger device. 20 | * `yarn test-speculos`. Runs the `test-integration` test against the Speculos emulator. 21 | 22 | 2. `yarn device-self-test`. Runs tests defined in the application code of the Ledger application, requires development build of the application. 23 | * `yarn device-self-test-speculos`. Runs `yarn device-self-test` on Speculos (useful because the full app in debug mode with self-tests does not fit on Nano S). 24 | 25 | Note that for these tests it is advisable to install the developer build of the Cardano app with _headless_ mode enabled unless you want to verify the UI flows, otherwise you will need a significant amount of time to manually confirm all prompts on the device. 26 | 27 | #### Speculos 28 | 29 | To run the Speculos emulator, you first need to install it. The [Speculos documentation](https://speculos.ledger.com/installation/build.html) should take you through the installation process. 30 | After installing you can start the emulator with the correct seed: 31 | `` 32 | speculos /path/to/your/ledger-app-cardano-shelley/bin/app.elf --seed "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" --display headless 33 | `` 34 | *Note: replace `/path/to/your/ledger-app-cardano-shelley/bin/app.elf` with a path to the `app.elf` file of the Cardano ledger app.* 35 | This will start the emulator with a TCP server listening on port 9999 for APDU messages and a web interface running on port 5000 (http://localhost:5000) which can be used to interact with the app. 36 | The `--display headless` option just hides any window UI. 37 | 38 | ### Documentation 39 | 40 | - you can build the docs by running `yarn gen-docs` and then navigate to docs_generated/index.html 41 | - generated docs can also be found at (https://vacuumlabs.github.io/ledgerjs-cardano-shelley) 42 | - [CHANGELOG](CHANGELOG.md) 43 | -------------------------------------------------------------------------------- /_typedoc/custom-theme/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardano-foundation/ledgerjs-hw-app-cardano/ee543694deaa9dd39d049d3efb888515bf058faa/_typedoc/custom-theme/assets/images/icons.png -------------------------------------------------------------------------------- /_typedoc/custom-theme/assets/images/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardano-foundation/ledgerjs-hw-app-cardano/ee543694deaa9dd39d049d3efb888515bf058faa/_typedoc/custom-theme/assets/images/icons@2x.png -------------------------------------------------------------------------------- /_typedoc/custom-theme/assets/images/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardano-foundation/ledgerjs-hw-app-cardano/ee543694deaa9dd39d049d3efb888515bf058faa/_typedoc/custom-theme/assets/images/widgets.png -------------------------------------------------------------------------------- /_typedoc/custom-theme/assets/images/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardano-foundation/ledgerjs-hw-app-cardano/ee543694deaa9dd39d049d3efb888515bf058faa/_typedoc/custom-theme/assets/images/widgets@2x.png -------------------------------------------------------------------------------- /_typedoc/custom-theme/layouts/default.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |Generated using TypeDoc
20 |
14 | {{#each tags}} 15 |- {{tagName}}
16 | - {{#markdown}}{{{text}}}{{/markdown}}
17 | {{/each}}
18 |
19 | {{/if}} 20 |