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