@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
@@ -0,0 +1,57 @@
1
+ /**
2
+ * An exact decimal value from the API, held as `numerator / 10^scale`.
3
+ *
4
+ * This exists because floating-point (and any fixed-precision decimal)
5
+ * arithmetic rounds. A share rate drives how many shares a withdraw burns, and
6
+ * the API does not validate amounts — it rewrites an over-sized withdraw to
7
+ * `u64::MAX`, meaning *withdraw everything*. A division that rounded up at the
8
+ * far end of the mantissa could therefore turn a partial withdraw into a full
9
+ * exit. Integer arithmetic removes the question.
10
+ */
11
+ export type KaminoRate = {
12
+ numerator: bigint;
13
+ /** Denominator exponent: the value is `numerator / 10^scale`. */
14
+ scale: number;
15
+ };
16
+ /**
17
+ * Parses Kamino's decimal-string form exactly, with no intermediate binary or
18
+ * fixed-precision representation. `undefined` when the string is not a plain
19
+ * decimal.
20
+ */
21
+ export declare const parseKaminoRate: (raw: string) => KaminoRate | undefined;
22
+ /** Whether the rate names a value strictly above zero. */
23
+ export declare const isPositiveKaminoRate: (rate: KaminoRate) => boolean;
24
+ /**
25
+ * This value's numerator at `targetScale` decimal places, or `undefined` when
26
+ * the target is too coarse to hold it without loss.
27
+ */
28
+ export declare const kaminoRateNumeratorAtScale: (rate: KaminoRate, targetScale: number) => bigint | undefined;
29
+ /**
30
+ * The exact sum of two API decimal strings, or `undefined` when either is not
31
+ * one.
32
+ *
33
+ * Exists so two reported figures can be added at the precision they were
34
+ * reported at, rather than after each has been truncated to a mint's scale.
35
+ * See `parseKaminoSharePosition` for why that distinction is the difference
36
+ * between a guard and a false refusal.
37
+ */
38
+ export declare const sumKaminoRates: (lhs: string, rhs: string) => KaminoRate | undefined;
39
+ /**
40
+ * Whether `raw` names exactly the same number as `rate`. `false` when it is
41
+ * not a plain decimal at all — an unreadable figure is never equal to a
42
+ * readable one.
43
+ */
44
+ export declare const kaminoRateEquals: (rate: KaminoRate, raw: string) => boolean;
45
+ /**
46
+ * Orders two exact rates: negative when `lhs < rhs`, zero when equal,
47
+ * positive when `lhs > rhs`. Both values are brought to a common scale first,
48
+ * so the comparison happens at full reported precision rather than after a
49
+ * truncation that could mask a one-base-unit difference.
50
+ */
51
+ export declare const compareKaminoRates: (lhs: KaminoRate, rhs: KaminoRate) => number;
52
+ /**
53
+ * Renders the rate back to its plain decimal-string form (no trailing zeros,
54
+ * no exponent).
55
+ */
56
+ export declare const renderKaminoRate: (rate: KaminoRate) => string;
57
+ //# sourceMappingURL=rate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/solana/kamino/rate.ts"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,KAAK,MAAM,KAAG,UAAU,GAAG,SAgB1D,CAAA;AAED,0DAA0D;AAC1D,eAAO,MAAM,oBAAoB,GAAI,MAAM,UAAU,KAAG,OAA8B,CAAA;AAEtF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,GAAI,MAAM,UAAU,EAAE,aAAa,MAAM,KAAG,MAAM,GAAG,SAG3F,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,EAAE,KAAK,MAAM,KAAG,UAAU,GAAG,SAWtE,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,UAAU,EAAE,KAAK,MAAM,KAAG,OAQhE,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,KAAK,UAAU,EAAE,KAAK,UAAU,KAAG,MAMrE,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,UAAU,KAAG,MACwB,CAAA"}
@@ -0,0 +1,88 @@
1
+ import { renderKaminoBaseUnits } from './baseUnits.js';
2
+ import { isPlainKaminoDecimal } from './decimal.js';
3
+ /**
4
+ * Parses Kamino's decimal-string form exactly, with no intermediate binary or
5
+ * fixed-precision representation. `undefined` when the string is not a plain
6
+ * decimal.
7
+ */
8
+ export const parseKaminoRate = (raw) => {
9
+ if (!isPlainKaminoDecimal(raw))
10
+ return undefined;
11
+ const separatorIndex = raw.indexOf('.');
12
+ const whole = separatorIndex === -1 ? raw : raw.slice(0, separatorIndex);
13
+ const fraction = separatorIndex === -1 ? '' : raw.slice(separatorIndex + 1);
14
+ // isPlainKaminoDecimal guarantees at least one digit, so `digits` is never
15
+ // empty even for forms like ".5" or "-.5".
16
+ const sign = whole.startsWith('-') ? -1n : 1n;
17
+ const digits = (whole.startsWith('-') ? whole.slice(1) : whole) + fraction;
18
+ return {
19
+ numerator: sign * BigInt(digits),
20
+ scale: fraction.length,
21
+ };
22
+ };
23
+ /** Whether the rate names a value strictly above zero. */
24
+ export const isPositiveKaminoRate = (rate) => rate.numerator > 0n;
25
+ /**
26
+ * This value's numerator at `targetScale` decimal places, or `undefined` when
27
+ * the target is too coarse to hold it without loss.
28
+ */
29
+ export const kaminoRateNumeratorAtScale = (rate, targetScale) => {
30
+ if (targetScale < rate.scale)
31
+ return undefined;
32
+ return rate.numerator * 10n ** BigInt(targetScale - rate.scale);
33
+ };
34
+ /**
35
+ * The exact sum of two API decimal strings, or `undefined` when either is not
36
+ * one.
37
+ *
38
+ * Exists so two reported figures can be added at the precision they were
39
+ * reported at, rather than after each has been truncated to a mint's scale.
40
+ * See `parseKaminoSharePosition` for why that distinction is the difference
41
+ * between a guard and a false refusal.
42
+ */
43
+ export const sumKaminoRates = (lhs, rhs) => {
44
+ const left = parseKaminoRate(lhs);
45
+ const right = parseKaminoRate(rhs);
46
+ if (!left || !right)
47
+ return undefined;
48
+ const scale = Math.max(left.scale, right.scale);
49
+ const a = kaminoRateNumeratorAtScale(left, scale);
50
+ const b = kaminoRateNumeratorAtScale(right, scale);
51
+ if (a === undefined || b === undefined)
52
+ return undefined;
53
+ return { numerator: a + b, scale };
54
+ };
55
+ /**
56
+ * Whether `raw` names exactly the same number as `rate`. `false` when it is
57
+ * not a plain decimal at all — an unreadable figure is never equal to a
58
+ * readable one.
59
+ */
60
+ export const kaminoRateEquals = (rate, raw) => {
61
+ const other = parseKaminoRate(raw);
62
+ if (!other)
63
+ return false;
64
+ const scale = Math.max(rate.scale, other.scale);
65
+ const a = kaminoRateNumeratorAtScale(rate, scale);
66
+ const b = kaminoRateNumeratorAtScale(other, scale);
67
+ return a !== undefined && b !== undefined && a === b;
68
+ };
69
+ /**
70
+ * Orders two exact rates: negative when `lhs < rhs`, zero when equal,
71
+ * positive when `lhs > rhs`. Both values are brought to a common scale first,
72
+ * so the comparison happens at full reported precision rather than after a
73
+ * truncation that could mask a one-base-unit difference.
74
+ */
75
+ export const compareKaminoRates = (lhs, rhs) => {
76
+ const scale = Math.max(lhs.scale, rhs.scale);
77
+ const a = lhs.numerator * 10n ** BigInt(scale - lhs.scale);
78
+ const b = rhs.numerator * 10n ** BigInt(scale - rhs.scale);
79
+ if (a === b)
80
+ return 0;
81
+ return a < b ? -1 : 1;
82
+ };
83
+ /**
84
+ * Renders the rate back to its plain decimal-string form (no trailing zeros,
85
+ * no exponent).
86
+ */
87
+ export const renderKaminoRate = (rate) => renderKaminoBaseUnits({ baseUnits: rate.numerator, decimals: rate.scale });
88
+ //# sourceMappingURL=rate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/solana/kamino/rate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAkBhD;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAW,EAA0B,EAAE;IACrE,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAA;IAEhD,MAAM,cAAc,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACvC,MAAM,KAAK,GAAG,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,CAAA;IACxE,MAAM,QAAQ,GAAG,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC,CAAA;IAE3E,2EAA2E;IAC3E,2CAA2C;IAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IAC7C,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAA;IAE1E,OAAO;QACL,SAAS,EAAE,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC;QAChC,KAAK,EAAE,QAAQ,CAAC,MAAM;KACvB,CAAA;AACH,CAAC,CAAA;AAED,0DAA0D;AAC1D,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,IAAgB,EAAW,EAAE,CAAC,IAAI,CAAC,SAAS,GAAG,EAAE,CAAA;AAEtF;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,IAAgB,EAAE,WAAmB,EAAsB,EAAE;IACtG,IAAI,WAAW,GAAG,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAA;IAC9C,OAAO,IAAI,CAAC,SAAS,GAAG,GAAG,IAAI,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;AACjE,CAAC,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAAW,EAAE,GAAW,EAA0B,EAAE;IACjF,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;IACjC,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;IAClC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAA;IAErC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IAC/C,MAAM,CAAC,GAAG,0BAA0B,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IACjD,MAAM,CAAC,GAAG,0BAA0B,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IAClD,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAExD,OAAO,EAAE,SAAS,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAA;AACpC,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAgB,EAAE,GAAW,EAAW,EAAE;IACzE,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;IAClC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAA;IAExB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IAC/C,MAAM,CAAC,GAAG,0BAA0B,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IACjD,MAAM,CAAC,GAAG,0BAA0B,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IAClD,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,CAAA;AACtD,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,GAAe,EAAE,GAAe,EAAU,EAAE;IAC7E,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAA;IAC5C,MAAM,CAAC,GAAG,GAAG,CAAC,SAAS,GAAG,GAAG,IAAI,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAA;IAC1D,MAAM,CAAC,GAAG,GAAG,CAAC,SAAS,GAAG,GAAG,IAAI,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAA;IAC1D,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAA;IACrB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AACvB,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAgB,EAAU,EAAE,CAC3D,qBAAqB,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Relative risk of a launch vault, used to order and label them.
3
+ *
4
+ * This is curation, not API data — Kamino exposes no risk or curator field
5
+ * anywhere, so both live here and travel with the allow-list.
6
+ *
7
+ * `conservative` is plain over-collateralised lending against liquid crypto
8
+ * collateral. `privateCredit` lends against tokenized private credit —
9
+ * reinsurance, receivables and corporate bonds — which is materially different
10
+ * risk and must not be presented as government-backed.
11
+ */
12
+ export declare const kaminoRiskTiers: readonly ["conservative", "privateCredit"];
13
+ /** One of the curated risk-tier labels a launch vault is shown under. */
14
+ export type KaminoRiskTier = (typeof kaminoRiskTiers)[number];
15
+ /**
16
+ * A curated vault the app offers.
17
+ *
18
+ * This carries everything a transaction is checked against, because a value
19
+ * fetched from the API cannot be used to validate a transaction built by the
20
+ * same API — the check would be circular, and a compromised response could
21
+ * supply a matching pair. The fields below are all immutable properties of the
22
+ * vault: a kVault's mints, their decimals and its farm are fixed at creation.
23
+ * Everything that legitimately moves — name, minimums, APY, rates, the lookup
24
+ * table — stays live, and the vault-info hydration refuses a response that
25
+ * disagrees with the pinned identity.
26
+ */
27
+ export type KaminoVaultDescriptor = {
28
+ address: string;
29
+ /**
30
+ * The vault's underlying token mint. Pinned: the deposit source and the
31
+ * withdraw destination are derived from it.
32
+ */
33
+ tokenMint: string;
34
+ /**
35
+ * Pinned because it scales every amount. A wrong scale mis-sizes the
36
+ * transfer by a power of ten while every other check still passes.
37
+ */
38
+ tokenDecimals: number;
39
+ sharesMint: string;
40
+ sharesDecimals: number;
41
+ /**
42
+ * The farm a deposit stakes into, or `undefined` when the vault has none.
43
+ * Pinned because `farms::stake` moves the whole share balance into it.
44
+ */
45
+ farm?: string;
46
+ /** Shown until live state arrives, and as the fallback if it never does. */
47
+ fallbackName: string;
48
+ curator: string;
49
+ riskTier: KaminoRiskTier;
50
+ };
51
+ /**
52
+ * The curated set of Kamino Earn vaults the app exposes.
53
+ *
54
+ * Kamino runs 160+ vaults; `GET /kvaults/vaults` returns all of them as a
55
+ * single ~340 KB payload. The allow-list both curates and keeps the fetch
56
+ * small — the three entries are hydrated with three ~2.8 KB per-vault requests
57
+ * instead.
58
+ *
59
+ * The share scale is independent of the token scale — 6 against 9 on the SOL
60
+ * vault — so nothing may assume the two match.
61
+ */
62
+ export declare const kaminoVaultRegistry: readonly KaminoVaultDescriptor[];
63
+ /**
64
+ * Resolves the curated entry for a vault address, or `undefined` for any
65
+ * address the registry does not carry. The returned descriptor is the app's
66
+ * record of the vault's identity — always resolve through here rather than
67
+ * accepting descriptor-shaped data from elsewhere.
68
+ */
69
+ export declare const getKaminoVaultDescriptor: (address: string) => KaminoVaultDescriptor | undefined;
70
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/solana/kamino/registry.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,4CAA6C,CAAA;AAEzE,yEAAyE;AACzE,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAA;AAE7D;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,4EAA4E;IAC5E,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,cAAc,CAAA;CACzB,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,qBAAqB,EAkC/D,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GAAI,SAAS,MAAM,KAAG,qBAAqB,GAAG,SACrB,CAAA"}
@@ -0,0 +1,67 @@
1
+ import { kaminoConfig } from './config.js';
2
+ /**
3
+ * Relative risk of a launch vault, used to order and label them.
4
+ *
5
+ * This is curation, not API data — Kamino exposes no risk or curator field
6
+ * anywhere, so both live here and travel with the allow-list.
7
+ *
8
+ * `conservative` is plain over-collateralised lending against liquid crypto
9
+ * collateral. `privateCredit` lends against tokenized private credit —
10
+ * reinsurance, receivables and corporate bonds — which is materially different
11
+ * risk and must not be presented as government-backed.
12
+ */
13
+ export const kaminoRiskTiers = ['conservative', 'privateCredit'];
14
+ /**
15
+ * The curated set of Kamino Earn vaults the app exposes.
16
+ *
17
+ * Kamino runs 160+ vaults; `GET /kvaults/vaults` returns all of them as a
18
+ * single ~340 KB payload. The allow-list both curates and keeps the fetch
19
+ * small — the three entries are hydrated with three ~2.8 KB per-vault requests
20
+ * instead.
21
+ *
22
+ * The share scale is independent of the token scale — 6 against 9 on the SOL
23
+ * vault — so nothing may assume the two match.
24
+ */
25
+ export const kaminoVaultRegistry = [
26
+ {
27
+ address: 'HDsayqAsDWy3QvANGqh2yNraqcD8Fnjgh73Mhb3WRS5E',
28
+ tokenMint: kaminoConfig.usdcMint,
29
+ tokenDecimals: 6,
30
+ sharesMint: '7D8C5pDFxug58L9zkwK7bCiDg4kD4AygzbcZUmf5usHS',
31
+ sharesDecimals: 6,
32
+ farm: '9FVjHqduhDPMVqvu3cXiEBjU6nvxvGdCCLRwd9WpVRZj',
33
+ fallbackName: 'Steakhouse USDC',
34
+ curator: 'Steakhouse Financial',
35
+ riskTier: 'conservative',
36
+ },
37
+ {
38
+ address: 'DWSXb18xZApz29vnQpgR2m6MynCT7PznaXt7Ut7M7KaP',
39
+ tokenMint: kaminoConfig.usdcMint,
40
+ tokenDecimals: 6,
41
+ sharesMint: 'DgHN3q3dSYAchNX7V3D4aYiTWMx8RHTgHbfPiwiqBkE9',
42
+ sharesDecimals: 6,
43
+ farm: 'ArwyAHmnFmbKbUxC2fnK5VUEpspHrnoFtJ22bvEyriKk',
44
+ fallbackName: 'RWA USDC',
45
+ curator: 'RockawayX',
46
+ riskTier: 'privateCredit',
47
+ },
48
+ {
49
+ address: 'A1so1bPD3W1TfeFwboDh8yfAAVaVtcdAYBYCjhg2mJQ',
50
+ tokenMint: kaminoConfig.wrappedSolMint,
51
+ tokenDecimals: 9,
52
+ sharesMint: 'FiM4VQdXXnTXL7GgChryf9zHNG9cmvKECwf34L2y3CkN',
53
+ sharesDecimals: 6,
54
+ farm: 'H6kauPaHmNqpdKtD5U2zw3Eb28ZB7iMeBdHVfLq1i4Kh',
55
+ fallbackName: 'Allez SOL',
56
+ curator: 'Allez Labs',
57
+ riskTier: 'conservative',
58
+ },
59
+ ];
60
+ /**
61
+ * Resolves the curated entry for a vault address, or `undefined` for any
62
+ * address the registry does not carry. The returned descriptor is the app's
63
+ * record of the vault's identity — always resolve through here rather than
64
+ * accepting descriptor-shaped data from elsewhere.
65
+ */
66
+ export const getKaminoVaultDescriptor = (address) => kaminoVaultRegistry.find(vault => vault.address === address);
67
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/solana/kamino/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAEvC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,cAAc,EAAE,eAAe,CAAU,CAAA;AA0CzE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAqC;IACnE;QACE,OAAO,EAAE,8CAA8C;QACvD,SAAS,EAAE,YAAY,CAAC,QAAQ;QAChC,aAAa,EAAE,CAAC;QAChB,UAAU,EAAE,8CAA8C;QAC1D,cAAc,EAAE,CAAC;QACjB,IAAI,EAAE,8CAA8C;QACpD,YAAY,EAAE,iBAAiB;QAC/B,OAAO,EAAE,sBAAsB;QAC/B,QAAQ,EAAE,cAAc;KACzB;IACD;QACE,OAAO,EAAE,8CAA8C;QACvD,SAAS,EAAE,YAAY,CAAC,QAAQ;QAChC,aAAa,EAAE,CAAC;QAChB,UAAU,EAAE,8CAA8C;QAC1D,cAAc,EAAE,CAAC;QACjB,IAAI,EAAE,8CAA8C;QACpD,YAAY,EAAE,UAAU;QACxB,OAAO,EAAE,WAAW;QACpB,QAAQ,EAAE,eAAe;KAC1B;IACD;QACE,OAAO,EAAE,6CAA6C;QACtD,SAAS,EAAE,YAAY,CAAC,cAAc;QACtC,aAAa,EAAE,CAAC;QAChB,UAAU,EAAE,8CAA8C;QAC1D,cAAc,EAAE,CAAC;QACjB,IAAI,EAAE,8CAA8C;QACpD,YAAY,EAAE,WAAW;QACzB,OAAO,EAAE,YAAY;QACrB,QAAQ,EAAE,cAAc;KACzB;CACF,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,OAAe,EAAqC,EAAE,CAC7F,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,KAAK,OAAO,CAAC,CAAA"}
@@ -0,0 +1,22 @@
1
+ import { KaminoShareAmount, KaminoTokenAmount } from '../amount.js';
2
+ /**
3
+ * Builds an unsigned deposit transaction. The amount is in the vault's
4
+ * underlying token — the type enforces it. The vault is resolved through the
5
+ * registry, so an arbitrary address cannot reach Kamino through here.
6
+ */
7
+ export declare const buildKaminoDepositTransaction: ({ owner, vaultAddress, amount, }: {
8
+ owner: string;
9
+ vaultAddress: string;
10
+ amount: KaminoTokenAmount;
11
+ }) => Promise<string>;
12
+ /**
13
+ * Builds an unsigned withdraw transaction. The amount is in SHARES — the
14
+ * inverse of deposit. This asymmetry is the API's, not ours, and the type is
15
+ * what keeps the two from crossing.
16
+ */
17
+ export declare const buildKaminoWithdrawTransaction: ({ owner, vaultAddress, shares, }: {
18
+ owner: string;
19
+ vaultAddress: string;
20
+ shares: KaminoShareAmount;
21
+ }) => Promise<string>;
22
+ //# sourceMappingURL=actions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/solana/kamino/tx/actions.ts"],"names":[],"mappings":"AAGA,OAAO,EAAqD,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAuFnH;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,GAAU,kCAIjD;IACD,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,iBAAiB,CAAA;CAC1B,KAAG,OAAO,CAAC,MAAM,CAQjB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,GAAU,kCAIlD;IACD,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,iBAAiB,CAAA;CAC1B,KAAG,OAAO,CAAC,MAAM,CAoBjB,CAAA"}
@@ -0,0 +1,85 @@
1
+ import { HttpResponseError } from '@vultisig/lib-utils/fetch/HttpResponseError';
2
+ import { queryUrl } from '@vultisig/lib-utils/query/queryUrl';
3
+ import { isValidKaminoRequestAmount, kaminoAmountApiString } from '../amount.js';
4
+ import { kaminoMaxBaseUnits } from '../baseUnits.js';
5
+ import { kaminoConfig } from '../config.js';
6
+ import { KaminoServiceError } from '../KaminoServiceError.js';
7
+ import { getKaminoVaultDescriptor } from '../registry.js';
8
+ const isKaminoErrorBody = (body) => typeof body === 'object' &&
9
+ body !== null &&
10
+ typeof body.statusCode === 'number' &&
11
+ typeof body.message === 'string';
12
+ const buildTransaction = async (path, body) => {
13
+ try {
14
+ const response = await queryUrl(`${kaminoConfig.apiBaseUrl}${path}`, { body });
15
+ // The type parameter asserts the response shape; it does not check it. A
16
+ // 200 without a transaction would otherwise surface downstream as an
17
+ // unreadable-transaction failure instead of naming the real cause.
18
+ if (typeof response?.transaction !== 'string' || response.transaction.length === 0) {
19
+ throw new KaminoServiceError({ api: { status: 200, message: `${path} response carried no transaction` } });
20
+ }
21
+ return response.transaction;
22
+ }
23
+ catch (error) {
24
+ if (error instanceof HttpResponseError && isKaminoErrorBody(error.body)) {
25
+ throw new KaminoServiceError({
26
+ api: { status: error.status, code: error.body.code, message: error.body.message },
27
+ });
28
+ }
29
+ throw error;
30
+ }
31
+ };
32
+ const requireCuratedVault = (vaultAddress) => {
33
+ const descriptor = getKaminoVaultDescriptor(vaultAddress);
34
+ if (!descriptor)
35
+ throw new KaminoServiceError({ vaultNotInRegistry: vaultAddress });
36
+ return descriptor;
37
+ };
38
+ const requireValidAmount = (amount, label) => {
39
+ if (!isValidKaminoRequestAmount(amount)) {
40
+ throw new KaminoServiceError({
41
+ invalidAmount: `${label} amount ${amount.baseUnits} at ${amount.decimals} decimals is out of range`,
42
+ });
43
+ }
44
+ };
45
+ /**
46
+ * Builds an unsigned deposit transaction. The amount is in the vault's
47
+ * underlying token — the type enforces it. The vault is resolved through the
48
+ * registry, so an arbitrary address cannot reach Kamino through here.
49
+ */
50
+ export const buildKaminoDepositTransaction = async ({ owner, vaultAddress, amount, }) => {
51
+ const descriptor = requireCuratedVault(vaultAddress);
52
+ requireValidAmount(amount, 'deposit');
53
+ return buildTransaction('/ktx/kvault/deposit', {
54
+ wallet: owner,
55
+ kvault: descriptor.address,
56
+ amount: kaminoAmountApiString(amount),
57
+ });
58
+ };
59
+ /**
60
+ * Builds an unsigned withdraw transaction. The amount is in SHARES — the
61
+ * inverse of deposit. This asymmetry is the API's, not ours, and the type is
62
+ * what keeps the two from crossing.
63
+ */
64
+ export const buildKaminoWithdrawTransaction = async ({ owner, vaultAddress, shares, }) => {
65
+ const descriptor = requireCuratedVault(vaultAddress);
66
+ requireValidAmount(shares, 'withdraw');
67
+ // u64::MAX is the API's own "withdraw everything" sentinel: it is what a
68
+ // request AT OR ABOVE the user's balance is silently rewritten to. No
69
+ // legitimate share balance is 18.4 quintillion base units, so refusing the
70
+ // value outright costs nothing and closes the one way this app could name
71
+ // it directly. The spendable-balance rule in `parseKaminoSharePosition` is
72
+ // what keeps every request strictly below the balance; the validator is
73
+ // what refuses the response if a sentinel arrives anyway.
74
+ if (shares.baseUnits >= kaminoMaxBaseUnits) {
75
+ throw new KaminoServiceError({
76
+ invalidAmount: `withdraw amount ${shares.baseUnits} is the withdraw-everything sentinel`,
77
+ });
78
+ }
79
+ return buildTransaction('/ktx/kvault/withdraw', {
80
+ wallet: owner,
81
+ kvault: descriptor.address,
82
+ amount: kaminoAmountApiString(shares),
83
+ });
84
+ };
85
+ //# sourceMappingURL=actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/solana/kamino/tx/actions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ import { KaminoVaultDescriptor } from '../registry.js';
2
+ /**
3
+ * Compute-budget parameters for the ComputeBudget instructions the app
4
+ * injects into Kamino's transactions.
5
+ *
6
+ * Kamino builds its transactions with NO ComputeBudget instruction at all,
7
+ * and ignores fee fields in the request body — the response is byte-identical
8
+ * with or without them. So the only way a Kamino transaction carries a
9
+ * priority fee is for the app to inject one, and injecting a price without a
10
+ * limit would price the fee off the runtime's default limit rather than the
11
+ * units the transaction actually needs.
12
+ *
13
+ * The limits carry roughly a quarter over what each shape measured in mainnet
14
+ * simulation (`err: null`): USDC deposit 252,146 · SOL deposit 287,029 ·
15
+ * unstaked withdraw 173,251 · farm-staked withdraw up to 309,310. The margin
16
+ * absorbs the drift a different account-existence mix causes — a deposit
17
+ * whose share ATA or farm user account still has to be created does strictly
18
+ * more work than one whose accounts already exist.
19
+ */
20
+ export declare const kaminoComputeBudget: {
21
+ /** Compute-unit limit for a deposit into a token vault. */
22
+ readonly tokenDepositUnitLimit: 320000;
23
+ /**
24
+ * A SOL-vault deposit additionally creates the wSOL account, transfers into
25
+ * it and syncs it, so it costs more than a token deposit.
26
+ */
27
+ readonly nativeDepositUnitLimit: 350000;
28
+ /**
29
+ * One limit for BOTH withdraw shapes, sized for the expensive one — the
30
+ * farm-staked path runs two extra farms instructions and a second account
31
+ * creation ahead of the vault withdraw. One value per operation keeps the
32
+ * limit pinnable by the verify screen; the unstaked path pays a few
33
+ * thousand lamports of headroom in exchange.
34
+ */
35
+ readonly withdrawUnitLimit: 400000;
36
+ /**
37
+ * Price used when the network's recent-fee sample is unavailable, in
38
+ * micro-lamports per compute unit. The live median is preferred; this is
39
+ * the floor beneath it — a sample below it would under-tip a transaction
40
+ * that has to land before its blockhash expires.
41
+ */
42
+ readonly fallbackUnitPriceMicroLamports: 20000n;
43
+ /**
44
+ * Ceiling on the live price. The recent-fee sample is a number a remote
45
+ * node hands us, multiplied by a six-figure compute limit into lamports the
46
+ * user pays — unbounded, a wrong or hostile sample is an unbounded fee. At
47
+ * this ceiling and the largest limit the priority fee tops out at 400,000
48
+ * lamports (0.0004 SOL).
49
+ */
50
+ readonly maxUnitPriceMicroLamports: 1000000n;
51
+ };
52
+ /**
53
+ * The compute-unit limit this app injects for one operation against one
54
+ * vault. Pinned rather than bounded by the checks: the app injects exactly
55
+ * one value, so any other one did not come from it.
56
+ */
57
+ export declare const kaminoExpectedUnitLimit: ({ operation, descriptor, }: {
58
+ operation: "deposit" | "withdraw";
59
+ descriptor: KaminoVaultDescriptor;
60
+ }) => number;
61
+ /**
62
+ * Brings a sampled network price inside `[fallback, max]` — the fallback is a
63
+ * floor rather than a default.
64
+ */
65
+ export declare const clampKaminoUnitPrice: (sampled: bigint) => bigint;
66
+ //# sourceMappingURL=computeBudget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computeBudget.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/solana/kamino/tx/computeBudget.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAEnD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,mBAAmB;IAC9B,2DAA2D;;IAE3D;;;OAGG;;IAEH;;;;;;OAMG;;IAEH;;;;;OAKG;;IAEH;;;;;;OAMG;;CAEK,CAAA;AAEV;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,GAAI,4BAGrC;IACD,SAAS,EAAE,SAAS,GAAG,UAAU,CAAA;IACjC,UAAU,EAAE,qBAAqB,CAAA;CAClC,KAAG,MAKH,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAS,MAAM,KAAG,MAItD,CAAA"}
@@ -0,0 +1,73 @@
1
+ import { kaminoConfig } from '../config.js';
2
+ /**
3
+ * Compute-budget parameters for the ComputeBudget instructions the app
4
+ * injects into Kamino's transactions.
5
+ *
6
+ * Kamino builds its transactions with NO ComputeBudget instruction at all,
7
+ * and ignores fee fields in the request body — the response is byte-identical
8
+ * with or without them. So the only way a Kamino transaction carries a
9
+ * priority fee is for the app to inject one, and injecting a price without a
10
+ * limit would price the fee off the runtime's default limit rather than the
11
+ * units the transaction actually needs.
12
+ *
13
+ * The limits carry roughly a quarter over what each shape measured in mainnet
14
+ * simulation (`err: null`): USDC deposit 252,146 · SOL deposit 287,029 ·
15
+ * unstaked withdraw 173,251 · farm-staked withdraw up to 309,310. The margin
16
+ * absorbs the drift a different account-existence mix causes — a deposit
17
+ * whose share ATA or farm user account still has to be created does strictly
18
+ * more work than one whose accounts already exist.
19
+ */
20
+ export const kaminoComputeBudget = {
21
+ /** Compute-unit limit for a deposit into a token vault. */
22
+ tokenDepositUnitLimit: 320_000,
23
+ /**
24
+ * A SOL-vault deposit additionally creates the wSOL account, transfers into
25
+ * it and syncs it, so it costs more than a token deposit.
26
+ */
27
+ nativeDepositUnitLimit: 350_000,
28
+ /**
29
+ * One limit for BOTH withdraw shapes, sized for the expensive one — the
30
+ * farm-staked path runs two extra farms instructions and a second account
31
+ * creation ahead of the vault withdraw. One value per operation keeps the
32
+ * limit pinnable by the verify screen; the unstaked path pays a few
33
+ * thousand lamports of headroom in exchange.
34
+ */
35
+ withdrawUnitLimit: 400_000,
36
+ /**
37
+ * Price used when the network's recent-fee sample is unavailable, in
38
+ * micro-lamports per compute unit. The live median is preferred; this is
39
+ * the floor beneath it — a sample below it would under-tip a transaction
40
+ * that has to land before its blockhash expires.
41
+ */
42
+ fallbackUnitPriceMicroLamports: 20000n,
43
+ /**
44
+ * Ceiling on the live price. The recent-fee sample is a number a remote
45
+ * node hands us, multiplied by a six-figure compute limit into lamports the
46
+ * user pays — unbounded, a wrong or hostile sample is an unbounded fee. At
47
+ * this ceiling and the largest limit the priority fee tops out at 400,000
48
+ * lamports (0.0004 SOL).
49
+ */
50
+ maxUnitPriceMicroLamports: 1000000n,
51
+ };
52
+ /**
53
+ * The compute-unit limit this app injects for one operation against one
54
+ * vault. Pinned rather than bounded by the checks: the app injects exactly
55
+ * one value, so any other one did not come from it.
56
+ */
57
+ export const kaminoExpectedUnitLimit = ({ operation, descriptor, }) => {
58
+ if (operation === 'withdraw')
59
+ return kaminoComputeBudget.withdrawUnitLimit;
60
+ return descriptor.tokenMint === kaminoConfig.wrappedSolMint
61
+ ? kaminoComputeBudget.nativeDepositUnitLimit
62
+ : kaminoComputeBudget.tokenDepositUnitLimit;
63
+ };
64
+ /**
65
+ * Brings a sampled network price inside `[fallback, max]` — the fallback is a
66
+ * floor rather than a default.
67
+ */
68
+ export const clampKaminoUnitPrice = (sampled) => {
69
+ const { fallbackUnitPriceMicroLamports, maxUnitPriceMicroLamports } = kaminoComputeBudget;
70
+ const floored = sampled > fallbackUnitPriceMicroLamports ? sampled : fallbackUnitPriceMicroLamports;
71
+ return floored < maxUnitPriceMicroLamports ? floored : maxUnitPriceMicroLamports;
72
+ };
73
+ //# sourceMappingURL=computeBudget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computeBudget.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/solana/kamino/tx/computeBudget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAGxC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,2DAA2D;IAC3D,qBAAqB,EAAE,OAAO;IAC9B;;;OAGG;IACH,sBAAsB,EAAE,OAAO;IAC/B;;;;;;OAMG;IACH,iBAAiB,EAAE,OAAO;IAC1B;;;;;OAKG;IACH,8BAA8B,EAAE,MAAO;IACvC;;;;;;OAMG;IACH,yBAAyB,EAAE,QAAU;CAC7B,CAAA;AAEV;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,EACtC,SAAS,EACT,UAAU,GAIX,EAAU,EAAE;IACX,IAAI,SAAS,KAAK,UAAU;QAAE,OAAO,mBAAmB,CAAC,iBAAiB,CAAA;IAC1E,OAAO,UAAU,CAAC,SAAS,KAAK,YAAY,CAAC,cAAc;QACzD,CAAC,CAAC,mBAAmB,CAAC,sBAAsB;QAC5C,CAAC,CAAC,mBAAmB,CAAC,qBAAqB,CAAA;AAC/C,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,OAAe,EAAU,EAAE;IAC9D,MAAM,EAAE,8BAA8B,EAAE,yBAAyB,EAAE,GAAG,mBAAmB,CAAA;IACzF,MAAM,OAAO,GAAG,OAAO,GAAG,8BAA8B,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,8BAA8B,CAAA;IACnG,OAAO,OAAO,GAAG,yBAAyB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,yBAAyB,CAAA;AAClF,CAAC,CAAA"}