@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.
Files changed (227) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/dist/amount/toChainAmount.d.ts +6 -1
  3. package/dist/amount/toChainAmount.d.ts.map +1 -1
  4. package/dist/amount/toChainAmount.js +88 -0
  5. package/dist/amount/toChainAmount.js.map +1 -1
  6. package/dist/chains/cardano/asset/cardanoAssetId.d.ts +14 -0
  7. package/dist/chains/cardano/asset/cardanoAssetId.d.ts.map +1 -0
  8. package/dist/chains/cardano/asset/cardanoAssetId.js +19 -0
  9. package/dist/chains/cardano/asset/cardanoAssetId.js.map +1 -0
  10. package/dist/chains/cardano/client/getCardanoAddressAssets.d.ts +10 -0
  11. package/dist/chains/cardano/client/getCardanoAddressAssets.d.ts.map +1 -0
  12. package/dist/chains/cardano/client/getCardanoAddressAssets.js +19 -0
  13. package/dist/chains/cardano/client/getCardanoAddressAssets.js.map +1 -0
  14. package/dist/chains/cardano/client/getCardanoAssetInfo.d.ts +23 -0
  15. package/dist/chains/cardano/client/getCardanoAssetInfo.d.ts.map +1 -0
  16. package/dist/chains/cardano/client/getCardanoAssetInfo.js +16 -0
  17. package/dist/chains/cardano/client/getCardanoAssetInfo.js.map +1 -0
  18. package/dist/chains/cardano/utxo/getCardanoExtendedUtxos.d.ts +20 -0
  19. package/dist/chains/cardano/utxo/getCardanoExtendedUtxos.d.ts.map +1 -0
  20. package/dist/chains/cardano/utxo/getCardanoExtendedUtxos.js +22 -0
  21. package/dist/chains/cardano/utxo/getCardanoExtendedUtxos.js.map +1 -0
  22. package/dist/chains/cosmos/computeCosmosTxReceiptFeeAmount.d.ts +14 -0
  23. package/dist/chains/cosmos/computeCosmosTxReceiptFeeAmount.d.ts.map +1 -0
  24. package/dist/chains/cosmos/computeCosmosTxReceiptFeeAmount.js +28 -0
  25. package/dist/chains/cosmos/computeCosmosTxReceiptFeeAmount.js.map +1 -0
  26. package/dist/chains/cosmos/qbtc/claim/BtcAddressType.d.ts +7 -0
  27. package/dist/chains/cosmos/qbtc/claim/BtcAddressType.d.ts.map +1 -0
  28. package/dist/chains/cosmos/qbtc/claim/BtcAddressType.js +9 -0
  29. package/dist/chains/cosmos/qbtc/claim/BtcAddressType.js.map +1 -0
  30. package/dist/chains/cosmos/qbtc/claim/ClaimableUtxo.d.ts +8 -0
  31. package/dist/chains/cosmos/qbtc/claim/ClaimableUtxo.d.ts.map +1 -0
  32. package/dist/chains/cosmos/qbtc/claim/ClaimableUtxo.js +2 -0
  33. package/dist/chains/cosmos/qbtc/claim/ClaimableUtxo.js.map +1 -0
  34. package/dist/chains/cosmos/qbtc/claim/broadcastClaimTx.d.ts +25 -0
  35. package/dist/chains/cosmos/qbtc/claim/broadcastClaimTx.d.ts.map +1 -0
  36. package/dist/chains/cosmos/qbtc/claim/broadcastClaimTx.js +43 -0
  37. package/dist/chains/cosmos/qbtc/claim/broadcastClaimTx.js.map +1 -0
  38. package/dist/chains/cosmos/qbtc/claim/buildClaimTx.d.ts +26 -0
  39. package/dist/chains/cosmos/qbtc/claim/buildClaimTx.d.ts.map +1 -0
  40. package/dist/chains/cosmos/qbtc/claim/buildClaimTx.js +57 -0
  41. package/dist/chains/cosmos/qbtc/claim/buildClaimTx.js.map +1 -0
  42. package/dist/chains/cosmos/qbtc/claim/computeClaimHashes.d.ts +49 -0
  43. package/dist/chains/cosmos/qbtc/claim/computeClaimHashes.d.ts.map +1 -0
  44. package/dist/chains/cosmos/qbtc/claim/computeClaimHashes.js +85 -0
  45. package/dist/chains/cosmos/qbtc/claim/computeClaimHashes.js.map +1 -0
  46. package/dist/chains/cosmos/qbtc/claim/detectBtcAddressType.d.ts +14 -0
  47. package/dist/chains/cosmos/qbtc/claim/detectBtcAddressType.d.ts.map +1 -0
  48. package/dist/chains/cosmos/qbtc/claim/detectBtcAddressType.js +31 -0
  49. package/dist/chains/cosmos/qbtc/claim/detectBtcAddressType.js.map +1 -0
  50. package/dist/chains/cosmos/qbtc/claim/getClaimWithProofDisabled.d.ts +3 -0
  51. package/dist/chains/cosmos/qbtc/claim/getClaimWithProofDisabled.d.ts.map +1 -0
  52. package/dist/chains/cosmos/qbtc/claim/getClaimWithProofDisabled.js +13 -0
  53. package/dist/chains/cosmos/qbtc/claim/getClaimWithProofDisabled.js.map +1 -0
  54. package/dist/chains/cosmos/qbtc/claim/getClaimableUtxos.d.ts +14 -0
  55. package/dist/chains/cosmos/qbtc/claim/getClaimableUtxos.d.ts.map +1 -0
  56. package/dist/chains/cosmos/qbtc/claim/getClaimableUtxos.js +22 -0
  57. package/dist/chains/cosmos/qbtc/claim/getClaimableUtxos.js.map +1 -0
  58. package/dist/chains/cosmos/qbtc/claim/proofService.d.ts +50 -0
  59. package/dist/chains/cosmos/qbtc/claim/proofService.d.ts.map +1 -0
  60. package/dist/chains/cosmos/qbtc/claim/proofService.js +71 -0
  61. package/dist/chains/cosmos/qbtc/claim/proofService.js.map +1 -0
  62. package/dist/chains/cosmos/qbtc/getQbtcAccountInfo.d.ts +1 -2
  63. package/dist/chains/cosmos/qbtc/getQbtcAccountInfo.d.ts.map +1 -1
  64. package/dist/chains/cosmos/qbtc/getQbtcAccountInfo.js +13 -9
  65. package/dist/chains/cosmos/qbtc/getQbtcAccountInfo.js.map +1 -1
  66. package/dist/chains/cosmos/qbtc/tendermintRpcUrl.d.ts +3 -5
  67. package/dist/chains/cosmos/qbtc/tendermintRpcUrl.d.ts.map +1 -1
  68. package/dist/chains/cosmos/qbtc/tendermintRpcUrl.js +3 -5
  69. package/dist/chains/cosmos/qbtc/tendermintRpcUrl.js.map +1 -1
  70. package/dist/chains/cosmos/sumFeeAmountForCosmosChainFeeDenom.d.ts +15 -0
  71. package/dist/chains/cosmos/sumFeeAmountForCosmosChainFeeDenom.d.ts.map +1 -0
  72. package/dist/chains/cosmos/sumFeeAmountForCosmosChainFeeDenom.js +22 -0
  73. package/dist/chains/cosmos/sumFeeAmountForCosmosChainFeeDenom.js.map +1 -0
  74. package/dist/chains/cosmos/thor/lp/halts.d.ts +56 -0
  75. package/dist/chains/cosmos/thor/lp/halts.d.ts.map +1 -0
  76. package/dist/chains/cosmos/thor/lp/halts.js +95 -0
  77. package/dist/chains/cosmos/thor/lp/halts.js.map +1 -0
  78. package/dist/chains/cosmos/thor/lp/index.d.ts +45 -0
  79. package/dist/chains/cosmos/thor/lp/index.d.ts.map +1 -0
  80. package/dist/chains/cosmos/thor/lp/index.js +12 -0
  81. package/dist/chains/cosmos/thor/lp/index.js.map +1 -0
  82. package/dist/chains/cosmos/thor/lp/lockup.d.ts +47 -0
  83. package/dist/chains/cosmos/thor/lp/lockup.d.ts.map +1 -0
  84. package/dist/chains/cosmos/thor/lp/lockup.js +56 -0
  85. package/dist/chains/cosmos/thor/lp/lockup.js.map +1 -0
  86. package/dist/chains/cosmos/thor/lp/lpChainMap.d.ts +25 -0
  87. package/dist/chains/cosmos/thor/lp/lpChainMap.d.ts.map +1 -0
  88. package/dist/chains/cosmos/thor/lp/lpChainMap.js +30 -0
  89. package/dist/chains/cosmos/thor/lp/lpChainMap.js.map +1 -0
  90. package/dist/chains/cosmos/thor/lp/math.d.ts +129 -0
  91. package/dist/chains/cosmos/thor/lp/math.d.ts.map +1 -0
  92. package/dist/chains/cosmos/thor/lp/math.js +227 -0
  93. package/dist/chains/cosmos/thor/lp/math.js.map +1 -0
  94. package/dist/chains/cosmos/thor/lp/memberPool.d.ts +4 -0
  95. package/dist/chains/cosmos/thor/lp/memberPool.d.ts.map +1 -0
  96. package/dist/chains/cosmos/thor/lp/memberPool.js +24 -0
  97. package/dist/chains/cosmos/thor/lp/memberPool.js.map +1 -0
  98. package/dist/chains/cosmos/thor/lp/memo.d.ts +62 -0
  99. package/dist/chains/cosmos/thor/lp/memo.d.ts.map +1 -0
  100. package/dist/chains/cosmos/thor/lp/memo.js +62 -0
  101. package/dist/chains/cosmos/thor/lp/memo.js.map +1 -0
  102. package/dist/chains/cosmos/thor/lp/pairing.d.ts +30 -0
  103. package/dist/chains/cosmos/thor/lp/pairing.d.ts.map +1 -0
  104. package/dist/chains/cosmos/thor/lp/pairing.js +44 -0
  105. package/dist/chains/cosmos/thor/lp/pairing.js.map +1 -0
  106. package/dist/chains/cosmos/thor/lp/payload.d.ts +66 -0
  107. package/dist/chains/cosmos/thor/lp/payload.d.ts.map +1 -0
  108. package/dist/chains/cosmos/thor/lp/payload.js +49 -0
  109. package/dist/chains/cosmos/thor/lp/payload.js.map +1 -0
  110. package/dist/chains/cosmos/thor/lp/pools.d.ts +46 -0
  111. package/dist/chains/cosmos/thor/lp/pools.d.ts.map +1 -0
  112. package/dist/chains/cosmos/thor/lp/pools.js +85 -0
  113. package/dist/chains/cosmos/thor/lp/pools.js.map +1 -0
  114. package/dist/chains/cosmos/thor/lp/position.d.ts +23 -0
  115. package/dist/chains/cosmos/thor/lp/position.d.ts.map +1 -0
  116. package/dist/chains/cosmos/thor/lp/position.js +105 -0
  117. package/dist/chains/cosmos/thor/lp/position.js.map +1 -0
  118. package/dist/chains/cosmos/thor/lp/positions.d.ts +15 -0
  119. package/dist/chains/cosmos/thor/lp/positions.d.ts.map +1 -0
  120. package/dist/chains/cosmos/thor/lp/positions.js +47 -0
  121. package/dist/chains/cosmos/thor/lp/positions.js.map +1 -0
  122. package/dist/chains/cosmos/thor/lp/types.d.ts +45 -0
  123. package/dist/chains/cosmos/thor/lp/types.d.ts.map +1 -0
  124. package/dist/chains/cosmos/thor/lp/types.js +2 -0
  125. package/dist/chains/cosmos/thor/lp/types.js.map +1 -0
  126. package/dist/chains/cosmos/thor/lp/validation.d.ts +38 -0
  127. package/dist/chains/cosmos/thor/lp/validation.d.ts.map +1 -0
  128. package/dist/chains/cosmos/thor/lp/validation.js +100 -0
  129. package/dist/chains/cosmos/thor/lp/validation.js.map +1 -0
  130. package/dist/chains/polkadot/dapp/PolkadotSignerPayload.d.ts +16 -0
  131. package/dist/chains/polkadot/dapp/PolkadotSignerPayload.d.ts.map +1 -0
  132. package/dist/chains/polkadot/dapp/PolkadotSignerPayload.js +2 -0
  133. package/dist/chains/polkadot/dapp/PolkadotSignerPayload.js.map +1 -0
  134. package/dist/chains/polkadot/dapp/constructSigningPayload.d.ts +12 -0
  135. package/dist/chains/polkadot/dapp/constructSigningPayload.d.ts.map +1 -0
  136. package/dist/chains/polkadot/dapp/constructSigningPayload.js +30 -0
  137. package/dist/chains/polkadot/dapp/constructSigningPayload.js.map +1 -0
  138. package/dist/chains/solana/getDynamicPriorityFeePrice.d.ts +3 -0
  139. package/dist/chains/solana/getDynamicPriorityFeePrice.d.ts.map +1 -0
  140. package/dist/chains/solana/getDynamicPriorityFeePrice.js +20 -0
  141. package/dist/chains/solana/getDynamicPriorityFeePrice.js.map +1 -0
  142. package/dist/chains/solana/jito.d.ts +6 -0
  143. package/dist/chains/solana/jito.d.ts.map +1 -0
  144. package/dist/chains/solana/jito.js +40 -0
  145. package/dist/chains/solana/jito.js.map +1 -0
  146. package/dist/chains/ton/address.d.ts +6 -0
  147. package/dist/chains/ton/address.d.ts.map +1 -0
  148. package/dist/chains/ton/address.js +17 -0
  149. package/dist/chains/ton/address.js.map +1 -0
  150. package/dist/chains/ton/api.d.ts +7 -2
  151. package/dist/chains/ton/api.d.ts.map +1 -1
  152. package/dist/chains/ton/api.js +16 -3
  153. package/dist/chains/ton/api.js.map +1 -1
  154. package/dist/chains/utxo/client/getDashUtxos.d.ts +3 -0
  155. package/dist/chains/utxo/client/getDashUtxos.d.ts.map +1 -0
  156. package/dist/chains/utxo/client/getDashUtxos.js +28 -0
  157. package/dist/chains/utxo/client/getDashUtxos.js.map +1 -0
  158. package/dist/chains/utxo/tx/buildSignBitcoinFromPsbt.d.ts +21 -0
  159. package/dist/chains/utxo/tx/buildSignBitcoinFromPsbt.d.ts.map +1 -0
  160. package/dist/chains/utxo/tx/buildSignBitcoinFromPsbt.js +182 -0
  161. package/dist/chains/utxo/tx/buildSignBitcoinFromPsbt.js.map +1 -0
  162. package/dist/chains/utxo/tx/getPsbtTransferInfo.js +1 -1
  163. package/dist/chains/utxo/tx/getPsbtTransferInfo.js.map +1 -1
  164. package/dist/chains/utxo/tx/getUtxos.d.ts.map +1 -1
  165. package/dist/chains/utxo/tx/getUtxos.js +5 -0
  166. package/dist/chains/utxo/tx/getUtxos.js.map +1 -1
  167. package/dist/coin/balance/resolvers/cardano.d.ts +1 -0
  168. package/dist/coin/balance/resolvers/cardano.d.ts.map +1 -1
  169. package/dist/coin/balance/resolvers/cardano.js +12 -0
  170. package/dist/coin/balance/resolvers/cardano.js.map +1 -1
  171. package/dist/coin/balance/resolvers/qbtc.d.ts.map +1 -1
  172. package/dist/coin/balance/resolvers/qbtc.js +6 -5
  173. package/dist/coin/balance/resolvers/qbtc.js.map +1 -1
  174. package/dist/coin/balance/resolvers/sui.d.ts.map +1 -1
  175. package/dist/coin/balance/resolvers/sui.js +1 -0
  176. package/dist/coin/balance/resolvers/sui.js.map +1 -1
  177. package/dist/coin/balance/resolvers/ton.d.ts.map +1 -1
  178. package/dist/coin/balance/resolvers/ton.js +11 -2
  179. package/dist/coin/balance/resolvers/ton.js.map +1 -1
  180. package/dist/coin/find/CoinFinderChainKind.d.ts +1 -1
  181. package/dist/coin/find/CoinFinderChainKind.d.ts.map +1 -1
  182. package/dist/coin/find/CoinFinderChainKind.js +1 -1
  183. package/dist/coin/find/CoinFinderChainKind.js.map +1 -1
  184. package/dist/coin/find/index.d.ts.map +1 -1
  185. package/dist/coin/find/index.js +2 -0
  186. package/dist/coin/find/index.js.map +1 -1
  187. package/dist/coin/find/resolvers/cardano.d.ts +5 -0
  188. package/dist/coin/find/resolvers/cardano.d.ts.map +1 -0
  189. package/dist/coin/find/resolvers/cardano.js +17 -0
  190. package/dist/coin/find/resolvers/cardano.js.map +1 -0
  191. package/dist/coin/knownTokens/index.d.ts.map +1 -1
  192. package/dist/coin/knownTokens/index.js +74 -0
  193. package/dist/coin/knownTokens/index.js.map +1 -1
  194. package/dist/coin/token/metadata/chains.d.ts +1 -1
  195. package/dist/coin/token/metadata/chains.d.ts.map +1 -1
  196. package/dist/coin/token/metadata/chains.js +1 -0
  197. package/dist/coin/token/metadata/chains.js.map +1 -1
  198. package/dist/coin/token/metadata/index.d.ts.map +1 -1
  199. package/dist/coin/token/metadata/index.js +2 -0
  200. package/dist/coin/token/metadata/index.js.map +1 -1
  201. package/dist/coin/token/metadata/resolvers/cardano.d.ts +8 -0
  202. package/dist/coin/token/metadata/resolvers/cardano.d.ts.map +1 -0
  203. package/dist/coin/token/metadata/resolvers/cardano.js +20 -0
  204. package/dist/coin/token/metadata/resolvers/cardano.js.map +1 -0
  205. package/dist/swap/native/utils/getNativeSwapDecimals.d.ts +8 -0
  206. package/dist/swap/native/utils/getNativeSwapDecimals.d.ts.map +1 -1
  207. package/dist/swap/native/utils/getNativeSwapDecimals.js +19 -4
  208. package/dist/swap/native/utils/getNativeSwapDecimals.js.map +1 -1
  209. package/dist/tx/broadcast/resolvers/qbtc.d.ts.map +1 -1
  210. package/dist/tx/broadcast/resolvers/qbtc.js +22 -5
  211. package/dist/tx/broadcast/resolvers/qbtc.js.map +1 -1
  212. package/dist/tx/broadcast/resolvers/solana.d.ts.map +1 -1
  213. package/dist/tx/broadcast/resolvers/solana.js +12 -1
  214. package/dist/tx/broadcast/resolvers/solana.js.map +1 -1
  215. package/dist/tx/hash/resolvers/cardano.d.ts.map +1 -1
  216. package/dist/tx/hash/resolvers/cardano.js +9 -5
  217. package/dist/tx/hash/resolvers/cardano.js.map +1 -1
  218. package/dist/tx/status/resolvers/cosmos.d.ts.map +1 -1
  219. package/dist/tx/status/resolvers/cosmos.js +21 -8
  220. package/dist/tx/status/resolvers/cosmos.js.map +1 -1
  221. package/dist/tx/status/resolvers/qbtc.d.ts.map +1 -1
  222. package/dist/tx/status/resolvers/qbtc.js +18 -19
  223. package/dist/tx/status/resolvers/qbtc.js.map +1 -1
  224. package/dist/tx/status/resolvers/ton.d.ts.map +1 -1
  225. package/dist/tx/status/resolvers/ton.js +4 -4
  226. package/dist/tx/status/resolvers/ton.js.map +1 -1
  227. 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"}