@continuumdao/ctm-mpc-defi 0.2.0 → 0.2.2

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 (100) hide show
  1. package/README.md +20 -78
  2. package/dist/agent/catalog.cjs +563 -5
  3. package/dist/agent/catalog.cjs.map +1 -1
  4. package/dist/agent/catalog.d.ts +166 -20
  5. package/dist/agent/catalog.js +551 -7
  6. package/dist/agent/catalog.js.map +1 -1
  7. package/dist/agent/skills/aave-v4/SKILL.md +43 -0
  8. package/dist/agent/skills/curve-dao/SKILL.md +13 -0
  9. package/dist/agent/skills/ethena/SKILL.md +10 -0
  10. package/dist/agent/skills/euler-v2/SKILL.md +10 -0
  11. package/dist/agent/skills/lido/SKILL.md +22 -0
  12. package/dist/agent/skills/maple-syrup/SKILL.md +10 -0
  13. package/dist/agent/skills/sky/SKILL.md +10 -0
  14. package/dist/agent/skills/uniswap-v4/SKILL.md +22 -0
  15. package/dist/chains/evm/index.cjs +79 -224
  16. package/dist/chains/evm/index.cjs.map +1 -1
  17. package/dist/chains/evm/index.d.ts +26 -26
  18. package/dist/chains/evm/index.js +69 -209
  19. package/dist/chains/evm/index.js.map +1 -1
  20. package/dist/chains/near/index.d.ts +1 -1
  21. package/dist/chains/solana/index.d.ts +1 -1
  22. package/dist/core/index.cjs +68 -106
  23. package/dist/core/index.cjs.map +1 -1
  24. package/dist/core/index.d.ts +21 -36
  25. package/dist/core/index.js +57 -96
  26. package/dist/core/index.js.map +1 -1
  27. package/dist/{envelope-CcE5Cz_q.d.ts → envelope-CpBUh9eP.d.ts} +1 -1
  28. package/dist/index.cjs +356 -1855
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.ts +7 -11
  31. package/dist/index.js +332 -1826
  32. package/dist/index.js.map +1 -1
  33. package/dist/protocols/evm/aave-v4/index.cjs +1152 -669
  34. package/dist/protocols/evm/aave-v4/index.cjs.map +1 -1
  35. package/dist/protocols/evm/aave-v4/index.d.ts +418 -3
  36. package/dist/protocols/evm/aave-v4/index.js +1126 -670
  37. package/dist/protocols/evm/aave-v4/index.js.map +1 -1
  38. package/dist/protocols/evm/curve-dao/index.cjs +257 -131
  39. package/dist/protocols/evm/curve-dao/index.cjs.map +1 -1
  40. package/dist/protocols/evm/curve-dao/index.d.ts +69 -5
  41. package/dist/protocols/evm/curve-dao/index.js +242 -124
  42. package/dist/protocols/evm/curve-dao/index.js.map +1 -1
  43. package/dist/protocols/evm/ethena/index.cjs +394 -402
  44. package/dist/protocols/evm/ethena/index.cjs.map +1 -1
  45. package/dist/protocols/evm/ethena/index.d.ts +47 -3
  46. package/dist/protocols/evm/ethena/index.js +390 -404
  47. package/dist/protocols/evm/ethena/index.js.map +1 -1
  48. package/dist/protocols/evm/euler-v2/index.cjs +2810 -1191
  49. package/dist/protocols/evm/euler-v2/index.cjs.map +1 -1
  50. package/dist/protocols/evm/euler-v2/index.d.ts +465 -3
  51. package/dist/protocols/evm/euler-v2/index.js +2761 -1192
  52. package/dist/protocols/evm/euler-v2/index.js.map +1 -1
  53. package/dist/protocols/evm/lido/index.cjs +351 -236
  54. package/dist/protocols/evm/lido/index.cjs.map +1 -1
  55. package/dist/protocols/evm/lido/index.d.ts +34 -4
  56. package/dist/protocols/evm/lido/index.js +348 -238
  57. package/dist/protocols/evm/lido/index.js.map +1 -1
  58. package/dist/protocols/evm/maple/index.cjs +390 -395
  59. package/dist/protocols/evm/maple/index.cjs.map +1 -1
  60. package/dist/protocols/evm/maple/index.d.ts +23 -3
  61. package/dist/protocols/evm/maple/index.js +390 -397
  62. package/dist/protocols/evm/maple/index.js.map +1 -1
  63. package/dist/protocols/evm/sky/index.cjs +454 -232
  64. package/dist/protocols/evm/sky/index.cjs.map +1 -1
  65. package/dist/protocols/evm/sky/index.d.ts +57 -3
  66. package/dist/protocols/evm/sky/index.js +444 -231
  67. package/dist/protocols/evm/sky/index.js.map +1 -1
  68. package/dist/protocols/evm/uniswap-v4/index.cjs +423 -658
  69. package/dist/protocols/evm/uniswap-v4/index.cjs.map +1 -1
  70. package/dist/protocols/evm/uniswap-v4/index.d.ts +3 -4
  71. package/dist/protocols/evm/uniswap-v4/index.js +422 -657
  72. package/dist/protocols/evm/uniswap-v4/index.js.map +1 -1
  73. package/dist/{registry-oMKlO_5z.d.ts → registry-Bv5o37_w.d.ts} +1 -1
  74. package/dist/{types-Ce2qNHai.d.cts → types-BfjWdw1j.d.ts} +3 -1
  75. package/dist/{types-5u863Fd9.d.ts → types-DUeNJLr9.d.ts} +1 -1
  76. package/package.json +7 -6
  77. package/dist/agent/catalog.d.cts +0 -939
  78. package/dist/chains/evm/index.d.cts +0 -64
  79. package/dist/chains/near/index.d.cts +0 -37
  80. package/dist/chains/solana/index.d.cts +0 -40
  81. package/dist/core/index.d.cts +0 -43
  82. package/dist/envelope-DYDPnrHZ.d.cts +0 -35
  83. package/dist/index.d.cts +0 -16
  84. package/dist/keygen-CfNp8yKJ.d.cts +0 -9
  85. package/dist/keygen-DsINazx8.d.ts +0 -9
  86. package/dist/nodeRead-BnmSaMGO.d.cts +0 -8
  87. package/dist/nodeRead-BnmSaMGO.d.ts +0 -8
  88. package/dist/protocols/evm/aave-v4/index.d.cts +0 -500
  89. package/dist/protocols/evm/curve-dao/index.d.cts +0 -147
  90. package/dist/protocols/evm/ethena/index.d.cts +0 -161
  91. package/dist/protocols/evm/euler-v2/index.d.cts +0 -317
  92. package/dist/protocols/evm/lido/index.d.cts +0 -120
  93. package/dist/protocols/evm/maple/index.d.cts +0 -109
  94. package/dist/protocols/evm/sky/index.d.cts +0 -218
  95. package/dist/protocols/evm/uniswap-v4/index.d.cts +0 -324
  96. package/dist/registry-BwZoE668.d.cts +0 -8
  97. package/dist/txParams-BC7ogvdR.d.cts +0 -19
  98. package/dist/txParams-BC7ogvdR.d.ts +0 -19
  99. package/dist/types-B8idm_gu.d.cts +0 -34
  100. package/dist/types-Ce2qNHai.d.ts +0 -57
