@temporalabs/treasury 0.1.1 → 0.1.3
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/NOTICE +4 -2
- package/README.md +100 -44
- package/THIRD_PARTY_NOTICES.connect-page.md +7836 -0
- package/THIRD_PARTY_NOTICES.md +543 -162
- package/dist/cli.d.ts +6 -0
- package/dist/cli.js +243 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +366 -239
- package/dist/client.js +202 -25
- package/dist/client.js.map +1 -1
- package/dist/config/earn.d.ts +48 -12
- package/dist/config/earn.js +48 -12
- package/dist/config/earn.js.map +1 -1
- package/dist/connect/ack.d.ts +76 -0
- package/dist/connect/ack.js +147 -0
- package/dist/connect/ack.js.map +1 -0
- package/dist/connect/commands.d.ts +81 -0
- package/dist/connect/commands.js +555 -0
- package/dist/connect/commands.js.map +1 -0
- package/dist/connect/config.d.ts +24 -0
- package/dist/connect/config.js +35 -0
- package/dist/connect/config.js.map +1 -0
- package/dist/connect/gate-solana.d.ts +8 -0
- package/dist/connect/gate-solana.js +147 -0
- package/dist/connect/gate-solana.js.map +1 -0
- package/dist/connect/gate.d.ts +37 -0
- package/dist/connect/gate.js +115 -0
- package/dist/connect/gate.js.map +1 -0
- package/dist/connect/http.d.ts +60 -0
- package/dist/connect/http.js +235 -0
- package/dist/connect/http.js.map +1 -0
- package/dist/connect/open.d.ts +2 -0
- package/dist/connect/open.js +35 -0
- package/dist/connect/open.js.map +1 -0
- package/dist/connect/page.d.ts +5 -0
- package/dist/connect/page.js +69 -0
- package/dist/connect/page.js.map +1 -0
- package/dist/connect/session.d.ts +39 -0
- package/dist/connect/session.js +198 -0
- package/dist/connect/session.js.map +1 -0
- package/dist/connect/solana.d.ts +73 -0
- package/dist/connect/solana.js +267 -0
- package/dist/connect/solana.js.map +1 -0
- package/dist/connect/verify.d.ts +37 -0
- package/dist/connect/verify.js +89 -0
- package/dist/connect/verify.js.map +1 -0
- package/dist/connect-page.js +5143 -0
- package/dist/disclosures.d.ts +22 -6
- package/dist/disclosures.js +34 -8
- package/dist/disclosures.js.map +1 -1
- package/dist/earn/commands.d.ts +46 -0
- package/dist/earn/commands.js +556 -0
- package/dist/earn/commands.js.map +1 -0
- package/dist/earn/solana.d.ts +278 -0
- package/dist/earn/solana.js +302 -0
- package/dist/earn/solana.js.map +1 -0
- package/dist/guide.d.ts +15 -0
- package/dist/guide.js +50 -0
- package/dist/guide.js.map +1 -0
- package/dist/links.d.ts +2 -0
- package/dist/links.js +40 -14
- package/dist/links.js.map +1 -1
- package/dist/position.d.ts +9 -6
- package/dist/position.js +39 -19
- package/dist/position.js.map +1 -1
- package/dist/preflight.d.ts +9 -0
- package/dist/preflight.js +14 -3
- package/dist/preflight.js.map +1 -1
- package/dist/quote.js +24 -7
- package/dist/quote.js.map +1 -1
- package/dist/redact.d.ts +3 -3
- package/dist/redact.js +3 -3
- package/dist/redact.js.map +1 -1
- package/dist/registry-schema.d.ts +82 -5
- package/dist/registry-schema.js +105 -15
- package/dist/registry-schema.js.map +1 -1
- package/dist/registry.d.ts +50 -7
- package/dist/registry.js +122 -21
- package/dist/registry.js.map +1 -1
- package/dist/solana/constants.d.ts +49 -0
- package/dist/solana/constants.js +50 -0
- package/dist/solana/constants.js.map +1 -0
- package/dist/solana/kvault.d.ts +99 -0
- package/dist/solana/kvault.js +192 -0
- package/dist/solana/kvault.js.map +1 -0
- package/dist/solana/layout.d.ts +143 -0
- package/dist/solana/layout.js +209 -0
- package/dist/solana/layout.js.map +1 -0
- package/dist/solana/rpc.d.ts +24 -0
- package/dist/solana/rpc.js +66 -0
- package/dist/solana/rpc.js.map +1 -0
- package/dist/solana/vault.d.ts +153 -0
- package/dist/solana/vault.js +324 -0
- package/dist/solana/vault.js.map +1 -0
- package/dist/{mcp-server.mjs → treasury.mjs} +41101 -49486
- package/dist/version.js +5 -10
- package/dist/version.js.map +1 -1
- package/llms.txt +621 -0
- package/package.json +12 -9
- package/registry/vaults.json +218 -4
- package/dist/mcp/server.d.ts +0 -8
- package/dist/mcp/server.js +0 -368
- package/dist/mcp/server.js.map +0 -1
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import type { SolanaVaultEntry } from "../registry-schema.js";
|
|
2
|
+
/** Which chain a Solana response is about: the name a caller passes back, and the cluster a wallet must be on. */
|
|
3
|
+
export declare const onSolana: {
|
|
4
|
+
readonly chain: "solana";
|
|
5
|
+
readonly chainId: null;
|
|
6
|
+
readonly cluster: "mainnet-beta";
|
|
7
|
+
readonly genesisHash: "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d";
|
|
8
|
+
};
|
|
9
|
+
/** The explorer page for a Solana account or transaction. */
|
|
10
|
+
export declare const solscan: (kind: "account" | "tx", id: string) => string;
|
|
11
|
+
/** A Solana address argument, checked here: the CLI's schema accepts either family's address form. */
|
|
12
|
+
export declare function solanaAccount(v: string, what: string): string;
|
|
13
|
+
/** The row `earn vaults` lists for a Solana vault. */
|
|
14
|
+
export declare function solanaVaultRow(v: SolanaVaultEntry): {
|
|
15
|
+
symbol: string;
|
|
16
|
+
name: string;
|
|
17
|
+
warning: string;
|
|
18
|
+
links: {
|
|
19
|
+
explorer: string;
|
|
20
|
+
};
|
|
21
|
+
backend: "morpho" | "tempora";
|
|
22
|
+
isDefault: boolean;
|
|
23
|
+
chain: "solana";
|
|
24
|
+
chainId: null;
|
|
25
|
+
address: string & import("@solana/nominal-types").NominalType<"brand", "Address"> & import("@solana/nominal-types").NominalType<"stringEncoding", "base58">;
|
|
26
|
+
chassis: "kamino-vault";
|
|
27
|
+
asset: {
|
|
28
|
+
address: string & import("@solana/nominal-types").NominalType<"brand", "Address"> & import("@solana/nominal-types").NominalType<"stringEncoding", "base58">;
|
|
29
|
+
symbol: string;
|
|
30
|
+
decimals: number;
|
|
31
|
+
};
|
|
32
|
+
sharesMint: string & import("@solana/nominal-types").NominalType<"brand", "Address"> & import("@solana/nominal-types").NominalType<"stringEncoding", "base58">;
|
|
33
|
+
shareDecimals: number;
|
|
34
|
+
depositOpen: {
|
|
35
|
+
open: boolean;
|
|
36
|
+
method: "simulated-deposit-from-stranger";
|
|
37
|
+
measuredAtSlot: number;
|
|
38
|
+
measuredAtIso: string;
|
|
39
|
+
reason?: "REVERTED_OTHER" | "PERMISSIONED" | undefined;
|
|
40
|
+
detail?: string | undefined;
|
|
41
|
+
};
|
|
42
|
+
notes: string[];
|
|
43
|
+
};
|
|
44
|
+
/** `earn status` with no account: is the Solana endpoint up, and is it mainnet. Never throws. */
|
|
45
|
+
export declare function solanaHealth(vault: SolanaVaultEntry, partial: Record<string, unknown>): Promise<{
|
|
46
|
+
rpc: string;
|
|
47
|
+
latestSlot: null;
|
|
48
|
+
reason: string;
|
|
49
|
+
vault: string;
|
|
50
|
+
rpcSource: string;
|
|
51
|
+
rpcConfigured: boolean;
|
|
52
|
+
chain: "solana";
|
|
53
|
+
chainId: null;
|
|
54
|
+
cluster: "mainnet-beta";
|
|
55
|
+
genesisHash: "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d";
|
|
56
|
+
server: string;
|
|
57
|
+
version: string;
|
|
58
|
+
registry: {
|
|
59
|
+
schemaVersion: 1;
|
|
60
|
+
vaults: number;
|
|
61
|
+
reconciledAtIso: string;
|
|
62
|
+
};
|
|
63
|
+
mode: string;
|
|
64
|
+
} | {
|
|
65
|
+
rpc: string;
|
|
66
|
+
chainVerified: boolean;
|
|
67
|
+
latestSlot: string;
|
|
68
|
+
vault: string;
|
|
69
|
+
rpcSource: string;
|
|
70
|
+
rpcConfigured: boolean;
|
|
71
|
+
chain: "solana";
|
|
72
|
+
chainId: null;
|
|
73
|
+
cluster: "mainnet-beta";
|
|
74
|
+
genesisHash: "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d";
|
|
75
|
+
server: string;
|
|
76
|
+
version: string;
|
|
77
|
+
registry: {
|
|
78
|
+
schemaVersion: 1;
|
|
79
|
+
vaults: number;
|
|
80
|
+
reconciledAtIso: string;
|
|
81
|
+
};
|
|
82
|
+
mode: string;
|
|
83
|
+
}>;
|
|
84
|
+
/** `earn status --account`: the deposit pre-flight. */
|
|
85
|
+
export declare function solanaPreflight(vault: SolanaVaultEntry, account: string, amountHuman?: string): Promise<{
|
|
86
|
+
vault: string;
|
|
87
|
+
depositor: string;
|
|
88
|
+
status: import("../solana/vault.js").SolanaPreflightStatus;
|
|
89
|
+
canDeposit: boolean;
|
|
90
|
+
findings: string[];
|
|
91
|
+
} | {
|
|
92
|
+
status: import("../solana/vault.js").SolanaPreflightStatus;
|
|
93
|
+
canDeposit: boolean;
|
|
94
|
+
findings: string[];
|
|
95
|
+
vault: string;
|
|
96
|
+
depositor: string;
|
|
97
|
+
balances: {
|
|
98
|
+
asset: string;
|
|
99
|
+
shares: string;
|
|
100
|
+
};
|
|
101
|
+
quotes: {
|
|
102
|
+
sharePriceInAssets: string;
|
|
103
|
+
};
|
|
104
|
+
measuredAtSlot: number;
|
|
105
|
+
} | {
|
|
106
|
+
status: import("../solana/vault.js").SolanaPreflightStatus;
|
|
107
|
+
canDeposit: boolean;
|
|
108
|
+
findings: string[];
|
|
109
|
+
vault: string;
|
|
110
|
+
depositor: string;
|
|
111
|
+
balances: {
|
|
112
|
+
asset: string;
|
|
113
|
+
shares: string;
|
|
114
|
+
};
|
|
115
|
+
quotes: {
|
|
116
|
+
sharePriceInAssets: string;
|
|
117
|
+
};
|
|
118
|
+
measuredAtSlot: number;
|
|
119
|
+
}>;
|
|
120
|
+
/** `earn quote --direction deposit`. */
|
|
121
|
+
export declare function solanaQuoteDeposit(vault: SolanaVaultEntry, account: string, amountHuman: string): Promise<{
|
|
122
|
+
vault: string;
|
|
123
|
+
depositor: string;
|
|
124
|
+
amountUsdc: string;
|
|
125
|
+
expectedShares: string;
|
|
126
|
+
sharePriceInAssets: string | undefined;
|
|
127
|
+
preflight: {
|
|
128
|
+
vault: string;
|
|
129
|
+
depositor: string;
|
|
130
|
+
status: import("../solana/vault.js").SolanaPreflightStatus;
|
|
131
|
+
canDeposit: boolean;
|
|
132
|
+
findings: string[];
|
|
133
|
+
} | {
|
|
134
|
+
status: import("../solana/vault.js").SolanaPreflightStatus;
|
|
135
|
+
canDeposit: boolean;
|
|
136
|
+
findings: string[];
|
|
137
|
+
vault: string;
|
|
138
|
+
depositor: string;
|
|
139
|
+
balances: {
|
|
140
|
+
asset: string;
|
|
141
|
+
shares: string;
|
|
142
|
+
};
|
|
143
|
+
quotes: {
|
|
144
|
+
sharePriceInAssets: string;
|
|
145
|
+
};
|
|
146
|
+
measuredAtSlot: number;
|
|
147
|
+
} | {
|
|
148
|
+
status: import("../solana/vault.js").SolanaPreflightStatus;
|
|
149
|
+
canDeposit: boolean;
|
|
150
|
+
findings: string[];
|
|
151
|
+
vault: string;
|
|
152
|
+
depositor: string;
|
|
153
|
+
balances: {
|
|
154
|
+
asset: string;
|
|
155
|
+
shares: string;
|
|
156
|
+
};
|
|
157
|
+
quotes: {
|
|
158
|
+
sharePriceInAssets: string;
|
|
159
|
+
};
|
|
160
|
+
measuredAtSlot: number;
|
|
161
|
+
};
|
|
162
|
+
note: string;
|
|
163
|
+
}>;
|
|
164
|
+
/** `earn quote --direction withdraw`. */
|
|
165
|
+
export declare function solanaQuoteWithdraw(vault: SolanaVaultEntry, account: string, amountHuman: string): Promise<{
|
|
166
|
+
canWithdraw: boolean;
|
|
167
|
+
note: string;
|
|
168
|
+
vault: string;
|
|
169
|
+
owner: string;
|
|
170
|
+
amountUsdc: string;
|
|
171
|
+
sharesToBurn: string;
|
|
172
|
+
sharesHeld: string;
|
|
173
|
+
instantLiquidity: string;
|
|
174
|
+
sharePriceInAssets: string;
|
|
175
|
+
} | {
|
|
176
|
+
canWithdraw: boolean;
|
|
177
|
+
measuredAtSlot: number;
|
|
178
|
+
note: string;
|
|
179
|
+
vault: string;
|
|
180
|
+
owner: string;
|
|
181
|
+
amountUsdc: string;
|
|
182
|
+
sharesToBurn: string;
|
|
183
|
+
sharesHeld: string;
|
|
184
|
+
instantLiquidity: string;
|
|
185
|
+
sharePriceInAssets: string;
|
|
186
|
+
} | {
|
|
187
|
+
canWithdraw: boolean;
|
|
188
|
+
receives: string;
|
|
189
|
+
measuredAtSlot: number;
|
|
190
|
+
note: string;
|
|
191
|
+
vault: string;
|
|
192
|
+
owner: string;
|
|
193
|
+
amountUsdc: string;
|
|
194
|
+
sharesToBurn: string;
|
|
195
|
+
sharesHeld: string;
|
|
196
|
+
instantLiquidity: string;
|
|
197
|
+
sharePriceInAssets: string;
|
|
198
|
+
}>;
|
|
199
|
+
/** `earn balance`: shares, value, and what a full exit would pay now. No event scan on Solana. */
|
|
200
|
+
export declare function solanaBalance(vault: SolanaVaultEntry, account: string): Promise<{
|
|
201
|
+
vault: string;
|
|
202
|
+
account: string;
|
|
203
|
+
sharesExact: string;
|
|
204
|
+
shares: string;
|
|
205
|
+
usdcValue: string;
|
|
206
|
+
sharePriceInAssets: string;
|
|
207
|
+
exit: {
|
|
208
|
+
instantLiquidity: string;
|
|
209
|
+
};
|
|
210
|
+
entryBasisUsdc: string;
|
|
211
|
+
accruedYieldUsdc: string;
|
|
212
|
+
scan: {
|
|
213
|
+
complete: boolean;
|
|
214
|
+
wholeHistory: boolean;
|
|
215
|
+
note: string;
|
|
216
|
+
};
|
|
217
|
+
measuredAtSlot: number;
|
|
218
|
+
}>;
|
|
219
|
+
/**
|
|
220
|
+
* What a Solana signer must do for a prepared transaction to land exactly once. Stated with every build,
|
|
221
|
+
* because nothing here signs or sends.
|
|
222
|
+
*/
|
|
223
|
+
export declare const SOLANA_SIGNER_RULES: readonly ["Sign and send on Solana mainnet-beta only: check the wallet's network before signing.", "Send before block height `transaction.expiresAfterBlockHeight` (about a minute after it was prepared). If that height has passed, do not sign: prepare the transaction again.", "Before signing, check the fee payer and signer is the account the operator named, and the vault the transaction calls (`vaultAddress`) is the vault named. Do not sign a transaction whose account you did not confirm.", "Confirm by the signature's status. If a send fails with no status, read the account's share balance before preparing again: a transaction that did land would be repeated by a new one."];
|
|
224
|
+
/** `earn prepare_deposit` on Solana. Simulated first; a deposit the program would refuse is not returned. */
|
|
225
|
+
export declare function solanaPrepareDeposit(vault: SolanaVaultEntry, account: string, amountHuman: string, receiver: string): Promise<{
|
|
226
|
+
next_step: string;
|
|
227
|
+
signer_rules: readonly ["Sign and send on Solana mainnet-beta only: check the wallet's network before signing.", "Send before block height `transaction.expiresAfterBlockHeight` (about a minute after it was prepared). If that height has passed, do not sign: prepare the transaction again.", "Before signing, check the fee payer and signer is the account the operator named, and the vault the transaction calls (`vaultAddress`) is the vault named. Do not sign a transaction whose account you did not confirm.", "Confirm by the signature's status. If a send fails with no status, read the account's share balance before preparing again: a transaction that did land would be repeated by a new one."];
|
|
228
|
+
vault: string;
|
|
229
|
+
vaultAddress: string & import("@solana/nominal-types").NominalType<"brand", "Address"> & import("@solana/nominal-types").NominalType<"stringEncoding", "base58">;
|
|
230
|
+
account: string;
|
|
231
|
+
kind: "deposit" | "withdraw";
|
|
232
|
+
expected: string;
|
|
233
|
+
simulated: string;
|
|
234
|
+
transaction: {
|
|
235
|
+
encoding: string;
|
|
236
|
+
wire: string;
|
|
237
|
+
bytes: number;
|
|
238
|
+
feePayer: string;
|
|
239
|
+
blockhash: string;
|
|
240
|
+
preparedAtBlockHeight: string;
|
|
241
|
+
expiresAfterBlockHeight: string;
|
|
242
|
+
};
|
|
243
|
+
chain: "solana";
|
|
244
|
+
chainId: null;
|
|
245
|
+
cluster: "mainnet-beta";
|
|
246
|
+
genesisHash: "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d";
|
|
247
|
+
requires_signature: boolean;
|
|
248
|
+
status: string;
|
|
249
|
+
}>;
|
|
250
|
+
/** `earn prepare_withdraw` on Solana. `all` burns exactly `sharesExact`. Simulated first. */
|
|
251
|
+
export declare function solanaPrepareWithdraw(vault: SolanaVaultEntry, account: string, receiver: string, args: {
|
|
252
|
+
amountHuman?: string;
|
|
253
|
+
sharesExact?: string;
|
|
254
|
+
}): Promise<{
|
|
255
|
+
next_step: string;
|
|
256
|
+
signer_rules: readonly ["Sign and send on Solana mainnet-beta only: check the wallet's network before signing.", "Send before block height `transaction.expiresAfterBlockHeight` (about a minute after it was prepared). If that height has passed, do not sign: prepare the transaction again.", "Before signing, check the fee payer and signer is the account the operator named, and the vault the transaction calls (`vaultAddress`) is the vault named. Do not sign a transaction whose account you did not confirm.", "Confirm by the signature's status. If a send fails with no status, read the account's share balance before preparing again: a transaction that did land would be repeated by a new one."];
|
|
257
|
+
vault: string;
|
|
258
|
+
vaultAddress: string & import("@solana/nominal-types").NominalType<"brand", "Address"> & import("@solana/nominal-types").NominalType<"stringEncoding", "base58">;
|
|
259
|
+
account: string;
|
|
260
|
+
kind: "deposit" | "withdraw";
|
|
261
|
+
expected: string;
|
|
262
|
+
simulated: string;
|
|
263
|
+
transaction: {
|
|
264
|
+
encoding: string;
|
|
265
|
+
wire: string;
|
|
266
|
+
bytes: number;
|
|
267
|
+
feePayer: string;
|
|
268
|
+
blockhash: string;
|
|
269
|
+
preparedAtBlockHeight: string;
|
|
270
|
+
expiresAfterBlockHeight: string;
|
|
271
|
+
};
|
|
272
|
+
chain: "solana";
|
|
273
|
+
chainId: null;
|
|
274
|
+
cluster: "mainnet-beta";
|
|
275
|
+
genesisHash: "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d";
|
|
276
|
+
requires_signature: boolean;
|
|
277
|
+
status: string;
|
|
278
|
+
}>;
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The earn commands on Solana: what `src/earn/commands.ts` answers when the vault is on Solana.
|
|
3
|
+
*
|
|
4
|
+
* The same contracts as on EVM, adapted where Solana differs:
|
|
5
|
+
* - A prepared deposit or withdrawal is ONE unsigned transaction (base64 wire bytes), not a list of calls,
|
|
6
|
+
* and it EXPIRES: it names a recent blockhash and lands only before `lastValidBlockHeight`, about a minute
|
|
7
|
+
* later. The envelope says so in structure (`transaction.expiresAfterBlockHeight`), not only in prose.
|
|
8
|
+
* - It is simulated before it is returned. A transaction the program would refuse is not handed to a signer:
|
|
9
|
+
* the refusal comes back instead, with the program's own reason.
|
|
10
|
+
* - There is no receiver. A Kamino vault mints shares to the signer's own account and pays a withdrawal to the
|
|
11
|
+
* account that burns the shares, so `--receiver` must be the account, and anything else is refused.
|
|
12
|
+
* - There is no approve step, and no event scan: entry basis and yield are not read on Solana, and say so.
|
|
13
|
+
*/
|
|
14
|
+
import { isAddress as isSolanaAddress } from "@solana/kit";
|
|
15
|
+
import { SOLANA_INFO, solanaRpcSourceForEnv, solanaRpcUrlFromEnv } from "../client.js";
|
|
16
|
+
import { describeError, redactEndpoints } from "../redact.js";
|
|
17
|
+
import { formatAmount, parseAmount } from "../units.js";
|
|
18
|
+
import { PACKAGE_VERSION } from "../version.js";
|
|
19
|
+
import { loadRegistry } from "../registry.js";
|
|
20
|
+
import { MAINNET_GENESIS_HASH } from "../solana/constants.js";
|
|
21
|
+
import { associatedTokenAccount, compileUnsigned } from "../solana/kvault.js";
|
|
22
|
+
import { makeSolanaRpc, solanaCluster } from "../solana/rpc.js";
|
|
23
|
+
import { depositInstructions, describeSimulation, freshLifetime, partialWithdrawal, preflightDepositSolana, readVault, sharePrice, simulate, simulateWithdrawal, tokenBalance, withdrawInstructions } from "../solana/vault.js";
|
|
24
|
+
/** Which chain a Solana response is about: the name a caller passes back, and the cluster a wallet must be on. */
|
|
25
|
+
export const onSolana = { chain: SOLANA_INFO.key, chainId: null, cluster: "mainnet-beta", genesisHash: MAINNET_GENESIS_HASH };
|
|
26
|
+
/** The explorer page for a Solana account or transaction. */
|
|
27
|
+
export const solscan = (kind, id) => `https://solscan.io/${kind}/${id}`;
|
|
28
|
+
/** A Solana address argument, checked here: the CLI's schema accepts either family's address form. */
|
|
29
|
+
export function solanaAccount(v, what) {
|
|
30
|
+
if (!isSolanaAddress(v))
|
|
31
|
+
throw new Error(`${what} must be a Solana address for a vault on Solana; got ${v}`);
|
|
32
|
+
return v;
|
|
33
|
+
}
|
|
34
|
+
/** Every Solana read goes through one client per command, on the endpoint the environment names. */
|
|
35
|
+
function rpcAndCheck() {
|
|
36
|
+
return { rpc: makeSolanaRpc(solanaRpcUrlFromEnv()), source: solanaRpcSourceForEnv().source };
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Runs the reads WHILE asking the endpoint which cluster it is. A devnet or local endpoint answers every
|
|
40
|
+
* read, and the vault's address has no account there, so the reads fail as "no account" — a mismatch is
|
|
41
|
+
* reported INSTEAD, naming the variable, as on EVM.
|
|
42
|
+
*/
|
|
43
|
+
async function onMainnet(rpc, source, work) {
|
|
44
|
+
const [cluster, settled] = await Promise.all([
|
|
45
|
+
solanaRpcSourceForEnv().configured ? solanaCluster(rpc) : Promise.resolve("mainnet"),
|
|
46
|
+
work().then((value) => ({ ok: true, value }), (error) => ({ ok: false, error })),
|
|
47
|
+
]);
|
|
48
|
+
if (cluster === "other")
|
|
49
|
+
throw new Error(`the endpoint in ${source} is not Solana mainnet-beta (its genesis hash differs). Point ${SOLANA_INFO.rpcEnv[0]} at a mainnet endpoint; until then no Solana read can be trusted.`);
|
|
50
|
+
if (!settled.ok)
|
|
51
|
+
throw settled.error;
|
|
52
|
+
return settled.value;
|
|
53
|
+
}
|
|
54
|
+
/** The row `earn vaults` lists for a Solana vault. */
|
|
55
|
+
export function solanaVaultRow(v) {
|
|
56
|
+
return {
|
|
57
|
+
symbol: v.symbol,
|
|
58
|
+
name: v.name,
|
|
59
|
+
warning: v.warning,
|
|
60
|
+
links: { explorer: solscan("account", v.address) },
|
|
61
|
+
backend: v.backend,
|
|
62
|
+
isDefault: v.isDefault,
|
|
63
|
+
chain: SOLANA_INFO.key,
|
|
64
|
+
chainId: null,
|
|
65
|
+
address: v.address,
|
|
66
|
+
chassis: v.chassis,
|
|
67
|
+
asset: v.asset,
|
|
68
|
+
sharesMint: v.sharesMint,
|
|
69
|
+
shareDecimals: v.shareDecimals,
|
|
70
|
+
depositOpen: v.depositOpen,
|
|
71
|
+
notes: v.notes,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/** `earn status` with no account: is the Solana endpoint up, and is it mainnet. Never throws. */
|
|
75
|
+
export async function solanaHealth(vault, partial) {
|
|
76
|
+
const src = solanaRpcSourceForEnv();
|
|
77
|
+
const base = {
|
|
78
|
+
mode: "health",
|
|
79
|
+
...partial,
|
|
80
|
+
server: "treasury",
|
|
81
|
+
version: PACKAGE_VERSION,
|
|
82
|
+
registry: { schemaVersion: loadRegistry().schemaVersion, vaults: loadRegistry().vaults.length + loadRegistry().solanaVaults.length, reconciledAtIso: loadRegistry().reconciledAtIso },
|
|
83
|
+
...onSolana,
|
|
84
|
+
vault: vault.symbol,
|
|
85
|
+
rpcSource: src.source,
|
|
86
|
+
rpcConfigured: src.configured,
|
|
87
|
+
};
|
|
88
|
+
try {
|
|
89
|
+
const rpc = makeSolanaRpc(solanaRpcUrlFromEnv());
|
|
90
|
+
const [cluster, slot] = await Promise.all([solanaCluster(rpc), rpc.getSlot({ commitment: "confirmed" }).send()]);
|
|
91
|
+
if (cluster === "other") {
|
|
92
|
+
return { ...base, rpc: "wrong_chain", latestSlot: null, reason: `the endpoint in ${src.source} is not Solana mainnet-beta (its genesis hash differs). Point ${SOLANA_INFO.rpcEnv[0]} at a mainnet endpoint.` };
|
|
93
|
+
}
|
|
94
|
+
return { ...base, rpc: "ok", chainVerified: cluster === "mainnet", latestSlot: slot.toString() };
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
return { ...base, rpc: "unreachable", latestSlot: null, reason: redactEndpoints(e instanceof Error ? e.message : String(e)) };
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/** `earn status --account`: the deposit pre-flight. */
|
|
101
|
+
export async function solanaPreflight(vault, account, amountHuman) {
|
|
102
|
+
const { rpc, source } = rpcAndCheck();
|
|
103
|
+
const r = await onMainnet(rpc, source, () => preflightDepositSolana(rpc, vault, solanaAccount(account, "account"), amountHuman));
|
|
104
|
+
const { expectedSharesRaw: _raw, ...rest } = r;
|
|
105
|
+
return rest;
|
|
106
|
+
}
|
|
107
|
+
/** `earn quote --direction deposit`. */
|
|
108
|
+
export async function solanaQuoteDeposit(vault, account, amountHuman) {
|
|
109
|
+
const { rpc, source } = rpcAndCheck();
|
|
110
|
+
const pf = await onMainnet(rpc, source, () => preflightDepositSolana(rpc, vault, solanaAccount(account, "account"), amountHuman));
|
|
111
|
+
const raw = pf.expectedSharesRaw;
|
|
112
|
+
const { expectedSharesRaw: _raw, ...preflight } = pf;
|
|
113
|
+
return {
|
|
114
|
+
vault: vault.symbol,
|
|
115
|
+
depositor: account,
|
|
116
|
+
amountUsdc: `${amountHuman} ${vault.asset.symbol}`,
|
|
117
|
+
expectedShares: raw === undefined ? "unknown — the simulated deposit did not succeed; see preflight" : `${formatAmount(raw, vault.shareDecimals)} ${vault.symbol}`,
|
|
118
|
+
sharePriceInAssets: preflight.quotes?.sharePriceInAssets,
|
|
119
|
+
preflight,
|
|
120
|
+
note: "Read from a simulated deposit at the slot shown: the shares the account would receive. This client quotes no rate.",
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/** Shares for `amountHuman` of the asset, rounded UP so the withdrawal is worth at least the amount asked. */
|
|
124
|
+
function sharesFor(v, amountHuman) {
|
|
125
|
+
const amount = parseAmount(amountHuman, v.entry.asset.decimals, `withdrawal amount (${v.entry.asset.symbol})`);
|
|
126
|
+
if (amount === 0n)
|
|
127
|
+
throw new Error("a withdrawal of 0");
|
|
128
|
+
if (v.holdings.netAum === 0n)
|
|
129
|
+
throw new Error(`${v.entry.symbol} holds nothing to withdraw`);
|
|
130
|
+
return (amount * v.state.sharesIssued + v.holdings.netAum - 1n) / v.holdings.netAum;
|
|
131
|
+
}
|
|
132
|
+
/** Simulates a withdrawal of `shares` and reads what the account would receive and how many shares it would burn. */
|
|
133
|
+
async function simulateWithdraw(rpc, v, account, shares) {
|
|
134
|
+
return simulateWithdrawal(rpc, v, account, await withdrawInstructions(v, account, shares));
|
|
135
|
+
}
|
|
136
|
+
/** `earn quote --direction withdraw`. */
|
|
137
|
+
export async function solanaQuoteWithdraw(vault, account, amountHuman) {
|
|
138
|
+
const { rpc, source } = rpcAndCheck();
|
|
139
|
+
return onMainnet(rpc, source, async () => {
|
|
140
|
+
const owner = solanaAccount(account, "account");
|
|
141
|
+
const v = await readVault(rpc, vault);
|
|
142
|
+
const held = await tokenBalance(rpc, await associatedTokenAccount(owner, v.state.sharesMint));
|
|
143
|
+
const shares = sharesFor(v, amountHuman);
|
|
144
|
+
const base = {
|
|
145
|
+
vault: vault.symbol,
|
|
146
|
+
owner,
|
|
147
|
+
amountUsdc: `${amountHuman} ${vault.asset.symbol}`,
|
|
148
|
+
sharesToBurn: `${formatAmount(shares, vault.shareDecimals)} ${vault.symbol}`,
|
|
149
|
+
sharesHeld: `${formatAmount(held.amount, vault.shareDecimals)} ${vault.symbol}`,
|
|
150
|
+
instantLiquidity: `${formatAmount(v.holdings.idle, vault.asset.decimals)} ${vault.asset.symbol}`,
|
|
151
|
+
sharePriceInAssets: `${sharePrice(v)} ${vault.asset.symbol} per share`,
|
|
152
|
+
};
|
|
153
|
+
if (shares > held.amount) {
|
|
154
|
+
return { ...base, canWithdraw: false, note: `the account holds ${formatAmount(held.amount, vault.shareDecimals)} shares, fewer than the ${formatAmount(shares, vault.shareDecimals)} this amount needs` };
|
|
155
|
+
}
|
|
156
|
+
const { sim, received, burned, legs } = await simulateWithdraw(rpc, v, owner, shares);
|
|
157
|
+
if (received === undefined || burned === undefined)
|
|
158
|
+
return { ...base, canWithdraw: false, measuredAtSlot: Number(sim.slot), note: `the simulated withdrawal failed: ${describeSimulation(sim)}` };
|
|
159
|
+
const partial = partialWithdrawal(shares, burned, legs, vault.shareDecimals, sim.slot);
|
|
160
|
+
if (partial)
|
|
161
|
+
return { ...base, canWithdraw: false, measuredAtSlot: Number(sim.slot), note: partial };
|
|
162
|
+
return {
|
|
163
|
+
...base,
|
|
164
|
+
canWithdraw: true,
|
|
165
|
+
receives: `${formatAmount(received, vault.asset.decimals)} ${vault.asset.symbol}`,
|
|
166
|
+
measuredAtSlot: Number(sim.slot),
|
|
167
|
+
note: "simulated withdrawal succeeds at this slot. `receives` is what the account's USDC balance would rise by — net of the up to 0.001 USDC Kamino keeps per withdraw instruction.",
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
/** `earn balance`: shares, value, and what a full exit would pay now. No event scan on Solana. */
|
|
172
|
+
export async function solanaBalance(vault, account) {
|
|
173
|
+
const { rpc, source } = rpcAndCheck();
|
|
174
|
+
return onMainnet(rpc, source, async () => {
|
|
175
|
+
const owner = solanaAccount(account, "account");
|
|
176
|
+
const v = await readVault(rpc, vault);
|
|
177
|
+
const held = await tokenBalance(rpc, await associatedTokenAccount(owner, v.state.sharesMint));
|
|
178
|
+
const value = v.state.sharesIssued === 0n ? 0n : (held.amount * v.holdings.netAum) / v.state.sharesIssued;
|
|
179
|
+
let exit;
|
|
180
|
+
if (held.amount === 0n) {
|
|
181
|
+
exit = { exitableNow: `0 ${vault.asset.symbol}`, measuredAs: "no position" };
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
try {
|
|
185
|
+
const { sim, received } = await simulateWithdraw(rpc, v, owner, held.amount);
|
|
186
|
+
exit =
|
|
187
|
+
received === undefined
|
|
188
|
+
? { exitableNow: "unknown", measuredAs: "refused", note: `a full withdrawal was refused at this slot: ${describeSimulation(sim)}` }
|
|
189
|
+
: { exitableNow: `${formatAmount(received, vault.asset.decimals)} ${vault.asset.symbol}`, measuredAs: "a simulated full withdrawal", note: "net of the up to 0.001 USDC Kamino keeps per withdraw instruction" };
|
|
190
|
+
}
|
|
191
|
+
catch (e) {
|
|
192
|
+
exit = { exitableNow: "unknown", measuredAs: "not measured", note: describeError(e) };
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
vault: vault.symbol,
|
|
197
|
+
account: owner,
|
|
198
|
+
sharesExact: formatAmount(held.amount, vault.shareDecimals),
|
|
199
|
+
shares: `${formatAmount(held.amount, vault.shareDecimals)} ${vault.symbol}`,
|
|
200
|
+
usdcValue: `${formatAmount(value, vault.asset.decimals)} ${vault.asset.symbol}`,
|
|
201
|
+
sharePriceInAssets: `${sharePrice(v)} ${vault.asset.symbol} per share`,
|
|
202
|
+
exit: { ...exit, instantLiquidity: `${formatAmount(v.holdings.idle, vault.asset.decimals)} ${vault.asset.symbol}` },
|
|
203
|
+
entryBasisUsdc: "unknown — not read on Solana; see scan.note",
|
|
204
|
+
accruedYieldUsdc: "unknown — not read on Solana; see scan.note",
|
|
205
|
+
scan: {
|
|
206
|
+
complete: false,
|
|
207
|
+
wholeHistory: false,
|
|
208
|
+
note: "On Solana this client reads the position, not its history: entry basis and yield are not derived. The account's own deposit and withdrawal transactions are the record (solscan.io lists them).",
|
|
209
|
+
},
|
|
210
|
+
measuredAtSlot: Number(v.slot),
|
|
211
|
+
};
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* What a Solana signer must do for a prepared transaction to land exactly once. Stated with every build,
|
|
216
|
+
* because nothing here signs or sends.
|
|
217
|
+
*/
|
|
218
|
+
export const SOLANA_SIGNER_RULES = [
|
|
219
|
+
"Sign and send on Solana mainnet-beta only: check the wallet's network before signing.",
|
|
220
|
+
"Send before block height `transaction.expiresAfterBlockHeight` (about a minute after it was prepared). If that height has passed, do not sign: prepare the transaction again.",
|
|
221
|
+
"Before signing, check the fee payer and signer is the account the operator named, and the vault the transaction calls (`vaultAddress`) is the vault named. Do not sign a transaction whose account you did not confirm.",
|
|
222
|
+
"Confirm by the signature's status. If a send fails with no status, read the account's share balance before preparing again: a transaction that did land would be repeated by a new one.",
|
|
223
|
+
];
|
|
224
|
+
/**
|
|
225
|
+
* The envelope a Solana build returns: one unsigned transaction, its expiry, and what simulating it showed.
|
|
226
|
+
* The deposit warning is NOT attached here: `commitsMoney` in ./commands.ts is the one place that writes it.
|
|
227
|
+
*/
|
|
228
|
+
async function envelope(rpc, v, account, kind, simulated, ixs, expected) {
|
|
229
|
+
const life = await freshLifetime(rpc);
|
|
230
|
+
const tx = compileUnsigned(ixs, account, life);
|
|
231
|
+
return {
|
|
232
|
+
requires_signature: true,
|
|
233
|
+
status: "unsigned",
|
|
234
|
+
...onSolana,
|
|
235
|
+
next_step: `This is ONE Solana transaction, for Solana mainnet-beta: tell the operator which chain. Hand it to the operator's own Solana wallet now — it lands only until block height ${life.lastValidBlockHeight}, about a minute from now — following \`signer_rules\`. Nothing has been submitted; no funds have moved.`,
|
|
236
|
+
signer_rules: SOLANA_SIGNER_RULES,
|
|
237
|
+
vault: v.entry.symbol,
|
|
238
|
+
vaultAddress: v.entry.address,
|
|
239
|
+
account,
|
|
240
|
+
kind,
|
|
241
|
+
expected,
|
|
242
|
+
simulated,
|
|
243
|
+
transaction: {
|
|
244
|
+
encoding: "base64",
|
|
245
|
+
wire: tx.base64,
|
|
246
|
+
bytes: tx.bytes,
|
|
247
|
+
feePayer: account,
|
|
248
|
+
blockhash: life.blockhash,
|
|
249
|
+
preparedAtBlockHeight: life.currentBlockHeight.toString(),
|
|
250
|
+
expiresAfterBlockHeight: life.lastValidBlockHeight.toString(),
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
/** The receiver must be the account: shares and withdrawals go to the signer's own accounts on this program. */
|
|
255
|
+
function sameAsAccount(receiver, account) {
|
|
256
|
+
if (receiver !== account) {
|
|
257
|
+
throw new Error(`on Solana the receiver must be the account itself: a Kamino vault mints shares to the signer's own account and pays a withdrawal to the account whose shares burn. --receiver ${receiver} is not --account ${account}.`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/** `earn prepare_deposit` on Solana. Simulated first; a deposit the program would refuse is not returned. */
|
|
261
|
+
export async function solanaPrepareDeposit(vault, account, amountHuman, receiver) {
|
|
262
|
+
const user = solanaAccount(account, "account");
|
|
263
|
+
sameAsAccount(solanaAccount(receiver, "receiver"), user);
|
|
264
|
+
const { rpc, source } = rpcAndCheck();
|
|
265
|
+
return onMainnet(rpc, source, async () => {
|
|
266
|
+
const v = await readVault(rpc, vault);
|
|
267
|
+
const amount = parseAmount(amountHuman, vault.asset.decimals, `deposit amount (${vault.asset.symbol})`);
|
|
268
|
+
if (amount === 0n)
|
|
269
|
+
throw new Error("a deposit of 0");
|
|
270
|
+
const ixs = await depositInstructions(v, user, amount);
|
|
271
|
+
const sharesAta = await associatedTokenAccount(user, v.state.sharesMint);
|
|
272
|
+
const before = await tokenBalance(rpc, sharesAta);
|
|
273
|
+
const sim = await simulate(rpc, ixs, user, [sharesAta]);
|
|
274
|
+
if (!sim.ok)
|
|
275
|
+
throw new Error(`not prepared: the simulated deposit fails at slot ${sim.slot}: ${describeSimulation(sim)}. Run \`earn status --chain solana --account ${user}\` for the reason in words.`);
|
|
276
|
+
const minted = (sim.after.get(sharesAta) ?? 0n) - before.amount;
|
|
277
|
+
return envelope(rpc, v, user, "deposit", `deposit ${formatAmount(amount, vault.asset.decimals)} ${vault.asset.symbol}; the simulation at slot ${sim.slot} minted ${formatAmount(minted, vault.shareDecimals)} ${vault.symbol}`, ixs, `${formatAmount(minted, vault.shareDecimals)} ${vault.symbol}`);
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
/** `earn prepare_withdraw` on Solana. `all` burns exactly `sharesExact`. Simulated first. */
|
|
281
|
+
export async function solanaPrepareWithdraw(vault, account, receiver, args) {
|
|
282
|
+
const user = solanaAccount(account, "account");
|
|
283
|
+
sameAsAccount(solanaAccount(receiver, "receiver"), user);
|
|
284
|
+
const { rpc, source } = rpcAndCheck();
|
|
285
|
+
return onMainnet(rpc, source, async () => {
|
|
286
|
+
const v = await readVault(rpc, vault);
|
|
287
|
+
const shares = args.sharesExact !== undefined ? parseAmount(args.sharesExact, vault.shareDecimals, "shares_exact") : sharesFor(v, args.amountHuman);
|
|
288
|
+
const held = await tokenBalance(rpc, await associatedTokenAccount(user, v.state.sharesMint));
|
|
289
|
+
if (shares > held.amount)
|
|
290
|
+
throw new Error(`the account holds ${formatAmount(held.amount, vault.shareDecimals)} shares, fewer than the ${formatAmount(shares, vault.shareDecimals)} this withdrawal burns`);
|
|
291
|
+
const ixs = await withdrawInstructions(v, user, shares);
|
|
292
|
+
const { sim, received, burned, legs } = await simulateWithdraw(rpc, v, user, shares);
|
|
293
|
+
if (received === undefined || burned === undefined)
|
|
294
|
+
throw new Error(`not prepared: the simulated withdrawal fails at slot ${sim.slot}: ${describeSimulation(sim)}`);
|
|
295
|
+
const partial = partialWithdrawal(shares, burned, legs, vault.shareDecimals, sim.slot);
|
|
296
|
+
if (partial)
|
|
297
|
+
throw new Error(`not prepared: ${partial}`);
|
|
298
|
+
const got = `${formatAmount(received, vault.asset.decimals)} ${vault.asset.symbol}`;
|
|
299
|
+
return envelope(rpc, v, user, "withdraw", `burn ${formatAmount(shares, vault.shareDecimals)} ${vault.symbol}; the simulation at slot ${sim.slot} paid ${got} (net of the up to 0.001 USDC Kamino keeps per withdraw instruction)`, ixs, got);
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
//# sourceMappingURL=solana.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana.js","sourceRoot":"","sources":["../../src/earn/solana.ts"],"names":[],"mappings":"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"}
|
package/dist/guide.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The public copy for THIS version: the file at its release tag, so the guide an agent reads describes the
|
|
3
|
+
* CLI it is running. The default branch does not: it moves with each release, and before v0.1.3 it had no
|
|
4
|
+
* llms.txt at all. A tag exists only once the release is cut, so an unreleased build's URL resolves then.
|
|
5
|
+
*/
|
|
6
|
+
export declare const GUIDE_URL: string;
|
|
7
|
+
/**
|
|
8
|
+
* The `guide` field of the top-level and per-skill `--help`; undefined when this is the plugin's copy.
|
|
9
|
+
* Only the existence of `llms.txt` beside the CLI is checked, to name its path; nothing in the CLI reads it.
|
|
10
|
+
*/
|
|
11
|
+
export declare function guidePointer(): {
|
|
12
|
+
read_first: string;
|
|
13
|
+
file?: string;
|
|
14
|
+
url: string;
|
|
15
|
+
} | undefined;
|