@sherwoodagent/cli 0.88.2 → 0.89.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 (87) hide show
  1. package/dist/{abis-WJQ6IVYV.js → abis-2VBXBA7Y.js} +16 -2
  2. package/dist/{agent-FCGZL4GF.js → agent-KMLNSKBS.js} +11 -11
  3. package/dist/{chat-AKLYUJZV.js → chat-JW5Z3JRE.js} +13 -13
  4. package/dist/{chunk-6SAE2VDK.js → chunk-6IC2NRED.js} +2 -2
  5. package/dist/{chunk-HMFPP2PE.js → chunk-77MBGRE5.js} +52 -24
  6. package/dist/chunk-77MBGRE5.js.map +1 -0
  7. package/dist/{chunk-G5MXVAFC.js → chunk-D3GTHAJS.js} +5 -5
  8. package/dist/chunk-G5FOHSQW.js +338 -0
  9. package/dist/chunk-G5FOHSQW.js.map +1 -0
  10. package/dist/chunk-GAQMHH44.js +18 -0
  11. package/dist/chunk-GAQMHH44.js.map +1 -0
  12. package/dist/{chunk-FWQESFFM.js → chunk-GYGSKMZE.js} +91 -8
  13. package/dist/chunk-GYGSKMZE.js.map +1 -0
  14. package/dist/{chunk-J2IZWAEW.js → chunk-JCL2DEH3.js} +2048 -2
  15. package/dist/chunk-JCL2DEH3.js.map +1 -0
  16. package/dist/{chunk-BH3VTJ4F.js → chunk-JKSDCCVL.js} +6 -6
  17. package/dist/{chunk-EEI6FRTE.js → chunk-JLOROS5V.js} +3 -3
  18. package/dist/{chunk-6D3FNU75.js → chunk-JRGYI34A.js} +5 -5
  19. package/dist/chunk-KZGY7NT7.js +209 -0
  20. package/dist/chunk-KZGY7NT7.js.map +1 -0
  21. package/dist/{chunk-G3FUEM5N.js → chunk-LIW6K4OJ.js} +2 -2
  22. package/dist/{chunk-4ITTHKRX.js → chunk-P4LFNKSX.js} +5 -5
  23. package/dist/{chunk-3TZIOAPH.js → chunk-QUAVAJWE.js} +13 -2
  24. package/dist/chunk-QUAVAJWE.js.map +1 -0
  25. package/dist/chunk-QVXKYT2N.js +489 -0
  26. package/dist/chunk-QVXKYT2N.js.map +1 -0
  27. package/dist/chunk-UPRFO4YU.js +458 -0
  28. package/dist/chunk-UPRFO4YU.js.map +1 -0
  29. package/dist/{chunk-QFGZQYZA.js → chunk-WDPA2BYK.js} +1024 -87
  30. package/dist/chunk-WDPA2BYK.js.map +1 -0
  31. package/dist/{chunk-CWGP4VXZ.js → chunk-YIN6R66K.js} +7 -7
  32. package/dist/{chunk-D4BSBW3Q.js → chunk-Z53JZORT.js} +3 -3
  33. package/dist/{chunk-SCQAKMMI.js → chunk-ZPOPWFSP.js} +5 -5
  34. package/dist/{client-PYFE6YQR.js → client-DA434B67.js} +4 -4
  35. package/dist/{config-ZGFS4I7K.js → config-UZ2GIXAO.js} +6 -2
  36. package/dist/{eas-B4HR2HXX.js → eas-ZH7BDEOK.js} +7 -7
  37. package/dist/{governor-QFBN6RYS.js → governor-WHT2V2EU.js} +7 -7
  38. package/dist/identity-TRPUQEQK.js +19 -0
  39. package/dist/index.js +7758 -5862
  40. package/dist/index.js.map +1 -1
  41. package/dist/launchpad-3N4ZFL6J.js +26 -0
  42. package/dist/lighter-perp-template-VC4TB7AM.js +92 -0
  43. package/dist/lighter-preflight-GH3JKLR6.js +149 -0
  44. package/dist/lighter-preflight-GH3JKLR6.js.map +1 -0
  45. package/dist/{network-7445KSCF.js → network-EZ5X2BF7.js} +3 -3
  46. package/dist/network-EZ5X2BF7.js.map +1 -0
  47. package/dist/{price-EXZDYVDD.js → price-RX5J7GTO.js} +9 -7
  48. package/dist/{price-EXZDYVDD.js.map → price-RX5J7GTO.js.map} +1 -1
  49. package/dist/{providers-6UZKDFQD.js → providers-XEEFKITN.js} +5 -5
  50. package/dist/{research-T7A27OMB.js → research-PYMQ5VKH.js} +9 -9
  51. package/dist/{session-45NQAHFI.js → session-DE47TUEW.js} +15 -15
  52. package/dist/{trade-ZOVM433K.js → trade-3VMAQ75D.js} +20 -18
  53. package/dist/{trade-ZOVM433K.js.map → trade-3VMAQ75D.js.map} +1 -1
  54. package/dist/{vault-E7XD6DLD.js → vault-PXGG2E3K.js} +9 -9
  55. package/dist/vault-PXGG2E3K.js.map +1 -0
  56. package/dist/{xmtp-72IRK7JL.js → xmtp-5PTIIVAI.js} +7 -7
  57. package/package.json +1 -1
  58. package/dist/chunk-3TZIOAPH.js.map +0 -1
  59. package/dist/chunk-FWQESFFM.js.map +0 -1
  60. package/dist/chunk-HMFPP2PE.js.map +0 -1
  61. package/dist/chunk-J2IZWAEW.js.map +0 -1
  62. package/dist/chunk-QFGZQYZA.js.map +0 -1
  63. package/dist/identity-I2BG4IGT.js +0 -18
  64. /package/dist/{abis-WJQ6IVYV.js.map → abis-2VBXBA7Y.js.map} +0 -0
  65. /package/dist/{agent-FCGZL4GF.js.map → agent-KMLNSKBS.js.map} +0 -0
  66. /package/dist/{chat-AKLYUJZV.js.map → chat-JW5Z3JRE.js.map} +0 -0
  67. /package/dist/{chunk-6SAE2VDK.js.map → chunk-6IC2NRED.js.map} +0 -0
  68. /package/dist/{chunk-G5MXVAFC.js.map → chunk-D3GTHAJS.js.map} +0 -0
  69. /package/dist/{chunk-BH3VTJ4F.js.map → chunk-JKSDCCVL.js.map} +0 -0
  70. /package/dist/{chunk-EEI6FRTE.js.map → chunk-JLOROS5V.js.map} +0 -0
  71. /package/dist/{chunk-6D3FNU75.js.map → chunk-JRGYI34A.js.map} +0 -0
  72. /package/dist/{chunk-G3FUEM5N.js.map → chunk-LIW6K4OJ.js.map} +0 -0
  73. /package/dist/{chunk-4ITTHKRX.js.map → chunk-P4LFNKSX.js.map} +0 -0
  74. /package/dist/{chunk-CWGP4VXZ.js.map → chunk-YIN6R66K.js.map} +0 -0
  75. /package/dist/{chunk-D4BSBW3Q.js.map → chunk-Z53JZORT.js.map} +0 -0
  76. /package/dist/{chunk-SCQAKMMI.js.map → chunk-ZPOPWFSP.js.map} +0 -0
  77. /package/dist/{client-PYFE6YQR.js.map → client-DA434B67.js.map} +0 -0
  78. /package/dist/{config-ZGFS4I7K.js.map → config-UZ2GIXAO.js.map} +0 -0
  79. /package/dist/{eas-B4HR2HXX.js.map → eas-ZH7BDEOK.js.map} +0 -0
  80. /package/dist/{governor-QFBN6RYS.js.map → governor-WHT2V2EU.js.map} +0 -0
  81. /package/dist/{identity-I2BG4IGT.js.map → identity-TRPUQEQK.js.map} +0 -0
  82. /package/dist/{network-7445KSCF.js.map → launchpad-3N4ZFL6J.js.map} +0 -0
  83. /package/dist/{vault-E7XD6DLD.js.map → lighter-perp-template-VC4TB7AM.js.map} +0 -0
  84. /package/dist/{providers-6UZKDFQD.js.map → providers-XEEFKITN.js.map} +0 -0
  85. /package/dist/{research-T7A27OMB.js.map → research-PYMQ5VKH.js.map} +0 -0
  86. /package/dist/{session-45NQAHFI.js.map → session-DE47TUEW.js.map} +0 -0
  87. /package/dist/{xmtp-72IRK7JL.js.map → xmtp-5PTIIVAI.js.map} +0 -0
