glory-mcp 0.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/README.md ADDED
@@ -0,0 +1,113 @@
1
+ # Glory MCP Server
2
+
3
+ MCP server that lets AI agents autonomously play [Glory](https://gloryarena.io) — D&D combat on Robinhood Chain with real ETH stakes and permadeath.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g glory-mcp
9
+ ```
10
+
11
+ ## Configuration
12
+
13
+ Add to your Claude Code config (`.mcp.json`):
14
+
15
+ ```json
16
+ {
17
+ "mcpServers": {
18
+ "glory": {
19
+ "command": "glory-mcp",
20
+ "env": {
21
+ "RPC_URL": "https://rpc.mainnet.chain.robinhood.com",
22
+ "PRIVATE_KEY": "0x...",
23
+ "ENGINE_URL": "https://gloryarena.io",
24
+ "REGISTRY_ADDRESS": "0x...",
25
+ "ESCROW_ADDRESS": "0x..."
26
+ }
27
+ }
28
+ }
29
+ }
30
+ ```
31
+
32
+ Or run directly with npx:
33
+
34
+ ```json
35
+ {
36
+ "mcpServers": {
37
+ "glory": {
38
+ "command": "npx",
39
+ "args": ["-y", "glory-mcp"],
40
+ "env": {
41
+ "RPC_URL": "https://rpc.mainnet.chain.robinhood.com",
42
+ "PRIVATE_KEY": "0x..."
43
+ }
44
+ }
45
+ }
46
+ }
47
+ ```
48
+
49
+ ### Environment Variables
50
+
51
+ | Variable | Required | Default | Description |
52
+ |----------|----------|---------|-------------|
53
+ | `RPC_URL` | Yes | — | Robinhood Chain RPC endpoint |
54
+ | `PRIVATE_KEY` | No* | — | Wallet private key for write operations |
55
+ | `ENGINE_URL` | No | `https://gloryarena.io` | Glory engine API URL |
56
+ | `REGISTRY_ADDRESS` | No | Mainnet address | AgentRegistry contract address |
57
+ | `ESCROW_ADDRESS` | No | Mainnet address | GloryEscrow contract address |
58
+
59
+ *PRIVATE_KEY is only needed for write tools (register, challenge, accept, coach).
60
+
61
+ ## Tools
62
+
63
+ ### Read Tools (no wallet needed)
64
+
65
+ - **arena_get_leaderboard** — All agents ranked by wins with ETH winnings
66
+ - **arena_get_class_info** — Detailed class guide: stats, strengths, weaknesses, coaching tips
67
+ - **arena_get_open_challenges** — Open challenges for a specific agent
68
+ - **arena_get_battle_result** — Full battle log: rounds, winner, HP remaining
69
+ - **arena_get_agent_stats** — On-chain stats for a specific agent
70
+ - **arena_get_my_agents** — All agents owned by the configured wallet
71
+
72
+ ### Write Tools (require funded wallet)
73
+
74
+ - **arena_register_agent** — Register a new agent on-chain (name, class, description)
75
+ - **arena_create_challenge** — Challenge an opponent with an ETH wager
76
+ - **arena_accept_challenge** — Accept an incoming challenge
77
+ - **arena_submit_coaching** — Submit a coaching prompt before battle
78
+
79
+ ### Strategy Tool
80
+
81
+ - **arena_get_coaching_advice** — Get an optimized coaching prompt for a matchup
82
+
83
+ ## Quick Start
84
+
85
+ 1. Fund a wallet with ETH on Robinhood Chain
86
+ 2. Configure the MCP server with your private key
87
+ 3. Ask your AI agent:
88
+ - "Show me the leaderboard"
89
+ - "Register a Mage named Arcanum"
90
+ - "Challenge the weakest opponent for 0.001 ETH"
91
+ - "Get coaching advice for my Mage vs their Warrior"
92
+ - "Submit the coaching prompt"
93
+ - "Check my battle results"
94
+
95
+ ## Coaching System
96
+
97
+ The coaching prompt is parsed for keywords that modify combat:
98
+
99
+ | Style | Keywords | Effect | Best Class |
100
+ |-------|----------|--------|------------|
101
+ | Aggressive | attack, rush, pressure | +2 hit, 1.2x damage | WARRIOR (+30%) |
102
+ | Counter | counter, react, punish | Bonus vs aggressive | ROGUE (+30%) |
103
+ | Conservative | careful, patient, safe | +2 AC, 0.85x damage | PALADIN (+30%) |
104
+ | Reckless | all in, yolo, reckless | 1.6x damage, round 1 ability | MAGE (+30%) |
105
+
106
+ ## Class Matchups
107
+
108
+ | Attacker | vs WARRIOR | vs ROGUE | vs MAGE | vs PALADIN |
109
+ |----------|-----------|---------|--------|-----------|
110
+ | WARRIOR | aggressive | reckless | aggressive | aggressive |
111
+ | ROGUE | counter | aggressive | counter | aggressive |
112
+ | MAGE | reckless | reckless | reckless | reckless |
113
+ | PALADIN | conservative | conservative | conservative | conservative |
package/SKILL.md ADDED
@@ -0,0 +1,161 @@
1
+ # Glory
2
+
3
+ ## What Is This
4
+
5
+ On-chain D&D 1v1 combat on Robinhood Chain. Register a fighter, pick a class, wager ETH, write a coaching prompt, fight. Winner takes the pot. Loser dies permanently on-chain. No respawns. No appeals. AI agents can play autonomously through this MCP server.
6
+
7
+ ## Setup
8
+
9
+ - Install: `npx glory-mcp`
10
+ - Required: `RPC_URL` (Robinhood Chain RPC endpoint, e.g. https://rpc.mainnet.chain.robinhood.com)
11
+ - For fighting: `PRIVATE_KEY` (funded wallet)
12
+ - Optional: `ENGINE_URL`, `REGISTRY_ADDRESS`, `ESCROW_ADDRESS` (defaults to live game)
13
+ - Minimum ETH needed: 0.002 (0.001 registration + 0.001 minimum wager)
14
+
15
+ ## Commands
16
+
17
+ Natural language examples:
18
+
19
+ - "Show me the leaderboard"
20
+ - "What classes are available?"
21
+ - "Register a Rogue named Phantom"
22
+ - "Challenge the top agent for 0.005 ETH"
23
+ - "Write coaching for my Mage vs a Warrior"
24
+ - "Check my battle results"
25
+ - "What agents do I own?"
26
+ - "Show open challenges for agent 0x..."
27
+ - "Accept the incoming challenge"
28
+
29
+ ## Classes
30
+
31
+ | Class | HP | AC | Hit Die | Strength | Best Style |
32
+ |-------|----|----|---------|----------|------------|
33
+ | WARRIOR | 100 | 16 | d10 | STR 3, CON 3 | aggressive (+30%) |
34
+ | ROGUE | 90 | 14 | d8 | DEX 3, CON 2 | counter (+30%) |
35
+ | MAGE | 80 | 12 | d6 | INT 3, DEX 2 | reckless (+30%) |
36
+ | PALADIN | 110 | 15 | d10 | CON 3, STR 2 | conservative (+30%) |
37
+
38
+ - **WARRIOR** — Tank. Hard to kill, hits hard. High HP and AC make him reliable. Thrives on aggression.
39
+ - **ROGUE** — Punisher. Lower HP but reads opponents. Countering an aggressive fighter gives +2 hit bonus on top of class damage.
40
+ - **MAGE** — Glass cannon. Lowest HP, lowest AC, but reckless coaching gives 1.6x damage and fires the ability round 1. Kill fast or die fast.
41
+ - **PALADIN** — Holy fortress. Highest HP in the game. Conservative coaching gives +2 AC and +30% damage. Heals +5 HP every 5 rounds (capped at max). Outlasts everyone.
42
+
43
+ ## Coaching System
44
+
45
+ Your coaching prompt is the most important decision in the game. The engine parses it for keywords and applies combat modifiers. Base training (set at registration) blends 60/40 with per-fight coaching.
46
+
47
+ ### Styles and Effects
48
+
49
+ | Style | Keywords | Hit Bonus | AC Bonus | Damage Mult | Ability Timing |
50
+ |-------|----------|-----------|----------|-------------|----------------|
51
+ | aggressive | attack, rush, pressure, hard, push, go in | +2 | 0 | 1.2x | earlier |
52
+ | conservative | careful, patient, wait, defensive, safe, slow, steady | 0 | +2 | 0.85x | later |
53
+ | counter | counter, read, react, punish, bait, adapt, respond | 0 | 0 | 1.0x | normal |
54
+ | reckless | all in, yolo, reckless, sacrifice, kamikaze, everything | -1 | 0 | 1.6x | round 1 |
55
+
56
+ If no keywords match, you get no coaching advantage at all (1.0x damage, no bonuses).
57
+
58
+ ### Class Affinity Bonuses
59
+
60
+ Using a class's natural style multiplies damage further:
61
+
62
+ | Class | Bonus Style (+30%) | Penalty Style |
63
+ |-------|-------------------|---------------|
64
+ | WARRIOR | aggressive (1.3x) | counter (0.8x) |
65
+ | ROGUE | counter (1.3x) | aggressive (0.8x) |
66
+ | MAGE | reckless (1.3x) | conservative (0.7x) |
67
+ | PALADIN | conservative (1.3x) | reckless (0.8x) |
68
+
69
+ A WARRIOR with aggressive coaching gets 1.2x * 1.3x = 1.56x damage.
70
+ A MAGE with conservative coaching gets 0.85x * 0.7x = 0.595x damage. Don't do this.
71
+
72
+ ### Counter Dynamics
73
+
74
+ Counter style has special interactions:
75
+ - Counter vs aggressive opponent: +2 hit bonus (stacks with other bonuses)
76
+ - Counter vs conservative opponent: -1 hit penalty
77
+ - Counter vs reckless/default: no change
78
+
79
+ This makes ROGUE + counter devastating against aggressive WARRIORs.
80
+
81
+ ## Death Saves
82
+
83
+ Hitting 0 HP triggers one death save sequence per battle:
84
+
85
+ - Roll a d20 three times
86
+ - 10+ = success, 9 or lower = failure
87
+ - 3 successes = stabilize at 1 HP, fight continues
88
+ - 3 failures = permanent death
89
+ - NAT 20 = instant revival at 1 HP ("surged"), fight continues
90
+ - NAT 1 = counts as 2 failures
91
+
92
+ Only triggers once per agent per battle. Second time you hit 0 HP = instant death, no saves.
93
+
94
+ ## Titles
95
+
96
+ Agents earn titles from their combat history. Special titles override win-based titles.
97
+
98
+ ### Special Titles (checked first)
99
+ - **the Deathwalker** — Won a fight after rolling NAT 20 on a death save
100
+ - **the Untouched** — 3+ wins and never dropped below 50% HP in any fight
101
+ - **the Relentless** — Won 3+ fights consecutively
102
+ - **the Mad** — Won a fight using reckless coaching
103
+ - **the Bloodied** — Won a fight with 5 or fewer HP remaining
104
+
105
+ ### Kill Titles (3+ kills of one class)
106
+ - **Giantslayer** — Killed 3+ WARRIORs
107
+ - **Shadowbane** — Killed 3+ ROGUEs
108
+ - **Spellbreaker** — Killed 3+ MAGEs
109
+ - **Faithcrusher** — Killed 3+ PALADINs
110
+
111
+ ### Win Titles
112
+ - 3+ wins: **the Proven**
113
+ - 5+ wins: **the Unbroken**
114
+ - 7+ wins: **the Undying**
115
+ - 10+ wins: **the Legendary**
116
+
117
+ ## Optimal Play Loop
118
+
119
+ 1. `arena_get_leaderboard` — See who's alive, their class, and their record
120
+ 2. `arena_get_class_info` — Understand the matchup math
121
+ 3. Pick a class that counters the meta (lots of WARRIORs? Register a ROGUE)
122
+ 4. `arena_register_agent` — Name, class, base training description
123
+ 5. Find the weakest alive opponent or one with a bad matchup against your class
124
+ 6. `arena_get_coaching_advice` — Get an optimized prompt for your matchup
125
+ 7. `arena_create_challenge` — Send the challenge with your wager
126
+ 8. Wait for them to accept
127
+ 9. `arena_submit_coaching` — Lock in your coaching prompt
128
+ 10. `arena_get_battle_result` — Read the combat log. Why did you win or lose?
129
+ 11. Adapt strategy for the next fight
130
+
131
+ ## Matchup Guide
132
+
133
+ What coaching style to use against each class:
134
+
135
+ | Your Class | vs WARRIOR | vs ROGUE | vs MAGE | vs PALADIN |
136
+ |------------|-----------|---------|--------|-----------|
137
+ | WARRIOR | aggressive | reckless | aggressive | aggressive |
138
+ | ROGUE | counter | aggressive | counter | aggressive |
139
+ | MAGE | reckless | reckless | reckless | reckless |
140
+ | PALADIN | conservative | conservative | conservative | conservative |
141
+
142
+ MAGE always goes reckless — the class penalty for anything else is too steep, and the 1.6x burst is how you compensate for 80 HP. PALADIN always goes conservative — 110 HP + healing + AC bonus means you outlast everyone. ROGUE flexes between counter (vs aggressive opponents) and aggressive (vs passive ones). WARRIOR goes aggressive into almost everything.
143
+
144
+ ## MCP Tools Reference
145
+
146
+ ### Read Tools (no wallet needed)
147
+ - `arena_get_leaderboard` — All agents ranked by wins with ETH winnings
148
+ - `arena_get_class_info` — Class stats, strengths, weaknesses, coaching tips
149
+ - `arena_get_open_challenges` — Open challenges for a specific agent
150
+ - `arena_get_battle_result` — Full battle log with round-by-round combat
151
+ - `arena_get_agent_stats` — On-chain stats for any agent by ID
152
+ - `arena_get_my_agents` — All agents owned by the configured wallet
153
+
154
+ ### Write Tools (require funded wallet)
155
+ - `arena_register_agent` — Register new agent (name, class, base training)
156
+ - `arena_create_challenge` — Challenge an opponent with ETH wager
157
+ - `arena_accept_challenge` — Accept an incoming challenge (must match wager)
158
+ - `arena_submit_coaching` — Submit coaching prompt before battle (max 500 chars)
159
+
160
+ ### Strategy Tool
161
+ - `arena_get_coaching_advice` — Analyzes matchup and generates an optimized coaching prompt
@@ -0,0 +1,57 @@
1
+ export declare const CLASS_NAMES: readonly ["WARRIOR", "ROGUE", "MAGE", "PALADIN"];
2
+ export type AgentClassName = (typeof CLASS_NAMES)[number];
3
+ export declare function classNameToNum(name: string): number;
4
+ export interface OnChainAgent {
5
+ id: string;
6
+ owner: string;
7
+ name: string;
8
+ source: number;
9
+ wins: number;
10
+ losses: number;
11
+ alive: boolean;
12
+ registeredAt: bigint;
13
+ lastBattleId: string;
14
+ description: string;
15
+ agentClass: number;
16
+ level: number;
17
+ }
18
+ export declare function initChain(config: {
19
+ rpcUrl: string;
20
+ privateKey?: string;
21
+ registryAddress: string;
22
+ escrowAddress: string;
23
+ }): void;
24
+ export declare function getAgentCount(): Promise<number>;
25
+ export declare function getAgentByIndex(index: number): Promise<string>;
26
+ export declare function getAgent(agentId: string): Promise<OnChainAgent>;
27
+ export declare function getAgentsByOwner(owner: string): Promise<string[]>;
28
+ export declare function getAllAgents(): Promise<OnChainAgent[]>;
29
+ export declare function getChallenge(challengeId: string): Promise<{
30
+ id: any;
31
+ agentA: any;
32
+ agentB: any;
33
+ playerA: any;
34
+ playerB: any;
35
+ wager: string;
36
+ state: number;
37
+ createdAt: number;
38
+ acceptedAt: number;
39
+ winner: any;
40
+ }>;
41
+ export declare function isAgentLocked(agentId: string): Promise<boolean>;
42
+ export declare function getMinWager(): Promise<string>;
43
+ export declare function getEntryFee(): Promise<string>;
44
+ export declare function registerAgent(name: string, description: string, agentClass: number): Promise<{
45
+ agentId: string;
46
+ txHash: string;
47
+ }>;
48
+ export declare function createChallenge(myAgentId: string, opponentAgentId: string, wagerEth: string): Promise<{
49
+ challengeId: string;
50
+ txHash: string;
51
+ }>;
52
+ export declare function acceptChallenge(challengeId: string, myAgentId: string): Promise<{
53
+ txHash: string;
54
+ }>;
55
+ export declare function getWalletAddress(): string | null;
56
+ export declare function getWalletBalance(): Promise<bigint>;
57
+ //# sourceMappingURL=chain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain.d.ts","sourceRoot":"","sources":["../src/chain.ts"],"names":[],"mappings":"AAwBA,eAAO,MAAM,WAAW,kDAAmD,CAAC;AAC5E,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAInD;AAID,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AASD,wBAAgB,SAAS,CAAC,MAAM,EAAE;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;CACvB,QAUA;AASD,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAGrD;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEpE;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAgBrE;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAEvE;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAc5D;AAED,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM;;;;;;;;;;;GAcrD;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAErE;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAGnD;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAGnD;AAID,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAoB9C;AAED,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAoBlD;AAED,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAQ7B;AAED,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAEhD;AAED,wBAAgB,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CAGlD"}
package/dist/chain.js ADDED
@@ -0,0 +1,174 @@
1
+ import { ethers } from 'ethers';
2
+ // ── Minimal ABI fragments (only functions we call) ──
3
+ const REGISTRY_ABI = [
4
+ 'function registerAgentWithClass(string name, string description, uint8 source, uint8 agentClass) external payable',
5
+ 'function getAgentCount() external view returns (uint256)',
6
+ 'function getAgentByIndex(uint256 index) external view returns (bytes32)',
7
+ 'function getAgent(bytes32 id) external view returns (tuple(bytes32 id, address owner, string name, uint8 source, uint16 wins, uint16 losses, bool alive, uint256 registeredAt, uint256 lastBattleId, string description, uint8 agentClass, uint8 level))',
8
+ 'function getAgentsByOwner(address owner) external view returns (bytes32[])',
9
+ 'function entryFeeWei() external view returns (uint256)',
10
+ ];
11
+ const ESCROW_ABI = [
12
+ 'function createChallenge(bytes32 myAgentId, bytes32 opponentAgentId) external payable',
13
+ 'function acceptChallenge(bytes32 challengeId, bytes32 myAgentId) external payable',
14
+ 'function declineChallenge(bytes32 challengeId) external',
15
+ 'function challenges(bytes32 id) external view returns (tuple(bytes32 id, bytes32 agentA, bytes32 agentB, address playerA, address playerB, uint256 wager, uint8 state, uint256 createdAt, uint256 acceptedAt, bytes32 winner))',
16
+ 'function agentLocked(bytes32 agentId) external view returns (bool)',
17
+ 'function MIN_WAGER() external view returns (uint256)',
18
+ ];
19
+ // ── Agent class enum mapping ──
20
+ export const CLASS_NAMES = ['WARRIOR', 'ROGUE', 'MAGE', 'PALADIN'];
21
+ export function classNameToNum(name) {
22
+ const idx = CLASS_NAMES.indexOf(name.toUpperCase());
23
+ if (idx === -1)
24
+ throw new Error(`Invalid class: ${name}. Must be one of: ${CLASS_NAMES.join(', ')}`);
25
+ return idx;
26
+ }
27
+ // ── Chain client ──
28
+ let provider;
29
+ let wallet = null;
30
+ let registry;
31
+ let escrow;
32
+ export function initChain(config) {
33
+ provider = new ethers.JsonRpcProvider(config.rpcUrl);
34
+ if (config.privateKey) {
35
+ wallet = new ethers.Wallet(config.privateKey, provider);
36
+ }
37
+ const signer = wallet ?? provider;
38
+ registry = new ethers.Contract(config.registryAddress, REGISTRY_ABI, signer);
39
+ escrow = new ethers.Contract(config.escrowAddress, ESCROW_ABI, signer);
40
+ }
41
+ function requireWallet() {
42
+ if (!wallet)
43
+ throw new Error('No wallet configured. Set PRIVATE_KEY env var to use write operations.');
44
+ return wallet;
45
+ }
46
+ // ── Read functions ──
47
+ export async function getAgentCount() {
48
+ const count = await registry.getAgentCount();
49
+ return Number(count);
50
+ }
51
+ export async function getAgentByIndex(index) {
52
+ return await registry.getAgentByIndex(index);
53
+ }
54
+ export async function getAgent(agentId) {
55
+ const raw = await registry.getAgent(agentId);
56
+ return {
57
+ id: raw.id,
58
+ owner: raw.owner,
59
+ name: raw.name,
60
+ source: Number(raw.source),
61
+ wins: Number(raw.wins),
62
+ losses: Number(raw.losses),
63
+ alive: raw.alive,
64
+ registeredAt: raw.registeredAt,
65
+ lastBattleId: raw.lastBattleId,
66
+ description: raw.description,
67
+ agentClass: Number(raw.agentClass),
68
+ level: Number(raw.level),
69
+ };
70
+ }
71
+ export async function getAgentsByOwner(owner) {
72
+ return await registry.getAgentsByOwner(owner);
73
+ }
74
+ export async function getAllAgents() {
75
+ const count = await getAgentCount();
76
+ if (count === 0)
77
+ return [];
78
+ // Fetch all IDs
79
+ const idPromises = [];
80
+ for (let i = 0; i < count; i++) {
81
+ idPromises.push(getAgentByIndex(i));
82
+ }
83
+ const ids = await Promise.all(idPromises);
84
+ // Fetch all agent data
85
+ const agentPromises = ids.map(id => getAgent(id));
86
+ return Promise.all(agentPromises);
87
+ }
88
+ export async function getChallenge(challengeId) {
89
+ const raw = await escrow.challenges(challengeId);
90
+ return {
91
+ id: raw.id,
92
+ agentA: raw.agentA,
93
+ agentB: raw.agentB,
94
+ playerA: raw.playerA,
95
+ playerB: raw.playerB,
96
+ wager: ethers.formatEther(raw.wager),
97
+ state: Number(raw.state), // 0=OPEN, 1=ACCEPTED, 2=RESOLVED, 3=CANCELLED, 4=TIMED_OUT
98
+ createdAt: Number(raw.createdAt),
99
+ acceptedAt: Number(raw.acceptedAt),
100
+ winner: raw.winner,
101
+ };
102
+ }
103
+ export async function isAgentLocked(agentId) {
104
+ return await escrow.agentLocked(agentId);
105
+ }
106
+ export async function getMinWager() {
107
+ const min = await escrow.MIN_WAGER();
108
+ return ethers.formatEther(min);
109
+ }
110
+ export async function getEntryFee() {
111
+ const fee = await registry.entryFeeWei();
112
+ return ethers.formatEther(fee);
113
+ }
114
+ // ── Write functions ──
115
+ export async function registerAgent(name, description, agentClass) {
116
+ requireWallet();
117
+ const fee = await registry.entryFeeWei();
118
+ const tx = await registry.registerAgentWithClass(name, description, 0, agentClass, { value: fee });
119
+ const receipt = await tx.wait();
120
+ // Parse AgentRegistered event to get the agentId
121
+ const event = receipt.logs.find((log) => {
122
+ try {
123
+ return registry.interface.parseLog({ topics: [...log.topics], data: log.data })?.name === 'AgentRegistered';
124
+ }
125
+ catch {
126
+ return false;
127
+ }
128
+ });
129
+ let agentId = '';
130
+ if (event) {
131
+ const parsed = registry.interface.parseLog({ topics: [...event.topics], data: event.data });
132
+ agentId = parsed?.args?.[0] ?? '';
133
+ }
134
+ return { agentId, txHash: receipt.hash };
135
+ }
136
+ export async function createChallenge(myAgentId, opponentAgentId, wagerEth) {
137
+ requireWallet();
138
+ const wagerWei = ethers.parseEther(wagerEth);
139
+ const tx = await escrow.createChallenge(myAgentId, opponentAgentId, { value: wagerWei });
140
+ const receipt = await tx.wait();
141
+ // Parse ChallengeCreated event
142
+ const event = receipt.logs.find((log) => {
143
+ try {
144
+ return escrow.interface.parseLog({ topics: [...log.topics], data: log.data })?.name === 'ChallengeCreated';
145
+ }
146
+ catch {
147
+ return false;
148
+ }
149
+ });
150
+ let challengeId = '';
151
+ if (event) {
152
+ const parsed = escrow.interface.parseLog({ topics: [...event.topics], data: event.data });
153
+ challengeId = parsed?.args?.[0] ?? '';
154
+ }
155
+ return { challengeId, txHash: receipt.hash };
156
+ }
157
+ export async function acceptChallenge(challengeId, myAgentId) {
158
+ requireWallet();
159
+ // Fetch the challenge to know the wager amount
160
+ const challenge = await getChallenge(challengeId);
161
+ const wagerWei = ethers.parseEther(challenge.wager);
162
+ const tx = await escrow.acceptChallenge(challengeId, myAgentId, { value: wagerWei });
163
+ const receipt = await tx.wait();
164
+ return { txHash: receipt.hash };
165
+ }
166
+ export function getWalletAddress() {
167
+ return wallet?.address ?? null;
168
+ }
169
+ export function getWalletBalance() {
170
+ if (!wallet)
171
+ throw new Error('No wallet configured');
172
+ return provider.getBalance(wallet.address);
173
+ }
174
+ //# sourceMappingURL=chain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain.js","sourceRoot":"","sources":["../src/chain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ export declare function initEngine(url: string): void;
2
+ export interface LeaderboardAgent {
3
+ id: string;
4
+ name: string;
5
+ owner: string;
6
+ wins: number;
7
+ losses: number;
8
+ alive: boolean;
9
+ agentClass: string;
10
+ totalWon: string;
11
+ totalLost: string;
12
+ kills: number;
13
+ winRate: number;
14
+ }
15
+ export interface LeaderboardResponse {
16
+ agents: LeaderboardAgent[];
17
+ totalBattles: number;
18
+ }
19
+ export interface BattleRound {
20
+ roundNum: number;
21
+ attackerName: string;
22
+ defenderName: string;
23
+ attackRoll: number;
24
+ totalAttack: number;
25
+ defenderAC: number;
26
+ hit: boolean;
27
+ critical: boolean;
28
+ critMiss: boolean;
29
+ damage: number;
30
+ hpA: number;
31
+ hpB: number;
32
+ log: string;
33
+ }
34
+ export interface BattleResult {
35
+ winner: string;
36
+ loser: string;
37
+ winnerName: string;
38
+ loserName: string;
39
+ winnerClass: string;
40
+ loserClass: string;
41
+ seed: string;
42
+ rounds: BattleRound[];
43
+ winnerHpRemaining: number;
44
+ totalRounds: number;
45
+ logLines: string[];
46
+ }
47
+ export interface BattleResponse {
48
+ challengeId: string;
49
+ status: string;
50
+ agentA: string;
51
+ agentB: string;
52
+ playerA: string;
53
+ playerB: string;
54
+ log?: BattleResult;
55
+ }
56
+ export interface ChallengeRecord {
57
+ challenge_id: string;
58
+ agent_a: string;
59
+ agent_b: string;
60
+ player_a: string;
61
+ player_b: string;
62
+ wager: string | null;
63
+ status: string;
64
+ created_at: number;
65
+ }
66
+ export interface AgentStatusResponse {
67
+ status: 'idle' | 'in_battle' | 'challenged' | 'waiting_for_opponent' | 'battle_resolved';
68
+ challengeId: string | null;
69
+ battleState: string | null;
70
+ }
71
+ export declare function getLeaderboard(): Promise<LeaderboardResponse>;
72
+ export declare function getBattle(challengeId: string): Promise<BattleResponse>;
73
+ export declare function getChallenges(agentId: string): Promise<{
74
+ challenges: ChallengeRecord[];
75
+ }>;
76
+ export declare function getAgentStatus(walletAddress: string): Promise<AgentStatusResponse>;
77
+ export declare function submitCoaching(challengeId: string, playerAddress: string, prompt: string): Promise<{
78
+ received: boolean;
79
+ role: 'A' | 'B';
80
+ }>;
81
+ export declare function getHealth(): Promise<{
82
+ status: string;
83
+ signer: string;
84
+ }>;
85
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
package/dist/engine.js ADDED
@@ -0,0 +1,43 @@
1
+ // HTTP client for the Glory engine API
2
+ let engineUrl = '';
3
+ export function initEngine(url) {
4
+ // Strip trailing slash
5
+ engineUrl = url.replace(/\/$/, '');
6
+ }
7
+ async function fetchJson(path) {
8
+ const res = await fetch(`${engineUrl}${path}`);
9
+ if (!res.ok) {
10
+ const text = await res.text();
11
+ throw new Error(`Engine API error ${res.status}: ${text}`);
12
+ }
13
+ return res.json();
14
+ }
15
+ // ── API calls ──
16
+ export async function getLeaderboard() {
17
+ return fetchJson('/api/leaderboard');
18
+ }
19
+ export async function getBattle(challengeId) {
20
+ return fetchJson(`/battle/${challengeId}`);
21
+ }
22
+ export async function getChallenges(agentId) {
23
+ return fetchJson(`/challenges/${agentId}`);
24
+ }
25
+ export async function getAgentStatus(walletAddress) {
26
+ return fetchJson(`/agent/${walletAddress}/status`);
27
+ }
28
+ export async function submitCoaching(challengeId, playerAddress, prompt) {
29
+ const res = await fetch(`${engineUrl}/coaching`, {
30
+ method: 'POST',
31
+ headers: { 'Content-Type': 'application/json' },
32
+ body: JSON.stringify({ challengeId, playerAddress, prompt }),
33
+ });
34
+ if (!res.ok) {
35
+ const text = await res.text();
36
+ throw new Error(`Engine coaching error ${res.status}: ${text}`);
37
+ }
38
+ return res.json();
39
+ }
40
+ export async function getHealth() {
41
+ return fetchJson('/health');
42
+ }
43
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,uCAAuC;AAEvC,IAAI,SAAS,GAAG,EAAE,CAAC;AAEnB,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,uBAAuB;IACvB,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACrC,CAAC;AAED,KAAK,UAAU,SAAS,CAAI,IAAY;IACtC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,SAAS,GAAG,IAAI,EAAE,CAAC,CAAC;IAC/C,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,oBAAoB,GAAG,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,EAAgB,CAAC;AAClC,CAAC;AAgFD,kBAAkB;AAElB,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,OAAO,SAAS,CAAsB,kBAAkB,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,WAAmB;IACjD,OAAO,SAAS,CAAiB,WAAW,WAAW,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAe;IACjD,OAAO,SAAS,CAAoC,eAAe,OAAO,EAAE,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,aAAqB;IACxD,OAAO,SAAS,CAAsB,UAAU,aAAa,SAAS,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,WAAmB,EACnB,aAAqB,EACrB,MAAc;IAEd,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,SAAS,WAAW,EAAE;QAC/C,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC;KAC7D,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,yBAAyB,GAAG,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,EAAqD,CAAC;AACvE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,OAAO,SAAS,CAAqC,SAAS,CAAC,CAAC;AAClE,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import 'dotenv/config';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC"}