@solard/cli 0.2.15 → 0.2.16
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/package.json +2 -2
- package/src/fairfun-commands.ts +32 -4
- package/src/index.ts +55 -8
- package/src/vault-onboarding.ts +5 -22
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solard/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.16",
|
|
4
4
|
"description": "Command-line interface for the Solard SDK.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"bun": ">=1.1.0"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@solard/sdk": "0.2.
|
|
21
|
+
"@solard/sdk": "0.2.16",
|
|
22
22
|
"bs58": "^6.0.0",
|
|
23
23
|
"@solana/web3.js": "^1.98.4"
|
|
24
24
|
},
|
package/src/fairfun-commands.ts
CHANGED
|
@@ -216,18 +216,41 @@ export async function handleFairfunCommand(args: {
|
|
|
216
216
|
const ref = values[0];
|
|
217
217
|
if (!ref)
|
|
218
218
|
throw new Error(
|
|
219
|
-
"Usage: slrd events <token|ca> [--swaps-only|--transfers-only] [--jsonl]",
|
|
219
|
+
"Usage: slrd events <token|ca> [--all|--swaps|--transfers|--creates|--swaps-only|--transfers-only] [--jsonl]",
|
|
220
220
|
);
|
|
221
221
|
const token = await ensureToken(slrd, ref);
|
|
222
222
|
const controller = new AbortController();
|
|
223
223
|
const stop = () => controller.abort();
|
|
224
224
|
process.once("SIGINT", stop);
|
|
225
225
|
process.once("SIGTERM", stop);
|
|
226
|
-
|
|
227
|
-
const
|
|
226
|
+
|
|
227
|
+
const explicit =
|
|
228
|
+
bool(flags, "all") ||
|
|
229
|
+
bool(flags, "swaps") ||
|
|
230
|
+
bool(flags, "transfers") ||
|
|
231
|
+
bool(flags, "creates");
|
|
232
|
+
let swaps = true;
|
|
233
|
+
let transfers = true;
|
|
234
|
+
let creates = false;
|
|
235
|
+
if (bool(flags, "swaps-only")) {
|
|
236
|
+
swaps = true;
|
|
237
|
+
transfers = false;
|
|
238
|
+
creates = false;
|
|
239
|
+
} else if (bool(flags, "transfers-only")) {
|
|
240
|
+
swaps = false;
|
|
241
|
+
transfers = true;
|
|
242
|
+
creates = false;
|
|
243
|
+
} else if (explicit) {
|
|
244
|
+
const all = bool(flags, "all");
|
|
245
|
+
swaps = all || bool(flags, "swaps");
|
|
246
|
+
transfers = all || bool(flags, "transfers");
|
|
247
|
+
creates = all || bool(flags, "creates");
|
|
248
|
+
}
|
|
249
|
+
|
|
228
250
|
const subscription = await slrd.subscribeTokenEvents(token.mint, {
|
|
229
251
|
swaps,
|
|
230
252
|
transfers,
|
|
253
|
+
creates,
|
|
231
254
|
commitment: bool(flags, "finalized") ? "finalized" : "confirmed",
|
|
232
255
|
signal: controller.signal,
|
|
233
256
|
});
|
|
@@ -251,7 +274,12 @@ export async function handleFairfunCommand(args: {
|
|
|
251
274
|
if (event.type === "swap") {
|
|
252
275
|
emit(
|
|
253
276
|
`${new Date(event.blockTimeMs ?? event.observedAtMs).toISOString()} SWAP ${event.venue} ${event.side.toUpperCase()} ` +
|
|
254
|
-
`${event.tokenAmountRaw} tokenRaw trader=${event.trader ?? "?"} sig=${event.signature}\n`,
|
|
277
|
+
`${event.tokenAmountRaw} tokenRaw quote=${event.quoteAmountRaw ?? "?"} ${event.quoteMint} trader=${event.trader ?? "?"} sig=${event.signature}\n`,
|
|
278
|
+
);
|
|
279
|
+
} else if (event.type === "create") {
|
|
280
|
+
emit(
|
|
281
|
+
`${new Date(event.blockTimeMs ?? event.observedAtMs).toISOString()} CREATE ` +
|
|
282
|
+
`${event.symbol ?? "?"} ${event.name ?? "?"} creator=${event.creator ?? "?"} quote=${event.quoteMint} sig=${event.signature}\n`,
|
|
255
283
|
);
|
|
256
284
|
} else {
|
|
257
285
|
emit(
|
package/src/index.ts
CHANGED
|
@@ -322,7 +322,7 @@ async function storedWalletCount(): Promise<number> {
|
|
|
322
322
|
const { createTraderSolard } = await import("@solard/sdk");
|
|
323
323
|
const probe = createTraderSolard();
|
|
324
324
|
try {
|
|
325
|
-
return probe.wallets.
|
|
325
|
+
return (probe.db.wallets.select().all() as unknown[]).length;
|
|
326
326
|
} finally {
|
|
327
327
|
probe.close();
|
|
328
328
|
}
|
|
@@ -333,7 +333,7 @@ function help(): string {
|
|
|
333
333
|
|
|
334
334
|
Wallets and tokens
|
|
335
335
|
slrd setup [--status] Check ephemeral wallet-password mode; no password is persisted
|
|
336
|
-
slrd wallet create [name]
|
|
336
|
+
slrd wallet create [name] [--vanity <suffix>] Generate and persist an encrypted Solana wallet
|
|
337
337
|
slrd import <private_key> [name]
|
|
338
338
|
cat key.json | slrd import --stdin [name]
|
|
339
339
|
|
|
@@ -356,7 +356,7 @@ External contacts (public addresses only; never signing wallets or group members
|
|
|
356
356
|
slrd token analyze <ca> [--top N] [--json]
|
|
357
357
|
slrd tokens
|
|
358
358
|
slrd holders <token|ca> [--exclude <a,b>] [--min-raw N] [--json] Complete on-chain holder snapshot
|
|
359
|
-
slrd events <token|ca> [--swaps
|
|
359
|
+
slrd events <token|ca> [--all|--swaps|--transfers|--creates] [--jsonl] Live typed Pump/PumpSwap + transfer/create stream
|
|
360
360
|
|
|
361
361
|
Vanity mints
|
|
362
362
|
slrd vanity --suffix pump --out .\\mint.json [--count <n>]
|
|
@@ -365,6 +365,9 @@ Vanity mints
|
|
|
365
365
|
slrd vanity pool release <mint-address> Release an ambiguous/failed launch reservation
|
|
366
366
|
launch/vamp: add --mint-pool pump [--mint-pool-address <address>] to consume a pooled mint
|
|
367
367
|
|
|
368
|
+
Pump pairs
|
|
369
|
+
slrd pump pairs [--json] Read Pump-supported quote mints from the on-chain Global account
|
|
370
|
+
|
|
368
371
|
Metadata and launching
|
|
369
372
|
slrd launch pump --creator <wallet> (--uri <metadata_uri> | --metadata <json> | --image <path> --description <text>) [--pair SOL|USDC|<custom-quote-mint>] [--beneficiary <wallet|address>] [--alias <name>] [--live] [--skip-simulation]
|
|
370
373
|
[--deployment-sender helius-rpc|helius-fast] [--helius-tip-sol 0.01]
|
|
@@ -559,7 +562,7 @@ async function main() {
|
|
|
559
562
|
return;
|
|
560
563
|
}
|
|
561
564
|
|
|
562
|
-
if (needsVault
|
|
565
|
+
if (needsVault) {
|
|
563
566
|
const allowCreate =
|
|
564
567
|
(command === "wallet" && values[0] === "create") ||
|
|
565
568
|
command === "import" ||
|
|
@@ -860,6 +863,20 @@ async function main() {
|
|
|
860
863
|
return;
|
|
861
864
|
}
|
|
862
865
|
|
|
866
|
+
if (command === "pump" && values[0] === "pairs") {
|
|
867
|
+
const pairs = await slrd.pump.getSupportedPairs();
|
|
868
|
+
if (flags.has("json")) {
|
|
869
|
+
emit(json(pairs) + "\n");
|
|
870
|
+
} else {
|
|
871
|
+
for (const pair of pairs) {
|
|
872
|
+
emit(
|
|
873
|
+
`${(pair.symbol ?? "?").padEnd(12)} ${(pair.name ?? "?").padEnd(28)} ${pair.mint} decimals=${pair.decimals}\n`,
|
|
874
|
+
);
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
|
|
863
880
|
if (command === "swap") {
|
|
864
881
|
const { runJupiterSwapCommand } =
|
|
865
882
|
await import("./commands/jupiter-swap.ts");
|
|
@@ -929,16 +946,46 @@ async function main() {
|
|
|
929
946
|
|
|
930
947
|
if (command === "wallet" && values[0] === "create") {
|
|
931
948
|
const firstWallet = slrd.wallets.list().length === 0;
|
|
932
|
-
const
|
|
933
|
-
|
|
934
|
-
|
|
949
|
+
const name = values[1] ?? (firstWallet ? "main" : undefined);
|
|
950
|
+
const vanity = flags.has("vanity") ? need(flags, "vanity") : null;
|
|
951
|
+
const vanityResult = vanity
|
|
952
|
+
? await slrd.createVanityWallet(name, {
|
|
953
|
+
suffix: vanity,
|
|
954
|
+
workers: int(flags, "workers"),
|
|
955
|
+
maxAttempts: int(flags, "max-attempts"),
|
|
956
|
+
timeoutMs: int(flags, "timeout-ms", 0),
|
|
957
|
+
reportEvery: int(flags, "report-every", 1_000_000),
|
|
958
|
+
onProgress: process.stderr.isTTY
|
|
959
|
+
? (progress) =>
|
|
960
|
+
process.stderr.write(
|
|
961
|
+
`${OWL} wallet vanity ${progress.suffix}: ${progress.attempts} attempts, ${progress.ratePerSecond}/s\r`,
|
|
962
|
+
)
|
|
963
|
+
: undefined,
|
|
964
|
+
})
|
|
965
|
+
: null;
|
|
966
|
+
if (vanityResult && process.stderr.isTTY) process.stderr.write("\n");
|
|
967
|
+
const wallet = vanityResult?.wallet ?? slrd.createWallet(name);
|
|
968
|
+
const output = vanityResult
|
|
969
|
+
? {
|
|
970
|
+
...wallet,
|
|
971
|
+
vanity: {
|
|
972
|
+
suffix: vanityResult.suffix,
|
|
973
|
+
attempts: vanityResult.attempts,
|
|
974
|
+
elapsedMs: vanityResult.elapsedMs,
|
|
975
|
+
ratePerSecond: vanityResult.ratePerSecond,
|
|
976
|
+
},
|
|
977
|
+
}
|
|
978
|
+
: wallet;
|
|
935
979
|
if (flags.has("json")) {
|
|
936
|
-
emit(json(
|
|
980
|
+
emit(json(output) + "\n");
|
|
937
981
|
} else if (process.stdout.isTTY) {
|
|
938
982
|
emit(
|
|
939
983
|
`\n╭─ ${OWL} wallet ready ──────────────────────────────────╮\n` +
|
|
940
984
|
` name @${wallet.name}\n` +
|
|
941
985
|
` address ${wallet.address}\n` +
|
|
986
|
+
(vanityResult
|
|
987
|
+
? ` vanity suffix=${vanityResult.suffix} attempts=${vanityResult.attempts}\n`
|
|
988
|
+
: "") +
|
|
942
989
|
` storage encrypted in Solard's local wallet database\n` +
|
|
943
990
|
` password NOT saved; you will enter it again next invocation\n` +
|
|
944
991
|
`╰──────────────────────────────────────────────────────╯\n` +
|
package/src/vault-onboarding.ts
CHANGED
|
@@ -118,37 +118,20 @@ async function validateAllStoredWallets(password: string): Promise<void> {
|
|
|
118
118
|
const { createTraderSolard } = await import("@solard/sdk");
|
|
119
119
|
const probe = createTraderSolard();
|
|
120
120
|
try {
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
.orderBy("id", "asc")
|
|
124
|
-
.all() as Array<{
|
|
125
|
-
name: string;
|
|
126
|
-
address: string;
|
|
127
|
-
}>;
|
|
128
|
-
if (!wallets.length) return;
|
|
129
|
-
const failures: Array<{ name: string; address: string }> = [];
|
|
130
|
-
let decrypted = 0;
|
|
131
|
-
for (const wallet of wallets) {
|
|
132
|
-
try {
|
|
133
|
-
probe.wallets.signer(wallet.address);
|
|
134
|
-
decrypted += 1;
|
|
135
|
-
} catch {
|
|
136
|
-
failures.push({ name: wallet.name, address: wallet.address });
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
if (!failures.length) return;
|
|
121
|
+
const integrity = probe.wallets.integrity();
|
|
122
|
+
if (!integrity.failures.length) return;
|
|
140
123
|
clearMasterKey();
|
|
141
|
-
if (decrypted === 0) {
|
|
124
|
+
if (integrity.decrypted === 0) {
|
|
142
125
|
throw new VaultOnboardingError(
|
|
143
126
|
"That wallet password could not decrypt the stored wallet database.",
|
|
144
127
|
);
|
|
145
128
|
}
|
|
146
|
-
const affected = failures
|
|
129
|
+
const affected = integrity.failures
|
|
147
130
|
.map((wallet) => `@${wallet.name} ${wallet.address}`)
|
|
148
131
|
.join(", ");
|
|
149
132
|
throw new VaultIntegrityError(
|
|
150
133
|
`Wallet database integrity check failed: one master password must decrypt every stored signing wallet. ` +
|
|
151
|
-
`Decrypted ${decrypted}/${
|
|
134
|
+
`Decrypted ${integrity.decrypted}/${integrity.total}; undecryptable or mismatched: ${affected}`,
|
|
152
135
|
);
|
|
153
136
|
} finally {
|
|
154
137
|
probe.close();
|