pyre-world-kit 3.1.2 → 3.2.0

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/tests/test_e2e.ts CHANGED
@@ -157,7 +157,7 @@ async function main() {
157
157
 
158
158
  assert(kit.state.tick === 1, `tick incremented to 1: ${kit.state.tick}`)
159
159
  assert(kit.state.state!.actionCounts.launch === 1, `launch count = 1`)
160
- assert(kit.state.getSentiment(mint) === 3, `launch sentiment = +3: ${kit.state.getSentiment(mint)}`)
160
+ assert(kit.state.getSentiment(mint) === 0.3, `launch sentiment = +0.3: ${kit.state.getSentiment(mint)}`)
161
161
  assert(kit.state.history.length === 1, `history has 1 entry`)
162
162
 
163
163
  // ═══════════════════════════════════════════════════════════════════
@@ -199,8 +199,9 @@ async function main() {
199
199
  // State assertions
200
200
  assert(kit.state.tick === 2, `tick = 2: ${kit.state.tick}`)
201
201
  assert(kit.state.state!.actionCounts.join === 1, `join count = 1`)
202
- assert(kit.state.getSentiment(mint) === 4, `sentiment after launch(+3) + join(+1) = 4: ${kit.state.getSentiment(mint)}`)
203
- assert(kit.state.getBalance(mint) > 0, `state holdings updated: ${kit.state.getBalance(mint)}`)
202
+ assert(kit.state.getSentiment(mint) === 0.4, `sentiment after launch(+0.3) + join(+0.1) = 0.4: ${kit.state.getSentiment(mint)}`)
203
+ const holdingsAfterJoin = await kit.state.getBalance(mint)
204
+ assert(holdingsAfterJoin > 0, `state holdings updated: ${holdingsAfterJoin}`)
204
205
 
205
206
  // ═══════════════════════════════════════════════════════════════════
206
207
  // TEST: VAULT SELL (defect) + SENTIMENT
@@ -242,7 +243,7 @@ async function main() {
242
243
 
243
244
  // State assertions
244
245
  assert(kit.state.tick === 3, `tick = 3: ${kit.state.tick}`)
245
- assert(kit.state.getSentiment(mint) === sentimentBeforeDefect - 2, `defect drops sentiment by 2: ${sentimentBeforeDefect} → ${kit.state.getSentiment(mint)}`)
246
+ assert(kit.state.getSentiment(mint) === sentimentBeforeDefect - 0.2, `defect drops sentiment by 0.2: ${sentimentBeforeDefect} → ${kit.state.getSentiment(mint)}`)
246
247
 
247
248
  // ═══════════════════════════════════════════════════════════════════
248
249
  // TEST: FUD + SENTIMENT
@@ -265,12 +266,12 @@ async function main() {
265
266
  const fudTokenDelta = fudTokensBefore - fudTokensAfter
266
267
 
267
268
  console.log(` POST — tokens: ${fudTokensAfter}, sentiment: ${kit.state.getSentiment(mint)}`)
268
- console.log(` TOKEN DELTA: ${fudTokenDelta} (expect ~100)`)
269
+ console.log(` TOKEN DELTA: ${fudTokenDelta} (expect ~10M raw = 10 tokens)`)
269
270
 
270
271
  assert(fudTokenDelta > 0, `FUD sold tokens: ${fudTokenDelta}`)
271
- assert(fudTokenDelta <= 100, `FUD micro amount: ${fudTokenDelta}`)
272
+ assert(fudTokenDelta <= 10_000_000, `FUD micro amount (10 tokens raw): ${fudTokenDelta}`)
272
273
  assert(kit.state.tick === 4, `tick = 4: ${kit.state.tick}`)
273
- assert(kit.state.getSentiment(mint) === sentimentBeforeFud - 1.5, `fud drops sentiment by 1.5: ${kit.state.getSentiment(mint)}`)
274
+ assert(kit.state.getSentiment(mint) === sentimentBeforeFud - 0.15, `fud drops sentiment by 0.15: ${kit.state.getSentiment(mint)}`)
274
275
 
275
276
  // ═══════════════════════════════════════════════════════════════════
276
277
  // TEST: MESSAGE + STATE
@@ -287,7 +288,7 @@ async function main() {
287
288
  await kit.state.record('message', mint, 'said in BTEST — "We are strong!"')
288
289
 
289
290
  assert(kit.state.tick === 5, `tick = 5: ${kit.state.tick}`)
290
- assert(kit.state.getSentiment(mint) === sentimentBeforeMsg + 0.5, `message bumps sentiment by 0.5: ${kit.state.getSentiment(mint)}`)
291
+ assert(kit.state.getSentiment(mint) === sentimentBeforeMsg + 0.05, `message bumps sentiment by 0.05: ${kit.state.getSentiment(mint)}`)
291
292
 
292
293
  // ═══════════════════════════════════════════════════════════════════
293
294
  // TEST: AGENT 2 JOIN + SEPARATE STATE
@@ -305,7 +306,7 @@ async function main() {
305
306
 
306
307
  assert(kit2.state.tick === 1, `agent 2 tick = 1: ${kit2.state.tick}`)
307
308
  assert(kit.state.tick === 5, `agent 1 tick unchanged: ${kit.state.tick}`)
308
- assert(kit2.state.getSentiment(mint) === 1, `agent 2 sentiment = +1 (join): ${kit2.state.getSentiment(mint)}`)
309
+ assert(kit2.state.getSentiment(mint) === 0.1, `agent 2 sentiment = +0.1 (join): ${kit2.state.getSentiment(mint)}`)
309
310
 
310
311
  // ═══════════════════════════════════════════════════════════════════
311
312
  // TEST: RALLY + STATE
@@ -324,7 +325,7 @@ async function main() {
324
325
  const detail2 = await kit.actions.getFaction(mint)
325
326
  assert(detail2.rallies > detail1.rallies, `rallies increased: ${detail1.rallies} → ${detail2.rallies}`)
326
327
  assert(kit2.state.tick === 2, `agent 2 tick = 2: ${kit2.state.tick}`)
327
- assert(kit2.state.getSentiment(mint) === 4, `agent 2 sentiment after join(+1) + rally(+3) = 4: ${kit2.state.getSentiment(mint)}`)
328
+ assert(kit2.state.getSentiment(mint) === 0.4, `agent 2 sentiment after join(+0.1) + rally(+0.3) = 0.4: ${kit2.state.getSentiment(mint)}`)
328
329
  assert(kit2.state.hasRallied(mint), `agent 2 marked as rallied`)
329
330
 
330
331
  // ═══════════════════════════════════════════════════════════════════
@@ -346,15 +347,88 @@ async function main() {
346
347
  assert(kitRestored.state.history.length === kit.state.history.length, `hydrated history length matches: ${kitRestored.state.history.length}`)
347
348
 
348
349
  // ═══════════════════════════════════════════════════════════════════
349
- // TEST: SCOUT
350
+ // TEST: MEMBERS
351
+ // ═══════════════════════════════════════════════════════════════════
352
+
353
+ console.log('\n═══ TEST: Members ═══')
354
+ try {
355
+ const members = await kit.actions.getMembers(mint)
356
+ console.log(` Total members: ${members.total_members}`)
357
+ for (const m of members.members.slice(0, 5)) {
358
+ console.log(` ${m.address.slice(0, 8)}... — ${m.balance} (${m.percentage.toFixed(2)}%)`)
359
+ }
360
+ assert(members.total_members > 0, `has members: ${members.total_members}`)
361
+ } catch (err: any) {
362
+ console.log(` Skipped — RPC error: ${err.message?.slice(0, 80)}`)
363
+ }
364
+
365
+ // ═══════════════════════════════════════════════════════════════════
366
+ // TEST: CHECKPOINT (register + checkpoint + verify)
367
+ // ═══════════════════════════════════════════════════════════════════
368
+
369
+ console.log('\n═══ TEST: Checkpoint ═══')
370
+
371
+ // Register agent 1 on pyre_world
372
+ const regResult = await kit.registry.register({ creator: agent.publicKey })
373
+ await sendAndConfirm(connection, agent, regResult)
374
+ console.log(` Registered agent 1`)
375
+
376
+ // Verify fresh profile — all counts should be 0
377
+ const profileBefore = await kit.registry.getProfile(agent.publicKey)
378
+ assert(profileBefore !== undefined, `profile exists after register`)
379
+ assert(profileBefore!.joins === 0, `initial joins = 0`)
380
+ assert(profileBefore!.messages === 0, `initial messages = 0`)
381
+
382
+ // Checkpoint with current action counts from state
383
+ const counts = kit.state.state!.actionCounts
384
+ const cpResult = await kit.registry.checkpoint({
385
+ signer: agent.publicKey,
386
+ creator: agent.publicKey,
387
+ joins: counts.join,
388
+ defects: counts.defect,
389
+ rallies: counts.rally,
390
+ launches: counts.launch,
391
+ messages: counts.message,
392
+ fuds: counts.fud,
393
+ infiltrates: counts.infiltrate,
394
+ reinforces: counts.reinforce,
395
+ war_loans: counts.war_loan,
396
+ repay_loans: counts.repay_loan,
397
+ sieges: counts.siege,
398
+ ascends: counts.ascend,
399
+ razes: counts.raze,
400
+ tithes: counts.tithe,
401
+ personality_summary: 'test agent — loyal and steadfast',
402
+ total_sol_spent: kit.state.state!.totalSolSpent,
403
+ total_sol_received: kit.state.state!.totalSolReceived,
404
+ })
405
+ await sendAndConfirm(connection, agent, cpResult)
406
+ console.log(` Checkpointed agent 1 (tick ${kit.state.tick})`)
407
+
408
+ // Verify checkpoint wrote correct counts
409
+ const profileAfter = await kit.registry.getProfile(agent.publicKey)
410
+ assert(profileAfter !== undefined, `profile still exists`)
411
+ assert(profileAfter!.joins === counts.join, `checkpoint joins match: ${profileAfter!.joins} === ${counts.join}`)
412
+ assert(profileAfter!.defects === counts.defect, `checkpoint defects match: ${profileAfter!.defects} === ${counts.defect}`)
413
+ assert(profileAfter!.launches === counts.launch, `checkpoint launches match: ${profileAfter!.launches} === ${counts.launch}`)
414
+ assert(profileAfter!.messages === counts.message, `checkpoint messages match: ${profileAfter!.messages} === ${counts.message}`)
415
+ assert(profileAfter!.fuds === counts.fud, `checkpoint fuds match: ${profileAfter!.fuds} === ${counts.fud}`)
416
+ assert(profileAfter!.personality_summary === 'test agent — loyal and steadfast', `checkpoint personality matches`)
417
+ assert(profileAfter!.last_checkpoint > 0, `last_checkpoint timestamp set: ${profileAfter!.last_checkpoint}`)
418
+ console.log(` Profile verified — ${Object.values(counts).reduce((a, b) => a + b, 0)} total actions checkpointed`)
419
+
420
+ // ═══════════════════════════════════════════════════════════════════
421
+ // TEST: SCOUT (after checkpoint — agent 1 now has a pyre identity)
350
422
  // ═══════════════════════════════════════════════════════════════════
351
423
 
352
424
  console.log('\n═══ TEST: Scout ═══')
353
- // Scout agent 1 from agent 2's perspective
425
+ // Scout agent 1 from agent 2's perspective — should find real profile data
354
426
  const scoutResult = await kit2.actions.scout(agent.publicKey)
355
427
  console.log(` ${scoutResult}`)
356
428
  assert(typeof scoutResult === 'string', `scout returns string`)
357
429
  assert(scoutResult.includes(agent.publicKey.slice(0, 8)), `scout result contains target address: ${agent.publicKey.slice(0, 8)}`)
430
+ assert(scoutResult.includes('loyal and steadfast'), `scout shows personality from checkpoint`)
431
+ assert(scoutResult.includes('actions'), `scout shows action counts`)
358
432
 
359
433
  // Scout a nonexistent address
360
434
  const fakeAddress = 'FakeAddress1111111111111111111111111111111111'
@@ -368,19 +442,67 @@ async function main() {
368
442
  assert(kit2.state.tick === 2, `agent 2 tick unchanged after scout (read-only): ${kit2.state.tick}`)
369
443
 
370
444
  // ═══════════════════════════════════════════════════════════════════
371
- // TEST: MEMBERS
445
+ // TEST: FACTION DISCOVERY (rising, ascended, nearby)
372
446
  // ═══════════════════════════════════════════════════════════════════
373
447
 
374
- console.log('\n═══ TEST: Members ═══')
375
- try {
376
- const members = await kit.actions.getMembers(mint)
377
- console.log(` Total members: ${members.total_members}`)
378
- for (const m of members.members.slice(0, 5)) {
379
- console.log(` ${m.address.slice(0, 8)}... — ${m.balance} (${m.percentage.toFixed(2)}%)`)
380
- }
381
- assert(members.total_members > 0, `has members: ${members.total_members}`)
382
- } catch (err: any) {
383
- console.log(` Skipped RPC error: ${err.message?.slice(0, 80)}`)
448
+ console.log('\n═══ TEST: Faction discovery ═══')
449
+
450
+ // Agent 3 launches a second faction
451
+ const agent3 = createEphemeralAgent()
452
+ const kit3 = new PyreKit(connection, agent3.publicKey)
453
+
454
+ const airdrop3 = await connection.requestAirdrop(agent3.keypair.publicKey, 10 * LAMPORTS_PER_SOL)
455
+ await connection.confirmTransaction(airdrop3, 'confirmed')
456
+
457
+ const vault3 = await kit3.actions.createStronghold({ creator: agent3.publicKey })
458
+ await sendAndConfirm(connection, agent3, vault3)
459
+ const fund3 = await kit3.actions.fundStronghold({
460
+ depositor: agent3.publicKey, stronghold_creator: agent3.publicKey, amount_sol: 5 * LAMPORTS_PER_SOL,
461
+ })
462
+ await sendAndConfirm(connection, agent3, fund3)
463
+ await kit3.state.init()
464
+
465
+ const launch2 = await kit3.actions.launch({
466
+ founder: agent3.publicKey, name: 'Nearby Test Faction', symbol: 'NEAR',
467
+ metadata_uri: 'https://pyre.gg/test2.json', community_faction: true,
468
+ })
469
+ await sendAndConfirm(connection, agent3, launch2)
470
+ const mint2 = launch2.mint.toBase58()
471
+ console.log(` Faction 2: ${mint2} (NEAR)`)
472
+
473
+ // Agent 2 joins faction 2 — creating a social link between BTEST and NEAR
474
+ const join2Near = await kit2.actions.join({
475
+ mint: mint2, agent: agent2.publicKey, amount_sol: Math.floor(0.3 * LAMPORTS_PER_SOL),
476
+ strategy: 'fortify', stronghold: agent2.publicKey,
477
+ })
478
+ await sendAndConfirm(connection, agent2, join2Near)
479
+ console.log(` Agent 2 joined NEAR — bridge between BTEST and NEAR`)
480
+
481
+ // Test getRisingFactions
482
+ const rising = await kit.intel.getRisingFactions()
483
+ console.log(` Rising factions: ${rising.factions.length}`)
484
+ assert(rising.factions.length >= 2, `at least 2 rising factions: ${rising.factions.length}`)
485
+
486
+ // Test getAscendedFactions (none expected on fresh fork with new factions)
487
+ const ascended = await kit.intel.getAscendedFactions()
488
+ console.log(` Ascended factions: ${ascended.factions.length}`)
489
+
490
+ // Test getNearbyFactions — agent 1 holds BTEST, agent 2 also holds BTEST + NEAR
491
+ // BFS uses getComms to find neighbors, which requires getSignaturesForAddress.
492
+ // Surfpool doesn't support this reliably — test the seed scan only.
493
+ const nearby = await kit.intel.getNearbyFactions(agent.publicKey)
494
+ const nearbyMints = nearby.factions.map((f) => f.mint)
495
+ console.log(` Nearby factions for agent 1: ${nearby.factions.length} (${nearby.factions.map((f) => f.symbol).join(', ')})`)
496
+ assert(nearbyMints.includes(mint), `nearby includes own faction BTEST`)
497
+
498
+ // NOTE: Social graph discovery (finding NEAR through agent 2) requires
499
+ // getComms which depends on getSignaturesForAddress — not available on surfpool.
500
+ // This is tested on devnet/mainnet where comms resolution works.
501
+ if (nearbyMints.includes(mint2)) {
502
+ console.log(` ✓ nearby discovered NEAR through social graph`)
503
+ passed++
504
+ } else {
505
+ console.log(` ⊘ nearby did not discover NEAR (surfpool limitation — getComms unavailable)`)
384
506
  }
385
507
 
386
508
  // ═══════════════════════════════════════════════════════════════════