@mimicprotocol/lib-ts 0.0.1-rc.17 → 0.0.1-rc.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mimicprotocol/lib-ts",
3
- "version": "0.0.1-rc.17",
3
+ "version": "0.0.1-rc.18",
4
4
  "license": "GPL-3.0",
5
5
  "private": false,
6
6
  "type": "module",
@@ -1,4 +1,5 @@
1
1
  import { Address, ChainId } from '../types'
2
+ import { TriggerType } from '../types/TriggerType'
2
3
 
3
4
  @json
4
5
  export class SerializableSettler {
@@ -19,6 +20,14 @@ export class Settler {
19
20
  }
20
21
  }
21
22
 
23
+ @json
24
+ export class Trigger {
25
+ constructor(
26
+ public type: TriggerType,
27
+ public data: string
28
+ ) {}
29
+ }
30
+
22
31
  @json
23
32
  export class SerializableContext {
24
33
  constructor(
@@ -26,7 +35,8 @@ export class SerializableContext {
26
35
  public readonly consensusThreshold: u8,
27
36
  public user: string,
28
37
  public settlers: SerializableSettler[],
29
- public configSig: string
38
+ public configSig: string,
39
+ public trigger: Trigger
30
40
  ) {}
31
41
  }
32
42
 
@@ -36,7 +46,8 @@ export class Context {
36
46
  public readonly consensusThreshold: u8,
37
47
  public user: Address,
38
48
  public settlers: Settler[],
39
- public configSig: string
49
+ public configSig: string,
50
+ public trigger: Trigger
40
51
  ) {}
41
52
 
42
53
  static fromSerializable(serializable: SerializableContext): Context {
@@ -45,7 +56,8 @@ export class Context {
45
56
  serializable.consensusThreshold,
46
57
  Address.fromString(serializable.user),
47
58
  serializable.settlers.map<Settler>((s) => Settler.fromSerializable(s)),
48
- serializable.configSig
59
+ serializable.configSig,
60
+ serializable.trigger
49
61
  )
50
62
  }
51
63
 
@@ -1,3 +1,6 @@
1
+ import { evm } from '../evm'
2
+ import { BigInt, EvmDecodeParam } from '../types'
3
+
1
4
  export interface Stringable {
2
5
  toString(): string
3
6
  }
@@ -12,3 +15,7 @@ export function serialize<T extends Stringable>(elem: T): string {
12
15
  if (elem instanceof Serializable) return elem.serialize()
13
16
  return elem.toString()
14
17
  }
18
+
19
+ export function deserializeCronTriggerData(data: string): BigInt {
20
+ return BigInt.fromString(evm.decode(new EvmDecodeParam('uint256', data)))
21
+ }
@@ -3,7 +3,7 @@ import { TokenAmount } from '../tokens'
3
3
  import { ChainId } from '../types'
4
4
  import { Address, BigInt, Bytes } from '../types'
5
5
 
6
- import { Intent, IntentBuilder, MaxFee, OperationType } from './Intent'
6
+ import { Intent, IntentBuilder, IntentEvent, MaxFee, OperationType } from './Intent'
7
7
 
8
8
  /**
9
9
  * Builder for creating Call intents with contract call operations.
@@ -108,12 +108,40 @@ export class CallBuilder extends IntentBuilder {
108
108
  return this
109
109
  }
110
110
 
111
+ /**
112
+ * Sets an event for the intent.
113
+ * @param topic - The topic to be indexed in the event
114
+ * @param data - The event data
115
+ * @returns This CallBuilder instance for method chaining
116
+ */
117
+ addEvent(topic: Bytes, data: Bytes): CallBuilder {
118
+ return changetype<CallBuilder>(super.addEvent(topic, data))
119
+ }
120
+
121
+ /**
122
+ * Sets multiple events for the intent.
123
+ * @param events - The list of events to be added
124
+ * @returns This CallBuilder instance for method chaining
125
+ */
126
+ addEvents(events: IntentEvent[]): CallBuilder {
127
+ return changetype<CallBuilder>(super.addEvents(events))
128
+ }
129
+
111
130
  /**
112
131
  * Builds and returns the final Call intent.
113
132
  * @returns A new Call instance with all configured parameters
114
133
  */
115
134
  build(): Call {
116
- return new Call(this.chainId, this.calls, this.maxFees, this.settler, this.user, this.deadline, this.nonce)
135
+ return new Call(
136
+ this.chainId,
137
+ this.calls,
138
+ this.maxFees,
139
+ this.settler,
140
+ this.user,
141
+ this.deadline,
142
+ this.nonce,
143
+ this.events
144
+ )
117
145
  }
118
146
  }