@@ -1,4 +1,5 @@
1
- import { parseAbi, parseGwei, serializeTransaction, keccak256, defineChain, createPublicClient, http, getAddress, parseUnits, encodeFunctionData, decodeFunctionData, formatUnits } from 'viem';
1
+ import { parseAbi, defineChain, createPublicClient, http, getAddress, parseUnits, encodeFunctionData, decodeFunctionData, formatUnits, parseGwei, serializeTransaction, keccak256 } from 'viem';
2
+ import { fetchChainFeeParams, gasLimitFromEstimateAndChainConfig, gweiToDecimalString, proposalTxParamsToFeeSnapshot, alignEip1559FeesWithLatestBase, getClientIdFromKeyGenResult } from '@continuumdao/continuum-node-sdk';
2
3
 
3
4
  // src/core/registry.ts
4
5
  var modules = [];
@@ -23,197 +24,167 @@ var SKY_LOCKSTAKE_DEFAULT_FARM_REF = 1;
23
24
  var SKY_LOCKSTAKE_UI_COLLATERAL_FACTOR = 0.65;
24
25
  var SKY_TOKEN_DECIMALS = 18;
25
26
  var USDS_DECIMALS = 18;
26
- async function fetchChainFeeParams(rpcUrl, chainId) {
27
- const url = rpcUrl.trim();
28
- if (!url) return { isEip1559: false };
29
- const chainIdNum = typeof chainId === "string" ? parseInt(chainId, 10) : chainId;
30
- if (Number.isNaN(chainIdNum)) return { isEip1559: false };
31
- const chain = defineChain({
32
- id: chainIdNum,
33
- name: "Discovery",
34
- nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
35
- rpcUrls: { default: { http: [url] } }
36
- });
37
- const publicClient = createPublicClient({
38
- chain,
39
- transport: http(url)
40
- });
41
- const getGasPriceGwei = async () => {
42
- const gasPriceWei = await publicClient.getGasPrice();
43
- return parseFloat(formatUnits(gasPriceWei, 9));
44
- };
45
- try {
46
- const block = await publicClient.getBlock({ blockTag: "latest" });
47
- const baseFeePerGas = block?.baseFeePerGas;
48
- if (baseFeePerGas == null || baseFeePerGas === void 0) {
49
- const gasPriceGwei2 = await getGasPriceGwei();
50
- return { isEip1559: false, gasPriceGwei: gasPriceGwei2 };
51
- }
52
- const baseFeeGwei = parseFloat(formatUnits(baseFeePerGas, 9));
53
- let priorityFeeGwei;
54
- try {
55
- const priorityWei = await publicClient.estimateMaxPriorityFeePerGas();
56
- priorityFeeGwei = parseFloat(formatUnits(priorityWei, 9));
57
- } catch {
58
- }
59
- const gasPriceGwei = await getGasPriceGwei();
60
- return {
61
- isEip1559: true,
62
- baseFeeGwei,
63
- priorityFeeGwei,
64
- gasPriceGwei
65
- };
66
- } catch {
67
- try {
68
- const gasPriceWei = await publicClient.getGasPrice();
69
- const gasPriceGwei = parseFloat(formatUnits(gasPriceWei, 9));
70
- return { isEip1559: false, gasPriceGwei };
71
- } catch {
72
- return { isEip1559: false };
73
- }
74
- }
27
+
28
+ // src/core/purpose.ts
29
+ function mergePurposeText(purposeText, purposeSuffix) {
30
+ const t = purposeText.trim();
31
+ const suffix = (purposeSuffix ?? "").trim();
32
+ if (!suffix) return t;
33
+ return t ? `${t}
34
+
35
+ ${suffix}` : suffix;
75
36
  }
76
- function finalizeEip1559Fees(maxFeePerGas, maxPriorityFeePerGas, floor, baseWei) {
77
- let maxP = maxPriorityFeePerGas;
78
- let maxF = maxFeePerGas;
79
- if (baseWei > 0n && maxF < baseWei + maxP) {
80
- maxF = baseWei + maxP + parseGwei("0.001");
37
+
38
+ // src/core/envelope.ts
39
+ function finalizeMultisign(input) {
40
+ const { keyGen, destinationChainID, legs } = input;
41
+ if (legs.length === 0) {
42
+ throw new Error("finalizeMultisign requires at least one leg");
81
43
  }
82
- if (maxF < maxP) {
83
- maxF = baseWei > 0n ? baseWei + maxP + parseGwei("0.001") : maxP * 2n;
44
+ const ph = (keyGen.pubkeyhex ?? "").trim();
45
+ if (!ph) throw new Error("keyGen pubKey (pubkeyhex) is required");
46
+ const keyList = keyGen.keylist ?? [];
47
+ const clientId = getClientIdFromKeyGenResult(keyGen);
48
+ const first = legs[0];
49
+ const messageHashes = legs.map((l) => l.msgHash);
50
+ const messageRawBatch = legs.map((l) => l.msgRaw);
51
+ const batchMeta = legs.map((l) => ({
52
+ destinationAddress: l.destinationAddress,
53
+ signatureText: l.signatureText,
54
+ ...l.audit
55
+ }));
56
+ const proposalTxParams = legs.map((l) => l.proposalTxParams).filter((p) => p != null && typeof p === "object");
57
+ const extraPayload = {
58
+ batchMeta,
59
+ ...input.extraJSON ?? {}
60
+ };
61
+ const extraJSON = JSON.stringify(extraPayload);
62
+ const bodyForSign = {
63
+ keyList,
64
+ pubKey: ph,
65
+ msgHash: messageHashes[0],
66
+ msgRaw: first.msgRaw,
67
+ destinationChainID,
68
+ destinationAddress: input.destinationAddress ?? first.destinationAddress,
69
+ extraJSON,
70
+ signatureText: first.signatureText,
71
+ purpose: mergePurposeText(input.purposeText, input.purposeSuffix),
72
+ ...first.feeSnapshot
73
+ };
74
+ if (legs.length > 1) {
75
+ bodyForSign.messageHashes = messageHashes;
76
+ bodyForSign.messageRawBatch = messageRawBatch;
84
77
  }
85
- return { maxFeePerGas: maxF, maxPriorityFeePerGas: maxP };
86
- }
87
- function alignEip1559FeesWithLatestBase(maxFeePerGas, maxPriorityFeePerGas, latestBlockBaseFeeWei) {
88
- return finalizeEip1559Fees(maxFeePerGas, maxPriorityFeePerGas, null, latestBlockBaseFeeWei);
89
- }
90
-
91
- // src/chains/evm/txParams.ts
92
- function gasLimitFromEstimateAndChainConfig(estimatedGas, chainGasLimit) {
93
- if (chainGasLimit == null || !Number.isFinite(chainGasLimit) || chainGasLimit <= 0) {
94
- return estimatedGas;
78
+ if (proposalTxParams.length > 0) {
79
+ bodyForSign.proposalTxParams = proposalTxParams;
80
+ }
81
+ const valueWei = first.valueWei;
82
+ if (valueWei != null && valueWei > 0n) {
83
+ bodyForSign.value = valueWei.toString();
95
84
  }
96
- const cfg = BigInt(Math.floor(chainGasLimit));
97
- return cfg > estimatedGas ? cfg : estimatedGas;
85
+ if (clientId) bodyForSign.clientId = clientId;
86
+ return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
98
87
  }
99
-
100
- // src/core/keygen.ts
101
- function firstClientIdFromKeyGen(data) {
102
- const map = data?.ClientKeys;
103
- if (!map || typeof map !== "object") return null;
104
- for (const v of Object.values(map)) {
105
- if (typeof v === "string" && v.trim()) return v.trim();
88
+ function routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimit) {
89
+ if (chainGasLimit != null && Number.isFinite(chainGasLimit) && chainGasLimit > 0) {
90
+ return gasLimitFromEstimateAndChainConfig(estimatedGas, chainGasLimit);
106
91
  }
107
- return null;
92
+ return (estimatedGas * 12n + 9n) / 10n;
108
93
  }
109
94
 
110
- // src/protocols/evm/sky/lockstakeMultisign.ts
111
- var SKY_LOCKSTAKE_MULTICALL_FALLBACK_GAS = 5000000n;
112
- var erc20AllowanceAbi = parseAbi([
113
- "function allowance(address owner, address spender) view returns (uint256)",
114
- "function decimals() view returns (uint8)"
115
- ]);
116
- var erc20ApproveAbi = parseAbi(["function approve(address spender, uint256 amount) returns (bool)"]);
117
- var engineAbi = parseAbi([
118
- "function multicall(bytes[] data) returns (bytes[])",
119
- "function open(uint256 index) returns (address)",
120
- "function selectFarm(address owner, uint256 index, address farm, uint16 ref)",
121
- /** Canonical SKY collateral (pulls ERC-20 `sky()`, then `mkrSky.skyToMkr`). Legacy `lock` pulls MKR only. */
122
- "function lockSky(address owner, uint256 index, uint256 skyWad, uint16 ref)",
123
- "function draw(address owner, uint256 index, address to, uint256 wad)",
124
- "function wipe(address owner, uint256 index, uint256 wad)",
125
- "function wipeAll(address owner, uint256 index) returns (uint256 wad)",
126
- /** Returns withdrawn SKY; legacy `free` returns MKR after fee-burn. */
127
- "function freeSky(address owner, uint256 index, address to, uint256 skyWad) returns (uint256 skyFreed)",
128
- "function getReward(address owner, uint256 index, address farm, address to) returns (uint256)",
129
- "function ownerUrnsCount(address usr) view returns (uint256)",
130
- "function ownerUrns(address owner, uint256 index) view returns (address urn)",
131
- "function urnFarms(address urn) view returns (address farm)",
132
- "function farms(address farm) view returns (uint8)"
133
- ]);
134
- var stakingRewardsFarmReadAbi = parseAbi([
135
- "function stakingToken() view returns (address)",
136
- "function rewardsToken() view returns (address)"
137
- ]);
138
- function gweiToDecimalString(n) {
139
- if (!Number.isFinite(n)) return "0";
140
- if (n === 0) return "0";
141
- const s = String(n);
142
- if (s.indexOf("e") !== -1 || s.indexOf("E") !== -1) return n.toFixed(9).replace(/\.?0+$/, "") || "0";
143
- return s;
144
- }
145
- async function appendSerializedSkyBatch(args) {
146
- const ph = (args.keyGen.pubkeyhex ?? "").trim();
147
- if (!ph) throw new Error("keyGen pubKey (pubkeyhex) is required");
148
- const keyList = args.keyGen.keylist ?? [];
149
- const clientId = firstClientIdFromKeyGen(args.keyGen);
150
- const feeParams = await fetchChainFeeParams(args.rpcUrl, args.chainId);
151
- const legacy = Boolean(args.chainDetail?.legacy) || !feeParams.isEip1559;
152
- const latestBaseFeeWei = !legacy ? (await args.publicClient.getBlock({ blockTag: "latest" })).baseFeePerGas ?? 0n : 0n;
153
- const useCustomGas = args.useCustomGas;
154
- const gasLimitConfig = useCustomGas && args.chainDetail?.gasLimit != null ? Number(args.chainDetail.gasLimit) : void 0;
155
- const gasFeeMultiplier = useCustomGas && args.chainDetail?.gasMultiplier != null ? Number(args.chainDetail.gasMultiplier) : void 0;
156
- const baseNonce = await args.publicClient.getTransactionCount({ address: args.executor, blockTag: "pending" });
157
- const messageHashes = [];
158
- const messageRawBatch = [];
159
- const proposalTxParamsBatch = [];
160
- let firstTxFeePayload = {};
161
- let firstDataNo0x = "";
162
- for (let i = 0; i < args.steps.length; i++) {
163
- const s = args.steps[i];
95
+ // src/chains/evm/buildBatch.ts
96
+ async function buildEvmMultisignBatch(args) {
97
+ const { context, steps } = args;
98
+ const {
99
+ chainId,
100
+ rpcUrl,
101
+ executorAddress,
102
+ chainDetail,
103
+ useCustomGas,
104
+ customGasChainDetails,
105
+ keyGen,
106
+ purposeText
107
+ } = context;
108
+ if (steps.length === 0) throw new Error("buildEvmMultisignBatch requires at least one step");
109
+ const ch = defineChain({
110
+ id: chainId,
111
+ name: "Destination",
112
+ nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
113
+ rpcUrls: { default: { http: [rpcUrl] } }
114
+ });
115
+ const publicClient = createPublicClient({ chain: ch, transport: http(rpcUrl) });
116
+ const feeParams = await fetchChainFeeParams(rpcUrl, chainId);
117
+ const legacy = Boolean(chainDetail?.legacy) || !feeParams.isEip1559;
118
+ const latestBaseFeeWei = !legacy ? (await publicClient.getBlock({ blockTag: "latest" })).baseFeePerGas ?? 0n : 0n;
119
+ const gasLimitConfig = useCustomGas && chainDetail?.gasLimit != null ? Number(chainDetail.gasLimit) : void 0;
120
+ const chainGasLimitRouter = chainDetail?.gasLimit != null && Number.isFinite(Number(chainDetail.gasLimit)) && Number(chainDetail.gasLimit) > 0 ? Number(chainDetail.gasLimit) : void 0;
121
+ const gasFeeMultiplier = useCustomGas && chainDetail?.gasMultiplier != null ? Number(chainDetail.gasMultiplier) : void 0;
122
+ const executor = getAddress(executorAddress);
123
+ const baseNonce = await publicClient.getTransactionCount({ address: executor, blockTag: "pending" });
124
+ const legs = [];
125
+ for (let i = 0; i < steps.length; i++) {
126
+ const step = steps[i];
164
127
  const currentNonce = baseNonce + i;
165
128
  let estimatedGas;
166
- try {
167
- estimatedGas = await args.publicClient.estimateGas({
168
- to: s.to,
169
- data: s.data,
170
- value: s.value,
171
- account: args.executor
172
- });
173
- } catch {
174
- estimatedGas = SKY_LOCKSTAKE_MULTICALL_FALLBACK_GAS;
129
+ if (args.estimateGasForStep) {
130
+ estimatedGas = await args.estimateGasForStep({ step, index: i, publicClient, executor });
131
+ } else {
132
+ try {
133
+ estimatedGas = await publicClient.estimateGas({
134
+ to: step.to,
135
+ data: step.data,
136
+ value: step.value,
137
+ account: executor
138
+ });
139
+ } catch {
140
+ estimatedGas = step.fallbackGas ?? 100000n;
141
+ }
142
+ }
143
+ let gasLimitI;
144
+ if (args.resolveGasLimit) {
145
+ gasLimitI = await args.resolveGasLimit({ step, index: i, estimatedGas, publicClient });
146
+ } else if (step.routerSwap) {
147
+ gasLimitI = routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimitRouter);
148
+ } else {
149
+ gasLimitI = useCustomGas ? gasLimitFromEstimateAndChainConfig(estimatedGas, gasLimitConfig) : estimatedGas;
175
150
  }
176
- const gasLimitI = useCustomGas ? gasLimitFromEstimateAndChainConfig(estimatedGas, gasLimitConfig) : estimatedGas;
151
+ let proposalTxParams;
152
+ let feeSnapshot;
153
+ let serialized;
177
154
  if (legacy) {
178
- let gasPriceWei = await args.publicClient.getGasPrice();
155
+ let gasPriceWei = await publicClient.getGasPrice();
179
156
  if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
180
157
  gasPriceWei = gasPriceWei * BigInt(100 + gasFeeMultiplier) / 100n;
181
158
  }
182
- if (useCustomGas && args.chainDetail?.gasPrice != null && args.chainDetail.gasPrice > 0) {
183
- const configured = parseGwei(gweiToDecimalString(Number(args.chainDetail.gasPrice)));
159
+ if (useCustomGas && chainDetail?.gasPrice != null && chainDetail.gasPrice > 0) {
160
+ const configured = parseGwei(gweiToDecimalString(Number(chainDetail.gasPrice)));
184
161
  if (configured > gasPriceWei) gasPriceWei = configured;
185
162
  }
186
- const ser = serializeTransaction({
163
+ serialized = serializeTransaction({
187
164
  type: "legacy",
188
- to: s.to,
189
- data: s.data,
190
- value: s.value,
165
+ to: step.to,
166
+ data: step.data,
167
+ value: step.value,
191
168
  gas: gasLimitI,
192
169
  gasPrice: gasPriceWei,
193
170
  nonce: currentNonce,
194
- chainId: args.chainId
171
+ chainId
195
172
  });
196
- const h = keccak256(ser);
197
- messageHashes.push(h.startsWith("0x") ? h.slice(2) : h);
198
- messageRawBatch.push(ser);
199
- proposalTxParamsBatch.push({
173
+ proposalTxParams = {
200
174
  nonce: currentNonce,
201
175
  gasLimit: gasLimitI.toString(),
202
176
  txType: "legacy",
203
177
  gasPrice: gasPriceWei.toString()
204
- });
205
- if (i === 0) {
206
- firstTxFeePayload = { txNonce: currentNonce, txGasLimit: gasLimitI.toString(), txGasPrice: gasPriceWei.toString() };
207
- firstDataNo0x = s.data.startsWith("0x") ? s.data.slice(2) : s.data;
208
- }
178
+ };
179
+ feeSnapshot = proposalTxParamsToFeeSnapshot(proposalTxParams);
209
180
  } else {
210
181
  const fetchedBase = feeParams.baseFeeGwei ?? 0;
211
182
  const fetchedPriority = feeParams.priorityFeeGwei ?? 0;
212
- const configuredBase = useCustomGas && args.chainDetail?.baseFee != null ? Number(args.chainDetail.baseFee) : 0;
213
- const configuredPriority = useCustomGas && args.chainDetail?.priorityFee != null ? Number(args.chainDetail.priorityFee) : 0;
183
+ const configuredBase = useCustomGas && chainDetail?.baseFee != null ? Number(chainDetail.baseFee) : 0;
184
+ const configuredPriority = useCustomGas && chainDetail?.priorityFee != null ? Number(chainDetail.priorityFee) : 0;
214
185
  const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase);
215
186
  const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority);
216
- const baseFeeMultiplierPct = useCustomGas && args.chainDetail?.baseFeeMultiplier != null ? Math.max(100, Number(args.chainDetail.baseFeeMultiplier)) : 100;
187
+ const baseFeeMultiplierPct = useCustomGas && chainDetail?.baseFeeMultiplier != null ? Math.max(100, Number(chainDetail.baseFeeMultiplier)) : 100;
217
188
  const baseComponentGwei = effectiveBaseFeeGwei * baseFeeMultiplierPct / 100;
218
189
  const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei;
219
190
  let maxPriorityFeePerGas = effectivePriorityFeeGwei > 0 ? parseGwei(gweiToDecimalString(effectivePriorityFeeGwei)) : parseGwei("1");
@@ -227,62 +198,117 @@ async function appendSerializedSkyBatch(args) {
227
198
  maxPriorityFeePerGas,
228
199
  latestBaseFeeWei
229
200
  ));
230
- const ser = serializeTransaction({
201
+ serialized = serializeTransaction({
231
202
  type: "eip1559",
232
- to: s.to,
233
- data: s.data,
234
- value: s.value,
203
+ to: step.to,
204
+ data: step.data,
205
+ value: step.value,
235
206
  gas: gasLimitI,
236
207
  maxFeePerGas,
237
208
  maxPriorityFeePerGas,
238
209
  nonce: currentNonce,
239
- chainId: args.chainId
210
+ chainId
240
211
  });
241
- const h = keccak256(ser);
242
- messageHashes.push(h.startsWith("0x") ? h.slice(2) : h);
243
- messageRawBatch.push(ser);
244
- proposalTxParamsBatch.push({
212
+ proposalTxParams = {
245
213
  nonce: currentNonce,
246
214
  gasLimit: gasLimitI.toString(),
247
215
  txType: "eip1559",
248
216
  maxFeePerGas: maxFeePerGas.toString(),
249
217
  maxPriorityFeePerGas: maxPriorityFeePerGas.toString()
250
- });
251
- if (i === 0) {
252
- firstTxFeePayload = {
253
- txNonce: currentNonce,
254
- txGasLimit: gasLimitI.toString(),
255
- txMaxFeePerGas: maxFeePerGas.toString(),
256
- txMaxPriorityFeePerGas: maxPriorityFeePerGas.toString()
257
- };
258
- firstDataNo0x = s.data.startsWith("0x") ? s.data.slice(2) : s.data;
259
- }
218
+ };
219
+ feeSnapshot = i === 0 ? proposalTxParamsToFeeSnapshot(proposalTxParams) : {};
220
+ }
221
+ const h = keccak256(serialized);
222
+ const msgHash = h.startsWith("0x") ? h.slice(2) : h;
223
+ const batchMetaExtra = args.buildBatchMeta({ step, index: i, gasLimit: gasLimitI });
224
+ legs.push({
225
+ msgHash,
226
+ msgRaw: i === 0 && args.firstMsgRawNo0x != null ? args.firstMsgRawNo0x : serialized,
227
+ destinationAddress: step.to,
228
+ signatureText: typeof batchMetaExtra.signatureText === "string" ? batchMetaExtra.signatureText : JSON.stringify(batchMetaExtra.signatureText ?? {}),
229
+ audit: batchMetaExtra,
230
+ feeSnapshot: i === 0 ? feeSnapshot : {},
231
+ proposalTxParams,
232
+ valueWei: i === 0 ? step.value : void 0
233
+ });
234
+ if (i === 0 && args.firstMsgRawNo0x != null) {
235
+ legs[0].msgRaw = args.firstMsgRawNo0x;
260
236
  }
261
237
  }
262
- const batchMeta = args.steps.map((s) => s.meta);
263
- const extraPayload = { batchMeta };
264
- if (useCustomGas && args.customGasChainDetails && Object.keys(args.customGasChainDetails).length > 0) {
265
- extraPayload.customGasChainDetails = args.customGasChainDetails;
238
+ const extraJSON = {};
239
+ if (useCustomGas && customGasChainDetails && Object.keys(customGasChainDetails).length > 0) {
240
+ extraJSON.customGasChainDetails = customGasChainDetails;
266
241
  }
267
- const extraJSON = JSON.stringify(extraPayload);
268
- const firstSigText = batchMeta[0].signatureText;
269
- const bodyForSign = {
270
- keyList,
271
- pubKey: ph,
272
- msgHash: messageHashes[0],
273
- msgRaw: firstDataNo0x,
274
- messageHashes,
275
- messageRawBatch,
276
- destinationChainID: args.destinationChainID,
242
+ const result = finalizeMultisign({
243
+ keyGen,
244
+ purposeText,
245
+ purposeSuffix: args.purposeSuffix,
246
+ destinationChainID: String(chainId),
247
+ destinationAddress: args.destinationAddress ?? steps[0].to,
248
+ legs,
249
+ extraJSON: Object.keys(extraJSON).length > 0 ? extraJSON : void 0
250
+ });
251
+ const pv = args.payableValueWei;
252
+ if (pv != null && pv > 0n) {
253
+ result.bodyForSign.value = pv.toString();
254
+ }
255
+ return result;
256
+ }
257
+
258
+ // src/protocols/evm/sky/lockstakeMultisign.ts
259
+ var SKY_LOCKSTAKE_MULTICALL_FALLBACK_GAS = 5000000n;
260
+ var erc20AllowanceAbi = parseAbi([
261
+ "function allowance(address owner, address spender) view returns (uint256)",
262
+ "function decimals() view returns (uint8)"
263
+ ]);
264
+ var erc20ApproveAbi = parseAbi(["function approve(address spender, uint256 amount) returns (bool)"]);
265
+ var engineAbi = parseAbi([
266
+ "function multicall(bytes[] data) returns (bytes[])",
267
+ "function open(uint256 index) returns (address)",
268
+ "function selectFarm(address owner, uint256 index, address farm, uint16 ref)",
269
+ /** Canonical SKY collateral (pulls ERC-20 `sky()`, then `mkrSky.skyToMkr`). Legacy `lock` pulls MKR only. */
270
+ "function lockSky(address owner, uint256 index, uint256 skyWad, uint16 ref)",
271
+ "function draw(address owner, uint256 index, address to, uint256 wad)",
272
+ "function wipe(address owner, uint256 index, uint256 wad)",
273
+ "function wipeAll(address owner, uint256 index) returns (uint256 wad)",
274
+ /** Returns withdrawn SKY; legacy `free` returns MKR after fee-burn. */
275
+ "function freeSky(address owner, uint256 index, address to, uint256 skyWad) returns (uint256 skyFreed)",
276
+ "function getReward(address owner, uint256 index, address farm, address to) returns (uint256)",
277
+ "function ownerUrnsCount(address usr) view returns (uint256)",
278
+ "function ownerUrns(address owner, uint256 index) view returns (address urn)",
279
+ "function urnFarms(address urn) view returns (address farm)",
280
+ "function farms(address farm) view returns (uint8)"
281
+ ]);
282
+ var stakingRewardsFarmReadAbi = parseAbi([
283
+ "function stakingToken() view returns (address)",
284
+ "function rewardsToken() view returns (address)"
285
+ ]);
286
+ async function appendSerializedSkyBatch(args) {
287
+ const evmSteps = args.steps.map((s) => ({
288
+ to: s.to,
289
+ data: s.data,
290
+ value: s.value,
291
+ fallbackGas: SKY_LOCKSTAKE_MULTICALL_FALLBACK_GAS
292
+ }));
293
+ const firstDataNo0x = evmSteps[0].data.startsWith("0x") ? evmSteps[0].data.slice(2) : evmSteps[0].data;
294
+ return buildEvmMultisignBatch({
295
+ context: {
296
+ chainCategory: "evm",
297
+ keyGen: args.keyGen,
298
+ purposeText: "",
299
+ chainId: args.chainId,
300
+ rpcUrl: args.rpcUrl,
301
+ executorAddress: args.executor,
302
+ chainDetail: args.chainDetail,
303
+ useCustomGas: args.useCustomGas,
304
+ customGasChainDetails: args.customGasChainDetails
305
+ },
306
+ steps: evmSteps,
307
+ purposeSuffix: args.purposePrefix,
308
+ firstMsgRawNo0x: firstDataNo0x,
277
309
  destinationAddress: args.steps[0].to,
278
- extraJSON,
279
- signatureText: firstSigText,
280
- purpose: args.purposePrefix,
281
- ...firstTxFeePayload,
282
- proposalTxParams: proposalTxParamsBatch
283
- };
284
- if (clientId) bodyForSign.clientId = clientId;
285
- return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
310
+ buildBatchMeta: ({ index }) => args.steps[index].meta
311
+ });
286
312
  }
287
313
  async function buildSkyLockstakeStakePositionBatch(args) {
288
314
  if (args.chainId !== 1) throw new Error("Sky LockStake is only supported on Ethereum mainnet (chain id 1).");
@@ -521,7 +547,6 @@ async function buildSkyLockstakeStakePositionBatch(args) {
521
547
  })();
522
548
  return appendSerializedSkyBatch({
523
549
  steps,
524
- publicClient,
525
550
  executor,
526
551
  chainId: 1,
527
552
  rpcUrl: rpc,
@@ -529,9 +554,7 @@ async function buildSkyLockstakeStakePositionBatch(args) {
529
554
  useCustomGas: args.useCustomGas,
530
555
  customGasChainDetails: args.customGasChainDetails,
531
556
  purposePrefix,
532
- keyGen: args.keyGen,
533
- destinationChainID: "1"
534
- });
557
+ keyGen: args.keyGen});
535
558
  }
536
559
  async function buildSkyLockstakeDrawBatch(args) {
537
560
  if (args.chainId !== 1) throw new Error("Sky LockStake is only supported on Ethereum mainnet (chain id 1).");
@@ -589,7 +612,6 @@ async function buildSkyLockstakeDrawBatch(args) {
589
612
  })();
590
613
  return appendSerializedSkyBatch({
591
614
  steps,
592
- publicClient,
593
615
  executor,
594
616
  chainId: 1,
595
617
  rpcUrl: rpc,
@@ -597,9 +619,7 @@ async function buildSkyLockstakeDrawBatch(args) {
597
619
  useCustomGas: args.useCustomGas,
598
620
  customGasChainDetails: args.customGasChainDetails,
599
621
  purposePrefix,
600
- keyGen: args.keyGen,
601
- destinationChainID: "1"
602
- });
622
+ keyGen: args.keyGen});
603
623
  }
604
624
  async function buildSkyLockstakeGetRewardBatch(args) {
605
625
  if (args.chainId !== 1) throw new Error("Sky LockStake is only supported on Ethereum mainnet (chain id 1).");
@@ -668,7 +688,6 @@ async function buildSkyLockstakeGetRewardBatch(args) {
668
688
  })();
669
689
  const built = await appendSerializedSkyBatch({
670
690
  steps,
671
- publicClient,
672
691
  executor,
673
692
  chainId: 1,
674
693
  rpcUrl: rpc,
@@ -676,9 +695,7 @@ async function buildSkyLockstakeGetRewardBatch(args) {
676
695
  useCustomGas: args.useCustomGas,
677
696
  customGasChainDetails: args.customGasChainDetails,
678
697
  purposePrefix,
679
- keyGen: args.keyGen,
680
- destinationChainID: "1"
681
- });
698
+ keyGen: args.keyGen});
682
699
  return { ...built, rewardToken };
683
700
  }
684
701
  async function buildSkyLockstakeWipeBatch(args) {
@@ -825,7 +842,6 @@ async function buildSkyLockstakeWipeBatch(args) {
825
842
  })();
826
843
  return appendSerializedSkyBatch({
827
844
  steps,
828
- publicClient,
829
845
  executor,
830
846
  chainId: 1,
831
847
  rpcUrl: rpc,
@@ -833,9 +849,7 @@ async function buildSkyLockstakeWipeBatch(args) {
833
849
  useCustomGas: args.useCustomGas,
834
850
  customGasChainDetails: args.customGasChainDetails,
835
851
  purposePrefix,
836
- keyGen: args.keyGen,
837
- destinationChainID: "1"
838
- });
852
+ keyGen: args.keyGen});
839
853
  }
840
854
  async function buildSkyLockstakeCloseBatch(args) {
841
855
  if (args.chainId !== 1) throw new Error("Sky LockStake is only supported on Ethereum mainnet (chain id 1).");
@@ -847,7 +861,7 @@ async function buildSkyLockstakeCloseBatch(args) {
847
861
  nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
848
862
  rpcUrls: { default: { http: [rpc] } }
849
863
  });
850
- const publicClient = createPublicClient({ chain: ch, transport: http(rpc) });
864
+ createPublicClient({ chain: ch, transport: http(rpc) });
851
865
  const executor = getAddress(args.executorAddress);
852
866
  const engine = getAddress(SKY_LOCKSTAKE_ENGINE_MAINNET);
853
867
  const usds = getAddress(USDS_ETHEREUM_MAINNET);
@@ -925,7 +939,6 @@ async function buildSkyLockstakeCloseBatch(args) {
925
939
  })();
926
940
  return appendSerializedSkyBatch({
927
941
  steps,
928
- publicClient,
929
942
  executor,
930
943
  chainId: 1,
931
944
  rpcUrl: rpc,
@@ -933,9 +946,7 @@ async function buildSkyLockstakeCloseBatch(args) {
933
946
  useCustomGas: args.useCustomGas,
934
947
  customGasChainDetails: args.customGasChainDetails,
935
948
  purposePrefix,
936
- keyGen: args.keyGen,
937
- destinationChainID: "1"
938
- });
949
+ keyGen: args.keyGen});
939
950
  }
