@spectratools/aborean-cli 0.2.0 → 0.4.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.
Files changed (2) hide show
  1. package/dist/cli.js +2132 -105
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -4,7 +4,12 @@
4
4
  import { readFileSync } from "fs";
5
5
  import { dirname, resolve } from "path";
6
6
  import { fileURLToPath } from "url";
7
+ import { Cli as Cli5, z as z5 } from "incur";
8
+
9
+ // src/commands/cl.ts
10
+ import { checksumAddress, isAddress } from "@spectratools/cli-shared";
7
11
  import { Cli, z } from "incur";
12
+ import { formatUnits, parseUnits } from "viem";
8
13
 
9
14
  // src/contracts/abis/CLFactory.abi.json
10
15
  var CLFactory_abi_default = [
@@ -119,177 +124,246 @@ var CLFactory_abi_default = [
119
124
  }
120
125
  ];
121
126
 
122
- // src/contracts/abis/PoolFactory.abi.json
123
- var PoolFactory_abi_default = [
127
+ // src/contracts/abis/CLPool.abi.json
128
+ var CLPool_abi_default = [
124
129
  {
125
130
  type: "function",
126
- name: "allPoolsLength",
131
+ name: "slot0",
127
132
  inputs: [],
128
- outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
133
+ outputs: [
134
+ { name: "sqrtPriceX96", type: "uint160", internalType: "uint160" },
135
+ { name: "tick", type: "int24", internalType: "int24" },
136
+ { name: "observationIndex", type: "uint16", internalType: "uint16" },
137
+ { name: "observationCardinality", type: "uint16", internalType: "uint16" },
138
+ { name: "observationCardinalityNext", type: "uint16", internalType: "uint16" },
139
+ { name: "unlocked", type: "bool", internalType: "bool" }
140
+ ],
129
141
  stateMutability: "view"
130
142
  },
131
143
  {
132
144
  type: "function",
133
- name: "allPools",
134
- inputs: [{ name: "index", type: "uint256", internalType: "uint256" }],
135
- outputs: [{ name: "", type: "address", internalType: "address" }],
145
+ name: "liquidity",
146
+ inputs: [],
147
+ outputs: [{ name: "", type: "uint128", internalType: "uint128" }],
136
148
  stateMutability: "view"
137
149
  },
138
150
  {
139
151
  type: "function",
140
- name: "getPool",
141
- inputs: [
142
- { name: "tokenA", type: "address", internalType: "address" },
143
- { name: "tokenB", type: "address", internalType: "address" },
144
- { name: "stable", type: "bool", internalType: "bool" }
145
- ],
152
+ name: "token0",
153
+ inputs: [],
146
154
  outputs: [{ name: "", type: "address", internalType: "address" }],
147
155
  stateMutability: "view"
148
156
  },
149
157
  {
150
158
  type: "function",
151
- name: "isPair",
152
- inputs: [{ name: "pool", type: "address", internalType: "address" }],
153
- outputs: [{ name: "", type: "bool", internalType: "bool" }],
159
+ name: "token1",
160
+ inputs: [],
161
+ outputs: [{ name: "", type: "address", internalType: "address" }],
154
162
  stateMutability: "view"
155
163
  },
156
164
  {
157
165
  type: "function",
158
- name: "getFee",
159
- inputs: [
160
- { name: "pool", type: "address", internalType: "address" },
161
- { name: "stable", type: "bool", internalType: "bool" }
162
- ],
163
- outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
166
+ name: "tickSpacing",
167
+ inputs: [],
168
+ outputs: [{ name: "", type: "int24", internalType: "int24" }],
164
169
  stateMutability: "view"
165
170
  },
166
171
  {
167
172
  type: "function",
168
- name: "implementation",
173
+ name: "factory",
169
174
  inputs: [],
170
175
  outputs: [{ name: "", type: "address", internalType: "address" }],
171
176
  stateMutability: "view"
172
177
  },
173
178
  {
174
179
  type: "function",
175
- name: "voter",
180
+ name: "gauge",
176
181
  inputs: [],
177
182
  outputs: [{ name: "", type: "address", internalType: "address" }],
178
183
  stateMutability: "view"
184
+ },
185
+ {
186
+ type: "function",
187
+ name: "fee",
188
+ inputs: [],
189
+ outputs: [{ name: "", type: "uint24", internalType: "uint24" }],
190
+ stateMutability: "view"
179
191
  }
180
192
  ];
181
193
 
182
- // src/contracts/abis/Voter.abi.json
183
- var Voter_abi_default = [
194
+ // src/contracts/abis/Gauge.abi.json
195
+ var Gauge_abi_default = [
184
196
  {
185
197
  type: "function",
186
- name: "length",
198
+ name: "stakingToken",
199
+ inputs: [],
200
+ outputs: [{ name: "", type: "address", internalType: "address" }],
201
+ stateMutability: "view"
202
+ },
203
+ {
204
+ type: "function",
205
+ name: "rewardToken",
206
+ inputs: [],
207
+ outputs: [{ name: "", type: "address", internalType: "address" }],
208
+ stateMutability: "view"
209
+ },
210
+ {
211
+ type: "function",
212
+ name: "periodFinish",
187
213
  inputs: [],
188
214
  outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
189
215
  stateMutability: "view"
190
216
  },
191
217
  {
192
218
  type: "function",
193
- name: "totalWeight",
219
+ name: "rewardRate",
194
220
  inputs: [],
195
221
  outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
196
222
  stateMutability: "view"
197
223
  },
198
224
  {
199
225
  type: "function",
200
- name: "gauges",
201
- inputs: [{ name: "pool", type: "address", internalType: "address" }],
202
- outputs: [{ name: "", type: "address", internalType: "address" }],
226
+ name: "lastUpdateTime",
227
+ inputs: [],
228
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
203
229
  stateMutability: "view"
204
230
  },
205
231
  {
206
232
  type: "function",
207
- name: "poolForGauge",
208
- inputs: [{ name: "gauge", type: "address", internalType: "address" }],
209
- outputs: [{ name: "", type: "address", internalType: "address" }],
233
+ name: "rewardPerTokenStored",
234
+ inputs: [],
235
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
210
236
  stateMutability: "view"
211
237
  },
212
238
  {
213
239
  type: "function",
214
- name: "weights",
215
- inputs: [{ name: "pool", type: "address", internalType: "address" }],
240
+ name: "totalSupply",
241
+ inputs: [],
216
242
  outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
217
243
  stateMutability: "view"
218
244
  },
219
245
  {
220
246
  type: "function",
221
- name: "isAlive",
222
- inputs: [{ name: "gauge", type: "address", internalType: "address" }],
223
- outputs: [{ name: "", type: "bool", internalType: "bool" }],
247
+ name: "balanceOf",
248
+ inputs: [{ name: "account", type: "address", internalType: "address" }],
249
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
224
250
  stateMutability: "view"
225
251
  },
226
252
  {
227
253
  type: "function",
228
- name: "isGauge",
229
- inputs: [{ name: "", type: "address", internalType: "address" }],
230
- outputs: [{ name: "", type: "bool", internalType: "bool" }],
254
+ name: "earned",
255
+ inputs: [{ name: "account", type: "address", internalType: "address" }],
256
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
231
257
  stateMutability: "view"
232
258
  },
233
259
  {
234
260
  type: "function",
235
- name: "ve",
261
+ name: "fees0",
236
262
  inputs: [],
237
- outputs: [{ name: "", type: "address", internalType: "address" }],
263
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
238
264
  stateMutability: "view"
239
265
  },
240
266
  {
241
267
  type: "function",
242
- name: "minter",
268
+ name: "fees1",
243
269
  inputs: [],
244
- outputs: [{ name: "", type: "address", internalType: "address" }],
270
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
245
271
  stateMutability: "view"
246
272
  },
247
273
  {
248
274
  type: "function",
249
- name: "factoryRegistry",
275
+ name: "left",
250
276
  inputs: [],
251
- outputs: [{ name: "", type: "address", internalType: "address" }],
277
+ outputs: [{ name: "_left", type: "uint256", internalType: "uint256" }],
278
+ stateMutability: "view"
279
+ }
280
+ ];
281
+
282
+ // src/contracts/abis/Minter.abi.json
283
+ var Minter_abi_default = [
284
+ {
285
+ type: "function",
286
+ name: "WEEK",
287
+ inputs: [],
288
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
252
289
  stateMutability: "view"
253
290
  },
254
291
  {
255
292
  type: "function",
256
- name: "forwarder",
293
+ name: "weekly",
257
294
  inputs: [],
258
- outputs: [{ name: "", type: "address", internalType: "address" }],
295
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
259
296
  stateMutability: "view"
260
297
  },
261
298
  {
262
299
  type: "function",
263
- name: "governor",
300
+ name: "activePeriod",
264
301
  inputs: [],
265
- outputs: [{ name: "", type: "address", internalType: "address" }],
302
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
266
303
  stateMutability: "view"
267
304
  },
268
305
  {
269
306
  type: "function",
270
- name: "emergencyCouncil",
307
+ name: "epochCount",
271
308
  inputs: [],
272
- outputs: [{ name: "", type: "address", internalType: "address" }],
309
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
273
310
  stateMutability: "view"
274
311
  },
275
312
  {
276
313
  type: "function",
277
- name: "maxVotingNum",
314
+ name: "teamRate",
278
315
  inputs: [],
279
316
  outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
280
317
  stateMutability: "view"
281
318
  },
282
319
  {
283
320
  type: "function",
284
- name: "claimable",
285
- inputs: [{ name: "gauge", type: "address", internalType: "address" }],
321
+ name: "tailEmissionRate",
322
+ inputs: [],
286
323
  outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
287
324
  stateMutability: "view"
288
325
  }
289
326
  ];
290
327
 
291
- // src/contracts/abis/VotingEscrow.abi.json
292
- var VotingEscrow_abi_default = [
328
+ // src/contracts/abis/NonfungiblePositionManager.abi.json
329
+ var NonfungiblePositionManager_abi_default = [
330
+ {
331
+ type: "function",
332
+ name: "positions",
333
+ inputs: [{ name: "tokenId", type: "uint256", internalType: "uint256" }],
334
+ outputs: [
335
+ { name: "nonce", type: "uint96", internalType: "uint96" },
336
+ { name: "operator", type: "address", internalType: "address" },
337
+ { name: "token0", type: "address", internalType: "address" },
338
+ { name: "token1", type: "address", internalType: "address" },
339
+ { name: "tickSpacing", type: "int24", internalType: "int24" },
340
+ { name: "tickLower", type: "int24", internalType: "int24" },
341
+ { name: "tickUpper", type: "int24", internalType: "int24" },
342
+ { name: "liquidity", type: "uint128", internalType: "uint128" },
343
+ { name: "feeGrowthInside0LastX128", type: "uint256", internalType: "uint256" },
344
+ { name: "feeGrowthInside1LastX128", type: "uint256", internalType: "uint256" },
345
+ { name: "tokensOwed0", type: "uint128", internalType: "uint128" },
346
+ { name: "tokensOwed1", type: "uint128", internalType: "uint128" }
347
+ ],
348
+ stateMutability: "view"
349
+ },
350
+ {
351
+ type: "function",
352
+ name: "balanceOf",
353
+ inputs: [{ name: "owner", type: "address", internalType: "address" }],
354
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
355
+ stateMutability: "view"
356
+ },
357
+ {
358
+ type: "function",
359
+ name: "tokenOfOwnerByIndex",
360
+ inputs: [
361
+ { name: "owner", type: "address", internalType: "address" },
362
+ { name: "index", type: "uint256", internalType: "uint256" }
363
+ ],
364
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
365
+ stateMutability: "view"
366
+ },
293
367
  {
294
368
  type: "function",
295
369
  name: "totalSupply",
@@ -299,46 +373,168 @@ var VotingEscrow_abi_default = [
299
373
  },
300
374
  {
301
375
  type: "function",
302
- name: "balanceOf",
303
- inputs: [{ name: "owner", type: "address", internalType: "address" }],
376
+ name: "factory",
377
+ inputs: [],
378
+ outputs: [{ name: "", type: "address", internalType: "address" }],
379
+ stateMutability: "view"
380
+ },
381
+ {
382
+ type: "function",
383
+ name: "WETH9",
384
+ inputs: [],
385
+ outputs: [{ name: "", type: "address", internalType: "address" }],
386
+ stateMutability: "view"
387
+ }
388
+ ];
389
+
390
+ // src/contracts/abis/PoolFactory.abi.json
391
+ var PoolFactory_abi_default = [
392
+ {
393
+ type: "function",
394
+ name: "allPoolsLength",
395
+ inputs: [],
304
396
  outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
305
397
  stateMutability: "view"
306
398
  },
307
399
  {
308
400
  type: "function",
309
- name: "locked",
310
- inputs: [{ name: "tokenId", type: "uint256", internalType: "uint256" }],
311
- outputs: [
312
- { name: "amount", type: "int128", internalType: "int128" },
313
- { name: "end", type: "uint256", internalType: "uint256" },
314
- { name: "isPermanent", type: "bool", internalType: "bool" }
401
+ name: "allPools",
402
+ inputs: [{ name: "index", type: "uint256", internalType: "uint256" }],
403
+ outputs: [{ name: "", type: "address", internalType: "address" }],
404
+ stateMutability: "view"
405
+ },
406
+ {
407
+ type: "function",
408
+ name: "getPool",
409
+ inputs: [
410
+ { name: "tokenA", type: "address", internalType: "address" },
411
+ { name: "tokenB", type: "address", internalType: "address" },
412
+ { name: "stable", type: "bool", internalType: "bool" }
315
413
  ],
414
+ outputs: [{ name: "", type: "address", internalType: "address" }],
316
415
  stateMutability: "view"
317
416
  },
318
417
  {
319
418
  type: "function",
320
- name: "ownerOf",
321
- inputs: [{ name: "tokenId", type: "uint256", internalType: "uint256" }],
419
+ name: "isPair",
420
+ inputs: [{ name: "pool", type: "address", internalType: "address" }],
421
+ outputs: [{ name: "", type: "bool", internalType: "bool" }],
422
+ stateMutability: "view"
423
+ },
424
+ {
425
+ type: "function",
426
+ name: "getFee",
427
+ inputs: [
428
+ { name: "pool", type: "address", internalType: "address" },
429
+ { name: "stable", type: "bool", internalType: "bool" }
430
+ ],
431
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
432
+ stateMutability: "view"
433
+ },
434
+ {
435
+ type: "function",
436
+ name: "implementation",
437
+ inputs: [],
322
438
  outputs: [{ name: "", type: "address", internalType: "address" }],
323
439
  stateMutability: "view"
324
440
  },
325
441
  {
326
442
  type: "function",
327
- name: "tokenOfOwnerByIndex",
443
+ name: "voter",
444
+ inputs: [],
445
+ outputs: [{ name: "", type: "address", internalType: "address" }],
446
+ stateMutability: "view"
447
+ }
448
+ ];
449
+
450
+ // src/contracts/abis/QuoterV2.abi.json
451
+ var QuoterV2_abi_default = [
452
+ {
453
+ type: "function",
454
+ name: "factory",
455
+ inputs: [],
456
+ outputs: [{ name: "", type: "address", internalType: "address" }],
457
+ stateMutability: "view"
458
+ },
459
+ {
460
+ type: "function",
461
+ name: "WETH9",
462
+ inputs: [],
463
+ outputs: [{ name: "", type: "address", internalType: "address" }],
464
+ stateMutability: "view"
465
+ },
466
+ {
467
+ type: "function",
468
+ name: "quoteExactInputSingle",
328
469
  inputs: [
329
- { name: "owner", type: "address", internalType: "address" },
330
- { name: "index", type: "uint256", internalType: "uint256" }
470
+ {
471
+ name: "params",
472
+ type: "tuple",
473
+ internalType: "struct IQuoterV2.QuoteExactInputSingleParams",
474
+ components: [
475
+ { name: "tokenIn", type: "address", internalType: "address" },
476
+ { name: "tokenOut", type: "address", internalType: "address" },
477
+ { name: "amountIn", type: "uint256", internalType: "uint256" },
478
+ { name: "tickSpacing", type: "int24", internalType: "int24" },
479
+ { name: "sqrtPriceLimitX96", type: "uint160", internalType: "uint160" }
480
+ ]
481
+ }
482
+ ],
483
+ outputs: [
484
+ { name: "amountOut", type: "uint256", internalType: "uint256" },
485
+ { name: "sqrtPriceX96After", type: "uint160", internalType: "uint160" },
486
+ { name: "initializedTicksCrossed", type: "uint32", internalType: "uint32" },
487
+ { name: "gasEstimate", type: "uint256", internalType: "uint256" }
488
+ ],
489
+ stateMutability: "nonpayable"
490
+ },
491
+ {
492
+ type: "function",
493
+ name: "quoteExactInput",
494
+ inputs: [
495
+ { name: "path", type: "bytes", internalType: "bytes" },
496
+ { name: "amountIn", type: "uint256", internalType: "uint256" }
497
+ ],
498
+ outputs: [
499
+ { name: "amountOut", type: "uint256", internalType: "uint256" },
500
+ { name: "sqrtPriceX96AfterList", type: "uint160[]", internalType: "uint160[]" },
501
+ { name: "initializedTicksCrossedList", type: "uint32[]", internalType: "uint32[]" },
502
+ { name: "gasEstimate", type: "uint256", internalType: "uint256" }
331
503
  ],
504
+ stateMutability: "nonpayable"
505
+ }
506
+ ];
507
+
508
+ // src/contracts/abis/RewardsDistributor.abi.json
509
+ var RewardsDistributor_abi_default = [
510
+ {
511
+ type: "function",
512
+ name: "WEEK",
513
+ inputs: [],
332
514
  outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
333
515
  stateMutability: "view"
334
516
  },
335
517
  {
336
518
  type: "function",
337
- name: "balanceOfNFT",
519
+ name: "startTime",
520
+ inputs: [],
521
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
522
+ stateMutability: "view"
523
+ },
524
+ {
525
+ type: "function",
526
+ name: "timeCursorOf",
338
527
  inputs: [{ name: "tokenId", type: "uint256", internalType: "uint256" }],
339
528
  outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
340
529
  stateMutability: "view"
341
530
  },
531
+ {
532
+ type: "function",
533
+ name: "lastTokenTime",
534
+ inputs: [],
535
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
536
+ stateMutability: "view"
537
+ },
342
538
  {
343
539
  type: "function",
344
540
  name: "token",
@@ -348,18 +544,329 @@ var VotingEscrow_abi_default = [
348
544
  },
349
545
  {
350
546
  type: "function",
351
- name: "supply",
547
+ name: "minter",
352
548
  inputs: [],
549
+ outputs: [{ name: "", type: "address", internalType: "address" }],
550
+ stateMutability: "view"
551
+ },
552
+ {
553
+ type: "function",
554
+ name: "claimable",
555
+ inputs: [{ name: "tokenId", type: "uint256", internalType: "uint256" }],
353
556
  outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
354
557
  stateMutability: "view"
355
558
  }
356
559
  ];
357
560
 
358
- // src/contracts/abis.ts
359
- var clFactoryAbi = CLFactory_abi_default;
360
- var poolFactoryAbi = PoolFactory_abi_default;
561
+ // src/contracts/abis/Voter.abi.json
562
+ var Voter_abi_default = [
563
+ {
564
+ type: "function",
565
+ name: "length",
566
+ inputs: [],
567
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
568
+ stateMutability: "view"
569
+ },
570
+ {
571
+ type: "function",
572
+ name: "totalWeight",
573
+ inputs: [],
574
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
575
+ stateMutability: "view"
576
+ },
577
+ {
578
+ type: "function",
579
+ name: "gauges",
580
+ inputs: [{ name: "pool", type: "address", internalType: "address" }],
581
+ outputs: [{ name: "", type: "address", internalType: "address" }],
582
+ stateMutability: "view"
583
+ },
584
+ {
585
+ type: "function",
586
+ name: "poolForGauge",
587
+ inputs: [{ name: "gauge", type: "address", internalType: "address" }],
588
+ outputs: [{ name: "", type: "address", internalType: "address" }],
589
+ stateMutability: "view"
590
+ },
591
+ {
592
+ type: "function",
593
+ name: "gaugeToFees",
594
+ inputs: [{ name: "gauge", type: "address", internalType: "address" }],
595
+ outputs: [{ name: "", type: "address", internalType: "address" }],
596
+ stateMutability: "view"
597
+ },
598
+ {
599
+ type: "function",
600
+ name: "gaugeToBribe",
601
+ inputs: [{ name: "gauge", type: "address", internalType: "address" }],
602
+ outputs: [{ name: "", type: "address", internalType: "address" }],
603
+ stateMutability: "view"
604
+ },
605
+ {
606
+ type: "function",
607
+ name: "weights",
608
+ inputs: [{ name: "pool", type: "address", internalType: "address" }],
609
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
610
+ stateMutability: "view"
611
+ },
612
+ {
613
+ type: "function",
614
+ name: "votes",
615
+ inputs: [
616
+ { name: "tokenId", type: "uint256", internalType: "uint256" },
617
+ { name: "pool", type: "address", internalType: "address" }
618
+ ],
619
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
620
+ stateMutability: "view"
621
+ },
622
+ {
623
+ type: "function",
624
+ name: "usedWeights",
625
+ inputs: [{ name: "tokenId", type: "uint256", internalType: "uint256" }],
626
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
627
+ stateMutability: "view"
628
+ },
629
+ {
630
+ type: "function",
631
+ name: "lastVoted",
632
+ inputs: [{ name: "tokenId", type: "uint256", internalType: "uint256" }],
633
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
634
+ stateMutability: "view"
635
+ },
636
+ {
637
+ type: "function",
638
+ name: "isAlive",
639
+ inputs: [{ name: "gauge", type: "address", internalType: "address" }],
640
+ outputs: [{ name: "", type: "bool", internalType: "bool" }],
641
+ stateMutability: "view"
642
+ },
643
+ {
644
+ type: "function",
645
+ name: "isGauge",
646
+ inputs: [{ name: "", type: "address", internalType: "address" }],
647
+ outputs: [{ name: "", type: "bool", internalType: "bool" }],
648
+ stateMutability: "view"
649
+ },
650
+ {
651
+ type: "function",
652
+ name: "ve",
653
+ inputs: [],
654
+ outputs: [{ name: "", type: "address", internalType: "address" }],
655
+ stateMutability: "view"
656
+ },
657
+ {
658
+ type: "function",
659
+ name: "minter",
660
+ inputs: [],
661
+ outputs: [{ name: "", type: "address", internalType: "address" }],
662
+ stateMutability: "view"
663
+ },
664
+ {
665
+ type: "function",
666
+ name: "factoryRegistry",
667
+ inputs: [],
668
+ outputs: [{ name: "", type: "address", internalType: "address" }],
669
+ stateMutability: "view"
670
+ },
671
+ {
672
+ type: "function",
673
+ name: "forwarder",
674
+ inputs: [],
675
+ outputs: [{ name: "", type: "address", internalType: "address" }],
676
+ stateMutability: "view"
677
+ },
678
+ {
679
+ type: "function",
680
+ name: "governor",
681
+ inputs: [],
682
+ outputs: [{ name: "", type: "address", internalType: "address" }],
683
+ stateMutability: "view"
684
+ },
685
+ {
686
+ type: "function",
687
+ name: "epochGovernor",
688
+ inputs: [],
689
+ outputs: [{ name: "", type: "address", internalType: "address" }],
690
+ stateMutability: "view"
691
+ },
692
+ {
693
+ type: "function",
694
+ name: "emergencyCouncil",
695
+ inputs: [],
696
+ outputs: [{ name: "", type: "address", internalType: "address" }],
697
+ stateMutability: "view"
698
+ },
699
+ {
700
+ type: "function",
701
+ name: "maxVotingNum",
702
+ inputs: [],
703
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
704
+ stateMutability: "view"
705
+ },
706
+ {
707
+ type: "function",
708
+ name: "claimable",
709
+ inputs: [{ name: "gauge", type: "address", internalType: "address" }],
710
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
711
+ stateMutability: "view"
712
+ }
713
+ ];
714
+
715
+ // src/contracts/abis/VotingEscrow.abi.json
716
+ var VotingEscrow_abi_default = [
717
+ {
718
+ type: "function",
719
+ name: "totalSupply",
720
+ inputs: [],
721
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
722
+ stateMutability: "view"
723
+ },
724
+ {
725
+ type: "function",
726
+ name: "supply",
727
+ inputs: [],
728
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
729
+ stateMutability: "view"
730
+ },
731
+ {
732
+ type: "function",
733
+ name: "permanentLockBalance",
734
+ inputs: [],
735
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
736
+ stateMutability: "view"
737
+ },
738
+ {
739
+ type: "function",
740
+ name: "epoch",
741
+ inputs: [],
742
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
743
+ stateMutability: "view"
744
+ },
745
+ {
746
+ type: "function",
747
+ name: "pointHistory",
748
+ inputs: [{ name: "_loc", type: "uint256", internalType: "uint256" }],
749
+ outputs: [
750
+ {
751
+ name: "",
752
+ type: "tuple",
753
+ internalType: "struct IVotingEscrow.GlobalPoint",
754
+ components: [
755
+ { name: "bias", type: "int128", internalType: "int128" },
756
+ { name: "slope", type: "int128", internalType: "int128" },
757
+ { name: "ts", type: "uint256", internalType: "uint256" },
758
+ { name: "blk", type: "uint256", internalType: "uint256" },
759
+ {
760
+ name: "permanentLockBalance",
761
+ type: "uint256",
762
+ internalType: "uint256"
763
+ }
764
+ ]
765
+ }
766
+ ],
767
+ stateMutability: "view"
768
+ },
769
+ {
770
+ type: "function",
771
+ name: "balanceOf",
772
+ inputs: [{ name: "owner", type: "address", internalType: "address" }],
773
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
774
+ stateMutability: "view"
775
+ },
776
+ {
777
+ type: "function",
778
+ name: "locked",
779
+ inputs: [{ name: "tokenId", type: "uint256", internalType: "uint256" }],
780
+ outputs: [
781
+ { name: "amount", type: "int128", internalType: "int128" },
782
+ { name: "end", type: "uint256", internalType: "uint256" },
783
+ { name: "isPermanent", type: "bool", internalType: "bool" }
784
+ ],
785
+ stateMutability: "view"
786
+ },
787
+ {
788
+ type: "function",
789
+ name: "ownerOf",
790
+ inputs: [{ name: "tokenId", type: "uint256", internalType: "uint256" }],
791
+ outputs: [{ name: "", type: "address", internalType: "address" }],
792
+ stateMutability: "view"
793
+ },
794
+ {
795
+ type: "function",
796
+ name: "tokenOfOwnerByIndex",
797
+ inputs: [
798
+ { name: "owner", type: "address", internalType: "address" },
799
+ { name: "index", type: "uint256", internalType: "uint256" }
800
+ ],
801
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
802
+ stateMutability: "view"
803
+ },
804
+ {
805
+ type: "function",
806
+ name: "balanceOfNFT",
807
+ inputs: [{ name: "tokenId", type: "uint256", internalType: "uint256" }],
808
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
809
+ stateMutability: "view"
810
+ },
811
+ {
812
+ type: "function",
813
+ name: "token",
814
+ inputs: [],
815
+ outputs: [{ name: "", type: "address", internalType: "address" }],
816
+ stateMutability: "view"
817
+ }
818
+ ];
819
+
820
+ // src/contracts/abis/VotingReward.abi.json
821
+ var VotingReward_abi_default = [
822
+ {
823
+ type: "function",
824
+ name: "rewardsListLength",
825
+ inputs: [],
826
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
827
+ stateMutability: "view"
828
+ },
829
+ {
830
+ type: "function",
831
+ name: "rewards",
832
+ inputs: [{ name: "", type: "uint256", internalType: "uint256" }],
833
+ outputs: [{ name: "", type: "address", internalType: "address" }],
834
+ stateMutability: "view"
835
+ },
836
+ {
837
+ type: "function",
838
+ name: "tokenRewardsPerEpoch",
839
+ inputs: [
840
+ { name: "token", type: "address", internalType: "address" },
841
+ { name: "epochStart", type: "uint256", internalType: "uint256" }
842
+ ],
843
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
844
+ stateMutability: "view"
845
+ },
846
+ {
847
+ type: "function",
848
+ name: "earned",
849
+ inputs: [
850
+ { name: "token", type: "address", internalType: "address" },
851
+ { name: "tokenId", type: "uint256", internalType: "uint256" }
852
+ ],
853
+ outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
854
+ stateMutability: "view"
855
+ }
856
+ ];
857
+
858
+ // src/contracts/abis.ts
859
+ var clFactoryAbi = CLFactory_abi_default;
860
+ var clPoolAbi = CLPool_abi_default;
861
+ var gaugeAbi = Gauge_abi_default;
862
+ var minterAbi = Minter_abi_default;
863
+ var nonfungiblePositionManagerAbi = NonfungiblePositionManager_abi_default;
864
+ var poolFactoryAbi = PoolFactory_abi_default;
865
+ var quoterV2Abi = QuoterV2_abi_default;
866
+ var rewardsDistributorAbi = RewardsDistributor_abi_default;
361
867
  var voterAbi = Voter_abi_default;
362
868
  var votingEscrowAbi = VotingEscrow_abi_default;
869
+ var votingRewardAbi = VotingReward_abi_default;
363
870
 
364
871
  // src/contracts/addresses.ts
365
872
  var ABOREAN_V2_ADDRESSES = {
@@ -423,28 +930,1544 @@ var ABOREAN_ADDRESSES = {
423
930
  ...ABOREAN_CL_ADDRESSES
424
931
  };
425
932
 
426
- // src/contracts/client.ts
427
- import { http, createPublicClient, defineChain } from "viem";
428
- var abstractMainnet = defineChain({
429
- id: 2741,
430
- name: "Abstract Mainnet",
431
- nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
432
- rpcUrls: {
433
- default: { http: ["https://api.mainnet.abs.xyz"] },
434
- public: { http: ["https://api.mainnet.abs.xyz"] }
435
- },
436
- contracts: {
437
- multicall3: {
438
- address: "0xcA11bde05977b3631167028862bE2a173976CA11"
933
+ // src/contracts/client.ts
934
+ import { http, createPublicClient, defineChain } from "viem";
935
+ var abstractMainnet = defineChain({
936
+ id: 2741,
937
+ name: "Abstract Mainnet",
938
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
939
+ rpcUrls: {
940
+ default: { http: ["https://api.mainnet.abs.xyz"] },
941
+ public: { http: ["https://api.mainnet.abs.xyz"] }
942
+ },
943
+ contracts: {
944
+ multicall3: {
945
+ address: "0xcA11bde05977b3631167028862bE2a173976CA11"
946
+ }
947
+ }
948
+ });
949
+ function createAboreanPublicClient(rpcUrl) {
950
+ return createPublicClient({
951
+ chain: abstractMainnet,
952
+ transport: http(rpcUrl ?? process.env.ABSTRACT_RPC_URL ?? "https://api.mainnet.abs.xyz")
953
+ });
954
+ }
955
+
956
+ // src/commands/cl.ts
957
+ var Q96 = 2n ** 96n;
958
+ var MULTICALL_BATCH_SIZE = 100;
959
+ var env = z.object({
960
+ ABSTRACT_RPC_URL: z.string().optional().describe("Abstract RPC URL override")
961
+ });
962
+ var tokenSchema = z.object({
963
+ address: z.string(),
964
+ symbol: z.string(),
965
+ decimals: z.number()
966
+ });
967
+ var poolRowSchema = z.object({
968
+ pool: z.string(),
969
+ pair: z.string(),
970
+ token0: tokenSchema,
971
+ token1: tokenSchema,
972
+ fee: z.number(),
973
+ feePercent: z.number(),
974
+ tickSpacing: z.number(),
975
+ liquidity: z.string(),
976
+ currentTick: z.number(),
977
+ sqrtPriceX96: z.string(),
978
+ activeLiquidityEstimate: z.object({
979
+ token0: z.string(),
980
+ token1: z.string(),
981
+ totalInToken0: z.number().nullable(),
982
+ totalInToken1: z.number().nullable()
983
+ }),
984
+ price: z.object({
985
+ token1PerToken0: z.number().nullable(),
986
+ token0PerToken1: z.number().nullable()
987
+ })
988
+ });
989
+ var quoteOutputSchema = z.object({
990
+ pool: z.string(),
991
+ selectedFee: z.number(),
992
+ selectedTickSpacing: z.number(),
993
+ tokenIn: tokenSchema,
994
+ tokenOut: tokenSchema,
995
+ amountIn: z.object({
996
+ raw: z.string(),
997
+ decimal: z.string()
998
+ }),
999
+ amountOut: z.object({
1000
+ raw: z.string(),
1001
+ decimal: z.string()
1002
+ }),
1003
+ execution: z.object({
1004
+ sqrtPriceX96After: z.string(),
1005
+ initializedTicksCrossed: z.number(),
1006
+ gasEstimate: z.string()
1007
+ }),
1008
+ prices: z.object({
1009
+ poolMidPriceOutPerIn: z.number().nullable(),
1010
+ quotePriceOutPerIn: z.number().nullable(),
1011
+ priceImpactPct: z.number().nullable()
1012
+ })
1013
+ });
1014
+ var erc20MetadataAbi = [
1015
+ {
1016
+ type: "function",
1017
+ name: "symbol",
1018
+ stateMutability: "view",
1019
+ inputs: [],
1020
+ outputs: [{ type: "string" }]
1021
+ },
1022
+ {
1023
+ type: "function",
1024
+ name: "decimals",
1025
+ stateMutability: "view",
1026
+ inputs: [],
1027
+ outputs: [{ type: "uint8" }]
1028
+ }
1029
+ ];
1030
+ function shortAddress(address) {
1031
+ return `${address.slice(0, 6)}\u2026${address.slice(-4)}`;
1032
+ }
1033
+ function finiteOrNull(value) {
1034
+ return Number.isFinite(value) ? value : null;
1035
+ }
1036
+ function toTokenMetaFallback(address) {
1037
+ return {
1038
+ address,
1039
+ symbol: shortAddress(checksumAddress(address)),
1040
+ decimals: 18
1041
+ };
1042
+ }
1043
+ function chunk(items, size) {
1044
+ const out = [];
1045
+ for (let i = 0; i < items.length; i += size) {
1046
+ out.push(items.slice(i, i + size));
1047
+ }
1048
+ return out;
1049
+ }
1050
+ async function multicallAllowFailure(client, contracts) {
1051
+ const batches = chunk(contracts, MULTICALL_BATCH_SIZE);
1052
+ const out = [];
1053
+ for (const batch of batches) {
1054
+ const res = await client.multicall({
1055
+ allowFailure: true,
1056
+ contracts: batch
1057
+ });
1058
+ out.push(...res);
1059
+ }
1060
+ return out;
1061
+ }
1062
+ async function multicallStrict(client, contracts) {
1063
+ const batches = chunk(contracts, MULTICALL_BATCH_SIZE);
1064
+ const out = [];
1065
+ for (const batch of batches) {
1066
+ const res = await client.multicall({
1067
+ allowFailure: false,
1068
+ contracts: batch
1069
+ });
1070
+ out.push(...res);
1071
+ }
1072
+ return out;
1073
+ }
1074
+ function derivePrices(sqrtPriceX96, token0Decimals, token1Decimals) {
1075
+ const sqrtRatio = Number(sqrtPriceX96) / 2 ** 96;
1076
+ const rawPrice = sqrtRatio * sqrtRatio;
1077
+ const decimalScale = 10 ** (token0Decimals - token1Decimals);
1078
+ const token1PerToken0 = finiteOrNull(rawPrice * decimalScale);
1079
+ const token0PerToken1 = token1PerToken0 === null || token1PerToken0 === 0 ? null : finiteOrNull(1 / token1PerToken0);
1080
+ return {
1081
+ token1PerToken0,
1082
+ token0PerToken1
1083
+ };
1084
+ }
1085
+ function estimateActiveLiquidity(liquidity, sqrtPriceX96, token0Decimals, token1Decimals, prices) {
1086
+ if (sqrtPriceX96 === 0n) {
1087
+ return {
1088
+ token0: "0",
1089
+ token1: "0",
1090
+ totalInToken0: null,
1091
+ totalInToken1: null
1092
+ };
1093
+ }
1094
+ const reserve0Raw = liquidity * Q96 / sqrtPriceX96;
1095
+ const reserve1Raw = liquidity * sqrtPriceX96 / Q96;
1096
+ const reserve0 = Number(formatUnits(reserve0Raw, token0Decimals));
1097
+ const reserve1 = Number(formatUnits(reserve1Raw, token1Decimals));
1098
+ const totalInToken1 = prices.token1PerToken0 === null ? null : finiteOrNull(reserve1 + reserve0 * prices.token1PerToken0);
1099
+ const totalInToken0 = prices.token0PerToken1 === null ? null : finiteOrNull(reserve0 + reserve1 * prices.token0PerToken1);
1100
+ return {
1101
+ token0: formatUnits(reserve0Raw, token0Decimals),
1102
+ token1: formatUnits(reserve1Raw, token1Decimals),
1103
+ totalInToken0,
1104
+ totalInToken1
1105
+ };
1106
+ }
1107
+ async function readTokenMetadata(client, tokenAddresses) {
1108
+ const uniqueTokens = [...new Set(tokenAddresses.map((x) => x.toLowerCase()))];
1109
+ if (uniqueTokens.length === 0) {
1110
+ return /* @__PURE__ */ new Map();
1111
+ }
1112
+ const contracts = uniqueTokens.flatMap((address) => [
1113
+ {
1114
+ abi: erc20MetadataAbi,
1115
+ address,
1116
+ functionName: "symbol"
1117
+ },
1118
+ {
1119
+ abi: erc20MetadataAbi,
1120
+ address,
1121
+ functionName: "decimals"
1122
+ }
1123
+ ]);
1124
+ const results = await multicallAllowFailure(client, contracts);
1125
+ const out = /* @__PURE__ */ new Map();
1126
+ for (let i = 0; i < uniqueTokens.length; i += 1) {
1127
+ const address = uniqueTokens[i];
1128
+ const symbolResult = results[i * 2];
1129
+ const decimalsResult = results[i * 2 + 1];
1130
+ const fallback = toTokenMetaFallback(address);
1131
+ const symbol = symbolResult && symbolResult.status === "success" && typeof symbolResult.result === "string" ? symbolResult.result : fallback.symbol;
1132
+ const decimals = decimalsResult && decimalsResult.status === "success" && typeof decimalsResult.result === "number" ? decimalsResult.result : fallback.decimals;
1133
+ out.set(address, {
1134
+ address: checksumAddress(address),
1135
+ symbol,
1136
+ decimals
1137
+ });
1138
+ }
1139
+ return out;
1140
+ }
1141
+ async function listPoolAddresses(client) {
1142
+ const count = await client.readContract({
1143
+ abi: clFactoryAbi,
1144
+ address: ABOREAN_CL_ADDRESSES.clFactory,
1145
+ functionName: "allPoolsLength"
1146
+ });
1147
+ if (count === 0n) {
1148
+ return [];
1149
+ }
1150
+ const poolIndexContracts = Array.from({ length: Number(count) }, (_, i) => ({
1151
+ abi: clFactoryAbi,
1152
+ address: ABOREAN_CL_ADDRESSES.clFactory,
1153
+ functionName: "allPools",
1154
+ args: [BigInt(i)]
1155
+ }));
1156
+ const poolAddresses = await multicallStrict(client, poolIndexContracts);
1157
+ return poolAddresses;
1158
+ }
1159
+ async function readPoolStates(client, poolAddresses) {
1160
+ if (poolAddresses.length === 0) {
1161
+ return [];
1162
+ }
1163
+ const poolContracts = poolAddresses.flatMap((pool) => [
1164
+ {
1165
+ abi: clPoolAbi,
1166
+ address: pool,
1167
+ functionName: "token0"
1168
+ },
1169
+ {
1170
+ abi: clPoolAbi,
1171
+ address: pool,
1172
+ functionName: "token1"
1173
+ },
1174
+ {
1175
+ abi: clPoolAbi,
1176
+ address: pool,
1177
+ functionName: "tickSpacing"
1178
+ },
1179
+ {
1180
+ abi: clPoolAbi,
1181
+ address: pool,
1182
+ functionName: "fee"
1183
+ },
1184
+ {
1185
+ abi: clPoolAbi,
1186
+ address: pool,
1187
+ functionName: "liquidity"
1188
+ },
1189
+ {
1190
+ abi: clPoolAbi,
1191
+ address: pool,
1192
+ functionName: "slot0"
1193
+ }
1194
+ ]);
1195
+ const values = await multicallStrict(client, poolContracts);
1196
+ return poolAddresses.map((pool, i) => ({
1197
+ pool,
1198
+ token0: values[i * 6],
1199
+ token1: values[i * 6 + 1],
1200
+ tickSpacing: Number(values[i * 6 + 2]),
1201
+ fee: Number(values[i * 6 + 3]),
1202
+ liquidity: values[i * 6 + 4],
1203
+ slot0: values[i * 6 + 5]
1204
+ }));
1205
+ }
1206
+ function toPoolRow(pool, tokenMeta) {
1207
+ const token0 = tokenMeta.get(pool.token0) ?? toTokenMetaFallback(pool.token0);
1208
+ const token1 = tokenMeta.get(pool.token1) ?? toTokenMetaFallback(pool.token1);
1209
+ const prices = derivePrices(pool.slot0[0], token0.decimals, token1.decimals);
1210
+ const activeLiquidityEstimate = estimateActiveLiquidity(
1211
+ pool.liquidity,
1212
+ pool.slot0[0],
1213
+ token0.decimals,
1214
+ token1.decimals,
1215
+ prices
1216
+ );
1217
+ return {
1218
+ pool: checksumAddress(pool.pool),
1219
+ pair: `${token0.symbol}/${token1.symbol}`,
1220
+ token0,
1221
+ token1,
1222
+ fee: pool.fee,
1223
+ feePercent: pool.fee / 1e4,
1224
+ tickSpacing: pool.tickSpacing,
1225
+ liquidity: pool.liquidity.toString(),
1226
+ currentTick: pool.slot0[1],
1227
+ sqrtPriceX96: pool.slot0[0].toString(),
1228
+ activeLiquidityEstimate,
1229
+ price: prices
1230
+ };
1231
+ }
1232
+ function normalizeAddress(address) {
1233
+ return address.toLowerCase();
1234
+ }
1235
+ var cl = Cli.create("cl", {
1236
+ description: "Concentrated liquidity (Slipstream) pools, positions, and quotes."
1237
+ });
1238
+ cl.command("pools", {
1239
+ description: "List Slipstream pools with current state, prices, and active liquidity estimate.",
1240
+ env,
1241
+ output: z.object({
1242
+ count: z.number(),
1243
+ pools: z.array(poolRowSchema)
1244
+ }),
1245
+ async run(c) {
1246
+ const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
1247
+ const pools = await listPoolAddresses(client);
1248
+ const poolStates = await readPoolStates(client, pools);
1249
+ const tokenMeta = await readTokenMetadata(
1250
+ client,
1251
+ poolStates.flatMap((pool) => [pool.token0, pool.token1])
1252
+ );
1253
+ const rows = poolStates.map((pool) => toPoolRow(pool, tokenMeta));
1254
+ return c.ok({
1255
+ count: rows.length,
1256
+ pools: rows
1257
+ });
1258
+ }
1259
+ });
1260
+ cl.command("pool", {
1261
+ description: "Get detailed state for a Slipstream pool address.",
1262
+ args: z.object({
1263
+ pool: z.string().describe("Pool address")
1264
+ }),
1265
+ env,
1266
+ output: z.object({
1267
+ pool: poolRowSchema
1268
+ }),
1269
+ async run(c) {
1270
+ if (!isAddress(c.args.pool)) {
1271
+ return c.error({
1272
+ code: "INVALID_ADDRESS",
1273
+ message: `Invalid pool address: "${c.args.pool}". Use a valid 0x-prefixed 20-byte hex address.`
1274
+ });
1275
+ }
1276
+ const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
1277
+ const checksummedPool = checksumAddress(c.args.pool);
1278
+ const [poolState] = await readPoolStates(client, [checksummedPool]);
1279
+ const tokenMeta = await readTokenMetadata(client, [poolState.token0, poolState.token1]);
1280
+ return c.ok({
1281
+ pool: toPoolRow(poolState, tokenMeta)
1282
+ });
1283
+ }
1284
+ });
1285
+ cl.command("positions", {
1286
+ description: "List concentrated liquidity NFT positions for an owner.",
1287
+ args: z.object({
1288
+ owner: z.string().describe("Owner wallet address")
1289
+ }),
1290
+ env,
1291
+ output: z.object({
1292
+ owner: z.string(),
1293
+ count: z.number(),
1294
+ positions: z.array(
1295
+ z.object({
1296
+ tokenId: z.string(),
1297
+ pair: z.string(),
1298
+ token0: tokenSchema,
1299
+ token1: tokenSchema,
1300
+ tickSpacing: z.number(),
1301
+ tickLower: z.number(),
1302
+ tickUpper: z.number(),
1303
+ liquidity: z.string(),
1304
+ tokensOwed0: z.object({ raw: z.string(), decimal: z.string() }),
1305
+ tokensOwed1: z.object({ raw: z.string(), decimal: z.string() })
1306
+ })
1307
+ )
1308
+ }),
1309
+ async run(c) {
1310
+ if (!isAddress(c.args.owner)) {
1311
+ return c.error({
1312
+ code: "INVALID_ADDRESS",
1313
+ message: `Invalid owner address: "${c.args.owner}". Use a valid 0x-prefixed 20-byte hex address.`
1314
+ });
1315
+ }
1316
+ const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
1317
+ const owner = checksumAddress(c.args.owner);
1318
+ const balance = await client.readContract({
1319
+ abi: nonfungiblePositionManagerAbi,
1320
+ address: ABOREAN_CL_ADDRESSES.nonfungiblePositionManager,
1321
+ functionName: "balanceOf",
1322
+ args: [owner]
1323
+ });
1324
+ if (balance === 0n) {
1325
+ return c.ok({ owner, count: 0, positions: [] });
1326
+ }
1327
+ const tokenIdContracts = Array.from({ length: Number(balance) }, (_, i) => ({
1328
+ abi: nonfungiblePositionManagerAbi,
1329
+ address: ABOREAN_CL_ADDRESSES.nonfungiblePositionManager,
1330
+ functionName: "tokenOfOwnerByIndex",
1331
+ args: [owner, BigInt(i)]
1332
+ }));
1333
+ const tokenIds = await multicallStrict(client, tokenIdContracts);
1334
+ const positionContracts = tokenIds.map((tokenId) => ({
1335
+ abi: nonfungiblePositionManagerAbi,
1336
+ address: ABOREAN_CL_ADDRESSES.nonfungiblePositionManager,
1337
+ functionName: "positions",
1338
+ args: [tokenId]
1339
+ }));
1340
+ const positionsRaw = await multicallStrict(client, positionContracts);
1341
+ const tokenMeta = await readTokenMetadata(
1342
+ client,
1343
+ positionsRaw.flatMap((position) => [position[2], position[3]])
1344
+ );
1345
+ const positions = tokenIds.map((tokenId, i) => {
1346
+ const position = positionsRaw[i];
1347
+ const token0 = tokenMeta.get(position[2]) ?? toTokenMetaFallback(position[2]);
1348
+ const token1 = tokenMeta.get(position[3]) ?? toTokenMetaFallback(position[3]);
1349
+ return {
1350
+ tokenId: tokenId.toString(),
1351
+ pair: `${token0.symbol}/${token1.symbol}`,
1352
+ token0,
1353
+ token1,
1354
+ tickSpacing: position[4],
1355
+ tickLower: position[5],
1356
+ tickUpper: position[6],
1357
+ liquidity: position[7].toString(),
1358
+ tokensOwed0: {
1359
+ raw: position[10].toString(),
1360
+ decimal: formatUnits(position[10], token0.decimals)
1361
+ },
1362
+ tokensOwed1: {
1363
+ raw: position[11].toString(),
1364
+ decimal: formatUnits(position[11], token1.decimals)
1365
+ }
1366
+ };
1367
+ });
1368
+ return c.ok({
1369
+ owner,
1370
+ count: positions.length,
1371
+ positions
1372
+ });
1373
+ }
1374
+ });
1375
+ cl.command("quote", {
1376
+ description: "Quote a single-hop Slipstream swap via QuoterV2.",
1377
+ args: z.object({
1378
+ tokenIn: z.string().describe("Input token address"),
1379
+ tokenOut: z.string().describe("Output token address"),
1380
+ amountIn: z.string().describe("Input amount in human-readable decimal units")
1381
+ }),
1382
+ options: z.object({
1383
+ fee: z.coerce.number().int().positive().optional().describe("Optional fee tier filter")
1384
+ }),
1385
+ env,
1386
+ output: quoteOutputSchema,
1387
+ async run(c) {
1388
+ const { tokenIn, tokenOut, amountIn } = c.args;
1389
+ if (!isAddress(tokenIn) || !isAddress(tokenOut)) {
1390
+ return c.error({
1391
+ code: "INVALID_ADDRESS",
1392
+ message: "tokenIn and tokenOut must both be valid 0x-prefixed 20-byte addresses."
1393
+ });
1394
+ }
1395
+ const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
1396
+ const inAddress = checksumAddress(tokenIn);
1397
+ const outAddress = checksumAddress(tokenOut);
1398
+ const allPools = await listPoolAddresses(client);
1399
+ const poolStates = await readPoolStates(client, allPools);
1400
+ const pairPools = poolStates.filter((pool) => {
1401
+ const a = normalizeAddress(pool.token0);
1402
+ const b = normalizeAddress(pool.token1);
1403
+ const tokenInNorm = normalizeAddress(inAddress);
1404
+ const tokenOutNorm = normalizeAddress(outAddress);
1405
+ return a === tokenInNorm && b === tokenOutNorm || a === tokenOutNorm && b === tokenInNorm;
1406
+ });
1407
+ const filteredPools = typeof c.options.fee === "number" ? pairPools.filter((pool) => pool.fee === c.options.fee) : pairPools;
1408
+ if (filteredPools.length === 0) {
1409
+ return c.error({
1410
+ code: "POOL_NOT_FOUND",
1411
+ message: typeof c.options.fee === "number" ? `No Slipstream pool found for pair ${inAddress}/${outAddress} at fee tier ${c.options.fee}.` : `No Slipstream pool found for pair ${inAddress}/${outAddress}.`
1412
+ });
1413
+ }
1414
+ const selectedPool = [...filteredPools].sort((a, b) => {
1415
+ if (a.liquidity === b.liquidity) return 0;
1416
+ return a.liquidity > b.liquidity ? -1 : 1;
1417
+ })[0];
1418
+ const tokenMeta = await readTokenMetadata(client, [inAddress, outAddress]);
1419
+ const inMeta = tokenMeta.get(inAddress) ?? toTokenMetaFallback(inAddress);
1420
+ const outMeta = tokenMeta.get(outAddress) ?? toTokenMetaFallback(outAddress);
1421
+ let amountInRaw;
1422
+ try {
1423
+ amountInRaw = parseUnits(amountIn, inMeta.decimals);
1424
+ } catch {
1425
+ return c.error({
1426
+ code: "INVALID_AMOUNT",
1427
+ message: `Invalid amountIn: "${amountIn}" for token ${inMeta.symbol} (${inMeta.decimals} decimals).`
1428
+ });
1429
+ }
1430
+ const quote = await client.readContract({
1431
+ abi: quoterV2Abi,
1432
+ address: ABOREAN_CL_ADDRESSES.quoterV2,
1433
+ functionName: "quoteExactInputSingle",
1434
+ args: [
1435
+ {
1436
+ tokenIn: inAddress,
1437
+ tokenOut: outAddress,
1438
+ amountIn: amountInRaw,
1439
+ tickSpacing: selectedPool.tickSpacing,
1440
+ sqrtPriceLimitX96: 0n
1441
+ }
1442
+ ]
1443
+ });
1444
+ const amountOutRaw = quote[0];
1445
+ const amountOutDecimal = formatUnits(amountOutRaw, outMeta.decimals);
1446
+ const amountInDecimal = formatUnits(amountInRaw, inMeta.decimals);
1447
+ const quotePriceOutPerIn = Number(amountInDecimal) === 0 ? null : finiteOrNull(Number(amountOutDecimal) / Number(amountInDecimal));
1448
+ const poolTokenMeta = await readTokenMetadata(client, [
1449
+ selectedPool.token0,
1450
+ selectedPool.token1
1451
+ ]);
1452
+ const poolToken0Meta = poolTokenMeta.get(selectedPool.token0) ?? toTokenMetaFallback(selectedPool.token0);
1453
+ const poolToken1Meta = poolTokenMeta.get(selectedPool.token1) ?? toTokenMetaFallback(selectedPool.token1);
1454
+ const poolPrices = derivePrices(
1455
+ selectedPool.slot0[0],
1456
+ poolToken0Meta.decimals,
1457
+ poolToken1Meta.decimals
1458
+ );
1459
+ const inIsToken0 = normalizeAddress(inAddress) === normalizeAddress(selectedPool.token0);
1460
+ const poolMidPriceOutPerIn = inIsToken0 ? poolPrices.token1PerToken0 : poolPrices.token0PerToken1;
1461
+ const priceImpactPct = quotePriceOutPerIn === null || poolMidPriceOutPerIn === null || poolMidPriceOutPerIn === 0 ? null : finiteOrNull((poolMidPriceOutPerIn - quotePriceOutPerIn) / poolMidPriceOutPerIn * 100);
1462
+ return c.ok({
1463
+ pool: checksumAddress(selectedPool.pool),
1464
+ selectedFee: selectedPool.fee,
1465
+ selectedTickSpacing: selectedPool.tickSpacing,
1466
+ tokenIn: inMeta,
1467
+ tokenOut: outMeta,
1468
+ amountIn: {
1469
+ raw: amountInRaw.toString(),
1470
+ decimal: amountInDecimal
1471
+ },
1472
+ amountOut: {
1473
+ raw: amountOutRaw.toString(),
1474
+ decimal: amountOutDecimal
1475
+ },
1476
+ execution: {
1477
+ sqrtPriceX96After: quote[1].toString(),
1478
+ initializedTicksCrossed: quote[2],
1479
+ gasEstimate: quote[3].toString()
1480
+ },
1481
+ prices: {
1482
+ poolMidPriceOutPerIn,
1483
+ quotePriceOutPerIn,
1484
+ priceImpactPct
1485
+ }
1486
+ });
1487
+ }
1488
+ });
1489
+
1490
+ // src/commands/gauges.ts
1491
+ import { Cli as Cli2, z as z2 } from "incur";
1492
+
1493
+ // src/commands/_common.ts
1494
+ import { checksumAddress as checksumAddress2, weiToEth } from "@spectratools/cli-shared";
1495
+ var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
1496
+ function toChecksum(address) {
1497
+ try {
1498
+ return checksumAddress2(address);
1499
+ } catch {
1500
+ return address;
1501
+ }
1502
+ }
1503
+ function asNum(value) {
1504
+ return Number(value);
1505
+ }
1506
+ function relTime(unixSeconds) {
1507
+ const ts = typeof unixSeconds === "bigint" ? Number(unixSeconds) : unixSeconds;
1508
+ if (!Number.isFinite(ts) || ts <= 0) return "n/a";
1509
+ const delta = ts - Math.floor(Date.now() / 1e3);
1510
+ const abs = Math.abs(delta);
1511
+ const hours = Math.floor(abs / 3600);
1512
+ const minutes = Math.floor(abs % 3600 / 60);
1513
+ const label = hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`;
1514
+ return delta >= 0 ? `in ${label}` : `${label} ago`;
1515
+ }
1516
+ function clampPositive(seconds) {
1517
+ return seconds > 0 ? seconds : 0;
1518
+ }
1519
+
1520
+ // src/commands/gauges.ts
1521
+ var env2 = z2.object({
1522
+ ABSTRACT_RPC_URL: z2.string().optional().describe("Abstract RPC URL override")
1523
+ });
1524
+ async function discoverGaugePools(client) {
1525
+ const [v2PoolCount, clPoolCount] = await Promise.all([
1526
+ client.readContract({
1527
+ abi: poolFactoryAbi,
1528
+ address: ABOREAN_V2_ADDRESSES.poolFactory,
1529
+ functionName: "allPoolsLength"
1530
+ }),
1531
+ client.readContract({
1532
+ abi: clFactoryAbi,
1533
+ address: ABOREAN_CL_ADDRESSES.clFactory,
1534
+ functionName: "allPoolsLength"
1535
+ })
1536
+ ]);
1537
+ const v2Indices = Array.from({ length: asNum(v2PoolCount) }, (_, i) => BigInt(i));
1538
+ const clIndices = Array.from({ length: asNum(clPoolCount) }, (_, i) => BigInt(i));
1539
+ const [v2Pools, clPools] = await Promise.all([
1540
+ v2Indices.length ? client.multicall({
1541
+ allowFailure: false,
1542
+ contracts: v2Indices.map((index) => ({
1543
+ abi: poolFactoryAbi,
1544
+ address: ABOREAN_V2_ADDRESSES.poolFactory,
1545
+ functionName: "allPools",
1546
+ args: [index]
1547
+ }))
1548
+ }) : Promise.resolve([]),
1549
+ clIndices.length ? client.multicall({
1550
+ allowFailure: false,
1551
+ contracts: clIndices.map((index) => ({
1552
+ abi: clFactoryAbi,
1553
+ address: ABOREAN_CL_ADDRESSES.clFactory,
1554
+ functionName: "allPools",
1555
+ args: [index]
1556
+ }))
1557
+ }) : Promise.resolve([])
1558
+ ]);
1559
+ const pools = [...v2Pools, ...clPools];
1560
+ if (!pools.length) return [];
1561
+ const gauges2 = await client.multicall({
1562
+ allowFailure: false,
1563
+ contracts: pools.map((pool) => ({
1564
+ abi: voterAbi,
1565
+ address: ABOREAN_V2_ADDRESSES.voter,
1566
+ functionName: "gauges",
1567
+ args: [pool]
1568
+ }))
1569
+ });
1570
+ return pools.map((pool, index) => ({ pool, gauge: gauges2[index] })).filter(({ gauge }) => gauge.toLowerCase() !== ZERO_ADDRESS.toLowerCase());
1571
+ }
1572
+ var gauges = Cli2.create("gauges", {
1573
+ description: "Inspect Aborean gauge emissions, staking, and user positions."
1574
+ });
1575
+ gauges.command("list", {
1576
+ description: "List active gauges with pool, emissions, and staking stats.",
1577
+ env: env2,
1578
+ output: z2.object({
1579
+ gauges: z2.array(
1580
+ z2.object({
1581
+ pool: z2.string(),
1582
+ gauge: z2.string(),
1583
+ rewardToken: z2.string(),
1584
+ rewardRate: z2.string(),
1585
+ totalStaked: z2.string(),
1586
+ claimableEmissions: z2.string(),
1587
+ periodFinish: z2.number(),
1588
+ periodFinishRelative: z2.string()
1589
+ })
1590
+ ),
1591
+ count: z2.number()
1592
+ }),
1593
+ examples: [{ description: "List all active gauges and current emissions state" }],
1594
+ async run(c) {
1595
+ const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
1596
+ const gaugePools = await discoverGaugePools(client);
1597
+ if (!gaugePools.length) {
1598
+ return c.ok({ gauges: [], count: 0 });
1599
+ }
1600
+ const details = await client.multicall({
1601
+ allowFailure: false,
1602
+ contracts: gaugePools.flatMap(({ gauge }) => [
1603
+ {
1604
+ abi: gaugeAbi,
1605
+ address: gauge,
1606
+ functionName: "rewardToken"
1607
+ },
1608
+ {
1609
+ abi: gaugeAbi,
1610
+ address: gauge,
1611
+ functionName: "rewardRate"
1612
+ },
1613
+ {
1614
+ abi: gaugeAbi,
1615
+ address: gauge,
1616
+ functionName: "totalSupply"
1617
+ },
1618
+ {
1619
+ abi: gaugeAbi,
1620
+ address: gauge,
1621
+ functionName: "periodFinish"
1622
+ },
1623
+ {
1624
+ abi: voterAbi,
1625
+ address: ABOREAN_V2_ADDRESSES.voter,
1626
+ functionName: "claimable",
1627
+ args: [gauge]
1628
+ }
1629
+ ])
1630
+ });
1631
+ const items = gaugePools.map(({ pool, gauge }, index) => {
1632
+ const offset = index * 5;
1633
+ const rewardToken = details[offset];
1634
+ const rewardRate = details[offset + 1];
1635
+ const totalStaked = details[offset + 2];
1636
+ const periodFinish = details[offset + 3];
1637
+ const claimableEmissions = details[offset + 4];
1638
+ return {
1639
+ pool: toChecksum(pool),
1640
+ gauge: toChecksum(gauge),
1641
+ rewardToken: toChecksum(rewardToken),
1642
+ rewardRate: rewardRate.toString(),
1643
+ totalStaked: totalStaked.toString(),
1644
+ claimableEmissions: claimableEmissions.toString(),
1645
+ periodFinish: asNum(periodFinish),
1646
+ periodFinishRelative: relTime(periodFinish)
1647
+ };
1648
+ });
1649
+ return c.ok({
1650
+ gauges: items,
1651
+ count: items.length
1652
+ });
1653
+ }
1654
+ });
1655
+ gauges.command("info", {
1656
+ description: "Get detailed state for one gauge address.",
1657
+ args: z2.object({
1658
+ gauge: z2.string().describe("Gauge contract address")
1659
+ }),
1660
+ env: env2,
1661
+ output: z2.object({
1662
+ gauge: z2.string(),
1663
+ pool: z2.string(),
1664
+ isAlive: z2.boolean(),
1665
+ stakingToken: z2.string(),
1666
+ rewardToken: z2.string(),
1667
+ totalStaked: z2.string(),
1668
+ rewardRate: z2.string(),
1669
+ rewardPerTokenStored: z2.string(),
1670
+ fees0: z2.string(),
1671
+ fees1: z2.string(),
1672
+ left: z2.string(),
1673
+ periodFinish: z2.number(),
1674
+ periodFinishRelative: z2.string(),
1675
+ lastUpdateTime: z2.number(),
1676
+ bribeContract: z2.string(),
1677
+ feeContract: z2.string()
1678
+ }),
1679
+ examples: [
1680
+ {
1681
+ args: { gauge: "0x0000000000000000000000000000000000000001" },
1682
+ description: "Inspect one gauge in detail"
1683
+ }
1684
+ ],
1685
+ async run(c) {
1686
+ const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
1687
+ const gauge = c.args.gauge;
1688
+ const [
1689
+ pool,
1690
+ isAlive,
1691
+ bribeContract,
1692
+ feeContract,
1693
+ stakingToken,
1694
+ rewardToken,
1695
+ totalStaked,
1696
+ rewardRate,
1697
+ periodFinish,
1698
+ lastUpdateTime,
1699
+ rewardPerTokenStored,
1700
+ fees0,
1701
+ fees1,
1702
+ left
1703
+ ] = await Promise.all([
1704
+ client.readContract({
1705
+ abi: voterAbi,
1706
+ address: ABOREAN_V2_ADDRESSES.voter,
1707
+ functionName: "poolForGauge",
1708
+ args: [gauge]
1709
+ }),
1710
+ client.readContract({
1711
+ abi: voterAbi,
1712
+ address: ABOREAN_V2_ADDRESSES.voter,
1713
+ functionName: "isAlive",
1714
+ args: [gauge]
1715
+ }),
1716
+ client.readContract({
1717
+ abi: voterAbi,
1718
+ address: ABOREAN_V2_ADDRESSES.voter,
1719
+ functionName: "gaugeToBribe",
1720
+ args: [gauge]
1721
+ }),
1722
+ client.readContract({
1723
+ abi: voterAbi,
1724
+ address: ABOREAN_V2_ADDRESSES.voter,
1725
+ functionName: "gaugeToFees",
1726
+ args: [gauge]
1727
+ }),
1728
+ client.readContract({
1729
+ abi: gaugeAbi,
1730
+ address: gauge,
1731
+ functionName: "stakingToken"
1732
+ }),
1733
+ client.readContract({
1734
+ abi: gaugeAbi,
1735
+ address: gauge,
1736
+ functionName: "rewardToken"
1737
+ }),
1738
+ client.readContract({
1739
+ abi: gaugeAbi,
1740
+ address: gauge,
1741
+ functionName: "totalSupply"
1742
+ }),
1743
+ client.readContract({
1744
+ abi: gaugeAbi,
1745
+ address: gauge,
1746
+ functionName: "rewardRate"
1747
+ }),
1748
+ client.readContract({
1749
+ abi: gaugeAbi,
1750
+ address: gauge,
1751
+ functionName: "periodFinish"
1752
+ }),
1753
+ client.readContract({
1754
+ abi: gaugeAbi,
1755
+ address: gauge,
1756
+ functionName: "lastUpdateTime"
1757
+ }),
1758
+ client.readContract({
1759
+ abi: gaugeAbi,
1760
+ address: gauge,
1761
+ functionName: "rewardPerTokenStored"
1762
+ }),
1763
+ client.readContract({
1764
+ abi: gaugeAbi,
1765
+ address: gauge,
1766
+ functionName: "fees0"
1767
+ }),
1768
+ client.readContract({
1769
+ abi: gaugeAbi,
1770
+ address: gauge,
1771
+ functionName: "fees1"
1772
+ }),
1773
+ client.readContract({
1774
+ abi: gaugeAbi,
1775
+ address: gauge,
1776
+ functionName: "left"
1777
+ })
1778
+ ]);
1779
+ return c.ok({
1780
+ gauge: toChecksum(gauge),
1781
+ pool: toChecksum(pool),
1782
+ isAlive,
1783
+ stakingToken: toChecksum(stakingToken),
1784
+ rewardToken: toChecksum(rewardToken),
1785
+ totalStaked: totalStaked.toString(),
1786
+ rewardRate: rewardRate.toString(),
1787
+ rewardPerTokenStored: rewardPerTokenStored.toString(),
1788
+ fees0: fees0.toString(),
1789
+ fees1: fees1.toString(),
1790
+ left: left.toString(),
1791
+ periodFinish: asNum(periodFinish),
1792
+ periodFinishRelative: relTime(periodFinish),
1793
+ lastUpdateTime: asNum(lastUpdateTime),
1794
+ bribeContract: toChecksum(bribeContract),
1795
+ feeContract: toChecksum(feeContract)
1796
+ });
1797
+ }
1798
+ });
1799
+ gauges.command("staked", {
1800
+ description: "Show one address staking positions across all gauges.",
1801
+ args: z2.object({
1802
+ address: z2.string().describe("Wallet address to inspect")
1803
+ }),
1804
+ env: env2,
1805
+ output: z2.object({
1806
+ address: z2.string(),
1807
+ positions: z2.array(
1808
+ z2.object({
1809
+ pool: z2.string(),
1810
+ gauge: z2.string(),
1811
+ rewardToken: z2.string(),
1812
+ staked: z2.string(),
1813
+ earned: z2.string()
1814
+ })
1815
+ ),
1816
+ count: z2.number()
1817
+ }),
1818
+ examples: [
1819
+ {
1820
+ args: { address: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" },
1821
+ description: "List gauge positions for a wallet"
1822
+ }
1823
+ ],
1824
+ async run(c) {
1825
+ const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
1826
+ const gaugePools = await discoverGaugePools(client);
1827
+ if (!gaugePools.length) {
1828
+ return c.ok({
1829
+ address: toChecksum(c.args.address),
1830
+ positions: [],
1831
+ count: 0
1832
+ });
1833
+ }
1834
+ const positionData = await client.multicall({
1835
+ allowFailure: false,
1836
+ contracts: gaugePools.flatMap(({ gauge }) => [
1837
+ {
1838
+ abi: gaugeAbi,
1839
+ address: gauge,
1840
+ functionName: "balanceOf",
1841
+ args: [c.args.address]
1842
+ },
1843
+ {
1844
+ abi: gaugeAbi,
1845
+ address: gauge,
1846
+ functionName: "earned",
1847
+ args: [c.args.address]
1848
+ },
1849
+ {
1850
+ abi: gaugeAbi,
1851
+ address: gauge,
1852
+ functionName: "rewardToken"
1853
+ }
1854
+ ])
1855
+ });
1856
+ const positions = gaugePools.map(({ pool, gauge }, index) => {
1857
+ const offset = index * 3;
1858
+ const staked = positionData[offset];
1859
+ const earned = positionData[offset + 1];
1860
+ const rewardToken = positionData[offset + 2];
1861
+ return {
1862
+ pool: toChecksum(pool),
1863
+ gauge: toChecksum(gauge),
1864
+ rewardToken: toChecksum(rewardToken),
1865
+ staked,
1866
+ earned
1867
+ };
1868
+ }).filter((position) => position.staked > 0n || position.earned > 0n).map((position) => ({
1869
+ pool: position.pool,
1870
+ gauge: position.gauge,
1871
+ rewardToken: position.rewardToken,
1872
+ staked: position.staked.toString(),
1873
+ earned: position.earned.toString()
1874
+ }));
1875
+ return c.ok({
1876
+ address: toChecksum(c.args.address),
1877
+ positions,
1878
+ count: positions.length
1879
+ });
1880
+ }
1881
+ });
1882
+
1883
+ // src/commands/ve.ts
1884
+ import { Cli as Cli3, z as z3 } from "incur";
1885
+ var env3 = z3.object({
1886
+ ABSTRACT_RPC_URL: z3.string().optional().describe("Abstract RPC URL override")
1887
+ });
1888
+ var ve = Cli3.create("ve", {
1889
+ description: "Inspect Aborean VotingEscrow (veABX) global and per-NFT lock state."
1890
+ });
1891
+ ve.command("stats", {
1892
+ description: "Get global VotingEscrow supply, locks, and decay checkpoint data.",
1893
+ env: env3,
1894
+ output: z3.object({
1895
+ token: z3.string(),
1896
+ totalVotingPower: z3.string(),
1897
+ totalLocked: z3.string(),
1898
+ permanentLocked: z3.string(),
1899
+ epoch: z3.number(),
1900
+ decayBias: z3.string(),
1901
+ decaySlope: z3.string(),
1902
+ lastCheckpointTimestamp: z3.number(),
1903
+ lastCheckpointBlock: z3.number()
1904
+ }),
1905
+ examples: [{ description: "Show global veABX state and decay metrics" }],
1906
+ async run(c) {
1907
+ const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
1908
+ const [token, totalVotingPower, totalLocked, permanentLocked, epoch] = await Promise.all([
1909
+ client.readContract({
1910
+ abi: votingEscrowAbi,
1911
+ address: ABOREAN_V2_ADDRESSES.votingEscrow,
1912
+ functionName: "token"
1913
+ }),
1914
+ client.readContract({
1915
+ abi: votingEscrowAbi,
1916
+ address: ABOREAN_V2_ADDRESSES.votingEscrow,
1917
+ functionName: "totalSupply"
1918
+ }),
1919
+ client.readContract({
1920
+ abi: votingEscrowAbi,
1921
+ address: ABOREAN_V2_ADDRESSES.votingEscrow,
1922
+ functionName: "supply"
1923
+ }),
1924
+ client.readContract({
1925
+ abi: votingEscrowAbi,
1926
+ address: ABOREAN_V2_ADDRESSES.votingEscrow,
1927
+ functionName: "permanentLockBalance"
1928
+ }),
1929
+ client.readContract({
1930
+ abi: votingEscrowAbi,
1931
+ address: ABOREAN_V2_ADDRESSES.votingEscrow,
1932
+ functionName: "epoch"
1933
+ })
1934
+ ]);
1935
+ const point = await client.readContract({
1936
+ abi: votingEscrowAbi,
1937
+ address: ABOREAN_V2_ADDRESSES.votingEscrow,
1938
+ functionName: "pointHistory",
1939
+ args: [epoch]
1940
+ });
1941
+ return c.ok({
1942
+ token: toChecksum(token),
1943
+ totalVotingPower: totalVotingPower.toString(),
1944
+ totalLocked: totalLocked.toString(),
1945
+ permanentLocked: permanentLocked.toString(),
1946
+ epoch: asNum(epoch),
1947
+ decayBias: point.bias.toString(),
1948
+ decaySlope: point.slope.toString(),
1949
+ lastCheckpointTimestamp: asNum(point.ts),
1950
+ lastCheckpointBlock: asNum(point.blk)
1951
+ });
1952
+ }
1953
+ });
1954
+ ve.command("lock", {
1955
+ description: "Get lock details and voting power for one veNFT token id.",
1956
+ args: z3.object({
1957
+ tokenId: z3.coerce.number().int().nonnegative().describe("veNFT token id")
1958
+ }),
1959
+ env: env3,
1960
+ output: z3.object({
1961
+ tokenId: z3.number(),
1962
+ owner: z3.string(),
1963
+ amount: z3.string(),
1964
+ unlockTime: z3.number(),
1965
+ isPermanent: z3.boolean(),
1966
+ votingPower: z3.string()
1967
+ }),
1968
+ examples: [{ args: { tokenId: 1 }, description: "Inspect lock details for veNFT #1" }],
1969
+ async run(c) {
1970
+ const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
1971
+ const tokenId = BigInt(c.args.tokenId);
1972
+ const [owner, locked, votingPower] = await Promise.all([
1973
+ client.readContract({
1974
+ abi: votingEscrowAbi,
1975
+ address: ABOREAN_V2_ADDRESSES.votingEscrow,
1976
+ functionName: "ownerOf",
1977
+ args: [tokenId]
1978
+ }),
1979
+ client.readContract({
1980
+ abi: votingEscrowAbi,
1981
+ address: ABOREAN_V2_ADDRESSES.votingEscrow,
1982
+ functionName: "locked",
1983
+ args: [tokenId]
1984
+ }),
1985
+ client.readContract({
1986
+ abi: votingEscrowAbi,
1987
+ address: ABOREAN_V2_ADDRESSES.votingEscrow,
1988
+ functionName: "balanceOfNFT",
1989
+ args: [tokenId]
1990
+ })
1991
+ ]);
1992
+ return c.ok({
1993
+ tokenId: c.args.tokenId,
1994
+ owner: toChecksum(owner),
1995
+ amount: locked.amount.toString(),
1996
+ unlockTime: asNum(locked.end),
1997
+ isPermanent: locked.isPermanent,
1998
+ votingPower: votingPower.toString()
1999
+ });
2000
+ }
2001
+ });
2002
+ ve.command("locks", {
2003
+ description: "List all veNFT locks owned by an address.",
2004
+ args: z3.object({
2005
+ address: z3.string().describe("Owner address")
2006
+ }),
2007
+ env: env3,
2008
+ output: z3.object({
2009
+ address: z3.string(),
2010
+ locks: z3.array(
2011
+ z3.object({
2012
+ tokenId: z3.string(),
2013
+ amount: z3.string(),
2014
+ unlockTime: z3.number(),
2015
+ isPermanent: z3.boolean(),
2016
+ votingPower: z3.string()
2017
+ })
2018
+ ),
2019
+ count: z3.number()
2020
+ }),
2021
+ examples: [
2022
+ {
2023
+ args: { address: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" },
2024
+ description: "List all veNFT locks for an address"
2025
+ }
2026
+ ],
2027
+ async run(c) {
2028
+ const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
2029
+ const balance = await client.readContract({
2030
+ abi: votingEscrowAbi,
2031
+ address: ABOREAN_V2_ADDRESSES.votingEscrow,
2032
+ functionName: "balanceOf",
2033
+ args: [c.args.address]
2034
+ });
2035
+ const count = asNum(balance);
2036
+ if (!count) {
2037
+ return c.ok({
2038
+ address: toChecksum(c.args.address),
2039
+ locks: [],
2040
+ count: 0
2041
+ });
439
2042
  }
2043
+ const indices = Array.from({ length: count }, (_, i) => BigInt(i));
2044
+ const tokenIds = await client.multicall({
2045
+ allowFailure: false,
2046
+ contracts: indices.map((index) => ({
2047
+ abi: votingEscrowAbi,
2048
+ address: ABOREAN_V2_ADDRESSES.votingEscrow,
2049
+ functionName: "tokenOfOwnerByIndex",
2050
+ args: [c.args.address, index]
2051
+ }))
2052
+ });
2053
+ const lockData = await client.multicall({
2054
+ allowFailure: false,
2055
+ contracts: tokenIds.flatMap((tokenId) => [
2056
+ {
2057
+ abi: votingEscrowAbi,
2058
+ address: ABOREAN_V2_ADDRESSES.votingEscrow,
2059
+ functionName: "locked",
2060
+ args: [tokenId]
2061
+ },
2062
+ {
2063
+ abi: votingEscrowAbi,
2064
+ address: ABOREAN_V2_ADDRESSES.votingEscrow,
2065
+ functionName: "balanceOfNFT",
2066
+ args: [tokenId]
2067
+ }
2068
+ ])
2069
+ });
2070
+ const locks = tokenIds.map((tokenId, index) => {
2071
+ const offset = index * 2;
2072
+ const locked = lockData[offset];
2073
+ const votingPower = lockData[offset + 1];
2074
+ return {
2075
+ tokenId: tokenId.toString(),
2076
+ amount: locked.amount.toString(),
2077
+ unlockTime: asNum(locked.end),
2078
+ isPermanent: locked.isPermanent,
2079
+ votingPower: votingPower.toString()
2080
+ };
2081
+ });
2082
+ return c.ok({
2083
+ address: toChecksum(c.args.address),
2084
+ locks,
2085
+ count: locks.length
2086
+ });
440
2087
  }
441
2088
  });
442
- function createAboreanPublicClient(rpcUrl) {
443
- return createPublicClient({
444
- chain: abstractMainnet,
445
- transport: http(rpcUrl ?? process.env.ABSTRACT_RPC_URL ?? "https://api.mainnet.abs.xyz")
446
- });
2089
+ ve.command("voting-power", {
2090
+ description: "Get current voting power for one veNFT token id.",
2091
+ args: z3.object({
2092
+ tokenId: z3.coerce.number().int().nonnegative().describe("veNFT token id")
2093
+ }),
2094
+ env: env3,
2095
+ output: z3.object({
2096
+ tokenId: z3.number(),
2097
+ votingPower: z3.string()
2098
+ }),
2099
+ examples: [{ args: { tokenId: 1 }, description: "Get current voting power for veNFT #1" }],
2100
+ async run(c) {
2101
+ const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
2102
+ const votingPower = await client.readContract({
2103
+ abi: votingEscrowAbi,
2104
+ address: ABOREAN_V2_ADDRESSES.votingEscrow,
2105
+ functionName: "balanceOfNFT",
2106
+ args: [BigInt(c.args.tokenId)]
2107
+ });
2108
+ return c.ok({
2109
+ tokenId: c.args.tokenId,
2110
+ votingPower: votingPower.toString()
2111
+ });
2112
+ }
2113
+ });
2114
+
2115
+ // src/commands/voter.ts
2116
+ import { Cli as Cli4, z as z4 } from "incur";
2117
+ var env4 = z4.object({
2118
+ ABSTRACT_RPC_URL: z4.string().optional().describe("Abstract RPC URL override")
2119
+ });
2120
+ async function discoverPools(client) {
2121
+ const [v2PoolCount, clPoolCount] = await Promise.all([
2122
+ client.readContract({
2123
+ abi: poolFactoryAbi,
2124
+ address: ABOREAN_V2_ADDRESSES.poolFactory,
2125
+ functionName: "allPoolsLength"
2126
+ }),
2127
+ client.readContract({
2128
+ abi: clFactoryAbi,
2129
+ address: ABOREAN_CL_ADDRESSES.clFactory,
2130
+ functionName: "allPoolsLength"
2131
+ })
2132
+ ]);
2133
+ const v2Indices = Array.from({ length: asNum(v2PoolCount) }, (_, i) => BigInt(i));
2134
+ const clIndices = Array.from({ length: asNum(clPoolCount) }, (_, i) => BigInt(i));
2135
+ const [v2Pools, clPools] = await Promise.all([
2136
+ v2Indices.length ? client.multicall({
2137
+ allowFailure: false,
2138
+ contracts: v2Indices.map((index) => ({
2139
+ abi: poolFactoryAbi,
2140
+ address: ABOREAN_V2_ADDRESSES.poolFactory,
2141
+ functionName: "allPools",
2142
+ args: [index]
2143
+ }))
2144
+ }) : Promise.resolve([]),
2145
+ clIndices.length ? client.multicall({
2146
+ allowFailure: false,
2147
+ contracts: clIndices.map((index) => ({
2148
+ abi: clFactoryAbi,
2149
+ address: ABOREAN_CL_ADDRESSES.clFactory,
2150
+ functionName: "allPools",
2151
+ args: [index]
2152
+ }))
2153
+ }) : Promise.resolve([])
2154
+ ]);
2155
+ return [...v2Pools, ...clPools];
447
2156
  }
2157
+ var voter = Cli4.create("voter", {
2158
+ description: "Inspect Aborean voter epoch, pool weights, and claimable rewards context."
2159
+ });
2160
+ voter.command("epoch", {
2161
+ description: "Show current emissions epoch timing from Minter.",
2162
+ env: env4,
2163
+ output: z4.object({
2164
+ activePeriod: z4.number(),
2165
+ epochEnd: z4.number(),
2166
+ secondsRemaining: z4.number(),
2167
+ timeRemaining: z4.string(),
2168
+ weekSeconds: z4.number(),
2169
+ epochCount: z4.number(),
2170
+ weeklyEmission: z4.string()
2171
+ }),
2172
+ examples: [{ description: "Inspect current voter epoch boundaries" }],
2173
+ async run(c) {
2174
+ const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
2175
+ const [activePeriod, weekSeconds, epochCount, weeklyEmission] = await Promise.all([
2176
+ client.readContract({
2177
+ abi: minterAbi,
2178
+ address: ABOREAN_V2_ADDRESSES.minter,
2179
+ functionName: "activePeriod"
2180
+ }),
2181
+ client.readContract({
2182
+ abi: minterAbi,
2183
+ address: ABOREAN_V2_ADDRESSES.minter,
2184
+ functionName: "WEEK"
2185
+ }),
2186
+ client.readContract({
2187
+ abi: minterAbi,
2188
+ address: ABOREAN_V2_ADDRESSES.minter,
2189
+ functionName: "epochCount"
2190
+ }),
2191
+ client.readContract({
2192
+ abi: minterAbi,
2193
+ address: ABOREAN_V2_ADDRESSES.minter,
2194
+ functionName: "weekly"
2195
+ })
2196
+ ]);
2197
+ const now = Math.floor(Date.now() / 1e3);
2198
+ const epochEnd = asNum(activePeriod + weekSeconds);
2199
+ return c.ok({
2200
+ activePeriod: asNum(activePeriod),
2201
+ epochEnd,
2202
+ secondsRemaining: clampPositive(epochEnd - now),
2203
+ timeRemaining: relTime(activePeriod + weekSeconds),
2204
+ weekSeconds: asNum(weekSeconds),
2205
+ epochCount: asNum(epochCount),
2206
+ weeklyEmission: weeklyEmission.toString()
2207
+ });
2208
+ }
2209
+ });
2210
+ voter.command("weights", {
2211
+ description: "Show current pool voting weight distribution.",
2212
+ env: env4,
2213
+ output: z4.object({
2214
+ totalWeight: z4.string(),
2215
+ pools: z4.array(
2216
+ z4.object({
2217
+ pool: z4.string(),
2218
+ gauge: z4.string(),
2219
+ weight: z4.string()
2220
+ })
2221
+ ),
2222
+ count: z4.number()
2223
+ }),
2224
+ examples: [{ description: "List all pools with non-zero voting weight" }],
2225
+ async run(c) {
2226
+ const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
2227
+ const pools = await discoverPools(client);
2228
+ if (!pools.length) {
2229
+ return c.ok({ totalWeight: "0", pools: [], count: 0 });
2230
+ }
2231
+ const [totalWeight, poolData] = await Promise.all([
2232
+ client.readContract({
2233
+ abi: voterAbi,
2234
+ address: ABOREAN_V2_ADDRESSES.voter,
2235
+ functionName: "totalWeight"
2236
+ }),
2237
+ client.multicall({
2238
+ allowFailure: false,
2239
+ contracts: pools.flatMap((pool) => [
2240
+ {
2241
+ abi: voterAbi,
2242
+ address: ABOREAN_V2_ADDRESSES.voter,
2243
+ functionName: "gauges",
2244
+ args: [pool]
2245
+ },
2246
+ {
2247
+ abi: voterAbi,
2248
+ address: ABOREAN_V2_ADDRESSES.voter,
2249
+ functionName: "weights",
2250
+ args: [pool]
2251
+ }
2252
+ ])
2253
+ })
2254
+ ]);
2255
+ const entries = pools.map((pool, index) => {
2256
+ const offset = index * 2;
2257
+ const gauge = poolData[offset] ?? ZERO_ADDRESS;
2258
+ const weight = poolData[offset + 1] ?? 0n;
2259
+ return {
2260
+ pool,
2261
+ gauge,
2262
+ weight
2263
+ };
2264
+ }).filter(
2265
+ (entry) => entry.gauge.toLowerCase() !== ZERO_ADDRESS.toLowerCase() && entry.weight > 0n
2266
+ ).sort((a, b) => a.weight > b.weight ? -1 : a.weight < b.weight ? 1 : 0).map((entry) => ({
2267
+ pool: toChecksum(entry.pool),
2268
+ gauge: toChecksum(entry.gauge),
2269
+ weight: entry.weight.toString()
2270
+ }));
2271
+ return c.ok({
2272
+ totalWeight: totalWeight.toString(),
2273
+ pools: entries,
2274
+ count: entries.length
2275
+ });
2276
+ }
2277
+ });
2278
+ voter.command("rewards", {
2279
+ description: "Show claimable rebase rewards and voting context for a veNFT.",
2280
+ args: z4.object({
2281
+ tokenId: z4.coerce.number().int().nonnegative().describe("veNFT token id")
2282
+ }),
2283
+ env: env4,
2284
+ output: z4.object({
2285
+ tokenId: z4.number(),
2286
+ rewardToken: z4.string(),
2287
+ claimableRebase: z4.string(),
2288
+ timeCursor: z4.number(),
2289
+ lastTokenTime: z4.number(),
2290
+ distributorStartTime: z4.number(),
2291
+ usedWeight: z4.string(),
2292
+ lastVoted: z4.number()
2293
+ }),
2294
+ examples: [{ args: { tokenId: 1 }, description: "Check claimable voter/distributor rewards" }],
2295
+ async run(c) {
2296
+ const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
2297
+ const tokenId = BigInt(c.args.tokenId);
2298
+ const [
2299
+ rewardToken,
2300
+ claimableRebase,
2301
+ timeCursor,
2302
+ lastTokenTime,
2303
+ distributorStartTime,
2304
+ usedWeight,
2305
+ lastVoted
2306
+ ] = await Promise.all([
2307
+ client.readContract({
2308
+ abi: rewardsDistributorAbi,
2309
+ address: ABOREAN_V2_ADDRESSES.rewardsDistributor,
2310
+ functionName: "token"
2311
+ }),
2312
+ client.readContract({
2313
+ abi: rewardsDistributorAbi,
2314
+ address: ABOREAN_V2_ADDRESSES.rewardsDistributor,
2315
+ functionName: "claimable",
2316
+ args: [tokenId]
2317
+ }),
2318
+ client.readContract({
2319
+ abi: rewardsDistributorAbi,
2320
+ address: ABOREAN_V2_ADDRESSES.rewardsDistributor,
2321
+ functionName: "timeCursorOf",
2322
+ args: [tokenId]
2323
+ }),
2324
+ client.readContract({
2325
+ abi: rewardsDistributorAbi,
2326
+ address: ABOREAN_V2_ADDRESSES.rewardsDistributor,
2327
+ functionName: "lastTokenTime"
2328
+ }),
2329
+ client.readContract({
2330
+ abi: rewardsDistributorAbi,
2331
+ address: ABOREAN_V2_ADDRESSES.rewardsDistributor,
2332
+ functionName: "startTime"
2333
+ }),
2334
+ client.readContract({
2335
+ abi: voterAbi,
2336
+ address: ABOREAN_V2_ADDRESSES.voter,
2337
+ functionName: "usedWeights",
2338
+ args: [tokenId]
2339
+ }),
2340
+ client.readContract({
2341
+ abi: voterAbi,
2342
+ address: ABOREAN_V2_ADDRESSES.voter,
2343
+ functionName: "lastVoted",
2344
+ args: [tokenId]
2345
+ })
2346
+ ]);
2347
+ return c.ok({
2348
+ tokenId: c.args.tokenId,
2349
+ rewardToken: toChecksum(rewardToken),
2350
+ claimableRebase: claimableRebase.toString(),
2351
+ timeCursor: asNum(timeCursor),
2352
+ lastTokenTime: asNum(lastTokenTime),
2353
+ distributorStartTime: asNum(distributorStartTime),
2354
+ usedWeight: usedWeight.toString(),
2355
+ lastVoted: asNum(lastVoted)
2356
+ });
2357
+ }
2358
+ });
2359
+ voter.command("bribes", {
2360
+ description: "Show active bribe reward tokens and current-epoch amounts for a pool.",
2361
+ args: z4.object({
2362
+ pool: z4.string().describe("Pool address")
2363
+ }),
2364
+ env: env4,
2365
+ output: z4.object({
2366
+ pool: z4.string(),
2367
+ gauge: z4.string(),
2368
+ bribeContract: z4.string(),
2369
+ epochStart: z4.number(),
2370
+ rewardTokens: z4.array(
2371
+ z4.object({
2372
+ token: z4.string(),
2373
+ epochAmount: z4.string()
2374
+ })
2375
+ ),
2376
+ count: z4.number()
2377
+ }),
2378
+ examples: [
2379
+ {
2380
+ args: { pool: "0x0000000000000000000000000000000000000001" },
2381
+ description: "Inspect bribe reward tokens for one pool"
2382
+ }
2383
+ ],
2384
+ async run(c) {
2385
+ const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
2386
+ const [gauge, epochStart] = await Promise.all([
2387
+ client.readContract({
2388
+ abi: voterAbi,
2389
+ address: ABOREAN_V2_ADDRESSES.voter,
2390
+ functionName: "gauges",
2391
+ args: [c.args.pool]
2392
+ }),
2393
+ client.readContract({
2394
+ abi: minterAbi,
2395
+ address: ABOREAN_V2_ADDRESSES.minter,
2396
+ functionName: "activePeriod"
2397
+ })
2398
+ ]);
2399
+ if (gauge.toLowerCase() === ZERO_ADDRESS.toLowerCase()) {
2400
+ return c.error({
2401
+ code: "NOT_FOUND",
2402
+ message: `No gauge exists for pool ${c.args.pool}`,
2403
+ retryable: false
2404
+ });
2405
+ }
2406
+ const bribeContract = await client.readContract({
2407
+ abi: voterAbi,
2408
+ address: ABOREAN_V2_ADDRESSES.voter,
2409
+ functionName: "gaugeToBribe",
2410
+ args: [gauge]
2411
+ });
2412
+ if (bribeContract.toLowerCase() === ZERO_ADDRESS.toLowerCase()) {
2413
+ return c.ok({
2414
+ pool: toChecksum(c.args.pool),
2415
+ gauge: toChecksum(gauge),
2416
+ bribeContract: toChecksum(bribeContract),
2417
+ epochStart: asNum(epochStart),
2418
+ rewardTokens: [],
2419
+ count: 0
2420
+ });
2421
+ }
2422
+ const rewardsLength = await client.readContract({
2423
+ abi: votingRewardAbi,
2424
+ address: bribeContract,
2425
+ functionName: "rewardsListLength"
2426
+ });
2427
+ const tokenCount = asNum(rewardsLength);
2428
+ if (!tokenCount) {
2429
+ return c.ok({
2430
+ pool: toChecksum(c.args.pool),
2431
+ gauge: toChecksum(gauge),
2432
+ bribeContract: toChecksum(bribeContract),
2433
+ epochStart: asNum(epochStart),
2434
+ rewardTokens: [],
2435
+ count: 0
2436
+ });
2437
+ }
2438
+ const tokenIndices = Array.from({ length: tokenCount }, (_, i) => BigInt(i));
2439
+ const rewardTokens = await client.multicall({
2440
+ allowFailure: false,
2441
+ contracts: tokenIndices.map((index) => ({
2442
+ abi: votingRewardAbi,
2443
+ address: bribeContract,
2444
+ functionName: "rewards",
2445
+ args: [index]
2446
+ }))
2447
+ });
2448
+ const epochAmounts = await client.multicall({
2449
+ allowFailure: false,
2450
+ contracts: rewardTokens.map((token) => ({
2451
+ abi: votingRewardAbi,
2452
+ address: bribeContract,
2453
+ functionName: "tokenRewardsPerEpoch",
2454
+ args: [token, epochStart]
2455
+ }))
2456
+ });
2457
+ const items = rewardTokens.map((token, index) => ({
2458
+ token: toChecksum(token),
2459
+ epochAmount: epochAmounts[index].toString()
2460
+ }));
2461
+ return c.ok({
2462
+ pool: toChecksum(c.args.pool),
2463
+ gauge: toChecksum(gauge),
2464
+ bribeContract: toChecksum(bribeContract),
2465
+ epochStart: asNum(epochStart),
2466
+ rewardTokens: items,
2467
+ count: items.length
2468
+ });
2469
+ }
2470
+ });
448
2471
 
449
2472
  // src/error-handling.ts
450
2473
  import { AsyncLocalStorage } from "async_hooks";
@@ -576,23 +2599,27 @@ function applyFriendlyErrorHandling(cli2) {
576
2599
  // src/cli.ts
577
2600
  var __dirname = dirname(fileURLToPath(import.meta.url));
578
2601
  var pkg = JSON.parse(readFileSync(resolve(__dirname, "../package.json"), "utf8"));
579
- var cli = Cli.create("aborean", {
2602
+ var cli = Cli5.create("aborean", {
580
2603
  version: pkg.version,
581
2604
  description: "Aborean Finance DEX CLI for Abstract chain."
582
2605
  });
583
- var rootEnv = z.object({
584
- ABSTRACT_RPC_URL: z.string().optional().describe("Abstract RPC URL override")
2606
+ cli.command(gauges);
2607
+ cli.command(ve);
2608
+ cli.command(voter);
2609
+ var rootEnv = z5.object({
2610
+ ABSTRACT_RPC_URL: z5.string().optional().describe("Abstract RPC URL override")
585
2611
  });
2612
+ cli.command(cl);
586
2613
  cli.command("status", {
587
2614
  description: "Get a cross-contract Aborean protocol snapshot (pool counts, gauge count, veABX supply).",
588
2615
  env: rootEnv,
589
- output: z.object({
590
- v2PoolCount: z.number().describe("Number of V2 AMM pools"),
591
- clPoolCount: z.number().describe("Number of Slipstream (CL) pools"),
592
- gaugeCount: z.number().describe("Number of pools with gauges"),
593
- totalVotingWeight: z.string().describe("Total voting weight (wei)"),
594
- veABXTotalSupply: z.string().describe("Total veABX supply (wei)"),
595
- veABXLockedSupply: z.string().describe("Total ABX locked in VotingEscrow (wei)")
2616
+ output: z5.object({
2617
+ v2PoolCount: z5.number().describe("Number of V2 AMM pools"),
2618
+ clPoolCount: z5.number().describe("Number of Slipstream (CL) pools"),
2619
+ gaugeCount: z5.number().describe("Number of pools with gauges"),
2620
+ totalVotingWeight: z5.string().describe("Total voting weight (wei)"),
2621
+ veABXTotalSupply: z5.string().describe("Total veABX supply (wei)"),
2622
+ veABXLockedSupply: z5.string().describe("Total ABX locked in VotingEscrow (wei)")
596
2623
  }),
597
2624
  examples: [{ description: "Fetch the current Aborean protocol status" }],
598
2625
  async run(c) {