@atomiqlabs/chain-starknet 4.0.0-dev.12 → 4.0.0-dev.13

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.
Files changed (146) hide show
  1. package/LICENSE +201 -201
  2. package/dist/index.d.ts +38 -38
  3. package/dist/index.js +54 -54
  4. package/dist/starknet/StarknetChainType.d.ts +13 -13
  5. package/dist/starknet/StarknetChainType.js +2 -2
  6. package/dist/starknet/StarknetInitializer.d.ts +27 -27
  7. package/dist/starknet/StarknetInitializer.js +69 -69
  8. package/dist/starknet/btcrelay/BtcRelayAbi.d.ts +250 -250
  9. package/dist/starknet/btcrelay/BtcRelayAbi.js +341 -341
  10. package/dist/starknet/btcrelay/StarknetBtcRelay.d.ts +186 -186
  11. package/dist/starknet/btcrelay/StarknetBtcRelay.js +379 -379
  12. package/dist/starknet/btcrelay/headers/StarknetBtcHeader.d.ts +31 -31
  13. package/dist/starknet/btcrelay/headers/StarknetBtcHeader.js +74 -74
  14. package/dist/starknet/btcrelay/headers/StarknetBtcStoredHeader.d.ts +51 -51
  15. package/dist/starknet/btcrelay/headers/StarknetBtcStoredHeader.js +113 -113
  16. package/dist/starknet/chain/StarknetAction.d.ts +19 -19
  17. package/dist/starknet/chain/StarknetAction.js +73 -73
  18. package/dist/starknet/chain/StarknetChainInterface.d.ts +52 -52
  19. package/dist/starknet/chain/StarknetChainInterface.js +91 -91
  20. package/dist/starknet/chain/StarknetModule.d.ts +14 -14
  21. package/dist/starknet/chain/StarknetModule.js +13 -13
  22. package/dist/starknet/chain/modules/ERC20Abi.d.ts +755 -755
  23. package/dist/starknet/chain/modules/ERC20Abi.js +1032 -1032
  24. package/dist/starknet/chain/modules/StarknetAccounts.d.ts +6 -6
  25. package/dist/starknet/chain/modules/StarknetAccounts.js +24 -24
  26. package/dist/starknet/chain/modules/StarknetAddresses.d.ts +9 -9
  27. package/dist/starknet/chain/modules/StarknetAddresses.js +26 -26
  28. package/dist/starknet/chain/modules/StarknetBlocks.d.ts +20 -20
  29. package/dist/starknet/chain/modules/StarknetBlocks.js +64 -64
  30. package/dist/starknet/chain/modules/StarknetEvents.d.ts +44 -44
  31. package/dist/starknet/chain/modules/StarknetEvents.js +88 -88
  32. package/dist/starknet/chain/modules/StarknetFees.d.ts +77 -77
  33. package/dist/starknet/chain/modules/StarknetFees.js +114 -114
  34. package/dist/starknet/chain/modules/StarknetSignatures.d.ts +29 -29
  35. package/dist/starknet/chain/modules/StarknetSignatures.js +72 -72
  36. package/dist/starknet/chain/modules/StarknetTokens.d.ts +69 -69
  37. package/dist/starknet/chain/modules/StarknetTokens.js +102 -98
  38. package/dist/starknet/chain/modules/StarknetTransactions.d.ts +93 -93
  39. package/dist/starknet/chain/modules/StarknetTransactions.js +261 -260
  40. package/dist/starknet/contract/StarknetContractBase.d.ts +13 -13
  41. package/dist/starknet/contract/StarknetContractBase.js +20 -16
  42. package/dist/starknet/contract/StarknetContractModule.d.ts +8 -8
  43. package/dist/starknet/contract/StarknetContractModule.js +11 -11
  44. package/dist/starknet/contract/modules/StarknetContractEvents.d.ts +51 -51
  45. package/dist/starknet/contract/modules/StarknetContractEvents.js +97 -97
  46. package/dist/starknet/events/StarknetChainEvents.d.ts +21 -21
  47. package/dist/starknet/events/StarknetChainEvents.js +52 -52
  48. package/dist/starknet/events/StarknetChainEventsBrowser.d.ts +89 -90
  49. package/dist/starknet/events/StarknetChainEventsBrowser.js +296 -294
  50. package/dist/starknet/provider/RpcProviderWithRetries.d.ts +21 -21
  51. package/dist/starknet/provider/RpcProviderWithRetries.js +32 -32
  52. package/dist/starknet/spv_swap/SpvVaultContractAbi.d.ts +488 -488
  53. package/dist/starknet/spv_swap/SpvVaultContractAbi.js +656 -656
  54. package/dist/starknet/spv_swap/StarknetSpvVaultContract.d.ts +66 -66
  55. package/dist/starknet/spv_swap/StarknetSpvVaultContract.js +382 -382
  56. package/dist/starknet/spv_swap/StarknetSpvVaultData.d.ts +49 -49
  57. package/dist/starknet/spv_swap/StarknetSpvVaultData.js +145 -145
  58. package/dist/starknet/spv_swap/StarknetSpvWithdrawalData.d.ts +25 -25
  59. package/dist/starknet/spv_swap/StarknetSpvWithdrawalData.js +72 -72
  60. package/dist/starknet/swaps/EscrowManagerAbi.d.ts +431 -431
  61. package/dist/starknet/swaps/EscrowManagerAbi.js +583 -583
  62. package/dist/starknet/swaps/StarknetSwapContract.d.ts +191 -191
  63. package/dist/starknet/swaps/StarknetSwapContract.js +424 -424
  64. package/dist/starknet/swaps/StarknetSwapData.d.ts +74 -74
  65. package/dist/starknet/swaps/StarknetSwapData.js +325 -325
  66. package/dist/starknet/swaps/StarknetSwapModule.d.ts +10 -10
  67. package/dist/starknet/swaps/StarknetSwapModule.js +11 -11
  68. package/dist/starknet/swaps/handlers/IHandler.d.ts +13 -13
  69. package/dist/starknet/swaps/handlers/IHandler.js +2 -2
  70. package/dist/starknet/swaps/handlers/claim/ClaimHandlers.d.ts +13 -13
  71. package/dist/starknet/swaps/handlers/claim/ClaimHandlers.js +13 -13
  72. package/dist/starknet/swaps/handlers/claim/HashlockClaimHandler.d.ts +21 -21
  73. package/dist/starknet/swaps/handlers/claim/HashlockClaimHandler.js +44 -44
  74. package/dist/starknet/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.d.ts +24 -24
  75. package/dist/starknet/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.js +48 -48
  76. package/dist/starknet/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.d.ts +25 -25
  77. package/dist/starknet/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.js +40 -40
  78. package/dist/starknet/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.d.ts +20 -20
  79. package/dist/starknet/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.js +30 -30
  80. package/dist/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.d.ts +45 -45
  81. package/dist/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.js +52 -52
  82. package/dist/starknet/swaps/handlers/refund/TimelockRefundHandler.d.ts +17 -17
  83. package/dist/starknet/swaps/handlers/refund/TimelockRefundHandler.js +27 -27
  84. package/dist/starknet/swaps/modules/StarknetLpVault.d.ts +69 -69
  85. package/dist/starknet/swaps/modules/StarknetLpVault.js +122 -122
  86. package/dist/starknet/swaps/modules/StarknetSwapClaim.d.ts +53 -53
  87. package/dist/starknet/swaps/modules/StarknetSwapClaim.js +100 -100
  88. package/dist/starknet/swaps/modules/StarknetSwapInit.d.ts +94 -87
  89. package/dist/starknet/swaps/modules/StarknetSwapInit.js +235 -225
  90. package/dist/starknet/swaps/modules/StarknetSwapRefund.d.ts +62 -62
  91. package/dist/starknet/swaps/modules/StarknetSwapRefund.js +128 -128
  92. package/dist/starknet/wallet/StarknetKeypairWallet.d.ts +7 -7
  93. package/dist/starknet/wallet/StarknetKeypairWallet.js +35 -30
  94. package/dist/starknet/wallet/StarknetSigner.d.ts +12 -12
  95. package/dist/starknet/wallet/StarknetSigner.js +47 -46
  96. package/dist/utils/Utils.d.ts +37 -37
  97. package/dist/utils/Utils.js +260 -261
  98. package/package.json +43 -37
  99. package/src/index.ts +47 -47
  100. package/src/starknet/StarknetChainType.ts +28 -28
  101. package/src/starknet/StarknetInitializer.ts +108 -108
  102. package/src/starknet/btcrelay/BtcRelayAbi.ts +338 -338
  103. package/src/starknet/btcrelay/StarknetBtcRelay.ts +494 -494
  104. package/src/starknet/btcrelay/headers/StarknetBtcHeader.ts +100 -100
  105. package/src/starknet/btcrelay/headers/StarknetBtcStoredHeader.ts +141 -141
  106. package/src/starknet/chain/StarknetAction.ts +85 -85
  107. package/src/starknet/chain/StarknetChainInterface.ts +149 -149
  108. package/src/starknet/chain/StarknetModule.ts +19 -19
  109. package/src/starknet/chain/modules/ERC20Abi.ts +1029 -1029
  110. package/src/starknet/chain/modules/StarknetAccounts.ts +25 -25
  111. package/src/starknet/chain/modules/StarknetAddresses.ts +22 -22
  112. package/src/starknet/chain/modules/StarknetBlocks.ts +75 -74
  113. package/src/starknet/chain/modules/StarknetEvents.ts +104 -104
  114. package/src/starknet/chain/modules/StarknetFees.ts +154 -154
  115. package/src/starknet/chain/modules/StarknetSignatures.ts +91 -91
  116. package/src/starknet/chain/modules/StarknetTokens.ts +120 -116
  117. package/src/starknet/chain/modules/StarknetTransactions.ts +285 -283
  118. package/src/starknet/contract/StarknetContractBase.ts +30 -26
  119. package/src/starknet/contract/StarknetContractModule.ts +16 -16
  120. package/src/starknet/contract/modules/StarknetContractEvents.ts +134 -134
  121. package/src/starknet/events/StarknetChainEvents.ts +67 -67
  122. package/src/starknet/events/StarknetChainEventsBrowser.ts +411 -411
  123. package/src/starknet/provider/RpcProviderWithRetries.ts +43 -43
  124. package/src/starknet/spv_swap/SpvVaultContractAbi.ts +656 -656
  125. package/src/starknet/spv_swap/StarknetSpvVaultContract.ts +483 -483
  126. package/src/starknet/spv_swap/StarknetSpvVaultData.ts +195 -195
  127. package/src/starknet/spv_swap/StarknetSpvWithdrawalData.ts +79 -79
  128. package/src/starknet/swaps/EscrowManagerAbi.ts +582 -582
  129. package/src/starknet/swaps/StarknetSwapContract.ts +647 -647
  130. package/src/starknet/swaps/StarknetSwapData.ts +455 -455
  131. package/src/starknet/swaps/StarknetSwapModule.ts +17 -17
  132. package/src/starknet/swaps/handlers/IHandler.ts +20 -20
  133. package/src/starknet/swaps/handlers/claim/ClaimHandlers.ts +23 -23
  134. package/src/starknet/swaps/handlers/claim/HashlockClaimHandler.ts +53 -53
  135. package/src/starknet/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.ts +73 -73
  136. package/src/starknet/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.ts +67 -67
  137. package/src/starknet/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.ts +50 -50
  138. package/src/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.ts +102 -102
  139. package/src/starknet/swaps/handlers/refund/TimelockRefundHandler.ts +38 -38
  140. package/src/starknet/swaps/modules/StarknetLpVault.ts +147 -147
  141. package/src/starknet/swaps/modules/StarknetSwapClaim.ts +141 -141
  142. package/src/starknet/swaps/modules/StarknetSwapInit.ts +300 -287
  143. package/src/starknet/swaps/modules/StarknetSwapRefund.ts +196 -196
  144. package/src/starknet/wallet/StarknetKeypairWallet.ts +44 -39
  145. package/src/starknet/wallet/StarknetSigner.ts +55 -55
  146. package/src/utils/Utils.ts +251 -252