940
951
  var SKY_FRAGILE_ETH_ESTIMATE_GAS_BATCH_EVMS = /* @__PURE__ */ new Set([
941
952
  "sky_lockstake_engine_multicall_stake",
@@ -1064,7 +1075,6 @@ async function buildSkySusdsRedeemToUsdsBatch(args) {
1064
1075
  })();
1065
1076
  return appendSerializedSkyBatch({
1066
1077
  steps,
1067
- publicClient,
1068
1078
  executor,
1069
1079
  chainId: 1,
1070
1080
  rpcUrl: rpc,
@@ -1072,9 +1082,7 @@ async function buildSkySusdsRedeemToUsdsBatch(args) {
1072
1082
  useCustomGas: args.useCustomGas,
1073
1083
  customGasChainDetails: args.customGasChainDetails,
1074
1084
  purposePrefix,
1075
- keyGen: args.keyGen,
1076
- destinationChainID: "1"
1077
- });
1085
+ keyGen: args.keyGen});
1078
1086
  }
1079
1087
  async function buildSkySusdsDepositFromUsdsBatch(args) {
1080
1088
  if (args.chainId !== 1) throw new Error("Sky sUSDS deposit is only supported on Ethereum mainnet (chain id 1).");
@@ -1188,7 +1196,6 @@ async function buildSkySusdsDepositFromUsdsBatch(args) {
1188
1196
  })();
