@symmio/trading-core 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/dist/index.d.ts +4 -2
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +304 -298
  4. package/dist/quotes/get-quote-history/solver-fees.d.ts +39 -0
  5. package/dist/quotes/get-quote-history/solver-fees.d.ts.map +1 -0
  6. package/dist/quotes/get-quote-history/solver-fees.js +36 -0
  7. package/dist/quotes/get-quote-history/solver-fees.js.map +1 -0
  8. package/dist/quotes/get-quote-history/to-history-row.d.ts.map +1 -1
  9. package/dist/quotes/get-quote-history/to-history-row.js +34 -30
  10. package/dist/quotes/get-quote-history/to-history-row.js.map +1 -1
  11. package/dist/quotes/get-quote-history/types.d.ts +20 -0
  12. package/dist/quotes/get-quote-history/types.d.ts.map +1 -1
  13. package/dist/quotes/get-quote-history/types.js.map +1 -1
  14. package/dist/solvers/get-solver-info/get-solver-info.d.ts +36 -0
  15. package/dist/solvers/get-solver-info/get-solver-info.d.ts.map +1 -0
  16. package/dist/solvers/get-solver-info/get-solver-info.js +28 -0
  17. package/dist/solvers/get-solver-info/get-solver-info.js.map +1 -0
  18. package/dist/solvers/get-solver-info/index.d.ts +3 -0
  19. package/dist/solvers/get-solver-info/index.d.ts.map +1 -0
  20. package/dist/solvers/get-solver-info/query.d.ts +29 -0
  21. package/dist/solvers/get-solver-info/query.d.ts.map +1 -0
  22. package/dist/solvers/get-solver-info/query.js +24 -0
  23. package/dist/solvers/get-solver-info/query.js.map +1 -0
  24. package/dist/solvers/instant-close/get-instant-close-fees/get-instant-close-fees.d.ts +152 -0
  25. package/dist/solvers/instant-close/get-instant-close-fees/get-instant-close-fees.d.ts.map +1 -0
  26. package/dist/solvers/instant-close/get-instant-close-fees/get-instant-close-fees.js +82 -0
  27. package/dist/solvers/instant-close/get-instant-close-fees/get-instant-close-fees.js.map +1 -0
  28. package/dist/solvers/instant-close/get-instant-close-fees/index.d.ts +3 -0
  29. package/dist/solvers/instant-close/get-instant-close-fees/index.d.ts.map +1 -0
  30. package/dist/solvers/instant-close/get-instant-close-fees/query.d.ts +37 -0
  31. package/dist/solvers/instant-close/get-instant-close-fees/query.d.ts.map +1 -0
  32. package/dist/solvers/instant-close/get-instant-close-fees/query.js +32 -0
  33. package/dist/solvers/instant-close/get-instant-close-fees/query.js.map +1 -0
  34. package/dist/solvers/instant-close/index.d.ts +1 -0
  35. package/dist/solvers/instant-close/index.d.ts.map +1 -1
  36. package/dist/solvers/instant-close/instant-close/instant-close.d.ts +4 -3
  37. package/dist/solvers/instant-close/instant-close/instant-close.d.ts.map +1 -1
  38. package/dist/solvers/instant-close/instant-close/instant-close.js +26 -22
  39. package/dist/solvers/instant-close/instant-close/instant-close.js.map +1 -1
  40. package/dist/solvers/instant-close/instant-close-bulk/instant-close-bulk.d.ts +2 -0
  41. package/dist/solvers/instant-close/instant-close-bulk/instant-close-bulk.d.ts.map +1 -1
  42. package/dist/solvers/instant-close/instant-close-bulk/instant-close-bulk.js +26 -22
  43. package/dist/solvers/instant-close/instant-close-bulk/instant-close-bulk.js.map +1 -1
  44. package/dist/solvers/instant-close/shared/calldata.d.ts +1 -1
  45. package/dist/solvers/instant-close/shared/calldata.d.ts.map +1 -1
  46. package/dist/solvers/instant-close/shared/calldata.js.map +1 -1
  47. package/dist/solvers/instant-close/shared/resolve-close-order-type.d.ts +13 -0
  48. package/dist/solvers/instant-close/shared/resolve-close-order-type.d.ts.map +1 -0
  49. package/dist/solvers/instant-close/shared/resolve-close-order-type.js +9 -0
  50. package/dist/solvers/instant-close/shared/resolve-close-order-type.js.map +1 -0
  51. package/dist/solvers/instant-close/shared/types.d.ts +3 -3
  52. package/dist/solvers/instant-open/get-instant-open-fees/get-instant-open-fees.d.ts +111 -35
  53. package/dist/solvers/instant-open/get-instant-open-fees/get-instant-open-fees.d.ts.map +1 -1
  54. package/dist/solvers/instant-open/get-instant-open-fees/get-instant-open-fees.js +168 -91
  55. package/dist/solvers/instant-open/get-instant-open-fees/get-instant-open-fees.js.map +1 -1
  56. package/dist/solvers/instant-open/get-instant-open-fees/query.d.ts +3 -2
  57. package/dist/solvers/instant-open/get-instant-open-fees/query.d.ts.map +1 -1
  58. package/dist/solvers/instant-open/get-instant-open-fees/query.js +4 -15
  59. package/dist/solvers/instant-open/get-instant-open-fees/query.js.map +1 -1
  60. package/dist/solvers/instant-open/prepare-instant-open-params/index.d.ts +1 -0
  61. package/dist/solvers/instant-open/prepare-instant-open-params/index.d.ts.map +1 -1
  62. package/dist/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.d.ts +108 -12
  63. package/dist/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.d.ts.map +1 -1
  64. package/dist/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.js +169 -149
  65. package/dist/solvers/instant-open/prepare-instant-open-params/prepare-instant-open-params.js.map +1 -1
  66. package/dist/solvers/instant-open/prepare-instant-open-params/query.d.ts +49 -0
  67. package/dist/solvers/instant-open/prepare-instant-open-params/query.d.ts.map +1 -0
  68. package/dist/solvers/instant-open/prepare-instant-open-params/query.js +24 -0
  69. package/dist/solvers/instant-open/prepare-instant-open-params/query.js.map +1 -0
  70. package/dist/solvers/instant-open/prepare-instant-open-params/resolvers/index.d.ts +0 -1
  71. package/dist/solvers/instant-open/prepare-instant-open-params/resolvers/index.d.ts.map +1 -1
  72. package/dist/solvers/instant-open/shared/full-balance-sizing.d.ts +164 -0
  73. package/dist/solvers/instant-open/shared/full-balance-sizing.d.ts.map +1 -0
  74. package/dist/solvers/instant-open/shared/full-balance-sizing.js +138 -0
  75. package/dist/solvers/instant-open/shared/full-balance-sizing.js.map +1 -0
  76. package/dist/solvers/instant-open/shared/index.d.ts +1 -0
  77. package/dist/solvers/instant-open/shared/index.d.ts.map +1 -1
  78. package/dist/solvers/instant-open/shared/resolve-instant-open-sizing.d.ts +46 -0
  79. package/dist/solvers/instant-open/shared/resolve-instant-open-sizing.d.ts.map +1 -0
  80. package/dist/solvers/instant-open/shared/resolve-instant-open-sizing.js +50 -0
  81. package/dist/solvers/instant-open/shared/resolve-instant-open-sizing.js.map +1 -0
  82. package/dist/solvers/instant-open/shared/trade-math.d.ts +73 -26
  83. package/dist/solvers/instant-open/shared/trade-math.d.ts.map +1 -1
  84. package/dist/solvers/instant-open/shared/trade-math.js +18 -13
  85. package/dist/solvers/instant-open/shared/trade-math.js.map +1 -1
  86. package/dist/solvers/instant-open/shared/types.d.ts +18 -1
  87. package/dist/solvers/instant-open/shared/types.d.ts.map +1 -1
  88. package/dist/solvers/instant-open/shared/types.js.map +1 -1
  89. package/dist/solvers/limit-open/prepare-limit-open-params.d.ts +3 -1
  90. package/dist/solvers/limit-open/prepare-limit-open-params.d.ts.map +1 -1
  91. package/dist/solvers/limit-open/prepare-limit-open-params.js.map +1 -1
  92. package/dist/solvers/shared/resolvers/index.d.ts +2 -0
  93. package/dist/solvers/shared/resolvers/index.d.ts.map +1 -1
  94. package/dist/solvers/{instant-open/prepare-instant-open-params → shared}/resolvers/resolve-fee-rates.d.ts +3 -3
  95. package/dist/solvers/shared/resolvers/resolve-fee-rates.d.ts.map +1 -0
  96. package/dist/solvers/{instant-open/prepare-instant-open-params → shared}/resolvers/resolve-fee-rates.js +2 -2
  97. package/dist/solvers/shared/resolvers/resolve-fee-rates.js.map +1 -0
  98. package/dist/solvers/shared/resolvers/resolve-market.d.ts +21 -0
  99. package/dist/solvers/shared/resolvers/resolve-market.d.ts.map +1 -1
  100. package/dist/solvers/shared/resolvers/resolve-market.js +34 -18
  101. package/dist/solvers/shared/resolvers/resolve-market.js.map +1 -1
  102. package/dist/solvers/shared/resolvers/resolve-solver-info.d.ts +29 -0
  103. package/dist/solvers/shared/resolvers/resolve-solver-info.d.ts.map +1 -0
  104. package/dist/solvers/shared/resolvers/resolve-solver-info.js +21 -0
  105. package/dist/solvers/shared/resolvers/resolve-solver-info.js.map +1 -0
  106. package/dist/solvers/shared/resolvers/types.d.ts +12 -0
  107. package/dist/solvers/shared/resolvers/types.d.ts.map +1 -1
  108. package/dist/solvers/types/generated/enigma-solver.d.ts +43 -82
  109. package/dist/solvers/types/generated/enigma-solver.d.ts.map +1 -1
  110. package/dist/solvers/types/generated/enigma-solver.js +6 -6
  111. package/dist/solvers/types/generated/enigma-solver.js.map +1 -1
  112. package/dist/symmio-contracts/abi/v0.8.6/account-layer.d.ts +696 -85
  113. package/dist/symmio-contracts/abi/v0.8.6/account-layer.d.ts.map +1 -1
  114. package/dist/symmio-contracts/abi/v0.8.6/account-layer.js +815 -116
  115. package/dist/symmio-contracts/abi/v0.8.6/account-layer.js.map +1 -1
  116. package/dist/symmio-contracts/abi/v0.8.6/symmio.d.ts +1044 -467
  117. package/dist/symmio-contracts/abi/v0.8.6/symmio.d.ts.map +1 -1
  118. package/dist/symmio-contracts/abi/v0.8.6/symmio.js +1183 -496
  119. package/dist/symmio-contracts/abi/v0.8.6/symmio.js.map +1 -1
  120. package/dist/symmio-contracts/symmio/types.d.ts +3 -1
  121. package/dist/symmio-contracts/symmio/types.d.ts.map +1 -1
  122. package/dist/symmio-contracts/symmio/types.js +1 -1
  123. package/dist/symmio-contracts/symmio/types.js.map +1 -1
  124. package/package.json +3 -3
  125. package/dist/solvers/instant-open/prepare-instant-open-params/resolvers/resolve-fee-rates.d.ts.map +0 -1
  126. package/dist/solvers/instant-open/prepare-instant-open-params/resolvers/resolve-fee-rates.js.map +0 -1
