@solana-compass/cli 0.1.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/README.md +327 -0
- package/bin/sol.mjs +6 -0
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.js +73 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/lend.d.ts +2 -0
- package/dist/commands/lend.js +262 -0
- package/dist/commands/lend.js.map +1 -0
- package/dist/commands/lp.d.ts +2 -0
- package/dist/commands/lp.js +158 -0
- package/dist/commands/lp.js.map +1 -0
- package/dist/commands/network.d.ts +2 -0
- package/dist/commands/network.js +126 -0
- package/dist/commands/network.js.map +1 -0
- package/dist/commands/portfolio.d.ts +2 -0
- package/dist/commands/portfolio.js +187 -0
- package/dist/commands/portfolio.js.map +1 -0
- package/dist/commands/stake.d.ts +2 -0
- package/dist/commands/stake.js +143 -0
- package/dist/commands/stake.js.map +1 -0
- package/dist/commands/token.d.ts +2 -0
- package/dist/commands/token.js +551 -0
- package/dist/commands/token.js.map +1 -0
- package/dist/commands/tx.d.ts +2 -0
- package/dist/commands/tx.js +131 -0
- package/dist/commands/tx.js.map +1 -0
- package/dist/commands/wallet.d.ts +2 -0
- package/dist/commands/wallet.js +403 -0
- package/dist/commands/wallet.js.map +1 -0
- package/dist/core/config-manager.d.ts +31 -0
- package/dist/core/config-manager.js +79 -0
- package/dist/core/config-manager.js.map +1 -0
- package/dist/core/kamino-compat.d.ts +17 -0
- package/dist/core/kamino-compat.js +38 -0
- package/dist/core/kamino-compat.js.map +1 -0
- package/dist/core/lend-service.d.ts +41 -0
- package/dist/core/lend-service.js +331 -0
- package/dist/core/lend-service.js.map +1 -0
- package/dist/core/lp-service.d.ts +30 -0
- package/dist/core/lp-service.js +21 -0
- package/dist/core/lp-service.js.map +1 -0
- package/dist/core/onramp-service.d.ts +15 -0
- package/dist/core/onramp-service.js +57 -0
- package/dist/core/onramp-service.js.map +1 -0
- package/dist/core/portfolio-service.d.ts +55 -0
- package/dist/core/portfolio-service.js +272 -0
- package/dist/core/portfolio-service.js.map +1 -0
- package/dist/core/price-service.d.ts +8 -0
- package/dist/core/price-service.js +116 -0
- package/dist/core/price-service.js.map +1 -0
- package/dist/core/rpc.d.ts +5 -0
- package/dist/core/rpc.js +69 -0
- package/dist/core/rpc.js.map +1 -0
- package/dist/core/stake-service.d.ts +42 -0
- package/dist/core/stake-service.js +319 -0
- package/dist/core/stake-service.js.map +1 -0
- package/dist/core/swap-service.d.ts +31 -0
- package/dist/core/swap-service.js +142 -0
- package/dist/core/swap-service.js.map +1 -0
- package/dist/core/token-registry.d.ts +23 -0
- package/dist/core/token-registry.js +174 -0
- package/dist/core/token-registry.js.map +1 -0
- package/dist/core/token-service.d.ts +20 -0
- package/dist/core/token-service.js +92 -0
- package/dist/core/token-service.js.map +1 -0
- package/dist/core/transaction.d.ts +55 -0
- package/dist/core/transaction.js +196 -0
- package/dist/core/transaction.js.map +1 -0
- package/dist/core/wallet-manager.d.ts +20 -0
- package/dist/core/wallet-manager.js +142 -0
- package/dist/core/wallet-manager.js.map +1 -0
- package/dist/db/database.d.ts +3 -0
- package/dist/db/database.js +44 -0
- package/dist/db/database.js.map +1 -0
- package/dist/db/migrations/001_initial.d.ts +1 -0
- package/dist/db/migrations/001_initial.js +116 -0
- package/dist/db/migrations/001_initial.js.map +1 -0
- package/dist/db/migrations/002_tx_prices.d.ts +1 -0
- package/dist/db/migrations/002_tx_prices.js +5 -0
- package/dist/db/migrations/002_tx_prices.js.map +1 -0
- package/dist/db/repos/price-repo.d.ts +11 -0
- package/dist/db/repos/price-repo.js +14 -0
- package/dist/db/repos/price-repo.js.map +1 -0
- package/dist/db/repos/snapshot-repo.d.ts +27 -0
- package/dist/db/repos/snapshot-repo.js +32 -0
- package/dist/db/repos/snapshot-repo.js.map +1 -0
- package/dist/db/repos/token-repo.d.ts +17 -0
- package/dist/db/repos/token-repo.js +53 -0
- package/dist/db/repos/token-repo.js.map +1 -0
- package/dist/db/repos/transaction-repo.d.ts +22 -0
- package/dist/db/repos/transaction-repo.js +28 -0
- package/dist/db/repos/transaction-repo.js.map +1 -0
- package/dist/db/repos/wallet-repo.d.ts +18 -0
- package/dist/db/repos/wallet-repo.js +44 -0
- package/dist/db/repos/wallet-repo.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +84 -0
- package/dist/index.js.map +1 -0
- package/dist/output/formatter.d.ts +27 -0
- package/dist/output/formatter.js +76 -0
- package/dist/output/formatter.js.map +1 -0
- package/dist/output/portfolio-renderer.d.ts +3 -0
- package/dist/output/portfolio-renderer.js +205 -0
- package/dist/output/portfolio-renderer.js.map +1 -0
- package/dist/output/table.d.ts +8 -0
- package/dist/output/table.js +22 -0
- package/dist/output/table.js.map +1 -0
- package/dist/utils/fs.d.ts +7 -0
- package/dist/utils/fs.js +39 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/retry.d.ts +17 -0
- package/dist/utils/retry.js +55 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/solana.d.ts +9 -0
- package/dist/utils/solana.js +26 -0
- package/dist/utils/solana.js.map +1 -0
- package/dist/utils/token-list.d.ts +9 -0
- package/dist/utils/token-list.js +31 -0
- package/dist/utils/token-list.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { getWellKnownBySymbol, getWellKnownByMint } from '../utils/token-list.js';
|
|
2
|
+
import * as tokenRepo from '../db/repos/token-repo.js';
|
|
3
|
+
import { verbose } from '../output/formatter.js';
|
|
4
|
+
import { withRetry, isRetryableHttpError } from '../utils/retry.js';
|
|
5
|
+
// Jupiter Token API v2 provider
|
|
6
|
+
export class JupiterTokenProvider {
|
|
7
|
+
name = 'jupiter';
|
|
8
|
+
baseUrl = 'https://lite-api.jup.ag';
|
|
9
|
+
async search(query) {
|
|
10
|
+
const url = `${this.baseUrl}/tokens/v2/search?query=${encodeURIComponent(query)}`;
|
|
11
|
+
verbose(`Fetching token metadata: ${url}`);
|
|
12
|
+
const res = await withRetry(() => fetch(url), {
|
|
13
|
+
maxRetries: 2,
|
|
14
|
+
shouldRetry: isRetryableHttpError,
|
|
15
|
+
});
|
|
16
|
+
if (!res.ok)
|
|
17
|
+
throw new Error(`Jupiter token search failed: ${res.status}`);
|
|
18
|
+
const data = await res.json();
|
|
19
|
+
return data.map(t => ({
|
|
20
|
+
mint: t.address || t.id,
|
|
21
|
+
symbol: t.symbol,
|
|
22
|
+
name: t.name,
|
|
23
|
+
decimals: t.decimals,
|
|
24
|
+
logoUri: t.logoURI || t.icon,
|
|
25
|
+
tags: t.tags,
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
async getByMint(mints) {
|
|
29
|
+
if (mints.length === 0)
|
|
30
|
+
return [];
|
|
31
|
+
// Jupiter v2: fetch by comma-separated mint addresses (max 100 per request)
|
|
32
|
+
const results = [];
|
|
33
|
+
for (let i = 0; i < mints.length; i += 100) {
|
|
34
|
+
const batch = mints.slice(i, i + 100);
|
|
35
|
+
const url = `${this.baseUrl}/tokens/v2/${batch.join(',')}`;
|
|
36
|
+
verbose(`Fetching token metadata for ${batch.length} mints`);
|
|
37
|
+
const res = await withRetry(() => fetch(url), {
|
|
38
|
+
maxRetries: 2,
|
|
39
|
+
shouldRetry: isRetryableHttpError,
|
|
40
|
+
});
|
|
41
|
+
if (!res.ok)
|
|
42
|
+
continue;
|
|
43
|
+
const data = await res.json();
|
|
44
|
+
for (const t of data) {
|
|
45
|
+
results.push({
|
|
46
|
+
mint: t.address || t.id,
|
|
47
|
+
symbol: t.symbol,
|
|
48
|
+
name: t.name,
|
|
49
|
+
decimals: t.decimals,
|
|
50
|
+
logoUri: t.logoURI || t.icon,
|
|
51
|
+
tags: t.tags,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return results;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Default providers — extensible
|
|
59
|
+
const providers = [new JupiterTokenProvider()];
|
|
60
|
+
export function registerProvider(provider) {
|
|
61
|
+
providers.push(provider);
|
|
62
|
+
}
|
|
63
|
+
// Resolution chain: hardcoded → SQLite cache → live providers
|
|
64
|
+
export async function resolveToken(symbolOrMint) {
|
|
65
|
+
// 1. Hardcoded well-known tokens
|
|
66
|
+
const wellKnown = getWellKnownBySymbol(symbolOrMint) || getWellKnownByMint(symbolOrMint);
|
|
67
|
+
if (wellKnown) {
|
|
68
|
+
return {
|
|
69
|
+
mint: wellKnown.mint,
|
|
70
|
+
symbol: wellKnown.symbol,
|
|
71
|
+
name: wellKnown.name,
|
|
72
|
+
decimals: wellKnown.decimals,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
// 2. SQLite cache — by symbol
|
|
76
|
+
const bySymbol = tokenRepo.getTokenBySymbol(symbolOrMint);
|
|
77
|
+
if (bySymbol.length > 0 && !tokenRepo.isTokenCacheStale(bySymbol[0].mint)) {
|
|
78
|
+
const t = bySymbol[0];
|
|
79
|
+
return { mint: t.mint, symbol: t.symbol || '', name: t.name || '', decimals: t.decimals, logoUri: t.logo_uri || undefined };
|
|
80
|
+
}
|
|
81
|
+
// 2b. SQLite cache — by mint address
|
|
82
|
+
const byMint = tokenRepo.getTokenByMint(symbolOrMint);
|
|
83
|
+
if (byMint && !tokenRepo.isTokenCacheStale(byMint.mint)) {
|
|
84
|
+
return { mint: byMint.mint, symbol: byMint.symbol || '', name: byMint.name || '', decimals: byMint.decimals, logoUri: byMint.logo_uri || undefined };
|
|
85
|
+
}
|
|
86
|
+
// 3. Live provider lookup
|
|
87
|
+
for (const provider of providers) {
|
|
88
|
+
try {
|
|
89
|
+
// If it looks like a mint address, fetch by mint
|
|
90
|
+
if (symbolOrMint.length >= 32) {
|
|
91
|
+
const results = await provider.getByMint([symbolOrMint]);
|
|
92
|
+
if (results.length > 0) {
|
|
93
|
+
cacheTokens(results, provider.name);
|
|
94
|
+
return results[0];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Search by symbol/name
|
|
98
|
+
const results = await provider.search(symbolOrMint);
|
|
99
|
+
if (results.length > 0) {
|
|
100
|
+
cacheTokens(results, provider.name);
|
|
101
|
+
return results[0];
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
verbose(`Provider ${provider.name} failed: ${err}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
// Resolve multiple tokens efficiently
|
|
111
|
+
export async function resolveTokens(queries) {
|
|
112
|
+
const results = new Map();
|
|
113
|
+
const unresolved = [];
|
|
114
|
+
for (const q of queries) {
|
|
115
|
+
// Check hardcoded + cache first
|
|
116
|
+
const wellKnown = getWellKnownBySymbol(q) || getWellKnownByMint(q);
|
|
117
|
+
if (wellKnown) {
|
|
118
|
+
results.set(q, { mint: wellKnown.mint, symbol: wellKnown.symbol, name: wellKnown.name, decimals: wellKnown.decimals });
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
const cached = tokenRepo.getTokenBySymbol(q)[0] || tokenRepo.getTokenByMint(q);
|
|
122
|
+
if (cached && !tokenRepo.isTokenCacheStale(cached.mint)) {
|
|
123
|
+
results.set(q, { mint: cached.mint, symbol: cached.symbol || '', name: cached.name || '', decimals: cached.decimals });
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
unresolved.push(q);
|
|
127
|
+
}
|
|
128
|
+
// Batch resolve unresolved ones
|
|
129
|
+
if (unresolved.length > 0) {
|
|
130
|
+
for (const q of unresolved) {
|
|
131
|
+
const resolved = await resolveToken(q);
|
|
132
|
+
if (resolved)
|
|
133
|
+
results.set(q, resolved);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return results;
|
|
137
|
+
}
|
|
138
|
+
function cacheTokens(tokens, source) {
|
|
139
|
+
tokenRepo.upsertTokenBatch(tokens.map(t => ({
|
|
140
|
+
mint: t.mint,
|
|
141
|
+
symbol: t.symbol,
|
|
142
|
+
name: t.name,
|
|
143
|
+
decimals: t.decimals,
|
|
144
|
+
logo_uri: t.logoUri || null,
|
|
145
|
+
tags: t.tags ? JSON.stringify(t.tags) : null,
|
|
146
|
+
source,
|
|
147
|
+
})));
|
|
148
|
+
}
|
|
149
|
+
// Sync: populate cache from well-known tokens
|
|
150
|
+
export async function syncTokenCache() {
|
|
151
|
+
const { WELL_KNOWN_TOKENS } = await import('../utils/token-list.js');
|
|
152
|
+
// Cache all well-known tokens
|
|
153
|
+
tokenRepo.upsertTokenBatch(WELL_KNOWN_TOKENS.map(t => ({
|
|
154
|
+
mint: t.mint,
|
|
155
|
+
symbol: t.symbol,
|
|
156
|
+
name: t.name,
|
|
157
|
+
decimals: t.decimals,
|
|
158
|
+
logo_uri: null,
|
|
159
|
+
tags: JSON.stringify(['well-known']),
|
|
160
|
+
source: 'hardcoded',
|
|
161
|
+
})));
|
|
162
|
+
// Try to fetch extended metadata from Jupiter for all well-known mints
|
|
163
|
+
try {
|
|
164
|
+
const provider = providers[0];
|
|
165
|
+
const mints = WELL_KNOWN_TOKENS.map(t => t.mint);
|
|
166
|
+
const fetched = await provider.getByMint(mints);
|
|
167
|
+
cacheTokens(fetched, provider.name);
|
|
168
|
+
return WELL_KNOWN_TOKENS.length + fetched.length;
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return WELL_KNOWN_TOKENS.length;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=token-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-registry.js","sourceRoot":"","sources":["../../src/core/token-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface TokenBalance {
|
|
2
|
+
mint: string;
|
|
3
|
+
symbol: string;
|
|
4
|
+
name: string;
|
|
5
|
+
decimals: number;
|
|
6
|
+
balance: string;
|
|
7
|
+
uiBalance: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function getSolBalance(addr: string): Promise<number>;
|
|
10
|
+
export declare function getTokenBalances(walletAddress: string): Promise<TokenBalance[]>;
|
|
11
|
+
export interface TokenAccountInfo {
|
|
12
|
+
pubkey: string;
|
|
13
|
+
mint: string;
|
|
14
|
+
symbol: string;
|
|
15
|
+
name: string;
|
|
16
|
+
decimals: number;
|
|
17
|
+
balance: string;
|
|
18
|
+
uiBalance: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function getAllTokenAccounts(walletAddress: string): Promise<TokenAccountInfo[]>;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { getRpc } from './rpc.js';
|
|
2
|
+
import { address } from '@solana/kit';
|
|
3
|
+
import { resolveToken } from './token-registry.js';
|
|
4
|
+
import { lamportsToSol, SOL_MINT, SOL_DECIMALS } from '../utils/solana.js';
|
|
5
|
+
import { verbose } from '../output/formatter.js';
|
|
6
|
+
export async function getSolBalance(addr) {
|
|
7
|
+
const rpc = getRpc();
|
|
8
|
+
const result = await rpc.getBalance(address(addr)).send();
|
|
9
|
+
return lamportsToSol(result.value);
|
|
10
|
+
}
|
|
11
|
+
export async function getTokenBalances(walletAddress) {
|
|
12
|
+
const rpc = getRpc();
|
|
13
|
+
const balances = [];
|
|
14
|
+
// SOL balance
|
|
15
|
+
const solBalance = await getSolBalance(walletAddress);
|
|
16
|
+
balances.push({
|
|
17
|
+
mint: SOL_MINT,
|
|
18
|
+
symbol: 'SOL',
|
|
19
|
+
name: 'Solana',
|
|
20
|
+
decimals: SOL_DECIMALS,
|
|
21
|
+
balance: String(BigInt(Math.round(solBalance * 1e9))),
|
|
22
|
+
uiBalance: solBalance,
|
|
23
|
+
});
|
|
24
|
+
// SPL token accounts
|
|
25
|
+
try {
|
|
26
|
+
const tokenAccounts = await rpc.getTokenAccountsByOwner(address(walletAddress), { programId: address('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA') }, { encoding: 'jsonParsed' }).send();
|
|
27
|
+
for (const account of tokenAccounts.value) {
|
|
28
|
+
const parsed = account.account.data.parsed?.info;
|
|
29
|
+
if (!parsed)
|
|
30
|
+
continue;
|
|
31
|
+
const mint = parsed.mint;
|
|
32
|
+
const rawBalance = parsed.tokenAmount?.amount;
|
|
33
|
+
const decimals = parsed.tokenAmount?.decimals;
|
|
34
|
+
const uiBalance = parsed.tokenAmount?.uiAmount;
|
|
35
|
+
if (!rawBalance || rawBalance === '0')
|
|
36
|
+
continue;
|
|
37
|
+
// Resolve token metadata
|
|
38
|
+
let symbol = mint.slice(0, 6) + '...';
|
|
39
|
+
let name = 'Unknown Token';
|
|
40
|
+
try {
|
|
41
|
+
const meta = await resolveToken(mint);
|
|
42
|
+
if (meta) {
|
|
43
|
+
symbol = meta.symbol;
|
|
44
|
+
name = meta.name;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
verbose(`Could not resolve metadata for ${mint}`);
|
|
49
|
+
}
|
|
50
|
+
balances.push({ mint, symbol, name, decimals, balance: rawBalance, uiBalance });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
verbose(`Failed to fetch token accounts: ${err}`);
|
|
55
|
+
}
|
|
56
|
+
return balances;
|
|
57
|
+
}
|
|
58
|
+
export async function getAllTokenAccounts(walletAddress) {
|
|
59
|
+
const rpc = getRpc();
|
|
60
|
+
const accounts = [];
|
|
61
|
+
try {
|
|
62
|
+
const tokenAccounts = await rpc.getTokenAccountsByOwner(address(walletAddress), { programId: address('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA') }, { encoding: 'jsonParsed' }).send();
|
|
63
|
+
for (const account of tokenAccounts.value) {
|
|
64
|
+
const parsed = account.account.data.parsed?.info;
|
|
65
|
+
if (!parsed)
|
|
66
|
+
continue;
|
|
67
|
+
const mint = parsed.mint;
|
|
68
|
+
const rawBalance = parsed.tokenAmount?.amount ?? '0';
|
|
69
|
+
const decimals = parsed.tokenAmount?.decimals ?? 0;
|
|
70
|
+
const uiBalance = parsed.tokenAmount?.uiAmount ?? 0;
|
|
71
|
+
const pubkey = String(account.pubkey);
|
|
72
|
+
let symbol = mint.slice(0, 6) + '...';
|
|
73
|
+
let name = 'Unknown Token';
|
|
74
|
+
try {
|
|
75
|
+
const meta = await resolveToken(mint);
|
|
76
|
+
if (meta) {
|
|
77
|
+
symbol = meta.symbol;
|
|
78
|
+
name = meta.name;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
verbose(`Could not resolve metadata for ${mint}`);
|
|
83
|
+
}
|
|
84
|
+
accounts.push({ pubkey, mint, symbol, name, decimals, balance: rawBalance, uiBalance });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
verbose(`Failed to fetch token accounts: ${err}`);
|
|
89
|
+
}
|
|
90
|
+
return accounts;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=token-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-service.js","sourceRoot":"","sources":["../../src/core/token-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,OAAO,EAA0B,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAsB,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,aAAa,EAAmB,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC5F,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAWjD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY;IAC9C,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IACrB,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1D,OAAO,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,aAAqB;IAC1D,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IACrB,MAAM,QAAQ,GAAmB,EAAE,CAAC;IAEpC,cAAc;IACd,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,aAAa,CAAC,CAAC;IACtD,QAAQ,CAAC,IAAI,CAAC;QACZ,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,YAAY;QACtB,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC,CAAC;QACrD,SAAS,EAAE,UAAU;KACtB,CAAC,CAAC;IAEH,qBAAqB;IACrB,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,MAAM,GAAG,CAAC,uBAAuB,CACrD,OAAO,CAAC,aAAa,CAAC,EACtB,EAAE,SAAS,EAAE,OAAO,CAAC,6CAA6C,CAAC,EAAE,EACrE,EAAE,QAAQ,EAAE,YAAY,EAAE,CAC3B,CAAC,IAAI,EAAE,CAAC;QAET,KAAK,MAAM,OAAO,IAAI,aAAa,CAAC,KAAK,EAAE,CAAC;YAC1C,MAAM,MAAM,GAAI,OAAO,CAAC,OAAO,CAAC,IAAY,CAAC,MAAM,EAAE,IAAI,CAAC;YAC1D,IAAI,CAAC,MAAM;gBAAE,SAAS;YAEtB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAc,CAAC;YACnC,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,EAAE,MAAgB,CAAC;YACxD,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,EAAE,QAAkB,CAAC;YACxD,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,EAAE,QAAkB,CAAC;YAEzD,IAAI,CAAC,UAAU,IAAI,UAAU,KAAK,GAAG;gBAAE,SAAS;YAEhD,yBAAyB;YACzB,IAAI,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC;YACtC,IAAI,IAAI,GAAG,eAAe,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;gBACtC,IAAI,IAAI,EAAE,CAAC;oBACT,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;oBACrB,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;gBACnB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,kCAAkC,IAAI,EAAE,CAAC,CAAC;YACpD,CAAC;YAED,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,mCAAmC,GAAG,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAcD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,aAAqB;IAC7D,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IACrB,MAAM,QAAQ,GAAuB,EAAE,CAAC;IAExC,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,MAAM,GAAG,CAAC,uBAAuB,CACrD,OAAO,CAAC,aAAa,CAAC,EACtB,EAAE,SAAS,EAAE,OAAO,CAAC,6CAA6C,CAAC,EAAE,EACrE,EAAE,QAAQ,EAAE,YAAY,EAAE,CAC3B,CAAC,IAAI,EAAE,CAAC;QAET,KAAK,MAAM,OAAO,IAAI,aAAa,CAAC,KAAK,EAAE,CAAC;YAC1C,MAAM,MAAM,GAAI,OAAO,CAAC,OAAO,CAAC,IAAY,CAAC,MAAM,EAAE,IAAI,CAAC;YAC1D,IAAI,CAAC,MAAM;gBAAE,SAAS;YAEtB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAc,CAAC;YACnC,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,EAAE,MAAgB,IAAI,GAAG,CAAC;YAC/D,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,EAAE,QAAkB,IAAI,CAAC,CAAC;YAC7D,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,EAAE,QAAkB,IAAI,CAAC,CAAC;YAC9D,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAEtC,IAAI,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC;YACtC,IAAI,IAAI,GAAG,eAAe,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;gBACtC,IAAI,IAAI,EAAE,CAAC;oBACT,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;oBACrB,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;gBACnB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,kCAAkC,IAAI,EAAE,CAAC,CAAC;YACpD,CAAC;YAED,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;QAC1F,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,mCAAmC,GAAG,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type TransactionSigner, type IInstruction } from '@solana/kit';
|
|
2
|
+
export declare enum ErrorClass {
|
|
3
|
+
RETRYABLE_TRANSIENT = "RETRYABLE_TRANSIENT",
|
|
4
|
+
RETRYABLE_EXPIRED = "RETRYABLE_EXPIRED",
|
|
5
|
+
RETRYABLE_STALE_QUOTE = "RETRYABLE_STALE_QUOTE",
|
|
6
|
+
TERMINAL_PROGRAM = "TERMINAL_PROGRAM",
|
|
7
|
+
TERMINAL_SIMULATION = "TERMINAL_SIMULATION",
|
|
8
|
+
TERMINAL_UNKNOWN = "TERMINAL_UNKNOWN"
|
|
9
|
+
}
|
|
10
|
+
export declare function classifyError(err: unknown): ErrorClass;
|
|
11
|
+
export interface TxLogEntry {
|
|
12
|
+
signature: string;
|
|
13
|
+
type: string;
|
|
14
|
+
walletName?: string;
|
|
15
|
+
fromMint?: string;
|
|
16
|
+
toMint?: string;
|
|
17
|
+
fromAmount?: string;
|
|
18
|
+
toAmount?: string;
|
|
19
|
+
fromPriceUsd?: number;
|
|
20
|
+
toPriceUsd?: number;
|
|
21
|
+
status: string;
|
|
22
|
+
error?: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function logTransaction(entry: TxLogEntry): void;
|
|
25
|
+
export declare function updateTransactionStatus(signature: string, status: string, error?: string): void;
|
|
26
|
+
export interface SendResult {
|
|
27
|
+
signature: string;
|
|
28
|
+
status: string;
|
|
29
|
+
attempts: number;
|
|
30
|
+
elapsed_ms: number;
|
|
31
|
+
explorerUrl: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function buildAndSendTransaction(instructions: IInstruction[], payer: TransactionSigner, opts?: {
|
|
34
|
+
maxRetries?: number;
|
|
35
|
+
skipPreflight?: boolean;
|
|
36
|
+
txType?: string;
|
|
37
|
+
walletName?: string;
|
|
38
|
+
fromMint?: string;
|
|
39
|
+
toMint?: string;
|
|
40
|
+
fromAmount?: string;
|
|
41
|
+
toAmount?: string;
|
|
42
|
+
fromPriceUsd?: number;
|
|
43
|
+
toPriceUsd?: number;
|
|
44
|
+
}): Promise<SendResult>;
|
|
45
|
+
export declare function sendEncodedTransaction(encodedTx: string, opts?: {
|
|
46
|
+
skipPreflight?: boolean;
|
|
47
|
+
txType?: string;
|
|
48
|
+
walletName?: string;
|
|
49
|
+
fromMint?: string;
|
|
50
|
+
toMint?: string;
|
|
51
|
+
fromAmount?: string;
|
|
52
|
+
toAmount?: string;
|
|
53
|
+
fromPriceUsd?: number;
|
|
54
|
+
toPriceUsd?: number;
|
|
55
|
+
}): Promise<SendResult>;
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { getSignatureFromTransaction, signTransactionMessageWithSigners, pipe, createTransactionMessage, setTransactionMessageFeePayer, setTransactionMessageLifetimeUsingBlockhash, appendTransactionMessageInstructions, } from '@solana/kit';
|
|
2
|
+
import { getBase64EncodedWireTransaction } from '@solana/transactions';
|
|
3
|
+
import { getRpc } from './rpc.js';
|
|
4
|
+
import { verbose } from '../output/formatter.js';
|
|
5
|
+
import { getDb } from '../db/database.js';
|
|
6
|
+
import { explorerUrl } from '../utils/solana.js';
|
|
7
|
+
export var ErrorClass;
|
|
8
|
+
(function (ErrorClass) {
|
|
9
|
+
ErrorClass["RETRYABLE_TRANSIENT"] = "RETRYABLE_TRANSIENT";
|
|
10
|
+
ErrorClass["RETRYABLE_EXPIRED"] = "RETRYABLE_EXPIRED";
|
|
11
|
+
ErrorClass["RETRYABLE_STALE_QUOTE"] = "RETRYABLE_STALE_QUOTE";
|
|
12
|
+
ErrorClass["TERMINAL_PROGRAM"] = "TERMINAL_PROGRAM";
|
|
13
|
+
ErrorClass["TERMINAL_SIMULATION"] = "TERMINAL_SIMULATION";
|
|
14
|
+
ErrorClass["TERMINAL_UNKNOWN"] = "TERMINAL_UNKNOWN";
|
|
15
|
+
})(ErrorClass || (ErrorClass = {}));
|
|
16
|
+
export function classifyError(err) {
|
|
17
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
18
|
+
if (msg.includes('BlockheightExceeded') || msg.includes('blockhash') || msg.includes('Blockhash not found')) {
|
|
19
|
+
return ErrorClass.RETRYABLE_EXPIRED;
|
|
20
|
+
}
|
|
21
|
+
if (msg.includes('429') || msg.includes('rate limit') || msg.includes('Too many requests')) {
|
|
22
|
+
return ErrorClass.RETRYABLE_TRANSIENT;
|
|
23
|
+
}
|
|
24
|
+
if (msg.includes('5') && (msg.includes('Internal') || msg.includes('server'))) {
|
|
25
|
+
return ErrorClass.RETRYABLE_TRANSIENT;
|
|
26
|
+
}
|
|
27
|
+
if (msg.includes('timeout') || msg.includes('ECONNRESET') || msg.includes('ENOTFOUND')) {
|
|
28
|
+
return ErrorClass.RETRYABLE_TRANSIENT;
|
|
29
|
+
}
|
|
30
|
+
if (msg.includes('-32005')) {
|
|
31
|
+
return ErrorClass.RETRYABLE_TRANSIENT;
|
|
32
|
+
}
|
|
33
|
+
if (msg.includes('insufficient') || msg.includes('Insufficient')) {
|
|
34
|
+
return ErrorClass.TERMINAL_PROGRAM;
|
|
35
|
+
}
|
|
36
|
+
if (msg.includes('simulation failed') || msg.includes('SimulationFailed')) {
|
|
37
|
+
return ErrorClass.TERMINAL_SIMULATION;
|
|
38
|
+
}
|
|
39
|
+
if (msg.includes('Program error') || msg.includes('custom program error')) {
|
|
40
|
+
return ErrorClass.TERMINAL_PROGRAM;
|
|
41
|
+
}
|
|
42
|
+
return ErrorClass.TERMINAL_UNKNOWN;
|
|
43
|
+
}
|
|
44
|
+
export function logTransaction(entry) {
|
|
45
|
+
try {
|
|
46
|
+
getDb().prepare(`
|
|
47
|
+
INSERT OR REPLACE INTO transaction_log
|
|
48
|
+
(signature, type, wallet_name, from_mint, to_mint, from_amount, to_amount, from_price_usd, to_price_usd, status, error)
|
|
49
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
50
|
+
`).run(entry.signature, entry.type, entry.walletName ?? null, entry.fromMint ?? null, entry.toMint ?? null, entry.fromAmount ?? null, entry.toAmount ?? null, entry.fromPriceUsd ?? null, entry.toPriceUsd ?? null, entry.status, entry.error ?? null);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// Non-critical — never fail a transaction because logging broke
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function updateTransactionStatus(signature, status, error) {
|
|
57
|
+
try {
|
|
58
|
+
getDb().prepare('UPDATE transaction_log SET status = ?, error = ? WHERE signature = ?').run(status, error ?? null, signature);
|
|
59
|
+
}
|
|
60
|
+
catch { /* non-critical */ }
|
|
61
|
+
}
|
|
62
|
+
export async function buildAndSendTransaction(instructions, payer, opts = {}) {
|
|
63
|
+
const rpc = getRpc();
|
|
64
|
+
const maxRetries = opts.maxRetries ?? 3;
|
|
65
|
+
const start = performance.now();
|
|
66
|
+
let attempts = 0;
|
|
67
|
+
let lastSignature;
|
|
68
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
69
|
+
attempts++;
|
|
70
|
+
try {
|
|
71
|
+
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
|
|
72
|
+
const message = pipe(createTransactionMessage({ version: 0 }), m => setTransactionMessageFeePayer(payer.address, m), m => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m), m => appendTransactionMessageInstructions(instructions, m));
|
|
73
|
+
const signedTx = await signTransactionMessageWithSigners(message);
|
|
74
|
+
const signature = getSignatureFromTransaction(signedTx);
|
|
75
|
+
lastSignature = signature;
|
|
76
|
+
const encodedTx = getBase64EncodedWireTransaction(signedTx);
|
|
77
|
+
// Log as pending before sending
|
|
78
|
+
logTransaction({
|
|
79
|
+
signature,
|
|
80
|
+
type: opts.txType ?? 'unknown',
|
|
81
|
+
walletName: opts.walletName,
|
|
82
|
+
fromMint: opts.fromMint,
|
|
83
|
+
toMint: opts.toMint,
|
|
84
|
+
fromAmount: opts.fromAmount,
|
|
85
|
+
toAmount: opts.toAmount,
|
|
86
|
+
fromPriceUsd: opts.fromPriceUsd,
|
|
87
|
+
toPriceUsd: opts.toPriceUsd,
|
|
88
|
+
status: 'sending',
|
|
89
|
+
});
|
|
90
|
+
await rpc.sendTransaction(encodedTx, {
|
|
91
|
+
skipPreflight: opts.skipPreflight ?? false,
|
|
92
|
+
encoding: 'base64',
|
|
93
|
+
}).send();
|
|
94
|
+
verbose(`Transaction sent: ${signature}, waiting for confirmation...`);
|
|
95
|
+
updateTransactionStatus(signature, 'sent');
|
|
96
|
+
// Poll for confirmation
|
|
97
|
+
await pollConfirmation(rpc, signature, 30_000);
|
|
98
|
+
const elapsed_ms = Math.round(performance.now() - start);
|
|
99
|
+
updateTransactionStatus(signature, 'confirmed');
|
|
100
|
+
return {
|
|
101
|
+
signature,
|
|
102
|
+
status: 'confirmed',
|
|
103
|
+
attempts,
|
|
104
|
+
elapsed_ms,
|
|
105
|
+
explorerUrl: explorerUrl(signature),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
const errorClass = classifyError(err);
|
|
110
|
+
verbose(`Transaction attempt ${attempt + 1} failed: ${errorClass} — ${err}`);
|
|
111
|
+
// Extract and log simulation logs from SolanaError context
|
|
112
|
+
const ctx = err?.context;
|
|
113
|
+
if (ctx?.logs?.length) {
|
|
114
|
+
verbose('Transaction logs:');
|
|
115
|
+
for (const log of ctx.logs)
|
|
116
|
+
verbose(` ${log}`);
|
|
117
|
+
}
|
|
118
|
+
if (lastSignature) {
|
|
119
|
+
updateTransactionStatus(lastSignature, 'failed', String(err));
|
|
120
|
+
}
|
|
121
|
+
if (errorClass === ErrorClass.RETRYABLE_EXPIRED || errorClass === ErrorClass.RETRYABLE_TRANSIENT) {
|
|
122
|
+
if (attempt < maxRetries - 1)
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
throw err;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
throw new Error('Max transaction retries exceeded');
|
|
129
|
+
}
|
|
130
|
+
// ── Send pre-built transaction (e.g. Jupiter swap) ─────────
|
|
131
|
+
export async function sendEncodedTransaction(encodedTx, opts = {}) {
|
|
132
|
+
const rpc = getRpc();
|
|
133
|
+
const start = performance.now();
|
|
134
|
+
// We don't know the signature until we parse or send, but Jupiter gives it back
|
|
135
|
+
// Log with a placeholder, update after
|
|
136
|
+
const signature = await rpc.sendTransaction(encodedTx, {
|
|
137
|
+
skipPreflight: opts.skipPreflight ?? false,
|
|
138
|
+
encoding: 'base64',
|
|
139
|
+
}).send();
|
|
140
|
+
const sigStr = String(signature);
|
|
141
|
+
logTransaction({
|
|
142
|
+
signature: sigStr,
|
|
143
|
+
type: opts.txType ?? 'unknown',
|
|
144
|
+
walletName: opts.walletName,
|
|
145
|
+
fromMint: opts.fromMint,
|
|
146
|
+
toMint: opts.toMint,
|
|
147
|
+
fromAmount: opts.fromAmount,
|
|
148
|
+
toAmount: opts.toAmount,
|
|
149
|
+
fromPriceUsd: opts.fromPriceUsd,
|
|
150
|
+
toPriceUsd: opts.toPriceUsd,
|
|
151
|
+
status: 'sent',
|
|
152
|
+
});
|
|
153
|
+
verbose(`Transaction sent: ${sigStr}, waiting for confirmation...`);
|
|
154
|
+
try {
|
|
155
|
+
await pollConfirmation(rpc, sigStr, 30_000);
|
|
156
|
+
updateTransactionStatus(sigStr, 'confirmed');
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
updateTransactionStatus(sigStr, 'failed', String(err));
|
|
160
|
+
throw err;
|
|
161
|
+
}
|
|
162
|
+
const elapsed_ms = Math.round(performance.now() - start);
|
|
163
|
+
return {
|
|
164
|
+
signature: sigStr,
|
|
165
|
+
status: 'confirmed',
|
|
166
|
+
attempts: 1,
|
|
167
|
+
elapsed_ms,
|
|
168
|
+
explorerUrl: explorerUrl(sigStr),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
// ── Confirmation polling ───────────────────────────────────
|
|
172
|
+
async function pollConfirmation(rpc, signature, timeoutMs) {
|
|
173
|
+
const start = Date.now();
|
|
174
|
+
while (Date.now() - start < timeoutMs) {
|
|
175
|
+
try {
|
|
176
|
+
const result = await rpc.getSignatureStatuses([signature]).send();
|
|
177
|
+
const status = result.value[0];
|
|
178
|
+
if (status) {
|
|
179
|
+
if (status.err)
|
|
180
|
+
throw new Error(`Transaction failed on-chain: ${JSON.stringify(status.err)}`);
|
|
181
|
+
if (status.confirmationStatus === 'confirmed' || status.confirmationStatus === 'finalized') {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch (err) {
|
|
187
|
+
if (err instanceof Error && err.message.includes('Transaction failed')) {
|
|
188
|
+
throw err;
|
|
189
|
+
}
|
|
190
|
+
verbose(`Polling error (will retry): ${err}`);
|
|
191
|
+
}
|
|
192
|
+
await new Promise(r => setTimeout(r, 2000));
|
|
193
|
+
}
|
|
194
|
+
throw new Error('Transaction confirmation timeout');
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=transaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../src/core/transaction.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type KeyPairSigner } from '@solana/kit';
|
|
2
|
+
export interface WalletInfo {
|
|
3
|
+
name: string;
|
|
4
|
+
address: string;
|
|
5
|
+
filePath: string;
|
|
6
|
+
labels: string[];
|
|
7
|
+
createdAt: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function createWallet(name: string): Promise<WalletInfo>;
|
|
10
|
+
export declare function createBatch(baseName: string, count: number): Promise<WalletInfo[]>;
|
|
11
|
+
export declare function importFromFile(filePath: string, name: string): Promise<WalletInfo>;
|
|
12
|
+
export declare function importFromSolanaCli(name?: string): Promise<WalletInfo>;
|
|
13
|
+
export declare function loadSigner(name: string): Promise<KeyPairSigner>;
|
|
14
|
+
export declare function resolveWalletName(nameOrAddress: string): string;
|
|
15
|
+
export declare function getDefaultWalletName(): string;
|
|
16
|
+
export declare function listWallets(label?: string): WalletInfo[];
|
|
17
|
+
export declare function removeWallet(name: string): void;
|
|
18
|
+
export declare function addLabel(name: string, label: string): void;
|
|
19
|
+
export declare function removeLabel(name: string, label: string): void;
|
|
20
|
+
export declare function getWalletFilePath(name: string): string;
|