@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,34 @@
|
|
|
1
|
+
import type { ParamAcctRec } from '../capnp/paramAcctRec.capnp';
|
|
2
|
+
import type { GeeqMetadataLimits } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Read the metadata limits a chain publishes in its parameter account list.
|
|
5
|
+
*
|
|
6
|
+
* `metadataVarNum` caps the NUMBER of entries and `metadataVarBytes` caps the bytes in
|
|
7
|
+
* ONE entry; there is no aggregate cap. The node enforces both at submit time, so
|
|
8
|
+
* having them here is what lets a transaction be rejected before it is signed rather
|
|
9
|
+
* than after it is sent.
|
|
10
|
+
*
|
|
11
|
+
* Returns `undefined` when either parameter is absent. A chain that does not publish
|
|
12
|
+
* them is a schema difference, not a caller error, so the preflight is skipped and the
|
|
13
|
+
* node stays the authority.
|
|
14
|
+
*
|
|
15
|
+
* `metadataFixedNum` / `metadataFixedBytes` exist in the schema but are read nowhere in
|
|
16
|
+
* the current node, so they are ignored here too.
|
|
17
|
+
*/
|
|
18
|
+
export declare function readMetadataLimits(records: readonly ParamAcctRec[]): GeeqMetadataLimits | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* The smallest transfer this chain will accept, in pennies: `minTxAmt × geeqNorm + 1`.
|
|
21
|
+
*
|
|
22
|
+
* The node rejects anything below `minTxAmt × geeqNorm` (geeq_node_core, Transaction
|
|
23
|
+
* Amount Conformity); the Geeq wallet asks for one penny more, and so does this. Knowing
|
|
24
|
+
* it here turns a rejected transaction into a message before it is signed.
|
|
25
|
+
*
|
|
26
|
+
* Returns `undefined` when either parameter is missing, in which case nothing is checked
|
|
27
|
+
* and the node stays the authority.
|
|
28
|
+
*/
|
|
29
|
+
export declare function readMinimumTransfer(records: readonly ParamAcctRec[]): bigint | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* The chain's `geeqNorm` parameter: the multiplier behind its minimum transfer and every
|
|
32
|
+
* fee. `undefined` when the chain does not publish it.
|
|
33
|
+
*/
|
|
34
|
+
export declare function readGeeqNorm(records: readonly ParamAcctRec[]): bigint | undefined;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { uint64ToPennies } from '../amount';
|
|
2
|
+
/**
|
|
3
|
+
* Read the metadata limits a chain publishes in its parameter account list.
|
|
4
|
+
*
|
|
5
|
+
* `metadataVarNum` caps the NUMBER of entries and `metadataVarBytes` caps the bytes in
|
|
6
|
+
* ONE entry; there is no aggregate cap. The node enforces both at submit time, so
|
|
7
|
+
* having them here is what lets a transaction be rejected before it is signed rather
|
|
8
|
+
* than after it is sent.
|
|
9
|
+
*
|
|
10
|
+
* Returns `undefined` when either parameter is absent. A chain that does not publish
|
|
11
|
+
* them is a schema difference, not a caller error, so the preflight is skipped and the
|
|
12
|
+
* node stays the authority.
|
|
13
|
+
*
|
|
14
|
+
* `metadataFixedNum` / `metadataFixedBytes` exist in the schema but are read nowhere in
|
|
15
|
+
* the current node, so they are ignored here too.
|
|
16
|
+
*/
|
|
17
|
+
export function readMetadataLimits(records) {
|
|
18
|
+
let maxEntries;
|
|
19
|
+
let maxBytesPerEntry;
|
|
20
|
+
for (const record of records) {
|
|
21
|
+
const param = record.getParamType();
|
|
22
|
+
if (maxEntries === undefined && param.isMetadataVarNum() && param.hasMetadataVarNum()) {
|
|
23
|
+
maxEntries = param.getMetadataVarNum().getCurrentValue();
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (maxBytesPerEntry === undefined &&
|
|
27
|
+
param.isMetadataVarBytes() &&
|
|
28
|
+
param.hasMetadataVarBytes()) {
|
|
29
|
+
maxBytesPerEntry = param.getMetadataVarBytes().getCurrentValue();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (maxEntries === undefined || maxBytesPerEntry === undefined)
|
|
33
|
+
return undefined;
|
|
34
|
+
return Object.freeze({ maxEntries, maxBytesPerEntry });
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The smallest transfer this chain will accept, in pennies: `minTxAmt × geeqNorm + 1`.
|
|
38
|
+
*
|
|
39
|
+
* The node rejects anything below `minTxAmt × geeqNorm` (geeq_node_core, Transaction
|
|
40
|
+
* Amount Conformity); the Geeq wallet asks for one penny more, and so does this. Knowing
|
|
41
|
+
* it here turns a rejected transaction into a message before it is signed.
|
|
42
|
+
*
|
|
43
|
+
* Returns `undefined` when either parameter is missing, in which case nothing is checked
|
|
44
|
+
* and the node stays the authority.
|
|
45
|
+
*/
|
|
46
|
+
export function readMinimumTransfer(records) {
|
|
47
|
+
const geeqNorm = readGeeqNorm(records);
|
|
48
|
+
for (const record of records) {
|
|
49
|
+
const param = record.getParamType();
|
|
50
|
+
if (param.isMinTxAmt() && param.hasMinTxAmt()) {
|
|
51
|
+
if (geeqNorm === undefined)
|
|
52
|
+
return undefined;
|
|
53
|
+
return uint64ToPennies(param.getMinTxAmt().getCurrentValue()) * geeqNorm + 1n;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The chain's `geeqNorm` parameter: the multiplier behind its minimum transfer and every
|
|
60
|
+
* fee. `undefined` when the chain does not publish it.
|
|
61
|
+
*/
|
|
62
|
+
export function readGeeqNorm(records) {
|
|
63
|
+
for (const record of records) {
|
|
64
|
+
const param = record.getParamType();
|
|
65
|
+
if (param.isGeeqNorm() && param.hasGeeqNorm()) {
|
|
66
|
+
return uint64ToPennies(param.getGeeqNorm().getCurrentValue());
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=params.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"params.js","sourceRoot":"","sources":["../../../src/ledger/params.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAG3C;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAgC;IAEhC,IAAI,UAA8B,CAAA;IAClC,IAAI,gBAAoC,CAAA;IAExC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,EAAE,CAAA;QACnC,IAAI,UAAU,KAAK,SAAS,IAAI,KAAK,CAAC,gBAAgB,EAAE,IAAI,KAAK,CAAC,iBAAiB,EAAE,EAAE,CAAC;YACtF,UAAU,GAAG,KAAK,CAAC,iBAAiB,EAAE,CAAC,eAAe,EAAE,CAAA;YACxD,SAAQ;QACV,CAAC;QACD,IACE,gBAAgB,KAAK,SAAS;YAC9B,KAAK,CAAC,kBAAkB,EAAE;YAC1B,KAAK,CAAC,mBAAmB,EAAE,EAC3B,CAAC;YACD,gBAAgB,GAAG,KAAK,CAAC,mBAAmB,EAAE,CAAC,eAAe,EAAE,CAAA;QAClE,CAAC;IACH,CAAC;IAED,IAAI,UAAU,KAAK,SAAS,IAAI,gBAAgB,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAChF,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,gBAAgB,EAAE,CAAC,CAAA;AACxD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAgC;IAEhC,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;IACtC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,EAAE,CAAA;QACnC,IAAI,KAAK,CAAC,UAAU,EAAE,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YAC9C,IAAI,QAAQ,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAA;YAC5C,OAAO,eAAe,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,eAAe,EAAE,CAAC,GAAG,QAAQ,GAAG,EAAE,CAAA;QAC/E,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,OAAgC;IAC3D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,EAAE,CAAA;QACnC,IAAI,KAAK,CAAC,UAAU,EAAE,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YAC9C,OAAO,eAAe,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,eAAe,EAAE,CAAC,CAAA;QAC/D,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ProxyAcctRec } from '../capnp/proxyAcctRec.capnp';
|
|
2
|
+
/** Which kind of proxy a record is. Only `'nft-mint'` is read further. */
|
|
3
|
+
export type GeeqProxyKind = 'nft-mint' | 'token-mint' | 'funding' | 'multisig' | 'dce' | 'unknown';
|
|
4
|
+
/** One proxy account record, as plain values. */
|
|
5
|
+
export interface GeeqProxyAccount {
|
|
6
|
+
readonly accountId: Uint8Array;
|
|
7
|
+
readonly kind: GeeqProxyKind;
|
|
8
|
+
/**
|
|
9
|
+
* The proxy's own nonce. A mint through it spends this one, not the admin's — a proxy
|
|
10
|
+
* carries its nonce on the record itself.
|
|
11
|
+
*/
|
|
12
|
+
readonly nonce: number;
|
|
13
|
+
/** Balance in pennies. Use `formatGeeq` to show it. */
|
|
14
|
+
readonly balance: bigint;
|
|
15
|
+
/** The account id of the only key that can sign for it. Read for NFT mint proxies only. */
|
|
16
|
+
readonly admin: Uint8Array | undefined;
|
|
17
|
+
}
|
|
18
|
+
/** What we keep per proxy. The id is the map key, so it is not repeated here. */
|
|
19
|
+
export type ProxyAccountFacts = Omit<GeeqProxyAccount, 'accountId'>;
|
|
20
|
+
/**
|
|
21
|
+
* Read a proxy record's kind and admin.
|
|
22
|
+
*
|
|
23
|
+
* The same zero-value trap as a coin account: `DCE` is the union's zero value, so every
|
|
24
|
+
* arm is checked with `isX()` before anything is read from it.
|
|
25
|
+
*/
|
|
26
|
+
export declare function readProxyAccount(record: ProxyAcctRec): ProxyAccountFacts;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { uint64ToPennies } from '../amount';
|
|
2
|
+
/**
|
|
3
|
+
* Read a proxy record's kind and admin.
|
|
4
|
+
*
|
|
5
|
+
* The same zero-value trap as a coin account: `DCE` is the union's zero value, so every
|
|
6
|
+
* arm is checked with `isX()` before anything is read from it.
|
|
7
|
+
*/
|
|
8
|
+
export function readProxyAccount(record) {
|
|
9
|
+
const recType = record.getRecType();
|
|
10
|
+
const nonce = record.getNonce();
|
|
11
|
+
const balance = uint64ToPennies(record.getAmtCoin());
|
|
12
|
+
if (recType.isNftMint() && recType.hasNftMint()) {
|
|
13
|
+
const admin = new Uint8Array(recType.getNftMint().getAcctNumAdminUser().toArrayBuffer());
|
|
14
|
+
return { kind: 'nft-mint', nonce, balance, admin };
|
|
15
|
+
}
|
|
16
|
+
const kind = recType.isTokenMint()
|
|
17
|
+
? 'token-mint'
|
|
18
|
+
: recType.isFunding()
|
|
19
|
+
? 'funding'
|
|
20
|
+
: recType.isMultisig()
|
|
21
|
+
? 'multisig'
|
|
22
|
+
: recType.isDce() && recType.hasDce()
|
|
23
|
+
? 'dce'
|
|
24
|
+
: 'unknown';
|
|
25
|
+
return { kind, nonce, balance, admin: undefined };
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=proxy-accounts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-accounts.js","sourceRoot":"","sources":["../../../src/ledger/proxy-accounts.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAuB3C;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAoB;IACnD,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,CAAA;IACnC,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAA;IAC/B,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAA;IAEpD,IAAI,OAAO,CAAC,SAAS,EAAE,IAAI,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,mBAAmB,EAAE,CAAC,aAAa,EAAE,CAAC,CAAA;QACxF,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;IACpD,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,EAAE;QAChC,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE;YACnB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE;gBACpB,CAAC,CAAC,UAAU;gBACZ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,OAAO,CAAC,MAAM,EAAE;oBACnC,CAAC,CAAC,KAAK;oBACP,CAAC,CAAC,SAAS,CAAA;IACnB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;AACnD,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { RequestOptions } from './transport';
|
|
2
|
+
/** How the directory classifies a node. Only `'active'` processes transactions. */
|
|
3
|
+
export type GeeqNodeKind = 'active' | 'relay' | 'listener' | 'chain-admin' | 'none' | 'unknown';
|
|
4
|
+
/** One chain the directory knows about. */
|
|
5
|
+
export interface GeeqDiscoveredChain {
|
|
6
|
+
/** The directory's own row id, which every other directory route calls `systemId`. */
|
|
7
|
+
readonly systemId: number;
|
|
8
|
+
/** The protocol chain number — what a transaction carries and a node checks. */
|
|
9
|
+
readonly chainNumber: number;
|
|
10
|
+
readonly name: string | undefined;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* One node the directory knows about.
|
|
14
|
+
*
|
|
15
|
+
* Note what is **missing**: a node number. The directory can say where a node is but
|
|
16
|
+
* not who it is in the chain's own net actor list, so the ledger read is still the only
|
|
17
|
+
* way to learn the number a transaction must carry.
|
|
18
|
+
*/
|
|
19
|
+
export interface GeeqDiscoveredNode {
|
|
20
|
+
readonly host: string;
|
|
21
|
+
readonly kind: GeeqNodeKind;
|
|
22
|
+
/** The directory's own lifecycle state — `new`, `ready`, `stopped`. */
|
|
23
|
+
readonly status: string;
|
|
24
|
+
/** Where to reach it. Always the client port; the directory's own port is internal. */
|
|
25
|
+
readonly url: string;
|
|
26
|
+
}
|
|
27
|
+
/** Every chain the directory knows about. */
|
|
28
|
+
export declare function listChains(origin: string, request: RequestOptions): Promise<GeeqDiscoveredChain[]>;
|
|
29
|
+
export interface NodeAddressing {
|
|
30
|
+
/** Scheme for the node URLs. Defaults to the directory's own. */
|
|
31
|
+
readonly protocol?: string | undefined;
|
|
32
|
+
/** Client port. Defaults to {@link GEEQ_NODE_PORT}; override only for local setups. */
|
|
33
|
+
readonly port?: number | undefined;
|
|
34
|
+
}
|
|
35
|
+
/** Every node the directory lists for one chain. */
|
|
36
|
+
export declare function listNodes(origin: string, systemId: number, request: RequestOptions, addressing?: NodeAddressing): Promise<GeeqDiscoveredNode[]>;
|
|
37
|
+
export interface DiscoverOptions extends NodeAddressing {
|
|
38
|
+
readonly origin: string;
|
|
39
|
+
/** Select the chain by the name the directory gives it. Matched case-insensitively. */
|
|
40
|
+
readonly chainName?: string | undefined;
|
|
41
|
+
/** Select by protocol chain number, or — alongside `chainName` — assert it. */
|
|
42
|
+
readonly chainNumber?: number | undefined;
|
|
43
|
+
readonly request: RequestOptions;
|
|
44
|
+
}
|
|
45
|
+
export interface Discovery {
|
|
46
|
+
readonly chain: GeeqDiscoveredChain;
|
|
47
|
+
/** Every node listed for the chain, in directory order. */
|
|
48
|
+
readonly nodes: readonly GeeqDiscoveredNode[];
|
|
49
|
+
/** Those that will actually take a transaction. */
|
|
50
|
+
readonly usable: readonly GeeqDiscoveredNode[];
|
|
51
|
+
}
|
|
52
|
+
/** True when the directory says this node is an active one that has not been stopped. */
|
|
53
|
+
export declare function isUsable(node: GeeqDiscoveredNode): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Find a chain in the directory and list its nodes.
|
|
56
|
+
*
|
|
57
|
+
* This reads two routes and nothing else. The directory is a deployment control plane:
|
|
58
|
+
* it has no authentication, and its other routes create and destroy machines and serve
|
|
59
|
+
* private keys. Treat every value it returns as a hint about *where* to look, never as
|
|
60
|
+
* authority about the chain itself — that comes from the ledger.
|
|
61
|
+
*/
|
|
62
|
+
export declare function discover(options: DiscoverOptions): Promise<Discovery>;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { invalidArgument, nodeUnusable } from '../errors';
|
|
2
|
+
import { GEEQ_NODE_PORT } from '../chain/select';
|
|
3
|
+
import { chainsRoute, nodesRoute } from './routes';
|
|
4
|
+
import { requestText } from './transport';
|
|
5
|
+
const KINDS = new Set([
|
|
6
|
+
'active',
|
|
7
|
+
'relay',
|
|
8
|
+
'listener',
|
|
9
|
+
'chain-admin',
|
|
10
|
+
'none',
|
|
11
|
+
]);
|
|
12
|
+
function resultOf(body, url) {
|
|
13
|
+
let parsed;
|
|
14
|
+
try {
|
|
15
|
+
parsed = JSON.parse(body);
|
|
16
|
+
}
|
|
17
|
+
catch (cause) {
|
|
18
|
+
throw nodeUnusable(`The directory at ${url} did not answer with JSON. A proxy or login page in front ` +
|
|
19
|
+
'of it is the usual reason.', cause);
|
|
20
|
+
}
|
|
21
|
+
const result = parsed?.result;
|
|
22
|
+
if (!Array.isArray(result)) {
|
|
23
|
+
throw nodeUnusable(`The directory at ${url} answered without a "result" array, so it does not look ` +
|
|
24
|
+
'like a Geeq node directory.');
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
/** Every chain the directory knows about. */
|
|
29
|
+
export async function listChains(origin, request) {
|
|
30
|
+
const url = chainsRoute(origin);
|
|
31
|
+
const rows = resultOf(await requestText(url, request), url);
|
|
32
|
+
return rows
|
|
33
|
+
.map((row) => row)
|
|
34
|
+
.filter((row) => typeof row.id === 'number' && typeof row.chainNumber === 'number')
|
|
35
|
+
.map((row) => Object.freeze({
|
|
36
|
+
systemId: row.id,
|
|
37
|
+
chainNumber: row.chainNumber,
|
|
38
|
+
name: typeof row.name === 'string' ? row.name : undefined,
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
/** Every node the directory lists for one chain. */
|
|
42
|
+
export async function listNodes(origin, systemId, request, addressing = {}) {
|
|
43
|
+
const protocol = addressing.protocol ?? new URL(origin).protocol;
|
|
44
|
+
const port = addressing.port ?? GEEQ_NODE_PORT;
|
|
45
|
+
const url = nodesRoute(origin, systemId);
|
|
46
|
+
const rows = resultOf(await requestText(url, request), url);
|
|
47
|
+
return rows
|
|
48
|
+
.map((row) => row)
|
|
49
|
+
.filter((row) => typeof row.ip === 'string' && row.ip !== '')
|
|
50
|
+
.map((row) => {
|
|
51
|
+
const kind = typeof row.type === 'string' && KINDS.has(row.type) ? row.type : 'unknown';
|
|
52
|
+
return Object.freeze({
|
|
53
|
+
host: row.ip,
|
|
54
|
+
kind: kind,
|
|
55
|
+
status: typeof row.status === 'string' ? row.status : 'unknown',
|
|
56
|
+
// The directory reports the node's own internal listener, which is not where
|
|
57
|
+
// clients connect, so its port field is deliberately ignored in favour of the
|
|
58
|
+
// one port every node answers on.
|
|
59
|
+
url: `${protocol}//${row.ip}:${port}`,
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/** True when the directory says this node is an active one that has not been stopped. */
|
|
64
|
+
export function isUsable(node) {
|
|
65
|
+
return node.kind === 'active' && node.status !== 'stopped';
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Find a chain in the directory and list its nodes.
|
|
69
|
+
*
|
|
70
|
+
* This reads two routes and nothing else. The directory is a deployment control plane:
|
|
71
|
+
* it has no authentication, and its other routes create and destroy machines and serve
|
|
72
|
+
* private keys. Treat every value it returns as a hint about *where* to look, never as
|
|
73
|
+
* authority about the chain itself — that comes from the ledger.
|
|
74
|
+
*/
|
|
75
|
+
export async function discover(options) {
|
|
76
|
+
const chains = await listChains(options.origin, options.request);
|
|
77
|
+
if (chains.length === 0) {
|
|
78
|
+
throw nodeUnusable(`The directory at ${options.origin} lists no chains.`);
|
|
79
|
+
}
|
|
80
|
+
const listed = chains
|
|
81
|
+
.map((c) => `${c.name ?? '(unnamed)'} (chain ${c.chainNumber})`)
|
|
82
|
+
.join(', ');
|
|
83
|
+
let chain;
|
|
84
|
+
if (options.chainName !== undefined) {
|
|
85
|
+
// Names are what a person types, so match them the way a person means them.
|
|
86
|
+
const wanted = options.chainName.trim().toLowerCase();
|
|
87
|
+
const matches = chains.filter((c) => c.name?.trim().toLowerCase() === wanted);
|
|
88
|
+
if (matches.length === 0) {
|
|
89
|
+
throw invalidArgument(`The directory at ${options.origin} has no chain named ` +
|
|
90
|
+
`${JSON.stringify(options.chainName)}. Available: ${listed}.`);
|
|
91
|
+
}
|
|
92
|
+
if (matches.length > 1) {
|
|
93
|
+
throw invalidArgument(`The directory at ${options.origin} lists ${matches.length} chains named ` +
|
|
94
|
+
`${JSON.stringify(options.chainName)} (numbers ` +
|
|
95
|
+
`${matches.map((c) => c.chainNumber).join(', ')}), so the name does not identify ` +
|
|
96
|
+
'one. Select it by chainNumber instead.');
|
|
97
|
+
}
|
|
98
|
+
chain = matches[0];
|
|
99
|
+
}
|
|
100
|
+
else if (options.chainNumber !== undefined) {
|
|
101
|
+
chain = chains.find((c) => c.chainNumber === options.chainNumber);
|
|
102
|
+
if (chain === undefined) {
|
|
103
|
+
throw invalidArgument(`The directory at ${options.origin} does not list chain ${options.chainNumber}. ` +
|
|
104
|
+
`Available: ${listed}.`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
if (chains.length > 1) {
|
|
109
|
+
throw invalidArgument(`The directory at ${options.origin} lists ${chains.length} chains, so chainName ` +
|
|
110
|
+
`or chainNumber is required to choose one. Available: ${listed}.`);
|
|
111
|
+
}
|
|
112
|
+
chain = chains[0];
|
|
113
|
+
}
|
|
114
|
+
const resolved = chain;
|
|
115
|
+
// A name and a number together are an assertion, not two ways of choosing.
|
|
116
|
+
if (options.chainName !== undefined &&
|
|
117
|
+
options.chainNumber !== undefined &&
|
|
118
|
+
resolved.chainNumber !== options.chainNumber) {
|
|
119
|
+
throw invalidArgument(`The directory at ${options.origin} says ${JSON.stringify(options.chainName)} is ` +
|
|
120
|
+
`chain ${resolved.chainNumber}, but chainNumber was given as ` +
|
|
121
|
+
`${options.chainNumber}. Drop one of the two.`);
|
|
122
|
+
}
|
|
123
|
+
const nodes = await listNodes(options.origin, resolved.systemId, options.request, {
|
|
124
|
+
...(options.protocol === undefined ? {} : { protocol: options.protocol }),
|
|
125
|
+
...(options.port === undefined ? {} : { port: options.port }),
|
|
126
|
+
});
|
|
127
|
+
const usable = nodes.filter(isUsable);
|
|
128
|
+
if (usable.length === 0) {
|
|
129
|
+
const seen = nodes.map((n) => `${n.host} (${n.kind}/${n.status})`).join(', ');
|
|
130
|
+
throw nodeUnusable(`The directory at ${options.origin} lists no node for chain ${resolved.chainNumber} ` +
|
|
131
|
+
'that is active and running. Only an active node processes transactions. ' +
|
|
132
|
+
(seen === '' ? 'It listed none at all.' : `It listed: ${seen}.`));
|
|
133
|
+
}
|
|
134
|
+
return Object.freeze({ chain: resolved, nodes: Object.freeze([...nodes]), usable: Object.freeze(usable) });
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../../src/net/discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { GeeqTransport } from './transport';
|
|
2
|
+
/** A transaction as a block explorer reports it, field for field. */
|
|
3
|
+
export interface GeeqExplorerTransaction {
|
|
4
|
+
/** Hex — the form the explorer files transactions under. */
|
|
5
|
+
readonly refHash: string;
|
|
6
|
+
/** The transaction's kind, such as `coin`. */
|
|
7
|
+
readonly type: string;
|
|
8
|
+
/** The explorer's verdict on it. */
|
|
9
|
+
readonly status: string;
|
|
10
|
+
readonly block: number;
|
|
11
|
+
readonly chainName: string;
|
|
12
|
+
readonly chainNumber: number;
|
|
13
|
+
/** The sender's wallet address. */
|
|
14
|
+
readonly from: string;
|
|
15
|
+
readonly senderType: string;
|
|
16
|
+
/** The receiver's wallet address, or empty when it has none. */
|
|
17
|
+
readonly to: string;
|
|
18
|
+
readonly receiverType: string;
|
|
19
|
+
readonly publicKey: string;
|
|
20
|
+
readonly signature: string;
|
|
21
|
+
readonly createdAt: string;
|
|
22
|
+
readonly fee: string;
|
|
23
|
+
readonly acctNumApp?: string;
|
|
24
|
+
/** What it moved — coin, tokens, NFTs — with amounts as decimal strings. */
|
|
25
|
+
readonly values: readonly {
|
|
26
|
+
readonly type: string;
|
|
27
|
+
readonly value: string;
|
|
28
|
+
readonly name?: string;
|
|
29
|
+
}[];
|
|
30
|
+
/** An attestation's hash and metadata. */
|
|
31
|
+
readonly payload?: {
|
|
32
|
+
readonly attestationHash: string;
|
|
33
|
+
readonly metadata: readonly string[];
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export interface ExplorerTransactionRequest {
|
|
37
|
+
/** The explorer's base URL, such as `https://blkexp.geeq-test.io`. */
|
|
38
|
+
readonly explorerUrl: string | URL;
|
|
39
|
+
/**
|
|
40
|
+
* The transaction's refHash in base64 — what `transactionIdOf(tx)` returns and socket
|
|
41
|
+
* status events carry. It is sent to the explorer as hex.
|
|
42
|
+
*/
|
|
43
|
+
readonly refHash: string;
|
|
44
|
+
/** Defaults to `globalThis.fetch`. */
|
|
45
|
+
readonly transport?: GeeqTransport;
|
|
46
|
+
/** Defaults to 10000. */
|
|
47
|
+
readonly timeoutMs?: number;
|
|
48
|
+
readonly signal?: AbortSignal;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Look a transaction up in a block explorer by its refHash.
|
|
52
|
+
*
|
|
53
|
+
* Resolves `null` when the explorer does not have it — not indexed yet, or never put in a
|
|
54
|
+
* block. The explorer only knows a transaction once a block has decided it, so for one
|
|
55
|
+
* you have just sent, the node socket answers first.
|
|
56
|
+
*/
|
|
57
|
+
export declare function getExplorerTransaction(request: ExplorerTransactionRequest): Promise<GeeqExplorerTransaction | null>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { GeeqError, invalidArgument, nodeUnusable } from '../errors';
|
|
2
|
+
import { fromBase64 } from '../encoding/base64';
|
|
3
|
+
import { toHex } from '../encoding/hex';
|
|
4
|
+
import { explorerTransactionRoute } from './routes';
|
|
5
|
+
import { defaultTransport, requestText } from './transport';
|
|
6
|
+
const DEFAULT_TIMEOUT_MS = 10_000;
|
|
7
|
+
const HASH_BYTES = 32;
|
|
8
|
+
/** What the explorer answers, with HTTP 500, for a refHash it does not have. */
|
|
9
|
+
const NOT_FOUND = 'Transaction does not exist';
|
|
10
|
+
function explorerBase(explorerUrl) {
|
|
11
|
+
let url;
|
|
12
|
+
try {
|
|
13
|
+
url = new URL(String(explorerUrl));
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
url = undefined;
|
|
17
|
+
}
|
|
18
|
+
if (url === undefined || (url.protocol !== 'https:' && url.protocol !== 'http:')) {
|
|
19
|
+
throw invalidArgument('explorerUrl must be an absolute http(s) URL, such as https://blkexp.geeq-test.io, ' +
|
|
20
|
+
`received ${JSON.stringify(String(explorerUrl))}.`);
|
|
21
|
+
}
|
|
22
|
+
return `${url.origin}${url.pathname.replace(/\/+$/u, '')}`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Look a transaction up in a block explorer by its refHash.
|
|
26
|
+
*
|
|
27
|
+
* Resolves `null` when the explorer does not have it — not indexed yet, or never put in a
|
|
28
|
+
* block. The explorer only knows a transaction once a block has decided it, so for one
|
|
29
|
+
* you have just sent, the node socket answers first.
|
|
30
|
+
*/
|
|
31
|
+
export async function getExplorerTransaction(request) {
|
|
32
|
+
const hash = fromBase64(request.refHash, 'refHash');
|
|
33
|
+
if (hash.length !== HASH_BYTES) {
|
|
34
|
+
throw invalidArgument(`refHash must be the base64 of a ${HASH_BYTES}-byte hash, received ${hash.length} bytes.`);
|
|
35
|
+
}
|
|
36
|
+
const url = explorerTransactionRoute(explorerBase(request.explorerUrl), toHex(hash));
|
|
37
|
+
let body;
|
|
38
|
+
try {
|
|
39
|
+
body = await requestText(url, {
|
|
40
|
+
transport: request.transport ?? defaultTransport,
|
|
41
|
+
timeoutMs: request.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
42
|
+
retries: 1,
|
|
43
|
+
signal: request.signal,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
if (error instanceof GeeqError && error.nodeDetails === NOT_FOUND)
|
|
48
|
+
return null;
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
let result;
|
|
52
|
+
try {
|
|
53
|
+
result = JSON.parse(body)?.result;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
result = undefined;
|
|
57
|
+
}
|
|
58
|
+
if (result === null || typeof result !== 'object' || !('refHash' in result)) {
|
|
59
|
+
throw nodeUnusable(`${url} did not answer with a transaction, so it does not look like a Geeq block ` +
|
|
60
|
+
'explorer.');
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=explorer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explorer.js","sourceRoot":"","sources":["../../../src/net/explorer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAG3D,MAAM,kBAAkB,GAAG,MAAM,CAAA;AACjC,MAAM,UAAU,GAAG,EAAE,CAAA;AACrB,gFAAgF;AAChF,MAAM,SAAS,GAAG,4BAA4B,CAAA;AAoD9C,SAAS,YAAY,CAAC,WAAyB;IAC7C,IAAI,GAAoB,CAAA;IACxB,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAA;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,GAAG,GAAG,SAAS,CAAA;IACjB,CAAC;IACD,IAAI,GAAG,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,CAAC,EAAE,CAAC;QACjF,MAAM,eAAe,CACnB,oFAAoF;YAClF,YAAY,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CACrD,CAAA;IACH,CAAC;IACD,OAAO,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAA;AAC5D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,OAAmC;IAEnC,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;IACnD,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QAC/B,MAAM,eAAe,CACnB,mCAAmC,UAAU,wBAAwB,IAAI,CAAC,MAAM,SAAS,CAC1F,CAAA;IACH,CAAC;IACD,MAAM,GAAG,GAAG,wBAAwB,CAAC,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;IAEpF,IAAI,IAAY,CAAA;IAChB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE;YAC5B,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,gBAAgB;YAChD,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,kBAAkB;YAClD,OAAO,EAAE,CAAC;YACV,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAA;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,SAAS,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS;YAAE,OAAO,IAAI,CAAA;QAC9E,MAAM,KAAK,CAAA;IACb,CAAC;IAED,IAAI,MAAe,CAAA;IACnB,IAAI,CAAC;QACH,MAAM,GAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAA0B,EAAE,MAAM,CAAA;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,GAAG,SAAS,CAAA;IACpB,CAAC;IACD,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,SAAS,IAAI,MAAM,CAAC,EAAE,CAAC;QAC5E,MAAM,YAAY,CAChB,GAAG,GAAG,4EAA4E;YAChF,WAAW,CACd,CAAA;IACH,CAAC;IACD,OAAO,MAAiC,CAAA;AAC1C,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { GeeqLedger } from '../ledger/geeq-ledger';
|
|
2
|
+
import type { NftRecordFacts } from '../ledger/nft-records';
|
|
3
|
+
import type { RequestOptions } from './transport';
|
|
4
|
+
/** Read and decode the validation layer ledger from one node. */
|
|
5
|
+
export declare function readLedger(origin: string, options: RequestOptions): Promise<GeeqLedger>;
|
|
6
|
+
/** Read the NFT records in the application layer ledger from one node. */
|
|
7
|
+
export declare function readNftRecords(origin: string, options: RequestOptions): Promise<Map<string, NftRecordFacts>>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ledgerUnreadable } from '../errors';
|
|
2
|
+
import { decodeValidationLedger } from '../ledger/decode';
|
|
3
|
+
import { decodeNftRecords } from '../ledger/nft-records';
|
|
4
|
+
import { appLedgerRoute, ledgerRoute } from './routes';
|
|
5
|
+
import { requestText } from './transport';
|
|
6
|
+
/** Pull `result` out of a node's response envelope. */
|
|
7
|
+
function resultOf(body, url) {
|
|
8
|
+
let parsed;
|
|
9
|
+
try {
|
|
10
|
+
parsed = JSON.parse(body);
|
|
11
|
+
}
|
|
12
|
+
catch (cause) {
|
|
13
|
+
throw ledgerUnreadable(`The node at ${url} did not answer with JSON. A login page or a proxy error is ` +
|
|
14
|
+
`the usual reason. First 120 characters: ${JSON.stringify(body.slice(0, 120))}.`, cause);
|
|
15
|
+
}
|
|
16
|
+
if (parsed === null || typeof parsed !== 'object' || !('result' in parsed)) {
|
|
17
|
+
throw ledgerUnreadable(`The node at ${url} answered JSON with no "result" field, so this is probably ` +
|
|
18
|
+
'not a Geeq node.');
|
|
19
|
+
}
|
|
20
|
+
const { result } = parsed;
|
|
21
|
+
if (typeof result !== 'string') {
|
|
22
|
+
throw ledgerUnreadable(`The node at ${url} answered with a "result" of type ${typeof result}, expected a ` +
|
|
23
|
+
'base64 string.');
|
|
24
|
+
}
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
/** Read and decode the validation layer ledger from one node. */
|
|
28
|
+
export async function readLedger(origin, options) {
|
|
29
|
+
const url = ledgerRoute(origin);
|
|
30
|
+
const body = await requestText(url, options);
|
|
31
|
+
return decodeValidationLedger(resultOf(body, url), { nodeUrl: origin });
|
|
32
|
+
}
|
|
33
|
+
/** Read the NFT records in the application layer ledger from one node. */
|
|
34
|
+
export async function readNftRecords(origin, options) {
|
|
35
|
+
const url = appLedgerRoute(origin);
|
|
36
|
+
const body = await requestText(url, options);
|
|
37
|
+
return decodeNftRecords(resultOf(body, url));
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=read-ledger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-ledger.js","sourceRoot":"","sources":["../../../src/net/read-ledger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAA;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAEtD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC,uDAAuD;AACvD,SAAS,QAAQ,CAAC,IAAY,EAAE,GAAW;IACzC,IAAI,MAAe,CAAA;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC3B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,gBAAgB,CACpB,eAAe,GAAG,8DAA8D;YAC9E,2CAA2C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,EAClF,KAAK,CACN,CAAA;IACH,CAAC;IAED,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC,EAAE,CAAC;QAC3E,MAAM,gBAAgB,CACpB,eAAe,GAAG,6DAA6D;YAC7E,kBAAkB,CACrB,CAAA;IACH,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,GAAG,MAA6B,CAAA;IAChD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,gBAAgB,CACpB,eAAe,GAAG,qCAAqC,OAAO,MAAM,eAAe;YACjF,gBAAgB,CACnB,CAAA;IACH,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,iEAAiE;AACjE,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAAc,EACd,OAAuB;IAEvB,MAAM,GAAG,GAAG,WAAW,CAAC,MAAM,CAAC,CAAA;IAC/B,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IAC5C,OAAO,sBAAsB,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAA;AACzE,CAAC;AAED,0EAA0E;AAC1E,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAc,EACd,OAAuB;IAEvB,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,CAAC,CAAA;IAClC,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IAC5C,OAAO,gBAAgB,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAA;AAC9C,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every node route the SDK knows, in one place.
|
|
3
|
+
*
|
|
4
|
+
* `origin` is an absolute node URL with no trailing slash — see `originOf`.
|
|
5
|
+
*/
|
|
6
|
+
/** `GET` the current validation layer ledger, base64 packed capnp under `result`. */
|
|
7
|
+
export declare function ledgerRoute(origin: string): string;
|
|
8
|
+
/** `GET` the current application layer ledger, where NFT records live. Same envelope. */
|
|
9
|
+
export declare function appLedgerRoute(origin: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Where a signed transaction is POSTed.
|
|
12
|
+
*
|
|
13
|
+
* The SDK does not submit — this is exported so an application builds the same URL the
|
|
14
|
+
* SDK read from, rather than keeping its own copy of the path.
|
|
15
|
+
*/
|
|
16
|
+
export declare function submitRoute(origin: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* The node's client WebSocket, where transaction status events arrive.
|
|
19
|
+
*
|
|
20
|
+
* Same host and port as the HTTP API — the node's TLS front door routes `/ws/` to the
|
|
21
|
+
* socket server and `/api/` to the HTTP one — so the only change is the scheme. The
|
|
22
|
+
* trailing slash is part of the route: the proxy answers `/ws` with a redirect, and a
|
|
23
|
+
* WebSocket handshake treats a redirect as failure.
|
|
24
|
+
*/
|
|
25
|
+
export declare function socketRoute(origin: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* The body a node expects for an application-layer transaction: an attestation or an NFT
|
|
28
|
+
* mint, each a transaction and its payload.
|
|
29
|
+
*/
|
|
30
|
+
export declare function attestationSubmitBody(transaction: string, payload: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* The body a node expects for a coin transfer.
|
|
33
|
+
*
|
|
34
|
+
* A different type and a different shape from an attestation: a validation-layer
|
|
35
|
+
* transaction carries no separate payload, so there is one blob rather than two.
|
|
36
|
+
*/
|
|
37
|
+
export declare function coinTransferSubmitBody(transaction: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Discovery routes on the chain's directory service.
|
|
40
|
+
*
|
|
41
|
+
* Only these two are ever called. The same service also exposes routes that start and
|
|
42
|
+
* stop nodes, install a genesis block, and — on `/api/accounts` — hand out plaintext
|
|
43
|
+
* private keys. None of those belong anywhere near an SDK, so the paths live here and
|
|
44
|
+
* nowhere else, and nothing constructs a URL against that origin by hand.
|
|
45
|
+
*/
|
|
46
|
+
export declare function chainsRoute(origin: string): string;
|
|
47
|
+
export declare function nodesRoute(origin: string, systemId: number): string;
|
|
48
|
+
/** A block explorer's transaction lookup. The explorer files transactions by hex refHash. */
|
|
49
|
+
export declare function explorerTransactionRoute(explorer: string, refHashHex: string): string;
|