119
147
 
@@ -170,10 +198,11 @@ export class Call extends Intent {
170
198
  settler: Address | null = null,
171
199
  user: Address | null = null,
172
200
  deadline: BigInt | null = null,
173
- nonce: string | null = null
201
+ nonce: string | null = null,
202
+ events: IntentEvent[] | null = null
174
203
  ): Call {
175
204
  const callData = new CallData(target, data, value)
176
- return new Call(chainId, [callData], [maxFee], settler, user, deadline, nonce)
205
+ return new Call(chainId, [callData], [maxFee], settler, user, deadline, nonce, events)
177
206
  }
178
207
 
179
208
  /**
@@ -193,10 +222,11 @@ export class Call extends Intent {
193
222
  settler: Address | null = null,
194
223
  user: Address | null = null,
195
224
  deadline: BigInt | null = null,
196
- nonce: string | null = null
225
+ nonce: string | null = null,
226
+ events: IntentEvent[] | null = null
197
227
  ) {
198
228
  const fees: MaxFee[] = maxFees.map((fee: TokenAmount) => MaxFee.fromTokenAmount(fee))
199
- super(OperationType.Call, chainId, fees, settler, user, deadline, nonce)
229
+ super(OperationType.Call, chainId, fees, settler, user, deadline, nonce, events)
200
230
  if (calls.length === 0) throw new Error('Call list cannot be empty')
201
231
  if (maxFees.length == 0) throw new Error('At least a max fee must be specified')
202
232
 
@@ -2,7 +2,7 @@ import { environment } from '../environment'
2
2
  import { evm } from '../evm'
3
3
  import { NULL_ADDRESS } from '../helpers'
4
4
  import { Token, TokenAmount } from '../tokens'
5
- import { Address, BigInt, ChainId } from '../types'
5
+ import { Address, BigInt, Bytes, ChainId } from '../types'
6
6
 
7
7
  export enum OperationType {
8
8
  Swap,
@@ -21,6 +21,7 @@ export abstract class IntentBuilder {
21
21
  protected deadline: BigInt | null = null
22
22
  protected nonce: string | null = null
23
23
  protected maxFees: TokenAmount[] = []
24
+ protected events: IntentEvent[] = []
24
25
 
25
26
  /**
26
27
  * Sets the settler address for this intent.
@@ -80,6 +81,30 @@ export abstract class IntentBuilder {
80
81
  return this
81
82
  }
82
83
 
84
+ /**
85
+ * Sets an event for the intent.
86
+ * @param topic - The topic to be indexed in the event
87
+ * @param data - The event data
88
+ * @returns This IntentBuilder instance for method chaining
89
+ */
90
+ addEvent(topic: Bytes, data: Bytes): IntentBuilder {
91
+ const event = new IntentEvent(topic, data)
92
+ this.events.push(event)
93
+ return this
94
+ }
95
+
96
+ /**
97
+ * Sets multiple events for the intent.
98
+ * @param events - The list of events to be added
99
+ * @returns This IntentBuilder instance for method chaining
100
+ */
101
+ addEvents(events: IntentEvent[]): IntentBuilder {
102
+ for (let i = 0; i < events.length; i++) {
103
+ this.events.push(events[i])
104
+ }
105
+ return this
106
+ }
107
+
83
108
  /**
84
109
  * Adds a max fee for this intent.
85
110
  * @param fee - The max fee token amount (must be on same chain)
@@ -153,6 +178,26 @@ export class MaxFee {
153
178
  }
154
179
  }
155
180
 
181
+ /**
182
+ * Represents an intent event.
183
+ * Specifies the topic and data for the event. The topic is an indexed parameter for the EVM events.
184
+ */
185
+ @json
186
+ export class IntentEvent {
187
+ topic: string
188
+ data: string
189
+
190
+ /**
191
+ * Creates a new Intent Event instance.
192
+ * @param topic - the topic that is going to be index in the event
193
+ * @param data - The event data
194
+ */
195
+ constructor(topic: Bytes, data: Bytes) {
196
+ this.topic = topic.toHexString()
197
+ this.data = data.toHexString()
198
+ }
199
+ }
200
+
156
201
  let INTENT_INDEX: u32 = 0
157
202
  @json
