@vultisig/core-chain 2.37.0 → 2.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/dist/chains/cosmos/gas.d.ts +9 -0
- package/dist/chains/cosmos/gas.d.ts.map +1 -1
- package/dist/chains/cosmos/gas.js +9 -0
- package/dist/chains/cosmos/gas.js.map +1 -1
- package/dist/chains/cosmos/terraClassicTax.d.ts +15 -0
- package/dist/chains/cosmos/terraClassicTax.d.ts.map +1 -1
- package/dist/chains/cosmos/terraClassicTax.js +14 -0
- package/dist/chains/cosmos/terraClassicTax.js.map +1 -1
- package/dist/chains/solana/kamino/KaminoServiceError.d.ts +63 -0
- package/dist/chains/solana/kamino/KaminoServiceError.d.ts.map +1 -0
- package/dist/chains/solana/kamino/KaminoServiceError.js +29 -0
- package/dist/chains/solana/kamino/KaminoServiceError.js.map +1 -0
- package/dist/chains/solana/kamino/amount.d.ts +141 -0
- package/dist/chains/solana/kamino/amount.d.ts.map +1 -0
- package/dist/chains/solana/kamino/amount.js +156 -0
- package/dist/chains/solana/kamino/amount.js.map +1 -0
- package/dist/chains/solana/kamino/api.d.ts +20 -0
- package/dist/chains/solana/kamino/api.d.ts.map +1 -0
- package/dist/chains/solana/kamino/api.js +59 -0
- package/dist/chains/solana/kamino/api.js.map +1 -0
- package/dist/chains/solana/kamino/baseUnits.d.ts +23 -0
- package/dist/chains/solana/kamino/baseUnits.d.ts.map +1 -0
- package/dist/chains/solana/kamino/baseUnits.js +30 -0
- package/dist/chains/solana/kamino/baseUnits.js.map +1 -0
- package/dist/chains/solana/kamino/config.d.ts +27 -0
- package/dist/chains/solana/kamino/config.d.ts.map +1 -0
- package/dist/chains/solana/kamino/config.js +27 -0
- package/dist/chains/solana/kamino/config.js.map +1 -0
- package/dist/chains/solana/kamino/decimal.d.ts +24 -0
- package/dist/chains/solana/kamino/decimal.d.ts.map +1 -0
- package/dist/chains/solana/kamino/decimal.js +52 -0
- package/dist/chains/solana/kamino/decimal.js.map +1 -0
- package/dist/chains/solana/kamino/models.d.ts +148 -0
- package/dist/chains/solana/kamino/models.d.ts.map +1 -0
- package/dist/chains/solana/kamino/models.js +2 -0
- package/dist/chains/solana/kamino/models.js.map +1 -0
- package/dist/chains/solana/kamino/position.d.ts +79 -0
- package/dist/chains/solana/kamino/position.d.ts.map +1 -0
- package/dist/chains/solana/kamino/position.js +52 -0
- package/dist/chains/solana/kamino/position.js.map +1 -0
- package/dist/chains/solana/kamino/rate.d.ts +57 -0
- package/dist/chains/solana/kamino/rate.d.ts.map +1 -0
- package/dist/chains/solana/kamino/rate.js +88 -0
- package/dist/chains/solana/kamino/rate.js.map +1 -0
- package/dist/chains/solana/kamino/registry.d.ts +70 -0
- package/dist/chains/solana/kamino/registry.d.ts.map +1 -0
- package/dist/chains/solana/kamino/registry.js +67 -0
- package/dist/chains/solana/kamino/registry.js.map +1 -0
- package/dist/chains/solana/kamino/tx/actions.d.ts +22 -0
- package/dist/chains/solana/kamino/tx/actions.d.ts.map +1 -0
- package/dist/chains/solana/kamino/tx/actions.js +85 -0
- package/dist/chains/solana/kamino/tx/actions.js.map +1 -0
- package/dist/chains/solana/kamino/tx/computeBudget.d.ts +66 -0
- package/dist/chains/solana/kamino/tx/computeBudget.d.ts.map +1 -0
- package/dist/chains/solana/kamino/tx/computeBudget.js +73 -0
- package/dist/chains/solana/kamino/tx/computeBudget.js.map +1 -0
- package/dist/chains/solana/kamino/tx/decode.d.ts +121 -0
- package/dist/chains/solana/kamino/tx/decode.d.ts.map +1 -0
- package/dist/chains/solana/kamino/tx/decode.js +458 -0
- package/dist/chains/solana/kamino/tx/decode.js.map +1 -0
- package/dist/chains/solana/kamino/tx/instructions.d.ts +260 -0
- package/dist/chains/solana/kamino/tx/instructions.d.ts.map +1 -0
- package/dist/chains/solana/kamino/tx/instructions.js +256 -0
- package/dist/chains/solana/kamino/tx/instructions.js.map +1 -0
- package/dist/chains/solana/kamino/tx/sequence.d.ts +123 -0
- package/dist/chains/solana/kamino/tx/sequence.d.ts.map +1 -0
- package/dist/chains/solana/kamino/tx/sequence.js +235 -0
- package/dist/chains/solana/kamino/tx/sequence.js.map +1 -0
- package/dist/chains/solana/kamino/tx/validate.d.ts +138 -0
- package/dist/chains/solana/kamino/tx/validate.d.ts.map +1 -0
- package/dist/chains/solana/kamino/tx/validate.js +542 -0
- package/dist/chains/solana/kamino/tx/validate.js.map +1 -0
- package/dist/chains/solana/kamino/tx/wire.d.ts +107 -0
- package/dist/chains/solana/kamino/tx/wire.d.ts.map +1 -0
- package/dist/chains/solana/kamino/tx/wire.js +274 -0
- package/dist/chains/solana/kamino/tx/wire.js.map +1 -0
- package/dist/chains/solana/kamino/vaultInfo.d.ts +17 -0
- package/dist/chains/solana/kamino/vaultInfo.d.ts.map +1 -0
- package/dist/chains/solana/kamino/vaultInfo.js +150 -0
- package/dist/chains/solana/kamino/vaultInfo.js.map +1 -0
- package/dist/swap/utils/getSwapArrivalStatus/index.d.ts +79 -0
- package/dist/swap/utils/getSwapArrivalStatus/index.d.ts.map +1 -0
- package/dist/swap/utils/getSwapArrivalStatus/index.js +374 -0
- package/dist/swap/utils/getSwapArrivalStatus/index.js.map +1 -0
- package/package.json +96 -1
|
@@ -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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"}
|