@ouronet/ouronet-core 4.3.6

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 (101) hide show
  1. package/CHANGELOG.md +3043 -0
  2. package/README.md +1940 -0
  3. package/dist/codex/codec.d.ts +77 -0
  4. package/dist/codex/codec.js +123 -0
  5. package/dist/codex/errors.d.ts +14 -0
  6. package/dist/codex/errors.js +20 -0
  7. package/dist/codex/index.d.ts +27 -0
  8. package/dist/codex/index.js +25 -0
  9. package/dist/codex/seedTypeMigration.d.ts +35 -0
  10. package/dist/codex/seedTypeMigration.js +45 -0
  11. package/dist/codex/types.d.ts +100 -0
  12. package/dist/codex/types.js +19 -0
  13. package/dist/constants/index.d.ts +2 -0
  14. package/dist/constants/index.js +3 -0
  15. package/dist/constants/ouronet.d.ts +33 -0
  16. package/dist/constants/ouronet.js +59 -0
  17. package/dist/constants/tokenIds.d.ts +13 -0
  18. package/dist/constants/tokenIds.js +21 -0
  19. package/dist/index.d.ts +18 -0
  20. package/dist/index.js +1 -0
  21. package/dist/interactions/activateFunctions.d.ts +67 -0
  22. package/dist/interactions/activateFunctions.js +154 -0
  23. package/dist/interactions/addLiquidityFunctions.d.ts +140 -0
  24. package/dist/interactions/addLiquidityFunctions.js +485 -0
  25. package/dist/interactions/coilFunctions.d.ts +73 -0
  26. package/dist/interactions/coilFunctions.js +213 -0
  27. package/dist/interactions/crossChainFunctions.d.ts +211 -0
  28. package/dist/interactions/crossChainFunctions.js +463 -0
  29. package/dist/interactions/dexAcquisitionPoolFunctions.d.ts +18 -0
  30. package/dist/interactions/dexAcquisitionPoolFunctions.js +18 -0
  31. package/dist/interactions/dexCollectablesFunctions.d.ts +28 -0
  32. package/dist/interactions/dexCollectablesFunctions.js +227 -0
  33. package/dist/interactions/dexFunctions.d.ts +23 -0
  34. package/dist/interactions/dexFunctions.js +23 -0
  35. package/dist/interactions/dexOrtoFungibleFunctions.d.ts +33 -0
  36. package/dist/interactions/dexOrtoFungibleFunctions.js +171 -0
  37. package/dist/interactions/dexParseFunctions.d.ts +150 -0
  38. package/dist/interactions/dexParseFunctions.js +316 -0
  39. package/dist/interactions/dexSwapPairAdminFunctions.d.ts +75 -0
  40. package/dist/interactions/dexSwapPairAdminFunctions.js +255 -0
  41. package/dist/interactions/dexSwapPairCalcFunctions.d.ts +55 -0
  42. package/dist/interactions/dexSwapPairCalcFunctions.js +218 -0
  43. package/dist/interactions/dexSwapPairDashboardFunctions.d.ts +47 -0
  44. package/dist/interactions/dexSwapPairDashboardFunctions.js +179 -0
  45. package/dist/interactions/dexSwapPairExecuteFunctions.d.ts +40 -0
  46. package/dist/interactions/dexSwapPairExecuteFunctions.js +301 -0
  47. package/dist/interactions/dexSwapPairSmartSwapFunctions.d.ts +25 -0
  48. package/dist/interactions/dexSwapPairSmartSwapFunctions.js +166 -0
  49. package/dist/interactions/dexTrueFungibleFunctions.d.ts +52 -0
  50. package/dist/interactions/dexTrueFungibleFunctions.js +220 -0
  51. package/dist/interactions/dexTypes.d.ts +465 -0
  52. package/dist/interactions/dexTypes.js +6 -0
  53. package/dist/interactions/errors.d.ts +12 -0
  54. package/dist/interactions/errors.js +13 -0
  55. package/dist/interactions/guardFunctions.d.ts +33 -0
  56. package/dist/interactions/guardFunctions.js +110 -0
  57. package/dist/interactions/index.d.ts +1 -0
  58. package/dist/interactions/index.js +20 -0
  59. package/dist/interactions/infoOneFunctions.d.ts +133 -0
  60. package/dist/interactions/infoOneFunctions.js +566 -0
  61. package/dist/interactions/kadenaFunctions.d.ts +11 -0
  62. package/dist/interactions/kadenaFunctions.js +40 -0
  63. package/dist/interactions/kpayFunctions.d.ts +45 -0
  64. package/dist/interactions/kpayFunctions.js +191 -0
  65. package/dist/interactions/ouroAccountFunctions.d.ts +64 -0
  66. package/dist/interactions/ouroAccountFunctions.js +229 -0
  67. package/dist/interactions/ouroBalanceFunctions.d.ts +39 -0
  68. package/dist/interactions/ouroBalanceFunctions.js +100 -0
  69. package/dist/interactions/ouroCoilFunctions.d.ts +33 -0
  70. package/dist/interactions/ouroCoilFunctions.js +190 -0
  71. package/dist/interactions/ouroFunctions.d.ts +23 -0
  72. package/dist/interactions/ouroFunctions.js +23 -0
  73. package/dist/interactions/ouroMovieBoosterFunctions.d.ts +18 -0
  74. package/dist/interactions/ouroMovieBoosterFunctions.js +203 -0
  75. package/dist/interactions/ouroPriceFunctions.d.ts +38 -0
  76. package/dist/interactions/ouroPriceFunctions.js +96 -0
  77. package/dist/interactions/ouroPrimordialsFunctions.d.ts +10 -0
  78. package/dist/interactions/ouroPrimordialsFunctions.js +480 -0
  79. package/dist/interactions/ouroRotateFunctions.d.ts +22 -0
  80. package/dist/interactions/ouroRotateFunctions.js +114 -0
  81. package/dist/interactions/ouroSubCompressFunctions.d.ts +23 -0
  82. package/dist/interactions/ouroSubCompressFunctions.js +191 -0
  83. package/dist/interactions/ouroTransferFunctions.d.ts +14 -0
  84. package/dist/interactions/ouroTransferFunctions.js +87 -0
  85. package/dist/interactions/ouroTypes.d.ts +113 -0
  86. package/dist/interactions/ouroTypes.js +6 -0
  87. package/dist/interactions/ouroUrStoaFunctions.d.ts +16 -0
  88. package/dist/interactions/ouroUrStoaFunctions.js +121 -0
  89. package/dist/interactions/ouroWrapFunctions.d.ts +22 -0
  90. package/dist/interactions/ouroWrapFunctions.js +234 -0
  91. package/dist/interactions/pensionFunctions.d.ts +12 -0
  92. package/dist/interactions/pensionFunctions.js +127 -0
  93. package/dist/interactions/urStoaFunctions.d.ts +104 -0
  94. package/dist/interactions/urStoaFunctions.js +475 -0
  95. package/dist/interactions/wrapFunctions.d.ts +46 -0
  96. package/dist/interactions/wrapFunctions.js +221 -0
  97. package/dist/pact/cfmBuilders.d.ts +807 -0
  98. package/dist/pact/cfmBuilders.js +812 -0
  99. package/dist/pact/index.d.ts +1 -0
  100. package/dist/pact/index.js +10 -0
  101. package/package.json +64 -0
