@colin999n9/gworld-agent 0.1.0-alpha.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.
Files changed (86) hide show
  1. package/README.md +127 -0
  2. package/dist/cli.d.ts +12 -0
  3. package/dist/cli.js +256 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/client-installer.d.ts +20 -0
  6. package/dist/client-installer.js +48 -0
  7. package/dist/client-installer.js.map +1 -0
  8. package/dist/config.d.ts +37 -0
  9. package/dist/config.js +184 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/data/indexer-client.d.ts +34 -0
  12. package/dist/data/indexer-client.js +172 -0
  13. package/dist/data/indexer-client.js.map +1 -0
  14. package/dist/data/rpc-reader.d.ts +69 -0
  15. package/dist/data/rpc-reader.js +163 -0
  16. package/dist/data/rpc-reader.js.map +1 -0
  17. package/dist/domain.d.ts +204 -0
  18. package/dist/domain.js +2 -0
  19. package/dist/domain.js.map +1 -0
  20. package/dist/errors.d.ts +10 -0
  21. package/dist/errors.js +16 -0
  22. package/dist/errors.js.map +1 -0
  23. package/dist/factory.d.ts +4 -0
  24. package/dist/factory.js +25 -0
  25. package/dist/factory.js.map +1 -0
  26. package/dist/fs.d.ts +3 -0
  27. package/dist/fs.js +35 -0
  28. package/dist/fs.js.map +1 -0
  29. package/dist/generated/abis.d.ts +7446 -0
  30. package/dist/generated/abis.js +4861 -0
  31. package/dist/generated/abis.js.map +1 -0
  32. package/dist/generated/deployments.d.ts +145 -0
  33. package/dist/generated/deployments.js +150 -0
  34. package/dist/generated/deployments.js.map +1 -0
  35. package/dist/generated/protocol.d.ts +165 -0
  36. package/dist/generated/protocol.js +132 -0
  37. package/dist/generated/protocol.js.map +1 -0
  38. package/dist/geometry.d.ts +24 -0
  39. package/dist/geometry.js +31 -0
  40. package/dist/geometry.js.map +1 -0
  41. package/dist/json.d.ts +3 -0
  42. package/dist/json.js +14 -0
  43. package/dist/json.js.map +1 -0
  44. package/dist/mcp/server.d.ts +4 -0
  45. package/dist/mcp/server.js +134 -0
  46. package/dist/mcp/server.js.map +1 -0
  47. package/dist/mcp/stdio.d.ts +2 -0
  48. package/dist/mcp/stdio.js +23 -0
  49. package/dist/mcp/stdio.js.map +1 -0
  50. package/dist/runner/audit-store.d.ts +27 -0
  51. package/dist/runner/audit-store.js +61 -0
  52. package/dist/runner/audit-store.js.map +1 -0
  53. package/dist/runner/file-state.d.ts +7 -0
  54. package/dist/runner/file-state.js +23 -0
  55. package/dist/runner/file-state.js.map +1 -0
  56. package/dist/runner/legal-actions.d.ts +22 -0
  57. package/dist/runner/legal-actions.js +171 -0
  58. package/dist/runner/legal-actions.js.map +1 -0
  59. package/dist/runner/observation.d.ts +12 -0
  60. package/dist/runner/observation.js +47 -0
  61. package/dist/runner/observation.js.map +1 -0
  62. package/dist/runner/policy.d.ts +10 -0
  63. package/dist/runner/policy.js +68 -0
  64. package/dist/runner/policy.js.map +1 -0
  65. package/dist/runner/runtime.d.ts +73 -0
  66. package/dist/runner/runtime.js +236 -0
  67. package/dist/runner/runtime.js.map +1 -0
  68. package/dist/runner/strategy.d.ts +2 -0
  69. package/dist/runner/strategy.js +19 -0
  70. package/dist/runner/strategy.js.map +1 -0
  71. package/dist/runner/transaction-executor.d.ts +58 -0
  72. package/dist/runner/transaction-executor.js +114 -0
  73. package/dist/runner/transaction-executor.js.map +1 -0
  74. package/dist/runner/writer-lock.d.ts +14 -0
  75. package/dist/runner/writer-lock.js +81 -0
  76. package/dist/runner/writer-lock.js.map +1 -0
  77. package/dist/wallet/keystore.d.ts +18 -0
  78. package/dist/wallet/keystore.js +111 -0
  79. package/dist/wallet/keystore.js.map +1 -0
  80. package/dist/wallet/password-store.d.ts +27 -0
  81. package/dist/wallet/password-store.js +118 -0
  82. package/dist/wallet/password-store.js.map +1 -0
  83. package/package.json +41 -0
  84. package/skill/gworld/SKILL.md +58 -0
  85. package/skill/gworld/references/rules.md +33 -0
  86. package/skill/gworld/references/troubleshooting.md +22 -0
