@geeqdev/geeq-sdk 0.1.0 → 0.2.0
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/.idea/geeq_sdk.iml +12 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/.nvmrc +1 -0
- package/CONTRIBUTING.md +20 -0
- package/dist/src/address/record-type.d.ts +10 -0
- package/dist/src/address/record-type.js +59 -0
- package/dist/src/address/record-type.js.map +1 -0
- package/dist/src/address/wallet-address.d.ts +34 -0
- package/dist/src/address/wallet-address.js +90 -0
- package/dist/src/address/wallet-address.js.map +1 -0
- package/dist/src/amount.d.ts +43 -0
- package/dist/src/amount.js +105 -0
- package/dist/src/amount.js.map +1 -0
- package/dist/src/assert.d.ts +12 -0
- package/dist/src/assert.js +24 -0
- package/dist/src/assert.js.map +1 -0
- package/dist/src/capnp/adminNetTx.capnp.d.ts +75 -0
- package/dist/src/capnp/adminNetTx.capnp.js +66 -0
- package/dist/src/capnp/adminNetTx.capnp.js.map +1 -0
- package/dist/src/capnp/appLayBlock.capnp.d.ts +26 -0
- package/dist/src/capnp/appLayBlock.capnp.js +24 -0
- package/dist/src/capnp/appLayBlock.capnp.js.map +1 -0
- package/dist/src/capnp/appLayLedger.capnp.d.ts +34 -0
- package/dist/src/capnp/appLayLedger.capnp.js +32 -0
- package/dist/src/capnp/appLayLedger.capnp.js.map +1 -0
- package/dist/src/capnp/appLayRec.capnp.d.ts +129 -0
- package/dist/src/capnp/appLayRec.capnp.js +156 -0
- package/dist/src/capnp/appLayRec.capnp.js.map +1 -0
- package/dist/src/capnp/chainStateView.capnp.d.ts +50 -0
- package/dist/src/capnp/chainStateView.capnp.js +48 -0
- package/dist/src/capnp/chainStateView.capnp.js.map +1 -0
- package/dist/src/capnp/coinAcctRec.capnp.d.ts +178 -0
- package/dist/src/capnp/coinAcctRec.capnp.js +189 -0
- package/dist/src/capnp/coinAcctRec.capnp.js.map +1 -0
- package/dist/src/capnp/genesisBlock.capnp.d.ts +61 -0
- package/dist/src/capnp/genesisBlock.capnp.js +55 -0
- package/dist/src/capnp/genesisBlock.capnp.js.map +1 -0
- package/dist/src/capnp/hubContentStmt.capnp.d.ts +63 -0
- package/dist/src/capnp/hubContentStmt.capnp.js +57 -0
- package/dist/src/capnp/hubContentStmt.capnp.js.map +1 -0
- package/dist/src/capnp/misc.capnp.d.ts +20 -0
- package/dist/src/capnp/misc.capnp.js +18 -0
- package/dist/src/capnp/misc.capnp.js.map +1 -0
- package/dist/src/capnp/netActorRec.capnp.d.ts +65 -0
- package/dist/src/capnp/netActorRec.capnp.js +65 -0
- package/dist/src/capnp/netActorRec.capnp.js.map +1 -0
- package/dist/src/capnp/nodeContentStmt.capnp.d.ts +67 -0
- package/dist/src/capnp/nodeContentStmt.capnp.js +61 -0
- package/dist/src/capnp/nodeContentStmt.capnp.js.map +1 -0
- package/dist/src/capnp/nodePayloadList.capnp.d.ts +28 -0
- package/dist/src/capnp/nodePayloadList.capnp.js +26 -0
- package/dist/src/capnp/nodePayloadList.capnp.js.map +1 -0
- package/dist/src/capnp/nodeTxList.capnp.d.ts +36 -0
- package/dist/src/capnp/nodeTxList.capnp.js +34 -0
- package/dist/src/capnp/nodeTxList.capnp.js.map +1 -0
- package/dist/src/capnp/paramAcctRec.capnp.d.ts +338 -0
- package/dist/src/capnp/paramAcctRec.capnp.js +669 -0
- package/dist/src/capnp/paramAcctRec.capnp.js.map +1 -0
- package/dist/src/capnp/payload.capnp.d.ts +237 -0
- package/dist/src/capnp/payload.capnp.js +260 -0
- package/dist/src/capnp/payload.capnp.js.map +1 -0
- package/dist/src/capnp/proxyAcctRec.capnp.d.ts +223 -0
- package/dist/src/capnp/proxyAcctRec.capnp.js +255 -0
- package/dist/src/capnp/proxyAcctRec.capnp.js.map +1 -0
- package/dist/src/capnp/relayContentStmt.capnp.d.ts +82 -0
- package/dist/src/capnp/relayContentStmt.capnp.js +85 -0
- package/dist/src/capnp/relayContentStmt.capnp.js.map +1 -0
- package/dist/src/capnp/sysAcctRec.capnp.d.ts +48 -0
- package/dist/src/capnp/sysAcctRec.capnp.js +46 -0
- package/dist/src/capnp/sysAcctRec.capnp.js.map +1 -0
- package/dist/src/capnp/userAppTx.capnp.d.ts +230 -0
- package/dist/src/capnp/userAppTx.capnp.js +270 -0
- package/dist/src/capnp/userAppTx.capnp.js.map +1 -0
- package/dist/src/capnp/userValTx.capnp.d.ts +1575 -0
- package/dist/src/capnp/userValTx.capnp.js +2004 -0
- package/dist/src/capnp/userValTx.capnp.js.map +1 -0
- package/dist/src/capnp/valLayBlock.capnp.d.ts +88 -0
- package/dist/src/capnp/valLayBlock.capnp.js +86 -0
- package/dist/src/capnp/valLayBlock.capnp.js.map +1 -0
- package/dist/src/capnp/valLayLedger.capnp.d.ts +85 -0
- package/dist/src/capnp/valLayLedger.capnp.js +75 -0
- package/dist/src/capnp/valLayLedger.capnp.js.map +1 -0
- package/dist/src/chain/geeq-chain.d.ts +474 -0
- package/dist/src/chain/geeq-chain.js +721 -0
- package/dist/src/chain/geeq-chain.js.map +1 -0
- package/dist/src/chain/geeq-node.d.ts +57 -0
- package/dist/src/chain/geeq-node.js +62 -0
- package/dist/src/chain/geeq-node.js.map +1 -0
- package/dist/src/chain/nonce-guard.d.ts +42 -0
- package/dist/src/chain/nonce-guard.js +68 -0
- package/dist/src/chain/nonce-guard.js.map +1 -0
- package/dist/src/chain/select.d.ts +40 -0
- package/dist/src/chain/select.js +114 -0
- package/dist/src/chain/select.js.map +1 -0
- package/dist/src/crypto/account-id.d.ts +35 -0
- package/dist/src/crypto/account-id.js +58 -0
- package/dist/src/crypto/account-id.js.map +1 -0
- package/dist/src/crypto/keypair.d.ts +24 -0
- package/dist/src/crypto/keypair.js +158 -0
- package/dist/src/crypto/keypair.js.map +1 -0
- package/dist/src/crypto/mnemonic.d.ts +34 -0
- package/dist/src/crypto/mnemonic.js +57 -0
- package/dist/src/crypto/mnemonic.js.map +1 -0
- package/dist/src/encoding/base64.d.ts +8 -0
- package/dist/src/encoding/base64.js +53 -0
- package/dist/src/encoding/base64.js.map +1 -0
- package/dist/src/encoding/hex.d.ts +2 -0
- package/dist/src/encoding/hex.js +35 -0
- package/dist/src/encoding/hex.js.map +1 -0
- package/dist/src/errors.d.ts +83 -0
- package/dist/src/errors.js +49 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/index.d.ts +59 -0
- package/dist/src/index.js +53 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/ledger/coin-accounts.d.ts +42 -0
- package/dist/src/ledger/coin-accounts.js +37 -0
- package/dist/src/ledger/coin-accounts.js.map +1 -0
- package/dist/src/ledger/decode.d.ts +18 -0
- package/dist/src/ledger/decode.js +113 -0
- package/dist/src/ledger/decode.js.map +1 -0
- package/dist/src/ledger/geeq-ledger.d.ts +99 -0
- package/dist/src/ledger/geeq-ledger.js +125 -0
- package/dist/src/ledger/geeq-ledger.js.map +1 -0
- package/dist/src/ledger/net-actors.d.ts +65 -0
- package/dist/src/ledger/net-actors.js +53 -0
- package/dist/src/ledger/net-actors.js.map +1 -0
- package/dist/src/ledger/nft-records.d.ts +13 -0
- package/dist/src/ledger/nft-records.js +41 -0
- package/dist/src/ledger/nft-records.js.map +1 -0
- package/dist/src/ledger/params.d.ts +34 -0
- package/dist/src/ledger/params.js +71 -0
- package/dist/src/ledger/params.js.map +1 -0
- package/dist/src/ledger/proxy-accounts.d.ts +26 -0
- package/dist/src/ledger/proxy-accounts.js +27 -0
- package/dist/src/ledger/proxy-accounts.js.map +1 -0
- package/dist/src/net/discovery.d.ts +62 -0
- package/dist/src/net/discovery.js +136 -0
- package/dist/src/net/discovery.js.map +1 -0
- package/dist/src/net/explorer.d.ts +57 -0
- package/dist/src/net/explorer.js +64 -0
- package/dist/src/net/explorer.js.map +1 -0
- package/dist/src/net/read-ledger.d.ts +7 -0
- package/dist/src/net/read-ledger.js +39 -0
- package/dist/src/net/read-ledger.js.map +1 -0
- package/dist/src/net/routes.d.ts +49 -0
- package/dist/src/net/routes.js +70 -0
- package/dist/src/net/routes.js.map +1 -0
- package/dist/src/net/transport.d.ts +55 -0
- package/dist/src/net/transport.js +168 -0
- package/dist/src/net/transport.js.map +1 -0
- package/dist/src/net/websocket.d.ts +49 -0
- package/dist/src/net/websocket.js +54 -0
- package/dist/src/net/websocket.js.map +1 -0
- package/dist/src/runtime/bindings.d.ts +9 -0
- package/dist/src/runtime/bindings.js +27 -0
- package/dist/src/runtime/bindings.js.map +1 -0
- package/dist/src/runtime/init.d.ts +13 -0
- package/dist/src/runtime/init.js +40 -0
- package/dist/src/runtime/init.js.map +1 -0
- package/dist/src/runtime/wasm-loader.browser.d.ts +14 -0
- package/dist/src/runtime/wasm-loader.browser.js +20 -0
- package/dist/src/runtime/wasm-loader.browser.js.map +1 -0
- package/dist/src/runtime/wasm-loader.node.d.ts +7 -0
- package/dist/src/runtime/wasm-loader.node.js +14 -0
- package/dist/src/runtime/wasm-loader.node.js.map +1 -0
- package/dist/src/socket/geeq-socket.d.ts +232 -0
- package/dist/src/socket/geeq-socket.js +634 -0
- package/dist/src/socket/geeq-socket.js.map +1 -0
- package/dist/src/socket/tracked-tx.d.ts +148 -0
- package/dist/src/socket/tracked-tx.js +212 -0
- package/dist/src/socket/tracked-tx.js.map +1 -0
- package/dist/src/socket/tx-status.d.ts +69 -0
- package/dist/src/socket/tx-status.js +72 -0
- package/dist/src/socket/tx-status.js.map +1 -0
- package/dist/src/tx/attestation.d.ts +60 -0
- package/dist/src/tx/attestation.js +163 -0
- package/dist/src/tx/attestation.js.map +1 -0
- package/dist/src/tx/content.d.ts +27 -0
- package/dist/src/tx/content.js +62 -0
- package/dist/src/tx/content.js.map +1 -0
- package/dist/src/tx/encode.d.ts +60 -0
- package/dist/src/tx/encode.js +82 -0
- package/dist/src/tx/encode.js.map +1 -0
- package/dist/src/tx/expiry.d.ts +11 -0
- package/dist/src/tx/expiry.js +12 -0
- package/dist/src/tx/expiry.js.map +1 -0
- package/dist/src/tx/fee.d.ts +16 -0
- package/dist/src/tx/fee.js +29 -0
- package/dist/src/tx/fee.js.map +1 -0
- package/dist/src/tx/metadata.d.ts +39 -0
- package/dist/src/tx/metadata.js +66 -0
- package/dist/src/tx/metadata.js.map +1 -0
- package/dist/src/tx/nft.d.ts +16 -0
- package/dist/src/tx/nft.js +98 -0
- package/dist/src/tx/nft.js.map +1 -0
- package/dist/src/tx/proxy.d.ts +37 -0
- package/dist/src/tx/proxy.js +134 -0
- package/dist/src/tx/proxy.js.map +1 -0
- package/dist/src/tx/transfer.d.ts +31 -0
- package/dist/src/tx/transfer.js +123 -0
- package/dist/src/tx/transfer.js.map +1 -0
- package/dist/src/types.d.ts +448 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/tests/account-id.test.d.ts +1 -0
- package/dist/tests/account-id.test.js +27 -0
- package/dist/tests/account-id.test.js.map +1 -0
- package/dist/tests/amount.test.d.ts +1 -0
- package/dist/tests/amount.test.js +113 -0
- package/dist/tests/amount.test.js.map +1 -0
- package/dist/tests/attestation.test.d.ts +1 -0
- package/dist/tests/attestation.test.js +182 -0
- package/dist/tests/attestation.test.js.map +1 -0
- package/dist/tests/chain.test.d.ts +1 -0
- package/dist/tests/chain.test.js +647 -0
- package/dist/tests/chain.test.js.map +1 -0
- package/dist/tests/content.test.d.ts +1 -0
- package/dist/tests/content.test.js +90 -0
- package/dist/tests/content.test.js.map +1 -0
- package/dist/tests/documented-api.test.d.ts +1 -0
- package/dist/tests/documented-api.test.js +229 -0
- package/dist/tests/documented-api.test.js.map +1 -0
- package/dist/tests/explorer.test.d.ts +1 -0
- package/dist/tests/explorer.test.js +95 -0
- package/dist/tests/explorer.test.js.map +1 -0
- package/dist/tests/fee.test.d.ts +1 -0
- package/dist/tests/fee.test.js +179 -0
- package/dist/tests/fee.test.js.map +1 -0
- package/dist/tests/fixtures/build-vll.d.ts +71 -0
- package/dist/tests/fixtures/build-vll.js +141 -0
- package/dist/tests/fixtures/build-vll.js.map +1 -0
- package/dist/tests/fixtures/fake-socket.d.ts +44 -0
- package/dist/tests/fixtures/fake-socket.js +93 -0
- package/dist/tests/fixtures/fake-socket.js.map +1 -0
- package/dist/tests/fixtures/fake-transport.d.ts +24 -0
- package/dist/tests/fixtures/fake-transport.js +30 -0
- package/dist/tests/fixtures/fake-transport.js.map +1 -0
- package/dist/tests/keypair.test.d.ts +1 -0
- package/dist/tests/keypair.test.js +163 -0
- package/dist/tests/keypair.test.js.map +1 -0
- package/dist/tests/ledger.test.d.ts +1 -0
- package/dist/tests/ledger.test.js +234 -0
- package/dist/tests/ledger.test.js.map +1 -0
- package/dist/tests/mnemonic.test.d.ts +1 -0
- package/dist/tests/mnemonic.test.js +97 -0
- package/dist/tests/mnemonic.test.js.map +1 -0
- package/dist/tests/nft-transfer.test.d.ts +1 -0
- package/dist/tests/nft-transfer.test.js +170 -0
- package/dist/tests/nft-transfer.test.js.map +1 -0
- package/dist/tests/nft.test.d.ts +1 -0
- package/dist/tests/nft.test.js +180 -0
- package/dist/tests/nft.test.js.map +1 -0
- package/dist/tests/offline.test.d.ts +1 -0
- package/dist/tests/offline.test.js +95 -0
- package/dist/tests/offline.test.js.map +1 -0
- package/dist/tests/proxy.test.d.ts +1 -0
- package/dist/tests/proxy.test.js +183 -0
- package/dist/tests/proxy.test.js.map +1 -0
- package/dist/tests/select.test.d.ts +1 -0
- package/dist/tests/select.test.js +200 -0
- package/dist/tests/select.test.js.map +1 -0
- package/dist/tests/socket.test.d.ts +1 -0
- package/dist/tests/socket.test.js +607 -0
- package/dist/tests/socket.test.js.map +1 -0
- package/dist/tests/transfer.test.d.ts +1 -0
- package/dist/tests/transfer.test.js +225 -0
- package/dist/tests/transfer.test.js.map +1 -0
- package/dist/tests/wallet-address.test.d.ts +1 -0
- package/dist/tests/wallet-address.test.js +101 -0
- package/dist/tests/wallet-address.test.js.map +1 -0
- package/dist/tests/wasm-loader.jest.d.ts +13 -0
- package/dist/tests/wasm-loader.jest.js +15 -0
- package/dist/tests/wasm-loader.jest.js.map +1 -0
- package/example/.env.example +4 -0
- package/example/README.md +304 -0
- package/example/USAGE.md +74 -0
- package/example/index.html +12 -0
- package/example/package-lock.json +1557 -0
- package/example/package.json +25 -0
- package/example/scripts/browser-check.mjs +1421 -0
- package/example/scripts/match-derivation.mjs +65 -0
- package/example/src/App.vue +138 -0
- package/example/src/components/AuthorityPanel.vue +277 -0
- package/example/src/components/ChainPanel.vue +267 -0
- package/example/src/components/ChainState.vue +59 -0
- package/example/src/components/CopyButton.vue +25 -0
- package/example/src/components/CreateAssetPanel.vue +313 -0
- package/example/src/components/DigitalAssetsPanel.vue +68 -0
- package/example/src/components/EvidencePanel.vue +396 -0
- package/example/src/components/ExplorerPanel.vue +119 -0
- package/example/src/components/KeypairPanel.vue +182 -0
- package/example/src/components/PhrasePanel.vue +105 -0
- package/example/src/components/SocketWarning.vue +18 -0
- package/example/src/components/StepGate.vue +24 -0
- package/example/src/components/TransferPanel.vue +416 -0
- package/example/src/components/TxDeadline.vue +19 -0
- package/example/src/components/TxFee.vue +31 -0
- package/example/src/components/TxStatus.vue +105 -0
- package/example/src/composables/useSocketConnection.ts +80 -0
- package/example/src/env.d.ts +12 -0
- package/example/src/main.ts +5 -0
- package/example/src/pennies.ts +7 -0
- package/example/src/style.css +149 -0
- package/example/tsconfig.json +19 -0
- package/example/vite.config.ts +26 -0
- package/jest.config.js +18 -0
- package/package.json +2 -6
- package/scripts/copy-wasm.mjs +21 -0
- package/scripts/smoke.mjs +382 -0
- package/src/address/record-type.ts +77 -0
- package/src/address/wallet-address.ts +105 -0
- package/src/amount.ts +143 -0
- package/src/assert.ts +30 -0
- package/src/capnp/README.md +15 -0
- package/src/capnp/adminNetTx.capnp.ts +66 -0
- package/src/capnp/appLayBlock.capnp.ts +26 -0
- package/src/capnp/appLayLedger.capnp.ts +35 -0
- package/src/capnp/appLayRec.capnp.ts +159 -0
- package/src/capnp/chainStateView.capnp.ts +49 -0
- package/src/capnp/coinAcctRec.capnp.ts +193 -0
- package/src/capnp/genesisBlock.capnp.ts +56 -0
- package/src/capnp/hubContentStmt.capnp.ts +59 -0
- package/src/capnp/misc.capnp.ts +19 -0
- package/src/capnp/netActorRec.capnp.ts +64 -0
- package/src/capnp/nodeContentStmt.capnp.ts +62 -0
- package/src/capnp/nodePayloadList.capnp.ts +28 -0
- package/src/capnp/nodeTxList.capnp.ts +37 -0
- package/src/capnp/paramAcctRec.capnp.ts +669 -0
- package/src/capnp/payload.capnp.ts +261 -0
- package/src/capnp/proxyAcctRec.capnp.ts +259 -0
- package/src/capnp/relayContentStmt.capnp.ts +85 -0
- package/src/capnp/sysAcctRec.capnp.ts +47 -0
- package/src/capnp/userAppTx.capnp.ts +269 -0
- package/src/capnp/userValTx.capnp.ts +1999 -0
- package/src/capnp/valLayBlock.capnp.ts +93 -0
- package/src/capnp/valLayLedger.capnp.ts +80 -0
- package/src/chain/geeq-chain.ts +1094 -0
- package/src/chain/geeq-node.ts +105 -0
- package/src/chain/nonce-guard.ts +73 -0
- package/src/chain/select.ts +149 -0
- package/src/crypto/account-id.ts +83 -0
- package/src/crypto/keypair.ts +221 -0
- package/src/crypto/mnemonic.ts +69 -0
- package/src/encoding/base64.ts +58 -0
- package/src/encoding/hex.ts +42 -0
- package/src/errors.ts +122 -0
- package/src/index.ts +195 -0
- package/src/ledger/coin-accounts.ts +73 -0
- package/src/ledger/decode.ts +147 -0
- package/src/ledger/geeq-ledger.ts +184 -0
- package/src/ledger/net-actors.ts +129 -0
- package/src/ledger/nft-records.ts +49 -0
- package/src/ledger/params.ts +82 -0
- package/src/ledger/proxy-accounts.ts +51 -0
- package/src/net/discovery.ts +231 -0
- package/src/net/explorer.ts +123 -0
- package/src/net/read-ledger.ts +58 -0
- package/src/net/routes.ts +79 -0
- package/src/net/transport.ts +221 -0
- package/src/net/websocket.ts +94 -0
- package/src/runtime/bindings.ts +38 -0
- package/src/runtime/init.ts +49 -0
- package/src/runtime/wasm-loader.browser.ts +22 -0
- package/src/runtime/wasm-loader.node.ts +16 -0
- package/src/socket/geeq-socket.ts +827 -0
- package/src/socket/tracked-tx.ts +319 -0
- package/src/socket/tx-status.ts +131 -0
- package/src/tx/attestation.ts +222 -0
- package/src/tx/content.ts +82 -0
- package/src/tx/encode.ts +107 -0
- package/src/tx/expiry.ts +11 -0
- package/src/tx/fee.ts +31 -0
- package/src/tx/metadata.ts +100 -0
- package/src/tx/nft.ts +108 -0
- package/src/tx/proxy.ts +156 -0
- package/src/tx/transfer.ts +162 -0
- package/src/types.ts +503 -0
- package/src/wasm/README.md +22 -0
- package/src/wasm/browser/geeq_core.d.ts +1224 -0
- package/src/wasm/browser/geeq_core.js +6014 -0
- package/src/wasm/browser/geeq_core_bg.wasm +0 -0
- package/src/wasm/browser/geeq_core_bg.wasm.d.ts +447 -0
- package/src/wasm/nodejs/geeq_core.d.ts +753 -0
- package/src/wasm/nodejs/geeq_core.js +6016 -0
- package/src/wasm/nodejs/geeq_core_bg.wasm +0 -0
- package/src/wasm/nodejs/geeq_core_bg.wasm.d.ts +447 -0
- package/src/wasm/nodejs/package.json +3 -0
- package/tsconfig.build.json +8 -0
- package/tsconfig.json +21 -0
- package/tsup.config.ts +60 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { describe, expect, it, beforeAll } from '@jest/globals';
|
|
2
|
+
import { ACCOUNT_ID_BYTES, GeeqError, accountIdFromPublicKey, generateKeypair, importKeypair, initGeeq, keypairFromMnemonic, keypairFromSecretKey, verifySignature, } from '../src/index';
|
|
3
|
+
// A standard BIP-39 test vector. Throwaway — never use it for real funds.
|
|
4
|
+
const MNEMONIC = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
|
|
5
|
+
beforeAll(async () => {
|
|
6
|
+
await initGeeq();
|
|
7
|
+
});
|
|
8
|
+
describe('generateKeypair', () => {
|
|
9
|
+
it('produces 32-byte keys and a 32-byte account id', async () => {
|
|
10
|
+
const kp = await generateKeypair();
|
|
11
|
+
expect(kp.publicKey).toBeInstanceOf(Uint8Array);
|
|
12
|
+
expect(kp.publicKey).toHaveLength(32);
|
|
13
|
+
expect(kp.privateKey).toHaveLength(32);
|
|
14
|
+
expect(kp.accountId).toHaveLength(ACCOUNT_ID_BYTES);
|
|
15
|
+
kp.dispose();
|
|
16
|
+
});
|
|
17
|
+
it('produces a different keypair each time', async () => {
|
|
18
|
+
const [a, b] = await Promise.all([generateKeypair(), generateKeypair()]);
|
|
19
|
+
expect(Buffer.from(a.publicKey)).not.toEqual(Buffer.from(b.publicKey));
|
|
20
|
+
a.dispose();
|
|
21
|
+
b.dispose();
|
|
22
|
+
});
|
|
23
|
+
it('derives the account id as blake3 of the public key', async () => {
|
|
24
|
+
const kp = await generateKeypair();
|
|
25
|
+
expect(Buffer.from(kp.accountId)).toEqual(Buffer.from(accountIdFromPublicKey(kp.publicKey)));
|
|
26
|
+
kp.dispose();
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
describe('importKeypair', () => {
|
|
30
|
+
it('round-trips a generated keypair', async () => {
|
|
31
|
+
const original = await generateKeypair();
|
|
32
|
+
const restored = await importKeypair(original.publicKey, original.privateKey);
|
|
33
|
+
expect(Buffer.from(restored.publicKey)).toEqual(Buffer.from(original.publicKey));
|
|
34
|
+
expect(Buffer.from(restored.privateKey)).toEqual(Buffer.from(original.privateKey));
|
|
35
|
+
expect(Buffer.from(restored.accountId)).toEqual(Buffer.from(original.accountId));
|
|
36
|
+
original.dispose();
|
|
37
|
+
restored.dispose();
|
|
38
|
+
});
|
|
39
|
+
it('rejects a mismatched pair rather than producing a broken signer', async () => {
|
|
40
|
+
const a = await generateKeypair();
|
|
41
|
+
const b = await generateKeypair();
|
|
42
|
+
await expect(importKeypair(a.publicKey, b.privateKey)).rejects.toMatchObject({
|
|
43
|
+
code: 'invalid-key',
|
|
44
|
+
});
|
|
45
|
+
a.dispose();
|
|
46
|
+
b.dispose();
|
|
47
|
+
});
|
|
48
|
+
it.each([
|
|
49
|
+
['publicKey', 31],
|
|
50
|
+
['publicKey', 33],
|
|
51
|
+
])('rejects a %s of %d bytes', async (_label, size) => {
|
|
52
|
+
const kp = await generateKeypair();
|
|
53
|
+
await expect(importKeypair(new Uint8Array(size), kp.privateKey)).rejects.toBeInstanceOf(GeeqError);
|
|
54
|
+
kp.dispose();
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
describe('keypairFromSecretKey', () => {
|
|
58
|
+
it('recovers the same public key', async () => {
|
|
59
|
+
const original = await generateKeypair();
|
|
60
|
+
const recovered = await keypairFromSecretKey(original.privateKey);
|
|
61
|
+
expect(Buffer.from(recovered.publicKey)).toEqual(Buffer.from(original.publicKey));
|
|
62
|
+
original.dispose();
|
|
63
|
+
recovered.dispose();
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
describe('keypairFromMnemonic', () => {
|
|
67
|
+
it('is deterministic for the same mnemonic and options', async () => {
|
|
68
|
+
const a = await keypairFromMnemonic(MNEMONIC);
|
|
69
|
+
const b = await keypairFromMnemonic(MNEMONIC);
|
|
70
|
+
expect(Buffer.from(a.publicKey)).toEqual(Buffer.from(b.publicKey));
|
|
71
|
+
a.dispose();
|
|
72
|
+
b.dispose();
|
|
73
|
+
});
|
|
74
|
+
it('derives mainnet keys by default', async () => {
|
|
75
|
+
const implicit = await keypairFromMnemonic(MNEMONIC);
|
|
76
|
+
const mainnet = await keypairFromMnemonic(MNEMONIC, { coinType: 'mainnet' });
|
|
77
|
+
const testnet = await keypairFromMnemonic(MNEMONIC, { coinType: 'testnet' });
|
|
78
|
+
expect(Buffer.from(implicit.publicKey)).toEqual(Buffer.from(mainnet.publicKey));
|
|
79
|
+
expect(Buffer.from(implicit.publicKey)).not.toEqual(Buffer.from(testnet.publicKey));
|
|
80
|
+
implicit.dispose();
|
|
81
|
+
mainnet.dispose();
|
|
82
|
+
testnet.dispose();
|
|
83
|
+
});
|
|
84
|
+
it('derives a different key per address index', async () => {
|
|
85
|
+
const a = await keypairFromMnemonic(MNEMONIC, { addressIndex: 0 });
|
|
86
|
+
const b = await keypairFromMnemonic(MNEMONIC, { addressIndex: 1 });
|
|
87
|
+
expect(Buffer.from(a.publicKey)).not.toEqual(Buffer.from(b.publicKey));
|
|
88
|
+
a.dispose();
|
|
89
|
+
b.dispose();
|
|
90
|
+
});
|
|
91
|
+
it('derives a different key with a passphrase', async () => {
|
|
92
|
+
const a = await keypairFromMnemonic(MNEMONIC);
|
|
93
|
+
const b = await keypairFromMnemonic(MNEMONIC, { passphrase: 'correct horse' });
|
|
94
|
+
expect(Buffer.from(a.publicKey)).not.toEqual(Buffer.from(b.publicKey));
|
|
95
|
+
a.dispose();
|
|
96
|
+
b.dispose();
|
|
97
|
+
});
|
|
98
|
+
it('rejects an empty mnemonic', async () => {
|
|
99
|
+
await expect(keypairFromMnemonic(' ')).rejects.toMatchObject({ code: 'invalid-argument' });
|
|
100
|
+
});
|
|
101
|
+
it('rejects a nonsense mnemonic', async () => {
|
|
102
|
+
await expect(keypairFromMnemonic('not actually a valid bip39 phrase at all')).rejects.toMatchObject({
|
|
103
|
+
code: 'invalid-key',
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
describe('sign / verify', () => {
|
|
108
|
+
it('produces a signature this public key verifies', async () => {
|
|
109
|
+
const kp = await generateKeypair();
|
|
110
|
+
const message = new TextEncoder().encode('geeq sdk smoke test');
|
|
111
|
+
const signature = kp.sign(message);
|
|
112
|
+
expect(signature).toHaveLength(64);
|
|
113
|
+
expect(verifySignature(kp.publicKey, signature, message)).toBe(true);
|
|
114
|
+
kp.dispose();
|
|
115
|
+
});
|
|
116
|
+
it('rejects a tampered message', async () => {
|
|
117
|
+
const kp = await generateKeypair();
|
|
118
|
+
const signature = kp.sign(new TextEncoder().encode('original'));
|
|
119
|
+
expect(verifySignature(kp.publicKey, signature, new TextEncoder().encode('tampered'))).toBe(false);
|
|
120
|
+
kp.dispose();
|
|
121
|
+
});
|
|
122
|
+
it('throws after dispose instead of signing with freed memory', async () => {
|
|
123
|
+
const kp = await generateKeypair();
|
|
124
|
+
kp.dispose();
|
|
125
|
+
expect(() => kp.sign(new Uint8Array([1]))).toThrow(GeeqError);
|
|
126
|
+
// Byte fields stay readable so callers can still persist them.
|
|
127
|
+
expect(kp.publicKey).toHaveLength(32);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
describe('secret hygiene', () => {
|
|
131
|
+
it('keeps the private key out of JSON and string coercion', async () => {
|
|
132
|
+
const kp = await generateKeypair();
|
|
133
|
+
const serialized = JSON.stringify({ wallet: kp });
|
|
134
|
+
const privateHex = Buffer.from(kp.privateKey).toString('hex');
|
|
135
|
+
expect(serialized).not.toContain(privateHex);
|
|
136
|
+
expect(serialized).not.toContain(Buffer.from(kp.privateKey).toString('base64'));
|
|
137
|
+
expect(`${String(kp)}`).toBe('[GeeqKeypair]');
|
|
138
|
+
kp.dispose();
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
describe('framework interop', () => {
|
|
142
|
+
/**
|
|
143
|
+
* Regression: the keypair used a `#private` field for its engine handle, which
|
|
144
|
+
* is unreachable through a Proxy. Storing one in Vue's `ref()` therefore threw
|
|
145
|
+
* `TypeError: Cannot read from private field` on every method call.
|
|
146
|
+
*/
|
|
147
|
+
it('works through a Proxy, as used by Vue/MobX reactive state', async () => {
|
|
148
|
+
const keypair = await generateKeypair();
|
|
149
|
+
const reactive = new Proxy(keypair, {});
|
|
150
|
+
expect(() => reactive.getAddress({ chainNumber: 1 })).not.toThrow();
|
|
151
|
+
expect(reactive.getAddress({ chainNumber: 1 })).toBe(keypair.getAddress({ chainNumber: 1 }));
|
|
152
|
+
expect(() => reactive.sign(new Uint8Array([1, 2, 3]))).not.toThrow();
|
|
153
|
+
expect(() => reactive.dispose()).not.toThrow();
|
|
154
|
+
expect(() => reactive.sign(new Uint8Array([1]))).toThrow(GeeqError);
|
|
155
|
+
});
|
|
156
|
+
it('keeps the engine handle out of enumeration and spreads', async () => {
|
|
157
|
+
const keypair = await generateKeypair();
|
|
158
|
+
expect(Object.keys(keypair)).toEqual(['publicKey', 'privateKey', 'accountId']);
|
|
159
|
+
expect(Object.keys({ ...keypair })).not.toContain('handle');
|
|
160
|
+
keypair.dispose();
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
//# sourceMappingURL=keypair.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keypair.test.js","sourceRoot":"","sources":["../../tests/keypair.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { describe, expect, it } from '@jest/globals';
|
|
2
|
+
import { decodeValidationLedger } from '../src/index';
|
|
3
|
+
import { NetActorStatus, NetActorType, buildVll, vllBase64, } from './fixtures/build-vll';
|
|
4
|
+
const ACCOUNT = new Uint8Array(32).fill(7);
|
|
5
|
+
const OTHER = new Uint8Array(32).fill(8);
|
|
6
|
+
// Nothing here touches the engine or the network: the ledger layer is pure.
|
|
7
|
+
describe('decodeValidationLedger', () => {
|
|
8
|
+
it('reads chain, block and the target block from a nominal ledger', () => {
|
|
9
|
+
const ledger = decodeValidationLedger(buildVll({ chainNumber: 5, blockNumber: 41 }));
|
|
10
|
+
expect(ledger.chainNumber).toBe(5);
|
|
11
|
+
expect(ledger.blockNumber).toBe(41);
|
|
12
|
+
expect(ledger.targetBlockNumber).toBe(42);
|
|
13
|
+
});
|
|
14
|
+
it('accepts base64 as a node serves it', () => {
|
|
15
|
+
const ledger = decodeValidationLedger(vllBase64({ blockNumber: 100 }));
|
|
16
|
+
expect(ledger.targetBlockNumber).toBe(101);
|
|
17
|
+
});
|
|
18
|
+
it.each([
|
|
19
|
+
[0, 1],
|
|
20
|
+
[41, 42],
|
|
21
|
+
[0xfffffffd, 0xfffffffe],
|
|
22
|
+
])('targets block %i + 1 = %i', (blockNumber, expected) => {
|
|
23
|
+
expect(decodeValidationLedger(buildVll({ blockNumber })).targetBlockNumber).toBe(expected);
|
|
24
|
+
});
|
|
25
|
+
it('refuses a ledger at the uint32 ceiling rather than overflowing to zero', () => {
|
|
26
|
+
expect(() => decodeValidationLedger(buildVll({ blockNumber: 0xffffffff }))).toThrow(/maximum a uint32 can hold/u);
|
|
27
|
+
});
|
|
28
|
+
it('reads nodeNumSelf, not the list index and not the sponsor', () => {
|
|
29
|
+
const ledger = decodeValidationLedger(buildVll({
|
|
30
|
+
nodes: [
|
|
31
|
+
{ ip: '10.0.0.1', nodeNumber: 11, sponsorNumber: 99 },
|
|
32
|
+
{ ip: '10.0.0.2', nodeNumber: 3, sponsorNumber: 77 },
|
|
33
|
+
],
|
|
34
|
+
}));
|
|
35
|
+
// Index 1, node number 3, sponsor 77 — all distinguishable on purpose.
|
|
36
|
+
expect(ledger.findNode({ host: '10.0.0.2' })?.nodeNumber).toBe(3);
|
|
37
|
+
});
|
|
38
|
+
it('matches a node on host alone, ignoring the record port', () => {
|
|
39
|
+
const ledger = decodeValidationLedger(buildVll({ nodes: [{ ip: '10.0.0.1', port: 9999, nodeNumber: 4 }] }));
|
|
40
|
+
// Whatever the record's port says, a client reaches the node on 2082 — so the port
|
|
41
|
+
// must play no part in matching.
|
|
42
|
+
expect(ledger.findNode({ host: '10.0.0.1' })?.nodeNumber).toBe(4);
|
|
43
|
+
expect(ledger.findNode({ nodeNumber: 4 })?.port).toBe(9999);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
describe('rotation deadline', () => {
|
|
47
|
+
// blockNumRemove is a rotation deadline, not a departure flag: it is reset 100-355
|
|
48
|
+
// blocks ahead every time a node is promoted back into the active set.
|
|
49
|
+
it('reads blockNumRemove and flags a node inside its shutdown window', () => {
|
|
50
|
+
const ledger = decodeValidationLedger(buildVll({
|
|
51
|
+
blockNumber: 100,
|
|
52
|
+
nodes: [
|
|
53
|
+
{ ip: '10.0.0.1', nodeNumber: 1, retiresAtBlock: 300 },
|
|
54
|
+
{ ip: '10.0.0.2', nodeNumber: 2, retiresAtBlock: 101 },
|
|
55
|
+
],
|
|
56
|
+
}));
|
|
57
|
+
expect(ledger.findNode({ nodeNumber: 1 })).toMatchObject({
|
|
58
|
+
retiresAtBlock: 300,
|
|
59
|
+
retiring: false,
|
|
60
|
+
});
|
|
61
|
+
// The node refuses once blockNumRemove < currentBlock + 2, i.e. 101 < 102.
|
|
62
|
+
expect(ledger.findNode({ nodeNumber: 2 })).toMatchObject({
|
|
63
|
+
retiresAtBlock: 101,
|
|
64
|
+
retiring: true,
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
it.each([
|
|
68
|
+
[101, true],
|
|
69
|
+
[102, false],
|
|
70
|
+
[103, false],
|
|
71
|
+
])('at blockNumRemove %i the node is retiring: %s', (retiresAtBlock, retiring) => {
|
|
72
|
+
const ledger = decodeValidationLedger(buildVll({ blockNumber: 100, nodes: [{ ip: '10.0.0.1', nodeNumber: 1, retiresAtBlock }] }));
|
|
73
|
+
expect(ledger.nodes[0]?.retiring).toBe(retiring);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
describe('processing predicate', () => {
|
|
77
|
+
const ROLES = [
|
|
78
|
+
NetActorType.NET_ACTOR_TYPE_ANCHOR_NODE,
|
|
79
|
+
NetActorType.NET_ACTOR_TYPE_ANON_NODE,
|
|
80
|
+
NetActorType.NET_ACTOR_TYPE_CERT_NODE,
|
|
81
|
+
NetActorType.NET_ACTOR_TYPE_CERT_AUTH,
|
|
82
|
+
NetActorType.NET_ACTOR_TYPE_CHAIN_ADMIN,
|
|
83
|
+
NetActorType.NET_ACTOR_TYPE_RELAY,
|
|
84
|
+
NetActorType.NET_ACTOR_TYPE_TREASURY_AGENT,
|
|
85
|
+
];
|
|
86
|
+
const STATUSES = [
|
|
87
|
+
NetActorStatus.NET_ACTOR_STATUS_CHAIN_ADMIN,
|
|
88
|
+
NetActorStatus.NET_ACTOR_STATUS_HUB,
|
|
89
|
+
NetActorStatus.NET_ACTOR_STATUS_LEAVING,
|
|
90
|
+
NetActorStatus.NET_ACTOR_STATUS_LISTENING,
|
|
91
|
+
NetActorStatus.NET_ACTOR_STATUS_NODE,
|
|
92
|
+
NetActorStatus.NET_ACTOR_STATUS_READY,
|
|
93
|
+
NetActorStatus.NET_ACTOR_STATUS_RELAY,
|
|
94
|
+
NetActorStatus.NET_ACTOR_STATUS_SUSPENDED,
|
|
95
|
+
];
|
|
96
|
+
const PROCESSING_ROLES = new Set([
|
|
97
|
+
NetActorType.NET_ACTOR_TYPE_ANCHOR_NODE,
|
|
98
|
+
NetActorType.NET_ACTOR_TYPE_ANON_NODE,
|
|
99
|
+
NetActorType.NET_ACTOR_TYPE_CERT_NODE,
|
|
100
|
+
]);
|
|
101
|
+
const PROCESSING_STATUSES = new Set([
|
|
102
|
+
NetActorStatus.NET_ACTOR_STATUS_NODE,
|
|
103
|
+
NetActorStatus.NET_ACTOR_STATUS_HUB,
|
|
104
|
+
]);
|
|
105
|
+
// Pins the node's own isActive(): exactly 3 x 2 of the 7 x 8 grid accept a transaction.
|
|
106
|
+
it('marks exactly {anchor,anon,cert} x {node,hub} as processing', () => {
|
|
107
|
+
for (const type of ROLES) {
|
|
108
|
+
for (const status of STATUSES) {
|
|
109
|
+
const ledger = decodeValidationLedger(buildVll({ nodes: [{ ip: '10.0.0.1', nodeNumber: 1, type, status }] }));
|
|
110
|
+
const expected = PROCESSING_ROLES.has(type) && PROCESSING_STATUSES.has(status);
|
|
111
|
+
expect(ledger.nodes[0]?.processing).toBe(expected);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
it('reports an unknown role or status without throwing, and never as processing', () => {
|
|
116
|
+
const ledger = decodeValidationLedger(buildVll({ nodes: [{ ip: '10.0.0.1', nodeNumber: 1, type: 42 }] }));
|
|
117
|
+
expect(ledger.nodes[0]?.role).toBe('unknown');
|
|
118
|
+
expect(ledger.nodes[0]?.processing).toBe(false);
|
|
119
|
+
});
|
|
120
|
+
it('lists only the processing nodes', () => {
|
|
121
|
+
const ledger = decodeValidationLedger(buildVll({
|
|
122
|
+
nodes: [
|
|
123
|
+
{ ip: '10.0.0.1', nodeNumber: 1 },
|
|
124
|
+
{
|
|
125
|
+
ip: '10.0.0.2',
|
|
126
|
+
nodeNumber: 2,
|
|
127
|
+
type: NetActorType.NET_ACTOR_TYPE_ANCHOR_NODE,
|
|
128
|
+
status: NetActorStatus.NET_ACTOR_STATUS_LISTENING,
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
}));
|
|
132
|
+
expect(ledger.processingNodes.map((n) => n.nodeNumber)).toEqual([1]);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
describe('coin accounts', () => {
|
|
136
|
+
it('finds an asset account by id wherever it sits in the list', () => {
|
|
137
|
+
const ledger = decodeValidationLedger(buildVll({
|
|
138
|
+
accounts: [
|
|
139
|
+
{ accountId: OTHER, kind: 'asset', nonce: 1 },
|
|
140
|
+
// Target placed last, so a position-dependent read fails this test.
|
|
141
|
+
{ accountId: ACCOUNT, kind: 'asset', nonce: 17 },
|
|
142
|
+
],
|
|
143
|
+
}));
|
|
144
|
+
const found = ledger.findCoinAccount(ACCOUNT);
|
|
145
|
+
expect(found?.kind).toBe('asset');
|
|
146
|
+
expect(found?.nonce).toBe(17);
|
|
147
|
+
});
|
|
148
|
+
it('accepts a keypair-shaped ref', () => {
|
|
149
|
+
const ledger = decodeValidationLedger(buildVll({ accounts: [{ accountId: ACCOUNT, kind: 'asset', nonce: 4 }] }));
|
|
150
|
+
expect(ledger.findCoinAccount({ accountId: ACCOUNT })?.nonce).toBe(4);
|
|
151
|
+
});
|
|
152
|
+
it('returns undefined for an account the chain has never seen', () => {
|
|
153
|
+
const ledger = decodeValidationLedger(buildVll({ accounts: [] }));
|
|
154
|
+
expect(ledger.findCoinAccount(ACCOUNT)).toBeUndefined();
|
|
155
|
+
});
|
|
156
|
+
it('reports a hash-lock record as having no nonce at all', () => {
|
|
157
|
+
const ledger = decodeValidationLedger(buildVll({ accounts: [{ accountId: ACCOUNT, kind: 'hl' }] }));
|
|
158
|
+
const found = ledger.findCoinAccount(ACCOUNT);
|
|
159
|
+
expect(found?.kind).toBe('hl');
|
|
160
|
+
expect(found?.nonce).toBeUndefined();
|
|
161
|
+
});
|
|
162
|
+
it('reports a micro record with its own nonce', () => {
|
|
163
|
+
const ledger = decodeValidationLedger(buildVll({ accounts: [{ accountId: ACCOUNT, kind: 'micro', nonce: 9 }] }));
|
|
164
|
+
expect(ledger.findCoinAccount(ACCOUNT)).toMatchObject({ kind: 'micro', nonce: 9 });
|
|
165
|
+
});
|
|
166
|
+
// The union's zero value is ASSET, so an unset tag with a null pointer passes
|
|
167
|
+
// testWhich. A naive read would call initStruct and hand back nonce 0.
|
|
168
|
+
it('does not invent nonce 0 for an asset tag with no asset data', () => {
|
|
169
|
+
const ledger = decodeValidationLedger(buildVll({ accounts: [{ accountId: ACCOUNT, kind: 'asset-empty' }] }));
|
|
170
|
+
const found = ledger.findCoinAccount(ACCOUNT);
|
|
171
|
+
expect(found?.kind).toBe('unknown');
|
|
172
|
+
expect(found?.nonce).toBeUndefined();
|
|
173
|
+
});
|
|
174
|
+
it('leaves the source bytes untouched while reading that record', () => {
|
|
175
|
+
const bytes = buildVll({ accounts: [{ accountId: ACCOUNT, kind: 'asset-empty' }] });
|
|
176
|
+
const before = Uint8Array.from(bytes);
|
|
177
|
+
const ledger = decodeValidationLedger(bytes);
|
|
178
|
+
ledger.findCoinAccount(ACCOUNT);
|
|
179
|
+
expect(Array.from(bytes)).toEqual(Array.from(before));
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
describe('metadata limits', () => {
|
|
183
|
+
it('reads currentValue, not the minimum or the maximum', () => {
|
|
184
|
+
const ledger = decodeValidationLedger(buildVll({ metadataVarNum: 4, metadataVarBytes: 64 }));
|
|
185
|
+
expect(ledger.metadataLimits).toEqual({ maxEntries: 4, maxBytesPerEntry: 64 });
|
|
186
|
+
});
|
|
187
|
+
it('reports no limits when the chain does not publish both', () => {
|
|
188
|
+
const ledger = decodeValidationLedger(buildVll({ metadataVarBytes: null }));
|
|
189
|
+
expect(ledger.metadataLimits).toBeUndefined();
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
describe('malformed input', () => {
|
|
193
|
+
it('rejects an empty ledger with an explanation', () => {
|
|
194
|
+
expect(() => decodeValidationLedger('')).toThrow(/empty/u);
|
|
195
|
+
});
|
|
196
|
+
it('rejects something that is not base64 at all', () => {
|
|
197
|
+
expect(() => decodeValidationLedger('<!DOCTYPE html><html>')).toThrow(/not valid base64/u);
|
|
198
|
+
});
|
|
199
|
+
it('rejects a ledger with no net actors or parameters', () => {
|
|
200
|
+
const empty = buildVll({ nodes: [], metadataVarNum: null, metadataVarBytes: null });
|
|
201
|
+
expect(() => decodeValidationLedger(empty)).toThrow(/does not look like one/u);
|
|
202
|
+
});
|
|
203
|
+
it.each([
|
|
204
|
+
['empty', ''],
|
|
205
|
+
['not base64', 'not base64!!'],
|
|
206
|
+
['valid base64, invalid capnp', Buffer.from('nonsense').toString('base64')],
|
|
207
|
+
])('throws a typed error for %s', (_label, source) => {
|
|
208
|
+
expect(() => decodeValidationLedger(source)).toThrow(expect.objectContaining({ name: 'GeeqError' }));
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
describe('snapshot semantics', () => {
|
|
212
|
+
// capnp-ts decrements a per-Message traversal budget on every pointer dereference and
|
|
213
|
+
// never resets it. A retained handle rescanned per transaction eventually throws.
|
|
214
|
+
it('survives thousands of lookups against a large ledger', () => {
|
|
215
|
+
const accounts = Array.from({ length: 5000 }, (_unused, index) => {
|
|
216
|
+
const accountId = new Uint8Array(32);
|
|
217
|
+
accountId[0] = index & 0xff;
|
|
218
|
+
accountId[1] = (index >> 8) & 0xff;
|
|
219
|
+
return { accountId, kind: 'asset', nonce: index };
|
|
220
|
+
});
|
|
221
|
+
const ledger = decodeValidationLedger(buildVll({ accounts }));
|
|
222
|
+
expect(ledger.coinAccountCount).toBe(5000);
|
|
223
|
+
for (let round = 0; round < 200; round += 1) {
|
|
224
|
+
expect(ledger.findCoinAccount(accounts[round].accountId)?.nonce).toBe(round);
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
it('keeps the account table out of its JSON form', () => {
|
|
228
|
+
const ledger = decodeValidationLedger(buildVll({ accounts: [{ accountId: ACCOUNT, kind: 'asset', nonce: 1 }] }));
|
|
229
|
+
const json = JSON.parse(JSON.stringify(ledger));
|
|
230
|
+
expect(json['accounts']).toBeUndefined();
|
|
231
|
+
expect(json['coinAccountCount']).toBe(1);
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
//# sourceMappingURL=ledger.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ledger.test.js","sourceRoot":"","sources":["../../tests/ledger.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { describe, expect, it, beforeAll } from '@jest/globals';
|
|
2
|
+
import { MNEMONIC_WORD_COUNTS, generateMnemonic, initGeeq, keypairFromMnemonic, normalizeMnemonic, validateMnemonic, } from '../src/index';
|
|
3
|
+
describe('generateMnemonic', () => {
|
|
4
|
+
it('returns 12 words by default', () => {
|
|
5
|
+
const mnemonic = generateMnemonic();
|
|
6
|
+
expect(mnemonic.split(' ')).toHaveLength(12);
|
|
7
|
+
});
|
|
8
|
+
it.each(MNEMONIC_WORD_COUNTS)('returns %i words on request', (words) => {
|
|
9
|
+
expect(generateMnemonic({ words }).split(' ')).toHaveLength(words);
|
|
10
|
+
});
|
|
11
|
+
it('returns a different phrase each time', () => {
|
|
12
|
+
const phrases = new Set(Array.from({ length: 25 }, () => generateMnemonic()));
|
|
13
|
+
expect(phrases.size).toBe(25);
|
|
14
|
+
});
|
|
15
|
+
it('produces phrases that validate', () => {
|
|
16
|
+
for (const words of MNEMONIC_WORD_COUNTS) {
|
|
17
|
+
expect(validateMnemonic(generateMnemonic({ words }))).toBe(true);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
it('rejects an unsupported word count', () => {
|
|
21
|
+
expect(() => generateMnemonic({ words: 13 })).toThrow(/words must be one of/);
|
|
22
|
+
});
|
|
23
|
+
it('needs no engine — it is pure JavaScript', () => {
|
|
24
|
+
// No initGeeq() anywhere in this describe block.
|
|
25
|
+
expect(validateMnemonic(generateMnemonic())).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
describe('validateMnemonic', () => {
|
|
29
|
+
it('accepts a known-good phrase', () => {
|
|
30
|
+
expect(validateMnemonic('legal winner thank year wave sausage worth useful legal winner thank yellow')).toBe(true);
|
|
31
|
+
});
|
|
32
|
+
it('rejects a bad checksum', () => {
|
|
33
|
+
// Valid words, wrong checksum: last word swapped.
|
|
34
|
+
expect(validateMnemonic('legal winner thank year wave sausage worth useful legal winner thank zoo')).toBe(false);
|
|
35
|
+
});
|
|
36
|
+
it.each([
|
|
37
|
+
['too few words', 'legal winner thank'],
|
|
38
|
+
['a word not in the list', 'legal winner thank year wave sausage worth useful legal winner thank notaword'],
|
|
39
|
+
['empty', ''],
|
|
40
|
+
['whitespace', ' '],
|
|
41
|
+
])('rejects %s', (_label, phrase) => {
|
|
42
|
+
expect(validateMnemonic(phrase)).toBe(false);
|
|
43
|
+
});
|
|
44
|
+
it('tolerates messy whitespace and casing', () => {
|
|
45
|
+
expect(validateMnemonic(' Legal winner\tthank\nyear wave sausage worth useful legal winner thank YELLOW ')).toBe(true);
|
|
46
|
+
});
|
|
47
|
+
it('never throws on hostile input', () => {
|
|
48
|
+
for (const bad of [null, undefined, 42, {}, []]) {
|
|
49
|
+
expect(() => validateMnemonic(bad)).not.toThrow();
|
|
50
|
+
expect(validateMnemonic(bad)).toBe(false);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
describe('normalizeMnemonic', () => {
|
|
55
|
+
it('collapses whitespace and lowercases', () => {
|
|
56
|
+
expect(normalizeMnemonic(' Legal WINNER\tthank\n ')).toBe('legal winner thank');
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe('generate -> derive round trip', () => {
|
|
60
|
+
beforeAll(async () => {
|
|
61
|
+
await initGeeq();
|
|
62
|
+
});
|
|
63
|
+
it('every generated length derives a usable keypair', async () => {
|
|
64
|
+
for (const words of MNEMONIC_WORD_COUNTS) {
|
|
65
|
+
const mnemonic = generateMnemonic({ words });
|
|
66
|
+
const keypair = await keypairFromMnemonic(mnemonic);
|
|
67
|
+
expect(keypair.publicKey).toHaveLength(32);
|
|
68
|
+
expect(keypair.accountId).toHaveLength(32);
|
|
69
|
+
expect(keypair.getAddress({ chainNumber: 1 }).length).toBeGreaterThan(0);
|
|
70
|
+
keypair.dispose();
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
it('is deterministic — the same phrase restores the same wallet', async () => {
|
|
74
|
+
const mnemonic = generateMnemonic();
|
|
75
|
+
const first = await keypairFromMnemonic(mnemonic);
|
|
76
|
+
const second = await keypairFromMnemonic(mnemonic);
|
|
77
|
+
expect(Buffer.from(second.publicKey)).toEqual(Buffer.from(first.publicKey));
|
|
78
|
+
first.dispose();
|
|
79
|
+
second.dispose();
|
|
80
|
+
});
|
|
81
|
+
it('restores the same wallet from a messily pasted phrase', async () => {
|
|
82
|
+
const mnemonic = generateMnemonic();
|
|
83
|
+
const clean = await keypairFromMnemonic(mnemonic);
|
|
84
|
+
const messy = await keypairFromMnemonic(` ${mnemonic.toUpperCase().replace(/ /g, ' ')} `);
|
|
85
|
+
expect(Buffer.from(messy.publicKey)).toEqual(Buffer.from(clean.publicKey));
|
|
86
|
+
clean.dispose();
|
|
87
|
+
messy.dispose();
|
|
88
|
+
});
|
|
89
|
+
it('different phrases give different wallets', async () => {
|
|
90
|
+
const a = await keypairFromMnemonic(generateMnemonic());
|
|
91
|
+
const b = await keypairFromMnemonic(generateMnemonic());
|
|
92
|
+
expect(Buffer.from(a.publicKey)).not.toEqual(Buffer.from(b.publicKey));
|
|
93
|
+
a.dispose();
|
|
94
|
+
b.dispose();
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
//# sourceMappingURL=mnemonic.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mnemonic.test.js","sourceRoot":"","sources":["../../tests/mnemonic.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|