@laceio/sdk 0.1.0 → 0.1.1-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/{Ed25519PublicKey-lvu1s54U.cjs → Address-AMKTo-dA.cjs} +17150 -61
- package/dist/{Ed25519PublicKey-CjnuAYRR.js → Address-_c_-9hLC.js} +16955 -264
- package/dist/{Bip32Account-r3KAhCgU.js → Bip32Account-CaW1zC9Y.js} +4 -5
- package/dist/{Bip32Account-Cz3h0ZUa.cjs → Bip32Account-DOaGmKpv.cjs} +4 -5
- package/dist/Cardano-B-gyqBBD.js +311 -0
- package/dist/Cardano-BQ_af0Y3.cjs +322 -0
- package/dist/Ed25519PublicKey-B3QcR0J2.cjs +88 -0
- package/dist/Ed25519PublicKey-DIE19xHg.js +83 -0
- package/dist/InMemoryKeyAgent-Bc_xZY-v.cjs +652 -0
- package/dist/InMemoryKeyAgent-D8T3vtXy.js +631 -0
- package/dist/{PaymentAddress-DhbtuYb7.cjs → PaymentAddress-B4n1KZMx.cjs} +1 -2
- package/dist/{PaymentAddress-xSmGUQ-8.js → PaymentAddress-Cml3EA1n.js} +1 -2
- package/dist/Percent-Cfuw5YyL.cjs +11 -0
- package/dist/Percent-DpvyJ_93.js +5 -0
- package/dist/SodiumBip32Ed25519-BaD-kjyx.cjs +380 -0
- package/dist/SodiumBip32Ed25519-DCikAMsl.js +363 -0
- package/dist/{TransactionBuilder-CeJTNzm-.cjs → TransactionBuilder-BakTJvsJ.cjs} +59 -89
- package/dist/{TransactionBuilder-DGNDM4kt.js → TransactionBuilder-D2ErwVWv.js} +5 -71
- package/dist/_md-6zV2Cme0.cjs +684 -0
- package/dist/_md-gbUqlhqd.js +399 -0
- package/dist/_web-crypto-random-bytes-BvzwTYPG.js +197 -0
- package/dist/acc-module-NL_8mEHH.cjs +27654 -0
- package/dist/acc-module-ur8CkBd1.js +27624 -0
- package/dist/account-call-B7cF8ly4.cjs +293 -0
- package/dist/account-call-BF4rBcNw.js +3 -0
- package/dist/account-call-CoCq3V55.js +252 -0
- package/dist/account-call-DFcD257E.cjs +4 -0
- package/dist/account-guards-BeKbV9D1.cjs +41 -0
- package/dist/account-guards-qnFXuXSE.js +36 -0
- package/dist/{activity-type.stable-ClO9j_PH.cjs → activity-type-BPXxdHBP.cjs} +2 -1
- package/dist/{activity-type.stable-Ml0SOYv9.js → activity-type-C1geyPsH.js} +2 -1
- package/dist/address-OxwXIwbF.js +15502 -0
- package/dist/address-book-address-validator-BqYM0Uyp.cjs +41 -0
- package/dist/{address-book-address-validator-BhqRfmlL.cjs → address-book-address-validator-CGIcqn5W.cjs} +5 -4
- package/dist/{address-book-address-validator-VqIOB8PY.js → address-book-address-validator-FkkYim3z.js} +6 -4
- package/dist/address-book-address-validator-RSx2Jozy.js +39 -0
- package/dist/address-lECYBd9-.cjs +13043 -0
- package/dist/{apply-vkey-witnesses-Ctzk7eye.cjs → apply-vkey-witnesses-1jyczTkw.cjs} +1 -1
- package/dist/{apply-vkey-witnesses-Dfo7XfhL.js → apply-vkey-witnesses-Byb40-yJ.js} +1 -1
- package/dist/artefact-loader-Cqc9eSkL.cjs +182 -0
- package/dist/artefact-loader-D0T2f6F7.js +159 -0
- package/dist/auto-dismiss-failure-on-success-BWJceNXd.cjs +37 -0
- package/dist/auto-dismiss-failure-on-success-Bpod-v4r.js +31 -0
- package/dist/bip32-EPpcFrpH.cjs +3851 -0
- package/dist/{bip32ed25519-D2In8WzR.cjs → bip32ed25519-CRiG-Kjg.cjs} +5 -4
- package/dist/{bip32ed25519-qsLH_eWO.js → bip32ed25519-E-fCUZNv.js} +6 -4
- package/dist/bip39-DZomfqeY.js +9 -0
- package/dist/bip39-MAck9iod.cjs +26 -0
- package/dist/bitcoin-data-provider-D0OT_Uiu.cjs +26 -0
- package/dist/bitcoin-data-provider-LN_8oamW.js +21 -0
- package/dist/bitcoin.cjs +48 -0
- package/dist/bitcoin.d.ts +29805 -1
- package/dist/bitcoin.js +22 -0
- package/dist/{blake2b-BGHUWMsV.js → blake2b-BL-eR5G2.js} +6 -4
- package/dist/{blake2b-DspUqw68.cjs → blake2b-Iy324FwH.cjs} +5 -4
- package/dist/{blockfrost-tx-submit-provider-BUEOmdvc.js → blockfrost-tx-submit-provider-BHDLgOIE.js} +9 -162
- package/dist/{blockfrost-tx-submit-provider-B5dWbdrZ.cjs → blockfrost-tx-submit-provider-BxC19smv.cjs} +7 -171
- package/dist/{blockingWithLatestFrom-BhaE7pnA.js → blockingWithLatestFrom-FUfZFEUG.js} +1 -1
- package/dist/{blockingWithLatestFrom-DkuT3G2a.cjs → blockingWithLatestFrom-bmCPgA3c.cjs} +1 -1
- package/dist/bn-BFq5a4dk.cjs +2553 -0
- package/dist/{SodiumBip32Ed25519-BEfo1Q9m.js → browser-D5jRKv_L.js} +4 -401
- package/dist/bytes.vo-CziaOsba.js +24 -0
- package/dist/bytes.vo-hecRu3YZ.cjs +35 -0
- package/dist/{cardano-network-id-to-network-type-PXvn1ycQ.cjs → cardano-network-id-to-network-type-BwG_d6QP.cjs} +1 -1
- package/dist/{cardano-network-id-to-network-type-DHgKhDAK.js → cardano-network-id-to-network-type-CYJheetp.js} +1 -1
- package/dist/{cardano-network-id.vo-CbNNKd-k.cjs → cardano-network-id.vo-C5VuBXT3.cjs} +2 -2
- package/dist/{cardano-network-id.vo-CTYe-Oix.js → cardano-network-id.vo-CeLJqmb_.js} +2 -2
- package/dist/{cardano-tx-id.vo-BMwemq5x.js → cardano-tx-id.vo-DJ70NC0-.js} +1 -1
- package/dist/{cardano-tx-id.vo-NY-gCOWJ.cjs → cardano-tx-id.vo-lnyO9XaW.cjs} +1 -1
- package/dist/cardano.cjs +31 -24
- package/dist/cardano.d.ts +27602 -8121
- package/dist/cardano.js +21 -13
- package/dist/client-Bw2foG5E.cjs +808 -0
- package/dist/const-BB3MccLt.js +153 -0
- package/dist/{const-BErUlcZw.cjs → const-BWBAzOmN.cjs} +1 -1
- package/dist/const-CSWmOyzn.cjs +42 -0
- package/dist/{const-Dy8Ctnpd.cjs → const-D3mCkwrM.cjs} +5 -5
- package/dist/const-DW7z3R5k.js +13 -0
- package/dist/{const-DeUA7zYl.js → const-DbuUHSzR.js} +5 -5
- package/dist/const-DgBzKfz6.cjs +31995 -0
- package/dist/{const-DVW6DGkZ.js → const-xGSNCtwQ.js} +1 -1
- package/dist/contract-BsIGhsYa.js +171 -0
- package/dist/contract-DD6CGnpB.cjs +189 -0
- package/dist/create-add-accounts-2mQA0ST2.js +102 -0
- package/dist/create-add-accounts-B6mR2NMn.cjs +114 -0
- package/dist/{delegation-tx-builder-CF0VunDW.cjs → delegation-tx-builder-Cp30jtj9.cjs} +9 -8
- package/dist/{delegation-tx-builder-C8LQxU2R.js → delegation-tx-builder-DUMikSTg.js} +9 -7
- package/dist/{deregistration-tx-builder-DcUXA3Ls.cjs → deregistration-tx-builder-B-ZeY-dR.cjs} +10 -9
- package/dist/{deregistration-tx-builder-BOBPP8m_.js → deregistration-tx-builder-CRLrK99U.js} +10 -8
- package/dist/device-commitment-hex.vo-BIUYUNz1.cjs +31 -0
- package/dist/device-commitment-hex.vo-D9FsYLn7.js +26 -0
- package/dist/device-key-BToCoS4D.js +2394 -0
- package/dist/device-key-D6euvxFi.cjs +2489 -0
- package/dist/device-readers-BHJeNR8I.js +3 -0
- package/dist/device-readers-Dw7uTNM5.cjs +167 -0
- package/dist/device-readers-b4g2j3QL.js +144 -0
- package/dist/device-readers-cxcJcWq5.cjs +7 -0
- package/dist/dist-B00GN41m.js +141 -0
- package/dist/dist-BA1xnF9O.cjs +4413 -0
- package/dist/dist-BmHOXLe8.cjs +3814 -0
- package/dist/dist-Br0OVXKt.cjs +535 -0
- package/dist/dist-C1JK9C1I.cjs +3452 -0
- package/dist/dist-DKEViNEI.cjs +1306 -0
- package/dist/dist-Dwqx184a.cjs +43175 -0
- package/dist/dist-MJof_Ky1.cjs +145 -0
- package/dist/dist-p84sVVJ9.cjs +1394 -0
- package/dist/{earn-rewards-tx-builder-BRlTueHS.js → earn-rewards-tx-builder-8G_rouIk.js} +9 -7
- package/dist/{earn-rewards-tx-builder-RgO0QUY8.cjs → earn-rewards-tx-builder-cOUNV58E.cjs} +9 -8
- package/dist/enc-key-circuits-0Dud78IB.js +13 -0
- package/dist/enc-key-circuits-yjPHbuo_.cjs +24 -0
- package/dist/english-BZ_ebp2-.cjs +2057 -0
- package/dist/envelopes-B3QCzo5p.js +2658 -0
- package/dist/envelopes-BdE1xlgz.cjs +2777 -0
- package/dist/errors-BA3b8aVu.cjs +584 -0
- package/dist/errors-pkQdxW-7.js +392 -0
- package/dist/experimental.cjs +6820 -0
- package/dist/experimental.d.ts +63552 -0
- package/dist/experimental.js +6670 -0
- package/dist/fees-6C2uEWFK.js +653 -0
- package/dist/fees-DtC71fOx.cjs +820 -0
- package/dist/gated-call-BrPjKolT.js +3 -0
- package/dist/gated-call-CcsuW9L5.js +691 -0
- package/dist/gated-call-DdDrxEq5.cjs +732 -0
- package/dist/gated-call-Dk7PazhG.cjs +4 -0
- package/dist/grant-rules-B7eDuD5G.cjs +5468 -0
- package/dist/grant-rules-qLrKUIR3.js +5217 -0
- package/dist/grant-status-CDmZpx32.js +296 -0
- package/dist/grant-status-CQtwjLsA.cjs +337 -0
- package/dist/grants-Bnb-3Hkv.cjs +16 -0
- package/dist/grants-CIb6nOV7.cjs +273 -0
- package/dist/grants-CYY0AquW.js +202 -0
- package/dist/grants-DOsFSotP.js +4 -0
- package/dist/{group-cardano-addresses-by-account-C-1GHUu8.cjs → group-cardano-addresses-by-account-BGOtPV-Y.cjs} +4 -40
- package/dist/{group-cardano-addresses-by-account-p4dXmCoj.js → group-cardano-addresses-by-account-TqvESg9x.js} +6 -37
- package/dist/{guarded-transaction-signer-DZSGHp1K.js → guarded-transaction-signer-BbVDE9Nn.js} +12 -18
- package/dist/{guarded-transaction-signer-BLSezbfV.cjs → guarded-transaction-signer-DTLjAkif.cjs} +26 -26
- package/dist/hex-BVtOKJki.cjs +263 -0
- package/dist/hex-CGYJPK_Z.js +192 -0
- package/dist/http-client-B7_kBTYn.js +155 -0
- package/dist/http-client-DYQ_7Rdf.cjs +167 -0
- package/dist/identity-DxPhxkZs.js +239 -0
- package/dist/identity-y41Yle03.cjs +274 -0
- package/dist/in-memory-wallet-integration-5BKiAvPT.js +20861 -0
- package/dist/{in-memory-wallet-integration-CUTa68ET.js → in-memory-wallet-integration-BCOqDgbt.js} +10 -107
- package/dist/in-memory-wallet-integration-Bi8I9Dso.js +128 -0
- package/dist/in-memory-wallet-integration-Bsl2ONua.cjs +239 -0
- package/dist/in-memory-wallet-integration-DZ0CAyvY.cjs +20865 -0
- package/dist/{in-memory-wallet-integration-Dw_S7amX.cjs → in-memory-wallet-integration-DsFm8gLk.cjs} +21 -112
- package/dist/{in-memory-wallet-integration-Z4Bp_DTv.cjs → in-memory-wallet-integration-aW_SF-go.cjs} +8 -5
- package/dist/{in-memory-wallet-integration-B6cbAlvD.js → in-memory-wallet-integration-mIEc8EfR.js} +9 -5
- package/dist/index.cjs +95 -58
- package/dist/index.d.ts +45152 -13448
- package/dist/index.js +55 -28
- package/dist/{init-CVi8J0zk.cjs → init-5SfWgCYD.cjs} +3 -3
- package/dist/{init-Ci7aqWCf2.cjs → init-8NVWbo302.cjs} +2 -2
- package/dist/init-B-C7n6u6.js +5 -0
- package/dist/{init-BFMWRf-L.js → init-B-ppfGO-.js} +1 -1
- package/dist/{init-IiR093Jw.cjs → init-B2OUhY5T.cjs} +2 -2
- package/dist/{init-DXnus199.cjs → init-B6Eg_o6G.cjs} +5 -5
- package/dist/{init-4hDl5bpr.js → init-BAWMHL1k.js} +2 -2
- package/dist/init-BC2CZZOu2.cjs +2002 -0
- package/dist/{init-a228hXnS.cjs → init-BF-a2p6E.cjs} +65 -73
- package/dist/{init-fFirX8OY.cjs → init-BFxlQAD8.cjs} +1 -1
- package/dist/init-BJE1ry0O.js +17 -0
- package/dist/{init-BVnI4z2J.js → init-BPKBVOHU.js} +2 -2
- package/dist/{init-bdqZBd-o.js → init-BSP_xcpB.js} +2 -2
- package/dist/{init-CFNOn3lo.js → init-BSd7mznK.js} +3 -3
- package/dist/{init-MjR4swi6.js → init-BUJTT0MN.js} +36 -43
- package/dist/init-BUpFzYsD.cjs +143 -0
- package/dist/{init-BvpYHyLH.cjs → init-BZ-WyAIL.cjs} +3 -3
- package/dist/init-BZdfdLX7.js +422 -0
- package/dist/{init-CJeOys1w.cjs → init-B_HWNXMD.cjs} +2 -2
- package/dist/init-BbIMt6xU.cjs +6 -0
- package/dist/{init-BYdN1aqE.cjs → init-BewG6swt.cjs} +2 -2
- package/dist/{init-BX0AZAVH2.js → init-Bilqsbng.js} +2 -2
- package/dist/{init-Tpn9VkFu.cjs → init-BpwlQ6wF.cjs} +1 -1
- package/dist/{init-D5-P0HXK.js → init-BtQOzUjX.js} +1 -1
- package/dist/{init-BvGz3qUd2.js → init-CCTscPaY2.js} +2 -2
- package/dist/{init-D4hPipCD.cjs → init-CH0yyBof.cjs} +1 -1
- package/dist/init-CaIkrXal.cjs +121 -0
- package/dist/init-CkZy4IMf.cjs +107 -0
- package/dist/{init-Drr2f_Pr.js → init-CmfcY7SV.js} +1 -1
- package/dist/{init-Kf3_OLv6.js → init-CnJAlks_.js} +1 -1
- package/dist/{init-Cdjt_z-b.cjs → init-CqqmtAIK.cjs} +4 -4
- package/dist/{init-Bb0avZeZ.js → init-Cu2znmIc.js} +5 -5
- package/dist/init-Cz5LAizN.js +2001 -0
- package/dist/init-D4WM3-Mn.cjs +18 -0
- package/dist/init-DMi2FGpf.cjs +424 -0
- package/dist/{init-lcaUSOOG.js → init-DPTJohPd.js} +1 -1
- package/dist/{init-BTYLMF9F2.cjs → init-DexLSprL2.cjs} +258 -61
- package/dist/init-DfKPgD21.js +106 -0
- package/dist/init-DgzRsI-C.js +141 -0
- package/dist/init-Dj4Cn7-P.js +4789 -0
- package/dist/init-DktAnYI0.cjs +2354 -0
- package/dist/{init-DFwhgert.cjs → init-DmyuM9Lo.cjs} +1 -1
- package/dist/{init-CX_zLXc6.js → init-IBnizp1U.js} +5 -5
- package/dist/init-MDKB6tGI2.cjs +4790 -0
- package/dist/{init-DbZ5byj42.js → init-TbB38KNt2.js} +258 -60
- package/dist/init-X6m_cqDy.js +2353 -0
- package/dist/{init-DvVgKCaP2.cjs → init-bzvl1JhF.cjs} +2 -2
- package/dist/{init-BgrY29gW.js → init-dsYkC_0B.js} +4 -4
- package/dist/{init-B5BsI3DR.cjs → init-kvn5FlPS.cjs} +7 -7
- package/dist/init-vfy9DW_E.js +119 -0
- package/dist/{init-BE_6Jyc4.js → init-w7xl6LsP.js} +3 -3
- package/dist/{init-DEsWVyn5.cjs → init-wgiBUmyW.cjs} +1 -1
- package/dist/{is-retriable-error-DWv_ob-f.js → is-retriable-error-CmFR20pe.js} +1 -1
- package/dist/{is-retriable-error-Dtb4JGjd.cjs → is-retriable-error-D2yo0_lS.cjs} +1 -1
- package/dist/jubjub-authoriser-A2c8vmkN.js +84 -0
- package/dist/jubjub-authoriser-D3ZDgzcF.cjs +85 -0
- package/dist/key-source-CcLTx8HK.js +2761 -0
- package/dist/key-source-D2tTAag-.cjs +806 -0
- package/dist/{key-value-store-DTX1quRS.js → key-value-store-DZcNDB3n.js} +1 -1
- package/dist/{key-value-store-B-XRIwaM.cjs → key-value-store-Htj4RgMe.cjs} +1 -1
- package/dist/keyDerivation-DcKRUCVh.cjs +274 -0
- package/dist/keyDerivation-QGesIMbS.js +4077 -0
- package/dist/{lace-context-FpU3iG3f.cjs → lace-context-BN0b_ury.cjs} +4 -4
- package/dist/{lace-context-BQvvxVLm.js → lace-context-DMRJ87Vg.js} +4 -4
- package/dist/lib-BC-62Byh.cjs +2359 -0
- package/dist/lib-JYqcAX0c.js +2354 -0
- package/dist/midnight-account-id.vo--Vcx34Xk.cjs +10 -0
- package/dist/midnight-account-id.vo-BuB8fiVO.js +5 -0
- package/dist/midnight-engine-B7D2hbHo.js +5 -0
- package/dist/midnight-engine-D5ikN_5F.cjs +6 -0
- package/dist/midnight-wallet-BOdFD6SX.cjs +24 -0
- package/dist/midnight-wallet-CAqZrNVe.js +18 -0
- package/dist/midnight.cjs +1412 -0
- package/dist/midnight.d.ts +28609 -0
- package/dist/midnight.js +1355 -0
- package/dist/modules-cardano-BiL9hoM3.js +996 -0
- package/dist/modules-cardano-UeXks3sd.cjs +1109 -0
- package/dist/node-relay-BOuvdZvC.cjs +49 -0
- package/dist/node-relay-CLtc5n1v.js +48 -0
- package/dist/outputs-5qdW8s-f.js +196 -0
- package/dist/outputs-BEM1GPMf.cjs +339 -0
- package/dist/{SodiumBip32Ed25519-BQUcrQWX.cjs → pbkdf2-B1veireP.cjs} +6 -411
- package/dist/pending-operation-CfTUNQVD.cjs +26 -0
- package/dist/pending-operation-Ljijb1Uh.js +21 -0
- package/dist/providers-1on_fwJO.cjs +364 -0
- package/dist/providers-C1MsxfMA.js +341 -0
- package/dist/redacted-4SJPqt-G.js +81 -0
- package/dist/redacted-DwxIDdIF.cjs +86 -0
- package/dist/{reselect-DPML1uFN.cjs → reselect-kP4DaAII.cjs} +1 -1
- package/dist/{retry-config-oNtfdyrG.cjs → retry-config-BGv5q5QM.cjs} +1 -1
- package/dist/{retry-config-VdbuqBsI.js → retry-config-Bu5Yn5ua.js} +1 -1
- package/dist/safe-buffer-CqGpSFCQ.js +43 -0
- package/dist/safe-buffer-DbXbwhUQ.cjs +48 -0
- package/dist/sdk-1SRu8Ype.cjs +1445 -0
- package/dist/sdk-BneJm7ey.js +1249 -0
- package/dist/sdk-init-9TG1ZvHF.cjs +3795 -0
- package/dist/sdk-init-Ce3mD-8F.js +1047 -0
- package/dist/secret-box-CSmRp6Tt.js +3777 -0
- package/dist/secret-box-ZfbYwBgS.cjs +6970 -0
- package/dist/send-proof-progress-DtAcrMP6.cjs +33 -0
- package/dist/send-proof-progress-Dx2cUz1B.js +22 -0
- package/dist/sha2-DaRJZOjk.cjs +390 -0
- package/dist/sha2-c4sB6peD.js +378 -0
- package/dist/side-effects-C3BhLrdP.js +768 -0
- package/dist/side-effects-DG0R-KFc.cjs +804 -0
- package/dist/sign-bitcoin-transaction-with-seed-C7vq9om8.js +147 -0
- package/dist/sign-bitcoin-transaction-with-seed-Ds1dwzan.cjs +158 -0
- package/dist/signer--2I6poMD.js +2 -0
- package/dist/signer-CX21Ups_.cjs +121 -0
- package/dist/signer-Cnn9q9oY.js +92 -0
- package/dist/signer-DbSxjk0F.cjs +7 -0
- package/dist/signer-factory-B5oFuUZ-.cjs +130 -0
- package/dist/signer-factory-BAt8FPNc.cjs +281 -0
- package/dist/signer-factory-BGE4nL4k.js +129 -0
- package/dist/signer-factory-C4pgsiJi.js +281 -0
- package/dist/{signer-factory-DySc1wRX.cjs → signer-factory-D95jQIPV.cjs} +9 -6
- package/dist/{signer-factory-D4HrwFPl.js → signer-factory-PrpsGX-8.js} +10 -6
- package/dist/{slice-BZTQgYSs.js → slice-B-xJcuT1.js} +4 -4
- package/dist/slice-B4QOYaOG.cjs +105 -0
- package/dist/{slice-CtIMw2YT.cjs → slice-B9QKuhi0.cjs} +3 -3
- package/dist/slice-BKnGkAkd.cjs +9031 -0
- package/dist/{slice-Bhwmqn1p.cjs → slice-Bf4enJKZ.cjs} +8 -8
- package/dist/{slice-DaNVz7_l.js → slice-ByNWnxKS.js} +8 -8
- package/dist/{slice-C2UDQrdt.js → slice-C1zOeseG.js} +449 -355
- package/dist/{slice-DFLyKRm5.cjs → slice-C4toRM6A.cjs} +2 -2
- package/dist/{slice-Cx4dULDA.cjs → slice-C8YVv4Qn.cjs} +1 -1
- package/dist/{slice-jnpOgiSZ.cjs → slice-CaMfviYu.cjs} +3 -3
- package/dist/{slice-DFvrwUur.js → slice-CgeRsYRg.js} +6 -6
- package/dist/slice-Cwt8jShq.js +9013 -0
- package/dist/{slice-zNEspZND.js → slice-D0VzpMbY.js} +2 -2
- package/dist/slice-D14F78Ca.js +87 -0
- package/dist/{slice-F6A1YKOF.cjs → slice-DLflttAu.cjs} +479 -366
- package/dist/{slice-C96EdeY1.js → slice-DcO-iNz2.js} +1 -1
- package/dist/{slice-C19quNWM.cjs → slice-DimtxfAT.cjs} +2 -2
- package/dist/{slice-KiNoGwD9.js → slice-DlTEqIoI.js} +1 -1
- package/dist/{slice-ws8PccRX.js → slice-Dn0WojD7.js} +3 -3
- package/dist/{slice-BLSxLmie.cjs → slice-Dongunf7.cjs} +4 -4
- package/dist/{slice-B6vPum19.js → slice-DpufJAjJ.js} +2 -2
- package/dist/{slice-exhhmucR.cjs → slice-DtitVc9L.cjs} +7 -7
- package/dist/{slice-Bjj2t2ut.cjs → slice-WMMMc1Xv.cjs} +2 -2
- package/dist/slice-a8VuIqzS.cjs +378 -0
- package/dist/slice-bRASyM-m.js +354 -0
- package/dist/{slice-CBFrgHSH.js → slice-hNyKbDry.js} +3 -3
- package/dist/{InMemoryKeyAgent-pyB2gA-N.cjs → src-BayYMIjw.cjs} +20 -8228
- package/dist/{InMemoryKeyAgent-D-3HejxN.js → src-CgINPlSx.js} +29 -4811
- package/dist/store-AUlTfcI_.js +37 -0
- package/dist/store-C7AneHEY.cjs +66 -0
- package/dist/submit-BuBCVi-l.cjs +87 -0
- package/dist/submit-D37lxFrK.js +70 -0
- package/dist/submit-bitcoin-tx-DFLnhidO.js +983 -0
- package/dist/submit-bitcoin-tx-sih2hSfb.cjs +1049 -0
- package/dist/{subtractValueQuantities-DfZg6oiG.js → subtractValueQuantities-BuDJVxq6.js} +3 -22
- package/dist/{subtractValueQuantities-C8qDTtgH.cjs → subtractValueQuantities-CqR606HV.cjs} +2 -32
- package/dist/{sync-operation-utils-BrQyWFS_.cjs → sync-operation-utils--Z_IQfyW.cjs} +0 -66
- package/dist/{sync-operation-utils-CAaCGvEN.js → sync-operation-utils-BimBpvI3.js} +1 -37
- package/dist/token-color.vo-CItgoOjw.js +26 -0
- package/dist/token-color.vo-Ca4hUXfh.cjs +37 -0
- package/dist/token-id-mapper-BVau2RXa.js +16 -0
- package/dist/token-id-mapper-CSeLzM4o.cjs +18 -0
- package/dist/{token-id-mapper-pDaTxpw2.js → token-id-mapper-ClBeIdJR.js} +2 -2
- package/dist/{token-id-mapper-DYcd8hhQ.cjs → token-id-mapper-D0wFdbOy.cjs} +2 -2
- package/dist/types-BhzypKMS.cjs +15 -0
- package/dist/types-DTE1ctDB.js +10 -0
- package/dist/types-DXSxXGz0.js +12 -0
- package/dist/types-Dls6Z5gV.cjs +23 -0
- package/dist/{util-P4PX2muj.cjs → util-D1YlKzrc.cjs} +2 -2
- package/dist/{util-CQSJU0wT.js → util-DHxtzUzY.js} +2 -2
- package/dist/{utils-Bv4OHT4S.cjs → utils-DYf4iZKX.cjs} +7 -1
- package/dist/{utils-DrtzChYN.js → utils-DcnoETEP.js} +2 -2
- package/dist/utils-Du0YXRcU.cjs +112 -0
- package/dist/utils-fF_rnZe3.js +65 -0
- package/dist/v8Signatures-ClGpA8mS.cjs +71 -0
- package/dist/{vote-delegation-tx-builder-69gOEkCB.cjs → vote-delegation-tx-builder-BjZxCOd3.cjs} +9 -8
- package/dist/{vote-delegation-tx-builder-BRJ_pf-c.js → vote-delegation-tx-builder-DRJwPXkD.js} +9 -7
- package/dist/watch-FGE4B_Ge.js +13056 -0
- package/dist/watch-imlsRZDp.cjs +52207 -0
- package/package.json +95 -3
- package/dist/Address-4KjeDt_x.cjs +0 -17269
- package/dist/Address-_VPkf7Xh.js +0 -17101
- package/dist/account-guards.stable-BKyYPj4z.cjs +0 -10
- package/dist/account-guards.stable-BdmQ43vC.js +0 -5
- package/dist/init-BR9ZIbED.cjs +0 -378
- package/dist/init-B_k1RUN_.cjs +0 -21
- package/dist/init-Bs3b5ZQH.js +0 -378
- package/dist/init-ChfcrHgG2.cjs +0 -4354
- package/dist/init-D1uUMMpG.js +0 -19
- package/dist/init-DV1OSZiK.js +0 -4352
- package/dist/modules-cardano-BINzpXpk.js +0 -5454
- package/dist/modules-cardano-Dt8OwoQb.cjs +0 -5640
- package/dist/slice-Caf98m0d2.js +0 -107
- package/dist/slice-PM6llajQ2.cjs +0 -125
- /package/dist/{BigIntMath-CoJWXt1h.cjs → BigIntMath-CBciEQn2.cjs} +0 -0
- /package/dist/{BigIntMath-BWUJOsOW.js → BigIntMath-X3EniYDo.js} +0 -0
- /package/dist/{ChainId-sdLmlIRk.cjs → ChainId-CNPSU9nn.cjs} +0 -0
- /package/dist/{ChainId-CKbm87yQ.js → ChainId-CeoG8Sov.js} +0 -0
- /package/dist/{_polyfill-node.process-4fnlkbBi.cjs → _polyfill-node.process-5UxyjoHG.cjs} +0 -0
- /package/dist/{account-id.vo-Xpgnu-av.cjs → account-id.vo-DYZBZQsz.cjs} +0 -0
- /package/dist/{account-id.vo-DP0BtOoF.js → account-id.vo-KDTWJ-W5.js} +0 -0
- /package/dist/{actions-BNagEO6m.cjs → actions-BnHFVSr_.cjs} +0 -0
- /package/dist/{actions-BWTyAr7B.js → actions-Cwj0ApZf.js} +0 -0
- /package/dist/{asyncoption-po7-RiA5.cjs → asyncoption-CYcZNBRM.cjs} +0 -0
- /package/dist/{asyncoption-CzIVH5Y1.js → asyncoption-DZQGfznq.js} +0 -0
- /package/dist/{bignum.vo-DhhZ9HP1.js → bignum.vo-Co6tMH2q.js} +0 -0
- /package/dist/{bignum.vo-CpkrIXjH.cjs → bignum.vo-Du-bpvar.cjs} +0 -0
- /package/dist/{blockchain-network-id.vo-CbgrAY_K.js → blockchain-network-id.vo-C6Jowh8t.js} +0 -0
- /package/dist/{blockchain-network-id.vo-5iC6Kffo.cjs → blockchain-network-id.vo-DEQ14dYj.cjs} +0 -0
- /package/dist/{composite-signer-factory-DABpCe1_.js → composite-signer-factory-D9RWY-1V.js} +0 -0
- /package/dist/{composite-signer-factory-BizuNPP7.cjs → composite-signer-factory-v4Pxn8bA.cjs} +0 -0
- /package/dist/{error-ggOihIfv.cjs → error-B6wj9nPv.cjs} +0 -0
- /package/dist/{error-DHKO2iS4.js → error-CvEYL98P.js} +0 -0
- /package/dist/{esm-browser-DnXNvpcn.cjs → esm-browser-CZbMeVod.cjs} +0 -0
- /package/dist/{esm-browser-BBVQuyQv.js → esm-browser-DpAD_RKv.js} +0 -0
- /package/dist/{feature-flag-key.vo-DoGK5Bfh.js → feature-flag-key.vo-9reURsOQ.js} +0 -0
- /package/dist/{feature-flag-key.vo-CP1Z9s8e.cjs → feature-flag-key.vo-KTIdnzYX.cjs} +0 -0
- /package/dist/{first-state-of-status-Bx4-QQ5m.cjs → first-state-of-status-9ICeDNSa.cjs} +0 -0
- /package/dist/{first-state-of-status-D7XzEuSa.js → first-state-of-status-BscbKj_t.js} +0 -0
- /package/dist/{init-4319psUJ.cjs → init-BT67pd9x.cjs} +0 -0
- /package/dist/{init-AFUM1TSg.js → init-CHk1fvJ2.js} +0 -0
- /package/dist/{init-ZX90nEJe2.js → init-DIyNx6DZ.js} +0 -0
- /package/dist/{init-CTQ2g6Xt.js → init-DtxxFaCx.js} +0 -0
- /package/dist/{init-Dt1Xifg_2.cjs → init-J8QobR93.cjs} +0 -0
- /package/dist/{init-BNewLCqw.cjs → init-xzZPlQwB.cjs} +0 -0
- /package/dist/{is-redux-persist-state-DxJSsvxB.cjs → is-redux-persist-state-C5luvPEH.cjs} +0 -0
- /package/dist/{is-redux-persist-state-Bl2n4VMr.js → is-redux-persist-state-CjcqyCoh.js} +0 -0
- /package/dist/{isNotNil-CZxBMfL5.js → isNotNil-Be7gCY0m.js} +0 -0
- /package/dist/{isNotNil-C_SO1tcC.cjs → isNotNil-CrYIUFry.cjs} +0 -0
- /package/dist/{logging-BvMDKgl0.js → logging-BAMMfn5j.js} +0 -0
- /package/dist/{logging-Bh9ikph3.cjs → logging-CbxgIX9V.cjs} +0 -0
- /package/dist/{metadatum-B-sxBnSY.cjs → metadatum-BGvFqGPt.cjs} +0 -0
- /package/dist/{metadatum-Ego4jVas.js → metadatum-BVocMYy_.js} +0 -0
- /package/dist/{repo-slice-BzZQUTj8.cjs → repo-slice-BB_W-6OL.cjs} +0 -0
- /package/dist/{repo-slice-vCcQJotS.js → repo-slice-BQlssw9M.js} +0 -0
- /package/dist/{reselect-BPkMzw3k.js → reselect-JIgawvPe.js} +0 -0
- /package/dist/{serializable-BxFUShKY.js → serializable-F7OtYl8d.js} +0 -0
- /package/dist/{serializable-DWgkHhv_.cjs → serializable-n3UoxbZc.cjs} +0 -0
- /package/dist/{slice-DY-DNtSi.js → slice-5dGBAz6w.js} +0 -0
- /package/dist/{slice-BEFoeqgr.cjs → slice-BzJgg9FS.cjs} +0 -0
- /package/dist/{src-CPmX4KUh.cjs → src-CeBNkonz.cjs} +0 -0
- /package/dist/{src-XOZXPKxe.js → src-Cv1ifqbe.js} +0 -0
- /package/dist/{time-CQPt4FdU.js → time-ByoKevdZ.js} +0 -0
- /package/dist/{time-Blvoyh9G.cjs → time-qD7edGU0.cjs} +0 -0
- /package/dist/{time.vo-Xln4yGBU.js → time.vo-C17-tYq3.js} +0 -0
- /package/dist/{time.vo-rwWwJzmP.cjs → time.vo-TmYE-_Y2.cjs} +0 -0
- /package/dist/{toEmpty-CzmoZVLN.cjs → toEmpty-Db6V94Mf.cjs} +0 -0
- /package/dist/{toEmpty-DzLd-ZCi.js → toEmpty-Djj-QbpI.js} +0 -0
- /package/dist/{token-id.vo-l8fuSpem.cjs → token-id.vo-CZ622zcZ.cjs} +0 -0
- /package/dist/{token-id.vo-DMKSaMlc.js → token-id.vo-IDI9C_Qm.js} +0 -0
- /package/dist/{types-B61DQoFW.js → types-By-XeXWg.js} +0 -0
- /package/dist/{types-CUC-Kcqh.cjs → types-Cn6WlQV6.cjs} +0 -0
- /package/dist/{util-BV3iGOrz.cjs → util-Cp1h58uD.cjs} +0 -0
- /package/dist/{util-BsQKLorV.js → util-DHppXj7U.js} +0 -0
- /package/dist/{util-selector-CKIyoAOz.js → util-selector-BWmHpo92.js} +0 -0
- /package/dist/{util-selector-C9H5RsNw.cjs → util-selector-glXkO-jR.cjs} +0 -0
- /package/dist/{while-active-CNXeLxre.js → while-active-CDBnUlQA.js} +0 -0
- /package/dist/{while-active-BsDWSNrO.cjs → while-active-I2TlHtm7.cjs} +0 -0
|
@@ -0,0 +1,804 @@
|
|
|
1
|
+
const require_chunk = require("./chunk-9hOWP6kD.cjs");
|
|
2
|
+
const require__polyfill_buffer_patch = require("./_polyfill-buffer-patch-BycQkEkK.cjs");
|
|
3
|
+
const require_address = require("./address-lECYBd9-.cjs");
|
|
4
|
+
const require_time_vo = require("./time.vo-TmYE-_Y2.cjs");
|
|
5
|
+
const require_bignum_vo = require("./bignum.vo-Du-bpvar.cjs");
|
|
6
|
+
const require_asyncoption = require("./asyncoption-CYcZNBRM.cjs");
|
|
7
|
+
const require_slice = require("./slice-B9QKuhi0.cjs");
|
|
8
|
+
const require_activity_type = require("./activity-type-BPXxdHBP.cjs");
|
|
9
|
+
const require_while_active = require("./while-active-I2TlHtm7.cjs");
|
|
10
|
+
const require_types = require("./types-Dls6Z5gV.cjs");
|
|
11
|
+
const require_const = require("./const-CSWmOyzn.cjs");
|
|
12
|
+
const require_keyDerivation = require("./keyDerivation-DcKRUCVh.cjs");
|
|
13
|
+
const require_bitcoin_data_provider = require("./bitcoin-data-provider-D0OT_Uiu.cjs");
|
|
14
|
+
let rxjs = require("rxjs");
|
|
15
|
+
let _reduxjs_toolkit = require("@reduxjs/toolkit");
|
|
16
|
+
let lodash_isEqual = require("lodash/isEqual.js");
|
|
17
|
+
lodash_isEqual = require_chunk.__toESM(lodash_isEqual);
|
|
18
|
+
let rxjs_operators = require("rxjs/operators");
|
|
19
|
+
//#region ../../packages/module/blockchain-bitcoin/src/store/slice.ts
|
|
20
|
+
const slice = (0, _reduxjs_toolkit.createSlice)({
|
|
21
|
+
name: "bitcoinContext",
|
|
22
|
+
initialState: { historyFetchErrors: [] },
|
|
23
|
+
reducers: {
|
|
24
|
+
getAddressTransactionHistoryFailed: (state, action) => {
|
|
25
|
+
state.historyFetchErrors.push(action.payload);
|
|
26
|
+
},
|
|
27
|
+
setTip: (state, { payload }) => {
|
|
28
|
+
state.tip = payload;
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
selectors: {
|
|
32
|
+
selectTip: ({ tip }) => tip,
|
|
33
|
+
bitcoinContext: (sliceState) => sliceState
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
const selectBlockchainNetworkId = (0, _reduxjs_toolkit.createSelector)(require_slice.networkSelectors.network.selectNetworkType, require_slice.networkSelectors.network.selectBlockchainNetworks, (networkType, blockchainNetworks) => blockchainNetworks.Bitcoin?.[networkType]);
|
|
37
|
+
const selectNetwork = (0, _reduxjs_toolkit.createSelector)(selectBlockchainNetworkId, (networkId) => networkId ? networkId.includes("mainnet") ? require_types.BitcoinNetwork.Mainnet : require_types.BitcoinNetwork.Testnet : void 0);
|
|
38
|
+
const bitcoinContextReducers = { [slice.name]: slice.reducer };
|
|
39
|
+
/** Direct import of this is an anti-pattern. OK for tests. */
|
|
40
|
+
const bitcoinContextActions = { bitcoinContext: {
|
|
41
|
+
...slice.actions,
|
|
42
|
+
getTipFailed: (0, _reduxjs_toolkit.createAction)("bitcoinContext/getTipFailed"),
|
|
43
|
+
requestResync: (0, _reduxjs_toolkit.createAction)("bitcoin/requestResync")
|
|
44
|
+
} };
|
|
45
|
+
/** Direct import of this is an anti-pattern. OK for tests. */
|
|
46
|
+
const bitcoinContextSelectors = { bitcoinContext: {
|
|
47
|
+
...slice.selectors,
|
|
48
|
+
selectBlockchainNetworkId,
|
|
49
|
+
selectNetwork
|
|
50
|
+
} };
|
|
51
|
+
const BITCOIN_TOKEN_METADATA = {
|
|
52
|
+
name: "Bitcoin",
|
|
53
|
+
ticker: "BTC",
|
|
54
|
+
decimals: 8,
|
|
55
|
+
displayDecimalPlaces: 8,
|
|
56
|
+
image: "data:image/png;base64,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",
|
|
57
|
+
blockchainSpecific: {}
|
|
58
|
+
};
|
|
59
|
+
//#endregion
|
|
60
|
+
//#region ../../packages/module/blockchain-bitcoin/src/tx-builder/utils.ts
|
|
61
|
+
require__polyfill_buffer_patch.init__polyfill_buffer_patch();
|
|
62
|
+
var import_src = /* @__PURE__ */ require_chunk.__toESM(require_address.require_src());
|
|
63
|
+
/**
|
|
64
|
+
* Converts a raw transaction hex into a BitcoinTransactionHistoryEntry using an InputResolver to fetch additional input details.
|
|
65
|
+
*
|
|
66
|
+
* This function deserializes a raw Bitcoin transaction hex and transforms it into a transaction history entry.
|
|
67
|
+
* It uses an InputResolver to asynchronously fetch and include details about each input, such as the associated address
|
|
68
|
+
* and the amount of satoshis, which are not directly available from the transaction input script.
|
|
69
|
+
*
|
|
70
|
+
* @param raw - The raw hexadecimal string of the Bitcoin transaction.
|
|
71
|
+
* @param network - The Bitcoin network (Mainnet or Testnet) that the transaction pertains to.
|
|
72
|
+
* @param inputResolver - An instance of InputResolver to fetch additional input details.
|
|
73
|
+
* @returns A promise that resolves to a detailed transaction history entry.
|
|
74
|
+
*/
|
|
75
|
+
const historyEntryFromRawTx = async (raw, network, inputResolver) => {
|
|
76
|
+
const tx = import_src.Transaction.fromHex(raw);
|
|
77
|
+
const bitcoinNetwork = network === require_types.BitcoinNetwork.Mainnet ? import_src.networks.bitcoin : import_src.networks.testnet;
|
|
78
|
+
return {
|
|
79
|
+
inputs: await Promise.all(tx.ins.map(async (input) => {
|
|
80
|
+
const txId = require__polyfill_buffer_patch.import_buffer.Buffer.from(input.hash).reverse().toString("hex");
|
|
81
|
+
const index = input.index;
|
|
82
|
+
try {
|
|
83
|
+
return {
|
|
84
|
+
...await inputResolver.resolve(txId, index),
|
|
85
|
+
isCoinbase: false
|
|
86
|
+
};
|
|
87
|
+
} catch {
|
|
88
|
+
return {
|
|
89
|
+
txId,
|
|
90
|
+
index,
|
|
91
|
+
address: "",
|
|
92
|
+
satoshis: 0,
|
|
93
|
+
isCoinbase: false
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
})),
|
|
97
|
+
outputs: tx.outs.map((o) => {
|
|
98
|
+
const chunks = import_src.script.decompile(o.script);
|
|
99
|
+
if (chunks && chunks[0] === import_src.opcodes.OP_RETURN) {
|
|
100
|
+
const payloadChunks = chunks.slice(1).filter((c) => require__polyfill_buffer_patch.import_buffer.Buffer.isBuffer(c));
|
|
101
|
+
const opReturnData = require__polyfill_buffer_patch.import_buffer.Buffer.concat(payloadChunks).toString("utf8");
|
|
102
|
+
return {
|
|
103
|
+
address: "",
|
|
104
|
+
satoshis: o.value,
|
|
105
|
+
opReturnData
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
address: import_src.address.fromOutputScript(o.script, bitcoinNetwork),
|
|
110
|
+
satoshis: o.value
|
|
111
|
+
};
|
|
112
|
+
}),
|
|
113
|
+
transactionHash: tx.getId(),
|
|
114
|
+
confirmations: 0,
|
|
115
|
+
status: require_bitcoin_data_provider.BitcoinTransactionStatus.Pending,
|
|
116
|
+
blockHeight: 0,
|
|
117
|
+
timestamp: 0
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
//#endregion
|
|
121
|
+
//#region ../../packages/module/blockchain-bitcoin/src/providers/BlockchainInputResolver.ts
|
|
122
|
+
/**
|
|
123
|
+
* Represents an implementation of the `InputResolver` interface that fetches detailed information
|
|
124
|
+
* about a transaction input from the blockchain data provider.
|
|
125
|
+
*/
|
|
126
|
+
var BlockchainInputResolver = class {
|
|
127
|
+
/**
|
|
128
|
+
* Creates an instance of `BlockchainInputResolver`.
|
|
129
|
+
*
|
|
130
|
+
* @param dataProvider - The provider used to fetch transaction data from the blockchain.
|
|
131
|
+
* @param network - The Bitcoin network the inputs belong to.
|
|
132
|
+
*/
|
|
133
|
+
constructor(dataProvider, network) {
|
|
134
|
+
this.dataProvider = dataProvider;
|
|
135
|
+
this.network = network;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Resolves the transaction input to a `UTxO` object providing detailed information
|
|
139
|
+
* about the input, including the owning address and the amount.
|
|
140
|
+
*
|
|
141
|
+
* @param txId - The hexadecimal string representing the transaction ID of the input to resolve.
|
|
142
|
+
* @param index - The zero-based index of the input within the transaction's list of outputs.
|
|
143
|
+
*
|
|
144
|
+
* @returns A promise that resolves to a `BitcoinUTxO` object containing the resolved input details.
|
|
145
|
+
* If the input cannot be resolved, the promise should reject with an error explaining the failure.
|
|
146
|
+
*/
|
|
147
|
+
async resolve(txId, index) {
|
|
148
|
+
const transaction = (await (0, rxjs.firstValueFrom)(this.dataProvider.getTransaction({ network: this.network }, txId))).unwrapOr(null);
|
|
149
|
+
if (!transaction || index >= transaction.outputs.length) throw new Error("Transaction or output index not found");
|
|
150
|
+
const output = transaction.outputs[index];
|
|
151
|
+
return {
|
|
152
|
+
txId,
|
|
153
|
+
index,
|
|
154
|
+
address: output.address,
|
|
155
|
+
satoshis: output.satoshis,
|
|
156
|
+
script: "",
|
|
157
|
+
confirmations: transaction.confirmations,
|
|
158
|
+
height: transaction.blockHeight,
|
|
159
|
+
runes: [],
|
|
160
|
+
inscriptions: []
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
//#endregion
|
|
165
|
+
//#region ../../packages/module/blockchain-bitcoin/src/wallet/BitcoinWallet.ts
|
|
166
|
+
require__polyfill_buffer_patch.init__polyfill_buffer_patch();
|
|
167
|
+
var import_dist = /* @__PURE__ */ require_chunk.__toESM(require_address.require_dist());
|
|
168
|
+
import_src.initEccLib(import_dist);
|
|
169
|
+
/** Where an account wallet is in syncing its state with the provider. */
|
|
170
|
+
let SyncStatus = /* @__PURE__ */ function(SyncStatus) {
|
|
171
|
+
SyncStatus["Pending"] = "pending";
|
|
172
|
+
SyncStatus["Syncing"] = "syncing";
|
|
173
|
+
SyncStatus["Synced"] = "synced";
|
|
174
|
+
SyncStatus["Error"] = "error";
|
|
175
|
+
return SyncStatus;
|
|
176
|
+
}({});
|
|
177
|
+
var BitcoinWallet = class {
|
|
178
|
+
syncStatus$ = new rxjs.BehaviorSubject({
|
|
179
|
+
status: SyncStatus.Syncing,
|
|
180
|
+
lastUpdate: Date.now()
|
|
181
|
+
});
|
|
182
|
+
transactionHistory$ = new rxjs.BehaviorSubject(new Array());
|
|
183
|
+
pendingTransactions$ = new rxjs.BehaviorSubject(new Array());
|
|
184
|
+
utxos$ = new rxjs.BehaviorSubject(new Array());
|
|
185
|
+
balance$ = new rxjs.BehaviorSubject(0);
|
|
186
|
+
addresses$ = new rxjs.BehaviorSubject(new Array());
|
|
187
|
+
isLoadingHistory$ = new rxjs.BehaviorSubject(false);
|
|
188
|
+
network;
|
|
189
|
+
address;
|
|
190
|
+
masterFingerprint;
|
|
191
|
+
nextCursor$ = new rxjs.BehaviorSubject(void 0);
|
|
192
|
+
pollSubscription = null;
|
|
193
|
+
lastKnownBlock = null;
|
|
194
|
+
historyDepth;
|
|
195
|
+
provider;
|
|
196
|
+
info;
|
|
197
|
+
pollController$;
|
|
198
|
+
requestResync$;
|
|
199
|
+
logger;
|
|
200
|
+
inputResolver;
|
|
201
|
+
feeMarketProvider;
|
|
202
|
+
constructor(provider, feeMarketProvider, historyDepth = 20, info, pollController$, requestResync$, logger) {
|
|
203
|
+
const bitcoinNetwork = info.network === require_types.BitcoinNetwork.Mainnet ? import_src.networks.bitcoin : import_src.networks.testnet;
|
|
204
|
+
this.pollController$ = pollController$;
|
|
205
|
+
this.requestResync$ = requestResync$;
|
|
206
|
+
this.logger = logger;
|
|
207
|
+
this.network = info.network;
|
|
208
|
+
this.historyDepth = historyDepth;
|
|
209
|
+
this.provider = provider;
|
|
210
|
+
this.info = info;
|
|
211
|
+
this.masterFingerprint = info.masterFingerprint;
|
|
212
|
+
this.inputResolver = new BlockchainInputResolver(provider, this.network);
|
|
213
|
+
this.feeMarketProvider = feeMarketProvider;
|
|
214
|
+
const extendedAccountPubKey = info.extendedAccountPublicKeys.nativeSegWit;
|
|
215
|
+
const pubKey = require_keyDerivation.deriveChildPublicKey(extendedAccountPubKey, require_keyDerivation.ChainType.External, 0);
|
|
216
|
+
this.address = {
|
|
217
|
+
address: require_address.deriveAddressByType(pubKey, require_address.AddressType.NativeSegWit, bitcoinNetwork),
|
|
218
|
+
addressType: require_address.AddressType.NativeSegWit,
|
|
219
|
+
network: info.network,
|
|
220
|
+
account: this.info.accountIndex,
|
|
221
|
+
chain: require_keyDerivation.ChainType.External,
|
|
222
|
+
index: 0,
|
|
223
|
+
publicKeyHex: require__polyfill_buffer_patch.import_buffer.Buffer.from(pubKey).toString("hex")
|
|
224
|
+
};
|
|
225
|
+
this.addresses$.next([this.address]);
|
|
226
|
+
this.startPolling();
|
|
227
|
+
this.utxos$.pipe((0, rxjs_operators.map)((utxos) => utxos.reduce((total, utxo) => total + utxo.satoshis, 0))).subscribe((balance) => {
|
|
228
|
+
this.balance$.next(balance);
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
getInfo() {
|
|
232
|
+
return (0, rxjs.of)(require_asyncoption.Ok(this.info));
|
|
233
|
+
}
|
|
234
|
+
getNetwork() {
|
|
235
|
+
return (0, rxjs.of)(require_asyncoption.Ok(this.network));
|
|
236
|
+
}
|
|
237
|
+
getAddress() {
|
|
238
|
+
return (0, rxjs.of)(require_asyncoption.Ok(this.address));
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Fetches the raw serialized transaction (hex) for a given transaction id.
|
|
242
|
+
*
|
|
243
|
+
* @param txId - 32-byte transaction ID in hexadecimal form.
|
|
244
|
+
*/
|
|
245
|
+
getRawTransaction(txId) {
|
|
246
|
+
return this.provider.getRawTransaction({ network: this.network }, txId);
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Fetches the current fee market for estimating transaction fees.
|
|
250
|
+
*/
|
|
251
|
+
getCurrentFeeMarket() {
|
|
252
|
+
return this.feeMarketProvider.getFeeMarket({ network: this.network });
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Fetches transaction history pages recursively until the total number of
|
|
256
|
+
* transactions reaches the `desiredAmount` or the end of history is found.
|
|
257
|
+
*
|
|
258
|
+
* @param desiredAmount - The target number of transactions to have loaded.
|
|
259
|
+
* @returns An observable that emits an `Ok<boolean>` on success or an `Err<ProviderError>` on failure.
|
|
260
|
+
* The boolean is `true` if the end of history was reached.
|
|
261
|
+
*/
|
|
262
|
+
fetchTxHistoryUpTo(desiredAmount) {
|
|
263
|
+
if (this.isLoadingHistory$.value) {
|
|
264
|
+
this.logger.debug("History loading already in progress. Skipping request.");
|
|
265
|
+
return (0, rxjs.of)(require_asyncoption.Ok(false));
|
|
266
|
+
}
|
|
267
|
+
this.isLoadingHistory$.next(true);
|
|
268
|
+
return (0, rxjs.of)(this.nextCursor$.value).pipe((0, rxjs.expand)((cursor) => {
|
|
269
|
+
if (this.transactionHistory$.value.length >= desiredAmount || cursor === null) return rxjs.EMPTY;
|
|
270
|
+
return this.provider.getTransactions({ network: this.network }, this.address.address, {
|
|
271
|
+
cursor,
|
|
272
|
+
limit: this.historyDepth,
|
|
273
|
+
order: "desc"
|
|
274
|
+
}).pipe((0, rxjs_operators.map)((result) => {
|
|
275
|
+
if (result.isErr()) {
|
|
276
|
+
this.logger.error("Failed to get older transactions:", result.error);
|
|
277
|
+
throw result.error;
|
|
278
|
+
}
|
|
279
|
+
const { items: olderHistory, cursor: nextCursor } = result.value;
|
|
280
|
+
const uniqueHistory = Array.from(new Map([...this.transactionHistory$.value, ...olderHistory].map((tx) => [tx.transactionHash, tx])).values());
|
|
281
|
+
this.transactionHistory$.next(uniqueHistory);
|
|
282
|
+
this.nextCursor$.next(nextCursor || null);
|
|
283
|
+
return nextCursor || null;
|
|
284
|
+
}));
|
|
285
|
+
}), (0, rxjs.defaultIfEmpty)(this.nextCursor$.value), (0, rxjs.last)(), (0, rxjs_operators.map)((lastCursor) => lastCursor === null), (0, rxjs_operators.map)((hasReachedEnd) => require_asyncoption.Ok(hasReachedEnd)), (0, rxjs_operators.catchError)((error) => {
|
|
286
|
+
this.logger.error("A critical error occurred during history fetch:", error);
|
|
287
|
+
return (0, rxjs.of)(require_asyncoption.Err(error));
|
|
288
|
+
}), (0, rxjs.finalize)(() => {
|
|
289
|
+
this.isLoadingHistory$.next(false);
|
|
290
|
+
}));
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Submits a raw transaction to the blockchain for inclusion in a block.
|
|
294
|
+
*
|
|
295
|
+
* On success the transaction is eagerly appended to pendingTransactions$.
|
|
296
|
+
* A failure to derive that pending entry (e.g. an output with no address
|
|
297
|
+
* form) is logged but never fails the submission: the transaction is
|
|
298
|
+
* already on the network, so the txId must still be returned.
|
|
299
|
+
*
|
|
300
|
+
* @param rawTransaction - The raw transaction data to be broadcast to the network.
|
|
301
|
+
*/
|
|
302
|
+
submitTransaction(rawTransaction) {
|
|
303
|
+
return this.provider.submitTransaction({ network: this.network }, rawTransaction).pipe((0, rxjs.mergeMap)((submitResult) => {
|
|
304
|
+
if (submitResult.isErr()) return (0, rxjs.of)(submitResult);
|
|
305
|
+
const transactionId = submitResult.value;
|
|
306
|
+
return (0, rxjs.from)(historyEntryFromRawTx(rawTransaction, this.network, this.inputResolver)).pipe((0, rxjs.tap)((entry) => {
|
|
307
|
+
entry.transactionHash = transactionId;
|
|
308
|
+
if (!this.pendingTransactions$.value.some((tx) => tx.transactionHash === entry.transactionHash)) this.pendingTransactions$.next([...this.pendingTransactions$.value, entry]);
|
|
309
|
+
}), (0, rxjs_operators.map)(() => submitResult), (0, rxjs_operators.catchError)((error) => {
|
|
310
|
+
this.logger.error("Failed to derive pending entry for submitted transaction:", error);
|
|
311
|
+
return (0, rxjs.of)(submitResult);
|
|
312
|
+
}));
|
|
313
|
+
}), (0, rxjs_operators.catchError)((error) => {
|
|
314
|
+
this.logger.error("Failed to submit transaction:", error);
|
|
315
|
+
return (0, rxjs.of)(require_asyncoption.Err(error));
|
|
316
|
+
}));
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Stop polling by unsubscribing from the subscription
|
|
320
|
+
*/
|
|
321
|
+
shutdown() {
|
|
322
|
+
if (this.pollSubscription) {
|
|
323
|
+
this.pollSubscription.unsubscribe();
|
|
324
|
+
this.pollSubscription = null;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Starts reacting to tip changes and updating wallet state.
|
|
329
|
+
* The polling controller is responsible for *when* we trigger,
|
|
330
|
+
* this method just reacts to those triggers.
|
|
331
|
+
*/
|
|
332
|
+
startPolling() {
|
|
333
|
+
this.pollSubscription = (0, rxjs.merge)(this.pollController$.pipe((0, rxjs_operators.map)((tip) => ({
|
|
334
|
+
type: "tip",
|
|
335
|
+
tip
|
|
336
|
+
}))), this.requestResync$.pipe((0, rxjs.withLatestFrom)(this.pollController$), (0, rxjs_operators.map)(([, tip]) => ({
|
|
337
|
+
type: "manual",
|
|
338
|
+
tip
|
|
339
|
+
})))).pipe((0, rxjs.tap)((event) => {
|
|
340
|
+
this.updateSyncStatus(SyncStatus.Pending);
|
|
341
|
+
this.logger.debug(event.type === "tip" ? `Poll triggered by tip ${event.tip.hash} at height ${event.tip.height}` : `Manual resync triggered at tip ${event.tip.hash} (height ${event.tip.height})`);
|
|
342
|
+
}), (0, rxjs_operators.switchMap)((event) => {
|
|
343
|
+
const latestBlockInfo = event.tip;
|
|
344
|
+
let task$;
|
|
345
|
+
if (event.type === "tip") task$ = !this.lastKnownBlock || this.lastKnownBlock.hash !== latestBlockInfo.hash ? this.updateState(latestBlockInfo) : this.updatePendingTransactions();
|
|
346
|
+
else task$ = this.updateState(latestBlockInfo);
|
|
347
|
+
this.updateSyncStatus(SyncStatus.Syncing);
|
|
348
|
+
return task$.pipe((0, rxjs.tap)(() => {
|
|
349
|
+
this.updateSyncStatus(SyncStatus.Synced);
|
|
350
|
+
}), (0, rxjs_operators.catchError)((error) => {
|
|
351
|
+
this.logger.error("Failed to update wallet state:", error);
|
|
352
|
+
this.updateSyncStatus(SyncStatus.Error, error);
|
|
353
|
+
return rxjs.EMPTY;
|
|
354
|
+
}));
|
|
355
|
+
})).subscribe();
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Fetches the latest transactions and updates the transactionHistory$ subject if they have changed.
|
|
359
|
+
*/
|
|
360
|
+
updateTransactions() {
|
|
361
|
+
return this.provider.getTransactions({ network: this.network }, this.address.address, {
|
|
362
|
+
limit: this.historyDepth,
|
|
363
|
+
order: "desc"
|
|
364
|
+
}).pipe((0, rxjs_operators.map)((result) => {
|
|
365
|
+
if (result.isErr()) {
|
|
366
|
+
this.logger.error("Failed to get transactions:", result.error);
|
|
367
|
+
throw result.error;
|
|
368
|
+
}
|
|
369
|
+
const { items: newHistory, cursor: nextCursor } = result.value;
|
|
370
|
+
const currentHistory = this.transactionHistory$.value;
|
|
371
|
+
const combinedHistory = [...currentHistory, ...newHistory];
|
|
372
|
+
const uniqueHistory = Array.from(new Map(combinedHistory.map((tx) => [tx.transactionHash, tx])).values());
|
|
373
|
+
uniqueHistory.sort((a, b) => b.timestamp - a.timestamp);
|
|
374
|
+
const hasSetChanged = !(0, lodash_isEqual.default)(uniqueHistory, currentHistory);
|
|
375
|
+
if (hasSetChanged) this.transactionHistory$.next(uniqueHistory);
|
|
376
|
+
if (this.nextCursor$.value === void 0) this.nextCursor$.next(nextCursor || null);
|
|
377
|
+
return hasSetChanged;
|
|
378
|
+
}));
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Updates the local list of pending transactions by synchronizing with the remote mempool.
|
|
382
|
+
*
|
|
383
|
+
* Transactions in the Bitcoin network can be replaced in the mempool by another transaction
|
|
384
|
+
* with the same inputs but possibly with a higher fee (Replace-By-Fee, RBF).
|
|
385
|
+
*
|
|
386
|
+
* The method performs the following operations:
|
|
387
|
+
*
|
|
388
|
+
* 1. **Fetch Remote Pending Transactions**: Retrieves the list of pending transactions from the mempool
|
|
389
|
+
* for the wallet's address. This includes transactions that are waiting to be confirmed.
|
|
390
|
+
*
|
|
391
|
+
* 2. **Synchronize Local and Remote Transactions**:
|
|
392
|
+
* - For each remote pending transaction:
|
|
393
|
+
* - If it matches a transaction in the local list (by transaction hash), it updates the local transaction
|
|
394
|
+
* with the remote version, since it contains more metadata (I.E resolved inputs).
|
|
395
|
+
*
|
|
396
|
+
* 3. **Purge Invalid Local Transactions**:
|
|
397
|
+
* - Iterates over the local list of pending transactions to check each transaction's inputs against:
|
|
398
|
+
* a. Inputs of **confirmed** transactions in the history (`confirmations > 0`) to detect inputs settled in a
|
|
399
|
+
* block. Unconfirmed history entries are ignored — a transaction stays pending until it is mined.
|
|
400
|
+
* b. Inputs of other remote pending transactions to handle RBF scenarios where a transaction might be replaced
|
|
401
|
+
* by another with the same inputs but not the same hash.
|
|
402
|
+
* - Removes any local transactions whose inputs are found in the confirmed transactions or in another competing pending transaction.
|
|
403
|
+
*/
|
|
404
|
+
updatePendingTransactions() {
|
|
405
|
+
return this.provider.getTransactionsInMempool({ network: this.network }, this.address.address, { order: "desc" }).pipe((0, rxjs.withLatestFrom)(this.pendingTransactions$), (0, rxjs.tap)(([mempoolResult, localPendingTxs]) => {
|
|
406
|
+
if (mempoolResult.isErr()) {
|
|
407
|
+
this.logger.error("Failed to get mempool transactions:", mempoolResult.error);
|
|
408
|
+
throw mempoolResult.error;
|
|
409
|
+
}
|
|
410
|
+
const { items: remotePendingTxs } = mempoolResult.value;
|
|
411
|
+
const confirmedHistory = this.transactionHistory$.value.filter((tx) => tx.confirmations > 0);
|
|
412
|
+
const validLocalTxs = localPendingTxs.filter((localTx) => {
|
|
413
|
+
return !localTx.inputs.some((input) => this.isInputSpent(input, confirmedHistory) || this.isInputSpent(input, remotePendingTxs.filter((remoteTx) => remoteTx.transactionHash !== localTx.transactionHash)));
|
|
414
|
+
});
|
|
415
|
+
const finalTxsMap = new Map(validLocalTxs.map((tx) => [tx.transactionHash, tx]));
|
|
416
|
+
remotePendingTxs.forEach((remoteTx) => {
|
|
417
|
+
finalTxsMap.set(remoteTx.transactionHash, remoteTx);
|
|
418
|
+
});
|
|
419
|
+
let newPendingTxs = Array.from(finalTxsMap.values());
|
|
420
|
+
const confirmedHashes = new Set(confirmedHistory.map((tx) => tx.transactionHash));
|
|
421
|
+
newPendingTxs = newPendingTxs.filter((tx) => !confirmedHashes.has(tx.transactionHash));
|
|
422
|
+
if (!(0, lodash_isEqual.default)(newPendingTxs, this.pendingTransactions$.value)) this.pendingTransactions$.next(newPendingTxs);
|
|
423
|
+
}), (0, rxjs_operators.map)(() => void 0));
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Helper method to check if a specific transaction input has been used
|
|
427
|
+
* in a given list of transactions.
|
|
428
|
+
*/
|
|
429
|
+
isInputSpent(inputToFind, transactionList) {
|
|
430
|
+
return transactionList.some((tx) => tx.inputs.some((input) => input.txId === inputToFind.txId && input.index === inputToFind.index));
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Fetches the latest UTxOs and updates the utxos$ subject if they have changed.
|
|
434
|
+
* Returns a cold observable that completes when the operation is done.
|
|
435
|
+
*/
|
|
436
|
+
updateUtxos() {
|
|
437
|
+
return this.provider.getUTxOs({ network: this.network }, this.address.address, {}).pipe((0, rxjs.withLatestFrom)(this.utxos$), (0, rxjs.tap)(([utxoResult, currentUtxos]) => {
|
|
438
|
+
if (utxoResult.isErr()) {
|
|
439
|
+
this.logger.error("Failed to get UTxOs:", utxoResult.error);
|
|
440
|
+
throw utxoResult.error;
|
|
441
|
+
}
|
|
442
|
+
const { items } = utxoResult.value;
|
|
443
|
+
if (!(0, lodash_isEqual.default)(items, currentUtxos)) this.utxos$.next(items);
|
|
444
|
+
}), (0, rxjs_operators.map)(() => void 0));
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Updates the entire wallet state.
|
|
448
|
+
* It chains the various update operations in the correct order.
|
|
449
|
+
*/
|
|
450
|
+
updateState(latestBlockInfo) {
|
|
451
|
+
return this.updateTransactions().pipe((0, rxjs.mergeMap)((hasTxSetChanged) => {
|
|
452
|
+
const tasksToRun = [this.updatePendingTransactions()];
|
|
453
|
+
if (hasTxSetChanged) tasksToRun.push(this.updateUtxos());
|
|
454
|
+
return (0, rxjs.forkJoin)(tasksToRun);
|
|
455
|
+
}), (0, rxjs.tap)(() => {
|
|
456
|
+
this.lastKnownBlock = latestBlockInfo;
|
|
457
|
+
}), (0, rxjs_operators.map)(() => void 0));
|
|
458
|
+
}
|
|
459
|
+
updateSyncStatus(status, lastError) {
|
|
460
|
+
this.syncStatus$.next({
|
|
461
|
+
status,
|
|
462
|
+
lastUpdate: Date.now(),
|
|
463
|
+
lastError
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
//#endregion
|
|
468
|
+
//#region ../../packages/module/blockchain-bitcoin/src/wallet/account-wallets.ts
|
|
469
|
+
/**
|
|
470
|
+
* A BehaviorSubject that holds a record of Bitcoin wallets associated with account IDs.
|
|
471
|
+
* The keys are AccountId strings, and the values are BitcoinWallet instances.
|
|
472
|
+
* It is a single module-level subject, so every wallet loaded in the same
|
|
473
|
+
* JavaScript realm registers its accounts here.
|
|
474
|
+
*/
|
|
475
|
+
const bitcoinAccountWallets$ = new rxjs.BehaviorSubject({});
|
|
476
|
+
//#endregion
|
|
477
|
+
//#region ../../packages/module/blockchain-bitcoin/src/store/helpers/compute-token-balances.ts
|
|
478
|
+
const outpointKey = (ref) => `${ref.txId}#${ref.index}`;
|
|
479
|
+
/**
|
|
480
|
+
* Derives the confirmed (`available`) and unconfirmed (`pending`) BTC balances
|
|
481
|
+
* for an account from its confirmed UTxO set and the transactions currently in
|
|
482
|
+
* the mempool.
|
|
483
|
+
*
|
|
484
|
+
* - `available`: confirmed UTxOs **minus** any consumed by an unconfirmed
|
|
485
|
+
* transaction. Those are in-flight spent and no longer spendable, even though
|
|
486
|
+
* the provider still reports them as confirmed UTxOs until the next block.
|
|
487
|
+
* - `pending`: value of unconfirmed outputs paying our own addresses — an
|
|
488
|
+
* incoming receive, or our own change from an outgoing send. These are
|
|
489
|
+
* recognised by the wallet but not yet finalised by the network.
|
|
490
|
+
*
|
|
491
|
+
* Deriving both from the same pending set avoids double-counting: on an
|
|
492
|
+
* outgoing send the spent UTxO leaves `available` while its change appears in
|
|
493
|
+
* `pending`, so `available + pending` reflects the true post-send balance.
|
|
494
|
+
*
|
|
495
|
+
* Outputs that are themselves spent by another mempool transaction (chained
|
|
496
|
+
* mempool spends) are excluded from `pending` so they are not counted twice.
|
|
497
|
+
*/
|
|
498
|
+
const computeBitcoinTokenBalances = ({ confirmedUtxos, pendingTransactions, ownAddresses }) => {
|
|
499
|
+
const spentOutpoints = /* @__PURE__ */ new Set();
|
|
500
|
+
for (const tx of pendingTransactions) for (const input of tx.inputs) spentOutpoints.add(outpointKey(input));
|
|
501
|
+
let available = 0n;
|
|
502
|
+
for (const utxo of confirmedUtxos) if (!spentOutpoints.has(outpointKey(utxo))) available += BigInt(utxo.satoshis);
|
|
503
|
+
let pending = 0n;
|
|
504
|
+
for (const tx of pendingTransactions) for (const [index, output] of tx.outputs.entries()) {
|
|
505
|
+
const isOwn = ownAddresses.has(output.address);
|
|
506
|
+
const isSpentByAnotherPendingTx = spentOutpoints.has(outpointKey({
|
|
507
|
+
txId: tx.transactionHash,
|
|
508
|
+
index
|
|
509
|
+
}));
|
|
510
|
+
if (isOwn && !isSpentByAnotherPendingTx) pending += BigInt(output.satoshis);
|
|
511
|
+
}
|
|
512
|
+
return {
|
|
513
|
+
available,
|
|
514
|
+
pending
|
|
515
|
+
};
|
|
516
|
+
};
|
|
517
|
+
//#endregion
|
|
518
|
+
//#region ../../packages/module/blockchain-bitcoin/src/store/side-effects.ts
|
|
519
|
+
const mapNetworkTypeToBitcoinNetwork = (networkType) => {
|
|
520
|
+
switch (networkType) {
|
|
521
|
+
case "mainnet": return require_types.BitcoinNetwork.Mainnet;
|
|
522
|
+
case "testnet": return require_types.BitcoinNetwork.Testnet;
|
|
523
|
+
default: {
|
|
524
|
+
const _exhaustive = networkType;
|
|
525
|
+
throw new Error(`Unhandled network type: ${String(_exhaustive)}`);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
const deriveBitcoinTestnetOptions = (config) => {
|
|
530
|
+
const maestroConfig = config.bitcoinProvider.maestroConfig;
|
|
531
|
+
if (!Object.keys(maestroConfig ?? {}).includes(require_types.BitcoinNetwork.Testnet)) return [];
|
|
532
|
+
return [{
|
|
533
|
+
id: require_address.BitcoinNetworkId("testnet4"),
|
|
534
|
+
label: "bitcoin.network-config.network-option.testnet4"
|
|
535
|
+
}];
|
|
536
|
+
};
|
|
537
|
+
const registerBitcoinTestnetOptions = (testnetOptions) => (_, { network: { selectTestnetOptions$ } }, { actions }) => selectTestnetOptions$.pipe((0, rxjs.filter)((options) => !options?.Bitcoin), (0, rxjs.map)(() => actions.network.setTestnetOptions({
|
|
538
|
+
blockchainName: "Bitcoin",
|
|
539
|
+
options: testnetOptions
|
|
540
|
+
})));
|
|
541
|
+
const registerBitcoinBlockchainNetworks = (_, { network: { selectBlockchainNetworks$ } }, { actions }) => selectBlockchainNetworks$.pipe((0, rxjs.filter)((blockchainNetworks) => !blockchainNetworks?.Bitcoin), (0, rxjs.map)(() => actions.network.setBlockchainNetworks({
|
|
542
|
+
blockchain: "Bitcoin",
|
|
543
|
+
mainnet: require_address.BitcoinNetworkId("mainnet"),
|
|
544
|
+
testnet: require_address.BitcoinNetworkId("testnet4")
|
|
545
|
+
})));
|
|
546
|
+
const mapBitcoinTxToActivity = (rawTx, userAddresses, accountId) => {
|
|
547
|
+
let totalInputFromUser = 0;
|
|
548
|
+
let totalOutputToUser = 0;
|
|
549
|
+
let hasForeignOutput = false;
|
|
550
|
+
let hasOwnInputs = false;
|
|
551
|
+
for (const input of rawTx.inputs) if (userAddresses.has(input.address)) {
|
|
552
|
+
totalInputFromUser += input.satoshis;
|
|
553
|
+
hasOwnInputs = true;
|
|
554
|
+
}
|
|
555
|
+
for (const output of rawTx.outputs) if (userAddresses.has(output.address)) totalOutputToUser += output.satoshis;
|
|
556
|
+
else hasForeignOutput = true;
|
|
557
|
+
const netAmount = BigInt(totalOutputToUser - totalInputFromUser);
|
|
558
|
+
let activityType;
|
|
559
|
+
if (hasOwnInputs && !hasForeignOutput) activityType = require_activity_type.ActivityType.Self;
|
|
560
|
+
else if (netAmount > 0n) activityType = require_activity_type.ActivityType.Receive;
|
|
561
|
+
else activityType = require_activity_type.ActivityType.Send;
|
|
562
|
+
if (rawTx.confirmations <= 0) activityType = require_activity_type.ActivityType.Pending;
|
|
563
|
+
return {
|
|
564
|
+
accountId,
|
|
565
|
+
activityId: rawTx.transactionHash,
|
|
566
|
+
type: activityType,
|
|
567
|
+
tokenBalanceChanges: [{
|
|
568
|
+
tokenId: require_const.BITCOIN_TOKEN_ID,
|
|
569
|
+
amount: require_bignum_vo.BigNumber(netAmount)
|
|
570
|
+
}],
|
|
571
|
+
timestamp: require_time_vo.Timestamp(rawTx.timestamp > 0 ? rawTx.timestamp * 1e3 : Date.now()),
|
|
572
|
+
...activityType === require_activity_type.ActivityType.Pending ? { blockchainSpecific: { Bitcoin: {
|
|
573
|
+
consumedInputs: rawTx.inputs.map((input) => ({
|
|
574
|
+
txId: input.txId,
|
|
575
|
+
index: input.index
|
|
576
|
+
})),
|
|
577
|
+
producedOutputs: []
|
|
578
|
+
} } } : {}
|
|
579
|
+
};
|
|
580
|
+
};
|
|
581
|
+
const trackTip = (tipPollFrequency) => (_, { bitcoinContext: { selectNetwork$ }, wallets: { selectActiveNetworkAccounts$ } }, { actions, bitcoinProvider: { getLastKnownBlock }, isWalletActive$ }) => (0, rxjs.combineLatest)([selectNetwork$.pipe((0, rxjs.distinctUntilChanged)()), selectActiveNetworkAccounts$.pipe((0, rxjs.map)((accounts) => accounts.some((account) => account.blockchainName === "Bitcoin")), (0, rxjs.distinctUntilChanged)())]).pipe((0, rxjs.switchMap)(([network, hasBitcoinAccounts]) => {
|
|
582
|
+
if (!network) return (0, rxjs.of)(actions.bitcoinContext.setTip(void 0));
|
|
583
|
+
if (!hasBitcoinAccounts) return rxjs.EMPTY;
|
|
584
|
+
return (0, rxjs.merge)((0, rxjs.of)(void 0), (0, rxjs.interval)(tipPollFrequency)).pipe((0, rxjs.exhaustMap)(() => getLastKnownBlock({ network })), (0, rxjs.mergeMap)((result) => {
|
|
585
|
+
if (result.isErr()) return (0, rxjs.of)(actions.bitcoinContext.getTipFailed({
|
|
586
|
+
failure: result.error.reason,
|
|
587
|
+
network
|
|
588
|
+
}));
|
|
589
|
+
return (0, rxjs.of)(actions.bitcoinContext.setTip(result.value));
|
|
590
|
+
}));
|
|
591
|
+
}), require_while_active.whileActive(isWalletActive$));
|
|
592
|
+
/**
|
|
593
|
+
* Factory function to create and configure a new BitcoinWallet instance.
|
|
594
|
+
*
|
|
595
|
+
* @param historyDepth - The depth of transaction history to maintain.
|
|
596
|
+
* @param requestResync$ - Observable that triggers wallet resynchronization.
|
|
597
|
+
* @param selectNetwork$ - Observable providing the current Bitcoin network (undefined when not yet registered).
|
|
598
|
+
* @param selectTip$ - Observable providing the current blockchain tip.
|
|
599
|
+
* @param bitcoinAccountWallets$ - Observable holding the mapping of account IDs to BitcoinWallet instances.
|
|
600
|
+
* @param provider - The Bitcoin data provider.
|
|
601
|
+
* @param feeMarketProvider - The provider for fee market estimations.
|
|
602
|
+
* @param account - The in-memory wallet account data.
|
|
603
|
+
* @param logger - The logger for wallet errors.
|
|
604
|
+
* @returns An object containing observables for the wallet's tokens and addresses.
|
|
605
|
+
*/
|
|
606
|
+
const createBitcoinWallet = ({ historyDepth, requestResync$, selectNetwork$, selectTip$, bitcoinAccountWallets$, provider, feeMarketProvider, account, logger }) => {
|
|
607
|
+
const walletInfo = {
|
|
608
|
+
accountIndex: account.blockchainSpecific.accountIndex,
|
|
609
|
+
extendedAccountPublicKeys: account.blockchainSpecific.extendedAccountPublicKeys,
|
|
610
|
+
masterFingerprint: account.blockchainSpecific.masterFingerprint,
|
|
611
|
+
network: mapNetworkTypeToBitcoinNetwork(account.networkType),
|
|
612
|
+
walletId: account.walletId
|
|
613
|
+
};
|
|
614
|
+
const resyncController$ = requestResync$.pipe((0, rxjs.filter)(({ payload: { accountId } }) => accountId === account.accountId));
|
|
615
|
+
const wallet = new BitcoinWallet(provider, feeMarketProvider, historyDepth, walletInfo, (0, rxjs.combineLatest)([selectTip$, selectNetwork$]).pipe((0, rxjs.filter)(([tip, currentNetwork]) => !!tip && currentNetwork === walletInfo.network), (0, rxjs.map)(([tip]) => tip)), resyncController$, logger);
|
|
616
|
+
const currentWallets = bitcoinAccountWallets$.value;
|
|
617
|
+
bitcoinAccountWallets$.next({
|
|
618
|
+
...currentWallets,
|
|
619
|
+
[account.accountId]: wallet
|
|
620
|
+
});
|
|
621
|
+
return {
|
|
622
|
+
addresses$: wallet.addresses$.pipe((0, rxjs.map)((derivedAddresses) => derivedAddresses.map((derivedAddr) => ({
|
|
623
|
+
address: derivedAddr.address,
|
|
624
|
+
accountId: account.accountId,
|
|
625
|
+
data: {
|
|
626
|
+
network: derivedAddr.network,
|
|
627
|
+
addressType: derivedAddr.addressType,
|
|
628
|
+
account: derivedAddr.account,
|
|
629
|
+
chain: derivedAddr.chain,
|
|
630
|
+
index: derivedAddr.index,
|
|
631
|
+
publicKeyHex: derivedAddr.publicKeyHex
|
|
632
|
+
}
|
|
633
|
+
})))),
|
|
634
|
+
tokens$: (0, rxjs.combineLatest)([
|
|
635
|
+
wallet.addresses$,
|
|
636
|
+
wallet.utxos$,
|
|
637
|
+
wallet.pendingTransactions$
|
|
638
|
+
]).pipe((0, rxjs.map)(([addresses, utxos, pendingTransactions]) => {
|
|
639
|
+
const primaryAddress = addresses[0]?.address || "";
|
|
640
|
+
const { available, pending } = computeBitcoinTokenBalances({
|
|
641
|
+
confirmedUtxos: utxos,
|
|
642
|
+
pendingTransactions,
|
|
643
|
+
ownAddresses: new Set(addresses.map((a) => a.address))
|
|
644
|
+
});
|
|
645
|
+
const btcToken = {
|
|
646
|
+
metadata: BITCOIN_TOKEN_METADATA,
|
|
647
|
+
accountId: account.accountId,
|
|
648
|
+
address: require_types.BitcoinAddress(primaryAddress),
|
|
649
|
+
tokenId: require_const.BITCOIN_TOKEN_ID,
|
|
650
|
+
available: require_bignum_vo.BigNumber(available),
|
|
651
|
+
pending: require_bignum_vo.BigNumber(pending),
|
|
652
|
+
decimals: 8,
|
|
653
|
+
displayDecimalPlaces: 8,
|
|
654
|
+
displayLongName: "Bitcoin",
|
|
655
|
+
displayShortName: "BTC",
|
|
656
|
+
blockchainName: "Bitcoin"
|
|
657
|
+
};
|
|
658
|
+
return {
|
|
659
|
+
address: require_types.BitcoinAddress(primaryAddress),
|
|
660
|
+
tokens: [btcToken]
|
|
661
|
+
};
|
|
662
|
+
})),
|
|
663
|
+
syncStatus$: wallet.syncStatus$,
|
|
664
|
+
activities$: (0, rxjs.combineLatest)([
|
|
665
|
+
wallet.transactionHistory$,
|
|
666
|
+
wallet.pendingTransactions$,
|
|
667
|
+
wallet.addresses$
|
|
668
|
+
]).pipe((0, rxjs.map)(([rawTxs, pendingTxs, derivedAddresses]) => {
|
|
669
|
+
const userAddresses = new Set(derivedAddresses.map((a) => a.address));
|
|
670
|
+
return [...pendingTxs, ...rawTxs].map((rawTx) => mapBitcoinTxToActivity(rawTx, userAddresses, account.accountId));
|
|
671
|
+
})),
|
|
672
|
+
fetchTxHistoryUpTo: (desiredCount) => {
|
|
673
|
+
return wallet.fetchTxHistoryUpTo(desiredCount);
|
|
674
|
+
}
|
|
675
|
+
};
|
|
676
|
+
};
|
|
677
|
+
const startBitcoinWallet = (historyDepth) => ({ bitcoinContext: { requestResync$, getTipFailed$ } }, { bitcoinContext: { selectTip$, selectNetwork$ }, wallets: { selectActiveNetworkAccounts$ }, activities: { selectDesiredLoadedActivitiesCountPerAccount$, selectAllMap$ } }, { bitcoinProvider, bitcoinAccountWallets$, bitcoinFeeMarketProvider, actions, logger }) => selectActiveNetworkAccounts$.pipe((0, rxjs.map)((accounts) => accounts.filter((account) => account.blockchainName === "Bitcoin")), (0, rxjs.mergeAll)(), (0, rxjs.mergeMap)((bitcoinAccount) => {
|
|
678
|
+
const bitcoinWallet = createBitcoinWallet({
|
|
679
|
+
historyDepth,
|
|
680
|
+
requestResync$,
|
|
681
|
+
selectNetwork$,
|
|
682
|
+
selectTip$,
|
|
683
|
+
bitcoinAccountWallets$,
|
|
684
|
+
provider: bitcoinProvider,
|
|
685
|
+
feeMarketProvider: bitcoinFeeMarketProvider,
|
|
686
|
+
account: bitcoinAccount,
|
|
687
|
+
logger
|
|
688
|
+
});
|
|
689
|
+
return (0, rxjs.merge)(selectActiveNetworkAccounts$.pipe((0, rxjs.take)(1), (0, rxjs.map)(() => actions.tokens.upsertTokensMetadata({ metadatas: [{
|
|
690
|
+
...BITCOIN_TOKEN_METADATA,
|
|
691
|
+
tokenId: require_const.BITCOIN_TOKEN_ID
|
|
692
|
+
}] }))), bitcoinWallet.addresses$.pipe((0, rxjs.map)((addresses) => {
|
|
693
|
+
return actions.addresses.upsertAddresses({
|
|
694
|
+
accountId: bitcoinAccount.accountId,
|
|
695
|
+
addresses,
|
|
696
|
+
blockchainName: "Bitcoin"
|
|
697
|
+
});
|
|
698
|
+
})), bitcoinWallet.syncStatus$.pipe((0, rxjs.map)((update) => {
|
|
699
|
+
const operationId = `${bitcoinAccount.accountId}-bitcoin-sync`;
|
|
700
|
+
switch (update.status) {
|
|
701
|
+
case SyncStatus.Pending: return actions.sync.addSyncOperation({
|
|
702
|
+
accountId: bitcoinAccount.accountId,
|
|
703
|
+
operation: {
|
|
704
|
+
operationId,
|
|
705
|
+
status: "Pending",
|
|
706
|
+
description: "sync.operation.bitcoin-wallet-sync",
|
|
707
|
+
startedAt: require_time_vo.Timestamp(update.lastUpdate)
|
|
708
|
+
}
|
|
709
|
+
});
|
|
710
|
+
case SyncStatus.Syncing: return actions.sync.addSyncOperation({
|
|
711
|
+
accountId: bitcoinAccount.accountId,
|
|
712
|
+
operation: {
|
|
713
|
+
operationId,
|
|
714
|
+
status: "InProgress",
|
|
715
|
+
type: "Indeterminate",
|
|
716
|
+
description: "sync.operation.bitcoin-wallet-sync",
|
|
717
|
+
startedAt: require_time_vo.Timestamp(update.lastUpdate)
|
|
718
|
+
}
|
|
719
|
+
});
|
|
720
|
+
case SyncStatus.Synced: return actions.sync.completeSyncOperation({
|
|
721
|
+
accountId: bitcoinAccount.accountId,
|
|
722
|
+
operationId
|
|
723
|
+
});
|
|
724
|
+
case SyncStatus.Error: return actions.sync.failSyncOperation({
|
|
725
|
+
accountId: bitcoinAccount.accountId,
|
|
726
|
+
operationId,
|
|
727
|
+
error: "sync.error.bitcoin-sync-failed"
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
})), getTipFailed$.pipe((0, rxjs.withLatestFrom)(selectNetwork$), (0, rxjs.filter)(([{ payload }, currentNetwork]) => payload.network === currentNetwork), (0, rxjs.withLatestFrom)(bitcoinWallet.syncStatus$), (0, rxjs.filter)(([, walletStatus]) => walletStatus.status === SyncStatus.Syncing), (0, rxjs.map)(() => actions.sync.failSyncOperation({
|
|
731
|
+
accountId: bitcoinAccount.accountId,
|
|
732
|
+
operationId: `${bitcoinAccount.accountId}-bitcoin-sync`,
|
|
733
|
+
error: "sync.error.bitcoin-sync-failed"
|
|
734
|
+
}))), bitcoinWallet.tokens$.pipe((0, rxjs.skip)(1), (0, rxjs.map)(({ address, tokens }) => {
|
|
735
|
+
return actions.tokens.setAddressTokens({
|
|
736
|
+
accountId: bitcoinAccount.accountId,
|
|
737
|
+
address: require_types.BitcoinAddress(address),
|
|
738
|
+
tokens,
|
|
739
|
+
blockchainName: "Bitcoin"
|
|
740
|
+
});
|
|
741
|
+
})), bitcoinWallet.activities$.pipe((0, rxjs.map)((activities) => {
|
|
742
|
+
return actions.activities.upsertActivities({
|
|
743
|
+
accountId: bitcoinAccount.accountId,
|
|
744
|
+
activities
|
|
745
|
+
});
|
|
746
|
+
})), selectDesiredLoadedActivitiesCountPerAccount$.pipe((0, rxjs.mergeMap)((desiredCountMap) => (0, rxjs.from)(Object.entries(desiredCountMap))), (0, rxjs.filter)(([accountId]) => accountId === bitcoinAccount.accountId), (0, rxjs.withLatestFrom)(selectAllMap$), (0, rxjs.filter)(([[, desiredCount], loadedActivities]) => {
|
|
747
|
+
return (loadedActivities[bitcoinAccount.accountId]?.length ?? 0) < desiredCount;
|
|
748
|
+
}), (0, rxjs.switchMap)(([[, desiredAmount]]) => bitcoinWallet.fetchTxHistoryUpTo(desiredAmount)), (0, rxjs.mergeMap)((result) => {
|
|
749
|
+
if (result.isErr()) return (0, rxjs.of)(actions.bitcoinContext.getAddressTransactionHistoryFailed({
|
|
750
|
+
accountId: bitcoinAccount.accountId,
|
|
751
|
+
failure: result.error.reason
|
|
752
|
+
}));
|
|
753
|
+
if (result.value) return (0, rxjs.of)(actions.activities.setHasLoadedOldestEntry({
|
|
754
|
+
accountId: bitcoinAccount.accountId,
|
|
755
|
+
hasLoadedOldestEntry: true
|
|
756
|
+
}));
|
|
757
|
+
return rxjs.EMPTY;
|
|
758
|
+
})));
|
|
759
|
+
}));
|
|
760
|
+
const createBitcoinProviderSideEffects = (config) => {
|
|
761
|
+
return [
|
|
762
|
+
registerBitcoinBlockchainNetworks,
|
|
763
|
+
registerBitcoinTestnetOptions(deriveBitcoinTestnetOptions(config)),
|
|
764
|
+
startBitcoinWallet(config.bitcoinProvider.historyDepth),
|
|
765
|
+
trackTip(config.bitcoinProvider.tipPollFrequency)
|
|
766
|
+
];
|
|
767
|
+
};
|
|
768
|
+
//#endregion
|
|
769
|
+
Object.defineProperty(exports, "SyncStatus", {
|
|
770
|
+
enumerable: true,
|
|
771
|
+
get: function() {
|
|
772
|
+
return SyncStatus;
|
|
773
|
+
}
|
|
774
|
+
});
|
|
775
|
+
Object.defineProperty(exports, "bitcoinAccountWallets$", {
|
|
776
|
+
enumerable: true,
|
|
777
|
+
get: function() {
|
|
778
|
+
return bitcoinAccountWallets$;
|
|
779
|
+
}
|
|
780
|
+
});
|
|
781
|
+
Object.defineProperty(exports, "bitcoinContextActions", {
|
|
782
|
+
enumerable: true,
|
|
783
|
+
get: function() {
|
|
784
|
+
return bitcoinContextActions;
|
|
785
|
+
}
|
|
786
|
+
});
|
|
787
|
+
Object.defineProperty(exports, "bitcoinContextReducers", {
|
|
788
|
+
enumerable: true,
|
|
789
|
+
get: function() {
|
|
790
|
+
return bitcoinContextReducers;
|
|
791
|
+
}
|
|
792
|
+
});
|
|
793
|
+
Object.defineProperty(exports, "bitcoinContextSelectors", {
|
|
794
|
+
enumerable: true,
|
|
795
|
+
get: function() {
|
|
796
|
+
return bitcoinContextSelectors;
|
|
797
|
+
}
|
|
798
|
+
});
|
|
799
|
+
Object.defineProperty(exports, "createBitcoinProviderSideEffects", {
|
|
800
|
+
enumerable: true,
|
|
801
|
+
get: function() {
|
|
802
|
+
return createBitcoinProviderSideEffects;
|
|
803
|
+
}
|
|
804
|
+
});
|