@symmio/trading-core 3.5.0 → 3.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/gasless/delegation-preflight.d.ts +22 -0
  2. package/dist/gasless/delegation-preflight.d.ts.map +1 -1
  3. package/dist/gasless/delegation-preflight.js +34 -19
  4. package/dist/gasless/delegation-preflight.js.map +1 -1
  5. package/dist/index.d.ts +12 -2
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +82 -79
  8. package/dist/pools/index.d.ts +1 -0
  9. package/dist/pools/index.d.ts.map +1 -1
  10. package/dist/pools/token-price/get-token-price.d.ts +71 -0
  11. package/dist/pools/token-price/get-token-price.d.ts.map +1 -0
  12. package/dist/pools/token-price/get-token-price.js +30 -0
  13. package/dist/pools/token-price/get-token-price.js.map +1 -0
  14. package/dist/pools/token-price/index.d.ts +4 -0
  15. package/dist/pools/token-price/index.d.ts.map +1 -0
  16. package/dist/pools/token-price/query.d.ts +52 -0
  17. package/dist/pools/token-price/query.d.ts.map +1 -0
  18. package/dist/pools/token-price/query.js +29 -0
  19. package/dist/pools/token-price/query.js.map +1 -0
  20. package/dist/pools/token-price/to-token-price.d.ts +14 -0
  21. package/dist/pools/token-price/to-token-price.d.ts.map +1 -0
  22. package/dist/pools/token-price/to-token-price.js +8 -0
  23. package/dist/pools/token-price/to-token-price.js.map +1 -0
  24. package/dist/pools/transactions/get-pool-transactions.d.ts +59 -17
  25. package/dist/pools/transactions/get-pool-transactions.d.ts.map +1 -1
  26. package/dist/pools/transactions/get-pool-transactions.js +7 -4
  27. package/dist/pools/transactions/get-pool-transactions.js.map +1 -1
  28. package/dist/pools/transactions/query.d.ts +6 -2
  29. package/dist/pools/transactions/query.d.ts.map +1 -1
  30. package/dist/pools/transactions/query.js +12 -13
  31. package/dist/pools/transactions/query.js.map +1 -1
  32. package/dist/pools/transactions/to-pool-transaction.d.ts +7 -0
  33. package/dist/pools/transactions/to-pool-transaction.d.ts.map +1 -1
  34. package/dist/pools/transactions/to-pool-transaction.js +3 -1
  35. package/dist/pools/transactions/to-pool-transaction.js.map +1 -1
  36. package/dist/pools/types/generated/listing-backend.js +8 -8
  37. package/dist/pools/types/generated/listing-backend.js.map +1 -1
  38. package/dist/pools/types.d.ts +53 -10
  39. package/dist/pools/types.d.ts.map +1 -1
  40. package/dist/pools/types.js +6 -4
  41. package/dist/pools/types.js.map +1 -1
  42. package/dist/solvers/instant-close/instant-close/instant-close.d.ts +8 -1
  43. package/dist/solvers/instant-close/instant-close/instant-close.d.ts.map +1 -1
  44. package/dist/solvers/instant-close/instant-close/instant-close.js +40 -32
  45. package/dist/solvers/instant-close/instant-close/instant-close.js.map +1 -1
  46. package/dist/solvers/instant-close/instant-close-bulk/instant-close-bulk.d.ts +7 -1
  47. package/dist/solvers/instant-close/instant-close-bulk/instant-close-bulk.d.ts.map +1 -1
  48. package/dist/solvers/instant-close/instant-close-bulk/instant-close-bulk.js +48 -40
  49. package/dist/solvers/instant-close/instant-close-bulk/instant-close-bulk.js.map +1 -1
  50. package/dist/solvers/instant-close/instant-close-bulk-auto/instant-close-bulk-auto.d.ts +4 -2
  51. package/dist/solvers/instant-close/instant-close-bulk-auto/instant-close-bulk-auto.d.ts.map +1 -1
  52. package/dist/solvers/instant-close/instant-close-bulk-auto/instant-close-bulk-auto.js +1 -0
  53. package/dist/solvers/instant-close/instant-close-bulk-auto/instant-close-bulk-auto.js.map +1 -1
  54. package/dist/solvers/instant-close/prepare-instant-close-params/prepare-instant-close-params.d.ts +4 -2
  55. package/dist/solvers/instant-close/prepare-instant-close-params/prepare-instant-close-params.d.ts.map +1 -1
  56. package/dist/solvers/instant-close/prepare-instant-close-params/prepare-instant-close-params.js +2 -1
  57. package/dist/solvers/instant-close/prepare-instant-close-params/prepare-instant-close-params.js.map +1 -1
  58. package/dist/solvers/instant-open/instant-open/adapters/enigma-instant-open.d.ts +2 -0
  59. package/dist/solvers/instant-open/instant-open/adapters/enigma-instant-open.d.ts.map +1 -1
  60. package/dist/solvers/instant-open/instant-open/adapters/enigma-instant-open.js +64 -56
  61. package/dist/solvers/instant-open/instant-open/adapters/enigma-instant-open.js.map +1 -1
  62. package/dist/solvers/instant-open/instant-open/adapters/rasa-instant-open.d.ts +2 -0
  63. package/dist/solvers/instant-open/instant-open/adapters/rasa-instant-open.d.ts.map +1 -1
  64. package/dist/solvers/instant-open/instant-open/adapters/rasa-instant-open.js +51 -43
  65. package/dist/solvers/instant-open/instant-open/adapters/rasa-instant-open.js.map +1 -1
  66. package/dist/solvers/instant-open/instant-open/instant-open.d.ts +6 -0
  67. package/dist/solvers/instant-open/instant-open/instant-open.d.ts.map +1 -1
  68. package/dist/solvers/instant-open/instant-open/instant-open.js.map +1 -1
  69. package/dist/solvers/instant-open/instant-open/types.d.ts +2 -1
  70. package/dist/solvers/instant-open/instant-open/types.d.ts.map +1 -1
  71. package/dist/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.d.ts +3 -1
  72. package/dist/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.d.ts.map +1 -1
  73. package/dist/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.js +2 -1
  74. package/dist/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.js.map +1 -1
  75. package/dist/solvers/shared/index.d.ts +1 -0
  76. package/dist/solvers/shared/index.d.ts.map +1 -1
  77. package/dist/solvers/shared/instant-delegation-preflight.d.ts +65 -0
  78. package/dist/solvers/shared/instant-delegation-preflight.d.ts.map +1 -0
  79. package/dist/solvers/shared/instant-delegation-preflight.js +34 -0
  80. package/dist/solvers/shared/instant-delegation-preflight.js.map +1 -0
  81. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../src/pools/types.ts"],"sourcesContent":["import type { MarketStatus } from \"./types/generated/listing-backend\";\n\n/**\n * Fixed-point scale of every money and rate field the listing service returns.\n *\n * The service reports these as decimal **strings** at 18 decimals, regardless of\n * the token's own decimals or the collateral's (`\"1000000000000000000\"` = `1`).\n * The SDK keeps them as `bigint` at this scale so nothing is lost; format with\n * `formatUnits(value, LISTING_VALUE_DECIMALS)` from `@symmio/utils/decimal` at\n * the display edge.\n *\n * **What the descaled number means differs by field.** For money fields it is a\n * USD amount (`1e18` = `$1`). For rate fields it is **already a percentage**\n * (`1e18` = `1%`), *not* a fraction — do **not** multiply by 100 to render one.\n *\n * Verified against the live service: a pool with `tvl` `177.78` and `reward_24h`\n * `0.0055` annualizes to `1.1295%`, and its `apr_24h` descales to exactly\n * `1.1295`.\n */\nexport const LISTING_VALUE_DECIMALS = 18;\n\n/**\n * Lifecycle status of a market in the permissionless-listing service.\n *\n * The service — not the chain — owns this state machine. A market becomes\n * tradable only at {@link ListingMarketStatus.LISTED}; before that it has no\n * `symbolId` and no solver market behind it.\n *\n * - `WAITING_FOR_DEPOSIT` — application accepted, the listing deposit has not\n * landed at the custodial address yet.\n * - `UNDER_REVIEW` — deposit received, awaiting the operator's decision.\n * - `REJECTED` — the operator declined the listing; the deposit is refundable.\n * - `LISTED` — live and tradable; `symbolId` is assigned.\n * - `DELISTED` — was live, has since been withdrawn from trading.\n */\nexport enum ListingMarketStatus {\n WAITING_FOR_DEPOSIT = \"waiting_for_deposit\",\n UNDER_REVIEW = \"under_review\",\n REJECTED = \"rejected\",\n LISTED = \"listed\",\n DELISTED = \"delisted\",\n}\n\n/**\n * Why the inventory service has locked a market's pool against new deposits.\n *\n * A lock blocks deposits only: trading, withdrawals, claims and every other\n * flow stay available. It is also orthogonal to {@link ListingMarketStatus}: a\n * `LISTED` market can be locked, and the lock lifts without the lifecycle\n * status moving. The catalogue\n * row carries only the flag ({@link ListingMarket.isLocked}); the reasons are on\n * the detail read ({@link ListingMarketDetail.lockReasons}).\n *\n * - `LIQUIDITY_EXPOSURE` — locked on the service's liquidity-exposure limit.\n * - `LOW_TVL` — the pool's TVL is below the service's threshold.\n * - `PRICE_UNAVAILABLE` — the service has no price for the token.\n * - `SHORT_CIRCUIT` — the service's short-circuit guard tripped.\n * - `MANUAL` — an operator locked the market by hand.\n * - `UNKNOWN` — a reason this SDK release does not recognize. The mapper folds\n * every unrecognized wire value here rather than throwing, so a newer backend\n * cannot break the read.\n */\nexport enum MarketLockReason {\n LIQUIDITY_EXPOSURE = \"LIQUIDITY_EXPOSURE\",\n LOW_TVL = \"LOW_TVL\",\n PRICE_UNAVAILABLE = \"PRICE_UNAVAILABLE\",\n SHORT_CIRCUIT = \"SHORT_CIRCUIT\",\n MANUAL = \"MANUAL\",\n UNKNOWN = \"UNKNOWN\",\n}\n\n/**\n * Chains the listing service accepts a listing deposit on.\n *\n * This is the chain the **token** lives on and where its listing collateral was\n * deposited — it is **not** the chain the resulting market trades on. A market\n * whose token is on Solana or BSC still trades on the SYMMIO deployment the\n * listing service is configured for.\n *\n * `SOLANA = 0` is a sentinel the service uses for its one non-EVM chain, not a\n * real chain id: a `ListingMarket` on it carries a base58 `contractAddress`, so\n * never feed one to an EVM address helper without checking `chainId` first.\n */\nexport enum ListingDepositChainId {\n /** Sentinel for Solana — not an EVM chain id. Addresses are base58. */\n SOLANA = 0,\n BSC = 56,\n BASE = 8453,\n SONIC = 146,\n ARBITRUM_ONE = 42161,\n HYPER_EVM = 999,\n}\n\n/**\n * The same metric measured over each trailing window the listing service\n * reports.\n *\n * Every entry is a `bigint` at {@link LISTING_VALUE_DECIMALS}, or `null` when\n * the service has no value for that window — a young market has no 30-day\n * figure, and `null` means *absent*, never zero.\n */\nexport interface ListingTrailingWindows {\n /** Trailing 1 hour. */\n h1: bigint | null;\n /** Trailing 6 hours. */\n h6: bigint | null;\n /** Trailing 24 hours. */\n h24: bigint | null;\n /** Trailing 30 days. */\n d30: bigint | null;\n}\n\n/**\n * A metric the service reports over the trailing windows **and** since listing.\n *\n * Only the two APY series carry a lifetime column; APR does not, which is why\n * `lifetime` lives here rather than on {@link ListingTrailingWindows}.\n */\nexport interface ListingApyWindows extends ListingTrailingWindows {\n /** Since the market was listed. */\n lifetime: bigint | null;\n}\n\n/**\n * One market in the permissionless-listing catalog — a row of the pools list.\n *\n * Money and rate fields are `bigint` at {@link LISTING_VALUE_DECIMALS}; `null`\n * means the service reported no value, which is distinct from zero.\n */\nexport interface ListingMarket {\n /**\n * The listed token's contract address on {@link ListingMarket.chainId}.\n *\n * Typed as `string`, **not** viem's `Address`: Solana listings\n * (`chainId === ListingDepositChainId.SOLANA`) carry a base58 address that is\n * not 0x-prefixed. This is also the id used to address a single market in the\n * rest of the listing API.\n */\n contractAddress: string;\n /** Chain the token lives on and its listing deposit was made on. */\n chainId: ListingDepositChainId;\n /**\n * The solver market id this listing trades under, or `null` when it has none\n * yet. Assigned when the market reaches {@link ListingMarketStatus.LISTED};\n * everything downstream (prices, notional caps, quotes, subgraph rows) keys\n * off it, so a `null` here means the market is not tradable.\n */\n symbolId: number | null;\n /** Token ticker, e.g. `\"SYMM\"`. */\n tokenTicker: string;\n /** Token display name, e.g. `\"Symmio\"`. */\n tokenName: string;\n /** Maximum leverage the market allows, as a whole multiplier (`20` = 20x). */\n maxLeverage: number;\n /** Token market capitalization, in USD. */\n marketCap: bigint | null;\n /** Trailing 24-hour trading volume, in USD. */\n vol24h: bigint | null;\n /** Total value locked in the market's pool, in USD. */\n tvl: bigint | null;\n /** Notional the solver will still take on this market, in USD. */\n liquidity: bigint | null;\n /** Notional currently open on this market, in USD. */\n openInterest: bigint | null;\n /** LP rewards accrued over the trailing 24 hours, in USD. */\n reward24h: bigint | null;\n /** Headline APR: a percentage already (`1e18` = `1%`), not a fraction — render it without multiplying by 100. */\n apr: bigint | null;\n /**\n * APR broken out per trailing window, same units as {@link ListingMarket.apr}.\n * There is no lifetime APR — use {@link ListingMarket.apr} for the headline.\n */\n aprByWindow: ListingTrailingWindows;\n /** APY attributed to TVL growth, per window: a percentage already (`1e18` = `1%`), not a fraction — render it without multiplying by 100. */\n tvlDrivenApy: ListingApyWindows;\n /** APY attributed to token price movement, per window: a percentage already (`1e18` = `1%`), not a fraction — render it without multiplying by 100. */\n priceDrivenApy: ListingApyWindows;\n /** When the market went live, as a Unix timestamp in **seconds**. `null` before it is listed. */\n listingTime: number | null;\n /** Where the market sits in the listing lifecycle. */\n marketStatus: ListingMarketStatus;\n /**\n * Whether the inventory service currently has this market's pool locked\n * against new deposits. Only deposits are blocked; trading, withdrawals and\n * every other flow stay available. Independent of\n * {@link ListingMarket.marketStatus}: a `LISTED` market can be locked. The row\n * carries only the flag; the reasons are on\n * {@link ListingMarketDetail.lockReasons}.\n */\n isLocked: boolean;\n}\n\n/** One page of {@link ListingMarket} rows, with the totals needed to paginate. */\nexport interface ListingMarketPage {\n /** Total rows matching the query across all pages. */\n total: number;\n /** Page size the service applied. */\n limit: number;\n /** Row offset of this page. */\n offset: number;\n /** The rows themselves. */\n items: ListingMarket[];\n}\n\n/**\n * A {@link ListingMarket} enriched with the signed-in user's position in it — one\n * row of \"Your Pools\", the markets that generated a deposit address for the user.\n */\nexport interface UserListingMarket extends ListingMarket {\n /** The user's current deposit into this pool, in USD (18-dec bigint). `null` when the deposit address exists but nothing has been deposited yet. */\n userDeposit: bigint | null;\n /** The user's share of the pool, as a percentage number (not 18-dec scaled). */\n userSharePercentage: number;\n /** The user's accrued revenue from this pool, in USD (18-dec bigint), or `null` when absent. */\n userRevenue: bigint | null;\n}\n\n/** One page of {@link UserListingMarket} rows, with the totals needed to paginate. */\nexport interface UserListingMarketPage {\n /** Total rows matching the query across all pages. */\n total: number;\n /** Page size the service applied. */\n limit: number;\n /** Row offset of this page. */\n offset: number;\n /** The rows themselves. */\n items: UserListingMarket[];\n}\n\n/**\n * The signed-in user's LP position and profit in a single pool — the authed\n * per-token read behind a pool's \"your position\" panel.\n *\n * Every field is a `bigint` at {@link LISTING_VALUE_DECIMALS} (18), independent\n * of the token's or collateral's own decimals; format with\n * `formatUnits(value, LISTING_VALUE_DECIMALS)` at the display edge. An absent\n * figure is normalized to `0n`, not `null`.\n */\nexport interface UserPoolProfit {\n /** LP balance valued in the pool's token units, 18-dec bigint. */\n userBalanceInTokens: bigint;\n /** LP balance valued in USDC, 18-dec bigint USD. */\n userBalanceInUsdc: bigint;\n /** Rewards the user can claim now, 18-dec bigint USD. */\n claimableReward: bigint;\n /** Rewards already claimed, 18-dec bigint USD. */\n claimedReward: bigint;\n /** Token amount the user deposited, 18-dec bigint. */\n userDepositedTokenAmount: bigint;\n /** The user's LP shares, 18-dec bigint. */\n userLpAmount: bigint;\n /** LP shares queued for withdrawal (the pending-withdrawal amount), 18-dec bigint. */\n pendingWithdrawLpAmount: bigint;\n /**\n * LP shares free to withdraw right now — `userLpAmount − pendingWithdrawLpAmount`,\n * floored at `0n`. This is the ceiling a withdrawal (`withdrawLp`) may request;\n * the shares already counted in {@link UserPoolProfit.pendingWithdrawLpAmount}\n * are spoken for. Derived by the SDK, not a field the service returns. 18-dec\n * bigint.\n */\n availableLpAmount: bigint;\n}\n\n/**\n * The receipt returned by `claimProfit` — the outcome of a `/v2/claim` request.\n *\n * The claim is synchronous: a `200` means the USDC was moved to the target\n * sub-account. `amountClaimed` is the moved figure normalized to a `bigint` at\n * `LISTING_VALUE_DECIMALS` (18), `claimRequestId` references the claim in the\n * service, and `transactionHash` is the on-chain transfer hash when the service\n * has one (`null` otherwise).\n */\nexport interface PoolClaimResult {\n /** The service's status string, e.g. `\"ok\"`. */\n status: string;\n /** USDC moved to the sub-account, 18-dec bigint USD. */\n amountClaimed: bigint;\n /** Claim id — reference it to restore or look up the claim later. */\n claimRequestId: string;\n /** On-chain hash of the claim transfer, or `null` when the service has none yet. */\n transactionHash: string | null;\n}\n\n/**\n * One past pool-reward claim, from the user's claim history (`getClaimHistory`).\n *\n * The internal `wallet_id` / `market_id` UUIDs the service carries are dropped —\n * they address rows in the backend, not anything a consumer renders.\n */\nexport interface PoolClaim {\n /** Claim id — reference it to look the claim up in the service. */\n claimRequestId: string;\n /** Sub-account address that received the claimed USDC. */\n accountAddress: string;\n /** USDC claimed, 18-dec bigint USD. */\n amount: bigint;\n /** On-chain hash of the claim transfer, or `null` when the service has none. */\n transactionHash: string | null;\n /** When the claim was created, Unix **seconds**. */\n time: number;\n}\n\n/** One page of {@link PoolClaim} rows — the signed-in user's claim history. */\nexport interface PoolClaimHistoryPage {\n /** Total claims matching the query across all pages — what a pager divides. */\n count: number;\n /** The claims themselves, newest first. */\n items: PoolClaim[];\n}\n\n/**\n * The receipt returned by `cancelWithdraw` — the outcome of cancelling a queued\n * LP withdrawal.\n */\nexport interface PoolCancelWithdrawResult {\n /** The affected withdrawal's transaction id, echoed by the service. */\n transactionId: string;\n /**\n * The withdrawal's resulting status, e.g. `\"canceled\"`. Carried through as the\n * service's raw string — its enum (`canceled` | `pending` | `transferred` | …)\n * is a superset of {@link PoolTransactionStatus}, so it is not narrowed to it.\n */\n status: string;\n}\n\n/**\n * The receipt returned by `refundMarket` — the outcome of refunding a deposit on\n * a rejected market.\n */\nexport interface PoolRefundResult {\n /** On-chain hash of the refund transfer. */\n transactionHash: string;\n}\n\n/**\n * The signed-in user's **retry allowance** for one rejected market\n * (`getRetryListingInfo`) — how many listing retries remain and the cooldown\n * before the next.\n */\nexport interface RetryListingInfo {\n /** Maximum retries allowed per market. */\n retryLimit: number;\n /** Retries the user has left for this market. */\n remainingRetries: number;\n /** Seconds until the next retry is allowed, or `null` when no cooldown is in effect. */\n remainingCooldownSeconds: number | null;\n}\n\n/**\n * The result of `retryListing` — the retry allowance left after re-submitting a\n * rejected market.\n */\nexport interface RetryListingResult {\n /** Maximum retries allowed per market. */\n retryLimit: number;\n /** Retries left after this one. */\n remainingRetries: number;\n /** Seconds before the next retry is allowed. */\n cooldownSeconds: number;\n}\n\n/**\n * The signed-in user's deposit wallet for one market — the get-or-create result\n * of the authed `/v2/market/deposit-address` endpoint. This is the address the\n * user sends funds to in order to deposit into the market's pool.\n */\nexport interface MarketDepositAddress {\n /** The market's token contract address (EVM 0x… or Solana base58). */\n tokenContractAddress: string;\n /** The signed-in user this deposit wallet belongs to. */\n userAddress: string;\n /** The market's deposit chain. */\n depositChain: ListingDepositChainId;\n /** The deposit address — where the user sends funds to deposit into this market. `null` when the service returned none. */\n depositAddress: string | null;\n /** The token's on-chain decimals. */\n tokenDecimal: number;\n /** The market's listing lifecycle status. */\n marketStatus: ListingMarketStatus;\n}\n\n/**\n * The listing-pipeline status of a single market — the normalized result of\n * `getListingStatus`, keyed by the market's token address and deposit chain.\n *\n * `marketStatus` is the overall lifecycle status (the same machine as\n * {@link ListingMarketStatus}); the remaining fields describe where the listing\n * is in the backend's step pipeline and whether the current step is retrying or\n * has errored.\n */\nexport interface ListingStatus {\n /** Overall lifecycle status of the market, mapped from the service's `market_status`. */\n marketStatus: ListingMarketStatus;\n /** The step the listing pipeline is currently on, or `null` when it is not in a step. */\n currentStep: string | null;\n /** The ordered pipeline steps the listing moves through. */\n steps: string[];\n /** Error code reported for the current step, or `null` when there is no error. */\n errorCode: number | null;\n /** Human-readable detail for the current step's error, or `null`. */\n errorDetail: string | null;\n /** How many times the current step has been retried. */\n retryCount: number;\n /** The maximum retries allowed for the current step. */\n retryLimit: number;\n}\n\n/**\n * The protocol's global new-market listing cap for the current rolling weekly\n * window — how many pools may still be listed across the protocol before the\n * window resets.\n */\nexport interface WeeklyListingLimit {\n /** Total new-market listings allowed per rolling weekly window. */\n limit: number;\n /** Listings still available in the current window — `0` means no more pools can be listed until reset. */\n remaining: number;\n /** When the window resets, as the Unix timestamp the service returns (`reset_at`). */\n resetAt: number;\n}\n\n/**\n * Server-side sort keys accepted by `getListingMarkets`.\n *\n * Mirrors the service's `sort_by` enum verbatim — snake_case, not the SDK's\n * camelCase field names — because the value is a wire literal, and translating\n * it would break silently the moment the service adds a key.\n *\n * Note the two bare keys: `tvl_driven_apy` and `price_driven_apy` have no\n * matching bare response field. They sort by the **lifetime** column\n * (`tvl_driven_apy_lifetime` / `price_driven_apy_lifetime`).\n */\nexport type ListingMarketSortField =\n | \"liquidity\"\n | \"tvl\"\n | \"market_cap\"\n | \"vol24h\"\n | \"open_interest\"\n | \"apr_1h\"\n | \"apr_6h\"\n | \"apr_24h\"\n | \"apr_30d\"\n | \"reward_24h\"\n | \"apr\"\n | \"tvl_driven_apy_1h\"\n | \"tvl_driven_apy_6h\"\n | \"tvl_driven_apy_24h\"\n | \"tvl_driven_apy_30d\"\n | \"tvl_driven_apy\"\n | \"price_driven_apy_1h\"\n | \"price_driven_apy_6h\"\n | \"price_driven_apy_24h\"\n | \"price_driven_apy_30d\"\n | \"price_driven_apy\"\n | \"listing_time\";\n\n/** Sort direction. */\nexport type ListingSortDirection = \"asc\" | \"desc\";\n\n/**\n * An inclusive `[min, max]` bound on one of the service's value fields. Either\n * end may be omitted for a one-sided bound.\n *\n * Bounds use the **same 18-decimal scale as the response**\n * ({@link LISTING_VALUE_DECIMALS}), not the human-readable figure. Filtering for\n * \"market cap of at least one million USD\" is\n * `{ min: parseUnits(\"1000000\", LISTING_VALUE_DECIMALS) }`, not `{ min: 1_000_000 }`\n * — the latter is a bound of `0.000000000001` USD and silently matches nothing\n * useful. Verified against the live service.\n */\nexport interface ListingValueRange {\n /** Inclusive lower bound at 18 decimals (`__ge` on the wire). */\n min?: bigint;\n /** Inclusive upper bound at 18 decimals (`__le` on the wire). */\n max?: bigint;\n}\n\n/**\n * An inclusive `[min, max]` bound on a timestamp field, in Unix **seconds**\n * (not milliseconds, and not 18-decimal scaled).\n */\nexport interface ListingTimeRange {\n /** Inclusive lower bound, Unix seconds (`__ge` on the wire). */\n min?: number;\n /** Inclusive upper bound, Unix seconds (`__le` on the wire). */\n max?: number;\n}\n\n/**\n * Range filters `getListingMarkets` accepts. Every key is optional; omitted keys\n * are not sent.\n *\n * All {@link ListingValueRange} bounds are at {@link LISTING_VALUE_DECIMALS};\n * `listingTime` is the one exception and takes Unix seconds.\n */\nexport interface ListingMarketFilters {\n /** Token market capitalization, USD. */\n marketCap?: ListingValueRange;\n /** Trailing 24-hour volume, USD. */\n vol24h?: ListingValueRange;\n /** Total value locked, USD. */\n tvl?: ListingValueRange;\n /** Available notional, USD. */\n liquidity?: ListingValueRange;\n /** Open notional, USD. */\n openInterest?: ListingValueRange;\n /** Trailing 24-hour LP rewards, USD. */\n reward24h?: ListingValueRange;\n /** Headline APR bounds, at the field's own scale (`1e18` = `1%`). */\n apr?: ListingValueRange;\n /** APR over the trailing hour. */\n apr1h?: ListingValueRange;\n /** APR over the trailing 6 hours. */\n apr6h?: ListingValueRange;\n /** APR over the trailing 24 hours. */\n apr24h?: ListingValueRange;\n /** APR over the trailing 30 days. */\n apr30d?: ListingValueRange;\n /** TVL-driven APY over the trailing hour. */\n tvlDrivenApy1h?: ListingValueRange;\n /** TVL-driven APY over the trailing 6 hours. */\n tvlDrivenApy6h?: ListingValueRange;\n /** TVL-driven APY over the trailing 24 hours. */\n tvlDrivenApy24h?: ListingValueRange;\n /** TVL-driven APY over the trailing 30 days. */\n tvlDrivenApy30d?: ListingValueRange;\n /** TVL-driven APY over the market's lifetime. */\n tvlDrivenApy?: ListingValueRange;\n /** Price-driven APY over the trailing hour. */\n priceDrivenApy1h?: ListingValueRange;\n /** Price-driven APY over the trailing 6 hours. */\n priceDrivenApy6h?: ListingValueRange;\n /** Price-driven APY over the trailing 24 hours. */\n priceDrivenApy24h?: ListingValueRange;\n /** Price-driven APY over the trailing 30 days. */\n priceDrivenApy30d?: ListingValueRange;\n /** Price-driven APY over the market's lifetime. */\n priceDrivenApy?: ListingValueRange;\n /** Listing timestamp bounds, Unix seconds. */\n listingTime?: ListingTimeRange;\n}\n\n/**\n * Which side of the pool's book a {@link PoolPosition} row describes.\n *\n * The pool's inventory is reported as two aggregates, not a list of individual\n * trades — the detail read gives one long total and one short total.\n */\nexport enum PoolPositionSide {\n LONG = \"long\",\n SHORT = \"short\",\n}\n\n/**\n * One side of a pool's aggregate position book.\n *\n * Every figure is a `bigint` at {@link LISTING_VALUE_DECIMALS}. `upnl` is signed\n * — a losing side reports a negative value — and is the only field here that\n * routinely is.\n */\nexport interface PoolPosition {\n /** Which side this row aggregates. */\n side: PoolPositionSide;\n /** Total size held on this side, in the pool token's units. */\n size: bigint;\n /** Notional value of the side, in USD. */\n value: bigint;\n /** Size-weighted average open price of the side, in USD. */\n avgOpenPrice: bigint;\n /** Unrealized PnL of the side, in USD. Signed. */\n upnl: bigint;\n}\n\n/**\n * A pool's public detail — the aggregate stats and inventory position behind a\n * pool page.\n *\n * Money and rate fields are `bigint` at {@link LISTING_VALUE_DECIMALS}; recall\n * that a descaled *rate* is already a percentage (`1e18` = `1%`) while a\n * descaled *money* field is USD (`1e18` = `$1`). `null` means the backend\n * reported no value, which is not zero.\n *\n * A **delisted** pool is a documented special case: the backend returns cached\n * remaining token and USDC balances with `tvl` fixed at zero.\n */\nexport interface ListingMarketDetail {\n /** The pool's token contract address — its id in the listing API. */\n tokenContractAddress: string;\n /** Chain the token lives on and its listing deposit was made on. */\n depositChain: ListingDepositChainId;\n /** Token display name. */\n tokenName: string;\n /** Token ticker, or `null` when the backend has none. */\n tokenTicker: string | null;\n /** Token decimals. */\n tokenDecimal: number;\n /** Solver market id, or `null` when the pool is not tradable yet. */\n symbolId: number | null;\n /** Where the pool sits in the listing lifecycle. */\n marketStatus: ListingMarketStatus;\n /**\n * Whether the inventory service currently has this pool locked against new\n * deposits. Only deposits are blocked; trading, withdrawals and every other\n * flow stay available. Independent of {@link ListingMarketDetail.marketStatus}.\n * `false` when the backend reports no lock state, as it does for a delisted\n * pool.\n */\n isLocked: boolean;\n /**\n * Why the pool is locked, one entry per active reason; empty when it is not\n * locked. A reason this SDK release does not recognize arrives as\n * {@link MarketLockReason.UNKNOWN}.\n */\n lockReasons: MarketLockReason[];\n /** Maximum leverage the market allows, as a whole multiplier. */\n maxLeverage: number;\n /** Share of revenue routed to token buybacks, as a percentage (`50` = 50%). */\n buybackRatio: number;\n /** When the market went live, as a Unix timestamp in **seconds**. */\n listingTime: number | null;\n /** Pool age in **seconds**, or `null` before listing. */\n age: number | null;\n /** Number of distinct LPs in the pool. */\n activeLps: number;\n /** Total value locked in the pool, USD. `0` for a delisted pool by design. */\n tvl: bigint | null;\n /** Collateral held by the pool, USD. */\n totalUsdcInPool: bigint;\n /** Pool token held by the pool, in the token's own units. */\n totalTokenInPool: bigint;\n /** Accrued maintenance fees, USD. */\n maintenanceFees: bigint;\n /** LP rewards per window, USD. */\n rewards: ListingApyWindows;\n /** Solver revenue per window, USD. */\n solverRevenue: ListingApyWindows;\n /** Headline APY per window, as a percentage. */\n apy: ListingApyWindows;\n /** APY attributed to TVL growth, per window, as a percentage. */\n tvlDrivenApy: ListingApyWindows;\n /** APY attributed to token price movement, per window, as a percentage. */\n priceDrivenApy: ListingApyWindows;\n /** The pool's aggregate long side, or `null` when the backend reported none. */\n longPosition: PoolPosition | null;\n /** The pool's aggregate short side, or `null` when the backend reported none. */\n shortPosition: PoolPosition | null;\n}\n\n/** Whether a pool transaction is money going in or coming out. */\nexport enum PoolTransactionType {\n DEPOSIT = \"deposit\",\n WITHDRAW = \"withdraw\",\n}\n\n/**\n * Where a pool transaction sits in its lifecycle, as the backend reports it to\n * users.\n */\nexport enum PoolTransactionStatus {\n PENDING = \"pending\",\n SUCCESS = \"success\",\n REJECTED = \"rejected\",\n REFUND = \"refund\",\n CANCELED = \"canceled\",\n}\n\n/**\n * One deposit or withdrawal against a pool.\n *\n * `amount`, `usdcAmount` and `tokenAmount` are `bigint` at\n * {@link LISTING_VALUE_DECIMALS}. The refund fields are populated only for a\n * refunded row.\n */\nexport interface PoolTransaction {\n /** Backend id for the transaction. */\n transactionId: string;\n /** The wallet that made it. */\n walletAddress: string;\n /** Amount moved, in the transaction's own denomination. */\n amount: bigint;\n /** Collateral value moved, USD. */\n usdcAmount: bigint;\n /** Token amount moved, in the pool token's units. */\n tokenAmount: bigint;\n /** On-chain transaction hash or Solana signature, when known. */\n transactionHash: string | null;\n /** Address a refund was sent to, or `null` when this is not a refund. */\n refundAddress: string | null;\n /** Hash of the refund transaction, or `null` when this is not a refund. */\n refundTransactionHash: string | null;\n /** When the refund completed, Unix **seconds**; `null` when not a refund. */\n refundTime: number | null;\n /** Deposit or withdrawal. */\n type: PoolTransactionType;\n /** Lifecycle status. */\n status: PoolTransactionStatus;\n /** When the transaction happened, Unix **seconds**. */\n time: number;\n}\n\n/** One page of {@link PoolTransaction} rows for a pool. */\nexport interface PoolTransactionPage {\n /** The pool's token contract address, echoed by the backend, or `null` when the history was not scoped to one pool. */\n marketAddress: string | null;\n /** Total rows matching the query across all pages. */\n count: number;\n /** The rows themselves. */\n items: PoolTransaction[];\n}\n\n/**\n * One row of the signed-in user's transaction history (`getUserTransactions`) —\n * a deposit or withdrawal they made, on any pool.\n *\n * Unlike {@link PoolTransaction} (one pool, every LP), this is one user, every\n * pool — so each row carries its own token identity (`tokenAddress`,\n * `tokenName`, `tokenTicker`, `tokenDecimals`, `chainId`).\n */\nexport interface UserTransaction {\n /** Backend id for the transaction. */\n transactionId: string;\n /** Deposit or withdrawal. */\n type: PoolTransactionType;\n /** Lifecycle status. */\n status: PoolTransactionStatus;\n /** Amount moved, 18-dec bigint (a 1e18-scaled figure, like every listing value). */\n amount: bigint;\n /** The token's own decimals, as reported by the service — metadata, not the `amount` scale. */\n tokenDecimals: number;\n /** The pool's token contract address (EVM `0x…` or Solana base58). */\n tokenAddress: string;\n /** The token's name. */\n tokenName: string;\n /** The token's ticker. */\n tokenTicker: string;\n /** The chain the transaction's token lives on. */\n chainId: ListingDepositChainId;\n /** The temporary deposit wallet involved, or `null` when the service omits it. */\n wallet: string | null;\n /** Address a refund was sent to, or `null` when this is not a refund. */\n refundAddress: string | null;\n /** On-chain transaction hash or Solana signature, when known. */\n transactionHash: string | null;\n /** When the transaction happened, Unix **seconds**; `null` when the service omits it. */\n time: number | null;\n}\n\n/** One page of {@link UserTransaction} rows — the signed-in user's transaction history. */\nexport interface UserTransactionPage {\n /** Total rows matching the query across all pages — what a pager divides. */\n count: number;\n /** The rows themselves, newest first. */\n items: UserTransaction[];\n}\n\n/**\n * The generated `MarketStatus` enum and {@link ListingMarketStatus} carry the\n * same string values; this alias documents that the cast in the mapper is\n * value-preserving rather than a widening.\n *\n * @internal\n */\nexport type GeneratedMarketStatus = MarketStatus;\n\n/**\n * One deposit chain a new listing may use, from the listing service's public\n * config ({@link ListingConfig.supportedDepositChains}).\n */\nexport interface ListingDepositChain {\n /** Numeric chain id to send with market/deposit requests. */\n chainId: ListingDepositChainId;\n /** Human-readable chain name, e.g. \"HyperEVM\". */\n chainName: string;\n}\n\n/**\n * The client mutation limits the listing service enforces, from its public\n * config ({@link ListingConfig.rateLimits}).\n */\nexport interface ListingRateLimits {\n /** Max successful market-config updates per user+market in a rolling 24h window. */\n marketConfigUpdatesPerDay: number;\n /** Max successful profit claims per user+market in a rolling 24h window. */\n profitClaimsPerDay: number;\n}\n\n/**\n * The listing service's public client configuration — the deposit guidance,\n * listing fee, supported deposit chains, rate limits, and protocol reward share\n * a create-listing flow needs.\n *\n * The three USDC figures are `bigint` at {@link LISTING_VALUE_DECIMALS} (18),\n * independent of the collateral token's own decimals; format them with\n * `formatUnits(value, LISTING_VALUE_DECIMALS)` at the display edge.\n */\nexport interface ListingConfig {\n /** Recommended initial USDC deposit to start a listing, USD at LISTING_VALUE_DECIMALS (18) as a bigint. */\n recommendedInitialDepositUsdc: bigint;\n /** Minimum accepted initial USDC deposit after slippage, USD 18-dec bigint. */\n minimumInitialDepositUsdc: bigint;\n /** Listing fee in USDC, USD 18-dec bigint. */\n listingFeeUsdc: bigint;\n /** Deposit chains new markets may use — the source of truth for a chain picker. */\n supportedDepositChains: ListingDepositChain[];\n /** Rolling-24h client mutation limits. */\n rateLimits: ListingRateLimits;\n /** Whole-percent of market revenue to the protocol before buyback/LP. */\n protocolRewardSharePercent: number;\n}\n\n/**\n * One quote in a pool's book, decoded from the analytics subgraph.\n *\n * A pool's book is **every trader's** quotes on that market, not one account's —\n * `partyA` differs from row to row. Amounts and prices are `bigint` at 18\n * decimals (the protocol's own scale, not the listing backend's), and `null`\n * means the subgraph had no value for that field.\n */\nexport interface PoolQuote {\n /** Subgraph row id (`{quoteId}-{source}`); stable, use as a table key. */\n id: string;\n /** Protocol quote id. */\n quoteId: bigint;\n /** Raw `QuoteStatus` ordinal as the subgraph reports it. */\n quoteStatus: number | null;\n /** Raw `PositionType` ordinal — `0` long, `1` short. */\n positionType: number | null;\n /** Raw `OrderType` ordinal of the open — `0` limit, `1` market. */\n orderTypeOpen: number | null;\n /** Market ticker, when the subgraph carries one. */\n symbol: string | null;\n /** Solver market id. */\n symbolId: number | null;\n /** The account that opened the quote. */\n partyA: string;\n /** The solver that took the other side. */\n partyB: string | null;\n /** Quote size. */\n quantity: bigint | null;\n /** How much of {@link PoolQuote.quantity} has been closed. */\n closedAmount: bigint | null;\n /** Size of an in-flight close request. */\n quantityToClose: bigint | null;\n /** Price the quote actually opened at. */\n openedPrice: bigint | null;\n /** Price the opener asked for. */\n requestedOpenPrice: bigint | null;\n /** Size-weighted average of the closes so far. */\n averageClosedPrice: bigint | null;\n /** Price of an in-flight close request. */\n closePrice: bigint | null;\n /** Open price before any modification. */\n initialOpenedPrice: bigint | null;\n /** Size liquidated, when the quote was liquidated. */\n liquidateAmount: bigint | null;\n /** Price the liquidation executed at. */\n liquidatePrice: bigint | null;\n /** Block timestamp of the quote's last update, Unix **seconds**. */\n timestamp: number;\n /** Block the quote was last updated in. */\n blockNumber: bigint;\n}\n\n/**\n * One day of LP reward for a pool.\n *\n * A series of these is what a pool page's rewards chart plots — the public\n * per-pool series from `getPoolRewardChart`, or one market's slice of the\n * signed-in user's {@link UserPoolRewardChart}.\n */\nexport interface PoolRewardPoint {\n /** Start of the reward day, unix **seconds**. */\n timestamp: number;\n /**\n * Reward earned that day, `bigint` at {@link LISTING_VALUE_DECIMALS} (18).\n *\n * A **money** field, so the descaled number is a USD amount (`1e18` = `$1`) —\n * unlike the catalog's rate fields, which are already percentages. A day the\n * service reports as absent collapses to `0n` rather than `null`: a missing\n * snapshot and a zero-reward day are the same point on a chart.\n */\n reward: bigint;\n}\n\n/**\n * The signed-in user's daily reward series for **one** market, as returned by\n * `getUserRewardChart` — which reports every market the user has rewards in,\n * one entry each.\n *\n * A market is addressed by the pair `(marketAddress, marketChainId)`, matching\n * {@link ListingMarket.contractAddress} and {@link ListingMarket.chainId}. Note\n * `marketChainId` is the chain the **token** lives on, not the SYMMIO chain the\n * market trades on.\n */\nexport interface UserPoolRewardChart {\n /** The pool's token contract address — matches {@link ListingMarket.contractAddress}. */\n marketAddress: string;\n /** Chain the token lives on — matches {@link ListingMarket.chainId}. */\n marketChainId: ListingDepositChainId;\n /** The user's daily rewards in this pool, in the order the service returns them. */\n rewards: PoolRewardPoint[];\n}\n"],"mappings":";AAmBA,IAAa,IAAyB,IAgB1B,IAAL,yBAAA,GAAA;QACL,EAAA,sBAAA,uBACA,EAAA,eAAA,gBACA,EAAA,WAAA,YACA,EAAA,SAAA,UACA,EAAA,WAAA;AACF,EAAA,CAAA,CAAA,GAqBY,IAAL,yBAAA,GAAA;QACL,EAAA,qBAAA,sBACA,EAAA,UAAA,WACA,EAAA,oBAAA,qBACA,EAAA,gBAAA,iBACA,EAAA,SAAA,UACA,EAAA,UAAA;AACF,EAAA,CAAA,CAAA,GAcY,IAAL,yBAAA,GAAA;QAEL,EAAA,EAAA,SAAA,KAAA,UACA,EAAA,EAAA,MAAA,MAAA,OACA,EAAA,EAAA,OAAA,QAAA,QACA,EAAA,EAAA,QAAA,OAAA,SACA,EAAA,EAAA,eAAA,SAAA,gBACA,EAAA,EAAA,YAAA,OAAA;AACF,EAAA,CAAA,CAAA,GAycY,IAAL,yBAAA,GAAA;QACL,EAAA,OAAA,QACA,EAAA,QAAA;AACF,EAAA,CAAA,CAAA,GAkGY,IAAL,yBAAA,GAAA;QACL,EAAA,UAAA,WACA,EAAA,WAAA;AACF,EAAA,CAAA,CAAA,GAMY,IAAL,yBAAA,GAAA;QACL,EAAA,UAAA,WACA,EAAA,UAAA,WACA,EAAA,WAAA,YACA,EAAA,SAAA,UACA,EAAA,WAAA;AACF,EAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../src/pools/types.ts"],"sourcesContent":["import type { MarketStatus } from \"./types/generated/listing-backend\";\n\n/**\n * Fixed-point scale of every money and rate field the listing service returns.\n *\n * The service reports these as decimal **strings** at 18 decimals, regardless of\n * the token's own decimals or the collateral's (`\"1000000000000000000\"` = `1`).\n * The SDK keeps them as `bigint` at this scale so nothing is lost; format with\n * `formatUnits(value, LISTING_VALUE_DECIMALS)` from `@symmio/utils/decimal` at\n * the display edge.\n *\n * **What the descaled number means differs by field.** For money fields it is a\n * USD amount (`1e18` = `$1`). For rate fields it is **already a percentage**\n * (`1e18` = `1%`), *not* a fraction — do **not** multiply by 100 to render one.\n *\n * Verified against the live service: a pool with `tvl` `177.78` and `reward_24h`\n * `0.0055` annualizes to `1.1295%`, and its `apr_24h` descales to exactly\n * `1.1295`.\n */\nexport const LISTING_VALUE_DECIMALS = 18;\n\n/**\n * Lifecycle status of a market in the permissionless-listing service.\n *\n * The service — not the chain — owns this state machine. A market becomes\n * tradable only at {@link ListingMarketStatus.LISTED}; before that it has no\n * `symbolId` and no solver market behind it.\n *\n * - `WAITING_FOR_DEPOSIT` — application accepted, the listing deposit has not\n * landed at the custodial address yet.\n * - `UNDER_REVIEW` — deposit received, awaiting the operator's decision.\n * - `REJECTED` — the operator declined the listing; the deposit is refundable.\n * - `LISTED` — live and tradable; `symbolId` is assigned.\n * - `DELISTED` — was live, has since been withdrawn from trading.\n */\nexport enum ListingMarketStatus {\n WAITING_FOR_DEPOSIT = \"waiting_for_deposit\",\n UNDER_REVIEW = \"under_review\",\n REJECTED = \"rejected\",\n LISTED = \"listed\",\n DELISTED = \"delisted\",\n}\n\n/**\n * Why the inventory service has locked a market's pool against new deposits.\n *\n * A lock blocks deposits only: trading, withdrawals, claims and every other\n * flow stay available. It is also orthogonal to {@link ListingMarketStatus}: a\n * `LISTED` market can be locked, and the lock lifts without the lifecycle\n * status moving. The catalogue\n * row carries only the flag ({@link ListingMarket.isLocked}); the reasons are on\n * the detail read ({@link ListingMarketDetail.lockReasons}).\n *\n * - `LIQUIDITY_EXPOSURE` — locked on the service's liquidity-exposure limit.\n * - `LOW_TVL` — the pool's TVL is below the service's threshold.\n * - `PRICE_UNAVAILABLE` — the service has no price for the token.\n * - `SHORT_CIRCUIT` — the service's short-circuit guard tripped.\n * - `MANUAL` — an operator locked the market by hand.\n * - `UNKNOWN` — a reason this SDK release does not recognize. The mapper folds\n * every unrecognized wire value here rather than throwing, so a newer backend\n * cannot break the read.\n */\nexport enum MarketLockReason {\n LIQUIDITY_EXPOSURE = \"LIQUIDITY_EXPOSURE\",\n LOW_TVL = \"LOW_TVL\",\n PRICE_UNAVAILABLE = \"PRICE_UNAVAILABLE\",\n SHORT_CIRCUIT = \"SHORT_CIRCUIT\",\n MANUAL = \"MANUAL\",\n UNKNOWN = \"UNKNOWN\",\n}\n\n/**\n * Chains the listing service accepts a listing deposit on.\n *\n * This is the chain the **token** lives on and where its listing collateral was\n * deposited — it is **not** the chain the resulting market trades on. A market\n * whose token is on Solana or BSC still trades on the SYMMIO deployment the\n * listing service is configured for.\n *\n * `SOLANA = 0` is a sentinel the service uses for its one non-EVM chain, not a\n * real chain id: a `ListingMarket` on it carries a base58 `contractAddress`, so\n * never feed one to an EVM address helper without checking `chainId` first.\n */\nexport enum ListingDepositChainId {\n /** Sentinel for Solana — not an EVM chain id. Addresses are base58. */\n SOLANA = 0,\n BSC = 56,\n BASE = 8453,\n SONIC = 146,\n ARBITRUM_ONE = 42161,\n ROBINHOOD = 4663,\n ARC = 5042,\n HYPER_EVM = 999,\n}\n\n/**\n * Chains the listing backend's token-price endpoint accepts, keyed by the\n * vendor's chain **name** — the `chain` input of `getTokenPrice`.\n *\n * This is a different key space from {@link ListingDepositChainId}: that enum\n * is numeric (an EVM chain id, or the `0` sentinel for Solana) and names where\n * a listing deposit lands; this one is a string name the price endpoint\n * understands, and two of its members (`ROBINHOOD`, `ARC`) have no numeric\n * twin at all. Do not cast between the two — pick the member explicitly.\n */\nexport enum TokenPriceChain {\n BASE = \"BASE\",\n SOLANA = \"SOLANA\",\n BSC = \"BSC\",\n ARBITRUM_ONE = \"ARBITRUM_ONE\",\n SONIC = \"SONIC\",\n ROBINHOOD = \"ROBINHOOD\",\n ARC = \"ARC\",\n}\n\n/**\n * The same metric measured over each trailing window the listing service\n * reports.\n *\n * Every entry is a `bigint` at {@link LISTING_VALUE_DECIMALS}, or `null` when\n * the service has no value for that window — a young market has no 30-day\n * figure, and `null` means *absent*, never zero.\n */\nexport interface ListingTrailingWindows {\n /** Trailing 1 hour. */\n h1: bigint | null;\n /** Trailing 6 hours. */\n h6: bigint | null;\n /** Trailing 24 hours. */\n h24: bigint | null;\n /** Trailing 30 days. */\n d30: bigint | null;\n}\n\n/**\n * A metric the service reports over the trailing windows **and** since listing.\n *\n * Only the two APY series carry a lifetime column; APR does not, which is why\n * `lifetime` lives here rather than on {@link ListingTrailingWindows}.\n */\nexport interface ListingApyWindows extends ListingTrailingWindows {\n /** Since the market was listed. */\n lifetime: bigint | null;\n}\n\n/**\n * One market in the permissionless-listing catalog — a row of the pools list.\n *\n * Money and rate fields are `bigint` at {@link LISTING_VALUE_DECIMALS}; `null`\n * means the service reported no value, which is distinct from zero.\n */\nexport interface ListingMarket {\n /**\n * The listed token's contract address on {@link ListingMarket.chainId}.\n *\n * Typed as `string`, **not** viem's `Address`: Solana listings\n * (`chainId === ListingDepositChainId.SOLANA`) carry a base58 address that is\n * not 0x-prefixed. This is also the id used to address a single market in the\n * rest of the listing API.\n */\n contractAddress: string;\n /** Chain the token lives on and its listing deposit was made on. */\n chainId: ListingDepositChainId;\n /**\n * The solver market id this listing trades under, or `null` when it has none\n * yet. Assigned when the market reaches {@link ListingMarketStatus.LISTED};\n * everything downstream (prices, notional caps, quotes, subgraph rows) keys\n * off it, so a `null` here means the market is not tradable.\n */\n symbolId: number | null;\n /** Token ticker, e.g. `\"SYMM\"`. */\n tokenTicker: string;\n /** Token display name, e.g. `\"Symmio\"`. */\n tokenName: string;\n /** Maximum leverage the market allows, as a whole multiplier (`20` = 20x). */\n maxLeverage: number;\n /** Token market capitalization, in USD. */\n marketCap: bigint | null;\n /** Trailing 24-hour trading volume, in USD. */\n vol24h: bigint | null;\n /** Total value locked in the market's pool, in USD. */\n tvl: bigint | null;\n /** Notional the solver will still take on this market, in USD. */\n liquidity: bigint | null;\n /** Notional currently open on this market, in USD. */\n openInterest: bigint | null;\n /** LP rewards accrued over the trailing 24 hours, in USD. */\n reward24h: bigint | null;\n /** Headline APR: a percentage already (`1e18` = `1%`), not a fraction — render it without multiplying by 100. */\n apr: bigint | null;\n /**\n * APR broken out per trailing window, same units as {@link ListingMarket.apr}.\n * There is no lifetime APR — use {@link ListingMarket.apr} for the headline.\n */\n aprByWindow: ListingTrailingWindows;\n /** APY attributed to TVL growth, per window: a percentage already (`1e18` = `1%`), not a fraction — render it without multiplying by 100. */\n tvlDrivenApy: ListingApyWindows;\n /** APY attributed to token price movement, per window: a percentage already (`1e18` = `1%`), not a fraction — render it without multiplying by 100. */\n priceDrivenApy: ListingApyWindows;\n /** When the market went live, as a Unix timestamp in **seconds**. `null` before it is listed. */\n listingTime: number | null;\n /** Where the market sits in the listing lifecycle. */\n marketStatus: ListingMarketStatus;\n /**\n * Whether the inventory service currently has this market's pool locked\n * against new deposits. Only deposits are blocked; trading, withdrawals and\n * every other flow stay available. Independent of\n * {@link ListingMarket.marketStatus}: a `LISTED` market can be locked. The row\n * carries only the flag; the reasons are on\n * {@link ListingMarketDetail.lockReasons}.\n */\n isLocked: boolean;\n}\n\n/** One page of {@link ListingMarket} rows, with the totals needed to paginate. */\nexport interface ListingMarketPage {\n /** Total rows matching the query across all pages. */\n total: number;\n /** Page size the service applied. */\n limit: number;\n /** Row offset of this page. */\n offset: number;\n /** The rows themselves. */\n items: ListingMarket[];\n}\n\n/**\n * A {@link ListingMarket} enriched with the signed-in user's position in it — one\n * row of \"Your Pools\", the markets that generated a deposit address for the user.\n */\nexport interface UserListingMarket extends ListingMarket {\n /** The user's current deposit into this pool, in USD (18-dec bigint). `null` when the deposit address exists but nothing has been deposited yet. */\n userDeposit: bigint | null;\n /** The user's share of the pool, as a percentage number (not 18-dec scaled). */\n userSharePercentage: number;\n /** The user's accrued revenue from this pool, in USD (18-dec bigint), or `null` when absent. */\n userRevenue: bigint | null;\n}\n\n/** One page of {@link UserListingMarket} rows, with the totals needed to paginate. */\nexport interface UserListingMarketPage {\n /** Total rows matching the query across all pages. */\n total: number;\n /** Page size the service applied. */\n limit: number;\n /** Row offset of this page. */\n offset: number;\n /** The rows themselves. */\n items: UserListingMarket[];\n}\n\n/**\n * The signed-in user's LP position and profit in a single pool — the authed\n * per-token read behind a pool's \"your position\" panel.\n *\n * Every field is a `bigint` at {@link LISTING_VALUE_DECIMALS} (18), independent\n * of the token's or collateral's own decimals; format with\n * `formatUnits(value, LISTING_VALUE_DECIMALS)` at the display edge. An absent\n * figure is normalized to `0n`, not `null`.\n */\nexport interface UserPoolProfit {\n /** LP balance valued in the pool's token units, 18-dec bigint. */\n userBalanceInTokens: bigint;\n /** LP balance valued in USDC, 18-dec bigint USD. */\n userBalanceInUsdc: bigint;\n /** Rewards the user can claim now, 18-dec bigint USD. */\n claimableReward: bigint;\n /** Rewards already claimed, 18-dec bigint USD. */\n claimedReward: bigint;\n /** Token amount the user deposited, 18-dec bigint. */\n userDepositedTokenAmount: bigint;\n /** The user's LP shares, 18-dec bigint. */\n userLpAmount: bigint;\n /** LP shares queued for withdrawal (the pending-withdrawal amount), 18-dec bigint. */\n pendingWithdrawLpAmount: bigint;\n /**\n * LP shares free to withdraw right now — `userLpAmount − pendingWithdrawLpAmount`,\n * floored at `0n`. This is the ceiling a withdrawal (`withdrawLp`) may request;\n * the shares already counted in {@link UserPoolProfit.pendingWithdrawLpAmount}\n * are spoken for. Derived by the SDK, not a field the service returns. 18-dec\n * bigint.\n */\n availableLpAmount: bigint;\n}\n\n/**\n * The receipt returned by `claimProfit` — the outcome of a `/v2/claim` request.\n *\n * The claim is synchronous: a `200` means the USDC was moved to the target\n * sub-account. `amountClaimed` is the moved figure normalized to a `bigint` at\n * `LISTING_VALUE_DECIMALS` (18), `claimRequestId` references the claim in the\n * service, and `transactionHash` is the on-chain transfer hash when the service\n * has one (`null` otherwise).\n */\nexport interface PoolClaimResult {\n /** The service's status string, e.g. `\"ok\"`. */\n status: string;\n /** USDC moved to the sub-account, 18-dec bigint USD. */\n amountClaimed: bigint;\n /** Claim id — reference it to restore or look up the claim later. */\n claimRequestId: string;\n /** On-chain hash of the claim transfer, or `null` when the service has none yet. */\n transactionHash: string | null;\n}\n\n/**\n * One past pool-reward claim, from the user's claim history (`getClaimHistory`).\n *\n * The internal `wallet_id` / `market_id` UUIDs the service carries are dropped —\n * they address rows in the backend, not anything a consumer renders.\n */\nexport interface PoolClaim {\n /** Claim id — reference it to look the claim up in the service. */\n claimRequestId: string;\n /** Sub-account address that received the claimed USDC. */\n accountAddress: string;\n /** USDC claimed, 18-dec bigint USD. */\n amount: bigint;\n /** On-chain hash of the claim transfer, or `null` when the service has none. */\n transactionHash: string | null;\n /** When the claim was created, Unix **seconds**. */\n time: number;\n}\n\n/** One page of {@link PoolClaim} rows — the signed-in user's claim history. */\nexport interface PoolClaimHistoryPage {\n /** Total claims matching the query across all pages — what a pager divides. */\n count: number;\n /** The claims themselves, newest first. */\n items: PoolClaim[];\n}\n\n/**\n * The receipt returned by `cancelWithdraw` — the outcome of cancelling a queued\n * LP withdrawal.\n */\nexport interface PoolCancelWithdrawResult {\n /** The affected withdrawal's transaction id, echoed by the service. */\n transactionId: string;\n /**\n * The withdrawal's resulting status, e.g. `\"canceled\"`. Carried through as the\n * service's raw string — its enum (`canceled` | `pending` | `transferred` | …)\n * is a superset of {@link PoolTransactionStatus}, so it is not narrowed to it.\n */\n status: string;\n}\n\n/**\n * The receipt returned by `refundMarket` — the outcome of refunding a deposit on\n * a rejected market.\n */\nexport interface PoolRefundResult {\n /** On-chain hash of the refund transfer. */\n transactionHash: string;\n}\n\n/**\n * The signed-in user's **retry allowance** for one rejected market\n * (`getRetryListingInfo`) — how many listing retries remain and the cooldown\n * before the next.\n */\nexport interface RetryListingInfo {\n /** Maximum retries allowed per market. */\n retryLimit: number;\n /** Retries the user has left for this market. */\n remainingRetries: number;\n /** Seconds until the next retry is allowed, or `null` when no cooldown is in effect. */\n remainingCooldownSeconds: number | null;\n}\n\n/**\n * The result of `retryListing` — the retry allowance left after re-submitting a\n * rejected market.\n */\nexport interface RetryListingResult {\n /** Maximum retries allowed per market. */\n retryLimit: number;\n /** Retries left after this one. */\n remainingRetries: number;\n /** Seconds before the next retry is allowed. */\n cooldownSeconds: number;\n}\n\n/**\n * The signed-in user's deposit wallet for one market — the get-or-create result\n * of the authed `/v2/market/deposit-address` endpoint. This is the address the\n * user sends funds to in order to deposit into the market's pool.\n */\nexport interface MarketDepositAddress {\n /** The market's token contract address (EVM 0x… or Solana base58). */\n tokenContractAddress: string;\n /** The signed-in user this deposit wallet belongs to. */\n userAddress: string;\n /** The market's deposit chain. */\n depositChain: ListingDepositChainId;\n /** The deposit address — where the user sends funds to deposit into this market. `null` when the service returned none. */\n depositAddress: string | null;\n /** The token's on-chain decimals. */\n tokenDecimal: number;\n /** The market's listing lifecycle status. */\n marketStatus: ListingMarketStatus;\n}\n\n/**\n * A pre-listing price **estimate** for one token — the normalized result of\n * the authed `/v2/market/token-price` endpoint, which asks the Price Service\n * for a token that is not (yet) listed.\n *\n * The backend caches the figure for about five minutes and rate-limits the\n * endpoint, so treat `price` as a display estimate, never as a mark or trade\n * price: render it with a `~`, and do not poll for a fresher one.\n */\nexport interface TokenPrice {\n /** USD per token, as the service reports it — a plain float, always `> 0`. */\n price: number;\n}\n\n/**\n * The listing-pipeline status of a single market — the normalized result of\n * `getListingStatus`, keyed by the market's token address and deposit chain.\n *\n * `marketStatus` is the overall lifecycle status (the same machine as\n * {@link ListingMarketStatus}); the remaining fields describe where the listing\n * is in the backend's step pipeline and whether the current step is retrying or\n * has errored.\n */\nexport interface ListingStatus {\n /** Overall lifecycle status of the market, mapped from the service's `market_status`. */\n marketStatus: ListingMarketStatus;\n /** The step the listing pipeline is currently on, or `null` when it is not in a step. */\n currentStep: string | null;\n /** The ordered pipeline steps the listing moves through. */\n steps: string[];\n /** Error code reported for the current step, or `null` when there is no error. */\n errorCode: number | null;\n /** Human-readable detail for the current step's error, or `null`. */\n errorDetail: string | null;\n /** How many times the current step has been retried. */\n retryCount: number;\n /** The maximum retries allowed for the current step. */\n retryLimit: number;\n}\n\n/**\n * The protocol's global new-market listing cap for the current rolling weekly\n * window — how many pools may still be listed across the protocol before the\n * window resets.\n */\nexport interface WeeklyListingLimit {\n /** Total new-market listings allowed per rolling weekly window. */\n limit: number;\n /** Listings still available in the current window — `0` means no more pools can be listed until reset. */\n remaining: number;\n /** When the window resets, as the Unix timestamp the service returns (`reset_at`). */\n resetAt: number;\n}\n\n/**\n * Server-side sort keys accepted by `getListingMarkets`.\n *\n * Mirrors the service's `sort_by` enum verbatim — snake_case, not the SDK's\n * camelCase field names — because the value is a wire literal, and translating\n * it would break silently the moment the service adds a key.\n *\n * Note the two bare keys: `tvl_driven_apy` and `price_driven_apy` have no\n * matching bare response field. They sort by the **lifetime** column\n * (`tvl_driven_apy_lifetime` / `price_driven_apy_lifetime`).\n */\nexport type ListingMarketSortField =\n | \"liquidity\"\n | \"tvl\"\n | \"market_cap\"\n | \"vol24h\"\n | \"open_interest\"\n | \"apr_1h\"\n | \"apr_6h\"\n | \"apr_24h\"\n | \"apr_30d\"\n | \"reward_24h\"\n | \"apr\"\n | \"tvl_driven_apy_1h\"\n | \"tvl_driven_apy_6h\"\n | \"tvl_driven_apy_24h\"\n | \"tvl_driven_apy_30d\"\n | \"tvl_driven_apy\"\n | \"price_driven_apy_1h\"\n | \"price_driven_apy_6h\"\n | \"price_driven_apy_24h\"\n | \"price_driven_apy_30d\"\n | \"price_driven_apy\"\n | \"listing_time\";\n\n/** Sort direction. */\nexport type ListingSortDirection = \"asc\" | \"desc\";\n\n/**\n * An inclusive `[min, max]` bound on one of the service's value fields. Either\n * end may be omitted for a one-sided bound.\n *\n * Bounds use the **same 18-decimal scale as the response**\n * ({@link LISTING_VALUE_DECIMALS}), not the human-readable figure. Filtering for\n * \"market cap of at least one million USD\" is\n * `{ min: parseUnits(\"1000000\", LISTING_VALUE_DECIMALS) }`, not `{ min: 1_000_000 }`\n * — the latter is a bound of `0.000000000001` USD and silently matches nothing\n * useful. Verified against the live service.\n */\nexport interface ListingValueRange {\n /** Inclusive lower bound at 18 decimals (`__ge` on the wire). */\n min?: bigint;\n /** Inclusive upper bound at 18 decimals (`__le` on the wire). */\n max?: bigint;\n}\n\n/**\n * An inclusive `[min, max]` bound on a timestamp field, in Unix **seconds**\n * (not milliseconds, and not 18-decimal scaled).\n */\nexport interface ListingTimeRange {\n /** Inclusive lower bound, Unix seconds (`__ge` on the wire). */\n min?: number;\n /** Inclusive upper bound, Unix seconds (`__le` on the wire). */\n max?: number;\n}\n\n/**\n * Range filters `getListingMarkets` accepts. Every key is optional; omitted keys\n * are not sent.\n *\n * All {@link ListingValueRange} bounds are at {@link LISTING_VALUE_DECIMALS};\n * `listingTime` is the one exception and takes Unix seconds.\n */\nexport interface ListingMarketFilters {\n /** Token market capitalization, USD. */\n marketCap?: ListingValueRange;\n /** Trailing 24-hour volume, USD. */\n vol24h?: ListingValueRange;\n /** Total value locked, USD. */\n tvl?: ListingValueRange;\n /** Available notional, USD. */\n liquidity?: ListingValueRange;\n /** Open notional, USD. */\n openInterest?: ListingValueRange;\n /** Trailing 24-hour LP rewards, USD. */\n reward24h?: ListingValueRange;\n /** Headline APR bounds, at the field's own scale (`1e18` = `1%`). */\n apr?: ListingValueRange;\n /** APR over the trailing hour. */\n apr1h?: ListingValueRange;\n /** APR over the trailing 6 hours. */\n apr6h?: ListingValueRange;\n /** APR over the trailing 24 hours. */\n apr24h?: ListingValueRange;\n /** APR over the trailing 30 days. */\n apr30d?: ListingValueRange;\n /** TVL-driven APY over the trailing hour. */\n tvlDrivenApy1h?: ListingValueRange;\n /** TVL-driven APY over the trailing 6 hours. */\n tvlDrivenApy6h?: ListingValueRange;\n /** TVL-driven APY over the trailing 24 hours. */\n tvlDrivenApy24h?: ListingValueRange;\n /** TVL-driven APY over the trailing 30 days. */\n tvlDrivenApy30d?: ListingValueRange;\n /** TVL-driven APY over the market's lifetime. */\n tvlDrivenApy?: ListingValueRange;\n /** Price-driven APY over the trailing hour. */\n priceDrivenApy1h?: ListingValueRange;\n /** Price-driven APY over the trailing 6 hours. */\n priceDrivenApy6h?: ListingValueRange;\n /** Price-driven APY over the trailing 24 hours. */\n priceDrivenApy24h?: ListingValueRange;\n /** Price-driven APY over the trailing 30 days. */\n priceDrivenApy30d?: ListingValueRange;\n /** Price-driven APY over the market's lifetime. */\n priceDrivenApy?: ListingValueRange;\n /** Listing timestamp bounds, Unix seconds. */\n listingTime?: ListingTimeRange;\n}\n\n/**\n * Which side of the pool's book a {@link PoolPosition} row describes.\n *\n * The pool's inventory is reported as two aggregates, not a list of individual\n * trades — the detail read gives one long total and one short total.\n */\nexport enum PoolPositionSide {\n LONG = \"long\",\n SHORT = \"short\",\n}\n\n/**\n * One side of a pool's aggregate position book.\n *\n * Every figure is a `bigint` at {@link LISTING_VALUE_DECIMALS}. `upnl` is signed\n * — a losing side reports a negative value — and is the only field here that\n * routinely is.\n */\nexport interface PoolPosition {\n /** Which side this row aggregates. */\n side: PoolPositionSide;\n /** Total size held on this side, in the pool token's units. */\n size: bigint;\n /** Notional value of the side, in USD. */\n value: bigint;\n /** Size-weighted average open price of the side, in USD. */\n avgOpenPrice: bigint;\n /** Unrealized PnL of the side, in USD. Signed. */\n upnl: bigint;\n}\n\n/**\n * A pool's public detail — the aggregate stats and inventory position behind a\n * pool page.\n *\n * Money and rate fields are `bigint` at {@link LISTING_VALUE_DECIMALS}; recall\n * that a descaled *rate* is already a percentage (`1e18` = `1%`) while a\n * descaled *money* field is USD (`1e18` = `$1`). `null` means the backend\n * reported no value, which is not zero.\n *\n * A **delisted** pool is a documented special case: the backend returns cached\n * remaining token and USDC balances with `tvl` fixed at zero.\n */\nexport interface ListingMarketDetail {\n /** The pool's token contract address — its id in the listing API. */\n tokenContractAddress: string;\n /** Chain the token lives on and its listing deposit was made on. */\n depositChain: ListingDepositChainId;\n /** Token display name. */\n tokenName: string;\n /** Token ticker, or `null` when the backend has none. */\n tokenTicker: string | null;\n /** Token decimals. */\n tokenDecimal: number;\n /** Solver market id, or `null` when the pool is not tradable yet. */\n symbolId: number | null;\n /** Where the pool sits in the listing lifecycle. */\n marketStatus: ListingMarketStatus;\n /**\n * Whether the inventory service currently has this pool locked against new\n * deposits. Only deposits are blocked; trading, withdrawals and every other\n * flow stay available. Independent of {@link ListingMarketDetail.marketStatus}.\n * `false` when the backend reports no lock state, as it does for a delisted\n * pool.\n */\n isLocked: boolean;\n /**\n * Why the pool is locked, one entry per active reason; empty when it is not\n * locked. A reason this SDK release does not recognize arrives as\n * {@link MarketLockReason.UNKNOWN}.\n */\n lockReasons: MarketLockReason[];\n /** Maximum leverage the market allows, as a whole multiplier. */\n maxLeverage: number;\n /** Share of revenue routed to token buybacks, as a percentage (`50` = 50%). */\n buybackRatio: number;\n /** When the market went live, as a Unix timestamp in **seconds**. */\n listingTime: number | null;\n /** Pool age in **seconds**, or `null` before listing. */\n age: number | null;\n /** Number of distinct LPs in the pool. */\n activeLps: number;\n /** Total value locked in the pool, USD. `0` for a delisted pool by design. */\n tvl: bigint | null;\n /** Collateral held by the pool, USD. */\n totalUsdcInPool: bigint;\n /** Pool token held by the pool, in the token's own units. */\n totalTokenInPool: bigint;\n /** Accrued maintenance fees, USD. */\n maintenanceFees: bigint;\n /** LP rewards per window, USD. */\n rewards: ListingApyWindows;\n /** Solver revenue per window, USD. */\n solverRevenue: ListingApyWindows;\n /** Headline APY per window, as a percentage. */\n apy: ListingApyWindows;\n /** APY attributed to TVL growth, per window, as a percentage. */\n tvlDrivenApy: ListingApyWindows;\n /** APY attributed to token price movement, per window, as a percentage. */\n priceDrivenApy: ListingApyWindows;\n /** The pool's aggregate long side, or `null` when the backend reported none. */\n longPosition: PoolPosition | null;\n /** The pool's aggregate short side, or `null` when the backend reported none. */\n shortPosition: PoolPosition | null;\n}\n\n/** Whether a pool transaction is money going in or coming out. */\nexport enum PoolTransactionType {\n DEPOSIT = \"deposit\",\n WITHDRAW = \"withdraw\",\n}\n\n/**\n * Where a pool transaction sits in its lifecycle, as the backend reports it to\n * users.\n */\nexport enum PoolTransactionStatus {\n PENDING = \"pending\",\n SUCCESS = \"success\",\n REJECTED = \"rejected\",\n REFUND = \"refund\",\n CANCELED = \"canceled\",\n}\n\n/**\n * One deposit or withdrawal against a pool.\n *\n * Each row names its own pool (`tokenAddress`, `chainId`), so a page read across\n * every pool stays attributable row by row. `amount`, `usdcAmount` and\n * `tokenAmount` are `bigint` at {@link LISTING_VALUE_DECIMALS}. The refund fields\n * are populated only for a refunded row.\n */\nexport interface PoolTransaction {\n /** Backend id for the transaction. */\n transactionId: string;\n /** The pool's token contract address (EVM `0x…` or Solana base58) — the pool this row belongs to. */\n tokenAddress: string;\n /** The chain the pool's token lives on — not the chain the market trades on. */\n chainId: ListingDepositChainId;\n /** The wallet that made it. */\n walletAddress: string;\n /** Amount moved, in the transaction's own denomination. */\n amount: bigint;\n /** Collateral value moved, USD. */\n usdcAmount: bigint;\n /** Token amount moved, in the pool token's units. */\n tokenAmount: bigint;\n /** On-chain transaction hash or Solana signature, when known. */\n transactionHash: string | null;\n /** Address a refund was sent to, or `null` when this is not a refund. */\n refundAddress: string | null;\n /** Hash of the refund transaction, or `null` when this is not a refund. */\n refundTransactionHash: string | null;\n /** When the refund completed, Unix **seconds**; `null` when not a refund. */\n refundTime: number | null;\n /** Deposit or withdrawal. */\n type: PoolTransactionType;\n /** Lifecycle status. */\n status: PoolTransactionStatus;\n /** When the transaction happened, Unix **seconds**. */\n time: number;\n}\n\n/** One page of {@link PoolTransaction} rows — one pool's, or every pool's when the read is not narrowed to a token. */\nexport interface PoolTransactionPage {\n /**\n * The token address the page was narrowed to, echoed by the backend in its canonical form, or `null` when the page\n * spans every pool. Each row carries its own `tokenAddress` either way.\n */\n marketAddress: string | null;\n /** Total rows matching the query across all pages — what a pager divides, not `items.length`. */\n count: number;\n /** The rows themselves, newest first. */\n items: PoolTransaction[];\n}\n\n/**\n * One row of the signed-in user's transaction history (`getUserTransactions`) —\n * a deposit or withdrawal they made, on any pool.\n *\n * Unlike {@link PoolTransaction} (public, every LP), this is authed and scoped to\n * one user, every pool — and each row carries the token's display metadata\n * (`tokenName`, `tokenTicker`, `tokenDecimals`), not just its identity\n * (`tokenAddress`, `chainId`).\n */\nexport interface UserTransaction {\n /** Backend id for the transaction. */\n transactionId: string;\n /** Deposit or withdrawal. */\n type: PoolTransactionType;\n /** Lifecycle status. */\n status: PoolTransactionStatus;\n /** Amount moved, 18-dec bigint (a 1e18-scaled figure, like every listing value). */\n amount: bigint;\n /** The token's own decimals, as reported by the service — metadata, not the `amount` scale. */\n tokenDecimals: number;\n /** The pool's token contract address (EVM `0x…` or Solana base58). */\n tokenAddress: string;\n /** The token's name. */\n tokenName: string;\n /** The token's ticker. */\n tokenTicker: string;\n /** The chain the transaction's token lives on. */\n chainId: ListingDepositChainId;\n /** The temporary deposit wallet involved, or `null` when the service omits it. */\n wallet: string | null;\n /** Address a refund was sent to, or `null` when this is not a refund. */\n refundAddress: string | null;\n /** On-chain transaction hash or Solana signature, when known. */\n transactionHash: string | null;\n /** When the transaction happened, Unix **seconds**; `null` when the service omits it. */\n time: number | null;\n}\n\n/** One page of {@link UserTransaction} rows — the signed-in user's transaction history. */\nexport interface UserTransactionPage {\n /** Total rows matching the query across all pages — what a pager divides. */\n count: number;\n /** The rows themselves, newest first. */\n items: UserTransaction[];\n}\n\n/**\n * The generated `MarketStatus` enum and {@link ListingMarketStatus} carry the\n * same string values; this alias documents that the cast in the mapper is\n * value-preserving rather than a widening.\n *\n * @internal\n */\nexport type GeneratedMarketStatus = MarketStatus;\n\n/**\n * One deposit chain a new listing may use, from the listing service's public\n * config ({@link ListingConfig.supportedDepositChains}).\n */\nexport interface ListingDepositChain {\n /** Numeric chain id to send with market/deposit requests. */\n chainId: ListingDepositChainId;\n /** Human-readable chain name, e.g. \"HyperEVM\". */\n chainName: string;\n}\n\n/**\n * The client mutation limits the listing service enforces, from its public\n * config ({@link ListingConfig.rateLimits}).\n */\nexport interface ListingRateLimits {\n /** Max successful market-config updates per user+market in a rolling 24h window. */\n marketConfigUpdatesPerDay: number;\n /** Max successful profit claims per user+market in a rolling 24h window. */\n profitClaimsPerDay: number;\n}\n\n/**\n * The listing service's public client configuration — the deposit guidance,\n * listing fee, supported deposit chains, rate limits, and protocol reward share\n * a create-listing flow needs.\n *\n * The three USDC figures are `bigint` at {@link LISTING_VALUE_DECIMALS} (18),\n * independent of the collateral token's own decimals; format them with\n * `formatUnits(value, LISTING_VALUE_DECIMALS)` at the display edge.\n */\nexport interface ListingConfig {\n /** Recommended initial USDC deposit to start a listing, USD at LISTING_VALUE_DECIMALS (18) as a bigint. */\n recommendedInitialDepositUsdc: bigint;\n /** Minimum accepted initial USDC deposit after slippage, USD 18-dec bigint. */\n minimumInitialDepositUsdc: bigint;\n /** Listing fee in USDC, USD 18-dec bigint. */\n listingFeeUsdc: bigint;\n /** Deposit chains new markets may use — the source of truth for a chain picker. */\n supportedDepositChains: ListingDepositChain[];\n /** Rolling-24h client mutation limits. */\n rateLimits: ListingRateLimits;\n /** Whole-percent of market revenue to the protocol before buyback/LP. */\n protocolRewardSharePercent: number;\n}\n\n/**\n * One quote in a pool's book, decoded from the analytics subgraph.\n *\n * A pool's book is **every trader's** quotes on that market, not one account's —\n * `partyA` differs from row to row. Amounts and prices are `bigint` at 18\n * decimals (the protocol's own scale, not the listing backend's), and `null`\n * means the subgraph had no value for that field.\n */\nexport interface PoolQuote {\n /** Subgraph row id (`{quoteId}-{source}`); stable, use as a table key. */\n id: string;\n /** Protocol quote id. */\n quoteId: bigint;\n /** Raw `QuoteStatus` ordinal as the subgraph reports it. */\n quoteStatus: number | null;\n /** Raw `PositionType` ordinal — `0` long, `1` short. */\n positionType: number | null;\n /** Raw `OrderType` ordinal of the open — `0` limit, `1` market. */\n orderTypeOpen: number | null;\n /** Market ticker, when the subgraph carries one. */\n symbol: string | null;\n /** Solver market id. */\n symbolId: number | null;\n /** The account that opened the quote. */\n partyA: string;\n /** The solver that took the other side. */\n partyB: string | null;\n /** Quote size. */\n quantity: bigint | null;\n /** How much of {@link PoolQuote.quantity} has been closed. */\n closedAmount: bigint | null;\n /** Size of an in-flight close request. */\n quantityToClose: bigint | null;\n /** Price the quote actually opened at. */\n openedPrice: bigint | null;\n /** Price the opener asked for. */\n requestedOpenPrice: bigint | null;\n /** Size-weighted average of the closes so far. */\n averageClosedPrice: bigint | null;\n /** Price of an in-flight close request. */\n closePrice: bigint | null;\n /** Open price before any modification. */\n initialOpenedPrice: bigint | null;\n /** Size liquidated, when the quote was liquidated. */\n liquidateAmount: bigint | null;\n /** Price the liquidation executed at. */\n liquidatePrice: bigint | null;\n /** Block timestamp of the quote's last update, Unix **seconds**. */\n timestamp: number;\n /** Block the quote was last updated in. */\n blockNumber: bigint;\n}\n\n/**\n * One day of LP reward for a pool.\n *\n * A series of these is what a pool page's rewards chart plots — the public\n * per-pool series from `getPoolRewardChart`, or one market's slice of the\n * signed-in user's {@link UserPoolRewardChart}.\n */\nexport interface PoolRewardPoint {\n /** Start of the reward day, unix **seconds**. */\n timestamp: number;\n /**\n * Reward earned that day, `bigint` at {@link LISTING_VALUE_DECIMALS} (18).\n *\n * A **money** field, so the descaled number is a USD amount (`1e18` = `$1`) —\n * unlike the catalog's rate fields, which are already percentages. A day the\n * service reports as absent collapses to `0n` rather than `null`: a missing\n * snapshot and a zero-reward day are the same point on a chart.\n */\n reward: bigint;\n}\n\n/**\n * The signed-in user's daily reward series for **one** market, as returned by\n * `getUserRewardChart` — which reports every market the user has rewards in,\n * one entry each.\n *\n * A market is addressed by the pair `(marketAddress, marketChainId)`, matching\n * {@link ListingMarket.contractAddress} and {@link ListingMarket.chainId}. Note\n * `marketChainId` is the chain the **token** lives on, not the SYMMIO chain the\n * market trades on.\n */\nexport interface UserPoolRewardChart {\n /** The pool's token contract address — matches {@link ListingMarket.contractAddress}. */\n marketAddress: string;\n /** Chain the token lives on — matches {@link ListingMarket.chainId}. */\n marketChainId: ListingDepositChainId;\n /** The user's daily rewards in this pool, in the order the service returns them. */\n rewards: PoolRewardPoint[];\n}\n"],"mappings":";AAmBA,IAAa,IAAyB,IAgB1B,IAAL,yBAAA,GAAA;QACL,EAAA,sBAAA,uBACA,EAAA,eAAA,gBACA,EAAA,WAAA,YACA,EAAA,SAAA,UACA,EAAA,WAAA;AACF,EAAA,CAAA,CAAA,GAqBY,IAAL,yBAAA,GAAA;QACL,EAAA,qBAAA,sBACA,EAAA,UAAA,WACA,EAAA,oBAAA,qBACA,EAAA,gBAAA,iBACA,EAAA,SAAA,UACA,EAAA,UAAA;AACF,EAAA,CAAA,CAAA,GAcY,IAAL,yBAAA,GAAA;QAEL,EAAA,EAAA,SAAA,KAAA,UACA,EAAA,EAAA,MAAA,MAAA,OACA,EAAA,EAAA,OAAA,QAAA,QACA,EAAA,EAAA,QAAA,OAAA,SACA,EAAA,EAAA,eAAA,SAAA,gBACA,EAAA,EAAA,YAAA,QAAA,aACA,EAAA,EAAA,MAAA,QAAA,OACA,EAAA,EAAA,YAAA,OAAA;AACF,EAAA,CAAA,CAAA,GAYY,IAAL,yBAAA,GAAA;QACL,EAAA,OAAA,QACA,EAAA,SAAA,UACA,EAAA,MAAA,OACA,EAAA,eAAA,gBACA,EAAA,QAAA,SACA,EAAA,YAAA,aACA,EAAA,MAAA;AACF,EAAA,CAAA,CAAA,GAudY,IAAL,yBAAA,GAAA;QACL,EAAA,OAAA,QACA,EAAA,QAAA;AACF,EAAA,CAAA,CAAA,GAkGY,IAAL,yBAAA,GAAA;QACL,EAAA,UAAA,WACA,EAAA,WAAA;AACF,EAAA,CAAA,CAAA,GAMY,IAAL,yBAAA,GAAA;QACL,EAAA,UAAA,WACA,EAAA,UAAA,WACA,EAAA,WAAA,YACA,EAAA,SAAA,UACA,EAAA,WAAA;AACF,EAAA,CAAA,CAAA"}