@@ -0,0 +1,46 @@
1
+ import { FullBalanceFunding } from '../prepare-instant-open-params/prepare-instant-open-params.js';
2
+ import { SizeFullBalanceInstantOpenParameters } from './full-balance-sizing.js';
3
+ import { CalculateTradeParamsReturnType } from './trade-math.js';
4
+ /**
5
+ * Validate the caller-supplied balance and typed margin without fetching data.
6
+ * Use before requesting a fill estimate; preparation and fee preview also run
7
+ * this check. An omitted availableBalance leaves existing funding behavior intact.
8
+ *
9
+ * @param parameters - Funding inputs and whether the selected solver supports lowcap opens.
10
+ * @returns Nothing when the supplied balance funding is valid.
11
+ * @throws {SymmError} INVALID_TRADE_PARAMETERS for invalid amounts or a margin above
12
+ * the balance; AMBIGUOUS_FUNDING for fund plus availableBalance;
13
+ * FULL_BALANCE_UNSUPPORTED for a non-lowcap solver with availableBalance.
14
+ * @example
15
+ * ```ts
16
+ * validateInstantOpenBalanceFunding({ initialMargin: "100", availableBalance: "100", isLowcap: true });
17
+ * ```
18
+ */
19
+ export declare function validateInstantOpenBalanceFunding(parameters: {
20
+ /** Explicit full-balance funding; cannot accompany availableBalance. */
21
+ fund?: FullBalanceFunding;
22
+ /** Typed initial margin as a decimal string; must not exceed availableBalance. */
23
+ initialMargin?: string;
24
+ /** Raw available collateral as a positive, finite decimal string. */
25
+ availableBalance?: string;
26
+ /** Whether the selected solver supports lowcap full-balance sizing. */
27
+ isLowcap: boolean;
28
+ }): void;
29
+ /** Resolve the effective trade and funding amount using the existing cost and full-balance formulas. */
30
+ export declare function resolveInstantOpenSizing(parameters: Omit<SizeFullBalanceInstantOpenParameters, "balance"> & {
31
+ trade: CalculateTradeParamsReturnType;
32
+ isLowcap: boolean;
33
+ fund?: FullBalanceFunding;
34
+ availableBalance?: string;
35
+ }): {
36
+ marginAmount: string;
37
+ fundingMode: "full-balance";
38
+ trade: CalculateTradeParamsReturnType;
39
+ costs: import('./full-balance-sizing.js').InstantOpenCostLegs;
40
+ } | {
41
+ trade: CalculateTradeParamsReturnType;
42
+ costs: import('./full-balance-sizing.js').InstantOpenCostLegs;
43
+ marginAmount: string;
44
+ fundingMode: "initial-margin";
45
+ };
46
+ //# sourceMappingURL=resolve-instant-open-sizing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-instant-open-sizing.d.ts","sourceRoot":"","sources":["../../../../src/solvers/instant-open/shared/resolve-instant-open-sizing.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4DAA4D,CAAC;AACrG,OAAO,EAGL,KAAK,oCAAoC,EAC1C,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAC;AAEnE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iCAAiC,CAAC,UAAU,EAAE;IAC5D,wEAAwE;IACxE,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,kFAAkF;IAClF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uEAAuE;IACvE,QAAQ,EAAE,OAAO,CAAC;CACnB,GAAG,IAAI,CAsBP;AAWD,wGAAwG;AACxG,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,IAAI,CAAC,oCAAoC,EAAE,SAAS,CAAC,GAAG;IAClE,KAAK,EAAE,8BAA8B,CAAC;IACtC,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;;;;;;;;;;EAsBF"}
@@ -0,0 +1,50 @@
1
+ import { SymmError as e } from "../../../shared/errors/symm-error.js";
2
+ import { computeInstantOpenCosts as t, sizeFullBalanceInstantOpen as n } from "./full-balance-sizing.js";
3
+ import { toDecimal as r } from "@symmio/utils/decimal";
4
+ //#region src/solvers/instant-open/shared/resolve-instant-open-sizing.ts
5
+ function i(t) {
6
+ let { fund: n, availableBalance: i, isLowcap: o } = t;
7
+ if (i !== void 0) {
8
+ if (n !== void 0) throw new e("validation", "AMBIGUOUS_FUNDING", "Pass availableBalance with initialMargin, not with fund.");
9
+ if (!o) throw new e("validation", "FULL_BALANCE_UNSUPPORTED", "Automatic full-balance funding is lowcap only.");
10
+ if (!a(i)) throw new e("validation", "INVALID_TRADE_PARAMETERS", "availableBalance must be a positive finite decimal.");
11
+ if (t.initialMargin !== void 0 && !a(t.initialMargin)) throw new e("validation", "INVALID_TRADE_PARAMETERS", "initialMargin must be a positive finite decimal.");
12
+ if (t.initialMargin !== void 0 && r(t.initialMargin).gt(i)) throw new e("validation", "INVALID_TRADE_PARAMETERS", "Initial margin exceeds available balance.");
13
+ }
14
+ }
15
+ function a(e) {
16
+ try {
17
+ let t = r(e);
18
+ return t.isFinite() && t.gt(0);
19
+ } catch {
20
+ return !1;
21
+ }
22
+ }
23
+ function o(i) {
24
+ let { trade: a, calculationInput: o, availableBalance: s, fund: c } = i, l = t({
25
+ ...i,
26
+ positionType: o.positionType,
27
+ markPrice: o.markPrice,
28
+ cvaPercent: o.cvaPercent,
29
+ lfPercent: o.lfPercent,
30
+ partyAmmPercent: o.partyAmmPercent
31
+ }), u = c?.balance ?? s;
32
+ if (c === void 0 && s !== void 0 && !r(l.marginAmount).isFinite()) throw new e("validation", "INVALID_TRADE_PARAMETERS", "Calculated funding must be finite.");
33
+ return u !== void 0 && (c !== void 0 || r(l.marginAmount).gt(u)) ? {
34
+ ...n({
35
+ ...i,
36
+ balance: u
37
+ }),
38
+ marginAmount: u,
39
+ fundingMode: "full-balance"
40
+ } : {
41
+ trade: a,
42
+ costs: l,
43
+ marginAmount: l.marginAmount,
44
+ fundingMode: "initial-margin"
45
+ };
46
+ }
47
+ //#endregion
48
+ export { o as resolveInstantOpenSizing, i as validateInstantOpenBalanceFunding };
49
+
50
+ //# sourceMappingURL=resolve-instant-open-sizing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-instant-open-sizing.js","names":[],"sources":["../../../../src/solvers/instant-open/shared/resolve-instant-open-sizing.ts"],"sourcesContent":["import { toDecimal } from \"@symmio/utils/decimal\";\nimport { SymmError } from \"../../../shared/errors/symm-error\";\nimport type { FullBalanceFunding } from \"../prepare-instant-open-params/prepare-instant-open-params\";\nimport {\n computeInstantOpenCosts,\n sizeFullBalanceInstantOpen,\n type SizeFullBalanceInstantOpenParameters,\n} from \"./full-balance-sizing\";\nimport type { CalculateTradeParamsReturnType } from \"./trade-math\";\n\n/**\n * Validate the caller-supplied balance and typed margin without fetching data.\n * Use before requesting a fill estimate; preparation and fee preview also run\n * this check. An omitted availableBalance leaves existing funding behavior intact.\n *\n * @param parameters - Funding inputs and whether the selected solver supports lowcap opens.\n * @returns Nothing when the supplied balance funding is valid.\n * @throws {SymmError} INVALID_TRADE_PARAMETERS for invalid amounts or a margin above\n * the balance; AMBIGUOUS_FUNDING for fund plus availableBalance;\n * FULL_BALANCE_UNSUPPORTED for a non-lowcap solver with availableBalance.\n * @example\n * ```ts\n * validateInstantOpenBalanceFunding({ initialMargin: \"100\", availableBalance: \"100\", isLowcap: true });\n * ```\n */\nexport function validateInstantOpenBalanceFunding(parameters: {\n /** Explicit full-balance funding; cannot accompany availableBalance. */\n fund?: FullBalanceFunding;\n /** Typed initial margin as a decimal string; must not exceed availableBalance. */\n initialMargin?: string;\n /** Raw available collateral as a positive, finite decimal string. */\n availableBalance?: string;\n /** Whether the selected solver supports lowcap full-balance sizing. */\n isLowcap: boolean;\n}): void {\n const { fund, availableBalance, isLowcap } = parameters;\n if (availableBalance === undefined) return;\n if (fund !== undefined) {\n throw new SymmError(\"validation\", \"AMBIGUOUS_FUNDING\", \"Pass availableBalance with initialMargin, not with fund.\");\n }\n if (!isLowcap) {\n throw new SymmError(\"validation\", \"FULL_BALANCE_UNSUPPORTED\", \"Automatic full-balance funding is lowcap only.\");\n }\n if (!isPositiveFiniteDecimal(availableBalance)) {\n throw new SymmError(\n \"validation\",\n \"INVALID_TRADE_PARAMETERS\",\n \"availableBalance must be a positive finite decimal.\",\n );\n }\n if (parameters.initialMargin !== undefined && !isPositiveFiniteDecimal(parameters.initialMargin)) {\n throw new SymmError(\"validation\", \"INVALID_TRADE_PARAMETERS\", \"initialMargin must be a positive finite decimal.\");\n }\n if (parameters.initialMargin !== undefined && toDecimal(parameters.initialMargin).gt(availableBalance)) {\n throw new SymmError(\"validation\", \"INVALID_TRADE_PARAMETERS\", \"Initial margin exceeds available balance.\");\n }\n}\n\nfunction isPositiveFiniteDecimal(value: string): boolean {\n try {\n const amount = toDecimal(value);\n return amount.isFinite() && amount.gt(0);\n } catch {\n return false;\n }\n}\n\n/** Resolve the effective trade and funding amount using the existing cost and full-balance formulas. */\nexport function resolveInstantOpenSizing(\n parameters: Omit<SizeFullBalanceInstantOpenParameters, \"balance\"> & {\n trade: CalculateTradeParamsReturnType;\n isLowcap: boolean;\n fund?: FullBalanceFunding;\n availableBalance?: string;\n },\n) {\n const { trade, calculationInput, availableBalance, fund } = parameters;\n const costs = computeInstantOpenCosts({\n ...parameters,\n positionType: calculationInput.positionType,\n markPrice: calculationInput.markPrice,\n cvaPercent: calculationInput.cvaPercent,\n lfPercent: calculationInput.lfPercent,\n partyAmmPercent: calculationInput.partyAmmPercent,\n });\n const balance = fund?.balance ?? availableBalance;\n if (fund === undefined && availableBalance !== undefined) {\n if (!toDecimal(costs.marginAmount).isFinite()) {\n throw new SymmError(\"validation\", \"INVALID_TRADE_PARAMETERS\", \"Calculated funding must be finite.\");\n }\n }\n if (balance !== undefined && (fund !== undefined || toDecimal(costs.marginAmount).gt(balance))) {\n const sized = sizeFullBalanceInstantOpen({ ...parameters, balance });\n return { ...sized, marginAmount: balance, fundingMode: \"full-balance\" as const };\n }\n return { trade, costs, marginAmount: costs.marginAmount, fundingMode: \"initial-margin\" as const };\n}\n"],"mappings":";;;;AAyBA,SAAgB,EAAkC,GASzC;CACP,IAAM,EAAE,SAAM,qBAAkB,gBAAa;CACzC,UAAqB,KAAA,GACzB;MAAI,MAAS,KAAA,GACX,MAAM,IAAI,EAAU,cAAc,qBAAqB,0DAA0D;EAEnH,IAAI,CAAC,GACH,MAAM,IAAI,EAAU,cAAc,4BAA4B,gDAAgD;EAEhH,IAAI,CAAC,EAAwB,CAAgB,GAC3C,MAAM,IAAI,EACR,cACA,4BACA,qDACF;EAEF,IAAI,EAAW,kBAAkB,KAAA,KAAa,CAAC,EAAwB,EAAW,aAAa,GAC7F,MAAM,IAAI,EAAU,cAAc,4BAA4B,kDAAkD;EAElH,IAAI,EAAW,kBAAkB,KAAA,KAAa,EAAU,EAAW,aAAa,EAAE,GAAG,CAAgB,GACnG,MAAM,IAAI,EAAU,cAAc,4BAA4B,2CAA2C;CAhBQ;AAkBrH;AAEA,SAAS,EAAwB,GAAwB;CACvD,IAAI;EACF,IAAM,IAAS,EAAU,CAAK;EAC9B,OAAO,EAAO,SAAS,KAAK,EAAO,GAAG,CAAC;CACzC,QAAQ;EACN,OAAO;CACT;AACF;AAGA,SAAgB,EACd,GAMA;CACA,IAAM,EAAE,UAAO,qBAAkB,qBAAkB,YAAS,GACtD,IAAQ,EAAwB;EACpC,GAAG;EACH,cAAc,EAAiB;EAC/B,WAAW,EAAiB;EAC5B,YAAY,EAAiB;EAC7B,WAAW,EAAiB;EAC5B,iBAAiB,EAAiB;CACpC,CAAC,GACK,IAAU,GAAM,WAAW;CACjC,IAAI,MAAS,KAAA,KAAa,MAAqB,KAAA,KACzC,CAAC,EAAU,EAAM,YAAY,EAAE,SAAS,GAC1C,MAAM,IAAI,EAAU,cAAc,4BAA4B,oCAAoC;CAOtG,OAJI,MAAY,KAAA,MAAc,MAAS,KAAA,KAAa,EAAU,EAAM,YAAY,EAAE,GAAG,CAAO,KAEnF;EAAE,GADK,EAA2B;GAAE,GAAG;GAAY;EAAQ,CACtD;EAAO,cAAc;EAAS,aAAa;CAAwB,IAE1E;EAAE;EAAO;EAAO,cAAc,EAAM;EAAc,aAAa;CAA0B;AAClG"}
@@ -101,38 +101,61 @@ export interface SolverFees {
101
101
  /** `hedgerFeeOpen × notional`, decimal string. */
102
102
  openSolverFee: string;
103
103
  /**
104
- * Close fee provisioned at open, decimal string. The solver charges more to
105
- * close a freshly opened position, so — since the holding time is unknown at
106
- * open — this provisions the **worst case**: `hedgerFeeCloseEarlyRate ×
107
- * notional` when the early-rate field is supplied, else the flat
108
- * `hedgerFeeClose × notional`.
104
+ * Close-fee **estimate**, decimal string — the solver charges this at close
105
+ * from the position, **not** funded by the open's `addMargin`. Reported at the
106
+ * representative **standard** (floor) rate: `hedgerFeeClose × notional` (the
107
+ * decay schedule evaluated at its standard threshold when the early fields are
108
+ * supplied). It is an estimate, not the exact charge: the actual close fee is
109
+ * priced from the real holding time at close and capped by the signed
110
+ * `closeRateCap`.
109
111
  */
110
112
  closeSolverFee: string;
113
+ /**
114
+ * Static solver fee charged per instant open, decimal string — a flat USD
115
+ * amount from the solver's `/info` config, **not** scaled by the notional.
116
+ * `"0"` when the solver publishes none.
117
+ */
118
+ staticSolverFeeOpen: string;
119
+ /**
120
+ * Static solver close fee provisioned at open, decimal string — a flat USD
121
+ * amount from the solver's `/info` config, **not** scaled by the notional.
122
+ * `"0"` when the solver publishes none.
123
+ */
124
+ staticSolverFeeClose: string;
111
125
  }
112
126
  /**
113
- * Compute the solver's open and close fees on the leveraged notional.
127
+ * Compute every fee the solver charges on an instant open: the rate legs on
128
+ * the leveraged notional plus the flat static legs.
114
129
  *
115
- * The solver charges its fees from the **VA balance**, so both legs must ride
116
- * the `addMargin` transfer from the SubAccount into the VA. The open leg is
117
- * `hedgerFeeOpen × notional`. The close leg is provisioned for the **worst
118
- * case**, because the holding time is unknown at open and an early close costs
119
- * more: when `hedgerFeeCloseEarlyRate` is supplied it uses the peak rate (the
120
- * rate at holding time 0); without it it falls back to the flat
121
- * `hedgerFeeClose`. An absent, NaN, or negative rate contributes `"0"`.
130
+ * The **open** legs (`openSolverFee`, `staticSolverFeeOpen`) are charged from
131
+ * the VA at open, so they ride the `addMargin` transfer. The **close** legs
132
+ * (`closeSolverFee`, `staticSolverFeeClose`) are charged at close from the
133
+ * position — the contract collects them at close execution, not at open — so
134
+ * they are returned as **estimates** for previews, not amounts the open funds.
135
+ * The close-fee estimate uses the **standard** (floor) rate: when
136
+ * `hedgerFeeCloseEarlyRate` is supplied the decay schedule is evaluated at its
137
+ * standard threshold (which yields `hedgerFeeClose`), else it is the flat
138
+ * `hedgerFeeClose × notional`. The static legs pass through as-is — flat USD
139
+ * amounts, size-independent. An absent, NaN, or negative rate or static
140
+ * contributes `"0"`.
122
141
  */
