@elisym/mcp 0.3.1 → 0.3.3
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/README.md +9 -9
- package/dist/index.js +99 -70
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -106,15 +106,15 @@ The bootstrap step is unchanged - the wizard collects the passphrase interactive
|
|
|
106
106
|
|
|
107
107
|
## Environment Variables
|
|
108
108
|
|
|
109
|
-
| Variable | Description
|
|
110
|
-
| --------------------------- |
|
|
111
|
-
| `ELISYM_AGENT` | Load agent from `~/.elisym/agents/<name>/`
|
|
112
|
-
| `ELISYM_NOSTR_SECRET` | Nostr secret key (hex or nsec) for ephemeral mode
|
|
113
|
-
| `ELISYM_AGENT_NAME` | Agent display name (default: mcp-agent)
|
|
114
|
-
| `ELISYM_NETWORK` | Solana network for ephemeral mode
|
|
115
|
-
| `ELISYM_PASSPHRASE` | Passphrase for encrypted agent configs (optional)
|
|
116
|
-
| `ELISYM_ALLOW_WITHDRAWAL` | Set to `1` to override per-agent `security.withdrawals_enabled` flag (CI use)
|
|
117
|
-
| `ELISYM_ALLOW_AGENT_SWITCH` | Set to `1` to override per-agent `security.agent_switch_enabled` flag
|
|
109
|
+
| Variable | Description |
|
|
110
|
+
| --------------------------- | ------------------------------------------------------------------------------- |
|
|
111
|
+
| `ELISYM_AGENT` | Load agent from `~/.elisym/agents/<name>/` |
|
|
112
|
+
| `ELISYM_NOSTR_SECRET` | Nostr secret key (hex or nsec) for ephemeral mode |
|
|
113
|
+
| `ELISYM_AGENT_NAME` | Agent display name (default: mcp-agent) |
|
|
114
|
+
| `ELISYM_NETWORK` | Solana network for ephemeral mode. Only `devnet` is supported (default: devnet) |
|
|
115
|
+
| `ELISYM_PASSPHRASE` | Passphrase for encrypted agent configs (optional) |
|
|
116
|
+
| `ELISYM_ALLOW_WITHDRAWAL` | Set to `1` to override per-agent `security.withdrawals_enabled` flag (CI use) |
|
|
117
|
+
| `ELISYM_ALLOW_AGENT_SWITCH` | Set to `1` to override per-agent `security.agent_switch_enabled` flag |
|
|
118
118
|
|
|
119
119
|
## Usage Examples
|
|
120
120
|
|
package/dist/index.js
CHANGED
|
@@ -42,8 +42,16 @@ function agentsDir() {
|
|
|
42
42
|
function agentConfigPath(name) {
|
|
43
43
|
return join(agentsDir(), name, "config.json");
|
|
44
44
|
}
|
|
45
|
-
function coerceNetwork(raw) {
|
|
46
|
-
|
|
45
|
+
function coerceNetwork(raw, agentName) {
|
|
46
|
+
if (raw === void 0 || raw === "devnet") {
|
|
47
|
+
return "devnet";
|
|
48
|
+
}
|
|
49
|
+
if (raw === "mainnet") {
|
|
50
|
+
throw new Error(
|
|
51
|
+
`Agent "${agentName}" is configured for mainnet, which is not supported until the elisym-config program is deployed there. Re-create the agent with --network devnet: rm -rf ~/.elisym/agents/${agentName} && elisym-mcp init ${agentName} --network devnet`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
throw new Error(`Agent "${agentName}" has unsupported network "${raw}". Expected "devnet".`);
|
|
47
55
|
}
|
|
48
56
|
async function loadAgentConfig(name, passphrase) {
|
|
49
57
|
validateAgentName(name);
|
|
@@ -65,7 +73,7 @@ async function loadAgentConfig(name, passphrase) {
|
|
|
65
73
|
`Failed to load agent "${name}": ${msg}. If this config was created by an earlier version, delete ~/.elisym/agents/${name} and run "elisym-mcp init ${name}" again.`
|
|
66
74
|
);
|
|
67
75
|
}
|
|
68
|
-
const network = coerceNetwork(config.wallet?.network ?? config.payments?.[0]?.network);
|
|
76
|
+
const network = coerceNetwork(config.wallet?.network ?? config.payments?.[0]?.network, name);
|
|
69
77
|
return {
|
|
70
78
|
nostrSecretKey: config.identity.secret_key,
|
|
71
79
|
solanaSecretKey: config.wallet?.secret_key,
|
|
@@ -160,18 +168,17 @@ async function listAgentNames() {
|
|
|
160
168
|
return [];
|
|
161
169
|
}
|
|
162
170
|
}
|
|
163
|
-
function rpcUrlFor(
|
|
164
|
-
return
|
|
171
|
+
function rpcUrlFor(_network) {
|
|
172
|
+
return "https://api.devnet.solana.com";
|
|
165
173
|
}
|
|
166
|
-
async function fetchProtocolConfig(
|
|
167
|
-
const
|
|
168
|
-
const
|
|
169
|
-
const rpc = createSolanaRpc(rpcUrlFor(cluster));
|
|
174
|
+
async function fetchProtocolConfig(_network) {
|
|
175
|
+
const programId = getProtocolProgramId("devnet");
|
|
176
|
+
const rpc = createSolanaRpc(rpcUrlFor());
|
|
170
177
|
const config = await getProtocolConfig(rpc, programId, { forceRefresh: true });
|
|
171
178
|
return { feeBps: config.feeBps, treasury: config.treasury };
|
|
172
179
|
}
|
|
173
|
-
function explorerClusterFor(
|
|
174
|
-
return
|
|
180
|
+
function explorerClusterFor(_network) {
|
|
181
|
+
return "devnet";
|
|
175
182
|
}
|
|
176
183
|
var RateLimiter = class {
|
|
177
184
|
constructor(maxCalls, windowSecs) {
|
|
@@ -632,7 +639,10 @@ var CreateAgentSchema = z.object({
|
|
|
632
639
|
// customer-mode in 0.1.x and never publishes a NIP-89 capability card,
|
|
633
640
|
// so an advertised capability list would be misleading. Provider-mode
|
|
634
641
|
// (0.2.0) will reintroduce this field.
|
|
635
|
-
|
|
642
|
+
// Only devnet is supported until the elisym-config program ships on mainnet.
|
|
643
|
+
// Mainnet was previously advertised here but every paid flow then crashed at
|
|
644
|
+
// payment time - rejecting at schema level surfaces the error up front.
|
|
645
|
+
network: z.enum(["devnet"]).default("devnet"),
|
|
636
646
|
passphrase: z.string().optional().describe("Optional passphrase; if set, secret keys are encrypted at rest."),
|
|
637
647
|
activate: z.boolean().default(true)
|
|
638
648
|
});
|
|
@@ -1072,6 +1082,7 @@ function sanitizeField(input, maxLen) {
|
|
|
1072
1082
|
}
|
|
1073
1083
|
|
|
1074
1084
|
// src/tools/customer.ts
|
|
1085
|
+
var PRE_PING_TIMEOUT_MS = 5e3;
|
|
1075
1086
|
var CreateJobSchema = z.object({
|
|
1076
1087
|
input: z.string().describe("The job prompt/input sent to the provider."),
|
|
1077
1088
|
capability: z.string().min(1).max(64).default("general").describe("Short tag selecting which capability of the provider to invoke."),
|
|
@@ -1192,18 +1203,34 @@ function makePaymentFeedbackHandler(opts) {
|
|
|
1192
1203
|
);
|
|
1193
1204
|
return;
|
|
1194
1205
|
}
|
|
1195
|
-
|
|
1206
|
+
let parsedRequest;
|
|
1207
|
+
try {
|
|
1208
|
+
parsedRequest = JSON.parse(paymentRequest);
|
|
1209
|
+
} catch {
|
|
1210
|
+
opts.rejectPayment(new Error("Provider sent a malformed payment_request (not valid JSON)."));
|
|
1211
|
+
return;
|
|
1212
|
+
}
|
|
1213
|
+
const signedAmount = typeof parsedRequest.amount === "number" && Number.isInteger(parsedRequest.amount) && parsedRequest.amount > 0 ? parsedRequest.amount : void 0;
|
|
1214
|
+
if (amount !== void 0 && amount > 0 && signedAmount !== void 0 && amount !== signedAmount) {
|
|
1196
1215
|
opts.rejectPayment(
|
|
1197
1216
|
new Error(
|
|
1198
|
-
`Payment
|
|
1217
|
+
`Payment request mismatch: feedback tag amount=${amount} differs from signed amount=${signedAmount}. Refusing to proceed.`
|
|
1199
1218
|
)
|
|
1200
1219
|
);
|
|
1201
1220
|
return;
|
|
1202
1221
|
}
|
|
1203
|
-
if (opts.maxPriceLamports
|
|
1222
|
+
if (opts.maxPriceLamports === void 0 && signedAmount !== void 0) {
|
|
1204
1223
|
opts.rejectPayment(
|
|
1205
1224
|
new Error(
|
|
1206
|
-
`
|
|
1225
|
+
`Payment of ${formatSol(BigInt(signedAmount))} required but no max_price_lamports set. Retry with max_price_lamports to approve.`
|
|
1226
|
+
)
|
|
1227
|
+
);
|
|
1228
|
+
return;
|
|
1229
|
+
}
|
|
1230
|
+
if (opts.maxPriceLamports !== void 0 && signedAmount !== void 0 && signedAmount > opts.maxPriceLamports) {
|
|
1231
|
+
opts.rejectPayment(
|
|
1232
|
+
new Error(
|
|
1233
|
+
`Price ${formatSol(BigInt(signedAmount))} exceeds max ${formatSol(BigInt(opts.maxPriceLamports))}`
|
|
1207
1234
|
)
|
|
1208
1235
|
);
|
|
1209
1236
|
return;
|
|
@@ -1211,7 +1238,7 @@ function makePaymentFeedbackHandler(opts) {
|
|
|
1211
1238
|
if (!opts.agent.solanaKeypair) {
|
|
1212
1239
|
opts.resolveNoWallet(
|
|
1213
1240
|
`Payment required but no Solana wallet configured.
|
|
1214
|
-
Amount: ${
|
|
1241
|
+
Amount: ${signedAmount !== void 0 ? formatSol(BigInt(signedAmount)) : "unknown"}
|
|
1215
1242
|
Payment request: ${paymentRequest}`
|
|
1216
1243
|
);
|
|
1217
1244
|
return;
|
|
@@ -1445,6 +1472,12 @@ ${wrapped}`);
|
|
|
1445
1472
|
const timeout = Math.min(input.timeout_secs, MAX_TIMEOUT_SECS) * 1e3;
|
|
1446
1473
|
const agent = ctx.active();
|
|
1447
1474
|
const providerPubkey = decodeNpub(input.provider_npub);
|
|
1475
|
+
const ping = await agent.client.ping.pingAgent(providerPubkey, PRE_PING_TIMEOUT_MS);
|
|
1476
|
+
if (!ping.online) {
|
|
1477
|
+
return errorResult(
|
|
1478
|
+
`Provider ${input.provider_npub} is offline. Run search_agents to find currently-online providers.`
|
|
1479
|
+
);
|
|
1480
|
+
}
|
|
1448
1481
|
const providers = await agent.client.discovery.fetchAgents(agent.network);
|
|
1449
1482
|
const provider = providers.find((a) => a.npub === input.provider_npub);
|
|
1450
1483
|
if (!provider) {
|
|
@@ -1526,6 +1559,12 @@ ${result}`);
|
|
|
1526
1559
|
const agent = ctx.active();
|
|
1527
1560
|
const providerPubkey = decodeNpub(input.provider_npub);
|
|
1528
1561
|
const dTag = toDTag(input.capability);
|
|
1562
|
+
const ping = await agent.client.ping.pingAgent(providerPubkey, PRE_PING_TIMEOUT_MS);
|
|
1563
|
+
if (!ping.online) {
|
|
1564
|
+
return errorResult(
|
|
1565
|
+
`Provider ${input.provider_npub} is offline. Run search_agents to find currently-online providers.`
|
|
1566
|
+
);
|
|
1567
|
+
}
|
|
1529
1568
|
const agents = await agent.client.discovery.fetchAgents(agent.network);
|
|
1530
1569
|
const provider = agents.find((a) => a.npub === input.provider_npub);
|
|
1531
1570
|
if (!provider) {
|
|
@@ -1629,7 +1668,7 @@ ${result}`);
|
|
|
1629
1668
|
var GetDashboardSchema = z.object({
|
|
1630
1669
|
top_n: z.number().int().min(1).max(100).default(10),
|
|
1631
1670
|
chain: z.enum(["solana"]).default("solana"),
|
|
1632
|
-
network: z.enum(["devnet"
|
|
1671
|
+
network: z.enum(["devnet"]).optional(),
|
|
1633
1672
|
timeout_secs: z.number().int().min(1).max(60).default(15)
|
|
1634
1673
|
});
|
|
1635
1674
|
var dashboardTools = [
|
|
@@ -1667,6 +1706,8 @@ ${text}`);
|
|
|
1667
1706
|
}
|
|
1668
1707
|
})
|
|
1669
1708
|
];
|
|
1709
|
+
var LAST_SEEN_ONLINE_WINDOW_SECS = 10 * 60;
|
|
1710
|
+
var SEARCH_PING_TIMEOUT_MS = 3e3;
|
|
1670
1711
|
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
1671
1712
|
"a",
|
|
1672
1713
|
"an",
|
|
@@ -1800,28 +1841,19 @@ var SearchAgentsSchema = z.object({
|
|
|
1800
1841
|
capabilities: z.array(z.string()).min(1).describe("OR-matched substring filter on agent names, descriptions, and capability tags."),
|
|
1801
1842
|
query: z.string().optional().describe("Optional secondary scoring for re-ranking. Omit when you have precise tokens."),
|
|
1802
1843
|
max_price_lamports: z.number().int().optional(),
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
recently_active_only: z.boolean().default(true).describe(
|
|
1806
|
-
"If true, only return agents with job activity in the last hour. Not a liveness probe."
|
|
1844
|
+
include_offline: z.boolean().default(false).describe(
|
|
1845
|
+
"If true, skip the live online check and return agents regardless of reachability. Default: false - only currently-online agents are returned."
|
|
1807
1846
|
)
|
|
1808
1847
|
});
|
|
1809
1848
|
var ListCapabilitiesSchema = z.object({});
|
|
1810
1849
|
var GetIdentitySchema = z.object({});
|
|
1811
|
-
var PingAgentSchema = z.object({
|
|
1812
|
-
agent_npub: z.string(),
|
|
1813
|
-
// single source of truth for the default.
|
|
1814
|
-
timeout_secs: z.number().int().min(1).max(600).default(15)
|
|
1815
|
-
});
|
|
1816
1850
|
var discoveryTools = [
|
|
1817
1851
|
defineTool({
|
|
1818
1852
|
name: "search_agents",
|
|
1819
|
-
|
|
1820
|
-
// Keep the operational rules short; schema `.describe()` fields carry the detail.
|
|
1821
|
-
description: "Search AI agents. `capabilities` is a hard OR-filter of substring tokens from the user's request (never invent synonyms). `query` is optional re-ranking; omit if not needed.",
|
|
1853
|
+
description: "Search AI agents currently online on elisym. `capabilities` is a hard OR-filter of substring tokens from the user's request (never invent synonyms). `query` is optional re-ranking; omit if not needed. Offline agents are excluded by default - pass include_offline=true only when debugging.",
|
|
1822
1854
|
schema: SearchAgentsSchema,
|
|
1823
1855
|
async handler(ctx, input) {
|
|
1824
|
-
const { capabilities, query, max_price_lamports,
|
|
1856
|
+
const { capabilities, query, max_price_lamports, include_offline } = input;
|
|
1825
1857
|
if (capabilities.length > MAX_CAPABILITIES) {
|
|
1826
1858
|
return errorResult(`Too many capabilities (max ${MAX_CAPABILITIES})`);
|
|
1827
1859
|
}
|
|
@@ -1834,10 +1866,6 @@ var discoveryTools = [
|
|
|
1834
1866
|
)
|
|
1835
1867
|
)
|
|
1836
1868
|
);
|
|
1837
|
-
if (recently_active_only) {
|
|
1838
|
-
const activeThreshold = Math.floor(Date.now() / 1e3) - 60 * 60;
|
|
1839
|
-
filtered = filtered.filter((a) => a.lastSeen >= activeThreshold);
|
|
1840
|
-
}
|
|
1841
1869
|
if (max_price_lamports !== void 0) {
|
|
1842
1870
|
filtered = filtered.filter(
|
|
1843
1871
|
(a) => a.cards.some(
|
|
@@ -1845,6 +1873,25 @@ var discoveryTools = [
|
|
|
1845
1873
|
)
|
|
1846
1874
|
);
|
|
1847
1875
|
}
|
|
1876
|
+
if (!include_offline) {
|
|
1877
|
+
const freshThreshold = Math.floor(Date.now() / 1e3) - LAST_SEEN_ONLINE_WINDOW_SECS;
|
|
1878
|
+
filtered = filtered.filter((a) => a.lastSeen >= freshThreshold);
|
|
1879
|
+
if (filtered.length > 0) {
|
|
1880
|
+
const probes = await Promise.allSettled(
|
|
1881
|
+
filtered.map(
|
|
1882
|
+
(candidate) => agent.client.ping.pingAgent(candidate.pubkey, SEARCH_PING_TIMEOUT_MS)
|
|
1883
|
+
)
|
|
1884
|
+
);
|
|
1885
|
+
const survivors = [];
|
|
1886
|
+
filtered.forEach((candidate, index) => {
|
|
1887
|
+
const probe = probes[index];
|
|
1888
|
+
if (probe?.status === "fulfilled" && probe.value.online) {
|
|
1889
|
+
survivors.push(candidate);
|
|
1890
|
+
}
|
|
1891
|
+
});
|
|
1892
|
+
filtered = survivors;
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1848
1895
|
if (query) {
|
|
1849
1896
|
const isAscii = /^[\u0000-\u007F]*$/.test(query);
|
|
1850
1897
|
const words = query.toLowerCase().split(/\s+/).filter((w) => w.length > 1 && (!isAscii || !STOP_WORDS.has(w)));
|
|
@@ -1865,7 +1912,7 @@ var discoveryTools = [
|
|
|
1865
1912
|
}
|
|
1866
1913
|
if (filtered.length === 0) {
|
|
1867
1914
|
return textResult(
|
|
1868
|
-
|
|
1915
|
+
include_offline ? "No agents found matching those capabilities." : "No online agents found matching those capabilities. Retry shortly or pass include_offline=true to see unreachable matches."
|
|
1869
1916
|
);
|
|
1870
1917
|
}
|
|
1871
1918
|
const results = filtered.map((a) => ({
|
|
@@ -1927,31 +1974,6 @@ ${text}`);
|
|
|
1927
1974
|
)
|
|
1928
1975
|
);
|
|
1929
1976
|
}
|
|
1930
|
-
}),
|
|
1931
|
-
defineTool({
|
|
1932
|
-
name: "ping_agent",
|
|
1933
|
-
description: "Ping an agent to check if it's online. Sends an encrypted heartbeat and waits for a pong.",
|
|
1934
|
-
schema: PingAgentSchema,
|
|
1935
|
-
async handler(ctx, input) {
|
|
1936
|
-
ctx.toolRateLimiter.check();
|
|
1937
|
-
const { agent_npub, timeout_secs } = input;
|
|
1938
|
-
const agent = ctx.active();
|
|
1939
|
-
let pubkey;
|
|
1940
|
-
try {
|
|
1941
|
-
const decoded = nip19.decode(agent_npub);
|
|
1942
|
-
if (decoded.type !== "npub") {
|
|
1943
|
-
return errorResult(`Expected npub, got ${decoded.type}`);
|
|
1944
|
-
}
|
|
1945
|
-
pubkey = decoded.data;
|
|
1946
|
-
} catch {
|
|
1947
|
-
return errorResult(`Invalid npub: ${agent_npub}`);
|
|
1948
|
-
}
|
|
1949
|
-
const timeoutMs = timeout_secs * 1e3;
|
|
1950
|
-
const result = await agent.client.ping.pingAgent(pubkey, timeoutMs);
|
|
1951
|
-
return textResult(
|
|
1952
|
-
result.online ? `Agent ${agent_npub} is online.` : `Agent ${agent_npub} did not respond within ${timeout_secs}s.`
|
|
1953
|
-
);
|
|
1954
|
-
}
|
|
1955
1977
|
})
|
|
1956
1978
|
];
|
|
1957
1979
|
var GetBalanceSchema = z.object({});
|
|
@@ -2415,9 +2437,14 @@ program.action(async () => {
|
|
|
2415
2437
|
}
|
|
2416
2438
|
const client = new ElisymClient({ relays: RELAYS });
|
|
2417
2439
|
const name = process.env.ELISYM_AGENT_NAME ?? "mcp-agent";
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2440
|
+
if (process.env.ELISYM_NETWORK && process.env.ELISYM_NETWORK !== "devnet") {
|
|
2441
|
+
console.error(
|
|
2442
|
+
`ELISYM_NETWORK="${process.env.ELISYM_NETWORK}" is not supported. Only "devnet" is available until the on-chain protocol program ships on mainnet.`
|
|
2443
|
+
);
|
|
2444
|
+
process.exit(1);
|
|
2445
|
+
}
|
|
2446
|
+
ctx.register({ client, identity, name, network: "devnet", security: {} });
|
|
2447
|
+
console.error(`Ephemeral agent: ${name} (devnet)`);
|
|
2421
2448
|
} else {
|
|
2422
2449
|
const names = (await listAgentNames()).slice().sort();
|
|
2423
2450
|
if (names.length > 0) {
|
|
@@ -2440,7 +2467,7 @@ program.action(async () => {
|
|
|
2440
2467
|
}
|
|
2441
2468
|
await startServer(ctx);
|
|
2442
2469
|
});
|
|
2443
|
-
program.command("init [name]").description("Create a new agent identity").option("-d, --description <desc>", "Agent description", "Elisym MCP agent").option("-n, --network <network>", "Solana network (devnet
|
|
2470
|
+
program.command("init [name]").description("Create a new agent identity").option("-d, --description <desc>", "Agent description", "Elisym MCP agent").option("-n, --network <network>", "Solana network (devnet only)", "devnet").option("--install", "Also install into MCP clients").action(async (name, options) => {
|
|
2444
2471
|
const { default: inquirer } = await import('inquirer');
|
|
2445
2472
|
if (!name) {
|
|
2446
2473
|
const answers = await inquirer.prompt([
|
|
@@ -2460,8 +2487,8 @@ program.command("init [name]").description("Create a new agent identity").option
|
|
|
2460
2487
|
type: "list",
|
|
2461
2488
|
name: "network",
|
|
2462
2489
|
message: "Solana network:",
|
|
2463
|
-
//
|
|
2464
|
-
choices: ["devnet"
|
|
2490
|
+
// Only devnet is supported until the elisym-config program ships on mainnet.
|
|
2491
|
+
choices: ["devnet"],
|
|
2465
2492
|
default: "devnet"
|
|
2466
2493
|
}
|
|
2467
2494
|
]);
|
|
@@ -2469,8 +2496,10 @@ program.command("init [name]").description("Create a new agent identity").option
|
|
|
2469
2496
|
options.description = answers.description;
|
|
2470
2497
|
options.network = answers.network;
|
|
2471
2498
|
}
|
|
2472
|
-
if (options.network !== "devnet"
|
|
2473
|
-
console.error(
|
|
2499
|
+
if (options.network !== "devnet") {
|
|
2500
|
+
console.error(
|
|
2501
|
+
`Network must be "devnet", got "${options.network}". Mainnet is not supported until the on-chain protocol program is deployed.`
|
|
2502
|
+
);
|
|
2474
2503
|
process.exit(1);
|
|
2475
2504
|
}
|
|
2476
2505
|
const { passphrase } = await inquirer.prompt([
|
|
@@ -2492,7 +2521,7 @@ program.command("init [name]").description("Create a new agent identity").option
|
|
|
2492
2521
|
nostrSecretKey: Buffer.from(nostrSecretKey).toString("hex"),
|
|
2493
2522
|
solanaSecretKey: bs58.encode(solanaSecretBytes),
|
|
2494
2523
|
solanaAddress: solanaSigner.address,
|
|
2495
|
-
network:
|
|
2524
|
+
network: "devnet",
|
|
2496
2525
|
security: { withdrawals_enabled: false, agent_switch_enabled: false },
|
|
2497
2526
|
passphrase: passphrase || void 0
|
|
2498
2527
|
});
|