1189
1197
  return appendSerializedSkyBatch({
1190
1198
  steps,
1191
- publicClient,
1192
1199
  executor,
1193
1200
  chainId: 1,
1194
1201
  rpcUrl: rpc,
@@ -1196,9 +1203,215 @@ async function buildSkySusdsDepositFromUsdsBatch(args) {
1196
1203
  useCustomGas: args.useCustomGas,
1197
1204
  customGasChainDetails: args.customGasChainDetails,
1198
1205
  purposePrefix,
1199
- keyGen: args.keyGen,
1200
- destinationChainID: "1"
1206
+ keyGen: args.keyGen});
1207
+ }
1208
+ var RAY = 10n ** 27n;
1209
+ var engineAbi2 = parseAbi([
1210
+ "function ownerUrnsCount(address usr) view returns (uint256)",
1211
+ "function ownerUrns(address owner, uint256 index) view returns (address urn)",
1212
+ "function urnFarms(address urn) view returns (address farm)",
1213
+ "function ilk() view returns (bytes32)",
1214
+ "function vat() view returns (address)"
1215
+ ]);
1216
+ var vatAbi = parseAbi([
1217
+ "function urns(bytes32 ilk, address urn) view returns (uint256 ink, uint256 art)",
1218
+ "function ilks(bytes32 ilk) view returns (uint256 Art, uint256 rate, uint256 spot, uint256 line, uint256 dust)"
1219
+ ]);
1220
+ function skyClient(rpcUrl) {
1221
+ const rpc = rpcUrl.trim();
1222
+ const ch = defineChain({
1223
+ id: 1,
1224
+ name: "Ethereum",
1225
+ nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
1226
+ rpcUrls: { default: { http: [rpc] } }
1227
+ });
1228
+ return createPublicClient({ chain: ch, transport: http(rpc) });
1229
+ }
1230
+ function skyUsdsDebtWeiFromUrnArt(art, rate) {
1231
+ if (art === 0n || rate === 0n) return 0n;
1232
+ return (art * rate + RAY - 1n) / RAY;
1233
+ }
1234
+ async function loadSkyLockstakePositions(args) {
1235
+ const client = skyClient(args.rpcUrl);
1236
+ const engine = getAddress(SKY_LOCKSTAKE_ENGINE_MAINNET);
1237
+ const ilk = await client.readContract({
1238
+ address: engine,
1239
+ abi: engineAbi2,
1240
+ functionName: "ilk"
1241
+ });
1242
+ const vat = await client.readContract({
1243
+ address: engine,
1244
+ abi: engineAbi2,
1245
+ functionName: "vat"
1246
+ });
1247
+ const count = await client.readContract({
1248
+ address: engine,
1249
+ abi: engineAbi2,
1250
+ functionName: "ownerUrnsCount",
1251
+ args: [args.owner]
1252
+ });
1253
+ const n = Number(count);
1254
+ if (!Number.isFinite(n) || n <= 0) return [];
1255
+ const ilkInfo = await client.readContract({
1256
+ address: vat,
1257
+ abi: vatAbi,
1258
+ functionName: "ilks",
1259
+ args: [ilk]
1260
+ });
1261
+ const rate = ilkInfo[1];
1262
+ const rows = [];
1263
+ for (let index = 0; index < n; index++) {
1264
+ const urn = await client.readContract({
1265
+ address: engine,
1266
+ abi: engineAbi2,
1267
+ functionName: "ownerUrns",
1268
+ args: [args.owner, BigInt(index)]
1269
+ });
1270
+ if (!urn || urn === "0x0000000000000000000000000000000000000000") continue;
1271
+ const u = await client.readContract({
1272
+ address: vat,
1273
+ abi: vatAbi,
1274
+ functionName: "urns",
1275
+ args: [ilk, urn]
1276
+ });
1277
+ const inkWei = u[0];
1278
+ const art = u[1];
1279
+ const debtUsdsWei = skyUsdsDebtWeiFromUrnArt(art, rate);
1280
+ const farm = await client.readContract({
1281
+ address: engine,
1282
+ abi: engineAbi2,
1283
+ functionName: "urnFarms",
1284
+ args: [urn]
1285
+ });
1286
+ const skyHuman = Number(formatUnits(inkWei, SKY_TOKEN_DECIMALS));
1287
+ const debtHuman = Number(formatUnits(debtUsdsWei, USDS_DECIMALS));
1288
+ let borrowLimitUsdApprox = null;
1289
+ if (args.skyUsd != null && Number.isFinite(args.skyUsd) && args.skyUsd > 0) {
1290
+ const collateralUsd = skyHuman * args.skyUsd;
1291
+ const maxDebtUsd = collateralUsd * SKY_LOCKSTAKE_UI_COLLATERAL_FACTOR;
1292
+ borrowLimitUsdApprox = Math.max(0, maxDebtUsd - debtHuman);
1293
+ }
1294
+ rows.push({
1295
+ index,
1296
+ urn,
1297
+ inkWei,
1298
+ art,
1299
+ debtUsdsWei,
1300
+ farm,
1301
+ skyLocked: formatUnits(inkWei, SKY_TOKEN_DECIMALS),
1302
+ debtUsds: formatUnits(debtUsdsWei, USDS_DECIMALS),
1303
+ borrowLimitUsdApprox,
1304
+ skyPriceUsd: args.skyUsd
1305
+ });
1306
+ }
1307
+ return rows;
1308
+ }
1309
+ var farmRewardsTokenAbi = parseAbi(["function rewardsToken() view returns (address)"]);
1310
+ async function readSkyLockstakeFarmRewardsToken(args) {
1311
+ const client = skyClient(args.rpcUrl);
1312
+ const farm = getAddress(args.farm);
1313
+ const zero = "0x0000000000000000000000000000000000000000";
1314
+ if (farm.toLowerCase() === zero.toLowerCase()) {
1315
+ throw new Error("Farm address is zero.");
1316
+ }
1317
+ const tok = await client.readContract({
1318
+ address: farm,
1319
+ abi: farmRewardsTokenAbi,
1320
+ functionName: "rewardsToken"
1321
+ });
1322
+ return getAddress(tok);
1323
+ }
1324
+ var vaultAbi = parseAbi([
1325
+ "function balanceOf(address account) view returns (uint256)",
1326
+ "function decimals() view returns (uint8)",
1327
+ "function previewRedeem(uint256 shares) view returns (uint256 assets)"
1328
+ ]);
1329
+ async function readSusdsVaultShareBalanceWei(args) {
1330
+ const rpc = args.rpcUrl.trim();
1331
+ const ch = defineChain({
1332
+ id: 1,
1333
+ name: "Ethereum",
1334
+ nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
1335
+ rpcUrls: { default: { http: [rpc] } }
1336
+ });
1337
+ const client = createPublicClient({ chain: ch, transport: http(rpc) });
1338
+ const vault = getAddress(SUSDS_VAULT_ERC4626_MAINNET);
1339
+ return client.readContract({
1340
+ address: vault,
1341
+ abi: vaultAbi,
1342
+ functionName: "balanceOf",
1343
+ args: [args.owner]
1344
+ });
1345
+ }
1346
+ async function readSusdsVaultDecimals(args) {
1347
+ const rpc = args.rpcUrl.trim();
1348
+ const ch = defineChain({
1349
+ id: 1,
1350
+ name: "Ethereum",
1351
+ nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
1352
+ rpcUrls: { default: { http: [rpc] } }
1353
+ });
1354
+ const client = createPublicClient({ chain: ch, transport: http(rpc) });
1355
+ const vault = getAddress(SUSDS_VAULT_ERC4626_MAINNET);
1356
+ const d = await client.readContract({
1357
+ address: vault,
1358
+ abi: vaultAbi,
1359
+ functionName: "decimals"
1360
+ });
1361
+ return Number(d);
1362
+ }
1363
+ async function readSusdsPreviewRedeemAssetsWei(args) {
1364
+ if (args.sharesWei <= 0n) return 0n;
1365
+ const rpc = args.rpcUrl.trim();
1366
+ const ch = defineChain({
1367
+ id: 1,
1368
+ name: "Ethereum",
1369
+ nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
1370
+ rpcUrls: { default: { http: [rpc] } }
1201
1371
  });
1372
+ const client = createPublicClient({ chain: ch, transport: http(rpc) });
1373
+ const vault = getAddress(SUSDS_VAULT_ERC4626_MAINNET);
1374
+ return client.readContract({
1375
+ address: vault,
1376
+ abi: vaultAbi,
1377
+ functionName: "previewRedeem",
1378
+ args: [args.sharesWei]
1379
+ });
1380
+ }
1381
+ function formatSusdsSharesHuman(sharesWei, decimals) {
1382
+ return formatUnits(sharesWei, decimals);
1383
+ }
1384
+
1385
+ // src/core/defiProxy.ts
1386
+ var coingeckoProxyUrl;
1387
+ function getCoingeckoProxyUrl() {
1388
+ return coingeckoProxyUrl;
1389
+ }
1390
+
1391
+ // src/protocols/evm/sky/usdPrice.ts
1392
+ async function fetchSkyUsdFromCoinGecko() {
1393
+ try {
1394
+ const addr = getAddress(SKY_ETHEREUM_MAINNET).toLowerCase();
1395
+ const url = "https://api.coingecko.com/api/v3/simple/token_price/ethereum?contract_addresses=" + encodeURIComponent(addr) + "&vs_currencies=usd";
1396
+ const proxy = getCoingeckoProxyUrl();
1397
+ const res = proxy ? await fetch(proxy, {
1398
+ method: "POST",
1399
+ headers: { "content-type": "application/json" },
1400
+ body: JSON.stringify({ platform: "ethereum", contractAddress: addr })
1401
+ }) : await fetch(url, { cache: "no-store" });
1402
+ if (!res.ok) return null;
1403
+ const raw = await res.json();
1404
+ const row = raw[addr];
1405
+ const n = row?.usd;
1406
+ return typeof n === "number" && Number.isFinite(n) && n > 0 ? n : null;
1407
+ } catch {
1408
+ return null;
1409
+ }
1410
+ }
1411
+
1412
+ // src/protocols/evm/sky/loadLockstakeSupportedChainIds.ts
1413
+ function loadSkyLockstakeSupportedChainIds() {
1414
+ return /* @__PURE__ */ new Set([1]);
1202
1415
  }
