@mimicprotocol/lib-ts 0.0.1-rc.9 → 0.0.1
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/CHANGELOG.md +134 -0
- package/README.md +7 -7
- package/constants.d.ts +1 -0
- package/constants.js +1 -0
- package/index.ts +3 -0
- package/package.json +18 -4
- package/src/chains/Arbitrum.ts +14 -0
- package/src/chains/Avalanche.ts +15 -0
- package/src/chains/BNB.ts +15 -0
- package/src/chains/Base.ts +14 -0
- package/src/chains/BaseSepolia.ts +7 -0
- package/src/chains/Ethereum.ts +7 -7
- package/src/chains/Gnosis.ts +14 -0
- package/src/chains/Optimism.ts +7 -7
- package/src/chains/Polygon.ts +10 -7
- package/src/chains/Sonic.ts +13 -0
- package/src/chains/index.ts +7 -0
- package/src/context/Context.ts +102 -7
- package/src/environment.ts +165 -53
- package/src/evm.ts +5 -4
- package/src/helpers/BorshDeserializer.ts +133 -0
- package/src/helpers/consensus.ts +35 -0
- package/src/helpers/constants.ts +7 -1
- package/src/helpers/index.ts +5 -0
- package/src/helpers/math.ts +20 -0
- package/src/helpers/serialize.ts +5 -125
- package/src/helpers/strings.ts +82 -5
- package/src/intents/Call/EvmCall.ts +283 -0
- package/src/intents/Call/SvmCall.ts +278 -0
- package/src/intents/Call/index.ts +2 -0
- package/src/intents/Intent.ts +178 -5
- package/src/intents/Swap.ts +136 -44
- package/src/intents/Transfer.ts +103 -58
- package/src/log.ts +83 -0
- package/src/queries/EvmCallQuery.ts +43 -0
- package/src/queries/QueryResponse.ts +26 -0
- package/src/queries/RelevantTokensQuery.ts +82 -0
- package/src/queries/SubgraphQuery.ts +50 -0
- package/src/queries/SvmAccountsInfoQuery.ts +65 -0
- package/src/queries/TokenPriceQuery.ts +47 -0
- package/src/queries/index.ts +6 -1
- package/src/storage/index.ts +1 -0
- package/src/storage/storage.ts +46 -0
- package/src/svm.ts +27 -0
- package/src/tokens/BlockchainToken.ts +108 -0
- package/src/tokens/DenominationToken.ts +70 -0
- package/src/tokens/ERC20Token.ts +192 -0
- package/src/tokens/SPLToken.ts +162 -0
- package/src/tokens/Token.ts +55 -155
- package/src/tokens/TokenAmount.ts +72 -30
- package/src/tokens/TokenProvider.ts +54 -0
- package/src/tokens/Tokens.ts +186 -0
- package/src/tokens/USD.ts +9 -6
- package/src/tokens/index.ts +6 -0
- package/src/types/Address.ts +86 -14
- package/src/types/BigInt.ts +14 -22
- package/src/types/ByteArray.ts +41 -3
- package/src/types/Bytes.ts +7 -0
- package/src/types/ChainId.ts +9 -1
- package/src/types/Option.ts +35 -0
- package/src/types/Result.ts +68 -0
- package/src/types/TriggerType.ts +4 -0
- package/src/types/evm/EvmDecodeParam.ts +7 -0
- package/src/types/evm/EvmEncodeParam.ts +31 -0
- package/src/types/evm/index.ts +2 -0
- package/src/types/index.ts +8 -2
- package/src/types/svm/SvmAccountInfo.ts +32 -0
- package/src/types/svm/SvmAccountMeta.ts +28 -0
- package/src/types/svm/SvmFindProgramAddress.ts +32 -0
- package/src/types/svm/SvmMint.ts +44 -0
- package/src/types/svm/SvmPdaSeed.ts +19 -0
- package/src/types/svm/SvmTokenMetadataData.ts +29 -0
- package/src/types/svm/index.ts +5 -0
- package/src/intents/Call.ts +0 -238
- package/src/queries/Call.ts +0 -16
- package/src/types/EvmDecodeParam.ts +0 -30
- package/src/types/EvmEncodeParam.ts +0 -54
package/src/helpers/strings.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { decode, encode } from 'as-base58/assembly/index'
|
|
2
|
+
|
|
3
|
+
import { ByteArray } from '../types'
|
|
4
|
+
|
|
5
|
+
export function bytesToString(bytes: Uint8Array, nullTerminated: bool = false): string {
|
|
6
|
+
return String.UTF8.decodeUnsafe(bytes.dataStart, bytes.length, nullTerminated)
|
|
3
7
|
}
|
|
4
8
|
|
|
5
9
|
export function bytesToHexString(bytes: Uint8Array): string {
|
|
@@ -8,6 +12,59 @@ export function bytesToHexString(bytes: Uint8Array): string {
|
|
|
8
12
|
return hex
|
|
9
13
|
}
|
|
10
14
|
|
|
15
|
+
export function bytesToBase58String(bytes: Uint8Array): string {
|
|
16
|
+
return encode(bytes)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function bytesFromBase58String(base58: string): ByteArray {
|
|
20
|
+
assert(isBase58(base58), `input ${base58} is not valid base58`)
|
|
21
|
+
return changetype<ByteArray>(decode(base58))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function stringToBool(str: string): bool {
|
|
25
|
+
if (str !== 'true' && str !== 'false') throw new Error(`Invalid boolean: ${str}`)
|
|
26
|
+
return str === 'true'
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Workaround for json-as boolean bug:
|
|
31
|
+
* Converts JSON boolean values (true/false) into their string equivalents ("true"/"false")
|
|
32
|
+
* without touching occurrences inside JSON strings or keys.
|
|
33
|
+
*
|
|
34
|
+
* This function assumes compact JSON (no newlines between the boolean and the delimiter).
|
|
35
|
+
*/
|
|
36
|
+
export function replaceJsonBooleans(json: string): string {
|
|
37
|
+
return (
|
|
38
|
+
json
|
|
39
|
+
// true after ':' (object property values)
|
|
40
|
+
.replaceAll(':true', ':"true"')
|
|
41
|
+
.replaceAll(':true,', ':"true",')
|
|
42
|
+
.replaceAll(':true}', ':"true"}')
|
|
43
|
+
.replaceAll(':true]', ':"true"]')
|
|
44
|
+
.replaceAll(': true,', ': "true",')
|
|
45
|
+
.replaceAll(': true}', ': "true"}')
|
|
46
|
+
.replaceAll(': true]', ': "true"]')
|
|
47
|
+
// true in arrays
|
|
48
|
+
.replaceAll('[true,', '["true",')
|
|
49
|
+
.replaceAll('[true]', '["true"]')
|
|
50
|
+
.replaceAll(',true,', ',"true",')
|
|
51
|
+
.replaceAll(',true]', ',"true"]')
|
|
52
|
+
// false after ':' (object property values)
|
|
53
|
+
.replaceAll(':false', ':"false"')
|
|
54
|
+
.replaceAll(':false,', ':"false",')
|
|
55
|
+
.replaceAll(':false}', ':"false"}')
|
|
56
|
+
.replaceAll(':false]', ':"false"]')
|
|
57
|
+
.replaceAll(': false,', ': "false",')
|
|
58
|
+
.replaceAll(': false}', ': "false"}')
|
|
59
|
+
.replaceAll(': false]', ': "false"]')
|
|
60
|
+
// false in arrays
|
|
61
|
+
.replaceAll('[false,', '["false",')
|
|
62
|
+
.replaceAll('[false]', '["false"]')
|
|
63
|
+
.replaceAll(',false,', ',"false",')
|
|
64
|
+
.replaceAll(',false]', ',"false"]')
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
|
|
11
68
|
export function areAllZeros(str: string): boolean {
|
|
12
69
|
for (let i = 0; i < str.length; i++) if (str.charCodeAt(i) !== 48) return false
|
|
13
70
|
return true
|
|
@@ -76,12 +133,14 @@ export function normalizeScientificNotation(input: string): string {
|
|
|
76
133
|
if (newDecimalPos <= 0) {
|
|
77
134
|
const zeros = '0'.repeat(-newDecimalPos)
|
|
78
135
|
return sign + '0.' + zeros + fullDigits
|
|
79
|
-
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (newDecimalPos >= fullDigits.length) {
|
|
80
139
|
const zeros = '0'.repeat(newDecimalPos - fullDigits.length)
|
|
81
140
|
return sign + fullDigits + zeros
|
|
82
|
-
} else {
|
|
83
|
-
return sign + fullDigits.substring(0, newDecimalPos) + '.' + fullDigits.substring(newDecimalPos)
|
|
84
141
|
}
|
|
142
|
+
|
|
143
|
+
return sign + fullDigits.substring(0, newDecimalPos) + '.' + fullDigits.substring(newDecimalPos)
|
|
85
144
|
}
|
|
86
145
|
|
|
87
146
|
export function isHex(str: string, strict: boolean = false): boolean {
|
|
@@ -101,3 +160,21 @@ export function isHex(str: string, strict: boolean = false): boolean {
|
|
|
101
160
|
|
|
102
161
|
return true
|
|
103
162
|
}
|
|
163
|
+
|
|
164
|
+
export function isBase58(str: string): boolean {
|
|
165
|
+
for (let i = 0; i < str.length; i++) {
|
|
166
|
+
const c = str.charCodeAt(i)
|
|
167
|
+
|
|
168
|
+
// Base58 alphabet: digits, letters (not 0IOl)
|
|
169
|
+
if (
|
|
170
|
+
(c >= '1'.charCodeAt(0) && c <= '9'.charCodeAt(0)) ||
|
|
171
|
+
(c >= 'A'.charCodeAt(0) && c <= 'Z'.charCodeAt(0) && c !== 'I'.charCodeAt(0) && c !== 'O'.charCodeAt(0)) ||
|
|
172
|
+
(c >= 'a'.charCodeAt(0) && c <= 'z'.charCodeAt(0) && c !== 'l'.charCodeAt(0))
|
|
173
|
+
) {
|
|
174
|
+
continue
|
|
175
|
+
}
|
|
176
|
+
return false
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return true
|
|
180
|
+
}
|
|
@@ -0,0 +1,283 @@
|
|
|
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'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Builder for creating EVM Call intents with contract call operations.
|
|
8
|
+
* Allows chaining multiple contract calls and configuring fees and settlement parameters.
|
|
9
|
+
*/
|
|
10
|
+
export class EvmCallBuilder extends IntentBuilder {
|
|
11
|
+
protected chainId: ChainId
|
|
12
|
+
protected calls: EvmCallData[] = []
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Creates a EvmCallBuilder for the specified EVM blockchain network.
|
|
16
|
+
* @param chainId - The blockchain network identifier
|
|
17
|
+
* @returns A new EvmCallBuilder instance
|
|
18
|
+
*/
|
|
19
|
+
static forChain(chainId: ChainId): EvmCallBuilder {
|
|
20
|
+
return new EvmCallBuilder(chainId)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Creates a new EvmCallBuilder instance.
|
|
25
|
+
* @param chainId - The EVM blockchain network identifier
|
|
26
|
+
*/
|
|
27
|
+
private constructor(chainId: ChainId) {
|
|
28
|
+
super()
|
|
29
|
+
this.chainId = chainId
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Adds a contract call to the intent.
|
|
34
|
+
* @param target - The contract address to call
|
|
35
|
+
* @param data - The call data (optional, defaults to empty bytes)
|
|
36
|
+
* @param value - The native token value to send (optional, defaults to zero)
|
|
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
|
|
72
|
+
*/
|
|
73
|
+
addCallsFromBuilders(builders: EvmCallBuilder[]): EvmCallBuilder {
|
|
74
|
+
for (let i = 0; i < builders.length; i++) this.addCallsFromBuilder(builders[i])
|
|
75
|
+
return this
|
|
76
|
+
}
|
|
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
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Sets the settler address for this intent.
|
|
88
|
+
* @param settler - The settler address as an Address instance
|
|
89
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
90
|
+
*/
|
|
91
|
+
addSettler(settler: Address): EvmCallBuilder {
|
|
92
|
+
return changetype<EvmCallBuilder>(super.addSettler(settler))
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Sets the settler address from a string.
|
|
97
|
+
* @param settler - The settler address as a hex string
|
|
98
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
99
|
+
*/
|
|
100
|
+
addSettlerAsString(settler: string): EvmCallBuilder {
|
|
101
|
+
return changetype<EvmCallBuilder>(super.addSettlerAsString(settler))
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Sets the deadline for this intent.
|
|
106
|
+
* @param deadline - The deadline as a timestamp
|
|
107
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
108
|
+
*/
|
|
109
|
+
addDeadline(deadline: BigInt): EvmCallBuilder {
|
|
110
|
+
return changetype<EvmCallBuilder>(super.addDeadline(deadline))
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Sets the user address for this intent.
|
|
115
|
+
* @param user - The user address
|
|
116
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
117
|
+
*/
|
|
118
|
+
addUser(user: Address): EvmCallBuilder {
|
|
119
|
+
return changetype<EvmCallBuilder>(super.addUser(user))
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Sets the user address from a string.
|
|
124
|
+
* @param user - The user address as a hex string
|
|
125
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
126
|
+
*/
|
|
127
|
+
addUserAsString(user: string): EvmCallBuilder {
|
|
128
|
+
return changetype<EvmCallBuilder>(super.addUserAsString(user))
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Sets the nonce for this intent.
|
|
133
|
+
* @param nonce - A unique identifier to prevent replay attacks
|
|
134
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
135
|
+
*/
|
|
136
|
+
addNonce(nonce: string): EvmCallBuilder {
|
|
137
|
+
return changetype<EvmCallBuilder>(super.addNonce(nonce))
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Adds a max fee for this intent.
|
|
142
|
+
* @param fee - The max fee token amount (must be on same chain)
|
|
143
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
144
|
+
*/
|
|
145
|
+
addMaxFee(fee: TokenAmount): EvmCallBuilder {
|
|
146
|
+
if (!fee.token.hasChain(this.chainId)) throw new Error('Fee token must be on the same chain')
|
|
147
|
+
this.maxFees.push(fee)
|
|
148
|
+
return this
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Sets an event for the intent.
|
|
153
|
+
* @param topic - The topic to be indexed in the event
|
|
154
|
+
* @param data - The event data
|
|
155
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
156
|
+
*/
|
|
157
|
+
addEvent(topic: Bytes, data: Bytes): EvmCallBuilder {
|
|
158
|
+
return changetype<EvmCallBuilder>(super.addEvent(topic, data))
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Sets multiple events for the intent.
|
|
163
|
+
* @param events - The list of events to be added
|
|
164
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
165
|
+
*/
|
|
166
|
+
addEvents(events: IntentEvent[]): EvmCallBuilder {
|
|
167
|
+
return changetype<EvmCallBuilder>(super.addEvents(events))
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Builds and returns the final EvmCall intent.
|
|
172
|
+
* @returns A new EvmCall instance with all configured parameters
|
|
173
|
+
*/
|
|
174
|
+
build(): EvmCall {
|
|
175
|
+
return new EvmCall(
|
|
176
|
+
this.chainId,
|
|
177
|
+
this.calls,
|
|
178
|
+
this.maxFees,
|
|
179
|
+
this.settler,
|
|
180
|
+
this.user,
|
|
181
|
+
this.deadline,
|
|
182
|
+
this.nonce,
|
|
183
|
+
this.events
|
|
184
|
+
)
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Represents data for a single contract call within a Call intent.
|
|
190
|
+
* Contains the target address, call data, and value to send.
|
|
191
|
+
*/
|
|
192
|
+
@json
|
|
193
|
+
export class EvmCallData {
|
|
194
|
+
public target: string
|
|
195
|
+
public data: string
|
|
196
|
+
public value: string
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Creates a new EvmCallData instance.
|
|
200
|
+
* @param target - The contract address to call
|
|
201
|
+
* @param data - The call data (optional, defaults to empty bytes)
|
|
202
|
+
* @param value - The native token value to send (optional, defaults to zero)
|
|
203
|
+
*/
|
|
204
|
+
constructor(target: Address, data: Bytes = Bytes.empty(), value: BigInt = BigInt.zero()) {
|
|
205
|
+
this.target = target.toString()
|
|
206
|
+
this.data = data.toHexString()
|
|
207
|
+
this.value = value.toString()
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Represents a Call intent containing one or more contract calls to be executed.
|
|
213
|
+
*/
|
|
214
|
+
@json
|
|
215
|
+
export class EvmCall extends Intent {
|
|
216
|
+
public chainId: ChainId
|
|
217
|
+
public calls: EvmCallData[]
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Creates a EvmCall intent with a single contract call.
|
|
221
|
+
* @param chainId - The blockchain network identifier
|
|
222
|
+
* @param target - The contract address to call
|
|
223
|
+
* @param data - The call data
|
|
224
|
+
* @param maxFee - The max fee to pay for the call intent
|
|
225
|
+
* @param value - The native token value to send (optional, defaults to zero)
|
|
226
|
+
* @param settler - The settler address (optional)
|
|
227
|
+
* @param user - The user address (optional)
|
|
228
|
+
* @param deadline - The deadline timestamp (optional)
|
|
229
|
+
* @param nonce - The nonce for replay protection (optional)
|
|
230
|
+
* @returns A new Call instance
|
|
231
|
+
*/
|
|
232
|
+
static create(
|
|
233
|
+
chainId: ChainId,
|
|
234
|
+
target: Address,
|
|
235
|
+
data: Bytes,
|
|
236
|
+
maxFee: TokenAmount,
|
|
237
|
+
value: BigInt = BigInt.zero(),
|
|
238
|
+
settler: Address | null = null,
|
|
239
|
+
user: Address | null = null,
|
|
240
|
+
deadline: BigInt | null = null,
|
|
241
|
+
nonce: string | null = null,
|
|
242
|
+
events: IntentEvent[] | null = null
|
|
243
|
+
): EvmCall {
|
|
244
|
+
const callData = new EvmCallData(target, data, value)
|
|
245
|
+
return new EvmCall(chainId, [callData], [maxFee], settler, user, deadline, nonce, events)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Creates a new EvmCall intent.
|
|
250
|
+
* @param chainId - The blockchain network identifier
|
|
251
|
+
* @param calls - Array of contract calls to execute
|
|
252
|
+
* @param maxFees - The list of max fees to pay for the call intent
|
|
253
|
+
* @param settler - The settler address (optional)
|
|
254
|
+
* @param user - The user address (optional)
|
|
255
|
+
* @param deadline - The deadline timestamp (optional)
|
|
256
|
+
* @param nonce - The nonce for replay protection (optional)
|
|
257
|
+
*/
|
|
258
|
+
constructor(
|
|
259
|
+
chainId: ChainId,
|
|
260
|
+
calls: EvmCallData[],
|
|
261
|
+
maxFees: TokenAmount[],
|
|
262
|
+
settler: Address | null = null,
|
|
263
|
+
user: Address | null = null,
|
|
264
|
+
deadline: BigInt | null = null,
|
|
265
|
+
nonce: string | null = null,
|
|
266
|
+
events: IntentEvent[] | null = null
|
|
267
|
+
) {
|
|
268
|
+
const fees: MaxFee[] = maxFees.map((fee: TokenAmount) => MaxFee.fromTokenAmount(fee))
|
|
269
|
+
super(OperationType.EvmCall, chainId, fees, settler, user, deadline, nonce, events)
|
|
270
|
+
if (calls.length === 0) throw new Error('Call list cannot be empty')
|
|
271
|
+
if (maxFees.length == 0) throw new Error('At least a max fee must be specified')
|
|
272
|
+
|
|
273
|
+
this.calls = calls
|
|
274
|
+
this.chainId = chainId
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Sends this EvmCall intent to the execution environment.
|
|
279
|
+
*/
|
|
280
|
+
public send(): void {
|
|
281
|
+
environment.evmCall(this)
|
|
282
|
+
}
|
|
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
|
+
}
|