@continuumdao/ctm-mpc-defi 0.2.20 → 0.2.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/catalog.cjs +118 -37
- package/dist/agent/catalog.cjs.map +1 -1
- package/dist/agent/catalog.d.ts +310 -97
- package/dist/agent/catalog.js +117 -38
- package/dist/agent/catalog.js.map +1 -1
- package/dist/agent/skills/uniswap-v4/SKILL.md +58 -0
- package/dist/chains/evm/index.cjs +5 -1
- package/dist/chains/evm/index.cjs.map +1 -1
- package/dist/chains/evm/index.d.ts +4 -4
- package/dist/chains/evm/index.js +5 -1
- package/dist/chains/evm/index.js.map +1 -1
- package/dist/chains/near/index.d.ts +1 -1
- package/dist/chains/solana/index.d.ts +1 -1
- package/dist/core/index.cjs +25 -0
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.ts +12 -5
- package/dist/core/index.js +23 -1
- package/dist/core/index.js.map +1 -1
- package/dist/{envelope-CpBUh9eP.d.ts → envelope-C_bfuKab.d.ts} +3 -1
- package/dist/index.cjs +27 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +25 -2
- package/dist/index.js.map +1 -1
- package/dist/protocols/evm/aave-v4/index.cjs +5 -1
- package/dist/protocols/evm/aave-v4/index.cjs.map +1 -1
- package/dist/protocols/evm/aave-v4/index.d.ts +1 -1
- package/dist/protocols/evm/aave-v4/index.js +5 -1
- package/dist/protocols/evm/aave-v4/index.js.map +1 -1
- package/dist/protocols/evm/circle-cctp/index.cjs +5 -1
- package/dist/protocols/evm/circle-cctp/index.cjs.map +1 -1
- package/dist/protocols/evm/circle-cctp/index.d.ts +2 -2
- package/dist/protocols/evm/circle-cctp/index.js +5 -1
- package/dist/protocols/evm/circle-cctp/index.js.map +1 -1
- package/dist/protocols/evm/curve-dao/index.cjs +5 -1
- package/dist/protocols/evm/curve-dao/index.cjs.map +1 -1
- package/dist/protocols/evm/curve-dao/index.d.ts +2 -2
- package/dist/protocols/evm/curve-dao/index.js +5 -1
- package/dist/protocols/evm/curve-dao/index.js.map +1 -1
- package/dist/protocols/evm/ethena/index.cjs +5 -1
- package/dist/protocols/evm/ethena/index.cjs.map +1 -1
- package/dist/protocols/evm/ethena/index.d.ts +1 -1
- package/dist/protocols/evm/ethena/index.js +5 -1
- package/dist/protocols/evm/ethena/index.js.map +1 -1
- package/dist/protocols/evm/euler-v2/index.cjs +5 -1
- package/dist/protocols/evm/euler-v2/index.cjs.map +1 -1
- package/dist/protocols/evm/euler-v2/index.d.ts +1 -1
- package/dist/protocols/evm/euler-v2/index.js +5 -1
- package/dist/protocols/evm/euler-v2/index.js.map +1 -1
- package/dist/protocols/evm/gmx/index.cjs +5 -1
- package/dist/protocols/evm/gmx/index.cjs.map +1 -1
- package/dist/protocols/evm/gmx/index.d.ts +2 -2
- package/dist/protocols/evm/gmx/index.js +5 -1
- package/dist/protocols/evm/gmx/index.js.map +1 -1
- package/dist/protocols/evm/hyperliquid/index.cjs +6 -1
- package/dist/protocols/evm/hyperliquid/index.cjs.map +1 -1
- package/dist/protocols/evm/hyperliquid/index.d.ts +2 -2
- package/dist/protocols/evm/hyperliquid/index.js +6 -1
- package/dist/protocols/evm/hyperliquid/index.js.map +1 -1
- package/dist/protocols/evm/lido/index.cjs +5 -1
- package/dist/protocols/evm/lido/index.cjs.map +1 -1
- package/dist/protocols/evm/lido/index.d.ts +1 -1
- package/dist/protocols/evm/lido/index.js +5 -1
- package/dist/protocols/evm/lido/index.js.map +1 -1
- package/dist/protocols/evm/maple/index.cjs +5 -1
- package/dist/protocols/evm/maple/index.cjs.map +1 -1
- package/dist/protocols/evm/maple/index.d.ts +1 -1
- package/dist/protocols/evm/maple/index.js +5 -1
- package/dist/protocols/evm/maple/index.js.map +1 -1
- package/dist/protocols/evm/morpho/index.cjs +5 -1
- package/dist/protocols/evm/morpho/index.cjs.map +1 -1
- package/dist/protocols/evm/morpho/index.d.ts +1 -1
- package/dist/protocols/evm/morpho/index.js +5 -1
- package/dist/protocols/evm/morpho/index.js.map +1 -1
- package/dist/protocols/evm/permit2/index.cjs +4 -0
- package/dist/protocols/evm/permit2/index.cjs.map +1 -1
- package/dist/protocols/evm/permit2/index.d.ts +1 -1
- package/dist/protocols/evm/permit2/index.js +4 -0
- package/dist/protocols/evm/permit2/index.js.map +1 -1
- package/dist/protocols/evm/sky/index.cjs +5 -1
- package/dist/protocols/evm/sky/index.cjs.map +1 -1
- package/dist/protocols/evm/sky/index.d.ts +1 -1
- package/dist/protocols/evm/sky/index.js +5 -1
- package/dist/protocols/evm/sky/index.js.map +1 -1
- package/dist/protocols/evm/uniswap-v4/index.cjs +684 -1
- package/dist/protocols/evm/uniswap-v4/index.cjs.map +1 -1
- package/dist/protocols/evm/uniswap-v4/index.d.ts +180 -3
- package/dist/protocols/evm/uniswap-v4/index.js +662 -2
- package/dist/protocols/evm/uniswap-v4/index.js.map +1 -1
- package/dist/{registry-Bv5o37_w.d.ts → registry-DxDSPQ-p.d.ts} +1 -1
- package/dist/{types-BfjWdw1j.d.ts → types-PZrvtjv8.d.ts} +2 -0
- package/dist/{types-DUeNJLr9.d.ts → types-RZWOTm8c.d.ts} +1 -1
- package/package.json +2 -2
|
@@ -197,3 +197,61 @@ Agents **do not** scan blockchain logs for positions. Positions must appear as *
|
|
|
197
197
|
- Do **not** pass `uniswapApiKey` in tool calls — the MCP server injects it.
|
|
198
198
|
- Native ETH always uses `tokenIn: 0x0` for Uniswap (not `0xeeee` — that is Curve’s placeholder).
|
|
199
199
|
- `get_defi_protocol_skill` (this file) is the canonical workflow reference for agents.
|
|
200
|
+
|
|
201
|
+
## Pool OHLCV (charts / analysis)
|
|
202
|
+
|
|
203
|
+
Read-only pool candle history via **`ctm_uniswap_v4_fetch_ohlcv`**. Does **not** use `UNISWAP_API_KEY`. Optional **`THE_GRAPH_API_KEY`** in Node → AI Agent → Variables improves The Graph gateway rate limits.
|
|
204
|
+
|
|
205
|
+
### OHLCV chain coverage (subgraph limit)
|
|
206
|
+
|
|
207
|
+
OHLCV is **only** available on chains with a pinned public Uniswap V4 subgraph on The Graph. **`get_defi_protocol_fetch_options`** returns `ohlcvSupportedChainIds` for this subset.
|
|
208
|
+
|
|
209
|
+
| chainId | Network |
|
|
210
|
+
|---------|---------|
|
|
211
|
+
| 1 | Ethereum |
|
|
212
|
+
| 10 | Optimism |
|
|
213
|
+
| 56 | BSC |
|
|
214
|
+
| 130 | Unichain |
|
|
215
|
+
| 137 | Polygon |
|
|
216
|
+
| 8453 | Base |
|
|
217
|
+
| 81457 | Blast |
|
|
218
|
+
| 42161 | Arbitrum |
|
|
219
|
+
| 43114 | Avalanche |
|
|
220
|
+
|
|
221
|
+
**Swap / LP / quote tools** work on all `supportedChainIds` (~20+ EVM chains). On chains **without** a pinned subgraph (e.g. zkSync `324`, Celo `42220`, World Chain `480`, Linea `59144`, Zora `7777777`), use **CoinGecko/CoinMarketCap time series** via `get_defi_protocol_fetch_options` — do not call `fetch_ohlcv`.
|
|
222
|
+
|
|
223
|
+
All OHLCV tiers (native subgraph, subgraph aggregation, sub-hour swap bucketing) require the same subgraph; there is no RPC-only fallback.
|
|
224
|
+
|
|
225
|
+
### Three-tier interval routing
|
|
226
|
+
|
|
227
|
+
| Interval | Source |
|
|
228
|
+
|----------|--------|
|
|
229
|
+
| `1h`, `1d` | Subgraph `PoolHourData` / `PoolDayData` (native) |
|
|
230
|
+
| Multiples of 1h or 1d (e.g. `4h`, `1w`) | Subgraph bars aggregated client-side |
|
|
231
|
+
| Sub-hour (`15m`, `5m`, …) | Raw `Swap` events bucketed into candles |
|
|
232
|
+
|
|
233
|
+
### Chart / analysis workflow
|
|
234
|
+
|
|
235
|
+
1. `load_defi_protocol({ protocolId: "uniswap-v4" })`
|
|
236
|
+
2. `get_defi_protocol_fetch_options` — pick `chainId` from **`ohlcvSupportedChainIds`** (not the full swap/LP list)
|
|
237
|
+
3. `ctm_uniswap_v4_list_lp_pools` — pick `poolPreset` or copy `poolReference`
|
|
238
|
+
4. `ctm_uniswap_v4_fetch_ohlcv({ chainId, poolPreset, interval, lookbackDays })`
|
|
239
|
+
5. **Analysis:** `continuum__analyze_*` with full fetch JSON as `toolResult`
|
|
240
|
+
6. **Chart:** `continuum__prepare_chart_from_rows` with full fetch JSON as `toolResult` (same agent turn)
|
|
241
|
+
|
|
242
|
+
### `ctm_uniswap_v4_fetch_ohlcv`
|
|
243
|
+
|
|
244
|
+
| Field | Required | Notes |
|
|
245
|
+
|-------|----------|-------|
|
|
246
|
+
| `chainId` | yes | Must be in `ohlcvSupportedChainIds` from fetch options |
|
|
247
|
+
| `poolPreset` | one of pool fields | From `list_lp_pools` |
|
|
248
|
+
| `poolReference` | one of pool fields | bytes32 pool id |
|
|
249
|
+
| `existingPool` | one of pool fields | token addresses + fee/tickSpacing or poolReference |
|
|
250
|
+
| `interval` | no | Default `1h`. See tier table above |
|
|
251
|
+
| `lookbackDays` | no | Default 7 when no explicit time range |
|
|
252
|
+
| `lookbackHours` / `startTimeMs` / `endTimeMs` | no | Alternative window bounds |
|
|
253
|
+
| `quoteToken` | no | Default `token0` (token0 per token1). Use `token1` to invert |
|
|
254
|
+
|
|
255
|
+
**Output:** `{ symbol, timeframe, chainId, poolReference, dataSource, candles, … }` — pass the **full object** to chart/analysis tools.
|
|
256
|
+
|
|
257
|
+
**Price note:** Default OHLC is **token0 priced in token1**, not USD. For USD-ish charts use stablecoin-quoted pools (e.g. ETH/USDC) or CoinGecko/CMC time series via `get_defi_protocol_fetch_options`.
|
|
@@ -77,6 +77,9 @@ function finalizeMultisign(input) {
|
|
|
77
77
|
bodyForSign.value = valueWei.toString();
|
|
78
78
|
}
|
|
79
79
|
if (clientId) bodyForSign.clientId = clientId;
|
|
80
|
+
if (input.expiryDate != null && input.expiryDate > 0) {
|
|
81
|
+
bodyForSign.expiryDate = Math.floor(input.expiryDate);
|
|
82
|
+
}
|
|
80
83
|
return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
|
|
81
84
|
}
|
|
82
85
|
function routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimit) {
|
|
@@ -240,7 +243,8 @@ async function buildEvmMultisignBatch(args) {
|
|
|
240
243
|
destinationChainID: String(chainId),
|
|
241
244
|
destinationAddress: args.destinationAddress ?? steps[0].to,
|
|
242
245
|
legs,
|
|
243
|
-
extraJSON: Object.keys(extraJSON).length > 0 ? extraJSON : void 0
|
|
246
|
+
extraJSON: Object.keys(extraJSON).length > 0 ? extraJSON : void 0,
|
|
247
|
+
expiryDate: context.expiryDate
|
|
244
248
|
});
|
|
245
249
|
const pv = args.payableValueWei;
|
|
246
250
|
if (pv != null && pv > 0n) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/chains/evm/types.ts","../../../src/core/purpose.ts","../../../src/core/envelope.ts","../../../src/chains/evm/routerSwapGas.ts","../../../src/chains/evm/buildBatch.ts","../../../src/chains/evm/chainIdParse.ts","../../../src/chains/evm/normalizeAmount.ts","../../../src/chains/evm/erc20Approve.ts","../../../src/chains/evm/coingecko.ts"],"names":["getAddress","zeroAddress","getClientIdFromKeyGenResult","gasLimitFromEstimateAndChainConfig","defineChain","createPublicClient","http","fetchChainFeeParams","parseGwei","gweiToDecimalString","serializeTransaction","proposalTxParamsToFeeSnapshot","alignEip1559FeesWithLatestBase","keccak256","parseUnits","formatUnits","parseAbi","encodeFunctionData"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { EvmTokenKind, MultisignCommonArgs } from '../../core/types.js'\nimport { getAddress, zeroAddress, type Address } from 'viem'\n\nexport type EvmChainDetail = {\n legacy?: boolean\n gasLimit?: number\n gasMultiplier?: number\n gasPrice?: number\n baseFee?: number\n priorityFee?: number\n baseFeeMultiplier?: number\n}\n\nexport interface EvmProtocolContext extends MultisignCommonArgs {\n chainCategory: 'evm'\n chainId: number\n rpcUrl: string\n executorAddress: Address\n chainDetail: EvmChainDetail\n useCustomGas: boolean\n customGasChainDetails?: Record<string, unknown> | null\n}\n\nexport type EvmTxStep = {\n to: Address\n data: `0x${string}`\n value: bigint\n /** Fallback when estimateGas reverts */\n fallbackGas?: bigint\n /** When set, use routerSwapGasLimitFromEstimate instead of plain estimate */\n routerSwap?: boolean\n}\n\nexport function isEvmNativeToken(address: string): boolean {\n try {\n return getAddress(address as `0x${string}`) === zeroAddress\n } catch {\n return address.toLowerCase() === zeroAddress\n }\n}\n\nexport function matchEvmTokenKind(\n kind: EvmTokenKind,\n address: string,\n): boolean {\n if (kind === 'native') return isEvmNativeToken(address)\n if (kind === 'erc20' || kind === 'ctmerc20' || kind === 'ctmrwa1') {\n return !isEvmNativeToken(address)\n }\n return true\n}\n","/** Merge user purpose text with an optional batch / protocol suffix. */\nexport function mergePurposeText(purposeText: string | undefined, purposeSuffix?: string): string {\n const t = (purposeText ?? '').trim()\n const suffix = (purposeSuffix ?? '').trim()\n if (!suffix) return t\n return t ? `${t}\\n\\n${suffix}` : suffix\n}\n","import type { ChainCategory, MultisignBuildResult, KeyGenSubset } from './types.js'\nimport { getClientIdFromKeyGenResult } from '@continuumdao/continuum-node-sdk'\nimport { mergePurposeText } from './purpose.js'\n\nexport interface MultisignLeg {\n msgHash: string\n msgRaw: string\n destinationAddress: string\n signatureText: string\n audit: Record<string, unknown>\n feeSnapshot: Record<string, unknown>\n proposalTxParams?: Record<string, unknown>\n /** Payable value wei string for first leg only when relevant */\n valueWei?: bigint\n}\n\nexport interface ChainCategoryBuildInput {\n keyGen: KeyGenSubset\n purposeText: string\n purposeSuffix?: string\n destinationChainID: string\n legs: MultisignLeg[]\n extraJSON?: Record<string, unknown>\n /** Top-level destination address (first leg destination if omitted) */\n destinationAddress?: string\n}\n\nexport interface ChainCategoryModule {\n category: ChainCategory\n finalizeMultisign(input: ChainCategoryBuildInput): MultisignBuildResult\n}\n\n/**\n * Assemble mpc-auth `bodyForSign` from category-built legs.\n * Supports single-tx and batch (messageHashes / messageRawBatch / proposalTxParams).\n */\nexport function finalizeMultisign(input: ChainCategoryBuildInput): MultisignBuildResult {\n const { keyGen, destinationChainID, legs } = input\n if (legs.length === 0) {\n throw new Error('finalizeMultisign requires at least one leg')\n }\n\n const ph = (keyGen.pubkeyhex ?? '').trim()\n if (!ph) throw new Error('keyGen pubKey (pubkeyhex) is required')\n\n const keyList = keyGen.keylist ?? []\n const clientId = getClientIdFromKeyGenResult(keyGen)\n const first = legs[0]!\n\n const messageHashes = legs.map((l) => l.msgHash)\n const messageRawBatch = legs.map((l) => l.msgRaw)\n const batchMeta = legs.map((l) => ({\n destinationAddress: l.destinationAddress,\n signatureText: l.signatureText,\n ...l.audit,\n }))\n\n const proposalTxParams = legs\n .map((l) => l.proposalTxParams)\n .filter((p): p is Record<string, unknown> => p != null && typeof p === 'object')\n\n const extraPayload: Record<string, unknown> = {\n batchMeta,\n ...(input.extraJSON ?? {}),\n }\n const extraJSON = JSON.stringify(extraPayload, (_, v) => (typeof v === 'bigint' ? v.toString() : v))\n\n const bodyForSign: Record<string, unknown> = {\n keyList,\n pubKey: ph,\n msgHash: messageHashes[0],\n msgRaw: first.msgRaw,\n destinationChainID,\n destinationAddress: input.destinationAddress ?? first.destinationAddress,\n extraJSON,\n signatureText: first.signatureText,\n purpose: mergePurposeText(input.purposeText, input.purposeSuffix),\n ...first.feeSnapshot,\n }\n\n if (legs.length > 1) {\n bodyForSign.messageHashes = messageHashes\n bodyForSign.messageRawBatch = messageRawBatch\n }\n\n if (proposalTxParams.length > 0) {\n bodyForSign.proposalTxParams = proposalTxParams\n }\n\n const valueWei = first.valueWei\n if (valueWei != null && valueWei > 0n) {\n bodyForSign.value = valueWei.toString()\n }\n\n if (clientId) bodyForSign.clientId = clientId\n\n return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) }\n}\n\nexport const coreChainCategoryModule: ChainCategoryModule = {\n category: 'evm',\n finalizeMultisign,\n}\n","import { gasLimitFromEstimateAndChainConfig } from '@continuumdao/continuum-node-sdk'\n\n/** Curve router swap gas: chain cap when set, else 12/10 estimate bump. */\nexport function routerSwapGasLimitFromEstimate(\n estimatedGas: bigint,\n chainGasLimit?: number | null,\n): bigint {\n if (chainGasLimit != null && Number.isFinite(chainGasLimit) && chainGasLimit > 0) {\n return gasLimitFromEstimateAndChainConfig(estimatedGas, chainGasLimit)\n }\n return (estimatedGas * 12n + 9n) / 10n\n}\n","import {\n keccak256,\n createPublicClient,\n defineChain,\n http,\n serializeTransaction,\n getAddress,\n parseGwei,\n type Address,\n type PublicClient,\n} from 'viem'\nimport type { MultisignBuildResult } from '../../core/types.js'\nimport { finalizeMultisign, type MultisignLeg } from '../../core/envelope.js'\nimport type { KeyGenSubset } from '../../core/types.js'\nimport {\n fetchChainFeeParams,\n alignEip1559FeesWithLatestBase,\n gweiToDecimalString,\n gasLimitFromEstimateAndChainConfig,\n proposalTxParamsToFeeSnapshot,\n type ProposalTxParams,\n} from '@continuumdao/continuum-node-sdk'\nimport { routerSwapGasLimitFromEstimate } from './routerSwapGas.js'\nimport type { EvmProtocolContext, EvmTxStep } from './types.js'\n\nexport type EvmBatchMetaBuilder = (args: {\n step: EvmTxStep\n index: number\n gasLimit: bigint\n}) => Record<string, unknown>\n\nexport type EvmBuildBatchArgs = {\n context: EvmProtocolContext\n steps: EvmTxStep[]\n purposeSuffix?: string\n buildBatchMeta: EvmBatchMetaBuilder\n /** First leg msgRaw without 0x prefix; defaults to first step calldata */\n firstMsgRawNo0x?: string\n destinationAddress?: Address\n /** Top-level `value` on bodyForSign when the payable amount is not on the first leg */\n payableValueWei?: bigint\n resolveGasLimit?: (args: {\n step: EvmTxStep\n index: number\n estimatedGas: bigint\n publicClient: PublicClient\n }) => Promise<bigint> | bigint\n /** Override default `estimateGas` (e.g. trade-API gas, skip post-approve deposit estimate). */\n estimateGasForStep?: (args: {\n step: EvmTxStep\n index: number\n publicClient: PublicClient\n executor: Address\n }) => Promise<bigint> | bigint\n}\n\n/**\n * Build unsigned EVM txs, estimate gas, serialize, hash — then assemble mpc-auth body via core envelope.\n */\nexport async function buildEvmMultisignBatch(args: EvmBuildBatchArgs): Promise<MultisignBuildResult> {\n const { context, steps } = args\n const {\n chainId,\n rpcUrl,\n executorAddress,\n chainDetail,\n useCustomGas,\n customGasChainDetails,\n keyGen,\n purposeText,\n } = context\n\n if (steps.length === 0) throw new Error('buildEvmMultisignBatch requires at least one step')\n\n const ch = defineChain({\n id: chainId,\n name: 'Destination',\n nativeCurrency: { decimals: 18, name: 'Ether', symbol: 'ETH' },\n rpcUrls: { default: { http: [rpcUrl] } },\n })\n const publicClient = createPublicClient({ chain: ch, transport: http(rpcUrl) })\n\n const feeParams = await fetchChainFeeParams(rpcUrl, chainId)\n const legacy = Boolean(chainDetail?.legacy) || !feeParams.isEip1559\n const latestBaseFeeWei = !legacy\n ? ((await publicClient.getBlock({ blockTag: 'latest' })).baseFeePerGas ?? 0n)\n : 0n\n\n const gasLimitConfig =\n useCustomGas && chainDetail?.gasLimit != null ? Number(chainDetail.gasLimit) : undefined\n const chainGasLimitRouter =\n chainDetail?.gasLimit != null &&\n Number.isFinite(Number(chainDetail.gasLimit)) &&\n Number(chainDetail.gasLimit) > 0\n ? Number(chainDetail.gasLimit)\n : undefined\n const gasFeeMultiplier =\n useCustomGas && chainDetail?.gasMultiplier != null ? Number(chainDetail.gasMultiplier) : undefined\n\n const executor = getAddress(executorAddress)\n const baseNonce = await publicClient.getTransactionCount({ address: executor, blockTag: 'pending' })\n\n const legs: MultisignLeg[] = []\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]!\n const currentNonce = baseNonce + i\n\n let estimatedGas: bigint\n if (args.estimateGasForStep) {\n estimatedGas = await args.estimateGasForStep({ step, index: i, publicClient, executor })\n } else {\n try {\n estimatedGas = await publicClient.estimateGas({\n to: step.to,\n data: step.data,\n value: step.value,\n account: executor,\n })\n } catch {\n estimatedGas = step.fallbackGas ?? 100_000n\n }\n }\n\n let gasLimitI: bigint\n if (args.resolveGasLimit) {\n gasLimitI = await args.resolveGasLimit({ step, index: i, estimatedGas, publicClient })\n } else if (step.routerSwap) {\n gasLimitI = routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimitRouter)\n } else {\n gasLimitI = useCustomGas\n ? gasLimitFromEstimateAndChainConfig(estimatedGas, gasLimitConfig)\n : estimatedGas\n }\n\n let proposalTxParams: ProposalTxParams\n let feeSnapshot: Record<string, unknown>\n let serialized: `0x${string}`\n\n if (legacy) {\n let gasPriceWei = await publicClient.getGasPrice()\n if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {\n gasPriceWei = (gasPriceWei * BigInt(100 + gasFeeMultiplier)) / 100n\n }\n if (useCustomGas && chainDetail?.gasPrice != null && chainDetail.gasPrice > 0) {\n const configured = parseGwei(gweiToDecimalString(Number(chainDetail.gasPrice)))\n if (configured > gasPriceWei) gasPriceWei = configured\n }\n serialized = serializeTransaction({\n type: 'legacy',\n to: step.to,\n data: step.data,\n value: step.value,\n gas: gasLimitI,\n gasPrice: gasPriceWei,\n nonce: currentNonce,\n chainId,\n })\n proposalTxParams = {\n nonce: currentNonce,\n gasLimit: gasLimitI.toString(),\n txType: 'legacy',\n gasPrice: gasPriceWei.toString(),\n }\n feeSnapshot = proposalTxParamsToFeeSnapshot(proposalTxParams)\n } else {\n const fetchedBase = feeParams.baseFeeGwei ?? 0\n const fetchedPriority = feeParams.priorityFeeGwei ?? 0\n const configuredBase =\n useCustomGas && chainDetail?.baseFee != null ? Number(chainDetail.baseFee) : 0\n const configuredPriority =\n useCustomGas && chainDetail?.priorityFee != null ? Number(chainDetail.priorityFee) : 0\n const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase)\n const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority)\n const baseFeeMultiplierPct =\n useCustomGas && chainDetail?.baseFeeMultiplier != null\n ? Math.max(100, Number(chainDetail.baseFeeMultiplier))\n : 100\n const baseComponentGwei = (effectiveBaseFeeGwei * baseFeeMultiplierPct) / 100\n const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei\n let maxPriorityFeePerGas =\n effectivePriorityFeeGwei > 0\n ? parseGwei(gweiToDecimalString(effectivePriorityFeeGwei))\n : parseGwei('1')\n let maxFeePerGas = parseGwei(gweiToDecimalString(maxFeePerGasGwei))\n if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {\n maxPriorityFeePerGas = (maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier)) / 100n\n maxFeePerGas = (maxFeePerGas * BigInt(100 + gasFeeMultiplier)) / 100n\n }\n ;({ maxFeePerGas, maxPriorityFeePerGas } = alignEip1559FeesWithLatestBase(\n maxFeePerGas,\n maxPriorityFeePerGas,\n latestBaseFeeWei,\n ))\n serialized = serializeTransaction({\n type: 'eip1559',\n to: step.to,\n data: step.data,\n value: step.value,\n gas: gasLimitI,\n maxFeePerGas,\n maxPriorityFeePerGas,\n nonce: currentNonce,\n chainId,\n })\n proposalTxParams = {\n nonce: currentNonce,\n gasLimit: gasLimitI.toString(),\n txType: 'eip1559',\n maxFeePerGas: maxFeePerGas.toString(),\n maxPriorityFeePerGas: maxPriorityFeePerGas.toString(),\n }\n feeSnapshot = i === 0 ? proposalTxParamsToFeeSnapshot(proposalTxParams) : {}\n }\n\n const h = keccak256(serialized)\n const msgHash = h.startsWith('0x') ? h.slice(2) : h\n\n const batchMetaExtra = args.buildBatchMeta({ step, index: i, gasLimit: gasLimitI })\n\n legs.push({\n msgHash,\n msgRaw: i === 0 && args.firstMsgRawNo0x != null ? args.firstMsgRawNo0x : serialized,\n destinationAddress: step.to,\n signatureText:\n typeof batchMetaExtra.signatureText === 'string'\n ? batchMetaExtra.signatureText\n : JSON.stringify(batchMetaExtra.signatureText ?? {}),\n audit: batchMetaExtra,\n feeSnapshot: i === 0 ? feeSnapshot : {},\n proposalTxParams,\n valueWei: i === 0 ? step.value : undefined,\n })\n\n if (i === 0 && args.firstMsgRawNo0x != null) {\n legs[0]!.msgRaw = args.firstMsgRawNo0x\n }\n }\n\n const extraJSON: Record<string, unknown> = {}\n if (useCustomGas && customGasChainDetails && Object.keys(customGasChainDetails).length > 0) {\n extraJSON.customGasChainDetails = customGasChainDetails\n }\n\n const result = finalizeMultisign({\n keyGen: keyGen as KeyGenSubset,\n purposeText,\n purposeSuffix: args.purposeSuffix,\n destinationChainID: String(chainId),\n destinationAddress: args.destinationAddress ?? steps[0]!.to,\n legs,\n extraJSON: Object.keys(extraJSON).length > 0 ? extraJSON : undefined,\n })\n const pv = args.payableValueWei\n if (pv != null && pv > 0n) {\n result.bodyForSign.value = pv.toString()\n }\n return result\n}\n\nexport const evmChainCategoryModule = {\n category: 'evm' as const,\n finalizeMultisign,\n buildEvmMultisignBatch,\n}\n","/** Parse chain id for comparisons (decimal, 0x hex, CAIP-2 eip155:N, bigint). */\nexport function parseEvmChainIdToNumber(chainId: string | number | bigint | null | undefined): number {\n if (chainId == null) return Number.NaN\n if (typeof chainId === 'bigint') {\n const n = Number(chainId)\n return Number.isSafeInteger(n) && n >= 0 ? n : Number.NaN\n }\n if (typeof chainId === 'number') {\n return Number.isInteger(chainId) && chainId >= 0 ? chainId : Number.NaN\n }\n const t = String(chainId).trim()\n if (!t) return Number.NaN\n const low = t.toLowerCase()\n if (low.startsWith('eip155:')) {\n const rest = t.slice('eip155:'.length).trim()\n const n = Number.parseInt(rest, 10)\n return Number.isNaN(n) || n < 0 ? Number.NaN : n\n }\n if (low.startsWith('0x')) {\n return Number.parseInt(t, 16)\n }\n return Number.parseInt(t, 10)\n}\n","import { formatUnits, parseUnits } from 'viem'\n\n/**\n * Canonical human decimal string for a token amount (truncate to token decimals via wei round-trip).\n * Used by Curve router and multisign dialogs across protocols.\n */\nexport function normalizeHumanDecimalAmount(raw: string, tokenDecimals: number): string {\n const t = raw.trim().replace(/,/g, '')\n if (!t) return ''\n if (!Number.isInteger(tokenDecimals) || tokenDecimals < 0 || tokenDecimals > 18) {\n throw new Error('Invalid token decimals for amount normalization.')\n }\n const wei = parseUnits(t, tokenDecimals)\n return formatUnits(wei, tokenDecimals)\n}\n\n/** @deprecated Prefer normalizeHumanDecimalAmount; kept for Curve router parity. */\nexport const normalizeCurveRouterAmountString = normalizeHumanDecimalAmount\n","import {\n createPublicClient,\n defineChain,\n encodeFunctionData,\n getAddress,\n http,\n parseAbi,\n type Address,\n type PublicClient,\n} from 'viem'\nimport type { EvmTxStep } from './types.js'\n\nconst erc20AllowanceAbi = parseAbi([\n 'function allowance(address owner, address spender) view returns (uint256)',\n 'function decimals() view returns (uint8)',\n])\nconst erc20ApproveAbi = parseAbi(['function approve(address spender, uint256 amount) returns (bool)'])\n\nexport function publicClientForRpc(chainId: number, rpcUrl: string): PublicClient {\n const ch = defineChain({\n id: chainId,\n name: `chain-${chainId}`,\n nativeCurrency: { decimals: 18, name: 'Ether', symbol: 'ETH' },\n rpcUrls: { default: { http: [rpcUrl.trim()] } },\n })\n return createPublicClient({ chain: ch, transport: http(rpcUrl.trim()) })\n}\n\n/**\n * Resolve ERC-20 decimals: on-chain `decimals()` is authoritative; optional registry/API hints\n * are validated and logged when they disagree (common when registry is stale).\n */\nexport async function resolveErc20Decimals(args: {\n publicClient: PublicClient\n token: Address\n registryDecimals?: number\n apiDecimals?: number\n}): Promise<number> {\n const token = getAddress(args.token)\n const onChain = await args.publicClient.readContract({\n address: token,\n abi: erc20AllowanceAbi,\n functionName: 'decimals',\n })\n const n = typeof onChain === 'bigint' ? Number(onChain) : Number(onChain)\n if (!Number.isFinite(n) || n < 0 || n > 36) {\n throw new Error(`Invalid on-chain decimals for ${token}.`)\n }\n for (const hint of [args.registryDecimals, args.apiDecimals]) {\n if (hint != null && Number.isFinite(hint) && hint !== n) {\n /* prefer on-chain — hints from token registry / fetch rows may be stale */\n }\n }\n return n\n}\n\nexport type ConditionalApproveStep = {\n to: Address\n data: `0x${string}`\n value: bigint\n fallbackGas?: bigint\n}\n\n/**\n * Standard deposit-path approve batch: skip when allowance sufficient; reset-to-zero when needed.\n */\nexport async function buildConditionalErc20ApproveSteps(args: {\n publicClient: PublicClient\n token: Address\n spender: Address\n owner: Address\n amountWei: bigint\n fallbackGas?: bigint\n}): Promise<ConditionalApproveStep[]> {\n if (args.amountWei <= 0n) return []\n const token = getAddress(args.token)\n const spender = getAddress(args.spender)\n const owner = getAddress(args.owner)\n const fallback = args.fallbackGas ?? 100_000n\n\n const allowance = await args.publicClient.readContract({\n address: token,\n abi: erc20AllowanceAbi,\n functionName: 'allowance',\n args: [owner, spender],\n })\n if (allowance >= args.amountWei) return []\n\n const steps: ConditionalApproveStep[] = []\n if (allowance > 0n) {\n steps.push({\n to: token,\n data: encodeFunctionData({ abi: erc20ApproveAbi, functionName: 'approve', args: [spender, 0n] }),\n value: 0n,\n fallbackGas: fallback,\n })\n }\n steps.push({\n to: token,\n data: encodeFunctionData({\n abi: erc20ApproveAbi,\n functionName: 'approve',\n args: [spender, args.amountWei],\n }),\n value: 0n,\n fallbackGas: fallback,\n })\n return steps\n}\n\nexport function approveStepsToEvmTxSteps(steps: ConditionalApproveStep[]): EvmTxStep[] {\n return steps.map((s) => ({\n to: s.to,\n data: s.data,\n value: s.value,\n fallbackGas: s.fallbackGas,\n }))\n}\n","/** CoinGecko asset platform id by mainnet chainId (contract price endpoint). */\nexport const COINGECKO_PLATFORM_BY_CHAIN_ID: Record<string, string> = {\n '1': 'ethereum',\n '56': 'binance-smart-chain',\n '137': 'polygon-pos',\n '42161': 'arbitrum-one',\n '10': 'optimistic-ethereum',\n '43114': 'avalanche',\n '8453': 'base',\n '324': 'zk-sync-era',\n '42220': 'celo',\n '250': 'fantom',\n '100': 'gnosis',\n '204': 'op-bnb',\n '534352': 'scroll',\n '5000': 'mantle',\n '169': 'manta-pacific',\n '1116': 'core',\n '30': 'rootstock',\n '288': 'boba',\n '1088': 'metis-andromeda',\n '34443': 'mode',\n '80084': 'berachain',\n '146': 'sonic',\n '60808': 'bob-network',\n '80094': 'berachain',\n '130': 'unichain',\n '57073': 'ink',\n '999': 'hyperevm',\n '239': 'tac',\n '9745': 'plasma',\n '1923': 'swellchain',\n '59144': 'linea',\n '81457': 'blast',\n '7777777': 'zora',\n}\n\nexport function coingeckoPlatformForChainId(chainId: string | number): string | undefined {\n return COINGECKO_PLATFORM_BY_CHAIN_ID[String(chainId).trim()]\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/chains/evm/types.ts","../../../src/core/purpose.ts","../../../src/core/envelope.ts","../../../src/chains/evm/routerSwapGas.ts","../../../src/chains/evm/buildBatch.ts","../../../src/chains/evm/chainIdParse.ts","../../../src/chains/evm/normalizeAmount.ts","../../../src/chains/evm/erc20Approve.ts","../../../src/chains/evm/coingecko.ts"],"names":["getAddress","zeroAddress","getClientIdFromKeyGenResult","gasLimitFromEstimateAndChainConfig","defineChain","createPublicClient","http","fetchChainFeeParams","parseGwei","gweiToDecimalString","serializeTransaction","proposalTxParamsToFeeSnapshot","alignEip1559FeesWithLatestBase","keccak256","parseUnits","formatUnits","parseAbi","encodeFunctionData"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { EvmTokenKind, MultisignCommonArgs } from '../../core/types.js'\nimport { getAddress, zeroAddress, type Address } from 'viem'\n\nexport type EvmChainDetail = {\n legacy?: boolean\n gasLimit?: number\n gasMultiplier?: number\n gasPrice?: number\n baseFee?: number\n priorityFee?: number\n baseFeeMultiplier?: number\n}\n\nexport interface EvmProtocolContext extends MultisignCommonArgs {\n chainCategory: 'evm'\n chainId: number\n rpcUrl: string\n executorAddress: Address\n chainDetail: EvmChainDetail\n useCustomGas: boolean\n customGasChainDetails?: Record<string, unknown> | null\n}\n\nexport type EvmTxStep = {\n to: Address\n data: `0x${string}`\n value: bigint\n /** Fallback when estimateGas reverts */\n fallbackGas?: bigint\n /** When set, use routerSwapGasLimitFromEstimate instead of plain estimate */\n routerSwap?: boolean\n}\n\nexport function isEvmNativeToken(address: string): boolean {\n try {\n return getAddress(address as `0x${string}`) === zeroAddress\n } catch {\n return address.toLowerCase() === zeroAddress\n }\n}\n\nexport function matchEvmTokenKind(\n kind: EvmTokenKind,\n address: string,\n): boolean {\n if (kind === 'native') return isEvmNativeToken(address)\n if (kind === 'erc20' || kind === 'ctmerc20' || kind === 'ctmrwa1') {\n return !isEvmNativeToken(address)\n }\n return true\n}\n","/** Merge user purpose text with an optional batch / protocol suffix. */\nexport function mergePurposeText(purposeText: string | undefined, purposeSuffix?: string): string {\n const t = (purposeText ?? '').trim()\n const suffix = (purposeSuffix ?? '').trim()\n if (!suffix) return t\n return t ? `${t}\\n\\n${suffix}` : suffix\n}\n","import type { ChainCategory, MultisignBuildResult, KeyGenSubset } from './types.js'\nimport { getClientIdFromKeyGenResult } from '@continuumdao/continuum-node-sdk'\nimport { mergePurposeText } from './purpose.js'\n\nexport interface MultisignLeg {\n msgHash: string\n msgRaw: string\n destinationAddress: string\n signatureText: string\n audit: Record<string, unknown>\n feeSnapshot: Record<string, unknown>\n proposalTxParams?: Record<string, unknown>\n /** Payable value wei string for first leg only when relevant */\n valueWei?: bigint\n}\n\nexport interface ChainCategoryBuildInput {\n keyGen: KeyGenSubset\n purposeText: string\n purposeSuffix?: string\n destinationChainID: string\n legs: MultisignLeg[]\n extraJSON?: Record<string, unknown>\n /** Top-level destination address (first leg destination if omitted) */\n destinationAddress?: string\n /** Unix seconds (UTC) for mpc-auth multiSignRequest expiryDate. */\n expiryDate?: number\n}\n\nexport interface ChainCategoryModule {\n category: ChainCategory\n finalizeMultisign(input: ChainCategoryBuildInput): MultisignBuildResult\n}\n\n/**\n * Assemble mpc-auth `bodyForSign` from category-built legs.\n * Supports single-tx and batch (messageHashes / messageRawBatch / proposalTxParams).\n */\nexport function finalizeMultisign(input: ChainCategoryBuildInput): MultisignBuildResult {\n const { keyGen, destinationChainID, legs } = input\n if (legs.length === 0) {\n throw new Error('finalizeMultisign requires at least one leg')\n }\n\n const ph = (keyGen.pubkeyhex ?? '').trim()\n if (!ph) throw new Error('keyGen pubKey (pubkeyhex) is required')\n\n const keyList = keyGen.keylist ?? []\n const clientId = getClientIdFromKeyGenResult(keyGen)\n const first = legs[0]!\n\n const messageHashes = legs.map((l) => l.msgHash)\n const messageRawBatch = legs.map((l) => l.msgRaw)\n const batchMeta = legs.map((l) => ({\n destinationAddress: l.destinationAddress,\n signatureText: l.signatureText,\n ...l.audit,\n }))\n\n const proposalTxParams = legs\n .map((l) => l.proposalTxParams)\n .filter((p): p is Record<string, unknown> => p != null && typeof p === 'object')\n\n const extraPayload: Record<string, unknown> = {\n batchMeta,\n ...(input.extraJSON ?? {}),\n }\n const extraJSON = JSON.stringify(extraPayload, (_, v) => (typeof v === 'bigint' ? v.toString() : v))\n\n const bodyForSign: Record<string, unknown> = {\n keyList,\n pubKey: ph,\n msgHash: messageHashes[0],\n msgRaw: first.msgRaw,\n destinationChainID,\n destinationAddress: input.destinationAddress ?? first.destinationAddress,\n extraJSON,\n signatureText: first.signatureText,\n purpose: mergePurposeText(input.purposeText, input.purposeSuffix),\n ...first.feeSnapshot,\n }\n\n if (legs.length > 1) {\n bodyForSign.messageHashes = messageHashes\n bodyForSign.messageRawBatch = messageRawBatch\n }\n\n if (proposalTxParams.length > 0) {\n bodyForSign.proposalTxParams = proposalTxParams\n }\n\n const valueWei = first.valueWei\n if (valueWei != null && valueWei > 0n) {\n bodyForSign.value = valueWei.toString()\n }\n\n if (clientId) bodyForSign.clientId = clientId\n\n if (input.expiryDate != null && input.expiryDate > 0) {\n bodyForSign.expiryDate = Math.floor(input.expiryDate)\n }\n\n return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) }\n}\n\nexport const coreChainCategoryModule: ChainCategoryModule = {\n category: 'evm',\n finalizeMultisign,\n}\n","import { gasLimitFromEstimateAndChainConfig } from '@continuumdao/continuum-node-sdk'\n\n/** Curve router swap gas: chain cap when set, else 12/10 estimate bump. */\nexport function routerSwapGasLimitFromEstimate(\n estimatedGas: bigint,\n chainGasLimit?: number | null,\n): bigint {\n if (chainGasLimit != null && Number.isFinite(chainGasLimit) && chainGasLimit > 0) {\n return gasLimitFromEstimateAndChainConfig(estimatedGas, chainGasLimit)\n }\n return (estimatedGas * 12n + 9n) / 10n\n}\n","import {\n keccak256,\n createPublicClient,\n defineChain,\n http,\n serializeTransaction,\n getAddress,\n parseGwei,\n type Address,\n type PublicClient,\n} from 'viem'\nimport type { MultisignBuildResult } from '../../core/types.js'\nimport { finalizeMultisign, type MultisignLeg } from '../../core/envelope.js'\nimport type { KeyGenSubset } from '../../core/types.js'\nimport {\n fetchChainFeeParams,\n alignEip1559FeesWithLatestBase,\n gweiToDecimalString,\n gasLimitFromEstimateAndChainConfig,\n proposalTxParamsToFeeSnapshot,\n type ProposalTxParams,\n} from '@continuumdao/continuum-node-sdk'\nimport { routerSwapGasLimitFromEstimate } from './routerSwapGas.js'\nimport type { EvmProtocolContext, EvmTxStep } from './types.js'\n\nexport type EvmBatchMetaBuilder = (args: {\n step: EvmTxStep\n index: number\n gasLimit: bigint\n}) => Record<string, unknown>\n\nexport type EvmBuildBatchArgs = {\n context: EvmProtocolContext\n steps: EvmTxStep[]\n purposeSuffix?: string\n buildBatchMeta: EvmBatchMetaBuilder\n /** First leg msgRaw without 0x prefix; defaults to first step calldata */\n firstMsgRawNo0x?: string\n destinationAddress?: Address\n /** Top-level `value` on bodyForSign when the payable amount is not on the first leg */\n payableValueWei?: bigint\n resolveGasLimit?: (args: {\n step: EvmTxStep\n index: number\n estimatedGas: bigint\n publicClient: PublicClient\n }) => Promise<bigint> | bigint\n /** Override default `estimateGas` (e.g. trade-API gas, skip post-approve deposit estimate). */\n estimateGasForStep?: (args: {\n step: EvmTxStep\n index: number\n publicClient: PublicClient\n executor: Address\n }) => Promise<bigint> | bigint\n}\n\n/**\n * Build unsigned EVM txs, estimate gas, serialize, hash — then assemble mpc-auth body via core envelope.\n */\nexport async function buildEvmMultisignBatch(args: EvmBuildBatchArgs): Promise<MultisignBuildResult> {\n const { context, steps } = args\n const {\n chainId,\n rpcUrl,\n executorAddress,\n chainDetail,\n useCustomGas,\n customGasChainDetails,\n keyGen,\n purposeText,\n } = context\n\n if (steps.length === 0) throw new Error('buildEvmMultisignBatch requires at least one step')\n\n const ch = defineChain({\n id: chainId,\n name: 'Destination',\n nativeCurrency: { decimals: 18, name: 'Ether', symbol: 'ETH' },\n rpcUrls: { default: { http: [rpcUrl] } },\n })\n const publicClient = createPublicClient({ chain: ch, transport: http(rpcUrl) })\n\n const feeParams = await fetchChainFeeParams(rpcUrl, chainId)\n const legacy = Boolean(chainDetail?.legacy) || !feeParams.isEip1559\n const latestBaseFeeWei = !legacy\n ? ((await publicClient.getBlock({ blockTag: 'latest' })).baseFeePerGas ?? 0n)\n : 0n\n\n const gasLimitConfig =\n useCustomGas && chainDetail?.gasLimit != null ? Number(chainDetail.gasLimit) : undefined\n const chainGasLimitRouter =\n chainDetail?.gasLimit != null &&\n Number.isFinite(Number(chainDetail.gasLimit)) &&\n Number(chainDetail.gasLimit) > 0\n ? Number(chainDetail.gasLimit)\n : undefined\n const gasFeeMultiplier =\n useCustomGas && chainDetail?.gasMultiplier != null ? Number(chainDetail.gasMultiplier) : undefined\n\n const executor = getAddress(executorAddress)\n const baseNonce = await publicClient.getTransactionCount({ address: executor, blockTag: 'pending' })\n\n const legs: MultisignLeg[] = []\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]!\n const currentNonce = baseNonce + i\n\n let estimatedGas: bigint\n if (args.estimateGasForStep) {\n estimatedGas = await args.estimateGasForStep({ step, index: i, publicClient, executor })\n } else {\n try {\n estimatedGas = await publicClient.estimateGas({\n to: step.to,\n data: step.data,\n value: step.value,\n account: executor,\n })\n } catch {\n estimatedGas = step.fallbackGas ?? 100_000n\n }\n }\n\n let gasLimitI: bigint\n if (args.resolveGasLimit) {\n gasLimitI = await args.resolveGasLimit({ step, index: i, estimatedGas, publicClient })\n } else if (step.routerSwap) {\n gasLimitI = routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimitRouter)\n } else {\n gasLimitI = useCustomGas\n ? gasLimitFromEstimateAndChainConfig(estimatedGas, gasLimitConfig)\n : estimatedGas\n }\n\n let proposalTxParams: ProposalTxParams\n let feeSnapshot: Record<string, unknown>\n let serialized: `0x${string}`\n\n if (legacy) {\n let gasPriceWei = await publicClient.getGasPrice()\n if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {\n gasPriceWei = (gasPriceWei * BigInt(100 + gasFeeMultiplier)) / 100n\n }\n if (useCustomGas && chainDetail?.gasPrice != null && chainDetail.gasPrice > 0) {\n const configured = parseGwei(gweiToDecimalString(Number(chainDetail.gasPrice)))\n if (configured > gasPriceWei) gasPriceWei = configured\n }\n serialized = serializeTransaction({\n type: 'legacy',\n to: step.to,\n data: step.data,\n value: step.value,\n gas: gasLimitI,\n gasPrice: gasPriceWei,\n nonce: currentNonce,\n chainId,\n })\n proposalTxParams = {\n nonce: currentNonce,\n gasLimit: gasLimitI.toString(),\n txType: 'legacy',\n gasPrice: gasPriceWei.toString(),\n }\n feeSnapshot = proposalTxParamsToFeeSnapshot(proposalTxParams)\n } else {\n const fetchedBase = feeParams.baseFeeGwei ?? 0\n const fetchedPriority = feeParams.priorityFeeGwei ?? 0\n const configuredBase =\n useCustomGas && chainDetail?.baseFee != null ? Number(chainDetail.baseFee) : 0\n const configuredPriority =\n useCustomGas && chainDetail?.priorityFee != null ? Number(chainDetail.priorityFee) : 0\n const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase)\n const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority)\n const baseFeeMultiplierPct =\n useCustomGas && chainDetail?.baseFeeMultiplier != null\n ? Math.max(100, Number(chainDetail.baseFeeMultiplier))\n : 100\n const baseComponentGwei = (effectiveBaseFeeGwei * baseFeeMultiplierPct) / 100\n const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei\n let maxPriorityFeePerGas =\n effectivePriorityFeeGwei > 0\n ? parseGwei(gweiToDecimalString(effectivePriorityFeeGwei))\n : parseGwei('1')\n let maxFeePerGas = parseGwei(gweiToDecimalString(maxFeePerGasGwei))\n if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {\n maxPriorityFeePerGas = (maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier)) / 100n\n maxFeePerGas = (maxFeePerGas * BigInt(100 + gasFeeMultiplier)) / 100n\n }\n ;({ maxFeePerGas, maxPriorityFeePerGas } = alignEip1559FeesWithLatestBase(\n maxFeePerGas,\n maxPriorityFeePerGas,\n latestBaseFeeWei,\n ))\n serialized = serializeTransaction({\n type: 'eip1559',\n to: step.to,\n data: step.data,\n value: step.value,\n gas: gasLimitI,\n maxFeePerGas,\n maxPriorityFeePerGas,\n nonce: currentNonce,\n chainId,\n })\n proposalTxParams = {\n nonce: currentNonce,\n gasLimit: gasLimitI.toString(),\n txType: 'eip1559',\n maxFeePerGas: maxFeePerGas.toString(),\n maxPriorityFeePerGas: maxPriorityFeePerGas.toString(),\n }\n feeSnapshot = i === 0 ? proposalTxParamsToFeeSnapshot(proposalTxParams) : {}\n }\n\n const h = keccak256(serialized)\n const msgHash = h.startsWith('0x') ? h.slice(2) : h\n\n const batchMetaExtra = args.buildBatchMeta({ step, index: i, gasLimit: gasLimitI })\n\n legs.push({\n msgHash,\n msgRaw: i === 0 && args.firstMsgRawNo0x != null ? args.firstMsgRawNo0x : serialized,\n destinationAddress: step.to,\n signatureText:\n typeof batchMetaExtra.signatureText === 'string'\n ? batchMetaExtra.signatureText\n : JSON.stringify(batchMetaExtra.signatureText ?? {}),\n audit: batchMetaExtra,\n feeSnapshot: i === 0 ? feeSnapshot : {},\n proposalTxParams,\n valueWei: i === 0 ? step.value : undefined,\n })\n\n if (i === 0 && args.firstMsgRawNo0x != null) {\n legs[0]!.msgRaw = args.firstMsgRawNo0x\n }\n }\n\n const extraJSON: Record<string, unknown> = {}\n if (useCustomGas && customGasChainDetails && Object.keys(customGasChainDetails).length > 0) {\n extraJSON.customGasChainDetails = customGasChainDetails\n }\n\n const result = finalizeMultisign({\n keyGen: keyGen as KeyGenSubset,\n purposeText,\n purposeSuffix: args.purposeSuffix,\n destinationChainID: String(chainId),\n destinationAddress: args.destinationAddress ?? steps[0]!.to,\n legs,\n extraJSON: Object.keys(extraJSON).length > 0 ? extraJSON : undefined,\n expiryDate: context.expiryDate,\n })\n const pv = args.payableValueWei\n if (pv != null && pv > 0n) {\n result.bodyForSign.value = pv.toString()\n }\n return result\n}\n\nexport const evmChainCategoryModule = {\n category: 'evm' as const,\n finalizeMultisign,\n buildEvmMultisignBatch,\n}\n","/** Parse chain id for comparisons (decimal, 0x hex, CAIP-2 eip155:N, bigint). */\nexport function parseEvmChainIdToNumber(chainId: string | number | bigint | null | undefined): number {\n if (chainId == null) return Number.NaN\n if (typeof chainId === 'bigint') {\n const n = Number(chainId)\n return Number.isSafeInteger(n) && n >= 0 ? n : Number.NaN\n }\n if (typeof chainId === 'number') {\n return Number.isInteger(chainId) && chainId >= 0 ? chainId : Number.NaN\n }\n const t = String(chainId).trim()\n if (!t) return Number.NaN\n const low = t.toLowerCase()\n if (low.startsWith('eip155:')) {\n const rest = t.slice('eip155:'.length).trim()\n const n = Number.parseInt(rest, 10)\n return Number.isNaN(n) || n < 0 ? Number.NaN : n\n }\n if (low.startsWith('0x')) {\n return Number.parseInt(t, 16)\n }\n return Number.parseInt(t, 10)\n}\n","import { formatUnits, parseUnits } from 'viem'\n\n/**\n * Canonical human decimal string for a token amount (truncate to token decimals via wei round-trip).\n * Used by Curve router and multisign dialogs across protocols.\n */\nexport function normalizeHumanDecimalAmount(raw: string, tokenDecimals: number): string {\n const t = raw.trim().replace(/,/g, '')\n if (!t) return ''\n if (!Number.isInteger(tokenDecimals) || tokenDecimals < 0 || tokenDecimals > 18) {\n throw new Error('Invalid token decimals for amount normalization.')\n }\n const wei = parseUnits(t, tokenDecimals)\n return formatUnits(wei, tokenDecimals)\n}\n\n/** @deprecated Prefer normalizeHumanDecimalAmount; kept for Curve router parity. */\nexport const normalizeCurveRouterAmountString = normalizeHumanDecimalAmount\n","import {\n createPublicClient,\n defineChain,\n encodeFunctionData,\n getAddress,\n http,\n parseAbi,\n type Address,\n type PublicClient,\n} from 'viem'\nimport type { EvmTxStep } from './types.js'\n\nconst erc20AllowanceAbi = parseAbi([\n 'function allowance(address owner, address spender) view returns (uint256)',\n 'function decimals() view returns (uint8)',\n])\nconst erc20ApproveAbi = parseAbi(['function approve(address spender, uint256 amount) returns (bool)'])\n\nexport function publicClientForRpc(chainId: number, rpcUrl: string): PublicClient {\n const ch = defineChain({\n id: chainId,\n name: `chain-${chainId}`,\n nativeCurrency: { decimals: 18, name: 'Ether', symbol: 'ETH' },\n rpcUrls: { default: { http: [rpcUrl.trim()] } },\n })\n return createPublicClient({ chain: ch, transport: http(rpcUrl.trim()) })\n}\n\n/**\n * Resolve ERC-20 decimals: on-chain `decimals()` is authoritative; optional registry/API hints\n * are validated and logged when they disagree (common when registry is stale).\n */\nexport async function resolveErc20Decimals(args: {\n publicClient: PublicClient\n token: Address\n registryDecimals?: number\n apiDecimals?: number\n}): Promise<number> {\n const token = getAddress(args.token)\n const onChain = await args.publicClient.readContract({\n address: token,\n abi: erc20AllowanceAbi,\n functionName: 'decimals',\n })\n const n = typeof onChain === 'bigint' ? Number(onChain) : Number(onChain)\n if (!Number.isFinite(n) || n < 0 || n > 36) {\n throw new Error(`Invalid on-chain decimals for ${token}.`)\n }\n for (const hint of [args.registryDecimals, args.apiDecimals]) {\n if (hint != null && Number.isFinite(hint) && hint !== n) {\n /* prefer on-chain — hints from token registry / fetch rows may be stale */\n }\n }\n return n\n}\n\nexport type ConditionalApproveStep = {\n to: Address\n data: `0x${string}`\n value: bigint\n fallbackGas?: bigint\n}\n\n/**\n * Standard deposit-path approve batch: skip when allowance sufficient; reset-to-zero when needed.\n */\nexport async function buildConditionalErc20ApproveSteps(args: {\n publicClient: PublicClient\n token: Address\n spender: Address\n owner: Address\n amountWei: bigint\n fallbackGas?: bigint\n}): Promise<ConditionalApproveStep[]> {\n if (args.amountWei <= 0n) return []\n const token = getAddress(args.token)\n const spender = getAddress(args.spender)\n const owner = getAddress(args.owner)\n const fallback = args.fallbackGas ?? 100_000n\n\n const allowance = await args.publicClient.readContract({\n address: token,\n abi: erc20AllowanceAbi,\n functionName: 'allowance',\n args: [owner, spender],\n })\n if (allowance >= args.amountWei) return []\n\n const steps: ConditionalApproveStep[] = []\n if (allowance > 0n) {\n steps.push({\n to: token,\n data: encodeFunctionData({ abi: erc20ApproveAbi, functionName: 'approve', args: [spender, 0n] }),\n value: 0n,\n fallbackGas: fallback,\n })\n }\n steps.push({\n to: token,\n data: encodeFunctionData({\n abi: erc20ApproveAbi,\n functionName: 'approve',\n args: [spender, args.amountWei],\n }),\n value: 0n,\n fallbackGas: fallback,\n })\n return steps\n}\n\nexport function approveStepsToEvmTxSteps(steps: ConditionalApproveStep[]): EvmTxStep[] {\n return steps.map((s) => ({\n to: s.to,\n data: s.data,\n value: s.value,\n fallbackGas: s.fallbackGas,\n }))\n}\n","/** CoinGecko asset platform id by mainnet chainId (contract price endpoint). */\nexport const COINGECKO_PLATFORM_BY_CHAIN_ID: Record<string, string> = {\n '1': 'ethereum',\n '56': 'binance-smart-chain',\n '137': 'polygon-pos',\n '42161': 'arbitrum-one',\n '10': 'optimistic-ethereum',\n '43114': 'avalanche',\n '8453': 'base',\n '324': 'zk-sync-era',\n '42220': 'celo',\n '250': 'fantom',\n '100': 'gnosis',\n '204': 'op-bnb',\n '534352': 'scroll',\n '5000': 'mantle',\n '169': 'manta-pacific',\n '1116': 'core',\n '30': 'rootstock',\n '288': 'boba',\n '1088': 'metis-andromeda',\n '34443': 'mode',\n '80084': 'berachain',\n '146': 'sonic',\n '60808': 'bob-network',\n '80094': 'berachain',\n '130': 'unichain',\n '57073': 'ink',\n '999': 'hyperevm',\n '239': 'tac',\n '9745': 'plasma',\n '1923': 'swellchain',\n '59144': 'linea',\n '81457': 'blast',\n '7777777': 'zora',\n}\n\nexport function coingeckoPlatformForChainId(chainId: string | number): string | undefined {\n return COINGECKO_PLATFORM_BY_CHAIN_ID[String(chainId).trim()]\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { b as EvmTxStep, a as EvmProtocolContext } from '../../types-
|
|
2
|
-
export { E as EvmChainDetail, i as isEvmNativeToken, m as matchEvmTokenKind } from '../../types-
|
|
1
|
+
import { b as EvmTxStep, a as EvmProtocolContext } from '../../types-RZWOTm8c.js';
|
|
2
|
+
export { E as EvmChainDetail, i as isEvmNativeToken, m as matchEvmTokenKind } from '../../types-RZWOTm8c.js';
|
|
3
3
|
import { Address, PublicClient } from 'viem';
|
|
4
|
-
import { M as MultisignBuildResult } from '../../types-
|
|
5
|
-
import { f as finalizeMultisign } from '../../envelope-
|
|
4
|
+
import { M as MultisignBuildResult } from '../../types-PZrvtjv8.js';
|
|
5
|
+
import { f as finalizeMultisign } from '../../envelope-C_bfuKab.js';
|
|
6
6
|
|
|
7
7
|
type EvmBatchMetaBuilder = (args: {
|
|
8
8
|
step: EvmTxStep;
|
package/dist/chains/evm/index.js
CHANGED
|
@@ -75,6 +75,9 @@ function finalizeMultisign(input) {
|
|
|
75
75
|
bodyForSign.value = valueWei.toString();
|
|
76
76
|
}
|
|
77
77
|
if (clientId) bodyForSign.clientId = clientId;
|
|
78
|
+
if (input.expiryDate != null && input.expiryDate > 0) {
|
|
79
|
+
bodyForSign.expiryDate = Math.floor(input.expiryDate);
|
|
80
|
+
}
|
|
78
81
|
return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
|
|
79
82
|
}
|
|
80
83
|
function routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimit) {
|
|
@@ -238,7 +241,8 @@ async function buildEvmMultisignBatch(args) {
|
|
|
238
241
|
destinationChainID: String(chainId),
|
|
239
242
|
destinationAddress: args.destinationAddress ?? steps[0].to,
|
|
240
243
|
legs,
|
|
241
|
-
extraJSON: Object.keys(extraJSON).length > 0 ? extraJSON : void 0
|
|
244
|
+
extraJSON: Object.keys(extraJSON).length > 0 ? extraJSON : void 0,
|
|
245
|
+
expiryDate: context.expiryDate
|
|
242
246
|
});
|
|
243
247
|
const pv = args.payableValueWei;
|
|
244
248
|
if (pv != null && pv > 0n) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/chains/evm/types.ts","../../../src/core/purpose.ts","../../../src/core/envelope.ts","../../../src/chains/evm/routerSwapGas.ts","../../../src/chains/evm/buildBatch.ts","../../../src/chains/evm/chainIdParse.ts","../../../src/chains/evm/normalizeAmount.ts","../../../src/chains/evm/erc20Approve.ts","../../../src/chains/evm/coingecko.ts"],"names":["getAddress","gasLimitFromEstimateAndChainConfig","defineChain","createPublicClient","http"],"mappings":"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","file":"index.js","sourcesContent":["import type { EvmTokenKind, MultisignCommonArgs } from '../../core/types.js'\nimport { getAddress, zeroAddress, type Address } from 'viem'\n\nexport type EvmChainDetail = {\n legacy?: boolean\n gasLimit?: number\n gasMultiplier?: number\n gasPrice?: number\n baseFee?: number\n priorityFee?: number\n baseFeeMultiplier?: number\n}\n\nexport interface EvmProtocolContext extends MultisignCommonArgs {\n chainCategory: 'evm'\n chainId: number\n rpcUrl: string\n executorAddress: Address\n chainDetail: EvmChainDetail\n useCustomGas: boolean\n customGasChainDetails?: Record<string, unknown> | null\n}\n\nexport type EvmTxStep = {\n to: Address\n data: `0x${string}`\n value: bigint\n /** Fallback when estimateGas reverts */\n fallbackGas?: bigint\n /** When set, use routerSwapGasLimitFromEstimate instead of plain estimate */\n routerSwap?: boolean\n}\n\nexport function isEvmNativeToken(address: string): boolean {\n try {\n return getAddress(address as `0x${string}`) === zeroAddress\n } catch {\n return address.toLowerCase() === zeroAddress\n }\n}\n\nexport function matchEvmTokenKind(\n kind: EvmTokenKind,\n address: string,\n): boolean {\n if (kind === 'native') return isEvmNativeToken(address)\n if (kind === 'erc20' || kind === 'ctmerc20' || kind === 'ctmrwa1') {\n return !isEvmNativeToken(address)\n }\n return true\n}\n","/** Merge user purpose text with an optional batch / protocol suffix. */\nexport function mergePurposeText(purposeText: string | undefined, purposeSuffix?: string): string {\n const t = (purposeText ?? '').trim()\n const suffix = (purposeSuffix ?? '').trim()\n if (!suffix) return t\n return t ? `${t}\\n\\n${suffix}` : suffix\n}\n","import type { ChainCategory, MultisignBuildResult, KeyGenSubset } from './types.js'\nimport { getClientIdFromKeyGenResult } from '@continuumdao/continuum-node-sdk'\nimport { mergePurposeText } from './purpose.js'\n\nexport interface MultisignLeg {\n msgHash: string\n msgRaw: string\n destinationAddress: string\n signatureText: string\n audit: Record<string, unknown>\n feeSnapshot: Record<string, unknown>\n proposalTxParams?: Record<string, unknown>\n /** Payable value wei string for first leg only when relevant */\n valueWei?: bigint\n}\n\nexport interface ChainCategoryBuildInput {\n keyGen: KeyGenSubset\n purposeText: string\n purposeSuffix?: string\n destinationChainID: string\n legs: MultisignLeg[]\n extraJSON?: Record<string, unknown>\n /** Top-level destination address (first leg destination if omitted) */\n destinationAddress?: string\n}\n\nexport interface ChainCategoryModule {\n category: ChainCategory\n finalizeMultisign(input: ChainCategoryBuildInput): MultisignBuildResult\n}\n\n/**\n * Assemble mpc-auth `bodyForSign` from category-built legs.\n * Supports single-tx and batch (messageHashes / messageRawBatch / proposalTxParams).\n */\nexport function finalizeMultisign(input: ChainCategoryBuildInput): MultisignBuildResult {\n const { keyGen, destinationChainID, legs } = input\n if (legs.length === 0) {\n throw new Error('finalizeMultisign requires at least one leg')\n }\n\n const ph = (keyGen.pubkeyhex ?? '').trim()\n if (!ph) throw new Error('keyGen pubKey (pubkeyhex) is required')\n\n const keyList = keyGen.keylist ?? []\n const clientId = getClientIdFromKeyGenResult(keyGen)\n const first = legs[0]!\n\n const messageHashes = legs.map((l) => l.msgHash)\n const messageRawBatch = legs.map((l) => l.msgRaw)\n const batchMeta = legs.map((l) => ({\n destinationAddress: l.destinationAddress,\n signatureText: l.signatureText,\n ...l.audit,\n }))\n\n const proposalTxParams = legs\n .map((l) => l.proposalTxParams)\n .filter((p): p is Record<string, unknown> => p != null && typeof p === 'object')\n\n const extraPayload: Record<string, unknown> = {\n batchMeta,\n ...(input.extraJSON ?? {}),\n }\n const extraJSON = JSON.stringify(extraPayload, (_, v) => (typeof v === 'bigint' ? v.toString() : v))\n\n const bodyForSign: Record<string, unknown> = {\n keyList,\n pubKey: ph,\n msgHash: messageHashes[0],\n msgRaw: first.msgRaw,\n destinationChainID,\n destinationAddress: input.destinationAddress ?? first.destinationAddress,\n extraJSON,\n signatureText: first.signatureText,\n purpose: mergePurposeText(input.purposeText, input.purposeSuffix),\n ...first.feeSnapshot,\n }\n\n if (legs.length > 1) {\n bodyForSign.messageHashes = messageHashes\n bodyForSign.messageRawBatch = messageRawBatch\n }\n\n if (proposalTxParams.length > 0) {\n bodyForSign.proposalTxParams = proposalTxParams\n }\n\n const valueWei = first.valueWei\n if (valueWei != null && valueWei > 0n) {\n bodyForSign.value = valueWei.toString()\n }\n\n if (clientId) bodyForSign.clientId = clientId\n\n return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) }\n}\n\nexport const coreChainCategoryModule: ChainCategoryModule = {\n category: 'evm',\n finalizeMultisign,\n}\n","import { gasLimitFromEstimateAndChainConfig } from '@continuumdao/continuum-node-sdk'\n\n/** Curve router swap gas: chain cap when set, else 12/10 estimate bump. */\nexport function routerSwapGasLimitFromEstimate(\n estimatedGas: bigint,\n chainGasLimit?: number | null,\n): bigint {\n if (chainGasLimit != null && Number.isFinite(chainGasLimit) && chainGasLimit > 0) {\n return gasLimitFromEstimateAndChainConfig(estimatedGas, chainGasLimit)\n }\n return (estimatedGas * 12n + 9n) / 10n\n}\n","import {\n keccak256,\n createPublicClient,\n defineChain,\n http,\n serializeTransaction,\n getAddress,\n parseGwei,\n type Address,\n type PublicClient,\n} from 'viem'\nimport type { MultisignBuildResult } from '../../core/types.js'\nimport { finalizeMultisign, type MultisignLeg } from '../../core/envelope.js'\nimport type { KeyGenSubset } from '../../core/types.js'\nimport {\n fetchChainFeeParams,\n alignEip1559FeesWithLatestBase,\n gweiToDecimalString,\n gasLimitFromEstimateAndChainConfig,\n proposalTxParamsToFeeSnapshot,\n type ProposalTxParams,\n} from '@continuumdao/continuum-node-sdk'\nimport { routerSwapGasLimitFromEstimate } from './routerSwapGas.js'\nimport type { EvmProtocolContext, EvmTxStep } from './types.js'\n\nexport type EvmBatchMetaBuilder = (args: {\n step: EvmTxStep\n index: number\n gasLimit: bigint\n}) => Record<string, unknown>\n\nexport type EvmBuildBatchArgs = {\n context: EvmProtocolContext\n steps: EvmTxStep[]\n purposeSuffix?: string\n buildBatchMeta: EvmBatchMetaBuilder\n /** First leg msgRaw without 0x prefix; defaults to first step calldata */\n firstMsgRawNo0x?: string\n destinationAddress?: Address\n /** Top-level `value` on bodyForSign when the payable amount is not on the first leg */\n payableValueWei?: bigint\n resolveGasLimit?: (args: {\n step: EvmTxStep\n index: number\n estimatedGas: bigint\n publicClient: PublicClient\n }) => Promise<bigint> | bigint\n /** Override default `estimateGas` (e.g. trade-API gas, skip post-approve deposit estimate). */\n estimateGasForStep?: (args: {\n step: EvmTxStep\n index: number\n publicClient: PublicClient\n executor: Address\n }) => Promise<bigint> | bigint\n}\n\n/**\n * Build unsigned EVM txs, estimate gas, serialize, hash — then assemble mpc-auth body via core envelope.\n */\nexport async function buildEvmMultisignBatch(args: EvmBuildBatchArgs): Promise<MultisignBuildResult> {\n const { context, steps } = args\n const {\n chainId,\n rpcUrl,\n executorAddress,\n chainDetail,\n useCustomGas,\n customGasChainDetails,\n keyGen,\n purposeText,\n } = context\n\n if (steps.length === 0) throw new Error('buildEvmMultisignBatch requires at least one step')\n\n const ch = defineChain({\n id: chainId,\n name: 'Destination',\n nativeCurrency: { decimals: 18, name: 'Ether', symbol: 'ETH' },\n rpcUrls: { default: { http: [rpcUrl] } },\n })\n const publicClient = createPublicClient({ chain: ch, transport: http(rpcUrl) })\n\n const feeParams = await fetchChainFeeParams(rpcUrl, chainId)\n const legacy = Boolean(chainDetail?.legacy) || !feeParams.isEip1559\n const latestBaseFeeWei = !legacy\n ? ((await publicClient.getBlock({ blockTag: 'latest' })).baseFeePerGas ?? 0n)\n : 0n\n\n const gasLimitConfig =\n useCustomGas && chainDetail?.gasLimit != null ? Number(chainDetail.gasLimit) : undefined\n const chainGasLimitRouter =\n chainDetail?.gasLimit != null &&\n Number.isFinite(Number(chainDetail.gasLimit)) &&\n Number(chainDetail.gasLimit) > 0\n ? Number(chainDetail.gasLimit)\n : undefined\n const gasFeeMultiplier =\n useCustomGas && chainDetail?.gasMultiplier != null ? Number(chainDetail.gasMultiplier) : undefined\n\n const executor = getAddress(executorAddress)\n const baseNonce = await publicClient.getTransactionCount({ address: executor, blockTag: 'pending' })\n\n const legs: MultisignLeg[] = []\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]!\n const currentNonce = baseNonce + i\n\n let estimatedGas: bigint\n if (args.estimateGasForStep) {\n estimatedGas = await args.estimateGasForStep({ step, index: i, publicClient, executor })\n } else {\n try {\n estimatedGas = await publicClient.estimateGas({\n to: step.to,\n data: step.data,\n value: step.value,\n account: executor,\n })\n } catch {\n estimatedGas = step.fallbackGas ?? 100_000n\n }\n }\n\n let gasLimitI: bigint\n if (args.resolveGasLimit) {\n gasLimitI = await args.resolveGasLimit({ step, index: i, estimatedGas, publicClient })\n } else if (step.routerSwap) {\n gasLimitI = routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimitRouter)\n } else {\n gasLimitI = useCustomGas\n ? gasLimitFromEstimateAndChainConfig(estimatedGas, gasLimitConfig)\n : estimatedGas\n }\n\n let proposalTxParams: ProposalTxParams\n let feeSnapshot: Record<string, unknown>\n let serialized: `0x${string}`\n\n if (legacy) {\n let gasPriceWei = await publicClient.getGasPrice()\n if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {\n gasPriceWei = (gasPriceWei * BigInt(100 + gasFeeMultiplier)) / 100n\n }\n if (useCustomGas && chainDetail?.gasPrice != null && chainDetail.gasPrice > 0) {\n const configured = parseGwei(gweiToDecimalString(Number(chainDetail.gasPrice)))\n if (configured > gasPriceWei) gasPriceWei = configured\n }\n serialized = serializeTransaction({\n type: 'legacy',\n to: step.to,\n data: step.data,\n value: step.value,\n gas: gasLimitI,\n gasPrice: gasPriceWei,\n nonce: currentNonce,\n chainId,\n })\n proposalTxParams = {\n nonce: currentNonce,\n gasLimit: gasLimitI.toString(),\n txType: 'legacy',\n gasPrice: gasPriceWei.toString(),\n }\n feeSnapshot = proposalTxParamsToFeeSnapshot(proposalTxParams)\n } else {\n const fetchedBase = feeParams.baseFeeGwei ?? 0\n const fetchedPriority = feeParams.priorityFeeGwei ?? 0\n const configuredBase =\n useCustomGas && chainDetail?.baseFee != null ? Number(chainDetail.baseFee) : 0\n const configuredPriority =\n useCustomGas && chainDetail?.priorityFee != null ? Number(chainDetail.priorityFee) : 0\n const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase)\n const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority)\n const baseFeeMultiplierPct =\n useCustomGas && chainDetail?.baseFeeMultiplier != null\n ? Math.max(100, Number(chainDetail.baseFeeMultiplier))\n : 100\n const baseComponentGwei = (effectiveBaseFeeGwei * baseFeeMultiplierPct) / 100\n const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei\n let maxPriorityFeePerGas =\n effectivePriorityFeeGwei > 0\n ? parseGwei(gweiToDecimalString(effectivePriorityFeeGwei))\n : parseGwei('1')\n let maxFeePerGas = parseGwei(gweiToDecimalString(maxFeePerGasGwei))\n if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {\n maxPriorityFeePerGas = (maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier)) / 100n\n maxFeePerGas = (maxFeePerGas * BigInt(100 + gasFeeMultiplier)) / 100n\n }\n ;({ maxFeePerGas, maxPriorityFeePerGas } = alignEip1559FeesWithLatestBase(\n maxFeePerGas,\n maxPriorityFeePerGas,\n latestBaseFeeWei,\n ))\n serialized = serializeTransaction({\n type: 'eip1559',\n to: step.to,\n data: step.data,\n value: step.value,\n gas: gasLimitI,\n maxFeePerGas,\n maxPriorityFeePerGas,\n nonce: currentNonce,\n chainId,\n })\n proposalTxParams = {\n nonce: currentNonce,\n gasLimit: gasLimitI.toString(),\n txType: 'eip1559',\n maxFeePerGas: maxFeePerGas.toString(),\n maxPriorityFeePerGas: maxPriorityFeePerGas.toString(),\n }\n feeSnapshot = i === 0 ? proposalTxParamsToFeeSnapshot(proposalTxParams) : {}\n }\n\n const h = keccak256(serialized)\n const msgHash = h.startsWith('0x') ? h.slice(2) : h\n\n const batchMetaExtra = args.buildBatchMeta({ step, index: i, gasLimit: gasLimitI })\n\n legs.push({\n msgHash,\n msgRaw: i === 0 && args.firstMsgRawNo0x != null ? args.firstMsgRawNo0x : serialized,\n destinationAddress: step.to,\n signatureText:\n typeof batchMetaExtra.signatureText === 'string'\n ? batchMetaExtra.signatureText\n : JSON.stringify(batchMetaExtra.signatureText ?? {}),\n audit: batchMetaExtra,\n feeSnapshot: i === 0 ? feeSnapshot : {},\n proposalTxParams,\n valueWei: i === 0 ? step.value : undefined,\n })\n\n if (i === 0 && args.firstMsgRawNo0x != null) {\n legs[0]!.msgRaw = args.firstMsgRawNo0x\n }\n }\n\n const extraJSON: Record<string, unknown> = {}\n if (useCustomGas && customGasChainDetails && Object.keys(customGasChainDetails).length > 0) {\n extraJSON.customGasChainDetails = customGasChainDetails\n }\n\n const result = finalizeMultisign({\n keyGen: keyGen as KeyGenSubset,\n purposeText,\n purposeSuffix: args.purposeSuffix,\n destinationChainID: String(chainId),\n destinationAddress: args.destinationAddress ?? steps[0]!.to,\n legs,\n extraJSON: Object.keys(extraJSON).length > 0 ? extraJSON : undefined,\n })\n const pv = args.payableValueWei\n if (pv != null && pv > 0n) {\n result.bodyForSign.value = pv.toString()\n }\n return result\n}\n\nexport const evmChainCategoryModule = {\n category: 'evm' as const,\n finalizeMultisign,\n buildEvmMultisignBatch,\n}\n","/** Parse chain id for comparisons (decimal, 0x hex, CAIP-2 eip155:N, bigint). */\nexport function parseEvmChainIdToNumber(chainId: string | number | bigint | null | undefined): number {\n if (chainId == null) return Number.NaN\n if (typeof chainId === 'bigint') {\n const n = Number(chainId)\n return Number.isSafeInteger(n) && n >= 0 ? n : Number.NaN\n }\n if (typeof chainId === 'number') {\n return Number.isInteger(chainId) && chainId >= 0 ? chainId : Number.NaN\n }\n const t = String(chainId).trim()\n if (!t) return Number.NaN\n const low = t.toLowerCase()\n if (low.startsWith('eip155:')) {\n const rest = t.slice('eip155:'.length).trim()\n const n = Number.parseInt(rest, 10)\n return Number.isNaN(n) || n < 0 ? Number.NaN : n\n }\n if (low.startsWith('0x')) {\n return Number.parseInt(t, 16)\n }\n return Number.parseInt(t, 10)\n}\n","import { formatUnits, parseUnits } from 'viem'\n\n/**\n * Canonical human decimal string for a token amount (truncate to token decimals via wei round-trip).\n * Used by Curve router and multisign dialogs across protocols.\n */\nexport function normalizeHumanDecimalAmount(raw: string, tokenDecimals: number): string {\n const t = raw.trim().replace(/,/g, '')\n if (!t) return ''\n if (!Number.isInteger(tokenDecimals) || tokenDecimals < 0 || tokenDecimals > 18) {\n throw new Error('Invalid token decimals for amount normalization.')\n }\n const wei = parseUnits(t, tokenDecimals)\n return formatUnits(wei, tokenDecimals)\n}\n\n/** @deprecated Prefer normalizeHumanDecimalAmount; kept for Curve router parity. */\nexport const normalizeCurveRouterAmountString = normalizeHumanDecimalAmount\n","import {\n createPublicClient,\n defineChain,\n encodeFunctionData,\n getAddress,\n http,\n parseAbi,\n type Address,\n type PublicClient,\n} from 'viem'\nimport type { EvmTxStep } from './types.js'\n\nconst erc20AllowanceAbi = parseAbi([\n 'function allowance(address owner, address spender) view returns (uint256)',\n 'function decimals() view returns (uint8)',\n])\nconst erc20ApproveAbi = parseAbi(['function approve(address spender, uint256 amount) returns (bool)'])\n\nexport function publicClientForRpc(chainId: number, rpcUrl: string): PublicClient {\n const ch = defineChain({\n id: chainId,\n name: `chain-${chainId}`,\n nativeCurrency: { decimals: 18, name: 'Ether', symbol: 'ETH' },\n rpcUrls: { default: { http: [rpcUrl.trim()] } },\n })\n return createPublicClient({ chain: ch, transport: http(rpcUrl.trim()) })\n}\n\n/**\n * Resolve ERC-20 decimals: on-chain `decimals()` is authoritative; optional registry/API hints\n * are validated and logged when they disagree (common when registry is stale).\n */\nexport async function resolveErc20Decimals(args: {\n publicClient: PublicClient\n token: Address\n registryDecimals?: number\n apiDecimals?: number\n}): Promise<number> {\n const token = getAddress(args.token)\n const onChain = await args.publicClient.readContract({\n address: token,\n abi: erc20AllowanceAbi,\n functionName: 'decimals',\n })\n const n = typeof onChain === 'bigint' ? Number(onChain) : Number(onChain)\n if (!Number.isFinite(n) || n < 0 || n > 36) {\n throw new Error(`Invalid on-chain decimals for ${token}.`)\n }\n for (const hint of [args.registryDecimals, args.apiDecimals]) {\n if (hint != null && Number.isFinite(hint) && hint !== n) {\n /* prefer on-chain — hints from token registry / fetch rows may be stale */\n }\n }\n return n\n}\n\nexport type ConditionalApproveStep = {\n to: Address\n data: `0x${string}`\n value: bigint\n fallbackGas?: bigint\n}\n\n/**\n * Standard deposit-path approve batch: skip when allowance sufficient; reset-to-zero when needed.\n */\nexport async function buildConditionalErc20ApproveSteps(args: {\n publicClient: PublicClient\n token: Address\n spender: Address\n owner: Address\n amountWei: bigint\n fallbackGas?: bigint\n}): Promise<ConditionalApproveStep[]> {\n if (args.amountWei <= 0n) return []\n const token = getAddress(args.token)\n const spender = getAddress(args.spender)\n const owner = getAddress(args.owner)\n const fallback = args.fallbackGas ?? 100_000n\n\n const allowance = await args.publicClient.readContract({\n address: token,\n abi: erc20AllowanceAbi,\n functionName: 'allowance',\n args: [owner, spender],\n })\n if (allowance >= args.amountWei) return []\n\n const steps: ConditionalApproveStep[] = []\n if (allowance > 0n) {\n steps.push({\n to: token,\n data: encodeFunctionData({ abi: erc20ApproveAbi, functionName: 'approve', args: [spender, 0n] }),\n value: 0n,\n fallbackGas: fallback,\n })\n }\n steps.push({\n to: token,\n data: encodeFunctionData({\n abi: erc20ApproveAbi,\n functionName: 'approve',\n args: [spender, args.amountWei],\n }),\n value: 0n,\n fallbackGas: fallback,\n })\n return steps\n}\n\nexport function approveStepsToEvmTxSteps(steps: ConditionalApproveStep[]): EvmTxStep[] {\n return steps.map((s) => ({\n to: s.to,\n data: s.data,\n value: s.value,\n fallbackGas: s.fallbackGas,\n }))\n}\n","/** CoinGecko asset platform id by mainnet chainId (contract price endpoint). */\nexport const COINGECKO_PLATFORM_BY_CHAIN_ID: Record<string, string> = {\n '1': 'ethereum',\n '56': 'binance-smart-chain',\n '137': 'polygon-pos',\n '42161': 'arbitrum-one',\n '10': 'optimistic-ethereum',\n '43114': 'avalanche',\n '8453': 'base',\n '324': 'zk-sync-era',\n '42220': 'celo',\n '250': 'fantom',\n '100': 'gnosis',\n '204': 'op-bnb',\n '534352': 'scroll',\n '5000': 'mantle',\n '169': 'manta-pacific',\n '1116': 'core',\n '30': 'rootstock',\n '288': 'boba',\n '1088': 'metis-andromeda',\n '34443': 'mode',\n '80084': 'berachain',\n '146': 'sonic',\n '60808': 'bob-network',\n '80094': 'berachain',\n '130': 'unichain',\n '57073': 'ink',\n '999': 'hyperevm',\n '239': 'tac',\n '9745': 'plasma',\n '1923': 'swellchain',\n '59144': 'linea',\n '81457': 'blast',\n '7777777': 'zora',\n}\n\nexport function coingeckoPlatformForChainId(chainId: string | number): string | undefined {\n return COINGECKO_PLATFORM_BY_CHAIN_ID[String(chainId).trim()]\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/chains/evm/types.ts","../../../src/core/purpose.ts","../../../src/core/envelope.ts","../../../src/chains/evm/routerSwapGas.ts","../../../src/chains/evm/buildBatch.ts","../../../src/chains/evm/chainIdParse.ts","../../../src/chains/evm/normalizeAmount.ts","../../../src/chains/evm/erc20Approve.ts","../../../src/chains/evm/coingecko.ts"],"names":["getAddress","gasLimitFromEstimateAndChainConfig","defineChain","createPublicClient","http"],"mappings":";;;;AAiCO,SAAS,iBAAiB,OAAA,EAA0B;AACzD,EAAA,IAAI;AACF,IAAA,OAAO,UAAA,CAAW,OAAwB,CAAA,KAAM,WAAA;AAAA,EAClD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,OAAA,CAAQ,aAAY,KAAM,WAAA;AAAA,EACnC;AACF;AAEO,SAAS,iBAAA,CACd,MACA,OAAA,EACS;AACT,EAAA,IAAI,IAAA,KAAS,QAAA,EAAU,OAAO,gBAAA,CAAiB,OAAO,CAAA;AACtD,EAAA,IAAI,IAAA,KAAS,OAAA,IAAW,IAAA,KAAS,UAAA,IAAc,SAAS,SAAA,EAAW;AACjE,IAAA,OAAO,CAAC,iBAAiB,OAAO,CAAA;AAAA,EAClC;AACA,EAAA,OAAO,IAAA;AACT;;;ACjDO,SAAS,gBAAA,CAAiB,aAAiC,aAAA,EAAgC;AAChG,EAAA,MAAM,CAAA,GAAA,CAAK,WAAA,IAAe,EAAA,EAAI,IAAA,EAAK;AACnC,EAAA,MAAM,MAAA,GAAA,CAAU,aAAA,IAAiB,EAAA,EAAI,IAAA,EAAK;AAC1C,EAAA,IAAI,CAAC,QAAQ,OAAO,CAAA;AACpB,EAAA,OAAO,CAAA,GAAI,GAAG,CAAC;;AAAA,EAAO,MAAM,CAAA,CAAA,GAAK,MAAA;AACnC;;;ACgCO,SAAS,kBAAkB,KAAA,EAAsD;AACtF,EAAA,MAAM,EAAE,MAAA,EAAQ,kBAAA,EAAoB,IAAA,EAAK,GAAI,KAAA;AAC7C,EAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,IAAA,MAAM,IAAI,MAAM,6CAA6C,CAAA;AAAA,EAC/D;AAEA,EAAA,MAAM,EAAA,GAAA,CAAM,MAAA,CAAO,SAAA,IAAa,EAAA,EAAI,IAAA,EAAK;AACzC,EAAA,IAAI,CAAC,EAAA,EAAI,MAAM,IAAI,MAAM,uCAAuC,CAAA;AAEhE,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,IAAW,EAAC;AACnC,EAAA,MAAM,QAAA,GAAW,4BAA4B,MAAM,CAAA;AACnD,EAAA,MAAM,KAAA,GAAQ,KAAK,CAAC,CAAA;AAEpB,EAAA,MAAM,gBAAgB,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,OAAO,CAAA;AAC/C,EAAA,MAAM,kBAAkB,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,MAAM,CAAA;AAChD,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,IACjC,oBAAoB,CAAA,CAAE,kBAAA;AAAA,IACtB,eAAe,CAAA,CAAE,aAAA;AAAA,IACjB,GAAG,CAAA,CAAE;AAAA,GACP,CAAE,CAAA;AAEF,EAAA,MAAM,gBAAA,GAAmB,IAAA,CACtB,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,gBAAgB,CAAA,CAC7B,MAAA,CAAO,CAAC,CAAA,KAAoC,CAAA,IAAK,IAAA,IAAQ,OAAO,MAAM,QAAQ,CAAA;AAEjF,EAAA,MAAM,YAAA,GAAwC;AAAA,IAC5C,SAAA;AAAA,IACA,GAAI,KAAA,CAAM,SAAA,IAAa;AAAC,GAC1B;AACA,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,SAAA,CAAU,YAAA,EAAc,CAAC,CAAA,EAAG,CAAA,KAAO,OAAO,CAAA,KAAM,QAAA,GAAW,CAAA,CAAE,QAAA,KAAa,CAAE,CAAA;AAEnG,EAAA,MAAM,WAAA,GAAuC;AAAA,IAC3C,OAAA;AAAA,IACA,MAAA,EAAQ,EAAA;AAAA,IACR,OAAA,EAAS,cAAc,CAAC,CAAA;AAAA,IACxB,QAAQ,KAAA,CAAM,MAAA;AAAA,IACd,kBAAA;AAAA,IACA,kBAAA,EAAoB,KAAA,CAAM,kBAAA,IAAsB,KAAA,CAAM,kBAAA;AAAA,IACtD,SAAA;AAAA,IACA,eAAe,KAAA,CAAM,aAAA;AAAA,IACrB,OAAA,EAAS,gBAAA,CAAiB,KAAA,CAAM,WAAA,EAAa,MAAM,aAAa,CAAA;AAAA,IAChE,GAAG,KAAA,CAAM;AAAA,GACX;AAEA,EAAA,IAAI,IAAA,CAAK,SAAS,CAAA,EAAG;AACnB,IAAA,WAAA,CAAY,aAAA,GAAgB,aAAA;AAC5B,IAAA,WAAA,CAAY,eAAA,GAAkB,eAAA;AAAA,EAChC;AAEA,EAAA,IAAI,gBAAA,CAAiB,SAAS,CAAA,EAAG;AAC/B,IAAA,WAAA,CAAY,gBAAA,GAAmB,gBAAA;AAAA,EACjC;AAEA,EAAA,MAAM,WAAW,KAAA,CAAM,QAAA;AACvB,EAAA,IAAI,QAAA,IAAY,IAAA,IAAQ,QAAA,GAAW,EAAA,EAAI;AACrC,IAAA,WAAA,CAAY,KAAA,GAAQ,SAAS,QAAA,EAAS;AAAA,EACxC;AAEA,EAAA,IAAI,QAAA,cAAsB,QAAA,GAAW,QAAA;AAErC,EAAA,IAAI,KAAA,CAAM,UAAA,IAAc,IAAA,IAAQ,KAAA,CAAM,aAAa,CAAA,EAAG;AACpD,IAAA,WAAA,CAAY,UAAA,GAAa,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,UAAU,CAAA;AAAA,EACtD;AAEA,EAAA,OAAO,EAAE,WAAA,EAAa,aAAA,EAAe,IAAA,CAAK,SAAA,CAAU,WAAW,CAAA,EAAE;AACnE;ACpGO,SAAS,8BAAA,CACd,cACA,aAAA,EACQ;AACR,EAAA,IAAI,iBAAiB,IAAA,IAAQ,MAAA,CAAO,SAAS,aAAa,CAAA,IAAK,gBAAgB,CAAA,EAAG;AAChF,IAAA,OAAO,kCAAA,CAAmC,cAAc,aAAa,CAAA;AAAA,EACvE;AACA,EAAA,OAAA,CAAQ,YAAA,GAAe,MAAM,EAAA,IAAM,GAAA;AACrC;;;ACgDA,eAAsB,uBAAuB,IAAA,EAAwD;AACnG,EAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAM,GAAI,IAAA;AAC3B,EAAA,MAAM;AAAA,IACJ,OAAA;AAAA,IACA,MAAA;AAAA,IACA,eAAA;AAAA,IACA,WAAA;AAAA,IACA,YAAA;AAAA,IACA,qBAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF,GAAI,OAAA;AAEJ,EAAA,IAAI,MAAM,MAAA,KAAW,CAAA,EAAG,MAAM,IAAI,MAAM,mDAAmD,CAAA;AAE3F,EAAA,MAAM,KAAK,WAAA,CAAY;AAAA,IACrB,EAAA,EAAI,OAAA;AAAA,IACJ,IAAA,EAAM,aAAA;AAAA,IACN,gBAAgB,EAAE,QAAA,EAAU,IAAI,IAAA,EAAM,OAAA,EAAS,QAAQ,KAAA,EAAM;AAAA,IAC7D,OAAA,EAAS,EAAE,OAAA,EAAS,EAAE,MAAM,CAAC,MAAM,GAAE;AAAE,GACxC,CAAA;AACD,EAAA,MAAM,YAAA,GAAe,mBAAmB,EAAE,KAAA,EAAO,IAAI,SAAA,EAAW,IAAA,CAAK,MAAM,CAAA,EAAG,CAAA;AAE9E,EAAA,MAAM,SAAA,GAAY,MAAM,mBAAA,CAAoB,MAAA,EAAQ,OAAO,CAAA;AAC3D,EAAA,MAAM,SAAS,OAAA,CAAQ,WAAA,EAAa,MAAM,CAAA,IAAK,CAAC,SAAA,CAAU,SAAA;AAC1D,EAAA,MAAM,gBAAA,GAAmB,CAAC,MAAA,GAAA,CACpB,MAAM,YAAA,CAAa,QAAA,CAAS,EAAE,QAAA,EAAU,QAAA,EAAU,CAAA,EAAG,aAAA,IAAiB,EAAA,GACxE,EAAA;AAEJ,EAAA,MAAM,cAAA,GACJ,gBAAgB,WAAA,EAAa,QAAA,IAAY,OAAO,MAAA,CAAO,WAAA,CAAY,QAAQ,CAAA,GAAI,MAAA;AACjF,EAAA,MAAM,sBACJ,WAAA,EAAa,QAAA,IAAY,QACzB,MAAA,CAAO,QAAA,CAAS,OAAO,WAAA,CAAY,QAAQ,CAAC,CAAA,IAC5C,MAAA,CAAO,YAAY,QAAQ,CAAA,GAAI,IAC3B,MAAA,CAAO,WAAA,CAAY,QAAQ,CAAA,GAC3B,MAAA;AACN,EAAA,MAAM,gBAAA,GACJ,gBAAgB,WAAA,EAAa,aAAA,IAAiB,OAAO,MAAA,CAAO,WAAA,CAAY,aAAa,CAAA,GAAI,MAAA;AAE3F,EAAA,MAAM,QAAA,GAAWA,WAAW,eAAe,CAAA;AAC3C,EAAA,MAAM,SAAA,GAAY,MAAM,YAAA,CAAa,mBAAA,CAAoB,EAAE,OAAA,EAAS,QAAA,EAAU,QAAA,EAAU,SAAA,EAAW,CAAA;AAEnG,EAAA,MAAM,OAAuB,EAAC;AAE9B,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AACpB,IAAA,MAAM,eAAe,SAAA,GAAY,CAAA;AAEjC,IAAA,IAAI,YAAA;AACJ,IAAA,IAAI,KAAK,kBAAA,EAAoB;AAC3B,MAAA,YAAA,GAAe,MAAM,KAAK,kBAAA,CAAmB,EAAE,MAAM,KAAA,EAAO,CAAA,EAAG,YAAA,EAAc,QAAA,EAAU,CAAA;AAAA,IACzF,CAAA,MAAO;AACL,MAAA,IAAI;AACF,QAAA,YAAA,GAAe,MAAM,aAAa,WAAA,CAAY;AAAA,UAC5C,IAAI,IAAA,CAAK,EAAA;AAAA,UACT,MAAM,IAAA,CAAK,IAAA;AAAA,UACX,OAAO,IAAA,CAAK,KAAA;AAAA,UACZ,OAAA,EAAS;AAAA,SACV,CAAA;AAAA,MACH,CAAA,CAAA,MAAQ;AACN,QAAA,YAAA,GAAe,KAAK,WAAA,IAAe,OAAA;AAAA,MACrC;AAAA,IACF;AAEA,IAAA,IAAI,SAAA;AACJ,IAAA,IAAI,KAAK,eAAA,EAAiB;AACxB,MAAA,SAAA,GAAY,MAAM,KAAK,eAAA,CAAgB,EAAE,MAAM,KAAA,EAAO,CAAA,EAAG,YAAA,EAAc,YAAA,EAAc,CAAA;AAAA,IACvF,CAAA,MAAA,IAAW,KAAK,UAAA,EAAY;AAC1B,MAAA,SAAA,GAAY,8BAAA,CAA+B,cAAc,mBAAmB,CAAA;AAAA,IAC9E,CAAA,MAAO;AACL,MAAA,SAAA,GAAY,YAAA,GACRC,kCAAAA,CAAmC,YAAA,EAAc,cAAc,CAAA,GAC/D,YAAA;AAAA,IACN;AAEA,IAAA,IAAI,gBAAA;AACJ,IAAA,IAAI,WAAA;AACJ,IAAA,IAAI,UAAA;AAEJ,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,IAAI,WAAA,GAAc,MAAM,YAAA,CAAa,WAAA,EAAY;AACjD,MAAA,IAAI,YAAA,IAAgB,gBAAA,IAAoB,IAAA,IAAQ,gBAAA,GAAmB,CAAA,EAAG;AACpE,QAAA,WAAA,GAAe,WAAA,GAAc,MAAA,CAAO,GAAA,GAAM,gBAAgB,CAAA,GAAK,IAAA;AAAA,MACjE;AACA,MAAA,IAAI,gBAAgB,WAAA,EAAa,QAAA,IAAY,IAAA,IAAQ,WAAA,CAAY,WAAW,CAAA,EAAG;AAC7E,QAAA,MAAM,aAAa,SAAA,CAAU,mBAAA,CAAoB,OAAO,WAAA,CAAY,QAAQ,CAAC,CAAC,CAAA;AAC9E,QAAA,IAAI,UAAA,GAAa,aAAa,WAAA,GAAc,UAAA;AAAA,MAC9C;AACA,MAAA,UAAA,GAAa,oBAAA,CAAqB;AAAA,QAChC,IAAA,EAAM,QAAA;AAAA,QACN,IAAI,IAAA,CAAK,EAAA;AAAA,QACT,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,OAAO,IAAA,CAAK,KAAA;AAAA,QACZ,GAAA,EAAK,SAAA;AAAA,QACL,QAAA,EAAU,WAAA;AAAA,QACV,KAAA,EAAO,YAAA;AAAA,QACP;AAAA,OACD,CAAA;AACD,MAAA,gBAAA,GAAmB;AAAA,QACjB,KAAA,EAAO,YAAA;AAAA,QACP,QAAA,EAAU,UAAU,QAAA,EAAS;AAAA,QAC7B,MAAA,EAAQ,QAAA;AAAA,QACR,QAAA,EAAU,YAAY,QAAA;AAAS,OACjC;AACA,MAAA,WAAA,GAAc,8BAA8B,gBAAgB,CAAA;AAAA,IAC9D,CAAA,MAAO;AACL,MAAA,MAAM,WAAA,GAAc,UAAU,WAAA,IAAe,CAAA;AAC7C,MAAA,MAAM,eAAA,GAAkB,UAAU,eAAA,IAAmB,CAAA;AACrD,MAAA,MAAM,cAAA,GACJ,gBAAgB,WAAA,EAAa,OAAA,IAAW,OAAO,MAAA,CAAO,WAAA,CAAY,OAAO,CAAA,GAAI,CAAA;AAC/E,MAAA,MAAM,kBAAA,GACJ,gBAAgB,WAAA,EAAa,WAAA,IAAe,OAAO,MAAA,CAAO,WAAA,CAAY,WAAW,CAAA,GAAI,CAAA;AACvF,MAAA,MAAM,oBAAA,GAAuB,IAAA,CAAK,GAAA,CAAI,WAAA,EAAa,cAAc,CAAA;AACjE,MAAA,MAAM,wBAAA,GAA2B,IAAA,CAAK,GAAA,CAAI,eAAA,EAAiB,kBAAkB,CAAA;AAC7E,MAAA,MAAM,oBAAA,GACJ,YAAA,IAAgB,WAAA,EAAa,iBAAA,IAAqB,IAAA,GAC9C,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,MAAA,CAAO,WAAA,CAAY,iBAAiB,CAAC,CAAA,GACnD,GAAA;AACN,MAAA,MAAM,iBAAA,GAAqB,uBAAuB,oBAAA,GAAwB,GAAA;AAC1E,MAAA,MAAM,mBAAmB,iBAAA,GAAoB,wBAAA;AAC7C,MAAA,IAAI,oBAAA,GACF,2BAA2B,CAAA,GACvB,SAAA,CAAU,oBAAoB,wBAAwB,CAAC,CAAA,GACvD,SAAA,CAAU,GAAG,CAAA;AACnB,MAAA,IAAI,YAAA,GAAe,SAAA,CAAU,mBAAA,CAAoB,gBAAgB,CAAC,CAAA;AAClE,MAAA,IAAI,YAAA,IAAgB,gBAAA,IAAoB,IAAA,IAAQ,gBAAA,GAAmB,CAAA,EAAG;AACpE,QAAA,oBAAA,GAAwB,oBAAA,GAAuB,MAAA,CAAO,GAAA,GAAM,gBAAgB,CAAA,GAAK,IAAA;AACjF,QAAA,YAAA,GAAgB,YAAA,GAAe,MAAA,CAAO,GAAA,GAAM,gBAAgB,CAAA,GAAK,IAAA;AAAA,MACnE;AACC,MAAA,CAAC,EAAE,YAAA,EAAc,oBAAA,EAAqB,GAAI,8BAAA;AAAA,QACzC,YAAA;AAAA,QACA,oBAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,UAAA,GAAa,oBAAA,CAAqB;AAAA,QAChC,IAAA,EAAM,SAAA;AAAA,QACN,IAAI,IAAA,CAAK,EAAA;AAAA,QACT,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,OAAO,IAAA,CAAK,KAAA;AAAA,QACZ,GAAA,EAAK,SAAA;AAAA,QACL,YAAA;AAAA,QACA,oBAAA;AAAA,QACA,KAAA,EAAO,YAAA;AAAA,QACP;AAAA,OACD,CAAA;AACD,MAAA,gBAAA,GAAmB;AAAA,QACjB,KAAA,EAAO,YAAA;AAAA,QACP,QAAA,EAAU,UAAU,QAAA,EAAS;AAAA,QAC7B,MAAA,EAAQ,SAAA;AAAA,QACR,YAAA,EAAc,aAAa,QAAA,EAAS;AAAA,QACpC,oBAAA,EAAsB,qBAAqB,QAAA;AAAS,OACtD;AACA,MAAA,WAAA,GAAc,CAAA,KAAM,CAAA,GAAI,6BAAA,CAA8B,gBAAgB,IAAI,EAAC;AAAA,IAC7E;AAEA,IAAA,MAAM,CAAA,GAAI,UAAU,UAAU,CAAA;AAC9B,IAAA,MAAM,OAAA,GAAU,EAAE,UAAA,CAAW,IAAI,IAAI,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA,GAAI,CAAA;AAElD,IAAA,MAAM,cAAA,GAAiB,KAAK,cAAA,CAAe,EAAE,MAAM,KAAA,EAAO,CAAA,EAAG,QAAA,EAAU,SAAA,EAAW,CAAA;AAElF,IAAA,IAAA,CAAK,IAAA,CAAK;AAAA,MACR,OAAA;AAAA,MACA,QAAQ,CAAA,KAAM,CAAA,IAAK,KAAK,eAAA,IAAmB,IAAA,GAAO,KAAK,eAAA,GAAkB,UAAA;AAAA,MACzE,oBAAoB,IAAA,CAAK,EAAA;AAAA,MACzB,aAAA,EACE,OAAO,cAAA,CAAe,aAAA,KAAkB,QAAA,GACpC,cAAA,CAAe,aAAA,GACf,IAAA,CAAK,SAAA,CAAU,cAAA,CAAe,aAAA,IAAiB,EAAE,CAAA;AAAA,MACvD,KAAA,EAAO,cAAA;AAAA,MACP,WAAA,EAAa,CAAA,KAAM,CAAA,GAAI,WAAA,GAAc,EAAC;AAAA,MACtC,gBAAA;AAAA,MACA,QAAA,EAAU,CAAA,KAAM,CAAA,GAAI,IAAA,CAAK,KAAA,GAAQ;AAAA,KAClC,CAAA;AAED,IAAA,IAAI,CAAA,KAAM,CAAA,IAAK,IAAA,CAAK,eAAA,IAAmB,IAAA,EAAM;AAC3C,MAAA,IAAA,CAAK,CAAC,CAAA,CAAG,MAAA,GAAS,IAAA,CAAK,eAAA;AAAA,IACzB;AAAA,EACF;AAEA,EAAA,MAAM,YAAqC,EAAC;AAC5C,EAAA,IAAI,gBAAgB,qBAAA,IAAyB,MAAA,CAAO,KAAK,qBAAqB,CAAA,CAAE,SAAS,CAAA,EAAG;AAC1F,IAAA,SAAA,CAAU,qBAAA,GAAwB,qBAAA;AAAA,EACpC;AAEA,EAAA,MAAM,SAAS,iBAAA,CAAkB;AAAA,IAC/B,MAAA;AAAA,IACA,WAAA;AAAA,IACA,eAAe,IAAA,CAAK,aAAA;AAAA,IACpB,kBAAA,EAAoB,OAAO,OAAO,CAAA;AAAA,IAClC,kBAAA,EAAoB,IAAA,CAAK,kBAAA,IAAsB,KAAA,CAAM,CAAC,CAAA,CAAG,EAAA;AAAA,IACzD,IAAA;AAAA,IACA,WAAW,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,CAAE,MAAA,GAAS,IAAI,SAAA,GAAY,MAAA;AAAA,IAC3D,YAAY,OAAA,CAAQ;AAAA,GACrB,CAAA;AACD,EAAA,MAAM,KAAK,IAAA,CAAK,eAAA;AAChB,EAAA,IAAI,EAAA,IAAM,IAAA,IAAQ,EAAA,GAAK,EAAA,EAAI;AACzB,IAAA,MAAA,CAAO,WAAA,CAAY,KAAA,GAAQ,EAAA,CAAG,QAAA,EAAS;AAAA,EACzC;AACA,EAAA,OAAO,MAAA;AACT;AAEO,IAAM,sBAAA,GAAyB;AAAA,EACpC,QAAA,EAAU,KAAA;AAAA,EACV,iBAAA;AAAA,EACA;AACF;;;ACxQO,SAAS,wBAAwB,OAAA,EAA8D;AACpG,EAAA,IAAI,OAAA,IAAW,IAAA,EAAM,OAAO,MAAA,CAAO,GAAA;AACnC,EAAA,IAAI,OAAO,YAAY,QAAA,EAAU;AAC/B,IAAA,MAAM,CAAA,GAAI,OAAO,OAAO,CAAA;AACxB,IAAA,OAAO,OAAO,aAAA,CAAc,CAAC,KAAK,CAAA,IAAK,CAAA,GAAI,IAAI,MAAA,CAAO,GAAA;AAAA,EACxD;AACA,EAAA,IAAI,OAAO,YAAY,QAAA,EAAU;AAC/B,IAAA,OAAO,OAAO,SAAA,CAAU,OAAO,KAAK,OAAA,IAAW,CAAA,GAAI,UAAU,MAAA,CAAO,GAAA;AAAA,EACtE;AACA,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,EAAK;AAC/B,EAAA,IAAI,CAAC,CAAA,EAAG,OAAO,MAAA,CAAO,GAAA;AACtB,EAAA,MAAM,GAAA,GAAM,EAAE,WAAA,EAAY;AAC1B,EAAA,IAAI,GAAA,CAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AAC7B,IAAA,MAAM,OAAO,CAAA,CAAE,KAAA,CAAM,SAAA,CAAU,MAAM,EAAE,IAAA,EAAK;AAC5C,IAAA,MAAM,CAAA,GAAI,MAAA,CAAO,QAAA,CAAS,IAAA,EAAM,EAAE,CAAA;AAClC,IAAA,OAAO,OAAO,KAAA,CAAM,CAAC,KAAK,CAAA,GAAI,CAAA,GAAI,OAAO,GAAA,GAAM,CAAA;AAAA,EACjD;AACA,EAAA,IAAI,GAAA,CAAI,UAAA,CAAW,IAAI,CAAA,EAAG;AACxB,IAAA,OAAO,MAAA,CAAO,QAAA,CAAS,CAAA,EAAG,EAAE,CAAA;AAAA,EAC9B;AACA,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,CAAA,EAAG,EAAE,CAAA;AAC9B;AChBO,SAAS,2BAAA,CAA4B,KAAa,aAAA,EAA+B;AACtF,EAAA,MAAM,IAAI,GAAA,CAAI,IAAA,EAAK,CAAE,OAAA,CAAQ,MAAM,EAAE,CAAA;AACrC,EAAA,IAAI,CAAC,GAAG,OAAO,EAAA;AACf,EAAA,IAAI,CAAC,OAAO,SAAA,CAAU,aAAa,KAAK,aAAA,GAAgB,CAAA,IAAK,gBAAgB,EAAA,EAAI;AAC/E,IAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAAA,EACpE;AACA,EAAA,MAAM,GAAA,GAAM,UAAA,CAAW,CAAA,EAAG,aAAa,CAAA;AACvC,EAAA,OAAO,WAAA,CAAY,KAAK,aAAa,CAAA;AACvC;AAGO,IAAM,gCAAA,GAAmC;ACLhD,IAAM,oBAAoB,QAAA,CAAS;AAAA,EACjC,2EAAA;AAAA,EACA;AACF,CAAC,CAAA;AACD,IAAM,eAAA,GAAkB,QAAA,CAAS,CAAC,kEAAkE,CAAC,CAAA;AAE9F,SAAS,kBAAA,CAAmB,SAAiB,MAAA,EAA8B;AAChF,EAAA,MAAM,KAAKC,WAAAA,CAAY;AAAA,IACrB,EAAA,EAAI,OAAA;AAAA,IACJ,IAAA,EAAM,SAAS,OAAO,CAAA,CAAA;AAAA,IACtB,gBAAgB,EAAE,QAAA,EAAU,IAAI,IAAA,EAAM,OAAA,EAAS,QAAQ,KAAA,EAAM;AAAA,IAC7D,OAAA,EAAS,EAAE,OAAA,EAAS,EAAE,IAAA,EAAM,CAAC,MAAA,CAAO,IAAA,EAAM,CAAA,EAAE;AAAE,GAC/C,CAAA;AACD,EAAA,OAAOC,kBAAAA,CAAmB,EAAE,KAAA,EAAO,EAAA,EAAI,SAAA,EAAWC,KAAK,MAAA,CAAO,IAAA,EAAM,CAAA,EAAG,CAAA;AACzE;AAMA,eAAsB,qBAAqB,IAAA,EAKvB;AAClB,EAAA,MAAM,KAAA,GAAQJ,UAAAA,CAAW,IAAA,CAAK,KAAK,CAAA;AACnC,EAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,YAAA,CAAa,YAAA,CAAa;AAAA,IACnD,OAAA,EAAS,KAAA;AAAA,IACT,GAAA,EAAK,iBAAA;AAAA,IACL,YAAA,EAAc;AAAA,GACf,CAAA;AACD,EAAA,MAAM,CAAA,GAAI,OAAO,OAAA,KAAY,QAAA,GAAW,OAAO,OAAO,CAAA,GAAI,OAAO,OAAO,CAAA;AACxE,EAAA,IAAI,CAAC,OAAO,QAAA,CAAS,CAAC,KAAK,CAAA,GAAI,CAAA,IAAK,IAAI,EAAA,EAAI;AAC1C,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,8BAAA,EAAiC,KAAK,CAAA,CAAA,CAAG,CAAA;AAAA,EAC3D;AACA,EAAA,KAAA,MAAW,QAAQ,CAAC,IAAA,CAAK,gBAAA,EAAkB,IAAA,CAAK,WAAW,CAAA,EAAG;AAG5D,EACF;AACA,EAAA,OAAO,CAAA;AACT;AAYA,eAAsB,kCAAkC,IAAA,EAOlB;AACpC,EAAA,IAAI,IAAA,CAAK,SAAA,IAAa,EAAA,EAAI,OAAO,EAAC;AAClC,EAAA,MAAM,KAAA,GAAQA,UAAAA,CAAW,IAAA,CAAK,KAAK,CAAA;AACnC,EAAA,MAAM,OAAA,GAAUA,UAAAA,CAAW,IAAA,CAAK,OAAO,CAAA;AACvC,EAAA,MAAM,KAAA,GAAQA,UAAAA,CAAW,IAAA,CAAK,KAAK,CAAA;AACnC,EAAA,MAAM,QAAA,GAAW,KAAK,WAAA,IAAe,OAAA;AAErC,EAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,YAAA,CAAa,YAAA,CAAa;AAAA,IACrD,OAAA,EAAS,KAAA;AAAA,IACT,GAAA,EAAK,iBAAA;AAAA,IACL,YAAA,EAAc,WAAA;AAAA,IACd,IAAA,EAAM,CAAC,KAAA,EAAO,OAAO;AAAA,GACtB,CAAA;AACD,EAAA,IAAI,SAAA,IAAa,IAAA,CAAK,SAAA,EAAW,OAAO,EAAC;AAEzC,EAAA,MAAM,QAAkC,EAAC;AACzC,EAAA,IAAI,YAAY,EAAA,EAAI;AAClB,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,EAAA,EAAI,KAAA;AAAA,MACJ,IAAA,EAAM,kBAAA,CAAmB,EAAE,GAAA,EAAK,eAAA,EAAiB,YAAA,EAAc,SAAA,EAAW,IAAA,EAAM,CAAC,OAAA,EAAS,EAAE,CAAA,EAAG,CAAA;AAAA,MAC/F,KAAA,EAAO,EAAA;AAAA,MACP,WAAA,EAAa;AAAA,KACd,CAAA;AAAA,EACH;AACA,EAAA,KAAA,CAAM,IAAA,CAAK;AAAA,IACT,EAAA,EAAI,KAAA;AAAA,IACJ,MAAM,kBAAA,CAAmB;AAAA,MACvB,GAAA,EAAK,eAAA;AAAA,MACL,YAAA,EAAc,SAAA;AAAA,MACd,IAAA,EAAM,CAAC,OAAA,EAAS,IAAA,CAAK,SAAS;AAAA,KAC/B,CAAA;AAAA,IACD,KAAA,EAAO,EAAA;AAAA,IACP,WAAA,EAAa;AAAA,GACd,CAAA;AACD,EAAA,OAAO,KAAA;AACT;AAEO,SAAS,yBAAyB,KAAA,EAA8C;AACrF,EAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,IACvB,IAAI,CAAA,CAAE,EAAA;AAAA,IACN,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,OAAO,CAAA,CAAE,KAAA;AAAA,IACT,aAAa,CAAA,CAAE;AAAA,GACjB,CAAE,CAAA;AACJ;;;ACpHO,IAAM,8BAAA,GAAyD;AAAA,EACpE,GAAA,EAAK,UAAA;AAAA,EACL,IAAA,EAAM,qBAAA;AAAA,EACN,KAAA,EAAO,aAAA;AAAA,EACP,OAAA,EAAS,cAAA;AAAA,EACT,IAAA,EAAM,qBAAA;AAAA,EACN,OAAA,EAAS,WAAA;AAAA,EACT,MAAA,EAAQ,MAAA;AAAA,EACR,KAAA,EAAO,aAAA;AAAA,EACP,OAAA,EAAS,MAAA;AAAA,EACT,KAAA,EAAO,QAAA;AAAA,EACP,KAAA,EAAO,QAAA;AAAA,EACP,KAAA,EAAO,QAAA;AAAA,EACP,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,QAAA;AAAA,EACR,KAAA,EAAO,eAAA;AAAA,EACP,MAAA,EAAQ,MAAA;AAAA,EACR,IAAA,EAAM,WAAA;AAAA,EACN,KAAA,EAAO,MAAA;AAAA,EACP,MAAA,EAAQ,iBAAA;AAAA,EACR,OAAA,EAAS,MAAA;AAAA,EACT,OAAA,EAAS,WAAA;AAAA,EACT,KAAA,EAAO,OAAA;AAAA,EACP,OAAA,EAAS,aAAA;AAAA,EACT,OAAA,EAAS,WAAA;AAAA,EACT,KAAA,EAAO,UAAA;AAAA,EACP,OAAA,EAAS,KAAA;AAAA,EACT,KAAA,EAAO,UAAA;AAAA,EACP,KAAA,EAAO,KAAA;AAAA,EACP,MAAA,EAAQ,QAAA;AAAA,EACR,MAAA,EAAQ,YAAA;AAAA,EACR,OAAA,EAAS,OAAA;AAAA,EACT,OAAA,EAAS,OAAA;AAAA,EACT,SAAA,EAAW;AACb;AAEO,SAAS,4BAA4B,OAAA,EAA8C;AACxF,EAAA,OAAO,8BAAA,CAA+B,MAAA,CAAO,OAAO,CAAA,CAAE,MAAM,CAAA;AAC9D","file":"index.js","sourcesContent":["import type { EvmTokenKind, MultisignCommonArgs } from '../../core/types.js'\nimport { getAddress, zeroAddress, type Address } from 'viem'\n\nexport type EvmChainDetail = {\n legacy?: boolean\n gasLimit?: number\n gasMultiplier?: number\n gasPrice?: number\n baseFee?: number\n priorityFee?: number\n baseFeeMultiplier?: number\n}\n\nexport interface EvmProtocolContext extends MultisignCommonArgs {\n chainCategory: 'evm'\n chainId: number\n rpcUrl: string\n executorAddress: Address\n chainDetail: EvmChainDetail\n useCustomGas: boolean\n customGasChainDetails?: Record<string, unknown> | null\n}\n\nexport type EvmTxStep = {\n to: Address\n data: `0x${string}`\n value: bigint\n /** Fallback when estimateGas reverts */\n fallbackGas?: bigint\n /** When set, use routerSwapGasLimitFromEstimate instead of plain estimate */\n routerSwap?: boolean\n}\n\nexport function isEvmNativeToken(address: string): boolean {\n try {\n return getAddress(address as `0x${string}`) === zeroAddress\n } catch {\n return address.toLowerCase() === zeroAddress\n }\n}\n\nexport function matchEvmTokenKind(\n kind: EvmTokenKind,\n address: string,\n): boolean {\n if (kind === 'native') return isEvmNativeToken(address)\n if (kind === 'erc20' || kind === 'ctmerc20' || kind === 'ctmrwa1') {\n return !isEvmNativeToken(address)\n }\n return true\n}\n","/** Merge user purpose text with an optional batch / protocol suffix. */\nexport function mergePurposeText(purposeText: string | undefined, purposeSuffix?: string): string {\n const t = (purposeText ?? '').trim()\n const suffix = (purposeSuffix ?? '').trim()\n if (!suffix) return t\n return t ? `${t}\\n\\n${suffix}` : suffix\n}\n","import type { ChainCategory, MultisignBuildResult, KeyGenSubset } from './types.js'\nimport { getClientIdFromKeyGenResult } from '@continuumdao/continuum-node-sdk'\nimport { mergePurposeText } from './purpose.js'\n\nexport interface MultisignLeg {\n msgHash: string\n msgRaw: string\n destinationAddress: string\n signatureText: string\n audit: Record<string, unknown>\n feeSnapshot: Record<string, unknown>\n proposalTxParams?: Record<string, unknown>\n /** Payable value wei string for first leg only when relevant */\n valueWei?: bigint\n}\n\nexport interface ChainCategoryBuildInput {\n keyGen: KeyGenSubset\n purposeText: string\n purposeSuffix?: string\n destinationChainID: string\n legs: MultisignLeg[]\n extraJSON?: Record<string, unknown>\n /** Top-level destination address (first leg destination if omitted) */\n destinationAddress?: string\n /** Unix seconds (UTC) for mpc-auth multiSignRequest expiryDate. */\n expiryDate?: number\n}\n\nexport interface ChainCategoryModule {\n category: ChainCategory\n finalizeMultisign(input: ChainCategoryBuildInput): MultisignBuildResult\n}\n\n/**\n * Assemble mpc-auth `bodyForSign` from category-built legs.\n * Supports single-tx and batch (messageHashes / messageRawBatch / proposalTxParams).\n */\nexport function finalizeMultisign(input: ChainCategoryBuildInput): MultisignBuildResult {\n const { keyGen, destinationChainID, legs } = input\n if (legs.length === 0) {\n throw new Error('finalizeMultisign requires at least one leg')\n }\n\n const ph = (keyGen.pubkeyhex ?? '').trim()\n if (!ph) throw new Error('keyGen pubKey (pubkeyhex) is required')\n\n const keyList = keyGen.keylist ?? []\n const clientId = getClientIdFromKeyGenResult(keyGen)\n const first = legs[0]!\n\n const messageHashes = legs.map((l) => l.msgHash)\n const messageRawBatch = legs.map((l) => l.msgRaw)\n const batchMeta = legs.map((l) => ({\n destinationAddress: l.destinationAddress,\n signatureText: l.signatureText,\n ...l.audit,\n }))\n\n const proposalTxParams = legs\n .map((l) => l.proposalTxParams)\n .filter((p): p is Record<string, unknown> => p != null && typeof p === 'object')\n\n const extraPayload: Record<string, unknown> = {\n batchMeta,\n ...(input.extraJSON ?? {}),\n }\n const extraJSON = JSON.stringify(extraPayload, (_, v) => (typeof v === 'bigint' ? v.toString() : v))\n\n const bodyForSign: Record<string, unknown> = {\n keyList,\n pubKey: ph,\n msgHash: messageHashes[0],\n msgRaw: first.msgRaw,\n destinationChainID,\n destinationAddress: input.destinationAddress ?? first.destinationAddress,\n extraJSON,\n signatureText: first.signatureText,\n purpose: mergePurposeText(input.purposeText, input.purposeSuffix),\n ...first.feeSnapshot,\n }\n\n if (legs.length > 1) {\n bodyForSign.messageHashes = messageHashes\n bodyForSign.messageRawBatch = messageRawBatch\n }\n\n if (proposalTxParams.length > 0) {\n bodyForSign.proposalTxParams = proposalTxParams\n }\n\n const valueWei = first.valueWei\n if (valueWei != null && valueWei > 0n) {\n bodyForSign.value = valueWei.toString()\n }\n\n if (clientId) bodyForSign.clientId = clientId\n\n if (input.expiryDate != null && input.expiryDate > 0) {\n bodyForSign.expiryDate = Math.floor(input.expiryDate)\n }\n\n return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) }\n}\n\nexport const coreChainCategoryModule: ChainCategoryModule = {\n category: 'evm',\n finalizeMultisign,\n}\n","import { gasLimitFromEstimateAndChainConfig } from '@continuumdao/continuum-node-sdk'\n\n/** Curve router swap gas: chain cap when set, else 12/10 estimate bump. */\nexport function routerSwapGasLimitFromEstimate(\n estimatedGas: bigint,\n chainGasLimit?: number | null,\n): bigint {\n if (chainGasLimit != null && Number.isFinite(chainGasLimit) && chainGasLimit > 0) {\n return gasLimitFromEstimateAndChainConfig(estimatedGas, chainGasLimit)\n }\n return (estimatedGas * 12n + 9n) / 10n\n}\n","import {\n keccak256,\n createPublicClient,\n defineChain,\n http,\n serializeTransaction,\n getAddress,\n parseGwei,\n type Address,\n type PublicClient,\n} from 'viem'\nimport type { MultisignBuildResult } from '../../core/types.js'\nimport { finalizeMultisign, type MultisignLeg } from '../../core/envelope.js'\nimport type { KeyGenSubset } from '../../core/types.js'\nimport {\n fetchChainFeeParams,\n alignEip1559FeesWithLatestBase,\n gweiToDecimalString,\n gasLimitFromEstimateAndChainConfig,\n proposalTxParamsToFeeSnapshot,\n type ProposalTxParams,\n} from '@continuumdao/continuum-node-sdk'\nimport { routerSwapGasLimitFromEstimate } from './routerSwapGas.js'\nimport type { EvmProtocolContext, EvmTxStep } from './types.js'\n\nexport type EvmBatchMetaBuilder = (args: {\n step: EvmTxStep\n index: number\n gasLimit: bigint\n}) => Record<string, unknown>\n\nexport type EvmBuildBatchArgs = {\n context: EvmProtocolContext\n steps: EvmTxStep[]\n purposeSuffix?: string\n buildBatchMeta: EvmBatchMetaBuilder\n /** First leg msgRaw without 0x prefix; defaults to first step calldata */\n firstMsgRawNo0x?: string\n destinationAddress?: Address\n /** Top-level `value` on bodyForSign when the payable amount is not on the first leg */\n payableValueWei?: bigint\n resolveGasLimit?: (args: {\n step: EvmTxStep\n index: number\n estimatedGas: bigint\n publicClient: PublicClient\n }) => Promise<bigint> | bigint\n /** Override default `estimateGas` (e.g. trade-API gas, skip post-approve deposit estimate). */\n estimateGasForStep?: (args: {\n step: EvmTxStep\n index: number\n publicClient: PublicClient\n executor: Address\n }) => Promise<bigint> | bigint\n}\n\n/**\n * Build unsigned EVM txs, estimate gas, serialize, hash — then assemble mpc-auth body via core envelope.\n */\nexport async function buildEvmMultisignBatch(args: EvmBuildBatchArgs): Promise<MultisignBuildResult> {\n const { context, steps } = args\n const {\n chainId,\n rpcUrl,\n executorAddress,\n chainDetail,\n useCustomGas,\n customGasChainDetails,\n keyGen,\n purposeText,\n } = context\n\n if (steps.length === 0) throw new Error('buildEvmMultisignBatch requires at least one step')\n\n const ch = defineChain({\n id: chainId,\n name: 'Destination',\n nativeCurrency: { decimals: 18, name: 'Ether', symbol: 'ETH' },\n rpcUrls: { default: { http: [rpcUrl] } },\n })\n const publicClient = createPublicClient({ chain: ch, transport: http(rpcUrl) })\n\n const feeParams = await fetchChainFeeParams(rpcUrl, chainId)\n const legacy = Boolean(chainDetail?.legacy) || !feeParams.isEip1559\n const latestBaseFeeWei = !legacy\n ? ((await publicClient.getBlock({ blockTag: 'latest' })).baseFeePerGas ?? 0n)\n : 0n\n\n const gasLimitConfig =\n useCustomGas && chainDetail?.gasLimit != null ? Number(chainDetail.gasLimit) : undefined\n const chainGasLimitRouter =\n chainDetail?.gasLimit != null &&\n Number.isFinite(Number(chainDetail.gasLimit)) &&\n Number(chainDetail.gasLimit) > 0\n ? Number(chainDetail.gasLimit)\n : undefined\n const gasFeeMultiplier =\n useCustomGas && chainDetail?.gasMultiplier != null ? Number(chainDetail.gasMultiplier) : undefined\n\n const executor = getAddress(executorAddress)\n const baseNonce = await publicClient.getTransactionCount({ address: executor, blockTag: 'pending' })\n\n const legs: MultisignLeg[] = []\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]!\n const currentNonce = baseNonce + i\n\n let estimatedGas: bigint\n if (args.estimateGasForStep) {\n estimatedGas = await args.estimateGasForStep({ step, index: i, publicClient, executor })\n } else {\n try {\n estimatedGas = await publicClient.estimateGas({\n to: step.to,\n data: step.data,\n value: step.value,\n account: executor,\n })\n } catch {\n estimatedGas = step.fallbackGas ?? 100_000n\n }\n }\n\n let gasLimitI: bigint\n if (args.resolveGasLimit) {\n gasLimitI = await args.resolveGasLimit({ step, index: i, estimatedGas, publicClient })\n } else if (step.routerSwap) {\n gasLimitI = routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimitRouter)\n } else {\n gasLimitI = useCustomGas\n ? gasLimitFromEstimateAndChainConfig(estimatedGas, gasLimitConfig)\n : estimatedGas\n }\n\n let proposalTxParams: ProposalTxParams\n let feeSnapshot: Record<string, unknown>\n let serialized: `0x${string}`\n\n if (legacy) {\n let gasPriceWei = await publicClient.getGasPrice()\n if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {\n gasPriceWei = (gasPriceWei * BigInt(100 + gasFeeMultiplier)) / 100n\n }\n if (useCustomGas && chainDetail?.gasPrice != null && chainDetail.gasPrice > 0) {\n const configured = parseGwei(gweiToDecimalString(Number(chainDetail.gasPrice)))\n if (configured > gasPriceWei) gasPriceWei = configured\n }\n serialized = serializeTransaction({\n type: 'legacy',\n to: step.to,\n data: step.data,\n value: step.value,\n gas: gasLimitI,\n gasPrice: gasPriceWei,\n nonce: currentNonce,\n chainId,\n })\n proposalTxParams = {\n nonce: currentNonce,\n gasLimit: gasLimitI.toString(),\n txType: 'legacy',\n gasPrice: gasPriceWei.toString(),\n }\n feeSnapshot = proposalTxParamsToFeeSnapshot(proposalTxParams)\n } else {\n const fetchedBase = feeParams.baseFeeGwei ?? 0\n const fetchedPriority = feeParams.priorityFeeGwei ?? 0\n const configuredBase =\n useCustomGas && chainDetail?.baseFee != null ? Number(chainDetail.baseFee) : 0\n const configuredPriority =\n useCustomGas && chainDetail?.priorityFee != null ? Number(chainDetail.priorityFee) : 0\n const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase)\n const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority)\n const baseFeeMultiplierPct =\n useCustomGas && chainDetail?.baseFeeMultiplier != null\n ? Math.max(100, Number(chainDetail.baseFeeMultiplier))\n : 100\n const baseComponentGwei = (effectiveBaseFeeGwei * baseFeeMultiplierPct) / 100\n const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei\n let maxPriorityFeePerGas =\n effectivePriorityFeeGwei > 0\n ? parseGwei(gweiToDecimalString(effectivePriorityFeeGwei))\n : parseGwei('1')\n let maxFeePerGas = parseGwei(gweiToDecimalString(maxFeePerGasGwei))\n if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {\n maxPriorityFeePerGas = (maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier)) / 100n\n maxFeePerGas = (maxFeePerGas * BigInt(100 + gasFeeMultiplier)) / 100n\n }\n ;({ maxFeePerGas, maxPriorityFeePerGas } = alignEip1559FeesWithLatestBase(\n maxFeePerGas,\n maxPriorityFeePerGas,\n latestBaseFeeWei,\n ))\n serialized = serializeTransaction({\n type: 'eip1559',\n to: step.to,\n data: step.data,\n value: step.value,\n gas: gasLimitI,\n maxFeePerGas,\n maxPriorityFeePerGas,\n nonce: currentNonce,\n chainId,\n })\n proposalTxParams = {\n nonce: currentNonce,\n gasLimit: gasLimitI.toString(),\n txType: 'eip1559',\n maxFeePerGas: maxFeePerGas.toString(),\n maxPriorityFeePerGas: maxPriorityFeePerGas.toString(),\n }\n feeSnapshot = i === 0 ? proposalTxParamsToFeeSnapshot(proposalTxParams) : {}\n }\n\n const h = keccak256(serialized)\n const msgHash = h.startsWith('0x') ? h.slice(2) : h\n\n const batchMetaExtra = args.buildBatchMeta({ step, index: i, gasLimit: gasLimitI })\n\n legs.push({\n msgHash,\n msgRaw: i === 0 && args.firstMsgRawNo0x != null ? args.firstMsgRawNo0x : serialized,\n destinationAddress: step.to,\n signatureText:\n typeof batchMetaExtra.signatureText === 'string'\n ? batchMetaExtra.signatureText\n : JSON.stringify(batchMetaExtra.signatureText ?? {}),\n audit: batchMetaExtra,\n feeSnapshot: i === 0 ? feeSnapshot : {},\n proposalTxParams,\n valueWei: i === 0 ? step.value : undefined,\n })\n\n if (i === 0 && args.firstMsgRawNo0x != null) {\n legs[0]!.msgRaw = args.firstMsgRawNo0x\n }\n }\n\n const extraJSON: Record<string, unknown> = {}\n if (useCustomGas && customGasChainDetails && Object.keys(customGasChainDetails).length > 0) {\n extraJSON.customGasChainDetails = customGasChainDetails\n }\n\n const result = finalizeMultisign({\n keyGen: keyGen as KeyGenSubset,\n purposeText,\n purposeSuffix: args.purposeSuffix,\n destinationChainID: String(chainId),\n destinationAddress: args.destinationAddress ?? steps[0]!.to,\n legs,\n extraJSON: Object.keys(extraJSON).length > 0 ? extraJSON : undefined,\n expiryDate: context.expiryDate,\n })\n const pv = args.payableValueWei\n if (pv != null && pv > 0n) {\n result.bodyForSign.value = pv.toString()\n }\n return result\n}\n\nexport const evmChainCategoryModule = {\n category: 'evm' as const,\n finalizeMultisign,\n buildEvmMultisignBatch,\n}\n","/** Parse chain id for comparisons (decimal, 0x hex, CAIP-2 eip155:N, bigint). */\nexport function parseEvmChainIdToNumber(chainId: string | number | bigint | null | undefined): number {\n if (chainId == null) return Number.NaN\n if (typeof chainId === 'bigint') {\n const n = Number(chainId)\n return Number.isSafeInteger(n) && n >= 0 ? n : Number.NaN\n }\n if (typeof chainId === 'number') {\n return Number.isInteger(chainId) && chainId >= 0 ? chainId : Number.NaN\n }\n const t = String(chainId).trim()\n if (!t) return Number.NaN\n const low = t.toLowerCase()\n if (low.startsWith('eip155:')) {\n const rest = t.slice('eip155:'.length).trim()\n const n = Number.parseInt(rest, 10)\n return Number.isNaN(n) || n < 0 ? Number.NaN : n\n }\n if (low.startsWith('0x')) {\n return Number.parseInt(t, 16)\n }\n return Number.parseInt(t, 10)\n}\n","import { formatUnits, parseUnits } from 'viem'\n\n/**\n * Canonical human decimal string for a token amount (truncate to token decimals via wei round-trip).\n * Used by Curve router and multisign dialogs across protocols.\n */\nexport function normalizeHumanDecimalAmount(raw: string, tokenDecimals: number): string {\n const t = raw.trim().replace(/,/g, '')\n if (!t) return ''\n if (!Number.isInteger(tokenDecimals) || tokenDecimals < 0 || tokenDecimals > 18) {\n throw new Error('Invalid token decimals for amount normalization.')\n }\n const wei = parseUnits(t, tokenDecimals)\n return formatUnits(wei, tokenDecimals)\n}\n\n/** @deprecated Prefer normalizeHumanDecimalAmount; kept for Curve router parity. */\nexport const normalizeCurveRouterAmountString = normalizeHumanDecimalAmount\n","import {\n createPublicClient,\n defineChain,\n encodeFunctionData,\n getAddress,\n http,\n parseAbi,\n type Address,\n type PublicClient,\n} from 'viem'\nimport type { EvmTxStep } from './types.js'\n\nconst erc20AllowanceAbi = parseAbi([\n 'function allowance(address owner, address spender) view returns (uint256)',\n 'function decimals() view returns (uint8)',\n])\nconst erc20ApproveAbi = parseAbi(['function approve(address spender, uint256 amount) returns (bool)'])\n\nexport function publicClientForRpc(chainId: number, rpcUrl: string): PublicClient {\n const ch = defineChain({\n id: chainId,\n name: `chain-${chainId}`,\n nativeCurrency: { decimals: 18, name: 'Ether', symbol: 'ETH' },\n rpcUrls: { default: { http: [rpcUrl.trim()] } },\n })\n return createPublicClient({ chain: ch, transport: http(rpcUrl.trim()) })\n}\n\n/**\n * Resolve ERC-20 decimals: on-chain `decimals()` is authoritative; optional registry/API hints\n * are validated and logged when they disagree (common when registry is stale).\n */\nexport async function resolveErc20Decimals(args: {\n publicClient: PublicClient\n token: Address\n registryDecimals?: number\n apiDecimals?: number\n}): Promise<number> {\n const token = getAddress(args.token)\n const onChain = await args.publicClient.readContract({\n address: token,\n abi: erc20AllowanceAbi,\n functionName: 'decimals',\n })\n const n = typeof onChain === 'bigint' ? Number(onChain) : Number(onChain)\n if (!Number.isFinite(n) || n < 0 || n > 36) {\n throw new Error(`Invalid on-chain decimals for ${token}.`)\n }\n for (const hint of [args.registryDecimals, args.apiDecimals]) {\n if (hint != null && Number.isFinite(hint) && hint !== n) {\n /* prefer on-chain — hints from token registry / fetch rows may be stale */\n }\n }\n return n\n}\n\nexport type ConditionalApproveStep = {\n to: Address\n data: `0x${string}`\n value: bigint\n fallbackGas?: bigint\n}\n\n/**\n * Standard deposit-path approve batch: skip when allowance sufficient; reset-to-zero when needed.\n */\nexport async function buildConditionalErc20ApproveSteps(args: {\n publicClient: PublicClient\n token: Address\n spender: Address\n owner: Address\n amountWei: bigint\n fallbackGas?: bigint\n}): Promise<ConditionalApproveStep[]> {\n if (args.amountWei <= 0n) return []\n const token = getAddress(args.token)\n const spender = getAddress(args.spender)\n const owner = getAddress(args.owner)\n const fallback = args.fallbackGas ?? 100_000n\n\n const allowance = await args.publicClient.readContract({\n address: token,\n abi: erc20AllowanceAbi,\n functionName: 'allowance',\n args: [owner, spender],\n })\n if (allowance >= args.amountWei) return []\n\n const steps: ConditionalApproveStep[] = []\n if (allowance > 0n) {\n steps.push({\n to: token,\n data: encodeFunctionData({ abi: erc20ApproveAbi, functionName: 'approve', args: [spender, 0n] }),\n value: 0n,\n fallbackGas: fallback,\n })\n }\n steps.push({\n to: token,\n data: encodeFunctionData({\n abi: erc20ApproveAbi,\n functionName: 'approve',\n args: [spender, args.amountWei],\n }),\n value: 0n,\n fallbackGas: fallback,\n })\n return steps\n}\n\nexport function approveStepsToEvmTxSteps(steps: ConditionalApproveStep[]): EvmTxStep[] {\n return steps.map((s) => ({\n to: s.to,\n data: s.data,\n value: s.value,\n fallbackGas: s.fallbackGas,\n }))\n}\n","/** CoinGecko asset platform id by mainnet chainId (contract price endpoint). */\nexport const COINGECKO_PLATFORM_BY_CHAIN_ID: Record<string, string> = {\n '1': 'ethereum',\n '56': 'binance-smart-chain',\n '137': 'polygon-pos',\n '42161': 'arbitrum-one',\n '10': 'optimistic-ethereum',\n '43114': 'avalanche',\n '8453': 'base',\n '324': 'zk-sync-era',\n '42220': 'celo',\n '250': 'fantom',\n '100': 'gnosis',\n '204': 'op-bnb',\n '534352': 'scroll',\n '5000': 'mantle',\n '169': 'manta-pacific',\n '1116': 'core',\n '30': 'rootstock',\n '288': 'boba',\n '1088': 'metis-andromeda',\n '34443': 'mode',\n '80084': 'berachain',\n '146': 'sonic',\n '60808': 'bob-network',\n '80094': 'berachain',\n '130': 'unichain',\n '57073': 'ink',\n '999': 'hyperevm',\n '239': 'tac',\n '9745': 'plasma',\n '1923': 'swellchain',\n '59144': 'linea',\n '81457': 'blast',\n '7777777': 'zora',\n}\n\nexport function coingeckoPlatformForChainId(chainId: string | number): string | undefined {\n return COINGECKO_PLATFORM_BY_CHAIN_ID[String(chainId).trim()]\n}\n"]}
|
package/dist/core/index.cjs
CHANGED
|
@@ -61,6 +61,9 @@ function finalizeMultisign(input) {
|
|
|
61
61
|
bodyForSign.value = valueWei.toString();
|
|
62
62
|
}
|
|
63
63
|
if (clientId) bodyForSign.clientId = clientId;
|
|
64
|
+
if (input.expiryDate != null && input.expiryDate > 0) {
|
|
65
|
+
bodyForSign.expiryDate = Math.floor(input.expiryDate);
|
|
66
|
+
}
|
|
64
67
|
return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
|
|
65
68
|
}
|
|
66
69
|
var coreChainCategoryModule = {
|
|
@@ -198,6 +201,7 @@ function buildEip712MultisignBody(args) {
|
|
|
198
201
|
destinationChainID: args.destinationChainID,
|
|
199
202
|
destinationAddress: args.destinationAddress,
|
|
200
203
|
extraJSON,
|
|
204
|
+
expiryDate: args.expiryDate,
|
|
201
205
|
legs: [
|
|
202
206
|
{
|
|
203
207
|
msgHash: msgHashNo0x(digest),
|
|
@@ -216,13 +220,34 @@ function buildEip712MultisignBody(args) {
|
|
|
216
220
|
});
|
|
217
221
|
}
|
|
218
222
|
|
|
223
|
+
// src/core/expiry.ts
|
|
224
|
+
var DEFAULT_DEFI_MULTISIGN_EXPIRY_SECONDS = 30 * 60;
|
|
225
|
+
var DEFI_PROTOCOLS_WITH_30MIN_EXPIRY = /* @__PURE__ */ new Set([
|
|
226
|
+
"uniswap-v4",
|
|
227
|
+
"gmx",
|
|
228
|
+
"hyperliquid",
|
|
229
|
+
"curve-dao"
|
|
230
|
+
]);
|
|
231
|
+
function defiMultisignExpiryUnixSeconds(protocolId, explicitExpiryDate) {
|
|
232
|
+
if (typeof explicitExpiryDate === "number" && Number.isFinite(explicitExpiryDate) && explicitExpiryDate > 0) {
|
|
233
|
+
return Math.floor(explicitExpiryDate);
|
|
234
|
+
}
|
|
235
|
+
if (protocolId && DEFI_PROTOCOLS_WITH_30MIN_EXPIRY.has(protocolId)) {
|
|
236
|
+
return Math.floor(Date.now() / 1e3) + DEFAULT_DEFI_MULTISIGN_EXPIRY_SECONDS;
|
|
237
|
+
}
|
|
238
|
+
return void 0;
|
|
239
|
+
}
|
|
240
|
+
|
|
219
241
|
Object.defineProperty(exports, "firstClientIdFromKeyGen", {
|
|
220
242
|
enumerable: true,
|
|
221
243
|
get: function () { return continuumNodeSdk.getClientIdFromKeyGenResult; }
|
|
222
244
|
});
|
|
245
|
+
exports.DEFAULT_DEFI_MULTISIGN_EXPIRY_SECONDS = DEFAULT_DEFI_MULTISIGN_EXPIRY_SECONDS;
|
|
246
|
+
exports.DEFI_PROTOCOLS_WITH_30MIN_EXPIRY = DEFI_PROTOCOLS_WITH_30MIN_EXPIRY;
|
|
223
247
|
exports.EIP712_SIGN_REQUEST_KIND = EIP712_SIGN_REQUEST_KIND;
|
|
224
248
|
exports.buildEip712MultisignBody = buildEip712MultisignBody;
|
|
225
249
|
exports.coreChainCategoryModule = coreChainCategoryModule;
|
|
250
|
+
exports.defiMultisignExpiryUnixSeconds = defiMultisignExpiryUnixSeconds;
|
|
226
251
|
exports.finalizeMultisign = finalizeMultisign;
|
|
227
252
|
exports.getAaveGraphqlProxyUrl = getAaveGraphqlProxyUrl;
|
|
228
253
|
exports.getActionsByChainCategory = getActionsByChainCategory;
|