@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,121 @@
1
+ import { VersionedTransaction } from '@solana/web3.js';
2
+ import { KaminoVaultDescriptor } from '../registry.js';
3
+ import { KaminoPriorityFee } from './validate.js';
4
+ /**
5
+ * What a Kamino transaction does, read back out of the bytes that will be
6
+ * signed.
7
+ *
8
+ * Every field is derived from the wire message plus values the app already
9
+ * holds — the vault registry and the associated-token-account derivation.
10
+ * Nothing here is taken from a payload field, a summary, or the API, because
11
+ * the point of this type is to be an INDEPENDENT reading: the initiator and a
12
+ * co-signing device run the same decode over the same bytes and must arrive
13
+ * at the same claim. A claim that agreed only because both devices were told
14
+ * the same thing would establish nothing.
15
+ */
16
+ export type KaminoDecodedTransaction = {
17
+ operation: 'deposit' | 'withdraw';
18
+ /** The curated vault, resolved from the registry — never a raw address the bytes named. */
19
+ descriptor: KaminoVaultDescriptor;
20
+ /**
21
+ * The `u64` the kvault instruction carries, in the operation's own unit:
22
+ * underlying-token base units for a deposit, SHARE base units for a
23
+ * withdraw.
24
+ */
25
+ amountBaseUnits: bigint;
26
+ /** The sole signer and fee payer — the account that authorises this. */
27
+ signer: string;
28
+ /**
29
+ * A deposit into the wrapped-SOL vault opens a wSOL account this
30
+ * transaction never closes, so its rent stays locked up until the user
31
+ * withdraws.
32
+ */
33
+ strandsWrappedSolRent: boolean;
34
+ /**
35
+ * The ComputeBudget pair the bytes actually carry, or `undefined` when they
36
+ * carry none. Read from the message rather than taken from the payload, so
37
+ * the two can be COMPARED: the payload says what the initiating device
38
+ * injected, the bytes say what will be charged.
39
+ */
40
+ priorityFee?: KaminoPriorityFee;
41
+ };
42
+ /**
43
+ * Whether a withdraw carries the `u64::MAX` sentinel, which the kVaults
44
+ * program reads as *withdraw everything* rather than as a share count. This
45
+ * app never produces one — the builder refuses to request it and the
46
+ * validator pins the instruction's `u64` — but neither of those runs on a
47
+ * co-signing device, which holds only the relayed bytes. Rendering 18.4
48
+ * quintillion shares would be literally true and would say nothing about
49
+ * what the transaction does.
50
+ */
51
+ export declare const withdrawsEntireKaminoPosition: (decoded: KaminoDecodedTransaction) => boolean;
52
+ /** The scale `amountBaseUnits` is expressed at, from the registry. */
53
+ export declare const kaminoDecodedAmountDecimals: (decoded: KaminoDecodedTransaction) => number;
54
+ /** The amount as plain human units — no grouping, no exponent, no locale. */
55
+ export declare const kaminoDecodedAmountString: (decoded: KaminoDecodedTransaction) => string;
56
+ /**
57
+ * Whether these bytes invoke the kVaults program at all. Separate from
58
+ * `decodeKaminoTransaction` on purpose: a transaction that invokes `kvault`
59
+ * but cannot be decoded must be surfaced as unreadable rather than as an
60
+ * ordinary Solana transaction. Program ids are always static keys, so this
61
+ * needs no lookup table.
62
+ */
63
+ export declare const invokesKaminoVaultProgram: (transaction: VersionedTransaction) => boolean;
64
+ /**
65
+ * Whether bytes this app cannot parse nonetheless mention the kVaults
66
+ * program.
67
+ *
68
+ * The structured check above needs a v0 message, but a raw signing path signs
69
+ * wire bytes verbatim without caring what version they are — so a LEGACY
70
+ * transaction invoking kVaults would parse to nothing and, without this, be
71
+ * classified as an ordinary Solana payload and sail past the signing guards.
72
+ * A program id is a 32-byte account key in the message under either format,
73
+ * so scanning for those bytes answers the only question that matters here:
74
+ * is this something we must refuse to stay quiet about?
75
+ *
76
+ * Deliberately coarse, and coarse in the safe direction: a payload that
77
+ * happens to contain these 32 bytes without invoking the program would be
78
+ * refused; a payload that invokes the program cannot escape.
79
+ */
80
+ export declare const mentionsKaminoVaultProgram: (base64Transaction: string) => boolean;
81
+ /**
82
+ * Decodes the single kvault deposit or withdraw these bytes perform, or
83
+ * `undefined` when they do not perform exactly one that this app recognises.
84
+ *
85
+ * `undefined` is a refusal to describe, never a "probably fine". This runs
86
+ * offline — the verify and join screens render before any network call is
87
+ * guaranteed to have happened — so lookup tables cannot be resolved, and the
88
+ * vault is identified the other way round: by deriving each curated vault's
89
+ * share account for this signer and matching it against the instruction's
90
+ * share slot, which is a static key in every observed transaction. That
91
+ * derivation is local, which makes it a stronger identification than reading
92
+ * an address out of the bytes would have been.
93
+ *
94
+ * What this establishes: every instruction fits the shape the named
95
+ * operation produces, the amount is the `u64` the kvault instruction
96
+ * carries, the authority is the transaction's own signer, and the share
97
+ * account that instruction spends or credits is the one this signer owns for
98
+ * the named vault's share mint. Every instruction argument that is a spend
99
+ * and is readable without a lookup table is also checked. What it does not
100
+ * establish is the account identities that live in the lookup table — the
101
+ * initiating device closes that gap by resolving the tables and running the
102
+ * full validator before the payload exists.
103
+ *
104
+ * One residue is specific to the farm-staked withdraw: how many shares a
105
+ * withdraw legitimately releases from the farm is `requested −
106
+ * alreadyUnstaked`, and the second term is a balance that is not in the
107
+ * bytes. So offline the release is bounded by the withdraw itself and no
108
+ * further — while the release provably acts on this signer's own position,
109
+ * in this vault's own farm, into the signer's own share account, with the
110
+ * stranding and misdirection shapes refused by the template and the
111
+ * derivations.
112
+ */
113
+ export declare const decodeKaminoTransaction: (transaction: VersionedTransaction) => KaminoDecodedTransaction | undefined;
114
+ /**
115
+ * Convenience over a raw payload: exactly one transaction, parseable as a v0
116
+ * message. More than one is refused rather than summarised from the first —
117
+ * describing one of several would put a claim on screen that is true of only
118
+ * part of what gets signed.
119
+ */
120
+ export declare const decodeKaminoRawTransactions: (rawTransactions: string[]) => KaminoDecodedTransaction | undefined;
121
+ //# sourceMappingURL=decode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decode.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/solana/kamino/tx/decode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAIjE,OAAO,EAAE,qBAAqB,EAAuB,MAAM,aAAa,CAAA;AAgBxE,OAAO,EAAE,iBAAiB,EAA2B,MAAM,YAAY,CAAA;AAGvE;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,SAAS,GAAG,UAAU,CAAA;IACjC,2FAA2F;IAC3F,UAAU,EAAE,qBAAqB,CAAA;IACjC;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAA;IACvB,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,qBAAqB,EAAE,OAAO,CAAA;IAC9B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,iBAAiB,CAAA;CAChC,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,6BAA6B,GAAI,SAAS,wBAAwB,KAAG,OACE,CAAA;AAEpF,sEAAsE;AACtE,eAAO,MAAM,2BAA2B,GAAI,SAAS,wBAAwB,KAAG,MACwB,CAAA;AAExG,6EAA6E;AAC7E,eAAO,MAAM,yBAAyB,GAAI,SAAS,wBAAwB,KAAG,MACiC,CAAA;AAE/G;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,GAAI,aAAa,oBAAoB,KAAG,OAK7E,CAAA;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,0BAA0B,GAAI,mBAAmB,MAAM,KAAG,OAStE,CAAA;AA8CD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,uBAAuB,GAAI,aAAa,oBAAoB,KAAG,wBAAwB,GAAG,SAiGtG,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,GAAI,iBAAiB,MAAM,EAAE,KAAG,wBAAwB,GAAG,SAIlG,CAAA"}
@@ -0,0 +1,458 @@
1
+ import { PublicKey } from '@solana/web3.js';
2
+ import { kaminoMaxBaseUnits, renderKaminoBaseUnits } from '../baseUnits.js';
3
+ import { kaminoConfig } from '../config.js';
4
+ import { kaminoVaultRegistry } from '../registry.js';
5
+ import { clampKaminoUnitPrice, kaminoComputeBudget, kaminoExpectedUnitLimit } from './computeBudget.js';
6
+ import { anchorU64Argument, anchorU128Argument, computeUnitLimitArgument, computeUnitPriceArgument, deriveKaminoFarmsUserState, hasNoAnchorArgument, kaminoAllowedProgram, kaminoFarmsStakeScale, kaminoInstructionAccounts, systemTransferLamports, } from './instructions.js';
7
+ import { expectedKaminoSequence, kaminoInstructionKind, matchKaminoSequence } from './sequence.js';
8
+ import { kaminoUserTokenAccounts } from './validate.js';
9
+ import { isUnsignedSingleSigner, parseKaminoWireTransaction } from './wire.js';
10
+ /**
11
+ * Whether a withdraw carries the `u64::MAX` sentinel, which the kVaults
12
+ * program reads as *withdraw everything* rather than as a share count. This
13
+ * app never produces one — the builder refuses to request it and the
14
+ * validator pins the instruction's `u64` — but neither of those runs on a
15
+ * co-signing device, which holds only the relayed bytes. Rendering 18.4
16
+ * quintillion shares would be literally true and would say nothing about
17
+ * what the transaction does.
18
+ */
19
+ export const withdrawsEntireKaminoPosition = (decoded) => decoded.operation === 'withdraw' && decoded.amountBaseUnits === kaminoMaxBaseUnits;
20
+ /** The scale `amountBaseUnits` is expressed at, from the registry. */
21
+ export const kaminoDecodedAmountDecimals = (decoded) => decoded.operation === 'deposit' ? decoded.descriptor.tokenDecimals : decoded.descriptor.sharesDecimals;
22
+ /** The amount as plain human units — no grouping, no exponent, no locale. */
23
+ export const kaminoDecodedAmountString = (decoded) => renderKaminoBaseUnits({ baseUnits: decoded.amountBaseUnits, decimals: kaminoDecodedAmountDecimals(decoded) });
24
+ /**
25
+ * Whether these bytes invoke the kVaults program at all. Separate from
26
+ * `decodeKaminoTransaction` on purpose: a transaction that invokes `kvault`
27
+ * but cannot be decoded must be surfaced as unreadable rather than as an
28
+ * ordinary Solana transaction. Program ids are always static keys, so this
29
+ * needs no lookup table.
30
+ */
31
+ export const invokesKaminoVaultProgram = (transaction) => {
32
+ const accounts = transaction.message.staticAccountKeys.map(key => key.toBase58());
33
+ return transaction.message.compiledInstructions.some(instruction => accounts[instruction.programIdIndex] === kaminoConfig.programId);
34
+ };
35
+ /**
36
+ * Whether bytes this app cannot parse nonetheless mention the kVaults
37
+ * program.
38
+ *
39
+ * The structured check above needs a v0 message, but a raw signing path signs
40
+ * wire bytes verbatim without caring what version they are — so a LEGACY
41
+ * transaction invoking kVaults would parse to nothing and, without this, be
42
+ * classified as an ordinary Solana payload and sail past the signing guards.
43
+ * A program id is a 32-byte account key in the message under either format,
44
+ * so scanning for those bytes answers the only question that matters here:
45
+ * is this something we must refuse to stay quiet about?
46
+ *
47
+ * Deliberately coarse, and coarse in the safe direction: a payload that
48
+ * happens to contain these 32 bytes without invoking the program would be
49
+ * refused; a payload that invokes the program cannot escape.
50
+ */
51
+ export const mentionsKaminoVaultProgram = (base64Transaction) => {
52
+ let bytes;
53
+ try {
54
+ bytes = Buffer.from(base64Transaction, 'base64');
55
+ }
56
+ catch {
57
+ return false;
58
+ }
59
+ const needle = new PublicKey(kaminoConfig.programId).toBytes();
60
+ return bytes.indexOf(Buffer.from(needle)) !== -1;
61
+ };
62
+ const staticAddress = (accounts, index) => index === undefined ? undefined : accounts[index];
63
+ /**
64
+ * The curated vault whose share account for `owner` is `account`. The share
65
+ * mint is pinned per vault in the registry and the ATA is a program-derived
66
+ * address, so this is a local computation over a three-element allow-list.
67
+ */
68
+ const descriptorForShareAccount = (account, owner) => kaminoVaultRegistry.find(descriptor => kaminoUserTokenAccounts({ owner, mint: descriptor.sharesMint }).has(account));
69
+ /**
70
+ * Whether a farms instruction acts on THIS signer's position in THIS vault's
71
+ * farm. The user state is a program address over the farm and the owner, so
72
+ * recomputing it locally binds the instruction to one farm and one user at
73
+ * once — offline, which the farm slot itself cannot be: the farm is a
74
+ * lookup-table entry in every captured transaction. The user state is a
75
+ * static key in every captured transaction, which is what makes this
76
+ * checkable here at all; one that is not static, or not the derived address,
77
+ * is a refusal. The farm slot is compared too whenever it happens to resolve
78
+ * statically.
79
+ */
80
+ const actsOnSignersFarmPosition = ({ accounts, userStateIndex, farmIndex, signer, descriptor, }) => {
81
+ const farm = descriptor.farm;
82
+ if (!farm)
83
+ return false;
84
+ const expected = deriveKaminoFarmsUserState({ farm, owner: signer });
85
+ if (!expected)
86
+ return false;
87
+ if (staticAddress(accounts, userStateIndex) !== expected)
88
+ return false;
89
+ return namesThisVaultsFarm({ accounts, index: farmIndex, descriptor });
90
+ };
91
+ /**
92
+ * Decodes the single kvault deposit or withdraw these bytes perform, or
93
+ * `undefined` when they do not perform exactly one that this app recognises.
94
+ *
95
+ * `undefined` is a refusal to describe, never a "probably fine". This runs
96
+ * offline — the verify and join screens render before any network call is
97
+ * guaranteed to have happened — so lookup tables cannot be resolved, and the
98
+ * vault is identified the other way round: by deriving each curated vault's
99
+ * share account for this signer and matching it against the instruction's
100
+ * share slot, which is a static key in every observed transaction. That
101
+ * derivation is local, which makes it a stronger identification than reading
102
+ * an address out of the bytes would have been.
103
+ *
104
+ * What this establishes: every instruction fits the shape the named
105
+ * operation produces, the amount is the `u64` the kvault instruction
106
+ * carries, the authority is the transaction's own signer, and the share
107
+ * account that instruction spends or credits is the one this signer owns for
108
+ * the named vault's share mint. Every instruction argument that is a spend
109
+ * and is readable without a lookup table is also checked. What it does not
110
+ * establish is the account identities that live in the lookup table — the
111
+ * initiating device closes that gap by resolving the tables and running the
112
+ * full validator before the payload exists.
113
+ *
114
+ * One residue is specific to the farm-staked withdraw: how many shares a
115
+ * withdraw legitimately releases from the farm is `requested −
116
+ * alreadyUnstaked`, and the second term is a balance that is not in the
117
+ * bytes. So offline the release is bounded by the withdraw itself and no
118
+ * further — while the release provably acts on this signer's own position,
119
+ * in this vault's own farm, into the signer's own share account, with the
120
+ * stranding and misdirection shapes refused by the template and the
121
+ * derivations.
122
+ */
123
+ export const decodeKaminoTransaction = (transaction) => {
124
+ const accounts = transaction.message.staticAccountKeys.map(key => key.toBase58());
125
+ const signer = accounts[0];
126
+ if (!signer)
127
+ return undefined;
128
+ // The shape this app is willing to SIGN, not merely one it can read: a
129
+ // single required signature, still an empty placeholder, paid for by slot
130
+ // 0. A relayed transaction never passed through the initiator's checks, and
131
+ // the raw signing path splices a signature into slot 0 without inspecting
132
+ // how many the message requires — so a payload carrying a second required
133
+ // signer would otherwise be summarised as an ordinary deposit.
134
+ if (!isUnsignedSingleSigner(transaction, signer))
135
+ return undefined;
136
+ const instructions = transaction.message.compiledInstructions;
137
+ const programs = instructions.map(instruction => kaminoAllowedProgram(accounts[instruction.programIdIndex] ?? ''));
138
+ const kinds = instructions.map((instruction, position) => kaminoInstructionKind(programs[position], instruction.data));
139
+ // Exactly one kvault instruction. Two would mean two amounts and two
140
+ // vaults, and picking either to display would be a guess.
141
+ const vaultPositions = kinds.flatMap((kind, position) => kind === 'kvaultDeposit' || kind === 'kvaultWithdraw' ? [position] : []);
142
+ if (vaultPositions.length !== 1)
143
+ return undefined;
144
+ const position = vaultPositions[0];
145
+ const operation = kinds[position] === 'kvaultDeposit' ? 'deposit' : 'withdraw';
146
+ const instruction = instructions[position];
147
+ const amount = anchorU64Argument(instruction.data);
148
+ if (amount === undefined)
149
+ return undefined;
150
+ const layout = operation === 'deposit' ? kaminoInstructionAccounts.kvaultDeposit : kaminoInstructionAccounts.kvaultWithdraw;
151
+ const indexes = instruction.accountKeyIndexes;
152
+ if (indexes.length < layout.minimumCount)
153
+ return undefined;
154
+ // The authority slot must be this transaction's own signer. Without it the
155
+ // amount and the vault would describe an instruction that some other
156
+ // account authorises, which is not what the user is being asked to approve.
157
+ if (staticAddress(accounts, indexes[layout.user]) !== signer)
158
+ return undefined;
159
+ const shareAccount = staticAddress(accounts, indexes[layout.userShareAccount]);
160
+ if (!shareAccount)
161
+ return undefined;
162
+ const descriptor = descriptorForShareAccount(shareAccount, signer);
163
+ if (!descriptor)
164
+ return undefined;
165
+ // When the vault slot happens to be a static key, it must be the vault the
166
+ // share account identified. It is a lookup-table entry in every captured
167
+ // transaction, but an attacker who moved it into the static keys must not
168
+ // thereby escape the comparison.
169
+ const namedVault = staticAddress(accounts, indexes[layout.vault]);
170
+ if (namedVault !== undefined && namedVault !== descriptor.address)
171
+ return undefined;
172
+ // EVERY instruction must fit the shape this operation produces — not just
173
+ // the one that was recognised. This is the check that stops a transfer
174
+ // riding alongside a plausible deposit: the decode either accounts for the
175
+ // whole transaction or it describes none of it. The fee/memo expectations
176
+ // are read from the bytes rather than assumed, because this device did not
177
+ // build the transaction; the memo's CONTENT is not read leniently — the
178
+ // kind matcher takes the tag whole, so any other memo is already
179
+ // unrecognisable here and the template refuses it.
180
+ const steps = expectedKaminoSequence({
181
+ operation,
182
+ isWrappedSolVault: descriptor.tokenMint === kaminoConfig.wrappedSolMint,
183
+ hasFarm: descriptor.farm !== undefined,
184
+ hasPriorityFee: kinds.includes('computeUnitLimit') || kinds.includes('computeUnitPrice'),
185
+ hasAttributionMemo: kinds.includes('attributionMemo'),
186
+ // Which of the two withdraw shapes this is depends on how the signer's
187
+ // position was split when the request was built, and this device holds no
188
+ // position at all. So both shapes are accepted and the unstake is bounded
189
+ // by its ARGUMENT instead — see below.
190
+ farmUnstake: 'unknown',
191
+ });
192
+ const outcome = matchKaminoSequence(kinds, steps);
193
+ if ('mismatch' in outcome)
194
+ return undefined;
195
+ const priorityFee = readArguments({
196
+ matched: outcome.matched,
197
+ transaction,
198
+ accounts,
199
+ signer,
200
+ operation,
201
+ amount,
202
+ descriptor,
203
+ shareAccount,
204
+ });
205
+ if (!priorityFee)
206
+ return undefined;
207
+ return {
208
+ operation,
209
+ descriptor,
210
+ amountBaseUnits: amount,
211
+ signer,
212
+ strandsWrappedSolRent: operation === 'deposit' && descriptor.tokenMint === kaminoConfig.wrappedSolMint,
213
+ priorityFee: priorityFee.fee,
214
+ };
215
+ };
216
+ /**
217
+ * Convenience over a raw payload: exactly one transaction, parseable as a v0
218
+ * message. More than one is refused rather than summarised from the first —
219
+ * describing one of several would put a claim on screen that is true of only
220
+ * part of what gets signed.
221
+ */
222
+ export const decodeKaminoRawTransactions = (rawTransactions) => {
223
+ if (rawTransactions.length !== 1)
224
+ return undefined;
225
+ const transaction = parseKaminoWireTransaction(rawTransactions[0]);
226
+ return transaction ? decodeKaminoTransaction(transaction) : undefined;
227
+ };
228
+ /**
229
+ * Checks every instruction contract that can be judged offline, and reads
230
+ * out the priority fee the presentation cross-checks. Three kinds of check,
231
+ * all of which the online validator also makes — the point is that a
232
+ * co-signing device should refuse what the initiating device would have
233
+ * refused, minus only what genuinely needs the network: amounts that are
234
+ * spends, arguments that encode behaviour (`farms::stake` must carry
235
+ * `u64::MAX`), and account cardinality.
236
+ */
237
+ const readArguments = (input) => {
238
+ const { matched, transaction, ...shared } = input;
239
+ const fee = {};
240
+ for (let position = 0; position < matched.length; position++) {
241
+ const { data, accountKeyIndexes } = transaction.message.compiledInstructions[position];
242
+ const accepted = argumentChecks[matched[position]]({ ...shared, data, indexes: accountKeyIndexes }, fee);
243
+ if (!accepted)
244
+ return undefined;
245
+ }
246
+ // Both halves or neither. The template already enforces that, but the pair
247
+ // is what the fee is, so it is assembled rather than assumed.
248
+ const { unitLimit, unitPriceMicroLamports } = fee;
249
+ if (unitLimit !== undefined && unitPriceMicroLamports !== undefined) {
250
+ return { fee: { unitLimit, unitPriceMicroLamports } };
251
+ }
252
+ if (unitLimit === undefined && unitPriceMicroLamports === undefined)
253
+ return {};
254
+ return undefined;
255
+ };
256
+ const accountLayout = kaminoInstructionAccounts;
257
+ /**
258
+ * Bounded on BOTH sides, because the producer clamps into exactly this range:
259
+ * above the ceiling is SOL spent for nothing, below the floor is a
260
+ * transaction that will not land before its blockhash expires — and either
261
+ * way a price this app never chooses.
262
+ */
263
+ const readComputeUnitPrice = ({ data, indexes }, fee) => {
264
+ const value = computeUnitPriceArgument(data);
265
+ if (indexes.length > 0 ||
266
+ value === undefined ||
267
+ value < kaminoComputeBudget.fallbackUnitPriceMicroLamports ||
268
+ value > kaminoComputeBudget.maxUnitPriceMicroLamports ||
269
+ value !== clampKaminoUnitPrice(value)) {
270
+ return false;
271
+ }
272
+ fee.unitPriceMicroLamports = value;
273
+ return true;
274
+ };
275
+ const readComputeUnitLimit = ({ data, indexes, operation, descriptor }, fee) => {
276
+ const value = computeUnitLimitArgument(data);
277
+ if (indexes.length > 0 || value === undefined || value !== kaminoExpectedUnitLimit({ operation, descriptor })) {
278
+ return false;
279
+ }
280
+ fee.unitLimit = value;
281
+ return true;
282
+ };
283
+ const checkWrapSolTransfer = ({ data, indexes, accounts, signer, operation, amount, descriptor, }) => {
284
+ const lamports = systemTransferLamports(data);
285
+ if (operation !== 'deposit' ||
286
+ lamports === undefined ||
287
+ lamports !== amount ||
288
+ indexes.length < accountLayout.systemTransfer.count ||
289
+ staticAddress(accounts, indexes[accountLayout.systemTransfer.source]) !== signer) {
290
+ return false;
291
+ }
292
+ // The destination is the user's own wrapped-SOL account whenever it
293
+ // resolves statically — and it does in every captured transaction.
294
+ const destination = staticAddress(accounts, indexes[accountLayout.systemTransfer.destination]);
295
+ return (destination === undefined || kaminoUserTokenAccounts({ owner: signer, mint: descriptor.tokenMint }).has(destination));
296
+ };
297
+ /**
298
+ * Bound to the signer's own wrapped-SOL account whenever the slot resolves
299
+ * statically — the derivation needs no network, so leaving this looser than
300
+ * the initiating validator would be an unnecessary asymmetry between the two
301
+ * devices' refusals.
302
+ */
303
+ const checkSyncNative = ({ indexes, accounts, signer, descriptor }) => {
304
+ if (indexes.length === 0)
305
+ return false;
306
+ const syncedAccount = staticAddress(accounts, indexes[0]);
307
+ return (syncedAccount === undefined ||
308
+ kaminoUserTokenAccounts({ owner: signer, mint: descriptor.tokenMint }).has(syncedAccount));
309
+ };
310
+ /**
311
+ * The stake that makes a deposit's shares invisible in the wallet, bound to
312
+ * the signer, to this vault's farm and to the same share account the deposit
313
+ * credited. All three derive offline, so leaving them unchecked would let a
314
+ * stake naming another authority — or another vault's farm, which parks the
315
+ * position somewhere this app never reads — pass a co-signing device that the
316
+ * initiating validator refuses.
317
+ *
318
+ * Kamino stakes the whole share balance rather than the freshly minted
319
+ * amount, so the argument is the u64 sentinel; a different value is a
320
+ * behaviour change rather than a variation.
321
+ */
322
+ const checkFarmsStake = ({ data, indexes, accounts, signer, descriptor, shareAccount }) => {
323
+ const layout = accountLayout.farmsStake;
324
+ if (indexes.length < layout.minimumCount || anchorU64Argument(data) !== kaminoMaxBaseUnits)
325
+ return false;
326
+ if (staticAddress(accounts, indexes[layout.owner]) !== signer)
327
+ return false;
328
+ if (!namesThisVaultsFarm({ accounts, index: indexes[layout.farm], descriptor }))
329
+ return false;
330
+ const staked = staticAddress(accounts, indexes[layout.userShareAccount]);
331
+ return staked === undefined || staked === shareAccount;
332
+ };
333
+ /**
334
+ * Creating the farm user state costs the payer rent and decides whose
335
+ * position the later stake lands in, so the authority and the farm are bound
336
+ * the same way as the stake's.
337
+ */
338
+ const checkFarmsInitializeUser = ({ indexes, accounts, signer, descriptor }) => {
339
+ const layout = accountLayout.farmsInitializeUser;
340
+ return (indexes.length >= layout.minimumCount &&
341
+ staticAddress(accounts, indexes[layout.authority]) === signer &&
342
+ namesThisVaultsFarm({ accounts, index: indexes[layout.farm], descriptor }));
343
+ };
344
+ /**
345
+ * Whether a farm slot names this vault's farm. The farm is a lookup-table
346
+ * entry in every captured transaction and cannot be resolved offline, so an
347
+ * unresolvable slot is accepted — the initiating validator resolves the
348
+ * tables and pins it. One that DOES resolve statically must match, so moving
349
+ * the farm into the static keys is not a way past the check.
350
+ */
351
+ const namesThisVaultsFarm = ({ accounts, index, descriptor, }) => {
352
+ if (!descriptor.farm)
353
+ return false;
354
+ const named = staticAddress(accounts, index);
355
+ return named === undefined || named === descriptor.farm;
356
+ };
357
+ /**
358
+ * The u128 WAD-scaled release amount. The exact figure is `requested −
359
+ * unstaked`, and the unstaked half is a balance this device cannot read — so
360
+ * what is checked here is the BOUND: a withdraw cannot legitimately take more
361
+ * out of the farm than it burns. The authority is checked too, and that is
362
+ * the half that matters most: whatever amount is released, it is released
363
+ * from THIS signer's own farm position and nobody else's.
364
+ */
365
+ const checkFarmsUnstake = ({ data, indexes, accounts, signer, operation, amount, descriptor, }) => {
366
+ const scaled = anchorU128Argument(data);
367
+ if (operation !== 'withdraw' ||
368
+ indexes.length < accountLayout.farmsUnstake.minimumCount ||
369
+ staticAddress(accounts, indexes[accountLayout.farmsUnstake.owner]) !== signer ||
370
+ scaled === undefined ||
371
+ scaled <= 0n ||
372
+ scaled % kaminoFarmsStakeScale !== 0n ||
373
+ scaled > amount * kaminoFarmsStakeScale) {
374
+ return false;
375
+ }
376
+ return actsOnSignersFarmPosition({
377
+ accounts,
378
+ userStateIndex: indexes[accountLayout.farmsUnstake.userState],
379
+ farmIndex: indexes[accountLayout.farmsUnstake.farm],
380
+ signer,
381
+ descriptor,
382
+ });
383
+ };
384
+ /**
385
+ * Where the released shares LAND. It has to be the same share account the
386
+ * vault withdraw then burns from — the one already proven to be this signer's,
387
+ * for this vault's share mint — or the release and the withdraw are two
388
+ * unrelated movements presented as one.
389
+ */
390
+ const checkFarmsWithdrawUnstakedDeposits = ({ data, indexes, accounts, signer, operation, descriptor, shareAccount, }) => {
391
+ const layout = accountLayout.farmsWithdrawUnstakedDeposits;
392
+ if (operation !== 'withdraw' ||
393
+ indexes.length < layout.minimumCount ||
394
+ !hasNoAnchorArgument(data) ||
395
+ staticAddress(accounts, indexes[layout.owner]) !== signer ||
396
+ staticAddress(accounts, indexes[layout.userShareAccount]) !== shareAccount) {
397
+ return false;
398
+ }
399
+ return actsOnSignersFarmPosition({
400
+ accounts,
401
+ userStateIndex: indexes[layout.userState],
402
+ farmIndex: indexes[layout.farm],
403
+ signer,
404
+ descriptor,
405
+ });
406
+ };
407
+ /**
408
+ * Creating an account is not free — the PAYER funds its rent — and the step
409
+ * is repeatable, so an extra creation for a stranger's wallet would otherwise
410
+ * ride along unremarked and spend the signer's SOL. Both slots that decide
411
+ * who pays and who owns are static keys. The mint and the derived address
412
+ * need the lookup table; the initiating validator pins those.
413
+ */
414
+ const checkCreateTokenAccount = ({ indexes, accounts, signer }) => indexes.length >= accountLayout.associatedToken.count &&
415
+ staticAddress(accounts, indexes[accountLayout.associatedToken.payer]) === signer &&
416
+ staticAddress(accounts, indexes[accountLayout.associatedToken.wallet]) === signer;
417
+ /**
418
+ * Closing an account SENDS its rent somewhere. Where it lands, and who
419
+ * authorised the close, decide whether that is the signer reclaiming their
420
+ * own lamports or a third party collecting them.
421
+ */
422
+ const checkCloseTokenAccount = ({ indexes, accounts, signer }) => indexes.length >= accountLayout.closeAccount.count &&
423
+ staticAddress(accounts, indexes[accountLayout.closeAccount.destination]) === signer &&
424
+ staticAddress(accounts, indexes[accountLayout.closeAccount.authority]) === signer;
425
+ /**
426
+ * The tag itself was matched whole by the sequence. What is left to check is
427
+ * that it attests to nobody: a memo carrying account indexes is the Memo
428
+ * program asserting those accounts signed.
429
+ */
430
+ const checkAttributionMemo = ({ indexes }) => indexes.length === 0;
431
+ /**
432
+ * Every instruction contract that can be judged offline, one entry per
433
+ * template step. Three kinds of check, all of which the online validator also
434
+ * makes — the point is that a co-signing device should refuse what the
435
+ * initiating device would have refused, minus only what genuinely needs the
436
+ * network: amounts that are spends, arguments that encode behaviour
437
+ * (`farms::stake` must carry `u64::MAX`), and account cardinality.
438
+ *
439
+ * A record rather than a switch so each check stands alone and the set stays
440
+ * exhaustive: a template step added without a check is a type error.
441
+ */
442
+ const argumentChecks = {
443
+ computeUnitPrice: readComputeUnitPrice,
444
+ computeUnitLimit: readComputeUnitLimit,
445
+ wrapSolTransfer: checkWrapSolTransfer,
446
+ syncNative: checkSyncNative,
447
+ farmsStake: checkFarmsStake,
448
+ farmsInitializeUser: checkFarmsInitializeUser,
449
+ farmsUnstake: checkFarmsUnstake,
450
+ farmsWithdrawUnstakedDeposits: checkFarmsWithdrawUnstakedDeposits,
451
+ createTokenAccount: checkCreateTokenAccount,
452
+ closeTokenAccount: checkCloseTokenAccount,
453
+ attributionMemo: checkAttributionMemo,
454
+ // Already read by the caller: the amount, the authority and the share account.
455
+ kvaultDeposit: () => true,
456
+ kvaultWithdraw: () => true,
457
+ };
458
+ //# sourceMappingURL=decode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decode.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/solana/kamino/tx/decode.ts"],"names":[],"mappings":"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"}