@laceio/sdk 0.1.1-canary.3 → 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-0J9XAADH.js → address-book-address-validator-DIUolI-s.js} +2 -2
- package/dist/{address-book-address-validator-Dte_YQ2L.cjs → address-book-address-validator-DNwQGlOB.cjs} +2 -2
- package/dist/bitcoin.cjs +0 -45
- package/dist/bitcoin.d.ts +1 -29906
- 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-Cfpvbod9.js → cardano-network-id.vo-CK1tNQDg.js} +1 -1
- package/dist/{cardano-network-id.vo-BEDPn6Li.cjs → cardano-network-id.vo-DSxrFk9S.cjs} +1 -1
- package/dist/cardano.cjs +18 -22
- package/dist/cardano.d.ts +3774 -18959
- package/dist/cardano.js +11 -16
- package/dist/codecs-B7X9pAsK.cjs +1945 -0
- package/dist/codecs-CC1Xjntz.js +1882 -0
- package/dist/{const-D-eZIS4n.cjs → const-BDEg2Trq.cjs} +4 -4
- package/dist/{const-iwzZEE_w.cjs → const-BY8B3_0_.cjs} +1 -1
- package/dist/{const-BJfIK_G-.js → const-C84qHkjp.js} +4 -4
- package/dist/{const-CjmfjBP3.js → const-DXk2tFyv.js} +1 -1
- package/dist/{delegation-tx-builder-DZFjHDS8.js → delegation-tx-builder-CGVqlaFE.js} +5 -5
- package/dist/{delegation-tx-builder-CCjiakoy.cjs → delegation-tx-builder-CRpLP6jH.cjs} +6 -6
- package/dist/{deregistration-tx-builder-Bf6xAYp4.js → deregistration-tx-builder-B-CrUyX6.js} +5 -5
- package/dist/{deregistration-tx-builder-CQP35yex.cjs → deregistration-tx-builder-DZGwB4cz.cjs} +6 -6
- package/dist/{earn-rewards-tx-builder-Bsga3yFb.js → earn-rewards-tx-builder-BDbTDZmD.js} +5 -5
- package/dist/{earn-rewards-tx-builder-GuxofYns.cjs → earn-rewards-tx-builder-D5sUT5v8.cjs} +6 -6
- package/dist/{group-cardano-addresses-by-account-Bp0g4wEY.cjs → group-cardano-addresses-by-account-B533oVXR.cjs} +39 -3
- package/dist/{group-cardano-addresses-by-account-SR8MMrZf.js → group-cardano-addresses-by-account-RHKoEskR.js} +35 -5
- package/dist/{guarded-transaction-signer-MFpPg98D.cjs → guarded-transaction-signer-Bxl6_XNd.cjs} +18 -17
- package/dist/{guarded-transaction-signer-P6Rp1faj.js → guarded-transaction-signer-CpKLj8Kp.js} +15 -8
- package/dist/{in-memory-wallet-integration-t9I00R_V.cjs → in-memory-wallet-integration-CnLYeX4-.cjs} +108 -17
- package/dist/{in-memory-wallet-integration-CljprQQV.js → in-memory-wallet-integration-Croiuopx.js} +104 -7
- package/dist/{in-memory-wallet-integration-ChIOirMW.js → in-memory-wallet-integration-D-qn65Kx.js} +2 -5
- package/dist/{in-memory-wallet-integration-Cm6P8sk6.cjs → in-memory-wallet-integration-DVh9sRXa.cjs} +2 -3
- package/dist/index.cjs +47 -84
- package/dist/index.d.ts +13480 -40888
- 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-EhzD7a8i.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-Bp9GsPS_.cjs → init-C4Bkib9u.cjs} +56 -46
- package/dist/{init-lzHt4Cli.cjs → init-C7IeJwQR.cjs} +59 -256
- 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-DS5qN63m.js → init-CR6tpw1B.js} +32 -24
- 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-kEfUTuG2.js → init-Dku4b2lG.js} +1 -1
- package/dist/{init-NdhG_VrF.cjs → init-DxUHsN53.cjs} +6 -6
- package/dist/{init-CfTbSEKy.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-DObB55D4.js → signer-factory-9URFliA5.js} +3 -6
- package/dist/{signer-factory-Ds6G2AZk.cjs → signer-factory-BWGUmnvm.cjs} +3 -4
- package/dist/{slice-qt0uBExh.js → slice-B2PhoWAg.js} +37 -325
- 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-DTZTiJle.cjs → slice-mxLQ_FeY.cjs} +39 -352
- 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-31iFLExW.js → sync-operation-utils-BYXLO80m.js} +38 -2
- package/dist/{sync-operation-utils-COIZ66-I.cjs → sync-operation-utils-SdPbwFoD.cjs} +67 -1
- package/dist/{token-id-mapper-D29Ggv8h.js → token-id-mapper-B2ivlLv3.js} +2 -2
- package/dist/{token-id-mapper-CVyQJUKY.cjs → token-id-mapper-DsPAL6Nh.cjs} +2 -2
- package/dist/{util-Cp5cZkfK.js → util-BaLzwa32.js} +1 -1
- package/dist/{util-Bu4W5lF4.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-BUg1S2Ep.cjs → vote-delegation-tx-builder-BpEMSti4.cjs} +6 -6
- package/dist/{vote-delegation-tx-builder-C6FiS7zI.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-BOQruszJ.js +0 -6
- package/dist/account-BUOj4pYJ.cjs +0 -11
- 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-DvkOFVON.js +0 -16
- package/dist/account-tokens-nwcvwLu4.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-BhYOdznB.cjs +0 -42
- package/dist/const-BsnjG2_Q.cjs +0 -32071
- package/dist/const-CUnCl5U0.js +0 -13
- package/dist/const-D0CbQlo4.js +0 -154
- package/dist/contract-BD_312b0.js +0 -171
- package/dist/contract-DevBp9u8.cjs +0 -189
- 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 -7075
- package/dist/experimental.d.ts +0 -85525
- package/dist/experimental.js +0 -6917
- 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-CBRiPjLO.js +0 -130
- package/dist/in-memory-wallet-integration-CULUB5Tf.cjs +0 -240
- package/dist/in-memory-wallet-integration-TM9bBphA.js +0 -20738
- package/dist/init-8v_n8boO.js +0 -1177
- package/dist/init-B5X_sGj9.cjs +0 -6
- package/dist/init-B8U3ABhS.cjs +0 -107
- package/dist/init-BJn-8_hf.js +0 -141
- package/dist/init-BmzfDaKL.js +0 -1142
- package/dist/init-BpHTq2R5.js +0 -105
- package/dist/init-BpSITBfF.js +0 -39
- package/dist/init-C00gw1zi.js +0 -422
- package/dist/init-CR7BfztQ.cjs +0 -18
- package/dist/init-Cp8EJGbm.js +0 -5
- package/dist/init-CuW7rHNA.js +0 -3584
- package/dist/init-Cz0rz5fU.cjs +0 -3585
- package/dist/init-D8OeObDF.cjs +0 -1141
- package/dist/init-D9g1HXYf.cjs +0 -40
- package/dist/init-DGjXwWs2.cjs +0 -143
- package/dist/init-DHrCbpkW.cjs +0 -121
- package/dist/init-DU5yYX5u.js +0 -2374
- package/dist/init-DlqJuHhl.js +0 -119
- package/dist/init-DrRdf5sZ.cjs +0 -1176
- package/dist/init-DuYENxci.js +0 -17
- package/dist/init-GsT2AEa4.cjs +0 -424
- 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 -1408
- package/dist/midnight.d.ts +0 -28934
- package/dist/midnight.js +0 -1352
- package/dist/modules-cardano-BrS68BbA.js +0 -995
- package/dist/modules-cardano-D843LvB0.cjs +0 -1108
- 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-Dd0MKXFz.cjs +0 -1439
- package/dist/sdk-_yO75IHD.js +0 -1241
- package/dist/sdk-init-CYViTJY_.cjs +0 -3841
- package/dist/sdk-init-OMHyOGOK.js +0 -4138
- package/dist/send-proof-progress-C-ljq1x5.js +0 -30
- package/dist/send-proof-progress-vmsaSfbz.cjs +0 -47
- 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-Cwd6o-lG.cjs +0 -281
- package/dist/signer-factory-DhZiE03y.cjs +0 -149
- package/dist/signer-factory-hzSRaIw2.js +0 -148
- package/dist/slice-BPNuHKfw.js +0 -9091
- package/dist/slice-CxKWDuBP.js +0 -87
- package/dist/slice-Czfp6t84.cjs +0 -436
- package/dist/slice-DnBWfA-k.cjs +0 -9109
- package/dist/slice-HjLXJyQG2.cjs +0 -105
- package/dist/slice-oWnc7YVD.js +0 -412
- 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-BG3Gemov.js +0 -983
- package/dist/submit-bitcoin-tx-Y0CtvFN7.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-DFwzEvbv.js +0 -65
- package/dist/utils-IXxR-Djh.cjs +0 -112
- package/dist/v8Signatures-CO_Uloy7.cjs +0 -71
- package/dist/watch-D-RoItM5.js +0 -21997
- package/dist/watch-DMF2s-II.cjs +0 -52281
- /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-TLjJZHCI.cjs → cardano-tx-id.vo-BPhV-AmZ.cjs} +0 -0
- /package/dist/{cardano-tx-id.vo-eVnKuzlm.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,768 +0,0 @@
|
|
|
1
|
-
import { a as __toESM } from "./rolldown-runtime-OvD0k9op.js";
|
|
2
|
-
import { n as import_buffer, r as init__polyfill_buffer_patch } from "./_polyfill-buffer-patch-yNxN4d5E.js";
|
|
3
|
-
import { c as require_dist, l as require_src, r as deriveAddressByType, s as BitcoinNetworkId, t as AddressType } from "./address-B9ntKL8K.js";
|
|
4
|
-
import { i as deriveChildPublicKey, t as ChainType } from "./keyDerivation-D3k9XyHg.js";
|
|
5
|
-
import { s as Timestamp } from "./time.vo-tNheinXm.js";
|
|
6
|
-
import { t as BigNumber } from "./bignum.vo-CEXOIew0.js";
|
|
7
|
-
import { n as Ok, t as Err } from "./asyncoption-CruEYOBI.js";
|
|
8
|
-
import { i as networkSelectors } from "./slice-GwiiJRoq.js";
|
|
9
|
-
import { t as ActivityType } from "./activity-type-GsJGWs-3.js";
|
|
10
|
-
import { t as whileActive } from "./while-active-B0lWy_6l.js";
|
|
11
|
-
import { n as BitcoinNetwork, t as BitcoinAddress } from "./types-B8uiJn-X.js";
|
|
12
|
-
import { r as BITCOIN_TOKEN_ID } from "./const-CUnCl5U0.js";
|
|
13
|
-
import { t as BitcoinTransactionStatus } from "./bitcoin-data-provider-BYPSmuZS.js";
|
|
14
|
-
import { BehaviorSubject, EMPTY, combineLatest, defaultIfEmpty, distinctUntilChanged, exhaustMap, expand, filter, finalize, firstValueFrom, forkJoin, from, interval, last, map, merge, mergeAll, mergeMap, of, skip, switchMap, take, tap, withLatestFrom } from "rxjs";
|
|
15
|
-
import { createAction, createSelector, createSlice } from "@reduxjs/toolkit";
|
|
16
|
-
import isEqual from "lodash/isEqual.js";
|
|
17
|
-
import { catchError as catchError$1, map as map$1, switchMap as switchMap$1 } from "rxjs/operators";
|
|
18
|
-
//#region ../../packages/module/blockchain-bitcoin/src/store/slice.ts
|
|
19
|
-
const slice = createSlice({
|
|
20
|
-
name: "bitcoinContext",
|
|
21
|
-
initialState: { historyFetchErrors: [] },
|
|
22
|
-
reducers: {
|
|
23
|
-
getAddressTransactionHistoryFailed: (state, action) => {
|
|
24
|
-
state.historyFetchErrors.push(action.payload);
|
|
25
|
-
},
|
|
26
|
-
setTip: (state, { payload }) => {
|
|
27
|
-
state.tip = payload;
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
selectors: {
|
|
31
|
-
selectTip: ({ tip }) => tip,
|
|
32
|
-
bitcoinContext: (sliceState) => sliceState
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
const selectBlockchainNetworkId = createSelector(networkSelectors.network.selectNetworkType, networkSelectors.network.selectBlockchainNetworks, (networkType, blockchainNetworks) => blockchainNetworks.Bitcoin?.[networkType]);
|
|
36
|
-
const selectNetwork = createSelector(selectBlockchainNetworkId, (networkId) => networkId ? networkId.includes("mainnet") ? BitcoinNetwork.Mainnet : BitcoinNetwork.Testnet : void 0);
|
|
37
|
-
const bitcoinContextReducers = { [slice.name]: slice.reducer };
|
|
38
|
-
/** Direct import of this is an anti-pattern. OK for tests. */
|
|
39
|
-
const bitcoinContextActions = { bitcoinContext: {
|
|
40
|
-
...slice.actions,
|
|
41
|
-
getTipFailed: createAction("bitcoinContext/getTipFailed"),
|
|
42
|
-
requestResync: createAction("bitcoin/requestResync")
|
|
43
|
-
} };
|
|
44
|
-
/** Direct import of this is an anti-pattern. OK for tests. */
|
|
45
|
-
const bitcoinContextSelectors = { bitcoinContext: {
|
|
46
|
-
...slice.selectors,
|
|
47
|
-
selectBlockchainNetworkId,
|
|
48
|
-
selectNetwork
|
|
49
|
-
} };
|
|
50
|
-
const BITCOIN_TOKEN_METADATA = {
|
|
51
|
-
name: "Bitcoin",
|
|
52
|
-
ticker: "BTC",
|
|
53
|
-
decimals: 8,
|
|
54
|
-
displayDecimalPlaces: 8,
|
|
55
|
-
image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABmJLR0QA/wD/AP+gvaeTAAAgAElEQVR4nOzde3xcdZ0//tf7zCQzk/R+SzJJoRQEuSMoqEBbEV1dLou4sK4XkNWlQpNwcRF116/Zm4poSzNJsXhBEH/r4rpewBsgFNqCiAUBYVFLKSWZpPR+ycyZZOa8f380IAJt5nLO+Zxz5vV8PPJ4KMycz6s8mjnv+bzP5/MBiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiCgoxHQAIprYzhUHTU+Vii2O6Bx1MEsg09SSaaI6TYFpojJNRCcpMBlASgRJVUwBEBdg2iuvpcBUANarhnAE2PWq1+0EMCaCPaqwAeQF2KPQPSqyUxzsVJGdAt2pojvFwVZLZEuu2Dg8/aqNO73870FEtWMBQGSQ3jwvWcgVO9RBB1QPgmAu4HQAMlcErapoATAHQKPprBUqANgCYFiBYYEOANYAxNkERzcJGgYSSAxI9/qC6aBE9YoFAJHHdGlHaiShR1glHAZLDxUHh0H0MEAOBdCB+v09VAADEKyHYr0KnoXq+rha6xuK8ke5eiBvOiBRlNXrBw+R63RpRyoXKx1lxXCUOHK0Y+EoURwF4BC8dsqdDswB8JwCTwnwNESfdkp4umlK4im5ZKNtOhxRFLAAIKqC9s6YYseSx4mjJymsowA9GsCbASRMZ4u4IoA/CvCUAk+LYt1oAg9NWZzdajoYUdiwACCagK48qSE3mj0+JnKKOnIKRE8BcLjpXPQyBfAnqDwslj5cKumvm5LpJ2TxujHTwYiCjAUA0avoyvlTC4XCaRBdoMCpAE4EkDKdiyqSh2KdAGsBWZ1AfrV0b99tOhRRkLAAoLq3a2nHjIbG0kKotdCCLlDgOAAx07nIVSUBHofKAyXR+8di8funXb5ph+lQRCaxAKC6oz2I56a3HS8xOVMUZwJYCKDBdC7ylSOCx+DgHgD3JNC0mksSqd6wAKC6kF/WOk9i1tkq+l5AFgJoNp2JAmUvgPsF+JmK/jTVOfS86UBEXmMBQJGkPbBy09veZFlyjgjOVsWJ4N93KptsUNE7LQd3JLZnV0kPiqYTEbmNH4gUGdp7WKJg2e9Udc6H4m8gmGU6E0XCFih+LOL8b2LbzF9Jz1OjpgMRuYEFAIWa3jwvWdgz+i6FXADRc7Fvn3sir+QUuFdUvp+Mjf6vLNmy13QgomqxAKDQ0dsRKwyn36GQi2DpeVBMNp2J6lJegDuh+E4i0fYL7jtAYcMCgEJjZHnbSRKTi0TxdwBaTOcheoXtUPmpQG9NdGV/JQI1HYhoIiwAKNDyfW0HA3IxVC4GdL7pPERleBaQW+DoLakrsptMhyHaHxYAFDh687xkfu/YOYBeJMB7wU15KJwcAA+J6K2JvPNduWbziOlARK/EAoACo7C85ZiSxD4hgg+DD/NRhCiwE8BtMXVuTHQPP206DxHAAoAM056jG/Mzd/6NQC8F8E7w7yRFnAjWAXpTYjT2Hbl6IG86D9UvftiSESOZuWkLTiegHwMwx3QeIgNeBOSbDqy+5q4XsqbDUP1hAUC+KqzoOM4p6RJALwKQNJ2HKABGBfhxyXKub14y/IjpMFQ/WACQL/L96dPUwbUCnAX+vSPan7WiuC7Rlb2TSwnJa/wgJs+83N9XXAPRt5jOQxQWqnjCsrQ/0Zy4VS7ZaJvOQ9HEAoBcp70zphQkcYlCPglgruk8RCG2GcDXRses3qlXD2w3HYaihQUAuWZv/+zWeKnxWhX9OIBJpvMQRYZgjzj69aJT+vKkK1/cbDoORQMLAKrZ7r72mQ2qXRBczX35iTyVU8E3nGLxCywEqFYsAKhqet2syfnmxstF8Rlw4x4iP+0VRb8dj1837fJNO0yHoXBiAUAV0/7Zk/LasASKTwswzXQeorol2CMOViQSyS/K4g27TMehcGEBQGXT61uaC0nr4wr5DHgaH1GQbAPQl1R7qXRv3206DIUDCwCakC7tSOUb9BMC/TS4ax9RkG1W0S+lmhNf4/JBmggLADoguzd9jgqWAzjEdBYiKtsAVP452TX4HW4oRPvDAoBe10hf+kRLcQOA001nIaKqPawqVzZ1D/7adBAKHhYA9Bd2r0zPio/hc6JYAiBmOg8R1cyByndLsdFPTVqyZdh0GAoOFgAEANCVJzUURrOXK+TfAEwxnYeIXDcC4CvJSY1f4vMBBLAAILzc518G4FDTWYjIc+sV8tmmrsHvmw5CZrEAqGOFTMexDpwbAJxhOgsR+e4eS5wrE53DT5kOQmawAKhDevO8pL139NMAPgOg0XQeIjKmqIIVqXzps3LN5hHTYchfLADqTL637XSI3ATgjaazEFFgPAuRxanOwV+ZDkL+YQFQJ3Tl/Kn5MfvfRNEJwDKdh4gCR6Fy22hRruTRw/WBBUAdGH/IbwWADtNZiCjwhlWlq6l78H9MByFvsQCIsL39s1vjGs+oyt+azkJE4aLAnVC5rKl7cMB0FvIGC4AIUoXYmfaPQHQZgBmm8xBRaO0S6OcT24Yy0gPHdBhyFwuAiMn3tR0MxbcBWWQ6CxFFhOA+lPDR1BXZTaajkHv4MFiE5Hrb/xYqj/LmT0SuUrwDFp7I97Z9yHQUcg9nACJAe2dMsSV1PaCXms5CRNEmwPfzxcZLp1+1cafpLFQbFgAhl+vrOEXUuQ3AYaazEFHdeB6qH0l1D602HYSqxwIgpLQH8fys9CdF8e8AGkznIaK6UxTFVxOJts/J4nVjpsNQ5VgAhFB+Wes8xKzvQHCa6SxEVO/0N2LFPpRcMrDedBKqDB8CDJlcpv0CjVuP8eZPRMEgJ6s6j9p9bXwGKWQ4AxASen1Ls52MfR3A35vOQkT0+uS2ZKMulsXZnOkkNDEWACFg93ccpo7zvwCONZ2FiOhAVPGEhdj5ye4XnjWdhQ6MLYCAs3vbz4Lj/Aa8+RNRCIjgOJXSo7m+tveZzkIHxhmAgFKF5PvTnxLFF8BCjYjCR0Xx5cT27Ge5jXAwsQAIIO2dMSWP5K0i+BvTWYiIaiM/L8RiH5p2+aYdppPQX2IBEDCjve3HlwT/C+h801mIiFyyyYG+v7lr6Lemg9CfcWo5QPK9bR8qiT7Imz8RRcxBFmR1PpO+xHQQ+jPOAASA9iCen5leJkCn6SxERF5SyPJUy+An5UKUTGepdywADNP+2ZNsp+F7AM4ynYWIyCd3JdW+QLq37zYdpJ6xADBoJDM3HUPpDgVONJ2FiMhnT6qFs5qWZF8wHaResQAwpJDpONaBcyeAg0xnISIyJOsozm7uzj5mOkg94kOABth96Xc5cFaDN38iqm9pS/CA3dvOFqgBLAB8lu9N/4MqfgpgquksREQBMElFf2z3tV9mOki9YQvAJ6oQuy/9eQCfN52FiCiIVNCb2pq9ijsH+oMFgA+097CELblvAfig6SxEREEmov+TGI1dJFcP5E1niToWAB7bsWzetGR89E4Ap5rOQkQUEquTjclzZPGGXaaDRBkLAA/tWtoxo7Gh9HNATjadhYgoTAR4dEyd90zuHt5iOktUsQDwyN7+2a0xp+Eu8BhfIqJq/Z/GrXc1XTYwaDpIFLEA8EB+efogWLgHwBtMZyEiCrnnJFY6M3n55g2mg0QNCwCX5TMthwCxXwE4xHQWIqKI2CSOdWbyioE/mQ4SJdwHwEWF/rYjgdga8OZPROSmg9RyVhdWdBxnOkiUsABwyUhf+kSnJA8ASJvOQkQUQS1aclbl+jpOMR0kKlgAuGCkv/UtluJuCGaZzkJEFFUKTBd1fpnLpLms2gUsAGqUz7SfYTnWfQBmmM5CRFQHpgrwy3ym/QzTQcKODwHWINfX/jZRvQvAJNNZiIjqTA6i7011Dj1gOkhYsQCo0t7+9hPijt6rwHTTWYiI6tRuB/rO5q6h35oOEkYsAKpQWN5yjGPFVgGYaToLEVFdU2y1LGdRonP4KdNRwoYFQIXs/o7D1HEeANBmOgsREQEAXrSAhYmu7DOmg4QJHwKsQK4/PVfVuRu8+RMRBckcB7grv6x1nukgYcICoEx7b5jTIoq7oZhnOgsREb3GXMStu0eWHcwvaGViAVCG3SvTs2Kx+K+gOMJ0FiIi2q/DrIax+/beMKfFdJAwYAEwAV05f2rjGH4B4GjTWYiIaAKKI+Kx+C92rjiIK7QmwALgAPTmeUl71P6pKk4ynYWIiMqjwAmJUvHH2ntYwnSWIGMBsB+qEHtk9BsAuOUkEVH4nG4jd6sqV7vtDwuA/Shk0l+E4kOmcxARUZUEF9p9bf9uOkZQsTJ6HflM+mMAvmE6BxER1U5ELk92Dt5oOkfQsAB4Fbu/7T3qyB0A4qazEBGRK8ZEcXayO3uX6SBBwhbAK4z2th+vKreDN38Knz9CcSOA/zMdhCiAGlTw/UKm41jTQYKEMwDjRjJz0xZKvwYw13QWokqJ4rpkd/bTALDnxpY5DWOxUwCcCgtnquJE8HedCACyqnJKU/fggOkgQcAPBQB63azJhabGBxQ4wXQWomoInL9Odg3//PX+HQsCoj8T4LGENbZAlmzZazqLaXX/IaC3I5Z/Mf1DUZxjOgtRlYpJtWdK9/bd5bx4T2/r7AZYbwULAqpb8vPktsFzpQdF00lMqvtf+lwmnRGg03QOourpb1JdQ6dU++49N7bMiY3FF0B0oQDvAHAU+NlAEaeQ5U1dg1eazmFSXf+S53vbPgSR20znIKqFAF9OdmWvdet6rzND8CbwgWGKIpGPpjoHbzEdw5S6LQAKKzqOc0rOQwCaTGchqoWIdVayc+BnXl1fe2dMKSB5MoAzWRBQxOQdwWnNndlHTQcxoS4LgF1LO2Y0NugjgM43nYWoRhX1/91g35A+QmN4xq/xiDy23i42vmX6VRt3mg7it7qr4rUHVmOD3sabP0WDPurnzR8AHEt5MiZFyWGJ+Oh3tKf+7od19we2Z7X9K6DvNZ2DyA0CWeX7oJYs9H1MIg8JcLY9K/0vpnP4ra4KALs3fQ5UPms6B5FrxLrf9zEVLAAoehSft/s6/tp0DD/VTQFgL+94gyO4FXX0Z6bIKyUaGtf6OeCupR0zBOB2qhRFFtS5ze6de6jpIH6pi5uhXt/SrJb+rwDTTGchco3Ko7J4wy4/h4w3OAvg3efGCwI8CqDk0fWJDkiB6ZDS/+jKdF2sDquLAsBOxr4O6DGmcxC5SUR9n/4XyCIPL//tZFf2JLvYOEsU54rqUhYE5DcFTrBHtS6ODo78qXf53vaPAvr3pnMQuU4NPAAIXeTdtff9ecaXY90x/gPtnz2pUGp4K4AzVXAagJMBNHiXg0guyve23ZXqHvqu6SReivQ+APaKlvlaij0GYIrpLEQuK9nFxll+rl3et3+GswXezByOJhsxXRZncxO9kAUB+WQXis4JqauGN5oO4pXIzgBoD+J2KXYbePOnKFJ51O+NSzzu/z9czs0fAMZPcbtn/Of1CoK3AGj0KCfVj6mIW7fp7VgoF0azDRXZAsCekf4cgLeZzkHkBbF0ld9jxlQWqqhXl19V7RtfUxBc39JcSMTeNl4MnApgAVgQUHVOtTe3fxYY/HfTQbwQyQIgl0mfCuCfTecg8owj/q//Fw/7/+Len0eu2TwCFgTkGv1/ub72e5o6Bx8yncRtkXsGQHtnTLEl+TsAh5jOQuSRUrIxOdPPJYBB6f+7Qa+bNdlubjgPKrf6MR5FwrPJ3Oib5Nqte0wHcVPklgHakuoHb/4UZdFb/192/98Ncu3WPaqW7dd4FAmH2k2Ny02HcFukCoBcb/vfAvph0zmIvGRi/X9MPdz/38CfB6rczpgqdUmuL/0B0yHcFJkCINfb3mGJ3mQ6B5HnXOyXlz+md/1/MfA8gwgW+T0mRYDixvzy9EGmY7glEgWAKkTE+Y4C001nIfJYKdGQWO3ngDtXHDRdgeM8uvxoIoEHPbr269rT2zobwFF+jknRIMA0CL6lGo3n5yJRABQybZfC2y1KiYLiMb/7/ymn6F3/X/EbP/v/ABBDbCEi+AA0+UTwTjuTvsR0DDeEvgAYWXZwG0S+aDoHkR+khvXy1VIv++UG9jOAsP9PNRIszd3Y0W46Rq1CXwDE4mP9nPqnumGi/+/h7JqR/j9nC6l2U62is8x0iFqFugDIZdrer8D7TOcg8kkpP9awxs8BdyybN83D/v9YolDydXOVff1/PdrPMSmaFLhgJJM+z3SOWoS2ANCV86cKJHLrMokO4DG/9/9vahhdCCDm0eV/M75rn2/Y/yc3WcCKHcvmTTOdo1qhLQDsgv0VAKHvwRCVK3L9f7D/T6HXloyNfsF0iGqFsgDI97YuhOBjpnMQ+Spq/X8Dfx4BWACQuwSL871tp5uOUY3QFQC6tCMFsb4OTuMRAEA2qOLHALabTuIx3/v/4+v/j/fo8mOJfMnX9f+7V6ZnATjGzzGpLlgQuUlvnpc0HaRSoSsACnHn8wDeYDoHBYXe3tSdPS/VlZ0psdKhIrpYgO8D2GY6mZtE8Du/+//JUvF0ePUZIXjE7/5/fFTZ/yevvNEeKYTuBNpQFQCFTMexKvik6RwUHALngZf+d/LyzRuSnUM3JbuyFya3ZefEVE4Q6JUC/AhhnyFwIrZfvhppZ3D6n7yjcm2htzVUO0zGTQeohAPnqwhZZvJUMaGja1/vX0gPHGDwcQCPA1gOAPaKlvlwrDOhcqYq3gHBLD/D1kZW+T+kh/1/9f8BQAH3/ydPNTiwegGcaTpIuUIzHZbrbTtfRH5gOgcFysOpruxbq31ziAqCkl1snOVnC0BXzp9qj9rb4M0SwGIyNzrDz7PVdy3tmNHY4GxByGY9KXxEcW6yO3uH6RzlCMW3ae05utGWHV8ynYOCRbS2ZXHJyzdvAHDT+E9gCwIT/f/CqO3l+v9H/Lz5A0BDvLQIEN78yXMqWKa9h90l3esLprNMJBQFgD1zx9Xgg3/0auK42kcOcEGwyvcRVRdCvJogNNDOsGQh1PdRqT4dmke+E8BXTQeZSOALgL03zGkB8BnTOShw9tv/d0tgCgIH/j8w52X/H+4WbmVxsCg8DU8KO7H083v7Z3930pItw6azHEjgC4BYLP5FAFNM56Cg0Uele/tuP0c0VBCU8qXG1R5cd7/G+/9erf8vJnJjvq7/37W0Y4aIw/X/5B/F5Jg2/iuAxaajHEigC4CR5W0nAbjYdA4KHhO7yL3aKwsCVchoX8cxCmcRIIsU+m4Ak2odQ4DHfe//F+wFEM/6/7/1vf/fWFoIZf+f/KYf29vffuOkJYO/M51kfwJdAFiWLAOf2qXXZa0yneCVRKDAwJMAngSQ0d4ZUwpInqyC0wCcCuA0AJXvFGZguRwseNgvl/u8uvJ+qbUQfACA/BeLOdqnitP3fT4ET2ALgFxf+gNQhHJ/ZfJcKdHQ6Gn/v1bj7Yl7xn+gK09qyNnZ42IWTgPkVAXeCWDGxBcyMtOxyKsLG+n/Qxf5PyYRAODUfF/b+cBQIJewB/KxGF3akbIbnGcAHGQ6CwWQyiOp7sGTTceohd6O2Nhw+zEO9HSVl2cIOl71MqcQi8+advmmHb7l4vp/Irc9l5zUeJRcstE2HeTVAjkDkG/Uy0R586fXJ5aBaXGXyYUovWKnwj4AGMnMTQucUyF6mgWcqgr18+YPsP9P5IFDCntH/xFAxnSQVwtcAaDXtzTbqteazkEB5ph/ANALzV0vZLHvIKPvA/vaBkDW3xAe9v9FDSxnZP+fAkCBz+rK9DdlcTZnOssrBa4ytpOxLgBzTOegwCrlSw2B7v+7RRavGzMw7CLPrhzzf+bGgocHGhGVrzVfkMtMh3i1QBUA2j97EoCrTeegAFN51O9lcfVCV86fqooTPLp8MbF3zNfCbdfSjhkKHOfnmET7I9BP63WzJpvO8UqBKgBsp+GTAGabzkHBJWLgWNw6URgrnA7v9v9f53f/P97gLEDAPuOojglm2amGLtMxXikwvxw7ls2bJsAVpnNQwAVgA6DIUu+my2s9uKkaMRVO/1OgqMg1O1ccNN10jpcEpgBINoxdo0Bg/sNQIJXyYw1rTIeIKvWy/+/ywU3ljcn1/xQsAkxLlIqB+aIbiAJg98r0LEADNTVCgfQY+//eKVlj54jiXFFcB2AtALceQvT84KZX27nioOns/1NAXbVracfEm4D5IBDLABtHca0CgXo4goJHTByLW0fGTy67Y/wH2j97UqHU8NZXbGd8KoBU5Vf2/+CmlFNc4ATkCw7Rq0xpbNB/AvBZ00GMFwB7+2e3qoPLTeegEGD/31eyZMtevHI74x7Ec9Pbjn95O+MyT0AUyCqPo76Gqi4M6EanRAC0e8+NLTdMvmzziyZTGC8A4k78Uwo0mc5Bgcf+v2HSgyIwtA7AOgDLVSGjmdYj1ZLT1LFOg+hpAA557RstA4WbLPJ/TKKyNTeUYv8E4FMmQxgtkXeuOGh6olTcBBeOTaVoE8G6ZGf2zaZz0IHt7Z/dGi81vAXAqeOtgxOTarf62QLYsWzetGR8dCu8W9JIVDvBnmRDcq4s3rDLVASjMwCNTvFS8OZP5XC4/j8MXvMcwfUtzXLN9hE/M6TiowuUN38KOsXk/Kj9jwC+YiqCsYdkdOVJDaLoNDU+hY3/fWSqnVyz2deb/z5c/kfhIMCV2nN0o6nxjRUAdmH4Q3jt8adEr8fJlxpXmw5BYcENgCg02u2Z2y80Nbi5GQDRK02NTeEiwO+4/p/KoSvnT1XgeNM5iMqlKteomnkez0gBYPem3y38JaUyKXT3SKbtzdpjftUKBVuhYC8A+/8UIiI4zu5vP8PE2EY+UFXwTybGpbCSRRbwiD0zPZLP4HeiWANgrR2Pr5l2+aYdptNRkOgirv+n0FF8EsCv/B7W99+UwoqO45yS8zsTY1PklAR43BGsgcoaLcbXNF/1/JDpUGSO3Zf+rSpOMp2DqEJqOaXjElds/r2fg/p+E85n2m4B5CK/x6W6MSTAGojeA8u5J3n55g2mA5E/dOX8qfaovQ1sAVA43Zzqyv6DnwP6WgCMZOamLZSeA2Bs2QPVGcFGqD4Ate5T4J6m7sEB05HIG9p7WMKW3PsB/RAg70YAdjolqkDBKTYc4ucspq8FQD7T/gVAP+PnmESv8qQKvhsrlX7q93Qb+WfvDXNa4rHYBxTyYQDcQZLCQfQ/Up1Dn/NtOL8GGq/ONwGY49eYRBNYD5VbSs7Y1ydd+eJm02HIG4VM+o2q+KgKLgE/fyjYsslt2YP3nbvhPd8KgHwm/UEA3/VrPKIK5FXw9bFR61+nXj2w3XQY8ob2HN2Yn7XzPHH0UgjOAB9EpgCyBOclOrM/9mMsPwuABwCc7td4RFXY4gCXNndlf2Q6CHnLXt7xBsScf1QHl5RzpDGRj36a6sqe7cdAvhQAheUtxzhW7Ek/xiKqkULx76nu7OdNByHv6dKOVCFeukgtuQqKI0znIQJQUpV5fjyw7MtOgCWJfcKPcYhcIBD8v3wmzQKgDsjVA/lk99DK5NbsUaI4FxCeOkmmxcRSX5YDej4DoEs7UnaDMwRgqtdjEbnIEeB9ya7sT0wHIX+NLG87KWbJPytwHvicAJnxfHJbdr70wPFyEM9nAOx46Xzw5k/hYznALbv72meaDkL+ar5iaF2yK3u+ozhJgZ8AUNOZqO4cXJjd9m6vB/GhBSCXeD8GkfsEmNawb49uqkPN3dnHmrqyf2PFrBME+D5YCJCfHOvjXg/h6fRWvq/tYKhsgMFjh4lqtDeZG03LtVv3mA5CZuWWp98uIjdA9C2ms1BdGCuVinO93KPE4xuzXOz9GESempRvbjjTdAgyr+mK7IPJrsFTFHIhgE2m81DkNVix+MVeDuDZzVkVAhVPwxP5QVTeazoDBYMItKlr8PvJ3OgxAL4EoGA6E0WXAB9X9W6m3rMCIN+Xfjug8726PpGPjjMdgIJFrt26J9WV/YxY1jFcOkgeekM+036KVxf3cnr+gx5em8hP80wHoGBKLhlYn+wcfIeILgaw13QeiiBL/96zS3txUV15UoMAF3hxbSIDuBSQ9ksEmuwcuklipeMBXWU6D0WLKP5Ob0fMi2t7UgAUCsPvBjDbi2sTEQVR8vLNG5KdQ2eo6FUARk3nochoKQyn3+nFhb2ZAfBwyoLIgF2mA1A4iECbOoduUJFFAAZN56FoUPGmpe56AaAr001QnOf2dYlMEWC16QwULk2dgw8V46UTIbjPdBaKhPfpzfOSbl807vYF8wV9j4g0u31dIlMc0Ug85W33ps+B4BJHZS1UH0pJ0zrpXs9lbB6ZfNnmF/V2vKswnP5PFVxrOg+F2pTCntF3AbjDzYu6XgCIJedzw0yKEkesVaYzuEEtPQsq7xPR90EAG7lCvi+9ThQPloC1Trz04OTLNr9oOmeUyIUoAdlP25n2jQrtA7x5mIuiTwXvh8sFgKsbDGjvYQlbcpvBw38oOrYnt2Vne30qlx/yfelnJj7zXjZAsVYsZ41A1zYuGX5ahCW9G0Yy6fMs4L8AuD6VS9GnwM7Utukt0vOUaw+YuloA2L3tZ6nonW5ek8gkAX6U7Mq+z3SOWu3tn90acxqGqnjrZgUegWCNCNYm420Py+J1Y64HrBP55e3vgKU/AjDFdBYKH1H8VbI7e5db13P1IUC19Hw3r0dkWlT6/5Y2LKryrS0CnC2KL8HB6vzo0It2pv0Hdqb9E3bv3EPdzFgPUlcM3qdivRsCHi5FFVOR97t5PddmAPR2xOzN6SFw/T9FiKM4sbk7+5jpHLXKZ9puBOQT7l9ZNkD1lyL648S2Gfe5OT0ZZXZf+l2quBNAo+ksFCqbk9uyabdakq7NANhb0m8Db/4UIQrsbGrNPmE6hztkkTfX1fkQXKaQX9gzd+zIZdJ35HvbL9qxbN40b8aLhmRn9m4VXAyE/9kS8lVLflaHa8dRu9cCcHCWa9ciCgLF/fue4g63PTe2zAEmevjPFU0CnA3RW5Lx0c0vFbWsNncAACAASURBVAO6Mt3kw9ih09SZ/Z4Iuk3noHARdVy717r4DICc7d61iAJAonHKW6wYewdcfuC3DI0vFQOFUQzk+9q+lu9Pn+ZzhsBLdmb7objRdA4KDwFcu9e6UgDk+9oOBvQYN65FFBSq0TjYRaCLTI6vwHSoLIaD1flM+g92pu0Kvb6Fm4WNS6LpKgUeN52DwkGBE3K97R1uXMuVAkBUznXjOkQBsitC/f+FphO8wuEKucFOxgZzfenl+WWt80wHMk261xdi6nwQQM50FgoFseBOG8CVAkCh73HjOkRBoYhG/3/vDXNaALzRdI7XMVUU3Yhbf8r3pW/eN4tYvxLdw0+L6tWmc1BIiLhyz625ANCeoxsD9g2DqHYR6f9b8YaF8L//X4k4FB+Fyh9zmXRmb//sVtOBTEl2D61U4Cemc1DwKfAO7al9K/+aCwB75q63A2A/jyJFEZH+v2O2/1+BRgE6Y07Ds/lM+xfq9RkBEe0GWwE0san5melTar1I7S0A0XfVfA2iAFFgZ9OcbDQeyhKEbXauCdDP2Mn4E/lM+xmmw/gt1Tn0PCBfMJ2Dgk+Amu+9tRcATu0hiALmgSj0/8fX/x9pOkd1dD6g9+R722/dtbRjhuk0fkqOyVIAg6ZzUMCJ4QJg19KOGRA9sdYQRIGi8oDpCG6IleKLEOz+/0QEoh9pbHAer6fZALl6IC+KL5nOQQGnOFlXzq/p5N2aCoCGeGkReL41RYyqs8p0Bleohm36f386AL0rn0n3qIa6oClbAk1fBzBsOgcFWrxQsBfUcoGaCgAL1um1vJ8ogHY1tQ39znQINwiwyHQGF8UAfN7uS9/sxtPPQSfd6wsQ7hBIExCYKwAgkfmGQQQAUGA1+/+BdrE9M/0jXdqRMh3Ea8VY6WsAxkznoOBSqJkCQFfOn6rAcbUMThQ4KqtMR3BDBPr/B3KW3eD8SHsPS5gO4qXJl21+UYGfm85BQSYn6nWzJlf77qoLgEKhcBrY/6eIUXEisQFQhPr/+/NuW3I3R/6ZANVbTEegQIsXUo1vq/bN1bcApLapB6IA2tXUMvSY6RBuEIRu/X81/j7fn/6U6RBeShVjPwc3BqIDUEurfhav+hYAcGq17yUKqDUR6v8fZTqHH0Txn/ne1sgWO3L1QF6Be03noABTVH3MdlUFgK48qQEA1/9TpCiwynQGN8TG4gsQ3f7/q8Ug1jei/FCgBdxlOgMFmby52pUxVRUAudHs8QAi+wtH9Skq+/8Dodn/3y2H2Y36L6ZDeKVoyWrTGSjQJo3Mbj+mmjdWVQDERGo+hIAoYHZHpv8vdXg6p+oV40cfR07z7MEnAew2nYOCK+7grdW8r7oWgMMCgCInGuv/e1tnA3q06RwGNMdj8X8yHcILciFKEPzedA4KLhWt6p5c3UOAolUvOyAKIlVEYvlfDLGFqJ/+/19Q4JLI7g2geMp0BAow9WkGYMeyedMAHFrNYERBpbGI7P9f37tzzsxbI39tOoQXVOQZ0xko0I7Q3hlTKn1TxQVA0hp7E+r0GwZFlGBP05bhaPT/IYtMZzBJIGebzuCRAdMBKNDERuL4St9UcQGgMbyp0vcQBZriAelB0XSMWtVx///PNKIFUElZANABCaTie3PFBYA4OKHS9xAFWWT6/yL1tP5/P3T++EZIkWIptpnOQMGmVuVfzit/CFCUGwBRxFiRKABQ59P/L4mVGg4xncFtjiUjpjNQsKl6XACM77Z1RKWDEAWWYE9q+8CjpmO4oU72/y+DE7kCoFBq2Gs6AwWbAEdWugqmogIgFysdBVS35SBRIKmsiUL/f/fK9CwAVe0GFjUWtOKnoYNuWmy3YzoDBV7jGPJvrOQNFRUAllj1/YARRU5Utv+Nj2rdrv9/LStyx5Tvik+K3J+J3FeEVnQIWEUFgFR4caLAk8j0/zn9/xLVyBVCVqzIAoAmJFLZKqCKCgDHqo8jRqlu7E1tHVhnOoQbBFhkOkNQOCovms7gtsaiNc10Bgo+gXVkJa+vbAZAhS0AihBZHYn+f1/7TAD83RwnMR02ncFtJRSnm85AwadezQDoynQToPMqTkQUUCoaien/uOMsRLXnekSQAs+bzuC2mCMzTGegEFAcWslKgLI/NEaKcnglrycKPmuV6QSusNj/f5lia9OS7AumY7hNIR2mM1AoxEd1zxvKfXHZN3SrhMOqy0MUSHtTDS2RWP8Ph/3/lwki8UzHawhnX6lMsVjZh/WV/43eUp4ASNGhWCOL142ZjlGr3X3tM0W4/v/PZK3pBJ5wrINNR6BwKDlS9pf1sgsAcTgDQBEi0dj/n/3/vxRT/MR0Bi9UuryL6peg/C/r5X9wiLIAoMhQlVWmM7iC/f9Xer6xe/Bx0yHcpj2IK7gEm8ok5X9Zr+CbQ/nTCkQBtzeVaI1Gr5j9/1f6tukAXhid0Xo4gKTpHBQW4u4MgN48Lwmgveo8RMGylv3/yBlzELvJdAgvlMQ61nQGChM9WFee1FDOK8sqAAq5Yge4zzhFxyrTAdwQUz0d7P/vo/K95q4XsqZjeMFSPdl0BgqVmD2WTZfzwvJmAIo6t7Y8RAGi+kJ+efqg8eOtQ0sgi0xnCIg8VP/FdAivqMgC0xkoZBwcVM7Lyvv2IGABQFExkkykb09dkd2E3QMF02Fqo4tMJwiIr6SuyG4yHcIL2jtjCoA3mc5BISNS1j2bBQDVm5fX/0sPQnvG+q6lHTMEqPvesAjWJbdN/w/TObxSkMZTAfAkQKqUizMAcLgNJUVDVPb/b3AWoM77/wrshFgfkJ6nRk1n8Y68y3QCCh9FeV/ay/wAKW86gSjotCSRKABiWvfr/3MAzk4uGVhvOohXVCEq8j7TOSiEypy1L6sAEEFrbWmIAmEklWx7xHQIV4izUYHHAajpKAbsFcF5TV3ZaG77Oy7Xn34TFPNM56DwEUfKumeXtwpA0VJbHKJAeDAK6/8BINk1tLypK3tCUZ0WBT4AyE0AnjWdyweDJUtOT3Zm7zYdxGuW6vmmM1BIic4p52XxiV6gCrH7UNbFiAJNdZXpCG6b3D28BcB/j/8gv6x1HmLWGYAsguhClPkwUBgI8MMxdRZPXjK8xXQWr2kPLBvyQdM5KLTK+tI+4eY+O1ccND1RKm6vPQ+RWerg1KYrsg+azuGnfKblEGh8IUQXQbAwlFPKgo2q+HRTV/a/TUfxi51p+yuF/MJ0DgqvpNpTpXv77gO9ZsIZgFSp2BLatVJEfzaS2jH9t0AkN4vbr1TX5ucAPIfxffLzfW0Hw7EWwtKFUJwC4EgEdzXBcyram3Kab5Tu9SHfs6FS1qX1+XgHuaWgTS1AjQWAIzoHyl2AKfQejPZysfKkOoeeB3Dr+A/0ulmT7abkSQrnZAtyskJPAHAIzBUFOSjuFMF3E9uyd4Z5r4Zq5XrbOxR6jukcFG4ad1oA/OlAr5n4GQBgJm//FHoR7P+7Qa7dugf7zkZY9dI/0+tbmnNNcpTlWMcJ9GhVORIWDhlvHyRcjmAD+oSIrAZkVaJB75XF2ZzLY4SL6LUAyjrMhWh/xMGMiV4zYQEgKtPciUNkjko01v/7Qa7ZPALgkfGfl6lCcn1z2yyrNB+qh6haswTOTKjMgGAGgBkir/3QUUVOgR0iOgSVYVEdgsiQiPNs49bhP0gPij790QJvJDM3LSh93HQOCj8VmT7Ra8qYAZBpwl4UhdtIatv0R+qt/+82ESjwQhb7/kOuMZ0nikRK10KRNJ2Dwk/UmfDL+4R9PoFOWEUQBRz7/xR49vKON4hisekcFA2KiWfvJywAFGALgEKO0/8UfCpOL9x/xoLqVDnt+4lnAPgMAIWcgg8AUrDlMu0XQPAe0zkoOlQmnr0vYwZAp7gTh8iI3L7+P1Ew7e2f3SrQPtM5KFoEmPDePfEMgKDJnThERqxl/5+CShUScxq+AXC7dXKXKlITvaaczT5YAFB4qTxgOgLR/uT70p8EcJbpHBRBguaJXlLGKgAWABRiMfb/KZjs/rb3CPBF0zkosmqfAVC2ACi8cslSE/v/FDiFvtaj1ZHvoYy9WIiqNOG9e+K/fGX0EYgCSfFQ/R0iQ0Fn97Uf7qj+EsBU01kowsr48j7xMwDKGQAKK1llOgHRKxX6247UfedStJvOQhFXxr27nBYAp6gonNj/pwAZ6Uuf6DhyH4A201moLkx47y7nIUAWABRG7P9TYOQybe+3FKsBtJjOQnUjNtELyrm5mzoXnKh67P9TAOjtiNnD6f8H4HMAeLI6+WnC+3s5BQBnACh8ePwvGZZf1jrP3mzdAsEC01moLnEGgOqUOqtMR6D6pD2IF2akP6EWvgDFZNN5qG65UgBMeBGigMkn0fwb0yGo/uT72hbkVXoFOB5qOg3VOVcKAKKwYf+ffJXr6zgF6vwLFGcJe/0UEuUUAKUyX0cUEFz/T97THliFWR3vUXWuhDrvMp2H6FVKE72ABQBFjziReABQe45u5EmGwZPrT88V1Q/bkEuhzjzTeYj2w7UCgCgs8kmn+WHTIdxgz9y+Op9JT4HgQThYawkebOzM/kGE3WW/jW/fe64AfwsHJwPCaX4Kugnv3RP+Jc73pXfzSVYKkXtTXdl3mg5RK+2dMcWW5Da8tkjfpoIHRfEgVNcmJycekUs22iYyRt2OZfOmJeNj1wH6XgBzTechqtCuVFd22oFeUM5hQI5rcYi8JojE9H8BqdMBfb3fz5miOAfAORCBvXe0aPelH3eAtVBZUxTcO6VzcJvfeaNo+lUbd+aXp/8TIimIfhh8uI/CxZUWAHuQFCIR2f/f0oVlTvTHVXGSACcB2t2gcHK96d9D8ACANYrY6uauF7Leho2u1BXZTQAuyi1Pf00sfBXAW01nIipTcaIXlFMA5F0IQuSHyPT/VXVhlV84LREcB+A4AJ2CEvKZ9LMA1kBllTbI3U2XDQy6GrYONF2RfVAVb7cz7RdD9CsAZprORHRAgtzEL5lAvi/9DBRHuJOIyFPR6P9fN2uy3dS4HZ6tvpENAO5R4J5UY+IuWbxhlzfjRNOupR0zGhv0i4BeajoL0QE8nerKHn2gF0x8GqBOXEUQBUJU+v/NydPh6dJbnQ/opQK93R61X8xn0r/K9bVdaa9ome/dmNEx9eqB7amuwcUC568BvGA6D9HrEZl49n7CAkDBAoDCIiL9f3UW+jhaI4AzRGWZlmLP5jPtz+b60svz/enTtIfngBxIsmv458nG5LECfN90FqJXU8XIRK8p5xecBQCFgR2Z/j90kcHR54uiGw5W2zPTm+xM29KRTNubzeUJNlm8YVeiM/t3orgCALefpiBxYQaALQAKA4nG/v963azJgJxoOse4doVcZUEeyfeln8ln0p+3l3e8wXSooBGBJruzvY7g7QCeN52HCACkjC/vEz8DIMoHhCj4NCL9/6b4aQji1tv7HgTuUcv5Yz7T9nC+t+0f9fqWZtOxgqS5M/toyRp7K1QeMZ2FSAUT3rsnngEQ2elOHCIPqbPKdAR3WIsMByiDnAyRm+xkLJvPtK8sLG85xnSioJi0ZMtwcnLDAihuN52F6puo7pjoNRPPADhgAUBBZycnJyPS/4efDwDWagqglzpW7Il8Jn13rrftfL194jPIo04u2WgnW7MfVEW/6SxUvxTCGQCqA4KHorAfvvbPngQgKP3/SgiAM0XkB/bm9J/svrZLtSeAbQwfyYUopbqyXQqsMJ2F6pMoXJgBgLIAoGCLSv/fiZ0OoMF0jhodoior7ZnpP9Z7ISACTXVmOyG60nQWqj+Kib+8lzEDwAKAgs6KRAEAtcI0/T+RfYXArPTv871tH6rXPQVEoMmtQ5cDcpvpLFRfpIx7dxkzAODJYhRkdnJS/NemQ7hBBYtMZ3Cd4giI3GbPaP91rq/9babjmCA9cJLbpn0MggdNZ6H64ZRx7564ACjKZnfiEHlBfx2J/v91syYDOMl0Ds+IvkVU1+Yz6W/v7muvu4N0pOep0ZKMvR8AD2IiX1iO9eKEr5noBXltZAFAASaRmP4P7Pp/dwmAixtUn85l2i8wHcZvk5ZsGXYE54InrJIPErY9PNFrJiwApl25cRe4xSUFlrXKdAI3KKwFpjP4aI5Ab89n2r8zvvKhbjR3Zh8VxadN56DIy8u1W/dM9KIydgKEAphwKoHIgMj0/4EI9v8npB+2nYZ1e/vbTzCdxE+J7dk+Pg9AHivrnl3Wk7kiLAAoiCLS/9/3LTi6/f8DOzzm6EO53vTfmw7iF+mBI0X8A4DQ/92loNKyWvdlFQCqmLCXQOS/iPT/nfipCP/6/1okRXBbri99rekgfklemf0DIP9hOgdFk0p5D++XuTZXX6glDJE3otL/l0WmMwSAJYov2X3pL5sO4pfkpIavAhgwnYMiSMs7lbK8AkDBAoCCppAcQyT2/0e49v/3lCquqZciQC7ZaIvgS6ZzUARJeYVleQWAxQKAgkZ+LVcPhH451Xj//82mcwSJKq7J9bZ/0nQOPyS2Tv86UN63NaKyOdhUzsvKnAGIsQCgYFFl/z/CRPTLud62803n8Jr0PDUqQF3MeJB/JFbel/byVgGosACgYFFZZTqCGxSR2v/fTZaI3Gr3tR9uOojXEtbYrQD2ms5BEVJ0cQYggcQAAKemQETuKSRLEpH1/7rIdIIAa1bVW6J+oqAs2bIXkB+ZzkGRUUzuyGbLeWF5MwDd6wvgHtYUHA+z/1833pqfkb7KdAivieotpjNQVMgm6UGxnFeWf0SnYH3VeYjcpFhlOoIbCqWGt4P9/wmJ4J/39LbONp3DS4nt2XsBPmxNbtBny31l+QWAsgCggJBobACkwvX/ZZoaE+tzpkN4SXrgAPiF6RwUARXcq8svAIANVUQhcttoslHZ/68zAnxs19KOGaZzeCoiK1vILLXE/QJAtfyLEnno17I4mzMdola6Mt2E+t3/vxpNDY36UdMhvOSUGu81nYHCz1J1vwCIA3+qLg6RqyLxLalQwGkAGk3nCBVHLzYdwUvNVz0/BH7OUo1EHPefAWgoyh/BpYBkXETW/1vC9f8VEsGxud72DtM5vCVR2d6azCg2OpPcnwEYX3bF5wDIpEJyTB4yHcId7P9XQQTOe02H8Fb507dEr2P9+LL9slTyECBU8H+V5yFyTTTW/69MN0G5/r8qVsSfmxDllyyqmkCeruT1FRUAoniqsjhELorK+v8xnAr2/6ujcqTpCF7SkpTdvyV6NRXHuwIAohVdnMhFY7D0W6ZDuEHB9f81OMJ0AC85WmQBQFVTx8MZAAfCGYD6VRRBJ1S+A6CsfabdpMDKVOdQNI5NVeUDgNWbajqAl5pTc7ebzkDhFYtbFd2jKyoAmpobnwbK22OYokVEf5TszPanugcvSnVl2y3gSBF0CvBDAXZ4PPymQrExEjvB6fUtzQDeYjpHiCW0p8KZyxCRxevGAJRM56BQGm18ceozlbyholO25JKNdj6T/j8Ax1YUi0JPHfS+8v8nurLPAHgGQL/ejlhuc9ubROSdojgDwGkAmlwaeq+jOG/6VRt3unQ9owqJ2NvA/n8tBDMOawDKf9I5hPIAJpkOQeEiwNPS89RoJe+p4phNfQwQFgB1RIBHk91Dq/f77y9ECRj6LYDfArhOe45utGfvOBmOvGN8udvbAKSqGHqzAz27uXvoseqSB4+KLgLEdIwwy1eyzCmUFDaEBQBVRoGKPycrLgBU8JgoLqr0fRReKtI78av+bLwKXTP+8+/ae1jCtkZOgco7oDgdglNw4G84owp8o9iIz09ZPLS1hugBxAcAa7TFdADPCWzTESh8xI8CQBx9DMJvMHVkc9JJfa+WC4x/Y3tg/Ad6O2KjW9oOh8rhJQeHQzAPAERkpyp+l9L8L6V7++6akweMrkw32aPs/9foRdMBPKdIcpKIKqWqv6v0PRUXAEmMPmYjqeA8Zr240e0p1/GWwf8B9bWxFNf/u+JJ0wG8pAqx+zDddA4KHU2i8Hilb6r4adrxb2Y8sKI+jJassZWmQ0SFcvlfzaqZ5gyVm+ZPARAzHYNC55lqZk2rW06jPLCiLqj896QlW4ZNx4gM5QFAtapmmjNM7LH8NNMZKIQEVd2TqyoARPTX1byPwsWJlTKmM0SFrkw3Qdj/r9Hu5PYZkf7yURKL0/9UMYFWdUhaVQVAydFI/xISAGBt85LhR0yHiAp7TN4GIGE6R8j9vNJ1zmETV0mbzkDhYzmWfzMATcn0E9i3WQVFlEKWm84QLc4i0wnCThU/Np3Ba45qpM86IE/sbWgd/H01b6yuBbB43RgU66p5L4XCYKqx9UemQ0SKw/X/NVFsTRWtyP+dFOCNpjNQ6Pxm38qqylW9p7YAa6t9LwWbAr3je5KTC9j/d4GlX5OrB+ph1pEzAFQZ0QerfWv1h2pY1gNVv5eCLFcU+abpEFHC/n/N8o7GbzQdwh9sAVBlBFL1vbjqAiDR0LgWPLUqguS2KZ2D20yniBSu/6/Vdc1dL/h+BLXfdq44aDqAVtM5KFTGEjJW1QoAoJYWwOINuwSoeOchCjYL0mc6QwQtMh0gxDYlG3G96RB+SDrO20xnoNB5VJZs2Vvtm2s7V1urn3qgQLo70TUQ6a1W/aZLO1IATjadI6SKEP2ILM7mTAfxg6pzuukMFC4C3F/L+2sqABzLYQEQIaJc+uc2u1HfDvb/q6Ii16Y6h+rpM4YFAFVGZL/HtJejpgJg1GpYBT4HEBXrE9sHf246RNSI6lEA1HSOEPp6asngMtMh/KI3z0sCeLPpHBQqxURDwlwBMO3yTTsA5X4AESBAr/TAMZ0japJd2cxYI+aI4lxRXCfC/TMmJPhWclv2EyL1UzjZI4WTwZkiqszDsnjDrlouUPFxwK/jbrDHGXa7E2rfYjpEVE1ZnN0K4I7xH+SXpw+CyBkAzoDoOwFw+9d9FMB/JLdme+qvGOVGUVSxu2u9QO0FgOrdEPnnmq9Dxijk5mqOkqTqpK7IbgLw7fEf2Dekj1BLF8CShVAsAtBuLp0ZCuyMCT6a6MxGfrvf1yPAuXUz3UGuUKf2AkBqDtFzdKM9c8c2AJNqvRYZ4YjGDk92v/Cs6SC0z0hmblrgnCrAmQDOBHS+6UxeUuBOqFzW1D04YDqLCbkbO9ql6LwAFz6PqT4osDO1LTtbelCs5Tqu/IXLZ9J3AjjLjWuRv1RwR1Nn9lzTOWj/8n1tB8OxFkJ0EYBTAbwB0bhZrBVFT7I7e4/pICbZvelOFfDobSqbAD9MdmXPr/U6bjwDAAF+piwAQkl46l/gpTqHngdw6/gPdq44aHqyNHaywjpZoScL8BYALUZDlq+owM8sRabeb/wvUeA80xkoXFTVlRVb7swA9LUdDJWNblyL/CS/T3YOHldPT1tHVX55+iCJyXEK51ioHA/gWACHw6Uiv0ZFQNaq4CeOjP5/k5ZsGTYdKCh2rjhoeqJU3AygwXQWCg11EOtwY3tsVz4cUp1Dz+cz6Sex70OHwkKdXt78o2H8wcJNAO586Z/pzfOSuZHRowQ4XBydD0sOhcqh488UdMCrNoJgDxSPieBhB/pQYSxx3/SrNu70ZKyQSzhjZwPCmz+VTYDH3Dobw8VvB3InoCwAwmNbshi7zXQI8o5cstEG8Oj4z1/Q3sMSBSc3Ty2doxZmWbBaFTpbFbMEmA1g1l9cSzD95fcqRgDkBdjtKF4UCy8CyALynDr4Q1NXfT7MVxWVj5iOQOGi+uciv1auFQDq6J1i4TNuXY+8JjfVyfnq9Dqke30BwB/Gf8iAXG97B6BnmM5B4eLEHNcKgNoOA3qFVFv2YQBb3LoeeaqoltbJ+epEwSTARwHETOegUBlu2jLs2m6irhUAciFKAH7i1vXIU8NS0gW5GzvqbsMZoiDQHlgQXGI6B4WM6I/d3CXT1SeEBc4PFNbH3LwmeaIDIrdJ0UE+074BirViOWt0TO9KXTW80XQ4oqgrzEifFfUNnsh94sj/uHk9VwuARGP7PYXRoR2KPz8wREGn8yGYryofQVyQz6SHBFgD0XtYEBB5QwXdpjNQ6GxLbM+ucvOCri8DymfavwPoh92+Lhnz54JAnbtTXZufMx2IKMwKva1HOWL9HtHYzZH8IvhWqjPr6gy765uEONAfWAALgOhoU+ACqFwAxP5yhoAFAVHFHLH+Cbz5U4UE1g/cv6bLdGlHym5wXgQPB6oXz0FwPyCrAGfV+La1RPQ68pmWQ4DYH8Cd/6gyu5La1DK+fNc1nlShbAPUtZdnCAS6NtE5/JTpQERBkc+kbwLwj6ZzUMh4MP2/77IesDOt71VYP/Pi2hQ6zwN6P9S6D1K8ny0Dqlfj3/6fAdBoOguFiwjenezM3u36dd2+IABoD+L2zPQAwnNCGfmHMwRUl+xM+nYFLjCdg0JnONmS7Rjfa8dVnj2IksukMwJ0enV9iowXAL0PYt2rovc2Lcm+YDoQkdtyy9NvFwtrwIf/qEIKWd7UNXilF9f2rgDY9xd+rVfXp8j6EyD3KfTeUrx03+TLNr9oOhBRLbQHlj0z/SCAU0xnofBRsd7a1DnwsBfX9qwAUIXYfek/ATjUqzEo8hTA7xVyrwW9N19sfIDHylLY2H3pJaroM52DQkjwh+SS7JFeHdvu6XRUPtP+OUD/zcsxqK6URPA7B1gLlTUpzf9SurfvNh2KaH9GMnPTFkpPA5hqOguFjwLXNHVlv+LV9b0tAJanD4KF5+DioUNErzAK4GEA90L03uTWGb+WnqdGTYciAl6eBb0DwFmms1AojRbjpbletkE9fyAln0nfBeBdXo9DBCCnKhc3dQ+6emAGUTXsTPpyBfpN56BwEtH/SXYOebpqxI9v5t/2YQwiAGhS6LOmQxAV+lqPVsCzqVuqA4583eshPC8AkmPWDxXgg1vkOQV2NrVmnzCdg+qbXjdrsqPWfwNImc5CISXYmNievcfrYTwvAOTq3Cw3WwAAGm1JREFUgTyA27wehwjAA15slkFULlVIoanxmwCONp2FQsyRb0oPHK+H8eXhvJg6N/oxDtU5kftNR6D6Zve3/wd3+6MaldSn1rkvBUCie/hpAKv9GIvql0JXmc5A9cvua78Mqp81nYPCTQU/a+oeHPBjLN+W56mCswDkpV1Nc7KPmw5B9SnX23a+qmZM56DwsxTf8GusuF8DpbZP/4E9c8eLAOb4NSbVDxX/+/8jmbY3iyONqR3Z30gPin6OTcGRy7S9XyD/BSBmOguFXjaxLevbSbq+zQBIz1OjEPGtsqE64/jf/49BPiUW1tqz0tvzmfSdub72q/f2t5+gPdz4ql7k+9ovFsh/A2gwnYUiQPRbfn6Z8PVkqvFtMZ8Dz8MmlzmOvrn5iqF1fo03vsvbMF5vRkuxVSxdBbV+BcG9yc7BP/qVi/yT62u/WlS/Ap7wR+4oOMWGQ5qven7IrwF9/4ub70vfDMVH/R6XIm1XsiU7088WQKGv9WhHrd+X+fJhAVZD9B4d07tSVw1v9DIbeUt7EM/PSN8ggiWms1CkfDPVlf24nwP69gzASyy1ljpwLgarZnKJAqv97v+rWgsreHmrAhdA5QLEBflM+o+A3quw7i1padXk7uEtngUlV+Vu7Gi3i85/CXC66SwUKWqJs8zvQX0vABJdA0+Onw/wV36PTZHle/9fFQtrKGEPB+RwgX4iLhbymfYNAO5R4J5CseFuHnkcTIW+9N84ReebAGaazkKR87NE5/BTfg9q5GElEXzVxLgUTX6v/1eFQFDJDMBEV5wP6KUCvT0ZH91i93cc5t61qVY7ls2bls+0r3QUPwRv/uQJWWpiVCMFQLIze7cAvzMxNkXOrqaWocf8HHA003okgBaPLr8rsWVgg0fXpgrZvelzkvHRJwG9FGxbkgcUeDzVNXivibF9bwG8RFWWQfQWU+NTZKzxvf8v1iKvri2QVX7sAU4HNpJpe7MFuU6BM0xnoWgT4Mumxja2Xjm5fdr3AAyaGp+iQdVA/x9Y4OHVeZ6BQYXlLcfkM+nvWZDfgDd/8t6mZGPb900NbqwAkJ6nRhXoNTU+RYPGnFW+jqcQwM3+/18SWKu8ujbtXy6TPjXXl/6JY8WeAPB34HQ/+UBVemXxujFT4xtrAQBASu2v2ZL8LICpJnNQSAn2NG0Z9rf/v6LtjQBaPbr8tsZtA74/CVyvtHfGlIKV+ABULlPgBKjpRFRndqcSCaO74xotAKR7+267t+2bKnK1yRwUUqqr/d6DXx1rITy6Uwjkfr/7/3Zv+1lqOW9VWE/GxHmyccvQn6J8roGuTDflR3GOBfydDbwXiqTpTFSfBPiaLN6wy2QGowUAABSd0pdjsfhiAM2ms1C4KPzf/1+hizy8+irvrr0flvNRqPytQOGowJ6ZHrUzeFohv1fok5ZYv9ex4tPJ9uEX/H7Y0g2qkNH+1qNKGnu3QP/KHsUCAVL8sk+G7R1T5yumQwSiz2Vn0tcp8CnTOShcVK1TmroHfuPfeBC7L52FRy0AK2Ydn7h84Akvrv16DniewWuNAtgA4FlR+RMsXQ/V9dD4+sT2F54PwqyB9iBemN5xCOT/b+/+w+Qs63uPv7/P7O7MbBLMDyC7swE9GiQRrW2prXokBk3tUfDY1lNbLdYLqqawPwK2iqd6HdNaf6AeILvZg4FLvUR7OGDx2AOW2qZSQqK0igUEkRIphOxsloTNr83OzGbm+Z4/CF4QE5Js5pl7npnP6z8uwjyfDdk8n72/z3Pf8TI3+yXw1wGvAxaGzibyPGafzg+MfSx0jOArAAAzXXy+8yCX4swLnUVSwtiff3r7jxp5yZn1hbNJcv7/1PbjPVugLmZGe17B8R/P3QUsA5a5+aEpiIHVKC8q1EojTJgxHkPR8CJu47gXLYrGa1abyNCxu0plag5MWf/Oqdnk3be+b1EXLIpjFkawyCNOxTnb4OWOLy/DUogPHTSmn/Glae2tRJngP/1DkxSAU1YXd5XW964D+3joLJISbpsbPv/HVrbS/N+JVtbpozJAwZ2Cwbk/X1g0w92JPMKJydBJGSiNFNxgj8N+YMqM0i9kc+aBdRz6h1MwFuFu/szHPvN/wZ/9OkRS5Zr5l23bHToENEkBAMh15r9QmSn3OywInUWan1vj35d3PLHX//AA7/97cq8zHoMd+j5fAOBHvYMf+hdNMagUOXkOeyrVrnWhczwr2D4Ah7PVj+11rOGnIUlaBXlfPrENgKyjsV+PO5bshkYicjiDq5rpsK+mKQAAuWjmGkBHo8qxTOU7Fzd0/l8ZKSwDCgl9/GSg+X9S5xmIyOGcXbnpmdHQMZ6rqQqA9e+ccp0UKMdkdzd696xn5v/JCLH/fx3n/yJyHDyyz9iVu/aHzvFcTVUAAPKl2npgInQOaV6a/9fjmsHm/yLtaDzf6V8MHeJwTVcA7MMTBxy7KnQOaWJx4zcAQvN/EZklcz5tq4vToXMcrukKAEB+bud1GI+HziFNaSqf7bm3kRcsX1s4m+Tm/41//3+kZzma/4s0iD2WpfuG0CmOpCkLgF38eNndtDOg/CJnc8NPz4qS2/43yPv/UXR+I68n0s5i/E9taGsldI4jacoCANA9OPYNAuz1Lk3OaPz830zzfxE5ccadcwaL3wod42iatgAA1CIuh/QdQCLJcQtSChO7YWr+L9KyalEUXR46xAtp6gIwt3/sPpyvhM4hTWMq39nzw0ZesLy+7+W00vv/mv+LNIZzfSMP95qNpi4AANXO2seAoGcmS9PY0vD5P/HKpD7ZoPHzf4tWNvJ6Iu3IYc/BLP8jdI5jafoCMO/Siafc+VToHNIEQrz/7wnO/wnx9Wj+L5I48784ZXVxV+gYx9L0BQAgP7lgHfDvoXNIWF5rrfl/5I2f/2MqACIJ+2m+s9BUW/4eTSoKgK19aMbgw6FzSFDT+d0LQsz/+xL6+MnOybEfJ/TZR6T5v0jyjPhDjR9Vzk4qCgBAbrD4/4DvhM4hwWy2tQ/NNPaSmv+LyAnZmBvccUfoEMcrNQUAIIprfwakollJnQV4X96xBF+XC/H16PU/kQTNRJEPhQ5xIlJVALJrJh7E7POhc0jjuds/N/6irEzqo4PM/xN8nkFE+Ey2f/zh0CFORKoKAEAuzv8lkKrfZDlpjZ//r1tyFq00//9fvcuAnkZeU6RtGI/k5nZ9NnSME5W6AmBDWyuY/wngobNIw2xp9PzfrbYyqc8OMv/3aGUjryfSRmKM99vFj5dDBzlRqSsAAPmB8U1gTXm6kiQhwOt/Uau9/+9a/hdJgDvX5fuLm0PnmI1UFgCAXFf2I0AxdA5pAPe+A+t6z/VbyDTumsnNy6tR1NACoPm/SGK25yn/eegQs2WhA5yM8vq+C939ttA5pGGmgHvc2GjGllxH778k8b5teXTJUo/jR+v9uYdM5p4untbIEUBltHd5HNtPGnU9kXYRGb+dHSj+begcs9UROsDJyA2M3V4e6fum478bOos0xFxglTmrcCjPjE+VRgp1LwTuLfb+v0cr9ciMSN3dnOabP6S8AABUo5n+jrjzfIcFobNIw71wIdi54F9n9fCg2xuTu2Fq/i/SAvbGZD4UOsTJSvUI4Fml4d4PYHZ96BzSdA4A3we2mLM5O7lg0/EUgtJI4QngzCQC1SL7lbn9Y/cl8dlHUxopjJHckcYi7eiS/GAx9UfVt0QBcMfKo4V/wjk/dBZpYsZ+3O927C48+uf85PYf2Vqqz/0l5eEzXuZW25pQgsbP/0cKy2LtmyFSTxtzA8W3mKV/rpb6EQCAGT49bH9k5vcDC0PnkSblzAN7m8HbsJjyosKB0sjzVwjK0e7zk/q2NtjU8Pk/tlLzf5H6cNhjMX/cCjd/aJECANA9NLZ9eqRwmcH/CZ1FUmMOsApY5QblU3fvx9mf1MViC7H/v+b/InXj9oH8mrFtoWPUS2r3ATiS7sHizeA3hs4hKeXMI8FZeWyN3f//EB0AJFIfX+oeGvub0CHqqaUKAEAuqvYDSb3DLTJbk3N2jj3QyAtWRgrL0MN/IvXws9z0zBWhQ9RbyxUA6985FUfxH6Jjg6WJhJv/i8hJqrrbRXblrsTGg6G0XAEAmNO/4wfAp0PnEHmW5v8iaWVru4fG7gmdIgktWQAAck8X/wrje6FziABYbPt8w7mdDb6sCoDIydmUWzyWumN+j1dL7ANwNKWRxf8JMvcBp4TOIgJMA/9mzmZgY5buu21oayWJC5WvLZztGX6axGeLtIm9mL86PzD+ROggSWnpAgBQGu77I8y/GjqHyBEkVgjKw72r3eyL9fgskXbkznu6h4o3hc6RpJYvAAClkb6vgV8UOofIMUzjfB+zu4j8zlmfZQCURgr/G3h3nfOJtIuv5AeLl4QOkbS2KAB+9ZJ8pTPe7PCrobOInIAS8KOfrxDM69psFz9ePq7/UPv/i8yKw/35Ll5vq4vTobMkrS0KAEDpmp6X0BH9EFgUOovILB004wFiNvIChUDzf5FZm7RM7TW5yyYeCx2kEdqmAACU1xd+0507gEzoLCJ1UDXj/sMLgeb/IrMSG/GFucEdd4QO0ihtVQAASiOFTwBrQ+cQSUAZ/B53W2jGL4UOI5Iu9vH84NinQqdopLYrAO5YZX3hVoffCZ1FRETCc+O2fH/xHa1yyt/xatmNgI7GDC9Vuy4BkjrzXURE0uPRfGfuve1284c2XAF4VmVkyati4u/zzJGwIiLSfg5Ece212TUTD4YOEkLbrQA8Kzu4/cfufCB0DhERCcPhj9v15g9tXAAAuoeKNzm2LnQOERFpLHO/unuweHPoHCG1dQEAyC8e+1N3/jZ0DhERaRT/u+zk+JWhU4TW9gXA3kUtnzl4kcG/hc4iIiLJMvhRLqr+vq2lGjpLaG1fAACsf+dUrdp5AbAtdBYREUnMWOz2DuvfORU6SDNo27cAjqSyvuecmkebDeaHziIiInW1L8pE52Uv2/5A6CDNQisAz5Ed2PGQxfa7wKxOYBMRkaZ00Iz/ppv/86kAHCa/ZuxOnEtD5xARkfow98HcQPEfQ+doNioAR5AfKn4Z7DOhc4iIyEn7ZG5ofEPoEM1IzwAchTtWXt93I/hFobOIiMis3JwbKL67Hbf5PR5aATgKMzzn+fcDd4fOIiIiJ8ruynn3+3TzPzqtAByDDy88pWy5fwJ+LXQWERE5NoP7ypmON82/bNvu0FmamVYAjsGGJvcd7OKtYG27X7SISIr8eMZslW7+x6YVgOO0/7rFp3dUM3cBy0JnERGRI9oaVztXzLniifHQQdJABeAETA/3LbHI78Z5SegsIiLyPE9SjVfkr9jxeOggaaECcILKo0uWehzfBRRCZxEREQCeshorcpcXHwkdJE1UAGahfG3hbM9wF7A4dBYRkbbm7IqieGV2YMdDoaOkjR4CnIXc5cVHMm6/ZaCHTEREwtkXm79VN//ZUQGYpa6hsftjt7cBOlVKRKTxpjF/+5zB8R+GDpJWKgAnoXto7B6wdwAHQmcREWkjB4jtwvzA+KbQQdJMzwDUwYHRntdEcfT3wMLQWUREWtxehwu6B4tbQgdJO60A1MGc/h0/iJ1VwM7QWUREWpXBbvfoLbr514dWAOqoMtq7PI7tH4G+0FlERFrMjojoLdnB7T8OHaRVaAWgjrL94w9D7Tywx0JnERFpIdssjlbo5l9fWgFIQGld4UwiNgJnhc4iIpJy/wG1N+cHJ/4jdJBWoxWABOTXFLfVatXz3HkgdBYRkRT7SUzmDbr5J0MFICFzL39qYqajYyXwL6GziIikjRn3HuzijXMGnyyGztKqNAJImG946YvKM+XbgPNCZxERSQe7K+el/2pDk/tCJ2llWgFImK1+bG/Ou38T7Ouhs4iINDuDb+Tmdv4X3fyTpxWABnHHyusLnwA+ETqLiEgzcmM431+83AwPnaUdqAA0WGmkcDGwAegMnUVEpElUzX0gNzS+IXSQdqICEEBpfd+bcb8VeFHoLCIiQRn7zePfzw3uuCN0lHajAhBIZd3iV8ZR5nbgxaGziIgEMlaL7MK5/WP3hQ7SjvQQYCDZNRMPxtXO15lxb+gsIiKN5s4D7vZa3fzDUQEIaM4VT4xnS7U3unFb6CwiIg30nXxp5g3dQ2PbQwdpZxoBNAG/hUxpou9/Gr4mdBYRkSSZ+9XZnvGP2Luohc7S7lQAmsj0cOHdZtwAzAmdRUSkzqYc3t89WLw5dBB5hgpAk6mMFJbF8E1geegsIiJ18mhE9E6d5tdc9AxAk8kOFn+a8/JrDf5v6CwiInXw7XK169d1828+WgFoUu5YabTwEXM+jYqaiKSPm/O57GTxz20tcegw8otUAJpceaTnrU70dWBh6CwiIsdp0vD35AbHvxM6iBydCkAKlNYVzsTsbzB/TegsIiIvxOA+MrV35i6beCx0FnlhWlpOgfya4rZc1leC3xg6i4jIC/hK9mD0et3800ErACkzPdL3exG+wWFB6CwiIofsA+/PD47r2PMUUQFIodK6wplEfA1YETqLiLS9eyxT+0P91J8+KgAp5WuJKot6Bx37HNAVOo+ItJ0q8Knc4uIntatfOqkApNyB0Z7XRHH018BZobOISJswHnfnou7B4pbQUWT29BBgys3p3/GDXBe/7MZw6Cwi0gbcvpazg6/SzT/9tALQQqZHet9p2PVozwARqb+97lzaPVS8KXQQqQ8VgBYzPVo4w2p8BePNobOISMvY6G4X6/je1qIC0KKmR/p+z/DrgEWhs4hIOjnsicyvzPaP32CGh84j9aUC0MKmrj19cSbq/Dzm7w2dRUTSxeF2OqI/6b50+1joLJIMFYA2UB7uu8DNrwPOCJ1FRJreuOOD3YPjt4YOIslSAWgTPrzwlFKU+6Q5A+jtDxH5RQ52Q85LH7ahyX2hw0jyVADazPRI4T8b3AAsD51FRJrGVmL7YH7N2J2hg0jj6CfBNtM9WNyS6+p9tRsfBWZC5xGRoA6ac1XOu1+pm3/70QpAG6sM97wituga4C2hs4hIgzl/HxlXZAeLPw0dRcJQARDKw4VVblwLnBM6i4gk7lHHPtY9OPaN0EEkLI0AhNxQcWOuq/dXDL/cYU/oPCJSfw573PhozrtfpZu/gFYA5DB7r16ysLMr/oQ5/UAmdB4ROWkxbn9d7az+2bxLJ54KHUaahwqAHFFltHd5HNs1wG+FziIis2TcmYntiq6hsftDR5HmowIgL6g8XHi7m10L/tLQWUTkuD2J28fzQ2M3hg4izUsFQI7Jh5dmK0yvduO/Az2h84jIUY0bfCbr3dfb0NZK6DDS3FQA5Lj58NJsJTrwPnf7C1QERJqHs8sjvpCfiYbtQ9tLoeNIOqgAyAnzzy+eU8pnBsz5CLAwdB6RNjYJjOS8fLW275UTpQIgs+ajp80teWc/zkcN5ofOI9JGpswZLdW6Prvgisf16q7MigqAnLS9Vy9Z2NUZDwFXAKeEziPSwg6Ys77c0XHV/Mu27Q4dRtJNBUDqZv91i0/vrGY+7PBBVARE6mmvwYaDHn9h3tCOnaHDSGtQAZC686tOnVfp7rzEsQ8BZ4bOI5Ji48D1lUzHOv3EL/WmAiCJ8bVElYWFC9z4GPAbofOIpIXD/eZ2dS7bc5Otvvdg6DzSmlQApCFKo4U3eMyVBhegP3ciR7PFnKuyg8XbzfDQYaS16S9iaajyuiVnxZl4wJwPAPnQeUSawAxuN0de/Vx2zcSDocNI+1ABkCAOXPPi3qhjph/sEqA3dB6RAIqYf7lm1dG5/Tt3hA4j7UcFQII69JzAmzA+6PA7QEfoTCIJioHvOnZ9vqvnW5rvS0gqANI0DoycUTCrvdfcPqjDh6TFjJnzdY/8uvzA+BOhw4iACoA0ocNWBd4BdIXOJDILMw7/AHZjfvHYN+1d1EIHEnkuFQBpalPXnr44ynS8z+D9wFmh84gck/GIx3yp1ln76rxLJ54KHUfkaFQAJDUq63vO8Th6rxvvQ6cRSnN5GuxWIv9a7rLiFr3CJ2mgAiCp47eQqewovNmN9/DMg4PadlhC2At804ybsqcXv6slfkkbFQBJNR9emq0wfV4c8XZz/gA4PXQmaV0Gu93tdjduy3f5t211cTp0JpHZUgGQluEbzu2sVMbPd7N3gv82KgNSHxOYf8uwW7O7infaWqqhA4nUgwqAtKzK+p5zakQXmvN24PXoz7scv5+Yc5tnuD23s/g9W0scOpBIvekvRGkL09ct6YtqtQtwe6vDm9BzA/J8ew2+6+53xNbx7TmDTxZDBxJJmgqAtB2/hcz0eO8vW8ZWmbMKWIH2Gmg3NTPuI2YjsDE7uWCTrX1oJnQokUZSAZC25xte+qJKpbwCY4XjK8B+FW1J3GqqwL1mbALblI1Lm2xocl/oUCIhqQCIHMZHT5tbqXW+3s1XQPQG8HOBuaFzyQmZAv8hxmbDNmXt4Petf+dU6FAizUQFQOQY/BYyB3f0vTI2Xuf4a4HfAM5G3z/NwoFHMO6x2O+JiO7p7Bl7UO/li7ww/QUmMgt+1anzynO7Xm3ur4ixc8w5FzgXyIXO1uKqwL/jdq9H/lAU85OZyL53ysDY06GDiaSNCoBInfjac7oOnLbnFVHNl5v5OUa03PFXAi9FzxScqCrGz8ztISd+2M0e7Ijt4c7J+Q/rYT2R+lABEEmYrz2na2bBrpdXo8xSc3uZWbwU7GXAUuBMIBM4YihVsG3gP8PZ6tjPMpFvhXhr165Fj+pGL5IsFQCRgHzDuZ3lg8UCZmdQ8xdjdoY7S4g409wXg/UCp5G+0UIZeAoYd+MpYrYR8aQ5TxKxjSrbcruLRe2qJxKOCoBICvhVp86rzMn2uvnpFrPQzRaYx/Mdm29u8z3y+YbPdbf5YJ1mPtedbrAs+IsMop9/FnQD2cMuUTGYfs6vicH2glfMmHa3KfCDZr7HsSmLbY+b7zF8j3u028z3xPB0ZLYze6Ayblfu2t+o3xsREREREREREREREREREREREREREREREREREREREREREZG0+/93Y8ES+k/o7gAAAABJRU5ErkJggg==",
|
|
56
|
-
blockchainSpecific: {}
|
|
57
|
-
};
|
|
58
|
-
//#endregion
|
|
59
|
-
//#region ../../packages/module/blockchain-bitcoin/src/tx-builder/utils.ts
|
|
60
|
-
init__polyfill_buffer_patch();
|
|
61
|
-
var import_src = /* @__PURE__ */ __toESM(require_src());
|
|
62
|
-
/**
|
|
63
|
-
* Converts a raw transaction hex into a BitcoinTransactionHistoryEntry using an InputResolver to fetch additional input details.
|
|
64
|
-
*
|
|
65
|
-
* This function deserializes a raw Bitcoin transaction hex and transforms it into a transaction history entry.
|
|
66
|
-
* It uses an InputResolver to asynchronously fetch and include details about each input, such as the associated address
|
|
67
|
-
* and the amount of satoshis, which are not directly available from the transaction input script.
|
|
68
|
-
*
|
|
69
|
-
* @param raw - The raw hexadecimal string of the Bitcoin transaction.
|
|
70
|
-
* @param network - The Bitcoin network (Mainnet or Testnet) that the transaction pertains to.
|
|
71
|
-
* @param inputResolver - An instance of InputResolver to fetch additional input details.
|
|
72
|
-
* @returns A promise that resolves to a detailed transaction history entry.
|
|
73
|
-
*/
|
|
74
|
-
const historyEntryFromRawTx = async (raw, network, inputResolver) => {
|
|
75
|
-
const tx = import_src.Transaction.fromHex(raw);
|
|
76
|
-
const bitcoinNetwork = network === BitcoinNetwork.Mainnet ? import_src.networks.bitcoin : import_src.networks.testnet;
|
|
77
|
-
return {
|
|
78
|
-
inputs: await Promise.all(tx.ins.map(async (input) => {
|
|
79
|
-
const txId = import_buffer.Buffer.from(input.hash).reverse().toString("hex");
|
|
80
|
-
const index = input.index;
|
|
81
|
-
try {
|
|
82
|
-
return {
|
|
83
|
-
...await inputResolver.resolve(txId, index),
|
|
84
|
-
isCoinbase: false
|
|
85
|
-
};
|
|
86
|
-
} catch {
|
|
87
|
-
return {
|
|
88
|
-
txId,
|
|
89
|
-
index,
|
|
90
|
-
address: "",
|
|
91
|
-
satoshis: 0,
|
|
92
|
-
isCoinbase: false
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
})),
|
|
96
|
-
outputs: tx.outs.map((o) => {
|
|
97
|
-
const chunks = import_src.script.decompile(o.script);
|
|
98
|
-
if (chunks && chunks[0] === import_src.opcodes.OP_RETURN) {
|
|
99
|
-
const payloadChunks = chunks.slice(1).filter((c) => import_buffer.Buffer.isBuffer(c));
|
|
100
|
-
const opReturnData = import_buffer.Buffer.concat(payloadChunks).toString("utf8");
|
|
101
|
-
return {
|
|
102
|
-
address: "",
|
|
103
|
-
satoshis: o.value,
|
|
104
|
-
opReturnData
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
return {
|
|
108
|
-
address: import_src.address.fromOutputScript(o.script, bitcoinNetwork),
|
|
109
|
-
satoshis: o.value
|
|
110
|
-
};
|
|
111
|
-
}),
|
|
112
|
-
transactionHash: tx.getId(),
|
|
113
|
-
confirmations: 0,
|
|
114
|
-
status: BitcoinTransactionStatus.Pending,
|
|
115
|
-
blockHeight: 0,
|
|
116
|
-
timestamp: 0
|
|
117
|
-
};
|
|
118
|
-
};
|
|
119
|
-
//#endregion
|
|
120
|
-
//#region ../../packages/module/blockchain-bitcoin/src/providers/BlockchainInputResolver.ts
|
|
121
|
-
/**
|
|
122
|
-
* Represents an implementation of the `InputResolver` interface that fetches detailed information
|
|
123
|
-
* about a transaction input from the blockchain data provider.
|
|
124
|
-
*/
|
|
125
|
-
var BlockchainInputResolver = class {
|
|
126
|
-
/**
|
|
127
|
-
* Creates an instance of `BlockchainInputResolver`.
|
|
128
|
-
*
|
|
129
|
-
* @param dataProvider - The provider used to fetch transaction data from the blockchain.
|
|
130
|
-
* @param network - The Bitcoin network the inputs belong to.
|
|
131
|
-
*/
|
|
132
|
-
constructor(dataProvider, network) {
|
|
133
|
-
this.dataProvider = dataProvider;
|
|
134
|
-
this.network = network;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Resolves the transaction input to a `UTxO` object providing detailed information
|
|
138
|
-
* about the input, including the owning address and the amount.
|
|
139
|
-
*
|
|
140
|
-
* @param txId - The hexadecimal string representing the transaction ID of the input to resolve.
|
|
141
|
-
* @param index - The zero-based index of the input within the transaction's list of outputs.
|
|
142
|
-
*
|
|
143
|
-
* @returns A promise that resolves to a `BitcoinUTxO` object containing the resolved input details.
|
|
144
|
-
* If the input cannot be resolved, the promise should reject with an error explaining the failure.
|
|
145
|
-
*/
|
|
146
|
-
async resolve(txId, index) {
|
|
147
|
-
const transaction = (await firstValueFrom(this.dataProvider.getTransaction({ network: this.network }, txId))).unwrapOr(null);
|
|
148
|
-
if (!transaction || index >= transaction.outputs.length) throw new Error("Transaction or output index not found");
|
|
149
|
-
const output = transaction.outputs[index];
|
|
150
|
-
return {
|
|
151
|
-
txId,
|
|
152
|
-
index,
|
|
153
|
-
address: output.address,
|
|
154
|
-
satoshis: output.satoshis,
|
|
155
|
-
script: "",
|
|
156
|
-
confirmations: transaction.confirmations,
|
|
157
|
-
height: transaction.blockHeight,
|
|
158
|
-
runes: [],
|
|
159
|
-
inscriptions: []
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
|
-
//#endregion
|
|
164
|
-
//#region ../../packages/module/blockchain-bitcoin/src/wallet/BitcoinWallet.ts
|
|
165
|
-
init__polyfill_buffer_patch();
|
|
166
|
-
var import_dist = /* @__PURE__ */ __toESM(require_dist());
|
|
167
|
-
import_src.initEccLib(import_dist);
|
|
168
|
-
/** Where an account wallet is in syncing its state with the provider. */
|
|
169
|
-
let SyncStatus = /* @__PURE__ */ function(SyncStatus) {
|
|
170
|
-
SyncStatus["Pending"] = "pending";
|
|
171
|
-
SyncStatus["Syncing"] = "syncing";
|
|
172
|
-
SyncStatus["Synced"] = "synced";
|
|
173
|
-
SyncStatus["Error"] = "error";
|
|
174
|
-
return SyncStatus;
|
|
175
|
-
}({});
|
|
176
|
-
var BitcoinWallet = class {
|
|
177
|
-
syncStatus$ = new BehaviorSubject({
|
|
178
|
-
status: SyncStatus.Syncing,
|
|
179
|
-
lastUpdate: Date.now()
|
|
180
|
-
});
|
|
181
|
-
transactionHistory$ = new BehaviorSubject(new Array());
|
|
182
|
-
pendingTransactions$ = new BehaviorSubject(new Array());
|
|
183
|
-
utxos$ = new BehaviorSubject(new Array());
|
|
184
|
-
balance$ = new BehaviorSubject(0);
|
|
185
|
-
addresses$ = new BehaviorSubject(new Array());
|
|
186
|
-
isLoadingHistory$ = new BehaviorSubject(false);
|
|
187
|
-
network;
|
|
188
|
-
address;
|
|
189
|
-
masterFingerprint;
|
|
190
|
-
nextCursor$ = new BehaviorSubject(void 0);
|
|
191
|
-
pollSubscription = null;
|
|
192
|
-
lastKnownBlock = null;
|
|
193
|
-
historyDepth;
|
|
194
|
-
provider;
|
|
195
|
-
info;
|
|
196
|
-
pollController$;
|
|
197
|
-
requestResync$;
|
|
198
|
-
logger;
|
|
199
|
-
inputResolver;
|
|
200
|
-
feeMarketProvider;
|
|
201
|
-
constructor(provider, feeMarketProvider, historyDepth = 20, info, pollController$, requestResync$, logger) {
|
|
202
|
-
const bitcoinNetwork = info.network === BitcoinNetwork.Mainnet ? import_src.networks.bitcoin : import_src.networks.testnet;
|
|
203
|
-
this.pollController$ = pollController$;
|
|
204
|
-
this.requestResync$ = requestResync$;
|
|
205
|
-
this.logger = logger;
|
|
206
|
-
this.network = info.network;
|
|
207
|
-
this.historyDepth = historyDepth;
|
|
208
|
-
this.provider = provider;
|
|
209
|
-
this.info = info;
|
|
210
|
-
this.masterFingerprint = info.masterFingerprint;
|
|
211
|
-
this.inputResolver = new BlockchainInputResolver(provider, this.network);
|
|
212
|
-
this.feeMarketProvider = feeMarketProvider;
|
|
213
|
-
const extendedAccountPubKey = info.extendedAccountPublicKeys.nativeSegWit;
|
|
214
|
-
const pubKey = deriveChildPublicKey(extendedAccountPubKey, ChainType.External, 0);
|
|
215
|
-
this.address = {
|
|
216
|
-
address: deriveAddressByType(pubKey, AddressType.NativeSegWit, bitcoinNetwork),
|
|
217
|
-
addressType: AddressType.NativeSegWit,
|
|
218
|
-
network: info.network,
|
|
219
|
-
account: this.info.accountIndex,
|
|
220
|
-
chain: ChainType.External,
|
|
221
|
-
index: 0,
|
|
222
|
-
publicKeyHex: import_buffer.Buffer.from(pubKey).toString("hex")
|
|
223
|
-
};
|
|
224
|
-
this.addresses$.next([this.address]);
|
|
225
|
-
this.startPolling();
|
|
226
|
-
this.utxos$.pipe(map$1((utxos) => utxos.reduce((total, utxo) => total + utxo.satoshis, 0))).subscribe((balance) => {
|
|
227
|
-
this.balance$.next(balance);
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
getInfo() {
|
|
231
|
-
return of(Ok(this.info));
|
|
232
|
-
}
|
|
233
|
-
getNetwork() {
|
|
234
|
-
return of(Ok(this.network));
|
|
235
|
-
}
|
|
236
|
-
getAddress() {
|
|
237
|
-
return of(Ok(this.address));
|
|
238
|
-
}
|
|
239
|
-
/**
|
|
240
|
-
* Fetches the raw serialized transaction (hex) for a given transaction id.
|
|
241
|
-
*
|
|
242
|
-
* @param txId - 32-byte transaction ID in hexadecimal form.
|
|
243
|
-
*/
|
|
244
|
-
getRawTransaction(txId) {
|
|
245
|
-
return this.provider.getRawTransaction({ network: this.network }, txId);
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* Fetches the current fee market for estimating transaction fees.
|
|
249
|
-
*/
|
|
250
|
-
getCurrentFeeMarket() {
|
|
251
|
-
return this.feeMarketProvider.getFeeMarket({ network: this.network });
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Fetches transaction history pages recursively until the total number of
|
|
255
|
-
* transactions reaches the `desiredAmount` or the end of history is found.
|
|
256
|
-
*
|
|
257
|
-
* @param desiredAmount - The target number of transactions to have loaded.
|
|
258
|
-
* @returns An observable that emits an `Ok<boolean>` on success or an `Err<ProviderError>` on failure.
|
|
259
|
-
* The boolean is `true` if the end of history was reached.
|
|
260
|
-
*/
|
|
261
|
-
fetchTxHistoryUpTo(desiredAmount) {
|
|
262
|
-
if (this.isLoadingHistory$.value) {
|
|
263
|
-
this.logger.debug("History loading already in progress. Skipping request.");
|
|
264
|
-
return of(Ok(false));
|
|
265
|
-
}
|
|
266
|
-
this.isLoadingHistory$.next(true);
|
|
267
|
-
return of(this.nextCursor$.value).pipe(expand((cursor) => {
|
|
268
|
-
if (this.transactionHistory$.value.length >= desiredAmount || cursor === null) return EMPTY;
|
|
269
|
-
return this.provider.getTransactions({ network: this.network }, this.address.address, {
|
|
270
|
-
cursor,
|
|
271
|
-
limit: this.historyDepth,
|
|
272
|
-
order: "desc"
|
|
273
|
-
}).pipe(map$1((result) => {
|
|
274
|
-
if (result.isErr()) {
|
|
275
|
-
this.logger.error("Failed to get older transactions:", result.error);
|
|
276
|
-
throw result.error;
|
|
277
|
-
}
|
|
278
|
-
const { items: olderHistory, cursor: nextCursor } = result.value;
|
|
279
|
-
const uniqueHistory = Array.from(new Map([...this.transactionHistory$.value, ...olderHistory].map((tx) => [tx.transactionHash, tx])).values());
|
|
280
|
-
this.transactionHistory$.next(uniqueHistory);
|
|
281
|
-
this.nextCursor$.next(nextCursor || null);
|
|
282
|
-
return nextCursor || null;
|
|
283
|
-
}));
|
|
284
|
-
}), defaultIfEmpty(this.nextCursor$.value), last(), map$1((lastCursor) => lastCursor === null), map$1((hasReachedEnd) => Ok(hasReachedEnd)), catchError$1((error) => {
|
|
285
|
-
this.logger.error("A critical error occurred during history fetch:", error);
|
|
286
|
-
return of(Err(error));
|
|
287
|
-
}), finalize(() => {
|
|
288
|
-
this.isLoadingHistory$.next(false);
|
|
289
|
-
}));
|
|
290
|
-
}
|
|
291
|
-
/**
|
|
292
|
-
* Submits a raw transaction to the blockchain for inclusion in a block.
|
|
293
|
-
*
|
|
294
|
-
* On success the transaction is eagerly appended to pendingTransactions$.
|
|
295
|
-
* A failure to derive that pending entry (e.g. an output with no address
|
|
296
|
-
* form) is logged but never fails the submission: the transaction is
|
|
297
|
-
* already on the network, so the txId must still be returned.
|
|
298
|
-
*
|
|
299
|
-
* @param rawTransaction - The raw transaction data to be broadcast to the network.
|
|
300
|
-
*/
|
|
301
|
-
submitTransaction(rawTransaction) {
|
|
302
|
-
return this.provider.submitTransaction({ network: this.network }, rawTransaction).pipe(mergeMap((submitResult) => {
|
|
303
|
-
if (submitResult.isErr()) return of(submitResult);
|
|
304
|
-
const transactionId = submitResult.value;
|
|
305
|
-
return from(historyEntryFromRawTx(rawTransaction, this.network, this.inputResolver)).pipe(tap((entry) => {
|
|
306
|
-
entry.transactionHash = transactionId;
|
|
307
|
-
if (!this.pendingTransactions$.value.some((tx) => tx.transactionHash === entry.transactionHash)) this.pendingTransactions$.next([...this.pendingTransactions$.value, entry]);
|
|
308
|
-
}), map$1(() => submitResult), catchError$1((error) => {
|
|
309
|
-
this.logger.error("Failed to derive pending entry for submitted transaction:", error);
|
|
310
|
-
return of(submitResult);
|
|
311
|
-
}));
|
|
312
|
-
}), catchError$1((error) => {
|
|
313
|
-
this.logger.error("Failed to submit transaction:", error);
|
|
314
|
-
return of(Err(error));
|
|
315
|
-
}));
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* Stop polling by unsubscribing from the subscription
|
|
319
|
-
*/
|
|
320
|
-
shutdown() {
|
|
321
|
-
if (this.pollSubscription) {
|
|
322
|
-
this.pollSubscription.unsubscribe();
|
|
323
|
-
this.pollSubscription = null;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
/**
|
|
327
|
-
* Starts reacting to tip changes and updating wallet state.
|
|
328
|
-
* The polling controller is responsible for *when* we trigger,
|
|
329
|
-
* this method just reacts to those triggers.
|
|
330
|
-
*/
|
|
331
|
-
startPolling() {
|
|
332
|
-
this.pollSubscription = merge(this.pollController$.pipe(map$1((tip) => ({
|
|
333
|
-
type: "tip",
|
|
334
|
-
tip
|
|
335
|
-
}))), this.requestResync$.pipe(withLatestFrom(this.pollController$), map$1(([, tip]) => ({
|
|
336
|
-
type: "manual",
|
|
337
|
-
tip
|
|
338
|
-
})))).pipe(tap((event) => {
|
|
339
|
-
this.updateSyncStatus(SyncStatus.Pending);
|
|
340
|
-
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})`);
|
|
341
|
-
}), switchMap$1((event) => {
|
|
342
|
-
const latestBlockInfo = event.tip;
|
|
343
|
-
let task$;
|
|
344
|
-
if (event.type === "tip") task$ = !this.lastKnownBlock || this.lastKnownBlock.hash !== latestBlockInfo.hash ? this.updateState(latestBlockInfo) : this.updatePendingTransactions();
|
|
345
|
-
else task$ = this.updateState(latestBlockInfo);
|
|
346
|
-
this.updateSyncStatus(SyncStatus.Syncing);
|
|
347
|
-
return task$.pipe(tap(() => {
|
|
348
|
-
this.updateSyncStatus(SyncStatus.Synced);
|
|
349
|
-
}), catchError$1((error) => {
|
|
350
|
-
this.logger.error("Failed to update wallet state:", error);
|
|
351
|
-
this.updateSyncStatus(SyncStatus.Error, error);
|
|
352
|
-
return EMPTY;
|
|
353
|
-
}));
|
|
354
|
-
})).subscribe();
|
|
355
|
-
}
|
|
356
|
-
/**
|
|
357
|
-
* Fetches the latest transactions and updates the transactionHistory$ subject if they have changed.
|
|
358
|
-
*/
|
|
359
|
-
updateTransactions() {
|
|
360
|
-
return this.provider.getTransactions({ network: this.network }, this.address.address, {
|
|
361
|
-
limit: this.historyDepth,
|
|
362
|
-
order: "desc"
|
|
363
|
-
}).pipe(map$1((result) => {
|
|
364
|
-
if (result.isErr()) {
|
|
365
|
-
this.logger.error("Failed to get transactions:", result.error);
|
|
366
|
-
throw result.error;
|
|
367
|
-
}
|
|
368
|
-
const { items: newHistory, cursor: nextCursor } = result.value;
|
|
369
|
-
const currentHistory = this.transactionHistory$.value;
|
|
370
|
-
const combinedHistory = [...currentHistory, ...newHistory];
|
|
371
|
-
const uniqueHistory = Array.from(new Map(combinedHistory.map((tx) => [tx.transactionHash, tx])).values());
|
|
372
|
-
uniqueHistory.sort((a, b) => b.timestamp - a.timestamp);
|
|
373
|
-
const hasSetChanged = !isEqual(uniqueHistory, currentHistory);
|
|
374
|
-
if (hasSetChanged) this.transactionHistory$.next(uniqueHistory);
|
|
375
|
-
if (this.nextCursor$.value === void 0) this.nextCursor$.next(nextCursor || null);
|
|
376
|
-
return hasSetChanged;
|
|
377
|
-
}));
|
|
378
|
-
}
|
|
379
|
-
/**
|
|
380
|
-
* Updates the local list of pending transactions by synchronizing with the remote mempool.
|
|
381
|
-
*
|
|
382
|
-
* Transactions in the Bitcoin network can be replaced in the mempool by another transaction
|
|
383
|
-
* with the same inputs but possibly with a higher fee (Replace-By-Fee, RBF).
|
|
384
|
-
*
|
|
385
|
-
* The method performs the following operations:
|
|
386
|
-
*
|
|
387
|
-
* 1. **Fetch Remote Pending Transactions**: Retrieves the list of pending transactions from the mempool
|
|
388
|
-
* for the wallet's address. This includes transactions that are waiting to be confirmed.
|
|
389
|
-
*
|
|
390
|
-
* 2. **Synchronize Local and Remote Transactions**:
|
|
391
|
-
* - For each remote pending transaction:
|
|
392
|
-
* - If it matches a transaction in the local list (by transaction hash), it updates the local transaction
|
|
393
|
-
* with the remote version, since it contains more metadata (I.E resolved inputs).
|
|
394
|
-
*
|
|
395
|
-
* 3. **Purge Invalid Local Transactions**:
|
|
396
|
-
* - Iterates over the local list of pending transactions to check each transaction's inputs against:
|
|
397
|
-
* a. Inputs of **confirmed** transactions in the history (`confirmations > 0`) to detect inputs settled in a
|
|
398
|
-
* block. Unconfirmed history entries are ignored — a transaction stays pending until it is mined.
|
|
399
|
-
* b. Inputs of other remote pending transactions to handle RBF scenarios where a transaction might be replaced
|
|
400
|
-
* by another with the same inputs but not the same hash.
|
|
401
|
-
* - Removes any local transactions whose inputs are found in the confirmed transactions or in another competing pending transaction.
|
|
402
|
-
*/
|
|
403
|
-
updatePendingTransactions() {
|
|
404
|
-
return this.provider.getTransactionsInMempool({ network: this.network }, this.address.address, { order: "desc" }).pipe(withLatestFrom(this.pendingTransactions$), tap(([mempoolResult, localPendingTxs]) => {
|
|
405
|
-
if (mempoolResult.isErr()) {
|
|
406
|
-
this.logger.error("Failed to get mempool transactions:", mempoolResult.error);
|
|
407
|
-
throw mempoolResult.error;
|
|
408
|
-
}
|
|
409
|
-
const { items: remotePendingTxs } = mempoolResult.value;
|
|
410
|
-
const confirmedHistory = this.transactionHistory$.value.filter((tx) => tx.confirmations > 0);
|
|
411
|
-
const validLocalTxs = localPendingTxs.filter((localTx) => {
|
|
412
|
-
return !localTx.inputs.some((input) => this.isInputSpent(input, confirmedHistory) || this.isInputSpent(input, remotePendingTxs.filter((remoteTx) => remoteTx.transactionHash !== localTx.transactionHash)));
|
|
413
|
-
});
|
|
414
|
-
const finalTxsMap = new Map(validLocalTxs.map((tx) => [tx.transactionHash, tx]));
|
|
415
|
-
remotePendingTxs.forEach((remoteTx) => {
|
|
416
|
-
finalTxsMap.set(remoteTx.transactionHash, remoteTx);
|
|
417
|
-
});
|
|
418
|
-
let newPendingTxs = Array.from(finalTxsMap.values());
|
|
419
|
-
const confirmedHashes = new Set(confirmedHistory.map((tx) => tx.transactionHash));
|
|
420
|
-
newPendingTxs = newPendingTxs.filter((tx) => !confirmedHashes.has(tx.transactionHash));
|
|
421
|
-
if (!isEqual(newPendingTxs, this.pendingTransactions$.value)) this.pendingTransactions$.next(newPendingTxs);
|
|
422
|
-
}), map$1(() => void 0));
|
|
423
|
-
}
|
|
424
|
-
/**
|
|
425
|
-
* Helper method to check if a specific transaction input has been used
|
|
426
|
-
* in a given list of transactions.
|
|
427
|
-
*/
|
|
428
|
-
isInputSpent(inputToFind, transactionList) {
|
|
429
|
-
return transactionList.some((tx) => tx.inputs.some((input) => input.txId === inputToFind.txId && input.index === inputToFind.index));
|
|
430
|
-
}
|
|
431
|
-
/**
|
|
432
|
-
* Fetches the latest UTxOs and updates the utxos$ subject if they have changed.
|
|
433
|
-
* Returns a cold observable that completes when the operation is done.
|
|
434
|
-
*/
|
|
435
|
-
updateUtxos() {
|
|
436
|
-
return this.provider.getUTxOs({ network: this.network }, this.address.address, {}).pipe(withLatestFrom(this.utxos$), tap(([utxoResult, currentUtxos]) => {
|
|
437
|
-
if (utxoResult.isErr()) {
|
|
438
|
-
this.logger.error("Failed to get UTxOs:", utxoResult.error);
|
|
439
|
-
throw utxoResult.error;
|
|
440
|
-
}
|
|
441
|
-
const { items } = utxoResult.value;
|
|
442
|
-
if (!isEqual(items, currentUtxos)) this.utxos$.next(items);
|
|
443
|
-
}), map$1(() => void 0));
|
|
444
|
-
}
|
|
445
|
-
/**
|
|
446
|
-
* Updates the entire wallet state.
|
|
447
|
-
* It chains the various update operations in the correct order.
|
|
448
|
-
*/
|
|
449
|
-
updateState(latestBlockInfo) {
|
|
450
|
-
return this.updateTransactions().pipe(mergeMap((hasTxSetChanged) => {
|
|
451
|
-
const tasksToRun = [this.updatePendingTransactions()];
|
|
452
|
-
if (hasTxSetChanged) tasksToRun.push(this.updateUtxos());
|
|
453
|
-
return forkJoin(tasksToRun);
|
|
454
|
-
}), tap(() => {
|
|
455
|
-
this.lastKnownBlock = latestBlockInfo;
|
|
456
|
-
}), map$1(() => void 0));
|
|
457
|
-
}
|
|
458
|
-
updateSyncStatus(status, lastError) {
|
|
459
|
-
this.syncStatus$.next({
|
|
460
|
-
status,
|
|
461
|
-
lastUpdate: Date.now(),
|
|
462
|
-
lastError
|
|
463
|
-
});
|
|
464
|
-
}
|
|
465
|
-
};
|
|
466
|
-
//#endregion
|
|
467
|
-
//#region ../../packages/module/blockchain-bitcoin/src/wallet/account-wallets.ts
|
|
468
|
-
/**
|
|
469
|
-
* A BehaviorSubject that holds a record of Bitcoin wallets associated with account IDs.
|
|
470
|
-
* The keys are AccountId strings, and the values are BitcoinWallet instances.
|
|
471
|
-
* It is a single module-level subject, so every wallet loaded in the same
|
|
472
|
-
* JavaScript realm registers its accounts here.
|
|
473
|
-
*/
|
|
474
|
-
const bitcoinAccountWallets$ = new BehaviorSubject({});
|
|
475
|
-
//#endregion
|
|
476
|
-
//#region ../../packages/module/blockchain-bitcoin/src/store/helpers/compute-token-balances.ts
|
|
477
|
-
const outpointKey = (ref) => `${ref.txId}#${ref.index}`;
|
|
478
|
-
/**
|
|
479
|
-
* Derives the confirmed (`available`) and unconfirmed (`pending`) BTC balances
|
|
480
|
-
* for an account from its confirmed UTxO set and the transactions currently in
|
|
481
|
-
* the mempool.
|
|
482
|
-
*
|
|
483
|
-
* - `available`: confirmed UTxOs **minus** any consumed by an unconfirmed
|
|
484
|
-
* transaction. Those are in-flight spent and no longer spendable, even though
|
|
485
|
-
* the provider still reports them as confirmed UTxOs until the next block.
|
|
486
|
-
* - `pending`: value of unconfirmed outputs paying our own addresses — an
|
|
487
|
-
* incoming receive, or our own change from an outgoing send. These are
|
|
488
|
-
* recognised by the wallet but not yet finalised by the network.
|
|
489
|
-
*
|
|
490
|
-
* Deriving both from the same pending set avoids double-counting: on an
|
|
491
|
-
* outgoing send the spent UTxO leaves `available` while its change appears in
|
|
492
|
-
* `pending`, so `available + pending` reflects the true post-send balance.
|
|
493
|
-
*
|
|
494
|
-
* Outputs that are themselves spent by another mempool transaction (chained
|
|
495
|
-
* mempool spends) are excluded from `pending` so they are not counted twice.
|
|
496
|
-
*/
|
|
497
|
-
const computeBitcoinTokenBalances = ({ confirmedUtxos, pendingTransactions, ownAddresses }) => {
|
|
498
|
-
const spentOutpoints = /* @__PURE__ */ new Set();
|
|
499
|
-
for (const tx of pendingTransactions) for (const input of tx.inputs) spentOutpoints.add(outpointKey(input));
|
|
500
|
-
let available = 0n;
|
|
501
|
-
for (const utxo of confirmedUtxos) if (!spentOutpoints.has(outpointKey(utxo))) available += BigInt(utxo.satoshis);
|
|
502
|
-
let pending = 0n;
|
|
503
|
-
for (const tx of pendingTransactions) for (const [index, output] of tx.outputs.entries()) {
|
|
504
|
-
const isOwn = ownAddresses.has(output.address);
|
|
505
|
-
const isSpentByAnotherPendingTx = spentOutpoints.has(outpointKey({
|
|
506
|
-
txId: tx.transactionHash,
|
|
507
|
-
index
|
|
508
|
-
}));
|
|
509
|
-
if (isOwn && !isSpentByAnotherPendingTx) pending += BigInt(output.satoshis);
|
|
510
|
-
}
|
|
511
|
-
return {
|
|
512
|
-
available,
|
|
513
|
-
pending
|
|
514
|
-
};
|
|
515
|
-
};
|
|
516
|
-
//#endregion
|
|
517
|
-
//#region ../../packages/module/blockchain-bitcoin/src/store/side-effects.ts
|
|
518
|
-
const mapNetworkTypeToBitcoinNetwork = (networkType) => {
|
|
519
|
-
switch (networkType) {
|
|
520
|
-
case "mainnet": return BitcoinNetwork.Mainnet;
|
|
521
|
-
case "testnet": return BitcoinNetwork.Testnet;
|
|
522
|
-
default: {
|
|
523
|
-
const _exhaustive = networkType;
|
|
524
|
-
throw new Error(`Unhandled network type: ${String(_exhaustive)}`);
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
};
|
|
528
|
-
const deriveBitcoinTestnetOptions = (config) => {
|
|
529
|
-
const maestroConfig = config.bitcoinProvider.maestroConfig;
|
|
530
|
-
if (!Object.keys(maestroConfig ?? {}).includes(BitcoinNetwork.Testnet)) return [];
|
|
531
|
-
return [{
|
|
532
|
-
id: BitcoinNetworkId("testnet4"),
|
|
533
|
-
label: "bitcoin.network-config.network-option.testnet4"
|
|
534
|
-
}];
|
|
535
|
-
};
|
|
536
|
-
const registerBitcoinTestnetOptions = (testnetOptions) => (_, { network: { selectTestnetOptions$ } }, { actions }) => selectTestnetOptions$.pipe(filter((options) => !options?.Bitcoin), map(() => actions.network.setTestnetOptions({
|
|
537
|
-
blockchainName: "Bitcoin",
|
|
538
|
-
options: testnetOptions
|
|
539
|
-
})));
|
|
540
|
-
const registerBitcoinBlockchainNetworks = (_, { network: { selectBlockchainNetworks$ } }, { actions }) => selectBlockchainNetworks$.pipe(filter((blockchainNetworks) => !blockchainNetworks?.Bitcoin), map(() => actions.network.setBlockchainNetworks({
|
|
541
|
-
blockchain: "Bitcoin",
|
|
542
|
-
mainnet: BitcoinNetworkId("mainnet"),
|
|
543
|
-
testnet: BitcoinNetworkId("testnet4")
|
|
544
|
-
})));
|
|
545
|
-
const mapBitcoinTxToActivity = (rawTx, userAddresses, accountId) => {
|
|
546
|
-
let totalInputFromUser = 0;
|
|
547
|
-
let totalOutputToUser = 0;
|
|
548
|
-
let hasForeignOutput = false;
|
|
549
|
-
let hasOwnInputs = false;
|
|
550
|
-
for (const input of rawTx.inputs) if (userAddresses.has(input.address)) {
|
|
551
|
-
totalInputFromUser += input.satoshis;
|
|
552
|
-
hasOwnInputs = true;
|
|
553
|
-
}
|
|
554
|
-
for (const output of rawTx.outputs) if (userAddresses.has(output.address)) totalOutputToUser += output.satoshis;
|
|
555
|
-
else hasForeignOutput = true;
|
|
556
|
-
const netAmount = BigInt(totalOutputToUser - totalInputFromUser);
|
|
557
|
-
let activityType;
|
|
558
|
-
if (hasOwnInputs && !hasForeignOutput) activityType = ActivityType.Self;
|
|
559
|
-
else if (netAmount > 0n) activityType = ActivityType.Receive;
|
|
560
|
-
else activityType = ActivityType.Send;
|
|
561
|
-
if (rawTx.confirmations <= 0) activityType = ActivityType.Pending;
|
|
562
|
-
return {
|
|
563
|
-
accountId,
|
|
564
|
-
activityId: rawTx.transactionHash,
|
|
565
|
-
type: activityType,
|
|
566
|
-
tokenBalanceChanges: [{
|
|
567
|
-
tokenId: BITCOIN_TOKEN_ID,
|
|
568
|
-
amount: BigNumber(netAmount)
|
|
569
|
-
}],
|
|
570
|
-
timestamp: Timestamp(rawTx.timestamp > 0 ? rawTx.timestamp * 1e3 : Date.now()),
|
|
571
|
-
...activityType === ActivityType.Pending ? { blockchainSpecific: { Bitcoin: {
|
|
572
|
-
consumedInputs: rawTx.inputs.map((input) => ({
|
|
573
|
-
txId: input.txId,
|
|
574
|
-
index: input.index
|
|
575
|
-
})),
|
|
576
|
-
producedOutputs: []
|
|
577
|
-
} } } : {}
|
|
578
|
-
};
|
|
579
|
-
};
|
|
580
|
-
const trackTip = (tipPollFrequency) => (_, { bitcoinContext: { selectNetwork$ }, wallets: { selectActiveNetworkAccounts$ } }, { actions, bitcoinProvider: { getLastKnownBlock }, isWalletActive$ }) => combineLatest([selectNetwork$.pipe(distinctUntilChanged()), selectActiveNetworkAccounts$.pipe(map((accounts) => accounts.some((account) => account.blockchainName === "Bitcoin")), distinctUntilChanged())]).pipe(switchMap(([network, hasBitcoinAccounts]) => {
|
|
581
|
-
if (!network) return of(actions.bitcoinContext.setTip(void 0));
|
|
582
|
-
if (!hasBitcoinAccounts) return EMPTY;
|
|
583
|
-
return merge(of(void 0), interval(tipPollFrequency)).pipe(exhaustMap(() => getLastKnownBlock({ network })), mergeMap((result) => {
|
|
584
|
-
if (result.isErr()) return of(actions.bitcoinContext.getTipFailed({
|
|
585
|
-
failure: result.error.reason,
|
|
586
|
-
network
|
|
587
|
-
}));
|
|
588
|
-
return of(actions.bitcoinContext.setTip(result.value));
|
|
589
|
-
}));
|
|
590
|
-
}), whileActive(isWalletActive$));
|
|
591
|
-
/**
|
|
592
|
-
* Factory function to create and configure a new BitcoinWallet instance.
|
|
593
|
-
*
|
|
594
|
-
* @param historyDepth - The depth of transaction history to maintain.
|
|
595
|
-
* @param requestResync$ - Observable that triggers wallet resynchronization.
|
|
596
|
-
* @param selectNetwork$ - Observable providing the current Bitcoin network (undefined when not yet registered).
|
|
597
|
-
* @param selectTip$ - Observable providing the current blockchain tip.
|
|
598
|
-
* @param bitcoinAccountWallets$ - Observable holding the mapping of account IDs to BitcoinWallet instances.
|
|
599
|
-
* @param provider - The Bitcoin data provider.
|
|
600
|
-
* @param feeMarketProvider - The provider for fee market estimations.
|
|
601
|
-
* @param account - The in-memory wallet account data.
|
|
602
|
-
* @param logger - The logger for wallet errors.
|
|
603
|
-
* @returns An object containing observables for the wallet's tokens and addresses.
|
|
604
|
-
*/
|
|
605
|
-
const createBitcoinWallet = ({ historyDepth, requestResync$, selectNetwork$, selectTip$, bitcoinAccountWallets$, provider, feeMarketProvider, account, logger }) => {
|
|
606
|
-
const walletInfo = {
|
|
607
|
-
accountIndex: account.blockchainSpecific.accountIndex,
|
|
608
|
-
extendedAccountPublicKeys: account.blockchainSpecific.extendedAccountPublicKeys,
|
|
609
|
-
masterFingerprint: account.blockchainSpecific.masterFingerprint,
|
|
610
|
-
network: mapNetworkTypeToBitcoinNetwork(account.networkType),
|
|
611
|
-
walletId: account.walletId
|
|
612
|
-
};
|
|
613
|
-
const resyncController$ = requestResync$.pipe(filter(({ payload: { accountId } }) => accountId === account.accountId));
|
|
614
|
-
const wallet = new BitcoinWallet(provider, feeMarketProvider, historyDepth, walletInfo, combineLatest([selectTip$, selectNetwork$]).pipe(filter(([tip, currentNetwork]) => !!tip && currentNetwork === walletInfo.network), map(([tip]) => tip)), resyncController$, logger);
|
|
615
|
-
const currentWallets = bitcoinAccountWallets$.value;
|
|
616
|
-
bitcoinAccountWallets$.next({
|
|
617
|
-
...currentWallets,
|
|
618
|
-
[account.accountId]: wallet
|
|
619
|
-
});
|
|
620
|
-
return {
|
|
621
|
-
addresses$: wallet.addresses$.pipe(map((derivedAddresses) => derivedAddresses.map((derivedAddr) => ({
|
|
622
|
-
address: derivedAddr.address,
|
|
623
|
-
accountId: account.accountId,
|
|
624
|
-
data: {
|
|
625
|
-
network: derivedAddr.network,
|
|
626
|
-
addressType: derivedAddr.addressType,
|
|
627
|
-
account: derivedAddr.account,
|
|
628
|
-
chain: derivedAddr.chain,
|
|
629
|
-
index: derivedAddr.index,
|
|
630
|
-
publicKeyHex: derivedAddr.publicKeyHex
|
|
631
|
-
}
|
|
632
|
-
})))),
|
|
633
|
-
tokens$: combineLatest([
|
|
634
|
-
wallet.addresses$,
|
|
635
|
-
wallet.utxos$,
|
|
636
|
-
wallet.pendingTransactions$
|
|
637
|
-
]).pipe(map(([addresses, utxos, pendingTransactions]) => {
|
|
638
|
-
const primaryAddress = addresses[0]?.address || "";
|
|
639
|
-
const { available, pending } = computeBitcoinTokenBalances({
|
|
640
|
-
confirmedUtxos: utxos,
|
|
641
|
-
pendingTransactions,
|
|
642
|
-
ownAddresses: new Set(addresses.map((a) => a.address))
|
|
643
|
-
});
|
|
644
|
-
const btcToken = {
|
|
645
|
-
metadata: BITCOIN_TOKEN_METADATA,
|
|
646
|
-
accountId: account.accountId,
|
|
647
|
-
address: BitcoinAddress(primaryAddress),
|
|
648
|
-
tokenId: BITCOIN_TOKEN_ID,
|
|
649
|
-
available: BigNumber(available),
|
|
650
|
-
pending: BigNumber(pending),
|
|
651
|
-
decimals: 8,
|
|
652
|
-
displayDecimalPlaces: 8,
|
|
653
|
-
displayLongName: "Bitcoin",
|
|
654
|
-
displayShortName: "BTC",
|
|
655
|
-
blockchainName: "Bitcoin"
|
|
656
|
-
};
|
|
657
|
-
return {
|
|
658
|
-
address: BitcoinAddress(primaryAddress),
|
|
659
|
-
tokens: [btcToken]
|
|
660
|
-
};
|
|
661
|
-
})),
|
|
662
|
-
syncStatus$: wallet.syncStatus$,
|
|
663
|
-
activities$: combineLatest([
|
|
664
|
-
wallet.transactionHistory$,
|
|
665
|
-
wallet.pendingTransactions$,
|
|
666
|
-
wallet.addresses$
|
|
667
|
-
]).pipe(map(([rawTxs, pendingTxs, derivedAddresses]) => {
|
|
668
|
-
const userAddresses = new Set(derivedAddresses.map((a) => a.address));
|
|
669
|
-
return [...pendingTxs, ...rawTxs].map((rawTx) => mapBitcoinTxToActivity(rawTx, userAddresses, account.accountId));
|
|
670
|
-
})),
|
|
671
|
-
fetchTxHistoryUpTo: (desiredCount) => {
|
|
672
|
-
return wallet.fetchTxHistoryUpTo(desiredCount);
|
|
673
|
-
}
|
|
674
|
-
};
|
|
675
|
-
};
|
|
676
|
-
const startBitcoinWallet = (historyDepth) => ({ bitcoinContext: { requestResync$, getTipFailed$ } }, { bitcoinContext: { selectTip$, selectNetwork$ }, wallets: { selectActiveNetworkAccounts$ }, activities: { selectDesiredLoadedActivitiesCountPerAccount$, selectAllMap$ } }, { bitcoinProvider, bitcoinAccountWallets$, bitcoinFeeMarketProvider, actions, logger }) => selectActiveNetworkAccounts$.pipe(map((accounts) => accounts.filter((account) => account.blockchainName === "Bitcoin")), mergeAll(), mergeMap((bitcoinAccount) => {
|
|
677
|
-
const bitcoinWallet = createBitcoinWallet({
|
|
678
|
-
historyDepth,
|
|
679
|
-
requestResync$,
|
|
680
|
-
selectNetwork$,
|
|
681
|
-
selectTip$,
|
|
682
|
-
bitcoinAccountWallets$,
|
|
683
|
-
provider: bitcoinProvider,
|
|
684
|
-
feeMarketProvider: bitcoinFeeMarketProvider,
|
|
685
|
-
account: bitcoinAccount,
|
|
686
|
-
logger
|
|
687
|
-
});
|
|
688
|
-
return merge(selectActiveNetworkAccounts$.pipe(take(1), map(() => actions.tokens.upsertTokensMetadata({ metadatas: [{
|
|
689
|
-
...BITCOIN_TOKEN_METADATA,
|
|
690
|
-
tokenId: BITCOIN_TOKEN_ID
|
|
691
|
-
}] }))), bitcoinWallet.addresses$.pipe(map((addresses) => {
|
|
692
|
-
return actions.addresses.upsertAddresses({
|
|
693
|
-
accountId: bitcoinAccount.accountId,
|
|
694
|
-
addresses,
|
|
695
|
-
blockchainName: "Bitcoin"
|
|
696
|
-
});
|
|
697
|
-
})), bitcoinWallet.syncStatus$.pipe(map((update) => {
|
|
698
|
-
const operationId = `${bitcoinAccount.accountId}-bitcoin-sync`;
|
|
699
|
-
switch (update.status) {
|
|
700
|
-
case SyncStatus.Pending: return actions.sync.addSyncOperation({
|
|
701
|
-
accountId: bitcoinAccount.accountId,
|
|
702
|
-
operation: {
|
|
703
|
-
operationId,
|
|
704
|
-
status: "Pending",
|
|
705
|
-
description: "sync.operation.bitcoin-wallet-sync",
|
|
706
|
-
startedAt: Timestamp(update.lastUpdate)
|
|
707
|
-
}
|
|
708
|
-
});
|
|
709
|
-
case SyncStatus.Syncing: return actions.sync.addSyncOperation({
|
|
710
|
-
accountId: bitcoinAccount.accountId,
|
|
711
|
-
operation: {
|
|
712
|
-
operationId,
|
|
713
|
-
status: "InProgress",
|
|
714
|
-
type: "Indeterminate",
|
|
715
|
-
description: "sync.operation.bitcoin-wallet-sync",
|
|
716
|
-
startedAt: Timestamp(update.lastUpdate)
|
|
717
|
-
}
|
|
718
|
-
});
|
|
719
|
-
case SyncStatus.Synced: return actions.sync.completeSyncOperation({
|
|
720
|
-
accountId: bitcoinAccount.accountId,
|
|
721
|
-
operationId
|
|
722
|
-
});
|
|
723
|
-
case SyncStatus.Error: return actions.sync.failSyncOperation({
|
|
724
|
-
accountId: bitcoinAccount.accountId,
|
|
725
|
-
operationId,
|
|
726
|
-
error: "sync.error.bitcoin-sync-failed"
|
|
727
|
-
});
|
|
728
|
-
}
|
|
729
|
-
})), getTipFailed$.pipe(withLatestFrom(selectNetwork$), filter(([{ payload }, currentNetwork]) => payload.network === currentNetwork), withLatestFrom(bitcoinWallet.syncStatus$), filter(([, walletStatus]) => walletStatus.status === SyncStatus.Syncing), map(() => actions.sync.failSyncOperation({
|
|
730
|
-
accountId: bitcoinAccount.accountId,
|
|
731
|
-
operationId: `${bitcoinAccount.accountId}-bitcoin-sync`,
|
|
732
|
-
error: "sync.error.bitcoin-sync-failed"
|
|
733
|
-
}))), bitcoinWallet.tokens$.pipe(skip(1), map(({ address, tokens }) => {
|
|
734
|
-
return actions.tokens.setAddressTokens({
|
|
735
|
-
accountId: bitcoinAccount.accountId,
|
|
736
|
-
address: BitcoinAddress(address),
|
|
737
|
-
tokens,
|
|
738
|
-
blockchainName: "Bitcoin"
|
|
739
|
-
});
|
|
740
|
-
})), bitcoinWallet.activities$.pipe(map((activities) => {
|
|
741
|
-
return actions.activities.upsertActivities({
|
|
742
|
-
accountId: bitcoinAccount.accountId,
|
|
743
|
-
activities
|
|
744
|
-
});
|
|
745
|
-
})), selectDesiredLoadedActivitiesCountPerAccount$.pipe(mergeMap((desiredCountMap) => from(Object.entries(desiredCountMap))), filter(([accountId]) => accountId === bitcoinAccount.accountId), withLatestFrom(selectAllMap$), filter(([[, desiredCount], loadedActivities]) => {
|
|
746
|
-
return (loadedActivities[bitcoinAccount.accountId]?.length ?? 0) < desiredCount;
|
|
747
|
-
}), switchMap(([[, desiredAmount]]) => bitcoinWallet.fetchTxHistoryUpTo(desiredAmount)), mergeMap((result) => {
|
|
748
|
-
if (result.isErr()) return of(actions.bitcoinContext.getAddressTransactionHistoryFailed({
|
|
749
|
-
accountId: bitcoinAccount.accountId,
|
|
750
|
-
failure: result.error.reason
|
|
751
|
-
}));
|
|
752
|
-
if (result.value) return of(actions.activities.setHasLoadedOldestEntry({
|
|
753
|
-
accountId: bitcoinAccount.accountId,
|
|
754
|
-
hasLoadedOldestEntry: true
|
|
755
|
-
}));
|
|
756
|
-
return EMPTY;
|
|
757
|
-
})));
|
|
758
|
-
}));
|
|
759
|
-
const createBitcoinProviderSideEffects = (config) => {
|
|
760
|
-
return [
|
|
761
|
-
registerBitcoinBlockchainNetworks,
|
|
762
|
-
registerBitcoinTestnetOptions(deriveBitcoinTestnetOptions(config)),
|
|
763
|
-
startBitcoinWallet(config.bitcoinProvider.historyDepth),
|
|
764
|
-
trackTip(config.bitcoinProvider.tipPollFrequency)
|
|
765
|
-
];
|
|
766
|
-
};
|
|
767
|
-
//#endregion
|
|
768
|
-
export { bitcoinContextReducers as a, bitcoinContextActions as i, bitcoinAccountWallets$ as n, bitcoinContextSelectors as o, SyncStatus as r, createBitcoinProviderSideEffects as t };
|