@@ -1,20 +1,20 @@
1
1
  import {
2
2
  SHERWOOD
3
- } from "./chunk-FWQESFFM.js";
3
+ } from "./chunk-GYGSKMZE.js";
4
4
  import {
5
5
  getAccount,
6
6
  getPublicClient,
7
7
  waitForReceipt,
8
8
  writeContractWithRetry
9
- } from "./chunk-D4BSBW3Q.js";
9
+ } from "./chunk-Z53JZORT.js";
10
10
  import {
11
11
  getChain
12
- } from "./chunk-G3FUEM5N.js";
12
+ } from "./chunk-LIW6K4OJ.js";
13
13
  import {
14
14
  PROTOCOL_CONFIG_ABI,
15
15
  SYNDICATE_FACTORY_ABI,
16
16
  SYNDICATE_GOVERNOR_ABI
17
- } from "./chunk-J2IZWAEW.js";
17
+ } from "./chunk-JCL2DEH3.js";
18
18
 
19
19
  // src/lib/governor.ts
20
20
  import { parseEventLogs } from "viem";
@@ -507,4 +507,4 @@ export {
507
507
  setMgmtSplit,
508
508
  setPerfSplit
509
509
  };
510
- //# sourceMappingURL=chunk-G5MXVAFC.js.map
510
+ //# sourceMappingURL=chunk-D3GTHAJS.js.map
@@ -0,0 +1,338 @@
1
+ import {
2
+ BASE_STRATEGY_ABI,
3
+ ERC20_ABI,
4
+ LIGHTER_PERP_STRATEGY_ABI
5
+ } from "./chunk-JCL2DEH3.js";
6
+
7
+ // src/strategies/lighter-perp-template.ts
8
+ import {
9
+ encodeAbiParameters,
10
+ encodeFunctionData,
11
+ encodePacked,
12
+ hexToBytes,
13
+ bytesToHex,
14
+ keccak256,
15
+ isHex
16
+ } from "viem";
17
+ var LIGHTER_ZK_LIGHTER = "0x94bAB9693Ba2f6358507eFfcbd372b0660AFfF9d";
18
+ var LIGHTER_USDG = "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168";
19
+ var LIGHTER_USDG_DECIMALS = 6;
20
+ var LIGHTER_TICKS_PER_USDG = 1000000n;
21
+ var LIGHTER_PUBKEY_LEN = 40;
22
+ var LIGHTER_MIN_API_KEY_INDEX = 2;
23
+ var LIGHTER_MAX_API_KEY_INDEX = 254;
24
+ var LIGHTER_DEFAULT_API_KEY_INDEX = 2;
25
+ var LIGHTER_MAX_MARKET_INDEX = 254;
26
+ var LIGHTER_MAX_MARKETS = 16;
27
+ var LIGHTER_MIN_DEPOSIT = 1000000n;
28
+ var LIGHTER_MAX_DEPOSIT = (1n << 64n) - 1n;
29
+ var GOLDILOCKS_P = 0xffffffff00000001n;
30
+ var LIGHTER_ACTION = {
31
+ CANCEL_ALL: 1,
32
+ CLOSE_MARKET: 2,
33
+ ROTATE_KEY: 3,
34
+ REGISTER_KEY: 5
35
+ };
36
+ var LIGHTER_MARKET_SELL_PRICE = 1;
37
+ var LIGHTER_MARKET_BUY_PRICE = 4294967295;
38
+ var LIGHTER_SIDE_BID = 0;
39
+ var LIGHTER_SIDE_ASK = 1;
40
+ function validateLighterPubKey(raw) {
41
+ const s = raw.trim();
42
+ const hex = (s.startsWith("0x") || s.startsWith("0X") ? `0x${s.slice(2)}` : `0x${s}`).toLowerCase();
43
+ if (!isHex(hex) || hex.length !== 2 + LIGHTER_PUBKEY_LEN * 2) {
44
+ throw new Error(`Lighter pubkey must be exactly ${LIGHTER_PUBKEY_LEN} bytes (0x + 80 hex chars)`);
45
+ }
46
+ const bytes = hexToBytes(hex);
47
+ for (let i = 0; i < 5; i++) {
48
+ let limb = 0n;
49
+ for (let j = 7; j >= 0; j--) limb = limb << 8n | BigInt(bytes[i * 8 + j]);
50
+ if (limb === 0n || limb >= GOLDILOCKS_P) {
51
+ throw new Error(`Lighter pubkey limb ${i} (0x${limb.toString(16)}) is not Goldilocks-canonical (must be in (0, p))`);
52
+ }
53
+ }
54
+ return hex;
55
+ }
56
+ function validateLighterKeyIndex(raw) {
57
+ const n = typeof raw === "number" ? raw : Number(String(raw).trim());
58
+ if (!Number.isInteger(n) || n < LIGHTER_MIN_API_KEY_INDEX || n > LIGHTER_MAX_API_KEY_INDEX) {
59
+ throw new Error(
60
+ `Lighter api key index must be an integer ${LIGHTER_MIN_API_KEY_INDEX}..${LIGHTER_MAX_API_KEY_INDEX} (0/1 are reserved by the web app)`
61
+ );
62
+ }
63
+ return n;
64
+ }
65
+ function validateLighterMarket(raw) {
66
+ const s = String(raw).trim();
67
+ if (!/^\d+$/.test(s)) throw new Error(`Lighter market id must be a non-negative integer (got "${raw}")`);
68
+ const n = Number(s);
69
+ if (n > LIGHTER_MAX_MARKET_INDEX) {
70
+ throw new Error(`Lighter market id ${n} exceeds ${LIGHTER_MAX_MARKET_INDEX} (perp markets only)`);
71
+ }
72
+ return n;
73
+ }
74
+ function parseLighterMarkets(raw) {
75
+ const parts = raw.split(",").map((p) => p.trim()).filter((p) => p !== "");
76
+ if (parts.length === 0) throw new Error("--markets needs at least one market id");
77
+ if (parts.length > LIGHTER_MAX_MARKETS) {
78
+ throw new Error(`--markets allows at most ${LIGHTER_MAX_MARKETS} ids (got ${parts.length}); initiateReturn closes each in one tx`);
79
+ }
80
+ const out = [];
81
+ for (const p of parts) {
82
+ const m = validateLighterMarket(p);
83
+ if (out.includes(m)) throw new Error(`--markets lists market ${m} twice (the template reverts DuplicateMarket)`);
84
+ out.push(m);
85
+ }
86
+ return out;
87
+ }
88
+ function validateLighterDeposit(amount) {
89
+ if (amount < LIGHTER_MIN_DEPOSIT) throw new Error("Lighter deposit must be at least 1 USDG (the template reverts DepositTooSmall)");
90
+ if (amount > LIGHTER_MAX_DEPOSIT) throw new Error("Lighter deposit exceeds type(uint64).max ticks (DepositTooLarge)");
91
+ return amount;
92
+ }
93
+ function buildInitData(p) {
94
+ const pubKey = validateLighterPubKey(p.pubKey);
95
+ const keyIndex = validateLighterKeyIndex(p.keyIndex);
96
+ if (p.markets.length === 0) throw new Error("at least one market is required");
97
+ const markets = parseLighterMarkets(p.markets.join(","));
98
+ const depositAmount = validateLighterDeposit(p.depositAmount);
99
+ return encodeAbiParameters(
100
+ [{ type: "bytes" }, { type: "uint8" }, { type: "uint16[]" }, { type: "uint256" }],
101
+ [pubKey, keyIndex, markets, depositAmount]
102
+ );
103
+ }
104
+ function buildExecuteCalls(clone, usdg, depositAmount) {
105
+ return [
106
+ {
107
+ target: usdg,
108
+ data: encodeFunctionData({ abi: ERC20_ABI, functionName: "approve", args: [clone, depositAmount] }),
109
+ value: 0n
110
+ },
111
+ {
112
+ target: clone,
113
+ data: encodeFunctionData({ abi: BASE_STRATEGY_ABI, functionName: "execute" }),
114
+ value: 0n
115
+ }
116
+ ];
117
+ }
118
+ function buildSettleCalls(clone) {
119
+ return [
120
+ {
121
+ target: clone,
122
+ data: encodeFunctionData({ abi: BASE_STRATEGY_ABI, functionName: "settle" }),
123
+ value: 0n
124
+ }
125
+ ];
126
+ }
127
+ function buildPostSettleRecoveryCalls(clone, usdg) {
128
+ return [
129
+ {
130
+ target: clone,
131
+ data: encodeFunctionData({ abi: LIGHTER_PERP_STRATEGY_ABI, functionName: "recoverResiduals" }),
132
+ value: 0n
133
+ },
134
+ {
135
+ target: clone,
136
+ data: encodeFunctionData({ abi: LIGHTER_PERP_STRATEGY_ABI, functionName: "rescueTo", args: [usdg] }),
137
+ value: 0n
138
+ }
139
+ ];
140
+ }
141
+ function guardrailPayload(action, args) {
142
+ return encodeAbiParameters([{ type: "uint8" }, { type: "bytes" }], [action, args]);
143
+ }
144
+ function encodeCancelAll() {
145
+ return guardrailPayload(LIGHTER_ACTION.CANCEL_ALL, "0x");
146
+ }
147
+ function encodeCloseMarket(market, price, isAsk) {
148
+ const m = validateLighterMarket(market);
149
+ if (!Number.isInteger(price) || price < 1 || price > LIGHTER_MARKET_BUY_PRICE) {
150
+ throw new Error(`close price bound must be an integer in [1, 2^32-1] (got ${price})`);
151
+ }
152
+ return guardrailPayload(
153
+ LIGHTER_ACTION.CLOSE_MARKET,
154
+ encodeAbiParameters([{ type: "uint16" }, { type: "uint32" }, { type: "uint8" }], [m, price, isAsk])
155
+ );
156
+ }
157
+ function encodeClosePosition(market, position, price) {
158
+ if (position === "long") {
159
+ return encodeCloseMarket(market, price ?? LIGHTER_MARKET_SELL_PRICE, LIGHTER_SIDE_ASK);
160
+ }
161
+ return encodeCloseMarket(market, price ?? LIGHTER_MARKET_BUY_PRICE, LIGHTER_SIDE_BID);
162
+ }
163
+ function encodeRotateKey(newPubKey) {
164
+ const pk = validateLighterPubKey(newPubKey);
165
+ return guardrailPayload(LIGHTER_ACTION.ROTATE_KEY, encodeAbiParameters([{ type: "bytes" }], [pk]));
166
+ }
167
+ function encodeRegisterKey() {
168
+ return guardrailPayload(LIGHTER_ACTION.REGISTER_KEY, "0x");
169
+ }
170
+ function guardrailActionCalldata(payload) {
171
+ return encodeFunctionData({ abi: LIGHTER_PERP_STRATEGY_ABI, functionName: "guardrailAction", args: [payload] });
172
+ }
173
+ function registerAgentKeyCalldata() {
174
+ return encodeFunctionData({ abi: LIGHTER_PERP_STRATEGY_ABI, functionName: "registerAgentKey" });
175
+ }
176
+ function initiateReturnCalldata() {
177
+ return encodeFunctionData({ abi: LIGHTER_PERP_STRATEGY_ABI, functionName: "initiateReturn" });
178
+ }
179
+ function queueWithdrawCalldata(ticks) {
180
+ if (ticks <= 0n) throw new Error("queueWithdraw ticks must be > 0 (the template reverts ZeroTicks)");
181
+ if (ticks > LIGHTER_MAX_DEPOSIT) throw new Error("queueWithdraw ticks overflow uint64");
182
+ return encodeFunctionData({ abi: LIGHTER_PERP_STRATEGY_ABI, functionName: "queueWithdraw", args: [ticks] });
183
+ }
184
+ function acknowledgeShortfallCalldata() {
185
+ return encodeFunctionData({ abi: LIGHTER_PERP_STRATEGY_ABI, functionName: "acknowledgeShortfall" });
186
+ }
187
+ function recoverResidualsCalldata() {
188
+ return encodeFunctionData({ abi: LIGHTER_PERP_STRATEGY_ABI, functionName: "recoverResiduals" });
189
+ }
190
+ function usdgToTicks(decimal) {
191
+ const s = decimal.trim();
192
+ if (!/^\d+(\.\d+)?$/.test(s)) throw new Error(`not a non-negative decimal USDG amount: "${decimal}"`);
193
+ const frac = s.split(".")[1] ?? "";
194
+ if (frac.length > 6) {
195
+ throw new Error(`USDG has 6 decimals (1 tick = 0.000001); "${decimal}" has ${frac.length} \u2014 refusing to truncate it`);
196
+ }
197
+ return usdgToTicksFloor(s);
198
+ }
199
+ function usdgToTicksFloor(decimal) {
200
+ const s = decimal.trim();
201
+ if (!/^\d+(\.\d+)?$/.test(s)) throw new Error(`not a non-negative decimal USDG amount: "${decimal}"`);
202
+ const [whole, frac = ""] = s.split(".");
203
+ return BigInt(whole) * LIGHTER_TICKS_PER_USDG + BigInt((frac + "000000").slice(0, 6));
204
+ }
205
+ var fp = (x) => (x % GOLDILOCKS_P + GOLDILOCKS_P) % GOLDILOCKS_P;
206
+ function fp5Mul(a, b) {
207
+ const c = [0n, 0n, 0n, 0n, 0n];
208
+ for (let i = 0; i < 5; i++) {
209
+ for (let j = 0; j < 5; j++) {
210
+ const k = i + j;
211
+ if (k < 5) c[k] += a[i] * b[j];
212
+ else c[k - 5] += 3n * a[i] * b[j];
213
+ }
214
+ }
215
+ return c.map(fp);
216
+ }
217
+ function fp5Sub(a, b) {
218
+ return a.map((x, i) => fp(x - b[i]));
219
+ }
220
+ function fp5Pow(a, e) {
221
+ let r = [1n, 0n, 0n, 0n, 0n];
222
+ let base = a;
223
+ while (e > 0n) {
224
+ if (e & 1n) r = fp5Mul(r, base);
225
+ base = fp5Mul(base, base);
226
+ e >>= 1n;
227
+ }
228
+ return r;
229
+ }
230
+ var FP5_LEGENDRE_EXP = (GOLDILOCKS_P ** 5n - 1n) / 2n;
231
+ var ECGFP5_A = [2n, 0n, 0n, 0n, 0n];
232
+ var ECGFP5_4B = [0n, 4n * 263n, 0n, 0n, 0n];
233
+ function isLighterPubKeyOnCurve(key) {
234
+ const bytes = hexToBytes(key);
235
+ if (bytes.length !== LIGHTER_PUBKEY_LEN) return false;
236
+ const w = [];
237
+ for (let i = 0; i < 5; i++) {
238
+ let limb = 0n;
239
+ for (let j = 7; j >= 0; j--) limb = limb << 8n | BigInt(bytes[i * 8 + j]);
240
+ if (limb >= GOLDILOCKS_P) return false;
241
+ w.push(limb);
242
+ }
243
+ const wf = w;
244
+ if (w.every((x) => x === 0n)) return true;
245
+ const e = fp5Sub(fp5Mul(wf, wf), ECGFP5_A);
246
+ const delta = fp5Sub(fp5Mul(e, e), ECGFP5_4B);
247
+ if (delta.every((x) => x === 0n)) return true;
248
+ const l = fp5Pow(delta, FP5_LEGENDRE_EXP);
249
+ return l[0] === 1n && l[1] === 0n && l[2] === 0n && l[3] === 0n && l[4] === 0n;
250
+ }
251
+ var BURN_TAG = "sherwood.lighter.burn-key.v1";
252
+ var BURN_MAX_ATTEMPTS = 256;
253
+ function burnCandidate(clone, attempt) {
254
+ const out = new Uint8Array(LIGHTER_PUBKEY_LEN);
255
+ for (let i = 0; i < 5; i++) {
256
+ const preimage = attempt === 0 ? encodePacked(["string", "address", "uint8"], [BURN_TAG, clone, i]) : encodePacked(["string", "address", "uint8", "uint16"], [BURN_TAG, clone, i, attempt]);
257
+ const h = hexToBytes(keccak256(preimage));
258
+ let limb = 0n;
259
+ for (let j = 0; j < 8; j++) limb = limb << 8n | BigInt(h[j]);
260
+ limb %= GOLDILOCKS_P;
261
+ if (limb === 0n) limb = 1n;
262
+ for (let j = 0; j < 8; j++) out[i * 8 + j] = Number(limb >> BigInt(8 * j) & 0xffn);
263
+ }
264
+ return bytesToHex(out);
265
+ }
266
+ function deriveBurnPubKey(clone) {
267
+ for (let attempt = 0; attempt < BURN_MAX_ATTEMPTS; attempt++) {
268
+ const key = burnCandidate(clone, attempt);
269
+ if (isLighterPubKeyOnCurve(key)) return key;
270
+ }
271
+ throw new Error(`no valid ECgFp5 burn key for ${clone} in ${BURN_MAX_ATTEMPTS} attempts`);
272
+ }
273
+ function parseLighterTemplateFlags(flags, saved) {
274
+ const rawPub = flags.pubkey ?? saved?.pubKey;
275
+ if (!rawPub) {
276
+ throw new Error("lighter-perp: --pubkey <hex> is required (or run `sherwood lighter keygen` to create and save one)");
277
+ }
278
+ const pubKey = validateLighterPubKey(rawPub);
279
+ const keyIndex = validateLighterKeyIndex(
280
+ flags.keyIndex ?? (flags.pubkey === void 0 && saved ? saved.apiKeyIndex : LIGHTER_DEFAULT_API_KEY_INDEX)
281
+ );
282
+ if (!flags.markets) throw new Error("lighter-perp: --markets <ids> is required (comma-separated perp market ids, \u2264 16)");
283
+ const markets = parseLighterMarkets(flags.markets);
284
+ if (flags.deposit !== void 0 && flags.amount !== void 0 && flags.deposit !== flags.amount) {
285
+ throw new Error("lighter-perp: --deposit and --amount disagree \u2014 pass one");
286
+ }
287
+ const human = flags.deposit ?? flags.amount;
288
+ if (!human) throw new Error("lighter-perp: --deposit <usdg> is required (human units, e.g. 1000 = 1,000 USDG)");
289
+ const depositAmount = validateLighterDeposit(usdgToTicks(human));
290
+ return { pubKey, keyIndex, markets, depositAmount };
291
+ }
292
+
293
+ export {
294
+ LIGHTER_ZK_LIGHTER,
295
+ LIGHTER_USDG,
296
+ LIGHTER_USDG_DECIMALS,
297
+ LIGHTER_TICKS_PER_USDG,
298
+ LIGHTER_PUBKEY_LEN,
299
+ LIGHTER_MIN_API_KEY_INDEX,
300
+ LIGHTER_MAX_API_KEY_INDEX,
301
+ LIGHTER_DEFAULT_API_KEY_INDEX,
302
+ LIGHTER_MAX_MARKET_INDEX,
303
+ LIGHTER_MAX_MARKETS,
304
+ LIGHTER_MIN_DEPOSIT,
305
+ LIGHTER_MAX_DEPOSIT,
306
+ GOLDILOCKS_P,
307
+ LIGHTER_ACTION,
308
+ LIGHTER_MARKET_SELL_PRICE,
309
+ LIGHTER_MARKET_BUY_PRICE,
310
+ LIGHTER_SIDE_BID,
311
+ LIGHTER_SIDE_ASK,
312
+ validateLighterPubKey,
313
+ validateLighterKeyIndex,
314
+ validateLighterMarket,
315
+ parseLighterMarkets,
316
+ validateLighterDeposit,
317
+ buildInitData,
318
+ buildExecuteCalls,
319
+ buildSettleCalls,
320
+ buildPostSettleRecoveryCalls,
321
+ encodeCancelAll,
322
+ encodeCloseMarket,
323
+ encodeClosePosition,
324
+ encodeRotateKey,
325
+ encodeRegisterKey,
326
+ guardrailActionCalldata,
327
+ registerAgentKeyCalldata,
328
+ initiateReturnCalldata,
329
+ queueWithdrawCalldata,
330
+ acknowledgeShortfallCalldata,
331
+ recoverResidualsCalldata,
332
+ usdgToTicks,
333
+ usdgToTicksFloor,
334
+ isLighterPubKeyOnCurve,
335
+ deriveBurnPubKey,
336
+ parseLighterTemplateFlags
337
+ };
338
+ //# sourceMappingURL=chunk-G5FOHSQW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/strategies/lighter-perp-template.ts"],"sourcesContent":["/**\n * LighterPerpStrategy call builder (sherwood-strategies\n * `src/lighter/LighterPerpStrategy.sol`, the v1 port).\n *\n * Init (Solidity), a FLAT tuple — not a struct:\n * abi.encode(bytes apiKeyPubKey, uint8 apiKeyIndex, uint16[] markets, uint256 depositAmount)\n *\n * Everything here is pure params → bytes. The chain-dependent checks (vault\n * asset is USDG, ZK_LIGHTER counterparty standing, Lighter API market list)\n * live in the command layer; see lib/lighter-preflight.ts.\n *\n * Settlement is THREE-STEP on this template and the proposal's own batches\n * cover only the outer two legs:\n * execute batch = [USDG.approve(clone, depositAmount), clone.execute()]\n * (off-batch) initiateReturn() → queueWithdraw(ticks) → wait for maturity\n * settle batch = [clone.settle()]\n * The middle leg is the proposer / vault owner driving the clone DIRECTLY\n * (`sherwood lighter …`), because the drain amount is only knowable after the\n * closes fill.\n *\n * NEVER put `rescueTo(USDG)` ahead of `settle()` in one batch: inside that batch\n * the settle guard reads the rescued USDG as missing (`WithdrawalInFlight`),\n * outside it nothing is missing (`acknowledgeShortfall` reverts `NoShortfall`),\n * and `unstick` replays the same calls — only the owner's emergency settle gets\n * out. `[recoverResiduals(), rescueTo(USDG)]` belongs AFTER settle only.\n */\n\nimport type { Address, Hex } from \"viem\";\nimport {\n encodeAbiParameters,\n encodeFunctionData,\n encodePacked,\n hexToBytes,\n bytesToHex,\n keccak256,\n isHex,\n} from \"viem\";\nimport { ERC20_ABI, BASE_STRATEGY_ABI, LIGHTER_PERP_STRATEGY_ABI } from \"../lib/abis.js\";\nimport type { BatchCall } from \"../lib/batch.js\";\n\n// ── Constants mirrored from LighterPerpStrategy.sol ──\n\n/** zkLighter proxy — a `constant` in the template (4663 + the 9994663 fork). */\nexport const LIGHTER_ZK_LIGHTER: Address = \"0x94bAB9693Ba2f6358507eFfcbd372b0660AFfF9d\";\n/** USDG — the template's pinned vault asset (6 dp). */\nexport const LIGHTER_USDG: Address = \"0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168\";\nexport const LIGHTER_USDG_DECIMALS = 6;\n/** 1 USDG = 1e6 ticks: one tick is one USDG base unit, so ticks and assets compare directly. */\nexport const LIGHTER_TICKS_PER_USDG = 1_000_000n;\n\nexport const LIGHTER_PUBKEY_LEN = 40;\nexport const LIGHTER_MIN_API_KEY_INDEX = 2;\nexport const LIGHTER_MAX_API_KEY_INDEX = 254;\nexport const LIGHTER_DEFAULT_API_KEY_INDEX = 2;\nexport const LIGHTER_MAX_MARKET_INDEX = 254;\n/** `initiateReturn` makes 2 venue calls per market in ONE tx — bounded for gas. */\nexport const LIGHTER_MAX_MARKETS = 16;\nexport const LIGHTER_MIN_DEPOSIT = 1_000_000n; // 1 USDG\n/** `IZkLighter.withdraw` takes uint64 ticks. */\nexport const LIGHTER_MAX_DEPOSIT = (1n << 64n) - 1n;\n/** Goldilocks prime — every 8-byte LE limb of an L2 pubkey must be in (0, p). */\nexport const GOLDILOCKS_P = 0xffffffff00000001n;\n\n/** Guardrail action ids (`_updateParams`). 4 (WITHDRAW) is RETIRED and reverts. */\nexport const LIGHTER_ACTION = {\n CANCEL_ALL: 1,\n CLOSE_MARKET: 2,\n ROTATE_KEY: 3,\n REGISTER_KEY: 5,\n} as const;\n\n/** Widest legal close bounds — the ones `initiateReturn` itself uses. */\nexport const LIGHTER_MARKET_SELL_PRICE = 1;\nexport const LIGHTER_MARKET_BUY_PRICE = 0xffffffff;\nexport const LIGHTER_SIDE_BID = 0; // buy — closes a SHORT\nexport const LIGHTER_SIDE_ASK = 1; // sell — closes a LONG\n\n// ── Validation (mirrors `_initialize`; fail here, not in a reverted clone tx) ──\n\n/**\n * Validate a 40-byte Goldilocks-canonical L2 pubkey: 5 little-endian uint64\n * limbs, each nonzero and below the Goldilocks prime. The template itself only\n * checks the length; the venue's `changePubKey` checks canonicality, so a key\n * that passes init but fails here would be a clone whose agent can never be\n * registered. Returns the lowercase hex.\n */\nexport function validateLighterPubKey(raw: string): Hex {\n const s = raw.trim();\n const hex = (s.startsWith(\"0x\") || s.startsWith(\"0X\") ? `0x${s.slice(2)}` : `0x${s}`).toLowerCase();\n if (!isHex(hex) || hex.length !== 2 + LIGHTER_PUBKEY_LEN * 2) {\n throw new Error(`Lighter pubkey must be exactly ${LIGHTER_PUBKEY_LEN} bytes (0x + 80 hex chars)`);\n }\n const bytes = hexToBytes(hex as Hex);\n for (let i = 0; i < 5; i++) {\n let limb = 0n;\n for (let j = 7; j >= 0; j--) limb = (limb << 8n) | BigInt(bytes[i * 8 + j]);\n if (limb === 0n || limb >= GOLDILOCKS_P) {\n throw new Error(`Lighter pubkey limb ${i} (0x${limb.toString(16)}) is not Goldilocks-canonical (must be in (0, p))`);\n }\n }\n return hex as Hex;\n}\n\nexport function validateLighterKeyIndex(raw: string | number): number {\n const n = typeof raw === \"number\" ? raw : Number(String(raw).trim());\n if (!Number.isInteger(n) || n < LIGHTER_MIN_API_KEY_INDEX || n > LIGHTER_MAX_API_KEY_INDEX) {\n throw new Error(\n `Lighter api key index must be an integer ${LIGHTER_MIN_API_KEY_INDEX}..${LIGHTER_MAX_API_KEY_INDEX} (0/1 are reserved by the web app)`,\n );\n }\n return n;\n}\n\nexport function validateLighterMarket(raw: string | number): number {\n const s = String(raw).trim();\n if (!/^\\d+$/.test(s)) throw new Error(`Lighter market id must be a non-negative integer (got \"${raw}\")`);\n const n = Number(s);\n if (n > LIGHTER_MAX_MARKET_INDEX) {\n throw new Error(`Lighter market id ${n} exceeds ${LIGHTER_MAX_MARKET_INDEX} (perp markets only)`);\n }\n return n;\n}\n\n/** Parse `--markets 0,1,24` → a nonempty, duplicate-free list of ≤ 16 perp market ids. */\nexport function parseLighterMarkets(raw: string): number[] {\n const parts = raw.split(\",\").map((p) => p.trim()).filter((p) => p !== \"\");\n if (parts.length === 0) throw new Error(\"--markets needs at least one market id\");\n if (parts.length > LIGHTER_MAX_MARKETS) {\n throw new Error(`--markets allows at most ${LIGHTER_MAX_MARKETS} ids (got ${parts.length}); initiateReturn closes each in one tx`);\n }\n const out: number[] = [];\n for (const p of parts) {\n const m = validateLighterMarket(p);\n if (out.includes(m)) throw new Error(`--markets lists market ${m} twice (the template reverts DuplicateMarket)`);\n out.push(m);\n }\n return out;\n}\n\nexport function validateLighterDeposit(amount: bigint): bigint {\n if (amount < LIGHTER_MIN_DEPOSIT) throw new Error(\"Lighter deposit must be at least 1 USDG (the template reverts DepositTooSmall)\");\n if (amount > LIGHTER_MAX_DEPOSIT) throw new Error(\"Lighter deposit exceeds type(uint64).max ticks (DepositTooLarge)\");\n return amount;\n}\n\n// ── Init + proposal batches ──\n\nexport interface LighterPerpInitParams {\n pubKey: Hex;\n keyIndex: number;\n markets: number[];\n /** USDG base units — the CEILING; execute() deploys it scaled by approve coverage. */\n depositAmount: bigint;\n}\n\nexport function buildInitData(p: LighterPerpInitParams): Hex {\n const pubKey = validateLighterPubKey(p.pubKey);\n const keyIndex = validateLighterKeyIndex(p.keyIndex);\n if (p.markets.length === 0) throw new Error(\"at least one market is required\");\n const markets = parseLighterMarkets(p.markets.join(\",\"));\n const depositAmount = validateLighterDeposit(p.depositAmount);\n return encodeAbiParameters(\n [{ type: \"bytes\" }, { type: \"uint8\" }, { type: \"uint16[]\" }, { type: \"uint256\" }],\n [pubKey, keyIndex, markets, depositAmount],\n );\n}\n\n/**\n * `[USDG.approve(clone, depositAmount), clone.execute()]`.\n *\n * `_execute` pulls `depositAmount × effectiveMaxCapital / maxCapital` (floored)\n * — the declaration is a ceiling. On an under-covered proposal the pull is\n * smaller than the approval; the leftover allowance is inert, because the only\n * `transferFrom(vault)` in the template is `_pullFromVault` inside the one-shot,\n * `onlyVault` `execute()`.\n */\nexport function buildExecuteCalls(clone: Address, usdg: Address, depositAmount: bigint): BatchCall[] {\n return [\n {\n target: usdg,\n data: encodeFunctionData({ abi: ERC20_ABI, functionName: \"approve\", args: [clone, depositAmount] }),\n value: 0n,\n },\n {\n target: clone,\n data: encodeFunctionData({ abi: BASE_STRATEGY_ABI, functionName: \"execute\" }),\n value: 0n,\n },\n ];\n}\n\n/** `[clone.settle()]` — and nothing ahead of it (see the module header on `rescueTo`). */\nexport function buildSettleCalls(clone: Address): BatchCall[] {\n return [\n {\n target: clone,\n data: encodeFunctionData({ abi: BASE_STRATEGY_ABI, functionName: \"settle\" }),\n value: 0n,\n },\n ];\n}\n\n/**\n * Post-settle recovery, for a LATER proposal's batch or an owner emergency\n * batch: claim matured pending USDG onto the clone, then push it home.\n * Only valid once the clone is `Settled` (or emergency-settled).\n */\nexport function buildPostSettleRecoveryCalls(clone: Address, usdg: Address): BatchCall[] {\n return [\n {\n target: clone,\n data: encodeFunctionData({ abi: LIGHTER_PERP_STRATEGY_ABI, functionName: \"recoverResiduals\" }),\n value: 0n,\n },\n {\n target: clone,\n data: encodeFunctionData({ abi: LIGHTER_PERP_STRATEGY_ABI, functionName: \"rescueTo\", args: [usdg] }),\n value: 0n,\n },\n ];\n}\n\n// ── Guardrail payloads: abi.encode(uint8 action, bytes args) ──\n\nfunction guardrailPayload(action: number, args: Hex): Hex {\n return encodeAbiParameters([{ type: \"uint8\" }, { type: \"bytes\" }], [action, args]);\n}\n\nexport function encodeCancelAll(): Hex {\n return guardrailPayload(LIGHTER_ACTION.CANCEL_ALL, \"0x\");\n}\n\n/**\n * CLOSE_MARKET(uint16 market, uint32 price, uint8 isAsk) — a `baseAmount = 0`\n * market order, which can only CLOSE. `market` is deliberately NOT checked\n * against the clone's list: this is the remedy for a position the agent opened\n * outside it.\n */\nexport function encodeCloseMarket(market: number, price: number, isAsk: 0 | 1): Hex {\n const m = validateLighterMarket(market);\n if (!Number.isInteger(price) || price < 1 || price > LIGHTER_MARKET_BUY_PRICE) {\n throw new Error(`close price bound must be an integer in [1, 2^32-1] (got ${price})`);\n }\n return guardrailPayload(\n LIGHTER_ACTION.CLOSE_MARKET,\n encodeAbiParameters([{ type: \"uint16\" }, { type: \"uint32\" }, { type: \"uint8\" }], [m, price, isAsk]),\n );\n}\n\n/**\n * Close a LONG: SELL bounded DOWN. Closing a SHORT: BUY bounded UP. Pairing the\n * side with its bound here is what stops an operator from sending a close that\n * can never fill. `price` defaults to the widest bound (no slippage\n * protection — the same trade-off `initiateReturn` makes).\n */\nexport function encodeClosePosition(market: number, position: \"long\" | \"short\", price?: number): Hex {\n if (position === \"long\") {\n return encodeCloseMarket(market, price ?? LIGHTER_MARKET_SELL_PRICE, LIGHTER_SIDE_ASK);\n }\n return encodeCloseMarket(market, price ?? LIGHTER_MARKET_BUY_PRICE, LIGHTER_SIDE_BID);\n}\n\nexport function encodeRotateKey(newPubKey: Hex): Hex {\n const pk = validateLighterPubKey(newPubKey);\n return guardrailPayload(LIGHTER_ACTION.ROTATE_KEY, encodeAbiParameters([{ type: \"bytes\" }], [pk]));\n}\n\nexport function encodeRegisterKey(): Hex {\n return guardrailPayload(LIGHTER_ACTION.REGISTER_KEY, \"0x\");\n}\n\n// ── Direct clone calldata (proposer / vault owner, NOT governor batches) ──\n\n/** `guardrailAction(payload)` — proposer OR vault owner, `Executed` only. */\nexport function guardrailActionCalldata(payload: Hex): Hex {\n return encodeFunctionData({ abi: LIGHTER_PERP_STRATEGY_ABI, functionName: \"guardrailAction\", args: [payload] });\n}\n\nexport function registerAgentKeyCalldata(): Hex {\n return encodeFunctionData({ abi: LIGHTER_PERP_STRATEGY_ABI, functionName: \"registerAgentKey\" });\n}\n\nexport function initiateReturnCalldata(): Hex {\n return encodeFunctionData({ abi: LIGHTER_PERP_STRATEGY_ABI, functionName: \"initiateReturn\" });\n}\n\nexport function queueWithdrawCalldata(ticks: bigint): Hex {\n if (ticks <= 0n) throw new Error(\"queueWithdraw ticks must be > 0 (the template reverts ZeroTicks)\");\n if (ticks > LIGHTER_MAX_DEPOSIT) throw new Error(\"queueWithdraw ticks overflow uint64\");\n return encodeFunctionData({ abi: LIGHTER_PERP_STRATEGY_ABI, functionName: \"queueWithdraw\", args: [ticks] });\n}\n\nexport function acknowledgeShortfallCalldata(): Hex {\n return encodeFunctionData({ abi: LIGHTER_PERP_STRATEGY_ABI, functionName: \"acknowledgeShortfall\" });\n}\n\nexport function recoverResidualsCalldata(): Hex {\n return encodeFunctionData({ abi: LIGHTER_PERP_STRATEGY_ABI, functionName: \"recoverResiduals\" });\n}\n\n// ── Units + keys ──\n\n/**\n * Exact USDG decimal string → venue ticks. For amounts a USER typed\n * (`--deposit`): more than 6 decimals is refused rather than silently\n * truncated — a tick is the smallest unit, so \"1.0000009\" is a typo, not an\n * amount. Never goes through a float.\n */\nexport function usdgToTicks(decimal: string): bigint {\n const s = decimal.trim();\n if (!/^\\d+(\\.\\d+)?$/.test(s)) throw new Error(`not a non-negative decimal USDG amount: \"${decimal}\"`);\n const frac = s.split(\".\")[1] ?? \"\";\n if (frac.length > 6) {\n throw new Error(`USDG has 6 decimals (1 tick = 0.000001); \"${decimal}\" has ${frac.length} — refusing to truncate it`);\n }\n return usdgToTicksFloor(s);\n}\n\n/**\n * A VENUE-reported balance → ticks, rounded DOWN. Only for balances read off\n * the Lighter API, which may carry more precision than a tick: rounding up by\n * one tick makes the venue reject the whole withdrawal, rounding down leaves\n * at most one tick behind.\n */\nexport function usdgToTicksFloor(decimal: string): bigint {\n const s = decimal.trim();\n if (!/^\\d+(\\.\\d+)?$/.test(s)) throw new Error(`not a non-negative decimal USDG amount: \"${decimal}\"`);\n const [whole, frac = \"\"] = s.split(\".\");\n return BigInt(whole) * LIGHTER_TICKS_PER_USDG + BigInt((frac + \"000000\").slice(0, 6));\n}\n\n// ── ECgFp5 point validity (for the burn key) ──\n//\n// Lighter's L2 pubkey is an encoded ECgFp5 point: one element w of\n// GF(p^5) = GF(p)[z]/(z^5 − 3), p = Goldilocks, written as 5 LE uint64 limbs.\n// The curve is y² = x(x² + a·x + b) with a = 2, b = 263·z (Pornin, \"EcGFp5\",\n// 2022). Decoding w succeeds iff w = 0 or Δ = (w² − a)² − 4b is a square in\n// GF(p^5), i.e. Δ^((p^5 − 1)/2) = 1. Only ~half of all field elements pass, so\n// a raw hash output is a valid pubkey about half the time — and the venue may\n// silently drop a `changePubKey` to a key that does not decode, leaving the\n// OLD agent key live. Verified against lighter-sdk's own `create_api_key()`\n// (40/40 generated pubkeys pass; ~50% of random elements do).\n\ntype Fp5 = readonly [bigint, bigint, bigint, bigint, bigint];\nconst fp = (x: bigint): bigint => ((x % GOLDILOCKS_P) + GOLDILOCKS_P) % GOLDILOCKS_P;\n\nfunction fp5Mul(a: Fp5, b: Fp5): Fp5 {\n const c = [0n, 0n, 0n, 0n, 0n];\n for (let i = 0; i < 5; i++) {\n for (let j = 0; j < 5; j++) {\n const k = i + j;\n if (k < 5) c[k] += a[i] * b[j];\n else c[k - 5] += 3n * a[i] * b[j]; // z^5 = 3\n }\n }\n return c.map(fp) as unknown as Fp5;\n}\n\nfunction fp5Sub(a: Fp5, b: Fp5): Fp5 {\n return a.map((x, i) => fp(x - b[i])) as unknown as Fp5;\n}\n\nfunction fp5Pow(a: Fp5, e: bigint): Fp5 {\n let r: Fp5 = [1n, 0n, 0n, 0n, 0n];\n let base = a;\n while (e > 0n) {\n if (e & 1n) r = fp5Mul(r, base);\n base = fp5Mul(base, base);\n e >>= 1n;\n }\n return r;\n}\n\nconst FP5_LEGENDRE_EXP = (GOLDILOCKS_P ** 5n - 1n) / 2n;\nconst ECGFP5_A: Fp5 = [2n, 0n, 0n, 0n, 0n];\nconst ECGFP5_4B: Fp5 = [0n, 4n * 263n, 0n, 0n, 0n];\n\n/** True when a 40-byte key decodes to an ECgFp5 point (see the block comment above). */\nexport function isLighterPubKeyOnCurve(key: Hex): boolean {\n const bytes = hexToBytes(key);\n if (bytes.length !== LIGHTER_PUBKEY_LEN) return false;\n const w: bigint[] = [];\n for (let i = 0; i < 5; i++) {\n let limb = 0n;\n for (let j = 7; j >= 0; j--) limb = (limb << 8n) | BigInt(bytes[i * 8 + j]);\n if (limb >= GOLDILOCKS_P) return false;\n w.push(limb);\n }\n const wf = w as unknown as Fp5;\n if (w.every((x) => x === 0n)) return true;\n const e = fp5Sub(fp5Mul(wf, wf), ECGFP5_A);\n const delta = fp5Sub(fp5Mul(e, e), ECGFP5_4B);\n if (delta.every((x) => x === 0n)) return true;\n const l = fp5Pow(delta, FP5_LEGENDRE_EXP);\n return l[0] === 1n && l[1] === 0n && l[2] === 0n && l[3] === 0n && l[4] === 0n;\n}\n\nconst BURN_TAG = \"sherwood.lighter.burn-key.v1\";\nconst BURN_MAX_ATTEMPTS = 256;\n\nfunction burnCandidate(clone: Address, attempt: number): Hex {\n const out = new Uint8Array(LIGHTER_PUBKEY_LEN);\n for (let i = 0; i < 5; i++) {\n const preimage =\n attempt === 0\n ? encodePacked([\"string\", \"address\", \"uint8\"], [BURN_TAG, clone, i])\n : encodePacked([\"string\", \"address\", \"uint8\", \"uint16\"], [BURN_TAG, clone, i, attempt]);\n const h = hexToBytes(keccak256(preimage));\n let limb = 0n;\n for (let j = 0; j < 8; j++) limb = (limb << 8n) | BigInt(h[j]);\n limb %= GOLDILOCKS_P;\n if (limb === 0n) limb = 1n;\n for (let j = 0; j < 8; j++) out[i * 8 + j] = Number((limb >> BigInt(8 * j)) & 0xffn);\n }\n return bytesToHex(out);\n}\n\n/**\n * A nothing-up-my-sleeve burn key for `ROTATE_KEY`, derived from the clone\n * address by try-and-increment until it is a VALID ECgFp5 point:\n * attempt 0: limb i = keccak256(\"sherwood.lighter.burn-key.v1\" ‖ clone ‖ uint8 i)[0..8] mod p (0 → 1)\n * attempt n: limb i = keccak256(\"sherwood.lighter.burn-key.v1\" ‖ clone ‖ uint8 i ‖ uint16 n)[0..8] mod p\n * written little-endian, first attempt that decodes wins. Attempt 0 is the\n * original derivation, so a clone whose original key already decoded keeps it.\n * Anyone can recompute it; nobody knows a private key for it (hash-to-curve by\n * try-and-increment leaves the discrete log unknown). It must be a valid point:\n * a non-decoding key may be silently dropped by the venue, leaving the old\n * agent key live. Rotating to it before settle retires the agent key for good\n * — after settle nobody can rotate it (guardrails are `Executed`-only).\n */\nexport function deriveBurnPubKey(clone: Address): Hex {\n for (let attempt = 0; attempt < BURN_MAX_ATTEMPTS; attempt++) {\n const key = burnCandidate(clone, attempt);\n if (isLighterPubKeyOnCurve(key)) return key;\n }\n // 2^-256 — unreachable in practice, but never return an invalid key.\n throw new Error(`no valid ECgFp5 burn key for ${clone} in ${BURN_MAX_ATTEMPTS} attempts`);\n}\n\n// ── CLI flag parsing (pure; shared by clone / init / propose) ──\n\nexport interface LighterTemplateFlags {\n pubkey?: string;\n keyIndex?: string;\n markets?: string;\n deposit?: string;\n amount?: string;\n}\n\n/**\n * `--pubkey` / `--key-index` / `--markets` / `--deposit` → init params.\n * `saved` is the key `sherwood lighter keygen` stored (the command layer reads\n * it); an explicit `--pubkey` always wins, and `--key-index` defaults to the\n * saved key's slot, else 2. `--amount` is accepted as an alias of `--deposit`\n * (every other template sizes with it).\n */\nexport function parseLighterTemplateFlags(\n flags: LighterTemplateFlags,\n saved?: { pubKey: string; apiKeyIndex: number },\n): LighterPerpInitParams {\n const rawPub = flags.pubkey ?? saved?.pubKey;\n if (!rawPub) {\n throw new Error(\"lighter-perp: --pubkey <hex> is required (or run `sherwood lighter keygen` to create and save one)\");\n }\n const pubKey = validateLighterPubKey(rawPub);\n const keyIndex = validateLighterKeyIndex(\n flags.keyIndex ?? (flags.pubkey === undefined && saved ? saved.apiKeyIndex : LIGHTER_DEFAULT_API_KEY_INDEX),\n );\n if (!flags.markets) throw new Error(\"lighter-perp: --markets <ids> is required (comma-separated perp market ids, ≤ 16)\");\n const markets = parseLighterMarkets(flags.markets);\n if (flags.deposit !== undefined && flags.amount !== undefined && flags.deposit !== flags.amount) {\n throw new Error(\"lighter-perp: --deposit and --amount disagree — pass one\");\n }\n const human = flags.deposit ?? flags.amount;\n if (!human) throw new Error(\"lighter-perp: --deposit <usdg> is required (human units, e.g. 1000 = 1,000 USDG)\");\n const depositAmount = validateLighterDeposit(usdgToTicks(human));\n return { pubKey, keyIndex, markets, depositAmount };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,18 @@
1
+ // src/lib/calldata.ts
2
+ var _calldataOnly = false;
3
+ function setCalldataOnly(value) {
4
+ _calldataOnly = value;
5
+ }
6
+ function isCalldataOnly() {
7
+ return _calldataOnly;
8
+ }
9
+ function emitCalldata(action) {
10
+ process.stdout.write(JSON.stringify(action, null, 2) + "\n");
11
+ }
12
+
13
+ export {
14
+ setCalldataOnly,
15
+ isCalldataOnly,
16
+ emitCalldata
17
+ };
18
+ //# sourceMappingURL=chunk-GAQMHH44.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/calldata.ts"],"sourcesContent":["/**\n * `--calldata-only` support.\n *\n * When the global `--calldata-only` flag is set, state-changing commands build\n * the unsigned EIP-5792-style calldata via the shared `@sherwoodagent/sdk`\n * encoders and print it as JSON instead of signing/sending — so an external\n * signer (MetaMask Agent Wallet, Frame, Privy, …) that can't export a private\n * key can take the final step. Output matches the HTTP API's `/v1/prepare/*`\n * envelope (the SDK `PreparedAction` shape).\n */\nimport type { PreparedAction } from \"@sherwoodagent/sdk\";\n\nlet _calldataOnly = false;\n\n/** Set by the root preAction hook from the global `--calldata-only` flag. */\nexport function setCalldataOnly(value: boolean): void {\n _calldataOnly = value;\n}\n\nexport function isCalldataOnly(): boolean {\n return _calldataOnly;\n}\n\n/**\n * Print a PreparedAction as pretty JSON. Each tx is `{ to, data, value, chainId }`\n * with a hex `value` (EIP-5792). `chainId` is per-tx, so multi-chain flows\n * (e.g. approve-agent: registerAgent on the fund chain + attest on Base)\n * are explicit.\n */\nexport function emitCalldata(action: PreparedAction): void {\n process.stdout.write(JSON.stringify(action, null, 2) + \"\\n\");\n}\n"],"mappings":";AAYA,IAAI,gBAAgB;AAGb,SAAS,gBAAgB,OAAsB;AACpD,kBAAgB;AAClB;AAEO,SAAS,iBAA0B;AACxC,SAAO;AACT;AAQO,SAAS,aAAa,QAA8B;AACzD,UAAQ,OAAO,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI,IAAI;AAC7D;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getNetwork
3
- } from "./chunk-G3FUEM5N.js";
3
+ } from "./chunk-LIW6K4OJ.js";
4
4
 
