@vultisig/core-chain 2.29.3 → 2.31.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 (97) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/Chain.d.ts +3 -0
  3. package/dist/Chain.d.ts.map +1 -1
  4. package/dist/Chain.js +1 -0
  5. package/dist/Chain.js.map +1 -1
  6. package/dist/ChainKind.d.ts +1 -0
  7. package/dist/ChainKind.d.ts.map +1 -1
  8. package/dist/ChainKind.js +1 -0
  9. package/dist/ChainKind.js.map +1 -1
  10. package/dist/chains/cosmos/thor/getThorchainTxResult.d.ts +32 -0
  11. package/dist/chains/cosmos/thor/getThorchainTxResult.d.ts.map +1 -0
  12. package/dist/chains/cosmos/thor/getThorchainTxResult.js +43 -0
  13. package/dist/chains/cosmos/thor/getThorchainTxResult.js.map +1 -0
  14. package/dist/chains/evm/chainInfo.d.ts +54 -0
  15. package/dist/chains/evm/chainInfo.d.ts.map +1 -1
  16. package/dist/chains/evm/chainInfo.js +22 -0
  17. package/dist/chains/evm/chainInfo.js.map +1 -1
  18. package/dist/chains/evm/tx/fee/index.d.ts.map +1 -1
  19. package/dist/chains/evm/tx/fee/index.js +1 -0
  20. package/dist/chains/evm/tx/fee/index.js.map +1 -1
  21. package/dist/coin/coinType.d.ts.map +1 -1
  22. package/dist/coin/coinType.js +1 -0
  23. package/dist/coin/coinType.js.map +1 -1
  24. package/dist/coin/find/resolvers/evm/index.d.ts.map +1 -1
  25. package/dist/coin/find/resolvers/evm/index.js +31 -2
  26. package/dist/coin/find/resolvers/evm/index.js.map +1 -1
  27. package/dist/coin/knownTokens/index.d.ts +1 -1
  28. package/dist/coin/knownTokens/index.d.ts.map +1 -1
  29. package/dist/coin/knownTokens/index.js +506 -0
  30. package/dist/coin/knownTokens/index.js.map +1 -1
  31. package/dist/coin/price/evm/getErc20Prices.d.ts.map +1 -1
  32. package/dist/coin/price/evm/getErc20Prices.js +1 -0
  33. package/dist/coin/price/evm/getErc20Prices.js.map +1 -1
  34. package/dist/coin/token/metadata/chains.d.ts +1 -1
  35. package/dist/coin/token/metadata/chains.d.ts.map +1 -1
  36. package/dist/security/blockaid/evmChains.d.ts.map +1 -1
  37. package/dist/security/blockaid/evmChains.js +2 -0
  38. package/dist/security/blockaid/evmChains.js.map +1 -1
  39. package/dist/swap/general/knownAggregatorRouters.d.ts.map +1 -1
  40. package/dist/swap/general/knownAggregatorRouters.js +7 -1
  41. package/dist/swap/general/knownAggregatorRouters.js.map +1 -1
  42. package/dist/swap/general/kyber/chains.d.ts +1 -1
  43. package/dist/swap/general/kyber/chains.d.ts.map +1 -1
  44. package/dist/swap/general/kyber/chains.js +1 -0
  45. package/dist/swap/general/kyber/chains.js.map +1 -1
  46. package/dist/swap/general/lifi/LifiSwapEnabledChains.d.ts +1 -1
  47. package/dist/swap/general/lifi/LifiSwapEnabledChains.d.ts.map +1 -1
  48. package/dist/swap/general/oneInch/OneInchSwapEnabledChains.d.ts +1 -1
  49. package/dist/swap/general/oneInch/OneInchSwapEnabledChains.d.ts.map +1 -1
  50. package/dist/swap/general/oneInch/OneInchSwapEnabledChains.js +3 -0
  51. package/dist/swap/general/oneInch/OneInchSwapEnabledChains.js.map +1 -1
  52. package/dist/swap/general/swapkit/api/getSwapKitQuote.d.ts.map +1 -1
  53. package/dist/swap/general/swapkit/api/getSwapKitQuote.js +72 -15
  54. package/dist/swap/general/swapkit/api/getSwapKitQuote.js.map +1 -1
  55. package/dist/swap/native/limitSwapCancelBucket.d.ts +47 -0
  56. package/dist/swap/native/limitSwapCancelBucket.d.ts.map +1 -0
  57. package/dist/swap/native/limitSwapCancelBucket.js +86 -0
  58. package/dist/swap/native/limitSwapCancelBucket.js.map +1 -0
  59. package/dist/swap/native/limitSwapCancelDust.d.ts +36 -0
  60. package/dist/swap/native/limitSwapCancelDust.d.ts.map +1 -0
  61. package/dist/swap/native/limitSwapCancelDust.js +100 -0
  62. package/dist/swap/native/limitSwapCancelDust.js.map +1 -0
  63. package/dist/swap/native/limitSwapCancelEligibility.d.ts +96 -0
  64. package/dist/swap/native/limitSwapCancelEligibility.d.ts.map +1 -0
  65. package/dist/swap/native/limitSwapCancelEligibility.js +165 -0
  66. package/dist/swap/native/limitSwapCancelEligibility.js.map +1 -0
  67. package/dist/swap/native/limitSwapCancelMemo.d.ts +123 -0
  68. package/dist/swap/native/limitSwapCancelMemo.d.ts.map +1 -0
  69. package/dist/swap/native/limitSwapCancelMemo.js +158 -0
  70. package/dist/swap/native/limitSwapCancelMemo.js.map +1 -0
  71. package/dist/swap/native/limitSwapMemo.d.ts.map +1 -1
  72. package/dist/swap/native/limitSwapMemo.js +7 -3
  73. package/dist/swap/native/limitSwapMemo.js.map +1 -1
  74. package/dist/swap/native/limitSwapOrderStatus.d.ts +23 -0
  75. package/dist/swap/native/limitSwapOrderStatus.d.ts.map +1 -0
  76. package/dist/swap/native/limitSwapOrderStatus.js +23 -0
  77. package/dist/swap/native/limitSwapOrderStatus.js.map +1 -0
  78. package/dist/swap/native/limitSwapOutcome.d.ts +61 -0
  79. package/dist/swap/native/limitSwapOutcome.d.ts.map +1 -0
  80. package/dist/swap/native/limitSwapOutcome.js +124 -0
  81. package/dist/swap/native/limitSwapOutcome.js.map +1 -0
  82. package/dist/swap/native/limitSwapQueue.d.ts +76 -0
  83. package/dist/swap/native/limitSwapQueue.d.ts.map +1 -0
  84. package/dist/swap/native/limitSwapQueue.js +175 -0
  85. package/dist/swap/native/limitSwapQueue.js.map +1 -0
  86. package/dist/swap/swapEnabledChains.d.ts +1 -1
  87. package/dist/swap/swapEnabledChains.d.ts.map +1 -1
  88. package/dist/tx/fee/evm/clampEvmPriorityFee.d.ts.map +1 -1
  89. package/dist/tx/fee/evm/clampEvmPriorityFee.js +2 -1
  90. package/dist/tx/fee/evm/clampEvmPriorityFee.js.map +1 -1
  91. package/dist/tx/fee/evm/evmGasLimit.d.ts.map +1 -1
  92. package/dist/tx/fee/evm/evmGasLimit.js +2 -0
  93. package/dist/tx/fee/evm/evmGasLimit.js.map +1 -1
  94. package/dist/utils/getBlockExplorerUrl/index.d.ts.map +1 -1
  95. package/dist/utils/getBlockExplorerUrl/index.js +4 -1
  96. package/dist/utils/getBlockExplorerUrl/index.js.map +1 -1
  97. package/package.json +41 -1
