diff --git a/dfx.json b/dfx.json index 7ab6126..6fd66b0 100644 --- a/dfx.json +++ b/dfx.json @@ -1,5 +1,5 @@ { - "dfx": "0.24.0", + "dfx": "0.24.1", "networks": { "local": { "bind": "127.0.0.1:8080", diff --git a/package-lock.json b/package-lock.json index 68cc1c8..bcfa847 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,15 +9,15 @@ "version": "0.6.0", "license": "ISC", "dependencies": { - "@dfinity/agent": "^2.1.2", - "@dfinity/ledger-icrc": "^2.6.0", - "@dfinity/nns": "^7.0.0", + "@dfinity/agent": "^2.1.3", + "@dfinity/ledger-icrc": "^2.6.2", + "@dfinity/nns": "^7.0.2", "@dfinity/principal": "^2.1.2", - "@dfinity/sns": "^3.2.1", - "@dfinity/utils": "^2.5.0", + "@dfinity/sns": "^3.2.3", + "@dfinity/utils": "^2.6.0", "@ledgerhq/hw-transport-node-hid-noevents": "^6.3.0", "@ledgerhq/hw-transport-webhid": "^6.27.1", - "@zondax/ledger-icp": "^0.6.0", + "@zondax/ledger-icp": "^3.2.4", "chalk": "^4.1.2", "commander": "^9.0.0", "node-fetch": "^2.6.1", @@ -53,9 +53,9 @@ } }, "node_modules/@dfinity/agent": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-2.1.2.tgz", - "integrity": "sha512-UAXf6uXovhBlSp245RWlA21zcCavy+vVUvKVQUpesk1gLJpJlvsCE6hYOwTeFZAP+bjmPi0Tl7cx8DT2KM4eDQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-2.1.3.tgz", + "integrity": "sha512-4XmqhFR3GQSUrmx7lMFx7DyHEhFkM6nz4O9FeYJ/WpkmPe8tulKaAfgWbWdTSCjbd8meCgKVHo+QYj+JHXagcw==", "license": "Apache-2.0", "dependencies": { "@noble/curves": "^1.4.0", @@ -66,18 +66,18 @@ "simple-cbor": "^0.4.1" }, "peerDependencies": { - "@dfinity/candid": "^2.1.2", - "@dfinity/principal": "^2.1.2" + "@dfinity/candid": "^2.1.3", + "@dfinity/principal": "^2.1.3" } }, "node_modules/@dfinity/candid": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@dfinity/candid/-/candid-2.1.2.tgz", - "integrity": "sha512-do69J9iahW2tlmbPdbmc8MDhi5cfIQyTcAlYqaSOOAyg+Kp8beCnW7mletXVfx30dyVlpkyCrYOXhbpQuSCKtw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@dfinity/candid/-/candid-2.1.3.tgz", + "integrity": "sha512-Asn7AfydLhhk7E5z9oW+5UL6ne11gxFlYTxHuhrIc7FdqYlM5Flcq1Wfg9EzRa6Btdol3w58Bcph7Brwh1bcIQ==", "license": "Apache-2.0", "peer": true, "peerDependencies": { - "@dfinity/principal": "^2.1.2" + "@dfinity/principal": "^2.1.3" } }, "node_modules/@dfinity/cketh": { @@ -94,81 +94,81 @@ } }, "node_modules/@dfinity/ledger-icp": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@dfinity/ledger-icp/-/ledger-icp-2.6.0.tgz", - "integrity": "sha512-EXYYtZe+hCyjkIczG6ONlThElrnX0IOxOr/1ahCkvMJ9mnMpS+2zfkzOe+1MBawhLidDAtOwXaCVHMOIbxJ6TQ==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@dfinity/ledger-icp/-/ledger-icp-2.6.2.tgz", + "integrity": "sha512-Ypz/WuwK830bvGAdnZBKcsmyOVz8E44qUnb/6tDFJWTX9MzEMqOdPby+UiQzmtWoehPahrt+W1fsEuVtJvhwHA==", "license": "Apache-2.0", "peer": true, "peerDependencies": { - "@dfinity/agent": "^2.1.2", - "@dfinity/candid": "^2.1.2", - "@dfinity/principal": "^2.1.2", - "@dfinity/utils": "^2.5.1" + "@dfinity/agent": "^2.0.0", + "@dfinity/candid": "^2.0.0", + "@dfinity/principal": "^2.0.0", + "@dfinity/utils": "^2.6.0" } }, "node_modules/@dfinity/ledger-icrc": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@dfinity/ledger-icrc/-/ledger-icrc-2.6.0.tgz", - "integrity": "sha512-gFnD50gzWq+N6P+A9yBiSXc0oaMdmh6W84x5GZOG5i58/p0xeGX4JPwUOrxFCKk0DRdWeH1muO4nknmWFhAZxA==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@dfinity/ledger-icrc/-/ledger-icrc-2.6.2.tgz", + "integrity": "sha512-EsX0LTmA9iAAQH0/CydqZ+P8mkU31A4OFB6oWQ2fjPwUxw1o0gggc0ZgWsj1YeerSer5Aa/PoRWaK7vwzukNSQ==", "license": "Apache-2.0", "peerDependencies": { - "@dfinity/agent": "^2.1.2", - "@dfinity/candid": "^2.1.2", - "@dfinity/principal": "^2.1.2", - "@dfinity/utils": "^2.5.1" + "@dfinity/agent": "^2.0.0", + "@dfinity/candid": "^2.0.0", + "@dfinity/principal": "^2.0.0", + "@dfinity/utils": "^2.6.0" } }, "node_modules/@dfinity/nns": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@dfinity/nns/-/nns-7.0.0.tgz", - "integrity": "sha512-kfLarj0/eZyXb7bvhmAqBAI/vfreCxuOVlyLYejlpkETqgAuLffyMC5SvmiBJmnwU9xgNYylhOKANgNY9nNS1g==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@dfinity/nns/-/nns-7.0.2.tgz", + "integrity": "sha512-YeCYBhNb1f5CXZeQwl3Qct3wccEMkm1M9ZhrjJQ9ALJvBHylFOH1Lb6jK64Pgh9DEsBZV+MnBmCeKeJBuE/zQg==", "license": "Apache-2.0", "dependencies": { "@noble/hashes": "^1.3.2", "randombytes": "^2.1.0" }, "peerDependencies": { - "@dfinity/agent": "^2.1.2", - "@dfinity/candid": "^2.1.2", - "@dfinity/ledger-icp": "^2.6.0", - "@dfinity/principal": "^2.1.2", - "@dfinity/utils": "^2.5.1" + "@dfinity/agent": "^2.0.0", + "@dfinity/candid": "^2.0.0", + "@dfinity/ledger-icp": "^2.6.2", + "@dfinity/principal": "^2.0.0", + "@dfinity/utils": "^2.6.0" } }, "node_modules/@dfinity/principal": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-2.1.2.tgz", - "integrity": "sha512-L3Y0nDjquqNFseM2Gx5fI4GOUKjjezFr9/6ZjSwAFeDeb4Ubqld4ZKL3FEzv4QKNbfZgCx19b7UXi+OdmLhi4w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-2.1.3.tgz", + "integrity": "sha512-HtiAfZcs+ToPYFepVJdFlorIfPA56KzC6J97ZuH2lGNMTAfJA+NEBzLe476B4wVCAwZ0TiGJ27J4ks9O79DFEg==", "license": "Apache-2.0", "dependencies": { "@noble/hashes": "^1.3.1" } }, "node_modules/@dfinity/sns": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@dfinity/sns/-/sns-3.2.1.tgz", - "integrity": "sha512-Ha4G8v3LbC1lTIRZmoRHqBqd6E7d3KDhq1XAl1oq3UjeEtH5BSVA+WkAJlGhBuKnbQ7CgOSTuY8uLR3Y+7pLuQ==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@dfinity/sns/-/sns-3.2.3.tgz", + "integrity": "sha512-CQiMmy0IvYiFxPokC7Sh1vnd0LKjLXl1bBRLlFqzQ772JZV+3RsGcjf7dGCGXveRVtvelIqKe7L1onrhTPHkxQ==", "license": "Apache-2.0", "dependencies": { "@noble/hashes": "^1.3.2" }, "peerDependencies": { - "@dfinity/agent": "^2.1.2", - "@dfinity/candid": "^2.1.2", - "@dfinity/ledger-icrc": "^2.6.0", - "@dfinity/principal": "^2.1.2", - "@dfinity/utils": "^2.5.1" + "@dfinity/agent": "^2.0.0", + "@dfinity/candid": "^2.0.0", + "@dfinity/ledger-icrc": "^2.6.2", + "@dfinity/principal": "^2.0.0", + "@dfinity/utils": "^2.6.0" } }, "node_modules/@dfinity/utils": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@dfinity/utils/-/utils-2.5.1.tgz", - "integrity": "sha512-ypu63xSX/7f79rVVe/T/2eiEwwi2+XvPNEuHz+isj8zf4jvEoG8DDDBZF9hedDgYC5uxuBDm1UJqHGYUcaCmRg==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@dfinity/utils/-/utils-2.6.0.tgz", + "integrity": "sha512-HgWi8sUJ8rmNosSTtPunET/t79hdRTSZ/B3+WVBzSkeamlMJcPgPt3cglZzRfLoNYXp0oC8tj38FPCPDtAgTsg==", "license": "Apache-2.0", "peerDependencies": { - "@dfinity/agent": "^2.1.2", - "@dfinity/candid": "^2.1.2", - "@dfinity/principal": "^2.1.2" + "@dfinity/agent": "^2.0.0", + "@dfinity/candid": "^2.0.0", + "@dfinity/principal": "^2.0.0" } }, "node_modules/@esbuild-plugins/node-resolve": { @@ -575,17 +575,19 @@ } }, "node_modules/@ledgerhq/errors": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.10.0.tgz", - "integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg==" + "version": "6.19.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.19.1.tgz", + "integrity": "sha512-75yK7Nnit/Gp7gdrJAz0ipp31CCgncRp+evWt6QawQEtQKYEDfGo10QywgrrBBixeRxwnMy1DP6g2oCWRf1bjw==", + "license": "Apache-2.0" }, "node_modules/@ledgerhq/hw-transport": { - "version": "6.27.1", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.27.1.tgz", - "integrity": "sha512-hnE4/Fq1YzQI4PA1W0H8tCkI99R3UWDb3pJeZd6/Xs4Qw/q1uiQO+vNLC6KIPPhK0IajUfuI/P2jk0qWcMsuAQ==", + "version": "6.28.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.28.1.tgz", + "integrity": "sha512-RaZe+abn0zBIz82cE9tp7Y7aZkHWWbEaE2yJpfxT8AhFz3fx+BU0kLYzuRN9fmA7vKueNJ1MTVUCY+Ex9/CHSQ==", + "license": "Apache-2.0", "dependencies": { - "@ledgerhq/devices": "^6.27.1", - "@ledgerhq/errors": "^6.10.0", + "@ledgerhq/devices": "^8.0.0", + "@ledgerhq/errors": "^6.12.3", "events": "^3.3.0" } }, @@ -612,10 +614,38 @@ "@ledgerhq/logs": "^6.10.0" } }, + "node_modules/@ledgerhq/hw-transport/node_modules/@ledgerhq/devices": { + "version": "8.4.4", + "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-8.4.4.tgz", + "integrity": "sha512-sz/ryhe/R687RHtevIE9RlKaV8kkKykUV4k29e7GAVwzHX1gqG+O75cu1NCJUHLbp3eABV5FdvZejqRUlLis9A==", + "license": "Apache-2.0", + "dependencies": { + "@ledgerhq/errors": "^6.19.1", + "@ledgerhq/logs": "^6.12.0", + "rxjs": "^7.8.1", + "semver": "^7.3.5" + } + }, + "node_modules/@ledgerhq/hw-transport/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@ledgerhq/hw-transport/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, "node_modules/@ledgerhq/logs": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/logs/-/logs-6.10.0.tgz", - "integrity": "sha512-lLseUPEhSFUXYTKj6q7s2O3s2vW2ebgA11vMAlKodXGf5AFw4zUoEbTz9CoFOC9jS6xY4Qr8BmRnxP/odT4Uuw==" + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/logs/-/logs-6.12.0.tgz", + "integrity": "sha512-ExDoj1QV5eC6TEbMdLUMMk9cfvNKhhv5gXol4SmULRVCx/3iyCPhJ74nsb3S0Vb+/f+XujBEj3vQn5+cwS0fNA==", + "license": "Apache-2.0" }, "node_modules/@noble/curves": { "version": "1.5.0", @@ -929,11 +959,21 @@ "dev": true }, "node_modules/@zondax/ledger-icp": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@zondax/ledger-icp/-/ledger-icp-0.6.0.tgz", - "integrity": "sha512-dmv95M81SQavQHWXHCN8r5Zycfd3iq9b3cudZrswplryaqFbhr1ZsJr3pHvGaWRVxq25rtr7Jg4ExZvAg8Pt2Q==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@zondax/ledger-icp/-/ledger-icp-3.2.4.tgz", + "integrity": "sha512-BwZ5uW4kn8UmfIefO6NAzsQ+JOx4gZoCV4lNioRVVftlZg94yzM9Jqk0vAdr8LlelBkhJ0bVnBgBGDFP/lq/7Q==", + "license": "Apache-2.0", "dependencies": { - "@ledgerhq/hw-transport": "^6.3.0" + "@zondax/ledger-js": "^0.2.2" + } + }, + "node_modules/@zondax/ledger-js": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@zondax/ledger-js/-/ledger-js-0.2.2.tgz", + "integrity": "sha512-7wOUlRF2+kRaRU2KSzKb7XjPfScwEg3Cjg6NH/p+ikQLJ9eMkGC45NhSxYn8lixIIk+TgZ4yzTNOzFvF836gQw==", + "license": "Apache-2.0", + "dependencies": { + "@ledgerhq/hw-transport": "6.28.1" } }, "node_modules/acorn": { @@ -2105,9 +2145,9 @@ } }, "@dfinity/agent": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-2.1.2.tgz", - "integrity": "sha512-UAXf6uXovhBlSp245RWlA21zcCavy+vVUvKVQUpesk1gLJpJlvsCE6hYOwTeFZAP+bjmPi0Tl7cx8DT2KM4eDQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-2.1.3.tgz", + "integrity": "sha512-4XmqhFR3GQSUrmx7lMFx7DyHEhFkM6nz4O9FeYJ/WpkmPe8tulKaAfgWbWdTSCjbd8meCgKVHo+QYj+JHXagcw==", "requires": { "@noble/curves": "^1.4.0", "@noble/hashes": "^1.3.1", @@ -2118,9 +2158,9 @@ } }, "@dfinity/candid": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@dfinity/candid/-/candid-2.1.2.tgz", - "integrity": "sha512-do69J9iahW2tlmbPdbmc8MDhi5cfIQyTcAlYqaSOOAyg+Kp8beCnW7mletXVfx30dyVlpkyCrYOXhbpQuSCKtw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@dfinity/candid/-/candid-2.1.3.tgz", + "integrity": "sha512-Asn7AfydLhhk7E5z9oW+5UL6ne11gxFlYTxHuhrIc7FdqYlM5Flcq1Wfg9EzRa6Btdol3w58Bcph7Brwh1bcIQ==", "peer": true, "requires": {} }, @@ -2132,47 +2172,47 @@ "requires": {} }, "@dfinity/ledger-icp": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@dfinity/ledger-icp/-/ledger-icp-2.6.0.tgz", - "integrity": "sha512-EXYYtZe+hCyjkIczG6ONlThElrnX0IOxOr/1ahCkvMJ9mnMpS+2zfkzOe+1MBawhLidDAtOwXaCVHMOIbxJ6TQ==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@dfinity/ledger-icp/-/ledger-icp-2.6.2.tgz", + "integrity": "sha512-Ypz/WuwK830bvGAdnZBKcsmyOVz8E44qUnb/6tDFJWTX9MzEMqOdPby+UiQzmtWoehPahrt+W1fsEuVtJvhwHA==", "peer": true, "requires": {} }, "@dfinity/ledger-icrc": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@dfinity/ledger-icrc/-/ledger-icrc-2.6.0.tgz", - "integrity": "sha512-gFnD50gzWq+N6P+A9yBiSXc0oaMdmh6W84x5GZOG5i58/p0xeGX4JPwUOrxFCKk0DRdWeH1muO4nknmWFhAZxA==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@dfinity/ledger-icrc/-/ledger-icrc-2.6.2.tgz", + "integrity": "sha512-EsX0LTmA9iAAQH0/CydqZ+P8mkU31A4OFB6oWQ2fjPwUxw1o0gggc0ZgWsj1YeerSer5Aa/PoRWaK7vwzukNSQ==", "requires": {} }, "@dfinity/nns": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@dfinity/nns/-/nns-7.0.0.tgz", - "integrity": "sha512-kfLarj0/eZyXb7bvhmAqBAI/vfreCxuOVlyLYejlpkETqgAuLffyMC5SvmiBJmnwU9xgNYylhOKANgNY9nNS1g==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@dfinity/nns/-/nns-7.0.2.tgz", + "integrity": "sha512-YeCYBhNb1f5CXZeQwl3Qct3wccEMkm1M9ZhrjJQ9ALJvBHylFOH1Lb6jK64Pgh9DEsBZV+MnBmCeKeJBuE/zQg==", "requires": { "@noble/hashes": "^1.3.2", "randombytes": "^2.1.0" } }, "@dfinity/principal": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-2.1.2.tgz", - "integrity": "sha512-L3Y0nDjquqNFseM2Gx5fI4GOUKjjezFr9/6ZjSwAFeDeb4Ubqld4ZKL3FEzv4QKNbfZgCx19b7UXi+OdmLhi4w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-2.1.3.tgz", + "integrity": "sha512-HtiAfZcs+ToPYFepVJdFlorIfPA56KzC6J97ZuH2lGNMTAfJA+NEBzLe476B4wVCAwZ0TiGJ27J4ks9O79DFEg==", "requires": { "@noble/hashes": "^1.3.1" } }, "@dfinity/sns": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@dfinity/sns/-/sns-3.2.1.tgz", - "integrity": "sha512-Ha4G8v3LbC1lTIRZmoRHqBqd6E7d3KDhq1XAl1oq3UjeEtH5BSVA+WkAJlGhBuKnbQ7CgOSTuY8uLR3Y+7pLuQ==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@dfinity/sns/-/sns-3.2.3.tgz", + "integrity": "sha512-CQiMmy0IvYiFxPokC7Sh1vnd0LKjLXl1bBRLlFqzQ772JZV+3RsGcjf7dGCGXveRVtvelIqKe7L1onrhTPHkxQ==", "requires": { "@noble/hashes": "^1.3.2" } }, "@dfinity/utils": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@dfinity/utils/-/utils-2.5.1.tgz", - "integrity": "sha512-ypu63xSX/7f79rVVe/T/2eiEwwi2+XvPNEuHz+isj8zf4jvEoG8DDDBZF9hedDgYC5uxuBDm1UJqHGYUcaCmRg==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@dfinity/utils/-/utils-2.6.0.tgz", + "integrity": "sha512-HgWi8sUJ8rmNosSTtPunET/t79hdRTSZ/B3+WVBzSkeamlMJcPgPt3cglZzRfLoNYXp0oC8tj38FPCPDtAgTsg==", "requires": {} }, "@esbuild-plugins/node-resolve": { @@ -2375,18 +2415,44 @@ } }, "@ledgerhq/errors": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.10.0.tgz", - "integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg==" + "version": "6.19.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-6.19.1.tgz", + "integrity": "sha512-75yK7Nnit/Gp7gdrJAz0ipp31CCgncRp+evWt6QawQEtQKYEDfGo10QywgrrBBixeRxwnMy1DP6g2oCWRf1bjw==" }, "@ledgerhq/hw-transport": { - "version": "6.27.1", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.27.1.tgz", - "integrity": "sha512-hnE4/Fq1YzQI4PA1W0H8tCkI99R3UWDb3pJeZd6/Xs4Qw/q1uiQO+vNLC6KIPPhK0IajUfuI/P2jk0qWcMsuAQ==", + "version": "6.28.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.28.1.tgz", + "integrity": "sha512-RaZe+abn0zBIz82cE9tp7Y7aZkHWWbEaE2yJpfxT8AhFz3fx+BU0kLYzuRN9fmA7vKueNJ1MTVUCY+Ex9/CHSQ==", "requires": { - "@ledgerhq/devices": "^6.27.1", - "@ledgerhq/errors": "^6.10.0", + "@ledgerhq/devices": "^8.0.0", + "@ledgerhq/errors": "^6.12.3", "events": "^3.3.0" + }, + "dependencies": { + "@ledgerhq/devices": { + "version": "8.4.4", + "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-8.4.4.tgz", + "integrity": "sha512-sz/ryhe/R687RHtevIE9RlKaV8kkKykUV4k29e7GAVwzHX1gqG+O75cu1NCJUHLbp3eABV5FdvZejqRUlLis9A==", + "requires": { + "@ledgerhq/errors": "^6.19.1", + "@ledgerhq/logs": "^6.12.0", + "rxjs": "^7.8.1", + "semver": "^7.5.3" + } + }, + "rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "requires": { + "tslib": "^2.1.0" + } + }, + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } } }, "@ledgerhq/hw-transport-node-hid-noevents": { @@ -2413,9 +2479,9 @@ } }, "@ledgerhq/logs": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/logs/-/logs-6.10.0.tgz", - "integrity": "sha512-lLseUPEhSFUXYTKj6q7s2O3s2vW2ebgA11vMAlKodXGf5AFw4zUoEbTz9CoFOC9jS6xY4Qr8BmRnxP/odT4Uuw==" + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/logs/-/logs-6.12.0.tgz", + "integrity": "sha512-ExDoj1QV5eC6TEbMdLUMMk9cfvNKhhv5gXol4SmULRVCx/3iyCPhJ74nsb3S0Vb+/f+XujBEj3vQn5+cwS0fNA==" }, "@noble/curves": { "version": "1.5.0", @@ -2612,11 +2678,19 @@ "dev": true }, "@zondax/ledger-icp": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@zondax/ledger-icp/-/ledger-icp-0.6.0.tgz", - "integrity": "sha512-dmv95M81SQavQHWXHCN8r5Zycfd3iq9b3cudZrswplryaqFbhr1ZsJr3pHvGaWRVxq25rtr7Jg4ExZvAg8Pt2Q==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@zondax/ledger-icp/-/ledger-icp-3.2.4.tgz", + "integrity": "sha512-BwZ5uW4kn8UmfIefO6NAzsQ+JOx4gZoCV4lNioRVVftlZg94yzM9Jqk0vAdr8LlelBkhJ0bVnBgBGDFP/lq/7Q==", + "requires": { + "@zondax/ledger-js": "^0.2.2" + } + }, + "@zondax/ledger-js": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@zondax/ledger-js/-/ledger-js-0.2.2.tgz", + "integrity": "sha512-7wOUlRF2+kRaRU2KSzKb7XjPfScwEg3Cjg6NH/p+ikQLJ9eMkGC45NhSxYn8lixIIk+TgZ4yzTNOzFvF836gQw==", "requires": { - "@ledgerhq/hw-transport": "^6.3.0" + "@ledgerhq/hw-transport": "6.28.1" } }, "acorn": { diff --git a/package.json b/package.json index 2bf0a72..63db1f7 100644 --- a/package.json +++ b/package.json @@ -35,15 +35,15 @@ }, "homepage": "https://github.com/dfinity/hardware-wallet-cli#readme", "dependencies": { - "@dfinity/agent": "^2.1.2", - "@dfinity/ledger-icrc": "^2.6.0", - "@dfinity/nns": "^7.0.0", + "@dfinity/agent": "^2.1.3", + "@dfinity/ledger-icrc": "^2.6.2", + "@dfinity/nns": "^7.0.2", "@dfinity/principal": "^2.1.2", - "@dfinity/sns": "^3.2.1", - "@dfinity/utils": "^2.5.0", + "@dfinity/sns": "^3.2.3", + "@dfinity/utils": "^2.6.0", "@ledgerhq/hw-transport-node-hid-noevents": "^6.3.0", "@ledgerhq/hw-transport-webhid": "^6.27.1", - "@zondax/ledger-icp": "^0.6.0", + "@zondax/ledger-icp": "^3.2.4", "chalk": "^4.1.2", "commander": "^9.0.0", "node-fetch": "^2.6.1", diff --git a/src/bls-test/ledger-icp/icrc21.d.ts b/src/bls-test/ledger-icp/icrc21.d.ts new file mode 100644 index 0000000..5394e0a --- /dev/null +++ b/src/bls-test/ledger-icp/icrc21.d.ts @@ -0,0 +1,74 @@ +import type { Principal } from "@dfinity/principal"; +import type { ActorMethod } from "@dfinity/agent"; +import type { IDL } from "@dfinity/candid"; + +export interface DurationSeconds { + amount: bigint; +} +export interface TextValue { + content: string; +} +export interface TimestampSeconds { + amount: bigint; +} +export interface TokenAmount { + decimals: number; + amount: bigint; + symbol: string; +} +export type Value = + | { Text: TextValue } + | { TokenAmount: TokenAmount } + | { TimestampSeconds: TimestampSeconds } + | { DurationSeconds: DurationSeconds }; +export interface icrc21_consent_info { + metadata: icrc21_consent_message_metadata; + consent_message: icrc21_consent_message; +} +export type icrc21_consent_message = + | { + FieldsDisplayMessage: { + fields: Array<[string, Value]>; + intent: string; + }; + } + | { GenericDisplayMessage: string }; +export interface icrc21_consent_message_metadata { + utc_offset_minutes: [] | [number]; + language: string; +} +export interface icrc21_consent_message_request { + arg: Uint8Array | number[]; + method: string; + user_preferences: icrc21_consent_message_spec; +} +export type icrc21_consent_message_response = + | { Ok: icrc21_consent_info } + | { Err: icrc21_error }; +export interface icrc21_consent_message_spec { + metadata: icrc21_consent_message_metadata; + device_spec: [] | [{ GenericDisplay: null } | { FieldsDisplay: null }]; +} +export type icrc21_error = + | { + GenericError: { description: string; error_code: bigint }; + } + | { InsufficientPayment: icrc21_error_info } + | { UnsupportedCanisterCall: icrc21_error_info } + | { ConsentMessageUnavailable: icrc21_error_info }; +export interface icrc21_error_info { + description: string; +} +export interface _SERVICE { + greet: ActorMethod<[string], string>; + icrc10_supported_standards: ActorMethod< + [], + Array<{ url: string; name: string }> + >; + icrc21_canister_call_consent_message: ActorMethod< + [icrc21_consent_message_request], + icrc21_consent_message_response + >; +} +export declare const idlFactory: IDL.InterfaceFactory; +export declare const init: (args: { IDL: typeof IDL }) => IDL.Type[]; diff --git a/src/bls-test/ledger-icp/icrc21.idl.ts b/src/bls-test/ledger-icp/icrc21.idl.ts new file mode 100644 index 0000000..2b69025 --- /dev/null +++ b/src/bls-test/ledger-icp/icrc21.idl.ts @@ -0,0 +1,139 @@ +import { IDL } from "@dfinity/candid"; +const icrc21_consent_message_metadata = IDL.Record({ + utc_offset_minutes: IDL.Opt(IDL.Int16), + language: IDL.Text, +}); +const icrc21_consent_message_spec = IDL.Record({ + metadata: icrc21_consent_message_metadata, + device_spec: IDL.Opt( + IDL.Variant({ GenericDisplay: IDL.Null, FieldsDisplay: IDL.Null }) + ), +}); +export const icrc21_consent_message_request = IDL.Record({ + arg: IDL.Vec(IDL.Nat8), + method: IDL.Text, + user_preferences: icrc21_consent_message_spec, +}); +const TextValue = IDL.Record({ content: IDL.Text }); +const TokenAmount = IDL.Record({ + decimals: IDL.Nat8, + amount: IDL.Nat64, + symbol: IDL.Text, +}); +const TimestampSeconds = IDL.Record({ amount: IDL.Nat64 }); +const DurationSeconds = IDL.Record({ amount: IDL.Nat64 }); +const Value = IDL.Variant({ + Text: TextValue, + TokenAmount: TokenAmount, + TimestampSeconds: TimestampSeconds, + DurationSeconds: DurationSeconds, +}); +export const icrc21_consent_message = IDL.Variant({ + FieldsDisplayMessage: IDL.Record({ + fields: IDL.Vec(IDL.Tuple(IDL.Text, Value)), + intent: IDL.Text, + }), + GenericDisplayMessage: IDL.Text, +}); +const icrc21_consent_info = IDL.Record({ + metadata: icrc21_consent_message_metadata, + consent_message: icrc21_consent_message, +}); +const icrc21_error_info = IDL.Record({ description: IDL.Text }); +const icrc21_error = IDL.Variant({ + GenericError: IDL.Record({ + description: IDL.Text, + error_code: IDL.Nat, + }), + InsufficientPayment: icrc21_error_info, + UnsupportedCanisterCall: icrc21_error_info, + ConsentMessageUnavailable: icrc21_error_info, +}); +export const icrc21_consent_message_response = IDL.Variant({ + Ok: icrc21_consent_info, + Err: icrc21_error, +}); +export const greetFunction = IDL.Func([IDL.Text], [IDL.Text], ["query"]); +export const icrc10SupportedStandardsFunction = IDL.Func( + [], + [IDL.Vec(IDL.Record({ url: IDL.Text, name: IDL.Text }))], + ["query"] +); +export const icrc21CanisterCallConsentMessageFunction = IDL.Func( + [icrc21_consent_message_request], + [icrc21_consent_message_response], + [] +); + +export const idlFactory = ({ IDL }) => { + const icrc21_consent_message_metadata = IDL.Record({ + utc_offset_minutes: IDL.Opt(IDL.Int16), + language: IDL.Text, + }); + const icrc21_consent_message_spec = IDL.Record({ + metadata: icrc21_consent_message_metadata, + device_spec: IDL.Opt( + IDL.Variant({ GenericDisplay: IDL.Null, FieldsDisplay: IDL.Null }) + ), + }); + const icrc21_consent_message_request = IDL.Record({ + arg: IDL.Vec(IDL.Nat8), + method: IDL.Text, + user_preferences: icrc21_consent_message_spec, + }); + const TextValue = IDL.Record({ content: IDL.Text }); + const TokenAmount = IDL.Record({ + decimals: IDL.Nat8, + amount: IDL.Nat64, + symbol: IDL.Text, + }); + const TimestampSeconds = IDL.Record({ amount: IDL.Nat64 }); + const DurationSeconds = IDL.Record({ amount: IDL.Nat64 }); + const Value = IDL.Variant({ + Text: TextValue, + TokenAmount: TokenAmount, + TimestampSeconds: TimestampSeconds, + DurationSeconds: DurationSeconds, + }); + const icrc21_consent_message = IDL.Variant({ + FieldsDisplayMessage: IDL.Record({ + fields: IDL.Vec(IDL.Tuple(IDL.Text, Value)), + intent: IDL.Text, + }), + GenericDisplayMessage: IDL.Text, + }); + const icrc21_consent_info = IDL.Record({ + metadata: icrc21_consent_message_metadata, + consent_message: icrc21_consent_message, + }); + const icrc21_error_info = IDL.Record({ description: IDL.Text }); + const icrc21_error = IDL.Variant({ + GenericError: IDL.Record({ + description: IDL.Text, + error_code: IDL.Nat, + }), + InsufficientPayment: icrc21_error_info, + UnsupportedCanisterCall: icrc21_error_info, + ConsentMessageUnavailable: icrc21_error_info, + }); + const icrc21_consent_message_response = IDL.Variant({ + Ok: icrc21_consent_info, + Err: icrc21_error, + }); + return IDL.Service({ + greet: IDL.Func([IDL.Text], [IDL.Text], []), + icrc10_supported_standards: IDL.Func( + [], + [IDL.Vec(IDL.Record({ url: IDL.Text, name: IDL.Text }))], + ["query"] + ), + icrc21_canister_call_consent_message: IDL.Func( + [icrc21_consent_message_request], + [icrc21_consent_message_response], + [] + ), + }); +}; +export const init = ({ IDL }) => { + return []; +}; diff --git a/src/index.ts b/src/index.ts index 99d7577..1102405 100755 --- a/src/index.ts +++ b/src/index.ts @@ -36,9 +36,14 @@ import { isCurrentVersionSmallerThanFullCandidParser, } from "./utils"; import { CANDID_PARSER_VERSION, HOTKEY_PERMISSIONS } from "./constants"; -import { AnonymousIdentity, Identity } from "@dfinity/agent"; +import { Actor, AnonymousIdentity, Identity } from "@dfinity/agent"; import { SnsGovernanceCanister, SnsNeuronId } from "@dfinity/sns"; -import { TokenAmountV2, fromNullable, toNullable } from "@dfinity/utils"; +import { + TokenAmountV2, + fromNullable, + jsonReplacer, + toNullable, +} from "@dfinity/utils"; import { encodeIcrcAccount, IcrcAccount, @@ -57,6 +62,7 @@ import "node-window-polyfill/register"; // @ts-ignore (no types are available) import fetch from "node-fetch"; import { Secp256k1PublicKey } from "./ledger/secp256k1"; +import { idlFactory } from "./bls-test/ledger-icp/icrc21.idl"; (global as any).fetch = fetch; // Add polyfill for `window.fetch` for agent-js to work. @@ -758,6 +764,58 @@ async function setNodeProviderAccount(account: AccountIdentifier) { ok(); } +async function callIcrc21() { + const identity = await getIdentity(); + // await assertLedgerVersion({ identity, minVersion: CANDID_PARSER_VERSION }); + const spenderOwner = Principal.fromText("rdmx6-jaaaa-aaaaa-aaadq-cai"); + // const hwLedger = LedgerCanister.create({ + // agent: await getCurrentAgent(identity), + // }); + // await hwLedger.icrc2Approve({ + // spender: { owner: spenderOwner, subaccount: [] }, + // amount: 100_000_000n, + // expires_at: BigInt(Date.now() * 1_000_000 + 1_000_000_000 * 60 * 60 * 24), + // }); + const ledgerCanister = IcrcLedgerCanister.create({ + agent: await getCurrentAgent(identity), + // CHAT + // canisterId: Principal.fromText("ekfwe-siaaa-aaaaf-qapta-cai"), + // ckBTC + // canisterId: Principal.fromText("mxzaz-hqaaa-aaaar-qaada-cai"), + // Test canister id + // canisterId: Principal.fromText("suje7-zaaaa-aaaad-abnzq-cai"), + // TESTICP Ledger canister id + canisterId: Principal.fromText("xafvr-biaaa-aaaai-aql5q-cai"), + }); + + // const anonymousIdentity = new AnonymousIdentityWrapper(); + + // const actor = Actor.createActor(idlFactory, { + // agent: await getCurrentAgent(identity), + // // agent: await getCurrentAgent(anonymousIdentity), + // canisterId: Principal.fromText("suje7-zaaaa-aaaad-abnzq-cai"), + // }); + + try { + // const response = await actor.greet("Hello, world!"); + // console.log(`Response from ICRC21 canister: ${response}`); + + const response = await ledgerCanister.approve({ + spender: { owner: spenderOwner, subaccount: [] }, + amount: 100_000_000n, + expires_at: BigInt(Date.now() * 1_000_000 + 1_000_000_000 * 60 * 60 * 24), + }); + + console.log(`Response from approve canister: ${response}`); + + ok("Approved 1 token for spending."); + } catch (error: any) { + console.log("in da catch"); + console.log(error); + err(error); + } +} + /** * Fetches the balance of the main account on the wallet. */ @@ -785,6 +843,7 @@ async function run(f: () => void) { try { await f(); } catch (error: any) { + err(JSON.stringify(error, jsonReplacer)); err(error); } } @@ -1306,6 +1365,11 @@ async function main() { ) .action((args) => run(() => setNodeProviderAccount(args.account))) ); + + const icrc21 = new Command("icrc-21") + .description("Commands for making ICRC 21 calls.") + .showSuggestionAfterError() + .addCommand(new Command("call").action((args) => run(() => callIcrc21()))); program .description("A CLI for the Ledger hardware wallet.") .enablePositionalOptions() @@ -1333,7 +1397,8 @@ async function main() { .addCommand(neuron) .addCommand(sns) .addCommand(icrc) - .addCommand(nodeProvider); + .addCommand(nodeProvider) + .addCommand(icrc21); await program.parseAsync(process.argv); } diff --git a/src/ledger/identity.ts b/src/ledger/identity.ts index 698d3f5..c0b9915 100644 --- a/src/ledger/identity.ts +++ b/src/ledger/identity.ts @@ -1,15 +1,32 @@ import { + AnonymousIdentity, + bufFromBufLike, CallRequest, Cbor, + Certificate, + Expiry, + HttpAgent, HttpAgentRequest, + HttpDetailsResponse, + lookupResultToBuffer, + pollForResponse, PublicKey, ReadRequest, Signature, SignIdentity, + strategy, + SubmitResponse, + v2ResponseBody, + v3ResponseBody, } from "@dfinity/agent"; import { Principal } from "@dfinity/principal"; -import LedgerApp, { LedgerError, ResponseSign } from "@zondax/ledger-icp"; +import LedgerApp, { ResponseSign } from "@zondax/ledger-icp"; import { Secp256k1PublicKey } from "./secp256k1"; +import { + icrc21_consent_message_request, + icrc21_consent_message_response, +} from "../bls-test/ledger-icp/icrc21.idl"; +import * as fs from "fs"; // @ts-ignore (no types are available) import TransportWebHID, { Transport } from "@ledgerhq/hw-transport-webhid"; @@ -18,6 +35,7 @@ import TransportNodeHidNoEvents from "@ledgerhq/hw-transport-node-hid-noevents"; // Add polyfill for `window.fetch` for agent-js to work. // @ts-ignore (no types are available) import fetch from "node-fetch"; +import { IDL, toHexString } from "@dfinity/candid"; global.fetch = fetch; /** @@ -110,18 +128,17 @@ export class LedgerIdentity extends SignIdentity { // @ts-ignore if (resp.returnCode == 28161) { throw "Please open the Internet Computer app on your wallet and try again."; - } else if (resp.returnCode == LedgerError.TransactionRejected) { - throw "Ledger Wallet is locked. Unlock it and try again."; // @ts-ignore } else if (resp.returnCode == 65535) { throw "Unable to fetch the public key. Please try again."; } + // TODO: Manage all return codes that are errors. // This type doesn't have the right fields in it, so we have to manually type it. const principal = (resp as unknown as { principalText: string }) .principalText; const publicKey = Secp256k1PublicKey.fromRaw( - new Uint8Array(resp.publicKey) + new Uint8Array(resp.publicKey as Buffer) ); if ( @@ -164,7 +181,44 @@ export class LedgerIdentity extends SignIdentity { return this._publicKey; } + public async signBls( + consentRequest: string, + canisterCall: string, + certificate: string + ): Promise { + console.log("in da signBls"); + return await this._executeWithApp(async (app: LedgerApp) => { + const resp: ResponseSign = await app.signBls( + this.derivePath, + consentRequest, + canisterCall, + certificate + ); + + // Remove the "neuron stake" flag, since we already signed the transaction. + this._neuronStakeFlag = false; + + const signatureRS = resp.signatureRS; + if (!signatureRS) { + throw new Error( + `A ledger error happened during signature:\n` + + `Code: ${resp.returnCode}\n` + + `Message: ${JSON.stringify(resp.errorMessage)}\n` + ); + } + + if (signatureRS?.byteLength !== 64) { + throw new Error( + `Signature must be 64 bytes long (is ${signatureRS.length})` + ); + } + + return bufferToArrayBuffer(signatureRS) as Signature; + }); + } + public async sign(blob: ArrayBuffer): Promise { + console.log("in da sign"); return await this._executeWithApp(async (app: LedgerApp) => { const resp: ResponseSign = await app.sign( this.derivePath, @@ -201,9 +255,189 @@ export class LedgerIdentity extends SignIdentity { this._neuronStakeFlag = true; } + private getResponseData = async ( + { requestId, response, requestDetails }: SubmitResponse, + agent: HttpAgent, + canisterId: Principal + ) => { + let reply: ArrayBuffer | undefined; + let certificate: Certificate | undefined; + if (response.body && (response.body as v3ResponseBody).certificate) { + const cert = (response.body as v3ResponseBody).certificate; + certificate = await Certificate.create({ + certificate: bufFromBufLike(cert), + rootKey: agent.rootKey, + canisterId, + }); + const path = [new TextEncoder().encode("request_status"), requestId]; + const status = new TextDecoder().decode( + lookupResultToBuffer(certificate.lookup([...path, "status"])) + ); + + switch (status) { + case "replied": + reply = lookupResultToBuffer(certificate.lookup([...path, "reply"])); + break; + case "rejected": { + // Find rejection details in the certificate + const rejectCode = new Uint8Array( + lookupResultToBuffer(certificate.lookup([...path, "reject_code"]))! + )[0]; + const rejectMessage = new TextDecoder().decode( + lookupResultToBuffer( + certificate.lookup([...path, "reject_message"]) + )! + ); + const error_code_buf = lookupResultToBuffer( + certificate.lookup([...path, "error_code"]) + ); + const error_code = error_code_buf + ? new TextDecoder().decode(error_code_buf) + : undefined; + throw new Error("Call rejected: " + rejectMessage); + } + } + } else if (response.body && "reject_message" in response.body) { + // handle v2 response errors by throwing an UpdateCallRejectedError object + const { reject_code, reject_message, error_code } = + response.body as v2ResponseBody; + throw new Error("Call rejected: " + reject_message); + } + + // Fall back to polling if we receive an Accepted response code + if (response.status === 202) { + // Contains the certificate and the reply from the boundary node + const response = await pollForResponse( + agent, + canisterId, + requestId, + strategy.defaultStrategy() + ); + certificate = response.certificate; + reply = response.reply; + } + + const httpDetails = { ...response, requestDetails } as HttpDetailsResponse; + if (reply !== undefined) { + return { + httpDetails, + certificate, + result: IDL.decode( + [icrc21_consent_message_response], + Buffer.from(reply) + ), + }; + } else { + throw new Error(`Call was returned undefined, but type [].`); + } + }; + public async transformRequest(request: HttpAgentRequest): Promise { const { body, ...fields } = request; - const signature = await this.sign(_prepareCborForLedger(body)); + if (body.request_type === "read_state") { + console.log("in da read_state", body); + const signature = await this.sign(_prepareCborForLedger(body)); + return { + ...fields, + body: { + content: body, + sender_pubkey: this._publicKey.toDer(), + sender_sig: signature, + }, + }; + } + + if (body.request_type === "call") { + // Not always necessary. + body.ingress_expiry = new Expiry(300_000); + } + const anonymousIdentity = new AnonymousIdentity(); + const anonymousAgent = await HttpAgent.create({ + identity: anonymousIdentity, + }); + + // CHAT Ledger + // const canisterId = Principal.fromText("ekfwe-siaaa-aaaaf-qapta-cai"); + // CkBTC Ledger + // const canisterId = Principal.fromText("mxzaz-hqaaa-aaaar-qaada-cai"); + // ICP Ledger + // const canisterId = Principal.fromText("ryjl3-tyaaa-aaaaa-aaaba-cai"); + // Test canister + // const canisterId = Principal.fromText("suje7-zaaaa-aaaad-abnzq-cai"); + // TESTICP Ledger canister id + const canisterId = Principal.fromText("xafvr-biaaa-aaaai-aql5q-cai"); + const consentMessageArgs = { + arg: body.arg, + // method: "greet", + method: body.method_name, + user_preferences: { + metadata: { + language: "en", + utc_offset_minutes: [], + }, + device_spec: [ + { + FieldsDisplay: null, + }, + ], + }, + }; + const arg = IDL.encode( + [icrc21_consent_message_request], + [consentMessageArgs] + ); + const icrc21ConsentMessageCall = { + methodName: "icrc21_canister_call_consent_message", + arg, + callSync: true, + }; + const submitResponse = await anonymousAgent.call( + canisterId, + icrc21ConsentMessageCall + ); + const responseData = await this.getResponseData( + submitResponse, + anonymousAgent, + canisterId + ); + console.log("responseData", responseData); + const consentRequest = toHexString( + _prepareCborForLedger(submitResponse.requestDetails as CallRequest) + ); + const canisterCall = toHexString(_prepareCborForLedger(body)); + const cert = (submitResponse.response.body as v3ResponseBody).certificate; + const certificate = toHexString(cert); + const data = { + consentRequest: submitResponse.requestDetails, + consentRequestArgs: consentMessageArgs, + consentRequestHex: consentRequest, + consentResponse: responseData.result[0], + cansiterCall: body, + canisterCallHex: canisterCall, + certificate, + }; + + fs.writeFileSync( + "output.json", + JSON.stringify(data, (key, value) => { + if (typeof value === "bigint") { + return value.toString(); + } + if (value instanceof Principal) { + return value.toText(); + } + if (value instanceof Uint8Array) { + return Array.from(value); + } + return value; + }) + ); + const signature = await this.signBls( + consentRequest, + canisterCall, + certificate + ); + console.log("after da signBls"); return { ...fields, body: { @@ -240,9 +474,9 @@ export class LedgerIdentity extends SignIdentity { } interface Version { - major: number; - minor: number; - patch: number; + major?: number; + minor?: number; + patch?: number; } function bufferToArrayBuffer(buffer: Buffer): ArrayBuffer { @@ -251,3 +485,20 @@ function bufferToArrayBuffer(buffer: Buffer): ArrayBuffer { buffer.byteOffset + buffer.byteLength ); } + +// This was used to prove that the the call to read_state also happens with the anonynoys identity. +// The error has nothing to do with the ICRC-21 flow. +export class AnonymousIdentityWrapper extends AnonymousIdentity { + public async transformRequest(request: HttpAgentRequest): Promise { + const { body, ...fields } = request; + console.log("transformRequest", request); + if (body.request_type === "read_state") { + console.log("in da read_state"); + if ("toText" in body.sender) { + console.log("sender is a Principal", body.sender.toText()); + } + return request; + } + return request; + } +} diff --git a/src/utils.ts b/src/utils.ts index 2a196d8..4fccf95 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -100,12 +100,13 @@ export async function getAgent( // Only fetch the rootkey if the network isn't mainnet. const fetchRootKey = new URL(network).host == "ic0.app" ? false : true; - const agent = new HttpAgent({ + const agent = await HttpAgent.create({ host: network, identity: identity, }); if (fetchRootKey) { + console.log("Fetching root key for agent..."); await agent.fetchRootKey(); }