158
203
  export abstract class Intent {
@@ -162,6 +207,7 @@ export abstract class Intent {
162
207
  public deadline: string
163
208
  public nonce: string
164
209
  public maxFees: MaxFee[]
210
+ public events: IntentEvent[]
165
211
 
166
212
  /**
167
213
  * Creates a new intent.
@@ -180,7 +226,8 @@ export abstract class Intent {
180
226
  settler: Address | null,
181
227
  user: Address | null,
182
228
  deadline: BigInt | null,
183
- nonce: string | null
229
+ nonce: string | null,
230
+ events: IntentEvent[] | null
184
231
  ) {
185
232
  const context = environment.getContext()
186
233
  this.op = op
@@ -188,7 +235,10 @@ export abstract class Intent {
188
235
  this.settler = settler ? settler.toString() : context.findSettler(chainId).toString()
189
236
  this.deadline = deadline ? deadline.toString() : (context.timestamp / 1000 + DEFAULT_DEADLINE).toString()
190
237
  this.user = user ? user.toString() : context.user.toString()
191
- this.nonce = nonce ? nonce : evm.keccak(`${context.configSig}${context.timestamp}${++INTENT_INDEX}`)
238
+ this.events = events || []
239
+ this.nonce = nonce
240
+ ? nonce
241
+ : evm.keccak(`${context.configSig}${context.timestamp}${context.trigger.data}${++INTENT_INDEX}`)
192
242
 
193
243
  if (!this.user || this.user == NULL_ADDRESS) throw new Error('A user must be specified')
194
244
  if (!this.settler || this.settler == NULL_ADDRESS) throw new Error('A settler contract must be specified')
@@ -1,8 +1,8 @@
1
1
  import { environment } from '../environment'
2
2
  import { Token, TokenAmount } from '../tokens'
3
- import { Address, BigInt, ChainId } from '../types'
3
+ import { Address, BigInt, Bytes, ChainId } from '../types'
4
4
 
5
- import { Intent, IntentBuilder, MaxFee, OperationType } from './Intent'
5
+ import { Intent, IntentBuilder, IntentEvent, MaxFee, OperationType } from './Intent'
6
6
 
7
7
  /**
8
8
  * Builder for creating Swap intents with token exchange operations.
@@ -215,6 +215,25 @@ export class SwapBuilder extends IntentBuilder {
215
215
  return this
216
216
  }
217
217
 
218
+ /**
219
+ * Sets an event for the intent.
220
+ * @param topic - The topic to be indexed in the event
221
+ * @param data - The event data
222
+ * @returns This SwapBuilder instance for method chaining
223
+ */
224
+ addEvent(topic: Bytes, data: Bytes): SwapBuilder {
225
+ return changetype<SwapBuilder>(super.addEvent(topic, data))
226
+ }
227
+
228
+ /**
229
+ * Sets multiple events for the intent.
230
+ * @param events - The list of events to be added
231
+ * @returns This SwapBuilder instance for method chaining
232
+ */
233
+ addEvents(events: IntentEvent[]): SwapBuilder {
234
+ return changetype<SwapBuilder>(super.addEvents(events))
235
+ }
236
+
218
237
  /**
219
238
  * Builds and returns the final Swap intent.
220
239
  * @returns A new Swap instance with all configured parameters
@@ -231,7 +250,8 @@ export class SwapBuilder extends IntentBuilder {
231
250
  this.user,
232
251
  this.deadline,
233
252
  this.nonce,
234
- this.maxFees
253
+ this.maxFees,
254
+ this.events
235
255
  )
236
256
  }
237
257
  }
@@ -388,13 +408,14 @@ export class Swap extends Intent {
388
408
  settler: Address | null = null,
389
409
  user: Address | null = null,
390
410
  deadline: BigInt | null = null,
391
- nonce: string | null = null
411
+ nonce: string | null = null,
412
+ events: IntentEvent[] | null = null
392
413
  ): Swap {
393
414
  const context = environment.getContext()
394
415
  const recipient = user || context.user
395
416
  const swapIn = TokenIn.fromBigInt(tokenIn, amountIn)
396
417
  const swapOut = TokenOut.fromBigInt(tokenOut, minAmountOut, recipient)
397
- return new Swap(chainId, [swapIn], [swapOut], chainId, settler, user, deadline, nonce)
418
+ return new Swap(chainId, [swapIn], [swapOut], chainId, settler, user, deadline, nonce, [], events)
398
419
  }
399
420
 
400
421
  /**
@@ -418,10 +439,11 @@ export class Swap extends Intent {
418
439
  user: Address | null = null,
419
440
  deadline: BigInt | null = null,
420
441
  nonce: string | null = null,
421
- maxFees: TokenAmount[] | null = null
442
+ maxFees: TokenAmount[] | null = null,
443
+ events: IntentEvent[] | null = null
422
444
  ) {
423
445
  const fees: MaxFee[] = maxFees ? maxFees.map((fee: TokenAmount) => MaxFee.fromTokenAmount(fee)) : []
424
- super(OperationType.Swap, sourceChain, fees, settler, user, deadline, nonce)
446
+ super(OperationType.Swap, sourceChain, fees, settler, user, deadline, nonce, events)
425
447
  if (tokensIn.length === 0) throw new Error('TokenIn list cannot be empty')
426
448
  if (tokensOut.length === 0) throw new Error('TokenOut list cannot be empty')
427
449
  }
@@ -1,8 +1,8 @@
1
1
  import { environment } from '../environment'
2
2
  import { ERC20Token, Token, TokenAmount } from '../tokens'
3
- import { Address, BigInt, ChainId } from '../types'
3
+ import { Address, BigInt, Bytes, ChainId } from '../types'
4
4
 
5
- import { Intent, IntentBuilder, MaxFee, OperationType } from './Intent'
5
+ import { Intent, IntentBuilder, IntentEvent, MaxFee, OperationType } from './Intent'
6
6
 
7
7
  /**
8
8
  * Builder for creating Transfer intents with token transfer operations.
@@ -173,12 +173,40 @@ export class TransferBuilder extends IntentBuilder {
173
173
  return this
174
174
  }
175
175
 
176
+ /**
177
+ * Sets an event for the intent.
178
+ * @param topic - The topic to be indexed in the event
179
+ * @param data - The event data
180
+ * @returns This TransferBuilder instance for method chaining
181
+ */
182
+ addEvent(topic: Bytes, data: Bytes): TransferBuilder {
183
+ return changetype<TransferBuilder>(super.addEvent(topic, data))
184
+ }
185
+
186
+ /**
187
+ * Sets multiple events for the intent.
188
+ * @param events - The list of events to be added
189
+ * @returns This TransferBuilder instance for method chaining
190
+ */
191
+ addEvents(events: IntentEvent[]): TransferBuilder {
192
+ return changetype<TransferBuilder>(super.addEvents(events))
193
+ }
194
+
176
195
  /**
177
196
  * Builds and returns the final Transfer intent.
178
197
  * @returns A new Transfer instance with all configured parameters
179
198
  */
180
199
  build(): Transfer {
181
- return new Transfer(this.chainId, this.transfers, this.maxFees, this.settler, this.user, this.deadline, this.nonce)
200
+ return new Transfer(
201
+ this.chainId,
202
+ this.transfers,
203
+ this.maxFees,
204
+ this.settler,
205
+ this.user,
206
+ this.deadline,
207
+ this.nonce,
208
+ this.events
209
+ )
182
210
  }
183
211
  }
184
212
 
@@ -276,7 +304,8 @@ export class Transfer extends Intent {
276
304
  settler: Address | null = null,
277
305
  user: Address | null = null,
278
306
  deadline: BigInt | null = null,
279
- nonce: string | null = null
307
+ nonce: string | null = null,
308
+ events: IntentEvent[] | null = null
280
309
  ): Transfer {
281
310
  const transferAmount = TokenAmount.fromBigInt(token, amount)
282
311
  const transferData = TransferData.fromTokenAmount(transferAmount, recipient)
@@ -288,7 +317,8 @@ export class Transfer extends Intent {
288
317
  settler,
289
318
  user,
290
319
  deadline,
291
- nonce
320
+ nonce,
321
+ events
292
322
  )
293
323
  }
294
324
 
@@ -309,10 +339,11 @@ export class Transfer extends Intent {
309
339
  settler: Address | null = null,
310
340
  user: Address | null = null,
311
341
  deadline: BigInt | null = null,
312
- nonce: string | null = null
342
+ nonce: string | null = null,
343
+ events: IntentEvent[] | null = null
313
344
  ) {
314
345
  const fees: MaxFee[] = maxFees.map((fee: TokenAmount) => MaxFee.fromTokenAmount(fee))
315
- super(OperationType.Transfer, chainId, fees, settler, user, deadline, nonce)
346
+ super(OperationType.Transfer, chainId, fees, settler, user, deadline, nonce, events)
316
347
  if (transfers.length === 0) throw new Error('Transfer list cannot be empty')
317
348
  if (maxFees.length == 0) throw new Error('At least a max fee must be specified')
318
349
 
package/src/log.ts CHANGED
@@ -4,6 +4,8 @@
4
4
  // Copyright (c) 2018 Graph Protocol, Inc. and contributors.
5
5
  // Modified by Mimic Protocol, 2025.
6
6
 
7
+ import { Stringable } from "./helpers"
8
+
7
9
  export namespace log {
8
10
  @external('log', '_log')
9
11
  declare function _log(level: Level, msg: string): void
@@ -22,7 +24,7 @@ export namespace log {
22
24
  * @param msg Format string like "Value = {}, other = {}".
23
25
  * @param args Format string arguments.
24
26
  */
25
- export function critical(msg: string, args: Array<string> = []): void {
27
+ export function critical<T extends Stringable>(msg: string, args: Array<T> = []): void {
26
28
  _log(Level.CRITICAL, format(msg, args))
27
29
  }
28
30
 
@@ -32,7 +34,7 @@ export namespace log {
32
34
  * @param msg Format string like "Value = {}, other = {}".
33
35
  * @param args Format string arguments.
34
36
  */
35
- export function error(msg: string, args: Array<string> = []): void {
37
+ export function error<T extends Stringable>(msg: string, args: Array<T> = []): void {
36
38
  _log(Level.ERROR, format(msg, args))
37
39
  }
38
40
 
@@ -41,7 +43,7 @@ export namespace log {
41
43
  * @param msg Format string like "Value = {}, other = {}".
42
44
  * @param args Format string arguments.
43
45
  */
44
- export function warning(msg: string, args: Array<string> = []): void {
46
+ export function warning<T extends Stringable>(msg: string, args: Array<T> = []): void {
45
47
  _log(Level.WARNING, format(msg, args))
46
48
  }
47
49
 
@@ -50,7 +52,7 @@ export namespace log {
50
52
  * @param msg Format string like "Value = {}, other = {}".
51
53
  * @param args Format string arguments.
52
54
  */
53
- export function info(msg: string, args: Array<string> = []): void {
55
+ export function info<T extends Stringable>(msg: string, args: Array<T> = []): void {
54
56
  _log(Level.INFO, format(msg, args))
55
57
  }
56
58
 
@@ -59,20 +61,21 @@ export namespace log {
59
61
  * @param msg Format string like "Value = {}, other = {}".
60
62
  * @param args Format string arguments.
61
63
  */
62
- export function debug(msg: string, args: Array<string> = []): void {
64
+ export function debug<T extends Stringable>(msg: string, args: Array<T> = []): void {
63
65
  _log(Level.DEBUG, format(msg, args))
64
66
  }
65
67
  }
66
68
 
67
- function format(fmt: string, args: string[]): string {
69
+ function format<T extends Stringable>(fmt: string, args: Array<T>): string {
68
70
  let out = ''
69
71
  let argIndex = 0
72
+ const argsStr = args.map<string>(a => a.toString())
70
73
  for (let i: i32 = 0, len: i32 = fmt.length; i < len; i++) {
71
74
  if (i < len - 1 && fmt.charCodeAt(i) == 0x7b /* '{' */ && fmt.charCodeAt(i + 1) == 0x7d /* '}' */) {
72
- if (argIndex >= args.length) {
75
+ if (argIndex >= argsStr.length) {
73
76
  throw new Error('Too few arguments for format string: ' + fmt)
74
77
  } else {
75
- out += args[argIndex++]
78
+ out += argsStr[argIndex++]
76
79
  i++
77
80
  }
78
81
  } else {
@@ -86,4 +86,13 @@ export abstract class BlockchainToken extends Token {
86
86
  hasChain(chain: ChainId): boolean {
87
87
  return this._chainId === chain
88
88
  }
89
+
90
+ /**
91
+ * Tells the string representation of this token.
92
+ * @returns The token address and chain ID along with symbol if present
93
+ */
94
+ toString(): string {
95
+ const description = 'Token ' + this.address.toString() + ' on chain ' + this.chainId.toString()
96
+ return description + (this._symbol ? ' (' + this._symbol + ')' : '')
97
+ }
89
98
  }
@@ -59,4 +59,12 @@ export class DenominationToken extends Token {
59
59
  hasChain(chain: ChainId): boolean {
60
60
  return true
61
61
  }
62
+
63
+ /**
64
+ * Tells the string representation of this token.
65
+ * @returns The token symbol
66
+ */
67
+ toString(): string {
68
+ return this.symbol
69
+ }
62
70
  }
@@ -77,9 +77,7 @@ export abstract class Token {
77
77
 
78
78
  /**
79
79
  * Tells the string representation of this token.
80
- * @returns The token symbol
80
+ * @returns The string representation of the token
81
81
  */
82
- toString(): string {
83
- return this.symbol
84
- }
82
+ abstract toString(): string
85
83
  }
@@ -0,0 +1,4 @@
1
+ export enum TriggerType {
2
+ CRON,
3
+ EVENT,
4
+ }