@xgamesfun/solana 0.26.0 → 0.26.2

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 CHANGED
@@ -64,7 +64,7 @@ codex plugin add xsolana@xgamesfun
64
64
 
65
65
  **claude.ai, ChatGPT or Claude Desktop:** add `https://xgames.fun/mcp` as a custom connector. Nothing to install.
66
66
 
67
- **Cursor, Cline, opencode or any MCP client:** run `npx -y --package=@xgamesfun/solana@0.26.0 xsolana mcp`.
67
+ **Cursor, Cline, opencode or any MCP client:** run `npx -y --package=@xgamesfun/solana@0.26.2 xsolana mcp`.
68
68
 
69
69
  **Any agent that reads skills** (Copilot, Gemini CLI, Windsurf…): `npx skills add XGamesFun/solana-kit`.
70
70
 
@@ -75,19 +75,19 @@ are in [docs/harnesses.md](docs/harnesses.md).
75
75
 
76
76
  ```bash
77
77
  # find a worked example close to your idea
78
- npx -y @xgamesfun/solana@0.26.0 examples shop with loot boxes
78
+ npx -y @xgamesfun/solana@0.26.2 examples shop with loot boxes
79
79
 
80
80
  # does it work? where does the money go? what does it cost?
81
- npx -y @xgamesfun/solana@0.26.0 check xsolana.json
82
- npx -y @xgamesfun/solana@0.26.0 simulate xsolana.json
83
- npx -y @xgamesfun/solana@0.26.0 cost xsolana.json
81
+ npx -y @xgamesfun/solana@0.26.2 check xsolana.json
82
+ npx -y @xgamesfun/solana@0.26.2 simulate xsolana.json
83
+ npx -y @xgamesfun/solana@0.26.2 cost xsolana.json
84
84
 
85
85
  # the whole economy in plain words, and what a cheater could get
86
- npx -y @xgamesfun/solana@0.26.0 explain xsolana.json
87
- npx -y @xgamesfun/solana@0.26.0 review xsolana.json
86
+ npx -y @xgamesfun/solana@0.26.2 explain xsolana.json
87
+ npx -y @xgamesfun/solana@0.26.2 review xsolana.json
88
88
 
89
89
  # go live, approved in your own wallet
90
- npx -y @xgamesfun/solana@0.26.0 approve xsolana.json
90
+ npx -y @xgamesfun/solana@0.26.2 approve xsolana.json
91
91
  ```
92
92
 
93
93
  Each command names an exact version, so you always run the release you meant to. `xsolana help` lists them all.
@@ -0,0 +1,76 @@
1
+ // A token's name on chain: its Token Metadata record (Metaplex), where wallets and explorers read a classic SPL
2
+ // token's name, ticker and picture link. Only what a setup needs: the record of a fungible token whose mint is made
3
+ // already. Token Metadata takes it only from the mint's authority, so it is made while that authority can still sign:
4
+ // once minting is handed on or turned off, no record can ever be made for the mint.
5
+ import { addressBytes, encodeBase58 } from './base58.js';
6
+ import { concat, uintLE, utf8 } from './bytes.js';
7
+ import { METAPLEX_METADATA_PROGRAM, pdaOf, SYSTEM_PROGRAM, SYSVAR_INSTRUCTIONS, TOKEN_PROGRAM } from './pda.js';
8
+ import { meta } from './programs.js';
9
+
10
+ /** A record's size: Token Metadata pads every one to it, whatever its name, ticker and link. */
11
+ export const METADATA_BYTES = 607;
12
+ /** What Token Metadata keeps in each record it makes, on top of the record's rent: its own fee. */
13
+ export const METADATA_FEE = 10_000_000n;
14
+ /** The longest name, ticker and link a record takes, in UTF-8 bytes. */
15
+ export const METADATA_LIMITS = Object.freeze({ name: 32, symbol: 10, uri: 200 });
16
+
17
+ const CREATE = 42;
18
+ const CREATE_V1 = 0;
19
+ const FUNGIBLE = 2;
20
+ const NONE = Uint8Array.of(0);
21
+ const text = s => concat(uintLE(utf8(s).length, 4), utf8(s));
22
+
23
+ /** The address of a mint's Token Metadata record. */
24
+ export const metadataAddress = mint =>
25
+ pdaOf([utf8('metadata'), addressBytes(METAPLEX_METADATA_PROGRAM), addressBytes(mint)], METAPLEX_METADATA_PROGRAM);
26
+
27
+ /**
28
+ * Token Metadata's CreateV1 for a fungible token whose mint exists: its name, its ticker and a link to a JSON file with
29
+ * its picture ('' for none). `authority` is the mint's authority and signs; it becomes the record's update authority,
30
+ * the only one who can change the record later. `payer` pays its rent and Token Metadata's fee (`METADATA_FEE`).
31
+ * The mint is listed read-only: this path of Token Metadata writes nothing to a mint that exists. That is the
32
+ * program's behaviour, not a lock: in a setup's own transaction the mint is writable all the same (the same
33
+ * transaction makes it), so the tests read its supply and authorities back after the record is made. The record says
34
+ * a fungible token whatever the decimals (CreateMetadataAccountV3 would call one of 0 decimals an asset, which
35
+ * wallets list with collectibles).
36
+ */
37
+ export function createFungibleMetadataIx({ mint, authority, payer = authority, name, symbol, uri = '' }) {
38
+ for (const [field, value] of Object.entries({ name, symbol, uri })) {
39
+ if (typeof value !== 'string') throw new TypeError(`A token's ${field} is text`);
40
+ if (utf8(value).length > METADATA_LIMITS[field])
41
+ throw new RangeError(`A token's ${field} is at most ${METADATA_LIMITS[field]} bytes`);
42
+ }
43
+ return {
44
+ programId: METAPLEX_METADATA_PROGRAM,
45
+ keys: [
46
+ meta(metadataAddress(mint), false, true),
47
+ meta(METAPLEX_METADATA_PROGRAM, false, false), // no edition: a fungible token has none
48
+ meta(mint, false, false),
49
+ meta(authority, true, false),
50
+ meta(payer, true, true),
51
+ meta(authority, true, false), // the update authority
52
+ meta(SYSTEM_PROGRAM, false, false),
53
+ meta(SYSVAR_INSTRUCTIONS, false, false),
54
+ meta(TOKEN_PROGRAM, false, false),
55
+ ],
56
+ data: concat(
57
+ Uint8Array.of(CREATE, CREATE_V1),
58
+ text(name),
59
+ text(symbol),
60
+ text(uri),
61
+ uintLE(0, 2), // no resale royalty
62
+ NONE, // no creators
63
+ Uint8Array.of(0, 1), // no primary sale yet; the record can be changed
64
+ Uint8Array.of(FUNGIBLE),
65
+ NONE, // no collection
66
+ NONE, // no uses
67
+ NONE, // no collection details
68
+ NONE, // no rule set
69
+ NONE, // decimals: the mint's own
70
+ NONE, // no print supply
71
+ ),
72
+ };
73
+ }
74
+
75
+ /** The update authority a Token Metadata record names (who can change its name, ticker and link). */
76
+ export const metadataUpdateAuthority = data => (data?.length >= 33 ? encodeBase58(data.subarray(1, 33)) : null);