5
5
  // src/lib/address-overrides.ts
6
6
  import { readFileSync } from "fs";
@@ -22,7 +22,19 @@ var CHAINS_TO_CLI = {
22
22
  MAMO_YIELD_TEMPLATE: "MAMO_YIELD",
23
23
  PORTFOLIO_TEMPLATE: "PORTFOLIO",
24
24
  HYPERLIQUID_PERP_TEMPLATE: "HYPERLIQUID_PERP",
25
- HYPERLIQUID_GRID_TEMPLATE: "HYPERLIQUID_GRID"
25
+ HYPERLIQUID_GRID_TEMPLATE: "HYPERLIQUID_GRID",
26
+ // v1 protocol templates (sherwood-protocol chains/<chainId>.json).
27
+ MORPHO_SUPPLY_TEMPLATE: "MORPHO_SUPPLY",
28
+ CONCENTRATED_LIQUIDITY_TEMPLATE: "CONCENTRATED_LIQUIDITY",
29
+ // sherwood-strategies templates (deployments/<chainId>.json — same flat
30
+ // KEY: address format, so SIM_ADDRESSES_FILE can point at either book or
31
+ // a merge of both).
32
+ LAUNCHPAD_TEMPLATE: "LAUNCHPAD",
33
+ LIGHTER_PERP_TEMPLATE: "LIGHTER_PERP"
34
+ },
35
+ LAUNCH_ADAPTERS: {
36
+ SUSHI_LAUNCH_ADAPTER: "SUSHI",
37
+ STONK_LAUNCH_ADAPTER: "STONK"
26
38
  },
