@atomiqlabs/chain-starknet 1.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/LICENSE +201 -0
  2. package/dist/get_serialized_block.d.ts +1 -0
  3. package/dist/get_serialized_block.js +28 -0
  4. package/dist/index.d.ts +34 -0
  5. package/dist/index.js +50 -0
  6. package/dist/starknet/StarknetChainType.d.ts +9 -0
  7. package/dist/starknet/StarknetChainType.js +2 -0
  8. package/dist/starknet/StarknetInitializer.d.ts +18 -0
  9. package/dist/starknet/StarknetInitializer.js +49 -0
  10. package/dist/starknet/base/StarknetAction.d.ts +27 -0
  11. package/dist/starknet/base/StarknetAction.js +73 -0
  12. package/dist/starknet/base/StarknetBase.d.ts +34 -0
  13. package/dist/starknet/base/StarknetBase.js +29 -0
  14. package/dist/starknet/base/StarknetModule.d.ts +14 -0
  15. package/dist/starknet/base/StarknetModule.js +13 -0
  16. package/dist/starknet/base/modules/ERC20Abi.d.ts +755 -0
  17. package/dist/starknet/base/modules/ERC20Abi.js +1032 -0
  18. package/dist/starknet/base/modules/StarknetAccounts.d.ts +6 -0
  19. package/dist/starknet/base/modules/StarknetAccounts.js +24 -0
  20. package/dist/starknet/base/modules/StarknetAddresses.d.ts +9 -0
  21. package/dist/starknet/base/modules/StarknetAddresses.js +26 -0
  22. package/dist/starknet/base/modules/StarknetBlocks.d.ts +19 -0
  23. package/dist/starknet/base/modules/StarknetBlocks.js +49 -0
  24. package/dist/starknet/base/modules/StarknetEvents.d.ts +44 -0
  25. package/dist/starknet/base/modules/StarknetEvents.js +88 -0
  26. package/dist/starknet/base/modules/StarknetFees.d.ts +55 -0
  27. package/dist/starknet/base/modules/StarknetFees.js +102 -0
  28. package/dist/starknet/base/modules/StarknetSignatures.d.ts +30 -0
  29. package/dist/starknet/base/modules/StarknetSignatures.js +71 -0
  30. package/dist/starknet/base/modules/StarknetTokens.d.ts +67 -0
  31. package/dist/starknet/base/modules/StarknetTokens.js +97 -0
  32. package/dist/starknet/base/modules/StarknetTransactions.d.ts +87 -0
  33. package/dist/starknet/base/modules/StarknetTransactions.js +226 -0
  34. package/dist/starknet/btcrelay/BtcRelayAbi.d.ts +250 -0
  35. package/dist/starknet/btcrelay/BtcRelayAbi.js +341 -0
  36. package/dist/starknet/btcrelay/StarknetBtcRelay.d.ts +166 -0
  37. package/dist/starknet/btcrelay/StarknetBtcRelay.js +323 -0
  38. package/dist/starknet/btcrelay/headers/StarknetBtcHeader.d.ts +32 -0
  39. package/dist/starknet/btcrelay/headers/StarknetBtcHeader.js +74 -0
  40. package/dist/starknet/btcrelay/headers/StarknetBtcStoredHeader.d.ts +52 -0
  41. package/dist/starknet/btcrelay/headers/StarknetBtcStoredHeader.js +113 -0
  42. package/dist/starknet/contract/StarknetContractBase.d.ts +13 -0
  43. package/dist/starknet/contract/StarknetContractBase.js +18 -0
  44. package/dist/starknet/contract/modules/StarknetContractEvents.d.ts +40 -0
  45. package/dist/starknet/contract/modules/StarknetContractEvents.js +77 -0
  46. package/dist/starknet/events/StarknetChainEvents.d.ts +19 -0
  47. package/dist/starknet/events/StarknetChainEvents.js +51 -0
  48. package/dist/starknet/events/StarknetChainEventsBrowser.d.ts +73 -0
  49. package/dist/starknet/events/StarknetChainEventsBrowser.js +210 -0
  50. package/dist/starknet/swaps/EscrowManagerAbi.d.ts +445 -0
  51. package/dist/starknet/swaps/EscrowManagerAbi.js +601 -0
  52. package/dist/starknet/swaps/StarknetSwapContract.d.ts +215 -0
  53. package/dist/starknet/swaps/StarknetSwapContract.js +452 -0
  54. package/dist/starknet/swaps/StarknetSwapData.d.ts +74 -0
  55. package/dist/starknet/swaps/StarknetSwapData.js +316 -0
  56. package/dist/starknet/swaps/StarknetSwapModule.d.ts +9 -0
  57. package/dist/starknet/swaps/StarknetSwapModule.js +12 -0
  58. package/dist/starknet/swaps/handlers/IHandler.d.ts +13 -0
  59. package/dist/starknet/swaps/handlers/IHandler.js +2 -0
  60. package/dist/starknet/swaps/handlers/claim/ClaimHandlers.d.ts +13 -0
  61. package/dist/starknet/swaps/handlers/claim/ClaimHandlers.js +13 -0
  62. package/dist/starknet/swaps/handlers/claim/HashlockClaimHandler.d.ts +22 -0
  63. package/dist/starknet/swaps/handlers/claim/HashlockClaimHandler.js +44 -0
  64. package/dist/starknet/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.d.ts +25 -0
  65. package/dist/starknet/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.js +48 -0
  66. package/dist/starknet/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.d.ts +26 -0
  67. package/dist/starknet/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.js +40 -0
  68. package/dist/starknet/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.d.ts +20 -0
  69. package/dist/starknet/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.js +29 -0
  70. package/dist/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.d.ts +64 -0
  71. package/dist/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.js +86 -0
  72. package/dist/starknet/swaps/handlers/refund/TimelockRefundHandler.d.ts +17 -0
  73. package/dist/starknet/swaps/handlers/refund/TimelockRefundHandler.js +27 -0
  74. package/dist/starknet/swaps/modules/StarknetLpVault.d.ts +69 -0
  75. package/dist/starknet/swaps/modules/StarknetLpVault.js +122 -0
  76. package/dist/starknet/swaps/modules/StarknetSwapClaim.d.ts +53 -0
  77. package/dist/starknet/swaps/modules/StarknetSwapClaim.js +100 -0
  78. package/dist/starknet/swaps/modules/StarknetSwapInit.d.ts +84 -0
  79. package/dist/starknet/swaps/modules/StarknetSwapInit.js +164 -0
  80. package/dist/starknet/swaps/modules/StarknetSwapRefund.d.ts +64 -0
  81. package/dist/starknet/swaps/modules/StarknetSwapRefund.js +131 -0
  82. package/dist/starknet/swaps/modules/SwapClaim.d.ts +54 -0
  83. package/dist/starknet/swaps/modules/SwapClaim.js +115 -0
  84. package/dist/starknet/swaps/modules/SwapInit.d.ts +79 -0
  85. package/dist/starknet/swaps/modules/SwapInit.js +174 -0
  86. package/dist/starknet/swaps/modules/SwapRefund.d.ts +63 -0
  87. package/dist/starknet/swaps/modules/SwapRefund.js +149 -0
  88. package/dist/starknet/wallet/StarknetKeypairWallet.d.ts +6 -0
  89. package/dist/starknet/wallet/StarknetKeypairWallet.js +26 -0
  90. package/dist/starknet/wallet/StarknetSigner.d.ts +12 -0
  91. package/dist/starknet/wallet/StarknetSigner.js +46 -0
  92. package/dist/utils/Utils.d.ts +38 -0
  93. package/dist/utils/Utils.js +255 -0
  94. package/package.json +39 -0
  95. package/src/index.ts +41 -0
  96. package/src/starknet/StarknetChainType.ts +20 -0
  97. package/src/starknet/StarknetInitializer.ts +75 -0
  98. package/src/starknet/base/StarknetAction.ts +90 -0
  99. package/src/starknet/base/StarknetBase.ts +56 -0
  100. package/src/starknet/base/StarknetModule.ts +20 -0
  101. package/src/starknet/base/modules/ERC20Abi.ts +1029 -0
  102. package/src/starknet/base/modules/StarknetAccounts.ts +26 -0
  103. package/src/starknet/base/modules/StarknetAddresses.ts +23 -0
  104. package/src/starknet/base/modules/StarknetBlocks.ts +59 -0
  105. package/src/starknet/base/modules/StarknetEvents.ts +105 -0
  106. package/src/starknet/base/modules/StarknetFees.ts +136 -0
  107. package/src/starknet/base/modules/StarknetSignatures.ts +91 -0
  108. package/src/starknet/base/modules/StarknetTokens.ts +116 -0
  109. package/src/starknet/base/modules/StarknetTransactions.ts +254 -0
  110. package/src/starknet/btcrelay/BtcRelayAbi.ts +338 -0
  111. package/src/starknet/btcrelay/StarknetBtcRelay.ts +415 -0
  112. package/src/starknet/btcrelay/headers/StarknetBtcHeader.ts +101 -0
  113. package/src/starknet/btcrelay/headers/StarknetBtcStoredHeader.ts +142 -0
  114. package/src/starknet/contract/StarknetContractBase.ts +29 -0
  115. package/src/starknet/contract/modules/StarknetContractEvents.ts +108 -0
  116. package/src/starknet/events/StarknetChainEvents.ts +63 -0
  117. package/src/starknet/events/StarknetChainEventsBrowser.ts +289 -0
  118. package/src/starknet/swaps/EscrowManagerAbi.ts +600 -0
  119. package/src/starknet/swaps/StarknetSwapContract.ts +694 -0
  120. package/src/starknet/swaps/StarknetSwapData.ts +441 -0
  121. package/src/starknet/swaps/StarknetSwapModule.ts +17 -0
  122. package/src/starknet/swaps/handlers/IHandler.ts +20 -0
  123. package/src/starknet/swaps/handlers/claim/ClaimHandlers.ts +23 -0
  124. package/src/starknet/swaps/handlers/claim/HashlockClaimHandler.ts +54 -0
  125. package/src/starknet/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.ts +73 -0
  126. package/src/starknet/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.ts +67 -0
  127. package/src/starknet/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.ts +49 -0
  128. package/src/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.ts +151 -0
  129. package/src/starknet/swaps/handlers/refund/TimelockRefundHandler.ts +39 -0
  130. package/src/starknet/swaps/modules/StarknetLpVault.ts +148 -0
  131. package/src/starknet/swaps/modules/StarknetSwapClaim.ts +142 -0
  132. package/src/starknet/swaps/modules/StarknetSwapInit.ts +226 -0
  133. package/src/starknet/swaps/modules/StarknetSwapRefund.ts +202 -0
  134. package/src/starknet/wallet/StarknetKeypairWallet.ts +34 -0
  135. package/src/starknet/wallet/StarknetSigner.ts +55 -0
  136. package/src/utils/Utils.ts +247 -0
