@atomiqlabs/sdk 8.9.0 → 8.9.2
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/LICENSE +201 -201
- package/README.md +1760 -1760
- package/api/index.d.ts +1 -1
- package/api/index.js +3 -3
- package/dist/ApiList.d.ts +37 -37
- package/dist/ApiList.js +30 -30
- package/dist/SmartChainAssets.d.ts +181 -181
- package/dist/SmartChainAssets.js +181 -181
- package/dist/api/ApiEndpoints.d.ts +393 -393
- package/dist/api/ApiEndpoints.js +2 -2
- package/dist/api/ApiParser.d.ts +10 -10
- package/dist/api/ApiParser.js +134 -134
- package/dist/api/ApiTypes.d.ts +157 -157
- package/dist/api/ApiTypes.js +75 -75
- package/dist/api/SerializedAction.d.ts +40 -40
- package/dist/api/SerializedAction.js +59 -59
- package/dist/api/SwapperApi.d.ts +50 -50
- package/dist/api/SwapperApi.js +431 -431
- package/dist/api/index.d.ts +5 -5
- package/dist/api/index.js +24 -24
- package/dist/bitcoin/coinselect2/accumulative.d.ts +7 -7
- package/dist/bitcoin/coinselect2/accumulative.js +52 -52
- package/dist/bitcoin/coinselect2/blackjack.d.ts +7 -7
- package/dist/bitcoin/coinselect2/blackjack.js +38 -38
- package/dist/bitcoin/coinselect2/index.d.ts +20 -20
- package/dist/bitcoin/coinselect2/index.js +69 -69
- package/dist/bitcoin/coinselect2/utils.d.ts +82 -82
- package/dist/bitcoin/coinselect2/utils.js +158 -158
- package/dist/bitcoin/wallet/BitcoinWallet.d.ts +113 -113
- package/dist/bitcoin/wallet/BitcoinWallet.js +335 -335
- package/dist/bitcoin/wallet/IBitcoinWallet.d.ts +116 -116
- package/dist/bitcoin/wallet/IBitcoinWallet.js +21 -21
- package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.d.ts +106 -106
- package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.js +196 -196
- package/dist/enums/FeeType.d.ts +15 -15
- package/dist/enums/FeeType.js +19 -19
- package/dist/enums/SwapAmountType.d.ts +15 -15
- package/dist/enums/SwapAmountType.js +19 -19
- package/dist/enums/SwapDirection.d.ts +15 -15
- package/dist/enums/SwapDirection.js +19 -19
- package/dist/enums/SwapSide.d.ts +15 -15
- package/dist/enums/SwapSide.js +19 -19
- package/dist/enums/SwapType.d.ts +75 -75
- package/dist/enums/SwapType.js +79 -79
- package/dist/errors/IntermediaryError.d.ts +13 -13
- package/dist/errors/IntermediaryError.js +27 -27
- package/dist/errors/RequestError.d.ts +32 -32
- package/dist/errors/RequestError.js +54 -54
- package/dist/errors/UserError.d.ts +8 -8
- package/dist/errors/UserError.js +16 -16
- package/dist/events/UnifiedSwapEventListener.d.ts +24 -24
- package/dist/events/UnifiedSwapEventListener.js +138 -138
- package/dist/http/HttpUtils.d.ts +29 -29
- package/dist/http/HttpUtils.js +97 -97
- package/dist/http/paramcoders/IParamReader.d.ts +8 -8
- package/dist/http/paramcoders/IParamReader.js +2 -2
- package/dist/http/paramcoders/ParamDecoder.d.ts +44 -44
- package/dist/http/paramcoders/ParamDecoder.js +137 -137
- package/dist/http/paramcoders/ParamEncoder.d.ts +20 -20
- package/dist/http/paramcoders/ParamEncoder.js +36 -36
- package/dist/http/paramcoders/SchemaVerifier.d.ts +26 -26
- package/dist/http/paramcoders/SchemaVerifier.js +145 -145
- package/dist/http/paramcoders/client/ResponseParamDecoder.d.ts +11 -11
- package/dist/http/paramcoders/client/ResponseParamDecoder.js +57 -57
- package/dist/http/paramcoders/client/StreamParamEncoder.d.ts +13 -13
- package/dist/http/paramcoders/client/StreamParamEncoder.js +26 -26
- package/dist/http/paramcoders/client/StreamingFetchPromise.d.ts +17 -17
- package/dist/http/paramcoders/client/StreamingFetchPromise.js +175 -175
- package/dist/index.d.ts +86 -86
- package/dist/index.js +159 -159
- package/dist/intermediaries/Intermediary.d.ts +178 -178
- package/dist/intermediaries/Intermediary.js +166 -166
- package/dist/intermediaries/IntermediaryDiscovery.d.ts +216 -216
- package/dist/intermediaries/IntermediaryDiscovery.js +424 -424
- package/dist/intermediaries/apis/IntermediaryAPI.d.ts +607 -607
- package/dist/intermediaries/apis/IntermediaryAPI.js +764 -764
- package/dist/intermediaries/apis/TrustedIntermediaryAPI.d.ts +155 -155
- package/dist/intermediaries/apis/TrustedIntermediaryAPI.js +137 -137
- package/dist/intermediaries/auth/SignedKeyBasedAuth.d.ts +14 -14
- package/dist/intermediaries/auth/SignedKeyBasedAuth.js +68 -68
- package/dist/lnurl/LNURL.d.ts +102 -102
- package/dist/lnurl/LNURL.js +321 -321
- package/dist/prices/RedundantSwapPrice.d.ts +110 -110
- package/dist/prices/RedundantSwapPrice.js +222 -222
- package/dist/prices/SingleSwapPrice.d.ts +34 -34
- package/dist/prices/SingleSwapPrice.js +44 -44
- package/dist/prices/SwapPriceWithChain.d.ts +107 -107
- package/dist/prices/SwapPriceWithChain.js +128 -128
- package/dist/prices/abstract/ICachedSwapPrice.d.ts +28 -28
- package/dist/prices/abstract/ICachedSwapPrice.js +62 -62
- package/dist/prices/abstract/IPriceProvider.d.ts +81 -81
- package/dist/prices/abstract/IPriceProvider.js +74 -74
- package/dist/prices/abstract/ISwapPrice.d.ts +168 -168
- package/dist/prices/abstract/ISwapPrice.js +279 -279
- package/dist/prices/providers/BinancePriceProvider.d.ts +23 -23
- package/dist/prices/providers/BinancePriceProvider.js +30 -30
- package/dist/prices/providers/CoinGeckoPriceProvider.d.ts +23 -23
- package/dist/prices/providers/CoinGeckoPriceProvider.js +29 -29
- package/dist/prices/providers/CoinPaprikaPriceProvider.d.ts +25 -25
- package/dist/prices/providers/CoinPaprikaPriceProvider.js +29 -29
- package/dist/prices/providers/CustomPriceProvider.d.ts +24 -24
- package/dist/prices/providers/CustomPriceProvider.js +35 -35
- package/dist/prices/providers/KrakenPriceProvider.d.ts +38 -38
- package/dist/prices/providers/KrakenPriceProvider.js +45 -45
- package/dist/prices/providers/OKXPriceProvider.d.ts +34 -34
- package/dist/prices/providers/OKXPriceProvider.js +29 -29
- package/dist/prices/providers/abstract/ExchangePriceProvider.d.ts +17 -17
- package/dist/prices/providers/abstract/ExchangePriceProvider.js +21 -21
- package/dist/prices/providers/abstract/HttpPriceProvider.d.ts +7 -7
- package/dist/prices/providers/abstract/HttpPriceProvider.js +12 -12
- package/dist/storage/IUnifiedStorage.d.ts +127 -127
- package/dist/storage/IUnifiedStorage.js +2 -2
- package/dist/storage/UnifiedSwapStorage.d.ts +120 -120
- package/dist/storage/UnifiedSwapStorage.js +154 -154
- package/dist/storage-browser/IndexedDBUnifiedStorage.d.ts +63 -63
- package/dist/storage-browser/IndexedDBUnifiedStorage.js +298 -298
- package/dist/storage-browser/LocalStorageManager.d.ts +49 -49
- package/dist/storage-browser/LocalStorageManager.js +93 -93
- package/dist/swapper/Swapper.d.ts +765 -765
- package/dist/swapper/Swapper.js +1749 -1749
- package/dist/swapper/SwapperFactory.d.ts +135 -135
- package/dist/swapper/SwapperFactory.js +162 -162
- package/dist/swapper/SwapperUtils.d.ts +222 -222
- package/dist/swapper/SwapperUtils.js +519 -519
- package/dist/swapper/SwapperWithChain.d.ts +404 -404
- package/dist/swapper/SwapperWithChain.js +469 -469
- package/dist/swapper/SwapperWithSigner.d.ts +322 -322
- package/dist/swapper/SwapperWithSigner.js +318 -318
- package/dist/swaps/IAddressSwap.d.ts +22 -22
- package/dist/swaps/IAddressSwap.js +14 -14
- package/dist/swaps/IBTCWalletSwap.d.ts +73 -73
- package/dist/swaps/IBTCWalletSwap.js +18 -18
- package/dist/swaps/IClaimableSwap.d.ts +49 -49
- package/dist/swaps/IClaimableSwap.js +15 -15
- package/dist/swaps/IClaimableSwapWrapper.d.ts +15 -15
- package/dist/swaps/IClaimableSwapWrapper.js +2 -2
- package/dist/swaps/IRefundableSwap.d.ts +43 -43
- package/dist/swaps/IRefundableSwap.js +14 -14
- package/dist/swaps/ISwap.d.ts +453 -453
- package/dist/swaps/ISwap.js +371 -371
- package/dist/swaps/ISwapWithGasDrop.d.ts +21 -21
- package/dist/swaps/ISwapWithGasDrop.js +12 -12
- package/dist/swaps/ISwapWrapper.d.ts +295 -295
- package/dist/swaps/ISwapWrapper.js +373 -373
- package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.d.ts +98 -98
- package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.js +126 -126
- package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +139 -139
- package/dist/swaps/escrow_swaps/IEscrowSwap.js +172 -172
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.d.ts +129 -129
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +167 -167
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.d.ts +107 -107
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.js +130 -130
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.d.ts +162 -162
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.js +190 -190
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.d.ts +64 -64
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.js +82 -82
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +547 -547
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +1419 -1419
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +192 -192
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +432 -432
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +650 -650
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +1577 -1577
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +237 -237
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +525 -525
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +491 -491
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +1463 -1463
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +204 -204
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +406 -406
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +446 -446
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +1097 -1097
- package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.d.ts +68 -68
- package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.js +117 -117
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.d.ts +127 -127
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.js +256 -256
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +252 -252
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +535 -535
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.d.ts +73 -73
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.js +155 -155
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +134 -134
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +286 -286
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +694 -694
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +1687 -1687
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +259 -259
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +947 -947
- package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +302 -302
- package/dist/swaps/trusted/ln/LnForGasSwap.js +625 -625
- package/dist/swaps/trusted/ln/LnForGasWrapper.d.ts +40 -40
- package/dist/swaps/trusted/ln/LnForGasWrapper.js +82 -82
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +343 -343
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +698 -698
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.d.ts +71 -71
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +93 -93
- package/dist/types/AmountData.d.ts +10 -10
- package/dist/types/AmountData.js +2 -2
- package/dist/types/CustomPriceFunction.d.ts +11 -11
- package/dist/types/CustomPriceFunction.js +2 -2
- package/dist/types/PriceInfoType.d.ts +28 -28
- package/dist/types/PriceInfoType.js +57 -57
- package/dist/types/SwapExecutionAction.d.ts +195 -195
- package/dist/types/SwapExecutionAction.js +106 -106
- package/dist/types/SwapExecutionStep.d.ts +144 -144
- package/dist/types/SwapExecutionStep.js +87 -87
- package/dist/types/SwapStateInfo.d.ts +5 -5
- package/dist/types/SwapStateInfo.js +2 -2
- package/dist/types/SwapWithSigner.d.ts +17 -17
- package/dist/types/SwapWithSigner.js +43 -43
- package/dist/types/Token.d.ts +99 -99
- package/dist/types/Token.js +76 -76
- package/dist/types/TokenAmount.d.ts +75 -75
- package/dist/types/TokenAmount.js +85 -85
- package/dist/types/fees/Fee.d.ts +50 -50
- package/dist/types/fees/Fee.js +2 -2
- package/dist/types/fees/FeeBreakdown.d.ts +11 -11
- package/dist/types/fees/FeeBreakdown.js +2 -2
- package/dist/types/fees/PercentagePPM.d.ts +17 -17
- package/dist/types/fees/PercentagePPM.js +18 -18
- package/dist/types/lnurl/LNURLPay.d.ts +61 -61
- package/dist/types/lnurl/LNURLPay.js +31 -31
- package/dist/types/lnurl/LNURLWithdraw.d.ts +48 -48
- package/dist/types/lnurl/LNURLWithdraw.js +27 -27
- package/dist/types/wallets/LightningInvoiceCreateService.d.ts +24 -24
- package/dist/types/wallets/LightningInvoiceCreateService.js +15 -15
- package/dist/types/wallets/MinimalBitcoinWalletInterface.d.ts +23 -23
- package/dist/types/wallets/MinimalBitcoinWalletInterface.js +2 -2
- package/dist/types/wallets/MinimalLightningNetworkWalletInterface.d.ts +9 -9
- package/dist/types/wallets/MinimalLightningNetworkWalletInterface.js +2 -2
- package/dist/utils/AutomaticClockDriftCorrection.d.ts +1 -1
- package/dist/utils/AutomaticClockDriftCorrection.js +70 -70
- package/dist/utils/BitcoinUtils.d.ts +18 -18
- package/dist/utils/BitcoinUtils.js +174 -174
- package/dist/utils/BitcoinWalletUtils.d.ts +7 -7
- package/dist/utils/BitcoinWalletUtils.js +14 -14
- package/dist/utils/Logger.d.ts +7 -7
- package/dist/utils/Logger.js +12 -12
- package/dist/utils/RetryUtils.d.ts +22 -22
- package/dist/utils/RetryUtils.js +67 -67
- package/dist/utils/SwapUtils.d.ts +88 -88
- package/dist/utils/SwapUtils.js +72 -72
- package/dist/utils/TimeoutUtils.d.ts +17 -17
- package/dist/utils/TimeoutUtils.js +55 -55
- package/dist/utils/TokenUtils.d.ts +19 -19
- package/dist/utils/TokenUtils.js +37 -37
- package/dist/utils/TypeUtils.d.ts +7 -7
- package/dist/utils/TypeUtils.js +2 -2
- package/dist/utils/Utils.d.ts +69 -69
- package/dist/utils/Utils.js +214 -214
- package/package.json +46 -46
- package/src/SmartChainAssets.ts +186 -186
- package/src/api/ApiEndpoints.ts +427 -427
- package/src/api/ApiParser.ts +138 -138
- package/src/api/ApiTypes.ts +229 -229
- package/src/api/SerializedAction.ts +97 -97
- package/src/api/SwapperApi.ts +545 -545
- package/src/api/index.ts +5 -5
- package/src/bitcoin/coinselect2/accumulative.ts +69 -69
- package/src/bitcoin/coinselect2/blackjack.ts +50 -50
- package/src/bitcoin/coinselect2/index.ts +93 -93
- package/src/bitcoin/coinselect2/utils.ts +236 -236
- package/src/bitcoin/wallet/BitcoinWallet.ts +439 -439
- package/src/bitcoin/wallet/IBitcoinWallet.ts +140 -140
- package/src/bitcoin/wallet/SingleAddressBitcoinWallet.ts +225 -225
- package/src/enums/FeeType.ts +15 -15
- package/src/enums/SwapAmountType.ts +16 -16
- package/src/enums/SwapDirection.ts +15 -15
- package/src/enums/SwapSide.ts +16 -16
- package/src/enums/SwapType.ts +75 -75
- package/src/errors/IntermediaryError.ts +28 -28
- package/src/errors/RequestError.ts +64 -64
- package/src/errors/UserError.ts +15 -15
- package/src/events/UnifiedSwapEventListener.ts +181 -181
- package/src/http/HttpUtils.ts +97 -97
- package/src/http/paramcoders/IParamReader.ts +9 -9
- package/src/http/paramcoders/ParamDecoder.ts +145 -145
- package/src/http/paramcoders/ParamEncoder.ts +40 -40
- package/src/http/paramcoders/SchemaVerifier.ts +153 -153
- package/src/http/paramcoders/client/ResponseParamDecoder.ts +57 -57
- package/src/http/paramcoders/client/StreamParamEncoder.ts +28 -28
- package/src/http/paramcoders/client/StreamingFetchPromise.ts +194 -194
- package/src/index.ts +141 -141
- package/src/intermediaries/Intermediary.ts +280 -280
- package/src/intermediaries/IntermediaryDiscovery.ts +548 -548
- package/src/intermediaries/apis/IntermediaryAPI.ts +1247 -1247
- package/src/intermediaries/auth/SignedKeyBasedAuth.ts +69 -69
- package/src/lnurl/LNURL.ts +402 -402
- package/src/prices/RedundantSwapPrice.ts +264 -264
- package/src/prices/SingleSwapPrice.ts +50 -50
- package/src/prices/SwapPriceWithChain.ts +194 -194
- package/src/prices/abstract/ICachedSwapPrice.ts +85 -85
- package/src/prices/abstract/IPriceProvider.ts +127 -127
- package/src/prices/abstract/ISwapPrice.ts +390 -390
- package/src/prices/providers/BinancePriceProvider.ts +48 -48
- package/src/prices/providers/CoinGeckoPriceProvider.ts +46 -46
- package/src/prices/providers/CoinPaprikaPriceProvider.ts +49 -49
- package/src/prices/providers/CustomPriceProvider.ts +40 -40
- package/src/prices/providers/KrakenPriceProvider.ts +83 -83
- package/src/prices/providers/OKXPriceProvider.ts +59 -59
- package/src/prices/providers/abstract/ExchangePriceProvider.ts +31 -31
- package/src/prices/providers/abstract/HttpPriceProvider.ts +14 -14
- package/src/storage/IUnifiedStorage.ts +136 -136
- package/src/storage/UnifiedSwapStorage.ts +175 -175
- package/src/storage-browser/IndexedDBUnifiedStorage.ts +350 -350
- package/src/storage-browser/LocalStorageManager.ts +106 -106
- package/src/swapper/Swapper.ts +2557 -2557
- package/src/swapper/SwapperFactory.ts +307 -307
- package/src/swapper/SwapperUtils.ts +610 -610
- package/src/swapper/SwapperWithChain.ts +707 -707
- package/src/swapper/SwapperWithSigner.ts +511 -511
- package/src/swaps/IAddressSwap.ts +30 -30
- package/src/swaps/IBTCWalletSwap.ts +92 -92
- package/src/swaps/IClaimableSwap.ts +65 -65
- package/src/swaps/IClaimableSwapWrapper.ts +17 -17
- package/src/swaps/IRefundableSwap.ts +58 -58
- package/src/swaps/ISwap.ts +775 -775
- package/src/swaps/ISwapWithGasDrop.ts +25 -25
- package/src/swaps/ISwapWrapper.ts +564 -564
- package/src/swaps/escrow_swaps/IEscrowSelfInitSwap.ts +217 -217
- package/src/swaps/escrow_swaps/IEscrowSwap.ts +271 -271
- package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +284 -284
- package/src/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.ts +172 -172
- package/src/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.ts +300 -300
- package/src/swaps/escrow_swaps/frombtc/IFromBTCWrapper.ts +107 -107
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +1670 -1671
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +603 -603
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +1883 -1883
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +752 -752
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +1753 -1753
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +612 -612
- package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +1327 -1327
- package/src/swaps/escrow_swaps/tobtc/IToBTCWrapper.ts +138 -138
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.ts +304 -304
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +787 -787
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.ts +206 -206
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +403 -403
- package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +2148 -2148
- package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +1238 -1238
- package/src/swaps/trusted/ln/LnForGasSwap.ts +753 -753
- package/src/swaps/trusted/ln/LnForGasWrapper.ts +90 -90
- package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +843 -843
- package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +133 -133
- package/src/types/AmountData.ts +9 -9
- package/src/types/CustomPriceFunction.ts +11 -11
- package/src/types/PriceInfoType.ts +66 -66
- package/src/types/SwapExecutionAction.ts +323 -323
- package/src/types/SwapExecutionStep.ts +224 -224
- package/src/types/SwapStateInfo.ts +6 -6
- package/src/types/SwapWithSigner.ts +61 -61
- package/src/types/Token.ts +163 -163
- package/src/types/TokenAmount.ts +167 -167
- package/src/types/fees/Fee.ts +56 -56
- package/src/types/fees/FeeBreakdown.ts +11 -11
- package/src/types/fees/PercentagePPM.ts +26 -26
- package/src/types/lnurl/LNURLPay.ts +79 -79
- package/src/types/lnurl/LNURLWithdraw.ts +61 -61
- package/src/types/wallets/LightningInvoiceCreateService.ts +30 -30
- package/src/types/wallets/MinimalBitcoinWalletInterface.ts +21 -21
- package/src/types/wallets/MinimalLightningNetworkWalletInterface.ts +9 -9
- package/src/utils/AutomaticClockDriftCorrection.ts +71 -71
- package/src/utils/BitcoinUtils.ts +164 -164
- package/src/utils/BitcoinWalletUtils.ts +15 -15
- package/src/utils/Logger.ts +14 -14
- package/src/utils/RetryUtils.ts +78 -78
- package/src/utils/SwapUtils.ts +99 -99
- package/src/utils/TimeoutUtils.ts +49 -49
- package/src/utils/TokenUtils.ts +33 -33
- package/src/utils/TypeUtils.ts +8 -8
- package/src/utils/Utils.ts +221 -221
|
@@ -1,611 +1,611 @@
|
|
|
1
|
-
import {decode as bolt11Decode} from "@atomiqlabs/bolt11";
|
|
2
|
-
import {Address, Transaction} from "@scure/btc-signer";
|
|
3
|
-
import {LNURL} from "../lnurl/LNURL";
|
|
4
|
-
import {BTC_NETWORK} from "@scure/btc-signer/utils";
|
|
5
|
-
import {SwapType} from "../enums/SwapType";
|
|
6
|
-
import {ChainIds, MultiChain, Swapper} from "./Swapper";
|
|
7
|
-
import {IBitcoinWallet} from "../bitcoin/wallet/IBitcoinWallet";
|
|
8
|
-
import {SingleAddressBitcoinWallet} from "../bitcoin/wallet/SingleAddressBitcoinWallet";
|
|
9
|
-
import {BigIntBufferUtils, ChainSwapType, isAbstractSigner} from "@atomiqlabs/base";
|
|
10
|
-
import {bigIntMax, fromDecimal, randomBytes} from "../utils/Utils";
|
|
11
|
-
import {MinimalBitcoinWalletInterface} from "../types/wallets/MinimalBitcoinWalletInterface";
|
|
12
|
-
import {TokenAmount, toTokenAmount} from "../types/TokenAmount";
|
|
13
|
-
import {BitcoinTokens, SCToken} from "../types/Token";
|
|
14
|
-
import {isLNURLWithdraw, LNURLWithdraw} from "../types/lnurl/LNURLWithdraw";
|
|
15
|
-
import {isLNURLPay, LNURLPay} from "../types/lnurl/LNURLPay";
|
|
16
|
-
import {toBitcoinWallet} from "../utils/BitcoinWalletUtils";
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Utility class providing helper methods for address parsing, token balances, serialization
|
|
20
|
-
* and other miscellaneous things.
|
|
21
|
-
*
|
|
22
|
-
* @category Core
|
|
23
|
-
*/
|
|
24
|
-
export class SwapperUtils<T extends MultiChain> {
|
|
25
|
-
|
|
26
|
-
readonly bitcoinNetwork: BTC_NETWORK;
|
|
27
|
-
private readonly root: Swapper<T>;
|
|
28
|
-
|
|
29
|
-
constructor(root: Swapper<T>) {
|
|
30
|
-
this.bitcoinNetwork = root._btcNetwork;
|
|
31
|
-
this.root = root;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Checks whether a passed address is a valid address on the smart chain
|
|
36
|
-
*
|
|
37
|
-
* @param address Address
|
|
38
|
-
* @param chainId Smart chain identifier string to check the address for
|
|
39
|
-
*/
|
|
40
|
-
isValidSmartChainAddress(address: string, chainId?: ChainIds<T>): boolean {
|
|
41
|
-
if(chainId!=null) {
|
|
42
|
-
if(this.root._chains[chainId]==null) throw new Error(`Unknown chain id: ${chainId}`);
|
|
43
|
-
return this.root._chains[chainId].chainInterface.isValidAddress(address);
|
|
44
|
-
}
|
|
45
|
-
for(let chainId of this.root.getSmartChains()) {
|
|
46
|
-
if(this.root._chains[chainId].chainInterface.isValidAddress(address)) return true;
|
|
47
|
-
}
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Checks whether an address is a valid BOLT11 bitcoin lightning invoice
|
|
53
|
-
*
|
|
54
|
-
* @param address Address to check
|
|
55
|
-
*/
|
|
56
|
-
isLightningInvoice(address: string): boolean {
|
|
57
|
-
try {
|
|
58
|
-
bolt11Decode(address);
|
|
59
|
-
return true;
|
|
60
|
-
} catch (e) {}
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Checks whether an address is a valid bitcoin address
|
|
66
|
-
*
|
|
67
|
-
* @param address Address to check
|
|
68
|
-
*/
|
|
69
|
-
isValidBitcoinAddress(address: string): boolean {
|
|
70
|
-
try {
|
|
71
|
-
Address(this.bitcoinNetwork).decode(address);
|
|
72
|
-
return true;
|
|
73
|
-
} catch (e) {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Checks whether an address is a valid BOLT11 bitcoin lightning invoice WITH AMOUNT
|
|
80
|
-
*
|
|
81
|
-
* @param address Address to check
|
|
82
|
-
*/
|
|
83
|
-
isValidLightningInvoice(address: string): boolean {
|
|
84
|
-
try {
|
|
85
|
-
const parsed = bolt11Decode(address);
|
|
86
|
-
if(parsed.millisatoshis!=null) return true;
|
|
87
|
-
} catch (e) {}
|
|
88
|
-
return false;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Checks whether an address is a valid LNURL (no checking on type is performed)
|
|
93
|
-
*
|
|
94
|
-
* @param address Address to check
|
|
95
|
-
*/
|
|
96
|
-
isValidLNURL(address: string): boolean {
|
|
97
|
-
return LNURL.isLNURL(address);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Returns type and data about an LNURL
|
|
102
|
-
*
|
|
103
|
-
* @param lnurl LNURL link to check, can be either `pay` or `withdraw` type
|
|
104
|
-
* @param shouldRetry Optional whether HTTP requests should retried on failure
|
|
105
|
-
*/
|
|
106
|
-
getLNURLTypeAndData(lnurl: string, shouldRetry?: boolean): Promise<LNURLPay | LNURLWithdraw | null> {
|
|
107
|
-
return LNURL.getLNURLType(lnurl, shouldRetry);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Returns satoshi value of BOLT11 bitcoin lightning invoice WITH AMOUNT, returns null otherwise
|
|
112
|
-
*
|
|
113
|
-
* @param lnpr
|
|
114
|
-
*/
|
|
115
|
-
getLightningInvoiceValue(lnpr: string): bigint | null {
|
|
116
|
-
const parsed = bolt11Decode(lnpr);
|
|
117
|
-
if(parsed.millisatoshis!=null) return (BigInt(parsed.millisatoshis) + 999n) / 1000n;
|
|
118
|
-
return null;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
private parseBitcoinAddress(resultText: string): {
|
|
122
|
-
address: string,
|
|
123
|
-
type: "BITCOIN",
|
|
124
|
-
swapType: SwapType.TO_BTC,
|
|
125
|
-
amount?: TokenAmount
|
|
126
|
-
} | null {
|
|
127
|
-
let _amount: bigint | undefined = undefined;
|
|
128
|
-
if(resultText.includes("?")) {
|
|
129
|
-
const arr = resultText.split("?");
|
|
130
|
-
resultText = arr[0];
|
|
131
|
-
const params = arr[1].split("&");
|
|
132
|
-
for(let param of params) {
|
|
133
|
-
const arr2 = param.split("=");
|
|
134
|
-
const key = arr2[0];
|
|
135
|
-
const value = decodeURIComponent(arr2[1]);
|
|
136
|
-
if(key==="amount") {
|
|
137
|
-
_amount = fromDecimal(parseFloat(value).toFixed(8), 8);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
if(this.isValidBitcoinAddress(resultText)) {
|
|
142
|
-
return {
|
|
143
|
-
address: resultText,
|
|
144
|
-
type: "BITCOIN",
|
|
145
|
-
swapType: SwapType.TO_BTC,
|
|
146
|
-
amount: _amount==null ? undefined : toTokenAmount(_amount, BitcoinTokens.BTC, this.root.prices)
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
return null;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
private parseLNURLSync(resultText: string): {
|
|
153
|
-
address: string,
|
|
154
|
-
type: "LNURL",
|
|
155
|
-
swapType: null
|
|
156
|
-
} | null {
|
|
157
|
-
if(this.isValidLNURL(resultText)) {
|
|
158
|
-
return {
|
|
159
|
-
address: resultText,
|
|
160
|
-
type: "LNURL",
|
|
161
|
-
swapType: null
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
return null;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
private async parseLNURL(resultText: string): Promise<{
|
|
168
|
-
address: string,
|
|
169
|
-
type: "LNURL",
|
|
170
|
-
swapType: SwapType.TO_BTCLN | SwapType.FROM_BTCLN,
|
|
171
|
-
lnurl: LNURLPay | LNURLWithdraw,
|
|
172
|
-
min?: TokenAmount,
|
|
173
|
-
max?: TokenAmount,
|
|
174
|
-
amount?: TokenAmount
|
|
175
|
-
} | null> {
|
|
176
|
-
if(this.isValidLNURL(resultText)) {
|
|
177
|
-
try {
|
|
178
|
-
const result = await this.getLNURLTypeAndData(resultText);
|
|
179
|
-
if(result==null) throw new Error("Invalid LNURL specified!");
|
|
180
|
-
const swapType = isLNURLPay(result) ? SwapType.TO_BTCLN : isLNURLWithdraw(result) ? SwapType.FROM_BTCLN : null;
|
|
181
|
-
if(swapType==null) return null;
|
|
182
|
-
const response = {
|
|
183
|
-
address: resultText,
|
|
184
|
-
type: "LNURL",
|
|
185
|
-
swapType,
|
|
186
|
-
lnurl: result
|
|
187
|
-
} as const;
|
|
188
|
-
if(result.min===result.max) {
|
|
189
|
-
return {
|
|
190
|
-
...response,
|
|
191
|
-
amount: result.min==null ? undefined : toTokenAmount(result.min, BitcoinTokens.BTCLN, this.root.prices)
|
|
192
|
-
}
|
|
193
|
-
} else {
|
|
194
|
-
return {
|
|
195
|
-
...response,
|
|
196
|
-
min: result.min==null ? undefined : toTokenAmount(result.min, BitcoinTokens.BTCLN, this.root.prices),
|
|
197
|
-
max: result.min==null ? undefined : toTokenAmount(result.max, BitcoinTokens.BTCLN, this.root.prices)
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
} catch (e) {
|
|
201
|
-
throw new Error("Failed to contact LNURL service, check your internet connection and retry later.");
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
return null;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
private parseLightningInvoice(resultText: string): {
|
|
208
|
-
address: string,
|
|
209
|
-
type: "LIGHTNING",
|
|
210
|
-
swapType: SwapType.TO_BTCLN,
|
|
211
|
-
amount: TokenAmount
|
|
212
|
-
} | null {
|
|
213
|
-
if(this.isLightningInvoice(resultText)) {
|
|
214
|
-
if(this.isValidLightningInvoice(resultText)) {
|
|
215
|
-
const amount = this.getLightningInvoiceValue(resultText);
|
|
216
|
-
if(amount==null) throw new Error();
|
|
217
|
-
return {
|
|
218
|
-
address: resultText,
|
|
219
|
-
type: "LIGHTNING",
|
|
220
|
-
swapType: SwapType.TO_BTCLN,
|
|
221
|
-
amount: toTokenAmount(amount, BitcoinTokens.BTCLN, this.root.prices)
|
|
222
|
-
}
|
|
223
|
-
} else {
|
|
224
|
-
throw new Error("Lightning invoice needs to contain an amount!");
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
return null;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
private parseSmartchainAddress(resultText: string): {
|
|
231
|
-
address: string,
|
|
232
|
-
type: ChainIds<T>,
|
|
233
|
-
swapType: null,
|
|
234
|
-
min?: TokenAmount,
|
|
235
|
-
max?: TokenAmount
|
|
236
|
-
} | null {
|
|
237
|
-
for(let chainId of this.root.getSmartChains()) {
|
|
238
|
-
if(this.root._chains[chainId].chainInterface.isValidAddress(resultText)) {
|
|
239
|
-
return {
|
|
240
|
-
address: resultText,
|
|
241
|
-
type: chainId,
|
|
242
|
-
swapType: null
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
return null;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* General parser for bitcoin addresses, LNURLs, lightning invoices, smart chain addresses. Also fetches LNURL data
|
|
251
|
-
* (hence async and returns Promise).
|
|
252
|
-
*
|
|
253
|
-
* @param addressString Address to parse
|
|
254
|
-
* @throws {Error} Error in address parsing
|
|
255
|
-
* @returns Address data or `null` if address doesn't conform to any known format
|
|
256
|
-
*/
|
|
257
|
-
async parseAddress(addressString: string): Promise<{
|
|
258
|
-
address: string,
|
|
259
|
-
type: "BITCOIN" | "LIGHTNING" | "LNURL" | ChainIds<T>,
|
|
260
|
-
swapType: SwapType.TO_BTC | SwapType.TO_BTCLN | SwapType.SPV_VAULT_FROM_BTC | SwapType.FROM_BTCLN | null,
|
|
261
|
-
lnurl?: LNURLPay | LNURLWithdraw,
|
|
262
|
-
min?: TokenAmount,
|
|
263
|
-
max?: TokenAmount,
|
|
264
|
-
amount?: TokenAmount
|
|
265
|
-
} | null> {
|
|
266
|
-
if(addressString.startsWith("bitcoin:")) {
|
|
267
|
-
const parsedBitcoinAddress = this.parseBitcoinAddress(addressString.substring(8));
|
|
268
|
-
if(parsedBitcoinAddress!=null) return parsedBitcoinAddress;
|
|
269
|
-
throw new Error("Invalid bitcoin address!");
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
const parsedBitcoinAddress = this.parseBitcoinAddress(addressString);
|
|
273
|
-
if(parsedBitcoinAddress!=null) return parsedBitcoinAddress;
|
|
274
|
-
|
|
275
|
-
if(addressString.startsWith("lightning:")) {
|
|
276
|
-
const resultText = addressString.substring(10);
|
|
277
|
-
const resultLnurl = await this.parseLNURL(resultText);
|
|
278
|
-
if(resultLnurl!=null) return resultLnurl;
|
|
279
|
-
|
|
280
|
-
const resultLightningInvoice = this.parseLightningInvoice(resultText);
|
|
281
|
-
if(resultLightningInvoice!=null) return resultLightningInvoice;
|
|
282
|
-
|
|
283
|
-
throw new Error("Invalid lightning network invoice or LNURL!");
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
const resultLnurl = await this.parseLNURL(addressString);
|
|
287
|
-
if(resultLnurl!=null) return resultLnurl;
|
|
288
|
-
|
|
289
|
-
const resultLightningInvoice = this.parseLightningInvoice(addressString);
|
|
290
|
-
if(resultLightningInvoice!=null) return resultLightningInvoice;
|
|
291
|
-
|
|
292
|
-
return this.parseSmartchainAddress(addressString);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Synchronous general parser for bitcoin addresses, LNURLs, lightning invoices, smart chain addresses, doesn't fetch
|
|
297
|
-
* LNURL data, returns `swapType: null` instead to prevent returning a Promise
|
|
298
|
-
*
|
|
299
|
-
* @param addressString Address to parse
|
|
300
|
-
* @throws {Error} Error in address parsing
|
|
301
|
-
* @returns Address data or `null` if address doesn't conform to any known format
|
|
302
|
-
*/
|
|
303
|
-
parseAddressSync(addressString: string): {
|
|
304
|
-
address: string,
|
|
305
|
-
type: "BITCOIN" | "LIGHTNING" | "LNURL" | ChainIds<T>,
|
|
306
|
-
swapType: SwapType.TO_BTC | SwapType.TO_BTCLN | SwapType.SPV_VAULT_FROM_BTC | null,
|
|
307
|
-
min?: TokenAmount,
|
|
308
|
-
max?: TokenAmount,
|
|
309
|
-
amount?: TokenAmount
|
|
310
|
-
} | null {
|
|
311
|
-
if(addressString.startsWith("bitcoin:")) {
|
|
312
|
-
const parsedBitcoinAddress = this.parseBitcoinAddress(addressString.substring(8));
|
|
313
|
-
if(parsedBitcoinAddress!=null) return parsedBitcoinAddress;
|
|
314
|
-
throw new Error("Invalid bitcoin address!");
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
const parsedBitcoinAddress = this.parseBitcoinAddress(addressString);
|
|
318
|
-
if(parsedBitcoinAddress!=null) return parsedBitcoinAddress;
|
|
319
|
-
|
|
320
|
-
if(addressString.startsWith("lightning:")) {
|
|
321
|
-
const resultText = addressString.substring(10);
|
|
322
|
-
const resultLnurl = this.parseLNURLSync(resultText);
|
|
323
|
-
if(resultLnurl!=null) return resultLnurl;
|
|
324
|
-
|
|
325
|
-
const resultLightningInvoice = this.parseLightningInvoice(resultText);
|
|
326
|
-
if(resultLightningInvoice!=null) return resultLightningInvoice;
|
|
327
|
-
|
|
328
|
-
throw new Error("Invalid lightning network invoice or LNURL!");
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
const resultLnurl = this.parseLNURLSync(addressString);
|
|
332
|
-
if(resultLnurl!=null) return resultLnurl;
|
|
333
|
-
|
|
334
|
-
const resultLightningInvoice = this.parseLightningInvoice(addressString);
|
|
335
|
-
if(resultLightningInvoice!=null) return resultLightningInvoice;
|
|
336
|
-
|
|
337
|
-
return this.parseSmartchainAddress(addressString);
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
/**
|
|
341
|
-
* Strips the URL encoding around `bitcoin:` and `lightning:` addresses, leaving just the raw address
|
|
342
|
-
*
|
|
343
|
-
* @param addressString Address to strip
|
|
344
|
-
*
|
|
345
|
-
* @returns Raw clean address
|
|
346
|
-
*/
|
|
347
|
-
stripAddress(addressString: string): string {
|
|
348
|
-
if(addressString.startsWith("lightning:") || addressString.startsWith("bitcoin:")) {
|
|
349
|
-
addressString = addressString.substring(addressString.indexOf(":")+1);
|
|
350
|
-
const delimeterIndex = addressString.indexOf("?");
|
|
351
|
-
if(delimeterIndex!==-1) addressString = addressString.substring(0, delimeterIndex);
|
|
352
|
-
}
|
|
353
|
-
return addressString;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
/**
|
|
357
|
-
* Returns a random PSBT that can be used for fee estimation for SPV vault (UTXO-controlled vault) based swaps
|
|
358
|
-
* {@link SwapType.SPV_VAULT_FROM_BTC}, the last output (the LP output) is omitted to allow for coinselection
|
|
359
|
-
* algorithm to determine maximum sendable amount there
|
|
360
|
-
*
|
|
361
|
-
* @param chainIdentifier Smart chain to swap to
|
|
362
|
-
* @param includeGasToken Whether to return the PSBT also with the gas token amount (increases the vSize by 8)
|
|
363
|
-
*/
|
|
364
|
-
getRandomSpvVaultPsbt<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier, includeGasToken?: boolean): Transaction {
|
|
365
|
-
const wrapper = this.root._chains[chainIdentifier].wrappers[SwapType.SPV_VAULT_FROM_BTC];
|
|
366
|
-
if(wrapper==null) throw new Error("Chain doesn't support spv vault swaps!");
|
|
367
|
-
return wrapper.getDummySwapPsbt(includeGasToken);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
/**
|
|
371
|
-
* Returns the spendable balance of a bitcoin wallet
|
|
372
|
-
*
|
|
373
|
-
* @param wallet Bitcoin wallet to check the spendable balance for, can either be a simple
|
|
374
|
-
* bitcoin address string or a wallet object
|
|
375
|
-
* @param targetChain Destination smart chain for the swap, the ensures proper spendable balance
|
|
376
|
-
* is estimated taking into consideration different swap primitives available on different chains
|
|
377
|
-
* @param options Additional options
|
|
378
|
-
*/
|
|
379
|
-
async getBitcoinSpendableBalance(
|
|
380
|
-
wallet: string | IBitcoinWallet | MinimalBitcoinWalletInterface,
|
|
381
|
-
targetChain?: ChainIds<T>,
|
|
382
|
-
options?: {
|
|
383
|
-
gasDrop?: boolean,
|
|
384
|
-
feeRate?: number,
|
|
385
|
-
minFeeRate?: number
|
|
386
|
-
}
|
|
387
|
-
): Promise<{
|
|
388
|
-
balance: TokenAmount,
|
|
389
|
-
feeRate: number
|
|
390
|
-
}> {
|
|
391
|
-
let bitcoinWallet: IBitcoinWallet;
|
|
392
|
-
if(typeof(wallet)==="string") {
|
|
393
|
-
bitcoinWallet = new SingleAddressBitcoinWallet(this.root._bitcoinRpc, this.bitcoinNetwork, {address: wallet, publicKey: ""});
|
|
394
|
-
} else {
|
|
395
|
-
bitcoinWallet = toBitcoinWallet(wallet, this.root._bitcoinRpc, this.bitcoinNetwork);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
let feeRate = options?.feeRate ?? await bitcoinWallet.getFeeRate();
|
|
399
|
-
if(options?.minFeeRate!=null) feeRate = Math.max(feeRate, options.minFeeRate);
|
|
400
|
-
|
|
401
|
-
let result: {balance: bigint, feeRate: number, totalFee: number};
|
|
402
|
-
if(targetChain!=null && this.root.supportsSwapType(targetChain, SwapType.SPV_VAULT_FROM_BTC)) {
|
|
403
|
-
result = await bitcoinWallet.getSpendableBalance(this.getRandomSpvVaultPsbt(targetChain, options?.gasDrop), feeRate);
|
|
404
|
-
} else {
|
|
405
|
-
result = await bitcoinWallet.getSpendableBalance(undefined, feeRate);
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
return {
|
|
409
|
-
balance: toTokenAmount(result.balance, BitcoinTokens.BTC, this.root.prices),
|
|
410
|
-
feeRate: result.feeRate
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
/**
|
|
415
|
-
* Returns the maximum spendable balance of the smart chain wallet, deducting the fee needed
|
|
416
|
-
* to initiate a swap for native balances
|
|
417
|
-
*/
|
|
418
|
-
async getSpendableBalance<ChainIdentifier extends ChainIds<T>>(wallet: string | T[ChainIdentifier]["Signer"] | T[ChainIdentifier]["NativeSigner"], token: SCToken<ChainIdentifier>, options?: {
|
|
419
|
-
feeMultiplier?: number,
|
|
420
|
-
feeRate?: any
|
|
421
|
-
}): Promise<TokenAmount> {
|
|
422
|
-
if(this.root._chains[token.chainId]==null) throw new Error("Invalid chain identifier! Unknown chain: "+token.chainId);
|
|
423
|
-
const {defaultVersion, versionedContracts, chainInterface} = this.root._chains[token.chainId];
|
|
424
|
-
|
|
425
|
-
const {swapContract} = versionedContracts[defaultVersion];
|
|
426
|
-
|
|
427
|
-
let signer: string;
|
|
428
|
-
if(typeof(wallet)==="string") {
|
|
429
|
-
signer = wallet;
|
|
430
|
-
} else {
|
|
431
|
-
const abstractSigner = isAbstractSigner(wallet) ? wallet : await chainInterface.wrapSigner(wallet);
|
|
432
|
-
signer = abstractSigner.getAddress();
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
let finalBalance: bigint;
|
|
436
|
-
if(chainInterface.getNativeCurrencyAddress()!==token.address) {
|
|
437
|
-
finalBalance = await chainInterface.getBalance(signer, token.address);
|
|
438
|
-
} else {
|
|
439
|
-
let [balance, commitFee] = await Promise.all([
|
|
440
|
-
chainInterface.getBalance(signer, token.address),
|
|
441
|
-
swapContract.getCommitFee(
|
|
442
|
-
signer,
|
|
443
|
-
//Use large amount, such that the fee for wrapping more tokens is always included!
|
|
444
|
-
await swapContract.createSwapData(
|
|
445
|
-
ChainSwapType.HTLC, signer, chainInterface.randomAddress(), token.address,
|
|
446
|
-
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn,
|
|
447
|
-
swapContract.getHashForHtlc(randomBytes(32)).toString("hex"),
|
|
448
|
-
BigIntBufferUtils.fromBuffer(randomBytes(8)), BigInt(Math.floor(Date.now()/1000)),
|
|
449
|
-
true, false, BigIntBufferUtils.fromBuffer(randomBytes(2)), BigIntBufferUtils.fromBuffer(randomBytes(2))
|
|
450
|
-
),
|
|
451
|
-
options?.feeRate
|
|
452
|
-
)
|
|
453
|
-
]);
|
|
454
|
-
|
|
455
|
-
if(options?.feeMultiplier!=null) {
|
|
456
|
-
commitFee = commitFee * (BigInt(Math.floor(options.feeMultiplier*1000000))) / 1000000n;
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
finalBalance = bigIntMax(balance - commitFee, 0n);
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
return toTokenAmount(finalBalance, token, this.root.prices);
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
/**
|
|
466
|
-
* Returns the address of the native currency of the smart chain
|
|
467
|
-
*/
|
|
468
|
-
getNativeToken<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier): SCToken<ChainIdentifier> {
|
|
469
|
-
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
470
|
-
return this.root._tokens[chainIdentifier][this.root._chains[chainIdentifier].chainInterface.getNativeCurrencyAddress()] as SCToken<ChainIdentifier>;
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
/**
|
|
474
|
-
* Returns whether when swapping to the provided token a gas drop can be requested
|
|
475
|
-
*
|
|
476
|
-
* @param token
|
|
477
|
-
*/
|
|
478
|
-
destinationTokenSupportsGasDrop<ChainIdentifier extends ChainIds<T>>(token: SCToken<ChainIdentifier>): boolean {
|
|
479
|
-
if(this.root._chains[token.chainId]==null) throw new Error("Invalid chain identifier! Unknown chain: "+token.chainId);
|
|
480
|
-
const {chainInterface} = this.root._chains[token.chainId];
|
|
481
|
-
if(chainInterface.shouldGetNativeTokenDrop!=null) return chainInterface.shouldGetNativeTokenDrop(token.address);
|
|
482
|
-
return chainInterface.getNativeCurrencyAddress() !== token.address;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
/**
|
|
486
|
-
* Returns a random signer for a given smart chain
|
|
487
|
-
*
|
|
488
|
-
* @param chainIdentifier
|
|
489
|
-
*/
|
|
490
|
-
randomSigner<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier): T[ChainIdentifier]["Signer"] {
|
|
491
|
-
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
492
|
-
return this.root._chains[chainIdentifier].chainInterface.randomSigner();
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
/**
|
|
496
|
-
* Returns a random address for a given smart chain or bitcoin
|
|
497
|
-
*
|
|
498
|
-
* @param chainIdentifier
|
|
499
|
-
*/
|
|
500
|
-
randomAddress<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier | "BITCOIN"): string {
|
|
501
|
-
if(chainIdentifier==="BITCOIN") {
|
|
502
|
-
// Return random p2wkh address
|
|
503
|
-
return Address(this.bitcoinNetwork).encode({
|
|
504
|
-
type: "wpkh",
|
|
505
|
-
hash: randomBytes(20)
|
|
506
|
-
});
|
|
507
|
-
}
|
|
508
|
-
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
509
|
-
return this.root._chains[chainIdentifier].chainInterface.randomAddress();
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
/**
|
|
513
|
-
* Signs and broadcasts the supplied smart chain transaction
|
|
514
|
-
*
|
|
515
|
-
* @param chainIdentifier Smart chain identifier string
|
|
516
|
-
* @param signer Signer to use for signing the transactions
|
|
517
|
-
* @param txs An array of transactions to sign
|
|
518
|
-
* @param abortSignal Abort signal
|
|
519
|
-
* @param onBeforePublish Callback invoked before a transaction is sent (invoked for every transaction to be sent)
|
|
520
|
-
*/
|
|
521
|
-
sendAndConfirm<ChainIdentifier extends ChainIds<T>>(
|
|
522
|
-
chainIdentifier: ChainIdentifier,
|
|
523
|
-
signer: T[ChainIdentifier]["NativeSigner"] | T[ChainIdentifier]["Signer"],
|
|
524
|
-
txs: T[ChainIdentifier]["TX"][],
|
|
525
|
-
abortSignal?: AbortSignal,
|
|
526
|
-
onBeforePublish?: (txId: string, rawTx: string) => Promise<void>
|
|
527
|
-
): Promise<string[]> {
|
|
528
|
-
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
529
|
-
return this.root._chains[chainIdentifier].chainInterface.sendAndConfirm(signer, txs, true, abortSignal, false, onBeforePublish);
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
/**
|
|
533
|
-
* Broadcasts already signed smart chain transactions
|
|
534
|
-
*
|
|
535
|
-
* @param chainIdentifier Smart chain identifier string
|
|
536
|
-
* @param txs An array of already signed transactions
|
|
537
|
-
* @param abortSignal Abort signal
|
|
538
|
-
* @param onBeforePublish Callback invoked before a transaction is sent (invoked for every transaction to be sent)
|
|
539
|
-
*/
|
|
540
|
-
sendSignedAndConfirm<ChainIdentifier extends ChainIds<T>>(
|
|
541
|
-
chainIdentifier: ChainIdentifier,
|
|
542
|
-
txs: T[ChainIdentifier]["SignedTXType"][],
|
|
543
|
-
abortSignal?: AbortSignal,
|
|
544
|
-
onBeforePublish?: (txId: string, rawTx: string) => Promise<void>
|
|
545
|
-
): Promise<string[]> {
|
|
546
|
-
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
547
|
-
return this.root._chains[chainIdentifier].chainInterface.sendSignedAndConfirm(txs, true, abortSignal, false, onBeforePublish);
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
/**
|
|
551
|
-
* Prepares a set of unsigned transactions for signing, by adding required nonces or recent blockhashes, might
|
|
552
|
-
* also add hints of account deployment on e.g. Starknet
|
|
553
|
-
*
|
|
554
|
-
* @param chainIdentifier A chain for which to prepare the txs
|
|
555
|
-
* @param txs Transactions to prepare
|
|
556
|
-
*/
|
|
557
|
-
prepareUnsignedTransactions<ChainIdentifier extends ChainIds<T>>(
|
|
558
|
-
chainIdentifier: ChainIdentifier,
|
|
559
|
-
txs: T[ChainIdentifier]["TX"][]
|
|
560
|
-
): Promise<T[ChainIdentifier]["TX"][]> {
|
|
561
|
-
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
562
|
-
const chainInterface = this.root._chains[chainIdentifier].chainInterface;
|
|
563
|
-
if(chainInterface.prepareTxs==null) throw new Error("Chain doesn't support tx preparation, chainId: "+chainIdentifier);
|
|
564
|
-
return chainInterface.prepareTxs(txs);
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
/**
|
|
568
|
-
* Serializes an unsigned smart chain transaction
|
|
569
|
-
*
|
|
570
|
-
* @param chainIdentifier Smart chain string identifier
|
|
571
|
-
* @param tx An unsigned transaction to serialize
|
|
572
|
-
*/
|
|
573
|
-
serializeUnsignedTransaction<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier, tx: T[ChainIdentifier]["TX"]): Promise<string> {
|
|
574
|
-
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
575
|
-
return this.root._chains[chainIdentifier].chainInterface.serializeTx(tx);
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
/**
|
|
579
|
-
* Deserializes an unsigned smart chain transaction
|
|
580
|
-
*
|
|
581
|
-
* @param chainIdentifier Smart chain string identifier
|
|
582
|
-
* @param tx Serialized unsigned transaction
|
|
583
|
-
*/
|
|
584
|
-
deserializeUnsignedTransaction<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier, tx: string): Promise<T[ChainIdentifier]["TX"]> {
|
|
585
|
-
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
586
|
-
return this.root._chains[chainIdentifier].chainInterface.deserializeTx(tx);
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
/**
|
|
590
|
-
* Serializes a signed smart chain transaction
|
|
591
|
-
*
|
|
592
|
-
* @param chainIdentifier Smart chain string identifier
|
|
593
|
-
* @param tx A signed transaction to serialize
|
|
594
|
-
*/
|
|
595
|
-
serializeSignedTransaction<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier, tx: T[ChainIdentifier]["SignedTXType"]): Promise<string> {
|
|
596
|
-
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
597
|
-
return this.root._chains[chainIdentifier].chainInterface.serializeSignedTx(tx);
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
/**
|
|
601
|
-
* Deserializes a signed smart chain transaction
|
|
602
|
-
*
|
|
603
|
-
* @param chainIdentifier Smart chain string identifier
|
|
604
|
-
* @param tx Serialized signed transaction
|
|
605
|
-
*/
|
|
606
|
-
deserializeSignedTransaction<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier, tx: string): Promise<T[ChainIdentifier]["SignedTXType"]> {
|
|
607
|
-
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
608
|
-
return this.root._chains[chainIdentifier].chainInterface.deserializeSignedTx(tx);
|
|
609
|
-
}
|
|
610
|
-
|
|
1
|
+
import {decode as bolt11Decode} from "@atomiqlabs/bolt11";
|
|
2
|
+
import {Address, Transaction} from "@scure/btc-signer";
|
|
3
|
+
import {LNURL} from "../lnurl/LNURL";
|
|
4
|
+
import {BTC_NETWORK} from "@scure/btc-signer/utils";
|
|
5
|
+
import {SwapType} from "../enums/SwapType";
|
|
6
|
+
import {ChainIds, MultiChain, Swapper} from "./Swapper";
|
|
7
|
+
import {IBitcoinWallet} from "../bitcoin/wallet/IBitcoinWallet";
|
|
8
|
+
import {SingleAddressBitcoinWallet} from "../bitcoin/wallet/SingleAddressBitcoinWallet";
|
|
9
|
+
import {BigIntBufferUtils, ChainSwapType, isAbstractSigner} from "@atomiqlabs/base";
|
|
10
|
+
import {bigIntMax, fromDecimal, randomBytes} from "../utils/Utils";
|
|
11
|
+
import {MinimalBitcoinWalletInterface} from "../types/wallets/MinimalBitcoinWalletInterface";
|
|
12
|
+
import {TokenAmount, toTokenAmount} from "../types/TokenAmount";
|
|
13
|
+
import {BitcoinTokens, SCToken} from "../types/Token";
|
|
14
|
+
import {isLNURLWithdraw, LNURLWithdraw} from "../types/lnurl/LNURLWithdraw";
|
|
15
|
+
import {isLNURLPay, LNURLPay} from "../types/lnurl/LNURLPay";
|
|
16
|
+
import {toBitcoinWallet} from "../utils/BitcoinWalletUtils";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Utility class providing helper methods for address parsing, token balances, serialization
|
|
20
|
+
* and other miscellaneous things.
|
|
21
|
+
*
|
|
22
|
+
* @category Core
|
|
23
|
+
*/
|
|
24
|
+
export class SwapperUtils<T extends MultiChain> {
|
|
25
|
+
|
|
26
|
+
readonly bitcoinNetwork: BTC_NETWORK;
|
|
27
|
+
private readonly root: Swapper<T>;
|
|
28
|
+
|
|
29
|
+
constructor(root: Swapper<T>) {
|
|
30
|
+
this.bitcoinNetwork = root._btcNetwork;
|
|
31
|
+
this.root = root;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Checks whether a passed address is a valid address on the smart chain
|
|
36
|
+
*
|
|
37
|
+
* @param address Address
|
|
38
|
+
* @param chainId Smart chain identifier string to check the address for
|
|
39
|
+
*/
|
|
40
|
+
isValidSmartChainAddress(address: string, chainId?: ChainIds<T>): boolean {
|
|
41
|
+
if(chainId!=null) {
|
|
42
|
+
if(this.root._chains[chainId]==null) throw new Error(`Unknown chain id: ${chainId}`);
|
|
43
|
+
return this.root._chains[chainId].chainInterface.isValidAddress(address);
|
|
44
|
+
}
|
|
45
|
+
for(let chainId of this.root.getSmartChains()) {
|
|
46
|
+
if(this.root._chains[chainId].chainInterface.isValidAddress(address)) return true;
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Checks whether an address is a valid BOLT11 bitcoin lightning invoice
|
|
53
|
+
*
|
|
54
|
+
* @param address Address to check
|
|
55
|
+
*/
|
|
56
|
+
isLightningInvoice(address: string): boolean {
|
|
57
|
+
try {
|
|
58
|
+
bolt11Decode(address);
|
|
59
|
+
return true;
|
|
60
|
+
} catch (e) {}
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Checks whether an address is a valid bitcoin address
|
|
66
|
+
*
|
|
67
|
+
* @param address Address to check
|
|
68
|
+
*/
|
|
69
|
+
isValidBitcoinAddress(address: string): boolean {
|
|
70
|
+
try {
|
|
71
|
+
Address(this.bitcoinNetwork).decode(address);
|
|
72
|
+
return true;
|
|
73
|
+
} catch (e) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Checks whether an address is a valid BOLT11 bitcoin lightning invoice WITH AMOUNT
|
|
80
|
+
*
|
|
81
|
+
* @param address Address to check
|
|
82
|
+
*/
|
|
83
|
+
isValidLightningInvoice(address: string): boolean {
|
|
84
|
+
try {
|
|
85
|
+
const parsed = bolt11Decode(address);
|
|
86
|
+
if(parsed.millisatoshis!=null) return true;
|
|
87
|
+
} catch (e) {}
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Checks whether an address is a valid LNURL (no checking on type is performed)
|
|
93
|
+
*
|
|
94
|
+
* @param address Address to check
|
|
95
|
+
*/
|
|
96
|
+
isValidLNURL(address: string): boolean {
|
|
97
|
+
return LNURL.isLNURL(address);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Returns type and data about an LNURL
|
|
102
|
+
*
|
|
103
|
+
* @param lnurl LNURL link to check, can be either `pay` or `withdraw` type
|
|
104
|
+
* @param shouldRetry Optional whether HTTP requests should retried on failure
|
|
105
|
+
*/
|
|
106
|
+
getLNURLTypeAndData(lnurl: string, shouldRetry?: boolean): Promise<LNURLPay | LNURLWithdraw | null> {
|
|
107
|
+
return LNURL.getLNURLType(lnurl, shouldRetry);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Returns satoshi value of BOLT11 bitcoin lightning invoice WITH AMOUNT, returns null otherwise
|
|
112
|
+
*
|
|
113
|
+
* @param lnpr
|
|
114
|
+
*/
|
|
115
|
+
getLightningInvoiceValue(lnpr: string): bigint | null {
|
|
116
|
+
const parsed = bolt11Decode(lnpr);
|
|
117
|
+
if(parsed.millisatoshis!=null) return (BigInt(parsed.millisatoshis) + 999n) / 1000n;
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private parseBitcoinAddress(resultText: string): {
|
|
122
|
+
address: string,
|
|
123
|
+
type: "BITCOIN",
|
|
124
|
+
swapType: SwapType.TO_BTC,
|
|
125
|
+
amount?: TokenAmount
|
|
126
|
+
} | null {
|
|
127
|
+
let _amount: bigint | undefined = undefined;
|
|
128
|
+
if(resultText.includes("?")) {
|
|
129
|
+
const arr = resultText.split("?");
|
|
130
|
+
resultText = arr[0];
|
|
131
|
+
const params = arr[1].split("&");
|
|
132
|
+
for(let param of params) {
|
|
133
|
+
const arr2 = param.split("=");
|
|
134
|
+
const key = arr2[0];
|
|
135
|
+
const value = decodeURIComponent(arr2[1]);
|
|
136
|
+
if(key==="amount") {
|
|
137
|
+
_amount = fromDecimal(parseFloat(value).toFixed(8), 8);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if(this.isValidBitcoinAddress(resultText)) {
|
|
142
|
+
return {
|
|
143
|
+
address: resultText,
|
|
144
|
+
type: "BITCOIN",
|
|
145
|
+
swapType: SwapType.TO_BTC,
|
|
146
|
+
amount: _amount==null ? undefined : toTokenAmount(_amount, BitcoinTokens.BTC, this.root.prices)
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private parseLNURLSync(resultText: string): {
|
|
153
|
+
address: string,
|
|
154
|
+
type: "LNURL",
|
|
155
|
+
swapType: null
|
|
156
|
+
} | null {
|
|
157
|
+
if(this.isValidLNURL(resultText)) {
|
|
158
|
+
return {
|
|
159
|
+
address: resultText,
|
|
160
|
+
type: "LNURL",
|
|
161
|
+
swapType: null
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
private async parseLNURL(resultText: string): Promise<{
|
|
168
|
+
address: string,
|
|
169
|
+
type: "LNURL",
|
|
170
|
+
swapType: SwapType.TO_BTCLN | SwapType.FROM_BTCLN,
|
|
171
|
+
lnurl: LNURLPay | LNURLWithdraw,
|
|
172
|
+
min?: TokenAmount,
|
|
173
|
+
max?: TokenAmount,
|
|
174
|
+
amount?: TokenAmount
|
|
175
|
+
} | null> {
|
|
176
|
+
if(this.isValidLNURL(resultText)) {
|
|
177
|
+
try {
|
|
178
|
+
const result = await this.getLNURLTypeAndData(resultText);
|
|
179
|
+
if(result==null) throw new Error("Invalid LNURL specified!");
|
|
180
|
+
const swapType = isLNURLPay(result) ? SwapType.TO_BTCLN : isLNURLWithdraw(result) ? SwapType.FROM_BTCLN : null;
|
|
181
|
+
if(swapType==null) return null;
|
|
182
|
+
const response = {
|
|
183
|
+
address: resultText,
|
|
184
|
+
type: "LNURL",
|
|
185
|
+
swapType,
|
|
186
|
+
lnurl: result
|
|
187
|
+
} as const;
|
|
188
|
+
if(result.min===result.max) {
|
|
189
|
+
return {
|
|
190
|
+
...response,
|
|
191
|
+
amount: result.min==null ? undefined : toTokenAmount(result.min, BitcoinTokens.BTCLN, this.root.prices)
|
|
192
|
+
}
|
|
193
|
+
} else {
|
|
194
|
+
return {
|
|
195
|
+
...response,
|
|
196
|
+
min: result.min==null ? undefined : toTokenAmount(result.min, BitcoinTokens.BTCLN, this.root.prices),
|
|
197
|
+
max: result.min==null ? undefined : toTokenAmount(result.max, BitcoinTokens.BTCLN, this.root.prices)
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
} catch (e) {
|
|
201
|
+
throw new Error("Failed to contact LNURL service, check your internet connection and retry later.");
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
private parseLightningInvoice(resultText: string): {
|
|
208
|
+
address: string,
|
|
209
|
+
type: "LIGHTNING",
|
|
210
|
+
swapType: SwapType.TO_BTCLN,
|
|
211
|
+
amount: TokenAmount
|
|
212
|
+
} | null {
|
|
213
|
+
if(this.isLightningInvoice(resultText)) {
|
|
214
|
+
if(this.isValidLightningInvoice(resultText)) {
|
|
215
|
+
const amount = this.getLightningInvoiceValue(resultText);
|
|
216
|
+
if(amount==null) throw new Error();
|
|
217
|
+
return {
|
|
218
|
+
address: resultText,
|
|
219
|
+
type: "LIGHTNING",
|
|
220
|
+
swapType: SwapType.TO_BTCLN,
|
|
221
|
+
amount: toTokenAmount(amount, BitcoinTokens.BTCLN, this.root.prices)
|
|
222
|
+
}
|
|
223
|
+
} else {
|
|
224
|
+
throw new Error("Lightning invoice needs to contain an amount!");
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
private parseSmartchainAddress(resultText: string): {
|
|
231
|
+
address: string,
|
|
232
|
+
type: ChainIds<T>,
|
|
233
|
+
swapType: null,
|
|
234
|
+
min?: TokenAmount,
|
|
235
|
+
max?: TokenAmount
|
|
236
|
+
} | null {
|
|
237
|
+
for(let chainId of this.root.getSmartChains()) {
|
|
238
|
+
if(this.root._chains[chainId].chainInterface.isValidAddress(resultText)) {
|
|
239
|
+
return {
|
|
240
|
+
address: resultText,
|
|
241
|
+
type: chainId,
|
|
242
|
+
swapType: null
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* General parser for bitcoin addresses, LNURLs, lightning invoices, smart chain addresses. Also fetches LNURL data
|
|
251
|
+
* (hence async and returns Promise).
|
|
252
|
+
*
|
|
253
|
+
* @param addressString Address to parse
|
|
254
|
+
* @throws {Error} Error in address parsing
|
|
255
|
+
* @returns Address data or `null` if address doesn't conform to any known format
|
|
256
|
+
*/
|
|
257
|
+
async parseAddress(addressString: string): Promise<{
|
|
258
|
+
address: string,
|
|
259
|
+
type: "BITCOIN" | "LIGHTNING" | "LNURL" | ChainIds<T>,
|
|
260
|
+
swapType: SwapType.TO_BTC | SwapType.TO_BTCLN | SwapType.SPV_VAULT_FROM_BTC | SwapType.FROM_BTCLN | null,
|
|
261
|
+
lnurl?: LNURLPay | LNURLWithdraw,
|
|
262
|
+
min?: TokenAmount,
|
|
263
|
+
max?: TokenAmount,
|
|
264
|
+
amount?: TokenAmount
|
|
265
|
+
} | null> {
|
|
266
|
+
if(addressString.startsWith("bitcoin:")) {
|
|
267
|
+
const parsedBitcoinAddress = this.parseBitcoinAddress(addressString.substring(8));
|
|
268
|
+
if(parsedBitcoinAddress!=null) return parsedBitcoinAddress;
|
|
269
|
+
throw new Error("Invalid bitcoin address!");
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const parsedBitcoinAddress = this.parseBitcoinAddress(addressString);
|
|
273
|
+
if(parsedBitcoinAddress!=null) return parsedBitcoinAddress;
|
|
274
|
+
|
|
275
|
+
if(addressString.startsWith("lightning:")) {
|
|
276
|
+
const resultText = addressString.substring(10);
|
|
277
|
+
const resultLnurl = await this.parseLNURL(resultText);
|
|
278
|
+
if(resultLnurl!=null) return resultLnurl;
|
|
279
|
+
|
|
280
|
+
const resultLightningInvoice = this.parseLightningInvoice(resultText);
|
|
281
|
+
if(resultLightningInvoice!=null) return resultLightningInvoice;
|
|
282
|
+
|
|
283
|
+
throw new Error("Invalid lightning network invoice or LNURL!");
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const resultLnurl = await this.parseLNURL(addressString);
|
|
287
|
+
if(resultLnurl!=null) return resultLnurl;
|
|
288
|
+
|
|
289
|
+
const resultLightningInvoice = this.parseLightningInvoice(addressString);
|
|
290
|
+
if(resultLightningInvoice!=null) return resultLightningInvoice;
|
|
291
|
+
|
|
292
|
+
return this.parseSmartchainAddress(addressString);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Synchronous general parser for bitcoin addresses, LNURLs, lightning invoices, smart chain addresses, doesn't fetch
|
|
297
|
+
* LNURL data, returns `swapType: null` instead to prevent returning a Promise
|
|
298
|
+
*
|
|
299
|
+
* @param addressString Address to parse
|
|
300
|
+
* @throws {Error} Error in address parsing
|
|
301
|
+
* @returns Address data or `null` if address doesn't conform to any known format
|
|
302
|
+
*/
|
|
303
|
+
parseAddressSync(addressString: string): {
|
|
304
|
+
address: string,
|
|
305
|
+
type: "BITCOIN" | "LIGHTNING" | "LNURL" | ChainIds<T>,
|
|
306
|
+
swapType: SwapType.TO_BTC | SwapType.TO_BTCLN | SwapType.SPV_VAULT_FROM_BTC | null,
|
|
307
|
+
min?: TokenAmount,
|
|
308
|
+
max?: TokenAmount,
|
|
309
|
+
amount?: TokenAmount
|
|
310
|
+
} | null {
|
|
311
|
+
if(addressString.startsWith("bitcoin:")) {
|
|
312
|
+
const parsedBitcoinAddress = this.parseBitcoinAddress(addressString.substring(8));
|
|
313
|
+
if(parsedBitcoinAddress!=null) return parsedBitcoinAddress;
|
|
314
|
+
throw new Error("Invalid bitcoin address!");
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const parsedBitcoinAddress = this.parseBitcoinAddress(addressString);
|
|
318
|
+
if(parsedBitcoinAddress!=null) return parsedBitcoinAddress;
|
|
319
|
+
|
|
320
|
+
if(addressString.startsWith("lightning:")) {
|
|
321
|
+
const resultText = addressString.substring(10);
|
|
322
|
+
const resultLnurl = this.parseLNURLSync(resultText);
|
|
323
|
+
if(resultLnurl!=null) return resultLnurl;
|
|
324
|
+
|
|
325
|
+
const resultLightningInvoice = this.parseLightningInvoice(resultText);
|
|
326
|
+
if(resultLightningInvoice!=null) return resultLightningInvoice;
|
|
327
|
+
|
|
328
|
+
throw new Error("Invalid lightning network invoice or LNURL!");
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const resultLnurl = this.parseLNURLSync(addressString);
|
|
332
|
+
if(resultLnurl!=null) return resultLnurl;
|
|
333
|
+
|
|
334
|
+
const resultLightningInvoice = this.parseLightningInvoice(addressString);
|
|
335
|
+
if(resultLightningInvoice!=null) return resultLightningInvoice;
|
|
336
|
+
|
|
337
|
+
return this.parseSmartchainAddress(addressString);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Strips the URL encoding around `bitcoin:` and `lightning:` addresses, leaving just the raw address
|
|
342
|
+
*
|
|
343
|
+
* @param addressString Address to strip
|
|
344
|
+
*
|
|
345
|
+
* @returns Raw clean address
|
|
346
|
+
*/
|
|
347
|
+
stripAddress(addressString: string): string {
|
|
348
|
+
if(addressString.startsWith("lightning:") || addressString.startsWith("bitcoin:")) {
|
|
349
|
+
addressString = addressString.substring(addressString.indexOf(":")+1);
|
|
350
|
+
const delimeterIndex = addressString.indexOf("?");
|
|
351
|
+
if(delimeterIndex!==-1) addressString = addressString.substring(0, delimeterIndex);
|
|
352
|
+
}
|
|
353
|
+
return addressString;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Returns a random PSBT that can be used for fee estimation for SPV vault (UTXO-controlled vault) based swaps
|
|
358
|
+
* {@link SwapType.SPV_VAULT_FROM_BTC}, the last output (the LP output) is omitted to allow for coinselection
|
|
359
|
+
* algorithm to determine maximum sendable amount there
|
|
360
|
+
*
|
|
361
|
+
* @param chainIdentifier Smart chain to swap to
|
|
362
|
+
* @param includeGasToken Whether to return the PSBT also with the gas token amount (increases the vSize by 8)
|
|
363
|
+
*/
|
|
364
|
+
getRandomSpvVaultPsbt<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier, includeGasToken?: boolean): Transaction {
|
|
365
|
+
const wrapper = this.root._chains[chainIdentifier].wrappers[SwapType.SPV_VAULT_FROM_BTC];
|
|
366
|
+
if(wrapper==null) throw new Error("Chain doesn't support spv vault swaps!");
|
|
367
|
+
return wrapper.getDummySwapPsbt(includeGasToken);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Returns the spendable balance of a bitcoin wallet
|
|
372
|
+
*
|
|
373
|
+
* @param wallet Bitcoin wallet to check the spendable balance for, can either be a simple
|
|
374
|
+
* bitcoin address string or a wallet object
|
|
375
|
+
* @param targetChain Destination smart chain for the swap, the ensures proper spendable balance
|
|
376
|
+
* is estimated taking into consideration different swap primitives available on different chains
|
|
377
|
+
* @param options Additional options
|
|
378
|
+
*/
|
|
379
|
+
async getBitcoinSpendableBalance(
|
|
380
|
+
wallet: string | IBitcoinWallet | MinimalBitcoinWalletInterface,
|
|
381
|
+
targetChain?: ChainIds<T>,
|
|
382
|
+
options?: {
|
|
383
|
+
gasDrop?: boolean,
|
|
384
|
+
feeRate?: number,
|
|
385
|
+
minFeeRate?: number
|
|
386
|
+
}
|
|
387
|
+
): Promise<{
|
|
388
|
+
balance: TokenAmount,
|
|
389
|
+
feeRate: number
|
|
390
|
+
}> {
|
|
391
|
+
let bitcoinWallet: IBitcoinWallet;
|
|
392
|
+
if(typeof(wallet)==="string") {
|
|
393
|
+
bitcoinWallet = new SingleAddressBitcoinWallet(this.root._bitcoinRpc, this.bitcoinNetwork, {address: wallet, publicKey: ""});
|
|
394
|
+
} else {
|
|
395
|
+
bitcoinWallet = toBitcoinWallet(wallet, this.root._bitcoinRpc, this.bitcoinNetwork);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
let feeRate = options?.feeRate ?? await bitcoinWallet.getFeeRate();
|
|
399
|
+
if(options?.minFeeRate!=null) feeRate = Math.max(feeRate, options.minFeeRate);
|
|
400
|
+
|
|
401
|
+
let result: {balance: bigint, feeRate: number, totalFee: number};
|
|
402
|
+
if(targetChain!=null && this.root.supportsSwapType(targetChain, SwapType.SPV_VAULT_FROM_BTC)) {
|
|
403
|
+
result = await bitcoinWallet.getSpendableBalance(this.getRandomSpvVaultPsbt(targetChain, options?.gasDrop), feeRate);
|
|
404
|
+
} else {
|
|
405
|
+
result = await bitcoinWallet.getSpendableBalance(undefined, feeRate);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
return {
|
|
409
|
+
balance: toTokenAmount(result.balance, BitcoinTokens.BTC, this.root.prices),
|
|
410
|
+
feeRate: result.feeRate
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Returns the maximum spendable balance of the smart chain wallet, deducting the fee needed
|
|
416
|
+
* to initiate a swap for native balances
|
|
417
|
+
*/
|
|
418
|
+
async getSpendableBalance<ChainIdentifier extends ChainIds<T>>(wallet: string | T[ChainIdentifier]["Signer"] | T[ChainIdentifier]["NativeSigner"], token: SCToken<ChainIdentifier>, options?: {
|
|
419
|
+
feeMultiplier?: number,
|
|
420
|
+
feeRate?: any
|
|
421
|
+
}): Promise<TokenAmount> {
|
|
422
|
+
if(this.root._chains[token.chainId]==null) throw new Error("Invalid chain identifier! Unknown chain: "+token.chainId);
|
|
423
|
+
const {defaultVersion, versionedContracts, chainInterface} = this.root._chains[token.chainId];
|
|
424
|
+
|
|
425
|
+
const {swapContract} = versionedContracts[defaultVersion];
|
|
426
|
+
|
|
427
|
+
let signer: string;
|
|
428
|
+
if(typeof(wallet)==="string") {
|
|
429
|
+
signer = wallet;
|
|
430
|
+
} else {
|
|
431
|
+
const abstractSigner = isAbstractSigner(wallet) ? wallet : await chainInterface.wrapSigner(wallet);
|
|
432
|
+
signer = abstractSigner.getAddress();
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
let finalBalance: bigint;
|
|
436
|
+
if(chainInterface.getNativeCurrencyAddress()!==token.address) {
|
|
437
|
+
finalBalance = await chainInterface.getBalance(signer, token.address);
|
|
438
|
+
} else {
|
|
439
|
+
let [balance, commitFee] = await Promise.all([
|
|
440
|
+
chainInterface.getBalance(signer, token.address),
|
|
441
|
+
swapContract.getCommitFee(
|
|
442
|
+
signer,
|
|
443
|
+
//Use large amount, such that the fee for wrapping more tokens is always included!
|
|
444
|
+
await swapContract.createSwapData(
|
|
445
|
+
ChainSwapType.HTLC, signer, chainInterface.randomAddress(), token.address,
|
|
446
|
+
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn,
|
|
447
|
+
swapContract.getHashForHtlc(randomBytes(32)).toString("hex"),
|
|
448
|
+
BigIntBufferUtils.fromBuffer(randomBytes(8)), BigInt(Math.floor(Date.now()/1000)),
|
|
449
|
+
true, false, BigIntBufferUtils.fromBuffer(randomBytes(2)), BigIntBufferUtils.fromBuffer(randomBytes(2))
|
|
450
|
+
),
|
|
451
|
+
options?.feeRate
|
|
452
|
+
)
|
|
453
|
+
]);
|
|
454
|
+
|
|
455
|
+
if(options?.feeMultiplier!=null) {
|
|
456
|
+
commitFee = commitFee * (BigInt(Math.floor(options.feeMultiplier*1000000))) / 1000000n;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
finalBalance = bigIntMax(balance - commitFee, 0n);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
return toTokenAmount(finalBalance, token, this.root.prices);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Returns the address of the native currency of the smart chain
|
|
467
|
+
*/
|
|
468
|
+
getNativeToken<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier): SCToken<ChainIdentifier> {
|
|
469
|
+
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
470
|
+
return this.root._tokens[chainIdentifier][this.root._chains[chainIdentifier].chainInterface.getNativeCurrencyAddress()] as SCToken<ChainIdentifier>;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Returns whether when swapping to the provided token a gas drop can be requested
|
|
475
|
+
*
|
|
476
|
+
* @param token
|
|
477
|
+
*/
|
|
478
|
+
destinationTokenSupportsGasDrop<ChainIdentifier extends ChainIds<T>>(token: SCToken<ChainIdentifier>): boolean {
|
|
479
|
+
if(this.root._chains[token.chainId]==null) throw new Error("Invalid chain identifier! Unknown chain: "+token.chainId);
|
|
480
|
+
const {chainInterface} = this.root._chains[token.chainId];
|
|
481
|
+
if(chainInterface.shouldGetNativeTokenDrop!=null) return chainInterface.shouldGetNativeTokenDrop(token.address);
|
|
482
|
+
return chainInterface.getNativeCurrencyAddress() !== token.address;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Returns a random signer for a given smart chain
|
|
487
|
+
*
|
|
488
|
+
* @param chainIdentifier
|
|
489
|
+
*/
|
|
490
|
+
randomSigner<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier): T[ChainIdentifier]["Signer"] {
|
|
491
|
+
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
492
|
+
return this.root._chains[chainIdentifier].chainInterface.randomSigner();
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Returns a random address for a given smart chain or bitcoin
|
|
497
|
+
*
|
|
498
|
+
* @param chainIdentifier
|
|
499
|
+
*/
|
|
500
|
+
randomAddress<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier | "BITCOIN"): string {
|
|
501
|
+
if(chainIdentifier==="BITCOIN") {
|
|
502
|
+
// Return random p2wkh address
|
|
503
|
+
return Address(this.bitcoinNetwork).encode({
|
|
504
|
+
type: "wpkh",
|
|
505
|
+
hash: randomBytes(20)
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
509
|
+
return this.root._chains[chainIdentifier].chainInterface.randomAddress();
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Signs and broadcasts the supplied smart chain transaction
|
|
514
|
+
*
|
|
515
|
+
* @param chainIdentifier Smart chain identifier string
|
|
516
|
+
* @param signer Signer to use for signing the transactions
|
|
517
|
+
* @param txs An array of transactions to sign
|
|
518
|
+
* @param abortSignal Abort signal
|
|
519
|
+
* @param onBeforePublish Callback invoked before a transaction is sent (invoked for every transaction to be sent)
|
|
520
|
+
*/
|
|
521
|
+
sendAndConfirm<ChainIdentifier extends ChainIds<T>>(
|
|
522
|
+
chainIdentifier: ChainIdentifier,
|
|
523
|
+
signer: T[ChainIdentifier]["NativeSigner"] | T[ChainIdentifier]["Signer"],
|
|
524
|
+
txs: T[ChainIdentifier]["TX"][],
|
|
525
|
+
abortSignal?: AbortSignal,
|
|
526
|
+
onBeforePublish?: (txId: string, rawTx: string) => Promise<void>
|
|
527
|
+
): Promise<string[]> {
|
|
528
|
+
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
529
|
+
return this.root._chains[chainIdentifier].chainInterface.sendAndConfirm(signer, txs, true, abortSignal, false, onBeforePublish);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Broadcasts already signed smart chain transactions
|
|
534
|
+
*
|
|
535
|
+
* @param chainIdentifier Smart chain identifier string
|
|
536
|
+
* @param txs An array of already signed transactions
|
|
537
|
+
* @param abortSignal Abort signal
|
|
538
|
+
* @param onBeforePublish Callback invoked before a transaction is sent (invoked for every transaction to be sent)
|
|
539
|
+
*/
|
|
540
|
+
sendSignedAndConfirm<ChainIdentifier extends ChainIds<T>>(
|
|
541
|
+
chainIdentifier: ChainIdentifier,
|
|
542
|
+
txs: T[ChainIdentifier]["SignedTXType"][],
|
|
543
|
+
abortSignal?: AbortSignal,
|
|
544
|
+
onBeforePublish?: (txId: string, rawTx: string) => Promise<void>
|
|
545
|
+
): Promise<string[]> {
|
|
546
|
+
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
547
|
+
return this.root._chains[chainIdentifier].chainInterface.sendSignedAndConfirm(txs, true, abortSignal, false, onBeforePublish);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Prepares a set of unsigned transactions for signing, by adding required nonces or recent blockhashes, might
|
|
552
|
+
* also add hints of account deployment on e.g. Starknet
|
|
553
|
+
*
|
|
554
|
+
* @param chainIdentifier A chain for which to prepare the txs
|
|
555
|
+
* @param txs Transactions to prepare
|
|
556
|
+
*/
|
|
557
|
+
prepareUnsignedTransactions<ChainIdentifier extends ChainIds<T>>(
|
|
558
|
+
chainIdentifier: ChainIdentifier,
|
|
559
|
+
txs: T[ChainIdentifier]["TX"][]
|
|
560
|
+
): Promise<T[ChainIdentifier]["TX"][]> {
|
|
561
|
+
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
562
|
+
const chainInterface = this.root._chains[chainIdentifier].chainInterface;
|
|
563
|
+
if(chainInterface.prepareTxs==null) throw new Error("Chain doesn't support tx preparation, chainId: "+chainIdentifier);
|
|
564
|
+
return chainInterface.prepareTxs(txs);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Serializes an unsigned smart chain transaction
|
|
569
|
+
*
|
|
570
|
+
* @param chainIdentifier Smart chain string identifier
|
|
571
|
+
* @param tx An unsigned transaction to serialize
|
|
572
|
+
*/
|
|
573
|
+
serializeUnsignedTransaction<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier, tx: T[ChainIdentifier]["TX"]): Promise<string> {
|
|
574
|
+
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
575
|
+
return this.root._chains[chainIdentifier].chainInterface.serializeTx(tx);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Deserializes an unsigned smart chain transaction
|
|
580
|
+
*
|
|
581
|
+
* @param chainIdentifier Smart chain string identifier
|
|
582
|
+
* @param tx Serialized unsigned transaction
|
|
583
|
+
*/
|
|
584
|
+
deserializeUnsignedTransaction<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier, tx: string): Promise<T[ChainIdentifier]["TX"]> {
|
|
585
|
+
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
586
|
+
return this.root._chains[chainIdentifier].chainInterface.deserializeTx(tx);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Serializes a signed smart chain transaction
|
|
591
|
+
*
|
|
592
|
+
* @param chainIdentifier Smart chain string identifier
|
|
593
|
+
* @param tx A signed transaction to serialize
|
|
594
|
+
*/
|
|
595
|
+
serializeSignedTransaction<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier, tx: T[ChainIdentifier]["SignedTXType"]): Promise<string> {
|
|
596
|
+
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
597
|
+
return this.root._chains[chainIdentifier].chainInterface.serializeSignedTx(tx);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* Deserializes a signed smart chain transaction
|
|
602
|
+
*
|
|
603
|
+
* @param chainIdentifier Smart chain string identifier
|
|
604
|
+
* @param tx Serialized signed transaction
|
|
605
|
+
*/
|
|
606
|
+
deserializeSignedTransaction<ChainIdentifier extends ChainIds<T>>(chainIdentifier: ChainIdentifier, tx: string): Promise<T[ChainIdentifier]["SignedTXType"]> {
|
|
607
|
+
if(this.root._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
608
|
+
return this.root._chains[chainIdentifier].chainInterface.deserializeSignedTx(tx);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
611
|
}
|