27
39
  ENS: {
28
40
  L2_REGISTRAR: "L2_REGISTRAR",
@@ -294,7 +306,26 @@ var ROBINHOOD_TESTNET_STRATEGY_TEMPLATES = {
294
306
  PORTFOLIO: "0x67420Cc504d70a42Adfd8867d878afe0978C7d10",
295
307
  // v1 templates — deployed on the fork only so far (no 46630 equivalent).
296
308
  MORPHO_SUPPLY: ZERO,
297
- CONCENTRATED_LIQUIDITY: ZERO
309
+ CONCENTRATED_LIQUIDITY: ZERO,
310
+ // sherwood-strategies templates (book: sherwood-strategies
311
+ // deployments/<chainId>.json, keys LAUNCHPAD_TEMPLATE / LIGHTER_PERP_TEMPLATE).
312
+ // No 46630 deployment of either.
313
+ LAUNCHPAD: ZERO,
314
+ LIGHTER_PERP: ZERO
315
+ };
316
+ var ROBINHOOD_TESTNET_LAUNCH_ADAPTERS = {
317
+ SUSHI: ZERO,
318
+ STONK: ZERO
319
+ };
320
+ var STONK_LANES = ["WETH", "STONK", "USDG", "GME", "NVDA", "AAPL", "SPCX", "USO"];
321
+ var NO_STRATEGY_VENUES = {
322
+ SUSHI_LAUNCHPAD_V2: ZERO,
323
+ STONK_PADS_V2: Object.fromEntries(STONK_LANES.map((l) => [l, ZERO])),
324
+ STONK_LENS_V2: ZERO,
325
+ ZK_LIGHTER: ZERO,
326
+ MORPHO_BLUE: ZERO,
327
+ UNISWAP_V3_FACTORY: ZERO,
328
+ UNISWAP_V3_POSITION_MANAGER: ZERO
298
329
  };
299
330
  var ROBINHOOD_MAINNET_EAS = {
300
331
  EAS: "0x7d70441Bb10AcE5d9771dc0b6205D89ddf63205B",
@@ -367,11 +398,40 @@ var ROBINHOOD_FORK_STRATEGY_TEMPLATES = {
367
398
  PORTFOLIO: "0xAA5872009c527cCb80343E41C52840CEdb095eb0",
368
399
  // MORPHO_SUPPLY_TEMPLATE / CONCENTRATED_LIQUIDITY_TEMPLATE from
369
400
  // sherwood-protocol/chains/9994663.json. Both are live and on the
370
- // StrategyFactory allowlist; the CLI has no init encoder for their init
371
- // tuples yet, so `strategy list` shows them and `clone`/`propose` say so
372
- // explicitly instead of the address book pretending they don't exist.
401
+ // StrategyFactory allowlist; their init encoders live in
402
+ // strategies/morpho-supply-template.ts and concentrated-liquidity-template.ts.
373
403
  MORPHO_SUPPLY: "0x5B55E1Da361573CB0788e750038567D2569BE41d",
374
- CONCENTRATED_LIQUIDITY: "0xcba9C84F2d382729D1519c5F7f4a9AAaC075f8B5"
404
+ CONCENTRATED_LIQUIDITY: "0xcba9C84F2d382729D1519c5F7f4a9AAaC075f8B5",
405
+ // LAUNCHPAD_TEMPLATE from sherwood-strategies deployments/9994663.json
406
+ // (StrategyFactory-approved on the fork).
407
+ LAUNCHPAD: "0x4435Aae199907f60588902Bcd7c4363a13Bb2951",
408
+ // ZERO by decision: Lighter deploys on Robinhood mainnet only (the fork has
409
+ // no Lighter sequencer, so withdrawals never mature), and mainnet is
410
+ // coordination-only in the CLI.
411
+ LIGHTER_PERP: ZERO
412
+ };
413
+ var ROBINHOOD_FORK_LAUNCH_ADAPTERS = {
414
+ SUSHI: "0x20348e428050031647d671F0e24752C01D4b7379",
415
+ STONK: "0x0D62944862996791a9BCE992872F9Fa8E3162B49"
416
+ };
417
+ var ROBINHOOD_FORK_STRATEGY_VENUES = {
418
+ SUSHI_LAUNCHPAD_V2: "0xF1716eBf85836ffE2985db9A50dd29e5814caBe9",
419
+ STONK_PADS_V2: {
420
+ WETH: "0xFCd61B25BbF3AbD6cf0070D6328E351cc30EEC9f",
421
+ STONK: "0x8f6782c5Aa37804d08a9b7bf3984Ff3245Fd6cD4",
422
+ USDG: "0xd4F20033586977A2511f4A2DB4aF7C79a340D70a",
423
+ GME: "0x4B9Dcd6CCFAeF0f6D23065Dd78E79d5E20ec8cFD",
424
+ // EIP-55 checksummed here; the source JSON carries a mis-cased form.
425
+ NVDA: "0xEe96d955d5634813374ecE4C74F2C0ff71B1F9fB",
426
+ AAPL: "0xB0453A81Cbf963903409FFF18AD92941e1c7a864",
427
+ SPCX: "0x0c3b4EDED41696eFF0ed70841f132B519d81c947",
428
+ USO: "0xDb3C81C841ff88db6cDFbDDB0eE049D162A6053B"
429
+ },
430
+ STONK_LENS_V2: "0x25b5Df581f4b2Ed450203f375ad8A28b17F115B3",
431
+ ZK_LIGHTER: "0x94bAB9693Ba2f6358507eFfcbd372b0660AFfF9d",
432
+ MORPHO_BLUE: "0x9D53d5E3bd5E8d4Cbfa6DB1ca238AEA02E651010",
433
+ UNISWAP_V3_FACTORY: "0x1f7d7550B1b028f7571E69A784071F0205FD2EfA",
434
+ UNISWAP_V3_POSITION_MANAGER: "0x73991a25C818Bf1f1128dEAaB1492D45638DE0D3"
375
435
  };
376
436
  var TOKEN_REGISTRY = {
377
437
  "robinhood-testnet": ROBINHOOD_TESTNET_TOKENS,
@@ -436,6 +496,18 @@ var STRATEGY_TEMPLATE_REGISTRY = {
436
496
  "robinhood-mainnet": noneOf(ROBINHOOD_TESTNET_STRATEGY_TEMPLATES)
437
497
  // coordination chain — no Sherwood contracts
438
498
  };
499
+ var LAUNCH_ADAPTER_REGISTRY = {
500
+ "robinhood-testnet": ROBINHOOD_TESTNET_LAUNCH_ADAPTERS,
501
+ "robinhood-fork": ROBINHOOD_FORK_LAUNCH_ADAPTERS,
502
+ "robinhood-mainnet": noneOf(ROBINHOOD_TESTNET_LAUNCH_ADAPTERS)
503
+ // coordination chain — no Sherwood contracts
504
+ };
505
+ var STRATEGY_VENUE_REGISTRY = {
506
+ "robinhood-testnet": NO_STRATEGY_VENUES,
507
+ "robinhood-fork": ROBINHOOD_FORK_STRATEGY_VENUES,
508
+ "robinhood-mainnet": NO_STRATEGY_VENUES
509
+ // coordination chain — venues live, but not exposed (decided)
510
+ };
439
511
  var SYNTHRA_REGISTRY = {
440
512
  "robinhood-testnet": ROBINHOOD_TESTNET_SYNTHRA,
441
513
  "robinhood-fork": ROBINHOOD_TESTNET_SYNTHRA,
@@ -489,6 +561,15 @@ function STRATEGY_TEMPLATES() {
489
561
  ...overridesFor("STRATEGY_TEMPLATES")
490
562
  };
491
563
  }
564
+ function LAUNCH_ADAPTERS() {
565
+ return {
566
+ ...LAUNCH_ADAPTER_REGISTRY[getNetwork()],
567
+ ...overridesFor("LAUNCH_ADAPTERS")
568
+ };
569
+ }
570
+ function STRATEGY_VENUES() {
571
+ return STRATEGY_VENUE_REGISTRY[getNetwork()];
572
+ }
492
573
  function EAS_CONTRACTS() {
493
574
  return EAS_CONTRACT_REGISTRY[getNetwork()];
494
575
  }
@@ -513,9 +594,11 @@ export {
513
594
  SHERWOOD,
514
595
  AERODROME,
515
596
  STRATEGY_TEMPLATES,
597
+ LAUNCH_ADAPTERS,
598
+ STRATEGY_VENUES,
516
599
  EAS_CONTRACTS,
517
600
  EAS_SCHEMAS,
518
601
  SYNTHRA,
519
602
  CHAINLINK
520
603
  };
521
- //# sourceMappingURL=chunk-FWQESFFM.js.map
604
+ //# sourceMappingURL=chunk-GYGSKMZE.js.map