@mimicprotocol/lib-ts 0.0.1-rc.10

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.
@@ -0,0 +1,238 @@
1
+ import { environment } from '../environment'
2
+ import { TokenAmount } from '../tokens'
3
+ import { ChainId } from '../types'
4
+ import { Address, BigInt, Bytes } from '../types'
5
+
6
+ import { Intent, IntentBuilder, OperationType } from './Intent'
7
+
8
+ /**
9
+ * Builder for creating Call intents with contract call operations.
10
+ * Allows chaining multiple contract calls and configuring fees and settlement parameters.
11
+ */
12
+ export class CallBuilder extends IntentBuilder {
13
+ private chainId: ChainId
14
+ private calls: CallData[] = []
15
+ private fee: TokenAmount | null = null
16
+
17
+ /**
18
+ * Creates a CallBuilder for the specified blockchain network.
19
+ * @param chainId - The blockchain network identifier
20
+ * @returns A new CallBuilder instance
21
+ */
22
+ static forChain(chainId: ChainId): CallBuilder {
23
+ return new CallBuilder(chainId)
24
+ }
25
+
26
+ /**
27
+ * Creates a CallBuilder with a pre-configured fee.
28
+ * @param chainId - The blockchain network identifier
29
+ * @param fee - The fee token amount to be charged for the call
30
+ * @returns A new CallBuilder instance with fee already set
31
+ */
32
+ static forChainWithFee(chainId: ChainId, fee: TokenAmount): CallBuilder {
33
+ const builder = new CallBuilder(chainId)
34
+ builder.addFee(fee)
35
+ return builder
36
+ }
37
+
38
+ /**
39
+ * Creates a new CallBuilder instance.
40
+ * @param chainId - The blockchain network identifier
41
+ */
42
+ constructor(chainId: ChainId) {
43
+ super()
44
+ this.chainId = chainId
45
+ }
46
+
47
+ /**
48
+ * Adds a contract call to the intent.
49
+ * @param target - The contract address to call
50
+ * @param data - The call data (optional, defaults to empty bytes)
51
+ * @param value - The native token value to send (optional, defaults to zero)
52
+ * @returns This CallBuilder instance for method chaining
53
+ */
54
+ addCall(target: Address, data: Bytes = Bytes.empty(), value: BigInt = BigInt.zero()): CallBuilder {
55
+ this.calls.push(new CallData(target, data, value))
56
+ return this
57
+ }
58
+
59
+ /**
60
+ * Sets the fee to be charged for executing this call intent.
61
+ * @param fee - The fee token amount (must be on the same chain as the call)
62
+ * @returns This CallBuilder instance for method chaining
63
+ */
64
+ addFee(fee: TokenAmount): CallBuilder {
65
+ if (fee.token.chainId !== this.chainId) throw new Error('Fee token must be on the same chain')
66
+ this.fee = fee
67
+ return this
68
+ }
69
+
70
+ /**
71
+ * Sets the settler address for this intent.
72
+ * @param settler - The settler address as an Address instance
73
+ * @returns This CallBuilder instance for method chaining
74
+ */
75
+ addSettler(settler: Address): CallBuilder {
76
+ return changetype<CallBuilder>(super.addSettler(settler))
77
+ }
78
+
79
+ /**
80
+ * Sets the settler address from a string.
81
+ * @param settler - The settler address as a hex string
82
+ * @returns This CallBuilder instance for method chaining
83
+ */
84
+ addSettlerAsString(settler: string): CallBuilder {
85
+ return changetype<CallBuilder>(super.addSettlerAsString(settler))
86
+ }
87
+
88
+ /**
89
+ * Sets the deadline for this intent.
90
+ * @param deadline - The deadline as a timestamp
91
+ * @returns This CallBuilder instance for method chaining
92
+ */
93
+ addDeadline(deadline: BigInt): CallBuilder {
94
+ return changetype<CallBuilder>(super.addDeadline(deadline))
95
+ }
96
+
97
+ /**
98
+ * Sets the user address for this intent.
99
+ * @param user - The user address
100
+ * @returns This CallBuilder instance for method chaining
101
+ */
102
+ addUser(user: Address): CallBuilder {
103
+ return changetype<CallBuilder>(super.addUser(user))
104
+ }
105
+
106
+ /**
107
+ * Sets the user address from a string.
108
+ * @param user - The user address as a hex string
109
+ * @returns This CallBuilder instance for method chaining
110
+ */
111
+ addUserAsString(user: string): CallBuilder {
112
+ return changetype<CallBuilder>(super.addUserAsString(user))
113
+ }
114
+
115
+ /**
116
+ * Sets the nonce for this intent.
117
+ * @param nonce - A unique identifier to prevent replay attacks
118
+ * @returns This CallBuilder instance for method chaining
119
+ */
120
+ addNonce(nonce: string): CallBuilder {
121
+ return changetype<CallBuilder>(super.addNonce(nonce))
122
+ }
123
+
124
+ /**
125
+ * Builds and returns the final Call intent.
126
+ * @returns A new Call instance with all configured parameters
127
+ */
128
+ build(): Call {
129
+ if (!this.fee) throw new Error('Call fee must be specified')
130
+ return new Call(
131
+ this.chainId,
132
+ this.calls,
133
+ this.fee as TokenAmount,
134
+ this.settler,
135
+ this.user,
136
+ this.deadline,
137
+ this.nonce
138
+ )
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Represents data for a single contract call within a Call intent.
144
+ * Contains the target address, call data, and value to send.
145
+ */
146
+ @json
147
+ export class CallData {
148
+ public target: string
149
+ public data: string
150
+ public value: string
151
+
152
+ /**
153
+ * Creates a new CallData instance.
154
+ * @param target - The contract address to call
155
+ * @param data - The call data (optional, defaults to empty bytes)
156
+ * @param value - The native token value to send (optional, defaults to zero)
157
+ */
158
+ constructor(target: Address, data: Bytes = Bytes.empty(), value: BigInt = BigInt.zero()) {
159
+ this.target = target.toString()
160
+ this.data = data.toHexString()
161
+ this.value = value.toString()
162
+ }
163
+ }
164
+
165
+ /**
166
+ * Represents a Call intent containing one or more contract calls to be executed.
167
+ */
168
+ @json
169
+ export class Call extends Intent {
170
+ public chainId: ChainId
171
+ public calls: CallData[]
172
+ public feeToken: string
173
+ public feeAmount: string
174
+
175
+ /**
176
+ * Creates a Call intent with a single contract call.
177
+ * @param chainId - The blockchain network identifier
178
+ * @param target - The contract address to call
179
+ * @param data - The call data
180
+ * @param fee - The fee token amount to be charged
181
+ * @param value - The native token value to send (optional, defaults to zero)
182
+ * @param settler - The settler address (optional)
183
+ * @param user - The user address (optional)
184
+ * @param deadline - The deadline timestamp (optional)
185
+ * @param nonce - The nonce for replay protection (optional)
186
+ * @returns A new Call instance
187
+ */
188
+ static create(
189
+ chainId: ChainId,
190
+ target: Address,
191
+ data: Bytes,
192
+ fee: TokenAmount,
193
+ value: BigInt = BigInt.zero(),
194
+ settler: Address | null = null,
195
+ user: Address | null = null,
196
+ deadline: BigInt | null = null,
197
+ nonce: string | null = null
198
+ ): Call {
199
+ const callData = new CallData(target, data, value)
200
+ return new Call(chainId, [callData], fee, settler, user, deadline, nonce)
201
+ }
202
+
203
+ /**
204
+ * Creates a new Call intent.
205
+ * @param chainId - The blockchain network identifier
206
+ * @param calls - Array of contract calls to execute
207
+ * @param fee - The fee token amount to be charged
208
+ * @param settler - The settler address (optional)
209
+ * @param user - The user address (optional)
210
+ * @param deadline - The deadline timestamp (optional)
211
+ * @param nonce - The nonce for replay protection (optional)
212
+ */
213
+ constructor(
214
+ chainId: ChainId,
215
+ calls: CallData[],
216
+ fee: TokenAmount,
217
+ settler: Address | null = null,
218
+ user: Address | null = null,
219
+ deadline: BigInt | null = null,
220
+ nonce: string | null = null
221
+ ) {
222
+ super(OperationType.Call, chainId, settler, user, deadline, nonce)
223
+
224
+ if (calls.length === 0) throw new Error('Call list cannot be empty')
225
+
226
+ this.calls = calls
227
+ this.feeToken = fee.token.address.toString()
228
+ this.feeAmount = fee.amount.toString()
229
+ this.chainId = chainId
230
+ }
231
+
232
+ /**
233
+ * Sends this Call intent to the execution environment.
234
+ */
235
+ public send(): void {
236
+ environment.call(this)
237
+ }
238
+ }
@@ -0,0 +1,80 @@
1
+ import { environment } from '../environment'
2
+ import { evm } from '../evm'
3
+ import { NULL_ADDRESS } from '../helpers'
4
+ import { Address, BigInt, ChainId } from '../types'
5
+
6
+ export enum OperationType {
7
+ Swap,
8
+ Transfer,
9
+ Call,
10
+ }
11
+
12
+ const DEFAULT_DEADLINE = 5 * 60 // 5 minutes in seconds
13
+
14
+ export abstract class IntentBuilder {
15
+ protected user: Address | null = null
16
+ protected settler: Address | null = null
17
+ protected deadline: BigInt | null = null
18
+ protected nonce: string | null = null
19
+
20
+ addSettler(settler: Address): IntentBuilder {
21
+ this.settler = settler
22
+ return this
23
+ }
24
+
25
+ addSettlerAsString(settler: string): IntentBuilder {
26
+ return this.addSettler(Address.fromString(settler))
27
+ }
28
+
29
+ addDeadline(deadline: BigInt): IntentBuilder {
30
+ this.deadline = deadline
31
+ return this
32
+ }
33
+
34
+ addUser(user: Address): IntentBuilder {
35
+ this.user = user
36
+ return this
37
+ }
38
+
39
+ addUserAsString(user: string): IntentBuilder {
40
+ return this.addUser(Address.fromString(user))
41
+ }
42
+
43
+ addNonce(nonce: string): IntentBuilder {
44
+ this.nonce = nonce
45
+ return this
46
+ }
47
+
48
+ abstract build(): Intent
49
+ }
50
+
51
+ let INTENT_INDEX: u32 = 0
52
+ @json
53
+ export abstract class Intent {
54
+ public op: OperationType
55
+ public settler: string
56
+ public user: string
57
+ public deadline: string
58
+ public nonce: string
59
+
60
+ protected constructor(
61
+ op: OperationType,
62
+ chainId: ChainId,
63
+ settler: Address | null,
64
+ user: Address | null,
65
+ deadline: BigInt | null,
66
+ nonce: string | null
67
+ ) {
68
+ const context = environment.getContext()
69
+ this.op = op
70
+ this.settler = settler ? settler.toString() : context.findSettler(chainId).toString()
71
+ this.deadline = deadline ? deadline.toString() : (context.timestamp / 1000 + DEFAULT_DEADLINE).toString()
72
+ this.user = user ? user.toString() : context.user.toString()
73
+ this.nonce = nonce ? nonce : evm.keccak(`${context.configSig}${context.timestamp}${++INTENT_INDEX}`)
74
+
75
+ if (!this.user || this.user == NULL_ADDRESS) throw new Error('A user must be specified')
76
+ if (!this.settler || this.settler == NULL_ADDRESS) throw new Error('A settler contract must be specified')
77
+ }
78
+
79
+ abstract send(): void
80
+ }