@solard/cli 0.2.29 → 0.2.31

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.29",
3
+ "version": "0.2.31",
4
4
  "description": "Command-line interface for the Solard SDK.",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -19,8 +19,8 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "@solana/web3.js": "^1.98.4",
22
- "@solard/core": "0.2.29",
23
- "@solard/sdk": "0.2.29",
22
+ "@solard/core": "0.2.31",
23
+ "@solard/sdk": "0.2.31",
24
24
  "bs58": "^6.0.0",
25
25
  "measure-fn": "5.2.0"
26
26
  },
@@ -1,216 +1,216 @@
1
- import {
2
- executeJupiterSwap,
3
- NATIVE_SOL_MINT,
4
- nativePumpTradeAvailable,
5
- quoteJupiterSwap,
6
- resolveTradeRoute,
7
- sol,
8
- type SenderId,
9
- type Solard,
10
- } from "@solard/core";
11
-
12
- import { resolveTradeTargets, type TradeTargets } from "./trade-targets.ts";
13
- import { tradeFeeOptions } from "./trade-fees.ts";
14
- import { summarizeTradeRoute, type TradeRouteSummary } from "./trade-result.ts";
15
- import { parseVenuePreference, type TradeCommandFlags } from "./trade-venue.ts";
16
-
17
- export type SmartBuyCommandResult =
18
- | {
19
- mode: "simulation";
20
- route: "native";
21
- target: TradeTargets;
22
- routing: TradeRouteSummary;
23
- results: unknown[];
24
- }
25
- | {
26
- mode: "quote";
27
- route: "jupiter";
28
- target: TradeTargets;
29
- routing: TradeRouteSummary;
30
- amountSol: string;
31
- quote: Awaited<ReturnType<typeof quoteJupiterSwap>>;
32
- hint: string;
33
- }
34
- | {
35
- mode: "live";
36
- route: "native";
37
- target: TradeTargets;
38
- routing: TradeRouteSummary;
39
- receipts: unknown;
40
- }
41
- | {
42
- mode: "live";
43
- route: "jupiter";
44
- target: TradeTargets;
45
- routing: TradeRouteSummary;
46
- results: Array<{
47
- wallet: string;
48
- result: Awaited<ReturnType<typeof executeJupiterSwap>>;
49
- }>;
50
- };
51
-
52
- type RunSmartBuyCommandArgs = {
53
- slrd: Solard;
54
- values: string[];
55
- flags: TradeCommandFlags;
56
- };
57
-
58
- function intFlag(
59
- flags: TradeCommandFlags,
60
- key: string,
61
- fallback: number,
62
- ): number {
63
- const value = flags.get(key);
64
- if (!value || value === "true") return fallback;
65
- const parsed = Number(value);
66
- if (!Number.isInteger(parsed)) throw new Error(`--${key} must be an integer`);
67
- return parsed;
68
- }
69
-
70
- export async function runSmartBuyCommand({
71
- slrd,
72
- values,
73
- flags,
74
- }: RunSmartBuyCommandArgs): Promise<SmartBuyCommandResult> {
75
- const tokenRef = values[0];
76
- const usage =
77
- "Usage: slrd buy <token|ca> (--wallet <wallet> | --wallets <w1,w2> | --group <group>) --sol <amount> [--venue auto|native|jupiter]";
78
- if (!tokenRef) throw new Error(usage);
79
-
80
- const amountSol = flags.get("sol");
81
- if (!amountSol || amountSol === "true") {
82
- throw new Error("Buy requires explicit --sol <amount>");
83
- }
84
-
85
- const amount = sol(amountSol);
86
- if (amount.raw <= 0n) throw new Error("--sol must be greater than zero");
87
-
88
- const target = resolveTradeTargets(slrd, flags, usage);
89
- const resolution = await resolveTradeRoute(
90
- slrd,
91
- tokenRef,
92
- parseVenuePreference(flags),
93
- );
94
-
95
- if (resolution.asset.mint === NATIVE_SOL_MINT) {
96
- throw new Error(
97
- "slrd buy expects an SPL token; SOL is already the input asset",
98
- );
99
- }
100
-
101
- if (resolution.route === "native") {
102
- if (!nativePumpTradeAvailable(resolution.token)) {
103
- throw new Error(
104
- "Native buy requires a registered Pump/PumpSwap token; use --venue jupiter for ordinary SPL assets",
105
- );
106
- }
107
-
108
- const options = {
109
- ...tradeFeeOptions(flags),
110
- slippageBps: intFlag(flags, "slippage-bps", 1_500),
111
- via: (flags.get("sender") ?? "rpc") as SenderId,
112
- skipSimulation: flags.has("skip-simulation"),
113
- skipPreflight:
114
- flags.has("skip-preflight") || flags.has("skip-simulation"),
115
- };
116
-
117
- if (flags.has("simulate-only")) {
118
- const plans =
119
- target.refs.length === 1
120
- ? [
121
- await slrd
122
- .tx(target.refs[0]!)
123
- .priorityFee(options.priorityFee)
124
- .buy(resolution.token!.mint, amount, options)
125
- .build(),
126
- ]
127
- : await slrd
128
- .composeMany(target.refs)
129
- .priorityFee(options.priorityFee)
130
- .buy(resolution.token!.mint, amount, options)
131
- .build();
132
- const results = await Promise.all(
133
- plans.map(async (plan, index) => {
134
- const prepared = await slrd.prepareTradePlan(target.refs[index]!, plan, options);
135
- return { ...await slrd.simulatePlan(prepared.plan),
136
- priorityMicroLamports: prepared.priorityMicroLamports,
137
- cuLimit: prepared.plan.draft.cuLimit ?? 600_000 };
138
- }),
139
- );
140
- return {
141
- mode: "simulation",
142
- route: "native",
143
- target,
144
- routing: summarizeTradeRoute(resolution),
145
- results,
146
- };
147
- }
148
-
149
- const receipts =
150
- target.refs.length === 1
151
- ? await slrd.buy(
152
- resolution.token!.mint,
153
- target.refs[0]!,
154
- amount,
155
- options,
156
- )
157
- : await slrd.buyMany(
158
- resolution.token!.mint,
159
- target.refs,
160
- amount,
161
- options,
162
- );
163
-
164
- return {
165
- mode: "live",
166
- route: "native",
167
- target,
168
- routing: summarizeTradeRoute(resolution),
169
- receipts,
170
- };
171
- }
172
-
173
- if (flags.has("simulate-only")) {
174
- const quote = await quoteJupiterSwap({
175
- inputMint: NATIVE_SOL_MINT,
176
- outputMint: resolution.asset.mint,
177
- amountRaw: amount.raw,
178
- });
179
- return {
180
- mode: "quote",
181
- route: "jupiter",
182
- target,
183
- routing: summarizeTradeRoute(resolution),
184
- amountSol,
185
- quote,
186
- hint: "Remove --simulate-only to execute this Jupiter-routed buy.",
187
- };
188
- }
189
-
190
- // Jupiter transport has its own measured, instance-scoped rate limiter. Keep
191
- // multi-wallet execution sequential so a one-shot CLI command cannot create
192
- // an avoidable burst against the API.
193
- const results: Array<{
194
- wallet: string;
195
- result: Awaited<ReturnType<typeof executeJupiterSwap>>;
196
- }> = [];
197
- for (const wallet of target.refs) {
198
- results.push({
199
- wallet,
200
- result: await executeJupiterSwap({
201
- inputMint: NATIVE_SOL_MINT,
202
- outputMint: resolution.asset.mint,
203
- amountRaw: amount.raw,
204
- signer: slrd.signer(wallet),
205
- }),
206
- });
207
- }
208
-
209
- return {
210
- mode: "live",
211
- route: "jupiter",
212
- target,
213
- routing: summarizeTradeRoute(resolution),
214
- results,
215
- };
216
- }
1
+ import {
2
+ executeJupiterSwap,
3
+ NATIVE_SOL_MINT,
4
+ nativePumpTradeAvailable,
5
+ quoteJupiterSwap,
6
+ resolveTradeRoute,
7
+ sol,
8
+ type SenderId,
9
+ type Solard,
10
+ } from "@solard/core";
11
+
12
+ import { resolveTradeTargets, type TradeTargets } from "./trade-targets.ts";
13
+ import { tradeFeeOptions } from "./trade-fees.ts";
14
+ import { summarizeTradeRoute, type TradeRouteSummary } from "./trade-result.ts";
15
+ import { parseVenuePreference, type TradeCommandFlags } from "./trade-venue.ts";
16
+
17
+ export type SmartBuyCommandResult =
18
+ | {
19
+ mode: "simulation";
20
+ route: "native";
21
+ target: TradeTargets;
22
+ routing: TradeRouteSummary;
23
+ results: unknown[];
24
+ }
25
+ | {
26
+ mode: "quote";
27
+ route: "jupiter";
28
+ target: TradeTargets;
29
+ routing: TradeRouteSummary;
30
+ amountSol: string;
31
+ quote: Awaited<ReturnType<typeof quoteJupiterSwap>>;
32
+ hint: string;
33
+ }
34
+ | {
35
+ mode: "live";
36
+ route: "native";
37
+ target: TradeTargets;
38
+ routing: TradeRouteSummary;
39
+ receipts: unknown;
40
+ }
41
+ | {
42
+ mode: "live";
43
+ route: "jupiter";
44
+ target: TradeTargets;
45
+ routing: TradeRouteSummary;
46
+ results: Array<{
47
+ wallet: string;
48
+ result: Awaited<ReturnType<typeof executeJupiterSwap>>;
49
+ }>;
50
+ };
51
+
52
+ type RunSmartBuyCommandArgs = {
53
+ slrd: Solard;
54
+ values: string[];
55
+ flags: TradeCommandFlags;
56
+ };
57
+
58
+ function intFlag(
59
+ flags: TradeCommandFlags,
60
+ key: string,
61
+ fallback: number,
62
+ ): number {
63
+ const value = flags.get(key);
64
+ if (!value || value === "true") return fallback;
65
+ const parsed = Number(value);
66
+ if (!Number.isInteger(parsed)) throw new Error(`--${key} must be an integer`);
67
+ return parsed;
68
+ }
69
+
70
+ export async function runSmartBuyCommand({
71
+ slrd,
72
+ values,
73
+ flags,
74
+ }: RunSmartBuyCommandArgs): Promise<SmartBuyCommandResult> {
75
+ const tokenRef = values[0];
76
+ const usage =
77
+ "Usage: slrd buy <token|ca> (--wallet <wallet> | --wallets <w1,w2> | --group <group>) --sol <amount> [--venue auto|native|jupiter]";
78
+ if (!tokenRef) throw new Error(usage);
79
+
80
+ const amountSol = flags.get("sol");
81
+ if (!amountSol || amountSol === "true") {
82
+ throw new Error("Buy requires explicit --sol <amount>");
83
+ }
84
+
85
+ const amount = sol(amountSol);
86
+ if (amount.raw <= 0n) throw new Error("--sol must be greater than zero");
87
+
88
+ const target = resolveTradeTargets(slrd, flags, usage);
89
+ const resolution = await resolveTradeRoute(
90
+ slrd,
91
+ tokenRef,
92
+ parseVenuePreference(flags),
93
+ );
94
+
95
+ if (resolution.asset.mint === NATIVE_SOL_MINT) {
96
+ throw new Error(
97
+ "slrd buy expects an SPL token; SOL is already the input asset",
98
+ );
99
+ }
100
+
101
+ if (resolution.route === "native") {
102
+ if (!nativePumpTradeAvailable(resolution.token)) {
103
+ throw new Error(
104
+ "Native buy requires a registered Pump/PumpSwap token; use --venue jupiter for ordinary SPL assets",
105
+ );
106
+ }
107
+
108
+ const options = {
109
+ ...tradeFeeOptions(flags),
110
+ slippageBps: intFlag(flags, "slippage-bps", 1_500),
111
+ via: (flags.get("sender") ?? "rpc") as SenderId,
112
+ skipSimulation: flags.has("skip-simulation"),
113
+ skipPreflight:
114
+ flags.has("skip-preflight") || flags.has("skip-simulation"),
115
+ };
116
+
117
+ if (flags.has("simulate-only")) {
118
+ const plans =
119
+ target.refs.length === 1
120
+ ? [
121
+ await slrd
122
+ .tx(target.refs[0]!)
123
+ .priorityFee(options.priorityFee)
124
+ .buy(resolution.token!.mint, amount, options)
125
+ .build(),
126
+ ]
127
+ : await slrd
128
+ .composeMany(target.refs)
129
+ .priorityFee(options.priorityFee)
130
+ .buy(resolution.token!.mint, amount, options)
131
+ .build();
132
+ const results = await Promise.all(
133
+ plans.map(async (plan, index) => {
134
+ const prepared = await slrd.prepareTradePlan(target.refs[index]!, plan, options);
135
+ return { ...await slrd.simulatePlan(prepared.plan),
136
+ priorityMicroLamports: prepared.priorityMicroLamports,
137
+ cuLimit: prepared.plan.draft.cuLimit ?? 600_000 };
138
+ }),
139
+ );
140
+ return {
141
+ mode: "simulation",
142
+ route: "native",
143
+ target,
144
+ routing: summarizeTradeRoute(resolution),
145
+ results,
146
+ };
147
+ }
148
+
149
+ const receipts =
150
+ target.refs.length === 1
151
+ ? await slrd.buy(
152
+ resolution.token!.mint,
153
+ target.refs[0]!,
154
+ amount,
155
+ options,
156
+ )
157
+ : await slrd.buyMany(
158
+ resolution.token!.mint,
159
+ target.refs,
160
+ amount,
161
+ options,
162
+ );
163
+
164
+ return {
165
+ mode: "live",
166
+ route: "native",
167
+ target,
168
+ routing: summarizeTradeRoute(resolution),
169
+ receipts,
170
+ };
171
+ }
172
+
173
+ if (flags.has("simulate-only")) {
174
+ const quote = await quoteJupiterSwap({
175
+ inputMint: NATIVE_SOL_MINT,
176
+ outputMint: resolution.asset.mint,
177
+ amountRaw: amount.raw,
178
+ });
179
+ return {
180
+ mode: "quote",
181
+ route: "jupiter",
182
+ target,
183
+ routing: summarizeTradeRoute(resolution),
184
+ amountSol,
185
+ quote,
186
+ hint: "Remove --simulate-only to execute this Jupiter-routed buy.",
187
+ };
188
+ }
189
+
190
+ // Jupiter transport has its own measured, instance-scoped rate limiter. Keep
191
+ // multi-wallet execution sequential so a one-shot CLI command cannot create
192
+ // an avoidable burst against the API.
193
+ const results: Array<{
194
+ wallet: string;
195
+ result: Awaited<ReturnType<typeof executeJupiterSwap>>;
196
+ }> = [];
197
+ for (const wallet of target.refs) {
198
+ results.push({
199
+ wallet,
200
+ result: await executeJupiterSwap({
201
+ inputMint: NATIVE_SOL_MINT,
202
+ outputMint: resolution.asset.mint,
203
+ amountRaw: amount.raw,
204
+ signer: slrd.signer(wallet),
205
+ }),
206
+ });
207
+ }
208
+
209
+ return {
210
+ mode: "live",
211
+ route: "jupiter",
212
+ target,
213
+ routing: summarizeTradeRoute(resolution),
214
+ results,
215
+ };
216
+ }