@vultisig/core-chain 2.36.0 → 2.38.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 (104) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/chains/cosmos/cosmosGasLimitRecord.d.ts.map +1 -1
  3. package/dist/chains/cosmos/cosmosGasLimitRecord.js +13 -14
  4. package/dist/chains/cosmos/cosmosGasLimitRecord.js.map +1 -1
  5. package/dist/chains/cosmos/gas.d.ts +16 -0
  6. package/dist/chains/cosmos/gas.d.ts.map +1 -1
  7. package/dist/chains/cosmos/gas.js +17 -1
  8. package/dist/chains/cosmos/gas.js.map +1 -1
  9. package/dist/chains/solana/kamino/KaminoServiceError.d.ts +63 -0
  10. package/dist/chains/solana/kamino/KaminoServiceError.d.ts.map +1 -0
  11. package/dist/chains/solana/kamino/KaminoServiceError.js +29 -0
  12. package/dist/chains/solana/kamino/KaminoServiceError.js.map +1 -0
  13. package/dist/chains/solana/kamino/amount.d.ts +141 -0
  14. package/dist/chains/solana/kamino/amount.d.ts.map +1 -0
  15. package/dist/chains/solana/kamino/amount.js +156 -0
  16. package/dist/chains/solana/kamino/amount.js.map +1 -0
  17. package/dist/chains/solana/kamino/api.d.ts +20 -0
  18. package/dist/chains/solana/kamino/api.d.ts.map +1 -0
  19. package/dist/chains/solana/kamino/api.js +59 -0
  20. package/dist/chains/solana/kamino/api.js.map +1 -0
  21. package/dist/chains/solana/kamino/baseUnits.d.ts +23 -0
  22. package/dist/chains/solana/kamino/baseUnits.d.ts.map +1 -0
  23. package/dist/chains/solana/kamino/baseUnits.js +30 -0
  24. package/dist/chains/solana/kamino/baseUnits.js.map +1 -0
  25. package/dist/chains/solana/kamino/config.d.ts +27 -0
  26. package/dist/chains/solana/kamino/config.d.ts.map +1 -0
  27. package/dist/chains/solana/kamino/config.js +27 -0
  28. package/dist/chains/solana/kamino/config.js.map +1 -0
  29. package/dist/chains/solana/kamino/decimal.d.ts +24 -0
  30. package/dist/chains/solana/kamino/decimal.d.ts.map +1 -0
  31. package/dist/chains/solana/kamino/decimal.js +52 -0
  32. package/dist/chains/solana/kamino/decimal.js.map +1 -0
  33. package/dist/chains/solana/kamino/models.d.ts +148 -0
  34. package/dist/chains/solana/kamino/models.d.ts.map +1 -0
  35. package/dist/chains/solana/kamino/models.js +2 -0
  36. package/dist/chains/solana/kamino/models.js.map +1 -0
  37. package/dist/chains/solana/kamino/position.d.ts +79 -0
  38. package/dist/chains/solana/kamino/position.d.ts.map +1 -0
  39. package/dist/chains/solana/kamino/position.js +52 -0
  40. package/dist/chains/solana/kamino/position.js.map +1 -0
  41. package/dist/chains/solana/kamino/rate.d.ts +57 -0
  42. package/dist/chains/solana/kamino/rate.d.ts.map +1 -0
  43. package/dist/chains/solana/kamino/rate.js +88 -0
  44. package/dist/chains/solana/kamino/rate.js.map +1 -0
  45. package/dist/chains/solana/kamino/registry.d.ts +70 -0
  46. package/dist/chains/solana/kamino/registry.d.ts.map +1 -0
  47. package/dist/chains/solana/kamino/registry.js +67 -0
  48. package/dist/chains/solana/kamino/registry.js.map +1 -0
  49. package/dist/chains/solana/kamino/tx/actions.d.ts +22 -0
  50. package/dist/chains/solana/kamino/tx/actions.d.ts.map +1 -0
  51. package/dist/chains/solana/kamino/tx/actions.js +85 -0
  52. package/dist/chains/solana/kamino/tx/actions.js.map +1 -0
  53. package/dist/chains/solana/kamino/tx/computeBudget.d.ts +66 -0
  54. package/dist/chains/solana/kamino/tx/computeBudget.d.ts.map +1 -0
  55. package/dist/chains/solana/kamino/tx/computeBudget.js +73 -0
  56. package/dist/chains/solana/kamino/tx/computeBudget.js.map +1 -0
  57. package/dist/chains/solana/kamino/tx/decode.d.ts +121 -0
  58. package/dist/chains/solana/kamino/tx/decode.d.ts.map +1 -0
  59. package/dist/chains/solana/kamino/tx/decode.js +458 -0
  60. package/dist/chains/solana/kamino/tx/decode.js.map +1 -0
  61. package/dist/chains/solana/kamino/tx/instructions.d.ts +260 -0
  62. package/dist/chains/solana/kamino/tx/instructions.d.ts.map +1 -0
  63. package/dist/chains/solana/kamino/tx/instructions.js +256 -0
  64. package/dist/chains/solana/kamino/tx/instructions.js.map +1 -0
  65. package/dist/chains/solana/kamino/tx/sequence.d.ts +123 -0
  66. package/dist/chains/solana/kamino/tx/sequence.d.ts.map +1 -0
  67. package/dist/chains/solana/kamino/tx/sequence.js +235 -0
  68. package/dist/chains/solana/kamino/tx/sequence.js.map +1 -0
  69. package/dist/chains/solana/kamino/tx/validate.d.ts +138 -0
  70. package/dist/chains/solana/kamino/tx/validate.d.ts.map +1 -0
  71. package/dist/chains/solana/kamino/tx/validate.js +542 -0
  72. package/dist/chains/solana/kamino/tx/validate.js.map +1 -0
  73. package/dist/chains/solana/kamino/tx/wire.d.ts +107 -0
  74. package/dist/chains/solana/kamino/tx/wire.d.ts.map +1 -0
  75. package/dist/chains/solana/kamino/tx/wire.js +274 -0
  76. package/dist/chains/solana/kamino/tx/wire.js.map +1 -0
  77. package/dist/chains/solana/kamino/vaultInfo.d.ts +17 -0
  78. package/dist/chains/solana/kamino/vaultInfo.d.ts.map +1 -0
  79. package/dist/chains/solana/kamino/vaultInfo.js +150 -0
  80. package/dist/chains/solana/kamino/vaultInfo.js.map +1 -0
  81. package/dist/chains/thorchain/ruji/services/fetchMergeableTokenBalances.d.ts +6 -1
  82. package/dist/chains/thorchain/ruji/services/fetchMergeableTokenBalances.d.ts.map +1 -1
  83. package/dist/chains/thorchain/ruji/services/fetchMergeableTokenBalances.js +6 -35
  84. package/dist/chains/thorchain/ruji/services/fetchMergeableTokenBalances.js.map +1 -1
  85. package/dist/swap/quote/findSwapQuote.d.ts +39 -0
  86. package/dist/swap/quote/findSwapQuote.d.ts.map +1 -1
  87. package/dist/swap/quote/findSwapQuote.js +33 -2
  88. package/dist/swap/quote/findSwapQuote.js.map +1 -1
  89. package/dist/tx/broadcast/cosmosSequenceMismatch.d.ts +26 -0
  90. package/dist/tx/broadcast/cosmosSequenceMismatch.d.ts.map +1 -0
  91. package/dist/tx/broadcast/cosmosSequenceMismatch.js +79 -0
  92. package/dist/tx/broadcast/cosmosSequenceMismatch.js.map +1 -0
  93. package/dist/tx/broadcast/resolvers/cosmos.d.ts +1 -0
  94. package/dist/tx/broadcast/resolvers/cosmos.d.ts.map +1 -1
  95. package/dist/tx/broadcast/resolvers/cosmos.js +7 -1
  96. package/dist/tx/broadcast/resolvers/cosmos.js.map +1 -1
  97. package/dist/tx/broadcast/transientRetry.d.ts.map +1 -1
  98. package/dist/tx/broadcast/transientRetry.js +6 -0
  99. package/dist/tx/broadcast/transientRetry.js.map +1 -1
  100. package/dist/utils/isValidTokenId.d.ts +6 -3
  101. package/dist/utils/isValidTokenId.d.ts.map +1 -1
  102. package/dist/utils/isValidTokenId.js +10 -3
  103. package/dist/utils/isValidTokenId.js.map +1 -1
  104. package/package.json +97 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # @vultisig/core-chain
