From deb1121fc5fbe9826ae068429a2b5c871d72a7af Mon Sep 17 00:00:00 2001 From: guibescos <59208140+guibescos@users.noreply.github.com> Date: Tue, 7 Nov 2023 18:33:56 +0100 Subject: [PATCH] Add ledger (#257) --- package-lock.json | 680 +++++++++++++++++++++++++++++++++++ staking/app/deploy/ledger.ts | 163 +++++++++ staking/package.json | 4 +- 3 files changed, 846 insertions(+), 1 deletion(-) create mode 100644 staking/app/deploy/ledger.ts diff --git a/package-lock.json b/package-lock.json index 13b4ce3b..bd5dd995 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3891,6 +3891,117 @@ "events": "^3.3.0" } }, + "node_modules/@ledgerhq/hw-transport-node-hid": { + "version": "6.27.21", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-6.27.21.tgz", + "integrity": "sha512-8G3Owpa2ex+TkGQSMkKoAbMEGZ7a23g0wZUvVzalQphMqbayebMhuXxue8iPp7F9pulm7uyLxgMYptYyw5i4yQ==", + "dev": true, + "dependencies": { + "@ledgerhq/devices": "^8.0.7", + "@ledgerhq/errors": "^6.14.0", + "@ledgerhq/hw-transport": "^6.28.8", + "@ledgerhq/hw-transport-node-hid-noevents": "^6.27.19", + "@ledgerhq/logs": "^6.10.1", + "lodash": "^4.17.21", + "node-hid": "^2.1.2", + "usb": "2.9.0" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid-noevents": { + "version": "6.27.19", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-6.27.19.tgz", + "integrity": "sha512-zOIB1fBiQH9ZYFzoEpNY4n1lE7bGPgRT+k85fKuLM7cxxm5Sy+TgrdxImvBz0IQUS8EvrtZCm+dVWkb2sH/6OA==", + "dev": true, + "dependencies": { + "@ledgerhq/devices": "^8.0.7", + "@ledgerhq/errors": "^6.14.0", + "@ledgerhq/hw-transport": "^6.28.8", + "@ledgerhq/logs": "^6.10.1", + "node-hid": "^2.1.2" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/@ledgerhq/devices": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-8.0.7.tgz", + "integrity": "sha512-BbPyET52lXnVs7CxJWrGYqmtGdbGzj+XnfCqLsDnA7QYr1CZREysxmie+Rr6BKpNDBRVesAovXjtaVaZOn+upw==", + "dev": true, + "dependencies": { + "@ledgerhq/errors": "^6.14.0", + "@ledgerhq/logs": "^6.10.1", + "rxjs": "6", + "semver": "^7.3.5" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/@ledgerhq/hw-transport": { + "version": "6.28.8", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.28.8.tgz", + "integrity": "sha512-XxQVl4htd018u/M66r0iu5nlHi+J6QfdPsORzDF6N39jaz+tMqItb7tUlXM/isggcuS5lc7GJo7NOuJ8rvHZaQ==", + "dev": true, + "dependencies": { + "@ledgerhq/devices": "^8.0.7", + "@ledgerhq/errors": "^6.14.0", + "events": "^3.3.0" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/@ledgerhq/hw-transport-node-hid/node_modules/@ledgerhq/devices": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-8.0.7.tgz", + "integrity": "sha512-BbPyET52lXnVs7CxJWrGYqmtGdbGzj+XnfCqLsDnA7QYr1CZREysxmie+Rr6BKpNDBRVesAovXjtaVaZOn+upw==", + "dev": true, + "dependencies": { + "@ledgerhq/errors": "^6.14.0", + "@ledgerhq/logs": "^6.10.1", + "rxjs": "6", + "semver": "^7.3.5" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid/node_modules/@ledgerhq/hw-transport": { + "version": "6.28.8", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.28.8.tgz", + "integrity": "sha512-XxQVl4htd018u/M66r0iu5nlHi+J6QfdPsORzDF6N39jaz+tMqItb7tUlXM/isggcuS5lc7GJo7NOuJ8rvHZaQ==", + "dev": true, + "dependencies": { + "@ledgerhq/devices": "^8.0.7", + "@ledgerhq/errors": "^6.14.0", + "events": "^3.3.0" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid/node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/@ledgerhq/hw-transport-node-hid/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, "node_modules/@ledgerhq/hw-transport-webhid": { "version": "6.27.1", "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webhid/-/hw-transport-webhid-6.27.1.tgz", @@ -8018,6 +8129,12 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "peer": true }, + "node_modules/@types/w3c-web-usb": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.9.tgz", + "integrity": "sha512-6EIpb9g9k/SGu59mQ6RW3tedmabtE+N3iGRa98+1CCFuhGt565wLEYKXoEVKTuNrCr2SrgfvBMN5db6hggkzKQ==", + "dev": true + }, "node_modules/@types/ws": { "version": "7.4.7", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", @@ -11143,6 +11260,21 @@ "node": ">=0.10" } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", @@ -11291,6 +11423,15 @@ "node": ">=4" } }, + "node_modules/detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -11844,6 +11985,15 @@ "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", "integrity": "sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==" }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/exponential-backoff": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", @@ -12562,6 +12712,12 @@ "ini": "^1.3.2" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -15788,6 +15944,18 @@ "node": ">=6" } }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -16030,6 +16198,12 @@ "node": ">=10" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, "node_modules/mocha": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", @@ -16367,6 +16541,12 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "dev": true + }, "node_modules/near-api-js": { "version": "0.44.2", "resolved": "https://registry.npmjs.org/near-api-js/-/near-api-js-0.44.2.tgz", @@ -16608,6 +16788,18 @@ "node": ">=12.0.0" } }, + "node_modules/node-abi": { + "version": "3.51.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.51.0.tgz", + "integrity": "sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/node-abort-controller": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", @@ -16716,6 +16908,24 @@ "node": ">= 8" } }, + "node_modules/node-hid": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-2.1.2.tgz", + "integrity": "sha512-qhCyQqrPpP93F/6Wc/xUR7L8mAJW0Z6R7HMQV8jCHHksAxNDe/4z4Un/H9CpLOT+5K39OPyt9tIQlavxWES3lg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.5.0", + "node-addon-api": "^3.0.2", + "prebuild-install": "^7.1.1" + }, + "bin": { + "hid-showdevices": "src/show-devices.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -18142,6 +18352,32 @@ "url": "https://opencollective.com/preact" } }, + "node_modules/prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "dev": true, + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/prettier": { "version": "2.8.8", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", @@ -20233,6 +20469,51 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -20887,6 +21168,24 @@ "node": ">= 10" } }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, "node_modules/tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", @@ -21402,6 +21701,18 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, "node_modules/tweetnacl": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", @@ -21656,6 +21967,27 @@ "node": ">=6" } }, + "node_modules/usb": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/usb/-/usb-2.9.0.tgz", + "integrity": "sha512-G0I/fPgfHUzWH8xo2KkDxTTFruUWfppgSFJ+bQxz/kVY2x15EQ/XDB7dqD1G432G4gBG4jYQuF3U7j/orSs5nw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@types/w3c-web-usb": "^1.0.6", + "node-addon-api": "^6.0.0", + "node-gyp-build": "^4.5.0" + }, + "engines": { + "node": ">=10.20.0 <11.x || >=12.17.0 <13.0 || >=14.0.0" + } + }, + "node_modules/usb/node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "dev": true + }, "node_modules/use-sync-external-store": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", @@ -22225,6 +22557,8 @@ "typescript": "^4.3.5" }, "devDependencies": { + "@ledgerhq/hw-transport": "^6.27.2", + "@ledgerhq/hw-transport-node-hid": "^6.27.21", "@metaplex-foundation/js": "^0.17.5", "@metaplex-foundation/mpl-token-metadata": "^2.5.1", "@types/bn.js": "^5.1.0", @@ -22239,6 +22573,29 @@ "wasm-pack": "^0.10.2" } }, + "staking/node_modules/@ledgerhq/devices": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-8.0.7.tgz", + "integrity": "sha512-BbPyET52lXnVs7CxJWrGYqmtGdbGzj+XnfCqLsDnA7QYr1CZREysxmie+Rr6BKpNDBRVesAovXjtaVaZOn+upw==", + "dev": true, + "dependencies": { + "@ledgerhq/errors": "^6.14.0", + "@ledgerhq/logs": "^6.10.1", + "rxjs": "6", + "semver": "^7.3.5" + } + }, + "staking/node_modules/@ledgerhq/hw-transport": { + "version": "6.28.8", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.28.8.tgz", + "integrity": "sha512-XxQVl4htd018u/M66r0iu5nlHi+J6QfdPsORzDF6N39jaz+tMqItb7tUlXM/isggcuS5lc7GJo7NOuJ8rvHZaQ==", + "dev": true, + "dependencies": { + "@ledgerhq/devices": "^8.0.7", + "@ledgerhq/errors": "^6.14.0", + "events": "^3.3.0" + } + }, "staking/node_modules/@project-serum/anchor": { "version": "0.24.2", "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.24.2.tgz", @@ -22299,6 +22656,24 @@ "base-x": "^3.0.2" } }, + "staking/node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "staking/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, "staking/node_modules/typescript": { "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", @@ -24969,6 +25344,115 @@ "events": "^3.3.0" } }, + "@ledgerhq/hw-transport-node-hid": { + "version": "6.27.21", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-6.27.21.tgz", + "integrity": "sha512-8G3Owpa2ex+TkGQSMkKoAbMEGZ7a23g0wZUvVzalQphMqbayebMhuXxue8iPp7F9pulm7uyLxgMYptYyw5i4yQ==", + "dev": true, + "requires": { + "@ledgerhq/devices": "^8.0.7", + "@ledgerhq/errors": "^6.14.0", + "@ledgerhq/hw-transport": "^6.28.8", + "@ledgerhq/hw-transport-node-hid-noevents": "^6.27.19", + "@ledgerhq/logs": "^6.10.1", + "lodash": "^4.17.21", + "node-hid": "^2.1.2", + "usb": "2.9.0" + }, + "dependencies": { + "@ledgerhq/devices": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-8.0.7.tgz", + "integrity": "sha512-BbPyET52lXnVs7CxJWrGYqmtGdbGzj+XnfCqLsDnA7QYr1CZREysxmie+Rr6BKpNDBRVesAovXjtaVaZOn+upw==", + "dev": true, + "requires": { + "@ledgerhq/errors": "^6.14.0", + "@ledgerhq/logs": "^6.10.1", + "rxjs": "6", + "semver": "^7.3.5" + } + }, + "@ledgerhq/hw-transport": { + "version": "6.28.8", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.28.8.tgz", + "integrity": "sha512-XxQVl4htd018u/M66r0iu5nlHi+J6QfdPsORzDF6N39jaz+tMqItb7tUlXM/isggcuS5lc7GJo7NOuJ8rvHZaQ==", + "dev": true, + "requires": { + "@ledgerhq/devices": "^8.0.7", + "@ledgerhq/errors": "^6.14.0", + "events": "^3.3.0" + } + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, + "@ledgerhq/hw-transport-node-hid-noevents": { + "version": "6.27.19", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-6.27.19.tgz", + "integrity": "sha512-zOIB1fBiQH9ZYFzoEpNY4n1lE7bGPgRT+k85fKuLM7cxxm5Sy+TgrdxImvBz0IQUS8EvrtZCm+dVWkb2sH/6OA==", + "dev": true, + "requires": { + "@ledgerhq/devices": "^8.0.7", + "@ledgerhq/errors": "^6.14.0", + "@ledgerhq/hw-transport": "^6.28.8", + "@ledgerhq/logs": "^6.10.1", + "node-hid": "^2.1.2" + }, + "dependencies": { + "@ledgerhq/devices": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-8.0.7.tgz", + "integrity": "sha512-BbPyET52lXnVs7CxJWrGYqmtGdbGzj+XnfCqLsDnA7QYr1CZREysxmie+Rr6BKpNDBRVesAovXjtaVaZOn+upw==", + "dev": true, + "requires": { + "@ledgerhq/errors": "^6.14.0", + "@ledgerhq/logs": "^6.10.1", + "rxjs": "6", + "semver": "^7.3.5" + } + }, + "@ledgerhq/hw-transport": { + "version": "6.28.8", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.28.8.tgz", + "integrity": "sha512-XxQVl4htd018u/M66r0iu5nlHi+J6QfdPsORzDF6N39jaz+tMqItb7tUlXM/isggcuS5lc7GJo7NOuJ8rvHZaQ==", + "dev": true, + "requires": { + "@ledgerhq/devices": "^8.0.7", + "@ledgerhq/errors": "^6.14.0", + "events": "^3.3.0" + } + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, "@ledgerhq/hw-transport-webhid": { "version": "6.27.1", "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webhid/-/hw-transport-webhid-6.27.1.tgz", @@ -28042,6 +28526,12 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "peer": true }, + "@types/w3c-web-usb": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.9.tgz", + "integrity": "sha512-6EIpb9g9k/SGu59mQ6RW3tedmabtE+N3iGRa98+1CCFuhGt565wLEYKXoEVKTuNrCr2SrgfvBMN5db6hggkzKQ==", + "dev": true + }, "@types/ws": { "version": "7.4.7", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", @@ -30589,6 +31079,15 @@ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==" }, + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "requires": { + "mimic-response": "^3.1.0" + } + }, "dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", @@ -30703,6 +31202,12 @@ "integrity": "sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==", "dev": true }, + "detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "dev": true + }, "didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -31155,6 +31660,12 @@ "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", "integrity": "sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==" }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true + }, "exponential-backoff": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", @@ -31699,6 +32210,12 @@ "ini": "^1.3.2" } }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true + }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -34241,6 +34758,12 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true + }, "min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -34435,6 +34958,12 @@ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, "mocha": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", @@ -34669,6 +35198,12 @@ "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", "dev": true }, + "napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "dev": true + }, "near-api-js": { "version": "0.44.2", "resolved": "https://registry.npmjs.org/near-api-js/-/near-api-js-0.44.2.tgz", @@ -34861,6 +35396,15 @@ "integrity": "sha512-WDD0bdg9mbq6F4mRxEYcPWwfA1vxd0mrvKOyxI7Xj/atfRHVeutzuWByG//jfm4uPzp0y4Kj051EORCBSQMycw==", "peer": true }, + "node-abi": { + "version": "3.51.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.51.0.tgz", + "integrity": "sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA==", + "dev": true, + "requires": { + "semver": "^7.3.5" + } + }, "node-abort-controller": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", @@ -34934,6 +35478,17 @@ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.1.tgz", "integrity": "sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==" }, + "node-hid": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-2.1.2.tgz", + "integrity": "sha512-qhCyQqrPpP93F/6Wc/xUR7L8mAJW0Z6R7HMQV8jCHHksAxNDe/4z4Un/H9CpLOT+5K39OPyt9tIQlavxWES3lg==", + "dev": true, + "requires": { + "bindings": "^1.5.0", + "node-addon-api": "^3.0.2", + "prebuild-install": "^7.1.1" + } + }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -35983,6 +36538,26 @@ "resolved": "https://registry.npmjs.org/preact/-/preact-10.4.1.tgz", "integrity": "sha512-WKrRpCSwL2t3tpOOGhf2WfTpcmbpxaWtDbdJdKdjd0aEiTkvOmS4NBkG6kzlaAHI9AkQ3iVqbFWM3Ei7mZ4o1Q==" }, + "prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "dev": true, + "requires": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + } + }, "prettier": { "version": "2.8.8", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", @@ -36143,6 +36718,8 @@ "pyth-staking-api": { "version": "file:staking", "requires": { + "@ledgerhq/hw-transport": "^6.27.2", + "@ledgerhq/hw-transport-node-hid": "^6.27.21", "@metaplex-foundation/js": "^0.17.5", "@metaplex-foundation/mpl-token-metadata": "^2.5.1", "@project-serum/anchor": "0.24.2", @@ -36165,6 +36742,29 @@ "wasm-pack": "^0.10.2" }, "dependencies": { + "@ledgerhq/devices": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-8.0.7.tgz", + "integrity": "sha512-BbPyET52lXnVs7CxJWrGYqmtGdbGzj+XnfCqLsDnA7QYr1CZREysxmie+Rr6BKpNDBRVesAovXjtaVaZOn+upw==", + "dev": true, + "requires": { + "@ledgerhq/errors": "^6.14.0", + "@ledgerhq/logs": "^6.10.1", + "rxjs": "6", + "semver": "^7.3.5" + } + }, + "@ledgerhq/hw-transport": { + "version": "6.28.8", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.28.8.tgz", + "integrity": "sha512-XxQVl4htd018u/M66r0iu5nlHi+J6QfdPsORzDF6N39jaz+tMqItb7tUlXM/isggcuS5lc7GJo7NOuJ8rvHZaQ==", + "dev": true, + "requires": { + "@ledgerhq/devices": "^8.0.7", + "@ledgerhq/errors": "^6.14.0", + "events": "^3.3.0" + } + }, "@project-serum/anchor": { "version": "0.24.2", "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.24.2.tgz", @@ -36222,6 +36822,21 @@ "base-x": "^3.0.2" } }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, "typescript": { "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", @@ -37754,6 +38369,23 @@ "make-fetch-happen": "^11.0.1" } }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true + }, + "simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "dev": true, + "requires": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -38280,6 +38912,26 @@ } } }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + }, + "dependencies": { + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + } + } + }, "tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", @@ -38671,6 +39323,15 @@ "make-fetch-happen": "^11.1.1" } }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, "tweetnacl": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", @@ -38846,6 +39507,25 @@ } } }, + "usb": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/usb/-/usb-2.9.0.tgz", + "integrity": "sha512-G0I/fPgfHUzWH8xo2KkDxTTFruUWfppgSFJ+bQxz/kVY2x15EQ/XDB7dqD1G432G4gBG4jYQuF3U7j/orSs5nw==", + "dev": true, + "requires": { + "@types/w3c-web-usb": "^1.0.6", + "node-addon-api": "^6.0.0", + "node-gyp-build": "^4.5.0" + }, + "dependencies": { + "node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "dev": true + } + } + }, "use-sync-external-store": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", diff --git a/staking/app/deploy/ledger.ts b/staking/app/deploy/ledger.ts new file mode 100644 index 00000000..237861e5 --- /dev/null +++ b/staking/app/deploy/ledger.ts @@ -0,0 +1,163 @@ +import { Wallet } from "@project-serum/anchor/dist/cjs/provider"; +import Transport, { + StatusCodes, + TransportStatusError, +} from "@ledgerhq/hw-transport"; +import TransportNodeHid from "@ledgerhq/hw-transport-node-hid"; +import { PublicKey, Transaction } from "@solana/web3.js"; + +export class LedgerNodeWallet implements Wallet { + private _derivationPath: Buffer; + private _transport: Transport; + publicKey: PublicKey; + + constructor( + derivationPath: Buffer, + transport: Transport, + publicKey: PublicKey + ) { + this._derivationPath = derivationPath; + this._transport = transport; + this.publicKey = publicKey; + } + + static async createWallet( + derivationAccount?: number, + derivationChange?: number + ): Promise { + const transport = await TransportNodeHid.create(); + const derivationPath = getDerivationPath( + derivationAccount, + derivationChange + ); + const publicKey = await getPublicKey(transport, derivationPath); + console.log(`Loaded ledger: ${publicKey.toBase58()}}`); + return new LedgerNodeWallet(derivationPath, transport, publicKey); + } + + async signTransaction(transaction: Transaction): Promise { + console.log("Please approve the transaction on your ledger device..."); + const transport = this._transport; + const publicKey = this.publicKey; + + const signature = await signTransaction( + transport, + transaction, + this._derivationPath + ); + transaction.addSignature(publicKey, signature); + return transaction; + } + + async signAllTransactions(txs: Transaction[]): Promise { + return await Promise.all(txs.map((tx) => this.signTransaction(tx))); + } +} + +/** @internal */ +function getDerivationPath(account?: number, change?: number): Buffer { + const length = account !== undefined ? (change === undefined ? 3 : 4) : 2; + const derivationPath = Buffer.alloc(1 + length * 4); + + let offset = derivationPath.writeUInt8(length, 0); + offset = derivationPath.writeUInt32BE(harden(44), offset); // Using BIP44 + offset = derivationPath.writeUInt32BE(harden(501), offset); // Solana's BIP44 path + + if (account !== undefined) { + offset = derivationPath.writeUInt32BE(harden(account), offset); + if (change !== undefined) { + derivationPath.writeUInt32BE(harden(change), offset); + } + } + + return derivationPath; +} + +const BIP32_HARDENED_BIT = (1 << 31) >>> 0; + +/** @internal */ +function harden(n: number): number { + return (n | BIP32_HARDENED_BIT) >>> 0; +} + +const INS_GET_PUBKEY = 0x05; +const INS_SIGN_MESSAGE = 0x06; + +const P1_NON_CONFIRM = 0x00; +const P1_CONFIRM = 0x01; + +const P2_EXTEND = 0x01; +const P2_MORE = 0x02; + +const MAX_PAYLOAD = 255; + +const LEDGER_CLA = 0xe0; + +/** @internal */ +export async function getPublicKey( + transport: Transport, + derivationPath: Buffer +): Promise { + const bytes = await send( + transport, + INS_GET_PUBKEY, + P1_NON_CONFIRM, + derivationPath + ); + return new PublicKey(bytes); +} + +/** @internal */ +export async function signTransaction( + transport: Transport, + transaction: Transaction, + derivationPath: Buffer +): Promise { + const paths = Buffer.alloc(1); + paths.writeUInt8(1, 0); + + const message = transaction.serializeMessage(); + const data = Buffer.concat([paths, derivationPath, message]); + + return await send(transport, INS_SIGN_MESSAGE, P1_CONFIRM, data); +} + +/** @internal */ +async function send( + transport: Transport, + instruction: number, + p1: number, + data: Buffer +): Promise { + let p2 = 0; + let offset = 0; + + if (data.length > MAX_PAYLOAD) { + while (data.length - offset > MAX_PAYLOAD) { + const buffer = data.subarray(offset, offset + MAX_PAYLOAD); + const response = await transport.send( + LEDGER_CLA, + instruction, + p1, + p2 | P2_MORE, + buffer + ); + if (response.length !== 2) + throw TransportStatusError(StatusCodes.INCORRECT_DATA); + + p2 |= P2_EXTEND; + offset += MAX_PAYLOAD; + } + } + + const buffer = data.subarray(offset); + const response = await transport.send( + LEDGER_CLA, + instruction, + p1, + p2, + buffer + ); + + return response.subarray(0, response.length - 2); +} diff --git a/staking/package.json b/staking/package.json index a18d30b6..54e1115a 100644 --- a/staking/package.json +++ b/staking/package.json @@ -27,7 +27,9 @@ "prettier": "^2.6.2", "shelljs": "^0.8.5", "ts-mocha": "^9.0.2", - "wasm-pack": "^0.10.2" + "wasm-pack": "^0.10.2", + "@ledgerhq/hw-transport-node-hid": "^6.27.21", + "@ledgerhq/hw-transport": "^6.27.2" }, "scripts": { "test": "npm run build_wasm && anchor build -- --features mock-clock && npm run dump_governance && ts-mocha --parallel -p ./tsconfig.json -t 1000000 tests/*.ts",