@vultisig/core-chain 1.1.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 +42 -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/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/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 +34 -11
- package/dist/chains/cosmos/thor/lp/index.d.ts.map +1 -1
- package/dist/chains/cosmos/thor/lp/index.js +9 -15
- package/dist/chains/cosmos/thor/lp/index.js.map +1 -1
- 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 +38 -17
- package/dist/chains/cosmos/thor/lp/memo.d.ts.map +1 -1
- package/dist/chains/cosmos/thor/lp/memo.js +40 -16
- package/dist/chains/cosmos/thor/lp/memo.js.map +1 -1
- 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 +30 -10
- package/dist/chains/cosmos/thor/lp/payload.d.ts.map +1 -1
- package/dist/chains/cosmos/thor/lp/payload.js +30 -18
- package/dist/chains/cosmos/thor/lp/payload.js.map +1 -1
- package/dist/chains/cosmos/thor/lp/position.d.ts +15 -22
- package/dist/chains/cosmos/thor/lp/position.d.ts.map +1 -1
- package/dist/chains/cosmos/thor/lp/position.js +82 -35
- package/dist/chains/cosmos/thor/lp/position.js.map +1 -1
- 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 +32 -7
- package/dist/chains/cosmos/thor/lp/validation.d.ts.map +1 -1
- package/dist/chains/cosmos/thor/lp/validation.js +76 -11
- package/dist/chains/cosmos/thor/lp/validation.js.map +1 -1
- 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/package.json +90 -5
- package/dist/chains/cosmos/thor/lp/affiliate.d.ts +0 -16
- package/dist/chains/cosmos/thor/lp/affiliate.d.ts.map +0 -1
- package/dist/chains/cosmos/thor/lp/affiliate.js +0 -16
- package/dist/chains/cosmos/thor/lp/affiliate.js.map +0 -1
|
@@ -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"}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Flat unsigned-transaction payload for an asymmetric RUNE-side LP add.
|
|
3
3
|
*
|
|
4
|
-
* Shape stays single-nesting-level on purpose: this object
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
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
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.
|
|
9
13
|
*/
|
|
10
14
|
export type ThorchainLpAddPayload = {
|
|
11
15
|
kind: 'thorchain_lp_add';
|
|
@@ -17,10 +21,11 @@ export type ThorchainLpAddPayload = {
|
|
|
17
21
|
memo: string;
|
|
18
22
|
/** Canonical pool id, denormalized for display. */
|
|
19
23
|
pool: string;
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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;
|
|
24
29
|
};
|
|
25
30
|
export type ThorchainLpRemovePayload = {
|
|
26
31
|
kind: 'thorchain_lp_remove';
|
|
@@ -32,15 +37,30 @@ export type ThorchainLpRemovePayload = {
|
|
|
32
37
|
memo: string;
|
|
33
38
|
pool: string;
|
|
34
39
|
basisPoints: number;
|
|
40
|
+
/**
|
|
41
|
+
* Asym-withdraw target asset, if any. Denormalized for display.
|
|
42
|
+
*/
|
|
43
|
+
withdrawToAsset?: string;
|
|
35
44
|
};
|
|
36
45
|
export type BuildThorchainLpAddPayloadInput = {
|
|
37
46
|
pool: string;
|
|
38
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;
|
|
39
54
|
};
|
|
40
|
-
export declare const buildThorchainLpAddPayload: ({ pool, amountRuneBaseUnits, }: BuildThorchainLpAddPayloadInput) => ThorchainLpAddPayload;
|
|
55
|
+
export declare const buildThorchainLpAddPayload: ({ pool, amountRuneBaseUnits, pairedAddress, }: BuildThorchainLpAddPayloadInput) => ThorchainLpAddPayload;
|
|
41
56
|
export type BuildThorchainLpRemovePayloadInput = {
|
|
42
57
|
pool: string;
|
|
43
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;
|
|
44
64
|
};
|
|
45
|
-
export declare const buildThorchainLpRemovePayload: ({ pool, basisPoints, }: BuildThorchainLpRemovePayloadInput) => ThorchainLpRemovePayload;
|
|
65
|
+
export declare const buildThorchainLpRemovePayload: ({ pool, basisPoints, withdrawToAsset, }: BuildThorchainLpRemovePayloadInput) => ThorchainLpRemovePayload;
|
|
46
66
|
//# sourceMappingURL=payload.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/payload.ts"],"names":[],"mappings":"
|
|
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"}
|
|
@@ -1,37 +1,49 @@
|
|
|
1
|
-
import { VULTISIG_AFFILIATE_LP_BPS, VULTISIG_AFFILIATE_NAME, } from './affiliate.js';
|
|
2
1
|
import { addLpMemo, removeLpMemo } from './memo.js';
|
|
3
2
|
/**
|
|
4
3
|
* Dust amount used for LP removes.
|
|
5
4
|
*
|
|
6
|
-
* Reference: vultisig-windows
|
|
7
|
-
*
|
|
8
|
-
* dust
|
|
9
|
-
*
|
|
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
10
|
*/
|
|
11
11
|
const LP_REMOVE_DUST_RUNE_BASE_UNITS = '2000000';
|
|
12
12
|
const isPositiveBaseUnitString = (value) => /^\d+$/.test(value) && BigInt(value) > 0n;
|
|
13
|
-
export const buildThorchainLpAddPayload = ({ pool, amountRuneBaseUnits, }) => {
|
|
13
|
+
export const buildThorchainLpAddPayload = ({ pool, amountRuneBaseUnits, pairedAddress, }) => {
|
|
14
14
|
if (!isPositiveBaseUnitString(amountRuneBaseUnits)) {
|
|
15
15
|
throw new Error(`buildThorchainLpAddPayload: amountRuneBaseUnits must be a positive integer string, got ${amountRuneBaseUnits}`);
|
|
16
16
|
}
|
|
17
|
+
const memo = addLpMemo({ pool, pairedAddress });
|
|
17
18
|
return {
|
|
18
19
|
kind: 'thorchain_lp_add',
|
|
19
20
|
chain: 'THORChain',
|
|
20
21
|
denom: 'rune',
|
|
21
22
|
amount: amountRuneBaseUnits,
|
|
22
|
-
memo
|
|
23
|
+
memo,
|
|
23
24
|
pool,
|
|
24
|
-
|
|
25
|
-
|
|
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 } : {}),
|
|
26
47
|
};
|
|
27
48
|
};
|
|
28
|
-
export const buildThorchainLpRemovePayload = ({ pool, basisPoints, }) => ({
|
|
29
|
-
kind: 'thorchain_lp_remove',
|
|
30
|
-
chain: 'THORChain',
|
|
31
|
-
denom: 'rune',
|
|
32
|
-
amount: LP_REMOVE_DUST_RUNE_BASE_UNITS,
|
|
33
|
-
memo: removeLpMemo({ pool, basisPoints }),
|
|
34
|
-
pool,
|
|
35
|
-
basisPoints,
|
|
36
|
-
});
|
|
37
49
|
//# sourceMappingURL=payload.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payload.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/payload.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
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"}
|
|
@@ -1,30 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* many more fields per position — we keep just the ones the agent stack
|
|
4
|
-
* surfaces in chat (units, added amounts, pending state, last-add timestamp).
|
|
5
|
-
*/
|
|
6
|
-
export type ThorchainLpPosition = {
|
|
7
|
-
pool: string;
|
|
8
|
-
liquidityUnits: string;
|
|
9
|
-
runeAdded: string;
|
|
10
|
-
assetAdded: string;
|
|
11
|
-
runePending: string;
|
|
12
|
-
assetPending: string;
|
|
13
|
-
runeAddress: string;
|
|
14
|
-
assetAddress: string;
|
|
15
|
-
/** Unix seconds (Midgard returns it as a string). */
|
|
16
|
-
dateLastAdded: string;
|
|
17
|
-
/**
|
|
18
|
-
* True when either side has a non-zero pending amount. Common for
|
|
19
|
-
* asymmetric adds that THORChain has not yet credited.
|
|
20
|
-
*/
|
|
21
|
-
isPending: boolean;
|
|
22
|
-
};
|
|
1
|
+
import type { ThorchainLpPosition } from './types.js';
|
|
2
|
+
export type { ThorchainLpPosition } from './types.js';
|
|
23
3
|
export type GetThorchainLpPositionInput = {
|
|
24
4
|
/** bech32 thor1... address (the RUNE side of the position). */
|
|
25
5
|
thorAddress: string;
|
|
26
6
|
/** Canonical pool id to look up. */
|
|
27
7
|
pool: string;
|
|
28
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* Fetch a single LP position from Midgard.
|
|
11
|
+
*
|
|
12
|
+
* Returns `null` when:
|
|
13
|
+
* - the address has no positions at all (Midgard returns 404), or
|
|
14
|
+
* - the address has positions but none in the requested pool.
|
|
15
|
+
*/
|
|
29
16
|
export declare const getThorchainLpPosition: ({ thorAddress, pool, }: GetThorchainLpPositionInput) => Promise<ThorchainLpPosition | null>;
|
|
17
|
+
/**
|
|
18
|
+
* Fetch a single LP position directly from thornode. Catches the
|
|
19
|
+
* pending-only case Midgard doesn't surface. Returns null when the
|
|
20
|
+
* position is truly empty (no units, no pending on either side).
|
|
21
|
+
*/
|
|
22
|
+
export declare const getThorchainLpPositionFromThornode: ({ thorAddress, pool, }: GetThorchainLpPositionInput) => Promise<ThorchainLpPosition | null>;
|
|
30
23
|
//# sourceMappingURL=position.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"position.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/position.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"position.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/position.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAqB,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAErE,YAAY,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAElD,MAAM,MAAM,2BAA2B,GAAG;IACxC,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAA;IACnB,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAWD;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GAAU,wBAG1C,2BAA2B,KAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CA2BlE,CAAA;AAaD;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,GAAU,wBAGtD,2BAA2B,KAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAkDlE,CAAA"}
|
|
@@ -1,35 +1,9 @@
|
|
|
1
|
+
import { Chain } from '@vultisig/core-chain/Chain';
|
|
2
|
+
import { cosmosRpcUrl } from '@vultisig/core-chain/chains/cosmos/cosmosRpcUrl';
|
|
1
3
|
import { HttpResponseError } from '@vultisig/lib-utils/fetch/HttpResponseError';
|
|
2
4
|
import { queryUrl } from '@vultisig/lib-utils/query/queryUrl';
|
|
5
|
+
import { isNonZeroBaseUnit, normalizeMemberPool } from './memberPool.js';
|
|
3
6
|
import { assertValidPoolId, thorchainMidgardBaseUrl } from './pools.js';
|
|
4
|
-
const isNonZero = (s) => {
|
|
5
|
-
if (!s)
|
|
6
|
-
return false;
|
|
7
|
-
try {
|
|
8
|
-
return BigInt(s) > 0n;
|
|
9
|
-
}
|
|
10
|
-
catch {
|
|
11
|
-
return false;
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
const normalizeMemberPool = (raw) => ({
|
|
15
|
-
pool: raw.pool ?? '',
|
|
16
|
-
liquidityUnits: raw.liquidityUnits ?? '0',
|
|
17
|
-
runeAdded: raw.runeAdded ?? '0',
|
|
18
|
-
assetAdded: raw.assetAdded ?? '0',
|
|
19
|
-
runePending: raw.runePending ?? '0',
|
|
20
|
-
assetPending: raw.assetPending ?? '0',
|
|
21
|
-
runeAddress: raw.runeAddress ?? '',
|
|
22
|
-
assetAddress: raw.assetAddress ?? '',
|
|
23
|
-
dateLastAdded: raw.dateLastAdded ?? '0',
|
|
24
|
-
isPending: isNonZero(raw.runePending) || isNonZero(raw.assetPending),
|
|
25
|
-
});
|
|
26
|
-
/**
|
|
27
|
-
* Fetch a single LP position from Midgard.
|
|
28
|
-
*
|
|
29
|
-
* Returns `null` when:
|
|
30
|
-
* - the address has no positions at all (Midgard returns 404), or
|
|
31
|
-
* - the address has positions but none in the requested pool.
|
|
32
|
-
*/
|
|
33
7
|
/**
|
|
34
8
|
* Detect a 404 from queryUrl by reading the typed `HttpResponseError.status`
|
|
35
9
|
* field that `@vultisig/lib-utils` `assertFetchResponse` now throws. The
|
|
@@ -37,22 +11,95 @@ const normalizeMemberPool = (raw) => ({
|
|
|
37
11
|
* but was brittle to wording changes. See NeoMakinG's PR #236 review note.
|
|
38
12
|
*/
|
|
39
13
|
const isMidgardNotFoundError = (err) => err instanceof HttpResponseError && err.status === 404;
|
|
14
|
+
/**
|
|
15
|
+
* Fetch a single LP position from Midgard.
|
|
16
|
+
*
|
|
17
|
+
* Returns `null` when:
|
|
18
|
+
* - the address has no positions at all (Midgard returns 404), or
|
|
19
|
+
* - the address has positions but none in the requested pool.
|
|
20
|
+
*/
|
|
40
21
|
export const getThorchainLpPosition = async ({ thorAddress, pool, }) => {
|
|
41
22
|
assertValidPoolId(pool);
|
|
42
23
|
const url = `${thorchainMidgardBaseUrl}/v2/member/${encodeURIComponent(thorAddress)}`;
|
|
24
|
+
let midgardNotFound = false;
|
|
25
|
+
let raw = {};
|
|
26
|
+
try {
|
|
27
|
+
raw = await queryUrl(url);
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
if (isMidgardNotFoundError(err)) {
|
|
31
|
+
midgardNotFound = true;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
throw err;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (!midgardNotFound) {
|
|
38
|
+
const pools = Array.isArray(raw.pools) ? raw.pools : [];
|
|
39
|
+
const found = pools.find(p => p.pool === pool);
|
|
40
|
+
if (found)
|
|
41
|
+
return normalizeMemberPool(found);
|
|
42
|
+
}
|
|
43
|
+
// Midgard has no record of this pool for this address. THORChain
|
|
44
|
+
// asymmetric adds land as `pending_rune` / `pending_asset` on thornode
|
|
45
|
+
// and stay off Midgard until the counter-side materializes the LP (or a
|
|
46
|
+
// pending-timeout flips the state). A pending-only position is still
|
|
47
|
+
// fully withdrawable via `-:POOL:BPS` — the handler refunds the pending
|
|
48
|
+
// side. Falling back to thornode here so the LLM sees the position and
|
|
49
|
+
// doesn't wrongly tell the user "nothing to withdraw".
|
|
50
|
+
return getThorchainLpPositionFromThornode({ thorAddress, pool });
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Fetch a single LP position directly from thornode. Catches the
|
|
54
|
+
* pending-only case Midgard doesn't surface. Returns null when the
|
|
55
|
+
* position is truly empty (no units, no pending on either side).
|
|
56
|
+
*/
|
|
57
|
+
export const getThorchainLpPositionFromThornode = async ({ thorAddress, pool, }) => {
|
|
58
|
+
assertValidPoolId(pool);
|
|
59
|
+
const url = `${cosmosRpcUrl[Chain.THORChain]}/thorchain/pool/${encodeURIComponent(pool)}` +
|
|
60
|
+
`/liquidity_provider/${encodeURIComponent(thorAddress)}`;
|
|
43
61
|
let raw;
|
|
44
62
|
try {
|
|
45
63
|
raw = await queryUrl(url);
|
|
46
64
|
}
|
|
47
65
|
catch (err) {
|
|
48
|
-
//
|
|
49
|
-
// "no position"
|
|
50
|
-
if (
|
|
66
|
+
// thornode returns 404 when no LP record exists for the address on
|
|
67
|
+
// this pool. Treat as "no position" same as Midgard.
|
|
68
|
+
if (err instanceof HttpResponseError && err.status === 404)
|
|
51
69
|
return null;
|
|
52
70
|
throw err;
|
|
53
71
|
}
|
|
54
|
-
const
|
|
55
|
-
const
|
|
56
|
-
|
|
72
|
+
const units = raw.units ?? '0';
|
|
73
|
+
const pendingRune = raw.pending_rune ?? '0';
|
|
74
|
+
const pendingAsset = raw.pending_asset ?? '0';
|
|
75
|
+
// Thornode always returns the endpoint with zeroed fields after a full
|
|
76
|
+
// withdraw, so explicitly guard "everything is zero" as "no position".
|
|
77
|
+
if (!isNonZeroBaseUnit(units) &&
|
|
78
|
+
!isNonZeroBaseUnit(pendingRune) &&
|
|
79
|
+
!isNonZeroBaseUnit(pendingAsset)) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
pool: raw.asset ?? pool,
|
|
84
|
+
liquidityUnits: units,
|
|
85
|
+
// Thornode doesn't track historical added amounts — those are a
|
|
86
|
+
// Midgard-only enrichment. Surface them as 0; the caller can still
|
|
87
|
+
// act on units/pending.
|
|
88
|
+
runeAdded: '0',
|
|
89
|
+
assetAdded: '0',
|
|
90
|
+
runePending: pendingRune,
|
|
91
|
+
assetPending: pendingAsset,
|
|
92
|
+
runeAddress: raw.rune_address ?? thorAddress,
|
|
93
|
+
assetAddress: raw.asset_address ?? '',
|
|
94
|
+
// Thornode exposes the last-add block height, not a Unix timestamp.
|
|
95
|
+
// Keep `dateLastAdded` semantically Unix-seconds-or-0 and expose the
|
|
96
|
+
// block height via the dedicated `lastAddHeight` field so lockup
|
|
97
|
+
// checks can use either source.
|
|
98
|
+
dateLastAdded: '0',
|
|
99
|
+
lastAddHeight: typeof raw.last_add_height === 'number'
|
|
100
|
+
? String(raw.last_add_height)
|
|
101
|
+
: '',
|
|
102
|
+
isPending: isNonZeroBaseUnit(pendingRune) || isNonZeroBaseUnit(pendingAsset),
|
|
103
|
+
};
|
|
57
104
|
};
|
|
58
105
|
//# sourceMappingURL=position.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"position.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/position.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAA;AAC/E,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAE7D,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"position.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/position.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ThorchainLpPosition } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Fetch every LP position for a THORChain address in a single Midgard call.
|
|
4
|
+
*
|
|
5
|
+
* Returns an empty array when:
|
|
6
|
+
* - the address has no positions at all (Midgard returns 404), or
|
|
7
|
+
* - Midgard returns a body without a `pools` array (defensive).
|
|
8
|
+
*
|
|
9
|
+
* Prefer this over calling `getThorchainLpPosition` N times — one HTTP
|
|
10
|
+
* round-trip regardless of position count.
|
|
11
|
+
*/
|
|
12
|
+
export declare const getThorchainLpPositions: ({ thorAddress, }: {
|
|
13
|
+
thorAddress: string;
|
|
14
|
+
}) => Promise<ThorchainLpPosition[]>;
|
|
15
|
+
//# sourceMappingURL=positions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"positions.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/positions.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAqB,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAErE;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,GAAU,kBAE3C;IACD,WAAW,EAAE,MAAM,CAAA;CACpB,KAAG,OAAO,CAAC,mBAAmB,EAAE,CAiChC,CAAA"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { HttpResponseError } from '@vultisig/lib-utils/fetch/HttpResponseError';
|
|
2
|
+
import { queryUrl } from '@vultisig/lib-utils/query/queryUrl';
|
|
3
|
+
import { normalizeMemberPool } from './memberPool.js';
|
|
4
|
+
import { thorchainMidgardBaseUrl } from './pools.js';
|
|
5
|
+
/**
|
|
6
|
+
* Fetch every LP position for a THORChain address in a single Midgard call.
|
|
7
|
+
*
|
|
8
|
+
* Returns an empty array when:
|
|
9
|
+
* - the address has no positions at all (Midgard returns 404), or
|
|
10
|
+
* - Midgard returns a body without a `pools` array (defensive).
|
|
11
|
+
*
|
|
12
|
+
* Prefer this over calling `getThorchainLpPosition` N times — one HTTP
|
|
13
|
+
* round-trip regardless of position count.
|
|
14
|
+
*/
|
|
15
|
+
export const getThorchainLpPositions = async ({ thorAddress, }) => {
|
|
16
|
+
const url = `${thorchainMidgardBaseUrl}/v2/member/${encodeURIComponent(thorAddress)}`;
|
|
17
|
+
let raw;
|
|
18
|
+
try {
|
|
19
|
+
raw = await queryUrl(url);
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
if (err instanceof HttpResponseError && err.status === 404)
|
|
23
|
+
return [];
|
|
24
|
+
throw err;
|
|
25
|
+
}
|
|
26
|
+
// Shape gates on the 200 response:
|
|
27
|
+
// - `raw` must be an object (not null, not a primitive, not an array of
|
|
28
|
+
// something unrelated) — otherwise the upstream shape is unrecognizable
|
|
29
|
+
// and we throw so the caller sees a real error.
|
|
30
|
+
// - `raw.pools` is allowed to be missing (treated as "no positions")
|
|
31
|
+
// for backward compat with the pre-404 era, when Midgard would
|
|
32
|
+
// return `{}` for known-empty addresses. A missing `pools` key is
|
|
33
|
+
// NOT treated as schema drift.
|
|
34
|
+
// - `raw.pools` MUST be an array if present — a non-array `pools`
|
|
35
|
+
// IS schema drift and we throw.
|
|
36
|
+
if (!raw || typeof raw !== 'object') {
|
|
37
|
+
throw new Error(`getThorchainLpPositions: unexpected Midgard response shape from ${url}`);
|
|
38
|
+
}
|
|
39
|
+
if (raw.pools === undefined) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
if (!Array.isArray(raw.pools)) {
|
|
43
|
+
throw new Error(`getThorchainLpPositions: Midgard response ${url} has non-array \`pools\` field`);
|
|
44
|
+
}
|
|
45
|
+
return raw.pools.map(normalizeMemberPool);
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=positions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"positions.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/positions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAA;AAC/E,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAE7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA;AAGjD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,EAAE,EAC5C,WAAW,GAGZ,EAAkC,EAAE;IACnC,MAAM,GAAG,GAAG,GAAG,uBAAuB,cAAc,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAA;IACrF,IAAI,GAAsB,CAAA;IAC1B,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAoB,GAAG,CAAC,CAAA;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,iBAAiB,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,EAAE,CAAA;QACrE,MAAM,GAAG,CAAA;IACX,CAAC;IACD,mCAAmC;IACnC,0EAA0E;IAC1E,4EAA4E;IAC5E,oDAAoD;IACpD,uEAAuE;IACvE,mEAAmE;IACnE,sEAAsE;IACtE,mCAAmC;IACnC,oEAAoE;IACpE,oCAAoC;IACpC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CACb,mEAAmE,GAAG,EAAE,CACzE,CAAA;IACH,CAAC;IACD,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,EAAE,CAAA;IACX,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CACb,6CAA6C,GAAG,gCAAgC,CACjF,CAAA;IACH,CAAC;IACD,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAA;AAC3C,CAAC,CAAA"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export type ThorchainLpPosition = {
|
|
2
|
+
pool: string;
|
|
3
|
+
liquidityUnits: string;
|
|
4
|
+
runeAdded: string;
|
|
5
|
+
assetAdded: string;
|
|
6
|
+
runePending: string;
|
|
7
|
+
assetPending: string;
|
|
8
|
+
runeAddress: string;
|
|
9
|
+
assetAddress: string;
|
|
10
|
+
/**
|
|
11
|
+
* Unix seconds of the last add. Midgard returns this; thornode does not,
|
|
12
|
+
* so positions sourced from the thornode fallback leave this as `"0"` and
|
|
13
|
+
* populate `lastAddHeight` instead.
|
|
14
|
+
*/
|
|
15
|
+
dateLastAdded: string;
|
|
16
|
+
/**
|
|
17
|
+
* THORChain block height of the last add. Populated from thornode's
|
|
18
|
+
* `last_add_height` when the position comes from the thornode fallback
|
|
19
|
+
* path. Empty string when the position comes from Midgard (which does not
|
|
20
|
+
* expose block height on `/v2/member`). Either field is sufficient to gate
|
|
21
|
+
* the 1h lockup check — `dateLastAdded` via wall-clock window, or
|
|
22
|
+
* `lastAddHeight` via block-count window.
|
|
23
|
+
*/
|
|
24
|
+
lastAddHeight: string;
|
|
25
|
+
/**
|
|
26
|
+
* True when either side has a non-zero pending amount. Common for
|
|
27
|
+
* asymmetric adds that THORChain has not yet credited.
|
|
28
|
+
*/
|
|
29
|
+
isPending: boolean;
|
|
30
|
+
};
|
|
31
|
+
export type RawMemberPool = {
|
|
32
|
+
pool?: string;
|
|
33
|
+
liquidityUnits?: string;
|
|
34
|
+
runeAdded?: string;
|
|
35
|
+
assetAdded?: string;
|
|
36
|
+
runePending?: string;
|
|
37
|
+
assetPending?: string;
|
|
38
|
+
runeAddress?: string;
|
|
39
|
+
assetAddress?: string;
|
|
40
|
+
dateLastAdded?: string;
|
|
41
|
+
};
|
|
42
|
+
export type RawMemberResponse = {
|
|
43
|
+
pools?: RawMemberPool[];
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAA;IACrB;;;;;;;OAOG;IACH,aAAa,EAAE,MAAM,CAAA;IACrB;;;OAGG;IACH,SAAS,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,CAAC,EAAE,aAAa,EAAE,CAAA;CACxB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/types.ts"],"names":[],"mappings":""}
|
|
@@ -1,13 +1,38 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Build the mimir flag key THORChain uses to pause LP deposits for a
|
|
3
|
+
* single pool. Format: `PAUSELPDEPOSIT-{CHAIN}-{ASSET_PLUS_CONTRACT}`.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Examples:
|
|
6
|
+
* BTC.BTC → PAUSELPDEPOSIT-BTC-BTC
|
|
7
|
+
* DOGE.DOGE → PAUSELPDEPOSIT-DOGE-DOGE
|
|
8
|
+
* ETH.USDC-0XA0B... → PAUSELPDEPOSIT-ETH-USDC-0XA0B...
|
|
7
9
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
10
|
+
* Note: `CHAIN.ASSET` splits on the FIRST `.`; the rest (including any
|
|
11
|
+
* `-CONTRACT` suffix) is the asset portion, which is appended with a
|
|
12
|
+
* single `-` separator.
|
|
13
|
+
*/
|
|
14
|
+
export declare const poolPauseMimirKey: (pool: string) => string;
|
|
15
|
+
/**
|
|
16
|
+
* Fetch the raw thornode mimir map. Returns an object with flag keys as
|
|
17
|
+
* numbers. Used to check per-pool LP deposit pauses (PAUSELPDEPOSIT-*),
|
|
18
|
+
* liquidity lockup (LIQUIDITYLOCKUPBLOCKS), etc.
|
|
19
|
+
*/
|
|
20
|
+
export declare const getThorchainMimir: () => Promise<Record<string, number>>;
|
|
21
|
+
/**
|
|
22
|
+
* Verify a THORChain pool is currently depositable. Checks TWO layers:
|
|
23
|
+
*
|
|
24
|
+
* 1. **Thornode pool status** — `/thorchain/pool/{asset}.status` must be
|
|
25
|
+
* `Available`. Catches staged / suspended pools.
|
|
26
|
+
* 2. **Mimir per-pool pause flag** — `PAUSELPDEPOSIT-{chain}-{asset}`
|
|
27
|
+
* must not be set. Catches the case where the pool is listed as
|
|
28
|
+
* available BUT the THORChain handler rejects LP adds for it via
|
|
29
|
+
* mimir (what happened to BTC.BTC on 2026-04-10: pool.status was
|
|
30
|
+
* `Available`, deposits silently accepted into mempool, handler
|
|
31
|
+
* rejected at execution with "deposits are paused for asset
|
|
32
|
+
* (btc.btc): internal error"). Without the mimir check, the user
|
|
33
|
+
* signs a tx that is guaranteed to fail on-chain.
|
|
34
|
+
*
|
|
35
|
+
* Use this as the fail-fast gate before building an LP add payload.
|
|
11
36
|
*/
|
|
12
37
|
export declare const assertPoolDepositable: (pool: string) => Promise<void>;
|
|
13
38
|
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/validation.ts"],"names":[],"mappings":"AAcA
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/thor/lp/validation.ts"],"names":[],"mappings":"AAcA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,KAAG,MAQhD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,QAAa,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAsBxE,CAAA;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,qBAAqB,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,IAAI,CAiCtE,CAAA"}
|