2
2
 
3
+ ## 2.38.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#2074](https://github.com/vultisig/vultisig-sdk/pull/2074) [`8929244`](https://github.com/vultisig/vultisig-sdk/commit/8929244cdb3b21059a46eabac6d4d9684e18a633) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - Add the Kamino Earn data layer under `chains/solana/kamino`: a REST client for the kVaults API (vault state, metrics, user positions, PnL) with a typed error envelope that separates retryable statuses from permanent refusals; a curated vault registry pinning each launch vault's identity (mints, decimals, farm, curator, risk tier); distinct token- and share-denominated amount types over exact `bigint` base units, with exact-rate conversions that truncate toward zero so a sized withdraw can never over-request (the API rewrites an over-sized withdraw to `u64::MAX` — withdraw everything); vault-info hydration that refuses responses disagreeing with the pinned identity and derives the effective deposit/withdraw minimums the on-chain program actually accepts; and position parsing with a spendable-balance rule that stays strictly below the reported balance.
8
+
9
+ - [#2124](https://github.com/vultisig/vultisig-sdk/pull/2124) [`514e31f`](https://github.com/vultisig/vultisig-sdk/commit/514e31f084c241792f3a9b2436074c324a909c0f) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - Add the Kamino Earn transaction pipeline under `chains/solana/kamino/tx`: build the unsigned deposit/withdraw transactions (with the withdraw-everything sentinel refused before a request leaves the device); inject the attribution memo and the compute-budget pair into the built v0 transaction without disturbing address-lookup-table indexes; replace the recent blockhash immediately before keysign; a fail-closed validator that admits only allow-listed programs, matches the exact instruction sequence each operation produces (both withdraw discriminators, the farms unstake pair, exactly one memo carrying exactly the attribution tag), pins every account that decides where money goes against the registry and local ATA/PDA derivations, pins every spend amount, and refuses unexplained writable accounts; and an offline decoder that lets a co-signing device derive an independent claim about what the bytes do — vault identified through the signer's own share account, both withdraw shapes accepted, the farm release bounded by the withdraw itself.
10
+
11
+ ## 2.37.0
12
+
13
+ ### Minor Changes
14
+
15
+ - [#2011](https://github.com/vultisig/vultisig-sdk/pull/2011) [`687f1ad`](https://github.com/vultisig/vultisig-sdk/commit/687f1adea7c81dde4a5f21520ea1cdbbf34e10fd) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - Add `findSwapQuotes`, returning the full ranked swap-route candidate set (`{ best, ranked }`) alongside the auto-selected winner, so consumers can offer route selection. Each ranked entry carries the fully bound quote (request amount, expiry, safety fingerprint), its provider name, and the comparable net output used for ranking. `findSwapQuote` now delegates to it and its behavior — selection, preference band, and every error path — is unchanged.
16
+
17
+ ### Patch Changes
18
+
19
+ - [#1881](https://github.com/vultisig/vultisig-sdk/pull/1881) [`f7caa39`](https://github.com/vultisig/vultisig-sdk/commit/f7caa39ad2eb3d322031d8ac56ae832a9108e6d4) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Surface Cosmos account-sequence mismatches with direction-aware recovery: stale signed transactions now require rebuilding and a new signing ceremony, while future-sequence transactions may wait for their predecessor and retry. Preserve peer-broadcast hash verification and retry only the recoverable future-sequence case.
20
+
21
+ - [#1839](https://github.com/vultisig/vultisig-sdk/pull/1839) [`50257ad`](https://github.com/vultisig/vultisig-sdk/commit/50257ad213a36952509f3548100334e5f3e44a09) Thanks [@rcoderdev](https://github.com/rcoderdev)! - cosmos/gas: raise the TerraClassic staking gas limit from 3M to 4M
22
+
23
+ `getCosmosStakingGasLimit` now returns 4M for `Chain.TerraClassic` regardless of `msgCount`, giving external SDK consumers headroom over the observed 2,501,503-gas `MsgBeginRedelegate` path.
24
+
25
+ Also exports `TERRA_CLASSIC_STAKING_ULUNA_FEE_BASE_UNITS`, the `uluna` fee correctly priced for this 4M staking gas limit (113.3 LUNC at the chain's 28.325 uluna/gas minimum). The existing `TERRA_CLASSIC_ULUNA_BASE_GAS` / `getCosmosSendFeeBaseUnits` fee is priced for the 300k native-send gas limit and under-pays a 4M-gas staking tx by ~13x, so consumers must pair the staking gas limit with this new constant, not the send fee.
26
+
27
+ - [#1871](https://github.com/vultisig/vultisig-sdk/pull/1871) [`76163b6`](https://github.com/vultisig/vultisig-sdk/commit/76163b6e533cb0178c999e5b6554bddf4517718e) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Make the expired, zero-caller Rujira merge-balance service inert. The KUJI-to-RUJI merge window closed on 2026-04-05, so the compatibility shim now returns an empty result without querying GraphQL.
28
+
29
+ - Updated dependencies [[`69b1c2e`](https://github.com/vultisig/vultisig-sdk/commit/69b1c2e4026e62a83151957a91651eaa982d0a13)]:
30
+ - @vultisig/lib-utils@0.10.5
31
+
3
32
  ## 2.36.0
4
33
 
5
34
  ### Minor Changes
@@ -1 +1 @@
1
- {"version":3,"file":"cosmosGasLimitRecord.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/cosmos/cosmosGasLimitRecord.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,WAAW,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAEtF,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAuBzC,eAAO,MAAM,iBAAiB,GAAI,MAAM,OAAO,CAAC,WAAW,CAAC,KAAG,MAE9D,CAAA;AAmCD,KAAK,6BAA6B,GAAG;IACnC,KAAK,EAAE,qBAAqB,CAAA;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,GAAI,qBAAyB,6BAA6B,KAAG,MAejG,CAAA"}
1
+ {"version":3,"file":"cosmosGasLimitRecord.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/cosmos/cosmosGasLimitRecord.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,WAAW,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAEtF,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAuBzC,eAAO,MAAM,iBAAiB,GAAI,MAAM,OAAO,CAAC,WAAW,CAAC,KAAG,MAE9D,CAAA;AAoCD,KAAK,6BAA6B,GAAG;IACnC,KAAK,EAAE,qBAAqB,CAAA;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,GAAI,qBAAyB,6BAA6B,KAAG,MAajG,CAAA"}
@@ -34,15 +34,16 @@ export const getCosmosGasLimit = (coin) => {
34
34
  * writes that the standard SDK gas estimate omits. In practice this adds
35
35
  * ~200-800 gas on top of the base delegate cost (~2M), so a 2M limit fails
36
36
  * consistently ("out of gas in location: ValuePerByte; gasWanted: 2000000,
37
- * gasUsed: 200X"). 3M needs ~84.97 LUNC at sign time (3M * 28.325 uluna/gas).
38
- * That fee is supplied by the CONSUMER's separate per-msg staking fee
39
- * (mcp-ts COSMOS_STAKING_FEE_PER_MSG_BASE_UNITS[TerraClassic] = 100 LUNC/msg,
40
- * written into the signAmino / signDirect fee) — NOT by
41
- * `cosmosGasRecord[TerraClassic]`, which is the native MsgSend gas fee
42
- * (8.4975 LUNC = 300k × 28.325) and never governs staking. The msgCount scaling is disabled for
43
- * TerraClassic: at msgCount>=2, scaled gasWanted would push the required fee
44
- * above the 100 LUNC per-msg staking fee, causing node rejection. Columbus-5
45
- * callers must split multi-validator claims into separate txs.
37
+ * gasUsed: 200X"). Production telemetry later observed MsgBeginRedelegate
38
+ * consuming 2_501_503 gas. The former 3M limit left little headroom over that
39
+ * observed burn, so TerraClassic uses 4M for the heaviest single-msg staking
40
+ * path. Consumers MUST pair this with `TERRA_CLASSIC_STAKING_ULUNA_FEE_BASE_UNITS`
41
+ * (from `./gas`), NOT `cosmosGasRecord[TerraClassic]` / `TERRA_CLASSIC_ULUNA_BASE_GAS`,
42
+ * since those govern native MsgSend at the much lower 300k send gas limit and
43
+ * under-price a 4M-gas staking tx by ~13x, which the node rejects for
44
+ * insufficient fees. TerraClassic keeps a fixed per-transaction staking
45
+ * budget, so callers must split multi-validator reward claims into separate
46
+ * transactions.
46
47
  */
47
48
  const cosmosStakingGasLimitRecord = {
48
49
  [Chain.Cosmos]: 350000n,
@@ -52,7 +53,7 @@ const cosmosStakingGasLimitRecord = {
52
53
  [Chain.Noble]: 350000n,
53
54
  [Chain.Akash]: 350000n,
54
55
  [Chain.Terra]: 500000n,
55
- [Chain.TerraClassic]: 3000000n,
56
+ [Chain.TerraClassic]: 4000000n,
56
57
  };
57
58
  /**
58
59
  * Returns the gas limit a Cosmos staking tx should request for the given
@@ -69,10 +70,8 @@ export const getCosmosStakingGasLimit = ({ chain, msgCount = 1 }) => {
69
70
  throw new Error(`getCosmosStakingGasLimit: msgCount must be a non-negative integer, got ${msgCount}`);
70
71
  }
71
72
  const base = cosmosStakingGasLimitRecord[chain];
72
- // TerraClassic: staking-fee cap (see comment on cosmosStakingGasLimitRecord).
73
- // Scaling would push the required fee above the consumer's 100 LUNC per-msg
74
- // staking fee at msgCount>=2; single-msg policy keeps the tx within that fee
75
- // for columbus-5 (independent of the cosmosGasRecord native-send gas fee).
73
+ // TerraClassic uses a fixed single-transaction budget (see the record
74
+ // comment). Multi-validator reward claims must be split by the caller.
76
75
  if (chain === Chain.TerraClassic)
77
76
  return base;
78
77
  const n = BigInt(Math.max(1, msgCount));
@@ -1 +1 @@
1
- {"version":3,"file":"cosmosGasLimitRecord.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/cosmos/cosmosGasLimitRecord.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAsC,MAAM,4BAA4B,CAAA;AAItF,MAAM,oBAAoB,GAAgC;IACxD,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO;IACvB,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO;IACxB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO;IACvB,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO;IACrB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO;IACtB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO;IACtB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO;IACtB,wDAAwD;IACxD,2EAA2E;IAC3E,0EAA0E;IAC1E,sEAAsE;IACtE,uEAAuE;IACvE,wEAAwE;IACxE,yEAAyE;IACzE,gCAAgC;IAChC,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,OAAO;IAC7B,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,SAAS;IAC5B,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,WAAW;CAC/B,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,IAA0B,EAAU,EAAE;IACtE,OAAO,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AACzC,CAAC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,2BAA2B,GAA0C;IACzE,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAQ;IACxB,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,OAAQ;IACzB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAQ;IACxB,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,OAAQ;IACtB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAQ;IACvB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAQ;IACvB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAQ;IACvB,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,QAAU;CACjC,CAAA;AAaD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,EAAiC,EAAU,EAAE;IACzG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,0EAA0E,QAAQ,EAAE,CAAC,CAAA;IACvG,CAAC;IAED,MAAM,IAAI,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAA;IAE/C,8EAA8E;IAC9E,4EAA4E;IAC5E,6EAA6E;IAC7E,2EAA2E;IAC3E,IAAI,KAAK,KAAK,KAAK,CAAC,YAAY;QAAE,OAAO,IAAI,CAAA;IAE7C,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAA;IACvC,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;AACtC,CAAC,CAAA"}
1
+ {"version":3,"file":"cosmosGasLimitRecord.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/cosmos/cosmosGasLimitRecord.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAsC,MAAM,4BAA4B,CAAA;AAItF,MAAM,oBAAoB,GAAgC;IACxD,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO;IACvB,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO;IACxB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO;IACvB,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO;IACrB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO;IACtB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO;IACtB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO;IACtB,wDAAwD;IACxD,2EAA2E;IAC3E,0EAA0E;IAC1E,sEAAsE;IACtE,uEAAuE;IACvE,wEAAwE;IACxE,yEAAyE;IACzE,gCAAgC;IAChC,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,OAAO;IAC7B,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,SAAS;IAC5B,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,WAAW;CAC/B,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,IAA0B,EAAU,EAAE;IACtE,OAAO,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AACzC,CAAC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,2BAA2B,GAA0C;IACzE,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAQ;IACxB,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,OAAQ;IACzB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAQ;IACxB,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,OAAQ;IACtB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAQ;IACvB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAQ;IACvB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAQ;IACvB,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,QAAU;CACjC,CAAA;AAaD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,EAAiC,EAAU,EAAE;IACzG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,0EAA0E,QAAQ,EAAE,CAAC,CAAA;IACvG,CAAC;IAED,MAAM,IAAI,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAA;IAE/C,sEAAsE;IACtE,uEAAuE;IACvE,IAAI,KAAK,KAAK,KAAK,CAAC,YAAY;QAAE,OAAO,IAAI,CAAA;IAE7C,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAA;IACvC,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;AACtC,CAAC,CAAA"}
@@ -23,6 +23,22 @@ export declare const MAYA_SEND_FEE_BASE_UNITS = 2000000000n;
23
23
  * `TerraClassicTax.ULUNA_BASE_GAS`.
24
24
  */
25
25
  export declare const TERRA_CLASSIC_ULUNA_BASE_GAS = 8497500n;
26
+ /**
27
+ * Terra Classic's `uluna` fee paired with the STAKING gas limit
28
+ * (`getCosmosStakingGasLimit({ chain: TerraClassic })`, currently 4M), priced
29
+ * at the same 28.325 uluna/gas chain minimum as `TERRA_CLASSIC_ULUNA_BASE_GAS`.
30
+ *
31
+ * TerraClassic staking runs ~13x hotter than a native send (4M vs 300k gas),
32
+ * so `TERRA_CLASSIC_ULUNA_BASE_GAS` under-prices it by a wide margin, and a
33
+ * consumer pairing the staking gas limit with the send-fee constant (or any
34
+ * other stale hand-picked LUNC figure) gets a SignDoc the node rejects for
35
+ * insufficient fees before delegate / undelegate / redelegate / withdraw-
36
+ * rewards can execute. Computed from `getCosmosStakingGasLimit` rather than
37
+ * hardcoded so a future retune of the staking gas limit can't silently
38
+ * desync the paired fee the way the gas-limit-only bump in vultisig-sdk#1839
39
+ * originally did.
40
+ */
41
+ export declare const TERRA_CLASSIC_STAKING_ULUNA_FEE_BASE_UNITS: bigint;
26
42
  export declare const cosmosGasRecord: Record<IbcEnabledCosmosChain, bigint>;
27
43
  /**
28
44
  * Returns the canonical static native-send fee in base units.
@@ -1 +1 @@
1
- {"version":3,"file":"gas.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/cosmos/gas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,WAAW,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAA4B,KAAK,aAAa,EAAgB,MAAM,iBAAiB,CAAA;AAM5F,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAA;AAE1D,yGAAyG;AACzG,eAAO,MAAM,uBAAuB,QAAQ,CAAA;AAE5C,qEAAqE;AACrE,eAAO,MAAM,wBAAwB,cAAc,CAAA;AAEnD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,4BAA4B,WAAa,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,qBAAqB,EAAE,MAAM,CASjE,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GAAI,OAAO,WAAW,KAAG,MAAM,GAAG,SAIvE,CAAA;AAED,KAAK,SAAS,GAAG;IACf,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACxB,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,CAAA;AAqBD,eAAO,MAAM,sBAAsB,GAAI,iBAAiB,MAAM,EAAE,aAAa,MAAM,KAAG,aAAa,GAAG,SAYrG,CAAA;AA0ED,eAAO,MAAM,kBAAkB,GAC7B,MAAM,OAAO,CAAC,qBAAqB,CAAC,EACpC,OAAM,SAAc,KACnB,OAAO,CAAC,MAAM,CAehB,CAAA"}
1
+ {"version":3,"file":"gas.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/cosmos/gas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,WAAW,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAA4B,KAAK,aAAa,EAAgB,MAAM,iBAAiB,CAAA;AAM5F,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAA;AAE1D,yGAAyG;AACzG,eAAO,MAAM,uBAAuB,QAAQ,CAAA;AAE5C,qEAAqE;AACrE,eAAO,MAAM,wBAAwB,cAAc,CAAA;AAEnD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,4BAA4B,WAAa,CAAA;AAEtD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,0CAA0C,QAGtD,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,qBAAqB,EAAE,MAAM,CASjE,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GAAI,OAAO,WAAW,KAAG,MAAM,GAAG,SAIvE,CAAA;AAED,KAAK,SAAS,GAAG;IACf,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACxB,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,CAAA;AAqBD,eAAO,MAAM,sBAAsB,GAAI,iBAAiB,MAAM,EAAE,aAAa,MAAM,KAAG,aAAa,GAAG,SAYrG,CAAA;AA0ED,eAAO,MAAM,kBAAkB,GAC7B,MAAM,OAAO,CAAC,qBAAqB,CAAC,EACpC,OAAM,SAAc,KACnB,OAAO,CAAC,MAAM,CAehB,CAAA"}
@@ -1,7 +1,7 @@
1
1
  import { Chain } from '../../Chain.js';
2
2
  import { getFeeAmountFromGasPrice, parseDecimal } from './cosmosDecimal.js';
3
3
  import { cosmosFeeCoinDenom } from './cosmosFeeCoinDenom.js';
4
- import { getCosmosGasLimit } from './cosmosGasLimitRecord.js';
4
+ import { getCosmosGasLimit, getCosmosStakingGasLimit } from './cosmosGasLimitRecord.js';
5
5
  import { getCosmosRpcUrl } from './getCosmosRpcUrl.js';
6
6
  import { getOsmosisDynamicFeeFloor } from './osmosisDynamicFee.js';
7
7
  export { getFeeAmountFromGasPrice } from './cosmosDecimal.js';
@@ -26,6 +26,22 @@ export const MAYA_SEND_FEE_BASE_UNITS = 2000000000n;
26
26
  * `TerraClassicTax.ULUNA_BASE_GAS`.
27
27
  */
28
28
  export const TERRA_CLASSIC_ULUNA_BASE_GAS = 8497500n;
29
+ /**
30
+ * Terra Classic's `uluna` fee paired with the STAKING gas limit
31
+ * (`getCosmosStakingGasLimit({ chain: TerraClassic })`, currently 4M), priced
32
+ * at the same 28.325 uluna/gas chain minimum as `TERRA_CLASSIC_ULUNA_BASE_GAS`.
33
+ *
34
+ * TerraClassic staking runs ~13x hotter than a native send (4M vs 300k gas),
35
+ * so `TERRA_CLASSIC_ULUNA_BASE_GAS` under-prices it by a wide margin, and a
36
+ * consumer pairing the staking gas limit with the send-fee constant (or any
37
+ * other stale hand-picked LUNC figure) gets a SignDoc the node rejects for
38
+ * insufficient fees before delegate / undelegate / redelegate / withdraw-
39
+ * rewards can execute. Computed from `getCosmosStakingGasLimit` rather than
40
+ * hardcoded so a future retune of the staking gas limit can't silently
41
+ * desync the paired fee the way the gas-limit-only bump in vultisig-sdk#1839
42
+ * originally did.
43
+ */
44
+ export const TERRA_CLASSIC_STAKING_ULUNA_FEE_BASE_UNITS = getFeeAmountFromGasPrice(getCosmosStakingGasLimit({ chain: Chain.TerraClassic }), parseDecimal('28.325'));
29
45
  export const cosmosGasRecord = {
30
46
  [Chain.Cosmos]: COSMOS_SEND_FEE_DEFAULT,
31
47
  [Chain.Osmosis]: 9000n,
@@ -1 +1 @@
1
- {"version":3,"file":"gas.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/cosmos/gas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gas.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/cosmos/gas.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Why a Kamino service call was refused or failed, as a record union so
3
+ * callers can branch with `matchRecordUnion`.
4
+ */
5
+ export type KaminoServiceErrorReason = {
6
+ /**
7
+ * A structured error from the API. `status` is retained alongside the
8
+ * machine-readable `code` (`KVAULT_NOT_FOUND`, `TRANSACTION_SIZE_ERROR`,
9
+ * …) because Kamino's error envelope carries a `statusCode` of its own
10
+ * and a retryable 503 can arrive in the same body shape as a permanent
11
+ * 400.
12
+ */
13
+ api: {
14
+ status: number;
15
+ code?: string;
16
+ message: string;
17
+ };
18
+ } | {
19
+ /** A numeric field did not parse under the strict decimal rules. */
20
+ malformedNumber: {
21
+ field: string;
22
+ value: string;
23
+ };
24
+ } | {
25
+ /**
26
+ * An amount could not be sent: non-positive, beyond the `u64` an
27
+ * on-chain instruction can carry, or at an implausible decimal scale.
28
+ */
29
+ invalidAmount: string;
30
+ } | {
31
+ /**
32
+ * A vault was described to the service in terms the registry does not
33
+ * recognise. The curated entry is the app's record of a vault's
34
+ * identity; anything else cannot be used to size or target a
35
+ * transaction.
36
+ */
37
+ vaultNotInRegistry: string;
38
+ } | {
39
+ /**
40
+ * The API described a vault differently from the registry. Mints, their
41
+ * decimals and the farm are immutable properties of a kVault, so a
42
+ * disagreement is either the wrong vault or a response that cannot be
43
+ * trusted to size or target a transaction.
44
+ */
45
+ vaultMetadataMismatch: {
46
+ field: string;
47
+ expected: string;
48
+ actual: string;
49
+ };
50
+ };
51
+ /**
52
+ * Typed failure from the Kamino service boundary. Carries a structured
53
+ * `reason` so callers branch on data instead of matching message text, and
54
+ * `isRetryable` so a transient 429/5xx can be told apart from a permanent
55
+ * refusal that arrived in the same shape.
56
+ */
57
+ export declare class KaminoServiceError extends Error {
58
+ readonly reason: KaminoServiceErrorReason;
59
+ constructor(reason: KaminoServiceErrorReason);
60
+ /** Whether retrying the same request could plausibly succeed. */
61
+ get isRetryable(): boolean;
62
+ }
63
+ //# sourceMappingURL=KaminoServiceError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KaminoServiceError.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/solana/kamino/KaminoServiceError.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAChC;IACE;;;;;;OAMG;IACH,GAAG,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;CACxD,GACD;IACE,oEAAoE;IACpE,eAAe,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CAClD,GACD;IACE;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAA;CACtB,GACD;IACE;;;;;OAKG;IACH,kBAAkB,EAAE,MAAM,CAAA;CAC3B,GACD;IACE;;;;;OAKG;IACH,qBAAqB,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAC3E,CAAA;AAEL;;;;;GAKG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAA;gBAE7B,MAAM,EAAE,wBAAwB;IAe5C,iEAAiE;IACjE,IAAI,WAAW,IAAI,OAAO,CAIzB;CACF"}
@@ -0,0 +1,29 @@
1
+ import { matchRecordUnion } from '@vultisig/lib-utils/matchRecordUnion';
2
+ /**
3
+ * Typed failure from the Kamino service boundary. Carries a structured
4
+ * `reason` so callers branch on data instead of matching message text, and
5
+ * `isRetryable` so a transient 429/5xx can be told apart from a permanent
6
+ * refusal that arrived in the same shape.
7
+ */
8
+ export class KaminoServiceError extends Error {
9
+ reason;
10
+ constructor(reason) {
11
+ super(matchRecordUnion(reason, {
12
+ api: ({ code, message }) => (code ? `${code}: ${message}` : message),
13
+ malformedNumber: ({ field, value }) => `Malformed Kamino number for ${field}: ${value}`,
14
+ invalidAmount: detail => `Invalid Kamino amount: ${detail}`,
15
+ vaultNotInRegistry: address => `Kamino vault not in registry: ${address}`,
16
+ vaultMetadataMismatch: ({ field, expected, actual }) => `Kamino vault ${field} is "${actual}", registry pins "${expected}"`,
17
+ }));
18
+ this.name = 'KaminoServiceError';
19
+ this.reason = reason;
20
+ }
21
+ /** Whether retrying the same request could plausibly succeed. */
22
+ get isRetryable() {
23
+ if (!('api' in this.reason))
24
+ return false;
25
+ const { status } = this.reason.api;
26
+ return status === 429 || (status >= 500 && status <= 599);
27
+ }
28
+ }
29
+ //# sourceMappingURL=KaminoServiceError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KaminoServiceError.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/solana/kamino/KaminoServiceError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAA;AA+CvE;;;;;GAKG;AACH,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAClC,MAAM,CAA0B;IAEzC,YAAY,MAAgC;QAC1C,KAAK,CACH,gBAAgB,CAAC,MAAM,EAAE;YACvB,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;YACpE,eAAe,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,+BAA+B,KAAK,KAAK,KAAK,EAAE;YACvF,aAAa,EAAE,MAAM,CAAC,EAAE,CAAC,0BAA0B,MAAM,EAAE;YAC3D,kBAAkB,EAAE,OAAO,CAAC,EAAE,CAAC,iCAAiC,OAAO,EAAE;YACzE,qBAAqB,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,CACrD,gBAAgB,KAAK,QAAQ,MAAM,qBAAqB,QAAQ,GAAG;SACtE,CAAC,CACH,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAA;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAED,iEAAiE;IACjE,IAAI,WAAW;QACb,IAAI,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC;YAAE,OAAO,KAAK,CAAA;QACzC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAA;QAClC,OAAO,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,CAAC,CAAA;IAC3D,CAAC;CACF"}
@@ -0,0 +1,141 @@
1
+ import { KaminoRate } from './rate.js';
2
+ /**
3
+ * An amount denominated in a vault's **underlying token** (USDC, SOL).
4
+ *
5
+ * This is what `POST /ktx/kvault/deposit` expects. Deposit and withdraw take
6
+ * the same `amount` JSON field with inverted units — deposit in tokens,
7
+ * withdraw in shares — so the two are separate types on purpose: passing one
8
+ * where the other belongs is a compile error rather than a silently mis-sized
9
+ * transaction. The `unit` discriminant is what makes that hold under
10
+ * structural typing.
11
+ */
12
+ export type KaminoTokenAmount = {
13
+ unit: 'kaminoToken';
14
+ /** The exact on-chain integer; every other form is derived from it. */
15
+ baseUnits: bigint;
16
+ decimals: number;
17
+ };
18
+ /**
19
+ * An amount denominated in a vault's **share token** (kTokens).
20
+ *
21
+ * This is what `POST /ktx/kvault/withdraw` expects — see `KaminoTokenAmount`
22
+ * for why the units are two distinct types.
23
+ */
24
+ export type KaminoShareAmount = {
25
+ unit: 'kaminoShare';
26
+ /** The exact on-chain integer; every other form is derived from it. */
27
+ baseUnits: bigint;
28
+ decimals: number;
29
+ };
30
+ /** Either Kamino amount unit; use where behaviour is unit-independent. */
31
+ export type KaminoAmount = KaminoTokenAmount | KaminoShareAmount;
32
+ /** Wraps base units as a token amount. */
33
+ export declare const kaminoTokenAmount: (baseUnits: bigint, decimals: number) => KaminoTokenAmount;
34
+ /** Wraps base units as a share amount. */
35
+ export declare const kaminoShareAmount: (baseUnits: bigint, decimals: number) => KaminoShareAmount;
36
+ /**
37
+ * Parses a base-unit integer string as it appears in vault state (e.g.
38
+ * `minDepositAmount = "100000"` for 0.1 USDC). The caller supplies the scale,
39
+ * because the response never says which of the two mints a figure belongs to.
40
+ */
41
+ export declare const kaminoTokenAmountFromBaseUnitString: (raw: string, decimals: number) => KaminoTokenAmount | undefined;
42
+ /**
43
+ * Parses a human-units token decimal string as returned by the metrics
44
+ * endpoint (e.g. `tokensAvailable = "9581.812345"`), exactly, truncating
45
+ * toward zero below the mint's scale.
46
+ */
47
+ export declare const kaminoTokenAmountFromDecimalString: (raw: string, decimals: number) => KaminoTokenAmount | undefined;
48
+ /**
49
+ * Parses a human-units share decimal string as returned by
50
+ * `GET /kvaults/users/{owner}/positions` (e.g. `"517536.857982"`), exactly,
51
+ * truncating toward zero below the mint's scale.
52
+ */
53
+ export declare const kaminoShareAmountFromDecimalString: (raw: string, decimals: number) => KaminoShareAmount | undefined;
54
+ /**
55
+ * Whether this amount may be sent to Kamino: strictly positive, expressible as
56
+ * a `u64`, and at a sane decimal scale. The API accepts anything it can parse
57
+ * — a below-minimum deposit builds a transaction that fails on-chain, and an
58
+ * over-sized withdraw is rewritten to `u64::MAX`, meaning withdraw everything
59
+ * — so bounds are enforced client-side; this is the only gate the API offers.
60
+ */
61
+ export declare const isValidKaminoRequestAmount: ({ baseUnits, decimals }: KaminoAmount) => boolean;
62
+ /**
63
+ * The value as Kamino's request bodies want it: a plain human-units decimal
64
+ * string with no grouping, no trailing zeros and no exponent.
65
+ */
66
+ export declare const kaminoAmountApiString: ({ baseUnits, decimals }: KaminoAmount) => string;
67
+ /**
68
+ * Rescales an exact rate to base units at `toDecimals`, truncating toward
69
+ * zero, plus whether anything was truncated away. `undefined` when the scale
70
+ * is implausible or the value negative.
71
+ *
72
+ * The exactness flag exists for one caller and one reason. `/positions`
73
+ * reports share balances at up to 14 decimal places while a share mint has 6,
74
+ * so the truncated figure is *strictly below* the real balance whenever there
75
+ * were extra digits — and exactly equal to it when there were not. The
76
+ * withdraw maximum has to be strictly below, so it needs to know which of the
77
+ * two happened. See `parseKaminoSharePosition`.
78
+ */
79
+ export declare const scaleKaminoRate: ({ rate, toDecimals, }: {
80
+ rate: KaminoRate;
81
+ toDecimals: number;
82
+ }) => {
83
+ baseUnits: bigint;
84
+ isExact: boolean;
85
+ } | undefined;
86
+ type ShareToTokenInput = {
87
+ shares: KaminoShareAmount;
88
+ /**
89
+ * Underlying tokens per share — `metrics.tokensPerShare`, never
90
+ * `metrics.sharePrice`, which is USD-denominated and only coincides with it
91
+ * on dollar-pegged vaults (Allez SOL: `sharePrice` 0.0794 vs `tokensPerShare`
92
+ * 0.0010749).
93
+ */
94
+ tokensPerShare: KaminoRate;
95
+ tokenDecimals: number;
96
+ };
97
+ /**
98
+ * The position's value in the underlying token: `shares × tokensPerShare`,
99
+ * computed in exact integer arithmetic and truncated toward zero.
100
+ */
101
+ export declare const kaminoShareToTokenValue: (input: ShareToTokenInput) => KaminoTokenAmount | undefined;
102
+ /**
103
+ * The same conversion rounded **up**.
104
+ *
105
+ * Used for one thing only: rendering a share-denominated *minimum* as an asset
106
+ * amount, so the displayed figure, converted back, still clears the minimum.
107
+ * Never use this to size a transaction: rounding up is exactly the direction
108
+ * that turns a partial withdraw into an over-request.
109
+ */
110
+ export declare const kaminoShareToTokenValueRoundedUp: (input: ShareToTokenInput) => KaminoTokenAmount | undefined;
111
+ type TokenToShareInput = {
112
+ tokens: KaminoTokenAmount;
113
+ /** Underlying tokens per share — see `ShareToTokenInput.tokensPerShare`. */
114
+ tokensPerShare: KaminoRate;
115
+ shareDecimals: number;
116
+ };
117
+ /**
118
+ * Converts a token amount into the share amount a withdraw actually burns:
119
+ * `shares = tokens / tokensPerShare`, truncated toward zero.
120
+ *
121
+ * Exact integer arithmetic, never floating point. Rounding down is a safety
122
+ * property, not a preference: the API does not validate the amount, and a
123
+ * withdraw larger than the user's share balance is silently rewritten to
124
+ * `u64::MAX` — "withdraw everything". A division that rounded up, even by one
125
+ * base unit at the far end of the mantissa, could turn a partial withdraw into
126
+ * a full exit. For the same reason a 100% withdraw must send the held share
127
+ * balance directly and never a number derived from here.
128
+ */
129
+ export declare const kaminoTokenToShareAmount: (input: TokenToShareInput) => KaminoShareAmount | undefined;
130
+ /**
131
+ * The same conversion rounded **up**.
132
+ *
133
+ * Used for one thing only: turning a token-denominated *minimum* into the
134
+ * share count a withdraw has to name to clear it. Rounding down there would
135
+ * produce a share figure worth fractionally less than the minimum, which is
136
+ * the whole bug this exists to avoid. Never use it to size a transaction —
137
+ * see `kaminoTokenToShareAmount` for what an over-request becomes.
138
+ */
139
+ export declare const kaminoTokenToShareAmountRoundedUp: (input: TokenToShareInput) => KaminoShareAmount | undefined;
140
+ export {};
141
+ //# sourceMappingURL=amount.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"amount.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/solana/kamino/amount.ts"],"names":[],"mappings":"AACA,OAAO,EAAwB,UAAU,EAAmB,MAAM,QAAQ,CAAA;AAE1E;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,aAAa,CAAA;IACnB,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,aAAa,CAAA;IACnB,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,0EAA0E;AAC1E,MAAM,MAAM,YAAY,GAAG,iBAAiB,GAAG,iBAAiB,CAAA;AAEhE,0CAA0C;AAC1C,eAAO,MAAM,iBAAiB,GAAI,WAAW,MAAM,EAAE,UAAU,MAAM,KAAG,iBAItE,CAAA;AAEF,0CAA0C;AAC1C,eAAO,MAAM,iBAAiB,GAAI,WAAW,MAAM,EAAE,UAAU,MAAM,KAAG,iBAItE,CAAA;AAEF;;;;GAIG;AACH,eAAO,MAAM,mCAAmC,GAAI,KAAK,MAAM,EAAE,UAAU,MAAM,KAAG,iBAAiB,GAAG,SAGvG,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,GAAI,KAAK,MAAM,EAAE,UAAU,MAAM,KAAG,iBAAiB,GAAG,SAKtG,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,GAAI,KAAK,MAAM,EAAE,UAAU,MAAM,KAAG,iBAAiB,GAAG,SAKtG,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,GAAI,yBAAyB,YAAY,KAAG,OACkB,CAAA;AAErG;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAAI,yBAAyB,YAAY,KAAG,MAC9B,CAAA;AAEhD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,GAAI,uBAG7B;IACD,IAAI,EAAE,UAAU,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;CACnB,KAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,SAU7C,CAAA;AAED,KAAK,iBAAiB,GAAG;IACvB,MAAM,EAAE,iBAAiB,CAAA;IACzB;;;;;OAKG;IACH,cAAc,EAAE,UAAU,CAAA;IAC1B,aAAa,EAAE,MAAM,CAAA;CACtB,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB,GAAI,OAAO,iBAAiB,KAAG,iBAAiB,GAAG,SAC3D,CAAA;AAE5B;;;;;;;GAOG;AACH,eAAO,MAAM,gCAAgC,GAAI,OAAO,iBAAiB,KAAG,iBAAiB,GAAG,SACrE,CAAA;AAE3B,KAAK,iBAAiB,GAAG;IACvB,MAAM,EAAE,iBAAiB,CAAA;IACzB,4EAA4E;IAC5E,cAAc,EAAE,UAAU,CAAA;IAC1B,aAAa,EAAE,MAAM,CAAA;CACtB,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,GAAI,OAAO,iBAAiB,KAAG,iBAAiB,GAAG,SAC5D,CAAA;AAE5B;;;;;;;;GAQG;AACH,eAAO,MAAM,iCAAiC,GAAI,OAAO,iBAAiB,KAAG,iBAAiB,GAAG,SACtE,CAAA"}
@@ -0,0 +1,156 @@
1
+ import { kaminoMaxBaseUnits, kaminoMaxDecimals, renderKaminoBaseUnits } from './baseUnits.js';
2
+ import { isPositiveKaminoRate, parseKaminoRate } from './rate.js';
3
+ /** Wraps base units as a token amount. */
4
+ export const kaminoTokenAmount = (baseUnits, decimals) => ({
5
+ unit: 'kaminoToken',
6
+ baseUnits,
7
+ decimals,
8
+ });
9
+ /** Wraps base units as a share amount. */
10
+ export const kaminoShareAmount = (baseUnits, decimals) => ({
11
+ unit: 'kaminoShare',
12
+ baseUnits,
13
+ decimals,
14
+ });
15
+ /**
16
+ * Parses a base-unit integer string as it appears in vault state (e.g.
17
+ * `minDepositAmount = "100000"` for 0.1 USDC). The caller supplies the scale,
18
+ * because the response never says which of the two mints a figure belongs to.
19
+ */
20
+ export const kaminoTokenAmountFromBaseUnitString = (raw, decimals) => {
21
+ const baseUnits = parseBaseUnitString(raw);
22
+ return baseUnits === undefined ? undefined : kaminoTokenAmount(baseUnits, decimals);
23
+ };
24
+ /**
25
+ * Parses a human-units token decimal string as returned by the metrics
26
+ * endpoint (e.g. `tokensAvailable = "9581.812345"`), exactly, truncating
27
+ * toward zero below the mint's scale.
28
+ */
29
+ export const kaminoTokenAmountFromDecimalString = (raw, decimals) => {
30
+ const rate = parseKaminoRate(raw);
31
+ if (!rate)
32
+ return undefined;
33
+ const scaled = scaleKaminoRate({ rate, toDecimals: decimals });
34
+ return scaled === undefined ? undefined : kaminoTokenAmount(scaled.baseUnits, decimals);
35
+ };
36
+ /**
37
+ * Parses a human-units share decimal string as returned by
38
+ * `GET /kvaults/users/{owner}/positions` (e.g. `"517536.857982"`), exactly,
39
+ * truncating toward zero below the mint's scale.
40
+ */
41
+ export const kaminoShareAmountFromDecimalString = (raw, decimals) => {
42
+ const rate = parseKaminoRate(raw);
43
+ if (!rate)
44
+ return undefined;
45
+ const scaled = scaleKaminoRate({ rate, toDecimals: decimals });
46
+ return scaled === undefined ? undefined : kaminoShareAmount(scaled.baseUnits, decimals);
47
+ };
48
+ /**
49
+ * Whether this amount may be sent to Kamino: strictly positive, expressible as
50
+ * a `u64`, and at a sane decimal scale. The API accepts anything it can parse
51
+ * — a below-minimum deposit builds a transaction that fails on-chain, and an
52
+ * over-sized withdraw is rewritten to `u64::MAX`, meaning withdraw everything
53
+ * — so bounds are enforced client-side; this is the only gate the API offers.
54
+ */
55
+ export const isValidKaminoRequestAmount = ({ baseUnits, decimals }) => baseUnits > 0n && baseUnits <= kaminoMaxBaseUnits && decimals >= 0 && decimals <= kaminoMaxDecimals;
56
+ /**
57
+ * The value as Kamino's request bodies want it: a plain human-units decimal
58
+ * string with no grouping, no trailing zeros and no exponent.
59
+ */
60
+ export const kaminoAmountApiString = ({ baseUnits, decimals }) => renderKaminoBaseUnits({ baseUnits, decimals });
61
+ /**
62
+ * Rescales an exact rate to base units at `toDecimals`, truncating toward
63
+ * zero, plus whether anything was truncated away. `undefined` when the scale
64
+ * is implausible or the value negative.
65
+ *
66
+ * The exactness flag exists for one caller and one reason. `/positions`
67
+ * reports share balances at up to 14 decimal places while a share mint has 6,
68
+ * so the truncated figure is *strictly below* the real balance whenever there
69
+ * were extra digits — and exactly equal to it when there were not. The
70
+ * withdraw maximum has to be strictly below, so it needs to know which of the
71
+ * two happened. See `parseKaminoSharePosition`.
72
+ */
73
+ export const scaleKaminoRate = ({ rate, toDecimals, }) => {
74
+ if (toDecimals < 0 || toDecimals > kaminoMaxDecimals)
75
+ return undefined;
76
+ if (rate.scale < 0 || rate.scale > kaminoMaxDecimals * 4)
77
+ return undefined;
78
+ if (rate.numerator < 0n)
79
+ return undefined;
80
+ if (toDecimals >= rate.scale) {
81
+ return { baseUnits: rate.numerator * 10n ** BigInt(toDecimals - rate.scale), isExact: true };
82
+ }
83
+ const divisor = 10n ** BigInt(rate.scale - toDecimals);
84
+ return { baseUnits: rate.numerator / divisor, isExact: rate.numerator % divisor === 0n };
85
+ };
86
+ /**
87
+ * The position's value in the underlying token: `shares × tokensPerShare`,
88
+ * computed in exact integer arithmetic and truncated toward zero.
89
+ */
90
+ export const kaminoShareToTokenValue = (input) => shareToToken(input, false);
91
+ /**
92
+ * The same conversion rounded **up**.
93
+ *
94
+ * Used for one thing only: rendering a share-denominated *minimum* as an asset
95
+ * amount, so the displayed figure, converted back, still clears the minimum.
96
+ * Never use this to size a transaction: rounding up is exactly the direction
97
+ * that turns a partial withdraw into an over-request.
98
+ */
99
+ export const kaminoShareToTokenValueRoundedUp = (input) => shareToToken(input, true);
100
+ /**
101
+ * Converts a token amount into the share amount a withdraw actually burns:
102
+ * `shares = tokens / tokensPerShare`, truncated toward zero.
103
+ *
104
+ * Exact integer arithmetic, never floating point. Rounding down is a safety
105
+ * property, not a preference: the API does not validate the amount, and a
106
+ * withdraw larger than the user's share balance is silently rewritten to
107
+ * `u64::MAX` — "withdraw everything". A division that rounded up, even by one
108
+ * base unit at the far end of the mantissa, could turn a partial withdraw into
109
+ * a full exit. For the same reason a 100% withdraw must send the held share
110
+ * balance directly and never a number derived from here.
111
+ */
112
+ export const kaminoTokenToShareAmount = (input) => tokenToShare(input, false);
113
+ /**
114
+ * The same conversion rounded **up**.
115
+ *
116
+ * Used for one thing only: turning a token-denominated *minimum* into the
117
+ * share count a withdraw has to name to clear it. Rounding down there would
118
+ * produce a share figure worth fractionally less than the minimum, which is
119
+ * the whole bug this exists to avoid. Never use it to size a transaction —
120
+ * see `kaminoTokenToShareAmount` for what an over-request becomes.
121
+ */
122
+ export const kaminoTokenToShareAmountRoundedUp = (input) => tokenToShare(input, true);
123
+ const shareToToken = ({ shares, tokensPerShare, tokenDecimals }, roundUp) => {
124
+ if (!isConvertible(tokensPerShare, shares.baseUnits, [tokenDecimals, shares.decimals]))
125
+ return undefined;
126
+ // tokens = shares × rate, in base units:
127
+ // tokensBase = sharesBase × numerator × 10^tokenDecimals
128
+ // ÷ (10^shareDecimals × 10^rateScale)
129
+ const numerator = shares.baseUnits * tokensPerShare.numerator * 10n ** BigInt(tokenDecimals);
130
+ const denominator = 10n ** BigInt(shares.decimals + tokensPerShare.scale);
131
+ return kaminoTokenAmount(divide(numerator, denominator, roundUp), tokenDecimals);
132
+ };
133
+ const tokenToShare = ({ tokens, tokensPerShare, shareDecimals }, roundUp) => {
134
+ if (!isConvertible(tokensPerShare, tokens.baseUnits, [shareDecimals, tokens.decimals]))
135
+ return undefined;
136
+ // shares = tokens ÷ rate, in base units:
137
+ // sharesBase = tokensBase × 10^rateScale × 10^shareDecimals
138
+ // ÷ (10^tokenDecimals × numerator)
139
+ const numerator = tokens.baseUnits * 10n ** BigInt(tokensPerShare.scale + shareDecimals);
140
+ const denominator = 10n ** BigInt(tokens.decimals) * tokensPerShare.numerator;
141
+ return kaminoShareAmount(divide(numerator, denominator, roundUp), shareDecimals);
142
+ };
143
+ const isConvertible = (rate, baseUnits, decimalScales) => isPositiveKaminoRate(rate) &&
144
+ baseUnits >= 0n &&
145
+ rate.scale >= 0 &&
146
+ rate.scale <= kaminoMaxDecimals * 4 &&
147
+ decimalScales.every(decimals => decimals >= 0 && decimals <= kaminoMaxDecimals);
148
+ const divide = (numerator, denominator, roundUp) => roundUp ? (numerator + denominator - 1n) / denominator : numerator / denominator;
149
+ // Unsigned on purpose: base-unit fields are u64 values, so a signed string is
150
+ // a malformed response, not a negative amount.
151
+ const parseBaseUnitString = (raw) => {
152
+ if (!/^\d+$/.test(raw))
153
+ return undefined;
154
+ return BigInt(raw);
155
+ };
156
+ //# sourceMappingURL=amount.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"amount.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/solana/kamino/amount.ts"],"names":[],"mappings":"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"}