pyre-world-kit 2.0.12 → 3.0.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.
Files changed (53) hide show
  1. package/.prettierrc.json +6 -0
  2. package/dist/index.d.ts +46 -4
  3. package/dist/index.js +105 -85
  4. package/dist/providers/action.provider.d.ts +46 -0
  5. package/dist/providers/action.provider.js +331 -0
  6. package/dist/providers/intel.provider.d.ts +29 -0
  7. package/dist/providers/intel.provider.js +363 -0
  8. package/dist/providers/mapper.provider.d.ts +197 -0
  9. package/dist/providers/mapper.provider.js +158 -0
  10. package/dist/providers/registry.provider.d.ts +25 -0
  11. package/dist/providers/registry.provider.js +229 -0
  12. package/dist/providers/state.provider.d.ts +42 -0
  13. package/dist/providers/state.provider.js +348 -0
  14. package/dist/pyre_world.json +34 -229
  15. package/dist/types/action.types.d.ts +41 -0
  16. package/dist/types/action.types.js +2 -0
  17. package/dist/types/intel.types.d.ts +20 -0
  18. package/dist/types/intel.types.js +2 -0
  19. package/dist/types/mapper.types.d.ts +27 -0
  20. package/dist/types/mapper.types.js +22 -0
  21. package/dist/types/registry.types.d.ts +0 -0
  22. package/dist/types/registry.types.js +1 -0
  23. package/dist/types/state.types.d.ts +112 -0
  24. package/dist/types/state.types.js +2 -0
  25. package/dist/types.d.ts +8 -24
  26. package/dist/util.d.ts +29 -0
  27. package/dist/util.js +144 -0
  28. package/dist/vanity.d.ts +3 -3
  29. package/dist/vanity.js +18 -15
  30. package/package.json +4 -2
  31. package/readme.md +184 -142
  32. package/src/index.ts +133 -92
  33. package/src/providers/action.provider.ts +443 -0
  34. package/src/providers/intel.provider.ts +383 -0
  35. package/src/providers/mapper.provider.ts +195 -0
  36. package/src/providers/registry.provider.ts +277 -0
  37. package/src/providers/state.provider.ts +357 -0
  38. package/src/pyre_world.json +35 -230
  39. package/src/types/action.types.ts +76 -0
  40. package/src/types/intel.types.ts +22 -0
  41. package/src/types/mapper.types.ts +84 -0
  42. package/src/types/registry.types.ts +0 -0
  43. package/src/types/state.types.ts +144 -0
  44. package/src/types.ts +329 -333
  45. package/src/util.ts +148 -0
  46. package/src/vanity.ts +27 -14
  47. package/tests/test_e2e.ts +339 -172
  48. package/src/actions.ts +0 -719
  49. package/src/intel.ts +0 -521
  50. package/src/mappers.ts +0 -302
  51. package/src/registry.ts +0 -317
  52. package/tests/test_devnet_e2e.ts +0 -401
  53. package/tests/test_sim.ts +0 -458
