@laceio/sdk 0.1.1-canary.2 → 0.1.1
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-CCjOn7NA.cjs → TransactionBuilder-DrB3NVTi.cjs} +0 -42
- package/dist/{TransactionBuilder-CIzdw18M.js → TransactionBuilder-V6aLx4SV.js} +1 -1
- package/dist/{_polyfill-buffer-patch-CM8X7JiY.cjs → _polyfill-buffer-patch-BnPVerlG.cjs} +2 -21
- package/dist/account-guards.stable-B1DSSh9D.cjs +10 -0
- package/dist/account-guards.stable-JRQ5qx2V.js +5 -0
- package/dist/{activity-type-Ch6ljxBy.cjs → activity-type.stable-BJEfeLxL.cjs} +1 -2
- package/dist/{activity-type-GsJGWs-3.js → activity-type.stable-C76_hWd7.js} +1 -2
- package/dist/{address-book-address-validator-ByIZOdO-.js → address-book-address-validator-DIUolI-s.js} +2 -2
- package/dist/{address-book-address-validator-BjOWerRE.cjs → address-book-address-validator-DNwQGlOB.cjs} +2 -2
- package/dist/bitcoin.cjs +0 -45
- package/dist/bitcoin.d.ts +1 -29782
- package/dist/bitcoin.js +0 -20
- package/dist/{blockfrost-tx-submit-provider-CLNQ5ycR.cjs → blockfrost-tx-submit-provider-BAIzV5o3.cjs} +167 -3
- package/dist/{blockfrost-tx-submit-provider-CBWQ0wK9.js → blockfrost-tx-submit-provider-DPTrapz-.js} +157 -5
- package/dist/{secret-box-DrjLZuS1.cjs → bytes.vo-Ck5u40RA.cjs} +35 -1
- package/dist/{secret-box-DUR0ACYz.js → bytes.vo-TgiwogWF.js} +25 -3
- package/dist/{cardano-network-id.vo-wfLiAxpY.js → cardano-network-id.vo-CK1tNQDg.js} +1 -1
- package/dist/{cardano-network-id.vo-BEvFd_74.cjs → cardano-network-id.vo-DSxrFk9S.cjs} +1 -1
- package/dist/cardano.cjs +18 -22
- package/dist/cardano.d.ts +3982 -18409
- package/dist/cardano.js +11 -16
- package/dist/codecs-B7X9pAsK.cjs +1945 -0
- package/dist/codecs-CC1Xjntz.js +1882 -0
- package/dist/{const-oMF-TLow.cjs → const-BDEg2Trq.cjs} +4 -4
- package/dist/{const-iwzZEE_w.cjs → const-BY8B3_0_.cjs} +1 -1
- package/dist/{const-CBGn60yu.js → const-C84qHkjp.js} +4 -4
- package/dist/{const-CjmfjBP3.js → const-DXk2tFyv.js} +1 -1
- package/dist/{delegation-tx-builder-BR6bt1fE.js → delegation-tx-builder-CGVqlaFE.js} +5 -5
- package/dist/{delegation-tx-builder-DVwGfiV0.cjs → delegation-tx-builder-CRpLP6jH.cjs} +6 -6
- package/dist/{deregistration-tx-builder-BhJRGj1M.js → deregistration-tx-builder-B-CrUyX6.js} +5 -5
- package/dist/{deregistration-tx-builder-Cv_09HGf.cjs → deregistration-tx-builder-DZGwB4cz.cjs} +6 -6
- package/dist/{earn-rewards-tx-builder-RYzKsZ6-.js → earn-rewards-tx-builder-BDbTDZmD.js} +5 -5
- package/dist/{earn-rewards-tx-builder-52gJiJYa.cjs → earn-rewards-tx-builder-D5sUT5v8.cjs} +6 -6
- package/dist/{group-cardano-addresses-by-account-D06r7daZ.cjs → group-cardano-addresses-by-account-B533oVXR.cjs} +35 -19
- package/dist/{group-cardano-addresses-by-account-CxCqFDrX.js → group-cardano-addresses-by-account-RHKoEskR.js} +35 -19
- package/dist/{guarded-transaction-signer-BhnTBjf6.cjs → guarded-transaction-signer-Bxl6_XNd.cjs} +18 -17
- package/dist/{guarded-transaction-signer-BSEx83R-.js → guarded-transaction-signer-CpKLj8Kp.js} +15 -8
- package/dist/{in-memory-wallet-integration-CH4rcg92.cjs → in-memory-wallet-integration-CnLYeX4-.cjs} +108 -17
- package/dist/{in-memory-wallet-integration-BKu985Jz.js → in-memory-wallet-integration-Croiuopx.js} +104 -7
- package/dist/{in-memory-wallet-integration-B0blZBxM.js → in-memory-wallet-integration-D-qn65Kx.js} +2 -5
- package/dist/{in-memory-wallet-integration-CwPCDMIe.cjs → in-memory-wallet-integration-DVh9sRXa.cjs} +2 -3
- package/dist/index.cjs +47 -84
- package/dist/index.d.ts +13618 -40268
- package/dist/index.js +24 -52
- package/dist/{init-DUF4ar8P.cjs → init-B64zCLxG.cjs} +4 -4
- package/dist/{init-Y3mkB4XS.js → init-BAJJzBza.js} +2 -2
- package/dist/{init-BTzOjA8x.cjs → init-BJVU54pI.cjs} +1 -1
- package/dist/{init-D6BxBs7e.cjs → init-BKhH6mVR.cjs} +1 -1
- package/dist/{init-EP0CUWNK.cjs → init-BsCBAGWf.cjs} +2 -2
- package/dist/{init-Dy-05ktr.cjs → init-BtzMZ7Pk.cjs} +1 -1
- package/dist/init-Bv53hpLM.js +19 -0
- package/dist/{init-BopV9ed4.cjs → init-C-jErzp5.cjs} +2 -2
- package/dist/{init-CjT-WZcW.cjs → init-C4Bkib9u.cjs} +59 -49
- package/dist/{init-BEjCRHxU.cjs → init-C7IeJwQR.cjs} +61 -258
- package/dist/{init-C-G32J12.cjs → init-CB__aLD7.cjs} +2 -2
- package/dist/{init-CyAY4Lzl.js → init-CFYsq82V.js} +1 -1
- package/dist/{init-0zzs9aqU.js → init-CLHuAMB-.js} +4 -4
- package/dist/{init-DA7zmptx.js → init-CNLGJJRx.js} +1 -1
- package/dist/{init-B-YE57gg.js → init-CR6tpw1B.js} +33 -25
- package/dist/init-CRbjI7p1.js +3494 -0
- package/dist/{init-CSDpdu0Q.cjs → init-CSHwHnfg.cjs} +2 -2
- package/dist/{init-CNM5m7M2.js → init-Cg9XdAru.js} +4 -4
- package/dist/{init-B3-1ghyx.js → init-CigestoM.js} +2 -2
- package/dist/{init-Dv3zKj0r.cjs → init-D6DBUsD3.cjs} +4 -4
- package/dist/init-DAna1KCg.cjs +3495 -0
- package/dist/{init-D74mn8nH2.js → init-DDdhguVC.js} +2 -2
- package/dist/init-DGe47B22.cjs +364 -0
- package/dist/init-DMtyvYfC.cjs +21 -0
- package/dist/{init-BrdVzxei.cjs → init-DX4WyB0R.cjs} +3 -3
- package/dist/{init-C8URA2OX.js → init-DcYY6zMD.js} +1 -1
- package/dist/{init-DFMiP2ZH.cjs → init-DkIc5nqF.cjs} +1 -1
- package/dist/{init-vqxOQNZi.js → init-Dku4b2lG.js} +1 -1
- package/dist/{init-NdhG_VrF.cjs → init-DxUHsN53.cjs} +6 -6
- package/dist/{init-COMH3Hfo.js → init-FMGDET-9.js} +60 -259
- package/dist/{init-DrkOb-wd.cjs → init-LfyMo-sS.cjs} +2 -2
- package/dist/{init-NCjgwCZy.js → init-Rxohwpmu.js} +2 -2
- package/dist/init-TkPDD750.js +363 -0
- package/dist/{init-C2RgrfZe.js → init-TkPq_Ny_.js} +1 -1
- package/dist/{init-5KcGcBb5.cjs → init-U8c9yHYx.cjs} +1 -1
- package/dist/{init-CX0AMQUn.js → init-aJHl-7AO.js} +2 -2
- package/dist/{init-rmt7-fQE.cjs → init-anYu6XB7.cjs} +2 -2
- package/dist/{init-Fw89ZmrR.js → init-w9GEs73W.js} +2 -2
- package/dist/{init-Dnsv155v.js → init-y2Ra0vZP.js} +3 -3
- package/dist/{init-DFjT8YvT.js → init-zSzCjoor.js} +4 -4
- package/dist/{is-retriable-error-BUiVJDwH.js → is-retriable-error-BU0e3hVI.js} +1 -1
- package/dist/{is-retriable-error-Dpt860if.cjs → is-retriable-error-CeeuHqDa.cjs} +1 -1
- package/dist/{lace-context-BZciB9c7.js → lace-context-CZcNHr4M.js} +4 -4
- package/dist/{lace-context-DgR6vLli.cjs → lace-context-fJTDghdp.cjs} +4 -4
- package/dist/{libsodium-wrappers-BhbOA8dQ.js → libsodium-wrappers-UH0LaOUE.js} +1647 -3
- package/dist/modules-cardano-BDvuL4Xx.js +5248 -0
- package/dist/modules-cardano-D2G3De2P.cjs +5432 -0
- package/dist/{retry-config-Dmgt28wM.js → retry-config-BcUmMS--.js} +1 -1
- package/dist/{retry-config-BaCfVC1H.cjs → retry-config-DC5IMaH7.cjs} +1 -1
- package/dist/{seam-cardano-B_etH4F4.js → seam-cardano-CATqBEyK.js} +1 -1
- package/dist/{signer-factory-B7PMe3lQ.js → signer-factory-9URFliA5.js} +3 -6
- package/dist/{signer-factory-DduwpsQj.cjs → signer-factory-BWGUmnvm.cjs} +3 -4
- package/dist/{slice-CqVNnz-j.js → slice-B2PhoWAg.js} +125 -316
- package/dist/{slice-DyNs7oWp.js → slice-BNu73oBa.js} +2 -2
- package/dist/{slice-GwiiJRoq.js → slice-CB4SnzMm.js} +3 -3
- package/dist/slice-CGVHXHDt.cjs +125 -0
- package/dist/{slice-CU80pbiu.js → slice-CnyWevM9.js} +3 -3
- package/dist/{slice-CwyYrh1H.js → slice-CobanYgn.js} +2 -2
- package/dist/{slice-7G2xxYKJ.cjs → slice-CuHUaPZx.cjs} +3 -3
- package/dist/{slice-DayJvMRD.cjs → slice-D11m2EKl.cjs} +1 -1
- package/dist/{slice-Bg6HEr3K.cjs → slice-DGcNrbPR.cjs} +4 -4
- package/dist/{slice-B4CdYoPu.cjs → slice-DZmQJNV8.cjs} +2 -2
- package/dist/slice-DhvF7L6X.js +107 -0
- package/dist/{slice-C9TT5KhY.cjs → slice-Do2R2CYW.cjs} +6 -6
- package/dist/{slice-Bs2aMERu.cjs → slice-DtaO72qY.cjs} +3 -3
- package/dist/{slice-C34iOOUH.cjs → slice-HeHCv3bl.cjs} +7 -7
- package/dist/{slice-D-9aPKG-.js → slice-d0p6-xj5.js} +6 -6
- package/dist/{slice-CK07EBCo.js → slice-eIwcwKHI.js} +4 -4
- package/dist/{slice-DBpJ2QGf.js → slice-maaskdUn.js} +6 -6
- package/dist/{slice-6sP0Qs5V.cjs → slice-mxLQ_FeY.cjs} +127 -343
- package/dist/{slice-DnG-yvpI.cjs → slice-oqm_r1cS.cjs} +2 -2
- package/dist/{slice-Da426sf9.js → slice-zJ9XVYjZ.js} +1 -1
- package/dist/{sync-operation-utils-KT5Y9yFK.js → sync-operation-utils-BYXLO80m.js} +52 -1
- package/dist/{sync-operation-utils-C9kcmjKH.cjs → sync-operation-utils-SdPbwFoD.cjs} +87 -0
- package/dist/{token-id-mapper-qx7XfH0b.js → token-id-mapper-B2ivlLv3.js} +2 -2
- package/dist/{token-id-mapper-IApjwuJb.cjs → token-id-mapper-DsPAL6Nh.cjs} +2 -2
- package/dist/{util-D1e0skzp.js → util-BaLzwa32.js} +1 -1
- package/dist/{util-BeG7WXzM.cjs → util-CGzqQ8IV.cjs} +1 -1
- package/dist/{utils-DsElZgCI.cjs → utils-5JvjbqH3.cjs} +1 -7
- package/dist/{utils-BfBEUvWA.js → utils-o8aMjfln.js} +2 -2
- package/dist/{vote-delegation-tx-builder-CtdIgaIt.cjs → vote-delegation-tx-builder-BpEMSti4.cjs} +6 -6
- package/dist/{vote-delegation-tx-builder-CQjGvVNZ.js → vote-delegation-tx-builder-CmKv6GoG.js} +5 -5
- package/package.json +4 -96
- package/dist/_polyfill-buffer-patch-yNxN4d5E.js +0 -1467
- package/dist/_web-crypto-random-bytes-Bo-GTcRS.js +0 -197
- package/dist/acc-module-4iIUv6My.cjs +0 -27654
- package/dist/acc-module-Cmj8EsIb.js +0 -27624
- package/dist/account-BlYkEmcs.cjs +0 -11
- package/dist/account-DVX0F5_M.js +0 -6
- package/dist/account-call-D68oF6bh.js +0 -267
- package/dist/account-call-DIIa2rK_.cjs +0 -314
- package/dist/account-call-NgLhYein.cjs +0 -4
- package/dist/account-call-n-Nkp35e.js +0 -3
- package/dist/account-guards-BtjTGxDZ.cjs +0 -42
- package/dist/account-guards-D9Lu5T3W.js +0 -36
- package/dist/account-tokens-CtN2BaFy.js +0 -16
- package/dist/account-tokens-DXr8DlpW.cjs +0 -21
- package/dist/address-B9ntKL8K.js +0 -13761
- package/dist/address-BXp-mY8H.cjs +0 -11270
- package/dist/address-book-address-validator-DK0dnsRS.cjs +0 -41
- package/dist/address-book-address-validator-Di_ywo8M.js +0 -39
- package/dist/artefact-loader-54uK5RAa.js +0 -160
- package/dist/artefact-loader-DZPYrq-6.cjs +0 -183
- package/dist/auto-dismiss-failure-on-success-C-qoJuid.cjs +0 -37
- package/dist/auto-dismiss-failure-on-success-s8MGDEIu.js +0 -31
- package/dist/bip32-D6wd_QMn.cjs +0 -3851
- package/dist/bitcoin-data-provider-BYPSmuZS.js +0 -21
- package/dist/bitcoin-data-provider-w1oEDSU3.cjs +0 -26
- package/dist/bn-d3nSOIf7.cjs +0 -2553
- package/dist/browser-B1eMbDwh.js +0 -7468
- package/dist/bytes.vo-BB7_4JK6.js +0 -23
- package/dist/bytes.vo-BNRquqaO.cjs +0 -34
- package/dist/cardano-DfPwhwm-.js +0 -3
- package/dist/client-DXBLHk7K.cjs +0 -808
- package/dist/codecs-Cswkg7Tm.cjs +0 -4051
- package/dist/codecs-Dc1Krpbt.js +0 -3903
- package/dist/const-BfEnY8fg.js +0 -153
- package/dist/const-BhYOdznB.cjs +0 -42
- package/dist/const-CUnCl5U0.js +0 -13
- package/dist/const-DLrX5SD9.cjs +0 -31995
- package/dist/contract-C_CBwwiC.cjs +0 -189
- package/dist/contract-s_x-9-lz.js +0 -171
- package/dist/create-add-accounts-Brqk84vF.js +0 -102
- package/dist/create-add-accounts-DzXIh7Ot.cjs +0 -114
- package/dist/device-commitment-hex.vo-5wFtQvDS.js +0 -26
- package/dist/device-commitment-hex.vo-CT3RmAug.cjs +0 -31
- package/dist/device-readers-70i7tQqU.cjs +0 -8
- package/dist/device-readers-B7--ezKM.js +0 -4
- package/dist/device-readers-BWOmz9eD.js +0 -145
- package/dist/device-readers-CIgYZN7f.cjs +0 -168
- package/dist/dist-BMi5ZjEq.cjs +0 -43175
- package/dist/dist-BtIq4XFn.cjs +0 -535
- package/dist/dist-C3SHC_Ho.cjs +0 -1394
- package/dist/dist-CykEjYEX.cjs +0 -3814
- package/dist/dist-Dcsxh3be.cjs +0 -3452
- package/dist/dist-DqJfSlTd.cjs +0 -4413
- package/dist/dist-nTZ70qj7.cjs +0 -1306
- package/dist/enc-key-circuits-C8fGAMEF.cjs +0 -24
- package/dist/enc-key-circuits-DA2Xs3vZ.js +0 -13
- package/dist/english-Byb9M0E_.cjs +0 -2057
- package/dist/envelopes-BkH1Qdxk.js +0 -1620
- package/dist/envelopes-ETZEJS_O.cjs +0 -1721
- package/dist/errors-BZ8hnhCM.cjs +0 -584
- package/dist/errors-DIJTAsLa.js +0 -392
- package/dist/esm-HBSUQw3w.js +0 -384
- package/dist/esm-LZuaZjMf.cjs +0 -389
- package/dist/experimental.cjs +0 -7073
- package/dist/experimental.d.ts +0 -84347
- package/dist/experimental.js +0 -6915
- package/dist/gated-call-Boy6rXdC.js +0 -3
- package/dist/gated-call-DJWY299W.cjs +0 -736
- package/dist/gated-call-DjoRPqn1.js +0 -695
- package/dist/gated-call-SomdJ5nj.cjs +0 -4
- package/dist/grant-circuits-_1x--moV.cjs +0 -49
- package/dist/grant-circuits-swuzEdUl.js +0 -26
- package/dist/grant-rules-7Zqi_3BN.cjs +0 -7114
- package/dist/grant-rules-_xJHAT2M.js +0 -6833
- package/dist/grant-status-B2y49iIu.js +0 -2688
- package/dist/grant-status-DOr3t_u8.cjs +0 -2820
- package/dist/grants--b0LQQzZ.cjs +0 -266
- package/dist/grants-BIs6qm3b.js +0 -213
- package/dist/grants-CSgfYlOO.js +0 -5
- package/dist/grants-D61131nK.cjs +0 -17
- package/dist/hex-D9ITYbwt.cjs +0 -263
- package/dist/hex-mkXcV3pN.js +0 -191
- package/dist/http-client-B3N-TMxu.cjs +0 -167
- package/dist/http-client-TRlhDZGh.js +0 -155
- package/dist/identity-BMLuufva.cjs +0 -263
- package/dist/identity-DII6f-h7.js +0 -233
- package/dist/in-memory-wallet-integration-B2xzxORj.cjs +0 -20741
- package/dist/in-memory-wallet-integration-CUKesGG1.js +0 -130
- package/dist/in-memory-wallet-integration-CoPx69lQ.cjs +0 -240
- package/dist/in-memory-wallet-integration-TM9bBphA.js +0 -20738
- package/dist/init-B5X_sGj9.cjs +0 -6
- package/dist/init-BJn-8_hf.js +0 -141
- package/dist/init-Bp6yJk31.js +0 -1142
- package/dist/init-Bu4iXcTH.cjs +0 -34
- package/dist/init-C00gw1zi.js +0 -422
- package/dist/init-CIjZaQvL.js +0 -3584
- package/dist/init-CR7BfztQ.cjs +0 -18
- package/dist/init-Cp8EJGbm.js +0 -5
- package/dist/init-CpIadSUb.js +0 -33
- package/dist/init-D5UiYI12.cjs +0 -106
- package/dist/init-DAikR9qU.js +0 -1177
- package/dist/init-DGjXwWs2.cjs +0 -143
- package/dist/init-DHrCbpkW.cjs +0 -121
- package/dist/init-DU5yYX5u.js +0 -2374
- package/dist/init-DWvkFDkc.cjs +0 -1176
- package/dist/init-DY1unoGb.cjs +0 -1141
- package/dist/init-DlqJuHhl.js +0 -119
- package/dist/init-DuYENxci.js +0 -17
- package/dist/init-E7c40ddW.cjs +0 -3585
- package/dist/init-GsT2AEa4.cjs +0 -424
- package/dist/init-KQnIdm39.js +0 -104
- package/dist/init-ZjNDDC-T.cjs +0 -2375
- package/dist/jubjub-authoriser-BxE3oN2y.js +0 -86
- package/dist/jubjub-authoriser-C6SDEP9I.cjs +0 -87
- package/dist/key-source-5oUBFiC7.cjs +0 -583
- package/dist/key-source-B08HukZg.js +0 -2550
- package/dist/keyDerivation-D3k9XyHg.js +0 -4077
- package/dist/keyDerivation-u0nBA93T.cjs +0 -274
- package/dist/lib--iqvW4O_.js +0 -2354
- package/dist/lib-Yk6Upl5D.cjs +0 -2359
- package/dist/midnight-account-id.vo-0x9X-r3l.cjs +0 -10
- package/dist/midnight-account-id.vo-DjCAGcqc.js +0 -5
- package/dist/midnight-engine-DpemplKO.js +0 -5
- package/dist/midnight-engine-xU1wotne.cjs +0 -6
- package/dist/midnight-wallet-DIsAlSn6.js +0 -18
- package/dist/midnight-wallet-XTZc2li7.cjs +0 -24
- package/dist/midnight.cjs +0 -1406
- package/dist/midnight.d.ts +0 -28586
- package/dist/midnight.js +0 -1350
- package/dist/modules-cardano-CtWLntet.cjs +0 -1108
- package/dist/modules-cardano-D2dkeKHY.js +0 -995
- package/dist/node-relay-Cv0cNknM.js +0 -48
- package/dist/node-relay-DblH5fKv.cjs +0 -49
- package/dist/outputs-Bd2yZVjx.js +0 -720
- package/dist/outputs-CJoQBIA2.cjs +0 -990
- package/dist/pbkdf2-CIW-oWrm.cjs +0 -1337
- package/dist/pending-operation-B0_P78Jo.cjs +0 -26
- package/dist/pending-operation-BIS6mpjB.js +0 -21
- package/dist/providers-BLgJ0uQs.cjs +0 -366
- package/dist/providers-CwnT4vEE.js +0 -343
- package/dist/redacted-BmE2aXqr.js +0 -81
- package/dist/redacted-CRZJLS3w.cjs +0 -86
- package/dist/safe-buffer-B_vMqJWU.js +0 -43
- package/dist/safe-buffer-DYOwEfHB.cjs +0 -48
- package/dist/sdk-DIcjlgLF.js +0 -1241
- package/dist/sdk-Dgal10kG.cjs +0 -1439
- package/dist/sdk-init-BKkqFtWZ.cjs +0 -3791
- package/dist/sdk-init-DNd-oQXp.js +0 -1044
- package/dist/send-proof-progress-DTK3ZuYB.js +0 -22
- package/dist/send-proof-progress-dDoqIohG.cjs +0 -33
- package/dist/side-effects-BnqYz7Nl.js +0 -768
- package/dist/side-effects-CngaeXi0.cjs +0 -804
- package/dist/sign-bitcoin-transaction-with-seed-D4z62-jV.js +0 -147
- package/dist/sign-bitcoin-transaction-with-seed-DsLYXnCY.cjs +0 -158
- package/dist/signer-3fk8lZtE.cjs +0 -7
- package/dist/signer-CsL28DrK.cjs +0 -121
- package/dist/signer-DGluibtn.js +0 -92
- package/dist/signer-RqB5pu3K.js +0 -2
- package/dist/signer-factory-BA7WFJVZ.js +0 -282
- package/dist/signer-factory-CORIG4Yl.cjs +0 -130
- package/dist/signer-factory-Cd2TwD50.js +0 -129
- package/dist/signer-factory-Cwd6o-lG.cjs +0 -281
- package/dist/slice-BOyAAaj0.cjs +0 -378
- package/dist/slice-BnTJeMOb.js +0 -354
- package/dist/slice-C4uXUT7S.js +0 -9013
- package/dist/slice-CxKWDuBP.js +0 -87
- package/dist/slice-DQv_RhsI.cjs +0 -9031
- package/dist/slice-HjLXJyQG2.cjs +0 -105
- package/dist/src-BDzYIksE.cjs +0 -20637
- package/dist/src-BFoefPv_.js +0 -20755
- package/dist/store-B1Lq3cEf.cjs +0 -66
- package/dist/store-DuBG8qh5.js +0 -37
- package/dist/submit-BBYjnZu8.cjs +0 -87
- package/dist/submit-D_yxYM_T.js +0 -70
- package/dist/submit-bitcoin-tx-BkZIeF4b.js +0 -983
- package/dist/submit-bitcoin-tx-DZNQgihl.cjs +0 -1049
- package/dist/token-id-mapper-Bnds3xKH.cjs +0 -18
- package/dist/token-id-mapper-CnKHQ8DV.js +0 -16
- package/dist/tokens-Cevp7rdU.cjs +0 -62
- package/dist/tokens-Diw4MLRM.js +0 -44
- package/dist/types-B8uiJn-X.js +0 -12
- package/dist/types-CJT6XF2c.js +0 -10
- package/dist/types-CLRUYpfe.cjs +0 -23
- package/dist/types-DWbVZpnF.cjs +0 -15
- package/dist/types-T0cjaR75.js +0 -33
- package/dist/types-Zj78LtYu.cjs +0 -50
- package/dist/unwrap-provider-result-BZSiwabU.js +0 -32
- package/dist/unwrap-provider-result-ZqfBsTkk.cjs +0 -39
- package/dist/utils-BfMdr_1w.cjs +0 -112
- package/dist/utils-CvAW5Yw7.js +0 -65
- package/dist/v8Signatures-CO_Uloy7.cjs +0 -71
- package/dist/watch-Cz1J42um.cjs +0 -52205
- package/dist/watch-Z53L4yoK.js +0 -13054
- /package/dist/{account-id.vo-DwqFjK5u.cjs → account-id.vo-LvCBVn5r.cjs} +0 -0
- /package/dist/{account-id.vo-OPz2v-JZ.js → account-id.vo-MYSI7YFm.js} +0 -0
- /package/dist/{actions-iLXdgL5Y.js → actions-9QSQR-GB.js} +0 -0
- /package/dist/{actions-B2BJ4RTy.cjs → actions-DdGbj7c7.cjs} +0 -0
- /package/dist/{apply-vkey-witnesses-ZnFS0jnJ.cjs → apply-vkey-witnesses-CLzVSWxl.cjs} +0 -0
- /package/dist/{apply-vkey-witnesses-BKx3lcs0.js → apply-vkey-witnesses-ClZbpk5w.js} +0 -0
- /package/dist/{asyncoption-CruEYOBI.js → asyncoption-Cw07zPH7.js} +0 -0
- /package/dist/{asyncoption-i0VbqVTq.cjs → asyncoption-DYoGuQfP.cjs} +0 -0
- /package/dist/{bignum.vo-CEXOIew0.js → bignum.vo-B0rK_PQ1.js} +0 -0
- /package/dist/{bignum.vo-hx2kuqlA.cjs → bignum.vo-DsG3kNiZ.cjs} +0 -0
- /package/dist/{bip32ed25519-B7Yat217.cjs → bip32ed25519-1ApqeAZk.cjs} +0 -0
- /package/dist/{bip32ed25519-FQ8qvdcq.js → bip32ed25519-DetAdGwD.js} +0 -0
- /package/dist/{blake2b-DEeVUdKR.cjs → blake2b-B9tftbvG.cjs} +0 -0
- /package/dist/{blake2b-BiQTw3GC.js → blake2b-DOEVc57D.js} +0 -0
- /package/dist/{blockchain-network-id.vo-BAKEwGjG.cjs → blockchain-network-id.vo-BXpZhvvQ.cjs} +0 -0
- /package/dist/{blockchain-network-id.vo-CiVykuqG.js → blockchain-network-id.vo-DNRkuT5B.js} +0 -0
- /package/dist/{blockingWithLatestFrom-Cd8c8EPG.js → blockingWithLatestFrom-C5wp_uA-.js} +0 -0
- /package/dist/{blockingWithLatestFrom-D8kBPBMX.cjs → blockingWithLatestFrom-DY8OPg0w.cjs} +0 -0
- /package/dist/{cardano-network-id-to-network-type-C0ufJOyE.cjs → cardano-network-id-to-network-type-BDTF-HmK.cjs} +0 -0
- /package/dist/{cardano-network-id-to-network-type-BWwzeEtM.js → cardano-network-id-to-network-type-CrZfUcyP.js} +0 -0
- /package/dist/{cardano-tx-id.vo-D3ASTIMd.cjs → cardano-tx-id.vo-BPhV-AmZ.cjs} +0 -0
- /package/dist/{cardano-tx-id.vo-BXLo1b7Q.js → cardano-tx-id.vo-DF9NzZXk.js} +0 -0
- /package/dist/{composite-signer-factory-m5cVs9h_.cjs → composite-signer-factory-BpF1mIYA.cjs} +0 -0
- /package/dist/{composite-signer-factory-CR8YHA1y.js → composite-signer-factory-_46QsNBz.js} +0 -0
- /package/dist/{error-DIZOY2Lw.js → error-BCp9NkPi.js} +0 -0
- /package/dist/{error-Cb3EnD0u.cjs → error-CNIquqT5.cjs} +0 -0
- /package/dist/{esm-browser-MG97cre9.js → esm-browser-C93Q-EOI.js} +0 -0
- /package/dist/{esm-browser-bweqfBlL.cjs → esm-browser-DTc9IK3D.cjs} +0 -0
- /package/dist/{feature-flag-key.vo-RlfHL3hq.cjs → feature-flag-key.vo-BPz-ZAp6.cjs} +0 -0
- /package/dist/{feature-flag-key.vo-DN_-4-sG.js → feature-flag-key.vo-ofrB6ZVQ.js} +0 -0
- /package/dist/{first-state-of-status-unPynOuM.js → first-state-of-status-DQnMT3ya.js} +0 -0
- /package/dist/{first-state-of-status-CbT7hPa4.cjs → first-state-of-status-OROkXcRv.cjs} +0 -0
- /package/dist/{init-zUoRG_EC2.cjs → init-C5CEZ1m0.cjs} +0 -0
- /package/dist/{init-DHaMxHM1.js → init-CKipPE_c.js} +0 -0
- /package/dist/{init-Atisw4x2.cjs → init-DFQQ9dTW.cjs} +0 -0
- /package/dist/{init-829HRYcz.js → init-Es3wHW7D.js} +0 -0
- /package/dist/{init-BgNobbNq.cjs → init-IAk_CkGa.cjs} +0 -0
- /package/dist/{init-atCFur0v.js → init-cqN3uX2j.js} +0 -0
- /package/dist/{is-redux-persist-state-BCFnSm36.cjs → is-redux-persist-state-CTn3WZVh.cjs} +0 -0
- /package/dist/{is-redux-persist-state-yBfq0h_E.js → is-redux-persist-state-Cxcd0_bM.js} +0 -0
- /package/dist/{key-value-store--W3SrMaw.js → key-value-store-8cMzeNyG.js} +0 -0
- /package/dist/{key-value-store-C2Xt5Emp.cjs → key-value-store-DUAepXQf.cjs} +0 -0
- /package/dist/{repo-slice-RxFm0zDZ.js → repo-slice-DwyMhCR1.js} +0 -0
- /package/dist/{repo-slice-7X4AYYVm.cjs → repo-slice-WxetRhMY.cjs} +0 -0
- /package/dist/{reselect-CGoLzEPv.js → reselect-C06X06oX.js} +0 -0
- /package/dist/{reselect-Bd94u0K-.cjs → reselect-CRDqmQY9.cjs} +0 -0
- /package/dist/{serializable-BHdKIgk3.js → serializable-B8GahgE1.js} +0 -0
- /package/dist/{serializable-BxHkoPdk.cjs → serializable-CRdnFaLZ.cjs} +0 -0
- /package/dist/{slice-obCSLm1x.js → slice-B87b52iM.js} +0 -0
- /package/dist/{slice-Bk0Sv05J.js → slice-Be7hj4Iy.js} +0 -0
- /package/dist/{slice-BiRsDKOK.cjs → slice-D11FHQuQ.cjs} +0 -0
- /package/dist/{slice-Dqw1ecum.cjs → slice-FioKeHtA.cjs} +0 -0
- /package/dist/{src-Cqp0B2M_.cjs → src-BTPIvlDI.cjs} +0 -0
- /package/dist/{src-BlxEp6Mm.js → src-vq1wS9sZ.js} +0 -0
- /package/dist/{time.vo-D3wWRw9L.cjs → time.vo-CQ8pSXz2.cjs} +0 -0
- /package/dist/{time.vo-tNheinXm.js → time.vo-DkYYGYp6.js} +0 -0
- /package/dist/{toEmpty-8Zax1MPd.js → toEmpty-CgAl3097.js} +0 -0
- /package/dist/{toEmpty-CYAbupM4.cjs → toEmpty-DAMmNB5r.cjs} +0 -0
- /package/dist/{token-id.vo-DXv5uS9n.cjs → token-id.vo-BxG9TG0O.cjs} +0 -0
- /package/dist/{token-id.vo-Bvwhr3ZE.js → token-id.vo-ClsroxHO.js} +0 -0
- /package/dist/{util-CzeB3hfa.cjs → util-CmdAhheh.cjs} +0 -0
- /package/dist/{util-C8a4fA9p.js → util-DxzlYNS5.js} +0 -0
- /package/dist/{util-selector-BWPH68_l.cjs → util-selector-BcAncU4L.cjs} +0 -0
- /package/dist/{util-selector-BSTsxgne.js → util-selector-CcK-GAdE.js} +0 -0
- /package/dist/{while-active-B0lWy_6l.js → while-active-BpppWuCs.js} +0 -0
- /package/dist/{while-active-Dsowp0Fi.cjs → while-active-Dhc2LwOm.cjs} +0 -0
|
@@ -1,1044 +0,0 @@
|
|
|
1
|
-
import "./_web-crypto-random-bytes-Bo-GTcRS.js";
|
|
2
|
-
import "./_polyfill-buffer-patch-yNxN4d5E.js";
|
|
3
|
-
import "./libsodium-wrappers-BhbOA8dQ.js";
|
|
4
|
-
import "./codecs-Dc1Krpbt.js";
|
|
5
|
-
import { n as HexBytes } from "./bytes.vo-BB7_4JK6.js";
|
|
6
|
-
import { r as Milliseconds, s as Timestamp } from "./time.vo-tNheinXm.js";
|
|
7
|
-
import { t as BigNumber } from "./bignum.vo-CEXOIew0.js";
|
|
8
|
-
import { t as autoDismissFailureOnSuccess } from "./auto-dismiss-failure-on-success-s8MGDEIu.js";
|
|
9
|
-
import "./retry-config-Dmgt28wM.js";
|
|
10
|
-
import { t as ActivityType } from "./activity-type-GsJGWs-3.js";
|
|
11
|
-
import { t as TokenId } from "./token-id.vo-Bvwhr3ZE.js";
|
|
12
|
-
import { t as AuthenticationCancelledError } from "./types-CJT6XF2c.js";
|
|
13
|
-
import { g as MidnightNetworkId, l as MidnightSDKTestNetworkId, x as getProofServerEndpoint, y as assertProofServerRouting } from "./const-BfEnY8fg.js";
|
|
14
|
-
import { n as midnightContextActions } from "./slice-BnTJeMOb.js";
|
|
15
|
-
import { c as toUnshieldedTokenType, o as hasMidnightAccount, s as isInMemoryMidnightAccount, t as convertHttpUrlToWebsocket } from "./utils-CvAW5Yw7.js";
|
|
16
|
-
import { t as midnightWalletsForRuntime } from "./midnight-wallet-DIsAlSn6.js";
|
|
17
|
-
import { c as createProofServerAccess, f as FEATURE_FLAG_MIDNIGHT_SHIELDED_ACTIVITY_ROWS, i as MidnightSyncFailureId, n as watchMidnightAccount, o as createAttestedProofServerAccess, r as watchMidnightAccounts, s as createHttpProofServerTransport, u as createScopedProofServerAccess } from "./watch-Z53L4yoK.js";
|
|
18
|
-
import { n as teeAttestationProgress$ } from "./send-proof-progress-DTK3ZuYB.js";
|
|
19
|
-
import { Percent, deepEquals } from "@laceio/cardano/util";
|
|
20
|
-
import { EMPTY, Observable, catchError, combineLatest, concat, defaultIfEmpty, defer, distinctUntilChanged, exhaustMap, filter, firstValueFrom, forkJoin, from, groupBy, map, merge, mergeMap, of, scan, shareReplay, switchMap, take, takeUntil, throttleTime, throwError, throwIfEmpty, withLatestFrom, zip } from "rxjs";
|
|
21
|
-
import isEqual from "lodash/isEqual.js";
|
|
22
|
-
import { DustAddress, ShieldedAddress, UnshieldedAddress } from "@midnightntwrk/wallet-sdk-address-format";
|
|
23
|
-
import * as ledger from "@midnight-ntwrk/ledger-v8";
|
|
24
|
-
import { PublicKey, UnshieldedWallet } from "@midnightntwrk/wallet-sdk/unshielded";
|
|
25
|
-
import { InMemoryTransactionHistoryStorage, WalletEntrySchema, mergeWalletEntries } from "@midnightntwrk/wallet-sdk";
|
|
26
|
-
import { DustWallet } from "@midnightntwrk/wallet-sdk/dust";
|
|
27
|
-
import { WalletFacade } from "@midnightntwrk/wallet-sdk/facade";
|
|
28
|
-
import { ShieldedWallet } from "@midnightntwrk/wallet-sdk/shielded";
|
|
29
|
-
//#region ../../packages/contract/midnight-context/src/value-objects/midnight-address.vo.ts
|
|
30
|
-
const MidnightShieldedAddress = (address) => address;
|
|
31
|
-
const MidnightUnshieldedAddress = (address) => address;
|
|
32
|
-
const MidnightDustAddress = (address) => address;
|
|
33
|
-
//#endregion
|
|
34
|
-
//#region ../../packages/contract/midnight-context/src/value-objects/serialised-wallet-state.vo.ts
|
|
35
|
-
/**
|
|
36
|
-
* Either encoding. Production only ever constructs this from the SDK's
|
|
37
|
-
* verbatim JSON; the hex form comes back from storage on older profiles.
|
|
38
|
-
*/
|
|
39
|
-
const SerialisedWalletState = (value) => value;
|
|
40
|
-
/**
|
|
41
|
-
* A heuristic over the values we actually persist, not a parse: hex and JSON
|
|
42
|
-
* overlap (`12345678` is both), so nothing can separate them in general. Every
|
|
43
|
-
* blob written here opens with `{`; `[` is headroom for a serialiser that
|
|
44
|
-
* returns a top-level array. Anything else reads as hex, and a wrong guess
|
|
45
|
-
* costs a rebuild from seed, which the restore path already handles.
|
|
46
|
-
*
|
|
47
|
-
* First character only: matching hex across the whole payload cost ~2500ms
|
|
48
|
-
* against 10k documents of 100k characters, against ~8ms here, and was
|
|
49
|
-
* case-sensitive so it missed uppercase hex besides.
|
|
50
|
-
*/
|
|
51
|
-
const isVerbatimJson = (value) => value.startsWith("{") || value.startsWith("[");
|
|
52
|
-
SerialisedWalletState.toJSON = (value) => isVerbatimJson(value) ? value : HexBytes.toUTF8(value);
|
|
53
|
-
//#endregion
|
|
54
|
-
//#region ../../packages/contract/midnight-context/src/midnight-accounts.ts
|
|
55
|
-
/** Two account lists are the same run of accounts when their ids line up in
|
|
56
|
-
* order — the identity the account stream re-emits on. */
|
|
57
|
-
const sameAccounts = (accounts1, accounts2) => {
|
|
58
|
-
if (accounts1.length !== accounts2.length) return false;
|
|
59
|
-
for (let index = 0; index < accounts1.length; index++) if (accounts1[index].accountId !== accounts2[index].accountId) return false;
|
|
60
|
-
return true;
|
|
61
|
-
};
|
|
62
|
-
/**
|
|
63
|
-
* The in-memory Midnight accounts on the active Midnight network, as a stream
|
|
64
|
-
* that only re-emits when the run of account ids actually changes. Emits an
|
|
65
|
-
* empty list while the wallet repo is migrating, so a consumer never acts on a
|
|
66
|
-
* half-migrated repo. Nothing is emitted until a Midnight network is registered.
|
|
67
|
-
*/
|
|
68
|
-
const midnightAccounts$ = (state) => combineLatest([
|
|
69
|
-
state.wallets.selectActiveNetworkAccounts$,
|
|
70
|
-
state.midnightContext.selectMidnightBlockchainNetworkId$.pipe(filter(Boolean)),
|
|
71
|
-
state.wallets.selectIsWalletRepoMigrating$
|
|
72
|
-
]).pipe(map(([accounts, activeNetwork, isWalletRepoMigrating]) => isWalletRepoMigrating ? [] : accounts.filter(isInMemoryMidnightAccount).filter((account) => account.blockchainNetworkId === activeNetwork)), distinctUntilChanged(sameAccounts));
|
|
73
|
-
//#endregion
|
|
74
|
-
//#region ../../packages/contract/midnight-context/src/register-midnight-blockchain-networks.ts
|
|
75
|
-
/**
|
|
76
|
-
* Registers the Midnight networks with the global network store once, the
|
|
77
|
-
* first time it reports Midnight absent. Every loadout with Midnight accounts
|
|
78
|
-
* needs this: `wallets.selectActiveNetworkAccounts` drops the accounts of an
|
|
79
|
-
* unregistered blockchain. The registration lands a tick after this decides,
|
|
80
|
-
* so it sets the networks only while Midnight still has none: a network the
|
|
81
|
-
* consumer selected in between keeps precedence.
|
|
82
|
-
*
|
|
83
|
-
* An existing Midnight account pins the testnet selection to its own network,
|
|
84
|
-
* so a profile created before the network store existed keeps syncing where
|
|
85
|
-
* its account lives; otherwise the default testnet is selected.
|
|
86
|
-
*/
|
|
87
|
-
const registerMidnightBlockchainNetworks = (_, { network: { selectBlockchainNetworks$ }, midnightContext: { selectDefaultTestNetNetworkId$ }, wallets: { selectAll$ } }, { actions }) => selectBlockchainNetworks$.pipe(filter((blockchainNetworks) => !blockchainNetworks?.Midnight), withLatestFrom(selectDefaultTestNetNetworkId$, selectAll$.pipe(map((allWallets) => allWallets.flatMap((wallet) => wallet.accounts)))), map(([, defaultTestNetNetworkId, accounts]) => {
|
|
88
|
-
const existingMidnightAccount = accounts.find((account) => account.blockchainName === "Midnight");
|
|
89
|
-
const testnetNetworkId = existingMidnightAccount ? existingMidnightAccount.blockchainSpecific.networkId : defaultTestNetNetworkId;
|
|
90
|
-
return actions.network.registerBlockchainNetworks({
|
|
91
|
-
blockchain: "Midnight",
|
|
92
|
-
mainnet: MidnightNetworkId("mainnet"),
|
|
93
|
-
testnet: MidnightNetworkId(testnetNetworkId)
|
|
94
|
-
});
|
|
95
|
-
}));
|
|
96
|
-
//#endregion
|
|
97
|
-
//#region ../../packages/lib/vendor/src/midnight-facade-reservations.ts
|
|
98
|
-
const NO_BALANCING_TRANSACTION = "No balancing transaction was created. Please check your transaction.";
|
|
99
|
-
const releasingOnFailure = async (build) => {
|
|
100
|
-
const releases = [];
|
|
101
|
-
const reserve = (transaction, holder) => {
|
|
102
|
-
if (transaction) releases.push(async () => holder.revertTransaction(transaction));
|
|
103
|
-
return transaction;
|
|
104
|
-
};
|
|
105
|
-
try {
|
|
106
|
-
return await build(reserve);
|
|
107
|
-
} catch (error) {
|
|
108
|
-
await Promise.allSettled(releases.map(async (release) => release()));
|
|
109
|
-
throw error;
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
const merge$1 = (first, second) => first && second ? first.merge(second) : first ?? second;
|
|
113
|
-
const kindsToBalance = (tokenKindsToBalance = "all") => {
|
|
114
|
-
const kinds = tokenKindsToBalance === "all" ? [
|
|
115
|
-
"shielded",
|
|
116
|
-
"unshielded",
|
|
117
|
-
"dust"
|
|
118
|
-
] : tokenKindsToBalance;
|
|
119
|
-
return {
|
|
120
|
-
dust: kinds.includes("dust"),
|
|
121
|
-
shielded: kinds.includes("shielded"),
|
|
122
|
-
unshielded: kinds.includes("unshielded")
|
|
123
|
-
};
|
|
124
|
-
};
|
|
125
|
-
/**
|
|
126
|
-
* The wallet SDK's multi-step builds over `facade`, releasing the coins the
|
|
127
|
-
* completed steps reserved when a later step fails. The wallet SDK keeps
|
|
128
|
-
* them, and its caller gets an error with no recipe to release. Each build
|
|
129
|
-
* takes the same steps over the same sub-wallets as its `WalletFacade`
|
|
130
|
-
* namesake and returns the same recipe.
|
|
131
|
-
*/
|
|
132
|
-
const withReservationRelease = (facade) => ({
|
|
133
|
-
balanceFinalizedTransaction: async (transaction, { shieldedSecretKeys, dustSecretKey }, { ttl, tokenKindsToBalance }) => releasingOnFailure(async (reserve) => {
|
|
134
|
-
const balance = kindsToBalance(tokenKindsToBalance);
|
|
135
|
-
const unshieldedBalancing = balance.unshielded ? reserve(await facade.unshielded.balanceFinalizedTransaction(transaction), facade.unshielded) : void 0;
|
|
136
|
-
const tokenBalancing = merge$1(balance.shielded ? reserve(await facade.shielded.balanceTransaction(shieldedSecretKeys, transaction), facade.shielded) : void 0, unshieldedBalancing);
|
|
137
|
-
const balancingTransaction = merge$1(tokenBalancing, balance.dust ? await facade.dust.balanceTransactions(dustSecretKey, tokenBalancing ? [transaction, tokenBalancing] : [transaction], ttl) : void 0);
|
|
138
|
-
if (!balancingTransaction) throw new Error(NO_BALANCING_TRANSACTION);
|
|
139
|
-
return {
|
|
140
|
-
type: "FINALIZED_TRANSACTION",
|
|
141
|
-
originalTransaction: transaction,
|
|
142
|
-
balancingTransaction
|
|
143
|
-
};
|
|
144
|
-
}),
|
|
145
|
-
balanceUnboundTransaction: async (transaction, { shieldedSecretKeys, dustSecretKey }, { ttl, tokenKindsToBalance }) => releasingOnFailure(async (reserve) => {
|
|
146
|
-
const balance = kindsToBalance(tokenKindsToBalance);
|
|
147
|
-
const shieldedBalancing = balance.shielded ? reserve(await facade.shielded.balanceTransaction(shieldedSecretKeys, transaction), facade.shielded) : void 0;
|
|
148
|
-
const balancedUnshielded = balance.unshielded ? await facade.unshielded.balanceUnboundTransaction(transaction) : void 0;
|
|
149
|
-
const baseTransaction = balancedUnshielded ?? transaction;
|
|
150
|
-
const balancingTransaction = merge$1(shieldedBalancing, balance.dust ? await facade.dust.balanceTransactions(dustSecretKey, shieldedBalancing ? [baseTransaction, shieldedBalancing] : [baseTransaction], ttl) : void 0);
|
|
151
|
-
if (!balancingTransaction && !balancedUnshielded) throw new Error(NO_BALANCING_TRANSACTION);
|
|
152
|
-
return {
|
|
153
|
-
type: "UNBOUND_TRANSACTION",
|
|
154
|
-
baseTransaction,
|
|
155
|
-
balancingTransaction: balancingTransaction ?? void 0
|
|
156
|
-
};
|
|
157
|
-
}),
|
|
158
|
-
transferTransaction: async (outputs, { shieldedSecretKeys, dustSecretKey }, { ttl, payFees = true }) => releasingOnFailure(async (reserve) => {
|
|
159
|
-
const shieldedOutputs = outputs.flatMap((output) => output.type === "shielded" ? output.outputs : []);
|
|
160
|
-
const unshieldedOutputs = outputs.flatMap((output) => output.type === "unshielded" ? output.outputs : []);
|
|
161
|
-
if (unshieldedOutputs.length === 0 && shieldedOutputs.length === 0) throw new Error("At least one shielded or unshielded output is required.");
|
|
162
|
-
const transfer = merge$1(shieldedOutputs.length > 0 ? reserve(await facade.shielded.transferTransaction(shieldedSecretKeys, shieldedOutputs), facade.shielded) : void 0, unshieldedOutputs.length > 0 ? reserve(await facade.unshielded.transferTransaction(unshieldedOutputs, ttl), facade.unshielded) : void 0);
|
|
163
|
-
if (!transfer) throw new Error("Unexpected transaction state.");
|
|
164
|
-
return {
|
|
165
|
-
type: "UNPROVEN_TRANSACTION",
|
|
166
|
-
transaction: merge$1(transfer, payFees ? await facade.dust.balanceTransactions(dustSecretKey, [transfer], ttl) : void 0) ?? transfer
|
|
167
|
-
};
|
|
168
|
-
}),
|
|
169
|
-
initSwap: async ({ desiredInputs, desiredOutputs }, { shieldedSecretKeys, dustSecretKey }, { ttl, payFees = false }) => releasingOnFailure(async (reserve) => {
|
|
170
|
-
const { shielded: shieldedInputs, unshielded: unshieldedInputs } = desiredInputs;
|
|
171
|
-
const shieldedOutputs = desiredOutputs.flatMap((output) => output.type === "shielded" ? output.outputs : []);
|
|
172
|
-
const unshieldedOutputs = desiredOutputs.flatMap((output) => output.type === "unshielded" ? output.outputs : []);
|
|
173
|
-
const hasShieldedPart = !!shieldedInputs && Object.keys(shieldedInputs).length > 0 || shieldedOutputs.length > 0;
|
|
174
|
-
const hasUnshieldedPart = !!unshieldedInputs && Object.keys(unshieldedInputs).length > 0 || unshieldedOutputs.length > 0;
|
|
175
|
-
if (!hasShieldedPart && !hasUnshieldedPart) throw new Error("At least one shielded or unshielded swap is required.");
|
|
176
|
-
const swap = merge$1(hasShieldedPart && shieldedInputs !== void 0 ? reserve(await facade.shielded.initSwap(shieldedSecretKeys, shieldedInputs, shieldedOutputs), facade.shielded) : void 0, hasUnshieldedPart && unshieldedInputs !== void 0 ? reserve(await facade.unshielded.initSwap(unshieldedInputs, unshieldedOutputs, ttl), facade.unshielded) : void 0);
|
|
177
|
-
if (!swap) throw new Error("Unexpected transaction state.");
|
|
178
|
-
return {
|
|
179
|
-
type: "UNPROVEN_TRANSACTION",
|
|
180
|
-
transaction: merge$1(swap, payFees ? await facade.dust.balanceTransactions(dustSecretKey, [swap], ttl) : void 0) ?? swap
|
|
181
|
-
};
|
|
182
|
-
})
|
|
183
|
-
});
|
|
184
|
-
//#endregion
|
|
185
|
-
//#region ../../packages/module/midnight-sync/src/store/compute-sync-ratio.ts
|
|
186
|
-
const computeConnectedSyncRatio = (applied, highest, isConnected) => isConnected && applied === 0n && highest === 0n ? Percent(1) : computeSyncRatio(applied, highest);
|
|
187
|
-
const computeSyncRatio = (applied, highest) => {
|
|
188
|
-
if (highest === 0n) {
|
|
189
|
-
if (applied === 0n) return Percent(0);
|
|
190
|
-
const ratio = 1 - 1 / (1 + Number(applied) / 1e3);
|
|
191
|
-
return Percent(Math.min(.99, ratio));
|
|
192
|
-
}
|
|
193
|
-
return Percent(Math.min(1, Number(applied) / Number(highest)));
|
|
194
|
-
};
|
|
195
|
-
//#endregion
|
|
196
|
-
//#region ../../packages/module/midnight-sync/src/store/dependencies.ts
|
|
197
|
-
/**
|
|
198
|
-
* Wraps keyManager.keys$ with recovery for AuthenticationCancelledError.
|
|
199
|
-
* If the user cancels the auth prompt, waits for keys to become available
|
|
200
|
-
* from another source (e.g., an unlock triggered by a different flow)
|
|
201
|
-
* and retries.
|
|
202
|
-
*/
|
|
203
|
-
const keysWithAuthCancelledRecovery$ = (keyManager) => keyManager.keys$.pipe(take(1), catchError((error) => {
|
|
204
|
-
if (!(error instanceof AuthenticationCancelledError)) return throwError(() => error);
|
|
205
|
-
return keyManager.areKeysAvailable$.pipe(filter((available) => available), take(1), switchMap(() => keyManager.keys$.pipe(take(1))));
|
|
206
|
-
}));
|
|
207
|
-
const STATE_SERIALISATION_THROTTLE_TIME = Milliseconds(5e3);
|
|
208
|
-
const DEFAULT_BATCH_UPDATES = {
|
|
209
|
-
size: 12,
|
|
210
|
-
spacing: 4
|
|
211
|
-
};
|
|
212
|
-
/**
|
|
213
|
-
* Restore accepts the legacy `unshieldedTxHistory` key so profiles written
|
|
214
|
-
* before the persisted key was renamed load without a resync; the next persist
|
|
215
|
-
* rewrites the doc under `txHistory`, migrating it lazily.
|
|
216
|
-
*/
|
|
217
|
-
const readPersistedTxHistory = (serializedState) => serializedState.txHistory ?? serializedState.unshieldedTxHistory;
|
|
218
|
-
/**
|
|
219
|
-
* djb2 over the serialized states. The previous-persist comparator must not
|
|
220
|
-
* RETAIN the inputs: keeping the raw serialized strings would pin ~10MB per
|
|
221
|
-
* synced wallet in service worker memory between persist cycles.
|
|
222
|
-
*/
|
|
223
|
-
const fingerprintOf = (parts) => {
|
|
224
|
-
let hash = 5381;
|
|
225
|
-
for (const part of parts) for (let index = 0; index < part.length; index += 1) {
|
|
226
|
-
hash = hash * 33 ^ part.charCodeAt(index);
|
|
227
|
-
hash |= 0;
|
|
228
|
-
}
|
|
229
|
-
return `${hash}:${parts.map((part) => part.length).join(":")}`;
|
|
230
|
-
};
|
|
231
|
-
const getAccountWalletInstance = async ({ account, config, getTemenosLedgerIndexerUrl, store, keyManager }, logger, { createAttestedProver, batchUpdates = DEFAULT_BATCH_UPDATES }) => {
|
|
232
|
-
const walletState = await firstValueFrom(store.get(String(account.accountId)).pipe(defaultIfEmpty(void 0)));
|
|
233
|
-
const indexerClientConnection = {
|
|
234
|
-
indexerHttpUrl: config.indexerAddress,
|
|
235
|
-
indexerWsUrl: convertHttpUrlToWebsocket(config.indexerAddress),
|
|
236
|
-
keepAlive: 15e3
|
|
237
|
-
};
|
|
238
|
-
const { networkId } = account.blockchainSpecific;
|
|
239
|
-
const proofServerUrl = getProofServerEndpoint(config.proofServer);
|
|
240
|
-
if (!proofServerUrl) throw new Error(`Cannot start Midnight wallet: proof server mode "${config.proofServer.kind}" has no HTTP endpoint`);
|
|
241
|
-
assertProofServerRouting(config.proofServer, !!createAttestedProver);
|
|
242
|
-
const createAccess = (onProgress) => config.proofServer.kind === "tee-delegated" && createAttestedProver ? createAttestedProofServerAccess(createAttestedProver({
|
|
243
|
-
networkId,
|
|
244
|
-
proofServerApiUrl: config.proofServer.url,
|
|
245
|
-
getLedgerIndexerUrl: async () => {
|
|
246
|
-
if (!getTemenosLedgerIndexerUrl) throw new Error("Temenos attestation requires a ledger indexer resolver");
|
|
247
|
-
return getTemenosLedgerIndexerUrl();
|
|
248
|
-
}
|
|
249
|
-
}), onProgress) : createProofServerAccess(createHttpProofServerTransport(proofServerUrl));
|
|
250
|
-
const proofServer = createScopedProofServerAccess(createAccess);
|
|
251
|
-
const { finalizeRecipe } = proofServer;
|
|
252
|
-
const configuration = {
|
|
253
|
-
costParameters: {
|
|
254
|
-
additionalFeeOverhead: 300000000000000n,
|
|
255
|
-
feeBlocksMargin: 5
|
|
256
|
-
},
|
|
257
|
-
networkId,
|
|
258
|
-
batchUpdates,
|
|
259
|
-
indexerClientConnection,
|
|
260
|
-
relayURL: new URL(convertHttpUrlToWebsocket(config.nodeAddress)),
|
|
261
|
-
txHistoryStorage: new InMemoryTransactionHistoryStorage(WalletEntrySchema, mergeWalletEntries)
|
|
262
|
-
};
|
|
263
|
-
if (walletState) {
|
|
264
|
-
const { dust, shielded, unshielded } = walletState.serializedState;
|
|
265
|
-
let restoredTxHistoryStorage;
|
|
266
|
-
try {
|
|
267
|
-
restoredTxHistoryStorage = InMemoryTransactionHistoryStorage.restore(SerialisedWalletState.toJSON(readPersistedTxHistory(walletState.serializedState)), WalletEntrySchema, mergeWalletEntries);
|
|
268
|
-
} catch (error) {
|
|
269
|
-
logger.warn(`Discarding unreadable persisted Midnight wallet state for account ${account.accountId}; rebuilding from seed`, error instanceof Error ? error.message : String(error));
|
|
270
|
-
await firstValueFrom(store.removeWhere((state) => state.accountId === account.accountId).pipe(defaultIfEmpty(void 0), catchError((wipeError) => {
|
|
271
|
-
logger.error(`Failed to discard unreadable Midnight wallet state for account ${account.accountId}`, wipeError);
|
|
272
|
-
return of(void 0);
|
|
273
|
-
})));
|
|
274
|
-
}
|
|
275
|
-
if (restoredTxHistoryStorage) {
|
|
276
|
-
configuration.txHistoryStorage = restoredTxHistoryStorage;
|
|
277
|
-
return {
|
|
278
|
-
walletFacade: await WalletFacade.init({
|
|
279
|
-
configuration,
|
|
280
|
-
provingService: () => proofServer.provingService,
|
|
281
|
-
shielded: (config) => ShieldedWallet(config).restore(SerialisedWalletState.toJSON(shielded)),
|
|
282
|
-
unshielded: (config) => UnshieldedWallet(config).restore(SerialisedWalletState.toJSON(unshielded)),
|
|
283
|
-
dust: (config) => DustWallet(config).restore(SerialisedWalletState.toJSON(dust))
|
|
284
|
-
}),
|
|
285
|
-
txHistoryStorage: restoredTxHistoryStorage,
|
|
286
|
-
proofServerTransport: proofServer.transport,
|
|
287
|
-
finalizeRecipe
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
const { walletKeys: { dustKeyBuffer, zswapKeyBuffer }, unshieldedKeystore } = await firstValueFrom(keysWithAuthCancelledRecovery$(keyManager));
|
|
292
|
-
const dustParameters = ledger.LedgerParameters.initialParameters().dust;
|
|
293
|
-
const txHistoryStorage = new InMemoryTransactionHistoryStorage(WalletEntrySchema, mergeWalletEntries);
|
|
294
|
-
configuration.txHistoryStorage = txHistoryStorage;
|
|
295
|
-
return {
|
|
296
|
-
walletFacade: await WalletFacade.init({
|
|
297
|
-
configuration,
|
|
298
|
-
provingService: () => proofServer.provingService,
|
|
299
|
-
shielded: (config) => ShieldedWallet(config).startWithSeed(zswapKeyBuffer),
|
|
300
|
-
unshielded: (config) => UnshieldedWallet(config).startWithPublicKey(PublicKey.fromKeyStore(unshieldedKeystore)),
|
|
301
|
-
dust: (config) => DustWallet(config).startWithSeed(dustKeyBuffer, dustParameters)
|
|
302
|
-
}),
|
|
303
|
-
txHistoryStorage,
|
|
304
|
-
proofServerTransport: proofServer.transport,
|
|
305
|
-
finalizeRecipe
|
|
306
|
-
};
|
|
307
|
-
};
|
|
308
|
-
/**
|
|
309
|
-
* Creates an observable MidnightWallet from wallet instances.
|
|
310
|
-
*
|
|
311
|
-
* The nightVerifyingKey is obtained from the wallet state, which works
|
|
312
|
-
* for both restored and new wallets.
|
|
313
|
-
*/
|
|
314
|
-
const createAccountObservableMidnightWallet = ({ account, keyManager, walletFacade, haltPersistence, proofServerTransport, finalizeRecipe }) => {
|
|
315
|
-
const { networkId } = account.blockchainSpecific;
|
|
316
|
-
const state$ = walletFacade.state().pipe(shareReplay({
|
|
317
|
-
bufferSize: 1,
|
|
318
|
-
refCount: true
|
|
319
|
-
}));
|
|
320
|
-
const releasing = withReservationRelease(walletFacade);
|
|
321
|
-
return state$.pipe(take(1), map((initialState) => {
|
|
322
|
-
const nightVerifyingKey = initialState.unshielded.capabilities.keys.getPublicKey(initialState.unshielded.state);
|
|
323
|
-
return {
|
|
324
|
-
accountId: account.accountId,
|
|
325
|
-
areKeysAvailable$: keyManager.areKeysAvailable$,
|
|
326
|
-
networkId,
|
|
327
|
-
nightVerifyingKey,
|
|
328
|
-
proofServerTransport,
|
|
329
|
-
walletId: account.walletId,
|
|
330
|
-
address$: state$.pipe(map(({ dust, shielded, unshielded }) => ({
|
|
331
|
-
dust: MidnightDustAddress(DustAddress.codec.encode(networkId, dust.capabilities.keys.getAddress(dust.state)).asString()),
|
|
332
|
-
shielded: MidnightShieldedAddress(ShieldedAddress.codec.encode(networkId, shielded.address).asString()),
|
|
333
|
-
unshielded: MidnightUnshieldedAddress(UnshieldedAddress.codec.encode(networkId, unshielded.address).asString())
|
|
334
|
-
})), distinctUntilChanged(deepEquals)),
|
|
335
|
-
coinsByTokenType$: state$.pipe(map(({ shielded, unshielded }) => {
|
|
336
|
-
const shieldedCoins = {};
|
|
337
|
-
const unshieldedCoins = {};
|
|
338
|
-
for (const { coin } of shielded.totalCoins) {
|
|
339
|
-
const previousCoinsList = shieldedCoins[coin.type] || [];
|
|
340
|
-
shieldedCoins[coin.type] = previousCoinsList.concat({
|
|
341
|
-
status: "mt_index" in coin ? "available" : "pending",
|
|
342
|
-
value: BigNumber(coin.value)
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
const parseUnshieldedCoins = (status, coins) => {
|
|
346
|
-
for (const { meta, utxo } of coins) {
|
|
347
|
-
const tokenType = toUnshieldedTokenType(utxo.type, networkId);
|
|
348
|
-
unshieldedCoins[tokenType] = (unshieldedCoins[tokenType] || []).concat({
|
|
349
|
-
status,
|
|
350
|
-
value: BigNumber(utxo.value),
|
|
351
|
-
registeredForDustGeneration: meta.registeredForDustGeneration,
|
|
352
|
-
ownerAddress: utxo.owner
|
|
353
|
-
});
|
|
354
|
-
}
|
|
355
|
-
};
|
|
356
|
-
parseUnshieldedCoins("pending", unshielded.pendingCoins);
|
|
357
|
-
parseUnshieldedCoins("available", unshielded.availableCoins);
|
|
358
|
-
return {
|
|
359
|
-
shielded: shieldedCoins,
|
|
360
|
-
unshielded: unshieldedCoins
|
|
361
|
-
};
|
|
362
|
-
}), distinctUntilChanged(deepEquals)),
|
|
363
|
-
syncProgress$: state$.pipe(map(({ dust, shielded, unshielded }) => ({
|
|
364
|
-
dust: computeConnectedSyncRatio(dust.state.progress.appliedIndex, dust.state.progress.highestRelevantWalletIndex, dust.state.progress.isConnected),
|
|
365
|
-
shielded: computeConnectedSyncRatio(shielded.state.progress.appliedIndex, shielded.state.progress.highestRelevantWalletIndex, shielded.state.progress.isConnected),
|
|
366
|
-
unshielded: computeConnectedSyncRatio(unshielded.state.progress.appliedId, unshielded.state.progress.highestTransactionId, unshielded.state.progress.isConnected),
|
|
367
|
-
isStrictlyComplete: {
|
|
368
|
-
dust: dust.state.progress.isStrictlyComplete(),
|
|
369
|
-
shielded: shielded.state.progress.isStrictlyComplete(),
|
|
370
|
-
unshielded: unshielded.state.progress.isStrictlyComplete()
|
|
371
|
-
}
|
|
372
|
-
})), distinctUntilChanged(deepEquals)),
|
|
373
|
-
transactionHistory$: state$.pipe(throttleTime(500, void 0, {
|
|
374
|
-
leading: true,
|
|
375
|
-
trailing: true
|
|
376
|
-
}), switchMap(() => from(walletFacade.getAllFromTxHistory())), distinctUntilChanged(deepEquals)),
|
|
377
|
-
balanceFinalizedTransaction: (tx, { ttl, tokenKindsToBalance }) => keyManager.keys$.pipe(take(1), switchMap(({ walletKeys: { dustSecretKey, zswapSecretKeys } }) => from(releasing.balanceFinalizedTransaction(tx, {
|
|
378
|
-
shieldedSecretKeys: zswapSecretKeys,
|
|
379
|
-
dustSecretKey
|
|
380
|
-
}, {
|
|
381
|
-
ttl,
|
|
382
|
-
tokenKindsToBalance
|
|
383
|
-
})))),
|
|
384
|
-
balanceUnboundTransaction: (tx, { ttl, tokenKindsToBalance }) => keyManager.keys$.pipe(take(1), switchMap(({ walletKeys: { dustSecretKey, zswapSecretKeys } }) => from(releasing.balanceUnboundTransaction(tx, {
|
|
385
|
-
shieldedSecretKeys: zswapSecretKeys,
|
|
386
|
-
dustSecretKey
|
|
387
|
-
}, {
|
|
388
|
-
ttl,
|
|
389
|
-
tokenKindsToBalance
|
|
390
|
-
})))),
|
|
391
|
-
balanceUnprovenTransaction: (tx, { ttl, tokenKindsToBalance }) => keyManager.keys$.pipe(take(1), switchMap(({ walletKeys: { dustSecretKey, zswapSecretKeys } }) => from(walletFacade.balanceUnprovenTransaction(tx, {
|
|
392
|
-
shieldedSecretKeys: zswapSecretKeys,
|
|
393
|
-
dustSecretKey
|
|
394
|
-
}, {
|
|
395
|
-
ttl,
|
|
396
|
-
tokenKindsToBalance
|
|
397
|
-
})))),
|
|
398
|
-
calculateTransactionFee: (tx) => from(walletFacade.calculateTransactionFee(tx)),
|
|
399
|
-
estimateTransactionFee: (tx, options) => keyManager.keys$.pipe(take(1), switchMap(({ walletKeys: { dustSecretKey } }) => from(walletFacade.estimateTransactionFee(tx, dustSecretKey, options)))),
|
|
400
|
-
deregisterFromDustGeneration: (nightUtxos) => keyManager.keys$.pipe(take(1), switchMap(({ unshieldedKeystore }) => from(walletFacade.deregisterFromDustGeneration(nightUtxos, unshieldedKeystore.getPublicKey(), (data) => unshieldedKeystore.signData(data))))),
|
|
401
|
-
getTransactionHistoryEntryByHash: (hash) => from(walletFacade.queryTxHistoryByHash(hash)),
|
|
402
|
-
finalizeRecipe: (recipe, onProgress) => defer(async () => finalizeRecipe(walletFacade, recipe, onProgress)),
|
|
403
|
-
finalizeTransaction: (recipe) => from(walletFacade.finalizeTransaction(recipe)),
|
|
404
|
-
registerNightUtxosForDustGeneration: (nightUtxos, dustAddress) => keyManager.keys$.pipe(take(1), switchMap(({ unshieldedKeystore }) => from(walletFacade.registerNightUtxosForDustGeneration(nightUtxos, unshieldedKeystore.getPublicKey(), (data) => unshieldedKeystore.signData(data), dustAddress)))),
|
|
405
|
-
revert: (recipe) => from(walletFacade.revert(recipe)),
|
|
406
|
-
state: () => state$,
|
|
407
|
-
stop: () => {
|
|
408
|
-
haltPersistence();
|
|
409
|
-
return from(walletFacade.stop());
|
|
410
|
-
},
|
|
411
|
-
signUnprovenTransaction: (tx) => keyManager.keys$.pipe(take(1), switchMap(({ unshieldedKeystore }) => from(walletFacade.signUnprovenTransaction(tx, (data) => unshieldedKeystore.signData(data))))),
|
|
412
|
-
signRecipe: (recipe) => keyManager.keys$.pipe(take(1), switchMap(({ unshieldedKeystore }) => from(walletFacade.signRecipe(recipe, (data) => unshieldedKeystore.signData(data))))),
|
|
413
|
-
signData: (data) => keyManager.keys$.pipe(take(1), map(({ unshieldedKeystore }) => ({
|
|
414
|
-
signature: unshieldedKeystore.signData(data),
|
|
415
|
-
verifyingKey: unshieldedKeystore.getPublicKey()
|
|
416
|
-
}))),
|
|
417
|
-
submitTransaction: (tx) => from(walletFacade.submitTransaction(tx)),
|
|
418
|
-
transferTransaction: (outputs, { ttl, payFees }) => keyManager.keys$.pipe(take(1), switchMap(({ walletKeys: { dustSecretKey, zswapSecretKeys } }) => from(releasing.transferTransaction(outputs, {
|
|
419
|
-
shieldedSecretKeys: zswapSecretKeys,
|
|
420
|
-
dustSecretKey
|
|
421
|
-
}, {
|
|
422
|
-
ttl,
|
|
423
|
-
payFees
|
|
424
|
-
})))),
|
|
425
|
-
initSwap: (desiredInputs, desiredOutputs, { ttl, payFees }) => keyManager.keys$.pipe(take(1), switchMap(({ walletKeys: { dustSecretKey, zswapSecretKeys } }) => from(releasing.initSwap({
|
|
426
|
-
desiredInputs,
|
|
427
|
-
desiredOutputs
|
|
428
|
-
}, {
|
|
429
|
-
shieldedSecretKeys: zswapSecretKeys,
|
|
430
|
-
dustSecretKey
|
|
431
|
-
}, {
|
|
432
|
-
ttl,
|
|
433
|
-
payFees
|
|
434
|
-
}))))
|
|
435
|
-
};
|
|
436
|
-
}));
|
|
437
|
-
};
|
|
438
|
-
/**
|
|
439
|
-
* Creates and manages the lifecycle of Midnight SDK wallet instances.
|
|
440
|
-
*
|
|
441
|
-
* Lifecycle:
|
|
442
|
-
* - Creates all 3 wallets (Unshielded, Shielded, Dust) via getAccountWalletInstance
|
|
443
|
-
* - Starts UnshieldedWallet immediately (no keys needed)
|
|
444
|
-
* - Starts ShieldedWallet and DustWallet once account keys become available
|
|
445
|
-
* (one auth prompt; sync then runs for the wallet's lifetime, surviving
|
|
446
|
-
* the key manager's idle zeroization — see the start step below)
|
|
447
|
-
* - DustWallet is never stopped once started
|
|
448
|
-
* (SDK limitation: stop() closes Effect runtime, breaking calculateFee)
|
|
449
|
-
* - On unsubscribe: stops all wallets and clears the sync key copy
|
|
450
|
-
*/
|
|
451
|
-
const createAndManageWallets = (props, { logger }, options) => {
|
|
452
|
-
const { keyManager, account, store } = props;
|
|
453
|
-
return new Observable((subscriber) => {
|
|
454
|
-
let walletFacade = null;
|
|
455
|
-
let syncSecretKeys = null;
|
|
456
|
-
let syncDustSecretKey = null;
|
|
457
|
-
let syncStartSubscription = null;
|
|
458
|
-
let persistSubscription = null;
|
|
459
|
-
let isDestroyed = false;
|
|
460
|
-
let isPersistenceHalted = false;
|
|
461
|
-
const init = async () => {
|
|
462
|
-
const { walletFacade: facade, txHistoryStorage, proofServerTransport, finalizeRecipe } = await getAccountWalletInstance(props, logger, options);
|
|
463
|
-
if (isDestroyed) {
|
|
464
|
-
facade.stop();
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
walletFacade = facade;
|
|
468
|
-
await walletFacade.unshielded.start();
|
|
469
|
-
syncStartSubscription = keysWithAuthCancelledRecovery$(keyManager).pipe(switchMap((keys) => {
|
|
470
|
-
if (!walletFacade) return from(Promise.resolve());
|
|
471
|
-
syncSecretKeys = ledger.ZswapSecretKeys.fromSeed(keys.walletKeys.zswapKeyBuffer);
|
|
472
|
-
syncDustSecretKey = ledger.DustSecretKey.fromSeed(keys.walletKeys.dustKeyBuffer);
|
|
473
|
-
const facade = walletFacade;
|
|
474
|
-
const syncKeys = syncSecretKeys;
|
|
475
|
-
const dustSyncKey = syncDustSecretKey;
|
|
476
|
-
return from((async () => {
|
|
477
|
-
const failures = [];
|
|
478
|
-
try {
|
|
479
|
-
await facade.shielded.start(syncKeys);
|
|
480
|
-
} catch (error) {
|
|
481
|
-
logger.error(`Midnight shielded wallet failed to start for account ${account.accountId}:`, error);
|
|
482
|
-
failures.push(error);
|
|
483
|
-
}
|
|
484
|
-
try {
|
|
485
|
-
await facade.dust.start(dustSyncKey);
|
|
486
|
-
} catch (error) {
|
|
487
|
-
logger.error(`Midnight dust wallet failed to start for account ${account.accountId}:`, error);
|
|
488
|
-
failures.push(error);
|
|
489
|
-
}
|
|
490
|
-
if (failures.length > 0) throw failures[0];
|
|
491
|
-
})());
|
|
492
|
-
})).subscribe({ error: (error) => {
|
|
493
|
-
logger.error(`Wallet sync start error for account ${account.accountId}:`, error);
|
|
494
|
-
subscriber.error(error);
|
|
495
|
-
} });
|
|
496
|
-
let lastPersistedFingerprint;
|
|
497
|
-
const persistOnce = async () => {
|
|
498
|
-
const [dust, shielded, unshielded, txHistory] = (await firstValueFrom(zip(from(walletFacade.dust.serializeState()), from(walletFacade.shielded.serializeState()), from(walletFacade.unshielded.serializeState()), from(txHistoryStorage.serialize())))).map(SerialisedWalletState);
|
|
499
|
-
const fingerprint = fingerprintOf([
|
|
500
|
-
dust,
|
|
501
|
-
shielded,
|
|
502
|
-
unshielded,
|
|
503
|
-
txHistory
|
|
504
|
-
]);
|
|
505
|
-
if (fingerprint === lastPersistedFingerprint) return;
|
|
506
|
-
if (isPersistenceHalted || isDestroyed) return;
|
|
507
|
-
await firstValueFrom(store.upsert({
|
|
508
|
-
serializedState: {
|
|
509
|
-
dust,
|
|
510
|
-
shielded,
|
|
511
|
-
unshielded,
|
|
512
|
-
txHistory
|
|
513
|
-
},
|
|
514
|
-
accountId: account.accountId,
|
|
515
|
-
walletId: account.walletId,
|
|
516
|
-
networkId: account.blockchainSpecific.networkId
|
|
517
|
-
}).pipe(defaultIfEmpty(void 0)));
|
|
518
|
-
lastPersistedFingerprint = fingerprint;
|
|
519
|
-
};
|
|
520
|
-
persistSubscription = walletFacade.state().pipe(throttleTime(STATE_SERIALISATION_THROTTLE_TIME, void 0, {
|
|
521
|
-
leading: true,
|
|
522
|
-
trailing: true
|
|
523
|
-
}), exhaustMap(() => from(persistOnce()).pipe(catchError((error) => {
|
|
524
|
-
logger.error(`Failed to persist wallet state for account ${account.accountId}:`, error);
|
|
525
|
-
return of(void 0);
|
|
526
|
-
})))).subscribe();
|
|
527
|
-
subscriber.next({
|
|
528
|
-
walletFacade,
|
|
529
|
-
haltPersistence: () => {
|
|
530
|
-
isPersistenceHalted = true;
|
|
531
|
-
},
|
|
532
|
-
proofServerTransport,
|
|
533
|
-
finalizeRecipe
|
|
534
|
-
});
|
|
535
|
-
};
|
|
536
|
-
init().catch((error) => {
|
|
537
|
-
subscriber.error(error);
|
|
538
|
-
});
|
|
539
|
-
return () => {
|
|
540
|
-
isDestroyed = true;
|
|
541
|
-
syncStartSubscription?.unsubscribe();
|
|
542
|
-
persistSubscription?.unsubscribe();
|
|
543
|
-
if (walletFacade) walletFacade.stop().catch(() => void 0).finally(() => {
|
|
544
|
-
syncSecretKeys?.clear();
|
|
545
|
-
syncDustSecretKey?.clear();
|
|
546
|
-
});
|
|
547
|
-
};
|
|
548
|
-
});
|
|
549
|
-
};
|
|
550
|
-
/**
|
|
551
|
-
* Starts a Midnight account wallet with full lifecycle management.
|
|
552
|
-
*
|
|
553
|
-
* Creates SDK wallets, manages their start/stop lifecycle, and converts
|
|
554
|
-
* to the MidnightWallet interface used by the rest of the application.
|
|
555
|
-
*/
|
|
556
|
-
const createStartMidnightAccountWallet = (dependencies, options) => (props) => createAndManageWallets(props, dependencies, options).pipe(switchMap(({ walletFacade, haltPersistence, proofServerTransport, finalizeRecipe }) => createAccountObservableMidnightWallet({
|
|
557
|
-
account: props.account,
|
|
558
|
-
keyManager: props.keyManager,
|
|
559
|
-
walletFacade,
|
|
560
|
-
haltPersistence,
|
|
561
|
-
proofServerTransport,
|
|
562
|
-
finalizeRecipe
|
|
563
|
-
})));
|
|
564
|
-
/**
|
|
565
|
-
* The engine's side-effect dependencies. The attested prover is the
|
|
566
|
-
* loadout's: the app proves through the bundled Temenos deployment, which a
|
|
567
|
-
* headless loadout does not ship.
|
|
568
|
-
*/
|
|
569
|
-
const createMidnightSideEffectDependencies = (options = {}) => ({ runtime }, dependencies) => {
|
|
570
|
-
const midnightWallets$ = midnightWalletsForRuntime(runtime);
|
|
571
|
-
return {
|
|
572
|
-
midnightWallets$,
|
|
573
|
-
teeAttestationProgress$,
|
|
574
|
-
getMidnightWalletByAccountId: (accountId) => midnightWallets$.pipe(take(1), map((wallets) => wallets[accountId]), switchMap((wallet) => wallet ? of(wallet) : throwError(() => /* @__PURE__ */ new Error(`Could not load midnight wallet for account ${accountId}`)))),
|
|
575
|
-
stopAllMidnightWallets: () => {
|
|
576
|
-
const walletsArray = Object.values(midnightWallets$.value);
|
|
577
|
-
midnightWallets$.next({});
|
|
578
|
-
if (walletsArray.length === 0) return of(void 0);
|
|
579
|
-
return forkJoin(walletsArray.map((wallet) => wallet.stop())).pipe(map(() => void 0));
|
|
580
|
-
},
|
|
581
|
-
stopMidnightWallet: (accountId) => {
|
|
582
|
-
const wallet = midnightWallets$.value[accountId];
|
|
583
|
-
if (!wallet) return of(void 0);
|
|
584
|
-
const { [accountId]: _, ...remaining } = midnightWallets$.value;
|
|
585
|
-
midnightWallets$.next(remaining);
|
|
586
|
-
return wallet.stop().pipe(map(() => void 0));
|
|
587
|
-
},
|
|
588
|
-
startMidnightAccountWallet: createStartMidnightAccountWallet(dependencies, options)
|
|
589
|
-
};
|
|
590
|
-
};
|
|
591
|
-
//#endregion
|
|
592
|
-
//#region ../../packages/module/midnight-sync/src/store/utils/activities.ts
|
|
593
|
-
const toBigInt = (v) => typeof v === "bigint" ? v : BigInt(v);
|
|
594
|
-
const buildTokenBalanceChangesFromUtxos = (createdUtxos, spentUtxos, networkId) => {
|
|
595
|
-
const changesByToken = /* @__PURE__ */ new Map();
|
|
596
|
-
for (const u of createdUtxos) {
|
|
597
|
-
const tokenId = TokenId(toUnshieldedTokenType(u.tokenType, networkId));
|
|
598
|
-
const existing = changesByToken.get(tokenId);
|
|
599
|
-
const value = toBigInt(u.value);
|
|
600
|
-
changesByToken.set(tokenId, {
|
|
601
|
-
tokenId,
|
|
602
|
-
amount: existing ? existing.amount + value : value
|
|
603
|
-
});
|
|
604
|
-
}
|
|
605
|
-
for (const u of spentUtxos) {
|
|
606
|
-
const tokenId = TokenId(toUnshieldedTokenType(u.tokenType, networkId));
|
|
607
|
-
const existing = changesByToken.get(tokenId);
|
|
608
|
-
const value = toBigInt(u.value);
|
|
609
|
-
changesByToken.set(tokenId, {
|
|
610
|
-
tokenId,
|
|
611
|
-
amount: existing ? existing.amount - value : -value
|
|
612
|
-
});
|
|
613
|
-
}
|
|
614
|
-
return [...changesByToken.values()].filter(({ amount }) => amount !== 0n).map(({ tokenId, amount }) => ({
|
|
615
|
-
tokenId,
|
|
616
|
-
amount: BigNumber(amount)
|
|
617
|
-
}));
|
|
618
|
-
};
|
|
619
|
-
const getAddressFromUtxos = (createdUtxos, spentUtxos) => {
|
|
620
|
-
return (createdUtxos[0] ?? spentUtxos[0])?.owner ?? "";
|
|
621
|
-
};
|
|
622
|
-
/**
|
|
623
|
-
* Whether the wallet took part in an unshielded movement in this transaction —
|
|
624
|
-
* the gate for surfacing it as an activity. True for unshielded and mixed sends,
|
|
625
|
-
* and for dust designation (which rotates night UTxOs into the unshielded
|
|
626
|
-
* section). False for shielded-only entries: their values are encrypted and
|
|
627
|
-
* unreadable, and the fee-dust they spend never lands in the unshielded section,
|
|
628
|
-
* so surfacing them would only produce an empty/unknown row.
|
|
629
|
-
*/
|
|
630
|
-
const entryHasUnshieldedActivity = (entry) => (entry.unshielded?.createdUtxos.length ?? 0) > 0 || (entry.unshielded?.spentUtxos.length ?? 0) > 0;
|
|
631
|
-
const mapStatusToActivityType = (status, tokenBalanceChanges) => {
|
|
632
|
-
switch (status) {
|
|
633
|
-
case "SUCCESS":
|
|
634
|
-
case "PARTIAL_SUCCESS": return !tokenBalanceChanges?.length || tokenBalanceChanges.some(({ amount }) => BigInt(amount) > 0n) ? ActivityType.Receive : ActivityType.Send;
|
|
635
|
-
case "FAILURE": return ActivityType.Failed;
|
|
636
|
-
}
|
|
637
|
-
};
|
|
638
|
-
/**
|
|
639
|
-
* Resolves the activity type and displayed token amounts for a transaction's
|
|
640
|
-
* unshielded section. A transaction that moved unshielded value but nets to zero
|
|
641
|
-
* is a self-transfer — a plain self-send, or a dust designation, which rotates
|
|
642
|
-
* NIGHT back to the owner — so it is surfaced as {@link ActivityType.Self}.
|
|
643
|
-
* No amount is shown: no value left the wallet, and the intended amount is not
|
|
644
|
-
* recoverable (a self output is indistinguishable from change). Failures keep
|
|
645
|
-
* their Failed type regardless.
|
|
646
|
-
*/
|
|
647
|
-
const deriveUnshieldedActivity = ({ status, createdUtxos, spentUtxos, networkId }) => {
|
|
648
|
-
const netChanges = buildTokenBalanceChangesFromUtxos(createdUtxos, spentUtxos, networkId);
|
|
649
|
-
if (status !== "FAILURE" && netChanges.length === 0 && (createdUtxos.length > 0 || spentUtxos.length > 0)) return {
|
|
650
|
-
type: ActivityType.Self,
|
|
651
|
-
tokenBalanceChanges: []
|
|
652
|
-
};
|
|
653
|
-
return {
|
|
654
|
-
type: mapStatusToActivityType(status, netChanges),
|
|
655
|
-
tokenBalanceChanges: netChanges
|
|
656
|
-
};
|
|
657
|
-
};
|
|
658
|
-
const formatFee = (fees) => fees === null || fees === void 0 ? "0" : String(fees);
|
|
659
|
-
//#endregion
|
|
660
|
-
//#region ../../packages/module/midnight-sync/src/store/side-effects/activities.ts
|
|
661
|
-
const mapTxHistoryEntryToActivity = ({ accountId, txHistoryEntry, networkId }) => {
|
|
662
|
-
const { hash, timestamp, status } = txHistoryEntry;
|
|
663
|
-
const { type, tokenBalanceChanges } = deriveUnshieldedActivity({
|
|
664
|
-
status,
|
|
665
|
-
createdUtxos: txHistoryEntry.unshielded?.createdUtxos ?? [],
|
|
666
|
-
spentUtxos: txHistoryEntry.unshielded?.spentUtxos ?? [],
|
|
667
|
-
networkId
|
|
668
|
-
});
|
|
669
|
-
return {
|
|
670
|
-
accountId,
|
|
671
|
-
activityId: hash,
|
|
672
|
-
type,
|
|
673
|
-
timestamp: Timestamp(timestamp?.getTime() ?? 0),
|
|
674
|
-
tokenBalanceChanges
|
|
675
|
-
};
|
|
676
|
-
};
|
|
677
|
-
const mapTxHistoryEntryToActivityDetail = ({ accountId, txHistoryEntry, networkId }) => {
|
|
678
|
-
const createdUtxos = txHistoryEntry.unshielded?.createdUtxos ?? [];
|
|
679
|
-
const spentUtxos = txHistoryEntry.unshielded?.spentUtxos ?? [];
|
|
680
|
-
const activity = mapTxHistoryEntryToActivity({
|
|
681
|
-
accountId,
|
|
682
|
-
txHistoryEntry,
|
|
683
|
-
networkId
|
|
684
|
-
});
|
|
685
|
-
const address = getAddressFromUtxos(createdUtxos, spentUtxos);
|
|
686
|
-
return {
|
|
687
|
-
...activity,
|
|
688
|
-
address,
|
|
689
|
-
fee: formatFee(txHistoryEntry.fees)
|
|
690
|
-
};
|
|
691
|
-
};
|
|
692
|
-
/**
|
|
693
|
-
* Whether confirmed rows with no unshielded section are shown. They carry no
|
|
694
|
-
* readable value or date, so they render as amount-less "unknown" / 1970 rows;
|
|
695
|
-
* hiding them is the default and the flag restores the earlier behaviour while
|
|
696
|
-
* the product decision is open.
|
|
697
|
-
*/
|
|
698
|
-
const showShieldedOnlyRows$ = (stateObservables) => stateObservables.features.selectLoadedFeatures$.pipe(map((loaded) => loaded.featureFlags.some((flag) => flag.key === FEATURE_FLAG_MIDNIGHT_SHIELDED_ACTIVITY_ROWS)), distinctUntilChanged());
|
|
699
|
-
const updateActivities = (_, stateObservables, { actions, midnightWallets$ }) => midnightWallets$.pipe(scan((accumulator, wallets) => ({
|
|
700
|
-
current: wallets,
|
|
701
|
-
added: Object.values(wallets).filter((w) => !(w.accountId in accumulator.current))
|
|
702
|
-
}), {
|
|
703
|
-
current: {},
|
|
704
|
-
added: []
|
|
705
|
-
}), mergeMap(({ added }) => added), mergeMap((wallet) => combineLatest([wallet.transactionHistory$, showShieldedOnlyRows$(stateObservables)]).pipe(map(([transactionHistory, showShieldedOnlyRows]) => ({
|
|
706
|
-
activities: transactionHistory.filter((entry) => showShieldedOnlyRows || entryHasUnshieldedActivity(entry)).map((txHistoryEntry) => mapTxHistoryEntryToActivity({
|
|
707
|
-
accountId: wallet.accountId,
|
|
708
|
-
txHistoryEntry,
|
|
709
|
-
networkId: wallet.networkId
|
|
710
|
-
})),
|
|
711
|
-
suppressedActivityIds: showShieldedOnlyRows ? [] : transactionHistory.filter((entry) => !entryHasUnshieldedActivity(entry)).map((entry) => entry.hash)
|
|
712
|
-
})), mergeMap(({ activities, suppressedActivityIds }) => [
|
|
713
|
-
actions.activities.upsertActivities({
|
|
714
|
-
accountId: wallet.accountId,
|
|
715
|
-
activities
|
|
716
|
-
}),
|
|
717
|
-
...suppressedActivityIds.length > 0 ? [actions.activities.removeActivities({
|
|
718
|
-
accountId: wallet.accountId,
|
|
719
|
-
activityIds: suppressedActivityIds
|
|
720
|
-
})] : [],
|
|
721
|
-
actions.activities.setHasLoadedOldestEntry({
|
|
722
|
-
accountId: wallet.accountId,
|
|
723
|
-
hasLoadedOldestEntry: true
|
|
724
|
-
}),
|
|
725
|
-
actions.activities.setDesiredLoadedActivitiesCount({
|
|
726
|
-
accountId: wallet.accountId,
|
|
727
|
-
desiredLoadedActivitiesCount: activities.length
|
|
728
|
-
})
|
|
729
|
-
]), takeUntil(midnightWallets$.pipe(filter((wallets) => !(wallet.accountId in wallets)))))));
|
|
730
|
-
const loadActivityDetails = ({ activities: { loadActivityDetails$ } }, _, { actions, getMidnightWalletByAccountId, logger }) => loadActivityDetails$.pipe(filter(({ payload: { blockchainName } }) => blockchainName === "Midnight"), map((action) => action.payload.activity), switchMap(({ activityId, accountId }) => getMidnightWalletByAccountId(accountId).pipe(switchMap((wallet) => wallet.getTransactionHistoryEntryByHash(activityId).pipe(map((txHistoryEntry) => {
|
|
731
|
-
if (!txHistoryEntry) return actions.activities.setActivityDetails({ activityDetails: void 0 });
|
|
732
|
-
return actions.activities.setActivityDetails({ activityDetails: mapTxHistoryEntryToActivityDetail({
|
|
733
|
-
accountId: wallet.accountId,
|
|
734
|
-
txHistoryEntry,
|
|
735
|
-
networkId: wallet.networkId
|
|
736
|
-
}) });
|
|
737
|
-
}), catchError((error) => {
|
|
738
|
-
logger.error("Failed to load Midnight activity details", error);
|
|
739
|
-
return EMPTY;
|
|
740
|
-
}))), catchError(() => EMPTY))));
|
|
741
|
-
//#endregion
|
|
742
|
-
//#region ../../packages/module/midnight-sync/src/store/side-effects/proof-server-kill-switch.ts
|
|
743
|
-
/** Persist the fallback when a selected provider is disabled or no longer
|
|
744
|
-
* belongs to the source-controlled catalogue. Notify once per affected batch. */
|
|
745
|
-
const migrateUnavailableProofServerSelection = (_, { midnightContext: { selectUnavailableProofServerNetworks$, selectNetworksConfig$, selectNetworksConfigFeatureFlagsOverrides$ } }, { actions }) => selectUnavailableProofServerNetworks$.pipe(distinctUntilChanged(isEqual), filter((networkIds) => networkIds.length > 0), withLatestFrom(selectNetworksConfig$, selectNetworksConfigFeatureFlagsOverrides$), mergeMap(([networkIds, networksConfig, featureFlagsOverrides]) => from([...networkIds.map((networkId) => actions.midnightContext.setUserNetworkConfigOverride({
|
|
746
|
-
networkId,
|
|
747
|
-
config: networksConfig[networkId],
|
|
748
|
-
featureFlagsOverrides: featureFlagsOverrides[networkId] ?? {}
|
|
749
|
-
})), actions.ui.showToast({
|
|
750
|
-
text: "midnight.proof-server.unavailable",
|
|
751
|
-
color: "neutral",
|
|
752
|
-
duration: 8,
|
|
753
|
-
leftIcon: {
|
|
754
|
-
name: "AlertTriangle",
|
|
755
|
-
size: 20
|
|
756
|
-
}
|
|
757
|
-
})])));
|
|
758
|
-
//#endregion
|
|
759
|
-
//#region ../../packages/module/midnight-sync/src/store/side-effects/resync.ts
|
|
760
|
-
const withMidnightAccounts = (makeSideEffect) => (actionObservables, stateObservables, dependencies) => makeSideEffect(midnightAccounts$(stateObservables))(actionObservables, stateObservables, dependencies);
|
|
761
|
-
const requestResyncWallet = withMidnightAccounts((midnightAccount$) => ({ midnightSync: { requestResync$ } }, _, { actions }) => merge(requestResync$.pipe(withLatestFrom(midnightAccount$), switchMap(([_, accounts]) => {
|
|
762
|
-
return from([...accounts.map(({ accountId }) => actions.sync.addSyncOperation({
|
|
763
|
-
accountId,
|
|
764
|
-
operation: {
|
|
765
|
-
operationId: `${accountId}-midnight-sync`,
|
|
766
|
-
status: "Pending",
|
|
767
|
-
description: "sync.operation.midnight-resync",
|
|
768
|
-
startedAt: Timestamp(Date.now())
|
|
769
|
-
}
|
|
770
|
-
})), actions.midnightSync.resync()]);
|
|
771
|
-
}))));
|
|
772
|
-
const createClearWalletStateOnResync = (store) => withMidnightAccounts((midnightAccounts$) => ({ midnightSync: { resync$ } }, _, { actions, stopAllMidnightWallets, logger }) => resync$.pipe(withLatestFrom(midnightAccounts$), switchMap(([_, midnightAccounts]) => stopAllMidnightWallets().pipe(catchError((error) => {
|
|
773
|
-
logger.error("Midnight resync: stop failed", error);
|
|
774
|
-
return of(void 0);
|
|
775
|
-
}), switchMap(() => store.clear().pipe(defaultIfEmpty(void 0), catchError((error) => {
|
|
776
|
-
logger.error("Midnight resync: state wipe failed", error);
|
|
777
|
-
return of(void 0);
|
|
778
|
-
}))), switchMap(() => [...midnightAccounts.flatMap(({ accountId }) => [
|
|
779
|
-
actions.addresses.resetAddresses({ accountId }),
|
|
780
|
-
actions.tokens.resetAccountTokens({ accountId }),
|
|
781
|
-
actions.activities.resetActivities({ accountId }),
|
|
782
|
-
actions.midnightContext.resetAccountDust({ accountId })
|
|
783
|
-
]), actions.midnightSync.restartWalletWatch()])))));
|
|
784
|
-
/**
|
|
785
|
-
* Side-effect that triggers a Midnight wallet resync whenever the config change
|
|
786
|
-
* is made with a feature flag override and the wallet is unlocked.
|
|
787
|
-
*/
|
|
788
|
-
const resyncWalletOnConfigChangeFromFeatureFlags = withMidnightAccounts((midnightAccounts$) => (_, { appLock: { isUnlocked$ }, midnightContext: { selectCurrentNetwork$, selectNetworksConfigFeatureFlagsOverrides$ } }, { actions }) => {
|
|
789
|
-
return selectNetworksConfigFeatureFlagsOverrides$.pipe(withLatestFrom(isUnlocked$), filter(([_, isUnlocked]) => isUnlocked), switchMap(() => selectCurrentNetwork$.pipe(take(1))), map(({ config }) => config), distinctUntilChanged(deepEquals)).pipe(withLatestFrom(midnightAccounts$), switchMap(([_, midnightAccounts]) => from([...midnightAccounts.map(({ accountId }) => actions.sync.addSyncOperation({
|
|
790
|
-
accountId,
|
|
791
|
-
operation: {
|
|
792
|
-
operationId: `${accountId}-midnight-sync`,
|
|
793
|
-
status: "Pending",
|
|
794
|
-
description: "sync.operation.midnight-resync",
|
|
795
|
-
startedAt: Timestamp(Date.now())
|
|
796
|
-
}
|
|
797
|
-
})), actions.midnightSync.resync()])));
|
|
798
|
-
});
|
|
799
|
-
const createDeleteWalletSideEffect = (storage) => ({ wallets: { removeWallet$ } }, { wallets: { selectAll$ } }, { stopMidnightWallet, actions, logger }) => removeWallet$.pipe(withLatestFrom(selectAll$.pipe(map((wallets) => wallets.filter(hasMidnightAccount)))), switchMap(([{ payload }, midnightWallets]) => {
|
|
800
|
-
const walletId = typeof payload === "string" ? payload : payload.walletId;
|
|
801
|
-
const targetWallet = midnightWallets.find((w) => w.walletId === walletId);
|
|
802
|
-
if (!targetWallet) return EMPTY;
|
|
803
|
-
const allMidnightAccounts = targetWallet.accounts.filter(isInMemoryMidnightAccount);
|
|
804
|
-
return (allMidnightAccounts.length > 0 ? forkJoin(allMidnightAccounts.map(({ accountId }) => stopMidnightWallet(accountId))) : of([])).pipe(switchMap(() => storage.removeWhere((wallet) => wallet.walletId === walletId).pipe(defaultIfEmpty(void 0), catchError((error) => {
|
|
805
|
-
logger.error("Midnight delete wallet: state wipe failed", error);
|
|
806
|
-
return of(void 0);
|
|
807
|
-
}))), mergeMap(() => allMidnightAccounts.flatMap(({ accountId }) => [
|
|
808
|
-
actions.addresses.resetAddresses({ accountId }),
|
|
809
|
-
actions.tokens.resetAccountTokens({ accountId }),
|
|
810
|
-
actions.activities.resetActivities({ accountId })
|
|
811
|
-
])));
|
|
812
|
-
}));
|
|
813
|
-
/**
|
|
814
|
-
* Stops one Midnight account's wallet, wipes that account's persisted SDK
|
|
815
|
-
* state, then emits the actions that clear every redux cache the wiped state
|
|
816
|
-
* fed. Scoped to a single account, unlike `createClearWalletStateOnResync`,
|
|
817
|
-
* which wipes the whole chain.
|
|
818
|
-
*
|
|
819
|
-
* A step that errors or completes without emitting is handed to
|
|
820
|
-
* `onStepFailure`: return an observable that emits to carry on with the next
|
|
821
|
-
* step, or one that errors to abort the reset with that error.
|
|
822
|
-
*/
|
|
823
|
-
const stopAndWipeAccountState$ = ({ accountId, actions, store, stop$, onStepFailure }) => stop$.pipe(take(1), throwIfEmpty(() => /* @__PURE__ */ new Error("Midnight account stop did not acknowledge completion")), catchError((error) => onStepFailure("stop", error)), switchMap(() => store.removeWhere((wallet) => wallet?.accountId === accountId).pipe(throwIfEmpty(() => /* @__PURE__ */ new Error("Midnight account storage wipe did not acknowledge completion")), catchError((error) => onStepFailure("wipe", error)))), mergeMap(() => [
|
|
824
|
-
actions.addresses.resetAddresses({ accountId }),
|
|
825
|
-
actions.tokens.resetAccountTokens({ accountId }),
|
|
826
|
-
actions.activities.resetActivities({ accountId }),
|
|
827
|
-
actions.midnightContext.resetAccountDust({ accountId }),
|
|
828
|
-
actions.sync.resetAccountSyncStatus({ accountId })
|
|
829
|
-
]));
|
|
830
|
-
/**
|
|
831
|
-
* The extension's per-account "reset sync state": stops and wipes the account,
|
|
832
|
-
* then reloads the app so every engine restarts from empty state. Stop and wipe
|
|
833
|
-
* failures are logged and the reset carries on, because the reload is what
|
|
834
|
-
* recovers the account.
|
|
835
|
-
*
|
|
836
|
-
* The reload is emitted LAST, after the storage write settles: sequencing it
|
|
837
|
-
* inside this chain (rather than firing it from a separate UI tap) is what stops
|
|
838
|
-
* a hard reload from preempting the wipe and leaving the old SDK document to
|
|
839
|
-
* restore from.
|
|
840
|
-
*/
|
|
841
|
-
const createResetSyncStateSideEffect = (store) => withMidnightAccounts((midnightAccounts$) => ({ midnightContext: { resetSyncState$ } }, _, { actions, stopMidnightWallet, logger }) => resetSyncState$.pipe(withLatestFrom(midnightAccounts$), switchMap(([{ payload }, midnightAccounts]) => {
|
|
842
|
-
const account = midnightAccounts.find(({ accountId }) => accountId === payload.accountId);
|
|
843
|
-
if (!account) return EMPTY;
|
|
844
|
-
const { accountId } = account;
|
|
845
|
-
return concat(stopAndWipeAccountState$({
|
|
846
|
-
accountId,
|
|
847
|
-
actions,
|
|
848
|
-
store,
|
|
849
|
-
stop$: stopMidnightWallet(accountId),
|
|
850
|
-
onStepFailure: (step, error) => {
|
|
851
|
-
logger.error(`Midnight reset sync state: ${step} failed`, error);
|
|
852
|
-
return of(void 0);
|
|
853
|
-
}
|
|
854
|
-
}), of(actions.app.reloadApplication()));
|
|
855
|
-
})));
|
|
856
|
-
/**
|
|
857
|
-
* The headless per-account "reset sync state": stops and wipes the account,
|
|
858
|
-
* then restarts that account's watcher in place, since a headless runtime has
|
|
859
|
-
* no application to reload. The account's sync operation reads Pending while
|
|
860
|
-
* the reset runs and Failed if a stop or wipe fails, so the caller can observe
|
|
861
|
-
* the outcome and retry.
|
|
862
|
-
*/
|
|
863
|
-
const createHeadlessResetSyncStateSideEffect = (store) => withMidnightAccounts((midnightAccounts$) => ({ midnightContext: { resetSyncState$ } }, _, { actions, stopMidnightWallet, logger }) => resetSyncState$.pipe(withLatestFrom(midnightAccounts$), groupBy(([{ payload }]) => payload.accountId), mergeMap((requests$) => requests$.pipe(exhaustMap(([{ payload }, midnightAccounts]) => {
|
|
864
|
-
const account = midnightAccounts.find(({ accountId }) => accountId === payload.accountId);
|
|
865
|
-
if (!account) return EMPTY;
|
|
866
|
-
const { accountId } = account;
|
|
867
|
-
const pendingOperation = () => actions.sync.addSyncOperation({
|
|
868
|
-
accountId,
|
|
869
|
-
operation: {
|
|
870
|
-
operationId: `${accountId}-midnight-sync`,
|
|
871
|
-
status: "Pending",
|
|
872
|
-
description: "sync.operation.midnight-resync",
|
|
873
|
-
startedAt: Timestamp(Date.now())
|
|
874
|
-
}
|
|
875
|
-
});
|
|
876
|
-
const stop$ = merge(of(void 0), requests$).pipe(switchMap(() => defer(() => stopMidnightWallet(accountId)).pipe(throwIfEmpty(() => /* @__PURE__ */ new Error("Midnight account stop did not acknowledge completion")))));
|
|
877
|
-
return concat(of(pendingOperation()), stopAndWipeAccountState$({
|
|
878
|
-
accountId,
|
|
879
|
-
actions,
|
|
880
|
-
store,
|
|
881
|
-
stop$,
|
|
882
|
-
onStepFailure: (step, error) => {
|
|
883
|
-
logger.error(`Midnight reset sync state: ${step} failed`, error);
|
|
884
|
-
return throwError(() => error);
|
|
885
|
-
}
|
|
886
|
-
}), defer(() => of(pendingOperation(), actions.midnightSync.restartAccountWatch({ accountId })))).pipe(catchError((error) => {
|
|
887
|
-
logger.error("Midnight account resync failed", error);
|
|
888
|
-
const failedAt = Timestamp(Date.now());
|
|
889
|
-
return of(actions.sync.addSyncOperation({
|
|
890
|
-
accountId,
|
|
891
|
-
operation: {
|
|
892
|
-
operationId: `${accountId}-midnight-sync`,
|
|
893
|
-
status: "Failed",
|
|
894
|
-
description: "sync.operation.midnight-resync",
|
|
895
|
-
error: "sync.error.midnight-sync-failed",
|
|
896
|
-
startedAt: failedAt,
|
|
897
|
-
failedAt
|
|
898
|
-
}
|
|
899
|
-
}));
|
|
900
|
-
}));
|
|
901
|
-
})))));
|
|
902
|
-
//#endregion
|
|
903
|
-
//#region ../../packages/module/midnight-sync/src/store/side-effects/sync-failure.ts
|
|
904
|
-
/**
|
|
905
|
-
* Dismiss a Midnight account's sync failure once its own sync recovers.
|
|
906
|
-
*
|
|
907
|
-
* The `completeSyncOperation` for `${accountId}-midnight-sync` is the
|
|
908
|
-
* "recovered" signal, whichever route got there — transparent retry, the
|
|
909
|
-
* failure's tap-to-retry `restartWalletWatch`, or the resubscription `whileActive`
|
|
910
|
-
* performs on unlock.
|
|
911
|
-
*
|
|
912
|
-
* Keyed per-account, so no lookup is needed: a completion for a sibling Midnight
|
|
913
|
-
* account (or a Cardano/Bitcoin one) maps to a different, non-existent
|
|
914
|
-
* MidnightSyncFailureId and no-ops, leaving a still-broken account's failure in
|
|
915
|
-
* place until its OWN sync completes.
|
|
916
|
-
*/
|
|
917
|
-
const autoDismissMidnightSyncFailureOnSyncSuccess = ({ sync: { completeSyncOperation$ } }, { failures: { selectFailureById$ } }) => completeSyncOperation$.pipe(map(({ payload }) => MidnightSyncFailureId(payload.accountId)), autoDismissFailureOnSuccess(selectFailureById$));
|
|
918
|
-
/**
|
|
919
|
-
* On resume, clear the sync failure for every Midnight account.
|
|
920
|
-
*
|
|
921
|
-
* Complements the per-account recovery dismissal above by clearing a stale error
|
|
922
|
-
* immediately, rather than leaving it on screen for the length of the first sync
|
|
923
|
-
* after unlock. No restart is dispatched: `watchMidnightAccounts` ends its pipe
|
|
924
|
-
* with `whileActive`, so resuming already resubscribes every account watcher.
|
|
925
|
-
* Accounts with no failure are a no-op.
|
|
926
|
-
*/
|
|
927
|
-
const autoDismissMidnightSyncFailureOnResume = (_, { wallets: { selectAll$ }, failures: { selectFailureById$ } }, { walletResumed$ }) => walletResumed$.pipe(withLatestFrom(selectAll$), mergeMap(([, wallets]) => from(wallets.flatMap((wallet) => wallet.accounts).filter(isInMemoryMidnightAccount).map((account) => MidnightSyncFailureId(account.accountId)))), autoDismissFailureOnSuccess(selectFailureById$));
|
|
928
|
-
//#endregion
|
|
929
|
-
//#region ../../packages/module/midnight-sync/src/store/side-effects/tee-attestation-progress.ts
|
|
930
|
-
/**
|
|
931
|
-
* Forwards attested-proving progress from the dependency-level stream into
|
|
932
|
-
* redux, where the send-flow checklist UI reads it. Pure mapping — the
|
|
933
|
-
* events originate inside the proving service (ADR 19).
|
|
934
|
-
*/
|
|
935
|
-
const watchTeeAttestationProgress = (_actionObservables, _stateObservables, { actions, teeAttestationProgress$ }) => teeAttestationProgress$.pipe(map((event) => event.type === "begin" ? actions.midnightContext.teeAttestationProgressStarted(event) : actions.midnightContext.teeAttestationProgressUpdated(event)));
|
|
936
|
-
/**
|
|
937
|
-
* Clears the previous run's checklist as soon as a new Midnight transaction
|
|
938
|
-
* starts building, so a redone send never opens the
|
|
939
|
-
* processing screen with stale step results. The attested proving service's
|
|
940
|
-
* `reset` then rebuilds the pending checklist when verification actually
|
|
941
|
-
* begins. The signer owns confirmation resets. Submit must not clear the
|
|
942
|
-
* completed checklist while the transaction is being submitted.
|
|
943
|
-
*/
|
|
944
|
-
const clearTeeAttestationProgressOnNewTx = ({ txExecutor: { txPhaseRequested$ } }, _stateObservables, { actions }) => txPhaseRequested$.pipe(filter(({ payload: { config } }) => config.params.blockchainName === "Midnight" && config.type === "buildTx"), map(() => actions.midnightContext.teeAttestationProgressCleared()));
|
|
945
|
-
//#endregion
|
|
946
|
-
//#region ../../packages/module/midnight-sync/src/store/side-effects/index.ts
|
|
947
|
-
/**
|
|
948
|
-
* The engine's side effects plus the ones a loadout adds over the same
|
|
949
|
-
* persisted wallet-state storage. The engine set reads only the contracts
|
|
950
|
-
* the engine itself depends on; a loadout decides what else it can run.
|
|
951
|
-
*/
|
|
952
|
-
const createInitializeSideEffects = (loadoutSideEffects) => () => [(actionObservables, stateObservables, dependencies) => {
|
|
953
|
-
const midnightStateStorage = dependencies.createCollectionStorage({
|
|
954
|
-
collectionId: "midnightWalletState",
|
|
955
|
-
computeDocId: (wallet) => String(wallet.accountId)
|
|
956
|
-
});
|
|
957
|
-
return merge(...[
|
|
958
|
-
updateActivities,
|
|
959
|
-
loadActivityDetails,
|
|
960
|
-
createDeleteWalletSideEffect(midnightStateStorage),
|
|
961
|
-
createClearWalletStateOnResync(midnightStateStorage),
|
|
962
|
-
requestResyncWallet,
|
|
963
|
-
autoDismissMidnightSyncFailureOnResume,
|
|
964
|
-
autoDismissMidnightSyncFailureOnSyncSuccess,
|
|
965
|
-
watchMidnightAccounts(midnightStateStorage, watchMidnightAccount),
|
|
966
|
-
...loadoutSideEffects(midnightStateStorage)
|
|
967
|
-
].map((sideEffect) => sideEffect(actionObservables, stateObservables, dependencies)));
|
|
968
|
-
}];
|
|
969
|
-
createInitializeSideEffects((storage) => [
|
|
970
|
-
createResetSyncStateSideEffect(storage),
|
|
971
|
-
resyncWalletOnConfigChangeFromFeatureFlags,
|
|
972
|
-
migrateUnavailableProofServerSelection,
|
|
973
|
-
watchTeeAttestationProgress,
|
|
974
|
-
clearTeeAttestationProgressOnNewTx
|
|
975
|
-
]);
|
|
976
|
-
//#endregion
|
|
977
|
-
//#region ../../packages/module/midnight-sync/src/store/side-effects/network-config.ts
|
|
978
|
-
/**
|
|
979
|
-
* Applies a loadout's supported networks and default proof servers right
|
|
980
|
-
* after the first action the store handles, which redux-persist dispatches
|
|
981
|
-
* while the store is created. Both therefore hold before the store is handed
|
|
982
|
-
* out and before any side effect starts: a side effect would land a tick
|
|
983
|
-
* later, and a network selected in between would be checked against the
|
|
984
|
-
* contract's full list.
|
|
985
|
-
*/
|
|
986
|
-
const createApplyNetworkDefaultsMiddleware = ({ supportedNetworkIds, defaultProofServers }) => {
|
|
987
|
-
const { setDefaultProofServers, setSupportedNetworksIds } = midnightContextActions.midnightContext;
|
|
988
|
-
return (store) => (next) => {
|
|
989
|
-
let pending = [...supportedNetworkIds ? [setSupportedNetworksIds(supportedNetworkIds)] : [], ...defaultProofServers ? [setDefaultProofServers(defaultProofServers)] : []];
|
|
990
|
-
return (action) => {
|
|
991
|
-
const result = next(action);
|
|
992
|
-
const defaults = pending;
|
|
993
|
-
pending = [];
|
|
994
|
-
for (const defaultAction of defaults) store.dispatch(defaultAction);
|
|
995
|
-
return result;
|
|
996
|
-
};
|
|
997
|
-
};
|
|
998
|
-
};
|
|
999
|
-
/**
|
|
1000
|
-
* Applies a loadout's endpoint choices as user overrides on startup, so they
|
|
1001
|
-
* take precedence over the contract defaults and the feature-flag values
|
|
1002
|
-
* without a settings UI to enter them through.
|
|
1003
|
-
*/
|
|
1004
|
-
const createApplyNetworkConfigOverrides = (overrides) => (_, { midnightContext: { selectNetworksConfig$, selectNetworksConfigFeatureFlagsOverrides$ } }, { actions }) => zip(selectNetworksConfig$.pipe(take(1)), selectNetworksConfigFeatureFlagsOverrides$.pipe(take(1))).pipe(mergeMap(([networksConfig, featureFlagsOverrides]) => Object.entries(overrides).map(([networkId, override]) => actions.midnightContext.setUserNetworkConfigOverride({
|
|
1005
|
-
networkId,
|
|
1006
|
-
config: {
|
|
1007
|
-
...networksConfig[networkId],
|
|
1008
|
-
...override
|
|
1009
|
-
},
|
|
1010
|
-
featureFlagsOverrides: featureFlagsOverrides[networkId]
|
|
1011
|
-
}))));
|
|
1012
|
-
//#endregion
|
|
1013
|
-
//#region ../../packages/module/midnight-sync/src/store/sdk-init.ts
|
|
1014
|
-
const assertDefaultTestnetConfigured = (config) => {
|
|
1015
|
-
const networkId = config?.defaultMidnightTestnetNetworkId;
|
|
1016
|
-
if (!networkId || !MidnightSDKTestNetworkId.includes(networkId)) throw new Error(`createLaceWallet needs config.defaultMidnightTestnetNetworkId, the Midnight testnet a wallet starts on: one of ${MidnightSDKTestNetworkId.join(", ")}; got ${String(networkId)}`);
|
|
1017
|
-
};
|
|
1018
|
-
const createSdkStoreInit = ({ auth, batchUpdates, createAttestedProver, networks = {}, supportedNetworkIds, defaultProofServers }) => {
|
|
1019
|
-
const initializeSideEffects = createInitializeSideEffects((storage) => [
|
|
1020
|
-
registerMidnightBlockchainNetworks,
|
|
1021
|
-
createApplyNetworkConfigOverrides(networks),
|
|
1022
|
-
createHeadlessResetSyncStateSideEffect(storage)
|
|
1023
|
-
]);
|
|
1024
|
-
const initializeDependencies = createMidnightSideEffectDependencies({
|
|
1025
|
-
batchUpdates,
|
|
1026
|
-
createAttestedProver
|
|
1027
|
-
});
|
|
1028
|
-
return (props, dependencies) => {
|
|
1029
|
-
assertDefaultTestnetConfigured(props.runtime.config);
|
|
1030
|
-
return {
|
|
1031
|
-
middleware: [createApplyNetworkDefaultsMiddleware({
|
|
1032
|
-
supportedNetworkIds,
|
|
1033
|
-
defaultProofServers
|
|
1034
|
-
})],
|
|
1035
|
-
sideEffects: initializeSideEffects(props, dependencies),
|
|
1036
|
-
sideEffectDependencies: {
|
|
1037
|
-
...initializeDependencies(props, dependencies),
|
|
1038
|
-
...auth
|
|
1039
|
-
}
|
|
1040
|
-
};
|
|
1041
|
-
};
|
|
1042
|
-
};
|
|
1043
|
-
//#endregion
|
|
1044
|
-
export { createSdkStoreInit };
|