@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 +1 -1
- package/src/environment.ts +19 -7
- package/src/intents/{Call.ts → Call/EvmCall.ts} +103 -62
- package/src/intents/Call/SvmCall.ts +278 -0
- package/src/intents/Call/index.ts +2 -0
- package/src/intents/Intent.ts +2 -1
- package/src/intents/Swap.ts +83 -29
- package/src/intents/Transfer.ts +30 -3
- package/src/tokens/BlockchainToken.ts +12 -2
- package/src/tokens/Token.ts +8 -0
- package/src/tokens/TokenAmount.ts +22 -2
- package/src/types/Address.ts +3 -3
- package/src/types/svm/SvmAccountMeta.ts +28 -0
package/package.json
CHANGED
package/src/environment.ts
CHANGED
|
@@ -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,
|
|
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', '
|
|
23
|
-
declare function
|
|
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
|
|
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
|
|
54
|
-
|
|
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 '
|
|
2
|
-
import { TokenAmount } from '
|
|
3
|
-
import { Address, BigInt, Bytes, ChainId } from '
|
|
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
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
export class EvmCallBuilder extends IntentBuilder {
|
|
11
|
+
protected chainId: ChainId
|
|
12
|
+
protected calls: EvmCallData[] = []
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
|
-
* Creates a
|
|
15
|
+
* Creates a EvmCallBuilder for the specified EVM blockchain network.
|
|
17
16
|
* @param chainId - The blockchain network identifier
|
|
18
|
-
* @returns A new
|
|
17
|
+
* @returns A new EvmCallBuilder instance
|
|
19
18
|
*/
|
|
20
|
-
static forChain(chainId: ChainId):
|
|
21
|
-
return new
|
|
19
|
+
static forChain(chainId: ChainId): EvmCallBuilder {
|
|
20
|
+
return new EvmCallBuilder(chainId)
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
/**
|
|
25
|
-
* Creates a new
|
|
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
|
|
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
|
-
|
|
41
|
-
|
|
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
|
|
89
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
49
90
|
*/
|
|
50
|
-
addSettler(settler: Address):
|
|
51
|
-
return changetype<
|
|
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
|
|
98
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
58
99
|
*/
|
|
59
|
-
addSettlerAsString(settler: string):
|
|
60
|
-
return changetype<
|
|
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
|
|
107
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
67
108
|
*/
|
|
68
|
-
addDeadline(deadline: BigInt):
|
|
69
|
-
return changetype<
|
|
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
|
|
116
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
76
117
|
*/
|
|
77
|
-
addUser(user: Address):
|
|
78
|
-
return changetype<
|
|
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
|
|
125
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
85
126
|
*/
|
|
86
|
-
addUserAsString(user: string):
|
|
87
|
-
return changetype<
|
|
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
|
|
134
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
94
135
|
*/
|
|
95
|
-
addNonce(nonce: string):
|
|
96
|
-
return changetype<
|
|
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
|
|
143
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
103
144
|
*/
|
|
104
|
-
addMaxFee(fee: TokenAmount):
|
|
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
|
|
155
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
115
156
|
*/
|
|
116
|
-
addEvent(topic: Bytes, data: Bytes):
|
|
117
|
-
return changetype<
|
|
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
|
|
164
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
124
165
|
*/
|
|
125
|
-
addEvents(events: IntentEvent[]):
|
|
126
|
-
return changetype<
|
|
166
|
+
addEvents(events: IntentEvent[]): EvmCallBuilder {
|
|
167
|
+
return changetype<EvmCallBuilder>(super.addEvents(events))
|
|
127
168
|
}
|
|
128
169
|
|
|
129
170
|
/**
|
|
130
|
-
* Builds and returns the final
|
|
131
|
-
* @returns A new
|
|
171
|
+
* Builds and returns the final EvmCall intent.
|
|
172
|
+
* @returns A new EvmCall instance with all configured parameters
|
|
132
173
|
*/
|
|
133
|
-
build():
|
|
134
|
-
return new
|
|
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
|
|
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
|
|
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
|
|
215
|
+
export class EvmCall extends Intent {
|
|
175
216
|
public chainId: ChainId
|
|
176
|
-
public calls:
|
|
217
|
+
public calls: EvmCallData[]
|
|
177
218
|
|
|
178
219
|
/**
|
|
179
|
-
* Creates a
|
|
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
|
-
):
|
|
203
|
-
const callData = new
|
|
204
|
-
return new
|
|
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
|
|
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:
|
|
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.
|
|
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
|
|
278
|
+
* Sends this EvmCall intent to the execution environment.
|
|
238
279
|
*/
|
|
239
280
|
public send(): void {
|
|
240
|
-
environment.
|
|
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
|
+
}
|
package/src/intents/Intent.ts
CHANGED
package/src/intents/Swap.ts
CHANGED
|
@@ -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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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):
|
|
274
|
-
return new
|
|
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):
|
|
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):
|
|
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):
|
|
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
|
|
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):
|
|
335
|
-
return new
|
|
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):
|
|
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):
|
|
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):
|
|
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 =
|
|
417
|
-
const swapOut =
|
|
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:
|
|
436
|
-
public tokensOut:
|
|
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,
|
package/src/intents/Transfer.ts
CHANGED
|
@@ -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
|
-
|
|
13
|
-
|
|
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.)
|
package/src/tokens/Token.ts
CHANGED
|
@@ -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 {
|
|
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
|
+
}
|
package/src/types/Address.ts
CHANGED
|
@@ -15,10 +15,10 @@ import { Option } from './Option'
|
|
|
15
15
|
*/
|
|
16
16
|
export class Address extends Bytes {
|
|
17
17
|
/**
|
|
18
|
-
* Returns
|
|
18
|
+
* Returns a zero address (default 20 bytes filled with zeroes).
|
|
19
19
|
*/
|
|
20
|
-
static zero(): Address {
|
|
21
|
-
const self = new ByteArray(
|
|
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
|
+
}
|