package/dist/config.js ADDED
@@ -0,0 +1,184 @@
1
+ import { homedir } from 'node:os';
2
+ import { join, resolve } from 'node:path';
3
+ import { readFile } from 'node:fs/promises';
4
+ import { getAddress } from 'viem';
5
+ import { AgentError } from './errors.js';
6
+ import { atomicWritePrivateFile } from './fs.js';
7
+ import { getDeployment } from './generated/deployments.js';
8
+ import { parseBigInt, stringifyJson } from './json.js';
9
+ export const ALL_ACTIONS = [
10
+ 'checkin',
11
+ 'claim',
12
+ 'move',
13
+ 'attack',
14
+ 'reinforce',
15
+ 'continueFragmentResolution',
16
+ 'requestMarket',
17
+ 'finalizeMarket',
18
+ 'bet',
19
+ 'settleMarket',
20
+ 'claimMarket',
21
+ ];
22
+ export const DEFAULT_ALLOWED_ACTIONS = [
23
+ 'checkin',
24
+ 'claim',
25
+ 'move',
26
+ 'reinforce',
27
+ 'continueFragmentResolution',
28
+ 'finalizeMarket',
29
+ 'settleMarket',
30
+ 'claimMarket',
31
+ ];
32
+ export function gworldHome() {
33
+ return resolve(process.env.GWORLD_HOME ?? join(homedir(), '.gworld'));
34
+ }
35
+ export function configPath(profile = 'default') {
36
+ assertProfile(profile);
37
+ return join(gworldHome(), 'profiles', profile, 'config.json');
38
+ }
39
+ function assertProfile(profile) {
40
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/.test(profile)) {
41
+ throw new AgentError('config_invalid', 'Profile must contain only letters, numbers, underscore, and hyphen');
42
+ }
43
+ }
44
+ function localNetwork() {
45
+ const deployment = getDeployment(31_337);
46
+ if (!deployment)
47
+ throw new AgentError('config_invalid', 'Generated local deployment is missing');
48
+ return {
49
+ name: 'local',
50
+ chainId: deployment.chainId,
51
+ rpcUrl: 'http://127.0.0.1:8545',
52
+ indexerUrl: 'http://127.0.0.1:42069',
53
+ routerAddress: deployment.router.address,
54
+ confirmations: deployment.confirmations,
55
+ };
56
+ }
57
+ export function networkPreset(name) {
58
+ switch (name) {
59
+ case 'local': return localNetwork();
60
+ case 'testnet': {
61
+ const deployment = getDeployment(7_771_625);
62
+ if (!deployment)
63
+ throw new AgentError('config_invalid', 'Generated Gravity Testnet deployment is missing');
64
+ return {
65
+ name: 'testnet',
66
+ chainId: deployment.chainId,
67
+ rpcUrl: 'https://testnet-rpc.gravity.xyz',
68
+ indexerUrl: 'https://gworld-indexer.gravity.xyz',
69
+ routerAddress: deployment.router.address,
70
+ confirmations: deployment.confirmations,
71
+ };
72
+ }
73
+ default: return null;
74
+ }
75
+ }
76
+ export function defaultConfig(profile = 'default') {
77
+ assertProfile(profile);
78
+ const root = join(gworldHome(), 'profiles', profile);
79
+ return {
80
+ version: 1,
81
+ profile,
82
+ network: localNetwork(),
83
+ wallet: { keystorePath: join(root, 'wallet.json') },
84
+ runner: {
85
+ agentId: null,
86
+ mapRadius: 8,
87
+ pollIntervalMs: 5_000,
88
+ actionTtlMs: 30_000,
89
+ indexingTimeoutMs: 15_000,
90
+ },
91
+ policy: {
92
+ maxApPerRoundCap: 600n,
93
+ maxGBetPerAction: 0n,
94
+ maxGSpendPerDay: 0n,
95
+ maxTransactionsPerRound: 3,
96
+ allowedAgentIds: [],
97
+ allowedActions: [...DEFAULT_ALLOWED_ACTIONS],
98
+ autoExecuteRisk: 'low',
99
+ },
100
+ auditPath: join(root, 'audit.jsonl'),
101
+ statePath: join(root, 'state.json'),
102
+ };
103
+ }
104
+ function parseUrl(value, label) {
105
+ try {
106
+ const url = new URL(String(value));
107
+ if (url.protocol !== 'http:' && url.protocol !== 'https:')
108
+ throw new Error();
109
+ return url.toString().replace(/\/$/, '');
110
+ }
111
+ catch {
112
+ throw new AgentError('config_invalid', `${label} must be an http(s) URL`);
113
+ }
114
+ }
115
+ export function parseConfig(value) {
116
+ const wire = value;
117
+ try {
118
+ assertProfile(wire.profile);
119
+ if (wire.version !== 1)
120
+ throw new Error('version must be 1');
121
+ if (!Number.isSafeInteger(wire.network.chainId) || wire.network.chainId <= 0)
122
+ throw new Error('invalid chain id');
123
+ if (!Number.isInteger(wire.network.confirmations) || wire.network.confirmations < 0)
124
+ throw new Error('invalid confirmations');
125
+ if (!Number.isInteger(wire.runner.mapRadius) || wire.runner.mapRadius < 1 || wire.runner.mapRadius > 50) {
126
+ throw new Error('map radius must be 1..50');
127
+ }
128
+ if (!Number.isInteger(wire.runner.pollIntervalMs) || wire.runner.pollIntervalMs < 250)
129
+ throw new Error('poll interval too low');
130
+ if (!Number.isInteger(wire.runner.actionTtlMs) || wire.runner.actionTtlMs < 1_000)
131
+ throw new Error('action ttl too low');
132
+ if (!Number.isInteger(wire.runner.indexingTimeoutMs) || wire.runner.indexingTimeoutMs < 1_000) {
133
+ throw new Error('indexing timeout too low');
134
+ }
135
+ if (!Number.isInteger(wire.policy.maxTransactionsPerRound) || wire.policy.maxTransactionsPerRound < 0) {
136
+ throw new Error('invalid transaction limit');
137
+ }
138
+ if (!['low', 'medium', 'high'].includes(wire.policy.autoExecuteRisk))
139
+ throw new Error('invalid risk');
140
+ if (!wire.policy.allowedActions.every((action) => ALL_ACTIONS.includes(action)))
141
+ throw new Error('invalid action');
142
+ const routerAddress = getAddress(wire.network.routerAddress).toLowerCase();
143
+ return {
144
+ ...wire,
145
+ network: {
146
+ ...wire.network,
147
+ rpcUrl: parseUrl(wire.network.rpcUrl, 'RPC URL'),
148
+ indexerUrl: parseUrl(wire.network.indexerUrl, 'Indexer URL'),
149
+ routerAddress,
150
+ },
151
+ runner: { ...wire.runner, agentId: wire.runner.agentId == null ? null : parseBigInt(wire.runner.agentId, 'agentId') },
152
+ policy: {
153
+ ...wire.policy,
154
+ maxApPerRoundCap: parseBigInt(wire.policy.maxApPerRoundCap, 'maxApPerRoundCap'),
155
+ maxGBetPerAction: parseBigInt(wire.policy.maxGBetPerAction, 'maxGBetPerAction'),
156
+ maxGSpendPerDay: parseBigInt(wire.policy.maxGSpendPerDay, 'maxGSpendPerDay'),
157
+ allowedAgentIds: wire.policy.allowedAgentIds.map((id) => parseBigInt(id, 'allowedAgentId')),
158
+ },
159
+ };
160
+ }
161
+ catch (error) {
162
+ if (error instanceof AgentError)
163
+ throw error;
164
+ throw new AgentError('config_invalid', `Invalid Agent config: ${error instanceof Error ? error.message : String(error)}`);
165
+ }
166
+ }
167
+ export async function loadConfig(profile = 'default') {
168
+ const path = configPath(profile);
169
+ try {
170
+ return parseConfig(JSON.parse(await readFile(path, 'utf8')));
171
+ }
172
+ catch (error) {
173
+ if (error.code === 'ENOENT')
174
+ return defaultConfig(profile);
175
+ if (error instanceof AgentError)
176
+ throw error;
177
+ throw new AgentError('config_invalid', `Cannot load config ${path}`, error);
178
+ }
179
+ }
180
+ export async function saveConfig(config) {
181
+ const validated = parseConfig(JSON.parse(stringifyJson(config)));
182
+ await atomicWritePrivateFile(configPath(validated.profile), `${stringifyJson(validated, 2)}\n`);
183
+ }
184
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { Address, AgentSummary, FragmentView, IndexerSync, MarketView, TileView } from '../domain.js';
2
+ export declare class AgentIndexerClient {
3
+ private readonly baseUrl;
4
+ private readonly fetcher;
5
+ private readonly pollIntervalMs;
6
+ private readonly sleep;
7
+ private readonly requestTimeoutMs;
8
+ constructor(baseUrl: string, fetcher?: typeof fetch, pollIntervalMs?: number, sleep?: (milliseconds: number) => Promise<void>, requestTimeoutMs?: number);
9
+ private get;
10
+ status(): Promise<IndexerSync>;
11
+ waitForBlock(blockNumber: bigint, timeoutMs: number): Promise<IndexerSync>;
12
+ walletAgents(wallet: Address): Promise<AgentSummary[]>;
13
+ getAgent(agentId: bigint): Promise<AgentSummary>;
14
+ world(center: {
15
+ q: number;
16
+ r: number;
17
+ }, radius: number): Promise<{
18
+ round: bigint;
19
+ asOfBlock: bigint;
20
+ sync: IndexerSync;
21
+ agents: AgentSummary[];
22
+ tiles: TileView[];
23
+ fragments: FragmentView[];
24
+ }>;
25
+ markets(wallet: Address, limit?: number): Promise<MarketView[]>;
26
+ market(marketId: bigint, wallet: Address): Promise<MarketView>;
27
+ marketRequest(round: bigint): Promise<{
28
+ round: bigint;
29
+ targetBlock: bigint | null;
30
+ marketId: bigint | null;
31
+ state: 'available' | 'too_late' | 'waiting' | 'finalizable' | 'expired' | 'opened';
32
+ updatedAtBlock: bigint;
33
+ }>;
34
+ }
@@ -0,0 +1,172 @@
1
+ import { AgentError } from '../errors.js';
2
+ import { parseBigInt } from '../json.js';
3
+ function agent(value) {
4
+ return {
5
+ id: parseBigInt(value.id, 'agent id'),
6
+ owner: value.owner.toLowerCase(),
7
+ lifecycle: value.lifecycle,
8
+ position: value.position,
9
+ territoryCount: parseBigInt(value.territoryCount, 'territory count'),
10
+ pendingRequest: value.pendingRequest
11
+ ? { ...value.pendingRequest, rng: value.pendingRequest.rng.toLowerCase(), targetBlock: parseBigInt(value.pendingRequest.targetBlock) }
12
+ : null,
13
+ };
14
+ }
15
+ function market(value) {
16
+ return {
17
+ id: parseBigInt(value.marketId, 'market id'),
18
+ sourceAddress: value.sourceAddress.toLowerCase(),
19
+ writeState: value.writeState,
20
+ currentRound: parseBigInt(value.currentRound),
21
+ asOfBlock: parseBigInt(value.asOfBlock),
22
+ tileKey: parseBigInt(value.tileKey),
23
+ openRound: parseBigInt(value.openRound),
24
+ closeRound: parseBigInt(value.closeRound),
25
+ settleRound: parseBigInt(value.settleRound),
26
+ status: value.status,
27
+ totalPoolG: parseBigInt(value.totalPoolG),
28
+ options: value.options.map((option) => ({
29
+ index: parseBigInt(option.index),
30
+ agentId: option.agentId == null ? null : parseBigInt(option.agentId),
31
+ poolG: parseBigInt(option.poolG),
32
+ })),
33
+ winningOption: value.winningOption == null ? null : parseBigInt(value.winningOption),
34
+ winningPoolG: parseBigInt(value.winningPoolG),
35
+ finalOwnerAgentId: value.finalOwnerAgentId == null ? null : parseBigInt(value.finalOwnerAgentId),
36
+ refundable: value.refundable,
37
+ apRewardCap: parseBigInt(value.apRewardCap),
38
+ walletPosition: value.walletPosition
39
+ ? {
40
+ agentId: parseBigInt(value.walletPosition.agentId),
41
+ optionIndex: parseBigInt(value.walletPosition.optionIndex),
42
+ stakeG: parseBigInt(value.walletPosition.stakeG),
43
+ claimed: value.walletPosition.claimed,
44
+ payoutG: parseBigInt(value.walletPosition.payoutG),
45
+ claimedApRewardCap: parseBigInt(value.walletPosition.claimedApRewardCap),
46
+ }
47
+ : null,
48
+ };
49
+ }
50
+ export class AgentIndexerClient {
51
+ baseUrl;
52
+ fetcher;
53
+ pollIntervalMs;
54
+ sleep;
55
+ requestTimeoutMs;
56
+ constructor(baseUrl, fetcher = fetch, pollIntervalMs = 500, sleep = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)), requestTimeoutMs = 10_000) {
57
+ this.baseUrl = baseUrl;
58
+ this.fetcher = fetcher;
59
+ this.pollIntervalMs = pollIntervalMs;
60
+ this.sleep = sleep;
61
+ this.requestTimeoutMs = requestTimeoutMs;
62
+ }
63
+ async get(path, query = {}) {
64
+ const url = new URL(path.replace(/^\/+/, ''), `${this.baseUrl.replace(/\/$/, '')}/`);
65
+ for (const [name, value] of Object.entries(query))
66
+ if (value != null)
67
+ url.searchParams.set(name, String(value));
68
+ let response;
69
+ try {
70
+ response = await this.fetcher.call(globalThis, url, { signal: AbortSignal.timeout(this.requestTimeoutMs) });
71
+ }
72
+ catch (error) {
73
+ throw new AgentError('indexer_unavailable', `Indexer request failed: ${url.pathname}`, error);
74
+ }
75
+ if (response.status === 404)
76
+ throw new AgentError('agent_missing', `Indexer resource not found: ${url.pathname}`);
77
+ if (!response.ok)
78
+ throw new AgentError('indexer_unavailable', `Indexer returned HTTP ${response.status}: ${url.pathname}`);
79
+ const envelope = (await response.json());
80
+ if (!envelope || !('data' in envelope) || !/^(0|[1-9]\d*)$/.test(String(envelope.asOfBlock))) {
81
+ throw new AgentError('indexer_unavailable', `Indexer returned an invalid envelope: ${url.pathname}`);
82
+ }
83
+ return envelope;
84
+ }
85
+ async status() {
86
+ const { data } = await this.get('/v1/status');
87
+ return {
88
+ state: data.state,
89
+ indexedBlock: parseBigInt(data.indexedBlock),
90
+ finalizedBlock: parseBigInt(data.finalizedBlock),
91
+ chainHeadBlock: parseBigInt(data.chainHeadBlock),
92
+ };
93
+ }
94
+ async waitForBlock(blockNumber, timeoutMs) {
95
+ const startedAt = Date.now();
96
+ while (true) {
97
+ const status = await this.status();
98
+ if (status.state === 'rebuilding')
99
+ throw new AgentError('indexer_lagging', 'Indexer is rebuilding');
100
+ if (status.indexedBlock > status.chainHeadBlock) {
101
+ throw new AgentError('indexer_lagging', 'Indexer cursor is ahead of the current chain head');
102
+ }
103
+ if (status.indexedBlock >= blockNumber)
104
+ return status;
105
+ if (Date.now() - startedAt >= timeoutMs) {
106
+ throw new AgentError('indexer_lagging', `Indexer did not reach block ${blockNumber} within ${timeoutMs}ms`);
107
+ }
108
+ await this.sleep(this.pollIntervalMs);
109
+ }
110
+ }
111
+ async walletAgents(wallet) {
112
+ const { data } = await this.get(`/v1/wallets/${wallet}/agents`);
113
+ return data.map(agent);
114
+ }
115
+ async getAgent(agentId) {
116
+ const { data } = await this.get(`/v1/agents/${agentId}`);
117
+ return agent(data);
118
+ }
119
+ async world(center, radius) {
120
+ const { data, asOfBlock } = await this.get('/v1/world', { q: center.q, r: center.r, radius });
121
+ const indexedBlock = parseBigInt(data.sync.indexedBlock);
122
+ if (indexedBlock !== parseBigInt(asOfBlock))
123
+ throw new AgentError('indexer_lagging', 'World snapshot has mismatched asOfBlock');
124
+ return {
125
+ round: parseBigInt(data.round),
126
+ asOfBlock: indexedBlock,
127
+ sync: {
128
+ state: data.sync.state,
129
+ indexedBlock,
130
+ finalizedBlock: parseBigInt(data.sync.finalizedBlock),
131
+ chainHeadBlock: parseBigInt(data.sync.chainHeadBlock),
132
+ },
133
+ agents: data.agents.map(agent),
134
+ tiles: data.tiles.map((tile) => ({
135
+ ...tile,
136
+ key: parseBigInt(tile.key),
137
+ ownerAgentId: tile.ownerAgentId == null ? null : parseBigInt(tile.ownerAgentId),
138
+ lastReinforceRound: parseBigInt(tile.lastReinforceRound),
139
+ })),
140
+ fragments: data.fragmentResolutions.map((fragment) => ({
141
+ ...fragment,
142
+ agentId: parseBigInt(fragment.agentId),
143
+ jobId: parseBigInt(fragment.jobId),
144
+ cursor: parseBigInt(fragment.cursor),
145
+ sourceRound: parseBigInt(fragment.sourceRound),
146
+ sourceTileCount: parseBigInt(fragment.sourceTileCount),
147
+ classifiedDrops: parseBigInt(fragment.classifiedDrops),
148
+ droppedCount: parseBigInt(fragment.droppedCount),
149
+ updatedAtBlock: parseBigInt(fragment.updatedAtBlock),
150
+ })),
151
+ };
152
+ }
153
+ async markets(wallet, limit = 20) {
154
+ const { data } = await this.get('/v1/markets', { limit });
155
+ return Promise.all(data.map((item) => this.market(parseBigInt(item.marketId), wallet)));
156
+ }
157
+ async market(marketId, wallet) {
158
+ const { data } = await this.get(`/v1/markets/${marketId}`, { wallet });
159
+ return market(data);
160
+ }
161
+ async marketRequest(round) {
162
+ const { data } = await this.get(`/v1/market-requests/${round}`);
163
+ return {
164
+ round: parseBigInt(data.round),
165
+ targetBlock: data.targetBlock == null ? null : parseBigInt(data.targetBlock),
166
+ marketId: data.marketId == null ? null : parseBigInt(data.marketId),
167
+ state: data.state,
168
+ updatedAtBlock: parseBigInt(data.updatedAtBlock),
169
+ };
170
+ }
171
+ }
172
+ //# sourceMappingURL=indexer-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexer-client.js","sourceRoot":"","sources":["../../src/data/indexer-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import type { Abi } from 'viem';
2
+ import type { Address, AgentActionState } from '../domain.js';
3
+ type ReadRequest = {
4
+ address: Address;
5
+ abi: Abi;
6
+ functionName: string;
7
+ args?: readonly unknown[];
8
+ blockNumber?: bigint;
9
+ };
10
+ export type RunnerPublicClient = {
11
+ getChainId(): Promise<number>;
12
+ getBlock(): Promise<{
13
+ number: bigint;
14
+ timestamp: bigint;
15
+ }>;
16
+ getBalance(args: {
17
+ address: Address;
18
+ }): Promise<bigint>;
19
+ readContract(args: ReadRequest): Promise<unknown>;
20
+ multicall(args: {
21
+ contracts: readonly ReadRequest[];
22
+ allowFailure: false;
23
+ blockNumber?: bigint;
24
+ }): Promise<readonly unknown[]>;
25
+ };
26
+ export type WalletAsset = {
27
+ gToken: Address | null;
28
+ mode: 'native' | 'erc20';
29
+ decimals: number;
30
+ balance: bigint;
31
+ };
32
+ export type MarketPayment = WalletAsset & {
33
+ market: Address;
34
+ escrow: Address;
35
+ allowance: bigint;
36
+ };
37
+ export type StrongTile = {
38
+ key: bigint;
39
+ ownerAgentId: bigint | null;
40
+ storedDefense: number;
41
+ lastReinforceRound: bigint;
42
+ activated: boolean;
43
+ };
44
+ export type CurrentModules = {
45
+ registry: Address;
46
+ ledger: Address;
47
+ world: Address;
48
+ market: Address;
49
+ escrow: Address;
50
+ };
51
+ export declare class AgentRpcReader {
52
+ private readonly client;
53
+ readonly chainId: number;
54
+ readonly router: Address;
55
+ constructor(client: RunnerPublicClient, chainId: number, router: Address);
56
+ assertNetwork(): Promise<void>;
57
+ block(): Promise<{
58
+ number: bigint;
59
+ timestamp: bigint;
60
+ }>;
61
+ private many;
62
+ modules(blockNumber?: bigint): Promise<CurrentModules>;
63
+ agent(agentId: bigint): Promise<AgentActionState>;
64
+ tile(tileKey: bigint): Promise<StrongTile>;
65
+ private assetAt;
66
+ walletAsset(wallet: Address): Promise<WalletAsset>;
67
+ marketPayment(marketId: bigint, wallet: Address): Promise<MarketPayment>;
68
+ }
69
+ export {};
@@ -0,0 +1,163 @@
1
+ import { AgentError } from '../errors.js';
2
+ import { contractAbis } from '../generated/abis.js';
3
+ import { protocolConfig } from '../generated/protocol.js';
4
+ function address(value) {
5
+ if (typeof value !== 'string' || !/^0x[0-9a-fA-F]{40}$/.test(value)) {
6
+ throw new AgentError('rpc_unavailable', `Contract returned an invalid address: ${String(value)}`);
7
+ }
8
+ return value.toLowerCase();
9
+ }
10
+ function tuple(value, name, index) {
11
+ return Array.isArray(value) ? value[index] : value[name];
12
+ }
13
+ function coord(value) {
14
+ return { q: Number(tuple(value, 'q', 0)), r: Number(tuple(value, 'r', 1)) };
15
+ }
16
+ export class AgentRpcReader {
17
+ client;
18
+ chainId;
19
+ router;
20
+ constructor(client, chainId, router) {
21
+ this.client = client;
22
+ this.chainId = chainId;
23
+ this.router = router;
24
+ }
25
+ async assertNetwork() {
26
+ let actual;
27
+ try {
28
+ actual = await this.client.getChainId();
29
+ }
30
+ catch (error) {
31
+ throw new AgentError('rpc_unavailable', 'Unable to read RPC chain id', error);
32
+ }
33
+ if (actual !== this.chainId)
34
+ throw new AgentError('wrong_chain', `RPC chain ${actual} does not match configured chain ${this.chainId}`);
35
+ }
36
+ async block() {
37
+ try {
38
+ return await this.client.getBlock();
39
+ }
40
+ catch (error) {
41
+ throw new AgentError('rpc_unavailable', 'Unable to read the current block', error);
42
+ }
43
+ }
44
+ async many(requests, blockNumber) {
45
+ try {
46
+ return await this.client.multicall({ contracts: requests, allowFailure: false, blockNumber });
47
+ }
48
+ catch (error) {
49
+ const message = error instanceof Error ? `${error.name} ${error.message}` : String(error);
50
+ if (!message.includes('ChainDoesNotSupportContract') && !message.includes('multicall3'))
51
+ throw error;
52
+ return Promise.all(requests.map((request) => this.client.readContract({ ...request, blockNumber })));
53
+ }
54
+ }
55
+ async modules(blockNumber) {
56
+ const names = ['agentRegistry', 'apLedger', 'worldCore', 'predictionMarket', 'marketEscrow'];
57
+ const values = await this.many(names.map((functionName) => ({ address: this.router, abi: contractAbis.router, functionName })), blockNumber);
58
+ return {
59
+ registry: address(values[0]),
60
+ ledger: address(values[1]),
61
+ world: address(values[2]),
62
+ market: address(values[3]),
63
+ escrow: address(values[4]),
64
+ };
65
+ }
66
+ async agent(agentId) {
67
+ try {
68
+ const block = await this.client.getBlock();
69
+ const modules = await this.modules(block.number);
70
+ const [ownerValue, activeValue] = await this.many([
71
+ { address: modules.registry, abi: contractAbis.registry, functionName: 'ownerOf', args: [agentId] },
72
+ { address: modules.registry, abi: contractAbis.registry, functionName: 'isActive', args: [agentId] },
73
+ ], block.number);
74
+ const active = Boolean(activeValue);
75
+ const values = await this.many([
76
+ { address: modules.ledger, abi: contractAbis.ledger, functionName: 'balanceOf', args: [agentId] },
77
+ { address: modules.ledger, abi: contractAbis.ledger, functionName: 'spentThisRound', args: [agentId] },
78
+ { address: modules.ledger, abi: contractAbis.ledger, functionName: 'lastCheckinAt', args: [agentId] },
79
+ { address: modules.world, abi: contractAbis.world, functionName: 'actionNonce', args: [agentId] },
80
+ { address: modules.world, abi: contractAbis.world, functionName: 'fragmentResolutionOf', args: [agentId] },
81
+ ...(active
82
+ ? [{ address: modules.registry, abi: contractAbis.registry, functionName: 'positionOf', args: [agentId] }]
83
+ : []),
84
+ ], block.number);
85
+ const fragment = values[4];
86
+ return {
87
+ blockNumber: block.number,
88
+ blockTimestamp: block.timestamp,
89
+ currentRound: block.number / protocolConfig.turnBlocks,
90
+ owner: address(ownerValue),
91
+ active,
92
+ position: active ? coord(values[5]) : null,
93
+ apBalanceCap: BigInt(values[0]),
94
+ spentThisRoundCap: BigInt(values[1]),
95
+ lastCheckinAt: BigInt(values[2]),
96
+ actionNonce: BigInt(values[3]),
97
+ fragment: {
98
+ jobId: BigInt(tuple(fragment, 'jobId', 0)),
99
+ phase: BigInt(tuple(fragment, 'phase', 1)),
100
+ cursor: BigInt(tuple(fragment, 'cursor', 2)),
101
+ sourceRound: BigInt(tuple(fragment, 'sourceRound', 3)),
102
+ sourceTileCount: BigInt(tuple(fragment, 'sourceTileCount', 4)),
103
+ classifiedDrops: BigInt(tuple(fragment, 'classifiedDrops', 5)),
104
+ },
105
+ };
106
+ }
107
+ catch (error) {
108
+ if (error instanceof AgentError)
109
+ throw error;
110
+ throw new AgentError('rpc_unavailable', `Unable to read Agent ${agentId}`, error);
111
+ }
112
+ }
113
+ async tile(tileKey) {
114
+ const block = await this.client.getBlock();
115
+ const modules = await this.modules(block.number);
116
+ const value = await this.client.readContract({
117
+ address: modules.world,
118
+ abi: contractAbis.world,
119
+ functionName: 'tileOf',
120
+ args: [tileKey],
121
+ blockNumber: block.number,
122
+ });
123
+ const owner = BigInt(tuple(value, 'owner', 0));
124
+ return {
125
+ key: tileKey,
126
+ ownerAgentId: owner === 0n ? null : owner,
127
+ storedDefense: Number(tuple(value, 'defense', 1)),
128
+ lastReinforceRound: BigInt(tuple(value, 'lastReinforceRound', 2)),
129
+ activated: Boolean(tuple(value, 'activated', 3)),
130
+ };
131
+ }
132
+ async assetAt(escrow, wallet) {
133
+ const token = address(await this.client.readContract({ address: escrow, abi: contractAbis.escrow, functionName: 'G_TOKEN' }));
134
+ if (token === '0x0000000000000000000000000000000000000000') {
135
+ return { gToken: null, mode: 'native', decimals: 18, balance: await this.client.getBalance({ address: wallet }) };
136
+ }
137
+ const [balance, decimals] = await this.many([
138
+ { address: token, abi: contractAbis.erc20, functionName: 'balanceOf', args: [wallet] },
139
+ { address: token, abi: contractAbis.erc20, functionName: 'decimals' },
140
+ ]);
141
+ return { gToken: token, mode: 'erc20', decimals: Number(decimals), balance: BigInt(balance) };
142
+ }
143
+ async walletAsset(wallet) {
144
+ const { escrow } = await this.modules();
145
+ return this.assetAt(escrow, wallet);
146
+ }
147
+ async marketPayment(marketId, wallet) {
148
+ const { market } = await this.modules();
149
+ const state = await this.client.readContract({ address: market, abi: contractAbis.market, functionName: 'marketOf', args: [marketId] });
150
+ const escrow = address(tuple(state, 'escrow', 1));
151
+ const asset = await this.assetAt(escrow, wallet);
152
+ const allowance = asset.mode === 'erc20'
153
+ ? BigInt(await this.client.readContract({
154
+ address: asset.gToken,
155
+ abi: contractAbis.erc20,
156
+ functionName: 'allowance',
157
+ args: [wallet, escrow],
158
+ }))
159
+ : 0n;
160
+ return { ...asset, market, escrow, allowance };
161
+ }
162
+ }
163
+ //# sourceMappingURL=rpc-reader.js.map