@solard/cli 0.2.33 → 0.2.40

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.33",
3
+ "version": "0.2.40",
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.33",
23
- "@solard/sdk": "0.2.33",
22
+ "@solard/core": "0.2.40",
23
+ "@solard/sdk": "0.2.40",
24
24
  "bs58": "^6.0.0",
25
25
  "measure-fn": "5.2.0"
26
26
  },
@@ -1,5 +1,7 @@
1
+ import { hasOutputMinimum, parseOutputMinimum } from "./trade-minimum.ts";
1
2
  import {
2
3
  executeJupiterSwap,
4
+ minimumBuyOutputForPrice,
3
5
  NATIVE_SOL_MINT,
4
6
  nativePumpTradeAvailable,
5
7
  quoteJupiterSwap,
@@ -74,7 +76,7 @@ export async function runSmartBuyCommand({
74
76
  }: RunSmartBuyCommandArgs): Promise<SmartBuyCommandResult> {
75
77
  const tokenRef = values[0];
76
78
  const usage =
77
- "Usage: slrd buy <token|ca> (--wallet <wallet> | --wallets <w1,w2> | --group <group>) --sol <amount> [--venue auto|native|jupiter]";
79
+ "Usage: slrd buy <token|ca> (--wallet <wallet> | --wallets <w1,w2> | --group <group>) --sol <amount> [--venue auto|native|jupiter] [--max-price-sol <SOL/token>] [--min-out <amount> | --min-out-raw <units> | --slippage-bps N]";
78
80
  if (!tokenRef) throw new Error(usage);
79
81
 
80
82
  const amountSol = flags.get("sol");
@@ -98,6 +100,20 @@ export async function runSmartBuyCommand({
98
100
  );
99
101
  }
100
102
 
103
+ const maxPriceSol = flags.get("max-price-sol");
104
+ if (flags.has("max-price-sol") && (!maxPriceSol || maxPriceSol === "true"))
105
+ throw new Error("--max-price-sol requires a positive SOL price per token");
106
+ if (maxPriceSol != null && flags.has("slippage-bps"))
107
+ throw new Error("Use --max-price-sol instead of --slippage-bps");
108
+ let outputMinimumRaw = parseOutputMinimum(flags, resolution.asset.decimals);
109
+ if (maxPriceSol != null) {
110
+ const priceMinimum = minimumBuyOutputForPrice(amount.raw, resolution.asset.decimals, maxPriceSol);
111
+ if (outputMinimumRaw == null || priceMinimum > outputMinimumRaw) outputMinimumRaw = priceMinimum;
112
+ }
113
+ if ((hasOutputMinimum(flags) || maxPriceSol != null) && resolution.route !== "native") {
114
+ throw new Error("Absolute minimum output is currently supported on native Pump/PumpSwap routes; Jupiter orders do not expose a verified on-chain minimum");
115
+ }
116
+
101
117
  if (resolution.route === "native") {
102
118
  if (!nativePumpTradeAvailable(resolution.token)) {
103
119
  throw new Error(
@@ -107,6 +123,8 @@ export async function runSmartBuyCommand({
107
123
 
108
124
  const options = {
109
125
  ...tradeFeeOptions(flags),
126
+ outputMinimumRaw,
127
+ maxPriceSol,
110
128
  slippageBps: intFlag(flags, "slippage-bps", 1_500),
111
129
  via: (flags.get("sender") ?? "rpc") as SenderId,
112
130
  skipSimulation: flags.has("skip-simulation"),
@@ -131,10 +149,18 @@ export async function runSmartBuyCommand({
131
149
  .build();
132
150
  const results = await Promise.all(
133
151
  plans.map(async (plan, index) => {
134
- const prepared = await slrd.prepareTradePlan(target.refs[index]!, plan, options);
135
- return { ...await slrd.simulatePlan(prepared.plan),
152
+ const prepared = await slrd.prepareTradePlan(
153
+ target.refs[index]!,
154
+ plan,
155
+ options,
156
+ );
157
+ return {
158
+ ...(await slrd.simulatePlan(prepared.plan)),
136
159
  priorityMicroLamports: prepared.priorityMicroLamports,
137
- cuLimit: prepared.plan.draft.cuLimit ?? 600_000 };
160
+ cuLimit: prepared.plan.draft.cuLimit ?? 600_000,
161
+ requestedMinimumOutputRaw: outputMinimumRaw?.toString(),
162
+ guaranteedOutputRaw: prepared.plan.draft.actions.find(action => action.kind === "buy")?.meta?.minOutputRaw,
163
+ };
138
164
  }),
139
165
  );
140
166
  return {
@@ -1,3 +1,4 @@
1
+ import { hasOutputMinimum, parseOutputMinimum } from "./trade-minimum.ts";
1
2
  import {
2
3
  executeJupiterSwap,
3
4
  NATIVE_SOL_MINT,
@@ -118,7 +119,7 @@ export async function runSmartSellCommand({
118
119
  }: RunSmartSellCommandArgs): Promise<SmartSellCommandResult> {
119
120
  const tokenRef = values[0];
120
121
  const usage =
121
- "Usage: slrd sell <token|ca> (--wallet <wallet> | --wallets <w1,w2> | --group <group>) [--bps 10000] [--venue auto|native|jupiter]";
122
+ "Usage: slrd sell <token|ca> (--wallet <wallet> | --wallets <w1,w2> | --group <group>) [--bps 10000] [--venue auto|native|jupiter] [--min-out <amount> | --min-out-raw <units> | --slippage-bps N]";
122
123
  if (!tokenRef) throw new Error(usage);
123
124
 
124
125
  const bps = intFlag(flags, "bps", 10_000);
@@ -135,6 +136,11 @@ export async function runSmartSellCommand({
135
136
  throw new Error("slrd sell expects an SPL token");
136
137
  }
137
138
 
139
+ const outputMinimumRaw = parseOutputMinimum(flags, 9);
140
+ if (hasOutputMinimum(flags) && resolution.route !== "native") {
141
+ throw new Error("Absolute minimum output is currently supported on native Pump/PumpSwap routes; Jupiter orders do not expose a verified on-chain minimum");
142
+ }
143
+
138
144
  if (resolution.route === "native") {
139
145
  if (!nativePumpTradeAvailable(resolution.token)) {
140
146
  throw new Error(
@@ -144,6 +150,7 @@ export async function runSmartSellCommand({
144
150
 
145
151
  const options = {
146
152
  ...tradeFeeOptions(flags),
153
+ outputMinimumRaw,
147
154
  bps,
148
155
  slippageBps: intFlag(flags, "slippage-bps", 1_500),
149
156
  via: (flags.get("sender") ?? "rpc") as SenderId,
@@ -169,10 +176,18 @@ export async function runSmartSellCommand({
169
176
  .build();
170
177
  const results = await Promise.all(
171
178
  plans.map(async (plan, index) => {
172
- const prepared = await slrd.prepareTradePlan(target.refs[index]!, plan, options);
173
- return { ...await slrd.simulatePlan(prepared.plan),
179
+ const prepared = await slrd.prepareTradePlan(
180
+ target.refs[index]!,
181
+ plan,
182
+ options,
183
+ );
184
+ return {
185
+ ...(await slrd.simulatePlan(prepared.plan)),
174
186
  priorityMicroLamports: prepared.priorityMicroLamports,
175
- cuLimit: prepared.plan.draft.cuLimit ?? 600_000 };
187
+ cuLimit: prepared.plan.draft.cuLimit ?? 600_000,
188
+ requestedMinimumOutputRaw: outputMinimumRaw?.toString(),
189
+ guaranteedOutputRaw: prepared.plan.draft.actions.find(action => action.kind === "sell")?.meta?.minOutputRaw,
190
+ };
176
191
  }),
177
192
  );
178
193
  return {
@@ -2,14 +2,26 @@ import { expect, test } from "bun:test";
2
2
  import { tradeFeeOptions } from "./trade-fees.ts";
3
3
 
4
4
  test("native buy/sell fee flags preserve custom compute limit and price", () => {
5
- expect(tradeFeeOptions(new Map([
6
- ["cu-limit", "150000"], ["priority-micro-lamports", "1000000"],
7
- ["trade-attempts", "4"], ["max-priority-fee-lamports", "500000"],
8
- ]))).toMatchObject({ priorityFee: { cuLimit: 150_000, microLamports: 1_000_000 },
9
- landing: { maxAttempts: 4, maxPriorityFeeLamports: 500_000 } });
5
+ expect(
6
+ tradeFeeOptions(
7
+ new Map([
8
+ ["cu-limit", "150000"],
9
+ ["priority-micro-lamports", "1000000"],
10
+ ["trade-attempts", "4"],
11
+ ["max-priority-fee-lamports", "500000"],
12
+ ]),
13
+ ),
14
+ ).toMatchObject({
15
+ priorityFee: { cuLimit: 150_000, microLamports: 1_000_000 },
16
+ landing: { maxAttempts: 4, maxPriorityFeeLamports: 500_000 },
17
+ });
10
18
  });
11
19
 
12
20
  test("invalid fee flags reject instead of being ignored", () => {
13
- for (const [name, value] of [["cu-limit", "0"], ["priority-micro-lamports", "-1"], ["priority-micro-lamports", "true"]])
21
+ for (const [name, value] of [
22
+ ["cu-limit", "0"],
23
+ ["priority-micro-lamports", "-1"],
24
+ ["priority-micro-lamports", "true"],
25
+ ])
14
26
  expect(() => tradeFeeOptions(new Map([[name!, value!]]))).toThrow();
15
27
  });
@@ -10,9 +10,15 @@ export function tradeFeeOptions(flags: ReadonlyMap<string, string>) {
10
10
  };
11
11
  const cuLimit = number("cu-limit");
12
12
  const microLamports = number("priority-micro-lamports");
13
- if (cuLimit != null && (!Number.isInteger(cuLimit) || cuLimit < 1 || cuLimit > 1_400_000))
13
+ if (
14
+ cuLimit != null &&
15
+ (!Number.isInteger(cuLimit) || cuLimit < 1 || cuLimit > 1_400_000)
16
+ )
14
17
  throw new Error("--cu-limit must be an integer between 1 and 1400000");
15
- if (microLamports != null && (!Number.isSafeInteger(microLamports) || microLamports < 0))
18
+ if (
19
+ microLamports != null &&
20
+ (!Number.isSafeInteger(microLamports) || microLamports < 0)
21
+ )
16
22
  throw new Error("--priority-micro-lamports must be a non-negative integer");
17
23
  const landing: TradeLandingPolicy = {
18
24
  maxAttempts: number("trade-attempts"),
@@ -0,0 +1,50 @@
1
+ import { expect, test } from "bun:test";
2
+ import { parseOutputMinimum } from "./trade-minimum.ts";
3
+ import { runSmartBuyCommand } from "./buy.ts";
4
+ import { runSmartSellCommand } from "./sell.ts";
5
+ import type { Solard } from "@solard/core";
6
+ import { TOKEN_PROGRAM_ID } from "@solana/spl-token";
7
+ const mint = "E4R6KvcnxvoHYBe872byyCeoyExGHja8n5Vo3JNWodus";
8
+ test("absolute output parsing preserves precision and rejects ambiguous or unsafe input", () => {
9
+ expect(parseOutputMinimum(new Map([["min-out", "123.000001"]]), 6)).toBe(123000001n);
10
+ expect(parseOutputMinimum(new Map([["min-out", "0.001"]]), 9)).toBe(1000000n);
11
+ expect(parseOutputMinimum(new Map([["min-out-raw", "9007199254740993"]]), 6)).toBe(9007199254740993n);
12
+ for (const value of ["true", "0", "-1", "1e3", "0.0000001", "18446744073709551616"]) {
13
+ expect(() => parseOutputMinimum(new Map([["min-out", value]]), 6)).toThrow();
14
+ }
15
+ expect(() => parseOutputMinimum(new Map([["min-out", "1"], ["slippage-bps", "100"]]), 6)).toThrow();
16
+ expect(() => parseOutputMinimum(new Map([["min-out", "1"], ["min-out-raw", "1"]]), 6)).toThrow();
17
+ });
18
+ test("CLI buy/sell forward per-wallet absolute output floors in correct units", async () => {
19
+ const seen: unknown[] = [];
20
+ const host = {
21
+ tokens: { list: () => [{ mint, decimals: 6, baseTokenProgram: TOKEN_PROGRAM_ID.toBase58(), venueHint: "pumpswap" }] },
22
+ buy: async (_mint: unknown, _wallet: unknown, _amount: unknown, options: unknown) => { seen.push(options); },
23
+ sell: async (_mint: unknown, _wallet: unknown, options: unknown) => { seen.push(options); },
24
+ } as unknown as Solard;
25
+ await runSmartBuyCommand({ slrd: host, values: [mint], flags: new Map([["wallet", "test"], ["sol", "0.001"], ["min-out", "123.5"]]) });
26
+ await runSmartSellCommand({ slrd: host, values: [mint], flags: new Map([["wallet", "test"], ["min-out", "0.001"]]) });
27
+ expect(seen[0]).toMatchObject({ outputMinimumRaw: 123500000n });
28
+ expect(seen[1]).toMatchObject({ outputMinimumRaw: 1000000n });
29
+ });
30
+ test("Jupiter absolute-floor requests fail explicitly without signing", async () => {
31
+ const host = { tokens: { list: () => [] }, signer: () => { throw new Error("SIGNER_ACCESSED"); } } as unknown as Solard;
32
+ await expect(runSmartBuyCommand({ slrd: host, values: ["USDC"],
33
+ flags: new Map([["wallet", "test"], ["sol", "0.001"], ["min-out", "1"]]),
34
+ })).rejects.toThrow("verified on-chain minimum");
35
+ });
36
+ test("maximum buy price derives the on-chain floor and combines with stricter token minima", async () => {
37
+ const seen: unknown[] = [];
38
+ const host = {
39
+ tokens: { list: () => [{ mint, decimals: 6, baseTokenProgram: TOKEN_PROGRAM_ID.toBase58(), venueHint: "pumpswap" }] },
40
+ buy: async (_mint: unknown, _wallet: unknown, _amount: unknown, options: unknown) => { seen.push(options); },
41
+ } as unknown as Solard;
42
+ const flags = new Map([["wallet", "test"], ["sol", "0.1"], ["max-price-sol", "0.0001"]]);
43
+ await runSmartBuyCommand({ slrd: host, values: [mint], flags });
44
+ expect(seen[0]).toMatchObject({ maxPriceSol: "0.0001", outputMinimumRaw: 1000000000n });
45
+ flags.set("min-out", "1100");
46
+ await runSmartBuyCommand({ slrd: host, values: [mint], flags });
47
+ expect(seen[1]).toMatchObject({ outputMinimumRaw: 1100000000n });
48
+ flags.delete("min-out"); flags.set("slippage-bps", "100");
49
+ await expect(runSmartBuyCommand({ slrd: host, values: [mint], flags })).rejects.toThrow("instead of");
50
+ });
@@ -0,0 +1,23 @@
1
+ import type { TradeCommandFlags } from "./trade-venue.ts";
2
+
3
+ export function hasOutputMinimum(flags: TradeCommandFlags): boolean {
4
+ return flags.has("min-out") || flags.has("min-out-raw");
5
+ }
6
+
7
+ export function parseOutputMinimum(flags: TradeCommandFlags, decimals: number): bigint | undefined {
8
+ if (!hasOutputMinimum(flags)) return undefined;
9
+ if (flags.has("slippage-bps")) throw new Error("Use --min-out or --min-out-raw instead of --slippage-bps");
10
+ if (flags.has("min-out") && flags.has("min-out-raw")) throw new Error("Choose --min-out or --min-out-raw");
11
+ const raw = flags.has("min-out-raw");
12
+ const value = flags.get(raw ? "min-out-raw" : "min-out") ?? "";
13
+ if (!Number.isSafeInteger(decimals) || decimals < 0 || decimals > 255)
14
+ throw new Error("Output mint decimals unavailable");
15
+ if (!(raw ? /^\d+$/ : /^\d+(?:\.\d+)?$/).test(value))
16
+ throw new Error("Minimum output must be a positive decimal amount (integer for --min-out-raw)");
17
+ const [whole, fraction = ""] = value.split(".");
18
+ if (!raw && fraction.length > decimals) throw new Error(`Minimum output supports at most ${decimals} decimal places`);
19
+ const amount = raw ? BigInt(value)
20
+ : BigInt(whole!) * 10n ** BigInt(decimals) + BigInt(fraction.padEnd(decimals, "0") || "0");
21
+ if (amount <= 0n || amount > 0xffffffffffffffffn) throw new Error("Minimum output must be a positive u64");
22
+ return amount;
23
+ }
@@ -3,31 +3,88 @@ import { Keypair } from "@solana/web3.js";
3
3
  import { Solard, estimatePlanFee, type PlannedTransaction } from "@solard/core";
4
4
  import { runTransferCommand } from "./transfer.ts";
5
5
  function fixture(status: "confirmed" | "submitted" | "failed" = "confirmed") {
6
- const core: Solard = Object.create(Solard.prototype); const payer = Keypair.generate();
7
- const prices: number[] = []; let samples = 0;
6
+ const core: Solard = Object.create(Solard.prototype);
7
+ const payer = Keypair.generate();
8
+ const prices: number[] = [];
9
+ let samples = 0;
8
10
  core.signer = () => payer;
9
- core.connection = () => ({
10
- getRecentPrioritizationFees: async () => { samples++; return [200_000, 400_000, 800_000, 1_000_000].map((prioritizationFee) => ({ prioritizationFee })); },
11
- getFeeForMessage: async (message: { price: number }) => ({ value: 5000 + Math.ceil(10_000 * message.price / 1_000_000) }),
12
- }) as any;
13
- core.compile = async (_payer, draft) => ({ draft, payer: payer.publicKey, transaction: { message: { price: draft.cuPriceMicroLamports ?? 100_000 } } }) as unknown as PlannedTransaction;
14
- core.submitPlan = async (plan, sender) => { prices.push(plan.draft.cuPriceMicroLamports!); return { signature: "test-signature", executionId: 1, sender, plan, feeEstimate: await estimatePlanFee(core.connection(), plan) }; };
15
- core.settleSubmission = async () => ({ signature: "test-signature", sender: "rpc", status, slot: status === "confirmed" ? 1 : null, ...(status === "confirmed" ? { feeLamports: 13000 } : {}) });
16
- Object.defineProperty(core, "executions", { value: { get: () => ({ metaJson: null }) } });
11
+ core.connection = () =>
12
+ ({
13
+ getRecentPrioritizationFees: async () => {
14
+ samples++;
15
+ return [200_000, 400_000, 800_000, 1_000_000].map(
16
+ (prioritizationFee) => ({ prioritizationFee }),
17
+ );
18
+ },
19
+ getFeeForMessage: async (message: { price: number }) => ({
20
+ value: 5000 + Math.ceil((10_000 * message.price) / 1_000_000),
21
+ }),
22
+ }) as any;
23
+ core.compile = async (_payer, draft) =>
24
+ ({
25
+ draft,
26
+ payer: payer.publicKey,
27
+ transaction: {
28
+ message: { price: draft.cuPriceMicroLamports ?? 100_000 },
29
+ },
30
+ }) as unknown as PlannedTransaction;
31
+ core.submitPlan = async (plan, sender) => {
32
+ prices.push(plan.draft.cuPriceMicroLamports!);
33
+ return {
34
+ signature: "test-signature",
35
+ executionId: 1,
36
+ sender,
37
+ plan,
38
+ feeEstimate: await estimatePlanFee(core.connection(), plan),
39
+ };
40
+ };
41
+ core.settleSubmission = async () => ({
42
+ signature: "test-signature",
43
+ sender: "rpc",
44
+ status,
45
+ slot: status === "confirmed" ? 1 : null,
46
+ ...(status === "confirmed" ? { feeLamports: 13000 } : {}),
47
+ });
48
+ Object.defineProperty(core, "executions", {
49
+ value: { get: () => ({ metaJson: null }) },
50
+ });
17
51
  return { core, prices, samples: () => samples };
18
52
  }
19
- const flags = (extra: Array<[string, string]> = []) => new Map([["wallet", "bags"], ["sol", "2"], ["live", "true"], ...extra]);
53
+ const flags = (extra: Array<[string, string]> = []) =>
54
+ new Map([["wallet", "bags"], ["sol", "2"], ["live", "true"], ...extra]);
20
55
  test("SOL transfer uses writable market fees and reports selected versus actual network fees", async () => {
21
56
  const ctx = fixture();
22
- const result = await runTransferCommand({ slrd: ctx.core, values: [Keypair.generate().publicKey.toBase58()], flags: flags() });
23
- expect(ctx.prices).toEqual([800_000]); expect(ctx.samples()).toBe(1);
24
- expect(result.status).toBe("confirmed"); expect(result.feeEstimate).toEqual({ cuLimit: 10_000, priorityMicroLamports: 800_000, priorityFeeLamports: 8000, estimatedBaseFeeLamports: 5000, estimatedNetworkFeeLamports: 13000 });
57
+ const result = await runTransferCommand({
58
+ slrd: ctx.core,
59
+ values: [Keypair.generate().publicKey.toBase58()],
60
+ flags: flags(),
61
+ });
62
+ expect(ctx.prices).toEqual([800_000]);
63
+ expect(ctx.samples()).toBe(1);
64
+ expect(result.status).toBe("confirmed");
65
+ expect(result.feeEstimate).toEqual({
66
+ cuLimit: 10_000,
67
+ priorityMicroLamports: 800_000,
68
+ priorityFeeLamports: 8000,
69
+ estimatedBaseFeeLamports: 5000,
70
+ estimatedNetworkFeeLamports: 13000,
71
+ });
25
72
  expect(result.feeLamports).toBe(13000);
26
73
  });
27
74
  test("explicit zero disables transfer fee estimation and pending outcome is never repeated blindly", async () => {
28
75
  const ctx = fixture("submitted");
29
- const result = await runTransferCommand({ slrd: ctx.core, values: [Keypair.generate().publicKey.toBase58()], flags: flags([["priority-micro-lamports", "0"]]) });
30
- expect(ctx.prices).toEqual([0]); expect(ctx.samples()).toBe(0);
31
- expect(result.status).toBe("unresolved"); expect(result.code).toBe("UNRESOLVED"); expect(result.feeLamports).toBeUndefined();
32
- expect(result.feeEstimate).toMatchObject({ priorityFeeLamports: 0, estimatedNetworkFeeLamports: 5000 });
76
+ const result = await runTransferCommand({
77
+ slrd: ctx.core,
78
+ values: [Keypair.generate().publicKey.toBase58()],
79
+ flags: flags([["priority-micro-lamports", "0"]]),
80
+ });
81
+ expect(ctx.prices).toEqual([0]);
82
+ expect(ctx.samples()).toBe(0);
83
+ expect(result.status).toBe("unresolved");
84
+ expect(result.code).toBe("UNRESOLVED");
85
+ expect(result.feeLamports).toBeUndefined();
86
+ expect(result.feeEstimate).toMatchObject({
87
+ priorityFeeLamports: 0,
88
+ estimatedNetworkFeeLamports: 5000,
89
+ });
33
90
  });
@@ -144,7 +144,11 @@ export async function runTransferCommand({
144
144
  .priorityFee({ cuLimit, microLamports: priorityMicroLamports });
145
145
 
146
146
  if (flags.has("simulate-only")) {
147
- const prepared = await slrd.prepareTradePlan(wallet, await composer.build(), executionOptions);
147
+ const prepared = await slrd.prepareTradePlan(
148
+ wallet,
149
+ await composer.build(),
150
+ executionOptions,
151
+ );
148
152
  const result = await slrd.simulatePlan(prepared.plan);
149
153
  return {
150
154
  mode: "simulation",
@@ -162,8 +166,18 @@ export async function runTransferCommand({
162
166
  };
163
167
  }
164
168
 
165
- const execution = await slrd.executeTradePlan(wallet, () => composer.build(), via, "transfer-token", executionOptions);
166
- const receipt = tradeResult(execution.receipt, execution.attempts, execution.submission.executionId);
169
+ const execution = await slrd.executeTradePlan(
170
+ wallet,
171
+ () => composer.build(),
172
+ via,
173
+ "transfer-token",
174
+ executionOptions,
175
+ );
176
+ const receipt = tradeResult(
177
+ execution.receipt,
178
+ execution.attempts,
179
+ execution.submission.executionId,
180
+ );
167
181
 
168
182
  return {
169
183
  ...receipt,
@@ -184,7 +198,11 @@ export async function runTransferCommand({
184
198
  .priorityFee({ cuLimit, microLamports: priorityMicroLamports });
185
199
 
186
200
  if (flags.has("simulate-only")) {
187
- const prepared = await slrd.prepareTradePlan(wallet, await composer.build(), executionOptions);
201
+ const prepared = await slrd.prepareTradePlan(
202
+ wallet,
203
+ await composer.build(),
204
+ executionOptions,
205
+ );
188
206
  const result = await slrd.simulatePlan(prepared.plan);
189
207
  return {
190
208
  mode: "simulation",
@@ -198,8 +216,18 @@ export async function runTransferCommand({
198
216
  };
199
217
  }
200
218
 
201
- const execution = await slrd.executeTradePlan(wallet, () => composer.build(), via, "transfer-sol", executionOptions);
202
- const receipt = tradeResult(execution.receipt, execution.attempts, execution.submission.executionId);
219
+ const execution = await slrd.executeTradePlan(
220
+ wallet,
221
+ () => composer.build(),
222
+ via,
223
+ "transfer-sol",
224
+ executionOptions,
225
+ );
226
+ const receipt = tradeResult(
227
+ execution.receipt,
228
+ execution.attempts,
229
+ execution.submission.executionId,
230
+ );
203
231
 
204
232
  return { ...receipt, recipient, wallet, sol: amount };
205
233
  }