@palmyr/cli 1.3.1 → 1.5.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 +9 -1
- package/dist/cli.js +305 -5
- package/dist/cli.js.map +1 -1
- package/dist/sdk.d.ts +9 -0
- package/dist/sdk.js +23 -0
- package/dist/sdk.js.map +1 -1
- package/dist/social-vault.d.ts +8 -0
- package/dist/social-vault.js +20 -0
- package/dist/social-vault.js.map +1 -1
- package/dist/wallet-daemon.d.ts +2 -0
- package/dist/wallet-daemon.js +5 -2
- package/dist/wallet-daemon.js.map +1 -1
- package/dist/wallet-live-test.d.ts +49 -0
- package/dist/wallet-live-test.js +162 -0
- package/dist/wallet-live-test.js.map +1 -0
- package/dist/wallet-readiness.d.ts +51 -0
- package/dist/wallet-readiness.js +183 -0
- package/dist/wallet-readiness.js.map +1 -0
- package/dist/wallet-trading.d.ts +9 -0
- package/dist/wallet-trading.js +11 -0
- package/dist/wallet-trading.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/** Liquid test tokens with tight spreads — minimises slippage on tiny trades. */
|
|
2
|
+
const TEST_MINT_SOLANA = 'JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN';
|
|
3
|
+
const TEST_MINT_BASE = '0x4200000000000000000000000000000000000006'; // WETH
|
|
4
|
+
async function timed(fn) {
|
|
5
|
+
const t0 = Date.now();
|
|
6
|
+
try {
|
|
7
|
+
const value = await fn();
|
|
8
|
+
return { ok: true, value, durationMs: Date.now() - t0 };
|
|
9
|
+
}
|
|
10
|
+
catch (e) {
|
|
11
|
+
return { ok: false, message: e?.message ?? String(e), durationMs: Date.now() - t0 };
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export async function runWalletLiveTest(opts) {
|
|
15
|
+
const startedAt = new Date().toISOString();
|
|
16
|
+
if (!(opts.budgetUsdc > 0)) {
|
|
17
|
+
throw new Error('--budget required, e.g. --budget 1usdc');
|
|
18
|
+
}
|
|
19
|
+
if (opts.budgetUsdc > 10) {
|
|
20
|
+
throw new Error(`--budget ${opts.budgetUsdc}usdc exceeds the live-test ceiling ($10). Trade manually for larger sizes.`);
|
|
21
|
+
}
|
|
22
|
+
const perLegUsdc = opts.budgetUsdc / 2;
|
|
23
|
+
const perLegAmountStr = `${perLegUsdc.toFixed(6)}usdc`;
|
|
24
|
+
const wantSolana = !opts.chain || opts.chain === 'solana' || opts.chain === 'all';
|
|
25
|
+
const wantBase = !opts.chain || opts.chain === 'base' || opts.chain === 'all';
|
|
26
|
+
const legs = [];
|
|
27
|
+
let totalRealizedUsdc = 0;
|
|
28
|
+
const { resolveWalletAddresses, buy, sell, buyBase, sellBase, listPositions } = await import('./wallet-trading.js');
|
|
29
|
+
const addrs = await resolveWalletAddresses(opts.walletRef, opts.passphrase);
|
|
30
|
+
// Solana round trip
|
|
31
|
+
if (wantSolana && addrs.solanaAddress) {
|
|
32
|
+
const solBuy = await timed(() => buy({
|
|
33
|
+
ca: TEST_MINT_SOLANA,
|
|
34
|
+
amount: perLegAmountStr,
|
|
35
|
+
thesis: 'live-test round trip',
|
|
36
|
+
walletRef: opts.walletRef,
|
|
37
|
+
passphrase: opts.passphrase,
|
|
38
|
+
}));
|
|
39
|
+
if (!solBuy.ok) {
|
|
40
|
+
legs.push({ name: 'solana-buy', chain: 'solana', step: 'buy', status: 'fail', message: solBuy.message, durationMs: solBuy.durationMs });
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
legs.push({
|
|
44
|
+
name: 'solana-buy',
|
|
45
|
+
chain: 'solana',
|
|
46
|
+
step: 'buy',
|
|
47
|
+
status: 'pass',
|
|
48
|
+
txHash: solBuy.value.txSignature,
|
|
49
|
+
amountIn: solBuy.value.amountIn,
|
|
50
|
+
durationMs: solBuy.durationMs,
|
|
51
|
+
});
|
|
52
|
+
const solSell = await timed(() => sell({
|
|
53
|
+
ca: TEST_MINT_SOLANA,
|
|
54
|
+
percent: 100,
|
|
55
|
+
reason: 'live-test close',
|
|
56
|
+
walletRef: opts.walletRef,
|
|
57
|
+
passphrase: opts.passphrase,
|
|
58
|
+
}));
|
|
59
|
+
if (!solSell.ok) {
|
|
60
|
+
legs.push({ name: 'solana-sell', chain: 'solana', step: 'sell', status: 'fail', message: solSell.message, durationMs: solSell.durationMs });
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
legs.push({
|
|
64
|
+
name: 'solana-sell',
|
|
65
|
+
chain: 'solana',
|
|
66
|
+
step: 'sell',
|
|
67
|
+
status: 'pass',
|
|
68
|
+
txHash: solSell.value.txSignature,
|
|
69
|
+
output: solSell.value.output,
|
|
70
|
+
realized: solSell.value.realized,
|
|
71
|
+
durationMs: solSell.durationMs,
|
|
72
|
+
});
|
|
73
|
+
if (solSell.value.realized.asset === 'USDC') {
|
|
74
|
+
totalRealizedUsdc += solSell.value.realized.amount;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (wantSolana) {
|
|
80
|
+
legs.push({ name: 'solana-buy', chain: 'solana', step: 'buy', status: 'skip', message: 'no Solana address' });
|
|
81
|
+
}
|
|
82
|
+
// Base round trip
|
|
83
|
+
if (wantBase && addrs.evmAddress) {
|
|
84
|
+
const baseBuy = await timed(() => buyBase({
|
|
85
|
+
ca: TEST_MINT_BASE,
|
|
86
|
+
amount: perLegAmountStr,
|
|
87
|
+
thesis: 'live-test round trip',
|
|
88
|
+
walletRef: opts.walletRef,
|
|
89
|
+
passphrase: opts.passphrase,
|
|
90
|
+
}));
|
|
91
|
+
if (!baseBuy.ok) {
|
|
92
|
+
legs.push({ name: 'base-buy', chain: 'base', step: 'buy', status: 'fail', message: baseBuy.message, durationMs: baseBuy.durationMs });
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
legs.push({
|
|
96
|
+
name: 'base-buy',
|
|
97
|
+
chain: 'base',
|
|
98
|
+
step: 'buy',
|
|
99
|
+
status: 'pass',
|
|
100
|
+
txHash: baseBuy.value.txHash,
|
|
101
|
+
amountIn: baseBuy.value.amountIn,
|
|
102
|
+
durationMs: baseBuy.durationMs,
|
|
103
|
+
});
|
|
104
|
+
const baseSell = await timed(() => sellBase({
|
|
105
|
+
ca: TEST_MINT_BASE,
|
|
106
|
+
percent: 100,
|
|
107
|
+
reason: 'live-test close',
|
|
108
|
+
walletRef: opts.walletRef,
|
|
109
|
+
passphrase: opts.passphrase,
|
|
110
|
+
}));
|
|
111
|
+
if (!baseSell.ok) {
|
|
112
|
+
legs.push({ name: 'base-sell', chain: 'base', step: 'sell', status: 'fail', message: baseSell.message, durationMs: baseSell.durationMs });
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
legs.push({
|
|
116
|
+
name: 'base-sell',
|
|
117
|
+
chain: 'base',
|
|
118
|
+
step: 'sell',
|
|
119
|
+
status: 'pass',
|
|
120
|
+
txHash: baseSell.value.txHash,
|
|
121
|
+
output: baseSell.value.output,
|
|
122
|
+
realized: baseSell.value.realized,
|
|
123
|
+
durationMs: baseSell.durationMs,
|
|
124
|
+
});
|
|
125
|
+
if (baseSell.value.realized.asset === 'USDC') {
|
|
126
|
+
totalRealizedUsdc += baseSell.value.realized.amount;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else if (wantBase) {
|
|
132
|
+
legs.push({ name: 'base-buy', chain: 'base', step: 'buy', status: 'skip', message: 'no EVM address' });
|
|
133
|
+
}
|
|
134
|
+
// Verify no positions left open for this wallet.
|
|
135
|
+
const walletAddrs = [addrs.solanaAddress, addrs.evmAddress].filter((x) => !!x);
|
|
136
|
+
const remaining = walletAddrs.length > 0
|
|
137
|
+
? listPositions({ walletAddress: walletAddrs, includeClosed: false })
|
|
138
|
+
: [];
|
|
139
|
+
legs.push({
|
|
140
|
+
name: 'verify-no-open-positions',
|
|
141
|
+
chain: remaining[0]?.chain ?? 'solana',
|
|
142
|
+
step: 'verify',
|
|
143
|
+
status: remaining.length === 0 ? 'pass' : 'fail',
|
|
144
|
+
message: remaining.length === 0
|
|
145
|
+
? undefined
|
|
146
|
+
: `${remaining.length} position(s) still open after live-test: ${remaining.map((p) => `${p.chain}:${p.mint}`).join(', ')}`,
|
|
147
|
+
});
|
|
148
|
+
const anyFail = legs.some((l) => l.status === 'fail');
|
|
149
|
+
const safeForAutonomousTrading = !anyFail && Math.abs(totalRealizedUsdc) <= opts.budgetUsdc;
|
|
150
|
+
return {
|
|
151
|
+
wallet: opts.walletRef,
|
|
152
|
+
startedAt,
|
|
153
|
+
finishedAt: new Date().toISOString(),
|
|
154
|
+
budgetUsdc: opts.budgetUsdc,
|
|
155
|
+
perLegUsdc,
|
|
156
|
+
legs,
|
|
157
|
+
totalRealizedUsdc,
|
|
158
|
+
safeForAutonomousTrading,
|
|
159
|
+
openPositionsAfter: remaining.length,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=wallet-live-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet-live-test.js","sourceRoot":"","sources":["../wallet-live-test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export interface ReadinessCheck {
|
|
2
|
+
name: string;
|
|
3
|
+
status: 'pass' | 'warn' | 'fail' | 'skip';
|
|
4
|
+
value?: string | number | boolean;
|
|
5
|
+
message?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ReadinessReport {
|
|
8
|
+
wallet: string;
|
|
9
|
+
solanaAddress: string | null;
|
|
10
|
+
evmAddress: string | null;
|
|
11
|
+
/** Aggregate verdict — true only when every required check is `pass`. */
|
|
12
|
+
safeForAutonomousTrading: boolean;
|
|
13
|
+
checks: ReadinessCheck[];
|
|
14
|
+
/** Open position count by chain, plus total. */
|
|
15
|
+
openPositions: {
|
|
16
|
+
solana: number;
|
|
17
|
+
base: number;
|
|
18
|
+
total: number;
|
|
19
|
+
};
|
|
20
|
+
/** Native-asset balances on each chain (display + raw). */
|
|
21
|
+
balances: {
|
|
22
|
+
solana: {
|
|
23
|
+
lamports: number;
|
|
24
|
+
sol: number;
|
|
25
|
+
} | null;
|
|
26
|
+
base: {
|
|
27
|
+
wei: string;
|
|
28
|
+
eth: number;
|
|
29
|
+
} | null;
|
|
30
|
+
};
|
|
31
|
+
/** Daemon process state — running flag + pid if any. */
|
|
32
|
+
daemon: {
|
|
33
|
+
running: boolean;
|
|
34
|
+
pid: number | null;
|
|
35
|
+
lastTick: string | null;
|
|
36
|
+
autoExecute: boolean | null;
|
|
37
|
+
walletRef: string | null;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export interface ReadinessOpts {
|
|
41
|
+
walletRef: string;
|
|
42
|
+
passphrase?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Minimum native balance (lamports / wei) required to count as "has gas".
|
|
45
|
+
* Defaults are intentionally low — the goal is "can sign + send", not "well
|
|
46
|
+
* funded". Callers tuning for big trades should pass explicit thresholds.
|
|
47
|
+
*/
|
|
48
|
+
minSolLamports?: number;
|
|
49
|
+
minEthWei?: bigint;
|
|
50
|
+
}
|
|
51
|
+
export declare function runWalletReadiness(opts: ReadinessOpts): Promise<ReadinessReport>;
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
const DEFAULT_MIN_SOL_LAMPORTS = 1_000_000; // 0.001 SOL — covers fees + a few tx
|
|
2
|
+
const DEFAULT_MIN_ETH_WEI = 100000000000000n; // 0.0001 ETH
|
|
3
|
+
export async function runWalletReadiness(opts) {
|
|
4
|
+
const checks = [];
|
|
5
|
+
const minSol = opts.minSolLamports ?? DEFAULT_MIN_SOL_LAMPORTS;
|
|
6
|
+
const minEth = opts.minEthWei ?? DEFAULT_MIN_ETH_WEI;
|
|
7
|
+
// Resolve addresses for both chains.
|
|
8
|
+
let solanaAddress = null;
|
|
9
|
+
let evmAddress = null;
|
|
10
|
+
try {
|
|
11
|
+
const { resolveWalletAddresses } = await import('./wallet-trading.js');
|
|
12
|
+
const addrs = await resolveWalletAddresses(opts.walletRef, opts.passphrase);
|
|
13
|
+
solanaAddress = addrs.solanaAddress;
|
|
14
|
+
evmAddress = addrs.evmAddress;
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
checks.push({ name: 'walletResolution', status: 'fail', message: e?.message ?? 'failed' });
|
|
18
|
+
}
|
|
19
|
+
checks.push({ name: 'canSignSolana', status: solanaAddress ? 'pass' : 'fail', value: solanaAddress ?? false });
|
|
20
|
+
checks.push({ name: 'canSignBase', status: evmAddress ? 'pass' : 'fail', value: evmAddress ?? false });
|
|
21
|
+
// Native balance checks — done in parallel with quote checks below.
|
|
22
|
+
const balanceTasks = [];
|
|
23
|
+
let solBalance = null;
|
|
24
|
+
let baseBalance = null;
|
|
25
|
+
if (solanaAddress) {
|
|
26
|
+
balanceTasks.push((async () => {
|
|
27
|
+
try {
|
|
28
|
+
const { PublicKey } = await import('@solana/web3.js');
|
|
29
|
+
const { makeConnection } = await import('./solana/index.js');
|
|
30
|
+
const conn = makeConnection();
|
|
31
|
+
const lamports = await conn.getBalance(new PublicKey(solanaAddress));
|
|
32
|
+
solBalance = { lamports, sol: lamports / 1e9 };
|
|
33
|
+
const hasGas = lamports >= minSol;
|
|
34
|
+
checks.push({
|
|
35
|
+
name: 'solanaHasGas',
|
|
36
|
+
status: hasGas ? 'pass' : 'fail',
|
|
37
|
+
value: `${(lamports / 1e9).toFixed(6)} SOL`,
|
|
38
|
+
message: hasGas ? undefined : `< ${(minSol / 1e9).toFixed(6)} SOL min for tx fees`,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
checks.push({ name: 'solanaHasGas', status: 'fail', message: e?.message ?? 'balance check failed' });
|
|
43
|
+
}
|
|
44
|
+
})());
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
checks.push({ name: 'solanaHasGas', status: 'skip', message: 'no Solana address' });
|
|
48
|
+
}
|
|
49
|
+
if (evmAddress) {
|
|
50
|
+
balanceTasks.push((async () => {
|
|
51
|
+
try {
|
|
52
|
+
const { getErc20Balance, makeEvmProvider, NATIVE_ETH } = await import('./evm-trading.js');
|
|
53
|
+
const wei = await getErc20Balance(makeEvmProvider(), NATIVE_ETH, evmAddress);
|
|
54
|
+
const ethValue = Number(wei) / 1e18;
|
|
55
|
+
baseBalance = { wei: wei.toString(), eth: ethValue };
|
|
56
|
+
const hasGas = wei >= minEth;
|
|
57
|
+
checks.push({
|
|
58
|
+
name: 'baseHasGas',
|
|
59
|
+
status: hasGas ? 'pass' : 'fail',
|
|
60
|
+
value: `${ethValue.toFixed(8)} ETH`,
|
|
61
|
+
message: hasGas ? undefined : `< ${(Number(minEth) / 1e18).toFixed(8)} ETH min for gas`,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
checks.push({ name: 'baseHasGas', status: 'fail', message: e?.message ?? 'balance check failed' });
|
|
66
|
+
}
|
|
67
|
+
})());
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
checks.push({ name: 'baseHasGas', status: 'skip', message: 'no EVM address' });
|
|
71
|
+
}
|
|
72
|
+
// Quote checks in parallel — trivial amounts, no signing.
|
|
73
|
+
const quoteTasks = [];
|
|
74
|
+
quoteTasks.push((async () => {
|
|
75
|
+
if (!solanaAddress) {
|
|
76
|
+
checks.push({ name: 'canQuoteSolana', status: 'skip', message: 'no Solana address' });
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
const { fetchQuote, SOL_MINT } = await import('./solana/index.js');
|
|
81
|
+
const { USDC_MINT_SOLANA } = await import('./wallet-trading.js');
|
|
82
|
+
await fetchQuote({
|
|
83
|
+
inputMint: SOL_MINT.toBase58(),
|
|
84
|
+
outputMint: USDC_MINT_SOLANA,
|
|
85
|
+
amount: 1_000_000,
|
|
86
|
+
slippageBps: 50,
|
|
87
|
+
});
|
|
88
|
+
checks.push({ name: 'canQuoteSolana', status: 'pass' });
|
|
89
|
+
}
|
|
90
|
+
catch (e) {
|
|
91
|
+
checks.push({ name: 'canQuoteSolana', status: 'fail', message: e?.message ?? 'quote failed' });
|
|
92
|
+
}
|
|
93
|
+
})());
|
|
94
|
+
quoteTasks.push((async () => {
|
|
95
|
+
if (!evmAddress) {
|
|
96
|
+
checks.push({ name: 'canQuoteBase', status: 'skip', message: 'no EVM address' });
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
const { fetchParaswapPrice, NATIVE_ETH, BASE_USDC, BASE_CHAIN_ID } = await import('./evm-trading.js');
|
|
101
|
+
await fetchParaswapPrice({
|
|
102
|
+
srcToken: NATIVE_ETH,
|
|
103
|
+
destToken: BASE_USDC,
|
|
104
|
+
amount: '100000000000000',
|
|
105
|
+
srcDecimals: 18,
|
|
106
|
+
destDecimals: 6,
|
|
107
|
+
network: BASE_CHAIN_ID,
|
|
108
|
+
});
|
|
109
|
+
checks.push({ name: 'canQuoteBase', status: 'pass' });
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
checks.push({ name: 'canQuoteBase', status: 'fail', message: e?.message ?? 'quote failed' });
|
|
113
|
+
}
|
|
114
|
+
})());
|
|
115
|
+
await Promise.all([...balanceTasks, ...quoteTasks]);
|
|
116
|
+
// Daemon status.
|
|
117
|
+
let daemonRunning = false;
|
|
118
|
+
let daemonPid = null;
|
|
119
|
+
let daemonLastTick = null;
|
|
120
|
+
let daemonAuto = null;
|
|
121
|
+
let daemonWalletRef = null;
|
|
122
|
+
try {
|
|
123
|
+
const { getDaemonStatus } = await import('./wallet-daemon.js');
|
|
124
|
+
const status = getDaemonStatus();
|
|
125
|
+
daemonRunning = status.running;
|
|
126
|
+
daemonPid = status.pid;
|
|
127
|
+
daemonLastTick = status.lastTick;
|
|
128
|
+
daemonAuto = status.opts?.autoExecute ?? null;
|
|
129
|
+
daemonWalletRef = status.opts?.walletRef ?? null;
|
|
130
|
+
}
|
|
131
|
+
catch { }
|
|
132
|
+
checks.push({
|
|
133
|
+
name: 'daemonRunning',
|
|
134
|
+
status: daemonRunning ? 'pass' : 'warn',
|
|
135
|
+
value: daemonRunning,
|
|
136
|
+
message: daemonRunning ? undefined : 'daemon not running — run `palmyr wallet daemon start --auto --wallet <ref>` for autonomous monitoring',
|
|
137
|
+
});
|
|
138
|
+
// Open position counts. Cross-chain by default.
|
|
139
|
+
let openSolana = 0;
|
|
140
|
+
let openBase = 0;
|
|
141
|
+
try {
|
|
142
|
+
const { listPositions } = await import('./wallet-trading.js');
|
|
143
|
+
const addrs = [solanaAddress, evmAddress].filter((x) => !!x);
|
|
144
|
+
if (addrs.length > 0) {
|
|
145
|
+
const positions = listPositions({ walletAddress: addrs, includeClosed: false });
|
|
146
|
+
openSolana = positions.filter((p) => p.chain === 'solana').length;
|
|
147
|
+
openBase = positions.filter((p) => p.chain === 'base').length;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch { }
|
|
151
|
+
checks.push({
|
|
152
|
+
name: 'openPositions',
|
|
153
|
+
status: 'pass',
|
|
154
|
+
value: openSolana + openBase,
|
|
155
|
+
message: `solana=${openSolana} base=${openBase}`,
|
|
156
|
+
});
|
|
157
|
+
const requiredChecks = ['canSignSolana', 'canSignBase', 'solanaHasGas', 'baseHasGas', 'canQuoteSolana', 'canQuoteBase'];
|
|
158
|
+
const safeForAutonomousTrading = !checks.some((c) => requiredChecks.includes(c.name) && c.status === 'fail');
|
|
159
|
+
return {
|
|
160
|
+
wallet: opts.walletRef,
|
|
161
|
+
solanaAddress,
|
|
162
|
+
evmAddress,
|
|
163
|
+
safeForAutonomousTrading,
|
|
164
|
+
checks,
|
|
165
|
+
openPositions: {
|
|
166
|
+
solana: openSolana,
|
|
167
|
+
base: openBase,
|
|
168
|
+
total: openSolana + openBase,
|
|
169
|
+
},
|
|
170
|
+
balances: {
|
|
171
|
+
solana: solBalance,
|
|
172
|
+
base: baseBalance,
|
|
173
|
+
},
|
|
174
|
+
daemon: {
|
|
175
|
+
running: daemonRunning,
|
|
176
|
+
pid: daemonPid,
|
|
177
|
+
lastTick: daemonLastTick,
|
|
178
|
+
autoExecute: daemonAuto,
|
|
179
|
+
walletRef: daemonWalletRef,
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=wallet-readiness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet-readiness.js","sourceRoot":"","sources":["../wallet-readiness.ts"],"names":[],"mappings":"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"}
|
package/dist/wallet-trading.d.ts
CHANGED
|
@@ -275,6 +275,7 @@ export type TradeLogLine = {
|
|
|
275
275
|
currentPct: number;
|
|
276
276
|
thresholdPct?: number;
|
|
277
277
|
peakPct?: number;
|
|
278
|
+
drawdownPct?: number;
|
|
278
279
|
thresholdDurationMs?: number;
|
|
279
280
|
elapsedMs?: number;
|
|
280
281
|
llmVerdict?: 'yes' | 'no' | 'unclear';
|
|
@@ -488,6 +489,8 @@ export interface BuyBaseResult {
|
|
|
488
489
|
protectedExec: boolean;
|
|
489
490
|
rpcUrl: string;
|
|
490
491
|
inputAsset: BaseInputAsset;
|
|
492
|
+
/** One-line human-readable summary; safe to print directly. */
|
|
493
|
+
summary: string;
|
|
491
494
|
}
|
|
492
495
|
export declare function buyBase(opts: BuyBaseOpts): Promise<BuyBaseResult>;
|
|
493
496
|
export interface SellBaseOpts {
|
|
@@ -530,6 +533,8 @@ export interface SellBaseResult {
|
|
|
530
533
|
output: AssetAmount;
|
|
531
534
|
/** Canonical, asset-tagged realized PnL for this sell. */
|
|
532
535
|
realized: AssetPnl;
|
|
536
|
+
/** One-line human-readable summary; safe to print directly. */
|
|
537
|
+
summary: string;
|
|
533
538
|
}
|
|
534
539
|
export declare function sellBase(opts: SellBaseOpts): Promise<SellBaseResult>;
|
|
535
540
|
export interface SyncBaseOpts {
|
|
@@ -594,6 +599,8 @@ export interface BuyResult {
|
|
|
594
599
|
protectedExec: boolean;
|
|
595
600
|
forensics?: FillForensics;
|
|
596
601
|
inputAsset: SolanaInputAsset;
|
|
602
|
+
/** One-line human-readable summary; safe to print directly. */
|
|
603
|
+
summary: string;
|
|
597
604
|
}
|
|
598
605
|
export declare function buy(opts: BuyOpts): Promise<BuyResult>;
|
|
599
606
|
export interface SellOpts {
|
|
@@ -630,6 +637,8 @@ export interface SellResult {
|
|
|
630
637
|
output: AssetAmount;
|
|
631
638
|
/** Canonical, asset-tagged realized PnL for this sell. */
|
|
632
639
|
realized: AssetPnl;
|
|
640
|
+
/** One-line human-readable summary; safe to print directly. */
|
|
641
|
+
summary: string;
|
|
633
642
|
}
|
|
634
643
|
export declare function sell(opts: SellOpts): Promise<SellResult>;
|
|
635
644
|
export interface SyncOpts {
|
package/dist/wallet-trading.js
CHANGED
|
@@ -884,6 +884,7 @@ export async function buyBase(opts) {
|
|
|
884
884
|
// Dry-run must be strictly read-only: simulated trades never touch live state.
|
|
885
885
|
if (!opts.dryRun)
|
|
886
886
|
writePosition(position);
|
|
887
|
+
const summary = `${opts.dryRun ? '[dry-run] ' : ''}Bought ${tokensOut} ${opts.ca} for ${position.entry.amountIn} on Base.`;
|
|
887
888
|
return {
|
|
888
889
|
positionPath: opts.dryRun
|
|
889
890
|
? `simulated:${opts.ca}`
|
|
@@ -903,6 +904,7 @@ export async function buyBase(opts) {
|
|
|
903
904
|
protectedExec: !!opts.protectedExec,
|
|
904
905
|
rpcUrl,
|
|
905
906
|
inputAsset,
|
|
907
|
+
summary,
|
|
906
908
|
};
|
|
907
909
|
}
|
|
908
910
|
export async function sellBase(opts) {
|
|
@@ -1065,6 +1067,9 @@ export async function sellBase(opts) {
|
|
|
1065
1067
|
// position file (otherwise a simulation can "close" a real position).
|
|
1066
1068
|
if (!opts.dryRun)
|
|
1067
1069
|
writePosition(position);
|
|
1070
|
+
const realizedSign = realizedAmount >= 0 ? '+' : '';
|
|
1071
|
+
const realizedDigits = outputAsset === 'USDC' ? 6 : 8;
|
|
1072
|
+
const summary = `${opts.dryRun ? '[dry-run] ' : ''}Sold ${tokensInDisplay} ${opts.ca} for ${outDisplay}; realized ${realizedSign}${realizedAmount.toFixed(realizedDigits)} ${outputAsset}; position ${position.status}.`;
|
|
1068
1073
|
return {
|
|
1069
1074
|
positionPath: opts.dryRun
|
|
1070
1075
|
? `simulated:${opts.ca}`
|
|
@@ -1085,6 +1090,7 @@ export async function sellBase(opts) {
|
|
|
1085
1090
|
reconcileDriftRaw: reconcileDriftRaw === 0n ? undefined : reconcileDriftRaw.toString(),
|
|
1086
1091
|
output: { asset: outputAsset, raw: outRaw, display: outDisplay },
|
|
1087
1092
|
realized: { asset: outputAsset, amount: realizedAmount },
|
|
1093
|
+
summary,
|
|
1088
1094
|
};
|
|
1089
1095
|
}
|
|
1090
1096
|
export async function syncBase(opts = {}) {
|
|
@@ -1358,6 +1364,7 @@ export async function buy(opts) {
|
|
|
1358
1364
|
protectedExec: !!opts.protectedExec,
|
|
1359
1365
|
forensics,
|
|
1360
1366
|
inputAsset,
|
|
1367
|
+
summary: `${opts.dryRun ? '[dry-run] ' : ''}Bought ${tokensOut} ${opts.ca} for ${position.entry.amountIn} on Solana.`,
|
|
1361
1368
|
};
|
|
1362
1369
|
}
|
|
1363
1370
|
export async function sell(opts) {
|
|
@@ -1511,6 +1518,9 @@ export async function sell(opts) {
|
|
|
1511
1518
|
forensics,
|
|
1512
1519
|
});
|
|
1513
1520
|
}
|
|
1521
|
+
const sign = realizedSol >= 0 ? '+' : '';
|
|
1522
|
+
const digits = outputAsset === 'USDC' ? 6 : 8;
|
|
1523
|
+
const summary = `${opts.dryRun ? '[dry-run] ' : ''}Sold ${tokensInDisplay} ${opts.ca} for ${solOutDisplay}; realized ${sign}${realizedSol.toFixed(digits)} ${outputAsset}; position ${position.status}.`;
|
|
1514
1524
|
return {
|
|
1515
1525
|
positionPath: opts.dryRun
|
|
1516
1526
|
? `simulated:${opts.ca}`
|
|
@@ -1531,6 +1541,7 @@ export async function sell(opts) {
|
|
|
1531
1541
|
outputAsset,
|
|
1532
1542
|
output: { asset: outputAsset, raw: String(solOutRaw), display: solOutDisplay },
|
|
1533
1543
|
realized: { asset: outputAsset, amount: realizedSol },
|
|
1544
|
+
summary,
|
|
1534
1545
|
};
|
|
1535
1546
|
}
|
|
1536
1547
|
export async function sync(opts = {}) {
|