quantumcoin 7.0.12 → 7.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README-SDK.md +828 -823
- package/README.md +4 -0
- package/config.d.ts +50 -50
- package/examples/example-generated-sdk-js/README.md +65 -0
- package/examples/example-generated-sdk-js/examples/_test-wallet.js +17 -0
- package/examples/example-generated-sdk-js/examples/deploy.js +41 -0
- package/examples/example-generated-sdk-js/examples/events.js +36 -0
- package/examples/example-generated-sdk-js/examples/read-operations.js +46 -0
- package/examples/example-generated-sdk-js/examples/write-operations.js +44 -0
- package/examples/example-generated-sdk-js/index.d.ts +1 -0
- package/examples/example-generated-sdk-js/index.js +15 -0
- package/examples/example-generated-sdk-js/package-lock.json +59 -0
- package/examples/example-generated-sdk-js/package.json +22 -0
- package/examples/example-generated-sdk-js/src/SimpleERC20.d.ts +19 -0
- package/examples/example-generated-sdk-js/src/SimpleERC20.js +353 -0
- package/examples/example-generated-sdk-js/src/SimpleERC20__factory.d.ts +10 -0
- package/examples/example-generated-sdk-js/src/SimpleERC20__factory.js +29 -0
- package/examples/example-generated-sdk-js/src/index.d.ts +4 -0
- package/examples/example-generated-sdk-js/src/index.js +5 -0
- package/examples/example-generated-sdk-js/src/quantumcoin-shims.d.ts +23 -0
- package/examples/example-generated-sdk-js/src/types.d.ts +3 -0
- package/examples/example-generated-sdk-js/src/types.js +3 -0
- package/examples/example-generated-sdk-js/test/e2e/SimpleERC20.e2e.test.js +78 -0
- package/examples/example-generated-sdk-ts/README.md +65 -0
- package/examples/example-generated-sdk-ts/examples/_test-wallet.js +17 -0
- package/examples/example-generated-sdk-ts/examples/deploy.js +41 -0
- package/examples/example-generated-sdk-ts/examples/events.js +36 -0
- package/examples/example-generated-sdk-ts/examples/read-operations.js +46 -0
- package/examples/example-generated-sdk-ts/examples/write-operations.js +44 -0
- package/examples/example-generated-sdk-ts/index.d.ts +1 -0
- package/examples/example-generated-sdk-ts/index.js +15 -0
- package/examples/example-generated-sdk-ts/package-lock.json +59 -0
- package/examples/example-generated-sdk-ts/package.json +23 -0
- package/examples/example-generated-sdk-ts/src/SimpleERC20.ts +334 -0
- package/examples/example-generated-sdk-ts/src/SimpleERC20__factory.ts +28 -0
- package/examples/example-generated-sdk-ts/src/index.ts +4 -0
- package/examples/example-generated-sdk-ts/src/quantumcoin-shims.d.ts +23 -0
- package/examples/example-generated-sdk-ts/src/types.ts +4 -0
- package/examples/example-generated-sdk-ts/test/e2e/SimpleERC20.e2e.test.js +78 -0
- package/examples/example-generated-sdk-ts/tsconfig.json +14 -0
- package/examples/sdk-generator-erc20.inline.json +251 -251
- package/generate-sdk.js +1824 -1822
- package/package.json +1 -1
- package/src/abi/fragments.d.ts +42 -42
- package/src/abi/index.d.ts +13 -13
- package/src/contract/index.d.ts +9 -9
- package/src/errors/index.d.ts +92 -92
- package/src/generator/index.d.ts +11 -4
- package/src/generator/index.js +33 -5
- package/src/internal/hex.d.ts +68 -61
- package/src/internal/hex.js +36 -0
- package/src/providers/json-rpc-provider.d.ts +12 -12
- package/src/providers/provider.js +3 -3
- package/src/utils/address.d.ts +58 -58
- package/src/utils/encoding.d.ts +120 -120
- package/src/utils/hashing.js +298 -298
- package/src/utils/index.d.ts +63 -63
- package/src/utils/index.js +14 -14
- package/src/utils/result.d.ts +57 -57
- package/src/utils/rlp.d.ts +12 -12
- package/src/utils/units.d.ts +29 -29
- package/src/wallet/index.d.ts +10 -10
- package/src/wallet/wallet.d.ts +192 -192
- package/src/wallet/wallet.js +630 -630
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/README.md +83 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/artifacts/AllSolidityTypes.abi.json +12544 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/artifacts/AllSolidityTypes.bin +1 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/_test-wallet.js +17 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/_test-wallet.ts +10 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/deploy.js +41 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/deploy.ts +41 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/events.js +36 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/events.ts +36 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/offline-signing.js +82 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/offline-signing.ts +80 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/read-operations.js +46 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/read-operations.ts +44 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/write-operations.js +44 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/examples/write-operations.ts +44 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/index.d.ts +1 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/index.js +21 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/package-lock.json +597 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/package.json +25 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/src/AllSolidityTypes.d.ts +1280 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/src/AllSolidityTypes.js +14021 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/src/AllSolidityTypes__factory.d.ts +11 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/src/AllSolidityTypes__factory.js +29 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/src/index.d.ts +4 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/src/index.js +5 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/src/quantumcoin-shims.d.ts +25 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/src/types.d.ts +3 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/src/types.js +3 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/test/e2e/AllSolidityTypes.e2e.test.js +77 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-js/test/e2e/AllSolidityTypes.extra.test.js +195 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/README.md +83 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/artifacts/AllSolidityTypes.abi.json +12544 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/artifacts/AllSolidityTypes.bin +1 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/_test-wallet.js +17 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/_test-wallet.ts +10 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/deploy.js +41 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/deploy.ts +41 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/events.js +36 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/events.ts +36 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/offline-signing.js +82 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/offline-signing.ts +80 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/read-operations.js +46 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/read-operations.ts +44 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/write-operations.js +44 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/examples/write-operations.ts +44 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/index.d.ts +1 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/index.js +21 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/package-lock.json +597 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/package.json +26 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/src/AllSolidityTypes.ts +13940 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/src/AllSolidityTypes__factory.ts +29 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/src/index.ts +4 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/src/quantumcoin-shims.d.ts +25 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/src/types.ts +4 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/test/e2e/AllSolidityTypes.e2e.test.js +77 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/test/e2e/AllSolidityTypes.extra.test.js +195 -0
- package/test/e2e/generated-sdks/all-solidity-types/all-solidity-types-ts/tsconfig.json +18 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/README.md +74 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/artifacts/SimpleERC20.abi.json +245 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/artifacts/SimpleERC20.bin +1 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/_test-wallet.js +17 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/_test-wallet.ts +10 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/deploy.js +41 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/deploy.ts +41 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/events.js +36 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/events.ts +36 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/offline-signing.js +82 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/offline-signing.ts +80 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/read-operations.js +46 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/read-operations.ts +44 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/write-operations.js +44 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/examples/write-operations.ts +44 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/index.d.ts +1 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/index.js +16 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/package-lock.json +597 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/package.json +25 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/src/SimpleERC20.d.ts +24 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/src/SimpleERC20.js +372 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/src/SimpleERC20__factory.d.ts +10 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/src/SimpleERC20__factory.js +29 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/src/index.d.ts +4 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/src/index.js +5 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/src/quantumcoin-shims.d.ts +25 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/src/types.d.ts +3 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/src/types.js +3 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-js/test/e2e/SimpleERC20.e2e.test.js +90 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/README.md +74 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/artifacts/SimpleERC20.abi.json +245 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/artifacts/SimpleERC20.bin +1 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/_test-wallet.js +17 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/_test-wallet.ts +10 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/deploy.js +41 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/deploy.ts +41 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/events.js +36 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/events.ts +36 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/offline-signing.js +82 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/offline-signing.ts +80 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/read-operations.js +46 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/read-operations.ts +44 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/write-operations.js +44 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/examples/write-operations.ts +44 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/index.d.ts +1 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/index.js +16 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/package-lock.json +597 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/package.json +26 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/src/SimpleERC20.ts +355 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/src/SimpleERC20__factory.ts +28 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/src/index.ts +4 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/src/quantumcoin-shims.d.ts +25 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/src/types.ts +4 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/test/e2e/SimpleERC20.e2e.test.js +90 -0
- package/test/e2e/generated-sdks/simple-erc20/simple-erc20-ts/tsconfig.json +18 -0
- package/test/e2e/generator-interface.e2e.test.js +163 -0
- package/test/e2e/generator-interface.e2e.test.ts +158 -0
- package/test/e2e/signing-context-and-fee.e2e.test.js +141 -141
- package/test/e2e/signing-context-and-fee.e2e.test.ts +128 -128
- package/test/integration/provider.test.js +88 -88
- package/test/unit/address-wallet.test.js +892 -892
- package/test/unit/address-wallet.test.ts +877 -877
- package/test/unit/generator.test.js +48 -1
- package/test/unit/generator.test.ts +48 -1
- package/test/unit/hashing.test.js +64 -64
- package/test/unit/hashing.test.ts +63 -63
- package/test/unit/internal-hex.test.js +32 -1
- package/test/unit/internal-hex.test.ts +32 -1
- package/test/unit/providers.test.js +51 -1
- package/test/unit/providers.test.ts +53 -0
- package/examples/node_modules/.bin/esbuild +0 -16
- package/examples/node_modules/.bin/esbuild.cmd +0 -17
- package/examples/node_modules/.bin/esbuild.ps1 +0 -28
- package/examples/node_modules/.bin/sdkgen +0 -16
- package/examples/node_modules/.bin/sdkgen.cmd +0 -17
- package/examples/node_modules/.bin/sdkgen.ps1 +0 -28
- package/examples/node_modules/.bin/tsx +0 -16
- package/examples/node_modules/.bin/tsx.cmd +0 -17
- package/examples/node_modules/.bin/tsx.ps1 +0 -28
- package/examples/node_modules/.package-lock.json +0 -144
- package/examples/node_modules/@esbuild/win32-x64/README.md +0 -3
- package/examples/node_modules/@esbuild/win32-x64/esbuild.exe +0 -0
- package/examples/node_modules/@esbuild/win32-x64/package.json +0 -20
- package/examples/node_modules/esbuild/LICENSE.md +0 -21
- package/examples/node_modules/esbuild/README.md +0 -3
- package/examples/node_modules/esbuild/bin/esbuild +0 -223
- package/examples/node_modules/esbuild/install.js +0 -289
- package/examples/node_modules/esbuild/lib/main.d.ts +0 -716
- package/examples/node_modules/esbuild/lib/main.js +0 -2532
- package/examples/node_modules/esbuild/package.json +0 -49
- package/examples/node_modules/get-tsconfig/LICENSE +0 -21
- package/examples/node_modules/get-tsconfig/README.md +0 -235
- package/examples/node_modules/get-tsconfig/dist/index.cjs +0 -7
- package/examples/node_modules/get-tsconfig/dist/index.d.cts +0 -2088
- package/examples/node_modules/get-tsconfig/dist/index.d.mts +0 -2088
- package/examples/node_modules/get-tsconfig/dist/index.mjs +0 -7
- package/examples/node_modules/get-tsconfig/package.json +0 -46
- package/examples/node_modules/quantum-coin-js-sdk/LICENSE +0 -21
- package/examples/node_modules/quantum-coin-js-sdk/LICENSE-wasm_exec.js.txt +0 -30
- package/examples/node_modules/quantum-coin-js-sdk/README.md +0 -1675
- package/examples/node_modules/quantum-coin-js-sdk/example/README.md +0 -14
- package/examples/node_modules/quantum-coin-js-sdk/example/conversion-example.js +0 -19
- package/examples/node_modules/quantum-coin-js-sdk/example/example-create-contract.js +0 -396
- package/examples/node_modules/quantum-coin-js-sdk/example/example-encode-decode-rlp.js +0 -225
- package/examples/node_modules/quantum-coin-js-sdk/example/example-event-pack-unpack.js +0 -391
- package/examples/node_modules/quantum-coin-js-sdk/example/example-misc.js +0 -101
- package/examples/node_modules/quantum-coin-js-sdk/example/example-rpc-send-signRawTransaction.js +0 -318
- package/examples/node_modules/quantum-coin-js-sdk/example/example-rpc-send.js +0 -116
- package/examples/node_modules/quantum-coin-js-sdk/example/example-send.js +0 -70
- package/examples/node_modules/quantum-coin-js-sdk/example/example-token-pack-unpack.js +0 -961
- package/examples/node_modules/quantum-coin-js-sdk/example/example-wallet-version4.js +0 -35
- package/examples/node_modules/quantum-coin-js-sdk/example/example-wallet.js +0 -43
- package/examples/node_modules/quantum-coin-js-sdk/example/example.js +0 -405
- package/examples/node_modules/quantum-coin-js-sdk/example/package-lock.json +0 -134
- package/examples/node_modules/quantum-coin-js-sdk/example/package.json +0 -15
- package/examples/node_modules/quantum-coin-js-sdk/index.d.ts +0 -1031
- package/examples/node_modules/quantum-coin-js-sdk/index.js +0 -3144
- package/examples/node_modules/quantum-coin-js-sdk/package.json +0 -34
- package/examples/node_modules/quantum-coin-js-sdk/tests/encrypted-32.json +0 -1
- package/examples/node_modules/quantum-coin-js-sdk/tests/encrypted-36.json +0 -1
- package/examples/node_modules/quantum-coin-js-sdk/tests/encrypted-48.json +0 -1
- package/examples/node_modules/quantum-coin-js-sdk/tests/generate-verify-vectors.js +0 -91
- package/examples/node_modules/quantum-coin-js-sdk/tests/non-transactional.preinit.test.js +0 -41
- package/examples/node_modules/quantum-coin-js-sdk/tests/non-transactional.test.js +0 -1389
- package/examples/node_modules/quantum-coin-js-sdk/tests/sign-raw-keytype5-context-null.test.js +0 -107
- package/examples/node_modules/quantum-coin-js-sdk/tests/sign-raw-transaction.test.js +0 -196
- package/examples/node_modules/quantum-coin-js-sdk/tests/sign-verify.test.js +0 -311
- package/examples/node_modules/quantum-coin-js-sdk/tests/transactional.relay.test.js +0 -131
- package/examples/node_modules/quantum-coin-js-sdk/tests/transactional.rpc.test.js +0 -103
- package/examples/node_modules/quantum-coin-js-sdk/tests/verify-vectors.json +0 -95035
- package/examples/node_modules/quantum-coin-js-sdk/wasmBase64.d.ts +0 -9
- package/examples/node_modules/quantum-coin-js-sdk/wasmBase64.js +0 -16
- package/examples/node_modules/quantum-coin-js-sdk/wasm_exec.d.ts +0 -0
- package/examples/node_modules/quantum-coin-js-sdk/wasm_exec.js +0 -587
- package/examples/node_modules/resolve-pkg-maps/LICENSE +0 -21
- package/examples/node_modules/resolve-pkg-maps/README.md +0 -216
- package/examples/node_modules/resolve-pkg-maps/dist/index.cjs +0 -1
- package/examples/node_modules/resolve-pkg-maps/dist/index.d.cts +0 -11
- package/examples/node_modules/resolve-pkg-maps/dist/index.d.mts +0 -11
- package/examples/node_modules/resolve-pkg-maps/dist/index.mjs +0 -1
- package/examples/node_modules/resolve-pkg-maps/package.json +0 -42
- package/examples/node_modules/seed-words/.github/workflows/publish-npmjs.yaml +0 -22
- package/examples/node_modules/seed-words/BUILD.md +0 -7
- package/examples/node_modules/seed-words/LICENSE +0 -121
- package/examples/node_modules/seed-words/README.md +0 -67
- package/examples/node_modules/seed-words/dist/seedwords.d.ts +0 -39
- package/examples/node_modules/seed-words/package.json +0 -27
- package/examples/node_modules/seed-words/seedwords.js +0 -315
- package/examples/node_modules/seed-words/seedwords.txt +0 -65536
- package/examples/node_modules/seed-words/tsconfig.json +0 -21
- package/examples/node_modules/tsx/LICENSE +0 -21
- package/examples/node_modules/tsx/README.md +0 -32
- package/examples/node_modules/tsx/dist/cjs/api/index.cjs +0 -1
- package/examples/node_modules/tsx/dist/cjs/api/index.d.cts +0 -35
- package/examples/node_modules/tsx/dist/cjs/api/index.d.mts +0 -35
- package/examples/node_modules/tsx/dist/cjs/api/index.mjs +0 -1
- package/examples/node_modules/tsx/dist/cjs/index.cjs +0 -1
- package/examples/node_modules/tsx/dist/cjs/index.mjs +0 -1
- package/examples/node_modules/tsx/dist/cli.cjs +0 -54
- package/examples/node_modules/tsx/dist/cli.mjs +0 -55
- package/examples/node_modules/tsx/dist/client-BQVF1NaW.mjs +0 -1
- package/examples/node_modules/tsx/dist/client-D6NvIMSC.cjs +0 -1
- package/examples/node_modules/tsx/dist/esm/api/index.cjs +0 -1
- package/examples/node_modules/tsx/dist/esm/api/index.d.cts +0 -35
- package/examples/node_modules/tsx/dist/esm/api/index.d.mts +0 -35
- package/examples/node_modules/tsx/dist/esm/api/index.mjs +0 -1
- package/examples/node_modules/tsx/dist/esm/index.cjs +0 -2
- package/examples/node_modules/tsx/dist/esm/index.mjs +0 -2
- package/examples/node_modules/tsx/dist/get-pipe-path-BHW2eJdv.mjs +0 -1
- package/examples/node_modules/tsx/dist/get-pipe-path-BoR10qr8.cjs +0 -1
- package/examples/node_modules/tsx/dist/index-7AaEi15b.mjs +0 -14
- package/examples/node_modules/tsx/dist/index-BWFBUo6r.cjs +0 -1
- package/examples/node_modules/tsx/dist/index-gbaejti9.mjs +0 -1
- package/examples/node_modules/tsx/dist/index-gckBtVBf.cjs +0 -14
- package/examples/node_modules/tsx/dist/lexer-DQCqS3nf.mjs +0 -3
- package/examples/node_modules/tsx/dist/lexer-DgIbo0BU.cjs +0 -3
- package/examples/node_modules/tsx/dist/loader.cjs +0 -1
- package/examples/node_modules/tsx/dist/loader.mjs +0 -1
- package/examples/node_modules/tsx/dist/node-features-_8ZFwP_x.mjs +0 -1
- package/examples/node_modules/tsx/dist/node-features-roYmp9jK.cjs +0 -1
- package/examples/node_modules/tsx/dist/package-CeBgXWuR.mjs +0 -1
- package/examples/node_modules/tsx/dist/package-Dxt5kIHw.cjs +0 -1
- package/examples/node_modules/tsx/dist/patch-repl.cjs +0 -1
- package/examples/node_modules/tsx/dist/patch-repl.mjs +0 -1
- package/examples/node_modules/tsx/dist/preflight.cjs +0 -1
- package/examples/node_modules/tsx/dist/preflight.mjs +0 -1
- package/examples/node_modules/tsx/dist/register-2sWVXuRQ.cjs +0 -1
- package/examples/node_modules/tsx/dist/register-B7jrtLTO.mjs +0 -1
- package/examples/node_modules/tsx/dist/register-CFH5oNdT.mjs +0 -4
- package/examples/node_modules/tsx/dist/register-D46fvsV_.cjs +0 -4
- package/examples/node_modules/tsx/dist/repl.cjs +0 -3
- package/examples/node_modules/tsx/dist/repl.mjs +0 -3
- package/examples/node_modules/tsx/dist/require-D4F1Lv60.cjs +0 -1
- package/examples/node_modules/tsx/dist/require-DQxpCAr4.mjs +0 -1
- package/examples/node_modules/tsx/dist/suppress-warnings.cjs +0 -1
- package/examples/node_modules/tsx/dist/suppress-warnings.mjs +0 -1
- package/examples/node_modules/tsx/dist/temporary-directory-B83uKxJF.cjs +0 -1
- package/examples/node_modules/tsx/dist/temporary-directory-CwHp0_NW.mjs +0 -1
- package/examples/node_modules/tsx/dist/types-Cxp8y2TL.d.ts +0 -5
- package/examples/node_modules/tsx/package.json +0 -68
package/src/wallet/wallet.js
CHANGED
|
@@ -1,630 +1,630 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Wallet and signer implementations.
|
|
3
|
-
*
|
|
4
|
-
* The QuantumCoin.js wallet model mirrors ethers.js v6:
|
|
5
|
-
* - AbstractSigner -> BaseWallet -> Wallet
|
|
6
|
-
* - NonceManager wrapper
|
|
7
|
-
*
|
|
8
|
-
* Cryptographic operations are delegated to `quantum-coin-js-sdk`.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
const qcsdk = require("quantum-coin-js-sdk");
|
|
12
|
-
const seedWords = require("seed-words");
|
|
13
|
-
const { JsonRpcProvider } = require("../providers/json-rpc-provider");
|
|
14
|
-
const { assertArgument, assertSecretArgument, makeError } = require("../errors");
|
|
15
|
-
const { arrayify, bytesToHex, hexToBytes, isHexString, normalizeHex } = require("../internal/hex");
|
|
16
|
-
const { getAddress } = require("../utils/address");
|
|
17
|
-
const { WeiPerEther } = require("../constants");
|
|
18
|
-
|
|
19
|
-
function _requireInitialized() {
|
|
20
|
-
// eslint-disable-next-line global-require
|
|
21
|
-
const { isInitialized, getInitializationPromise } = require("../../config");
|
|
22
|
-
if (isInitialized()) return;
|
|
23
|
-
if (getInitializationPromise() != null) {
|
|
24
|
-
throw makeError(
|
|
25
|
-
"QuantumCoin SDK is still initializing. Await the Initialize() promise before using SDK methods.",
|
|
26
|
-
"UNKNOWN_ERROR",
|
|
27
|
-
{ operation: "requireInitialized" },
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
throw makeError("QuantumCoin SDK not initialized. Call Initialize() first.", "UNKNOWN_ERROR", { operation: "wallet" });
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function _bytesToNumberArray(bytes) {
|
|
34
|
-
return Array.from(bytes);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const _maxSafeInt = 0x1fffffffffffffn; // 2^53 - 1
|
|
38
|
-
|
|
39
|
-
function _getBigInt(value, name) {
|
|
40
|
-
if (typeof value === "bigint") return value;
|
|
41
|
-
if (typeof value === "number") {
|
|
42
|
-
assertArgument(Number.isInteger(value), "underflow", name, value);
|
|
43
|
-
assertArgument(value >= -Number(_maxSafeInt) && value <= Number(_maxSafeInt), "overflow", name, value);
|
|
44
|
-
return BigInt(value);
|
|
45
|
-
}
|
|
46
|
-
if (typeof value === "string") {
|
|
47
|
-
if (value === "0x" || value === "0X") return 0n;
|
|
48
|
-
try { return BigInt(value); }
|
|
49
|
-
catch { assertArgument(false, "invalid BigNumberish string", name, value); }
|
|
50
|
-
}
|
|
51
|
-
assertArgument(false, "invalid BigNumberish", name, value);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function _getNumber(value, name) {
|
|
55
|
-
const bi = _getBigInt(value, name);
|
|
56
|
-
assertArgument(bi >= -_maxSafeInt && bi <= _maxSafeInt, "overflow", name, value);
|
|
57
|
-
return Number(bi);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* SigningKey wrapper (PQC private/public key bytes).
|
|
62
|
-
*/
|
|
63
|
-
class SigningKey {
|
|
64
|
-
/**
|
|
65
|
-
* @param {Uint8Array} privateKeyBytes
|
|
66
|
-
* @param {Uint8Array} publicKeyBytes
|
|
67
|
-
*/
|
|
68
|
-
constructor(privateKeyBytes, publicKeyBytes) {
|
|
69
|
-
Object.defineProperty(this, "privateKeyBytes", {
|
|
70
|
-
enumerable: false,
|
|
71
|
-
configurable: false,
|
|
72
|
-
writable: false,
|
|
73
|
-
value: new Uint8Array(privateKeyBytes),
|
|
74
|
-
});
|
|
75
|
-
this.publicKeyBytes = new Uint8Array(publicKeyBytes);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
toJSON() {
|
|
79
|
-
return {};
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* AbstractSigner base (minimal).
|
|
85
|
-
*/
|
|
86
|
-
class AbstractSigner {
|
|
87
|
-
/**
|
|
88
|
-
* @param {import("../providers/provider").AbstractProvider|null} provider
|
|
89
|
-
*/
|
|
90
|
-
constructor(provider) {
|
|
91
|
-
this.provider = provider || null;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
async getAddress() {
|
|
95
|
-
throw makeError("getAddress not implemented", "NOT_IMPLEMENTED", {});
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* BaseWallet - core signing implementation.
|
|
101
|
-
*/
|
|
102
|
-
class BaseWallet extends AbstractSigner {
|
|
103
|
-
/**
|
|
104
|
-
* @param {SigningKey} signingKey
|
|
105
|
-
* @param {import("../providers/provider").AbstractProvider|null=} provider
|
|
106
|
-
* @param {{ address: string }=} precomputed
|
|
107
|
-
* @param {any=} qcWallet Internal quantum-coin-js-sdk Wallet (optional)
|
|
108
|
-
*/
|
|
109
|
-
constructor(signingKey, provider, precomputed, qcWallet) {
|
|
110
|
-
super(provider || null);
|
|
111
|
-
_requireInitialized();
|
|
112
|
-
|
|
113
|
-
Object.defineProperty(this, "signingKey", {
|
|
114
|
-
enumerable: false,
|
|
115
|
-
configurable: false,
|
|
116
|
-
writable: false,
|
|
117
|
-
value: signingKey,
|
|
118
|
-
});
|
|
119
|
-
Object.defineProperty(this, "_qcWallet", {
|
|
120
|
-
enumerable: false,
|
|
121
|
-
configurable: true,
|
|
122
|
-
writable: true,
|
|
123
|
-
value: qcWallet || null,
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
/** @type {string} */
|
|
127
|
-
this.address = precomputed?.address || "";
|
|
128
|
-
|
|
129
|
-
Object.defineProperty(this, "privateKey", {
|
|
130
|
-
enumerable: false,
|
|
131
|
-
get: () => bytesToHex(this.signingKey.privateKeyBytes),
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
Object.defineProperty(this, "publicKey", {
|
|
135
|
-
enumerable: true,
|
|
136
|
-
get: () => bytesToHex(this.signingKey.publicKeyBytes),
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
Object.defineProperty(this, "_seed", {
|
|
140
|
-
enumerable: false,
|
|
141
|
-
configurable: true,
|
|
142
|
-
writable: true,
|
|
143
|
-
value: null,
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
Object.defineProperty(this, "seed", {
|
|
147
|
-
enumerable: false,
|
|
148
|
-
get: () => this._seed,
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
toJSON() {
|
|
153
|
-
return { address: this.address };
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
async getAddress() {
|
|
157
|
-
return this.address;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Sign a transaction using quantum-coin-js-sdk signRawTransaction().
|
|
162
|
-
* @param {import("../providers/provider").TransactionRequest} tx
|
|
163
|
-
* @returns {Promise<string>}
|
|
164
|
-
*/
|
|
165
|
-
async signTransaction(tx) {
|
|
166
|
-
_requireInitialized();
|
|
167
|
-
assertArgument(tx && typeof tx === "object", "invalid tx", "tx", tx);
|
|
168
|
-
|
|
169
|
-
const toAddress = tx.to == null ? null : getAddress(tx.to);
|
|
170
|
-
const valueInWei = tx.value == null ? 0n : _getBigInt(tx.value, "tx.value");
|
|
171
|
-
const gasLimit = tx.gasLimit == null ? 21000 : _getNumber(tx.gasLimit, "tx.gasLimit");
|
|
172
|
-
|
|
173
|
-
const data = tx.data == null ? null : normalizeHex(tx.data);
|
|
174
|
-
const remarks = tx.remarks == null ? null : normalizeHex(tx.remarks);
|
|
175
|
-
|
|
176
|
-
if (remarks != null) {
|
|
177
|
-
assertArgument(isHexString(remarks), "remarks must be hex string", "remarks", remarks);
|
|
178
|
-
const remarkBytes = hexToBytes(remarks);
|
|
179
|
-
assertArgument(remarkBytes.length <= 32, "remarks too long (max 32 bytes)", "remarks", remarks);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// Nonce must be provided or resolved from provider.
|
|
183
|
-
let nonce = tx.nonce;
|
|
184
|
-
if (nonce == null) {
|
|
185
|
-
if (!this.provider) throw makeError("missing provider to resolve nonce", "UNKNOWN_ERROR", { operation: "signTransaction" });
|
|
186
|
-
// Prefer pending to avoid nonce collisions with in-flight transactions.
|
|
187
|
-
try {
|
|
188
|
-
nonce = await this.provider.getTransactionCount(this.address, "pending");
|
|
189
|
-
} catch {
|
|
190
|
-
nonce = await this.provider.getTransactionCount(this.address, "latest");
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
assertArgument(Number.isInteger(nonce) && nonce >= 0, "invalid nonce", "nonce", nonce);
|
|
194
|
-
|
|
195
|
-
const chainId = tx.chainId != null ? tx.chainId : (this.provider && this.provider.chainId != null ? this.provider.chainId : null);
|
|
196
|
-
const signingContext = tx.signingContext ?? null;
|
|
197
|
-
|
|
198
|
-
/** @type {any} */
|
|
199
|
-
const qcWallet =
|
|
200
|
-
this._qcWallet ||
|
|
201
|
-
new qcsdk.Wallet(
|
|
202
|
-
this.address,
|
|
203
|
-
_bytesToNumberArray(this.signingKey.privateKeyBytes),
|
|
204
|
-
_bytesToNumberArray(this.signingKey.publicKeyBytes),
|
|
205
|
-
);
|
|
206
|
-
|
|
207
|
-
const req = new qcsdk.TransactionSigningRequest(
|
|
208
|
-
qcWallet,
|
|
209
|
-
toAddress,
|
|
210
|
-
valueInWei,
|
|
211
|
-
nonce,
|
|
212
|
-
data,
|
|
213
|
-
gasLimit,
|
|
214
|
-
remarks,
|
|
215
|
-
chainId,
|
|
216
|
-
signingContext,
|
|
217
|
-
);
|
|
218
|
-
const signResult = qcsdk.signRawTransaction(req);
|
|
219
|
-
// quantum-coin-js-sdk returns a SignResult object: { resultCode, txnHash, txnData }
|
|
220
|
-
if (!signResult || typeof signResult !== "object") {
|
|
221
|
-
throw makeError("signRawTransaction failed", "UNKNOWN_ERROR", {});
|
|
222
|
-
}
|
|
223
|
-
if (typeof signResult.resultCode === "number" && signResult.resultCode !== 0) {
|
|
224
|
-
throw makeError("signRawTransaction failed", "UNKNOWN_ERROR", {
|
|
225
|
-
resultCode: signResult.resultCode,
|
|
226
|
-
hash: signResult.txnHash || null,
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
const raw = signResult.txnData;
|
|
230
|
-
if (typeof raw !== "string") throw makeError("signRawTransaction did not return txnData", "UNKNOWN_ERROR", {});
|
|
231
|
-
return normalizeHex(raw);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Signs and sends a transaction.
|
|
236
|
-
* @param {import("../providers/provider").TransactionRequest} tx
|
|
237
|
-
* @returns {Promise<import("../providers/provider").TransactionResponse>}
|
|
238
|
-
*/
|
|
239
|
-
async sendTransaction(tx) {
|
|
240
|
-
if (!this.provider) throw makeError("missing provider", "UNKNOWN_ERROR", { operation: "sendTransaction" });
|
|
241
|
-
const raw = await this.signTransaction({ ...tx, from: this.address });
|
|
242
|
-
return this.provider.sendTransaction(raw);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Wallet - convenience methods around BaseWallet.
|
|
248
|
-
*/
|
|
249
|
-
class Wallet extends BaseWallet {
|
|
250
|
-
/**
|
|
251
|
-
* @param {string|Uint8Array|SigningKey} key
|
|
252
|
-
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
253
|
-
*/
|
|
254
|
-
constructor(key, provider) {
|
|
255
|
-
_requireInitialized();
|
|
256
|
-
|
|
257
|
-
let signingKey;
|
|
258
|
-
let qcAddress;
|
|
259
|
-
|
|
260
|
-
if (key instanceof SigningKey) {
|
|
261
|
-
signingKey = key;
|
|
262
|
-
// Compute address from public key
|
|
263
|
-
const addr = qcsdk.addressFromPublicKey(_bytesToNumberArray(signingKey.publicKeyBytes));
|
|
264
|
-
if (typeof addr !== "string") throw makeError("addressFromPublicKey failed", "UNKNOWN_ERROR", {});
|
|
265
|
-
qcAddress = normalizeHex(addr);
|
|
266
|
-
} else {
|
|
267
|
-
const privBytes = typeof key === "string" ? hexToBytes(key) : arrayify(key);
|
|
268
|
-
const pubHex = qcsdk.publicKeyFromPrivateKey(_bytesToNumberArray(privBytes));
|
|
269
|
-
if (typeof pubHex !== "string") throw makeError("publicKeyFromPrivateKey failed", "UNKNOWN_ERROR", {});
|
|
270
|
-
const pubBytes = hexToBytes(pubHex);
|
|
271
|
-
const addr = qcsdk.addressFromPublicKey(_bytesToNumberArray(pubBytes));
|
|
272
|
-
if (typeof addr !== "string") throw makeError("addressFromPublicKey failed", "UNKNOWN_ERROR", {});
|
|
273
|
-
qcAddress = normalizeHex(addr);
|
|
274
|
-
signingKey = new SigningKey(privBytes, pubBytes);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/** @type {any} */
|
|
278
|
-
const qcWallet = new qcsdk.Wallet(
|
|
279
|
-
qcAddress,
|
|
280
|
-
_bytesToNumberArray(signingKey.privateKeyBytes),
|
|
281
|
-
_bytesToNumberArray(signingKey.publicKeyBytes),
|
|
282
|
-
);
|
|
283
|
-
|
|
284
|
-
super(signingKey, provider || null, { address: qcAddress }, qcWallet);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
/**
|
|
288
|
-
* Returns wallet address (sync).
|
|
289
|
-
* @returns {string}
|
|
290
|
-
*/
|
|
291
|
-
getAddress() {
|
|
292
|
-
return this.address;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Returns wallet balance.
|
|
297
|
-
* @param {string=} blockTag
|
|
298
|
-
* @returns {Promise<bigint>}
|
|
299
|
-
*/
|
|
300
|
-
async getBalance(blockTag) {
|
|
301
|
-
if (!this.provider) throw makeError("missing provider", "UNKNOWN_ERROR", { operation: "getBalance" });
|
|
302
|
-
void blockTag;
|
|
303
|
-
return this.provider.getBalance(this.address);
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* Returns wallet nonce.
|
|
308
|
-
* @param {string=} blockTag
|
|
309
|
-
* @returns {Promise<number>}
|
|
310
|
-
*/
|
|
311
|
-
async getTransactionCount(blockTag) {
|
|
312
|
-
if (!this.provider) throw makeError("missing provider", "UNKNOWN_ERROR", { operation: "getTransactionCount" });
|
|
313
|
-
return this.provider.getTransactionCount(this.address, blockTag);
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* Encrypts and serializes this wallet to JSON.
|
|
318
|
-
* @param {string|Uint8Array} password
|
|
319
|
-
* @returns {string}
|
|
320
|
-
*/
|
|
321
|
-
encryptSync(password) {
|
|
322
|
-
_requireInitialized();
|
|
323
|
-
if (this._seed != null) {
|
|
324
|
-
return Wallet.encryptSeedSync(hexToBytes(this._seed), password);
|
|
325
|
-
}
|
|
326
|
-
const pw = typeof password === "string"
|
|
327
|
-
? password.normalize("NFC")
|
|
328
|
-
: Buffer.from(arrayify(password)).toString("utf8").normalize("NFC");
|
|
329
|
-
assertSecretArgument(pw.length >= 12, "password must be at least 12 characters", "password");
|
|
330
|
-
const json = qcsdk.serializeEncryptedWallet(this._qcWallet, pw);
|
|
331
|
-
if (typeof json !== "string") throw makeError("serializeEncryptedWallet failed", "UNKNOWN_ERROR", {});
|
|
332
|
-
return json;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
/**
|
|
336
|
-
* Encrypts raw seed bytes into a wallet JSON string (version 5 pre-expansion format).
|
|
337
|
-
* The resulting JSON can be opened with `Wallet.fromEncryptedJsonSync()` or
|
|
338
|
-
* Desktop/Mobile/Web/CLI wallet applications.
|
|
339
|
-
* @param {number[]|Uint8Array} seed Raw seed bytes: 64 (keyType 3), 72 (keyType 5), or 96 (legacy)
|
|
340
|
-
* @param {string|Uint8Array} password Passphrase (at least 12 characters)
|
|
341
|
-
* @returns {string}
|
|
342
|
-
*/
|
|
343
|
-
static encryptSeedSync(seed, password) {
|
|
344
|
-
_requireInitialized();
|
|
345
|
-
const seedArr = seed instanceof Uint8Array ? Array.from(seed) : seed;
|
|
346
|
-
assertArgument(Array.isArray(seedArr), "seed must be an array of numbers or Uint8Array", "seed", seed);
|
|
347
|
-
const allowedLengths = [64, 72, 96];
|
|
348
|
-
assertArgument(allowedLengths.includes(seedArr.length), "seed must be 64, 72, or 96 bytes", "seed", seedArr.length);
|
|
349
|
-
const pw = typeof password === "string"
|
|
350
|
-
? password.normalize("NFC")
|
|
351
|
-
: Buffer.from(arrayify(password)).toString("utf8").normalize("NFC");
|
|
352
|
-
assertSecretArgument(pw.length >= 12, "password must be at least 12 characters", "password");
|
|
353
|
-
const json = qcsdk.serializeSeedAsEncryptedWallet(seedArr, pw);
|
|
354
|
-
if (typeof json !== "string") throw makeError("serializeSeedAsEncryptedWallet failed", "UNKNOWN_ERROR", {});
|
|
355
|
-
return json;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* Returns the seed phrase (list of words) if this wallet has a seed, else null.
|
|
360
|
-
* Derived from the stored pre-expansion seed via seed-words.getWordListFromSeedArray.
|
|
361
|
-
*
|
|
362
|
-
* Non-null for wallets created via createRandom, fromPhrase, fromSeed, and
|
|
363
|
-
* fromEncryptedJsonSync when the JSON is a version-5 keystore produced by
|
|
364
|
-
* encryptSync on a seed-bearing wallet or by encryptSeedSync.
|
|
365
|
-
* Null for fromKeys and for v3/v4 keystores without preExpansionSeed.
|
|
366
|
-
*
|
|
367
|
-
* @returns {string[]|null}
|
|
368
|
-
*/
|
|
369
|
-
getPhrase() {
|
|
370
|
-
_requireInitialized();
|
|
371
|
-
if (this._seed == null) return null;
|
|
372
|
-
const bytes = Array.from(hexToBytes(this._seed));
|
|
373
|
-
const words = seedWords.getWordListFromSeedArray(bytes);
|
|
374
|
-
return Array.isArray(words) ? words : null;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
/**
|
|
378
|
-
* Returns the recommended signing context for this wallet.
|
|
379
|
-
* Setting fullSign to true may incur additional gas cost.
|
|
380
|
-
* @param {boolean|null=} fullSign Defaults to false when null or omitted.
|
|
381
|
-
* @returns {number}
|
|
382
|
-
*/
|
|
383
|
-
getSigningContext(fullSign) {
|
|
384
|
-
const fs = fullSign ?? false;
|
|
385
|
-
const pubLen = this.signingKey.publicKeyBytes.length;
|
|
386
|
-
if (pubLen === 1408) {
|
|
387
|
-
return fs ? 2 : 0;
|
|
388
|
-
}
|
|
389
|
-
if (pubLen === 2688) {
|
|
390
|
-
return 1;
|
|
391
|
-
}
|
|
392
|
-
throw makeError("unsupported public key size", "UNSUPPORTED_OPERATION", { publicKeyLength: pubLen });
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
/**
|
|
396
|
-
* Returns a new wallet connected to a provider.
|
|
397
|
-
* @param {import("../providers/provider").AbstractProvider} provider
|
|
398
|
-
* @returns {Wallet}
|
|
399
|
-
*/
|
|
400
|
-
connect(provider) {
|
|
401
|
-
const w = new Wallet(this.signingKey, provider);
|
|
402
|
-
w._qcWallet = this._qcWallet;
|
|
403
|
-
w._seed = this._seed;
|
|
404
|
-
return w;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
/**
|
|
408
|
-
* Creates a new random wallet.
|
|
409
|
-
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
410
|
-
* @param {number|null=} keyType Optional key type: null (default=3), 3, or 5
|
|
411
|
-
* @returns {Wallet}
|
|
412
|
-
*/
|
|
413
|
-
static createRandom(provider, keyType) {
|
|
414
|
-
_requireInitialized();
|
|
415
|
-
if (keyType != null) {
|
|
416
|
-
assertArgument(keyType === 3 || keyType === 5, "keyType must be null, 3, or 5", "keyType", keyType);
|
|
417
|
-
}
|
|
418
|
-
const words = qcsdk.newWalletSeedWords(keyType ?? null);
|
|
419
|
-
if (!words || !Array.isArray(words)) {
|
|
420
|
-
throw makeError("newWalletSeedWords failed", "UNKNOWN_ERROR", { result: words });
|
|
421
|
-
}
|
|
422
|
-
return Wallet.fromPhrase(words, provider);
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
/**
|
|
426
|
-
* Creates a wallet from raw seed bytes.
|
|
427
|
-
* @param {number[]} seed Raw seed bytes: 64 (keyType 3), 72 (keyType 5), or 96 (legacy)
|
|
428
|
-
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
429
|
-
* @returns {Wallet}
|
|
430
|
-
*/
|
|
431
|
-
static fromSeed(seed, provider) {
|
|
432
|
-
_requireInitialized();
|
|
433
|
-
assertArgument(Array.isArray(seed), "seed must be an array of numbers", "seed", seed);
|
|
434
|
-
const allowedLengths = [64, 72, 96];
|
|
435
|
-
assertArgument(allowedLengths.includes(seed.length), "seed must be 64, 72, or 96 bytes", "seed", seed.length);
|
|
436
|
-
const qcWallet = qcsdk.openWalletFromSeed(seed);
|
|
437
|
-
if (!qcWallet || typeof qcWallet === "number") {
|
|
438
|
-
throw makeError("openWalletFromSeed failed", "UNKNOWN_ERROR", { result: qcWallet });
|
|
439
|
-
}
|
|
440
|
-
return Wallet._fromQcWallet(qcWallet, provider || null);
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
/**
|
|
444
|
-
* Creates a wallet from an encrypted JSON string.
|
|
445
|
-
* @param {string} json
|
|
446
|
-
* @param {string} password
|
|
447
|
-
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
448
|
-
* @returns {Wallet}
|
|
449
|
-
*/
|
|
450
|
-
static fromEncryptedJsonSync(json, password, provider) {
|
|
451
|
-
_requireInitialized();
|
|
452
|
-
const qcWallet = qcsdk.deserializeEncryptedWallet(json, password);
|
|
453
|
-
if (!qcWallet) throw makeError("deserializeEncryptedWallet failed", "UNKNOWN_ERROR", {});
|
|
454
|
-
return Wallet._fromQcWallet(qcWallet, provider || null);
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
/**
|
|
458
|
-
* Creates a wallet from a seed phrase (32, 36, or 48 words).
|
|
459
|
-
* @param {string|string[]} phrase
|
|
460
|
-
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
461
|
-
* @returns {Wallet}
|
|
462
|
-
*/
|
|
463
|
-
static fromPhrase(phrase, provider) {
|
|
464
|
-
_requireInitialized();
|
|
465
|
-
let words = phrase;
|
|
466
|
-
if (typeof phrase === "string") {
|
|
467
|
-
words = phrase
|
|
468
|
-
.split(/[,\s]+/g)
|
|
469
|
-
.map((w) => w.trim())
|
|
470
|
-
.filter(Boolean);
|
|
471
|
-
}
|
|
472
|
-
assertArgument(Array.isArray(words), "phrase must be a string or string[]", "phrase", phrase);
|
|
473
|
-
const allowedLengths = [32, 36, 48];
|
|
474
|
-
assertArgument(
|
|
475
|
-
allowedLengths.includes(words.length),
|
|
476
|
-
"seed phrase must contain 32, 36, or 48 words",
|
|
477
|
-
"phrase",
|
|
478
|
-
words.length,
|
|
479
|
-
);
|
|
480
|
-
const qcWallet = qcsdk.openWalletFromSeedWords(words);
|
|
481
|
-
if (!qcWallet) throw makeError("openWalletFromSeedWords failed", "UNKNOWN_ERROR", {});
|
|
482
|
-
return Wallet._fromQcWallet(qcWallet, provider || null);
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
/**
|
|
486
|
-
* Creates a wallet from raw private and public key bytes.
|
|
487
|
-
* @param {Uint8Array|string} privateKey Private key bytes or hex string
|
|
488
|
-
* @param {Uint8Array|string} publicKey Public key bytes or hex string
|
|
489
|
-
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
490
|
-
* @returns {Wallet}
|
|
491
|
-
*/
|
|
492
|
-
static fromKeys(privateKey, publicKey, provider) {
|
|
493
|
-
_requireInitialized();
|
|
494
|
-
const privBytes = typeof privateKey === "string" ? hexToBytes(privateKey) : arrayify(privateKey);
|
|
495
|
-
const pubBytes = typeof publicKey === "string" ? hexToBytes(publicKey) : arrayify(publicKey);
|
|
496
|
-
assertSecretArgument(privBytes.length > 0, "privateKey must not be empty", "privateKey");
|
|
497
|
-
assertSecretArgument(pubBytes.length > 0, "publicKey must not be empty", "publicKey");
|
|
498
|
-
|
|
499
|
-
const privArr = _bytesToNumberArray(privBytes);
|
|
500
|
-
const pubArr = _bytesToNumberArray(pubBytes);
|
|
501
|
-
const addr = qcsdk.addressFromPublicKey(pubArr);
|
|
502
|
-
if (typeof addr !== "string") throw makeError("addressFromPublicKey failed", "UNKNOWN_ERROR", {});
|
|
503
|
-
|
|
504
|
-
const qcWallet = new qcsdk.Wallet(addr, privArr, pubArr);
|
|
505
|
-
const verified = qcsdk.verifyWallet(qcWallet);
|
|
506
|
-
if (verified !== true) {
|
|
507
|
-
throw makeError("verifyWallet failed: the provided key pair is invalid", "INVALID_ARGUMENT", { verified });
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
return Wallet._fromQcWallet(qcWallet, provider || null);
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
/**
|
|
514
|
-
* Internal helper: build a Wallet from a quantum-coin-js-sdk Wallet object.
|
|
515
|
-
* @param {any} qcWallet
|
|
516
|
-
* @param {import("../providers/provider").AbstractProvider|null} provider
|
|
517
|
-
* @returns {Wallet}
|
|
518
|
-
*/
|
|
519
|
-
static _fromQcWallet(qcWallet, provider) {
|
|
520
|
-
const privSrc = qcWallet.privateKey;
|
|
521
|
-
const pubSrc = qcWallet.publicKey;
|
|
522
|
-
|
|
523
|
-
if (!privSrc || (privSrc instanceof Uint8Array && privSrc.length === 0) || (Array.isArray(privSrc) && privSrc.length === 0)) {
|
|
524
|
-
throw makeError("qcWallet.privateKey is empty or missing", "UNKNOWN_ERROR", {});
|
|
525
|
-
}
|
|
526
|
-
if (!pubSrc || (pubSrc instanceof Uint8Array && pubSrc.length === 0) || (Array.isArray(pubSrc) && pubSrc.length === 0)) {
|
|
527
|
-
throw makeError("qcWallet.publicKey is empty or missing", "UNKNOWN_ERROR", {});
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
const privBytes =
|
|
531
|
-
privSrc instanceof Uint8Array ? new Uint8Array(privSrc) : Uint8Array.from(Array.from(privSrc).map((n) => (Number(n) & 0xff)));
|
|
532
|
-
const pubBytes =
|
|
533
|
-
pubSrc instanceof Uint8Array ? new Uint8Array(pubSrc) : Uint8Array.from(Array.from(pubSrc).map((n) => (Number(n) & 0xff)));
|
|
534
|
-
const key = new SigningKey(privBytes, pubBytes);
|
|
535
|
-
|
|
536
|
-
const w = new Wallet(key, provider || null);
|
|
537
|
-
// Ensure we keep the exact underlying qcWallet for operations like encrypt/signRawTransaction.
|
|
538
|
-
w._qcWallet = qcWallet;
|
|
539
|
-
if (typeof qcWallet.address === "string") {
|
|
540
|
-
w.address = normalizeHex(qcWallet.address);
|
|
541
|
-
}
|
|
542
|
-
if (qcWallet.preExpansionSeed != null) {
|
|
543
|
-
const seedSrc = qcWallet.preExpansionSeed;
|
|
544
|
-
const seedBytes =
|
|
545
|
-
seedSrc instanceof Uint8Array ? seedSrc : Uint8Array.from(Array.from(seedSrc).map((n) => (Number(n) & 0xff)));
|
|
546
|
-
w._seed = bytesToHex(seedBytes);
|
|
547
|
-
}
|
|
548
|
-
return w;
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
/**
|
|
553
|
-
* NonceManager wrapper.
|
|
554
|
-
*/
|
|
555
|
-
class NonceManager extends AbstractSigner {
|
|
556
|
-
/**
|
|
557
|
-
* @param {AbstractSigner} signer
|
|
558
|
-
*/
|
|
559
|
-
constructor(signer) {
|
|
560
|
-
super(signer.provider || null);
|
|
561
|
-
this.signer = signer;
|
|
562
|
-
this._nonce = null;
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
async getAddress() {
|
|
566
|
-
return this.signer.getAddress();
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
async getTransactionCount(blockTag) {
|
|
570
|
-
if (this._nonce != null) return this._nonce;
|
|
571
|
-
if (!this.provider) throw makeError("missing provider", "UNKNOWN_ERROR", { operation: "getTransactionCount" });
|
|
572
|
-
const address = await this.getAddress();
|
|
573
|
-
this._nonce = await this.provider.getTransactionCount(address, blockTag);
|
|
574
|
-
return this._nonce;
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
async sendTransaction(tx) {
|
|
578
|
-
const nonce = await this.getTransactionCount("latest");
|
|
579
|
-
const result = await this.signer.sendTransaction({ ...tx, nonce });
|
|
580
|
-
this._nonce = nonce + 1;
|
|
581
|
-
return result;
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
reset() {
|
|
585
|
-
this._nonce = null;
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
increment() {
|
|
589
|
-
if (this._nonce == null) this._nonce = 0;
|
|
590
|
-
this._nonce++;
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
/**
|
|
595
|
-
* JsonRpcSigner placeholder (ethers-like).
|
|
596
|
-
* This SDK encourages using Wallet directly for signing.
|
|
597
|
-
*/
|
|
598
|
-
class JsonRpcSigner extends AbstractSigner {
|
|
599
|
-
constructor(provider, address) {
|
|
600
|
-
super(provider);
|
|
601
|
-
this._address = address;
|
|
602
|
-
}
|
|
603
|
-
async getAddress() {
|
|
604
|
-
return this._address;
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
/**
|
|
609
|
-
* VoidSigner (cannot sign, only provides address).
|
|
610
|
-
*/
|
|
611
|
-
class VoidSigner extends AbstractSigner {
|
|
612
|
-
constructor(address, provider) {
|
|
613
|
-
super(provider || null);
|
|
614
|
-
this._address = getAddress(address);
|
|
615
|
-
}
|
|
616
|
-
async getAddress() {
|
|
617
|
-
return this._address;
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
module.exports = {
|
|
622
|
-
SigningKey,
|
|
623
|
-
AbstractSigner,
|
|
624
|
-
BaseWallet,
|
|
625
|
-
Wallet,
|
|
626
|
-
NonceManager,
|
|
627
|
-
JsonRpcSigner,
|
|
628
|
-
VoidSigner,
|
|
629
|
-
};
|
|
630
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Wallet and signer implementations.
|
|
3
|
+
*
|
|
4
|
+
* The QuantumCoin.js wallet model mirrors ethers.js v6:
|
|
5
|
+
* - AbstractSigner -> BaseWallet -> Wallet
|
|
6
|
+
* - NonceManager wrapper
|
|
7
|
+
*
|
|
8
|
+
* Cryptographic operations are delegated to `quantum-coin-js-sdk`.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const qcsdk = require("quantum-coin-js-sdk");
|
|
12
|
+
const seedWords = require("seed-words");
|
|
13
|
+
const { JsonRpcProvider } = require("../providers/json-rpc-provider");
|
|
14
|
+
const { assertArgument, assertSecretArgument, makeError } = require("../errors");
|
|
15
|
+
const { arrayify, bytesToHex, hexToBytes, isHexString, normalizeHex } = require("../internal/hex");
|
|
16
|
+
const { getAddress } = require("../utils/address");
|
|
17
|
+
const { WeiPerEther } = require("../constants");
|
|
18
|
+
|
|
19
|
+
function _requireInitialized() {
|
|
20
|
+
// eslint-disable-next-line global-require
|
|
21
|
+
const { isInitialized, getInitializationPromise } = require("../../config");
|
|
22
|
+
if (isInitialized()) return;
|
|
23
|
+
if (getInitializationPromise() != null) {
|
|
24
|
+
throw makeError(
|
|
25
|
+
"QuantumCoin SDK is still initializing. Await the Initialize() promise before using SDK methods.",
|
|
26
|
+
"UNKNOWN_ERROR",
|
|
27
|
+
{ operation: "requireInitialized" },
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
throw makeError("QuantumCoin SDK not initialized. Call Initialize() first.", "UNKNOWN_ERROR", { operation: "wallet" });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function _bytesToNumberArray(bytes) {
|
|
34
|
+
return Array.from(bytes);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const _maxSafeInt = 0x1fffffffffffffn; // 2^53 - 1
|
|
38
|
+
|
|
39
|
+
function _getBigInt(value, name) {
|
|
40
|
+
if (typeof value === "bigint") return value;
|
|
41
|
+
if (typeof value === "number") {
|
|
42
|
+
assertArgument(Number.isInteger(value), "underflow", name, value);
|
|
43
|
+
assertArgument(value >= -Number(_maxSafeInt) && value <= Number(_maxSafeInt), "overflow", name, value);
|
|
44
|
+
return BigInt(value);
|
|
45
|
+
}
|
|
46
|
+
if (typeof value === "string") {
|
|
47
|
+
if (value === "0x" || value === "0X") return 0n;
|
|
48
|
+
try { return BigInt(value); }
|
|
49
|
+
catch { assertArgument(false, "invalid BigNumberish string", name, value); }
|
|
50
|
+
}
|
|
51
|
+
assertArgument(false, "invalid BigNumberish", name, value);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function _getNumber(value, name) {
|
|
55
|
+
const bi = _getBigInt(value, name);
|
|
56
|
+
assertArgument(bi >= -_maxSafeInt && bi <= _maxSafeInt, "overflow", name, value);
|
|
57
|
+
return Number(bi);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* SigningKey wrapper (PQC private/public key bytes).
|
|
62
|
+
*/
|
|
63
|
+
class SigningKey {
|
|
64
|
+
/**
|
|
65
|
+
* @param {Uint8Array} privateKeyBytes
|
|
66
|
+
* @param {Uint8Array} publicKeyBytes
|
|
67
|
+
*/
|
|
68
|
+
constructor(privateKeyBytes, publicKeyBytes) {
|
|
69
|
+
Object.defineProperty(this, "privateKeyBytes", {
|
|
70
|
+
enumerable: false,
|
|
71
|
+
configurable: false,
|
|
72
|
+
writable: false,
|
|
73
|
+
value: new Uint8Array(privateKeyBytes),
|
|
74
|
+
});
|
|
75
|
+
this.publicKeyBytes = new Uint8Array(publicKeyBytes);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
toJSON() {
|
|
79
|
+
return {};
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* AbstractSigner base (minimal).
|
|
85
|
+
*/
|
|
86
|
+
class AbstractSigner {
|
|
87
|
+
/**
|
|
88
|
+
* @param {import("../providers/provider").AbstractProvider|null} provider
|
|
89
|
+
*/
|
|
90
|
+
constructor(provider) {
|
|
91
|
+
this.provider = provider || null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async getAddress() {
|
|
95
|
+
throw makeError("getAddress not implemented", "NOT_IMPLEMENTED", {});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* BaseWallet - core signing implementation.
|
|
101
|
+
*/
|
|
102
|
+
class BaseWallet extends AbstractSigner {
|
|
103
|
+
/**
|
|
104
|
+
* @param {SigningKey} signingKey
|
|
105
|
+
* @param {import("../providers/provider").AbstractProvider|null=} provider
|
|
106
|
+
* @param {{ address: string }=} precomputed
|
|
107
|
+
* @param {any=} qcWallet Internal quantum-coin-js-sdk Wallet (optional)
|
|
108
|
+
*/
|
|
109
|
+
constructor(signingKey, provider, precomputed, qcWallet) {
|
|
110
|
+
super(provider || null);
|
|
111
|
+
_requireInitialized();
|
|
112
|
+
|
|
113
|
+
Object.defineProperty(this, "signingKey", {
|
|
114
|
+
enumerable: false,
|
|
115
|
+
configurable: false,
|
|
116
|
+
writable: false,
|
|
117
|
+
value: signingKey,
|
|
118
|
+
});
|
|
119
|
+
Object.defineProperty(this, "_qcWallet", {
|
|
120
|
+
enumerable: false,
|
|
121
|
+
configurable: true,
|
|
122
|
+
writable: true,
|
|
123
|
+
value: qcWallet || null,
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
/** @type {string} */
|
|
127
|
+
this.address = precomputed?.address || "";
|
|
128
|
+
|
|
129
|
+
Object.defineProperty(this, "privateKey", {
|
|
130
|
+
enumerable: false,
|
|
131
|
+
get: () => bytesToHex(this.signingKey.privateKeyBytes),
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
Object.defineProperty(this, "publicKey", {
|
|
135
|
+
enumerable: true,
|
|
136
|
+
get: () => bytesToHex(this.signingKey.publicKeyBytes),
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
Object.defineProperty(this, "_seed", {
|
|
140
|
+
enumerable: false,
|
|
141
|
+
configurable: true,
|
|
142
|
+
writable: true,
|
|
143
|
+
value: null,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
Object.defineProperty(this, "seed", {
|
|
147
|
+
enumerable: false,
|
|
148
|
+
get: () => this._seed,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
toJSON() {
|
|
153
|
+
return { address: this.address };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async getAddress() {
|
|
157
|
+
return this.address;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Sign a transaction using quantum-coin-js-sdk signRawTransaction().
|
|
162
|
+
* @param {import("../providers/provider").TransactionRequest} tx
|
|
163
|
+
* @returns {Promise<string>}
|
|
164
|
+
*/
|
|
165
|
+
async signTransaction(tx) {
|
|
166
|
+
_requireInitialized();
|
|
167
|
+
assertArgument(tx && typeof tx === "object", "invalid tx", "tx", tx);
|
|
168
|
+
|
|
169
|
+
const toAddress = tx.to == null ? null : getAddress(tx.to);
|
|
170
|
+
const valueInWei = tx.value == null ? 0n : _getBigInt(tx.value, "tx.value");
|
|
171
|
+
const gasLimit = tx.gasLimit == null ? 21000 : _getNumber(tx.gasLimit, "tx.gasLimit");
|
|
172
|
+
|
|
173
|
+
const data = tx.data == null ? null : normalizeHex(tx.data);
|
|
174
|
+
const remarks = tx.remarks == null ? null : normalizeHex(tx.remarks);
|
|
175
|
+
|
|
176
|
+
if (remarks != null) {
|
|
177
|
+
assertArgument(isHexString(remarks), "remarks must be hex string", "remarks", remarks);
|
|
178
|
+
const remarkBytes = hexToBytes(remarks);
|
|
179
|
+
assertArgument(remarkBytes.length <= 32, "remarks too long (max 32 bytes)", "remarks", remarks);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Nonce must be provided or resolved from provider.
|
|
183
|
+
let nonce = tx.nonce;
|
|
184
|
+
if (nonce == null) {
|
|
185
|
+
if (!this.provider) throw makeError("missing provider to resolve nonce", "UNKNOWN_ERROR", { operation: "signTransaction" });
|
|
186
|
+
// Prefer pending to avoid nonce collisions with in-flight transactions.
|
|
187
|
+
try {
|
|
188
|
+
nonce = await this.provider.getTransactionCount(this.address, "pending");
|
|
189
|
+
} catch {
|
|
190
|
+
nonce = await this.provider.getTransactionCount(this.address, "latest");
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
assertArgument(Number.isInteger(nonce) && nonce >= 0, "invalid nonce", "nonce", nonce);
|
|
194
|
+
|
|
195
|
+
const chainId = tx.chainId != null ? tx.chainId : (this.provider && this.provider.chainId != null ? this.provider.chainId : null);
|
|
196
|
+
const signingContext = tx.signingContext ?? null;
|
|
197
|
+
|
|
198
|
+
/** @type {any} */
|
|
199
|
+
const qcWallet =
|
|
200
|
+
this._qcWallet ||
|
|
201
|
+
new qcsdk.Wallet(
|
|
202
|
+
this.address,
|
|
203
|
+
_bytesToNumberArray(this.signingKey.privateKeyBytes),
|
|
204
|
+
_bytesToNumberArray(this.signingKey.publicKeyBytes),
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
const req = new qcsdk.TransactionSigningRequest(
|
|
208
|
+
qcWallet,
|
|
209
|
+
toAddress,
|
|
210
|
+
valueInWei,
|
|
211
|
+
nonce,
|
|
212
|
+
data,
|
|
213
|
+
gasLimit,
|
|
214
|
+
remarks,
|
|
215
|
+
chainId,
|
|
216
|
+
signingContext,
|
|
217
|
+
);
|
|
218
|
+
const signResult = qcsdk.signRawTransaction(req);
|
|
219
|
+
// quantum-coin-js-sdk returns a SignResult object: { resultCode, txnHash, txnData }
|
|
220
|
+
if (!signResult || typeof signResult !== "object") {
|
|
221
|
+
throw makeError("signRawTransaction failed", "UNKNOWN_ERROR", {});
|
|
222
|
+
}
|
|
223
|
+
if (typeof signResult.resultCode === "number" && signResult.resultCode !== 0) {
|
|
224
|
+
throw makeError("signRawTransaction failed", "UNKNOWN_ERROR", {
|
|
225
|
+
resultCode: signResult.resultCode,
|
|
226
|
+
hash: signResult.txnHash || null,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
const raw = signResult.txnData;
|
|
230
|
+
if (typeof raw !== "string") throw makeError("signRawTransaction did not return txnData", "UNKNOWN_ERROR", {});
|
|
231
|
+
return normalizeHex(raw);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Signs and sends a transaction.
|
|
236
|
+
* @param {import("../providers/provider").TransactionRequest} tx
|
|
237
|
+
* @returns {Promise<import("../providers/provider").TransactionResponse>}
|
|
238
|
+
*/
|
|
239
|
+
async sendTransaction(tx) {
|
|
240
|
+
if (!this.provider) throw makeError("missing provider", "UNKNOWN_ERROR", { operation: "sendTransaction" });
|
|
241
|
+
const raw = await this.signTransaction({ ...tx, from: this.address });
|
|
242
|
+
return this.provider.sendTransaction(raw);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Wallet - convenience methods around BaseWallet.
|
|
248
|
+
*/
|
|
249
|
+
class Wallet extends BaseWallet {
|
|
250
|
+
/**
|
|
251
|
+
* @param {string|Uint8Array|SigningKey} key
|
|
252
|
+
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
253
|
+
*/
|
|
254
|
+
constructor(key, provider) {
|
|
255
|
+
_requireInitialized();
|
|
256
|
+
|
|
257
|
+
let signingKey;
|
|
258
|
+
let qcAddress;
|
|
259
|
+
|
|
260
|
+
if (key instanceof SigningKey) {
|
|
261
|
+
signingKey = key;
|
|
262
|
+
// Compute address from public key
|
|
263
|
+
const addr = qcsdk.addressFromPublicKey(_bytesToNumberArray(signingKey.publicKeyBytes));
|
|
264
|
+
if (typeof addr !== "string") throw makeError("addressFromPublicKey failed", "UNKNOWN_ERROR", {});
|
|
265
|
+
qcAddress = normalizeHex(addr);
|
|
266
|
+
} else {
|
|
267
|
+
const privBytes = typeof key === "string" ? hexToBytes(key) : arrayify(key);
|
|
268
|
+
const pubHex = qcsdk.publicKeyFromPrivateKey(_bytesToNumberArray(privBytes));
|
|
269
|
+
if (typeof pubHex !== "string") throw makeError("publicKeyFromPrivateKey failed", "UNKNOWN_ERROR", {});
|
|
270
|
+
const pubBytes = hexToBytes(pubHex);
|
|
271
|
+
const addr = qcsdk.addressFromPublicKey(_bytesToNumberArray(pubBytes));
|
|
272
|
+
if (typeof addr !== "string") throw makeError("addressFromPublicKey failed", "UNKNOWN_ERROR", {});
|
|
273
|
+
qcAddress = normalizeHex(addr);
|
|
274
|
+
signingKey = new SigningKey(privBytes, pubBytes);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/** @type {any} */
|
|
278
|
+
const qcWallet = new qcsdk.Wallet(
|
|
279
|
+
qcAddress,
|
|
280
|
+
_bytesToNumberArray(signingKey.privateKeyBytes),
|
|
281
|
+
_bytesToNumberArray(signingKey.publicKeyBytes),
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
super(signingKey, provider || null, { address: qcAddress }, qcWallet);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Returns wallet address (sync).
|
|
289
|
+
* @returns {string}
|
|
290
|
+
*/
|
|
291
|
+
getAddress() {
|
|
292
|
+
return this.address;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Returns wallet balance.
|
|
297
|
+
* @param {string=} blockTag
|
|
298
|
+
* @returns {Promise<bigint>}
|
|
299
|
+
*/
|
|
300
|
+
async getBalance(blockTag) {
|
|
301
|
+
if (!this.provider) throw makeError("missing provider", "UNKNOWN_ERROR", { operation: "getBalance" });
|
|
302
|
+
void blockTag;
|
|
303
|
+
return this.provider.getBalance(this.address);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Returns wallet nonce.
|
|
308
|
+
* @param {string=} blockTag
|
|
309
|
+
* @returns {Promise<number>}
|
|
310
|
+
*/
|
|
311
|
+
async getTransactionCount(blockTag) {
|
|
312
|
+
if (!this.provider) throw makeError("missing provider", "UNKNOWN_ERROR", { operation: "getTransactionCount" });
|
|
313
|
+
return this.provider.getTransactionCount(this.address, blockTag);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Encrypts and serializes this wallet to JSON.
|
|
318
|
+
* @param {string|Uint8Array} password
|
|
319
|
+
* @returns {string}
|
|
320
|
+
*/
|
|
321
|
+
encryptSync(password) {
|
|
322
|
+
_requireInitialized();
|
|
323
|
+
if (this._seed != null) {
|
|
324
|
+
return Wallet.encryptSeedSync(hexToBytes(this._seed), password);
|
|
325
|
+
}
|
|
326
|
+
const pw = typeof password === "string"
|
|
327
|
+
? password.normalize("NFC")
|
|
328
|
+
: Buffer.from(arrayify(password)).toString("utf8").normalize("NFC");
|
|
329
|
+
assertSecretArgument(pw.length >= 12, "password must be at least 12 characters", "password");
|
|
330
|
+
const json = qcsdk.serializeEncryptedWallet(this._qcWallet, pw);
|
|
331
|
+
if (typeof json !== "string") throw makeError("serializeEncryptedWallet failed", "UNKNOWN_ERROR", {});
|
|
332
|
+
return json;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Encrypts raw seed bytes into a wallet JSON string (version 5 pre-expansion format).
|
|
337
|
+
* The resulting JSON can be opened with `Wallet.fromEncryptedJsonSync()` or
|
|
338
|
+
* Desktop/Mobile/Web/CLI wallet applications.
|
|
339
|
+
* @param {number[]|Uint8Array} seed Raw seed bytes: 64 (keyType 3), 72 (keyType 5), or 96 (legacy)
|
|
340
|
+
* @param {string|Uint8Array} password Passphrase (at least 12 characters)
|
|
341
|
+
* @returns {string}
|
|
342
|
+
*/
|
|
343
|
+
static encryptSeedSync(seed, password) {
|
|
344
|
+
_requireInitialized();
|
|
345
|
+
const seedArr = seed instanceof Uint8Array ? Array.from(seed) : seed;
|
|
346
|
+
assertArgument(Array.isArray(seedArr), "seed must be an array of numbers or Uint8Array", "seed", seed);
|
|
347
|
+
const allowedLengths = [64, 72, 96];
|
|
348
|
+
assertArgument(allowedLengths.includes(seedArr.length), "seed must be 64, 72, or 96 bytes", "seed", seedArr.length);
|
|
349
|
+
const pw = typeof password === "string"
|
|
350
|
+
? password.normalize("NFC")
|
|
351
|
+
: Buffer.from(arrayify(password)).toString("utf8").normalize("NFC");
|
|
352
|
+
assertSecretArgument(pw.length >= 12, "password must be at least 12 characters", "password");
|
|
353
|
+
const json = qcsdk.serializeSeedAsEncryptedWallet(seedArr, pw);
|
|
354
|
+
if (typeof json !== "string") throw makeError("serializeSeedAsEncryptedWallet failed", "UNKNOWN_ERROR", {});
|
|
355
|
+
return json;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Returns the seed phrase (list of words) if this wallet has a seed, else null.
|
|
360
|
+
* Derived from the stored pre-expansion seed via seed-words.getWordListFromSeedArray.
|
|
361
|
+
*
|
|
362
|
+
* Non-null for wallets created via createRandom, fromPhrase, fromSeed, and
|
|
363
|
+
* fromEncryptedJsonSync when the JSON is a version-5 keystore produced by
|
|
364
|
+
* encryptSync on a seed-bearing wallet or by encryptSeedSync.
|
|
365
|
+
* Null for fromKeys and for v3/v4 keystores without preExpansionSeed.
|
|
366
|
+
*
|
|
367
|
+
* @returns {string[]|null}
|
|
368
|
+
*/
|
|
369
|
+
getPhrase() {
|
|
370
|
+
_requireInitialized();
|
|
371
|
+
if (this._seed == null) return null;
|
|
372
|
+
const bytes = Array.from(hexToBytes(this._seed));
|
|
373
|
+
const words = seedWords.getWordListFromSeedArray(bytes);
|
|
374
|
+
return Array.isArray(words) ? words : null;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Returns the recommended signing context for this wallet.
|
|
379
|
+
* Setting fullSign to true may incur additional gas cost.
|
|
380
|
+
* @param {boolean|null=} fullSign Defaults to false when null or omitted.
|
|
381
|
+
* @returns {number}
|
|
382
|
+
*/
|
|
383
|
+
getSigningContext(fullSign) {
|
|
384
|
+
const fs = fullSign ?? false;
|
|
385
|
+
const pubLen = this.signingKey.publicKeyBytes.length;
|
|
386
|
+
if (pubLen === 1408) {
|
|
387
|
+
return fs ? 2 : 0;
|
|
388
|
+
}
|
|
389
|
+
if (pubLen === 2688) {
|
|
390
|
+
return 1;
|
|
391
|
+
}
|
|
392
|
+
throw makeError("unsupported public key size", "UNSUPPORTED_OPERATION", { publicKeyLength: pubLen });
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Returns a new wallet connected to a provider.
|
|
397
|
+
* @param {import("../providers/provider").AbstractProvider} provider
|
|
398
|
+
* @returns {Wallet}
|
|
399
|
+
*/
|
|
400
|
+
connect(provider) {
|
|
401
|
+
const w = new Wallet(this.signingKey, provider);
|
|
402
|
+
w._qcWallet = this._qcWallet;
|
|
403
|
+
w._seed = this._seed;
|
|
404
|
+
return w;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Creates a new random wallet.
|
|
409
|
+
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
410
|
+
* @param {number|null=} keyType Optional key type: null (default=3), 3, or 5
|
|
411
|
+
* @returns {Wallet}
|
|
412
|
+
*/
|
|
413
|
+
static createRandom(provider, keyType) {
|
|
414
|
+
_requireInitialized();
|
|
415
|
+
if (keyType != null) {
|
|
416
|
+
assertArgument(keyType === 3 || keyType === 5, "keyType must be null, 3, or 5", "keyType", keyType);
|
|
417
|
+
}
|
|
418
|
+
const words = qcsdk.newWalletSeedWords(keyType ?? null);
|
|
419
|
+
if (!words || !Array.isArray(words)) {
|
|
420
|
+
throw makeError("newWalletSeedWords failed", "UNKNOWN_ERROR", { result: words });
|
|
421
|
+
}
|
|
422
|
+
return Wallet.fromPhrase(words, provider);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Creates a wallet from raw seed bytes.
|
|
427
|
+
* @param {number[]} seed Raw seed bytes: 64 (keyType 3), 72 (keyType 5), or 96 (legacy)
|
|
428
|
+
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
429
|
+
* @returns {Wallet}
|
|
430
|
+
*/
|
|
431
|
+
static fromSeed(seed, provider) {
|
|
432
|
+
_requireInitialized();
|
|
433
|
+
assertArgument(Array.isArray(seed), "seed must be an array of numbers", "seed", seed);
|
|
434
|
+
const allowedLengths = [64, 72, 96];
|
|
435
|
+
assertArgument(allowedLengths.includes(seed.length), "seed must be 64, 72, or 96 bytes", "seed", seed.length);
|
|
436
|
+
const qcWallet = qcsdk.openWalletFromSeed(seed);
|
|
437
|
+
if (!qcWallet || typeof qcWallet === "number") {
|
|
438
|
+
throw makeError("openWalletFromSeed failed", "UNKNOWN_ERROR", { result: qcWallet });
|
|
439
|
+
}
|
|
440
|
+
return Wallet._fromQcWallet(qcWallet, provider || null);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Creates a wallet from an encrypted JSON string.
|
|
445
|
+
* @param {string} json
|
|
446
|
+
* @param {string} password
|
|
447
|
+
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
448
|
+
* @returns {Wallet}
|
|
449
|
+
*/
|
|
450
|
+
static fromEncryptedJsonSync(json, password, provider) {
|
|
451
|
+
_requireInitialized();
|
|
452
|
+
const qcWallet = qcsdk.deserializeEncryptedWallet(json, password);
|
|
453
|
+
if (!qcWallet) throw makeError("deserializeEncryptedWallet failed", "UNKNOWN_ERROR", {});
|
|
454
|
+
return Wallet._fromQcWallet(qcWallet, provider || null);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Creates a wallet from a seed phrase (32, 36, or 48 words).
|
|
459
|
+
* @param {string|string[]} phrase
|
|
460
|
+
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
461
|
+
* @returns {Wallet}
|
|
462
|
+
*/
|
|
463
|
+
static fromPhrase(phrase, provider) {
|
|
464
|
+
_requireInitialized();
|
|
465
|
+
let words = phrase;
|
|
466
|
+
if (typeof phrase === "string") {
|
|
467
|
+
words = phrase
|
|
468
|
+
.split(/[,\s]+/g)
|
|
469
|
+
.map((w) => w.trim())
|
|
470
|
+
.filter(Boolean);
|
|
471
|
+
}
|
|
472
|
+
assertArgument(Array.isArray(words), "phrase must be a string or string[]", "phrase", phrase);
|
|
473
|
+
const allowedLengths = [32, 36, 48];
|
|
474
|
+
assertArgument(
|
|
475
|
+
allowedLengths.includes(words.length),
|
|
476
|
+
"seed phrase must contain 32, 36, or 48 words",
|
|
477
|
+
"phrase",
|
|
478
|
+
words.length,
|
|
479
|
+
);
|
|
480
|
+
const qcWallet = qcsdk.openWalletFromSeedWords(words);
|
|
481
|
+
if (!qcWallet) throw makeError("openWalletFromSeedWords failed", "UNKNOWN_ERROR", {});
|
|
482
|
+
return Wallet._fromQcWallet(qcWallet, provider || null);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Creates a wallet from raw private and public key bytes.
|
|
487
|
+
* @param {Uint8Array|string} privateKey Private key bytes or hex string
|
|
488
|
+
* @param {Uint8Array|string} publicKey Public key bytes or hex string
|
|
489
|
+
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
490
|
+
* @returns {Wallet}
|
|
491
|
+
*/
|
|
492
|
+
static fromKeys(privateKey, publicKey, provider) {
|
|
493
|
+
_requireInitialized();
|
|
494
|
+
const privBytes = typeof privateKey === "string" ? hexToBytes(privateKey) : arrayify(privateKey);
|
|
495
|
+
const pubBytes = typeof publicKey === "string" ? hexToBytes(publicKey) : arrayify(publicKey);
|
|
496
|
+
assertSecretArgument(privBytes.length > 0, "privateKey must not be empty", "privateKey");
|
|
497
|
+
assertSecretArgument(pubBytes.length > 0, "publicKey must not be empty", "publicKey");
|
|
498
|
+
|
|
499
|
+
const privArr = _bytesToNumberArray(privBytes);
|
|
500
|
+
const pubArr = _bytesToNumberArray(pubBytes);
|
|
501
|
+
const addr = qcsdk.addressFromPublicKey(pubArr);
|
|
502
|
+
if (typeof addr !== "string") throw makeError("addressFromPublicKey failed", "UNKNOWN_ERROR", {});
|
|
503
|
+
|
|
504
|
+
const qcWallet = new qcsdk.Wallet(addr, privArr, pubArr);
|
|
505
|
+
const verified = qcsdk.verifyWallet(qcWallet);
|
|
506
|
+
if (verified !== true) {
|
|
507
|
+
throw makeError("verifyWallet failed: the provided key pair is invalid", "INVALID_ARGUMENT", { verified });
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
return Wallet._fromQcWallet(qcWallet, provider || null);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Internal helper: build a Wallet from a quantum-coin-js-sdk Wallet object.
|
|
515
|
+
* @param {any} qcWallet
|
|
516
|
+
* @param {import("../providers/provider").AbstractProvider|null} provider
|
|
517
|
+
* @returns {Wallet}
|
|
518
|
+
*/
|
|
519
|
+
static _fromQcWallet(qcWallet, provider) {
|
|
520
|
+
const privSrc = qcWallet.privateKey;
|
|
521
|
+
const pubSrc = qcWallet.publicKey;
|
|
522
|
+
|
|
523
|
+
if (!privSrc || (privSrc instanceof Uint8Array && privSrc.length === 0) || (Array.isArray(privSrc) && privSrc.length === 0)) {
|
|
524
|
+
throw makeError("qcWallet.privateKey is empty or missing", "UNKNOWN_ERROR", {});
|
|
525
|
+
}
|
|
526
|
+
if (!pubSrc || (pubSrc instanceof Uint8Array && pubSrc.length === 0) || (Array.isArray(pubSrc) && pubSrc.length === 0)) {
|
|
527
|
+
throw makeError("qcWallet.publicKey is empty or missing", "UNKNOWN_ERROR", {});
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
const privBytes =
|
|
531
|
+
privSrc instanceof Uint8Array ? new Uint8Array(privSrc) : Uint8Array.from(Array.from(privSrc).map((n) => (Number(n) & 0xff)));
|
|
532
|
+
const pubBytes =
|
|
533
|
+
pubSrc instanceof Uint8Array ? new Uint8Array(pubSrc) : Uint8Array.from(Array.from(pubSrc).map((n) => (Number(n) & 0xff)));
|
|
534
|
+
const key = new SigningKey(privBytes, pubBytes);
|
|
535
|
+
|
|
536
|
+
const w = new Wallet(key, provider || null);
|
|
537
|
+
// Ensure we keep the exact underlying qcWallet for operations like encrypt/signRawTransaction.
|
|
538
|
+
w._qcWallet = qcWallet;
|
|
539
|
+
if (typeof qcWallet.address === "string") {
|
|
540
|
+
w.address = normalizeHex(qcWallet.address);
|
|
541
|
+
}
|
|
542
|
+
if (qcWallet.preExpansionSeed != null) {
|
|
543
|
+
const seedSrc = qcWallet.preExpansionSeed;
|
|
544
|
+
const seedBytes =
|
|
545
|
+
seedSrc instanceof Uint8Array ? seedSrc : Uint8Array.from(Array.from(seedSrc).map((n) => (Number(n) & 0xff)));
|
|
546
|
+
w._seed = bytesToHex(seedBytes);
|
|
547
|
+
}
|
|
548
|
+
return w;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* NonceManager wrapper.
|
|
554
|
+
*/
|
|
555
|
+
class NonceManager extends AbstractSigner {
|
|
556
|
+
/**
|
|
557
|
+
* @param {AbstractSigner} signer
|
|
558
|
+
*/
|
|
559
|
+
constructor(signer) {
|
|
560
|
+
super(signer.provider || null);
|
|
561
|
+
this.signer = signer;
|
|
562
|
+
this._nonce = null;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
async getAddress() {
|
|
566
|
+
return this.signer.getAddress();
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
async getTransactionCount(blockTag) {
|
|
570
|
+
if (this._nonce != null) return this._nonce;
|
|
571
|
+
if (!this.provider) throw makeError("missing provider", "UNKNOWN_ERROR", { operation: "getTransactionCount" });
|
|
572
|
+
const address = await this.getAddress();
|
|
573
|
+
this._nonce = await this.provider.getTransactionCount(address, blockTag);
|
|
574
|
+
return this._nonce;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
async sendTransaction(tx) {
|
|
578
|
+
const nonce = await this.getTransactionCount("latest");
|
|
579
|
+
const result = await this.signer.sendTransaction({ ...tx, nonce });
|
|
580
|
+
this._nonce = nonce + 1;
|
|
581
|
+
return result;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
reset() {
|
|
585
|
+
this._nonce = null;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
increment() {
|
|
589
|
+
if (this._nonce == null) this._nonce = 0;
|
|
590
|
+
this._nonce++;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* JsonRpcSigner placeholder (ethers-like).
|
|
596
|
+
* This SDK encourages using Wallet directly for signing.
|
|
597
|
+
*/
|
|
598
|
+
class JsonRpcSigner extends AbstractSigner {
|
|
599
|
+
constructor(provider, address) {
|
|
600
|
+
super(provider);
|
|
601
|
+
this._address = address;
|
|
602
|
+
}
|
|
603
|
+
async getAddress() {
|
|
604
|
+
return this._address;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
/**
|
|
609
|
+
* VoidSigner (cannot sign, only provides address).
|
|
610
|
+
*/
|
|
611
|
+
class VoidSigner extends AbstractSigner {
|
|
612
|
+
constructor(address, provider) {
|
|
613
|
+
super(provider || null);
|
|
614
|
+
this._address = getAddress(address);
|
|
615
|
+
}
|
|
616
|
+
async getAddress() {
|
|
617
|
+
return this._address;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
module.exports = {
|
|
622
|
+
SigningKey,
|
|
623
|
+
AbstractSigner,
|
|
624
|
+
BaseWallet,
|
|
625
|
+
Wallet,
|
|
626
|
+
NonceManager,
|
|
627
|
+
JsonRpcSigner,
|
|
628
|
+
VoidSigner,
|
|
629
|
+
};
|
|
630
|
+
|