@symmio/trading-core 3.5.0 → 4.0.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.
- package/dist/gasless/delegation-preflight.d.ts +22 -0
- package/dist/gasless/delegation-preflight.d.ts.map +1 -1
- package/dist/gasless/delegation-preflight.js +34 -19
- package/dist/gasless/delegation-preflight.js.map +1 -1
- package/dist/index.d.ts +14 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +248 -243
- package/dist/pools/index.d.ts +1 -0
- package/dist/pools/index.d.ts.map +1 -1
- package/dist/pools/markets/get-listing-markets.d.ts +2 -0
- package/dist/pools/markets/get-listing-markets.d.ts.map +1 -1
- package/dist/pools/markets/get-listing-markets.js +1 -0
- package/dist/pools/markets/get-listing-markets.js.map +1 -1
- package/dist/pools/markets/query.d.ts.map +1 -1
- package/dist/pools/markets/query.js +1 -0
- package/dist/pools/markets/query.js.map +1 -1
- package/dist/pools/markets/to-search-params.d.ts +1 -0
- package/dist/pools/markets/to-search-params.d.ts.map +1 -1
- package/dist/pools/markets/to-search-params.js +1 -1
- package/dist/pools/markets/to-search-params.js.map +1 -1
- package/dist/pools/token-price/get-token-price.d.ts +71 -0
- package/dist/pools/token-price/get-token-price.d.ts.map +1 -0
- package/dist/pools/token-price/get-token-price.js +30 -0
- package/dist/pools/token-price/get-token-price.js.map +1 -0
- package/dist/pools/token-price/index.d.ts +4 -0
- package/dist/pools/token-price/index.d.ts.map +1 -0
- package/dist/pools/token-price/query.d.ts +52 -0
- package/dist/pools/token-price/query.d.ts.map +1 -0
- package/dist/pools/token-price/query.js +29 -0
- package/dist/pools/token-price/query.js.map +1 -0
- package/dist/pools/token-price/to-token-price.d.ts +14 -0
- package/dist/pools/token-price/to-token-price.d.ts.map +1 -0
- package/dist/pools/token-price/to-token-price.js +8 -0
- package/dist/pools/token-price/to-token-price.js.map +1 -0
- package/dist/pools/transactions/get-pool-transactions.d.ts +59 -17
- package/dist/pools/transactions/get-pool-transactions.d.ts.map +1 -1
- package/dist/pools/transactions/get-pool-transactions.js +7 -4
- package/dist/pools/transactions/get-pool-transactions.js.map +1 -1
- package/dist/pools/transactions/query.d.ts +6 -2
- package/dist/pools/transactions/query.d.ts.map +1 -1
- package/dist/pools/transactions/query.js +12 -13
- package/dist/pools/transactions/query.js.map +1 -1
- package/dist/pools/transactions/to-pool-transaction.d.ts +7 -0
- package/dist/pools/transactions/to-pool-transaction.d.ts.map +1 -1
- package/dist/pools/transactions/to-pool-transaction.js +3 -1
- package/dist/pools/transactions/to-pool-transaction.js.map +1 -1
- package/dist/pools/types/generated/listing-backend.js +8 -8
- package/dist/pools/types/generated/listing-backend.js.map +1 -1
- package/dist/pools/types.d.ts +53 -10
- package/dist/pools/types.d.ts.map +1 -1
- package/dist/pools/types.js +6 -4
- package/dist/pools/types.js.map +1 -1
- package/dist/solvers/estimated-price/get-estimated-price.d.ts +2 -0
- package/dist/solvers/estimated-price/get-estimated-price.d.ts.map +1 -1
- package/dist/solvers/estimated-price/get-estimated-price.js +4 -1
- package/dist/solvers/estimated-price/get-estimated-price.js.map +1 -1
- package/dist/solvers/estimated-price/query.d.ts +6 -2
- package/dist/solvers/estimated-price/query.d.ts.map +1 -1
- package/dist/solvers/estimated-price/query.js +3 -2
- package/dist/solvers/estimated-price/query.js.map +1 -1
- package/dist/solvers/funding-info/adapters/enigma-funding-info.d.ts +4 -0
- package/dist/solvers/funding-info/adapters/enigma-funding-info.d.ts.map +1 -0
- package/dist/solvers/funding-info/adapters/enigma-funding-info.js +17 -0
- package/dist/solvers/funding-info/adapters/enigma-funding-info.js.map +1 -0
- package/dist/solvers/funding-info/adapters/rasa-funding-info.d.ts +4 -0
- package/dist/solvers/funding-info/adapters/rasa-funding-info.d.ts.map +1 -0
- package/dist/solvers/funding-info/adapters/rasa-funding-info.js +21 -0
- package/dist/solvers/funding-info/adapters/rasa-funding-info.js.map +1 -0
- package/dist/solvers/funding-info/get-funding-info.d.ts +22 -13
- package/dist/solvers/funding-info/get-funding-info.d.ts.map +1 -1
- package/dist/solvers/funding-info/get-funding-info.js +24 -12
- package/dist/solvers/funding-info/get-funding-info.js.map +1 -1
- package/dist/solvers/funding-info/query.d.ts +14 -6
- package/dist/solvers/funding-info/query.d.ts.map +1 -1
- package/dist/solvers/funding-info/query.js +1 -0
- package/dist/solvers/funding-info/query.js.map +1 -1
- package/dist/solvers/funding-info/to-funding-info.d.ts +8 -4
- package/dist/solvers/funding-info/to-funding-info.d.ts.map +1 -1
- package/dist/solvers/funding-info/to-funding-info.js +2 -1
- package/dist/solvers/funding-info/to-funding-info.js.map +1 -1
- package/dist/solvers/funding-info/types.d.ts +26 -4
- package/dist/solvers/funding-info/types.d.ts.map +1 -1
- package/dist/solvers/instant-close/instant-close/instant-close.d.ts +8 -1
- package/dist/solvers/instant-close/instant-close/instant-close.d.ts.map +1 -1
- package/dist/solvers/instant-close/instant-close/instant-close.js +40 -32
- package/dist/solvers/instant-close/instant-close/instant-close.js.map +1 -1
- package/dist/solvers/instant-close/instant-close-bulk/instant-close-bulk.d.ts +7 -1
- package/dist/solvers/instant-close/instant-close-bulk/instant-close-bulk.d.ts.map +1 -1
- package/dist/solvers/instant-close/instant-close-bulk/instant-close-bulk.js +48 -40
- package/dist/solvers/instant-close/instant-close-bulk/instant-close-bulk.js.map +1 -1
- package/dist/solvers/instant-close/instant-close-bulk-auto/instant-close-bulk-auto.d.ts +4 -2
- package/dist/solvers/instant-close/instant-close-bulk-auto/instant-close-bulk-auto.d.ts.map +1 -1
- package/dist/solvers/instant-close/instant-close-bulk-auto/instant-close-bulk-auto.js +1 -0
- package/dist/solvers/instant-close/instant-close-bulk-auto/instant-close-bulk-auto.js.map +1 -1
- package/dist/solvers/instant-close/prepare-instant-close-params/prepare-instant-close-params.d.ts +4 -2
- package/dist/solvers/instant-close/prepare-instant-close-params/prepare-instant-close-params.d.ts.map +1 -1
- package/dist/solvers/instant-close/prepare-instant-close-params/prepare-instant-close-params.js +2 -1
- package/dist/solvers/instant-close/prepare-instant-close-params/prepare-instant-close-params.js.map +1 -1
- package/dist/solvers/instant-open/instant-open/adapters/enigma-instant-open.d.ts +2 -0
- package/dist/solvers/instant-open/instant-open/adapters/enigma-instant-open.d.ts.map +1 -1
- package/dist/solvers/instant-open/instant-open/adapters/enigma-instant-open.js +64 -56
- package/dist/solvers/instant-open/instant-open/adapters/enigma-instant-open.js.map +1 -1
- package/dist/solvers/instant-open/instant-open/adapters/rasa-instant-open.d.ts +2 -0
- package/dist/solvers/instant-open/instant-open/adapters/rasa-instant-open.d.ts.map +1 -1
- package/dist/solvers/instant-open/instant-open/adapters/rasa-instant-open.js +51 -43
- package/dist/solvers/instant-open/instant-open/adapters/rasa-instant-open.js.map +1 -1
- package/dist/solvers/instant-open/instant-open/instant-open.d.ts +6 -0
- package/dist/solvers/instant-open/instant-open/instant-open.d.ts.map +1 -1
- package/dist/solvers/instant-open/instant-open/instant-open.js.map +1 -1
- package/dist/solvers/instant-open/instant-open/types.d.ts +2 -1
- package/dist/solvers/instant-open/instant-open/types.d.ts.map +1 -1
- package/dist/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.d.ts +3 -1
- package/dist/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.d.ts.map +1 -1
- package/dist/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.js +2 -1
- package/dist/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.js.map +1 -1
- package/dist/solvers/market-info/adapters/enigma-market-info.d.ts +3 -3
- package/dist/solvers/market-info/adapters/enigma-market-info.d.ts.map +1 -1
- package/dist/solvers/market-info/adapters/enigma-market-info.js +7 -5
- package/dist/solvers/market-info/adapters/enigma-market-info.js.map +1 -1
- package/dist/solvers/market-info/get-market-info.d.ts +3 -2
- package/dist/solvers/market-info/get-market-info.d.ts.map +1 -1
- package/dist/solvers/market-info/get-market-info.js.map +1 -1
- package/dist/solvers/market-info/types.d.ts +4 -3
- package/dist/solvers/market-info/types.d.ts.map +1 -1
- package/dist/solvers/notional-cap/get-notional-cap-all.d.ts +10 -10
- package/dist/solvers/notional-cap/get-notional-cap-all.d.ts.map +1 -1
- package/dist/solvers/notional-cap/get-notional-cap-all.js +26 -23
- package/dist/solvers/notional-cap/get-notional-cap-all.js.map +1 -1
- package/dist/solvers/notional-cap/get-notional-cap-page.d.ts +49 -0
- package/dist/solvers/notional-cap/get-notional-cap-page.d.ts.map +1 -0
- package/dist/solvers/notional-cap/get-notional-cap-page.js +37 -0
- package/dist/solvers/notional-cap/get-notional-cap-page.js.map +1 -0
- package/dist/solvers/notional-cap/index.d.ts +2 -0
- package/dist/solvers/notional-cap/index.d.ts.map +1 -1
- package/dist/solvers/notional-cap/query-page.d.ts +45 -0
- package/dist/solvers/notional-cap/query-page.d.ts.map +1 -0
- package/dist/solvers/notional-cap/query-page.js +26 -0
- package/dist/solvers/notional-cap/query-page.js.map +1 -0
- package/dist/solvers/shared/index.d.ts +1 -0
- package/dist/solvers/shared/index.d.ts.map +1 -1
- package/dist/solvers/shared/instant-delegation-preflight.d.ts +65 -0
- package/dist/solvers/shared/instant-delegation-preflight.d.ts.map +1 -0
- package/dist/solvers/shared/instant-delegation-preflight.js +34 -0
- package/dist/solvers/shared/instant-delegation-preflight.js.map +1 -0
- package/dist/solvers/symbols/get-symbols.d.ts +3 -2
- package/dist/solvers/symbols/get-symbols.d.ts.map +1 -1
- package/dist/solvers/symbols/get-symbols.js +17 -3
- package/dist/solvers/symbols/get-symbols.js.map +1 -1
- package/dist/solvers/trade-volume/get-trade-volume.d.ts +2 -1
- package/dist/solvers/trade-volume/get-trade-volume.d.ts.map +1 -1
- package/dist/solvers/trade-volume/get-trade-volume.js +6 -1
- package/dist/solvers/trade-volume/get-trade-volume.js.map +1 -1
- package/dist/solvers/trade-volume/to-daily-volume.d.ts +6 -6
- package/dist/solvers/trade-volume/to-daily-volume.js.map +1 -1
- package/dist/solvers/trade-volume/types.d.ts +4 -3
- package/dist/solvers/trade-volume/types.d.ts.map +1 -1
- package/dist/solvers/types/generated/enigma-solver.js +3 -3
- package/dist/solvers/types/generated/enigma-solver.js.map +1 -1
- package/dist/solvers/types/generated/rasa-solver.js +8 -2
- package/dist/solvers/types/generated/rasa-solver.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rasa-instant-open.js","names":[],"sources":["../../../../../src/solvers/instant-open/instant-open/adapters/rasa-instant-open.ts"],"sourcesContent":["import { getSendQuoteUpnlSig } from \"../../../../muon/send-quote-upnl-sig\";\nimport { toRasaInstantOpen } from \"../../get-instant-opens/adapters/rasa-instant-opens\";\nimport { encodeSendQuoteWithAffiliateAndData } from \"../../shared/calldata\";\nimport { sendRasaInstantOpen } from \"../../shared/hedger-api\";\nimport { buildSignedOperation, signAndFormatInstantOperation } from \"../../shared/operations\";\nimport { ORDER_TYPE_MARKET } from \"../../shared/types\";\nimport type { InstantOpenParameters, RasaInstantOpenResult } from \"../types\";\nimport type { InstantOpenAdapterContext } from \"./context\";\n\n/**\n * Submit an instant open to a **Rasa** (majors) hedger.\n *\n * Signs a single `sendQuote` operation on the diamond, under the sub-account's\n * authority, and posts it to `/instant_trade/open`. Rasa is cross-margin: there\n * is no virtual account and no `addMargin` leg, so the request body carries only\n * `sendQuote`.\n *\n * Unlike the Enigma flow, Rasa enforces Muon verification — the quote must carry\n * a live `uPnl_A_withSymbolPrice` attestation. It is fetched here, immediately\n * before signing, because the signature is encoded *inside* the signed calldata\n * and cannot be filled in afterwards. That also means no `flexFields`: there is\n * nothing to delegate.\n *\n * @throws {SymmError} when the Muon attestation cannot be fetched.\n * @throws {SymmApiError} when the hedger request fails.\n * @internal\n */\nexport async function submitRasaInstantOpen(\n context: InstantOpenAdapterContext,\n parameters: InstantOpenParameters,\n): Promise<RasaInstantOpenResult> {\n const { config, solver, chainConfig, walletClient, signerAddress, deadline, symbolId, metadata } = context;\n const { symmioAddress, affiliatesAddress } = chainConfig.addresses;\n\n /** Fetch last: the attestation is short-lived and is signed into the calldata. */\n const upnlSig = await getSendQuoteUpnlSig(config, {\n chainId: context.chainId,\n partyA: parameters.subAccountAddress,\n symbolId,\n });\n\n const sendQuoteCallData = encodeSendQuoteWithAffiliateAndData({\n partyBsWhiteList: [solver.address],\n symbolId,\n positionType: parameters.positionType,\n orderType: parameters.orderType ?? ORDER_TYPE_MARKET,\n price: parameters.order.price,\n quantity: parameters.order.quantity,\n cva: parameters.lockedParam.cva,\n lf: parameters.lockedParam.lf,\n partyAmm: parameters.lockedParam.partyAmm,\n partyBmm: parameters.lockedParam.partyBmm,\n deadline,\n affiliate: affiliatesAddress,\n data: metadata,\n upnlSig,\n });\n\n const sendQuoteOp = buildSignedOperation({\n signer: signerAddress,\n target: symmioAddress,\n callData: sendQuoteCallData,\n signerAccount: parameters.subAccountAddress,\n deadline,\n salt: parameters.sendQuoteSalt,\n });\n\n const sendQuote = await signAndFormatInstantOperation(config, {\n operation: sendQuoteOp,\n chainId: context.chainId,\n walletClient,\n });\n\n const response = await sendRasaInstantOpen(config, {\n chainId: context.chainId,\n // The resolved solver's own id — never a hardcoded kind, so a differently-id'd\n // solver of the same kind can never be re-resolved onto the wrong endpoint.\n solverId: solver.id,\n sendQuote,\n });\n\n const rfq = toRasaInstantOpen(response);\n\n return {\n kind: \"rasa\",\n success: true,\n tempQuoteId: String(response.temp_quote_id),\n partyBmm: response.partyBmm,\n rfq,\n };\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"rasa-instant-open.js","names":[],"sources":["../../../../../src/solvers/instant-open/instant-open/adapters/rasa-instant-open.ts"],"sourcesContent":["import { getSendQuoteUpnlSig } from \"../../../../muon/send-quote-upnl-sig\";\nimport { assertInstantSignerDelegated } from \"../../../shared/instant-delegation-preflight\";\nimport { toRasaInstantOpen } from \"../../get-instant-opens/adapters/rasa-instant-opens\";\nimport { encodeSendQuoteWithAffiliateAndData } from \"../../shared/calldata\";\nimport { sendRasaInstantOpen } from \"../../shared/hedger-api\";\nimport { buildSignedOperation, signAndFormatInstantOperation } from \"../../shared/operations\";\nimport { ORDER_TYPE_MARKET } from \"../../shared/types\";\nimport type { InstantOpenParameters, RasaInstantOpenResult } from \"../types\";\nimport type { InstantOpenAdapterContext } from \"./context\";\n\n/**\n * Submit an instant open to a **Rasa** (majors) hedger.\n *\n * Signs a single `sendQuote` operation on the diamond, under the sub-account's\n * authority, and posts it to `/instant_trade/open`. Rasa is cross-margin: there\n * is no virtual account and no `addMargin` leg, so the request body carries only\n * `sendQuote`.\n *\n * Unlike the Enigma flow, Rasa enforces Muon verification — the quote must carry\n * a live `uPnl_A_withSymbolPrice` attestation. It is fetched here, immediately\n * before signing, because the signature is encoded *inside* the signed calldata\n * and cannot be filled in afterwards. That also means no `flexFields`: there is\n * nothing to delegate.\n *\n * @throws {SymmError} when the Muon attestation cannot be fetched.\n * @throws {SymmError} `INSTANT_SIGNER_NOT_DELEGATED` when the signer lacks the\n * delegation for the operation, before it is signed.\n * @throws {SymmApiError} when the hedger request fails.\n * @internal\n */\nexport async function submitRasaInstantOpen(\n context: InstantOpenAdapterContext,\n parameters: InstantOpenParameters,\n): Promise<RasaInstantOpenResult> {\n const { config, solver, chainConfig, walletClient, signerAddress, deadline, symbolId, metadata } = context;\n const { symmioAddress, affiliatesAddress } = chainConfig.addresses;\n\n /** Fetch last: the attestation is short-lived and is signed into the calldata. */\n const upnlSig = await getSendQuoteUpnlSig(config, {\n chainId: context.chainId,\n partyA: parameters.subAccountAddress,\n symbolId,\n });\n\n const sendQuoteCallData = encodeSendQuoteWithAffiliateAndData({\n partyBsWhiteList: [solver.address],\n symbolId,\n positionType: parameters.positionType,\n orderType: parameters.orderType ?? ORDER_TYPE_MARKET,\n price: parameters.order.price,\n quantity: parameters.order.quantity,\n cva: parameters.lockedParam.cva,\n lf: parameters.lockedParam.lf,\n partyAmm: parameters.lockedParam.partyAmm,\n partyBmm: parameters.lockedParam.partyBmm,\n deadline,\n affiliate: affiliatesAddress,\n data: metadata,\n upnlSig,\n });\n\n const sendQuoteOp = buildSignedOperation({\n signer: signerAddress,\n target: symmioAddress,\n callData: sendQuoteCallData,\n signerAccount: parameters.subAccountAddress,\n deadline,\n salt: parameters.sendQuoteSalt,\n });\n\n await assertInstantSignerDelegated(config, {\n chainId: context.chainId,\n action: \"instantOpen\",\n operations: [sendQuoteOp],\n enabled: parameters.preflightDelegation,\n });\n\n const sendQuote = await signAndFormatInstantOperation(config, {\n operation: sendQuoteOp,\n chainId: context.chainId,\n walletClient,\n });\n\n const response = await sendRasaInstantOpen(config, {\n chainId: context.chainId,\n // The resolved solver's own id — never a hardcoded kind, so a differently-id'd\n // solver of the same kind can never be re-resolved onto the wrong endpoint.\n solverId: solver.id,\n sendQuote,\n });\n\n const rfq = toRasaInstantOpen(response);\n\n return {\n kind: \"rasa\",\n success: true,\n tempQuoteId: String(response.temp_quote_id),\n partyBmm: response.partyBmm,\n rfq,\n };\n}\n"],"mappings":";;;;;;;;AA8BA,eAAsB,EACpB,GACA,GACgC;CAChC,IAAM,EAAE,WAAQ,WAAQ,gBAAa,iBAAc,kBAAe,aAAU,aAAU,gBAAa,GAC7F,EAAE,kBAAe,yBAAsB,EAAY,WAGnD,IAAU,MAAM,EAAoB,GAAQ;EAChD,SAAS,EAAQ;EACjB,QAAQ,EAAW;EACnB;CACF,CAAC,GAmBK,IAAc,EAAqB;EACvC,QAAQ;EACR,QAAQ;EACR,UApBwB,EAAoC;GAC5D,kBAAkB,CAAC,EAAO,OAAO;GACjC;GACA,cAAc,EAAW;GACzB,WAAW,EAAW,aAAA;GACtB,OAAO,EAAW,MAAM;GACxB,UAAU,EAAW,MAAM;GAC3B,KAAK,EAAW,YAAY;GAC5B,IAAI,EAAW,YAAY;GAC3B,UAAU,EAAW,YAAY;GACjC,UAAU,EAAW,YAAY;GACjC;GACA,WAAW;GACX,MAAM;GACN;EACF,CAKY;EACV,eAAe,EAAW;EAC1B;EACA,MAAM,EAAW;CACnB,CAAC;CAED,MAAM,EAA6B,GAAQ;EACzC,SAAS,EAAQ;EACjB,QAAQ;EACR,YAAY,CAAC,CAAW;EACxB,SAAS,EAAW;CACtB,CAAC;CAED,IAAM,IAAY,MAAM,EAA8B,GAAQ;EAC5D,WAAW;EACX,SAAS,EAAQ;EACjB;CACF,CAAC,GAEK,IAAW,MAAM,EAAoB,GAAQ;EACjD,SAAS,EAAQ;EAGjB,UAAU,EAAO;EACjB;CACF,CAAC,GAEK,IAAM,EAAkB,CAAQ;CAEtC,OAAO;EACL,MAAM;EACN,SAAS;EACT,aAAa,OAAO,EAAS,aAAa;EAC1C,UAAU,EAAS;EACnB;CACF;AACF"}
|
|
@@ -25,11 +25,17 @@ import { InstantOpenParameters, InstantOpenReturnType } from './types.js';
|
|
|
25
25
|
* which case a missing `margin` on an Enigma chain throws
|
|
26
26
|
* `INSTANT_OPEN_MARGIN_REQUIRED` rather than silently under-funding the trade.
|
|
27
27
|
*
|
|
28
|
+
* Before signing, it checks that the signer holds the InstantLayer delegation
|
|
29
|
+
* for every operation it is about to sign (skip it with
|
|
30
|
+
* `preflightDelegation: false`). The sub-account's owner needs none.
|
|
31
|
+
*
|
|
28
32
|
* @param config - The SDK config.
|
|
29
33
|
* @param parameters - Final-wei order, locked params, and the target sub-account.
|
|
30
34
|
* @returns The hedger's acknowledgement, discriminated on `kind`.
|
|
31
35
|
* @throws {SymmError} when the chain or solver is unsupported, or a kind's
|
|
32
36
|
* required inputs are missing.
|
|
37
|
+
* @throws {SymmError} `INSTANT_SIGNER_NOT_DELEGATED` when the signer lacks the
|
|
38
|
+
* delegation, before anything is signed.
|
|
33
39
|
* @throws {SymmApiError} when the hedger request fails.
|
|
34
40
|
*
|
|
35
41
|
* @example
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instant-open.d.ts","sourceRoot":"","sources":["../../../../src/solvers/instant-open/instant-open/instant-open.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAKnD,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAE5E
|
|
1
|
+
{"version":3,"file":"instant-open.d.ts","sourceRoot":"","sources":["../../../../src/solvers/instant-open/instant-open/instant-open.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAKnD,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,wBAAsB,WAAW,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,EAC7E,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,qBAAqB,CAAC,CAAC,CAAC,GACnC,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAkCnC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instant-open.js","names":[],"sources":["../../../../src/solvers/instant-open/instant-open/instant-open.ts"],"sourcesContent":["import type { SymmioSolverKind } from \"../../../core/chains/types\";\nimport type { Config } from \"../../../core/config\";\nimport { SymmError } from \"../../../shared/errors/symm-error\";\nimport { buildQuoteMetadata } from \"../shared/calldata\";\nimport { getMarketOrderDeadline } from \"../shared/trade-math\";\nimport { submitEnigmaInstantOpen, submitRasaInstantOpen, type InstantOpenAdapterContext } from \"./adapters\";\nimport type { InstantOpenParameters, InstantOpenReturnType } from \"./types\";\n\n/**\n * Open an instant position through the solver's InstantLayer v2 flow.\n *\n * Pure primitive — every domain value is already final wei. It builds calldata,\n * signs the operations, and submits them. It does no math and no market\n * fetching; use `prepareInstantOpenParams` to derive this shape from UI inputs,\n * or `instantOpenAuto` for the combined convenience.\n *\n * **The two solver kinds open positions differently, and this dispatches on that:**\n *\n * - **Enigma (lowcap)** signs *two* operations — `addMarginToNextVA` on the\n * AccountLayer plus `sendQuote` on the diamond — funding a fresh virtual\n * account in the same batch. `margin.amount` is required. The quote carries a\n * placeholder Muon signature whose byte range is delegated to the solver.\n * - **Rasa (majors)** signs *one* operation — `sendQuote` on the diamond, under\n * the sub-account. It is cross-margin, so there is no virtual account, no\n * `addMargin`, and no `margin` parameter. The quote carries a **live** Muon\n * attestation fetched immediately before signing.\n *\n * Pass a literal `solverId` to narrow both the parameters and the return type to\n * one kind. Omit it and the chain's `defaultSolverId` decides at runtime — in\n * which case a missing `margin` on an Enigma chain throws\n * `INSTANT_OPEN_MARGIN_REQUIRED` rather than silently under-funding the trade.\n *\n * @param config - The SDK config.\n * @param parameters - Final-wei order, locked params, and the target sub-account.\n * @returns The hedger's acknowledgement, discriminated on `kind`.\n * @throws {SymmError} when the chain or solver is unsupported, or a kind's\n * required inputs are missing.\n * @throws {SymmApiError} when the hedger request fails.\n *\n * @example\n * ```ts\n * // Rasa (majors) — one operation, live Muon sig, no margin.\n * const { tempQuoteId, rfq } = await instantOpen(config, {\n * solverId: \"rasa\",\n * subAccountAddress,\n * marketId: 1,\n * positionType: PositionType.LONG,\n * order: { price: 50_000000000000000000n, quantity: 1_000000000000000000n },\n * lockedParam: { cva: 1_000000000000000000n, lf: 500000000000000000n, partyAmm: 1_500000000000000000n, partyBmm: 1_500000000000000000n },\n * });\n * ```\n */\nexport async function instantOpen<K extends SymmioSolverKind = SymmioSolverKind>(\n config: Config,\n parameters: InstantOpenParameters<K>,\n): Promise<InstantOpenReturnType<K>> {\n const chainConfig = config.getChainConfig(parameters.chainId);\n const solver = config.getSolver({ chainId: parameters.chainId, solverId: parameters.solverId });\n\n /** Resolved once: this can prompt the user, so it must not run per adapter. */\n const walletClient = await config.getWalletClient({ chainId: parameters.chainId, from: parameters.from });\n\n const context: InstantOpenAdapterContext = {\n config,\n solver,\n chainConfig,\n walletClient,\n signerAddress: walletClient.account.address,\n chainId: parameters.chainId,\n deadline: parameters.deadline ?? getMarketOrderDeadline(),\n symbolId: BigInt(parameters.marketId),\n metadata: buildQuoteMetadata(parameters.uuid ?? globalThis.crypto.randomUUID()),\n };\n\n switch (solver.id) {\n case \"enigma\":\n return (await submitEnigmaInstantOpen(context, parameters)) as InstantOpenReturnType<K>;\n case \"rasa\":\n return (await submitRasaInstantOpen(context, parameters)) as InstantOpenReturnType<K>;\n default: {\n /** A new solver kind fails to compile here until its adapter is wired in. */\n const unreachable: never = solver.id;\n throw new SymmError(\n \"api\",\n \"UNSUPPORTED_BY_SOLVER\",\n `instantOpen: solver kind \"${String(unreachable)}\" has no instant-open adapter.`,\n );\n }\n }\n}\n"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"instant-open.js","names":[],"sources":["../../../../src/solvers/instant-open/instant-open/instant-open.ts"],"sourcesContent":["import type { SymmioSolverKind } from \"../../../core/chains/types\";\nimport type { Config } from \"../../../core/config\";\nimport { SymmError } from \"../../../shared/errors/symm-error\";\nimport { buildQuoteMetadata } from \"../shared/calldata\";\nimport { getMarketOrderDeadline } from \"../shared/trade-math\";\nimport { submitEnigmaInstantOpen, submitRasaInstantOpen, type InstantOpenAdapterContext } from \"./adapters\";\nimport type { InstantOpenParameters, InstantOpenReturnType } from \"./types\";\n\n/**\n * Open an instant position through the solver's InstantLayer v2 flow.\n *\n * Pure primitive — every domain value is already final wei. It builds calldata,\n * signs the operations, and submits them. It does no math and no market\n * fetching; use `prepareInstantOpenParams` to derive this shape from UI inputs,\n * or `instantOpenAuto` for the combined convenience.\n *\n * **The two solver kinds open positions differently, and this dispatches on that:**\n *\n * - **Enigma (lowcap)** signs *two* operations — `addMarginToNextVA` on the\n * AccountLayer plus `sendQuote` on the diamond — funding a fresh virtual\n * account in the same batch. `margin.amount` is required. The quote carries a\n * placeholder Muon signature whose byte range is delegated to the solver.\n * - **Rasa (majors)** signs *one* operation — `sendQuote` on the diamond, under\n * the sub-account. It is cross-margin, so there is no virtual account, no\n * `addMargin`, and no `margin` parameter. The quote carries a **live** Muon\n * attestation fetched immediately before signing.\n *\n * Pass a literal `solverId` to narrow both the parameters and the return type to\n * one kind. Omit it and the chain's `defaultSolverId` decides at runtime — in\n * which case a missing `margin` on an Enigma chain throws\n * `INSTANT_OPEN_MARGIN_REQUIRED` rather than silently under-funding the trade.\n *\n * Before signing, it checks that the signer holds the InstantLayer delegation\n * for every operation it is about to sign (skip it with\n * `preflightDelegation: false`). The sub-account's owner needs none.\n *\n * @param config - The SDK config.\n * @param parameters - Final-wei order, locked params, and the target sub-account.\n * @returns The hedger's acknowledgement, discriminated on `kind`.\n * @throws {SymmError} when the chain or solver is unsupported, or a kind's\n * required inputs are missing.\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 * // Rasa (majors) — one operation, live Muon sig, no margin.\n * const { tempQuoteId, rfq } = await instantOpen(config, {\n * solverId: \"rasa\",\n * subAccountAddress,\n * marketId: 1,\n * positionType: PositionType.LONG,\n * order: { price: 50_000000000000000000n, quantity: 1_000000000000000000n },\n * lockedParam: { cva: 1_000000000000000000n, lf: 500000000000000000n, partyAmm: 1_500000000000000000n, partyBmm: 1_500000000000000000n },\n * });\n * ```\n */\nexport async function instantOpen<K extends SymmioSolverKind = SymmioSolverKind>(\n config: Config,\n parameters: InstantOpenParameters<K>,\n): Promise<InstantOpenReturnType<K>> {\n const chainConfig = config.getChainConfig(parameters.chainId);\n const solver = config.getSolver({ chainId: parameters.chainId, solverId: parameters.solverId });\n\n /** Resolved once: this can prompt the user, so it must not run per adapter. */\n const walletClient = await config.getWalletClient({ chainId: parameters.chainId, from: parameters.from });\n\n const context: InstantOpenAdapterContext = {\n config,\n solver,\n chainConfig,\n walletClient,\n signerAddress: walletClient.account.address,\n chainId: parameters.chainId,\n deadline: parameters.deadline ?? getMarketOrderDeadline(),\n symbolId: BigInt(parameters.marketId),\n metadata: buildQuoteMetadata(parameters.uuid ?? globalThis.crypto.randomUUID()),\n };\n\n switch (solver.id) {\n case \"enigma\":\n return (await submitEnigmaInstantOpen(context, parameters)) as InstantOpenReturnType<K>;\n case \"rasa\":\n return (await submitRasaInstantOpen(context, parameters)) as InstantOpenReturnType<K>;\n default: {\n /** A new solver kind fails to compile here until its adapter is wired in. */\n const unreachable: never = solver.id;\n throw new SymmError(\n \"api\",\n \"UNSUPPORTED_BY_SOLVER\",\n `instantOpen: solver kind \"${String(unreachable)}\" has no instant-open adapter.`,\n );\n }\n }\n}\n"],"mappings":";;;;;;AA0DA,eAAsB,EACpB,GACA,GACmC;CACnC,IAAM,IAAc,EAAO,eAAe,EAAW,OAAO,GACtD,IAAS,EAAO,UAAU;EAAE,SAAS,EAAW;EAAS,UAAU,EAAW;CAAS,CAAC,GAGxF,IAAe,MAAM,EAAO,gBAAgB;EAAE,SAAS,EAAW;EAAS,MAAM,EAAW;CAAK,CAAC,GAElG,IAAqC;EACzC;EACA;EACA;EACA;EACA,eAAe,EAAa,QAAQ;EACpC,SAAS,EAAW;EACpB,UAAU,EAAW,YAAY,EAAuB;EACxD,UAAU,OAAO,EAAW,QAAQ;EACpC,UAAU,EAAmB,EAAW,QAAQ,WAAW,OAAO,WAAW,CAAC;CAChF;CAEA,QAAQ,EAAO,IAAf;EACE,KAAK,UACH,OAAQ,MAAM,EAAwB,GAAS,CAAU;EAC3D,KAAK,QACH,OAAQ,MAAM,EAAsB,GAAS,CAAU;EACzD,SAAS;GAEP,IAAM,IAAqB,EAAO;GAClC,MAAM,IAAI,EACR,OACA,yBACA,6BAA6B,OAAO,CAAW,EAAE,+BACnD;EACF;CACF;AACF"}
|
|
@@ -2,6 +2,7 @@ import { Address, Hex } from 'viem';
|
|
|
2
2
|
import { SymmioSolverKind } from '../../../core/chains/types.js';
|
|
3
3
|
import { ChainIdParameter, Compute, FromParameter } from '../../../shared/types/properties.js';
|
|
4
4
|
import { PositionType } from '../../../symmio-contracts/symmio/types.js';
|
|
5
|
+
import { InstantDelegationPreflightParameter } from '../../shared/instant-delegation-preflight.js';
|
|
5
6
|
import { RasaInstantOpen } from '../get-instant-opens/types.js';
|
|
6
7
|
import { InstantOpenLockedParams, InstantOpenMargin, InstantOpenOrder, SolverFeeCaps, SolverOrderType } from '../shared/types.js';
|
|
7
8
|
/**
|
|
@@ -14,7 +15,7 @@ import { InstantOpenLockedParams, InstantOpenMargin, InstantOpenOrder, SolverFee
|
|
|
14
15
|
* Passing a literal `solverId` binds `K`, which narrows the **return** type to
|
|
15
16
|
* that solver's result variant.
|
|
16
17
|
*/
|
|
17
|
-
export type InstantOpenParameters<K extends SymmioSolverKind = SymmioSolverKind> = Compute<ChainIdParameter & FromParameter & {
|
|
18
|
+
export type InstantOpenParameters<K extends SymmioSolverKind = SymmioSolverKind> = Compute<ChainIdParameter & FromParameter & InstantDelegationPreflightParameter & {
|
|
18
19
|
/** Which solver to open against. Omit to use the chain's default solver. */
|
|
19
20
|
solverId?: K;
|
|
20
21
|
/** Sub-account / partyA address — the `signerAccount.addr` the operation runs under. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/solvers/instant-open/instant-open/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,KAAK,EACV,uBAAuB,EACvB,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,eAAe,EAChB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;;GASG;AACH,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,IAAI,OAAO,CACxF,gBAAgB,GACd,aAAa,GAAG;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/solvers/instant-open/instant-open/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,2CAA2C,CAAC;AACrG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,KAAK,EACV,uBAAuB,EACvB,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,eAAe,EAChB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;;GASG;AACH,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,IAAI,OAAO,CACxF,gBAAgB,GACd,aAAa,GACb,mCAAmC,GAAG;IACpC,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,CAAC,CAAC;IACb,wFAAwF;IACxF,iBAAiB,EAAE,OAAO,CAAC;IAC3B,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B;;;;OAIG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,8EAA8E;IAC9E,KAAK,EAAE,gBAAgB,CAAC;IACxB,8FAA8F;IAC9F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mGAAmG;IACnG,WAAW,EAAE,uBAAuB,CAAC;IACrC;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,gFAAgF;IAChF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mFAAmF;IACnF,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,sEAAsE;IACtE,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CACJ,CAAC;AAEF,sEAAsE;AACtE,UAAU,qBAAqB;IAC7B,iDAAiD;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,mEAAmE;AACnE,MAAM,WAAW,uBAAwB,SAAQ,qBAAqB;IACpE,mDAAmD;IACnD,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,gEAAgE;AAChE,MAAM,WAAW,qBAAsB,SAAQ,qBAAqB;IAClE,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,GAAG,EAAE,eAAe,CAAC;CACtB;AAED,8DAA8D;AAC9D,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,uBAAuB,CAAC;IAChC,IAAI,EAAE,qBAAqB,CAAC;CAC7B;AAED;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,IAAI,uBAAuB,CAAC,CAAC,CAAC,CAAC"}
|
package/dist/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Config } from '../../../core/config/index.js';
|
|
|
3
3
|
import { Compute, WriteSolverParameter } from '../../../shared/types/properties.js';
|
|
4
4
|
import { FeeForUser } from '../../../symmio-contracts/symmio/actions/get-fee-for-user.js';
|
|
5
5
|
import { EnigmaSolverInfo } from '../../get-solver-info/index.js';
|
|
6
|
+
import { InstantDelegationPreflightParameter } from '../../shared/instant-delegation-preflight.js';
|
|
6
7
|
import { ApiLockedParamsBySymbolIdResponse } from '../../types/generated/enigma-solver.js';
|
|
7
8
|
import { InstantOpenParameters } from '../instant-open/types.js';
|
|
8
9
|
import { InstantOpenMarketData, PositionType } from '../shared/types.js';
|
|
@@ -37,8 +38,9 @@ export interface FullBalanceFunding {
|
|
|
37
38
|
}
|
|
38
39
|
/**
|
|
39
40
|
* Fields shared by every {@link PrepareInstantOpenParameters} funding mode.
|
|
41
|
+
* `preflightDelegation` is forwarded to {@link InstantOpenParameters}.
|
|
40
42
|
*/
|
|
41
|
-
type PrepareInstantOpenBaseParameters = WriteSolverParameter & {
|
|
43
|
+
type PrepareInstantOpenBaseParameters = WriteSolverParameter & InstantDelegationPreflightParameter & {
|
|
42
44
|
/** Sub-account / partyA address. */
|
|
43
45
|
subAccountAddress: Address;
|
|
44
46
|
/** Market identification + optional pre-fetched precision metadata. */
|
package/dist/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prepare-instant-open-params.d.ts","sourceRoot":"","sources":["../../../../src/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAEtF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2DAA2D,CAAC;AAC5F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,qCAAqC,CAAC;AAC7F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AASnE,OAAO,EAAE,KAAK,qBAAqB,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AA+BhF;;;;;;GAMG;AACH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,kBAAkB;IACjC,2DAA2D;IAC3D,IAAI,EAAE,cAAc,CAAC;IACrB,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED
|
|
1
|
+
{"version":3,"file":"prepare-instant-open-params.d.ts","sourceRoot":"","sources":["../../../../src/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAEtF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2DAA2D,CAAC;AAC5F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,2CAA2C,CAAC;AACrG,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,qCAAqC,CAAC;AAC7F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AASnE,OAAO,EAAE,KAAK,qBAAqB,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AA+BhF;;;;;;GAMG;AACH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,kBAAkB;IACjC,2DAA2D;IAC3D,IAAI,EAAE,cAAc,CAAC;IACrB,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,KAAK,gCAAgC,GAAG,oBAAoB,GAC1D,mCAAmC,GAAG;IACpC,oCAAoC;IACpC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,uEAAuE;IACvE,MAAM,EAAE,qBAAqB,CAAC;IAC9B,kBAAkB;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gGAAgG;IAChG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,8GAA8G;IAC9G,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,iCAAiC,CAAC;IACvD;;;OAGG;IACH,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,kDAAkD;IAClD,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEJ;;;;;;;;GAQG;AACH,MAAM,MAAM,4BAA4B,GAAG,OAAO,CAChD,gCAAgC,GAAG;IACjC,sGAAsG;IACtG,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,IAAI,CAAC,EAAE,kBAAkB,CAAC;CAC3B,CACF,CAAC;AAEF,+FAA+F;AAC/F,MAAM,MAAM,kCAAkC,GAAG,qBAAqB,GAAG;IACvE,uFAAuF;IACvF,WAAW,EAAE,gBAAgB,GAAG,cAAc,CAAC;CAChD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,4BAA4B,GACvC,OAAO,CAAC,kCAAkC,CAAC,CAkR7C"}
|
package/dist/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.js
CHANGED
|
@@ -188,7 +188,8 @@ async function b(r, v) {
|
|
|
188
188
|
addMarginSalt: v.addMarginSalt,
|
|
189
189
|
sendQuoteSalt: v.sendQuoteSalt,
|
|
190
190
|
deadline: v.deadline,
|
|
191
|
-
operationDeadline: v.operationDeadline
|
|
191
|
+
operationDeadline: v.operationDeadline,
|
|
192
|
+
preflightDelegation: v.preflightDelegation
|
|
192
193
|
};
|
|
193
194
|
}
|
|
194
195
|
//#endregion
|
package/dist/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prepare-instant-open-params.js","names":[],"sources":["../../../../src/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.ts"],"sourcesContent":["import { RoundingMode, toDecimal } from \"@symmio/utils/decimal\";\nimport { parseUnits, type Address, type 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 { decimalPriceToWei } from \"../../../shared/utils/price\";\nimport type { FeeForUser } from \"../../../symmio-contracts/symmio/actions/get-fee-for-user\";\nimport type { EnigmaSolverInfo } from \"../../get-solver-info\";\nimport type { ApiLockedParamsBySymbolIdResponse } from \"../../types/generated/enigma-solver\";\nimport type { InstantOpenParameters } from \"../instant-open/types\";\nimport {\n assertOpenEstimateWithinSlippage,\n assertValidSlippage,\n deriveAutoSlippage,\n fetchOpenEstimatePrice,\n} from \"../shared/open-estimate-guard\";\nimport { resolveInstantOpenSizing, validateInstantOpenBalanceFunding } from \"../shared/resolve-instant-open-sizing\";\nimport { calculateTradeParams, toWeiBigInt } from \"../shared/trade-math\";\nimport { type InstantOpenMarketData, type PositionType } from \"../shared/types\";\nimport { resolveFeeRates, resolveLockedParams, resolveMarket, resolveMarkPrice, resolveSolverInfo } from \"./resolvers\";\n\n/**\n * Default solver-fee rate cap when the market publishes none: `\"0.01\"` — 1% of\n * notional, as a decimal ratio. Applied per side before wei conversion.\n */\nconst DEFAULT_SOLVER_FEE_CAP = \"0.01\";\n\n/**\n * Convert a market's solver-fee cap ratio string to its 18-decimal wei value.\n *\n * An absent cap falls back to {@link DEFAULT_SOLVER_FEE_CAP}; a present but\n * malformed string **throws** rather than silently signing zero caps — the caps\n * are immutable once `sendQuote` lands, so a bad vendor string must surface\n * before the signature, not after.\n *\n * @throws {SymmError} `INVALID_SOLVER_FEE_CAP` when the string does not parse.\n */\nfunction solverFeeCapToWei(field: \"minOpenSolverFeeCap\" | \"minCloseSolverFeeCap\", value: string | undefined): bigint {\n const cap = decimalPriceToWei(value ?? DEFAULT_SOLVER_FEE_CAP);\n if (cap === undefined) {\n throw new SymmError(\n \"validation\",\n \"INVALID_SOLVER_FEE_CAP\",\n `prepareInstantOpenParams: market ${field} \"${value}\" is not a valid decimal ratio.`,\n );\n }\n return cap;\n}\n\n/**\n * Parameters for {@link prepareInstantOpenParams} and `instantOpenAuto`.\n *\n * Required = inputs only the caller can know (wallet, session key, trade\n * intent). Optional = anything derivable from solver / price-service / on-chain\n * reads. Pre-fill an optional field to skip its fetch.\n */\n/**\n * Full-balance funding for a lowcap (Enigma) open — deploy the **entire**\n * selected collateral into the position's Virtual Account instead of typing an\n * initial margin.\n *\n * With a typed `initialMargin` the SubAccount keeps back whatever the position\n * did not need (locks + open fees + settlement), so a user who deposited `$100`\n * and hit \"Max\" saw a smaller spendable figure and left dust behind. In this\n * mode the whole balance moves to the VA and the SDK sizes the quantity **down**\n * so its locks + open fees + worst-case settlement fit inside it — nothing is\n * stranded and the figure the user deployed is the figure they picked. (Close\n * fees are charged at close from the position, so they are not sized in here.)\n *\n * Lowcap (Enigma) only: it relies on the per-position VA and the solver-fee /\n * settlement legs a majors (cross-margin) open does not have.\n */\nexport interface FullBalanceFunding {\n /** Discriminant selecting the full-balance sizing path. */\n mode: \"full-balance\";\n /** Fee-inclusive funding budget to move into the VA, in USD. */\n balance: string;\n}\n\n/**\n * Fields shared by every {@link PrepareInstantOpenParameters} funding mode.\n */\ntype PrepareInstantOpenBaseParameters = WriteSolverParameter & {\n /** Sub-account / partyA address. */\n subAccountAddress: Address;\n /** Market identification + optional pre-fetched precision metadata. */\n market: InstantOpenMarketData;\n /** Trade side. */\n positionType: PositionType;\n /** Position leverage (integer ≥ 1). */\n leverage: number;\n /**\n * Slippage tolerance percent (e.g. `5` for 5%). **Required on majors\n * (non-lowcap) solvers.** On a lowcap solver it may be omitted to\n * auto-derive: the SDK dry-runs the sized order and sets the price bound\n * to the estimated fill price plus 4% headroom (falling back to a flat 4%\n * off mark when the estimate is unavailable).\n */\n slippage?: number;\n /** Pre-fetched mark price as decimal string. When omitted, fetched via Enigma price service. */\n markPrice?: string;\n /**\n * Pre-fetched solver estimated open (fill) price as decimal string —\n * **lowcap/Enigma only**; ignored on any other solver kind. When omitted\n * on a lowcap solver, fetched via `GET /estimated-price`. Pass `null` when\n * an estimate was attempted but unavailable to skip fetching and use the fallback.\n * Feeds the settlement-loss provision, the slippage gate, and (when `slippage` is\n * omitted) the auto-slippage derivation.\n */\n estimatedOpenPrice?: string | null;\n /** Optional estimate arrival time in epoch milliseconds. Accepted for compatibility; core does not use it. */\n estimatedOpenPriceTimestamp?: number;\n /**\n * Pre-fetched solver locked params (matches `getLockedParams` return —\n * `ApiLockedParamsBySymbolIdResponse`). When supplied with all four\n * percent fields, the fetch is skipped.\n */\n lockedParamPercent?: ApiLockedParamsBySymbolIdResponse;\n /**\n * Pre-fetched on-chain fee rates (matches `getFeeForUser` return —\n * `FeeForUser`). When omitted, fetched via `getFeeForUser`.\n */\n feeRates?: FeeForUser;\n /**\n * Pre-fetched solver static fees (matches `getSolverInfo` return) —\n * **lowcap/Enigma only**; ignored on any other solver kind. When omitted on\n * a lowcap solver, fetched via `getSolverInfo` (fail-soft: an unreachable\n * `/info` prices both static legs at `\"0\"`). The flat USD legs ride the\n * `addMargin` transfer like the rate-based solver fees.\n */\n solverInfo?: EnigmaSolverInfo;\n /** Forwarded to {@link InstantOpenParameters}. */\n uuid?: string;\n /** Forwarded to {@link InstantOpenParameters}. */\n addMarginSalt?: Hex;\n /** Forwarded to {@link InstantOpenParameters}. */\n sendQuoteSalt?: Hex;\n /** Forwarded to {@link InstantOpenParameters}. */\n deadline?: bigint;\n /** Lowcap operation expiry, separate from quote expiry. Forwarded to instantOpen. */\n operationDeadline?: bigint;\n};\n\n/**\n * Parameters for {@link prepareInstantOpenParams} and `instantOpenAuto`.\n *\n * The funding source is a choice: pass a typed `initialMargin` (the classic\n * path, works on every solver), **or** `fund` with {@link FullBalanceFunding} to\n * deploy the whole balance on a lowcap (Enigma) solver. Provide **exactly one** —\n * passing both, or neither, throws. (Both are typed optional so the params\n * spread cleanly through wrapper flows; the one-of rule is enforced at runtime.)\n */\nexport type PrepareInstantOpenParameters = Compute<\n PrepareInstantOpenBaseParameters & {\n /** Collateral (USD) the user enters as initial margin. Decimal string. Provide this **or** `fund`. */\n initialMargin?: string;\n /**\n * Raw available collateral (USD decimal string). With initialMargin, automatically\n * use full-balance sizing when required funding exceeds this amount. Lowcap only;\n * must be positive and finite. initialMargin above this balance throws.\n * Omit to preserve typed sizing. Cannot accompany fund.\n */\n availableBalance?: string;\n /**\n * Deploy the entire collateral and size the quantity to fit it — lowcap\n * (Enigma) only. Provide this **or** `initialMargin`. See\n * {@link FullBalanceFunding}.\n */\n fund?: FullBalanceFunding;\n }\n>;\n\n/** Prepared order parameters plus the effective funding mode. Pass directly to instantOpen. */\nexport type PrepareInstantOpenParamsReturnType = InstantOpenParameters & {\n /** Effective sizing mode, including automatic fallback from a typed initial margin. */\n fundingMode: \"initial-margin\" | \"full-balance\";\n};\n\n/**\n * Resolve every input the {@link InstantOpenParameters} primitive needs from a\n * minimal parameter set.\n *\n * The estimate-driven steps (auto slippage, dry-run gate, solver fees,\n * settlement provision) are **lowcap-only** — a majors (non-lowcap) prepare is\n * unchanged: `slippage` required, no estimate fetch, margin = locks +\n * platform fee.\n *\n * Funding is a discriminated choice (see {@link PrepareInstantOpenParameters}):\n * a typed `initialMargin`, or `fund` ({@link FullBalanceFunding}, lowcap only)\n * to deploy the whole balance. In full-balance mode the balance is used as a\n * sizing probe: since the addMargin amount is linear in the sizing input at a\n * fixed fill price, one probe gives the exact factor that shrinks the quantity\n * so its locks + fees + settlement fit the balance, and the transfer then funds\n * the whole balance (any remainder rides as free VA margin). The sized\n * quantity is snapped down to the market's lot grid, re-checked so its costs\n * never exceed the balance (precision rounding can overshoot the linear\n * factor), and validated against the market's published quote constraints;\n * when no fill estimate is available the settlement leg is provisioned at the\n * slippage bound instead of zero — a full-balance open leaves nothing behind\n * to absorb an optimistic estimate.\n *\n * Pass `availableBalance` with `initialMargin` to automatically select full-balance\n * sizing when the typed position's required funding exceeds the raw balance.\n * An initialMargin above availableBalance throws before sizing. Otherwise, funding\n * equality preserves typed sizing. The returned `fundingMode` reports the choice.\n *\n * @param config - SDK configuration used to resolve market and account inputs.\n * @param parameters - Trade intent, optional balance budget, and prefetched inputs.\n * @returns Prepared order parameters and the effective funding mode.\n *\n * Steps:\n * 1. Validate the user's `slippage` ({@link assertValidSlippage}). On a\n * lowcap solver it may be omitted and is auto-derived: dry-run the\n * mark-sized order and set the price bound to the estimated fill plus 4%\n * headroom ({@link deriveAutoSlippage}). On majors an omitted slippage\n * throws `SLIPPAGE_REQUIRED`.\n * 2. Resolve market metadata, mark price, locked params, and fee rates —\n * concurrent fetches with caller-supplied fields short-circuiting.\n * 3. Run {@link calculateTradeParams} to derive `requestedOpenPrice`,\n * `quantity`, `cva`, `lf`, `partyAmm`, `partyBmm`, `notional`.\n * 4. Dry-run the sized order and reject when the expected fill deviates from\n * mark beyond the slippage tolerance\n * ({@link assertOpenEstimateWithinSlippage}; skipped when the estimate is\n * unavailable, reusing the caller-supplied `estimatedOpenPrice` or the\n * auto-slippage estimate when one exists).\n * 5. Run {@link computePlatformFee}, {@link calculateSolverFees}, and\n * {@link calculateExpectedSettlementLoss}, then {@link calculateMargin} to\n * derive the `addMargin` amount. The open funds only the **open-side** legs\n * plus the open-price settlement from the VA, so the transfer funds\n * `locks + platformOpenFee + openSolverFee + staticSolverFeeOpen +\n * expectedSettlementLoss` (the static open leg is a flat USD amount from the\n * solver's `/info` config). The close-side legs (platform close, solver\n * close, static close) are **charged at close** from the position — the\n * contract collects them at close execution — so they are not pre-funded\n * here; pre-funding them would strand collateral in the VA. In full-balance\n * mode the quantity is rescaled to fit the balance — the static open leg is\n * carved off the budget before the linear solve — and the `addMargin` amount\n * is the whole balance instead.\n * 6. Convert all final values to 18-decimal-wei `bigint`.\n *\n * @throws {SymmError} `INVALID_SLIPPAGE` / `SLIPPAGE_REQUIRED` /\n * `SLIPPAGE_EXCEEDED` / `AMBIGUOUS_FUNDING` / `FULL_BALANCE_UNSUPPORTED` /\n * `INITIAL_MARGIN_REQUIRED` / `QUOTE_CONSTRAINT_VIOLATED` /\n * `RESOLVE_MARKET_NOT_FOUND` /\n * `RESOLVE_MARKET_METADATA_INCOMPLETE` /\n * `RESOLVE_MARK_PRICE_NOT_FOUND` / `INVALID_TRADE_PARAMETERS` /\n * `INVALID_SOLVER_FEE_CAP` for invalid inputs or an out-of-tolerance fill.\n */\nexport async function prepareInstantOpenParams(\n config: Config,\n parameters: PrepareInstantOpenParameters,\n): Promise<PrepareInstantOpenParamsReturnType> {\n // Reject a malformed user slippage before any network work. An omitted\n // slippage is auto-derived from the dry-run estimate after sizing.\n if (parameters.slippage !== undefined) assertValidSlippage(parameters.slippage);\n\n /**\n * The estimate-driven behaviors — auto slippage, the dry-run gate, solver\n * fees, and the settlement provision — exist only on lowcap (Enigma)\n * solvers. On majors the flow is unchanged: slippage is required, no\n * estimate is fetched, and the margin carries locks + the platform open fee\n * only (the platform close fee is charged at close).\n */\n const isLowcap = config.getSolver({ chainId: parameters.chainId, solverId: parameters.solverId }).id === \"enigma\";\n if (parameters.slippage === undefined && !isLowcap) {\n throw new SymmError(\n \"validation\",\n \"SLIPPAGE_REQUIRED\",\n \"prepareInstantOpenParams: slippage is required on this solver — auto-derived slippage is lowcap-only.\",\n );\n }\n\n // Full-balance funding relies on the per-position VA plus the solver-fee and\n // settlement legs a majors open does not carry, so it is lowcap-only. When it\n // is off, a typed initialMargin is mandatory (the union guarantees this for TS\n // callers; this guard covers plain-JS ones).\n const isFullBalance = parameters.fund !== undefined;\n validateInstantOpenBalanceFunding({ ...parameters, isLowcap });\n const canSizeFullBalance = isFullBalance || parameters.availableBalance !== undefined;\n if (isFullBalance && parameters.initialMargin !== undefined) {\n throw new SymmError(\n \"validation\",\n \"AMBIGUOUS_FUNDING\",\n \"prepareInstantOpenParams: pass exactly one of initialMargin or fund, not both.\",\n );\n }\n if (isFullBalance && !isLowcap) {\n throw new SymmError(\n \"validation\",\n \"FULL_BALANCE_UNSUPPORTED\",\n \"prepareInstantOpenParams: full-balance funding is lowcap (Enigma) only — pass initialMargin on this solver.\",\n );\n }\n if (!isFullBalance && parameters.initialMargin === undefined) {\n throw new SymmError(\n \"validation\",\n \"INITIAL_MARGIN_REQUIRED\",\n \"prepareInstantOpenParams: pass initialMargin, or fund: { mode: 'full-balance', balance } on a lowcap solver.\",\n );\n }\n // The sizing input: the typed margin, or — in full-balance mode — the whole\n // balance used as a probe. The final quantity is rescaled from it below.\n const initialMargin = isFullBalance ? parameters.fund!.balance : parameters.initialMargin!;\n\n /** Fee caps only exist on the v0.8.6 quote API — don't force a market fetch for them on a legacy chain. */\n const needsSolverFeeCaps = config.getChainConfig(parameters.chainId).contractsVersion === \"0.8.6\";\n\n const market = await resolveMarket(config, {\n chainId: parameters.chainId,\n solverId: parameters.solverId,\n marketId: parameters.market.id,\n marketName: parameters.market.name,\n pricePrecision: parameters.market.pricePrecision,\n quantityPrecision: parameters.market.quantityPrecision,\n minOpenSolverFeeCap: parameters.market.minOpenSolverFeeCap,\n minCloseSolverFeeCap: parameters.market.minCloseSolverFeeCap,\n includeSolverFeeCaps: needsSolverFeeCaps,\n hedgerFeeOpen: parameters.market.hedgerFeeOpen,\n hedgerFeeClose: parameters.market.hedgerFeeClose,\n hedgerFeeCloseEarlyRate: parameters.market.hedgerFeeCloseEarlyRate,\n hedgerFeeCloseEarlyThreshold: parameters.market.hedgerFeeCloseEarlyThreshold,\n hedgerFeeCloseStandardThreshold: parameters.market.hedgerFeeCloseStandardThreshold,\n /** Lowcap only: the solver charges its fees from the VA, so `addMargin` must fund them. */\n includeHedgerFees: isLowcap,\n /** Explicit or automatic full-balance sizing needs the lot grid and published floors. */\n includeQuoteConstraints: canSizeFullBalance,\n minAcceptablePortionLf: parameters.market.minAcceptablePortionLf,\n minAcceptableQuoteValue: parameters.market.minAcceptableQuoteValue,\n maxNotionalValue: parameters.market.maxNotionalValue,\n minNotionalValue: parameters.market.minNotionalValue,\n maxQuantity: parameters.market.maxQuantity,\n lotSize: parameters.market.lotSize,\n });\n const [markPrice, lockedParams, feeRates, staticFees] = await Promise.all([\n resolveMarkPrice(config, {\n chainId: parameters.chainId,\n solverId: parameters.solverId,\n marketName: market.name,\n markPrice: parameters.markPrice,\n }),\n resolveLockedParams(config, {\n chainId: parameters.chainId,\n solverId: parameters.solverId,\n marketName: market.name,\n leverage: parameters.leverage,\n lockedParamPercent: parameters.lockedParamPercent,\n }),\n resolveFeeRates(config, {\n chainId: parameters.chainId,\n subAccountAddress: parameters.subAccountAddress,\n marketId: parameters.market.id,\n feeRates: parameters.feeRates,\n }),\n // Static solver fees are a lowcap leg — a majors open never fetches them.\n isLowcap\n ? resolveSolverInfo(config, {\n chainId: parameters.chainId,\n solverId: parameters.solverId,\n solverInfo: parameters.solverInfo,\n })\n : Promise.resolve({ staticSolverFeeOpen: \"0\", staticSolverFeeClose: \"0\" }),\n ]);\n\n const calculationInput = {\n markPrice,\n positionType: parameters.positionType,\n userInput: initialMargin,\n inputField: \"PRICE\" as const,\n leverage: parameters.leverage,\n pricePrecision: market.pricePrecision,\n quantityPrecision: market.quantityPrecision,\n cvaPercent: lockedParams.cva,\n lfPercent: lockedParams.lf,\n partyAmmPercent: lockedParams.partyAmm,\n partyBmmPercent: lockedParams.partyBmm,\n };\n\n // Auto slippage: dry-run the mark-sized order (quantity is slippage-\n // independent) and set the price bound to the estimated fill plus 4%\n // headroom, re-expressed as a percent off mark. A caller-supplied\n // `estimatedOpenPrice` short-circuits the fetch; either way the estimate is\n // reused by the gate and the settlement provision so the solver is asked at\n // most once.\n let slippage = parameters.slippage;\n let expectedFillPrice = isLowcap ? (parameters.estimatedOpenPrice ?? undefined) : undefined;\n let needsEstimate = isLowcap && parameters.estimatedOpenPrice === undefined;\n if (slippage === undefined) {\n const sized = calculateTradeParams({ ...calculationInput, slippage: 0 });\n if (!sized) {\n throw new SymmError(\n \"validation\",\n \"INVALID_TRADE_PARAMETERS\",\n \"Invalid trade parameters: markPrice or initialMargin is zero/NaN.\",\n );\n }\n if (needsEstimate) {\n needsEstimate = false;\n expectedFillPrice = await fetchOpenEstimatePrice(config, {\n chainId: parameters.chainId,\n solverId: parameters.solverId,\n symbolId: parameters.market.id,\n positionType: parameters.positionType,\n quantity: sized.quantity,\n markPrice,\n });\n }\n slippage = deriveAutoSlippage({ markPrice, expectedFillPrice, positionType: parameters.positionType });\n }\n\n const tradeCalc = calculateTradeParams({ ...calculationInput, slippage });\n if (!tradeCalc) {\n throw new SymmError(\n \"validation\",\n \"INVALID_TRADE_PARAMETERS\",\n \"Invalid trade parameters: markPrice or initialMargin is zero/NaN.\",\n );\n }\n\n // The expected fill price funds the settlement-loss provision and feeds the\n // slippage gate. Fetch it once here when neither the caller nor the\n // auto-slippage path supplied it — pass `estimatedOpenPrice` to skip the\n // round-trip on latency-sensitive submits.\n if (needsEstimate) {\n expectedFillPrice = await fetchOpenEstimatePrice(config, {\n chainId: parameters.chainId,\n solverId: parameters.solverId,\n symbolId: parameters.market.id,\n positionType: parameters.positionType,\n quantity: tradeCalc.quantity,\n markPrice,\n });\n }\n\n // Dry-run gate: reject early when the expected fill deviates from mark\n // beyond the user's slippage — the solver would reject the quote anyway.\n // Best-effort: an unavailable estimate skips the gate, never blocks the open.\n if (expectedFillPrice !== undefined) {\n await assertOpenEstimateWithinSlippage(config, {\n chainId: parameters.chainId,\n solverId: parameters.solverId,\n symbolId: parameters.market.id,\n positionType: parameters.positionType,\n quantity: tradeCalc.quantity,\n markPrice,\n slippage,\n expectedFillPrice,\n });\n }\n\n // The cost legs a sized order pays. The open funds the OPEN-side legs and the\n // open-price settlement from the VA (they ride the SubAccount → VA transfer);\n // the close-side legs are charged at close from the position, not funded here.\n // Majors carry locks + the platform open fee only. The shared cost model\n // (`computeInstantOpenCosts`) is also what `getInstantOpenFees` prices, so the\n // preview equals what the open charges by construction.\n const {\n trade: finalTrade,\n marginAmount,\n fundingMode,\n } = resolveInstantOpenSizing({\n trade: tradeCalc,\n calculationInput: { ...calculationInput, slippage },\n isLowcap,\n fund: parameters.fund,\n availableBalance: parameters.availableBalance,\n expectedFillPrice,\n feeRates,\n hedgerFeeOpen: market.hedgerFeeOpen,\n staticSolverFeeOpen: staticFees.staticSolverFeeOpen,\n constraints: {\n minAcceptablePortionLf: market.minAcceptablePortionLf,\n minAcceptableQuoteValue: market.minAcceptableQuoteValue,\n maxNotionalValue: market.maxNotionalValue,\n minNotionalValue: market.minNotionalValue,\n maxQuantity: market.maxQuantity,\n lotSize: market.lotSize,\n },\n });\n\n return {\n fundingMode,\n chainId: parameters.chainId,\n /**\n * Carried through deliberately: `instantOpen` resolves the solver from it to\n * fill `partyBsWhiteList` — which is signed into the EIP-712 payload — and to\n * pick the submit URL. Dropping it here would sign against the default\n * solver's address while the quote was priced and sized for another.\n */\n solverId: parameters.solverId,\n from: parameters.from,\n subAccountAddress: parameters.subAccountAddress,\n marketId: parameters.market.id,\n positionType: parameters.positionType,\n markPrice: toWeiBigInt(markPrice),\n order: {\n price: toWeiBigInt(finalTrade.requestedOpenPrice),\n quantity: toWeiBigInt(finalTrade.quantity),\n },\n lockedParam: {\n cva: toWeiBigInt(finalTrade.cva),\n lf: toWeiBigInt(finalTrade.lf),\n partyAmm: toWeiBigInt(finalTrade.partyAmm),\n partyBmm: toWeiBigInt(finalTrade.partyBmm),\n },\n margin: {\n // Shift the decimal point without a Decimal multiplication, whose global\n // significant-digit precision can round a full balance up by one wei.\n amount: parseUnits(toDecimal(marginAmount).toFixed(18, RoundingMode.ROUND_DOWN), 18),\n },\n /** Only meaningful on a v0.8.6 chain — absent on v0.8.5, whose flow signs the legacy call. */\n ...(needsSolverFeeCaps\n ? {\n solverFeeCaps: {\n openRateCap: solverFeeCapToWei(\"minOpenSolverFeeCap\", market.minOpenSolverFeeCap),\n closeRateCap: solverFeeCapToWei(\"minCloseSolverFeeCap\", market.minCloseSolverFeeCap),\n },\n }\n : {}),\n uuid: parameters.uuid,\n addMarginSalt: parameters.addMarginSalt,\n sendQuoteSalt: parameters.sendQuoteSalt,\n deadline: parameters.deadline,\n operationDeadline: parameters.operationDeadline,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"prepare-instant-open-params.js","names":[],"sources":["../../../../src/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.ts"],"sourcesContent":["import { RoundingMode, toDecimal } from \"@symmio/utils/decimal\";\nimport { parseUnits, type Address, type 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 { decimalPriceToWei } from \"../../../shared/utils/price\";\nimport type { FeeForUser } from \"../../../symmio-contracts/symmio/actions/get-fee-for-user\";\nimport type { EnigmaSolverInfo } from \"../../get-solver-info\";\nimport type { InstantDelegationPreflightParameter } from \"../../shared/instant-delegation-preflight\";\nimport type { ApiLockedParamsBySymbolIdResponse } from \"../../types/generated/enigma-solver\";\nimport type { InstantOpenParameters } from \"../instant-open/types\";\nimport {\n assertOpenEstimateWithinSlippage,\n assertValidSlippage,\n deriveAutoSlippage,\n fetchOpenEstimatePrice,\n} from \"../shared/open-estimate-guard\";\nimport { resolveInstantOpenSizing, validateInstantOpenBalanceFunding } from \"../shared/resolve-instant-open-sizing\";\nimport { calculateTradeParams, toWeiBigInt } from \"../shared/trade-math\";\nimport { type InstantOpenMarketData, type PositionType } from \"../shared/types\";\nimport { resolveFeeRates, resolveLockedParams, resolveMarket, resolveMarkPrice, resolveSolverInfo } from \"./resolvers\";\n\n/**\n * Default solver-fee rate cap when the market publishes none: `\"0.01\"` — 1% of\n * notional, as a decimal ratio. Applied per side before wei conversion.\n */\nconst DEFAULT_SOLVER_FEE_CAP = \"0.01\";\n\n/**\n * Convert a market's solver-fee cap ratio string to its 18-decimal wei value.\n *\n * An absent cap falls back to {@link DEFAULT_SOLVER_FEE_CAP}; a present but\n * malformed string **throws** rather than silently signing zero caps — the caps\n * are immutable once `sendQuote` lands, so a bad vendor string must surface\n * before the signature, not after.\n *\n * @throws {SymmError} `INVALID_SOLVER_FEE_CAP` when the string does not parse.\n */\nfunction solverFeeCapToWei(field: \"minOpenSolverFeeCap\" | \"minCloseSolverFeeCap\", value: string | undefined): bigint {\n const cap = decimalPriceToWei(value ?? DEFAULT_SOLVER_FEE_CAP);\n if (cap === undefined) {\n throw new SymmError(\n \"validation\",\n \"INVALID_SOLVER_FEE_CAP\",\n `prepareInstantOpenParams: market ${field} \"${value}\" is not a valid decimal ratio.`,\n );\n }\n return cap;\n}\n\n/**\n * Parameters for {@link prepareInstantOpenParams} and `instantOpenAuto`.\n *\n * Required = inputs only the caller can know (wallet, session key, trade\n * intent). Optional = anything derivable from solver / price-service / on-chain\n * reads. Pre-fill an optional field to skip its fetch.\n */\n/**\n * Full-balance funding for a lowcap (Enigma) open — deploy the **entire**\n * selected collateral into the position's Virtual Account instead of typing an\n * initial margin.\n *\n * With a typed `initialMargin` the SubAccount keeps back whatever the position\n * did not need (locks + open fees + settlement), so a user who deposited `$100`\n * and hit \"Max\" saw a smaller spendable figure and left dust behind. In this\n * mode the whole balance moves to the VA and the SDK sizes the quantity **down**\n * so its locks + open fees + worst-case settlement fit inside it — nothing is\n * stranded and the figure the user deployed is the figure they picked. (Close\n * fees are charged at close from the position, so they are not sized in here.)\n *\n * Lowcap (Enigma) only: it relies on the per-position VA and the solver-fee /\n * settlement legs a majors (cross-margin) open does not have.\n */\nexport interface FullBalanceFunding {\n /** Discriminant selecting the full-balance sizing path. */\n mode: \"full-balance\";\n /** Fee-inclusive funding budget to move into the VA, in USD. */\n balance: string;\n}\n\n/**\n * Fields shared by every {@link PrepareInstantOpenParameters} funding mode.\n * `preflightDelegation` is forwarded to {@link InstantOpenParameters}.\n */\ntype PrepareInstantOpenBaseParameters = WriteSolverParameter &\n InstantDelegationPreflightParameter & {\n /** Sub-account / partyA address. */\n subAccountAddress: Address;\n /** Market identification + optional pre-fetched precision metadata. */\n market: InstantOpenMarketData;\n /** Trade side. */\n positionType: PositionType;\n /** Position leverage (integer ≥ 1). */\n leverage: number;\n /**\n * Slippage tolerance percent (e.g. `5` for 5%). **Required on majors\n * (non-lowcap) solvers.** On a lowcap solver it may be omitted to\n * auto-derive: the SDK dry-runs the sized order and sets the price bound\n * to the estimated fill price plus 4% headroom (falling back to a flat 4%\n * off mark when the estimate is unavailable).\n */\n slippage?: number;\n /** Pre-fetched mark price as decimal string. When omitted, fetched via Enigma price service. */\n markPrice?: string;\n /**\n * Pre-fetched solver estimated open (fill) price as decimal string —\n * **lowcap/Enigma only**; ignored on any other solver kind. When omitted\n * on a lowcap solver, fetched via `GET /estimated-price`. Pass `null` when\n * an estimate was attempted but unavailable to skip fetching and use the fallback.\n * Feeds the settlement-loss provision, the slippage gate, and (when `slippage` is\n * omitted) the auto-slippage derivation.\n */\n estimatedOpenPrice?: string | null;\n /** Optional estimate arrival time in epoch milliseconds. Accepted for compatibility; core does not use it. */\n estimatedOpenPriceTimestamp?: number;\n /**\n * Pre-fetched solver locked params (matches `getLockedParams` return —\n * `ApiLockedParamsBySymbolIdResponse`). When supplied with all four\n * percent fields, the fetch is skipped.\n */\n lockedParamPercent?: ApiLockedParamsBySymbolIdResponse;\n /**\n * Pre-fetched on-chain fee rates (matches `getFeeForUser` return —\n * `FeeForUser`). When omitted, fetched via `getFeeForUser`.\n */\n feeRates?: FeeForUser;\n /**\n * Pre-fetched solver static fees (matches `getSolverInfo` return) —\n * **lowcap/Enigma only**; ignored on any other solver kind. When omitted on\n * a lowcap solver, fetched via `getSolverInfo` (fail-soft: an unreachable\n * `/info` prices both static legs at `\"0\"`). The flat USD legs ride the\n * `addMargin` transfer like the rate-based solver fees.\n */\n solverInfo?: EnigmaSolverInfo;\n /** Forwarded to {@link InstantOpenParameters}. */\n uuid?: string;\n /** Forwarded to {@link InstantOpenParameters}. */\n addMarginSalt?: Hex;\n /** Forwarded to {@link InstantOpenParameters}. */\n sendQuoteSalt?: Hex;\n /** Forwarded to {@link InstantOpenParameters}. */\n deadline?: bigint;\n /** Lowcap operation expiry, separate from quote expiry. Forwarded to instantOpen. */\n operationDeadline?: bigint;\n };\n\n/**\n * Parameters for {@link prepareInstantOpenParams} and `instantOpenAuto`.\n *\n * The funding source is a choice: pass a typed `initialMargin` (the classic\n * path, works on every solver), **or** `fund` with {@link FullBalanceFunding} to\n * deploy the whole balance on a lowcap (Enigma) solver. Provide **exactly one** —\n * passing both, or neither, throws. (Both are typed optional so the params\n * spread cleanly through wrapper flows; the one-of rule is enforced at runtime.)\n */\nexport type PrepareInstantOpenParameters = Compute<\n PrepareInstantOpenBaseParameters & {\n /** Collateral (USD) the user enters as initial margin. Decimal string. Provide this **or** `fund`. */\n initialMargin?: string;\n /**\n * Raw available collateral (USD decimal string). With initialMargin, automatically\n * use full-balance sizing when required funding exceeds this amount. Lowcap only;\n * must be positive and finite. initialMargin above this balance throws.\n * Omit to preserve typed sizing. Cannot accompany fund.\n */\n availableBalance?: string;\n /**\n * Deploy the entire collateral and size the quantity to fit it — lowcap\n * (Enigma) only. Provide this **or** `initialMargin`. See\n * {@link FullBalanceFunding}.\n */\n fund?: FullBalanceFunding;\n }\n>;\n\n/** Prepared order parameters plus the effective funding mode. Pass directly to instantOpen. */\nexport type PrepareInstantOpenParamsReturnType = InstantOpenParameters & {\n /** Effective sizing mode, including automatic fallback from a typed initial margin. */\n fundingMode: \"initial-margin\" | \"full-balance\";\n};\n\n/**\n * Resolve every input the {@link InstantOpenParameters} primitive needs from a\n * minimal parameter set.\n *\n * The estimate-driven steps (auto slippage, dry-run gate, solver fees,\n * settlement provision) are **lowcap-only** — a majors (non-lowcap) prepare is\n * unchanged: `slippage` required, no estimate fetch, margin = locks +\n * platform fee.\n *\n * Funding is a discriminated choice (see {@link PrepareInstantOpenParameters}):\n * a typed `initialMargin`, or `fund` ({@link FullBalanceFunding}, lowcap only)\n * to deploy the whole balance. In full-balance mode the balance is used as a\n * sizing probe: since the addMargin amount is linear in the sizing input at a\n * fixed fill price, one probe gives the exact factor that shrinks the quantity\n * so its locks + fees + settlement fit the balance, and the transfer then funds\n * the whole balance (any remainder rides as free VA margin). The sized\n * quantity is snapped down to the market's lot grid, re-checked so its costs\n * never exceed the balance (precision rounding can overshoot the linear\n * factor), and validated against the market's published quote constraints;\n * when no fill estimate is available the settlement leg is provisioned at the\n * slippage bound instead of zero — a full-balance open leaves nothing behind\n * to absorb an optimistic estimate.\n *\n * Pass `availableBalance` with `initialMargin` to automatically select full-balance\n * sizing when the typed position's required funding exceeds the raw balance.\n * An initialMargin above availableBalance throws before sizing. Otherwise, funding\n * equality preserves typed sizing. The returned `fundingMode` reports the choice.\n *\n * @param config - SDK configuration used to resolve market and account inputs.\n * @param parameters - Trade intent, optional balance budget, and prefetched inputs.\n * @returns Prepared order parameters and the effective funding mode.\n *\n * Steps:\n * 1. Validate the user's `slippage` ({@link assertValidSlippage}). On a\n * lowcap solver it may be omitted and is auto-derived: dry-run the\n * mark-sized order and set the price bound to the estimated fill plus 4%\n * headroom ({@link deriveAutoSlippage}). On majors an omitted slippage\n * throws `SLIPPAGE_REQUIRED`.\n * 2. Resolve market metadata, mark price, locked params, and fee rates —\n * concurrent fetches with caller-supplied fields short-circuiting.\n * 3. Run {@link calculateTradeParams} to derive `requestedOpenPrice`,\n * `quantity`, `cva`, `lf`, `partyAmm`, `partyBmm`, `notional`.\n * 4. Dry-run the sized order and reject when the expected fill deviates from\n * mark beyond the slippage tolerance\n * ({@link assertOpenEstimateWithinSlippage}; skipped when the estimate is\n * unavailable, reusing the caller-supplied `estimatedOpenPrice` or the\n * auto-slippage estimate when one exists).\n * 5. Run {@link computePlatformFee}, {@link calculateSolverFees}, and\n * {@link calculateExpectedSettlementLoss}, then {@link calculateMargin} to\n * derive the `addMargin` amount. The open funds only the **open-side** legs\n * plus the open-price settlement from the VA, so the transfer funds\n * `locks + platformOpenFee + openSolverFee + staticSolverFeeOpen +\n * expectedSettlementLoss` (the static open leg is a flat USD amount from the\n * solver's `/info` config). The close-side legs (platform close, solver\n * close, static close) are **charged at close** from the position — the\n * contract collects them at close execution — so they are not pre-funded\n * here; pre-funding them would strand collateral in the VA. In full-balance\n * mode the quantity is rescaled to fit the balance — the static open leg is\n * carved off the budget before the linear solve — and the `addMargin` amount\n * is the whole balance instead.\n * 6. Convert all final values to 18-decimal-wei `bigint`.\n *\n * @throws {SymmError} `INVALID_SLIPPAGE` / `SLIPPAGE_REQUIRED` /\n * `SLIPPAGE_EXCEEDED` / `AMBIGUOUS_FUNDING` / `FULL_BALANCE_UNSUPPORTED` /\n * `INITIAL_MARGIN_REQUIRED` / `QUOTE_CONSTRAINT_VIOLATED` /\n * `RESOLVE_MARKET_NOT_FOUND` /\n * `RESOLVE_MARKET_METADATA_INCOMPLETE` /\n * `RESOLVE_MARK_PRICE_NOT_FOUND` / `INVALID_TRADE_PARAMETERS` /\n * `INVALID_SOLVER_FEE_CAP` for invalid inputs or an out-of-tolerance fill.\n */\nexport async function prepareInstantOpenParams(\n config: Config,\n parameters: PrepareInstantOpenParameters,\n): Promise<PrepareInstantOpenParamsReturnType> {\n // Reject a malformed user slippage before any network work. An omitted\n // slippage is auto-derived from the dry-run estimate after sizing.\n if (parameters.slippage !== undefined) assertValidSlippage(parameters.slippage);\n\n /**\n * The estimate-driven behaviors — auto slippage, the dry-run gate, solver\n * fees, and the settlement provision — exist only on lowcap (Enigma)\n * solvers. On majors the flow is unchanged: slippage is required, no\n * estimate is fetched, and the margin carries locks + the platform open fee\n * only (the platform close fee is charged at close).\n */\n const isLowcap = config.getSolver({ chainId: parameters.chainId, solverId: parameters.solverId }).id === \"enigma\";\n if (parameters.slippage === undefined && !isLowcap) {\n throw new SymmError(\n \"validation\",\n \"SLIPPAGE_REQUIRED\",\n \"prepareInstantOpenParams: slippage is required on this solver — auto-derived slippage is lowcap-only.\",\n );\n }\n\n // Full-balance funding relies on the per-position VA plus the solver-fee and\n // settlement legs a majors open does not carry, so it is lowcap-only. When it\n // is off, a typed initialMargin is mandatory (the union guarantees this for TS\n // callers; this guard covers plain-JS ones).\n const isFullBalance = parameters.fund !== undefined;\n validateInstantOpenBalanceFunding({ ...parameters, isLowcap });\n const canSizeFullBalance = isFullBalance || parameters.availableBalance !== undefined;\n if (isFullBalance && parameters.initialMargin !== undefined) {\n throw new SymmError(\n \"validation\",\n \"AMBIGUOUS_FUNDING\",\n \"prepareInstantOpenParams: pass exactly one of initialMargin or fund, not both.\",\n );\n }\n if (isFullBalance && !isLowcap) {\n throw new SymmError(\n \"validation\",\n \"FULL_BALANCE_UNSUPPORTED\",\n \"prepareInstantOpenParams: full-balance funding is lowcap (Enigma) only — pass initialMargin on this solver.\",\n );\n }\n if (!isFullBalance && parameters.initialMargin === undefined) {\n throw new SymmError(\n \"validation\",\n \"INITIAL_MARGIN_REQUIRED\",\n \"prepareInstantOpenParams: pass initialMargin, or fund: { mode: 'full-balance', balance } on a lowcap solver.\",\n );\n }\n // The sizing input: the typed margin, or — in full-balance mode — the whole\n // balance used as a probe. The final quantity is rescaled from it below.\n const initialMargin = isFullBalance ? parameters.fund!.balance : parameters.initialMargin!;\n\n /** Fee caps only exist on the v0.8.6 quote API — don't force a market fetch for them on a legacy chain. */\n const needsSolverFeeCaps = config.getChainConfig(parameters.chainId).contractsVersion === \"0.8.6\";\n\n const market = await resolveMarket(config, {\n chainId: parameters.chainId,\n solverId: parameters.solverId,\n marketId: parameters.market.id,\n marketName: parameters.market.name,\n pricePrecision: parameters.market.pricePrecision,\n quantityPrecision: parameters.market.quantityPrecision,\n minOpenSolverFeeCap: parameters.market.minOpenSolverFeeCap,\n minCloseSolverFeeCap: parameters.market.minCloseSolverFeeCap,\n includeSolverFeeCaps: needsSolverFeeCaps,\n hedgerFeeOpen: parameters.market.hedgerFeeOpen,\n hedgerFeeClose: parameters.market.hedgerFeeClose,\n hedgerFeeCloseEarlyRate: parameters.market.hedgerFeeCloseEarlyRate,\n hedgerFeeCloseEarlyThreshold: parameters.market.hedgerFeeCloseEarlyThreshold,\n hedgerFeeCloseStandardThreshold: parameters.market.hedgerFeeCloseStandardThreshold,\n /** Lowcap only: the solver charges its fees from the VA, so `addMargin` must fund them. */\n includeHedgerFees: isLowcap,\n /** Explicit or automatic full-balance sizing needs the lot grid and published floors. */\n includeQuoteConstraints: canSizeFullBalance,\n minAcceptablePortionLf: parameters.market.minAcceptablePortionLf,\n minAcceptableQuoteValue: parameters.market.minAcceptableQuoteValue,\n maxNotionalValue: parameters.market.maxNotionalValue,\n minNotionalValue: parameters.market.minNotionalValue,\n maxQuantity: parameters.market.maxQuantity,\n lotSize: parameters.market.lotSize,\n });\n const [markPrice, lockedParams, feeRates, staticFees] = await Promise.all([\n resolveMarkPrice(config, {\n chainId: parameters.chainId,\n solverId: parameters.solverId,\n marketName: market.name,\n markPrice: parameters.markPrice,\n }),\n resolveLockedParams(config, {\n chainId: parameters.chainId,\n solverId: parameters.solverId,\n marketName: market.name,\n leverage: parameters.leverage,\n lockedParamPercent: parameters.lockedParamPercent,\n }),\n resolveFeeRates(config, {\n chainId: parameters.chainId,\n subAccountAddress: parameters.subAccountAddress,\n marketId: parameters.market.id,\n feeRates: parameters.feeRates,\n }),\n // Static solver fees are a lowcap leg — a majors open never fetches them.\n isLowcap\n ? resolveSolverInfo(config, {\n chainId: parameters.chainId,\n solverId: parameters.solverId,\n solverInfo: parameters.solverInfo,\n })\n : Promise.resolve({ staticSolverFeeOpen: \"0\", staticSolverFeeClose: \"0\" }),\n ]);\n\n const calculationInput = {\n markPrice,\n positionType: parameters.positionType,\n userInput: initialMargin,\n inputField: \"PRICE\" as const,\n leverage: parameters.leverage,\n pricePrecision: market.pricePrecision,\n quantityPrecision: market.quantityPrecision,\n cvaPercent: lockedParams.cva,\n lfPercent: lockedParams.lf,\n partyAmmPercent: lockedParams.partyAmm,\n partyBmmPercent: lockedParams.partyBmm,\n };\n\n // Auto slippage: dry-run the mark-sized order (quantity is slippage-\n // independent) and set the price bound to the estimated fill plus 4%\n // headroom, re-expressed as a percent off mark. A caller-supplied\n // `estimatedOpenPrice` short-circuits the fetch; either way the estimate is\n // reused by the gate and the settlement provision so the solver is asked at\n // most once.\n let slippage = parameters.slippage;\n let expectedFillPrice = isLowcap ? (parameters.estimatedOpenPrice ?? undefined) : undefined;\n let needsEstimate = isLowcap && parameters.estimatedOpenPrice === undefined;\n if (slippage === undefined) {\n const sized = calculateTradeParams({ ...calculationInput, slippage: 0 });\n if (!sized) {\n throw new SymmError(\n \"validation\",\n \"INVALID_TRADE_PARAMETERS\",\n \"Invalid trade parameters: markPrice or initialMargin is zero/NaN.\",\n );\n }\n if (needsEstimate) {\n needsEstimate = false;\n expectedFillPrice = await fetchOpenEstimatePrice(config, {\n chainId: parameters.chainId,\n solverId: parameters.solverId,\n symbolId: parameters.market.id,\n positionType: parameters.positionType,\n quantity: sized.quantity,\n markPrice,\n });\n }\n slippage = deriveAutoSlippage({ markPrice, expectedFillPrice, positionType: parameters.positionType });\n }\n\n const tradeCalc = calculateTradeParams({ ...calculationInput, slippage });\n if (!tradeCalc) {\n throw new SymmError(\n \"validation\",\n \"INVALID_TRADE_PARAMETERS\",\n \"Invalid trade parameters: markPrice or initialMargin is zero/NaN.\",\n );\n }\n\n // The expected fill price funds the settlement-loss provision and feeds the\n // slippage gate. Fetch it once here when neither the caller nor the\n // auto-slippage path supplied it — pass `estimatedOpenPrice` to skip the\n // round-trip on latency-sensitive submits.\n if (needsEstimate) {\n expectedFillPrice = await fetchOpenEstimatePrice(config, {\n chainId: parameters.chainId,\n solverId: parameters.solverId,\n symbolId: parameters.market.id,\n positionType: parameters.positionType,\n quantity: tradeCalc.quantity,\n markPrice,\n });\n }\n\n // Dry-run gate: reject early when the expected fill deviates from mark\n // beyond the user's slippage — the solver would reject the quote anyway.\n // Best-effort: an unavailable estimate skips the gate, never blocks the open.\n if (expectedFillPrice !== undefined) {\n await assertOpenEstimateWithinSlippage(config, {\n chainId: parameters.chainId,\n solverId: parameters.solverId,\n symbolId: parameters.market.id,\n positionType: parameters.positionType,\n quantity: tradeCalc.quantity,\n markPrice,\n slippage,\n expectedFillPrice,\n });\n }\n\n // The cost legs a sized order pays. The open funds the OPEN-side legs and the\n // open-price settlement from the VA (they ride the SubAccount → VA transfer);\n // the close-side legs are charged at close from the position, not funded here.\n // Majors carry locks + the platform open fee only. The shared cost model\n // (`computeInstantOpenCosts`) is also what `getInstantOpenFees` prices, so the\n // preview equals what the open charges by construction.\n const {\n trade: finalTrade,\n marginAmount,\n fundingMode,\n } = resolveInstantOpenSizing({\n trade: tradeCalc,\n calculationInput: { ...calculationInput, slippage },\n isLowcap,\n fund: parameters.fund,\n availableBalance: parameters.availableBalance,\n expectedFillPrice,\n feeRates,\n hedgerFeeOpen: market.hedgerFeeOpen,\n staticSolverFeeOpen: staticFees.staticSolverFeeOpen,\n constraints: {\n minAcceptablePortionLf: market.minAcceptablePortionLf,\n minAcceptableQuoteValue: market.minAcceptableQuoteValue,\n maxNotionalValue: market.maxNotionalValue,\n minNotionalValue: market.minNotionalValue,\n maxQuantity: market.maxQuantity,\n lotSize: market.lotSize,\n },\n });\n\n return {\n fundingMode,\n chainId: parameters.chainId,\n /**\n * Carried through deliberately: `instantOpen` resolves the solver from it to\n * fill `partyBsWhiteList` — which is signed into the EIP-712 payload — and to\n * pick the submit URL. Dropping it here would sign against the default\n * solver's address while the quote was priced and sized for another.\n */\n solverId: parameters.solverId,\n from: parameters.from,\n subAccountAddress: parameters.subAccountAddress,\n marketId: parameters.market.id,\n positionType: parameters.positionType,\n markPrice: toWeiBigInt(markPrice),\n order: {\n price: toWeiBigInt(finalTrade.requestedOpenPrice),\n quantity: toWeiBigInt(finalTrade.quantity),\n },\n lockedParam: {\n cva: toWeiBigInt(finalTrade.cva),\n lf: toWeiBigInt(finalTrade.lf),\n partyAmm: toWeiBigInt(finalTrade.partyAmm),\n partyBmm: toWeiBigInt(finalTrade.partyBmm),\n },\n margin: {\n // Shift the decimal point without a Decimal multiplication, whose global\n // significant-digit precision can round a full balance up by one wei.\n amount: parseUnits(toDecimal(marginAmount).toFixed(18, RoundingMode.ROUND_DOWN), 18),\n },\n /** Only meaningful on a v0.8.6 chain — absent on v0.8.5, whose flow signs the legacy call. */\n ...(needsSolverFeeCaps\n ? {\n solverFeeCaps: {\n openRateCap: solverFeeCapToWei(\"minOpenSolverFeeCap\", market.minOpenSolverFeeCap),\n closeRateCap: solverFeeCapToWei(\"minCloseSolverFeeCap\", market.minCloseSolverFeeCap),\n },\n }\n : {}),\n uuid: parameters.uuid,\n addMarginSalt: parameters.addMarginSalt,\n sendQuoteSalt: parameters.sendQuoteSalt,\n deadline: parameters.deadline,\n operationDeadline: parameters.operationDeadline,\n preflightDelegation: parameters.preflightDelegation,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GetMarketInfo200 } from '../../types/generated/enigma-solver.js';
|
|
2
2
|
import { EnigmaMarketInfo } from '../types.js';
|
|
3
3
|
/**
|
|
4
|
-
* Map Enigma's flat `/
|
|
4
|
+
* Map Enigma's flat `/market-info` bag into {@link EnigmaMarketInfo},
|
|
5
5
|
* splitting the top-level aggregate totals from the per-market volume rows.
|
|
6
6
|
*/
|
|
7
|
-
export declare function toEnigmaMarketInfo(raw:
|
|
7
|
+
export declare function toEnigmaMarketInfo(raw: GetMarketInfo200): EnigmaMarketInfo;
|
|
8
8
|
/**
|
|
9
9
|
* Fetch and normalize market info from an **Enigma** solver — the generated
|
|
10
10
|
* client call plus mapping to {@link EnigmaMarketInfo}.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enigma-market-info.d.ts","sourceRoot":"","sources":["../../../../src/solvers/market-info/adapters/enigma-market-info.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"enigma-market-info.d.ts","sourceRoot":"","sources":["../../../../src/solvers/market-info/adapters/enigma-market-info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAChH,OAAO,KAAK,EAAE,gBAAgB,EAAgB,MAAM,UAAU,CAAC;AAmB/D;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,gBAAgB,GAAG,gBAAgB,CAoB1E;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAGtF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getMarketInfo as e } from "../../types/generated/enigma-solver.js";
|
|
2
2
|
//#region src/solvers/market-info/adapters/enigma-market-info.ts
|
|
3
3
|
var t = new Set(["total_value_24h", "total_lifetime_value"]);
|
|
4
4
|
function n(e) {
|
|
@@ -10,11 +10,13 @@ function r(e) {
|
|
|
10
10
|
let r = [];
|
|
11
11
|
for (let [i, a] of Object.entries(e)) {
|
|
12
12
|
if (t.has(i) || typeof a != "object" || !a) continue;
|
|
13
|
-
let e =
|
|
13
|
+
let e = Number(i);
|
|
14
|
+
if (!Number.isSafeInteger(e) || e <= 0) continue;
|
|
15
|
+
let o = a;
|
|
14
16
|
r.push({
|
|
15
|
-
|
|
16
|
-
tradingVolume: n(
|
|
17
|
-
lifetimeValue: n(
|
|
17
|
+
symbolId: e,
|
|
18
|
+
tradingVolume: n(o.trading_volume),
|
|
19
|
+
lifetimeValue: n(o.lifetime_value)
|
|
18
20
|
});
|
|
19
21
|
}
|
|
20
22
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enigma-market-info.js","names":[],"sources":["../../../../src/solvers/market-info/adapters/enigma-market-info.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"enigma-market-info.js","names":[],"sources":["../../../../src/solvers/market-info/adapters/enigma-market-info.ts"],"sourcesContent":["import { getMarketInfo as requestMarketInfo, type GetMarketInfo200 } from \"../../types/generated/enigma-solver\";\nimport type { EnigmaMarketInfo, MarketVolume } from \"../types\";\n\n/**\n * Top-level aggregate keys in Enigma's `/market-info` bag. Every other key is\n * a symbol ID whose value is a `{ trading_volume, lifetime_value }` object.\n */\nconst AGGREGATE_KEYS = new Set<string>([\"total_value_24h\", \"total_lifetime_value\"]);\n\n/**\n * Coerce an optional numeric solver field to a finite `number`, defaulting to\n * `0`. Enigma's volume bag is untyped in the OpenAPI spec but the running solver\n * may serve numbers or decimal strings, so accept both.\n */\nfunction toNumber(value: unknown): number {\n if (value === undefined || value === null) return 0;\n const parsed = typeof value === \"number\" ? value : Number(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\n/**\n * Map Enigma's flat `/market-info` bag into {@link EnigmaMarketInfo},\n * splitting the top-level aggregate totals from the per-market volume rows.\n */\nexport function toEnigmaMarketInfo(raw: GetMarketInfo200): EnigmaMarketInfo {\n const markets: MarketVolume[] = [];\n for (const [key, value] of Object.entries(raw)) {\n if (AGGREGATE_KEYS.has(key)) continue;\n if (typeof value !== \"object\" || value === null) continue;\n const symbolId = Number(key);\n if (!Number.isSafeInteger(symbolId) || symbolId <= 0) continue;\n const entry = value as Record<string, unknown>;\n markets.push({\n symbolId,\n tradingVolume: toNumber(entry.trading_volume),\n lifetimeValue: toNumber(entry.lifetime_value),\n });\n }\n return {\n kind: \"enigma\",\n markets,\n totalValue24h: toNumber(raw.total_value_24h),\n totalLifetimeValue: toNumber(raw.total_lifetime_value),\n };\n}\n\n/**\n * Fetch and normalize market info from an **Enigma** solver — the generated\n * client call plus mapping to {@link EnigmaMarketInfo}.\n *\n * @internal\n */\nexport async function fetchEnigmaMarketInfo(baseURL: string): Promise<EnigmaMarketInfo> {\n const response = await requestMarketInfo({ baseURL });\n return toEnigmaMarketInfo(response.data);\n}\n"],"mappings":";;AAOA,IAAM,IAAiB,IAAI,IAAY,CAAC,mBAAmB,sBAAsB,CAAC;AAOlF,SAAS,EAAS,GAAwB;CACxC,IAAI,KAAiC,MAAM,OAAO;CAClD,IAAM,IAAS,OAAO,KAAU,WAAW,IAAQ,OAAO,CAAK;CAC/D,OAAO,OAAO,SAAS,CAAM,IAAI,IAAS;AAC5C;AAMA,SAAgB,EAAmB,GAAyC;CAC1E,IAAM,IAA0B,CAAC;CACjC,KAAK,IAAM,CAAC,GAAK,MAAU,OAAO,QAAQ,CAAG,GAAG;EAE9C,IADI,EAAe,IAAI,CAAG,KACtB,OAAO,KAAU,aAAY,GAAgB;EACjD,IAAM,IAAW,OAAO,CAAG;EAC3B,IAAI,CAAC,OAAO,cAAc,CAAQ,KAAK,KAAY,GAAG;EACtD,IAAM,IAAQ;EACd,EAAQ,KAAK;GACX;GACA,eAAe,EAAS,EAAM,cAAc;GAC5C,eAAe,EAAS,EAAM,cAAc;EAC9C,CAAC;CACH;CACA,OAAO;EACL,MAAM;EACN;EACA,eAAe,EAAS,EAAI,eAAe;EAC3C,oBAAoB,EAAS,EAAI,oBAAoB;CACvD;AACF;AAQA,eAAsB,EAAsB,GAA4C;CAEtF,OAAO,GAAmB,MADH,EAAkB,EAAE,WAAQ,CAAC,GACjB,IAAI;AACzC"}
|
|
@@ -14,11 +14,12 @@ export type GetMarketInfoParameters<K extends SymmioSolverKind = SymmioSolverKin
|
|
|
14
14
|
/** Return type of {@link getMarketInfo}: the market-info type for kind `K` (the {@link MarketInfo} union when unspecified). */
|
|
15
15
|
export type GetMarketInfoReturnType<K extends SymmioSolverKind = SymmioSolverKind> = NormalizedMarketInfoByKind[K];
|
|
16
16
|
/**
|
|
17
|
-
* Fetch
|
|
17
|
+
* Fetch market info from Enigma `/market-info` or Rasa `/get_market_info`,
|
|
18
18
|
* normalized to the {@link MarketInfo} union. The response diverges by solver
|
|
19
19
|
* kind — **Enigma** returns per-market 24h volume + lifetime value plus aggregate
|
|
20
|
-
* totals; **Rasa** returns per-market price / 24h change / volume / notional cap.
|
|
20
|
+
* totals keyed by symbol ID; **Rasa** returns per-market price / 24h change / volume / notional cap.
|
|
21
21
|
* So **narrow on `kind`** before reading either side's rows.
|
|
22
|
+
* Enigma has no per-market route: select a symbol ID from this shared response.
|
|
22
23
|
*
|
|
23
24
|
* Pass a **literal** `solverId` to narrow the return to that solver's type; omit
|
|
24
25
|
* it (default solver) to get the union.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-market-info.d.ts","sourceRoot":"","sources":["../../../src/solvers/market-info/get-market-info.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAwB,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACtF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAE/E,OAAO,KAAK,EAAc,0BAA0B,EAAE,MAAM,SAAS,CAAC;AAEtE;;;;GAIG;AACH,MAAM,MAAM,uBAAuB,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,IAAI,OAAO,CAC1F,gBAAgB,GAAG;IACjB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,CAAC,CAAC;CACd,CACF,CAAC;AAEF,+HAA+H;AAC/H,MAAM,MAAM,uBAAuB,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,IAAI,0BAA0B,CAAC,CAAC,CAAC,CAAC;AAEnH
|
|
1
|
+
{"version":3,"file":"get-market-info.d.ts","sourceRoot":"","sources":["../../../src/solvers/market-info/get-market-info.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAwB,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACtF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAE/E,OAAO,KAAK,EAAc,0BAA0B,EAAE,MAAM,SAAS,CAAC;AAEtE;;;;GAIG;AACH,MAAM,MAAM,uBAAuB,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,IAAI,OAAO,CAC1F,gBAAgB,GAAG;IACjB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,CAAC,CAAC;CACd,CACF,CAAC;AAEF,+HAA+H;AAC/H,MAAM,MAAM,uBAAuB,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,IAAI,0BAA0B,CAAC,CAAC,CAAC,CAAC;AAEnH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,aAAa,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,EAC/E,MAAM,EAAE,MAAM,EACd,UAAU,GAAE,uBAAuB,CAAC,CAAC,CAAM,GAC1C,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAQrC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-market-info.js","names":[],"sources":["../../../src/solvers/market-info/get-market-info.ts"],"sourcesContent":["import { isAxiosError } from \"axios\";\nimport type { SymmioResolvedSolver, SymmioSolverKind } from \"../../core/chains/types\";\nimport type { Config } from \"../../core/config\";\nimport { SymmApiError, SymmError } from \"../../shared/errors/symm-error\";\nimport type { ChainIdParameter, Compute } from \"../../shared/types/properties\";\nimport { fetchEnigmaMarketInfo, fetchRasaMarketInfo } from \"./adapters\";\nimport type { MarketInfo, NormalizedMarketInfoByKind } from \"./types\";\n\n/**\n * Parameters for {@link getMarketInfo}, generic over the solver kind `K`. A\n * **literal** `solverId` narrows the return to that solver's market-info type; a\n * variable or omitted `solverId` yields the {@link MarketInfo} union.\n */\nexport type GetMarketInfoParameters<K extends SymmioSolverKind = SymmioSolverKind> = Compute<\n ChainIdParameter & {\n /** Which solver kind to read. A literal narrows the return; omit for the chain's default. */\n solverId?: K;\n }\n>;\n\n/** Return type of {@link getMarketInfo}: the market-info type for kind `K` (the {@link MarketInfo} union when unspecified). */\nexport type GetMarketInfoReturnType<K extends SymmioSolverKind = SymmioSolverKind> = NormalizedMarketInfoByKind[K];\n\n/**\n * Fetch
|
|
1
|
+
{"version":3,"file":"get-market-info.js","names":[],"sources":["../../../src/solvers/market-info/get-market-info.ts"],"sourcesContent":["import { isAxiosError } from \"axios\";\nimport type { SymmioResolvedSolver, SymmioSolverKind } from \"../../core/chains/types\";\nimport type { Config } from \"../../core/config\";\nimport { SymmApiError, SymmError } from \"../../shared/errors/symm-error\";\nimport type { ChainIdParameter, Compute } from \"../../shared/types/properties\";\nimport { fetchEnigmaMarketInfo, fetchRasaMarketInfo } from \"./adapters\";\nimport type { MarketInfo, NormalizedMarketInfoByKind } from \"./types\";\n\n/**\n * Parameters for {@link getMarketInfo}, generic over the solver kind `K`. A\n * **literal** `solverId` narrows the return to that solver's market-info type; a\n * variable or omitted `solverId` yields the {@link MarketInfo} union.\n */\nexport type GetMarketInfoParameters<K extends SymmioSolverKind = SymmioSolverKind> = Compute<\n ChainIdParameter & {\n /** Which solver kind to read. A literal narrows the return; omit for the chain's default. */\n solverId?: K;\n }\n>;\n\n/** Return type of {@link getMarketInfo}: the market-info type for kind `K` (the {@link MarketInfo} union when unspecified). */\nexport type GetMarketInfoReturnType<K extends SymmioSolverKind = SymmioSolverKind> = NormalizedMarketInfoByKind[K];\n\n/**\n * Fetch market info from Enigma `/market-info` or Rasa `/get_market_info`,\n * normalized to the {@link MarketInfo} union. The response diverges by solver\n * kind — **Enigma** returns per-market 24h volume + lifetime value plus aggregate\n * totals keyed by symbol ID; **Rasa** returns per-market price / 24h change / volume / notional cap.\n * So **narrow on `kind`** before reading either side's rows.\n * Enigma has no per-market route: select a symbol ID from this shared response.\n *\n * Pass a **literal** `solverId` to narrow the return to that solver's type; omit\n * it (default solver) to get the union.\n *\n * @param config - The SDK config.\n * @param parameters - Optional chain id and solver kind.\n * @returns Normalized market info for the resolved solver.\n * @throws {SymmApiError} when the API request fails.\n * @throws {SymmError} when the chain or solver is unsupported.\n *\n * @example\n * ```ts\n * const info = await getMarketInfo(config, {});\n * if (info.kind === \"enigma\") console.log(info.totalValue24h);\n * else console.log(info.markets[0]?.price); // Rasa\n * ```\n */\nexport async function getMarketInfo<K extends SymmioSolverKind = SymmioSolverKind>(\n config: Config,\n parameters: GetMarketInfoParameters<K> = {},\n): Promise<GetMarketInfoReturnType<K>> {\n const solver = config.getSolver({ chainId: parameters.chainId, solverId: parameters.solverId });\n try {\n const info = await fetchMarketInfoBySolverKind(solver);\n return info as GetMarketInfoReturnType<K>;\n } catch (err) {\n throw toMarketInfoError(err, solver.url);\n }\n}\n\n/**\n * Dispatch to the resolved solver's per-kind market-info adapter (each owns its\n * client call + normalization). Exhaustive over the solver kinds — a new kind\n * fails to compile at the `never` guard until its adapter is wired in.\n *\n * @internal\n */\nasync function fetchMarketInfoBySolverKind(solver: SymmioResolvedSolver): Promise<MarketInfo> {\n switch (solver.id) {\n case \"enigma\":\n return fetchEnigmaMarketInfo(solver.url);\n case \"rasa\":\n return fetchRasaMarketInfo(solver.url);\n default: {\n const unreachable: never = solver.id;\n throw new SymmError(\n \"api\",\n \"UNSUPPORTED_BY_SOLVER\",\n `Market info is not supported by solver kind \"${unreachable}\".`,\n );\n }\n }\n}\n\n/**\n * Map a fetch failure to a typed {@link SymmError}.\n *\n * @internal\n */\nfunction toMarketInfoError(err: unknown, baseURL: string): SymmError {\n if (err instanceof SymmError) return err;\n if (isAxiosError(err)) {\n return SymmApiError.fromAxios(err, { code: \"FETCH_MARKET_INFO_FAILED\", baseURL });\n }\n return new SymmError(\n \"api\",\n \"FETCH_MARKET_INFO_FAILED\",\n `Failed to fetch market info: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err instanceof Error ? err : undefined },\n );\n}\n"],"mappings":";;;;;AA+CA,eAAsB,EACpB,GACA,IAAyC,CAAC,GACL;CACrC,IAAM,IAAS,EAAO,UAAU;EAAE,SAAS,EAAW;EAAS,UAAU,EAAW;CAAS,CAAC;CAC9F,IAAI;EAEF,OAAO,MADY,EAA4B,CAAM;CAEvD,SAAS,GAAK;EACZ,MAAM,EAAkB,GAAK,EAAO,GAAG;CACzC;AACF;AASA,eAAe,EAA4B,GAAmD;CAC5F,QAAQ,EAAO,IAAf;EACE,KAAK,UACH,OAAO,EAAsB,EAAO,GAAG;EACzC,KAAK,QACH,OAAO,EAAoB,EAAO,GAAG;EACvC,SAAS;GACP,IAAM,IAAqB,EAAO;GAClC,MAAM,IAAI,EACR,OACA,yBACA,gDAAgD,EAAY,GAC9D;EACF;CACF;AACF;AAOA,SAAS,EAAkB,GAAc,GAA4B;CAKnE,OAJI,aAAe,IAAkB,IACjC,EAAa,CAAG,IACX,EAAa,UAAU,GAAK;EAAE,MAAM;EAA4B;CAAQ,CAAC,IAE3E,IAAI,EACT,OACA,4BACA,gCAAgC,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,KAC/E,EAAE,OAAO,aAAe,QAAQ,IAAM,KAAA,EAAU,CAClD;AACF"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 24h volume figures for one **Enigma** market, normalized from `/
|
|
2
|
+
* 24h volume figures for one **Enigma** market, normalized from `/market-info`.
|
|
3
3
|
*
|
|
4
4
|
* Every numeric field is a plain JavaScript `number` in the **dollar units the
|
|
5
5
|
* solver already reports** — no decimal scaling. `1234` here means $1,234.
|
|
6
|
+
* @example const row: MarketVolume = { symbolId: 117, tradingVolume: 1234, lifetimeValue: 5678 };
|
|
6
7
|
*/
|
|
7
8
|
export interface MarketVolume {
|
|
8
|
-
/**
|
|
9
|
-
|
|
9
|
+
/** Stable solver symbol ID; join with getSymbols for names and tickers. */
|
|
10
|
+
symbolId: number;
|
|
10
11
|
/** Rolling 24-hour trading volume for the market (dollars). */
|
|
11
12
|
tradingVolume: number;
|
|
12
13
|
/** Cumulative lifetime traded value for the market (dollars). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/solvers/market-info/types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/solvers/market-info/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,aAAa,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,sFAAsF;AACtF,MAAM,WAAW,iBAAiB;IAChC,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2CAA2C;IAC3C,IAAI,EAAE,QAAQ,CAAC;IACf,mEAAmE;IACnE,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,4DAA4D;IAC5D,aAAa,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,gBAAgB,GAAG,cAAc,CAAC;AAE3D,gEAAgE;AAChE,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,gBAAgB,CAAC;IACzB,IAAI,EAAE,cAAc,CAAC;CACtB"}
|
|
@@ -17,18 +17,18 @@ export interface GetNotionalCapAllReturnType {
|
|
|
17
17
|
symbols: EnigmaNotionalCap[];
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
|
-
* Fetch every
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
20
|
+
* Fetch every Enigma notional-cap page in server order and sum page totals.
|
|
21
|
+
* Dollar amounts remain plain numbers, with the existing zero fallback for
|
|
22
|
+
* missing fields. A failed later page rejects the whole read.
|
|
23
|
+
* @param config - SDK configuration selecting the deployment.
|
|
24
|
+
* @param parameters - Optional chain and solver selection.
|
|
25
|
+
* @returns All rows, their count and aggregate totals in float dollars.
|
|
26
|
+
* @throws {SymmError} For an unsupported solver or chain.
|
|
27
|
+
* @throws {SymmApiError} When any page request fails.
|
|
28
28
|
* @example
|
|
29
29
|
* ```ts
|
|
30
|
-
* const
|
|
31
|
-
* console.log(
|
|
30
|
+
* const caps = await getNotionalCapAll(config, {});
|
|
31
|
+
* console.log(caps.count, caps.totalUsed);
|
|
32
32
|
* ```
|
|
33
33
|
*/
|
|
34
34
|
export declare function getNotionalCapAll(config: Config, parameters?: GetNotionalCapAllParameters): Promise<GetNotionalCapAllReturnType>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-notional-cap-all.d.ts","sourceRoot":"","sources":["../../../src/solvers/notional-cap/get-notional-cap-all.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"get-notional-cap-all.d.ts","sourceRoot":"","sources":["../../../src/solvers/notional-cap/get-notional-cap-all.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAElF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,2BAA2B,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAEvE,oFAAoF;AACpF,MAAM,WAAW,2BAA2B;IAC1C,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,gGAAgG;IAChG,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,UAAU,GAAE,2BAAgC,GAC3C,OAAO,CAAC,2BAA2B,CAAC,CA4BtC"}
|
|
@@ -1,30 +1,33 @@
|
|
|
1
1
|
import { SymmApiError as e, SymmError as t } from "../../shared/errors/symm-error.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { isAxiosError as i } from "axios";
|
|
5
|
-
import { toFiniteNumber as a } from "@symmio/utils/number";
|
|
2
|
+
import { getNotionalCapPage as n } from "./get-notional-cap-page.js";
|
|
3
|
+
import { isAxiosError as r } from "axios";
|
|
6
4
|
//#region src/solvers/notional-cap/get-notional-cap-all.ts
|
|
7
|
-
async function
|
|
8
|
-
let
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
5
|
+
async function i(i, a = {}) {
|
|
6
|
+
let o = {
|
|
7
|
+
count: 0,
|
|
8
|
+
totalOpenInterest: 0,
|
|
9
|
+
totalUsed: 0,
|
|
10
|
+
symbols: []
|
|
11
|
+
};
|
|
12
|
+
for (let s = 0;; s += 100) {
|
|
13
|
+
let c;
|
|
14
|
+
try {
|
|
15
|
+
c = await n(i, {
|
|
16
|
+
...a,
|
|
17
|
+
limit: 100,
|
|
18
|
+
offset: s
|
|
19
|
+
});
|
|
20
|
+
} catch (n) {
|
|
21
|
+
throw n instanceof e && r(n.cause) ? e.fromAxios(n.cause, {
|
|
22
|
+
code: "FETCH_NOTIONAL_CAP_ALL_FAILED",
|
|
23
|
+
baseURL: i.getSolver(a).url
|
|
24
|
+
}) : n instanceof t && n.code === "FETCH_NOTIONAL_CAP_PAGE_FAILED" ? new t(n.kind, "FETCH_NOTIONAL_CAP_ALL_FAILED", n.message, { cause: n.cause }) : n;
|
|
25
|
+
}
|
|
26
|
+
if (o.symbols.push(...c.symbols), o.totalOpenInterest += c.totalOpenInterest, o.totalUsed += c.totalUsed, c.symbols.length < 100) break;
|
|
25
27
|
}
|
|
28
|
+
return o.count = o.symbols.length, o;
|
|
26
29
|
}
|
|
27
30
|
//#endregion
|
|
28
|
-
export {
|
|
31
|
+
export { i as getNotionalCapAll };
|
|
29
32
|
|
|
30
33
|
//# sourceMappingURL=get-notional-cap-all.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-notional-cap-all.js","names":[],"sources":["../../../src/solvers/notional-cap/get-notional-cap-all.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"get-notional-cap-all.js","names":[],"sources":["../../../src/solvers/notional-cap/get-notional-cap-all.ts"],"sourcesContent":["import { isAxiosError } from \"axios\";\nimport type { Config } from \"../../core/config\";\nimport { SymmApiError, SymmError } from \"../../shared/errors/symm-error\";\nimport type { Compute, ReadSolverParameter } from \"../../shared/types/properties\";\nimport { getNotionalCapPage } from \"./get-notional-cap-page\";\nimport type { EnigmaNotionalCap } from \"./types\";\n\n/**\n * Parameters for {@link getNotionalCapAll}.\n */\nexport type GetNotionalCapAllParameters = Compute<ReadSolverParameter>;\n\n/** Return type of {@link getNotionalCapAll}: aggregate totals + per-symbol rows. */\nexport interface GetNotionalCapAllReturnType {\n /** Number of symbols the solver returned. */\n count: number;\n /** Σ `openInterest` across every market (dollars). */\n totalOpenInterest: number;\n /** Σ `used` across every market (dollars). */\n totalUsed: number;\n /** Per-symbol rows. `/notional_cap` (list) is Enigma-only, so rows are always Enigma-shaped. */\n symbols: EnigmaNotionalCap[];\n}\n\n/**\n * Fetch every Enigma notional-cap page in server order and sum page totals.\n * Dollar amounts remain plain numbers, with the existing zero fallback for\n * missing fields. A failed later page rejects the whole read.\n * @param config - SDK configuration selecting the deployment.\n * @param parameters - Optional chain and solver selection.\n * @returns All rows, their count and aggregate totals in float dollars.\n * @throws {SymmError} For an unsupported solver or chain.\n * @throws {SymmApiError} When any page request fails.\n * @example\n * ```ts\n * const caps = await getNotionalCapAll(config, {});\n * console.log(caps.count, caps.totalUsed);\n * ```\n */\nexport async function getNotionalCapAll(\n config: Config,\n parameters: GetNotionalCapAllParameters = {},\n): Promise<GetNotionalCapAllReturnType> {\n const result: GetNotionalCapAllReturnType = { count: 0, totalOpenInterest: 0, totalUsed: 0, symbols: [] };\n // Live limit differs from the generated vendor spec. Do not raise it to 500.\n const pageSize = 100;\n for (let offset = 0; ; offset += pageSize) {\n let page: GetNotionalCapAllReturnType;\n try {\n page = await getNotionalCapPage(config, { ...parameters, limit: pageSize, offset });\n } catch (error) {\n // Preserve the bulk action's existing error code for transport failures.\n if (error instanceof SymmApiError && isAxiosError(error.cause)) {\n throw SymmApiError.fromAxios(error.cause, {\n code: \"FETCH_NOTIONAL_CAP_ALL_FAILED\",\n baseURL: config.getSolver(parameters).url,\n });\n }\n if (error instanceof SymmError && error.code === \"FETCH_NOTIONAL_CAP_PAGE_FAILED\") {\n throw new SymmError(error.kind, \"FETCH_NOTIONAL_CAP_ALL_FAILED\", error.message, { cause: error.cause });\n }\n throw error;\n }\n result.symbols.push(...page.symbols);\n result.totalOpenInterest += page.totalOpenInterest;\n result.totalUsed += page.totalUsed;\n if (page.symbols.length < pageSize) break;\n }\n result.count = result.symbols.length;\n return result;\n}\n"],"mappings":";;;;AAuCA,eAAsB,EACpB,GACA,IAA0C,CAAC,GACL;CACtC,IAAM,IAAsC;EAAE,OAAO;EAAG,mBAAmB;EAAG,WAAW;EAAG,SAAS,CAAC;CAAE;CAGxG,KAAK,IAAI,IAAS,IAAK,KAAU,KAAU;EACzC,IAAI;EACJ,IAAI;GACF,IAAO,MAAM,EAAmB,GAAQ;IAAE,GAAG;IAAY,OAAO;IAAU;GAAO,CAAC;EACpF,SAAS,GAAO;GAWd,MATI,aAAiB,KAAgB,EAAa,EAAM,KAAK,IACrD,EAAa,UAAU,EAAM,OAAO;IACxC,MAAM;IACN,SAAS,EAAO,UAAU,CAAU,EAAE;GACxC,CAAC,IAEC,aAAiB,KAAa,EAAM,SAAS,mCACzC,IAAI,EAAU,EAAM,MAAM,iCAAiC,EAAM,SAAS,EAAE,OAAO,EAAM,MAAM,CAAC,IAElG;EACR;EAIA,IAHA,EAAO,QAAQ,KAAK,GAAG,EAAK,OAAO,GACnC,EAAO,qBAAqB,EAAK,mBACjC,EAAO,aAAa,EAAK,WACrB,EAAK,QAAQ,SAAS,KAAU;CACtC;CAEA,OADA,EAAO,QAAQ,EAAO,QAAQ,QACvB;AACT"}
|