@xgamesfun/solana 0.24.0 → 0.25.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 (92) hide show
  1. package/README.md +94 -51
  2. package/bin/xsolana.mjs +23 -8
  3. package/examples/blind-forge.json +2 -4
  4. package/examples/coin-flip-arena.json +2 -5
  5. package/examples/duel-arena.json +1 -4
  6. package/examples/fair-presale.json +1 -3
  7. package/examples/hero-trials.json +14 -2
  8. package/examples/holder-den.json +38 -0
  9. package/examples/holders-drop.json +105 -0
  10. package/examples/ideas.json +788 -788
  11. package/examples/match-predictions.json +24 -0
  12. package/examples/nft-raffle.json +1 -0
  13. package/examples/pack-league.json +108 -0
  14. package/examples/partner-vault.json +19 -3
  15. package/examples/sacrifice-raffle.json +2 -10
  16. package/examples/shelter-fair.json +1 -0
  17. package/examples/stakers-draw.json +3 -7
  18. package/examples/stride-sneakers.json +164 -0
  19. package/examples/trade-in-shop.json +2 -3
  20. package/js/approve/details.mjs +117 -48
  21. package/js/approve/ed25519.mjs +5 -1
  22. package/js/approve/live-check.mjs +83 -26
  23. package/js/approve/page.html +217 -78
  24. package/js/approve/page.js +43 -15
  25. package/js/approve/server.mjs +276 -74
  26. package/js/chain/base58.js +7 -1
  27. package/js/chain/borsh.js +15 -11
  28. package/js/chain/bytes.js +11 -8
  29. package/js/chain/core.js +21 -5
  30. package/js/chain/curve.js +1 -1
  31. package/js/chain/lookup.js +118 -36
  32. package/js/chain/mint.js +6 -2
  33. package/js/chain/pda.js +2 -2
  34. package/js/chain/programs.js +6 -6
  35. package/js/chain/rpc.js +40 -14
  36. package/js/chain/token.js +13 -2
  37. package/js/chain/token2022.js +55 -16
  38. package/js/chain/tx.js +32 -22
  39. package/js/client/accounts.js +270 -80
  40. package/js/client/compressed.js +4 -3
  41. package/js/client/grant.js +165 -40
  42. package/js/client/idl/loot.js +1 -1
  43. package/js/client/idl/loot.json +104 -16
  44. package/js/client/ix.js +2121 -457
  45. package/js/client/pda.js +20 -18
  46. package/js/client/policy.js +12 -5
  47. package/js/client/random.js +1 -1
  48. package/js/client/sizes.js +220 -65
  49. package/js/client/traits.js +14 -5
  50. package/js/connect/connect.mjs +59 -17
  51. package/js/economy/check.mjs +3873 -690
  52. package/js/economy/cost.mjs +380 -56
  53. package/js/economy/examples.mjs +176 -35
  54. package/js/economy/explain.mjs +461 -110
  55. package/js/economy/guide.mjs +282 -59
  56. package/js/economy/legal.mjs +12 -6
  57. package/js/economy/live.mjs +60 -19
  58. package/js/economy/model.mjs +320 -97
  59. package/js/economy/plan.mjs +1022 -203
  60. package/js/economy/schema.json +127 -369
  61. package/js/economy/secrets.mjs +17 -7
  62. package/js/economy/simulate.mjs +771 -178
  63. package/js/economy/txsize.mjs +15 -3
  64. package/js/economy/validate.mjs +61 -24
  65. package/js/mcp/server.mjs +42 -14
  66. package/js/mcp/tools.mjs +293 -80
  67. package/js/play/index.js +1960 -461
  68. package/js/play/keys.js +35 -9
  69. package/js/results/index.js +223 -30
  70. package/js/results/server.js +230 -0
  71. package/js/results/wire.js +64 -16
  72. package/package.json +6 -4
  73. package/release.json +5 -5
  74. package/skills/xsolana-economy/SKILL.md +30 -16
  75. package/skills/xsolana-economy/references/after-launch.md +30 -20
  76. package/skills/xsolana-economy/references/apps.md +47 -36
  77. package/skills/xsolana-economy/references/sentence-to-spec.md +148 -129
  78. package/skills/xsolana-economy/references/telling-the-person.md +9 -6
  79. package/types/chain/core.d.ts +1 -1
  80. package/types/chain/lookup.d.ts +1 -1
  81. package/types/client/accounts.d.ts +24 -3
  82. package/types/client/grant.d.ts +2 -2
  83. package/types/client/idl/loot.d.ts +22 -0
  84. package/types/client/ix.d.ts +54 -45
  85. package/types/client/pda.d.ts +3 -1
  86. package/types/economy/guide.d.mts +5 -0
  87. package/types/economy/model.d.mts +48 -3
  88. package/types/economy/plan.d.mts +44 -2
  89. package/types/play/index.d.ts +8 -19
  90. package/types/results/index.d.ts +7 -6
  91. package/types/results/server.d.ts +126 -0
  92. package/types/results/wire.d.ts +1 -1
