@mimicprotocol/lib-ts 0.0.1-rc.21 → 0.0.1-rc.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mimicprotocol/lib-ts",
3
- "version": "0.0.1-rc.21",
3
+ "version": "0.0.1-rc.23",
4
4
  "license": "GPL-3.0",
5
5
  "private": false,
6
6
  "type": "module",
@@ -2,7 +2,7 @@ import { JSON } from 'json-as/assembly'
2
2
 
3
3
  import { Context, SerializableContext } from './context'
4
4
  import { ListType } from './helpers'
5
- import { Swap, Transfer, Call } from './intents'
5
+ import { Swap, Transfer, EvmCall, SvmCall } from './intents'
6
6
  import {
7
7
  Call as CallQuery,
8
8
  GetAccountsInfo,
@@ -17,10 +17,14 @@ import {
17
17
  } from './queries'
18
18
  import { BlockchainToken, Token, TokenAmount, USD } from './tokens'
19
19
  import { Address, BigInt, ChainId } from './types'
20
+ import { log } from './log'
20
21
 
21
22
  export namespace environment {
22
- @external('environment', '_call')
23
- declare function _call(params: string): void
23
+ @external('environment', '_evmCall')
24
+ declare function _evmCall(params: string): void
25
+
26
+ @external('environment', '_svmCall')
27
+ declare function _svmCall(params: string): void
24
28
 
25
29
  @external('environment', '_swap')
26
30
  declare function _swap(params: string): void
@@ -47,11 +51,19 @@ export namespace environment {
47
51
  declare function _getContext(): string
48
52
 
49
53
  /**
50
- * Generates a Call intent containing contract calls on the blockchain.
51
- * @param call - The Call intent to generate
54
+ * Generates a EVM Call intent containing contract calls on the blockchain.
55
+ * @param call - The EvmCall intent to generate
56
+ */
57
+ export function evmCall(call: EvmCall): void {
58
+ _evmCall(JSON.stringify(call))
59
+ }
60
+
61
+ /**
62
+ * Generates a SVM Call intent containing contract calls on the blockchain.
63
+ * @param call - The SvmCall intent to generate
52
64
  */
53
- export function call(call: Call): void {
54
- _call(JSON.stringify(call))
65
+ export function svmCall(call: SvmCall): void {
66
+ _svmCall(JSON.stringify(call))
55
67
  }
56
68
 
57
69
  /**
@@ -1,31 +1,30 @@
1
- import { environment } from '../environment'
2
- import { TokenAmount } from '../tokens'
3
- import { Address, BigInt, Bytes, ChainId } from '../types'
4
-
5
- import { Intent, IntentBuilder, IntentEvent, MaxFee, OperationType } from './Intent'
1
+ import { environment } from '../../environment'
2
+ import { TokenAmount } from '../../tokens'
3
+ import { Address, BigInt, Bytes, ChainId } from '../../types'
4
+ import { Intent, IntentBuilder, IntentEvent, MaxFee, OperationType } from '../Intent'
6
5
 
7
6
  /**
8
- * Builder for creating Call intents with contract call operations.
7
+ * Builder for creating EVM Call intents with contract call operations.
9
8
  * Allows chaining multiple contract calls and configuring fees and settlement parameters.
10
9
  */
11
- export class CallBuilder extends IntentBuilder {
12
- private chainId: ChainId
13
- private calls: CallData[] = []
10
+ export class EvmCallBuilder extends IntentBuilder {
11
+ protected chainId: ChainId
12
+ protected calls: EvmCallData[] = []
14
13
 
15
14
  /**
16
- * Creates a CallBuilder for the specified blockchain network.
15
+ * Creates a EvmCallBuilder for the specified EVM blockchain network.
17
16
  * @param chainId - The blockchain network identifier
18
- * @returns A new CallBuilder instance
17
+ * @returns A new EvmCallBuilder instance
19
18
  */
20
- static forChain(chainId: ChainId): CallBuilder {
21
- return new CallBuilder(chainId)
19
+ static forChain(chainId: ChainId): EvmCallBuilder {
20
+ return new EvmCallBuilder(chainId)
22
21
  }
23
22
 
24
23
  /**
25
- * Creates a new CallBuilder instance.
26
- * @param chainId - The blockchain network identifier
24
+ * Creates a new EvmCallBuilder instance.
25
+ * @param chainId - The EVM blockchain network identifier
27
26
  */
28
- constructor(chainId: ChainId) {
27
+ private constructor(chainId: ChainId) {
29
28
  super()
30
29
  this.chainId = chainId
31
30
  }
@@ -35,73 +34,115 @@ export class CallBuilder extends IntentBuilder {
35
34
  * @param target - The contract address to call
36
35
  * @param data - The call data (optional, defaults to empty bytes)
37
36
  * @param value - The native token value to send (optional, defaults to zero)
38
- * @returns This CallBuilder instance for method chaining
37
+ * @returns This EvmCallBuilder instance for method chaining
38
+ */
39
+ addCall(target: Address, data: Bytes = Bytes.empty(), value: BigInt = BigInt.zero()): EvmCallBuilder {
40
+ this.calls.push(new EvmCallData(target, data, value))
41
+ return this
42
+ }
43
+
44
+ /**
45
+ * Adds multiple contract calls to the intent.
46
+ * @param calls - The contract calls to add
47
+ * @returns This EvmCallBuilder instance for method chaining
48
+ */
49
+ addCalls(calls: EvmCallData[]): EvmCallBuilder {
50
+ for (let i = 0; i < calls.length; i++)
51
+ this.addCall(
52
+ Address.fromString(calls[i].target),
53
+ Bytes.fromHexString(calls[i].data),
54
+ BigInt.fromString(calls[i].value)
55
+ )
56
+ return this
57
+ }
58
+
59
+ /**
60
+ * Adds the calls from another EvmCallBuilder to this EvmCallBuilder.
61
+ * @param builder - The EvmCallBuilder to add the calls from
62
+ * @returns This EvmCallBuilder instance for method chaining
63
+ */
64
+ addCallsFromBuilder(builder: EvmCallBuilder): EvmCallBuilder {
65
+ return this.addCalls(builder.getCalls())
66
+ }
67
+
68
+ /**
69
+ * Adds the calls from multiple EvmCallBuilders to this EvmCallBuilder.
70
+ * @param builders - The EvmCallBuilders to add the calls from
71
+ * @returns This EvmCallBuilder instance for method chaining
39
72
  */
40
- addCall(target: Address, data: Bytes = Bytes.empty(), value: BigInt = BigInt.zero()): CallBuilder {
41
- this.calls.push(new CallData(target, data, value))
73
+ addCallsFromBuilders(builders: EvmCallBuilder[]): EvmCallBuilder {
74
+ for (let i = 0; i < builders.length; i++) this.addCallsFromBuilder(builders[i])
42
75
  return this
43
76
  }
44
77
 
78
+ /**
79
+ * Returns a copy of the calls array.
80
+ * @returns A copy of the calls array
81
+ */
82
+ getCalls(): EvmCallData[] {
83
+ return this.calls.slice(0)
84
+ }
85
+
45
86
  /**
46
87
  * Sets the settler address for this intent.
47
88
  * @param settler - The settler address as an Address instance
48
- * @returns This CallBuilder instance for method chaining
89
+ * @returns This EvmCallBuilder instance for method chaining
49
90
  */
50
- addSettler(settler: Address): CallBuilder {
51
- return changetype<CallBuilder>(super.addSettler(settler))
91
+ addSettler(settler: Address): EvmCallBuilder {
92
+ return changetype<EvmCallBuilder>(super.addSettler(settler))
52
93
  }
53
94
 
54
95
  /**
55
96
  * Sets the settler address from a string.
56
97
  * @param settler - The settler address as a hex string
57
- * @returns This CallBuilder instance for method chaining
98
+ * @returns This EvmCallBuilder instance for method chaining
58
99
  */
59
- addSettlerAsString(settler: string): CallBuilder {
60
- return changetype<CallBuilder>(super.addSettlerAsString(settler))
100
+ addSettlerAsString(settler: string): EvmCallBuilder {
101
+ return changetype<EvmCallBuilder>(super.addSettlerAsString(settler))
61
102
  }
62
103
 
63
104
  /**
64
105
  * Sets the deadline for this intent.
65
106
  * @param deadline - The deadline as a timestamp
66
- * @returns This CallBuilder instance for method chaining
107
+ * @returns This EvmCallBuilder instance for method chaining
67
108
  */
68
- addDeadline(deadline: BigInt): CallBuilder {
69
- return changetype<CallBuilder>(super.addDeadline(deadline))
109
+ addDeadline(deadline: BigInt): EvmCallBuilder {
110
+ return changetype<EvmCallBuilder>(super.addDeadline(deadline))
70
111
  }
71
112
 
72
113
  /**
73
114
  * Sets the user address for this intent.
74
115
  * @param user - The user address
75
- * @returns This CallBuilder instance for method chaining
116
+ * @returns This EvmCallBuilder instance for method chaining
76
117
  */
77
- addUser(user: Address): CallBuilder {
78
- return changetype<CallBuilder>(super.addUser(user))
118
+ addUser(user: Address): EvmCallBuilder {
119
+ return changetype<EvmCallBuilder>(super.addUser(user))
79
120
  }
80
121
 
81
122
  /**
82
123
  * Sets the user address from a string.
83
124
  * @param user - The user address as a hex string
84
- * @returns This CallBuilder instance for method chaining
125
+ * @returns This EvmCallBuilder instance for method chaining
85
126
  */
86
- addUserAsString(user: string): CallBuilder {
87
- return changetype<CallBuilder>(super.addUserAsString(user))
127
+ addUserAsString(user: string): EvmCallBuilder {
128
+ return changetype<EvmCallBuilder>(super.addUserAsString(user))
88
129
  }
89
130
 
90
131
  /**
91
132
  * Sets the nonce for this intent.
92
133
  * @param nonce - A unique identifier to prevent replay attacks
93
- * @returns This CallBuilder instance for method chaining
134
+ * @returns This EvmCallBuilder instance for method chaining
94
135
  */
95
- addNonce(nonce: string): CallBuilder {
96
- return changetype<CallBuilder>(super.addNonce(nonce))
136
+ addNonce(nonce: string): EvmCallBuilder {
137
+ return changetype<EvmCallBuilder>(super.addNonce(nonce))
97
138
  }
98
139
 
99
140
  /**
100
141
  * Adds a max fee for this intent.
101
142
  * @param fee - The max fee token amount (must be on same chain)
102
- * @returns This CallBuilder instance for method chaining
143
+ * @returns This EvmCallBuilder instance for method chaining
103
144
  */
104
- addMaxFee(fee: TokenAmount): CallBuilder {
145
+ addMaxFee(fee: TokenAmount): EvmCallBuilder {
105
146
  if (!fee.token.hasChain(this.chainId)) throw new Error('Fee token must be on the same chain')
106
147
  this.maxFees.push(fee)
107
148
  return this
@@ -111,27 +152,27 @@ export class CallBuilder extends IntentBuilder {
111
152
  * Sets an event for the intent.
112
153
  * @param topic - The topic to be indexed in the event
113
154
  * @param data - The event data
114
- * @returns This CallBuilder instance for method chaining
155
+ * @returns This EvmCallBuilder instance for method chaining
115
156
  */
116
- addEvent(topic: Bytes, data: Bytes): CallBuilder {
117
- return changetype<CallBuilder>(super.addEvent(topic, data))
157
+ addEvent(topic: Bytes, data: Bytes): EvmCallBuilder {
158
+ return changetype<EvmCallBuilder>(super.addEvent(topic, data))
118
159
  }
119
160
 
120
161
  /**
121
162
  * Sets multiple events for the intent.
122
163
  * @param events - The list of events to be added
123
- * @returns This CallBuilder instance for method chaining
164
+ * @returns This EvmCallBuilder instance for method chaining
124
165
  */
125
- addEvents(events: IntentEvent[]): CallBuilder {
126
- return changetype<CallBuilder>(super.addEvents(events))
166
+ addEvents(events: IntentEvent[]): EvmCallBuilder {
167
+ return changetype<EvmCallBuilder>(super.addEvents(events))
127
168
  }
128
169
 
129
170
  /**
130
- * Builds and returns the final Call intent.
131
- * @returns A new Call instance with all configured parameters
171
+ * Builds and returns the final EvmCall intent.
172
+ * @returns A new EvmCall instance with all configured parameters
132
173
  */
133
- build(): Call {
134
- return new Call(
174
+ build(): EvmCall {
175
+ return new EvmCall(
135
176
  this.chainId,
136
177
  this.calls,
137
178
  this.maxFees,
@@ -149,13 +190,13 @@ export class CallBuilder extends IntentBuilder {
149
190
  * Contains the target address, call data, and value to send.
150
191
  */
151
192
  @json
152
- export class CallData {
193
+ export class EvmCallData {
153
194
  public target: string
154
195
  public data: string
155
196
  public value: string
156
197
 
157
198
  /**
158
- * Creates a new CallData instance.
199
+ * Creates a new EvmCallData instance.
159
200
  * @param target - The contract address to call
160
201
  * @param data - The call data (optional, defaults to empty bytes)
161
202
  * @param value - The native token value to send (optional, defaults to zero)
@@ -171,12 +212,12 @@ export class CallData {
171
212
  * Represents a Call intent containing one or more contract calls to be executed.
172
213
  */
173
214
  @json
174
- export class Call extends Intent {
215
+ export class EvmCall extends Intent {
175
216
  public chainId: ChainId
176
- public calls: CallData[]
217
+ public calls: EvmCallData[]
177
218
 
178
219
  /**
179
- * Creates a Call intent with a single contract call.
220
+ * Creates a EvmCall intent with a single contract call.
180
221
  * @param chainId - The blockchain network identifier
181
222
  * @param target - The contract address to call
182
223
  * @param data - The call data
@@ -199,13 +240,13 @@ export class Call extends Intent {
199
240
  deadline: BigInt | null = null,
200
241
  nonce: string | null = null,
201
242
  events: IntentEvent[] | null = null
202
- ): Call {
203
- const callData = new CallData(target, data, value)
204
- return new Call(chainId, [callData], [maxFee], settler, user, deadline, nonce, events)
243
+ ): EvmCall {
244
+ const callData = new EvmCallData(target, data, value)
245
+ return new EvmCall(chainId, [callData], [maxFee], settler, user, deadline, nonce, events)
205
246
  }
206
247
 
207
248
  /**
208
- * Creates a new Call intent.
249
+ * Creates a new EvmCall intent.
209
250
  * @param chainId - The blockchain network identifier
210
251
  * @param calls - Array of contract calls to execute
211
252
  * @param maxFees - The list of max fees to pay for the call intent
@@ -216,7 +257,7 @@ export class Call extends Intent {
216
257
  */
217
258
  constructor(
218
259
  chainId: ChainId,
219
- calls: CallData[],
260
+ calls: EvmCallData[],
220
261
  maxFees: TokenAmount[],
221
262
  settler: Address | null = null,
222
263
  user: Address | null = null,
@@ -225,7 +266,7 @@ export class Call extends Intent {
225
266
  events: IntentEvent[] | null = null
226
267
  ) {
227
268
  const fees: MaxFee[] = maxFees.map((fee: TokenAmount) => MaxFee.fromTokenAmount(fee))
228
- super(OperationType.Call, chainId, fees, settler, user, deadline, nonce, events)
269
+ super(OperationType.EvmCall, chainId, fees, settler, user, deadline, nonce, events)
229
270
  if (calls.length === 0) throw new Error('Call list cannot be empty')
230
271
  if (maxFees.length == 0) throw new Error('At least a max fee must be specified')
231
272
 
@@ -234,9 +275,9 @@ export class Call extends Intent {
234
275
  }
235
276
 
236
277
  /**
237
- * Sends this Call intent to the execution environment.
278
+ * Sends this EvmCall intent to the execution environment.
238
279
  */
239
280
  public send(): void {
240
- environment.call(this)
281
+ environment.evmCall(this)
241
282
  }
242
283
  }
@@ -0,0 +1,278 @@
1
+ import { environment } from '../../environment'
2
+ import { TokenAmount } from '../../tokens'
3
+ import { Address, BigInt, Bytes, ChainId } from '../../types'
4
+ import { SvmAccountMeta } from '../../types/svm/SvmAccountMeta'
5
+ import { Intent, IntentBuilder, IntentEvent, MaxFee, OperationType } from '../Intent'
6
+
7
+ /**
8
+ * Builder for creating SVM Call intents with program call operations.
9
+ * Allows chaining multiple calls and configuring fees and settlement parameters.
10
+ */
11
+ export class SvmCallBuilder extends IntentBuilder {
12
+ protected chainId: ChainId
13
+ protected instructions: SvmInstruction[] = []
14
+
15
+ /**
16
+ * Creates a SvmCallBuilder for Solana mainnet.
17
+ * @returns A new SvmCallBuilder instance
18
+ */
19
+ static forChain(): SvmCallBuilder {
20
+ return new SvmCallBuilder()
21
+ }
22
+
23
+ /**
24
+ * Creates a new SvmCallBuilder instance.
25
+ */
26
+ private constructor() {
27
+ super()
28
+ this.chainId = ChainId.SOLANA_MAINNET
29
+ }
30
+
31
+ /**
32
+ * Adds an instruction to the intent.
33
+ * @param instruction - The instruction to add
34
+ * @returns This SvmCallBuilder instance for method chaining
35
+ */
36
+ addInstruction(instruction: SvmInstruction): SvmCallBuilder {
37
+ this.instructions.push(instruction)
38
+ return this
39
+ }
40
+
41
+ /**
42
+ * Adds multiple instructions to the intent.
43
+ * @param instructions - The instructions to add
44
+ * @returns This SvmCallBuilder instance for method chaining
45
+ */
46
+ addInstructions(instructions: SvmInstruction[]): SvmCallBuilder {
47
+ for (let i = 0; i < instructions.length; i++) this.addInstruction(instructions[i])
48
+ return this
49
+ }
50
+
51
+ /**
52
+ * Adds the instructions from another SvmCallBuilder to this SvmCallBuilder.
53
+ * @param builder - The SvmCallBuilder to add the instructions from
54
+ * @returns This SvmCallBuilder instance for method chaining
55
+ */
56
+ addInstructionsFromBuilder(builder: SvmCallBuilder): SvmCallBuilder {
57
+ return this.addInstructions(builder.getInstructions())
58
+ }
59
+
60
+ /**
61
+ * Adds the instructions from multiple SvmCallBuilders to this SvmCallBuilder.
62
+ * @param builders - The SvmCallBuilders to add the instructions from
63
+ * @returns This SvmCallBuilder instance for method chaining
64
+ */
65
+ addInstructionsFromBuilders(builders: SvmCallBuilder[]): SvmCallBuilder {
66
+ for (let i = 0; i < builders.length; i++) this.addInstructionsFromBuilder(builders[i])
67
+ return this
68
+ }
69
+
70
+ /**
71
+ * Returns a copy of the instructions array.
72
+ * @returns A copy of the instructions array
73
+ */
74
+ getInstructions(): SvmInstruction[] {
75
+ return this.instructions.slice(0)
76
+ }
77
+
78
+ /**
79
+ * Sets the settler address for this intent.
80
+ * @param settler - The settler address as an Address instance
81
+ * @returns This SvmCallBuilder instance for method chaining
82
+ */
83
+ addSettler(settler: Address): SvmCallBuilder {
84
+ return changetype<SvmCallBuilder>(super.addSettler(settler))
85
+ }
86
+
87
+ /**
88
+ * Sets the settler address from a string.
89
+ * @param settler - The settler address as a hex string
90
+ * @returns This SvmCallBuilder instance for method chaining
91
+ */
92
+ addSettlerAsString(settler: string): SvmCallBuilder {
93
+ return changetype<SvmCallBuilder>(super.addSettlerAsString(settler))
94
+ }
95
+
96
+ /**
97
+ * Sets the deadline for this intent.
98
+ * @param deadline - The deadline as a timestamp
99
+ * @returns This SvmCallBuilder instance for method chaining
100
+ */
101
+ addDeadline(deadline: BigInt): SvmCallBuilder {
102
+ return changetype<SvmCallBuilder>(super.addDeadline(deadline))
103
+ }
104
+
105
+ /**
106
+ * Sets the user address for this intent.
107
+ * @param user - The user address
108
+ * @returns This SvmCallBuilder instance for method chaining
109
+ */
110
+ addUser(user: Address): SvmCallBuilder {
111
+ return changetype<SvmCallBuilder>(super.addUser(user))
112
+ }
113
+
114
+ /**
115
+ * Sets the user address from a string.
116
+ * @param user - The user address as a hex string
117
+ * @returns This SvmCallBuilder instance for method chaining
118
+ */
119
+ addUserAsString(user: string): SvmCallBuilder {
120
+ return changetype<SvmCallBuilder>(super.addUserAsString(user))
121
+ }
122
+
123
+ /**
124
+ * Sets the nonce for this intent.
125
+ * @param nonce - A unique identifier to prevent replay attacks
126
+ * @returns This SvmCallBuilder instance for method chaining
127
+ */
128
+ addNonce(nonce: string): SvmCallBuilder {
129
+ return changetype<SvmCallBuilder>(super.addNonce(nonce))
130
+ }
131
+
132
+ /**
133
+ * Adds a max fee for this intent.
134
+ * @param fee - The max fee token amount (must be on same chain)
135
+ * @returns This SvmCallBuilder instance for method chaining
136
+ */
137
+ addMaxFee(fee: TokenAmount): SvmCallBuilder {
138
+ if (!fee.token.hasChain(this.chainId)) throw new Error('Fee token must be on the same chain')
139
+ this.maxFees.push(fee)
140
+ return this
141
+ }
142
+
143
+ /**
144
+ * Sets an event for the intent.
145
+ * @param topic - The topic to be indexed in the event
146
+ * @param data - The event data
147
+ * @returns This SvmCallBuilder instance for method chaining
148
+ */
149
+ addEvent(topic: Bytes, data: Bytes): SvmCallBuilder {
150
+ return changetype<SvmCallBuilder>(super.addEvent(topic, data))
151
+ }
152
+
153
+ /**
154
+ * Sets multiple events for the intent.
155
+ * @param events - The list of events to be added
156
+ * @returns This SvmCallBuilder instance for method chaining
157
+ */
158
+ addEvents(events: IntentEvent[]): SvmCallBuilder {
159
+ return changetype<SvmCallBuilder>(super.addEvents(events))
160
+ }
161
+
162
+ /**
163
+ * Builds and returns the final SvmCall intent.
164
+ * @returns A new SvmCall instance with all configured parameters
165
+ */
166
+ build(): SvmCall {
167
+ return new SvmCall(this.instructions, this.maxFees, this.settler, this.user, this.deadline, this.nonce, this.events)
168
+ }
169
+ }
170
+
171
+ export class SvmInstructionBuilder {
172
+ protected programId: Address = Address.zero(32)
173
+ protected accountsMeta: SvmAccountMeta[] = []
174
+ protected data: Bytes = Bytes.empty()
175
+
176
+ setProgram(programId: Address): SvmInstructionBuilder {
177
+ this.programId = programId
178
+ return this
179
+ }
180
+
181
+ setAccounts(accountsMeta: SvmAccountMeta[]): SvmInstructionBuilder {
182
+ this.accountsMeta = accountsMeta
183
+ return this
184
+ }
185
+
186
+ setDataFromBytes(data: Bytes): SvmInstructionBuilder {
187
+ this.data = data
188
+ return this
189
+ }
190
+
191
+ setDataFromHex(data: string): SvmInstructionBuilder {
192
+ return this.setDataFromBytes(Bytes.fromHexString(data))
193
+ }
194
+
195
+ instruction(): SvmInstruction {
196
+ return SvmInstruction.create(this.programId, this.accountsMeta, this.data)
197
+ }
198
+ }
199
+
200
+ @json
201
+ export class SvmInstruction {
202
+ constructor(
203
+ public programId: string,
204
+ public accountsMeta: SvmAccountMeta[],
205
+ public data: string
206
+ ) {}
207
+
208
+ static create(programId: Address, accountsMeta: SvmAccountMeta[], data: Bytes): SvmInstruction {
209
+ return new SvmInstruction(programId.toBase58String(), accountsMeta, data.toHexString())
210
+ }
211
+ }
212
+
213
+ /**
214
+ * Represents a SVM Call intent containing one or more program calls to be executed.
215
+ */
216
+ @json
217
+ export class SvmCall extends Intent {
218
+ public chainId: ChainId
219
+ public instructions: SvmInstruction[]
220
+
221
+ /**
222
+ * Creates a SvmCall intent with a single program call.
223
+ * @param maxFee - The max fee to pay for the call intent
224
+ * @param settler - The settler address (optional)
225
+ * @param user - The user address (optional)
226
+ * @param deadline - The deadline timestamp (optional)
227
+ * @param nonce - The nonce for replay protection (optional)
228
+ * @returns A new Call instance
229
+ */
230
+ static create(
231
+ programId: Address,
232
+ accountsMeta: SvmAccountMeta[],
233
+ data: Bytes,
234
+ maxFee: TokenAmount,
235
+ settler: Address | null = null,
236
+ user: Address | null = null,
237
+ deadline: BigInt | null = null,
238
+ nonce: string | null = null,
239
+ events: IntentEvent[] | null = null
240
+ ): SvmCall {
241
+ const instruction = SvmInstruction.create(programId, accountsMeta, data)
242
+ return new SvmCall([instruction], [maxFee], settler, user, deadline, nonce, events)
243
+ }
244
+
245
+ /**
246
+ * Creates a new SvmCall intent.
247
+ * @param instructions - Array of instructions to execute
248
+ * @param maxFees - The list of max fees to pay for the call intent
249
+ * @param settler - The settler address (optional)
250
+ * @param user - The user address (optional)
251
+ * @param deadline - The deadline timestamp (optional)
252
+ * @param nonce - The nonce for replay protection (optional)
253
+ */
254
+ constructor(
255
+ instructions: SvmInstruction[],
256
+ maxFees: TokenAmount[],
257
+ settler: Address | null = null,
258
+ user: Address | null = null,
259
+ deadline: BigInt | null = null,
260
+ nonce: string | null = null,
261
+ events: IntentEvent[] | null = null
262
+ ) {
263
+ const fees: MaxFee[] = maxFees.map((fee: TokenAmount) => MaxFee.fromTokenAmount(fee))
264
+ super(OperationType.SvmCall, ChainId.SOLANA_MAINNET, fees, settler, user, deadline, nonce, events)
265
+ if (instructions.length === 0) throw new Error('Call list cannot be empty')
266
+ if (maxFees.length == 0) throw new Error('At least a max fee must be specified')
267
+
268
+ this.instructions = instructions
269
+ this.chainId = ChainId.SOLANA_MAINNET
270
+ }
271
+
272
+ /**
273
+ * Sends this SvmCall intent to the execution environment.
274
+ */
275
+ public send(): void {
276
+ environment.svmCall(this)
277
+ }
278
+ }
@@ -0,0 +1,2 @@
1
+ export * from './EvmCall'
2
+ export * from './SvmCall'
@@ -7,7 +7,8 @@ import { Address, BigInt, Bytes, ChainId } from '../types'
7
7
  export enum OperationType {
8
8
  Swap,
9
9
  Transfer,
10
- Call,
10
+ EvmCall,
11
+ SvmCall,
11
12
  }
12
13
 
13
14
  const DEFAULT_DEADLINE = 5 * 60 // 5 minutes in seconds
@@ -9,10 +9,10 @@ import { Intent, IntentBuilder, IntentEvent, MaxFee, OperationType } from './Int
9
9
  * Supports both single-chain and cross-chain swaps with multiple input and output tokens.
10
10
  */
11
11
  export class SwapBuilder extends IntentBuilder {
12
- private sourceChain: ChainId
13
- private destinationChain: ChainId
14
- private tokensIn: TokenIn[] = []
15
- private tokensOut: TokenOut[] = []
12
+ protected sourceChain: ChainId
13
+ protected destinationChain: ChainId
14
+ protected tokensIn: SwapTokenIn[] = []
15
+ protected tokensOut: SwapTokenOut[] = []
16
16
 
17
17
  /**
18
18
  * Creates a SwapBuilder for a single-chain swap.
@@ -38,7 +38,7 @@ export class SwapBuilder extends IntentBuilder {
38
38
  * @param sourceChain - The source blockchain network identifier
39
39
  * @param destinationChain - The destination blockchain network identifier
40
40
  */
41
- constructor(sourceChain: ChainId, destinationChain: ChainId) {
41
+ private constructor(sourceChain: ChainId, destinationChain: ChainId) {
42
42
  super()
43
43
  this.sourceChain = sourceChain
44
44
  this.destinationChain = destinationChain
@@ -49,7 +49,7 @@ export class SwapBuilder extends IntentBuilder {
49
49
  * @param tokenIn - The token input configuration
50
50
  * @returns This SwapBuilder instance for method chaining
51
51
  */
52
- addTokenIn(tokenIn: TokenIn): SwapBuilder {
52
+ addTokenIn(tokenIn: SwapTokenIn): SwapBuilder {
53
53
  this.tokensIn.push(tokenIn)
54
54
  return this
55
55
  }
@@ -59,17 +59,44 @@ export class SwapBuilder extends IntentBuilder {
59
59
  * @param tokensIn - Array of token input configurations
60
60
  * @returns This SwapBuilder instance for method chaining
61
61
  */
62
- addTokensIn(tokensIn: TokenIn[]): SwapBuilder {
62
+ addTokensIn(tokensIn: SwapTokenIn[]): SwapBuilder {
63
63
  for (let i = 0; i < tokensIn.length; i++) this.addTokenIn(tokensIn[i])
64
64
  return this
65
65
  }
66
66
 
67
+ /**
68
+ * Adds the tokens in from another SwapBuilder to this SwapBuilder.
69
+ * @param builder - The SwapBuilder to add the tokens in from
70
+ * @returns This SwapBuilder instance for method chaining
71
+ */
72
+ addTokensInFromBuilder(builder: SwapBuilder): SwapBuilder {
73
+ return this.addTokensIn(builder.getTokensIn())
74
+ }
75
+
76
+ /**
77
+ * Adds the tokens in from multiple SwapBuilders to this SwapBuilder.
78
+ * @param builders - The SwapBuilders to add the tokens in from
79
+ * @returns This SwapBuilder instance for method chaining
80
+ */
81
+ addTokensInFromBuilders(builders: SwapBuilder[]): SwapBuilder {
82
+ for (let i = 0; i < builders.length; i++) this.addTokensInFromBuilder(builders[i])
83
+ return this
84
+ }
85
+
86
+ /**
87
+ * Returns a copy of the tokens in array.
88
+ * @returns A copy of the tokens in array
89
+ */
90
+ getTokensIn(): SwapTokenIn[] {
91
+ return this.tokensIn.slice(0)
92
+ }
93
+
67
94
  /**
68
95
  * Adds an output token to the swap.
69
96
  * @param tokenOut - The token output configuration
70
97
  * @returns This SwapBuilder instance for method chaining
71
98
  */
72
- addTokenOut(tokenOut: TokenOut): SwapBuilder {
99
+ addTokenOut(tokenOut: SwapTokenOut): SwapBuilder {
73
100
  this.tokensOut.push(tokenOut)
74
101
  return this
75
102
  }
@@ -79,11 +106,38 @@ export class SwapBuilder extends IntentBuilder {
79
106
  * @param tokensOut - Array of token output configurations
80
107
  * @returns This SwapBuilder instance for method chaining
81
108
  */
82
- addTokensOut(tokensOut: TokenOut[]): SwapBuilder {
109
+ addTokensOut(tokensOut: SwapTokenOut[]): SwapBuilder {
83
110
  for (let i = 0; i < tokensOut.length; i++) this.addTokenOut(tokensOut[i])
84
111
  return this
85
112
  }
86
113
 
114
+ /**
115
+ * Adds the tokens out from another SwapBuilder to this SwapBuilder.
116
+ * @param builder - The SwapBuilder to add the tokens out from
117
+ * @returns This SwapBuilder instance for method chaining
118
+ */
119
+ addTokensOutFromBuilder(builder: SwapBuilder): SwapBuilder {
120
+ return this.addTokensOut(builder.getTokensOut())
121
+ }
122
+
123
+ /**
124
+ * Adds the tokens out from multiple SwapBuilders to this SwapBuilder.
125
+ * @param builders - The SwapBuilders to add the tokens out from
126
+ * @returns This SwapBuilder instance for method chaining
127
+ */
128
+ addTokensOutFromBuilders(builders: SwapBuilder[]): SwapBuilder {
129
+ for (let i = 0; i < builders.length; i++) this.addTokensOutFromBuilder(builders[i])
130
+ return this
131
+ }
132
+
133
+ /**
134
+ * Returns a copy of the tokens out array.
135
+ * @returns A copy of the tokens out array
136
+ */
137
+ getTokensOut(): SwapTokenOut[] {
138
+ return this.tokensOut.slice(0)
139
+ }
140
+
87
141
  /**
88
142
  * Adds an input token from a TokenAmount.
89
143
  * @param tokenAmount - The token amount to swap from (must be on source chain)
@@ -91,7 +145,7 @@ export class SwapBuilder extends IntentBuilder {
91
145
  */
92
146
  addTokenInFromTokenAmount(tokenAmount: TokenAmount): SwapBuilder {
93
147
  if (!tokenAmount.token.hasChain(this.sourceChain)) throw new Error('Tokens in must be on the same chain')
94
- return this.addTokenIn(TokenIn.fromTokenAmount(tokenAmount))
148
+ return this.addTokenIn(SwapTokenIn.fromTokenAmount(tokenAmount))
95
149
  }
96
150
 
97
151
  /**
@@ -112,7 +166,7 @@ export class SwapBuilder extends IntentBuilder {
112
166
  */
113
167
  addTokenInFromStringDecimal(token: Token, amount: string): SwapBuilder {
114
168
  if (!token.hasChain(this.sourceChain)) throw new Error('Tokens in must be on the source chain')
115
- return this.addTokenIn(TokenIn.fromStringDecimal(token, amount))
169
+ return this.addTokenIn(SwapTokenIn.fromStringDecimal(token, amount))
116
170
  }
117
171
 
118
172
  /**
@@ -124,7 +178,7 @@ export class SwapBuilder extends IntentBuilder {
124
178
  addTokenOutFromTokenAmount(tokenAmount: TokenAmount, recipient: Address): SwapBuilder {
125
179
  if (!tokenAmount.token.hasChain(this.destinationChain))
126
180
  throw new Error('Tokens out must be on the destination chain')
127
- return this.addTokenOut(TokenOut.fromTokenAmount(tokenAmount, recipient))
181
+ return this.addTokenOut(SwapTokenOut.fromTokenAmount(tokenAmount, recipient))
128
182
  }
129
183
 
130
184
  /**
@@ -147,7 +201,7 @@ export class SwapBuilder extends IntentBuilder {
147
201
  */
148
202
  addTokenOutFromStringDecimal(token: Token, amount: string, recipient: Address): SwapBuilder {
149
203
  if (!token.hasChain(this.destinationChain)) throw new Error('Tokens out must be on the destination chain')
150
- return this.addTokenOut(TokenOut.fromStringDecimal(token, amount, recipient))
204
+ return this.addTokenOut(SwapTokenOut.fromStringDecimal(token, amount, recipient))
151
205
  }
152
206
 
153
207
  /**
@@ -261,7 +315,7 @@ export class SwapBuilder extends IntentBuilder {
261
315
  * Specifies the token address and amount to be swapped.
262
316
  */
263
317
  @json
264
- export class TokenIn {
318
+ export class SwapTokenIn {
265
319
  token: string
266
320
  amount: string
267
321
 
@@ -270,8 +324,8 @@ export class TokenIn {
270
324
  * @param tokenAmount - The token amount to swap from
271
325
  * @returns A new TokenIn instance
272
326
  */
273
- static fromTokenAmount(tokenAmount: TokenAmount): TokenIn {
274
- return new TokenIn(tokenAmount.token.address, tokenAmount.amount)
327
+ static fromTokenAmount(tokenAmount: TokenAmount): SwapTokenIn {
328
+ return new SwapTokenIn(tokenAmount.token.address, tokenAmount.amount)
275
329
  }
276
330
 
277
331
  /**
@@ -280,7 +334,7 @@ export class TokenIn {
280
334
  * @param amount - The amount as a whole number
281
335
  * @returns A new TokenIn instance
282
336
  */
283
- static fromI32(token: Token, amount: i32): TokenIn {
337
+ static fromI32(token: Token, amount: i32): SwapTokenIn {
284
338
  return this.fromTokenAmount(TokenAmount.fromI32(token, amount))
285
339
  }
286
340
 
@@ -290,7 +344,7 @@ export class TokenIn {
290
344
  * @param amount - The amount in the token's smallest unit
291
345
  * @returns A new TokenIn instance
292
346
  */
293
- static fromBigInt(token: Token, amount: BigInt): TokenIn {
347
+ static fromBigInt(token: Token, amount: BigInt): SwapTokenIn {
294
348
  return this.fromTokenAmount(TokenAmount.fromBigInt(token, amount))
295
349
  }
296
350
 
@@ -300,7 +354,7 @@ export class TokenIn {
300
354
  * @param amount - The amount as a decimal string
301
355
  * @returns A new TokenIn instance
302
356
  */
303
- static fromStringDecimal(token: Token, amount: string): TokenIn {
357
+ static fromStringDecimal(token: Token, amount: string): SwapTokenIn {
304
358
  return this.fromTokenAmount(TokenAmount.fromStringDecimal(token, amount))
305
359
  }
306
360
 
@@ -320,7 +374,7 @@ export class TokenIn {
320
374
  * Specifies the token address, minimum amount to receive, and recipient.
321
375
  */
322
376
  @json
323
- export class TokenOut {
377
+ export class SwapTokenOut {
324
378
  token: string
325
379
  minAmount: string
326
380
  recipient: string
@@ -331,8 +385,8 @@ export class TokenOut {
331
385
  * @param recipient - The address to receive the tokens
332
386
  * @returns A new TokenOut instance
333
387
  */
334
- static fromTokenAmount(tokenAmount: TokenAmount, recipient: Address): TokenOut {
335
- return new TokenOut(tokenAmount.token.address, tokenAmount.amount, recipient)
388
+ static fromTokenAmount(tokenAmount: TokenAmount, recipient: Address): SwapTokenOut {
389
+ return new SwapTokenOut(tokenAmount.token.address, tokenAmount.amount, recipient)
336
390
  }
337
391
 
338
392
  /**
@@ -342,7 +396,7 @@ export class TokenOut {
342
396
  * @param recipient - The address to receive the tokens
343
397
  * @returns A new TokenOut instance
344
398
  */
345
- static fromI32(token: Token, amount: i32, recipient: Address): TokenOut {
399
+ static fromI32(token: Token, amount: i32, recipient: Address): SwapTokenOut {
346
400
  return this.fromTokenAmount(TokenAmount.fromI32(token, amount), recipient)
347
401
  }
348
402
 
@@ -353,7 +407,7 @@ export class TokenOut {
353
407
  * @param recipient - The address to receive the tokens
354
408
  * @returns A new TokenOut instance
355
409
  */
356
- static fromBigInt(token: Token, amount: BigInt, recipient: Address): TokenOut {
410
+ static fromBigInt(token: Token, amount: BigInt, recipient: Address): SwapTokenOut {
357
411
  return this.fromTokenAmount(TokenAmount.fromBigInt(token, amount), recipient)
358
412
  }
359
413
 
@@ -364,7 +418,7 @@ export class TokenOut {
364
418
  * @param recipient - The address to receive the tokens
365
419
  * @returns A new TokenOut instance
366
420
  */
367
- static fromStringDecimal(token: Token, amount: string, recipient: Address): TokenOut {
421
+ static fromStringDecimal(token: Token, amount: string, recipient: Address): SwapTokenOut {
368
422
  return this.fromTokenAmount(TokenAmount.fromStringDecimal(token, amount), recipient)
369
423
  }
370
424
 
@@ -413,8 +467,8 @@ export class Swap extends Intent {
413
467
  ): Swap {
414
468
  const context = environment.getContext()
415
469
  const recipient = user || context.user
416
- const swapIn = TokenIn.fromBigInt(tokenIn, amountIn)
417
- const swapOut = TokenOut.fromBigInt(tokenOut, minAmountOut, recipient)
470
+ const swapIn = SwapTokenIn.fromBigInt(tokenIn, amountIn)
471
+ const swapOut = SwapTokenOut.fromBigInt(tokenOut, minAmountOut, recipient)
418
472
  return new Swap(chainId, [swapIn], [swapOut], chainId, settler, user, deadline, nonce, [], events)
419
473
  }
420
474
 
@@ -432,8 +486,8 @@ export class Swap extends Intent {
432
486
  */
433
487
  constructor(
434
488
  public sourceChain: ChainId,
435
- public tokensIn: TokenIn[],
436
- public tokensOut: TokenOut[],
489
+ public tokensIn: SwapTokenIn[],
490
+ public tokensOut: SwapTokenOut[],
437
491
  public destinationChain: ChainId,
438
492
  settler: Address | null = null,
439
493
  user: Address | null = null,
@@ -9,8 +9,8 @@ import { Intent, IntentBuilder, IntentEvent, MaxFee, OperationType } from './Int
9
9
  * Supports multiple transfers within a single transaction on the same chain.
10
10
  */
11
11
  export class TransferBuilder extends IntentBuilder {
12
- private chainId: ChainId
13
- private transfers: TransferData[] = []
12
+ protected chainId: ChainId
13
+ protected transfers: TransferData[] = []
14
14
 
15
15
  /**
16
16
  * Creates a TransferBuilder for a specific chain.
@@ -25,7 +25,7 @@ export class TransferBuilder extends IntentBuilder {
25
25
  * Creates a new TransferBuilder instance.
26
26
  * @param chainId - The blockchain network identifier
27
27
  */
28
- constructor(chainId: ChainId) {
28
+ private constructor(chainId: ChainId) {
29
29
  super()
30
30
  this.chainId = chainId
31
31
  }
@@ -50,6 +50,33 @@ export class TransferBuilder extends IntentBuilder {
50
50
  return this
51
51
  }
52
52
 
53
+ /**
54
+ * Adds the transfers from another TransferBuilder to this TransferBuilder.
55
+ * @param builder - The TransferBuilder to add the transfers from
56
+ * @returns This TransferBuilder instance for method chaining
57
+ */
58
+ addTransfersFromBuilder(builder: TransferBuilder): TransferBuilder {
59
+ return this.addTransfers(builder.getTransfers())
60
+ }
61
+
62
+ /**
63
+ * Adds the transfers from multiple TransferBuilders to this TransferBuilder.
64
+ * @param builders - The TransferBuilders to add the transfers from
65
+ * @returns This TransferBuilder instance for method chaining
66
+ */
67
+ addTransfersFromBuilders(builders: TransferBuilder[]): TransferBuilder {
68
+ for (let i = 0; i < builders.length; i++) this.addTransfersFromBuilder(builders[i])
69
+ return this
70
+ }
71
+
72
+ /**
73
+ * Returns a copy of the transfers array.
74
+ * @returns A copy of the transfers array
75
+ */
76
+ getTransfers(): TransferData[] {
77
+ return this.transfers.slice(0)
78
+ }
79
+
53
80
  /**
54
81
  * Adds a transfer from a TokenAmount.
55
82
  * @param tokenAmount - The token amount to transfer (must be on same chain)
@@ -1,8 +1,8 @@
1
- import { Address, ChainId } from '../types'
1
+ import { Address, ChainId, JSON } from '../types'
2
2
 
3
3
  import { ERC20Token } from './ERC20Token'
4
4
  import { SPLToken } from './SPLToken'
5
- import { Token } from './Token'
5
+ import { SerializableToken, Token } from './Token'
6
6
 
7
7
  /**
8
8
  * Represents a token on a blockchain network
@@ -49,6 +49,16 @@ export abstract class BlockchainToken extends Token {
49
49
  return BlockchainToken.fromAddress(Address.fromString(address), chainId, decimals, symbol)
50
50
  }
51
51
 
52
+ /**
53
+ * Creates a BlockchainToken from a serialized string.
54
+ * @param serialized - The serialized string to parse
55
+ * @returns A new BlockchainToken instance
56
+ */
57
+ static fromSerializable(serialized: string): BlockchainToken {
58
+ const data = JSON.parse<SerializableToken>(serialized)
59
+ return BlockchainToken.fromString(data.address, data.chainId)
60
+ }
61
+
52
62
  /**
53
63
  * Creates a new BlockchainToken instance
54
64
  * @param address The token address in the corresponding blockchain (contract, mint, etc.)
@@ -81,3 +81,11 @@ export abstract class Token {
81
81
  */
82
82
  abstract toString(): string
83
83
  }
84
+
85
+ @json
86
+ export class SerializableToken {
87
+ constructor(
88
+ public address: string,
89
+ public chainId: i32
90
+ ) {}
91
+ }
@@ -1,7 +1,8 @@
1
1
  import { environment } from '../environment'
2
- import { BigInt } from '../types'
2
+ import { BigInt, JSON } from '../types'
3
3
 
4
- import { Token } from './Token'
4
+ import { BlockchainToken } from './BlockchainToken'
5
+ import { SerializableToken, Token } from './Token'
5
6
  import { USD } from './USD'
6
7
 
7
8
  /**
@@ -50,6 +51,17 @@ export class TokenAmount {
50
51
  return new TokenAmount(token, amount)
51
52
  }
52
53
 
54
+ /**
55
+ * Creates a TokenAmount from a serialized string.
56
+ * @param serialized - The serialized string to parse
57
+ * @returns A new TokenAmount instance
58
+ */
59
+ static fromSerializable(serialized: string): TokenAmount {
60
+ const data = JSON.parse<SerializableTokenAmount>(serialized)
61
+ const token = BlockchainToken.fromString(data.token.address, data.token.chainId)
62
+ return TokenAmount.fromStringDecimal(token, data.amount)
63
+ }
64
+
53
65
  /**
54
66
  * Creates a new TokenAmount instance.
55
67
  * @param token - The token this amount represents
@@ -228,3 +240,11 @@ export class TokenAmount {
228
240
  if (!this.token.equals(other)) throw new Error(`Cannot ${action} different tokens`)
229
241
  }
230
242
  }
243
+
244
+ @json
245
+ export class SerializableTokenAmount {
246
+ constructor(
247
+ public token: SerializableToken,
248
+ public amount: string
249
+ ) {}
250
+ }
@@ -15,10 +15,10 @@ import { Option } from './Option'
15
15
  */
16
16
  export class Address extends Bytes {
17
17
  /**
18
- * Returns an EVM zero address (20 bytes filled with zeroes).
18
+ * Returns a zero address (default 20 bytes filled with zeroes).
19
19
  */
20
- static zero(): Address {
21
- const self = new ByteArray(20)
20
+ static zero(length: i32 = 20): Address {
21
+ const self = new ByteArray(length)
22
22
  return changetype<Address>(self)
23
23
  }
24
24
 
@@ -0,0 +1,28 @@
1
+ import { Address } from '../Address'
2
+
3
+ @json
4
+ export class SvmAccountMeta {
5
+ constructor(
6
+ public pubkey: string,
7
+ public isWritable: bool = false,
8
+ public isSigner: bool = false
9
+ ) {}
10
+
11
+ writable(): SvmAccountMeta {
12
+ this.isWritable = true
13
+ return this
14
+ }
15
+
16
+ signer(): SvmAccountMeta {
17
+ this.isSigner = true
18
+ return this
19
+ }
20
+
21
+ static fromAddress(pubkey: Address): SvmAccountMeta {
22
+ return new SvmAccountMeta(pubkey.toString())
23
+ }
24
+
25
+ static fromString(pubkey: string): SvmAccountMeta {
26
+ return new SvmAccountMeta(pubkey)
27
+ }
28
+ }