@mimicprotocol/lib-ts 0.0.1-rc.9 → 0.1.0
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 +144 -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 +150 -71
- 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 +199 -0
- package/src/intents/Call/EvmDynamicCall.ts +272 -0
- package/src/intents/Call/SvmCall.ts +204 -0
- package/src/intents/Call/index.ts +3 -0
- package/src/intents/Intent.ts +347 -35
- package/src/intents/Operation.ts +114 -0
- package/src/intents/Swap.ts +127 -114
- package/src/intents/Transfer.ts +72 -123
- package/src/intents/index.ts +1 -0
- 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 +40 -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,199 @@
|
|
|
1
|
+
import { environment } from '../../environment'
|
|
2
|
+
import { TokenAmount } from '../../tokens'
|
|
3
|
+
import { Address, BigInt, Bytes, ChainId } from '../../types'
|
|
4
|
+
import { IntentBuilder } from '../Intent'
|
|
5
|
+
import { Operation, OperationBuilder, OperationEvent, OperationType } from '../Operation'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Builder for creating EVM call operations.
|
|
9
|
+
*/
|
|
10
|
+
export class EvmCallBuilder extends OperationBuilder {
|
|
11
|
+
protected chainId: ChainId
|
|
12
|
+
protected calls: EvmCallData[] = []
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Creates an 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 operation.
|
|
34
|
+
* @param target - The contract address to call
|
|
35
|
+
* @param data - The call data
|
|
36
|
+
* @param value - The native token value to send
|
|
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 operation.
|
|
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 user address for this operation.
|
|
88
|
+
* @param user - The user address
|
|
89
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
90
|
+
*/
|
|
91
|
+
addUser(user: Address): EvmCallBuilder {
|
|
92
|
+
return changetype<EvmCallBuilder>(super.addUser(user))
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Sets the user address from a string.
|
|
97
|
+
* @param user - The user address as a hex string
|
|
98
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
99
|
+
*/
|
|
100
|
+
addUserAsString(user: string): EvmCallBuilder {
|
|
101
|
+
return changetype<EvmCallBuilder>(super.addUserAsString(user))
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Sets an event for the operation.
|
|
106
|
+
* @param topic - The topic to be indexed in the event
|
|
107
|
+
* @param data - The event data
|
|
108
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
109
|
+
*/
|
|
110
|
+
addEvent(topic: Bytes, data: Bytes): EvmCallBuilder {
|
|
111
|
+
return changetype<EvmCallBuilder>(super.addEvent(topic, data))
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Sets multiple events for the operation.
|
|
116
|
+
* @param events - The list of events to be added
|
|
117
|
+
* @returns This EvmCallBuilder instance for method chaining
|
|
118
|
+
*/
|
|
119
|
+
addEvents(events: OperationEvent[]): EvmCallBuilder {
|
|
120
|
+
return changetype<EvmCallBuilder>(super.addEvents(events))
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Builds and returns the final EvmCall operation.
|
|
125
|
+
* @returns A new EvmCall instance with all configured parameters
|
|
126
|
+
*/
|
|
127
|
+
build(): EvmCall {
|
|
128
|
+
return new EvmCall(this.chainId, this.calls, this.user, this.events)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Builds this operation and sends it inside an intent with the provided fee data.
|
|
133
|
+
* @param maxFee - The max fee to pay for the intent
|
|
134
|
+
* @param feePayer - The fee payer for the intent (optional)
|
|
135
|
+
*/
|
|
136
|
+
send(maxFee: TokenAmount, feePayer: Address | null = null): void {
|
|
137
|
+
this.build().send(maxFee, feePayer)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Represents data for a single contract call within an EVM call operation.
|
|
143
|
+
* Contains the target address, call data, and value to send.
|
|
144
|
+
*/
|
|
145
|
+
@json
|
|
146
|
+
export class EvmCallData {
|
|
147
|
+
public target: string
|
|
148
|
+
public data: string
|
|
149
|
+
public value: string
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Creates a new EvmCallData instance.
|
|
153
|
+
* @param target - The contract address to call
|
|
154
|
+
* @param data - The call data
|
|
155
|
+
* @param value - The native token value to send
|
|
156
|
+
*/
|
|
157
|
+
constructor(target: Address, data: Bytes = Bytes.empty(), value: BigInt = BigInt.zero()) {
|
|
158
|
+
this.target = target.toString()
|
|
159
|
+
this.data = data.toHexString()
|
|
160
|
+
this.value = value.toString()
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Represents an EVM call operation containing one or more contract calls to be executed.
|
|
166
|
+
*/
|
|
167
|
+
@json
|
|
168
|
+
export class EvmCall extends Operation {
|
|
169
|
+
public calls: EvmCallData[]
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Creates a new EvmCall operation.
|
|
173
|
+
* @param chainId - The blockchain network identifier
|
|
174
|
+
* @param calls - Array of contract calls to execute
|
|
175
|
+
* @param user - The user address
|
|
176
|
+
* @param events - The operation events to emit
|
|
177
|
+
*/
|
|
178
|
+
constructor(
|
|
179
|
+
chainId: ChainId,
|
|
180
|
+
calls: EvmCallData[],
|
|
181
|
+
user: Address | null = null,
|
|
182
|
+
events: OperationEvent[] | null = null
|
|
183
|
+
) {
|
|
184
|
+
super(OperationType.EvmCall, chainId, user, events)
|
|
185
|
+
if (calls.length === 0) throw new Error('Call list cannot be empty')
|
|
186
|
+
this.calls = calls
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Sends this EvmCall operation wrapped in an intent.
|
|
191
|
+
* @param maxFee - The max fee to pay for the intent
|
|
192
|
+
* @param feePayer - The fee payer for the intent (optional)
|
|
193
|
+
*/
|
|
194
|
+
public send(maxFee: TokenAmount, feePayer: Address | null = null): void {
|
|
195
|
+
const intentBuilder = new IntentBuilder().addMaxFee(maxFee).addOperation(this)
|
|
196
|
+
if (feePayer) intentBuilder.addFeePayer(feePayer)
|
|
197
|
+
environment.sendIntent(intentBuilder.build())
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { environment } from '../../environment'
|
|
2
|
+
import { evm } from '../../evm'
|
|
3
|
+
import { TokenAmount } from '../../tokens'
|
|
4
|
+
import { Address, BigInt, Bytes, ChainId, EvmEncodeParam } from '../../types'
|
|
5
|
+
import { IntentBuilder } from '../Intent'
|
|
6
|
+
import { Operation, OperationBuilder, OperationEvent, OperationType } from '../Operation'
|
|
7
|
+
|
|
8
|
+
export enum EvmDynamicArgKind {
|
|
9
|
+
Literal = 0,
|
|
10
|
+
Variable = 1,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Builder for creating EVM dynamic call operations.
|
|
15
|
+
*/
|
|
16
|
+
export class EvmDynamicCallBuilder extends OperationBuilder {
|
|
17
|
+
protected chainId: ChainId
|
|
18
|
+
protected calls: EvmDynamicCallData[] = []
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Creates an EvmDynamicCallBuilder for the specified EVM blockchain network.
|
|
22
|
+
* @param chainId - The blockchain network identifier
|
|
23
|
+
* @returns A new EvmDynamicCallBuilder instance
|
|
24
|
+
*/
|
|
25
|
+
static forChain(chainId: ChainId): EvmDynamicCallBuilder {
|
|
26
|
+
return new EvmDynamicCallBuilder(chainId)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Creates a new EvmDynamicCallBuilder instance.
|
|
31
|
+
* @param chainId - The EVM blockchain network identifier
|
|
32
|
+
*/
|
|
33
|
+
private constructor(chainId: ChainId) {
|
|
34
|
+
super()
|
|
35
|
+
this.chainId = chainId
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Adds a dynamic contract call to the operation.
|
|
40
|
+
* @param target - The contract address to call
|
|
41
|
+
* @param selector - The function selector to call
|
|
42
|
+
* @param args - The dynamic call arguments
|
|
43
|
+
* @param value - The native token value to send
|
|
44
|
+
* @returns This EvmDynamicCallBuilder instance for method chaining
|
|
45
|
+
*/
|
|
46
|
+
addCall(
|
|
47
|
+
target: Address,
|
|
48
|
+
selector: Bytes,
|
|
49
|
+
args: EvmDynamicArg[] = [],
|
|
50
|
+
value: BigInt = BigInt.zero()
|
|
51
|
+
): EvmDynamicCallBuilder {
|
|
52
|
+
this.calls.push(new EvmDynamicCallData(target, selector, args, value))
|
|
53
|
+
return this
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Adds multiple dynamic contract calls to the operation.
|
|
58
|
+
* @param calls - The contract calls to add
|
|
59
|
+
* @returns This EvmDynamicCallBuilder instance for method chaining
|
|
60
|
+
*/
|
|
61
|
+
addCalls(calls: EvmDynamicCallData[]): EvmDynamicCallBuilder {
|
|
62
|
+
for (let i = 0; i < calls.length; i++) {
|
|
63
|
+
this.addCall(
|
|
64
|
+
Address.fromString(calls[i].target),
|
|
65
|
+
Bytes.fromHexString(calls[i].selector),
|
|
66
|
+
calls[i].arguments,
|
|
67
|
+
BigInt.fromString(calls[i].value)
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
return this
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Adds the calls from another EvmDynamicCallBuilder to this EvmDynamicCallBuilder.
|
|
75
|
+
* @param builder - The EvmDynamicCallBuilder to add the calls from
|
|
76
|
+
* @returns This EvmDynamicCallBuilder instance for method chaining
|
|
77
|
+
*/
|
|
78
|
+
addCallsFromBuilder(builder: EvmDynamicCallBuilder): EvmDynamicCallBuilder {
|
|
79
|
+
return this.addCalls(builder.getCalls())
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Adds the calls from multiple EvmDynamicCallBuilders to this EvmDynamicCallBuilder.
|
|
84
|
+
* @param builders - The EvmDynamicCallBuilders to add the calls from
|
|
85
|
+
* @returns This EvmDynamicCallBuilder instance for method chaining
|
|
86
|
+
*/
|
|
87
|
+
addCallsFromBuilders(builders: EvmDynamicCallBuilder[]): EvmDynamicCallBuilder {
|
|
88
|
+
for (let i = 0; i < builders.length; i++) this.addCallsFromBuilder(builders[i])
|
|
89
|
+
return this
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Returns a copy of the calls array.
|
|
94
|
+
* @returns A copy of the calls array
|
|
95
|
+
*/
|
|
96
|
+
getCalls(): EvmDynamicCallData[] {
|
|
97
|
+
return this.calls.slice(0)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Sets the user address for this operation.
|
|
102
|
+
* @param user - The user address
|
|
103
|
+
* @returns This EvmDynamicCallBuilder instance for method chaining
|
|
104
|
+
*/
|
|
105
|
+
addUser(user: Address): EvmDynamicCallBuilder {
|
|
106
|
+
return changetype<EvmDynamicCallBuilder>(super.addUser(user))
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Sets the user address from a string.
|
|
111
|
+
* @param user - The user address as a hex string
|
|
112
|
+
* @returns This EvmDynamicCallBuilder instance for method chaining
|
|
113
|
+
*/
|
|
114
|
+
addUserAsString(user: string): EvmDynamicCallBuilder {
|
|
115
|
+
return changetype<EvmDynamicCallBuilder>(super.addUserAsString(user))
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Sets an event for the operation.
|
|
120
|
+
* @param topic - The topic to be indexed in the event
|
|
121
|
+
* @param data - The event data
|
|
122
|
+
* @returns This EvmDynamicCallBuilder instance for method chaining
|
|
123
|
+
*/
|
|
124
|
+
addEvent(topic: Bytes, data: Bytes): EvmDynamicCallBuilder {
|
|
125
|
+
return changetype<EvmDynamicCallBuilder>(super.addEvent(topic, data))
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Sets multiple events for the operation.
|
|
130
|
+
* @param events - The list of events to be added
|
|
131
|
+
* @returns This EvmDynamicCallBuilder instance for method chaining
|
|
132
|
+
*/
|
|
133
|
+
addEvents(events: OperationEvent[]): EvmDynamicCallBuilder {
|
|
134
|
+
return changetype<EvmDynamicCallBuilder>(super.addEvents(events))
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Builds and returns the final EvmDynamicCall operation.
|
|
139
|
+
* @returns A new EvmDynamicCall instance with all configured parameters
|
|
140
|
+
*/
|
|
141
|
+
build(): EvmDynamicCall {
|
|
142
|
+
return new EvmDynamicCall(this.chainId, this.calls, this.user, this.events)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Builds this operation and sends it inside an intent with the provided fee data.
|
|
147
|
+
* @param maxFee - The max fee to pay for the intent
|
|
148
|
+
* @param feePayer - The fee payer for the intent (optional)
|
|
149
|
+
*/
|
|
150
|
+
send(maxFee: TokenAmount, feePayer: Address | null = null): void {
|
|
151
|
+
this.build().send(maxFee, feePayer)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Represents a single dynamic argument in a dynamic call.
|
|
157
|
+
*/
|
|
158
|
+
@json
|
|
159
|
+
export class EvmDynamicArg {
|
|
160
|
+
public kind: EvmDynamicArgKind
|
|
161
|
+
public data: string
|
|
162
|
+
public isDynamic: bool
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Creates a literal dynamic argument from ABI-encoded parameters.
|
|
166
|
+
* @param parameters - The ABI parameters to encode as a literal argument
|
|
167
|
+
* @param isDynamic - Whether the resolved argument is ABI-dynamic
|
|
168
|
+
* @returns A new literal dynamic argument
|
|
169
|
+
*/
|
|
170
|
+
static literal(parameters: EvmEncodeParam[], isDynamic: bool): EvmDynamicArg {
|
|
171
|
+
return new EvmDynamicArg(EvmDynamicArgKind.Literal, Bytes.fromHexString(evm.encode(parameters)), isDynamic)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Creates a variable reference dynamic argument.
|
|
176
|
+
* @param opIndex - The referenced operation index
|
|
177
|
+
* @param subIndex - The referenced output index within the operation
|
|
178
|
+
* @param isDynamic - Whether the resolved argument is ABI-dynamic
|
|
179
|
+
* @returns A new variable dynamic argument
|
|
180
|
+
*/
|
|
181
|
+
static variable(opIndex: u32, subIndex: u32, isDynamic: bool): EvmDynamicArg {
|
|
182
|
+
return new EvmDynamicArg(
|
|
183
|
+
EvmDynamicArgKind.Variable,
|
|
184
|
+
Bytes.fromHexString(
|
|
185
|
+
evm.encode([
|
|
186
|
+
EvmEncodeParam.fromValue('uint256', BigInt.fromU32(opIndex)),
|
|
187
|
+
EvmEncodeParam.fromValue('uint256', BigInt.fromU32(subIndex)),
|
|
188
|
+
])
|
|
189
|
+
),
|
|
190
|
+
isDynamic
|
|
191
|
+
)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Creates a new EvmDynamicArg instance.
|
|
196
|
+
* @param kind - The argument resolution strategy
|
|
197
|
+
* @param data - The ABI-encoded argument data
|
|
198
|
+
* @param isDynamic - Whether the resolved argument is ABI-dynamic
|
|
199
|
+
*/
|
|
200
|
+
constructor(kind: EvmDynamicArgKind, data: Bytes, isDynamic: bool) {
|
|
201
|
+
this.kind = kind
|
|
202
|
+
this.data = data.toHexString()
|
|
203
|
+
this.isDynamic = isDynamic
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Represents data for a single dynamic contract call within an EVM dynamic call operation.
|
|
209
|
+
*/
|
|
210
|
+
@json
|
|
211
|
+
export class EvmDynamicCallData {
|
|
212
|
+
public target: string
|
|
213
|
+
public value: string
|
|
214
|
+
public selector: string
|
|
215
|
+
public arguments: EvmDynamicArg[]
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Creates a new EvmDynamicCallData instance.
|
|
219
|
+
* @param target - The contract address to call
|
|
220
|
+
* @param selector - The function selector to call
|
|
221
|
+
* @param args - The dynamic arguments for the call
|
|
222
|
+
* @param value - The native token value to send
|
|
223
|
+
*/
|
|
224
|
+
constructor(target: Address, selector: Bytes, args: EvmDynamicArg[] = [], value: BigInt = BigInt.zero()) {
|
|
225
|
+
if (selector.length !== 4) throw new Error('Selector must be 4 bytes')
|
|
226
|
+
this.target = target.toString()
|
|
227
|
+
this.value = value.toString()
|
|
228
|
+
this.selector = selector.toHexString()
|
|
229
|
+
this.arguments = new Array<EvmDynamicArg>(args.length)
|
|
230
|
+
for (let i = 0; i < args.length; i++) {
|
|
231
|
+
const argument = args[i]
|
|
232
|
+
this.arguments[i] = new EvmDynamicArg(argument.kind, Bytes.fromHexString(argument.data), argument.isDynamic)
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Represents an EVM dynamic call operation containing one or more dynamic contract calls.
|
|
239
|
+
*/
|
|
240
|
+
@json
|
|
241
|
+
export class EvmDynamicCall extends Operation {
|
|
242
|
+
public calls: EvmDynamicCallData[]
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Creates a new EvmDynamicCall operation.
|
|
246
|
+
* @param chainId - The blockchain network identifier
|
|
247
|
+
* @param calls - Array of dynamic contract calls to execute
|
|
248
|
+
* @param user - The user address
|
|
249
|
+
* @param events - The operation events to emit
|
|
250
|
+
*/
|
|
251
|
+
constructor(
|
|
252
|
+
chainId: ChainId,
|
|
253
|
+
calls: EvmDynamicCallData[],
|
|
254
|
+
user: Address | null = null,
|
|
255
|
+
events: OperationEvent[] | null = null
|
|
256
|
+
) {
|
|
257
|
+
super(OperationType.EvmDynamicCall, chainId, user, events)
|
|
258
|
+
if (calls.length === 0) throw new Error('Call list cannot be empty')
|
|
259
|
+
this.calls = calls
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Sends this EvmDynamicCall operation wrapped in an intent.
|
|
264
|
+
* @param maxFee - The max fee to pay for the intent
|
|
265
|
+
* @param feePayer - The fee payer for the intent (optional)
|
|
266
|
+
*/
|
|
267
|
+
public send(maxFee: TokenAmount, feePayer: Address | null = null): void {
|
|
268
|
+
const intentBuilder = new IntentBuilder().addMaxFee(maxFee).addOperation(this)
|
|
269
|
+
if (feePayer) intentBuilder.addFeePayer(feePayer)
|
|
270
|
+
environment.sendIntent(intentBuilder.build())
|
|
271
|
+
}
|
|
272
|
+
}
|