@@ -1,401 +0,0 @@
1
- /**
2
- * Pyre Kit Devnet E2E Test
3
- *
4
- * Tests the full faction warfare flow on Solana devnet.
5
- * Creates a faction with a "py" vanity mint, joins, rallies, defects.
6
- *
7
- * Run:
8
- * npx tsx tests/test_devnet_e2e.ts
9
- *
10
- * Requirements:
11
- * - Devnet wallet (~/.config/solana/id.json) with ~5 SOL
12
- * - Torch Market program deployed to devnet
13
- */
14
-
15
- // Must be set before any torchsdk imports
16
- process.env.TORCH_NETWORK = 'devnet'
17
-
18
- import {
19
- Connection,
20
- Keypair,
21
- LAMPORTS_PER_SOL,
22
- Transaction,
23
- SystemProgram,
24
- } from '@solana/web3.js'
25
- import {
26
- createEphemeralAgent,
27
- createStronghold,
28
- fundStronghold,
29
- recruitAgent,
30
- launchFaction,
31
- getFactions,
32
- getFaction,
33
- getJoinQuote,
34
- joinFaction,
35
- directJoinFaction,
36
- getComms,
37
- rally,
38
- defect,
39
- getMembers,
40
- getStrongholdForAgent,
41
- isPyreMint,
42
- } from '../src/index'
43
- import * as fs from 'fs'
44
- import * as path from 'path'
45
- import * as os from 'os'
46
-
47
- // ============================================================================
48
- // Config
49
- // ============================================================================
50
-
51
- const DEVNET_RPC = 'https://api.devnet.solana.com'
52
- const WALLET_PATH = path.join(os.homedir(), '.config/solana/id.json')
53
-
54
- // ============================================================================
55
- // Helpers
56
- // ============================================================================
57
-
58
- const loadWallet = (): Keypair => {
59
- const raw = JSON.parse(fs.readFileSync(WALLET_PATH, 'utf-8'))
60
- return Keypair.fromSecretKey(Uint8Array.from(raw))
61
- }
62
-
63
- const log = (msg: string) => {
64
- const ts = new Date().toISOString().substr(11, 8)
65
- console.log(`[${ts}] ${msg}`)
66
- }
67
-
68
- const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms))
69
-
70
- const signAndSend = async (
71
- connection: Connection,
72
- signer: Keypair,
73
- tx: Transaction,
74
- ): Promise<string> => {
75
- tx.partialSign(signer)
76
- const sig = await connection.sendRawTransaction(tx.serialize(), {
77
- skipPreflight: false,
78
- preflightCommitment: 'confirmed',
79
- })
80
- await connection.confirmTransaction(sig, 'confirmed')
81
- return sig
82
- }
83
-
84
- let passed = 0
85
- let failed = 0
86
- const ok = (name: string, detail?: string) => {
87
- passed++
88
- log(` ✓ ${name}${detail ? ` — ${detail}` : ''}`)
89
- }
90
- const fail = (name: string, err: any) => {
91
- failed++
92
- log(` ✗ ${name} — ${err.message || err}`)
93
- }
94
-
95
- // ============================================================================
96
- // Main
97
- // ============================================================================
98
-
99
- async function main() {
100
- console.log('='.repeat(60))
101
- console.log('PYRE KIT — DEVNET E2E TEST')
102
- console.log('='.repeat(60))
103
-
104
- const connection = new Connection(DEVNET_RPC, 'confirmed')
105
- const wallet = loadWallet()
106
- const walletAddr = wallet.publicKey.toBase58()
107
-
108
- log(`Wallet: ${walletAddr}`)
109
- const balance = await connection.getBalance(wallet.publicKey)
110
- log(`Balance: ${(balance / LAMPORTS_PER_SOL).toFixed(2)} SOL`)
111
-
112
- if (balance < 3 * LAMPORTS_PER_SOL) {
113
- console.error('Need at least ~3 SOL on devnet.')
114
- process.exit(1)
115
- }
116
-
117
- // ================================================================
118
- // 1. Create ephemeral agents
119
- // ================================================================
120
- log('\n[1] Creating ephemeral agents')
121
- const agent1 = createEphemeralAgent()
122
- const agent2 = createEphemeralAgent()
123
- log(` Agent 1: ${agent1.publicKey}`)
124
- log(` Agent 2: ${agent2.publicKey}`)
125
-
126
- // Fund agents from main wallet
127
- const fundTx = new Transaction().add(
128
- SystemProgram.transfer({
129
- fromPubkey: wallet.publicKey,
130
- toPubkey: agent1.keypair.publicKey,
131
- lamports: 1.5 * LAMPORTS_PER_SOL,
132
- }),
133
- SystemProgram.transfer({
134
- fromPubkey: wallet.publicKey,
135
- toPubkey: agent2.keypair.publicKey,
136
- lamports: 0.5 * LAMPORTS_PER_SOL,
137
- }),
138
- )
139
- const { blockhash } = await connection.getLatestBlockhash()
140
- fundTx.recentBlockhash = blockhash
141
- fundTx.feePayer = wallet.publicKey
142
- await signAndSend(connection, wallet, fundTx)
143
- ok('Fund agents', '1.5 SOL + 0.5 SOL')
144
-
145
- await sleep(500)
146
-
147
- // ================================================================
148
- // 2. Create stronghold
149
- // ================================================================
150
- log('\n[2] Creating stronghold')
151
- try {
152
- const result = await createStronghold(connection, {
153
- creator: agent1.publicKey,
154
- })
155
- await signAndSend(connection, agent1.keypair, result.transaction)
156
- ok('Create stronghold')
157
- } catch (e: any) {
158
- if (e.message?.includes('already in use')) {
159
- ok('Create stronghold', 'already exists')
160
- } else {
161
- fail('Create stronghold', e)
162
- }
163
- }
164
-
165
- await sleep(500)
166
-
167
- // ================================================================
168
- // 3. Fund stronghold
169
- // ================================================================
170
- log('\n[3] Funding stronghold')
171
- try {
172
- const result = await fundStronghold(connection, {
173
- depositor: agent1.publicKey,
174
- stronghold_creator: agent1.publicKey,
175
- amount_sol: 1 * LAMPORTS_PER_SOL,
176
- })
177
- await signAndSend(connection, agent1.keypair, result.transaction)
178
- ok('Fund stronghold', '1 SOL')
179
- } catch (e: any) {
180
- fail('Fund stronghold', e)
181
- }
182
-
183
- await sleep(500)
184
-
185
- // ================================================================
186
- // 4. Verify stronghold link
187
- // ================================================================
188
- log('\n[4] Verifying stronghold')
189
- try {
190
- const stronghold = await getStrongholdForAgent(connection, agent1.publicKey)
191
- if (stronghold) {
192
- ok('Stronghold link', `balance=${(stronghold.sol_balance / LAMPORTS_PER_SOL).toFixed(2)} SOL, agents=${stronghold.linked_agents}`)
193
- } else {
194
- fail('Stronghold link', { message: 'not found' })
195
- }
196
- } catch (e: any) {
197
- fail('Stronghold link', e)
198
- }
199
-
200
- // ================================================================
201
- // 5. Launch faction (with py vanity mint!)
202
- // ================================================================
203
- log('\n[5] Launching faction (grinding py vanity mint...)')
204
- let factionMint: string = ''
205
- try {
206
- const startTime = Date.now()
207
- const result = await launchFaction(connection, {
208
- founder: agent1.publicKey,
209
- name: 'Devnet Pyre Faction',
210
- symbol: 'DPYRE',
211
- metadata_uri: 'https://torch.market/test-metadata.json',
212
- community_faction: true,
213
- })
214
- const grindMs = Date.now() - startTime
215
- await signAndSend(connection, agent1.keypair, result.transaction)
216
- factionMint = result.mint.toBase58()
217
-
218
- const hasPySuffix = isPyreMint(factionMint)
219
- ok('Launch faction', `mint=${factionMint.slice(0, 8)}...${factionMint.slice(-4)} vanity=${hasPySuffix ? 'py✓' : 'MISS'} grind=${grindMs}ms`)
220
-
221
- if (!hasPySuffix) {
222
- log(' ⚠ Vanity grind did not find "py" suffix — faction still works but won\'t be filtered as pyre')
223
- }
224
- } catch (e: any) {
225
- fail('Launch faction', e)
226
- console.error('Cannot continue without faction. Exiting.')
227
- process.exit(1)
228
- }
229
-
230
- await sleep(1000)
231
-
232
- // ================================================================
233
- // 6. List factions
234
- // ================================================================
235
- log('\n[6] Listing factions')
236
- try {
237
- const factions = await getFactions(connection, { limit: 10 })
238
- const ourFaction = factions.factions.find(f => f.mint === factionMint)
239
- ok('List factions', `total=${factions.total}, ours=${ourFaction ? 'found' : 'not found'}`)
240
- } catch (e: any) {
241
- fail('List factions', e)
242
- }
243
-
244
- // ================================================================
245
- // 7. Get faction detail
246
- // ================================================================
247
- log('\n[7] Getting faction detail')
248
- try {
249
- const detail = await getFaction(connection, factionMint)
250
- ok('Faction detail', `name=${detail.name} status=${detail.status} tier=${detail.tier}`)
251
- } catch (e: any) {
252
- fail('Faction detail', e)
253
- }
254
-
255
- // ================================================================
256
- // 8. Get join quote
257
- // ================================================================
258
- log('\n[8] Getting join quote (0.1 SOL)')
259
- let tokensOut = 0
260
- try {
261
- const quote = await getJoinQuote(connection, factionMint, 0.1 * LAMPORTS_PER_SOL)
262
- tokensOut = quote.tokens_to_user
263
- ok('Join quote', `tokens=${tokensOut} impact=${quote.price_impact_percent}%`)
264
- } catch (e: any) {
265
- fail('Join quote', e)
266
- }
267
-
268
- // ================================================================
269
- // 9. Join faction via vault
270
- // ================================================================
271
- log('\n[9] Joining faction via vault')
272
- try {
273
- const result = await joinFaction(connection, {
274
- mint: factionMint,
275
- agent: agent1.publicKey,
276
- amount_sol: 0.1 * LAMPORTS_PER_SOL,
277
- strategy: 'fortify',
278
- message: 'First blood. The pyre burns.',
279
- stronghold: agent1.publicKey,
280
- })
281
- await signAndSend(connection, agent1.keypair, result.transaction)
282
- ok('Join faction', result.message)
283
- } catch (e: any) {
284
- fail('Join faction', e)
285
- }
286
-
287
- await sleep(1000)
288
-
289
- // ================================================================
290
- // 10. Agent 2 joins directly (no vault)
291
- // ================================================================
292
- log('\n[10] Agent 2 joins directly')
293
- try {
294
- const result = await directJoinFaction(connection, {
295
- mint: factionMint,
296
- agent: agent2.publicKey,
297
- amount_sol: 0.05 * LAMPORTS_PER_SOL,
298
- strategy: 'scorched_earth',
299
- message: 'Reporting for duty.',
300
- })
301
- await signAndSend(connection, agent2.keypair, result.transaction)
302
- ok('Agent 2 join', result.message)
303
- } catch (e: any) {
304
- fail('Agent 2 join', e)
305
- }
306
-
307
- await sleep(1000)
308
-
309
- // ================================================================
310
- // 11. Read comms
311
- // ================================================================
312
- log('\n[11] Reading comms')
313
- try {
314
- const comms = await getComms(connection, factionMint)
315
- ok('Read comms', `total=${comms.total}`)
316
- for (const c of comms.comms) {
317
- log(` ${c.sender.slice(0, 8)}...: "${c.memo}"`)
318
- }
319
- } catch (e: any) {
320
- fail('Read comms', e)
321
- }
322
-
323
- // ================================================================
324
- // 12. Rally (agent 2 — can't rally your own faction)
325
- // ================================================================
326
- log('\n[12] Agent 2 rallies faction')
327
- try {
328
- const result = await rally(connection, {
329
- mint: factionMint,
330
- agent: agent2.publicKey,
331
- })
332
- await signAndSend(connection, agent2.keypair, result.transaction)
333
- ok('Rally')
334
-
335
- const detail = await getFaction(connection, factionMint)
336
- log(` Rallies: ${detail.rallies}`)
337
- } catch (e: any) {
338
- fail('Rally', e)
339
- }
340
-
341
- await sleep(500)
342
-
343
- // ================================================================
344
- // 13. Defect (agent 1 sells half)
345
- // ================================================================
346
- log('\n[13] Agent 1 defects (partial)')
347
- try {
348
- const sellAmount = Math.floor(tokensOut / 2)
349
- if (sellAmount < 1) {
350
- ok('Defect', 'skipped — no tokens')
351
- } else {
352
- const result = await defect(connection, {
353
- mint: factionMint,
354
- agent: agent1.publicKey,
355
- amount_tokens: sellAmount,
356
- message: 'Strategic withdrawal.',
357
- stronghold: agent1.publicKey,
358
- })
359
- await signAndSend(connection, agent1.keypair, result.transaction)
360
- ok('Defect', `sold ${sellAmount} tokens`)
361
- }
362
- } catch (e: any) {
363
- fail('Defect', e)
364
- }
365
-
366
- await sleep(500)
367
-
368
- // ================================================================
369
- // 14. Check members
370
- // ================================================================
371
- log('\n[14] Checking members')
372
- try {
373
- const members = await getMembers(connection, factionMint)
374
- ok('Members', `total=${members.total_members}`)
375
- for (const m of members.members.slice(0, 5)) {
376
- log(` ${m.address.slice(0, 8)}... — ${m.percentage.toFixed(2)}%`)
377
- }
378
- } catch (e: any) {
379
- fail('Members', e)
380
- }
381
-
382
- // ================================================================
383
- // Summary
384
- // ================================================================
385
- const finalBalance = await connection.getBalance(wallet.publicKey)
386
- const solSpent = (balance - finalBalance) / LAMPORTS_PER_SOL
387
-
388
- console.log('\n' + '='.repeat(60))
389
- console.log(`RESULTS: ${passed} passed, ${failed} failed`)
390
- console.log(`Faction mint: ${factionMint}`)
391
- console.log(`Vanity "py" suffix: ${isPyreMint(factionMint) ? 'YES' : 'NO'}`)
392
- console.log(`SOL spent: ${solSpent.toFixed(4)} SOL (${(finalBalance / LAMPORTS_PER_SOL).toFixed(2)} remaining)`)
393
- console.log('='.repeat(60))
394
-
395
- process.exit(failed > 0 ? 1 : 0)
396
- }
397
-
398
- main().catch((e) => {
399
- console.error('\nFATAL:', e)
400
- process.exit(1)
401
- })