pyre-agent-kit 2.0.9 → 2.0.11
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/dist/agent.js +58 -39
- package/dist/chain.d.ts +1 -1
- package/dist/chain.js +4 -12
- package/dist/executor.js +3 -14
- package/dist/index.js +10 -4
- package/dist/stronghold.js +8 -51
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
package/dist/agent.js
CHANGED
|
@@ -34,7 +34,7 @@ const buildAgentPrompt = (agent, factions, leaderboardSnippet, intelSnippet, rec
|
|
|
34
34
|
? `\nYour on-chain memory (things you said before — this is who you are, stay consistent):\n${chainMemories.slice(-20).map(m => `- ${m}`).join('\n')}\n`
|
|
35
35
|
: '';
|
|
36
36
|
const voiceNudge = (0, util_1.pick)(defaults_1.VOICE_NUDGES);
|
|
37
|
-
return `You are an autonomous agent in Pyre, a faction warfare and strategy game on Solana, where you form both alliances and make enemies while trying to build the most powerful factions. Factions are like rival guilds — each with its own treasury, members, and reputation. You have your own opinions, allegiances, and grudges. Talk trash, call out agents, flex your position, challenge rivals, and coordinate with allies. Think competitive guild chat with real stakes. You make ONE decision per turn.
|
|
37
|
+
return `You are an autonomous agent in Pyre, a text-based open world faction warfare and strategy game on Solana. The goal is to WIN, become the strongest agent, and turn a profit. Accumulate power, dominate the leaderboard, crush rivals, and make your faction the strongest. Pyre is collaborative and you are also here where you form both alliances and make enemies while trying to build the most powerful factions. Factions are like rival guilds — each with its own treasury, members, and reputation. You have your own opinions, allegiances, and grudges. Talk trash, call out agents, flex your position, challenge rivals, and coordinate with allies. Think competitive guild chat with real stakes. You make ONE decision per turn.
|
|
38
38
|
|
|
39
39
|
SYMBOL is the token ticker from the leaderboard above (e.g. ${factions.slice(0, 3).map(f => f.symbol).join(', ') || 'STD, INC'}). NOT an address or wallet. ACTIONS that do not contain "message" do not accept a message and will not parse if a message is included.
|
|
40
40
|
|
|
@@ -42,50 +42,67 @@ RULES:
|
|
|
42
42
|
- Respond with EXACTLY one line, e.g.: JOIN ${factions[0]?.symbol || 'IRON'} "deploying capital, let's build"
|
|
43
43
|
- To mention an agent: @address (e.g. @${Math.random().toString(36).slice(2, 10)})
|
|
44
44
|
- The second word MUST be one of these faction symbols: ${factions.slice(0, 10).map(f => f.symbol).join(', ') || 'STD, INC'}. NOTHING ELSE is valid. Random alphanumeric strings like FVw8uGKk, CPQNA2G1, 3cAS5vEm are WALLET addresses, NOT faction symbols. Never use them as the second word.
|
|
45
|
-
- Messages must be under 80 characters, plain English, one short sentence
|
|
45
|
+
- Messages must be under 80 characters, plain English ONLY, one short sentence
|
|
46
|
+
- ENGLISH ONLY — no German, Spanish, Hindi, Chinese, or any other language. Never mix scripts or alphabets.
|
|
46
47
|
- Use "" for no message
|
|
47
48
|
- NO hashtags, NO angle brackets <>
|
|
48
49
|
- NO generic crypto slang
|
|
49
50
|
|
|
50
51
|
ACTIONS (pick exactly one — every action with "message" lets you talk in comms at the same time):
|
|
51
|
-
- JOIN SYMBOL "message"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
-
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
- JOIN SYMBOL "message" -
|
|
53
|
+
buy into a faction AND OPTIONALLY post a message.
|
|
54
|
+
JOIN is how you enter the war. You're putting SOL behind a faction — backing a side, growing the treasury, climbing the leaderboard.
|
|
55
|
+
Every join is a statement: you believe in this faction.
|
|
56
|
+
- DEFECT SYMBOL "message" -
|
|
57
|
+
sell tokens AND OPTIONALLY post a message.
|
|
58
|
+
DEFECT is a power move. If a faction is underperforming, if sentiment is bearish, if you've been infiltrating, or if you just want to take profits — DEFECT.
|
|
59
|
+
Selling is part of the game. The best agents know when to cut and run. You must hold the token to defect.
|
|
60
|
+
- REINFORCE SYMBOL "message" -
|
|
61
|
+
increase your position AND OPTIONALLY post a message.
|
|
62
|
+
REINFORCE is conviction. You already hold — now you're doubling down.
|
|
63
|
+
This increases your power in a faction and signals to everyone that you're not going anywhere.
|
|
64
|
+
Reinforce when you're bullish and want to flex your position.
|
|
65
|
+
- FUD SYMBOL "message" -
|
|
66
|
+
micro sell + trash talk a faction you hold.
|
|
67
|
+
FUD is psychological warfare. This action is designed to shake weak hands, tank sentiment, and set up bigger dumps.
|
|
68
|
+
Use it to destabilize a faction from the inside. Only works on factions you hold.
|
|
69
|
+
- INFILTRATE SYMBOL "message" -
|
|
70
|
+
secretly join a rival AND OPTIONALLY post a message.
|
|
71
|
+
INFILTRATE is the long con. You blend in, and when the time is right — DEFECT and dump everything.
|
|
72
|
+
The ultimate betrayal. Use it when you want to sabotage from within.
|
|
73
|
+
- MESSAGE SYMBOL "message" -
|
|
74
|
+
post in comms only (no buy/sell).
|
|
75
|
+
MESSAGE is the meta-game. No trade, just comms.
|
|
76
|
+
Coordinate with allies, drop intel, call out rivals, start beef, make predictions.
|
|
77
|
+
The social layer is where real power plays happen.
|
|
78
|
+
- RALLY SYMBOL -
|
|
79
|
+
show support (one-time per faction, no message).
|
|
80
|
+
RALLY is a one-time public signal of support.
|
|
81
|
+
No trade, no message — just planting your flag.
|
|
82
|
+
Choose wisely, you only get one per faction.
|
|
83
|
+
- WAR_LOAN SYMBOL -
|
|
84
|
+
borrow SOL against collateral (ascended factions only).
|
|
85
|
+
WAR_LOAN lets you borrow SOL against your tokens in an ascended faction. Use the leverage to make moves elsewhere — but if your collateral value drops, you risk getting sieged.
|
|
86
|
+
Only available after a faction ascends.
|
|
87
|
+
- REPAY_LOAN SYMBOL -
|
|
88
|
+
repay a loan.
|
|
89
|
+
REPAY_LOAN clears your debt and protects your collateral.
|
|
90
|
+
Pay back before someone liquidates you.
|
|
91
|
+
Smart agents manage their loans.
|
|
92
|
+
- SIEGE SYMBOL —
|
|
93
|
+
liquidate undercollateralized loan (ascended factions only).
|
|
94
|
+
SIEGE is the predator move. If another agent's war loan is undercollateralized, you can liquidate them and take a cut.
|
|
95
|
+
Ruthless, profitable, and only available on ascended factions.
|
|
96
|
+
- LAUNCH "name" —
|
|
97
|
+
create a new faction.
|
|
98
|
+
LAUNCH creates a brand new faction from scratch.
|
|
99
|
+
You're the founder — if it gains members and momentum, you're sitting on top. High risk, high reward.
|
|
62
100
|
|
|
63
|
-
|
|
101
|
+
Prefer actions that move tokens AND include a message — JOIN, DEFECT, FUD, INFILTRATE, REINFORCE all let you trade AND talk at the same time. However, experiment and find a strategy that is optimized for you to win.
|
|
64
102
|
|
|
65
|
-
|
|
103
|
+
Comms are where the real game happens — trash talk, alliances, intel drops, call-outs, and power plays. Be specific. Reference real agents, real numbers, real moves. Generic messages are boring. Have an opinion and say it loud. Mix it up — trade often, but keep the comms active too.
|
|
66
104
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
FUD is psychological warfare. A micro sell paired with trash talk — designed to shake weak hands, tank sentiment, and set up bigger dumps. Use it to destabilize a faction from the inside. Only works on factions you hold.
|
|
70
|
-
|
|
71
|
-
INFILTRATE is the long con. You secretly buy into a rival faction, blend in, and when the time is right — DEFECT and dump everything. The ultimate betrayal. Use it when you want to sabotage from within.
|
|
72
|
-
|
|
73
|
-
MESSAGE is the meta-game. No trade, just comms. Coordinate with allies, drop intel, call out rivals, start beef, make predictions. The social layer is where real power plays happen.
|
|
74
|
-
|
|
75
|
-
RALLY is a one-time public signal of support. No trade, no message — just planting your flag. Choose wisely, you only get one per faction.
|
|
76
|
-
|
|
77
|
-
WAR_LOAN lets you borrow SOL against your tokens in an ascended faction. Use the leverage to make moves elsewhere — but if your collateral value drops, you risk getting sieged. Only available after a faction ascends.
|
|
78
|
-
|
|
79
|
-
REPAY_LOAN clears your debt and protects your collateral. Pay back before someone liquidates you. Smart agents manage their loans.
|
|
80
|
-
|
|
81
|
-
SIEGE is the predator move. If another agent's war loan is undercollateralized, you can liquidate them and take a cut. Ruthless, profitable, and only available on ascended factions.
|
|
82
|
-
|
|
83
|
-
LAUNCH creates a brand new faction from scratch. You're the founder — if it gains members and momentum, you're sitting on top. High risk, high reward.
|
|
84
|
-
|
|
85
|
-
Examples:
|
|
86
|
-
${(0, faction_1.generateDynamicExamples)(factions, agent)}
|
|
87
|
-
|
|
88
|
-
The goal is to WIN. Accumulate power, dominate the leaderboard, crush rivals, and make your faction the strongest. Every action should move you closer to the top.
|
|
105
|
+
STATS:
|
|
89
106
|
|
|
90
107
|
Your address: ${agent.publicKey.slice(0, 8)}
|
|
91
108
|
Personality: ${agent.personality} — ${defaults_1.personalityDesc[agent.personality]}
|
|
@@ -103,10 +120,11 @@ Leaderboard preview: ${leaderboardSnippet}
|
|
|
103
120
|
Intel preview: ${intelSnippet}
|
|
104
121
|
${memoryBlock}${doNotRepeat}
|
|
105
122
|
|
|
106
|
-
Prefer actions that move tokens AND include a message — JOIN, DEFECT, FUD, INFILTRATE, REINFORCE all let you trade AND talk at the same time. Comms are where the real game happens — trash talk, alliances, intel drops, call-outs, and power plays. Be specific. Reference real agents, real numbers, real moves. Generic messages are boring. Have an opinion and say it loud. Mix it up — trade often, but keep the comms active too.
|
|
107
|
-
|
|
108
123
|
Use your messages to define who YOU are. Be unique — don't sound like every other agent. Explore different angles, develop your own voice, create a reputation. The pyre.world realm is vast — find your niche and own it. Keep it varied and conversational — talk like a real person, not a bot. Mix up your sentence structure, tone, and energy. Sometimes ask questions, sometimes make statements, sometimes joke around.
|
|
109
124
|
|
|
125
|
+
EXAMPLES:
|
|
126
|
+
${(0, faction_1.generateDynamicExamples)(factions, agent)}
|
|
127
|
+
|
|
110
128
|
Your response (one line only):`;
|
|
111
129
|
};
|
|
112
130
|
exports.buildAgentPrompt = buildAgentPrompt;
|
|
@@ -170,6 +188,7 @@ function parseLLMMatch(match, factions, agent, line, solRange) {
|
|
|
170
188
|
const action = rawAction;
|
|
171
189
|
const target = match[2] || match[3];
|
|
172
190
|
const rawMsg = match[4]?.trim()
|
|
191
|
+
?.replace(/[^\x20-\x7E@]/g, '') // strip non-ASCII (non-English characters)
|
|
173
192
|
?.replace(/^[\\\/]+/, '')
|
|
174
193
|
?.replace(/[\\\/]+$/, '')
|
|
175
194
|
?.replace(/^["']+|["']+$/g, '')
|
package/dist/chain.d.ts
CHANGED
|
@@ -47,7 +47,7 @@ export declare function actionIndex(action: Action): number;
|
|
|
47
47
|
* LLM-based personality classification.
|
|
48
48
|
* Falls back to formula scoring if LLM is unavailable.
|
|
49
49
|
*/
|
|
50
|
-
export declare function classifyPersonality(weights: number[], memos: string[], perFactionHistory?: Map<string, number[]>, llmGenerate?: (prompt: string) => Promise<string | null>, factionNames?: Map<string, string
|
|
50
|
+
export declare function classifyPersonality(weights: number[], memos: string[], perFactionHistory?: Map<string, number[]>, llmGenerate?: (prompt: string) => Promise<string | null>, factionNames?: Map<string, string>): Promise<Personality>;
|
|
51
51
|
/**
|
|
52
52
|
* Compute sentiment towards factions from on-chain interaction patterns.
|
|
53
53
|
*
|
package/dist/chain.js
CHANGED
|
@@ -375,10 +375,10 @@ function classifyPersonalityFormula(weights, memos) {
|
|
|
375
375
|
* LLM-based personality classification.
|
|
376
376
|
* Falls back to formula scoring if LLM is unavailable.
|
|
377
377
|
*/
|
|
378
|
-
async function classifyPersonality(weights, memos, perFactionHistory, llmGenerate, factionNames
|
|
378
|
+
async function classifyPersonality(weights, memos, perFactionHistory, llmGenerate, factionNames) {
|
|
379
379
|
const total = weights.reduce((a, b) => a + b, 0);
|
|
380
380
|
if (total === 0)
|
|
381
|
-
return
|
|
381
|
+
return 'loyalist';
|
|
382
382
|
if (llmGenerate) {
|
|
383
383
|
try {
|
|
384
384
|
const prompt = buildClassifyPrompt(weights, memos, perFactionHistory, factionNames);
|
|
@@ -387,21 +387,13 @@ async function classifyPersonality(weights, memos, perFactionHistory, llmGenerat
|
|
|
387
387
|
const cleaned = response.toLowerCase().replace(/[^a-z]/g, '').trim();
|
|
388
388
|
const valid = ['loyalist', 'mercenary', 'provocateur', 'scout', 'whale'];
|
|
389
389
|
const match = valid.find(p => cleaned.includes(p));
|
|
390
|
-
if (match)
|
|
391
|
-
if (currentPersonality && match !== currentPersonality && total < 20) {
|
|
392
|
-
return currentPersonality;
|
|
393
|
-
}
|
|
390
|
+
if (match)
|
|
394
391
|
return match;
|
|
395
|
-
}
|
|
396
392
|
}
|
|
397
393
|
}
|
|
398
394
|
catch { /* fall through to formula */ }
|
|
399
395
|
}
|
|
400
|
-
|
|
401
|
-
if (currentPersonality && formula !== currentPersonality && total < 20) {
|
|
402
|
-
return currentPersonality;
|
|
403
|
-
}
|
|
404
|
-
return formula;
|
|
396
|
+
return classifyPersonalityFormula(weights, memos);
|
|
405
397
|
}
|
|
406
398
|
// ─── Sentiment from On-Chain Data ────────────────────────────────
|
|
407
399
|
const POSITIVE_PATTERN = /strong|rally|bull|pump|rising|hold|loyal|power|growing|moon|love|trust|alpha|build|conviction/;
|
package/dist/executor.js
CHANGED
|
@@ -4,7 +4,6 @@ exports.executeAction = executeAction;
|
|
|
4
4
|
const web3_js_1 = require("@solana/web3.js");
|
|
5
5
|
const spl_token_1 = require("@solana/spl-token");
|
|
6
6
|
const pyre_world_kit_1 = require("pyre-world-kit");
|
|
7
|
-
const defaults_1 = require("./defaults");
|
|
8
7
|
const tx_1 = require("./tx");
|
|
9
8
|
const stronghold_1 = require("./stronghold");
|
|
10
9
|
const action_1 = require("./action");
|
|
@@ -181,19 +180,9 @@ const handlers = {
|
|
|
181
180
|
async stronghold(ctx) {
|
|
182
181
|
if (ctx.agent.hasStronghold)
|
|
183
182
|
return null;
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
const fundAmt = Math.floor((ctx.strongholdOpts?.fundSol ?? defaults_1.STRONGHOLD_FUND_SOL) * web3_js_1.LAMPORTS_PER_SOL);
|
|
188
|
-
try {
|
|
189
|
-
const fundResult = await (0, pyre_world_kit_1.fundStronghold)(ctx.connection, {
|
|
190
|
-
depositor: ctx.agent.publicKey, stronghold_creator: ctx.agent.publicKey, amount_sol: fundAmt,
|
|
191
|
-
});
|
|
192
|
-
await (0, tx_1.sendAndConfirm)(ctx.connection, ctx.agent.keypair, fundResult);
|
|
193
|
-
}
|
|
194
|
-
catch { /* fund failed, stronghold still created */ }
|
|
195
|
-
ctx.agent.lastAction = 'created stronghold';
|
|
196
|
-
return `created stronghold + funded ${(fundAmt / web3_js_1.LAMPORTS_PER_SOL).toFixed(1)} SOL`;
|
|
183
|
+
// Kit agents don't create vaults — they must be created on pyre.world
|
|
184
|
+
ctx.log(`[${ctx.agent.publicKey.slice(0, 8)}] no vault — create one at pyre.world and link agent key ${ctx.agent.publicKey}`);
|
|
185
|
+
return null;
|
|
197
186
|
},
|
|
198
187
|
async war_loan(ctx) {
|
|
199
188
|
const faction = findFaction(ctx.factions, ctx.decision.faction);
|
package/dist/index.js
CHANGED
|
@@ -43,6 +43,8 @@ async function createPyreAgent(config) {
|
|
|
43
43
|
// Runtime action tracking for live personality evolution
|
|
44
44
|
const actionCounts = new Array(14).fill(0);
|
|
45
45
|
const memoBuffer = [];
|
|
46
|
+
const driftScores = { loyalist: 0, mercenary: 0, provocateur: 0, scout: 0, whale: 0 };
|
|
47
|
+
const DRIFT_THRESHOLD = 3;
|
|
46
48
|
// Discover existing factions
|
|
47
49
|
try {
|
|
48
50
|
const result = await (0, pyre_world_kit_1.getFactions)(connection, { limit: 50, sort: 'newest' });
|
|
@@ -266,11 +268,15 @@ async function createPyreAgent(config) {
|
|
|
266
268
|
return false; // not enough data
|
|
267
269
|
const weights = (0, chain_1.weightsFromCounts)(actionCounts, seedPersonality);
|
|
268
270
|
const llmGen = llm ? (p) => llm.generate(p) : undefined;
|
|
269
|
-
const
|
|
271
|
+
const suggested = await (0, chain_1.classifyPersonality)(weights, memoBuffer, undefined, llmGen);
|
|
270
272
|
dynamicWeights = weights;
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
273
|
+
// Gradual drift — track suggestions, only flip after consistent lead
|
|
274
|
+
driftScores[suggested]++;
|
|
275
|
+
const currentScore = driftScores[state.personality];
|
|
276
|
+
const suggestedScore = driftScores[suggested];
|
|
277
|
+
if (suggested !== state.personality && suggestedScore - currentScore >= DRIFT_THRESHOLD) {
|
|
278
|
+
logger(`[${publicKey.slice(0, 8)}] personality drifted: ${state.personality} → ${suggested} (drift: ${suggestedScore} vs ${currentScore}, ${total} actions)`);
|
|
279
|
+
state.personality = suggested;
|
|
274
280
|
return true;
|
|
275
281
|
}
|
|
276
282
|
return false;
|
package/dist/stronghold.js
CHANGED
|
@@ -7,42 +7,17 @@ const tx_1 = require("./tx");
|
|
|
7
7
|
const defaults_1 = require("./defaults");
|
|
8
8
|
const ensureStronghold = async (connection, agent, log, opts) => {
|
|
9
9
|
const short = agent.publicKey.slice(0, 8);
|
|
10
|
-
const fundSol = opts?.fundSol ?? defaults_1.STRONGHOLD_FUND_SOL;
|
|
11
10
|
const topupThreshold = opts?.topupThresholdSol ?? defaults_1.STRONGHOLD_TOPUP_THRESHOLD_SOL;
|
|
12
11
|
const topupReserve = opts?.topupReserveSol ?? defaults_1.STRONGHOLD_TOPUP_RESERVE_SOL;
|
|
13
|
-
if
|
|
14
|
-
// Already known — just check if vault needs a top-up
|
|
15
|
-
try {
|
|
16
|
-
const existing = await (0, pyre_world_kit_1.getStronghold)(connection, agent.publicKey);
|
|
17
|
-
const vaultBal = existing?.sol_balance ?? 0;
|
|
18
|
-
const threshold = topupThreshold * pyre_world_kit_1.LAMPORTS_PER_SOL;
|
|
19
|
-
if (existing && vaultBal < threshold) {
|
|
20
|
-
const walletBal = await connection.getBalance(new web3_js_1.PublicKey(agent.publicKey));
|
|
21
|
-
const reserve = topupReserve * pyre_world_kit_1.LAMPORTS_PER_SOL;
|
|
22
|
-
const available = walletBal - reserve;
|
|
23
|
-
if (available > 0.01 * pyre_world_kit_1.LAMPORTS_PER_SOL) {
|
|
24
|
-
const fundAmt = Math.floor(available);
|
|
25
|
-
const fundResult = await (0, pyre_world_kit_1.fundStronghold)(connection, {
|
|
26
|
-
depositor: agent.publicKey,
|
|
27
|
-
stronghold_creator: agent.publicKey,
|
|
28
|
-
amount_sol: fundAmt,
|
|
29
|
-
});
|
|
30
|
-
await (0, tx_1.sendAndConfirm)(connection, agent.keypair, fundResult);
|
|
31
|
-
log(`[${short}] topped up vault with ${(fundAmt / pyre_world_kit_1.LAMPORTS_PER_SOL).toFixed(2)} SOL`);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
catch (err) {
|
|
36
|
-
log(`[${short}] vault topup check failed: ${err.message?.slice(0, 80) ?? err}`);
|
|
37
|
-
}
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
// Check if stronghold already exists on-chain (from a previous run)
|
|
12
|
+
// Check if stronghold exists on-chain
|
|
41
13
|
try {
|
|
42
14
|
const existing = await (0, pyre_world_kit_1.getStronghold)(connection, agent.publicKey);
|
|
43
15
|
if (existing) {
|
|
44
16
|
agent.hasStronghold = true;
|
|
45
|
-
|
|
17
|
+
// Top up if below threshold
|
|
18
|
+
const vaultBal = existing.sol_balance ?? 0;
|
|
19
|
+
const threshold = topupThreshold * pyre_world_kit_1.LAMPORTS_PER_SOL;
|
|
20
|
+
if (vaultBal < threshold) {
|
|
46
21
|
try {
|
|
47
22
|
const walletBal = await connection.getBalance(new web3_js_1.PublicKey(agent.publicKey));
|
|
48
23
|
const reserve = topupReserve * pyre_world_kit_1.LAMPORTS_PER_SOL;
|
|
@@ -63,26 +38,8 @@ const ensureStronghold = async (connection, agent, log, opts) => {
|
|
|
63
38
|
return;
|
|
64
39
|
}
|
|
65
40
|
}
|
|
66
|
-
catch { /*
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
await (0, tx_1.sendAndConfirm)(connection, agent.keypair, result);
|
|
70
|
-
agent.hasStronghold = true;
|
|
71
|
-
// Fund it so it can trade on DEX
|
|
72
|
-
const fundAmt = Math.floor(fundSol * pyre_world_kit_1.LAMPORTS_PER_SOL);
|
|
73
|
-
try {
|
|
74
|
-
const fundResult = await (0, pyre_world_kit_1.fundStronghold)(connection, {
|
|
75
|
-
depositor: agent.publicKey,
|
|
76
|
-
stronghold_creator: agent.publicKey,
|
|
77
|
-
amount_sol: fundAmt,
|
|
78
|
-
});
|
|
79
|
-
await (0, tx_1.sendAndConfirm)(connection, agent.keypair, fundResult);
|
|
80
|
-
}
|
|
81
|
-
catch { /* fund failed, stronghold still created */ }
|
|
82
|
-
log(`[${short}] auto-created stronghold`);
|
|
83
|
-
}
|
|
84
|
-
catch (err) {
|
|
85
|
-
log(`[${short}] failed to create stronghold: ${err.message?.slice(0, 80)}`);
|
|
86
|
-
}
|
|
41
|
+
catch { /* fetch failed */ }
|
|
42
|
+
// No vault found — user needs to create one on pyre.world
|
|
43
|
+
log(`[${short}] no vault found — create one at pyre.world and link agent key ${agent.publicKey}`);
|
|
87
44
|
};
|
|
88
45
|
exports.ensureStronghold = ensureStronghold;
|
package/dist/types.d.ts
CHANGED
|
@@ -64,7 +64,7 @@ export interface PyreAgentConfig {
|
|
|
64
64
|
solRange?: [number, number];
|
|
65
65
|
/** Max factions this agent can found (default: 2) */
|
|
66
66
|
maxFoundedFactions?: number;
|
|
67
|
-
/** SOL to fund stronghold vault
|
|
67
|
+
/** SOL to fund stronghold vault when topping up */
|
|
68
68
|
strongholdFundSol?: number;
|
|
69
69
|
/** Vault balance threshold below which to top up */
|
|
70
70
|
strongholdTopupThresholdSol?: number;
|