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.
@@ -2,6 +2,7 @@ import { Connection, PublicKey } from '@solana/web3.js'
2
2
 
3
3
  import { isPyreMint } from '../vanity'
4
4
  import { isBlacklistedMint } from '../util'
5
+ import type { Stronghold } from '../types'
5
6
  import type {
6
7
  State,
7
8
  AgentGameState,
@@ -11,6 +12,10 @@ import type {
11
12
  } from '../types/state.types'
12
13
  import { Registry } from '../types/registry.types'
13
14
 
15
+ // Pre-warm imports — resolved once, cached as module-level promises
16
+ const splTokenImport = import('@solana/spl-token')
17
+ const torchsdkImport = import('torchsdk')
18
+
14
19
  const EMPTY_COUNTS: Record<TrackedAction, number> = {
15
20
  join: 0,
16
21
  defect: 0,
@@ -33,6 +38,11 @@ export class StateProvider implements State {
33
38
  private checkpointConfig: CheckpointConfig | null = null
34
39
  private ticksSinceCheckpoint = 0
35
40
 
41
+ // Lazy vault — undefined = not resolved, null = resolved to nothing
42
+ private _vaultCreator: string | null | undefined = undefined
43
+ private _stronghold: Stronghold | null | undefined = undefined
44
+ private _vaultPromise: Promise<void> | null = null
45
+
36
46
  constructor(
37
47
  private connection: Connection,
38
48
  private registry: Registry,
@@ -42,9 +52,6 @@ export class StateProvider implements State {
42
52
  get state() {
43
53
  return this._state
44
54
  }
45
- get vaultCreator() {
46
- return this._state?.vaultCreator ?? null
47
- }
48
55
  get initialized() {
49
56
  return this._state?.initialized ?? false
50
57
  }
@@ -52,86 +59,113 @@ export class StateProvider implements State {
52
59
  return this._state?.tick ?? 0
53
60
  }
54
61
 
55
- /** Configure auto-checkpoint behavior */
56
62
  setCheckpointConfig(config: CheckpointConfig) {
57
63
  this.checkpointConfig = config
58
64
  }
59
65
 
60
- async init(): Promise<AgentGameState> {
61
- if (this._state?.initialized) return this._state
62
-
63
- const state: AgentGameState = {
64
- publicKey: this.publicKey,
65
- vaultCreator: null,
66
- stronghold: null,
67
- tick: 0,
68
- actionCounts: { ...EMPTY_COUNTS },
69
- holdings: new Map(),
70
- activeLoans: new Set(),
71
- founded: [],
72
- rallied: new Set(),
73
- voted: new Set(),
74
- sentiment: new Map(),
75
- recentHistory: [],
76
- personalitySummary: null,
77
- totalSolSpent: 0,
78
- totalSolReceived: 0,
79
- initialized: false,
66
+ private async resolveVault(): Promise<void> {
67
+ if (this._vaultCreator !== undefined) return
68
+ if (!this._vaultPromise) {
69
+ this._vaultPromise = (async () => {
70
+ const { getVaultForWallet } = await torchsdkImport
71
+ try {
72
+ const vault = await getVaultForWallet(this.connection, this.publicKey)
73
+ if (vault) {
74
+ this._vaultCreator = vault.creator
75
+ this._stronghold = {
76
+ address: vault.address,
77
+ creator: vault.creator,
78
+ authority: vault.authority,
79
+ sol_balance: vault.sol_balance,
80
+ total_deposited: vault.total_deposited,
81
+ total_withdrawn: vault.total_withdrawn,
82
+ total_spent: vault.total_spent,
83
+ total_received: vault.total_received,
84
+ linked_agents: vault.linked_wallets,
85
+ created_at: vault.created_at,
86
+ }
87
+ } else {
88
+ this._vaultCreator = null
89
+ this._stronghold = null
90
+ }
91
+ } catch {
92
+ this._vaultCreator = null
93
+ this._stronghold = null
94
+ }
95
+ this._vaultPromise = null
96
+ })()
80
97
  }
98
+ return this._vaultPromise
99
+ }
81
100
 
82
- this._state = state
83
-
84
- // resolve vault link
85
- const { getVaultForWallet } = await import('torchsdk')
86
- try {
87
- const vault = await getVaultForWallet(this.connection, this.publicKey)
88
- if (vault) {
89
- state.vaultCreator = vault.creator
90
- state.stronghold = {
91
- address: vault.address,
92
- creator: vault.creator,
93
- authority: vault.authority,
94
- sol_balance: vault.sol_balance,
95
- total_deposited: vault.total_deposited,
96
- total_withdrawn: vault.total_withdrawn,
97
- total_spent: vault.total_spent,
98
- total_received: vault.total_received,
99
- linked_agents: vault.linked_wallets,
100
- created_at: vault.created_at,
101
- }
102
- }
103
- } catch {}
104
-
105
- try {
106
- const profile = await this.registry.getProfile(this.publicKey)
107
- if (profile) {
108
- state.personalitySummary = profile.personality_summary || null
109
- state.totalSolSpent = profile.total_sol_spent
110
- state.totalSolReceived = profile.total_sol_received
111
-
112
- state.actionCounts.join = Math.max(state.actionCounts.join, profile.joins)
113
- state.actionCounts.defect = Math.max(state.actionCounts.defect, profile.defects)
114
- state.actionCounts.rally = Math.max(state.actionCounts.rally, profile.rallies)
115
- state.actionCounts.launch = Math.max(state.actionCounts.launch, profile.launches)
116
- state.actionCounts.message = Math.max(state.actionCounts.message, profile.messages)
117
- state.actionCounts.reinforce = Math.max(state.actionCounts.reinforce, profile.reinforces)
118
- state.actionCounts.fud = Math.max(state.actionCounts.fud, profile.fuds)
119
- state.actionCounts.infiltrate = Math.max(state.actionCounts.infiltrate, profile.infiltrates)
120
- state.actionCounts.war_loan = Math.max(state.actionCounts.war_loan, profile.war_loans)
121
- state.actionCounts.repay_loan = Math.max(state.actionCounts.repay_loan, profile.repay_loans)
122
- state.actionCounts.siege = Math.max(state.actionCounts.siege, profile.sieges)
123
- state.actionCounts.ascend = Math.max(state.actionCounts.ascend, profile.ascends)
124
- state.actionCounts.raze = Math.max(state.actionCounts.raze, profile.razes)
125
- state.actionCounts.tithe = Math.max(state.actionCounts.tithe, profile.tithes)
126
-
127
- const totalFromCheckpoint = Object.values(state.actionCounts).reduce((a, b) => a + b, 0)
128
- state.tick = totalFromCheckpoint
101
+ async getVaultCreator(): Promise<string | null> {
102
+ await this.resolveVault()
103
+ return this._vaultCreator ?? null
104
+ }
105
+
106
+ async getStronghold(): Promise<Stronghold | null> {
107
+ await this.resolveVault()
108
+ return this._stronghold ?? null
109
+ }
110
+
111
+ async init(): Promise<AgentGameState> {
112
+ if (!this._state?.initialized) {
113
+ const state: AgentGameState = {
114
+ publicKey: this.publicKey,
115
+ tick: 0,
116
+ actionCounts: { ...EMPTY_COUNTS },
117
+ activeLoans: new Set(),
118
+ founded: [],
119
+ rallied: new Set(),
120
+ voted: new Set(),
121
+ sentiment: new Map(),
122
+ recentHistory: [],
123
+ personalitySummary: null,
124
+ totalSolSpent: 0,
125
+ totalSolReceived: 0,
126
+ initialized: false,
129
127
  }
130
- } catch {}
131
128
 
132
- await this.refreshHoldings()
133
- state.initialized = true
134
- return state
129
+ // Fire vault resolution in background — don't block init
130
+ this.resolveVault()
131
+
132
+ try {
133
+ const profile = await this.registry.getProfile(this.publicKey)
134
+ if (profile) {
135
+ state.personalitySummary = profile.personality_summary || null
136
+ state.totalSolSpent = profile.total_sol_spent
137
+ state.totalSolReceived = profile.total_sol_received
138
+
139
+ state.actionCounts.join = Math.max(state.actionCounts.join, profile.joins)
140
+ state.actionCounts.defect = Math.max(state.actionCounts.defect, profile.defects)
141
+ state.actionCounts.rally = Math.max(state.actionCounts.rally, profile.rallies)
142
+ state.actionCounts.launch = Math.max(state.actionCounts.launch, profile.launches)
143
+ state.actionCounts.message = Math.max(state.actionCounts.message, profile.messages)
144
+ state.actionCounts.reinforce = Math.max(state.actionCounts.reinforce, profile.reinforces)
145
+ state.actionCounts.fud = Math.max(state.actionCounts.fud, profile.fuds)
146
+ state.actionCounts.infiltrate = Math.max(
147
+ state.actionCounts.infiltrate,
148
+ profile.infiltrates,
149
+ )
150
+ state.actionCounts.war_loan = Math.max(state.actionCounts.war_loan, profile.war_loans)
151
+ state.actionCounts.repay_loan = Math.max(
152
+ state.actionCounts.repay_loan,
153
+ profile.repay_loans,
154
+ )
155
+ state.actionCounts.siege = Math.max(state.actionCounts.siege, profile.sieges)
156
+ state.actionCounts.ascend = Math.max(state.actionCounts.ascend, profile.ascends)
157
+ state.actionCounts.raze = Math.max(state.actionCounts.raze, profile.razes)
158
+ state.actionCounts.tithe = Math.max(state.actionCounts.tithe, profile.tithes)
159
+
160
+ const totalFromCheckpoint = Object.values(state.actionCounts).reduce((a, b) => a + b, 0)
161
+ state.tick = totalFromCheckpoint
162
+ }
163
+ } catch {}
164
+
165
+ state.initialized = true
166
+ this._state = state
167
+ }
168
+ return this._state
135
169
  }
136
170
 
137
171
  async record(action: TrackedAction, mint?: string, description?: string): Promise<void> {
@@ -156,7 +190,6 @@ export class StateProvider implements State {
156
190
  }
157
191
  }
158
192
 
159
- await this.refreshHoldings()
160
193
  if (this.checkpointConfig && this.ticksSinceCheckpoint >= this.checkpointConfig.interval) {
161
194
  this.ticksSinceCheckpoint = 0
162
195
  this.onCheckpointDue?.()
@@ -167,15 +200,15 @@ export class StateProvider implements State {
167
200
  if (!this._state) return
168
201
  const current = this._state.sentiment.get(mint) ?? 0
169
202
  const SENTIMENT_DELTAS: Partial<Record<TrackedAction, number>> = {
170
- join: 1,
171
- reinforce: 1.5,
172
- defect: -2,
173
- rally: 3,
174
- infiltrate: -5,
175
- message: 0.5,
176
- fud: -1.5,
177
- war_loan: 1,
178
- launch: 3,
203
+ join: 0.1,
204
+ reinforce: 0.15,
205
+ defect: -0.2,
206
+ rally: 0.3,
207
+ infiltrate: -0.5,
208
+ message: 0.05,
209
+ fud: -0.15,
210
+ war_loan: 0.1,
211
+ launch: 0.3,
179
212
  }
180
213
 
181
214
  const delta = SENTIMENT_DELTAS[action] ?? 0
@@ -186,44 +219,43 @@ export class StateProvider implements State {
186
219
 
187
220
  onCheckpointDue: (() => void) | null = null
188
221
 
189
- async refreshHoldings(): Promise<void> {
190
- if (!this._state) return
191
-
192
- const { TOKEN_2022_PROGRAM_ID } = await import('@solana/spl-token')
222
+ async getHoldings(): Promise<Map<string, number>> {
223
+ const { TOKEN_2022_PROGRAM_ID } = await splTokenImport
193
224
  const walletPk = new PublicKey(this.publicKey)
194
225
 
195
- let walletValues: any[] = []
196
- try {
197
- const walletAccounts = await this.connection.getParsedTokenAccountsByOwner(walletPk, {
198
- programId: TOKEN_2022_PROGRAM_ID,
199
- })
200
- walletValues = walletAccounts.value
201
- } catch {}
202
-
203
- let vaultValues: any[] = []
204
- if (this._state.stronghold) {
205
- try {
206
- const vaultPk = new PublicKey(this._state.stronghold.address)
207
- const vaultAccounts = await this.connection.getParsedTokenAccountsByOwner(vaultPk, {
208
- programId: TOKEN_2022_PROGRAM_ID,
209
- })
210
- vaultValues = vaultAccounts.value
211
- } catch {}
212
- }
213
-
214
- const newHoldings = new Map<string, number>()
226
+ // Parallel scan: wallet + vault
227
+ const stronghold = await this.getStronghold()
228
+ const scanWallet = this.connection
229
+ .getParsedTokenAccountsByOwner(walletPk, { programId: TOKEN_2022_PROGRAM_ID })
230
+ .then((r) => r.value)
231
+ .catch(() => [] as any[])
232
+
233
+ const scanVault = stronghold
234
+ ? this.connection
235
+ .getParsedTokenAccountsByOwner(new PublicKey(stronghold.address), {
236
+ programId: TOKEN_2022_PROGRAM_ID,
237
+ })
238
+ .then((r) => r.value)
239
+ .catch(() => [] as any[])
240
+ : Promise.resolve([] as any[])
241
+
242
+ const [walletValues, vaultValues] = await Promise.all([scanWallet, scanVault])
243
+
244
+ const holdings = new Map<string, number>()
215
245
  for (const a of [...walletValues, ...vaultValues]) {
216
246
  const mint = a.account.data.parsed.info.mint as string
217
247
  const balance = Number(a.account.data.parsed.info.tokenAmount.uiAmount ?? 0)
218
248
  if (balance > 0 && isPyreMint(mint) && !isBlacklistedMint(mint)) {
219
- newHoldings.set(mint, (newHoldings.get(mint) ?? 0) + balance)
249
+ holdings.set(mint, (holdings.get(mint) ?? 0) + balance)
220
250
  }
221
251
  }
222
252
 
223
- this._state.holdings.clear()
224
- for (const [mint, balance] of newHoldings) {
225
- this._state.holdings.set(mint, balance)
226
- }
253
+ return holdings
254
+ }
255
+
256
+ async getBalance(mint: string): Promise<number> {
257
+ const holdings = await this.getHoldings()
258
+ return holdings.get(mint) ?? 0
227
259
  }
228
260
 
229
261
  getSentiment(mint: string): number {
@@ -238,10 +270,6 @@ export class StateProvider implements State {
238
270
  return this._state?.recentHistory ?? []
239
271
  }
240
272
 
241
- getBalance(mint: string): number {
242
- return this._state?.holdings.get(mint) ?? 0
243
- }
244
-
245
273
  hasVoted(mint: string): boolean {
246
274
  return this._state?.voted.has(mint) ?? false
247
275
  }
@@ -259,51 +287,50 @@ export class StateProvider implements State {
259
287
  }
260
288
 
261
289
  serialize(): SerializedGameState {
262
- if (!this._state) {
263
- return {
264
- publicKey: this.publicKey,
265
- vaultCreator: null,
266
- tick: 0,
267
- actionCounts: { ...EMPTY_COUNTS },
268
- holdings: {},
269
- activeLoans: [],
270
- founded: [],
271
- rallied: [],
272
- voted: [],
273
- sentiment: {},
274
- recentHistory: [],
275
- personalitySummary: null,
276
- totalSolSpent: 0,
277
- totalSolReceived: 0,
278
- }
279
- }
280
-
281
- return {
282
- publicKey: this._state.publicKey,
283
- vaultCreator: this._state.vaultCreator,
284
- tick: this._state.tick,
285
- actionCounts: { ...this._state.actionCounts },
286
- holdings: Object.fromEntries(this._state.holdings),
287
- activeLoans: Array.from(this._state.activeLoans),
288
- founded: [...this._state.founded],
289
- rallied: Array.from(this._state.rallied),
290
- voted: Array.from(this._state.voted),
291
- sentiment: Object.fromEntries(this._state.sentiment),
292
- recentHistory: this._state.recentHistory.slice(-20),
293
- personalitySummary: this._state.personalitySummary,
294
- totalSolSpent: this._state.totalSolSpent,
295
- totalSolReceived: this._state.totalSolReceived,
296
- }
290
+ return !this._state
291
+ ? {
292
+ publicKey: this.publicKey,
293
+ vaultCreator: null,
294
+ tick: 0,
295
+ actionCounts: { ...EMPTY_COUNTS },
296
+ holdings: {},
297
+ activeLoans: [],
298
+ founded: [],
299
+ rallied: [],
300
+ voted: [],
301
+ sentiment: {},
302
+ recentHistory: [],
303
+ personalitySummary: null,
304
+ totalSolSpent: 0,
305
+ totalSolReceived: 0,
306
+ }
307
+ : {
308
+ publicKey: this._state.publicKey,
309
+ vaultCreator: this._vaultCreator ?? null,
310
+ tick: this._state.tick,
311
+ actionCounts: { ...this._state.actionCounts },
312
+ holdings: {},
313
+ activeLoans: Array.from(this._state.activeLoans),
314
+ founded: [...this._state.founded],
315
+ rallied: Array.from(this._state.rallied),
316
+ voted: Array.from(this._state.voted),
317
+ sentiment: Object.fromEntries(this._state.sentiment),
318
+ recentHistory: this._state.recentHistory.slice(-20),
319
+ personalitySummary: this._state.personalitySummary,
320
+ totalSolSpent: this._state.totalSolSpent,
321
+ totalSolReceived: this._state.totalSolReceived,
322
+ }
297
323
  }
298
324
 
299
325
  hydrate(saved: SerializedGameState): void {
326
+ if (saved.vaultCreator) {
327
+ this._vaultCreator = saved.vaultCreator
328
+ }
329
+
300
330
  this._state = {
301
331
  publicKey: saved.publicKey,
302
- vaultCreator: saved.vaultCreator,
303
- stronghold: null, // will be resolved on next refreshHoldings or init
304
332
  tick: saved.tick,
305
333
  actionCounts: { ...EMPTY_COUNTS, ...saved.actionCounts },
306
- holdings: new Map(Object.entries(saved.holdings)),
307
334
  activeLoans: new Set(saved.activeLoans),
308
335
  founded: [...saved.founded],
309
336
  rallied: new Set(saved.rallied),
@@ -2,21 +2,29 @@ import {
2
2
  AgentFactionPosition,
3
3
  AgentProfile,
4
4
  AllianceCluster,
5
+ FactionListResult,
5
6
  FactionPower,
6
7
  FactionStatus,
8
+ NearbyResult,
7
9
  RivalFaction,
8
10
  WorldEvent,
9
11
  WorldStats,
10
12
  } from '../types'
11
13
 
12
14
  export interface Intel {
13
- getAgentFactions(wallet: string, factionLimit?: number): Promise<AgentFactionPosition[]>
15
+ getAgentFactions(wallet: string): Promise<AgentFactionPosition[]>
14
16
  getAgentProfile(wallet: string): Promise<AgentProfile>
15
17
  getAgentSolLamports(wallet: string): Promise<number>
16
18
  getAllies(mints: string[], holderLimit?: number): Promise<AllianceCluster[]>
19
+ getAscendedFactions(limit?: number): Promise<FactionListResult>
17
20
  getFactionPower(mint: string): Promise<FactionPower>
18
21
  getFactionLeaderboard(opts?: { status?: FactionStatus; limit?: number }): Promise<FactionPower[]>
19
22
  getFactionRivals(mint: string, opts?: { limit?: number }): Promise<RivalFaction[]>
23
+ getNearbyFactions(
24
+ wallet: string,
25
+ opts?: { depth?: number; limit?: number },
26
+ ): Promise<NearbyResult>
27
+ getRisingFactions(limit?: number): Promise<FactionListResult>
20
28
  getWorldFeed(opts?: { limit?: number; factionLimit?: number }): Promise<WorldEvent[]>
21
29
  getWorldStats(): Promise<WorldStats>
22
30
  }
@@ -21,16 +21,10 @@ export type TrackedAction =
21
21
  export interface AgentGameState {
22
22
  /** Agent wallet public key */
23
23
  publicKey: string
24
- /** Vault creator key (resolved from on-chain vault link) */
25
- vaultCreator: string | null
26
- /** Vault info (null if no vault found) */
27
- stronghold: Stronghold | null
28
24
  /** Monotonic tick counter — increments on each successful action */
29
25
  tick: number
30
26
  /** Cumulative action counts keyed by action type */
31
27
  actionCounts: Record<TrackedAction, number>
32
- /** Token holdings: mint → balance (wallet + vault combined) */
33
- holdings: Map<string, number>
34
28
  /** Mints with active war loans */
35
29
  activeLoans: Set<string>
36
30
  /** Mints this agent founded */
@@ -86,9 +80,6 @@ export interface State {
86
80
  /** Current game state (null before init) */
87
81
  readonly state: AgentGameState | null
88
82
 
89
- /** Vault creator key (shorthand for state.vaultCreator) */
90
- readonly vaultCreator: string | null
91
-
92
83
  /** Whether state has been initialized */
93
84
  readonly initialized: boolean
94
85
 
@@ -97,20 +88,28 @@ export interface State {
97
88
 
98
89
  /**
99
90
  * Initialize state from chain.
100
- * Resolves vault link, loads holdings, loads action counts from registry checkpoint.
101
- * Must be called before any action. Returns the resolved state.
91
+ * Loads action counts from registry checkpoint.
92
+ * Vault and holdings are resolved lazily on first access.
102
93
  */
103
94
  init(): Promise<AgentGameState>
104
95
 
105
96
  /**
106
97
  * Record a successful action — increments tick, updates action counts,
107
- * updates sentiment, appends to history, refreshes holdings.
108
- * Called by ActionProvider after tx confirmation.
98
+ * updates sentiment, appends to history.
109
99
  */
110
100
  record(action: TrackedAction, mint?: string, description?: string): Promise<void>
111
101
 
112
- /** Refresh holdings from on-chain (wallet + vault token accounts) */
113
- refreshHoldings(): Promise<void>
102
+ /** Get vault creator key (lazy resolves on first call, cached after) */
103
+ getVaultCreator(): Promise<string | null>
104
+
105
+ /** Get stronghold info (lazy — resolves on first call, cached after) */
106
+ getStronghold(): Promise<Stronghold | null>
107
+
108
+ /** Get token holdings fresh from chain (wallet + vault) */
109
+ getHoldings(): Promise<Map<string, number>>
110
+
111
+ /** Get token balance for a specific mint (fresh from chain) */
112
+ getBalance(mint: string): Promise<number>
114
113
 
115
114
  /** Get sentiment score for a faction (-10 to +10) */
116
115
  getSentiment(mint: string): number
@@ -121,9 +120,6 @@ export interface State {
121
120
  /** Get recent action history (for LLM memory block) */
122
121
  readonly history: readonly string[]
123
122
 
124
- /** Get token balance for a specific mint */
125
- getBalance(mint: string): number
126
-
127
123
  /** Check if agent has voted on a faction */
128
124
  hasVoted(mint: string): boolean
129
125
 
package/src/types.ts CHANGED
@@ -402,6 +402,12 @@ export interface FactionPower {
402
402
  status: FactionStatus
403
403
  }
404
404
 
405
+ /** Result from getNearbyFactions — factions + discovered agents in the social graph */
406
+ export interface NearbyResult extends FactionListResult {
407
+ /** Wallet addresses discovered as co-holders (natural allies) */
408
+ allies: string[]
409
+ }
410
+
405
411
  export interface AllianceCluster {
406
412
  factions: string[]
407
413
  shared_members: number
package/src/vanity.ts CHANGED
@@ -42,23 +42,25 @@ export const getBondingCurvePda = (mint: PublicKey): [PublicKey, number] =>
42
42
  export const getTokenTreasuryPda = (mint: PublicKey): [PublicKey, number] =>
43
43
  PublicKey.findProgramAddressSync([Buffer.from(TREASURY_SEED), mint.toBuffer()], PROGRAM_ID)
44
44
 
45
- const getTreasuryTokenAccount = (mint: PublicKey, treasury: PublicKey): PublicKey =>
45
+ const getTreasuryTokenAccount = (mint: PublicKey, treasury: PublicKey) =>
46
46
  getAssociatedTokenAddressSync(mint, treasury, true, TOKEN_2022_PROGRAM_ID)
47
47
 
48
48
  export const getTreasuryLockPda = (mint: PublicKey): [PublicKey, number] =>
49
49
  PublicKey.findProgramAddressSync([Buffer.from(TREASURY_LOCK_SEED), mint.toBuffer()], PROGRAM_ID)
50
50
 
51
- const getTreasuryLockTokenAccount = (mint: PublicKey, treasuryLock: PublicKey): PublicKey =>
51
+ const getTreasuryLockTokenAccount = (mint: PublicKey, treasuryLock: PublicKey) =>
52
52
  getAssociatedTokenAddressSync(mint, treasuryLock, true, TOKEN_2022_PROGRAM_ID)
53
53
 
54
- const makeDummyProvider = (connection: Connection, payer: PublicKey): AnchorProvider => {
55
- const dummyWallet = {
56
- publicKey: payer,
57
- signTransaction: async (t: Transaction) => t,
58
- signAllTransactions: async (t: Transaction[]) => t,
59
- }
60
- return new AnchorProvider(connection, dummyWallet as unknown as Wallet, {})
61
- }
54
+ const makeDummyProvider = (connection: Connection, payer: PublicKey) =>
55
+ new AnchorProvider(
56
+ connection,
57
+ {
58
+ publicKey: payer,
59
+ signTransaction: async (t: Transaction) => t,
60
+ signAllTransactions: async (t: Transaction[]) => t,
61
+ } as unknown as Wallet,
62
+ {},
63
+ )
62
64
 
63
65
  const finalizeTransaction = async (
64
66
  connection: Connection,
@@ -72,9 +74,9 @@ const finalizeTransaction = async (
72
74
 
73
75
  // ── Vanity grinder ──
74
76
 
75
- const PYRE_SUFFIX = 'py'
77
+ const PYRE_SUFFIX = 'pw'
76
78
 
77
- /** Grind for a keypair whose base58 address ends with "py" */
79
+ /** Grind for a keypair whose base58 address ends with "pw" (pyreworld) */
78
80
  export const grindPyreMint = (maxAttempts: number = 500_000): Keypair => {
79
81
  for (let i = 0; i < maxAttempts; i++) {
80
82
  const kp = Keypair.generate()
@@ -86,7 +88,7 @@ export const grindPyreMint = (maxAttempts: number = 500_000): Keypair => {
86
88
  return Keypair.generate()
87
89
  }
88
90
 
89
- /** Check if a mint address is a pyre faction (ends with "py") */
91
+ /** Check if a mint address is a pyre faction (ends with "pw") */
90
92
  export const isPyreMint = (mint: string): boolean => mint.endsWith(PYRE_SUFFIX)
91
93
 
92
94
  // ── Build create transaction with pyre vanity address ──