@@ -25,11 +25,24 @@ export const AGENTS = {
25
25
  name: 'Claude Code',
26
26
  bin: 'claude',
27
27
  scopes: ['user', 'project'],
28
- add: (command, args, scope) => ['mcp', 'add', '--transport', 'stdio', '--scope', scope, NAME, '--', command, ...args],
29
- remove: (scope) => ['mcp', 'remove', '--scope', scope, NAME],
28
+ add: (command, args, scope) => [
29
+ 'mcp',
30
+ 'add',
31
+ '--transport',
32
+ 'stdio',
33
+ '--scope',
34
+ scope,
35
+ NAME,
36
+ '--',
37
+ command,
38
+ ...args,
39
+ ],
40
+ remove: scope => ['mcp', 'remove', '--scope', scope, NAME],
30
41
  get: ['mcp', 'get', NAME],
31
- skills: (scope, cwd) => (scope === 'project' ? path.join(cwd, '.claude', 'skills') : path.join(os.homedir(), '.claude', 'skills')),
32
- plugin: 'Or install the plugin: /plugin marketplace add XGamesFun/solana-kit, then /plugin install xsolana@xgamesfun.',
42
+ skills: (scope, cwd) =>
43
+ scope === 'project' ? path.join(cwd, '.claude', 'skills') : path.join(os.homedir(), '.claude', 'skills'),
44
+ plugin:
45
+ 'Or install the plugin: /plugin marketplace add XGamesFun/solana-kit, then /plugin install xsolana@xgamesfun.',
33
46
  next: 'Start a new Claude Code session (or /mcp) to load the xsolana tools.',
34
47
  },
35
48
  codex: {
@@ -39,23 +52,30 @@ export const AGENTS = {
39
52
  add: (command, args) => ['mcp', 'add', NAME, '--', command, ...args],
40
53
  remove: () => ['mcp', 'remove', NAME],
41
54
  get: ['mcp', 'get', NAME],
42
- skills: (scope, cwd) => (scope === 'project' ? path.join(cwd, '.agents', 'skills') : path.join(os.homedir(), '.agents', 'skills')),
43
- plugin: 'Or install the plugin: codex plugin marketplace add XGamesFun/solana-kit, then codex plugin add xsolana@xgamesfun.',
55
+ skills: (scope, cwd) =>
56
+ scope === 'project' ? path.join(cwd, '.agents', 'skills') : path.join(os.homedir(), '.agents', 'skills'),
57
+ plugin:
58
+ 'Or install the plugin: codex plugin marketplace add XGamesFun/solana-kit, then codex plugin add xsolana@xgamesfun.',
44
59
  next: 'Start a new Codex session so it picks up the xsolana tools.',
45
60
  },
46
61
  };
47
62
 
48
63
  /** One word for cmd.exe: as it is when it is plain, else in double quotes (a quote inside doubled). */
49
- const winWord = (a) => (/^[\w@+=:,./\\-]+$/.test(a) ? a : `"${String(a).replace(/"/g, '""')}"`);
64
+ const winWord = a => (/^[\w@+=:,./\\-]+$/.test(a) ? a : `"${String(a).replace(/"/g, '""')}"`);
50
65
 
51
66
  /**
52
67
  * Runs an agent's command and answers { code, out }. On Windows the agents are installed as .cmd shims, which only a
53
68
  * shell can start: there the command goes to cmd.exe as one line, each word quoted as it needs.
54
69
  */
