@mimicprotocol/lib-ts 0.0.1-rc.9

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.
@@ -0,0 +1,419 @@
1
+ import { environment } from '../environment'
2
+ import { Token, TokenAmount } from '../tokens'
3
+ import { Address, BigInt, ChainId } from '../types'
4
+
5
+ import { Intent, IntentBuilder, OperationType } from './Intent'
6
+
7
+ /**
8
+ * Builder for creating Swap intents with token exchange operations.
9
+ * Supports both single-chain and cross-chain swaps with multiple input and output tokens.
10
+ */
11
+ export class SwapBuilder extends IntentBuilder {
12
+ private sourceChain: ChainId
13
+ private destinationChain: ChainId
14
+ private tokensIn: TokenIn[] = []
15
+ private tokensOut: TokenOut[] = []
16
+
17
+ /**
18
+ * Creates a SwapBuilder for a single-chain swap.
19
+ * @param chainId - The blockchain network identifier for both source and destination
20
+ * @returns A new SwapBuilder instance
21
+ */
22
+ static forChain(chainId: ChainId): SwapBuilder {
23
+ return new SwapBuilder(chainId, chainId)
24
+ }
25
+
26
+ /**
27
+ * Creates a SwapBuilder for a cross-chain swap.
28
+ * @param sourceChain - The source blockchain network identifier
29
+ * @param destinationChain - The destination blockchain network identifier
30
+ * @returns A new SwapBuilder instance
31
+ */
32
+ static forChains(sourceChain: ChainId, destinationChain: ChainId): SwapBuilder {
33
+ return new SwapBuilder(sourceChain, destinationChain)
34
+ }
35
+
36
+ /**
37
+ * Creates a new SwapBuilder instance.
38
+ * @param sourceChain - The source blockchain network identifier
39
+ * @param destinationChain - The destination blockchain network identifier
40
+ */
41
+ constructor(sourceChain: ChainId, destinationChain: ChainId) {
42
+ super()
43
+ this.sourceChain = sourceChain
44
+ this.destinationChain = destinationChain
45
+ }
46
+
47
+ /**
48
+ * Adds an input token to the swap.
49
+ * @param tokenIn - The token input configuration
50
+ * @returns This SwapBuilder instance for method chaining
51
+ */
52
+ addTokenIn(tokenIn: TokenIn): SwapBuilder {
53
+ this.tokensIn.push(tokenIn)
54
+ return this
55
+ }
56
+
57
+ /**
58
+ * Adds multiple input tokens to the swap.
59
+ * @param tokensIn - Array of token input configurations
60
+ * @returns This SwapBuilder instance for method chaining
61
+ */
62
+ addTokensIn(tokensIn: TokenIn[]): SwapBuilder {
63
+ for (let i = 0; i < tokensIn.length; i++) this.addTokenIn(tokensIn[i])
64
+ return this
65
+ }
66
+
67
+ /**
68
+ * Adds an output token to the swap.
69
+ * @param tokenOut - The token output configuration
70
+ * @returns This SwapBuilder instance for method chaining
71
+ */
72
+ addTokenOut(tokenOut: TokenOut): SwapBuilder {
73
+ this.tokensOut.push(tokenOut)
74
+ return this
75
+ }
76
+
77
+ /**
78
+ * Adds multiple output tokens to the swap.
79
+ * @param tokensOut - Array of token output configurations
80
+ * @returns This SwapBuilder instance for method chaining
81
+ */
82
+ addTokensOut(tokensOut: TokenOut[]): SwapBuilder {
83
+ for (let i = 0; i < tokensOut.length; i++) this.addTokenOut(tokensOut[i])
84
+ return this
85
+ }
86
+
87
+ /**
88
+ * Adds an input token from a TokenAmount.
89
+ * @param tokenAmount - The token amount to swap from (must be on source chain)
90
+ * @returns This SwapBuilder instance for method chaining
91
+ */
92
+ addTokenInFromTokenAmount(tokenAmount: TokenAmount): SwapBuilder {
93
+ if (tokenAmount.token.chainId !== this.sourceChain) throw new Error('Tokens in must be on the same chain')
94
+ return this.addTokenIn(TokenIn.fromTokenAmount(tokenAmount))
95
+ }
96
+
97
+ /**
98
+ * Adds multiple input tokens from TokenAmounts.
99
+ * @param tokenAmounts - Array of token amounts to swap from (must be on source chain)
100
+ * @returns This SwapBuilder instance for method chaining
101
+ */
102
+ addTokensInFromTokenAmounts(tokenAmounts: TokenAmount[]): SwapBuilder {
103
+ for (let i = 0; i < tokenAmounts.length; i++) this.addTokenInFromTokenAmount(tokenAmounts[i])
104
+ return this
105
+ }
106
+
107
+ /**
108
+ * Adds an input token from a decimal string amount.
109
+ * @param token - The token to swap from (must be on source chain)
110
+ * @param amount - The amount as a decimal string
111
+ * @returns This SwapBuilder instance for method chaining
112
+ */
113
+ addTokenInFromStringDecimal(token: Token, amount: string): SwapBuilder {
114
+ if (token.chainId !== this.sourceChain) throw new Error('Tokens in must be on the same chain')
115
+ return this.addTokenIn(TokenIn.fromStringDecimal(token, amount))
116
+ }
117
+
118
+ /**
119
+ * Adds an output token from a TokenAmount.
120
+ * @param tokenAmount - The minimum token amount to receive (must be on destination chain)
121
+ * @param recipient - The address to receive the tokens
122
+ * @returns This SwapBuilder instance for method chaining
123
+ */
124
+ addTokenOutFromTokenAmount(tokenAmount: TokenAmount, recipient: Address): SwapBuilder {
125
+ if (tokenAmount.token.chainId !== this.destinationChain) throw new Error('Tokens out must be on the same chain')
126
+ return this.addTokenOut(TokenOut.fromTokenAmount(tokenAmount, recipient))
127
+ }
128
+
129
+ /**
130
+ * Adds multiple output tokens from TokenAmounts.
131
+ * @param tokenAmounts - Array of minimum token amounts to receive (must be on destination chain)
132
+ * @param recipient - The address to receive the tokens
133
+ * @returns This SwapBuilder instance for method chaining
134
+ */
135
+ addTokensOutFromTokenAmounts(tokenAmounts: TokenAmount[], recipient: Address): SwapBuilder {
136
+ for (let i = 0; i < tokenAmounts.length; i++) this.addTokenOutFromTokenAmount(tokenAmounts[i], recipient)
137
+ return this
138
+ }
139
+
140
+ /**
141
+ * Adds an output token from a decimal string amount.
142
+ * @param token - The token to receive (must be on destination chain)
143
+ * @param amount - The minimum amount as a decimal string
144
+ * @param recipient - The address to receive the tokens
145
+ * @returns This SwapBuilder instance for method chaining
146
+ */
147
+ addTokenOutFromStringDecimal(token: Token, amount: string, recipient: Address): SwapBuilder {
148
+ if (token.chainId !== this.destinationChain) throw new Error('Tokens out must be on the same chain')
149
+ return this.addTokenOut(TokenOut.fromStringDecimal(token, amount, recipient))
150
+ }
151
+
152
+ /**
153
+ * Sets the settler address for this intent.
154
+ * @param settler - The settler address as an Address instance
155
+ * @returns This SwapBuilder instance for method chaining
156
+ */
157
+ addSettler(settler: Address): SwapBuilder {
158
+ return changetype<SwapBuilder>(super.addSettler(settler))
159
+ }
160
+
161
+ /**
162
+ * Sets the settler address from a string.
163
+ * @param settler - The settler address as a hex string
164
+ * @returns This SwapBuilder instance for method chaining
165
+ */
166
+ addSettlerAsString(settler: string): SwapBuilder {
167
+ return changetype<SwapBuilder>(super.addSettlerAsString(settler))
168
+ }
169
+
170
+ /**
171
+ * Sets the deadline for this intent.
172
+ * @param deadline - The deadline as a timestamp
173
+ * @returns This SwapBuilder instance for method chaining
174
+ */
175
+ addDeadline(deadline: BigInt): SwapBuilder {
176
+ return changetype<SwapBuilder>(super.addDeadline(deadline))
177
+ }
178
+
179
+ /**
180
+ * Sets the user address for this intent.
181
+ * @param user - The user address
182
+ * @returns This SwapBuilder instance for method chaining
183
+ */
184
+ addUser(user: Address): SwapBuilder {
185
+ return changetype<SwapBuilder>(super.addUser(user))
186
+ }
187
+
188
+ /**
189
+ * Sets the user address from a string.
190
+ * @param user - The user address as a hex string
191
+ * @returns This SwapBuilder instance for method chaining
192
+ */
193
+ addUserAsString(user: string): SwapBuilder {
194
+ return changetype<SwapBuilder>(super.addUserAsString(user))
195
+ }
196
+
197
+ /**
198
+ * Sets the nonce for this intent.
199
+ * @param nonce - A unique identifier to prevent replay attacks
200
+ * @returns This SwapBuilder instance for method chaining
201
+ */
202
+ addNonce(nonce: string): SwapBuilder {
203
+ return changetype<SwapBuilder>(super.addNonce(nonce))
204
+ }
205
+
206
+ /**
207
+ * Builds and returns the final Swap intent.
208
+ * @returns A new Swap instance with all configured parameters
209
+ */
210
+ build(): Swap {
211
+ if (this.tokensIn.length === 0 || this.tokensOut.length === 0) throw new Error('Tokens in and out are required')
212
+
213
+ return new Swap(
214
+ this.sourceChain,
215
+ this.tokensIn,
216
+ this.tokensOut,
217
+ this.destinationChain,
218
+ this.settler,
219
+ this.user,
220
+ this.deadline,
221
+ this.nonce
222
+ )
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Represents an input token configuration for a swap operation.
228
+ * Specifies the token address and amount to be swapped.
229
+ */
230
+ @json
231
+ export class TokenIn {
232
+ token: string
233
+ amount: string
234
+
235
+ /**
236
+ * Creates a TokenIn from a TokenAmount.
237
+ * @param tokenAmount - The token amount to swap from
238
+ * @returns A new TokenIn instance
239
+ */
240
+ static fromTokenAmount(tokenAmount: TokenAmount): TokenIn {
241
+ return new TokenIn(tokenAmount.token.address, tokenAmount.amount)
242
+ }
243
+
244
+ /**
245
+ * Creates a TokenIn from a 32-bit integer amount.
246
+ * @param token - The token to swap from
247
+ * @param amount - The amount as a whole number
248
+ * @returns A new TokenIn instance
249
+ */
250
+ static fromI32(token: Token, amount: i32): TokenIn {
251
+ return this.fromTokenAmount(TokenAmount.fromI32(token, amount))
252
+ }
253
+
254
+ /**
255
+ * Creates a TokenIn from a BigInt amount.
256
+ * @param token - The token to swap from
257
+ * @param amount - The amount in the token's smallest unit
258
+ * @returns A new TokenIn instance
259
+ */
260
+ static fromBigInt(token: Token, amount: BigInt): TokenIn {
261
+ return this.fromTokenAmount(TokenAmount.fromBigInt(token, amount))
262
+ }
263
+
264
+ /**
265
+ * Creates a TokenIn from a decimal string amount.
266
+ * @param token - The token to swap from
267
+ * @param amount - The amount as a decimal string
268
+ * @returns A new TokenIn instance
269
+ */
270
+ static fromStringDecimal(token: Token, amount: string): TokenIn {
271
+ return this.fromTokenAmount(TokenAmount.fromStringDecimal(token, amount))
272
+ }
273
+
274
+ /**
275
+ * Creates a new TokenIn instance.
276
+ * @param token - The token address
277
+ * @param amount - The amount in the token's smallest unit
278
+ */
279
+ constructor(token: Address, amount: BigInt) {
280
+ this.token = token.toString()
281
+ this.amount = amount.toString()
282
+ }
283
+ }
284
+
285
+ /**
286
+ * Represents an output token configuration for a swap operation.
287
+ * Specifies the token address, minimum amount to receive, and recipient.
288
+ */
289
+ @json
290
+ export class TokenOut {
291
+ token: string
292
+ minAmount: string
293
+ recipient: string
294
+
295
+ /**
296
+ * Creates a TokenOut from a TokenAmount.
297
+ * @param tokenAmount - The minimum token amount to receive
298
+ * @param recipient - The address to receive the tokens
299
+ * @returns A new TokenOut instance
300
+ */
301
+ static fromTokenAmount(tokenAmount: TokenAmount, recipient: Address): TokenOut {
302
+ return new TokenOut(tokenAmount.token.address, tokenAmount.amount, recipient)
303
+ }
304
+
305
+ /**
306
+ * Creates a TokenOut from a 32-bit integer amount.
307
+ * @param token - The token to receive
308
+ * @param amount - The minimum amount as a whole number
309
+ * @param recipient - The address to receive the tokens
310
+ * @returns A new TokenOut instance
311
+ */
312
+ static fromI32(token: Token, amount: i32, recipient: Address): TokenOut {
313
+ return this.fromTokenAmount(TokenAmount.fromI32(token, amount), recipient)
314
+ }
315
+
316
+ /**
317
+ * Creates a TokenOut from a BigInt amount.
318
+ * @param token - The token to receive
319
+ * @param amount - The minimum amount in the token's smallest unit
320
+ * @param recipient - The address to receive the tokens
321
+ * @returns A new TokenOut instance
322
+ */
323
+ static fromBigInt(token: Token, amount: BigInt, recipient: Address): TokenOut {
324
+ return this.fromTokenAmount(TokenAmount.fromBigInt(token, amount), recipient)
325
+ }
326
+
327
+ /**
328
+ * Creates a TokenOut from a decimal string amount.
329
+ * @param token - The token to receive
330
+ * @param amount - The minimum amount as a decimal string
331
+ * @param recipient - The address to receive the tokens
332
+ * @returns A new TokenOut instance
333
+ */
334
+ static fromStringDecimal(token: Token, amount: string, recipient: Address): TokenOut {
335
+ return this.fromTokenAmount(TokenAmount.fromStringDecimal(token, amount), recipient)
336
+ }
337
+
338
+ /**
339
+ * Creates a new TokenOut instance.
340
+ * @param token - The token address
341
+ * @param minAmount - The minimum amount in the token's smallest unit
342
+ * @param recipient - The address to receive the tokens
343
+ */
344
+ constructor(token: Address, minAmount: BigInt, recipient: Address) {
345
+ this.token = token.toString()
346
+ this.minAmount = minAmount.toString()
347
+ this.recipient = recipient.toString()
348
+ }
349
+ }
350
+
351
+ /**
352
+ * Represents a Swap intent for exchanging tokens between blockchain networks.
353
+ */
354
+ @json
355
+ export class Swap extends Intent {
356
+ /**
357
+ * Creates a simple single-chain swap intent.
358
+ * @param chainId - The blockchain network identifier
359
+ * @param tokenIn - The input token address
360
+ * @param amountIn - The amount to swap from
361
+ * @param tokenOut - The output token address
362
+ * @param minAmountOut - The minimum amount to receive
363
+ * @param settler - The settler address (optional)
364
+ * @param user - The user address (optional)
365
+ * @param deadline - The deadline timestamp (optional)
366
+ * @param nonce - The nonce for replay protection (optional)
367
+ * @returns A new Swap instance
368
+ */
369
+ static create(
370
+ chainId: ChainId,
371
+ tokenIn: Address,
372
+ amountIn: BigInt,
373
+ tokenOut: Address,
374
+ minAmountOut: BigInt,
375
+ settler: Address | null = null,
376
+ user: Address | null = null,
377
+ deadline: BigInt | null = null,
378
+ nonce: string | null = null
379
+ ): Swap {
380
+ const context = environment.getContext()
381
+ const recipient = user || context.user
382
+ const swapIn = TokenIn.fromBigInt(Token.fromAddress(tokenIn, chainId), amountIn)
383
+ const swapOut = TokenOut.fromBigInt(Token.fromAddress(tokenOut, chainId), minAmountOut, recipient)
384
+ return new Swap(chainId, [swapIn], [swapOut], chainId, settler, user, deadline, nonce)
385
+ }
386
+
387
+ /**
388
+ * Creates a new Swap intent.
389
+ * @param sourceChain - The source blockchain network identifier
390
+ * @param tokensIn - Array of input token configurations
391
+ * @param tokensOut - Array of output token configurations
392
+ * @param destinationChain - The destination blockchain network identifier
393
+ * @param settler - The settler address (optional)
394
+ * @param user - The user address (optional)
395
+ * @param deadline - The deadline timestamp (optional)
396
+ * @param nonce - The nonce for replay protection (optional)
397
+ */
398
+ constructor(
399
+ public sourceChain: ChainId,
400
+ public tokensIn: TokenIn[],
401
+ public tokensOut: TokenOut[],
402
+ public destinationChain: ChainId,
403
+ settler: Address | null = null,
404
+ user: Address | null = null,
405
+ deadline: BigInt | null = null,
406
+ nonce: string | null = null
407
+ ) {
408
+ super(OperationType.Swap, settler, user, deadline, nonce)
409
+ if (tokensIn.length === 0) throw new Error('TokenIn list cannot be empty')
410
+ if (tokensOut.length === 0) throw new Error('TokenOut list cannot be empty')
411
+ }
412
+
413
+ /**
414
+ * Sends this Swap intent to the execution environment.
415
+ */
416
+ send(): void {
417
+ environment.swap(this)
418
+ }
419
+ }