1203
1416
 
1204
1417
  // src/protocols/evm/sky/index.ts
@@ -1224,6 +1437,6 @@ var skyProtocolModule = {
1224
1437
  };
1225
1438
  registerProtocolModule(skyProtocolModule);
1226
1439
 
1227
- export { SKY_ETHEREUM_MAINNET, SKY_ETHEREUM_MAINNET_CHAIN_ID, SKY_LOCKSTAKE_DEFAULT_FARM_MAINNET, SKY_LOCKSTAKE_DEFAULT_FARM_REF, SKY_LOCKSTAKE_ENGINE_MAINNET, SKY_LOCKSTAKE_MULTICALL_FALLBACK_GAS, SKY_LOCKSTAKE_UI_COLLATERAL_FACTOR, SKY_LS_SKY_ERC20_MAINNET, SKY_PROTOCOL_ID, SKY_TOKEN_DECIMALS, SUSDS_VAULT_ERC4626_MAINNET, USDS_DECIMALS, USDS_ETHEREUM_MAINNET, appendSerializedSkyBatch, buildSkyLockstakeCloseBatch, buildSkyLockstakeDrawBatch, buildSkyLockstakeGetRewardBatch, buildSkyLockstakeStakePositionBatch, buildSkyLockstakeWipeBatch, buildSkySusdsDepositFromUsdsBatch, buildSkySusdsRedeemToUsdsBatch, isSkyLockstakeIsolationEstimateGasFragileBatchStep, resolveSkyLockstakeBatchStepGasFromSignRequest, skyProtocolModule };
1440
+ export { SKY_ETHEREUM_MAINNET, SKY_ETHEREUM_MAINNET_CHAIN_ID, SKY_LOCKSTAKE_DEFAULT_FARM_MAINNET, SKY_LOCKSTAKE_DEFAULT_FARM_REF, SKY_LOCKSTAKE_ENGINE_MAINNET, SKY_LOCKSTAKE_MULTICALL_FALLBACK_GAS, SKY_LOCKSTAKE_UI_COLLATERAL_FACTOR, SKY_LS_SKY_ERC20_MAINNET, SKY_PROTOCOL_ID, SKY_TOKEN_DECIMALS, SUSDS_VAULT_ERC4626_MAINNET, USDS_DECIMALS, USDS_ETHEREUM_MAINNET, appendSerializedSkyBatch, buildSkyLockstakeCloseBatch, buildSkyLockstakeDrawBatch, buildSkyLockstakeGetRewardBatch, buildSkyLockstakeStakePositionBatch, buildSkyLockstakeWipeBatch, buildSkySusdsDepositFromUsdsBatch, buildSkySusdsRedeemToUsdsBatch, fetchSkyUsdFromCoinGecko, formatSusdsSharesHuman, isSkyLockstakeIsolationEstimateGasFragileBatchStep, loadSkyLockstakePositions, loadSkyLockstakeSupportedChainIds, readSkyLockstakeFarmRewardsToken, readSusdsPreviewRedeemAssetsWei, readSusdsVaultDecimals, readSusdsVaultShareBalanceWei, resolveSkyLockstakeBatchStepGasFromSignRequest, skyProtocolModule, skyUsdsDebtWeiFromUrnArt };
1228
1441
  //# sourceMappingURL=index.js.map
1229
1442
  //# sourceMappingURL=index.js.map