@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solard/cli",
3
- "version": "0.2.15",
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.15",
21
+ "@solard/sdk": "0.2.16",
22
22
  "bs58": "^6.0.0",
23
23
  "@solana/web3.js": "^1.98.4"
24
24
  },
@@ -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
- const swaps = !bool(flags, "transfers-only");
227
- const transfers = !bool(flags, "swaps-only");
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.list().length;
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] Generate and persist an encrypted Solana wallet
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-only|--transfers-only] [--jsonl] Live typed Pump/PumpSwap + transfer stream
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 && !process.env.SLRD_MASTER_KEY?.trim()) {
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 wallet = slrd.createWallet(
933
- values[1] ?? (firstWallet ? "main" : undefined),
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(wallet) + "\n");
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` +
@@ -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 wallets = probe.db.wallets
122
- .select()
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}/${wallets.length}; undecryptable: ${affected}`,
134
+ `Decrypted ${integrity.decrypted}/${integrity.total}; undecryptable or mismatched: ${affected}`,
152
135
  );
153
136
  } finally {
154
137
  probe.close();