@laceio/sdk 0.1.1 → 0.1.2-canary.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/dist/{TransactionBuilder-DrB3NVTi.cjs → TransactionBuilder-CCjOn7NA.cjs} +42 -0
- package/dist/{TransactionBuilder-V6aLx4SV.js → TransactionBuilder-CIzdw18M.js} +1 -1
- package/dist/{_polyfill-buffer-patch-BnPVerlG.cjs → _polyfill-buffer-patch-CM8X7JiY.cjs} +21 -2
- package/dist/_polyfill-buffer-patch-yNxN4d5E.js +1467 -0
- package/dist/_web-crypto-random-bytes-Bo-GTcRS.js +197 -0
- package/dist/acc-module-4iIUv6My.cjs +27654 -0
- package/dist/acc-module-Cmj8EsIb.js +27624 -0
- package/dist/account-BOQruszJ.js +6 -0
- package/dist/account-BUOj4pYJ.cjs +11 -0
- package/dist/account-call-7wnopBq0.cjs +5 -0
- package/dist/account-call-B9d_2Xwi.js +4 -0
- package/dist/account-call-Bd4Rpbvt.cjs +323 -0
- package/dist/account-call-C3CkDqEC.js +276 -0
- package/dist/account-guards-BtjTGxDZ.cjs +42 -0
- package/dist/account-guards-D9Lu5T3W.js +36 -0
- package/dist/account-tokens-DvkOFVON.js +16 -0
- package/dist/account-tokens-nwcvwLu4.cjs +21 -0
- package/dist/{activity-type.stable-BJEfeLxL.cjs → activity-type-Ch6ljxBy.cjs} +2 -1
- package/dist/{activity-type.stable-C76_hWd7.js → activity-type-GsJGWs-3.js} +2 -1
- package/dist/address-B9ntKL8K.js +13761 -0
- package/dist/address-BXp-mY8H.cjs +11270 -0
- package/dist/{address-book-address-validator-DIUolI-s.js → address-book-address-validator-0J9XAADH.js} +2 -2
- package/dist/address-book-address-validator-DK0dnsRS.cjs +41 -0
- package/dist/address-book-address-validator-Di_ywo8M.js +39 -0
- package/dist/{address-book-address-validator-DNwQGlOB.cjs → address-book-address-validator-Dte_YQ2L.cjs} +2 -2
- package/dist/artefact-loader-BWWYAD7E.cjs +183 -0
- package/dist/artefact-loader-Dik4HIfv.js +160 -0
- package/dist/auto-dismiss-failure-on-success-C-qoJuid.cjs +37 -0
- package/dist/auto-dismiss-failure-on-success-s8MGDEIu.js +31 -0
- package/dist/bip32-D6wd_QMn.cjs +3851 -0
- package/dist/bitcoin-data-provider-BYPSmuZS.js +21 -0
- package/dist/bitcoin-data-provider-w1oEDSU3.cjs +26 -0
- package/dist/bitcoin.cjs +45 -0
- package/dist/bitcoin.d.ts +29906 -1
- package/dist/bitcoin.js +20 -0
- package/dist/{blockfrost-tx-submit-provider-DPTrapz-.js → blockfrost-tx-submit-provider-CBWQ0wK9.js} +5 -157
- package/dist/{blockfrost-tx-submit-provider-BAIzV5o3.cjs → blockfrost-tx-submit-provider-CLNQ5ycR.cjs} +3 -167
- package/dist/bn-d3nSOIf7.cjs +2553 -0
- package/dist/browser-B1eMbDwh.js +7468 -0
- package/dist/bytes.vo-BB7_4JK6.js +23 -0
- package/dist/bytes.vo-BNRquqaO.cjs +34 -0
- package/dist/cardano-DfPwhwm-.js +3 -0
- package/dist/{cardano-network-id.vo-DSxrFk9S.cjs → cardano-network-id.vo-BEDPn6Li.cjs} +1 -1
- package/dist/{cardano-network-id.vo-CK1tNQDg.js → cardano-network-id.vo-Cfpvbod9.js} +1 -1
- package/dist/cardano.cjs +22 -18
- package/dist/cardano.d.ts +16956 -1716
- package/dist/cardano.js +16 -11
- package/dist/client-DXBLHk7K.cjs +808 -0
- package/dist/codecs-Cswkg7Tm.cjs +4051 -0
- package/dist/codecs-Dc1Krpbt.js +3903 -0
- package/dist/{const-C84qHkjp.js → const-BJfIK_G-.js} +4 -4
- package/dist/const-BhYOdznB.cjs +42 -0
- package/dist/const-BsnjG2_Q.cjs +32071 -0
- package/dist/const-CUnCl5U0.js +13 -0
- package/dist/{const-DXk2tFyv.js → const-CjmfjBP3.js} +1 -1
- package/dist/{const-BDEg2Trq.cjs → const-D-eZIS4n.cjs} +4 -4
- package/dist/const-D0CbQlo4.js +154 -0
- package/dist/{const-BY8B3_0_.cjs → const-iwzZEE_w.cjs} +1 -1
- package/dist/contract-1R86jhSw.js +171 -0
- package/dist/contract-MKLzYVkW.cjs +189 -0
- package/dist/create-add-accounts-Brqk84vF.js +102 -0
- package/dist/create-add-accounts-DzXIh7Ot.cjs +114 -0
- package/dist/{delegation-tx-builder-CRpLP6jH.cjs → delegation-tx-builder-CCjiakoy.cjs} +6 -6
- package/dist/{delegation-tx-builder-CGVqlaFE.js → delegation-tx-builder-DZFjHDS8.js} +5 -5
- package/dist/{deregistration-tx-builder-B-CrUyX6.js → deregistration-tx-builder-Bf6xAYp4.js} +5 -5
- package/dist/{deregistration-tx-builder-DZGwB4cz.cjs → deregistration-tx-builder-CQP35yex.cjs} +6 -6
- package/dist/device-commitment-hex.vo-5wFtQvDS.js +26 -0
- package/dist/device-commitment-hex.vo-CT3RmAug.cjs +31 -0
- package/dist/device-readers-CUHYoYOH.js +145 -0
- package/dist/device-readers-CdxS2btd.cjs +168 -0
- package/dist/device-readers-D_JZeNL2.cjs +8 -0
- package/dist/device-readers-DwSNCGPP.js +4 -0
- package/dist/dist-BMi5ZjEq.cjs +43175 -0
- package/dist/dist-BtIq4XFn.cjs +535 -0
- package/dist/dist-C3SHC_Ho.cjs +1394 -0
- package/dist/dist-CykEjYEX.cjs +3814 -0
- package/dist/dist-Dcsxh3be.cjs +3452 -0
- package/dist/dist-DqJfSlTd.cjs +4413 -0
- package/dist/dist-nTZ70qj7.cjs +1306 -0
- package/dist/{earn-rewards-tx-builder-BDbTDZmD.js → earn-rewards-tx-builder-Bsga3yFb.js} +5 -5
- package/dist/{earn-rewards-tx-builder-D5sUT5v8.cjs → earn-rewards-tx-builder-GuxofYns.cjs} +6 -6
- package/dist/enc-key-circuits-B7BjgUL9.js +13 -0
- package/dist/enc-key-circuits-BLrZrBVI.cjs +24 -0
- package/dist/english-Byb9M0E_.cjs +2057 -0
- package/dist/envelopes-BGoO_v8m.js +1621 -0
- package/dist/envelopes-CH25R-DN.cjs +1722 -0
- package/dist/errors-BIftM8ZN.cjs +688 -0
- package/dist/errors-DSq5wUwt.js +466 -0
- package/dist/esm-HBSUQw3w.js +384 -0
- package/dist/esm-LZuaZjMf.cjs +389 -0
- package/dist/experimental.cjs +7349 -0
- package/dist/experimental.d.ts +86273 -0
- package/dist/experimental.js +7184 -0
- package/dist/gated-call-CDCVZIK-.cjs +5 -0
- package/dist/gated-call-D-tT7P_t.js +722 -0
- package/dist/gated-call-D_VT2quk.js +4 -0
- package/dist/gated-call-DgJm1Mi_.cjs +787 -0
- package/dist/grant-circuits-DswmW3nI.cjs +71 -0
- package/dist/grant-circuits-Jxb5y1HW.js +42 -0
- package/dist/grant-rules-By07_eDi.js +6824 -0
- package/dist/grant-rules-BzVTWXS7.cjs +7099 -0
- package/dist/grant-spend-B3Md9L0n.js +215 -0
- package/dist/grant-spend-oWmzRsjH.cjs +217 -0
- package/dist/grant-status-B2y49iIu.js +2688 -0
- package/dist/grant-status-DOr3t_u8.cjs +2820 -0
- package/dist/grants-2BZ-qEVQ.js +5 -0
- package/dist/grants-BPoLSiMt.cjs +18 -0
- package/dist/grants-BoI5uwSF.cjs +272 -0
- package/dist/grants-CtofFu-e.js +213 -0
- package/dist/{group-cardano-addresses-by-account-B533oVXR.cjs → group-cardano-addresses-by-account-Bp0g4wEY.cjs} +3 -39
- package/dist/{group-cardano-addresses-by-account-RHKoEskR.js → group-cardano-addresses-by-account-SR8MMrZf.js} +5 -35
- package/dist/{guarded-transaction-signer-Bxl6_XNd.cjs → guarded-transaction-signer-MFpPg98D.cjs} +17 -18
- package/dist/{guarded-transaction-signer-CpKLj8Kp.js → guarded-transaction-signer-P6Rp1faj.js} +8 -15
- package/dist/hex-D9ITYbwt.cjs +263 -0
- package/dist/hex-mkXcV3pN.js +191 -0
- package/dist/http-client-B3N-TMxu.cjs +167 -0
- package/dist/http-client-TRlhDZGh.js +155 -0
- package/dist/identity-BMLuufva.cjs +263 -0
- package/dist/identity-DII6f-h7.js +233 -0
- package/dist/in-memory-wallet-integration-B2xzxORj.cjs +20741 -0
- package/dist/in-memory-wallet-integration-CBRiPjLO.js +130 -0
- package/dist/in-memory-wallet-integration-CULUB5Tf.cjs +240 -0
- package/dist/{in-memory-wallet-integration-D-qn65Kx.js → in-memory-wallet-integration-ChIOirMW.js} +5 -2
- package/dist/{in-memory-wallet-integration-Croiuopx.js → in-memory-wallet-integration-CljprQQV.js} +7 -104
- package/dist/{in-memory-wallet-integration-DVh9sRXa.cjs → in-memory-wallet-integration-Cm6P8sk6.cjs} +3 -2
- package/dist/in-memory-wallet-integration-TM9bBphA.js +20738 -0
- package/dist/{in-memory-wallet-integration-CnLYeX4-.cjs → in-memory-wallet-integration-t9I00R_V.cjs} +17 -108
- package/dist/index.cjs +84 -47
- package/dist/index.d.ts +37496 -10033
- package/dist/index.js +52 -24
- package/dist/{init-CLHuAMB-.js → init-0zzs9aqU.js} +4 -4
- package/dist/{init-U8c9yHYx.cjs → init-5KcGcBb5.cjs} +1 -1
- package/dist/init-8v_n8boO.js +1177 -0
- package/dist/{init-CigestoM.js → init-B3-1ghyx.js} +2 -2
- package/dist/init-B8U3ABhS.cjs +107 -0
- package/dist/init-BJn-8_hf.js +141 -0
- package/dist/init-BPU3j8sT.cjs +6 -0
- package/dist/init-BRzH6xu-2.cjs +2797 -0
- package/dist/init-BmzfDaKL.js +1142 -0
- package/dist/{init-C-jErzp5.cjs → init-BopV9ed4.cjs} +2 -2
- package/dist/init-BpHTq2R5.js +105 -0
- package/dist/init-BpSITBfF.js +39 -0
- package/dist/{init-DX4WyB0R.cjs → init-BrdVzxei.cjs} +3 -3
- package/dist/{init-LfyMo-sS.cjs → init-BwkU0ruo.cjs} +2 -2
- package/dist/{init-CB__aLD7.cjs → init-C-G32J12.cjs} +2 -2
- package/dist/init-C00gw1zi.js +422 -0
- package/dist/{init-TkPq_Ny_.js → init-C2RgrfZe.js} +1 -1
- package/dist/{init-DcYY6zMD.js → init-C8URA2OX.js} +1 -1
- package/dist/init-CDkRynJa.js +2796 -0
- package/dist/{init-Cg9XdAru.js → init-CNM5m7M2.js} +4 -4
- package/dist/init-CR7BfztQ.cjs +18 -0
- package/dist/{init-CSHwHnfg.cjs → init-CSDpdu0Q.cjs} +2 -2
- package/dist/{init-aJHl-7AO.js → init-CX0AMQUn.js} +2 -2
- package/dist/{init-FMGDET-9.js → init-CfTbSEKy.js} +259 -60
- package/dist/{init-CR6tpw1B.js → init-Cigr_tKx.js} +47 -43
- package/dist/init-CuW7rHNA.js +3584 -0
- package/dist/{init-CFYsq82V.js → init-CyAY4Lzl.js} +1 -1
- package/dist/init-Cz0rz5fU.cjs +3585 -0
- package/dist/{init-BKhH6mVR.cjs → init-D6BxBs7e.cjs} +1 -1
- package/dist/init-D8OeObDF.cjs +1141 -0
- package/dist/init-D9g1HXYf.cjs +40 -0
- package/dist/{init-CNLGJJRx.js → init-DA7zmptx.js} +1 -1
- package/dist/{init-DkIc5nqF.cjs → init-DFMiP2ZH.cjs} +1 -1
- package/dist/{init-zSzCjoor.js → init-DFjT8YvT.js} +4 -4
- package/dist/init-DGjXwWs2.cjs +143 -0
- package/dist/init-DHrCbpkW.cjs +121 -0
- package/dist/{init-B64zCLxG.cjs → init-DUF4ar8P.cjs} +4 -4
- package/dist/init-DlqJuHhl.js +119 -0
- package/dist/{init-y2Ra0vZP.js → init-Dnsv155v.js} +3 -3
- package/dist/init-DrRdf5sZ.cjs +1176 -0
- package/dist/init-DuYENxci.js +17 -0
- package/dist/{init-D6DBUsD3.cjs → init-Dv3zKj0r.cjs} +4 -4
- package/dist/{init-BtzMZ7Pk.cjs → init-Dy-05ktr.cjs} +1 -1
- package/dist/{init-BsCBAGWf.cjs → init-EP0CUWNK.cjs} +2 -2
- package/dist/{init-BJVU54pI.cjs → init-EhzD7a8i.cjs} +1 -1
- package/dist/{init-w9GEs73W.js → init-Fw89ZmrR.js} +2 -2
- package/dist/init-GsT2AEa4.cjs +424 -0
- package/dist/{init-Rxohwpmu.js → init-NCjgwCZy.js} +2 -2
- package/dist/{init-DxUHsN53.cjs → init-NdhG_VrF.cjs} +6 -6
- package/dist/{init-DDdhguVC.js → init-SZ01tARX2.js} +2 -2
- package/dist/{init-BAJJzBza.js → init-Y3mkB4XS.js} +2 -2
- package/dist/init-c4l6r-o-.js +5 -0
- package/dist/{init-Dku4b2lG.js → init-kEfUTuG2.js} +1 -1
- package/dist/{init-C7IeJwQR.cjs → init-lzHt4Cli.cjs} +256 -59
- package/dist/{init-anYu6XB7.cjs → init-rmt7-fQE.cjs} +2 -2
- package/dist/{init-C4Bkib9u.cjs → init-zU-_9Gsp.cjs} +67 -65
- package/dist/{is-retriable-error-BU0e3hVI.js → is-retriable-error-BUiVJDwH.js} +1 -1
- package/dist/{is-retriable-error-CeeuHqDa.cjs → is-retriable-error-Dpt860if.cjs} +1 -1
- package/dist/jubjub-authoriser-D7zDXu3V.js +86 -0
- package/dist/jubjub-authoriser-Dgu6o3Sv.cjs +87 -0
- package/dist/key-source-5oUBFiC7.cjs +583 -0
- package/dist/key-source-B08HukZg.js +2550 -0
- package/dist/keyDerivation-D3k9XyHg.js +4077 -0
- package/dist/keyDerivation-u0nBA93T.cjs +274 -0
- package/dist/{lace-context-CZcNHr4M.js → lace-context-BZciB9c7.js} +4 -4
- package/dist/{lace-context-fJTDghdp.cjs → lace-context-DgR6vLli.cjs} +4 -4
- package/dist/lib--iqvW4O_.js +2354 -0
- package/dist/lib-Yk6Upl5D.cjs +2359 -0
- package/dist/{libsodium-wrappers-UH0LaOUE.js → libsodium-wrappers-BhbOA8dQ.js} +3 -1647
- package/dist/midnight-account-id.vo-0x9X-r3l.cjs +10 -0
- package/dist/midnight-account-id.vo-DjCAGcqc.js +5 -0
- package/dist/midnight-engine-DpemplKO.js +5 -0
- package/dist/midnight-engine-xU1wotne.cjs +6 -0
- package/dist/midnight-wallet-DIsAlSn6.js +18 -0
- package/dist/midnight-wallet-XTZc2li7.cjs +24 -0
- package/dist/midnight.cjs +1408 -0
- package/dist/midnight.d.ts +28934 -0
- package/dist/midnight.js +1352 -0
- package/dist/modules-cardano-B1nDUWqy.js +995 -0
- package/dist/modules-cardano-BYeYHrRm.cjs +1108 -0
- package/dist/node-relay-DWe1U0w2.cjs +49 -0
- package/dist/node-relay-h4i5IlAQ.js +48 -0
- package/dist/outputs-Bd2yZVjx.js +720 -0
- package/dist/outputs-CJoQBIA2.cjs +990 -0
- package/dist/pbkdf2-CIW-oWrm.cjs +1337 -0
- package/dist/pending-operation-B0_P78Jo.cjs +26 -0
- package/dist/pending-operation-BIS6mpjB.js +21 -0
- package/dist/providers-FjhM47BH.cjs +388 -0
- package/dist/providers-WtiSuxFu.js +365 -0
- package/dist/redacted-BmE2aXqr.js +81 -0
- package/dist/redacted-CRZJLS3w.cjs +86 -0
- package/dist/{retry-config-DC5IMaH7.cjs → retry-config-BaCfVC1H.cjs} +1 -1
- package/dist/{retry-config-BcUmMS--.js → retry-config-Dmgt28wM.js} +1 -1
- package/dist/safe-buffer-B_vMqJWU.js +43 -0
- package/dist/safe-buffer-DYOwEfHB.cjs +48 -0
- package/dist/sdk-Cb-gZnS9.js +1241 -0
- package/dist/sdk-DffwmX8b.cjs +1439 -0
- package/dist/sdk-init-Bln9rFtn.js +4138 -0
- package/dist/sdk-init-CYViTJY_.cjs +3841 -0
- package/dist/{seam-cardano-CATqBEyK.js → seam-cardano-B_etH4F4.js} +1 -1
- package/dist/{bytes.vo-TgiwogWF.js → secret-box-DUR0ACYz.js} +3 -25
- package/dist/{bytes.vo-Ck5u40RA.cjs → secret-box-DrjLZuS1.cjs} +1 -35
- package/dist/send-proof-progress-C-ljq1x5.js +30 -0
- package/dist/send-proof-progress-vmsaSfbz.cjs +47 -0
- package/dist/side-effects-BnqYz7Nl.js +768 -0
- package/dist/side-effects-CngaeXi0.cjs +804 -0
- package/dist/sign-bitcoin-transaction-with-seed-D4z62-jV.js +147 -0
- package/dist/sign-bitcoin-transaction-with-seed-DsLYXnCY.cjs +158 -0
- package/dist/signer-3fk8lZtE.cjs +7 -0
- package/dist/signer-CsL28DrK.cjs +121 -0
- package/dist/signer-DGluibtn.js +92 -0
- package/dist/signer-RqB5pu3K.js +2 -0
- package/dist/signer-factory-BA7WFJVZ.js +282 -0
- package/dist/signer-factory-Cwd6o-lG.cjs +281 -0
- package/dist/{signer-factory-9URFliA5.js → signer-factory-DObB55D4.js} +6 -3
- package/dist/signer-factory-DhZiE03y.cjs +149 -0
- package/dist/{signer-factory-BWGUmnvm.cjs → signer-factory-Ds6G2AZk.cjs} +4 -3
- package/dist/signer-factory-hzSRaIw2.js +148 -0
- package/dist/{slice-CuHUaPZx.cjs → slice-7G2xxYKJ.cjs} +3 -3
- package/dist/{slice-DZmQJNV8.cjs → slice-B4CdYoPu.cjs} +2 -2
- package/dist/slice-BPNuHKfw.js +9091 -0
- package/dist/{slice-DGcNrbPR.cjs → slice-Bg6HEr3K.cjs} +4 -4
- package/dist/{slice-DtaO72qY.cjs → slice-Bs2aMERu.cjs} +3 -3
- package/dist/{slice-HeHCv3bl.cjs → slice-C34iOOUH.cjs} +7 -7
- package/dist/{slice-Do2R2CYW.cjs → slice-C9TT5KhY.cjs} +6 -6
- package/dist/{slice-eIwcwKHI.js → slice-CK07EBCo.js} +4 -4
- package/dist/{slice-CnyWevM9.js → slice-CU80pbiu.js} +3 -3
- package/dist/{slice-CobanYgn.js → slice-CwyYrh1H.js} +2 -2
- package/dist/slice-Czfp6t84.cjs +436 -0
- package/dist/{slice-d0p6-xj5.js → slice-D-9aPKG-.js} +6 -6
- package/dist/{slice-maaskdUn.js → slice-DBpJ2QGf.js} +6 -6
- package/dist/{slice-mxLQ_FeY.cjs → slice-DTZTiJle.cjs} +352 -39
- package/dist/{slice-zJ9XVYjZ.js → slice-Da426sf9.js} +1 -1
- package/dist/{slice-D11m2EKl.cjs → slice-DayJvMRD.cjs} +1 -1
- package/dist/slice-DnBWfA-k.cjs +9109 -0
- package/dist/{slice-oqm_r1cS.cjs → slice-DnG-yvpI.cjs} +2 -2
- package/dist/{slice-BNu73oBa.js → slice-DyNs7oWp.js} +2 -2
- package/dist/{slice-CB4SnzMm.js → slice-GwiiJRoq.js} +3 -3
- package/dist/slice-oWnc7YVD.js +412 -0
- package/dist/{slice-B2PhoWAg.js → slice-qt0uBExh.js} +325 -37
- package/dist/slice-t8Gzj55G2.cjs +106 -0
- package/dist/slice-t8Q1cHm-.js +88 -0
- package/dist/src-BDzYIksE.cjs +20637 -0
- package/dist/src-BFoefPv_.js +20755 -0
- package/dist/store-B1Lq3cEf.cjs +66 -0
- package/dist/store-DuBG8qh5.js +37 -0
- package/dist/submit-Bs77dPn_.cjs +413 -0
- package/dist/submit-DOv8Z0Vf.js +336 -0
- package/dist/submit-bitcoin-tx-D6oYgH5S.js +983 -0
- package/dist/submit-bitcoin-tx-goFuRL7K.cjs +1049 -0
- package/dist/{sync-operation-utils-BYXLO80m.js → sync-operation-utils-31iFLExW.js} +2 -38
- package/dist/{sync-operation-utils-SdPbwFoD.cjs → sync-operation-utils-COIZ66-I.cjs} +1 -67
- package/dist/token-id-mapper-Bnds3xKH.cjs +18 -0
- package/dist/{token-id-mapper-DsPAL6Nh.cjs → token-id-mapper-CVyQJUKY.cjs} +2 -2
- package/dist/token-id-mapper-CnKHQ8DV.js +16 -0
- package/dist/{token-id-mapper-B2ivlLv3.js → token-id-mapper-D29Ggv8h.js} +2 -2
- package/dist/tokens-Cevp7rdU.cjs +62 -0
- package/dist/tokens-Diw4MLRM.js +44 -0
- package/dist/types-B8uiJn-X.js +12 -0
- package/dist/types-BHC12eSa.js +33 -0
- package/dist/types-CJT6XF2c.js +10 -0
- package/dist/types-CLRUYpfe.cjs +23 -0
- package/dist/types-Cc3mC8u0.cjs +50 -0
- package/dist/types-DWbVZpnF.cjs +15 -0
- package/dist/unwrap-provider-result-BZSiwabU.js +32 -0
- package/dist/unwrap-provider-result-ZqfBsTkk.cjs +39 -0
- package/dist/{util-CGzqQ8IV.cjs → util-Bu4W5lF4.cjs} +1 -1
- package/dist/{util-BaLzwa32.js → util-Cp5cZkfK.js} +1 -1
- package/dist/{utils-o8aMjfln.js → utils-BfBEUvWA.js} +2 -2
- package/dist/utils-DFwzEvbv.js +65 -0
- package/dist/{utils-5JvjbqH3.cjs → utils-DsElZgCI.cjs} +7 -1
- package/dist/utils-IXxR-Djh.cjs +112 -0
- package/dist/v8Signatures-CO_Uloy7.cjs +71 -0
- package/dist/{vote-delegation-tx-builder-BpEMSti4.cjs → vote-delegation-tx-builder-BUg1S2Ep.cjs} +6 -6
- package/dist/{vote-delegation-tx-builder-CmKv6GoG.js → vote-delegation-tx-builder-C6FiS7zI.js} +5 -5
- package/dist/watch-CUEvcP-V.js +21997 -0
- package/dist/watch-DMF2s-II.cjs +52281 -0
- package/package.json +96 -4
- package/dist/account-guards.stable-B1DSSh9D.cjs +0 -10
- package/dist/account-guards.stable-JRQ5qx2V.js +0 -5
- package/dist/codecs-B7X9pAsK.cjs +0 -1945
- package/dist/codecs-CC1Xjntz.js +0 -1882
- package/dist/init-Bv53hpLM.js +0 -19
- package/dist/init-CRbjI7p1.js +0 -3494
- package/dist/init-DAna1KCg.cjs +0 -3495
- package/dist/init-DGe47B22.cjs +0 -364
- package/dist/init-DMtyvYfC.cjs +0 -21
- package/dist/init-TkPDD750.js +0 -363
- package/dist/modules-cardano-BDvuL4Xx.js +0 -5248
- package/dist/modules-cardano-D2G3De2P.cjs +0 -5432
- package/dist/slice-CGVHXHDt.cjs +0 -125
- package/dist/slice-DhvF7L6X.js +0 -107
- /package/dist/{account-id.vo-LvCBVn5r.cjs → account-id.vo-DwqFjK5u.cjs} +0 -0
- /package/dist/{account-id.vo-MYSI7YFm.js → account-id.vo-OPz2v-JZ.js} +0 -0
- /package/dist/{actions-DdGbj7c7.cjs → actions-B2BJ4RTy.cjs} +0 -0
- /package/dist/{actions-9QSQR-GB.js → actions-iLXdgL5Y.js} +0 -0
- /package/dist/{apply-vkey-witnesses-ClZbpk5w.js → apply-vkey-witnesses-BKx3lcs0.js} +0 -0
- /package/dist/{apply-vkey-witnesses-CLzVSWxl.cjs → apply-vkey-witnesses-ZnFS0jnJ.cjs} +0 -0
- /package/dist/{asyncoption-Cw07zPH7.js → asyncoption-CruEYOBI.js} +0 -0
- /package/dist/{asyncoption-DYoGuQfP.cjs → asyncoption-i0VbqVTq.cjs} +0 -0
- /package/dist/{bignum.vo-B0rK_PQ1.js → bignum.vo-CEXOIew0.js} +0 -0
- /package/dist/{bignum.vo-DsG3kNiZ.cjs → bignum.vo-hx2kuqlA.cjs} +0 -0
- /package/dist/{bip32ed25519-1ApqeAZk.cjs → bip32ed25519-B7Yat217.cjs} +0 -0
- /package/dist/{bip32ed25519-DetAdGwD.js → bip32ed25519-FQ8qvdcq.js} +0 -0
- /package/dist/{blake2b-DOEVc57D.js → blake2b-BiQTw3GC.js} +0 -0
- /package/dist/{blake2b-B9tftbvG.cjs → blake2b-DEeVUdKR.cjs} +0 -0
- /package/dist/{blockchain-network-id.vo-BXpZhvvQ.cjs → blockchain-network-id.vo-BAKEwGjG.cjs} +0 -0
- /package/dist/{blockchain-network-id.vo-DNRkuT5B.js → blockchain-network-id.vo-CiVykuqG.js} +0 -0
- /package/dist/{blockingWithLatestFrom-C5wp_uA-.js → blockingWithLatestFrom-Cd8c8EPG.js} +0 -0
- /package/dist/{blockingWithLatestFrom-DY8OPg0w.cjs → blockingWithLatestFrom-D8kBPBMX.cjs} +0 -0
- /package/dist/{cardano-network-id-to-network-type-CrZfUcyP.js → cardano-network-id-to-network-type-BWwzeEtM.js} +0 -0
- /package/dist/{cardano-network-id-to-network-type-BDTF-HmK.cjs → cardano-network-id-to-network-type-C0ufJOyE.cjs} +0 -0
- /package/dist/{cardano-tx-id.vo-BPhV-AmZ.cjs → cardano-tx-id.vo-TLjJZHCI.cjs} +0 -0
- /package/dist/{cardano-tx-id.vo-DF9NzZXk.js → cardano-tx-id.vo-eVnKuzlm.js} +0 -0
- /package/dist/{composite-signer-factory-_46QsNBz.js → composite-signer-factory-CR8YHA1y.js} +0 -0
- /package/dist/{composite-signer-factory-BpF1mIYA.cjs → composite-signer-factory-m5cVs9h_.cjs} +0 -0
- /package/dist/{error-CNIquqT5.cjs → error-Cb3EnD0u.cjs} +0 -0
- /package/dist/{error-BCp9NkPi.js → error-DIZOY2Lw.js} +0 -0
- /package/dist/{esm-browser-C93Q-EOI.js → esm-browser-MG97cre9.js} +0 -0
- /package/dist/{esm-browser-DTc9IK3D.cjs → esm-browser-bweqfBlL.cjs} +0 -0
- /package/dist/{feature-flag-key.vo-ofrB6ZVQ.js → feature-flag-key.vo-DN_-4-sG.js} +0 -0
- /package/dist/{feature-flag-key.vo-BPz-ZAp6.cjs → feature-flag-key.vo-RlfHL3hq.cjs} +0 -0
- /package/dist/{first-state-of-status-OROkXcRv.cjs → first-state-of-status-CbT7hPa4.cjs} +0 -0
- /package/dist/{first-state-of-status-DQnMT3ya.js → first-state-of-status-unPynOuM.js} +0 -0
- /package/dist/{init-Es3wHW7D.js → init-829HRYcz.js} +0 -0
- /package/dist/{init-CKipPE_c.js → init-A-VyGSNW2.js} +0 -0
- /package/dist/{init-DFQQ9dTW.cjs → init-Atisw4x2.cjs} +0 -0
- /package/dist/{init-C5CEZ1m0.cjs → init-BFcvPHL-.cjs} +0 -0
- /package/dist/{init-IAk_CkGa.cjs → init-BgNobbNq.cjs} +0 -0
- /package/dist/{init-cqN3uX2j.js → init-atCFur0v.js} +0 -0
- /package/dist/{is-redux-persist-state-CTn3WZVh.cjs → is-redux-persist-state-BCFnSm36.cjs} +0 -0
- /package/dist/{is-redux-persist-state-Cxcd0_bM.js → is-redux-persist-state-yBfq0h_E.js} +0 -0
- /package/dist/{key-value-store-8cMzeNyG.js → key-value-store--W3SrMaw.js} +0 -0
- /package/dist/{key-value-store-DUAepXQf.cjs → key-value-store-C2Xt5Emp.cjs} +0 -0
- /package/dist/{repo-slice-WxetRhMY.cjs → repo-slice-7X4AYYVm.cjs} +0 -0
- /package/dist/{repo-slice-DwyMhCR1.js → repo-slice-RxFm0zDZ.js} +0 -0
- /package/dist/{reselect-CRDqmQY9.cjs → reselect-Bd94u0K-.cjs} +0 -0
- /package/dist/{reselect-C06X06oX.js → reselect-CGoLzEPv.js} +0 -0
- /package/dist/{serializable-B8GahgE1.js → serializable-BHdKIgk3.js} +0 -0
- /package/dist/{serializable-CRdnFaLZ.cjs → serializable-BxHkoPdk.cjs} +0 -0
- /package/dist/{slice-D11FHQuQ.cjs → slice-BiRsDKOK.cjs} +0 -0
- /package/dist/{slice-Be7hj4Iy.js → slice-Bk0Sv05J.js} +0 -0
- /package/dist/{slice-FioKeHtA.cjs → slice-Dqw1ecum.cjs} +0 -0
- /package/dist/{slice-B87b52iM.js → slice-obCSLm1x.js} +0 -0
- /package/dist/{src-vq1wS9sZ.js → src-BlxEp6Mm.js} +0 -0
- /package/dist/{src-BTPIvlDI.cjs → src-Cqp0B2M_.cjs} +0 -0
- /package/dist/{time.vo-CQ8pSXz2.cjs → time.vo-D3wWRw9L.cjs} +0 -0
- /package/dist/{time.vo-DkYYGYp6.js → time.vo-tNheinXm.js} +0 -0
- /package/dist/{toEmpty-CgAl3097.js → toEmpty-8Zax1MPd.js} +0 -0
- /package/dist/{toEmpty-DAMmNB5r.cjs → toEmpty-CYAbupM4.cjs} +0 -0
- /package/dist/{token-id.vo-ClsroxHO.js → token-id.vo-Bvwhr3ZE.js} +0 -0
- /package/dist/{token-id.vo-BxG9TG0O.cjs → token-id.vo-DXv5uS9n.cjs} +0 -0
- /package/dist/{util-DxzlYNS5.js → util-C8a4fA9p.js} +0 -0
- /package/dist/{util-CmdAhheh.cjs → util-CzeB3hfa.cjs} +0 -0
- /package/dist/{util-selector-CcK-GAdE.js → util-selector-BSTsxgne.js} +0 -0
- /package/dist/{util-selector-BcAncU4L.cjs → util-selector-BWPH68_l.cjs} +0 -0
- /package/dist/{while-active-BpppWuCs.js → while-active-B0lWy_6l.js} +0 -0
- /package/dist/{while-active-Dhc2LwOm.cjs → while-active-Dsowp0Fi.cjs} +0 -0
|
@@ -0,0 +1,722 @@
|
|
|
1
|
+
import { n as HexBytes, t as ByteArray } from "./bytes.vo-BB7_4JK6.js";
|
|
2
|
+
import { E as MaintenanceAuthorityMismatchError, d as DeviceEntryNotFoundError, l as CreationArtefactMismatchError, o as AuthorityNotRetiredError, s as AuthorityRetiredError, t as AccountContractMissingError } from "./errors-DSq5wUwt.js";
|
|
3
|
+
import { d as assertVerifierKeyHeader, f as verifierKeyInsert, n as submitTx, o as isSameAuthority, p as DEPLOYED_OPERATIONS, r as submitWithDustRetry, t as assertSubmitted } from "./submit-DOv8Z0Vf.js";
|
|
4
|
+
import { a as pureCircuits, i as ledger, r as expectedVk, t as Contract } from "./acc-module-Cmj8EsIb.js";
|
|
5
|
+
import { n as JubjubDevice, r as authArgs } from "./signer-DGluibtn.js";
|
|
6
|
+
//#region ../../packages/contract/passport/src/value-objects/use-counter.vo.ts
|
|
7
|
+
/** Types a bigint as an authoriser's use counter. It checks nothing. */
|
|
8
|
+
const UseCounter = (value) => value;
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region ../../packages/contract/passport/src/value-objects/device-epoch.vo.ts
|
|
11
|
+
/** Types a bigint as a device authoriser's epoch. It checks nothing. */
|
|
12
|
+
const DeviceEpoch = (value) => value;
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region ../../packages/module/passport-account/src/acc/wave-plan.ts
|
|
15
|
+
/**
|
|
16
|
+
* Most verifier key bytes one transaction may carry. A deploy or
|
|
17
|
+
* maintenance update above it is refused by the node for exhausting the
|
|
18
|
+
* block limits, so the roster is split into waves packed under this
|
|
19
|
+
* figure. The budget is a packing heuristic over the measured key sizes,
|
|
20
|
+
* not the node's own weight check.
|
|
21
|
+
*/
|
|
22
|
+
const VERIFIER_BYTE_BUDGET = 15e3;
|
|
23
|
+
const sizeOf = (sizes, operation) => {
|
|
24
|
+
const size = sizes.get(operation);
|
|
25
|
+
if (size === void 0) throw new Error(`No verifier key size for operation '${operation}'`);
|
|
26
|
+
return size;
|
|
27
|
+
};
|
|
28
|
+
const assertBudget = (budget) => {
|
|
29
|
+
if (!Number.isFinite(budget) || budget <= 0) throw new Error(`The verifier byte budget must be a positive number, got ${budget}`);
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Packs the operations greedily, in order, into batches no larger than
|
|
33
|
+
* the budget. Greedy over one fixed order keeps the plan deterministic
|
|
34
|
+
* for a given roster and key set, so a retry computes the same waves.
|
|
35
|
+
*/
|
|
36
|
+
const packOperations = (operations, sizes, budget) => {
|
|
37
|
+
const batches = [];
|
|
38
|
+
let current = {
|
|
39
|
+
operations: [],
|
|
40
|
+
verifierBytes: 0
|
|
41
|
+
};
|
|
42
|
+
for (const operation of operations) {
|
|
43
|
+
const size = sizeOf(sizes, operation);
|
|
44
|
+
if (size > budget) throw new Error(`The verifier key of '${operation}' (${size} bytes) exceeds the ${budget} byte wave budget`);
|
|
45
|
+
if (current.verifierBytes + size > budget) {
|
|
46
|
+
batches.push(current);
|
|
47
|
+
current = {
|
|
48
|
+
operations: [],
|
|
49
|
+
verifierBytes: 0
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
current.operations.push(operation);
|
|
53
|
+
current.verifierBytes += size;
|
|
54
|
+
}
|
|
55
|
+
if (current.operations.length > 0) batches.push(current);
|
|
56
|
+
return batches;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* The maintenance waves for the given batches. The replacement of the
|
|
60
|
+
* deploy-time authority rides on the last of them, the last update that
|
|
61
|
+
* needs it; with nothing left to install, a replace-only update is the
|
|
62
|
+
* whole of it.
|
|
63
|
+
*/
|
|
64
|
+
const toMaintenanceWaves = (batches) => {
|
|
65
|
+
const waves = batches.map((batch) => ({
|
|
66
|
+
kind: "maintenance",
|
|
67
|
+
...batch,
|
|
68
|
+
replacesAuthority: false
|
|
69
|
+
}));
|
|
70
|
+
const last = waves.at(-1);
|
|
71
|
+
if (last) last.replacesAuthority = true;
|
|
72
|
+
else waves.push({
|
|
73
|
+
kind: "maintenance",
|
|
74
|
+
operations: [],
|
|
75
|
+
verifierBytes: 0,
|
|
76
|
+
replacesAuthority: true
|
|
77
|
+
});
|
|
78
|
+
return waves;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Plans a fresh deployment: the deploy carries the longest prefix of the
|
|
82
|
+
* roster under the budget, and every later wave is one maintenance update
|
|
83
|
+
* with the next batch. The order is the roster's, so the activation
|
|
84
|
+
* circuit lands in the deploy and the account is usable as early as the
|
|
85
|
+
* waves allow.
|
|
86
|
+
*/
|
|
87
|
+
const planDeployWaves = (operations, sizes, { budget = VERIFIER_BYTE_BUDGET } = {}) => {
|
|
88
|
+
assertBudget(budget);
|
|
89
|
+
const [deploy, ...rest] = packOperations(operations, sizes, budget);
|
|
90
|
+
if (!deploy) throw new Error("A deployment needs at least one operation");
|
|
91
|
+
return [{
|
|
92
|
+
kind: "deploy",
|
|
93
|
+
...deploy,
|
|
94
|
+
replacesAuthority: false
|
|
95
|
+
}, ...toMaintenanceWaves(rest)];
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Plans the waves a deployed contract still needs: the roster operations
|
|
99
|
+
* not yet installed, packed as maintenance updates, and the replacement
|
|
100
|
+
* of the deploy-time authority while it is still live.
|
|
101
|
+
* Installed operations are read from chain rather than from any local
|
|
102
|
+
* count, so a wave that landed without being recorded is never sent
|
|
103
|
+
* twice.
|
|
104
|
+
*
|
|
105
|
+
* @throws {@link AuthorityRetiredError} when operations are missing but
|
|
106
|
+
* the deploy-time authority is already replaced: nothing that holds it
|
|
107
|
+
* can install them any more.
|
|
108
|
+
*/
|
|
109
|
+
const planResumeWaves = ({ operations, sizes, installed, isAuthorityReplaced, budget = VERIFIER_BYTE_BUDGET }) => {
|
|
110
|
+
assertBudget(budget);
|
|
111
|
+
const installedSet = new Set(installed);
|
|
112
|
+
const missing = operations.filter((operation) => !installedSet.has(operation));
|
|
113
|
+
if (isAuthorityReplaced) {
|
|
114
|
+
if (missing.length > 0) throw new AuthorityRetiredError(`The deploy-time maintenance authority is replaced and ${missing.length} operations are not installed: ${missing.join(", ")}`);
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
return toMaintenanceWaves(packOperations(missing, sizes, budget));
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Plans the waves that install `operations` on a live account: one
|
|
121
|
+
* maintenance update per batch packed under the budget, in the order
|
|
122
|
+
* given, none replacing the authority, which stays the one that signs
|
|
123
|
+
* them.
|
|
124
|
+
*/
|
|
125
|
+
const planInstallWaves = (operations, sizes, { budget = VERIFIER_BYTE_BUDGET } = {}) => {
|
|
126
|
+
assertBudget(budget);
|
|
127
|
+
return packOperations(operations, sizes, budget).map((batch) => ({
|
|
128
|
+
kind: "maintenance",
|
|
129
|
+
...batch,
|
|
130
|
+
replacesAuthority: false
|
|
131
|
+
}));
|
|
132
|
+
};
|
|
133
|
+
//#endregion
|
|
134
|
+
//#region ../../packages/module/passport-account/src/acc/deploy.ts
|
|
135
|
+
const ACTIVATE_INITIAL_DEVICE_CIRCUIT = "activate_initial_device_with_jubjub";
|
|
136
|
+
const SALT_LENGTH = 32;
|
|
137
|
+
const RECOVERY_WRAP_LENGTH = 64;
|
|
138
|
+
const PRIVATE_STATE_ID_LENGTH$1 = 8;
|
|
139
|
+
/** Three days, the veto window published with the throwaway recovery. */
|
|
140
|
+
const VETO_WINDOW_SECONDS = 259200n;
|
|
141
|
+
const DEPLOY_TX_TTL_MS = 6e4;
|
|
142
|
+
/** How long a landed wave may take to show in the indexer's state. */
|
|
143
|
+
const AUTHORITY_POLL_ATTEMPTS = 60;
|
|
144
|
+
const AUTHORITY_POLL_DELAY_MS = 2e3;
|
|
145
|
+
/** How long a landed deploy may take to appear in the indexer at all. */
|
|
146
|
+
const INDEXED_POLL_ATTEMPTS = 30;
|
|
147
|
+
const defaultSleep = async (ms) => new Promise((resolve) => {
|
|
148
|
+
setTimeout(resolve, ms);
|
|
149
|
+
});
|
|
150
|
+
/**
|
|
151
|
+
* The contract's witness implementations over {@link AccountPrivateState}.
|
|
152
|
+
* `held_coin` serves the exact qualified coin a shielded spend consumes;
|
|
153
|
+
* a color the store has not captured cannot be spent by a conforming
|
|
154
|
+
* client, so the witness refuses it.
|
|
155
|
+
*/
|
|
156
|
+
const accountWitnesses = { held_coin: (context, color) => {
|
|
157
|
+
const key = HexBytes.fromByteArray(color);
|
|
158
|
+
const stored = context.privateState.coins[key];
|
|
159
|
+
if (!stored) throw new Error(`held_coin witness: no coin for color ${key} in the local store`);
|
|
160
|
+
return [context.privateState, {
|
|
161
|
+
nonce: ByteArray.fromHex(HexBytes(stored.nonceHex)),
|
|
162
|
+
color: ByteArray.fromHex(HexBytes(stored.colorHex)),
|
|
163
|
+
value: BigInt(stored.value),
|
|
164
|
+
mt_index: BigInt(stored.mtIndex)
|
|
165
|
+
}];
|
|
166
|
+
} };
|
|
167
|
+
/** The private state a handle starts from: no captured coins yet. */
|
|
168
|
+
const initialAccountPrivateState = () => ({ coins: {} });
|
|
169
|
+
const noSponsorSetup = async () => void 0;
|
|
170
|
+
/** The expiry of a transaction built now, once the sponsor is ready. */
|
|
171
|
+
const transactionTtl = async (sponsorReady) => {
|
|
172
|
+
await sponsorReady();
|
|
173
|
+
return new Date(Date.now() + DEPLOY_TX_TTL_MS);
|
|
174
|
+
};
|
|
175
|
+
const defaultRandomBytes = (length) => crypto.getRandomValues(new Uint8Array(length));
|
|
176
|
+
const importChainModules = async () => Promise.all([
|
|
177
|
+
import("@midnight-ntwrk/midnight-js-contracts"),
|
|
178
|
+
import("@midnightntwrk/ledger-v9"),
|
|
179
|
+
import("@midnight-ntwrk/midnight-js-network-id"),
|
|
180
|
+
import("@midnight-ntwrk/compact-js/effect/CompiledContract")
|
|
181
|
+
]);
|
|
182
|
+
/**
|
|
183
|
+
* Names the verifier keys this build installs: the lowercase hex sha256
|
|
184
|
+
* over each roster operation's name and the sha256 pin of its verifier
|
|
185
|
+
* key, in installation order. A deployment records it once the deploy
|
|
186
|
+
* lands, and a resume compares it before any wave, so an account never
|
|
187
|
+
* holds verifier keys of two builds.
|
|
188
|
+
*/
|
|
189
|
+
const deployedVerifierKeysDigest = async () => {
|
|
190
|
+
const pins = DEPLOYED_OPERATIONS.map((operation) => {
|
|
191
|
+
const pin = expectedVk[operation];
|
|
192
|
+
if (!pin) throw new Error(`No verifier key pin for '${operation}'`);
|
|
193
|
+
return `${operation}:${pin}`;
|
|
194
|
+
});
|
|
195
|
+
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(pins.join("\n")));
|
|
196
|
+
return HexBytes.fromByteArray(new Uint8Array(digest));
|
|
197
|
+
};
|
|
198
|
+
/**
|
|
199
|
+
* The verifier key of each of `operations`, downloaded through the zk
|
|
200
|
+
* config provider so each one is checked against its pin and its header,
|
|
201
|
+
* and the sizes the wave plan is computed from. The plan follows the
|
|
202
|
+
* real keys, so a roster or key-size change re-plans itself.
|
|
203
|
+
*/
|
|
204
|
+
const loadVerifierKeys = async (providers, operations) => {
|
|
205
|
+
const zkConfig = providers.zkConfigProvider;
|
|
206
|
+
const keys = new Map(await Promise.all(operations.map(async (operation) => {
|
|
207
|
+
const key = await zkConfig.getVerifierKey(operation);
|
|
208
|
+
assertVerifierKeyHeader(operation, key);
|
|
209
|
+
return [operation, key];
|
|
210
|
+
})));
|
|
211
|
+
return {
|
|
212
|
+
keys,
|
|
213
|
+
sizes: new Map([...keys].map(([operation, key]) => [operation, key.length]))
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
const queryContractState = async ({ providers, address }) => providers.publicDataProvider.queryContractState(address);
|
|
217
|
+
/** The contract state as the indexer serves it, which must exist. */
|
|
218
|
+
const readProvidedState = async (chain) => {
|
|
219
|
+
const state = await queryContractState(chain);
|
|
220
|
+
if (!state) throw new AccountContractMissingError(`No live Account Custody Contract found at ${chain.address}.`);
|
|
221
|
+
return state;
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* The contract state as it stands on chain, read as the ledger's class.
|
|
225
|
+
* The public data provider hands back a compact-runtime state; the two
|
|
226
|
+
* bridge by serialisation.
|
|
227
|
+
*/
|
|
228
|
+
const readContractState = async (chain) => chain.ledger.ContractState.deserialize((await readProvidedState(chain)).serialize());
|
|
229
|
+
/**
|
|
230
|
+
* The contract maintenance authority as it stands on chain: its
|
|
231
|
+
* committee, threshold and the counter the next update is built against.
|
|
232
|
+
*
|
|
233
|
+
* @throws {@link AccountContractMissingError} when the address holds no
|
|
234
|
+
* live contract.
|
|
235
|
+
*/
|
|
236
|
+
const readMaintenanceAuthority = async (chain) => (await readContractState(chain)).maintenanceAuthority;
|
|
237
|
+
/**
|
|
238
|
+
* Blocks until the indexer serves the contract the deploy created. The
|
|
239
|
+
* deploy is final once its submission settles, but the indexer can lag
|
|
240
|
+
* the block it landed in, and the first wave reads the authority counter
|
|
241
|
+
* from it.
|
|
242
|
+
*/
|
|
243
|
+
const awaitContractIndexed = async (chain, sleep) => {
|
|
244
|
+
for (let attempt = 0; attempt < INDEXED_POLL_ATTEMPTS; attempt++) {
|
|
245
|
+
if (await queryContractState(chain)) return;
|
|
246
|
+
await sleep(AUTHORITY_POLL_DELAY_MS);
|
|
247
|
+
}
|
|
248
|
+
throw new AccountContractMissingError(`The Account Custody Contract deployed at ${chain.address} never appeared in the indexer.`);
|
|
249
|
+
};
|
|
250
|
+
/**
|
|
251
|
+
* Blocks until the chain shows the counter a wave advanced the authority
|
|
252
|
+
* to. The next update must be built against the advanced counter, and
|
|
253
|
+
* the indexer can lag the block the wave landed in.
|
|
254
|
+
*/
|
|
255
|
+
const awaitAuthorityCounter = async (chain, expected, sleep) => {
|
|
256
|
+
for (let attempt = 0; attempt < AUTHORITY_POLL_ATTEMPTS; attempt++) {
|
|
257
|
+
const { maintenanceAuthority } = await readContractState(chain);
|
|
258
|
+
if (maintenanceAuthority.counter >= expected) return;
|
|
259
|
+
await sleep(AUTHORITY_POLL_DELAY_MS);
|
|
260
|
+
}
|
|
261
|
+
throw new Error(`The maintenance authority counter of ${chain.address} never reached ${expected}`);
|
|
262
|
+
};
|
|
263
|
+
/**
|
|
264
|
+
* Submits one maintenance update carrying the signature of the sole
|
|
265
|
+
* committee member, at index 0, and blocks until the chain shows the
|
|
266
|
+
* counter its application advanced the authority to, so the next update
|
|
267
|
+
* or call is built against the advanced state.
|
|
268
|
+
*
|
|
269
|
+
* @throws when the update lands with a failing status, or when the
|
|
270
|
+
* counter never advances within the polling window.
|
|
271
|
+
*/
|
|
272
|
+
const submitMaintenanceUpdate = async ({ providers, ledger, address, networkId, update, signature, label, sleep = defaultSleep, sponsorReady = noSponsorSetup }) => {
|
|
273
|
+
assertSubmitted(label, await submitTx(providers, { unprovenTx: ledger.Transaction.fromParts(networkId.getNetworkId(), void 0, void 0, ledger.Intent.new(await transactionTtl(sponsorReady)).addMaintenanceUpdate(update.addSignature(0n, signature))) }));
|
|
274
|
+
await awaitAuthorityCounter({
|
|
275
|
+
providers,
|
|
276
|
+
ledger,
|
|
277
|
+
address
|
|
278
|
+
}, update.counter + 1n, sleep);
|
|
279
|
+
};
|
|
280
|
+
/**
|
|
281
|
+
* The committee that succeeds the deploy-time authority: none for a
|
|
282
|
+
* locked account, which retires it, or else the handover authority
|
|
283
|
+
* alone, so every device holding the roster key can sign maintenance.
|
|
284
|
+
*/
|
|
285
|
+
const successorOf = ({ lockAccount, handoverAuthority }) => lockAccount ? [] : [handoverAuthority];
|
|
286
|
+
/** Whether a committee on chain is exactly `expected`, member for member. */
|
|
287
|
+
const isCommittee = (committee, expected) => committee.length === expected.length && committee.every((member, index) => isSameAuthority(member, expected[index]));
|
|
288
|
+
const verifierKeyOf = (verifierKeys, operation) => {
|
|
289
|
+
const key = verifierKeys.get(operation);
|
|
290
|
+
if (!key) throw new Error(`No verifier key loaded for '${operation}'`);
|
|
291
|
+
return key;
|
|
292
|
+
};
|
|
293
|
+
/**
|
|
294
|
+
* Submits the maintenance waves in order, each one update carrying its
|
|
295
|
+
* batch of verifier key inserts, signed by the maintenance authority key.
|
|
296
|
+
* The counter is read from chain before every update because each
|
|
297
|
+
* applied update advances it, and the wave that replaces the authority
|
|
298
|
+
* installs the successor committee, threshold one, at the counter its
|
|
299
|
+
* own application leaves behind.
|
|
300
|
+
*/
|
|
301
|
+
const installWaves = async ({ providers, ledger, address, networkId, waves, verifierKeys, authorityKey, successor, sleep, sponsorReady }) => {
|
|
302
|
+
const chain = {
|
|
303
|
+
providers,
|
|
304
|
+
ledger,
|
|
305
|
+
address
|
|
306
|
+
};
|
|
307
|
+
for (const [index, wave] of waves.entries()) {
|
|
308
|
+
const { counter } = await readMaintenanceAuthority(chain);
|
|
309
|
+
const updates = wave.operations.map((operation) => verifierKeyInsert(ledger, operation, verifierKeyOf(verifierKeys, operation)));
|
|
310
|
+
if (wave.replacesAuthority) updates.push(new ledger.ReplaceAuthority(new ledger.ContractMaintenanceAuthority([...successor], 1, counter + 1n)));
|
|
311
|
+
const update = new ledger.MaintenanceUpdate(address, updates, counter);
|
|
312
|
+
await submitMaintenanceUpdate({
|
|
313
|
+
...chain,
|
|
314
|
+
networkId,
|
|
315
|
+
update,
|
|
316
|
+
signature: ledger.signData(authorityKey, update.dataToSign),
|
|
317
|
+
label: `Verifier key wave ${index + 1} of ${waves.length}`,
|
|
318
|
+
sleep,
|
|
319
|
+
sponsorReady
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
/**
|
|
324
|
+
* Connects to the deployed contract and returns the account with its
|
|
325
|
+
* activation call. The connection checks the pinned circuits' keys on
|
|
326
|
+
* chain, so it runs only once every wave is in.
|
|
327
|
+
*/
|
|
328
|
+
const toDeployedAccount = async ({ providers, findContract, compiledContract, address, publicKey, salt, privateStateId, isActivated }) => {
|
|
329
|
+
const found = await findContract(providers, {
|
|
330
|
+
contractAddress: address,
|
|
331
|
+
compiledContract,
|
|
332
|
+
privateStateId,
|
|
333
|
+
initialPrivateState: initialAccountPrivateState()
|
|
334
|
+
});
|
|
335
|
+
return {
|
|
336
|
+
address,
|
|
337
|
+
salt,
|
|
338
|
+
isActivated,
|
|
339
|
+
activate: async () => {
|
|
340
|
+
const finalized = await submitWithDustRetry(async () => found.callTx[ACTIVATE_INITIAL_DEVICE_CIRCUIT](publicKey, salt));
|
|
341
|
+
assertSubmitted("Account activation", finalized);
|
|
342
|
+
return finalized;
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
};
|
|
346
|
+
const compileAccountContract = (CompiledContract) => CompiledContract.make("account", Contract).pipe(CompiledContract.withWitnesses(accountWitnesses));
|
|
347
|
+
const privateStateIdFrom = (randomBytes) => `account-${HexBytes.fromByteArray(randomBytes(PRIVATE_STATE_ID_LENGTH$1))}`;
|
|
348
|
+
/**
|
|
349
|
+
* The state the deploy carries: the constructor's data and maintenance
|
|
350
|
+
* authority with only the first wave's operations, each one's verifier
|
|
351
|
+
* key set from the downloaded, header-checked bytes. The pipeline's own
|
|
352
|
+
* state is not reused as is because compact-js fills verifier keys only
|
|
353
|
+
* for the circuits the zk config provider lists, the manifest-pinned
|
|
354
|
+
* ones, so the deposits would land without a key.
|
|
355
|
+
*/
|
|
356
|
+
const toDeployedState = ({ ledger, fullState, operations, verifierKeys }) => {
|
|
357
|
+
const deployedState = new ledger.ContractState();
|
|
358
|
+
deployedState.data = fullState.data;
|
|
359
|
+
deployedState.maintenanceAuthority = fullState.maintenanceAuthority;
|
|
360
|
+
for (const name of operations) {
|
|
361
|
+
const operation = fullState.operation(name);
|
|
362
|
+
if (!operation) throw new Error(`Compiled account contract has no operation '${name}'`);
|
|
363
|
+
operation.verifierKey = verifierKeyOf(verifierKeys, name);
|
|
364
|
+
deployedState.setOperation(name, operation);
|
|
365
|
+
}
|
|
366
|
+
return deployedState;
|
|
367
|
+
};
|
|
368
|
+
/**
|
|
369
|
+
* Deploys a fresh Account Custody Contract carrying the deposits, the
|
|
370
|
+
* jubjub device arm and the grant circuits, including the secp256k1
|
|
371
|
+
* grantee withdrawals, and returns its address, the boot salt, and the
|
|
372
|
+
* activation call.
|
|
373
|
+
*
|
|
374
|
+
* The constructor cannot insert the initial device entry (the contract
|
|
375
|
+
* address does not exist yet inside it), so it stores a salted boot
|
|
376
|
+
* commitment over the authoriser's public key with no device entry yet;
|
|
377
|
+
* `activate` presents the same key and salt to install the real entry
|
|
378
|
+
* once every wave is in.
|
|
379
|
+
*
|
|
380
|
+
* The constructor also publishes the account's recovery material: a
|
|
381
|
+
* recovery public key, the wrap its secret is sealed under, and the veto
|
|
382
|
+
* window a recovery must survive. This module offers no recovery, so it
|
|
383
|
+
* publishes a throwaway: a fresh jubjub key whose secret is discarded
|
|
384
|
+
* here and a three day window. No secret is sealed, so the wrap is left
|
|
385
|
+
* empty: all zero bytes are the unambiguous "no container" encoding,
|
|
386
|
+
* whereas random bytes would be indistinguishable on chain from a sealed
|
|
387
|
+
* viewing secret. Nobody holds the secret, so the account is recoverable
|
|
388
|
+
* by nobody, exactly as before the contract gained the field.
|
|
389
|
+
*
|
|
390
|
+
* The roster's verifier keys exceed what one transaction may carry, so
|
|
391
|
+
* the deployment runs in waves: the deploy carries the budgeted prefix of
|
|
392
|
+
* the roster, and each later wave is one maintenance update inserting
|
|
393
|
+
* the next batch, signed by the maintenance authority the deploy minted.
|
|
394
|
+
* `onDeployed` is called between the deploy and the first update with
|
|
395
|
+
* what a retry needs ({@link PendingDeployment}), so an interruption
|
|
396
|
+
* leaves a deployment {@link resumeAccountDeployment} can finish.
|
|
397
|
+
* The deploy and every wave are built only once `sponsorReady`
|
|
398
|
+
* resolves, so a sponsor's setup never runs down their expiry.
|
|
399
|
+
*
|
|
400
|
+
* The maintenance authority's signing key is total custody: it can
|
|
401
|
+
* replace any operation's verifier key and release the account's assets
|
|
402
|
+
* around the device seam. The deploy-time key only signs the waves: the
|
|
403
|
+
* last wave always replaces it, and the key is dropped once the account
|
|
404
|
+
* is activated, held until then only for the duration of the flow and in
|
|
405
|
+
* the pending record a retry reads. `lockAccount` decides what replaces
|
|
406
|
+
* it, explicitly:
|
|
407
|
+
*
|
|
408
|
+
* - `true`: an unsatisfiable authority (empty committee at threshold 1).
|
|
409
|
+
* No maintenance update can ever be signed again, so the device seam
|
|
410
|
+
* becomes the only way to move the account's assets. The cost is that
|
|
411
|
+
* the account can never receive a future arm's circuits.
|
|
412
|
+
* - `false`: `handoverAuthority` alone at threshold 1, the authority the
|
|
413
|
+
* account's roster key derives. Every enrolled device that holds the
|
|
414
|
+
* roster key can then sign maintenance updates through the encryption
|
|
415
|
+
* key seam and grantees never can; a roster rotation rotates the
|
|
416
|
+
* authority with it, so a removed device loses its upgrade rights.
|
|
417
|
+
*/
|
|
418
|
+
const deployAccount = async ({ providers, authoriser, encPublicKey, lockAccount, handoverAuthority, onDeployed, randomBytes = defaultRandomBytes, sleep = defaultSleep, sponsorReady = noSponsorSetup }) => {
|
|
419
|
+
const [contracts, ledger, networkId, CompiledContract] = await importChainModules();
|
|
420
|
+
const publicKey = await authoriser.devicePublicKey();
|
|
421
|
+
const salt = randomBytes(SALT_LENGTH);
|
|
422
|
+
const bootCommitment = pureCircuits.derive_boot_commitment_with_jubjub(salt, publicKey);
|
|
423
|
+
const recoveryPublicKey = JubjubDevice.generate().pk;
|
|
424
|
+
const recoveryWrap = new Uint8Array(RECOVERY_WRAP_LENGTH);
|
|
425
|
+
const privateStateId = privateStateIdFrom(randomBytes);
|
|
426
|
+
const compiledContract = compileAccountContract(CompiledContract);
|
|
427
|
+
const createDeployTransaction = contracts.createUnprovenDeployTx;
|
|
428
|
+
const deployData = await createDeployTransaction(providers, {
|
|
429
|
+
compiledContract,
|
|
430
|
+
initialPrivateState: initialAccountPrivateState(),
|
|
431
|
+
args: [
|
|
432
|
+
bootCommitment,
|
|
433
|
+
encPublicKey,
|
|
434
|
+
recoveryPublicKey,
|
|
435
|
+
recoveryWrap,
|
|
436
|
+
VETO_WINDOW_SECONDS
|
|
437
|
+
]
|
|
438
|
+
});
|
|
439
|
+
const fullState = ledger.ContractState.deserialize(deployData.public.initialContractState.serialize());
|
|
440
|
+
const { keys: verifierKeys, sizes } = await loadVerifierKeys(providers, DEPLOYED_OPERATIONS);
|
|
441
|
+
const verifierKeysDigest = await deployedVerifierKeysDigest();
|
|
442
|
+
const [deployWave, ...maintenanceWaves] = planDeployWaves(DEPLOYED_OPERATIONS, sizes);
|
|
443
|
+
const deploy = new ledger.ContractDeploy(toDeployedState({
|
|
444
|
+
ledger,
|
|
445
|
+
fullState,
|
|
446
|
+
operations: deployWave.operations,
|
|
447
|
+
verifierKeys
|
|
448
|
+
}));
|
|
449
|
+
const address = String(deploy.address);
|
|
450
|
+
assertSubmitted("Account deploy", await submitTx(providers, { unprovenTx: ledger.Transaction.fromParts(networkId.getNetworkId(), void 0, void 0, ledger.Intent.new(await transactionTtl(sponsorReady)).addDeploy(deploy)) }));
|
|
451
|
+
const authorityKey = deployData.private.signingKey;
|
|
452
|
+
await onDeployed(address, {
|
|
453
|
+
operations: [...DEPLOYED_OPERATIONS],
|
|
454
|
+
lockAccount,
|
|
455
|
+
verifierKeysDigest,
|
|
456
|
+
saltHex: HexBytes.fromByteArray(salt),
|
|
457
|
+
authorityKey,
|
|
458
|
+
handoverAuthority
|
|
459
|
+
});
|
|
460
|
+
await awaitContractIndexed({
|
|
461
|
+
providers,
|
|
462
|
+
ledger,
|
|
463
|
+
address
|
|
464
|
+
}, sleep);
|
|
465
|
+
await installWaves({
|
|
466
|
+
providers,
|
|
467
|
+
ledger,
|
|
468
|
+
address,
|
|
469
|
+
networkId,
|
|
470
|
+
waves: maintenanceWaves,
|
|
471
|
+
verifierKeys,
|
|
472
|
+
authorityKey,
|
|
473
|
+
successor: successorOf({
|
|
474
|
+
lockAccount,
|
|
475
|
+
handoverAuthority
|
|
476
|
+
}),
|
|
477
|
+
sleep,
|
|
478
|
+
sponsorReady
|
|
479
|
+
});
|
|
480
|
+
return toDeployedAccount({
|
|
481
|
+
providers,
|
|
482
|
+
findContract: contracts.findDeployedContract,
|
|
483
|
+
compiledContract,
|
|
484
|
+
address,
|
|
485
|
+
publicKey,
|
|
486
|
+
salt,
|
|
487
|
+
privateStateId,
|
|
488
|
+
isActivated: false
|
|
489
|
+
});
|
|
490
|
+
};
|
|
491
|
+
/**
|
|
492
|
+
* Whether the chain shows the deploy-time authority already replaced by
|
|
493
|
+
* the committee the recorded lock choice installs, a retirement or a
|
|
494
|
+
* handover that landed, rather than still live.
|
|
495
|
+
*
|
|
496
|
+
* @throws {@link MaintenanceAuthorityMismatchError} when the committee
|
|
497
|
+
* is neither: the waves can no longer be signed and the record does not
|
|
498
|
+
* describe this contract.
|
|
499
|
+
*/
|
|
500
|
+
const isDeployAuthorityReplaced = ({ ledger, address, committee, pending }) => {
|
|
501
|
+
if (isCommittee(committee, successorOf(pending))) return true;
|
|
502
|
+
if (isCommittee(committee, [ledger.signatureVerifyingKey(pending.authorityKey)])) return false;
|
|
503
|
+
throw new MaintenanceAuthorityMismatchError(`The maintenance authority of the account at ${address} is neither the deploy-time key nor the one its unfinished creation installs, so it cannot be resumed.`);
|
|
504
|
+
};
|
|
505
|
+
/**
|
|
506
|
+
* Finishes a deployment whose waves were interrupted. The operations the
|
|
507
|
+
* contract already holds are read from chain, the waves still missing
|
|
508
|
+
* are planned from the pending roster and submitted, and the account is
|
|
509
|
+
* returned with its activation call; a deployment that only missed its
|
|
510
|
+
* activation plans no wave at all. A deployment the chain shows already
|
|
511
|
+
* activated, because the creation died between its activation and its
|
|
512
|
+
* final record write, installs nothing and is returned as activated once
|
|
513
|
+
* the chain shows its authority replaced. The lock choice and the
|
|
514
|
+
* handover authority are the ones recorded when the deployment began.
|
|
515
|
+
* The chain's authority is read as the deploy-time key still live, or as
|
|
516
|
+
* already replaced when it is the committee the recorded choice
|
|
517
|
+
* installs, a retirement or a handover that landed. An activated
|
|
518
|
+
* deployment whose deploy-time key is still live is refused under either
|
|
519
|
+
* choice: the flow replaces the authority before it activates, so the
|
|
520
|
+
* waves ran outside it and the verifier keys they installed are not
|
|
521
|
+
* known to be this build's. A deployment recorded under other verifier
|
|
522
|
+
* key pins than this build installs, or without a handover authority, is
|
|
523
|
+
* refused before the chain is read.
|
|
524
|
+
*
|
|
525
|
+
* @throws {@link CreationArtefactMismatchError} when the recorded
|
|
526
|
+
* verifier key digest is missing or is not this build's, or when the
|
|
527
|
+
* record names no handover authority.
|
|
528
|
+
* @throws {@link MaintenanceAuthorityMismatchError} when the chain's
|
|
529
|
+
* authority is neither the deploy-time key nor the recorded successor.
|
|
530
|
+
* @throws {@link AuthorityNotRetiredError} when the chain shows the
|
|
531
|
+
* account activated with the deploy-time authority still live, whether it
|
|
532
|
+
* was to be locked or handed to its devices.
|
|
533
|
+
* @throws {@link AuthorityRetiredError} when operations are missing but
|
|
534
|
+
* the authority has already been replaced, which no update can mend.
|
|
535
|
+
* @throws {@link AccountContractMissingError} when the address holds no
|
|
536
|
+
* live contract.
|
|
537
|
+
*/
|
|
538
|
+
const resumeAccountDeployment = async ({ providers, authoriser, address, pending, randomBytes = defaultRandomBytes, sleep = defaultSleep, sponsorReady = noSponsorSetup }) => {
|
|
539
|
+
if (pending.verifierKeysDigest !== await deployedVerifierKeysDigest()) throw new CreationArtefactMismatchError(`The unfinished creation of the account at ${address} was started under other verifier key pins than this build installs, so it cannot be resumed.`);
|
|
540
|
+
if (!pending.handoverAuthority) throw new CreationArtefactMismatchError(`The unfinished creation of the account at ${address} names no maintenance authority to hand over to, so it cannot be resumed.`);
|
|
541
|
+
const [contracts, ledger$1, networkId, CompiledContract] = await importChainModules();
|
|
542
|
+
const publicKey = await authoriser.devicePublicKey();
|
|
543
|
+
const chain = {
|
|
544
|
+
providers,
|
|
545
|
+
ledger: ledger$1,
|
|
546
|
+
address
|
|
547
|
+
};
|
|
548
|
+
const provided = await readProvidedState(chain);
|
|
549
|
+
const isActivated = ledger(provided.data).booted;
|
|
550
|
+
const onChain = ledger$1.ContractState.deserialize(provided.serialize());
|
|
551
|
+
const isAuthorityReplaced = isDeployAuthorityReplaced({
|
|
552
|
+
ledger: ledger$1,
|
|
553
|
+
address,
|
|
554
|
+
committee: onChain.maintenanceAuthority.committee,
|
|
555
|
+
pending
|
|
556
|
+
});
|
|
557
|
+
if (isActivated && !isAuthorityReplaced) throw new AuthorityNotRetiredError(pending.lockAccount ? `The account at ${address} was created to be locked and is activated, but its maintenance authority is still live.` : `The account at ${address} was created to hand its maintenance authority to its devices, but is activated with the deploy-time authority still live.`);
|
|
558
|
+
if (!isActivated) {
|
|
559
|
+
const { keys: verifierKeys, sizes } = await loadVerifierKeys(providers, pending.operations);
|
|
560
|
+
const waves = planResumeWaves({
|
|
561
|
+
operations: pending.operations,
|
|
562
|
+
sizes,
|
|
563
|
+
installed: onChain.operations().map(String),
|
|
564
|
+
isAuthorityReplaced
|
|
565
|
+
});
|
|
566
|
+
await installWaves({
|
|
567
|
+
...chain,
|
|
568
|
+
networkId,
|
|
569
|
+
waves,
|
|
570
|
+
verifierKeys,
|
|
571
|
+
authorityKey: pending.authorityKey,
|
|
572
|
+
successor: successorOf(pending),
|
|
573
|
+
sleep,
|
|
574
|
+
sponsorReady
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
return toDeployedAccount({
|
|
578
|
+
providers,
|
|
579
|
+
findContract: contracts.findDeployedContract,
|
|
580
|
+
compiledContract: compileAccountContract(CompiledContract),
|
|
581
|
+
address,
|
|
582
|
+
publicKey,
|
|
583
|
+
salt: ByteArray.fromHex(HexBytes(pending.saltHex)),
|
|
584
|
+
privateStateId: privateStateIdFrom(randomBytes),
|
|
585
|
+
isActivated
|
|
586
|
+
});
|
|
587
|
+
};
|
|
588
|
+
//#endregion
|
|
589
|
+
//#region ../../packages/module/passport-account/src/acc/use-counter.ts
|
|
590
|
+
/** How far past the last known counter the rescan probes. */
|
|
591
|
+
const RESCAN_LIMIT = 4096n;
|
|
592
|
+
/**
|
|
593
|
+
* Candidates batched per deviceCommitments call. 64 keeps a typical rescan
|
|
594
|
+
* (small counter drift) at one ceremony while it caps a full-window miss at
|
|
595
|
+
* 64 ceremonies instead of 4096, and the per-chunk membership check stops
|
|
596
|
+
* the scan before the remaining commitments are ever computed.
|
|
597
|
+
*/
|
|
598
|
+
const RESCAN_CHUNK = 64n;
|
|
599
|
+
const isLiveEntry = (ledgerState, commitmentHex) => ledgerState.devices.member(ByteArray.fromHex(HexBytes(commitmentHex)));
|
|
600
|
+
const probeInBatches = async (deviceCommitments, { ledgerState, address, epoch, from, to }) => {
|
|
601
|
+
for (let chunkStart = from; chunkStart < to; chunkStart += RESCAN_CHUNK) {
|
|
602
|
+
const counters = [];
|
|
603
|
+
const chunkEnd = chunkStart + RESCAN_CHUNK < to ? chunkStart + RESCAN_CHUNK : to;
|
|
604
|
+
for (let candidate = chunkStart; candidate < chunkEnd; candidate++) counters.push(UseCounter(candidate));
|
|
605
|
+
const commitments = await deviceCommitments(address, epoch, counters);
|
|
606
|
+
for (const [index, useCounter] of counters.entries()) {
|
|
607
|
+
const commitmentHex = commitments[index];
|
|
608
|
+
if (isLiveEntry(ledgerState, commitmentHex)) return {
|
|
609
|
+
useCounter,
|
|
610
|
+
commitmentHex
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
};
|
|
615
|
+
const probeOneByOne = async ({ ledgerState, authoriser, address, epoch, from, to }) => {
|
|
616
|
+
for (let candidate = from; candidate < to; candidate++) {
|
|
617
|
+
const useCounter = UseCounter(candidate);
|
|
618
|
+
const commitmentHex = await authoriser.deviceCommitment(address, epoch, useCounter);
|
|
619
|
+
if (isLiveEntry(ledgerState, commitmentHex)) return {
|
|
620
|
+
useCounter,
|
|
621
|
+
commitmentHex
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
};
|
|
625
|
+
const probeWindow = async (props) => {
|
|
626
|
+
const { deviceCommitments } = props.authoriser;
|
|
627
|
+
return deviceCommitments ? probeInBatches(deviceCommitments, props) : probeOneByOne(props);
|
|
628
|
+
};
|
|
629
|
+
/**
|
|
630
|
+
* Recovers the device's current use counter from chain. The Account
|
|
631
|
+
* Custody Contract stores one rolling entry per device, positioned at the
|
|
632
|
+
* counter of its next authorisation, so the local counter can fall behind
|
|
633
|
+
* after out-of-band calls or lost state. Candidate counters are probed
|
|
634
|
+
* from the last known value (0 when unknown): the commitment computed for
|
|
635
|
+
* each candidate is tested for membership in the on-chain device set, and
|
|
636
|
+
* the first live entry wins. That window ends after RESCAN_LIMIT
|
|
637
|
+
* candidates, and only then are the counters below the anchor probed,
|
|
638
|
+
* from 0 up to it: a device removed and re-enrolled gets a fresh entry at
|
|
639
|
+
* a low counter while the persisted anchor still holds the old high one,
|
|
640
|
+
* and without the second pass such a device reads as revoked. A device
|
|
641
|
+
* with no entry in either pass is not registered on the account, has been
|
|
642
|
+
* revoked, or holds a counter beyond the probed window (a synced passkey
|
|
643
|
+
* used heavily on another device can outrun RESCAN_LIMIT between
|
|
644
|
+
* sign-ins here); the miss raises DeviceEntryNotFoundError, which names
|
|
645
|
+
* that ambiguity. An authoriser exposing deviceCommitments is probed in
|
|
646
|
+
* RESCAN_CHUNK batches so one key ceremony covers a whole chunk of
|
|
647
|
+
* candidates; otherwise each candidate costs one deviceCommitment call.
|
|
648
|
+
*/
|
|
649
|
+
const resolveUseCounter = async ({ ledgerState, authoriser, address, knownUseCounter }) => {
|
|
650
|
+
const epoch = DeviceEpoch(ledgerState.device_epoch);
|
|
651
|
+
const anchor = knownUseCounter ?? 0n;
|
|
652
|
+
const probe = async (from, to) => probeWindow({
|
|
653
|
+
ledgerState,
|
|
654
|
+
authoriser,
|
|
655
|
+
address,
|
|
656
|
+
epoch,
|
|
657
|
+
from,
|
|
658
|
+
to
|
|
659
|
+
});
|
|
660
|
+
const ahead = await probe(anchor, anchor + RESCAN_LIMIT);
|
|
661
|
+
if (ahead) return ahead;
|
|
662
|
+
const behind = await probe(0n, anchor);
|
|
663
|
+
if (behind) return behind;
|
|
664
|
+
throw new DeviceEntryNotFoundError(`No live device entry on the ledger within ${RESCAN_LIMIT} counters of the last known one (${anchor}), nor below it; the device is not registered on this account, or its counter has moved beyond the probed window.`);
|
|
665
|
+
};
|
|
666
|
+
//#endregion
|
|
667
|
+
//#region ../../packages/module/passport-account/src/acc/gated-call.ts
|
|
668
|
+
const PRIVATE_STATE_ID_LENGTH = 8;
|
|
669
|
+
/**
|
|
670
|
+
* Connects to a deployed Account Custody Contract and returns the handle
|
|
671
|
+
* gated calls run through. The private state starts without the account
|
|
672
|
+
* encryption secret: the device-management and grant lifecycle circuits
|
|
673
|
+
* consume no witnesses, so no coin or encryption key material is needed.
|
|
674
|
+
* Shielded flows will seed the viewing secret when they arrive.
|
|
675
|
+
*/
|
|
676
|
+
const connectAccountHandle = async (providers, contractAddress) => {
|
|
677
|
+
const [contracts, CompiledContract] = await Promise.all([import("@midnight-ntwrk/midnight-js-contracts"), import("@midnight-ntwrk/compact-js/effect/CompiledContract")]);
|
|
678
|
+
const compiledContract = CompiledContract.make("account", Contract).pipe(CompiledContract.withWitnesses(accountWitnesses));
|
|
679
|
+
const findContract = contracts.findDeployedContract;
|
|
680
|
+
return findContract(providers, {
|
|
681
|
+
contractAddress,
|
|
682
|
+
compiledContract,
|
|
683
|
+
privateStateId: `account-${HexBytes.fromByteArray(crypto.getRandomValues(new Uint8Array(PRIVATE_STATE_ID_LENGTH)))}`,
|
|
684
|
+
initialPrivateState: initialAccountPrivateState()
|
|
685
|
+
});
|
|
686
|
+
};
|
|
687
|
+
/**
|
|
688
|
+
* Executes one authorised circuit call against a deployed Account Custody
|
|
689
|
+
* Contract: resolves the device's current use counter from the ledger,
|
|
690
|
+
* has the authoriser sign the call over the observed auth nonce, submits
|
|
691
|
+
* the circuit with the authorising material appended as its trailing
|
|
692
|
+
* arguments (pk, use counter, announcement, closing scalar, grind nonce),
|
|
693
|
+
* and returns the counter the device holds after the accepted call: the
|
|
694
|
+
* consumed one plus one.
|
|
695
|
+
*
|
|
696
|
+
* A transaction that lands with a failing status rejects instead of
|
|
697
|
+
* returning: the contract applied nothing, so no counter may advance and
|
|
698
|
+
* no roster change may be recorded for it.
|
|
699
|
+
*/
|
|
700
|
+
const executeGatedCall = async ({ handle, authoriser, circuit, args, address, ledgerState, knownUseCounter }) => {
|
|
701
|
+
const call = handle.callTx[circuit];
|
|
702
|
+
if (!call) throw new Error(`Account contract handle has no circuit '${circuit}'`);
|
|
703
|
+
const { useCounter } = await resolveUseCounter({
|
|
704
|
+
ledgerState,
|
|
705
|
+
authoriser,
|
|
706
|
+
address,
|
|
707
|
+
knownUseCounter
|
|
708
|
+
});
|
|
709
|
+
const authorisation = await authoriser.authorise({
|
|
710
|
+
account: address,
|
|
711
|
+
circuit,
|
|
712
|
+
args,
|
|
713
|
+
witnessValues: [],
|
|
714
|
+
authNonce: ledgerState.auth_nonce,
|
|
715
|
+
useCounter
|
|
716
|
+
});
|
|
717
|
+
const finalized = await submitWithDustRetry(async () => call(...args, ...authArgs(authorisation)));
|
|
718
|
+
assertSubmitted(`Call to ${circuit}`, finalized);
|
|
719
|
+
return UseCounter(useCounter + 1n);
|
|
720
|
+
};
|
|
721
|
+
//#endregion
|
|
722
|
+
export { loadVerifierKeys as a, submitMaintenanceUpdate as c, UseCounter as d, deployAccount as i, planInstallWaves as l, executeGatedCall as n, readMaintenanceAuthority as o, resolveUseCounter as r, resumeAccountDeployment as s, connectAccountHandle as t, DeviceEpoch as u };
|