@@ -0,0 +1,485 @@
1
+ import { calculateAutoGasLimit } from "@stoachain/stoa-core/gas";
2
+ import { KADENA_CHAIN_ID, KADENA_NAMESPACE, STOA_AUTONOMIC_OURONETGASSTATION, KADENA_NETWORK, } from "../constants/index.js";
3
+ import { Pact } from "@stoachain/kadena-stoic-legacy/client";
4
+ import { getFailoverClient } from "@stoachain/stoa-core/network";
5
+ import { universalSignTransaction, fromKeypair } from "@stoachain/stoa-core/signing";
6
+ import { mayComeWithDeimal, safeCreationTime } from "@stoachain/stoa-core/pact";
7
+ import { pactRead } from "@stoachain/stoa-core/reads";
8
+ import { getLogger } from "@stoachain/stoa-core/observability";
9
+ /**
10
+ * Generate LiquidityData object for deviation validation
11
+ */
12
+ export async function generateLiquidityData(swpair, input, amounts) {
13
+ try {
14
+ const pactAmounts = `[${amounts.map(amount => {
15
+ const amountStr = amount.toString();
16
+ return amountStr.includes('.') ? amountStr : `${amountStr}.0`;
17
+ }).join(' ')}]`;
18
+ const response = await pactRead(`(${KADENA_NAMESPACE}.SWPL.URC_LD "${swpair}" "${input}" ${pactAmounts})`, { tier: "T2" });
19
+ if (!response || !response.result) {
20
+ throw new Error("Failed to generate liquidity data from the transaction.");
21
+ }
22
+ if (response.result.status === "failure") {
23
+ throw new Error(`Liquidity data generation failed: ${response.result.error?.message || "Unknown error"}`);
24
+ }
25
+ return response.result.data;
26
+ }
27
+ catch (error) {
28
+ getLogger().error("Generate liquidity data failed:", error);
29
+ throw error instanceof Error ? error : new Error("Unknown error occurred");
30
+ }
31
+ }
32
+ /**
33
+ * Validate liquidity deviation
34
+ */
35
+ export async function validateLiquidityDeviation(swpair, liquidityData) {
36
+ try {
37
+ const response = await pactRead(`(${KADENA_NAMESPACE}.SWPL.UEV_Liquidity "${swpair}" ${JSON.stringify(liquidityData)})`, { tier: "T2" });
38
+ if (!response || !response.result) {
39
+ throw new Error("Failed to validate liquidity deviation from the transaction.");
40
+ }
41
+ if (response.result.status === "failure") {
42
+ // This might fail if deviation exceeds max - capture the error for UI
43
+ const errorMessage = response.result.error?.message || "";
44
+ const deviationMatch = errorMessage.match(/(\d+\.?\d*)\s*deviation.*maximum.*?(\d+\.?\d*)/);
45
+ if (deviationMatch) {
46
+ return {
47
+ deviation: parseFloat(deviationMatch[1]),
48
+ maxDeviation: parseFloat(deviationMatch[2]),
49
+ isValid: false
50
+ };
51
+ }
52
+ throw new Error(`Liquidity deviation validation failed: ${errorMessage}`);
53
+ }
54
+ const data = response.result.data;
55
+ // Data should be [dev, max-dev]
56
+ if (Array.isArray(data) && data.length >= 2) {
57
+ const deviation = typeof data[0] === 'object' ? parseFloat(data[0].decimal) : parseFloat(data[0]);
58
+ const maxDeviation = typeof data[1] === 'object' ? parseFloat(data[1].decimal) : parseFloat(data[1]);
59
+ return {
60
+ deviation,
61
+ maxDeviation,
62
+ isValid: deviation <= maxDeviation
63
+ };
64
+ }
65
+ return null;
66
+ }
67
+ catch (error) {
68
+ throw error instanceof Error ? error : new Error("Unknown error occurred");
69
+ }
70
+ }
71
+ /**
72
+ * Calculate balanced liquidity amounts based on one input token
73
+ */
74
+ export async function calculateBalancedLiquidity(swpair, inputTokenId, inputAmount, withValidation = true) {
75
+ try {
76
+ // Format amount for Pact (ensure decimal format)
77
+ const pactAmount = inputAmount.includes('.')
78
+ ? inputAmount
79
+ : `${inputAmount}.0`;
80
+ const pactCode = `(${KADENA_NAMESPACE}.SWPL.URC_BalancedLiquidity "${swpair}" "${inputTokenId}" ${pactAmount} ${withValidation})`;
81
+ const response = await pactRead(pactCode, { tier: "T2" });
82
+ if (!response || !response.result) {
83
+ throw new Error("Failed to calculate balanced liquidity from the transaction.");
84
+ }
85
+ if (response.result.status === "failure") {
86
+ const errorMessage = response.result.error?.message || "Unknown error";
87
+ throw new Error(`Balanced liquidity calculation failed: ${errorMessage}`);
88
+ }
89
+ const data = response.result.data;
90
+ // Parse the result array using mayComeWithDeimal for consistent handling
91
+ let balancedAmounts = [];
92
+ if (Array.isArray(data)) {
93
+ balancedAmounts = data.map(item => mayComeWithDeimal(item));
94
+ }
95
+ else {
96
+ throw new Error("Expected array result from balanced liquidity calculation");
97
+ }
98
+ return balancedAmounts;
99
+ }
100
+ catch (error) {
101
+ throw error instanceof Error ? error : new Error("Balanced liquidity calculation failed");
102
+ }
103
+ }
104
+ /**
105
+ * Check if pool supports special LP types
106
+ */
107
+ export async function getLPTypeInfo(swpair) {
108
+ const [frozenCheck, sleepingCheck] = await Promise.all([
109
+ // Check for Frozen LP support
110
+ (async () => {
111
+ try {
112
+ const response = await pactRead(`(${KADENA_NAMESPACE}.SWP.UR_IzFrozenLP "${swpair}")`, { tier: "T7" });
113
+ return response?.result?.status === "success" ? response.result.data === true : false;
114
+ }
115
+ catch (error) {
116
+ getLogger().error("Error checking Frozen LP:", error);
117
+ return null;
118
+ }
119
+ })(),
120
+ // Check for Sleeping LP support
121
+ (async () => {
122
+ try {
123
+ const response = await pactRead(`(${KADENA_NAMESPACE}.SWP.UR_IzSleepingLP "${swpair}")`, { tier: "T7" });
124
+ return response?.result?.status === "success" ? response.result.data === true : false;
125
+ }
126
+ catch (error) {
127
+ getLogger().error("Error checking Sleeping LP:", error);
128
+ return null;
129
+ }
130
+ })()
131
+ ]);
132
+ return {
133
+ hasFrozenLP: frozenCheck,
134
+ hasSleepingLP: sleepingCheck
135
+ };
136
+ }
137
+ /**
138
+ * @internal
139
+ * Shared liquidity-execution pipeline behind the 5 public wrappers
140
+ * (executeAddLiquiditySingle, executeAddLiquidity, executeSpecialAddLiquidity,
141
+ * executeFuel, executeRemoveLiquidity).
142
+ *
143
+ * Steps:
144
+ * 1. Build a simulation transaction with `defaultGasLimit`.
145
+ * 2. Run dirtyRead; on failure throw with `errorPrefix`.
146
+ * 3. Apply the buffer strategy:
147
+ * - "fixed-5k": always rebuild with `(simulation.gas ?? defaultGasLimit) + 5_000`.
148
+ * - "auto-gas-limit": rebuild only if `simulation.gas > defaultGasLimit`,
149
+ * otherwise reuse the simulation transaction unchanged.
150
+ * 4. Sign with `[kadenaKeypair, guardKeypair]` via universalSignTransaction.
151
+ * 5. Submit and return the result.
152
+ *
153
+ * `patronKeypair` does NOT appear here — it is interpolated into `pactCode` by
154
+ * the wrapper before invocation and never participates in signing.
155
+ */
156
+ async function executeLiquidityOp(opts) {
157
+ const keysetName = `ks`;
158
+ const { defaultGasLimit, bufferStrategy } = opts.gasPolicy;
159
+ const { kadenaKeypair, guardKeypair } = opts.signers;
160
+ const buildTransaction = (gasLimitOverride) => {
161
+ return Pact.builder
162
+ .execution(opts.pactCode)
163
+ .addData(keysetName, {
164
+ keys: [guardKeypair.publicKey],
165
+ pred: "keys-all",
166
+ })
167
+ .setMeta({
168
+ senderAccount: STOA_AUTONOMIC_OURONETGASSTATION,
169
+ creationTime: safeCreationTime(),
170
+ chainId: KADENA_CHAIN_ID,
171
+ gasLimit: gasLimitOverride ?? defaultGasLimit,
172
+ })
173
+ .setNetworkId(KADENA_NETWORK)
174
+ .addSigner(kadenaKeypair.publicKey, (withCapability) => [
175
+ withCapability(`${KADENA_NAMESPACE}.DALOS.GAS_PAYER`, "", { int: 0 }, { decimal: "0.0" }),
176
+ ])
177
+ .addSigner(guardKeypair.publicKey)
178
+ .createTransaction();
179
+ };
180
+ const { dirtyRead, submit } = getFailoverClient(KADENA_CHAIN_ID);
181
+ let transaction = buildTransaction(defaultGasLimit);
182
+ const simulation = await dirtyRead(transaction);
183
+ if (simulation.result.status === "failure") {
184
+ const errorMessage = simulation.result.error?.message || "Transaction simulation failed";
185
+ throw new Error(`${opts.errorPrefix} ${errorMessage}`);
186
+ }
187
+ if (bufferStrategy === "fixed-5k") {
188
+ const actualGasLimit = (simulation.gas || defaultGasLimit) + 5000;
189
+ transaction = buildTransaction(actualGasLimit);
190
+ }
191
+ else {
192
+ const requiredGas = simulation.gas;
193
+ if (requiredGas && requiredGas > defaultGasLimit) {
194
+ transaction = buildTransaction(calculateAutoGasLimit(requiredGas));
195
+ }
196
+ }
197
+ const signedTransaction = await universalSignTransaction(transaction, [
198
+ fromKeypair(kadenaKeypair),
199
+ fromKeypair(guardKeypair),
200
+ ]);
201
+ return await submit(signedTransaction);
202
+ }
203
+ /**
204
+ * Execute single-step add liquidity (TS01-C3 module)
205
+ */
206
+ export async function executeAddLiquiditySingle(params) {
207
+ try {
208
+ const pactInputAmounts = `[${params.inputAmounts.map(amount => {
209
+ const amountStr = typeof amount === 'string' ? amount : String(amount);
210
+ return amountStr.includes('.') ? amountStr : `${amountStr}.0`;
211
+ }).join(' ')}]`;
212
+ const pactCode = `(${KADENA_NAMESPACE}.TS01-C3.SWP|C_AddLiquidity "${params.patronKeypair.address}" "${params.account}" "${params.swpair}" ${pactInputAmounts})`;
213
+ return await executeLiquidityOp({
214
+ pactCode,
215
+ signers: {
216
+ kadenaKeypair: params.kadenaKeypair,
217
+ guardKeypair: params.guardKeypair,
218
+ },
219
+ gasPolicy: {
220
+ defaultGasLimit: params.inputAmounts.length * 100000,
221
+ bufferStrategy: "fixed-5k",
222
+ },
223
+ errorPrefix: "Add liquidity simulation failed:",
224
+ });
225
+ }
226
+ catch (error) {
227
+ throw error instanceof Error ? error : new Error("Unknown error occurred");
228
+ }
229
+ }
230
+ /**
231
+ * Main add liquidity function — single-step with gas simulation.
232
+ *
233
+ * REMOVED IN v3.2.2: the four multi-step execute functions
234
+ * (`executeAddLiquidityMultiStep1`, `executeAddLiquidityMultiStep2`,
235
+ * `executeAddLiquidityMultiStep3`, `executeAddLiquidityMultiStepComplete`)
236
+ * and the `MultiStepAddLiquidityResult` type they returned. The
237
+ * multi-step pipeline existed because the historical Kadena chainweb
238
+ * gas limit (150k per block) couldn't fit a single-block add-liquidity
239
+ * transaction; the consumer had to split into a defpact with two
240
+ * continuation steps. StoaChain's chainweb runs at 2M gas per block
241
+ * (13×), which fits the entire add-liquidity flow in one transaction —
242
+ * so the multi-step path has been dead code in OuronetUI since the
243
+ * gas-limit increase. Removing it closes audit findings F-ERR-005
244
+ * (`error.message.includes` on possibly-undefined retry-loop crashes),
245
+ * F-ERR-014 (listen timeout vs submit failure double-pay risk),
246
+ * F-PERF-014 (4× hardcoded 3-second sleeps), F-PERF-015 (retry-with-
247
+ * fixed-sleep against string-matched error messages), and F-API-026
248
+ * (the `_strategy` parameter on `executeAddLiquidity` was always
249
+ * `"auto"` → single-step path; dead public surface).
250
+ *
251
+ * The Pact-side multi-step contract still exists on chain
252
+ * (`TS01-CP.SWP|C_AddStandardLiquidity` defpact with continuation
253
+ * steps) — preserved for historical interoperability. This package
254
+ * just stops exposing the TypeScript wrappers around it because no
255
+ * consumer needs them any more.
256
+ */
257
+ export async function executeAddLiquidity(params) {
258
+ try {
259
+ return await executeAddLiquiditySingle(params);
260
+ }
261
+ catch (error) {
262
+ getLogger().error("Add Liquidity Error:", error);
263
+ throw error instanceof Error ? error : new Error("Add liquidity execution failed");
264
+ }
265
+ }
266
+ /**
267
+ * Execute special LP type add liquidity (Iced, Glacial, Frozen, Sleeping)
268
+ */
269
+ export async function executeSpecialAddLiquidity(params, specialParams) {
270
+ try {
271
+ const pactInputAmounts = `[${params.inputAmounts.map(amount => {
272
+ const amountStr = typeof amount === 'string' ? amount : String(amount);
273
+ return amountStr.includes('.') ? amountStr : `${amountStr}.0`;
274
+ }).join(' ')}]`;
275
+ let pactCode;
276
+ switch (specialParams.type) {
277
+ case "iced":
278
+ pactCode = `(${KADENA_NAMESPACE}.TS01-CP.SWP|C_AddIcedLiquidity "${params.patronKeypair.address}" "${params.account}" "${params.swpair}" ${pactInputAmounts})`;
279
+ break;
280
+ case "glacial":
281
+ pactCode = `(${KADENA_NAMESPACE}.TS01-CP.SWP|C_AddGlacialLiquidity "${params.patronKeypair.address}" "${params.account}" "${params.swpair}" ${pactInputAmounts})`;
282
+ break;
283
+ case "frozen": {
284
+ if (!specialParams.frozenDptf) {
285
+ throw new Error("frozenDptf parameter required for frozen liquidity");
286
+ }
287
+ // Frozen liquidity uses a single input amount, not the array.
288
+ const frozenAmount = params.inputAmounts[0] || 0;
289
+ const frozenAmountStr = frozenAmount.toString().includes('.') ? frozenAmount.toString() : `${frozenAmount}.0`;
290
+ pactCode = `(${KADENA_NAMESPACE}.TS01-CP.SWP|C_AddFrozenLiquidity "${params.patronKeypair.address}" "${params.account}" "${params.swpair}" "${specialParams.frozenDptf}" ${frozenAmountStr})`;
291
+ break;
292
+ }
293
+ case "sleeping":
294
+ if (!specialParams.sleepingDpmf || specialParams.nonce === undefined) {
295
+ throw new Error("sleepingDpmf and nonce parameters required for sleeping liquidity");
296
+ }
297
+ pactCode = `(${KADENA_NAMESPACE}.TS01-CP.SWP|C_AddSleepingLiquidity "${params.patronKeypair.address}" "${params.account}" "${params.swpair}" "${specialParams.sleepingDpmf}" ${specialParams.nonce})`;
298
+ break;
299
+ default:
300
+ throw new Error(`Unsupported special LP type: ${specialParams.type}`);
301
+ }
302
+ return await executeLiquidityOp({
303
+ pactCode,
304
+ signers: {
305
+ kadenaKeypair: params.kadenaKeypair,
306
+ guardKeypair: params.guardKeypair,
307
+ },
308
+ gasPolicy: {
309
+ defaultGasLimit: 2000000,
310
+ bufferStrategy: "auto-gas-limit",
311
+ },
312
+ errorPrefix: `Add ${specialParams.type} liquidity simulation failed:`,
313
+ });
314
+ }
315
+ catch (error) {
316
+ getLogger().error(`Add ${specialParams.type} Liquidity Error:`, error);
317
+ throw error instanceof Error ? error : new Error("Special add liquidity execution failed");
318
+ }
319
+ }
320
+ // ── Balanced & Asymmetric Liquidity Functions ─────────────────────────────────
321
+ /**
322
+ * URC_BalancedLiquidity — compute balanced amounts for all tokens given one input.
323
+ * Returns decimal[] with balanced values for each pool token.
324
+ */
325
+ export async function getBalancedLiquidity(swpair, inputId, inputAmount, withValidation = false) {
326
+ try {
327
+ const amt = inputAmount.includes(".") ? inputAmount : inputAmount + ".0";
328
+ const pactCode = `(${KADENA_NAMESPACE}.SWPL.URC_BalancedLiquidity "${swpair}" "${inputId}" ${amt} ${withValidation})`;
329
+ const res = await pactRead(pactCode, { tier: "T2" });
330
+ if (!res?.result || res.result.status === "failure")
331
+ return null;
332
+ const data = res.result.data;
333
+ if (!Array.isArray(data))
334
+ return null;
335
+ return data.map((v) => {
336
+ if (typeof v === "object" && v?.decimal)
337
+ return String(v.decimal);
338
+ return String(v);
339
+ });
340
+ }
341
+ catch (e) {
342
+ getLogger().error("getBalancedLiquidity error:", e);
343
+ return null;
344
+ }
345
+ }
346
+ /**
347
+ * URC_SortLiquidity — split input amounts into balanced + asymmetric portions.
348
+ * Returns { balanced: string[], asymmetric: string[] }
349
+ */
350
+ export async function getSortLiquidity(swpair, inputAmounts) {
351
+ try {
352
+ const pactAmounts = `[${inputAmounts.map(a => { const s = String(a); return s.includes(".") ? s : s + ".0"; }).join(" ")}]`;
353
+ const pactCode = `(${KADENA_NAMESPACE}.SWPL.URC_SortLiquidity "${swpair}" ${pactAmounts})`;
354
+ const res = await pactRead(pactCode, { tier: "T2" });
355
+ if (!res?.result || res.result.status === "failure")
356
+ return null;
357
+ const data = res.result.data;
358
+ const parseArr = (arr) => arr.map((v) => typeof v === "object" && v?.decimal ? String(v.decimal) : String(v));
359
+ return {
360
+ balanced: parseArr(data?.balanced ?? []),
361
+ asymmetric: parseArr(data?.asymmetric ?? []),
362
+ };
363
+ }
364
+ catch (e) {
365
+ getLogger().error("getSortLiquidity error:", e);
366
+ return null;
367
+ }
368
+ }
369
+ /**
370
+ * URC_LD — build LiquidityData object from input amounts.
371
+ */
372
+ export async function getLiquidityData(swpair, inputAmounts) {
373
+ try {
374
+ const pactAmounts = `[${inputAmounts.map(a => { const s = String(a); return s.includes(".") ? s : s + ".0"; }).join(" ")}]`;
375
+ const pactCode = `(${KADENA_NAMESPACE}.SWPL.URC_LD "${swpair}" ${pactAmounts})`;
376
+ const res = await pactRead(pactCode, { tier: "T2" });
377
+ if (!res?.result || res.result.status === "failure")
378
+ return null;
379
+ return res.result.data;
380
+ }
381
+ catch (e) {
382
+ getLogger().error("getLiquidityData error:", e);
383
+ return null;
384
+ }
385
+ }
386
+ /**
387
+ * UEV_Liquidity — validate asymmetric liquidity doesn't exceed max deviation.
388
+ * Returns true if valid, false if deviation too high.
389
+ */
390
+ /**
391
+ * Validate asymmetric liquidity deviation.
392
+ * Returns { valid: true, computed: string, max: string } on success,
393
+ * { valid: false } when deviation exceeds limit (chain rejection / validation failure),
394
+ * or { valid: false, error: string } when the read itself throws (RPC failure).
395
+ * Consumers distinguish RPC failure from validation rejection by checking the optional `error` field.
396
+ */
397
+ export async function validateLiquidity(swpair, inputAmounts) {
398
+ try {
399
+ const pactAmounts = `[${inputAmounts.map(a => { const s = String(a || "0"); return s.includes(".") ? s : s + ".0"; }).join(" ")}]`;
400
+ // Try to run UEV_Liquidity — returns [computed_deviation, max_deviation] on success, throws on exceed
401
+ const pactCode = `(let ((ld (${KADENA_NAMESPACE}.SWPL.URC_LD "${swpair}" ${pactAmounts}))) (try [false false] (${KADENA_NAMESPACE}.SWPL.UEV_Liquidity "${swpair}" ld)))`;
402
+ const res = await pactRead(pactCode, { tier: "T2" });
403
+ if (!res?.result || res.result.status === "failure")
404
+ return { valid: false };
405
+ const data = res.result.data;
406
+ // If try caught the error, data = [false, false]
407
+ if (Array.isArray(data) && data[0] === false)
408
+ return { valid: false };
409
+ // Success: data = [computed_deviation, max_deviation]
410
+ if (Array.isArray(data) && data.length >= 2) {
411
+ const parseVal = (v) => typeof v === "object" && v?.decimal ? String(v.decimal) : String(v);
412
+ return { valid: true, computed: parseVal(data[0]), max: parseVal(data[1]) };
413
+ }
414
+ return { valid: true };
415
+ }
416
+ catch (error) {
417
+ getLogger().error("Error in validateLiquidity:", error);
418
+ return { valid: false, error: error instanceof Error ? error.message : String(error) };
419
+ }
420
+ }
421
+ /**
422
+ * Execute Fuel — transfer tokens into pool without receiving LP.
423
+ * (ouronet-ns.TS01-C3.SWP|C_Fuel patron account swpair input-amounts)
424
+ */
425
+ export async function executeFuel(params) {
426
+ try {
427
+ const pactInputAmounts = `[${params.inputAmounts.map(amount => {
428
+ const amountStr = typeof amount === 'string' ? amount : String(amount);
429
+ return amountStr.includes('.') ? amountStr : `${amountStr}.0`;
430
+ }).join(' ')}]`;
431
+ const pactCode = `(${KADENA_NAMESPACE}.TS01-C3.SWP|C_Fuel "${params.patronKeypair.address}" "${params.account}" "${params.swpair}" ${pactInputAmounts})`;
432
+ return await executeLiquidityOp({
433
+ pactCode,
434
+ signers: {
435
+ kadenaKeypair: params.kadenaKeypair,
436
+ guardKeypair: params.guardKeypair,
437
+ },
438
+ gasPolicy: {
439
+ defaultGasLimit: params.inputAmounts.length * 100000,
440
+ bufferStrategy: "fixed-5k",
441
+ },
442
+ errorPrefix: "Fuel simulation failed:",
443
+ });
444
+ }
445
+ catch (error) {
446
+ throw error instanceof Error ? error : new Error("Fuel execution failed");
447
+ }
448
+ }
449
+ /**
450
+ * Execute Remove Liquidity (Unfold) — burn LP tokens to recover underlying pool tokens.
451
+ * (ouronet-ns.TS01-C3.SWP|C_RemoveLiquidity patron account swpair lp-amount)
452
+ */
453
+ export async function executeRemoveLiquidity(params) {
454
+ try {
455
+ const decLpAmount = params.lpAmount.includes(".") ? params.lpAmount : params.lpAmount + ".0";
456
+ const pactCode = `(${KADENA_NAMESPACE}.TS01-C3.SWP|C_RemoveLiquidity "${params.patronKeypair.address}" "${params.account}" "${params.swpair}" ${decLpAmount})`;
457
+ // Inline `secretKey` is the legacy field name; `IKadenaKeypair` (the
458
+ // executor's signer-type contract) uses `privateKey`. Explicit field-name
459
+ // conversion is preferred over `as IKadenaKeypair` casts because TypeScript
460
+ // rejects narrow casts between structurally-distinct types — and a double
461
+ // `as unknown as IKadenaKeypair` would erase the type-safety guard. Both
462
+ // compile to identical runtime values.
463
+ return await executeLiquidityOp({
464
+ pactCode,
465
+ signers: {
466
+ kadenaKeypair: {
467
+ publicKey: params.kadenaKeypair.publicKey,
468
+ privateKey: params.kadenaKeypair.secretKey,
469
+ },
470
+ guardKeypair: {
471
+ publicKey: params.guardKeypair.publicKey,
472
+ privateKey: params.guardKeypair.secretKey,
473
+ },
474
+ },
475
+ gasPolicy: {
476
+ defaultGasLimit: 200000,
477
+ bufferStrategy: "fixed-5k",
478
+ },
479
+ errorPrefix: "Remove liquidity simulation failed:",
480
+ });
481
+ }
482
+ catch (error) {
483
+ throw error instanceof Error ? error : new Error("Remove liquidity execution failed");
484
+ }
485
+ }
@@ -0,0 +1,73 @@
1
+ import type { IKadenaKeypair } from "@stoachain/stoa-core/signing";
2
+ export type { IKadenaKeypair } from "@stoachain/stoa-core/signing";
3
+ import type { IOuroAccountKeypair } from "./ouroTypes.js";
4
+ export interface CoilConfig {
5
+ atsPair: string;
6
+ sourceToken: string;
7
+ targetToken: string;
8
+ previewCommand: string;
9
+ }
10
+ export declare const COIL_CONFIGS: {
11
+ readonly ouroToAuryn: {
12
+ readonly atsPair: "Auryndex-O136CBn22ncY";
13
+ readonly sourceToken: "OURO-8Nh-JO8JO4F5";
14
+ readonly targetToken: "AURYN-8Nh-JO8JO4F5";
15
+ readonly previewCommand: "Auryndex-O136CBn22ncY";
16
+ };
17
+ readonly aurynToElite: {
18
+ readonly atsPair: "EliteAuryndex-O136CBn22ncY";
19
+ readonly sourceToken: "AURYN-8Nh-JO8JO4F5";
20
+ readonly targetToken: "ELITEAURYN-8Nh-JO8JO4F5";
21
+ readonly previewCommand: "EliteAuryndex-O136CBn22ncY";
22
+ };
23
+ readonly wkdaToLkda: {
24
+ readonly atsPair: "SilverStoaPillar-O136CBn22ncY";
25
+ readonly sourceToken: "WSTOA-8Nh-JO8JO4F5";
26
+ readonly targetToken: "SSTOA-8Nh-JO8JO4F5";
27
+ readonly previewCommand: "SilverStoaPillar-O136CBn22ncY";
28
+ };
29
+ };
30
+ export declare function getCoilPreviewGeneric(amount: string, config: CoilConfig): Promise<{
31
+ targetAmount: number;
32
+ fee: number;
33
+ kadenaInfo: {
34
+ text: string;
35
+ discount: number;
36
+ full: number;
37
+ need: number;
38
+ };
39
+ }>;
40
+ export declare function coilTokensGeneric(ouroAccount: IOuroAccountKeypair, kadenaAccount: IKadenaKeypair, guard: IKadenaKeypair, targetAccount: string, amount: string, config: CoilConfig): Promise<import("@stoachain/kadena-stoic-legacy/client").ITransactionDescriptor>;
41
+ export declare function getCoilPreview(ouroAmount: string): Promise<{
42
+ auryn: number;
43
+ fee: number;
44
+ kadenaInfo: {
45
+ text: string;
46
+ discount: number;
47
+ full: number;
48
+ need: number;
49
+ };
50
+ }>;
51
+ export declare function coilOuroToAuryn(ouroAccount: IOuroAccountKeypair, kadenaAccount: IKadenaKeypair, guard: IKadenaKeypair, targetAccount: string, ouroAmount: string): Promise<import("@stoachain/kadena-stoic-legacy/client").ITransactionDescriptor>;
52
+ export declare function getAurynCoilPreview(aurynAmount: string): Promise<{
53
+ eliteAuryn: number;
54
+ fee: number;
55
+ kadenaInfo: {
56
+ text: string;
57
+ discount: number;
58
+ full: number;
59
+ need: number;
60
+ };
61
+ }>;
62
+ export declare function coilAurynToElite(ouroAccount: IOuroAccountKeypair, kadenaAccount: IKadenaKeypair, guard: IKadenaKeypair, targetAccount: string, aurynAmount: string): Promise<import("@stoachain/kadena-stoic-legacy/client").ITransactionDescriptor>;
63
+ export declare function getWkdaCoilPreview(wkdaAmount: string): Promise<{
64
+ lkda: number;
65
+ fee: number;
66
+ kadenaInfo: {
67
+ text: string;
68
+ discount: number;
69
+ full: number;
70
+ need: number;
71
+ };
72
+ }>;
73
+ export declare function coilWkdaToLkda(ouroAccount: IOuroAccountKeypair, kadenaAccount: IKadenaKeypair, guard: IKadenaKeypair, targetAccount: string, wkdaAmount: string): Promise<import("@stoachain/kadena-stoic-legacy/client").ITransactionDescriptor>;