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/dist/index.d.ts +1 -1
- package/dist/providers/action.provider.js +1 -1
- package/dist/providers/intel.provider.d.ts +8 -2
- package/dist/providers/intel.provider.js +159 -36
- package/dist/providers/registry.provider.d.ts +3 -2
- package/dist/providers/registry.provider.js +29 -29
- package/dist/providers/state.provider.d.ts +9 -4
- package/dist/providers/state.provider.js +150 -135
- package/dist/types/intel.types.d.ts +8 -2
- package/dist/types/state.types.d.ts +11 -16
- package/dist/types.d.ts +5 -0
- package/dist/vanity.d.ts +2 -2
- package/dist/vanity.js +8 -11
- package/package.json +1 -1
- package/readme.md +79 -18
- package/src/index.ts +1 -0
- package/src/providers/action.provider.ts +1 -2
- package/src/providers/intel.provider.ts +182 -36
- package/src/providers/registry.provider.ts +24 -22
- package/src/providers/state.provider.ts +183 -156
- package/src/types/intel.types.ts +9 -1
- package/src/types/state.types.ts +14 -18
- package/src/types.ts +6 -0
- package/src/vanity.ts +15 -13
- package/tests/test_e2e.ts +145 -23
|
@@ -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
|
|
61
|
-
if (this.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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:
|
|
172
|
-
defect: -2,
|
|
173
|
-
rally: 3,
|
|
174
|
-
infiltrate: -5,
|
|
175
|
-
message: 0.
|
|
176
|
-
fud: -
|
|
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
|
|
190
|
-
|
|
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
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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
|
-
|
|
249
|
+
holdings.set(mint, (holdings.get(mint) ?? 0) + balance)
|
|
220
250
|
}
|
|
221
251
|
}
|
|
222
252
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
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),
|
package/src/types/intel.types.ts
CHANGED
|
@@ -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
|
|
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
|
}
|
package/src/types/state.types.ts
CHANGED
|
@@ -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
|
-
*
|
|
101
|
-
*
|
|
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
|
|
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
|
-
/**
|
|
113
|
-
|
|
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)
|
|
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)
|
|
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)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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 = '
|
|
77
|
+
const PYRE_SUFFIX = 'pw'
|
|
76
78
|
|
|
77
|
-
/** Grind for a keypair whose base58 address ends with "
|
|
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 "
|
|
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 ──
|