@@ -0,0 +1,100 @@
1
+ /**
2
+ * THORChain publishes `dust_threshold` in its own 1e8 fixed point, regardless
3
+ * of the source chain's native precision.
4
+ */
5
+ const thorchainFixedPointDecimals = 8;
6
+ /**
7
+ * Safety multiple over the larger floor.
8
+ *
9
+ * A cancel sitting exactly ON a threshold is a coin flip: THORNode's own
10
+ * comparisons are not uniformly `>=`, and the published threshold can move
11
+ * between the inbound fetch and the transaction landing. Doubling removes both
12
+ * without a magic absolute floor that would be wrong on some chain's units
13
+ * (10,000 is dust on an 18-decimal chain and real money on an 8-decimal one).
14
+ */
15
+ const dustSafetyMultiple = 2n;
16
+ /**
17
+ * Largest `dust_threshold`, in THORChain's own 1e8 units, that is plausible for
18
+ * any chain — one whole unit of the asset.
19
+ *
20
+ * `dust_threshold` is a REMOTE value that directly decides how much of the
21
+ * user's money is irreversibly donated: there is no refund path for anything
22
+ * attached to an `m=<`. So the bound has to be ABSOLUTE. A ceiling expressed as
23
+ * a multiple of the threshold itself cannot work — a hostile value scales both
24
+ * sides equally and is honoured verbatim.
25
+ *
26
+ * Real thresholds are orders of magnitude below this (Bitcoin's is 10000, or
27
+ * 0.0001 BTC), so the bound rejects only the absurd.
28
+ */
29
+ const maximumThresholdIn1e8 = 100000000n;
30
+ /**
31
+ * Largest coin precision this rescaling supports.
32
+ *
33
+ * Without it, any non-negative integer is accepted and `decimals: 1000` yields
34
+ * a 993-digit multiplier and a meaningless amount. 36 is far above every real
35
+ * chain (18 is the EVM maximum) while keeping the arithmetic bounded.
36
+ */
37
+ const maximumDecimals = 36;
38
+ export const limitSwapCancelDustErrors = [
39
+ 'thresholdUnavailable',
40
+ 'malformedThreshold',
41
+ 'unusablePrecision',
42
+ 'belowObservableMinimum',
43
+ 'exceedsCeiling',
44
+ ];
45
+ export class LimitSwapCancelDustError extends Error {
46
+ reason;
47
+ constructor(reason, message) {
48
+ super(message);
49
+ this.reason = reason;
50
+ this.name = 'LimitSwapCancelDustError';
51
+ }
52
+ }
53
+ /**
54
+ * How much to attach to a cancel sent FROM an L1 chain, in the source coin's
55
+ * smallest units.
56
+ *
57
+ * A cancel carries no value; the amount exists solely so Bifrost observes the
58
+ * transaction at all. Both failure modes are silent, which is why every branch
59
+ * here throws rather than defaulting:
60
+ *
61
+ * - Under-funded, and Bifrost drops it before it becomes a `MsgObservedTxIn` —
62
+ * the transaction confirms, the fee is spent, nothing is cancelled.
63
+ * - Over-funded, and the excess is irreversibly donated.
64
+ *
65
+ * The conversion is the part that has actually gone wrong in practice: a cancel
66
+ * was once signed for **2000 wei** — THORChain's 1e8-unit threshold used
67
+ * verbatim as an 18-decimal chain's smallest unit — which `ConvertAmount`
68
+ * truncates to zero. So the threshold is rescaled from 1e8 into the coin's own
69
+ * precision, and a result that rounds away is refused rather than nudged up to
70
+ * the bare observable minimum, which would be the same silent failure one order
71
+ * of magnitude higher.
72
+ */
73
+ export const getLimitSwapCancelDust = ({ inbound, decimals }) => {
74
+ const { chain, dust_threshold: threshold } = inbound;
75
+ if (!threshold?.trim()) {
76
+ throw new LimitSwapCancelDustError('thresholdUnavailable', `cancel dust: ${chain} inbound carries no dust_threshold, so the minimum Bifrost will observe is unknown`);
77
+ }
78
+ if (!/^\d+$/.test(threshold.trim())) {
79
+ throw new LimitSwapCancelDustError('malformedThreshold', `cancel dust: ${chain} dust_threshold is not an integer: ${JSON.stringify(threshold)}`);
80
+ }
81
+ if (!Number.isInteger(decimals) || decimals < 0 || decimals > maximumDecimals) {
82
+ throw new LimitSwapCancelDustError('unusablePrecision', `cancel dust: ${chain} source coin declares an unusable precision (${decimals})`);
83
+ }
84
+ const thresholdIn1e8 = BigInt(threshold.trim());
85
+ if (thresholdIn1e8 > maximumThresholdIn1e8) {
86
+ throw new LimitSwapCancelDustError('exceedsCeiling', `cancel dust: ${chain} dust_threshold ${thresholdIn1e8} (1e8) exceeds the plausible ceiling ${maximumThresholdIn1e8}`);
87
+ }
88
+ // Rescale from THORChain's 1e8 into the coin's own precision. Integer-only,
89
+ // in a direction chosen per branch so nothing is silently lost.
90
+ const scaled = decimals >= thorchainFixedPointDecimals
91
+ ? thresholdIn1e8 * 10n ** BigInt(decimals - thorchainFixedPointDecimals)
92
+ : thresholdIn1e8 / 10n ** BigInt(thorchainFixedPointDecimals - decimals);
93
+ const dust = scaled * dustSafetyMultiple;
94
+ if (thresholdIn1e8 > 0n && dust <= 0n) {
95
+ throw new LimitSwapCancelDustError('belowObservableMinimum', `cancel dust: ${chain} threshold ${thresholdIn1e8} (1e8) rounds away at ${decimals} decimals, ` +
96
+ 'so no attachable amount would be observed');
97
+ }
98
+ return dust;
99
+ };
100
+ //# sourceMappingURL=limitSwapCancelDust.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limitSwapCancelDust.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/swap/native/limitSwapCancelDust.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,2BAA2B,GAAG,CAAC,CAAA;AAErC;;;;;;;;GAQG;AACH,MAAM,kBAAkB,GAAG,EAAE,CAAA;AAE7B;;;;;;;;;;;;GAYG;AACH,MAAM,qBAAqB,GAAG,UAAY,CAAA;AAE1C;;;;;;GAMG;AACH,MAAM,eAAe,GAAG,EAAE,CAAA;AAE1B,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,sBAAsB;IACtB,oBAAoB;IACpB,mBAAmB;IACnB,wBAAwB;IACxB,gBAAgB;CACR,CAAA;AAIV,MAAM,OAAO,wBAAyB,SAAQ,KAAK;IACxC,MAAM,CAAgC;IAE/C,YAAY,MAAsC,EAAE,OAAe;QACjE,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAA;IACxC,CAAC;CACF;AASD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,EAAE,OAAO,EAAE,QAAQ,EAA+B,EAAU,EAAE;IACnG,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,GAAG,OAAO,CAAA;IAEpD,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC;QACvB,MAAM,IAAI,wBAAwB,CAChC,sBAAsB,EACtB,gBAAgB,KAAK,oFAAoF,CAC1G,CAAA;IACH,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,wBAAwB,CAChC,oBAAoB,EACpB,gBAAgB,KAAK,sCAAsC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CACvF,CAAA;IACH,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,GAAG,eAAe,EAAE,CAAC;QAC9E,MAAM,IAAI,wBAAwB,CAChC,mBAAmB,EACnB,gBAAgB,KAAK,gDAAgD,QAAQ,GAAG,CACjF,CAAA;IACH,CAAC;IAED,MAAM,cAAc,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAA;IAE/C,IAAI,cAAc,GAAG,qBAAqB,EAAE,CAAC;QAC3C,MAAM,IAAI,wBAAwB,CAChC,gBAAgB,EAChB,gBAAgB,KAAK,mBAAmB,cAAc,wCAAwC,qBAAqB,EAAE,CACtH,CAAA;IACH,CAAC;IAED,4EAA4E;IAC5E,gEAAgE;IAChE,MAAM,MAAM,GACV,QAAQ,IAAI,2BAA2B;QACrC,CAAC,CAAC,cAAc,GAAG,GAAG,IAAI,MAAM,CAAC,QAAQ,GAAG,2BAA2B,CAAC;QACxE,CAAC,CAAC,cAAc,GAAG,GAAG,IAAI,MAAM,CAAC,2BAA2B,GAAG,QAAQ,CAAC,CAAA;IAE5E,MAAM,IAAI,GAAG,MAAM,GAAG,kBAAkB,CAAA;IAExC,IAAI,cAAc,GAAG,EAAE,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,wBAAwB,CAChC,wBAAwB,EACxB,gBAAgB,KAAK,cAAc,cAAc,yBAAyB,QAAQ,aAAa;YAC7F,2CAA2C,CAC9C,CAAA;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA"}
@@ -0,0 +1,96 @@
1
+ import { LimitSwapCancelInputs } from './limitSwapCancelMemo.js';
2
+ export declare const limitSwapCancelBlockers: readonly ["terminal", "cancelAlreadyBroadcast", "missingSignedData", "signedDataDisagreesWithChain", "memoTooLongForSourceChain", "unroutableSourceChain"];
3
+ export type LimitSwapCancelBlocker = (typeof limitSwapCancelBlockers)[number];
4
+ /**
5
+ * Which spelling of an asset a cancel memo may use, or why there isn't one.
6
+ */
7
+ export type LimitSwapCancelAssetResolution = {
8
+ resolved: string;
9
+ } | {
10
+ problem: 'disagrees';
11
+ } | {
12
+ problem: 'unknown';
13
+ };
14
+ type ResolveLimitSwapCancelAssetInput = {
15
+ /** The PLACEMENT memo's spelling — lossy, usable only when not truncated. */
16
+ stored: string;
17
+ /** The full form captured locally at signing, when it exists. */
18
+ signed?: string;
19
+ /** The queue's own report, after `fuzzyAssetMatch` resolved the placement. */
20
+ observed?: string;
21
+ };
22
+ /**
23
+ * Resolve which spelling of one of the order's assets a cancel may use.
24
+ *
25
+ * Three sources, in decreasing order of how much they prove:
26
+ *
27
+ * 1. **The queue's own report** — the string THORChain built this order's index
28
+ * entry from. Authoritative by construction, and the only source for an
29
+ * order placed before the full form was recorded locally.
30
+ * 2. **The full form captured at signing** — derived from the coin's own
31
+ * contract, so exact whenever it exists.
32
+ * 3. **The stored placement spelling** — usable ONLY when it carries no
33
+ * truncated identifier, which makes it full by construction. That covers
34
+ * every native leg (`BTC.BTC`, `THOR.RUNE`) and every secured denom.
35
+ *
36
+ * `disagrees` when a local spelling and the chain's own differ: one is wrong
37
+ * and there is no way to tell which. This is the check a real failure needed —
38
+ * the amounts were cross-checked and agreed, the assets were never compared,
39
+ * and the asset was the entire defect.
40
+ *
41
+ * Compared case-insensitively: the sources differ on case by convention (a
42
+ * secured denom is emitted lower-case and reported upper-case, and
43
+ * `common.ParseCoin` upper-cases whatever it is given). Anything beyond case is
44
+ * a real difference.
45
+ */
46
+ export declare const resolveLimitSwapCancelAsset: ({ stored, signed, observed, }: ResolveLimitSwapCancelAssetInput) => LimitSwapCancelAssetResolution;
47
+ export type LimitSwapCancelCandidate = {
48
+ /** Whether the order has already closed. */
49
+ isTerminal: boolean;
50
+ /** Whether a cancel has already been broadcast against this order. */
51
+ hasPendingCancel?: boolean;
52
+ /** Source asset as the PLACEMENT memo spelled it. */
53
+ sourceAsset: string;
54
+ /** Target asset as the PLACEMENT memo spelled it. */
55
+ targetAsset: string;
56
+ /** Full source spelling captured at signing, if recorded. */
57
+ signedSourceAsset?: string;
58
+ /** Full target spelling captured at signing, if recorded. */
59
+ signedTargetAsset?: string;
60
+ /** Deposited source amount recorded at signing, in 1e8. */
61
+ signedSourceAmount?: bigint;
62
+ /** Trade target recorded at signing, in 1e8. */
63
+ signedTradeTarget?: bigint;
64
+ /** The queue's `coins[0].asset`, once polled. */
65
+ observedSourceAsset?: string;
66
+ /** The queue's `target_asset`, once polled. */
67
+ observedTargetAsset?: string;
68
+ /** The queue's `state.deposit`, once polled. */
69
+ observedDeposit?: bigint;
70
+ /** The queue's `trade_target`, once polled. */
71
+ observedTradeTarget?: bigint;
72
+ };
73
+ export type LimitSwapCancelEligibility = {
74
+ cancellable: LimitSwapCancelInputs;
75
+ } | {
76
+ blocked: LimitSwapCancelBlocker;
77
+ };
78
+ /**
79
+ * Decide whether an order can be cancelled, and if so with which exact amounts.
80
+ *
81
+ * **Fails closed at every unknown.** The failure this guards against is not a
82
+ * crash or an error dialog — it is a cancel that is accepted, costs a fee, and
83
+ * silently matches no order at all. Every branch that cannot prove the values
84
+ * are the ones THORChain holds returns a blocker.
85
+ *
86
+ * The signed-versus-observed cross-check covers assets as well as amounts.
87
+ * Absence is NOT disagreement: an order placed seconds ago has not been polled,
88
+ * and refusing to cancel until the first poll lands would be a worse failure
89
+ * than the one this prevents. But present-and-unparseable blocks exactly as a
90
+ * mismatch does — "not polled yet" and "polled, and the wire carried something
91
+ * we do not model" are different claims, and only the first is safe to proceed
92
+ * through.
93
+ */
94
+ export declare const getLimitSwapCancelEligibility: (candidate: LimitSwapCancelCandidate) => LimitSwapCancelEligibility;
95
+ export {};
96
+ //# sourceMappingURL=limitSwapCancelEligibility.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limitSwapCancelEligibility.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/swap/native/limitSwapCancelEligibility.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,qBAAqB,EACtB,MAAM,uBAAuB,CAAA;AAG9B,eAAO,MAAM,uBAAuB,4JA+B1B,CAAA;AAEV,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE7E;;GAEG;AACH,MAAM,MAAM,8BAA8B,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,WAAW,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,SAAS,CAAA;CAAE,CAAA;AAErH,KAAK,gCAAgC,GAAG;IACtC,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAA;IACd,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAOD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,2BAA2B,GAAI,+BAIzC,gCAAgC,KAAG,8BAmBrC,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,4CAA4C;IAC5C,UAAU,EAAE,OAAO,CAAA;IACnB,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAA;IACnB,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAA;IACnB,6DAA6D;IAC7D,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,6DAA6D;IAC7D,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,2DAA2D;IAC3D,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,gDAAgD;IAChD,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,iDAAiD;IACjD,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,+CAA+C;IAC/C,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,+CAA+C;IAC/C,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG;IAAE,WAAW,EAAE,qBAAqB,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,sBAAsB,CAAA;CAAE,CAAA;AAErH;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,6BAA6B,GAAI,WAAW,wBAAwB,KAAG,0BA4EnF,CAAA"}
@@ -0,0 +1,165 @@
1
+ import { buildCancelLimitSwapMemo, doesCancelLimitSwapMemoFit, isAbbreviatedThorchainMemoAsset, } from './limitSwapCancelMemo.js';
2
+ import { getLimitSwapSourceChainKind } from './limitSwapMemo.js';
3
+ export const limitSwapCancelBlockers = [
4
+ /** The order has already closed. Nothing left to cancel. */
5
+ 'terminal',
6
+ /**
7
+ * A cancel for this order has already been broadcast and is waiting to be
8
+ * observed. Without this, a user could pay the fee (and on L1 donate the
9
+ * dust) again for an identical memo landing in the identical bucket.
10
+ */
11
+ 'cancelAlreadyBroadcast',
12
+ /**
13
+ * The order predates the fields cancelling needs, or no source can supply an
14
+ * asset's full spelling. Fails closed rather than guessing at the values the
15
+ * matcher keys on.
16
+ */
17
+ 'missingSignedData',
18
+ /**
19
+ * What was recorded at signing and what the queue reports disagree. One of
20
+ * them is wrong and there is no way to tell which, so neither is signed.
21
+ */
22
+ 'signedDataDisagreesWithChain',
23
+ /**
24
+ * The cancel memo does not fit the source chain's per-transaction budget —
25
+ * in practice an ERC20 target from a UTXO source. Nothing in a cancel memo
26
+ * can be shortened, so the order simply refunds at expiry instead.
27
+ */
28
+ 'memoTooLongForSourceChain',
29
+ /**
30
+ * The source asset names a chain THORChain cannot route, so there is no
31
+ * inbound vault to send the cancel to and no byte budget to size it against.
32
+ */
33
+ 'unroutableSourceChain',
34
+ ];
35
+ const trimmed = (value) => {
36
+ const text = value?.trim();
37
+ return text ? text : undefined;
38
+ };
39
+ /**
40
+ * Resolve which spelling of one of the order's assets a cancel may use.
41
+ *
42
+ * Three sources, in decreasing order of how much they prove:
43
+ *
44
+ * 1. **The queue's own report** — the string THORChain built this order's index
45
+ * entry from. Authoritative by construction, and the only source for an
46
+ * order placed before the full form was recorded locally.
47
+ * 2. **The full form captured at signing** — derived from the coin's own
48
+ * contract, so exact whenever it exists.
49
+ * 3. **The stored placement spelling** — usable ONLY when it carries no
50
+ * truncated identifier, which makes it full by construction. That covers
51
+ * every native leg (`BTC.BTC`, `THOR.RUNE`) and every secured denom.
52
+ *
53
+ * `disagrees` when a local spelling and the chain's own differ: one is wrong
54
+ * and there is no way to tell which. This is the check a real failure needed —
55
+ * the amounts were cross-checked and agreed, the assets were never compared,
56
+ * and the asset was the entire defect.
57
+ *
58
+ * Compared case-insensitively: the sources differ on case by convention (a
59
+ * secured denom is emitted lower-case and reported upper-case, and
60
+ * `common.ParseCoin` upper-cases whatever it is given). Anything beyond case is
61
+ * a real difference.
62
+ */
63
+ export const resolveLimitSwapCancelAsset = ({ stored, signed, observed, }) => {
64
+ const storedIfUsable = isAbbreviatedThorchainMemoAsset(stored) ? undefined : trimmed(stored);
65
+ const local = trimmed(signed) ?? storedIfUsable;
66
+ const chain = trimmed(observed);
67
+ if (!chain) {
68
+ return local ? { resolved: local } : { problem: 'unknown' };
69
+ }
70
+ if (!local) {
71
+ // No local spelling to check against — the legacy token case, rescued by
72
+ // the only source still holding the full contract.
73
+ return { resolved: chain };
74
+ }
75
+ if (local.toLowerCase() !== chain.toLowerCase()) {
76
+ return { problem: 'disagrees' };
77
+ }
78
+ // Proven equal bar case, so the local spelling is kept: it is the exact byte
79
+ // form this SDK derived.
80
+ return { resolved: local };
81
+ };
82
+ /**
83
+ * Decide whether an order can be cancelled, and if so with which exact amounts.
84
+ *
85
+ * **Fails closed at every unknown.** The failure this guards against is not a
86
+ * crash or an error dialog — it is a cancel that is accepted, costs a fee, and
87
+ * silently matches no order at all. Every branch that cannot prove the values
88
+ * are the ones THORChain holds returns a blocker.
89
+ *
90
+ * The signed-versus-observed cross-check covers assets as well as amounts.
91
+ * Absence is NOT disagreement: an order placed seconds ago has not been polled,
92
+ * and refusing to cancel until the first poll lands would be a worse failure
93
+ * than the one this prevents. But present-and-unparseable blocks exactly as a
94
+ * mismatch does — "not polled yet" and "polled, and the wire carried something
95
+ * we do not model" are different claims, and only the first is safe to proceed
96
+ * through.
97
+ */
98
+ export const getLimitSwapCancelEligibility = (candidate) => {
99
+ if (candidate.isTerminal) {
100
+ return { blocked: 'terminal' };
101
+ }
102
+ if (candidate.hasPendingCancel) {
103
+ return { blocked: 'cancelAlreadyBroadcast' };
104
+ }
105
+ const { signedSourceAmount, signedTradeTarget } = candidate;
106
+ if (signedSourceAmount === undefined ||
107
+ signedTradeTarget === undefined ||
108
+ signedSourceAmount <= 0n ||
109
+ signedTradeTarget <= 0n) {
110
+ return { blocked: 'missingSignedData' };
111
+ }
112
+ // `state.deposit` IS the swap's `Tx.Coins[0].Amount` and `trade_target` IS
113
+ // `msg.TradeTarget` — the exact pair the matcher's ratio is computed from.
114
+ if (candidate.observedDeposit !== undefined && candidate.observedDeposit !== signedSourceAmount) {
115
+ return { blocked: 'signedDataDisagreesWithChain' };
116
+ }
117
+ if (candidate.observedTradeTarget !== undefined && candidate.observedTradeTarget !== signedTradeTarget) {
118
+ return { blocked: 'signedDataDisagreesWithChain' };
119
+ }
120
+ const source = resolveLimitSwapCancelAsset({
121
+ stored: candidate.sourceAsset,
122
+ signed: candidate.signedSourceAsset,
123
+ observed: candidate.observedSourceAsset,
124
+ });
125
+ const target = resolveLimitSwapCancelAsset({
126
+ stored: candidate.targetAsset,
127
+ signed: candidate.signedTargetAsset,
128
+ observed: candidate.observedTargetAsset,
129
+ });
130
+ if (!('resolved' in source) || !('resolved' in target)) {
131
+ const disagrees = ('problem' in source && source.problem === 'disagrees') || ('problem' in target && target.problem === 'disagrees');
132
+ return { blocked: disagrees ? 'signedDataDisagreesWithChain' : 'missingSignedData' };
133
+ }
134
+ const inputs = {
135
+ sourceAsset: source.resolved,
136
+ sourceAmount: signedSourceAmount,
137
+ targetAsset: target.resolved,
138
+ tradeTarget: signedTradeTarget,
139
+ };
140
+ // The memo must be buildable AND fit the chain it will be sent from. Checked
141
+ // here rather than at signing so the action is never offered for an order
142
+ // that cannot actually be cancelled.
143
+ let memo;
144
+ try {
145
+ memo = buildCancelLimitSwapMemo(inputs);
146
+ }
147
+ catch {
148
+ return { blocked: 'missingSignedData' };
149
+ }
150
+ // Resolved in its own guarded step: the memo builder does not check
151
+ // routability, so an unrecognised prefix reaches this call and throws —
152
+ // escaping a function whose whole contract is to answer with a blocker.
153
+ let sourceChainKind;
154
+ try {
155
+ sourceChainKind = getLimitSwapSourceChainKind(inputs.sourceAsset);
156
+ }
157
+ catch {
158
+ return { blocked: 'unroutableSourceChain' };
159
+ }
160
+ if (!doesCancelLimitSwapMemoFit(memo, sourceChainKind)) {
161
+ return { blocked: 'memoTooLongForSourceChain' };
162
+ }
163
+ return { cancellable: inputs };
164
+ };
165
+ //# sourceMappingURL=limitSwapCancelEligibility.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limitSwapCancelEligibility.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/swap/native/limitSwapCancelEligibility.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,123 @@
1
+ import { LimitSwapSourceChainKind } from './limitSwapMemo.js';
2
+ /**
3
+ * THORChain's modify-limit-swap prefix. Distinct from `limitSwapMemoPrefix`
4
+ * (`=<:`), which PLACES an order — `m=<:` modifies one that is already resting.
5
+ */
6
+ export declare const modifyLimitSwapMemoPrefix = "m=<:";
7
+ /**
8
+ * Whether `memo` MODIFIES a resting order — which includes, but is not limited
9
+ * to, cancelling it.
10
+ *
11
+ * Named for what it matches. A cancel is the special case where the final field
12
+ * is zero; a non-zero value re-targets. Only the cancel form is built here, so
13
+ * today the two coincide — but a predicate that says "cancel" while matching
14
+ * any modification is the kind of small lie that outlives the assumption that
15
+ * made it true.
16
+ */
17
+ export declare const isModifyLimitSwapMemo: (memo: string | undefined | null) => boolean;
18
+ /**
19
+ * Whether `memo` CANCELS a resting order, rather than merely modifying one.
20
+ *
21
+ * The final field is compared NUMERICALLY, the way THORNode's `getUint` reads
22
+ * it: `"00"` is zero there, and a string comparison would call that a retarget.
23
+ * Digits only, so a sign cannot smuggle `"-0"` past an unsigned field.
24
+ */
25
+ export declare const isCancelLimitSwapMemo: (memo: string | undefined | null) => boolean;
26
+ /**
27
+ * Everything the cancel memo needs, reduced to the exact integers THORChain
28
+ * itself holds. Amounts are bigint so a caller cannot pass an unparsed or
29
+ * negative value.
30
+ */
31
+ export type LimitSwapCancelInputs = {
32
+ /**
33
+ * THORChain memo form of the order's SOURCE asset.
34
+ *
35
+ * Must carry the token's FULL contract (`ETH.USDC-0XA0B86991…`), never the
36
+ * placement memo's 6-character abbreviation — see `buildCancelLimitSwapMemo`.
37
+ *
38
+ * Must be the asset's SECURED denom (`eth-usdc-0xa0b…`) when the source is a
39
+ * secured asset, never its layer-1 form. `MsgModifyLimitSwap.ValidateBasic`
40
+ * enforces `From.IsChain(Source.Asset.GetChain())`, and `GetChain()` returns
41
+ * THORChain only for synth, trade and secured assets. The layer-1 spelling
42
+ * makes it report the L1 chain, and a cancel sent from a THOR address is then
43
+ * rejected outright at validation.
44
+ */
45
+ sourceAsset: string;
46
+ /** The order's deposited source amount, in THORChain's 1e8 fixed point. */
47
+ sourceAmount: bigint;
48
+ /** THORChain memo form of the TARGET asset, under the same full-spelling rule. */
49
+ targetAsset: string;
50
+ /** The order's ORIGINAL trade target (the placement memo's LIM), in 1e8. */
51
+ tradeTarget: bigint;
52
+ };
53
+ /**
54
+ * Whether a memo asset carries a TRUNCATED token identifier —
55
+ * `ETH.USDC-06EB48` rather than `ETH.USDC-0XA0B86991…`.
56
+ *
57
+ * The chain prefix has to be stripped first, and cannot be assumed to end at a
58
+ * `.`: a SECURED asset spells the whole thing with `-`, so a secured native
59
+ * denom is `btc-btc` and a secured token is `eth-usdc-0xa0b…`. Reading the tail
60
+ * after the last `-` would call the first of those truncated and make every
61
+ * secured-native order uncancellable.
62
+ *
63
+ * So: drop everything up to the first separator — that is the chain — and look
64
+ * at the SYMBOL that follows. A symbol is `TICKER` or `TICKER-<identifier>`,
65
+ * and only the second form can be truncated. `BTC.BTC`, `THOR.RUNE` and
66
+ * `btc-btc` carry no identifier at all and are full by construction.
67
+ */
68
+ export declare const isAbbreviatedThorchainMemoAsset: (asset: string) => boolean;
69
+ export declare const limitSwapCancelMemoErrors: readonly ["emptyAsset", "nonPositiveAmount", "abbreviatedAsset"];
70
+ export type LimitSwapCancelMemoError = (typeof limitSwapCancelMemoErrors)[number];
71
+ export declare class LimitSwapCancelMemoBuildError extends Error {
72
+ readonly reason: LimitSwapCancelMemoError;
73
+ constructor(reason: LimitSwapCancelMemoError, message: string);
74
+ }
75
+ /**
76
+ * Both amounts must be positive, for every consumer of these inputs.
77
+ *
78
+ * Shared because two modules depend on it for different reasons: the memo would
79
+ * encode a coin THORNode cannot parse, and the bucket key divides by the trade
80
+ * target — where a zero would raise `RangeError` rather than a domain error a
81
+ * caller can branch on.
82
+ */
83
+ export declare const assertPositiveLimitSwapCancelAmounts: ({ sourceAmount, tradeTarget, }: Pick<LimitSwapCancelInputs, "sourceAmount" | "tradeTarget">) => void;
84
+ /**
85
+ * Build the `m=<` memo that cancels a resting limit order.
86
+ *
87
+ * m=<:<SRC_AMOUNT><SRC_ASSET>:<TRADE_TARGET><TGT_ASSET>:0
88
+ *
89
+ * Both coins are `<amount><ASSET>` with NO space — THORNode's `getCoin` scans
90
+ * leading digits and splices the space back in before parsing.
91
+ *
92
+ * Three properties, each of which causes a SILENT no-op if broken — the cancel
93
+ * is accepted, costs a fee, matches nothing, and looks exactly like success:
94
+ *
95
+ * - **Assets are spelled in FULL.** `processOneTxIn` runs every other inbound
96
+ * memo through `fuzzyAssetMatch`, which is what lets a placement say
97
+ * `ETH.USDC-06EB48` and still be indexed under the full contract.
98
+ * `ModifyLimitSwapMemo` is the exception: its asset string builds the lookup
99
+ * key verbatim, so an abbreviation addresses a bucket that by construction
100
+ * holds nothing. Enforced here, not merely documented.
101
+ * - **Amounts are plain decimal integers.** The placement memo's LIM goes
102
+ * through `getUintWithScientificNotation` and understands `544e6`; these
103
+ * coins go through `cosmos.ParseCoins`, which does not.
104
+ * - **Both amounts are exact.** THORNode does not compare them directly — they
105
+ * feed the ratio its index key is built from (see
106
+ * `getThorchainLimitOrderBucketKey`), and one unit of drift lands in a
107
+ * different bucket.
108
+ */
109
+ export declare const buildCancelLimitSwapMemo: (inputs: LimitSwapCancelInputs) => string;
110
+ /**
111
+ * Whether a cancel memo fits the per-transaction budget of the chain it will be
112
+ * sent from.
113
+ *
114
+ * In practice this rules out an ERC20 target from a UTXO source: two
115
+ * full-contract assets plus two exact amounts overflow the 80-byte OP_RETURN
116
+ * cap, and NOTHING in a cancel memo can be shortened — the amounts define the
117
+ * bucket, short codes are rejected by `cosmos.ParseCoins`, and this memo type
118
+ * skips `fuzzyAssetMatch`. Such an order still refunds automatically at expiry.
119
+ */
120
+ export declare const doesCancelLimitSwapMemoFit: (memo: string, sourceChainKind: LimitSwapSourceChainKind) => boolean;
121
+ /** Convenience: the byte-cap check keyed off the source asset's memo notation. */
122
+ export declare const doesCancelLimitSwapMemoFitSourceAsset: (memo: string, sourceAsset: string) => boolean;
123
+ //# sourceMappingURL=limitSwapCancelMemo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limitSwapCancelMemo.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/swap/native/limitSwapCancelMemo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuD,wBAAwB,EAAE,MAAM,iBAAiB,CAAA;AAE/G;;;GAGG;AACH,eAAO,MAAM,yBAAyB,SAAS,CAAA;AAS/C;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,GAAI,MAAM,MAAM,GAAG,SAAS,GAAG,IAAI,KAAG,OACzB,CAAA;AAE/C;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,GAAI,MAAM,MAAM,GAAG,SAAS,GAAG,IAAI,KAAG,OAUvE,CAAA;AAED;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;;;;;;;;;;OAYG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB,2EAA2E;IAC3E,YAAY,EAAE,MAAM,CAAA;IACpB,kFAAkF;IAClF,WAAW,EAAE,MAAM,CAAA;IACnB,4EAA4E;IAC5E,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAgBD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,+BAA+B,GAAI,OAAO,MAAM,KAAG,OAQ/D,CAAA;AAED,eAAO,MAAM,yBAAyB,kEAAmE,CAAA;AAEzG,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEjF,qBAAa,6BAA8B,SAAQ,KAAK;IACtD,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAA;gBAE7B,MAAM,EAAE,wBAAwB,EAAE,OAAO,EAAE,MAAM;CAK9D;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,oCAAoC,GAAI,gCAGlD,IAAI,CAAC,qBAAqB,EAAE,cAAc,GAAG,aAAa,CAAC,KAAG,IAOhE,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,wBAAwB,GAAI,QAAQ,qBAAqB,KAAG,MAwBxE,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,0BAA0B,GAAI,MAAM,MAAM,EAAE,iBAAiB,wBAAwB,KAAG,OACnB,CAAA;AAElF,kFAAkF;AAClF,eAAO,MAAM,qCAAqC,GAAI,MAAM,MAAM,EAAE,aAAa,MAAM,KAAG,OACd,CAAA"}