123
- export declare function calculateSolverFees({ notional, hedgerFeeOpen, hedgerFeeClose, hedgerFeeCloseEarlyRate, hedgerFeeCloseEarlyThreshold, hedgerFeeCloseStandardThreshold, }: {
142
+ export declare function calculateSolverFees({ notional, hedgerFeeOpen, hedgerFeeClose, hedgerFeeCloseEarlyRate, hedgerFeeCloseEarlyThreshold, hedgerFeeCloseStandardThreshold, staticSolverFeeOpen, staticSolverFeeClose, }: {
124
143
  /** Leveraged notional (decimal string). */
125
144
  notional: string;
126
145
  /** Solver open-fee rate as a decimal fraction string (e.g. `"0.0004"`). */
127
146
  hedgerFeeOpen: string | undefined;
128
- /** Solver standard close-fee rate as a decimal fraction string. Used when no early rate is given. */
147
+ /** Solver standard (floor) close-fee rate as a decimal fraction string — the close-fee estimate is priced at this rate. */
129
148
  hedgerFeeClose: string | undefined;
130
- /** Early (peak) close-fee rate; when given, the close leg provisions this worst-case rate. */
149
+ /** Early (peak) close-fee rate; parametrizes the decay schedule the standard-rate estimate is read from. */
131
150
  hedgerFeeCloseEarlyRate?: string;
132
151
  /** Early-window length in seconds (paired with `hedgerFeeCloseEarlyRate`). */
133
152
  hedgerFeeCloseEarlyThreshold?: number;
134
- /** Standard-rate threshold in seconds (paired with `hedgerFeeCloseEarlyRate`). */
153
+ /** Standard-rate threshold in seconds (paired with `hedgerFeeCloseEarlyRate`) — the close-fee estimate is evaluated here. */
135
154
  hedgerFeeCloseStandardThreshold?: number;
155
+ /** Static solver open fee — flat USD decimal string (solver `/info`). Defaults to `"0"`. */
156
+ staticSolverFeeOpen?: string;
157
+ /** Static solver close fee — flat USD decimal string (solver `/info`); an estimate charged at close, not funded at open. Defaults to `"0"`. */
158
+ staticSolverFeeClose?: string;
136
159
  }): SolverFees;
137
160
  /**
138
161
  * Expected settlement loss charged from the VA when the fill lands away from
@@ -179,10 +202,23 @@ export interface CalculateMarginParameters {
179
202
  platformFee: string;
180
203
  /** Solver open fee funded from the VA (from {@link calculateSolverFees}). Defaults to `"0"`. */
181
204
  openSolverFee?: string;
182
- /** Solver close fee provisioned at open (from {@link calculateSolverFees}). Defaults to `"0"`. */
205
+ /**
206
+ * Solver close fee (from {@link calculateSolverFees}). Defaults to `"0"`. The
207
+ * instant-open flow leaves this at `0` — the close fee is charged at close
208
+ * from the position, not funded here — and includes it only if a caller
209
+ * deliberately chooses to reserve it.
210
+ */
183
211
  closeSolverFee?: string;
184
212
  /** Expected settlement loss vs the estimated fill (from {@link calculateExpectedSettlementLoss}). Defaults to `"0"`. */
185
213
  expectedSettlementLoss?: string;
214
+ /** Static solver open fee — flat USD, not rate × notional (from {@link calculateSolverFees}). Defaults to `"0"`. */
215
+ staticSolverFeeOpen?: string;
216
+ /**
217
+ * Static solver close fee — flat USD (from {@link calculateSolverFees}).
218
+ * Defaults to `"0"`. Like {@link CalculateMarginParameters.closeSolverFee},
219
+ * the instant-open flow leaves this at `0`; it is charged at close.
220
+ */
221
+ staticSolverFeeClose?: string;
186
222
  /**
187
223
  * Extra funding headroom percent applied to a SHORT's margin basis
188
224
  * (`markPrice × (1 + percent/100)`). A SHORT's `requestedOpenPrice` is a
@@ -206,9 +242,14 @@ export declare const SHORT_FUNDING_BUFFER_PERCENT = 1;
206
242
  * buffer covers lock growth when the fill lands above the SHORT's floor.
207
243
  *
208
244
  * `fees = platformFee + openSolverFee + closeSolverFee +
209
- * expectedSettlementLoss` — the solver charges its fees and the open-price
210
- * settlement from the **VA balance**, so every leg must ride this SubAccount →
211
- * VA transfer or the position opens underfunded.
245
+ * staticSolverFeeOpen + staticSolverFeeClose + expectedSettlementLoss` — the
246
+ * sum of whatever legs the caller passes, funded from the **VA balance** via
247
+ * the SubAccount → VA transfer. The instant-open flow passes only the
248
+ * **open-side** legs plus the settlement provision (`platformFee` = the open
249
+ * leg, `openSolverFee`, `staticSolverFeeOpen`, `expectedSettlementLoss`) and
250
+ * leaves the close legs at `0`: close fees are charged at close from the
251
+ * position, so pre-funding them would strand collateral. The static legs are
252
+ * flat USD amounts and do not scale with the notional.
212
253
  *
213
254
  * @returns Margin as decimal string.
214
255
  */
@@ -266,8 +307,12 @@ export interface CalculateAvailableInstantOpenMarginParameters {
266
307
  balance: bigint;
267
308
  /** Open fee rate (18-decimal fixed-point) from `getFeeForUser`. */
268
309
  openFee: bigint;
269
- /** Close fee rate (18-decimal fixed-point) from `getFeeForUser`. */
270
- closeFee: bigint;
310
+ /**
311
+ * @deprecated No longer used and ignored. Close fees are charged at close from
312
+ * the position, not reserved from the open budget, so the shave applies the
313
+ * open fee only. Kept as an optional field so existing callers still compile.
314
+ */
315
+ closeFee?: bigint;
271
316
  /** Slippage as an 18-decimal fraction (5% → `5n * 10n ** 16n`). */
272
317
  slippageFractionWei: bigint;
273
318
  /** Requested leverage (integer ≥ 1). */
@@ -277,15 +322,18 @@ export interface CalculateAvailableInstantOpenMarginParameters {
277
322
  }
278
323
  /**
279
324
  * Maximum initial margin an instant open can spend. Shaves the raw available
280
- * balance for fees (both sides, charged on the leveraged notional) and — for
325
+ * balance for the **open** fee (charged on the leveraged notional) and — for
281
326
  * SHORT only — a worst-case slippage-fill buffer. Pure `bigint`; clamps to `0n`.
282
327
  *
283
328
  * ```text
284
329
  * available = balance
285
330
  * × max(0, 1 − slippageFactor) // SHORT: slippage, LONG: 0
286
- * × max(0, 1 − leverage × (openFee + closeFee))
331
+ * × max(0, 1 − leverage × openFee)
287
332
  * ```
288
333
  *
334
+ * The close fee is **not** shaved: it is charged at close from the position, not
335
+ * reserved from the open budget, so reserving it here would understate the max.
336
+ *
289
337
  * A SHORT's `requestOpenPrice = markPrice × (1 − s)` is a contract FLOOR: a fill
290
338
  * above it rescales the signed locks by up to `1 / (1 − s)`, so capping usable
291
339
  * balance at `balance × (1 − s)` covers that growth. A LONG's request price is a
@@ -297,7 +345,6 @@ export interface CalculateAvailableInstantOpenMarginParameters {
297
345
  * const max = calculateAvailableInstantOpenMargin({
298
346
  * balance,
299
347
  * openFee,
300
- * closeFee,
301
348
  * slippageFractionWei: 5n * 10n ** 16n, // 5%
302
349
  * leverage: 10,
303
350
  * positionType: PositionType.SHORT,
@@ -1 +1 @@
1
- {"version":3,"file":"trade-math.d.ts","sourceRoot":"","sources":["../../../../src/solvers/instant-open/shared/trade-math.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"trade-math.d.ts","sourceRoot":"","sources":["../../../../src/solvers/instant-open/shared/trade-math.ts"],"names":[],"mappings":"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"}
@@ -28,22 +28,27 @@ function l(t) {
28
28
  partyBmm: T
29
29
  };
30
30
  }
31
- function u({ notional: e, hedgerFeeOpen: n, hedgerFeeClose: r, hedgerFeeCloseEarlyRate: a, hedgerFeeCloseEarlyThreshold: o, hedgerFeeCloseStandardThreshold: s }) {
32
- let c = i(e), l = (e) => {
31
+ function u({ notional: e, hedgerFeeOpen: n, hedgerFeeClose: r, hedgerFeeCloseEarlyRate: a, hedgerFeeCloseEarlyThreshold: o, hedgerFeeCloseStandardThreshold: s, staticSolverFeeOpen: c, staticSolverFeeClose: l }) {
32
+ let u = i(e), d = (e) => {
33
33
  let t = i(e);
34
- return t.isNaN() || t.isNegative() || c.isNaN() ? "0" : c.times(t).toString();
35
- }, u = a === void 0 ? l(r) : t({
34
+ return t.isNaN() || t.isNegative() || u.isNaN() ? "0" : u.times(t).toString();
35
+ }, f = (e) => {
36
+ let t = i(e);
37
+ return t.isNaN() || t.isNegative() ? "0" : t.toString();
38
+ }, p = a === void 0 ? d(r) : t({
36
39
  hedgerFeeClose: r ?? "0",
37
40
  hedgerFeeCloseEarlyRate: a,
38
41
  hedgerFeeCloseEarlyThreshold: o ?? 0,
39
42
  hedgerFeeCloseStandardThreshold: s ?? 0
40
43
  }, {
41
44
  notional: e,
42
- holdingSeconds: 0
45
+ holdingSeconds: s ?? 0
43
46
  });
44
47
  return {
45
- openSolverFee: l(n),
46
- closeSolverFee: u
48
+ openSolverFee: d(n),
49
+ closeSolverFee: p,
50
+ staticSolverFeeOpen: f(c),
51
+ staticSolverFeeClose: f(l)
47
52
  };
48
53
  }
49
54
  function d({ positionType: t, markPrice: n, expectedFillPrice: r, quantity: a }) {
@@ -55,10 +60,10 @@ function d({ positionType: t, markPrice: n, expectedFillPrice: r, quantity: a })
55
60
  }
56
61
  var f = 1;
57
62
  function p(t) {
58
- let { positionType: n, markPrice: r, quantityBasic: a, cva: o, lf: s, partyAmm: c, cvaPercent: l, lfPercent: u, partyAmmPercent: d, platformFee: f, openSolverFee: p = "0", closeSolverFee: m = "0", expectedSettlementLoss: h = "0", shortFundingBufferPercent: g = 0 } = t, _ = i(f).plus(p).plus(m).plus(h);
59
- if (n === e.LONG) return i(o).plus(s).plus(c).plus(_).toString();
60
- let v = i(r).times(i(100 + g).div(100)), y = i(a).times(v).toString(), b = i(y).times(i(l)).div(100).toString(), x = i(y).times(i(u)).div(100).toString(), S = i(y).times(i(d)).div(100).toString();
61
- return i(b).plus(x).plus(S).plus(_).toString();
63
+ let { positionType: n, markPrice: r, quantityBasic: a, cva: o, lf: s, partyAmm: c, cvaPercent: l, lfPercent: u, partyAmmPercent: d, platformFee: f, openSolverFee: p = "0", closeSolverFee: m = "0", expectedSettlementLoss: h = "0", staticSolverFeeOpen: g = "0", staticSolverFeeClose: _ = "0", shortFundingBufferPercent: v = 0 } = t, y = i(f).plus(p).plus(m).plus(g).plus(_).plus(h);
64
+ if (n === e.LONG) return i(o).plus(s).plus(c).plus(y).toString();
65
+ let b = i(r).times(i(100 + v).div(100)), x = i(a).times(b).toString(), S = i(x).times(i(l)).div(100).toString(), C = i(x).times(i(u)).div(100).toString(), w = i(x).times(i(d)).div(100).toString();
66
+ return i(S).plus(C).plus(w).plus(y).toString();
62
67
  }
63
68
  function m(e, t, n) {
64
69
  let r = i(e.openFee.toString()).times(t), a = i(e.closeFee.toString()).times(n);
@@ -75,8 +80,8 @@ function g(e) {
75
80
  return BigInt(r(e).toFixed(0, n.ROUND_DOWN));
76
81
  }
77
82
  function _(t) {
78
- let { balance: n, openFee: r, closeFee: i, slippageFractionWei: a, leverage: o, positionType: s } = t, c = 10n ** 18n, l = s === e.SHORT ? a >= c ? 0n : c - a : c, u = BigInt(o) * (r + i), d = u >= c ? 0n : c - u;
79
- return n * l / c * d / c;
83
+ let { balance: n, openFee: r, slippageFractionWei: i, leverage: a, positionType: o } = t, s = 10n ** 18n, c = o === e.SHORT ? i >= s ? 0n : s - i : s, l = BigInt(a) * r, u = l >= s ? 0n : s - l;
84
+ return n * c / s * u / s;
80
85
  }
81
86
  //#endregion
82
87
  export { a as MARKET_ORDER_DEADLINE_SECONDS, f as SHORT_FUNDING_BUFFER_PERCENT, _ as calculateAvailableInstantOpenMargin, d as calculateExpectedSettlementLoss, p as calculateMargin, u as calculateSolverFees, l as calculateTradeParams, m as computePlatformFee, h as computePlatformFeeLegs, c as getLimitOrderDeadline, o as getMarketOrderDeadline, g as toWeiBigInt };
@@ -1 +1 @@
1
- {"version":3,"file":"trade-math.js","names":[],"sources":["../../../../src/solvers/instant-open/shared/trade-math.ts"],"sourcesContent":["import { parseEther, RoundingMode, toDecimal } from \"@symmio/utils/decimal\";\nimport { calculateSolverCloseFee } from \"../../shared/solver-close-fee\";\nimport { PositionType } from \"./types\";\n\n/**\n * Unix-seconds remaining for a MARKET-order deadline (5 minutes).\n */\nexport const MARKET_ORDER_DEADLINE_SECONDS = 300n;\n\n/**\n * Compute a unix-seconds `deadline` for a MARKET order.\n *\n * @param now - Optional override for `Math.floor(Date.now() / 1000)`. Useful for tests.\n */\nexport function getMarketOrderDeadline(now?: bigint): bigint {\n const base = now ?? BigInt(Math.floor(Date.now() / 1000));\n return base + MARKET_ORDER_DEADLINE_SECONDS;\n}\n\n/**\n * Unix-seconds remaining for a LIMIT-order deadline (15 minutes). A resting\n * limit order lives longer than a market fill, so it gets a wider window.\n */\nexport const LIMIT_ORDER_DEADLINE_SECONDS = 900n;\n\n/**\n * Compute a unix-seconds `deadline` for a LIMIT order (default 15 minutes).\n *\n * @param now - Optional override for `Math.floor(Date.now() / 1000)`. Useful for tests.\n */\nexport function getLimitOrderDeadline(now?: bigint): bigint {\n const base = now ?? BigInt(Math.floor(Date.now() / 1000));\n return base + LIMIT_ORDER_DEADLINE_SECONDS;\n}\n\n/**\n * Parameters for {@link calculateTradeParams}.\n */\nexport interface CalculateTradeParamsParameters {\n /** Mark price as decimal string (e.g. `\"50123.45\"`). */\n markPrice: string;\n /** Slippage percent (e.g. `5` for 5%). */\n slippage: number;\n /** Position side: `\"LONG\"` or `\"SHORT\"`. */\n positionType: PositionType;\n /** User input as decimal string. Interpreted as collateral when `inputField === \"PRICE\"`. */\n userInput: string;\n /** Input mode. `\"PRICE\"` = userInput is USD collateral; `\"TOKEN\"` = userInput is base token amount. */\n inputField: \"PRICE\" | \"TOKEN\";\n /** Position leverage (integer ≥ 1). */\n leverage: number;\n /** Price precision (decimals). */\n pricePrecision: number;\n /** Quantity precision (decimals). */\n quantityPrecision: number;\n /** Solver locked-param percentages (e.g. `\"0.02\"` for 2%). */\n cvaPercent?: string;\n /** Solver locked-param percentages (e.g. `\"0.01\"` for 1%). */\n lfPercent?: string;\n /** Solver locked-param percentages. */\n partyAmmPercent?: string;\n /** Solver locked-param percentages. */\n partyBmmPercent?: string;\n}\n\n/**\n * Return type of {@link calculateTradeParams}.\n *\n * All values are decimal strings. Convert to 18-decimal `bigint` with\n * `parseEther(...).toFixed(0)` (or {@link toWeiBigInt}) before passing to a\n * contract call.\n */\nexport interface CalculateTradeParamsReturnType {\n /** Open price with slippage applied, trimmed to `pricePrecision`. */\n requestedOpenPrice: string;\n /** Base quantity (no leverage), trimmed to `quantityPrecision`. */\n quantityBasic: string;\n /** Leveraged quantity (`quantityBasic × leverage`), trimmed to `quantityPrecision`. */\n quantity: string;\n /** Base notional (`quantityBasic × requestedOpenPrice`). */\n notionalBasic: string;\n /** Leveraged notional (`notionalBasic × leverage`). */\n notional: string;\n /** CVA locked margin (`notionalBasic × cvaPercent / 100`). */\n cva: string;\n /** LF locked margin (`notionalBasic × lfPercent / 100`). */\n lf: string;\n /** PartyA maintenance margin. */\n partyAmm: string;\n /** PartyB maintenance margin. */\n partyBmm: string;\n}\n\n/**\n * Pure trade-parameters calculator for lowcap MARKET orders.\n *\n * Steps:\n * 1. `requestedOpenPrice = markPrice × (1 ± slippage/100)` trimmed to `pricePrecision`.\n * 2. `quantityBasic = userInput / markPrice` (when `inputField === \"PRICE\"`) or\n * `userInput` (when `inputField === \"TOKEN\"`) trimmed to `quantityPrecision`.\n * Sized at the raw mark price, never the slippage-adjusted bound: `V × L` of\n * notional at mark `M` is `V × L / M` units on every fill, so changing the\n * slippage setting moves only the price bound and never resizes the position.\n * 3. `notionalBasic = quantityBasic × requestedOpenPrice`.\n * 4. `cva / lf / partyAmm / partyBmm = notionalBasic × percent / 100`.\n * 5. `quantity = quantityBasic × leverage` trimmed to `quantityPrecision`.\n * 6. `notional = notionalBasic × leverage`.\n *\n * @returns `null` when `markPrice` is zero/NaN or `userInput` is invalid.\n */\nexport function calculateTradeParams(\n parameters: CalculateTradeParamsParameters,\n): CalculateTradeParamsReturnType | null {\n const {\n markPrice,\n slippage,\n positionType,\n userInput,\n inputField,\n leverage,\n pricePrecision,\n quantityPrecision,\n cvaPercent,\n lfPercent,\n partyAmmPercent,\n partyBmmPercent,\n } = parameters;\n\n const markPriceDec = toDecimal(markPrice);\n if (markPriceDec.isZero() || markPriceDec.isNaN()) return null;\n const userInputDec = toDecimal(userInput);\n if (userInputDec.isZero() || userInputDec.isNaN()) return null;\n\n const signedSlippage = positionType === PositionType.SHORT ? slippage : -slippage;\n const slippageFactor = toDecimal(100 - signedSlippage).div(100);\n const requestedOpenPrice = markPriceDec.times(slippageFactor).toFixed(pricePrecision, RoundingMode.ROUND_DOWN);\n\n const quantityBasic =\n inputField === \"PRICE\"\n ? userInputDec.div(markPriceDec).toFixed(quantityPrecision, RoundingMode.ROUND_DOWN)\n : userInputDec.toFixed(quantityPrecision, RoundingMode.ROUND_DOWN);\n\n const notionalBasic = toDecimal(quantityBasic).times(requestedOpenPrice).toString();\n const cva = toDecimal(notionalBasic).times(toDecimal(cvaPercent)).div(100).toString();\n const lf = toDecimal(notionalBasic).times(toDecimal(lfPercent)).div(100).toString();\n const partyAmm = toDecimal(notionalBasic).times(toDecimal(partyAmmPercent)).div(100).toString();\n const partyBmm = toDecimal(notionalBasic).times(toDecimal(partyBmmPercent)).div(100).toString();\n\n const quantity = toDecimal(quantityBasic).times(leverage).toFixed(quantityPrecision, RoundingMode.ROUND_DOWN);\n const notional = toDecimal(notionalBasic).times(leverage).toString();\n\n return {\n requestedOpenPrice,\n quantityBasic,\n quantity,\n notionalBasic,\n notional,\n cva,\n lf,\n partyAmm,\n partyBmm,\n };\n}\n\n/**\n * Solver fees charged on the position, funded from the VA at open.\n */\nexport interface SolverFees {\n /** `hedgerFeeOpen × notional`, decimal string. */\n openSolverFee: string;\n /**\n * Close fee provisioned at open, decimal string. The solver charges more to\n * close a freshly opened position, so — since the holding time is unknown at\n * open — this provisions the **worst case**: `hedgerFeeCloseEarlyRate ×\n * notional` when the early-rate field is supplied, else the flat\n * `hedgerFeeClose × notional`.\n */\n closeSolverFee: string;\n}\n\n/**\n * Compute the solver's open and close fees on the leveraged notional.\n *\n * The solver charges its fees from the **VA balance**, so both legs must ride\n * the `addMargin` transfer from the SubAccount into the VA. The open leg is\n * `hedgerFeeOpen × notional`. The close leg is provisioned for the **worst\n * case**, because the holding time is unknown at open and an early close costs\n * more: when `hedgerFeeCloseEarlyRate` is supplied it uses the peak rate (the\n * rate at holding time 0); without it it falls back to the flat\n * `hedgerFeeClose`. An absent, NaN, or negative rate contributes `\"0\"`.\n */\nexport function calculateSolverFees({\n notional,\n hedgerFeeOpen,\n hedgerFeeClose,\n hedgerFeeCloseEarlyRate,\n hedgerFeeCloseEarlyThreshold,\n hedgerFeeCloseStandardThreshold,\n}: {\n /** Leveraged notional (decimal string). */\n notional: string;\n /** Solver open-fee rate as a decimal fraction string (e.g. `\"0.0004\"`). */\n hedgerFeeOpen: string | undefined;\n /** Solver standard close-fee rate as a decimal fraction string. Used when no early rate is given. */\n hedgerFeeClose: string | undefined;\n /** Early (peak) close-fee rate; when given, the close leg provisions this worst-case rate. */\n hedgerFeeCloseEarlyRate?: string;\n /** Early-window length in seconds (paired with `hedgerFeeCloseEarlyRate`). */\n hedgerFeeCloseEarlyThreshold?: number;\n /** Standard-rate threshold in seconds (paired with `hedgerFeeCloseEarlyRate`). */\n hedgerFeeCloseStandardThreshold?: number;\n}): SolverFees {\n const notionalDec = toDecimal(notional);\n const toFee = (rate: string | undefined) => {\n const rateDec = toDecimal(rate);\n if (rateDec.isNaN() || rateDec.isNegative() || notionalDec.isNaN()) return \"0\";\n return notionalDec.times(rateDec).toString();\n };\n const closeSolverFee =\n hedgerFeeCloseEarlyRate !== undefined\n ? calculateSolverCloseFee(\n {\n hedgerFeeClose: hedgerFeeClose ?? \"0\",\n hedgerFeeCloseEarlyRate,\n hedgerFeeCloseEarlyThreshold: hedgerFeeCloseEarlyThreshold ?? 0,\n hedgerFeeCloseStandardThreshold: hedgerFeeCloseStandardThreshold ?? 0,\n },\n { notional, holdingSeconds: 0 },\n )\n : toFee(hedgerFeeClose);\n return { openSolverFee: toFee(hedgerFeeOpen), closeSolverFee };\n}\n\n/**\n * Expected settlement loss charged from the VA when the fill lands away from\n * the mark price the order was sized at.\n *\n * Side-aware: a LONG loses when the expected fill is **above** mark\n * (`(expectedFillPrice − markPrice) × quantity`), a SHORT when it is **below**\n * (`(markPrice − expectedFillPrice) × quantity`). Clamped at zero — a\n * favorable expected fill never shrinks the transfer. Returns `\"0\"` when no\n * usable estimate exists.\n */\nexport function calculateExpectedSettlementLoss({\n positionType,\n markPrice,\n expectedFillPrice,\n quantity,\n}: {\n positionType: PositionType;\n /** Mark price the order was sized at (decimal string). */\n markPrice: string;\n /** Solver's estimated fill price (decimal string), when available. */\n expectedFillPrice: string | undefined;\n /** Leveraged order quantity (decimal string). */\n quantity: string;\n}): string {\n if (expectedFillPrice === undefined) return \"0\";\n const mark = toDecimal(markPrice);\n const fill = toDecimal(expectedFillPrice);\n const quantityDec = toDecimal(quantity);\n if (mark.isNaN() || fill.isNaN() || fill.isZero() || quantityDec.isNaN()) return \"0\";\n\n const loss =\n positionType === PositionType.SHORT ? mark.minus(fill).times(quantityDec) : fill.minus(mark).times(quantityDec);\n return loss.isNegative() || loss.isNaN() ? \"0\" : loss.toString();\n}\n\n/**\n * Parameters for {@link calculateMargin}.\n */\nexport interface CalculateMarginParameters {\n /** Position side. */\n positionType: PositionType;\n /** Mark price (decimal string). */\n markPrice: string;\n /** Base quantity from {@link calculateTradeParams}. */\n quantityBasic: string;\n /** CVA from {@link calculateTradeParams}. */\n cva: string;\n /** LF from {@link calculateTradeParams}. */\n lf: string;\n /** PartyA maintenance margin from {@link calculateTradeParams}. */\n partyAmm: string;\n /** Solver locked-param percents (passed when recomputing for SHORT). */\n cvaPercent?: string;\n /** Solver locked-param percents. */\n lfPercent?: string;\n /** Solver locked-param percents. */\n partyAmmPercent?: string;\n /** On-chain platform fee as decimal string (from {@link computePlatformFee}). */\n platformFee: string;\n /** Solver open fee funded from the VA (from {@link calculateSolverFees}). Defaults to `\"0\"`. */\n openSolverFee?: string;\n /** Solver close fee provisioned at open (from {@link calculateSolverFees}). Defaults to `\"0\"`. */\n closeSolverFee?: string;\n /** Expected settlement loss vs the estimated fill (from {@link calculateExpectedSettlementLoss}). Defaults to `\"0\"`. */\n expectedSettlementLoss?: string;\n /**\n * Extra funding headroom percent applied to a SHORT's margin basis\n * (`markPrice × (1 + percent/100)`). A SHORT's `requestedOpenPrice` is a\n * contract FLOOR — a fill above it rescales the signed locks up, so the\n * prefund needs headroom the signed values do not carry. Defaults to `0`;\n * the lowcap open flow passes {@link SHORT_FUNDING_BUFFER_PERCENT}.\n */\n shortFundingBufferPercent?: number;\n}\n\n/**\n * Funding headroom percent the lowcap open flow applies to a SHORT's margin\n * basis (see {@link CalculateMarginParameters.shortFundingBufferPercent}).\n */\nexport const SHORT_FUNDING_BUFFER_PERCENT = 1;\n\n/**\n * Compute the `addMargin` amount for lowcap isolation.\n *\n * - **LONG**: `margin = cva + lf + partyAmm + fees`.\n * - **SHORT**: recompute the locked values at\n * `markPrice × (1 + shortFundingBufferPercent/100)`, then sum + fees — the\n * buffer covers lock growth when the fill lands above the SHORT's floor.\n *\n * `fees = platformFee + openSolverFee + closeSolverFee +\n * expectedSettlementLoss` — the solver charges its fees and the open-price\n * settlement from the **VA balance**, so every leg must ride this SubAccount →\n * VA transfer or the position opens underfunded.\n *\n * @returns Margin as decimal string.\n */\nexport function calculateMargin(parameters: CalculateMarginParameters): string {\n const {\n positionType,\n markPrice,\n quantityBasic,\n cva,\n lf,\n partyAmm,\n cvaPercent,\n lfPercent,\n partyAmmPercent,\n platformFee,\n openSolverFee = \"0\",\n closeSolverFee = \"0\",\n expectedSettlementLoss = \"0\",\n shortFundingBufferPercent = 0,\n } = parameters;\n\n const fees = toDecimal(platformFee).plus(openSolverFee).plus(closeSolverFee).plus(expectedSettlementLoss);\n\n if (positionType === PositionType.LONG) {\n return toDecimal(cva).plus(lf).plus(partyAmm).plus(fees).toString();\n }\n\n const marginPrice = toDecimal(markPrice).times(toDecimal(100 + shortFundingBufferPercent).div(100));\n const notionalBasicMargin = toDecimal(quantityBasic).times(marginPrice).toString();\n const cvaMargin = toDecimal(notionalBasicMargin).times(toDecimal(cvaPercent)).div(100).toString();\n const lfMargin = toDecimal(notionalBasicMargin).times(toDecimal(lfPercent)).div(100).toString();\n const partyAmmMargin = toDecimal(notionalBasicMargin).times(toDecimal(partyAmmPercent)).div(100).toString();\n\n return toDecimal(cvaMargin).plus(lfMargin).plus(partyAmmMargin).plus(fees).toString();\n}\n\n/**\n * On-chain `getFeeForUser` result, in 18-decimal fixed-point.\n */\nexport interface ComputePlatformFeeRates {\n /** Open fee rate as 18-decimal `bigint`. */\n openFee: bigint;\n /** Close fee rate as 18-decimal `bigint`. */\n closeFee: bigint;\n}\n\n/**\n * Compute the total platform fee for an open + close round trip.\n *\n * `(openFee × initialNotional + closeFee × closeNotional) / 1e18`.\n *\n * @param rates - Fee rates from `getFeeForUser`.\n * @param initialNotional - Notional at open, decimal string.\n * @param closeNotional - Notional at close, decimal string.\n * @returns Total fee as decimal string.\n */\nexport function computePlatformFee(\n rates: ComputePlatformFeeRates,\n initialNotional: string,\n closeNotional: string,\n): string {\n const open = toDecimal(rates.openFee.toString()).times(initialNotional);\n const close = toDecimal(rates.closeFee.toString()).times(closeNotional);\n return open.plus(close).div(toDecimal(\"1e18\")).toString();\n}\n\n/**\n * The two platform-fee legs, separated. Their sum equals\n * {@link computePlatformFee} for the same inputs.\n */\nexport interface PlatformFeeLegs {\n /** `openFee × openNotional / 1e18`, decimal string. */\n platformOpenFee: string;\n /** `closeFee × closeNotional / 1e18`, decimal string — provisioned at open. */\n platformCloseFee: string;\n}\n\n/**\n * Compute the platform open and close fee legs separately.\n *\n * Same math as {@link computePlatformFee}, split per leg for fee-breakdown\n * displays. Rates come from on-chain `getFeeForUser` (18-decimal fixed-point).\n */\nexport function computePlatformFeeLegs(\n rates: ComputePlatformFeeRates,\n openNotional: string,\n closeNotional: string,\n): PlatformFeeLegs {\n const scale = toDecimal(\"1e18\");\n return {\n platformOpenFee: toDecimal(rates.openFee.toString()).times(openNotional).div(scale).toString(),\n platformCloseFee: toDecimal(rates.closeFee.toString()).times(closeNotional).div(scale).toString(),\n };\n}\n\n/**\n * Convert a decimal string to an 18-decimal-fixed-point `bigint`.\n *\n * Wrapper over `parseEther` from `@symmio/utils/decimal` that returns\n * the wei value as `bigint` (truncated, no rounding) suitable for contract calls.\n */\nexport function toWeiBigInt(value: string): bigint {\n return BigInt(parseEther(value).toFixed(0, RoundingMode.ROUND_DOWN));\n}\n\n/**\n * Inputs for {@link calculateAvailableInstantOpenMargin}. All amounts are\n * 18-decimal wei / fixed-point.\n */\nexport interface CalculateAvailableInstantOpenMarginParameters {\n /** SubAccount available (deallocated) balance from `getAccountBalanceOf`; 1e18-scaled. */\n balance: bigint;\n /** Open fee rate (18-decimal fixed-point) from `getFeeForUser`. */\n openFee: bigint;\n /** Close fee rate (18-decimal fixed-point) from `getFeeForUser`. */\n closeFee: bigint;\n /** Slippage as an 18-decimal fraction (5% → `5n * 10n ** 16n`). */\n slippageFractionWei: bigint;\n /** Requested leverage (integer ≥ 1). */\n leverage: number;\n /** LONG skips the slippage cap; SHORT applies it. */\n positionType: PositionType;\n}\n\n/**\n * Maximum initial margin an instant open can spend. Shaves the raw available\n * balance for fees (both sides, charged on the leveraged notional) and — for\n * SHORT only — a worst-case slippage-fill buffer. Pure `bigint`; clamps to `0n`.\n *\n * ```text\n * available = balance\n * × max(0, 1 − slippageFactor) // SHORT: slippage, LONG: 0\n * × max(0, 1 − leverage × (openFee + closeFee))\n * ```\n *\n * A SHORT's `requestOpenPrice = markPrice × (1 − s)` is a contract FLOOR: a fill\n * above it rescales the signed locks by up to `1 / (1 − s)`, so capping usable\n * balance at `balance × (1 − s)` covers that growth. A LONG's request price is a\n * ceiling, so fills can only shrink the locks and need no cap.\n *\n * @returns spendable margin in 18-decimal wei.\n * @example\n * ```ts\n * const max = calculateAvailableInstantOpenMargin({\n * balance,\n * openFee,\n * closeFee,\n * slippageFractionWei: 5n * 10n ** 16n, // 5%\n * leverage: 10,\n * positionType: PositionType.SHORT,\n * });\n * ```\n */\nexport function calculateAvailableInstantOpenMargin(parameters: CalculateAvailableInstantOpenMarginParameters): bigint {\n const { balance, openFee, closeFee, slippageFractionWei, leverage, positionType } = parameters;\n const ONE_E18 = 10n ** 18n;\n\n const slippageMultiplier =\n positionType === PositionType.SHORT\n ? slippageFractionWei >= ONE_E18\n ? 0n\n : ONE_E18 - slippageFractionWei\n : ONE_E18;\n\n const leverageScaled = BigInt(leverage) * (openFee + closeFee);\n const feeMultiplier = leverageScaled >= ONE_E18 ? 0n : ONE_E18 - leverageScaled;\n\n const afterSlippage = (balance * slippageMultiplier) / ONE_E18;\n return (afterSlippage * feeMultiplier) / ONE_E18;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"trade-math.js","names":[],"sources":["../../../../src/solvers/instant-open/shared/trade-math.ts"],"sourcesContent":["import { parseEther, RoundingMode, toDecimal } from \"@symmio/utils/decimal\";\nimport { calculateSolverCloseFee } from \"../../shared/solver-close-fee\";\nimport { PositionType } from \"./types\";\n\n/**\n * Unix-seconds remaining for a MARKET-order deadline (5 minutes).\n */\nexport const MARKET_ORDER_DEADLINE_SECONDS = 300n;\n\n/**\n * Compute a unix-seconds `deadline` for a MARKET order.\n *\n * @param now - Optional override for `Math.floor(Date.now() / 1000)`. Useful for tests.\n */\nexport function getMarketOrderDeadline(now?: bigint): bigint {\n const base = now ?? BigInt(Math.floor(Date.now() / 1000));\n return base + MARKET_ORDER_DEADLINE_SECONDS;\n}\n\n/**\n * Unix-seconds remaining for a LIMIT-order deadline (15 minutes). A resting\n * limit order lives longer than a market fill, so it gets a wider window.\n */\nexport const LIMIT_ORDER_DEADLINE_SECONDS = 900n;\n\n/**\n * Compute a unix-seconds `deadline` for a LIMIT order (default 15 minutes).\n *\n * @param now - Optional override for `Math.floor(Date.now() / 1000)`. Useful for tests.\n */\nexport function getLimitOrderDeadline(now?: bigint): bigint {\n const base = now ?? BigInt(Math.floor(Date.now() / 1000));\n return base + LIMIT_ORDER_DEADLINE_SECONDS;\n}\n\n/**\n * Parameters for {@link calculateTradeParams}.\n */\nexport interface CalculateTradeParamsParameters {\n /** Mark price as decimal string (e.g. `\"50123.45\"`). */\n markPrice: string;\n /** Slippage percent (e.g. `5` for 5%). */\n slippage: number;\n /** Position side: `\"LONG\"` or `\"SHORT\"`. */\n positionType: PositionType;\n /** User input as decimal string. Interpreted as collateral when `inputField === \"PRICE\"`. */\n userInput: string;\n /** Input mode. `\"PRICE\"` = userInput is USD collateral; `\"TOKEN\"` = userInput is base token amount. */\n inputField: \"PRICE\" | \"TOKEN\";\n /** Position leverage (integer ≥ 1). */\n leverage: number;\n /** Price precision (decimals). */\n pricePrecision: number;\n /** Quantity precision (decimals). */\n quantityPrecision: number;\n /** Solver locked-param percentages (e.g. `\"0.02\"` for 2%). */\n cvaPercent?: string;\n /** Solver locked-param percentages (e.g. `\"0.01\"` for 1%). */\n lfPercent?: string;\n /** Solver locked-param percentages. */\n partyAmmPercent?: string;\n /** Solver locked-param percentages. */\n partyBmmPercent?: string;\n}\n\n/**\n * Return type of {@link calculateTradeParams}.\n *\n * All values are decimal strings. Convert to 18-decimal `bigint` with\n * `parseEther(...).toFixed(0)` (or {@link toWeiBigInt}) before passing to a\n * contract call.\n */\nexport interface CalculateTradeParamsReturnType {\n /** Open price with slippage applied, trimmed to `pricePrecision`. */\n requestedOpenPrice: string;\n /** Base quantity (no leverage), trimmed to `quantityPrecision`. */\n quantityBasic: string;\n /** Leveraged quantity (`quantityBasic × leverage`), trimmed to `quantityPrecision`. */\n quantity: string;\n /** Base notional (`quantityBasic × requestedOpenPrice`). */\n notionalBasic: string;\n /** Leveraged notional (`notionalBasic × leverage`). */\n notional: string;\n /** CVA locked margin (`notionalBasic × cvaPercent / 100`). */\n cva: string;\n /** LF locked margin (`notionalBasic × lfPercent / 100`). */\n lf: string;\n /** PartyA maintenance margin. */\n partyAmm: string;\n /** PartyB maintenance margin. */\n partyBmm: string;\n}\n\n/**\n * Pure trade-parameters calculator for lowcap MARKET orders.\n *\n * Steps:\n * 1. `requestedOpenPrice = markPrice × (1 ± slippage/100)` trimmed to `pricePrecision`.\n * 2. `quantityBasic = userInput / markPrice` (when `inputField === \"PRICE\"`) or\n * `userInput` (when `inputField === \"TOKEN\"`) trimmed to `quantityPrecision`.\n * Sized at the raw mark price, never the slippage-adjusted bound: `V × L` of\n * notional at mark `M` is `V × L / M` units on every fill, so changing the\n * slippage setting moves only the price bound and never resizes the position.\n * 3. `notionalBasic = quantityBasic × requestedOpenPrice`.\n * 4. `cva / lf / partyAmm / partyBmm = notionalBasic × percent / 100`.\n * 5. `quantity = quantityBasic × leverage` trimmed to `quantityPrecision`.\n * 6. `notional = notionalBasic × leverage`.\n *\n * @returns `null` when `markPrice` is zero/NaN or `userInput` is invalid.\n */\nexport function calculateTradeParams(\n parameters: CalculateTradeParamsParameters,\n): CalculateTradeParamsReturnType | null {\n const {\n markPrice,\n slippage,\n positionType,\n userInput,\n inputField,\n leverage,\n pricePrecision,\n quantityPrecision,\n cvaPercent,\n lfPercent,\n partyAmmPercent,\n partyBmmPercent,\n } = parameters;\n\n const markPriceDec = toDecimal(markPrice);\n if (markPriceDec.isZero() || markPriceDec.isNaN()) return null;\n const userInputDec = toDecimal(userInput);\n if (userInputDec.isZero() || userInputDec.isNaN()) return null;\n\n const signedSlippage = positionType === PositionType.SHORT ? slippage : -slippage;\n const slippageFactor = toDecimal(100 - signedSlippage).div(100);\n const requestedOpenPrice = markPriceDec.times(slippageFactor).toFixed(pricePrecision, RoundingMode.ROUND_DOWN);\n\n const quantityBasic =\n inputField === \"PRICE\"\n ? userInputDec.div(markPriceDec).toFixed(quantityPrecision, RoundingMode.ROUND_DOWN)\n : userInputDec.toFixed(quantityPrecision, RoundingMode.ROUND_DOWN);\n\n const notionalBasic = toDecimal(quantityBasic).times(requestedOpenPrice).toString();\n const cva = toDecimal(notionalBasic).times(toDecimal(cvaPercent)).div(100).toString();\n const lf = toDecimal(notionalBasic).times(toDecimal(lfPercent)).div(100).toString();\n const partyAmm = toDecimal(notionalBasic).times(toDecimal(partyAmmPercent)).div(100).toString();\n const partyBmm = toDecimal(notionalBasic).times(toDecimal(partyBmmPercent)).div(100).toString();\n\n const quantity = toDecimal(quantityBasic).times(leverage).toFixed(quantityPrecision, RoundingMode.ROUND_DOWN);\n const notional = toDecimal(notionalBasic).times(leverage).toString();\n\n return {\n requestedOpenPrice,\n quantityBasic,\n quantity,\n notionalBasic,\n notional,\n cva,\n lf,\n partyAmm,\n partyBmm,\n };\n}\n\n/**\n * Solver fees charged on the position, funded from the VA at open.\n */\nexport interface SolverFees {\n /** `hedgerFeeOpen × notional`, decimal string. */\n openSolverFee: string;\n /**\n * Close-fee **estimate**, decimal string — the solver charges this at close\n * from the position, **not** funded by the open's `addMargin`. Reported at the\n * representative **standard** (floor) rate: `hedgerFeeClose × notional` (the\n * decay schedule evaluated at its standard threshold when the early fields are\n * supplied). It is an estimate, not the exact charge: the actual close fee is\n * priced from the real holding time at close and capped by the signed\n * `closeRateCap`.\n */\n closeSolverFee: string;\n /**\n * Static solver fee charged per instant open, decimal string — a flat USD\n * amount from the solver's `/info` config, **not** scaled by the notional.\n * `\"0\"` when the solver publishes none.\n */\n staticSolverFeeOpen: string;\n /**\n * Static solver close fee provisioned at open, decimal string — a flat USD\n * amount from the solver's `/info` config, **not** scaled by the notional.\n * `\"0\"` when the solver publishes none.\n */\n staticSolverFeeClose: string;\n}\n\n/**\n * Compute every fee the solver charges on an instant open: the rate legs on\n * the leveraged notional plus the flat static legs.\n *\n * The **open** legs (`openSolverFee`, `staticSolverFeeOpen`) are charged from\n * the VA at open, so they ride the `addMargin` transfer. The **close** legs\n * (`closeSolverFee`, `staticSolverFeeClose`) are charged at close from the\n * position — the contract collects them at close execution, not at open — so\n * they are returned as **estimates** for previews, not amounts the open funds.\n * The close-fee estimate uses the **standard** (floor) rate: when\n * `hedgerFeeCloseEarlyRate` is supplied the decay schedule is evaluated at its\n * standard threshold (which yields `hedgerFeeClose`), else it is the flat\n * `hedgerFeeClose × notional`. The static legs pass through as-is — flat USD\n * amounts, size-independent. An absent, NaN, or negative rate or static\n * contributes `\"0\"`.\n */\nexport function calculateSolverFees({\n notional,\n hedgerFeeOpen,\n hedgerFeeClose,\n hedgerFeeCloseEarlyRate,\n hedgerFeeCloseEarlyThreshold,\n hedgerFeeCloseStandardThreshold,\n staticSolverFeeOpen,\n staticSolverFeeClose,\n}: {\n /** Leveraged notional (decimal string). */\n notional: string;\n /** Solver open-fee rate as a decimal fraction string (e.g. `\"0.0004\"`). */\n hedgerFeeOpen: string | undefined;\n /** Solver standard (floor) close-fee rate as a decimal fraction string — the close-fee estimate is priced at this rate. */\n hedgerFeeClose: string | undefined;\n /** Early (peak) close-fee rate; parametrizes the decay schedule the standard-rate estimate is read from. */\n hedgerFeeCloseEarlyRate?: string;\n /** Early-window length in seconds (paired with `hedgerFeeCloseEarlyRate`). */\n hedgerFeeCloseEarlyThreshold?: number;\n /** Standard-rate threshold in seconds (paired with `hedgerFeeCloseEarlyRate`) — the close-fee estimate is evaluated here. */\n hedgerFeeCloseStandardThreshold?: number;\n /** Static solver open fee — flat USD decimal string (solver `/info`). Defaults to `\"0\"`. */\n staticSolverFeeOpen?: string;\n /** Static solver close fee — flat USD decimal string (solver `/info`); an estimate charged at close, not funded at open. Defaults to `\"0\"`. */\n staticSolverFeeClose?: string;\n}): SolverFees {\n const notionalDec = toDecimal(notional);\n const toFee = (rate: string | undefined) => {\n const rateDec = toDecimal(rate);\n if (rateDec.isNaN() || rateDec.isNegative() || notionalDec.isNaN()) return \"0\";\n return notionalDec.times(rateDec).toString();\n };\n /** Flat USD leg: passed through, not multiplied by the notional. */\n const toStaticFee = (value: string | undefined) => {\n const valueDec = toDecimal(value);\n return valueDec.isNaN() || valueDec.isNegative() ? \"0\" : valueDec.toString();\n };\n // Close-fee ESTIMATE at the STANDARD (floor) rate. The close fee is charged at\n // close from the position — not funded by the open's addMargin — so the\n // estimate reports the representative standard rate (the decay schedule read\n // at its standard threshold) rather than the worst-case early rate.\n const closeSolverFee =\n hedgerFeeCloseEarlyRate !== undefined\n ? calculateSolverCloseFee(\n {\n hedgerFeeClose: hedgerFeeClose ?? \"0\",\n hedgerFeeCloseEarlyRate,\n hedgerFeeCloseEarlyThreshold: hedgerFeeCloseEarlyThreshold ?? 0,\n hedgerFeeCloseStandardThreshold: hedgerFeeCloseStandardThreshold ?? 0,\n },\n { notional, holdingSeconds: hedgerFeeCloseStandardThreshold ?? 0 },\n )\n : toFee(hedgerFeeClose);\n return {\n openSolverFee: toFee(hedgerFeeOpen),\n closeSolverFee,\n staticSolverFeeOpen: toStaticFee(staticSolverFeeOpen),\n staticSolverFeeClose: toStaticFee(staticSolverFeeClose),\n };\n}\n\n/**\n * Expected settlement loss charged from the VA when the fill lands away from\n * the mark price the order was sized at.\n *\n * Side-aware: a LONG loses when the expected fill is **above** mark\n * (`(expectedFillPrice − markPrice) × quantity`), a SHORT when it is **below**\n * (`(markPrice − expectedFillPrice) × quantity`). Clamped at zero — a\n * favorable expected fill never shrinks the transfer. Returns `\"0\"` when no\n * usable estimate exists.\n */\nexport function calculateExpectedSettlementLoss({\n positionType,\n markPrice,\n expectedFillPrice,\n quantity,\n}: {\n positionType: PositionType;\n /** Mark price the order was sized at (decimal string). */\n markPrice: string;\n /** Solver's estimated fill price (decimal string), when available. */\n expectedFillPrice: string | undefined;\n /** Leveraged order quantity (decimal string). */\n quantity: string;\n}): string {\n if (expectedFillPrice === undefined) return \"0\";\n const mark = toDecimal(markPrice);\n const fill = toDecimal(expectedFillPrice);\n const quantityDec = toDecimal(quantity);\n if (mark.isNaN() || fill.isNaN() || fill.isZero() || quantityDec.isNaN()) return \"0\";\n\n const loss =\n positionType === PositionType.SHORT ? mark.minus(fill).times(quantityDec) : fill.minus(mark).times(quantityDec);\n return loss.isNegative() || loss.isNaN() ? \"0\" : loss.toString();\n}\n\n/**\n * Parameters for {@link calculateMargin}.\n */\nexport interface CalculateMarginParameters {\n /** Position side. */\n positionType: PositionType;\n /** Mark price (decimal string). */\n markPrice: string;\n /** Base quantity from {@link calculateTradeParams}. */\n quantityBasic: string;\n /** CVA from {@link calculateTradeParams}. */\n cva: string;\n /** LF from {@link calculateTradeParams}. */\n lf: string;\n /** PartyA maintenance margin from {@link calculateTradeParams}. */\n partyAmm: string;\n /** Solver locked-param percents (passed when recomputing for SHORT). */\n cvaPercent?: string;\n /** Solver locked-param percents. */\n lfPercent?: string;\n /** Solver locked-param percents. */\n partyAmmPercent?: string;\n /** On-chain platform fee as decimal string (from {@link computePlatformFee}). */\n platformFee: string;\n /** Solver open fee funded from the VA (from {@link calculateSolverFees}). Defaults to `\"0\"`. */\n openSolverFee?: string;\n /**\n * Solver close fee (from {@link calculateSolverFees}). Defaults to `\"0\"`. The\n * instant-open flow leaves this at `0` — the close fee is charged at close\n * from the position, not funded here — and includes it only if a caller\n * deliberately chooses to reserve it.\n */\n closeSolverFee?: string;\n /** Expected settlement loss vs the estimated fill (from {@link calculateExpectedSettlementLoss}). Defaults to `\"0\"`. */\n expectedSettlementLoss?: string;\n /** Static solver open fee — flat USD, not rate × notional (from {@link calculateSolverFees}). Defaults to `\"0\"`. */\n staticSolverFeeOpen?: string;\n /**\n * Static solver close fee — flat USD (from {@link calculateSolverFees}).\n * Defaults to `\"0\"`. Like {@link CalculateMarginParameters.closeSolverFee},\n * the instant-open flow leaves this at `0`; it is charged at close.\n */\n staticSolverFeeClose?: string;\n /**\n * Extra funding headroom percent applied to a SHORT's margin basis\n * (`markPrice × (1 + percent/100)`). A SHORT's `requestedOpenPrice` is a\n * contract FLOOR — a fill above it rescales the signed locks up, so the\n * prefund needs headroom the signed values do not carry. Defaults to `0`;\n * the lowcap open flow passes {@link SHORT_FUNDING_BUFFER_PERCENT}.\n */\n shortFundingBufferPercent?: number;\n}\n\n/**\n * Funding headroom percent the lowcap open flow applies to a SHORT's margin\n * basis (see {@link CalculateMarginParameters.shortFundingBufferPercent}).\n */\nexport const SHORT_FUNDING_BUFFER_PERCENT = 1;\n\n/**\n * Compute the `addMargin` amount for lowcap isolation.\n *\n * - **LONG**: `margin = cva + lf + partyAmm + fees`.\n * - **SHORT**: recompute the locked values at\n * `markPrice × (1 + shortFundingBufferPercent/100)`, then sum + fees — the\n * buffer covers lock growth when the fill lands above the SHORT's floor.\n *\n * `fees = platformFee + openSolverFee + closeSolverFee +\n * staticSolverFeeOpen + staticSolverFeeClose + expectedSettlementLoss` — the\n * sum of whatever legs the caller passes, funded from the **VA balance** via\n * the SubAccount → VA transfer. The instant-open flow passes only the\n * **open-side** legs plus the settlement provision (`platformFee` = the open\n * leg, `openSolverFee`, `staticSolverFeeOpen`, `expectedSettlementLoss`) and\n * leaves the close legs at `0`: close fees are charged at close from the\n * position, so pre-funding them would strand collateral. The static legs are\n * flat USD amounts and do not scale with the notional.\n *\n * @returns Margin as decimal string.\n */\nexport function calculateMargin(parameters: CalculateMarginParameters): string {\n const {\n positionType,\n markPrice,\n quantityBasic,\n cva,\n lf,\n partyAmm,\n cvaPercent,\n lfPercent,\n partyAmmPercent,\n platformFee,\n openSolverFee = \"0\",\n closeSolverFee = \"0\",\n expectedSettlementLoss = \"0\",\n staticSolverFeeOpen = \"0\",\n staticSolverFeeClose = \"0\",\n shortFundingBufferPercent = 0,\n } = parameters;\n\n const fees = toDecimal(platformFee)\n .plus(openSolverFee)\n .plus(closeSolverFee)\n .plus(staticSolverFeeOpen)\n .plus(staticSolverFeeClose)\n .plus(expectedSettlementLoss);\n\n if (positionType === PositionType.LONG) {\n return toDecimal(cva).plus(lf).plus(partyAmm).plus(fees).toString();\n }\n\n const marginPrice = toDecimal(markPrice).times(toDecimal(100 + shortFundingBufferPercent).div(100));\n const notionalBasicMargin = toDecimal(quantityBasic).times(marginPrice).toString();\n const cvaMargin = toDecimal(notionalBasicMargin).times(toDecimal(cvaPercent)).div(100).toString();\n const lfMargin = toDecimal(notionalBasicMargin).times(toDecimal(lfPercent)).div(100).toString();\n const partyAmmMargin = toDecimal(notionalBasicMargin).times(toDecimal(partyAmmPercent)).div(100).toString();\n\n return toDecimal(cvaMargin).plus(lfMargin).plus(partyAmmMargin).plus(fees).toString();\n}\n\n/**\n * On-chain `getFeeForUser` result, in 18-decimal fixed-point.\n */\nexport interface ComputePlatformFeeRates {\n /** Open fee rate as 18-decimal `bigint`. */\n openFee: bigint;\n /** Close fee rate as 18-decimal `bigint`. */\n closeFee: bigint;\n}\n\n/**\n * Compute the total platform fee for an open + close round trip.\n *\n * `(openFee × initialNotional + closeFee × closeNotional) / 1e18`.\n *\n * @param rates - Fee rates from `getFeeForUser`.\n * @param initialNotional - Notional at open, decimal string.\n * @param closeNotional - Notional at close, decimal string.\n * @returns Total fee as decimal string.\n */\nexport function computePlatformFee(\n rates: ComputePlatformFeeRates,\n initialNotional: string,\n closeNotional: string,\n): string {\n const open = toDecimal(rates.openFee.toString()).times(initialNotional);\n const close = toDecimal(rates.closeFee.toString()).times(closeNotional);\n return open.plus(close).div(toDecimal(\"1e18\")).toString();\n}\n\n/**\n * The two platform-fee legs, separated. Their sum equals\n * {@link computePlatformFee} for the same inputs.\n */\nexport interface PlatformFeeLegs {\n /** `openFee × openNotional / 1e18`, decimal string. */\n platformOpenFee: string;\n /** `closeFee × closeNotional / 1e18`, decimal string — provisioned at open. */\n platformCloseFee: string;\n}\n\n/**\n * Compute the platform open and close fee legs separately.\n *\n * Same math as {@link computePlatformFee}, split per leg for fee-breakdown\n * displays. Rates come from on-chain `getFeeForUser` (18-decimal fixed-point).\n */\nexport function computePlatformFeeLegs(\n rates: ComputePlatformFeeRates,\n openNotional: string,\n closeNotional: string,\n): PlatformFeeLegs {\n const scale = toDecimal(\"1e18\");\n return {\n platformOpenFee: toDecimal(rates.openFee.toString()).times(openNotional).div(scale).toString(),\n platformCloseFee: toDecimal(rates.closeFee.toString()).times(closeNotional).div(scale).toString(),\n };\n}\n\n/**\n * Convert a decimal string to an 18-decimal-fixed-point `bigint`.\n *\n * Wrapper over `parseEther` from `@symmio/utils/decimal` that returns\n * the wei value as `bigint` (truncated, no rounding) suitable for contract calls.\n */\nexport function toWeiBigInt(value: string): bigint {\n return BigInt(parseEther(value).toFixed(0, RoundingMode.ROUND_DOWN));\n}\n\n/**\n * Inputs for {@link calculateAvailableInstantOpenMargin}. All amounts are\n * 18-decimal wei / fixed-point.\n */\nexport interface CalculateAvailableInstantOpenMarginParameters {\n /** SubAccount available (deallocated) balance from `getAccountBalanceOf`; 1e18-scaled. */\n balance: bigint;\n /** Open fee rate (18-decimal fixed-point) from `getFeeForUser`. */\n openFee: bigint;\n /**\n * @deprecated No longer used and ignored. Close fees are charged at close from\n * the position, not reserved from the open budget, so the shave applies the\n * open fee only. Kept as an optional field so existing callers still compile.\n */\n closeFee?: bigint;\n /** Slippage as an 18-decimal fraction (5% → `5n * 10n ** 16n`). */\n slippageFractionWei: bigint;\n /** Requested leverage (integer ≥ 1). */\n leverage: number;\n /** LONG skips the slippage cap; SHORT applies it. */\n positionType: PositionType;\n}\n\n/**\n * Maximum initial margin an instant open can spend. Shaves the raw available\n * balance for the **open** fee (charged on the leveraged notional) and — for\n * SHORT only — a worst-case slippage-fill buffer. Pure `bigint`; clamps to `0n`.\n *\n * ```text\n * available = balance\n * × max(0, 1 − slippageFactor) // SHORT: slippage, LONG: 0\n * × max(0, 1 − leverage × openFee)\n * ```\n *\n * The close fee is **not** shaved: it is charged at close from the position, not\n * reserved from the open budget, so reserving it here would understate the max.\n *\n * A SHORT's `requestOpenPrice = markPrice × (1 − s)` is a contract FLOOR: a fill\n * above it rescales the signed locks by up to `1 / (1 − s)`, so capping usable\n * balance at `balance × (1 − s)` covers that growth. A LONG's request price is a\n * ceiling, so fills can only shrink the locks and need no cap.\n *\n * @returns spendable margin in 18-decimal wei.\n * @example\n * ```ts\n * const max = calculateAvailableInstantOpenMargin({\n * balance,\n * openFee,\n * slippageFractionWei: 5n * 10n ** 16n, // 5%\n * leverage: 10,\n * positionType: PositionType.SHORT,\n * });\n * ```\n */\nexport function calculateAvailableInstantOpenMargin(parameters: CalculateAvailableInstantOpenMarginParameters): bigint {\n const { balance, openFee, slippageFractionWei, leverage, positionType } = parameters;\n const ONE_E18 = 10n ** 18n;\n\n const slippageMultiplier =\n positionType === PositionType.SHORT\n ? slippageFractionWei >= ONE_E18\n ? 0n\n : ONE_E18 - slippageFractionWei\n : ONE_E18;\n\n const leverageScaled = BigInt(leverage) * openFee;\n const feeMultiplier = leverageScaled >= ONE_E18 ? 0n : ONE_E18 - leverageScaled;\n\n const afterSlippage = (balance * slippageMultiplier) / ONE_E18;\n return (afterSlippage * feeMultiplier) / ONE_E18;\n}\n"],"mappings":"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"}
@@ -12,7 +12,7 @@ export { PositionType };
12
12
  export declare const ORDER_TYPE_MARKET: 1;
13
13
  /** Contract enum value for LIMIT orders (majors / rasa only). */
14
14
  export declare const ORDER_TYPE_LIMIT: 0;
15
- /** Order type sent to the hedger: `ORDER_TYPE_MARKET` (instant) or `ORDER_TYPE_LIMIT`. */
15
+ /** Requested market or limit order. Close actions resolve the solver's contract order type before signing. */
16
16
  export type SolverOrderType = typeof ORDER_TYPE_MARKET | typeof ORDER_TYPE_LIMIT;
17
17
  /**
18
18
  * Virtual-account isolation type values used by `addMarginToNextVA`.
@@ -178,6 +178,23 @@ export interface InstantOpenMarketData {
178
178
  hedgerFeeCloseEarlyThreshold?: number;
179
179
  /** Pre-fetched standard-rate threshold in seconds (paired with `hedgerFeeCloseEarlyRate`). */
180
180
  hedgerFeeCloseStandardThreshold?: number;
181
+ /**
182
+ * Pre-fetched minimum `lf / (cva + lf + partyAmm)` portion (decimal
183
+ * fraction). Only consulted by full-balance funding, which validates the
184
+ * SDK-sized quantity against the market's quote constraints; when omitted
185
+ * there, resolved from solver markets.
186
+ */
187
+ minAcceptablePortionLf?: string;
188
+ /** Pre-fetched minimum locked-margin sum (decimal string). Full-balance funding only; see `minAcceptablePortionLf`. */
189
+ minAcceptableQuoteValue?: string;
190
+ /** Pre-fetched maximum notional position value; `0` ⇒ unpublished. Full-balance funding only. */
191
+ maxNotionalValue?: number;
192
+ /** Pre-fetched minimum notional position value (decimal string). Full-balance funding only. */
193
+ minNotionalValue?: string;
194
+ /** Pre-fetched maximum order quantity (decimal string); `"0"` ⇒ unpublished. Full-balance funding only. */
195
+ maxQuantity?: string;
196
+ /** Pre-fetched minimum tradable increment / lot size (decimal string). Full-balance funding only. */
197
+ lotSize?: string;
181
198
  }
182
199
  /**
183
200
  * Solver-fee rate caps authorized on a quote, as 18-decimal fixed-point ratios
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/solvers/instant-open/shared/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/solvers/instant-open/shared/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../../../src/solvers/instant-open/shared/types.ts"],"sourcesContent":["import type { Address, Hex } from \"viem\";\nimport type { InstantLayerAccount } from \"../../../symmio-contracts/instant-layer/types\";\nimport { PositionType, type SingleUpnlAndPriceSig } from \"../../../symmio-contracts/symmio/types\";\n\n/**\n * Re-export the canonical trade-side enum (defined in\n * `symmio-contracts/symmio/types.ts`) so the instant-open slice has one place\n * to import it from. Numeric values match the on-chain enum: `LONG = 0`,\n * `SHORT = 1`.\n */\nexport { PositionType };\n\n/** Contract enum value for MARKET orders. */\nexport const ORDER_TYPE_MARKET = 1 as const;\n/** Contract enum value for LIMIT orders (majors / rasa only). */\nexport const ORDER_TYPE_LIMIT = 0 as const;\n/** Order type sent to the hedger: `ORDER_TYPE_MARKET` (instant) or `ORDER_TYPE_LIMIT`. */\nexport type SolverOrderType = typeof ORDER_TYPE_MARKET | typeof ORDER_TYPE_LIMIT;\n\n/**\n * Virtual-account isolation type values used by `addMarginToNextVA`.\n *\n * Matches the on-chain `VirtualAccountIsolationType` enum.\n */\nexport const VIRTUAL_ACCOUNT_ISOLATION_TYPE = {\n POSITION: 0,\n MARKET: 1,\n MARKET_LONG: 2,\n MARKET_SHORT: 3,\n} as const;\n\nexport type VirtualAccountIsolationType =\n (typeof VIRTUAL_ACCOUNT_ISOLATION_TYPE)[keyof typeof VIRTUAL_ACCOUNT_ISOLATION_TYPE];\n\n/**\n * Map a trade side to the market-isolation type its Virtual Account is created\n * with. A `SHORT` lands in a `MARKET_SHORT` VA; everything else (i.e. `LONG`)\n * lands in a `MARKET_LONG` VA.\n *\n * This is the side ↔ isolation rule used both when opening (`addMarginToNextVA`)\n * and when predicting a not-yet-created VA's address\n * (`predictNextVirtualAccountAddress`). It lives next to\n * {@link VIRTUAL_ACCOUNT_ISOLATION_TYPE} so callers that only need the side\n * mapping (e.g. the quotes slice) can import it without pulling in the rest of\n * the instant-open flow.\n *\n * @param positionType - The trade side (`LONG` or `SHORT`).\n * @returns The matching {@link VirtualAccountIsolationType}\n * (`MARKET_SHORT` for `SHORT`, otherwise `MARKET_LONG`).\n *\n * @example\n * ```ts\n * isolationTypeForSide(PositionType.SHORT); // VIRTUAL_ACCOUNT_ISOLATION_TYPE.MARKET_SHORT\n * isolationTypeForSide(PositionType.LONG); // VIRTUAL_ACCOUNT_ISOLATION_TYPE.MARKET_LONG\n * ```\n *\n * TODO: what happend if someone have different isolation type than the one we expect? like POSITION or MARKET?\n */\nexport function isolationTypeForSide(positionType: PositionType): VirtualAccountIsolationType {\n return positionType === PositionType.SHORT\n ? VIRTUAL_ACCOUNT_ISOLATION_TYPE.MARKET_SHORT\n : VIRTUAL_ACCOUNT_ISOLATION_TYPE.MARKET_LONG;\n}\n\n/**\n * Muon oracle signature accepted by `sendQuoteWithAffiliateAndData`.\n *\n * For lowcap flows, pass `ZERO_UPNL_SIG` or build a placeholder with\n * `getFakeSendQuoteMuonSignature`. Solvers that enforce Muon verification\n * (Rasa / majors) need a live attestation from `getSendQuoteUpnlSig`.\n *\n * @deprecated Renamed to {@link SingleUpnlAndPriceSig} to match the on-chain\n * struct name. This alias is kept for one release and will be removed in the\n * next major.\n */\nexport type UpnlSig = SingleUpnlAndPriceSig;\n\n/**\n * InstantLayer EIP-712 `ReplayAttackHeader` struct.\n */\nexport interface ReplayAttackHeader {\n /** Operation nonce (`0n` for single-use ops). */\n nonce: bigint;\n /** Unix-seconds deadline. */\n deadline: bigint;\n /** Random 32-byte salt. */\n salt: Hex;\n}\n\n/**\n * InstantLayer EIP-712 `FlexField` struct.\n */\nexport interface FlexField {\n /** Byte offset into `callData`. */\n offset: bigint;\n /** Byte length. */\n length: bigint;\n /** Address authorized to fill this slot. */\n authorizedFlexFiller: Address;\n}\n\n/**\n * InstantLayer EIP-712 `SignedOperation` struct.\n */\nexport interface SignedOperation {\n /** Session-key signer that produces the EIP-712 signature. */\n signer: Address;\n /** Target contract the operation calls. */\n target: Address;\n /** ABI-encoded calldata for the `target` call. */\n callData: Hex;\n /** Account whose authority the operation runs under. */\n signerAccount: InstantLayerAccount;\n /** Flex fields (empty for lowcap flows). */\n flexFields: FlexField[];\n /** Max number of times the operation may be executed. */\n maxUses: bigint;\n /** Replay-attack protection header. */\n replayAttackHeader: ReplayAttackHeader;\n}\n\n/**\n * Wire-format `SignedOperation` accepted by the hedger's `/instant_trade/*` REST API.\n *\n * Re-exports the orval-generated `Eip712SignedOperationJSON` shape; `bigint`s\n * are serialized as decimal strings to survive JSON.\n */\nexport type { Eip712SignedOperationJSON as SignedOperationPayload } from \"../../types/generated/enigma-solver\";\n\n/**\n * Wire-format signed-and-signed-operation pair accepted by the hedger API.\n *\n * Re-exports the orval-generated `Eip712OperationWithSigJSON`.\n */\nexport type { Eip712OperationWithSigJSON as InstantOperationPayload } from \"../../types/generated/enigma-solver\";\n\n/**\n * Locked-margin breakdown passed to `InstantOpenParameters`.\n *\n * All values are 18-decimal-wei `bigint` matching the contract argument order\n * of `sendQuoteWithAffiliateAndData`.\n */\nexport interface InstantOpenLockedParams {\n /** CVA locked margin (wei). */\n cva: bigint;\n /** LF locked margin (wei). */\n lf: bigint;\n /** PartyA maintenance margin (wei). */\n partyAmm: bigint;\n /** PartyB maintenance margin (wei). */\n partyBmm: bigint;\n}\n\n/**\n * Order-side trade values passed to `InstantOpenParameters`.\n *\n * All wei `bigint`s, final values (already through trade math + leverage).\n */\nexport interface InstantOpenOrder {\n /** Requested open price (wei). */\n price: bigint;\n /** Leveraged quantity (wei). */\n quantity: bigint;\n}\n\n/**\n * Market identification + precision metadata used by the wizard.\n *\n * Only `id` is required. `name`, `pricePrecision`, and `quantityPrecision` are\n * pre-fetched overrides; when omitted, the wizard resolves them from solver\n * `/contract-symbols` via `id`.\n */\nexport interface InstantOpenMarketData {\n /** Market `symbol_id` from solver markets. */\n id: number;\n /** Pre-fetched market name. When omitted, resolved from solver markets. */\n name?: string;\n /** Pre-fetched market price precision. When omitted, resolved from solver markets. */\n pricePrecision?: number;\n /** Pre-fetched market quantity precision. When omitted, resolved from solver markets. */\n quantityPrecision?: number;\n /** Pre-fetched `minOpenSolverFeeCap` (decimal ratio string). When omitted, resolved from solver markets. */\n minOpenSolverFeeCap?: string;\n /** Pre-fetched `minCloseSolverFeeCap` (decimal ratio string). When omitted, resolved from solver markets. */\n minCloseSolverFeeCap?: string;\n /** Pre-fetched solver open-fee rate (decimal fraction string). When omitted, resolved from solver markets. */\n hedgerFeeOpen?: string;\n /** Pre-fetched solver close-fee rate (decimal fraction string). When omitted, resolved from solver markets. */\n hedgerFeeClose?: string;\n /**\n * Pre-fetched early (peak) close-fee rate. When omitted on a lowcap (Enigma)\n * solver, resolved from `/symbols`; the open provisions this worst-case rate.\n * Ignored on non-lowcap solvers.\n */\n hedgerFeeCloseEarlyRate?: string;\n /** Pre-fetched early-window length in seconds (paired with `hedgerFeeCloseEarlyRate`). */\n hedgerFeeCloseEarlyThreshold?: number;\n /** Pre-fetched standard-rate threshold in seconds (paired with `hedgerFeeCloseEarlyRate`). */\n hedgerFeeCloseStandardThreshold?: number;\n}\n\n/**\n * Solver-fee rate caps authorized on a quote, as 18-decimal fixed-point ratios\n * of quote notional (perps-core v0.8.6 solver fees).\n *\n * Both caps are set immutably at `sendQuote` time — the close-side cap cannot\n * be changed later in `requestToClosePosition`. On-chain the solver may charge\n * up to `notional * rateCap / 1e18` on each side.\n */\nexport interface SolverFeeCaps {\n /** Maximum open-side solver fee, as an 18-decimal ratio of open notional. */\n openRateCap: bigint;\n /** Maximum close-side solver fee, as an 18-decimal ratio of close notional. Immutable after `sendQuote`. */\n closeRateCap: bigint;\n}\n\n/**\n * Margin context passed to `InstantOpenParameters`.\n *\n * The single mark price for the trade lives in `order.price` (wei); it's\n * forwarded into the fake-Muon `upnlSig.price` field by the primitive.\n */\nexport interface InstantOpenMargin {\n /** Total margin amount for `addMarginToNextVA` (wei). */\n amount: bigint;\n}\n"],"mappings":";;AAaA,IAAa,IAAoB,GAWpB,IAAiC;CAC5C,UAAU;CACV,QAAQ;CACR,aAAa;CACb,cAAc;AAChB;AA6BA,SAAgB,EAAqB,GAAyD;CAC5F,OAAO,MAAiB,EAAa,QACjC,EAA+B,eAC/B,EAA+B;AACrC"}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../../../src/solvers/instant-open/shared/types.ts"],"sourcesContent":["import type { Address, Hex } from \"viem\";\nimport type { InstantLayerAccount } from \"../../../symmio-contracts/instant-layer/types\";\nimport { PositionType, type SingleUpnlAndPriceSig } from \"../../../symmio-contracts/symmio/types\";\n\n/**\n * Re-export the canonical trade-side enum (defined in\n * `symmio-contracts/symmio/types.ts`) so the instant-open slice has one place\n * to import it from. Numeric values match the on-chain enum: `LONG = 0`,\n * `SHORT = 1`.\n */\nexport { PositionType };\n\n/** Contract enum value for MARKET orders. */\nexport const ORDER_TYPE_MARKET = 1 as const;\n/** Contract enum value for LIMIT orders (majors / rasa only). */\nexport const ORDER_TYPE_LIMIT = 0 as const;\n/** Requested market or limit order. Close actions resolve the solver's contract order type before signing. */\nexport type SolverOrderType = typeof ORDER_TYPE_MARKET | typeof ORDER_TYPE_LIMIT;\n\n/**\n * Virtual-account isolation type values used by `addMarginToNextVA`.\n *\n * Matches the on-chain `VirtualAccountIsolationType` enum.\n */\nexport const VIRTUAL_ACCOUNT_ISOLATION_TYPE = {\n POSITION: 0,\n MARKET: 1,\n MARKET_LONG: 2,\n MARKET_SHORT: 3,\n} as const;\n\nexport type VirtualAccountIsolationType =\n (typeof VIRTUAL_ACCOUNT_ISOLATION_TYPE)[keyof typeof VIRTUAL_ACCOUNT_ISOLATION_TYPE];\n\n/**\n * Map a trade side to the market-isolation type its Virtual Account is created\n * with. A `SHORT` lands in a `MARKET_SHORT` VA; everything else (i.e. `LONG`)\n * lands in a `MARKET_LONG` VA.\n *\n * This is the side ↔ isolation rule used both when opening (`addMarginToNextVA`)\n * and when predicting a not-yet-created VA's address\n * (`predictNextVirtualAccountAddress`). It lives next to\n * {@link VIRTUAL_ACCOUNT_ISOLATION_TYPE} so callers that only need the side\n * mapping (e.g. the quotes slice) can import it without pulling in the rest of\n * the instant-open flow.\n *\n * @param positionType - The trade side (`LONG` or `SHORT`).\n * @returns The matching {@link VirtualAccountIsolationType}\n * (`MARKET_SHORT` for `SHORT`, otherwise `MARKET_LONG`).\n *\n * @example\n * ```ts\n * isolationTypeForSide(PositionType.SHORT); // VIRTUAL_ACCOUNT_ISOLATION_TYPE.MARKET_SHORT\n * isolationTypeForSide(PositionType.LONG); // VIRTUAL_ACCOUNT_ISOLATION_TYPE.MARKET_LONG\n * ```\n *\n * TODO: what happend if someone have different isolation type than the one we expect? like POSITION or MARKET?\n */\nexport function isolationTypeForSide(positionType: PositionType): VirtualAccountIsolationType {\n return positionType === PositionType.SHORT\n ? VIRTUAL_ACCOUNT_ISOLATION_TYPE.MARKET_SHORT\n : VIRTUAL_ACCOUNT_ISOLATION_TYPE.MARKET_LONG;\n}\n\n/**\n * Muon oracle signature accepted by `sendQuoteWithAffiliateAndData`.\n *\n * For lowcap flows, pass `ZERO_UPNL_SIG` or build a placeholder with\n * `getFakeSendQuoteMuonSignature`. Solvers that enforce Muon verification\n * (Rasa / majors) need a live attestation from `getSendQuoteUpnlSig`.\n *\n * @deprecated Renamed to {@link SingleUpnlAndPriceSig} to match the on-chain\n * struct name. This alias is kept for one release and will be removed in the\n * next major.\n */\nexport type UpnlSig = SingleUpnlAndPriceSig;\n\n/**\n * InstantLayer EIP-712 `ReplayAttackHeader` struct.\n */\nexport interface ReplayAttackHeader {\n /** Operation nonce (`0n` for single-use ops). */\n nonce: bigint;\n /** Unix-seconds deadline. */\n deadline: bigint;\n /** Random 32-byte salt. */\n salt: Hex;\n}\n\n/**\n * InstantLayer EIP-712 `FlexField` struct.\n */\nexport interface FlexField {\n /** Byte offset into `callData`. */\n offset: bigint;\n /** Byte length. */\n length: bigint;\n /** Address authorized to fill this slot. */\n authorizedFlexFiller: Address;\n}\n\n/**\n * InstantLayer EIP-712 `SignedOperation` struct.\n */\nexport interface SignedOperation {\n /** Session-key signer that produces the EIP-712 signature. */\n signer: Address;\n /** Target contract the operation calls. */\n target: Address;\n /** ABI-encoded calldata for the `target` call. */\n callData: Hex;\n /** Account whose authority the operation runs under. */\n signerAccount: InstantLayerAccount;\n /** Flex fields (empty for lowcap flows). */\n flexFields: FlexField[];\n /** Max number of times the operation may be executed. */\n maxUses: bigint;\n /** Replay-attack protection header. */\n replayAttackHeader: ReplayAttackHeader;\n}\n\n/**\n * Wire-format `SignedOperation` accepted by the hedger's `/instant_trade/*` REST API.\n *\n * Re-exports the orval-generated `Eip712SignedOperationJSON` shape; `bigint`s\n * are serialized as decimal strings to survive JSON.\n */\nexport type { Eip712SignedOperationJSON as SignedOperationPayload } from \"../../types/generated/enigma-solver\";\n\n/**\n * Wire-format signed-and-signed-operation pair accepted by the hedger API.\n *\n * Re-exports the orval-generated `Eip712OperationWithSigJSON`.\n */\nexport type { Eip712OperationWithSigJSON as InstantOperationPayload } from \"../../types/generated/enigma-solver\";\n\n/**\n * Locked-margin breakdown passed to `InstantOpenParameters`.\n *\n * All values are 18-decimal-wei `bigint` matching the contract argument order\n * of `sendQuoteWithAffiliateAndData`.\n */\nexport interface InstantOpenLockedParams {\n /** CVA locked margin (wei). */\n cva: bigint;\n /** LF locked margin (wei). */\n lf: bigint;\n /** PartyA maintenance margin (wei). */\n partyAmm: bigint;\n /** PartyB maintenance margin (wei). */\n partyBmm: bigint;\n}\n\n/**\n * Order-side trade values passed to `InstantOpenParameters`.\n *\n * All wei `bigint`s, final values (already through trade math + leverage).\n */\nexport interface InstantOpenOrder {\n /** Requested open price (wei). */\n price: bigint;\n /** Leveraged quantity (wei). */\n quantity: bigint;\n}\n\n/**\n * Market identification + precision metadata used by the wizard.\n *\n * Only `id` is required. `name`, `pricePrecision`, and `quantityPrecision` are\n * pre-fetched overrides; when omitted, the wizard resolves them from solver\n * `/contract-symbols` via `id`.\n */\nexport interface InstantOpenMarketData {\n /** Market `symbol_id` from solver markets. */\n id: number;\n /** Pre-fetched market name. When omitted, resolved from solver markets. */\n name?: string;\n /** Pre-fetched market price precision. When omitted, resolved from solver markets. */\n pricePrecision?: number;\n /** Pre-fetched market quantity precision. When omitted, resolved from solver markets. */\n quantityPrecision?: number;\n /** Pre-fetched `minOpenSolverFeeCap` (decimal ratio string). When omitted, resolved from solver markets. */\n minOpenSolverFeeCap?: string;\n /** Pre-fetched `minCloseSolverFeeCap` (decimal ratio string). When omitted, resolved from solver markets. */\n minCloseSolverFeeCap?: string;\n /** Pre-fetched solver open-fee rate (decimal fraction string). When omitted, resolved from solver markets. */\n hedgerFeeOpen?: string;\n /** Pre-fetched solver close-fee rate (decimal fraction string). When omitted, resolved from solver markets. */\n hedgerFeeClose?: string;\n /**\n * Pre-fetched early (peak) close-fee rate. When omitted on a lowcap (Enigma)\n * solver, resolved from `/symbols`; the open provisions this worst-case rate.\n * Ignored on non-lowcap solvers.\n */\n hedgerFeeCloseEarlyRate?: string;\n /** Pre-fetched early-window length in seconds (paired with `hedgerFeeCloseEarlyRate`). */\n hedgerFeeCloseEarlyThreshold?: number;\n /** Pre-fetched standard-rate threshold in seconds (paired with `hedgerFeeCloseEarlyRate`). */\n hedgerFeeCloseStandardThreshold?: number;\n /**\n * Pre-fetched minimum `lf / (cva + lf + partyAmm)` portion (decimal\n * fraction). Only consulted by full-balance funding, which validates the\n * SDK-sized quantity against the market's quote constraints; when omitted\n * there, resolved from solver markets.\n */\n minAcceptablePortionLf?: string;\n /** Pre-fetched minimum locked-margin sum (decimal string). Full-balance funding only; see `minAcceptablePortionLf`. */\n minAcceptableQuoteValue?: string;\n /** Pre-fetched maximum notional position value; `0` ⇒ unpublished. Full-balance funding only. */\n maxNotionalValue?: number;\n /** Pre-fetched minimum notional position value (decimal string). Full-balance funding only. */\n minNotionalValue?: string;\n /** Pre-fetched maximum order quantity (decimal string); `\"0\"` ⇒ unpublished. Full-balance funding only. */\n maxQuantity?: string;\n /** Pre-fetched minimum tradable increment / lot size (decimal string). Full-balance funding only. */\n lotSize?: string;\n}\n\n/**\n * Solver-fee rate caps authorized on a quote, as 18-decimal fixed-point ratios\n * of quote notional (perps-core v0.8.6 solver fees).\n *\n * Both caps are set immutably at `sendQuote` time — the close-side cap cannot\n * be changed later in `requestToClosePosition`. On-chain the solver may charge\n * up to `notional * rateCap / 1e18` on each side.\n */\nexport interface SolverFeeCaps {\n /** Maximum open-side solver fee, as an 18-decimal ratio of open notional. */\n openRateCap: bigint;\n /** Maximum close-side solver fee, as an 18-decimal ratio of close notional. Immutable after `sendQuote`. */\n closeRateCap: bigint;\n}\n\n/**\n * Margin context passed to `InstantOpenParameters`.\n *\n * The single mark price for the trade lives in `order.price` (wei); it's\n * forwarded into the fake-Muon `upnlSig.price` field by the primitive.\n */\nexport interface InstantOpenMargin {\n /** Total margin amount for `addMarginToNextVA` (wei). */\n amount: bigint;\n}\n"],"mappings":";;AAaA,IAAa,IAAoB,GAWpB,IAAiC;CAC5C,UAAU;CACV,QAAQ;CACR,aAAa;CACb,cAAc;AAChB;AA6BA,SAAgB,EAAqB,GAAyD;CAC5F,OAAO,MAAiB,EAAa,QACjC,EAA+B,eAC/B,EAA+B;AACrC"}
@@ -9,7 +9,9 @@ import { PrepareInstantOpenParameters } from '../instant-open/prepare-instant-op
9
9
  * explicit resting **`price`** instead of a fetched `markPrice` + `slippage`
10
10
  * band — a limit order rests at exactly that price.
11
11
  */
12
- export type PrepareLimitOpenParameters = Compute<Omit<PrepareInstantOpenParameters, "markPrice" | "slippage"> & {
12
+ export type PrepareLimitOpenParameters = Compute<Omit<PrepareInstantOpenParameters, "markPrice" | "slippage" | "initialMargin" | "fund"> & {
13
+ /** Collateral (USD) the user enters as initial margin. Decimal string. */
14
+ initialMargin: string;
13
15
  /** Limit price (decimal string) the order rests at. Set by the user; no slippage is applied. */
14
16
  price: string;
15
17
  }>;