@@ -0,0 +1,441 @@
1
+ import {SwapData, ChainSwapType} from "@atomiqlabs/base";
2
+ import {TimelockRefundHandler} from "./handlers/refund/TimelockRefundHandler";
3
+ import {BigNumberish, cairo, hash} from "starknet";
4
+ import {toBigInt, toHex} from "../../utils/Utils";
5
+ import {
6
+ StringToPrimitiveType
7
+ } from "abi-wan-kanabi/dist/kanabi";
8
+ import {EscrowManagerAbi} from "./EscrowManagerAbi";
9
+ import {IClaimHandler} from "./handlers/claim/ClaimHandlers";
10
+
11
+ const FLAG_PAY_OUT: bigint = 0x01n;
12
+ const FLAG_PAY_IN: bigint = 0x02n;
13
+ const FLAG_REPUTATION: bigint = 0x04n;
14
+
15
+ export type StarknetSwapDataType = StringToPrimitiveType<typeof EscrowManagerAbi, "escrow_manager::structs::escrow::EscrowData">;
16
+
17
+ type SerializedContractCall = {
18
+ address: string,
19
+ entrypoint: string,
20
+ calldata: string[]
21
+ };
22
+
23
+ function deserializeContractCalls(span: BigNumberish[]): SerializedContractCall[] {
24
+ const successActionsLen = Number(toBigInt(span.shift()));
25
+ const successActions: SerializedContractCall[] = [];
26
+ for(let i=0; i<successActionsLen; i++) {
27
+ const address = toHex(span.shift());
28
+ const entrypoint = toHex(span.shift());
29
+ const calldataLen = Number(toBigInt(span.shift()));
30
+ const calldata = span.splice(0, calldataLen).map(toHex);
31
+ successActions.push({
32
+ address,
33
+ entrypoint,
34
+ calldata
35
+ });
36
+ }
37
+ return successActions;
38
+ }
39
+
40
+ function serializeContractCalls(calls: SerializedContractCall[], span: BigNumberish[]): BigNumberish[] {
41
+ span.push(toHex(calls.length));
42
+ calls.forEach((call) => {
43
+ span.push(call.address);
44
+ span.push(call.entrypoint);
45
+ span.push(toHex(call.calldata.length));
46
+ span.push(...call.calldata);
47
+ });
48
+ return span;
49
+ }
50
+
51
+ export class StarknetSwapData extends SwapData {
52
+
53
+ static toFlags(value: number | bigint | string): {payOut: boolean, payIn: boolean, reputation: boolean, sequence: bigint} {
54
+ const val = toBigInt(value);
55
+ return {
56
+ sequence: val >> 64n,
57
+ payOut: (val & FLAG_PAY_OUT) === FLAG_PAY_OUT,
58
+ payIn: (val & FLAG_PAY_IN) === FLAG_PAY_IN,
59
+ reputation: (val & FLAG_REPUTATION) === FLAG_REPUTATION
60
+ }
61
+ }
62
+
63
+ private getFlags(): bigint {
64
+ return (this.sequence << 64n) +
65
+ (this.payOut ? FLAG_PAY_OUT : 0n) +
66
+ (this.payIn ? FLAG_PAY_IN : 0n) +
67
+ (this.reputation ? FLAG_REPUTATION : 0n);
68
+ }
69
+
70
+ offerer: string;
71
+ claimer: string;
72
+ token: string;
73
+
74
+ refundHandler: string;
75
+ claimHandler: string;
76
+
77
+ //Flags
78
+ payOut: boolean;
79
+ payIn: boolean;
80
+ reputation: boolean;
81
+ sequence: bigint;
82
+
83
+ claimData: string;
84
+ refundData: string;
85
+
86
+ amount: bigint;
87
+
88
+ feeToken: string;
89
+ securityDeposit: bigint;
90
+ claimerBounty: bigint;
91
+
92
+ successAction: SerializedContractCall[];
93
+
94
+ extraData: string;
95
+
96
+ kind: ChainSwapType;
97
+
98
+ constructor(
99
+ offerer: string,
100
+ claimer: string,
101
+ token: string,
102
+ refundHandler: string,
103
+ claimHandler: string,
104
+ payOut: boolean,
105
+ payIn: boolean,
106
+ reputation: boolean,
107
+ sequence: bigint,
108
+ claimData: string,
109
+ refundData: string,
110
+ amount: bigint,
111
+ feeToken: string,
112
+ securityDeposit: bigint,
113
+ claimerBounty: bigint,
114
+ kind: ChainSwapType,
115
+ extraData: string,
116
+ successAction: SerializedContractCall[]
117
+ );
118
+
119
+ constructor(data: any);
120
+
121
+ constructor(
122
+ offererOrData: string | any,
123
+ claimer?: string,
124
+ token?: string,
125
+ refundHandler?: string,
126
+ claimHandler?: string,
127
+ payOut?: boolean,
128
+ payIn?: boolean,
129
+ reputation?: boolean,
130
+ sequence?: bigint,
131
+ claimData?: string,
132
+ refundData?: string,
133
+ amount?: bigint,
134
+ feeToken?: string,
135
+ securityDeposit?: bigint,
136
+ claimerBounty?: bigint,
137
+ kind?: ChainSwapType,
138
+ extraData?: string,
139
+ successAction?: SerializedContractCall[]
140
+ ) {
141
+ super();
142
+ if(claimer!=null || token!=null || refundHandler!=null || claimHandler!=null ||
143
+ payOut!=null || payIn!=null || reputation!=null || sequence!=null || claimData!=null || refundData!=null ||
144
+ amount!=null || feeToken!=null || securityDeposit!=null || claimerBounty!=null) {
145
+ this.offerer = offererOrData;
146
+ this.claimer = claimer;
147
+ this.token = token;
148
+ this.refundHandler = refundHandler;
149
+ this.claimHandler = claimHandler;
150
+ this.payOut = payOut;
151
+ this.payIn = payIn;
152
+ this.reputation = reputation;
153
+ this.sequence = sequence;
154
+ this.claimData = claimData;
155
+ this.refundData = refundData;
156
+ this.amount = amount;
157
+ this.feeToken = feeToken;
158
+ this.securityDeposit = securityDeposit;
159
+ this.claimerBounty = claimerBounty;
160
+ this.kind = kind;
161
+ this.extraData = extraData;
162
+ this.successAction = successAction;
163
+ } else {
164
+ this.offerer = offererOrData.offerer;
165
+ this.claimer = offererOrData.claimer;
166
+ this.token = offererOrData.token;
167
+ this.refundHandler = offererOrData.refundHandler;
168
+ this.claimHandler = offererOrData.claimHandler;
169
+ this.payOut = offererOrData.payOut;
170
+ this.payIn = offererOrData.payIn;
171
+ this.reputation = offererOrData.reputation;
172
+ this.sequence = offererOrData.sequence==null ? null : BigInt(offererOrData.sequence);
173
+ this.claimData = offererOrData.claimData;
174
+ this.refundData = offererOrData.refundData;
175
+ this.amount = offererOrData.amount==null ? null : BigInt(offererOrData.amount);
176
+ this.feeToken = offererOrData.feeToken;
177
+ this.securityDeposit = offererOrData.securityDeposit==null ? null : BigInt(offererOrData.securityDeposit);
178
+ this.claimerBounty = offererOrData.claimerBounty==null ? null : BigInt(offererOrData.claimerBounty);
179
+ this.kind = offererOrData.kind;
180
+ this.extraData = offererOrData.extraData;
181
+ this.successAction = offererOrData.successAction;
182
+ }
183
+ //For now we disallow usage of success actions
184
+ if(this.successAction.length>0) throw new Error("Success actions are not supported yet!");
185
+ }
186
+
187
+ getOfferer(): string {
188
+ return this.offerer;
189
+ }
190
+
191
+ setOfferer(newOfferer: string) {
192
+ this.offerer = newOfferer;
193
+ this.payIn = true;
194
+ }
195
+
196
+ getClaimer(): string {
197
+ return this.claimer;
198
+ }
199
+
200
+ setClaimer(newClaimer: string) {
201
+ this.claimer = newClaimer;
202
+ this.payIn = false;
203
+ this.payOut = true;
204
+ this.reputation = false;
205
+ }
206
+
207
+ serialize(): any {
208
+ return {
209
+ type: "strk",
210
+ offerer: this.offerer,
211
+ claimer: this.claimer,
212
+ token: this.token,
213
+ refundHandler: this.refundHandler,
214
+ claimHandler: this.claimHandler,
215
+ payOut: this.payOut,
216
+ payIn: this.payIn,
217
+ reputation: this.reputation,
218
+ sequence: this.sequence==null ? null : this.sequence.toString(10),
219
+ claimData: this.claimData,
220
+ refundData: this.refundData,
221
+ amount: this.amount==null ? null : this.amount.toString(10),
222
+ feeToken: this.feeToken,
223
+ securityDeposit: this.securityDeposit==null ? null : this.securityDeposit.toString(10),
224
+ claimerBounty: this.claimerBounty==null ? null : this.claimerBounty.toString(10),
225
+ kind: this.kind,
226
+ extraData: this.extraData,
227
+ successAction: this.successAction
228
+ }
229
+ }
230
+
231
+ getAmount(): bigint {
232
+ return this.amount;
233
+ }
234
+
235
+ getToken(): string {
236
+ return this.token;
237
+ }
238
+
239
+ isToken(token: string): boolean {
240
+ return this.token.toLowerCase()===token.toLowerCase();
241
+ }
242
+
243
+ getType(): ChainSwapType {
244
+ return this.kind;
245
+ }
246
+
247
+ getExpiry(): bigint {
248
+ return TimelockRefundHandler.getExpiry(this);
249
+ }
250
+
251
+ isPayIn(): boolean {
252
+ return this.payIn;
253
+ }
254
+
255
+ isPayOut(): boolean {
256
+ return this.payOut;
257
+ }
258
+
259
+ getEscrowHash(): string {
260
+ const amountValue = cairo.uint256("0x"+this.amount.toString(16));
261
+ const securityDepositValue = cairo.uint256("0x"+this.securityDeposit.toString(16));
262
+ const claimerBountyValue = cairo.uint256("0x"+this.claimerBounty.toString(16));
263
+ let escrowHash = hash.computePoseidonHashOnElements([
264
+ this.offerer,
265
+ this.claimer,
266
+ this.token,
267
+ this.refundHandler,
268
+ this.claimHandler,
269
+ this.getFlags(),
270
+ this.claimData,
271
+ this.refundData,
272
+ amountValue.low,
273
+ amountValue.high,
274
+ this.feeToken,
275
+ securityDepositValue.low,
276
+ securityDepositValue.high,
277
+ claimerBountyValue.low,
278
+ claimerBountyValue.high,
279
+ ...serializeContractCalls(this.successAction, []).slice(1) //Remove length prefix
280
+ ]);
281
+ if(escrowHash.startsWith("0x")) escrowHash = escrowHash.slice(2);
282
+ return escrowHash.padStart(64, "0");
283
+ }
284
+
285
+ getClaimHash(): string {
286
+ let hash = this.claimData;
287
+ if(hash.startsWith("0x")) hash = hash.slice(2);
288
+ return hash.padStart(64, "0");
289
+ }
290
+
291
+ getSequence(): bigint {
292
+ return this.sequence;
293
+ }
294
+
295
+ getConfirmationsHint(): number {
296
+ if(this.extraData==null) return null;
297
+ if(this.extraData.length!=84) return null;
298
+ return parseInt(this.extraData.slice(80), 16);
299
+ }
300
+
301
+ getNonceHint(): bigint {
302
+ if(this.extraData==null) return null;
303
+ if(this.extraData.length!=84) return null;
304
+ return BigInt("0x"+this.extraData.slice(64, 80));
305
+ }
306
+
307
+ getTxoHashHint(): string {
308
+ if(this.extraData==null) return null;
309
+ if(this.extraData.length!=84) return null;
310
+ return this.extraData.slice(0, 64);
311
+ }
312
+
313
+ getExtraData(): string {
314
+ return this.extraData;
315
+ }
316
+
317
+ setExtraData(extraData: string): void {
318
+ this.extraData = extraData;
319
+ }
320
+
321
+ getSecurityDeposit() {
322
+ return this.securityDeposit;
323
+ }
324
+
325
+ getClaimerBounty() {
326
+ return this.claimerBounty;
327
+ }
328
+
329
+ getTotalDeposit() {
330
+ return this.claimerBounty < this.securityDeposit ? this.securityDeposit : this.claimerBounty;
331
+ }
332
+
333
+ getDepositToken() {
334
+ return this.feeToken;
335
+ }
336
+
337
+ isDepositToken(token: string): boolean {
338
+ if(!token.startsWith("0x")) token = "0x"+token;
339
+ return toHex(this.feeToken)===toHex(token);
340
+ }
341
+
342
+ isClaimer(address: string) {
343
+ if(!address.startsWith("0x")) address = "0x"+address;
344
+ return toHex(this.claimer)===toHex(address);
345
+ }
346
+
347
+ isOfferer(address: string) {
348
+ if(!address.startsWith("0x")) address = "0x"+address;
349
+ return toHex(this.offerer)===toHex(address);
350
+ }
351
+
352
+ isRefundHandler(address: string): boolean {
353
+ if(!address.startsWith("0x")) address = "0x"+address;
354
+ return toHex(this.refundHandler)===toHex(address);
355
+ }
356
+
357
+ isClaimHandler(address: string): boolean {
358
+ if(!address.startsWith("0x")) address = "0x"+address;
359
+ return toHex(this.claimHandler)===toHex(address);
360
+ }
361
+
362
+ isClaimData(data: string): boolean {
363
+ if(!data.startsWith("0x")) data = "0x"+data;
364
+ return toHex(this.claimData)===toHex(data);
365
+ }
366
+
367
+ equals(other: StarknetSwapData): boolean {
368
+ return other.offerer.toLowerCase()===this.offerer.toLowerCase() &&
369
+ other.claimer.toLowerCase()===this.claimer.toLowerCase() &&
370
+ other.token.toLowerCase()===this.token.toLowerCase() &&
371
+ other.refundHandler.toLowerCase()===this.refundHandler.toLowerCase() &&
372
+ other.claimHandler.toLowerCase()===this.claimHandler.toLowerCase() &&
373
+ other.payIn===this.payIn &&
374
+ other.payOut===this.payOut &&
375
+ other.reputation===this.reputation &&
376
+ this.sequence === other.sequence &&
377
+ other.claimData.toLowerCase()===this.claimData.toLowerCase() &&
378
+ other.refundData.toLowerCase()===this.refundData.toLowerCase() &&
379
+ other.amount === this.amount &&
380
+ other.securityDeposit === this.securityDeposit &&
381
+ other.claimerBounty === this.claimerBounty
382
+ }
383
+
384
+ toEscrowStruct(): StarknetSwapDataType {
385
+ return {
386
+ offerer: this.offerer,
387
+ claimer: this.claimer,
388
+ token: this.token,
389
+ refund_handler: this.refundHandler,
390
+ claim_handler: this.claimHandler,
391
+ flags: this.getFlags(),
392
+ claim_data: this.claimData,
393
+ refund_data: this.refundData,
394
+ amount: cairo.uint256(toBigInt(this.amount)),
395
+ fee_token: this.feeToken,
396
+ security_deposit: cairo.uint256(toBigInt(this.securityDeposit)),
397
+ claimer_bounty: cairo.uint256(toBigInt(this.claimerBounty)),
398
+ success_action: this.successAction
399
+ }
400
+ }
401
+
402
+ static fromSerializedFeltArray(span: BigNumberish[], claimHandlerImpl: IClaimHandler<any, any>) {
403
+ const offerer = toHex(span.shift());
404
+ const claimer = toHex(span.shift());
405
+ const token = toHex(span.shift());
406
+ const refundHandler = toHex(span.shift());
407
+ const claimHandler = toHex(span.shift());
408
+ const {payOut, payIn, reputation, sequence} = StarknetSwapData.toFlags(span.shift());
409
+ const claimData = toHex(span.shift());
410
+ const refundData = toHex(span.shift());
411
+ const amount = toBigInt({low: span.shift(), high: span.shift()});
412
+ const feeToken = toHex(span.shift());
413
+ const securityDeposit = toBigInt({low: span.shift(), high: span.shift()});
414
+ const claimerBounty = toBigInt({low: span.shift(), high: span.shift()});
415
+ const successActions: SerializedContractCall[] = deserializeContractCalls(span)
416
+
417
+ return new StarknetSwapData(
418
+ offerer,
419
+ claimer,
420
+ token,
421
+ refundHandler,
422
+ claimHandler,
423
+ payOut,
424
+ payIn,
425
+ reputation,
426
+ sequence,
427
+ claimData,
428
+ refundData,
429
+ amount,
430
+ feeToken,
431
+ securityDeposit,
432
+ claimerBounty,
433
+ claimHandlerImpl.getType(),
434
+ null,
435
+ successActions
436
+ );
437
+ }
438
+
439
+ }
440
+
441
+ SwapData.deserializers["strk"] = StarknetSwapData;
@@ -0,0 +1,17 @@
1
+ import {StarknetModule} from "../base/StarknetModule";
2
+ import {StarknetSwapContract} from "./StarknetSwapContract";
3
+ import {TypedContractV2} from "starknet";
4
+ import {EscrowManagerAbi} from "./EscrowManagerAbi";
5
+
6
+ export class StarknetSwapModule extends StarknetModule {
7
+
8
+ readonly root: StarknetSwapContract;
9
+ readonly contract: TypedContractV2<typeof EscrowManagerAbi>;
10
+
11
+ constructor(root: StarknetSwapContract) {
12
+ super(root);
13
+ this.root = root;
14
+ this.contract = root.contract;
15
+ }
16
+
17
+ }
@@ -0,0 +1,20 @@
1
+ import {StarknetSwapData} from "../StarknetSwapData";
2
+ import {BigNumberish} from "starknet";
3
+ import {StarknetGas} from "../../base/StarknetAction";
4
+ import {StarknetTx} from "../../base/modules/StarknetTransactions";
5
+
6
+
7
+ export interface IHandler<TCommitmentData, TWitnessData> {
8
+
9
+ readonly address: string;
10
+
11
+ getCommitment(data: TCommitmentData): BigNumberish;
12
+
13
+ getWitness(signer: string, data: StarknetSwapData, witnessData: TWitnessData, feeRate?: string): Promise<{
14
+ initialTxns: StarknetTx[],
15
+ witness: BigNumberish[]
16
+ }>;
17
+
18
+ getGas(data: StarknetSwapData): StarknetGas;
19
+
20
+ }
@@ -0,0 +1,23 @@
1
+ import {HashlockClaimHandler} from "./HashlockClaimHandler";
2
+ import {ChainSwapType} from "@atomiqlabs/base";
3
+ import {StarknetGas} from "../../../base/StarknetAction";
4
+ import {IHandler} from "../IHandler";
5
+ import {BitcoinTxIdClaimHandler} from "./btc/BitcoinTxIdClaimHandler";
6
+ import {BitcoinOutputClaimHandler} from "./btc/BitcoinOutputClaimHandler";
7
+ import {BitcoinNoncedOutputClaimHandler} from "./btc/BitcoinNoncedOutputClaimHandler";
8
+ import {BigNumberish} from "starknet";
9
+
10
+ export interface IClaimHandler<C, W> extends IHandler<C, W> {
11
+ getType(): ChainSwapType;
12
+ parseWitnessResult(result: BigNumberish[]): string;
13
+ }
14
+
15
+ export type ClaimHandlerType = {gas: StarknetGas, type: ChainSwapType} & (new (address: string) => IClaimHandler<any, any>);
16
+
17
+ export const claimHandlersList: ClaimHandlerType[] = [
18
+ HashlockClaimHandler,
19
+ BitcoinTxIdClaimHandler,
20
+ BitcoinOutputClaimHandler,
21
+ BitcoinNoncedOutputClaimHandler
22
+ ];
23
+
@@ -0,0 +1,54 @@
1
+ import {StarknetSwapData} from "../../StarknetSwapData";
2
+ import {bufferToU32Array, toHex, u32ArrayToBuffer} from "../../../../utils/Utils";
3
+ import {BigNumberish, hash} from "starknet";
4
+ import {ChainSwapType} from "@atomiqlabs/base";
5
+ import {StarknetGas} from "../../../base/StarknetAction";
6
+ import {Buffer} from "buffer";
7
+ import * as createHash from "create-hash";
8
+ import {StarknetTx} from "../../../base/modules/StarknetTransactions";
9
+ import {IClaimHandler} from "./ClaimHandlers";
10
+
11
+ export class HashlockClaimHandler implements IClaimHandler<Buffer, string> {
12
+
13
+ public readonly address: string;
14
+ public static readonly type: ChainSwapType = ChainSwapType.HTLC;
15
+ public static readonly gas: StarknetGas = {l1: 750};
16
+
17
+ constructor(address: string) {
18
+ this.address = address;
19
+ }
20
+
21
+ getCommitment(data: Buffer): BigNumberish {
22
+ if(data.length!==32) throw new Error("Invalid swap hash");
23
+ return hash.computePoseidonHashOnElements(bufferToU32Array(data));
24
+ }
25
+
26
+ public getWitness(signer: string, data: StarknetSwapData, witnessData: string): Promise<{
27
+ initialTxns: StarknetTx[],
28
+ witness: BigNumberish[]
29
+ }> {
30
+ if(!data.isClaimHandler(this.address)) throw new Error("Invalid claim handler");
31
+ if(witnessData.length!==64) throw new Error("Invalid hash secret: string length");
32
+ const buffer = Buffer.from(witnessData, "hex");
33
+ if(buffer.length!==32) throw new Error("Invalid hash secret: buff length");
34
+
35
+ const witnessSha256 = createHash("sha256").update(buffer).digest()
36
+ if(!data.isClaimData(toHex(this.getCommitment(witnessSha256)))) throw new Error("Invalid hash secret: poseidon hash doesn't match");
37
+
38
+ const witnessArray = bufferToU32Array(buffer);
39
+ return Promise.resolve({initialTxns: [], witness: witnessArray});
40
+ }
41
+
42
+ getGas(): StarknetGas {
43
+ return HashlockClaimHandler.gas;
44
+ }
45
+
46
+ getType(): ChainSwapType {
47
+ return HashlockClaimHandler.type;
48
+ }
49
+
50
+ parseWitnessResult(result: BigNumberish[]): string {
51
+ return u32ArrayToBuffer(result).toString("hex");
52
+ }
53
+
54
+ }
@@ -0,0 +1,73 @@
1
+ import {StarknetSwapData} from "../../../StarknetSwapData";
2
+ import {StarknetGas} from "../../../../base/StarknetAction";
3
+ import {ChainSwapType} from "@atomiqlabs/base";
4
+ import {BigNumberish, hash} from "starknet";
5
+ import {StarknetTx} from "../../../../base/modules/StarknetTransactions";
6
+ import {bufferToByteArray, getLogger, poseidonHashRange, toBigInt} from "../../../../../utils/Utils";
7
+ import {BitcoinCommitmentData, IBitcoinClaimHandler} from "./IBitcoinClaimHandler";
8
+ import {BitcoinOutputWitnessData} from "./BitcoinOutputClaimHandler";
9
+ import {Transaction} from "@scure/btc-signer";
10
+ import {Buffer} from "buffer";
11
+
12
+ export type BitcoinNoncedOutputCommitmentData = {
13
+ output: Buffer,
14
+ amount: bigint,
15
+ nonce: bigint
16
+ };
17
+
18
+ const logger = getLogger("BitcoinNoncedOutputClaimHandler: ");
19
+
20
+ function getTransactionNonce(btcTx: Transaction): bigint {
21
+ const locktimeSub500M = BigInt(btcTx.lockTime - 500000000);
22
+ if(locktimeSub500M < 0n) throw new Error("Locktime too low!");
23
+ const nSequence = BigInt(btcTx.getInput(0).sequence);
24
+ return (locktimeSub500M << 24n) | (nSequence & 0x00FFFFFFn);
25
+ }
26
+
27
+ export class BitcoinNoncedOutputClaimHandler extends IBitcoinClaimHandler<BitcoinNoncedOutputCommitmentData, BitcoinOutputWitnessData> {
28
+
29
+ public static readonly type: ChainSwapType = ChainSwapType.CHAIN_NONCED;
30
+ public static readonly gas: StarknetGas = {l1: 20000};
31
+
32
+ protected serializeCommitment(data: BitcoinNoncedOutputCommitmentData & BitcoinCommitmentData): BigNumberish[] {
33
+ return [
34
+ hash.computePoseidonHashOnElements([toBigInt(data.nonce), toBigInt(data.amount), poseidonHashRange(data.output)]),
35
+ ...super.serializeCommitment(data)
36
+ ];
37
+ }
38
+
39
+ async getWitness(
40
+ signer: string,
41
+ swapData: StarknetSwapData,
42
+ witnessData: BitcoinOutputWitnessData,
43
+ feeRate?: string
44
+ ): Promise<{
45
+ initialTxns: StarknetTx[];
46
+ witness: BigNumberish[]
47
+ }> {
48
+ if(!swapData.isClaimHandler(this.address)) throw new Error("Invalid claim handler");
49
+
50
+ const parsedBtcTx = Transaction.fromRaw(Buffer.from(witnessData.tx.hex, "hex"));
51
+ const out = parsedBtcTx.getOutput(witnessData.vout);
52
+
53
+ const {initialTxns, witness} = await this._getWitness(signer, swapData, witnessData, {
54
+ output: Buffer.from(out.script),
55
+ amount: out.amount,
56
+ nonce: getTransactionNonce(parsedBtcTx)
57
+ });
58
+
59
+ witness.push(...bufferToByteArray(Buffer.from(witnessData.tx.hex, "hex")));
60
+ witness.push(BigInt(witnessData.vout));
61
+
62
+ return {initialTxns, witness};
63
+ }
64
+
65
+ getGas(data: StarknetSwapData): StarknetGas {
66
+ return BitcoinNoncedOutputClaimHandler.gas;
67
+ }
68
+
69
+ getType(): ChainSwapType {
70
+ return BitcoinNoncedOutputClaimHandler.type;
71
+ }
72
+
73
+ }
@@ -0,0 +1,67 @@
1
+ import {StarknetSwapData} from "../../../StarknetSwapData";
2
+ import {StarknetGas} from "../../../../base/StarknetAction";
3
+ import {ChainSwapType} from "@atomiqlabs/base";
4
+ import {BigNumberish, hash} from "starknet";
5
+ import {StarknetTx} from "../../../../base/modules/StarknetTransactions";
6
+ import {bufferToByteArray, getLogger, poseidonHashRange, toBigInt} from "../../../../../utils/Utils";
7
+ import {BitcoinCommitmentData, BitcoinWitnessData, IBitcoinClaimHandler} from "./IBitcoinClaimHandler";
8
+ import {Transaction} from "@scure/btc-signer";
9
+ import {Buffer} from "buffer";
10
+
11
+ export type BitcoinOutputCommitmentData = {
12
+ output: Buffer,
13
+ amount: bigint
14
+ };
15
+
16
+ export type BitcoinOutputWitnessData = BitcoinWitnessData & {
17
+ vout: number
18
+ };
19
+
20
+ const logger = getLogger("BitcoinOutputClaimHandler: ");
21
+
22
+ export class BitcoinOutputClaimHandler extends IBitcoinClaimHandler<BitcoinOutputCommitmentData, BitcoinOutputWitnessData> {
23
+
24
+ public static readonly type: ChainSwapType = ChainSwapType.CHAIN;
25
+ public static readonly gas: StarknetGas = {l1: 20000};
26
+
27
+ protected serializeCommitment(data: BitcoinOutputCommitmentData & BitcoinCommitmentData): BigNumberish[] {
28
+ return [
29
+ hash.computePoseidonHashOnElements([toBigInt(data.amount), poseidonHashRange(data.output)]),
30
+ ...super.serializeCommitment(data)
31
+ ];
32
+ }
33
+
34
+ async getWitness(
35
+ signer: string,
36
+ swapData: StarknetSwapData,
37
+ witnessData: BitcoinOutputWitnessData,
38
+ feeRate?: string
39
+ ): Promise<{
40
+ initialTxns: StarknetTx[];
41
+ witness: BigNumberish[]
42
+ }> {
43
+ if(!swapData.isClaimHandler(this.address)) throw new Error("Invalid claim handler");
44
+
45
+ const parsedBtcTx = Transaction.fromRaw(Buffer.from(witnessData.tx.hex, "hex"));
46
+ const out = parsedBtcTx.getOutput(witnessData.vout);
47
+
48
+ const {initialTxns, witness} = await this._getWitness(signer, swapData, witnessData, {
49
+ output: Buffer.from(out.script),
50
+ amount: out.amount
51
+ });
52
+
53
+ witness.push(...bufferToByteArray(Buffer.from(witnessData.tx.hex, "hex")));
54
+ witness.push(BigInt(witnessData.vout));
55
+
56
+ return {initialTxns, witness};
57
+ }
58
+
59
+ getGas(data: StarknetSwapData): StarknetGas {
60
+ return BitcoinOutputClaimHandler.gas;
61
+ }
62
+
63
+ getType(): ChainSwapType {
64
+ return BitcoinOutputClaimHandler.type;
65
+ }
66
+
67
+ }