@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.
Files changed (77) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/README.md +7 -7
  3. package/constants.d.ts +1 -0
  4. package/constants.js +1 -0
  5. package/index.ts +3 -0
  6. package/package.json +18 -4
  7. package/src/chains/Arbitrum.ts +14 -0
  8. package/src/chains/Avalanche.ts +15 -0
  9. package/src/chains/BNB.ts +15 -0
  10. package/src/chains/Base.ts +14 -0
  11. package/src/chains/BaseSepolia.ts +7 -0
  12. package/src/chains/Ethereum.ts +7 -7
  13. package/src/chains/Gnosis.ts +14 -0
  14. package/src/chains/Optimism.ts +7 -7
  15. package/src/chains/Polygon.ts +10 -7
  16. package/src/chains/Sonic.ts +13 -0
  17. package/src/chains/index.ts +7 -0
  18. package/src/context/Context.ts +102 -7
  19. package/src/environment.ts +165 -53
  20. package/src/evm.ts +5 -4
  21. package/src/helpers/BorshDeserializer.ts +133 -0
  22. package/src/helpers/consensus.ts +35 -0
  23. package/src/helpers/constants.ts +7 -1
  24. package/src/helpers/index.ts +5 -0
  25. package/src/helpers/math.ts +20 -0
  26. package/src/helpers/serialize.ts +5 -125
  27. package/src/helpers/strings.ts +82 -5
  28. package/src/intents/Call/EvmCall.ts +283 -0
  29. package/src/intents/Call/SvmCall.ts +278 -0
  30. package/src/intents/Call/index.ts +2 -0
  31. package/src/intents/Intent.ts +178 -5
  32. package/src/intents/Swap.ts +136 -44
  33. package/src/intents/Transfer.ts +103 -58
  34. package/src/log.ts +83 -0
  35. package/src/queries/EvmCallQuery.ts +43 -0
  36. package/src/queries/QueryResponse.ts +26 -0
  37. package/src/queries/RelevantTokensQuery.ts +82 -0
  38. package/src/queries/SubgraphQuery.ts +50 -0
  39. package/src/queries/SvmAccountsInfoQuery.ts +65 -0
  40. package/src/queries/TokenPriceQuery.ts +47 -0
  41. package/src/queries/index.ts +6 -1
  42. package/src/storage/index.ts +1 -0
  43. package/src/storage/storage.ts +46 -0
  44. package/src/svm.ts +27 -0
  45. package/src/tokens/BlockchainToken.ts +108 -0
  46. package/src/tokens/DenominationToken.ts +70 -0
  47. package/src/tokens/ERC20Token.ts +192 -0
  48. package/src/tokens/SPLToken.ts +162 -0
  49. package/src/tokens/Token.ts +55 -155
  50. package/src/tokens/TokenAmount.ts +72 -30
  51. package/src/tokens/TokenProvider.ts +54 -0
  52. package/src/tokens/Tokens.ts +186 -0
  53. package/src/tokens/USD.ts +9 -6
  54. package/src/tokens/index.ts +6 -0
  55. package/src/types/Address.ts +86 -14
  56. package/src/types/BigInt.ts +14 -22
  57. package/src/types/ByteArray.ts +41 -3
  58. package/src/types/Bytes.ts +7 -0
  59. package/src/types/ChainId.ts +9 -1
  60. package/src/types/Option.ts +35 -0
  61. package/src/types/Result.ts +68 -0
  62. package/src/types/TriggerType.ts +4 -0
  63. package/src/types/evm/EvmDecodeParam.ts +7 -0
  64. package/src/types/evm/EvmEncodeParam.ts +31 -0
  65. package/src/types/evm/index.ts +2 -0
  66. package/src/types/index.ts +8 -2
  67. package/src/types/svm/SvmAccountInfo.ts +32 -0
  68. package/src/types/svm/SvmAccountMeta.ts +28 -0
  69. package/src/types/svm/SvmFindProgramAddress.ts +32 -0
  70. package/src/types/svm/SvmMint.ts +44 -0
  71. package/src/types/svm/SvmPdaSeed.ts +19 -0
  72. package/src/types/svm/SvmTokenMetadataData.ts +29 -0
  73. package/src/types/svm/index.ts +5 -0
  74. package/src/intents/Call.ts +0 -238
  75. package/src/queries/Call.ts +0 -16
  76. package/src/types/EvmDecodeParam.ts +0 -30
  77. package/src/types/EvmEncodeParam.ts +0 -54
@@ -1,5 +1,9 @@
1
- export function bytesToString(bytes: Uint8Array): string {
2
- return String.UTF8.decodeUnsafe(bytes.dataStart, bytes.length)
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
- } else if (newDecimalPos >= fullDigits.length) {
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
+ }
@@ -0,0 +1,2 @@
1
+ export * from './EvmCall'
2
+ export * from './SvmCall'