@vultisig/core-chain 1.0.0 → 1.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.
- package/CHANGELOG.md +52 -0
- package/dist/amount/toChainAmount.d.ts +6 -1
- package/dist/amount/toChainAmount.d.ts.map +1 -1
- package/dist/amount/toChainAmount.js +88 -0
- package/dist/amount/toChainAmount.js.map +1 -1
- package/dist/chains/cardano/asset/cardanoAssetId.d.ts +14 -0
- package/dist/chains/cardano/asset/cardanoAssetId.d.ts.map +1 -0
- package/dist/chains/cardano/asset/cardanoAssetId.js +19 -0
- package/dist/chains/cardano/asset/cardanoAssetId.js.map +1 -0
- package/dist/chains/cardano/client/getCardanoAddressAssets.d.ts +10 -0
- package/dist/chains/cardano/client/getCardanoAddressAssets.d.ts.map +1 -0
- package/dist/chains/cardano/client/getCardanoAddressAssets.js +19 -0
- package/dist/chains/cardano/client/getCardanoAddressAssets.js.map +1 -0
- package/dist/chains/cardano/client/getCardanoAssetInfo.d.ts +23 -0
- package/dist/chains/cardano/client/getCardanoAssetInfo.d.ts.map +1 -0
- package/dist/chains/cardano/client/getCardanoAssetInfo.js +16 -0
- package/dist/chains/cardano/client/getCardanoAssetInfo.js.map +1 -0
- package/dist/chains/cardano/utxo/getCardanoExtendedUtxos.d.ts +20 -0
- package/dist/chains/cardano/utxo/getCardanoExtendedUtxos.d.ts.map +1 -0
- package/dist/chains/cardano/utxo/getCardanoExtendedUtxos.js +22 -0
- package/dist/chains/cardano/utxo/getCardanoExtendedUtxos.js.map +1 -0
- package/dist/chains/cosmos/computeCosmosTxReceiptFeeAmount.d.ts +14 -0
- package/dist/chains/cosmos/computeCosmosTxReceiptFeeAmount.d.ts.map +1 -0
- package/dist/chains/cosmos/computeCosmosTxReceiptFeeAmount.js +28 -0
- package/dist/chains/cosmos/computeCosmosTxReceiptFeeAmount.js.map +1 -0
- package/dist/chains/cosmos/qbtc/claim/BtcAddressType.d.ts +7 -0
- package/dist/chains/cosmos/qbtc/claim/BtcAddressType.d.ts.map +1 -0
- package/dist/chains/cosmos/qbtc/claim/BtcAddressType.js +9 -0
- package/dist/chains/cosmos/qbtc/claim/BtcAddressType.js.map +1 -0
- package/dist/chains/cosmos/qbtc/claim/ClaimableUtxo.d.ts +8 -0
- package/dist/chains/cosmos/qbtc/claim/ClaimableUtxo.d.ts.map +1 -0
- package/dist/chains/cosmos/qbtc/claim/ClaimableUtxo.js +2 -0
- package/dist/chains/cosmos/qbtc/claim/ClaimableUtxo.js.map +1 -0
- package/dist/chains/cosmos/qbtc/claim/broadcastClaimTx.d.ts +25 -0
- package/dist/chains/cosmos/qbtc/claim/broadcastClaimTx.d.ts.map +1 -0
- package/dist/chains/cosmos/qbtc/claim/broadcastClaimTx.js +43 -0
- package/dist/chains/cosmos/qbtc/claim/broadcastClaimTx.js.map +1 -0
- package/dist/chains/cosmos/qbtc/claim/buildClaimTx.d.ts +26 -0
- package/dist/chains/cosmos/qbtc/claim/buildClaimTx.d.ts.map +1 -0
- package/dist/chains/cosmos/qbtc/claim/buildClaimTx.js +57 -0
- package/dist/chains/cosmos/qbtc/claim/buildClaimTx.js.map +1 -0
- package/dist/chains/cosmos/qbtc/claim/computeClaimHashes.d.ts +49 -0
- package/dist/chains/cosmos/qbtc/claim/computeClaimHashes.d.ts.map +1 -0
- package/dist/chains/cosmos/qbtc/claim/computeClaimHashes.js +85 -0
- package/dist/chains/cosmos/qbtc/claim/computeClaimHashes.js.map +1 -0
- package/dist/chains/cosmos/qbtc/claim/detectBtcAddressType.d.ts +14 -0
- package/dist/chains/cosmos/qbtc/claim/detectBtcAddressType.d.ts.map +1 -0
- package/dist/chains/cosmos/qbtc/claim/detectBtcAddressType.js +31 -0
- package/dist/chains/cosmos/qbtc/claim/detectBtcAddressType.js.map +1 -0
- package/dist/chains/cosmos/qbtc/claim/getClaimWithProofDisabled.d.ts +3 -0
- package/dist/chains/cosmos/qbtc/claim/getClaimWithProofDisabled.d.ts.map +1 -0
- package/dist/chains/cosmos/qbtc/claim/getClaimWithProofDisabled.js +13 -0
- package/dist/chains/cosmos/qbtc/claim/getClaimWithProofDisabled.js.map +1 -0
- package/dist/chains/cosmos/qbtc/claim/getClaimableUtxos.d.ts +14 -0
- package/dist/chains/cosmos/qbtc/claim/getClaimableUtxos.d.ts.map +1 -0
- package/dist/chains/cosmos/qbtc/claim/getClaimableUtxos.js +22 -0
- package/dist/chains/cosmos/qbtc/claim/getClaimableUtxos.js.map +1 -0
- package/dist/chains/cosmos/qbtc/claim/proofService.d.ts +50 -0
- package/dist/chains/cosmos/qbtc/claim/proofService.d.ts.map +1 -0
- package/dist/chains/cosmos/qbtc/claim/proofService.js +71 -0
- package/dist/chains/cosmos/qbtc/claim/proofService.js.map +1 -0
- package/dist/chains/cosmos/qbtc/getQbtcAccountInfo.d.ts +1 -2
- package/dist/chains/cosmos/qbtc/getQbtcAccountInfo.d.ts.map +1 -1
- package/dist/chains/cosmos/qbtc/getQbtcAccountInfo.js +13 -9
- package/dist/chains/cosmos/qbtc/getQbtcAccountInfo.js.map +1 -1
- package/dist/chains/cosmos/qbtc/tendermintRpcUrl.d.ts +3 -5
- package/dist/chains/cosmos/qbtc/tendermintRpcUrl.d.ts.map +1 -1
- package/dist/chains/cosmos/qbtc/tendermintRpcUrl.js +3 -5
- package/dist/chains/cosmos/qbtc/tendermintRpcUrl.js.map +1 -1
- package/dist/chains/cosmos/sumFeeAmountForCosmosChainFeeDenom.d.ts +15 -0
- package/dist/chains/cosmos/sumFeeAmountForCosmosChainFeeDenom.d.ts.map +1 -0
- package/dist/chains/cosmos/sumFeeAmountForCosmosChainFeeDenom.js +22 -0
- package/dist/chains/cosmos/sumFeeAmountForCosmosChainFeeDenom.js.map +1 -0
- package/dist/chains/cosmos/thor/lp/halts.d.ts +56 -0
- package/dist/chains/cosmos/thor/lp/halts.d.ts.map +1 -0
- package/dist/chains/cosmos/thor/lp/halts.js +95 -0
- package/dist/chains/cosmos/thor/lp/halts.js.map +1 -0
- package/dist/chains/cosmos/thor/lp/index.d.ts +45 -0
- package/dist/chains/cosmos/thor/lp/index.d.ts.map +1 -0
- package/dist/chains/cosmos/thor/lp/index.js +12 -0
- package/dist/chains/cosmos/thor/lp/index.js.map +1 -0
- package/dist/chains/cosmos/thor/lp/lockup.d.ts +47 -0
- package/dist/chains/cosmos/thor/lp/lockup.d.ts.map +1 -0
- package/dist/chains/cosmos/thor/lp/lockup.js +56 -0
- package/dist/chains/cosmos/thor/lp/lockup.js.map +1 -0
- package/dist/chains/cosmos/thor/lp/lpChainMap.d.ts +25 -0
- package/dist/chains/cosmos/thor/lp/lpChainMap.d.ts.map +1 -0
- package/dist/chains/cosmos/thor/lp/lpChainMap.js +30 -0
- package/dist/chains/cosmos/thor/lp/lpChainMap.js.map +1 -0
- package/dist/chains/cosmos/thor/lp/math.d.ts +129 -0
- package/dist/chains/cosmos/thor/lp/math.d.ts.map +1 -0
- package/dist/chains/cosmos/thor/lp/math.js +227 -0
- package/dist/chains/cosmos/thor/lp/math.js.map +1 -0
- package/dist/chains/cosmos/thor/lp/memberPool.d.ts +4 -0
- package/dist/chains/cosmos/thor/lp/memberPool.d.ts.map +1 -0
- package/dist/chains/cosmos/thor/lp/memberPool.js +24 -0
- package/dist/chains/cosmos/thor/lp/memberPool.js.map +1 -0
- package/dist/chains/cosmos/thor/lp/memo.d.ts +62 -0
- package/dist/chains/cosmos/thor/lp/memo.d.ts.map +1 -0
- package/dist/chains/cosmos/thor/lp/memo.js +62 -0
- package/dist/chains/cosmos/thor/lp/memo.js.map +1 -0
- package/dist/chains/cosmos/thor/lp/pairing.d.ts +30 -0
- package/dist/chains/cosmos/thor/lp/pairing.d.ts.map +1 -0
- package/dist/chains/cosmos/thor/lp/pairing.js +44 -0
- package/dist/chains/cosmos/thor/lp/pairing.js.map +1 -0
- package/dist/chains/cosmos/thor/lp/payload.d.ts +66 -0
- package/dist/chains/cosmos/thor/lp/payload.d.ts.map +1 -0
- package/dist/chains/cosmos/thor/lp/payload.js +49 -0
- package/dist/chains/cosmos/thor/lp/payload.js.map +1 -0
- package/dist/chains/cosmos/thor/lp/pools.d.ts +46 -0
- package/dist/chains/cosmos/thor/lp/pools.d.ts.map +1 -0
- package/dist/chains/cosmos/thor/lp/pools.js +85 -0
- package/dist/chains/cosmos/thor/lp/pools.js.map +1 -0
- package/dist/chains/cosmos/thor/lp/position.d.ts +23 -0
- package/dist/chains/cosmos/thor/lp/position.d.ts.map +1 -0
- package/dist/chains/cosmos/thor/lp/position.js +105 -0
- package/dist/chains/cosmos/thor/lp/position.js.map +1 -0
- package/dist/chains/cosmos/thor/lp/positions.d.ts +15 -0
- package/dist/chains/cosmos/thor/lp/positions.d.ts.map +1 -0
- package/dist/chains/cosmos/thor/lp/positions.js +47 -0
- package/dist/chains/cosmos/thor/lp/positions.js.map +1 -0
- package/dist/chains/cosmos/thor/lp/types.d.ts +45 -0
- package/dist/chains/cosmos/thor/lp/types.d.ts.map +1 -0
- package/dist/chains/cosmos/thor/lp/types.js +2 -0
- package/dist/chains/cosmos/thor/lp/types.js.map +1 -0
- package/dist/chains/cosmos/thor/lp/validation.d.ts +38 -0
- package/dist/chains/cosmos/thor/lp/validation.d.ts.map +1 -0
- package/dist/chains/cosmos/thor/lp/validation.js +100 -0
- package/dist/chains/cosmos/thor/lp/validation.js.map +1 -0
- package/dist/chains/polkadot/dapp/PolkadotSignerPayload.d.ts +16 -0
- package/dist/chains/polkadot/dapp/PolkadotSignerPayload.d.ts.map +1 -0
- package/dist/chains/polkadot/dapp/PolkadotSignerPayload.js +2 -0
- package/dist/chains/polkadot/dapp/PolkadotSignerPayload.js.map +1 -0
- package/dist/chains/polkadot/dapp/constructSigningPayload.d.ts +12 -0
- package/dist/chains/polkadot/dapp/constructSigningPayload.d.ts.map +1 -0
- package/dist/chains/polkadot/dapp/constructSigningPayload.js +30 -0
- package/dist/chains/polkadot/dapp/constructSigningPayload.js.map +1 -0
- package/dist/chains/solana/getDynamicPriorityFeePrice.d.ts +3 -0
- package/dist/chains/solana/getDynamicPriorityFeePrice.d.ts.map +1 -0
- package/dist/chains/solana/getDynamicPriorityFeePrice.js +20 -0
- package/dist/chains/solana/getDynamicPriorityFeePrice.js.map +1 -0
- package/dist/chains/solana/jito.d.ts +6 -0
- package/dist/chains/solana/jito.d.ts.map +1 -0
- package/dist/chains/solana/jito.js +40 -0
- package/dist/chains/solana/jito.js.map +1 -0
- package/dist/chains/ton/address.d.ts +6 -0
- package/dist/chains/ton/address.d.ts.map +1 -0
- package/dist/chains/ton/address.js +17 -0
- package/dist/chains/ton/address.js.map +1 -0
- package/dist/chains/ton/api.d.ts +7 -2
- package/dist/chains/ton/api.d.ts.map +1 -1
- package/dist/chains/ton/api.js +16 -3
- package/dist/chains/ton/api.js.map +1 -1
- package/dist/chains/utxo/client/getDashUtxos.d.ts +3 -0
- package/dist/chains/utxo/client/getDashUtxos.d.ts.map +1 -0
- package/dist/chains/utxo/client/getDashUtxos.js +28 -0
- package/dist/chains/utxo/client/getDashUtxos.js.map +1 -0
- package/dist/chains/utxo/tx/buildSignBitcoinFromPsbt.d.ts +21 -0
- package/dist/chains/utxo/tx/buildSignBitcoinFromPsbt.d.ts.map +1 -0
- package/dist/chains/utxo/tx/buildSignBitcoinFromPsbt.js +182 -0
- package/dist/chains/utxo/tx/buildSignBitcoinFromPsbt.js.map +1 -0
- package/dist/chains/utxo/tx/getPsbtTransferInfo.js +1 -1
- package/dist/chains/utxo/tx/getPsbtTransferInfo.js.map +1 -1
- package/dist/chains/utxo/tx/getUtxos.d.ts.map +1 -1
- package/dist/chains/utxo/tx/getUtxos.js +5 -0
- package/dist/chains/utxo/tx/getUtxos.js.map +1 -1
- package/dist/coin/balance/resolvers/cardano.d.ts +1 -0
- package/dist/coin/balance/resolvers/cardano.d.ts.map +1 -1
- package/dist/coin/balance/resolvers/cardano.js +12 -0
- package/dist/coin/balance/resolvers/cardano.js.map +1 -1
- package/dist/coin/balance/resolvers/qbtc.d.ts.map +1 -1
- package/dist/coin/balance/resolvers/qbtc.js +6 -5
- package/dist/coin/balance/resolvers/qbtc.js.map +1 -1
- package/dist/coin/balance/resolvers/sui.d.ts.map +1 -1
- package/dist/coin/balance/resolvers/sui.js +1 -0
- package/dist/coin/balance/resolvers/sui.js.map +1 -1
- package/dist/coin/balance/resolvers/ton.d.ts.map +1 -1
- package/dist/coin/balance/resolvers/ton.js +11 -2
- package/dist/coin/balance/resolvers/ton.js.map +1 -1
- package/dist/coin/find/CoinFinderChainKind.d.ts +1 -1
- package/dist/coin/find/CoinFinderChainKind.d.ts.map +1 -1
- package/dist/coin/find/CoinFinderChainKind.js +1 -1
- package/dist/coin/find/CoinFinderChainKind.js.map +1 -1
- package/dist/coin/find/index.d.ts.map +1 -1
- package/dist/coin/find/index.js +2 -0
- package/dist/coin/find/index.js.map +1 -1
- package/dist/coin/find/resolvers/cardano.d.ts +5 -0
- package/dist/coin/find/resolvers/cardano.d.ts.map +1 -0
- package/dist/coin/find/resolvers/cardano.js +17 -0
- package/dist/coin/find/resolvers/cardano.js.map +1 -0
- package/dist/coin/knownTokens/index.d.ts.map +1 -1
- package/dist/coin/knownTokens/index.js +74 -0
- package/dist/coin/knownTokens/index.js.map +1 -1
- package/dist/coin/token/metadata/chains.d.ts +1 -1
- package/dist/coin/token/metadata/chains.d.ts.map +1 -1
- package/dist/coin/token/metadata/chains.js +1 -0
- package/dist/coin/token/metadata/chains.js.map +1 -1
- package/dist/coin/token/metadata/index.d.ts.map +1 -1
- package/dist/coin/token/metadata/index.js +2 -0
- package/dist/coin/token/metadata/index.js.map +1 -1
- package/dist/coin/token/metadata/resolvers/cardano.d.ts +8 -0
- package/dist/coin/token/metadata/resolvers/cardano.d.ts.map +1 -0
- package/dist/coin/token/metadata/resolvers/cardano.js +20 -0
- package/dist/coin/token/metadata/resolvers/cardano.js.map +1 -0
- package/dist/swap/native/utils/getNativeSwapDecimals.d.ts +8 -0
- package/dist/swap/native/utils/getNativeSwapDecimals.d.ts.map +1 -1
- package/dist/swap/native/utils/getNativeSwapDecimals.js +19 -4
- package/dist/swap/native/utils/getNativeSwapDecimals.js.map +1 -1
- package/dist/tx/broadcast/resolvers/qbtc.d.ts.map +1 -1
- package/dist/tx/broadcast/resolvers/qbtc.js +22 -5
- package/dist/tx/broadcast/resolvers/qbtc.js.map +1 -1
- package/dist/tx/broadcast/resolvers/solana.d.ts.map +1 -1
- package/dist/tx/broadcast/resolvers/solana.js +12 -1
- package/dist/tx/broadcast/resolvers/solana.js.map +1 -1
- package/dist/tx/hash/resolvers/cardano.d.ts.map +1 -1
- package/dist/tx/hash/resolvers/cardano.js +9 -5
- package/dist/tx/hash/resolvers/cardano.js.map +1 -1
- package/dist/tx/status/resolvers/cosmos.d.ts.map +1 -1
- package/dist/tx/status/resolvers/cosmos.js +21 -8
- package/dist/tx/status/resolvers/cosmos.js.map +1 -1
- package/dist/tx/status/resolvers/qbtc.d.ts.map +1 -1
- package/dist/tx/status/resolvers/qbtc.js +18 -19
- package/dist/tx/status/resolvers/qbtc.js.map +1 -1
- package/dist/tx/status/resolvers/ton.d.ts.map +1 -1
- package/dist/tx/status/resolvers/ton.js +4 -4
- package/dist/tx/status/resolvers/ton.js.map +1 -1
- package/package.json +192 -1
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { Chain } from '@vultisig/core-chain/Chain';
|
|
2
|
+
import { cosmosRpcUrl } from '@vultisig/core-chain/chains/cosmos/cosmosRpcUrl';
|
|
3
|
+
import { queryUrl } from '@vultisig/lib-utils/query/queryUrl';
|
|
4
|
+
import { assertValidPoolId } from './pools.js';
|
|
5
|
+
/**
|
|
6
|
+
* Assert a numeric input is a non-negative base-unit integer string.
|
|
7
|
+
*
|
|
8
|
+
* Public math helpers consume untrusted strings (LLM tool args, API
|
|
9
|
+
* responses). Raw `BigInt('abc')` throws `SyntaxError: Cannot convert
|
|
10
|
+
* abc to a BigInt`, which is an unhelpful error for callers and hides
|
|
11
|
+
* the field name. This validator produces stable SDK-level errors
|
|
12
|
+
* instead.
|
|
13
|
+
*/
|
|
14
|
+
const assertBaseUnitString = (value, fieldName) => {
|
|
15
|
+
if (typeof value !== 'string' || value.length === 0) {
|
|
16
|
+
throw new Error(`${fieldName} must be a non-empty base-unit string, got ${typeof value === 'string' ? JSON.stringify(value) : typeof value}`);
|
|
17
|
+
}
|
|
18
|
+
if (!/^\d+$/.test(value)) {
|
|
19
|
+
throw new Error(`${fieldName} must be a non-negative integer base-unit string, got ${JSON.stringify(value)}`);
|
|
20
|
+
}
|
|
21
|
+
return BigInt(value);
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Calculate the liquidity units earned for a deposit.
|
|
25
|
+
*
|
|
26
|
+
* Formula: `units = P * (R*a + r*A) / (2 * R * A)`
|
|
27
|
+
*
|
|
28
|
+
* P = current pool units
|
|
29
|
+
* r = RUNE deposited (base units)
|
|
30
|
+
* a = asset deposited (base units)
|
|
31
|
+
* R = current pool RUNE depth
|
|
32
|
+
* A = current pool asset depth
|
|
33
|
+
*
|
|
34
|
+
* Source: docs.thorchain.org continuous-liquidity-pools.md and the
|
|
35
|
+
* THORChain dev handbook. Implemented from the canonical formula, not
|
|
36
|
+
* copied from any third-party codebase. The on-chain handler multiplies
|
|
37
|
+
* by a slip-adjustment term (`1 - |rA - aR| / (rA + aR)`) before minting
|
|
38
|
+
* the final units; this helper intentionally omits that adjustment so UIs
|
|
39
|
+
* can show a quick estimate. For asymmetric adds the simplified number
|
|
40
|
+
* can diverge a few percent from mainnet — note that in UX copy if you
|
|
41
|
+
* display it directly.
|
|
42
|
+
*
|
|
43
|
+
* For an asymmetric deposit either `r` or `a` is zero — the formula still
|
|
44
|
+
* holds (the internal 50/50 rebalancing happens on-chain and is reflected
|
|
45
|
+
* in the returned units via the pool's existing depth ratio).
|
|
46
|
+
*
|
|
47
|
+
* All inputs / outputs are in 1e8 base units. Returns a non-negative
|
|
48
|
+
* BigInt-safe integer string.
|
|
49
|
+
*/
|
|
50
|
+
export const getLiquidityUnits = ({ pool, assetAmountBaseUnit, runeAmountBaseUnit, }) => {
|
|
51
|
+
const P = assertBaseUnitString(pool.poolUnits, 'pool.poolUnits');
|
|
52
|
+
const R = assertBaseUnitString(pool.runeDepth, 'pool.runeDepth');
|
|
53
|
+
const A = assertBaseUnitString(pool.assetDepth, 'pool.assetDepth');
|
|
54
|
+
const r = assertBaseUnitString(runeAmountBaseUnit, 'runeAmountBaseUnit');
|
|
55
|
+
const a = assertBaseUnitString(assetAmountBaseUnit, 'assetAmountBaseUnit');
|
|
56
|
+
if (R === 0n || A === 0n || P === 0n) {
|
|
57
|
+
// Empty / just-initialized pool — the first-deposit case is handled
|
|
58
|
+
// differently on-chain (the depositor mints the full initial unit
|
|
59
|
+
// supply). We can't model that here without knowing the genesis
|
|
60
|
+
// unit scale, so return 0 and let the caller decide what to do.
|
|
61
|
+
return '0';
|
|
62
|
+
}
|
|
63
|
+
const numerator = P * (R * a + r * A);
|
|
64
|
+
const denominator = 2n * R * A;
|
|
65
|
+
return (numerator / denominator).toString();
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Calculate the user's fractional share of a pool AFTER a deposit settles.
|
|
69
|
+
*
|
|
70
|
+
* Returns only the decimal share (`units / (poolUnits + units)`). The
|
|
71
|
+
* rune/asset base-unit shares are NOT computed here because the correct
|
|
72
|
+
* values depend on the post-deposit pool depths, which this helper does
|
|
73
|
+
* not take as inputs. For those values, use `estimateLpAdd` which has
|
|
74
|
+
* the full pool state and deposit amounts.
|
|
75
|
+
*
|
|
76
|
+
* For display only — the on-chain accounting uses the units directly.
|
|
77
|
+
*/
|
|
78
|
+
export const getPoolShare = ({ pool, liquidityUnits, }) => {
|
|
79
|
+
const P = assertBaseUnitString(pool.poolUnits, 'pool.poolUnits');
|
|
80
|
+
const L = assertBaseUnitString(liquidityUnits, 'liquidityUnits');
|
|
81
|
+
if (P === 0n || L === 0n) {
|
|
82
|
+
return { poolShareDecimal: '0' };
|
|
83
|
+
}
|
|
84
|
+
const totalAfter = P + L;
|
|
85
|
+
// Decimal share with 18-digit precision as a string (no floats).
|
|
86
|
+
// We multiply by 1e18, divide, then format as "0.xxx".
|
|
87
|
+
const SCALE = 10n ** 18n;
|
|
88
|
+
const scaled = (L * SCALE) / totalAfter;
|
|
89
|
+
const decimal = scaled.toString().padStart(19, '0'); // at least 18 fractional digits
|
|
90
|
+
const intPart = decimal.slice(0, -18) || '0';
|
|
91
|
+
const fracPart = decimal.slice(-18).replace(/0+$/, '');
|
|
92
|
+
return {
|
|
93
|
+
poolShareDecimal: fracPart.length > 0 ? `${intPart}.${fracPart}` : intPart,
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Calculate slippage for an LP add.
|
|
98
|
+
*
|
|
99
|
+
* Formula: `slip = |R*a - A*r| / (A*r + R*A)`
|
|
100
|
+
*
|
|
101
|
+
* This is the asym-rebalancing slip cost: when only one side is deposited,
|
|
102
|
+
* THORChain internally performs a 50/50 swap to balance the pool, and
|
|
103
|
+
* that swap incurs a slip cost proportional to how imbalanced the input
|
|
104
|
+
* is against the existing depth.
|
|
105
|
+
*
|
|
106
|
+
* For symmetric deposits (r/a ratio matches R/A), the numerator is zero
|
|
107
|
+
* and the slippage is exactly zero.
|
|
108
|
+
*
|
|
109
|
+
* Source: derived from the THORChain asymmetric-deposit-as-swap
|
|
110
|
+
* documentation. Cross-checked against the formula used by multiple
|
|
111
|
+
* independent implementations (iOS / extension don't compute this in
|
|
112
|
+
* their UI — they leave it to the chain).
|
|
113
|
+
*/
|
|
114
|
+
export const getLpAddSlippage = ({ pool, assetAmountBaseUnit, runeAmountBaseUnit, }) => {
|
|
115
|
+
const R = assertBaseUnitString(pool.runeDepth, 'pool.runeDepth');
|
|
116
|
+
const A = assertBaseUnitString(pool.assetDepth, 'pool.assetDepth');
|
|
117
|
+
const r = assertBaseUnitString(runeAmountBaseUnit, 'runeAmountBaseUnit');
|
|
118
|
+
const a = assertBaseUnitString(assetAmountBaseUnit, 'assetAmountBaseUnit');
|
|
119
|
+
if (R === 0n || A === 0n) {
|
|
120
|
+
return { decimalPercent: '0', slippageInRuneBaseUnit: '0' };
|
|
121
|
+
}
|
|
122
|
+
// |R*a - A*r| / (A*r + R*A)
|
|
123
|
+
const ra = R * a;
|
|
124
|
+
const ar = A * r;
|
|
125
|
+
const numerator = ra > ar ? ra - ar : ar - ra;
|
|
126
|
+
const denominator = A * r + R * A;
|
|
127
|
+
if (denominator === 0n) {
|
|
128
|
+
return { decimalPercent: '0', slippageInRuneBaseUnit: '0' };
|
|
129
|
+
}
|
|
130
|
+
// Express as decimal with 18-digit precision
|
|
131
|
+
const SCALE = 10n ** 18n;
|
|
132
|
+
const scaled = (numerator * SCALE) / denominator;
|
|
133
|
+
const decimal = scaled.toString().padStart(19, '0');
|
|
134
|
+
const intPart = decimal.slice(0, -18) || '0';
|
|
135
|
+
const fracPart = decimal.slice(-18).replace(/0+$/, '');
|
|
136
|
+
const decimalPercent = fracPart.length > 0 ? `${intPart}.${fracPart}` : intPart;
|
|
137
|
+
// Convert to rune-equivalent for display. The slip applies only to the
|
|
138
|
+
// imbalanced portion of the deposit — the part that has to be swapped
|
|
139
|
+
// internally to balance the pool. We compute the imbalance in rune
|
|
140
|
+
// terms: |R*a - A*r| / (2*A), then apply the slip fraction to it.
|
|
141
|
+
//
|
|
142
|
+
// For pure asym RUNE (a=0): imbalance = R*0 - A*r divided by 2*A, abs
|
|
143
|
+
// → r/2 (half the deposit gets swapped) → slippageInRune ≈ (r/2) * slip
|
|
144
|
+
// For pure asym asset (r=0): imbalance = (R*a) / (2*A), the rune-value
|
|
145
|
+
// of half the deposit → slippageInRune ≈ (a*R / (2*A)) * slip
|
|
146
|
+
// For balanced deposit: imbalance = 0 → slippageInRune = 0
|
|
147
|
+
//
|
|
148
|
+
// This is a heuristic display value, not an exact chain computation.
|
|
149
|
+
// It under/overstates real on-chain slip by a constant factor in some
|
|
150
|
+
// regimes but is directionally correct and never overstates by orders
|
|
151
|
+
// of magnitude the way "slip * total deposit value" did.
|
|
152
|
+
const imbalanceNumerator = ra > ar ? ra - ar : ar - ra;
|
|
153
|
+
const imbalanceInRune = A === 0n ? 0n : imbalanceNumerator / (2n * A);
|
|
154
|
+
const slippageInRune = (imbalanceInRune * scaled) / SCALE;
|
|
155
|
+
return {
|
|
156
|
+
decimalPercent,
|
|
157
|
+
slippageInRuneBaseUnit: slippageInRune.toString(),
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* One-shot estimator that chains pool-state fetch + the three math
|
|
162
|
+
* helpers. Returns everything a UI needs to surface a quote before the
|
|
163
|
+
* user signs.
|
|
164
|
+
*
|
|
165
|
+
* Fetches from thornode `/thorchain/pool/{asset}`. Injectable
|
|
166
|
+
* `fetchImpl` for tests.
|
|
167
|
+
*/
|
|
168
|
+
export const estimateLpAdd = async ({ pool, assetAmountBaseUnit, runeAmountBaseUnit, thornodeBaseUrl, }) => {
|
|
169
|
+
assertValidPoolId(pool);
|
|
170
|
+
const base = thornodeBaseUrl ?? cosmosRpcUrl[Chain.THORChain];
|
|
171
|
+
const url = `${base}/thorchain/pool/${encodeURIComponent(pool)}`;
|
|
172
|
+
const raw = await queryUrl(url);
|
|
173
|
+
if (!raw ||
|
|
174
|
+
typeof raw !== 'object' ||
|
|
175
|
+
typeof raw.balance_asset !== 'string' ||
|
|
176
|
+
typeof raw.balance_rune !== 'string') {
|
|
177
|
+
throw new Error(`estimateLpAdd: pool ${pool} response from ${url} missing balance fields`);
|
|
178
|
+
}
|
|
179
|
+
const poolUnitsRaw = raw.pool_units ?? raw.LP_units;
|
|
180
|
+
if (typeof poolUnitsRaw !== 'string' || poolUnitsRaw.length === 0) {
|
|
181
|
+
throw new Error(`estimateLpAdd: pool ${pool} response from ${url} missing pool_units / LP_units`);
|
|
182
|
+
}
|
|
183
|
+
const poolState = {
|
|
184
|
+
assetDepth: raw.balance_asset,
|
|
185
|
+
runeDepth: raw.balance_rune,
|
|
186
|
+
poolUnits: poolUnitsRaw,
|
|
187
|
+
};
|
|
188
|
+
const liquidityUnits = getLiquidityUnits({
|
|
189
|
+
pool: poolState,
|
|
190
|
+
assetAmountBaseUnit,
|
|
191
|
+
runeAmountBaseUnit,
|
|
192
|
+
});
|
|
193
|
+
const share = getPoolShare({
|
|
194
|
+
pool: poolState,
|
|
195
|
+
liquidityUnits,
|
|
196
|
+
});
|
|
197
|
+
const slip = getLpAddSlippage({
|
|
198
|
+
pool: poolState,
|
|
199
|
+
assetAmountBaseUnit,
|
|
200
|
+
runeAmountBaseUnit,
|
|
201
|
+
});
|
|
202
|
+
// Compute post-deposit base-unit shares from the caller's deposit
|
|
203
|
+
// amounts. This is the correct frame for display ("you'll own X RUNE +
|
|
204
|
+
// Y asset's worth"). Uses post-deposit depths R+r and A+a, which is
|
|
205
|
+
// the pre-internal-swap state — close enough for display purposes and
|
|
206
|
+
// doesn't require simulating the chain's internal rebalancing swap.
|
|
207
|
+
const R = BigInt(poolState.runeDepth);
|
|
208
|
+
const A = BigInt(poolState.assetDepth);
|
|
209
|
+
const P = BigInt(poolState.poolUnits);
|
|
210
|
+
const r = BigInt(runeAmountBaseUnit);
|
|
211
|
+
const a = BigInt(assetAmountBaseUnit);
|
|
212
|
+
const L = BigInt(liquidityUnits);
|
|
213
|
+
const totalAfter = P + L;
|
|
214
|
+
const runeDepthAfter = R + r;
|
|
215
|
+
const assetDepthAfter = A + a;
|
|
216
|
+
const runeShareBaseUnit = totalAfter === 0n ? '0' : ((runeDepthAfter * L) / totalAfter).toString();
|
|
217
|
+
const assetShareBaseUnit = totalAfter === 0n ? '0' : ((assetDepthAfter * L) / totalAfter).toString();
|
|
218
|
+
return {
|
|
219
|
+
liquidityUnits,
|
|
220
|
+
poolShareDecimal: share.poolShareDecimal,
|
|
221
|
+
runeShareBaseUnit,
|
|
222
|
+
assetShareBaseUnit,
|
|
223
|
+
slippageDecimal: slip.decimalPercent,
|
|
224
|
+
slippageRuneBaseUnit: slip.slippageInRuneBaseUnit,
|
|
225
|
+
};
|
|
226
|
+
};
|
|
227
|
+
//# sourceMappingURL=math.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"math.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/math.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { RawMemberPool, ThorchainLpPosition } from './types.js';
|
|
2
|
+
export declare const isNonZeroBaseUnit: (value: string | undefined) => boolean;
|
|
3
|
+
export declare const normalizeMemberPool: (raw: RawMemberPool) => ThorchainLpPosition;
|
|
4
|
+
//# sourceMappingURL=memberPool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memberPool.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/memberPool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAEjE,eAAO,MAAM,iBAAiB,GAAI,OAAO,MAAM,GAAG,SAAS,KAAG,OAO7D,CAAA;AAED,eAAO,MAAM,mBAAmB,GAC9B,KAAK,aAAa,KACjB,mBAaD,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export const isNonZeroBaseUnit = (value) => {
|
|
2
|
+
if (!value)
|
|
3
|
+
return false;
|
|
4
|
+
try {
|
|
5
|
+
return BigInt(value) > 0n;
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
export const normalizeMemberPool = (raw) => ({
|
|
12
|
+
pool: raw.pool ?? '',
|
|
13
|
+
liquidityUnits: raw.liquidityUnits ?? '0',
|
|
14
|
+
runeAdded: raw.runeAdded ?? '0',
|
|
15
|
+
assetAdded: raw.assetAdded ?? '0',
|
|
16
|
+
runePending: raw.runePending ?? '0',
|
|
17
|
+
assetPending: raw.assetPending ?? '0',
|
|
18
|
+
runeAddress: raw.runeAddress ?? '',
|
|
19
|
+
assetAddress: raw.assetAddress ?? '',
|
|
20
|
+
dateLastAdded: raw.dateLastAdded ?? '0',
|
|
21
|
+
lastAddHeight: '',
|
|
22
|
+
isPending: isNonZeroBaseUnit(raw.runePending) || isNonZeroBaseUnit(raw.assetPending),
|
|
23
|
+
});
|
|
24
|
+
//# sourceMappingURL=memberPool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memberPool.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/memberPool.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAyB,EAAW,EAAE;IACtE,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAA;IACxB,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAA;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,GAAkB,EACG,EAAE,CAAC,CAAC;IACzB,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE;IACpB,cAAc,EAAE,GAAG,CAAC,cAAc,IAAI,GAAG;IACzC,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,GAAG;IAC/B,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,GAAG;IACjC,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,GAAG;IACnC,YAAY,EAAE,GAAG,CAAC,YAAY,IAAI,GAAG;IACrC,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,EAAE;IAClC,YAAY,EAAE,GAAG,CAAC,YAAY,IAAI,EAAE;IACpC,aAAa,EAAE,GAAG,CAAC,aAAa,IAAI,GAAG;IACvC,aAAa,EAAE,EAAE;IACjB,SAAS,EACP,iBAAiB,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,iBAAiB,CAAC,GAAG,CAAC,YAAY,CAAC;CAC5E,CAAC,CAAA"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export type AddLpMemoInput = {
|
|
2
|
+
/** Canonical pool id, e.g. `BTC.BTC` or `ETH.USDC-0X...`. */
|
|
3
|
+
pool: string;
|
|
4
|
+
/**
|
|
5
|
+
* Paired L1 address. When set, THORChain registers the deposit with a
|
|
6
|
+
* counterpart address on the other side of the pool. The paired address
|
|
7
|
+
* is the vault's address on the OTHER chain relative to the side being
|
|
8
|
+
* deposited:
|
|
9
|
+
*
|
|
10
|
+
* - For a RUNE-side add (depositing RUNE on THORChain), this is the
|
|
11
|
+
* vault's L1 address on the pool's asset chain (e.g., BTC.BTC → the
|
|
12
|
+
* vault's BTC address).
|
|
13
|
+
* - For an asset-side add (depositing L1 asset), this is the vault's
|
|
14
|
+
* THORChain address (`thor1...`).
|
|
15
|
+
*
|
|
16
|
+
* Matches the default behavior of vultisig-ios and vultisig-windows
|
|
17
|
+
* (the extension), which always auto-populate the paired address from
|
|
18
|
+
* the vault. Leave omitted for a pure asymmetric deposit with no
|
|
19
|
+
* paired-address registration.
|
|
20
|
+
*/
|
|
21
|
+
pairedAddress?: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Build a THORChain liquidity-pool add memo.
|
|
25
|
+
*
|
|
26
|
+
* Format: `+:POOL` (pure asym, no paired address) or
|
|
27
|
+
* `+:POOL:PAIRED_ADDR` (when paired address is provided)
|
|
28
|
+
*
|
|
29
|
+
* Matches vultisig-ios `AddLPMemoData.memo` and
|
|
30
|
+
* vultisig-windows `memoGenerator` `add_thor_lp` output exactly — no
|
|
31
|
+
* affiliate suffix. The THORChain memo spec allows an affiliate via
|
|
32
|
+
* `+:POOL::AFFILIATE:BPS` but neither Vultisig native client ships it;
|
|
33
|
+
* we match the native behavior for wire-level consistency.
|
|
34
|
+
*/
|
|
35
|
+
export declare const addLpMemo: ({ pool, pairedAddress, }: AddLpMemoInput) => string;
|
|
36
|
+
export type RemoveLpMemoInput = {
|
|
37
|
+
pool: string;
|
|
38
|
+
/** Withdraw fraction in basis points: 1..10000 (10000 = 100%). */
|
|
39
|
+
basisPoints: number;
|
|
40
|
+
/**
|
|
41
|
+
* Optional asymmetric-withdraw target. When set, THORChain sends the
|
|
42
|
+
* withdrawn value out to this side only (e.g., `withdrawToAsset: "BTC"`
|
|
43
|
+
* forces all output to BTC). When omitted, the protocol returns both
|
|
44
|
+
* sides proportionally for symmetric positions, or to the same side for
|
|
45
|
+
* asymmetric positions.
|
|
46
|
+
*
|
|
47
|
+
* Only the short asset ticker is used on the wire (e.g., `BTC`, not
|
|
48
|
+
* `BTC.BTC`). Pass the pool's ASSET section, not the full pool id.
|
|
49
|
+
*/
|
|
50
|
+
withdrawToAsset?: string;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Build a THORChain liquidity-pool remove memo.
|
|
54
|
+
*
|
|
55
|
+
* Format: `-:POOL:BPS` or `-:POOL:BPS:ASSET` when asym-withdraw target set.
|
|
56
|
+
*
|
|
57
|
+
* Withdraws do not include an affiliate suffix per the THORChain memo spec.
|
|
58
|
+
* THORChain enforces a ~1 hour window (`LIQUIDITYLOCKUPBLOCKS`, currently
|
|
59
|
+
* 600 on mainnet) after the most recent add before broadcasts process cleanly.
|
|
60
|
+
*/
|
|
61
|
+
export declare const removeLpMemo: ({ pool, basisPoints, withdrawToAsset, }: RemoveLpMemoInput) => string;
|
|
62
|
+
//# sourceMappingURL=memo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memo.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/memo.ts"],"names":[],"mappings":"AA4BA,MAAM,MAAM,cAAc,GAAG;IAC3B,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAA;IACZ;;;;;;;;;;;;;;;;OAgBG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,SAAS,GAAI,0BAGvB,cAAc,KAAG,MAOnB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAA;IACnB;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,GAAI,yCAI1B,iBAAiB,KAAG,MAgBtB,CAAA"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { assertValidPoolId } from './pools.js';
|
|
2
|
+
/**
|
|
3
|
+
* Reject memo-segment values that would smuggle additional `:`-separated
|
|
4
|
+
* fields into the memo (e.g. a pairedAddress like `bc1q:ss:60` that tries
|
|
5
|
+
* to inject an affiliate). Also rejects whitespace since THORChain memos
|
|
6
|
+
* are tokenized on `:` and trimmed/rejected when they contain internal
|
|
7
|
+
* whitespace.
|
|
8
|
+
*/
|
|
9
|
+
const assertMemoSegmentSafe = (value, fieldName) => {
|
|
10
|
+
if (typeof value !== 'string') {
|
|
11
|
+
throw new Error(`${fieldName} must be a string, got ${typeof value}`);
|
|
12
|
+
}
|
|
13
|
+
if (value.includes(':')) {
|
|
14
|
+
throw new Error(`${fieldName} must not contain \`:\` (would inject extra memo segments), got ${JSON.stringify(value)}`);
|
|
15
|
+
}
|
|
16
|
+
if (/\s/.test(value)) {
|
|
17
|
+
throw new Error(`${fieldName} must not contain whitespace, got ${JSON.stringify(value)}`);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Build a THORChain liquidity-pool add memo.
|
|
22
|
+
*
|
|
23
|
+
* Format: `+:POOL` (pure asym, no paired address) or
|
|
24
|
+
* `+:POOL:PAIRED_ADDR` (when paired address is provided)
|
|
25
|
+
*
|
|
26
|
+
* Matches vultisig-ios `AddLPMemoData.memo` and
|
|
27
|
+
* vultisig-windows `memoGenerator` `add_thor_lp` output exactly — no
|
|
28
|
+
* affiliate suffix. The THORChain memo spec allows an affiliate via
|
|
29
|
+
* `+:POOL::AFFILIATE:BPS` but neither Vultisig native client ships it;
|
|
30
|
+
* we match the native behavior for wire-level consistency.
|
|
31
|
+
*/
|
|
32
|
+
export const addLpMemo = ({ pool, pairedAddress, }) => {
|
|
33
|
+
assertValidPoolId(pool);
|
|
34
|
+
if (pairedAddress && pairedAddress.length > 0) {
|
|
35
|
+
assertMemoSegmentSafe(pairedAddress, 'pairedAddress');
|
|
36
|
+
return `+:${pool}:${pairedAddress}`;
|
|
37
|
+
}
|
|
38
|
+
return `+:${pool}`;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Build a THORChain liquidity-pool remove memo.
|
|
42
|
+
*
|
|
43
|
+
* Format: `-:POOL:BPS` or `-:POOL:BPS:ASSET` when asym-withdraw target set.
|
|
44
|
+
*
|
|
45
|
+
* Withdraws do not include an affiliate suffix per the THORChain memo spec.
|
|
46
|
+
* THORChain enforces a ~1 hour window (`LIQUIDITYLOCKUPBLOCKS`, currently
|
|
47
|
+
* 600 on mainnet) after the most recent add before broadcasts process cleanly.
|
|
48
|
+
*/
|
|
49
|
+
export const removeLpMemo = ({ pool, basisPoints, withdrawToAsset, }) => {
|
|
50
|
+
assertValidPoolId(pool);
|
|
51
|
+
if (!Number.isInteger(basisPoints) ||
|
|
52
|
+
basisPoints < 1 ||
|
|
53
|
+
basisPoints > 10000) {
|
|
54
|
+
throw new Error(`removeLpMemo: basisPoints must be an integer in [1, 10000], got ${basisPoints}`);
|
|
55
|
+
}
|
|
56
|
+
if (withdrawToAsset && withdrawToAsset.length > 0) {
|
|
57
|
+
assertMemoSegmentSafe(withdrawToAsset, 'withdrawToAsset');
|
|
58
|
+
return `-:${pool}:${basisPoints}:${withdrawToAsset}`;
|
|
59
|
+
}
|
|
60
|
+
return `-:${pool}:${basisPoints}`;
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=memo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memo.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/memo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAE3C;;;;;;GAMG;AACH,MAAM,qBAAqB,GAAG,CAC5B,KAAa,EACb,SAAiB,EACX,EAAE;IACR,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,GAAG,SAAS,0BAA0B,OAAO,KAAK,EAAE,CAAC,CAAA;IACvE,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,GAAG,SAAS,mEAAmE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CACvG,CAAA;IACH,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,GAAG,SAAS,qCAAqC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CACzE,CAAA;IACH,CAAC;AACH,CAAC,CAAA;AAyBD;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,EACxB,IAAI,EACJ,aAAa,GACE,EAAU,EAAE;IAC3B,iBAAiB,CAAC,IAAI,CAAC,CAAA;IACvB,IAAI,aAAa,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,qBAAqB,CAAC,aAAa,EAAE,eAAe,CAAC,CAAA;QACrD,OAAO,KAAK,IAAI,IAAI,aAAa,EAAE,CAAA;IACrC,CAAC;IACD,OAAO,KAAK,IAAI,EAAE,CAAA;AACpB,CAAC,CAAA;AAmBD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAC3B,IAAI,EACJ,WAAW,EACX,eAAe,GACG,EAAU,EAAE;IAC9B,iBAAiB,CAAC,IAAI,CAAC,CAAA;IACvB,IACE,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC;QAC9B,WAAW,GAAG,CAAC;QACf,WAAW,GAAG,KAAK,EACnB,CAAC;QACD,MAAM,IAAI,KAAK,CACb,mEAAmE,WAAW,EAAE,CACjF,CAAA;IACH,CAAC;IACD,IAAI,eAAe,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,qBAAqB,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAA;QACzD,OAAO,KAAK,IAAI,IAAI,WAAW,IAAI,eAAe,EAAE,CAAA;IACtD,CAAC;IACD,OAAO,KAAK,IAAI,IAAI,WAAW,EAAE,CAAA;AACnC,CAAC,CAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Chain } from '@vultisig/core-chain/Chain';
|
|
2
|
+
export type VaultAddressMap = Partial<Record<Chain, string>>;
|
|
3
|
+
export type LpSide = 'rune' | 'asset';
|
|
4
|
+
/**
|
|
5
|
+
* Resolve the paired-address for an LP add based on which side of the
|
|
6
|
+
* pool the caller is depositing.
|
|
7
|
+
*
|
|
8
|
+
* - `side: 'rune'` (depositing RUNE on THORChain): returns the vault's L1
|
|
9
|
+
* address on the pool's ASSET chain. E.g. `BTC.BTC` → vault's BTC
|
|
10
|
+
* address.
|
|
11
|
+
* - `side: 'asset'` (depositing L1 asset): returns the vault's THORChain
|
|
12
|
+
* address (`thor1...`).
|
|
13
|
+
*
|
|
14
|
+
* Matches vultisig-ios `FunctionCallAddThorLP.prefillPairedAddressForPool`
|
|
15
|
+
* and vultisig-windows (the extension) `ThorLpSpecific.tsx`
|
|
16
|
+
* behavior exactly — both always auto-populate the paired address when the
|
|
17
|
+
* vault has the required address, producing a symmetric-pending memo.
|
|
18
|
+
*
|
|
19
|
+
* Returns `undefined` when the vault map does not contain the required
|
|
20
|
+
* address. The caller decides whether to:
|
|
21
|
+
* - fall back to a pure asymmetric deposit (`+:POOL` with no paired
|
|
22
|
+
* address), or
|
|
23
|
+
* - surface an error ("add the other chain to your vault first").
|
|
24
|
+
*/
|
|
25
|
+
export declare const resolvePairedAddressForLpAdd: ({ pool, side, vaultAddresses, }: {
|
|
26
|
+
pool: string;
|
|
27
|
+
side: LpSide;
|
|
28
|
+
vaultAddresses: VaultAddressMap;
|
|
29
|
+
}) => string | undefined;
|
|
30
|
+
//# sourceMappingURL=pairing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairing.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/pairing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAKlD,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAA;AAE5D,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;AAErC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,4BAA4B,GAAI,iCAI1C;IACD,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,cAAc,EAAE,eAAe,CAAA;CAChC,KAAG,MAAM,GAAG,SAmBZ,CAAA"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Chain } from '@vultisig/core-chain/Chain';
|
|
2
|
+
import { chainPrefixToChain } from './lpChainMap.js';
|
|
3
|
+
import { assertValidPoolId } from './pools.js';
|
|
4
|
+
/**
|
|
5
|
+
* Resolve the paired-address for an LP add based on which side of the
|
|
6
|
+
* pool the caller is depositing.
|
|
7
|
+
*
|
|
8
|
+
* - `side: 'rune'` (depositing RUNE on THORChain): returns the vault's L1
|
|
9
|
+
* address on the pool's ASSET chain. E.g. `BTC.BTC` → vault's BTC
|
|
10
|
+
* address.
|
|
11
|
+
* - `side: 'asset'` (depositing L1 asset): returns the vault's THORChain
|
|
12
|
+
* address (`thor1...`).
|
|
13
|
+
*
|
|
14
|
+
* Matches vultisig-ios `FunctionCallAddThorLP.prefillPairedAddressForPool`
|
|
15
|
+
* and vultisig-windows (the extension) `ThorLpSpecific.tsx`
|
|
16
|
+
* behavior exactly — both always auto-populate the paired address when the
|
|
17
|
+
* vault has the required address, producing a symmetric-pending memo.
|
|
18
|
+
*
|
|
19
|
+
* Returns `undefined` when the vault map does not contain the required
|
|
20
|
+
* address. The caller decides whether to:
|
|
21
|
+
* - fall back to a pure asymmetric deposit (`+:POOL` with no paired
|
|
22
|
+
* address), or
|
|
23
|
+
* - surface an error ("add the other chain to your vault first").
|
|
24
|
+
*/
|
|
25
|
+
export const resolvePairedAddressForLpAdd = ({ pool, side, vaultAddresses, }) => {
|
|
26
|
+
assertValidPoolId(pool);
|
|
27
|
+
// Guard against unknown pool prefixes on BOTH sides — the pool id regex
|
|
28
|
+
// accepts `ZZZ.ABC` but `chainPrefixToChain` is the source of truth for
|
|
29
|
+
// THORChain-supported chains. If we can't resolve the prefix we refuse
|
|
30
|
+
// to auto-pair either way; the caller can still fall back to a pure
|
|
31
|
+
// asym memo if they want.
|
|
32
|
+
const [chainPrefix] = pool.split('.');
|
|
33
|
+
if (!chainPrefix)
|
|
34
|
+
return undefined;
|
|
35
|
+
const assetChain = chainPrefixToChain(chainPrefix);
|
|
36
|
+
if (!assetChain)
|
|
37
|
+
return undefined;
|
|
38
|
+
if (side === 'asset') {
|
|
39
|
+
return vaultAddresses[Chain.THORChain];
|
|
40
|
+
}
|
|
41
|
+
// side === 'rune' — need the vault's address on the pool's asset chain
|
|
42
|
+
return vaultAddresses[assetChain];
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=pairing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairing.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/pairing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAElD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAM3C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,EAC3C,IAAI,EACJ,IAAI,EACJ,cAAc,GAKf,EAAsB,EAAE;IACvB,iBAAiB,CAAC,IAAI,CAAC,CAAA;IAEvB,wEAAwE;IACxE,wEAAwE;IACxE,uEAAuE;IACvE,oEAAoE;IACpE,0BAA0B;IAC1B,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACrC,IAAI,CAAC,WAAW;QAAE,OAAO,SAAS,CAAA;IAClC,MAAM,UAAU,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAA;IAClD,IAAI,CAAC,UAAU;QAAE,OAAO,SAAS,CAAA;IAEjC,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,OAAO,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IACxC,CAAC;IAED,uEAAuE;IACvE,OAAO,cAAc,CAAC,UAAU,CAAC,CAAA;AACnC,CAAC,CAAA"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flat unsigned-transaction payload for an asymmetric RUNE-side LP add.
|
|
3
|
+
*
|
|
4
|
+
* Shape stays single-nesting-level on purpose: this object flows through
|
|
5
|
+
* the agent backend's SSE `tx_ready` event, and the 2026-04-09 audit
|
|
6
|
+
* flagged tool result flattening as a known wire-level hazard for nested
|
|
7
|
+
* fields. Every consumer (MCP tool result, backend SSE emit, app
|
|
8
|
+
* `parseServerTx`) reads the same flat keys.
|
|
9
|
+
*
|
|
10
|
+
* v2 wire format drops the `affiliate` / `affiliateBps` fields. Matches
|
|
11
|
+
* vultisig-ios and vultisig-windows (the extension) — neither ships an
|
|
12
|
+
* affiliate on LP memos.
|
|
13
|
+
*/
|
|
14
|
+
export type ThorchainLpAddPayload = {
|
|
15
|
+
kind: 'thorchain_lp_add';
|
|
16
|
+
chain: 'THORChain';
|
|
17
|
+
denom: 'rune';
|
|
18
|
+
/** RUNE base units; 1 RUNE = 100000000 (8 decimals). */
|
|
19
|
+
amount: string;
|
|
20
|
+
/** Pre-built memo via `addLpMemo`. */
|
|
21
|
+
memo: string;
|
|
22
|
+
/** Canonical pool id, denormalized for display. */
|
|
23
|
+
pool: string;
|
|
24
|
+
/**
|
|
25
|
+
* Paired L1 address embedded in the memo, if any. Denormalized for
|
|
26
|
+
* display so consumers don't have to re-parse the memo.
|
|
27
|
+
*/
|
|
28
|
+
pairedAddress?: string;
|
|
29
|
+
};
|
|
30
|
+
export type ThorchainLpRemovePayload = {
|
|
31
|
+
kind: 'thorchain_lp_remove';
|
|
32
|
+
chain: 'THORChain';
|
|
33
|
+
denom: 'rune';
|
|
34
|
+
/** Dust amount in RUNE base units. The withdraw fraction lives in the memo. */
|
|
35
|
+
amount: string;
|
|
36
|
+
/** Pre-built memo via `removeLpMemo`. */
|
|
37
|
+
memo: string;
|
|
38
|
+
pool: string;
|
|
39
|
+
basisPoints: number;
|
|
40
|
+
/**
|
|
41
|
+
* Asym-withdraw target asset, if any. Denormalized for display.
|
|
42
|
+
*/
|
|
43
|
+
withdrawToAsset?: string;
|
|
44
|
+
};
|
|
45
|
+
export type BuildThorchainLpAddPayloadInput = {
|
|
46
|
+
pool: string;
|
|
47
|
+
amountRuneBaseUnits: string;
|
|
48
|
+
/**
|
|
49
|
+
* Optional paired address. When provided, embedded in the memo (matching
|
|
50
|
+
* iOS / Windows-extension auto-pair behavior) and denormalized on the
|
|
51
|
+
* payload for display.
|
|
52
|
+
*/
|
|
53
|
+
pairedAddress?: string;
|
|
54
|
+
};
|
|
55
|
+
export declare const buildThorchainLpAddPayload: ({ pool, amountRuneBaseUnits, pairedAddress, }: BuildThorchainLpAddPayloadInput) => ThorchainLpAddPayload;
|
|
56
|
+
export type BuildThorchainLpRemovePayloadInput = {
|
|
57
|
+
pool: string;
|
|
58
|
+
basisPoints: number;
|
|
59
|
+
/**
|
|
60
|
+
* Optional asym-withdraw target. Pass the short asset ticker (e.g. `BTC`),
|
|
61
|
+
* not the full pool id.
|
|
62
|
+
*/
|
|
63
|
+
withdrawToAsset?: string;
|
|
64
|
+
};
|
|
65
|
+
export declare const buildThorchainLpRemovePayload: ({ pool, basisPoints, withdrawToAsset, }: BuildThorchainLpRemovePayloadInput) => ThorchainLpRemovePayload;
|
|
66
|
+
//# sourceMappingURL=payload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/payload.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,kBAAkB,CAAA;IACxB,KAAK,EAAE,WAAW,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAA;IACd,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,IAAI,EAAE,qBAAqB,CAAA;IAC3B,KAAK,EAAE,WAAW,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAA;IACd,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB,CAAA;AAgBD,MAAM,MAAM,+BAA+B,GAAG;IAC5C,IAAI,EAAE,MAAM,CAAA;IACZ,mBAAmB,EAAE,MAAM,CAAA;IAC3B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,eAAO,MAAM,0BAA0B,GAAI,+CAIxC,+BAA+B,KAAG,qBAgBpC,CAAA;AAED,MAAM,MAAM,kCAAkC,GAAG;IAC/C,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB,CAAA;AAED,eAAO,MAAM,6BAA6B,GAAI,yCAI3C,kCAAkC,KAAG,wBAwBvC,CAAA"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { addLpMemo, removeLpMemo } from './memo.js';
|
|
2
|
+
/**
|
|
3
|
+
* Dust amount used for LP removes.
|
|
4
|
+
*
|
|
5
|
+
* Reference: vultisig-windows (the extension)
|
|
6
|
+
* `core/ui/vault/deposit/keysignPayload/build.ts` uses 0.02 RUNE as the
|
|
7
|
+
* dust amount on LP remove transactions — the on-chain amount is just
|
|
8
|
+
* dust to make the cosmos message valid; the actual withdraw fraction
|
|
9
|
+
* lives inside the memo (`-:POOL:BPS`).
|
|
10
|
+
*/
|
|
11
|
+
const LP_REMOVE_DUST_RUNE_BASE_UNITS = '2000000';
|
|
12
|
+
const isPositiveBaseUnitString = (value) => /^\d+$/.test(value) && BigInt(value) > 0n;
|
|
13
|
+
export const buildThorchainLpAddPayload = ({ pool, amountRuneBaseUnits, pairedAddress, }) => {
|
|
14
|
+
if (!isPositiveBaseUnitString(amountRuneBaseUnits)) {
|
|
15
|
+
throw new Error(`buildThorchainLpAddPayload: amountRuneBaseUnits must be a positive integer string, got ${amountRuneBaseUnits}`);
|
|
16
|
+
}
|
|
17
|
+
const memo = addLpMemo({ pool, pairedAddress });
|
|
18
|
+
return {
|
|
19
|
+
kind: 'thorchain_lp_add',
|
|
20
|
+
chain: 'THORChain',
|
|
21
|
+
denom: 'rune',
|
|
22
|
+
amount: amountRuneBaseUnits,
|
|
23
|
+
memo,
|
|
24
|
+
pool,
|
|
25
|
+
...(pairedAddress ? { pairedAddress } : {}),
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
export const buildThorchainLpRemovePayload = ({ pool, basisPoints, withdrawToAsset, }) => {
|
|
29
|
+
// removeLpMemo validates this too, but fail fast at the payload
|
|
30
|
+
// boundary so callers see a consistent error shape with the add
|
|
31
|
+
// builder (which validates amountRuneBaseUnits up-front).
|
|
32
|
+
if (!Number.isInteger(basisPoints) ||
|
|
33
|
+
basisPoints < 1 ||
|
|
34
|
+
basisPoints > 10000) {
|
|
35
|
+
throw new Error(`buildThorchainLpRemovePayload: basisPoints must be an integer in [1, 10000], got ${basisPoints}`);
|
|
36
|
+
}
|
|
37
|
+
const memo = removeLpMemo({ pool, basisPoints, withdrawToAsset });
|
|
38
|
+
return {
|
|
39
|
+
kind: 'thorchain_lp_remove',
|
|
40
|
+
chain: 'THORChain',
|
|
41
|
+
denom: 'rune',
|
|
42
|
+
amount: LP_REMOVE_DUST_RUNE_BASE_UNITS,
|
|
43
|
+
memo,
|
|
44
|
+
pool,
|
|
45
|
+
basisPoints,
|
|
46
|
+
...(withdrawToAsset ? { withdrawToAsset } : {}),
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
//# sourceMappingURL=payload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payload.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/payload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAgDhD;;;;;;;;GAQG;AACH,MAAM,8BAA8B,GAAG,SAAS,CAAA;AAEhD,MAAM,wBAAwB,GAAG,CAAC,KAAa,EAAW,EAAE,CAC1D,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAA;AAa3C,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,EACzC,IAAI,EACJ,mBAAmB,EACnB,aAAa,GACmB,EAAyB,EAAE;IAC3D,IAAI,CAAC,wBAAwB,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CACb,0FAA0F,mBAAmB,EAAE,CAChH,CAAA;IACH,CAAC;IACD,MAAM,IAAI,GAAG,SAAS,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAA;IAC/C,OAAO;QACL,IAAI,EAAE,kBAAkB;QACxB,KAAK,EAAE,WAAW;QAClB,KAAK,EAAE,MAAM;QACb,MAAM,EAAE,mBAAmB;QAC3B,IAAI;QACJ,IAAI;QACJ,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5C,CAAA;AACH,CAAC,CAAA;AAYD,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,EAC5C,IAAI,EACJ,WAAW,EACX,eAAe,GACoB,EAA4B,EAAE;IACjE,gEAAgE;IAChE,gEAAgE;IAChE,0DAA0D;IAC1D,IACE,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC;QAC9B,WAAW,GAAG,CAAC;QACf,WAAW,GAAG,KAAK,EACnB,CAAC;QACD,MAAM,IAAI,KAAK,CACb,oFAAoF,WAAW,EAAE,CAClG,CAAA;IACH,CAAC;IACD,MAAM,IAAI,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC,CAAA;IACjE,OAAO;QACL,IAAI,EAAE,qBAAqB;QAC3B,KAAK,EAAE,WAAW;QAClB,KAAK,EAAE,MAAM;QACb,MAAM,EAAE,8BAA8B;QACtC,IAAI;QACJ,IAAI;QACJ,WAAW;QACX,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChD,CAAA;AACH,CAAC,CAAA"}
|