@@ -1,382 +1,382 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.StarknetSpvVaultContract = void 0;
4
- const base_1 = require("@atomiqlabs/base");
5
- const buffer_1 = require("buffer");
6
- const StarknetContractBase_1 = require("../contract/StarknetContractBase");
7
- const StarknetBtcRelay_1 = require("../btcrelay/StarknetBtcRelay");
8
- const starknet_1 = require("starknet");
9
- const StarknetAction_1 = require("../chain/StarknetAction");
10
- const SpvVaultContractAbi_1 = require("./SpvVaultContractAbi");
11
- const StarknetSpvVaultData_1 = require("./StarknetSpvVaultData");
12
- const StarknetSpvWithdrawalData_1 = require("./StarknetSpvWithdrawalData");
13
- const Utils_1 = require("../../utils/Utils");
14
- const StarknetAddresses_1 = require("../chain/modules/StarknetAddresses");
15
- const StarknetFees_1 = require("../chain/modules/StarknetFees");
16
- const spvVaultContractAddreses = {
17
- [starknet_1.constants.StarknetChainId.SN_SEPOLIA]: "0x02d581ea838cd5ca46ba08660eddd064d50a0392f618e95310432147928d572e",
18
- [starknet_1.constants.StarknetChainId.SN_MAIN]: "0x01932042992647771f3d0aa6ee526e65359c891fe05a285faaf4d3ffa373e132"
19
- };
20
- const STARK_PRIME_MOD = 2n ** 251n + 17n * 2n ** 192n + 1n;
21
- function decodeUtxo(utxo) {
22
- const [txId, vout] = utxo.split(":");
23
- return {
24
- txHash: BigInt("0x" + buffer_1.Buffer.from(txId, "hex").reverse().toString("hex")),
25
- vout: BigInt(vout)
26
- };
27
- }
28
- class StarknetSpvVaultContract extends StarknetContractBase_1.StarknetContractBase {
29
- constructor(chainInterface, btcRelay, bitcoinRpc, contractAddress = spvVaultContractAddreses[chainInterface.starknetChainId]) {
30
- super(chainInterface, contractAddress, SpvVaultContractAbi_1.SpvVaultContractAbi);
31
- this.chainId = "STARKNET";
32
- this.claimTimeout = 180;
33
- this.maxClaimsPerTx = 10;
34
- this.logger = (0, Utils_1.getLogger)("StarknetSpvVaultContract: ");
35
- this.btcRelay = btcRelay;
36
- this.bitcoinRpc = bitcoinRpc;
37
- }
38
- //StarknetActions
39
- Open(signer, vault) {
40
- const { txHash, vout } = decodeUtxo(vault.getUtxo());
41
- const tokens = vault.getTokenData();
42
- if (tokens.length !== 2)
43
- throw new Error("Must specify exactly 2 tokens for vault!");
44
- return new StarknetAction_1.StarknetAction(signer, this.Chain, this.contract.populateTransaction.open(vault.getVaultId(), this.btcRelay.contract.address, starknet_1.cairo.tuple(starknet_1.cairo.uint256(txHash), vout), vault.getConfirmations(), tokens[0].token, tokens[1].token, tokens[0].multiplier, tokens[1].multiplier), StarknetSpvVaultContract.GasCosts.OPEN);
45
- }
46
- Deposit(signer, vault, rawAmounts) {
47
- return new StarknetAction_1.StarknetAction(signer, this.Chain, this.contract.populateTransaction.deposit(vault.getOwner(), vault.getVaultId(), rawAmounts[0], rawAmounts[1] ?? 0n), StarknetSpvVaultContract.GasCosts.DEPOSIT);
48
- }
49
- Front(signer, vault, data, withdrawalSequence) {
50
- return new StarknetAction_1.StarknetAction(signer, this.Chain, this.contract.populateTransaction.front(vault.getOwner(), vault.getVaultId(), BigInt(withdrawalSequence), data.getTxHash(), data.serializeToStruct()), StarknetSpvVaultContract.GasCosts.FRONT);
51
- }
52
- Claim(signer, vault, data, blockheader, merkle, position) {
53
- return new StarknetAction_1.StarknetAction(signer, this.Chain, {
54
- contractAddress: this.contract.address,
55
- entrypoint: "claim",
56
- calldata: [
57
- vault.getOwner(),
58
- vault.getVaultId(),
59
- ...(0, Utils_1.bufferToByteArray)(buffer_1.Buffer.from(data.btcTx.hex, "hex")),
60
- ...blockheader.serialize(),
61
- merkle.length,
62
- ...merkle.map(Utils_1.bufferToU32Array).flat(),
63
- position,
64
- ].map(val => (0, Utils_1.toHex)(val, 0))
65
- }, StarknetSpvVaultContract.GasCosts.CLAIM);
66
- }
67
- async checkWithdrawalTx(tx) {
68
- const result = await this.Chain.provider.callContract({
69
- contractAddress: this.contract.address,
70
- entrypoint: "parse_bitcoin_tx",
71
- calldata: (0, Utils_1.bufferToByteArray)(buffer_1.Buffer.from(tx.btcTx.hex, "hex"))
72
- });
73
- if (result == null)
74
- throw new Error("Failed to parse transaction!");
75
- }
76
- createVaultData(owner, vaultId, utxo, confirmations, tokenData) {
77
- if (tokenData.length !== 2)
78
- throw new Error("Must specify 2 tokens in tokenData!");
79
- return Promise.resolve(new StarknetSpvVaultData_1.StarknetSpvVaultData(owner, vaultId, {
80
- relay_contract: this.btcRelay.contract.address,
81
- token_0: tokenData[0].token,
82
- token_1: tokenData[1].token,
83
- token_0_multiplier: tokenData[0].multiplier,
84
- token_1_multiplier: tokenData[1].multiplier,
85
- utxo: starknet_1.cairo.tuple(starknet_1.cairo.uint256(0), 0),
86
- confirmations: confirmations,
87
- withdraw_count: 0,
88
- deposit_count: 0,
89
- token_0_amount: 0n,
90
- token_1_amount: 0n
91
- }, utxo));
92
- }
93
- //Getters
94
- async getVaultData(owner, vaultId) {
95
- const struct = await this.contract.get_vault(owner, vaultId);
96
- if ((0, Utils_1.toHex)(struct.relay_contract) !== (0, Utils_1.toHex)(this.btcRelay.contract.address))
97
- return null;
98
- return new StarknetSpvVaultData_1.StarknetSpvVaultData(owner, vaultId, struct);
99
- }
100
- async getAllVaults(owner) {
101
- const openedVaults = new Set();
102
- await this.Events.findInContractEventsForward(["spv_swap_vault::events::Opened", "spv_swap_vault::events::Closed"], owner == null ? null : [null, owner], (event) => {
103
- const owner = (0, Utils_1.toHex)(event.params.owner);
104
- const vaultId = (0, Utils_1.toBigInt)(event.params.vault_id);
105
- const vaultIdentifier = owner + ":" + vaultId.toString(10);
106
- if (event.name === "spv_swap_vault::events::Opened") {
107
- openedVaults.add(vaultIdentifier);
108
- }
109
- else {
110
- openedVaults.delete(vaultIdentifier);
111
- }
112
- return null;
113
- });
114
- const vaults = [];
115
- for (let identifier of openedVaults.keys()) {
116
- const [owner, vaultIdStr] = identifier.split(":");
117
- const vaultData = await this.getVaultData(owner, BigInt(vaultIdStr));
118
- if (vaultData != null)
119
- vaults.push(vaultData);
120
- }
121
- return vaults;
122
- }
123
- async getFronterAddress(owner, vaultId, withdrawal) {
124
- const fronterAddress = await this.contract.get_fronter_address_by_id(owner, vaultId, "0x" + withdrawal.getFrontingId());
125
- if ((0, Utils_1.toHex)(fronterAddress, 64) === "0x0000000000000000000000000000000000000000000000000000000000000000")
126
- return null;
127
- return fronterAddress;
128
- }
129
- async getWithdrawalState(btcTxId) {
130
- const txHash = buffer_1.Buffer.from(btcTxId, "hex").reverse();
131
- const txHashU256 = starknet_1.cairo.uint256("0x" + txHash.toString("hex"));
132
- let result = {
133
- type: base_1.SpvWithdrawalStateType.NOT_FOUND
134
- };
135
- await this.Events.findInContractEventsForward(["spv_swap_vault::events::Fronted", "spv_swap_vault::events::Claimed", "spv_swap_vault::events::Closed"], [
136
- (0, Utils_1.toHex)(txHashU256.low),
137
- (0, Utils_1.toHex)(txHashU256.high)
138
- ], async (event) => {
139
- switch (event.name) {
140
- case "spv_swap_vault::events::Fronted":
141
- result = {
142
- type: base_1.SpvWithdrawalStateType.FRONTED,
143
- txId: event.txHash,
144
- owner: (0, Utils_1.toHex)(event.params.owner),
145
- vaultId: (0, Utils_1.toBigInt)(event.params.vault_id),
146
- recipient: (0, Utils_1.toHex)(event.params.recipient),
147
- fronter: (0, Utils_1.toHex)(event.params.fronting_address)
148
- };
149
- break;
150
- case "spv_swap_vault::events::Claimed":
151
- result = {
152
- type: base_1.SpvWithdrawalStateType.CLAIMED,
153
- txId: event.txHash,
154
- owner: (0, Utils_1.toHex)(event.params.owner),
155
- vaultId: (0, Utils_1.toBigInt)(event.params.vault_id),
156
- recipient: (0, Utils_1.toHex)(event.params.recipient),
157
- claimer: (0, Utils_1.toHex)(event.params.caller),
158
- fronter: (0, Utils_1.toHex)(event.params.fronting_address)
159
- };
160
- break;
161
- case "spv_swap_vault::events::Closed":
162
- result = {
163
- type: base_1.SpvWithdrawalStateType.CLOSED,
164
- txId: event.txHash,
165
- owner: (0, Utils_1.toHex)(event.params.owner),
166
- vaultId: (0, Utils_1.toBigInt)(event.params.vault_id),
167
- error: (0, Utils_1.bigNumberishToBuffer)(event.params.error).toString()
168
- };
169
- break;
170
- }
171
- });
172
- return result;
173
- }
174
- getWithdrawalData(btcTx) {
175
- return Promise.resolve(new StarknetSpvWithdrawalData_1.StarknetSpvWithdrawalData(btcTx));
176
- }
177
- //OP_RETURN data encoding/decoding
178
- fromOpReturnData(data) {
179
- return StarknetSpvVaultContract.fromOpReturnData(data);
180
- }
181
- static fromOpReturnData(data) {
182
- let rawAmount0 = 0n;
183
- let rawAmount1 = 0n;
184
- let executionHash = null;
185
- if (data.length === 40) {
186
- rawAmount0 = data.readBigInt64LE(32).valueOf();
187
- }
188
- else if (data.length === 48) {
189
- rawAmount0 = data.readBigInt64LE(32).valueOf();
190
- rawAmount1 = data.readBigInt64LE(40).valueOf();
191
- }
192
- else if (data.length === 72) {
193
- rawAmount0 = data.readBigInt64LE(32).valueOf();
194
- executionHash = data.slice(40, 72).toString("hex");
195
- }
196
- else if (data.length === 80) {
197
- rawAmount0 = data.readBigInt64LE(32).valueOf();
198
- rawAmount1 = data.readBigInt64LE(40).valueOf();
199
- executionHash = data.slice(48, 80).toString("hex");
200
- }
201
- else {
202
- throw new Error("Invalid OP_RETURN data length!");
203
- }
204
- if (executionHash != null) {
205
- const executionHashValue = BigInt("0x" + executionHash);
206
- if (executionHashValue >= STARK_PRIME_MOD)
207
- throw new Error("Execution hash not in range of starknet prime");
208
- }
209
- const recipient = "0x" + data.slice(0, 32).toString("hex");
210
- if (!StarknetAddresses_1.StarknetAddresses.isValidAddress(recipient))
211
- throw new Error("Invalid recipient specified");
212
- return { executionHash, rawAmounts: [rawAmount0, rawAmount1], recipient };
213
- }
214
- toOpReturnData(recipient, rawAmounts, executionHash) {
215
- return StarknetSpvVaultContract.toOpReturnData(recipient, rawAmounts, executionHash);
216
- }
217
- static toOpReturnData(recipient, rawAmounts, executionHash) {
218
- if (!StarknetAddresses_1.StarknetAddresses.isValidAddress(recipient))
219
- throw new Error("Invalid recipient specified");
220
- if (rawAmounts.length < 1)
221
- throw new Error("At least 1 amount needs to be specified");
222
- if (rawAmounts.length > 2)
223
- throw new Error("At most 2 amounts need to be specified");
224
- rawAmounts.forEach(val => {
225
- if (val < 0n)
226
- throw new Error("Negative raw amount specified");
227
- if (val >= 2n ** 64n)
228
- throw new Error("Raw amount overflow");
229
- });
230
- if (executionHash != null) {
231
- const executionHashValue = (0, Utils_1.toBigInt)(executionHash);
232
- if (executionHashValue < 0n)
233
- throw new Error("Execution hash negative");
234
- if (executionHashValue >= STARK_PRIME_MOD)
235
- throw new Error("Execution hash not in range of starknet prime");
236
- }
237
- const recipientBuffer = buffer_1.Buffer.from(recipient.substring(2).padStart(64, "0"), "hex");
238
- const amount0Buffer = buffer_1.Buffer.from(rawAmounts[0].toString(16).padStart(16, "0"), "hex");
239
- const amount1Buffer = rawAmounts[1] == null || rawAmounts[1] === 0n ? buffer_1.Buffer.alloc(0) : buffer_1.Buffer.from(rawAmounts[1].toString(16).padStart(16, "0"), "hex");
240
- const executionHashBuffer = executionHash == null ? buffer_1.Buffer.alloc(0) : buffer_1.Buffer.from(executionHash.substring(2).padStart(64, "0"), "hex");
241
- return buffer_1.Buffer.concat([
242
- recipientBuffer,
243
- amount0Buffer.reverse(),
244
- amount1Buffer.reverse(),
245
- executionHashBuffer
246
- ]);
247
- }
248
- //Actions
249
- async claim(signer, vault, txs, synchronizer, initAta, txOptions) {
250
- const result = await this.txsClaim(signer.getAddress(), vault, txs, synchronizer, initAta, txOptions?.feeRate);
251
- const [signature] = await this.Chain.sendAndConfirm(signer, result, txOptions?.waitForConfirmation, txOptions?.abortSignal);
252
- return signature;
253
- }
254
- async deposit(signer, vault, rawAmounts, txOptions) {
255
- const result = await this.txsDeposit(signer.getAddress(), vault, rawAmounts, txOptions?.feeRate);
256
- const [signature] = await this.Chain.sendAndConfirm(signer, result, txOptions?.waitForConfirmation, txOptions?.abortSignal);
257
- return signature;
258
- }
259
- async frontLiquidity(signer, vault, realWithdrawalTx, withdrawSequence, txOptions) {
260
- const result = await this.txsFrontLiquidity(signer.getAddress(), vault, realWithdrawalTx, withdrawSequence, txOptions?.feeRate);
261
- const [signature] = await this.Chain.sendAndConfirm(signer, result, txOptions?.waitForConfirmation, txOptions?.abortSignal);
262
- return signature;
263
- }
264
- async open(signer, vault, txOptions) {
265
- const result = await this.txsOpen(signer.getAddress(), vault, txOptions?.feeRate);
266
- const [signature] = await this.Chain.sendAndConfirm(signer, result, txOptions?.waitForConfirmation, txOptions?.abortSignal);
267
- return signature;
268
- }
269
- //Transactions
270
- async txsClaim(signer, vault, txs, synchronizer, initAta, feeRate) {
271
- if (!vault.isOpened())
272
- throw new Error("Cannot claim from a closed vault!");
273
- feeRate ?? (feeRate = await this.Chain.Fees.getFeeRate());
274
- const txsWithMerkleProofs = [];
275
- for (let tx of txs) {
276
- const merkleProof = await this.bitcoinRpc.getMerkleProof(tx.tx.btcTx.txid, tx.tx.btcTx.blockhash);
277
- this.logger.debug("txsClaim(): merkle proof computed: ", merkleProof);
278
- txsWithMerkleProofs.push({
279
- ...merkleProof,
280
- ...tx
281
- });
282
- }
283
- const starknetTxs = [];
284
- const storedHeaders = await StarknetBtcRelay_1.StarknetBtcRelay.getCommitedHeadersAndSynchronize(signer, this.btcRelay, txsWithMerkleProofs.filter(tx => tx.storedHeader == null).map(tx => {
285
- return {
286
- blockhash: tx.tx.btcTx.blockhash,
287
- blockheight: tx.blockheight,
288
- requiredConfirmations: vault.getConfirmations()
289
- };
290
- }), starknetTxs, synchronizer, feeRate);
291
- if (storedHeaders == null)
292
- throw new Error("Cannot fetch committed header!");
293
- const actions = txsWithMerkleProofs.map(tx => {
294
- return this.Claim(signer, vault, tx.tx, tx.storedHeader ?? storedHeaders[tx.tx.btcTx.blockhash], tx.merkle, tx.pos);
295
- });
296
- let starknetAction = new StarknetAction_1.StarknetAction(signer, this.Chain);
297
- for (let action of actions) {
298
- starknetAction.add(action);
299
- if (starknetAction.ixsLength() >= this.maxClaimsPerTx) {
300
- await starknetAction.addToTxs(starknetTxs, feeRate);
301
- starknetAction = new StarknetAction_1.StarknetAction(signer, this.Chain);
302
- }
303
- }
304
- if (starknetAction.ixsLength() > 0) {
305
- await starknetAction.addToTxs(starknetTxs, feeRate);
306
- }
307
- this.logger.debug("txsClaim(): " + starknetTxs.length + " claim TXs created claiming " + txs.length + " txs, owner: " + vault.getOwner() +
308
- " vaultId: " + vault.getVaultId().toString(10));
309
- return starknetTxs;
310
- }
311
- async txsDeposit(signer, vault, rawAmounts, feeRate) {
312
- if (!vault.isOpened())
313
- throw new Error("Cannot deposit to a closed vault!");
314
- //Approve first
315
- const vaultTokens = vault.getTokenData();
316
- const action = new StarknetAction_1.StarknetAction(signer, this.Chain);
317
- let realAmount0 = 0n;
318
- let realAmount1 = 0n;
319
- if (rawAmounts[0] != null && rawAmounts[0] !== 0n) {
320
- realAmount0 = rawAmounts[0] * vaultTokens[0].multiplier;
321
- action.add(this.Chain.Tokens.Approve(signer, this.contract.address, vaultTokens[0].token, realAmount0));
322
- }
323
- if (rawAmounts[1] != null && rawAmounts[1] !== 0n) {
324
- realAmount1 = rawAmounts[1] * vaultTokens[1].multiplier;
325
- action.add(this.Chain.Tokens.Approve(signer, this.contract.address, vaultTokens[1].token, realAmount1));
326
- }
327
- action.add(this.Deposit(signer, vault, rawAmounts));
328
- feeRate ?? (feeRate = await this.Chain.Fees.getFeeRate());
329
- this.logger.debug("txsDeposit(): deposit TX created," +
330
- " token0: " + vaultTokens[0].token + " rawAmount0: " + rawAmounts[0].toString(10) + " amount0: " + realAmount0.toString(10) +
331
- " token1: " + vaultTokens[1].token + " rawAmount1: " + (rawAmounts[1] ?? 0n).toString(10) + " amount1: " + realAmount1.toString(10));
332
- return [await action.tx(feeRate)];
333
- }
334
- async txsFrontLiquidity(signer, vault, realWithdrawalTx, withdrawSequence, feeRate) {
335
- if (!vault.isOpened())
336
- throw new Error("Cannot front on a closed vault!");
337
- //Approve first
338
- const vaultTokens = vault.getTokenData();
339
- const action = new StarknetAction_1.StarknetAction(signer, this.Chain);
340
- const rawAmounts = realWithdrawalTx.getFrontingAmount();
341
- let realAmount0 = 0n;
342
- let realAmount1 = 0n;
343
- if (rawAmounts[0] != null && rawAmounts[0] !== 0n) {
344
- realAmount0 = rawAmounts[0] * vaultTokens[0].multiplier;
345
- action.add(this.Chain.Tokens.Approve(signer, this.contract.address, vaultTokens[0].token, realAmount0));
346
- }
347
- if (rawAmounts[1] != null && rawAmounts[1] !== 0n) {
348
- realAmount1 = rawAmounts[1] * vaultTokens[1].multiplier;
349
- action.add(this.Chain.Tokens.Approve(signer, this.contract.address, vaultTokens[1].token, realAmount1));
350
- }
351
- action.add(this.Front(signer, vault, realWithdrawalTx, withdrawSequence));
352
- feeRate ?? (feeRate = await this.Chain.Fees.getFeeRate());
353
- this.logger.debug("txsFrontLiquidity(): front TX created," +
354
- " token0: " + vaultTokens[0].token + " rawAmount0: " + rawAmounts[0].toString(10) + " amount0: " + realAmount0.toString(10) +
355
- " token1: " + vaultTokens[1].token + " rawAmount1: " + (rawAmounts[1] ?? 0n).toString(10) + " amount1: " + realAmount1.toString(10));
356
- return [await action.tx(feeRate)];
357
- }
358
- async txsOpen(signer, vault, feeRate) {
359
- if (vault.isOpened())
360
- throw new Error("Cannot open an already opened vault!");
361
- const action = this.Open(signer, vault);
362
- feeRate ?? (feeRate = await this.Chain.Fees.getFeeRate());
363
- this.logger.debug("txsOpen(): open TX created, owner: " + vault.getOwner() +
364
- " vaultId: " + vault.getVaultId().toString(10));
365
- return [await action.tx(feeRate)];
366
- }
367
- async getClaimFee(signer, vault, withdrawalData, feeRate) {
368
- feeRate ?? (feeRate = await this.Chain.Fees.getFeeRate());
369
- return StarknetFees_1.StarknetFees.getGasFee(StarknetSpvVaultContract.GasCosts.CLAIM, feeRate);
370
- }
371
- async getFrontFee(signer, vault, withdrawalData, feeRate) {
372
- feeRate ?? (feeRate = await this.Chain.Fees.getFeeRate());
373
- return StarknetFees_1.StarknetFees.getGasFee(StarknetSpvVaultContract.GasCosts.FRONT, feeRate);
374
- }
375
- }
376
- exports.StarknetSpvVaultContract = StarknetSpvVaultContract;
377
- StarknetSpvVaultContract.GasCosts = {
378
- DEPOSIT: { l1DataGas: 400, l2Gas: 4000000, l1Gas: 0 },
379
- OPEN: { l1DataGas: 1200, l2Gas: 3200000, l1Gas: 0 },
380
- FRONT: { l1DataGas: 800, l2Gas: 12000000, l1Gas: 0 },
381
- CLAIM: { l1DataGas: 1000, l2Gas: 400000000, l1Gas: 0 }
382
- };
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StarknetSpvVaultContract = void 0;
4
+ const base_1 = require("@atomiqlabs/base");
5
+ const buffer_1 = require("buffer");
6
+ const StarknetContractBase_1 = require("../contract/StarknetContractBase");
7
+ const StarknetBtcRelay_1 = require("../btcrelay/StarknetBtcRelay");
8
+ const starknet_1 = require("starknet");
9
+ const StarknetAction_1 = require("../chain/StarknetAction");
10
+ const SpvVaultContractAbi_1 = require("./SpvVaultContractAbi");
11
+ const StarknetSpvVaultData_1 = require("./StarknetSpvVaultData");
12
+ const StarknetSpvWithdrawalData_1 = require("./StarknetSpvWithdrawalData");
13
+ const Utils_1 = require("../../utils/Utils");
14
+ const StarknetAddresses_1 = require("../chain/modules/StarknetAddresses");
15
+ const StarknetFees_1 = require("../chain/modules/StarknetFees");
16
+ const spvVaultContractAddreses = {
17
+ [starknet_1.constants.StarknetChainId.SN_SEPOLIA]: "0x02d581ea838cd5ca46ba08660eddd064d50a0392f618e95310432147928d572e",
18
+ [starknet_1.constants.StarknetChainId.SN_MAIN]: "0x01932042992647771f3d0aa6ee526e65359c891fe05a285faaf4d3ffa373e132"
19
+ };
20
+ const STARK_PRIME_MOD = 2n ** 251n + 17n * 2n ** 192n + 1n;
21
+ function decodeUtxo(utxo) {
22
+ const [txId, vout] = utxo.split(":");
23
+ return {
24
+ txHash: BigInt("0x" + buffer_1.Buffer.from(txId, "hex").reverse().toString("hex")),
25
+ vout: BigInt(vout)
26
+ };
27
+ }
28
+ class StarknetSpvVaultContract extends StarknetContractBase_1.StarknetContractBase {
29
+ constructor(chainInterface, btcRelay, bitcoinRpc, contractAddress = spvVaultContractAddreses[chainInterface.starknetChainId]) {
30
+ super(chainInterface, contractAddress, SpvVaultContractAbi_1.SpvVaultContractAbi);
31
+ this.chainId = "STARKNET";
32
+ this.claimTimeout = 180;
33
+ this.maxClaimsPerTx = 10;
34
+ this.logger = (0, Utils_1.getLogger)("StarknetSpvVaultContract: ");
35
+ this.btcRelay = btcRelay;
36
+ this.bitcoinRpc = bitcoinRpc;
37
+ }
38
+ //StarknetActions
39
+ Open(signer, vault) {
40
+ const { txHash, vout } = decodeUtxo(vault.getUtxo());
41
+ const tokens = vault.getTokenData();
42
+ if (tokens.length !== 2)
43
+ throw new Error("Must specify exactly 2 tokens for vault!");
44
+ return new StarknetAction_1.StarknetAction(signer, this.Chain, this.contract.populateTransaction.open(vault.getVaultId(), this.btcRelay.contract.address, starknet_1.cairo.tuple(starknet_1.cairo.uint256(txHash), vout), vault.getConfirmations(), tokens[0].token, tokens[1].token, tokens[0].multiplier, tokens[1].multiplier), StarknetSpvVaultContract.GasCosts.OPEN);
45
+ }
46
+ Deposit(signer, vault, rawAmounts) {
47
+ return new StarknetAction_1.StarknetAction(signer, this.Chain, this.contract.populateTransaction.deposit(vault.getOwner(), vault.getVaultId(), rawAmounts[0], rawAmounts[1] ?? 0n), StarknetSpvVaultContract.GasCosts.DEPOSIT);
48
+ }
49
+ Front(signer, vault, data, withdrawalSequence) {
50
+ return new StarknetAction_1.StarknetAction(signer, this.Chain, this.contract.populateTransaction.front(vault.getOwner(), vault.getVaultId(), BigInt(withdrawalSequence), data.getTxHash(), data.serializeToStruct()), StarknetSpvVaultContract.GasCosts.FRONT);
51
+ }
52
+ Claim(signer, vault, data, blockheader, merkle, position) {
53
+ return new StarknetAction_1.StarknetAction(signer, this.Chain, {
54
+ contractAddress: this.contract.address,
55
+ entrypoint: "claim",
56
+ calldata: [
57
+ vault.getOwner(),
58
+ vault.getVaultId(),
59
+ ...(0, Utils_1.bufferToByteArray)(buffer_1.Buffer.from(data.btcTx.hex, "hex")),
60
+ ...blockheader.serialize(),
61
+ merkle.length,
62
+ ...merkle.map(Utils_1.bufferToU32Array).flat(),
63
+ position,
64
+ ].map(val => (0, Utils_1.toHex)(val, 0))
65
+ }, StarknetSpvVaultContract.GasCosts.CLAIM);
66
+ }
67
+ async checkWithdrawalTx(tx) {
68
+ const result = await this.Chain.provider.callContract({
69
+ contractAddress: this.contract.address,
70
+ entrypoint: "parse_bitcoin_tx",
71
+ calldata: (0, Utils_1.bufferToByteArray)(buffer_1.Buffer.from(tx.btcTx.hex, "hex"))
72
+ });
73
+ if (result == null)
74
+ throw new Error("Failed to parse transaction!");
75
+ }
76
+ createVaultData(owner, vaultId, utxo, confirmations, tokenData) {
77
+ if (tokenData.length !== 2)
78
+ throw new Error("Must specify 2 tokens in tokenData!");
79
+ return Promise.resolve(new StarknetSpvVaultData_1.StarknetSpvVaultData(owner, vaultId, {
80
+ relay_contract: this.btcRelay.contract.address,
81
+ token_0: tokenData[0].token,
82
+ token_1: tokenData[1].token,
83
+ token_0_multiplier: tokenData[0].multiplier,
84
+ token_1_multiplier: tokenData[1].multiplier,
85
+ utxo: starknet_1.cairo.tuple(starknet_1.cairo.uint256(0), 0),
86
+ confirmations: confirmations,
87
+ withdraw_count: 0,
88
+ deposit_count: 0,
89
+ token_0_amount: 0n,
90
+ token_1_amount: 0n
91
+ }, utxo));
92
+ }
93
+ //Getters
94
+ async getVaultData(owner, vaultId) {
95
+ const struct = await this.contract.get_vault(owner, vaultId);
96
+ if ((0, Utils_1.toHex)(struct.relay_contract) !== (0, Utils_1.toHex)(this.btcRelay.contract.address))
97
+ return null;
98
+ return new StarknetSpvVaultData_1.StarknetSpvVaultData(owner, vaultId, struct);
99
+ }
100
+ async getAllVaults(owner) {
101
+ const openedVaults = new Set();
102
+ await this.Events.findInContractEventsForward(["spv_swap_vault::events::Opened", "spv_swap_vault::events::Closed"], owner == null ? null : [null, owner], (event) => {
103
+ const owner = (0, Utils_1.toHex)(event.params.owner);
104
+ const vaultId = (0, Utils_1.toBigInt)(event.params.vault_id);
105
+ const vaultIdentifier = owner + ":" + vaultId.toString(10);
106
+ if (event.name === "spv_swap_vault::events::Opened") {
107
+ openedVaults.add(vaultIdentifier);
108
+ }
109
+ else {
110
+ openedVaults.delete(vaultIdentifier);
111
+ }
112
+ return null;
113
+ });
114
+ const vaults = [];
115
+ for (let identifier of openedVaults.keys()) {
116
+ const [owner, vaultIdStr] = identifier.split(":");
117
+ const vaultData = await this.getVaultData(owner, BigInt(vaultIdStr));
118
+ if (vaultData != null)
119
+ vaults.push(vaultData);
120
+ }
121
+ return vaults;
122
+ }
123
+ async getFronterAddress(owner, vaultId, withdrawal) {
124
+ const fronterAddress = await this.contract.get_fronter_address_by_id(owner, vaultId, "0x" + withdrawal.getFrontingId());
125
+ if ((0, Utils_1.toHex)(fronterAddress, 64) === "0x0000000000000000000000000000000000000000000000000000000000000000")
126
+ return null;
127
+ return fronterAddress;
128
+ }
129
+ async getWithdrawalState(btcTxId) {
130
+ const txHash = buffer_1.Buffer.from(btcTxId, "hex").reverse();
131
+ const txHashU256 = starknet_1.cairo.uint256("0x" + txHash.toString("hex"));
132
+ let result = {
133
+ type: base_1.SpvWithdrawalStateType.NOT_FOUND
134
+ };
135
+ await this.Events.findInContractEventsForward(["spv_swap_vault::events::Fronted", "spv_swap_vault::events::Claimed", "spv_swap_vault::events::Closed"], [
136
+ (0, Utils_1.toHex)(txHashU256.low),
137
+ (0, Utils_1.toHex)(txHashU256.high)
138
+ ], async (event) => {
139
+ switch (event.name) {
140
+ case "spv_swap_vault::events::Fronted":
141
+ result = {
142
+ type: base_1.SpvWithdrawalStateType.FRONTED,
143
+ txId: event.txHash,
144
+ owner: (0, Utils_1.toHex)(event.params.owner),
145
+ vaultId: (0, Utils_1.toBigInt)(event.params.vault_id),
146
+ recipient: (0, Utils_1.toHex)(event.params.recipient),
147
+ fronter: (0, Utils_1.toHex)(event.params.fronting_address)
148
+ };
149
+ break;
150
+ case "spv_swap_vault::events::Claimed":
151
+ result = {
152
+ type: base_1.SpvWithdrawalStateType.CLAIMED,
153
+ txId: event.txHash,
154
+ owner: (0, Utils_1.toHex)(event.params.owner),
155
+ vaultId: (0, Utils_1.toBigInt)(event.params.vault_id),
156
+ recipient: (0, Utils_1.toHex)(event.params.recipient),
157
+ claimer: (0, Utils_1.toHex)(event.params.caller),
158
+ fronter: (0, Utils_1.toHex)(event.params.fronting_address)
159
+ };
160
+ break;
161
+ case "spv_swap_vault::events::Closed":
162
+ result = {
163
+ type: base_1.SpvWithdrawalStateType.CLOSED,
164
+ txId: event.txHash,
165
+ owner: (0, Utils_1.toHex)(event.params.owner),
166
+ vaultId: (0, Utils_1.toBigInt)(event.params.vault_id),
167
+ error: (0, Utils_1.bigNumberishToBuffer)(event.params.error).toString()
168
+ };
169
+ break;
170
+ }
171
+ });
172
+ return result;
173
+ }
174
+ getWithdrawalData(btcTx) {
175
+ return Promise.resolve(new StarknetSpvWithdrawalData_1.StarknetSpvWithdrawalData(btcTx));
176
+ }
177
+ //OP_RETURN data encoding/decoding
178
+ fromOpReturnData(data) {
179
+ return StarknetSpvVaultContract.fromOpReturnData(data);
180
+ }
181
+ static fromOpReturnData(data) {
182
+ let rawAmount0 = 0n;
183
+ let rawAmount1 = 0n;
184
+ let executionHash = null;
185
+ if (data.length === 40) {
186
+ rawAmount0 = data.readBigInt64LE(32).valueOf();
187
+ }
188
+ else if (data.length === 48) {
189
+ rawAmount0 = data.readBigInt64LE(32).valueOf();
190
+ rawAmount1 = data.readBigInt64LE(40).valueOf();
191
+ }
192
+ else if (data.length === 72) {
193
+ rawAmount0 = data.readBigInt64LE(32).valueOf();
194
+ executionHash = data.slice(40, 72).toString("hex");
195
+ }
196
+ else if (data.length === 80) {
197
+ rawAmount0 = data.readBigInt64LE(32).valueOf();
198
+ rawAmount1 = data.readBigInt64LE(40).valueOf();
199
+ executionHash = data.slice(48, 80).toString("hex");
200
+ }
201
+ else {
202
+ throw new Error("Invalid OP_RETURN data length!");
203
+ }
204
+ if (executionHash != null) {
205
+ const executionHashValue = BigInt("0x" + executionHash);
206
+ if (executionHashValue >= STARK_PRIME_MOD)
207
+ throw new Error("Execution hash not in range of starknet prime");
208
+ }
209
+ const recipient = "0x" + data.slice(0, 32).toString("hex");
210
+ if (!StarknetAddresses_1.StarknetAddresses.isValidAddress(recipient))
211
+ throw new Error("Invalid recipient specified");
212
+ return { executionHash, rawAmounts: [rawAmount0, rawAmount1], recipient };
213
+ }
214
+ toOpReturnData(recipient, rawAmounts, executionHash) {
215
+ return StarknetSpvVaultContract.toOpReturnData(recipient, rawAmounts, executionHash);
216
+ }
217
+ static toOpReturnData(recipient, rawAmounts, executionHash) {
218
+ if (!StarknetAddresses_1.StarknetAddresses.isValidAddress(recipient))
219
+ throw new Error("Invalid recipient specified");
220
+ if (rawAmounts.length < 1)
221
+ throw new Error("At least 1 amount needs to be specified");
222
+ if (rawAmounts.length > 2)
223
+ throw new Error("At most 2 amounts need to be specified");
224
+ rawAmounts.forEach(val => {
225
+ if (val < 0n)
226
+ throw new Error("Negative raw amount specified");
227
+ if (val >= 2n ** 64n)
228
+ throw new Error("Raw amount overflow");
229
+ });
230
+ if (executionHash != null) {
231
+ const executionHashValue = (0, Utils_1.toBigInt)(executionHash);
232
+ if (executionHashValue < 0n)
233
+ throw new Error("Execution hash negative");
234
+ if (executionHashValue >= STARK_PRIME_MOD)
235
+ throw new Error("Execution hash not in range of starknet prime");
236
+ }
237
+ const recipientBuffer = buffer_1.Buffer.from(recipient.substring(2).padStart(64, "0"), "hex");
238
+ const amount0Buffer = buffer_1.Buffer.from(rawAmounts[0].toString(16).padStart(16, "0"), "hex");
239
+ const amount1Buffer = rawAmounts[1] == null || rawAmounts[1] === 0n ? buffer_1.Buffer.alloc(0) : buffer_1.Buffer.from(rawAmounts[1].toString(16).padStart(16, "0"), "hex");
240
+ const executionHashBuffer = executionHash == null ? buffer_1.Buffer.alloc(0) : buffer_1.Buffer.from(executionHash.substring(2).padStart(64, "0"), "hex");
241
+ return buffer_1.Buffer.concat([
242
+ recipientBuffer,
243
+ amount0Buffer.reverse(),
244
+ amount1Buffer.reverse(),
245
+ executionHashBuffer
246
+ ]);
247
+ }
248
+ //Actions
249
+ async claim(signer, vault, txs, synchronizer, initAta, txOptions) {
250
+ const result = await this.txsClaim(signer.getAddress(), vault, txs, synchronizer, initAta, txOptions?.feeRate);
251
+ const [signature] = await this.Chain.sendAndConfirm(signer, result, txOptions?.waitForConfirmation, txOptions?.abortSignal);
252
+ return signature;
253
+ }
254
+ async deposit(signer, vault, rawAmounts, txOptions) {
255
+ const result = await this.txsDeposit(signer.getAddress(), vault, rawAmounts, txOptions?.feeRate);
256
+ const [signature] = await this.Chain.sendAndConfirm(signer, result, txOptions?.waitForConfirmation, txOptions?.abortSignal);
257
+ return signature;
258
+ }
259
+ async frontLiquidity(signer, vault, realWithdrawalTx, withdrawSequence, txOptions) {
260
+ const result = await this.txsFrontLiquidity(signer.getAddress(), vault, realWithdrawalTx, withdrawSequence, txOptions?.feeRate);
261
+ const [signature] = await this.Chain.sendAndConfirm(signer, result, txOptions?.waitForConfirmation, txOptions?.abortSignal);
262
+ return signature;
263
+ }
264
+ async open(signer, vault, txOptions) {
265
+ const result = await this.txsOpen(signer.getAddress(), vault, txOptions?.feeRate);
266
+ const [signature] = await this.Chain.sendAndConfirm(signer, result, txOptions?.waitForConfirmation, txOptions?.abortSignal);
267
+ return signature;
268
+ }
269
+ //Transactions
270
+ async txsClaim(signer, vault, txs, synchronizer, initAta, feeRate) {
271
+ if (!vault.isOpened())
272
+ throw new Error("Cannot claim from a closed vault!");
273
+ feeRate ?? (feeRate = await this.Chain.Fees.getFeeRate());
274
+ const txsWithMerkleProofs = [];
275
+ for (let tx of txs) {
276
+ const merkleProof = await this.bitcoinRpc.getMerkleProof(tx.tx.btcTx.txid, tx.tx.btcTx.blockhash);
277
+ this.logger.debug("txsClaim(): merkle proof computed: ", merkleProof);
278
+ txsWithMerkleProofs.push({
279
+ ...merkleProof,
280
+ ...tx
281
+ });
282
+ }
283
+ const starknetTxs = [];
284
+ const storedHeaders = await StarknetBtcRelay_1.StarknetBtcRelay.getCommitedHeadersAndSynchronize(signer, this.btcRelay, txsWithMerkleProofs.filter(tx => tx.storedHeader == null).map(tx => {
285
+ return {
286
+ blockhash: tx.tx.btcTx.blockhash,
287
+ blockheight: tx.blockheight,
288
+ requiredConfirmations: vault.getConfirmations()
289
+ };
290
+ }), starknetTxs, synchronizer, feeRate);
291
+ if (storedHeaders == null)
292
+ throw new Error("Cannot fetch committed header!");
293
+ const actions = txsWithMerkleProofs.map(tx => {
294
+ return this.Claim(signer, vault, tx.tx, tx.storedHeader ?? storedHeaders[tx.tx.btcTx.blockhash], tx.merkle, tx.pos);
295
+ });
296
+ let starknetAction = new StarknetAction_1.StarknetAction(signer, this.Chain);
297
+ for (let action of actions) {
298
+ starknetAction.add(action);
299
+ if (starknetAction.ixsLength() >= this.maxClaimsPerTx) {
300
+ await starknetAction.addToTxs(starknetTxs, feeRate);
301
+ starknetAction = new StarknetAction_1.StarknetAction(signer, this.Chain);
302
+ }
303
+ }
304
+ if (starknetAction.ixsLength() > 0) {
305
+ await starknetAction.addToTxs(starknetTxs, feeRate);
306
+ }
307
+ this.logger.debug("txsClaim(): " + starknetTxs.length + " claim TXs created claiming " + txs.length + " txs, owner: " + vault.getOwner() +
308
+ " vaultId: " + vault.getVaultId().toString(10));
309
+ return starknetTxs;
310
+ }
311
+ async txsDeposit(signer, vault, rawAmounts, feeRate) {
312
+ if (!vault.isOpened())
313
+ throw new Error("Cannot deposit to a closed vault!");
314
+ //Approve first
315
+ const vaultTokens = vault.getTokenData();
316
+ const action = new StarknetAction_1.StarknetAction(signer, this.Chain);
317
+ let realAmount0 = 0n;
318
+ let realAmount1 = 0n;
319
+ if (rawAmounts[0] != null && rawAmounts[0] !== 0n) {
320
+ realAmount0 = rawAmounts[0] * vaultTokens[0].multiplier;
321
+ action.add(this.Chain.Tokens.Approve(signer, this.contract.address, vaultTokens[0].token, realAmount0));
322
+ }
323
+ if (rawAmounts[1] != null && rawAmounts[1] !== 0n) {
324
+ realAmount1 = rawAmounts[1] * vaultTokens[1].multiplier;
325
+ action.add(this.Chain.Tokens.Approve(signer, this.contract.address, vaultTokens[1].token, realAmount1));
326
+ }
327
+ action.add(this.Deposit(signer, vault, rawAmounts));
328
+ feeRate ?? (feeRate = await this.Chain.Fees.getFeeRate());
329
+ this.logger.debug("txsDeposit(): deposit TX created," +
330
+ " token0: " + vaultTokens[0].token + " rawAmount0: " + rawAmounts[0].toString(10) + " amount0: " + realAmount0.toString(10) +
331
+ " token1: " + vaultTokens[1].token + " rawAmount1: " + (rawAmounts[1] ?? 0n).toString(10) + " amount1: " + realAmount1.toString(10));
332
+ return [await action.tx(feeRate)];
333
+ }
334
+ async txsFrontLiquidity(signer, vault, realWithdrawalTx, withdrawSequence, feeRate) {
335
+ if (!vault.isOpened())
336
+ throw new Error("Cannot front on a closed vault!");
337
+ //Approve first
338
+ const vaultTokens = vault.getTokenData();
339
+ const action = new StarknetAction_1.StarknetAction(signer, this.Chain);
340
+ const rawAmounts = realWithdrawalTx.getFrontingAmount();
341
+ let realAmount0 = 0n;
342
+ let realAmount1 = 0n;
343
+ if (rawAmounts[0] != null && rawAmounts[0] !== 0n) {
344
+ realAmount0 = rawAmounts[0] * vaultTokens[0].multiplier;
345
+ action.add(this.Chain.Tokens.Approve(signer, this.contract.address, vaultTokens[0].token, realAmount0));
346
+ }
347
+ if (rawAmounts[1] != null && rawAmounts[1] !== 0n) {
348
+ realAmount1 = rawAmounts[1] * vaultTokens[1].multiplier;
349
+ action.add(this.Chain.Tokens.Approve(signer, this.contract.address, vaultTokens[1].token, realAmount1));
350
+ }
351
+ action.add(this.Front(signer, vault, realWithdrawalTx, withdrawSequence));
352
+ feeRate ?? (feeRate = await this.Chain.Fees.getFeeRate());
353
+ this.logger.debug("txsFrontLiquidity(): front TX created," +
354
+ " token0: " + vaultTokens[0].token + " rawAmount0: " + rawAmounts[0].toString(10) + " amount0: " + realAmount0.toString(10) +
355
+ " token1: " + vaultTokens[1].token + " rawAmount1: " + (rawAmounts[1] ?? 0n).toString(10) + " amount1: " + realAmount1.toString(10));
356
+ return [await action.tx(feeRate)];
357
+ }
358
+ async txsOpen(signer, vault, feeRate) {
359
+ if (vault.isOpened())
360
+ throw new Error("Cannot open an already opened vault!");
361
+ const action = this.Open(signer, vault);
362
+ feeRate ?? (feeRate = await this.Chain.Fees.getFeeRate());
363
+ this.logger.debug("txsOpen(): open TX created, owner: " + vault.getOwner() +
364
+ " vaultId: " + vault.getVaultId().toString(10));
365
+ return [await action.tx(feeRate)];
366
+ }
367
+ async getClaimFee(signer, vault, withdrawalData, feeRate) {
368
+ feeRate ?? (feeRate = await this.Chain.Fees.getFeeRate());
369
+ return StarknetFees_1.StarknetFees.getGasFee(StarknetSpvVaultContract.GasCosts.CLAIM, feeRate);
370
+ }
371
+ async getFrontFee(signer, vault, withdrawalData, feeRate) {
372
+ feeRate ?? (feeRate = await this.Chain.Fees.getFeeRate());
373
+ return StarknetFees_1.StarknetFees.getGasFee(StarknetSpvVaultContract.GasCosts.FRONT, feeRate);
374
+ }
375
+ }
376
+ exports.StarknetSpvVaultContract = StarknetSpvVaultContract;
377
+ StarknetSpvVaultContract.GasCosts = {
378
+ DEPOSIT: { l1DataGas: 400, l2Gas: 4000000, l1Gas: 0 },
379
+ OPEN: { l1DataGas: 1200, l2Gas: 3200000, l1Gas: 0 },
380
+ FRONT: { l1DataGas: 800, l2Gas: 12000000, l1Gas: 0 },
381
+ CLAIM: { l1DataGas: 1000, l2Gas: 400000000, l1Gas: 0 }
382
+ };