@nodiusxyz/solana-agent-kit 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/README.md +131 -2
- package/dist/index.d.ts +281 -0
- package/dist/index.js +277 -0
- package/dist/internal/admission.d.ts +11 -0
- package/dist/internal/admission.js +96 -0
- package/dist/internal/app.d.ts +6 -0
- package/dist/internal/app.js +422 -0
- package/dist/internal/config.d.ts +10 -0
- package/dist/internal/config.js +106 -0
- package/dist/internal/journal.d.ts +13 -0
- package/dist/internal/journal.js +135 -0
- package/dist/internal/monitor.d.ts +12 -0
- package/dist/internal/monitor.js +122 -0
- package/dist/internal/safety.d.ts +37 -0
- package/dist/internal/safety.js +199 -0
- package/dist/internal/transport.d.ts +23 -0
- package/dist/internal/transport.js +97 -0
- package/dist/internal/v2-policy.d.ts +19 -0
- package/dist/internal/v2-policy.js +168 -0
- package/examples/readonly.ts +42 -0
- package/package.json +62 -4
- package/src/index.ts +297 -0
- package/src/internal/admission.ts +131 -0
- package/src/internal/app.ts +509 -0
- package/src/internal/config.ts +107 -0
- package/src/internal/journal.ts +145 -0
- package/src/internal/monitor.ts +141 -0
- package/src/internal/safety.ts +259 -0
- package/src/internal/transport.ts +112 -0
- package/src/internal/v2-policy.ts +315 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { run } from "./internal/app.js";
|
|
3
|
+
import { endpoint as validateEndpoint } from "./internal/config.js";
|
|
4
|
+
export { decodeBuilderUnsigned } from "./internal/safety.js";
|
|
5
|
+
const integer = z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
|
|
6
|
+
const decimal = z.string().regex(/^(0|[1-9]\d*)(\.\d{1,9})?$/);
|
|
7
|
+
const base = {
|
|
8
|
+
mint: z.string().min(32).max(44),
|
|
9
|
+
maxSol: decimal,
|
|
10
|
+
maxFeeCredits: integer,
|
|
11
|
+
slippageBps: integer.max(9999),
|
|
12
|
+
priorityFee: integer,
|
|
13
|
+
maxPriorityFee: integer,
|
|
14
|
+
maxPriorityLamports: integer.optional(),
|
|
15
|
+
execute: z.boolean().default(false),
|
|
16
|
+
buildOnly: z.boolean().default(false),
|
|
17
|
+
operationId: z
|
|
18
|
+
.string()
|
|
19
|
+
.regex(/^[A-Za-z0-9_-]{1,80}$/)
|
|
20
|
+
.optional(),
|
|
21
|
+
acceptUnquotedBuildCharge: z.boolean().default(false),
|
|
22
|
+
};
|
|
23
|
+
export const tradeSchema = z.discriminatedUnion("side", [
|
|
24
|
+
z.object({ ...base, side: z.literal("buy"), amountSol: decimal }).strict(),
|
|
25
|
+
z
|
|
26
|
+
.object({
|
|
27
|
+
...base,
|
|
28
|
+
side: z.literal("sell"),
|
|
29
|
+
amountRaw: z.string().regex(/^[1-9]\d*$/),
|
|
30
|
+
})
|
|
31
|
+
.strict(),
|
|
32
|
+
]);
|
|
33
|
+
const tradeActionSchema = z
|
|
34
|
+
.object({
|
|
35
|
+
...base,
|
|
36
|
+
side: z.enum(["buy", "sell"]),
|
|
37
|
+
amountSol: decimal.optional(),
|
|
38
|
+
amountRaw: z
|
|
39
|
+
.string()
|
|
40
|
+
.regex(/^[1-9]\d*$/)
|
|
41
|
+
.optional(),
|
|
42
|
+
})
|
|
43
|
+
.strict();
|
|
44
|
+
export const monitorSchema = z
|
|
45
|
+
.object({
|
|
46
|
+
maxFeeCredits: integer,
|
|
47
|
+
seconds: integer.min(1).max(300).default(30),
|
|
48
|
+
maxEvents: integer.min(1).max(1000).default(100),
|
|
49
|
+
mint: z.string().min(32).max(44).optional(),
|
|
50
|
+
kinds: z
|
|
51
|
+
.array(z.enum(["newPair", "graduation", "walletActivity", "largeSwap"]))
|
|
52
|
+
.min(1)
|
|
53
|
+
.max(4)
|
|
54
|
+
.optional(),
|
|
55
|
+
})
|
|
56
|
+
.strict();
|
|
57
|
+
export const statusSchema = z
|
|
58
|
+
.object({ operationId: z.string().regex(/^[A-Za-z0-9_-]{1,80}$/) })
|
|
59
|
+
.strict();
|
|
60
|
+
export const sendSchema = z
|
|
61
|
+
.object({
|
|
62
|
+
signedTxBase64: z.string().min(1).max(1644),
|
|
63
|
+
maxFeeCredits: integer,
|
|
64
|
+
execute: z.boolean().default(false),
|
|
65
|
+
operationId: z
|
|
66
|
+
.string()
|
|
67
|
+
.regex(/^[A-Za-z0-9_-]{1,80}$/)
|
|
68
|
+
.optional(),
|
|
69
|
+
})
|
|
70
|
+
.strict();
|
|
71
|
+
export function createNodiusPlugin(options) {
|
|
72
|
+
const parsed = z
|
|
73
|
+
.object({
|
|
74
|
+
apiKey: z
|
|
75
|
+
.string()
|
|
76
|
+
.min(1)
|
|
77
|
+
.regex(/^[^\r\n]+$/)
|
|
78
|
+
.optional(),
|
|
79
|
+
endpoint: z.string().optional(),
|
|
80
|
+
journalDir: z.string().min(1),
|
|
81
|
+
allowExecution: z.boolean().default(false),
|
|
82
|
+
ackIncompletePolicy: z.boolean().default(false),
|
|
83
|
+
})
|
|
84
|
+
.strict()
|
|
85
|
+
.parse(options);
|
|
86
|
+
const o = Object.freeze({
|
|
87
|
+
...parsed,
|
|
88
|
+
endpoint: validateEndpoint(parsed.endpoint ?? "https://rpc.nodius.xyz"),
|
|
89
|
+
});
|
|
90
|
+
let owner;
|
|
91
|
+
const recent = z
|
|
92
|
+
.object({ limit: integer.min(1).max(50).default(20) })
|
|
93
|
+
.strict();
|
|
94
|
+
function clean(value) {
|
|
95
|
+
const text = (s) => o.apiKey ? s.split(o.apiKey).join("[REDACTED]") : s;
|
|
96
|
+
if (typeof value === "string")
|
|
97
|
+
return text(value);
|
|
98
|
+
if (typeof value === "bigint")
|
|
99
|
+
return value.toString();
|
|
100
|
+
if (Array.isArray(value))
|
|
101
|
+
return value.map(clean);
|
|
102
|
+
if (value && typeof value === "object")
|
|
103
|
+
return Object.fromEntries(Object.entries(value)
|
|
104
|
+
.filter(([, v]) => v !== undefined)
|
|
105
|
+
.map(([k, v]) => [text(k), clean(v)]));
|
|
106
|
+
return value;
|
|
107
|
+
}
|
|
108
|
+
async function invoke(agent, input, kind) {
|
|
109
|
+
try {
|
|
110
|
+
return clean(await dispatch(agent, input, kind));
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
throw new Error(clean(e instanceof Error ? e.message : String(e)));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async function dispatch(agent, input, kind) {
|
|
117
|
+
if (!owner || agent !== owner)
|
|
118
|
+
throw Error("Plugin agent mismatch");
|
|
119
|
+
let args = {
|
|
120
|
+
command: kind,
|
|
121
|
+
endpoint: o.endpoint ?? "https://rpc.nodius.xyz",
|
|
122
|
+
journal: o.journalDir,
|
|
123
|
+
};
|
|
124
|
+
if (kind === "recent") {
|
|
125
|
+
const v = recent.parse(input);
|
|
126
|
+
args.limit = String(v.limit);
|
|
127
|
+
}
|
|
128
|
+
else if (kind === "send") {
|
|
129
|
+
const v = sendSchema.parse(input);
|
|
130
|
+
if (v.execute && o.allowExecution !== true)
|
|
131
|
+
throw Error("Host execution is disabled");
|
|
132
|
+
if (v.execute && o.ackIncompletePolicy !== true)
|
|
133
|
+
throw Error("Host incomplete policy acknowledgement required");
|
|
134
|
+
args["signed-tx-base64"] = v.signedTxBase64;
|
|
135
|
+
args.wallet = owner.wallet.publicKey.toBase58();
|
|
136
|
+
args["max-fee-credits"] = String(v.maxFeeCredits);
|
|
137
|
+
args.execute = v.execute;
|
|
138
|
+
if (v.operationId)
|
|
139
|
+
args["operation-id"] = v.operationId;
|
|
140
|
+
}
|
|
141
|
+
else if (kind === "status") {
|
|
142
|
+
const v = statusSchema.parse(input);
|
|
143
|
+
args["operation-id"] = v.operationId;
|
|
144
|
+
}
|
|
145
|
+
else if (kind === "monitor") {
|
|
146
|
+
const v = monitorSchema.parse(input);
|
|
147
|
+
args["max-fee-credits"] = String(v.maxFeeCredits);
|
|
148
|
+
args.seconds = String(v.seconds);
|
|
149
|
+
args["max-events"] = String(v.maxEvents);
|
|
150
|
+
if (v.mint)
|
|
151
|
+
args.mint = v.mint;
|
|
152
|
+
if (v.kinds)
|
|
153
|
+
args.kinds = v.kinds.join(",");
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
const v = tradeSchema.parse(input);
|
|
157
|
+
if (v.execute && o.allowExecution !== true)
|
|
158
|
+
throw Error("Host execution is disabled");
|
|
159
|
+
if (v.execute && !v.buildOnly && o.ackIncompletePolicy !== true)
|
|
160
|
+
throw Error("Host incomplete policy acknowledgement required");
|
|
161
|
+
args.command = v.side;
|
|
162
|
+
args.wallet = owner.wallet.publicKey.toBase58();
|
|
163
|
+
const map = {
|
|
164
|
+
amountSol: "amount-sol",
|
|
165
|
+
amountRaw: "amount-raw",
|
|
166
|
+
maxSol: "max-sol",
|
|
167
|
+
maxFeeCredits: "max-fee-credits",
|
|
168
|
+
slippageBps: "slippage-bps",
|
|
169
|
+
priorityFee: "priority-fee",
|
|
170
|
+
maxPriorityFee: "max-priority-fee",
|
|
171
|
+
maxPriorityLamports: "max-priority-lamports",
|
|
172
|
+
operationId: "operation-id",
|
|
173
|
+
buildOnly: "build-only",
|
|
174
|
+
acceptUnquotedBuildCharge: "accept-unquoted-build-charge",
|
|
175
|
+
};
|
|
176
|
+
for (const [k, value] of Object.entries(v)) {
|
|
177
|
+
if (k === "side")
|
|
178
|
+
continue;
|
|
179
|
+
args[map[k] ?? k] = typeof value === "boolean" ? value : String(value);
|
|
180
|
+
}
|
|
181
|
+
args["ack-incomplete-policy"] = o.ackIncompletePolicy === true;
|
|
182
|
+
}
|
|
183
|
+
const notifications = [];
|
|
184
|
+
let monitorPlan = {};
|
|
185
|
+
const result = await run(args, { NODIUS_API_KEY: o.apiKey }, (v) => {
|
|
186
|
+
if (kind === "monitor") {
|
|
187
|
+
if (v.state === "monitor-plan")
|
|
188
|
+
monitorPlan = v;
|
|
189
|
+
else
|
|
190
|
+
notifications.push(v);
|
|
191
|
+
}
|
|
192
|
+
}, {
|
|
193
|
+
publicKey: owner.wallet.publicKey,
|
|
194
|
+
signTransaction: (tx) => owner.wallet.signTransaction(tx),
|
|
195
|
+
});
|
|
196
|
+
return kind === "monitor"
|
|
197
|
+
? { ...monitorPlan, ...result, notifications }
|
|
198
|
+
: result;
|
|
199
|
+
}
|
|
200
|
+
const plugin = {
|
|
201
|
+
name: "nodius",
|
|
202
|
+
methods: {
|
|
203
|
+
nodiusSend: (input) => invoke(owner, input, "send"),
|
|
204
|
+
nodiusStatus: (input) => invoke(owner, input, "status"),
|
|
205
|
+
nodiusMonitor: (input) => invoke(owner, input, "monitor"),
|
|
206
|
+
nodiusRecent: (input = {}) => invoke(owner, input, "recent"),
|
|
207
|
+
nodiusTrade: (input) => invoke(owner, input, "trade"),
|
|
208
|
+
},
|
|
209
|
+
actions: [
|
|
210
|
+
{
|
|
211
|
+
name: "nodiusSend",
|
|
212
|
+
similes: [],
|
|
213
|
+
description: "Submit independently reviewed, already signed own-wallet transaction. Defaults plan; no trade instruction proof. Requires both host permissions.",
|
|
214
|
+
examples: [],
|
|
215
|
+
schema: sendSchema,
|
|
216
|
+
handler: (a, i) => invoke(a, i, "send"),
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
name: "nodiusStatus",
|
|
220
|
+
similes: [],
|
|
221
|
+
description: "Reconcile local operation status; never rebuild or rebroadcast",
|
|
222
|
+
examples: [],
|
|
223
|
+
schema: statusSchema,
|
|
224
|
+
handler: (a, i) => invoke(a, i, "status"),
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
name: "nodiusMonitor",
|
|
228
|
+
similes: [],
|
|
229
|
+
description: "Paid bounded signal monitor (<=300s, <=1000 events); no autonomous trading",
|
|
230
|
+
examples: [],
|
|
231
|
+
schema: monitorSchema,
|
|
232
|
+
handler: (a, i) => invoke(a, i, "monitor"),
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
name: "nodiusRecent",
|
|
236
|
+
similes: [],
|
|
237
|
+
description: "Read recent Nodius signals; never trades",
|
|
238
|
+
examples: [],
|
|
239
|
+
schema: recent,
|
|
240
|
+
handler: (a, i) => invoke(a, i, "recent"),
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
name: "nodiusTrade",
|
|
244
|
+
similes: [],
|
|
245
|
+
description: "Buy/sell defaults to read-only plan. Host must separately authorize charged execution and partial policy.",
|
|
246
|
+
examples: [],
|
|
247
|
+
schema: tradeActionSchema,
|
|
248
|
+
handler: (a, i) => invoke(a, i, "trade"),
|
|
249
|
+
},
|
|
250
|
+
],
|
|
251
|
+
initialize(agent) {
|
|
252
|
+
if (owner && owner !== agent)
|
|
253
|
+
throw Error("Plugin instance already bound to another agent");
|
|
254
|
+
owner = agent;
|
|
255
|
+
},
|
|
256
|
+
};
|
|
257
|
+
// Keep ZodObject identity for the published tool converters, but sanitize
|
|
258
|
+
// validation issues before the framework's pre-handler executor surfaces them.
|
|
259
|
+
for (const action of plugin.actions) {
|
|
260
|
+
const schema = action.schema.strict();
|
|
261
|
+
const sync = schema.safeParse.bind(schema), asyncParse = schema.safeParseAsync.bind(schema);
|
|
262
|
+
schema.safeParse = (data, params) => {
|
|
263
|
+
const r = sync(data, params);
|
|
264
|
+
return r.success
|
|
265
|
+
? r
|
|
266
|
+
: { success: false, error: new z.ZodError(clean(r.error.issues)) };
|
|
267
|
+
};
|
|
268
|
+
schema.safeParseAsync = async (data, params) => {
|
|
269
|
+
const r = await asyncParse(data, params);
|
|
270
|
+
return r.success
|
|
271
|
+
? r
|
|
272
|
+
: { success: false, error: new z.ZodError(clean(r.error.issues)) };
|
|
273
|
+
};
|
|
274
|
+
action.schema = schema;
|
|
275
|
+
}
|
|
276
|
+
return plugin;
|
|
277
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { PublicKey } from "@solana/web3.js";
|
|
2
|
+
import type { Transport } from "./transport.js";
|
|
3
|
+
/** Conservative admission, not a guarantee against dynamic CPI/fee changes. */
|
|
4
|
+
export declare function admitBuy(t: Transport, wallet: PublicKey, mint: PublicKey, amount: bigint, slippage: number, maxSol: bigint, priority: bigint): Promise<{
|
|
5
|
+
trade_bound_lamports: string;
|
|
6
|
+
account_rent_lamports: string;
|
|
7
|
+
rent_accounts: Record<string, string>;
|
|
8
|
+
network_fee_bound_lamports: string;
|
|
9
|
+
required_lamports: string;
|
|
10
|
+
note: string;
|
|
11
|
+
}>;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { PublicKey } from "@solana/web3.js";
|
|
2
|
+
import { unpackMint, getAccountLenForMint, getAccountLen, getExtensionTypes, getAccountTypeOfMintType, ExtensionType, } from "@solana/spl-token";
|
|
3
|
+
const PUMP = new PublicKey("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P");
|
|
4
|
+
const ATA = new PublicKey("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL");
|
|
5
|
+
const TOKEN = new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
|
|
6
|
+
const TOKEN22 = new PublicKey("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb");
|
|
7
|
+
const WSOL = new PublicKey("So11111111111111111111111111111111111111112");
|
|
8
|
+
function lamports(n) {
|
|
9
|
+
if (!Number.isSafeInteger(n) || n < 0)
|
|
10
|
+
throw Error("Unsafe admission lamports");
|
|
11
|
+
return BigInt(n);
|
|
12
|
+
}
|
|
13
|
+
/** Conservative admission, not a guarantee against dynamic CPI/fee changes. */
|
|
14
|
+
export async function admitBuy(t, wallet, mint, amount, slippage, maxSol, priority) {
|
|
15
|
+
const mintInfo = await t.connection.getAccountInfo(mint);
|
|
16
|
+
if (!mintInfo ||
|
|
17
|
+
mintInfo.executable ||
|
|
18
|
+
![TOKEN, TOKEN22].some((p) => p.equals(mintInfo.owner)))
|
|
19
|
+
throw Error("Buy admission mint account unavailable/unsupported");
|
|
20
|
+
let baseSize;
|
|
21
|
+
try {
|
|
22
|
+
const parsed = unpackMint(mint, mintInfo, mintInfo.owner);
|
|
23
|
+
if (!parsed.isInitialized)
|
|
24
|
+
throw Error("uninitialized");
|
|
25
|
+
baseSize = getAccountLenForMint(parsed);
|
|
26
|
+
if (mintInfo.owner.equals(TOKEN22))
|
|
27
|
+
baseSize = Math.max(baseSize, getAccountLen([
|
|
28
|
+
...getExtensionTypes(parsed.tlvData)
|
|
29
|
+
.map(getAccountTypeOfMintType)
|
|
30
|
+
.filter((t) => t !== ExtensionType.Uninitialized),
|
|
31
|
+
ExtensionType.ImmutableOwner,
|
|
32
|
+
]));
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
throw Error("Buy admission mint layout/extensions unsupported before builder");
|
|
36
|
+
}
|
|
37
|
+
const ata = (owner, m, token) => PublicKey.findProgramAddressSync([owner.toBuffer(), token.toBuffer(), m.toBuffer()], ATA)[0];
|
|
38
|
+
const pda = (name, key) => PublicKey.findProgramAddressSync([Buffer.from(name), key.toBuffer()], PUMP)[0];
|
|
39
|
+
const uva = pda("user_volume_accumulator", wallet);
|
|
40
|
+
const keys = [
|
|
41
|
+
ata(wallet, mint, mintInfo.owner),
|
|
42
|
+
ata(wallet, WSOL, TOKEN),
|
|
43
|
+
uva,
|
|
44
|
+
ata(uva, WSOL, TOKEN),
|
|
45
|
+
pda("bonding-curve", mint),
|
|
46
|
+
];
|
|
47
|
+
const accounts = await t.connection.getMultipleAccountsInfo(keys);
|
|
48
|
+
const curve = accounts[4];
|
|
49
|
+
if (!curve ||
|
|
50
|
+
!curve.owner.equals(PUMP) ||
|
|
51
|
+
curve.data.length < 81 ||
|
|
52
|
+
!curve.data
|
|
53
|
+
.subarray(0, 8)
|
|
54
|
+
.equals(Buffer.from([23, 183, 248, 55, 96, 216, 172, 96])))
|
|
55
|
+
throw Error("Buy admission curve unavailable/unsupported before builder");
|
|
56
|
+
const quote = curve.data.subarray(83, 115);
|
|
57
|
+
const v2 = curve.data.length >= 115 &&
|
|
58
|
+
(quote.equals(WSOL.toBuffer()) || quote.every((b) => b === 0));
|
|
59
|
+
// Current Pump IDL UserVolumeAccumulator serialized fields: discriminator8 +
|
|
60
|
+
// user32 + bool1 + four u64/i64 + bool1 + four cashback u64 = 106 bytes.
|
|
61
|
+
// Curve uses its live allocation; these builders do not emit extendAccount.
|
|
62
|
+
const sizes = [baseSize, 165, 106, 165, curve.data.length];
|
|
63
|
+
const names = [
|
|
64
|
+
"base_ata",
|
|
65
|
+
"wsol_ata",
|
|
66
|
+
"user_volume",
|
|
67
|
+
"user_volume_wsol_ata",
|
|
68
|
+
"curve",
|
|
69
|
+
];
|
|
70
|
+
let rent = 0n;
|
|
71
|
+
const rentAccounts = {};
|
|
72
|
+
for (let i = 0; i < keys.length; i++) {
|
|
73
|
+
if (!v2 && (i === 1 || i === 3))
|
|
74
|
+
continue;
|
|
75
|
+
const info = accounts[i];
|
|
76
|
+
const size = Math.max(sizes[i], info?.data.length ?? 0);
|
|
77
|
+
const minimum = lamports(await t.connection.getMinimumBalanceForRentExemption(size));
|
|
78
|
+
const existing = info ? lamports(info.lamports) : 0n;
|
|
79
|
+
const deficit = minimum > existing ? minimum - existing : 0n;
|
|
80
|
+
rent += deficit;
|
|
81
|
+
rentAccounts[names[i]] = deficit.toString();
|
|
82
|
+
}
|
|
83
|
+
const trade = (amount * BigInt(10000 + slippage) + 9999n) / 10000n;
|
|
84
|
+
const required = trade + rent + 5000n + priority;
|
|
85
|
+
const breakdown = {
|
|
86
|
+
trade_bound_lamports: trade.toString(),
|
|
87
|
+
account_rent_lamports: rent.toString(),
|
|
88
|
+
rent_accounts: rentAccounts,
|
|
89
|
+
network_fee_bound_lamports: (5000n + priority).toString(),
|
|
90
|
+
required_lamports: required.toString(),
|
|
91
|
+
note: "Conservative pre-build admission only; dynamic fees/CPI and account races remain outside this partial policy.",
|
|
92
|
+
};
|
|
93
|
+
if (required > maxSol)
|
|
94
|
+
throw Error(`Trade + conservative network/account rent exceeds max SOL before builder; required ${required} lamports (trade ${trade}, rent ${rent}, network ${5000n + priority})`);
|
|
95
|
+
return breakdown;
|
|
96
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { PublicKey, VersionedTransaction } from "@solana/web3.js";
|
|
2
|
+
import { Args } from "./config.js";
|
|
3
|
+
export declare function run(a: Args, env?: NodeJS.ProcessEnv, emit?: (v: any) => void, bridge?: {
|
|
4
|
+
publicKey: PublicKey;
|
|
5
|
+
signTransaction(tx: VersionedTransaction): Promise<VersionedTransaction>;
|
|
6
|
+
}): Promise<any>;
|