55
70
  export function runAgent(bin, args, { platform = process.platform, execFileImpl = execFile, execImpl = exec } = {}) {
56
- return new Promise((resolve) => {
57
- const done = (error, stdout, stderr) => resolve({ code: error ? (typeof error.code === 'number' ? error.code : 1) : 0, out: `${stdout ?? ''}${stderr ?? ''}`.trim() });
58
- if (platform === 'win32') execImpl([bin, ...args].map(winWord).join(' '), { timeout: 60_000, windowsHide: true }, done);
71
+ return new Promise(resolve => {
72
+ const done = (error, stdout, stderr) =>
73
+ resolve({
74
+ code: error ? (typeof error.code === 'number' ? error.code : 1) : 0,
75
+ out: `${stdout ?? ''}${stderr ?? ''}`.trim(),
76
+ });
77
+ if (platform === 'win32')
78
+ execImpl([bin, ...args].map(winWord).join(' '), { timeout: 60_000, windowsHide: true }, done);
59
79
  else execFileImpl(bin, args, { timeout: 60_000 }, done);
60
80
  });
61
81
  }
@@ -91,7 +111,16 @@ export async function skillFolder(dir) {
91
111
  }
92
112
 
93
113
  /** Connects (or with `remove`, disconnects) each agent found. Returns an exit code. */
94
- export async function connect({ agent, local = false, remove = false, dryRun = false, scope = 'user', cwd = process.cwd(), log = (...a) => console.log(...a), run = runAgent } = {}) {
114
+ export async function connect({
115
+ agent,
116
+ local = false,
117
+ remove = false,
118
+ dryRun = false,
119
+ scope = 'user',
120
+ cwd = process.cwd(),
121
+ log = (...a) => console.log(...a),
122
+ run = runAgent,
123
+ } = {}) {
95
124
  if (!SCOPES.includes(scope)) {
96
125
  log(`No scope called “${scope}” (${SCOPES.join(', ')}).`);
97
126
  return 1;
@@ -113,7 +142,9 @@ export async function connect({ agent, local = false, remove = false, dryRun = f
113
142
  }
114
143
  found++;
115
144
  if (!a.scopes.includes(scope)) {
116
- log(`${a.name}: adds MCP servers only for the whole user (--scope ${a.scopes.join(' or ')}), so it was left as it is. Run \`xsolana connect --agent ${id}\` for that.`);
145
+ log(
146
+ `${a.name}: adds MCP servers only for the whole user (--scope ${a.scopes.join(' or ')}), so it was left as it is. Run \`xsolana connect --agent ${id}\` for that.`,
147
+ );
117
148
  if (agent) failed++;
118
149
  continue;
119
150
  }
@@ -146,7 +177,9 @@ export async function connect({ agent, local = false, remove = false, dryRun = f
146
177
  const there = await skillFolder(skillDir);
147
178
  let skillSaid;
148
179
  if (there === 'other') {
149
- log(`${a.name}: ${skillDir} is there already and is not xsolana's ${SKILL} skill, so it was left as it is${remove ? '' : ' and the skill was not copied'}. Move it away, then run \`xsolana connect\` again.`);
180
+ log(
181
+ `${a.name}: ${skillDir} is there already and is not xsolana's ${SKILL} skill, so it was left as it is${remove ? '' : ' and the skill was not copied'}. Move it away, then run \`xsolana connect\` again.`,
182
+ );
150
183
  failed++;
151
184
  ok = false;
152
185
  } else if (remove) {
@@ -154,7 +187,8 @@ export async function connect({ agent, local = false, remove = false, dryRun = f
154
187
  else if (there === 'ours') await rm(skillDir, { recursive: true, force: true });
155
188
  skillSaid = there === 'ours' ? `; the ${SKILL} skill removed from ${skillDir}` : '';
156
189
  } else {
157
- if (dryRun) log(`${there === 'ours' ? 'replace the xsolana skill at' : 'copy skills/xsolana-economy to'} ${skillDir}`);
190
+ if (dryRun)
191
+ log(`${there === 'ours' ? 'replace the xsolana skill at' : 'copy skills/xsolana-economy to'} ${skillDir}`);
158
192
  else {
159
193
  await mkdir(skills, { recursive: true });
160
194
  if (there === 'ours') await rm(skillDir, { recursive: true, force: true });
@@ -167,15 +201,23 @@ export async function connect({ agent, local = false, remove = false, dryRun = f
167
201
  // Registered, but not at this scope: it is still there, and the person asked for it gone.
168
202
  const stays = had.code === 0 && !removed;
169
203
  if (stays) failed++;
170
- const server = removed ? 'xsolana removed' : stays ? `xsolana’s server was not found at the ${scope} scope, so it was left where it is (\`${a.bin} mcp get ${NAME}\` shows where)` : 'xsolana’s server was not registered';
204
+ const server = removed
205
+ ? 'xsolana removed'
206
+ : stays
207
+ ? `xsolana’s server was not found at the ${scope} scope, so it was left where it is (\`${a.bin} mcp get ${NAME}\` shows where)`
208
+ : 'xsolana’s server was not registered';
171
209
  log(`${a.name}: ${server}${skillSaid ?? ''}.`);
172
210
  } else if (ok) {
173
- log(`${a.name}: xsolana tools added (${local ? 'from this checkout' : 'from npm'}, ${scope === 'project' ? `for ${cwd} only` : 'for every project'})${skillSaid}. ${a.next}`);
211
+ log(
212
+ `${a.name}: xsolana tools added (${local ? 'from this checkout' : 'from npm'}, ${scope === 'project' ? `for ${cwd} only` : 'for every project'})${skillSaid}. ${a.next}`,
213
+ );
174
214
  log(` ${a.plugin}`);
175
215
  }
176
216
  }
177
217
  if (!found) {
178
- log('No coding agent found (Claude Code: npm install -g @anthropic-ai/claude-code; Codex: npm install -g @openai/codex).');
218
+ log(
219
+ 'No coding agent found (Claude Code: npm install -g @anthropic-ai/claude-code; Codex: npm install -g @openai/codex).',
220
+ );
179
221
  return 1;
180
222
  }
181
223
  return failed ? 1 : 0;