@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.
- package/CHANGELOG.md +3043 -0
- package/README.md +1940 -0
- package/dist/codex/codec.d.ts +77 -0
- package/dist/codex/codec.js +123 -0
- package/dist/codex/errors.d.ts +14 -0
- package/dist/codex/errors.js +20 -0
- package/dist/codex/index.d.ts +27 -0
- package/dist/codex/index.js +25 -0
- package/dist/codex/seedTypeMigration.d.ts +35 -0
- package/dist/codex/seedTypeMigration.js +45 -0
- package/dist/codex/types.d.ts +100 -0
- package/dist/codex/types.js +19 -0
- package/dist/constants/index.d.ts +2 -0
- package/dist/constants/index.js +3 -0
- package/dist/constants/ouronet.d.ts +33 -0
- package/dist/constants/ouronet.js +59 -0
- package/dist/constants/tokenIds.d.ts +13 -0
- package/dist/constants/tokenIds.js +21 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +1 -0
- package/dist/interactions/activateFunctions.d.ts +67 -0
- package/dist/interactions/activateFunctions.js +154 -0
- package/dist/interactions/addLiquidityFunctions.d.ts +140 -0
- package/dist/interactions/addLiquidityFunctions.js +485 -0
- package/dist/interactions/coilFunctions.d.ts +73 -0
- package/dist/interactions/coilFunctions.js +213 -0
- package/dist/interactions/crossChainFunctions.d.ts +211 -0
- package/dist/interactions/crossChainFunctions.js +463 -0
- package/dist/interactions/dexAcquisitionPoolFunctions.d.ts +18 -0
- package/dist/interactions/dexAcquisitionPoolFunctions.js +18 -0
- package/dist/interactions/dexCollectablesFunctions.d.ts +28 -0
- package/dist/interactions/dexCollectablesFunctions.js +227 -0
- package/dist/interactions/dexFunctions.d.ts +23 -0
- package/dist/interactions/dexFunctions.js +23 -0
- package/dist/interactions/dexOrtoFungibleFunctions.d.ts +33 -0
- package/dist/interactions/dexOrtoFungibleFunctions.js +171 -0
- package/dist/interactions/dexParseFunctions.d.ts +150 -0
- package/dist/interactions/dexParseFunctions.js +316 -0
- package/dist/interactions/dexSwapPairAdminFunctions.d.ts +75 -0
- package/dist/interactions/dexSwapPairAdminFunctions.js +255 -0
- package/dist/interactions/dexSwapPairCalcFunctions.d.ts +55 -0
- package/dist/interactions/dexSwapPairCalcFunctions.js +218 -0
- package/dist/interactions/dexSwapPairDashboardFunctions.d.ts +47 -0
- package/dist/interactions/dexSwapPairDashboardFunctions.js +179 -0
- package/dist/interactions/dexSwapPairExecuteFunctions.d.ts +40 -0
- package/dist/interactions/dexSwapPairExecuteFunctions.js +301 -0
- package/dist/interactions/dexSwapPairSmartSwapFunctions.d.ts +25 -0
- package/dist/interactions/dexSwapPairSmartSwapFunctions.js +166 -0
- package/dist/interactions/dexTrueFungibleFunctions.d.ts +52 -0
- package/dist/interactions/dexTrueFungibleFunctions.js +220 -0
- package/dist/interactions/dexTypes.d.ts +465 -0
- package/dist/interactions/dexTypes.js +6 -0
- package/dist/interactions/errors.d.ts +12 -0
- package/dist/interactions/errors.js +13 -0
- package/dist/interactions/guardFunctions.d.ts +33 -0
- package/dist/interactions/guardFunctions.js +110 -0
- package/dist/interactions/index.d.ts +1 -0
- package/dist/interactions/index.js +20 -0
- package/dist/interactions/infoOneFunctions.d.ts +133 -0
- package/dist/interactions/infoOneFunctions.js +566 -0
- package/dist/interactions/kadenaFunctions.d.ts +11 -0
- package/dist/interactions/kadenaFunctions.js +40 -0
- package/dist/interactions/kpayFunctions.d.ts +45 -0
- package/dist/interactions/kpayFunctions.js +191 -0
- package/dist/interactions/ouroAccountFunctions.d.ts +64 -0
- package/dist/interactions/ouroAccountFunctions.js +229 -0
- package/dist/interactions/ouroBalanceFunctions.d.ts +39 -0
- package/dist/interactions/ouroBalanceFunctions.js +100 -0
- package/dist/interactions/ouroCoilFunctions.d.ts +33 -0
- package/dist/interactions/ouroCoilFunctions.js +190 -0
- package/dist/interactions/ouroFunctions.d.ts +23 -0
- package/dist/interactions/ouroFunctions.js +23 -0
- package/dist/interactions/ouroMovieBoosterFunctions.d.ts +18 -0
- package/dist/interactions/ouroMovieBoosterFunctions.js +203 -0
- package/dist/interactions/ouroPriceFunctions.d.ts +38 -0
- package/dist/interactions/ouroPriceFunctions.js +96 -0
- package/dist/interactions/ouroPrimordialsFunctions.d.ts +10 -0
- package/dist/interactions/ouroPrimordialsFunctions.js +480 -0
- package/dist/interactions/ouroRotateFunctions.d.ts +22 -0
- package/dist/interactions/ouroRotateFunctions.js +114 -0
- package/dist/interactions/ouroSubCompressFunctions.d.ts +23 -0
- package/dist/interactions/ouroSubCompressFunctions.js +191 -0
- package/dist/interactions/ouroTransferFunctions.d.ts +14 -0
- package/dist/interactions/ouroTransferFunctions.js +87 -0
- package/dist/interactions/ouroTypes.d.ts +113 -0
- package/dist/interactions/ouroTypes.js +6 -0
- package/dist/interactions/ouroUrStoaFunctions.d.ts +16 -0
- package/dist/interactions/ouroUrStoaFunctions.js +121 -0
- package/dist/interactions/ouroWrapFunctions.d.ts +22 -0
- package/dist/interactions/ouroWrapFunctions.js +234 -0
- package/dist/interactions/pensionFunctions.d.ts +12 -0
- package/dist/interactions/pensionFunctions.js +127 -0
- package/dist/interactions/urStoaFunctions.d.ts +104 -0
- package/dist/interactions/urStoaFunctions.js +475 -0
- package/dist/interactions/wrapFunctions.d.ts +46 -0
- package/dist/interactions/wrapFunctions.js +221 -0
- package/dist/pact/cfmBuilders.d.ts +807 -0
- package/dist/pact/cfmBuilders.js +812 -0
- package/dist/pact/index.d.ts +1 -0
- package/dist/pact/index.js +10 -0
- 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>;
|