@@ -1,6 +1,7 @@
1
1
  import { Address, Hex } from 'viem';
2
2
  import { Config } from '../../../core/config/index.js';
3
3
  import { Compute, WriteSolverParameter } from '../../../shared/types/properties.js';
4
+ import { InstantDelegationPreflightParameter } from '../../shared/instant-delegation-preflight.js';
4
5
  import { InstantCloseOrder, InstantCloseReturnType, SolverOrderType } from '../shared/types.js';
5
6
  /**
6
7
  * Parameters for the pure {@link instantClose} primitive.
@@ -9,7 +10,7 @@ import { InstantCloseOrder, InstantCloseReturnType, SolverOrderType } from '../s
9
10
  * `requestToClosePosition`. The caller (or the `prepareInstantCloseParams`
10
11
  * wizard) is responsible for trade math.
11
12
  */
12
- export type InstantCloseParameters = Compute<WriteSolverParameter & {
13
+ export type InstantCloseParameters = Compute<WriteSolverParameter & InstantDelegationPreflightParameter & {
13
14
  /**
14
15
  * PartyA — the account that owns the position and signs the close
15
16
  * (EIP-712 `signerAccount`). The VA address on Enigma (lowcap); the
@@ -45,6 +46,12 @@ export type InstantCloseParameters = Compute<WriteSolverParameter & {
45
46
  * Use `prepareInstantCloseParams` to derive this shape from UI-shape inputs,
46
47
  * or `instantCloseAuto` for the combined convenience.
47
48
  *
49
+ * Before signing, it checks that the signer holds the `requestToClosePosition`
50
+ * delegation — on the VA's parent sub-account when `partyA` is a VA (skip it
51
+ * with `preflightDelegation: false`). The sub-account's owner needs none.
52
+ *
53
+ * @throws {SymmError} `INSTANT_SIGNER_NOT_DELEGATED` when the signer lacks the
54
+ * delegation, before anything is signed.
48
55
  * @throws {SymmApiError} when the hedger request fails.
49
56
  *
50
57
  * @example
@@ -1 +1 @@
1
- {"version":3,"file":"instant-close.d.ts","sourceRoot":"","sources":["../../../../src/solvers/instant-close/instant-close/instant-close.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAMtF,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACrB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;GAMG;AACH,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAC1C,oBAAoB,GAAG;IACrB;;;;OAIG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB,sEAAsE;IACtE,KAAK,EAAE,iBAAiB,CAAC;IACzB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,oEAAoE;IACpE,IAAI,CAAC,EAAE,GAAG,CAAC;IACX;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CACF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,sBAAsB,GACjC,OAAO,CAAC,sBAAsB,CAAC,CA0CjC"}
1
+ {"version":3,"file":"instant-close.d.ts","sourceRoot":"","sources":["../../../../src/solvers/instant-close/instant-close/instant-close.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAGtF,OAAO,EAEL,KAAK,mCAAmC,EACzC,MAAM,2CAA2C,CAAC;AAInD,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACrB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;GAMG;AACH,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAC1C,oBAAoB,GAClB,mCAAmC,GAAG;IACpC;;;;OAIG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB,sEAAsE;IACtE,KAAK,EAAE,iBAAiB,CAAC;IACzB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,oEAAoE;IACpE,IAAI,CAAC,EAAE,GAAG,CAAC;IACX;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CACJ,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,sBAAsB,GACjC,OAAO,CAAC,sBAAsB,CAAC,CAiDjC"}
@@ -1,42 +1,50 @@
1
1
  import { buildSignedOperation as e, signAndFormatInstantOperation as t } from "../../instant-open/shared/operations.js";
2
+ import { assertInstantSignerDelegated as n } from "../../shared/instant-delegation-preflight.js";
2
3
  import "../../instant-open/shared/types.js";
3
- import { getLimitOrderDeadline as n, getMarketOrderDeadline as r } from "../../instant-open/shared/trade-math.js";
4
- import { encodeRequestToClosePosition as i } from "../shared/calldata.js";
5
- import { sendInstantClose as a } from "../shared/hedger-api.js";
6
- import { resolveCloseOrderType as o } from "../shared/resolve-close-order-type.js";
4
+ import { getLimitOrderDeadline as r, getMarketOrderDeadline as i } from "../../instant-open/shared/trade-math.js";
5
+ import { encodeRequestToClosePosition as a } from "../shared/calldata.js";
6
+ import { sendInstantClose as o } from "../shared/hedger-api.js";
7
+ import { resolveCloseOrderType as s } from "../shared/resolve-close-order-type.js";
7
8
  //#region src/solvers/instant-close/instant-close/instant-close.ts
8
- async function s(s, c) {
9
- let { symmioAddress: l } = s.getChainConfig(c.chainId).addresses, u = s.getSolver({
10
- chainId: c.chainId,
11
- solverId: c.solverId
12
- }), d = await s.getWalletClient({
13
- chainId: c.chainId,
14
- from: c.from
15
- }), f = d.account.address, p = o(u.id, c.orderType ?? 1), m = c.deadline ?? (p === 0 ? n() : r()), h = await t(s, {
16
- operation: e({
17
- signer: f,
18
- target: l,
19
- callData: i({
20
- quoteId: c.order.quoteId,
21
- closePrice: c.order.closePrice,
22
- quantityToClose: c.order.quantityToClose,
23
- orderType: p,
24
- deadline: m
25
- }),
26
- signerAccount: c.partyA,
27
- deadline: m,
28
- salt: c.salt
9
+ async function c(c, l) {
10
+ let { symmioAddress: u } = c.getChainConfig(l.chainId).addresses, d = c.getSolver({
11
+ chainId: l.chainId,
12
+ solverId: l.solverId
13
+ }), f = await c.getWalletClient({
14
+ chainId: l.chainId,
15
+ from: l.from
16
+ }), p = f.account.address, m = s(d.id, l.orderType ?? 1), h = l.deadline ?? (m === 0 ? r() : i()), g = e({
17
+ signer: p,
18
+ target: u,
19
+ callData: a({
20
+ quoteId: l.order.quoteId,
21
+ closePrice: l.order.closePrice,
22
+ quantityToClose: l.order.quantityToClose,
23
+ orderType: m,
24
+ deadline: h
29
25
  }),
30
- chainId: c.chainId,
31
- walletClient: d
26
+ signerAccount: l.partyA,
27
+ deadline: h,
28
+ salt: l.salt
32
29
  });
33
- return await a(s, {
34
- chainId: c.chainId,
35
- solverId: u.id,
36
- operations: [h]
30
+ await n(c, {
31
+ chainId: l.chainId,
32
+ action: "instantClose",
33
+ operations: [g],
34
+ enabled: l.preflightDelegation
35
+ });
36
+ let _ = await t(c, {
37
+ operation: g,
38
+ chainId: l.chainId,
39
+ walletClient: f
40
+ });
41
+ return await o(c, {
42
+ chainId: l.chainId,
43
+ solverId: d.id,
44
+ operations: [_]
37
45
  }), { success: !0 };
38
46
  }
39
47
  //#endregion
40
- export { s as instantClose };
48
+ export { c as instantClose };
41
49
 
42
50
  //# sourceMappingURL=instant-close.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"instant-close.js","names":[],"sources":["../../../../src/solvers/instant-close/instant-close/instant-close.ts"],"sourcesContent":["import type { Address, Hex } from \"viem\";\nimport type { Config } from \"../../../core/config\";\nimport type { Compute, WriteSolverParameter } from \"../../../shared/types/properties\";\nimport { buildSignedOperation, signAndFormatInstantOperation } from \"../../instant-open/shared/operations\";\nimport { getLimitOrderDeadline, getMarketOrderDeadline } from \"../../instant-open/shared/trade-math\";\nimport { encodeRequestToClosePosition } from \"../shared/calldata\";\nimport { sendInstantClose } from \"../shared/hedger-api\";\nimport { resolveCloseOrderType } from \"../shared/resolve-close-order-type\";\nimport {\n ORDER_TYPE_LIMIT,\n ORDER_TYPE_MARKET,\n type InstantCloseOrder,\n type InstantCloseReturnType,\n type SolverOrderType,\n} from \"../shared/types\";\n\n/**\n * Parameters for the pure {@link instantClose} primitive.\n *\n * Every domain value is the **final** 18-decimal-wei `bigint` ready to feed\n * `requestToClosePosition`. The caller (or the `prepareInstantCloseParams`\n * wizard) is responsible for trade math.\n */\nexport type InstantCloseParameters = Compute<\n WriteSolverParameter & {\n /**\n * PartyA — the account that owns the position and signs the close\n * (EIP-712 `signerAccount`). The VA address on Enigma (lowcap); the\n * sub-account itself on Rasa (cross-margin, no VA).\n */\n partyA: Address;\n /** Order-side values (`quoteId`, `closePrice`, `quantityToClose`). */\n order: InstantCloseOrder;\n /**\n * Requested close order type: `ORDER_TYPE_MARKET` (default) or\n * `ORDER_TYPE_LIMIT` (majors / rasa only — writes a **pending close**\n * that rests at `closePrice`). Enigma market closes encode\n * `OrderType.MARKET_BEST_EFFORT` (2) before signing; Rasa encodes MARKET (1).\n */\n orderType?: SolverOrderType;\n /** Override the EIP-712 salt. Defaults to a random 32-byte salt. */\n salt?: Hex;\n /**\n * Override the unix-seconds deadline. Defaults to `now + 300s` for a market\n * close, `now + 900s` (15 min) for a limit close.\n */\n deadline?: bigint;\n }\n>;\n\n/**\n * Close (or partially close) a lowcap instant position via the InstantLayer\n * v2 flow.\n *\n * Pure primitive — every domain value is already final wei. Builds calldata\n * for one `requestToClosePosition`, signs an EIP-712 `SignedOperation`, and\n * submits it to the chain's solver/hedger `/instant_trade/instant_close`\n * endpoint. Does no math, no fetching.\n *\n * Use `prepareInstantCloseParams` to derive this shape from UI-shape inputs,\n * or `instantCloseAuto` for the combined convenience.\n *\n * @throws {SymmApiError} when the hedger request fails.\n *\n * @example\n * ```ts\n * const { success } = await instantClose(config, {\n * partyA,\n * order: {\n * quoteId: 42n,\n * closePrice: 50_000_000_000_000_000_000n,\n * quantityToClose: 1_000_000_000_000_000_000n,\n * },\n * });\n * ```\n */\nexport async function instantClose(\n config: Config,\n parameters: InstantCloseParameters,\n): Promise<InstantCloseReturnType> {\n const chainConfig = config.getChainConfig(parameters.chainId);\n const { symmioAddress } = chainConfig.addresses;\n const solver = config.getSolver({ chainId: parameters.chainId, solverId: parameters.solverId });\n\n const walletClient = await config.getWalletClient({ chainId: parameters.chainId, from: parameters.from });\n const signerAddress = walletClient.account.address;\n\n const orderType = resolveCloseOrderType(solver.id, parameters.orderType ?? ORDER_TYPE_MARKET);\n const deadline =\n parameters.deadline ?? (orderType === ORDER_TYPE_LIMIT ? getLimitOrderDeadline() : getMarketOrderDeadline());\n\n const callData = encodeRequestToClosePosition({\n quoteId: parameters.order.quoteId,\n closePrice: parameters.order.closePrice,\n quantityToClose: parameters.order.quantityToClose,\n orderType,\n deadline,\n });\n\n const operation = buildSignedOperation({\n signer: signerAddress,\n target: symmioAddress,\n callData,\n signerAccount: parameters.partyA,\n deadline,\n salt: parameters.salt,\n });\n\n const signed = await signAndFormatInstantOperation(config, {\n operation,\n chainId: parameters.chainId,\n walletClient,\n });\n\n await sendInstantClose(config, {\n chainId: parameters.chainId,\n solverId: solver.id,\n operations: [signed],\n });\n\n return { success: true };\n}\n"],"mappings":";;;;;;;AA4EA,eAAsB,EACpB,GACA,GACiC;CAEjC,IAAM,EAAE,qBADY,EAAO,eAAe,EAAW,OAC3B,EAAY,WAChC,IAAS,EAAO,UAAU;EAAE,SAAS,EAAW;EAAS,UAAU,EAAW;CAAS,CAAC,GAExF,IAAe,MAAM,EAAO,gBAAgB;EAAE,SAAS,EAAW;EAAS,MAAM,EAAW;CAAK,CAAC,GAClG,IAAgB,EAAa,QAAQ,SAErC,IAAY,EAAsB,EAAO,IAAI,EAAW,aAAA,CAA8B,GACtF,IACJ,EAAW,aAAa,MAAA,IAAiC,EAAsB,IAAI,EAAuB,IAmBtG,IAAS,MAAM,EAA8B,GAAQ;EACzD,WAVgB,EAAqB;GACrC,QAAQ;GACR,QAAQ;GACR,UAXe,EAA6B;IAC5C,SAAS,EAAW,MAAM;IAC1B,YAAY,EAAW,MAAM;IAC7B,iBAAiB,EAAW,MAAM;IAClC;IACA;GACF,CAKE;GACA,eAAe,EAAW;GAC1B;GACA,MAAM,EAAW;EACnB,CAGE;EACA,SAAS,EAAW;EACpB;CACF,CAAC;CAQD,OANA,MAAM,EAAiB,GAAQ;EAC7B,SAAS,EAAW;EACpB,UAAU,EAAO;EACjB,YAAY,CAAC,CAAM;CACrB,CAAC,GAEM,EAAE,SAAS,GAAK;AACzB"}
1
+ {"version":3,"file":"instant-close.js","names":[],"sources":["../../../../src/solvers/instant-close/instant-close/instant-close.ts"],"sourcesContent":["import type { Address, Hex } from \"viem\";\nimport type { Config } from \"../../../core/config\";\nimport type { Compute, WriteSolverParameter } from \"../../../shared/types/properties\";\nimport { buildSignedOperation, signAndFormatInstantOperation } from \"../../instant-open/shared/operations\";\nimport { getLimitOrderDeadline, getMarketOrderDeadline } from \"../../instant-open/shared/trade-math\";\nimport {\n assertInstantSignerDelegated,\n type InstantDelegationPreflightParameter,\n} from \"../../shared/instant-delegation-preflight\";\nimport { encodeRequestToClosePosition } from \"../shared/calldata\";\nimport { sendInstantClose } from \"../shared/hedger-api\";\nimport { resolveCloseOrderType } from \"../shared/resolve-close-order-type\";\nimport {\n ORDER_TYPE_LIMIT,\n ORDER_TYPE_MARKET,\n type InstantCloseOrder,\n type InstantCloseReturnType,\n type SolverOrderType,\n} from \"../shared/types\";\n\n/**\n * Parameters for the pure {@link instantClose} primitive.\n *\n * Every domain value is the **final** 18-decimal-wei `bigint` ready to feed\n * `requestToClosePosition`. The caller (or the `prepareInstantCloseParams`\n * wizard) is responsible for trade math.\n */\nexport type InstantCloseParameters = Compute<\n WriteSolverParameter &\n InstantDelegationPreflightParameter & {\n /**\n * PartyA — the account that owns the position and signs the close\n * (EIP-712 `signerAccount`). The VA address on Enigma (lowcap); the\n * sub-account itself on Rasa (cross-margin, no VA).\n */\n partyA: Address;\n /** Order-side values (`quoteId`, `closePrice`, `quantityToClose`). */\n order: InstantCloseOrder;\n /**\n * Requested close order type: `ORDER_TYPE_MARKET` (default) or\n * `ORDER_TYPE_LIMIT` (majors / rasa only — writes a **pending close**\n * that rests at `closePrice`). Enigma market closes encode\n * `OrderType.MARKET_BEST_EFFORT` (2) before signing; Rasa encodes MARKET (1).\n */\n orderType?: SolverOrderType;\n /** Override the EIP-712 salt. Defaults to a random 32-byte salt. */\n salt?: Hex;\n /**\n * Override the unix-seconds deadline. Defaults to `now + 300s` for a market\n * close, `now + 900s` (15 min) for a limit close.\n */\n deadline?: bigint;\n }\n>;\n\n/**\n * Close (or partially close) a lowcap instant position via the InstantLayer\n * v2 flow.\n *\n * Pure primitive — every domain value is already final wei. Builds calldata\n * for one `requestToClosePosition`, signs an EIP-712 `SignedOperation`, and\n * submits it to the chain's solver/hedger `/instant_trade/instant_close`\n * endpoint. Does no math, no fetching.\n *\n * Use `prepareInstantCloseParams` to derive this shape from UI-shape inputs,\n * or `instantCloseAuto` for the combined convenience.\n *\n * Before signing, it checks that the signer holds the `requestToClosePosition`\n * delegation — on the VA's parent sub-account when `partyA` is a VA (skip it\n * with `preflightDelegation: false`). The sub-account's owner needs none.\n *\n * @throws {SymmError} `INSTANT_SIGNER_NOT_DELEGATED` when the signer lacks the\n * delegation, before anything is signed.\n * @throws {SymmApiError} when the hedger request fails.\n *\n * @example\n * ```ts\n * const { success } = await instantClose(config, {\n * partyA,\n * order: {\n * quoteId: 42n,\n * closePrice: 50_000_000_000_000_000_000n,\n * quantityToClose: 1_000_000_000_000_000_000n,\n * },\n * });\n * ```\n */\nexport async function instantClose(\n config: Config,\n parameters: InstantCloseParameters,\n): Promise<InstantCloseReturnType> {\n const chainConfig = config.getChainConfig(parameters.chainId);\n const { symmioAddress } = chainConfig.addresses;\n const solver = config.getSolver({ chainId: parameters.chainId, solverId: parameters.solverId });\n\n const walletClient = await config.getWalletClient({ chainId: parameters.chainId, from: parameters.from });\n const signerAddress = walletClient.account.address;\n\n const orderType = resolveCloseOrderType(solver.id, parameters.orderType ?? ORDER_TYPE_MARKET);\n const deadline =\n parameters.deadline ?? (orderType === ORDER_TYPE_LIMIT ? getLimitOrderDeadline() : getMarketOrderDeadline());\n\n const callData = encodeRequestToClosePosition({\n quoteId: parameters.order.quoteId,\n closePrice: parameters.order.closePrice,\n quantityToClose: parameters.order.quantityToClose,\n orderType,\n deadline,\n });\n\n const operation = buildSignedOperation({\n signer: signerAddress,\n target: symmioAddress,\n callData,\n signerAccount: parameters.partyA,\n deadline,\n salt: parameters.salt,\n });\n\n await assertInstantSignerDelegated(config, {\n chainId: parameters.chainId,\n action: \"instantClose\",\n operations: [operation],\n enabled: parameters.preflightDelegation,\n });\n\n const signed = await signAndFormatInstantOperation(config, {\n operation,\n chainId: parameters.chainId,\n walletClient,\n });\n\n await sendInstantClose(config, {\n chainId: parameters.chainId,\n solverId: solver.id,\n operations: [signed],\n });\n\n return { success: true };\n}\n"],"mappings":";;;;;;;;AAuFA,eAAsB,EACpB,GACA,GACiC;CAEjC,IAAM,EAAE,qBADY,EAAO,eAAe,EAAW,OAC3B,EAAY,WAChC,IAAS,EAAO,UAAU;EAAE,SAAS,EAAW;EAAS,UAAU,EAAW;CAAS,CAAC,GAExF,IAAe,MAAM,EAAO,gBAAgB;EAAE,SAAS,EAAW;EAAS,MAAM,EAAW;CAAK,CAAC,GAClG,IAAgB,EAAa,QAAQ,SAErC,IAAY,EAAsB,EAAO,IAAI,EAAW,aAAA,CAA8B,GACtF,IACJ,EAAW,aAAa,MAAA,IAAiC,EAAsB,IAAI,EAAuB,IAUtG,IAAY,EAAqB;EACrC,QAAQ;EACR,QAAQ;EACR,UAXe,EAA6B;GAC5C,SAAS,EAAW,MAAM;GAC1B,YAAY,EAAW,MAAM;GAC7B,iBAAiB,EAAW,MAAM;GAClC;GACA;EACF,CAKE;EACA,eAAe,EAAW;EAC1B;EACA,MAAM,EAAW;CACnB,CAAC;CAED,MAAM,EAA6B,GAAQ;EACzC,SAAS,EAAW;EACpB,QAAQ;EACR,YAAY,CAAC,CAAS;EACtB,SAAS,EAAW;CACtB,CAAC;CAED,IAAM,IAAS,MAAM,EAA8B,GAAQ;EACzD;EACA,SAAS,EAAW;EACpB;CACF,CAAC;CAQD,OANA,MAAM,EAAiB,GAAQ;EAC7B,SAAS,EAAW;EACpB,UAAU,EAAO;EACjB,YAAY,CAAC,CAAM;CACrB,CAAC,GAEM,EAAE,SAAS,GAAK;AACzB"}
@@ -1,6 +1,7 @@
1
1
  import { Address, Hex } from 'viem';
2
2
  import { Config } from '../../../core/config/index.js';
3
3
  import { Compute, WriteSolverParameter } from '../../../shared/types/properties.js';
4
+ import { InstantDelegationPreflightParameter } from '../../shared/instant-delegation-preflight.js';
4
5
  import { InstantCloseOrder } from '../shared/types.js';
5
6
  /** Maximum orders per {@link instantCloseBulk} call (matches the hedger's `1–100` window). */
6
7
  export declare const MAX_INSTANT_CLOSE_BULK_ORDERS = 100;
@@ -27,7 +28,7 @@ export interface InstantCloseBulkOrder {
27
28
  * Each order may still target a different VA via its own `partyA` — the
28
29
  * delegation lives on the subaccount and is inherited by every owned VA.
29
30
  */
30
- export type InstantCloseBulkParameters = Compute<WriteSolverParameter & {
31
+ export type InstantCloseBulkParameters = Compute<WriteSolverParameter & InstantDelegationPreflightParameter & {
31
32
  /** Orders to submit. Length must be in `[1, MAX_INSTANT_CLOSE_BULK_ORDERS]`. */
32
33
  orders: readonly InstantCloseBulkOrder[];
33
34
  }>;
@@ -47,6 +48,9 @@ export interface InstantCloseBulkReturnType {
47
48
  * `from`), so the caller must hold a `requestToClosePosition` delegation on
48
49
  * the owning subaccount. The delegation is inherited by every owned VA, so
49
50
  * orders across different VAs in the same subaccount sign with one key.
51
+ * Every order is built first and that delegation is checked once per
52
+ * sub-account before any order is signed (skip it with
53
+ * `preflightDelegation: false`); the sub-account's owner needs none.
50
54
  *
51
55
  * Pure primitive — every domain value is already final wei. Use
52
56
  * `instantCloseBulkAuto` to derive these inputs from UI-shape parameters.
@@ -55,6 +59,8 @@ export interface InstantCloseBulkReturnType {
55
59
  *
56
60
  * @throws {SymmError} `INSTANT_CLOSE_BULK_INVALID_ORDERS` when the batch is
57
61
  * empty or exceeds {@link MAX_INSTANT_CLOSE_BULK_ORDERS}.
62
+ * @throws {SymmError} `INSTANT_SIGNER_NOT_DELEGATED` when the signer lacks the
63
+ * delegation for any order, before anything is signed.
58
64
  * @throws {SymmApiError} when the hedger request fails — the whole batch is
59
65
  * rejected; the caller should retry with fewer orders.
60
66
  *
@@ -1 +1 @@
1
- {"version":3,"file":"instant-close-bulk.d.ts","sourceRoot":"","sources":["../../../../src/solvers/instant-close/instant-close-bulk/instant-close-bulk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAMtF,OAAO,EAAqB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAE5E,8FAA8F;AAC9F,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAEjD;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,wEAAwE;IACxE,MAAM,EAAE,OAAO,CAAC;IAChB,4EAA4E;IAC5E,KAAK,EAAE,iBAAiB,CAAC;IACzB,mFAAmF;IACnF,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,0BAA0B,GAAG,OAAO,CAC9C,oBAAoB,GAAG;IACrB,gFAAgF;IAChF,MAAM,EAAE,SAAS,qBAAqB,EAAE,CAAC;CAC1C,CACF,CAAC;AAEF,+CAA+C;AAC/C,MAAM,WAAW,0BAA0B;IACzC,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,OAAO,EAAE,IAAI,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,0BAA0B,GACrC,OAAO,CAAC,0BAA0B,CAAC,CA4DrC"}
1
+ {"version":3,"file":"instant-close-bulk.d.ts","sourceRoot":"","sources":["../../../../src/solvers/instant-close/instant-close-bulk/instant-close-bulk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAGtF,OAAO,EAEL,KAAK,mCAAmC,EACzC,MAAM,2CAA2C,CAAC;AAInD,OAAO,EAAqB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAE5E,8FAA8F;AAC9F,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAEjD;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,wEAAwE;IACxE,MAAM,EAAE,OAAO,CAAC;IAChB,4EAA4E;IAC5E,KAAK,EAAE,iBAAiB,CAAC;IACzB,mFAAmF;IACnF,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,0BAA0B,GAAG,OAAO,CAC9C,oBAAoB,GAClB,mCAAmC,GAAG;IACpC,gFAAgF;IAChF,MAAM,EAAE,SAAS,qBAAqB,EAAE,CAAC;CAC1C,CACJ,CAAC;AAEF,+CAA+C;AAC/C,MAAM,WAAW,0BAA0B;IACzC,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,OAAO,EAAE,IAAI,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,0BAA0B,GACrC,OAAO,CAAC,0BAA0B,CAAC,CAuErC"}
@@ -1,53 +1,61 @@
1
1
  import { SymmError as e } from "../../../shared/errors/symm-error.js";
2
2
  import { buildSignedOperation as t, signAndFormatInstantOperation as n } from "../../instant-open/shared/operations.js";
3
+ import { assertInstantSignerDelegated as r } from "../../shared/instant-delegation-preflight.js";
3
4
  import "../../instant-open/shared/types.js";
4
- import { getMarketOrderDeadline as r } from "../../instant-open/shared/trade-math.js";
5
- import { encodeRequestToClosePosition as i } from "../shared/calldata.js";
6
- import { sendInstantClose as a } from "../shared/hedger-api.js";
7
- import { resolveCloseOrderType as o } from "../shared/resolve-close-order-type.js";
5
+ import { getMarketOrderDeadline as i } from "../../instant-open/shared/trade-math.js";
6
+ import { encodeRequestToClosePosition as a } from "../shared/calldata.js";
7
+ import { sendInstantClose as o } from "../shared/hedger-api.js";
8
+ import { resolveCloseOrderType as s } from "../shared/resolve-close-order-type.js";
8
9
  //#region src/solvers/instant-close/instant-close-bulk/instant-close-bulk.ts
9
- var s = 100;
10
- async function c(s, c) {
11
- if (c.orders.length === 0) throw new e("validation", "INSTANT_CLOSE_BULK_INVALID_ORDERS", "instantCloseBulk: at least one order is required.");
12
- if (c.orders.length > 100) throw new e("validation", "INSTANT_CLOSE_BULK_INVALID_ORDERS", `instantCloseBulk: at most 100 orders per call; received ${c.orders.length}.`);
13
- let { symmioAddress: l } = s.getChainConfig(c.chainId).addresses, u = s.getSolver({
14
- chainId: c.chainId,
15
- solverId: c.solverId
16
- }), d = o(u.id, 1), f = await s.getWalletClient({
17
- chainId: c.chainId,
18
- from: c.from
19
- }), p = f.account.address, m = [];
20
- for (let e of c.orders) {
21
- let a = e.deadline ?? r(), o = await n(s, {
22
- operation: t({
23
- signer: p,
24
- target: l,
25
- callData: i({
26
- quoteId: e.order.quoteId,
27
- closePrice: e.order.closePrice,
28
- quantityToClose: e.order.quantityToClose,
29
- orderType: d,
30
- deadline: a
31
- }),
32
- signerAccount: e.partyA,
33
- deadline: a,
34
- salt: e.salt
10
+ var c = 100;
11
+ async function l(c, l) {
12
+ if (l.orders.length === 0) throw new e("validation", "INSTANT_CLOSE_BULK_INVALID_ORDERS", "instantCloseBulk: at least one order is required.");
13
+ if (l.orders.length > 100) throw new e("validation", "INSTANT_CLOSE_BULK_INVALID_ORDERS", `instantCloseBulk: at most 100 orders per call; received ${l.orders.length}.`);
14
+ let { symmioAddress: u } = c.getChainConfig(l.chainId).addresses, d = c.getSolver({
15
+ chainId: l.chainId,
16
+ solverId: l.solverId
17
+ }), f = s(d.id, 1), p = await c.getWalletClient({
18
+ chainId: l.chainId,
19
+ from: l.from
20
+ }), m = p.account.address, h = l.orders.map((e) => {
21
+ let n = e.deadline ?? i();
22
+ return t({
23
+ signer: m,
24
+ target: u,
25
+ callData: a({
26
+ quoteId: e.order.quoteId,
27
+ closePrice: e.order.closePrice,
28
+ quantityToClose: e.order.quantityToClose,
29
+ orderType: f,
30
+ deadline: n
35
31
  }),
36
- chainId: c.chainId,
37
- walletClient: f
32
+ signerAccount: e.partyA,
33
+ deadline: n,
34
+ salt: e.salt
38
35
  });
39
- m.push(o);
40
- }
41
- return await a(s, {
42
- chainId: c.chainId,
43
- solverId: u.id,
44
- operations: m
36
+ });
37
+ await r(c, {
38
+ chainId: l.chainId,
39
+ action: "instantCloseBulk",
40
+ operations: h,
41
+ enabled: l.preflightDelegation
42
+ });
43
+ let g = [];
44
+ for (let e of h) g.push(await n(c, {
45
+ operation: e,
46
+ chainId: l.chainId,
47
+ walletClient: p
48
+ }));
49
+ return await o(c, {
50
+ chainId: l.chainId,
51
+ solverId: d.id,
52
+ operations: g
45
53
  }), {
46
- count: m.length,
54
+ count: g.length,
47
55
  success: !0
48
56
  };
49
57
  }
50
58
  //#endregion
51
- export { s as MAX_INSTANT_CLOSE_BULK_ORDERS, c as instantCloseBulk };
59
+ export { c as MAX_INSTANT_CLOSE_BULK_ORDERS, l as instantCloseBulk };
52
60
 
53
61
  //# sourceMappingURL=instant-close-bulk.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"instant-close-bulk.js","names":[],"sources":["../../../../src/solvers/instant-close/instant-close-bulk/instant-close-bulk.ts"],"sourcesContent":["import type { Address, Hex } from \"viem\";\nimport type { Config } from \"../../../core/config\";\nimport { SymmError } from \"../../../shared/errors/symm-error\";\nimport type { Compute, WriteSolverParameter } from \"../../../shared/types/properties\";\nimport { buildSignedOperation, signAndFormatInstantOperation } from \"../../instant-open/shared/operations\";\nimport { getMarketOrderDeadline } from \"../../instant-open/shared/trade-math\";\nimport { encodeRequestToClosePosition } from \"../shared/calldata\";\nimport { sendInstantClose } from \"../shared/hedger-api\";\nimport { resolveCloseOrderType } from \"../shared/resolve-close-order-type\";\nimport { ORDER_TYPE_MARKET, type InstantCloseOrder } from \"../shared/types\";\n\n/** Maximum orders per {@link instantCloseBulk} call (matches the hedger's `1–100` window). */\nexport const MAX_INSTANT_CLOSE_BULK_ORDERS = 100;\n\n/**\n * One position contributing to a {@link instantCloseBulk} batch. Each entry is\n * already fully-resolved: a VA address, the wei-shape order, and optional\n * per-order salt / deadline overrides.\n */\nexport interface InstantCloseBulkOrder {\n /** PartyA — the VA that owns the position (EIP-712 `signerAccount`). */\n partyA: Address;\n /** Already-final wei order (`quoteId`, `closePrice`, `quantityToClose`). */\n order: InstantCloseOrder;\n /** Override the EIP-712 salt for this order. Defaults to a random 32-byte salt. */\n salt?: Hex;\n /** Override the unix-seconds deadline for this order. Defaults to `now + 300s`. */\n deadline?: bigint;\n}\n\n/**\n * Parameters for {@link instantCloseBulk}.\n *\n * The wallet client identified by `from` is reused to sign every order, so all\n * orders in a batch share the same signer (the subaccount-level session key).\n * Each order may still target a different VA via its own `partyA` — the\n * delegation lives on the subaccount and is inherited by every owned VA.\n */\nexport type InstantCloseBulkParameters = Compute<\n WriteSolverParameter & {\n /** Orders to submit. Length must be in `[1, MAX_INSTANT_CLOSE_BULK_ORDERS]`. */\n orders: readonly InstantCloseBulkOrder[];\n }\n>;\n\n/** Return type of {@link instantCloseBulk}. */\nexport interface InstantCloseBulkReturnType {\n /** Number of orders submitted. */\n count: number;\n /** Always `true` on success — the hedger returns no per-order body. */\n success: true;\n}\n\n/**\n * Close multiple lowcap positions in one solver round-trip via the InstantLayer\n * v2 `/instant_trade/instant_close` endpoint, which natively accepts 1–100\n * signed operations per request.\n *\n * Each order is signed with the same wallet client (the session key bound to\n * `from`), so the caller must hold a `requestToClosePosition` delegation on\n * the owning subaccount. The delegation is inherited by every owned VA, so\n * orders across different VAs in the same subaccount sign with one key.\n *\n * Pure primitive — every domain value is already final wei. Use\n * `instantCloseBulkAuto` to derive these inputs from UI-shape parameters.\n * Enigma market closes encode `OrderType.MARKET_BEST_EFFORT` (2) before\n * signing; Rasa market closes encode MARKET (1).\n *\n * @throws {SymmError} `INSTANT_CLOSE_BULK_INVALID_ORDERS` when the batch is\n * empty or exceeds {@link MAX_INSTANT_CLOSE_BULK_ORDERS}.\n * @throws {SymmApiError} when the hedger request fails — the whole batch is\n * rejected; the caller should retry with fewer orders.\n *\n * @example\n * ```ts\n * await instantCloseBulk(config, {\n * from: sessionKey,\n * orders: [\n * { partyA: vaA, order: { quoteId: 1n, closePrice: …, quantityToClose: … } },\n * { partyA: vaB, order: { quoteId: 2n, closePrice: …, quantityToClose: … } },\n * ],\n * });\n * ```\n */\nexport async function instantCloseBulk(\n config: Config,\n parameters: InstantCloseBulkParameters,\n): Promise<InstantCloseBulkReturnType> {\n if (parameters.orders.length === 0) {\n throw new SymmError(\n \"validation\",\n \"INSTANT_CLOSE_BULK_INVALID_ORDERS\",\n \"instantCloseBulk: at least one order is required.\",\n );\n }\n if (parameters.orders.length > MAX_INSTANT_CLOSE_BULK_ORDERS) {\n throw new SymmError(\n \"validation\",\n \"INSTANT_CLOSE_BULK_INVALID_ORDERS\",\n `instantCloseBulk: at most ${MAX_INSTANT_CLOSE_BULK_ORDERS} orders per call; received ${parameters.orders.length}.`,\n );\n }\n\n const chainConfig = config.getChainConfig(parameters.chainId);\n const { symmioAddress } = chainConfig.addresses;\n const solver = config.getSolver({ chainId: parameters.chainId, solverId: parameters.solverId });\n const orderType = resolveCloseOrderType(solver.id, ORDER_TYPE_MARKET);\n\n const walletClient = await config.getWalletClient({ chainId: parameters.chainId, from: parameters.from });\n const signerAddress = walletClient.account.address;\n\n const signedOperations = [] as Awaited<ReturnType<typeof signAndFormatInstantOperation>>[];\n for (const entry of parameters.orders) {\n const deadline = entry.deadline ?? getMarketOrderDeadline();\n\n const callData = encodeRequestToClosePosition({\n quoteId: entry.order.quoteId,\n closePrice: entry.order.closePrice,\n quantityToClose: entry.order.quantityToClose,\n orderType,\n deadline,\n });\n\n const operation = buildSignedOperation({\n signer: signerAddress,\n target: symmioAddress,\n callData,\n signerAccount: entry.partyA,\n deadline,\n salt: entry.salt,\n });\n\n const signed = await signAndFormatInstantOperation(config, {\n operation,\n chainId: parameters.chainId,\n walletClient,\n });\n signedOperations.push(signed);\n }\n\n await sendInstantClose(config, {\n chainId: parameters.chainId,\n solverId: solver.id,\n operations: signedOperations,\n });\n\n return { count: signedOperations.length, success: true };\n}\n"],"mappings":";;;;;;;;AAYA,IAAa,IAAgC;AAwE7C,eAAsB,EACpB,GACA,GACqC;CACrC,IAAI,EAAW,OAAO,WAAW,GAC/B,MAAM,IAAI,EACR,cACA,qCACA,mDACF;CAEF,IAAI,EAAW,OAAO,SAAA,KACpB,MAAM,IAAI,EACR,cACA,qCACA,2DAAwF,EAAW,OAAO,OAAO,EACnH;CAIF,IAAM,EAAE,qBADY,EAAO,eAAe,EAAW,OAC3B,EAAY,WAChC,IAAS,EAAO,UAAU;EAAE,SAAS,EAAW;EAAS,UAAU,EAAW;CAAS,CAAC,GACxF,IAAY,EAAsB,EAAO,IAAA,CAAqB,GAE9D,IAAe,MAAM,EAAO,gBAAgB;EAAE,SAAS,EAAW;EAAS,MAAM,EAAW;CAAK,CAAC,GAClG,IAAgB,EAAa,QAAQ,SAErC,IAAmB,CAAC;CAC1B,KAAK,IAAM,KAAS,EAAW,QAAQ;EACrC,IAAM,IAAW,EAAM,YAAY,EAAuB,GAmBpD,IAAS,MAAM,EAA8B,GAAQ;GACzD,WAVgB,EAAqB;IACrC,QAAQ;IACR,QAAQ;IACR,UAXe,EAA6B;KAC5C,SAAS,EAAM,MAAM;KACrB,YAAY,EAAM,MAAM;KACxB,iBAAiB,EAAM,MAAM;KAC7B;KACA;IACF,CAKE;IACA,eAAe,EAAM;IACrB;IACA,MAAM,EAAM;GACd,CAGE;GACA,SAAS,EAAW;GACpB;EACF,CAAC;EACD,EAAiB,KAAK,CAAM;CAC9B;CAQA,OANA,MAAM,EAAiB,GAAQ;EAC7B,SAAS,EAAW;EACpB,UAAU,EAAO;EACjB,YAAY;CACd,CAAC,GAEM;EAAE,OAAO,EAAiB;EAAQ,SAAS;CAAK;AACzD"}
1
+ {"version":3,"file":"instant-close-bulk.js","names":[],"sources":["../../../../src/solvers/instant-close/instant-close-bulk/instant-close-bulk.ts"],"sourcesContent":["import type { Address, Hex } from \"viem\";\nimport type { Config } from \"../../../core/config\";\nimport { SymmError } from \"../../../shared/errors/symm-error\";\nimport type { Compute, WriteSolverParameter } from \"../../../shared/types/properties\";\nimport { buildSignedOperation, signAndFormatInstantOperation } from \"../../instant-open/shared/operations\";\nimport { getMarketOrderDeadline } from \"../../instant-open/shared/trade-math\";\nimport {\n assertInstantSignerDelegated,\n type InstantDelegationPreflightParameter,\n} from \"../../shared/instant-delegation-preflight\";\nimport { encodeRequestToClosePosition } from \"../shared/calldata\";\nimport { sendInstantClose } from \"../shared/hedger-api\";\nimport { resolveCloseOrderType } from \"../shared/resolve-close-order-type\";\nimport { ORDER_TYPE_MARKET, type InstantCloseOrder } from \"../shared/types\";\n\n/** Maximum orders per {@link instantCloseBulk} call (matches the hedger's `1–100` window). */\nexport const MAX_INSTANT_CLOSE_BULK_ORDERS = 100;\n\n/**\n * One position contributing to a {@link instantCloseBulk} batch. Each entry is\n * already fully-resolved: a VA address, the wei-shape order, and optional\n * per-order salt / deadline overrides.\n */\nexport interface InstantCloseBulkOrder {\n /** PartyA — the VA that owns the position (EIP-712 `signerAccount`). */\n partyA: Address;\n /** Already-final wei order (`quoteId`, `closePrice`, `quantityToClose`). */\n order: InstantCloseOrder;\n /** Override the EIP-712 salt for this order. Defaults to a random 32-byte salt. */\n salt?: Hex;\n /** Override the unix-seconds deadline for this order. Defaults to `now + 300s`. */\n deadline?: bigint;\n}\n\n/**\n * Parameters for {@link instantCloseBulk}.\n *\n * The wallet client identified by `from` is reused to sign every order, so all\n * orders in a batch share the same signer (the subaccount-level session key).\n * Each order may still target a different VA via its own `partyA` — the\n * delegation lives on the subaccount and is inherited by every owned VA.\n */\nexport type InstantCloseBulkParameters = Compute<\n WriteSolverParameter &\n InstantDelegationPreflightParameter & {\n /** Orders to submit. Length must be in `[1, MAX_INSTANT_CLOSE_BULK_ORDERS]`. */\n orders: readonly InstantCloseBulkOrder[];\n }\n>;\n\n/** Return type of {@link instantCloseBulk}. */\nexport interface InstantCloseBulkReturnType {\n /** Number of orders submitted. */\n count: number;\n /** Always `true` on success — the hedger returns no per-order body. */\n success: true;\n}\n\n/**\n * Close multiple lowcap positions in one solver round-trip via the InstantLayer\n * v2 `/instant_trade/instant_close` endpoint, which natively accepts 1–100\n * signed operations per request.\n *\n * Each order is signed with the same wallet client (the session key bound to\n * `from`), so the caller must hold a `requestToClosePosition` delegation on\n * the owning subaccount. The delegation is inherited by every owned VA, so\n * orders across different VAs in the same subaccount sign with one key.\n * Every order is built first and that delegation is checked once per\n * sub-account before any order is signed (skip it with\n * `preflightDelegation: false`); the sub-account's owner needs none.\n *\n * Pure primitive — every domain value is already final wei. Use\n * `instantCloseBulkAuto` to derive these inputs from UI-shape parameters.\n * Enigma market closes encode `OrderType.MARKET_BEST_EFFORT` (2) before\n * signing; Rasa market closes encode MARKET (1).\n *\n * @throws {SymmError} `INSTANT_CLOSE_BULK_INVALID_ORDERS` when the batch is\n * empty or exceeds {@link MAX_INSTANT_CLOSE_BULK_ORDERS}.\n * @throws {SymmError} `INSTANT_SIGNER_NOT_DELEGATED` when the signer lacks the\n * delegation for any order, before anything is signed.\n * @throws {SymmApiError} when the hedger request fails — the whole batch is\n * rejected; the caller should retry with fewer orders.\n *\n * @example\n * ```ts\n * await instantCloseBulk(config, {\n * from: sessionKey,\n * orders: [\n * { partyA: vaA, order: { quoteId: 1n, closePrice: …, quantityToClose: … } },\n * { partyA: vaB, order: { quoteId: 2n, closePrice: …, quantityToClose: … } },\n * ],\n * });\n * ```\n */\nexport async function instantCloseBulk(\n config: Config,\n parameters: InstantCloseBulkParameters,\n): Promise<InstantCloseBulkReturnType> {\n if (parameters.orders.length === 0) {\n throw new SymmError(\n \"validation\",\n \"INSTANT_CLOSE_BULK_INVALID_ORDERS\",\n \"instantCloseBulk: at least one order is required.\",\n );\n }\n if (parameters.orders.length > MAX_INSTANT_CLOSE_BULK_ORDERS) {\n throw new SymmError(\n \"validation\",\n \"INSTANT_CLOSE_BULK_INVALID_ORDERS\",\n `instantCloseBulk: at most ${MAX_INSTANT_CLOSE_BULK_ORDERS} orders per call; received ${parameters.orders.length}.`,\n );\n }\n\n const chainConfig = config.getChainConfig(parameters.chainId);\n const { symmioAddress } = chainConfig.addresses;\n const solver = config.getSolver({ chainId: parameters.chainId, solverId: parameters.solverId });\n const orderType = resolveCloseOrderType(solver.id, ORDER_TYPE_MARKET);\n\n const walletClient = await config.getWalletClient({ chainId: parameters.chainId, from: parameters.from });\n const signerAddress = walletClient.account.address;\n\n const operations = parameters.orders.map((entry) => {\n const deadline = entry.deadline ?? getMarketOrderDeadline();\n\n const callData = encodeRequestToClosePosition({\n quoteId: entry.order.quoteId,\n closePrice: entry.order.closePrice,\n quantityToClose: entry.order.quantityToClose,\n orderType,\n deadline,\n });\n\n return buildSignedOperation({\n signer: signerAddress,\n target: symmioAddress,\n callData,\n signerAccount: entry.partyA,\n deadline,\n salt: entry.salt,\n });\n });\n\n await assertInstantSignerDelegated(config, {\n chainId: parameters.chainId,\n action: \"instantCloseBulk\",\n operations,\n enabled: parameters.preflightDelegation,\n });\n\n /** One at a time, so a wallet signer sees its prompts in order. */\n const signedOperations = [] as Awaited<ReturnType<typeof signAndFormatInstantOperation>>[];\n for (const operation of operations) {\n signedOperations.push(\n await signAndFormatInstantOperation(config, {\n operation,\n chainId: parameters.chainId,\n walletClient,\n }),\n );\n }\n\n await sendInstantClose(config, {\n chainId: parameters.chainId,\n solverId: solver.id,\n operations: signedOperations,\n });\n\n return { count: signedOperations.length, success: true };\n}\n"],"mappings":";;;;;;;;;AAgBA,IAAa,IAAgC;AA8E7C,eAAsB,EACpB,GACA,GACqC;CACrC,IAAI,EAAW,OAAO,WAAW,GAC/B,MAAM,IAAI,EACR,cACA,qCACA,mDACF;CAEF,IAAI,EAAW,OAAO,SAAA,KACpB,MAAM,IAAI,EACR,cACA,qCACA,2DAAwF,EAAW,OAAO,OAAO,EACnH;CAIF,IAAM,EAAE,qBADY,EAAO,eAAe,EAAW,OAC3B,EAAY,WAChC,IAAS,EAAO,UAAU;EAAE,SAAS,EAAW;EAAS,UAAU,EAAW;CAAS,CAAC,GACxF,IAAY,EAAsB,EAAO,IAAA,CAAqB,GAE9D,IAAe,MAAM,EAAO,gBAAgB;EAAE,SAAS,EAAW;EAAS,MAAM,EAAW;CAAK,CAAC,GAClG,IAAgB,EAAa,QAAQ,SAErC,IAAa,EAAW,OAAO,KAAK,MAAU;EAClD,IAAM,IAAW,EAAM,YAAY,EAAuB;EAU1D,OAAO,EAAqB;GAC1B,QAAQ;GACR,QAAQ;GACR,UAXe,EAA6B;IAC5C,SAAS,EAAM,MAAM;IACrB,YAAY,EAAM,MAAM;IACxB,iBAAiB,EAAM,MAAM;IAC7B;IACA;GACF,CAKE;GACA,eAAe,EAAM;GACrB;GACA,MAAM,EAAM;EACd,CAAC;CACH,CAAC;CAED,MAAM,EAA6B,GAAQ;EACzC,SAAS,EAAW;EACpB,QAAQ;EACR;EACA,SAAS,EAAW;CACtB,CAAC;CAGD,IAAM,IAAmB,CAAC;CAC1B,KAAK,IAAM,KAAa,GACtB,EAAiB,KACf,MAAM,EAA8B,GAAQ;EAC1C;EACA,SAAS,EAAW;EACpB;CACF,CAAC,CACH;CASF,OANA,MAAM,EAAiB,GAAQ;EAC7B,SAAS,EAAW;EACpB,UAAU,EAAO;EACjB,YAAY;CACd,CAAC,GAEM;EAAE,OAAO,EAAiB;EAAQ,SAAS;CAAK;AACzD"}
@@ -1,6 +1,7 @@
1
1
  import { Address, Hex } from 'viem';
2
2
  import { Config } from '../../../core/config/index.js';
3
3
  import { Compute, WriteSolverParameter } from '../../../shared/types/properties.js';
4
+ import { InstantDelegationPreflightParameter } from '../../shared/instant-delegation-preflight.js';
4
5
  import { InstantCloseBulkReturnType } from '../instant-close-bulk/instant-close-bulk.js';
5
6
  import { InstantCloseMarketData, PositionType } from '../shared/types.js';
6
7
  /**
@@ -30,9 +31,10 @@ export interface InstantCloseBulkAutoOrder {
30
31
  deadline?: bigint;
31
32
  }
32
33
  /**
33
- * Parameters for {@link instantCloseBulkAuto}.
34
+ * Parameters for {@link instantCloseBulkAuto}. `preflightDelegation` is
35
+ * forwarded to `instantCloseBulk`.
34
36
  */
35
- export type InstantCloseBulkAutoParameters = Compute<WriteSolverParameter & {
37
+ export type InstantCloseBulkAutoParameters = Compute<WriteSolverParameter & InstantDelegationPreflightParameter & {
36
38
  orders: readonly InstantCloseBulkAutoOrder[];
37
39
  }>;
38
40
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"instant-close-bulk-auto.d.ts","sourceRoot":"","sources":["../../../../src/solvers/instant-close/instant-close-bulk-auto/instant-close-bulk-auto.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACtF,OAAO,EAGL,KAAK,0BAA0B,EAChC,MAAM,0CAA0C,CAAC;AAElD,OAAO,EAAE,KAAK,sBAAsB,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEjF;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB;IACxC,8CAA8C;IAC9C,MAAM,EAAE,OAAO,CAAC;IAChB,uEAAuE;IACvE,MAAM,EAAE,sBAAsB,CAAC;IAC/B,yCAAyC;IACzC,YAAY,EAAE,YAAY,CAAC;IAC3B,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,eAAe,EAAE,MAAM,CAAC;IACxB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,8BAA8B,GAAG,OAAO,CAClD,oBAAoB,GAAG;IACrB,MAAM,EAAE,SAAS,yBAAyB,EAAE,CAAC;CAC9C,CACF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,8BAA8B,GACzC,OAAO,CAAC,0BAA0B,CAAC,CAiCrC"}
1
+ {"version":3,"file":"instant-close-bulk-auto.d.ts","sourceRoot":"","sources":["../../../../src/solvers/instant-close/instant-close-bulk-auto/instant-close-bulk-auto.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACtF,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,2CAA2C,CAAC;AACrG,OAAO,EAGL,KAAK,0BAA0B,EAChC,MAAM,0CAA0C,CAAC;AAElD,OAAO,EAAE,KAAK,sBAAsB,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEjF;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB;IACxC,8CAA8C;IAC9C,MAAM,EAAE,OAAO,CAAC;IAChB,uEAAuE;IACvE,MAAM,EAAE,sBAAsB,CAAC;IAC/B,yCAAyC;IACzC,YAAY,EAAE,YAAY,CAAC;IAC3B,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,eAAe,EAAE,MAAM,CAAC;IACxB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,8BAA8B,GAAG,OAAO,CAClD,oBAAoB,GAClB,mCAAmC,GAAG;IACpC,MAAM,EAAE,SAAS,yBAAyB,EAAE,CAAC;CAC9C,CACJ,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,8BAA8B,GACzC,OAAO,CAAC,0BAA0B,CAAC,CAkCrC"}
@@ -27,6 +27,7 @@ async function n(n, r) {
27
27
  chainId: r.chainId,
28
28
  from: r.from,
29
29
  solverId: r.solverId,
30
+ preflightDelegation: r.preflightDelegation,
30
31
  orders: i
31
32
  });
32
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"instant-close-bulk-auto.js","names":[],"sources":["../../../../src/solvers/instant-close/instant-close-bulk-auto/instant-close-bulk-auto.ts"],"sourcesContent":["import type { Address, Hex } from \"viem\";\nimport type { Config } from \"../../../core/config\";\nimport type { Compute, WriteSolverParameter } from \"../../../shared/types/properties\";\nimport {\n instantCloseBulk,\n type InstantCloseBulkOrder,\n type InstantCloseBulkReturnType,\n} from \"../instant-close-bulk/instant-close-bulk\";\nimport { prepareInstantCloseParams } from \"../prepare-instant-close-params/prepare-instant-close-params\";\nimport { type InstantCloseMarketData, type PositionType } from \"../shared/types\";\n\n/**\n * One UI-shape close intent inside an {@link instantCloseBulkAuto} batch. Each\n * entry mirrors `prepareInstantCloseParams` minus the per-call `from`/`chainId`\n * — those are hoisted to the batch parameters because the whole batch shares\n * one signer and chain.\n */\nexport interface InstantCloseBulkAutoOrder {\n /** PartyA — the VA that owns the position. */\n partyA: Address;\n /** Market identification + optional pre-fetched precision metadata. */\n market: InstantCloseMarketData;\n /** Side of the position being closed. */\n positionType: PositionType;\n /** Quote id of the position. */\n quoteId: bigint;\n /** Quantity to close as decimal string (base-token units). */\n quantityToClose: string;\n /** Slippage tolerance percent (e.g. `5` for 5%). */\n slippage: number;\n /** Pre-fetched mark price as decimal string. */\n markPrice?: string;\n /** Override the EIP-712 salt for this order. */\n salt?: Hex;\n /** Override the unix-seconds deadline for this order. */\n deadline?: bigint;\n}\n\n/**\n * Parameters for {@link instantCloseBulkAuto}.\n */\nexport type InstantCloseBulkAutoParameters = Compute<\n WriteSolverParameter & {\n orders: readonly InstantCloseBulkAutoOrder[];\n }\n>;\n\n/**\n * Resolve every order's missing wei fields via\n * `prepareInstantCloseParams` (parallel) and submit them in one\n * `instantCloseBulk` round-trip.\n *\n * Friendly default for callers that have a list of close intents and trust the\n * SDK to fetch market/price metadata. For full control, call\n * `prepareInstantCloseParams` per order + `instantCloseBulk` directly.\n *\n * @example\n * ```ts\n * await instantCloseBulkAuto(config, {\n * from: sessionKey,\n * orders: [\n * { partyA: vaA, market: { id: 1 }, positionType: PositionType.LONG, quoteId: 1n, quantityToClose: \"0.5\", slippage: 5 },\n * { partyA: vaB, market: { id: 2 }, positionType: PositionType.SHORT, quoteId: 2n, quantityToClose: \"1.0\", slippage: 5 },\n * ],\n * });\n * ```\n */\nexport async function instantCloseBulkAuto(\n config: Config,\n parameters: InstantCloseBulkAutoParameters,\n): Promise<InstantCloseBulkReturnType> {\n const resolved = await Promise.all(\n parameters.orders.map(async (intent): Promise<InstantCloseBulkOrder> => {\n const prepared = await prepareInstantCloseParams(config, {\n chainId: parameters.chainId,\n from: parameters.from,\n partyA: intent.partyA,\n market: intent.market,\n positionType: intent.positionType,\n quoteId: intent.quoteId,\n quantityToClose: intent.quantityToClose,\n slippage: intent.slippage,\n markPrice: intent.markPrice,\n salt: intent.salt,\n deadline: intent.deadline,\n });\n return {\n partyA: prepared.partyA,\n order: prepared.order,\n salt: prepared.salt,\n deadline: prepared.deadline,\n };\n }),\n );\n\n return instantCloseBulk(config, {\n chainId: parameters.chainId,\n from: parameters.from,\n // Forward the resolved solver so a bulk close on a rasa chain hits its own\n // endpoint instead of falling back to the chain default.\n solverId: parameters.solverId,\n orders: resolved,\n });\n}\n"],"mappings":";;;AAmEA,eAAsB,EACpB,GACA,GACqC;CACrC,IAAM,IAAW,MAAM,QAAQ,IAC7B,EAAW,OAAO,IAAI,OAAO,MAA2C;EACtE,IAAM,IAAW,MAAM,EAA0B,GAAQ;GACvD,SAAS,EAAW;GACpB,MAAM,EAAW;GACjB,QAAQ,EAAO;GACf,QAAQ,EAAO;GACf,cAAc,EAAO;GACrB,SAAS,EAAO;GAChB,iBAAiB,EAAO;GACxB,UAAU,EAAO;GACjB,WAAW,EAAO;GAClB,MAAM,EAAO;GACb,UAAU,EAAO;EACnB,CAAC;EACD,OAAO;GACL,QAAQ,EAAS;GACjB,OAAO,EAAS;GAChB,MAAM,EAAS;GACf,UAAU,EAAS;EACrB;CACF,CAAC,CACH;CAEA,OAAO,EAAiB,GAAQ;EAC9B,SAAS,EAAW;EACpB,MAAM,EAAW;EAGjB,UAAU,EAAW;EACrB,QAAQ;CACV,CAAC;AACH"}
1
+ {"version":3,"file":"instant-close-bulk-auto.js","names":[],"sources":["../../../../src/solvers/instant-close/instant-close-bulk-auto/instant-close-bulk-auto.ts"],"sourcesContent":["import type { Address, Hex } from \"viem\";\nimport type { Config } from \"../../../core/config\";\nimport type { Compute, WriteSolverParameter } from \"../../../shared/types/properties\";\nimport type { InstantDelegationPreflightParameter } from \"../../shared/instant-delegation-preflight\";\nimport {\n instantCloseBulk,\n type InstantCloseBulkOrder,\n type InstantCloseBulkReturnType,\n} from \"../instant-close-bulk/instant-close-bulk\";\nimport { prepareInstantCloseParams } from \"../prepare-instant-close-params/prepare-instant-close-params\";\nimport { type InstantCloseMarketData, type PositionType } from \"../shared/types\";\n\n/**\n * One UI-shape close intent inside an {@link instantCloseBulkAuto} batch. Each\n * entry mirrors `prepareInstantCloseParams` minus the per-call `from`/`chainId`\n * — those are hoisted to the batch parameters because the whole batch shares\n * one signer and chain.\n */\nexport interface InstantCloseBulkAutoOrder {\n /** PartyA — the VA that owns the position. */\n partyA: Address;\n /** Market identification + optional pre-fetched precision metadata. */\n market: InstantCloseMarketData;\n /** Side of the position being closed. */\n positionType: PositionType;\n /** Quote id of the position. */\n quoteId: bigint;\n /** Quantity to close as decimal string (base-token units). */\n quantityToClose: string;\n /** Slippage tolerance percent (e.g. `5` for 5%). */\n slippage: number;\n /** Pre-fetched mark price as decimal string. */\n markPrice?: string;\n /** Override the EIP-712 salt for this order. */\n salt?: Hex;\n /** Override the unix-seconds deadline for this order. */\n deadline?: bigint;\n}\n\n/**\n * Parameters for {@link instantCloseBulkAuto}. `preflightDelegation` is\n * forwarded to `instantCloseBulk`.\n */\nexport type InstantCloseBulkAutoParameters = Compute<\n WriteSolverParameter &\n InstantDelegationPreflightParameter & {\n orders: readonly InstantCloseBulkAutoOrder[];\n }\n>;\n\n/**\n * Resolve every order's missing wei fields via\n * `prepareInstantCloseParams` (parallel) and submit them in one\n * `instantCloseBulk` round-trip.\n *\n * Friendly default for callers that have a list of close intents and trust the\n * SDK to fetch market/price metadata. For full control, call\n * `prepareInstantCloseParams` per order + `instantCloseBulk` directly.\n *\n * @example\n * ```ts\n * await instantCloseBulkAuto(config, {\n * from: sessionKey,\n * orders: [\n * { partyA: vaA, market: { id: 1 }, positionType: PositionType.LONG, quoteId: 1n, quantityToClose: \"0.5\", slippage: 5 },\n * { partyA: vaB, market: { id: 2 }, positionType: PositionType.SHORT, quoteId: 2n, quantityToClose: \"1.0\", slippage: 5 },\n * ],\n * });\n * ```\n */\nexport async function instantCloseBulkAuto(\n config: Config,\n parameters: InstantCloseBulkAutoParameters,\n): Promise<InstantCloseBulkReturnType> {\n const resolved = await Promise.all(\n parameters.orders.map(async (intent): Promise<InstantCloseBulkOrder> => {\n const prepared = await prepareInstantCloseParams(config, {\n chainId: parameters.chainId,\n from: parameters.from,\n partyA: intent.partyA,\n market: intent.market,\n positionType: intent.positionType,\n quoteId: intent.quoteId,\n quantityToClose: intent.quantityToClose,\n slippage: intent.slippage,\n markPrice: intent.markPrice,\n salt: intent.salt,\n deadline: intent.deadline,\n });\n return {\n partyA: prepared.partyA,\n order: prepared.order,\n salt: prepared.salt,\n deadline: prepared.deadline,\n };\n }),\n );\n\n return instantCloseBulk(config, {\n chainId: parameters.chainId,\n from: parameters.from,\n // Forward the resolved solver so a bulk close on a rasa chain hits its own\n // endpoint instead of falling back to the chain default.\n solverId: parameters.solverId,\n preflightDelegation: parameters.preflightDelegation,\n orders: resolved,\n });\n}\n"],"mappings":";;;AAsEA,eAAsB,EACpB,GACA,GACqC;CACrC,IAAM,IAAW,MAAM,QAAQ,IAC7B,EAAW,OAAO,IAAI,OAAO,MAA2C;EACtE,IAAM,IAAW,MAAM,EAA0B,GAAQ;GACvD,SAAS,EAAW;GACpB,MAAM,EAAW;GACjB,QAAQ,EAAO;GACf,QAAQ,EAAO;GACf,cAAc,EAAO;GACrB,SAAS,EAAO;GAChB,iBAAiB,EAAO;GACxB,UAAU,EAAO;GACjB,WAAW,EAAO;GAClB,MAAM,EAAO;GACb,UAAU,EAAO;EACnB,CAAC;EACD,OAAO;GACL,QAAQ,EAAS;GACjB,OAAO,EAAS;GAChB,MAAM,EAAS;GACf,UAAU,EAAS;EACrB;CACF,CAAC,CACH;CAEA,OAAO,EAAiB,GAAQ;EAC9B,SAAS,EAAW;EACpB,MAAM,EAAW;EAGjB,UAAU,EAAW;EACrB,qBAAqB,EAAW;EAChC,QAAQ;CACV,CAAC;AACH"}