@xgamesfun/solana 0.28.1 → 0.28.3
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/DISCLAIMER.md +3 -1
- package/README.md +18 -16
- package/bin/xsolana.mjs +27 -1
- package/js/approve/details.mjs +3 -3
- package/js/approve/live-check.mjs +2 -2
- package/js/approve/page.html +5 -5
- package/js/approve/page.js +16 -4
- package/js/approve/server.mjs +31 -26
- package/js/approve/with-key.mjs +7 -4
- package/js/chain/borsh.js +5 -3
- package/js/chain/rpc.js +26 -10
- package/js/client/accounts.js +6 -6
- package/js/client/cluster.js +136 -0
- package/js/client/grant.js +2 -2
- package/js/client/ix.js +16 -16
- package/js/client/pda.js +18 -5
- package/js/economy/check.mjs +28 -13
- package/js/economy/explain.mjs +2 -1
- package/js/economy/guide.mjs +6 -4
- package/js/economy/live.mjs +2 -2
- package/js/economy/plan.mjs +1 -1
- package/js/economy/schema.json +2 -2
- package/js/mcp/server.mjs +35 -4
- package/js/mcp/tools.mjs +56 -45
- package/js/mcp/with-cluster.mjs +25 -0
- package/js/play/index.js +48 -38
- package/js/play/sponsor.js +4 -4
- package/js/results/index.js +36 -14
- package/js/results/server.js +4 -3
- package/js/results/wire.js +9 -8
- package/package.json +6 -1
- package/release.json +6 -1
- package/skills/xsolana-economy/SKILL.md +13 -9
- package/skills/xsolana-economy/references/apps.md +2 -1
- package/skills/xsolana-economy/references/telling-the-person.md +1 -1
- package/skills/xsolana-economy/references/trust-and-cheating.md +1 -1
- package/types/chain/borsh.d.ts +4 -2
- package/types/chain/rpc.d.ts +10 -4
- package/types/client/cluster.d.ts +61 -0
- package/types/client/idl/loot.d.ts +9 -9
- package/types/client/pda.d.ts +1 -1
- package/types/economy/check.d.mts +1 -2
- package/types/economy/plan.d.mts +14 -14
- package/types/mcp/server.d.mts +1 -1
- package/types/mcp/tools.d.mts +9 -7
- package/types/mcp/with-cluster.d.mts +8 -0
- package/types/play/index.d.ts +2 -2
- package/types/results/index.d.ts +14 -7
- package/types/results/server.d.ts +3 -3
- package/types/results/wire.d.ts +8 -8
|
@@ -8,11 +8,12 @@ description: Build a web3, token or NFT economy on Solana without writing a smar
|
|
|
8
8
|
An economy is one JSON spec (`xsolana.json` in the project) on **loot**, a Solana program every project shares. Nobody
|
|
9
9
|
writes or deploys a contract: the spec is checked, simulated and priced by the `xsolana_*` tools, and it goes live
|
|
10
10
|
signed by a key file on the owner's own machine, once they have read what will be sent and said yes. It runs on
|
|
11
|
-
**devnet**
|
|
11
|
+
**devnet**, where nothing is real money, and on **mainnet**, where everything is: an economy is on devnet unless its
|
|
12
|
+
file says `"network": "mainnet"`.
|
|
12
13
|
|
|
13
|
-
The tools are the `xsolana_*` MCP tools. Without MCP, the same from a terminal: `npx -y @xgamesfun/solana@0.28.
|
|
14
|
-
`npx -y @xgamesfun/solana@0.28.
|
|
15
|
-
or `npx -y @xgamesfun/solana@0.28.
|
|
14
|
+
The tools are the `xsolana_*` MCP tools. Without MCP, the same from a terminal: `npx -y @xgamesfun/solana@0.28.3 <guide|examples|check|simulate|cost|explain|review|publish|status> [xsolana.json]`,
|
|
15
|
+
`npx -y @xgamesfun/solana@0.28.3 token <mint>` for a coin made elsewhere,
|
|
16
|
+
or `npx -y @xgamesfun/solana@0.28.3 tool <name> '<json>'` for any tool (always with the exact version).
|
|
16
17
|
|
|
17
18
|
## Rules (always)
|
|
18
19
|
|
|
@@ -33,7 +34,10 @@ or `npx -y @xgamesfun/solana@0.28.1 tool <name> '<json>'` for any tool (always w
|
|
|
33
34
|
owner: whoever can read it controls the project. Never open it, copy it or print it, and never put it in a chat, a
|
|
34
35
|
spec, a repository or a page. Never ask for a seed phrase or the key of a wallet the person already has; if they
|
|
35
36
|
paste one, tell them to treat it as exposed and move its funds, and write it nowhere.
|
|
36
|
-
3. **Devnet only.**
|
|
37
|
+
3. **Devnet first; mainnet only on the person's own word.** Build, check and try every economy on devnet, and say
|
|
38
|
+
that nothing there is real money. Write `"network": "mainnet"` only when the person asks for mainnet in their own
|
|
39
|
+
words, never to make something feel real. Tell them then, before anything is sent: it is real money, loot has not
|
|
40
|
+
been independently audited, what is sent can be lost, and what the review and the checker's legal warnings say.
|
|
37
41
|
4. **The checker decides.** Never save or publish a spec with refusals. Fix each refusal the way its `fix` says.
|
|
38
42
|
5. **Numbers come from the tools.** What a box gives back, how long a pool lasts, what going live costs: quote
|
|
39
43
|
`xsolana_simulate`, `xsolana_cost` and `xsolana_explain`, never your own arithmetic. What a player pays is the tools'
|
|
@@ -137,7 +141,7 @@ or `npx -y @xgamesfun/solana@0.28.1 tool <name> '<json>'` for any tool (always w
|
|
|
137
141
|
9. **When they say "put it live"**: `xsolana_publish` lists every step and its cost and gives the commands, which you
|
|
138
142
|
run in the project folder exactly as given (they name the exact version; never drop it):
|
|
139
143
|
- **A new economy gets a key file**, unless the project has one:
|
|
140
|
-
`npx -y @xgamesfun/solana@0.28.
|
|
144
|
+
`npx -y @xgamesfun/solana@0.28.3 keygen ~/.config/xsolana/<name>.json`. Give the person the address it prints. A
|
|
141
145
|
Solana key file they already have and name themselves (`~/.config/solana/id.json`) works the same; never go
|
|
142
146
|
looking for one.
|
|
143
147
|
- **Say what the key file is** before anything is sent: the project's owner, and, unless the spec says otherwise,
|
|
@@ -148,11 +152,11 @@ or `npx -y @xgamesfun/solana@0.28.1 tool <name> '<json>'` for any tool (always w
|
|
|
148
152
|
set `"treasury": "wallet:<address>"` first: it can't be changed through the spec once live. Tell them to back
|
|
149
153
|
the file up themselves (a USB stick, a password manager): if it is lost, nobody can change the economy, decide
|
|
150
154
|
a contest or move what its address holds, and nothing restores it. You never open or copy it.
|
|
151
|
-
- **Everything the setup takes from the owner must be at the key's address first**: the
|
|
152
|
-
|
|
155
|
+
- **Everything the setup takes from the owner must be at the key's address first**: the SOL (`xsolana_cost`;
|
|
156
|
+
devnet SOL for an economy on devnet, real SOL for one on mainnet), any seed in a coin that already exists, and every NFT a stash, a raffle or an auction names. A
|
|
153
157
|
collection they already have needs the key's address as its update authority. If they would rather not move
|
|
154
158
|
those, offer the browser wallet.
|
|
155
|
-
- **Show it**: `npx -y @xgamesfun/solana@0.28.
|
|
159
|
+
- **Show it**: `npx -y @xgamesfun/solana@0.28.3 approve xsolana.json --keypair <key file>` prints every step with
|
|
156
160
|
what it pays and trusts, the warnings, the notice and a code, and sends nothing. Give the person that printout as
|
|
157
161
|
it is, not a summary of it, and ask.
|
|
158
162
|
- **On their yes**, the same command with `--yes <code>`. What lands is written back into `xsolana.json`. If it
|
|
@@ -76,7 +76,8 @@ await app.balances(); // what they hold of each of the economy's tokens
|
|
|
76
76
|
}
|
|
77
77
|
</script>
|
|
78
78
|
```
|
|
79
|
-
Tell the person the one command that starts it, and
|
|
79
|
+
Tell the person the one command that starts it, and which cluster its economy is on (devnet unless its file says
|
|
80
|
+
mainnet).
|
|
80
81
|
- **What a roll looks like**: a box of several outcomes is rolled by the oracle a few seconds after the open; `openBox`
|
|
81
82
|
waits for it. Show the player that it is rolling.
|
|
82
83
|
- **A page that closes before the settle**: the SOL its settle key holds is not lost in the same browser (on another device, with nothing stored, it can't be found yet). Build the wallet with
|
|
@@ -29,7 +29,7 @@ and the spec differ (a limit, an amount, a key not set yet), change one of them
|
|
|
29
29
|
a score): "Checking that a player really did it is up to you, on your own server: a game runs in the player's
|
|
30
30
|
browser, and the program trusts the authority's signature."
|
|
31
31
|
6. **Flags for the law, once.** `W-CHANCE-PRIZE`: "Players pay for a chance at money. That is gambling in many places once
|
|
32
|
-
it is real money; this
|
|
32
|
+
it is real money; this one is on devnet, which is not." (On mainnet: "this one is on mainnet, so it is.") `W-CHANCE-ITEMS`: "Players pay for random items they can resell: some
|
|
33
33
|
places treat that as gambling, and many require the odds to be shown." `W-REVENUE-SHARE`: "Stakers are paid from
|
|
34
34
|
what players spend; regulators look at that when they decide whether a token is a security." `W-TOKEN-SALE`:
|
|
35
35
|
"People pay for a share of a new token; selling a token to raise money is what securities law looks at first."
|
|
@@ -104,7 +104,7 @@ Run `xsolana_review` and go through what it reports; these are the points behind
|
|
|
104
104
|
11. **The authority and the treasury.** The owner's wallet alone changes every price, rate, grant, limit and voucher
|
|
105
105
|
key; the authority mints, moves pool funds, decides contests and releases holds, with no caps. On devnet the
|
|
106
106
|
owner's key is the key file the setup was signed with: readable by its user alone, outside any repository, never
|
|
107
|
-
pasted anywhere. With real money (
|
|
107
|
+
pasted anywhere. With real money (an economy on mainnet) those keys belong in a hardware wallet or a multisig; a
|
|
108
108
|
server that signs gets an authority key of its own, never the owner's.
|
|
109
109
|
12. **The page is untrusted.** A page builds the player's transactions, and a cheater builds their own: the program's
|
|
110
110
|
checks are what count, never the page's. Anything the page decides (a score, a reward amount, who won) is only as
|
package/types/chain/borsh.d.ts
CHANGED
|
@@ -15,9 +15,11 @@ export declare function isAccount(idl: any, name: any, data: any): boolean;
|
|
|
15
15
|
* [{ name, data }]. Only lines the program itself printed count: the log names which program each line comes from
|
|
16
16
|
* (`Program <id> invoke [n]` … `success`), and any program can print a line that looks like an event. Logs alone
|
|
17
17
|
* cannot say whether the transaction succeeded (the runtime can fail it after every instruction logged success), so
|
|
18
|
-
* the caller decides that from the transaction's `meta.err` and reads events only when it is null.
|
|
18
|
+
* the caller decides that from the transaction's `meta.err` and reads events only when it is null. `program` is the
|
|
19
|
+
* address the program runs at: the IDL's own unless the caller names another (the program has an address of its own on
|
|
20
|
+
* each cluster, and an IDL holds one).
|
|
19
21
|
*/
|
|
20
|
-
export declare function decodeEvents(idl: any, logs: any): {
|
|
22
|
+
export declare function decodeEvents(idl: any, logs: any, program?: any): {
|
|
21
23
|
name: any;
|
|
22
24
|
data: any;
|
|
23
25
|
}[];
|
package/types/chain/rpc.d.ts
CHANGED
|
@@ -19,13 +19,19 @@ export declare const GENESIS: Readonly<{
|
|
|
19
19
|
mainnet: "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d";
|
|
20
20
|
testnet: "4uhcVJyU9pJkvQyS88uRDiswHXSCkY3zQawwpjk2NsNY";
|
|
21
21
|
}>;
|
|
22
|
+
/**
|
|
23
|
+
* Refuses an RPC URL that names another cluster than the one the caller works on (`devnet` or `mainnet`). Returns the
|
|
24
|
+
* URL. A URL names nothing for certain: `checkCluster` reads the chain itself.
|
|
25
|
+
*/
|
|
26
|
+
export declare function rightCluster(url: any, cluster?: string): any;
|
|
22
27
|
/** Refuses an RPC URL that names mainnet. Returns the URL. */
|
|
23
|
-
export declare
|
|
28
|
+
export declare const notMainnet: (url: any) => any;
|
|
24
29
|
/**
|
|
25
|
-
* Refuses a chain that is
|
|
26
|
-
* let through
|
|
30
|
+
* Refuses a chain that is not the cluster the caller works on, by its genesis block, whatever its URL says. On
|
|
31
|
+
* devnet, mainnet and testnet are refused and a local validator is let through; on mainnet, only mainnet itself
|
|
32
|
+
* passes. `rpc` has `call`. Returns the genesis hash.
|
|
27
33
|
*/
|
|
28
|
-
export declare function checkCluster(rpc: any): Promise<any>;
|
|
34
|
+
export declare function checkCluster(rpc: any, cluster?: string): Promise<any>;
|
|
29
35
|
/** The program's own words for a failed run (`AnchorError … Error Message: …`), else the last error log line. A program
|
|
30
36
|
* built without its errors' text logs the error's name as its message: then the name alone (the client's IDL has
|
|
31
37
|
* the sentence: `loot.lootError`). */
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Each cluster: loot's program there (devnet's is the IDL's own address), the chain as a wallet names it (Wallet
|
|
3
|
+
* Standard), and the RPC used when none is given. Mainnet has none: its public RPC refuses or limits what loot reads
|
|
4
|
+
* (a program's accounts, a compressed NFT's proof), so a mainnet RPC is always named (XSOLANA_RPC_URL, or `rpcUrl`).
|
|
5
|
+
*/
|
|
6
|
+
export declare const CLUSTERS: Readonly<{
|
|
7
|
+
devnet: Readonly<{
|
|
8
|
+
program: string;
|
|
9
|
+
chain: "solana:devnet";
|
|
10
|
+
rpc: "https://api.devnet.solana.com";
|
|
11
|
+
}>;
|
|
12
|
+
mainnet: Readonly<{
|
|
13
|
+
program: "xgames8C758PyweWB9sDw8evvwsTVwyA2fGRUeAXVPy";
|
|
14
|
+
chain: "solana:mainnet";
|
|
15
|
+
rpc: null;
|
|
16
|
+
}>;
|
|
17
|
+
}>;
|
|
18
|
+
/**
|
|
19
|
+
* loot's program on this process's own cluster. A live binding: it follows `useCluster`. It knows nothing of
|
|
20
|
+
* `withCluster`: code that may run for either cluster asks `lootProgram()`, as the client itself does.
|
|
21
|
+
* @type {string}
|
|
22
|
+
*/
|
|
23
|
+
export declare let LOOT_PROGRAM: string;
|
|
24
|
+
/**
|
|
25
|
+
* For a server's own set-up (js/mcp/with-cluster.mjs does it): `current()` answers the cluster of the work being done now,
|
|
26
|
+
* or nothing outside any. While it answers one, the client is on that cluster.
|
|
27
|
+
* @param {(() => string | undefined | null) | null} current
|
|
28
|
+
*/
|
|
29
|
+
export declare function scopeClusters(current: (() => string | undefined | null) | null): void;
|
|
30
|
+
/**
|
|
31
|
+
* Names the cluster this process works on (`devnet` or `mainnet`) and returns it. Call it first, before any address
|
|
32
|
+
* is derived: it throws when the process already works on another cluster. Inside `withCluster` it names nothing: it
|
|
33
|
+
* throws unless the cluster named is the one that work is on.
|
|
34
|
+
* @param {'devnet' | 'mainnet'} cluster
|
|
35
|
+
* @returns {'devnet' | 'mainnet'}
|
|
36
|
+
*/
|
|
37
|
+
export declare function useCluster(cluster: 'devnet' | 'mainnet'): 'devnet' | 'mainnet';
|
|
38
|
+
/**
|
|
39
|
+
* The cluster the client works on now: inside `withCluster` that work's, else the process's own (asking settles it).
|
|
40
|
+
* @returns {'devnet' | 'mainnet'}
|
|
41
|
+
*/
|
|
42
|
+
export declare function cluster(): 'devnet' | 'mainnet';
|
|
43
|
+
/**
|
|
44
|
+
* loot's program on the cluster the client works on now (`cluster()`): what derives an address, builds an
|
|
45
|
+
* instruction or reads who owns an account calls this.
|
|
46
|
+
* @returns {string}
|
|
47
|
+
*/
|
|
48
|
+
export declare function lootProgram(): string;
|
|
49
|
+
/** Whether the client works on mainnet now: what is paid and won there is real money. */
|
|
50
|
+
export declare const realMoney: () => boolean;
|
|
51
|
+
/** The cluster an economy is on: the `network` its file names, devnet when it names none. */
|
|
52
|
+
export declare const networkOf: (economy: any) => any;
|
|
53
|
+
/**
|
|
54
|
+
* The RPC URL this process reads and sends through: the one given, else XSOLANA_RPC_URL, else the cluster's own
|
|
55
|
+
* (devnet's public RPC; mainnet has none). A URL that names another cluster is refused.
|
|
56
|
+
*/
|
|
57
|
+
export declare function clusterRpcUrl(url?: any): any;
|
|
58
|
+
/** Refuses a chain that is not this process's cluster, by its genesis block (`rpc.js`, `checkCluster`). */
|
|
59
|
+
export declare const checkOnCluster: (rpc: any) => Promise<any>;
|
|
60
|
+
/** This process's cluster as a wallet names it (Wallet Standard): `solana:devnet` or `solana:mainnet`. */
|
|
61
|
+
export declare const walletChain: () => "solana:devnet" | "solana:mainnet";
|
|
@@ -3613,8 +3613,8 @@ declare const _default: {
|
|
|
3613
3613
|
};
|
|
3614
3614
|
}[];
|
|
3615
3615
|
} | {
|
|
3616
|
-
fields?: undefined;
|
|
3617
3616
|
name: string;
|
|
3617
|
+
fields?: undefined;
|
|
3618
3618
|
})[];
|
|
3619
3619
|
fields?: undefined;
|
|
3620
3620
|
};
|
|
@@ -3862,7 +3862,6 @@ declare const _default: {
|
|
|
3862
3862
|
name: string;
|
|
3863
3863
|
docs: string[];
|
|
3864
3864
|
type: {
|
|
3865
|
-
fields?: undefined;
|
|
3866
3865
|
kind: string;
|
|
3867
3866
|
variants: ({
|
|
3868
3867
|
name: string;
|
|
@@ -3888,6 +3887,7 @@ declare const _default: {
|
|
|
3888
3887
|
type: string;
|
|
3889
3888
|
})[];
|
|
3890
3889
|
})[];
|
|
3890
|
+
fields?: undefined;
|
|
3891
3891
|
};
|
|
3892
3892
|
} | {
|
|
3893
3893
|
name: string;
|
|
@@ -4041,11 +4041,11 @@ declare const _default: {
|
|
|
4041
4041
|
docs?: undefined;
|
|
4042
4042
|
name: string;
|
|
4043
4043
|
type: {
|
|
4044
|
-
fields?: undefined;
|
|
4045
4044
|
kind: string;
|
|
4046
4045
|
variants: {
|
|
4047
4046
|
name: string;
|
|
4048
4047
|
}[];
|
|
4048
|
+
fields?: undefined;
|
|
4049
4049
|
};
|
|
4050
4050
|
} | {
|
|
4051
4051
|
name: string;
|
|
@@ -4378,7 +4378,6 @@ declare const _default: {
|
|
|
4378
4378
|
name: string;
|
|
4379
4379
|
docs: string[];
|
|
4380
4380
|
type: {
|
|
4381
|
-
fields?: undefined;
|
|
4382
4381
|
kind: string;
|
|
4383
4382
|
variants: ({
|
|
4384
4383
|
name: string;
|
|
@@ -4397,9 +4396,10 @@ declare const _default: {
|
|
|
4397
4396
|
name: string;
|
|
4398
4397
|
fields: string[];
|
|
4399
4398
|
} | {
|
|
4400
|
-
fields?: undefined;
|
|
4401
4399
|
name: string;
|
|
4400
|
+
fields?: undefined;
|
|
4402
4401
|
})[];
|
|
4402
|
+
fields?: undefined;
|
|
4403
4403
|
};
|
|
4404
4404
|
} | {
|
|
4405
4405
|
name: string;
|
|
@@ -4485,11 +4485,10 @@ declare const _default: {
|
|
|
4485
4485
|
name: string;
|
|
4486
4486
|
docs: string[];
|
|
4487
4487
|
type: {
|
|
4488
|
-
fields?: undefined;
|
|
4489
4488
|
kind: string;
|
|
4490
4489
|
variants: ({
|
|
4491
|
-
fields?: undefined;
|
|
4492
4490
|
name: string;
|
|
4491
|
+
fields?: undefined;
|
|
4493
4492
|
} | {
|
|
4494
4493
|
name: string;
|
|
4495
4494
|
fields: string[];
|
|
@@ -4502,16 +4501,16 @@ declare const _default: {
|
|
|
4502
4501
|
};
|
|
4503
4502
|
}[];
|
|
4504
4503
|
})[];
|
|
4504
|
+
fields?: undefined;
|
|
4505
4505
|
};
|
|
4506
4506
|
} | {
|
|
4507
4507
|
name: string;
|
|
4508
4508
|
docs: string[];
|
|
4509
4509
|
type: {
|
|
4510
|
-
fields?: undefined;
|
|
4511
4510
|
kind: string;
|
|
4512
4511
|
variants: ({
|
|
4513
|
-
fields?: undefined;
|
|
4514
4512
|
name: string;
|
|
4513
|
+
fields?: undefined;
|
|
4515
4514
|
} | {
|
|
4516
4515
|
name: string;
|
|
4517
4516
|
fields: string[];
|
|
@@ -4524,6 +4523,7 @@ declare const _default: {
|
|
|
4524
4523
|
};
|
|
4525
4524
|
}[];
|
|
4526
4525
|
})[];
|
|
4526
|
+
fields?: undefined;
|
|
4527
4527
|
};
|
|
4528
4528
|
})[];
|
|
4529
4529
|
constants: ({
|
package/types/client/pda.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MPL_CORE_PROGRAM } from '../chain/pda.js';
|
|
2
|
-
export
|
|
2
|
+
export { checkOnCluster, CLUSTERS, cluster, clusterRpcUrl, LOOT_PROGRAM, lootProgram, networkOf, realMoney, scopeClusters, useCluster, walletChain, } from './cluster.js';
|
|
3
3
|
/** MagicBlock's VRF program and its default queue, the only queue the program accepts. */
|
|
4
4
|
export declare const VRF_PROGRAM = "Vrf1RNUjXmQGjmQrQLvJHs9SNkvDJEsRVFPkfSQUwGz";
|
|
5
5
|
export declare const VRF_QUEUE = "Cuj97ggrhhidhbu39TijNVqE74xvKJ69gDervRUXAxGh";
|
|
@@ -93,8 +93,7 @@ export declare function dateWords(seconds: any): string;
|
|
|
93
93
|
* (`ASSUMED_TRIES`).
|
|
94
94
|
* Returns { ok, refusals: [{ code, where, message, fix }], warnings: [{ code, where, message, fix? }] }.
|
|
95
95
|
*/
|
|
96
|
-
export declare function check(economy: any, {
|
|
97
|
-
network?: string | undefined;
|
|
96
|
+
export declare function check(economy: any, { now, project }?: {
|
|
98
97
|
now?: number | undefined;
|
|
99
98
|
project?: any;
|
|
100
99
|
}): {
|
package/types/economy/plan.d.mts
CHANGED
|
@@ -30,11 +30,11 @@ export declare function tableBatches(t: any): never[][];
|
|
|
30
30
|
export declare function partPrize(o: any, m: any): "Raffled" | {
|
|
31
31
|
Stash: any[];
|
|
32
32
|
} | {
|
|
33
|
+
Item?: undefined;
|
|
33
34
|
Compressed: {
|
|
34
35
|
item: any;
|
|
35
36
|
tree: string;
|
|
36
37
|
};
|
|
37
|
-
Item?: undefined;
|
|
38
38
|
Held?: undefined;
|
|
39
39
|
Nft?: undefined;
|
|
40
40
|
Roll?: undefined;
|
|
@@ -137,8 +137,8 @@ export declare function boxArgs(b: any, m: any): {
|
|
|
137
137
|
Item: any[];
|
|
138
138
|
Collection?: undefined;
|
|
139
139
|
} | {
|
|
140
|
-
Collection: any[];
|
|
141
140
|
Item?: undefined;
|
|
141
|
+
Collection: any[];
|
|
142
142
|
};
|
|
143
143
|
key: any;
|
|
144
144
|
test: any;
|
|
@@ -159,8 +159,8 @@ export declare function boxArgs(b: any, m: any): {
|
|
|
159
159
|
Item: any[];
|
|
160
160
|
Collection?: undefined;
|
|
161
161
|
} | {
|
|
162
|
-
Collection: any[];
|
|
163
162
|
Item?: undefined;
|
|
163
|
+
Collection: any[];
|
|
164
164
|
};
|
|
165
165
|
key: any;
|
|
166
166
|
test: any;
|
|
@@ -341,11 +341,11 @@ export declare function scheduleArgs(s: any, m: any): {
|
|
|
341
341
|
* of the pool), an item (a compressed NFT of it into the project's tree, "@tree"), one NFT of a stash, or a roll of a box.
|
|
342
342
|
*/
|
|
343
343
|
export declare function prizeArgs(p: any, m: any): "Raffled" | {
|
|
344
|
+
Item?: undefined;
|
|
344
345
|
Compressed: {
|
|
345
346
|
item: any;
|
|
346
347
|
tree: string;
|
|
347
348
|
};
|
|
348
|
-
Item?: undefined;
|
|
349
349
|
Held?: undefined;
|
|
350
350
|
Nft?: undefined;
|
|
351
351
|
Roll?: undefined;
|
|
@@ -464,8 +464,8 @@ export declare function lotteryArgs(l: any, m: any): {
|
|
|
464
464
|
Item: any[];
|
|
465
465
|
Collection?: undefined;
|
|
466
466
|
} | {
|
|
467
|
-
Collection: any[];
|
|
468
467
|
Item?: undefined;
|
|
468
|
+
Collection: any[];
|
|
469
469
|
};
|
|
470
470
|
key: any;
|
|
471
471
|
test: any;
|
|
@@ -514,8 +514,8 @@ export declare function lotteryArgs(l: any, m: any): {
|
|
|
514
514
|
Item: any[];
|
|
515
515
|
Collection?: undefined;
|
|
516
516
|
} | {
|
|
517
|
-
Collection: any[];
|
|
518
517
|
Item?: undefined;
|
|
518
|
+
Collection: any[];
|
|
519
519
|
};
|
|
520
520
|
key: any;
|
|
521
521
|
test: any;
|
|
@@ -608,8 +608,8 @@ export declare function contestArgs(c: any, m: any, at?: any): {
|
|
|
608
608
|
Item: any[];
|
|
609
609
|
Collection?: undefined;
|
|
610
610
|
} | {
|
|
611
|
-
Collection: any[];
|
|
612
611
|
Item?: undefined;
|
|
612
|
+
Collection: any[];
|
|
613
613
|
};
|
|
614
614
|
key: any;
|
|
615
615
|
test: any;
|
|
@@ -619,11 +619,11 @@ export declare function contestArgs(c: any, m: any, at?: any): {
|
|
|
619
619
|
min_pot: bigint;
|
|
620
620
|
stake: bigint;
|
|
621
621
|
prize: string | {
|
|
622
|
+
Item?: undefined;
|
|
622
623
|
Compressed: {
|
|
623
624
|
item: any;
|
|
624
625
|
tree: string;
|
|
625
626
|
};
|
|
626
|
-
Item?: undefined;
|
|
627
627
|
Held?: undefined;
|
|
628
628
|
Nft?: undefined;
|
|
629
629
|
Roll?: undefined;
|
|
@@ -682,8 +682,8 @@ export declare function contestArgs(c: any, m: any, at?: any): {
|
|
|
682
682
|
Item: any[];
|
|
683
683
|
Collection?: undefined;
|
|
684
684
|
} | {
|
|
685
|
-
Collection: any[];
|
|
686
685
|
Item?: undefined;
|
|
686
|
+
Collection: any[];
|
|
687
687
|
};
|
|
688
688
|
key: any;
|
|
689
689
|
test: any;
|
|
@@ -700,8 +700,8 @@ export declare function farmArgs(f: any, m: any): {
|
|
|
700
700
|
Item: any[];
|
|
701
701
|
Collection?: undefined;
|
|
702
702
|
} | {
|
|
703
|
-
Collection: any[];
|
|
704
703
|
Item?: undefined;
|
|
704
|
+
Collection: any[];
|
|
705
705
|
};
|
|
706
706
|
key: any;
|
|
707
707
|
test: any;
|
|
@@ -780,8 +780,8 @@ export declare function auctionArgs(a: any, m: any): {
|
|
|
780
780
|
Item: any[];
|
|
781
781
|
Collection?: undefined;
|
|
782
782
|
} | {
|
|
783
|
-
Collection: any[];
|
|
784
783
|
Item?: undefined;
|
|
784
|
+
Collection: any[];
|
|
785
785
|
};
|
|
786
786
|
key: any;
|
|
787
787
|
test: any;
|
|
@@ -792,8 +792,8 @@ export declare function auctionArgs(a: any, m: any): {
|
|
|
792
792
|
Item: any[];
|
|
793
793
|
Collection?: undefined;
|
|
794
794
|
} | {
|
|
795
|
-
Collection: any[];
|
|
796
795
|
Item?: undefined;
|
|
796
|
+
Collection: any[];
|
|
797
797
|
};
|
|
798
798
|
key: any;
|
|
799
799
|
test: any;
|
|
@@ -801,11 +801,11 @@ export declare function auctionArgs(a: any, m: any): {
|
|
|
801
801
|
};
|
|
802
802
|
export declare function grantArgs(g: any, m: any): {
|
|
803
803
|
gives: string | {
|
|
804
|
+
Item?: undefined;
|
|
804
805
|
Compressed: {
|
|
805
806
|
item: any;
|
|
806
807
|
tree: string;
|
|
807
808
|
};
|
|
808
|
-
Item?: undefined;
|
|
809
809
|
Held?: undefined;
|
|
810
810
|
Nft?: undefined;
|
|
811
811
|
Roll?: undefined;
|
|
@@ -911,8 +911,8 @@ export declare function grantArgs(g: any, m: any): {
|
|
|
911
911
|
Item: any[];
|
|
912
912
|
Collection?: undefined;
|
|
913
913
|
} | {
|
|
914
|
-
Collection: any[];
|
|
915
914
|
Item?: undefined;
|
|
915
|
+
Collection: any[];
|
|
916
916
|
};
|
|
917
917
|
key: any;
|
|
918
918
|
test: any;
|
package/types/mcp/server.d.mts
CHANGED
|
@@ -352,7 +352,7 @@ export declare function runTool(name: any, input?: {}, ctx?: {}): Promise<{
|
|
|
352
352
|
text: string;
|
|
353
353
|
} | {
|
|
354
354
|
program: string;
|
|
355
|
-
cluster: "devnet";
|
|
355
|
+
cluster: "devnet" | "mainnet";
|
|
356
356
|
version: string;
|
|
357
357
|
idl: "@xgamesfun/solana/idl.json";
|
|
358
358
|
package: `@xgamesfun/solana@${any}`;
|
package/types/mcp/tools.d.mts
CHANGED
|
@@ -22,12 +22,14 @@ export declare function approveCommand(file?: string, paths?: any): string;
|
|
|
22
22
|
export declare function keyFileFor(name: any): string;
|
|
23
23
|
/** The command that makes a project's key file (it prints the key's address, never the key). */
|
|
24
24
|
export declare const keygenCommand: (keyFile: any) => string;
|
|
25
|
-
export declare const CLUSTER = "devnet";
|
|
26
25
|
export declare const DEVNET_RPC = "https://api.devnet.solana.com";
|
|
27
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* What every answer carries, so an agent never has to remember the program's address. The program and the cluster are
|
|
28
|
+
* read when asked for: this process's cluster (`client/cluster.js`).
|
|
29
|
+
*/
|
|
28
30
|
export declare const PROGRAM_INFO: Readonly<{
|
|
29
|
-
program: string;
|
|
30
|
-
cluster: "devnet";
|
|
31
|
+
readonly program: string;
|
|
32
|
+
readonly cluster: "devnet" | "mainnet";
|
|
31
33
|
version: string;
|
|
32
34
|
idl: "@xgamesfun/solana/idl.json";
|
|
33
35
|
package: `@xgamesfun/solana@${any}`;
|
|
@@ -90,7 +92,7 @@ export declare const tools: ({
|
|
|
90
92
|
};
|
|
91
93
|
handler({ part }?: Readonly<Record<string, any>>): Promise<{
|
|
92
94
|
program: string;
|
|
93
|
-
cluster: "devnet";
|
|
95
|
+
cluster: "devnet" | "mainnet";
|
|
94
96
|
version: string;
|
|
95
97
|
idl: "@xgamesfun/solana/idl.json";
|
|
96
98
|
package: `@xgamesfun/solana@${any}`;
|
|
@@ -743,10 +745,10 @@ export declare const tools: ({
|
|
|
743
745
|
additionalProperties: boolean;
|
|
744
746
|
};
|
|
745
747
|
handler(input: any, ctx: any): Promise<{
|
|
748
|
+
token?: undefined;
|
|
746
749
|
mint?: undefined;
|
|
747
750
|
ok: boolean;
|
|
748
751
|
text: string;
|
|
749
|
-
token?: undefined;
|
|
750
752
|
} | {
|
|
751
753
|
mint?: undefined;
|
|
752
754
|
ok: boolean;
|
|
@@ -823,7 +825,7 @@ export declare const tools: ({
|
|
|
823
825
|
};
|
|
824
826
|
handler(): Promise<{
|
|
825
827
|
program: string;
|
|
826
|
-
cluster: "devnet";
|
|
828
|
+
cluster: "devnet" | "mainnet";
|
|
827
829
|
version: string;
|
|
828
830
|
idl: "@xgamesfun/solana/idl.json";
|
|
829
831
|
package: `@xgamesfun/solana@${any}`;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runs `fn` on `cluster` (`devnet` or `mainnet`) and returns what it returns. A cluster loot does not know is refused.
|
|
3
|
+
* @template T
|
|
4
|
+
* @param {'devnet' | 'mainnet'} cluster
|
|
5
|
+
* @param {() => T} fn
|
|
6
|
+
* @returns {T}
|
|
7
|
+
*/
|
|
8
|
+
export declare function withCluster<T>(cluster: 'devnet' | 'mainnet', fn: () => T): T;
|
package/types/play/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export { checkSponsored, httpSponsor, sponsoredCost, sponsorGiveBack, sponsorHan
|
|
|
4
4
|
* `solana:signMessage`, also `signMessage(bytes)`: the app's settle keys are made from one signature of it a session,
|
|
5
5
|
* so a page that closes can make them again (`recover`).
|
|
6
6
|
*/
|
|
7
|
-
export declare function walletStandardSigner(wallet: any, account: any, chain?:
|
|
7
|
+
export declare function walletStandardSigner(wallet: any, account: any, chain?: "solana:devnet" | "solana:mainnet"): {
|
|
8
8
|
address: any;
|
|
9
9
|
signTransaction(wire: any): Promise<any>;
|
|
10
10
|
signMessage?: ((message: any) => Promise<any>) | undefined;
|
|
@@ -34,7 +34,7 @@ export declare function solanaApp({ spec, rpcUrl, rpc, wallet, programs, now, ke
|
|
|
34
34
|
now?: (() => number) | undefined;
|
|
35
35
|
programs?: {} | undefined;
|
|
36
36
|
rpc?: null | undefined;
|
|
37
|
-
rpcUrl?:
|
|
37
|
+
rpcUrl?: null | undefined;
|
|
38
38
|
spec: any;
|
|
39
39
|
sponsor?: null | undefined;
|
|
40
40
|
wallet: any;
|
package/types/results/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { canonicalJson, CERT_KINDS, CLUSTERS, drawText, entryText, giveawayHostText, hostCertText, lockText, NO_GRANT, RESULT_DOMAIN, resultBytes, revokeGiveawayText, revokeText, rosterHash, } from './wire.js';
|
|
2
|
-
/** xgames.fun's results server, on its play host
|
|
2
|
+
/** xgames.fun's results server, on its play host. One host answers for devnet and for mainnet: each request names its cluster. */
|
|
3
3
|
export declare const RESULTS_SERVER = "https://play.xgames.fun/xsolana";
|
|
4
4
|
/** A fresh round id: 16 random bytes, in hex. Make it when the round starts. */
|
|
5
5
|
export declare const newRound: () => string;
|
|
@@ -19,7 +19,7 @@ export declare function keyFromSecret(secret: any): Promise<{
|
|
|
19
19
|
sign: (message: any) => Promise<Uint8Array<ArrayBuffer>>;
|
|
20
20
|
}>;
|
|
21
21
|
/** One signer's signature of a result: { key, signature }. `signer` is a key from newKey, or anything with sign(). */
|
|
22
|
-
export declare function signResult(signer: any, result: any, cluster?:
|
|
22
|
+
export declare function signResult(signer: any, result: any, cluster?: "devnet" | "mainnet"): Promise<{
|
|
23
23
|
key: any;
|
|
24
24
|
signature: string;
|
|
25
25
|
}>;
|
|
@@ -30,7 +30,7 @@ export declare function signResult(signer: any, result: any, cluster?: string):
|
|
|
30
30
|
*/
|
|
31
31
|
export declare function report({ server, cert, signer, game, round, endedAt, winners, cluster, fetchImpl, }: {
|
|
32
32
|
cert: any;
|
|
33
|
-
cluster?:
|
|
33
|
+
cluster?: "devnet" | "mainnet" | undefined;
|
|
34
34
|
endedAt: any;
|
|
35
35
|
fetchImpl?: typeof fetch | undefined;
|
|
36
36
|
game: any;
|
|
@@ -40,7 +40,8 @@ export declare function report({ server, cert, signer, game, round, endedAt, win
|
|
|
40
40
|
winners: any;
|
|
41
41
|
}): Promise<any>;
|
|
42
42
|
/** A wallet's vouchers for a round it won: [{ grant, publicKey, signature, round, expires, … }]. */
|
|
43
|
-
export declare function fetchVouchers({ server, game, round, wallet, fetchImpl }: {
|
|
43
|
+
export declare function fetchVouchers({ server, game, round, wallet, cluster, fetchImpl, }: {
|
|
44
|
+
cluster?: "devnet" | "mainnet" | undefined;
|
|
44
45
|
fetchImpl?: typeof fetch | undefined;
|
|
45
46
|
game: any;
|
|
46
47
|
round: any;
|
|
@@ -80,6 +81,12 @@ export declare function signVoucher({ signer, game, grant, incarnation, wallet,
|
|
|
80
81
|
personHash: string;
|
|
81
82
|
amount: string;
|
|
82
83
|
}>;
|
|
84
|
+
/**
|
|
85
|
+
* A path on a results server, for the cluster the request is on. One server answers for both clusters, and a request
|
|
86
|
+
* that names none is devnet's: so nothing is added on devnet (as every request was before), and `cluster=mainnet` on
|
|
87
|
+
* mainnet.
|
|
88
|
+
*/
|
|
89
|
+
export declare function serverUrl(server: any, path: any, cluster?: "devnet" | "mainnet"): string;
|
|
83
90
|
/**
|
|
84
91
|
* A draw, from the organizer's side and the players'. `signMessage(text) → signature bytes` is the organizer's wallet
|
|
85
92
|
* (its signMessage) or a host key's sign; `by` its address; `cert` the owner's host certificate when `by` is a host key.
|
|
@@ -96,7 +103,7 @@ export declare const draws: {
|
|
|
96
103
|
}) => Promise<any>;
|
|
97
104
|
/** A player enters with their play-host token, or with their wallet's signature (`wallet`, `signMessage`). */
|
|
98
105
|
enter: ({ server, game, draw, token, wallet, signMessage, cluster, fetchImpl, }: {
|
|
99
|
-
cluster?:
|
|
106
|
+
cluster?: "devnet" | "mainnet" | undefined;
|
|
100
107
|
draw: any;
|
|
101
108
|
fetchImpl?: typeof fetch | undefined;
|
|
102
109
|
game: any;
|
|
@@ -110,7 +117,7 @@ export declare const draws: {
|
|
|
110
117
|
beacon: any;
|
|
111
118
|
by: any;
|
|
112
119
|
cert?: null | undefined;
|
|
113
|
-
cluster?:
|
|
120
|
+
cluster?: "devnet" | "mainnet" | undefined;
|
|
114
121
|
draw: any;
|
|
115
122
|
fetchImpl?: typeof fetch | undefined;
|
|
116
123
|
game: any;
|
|
@@ -142,7 +149,7 @@ export declare const giveaways: {
|
|
|
142
149
|
}) => Promise<any>;
|
|
143
150
|
/** Reports its result, signed by its session key. `grant`: the host's grant (each winner is paid from it). */
|
|
144
151
|
report: ({ server, game, giveaway, session, endedAt, winners, grant, cluster, fetchImpl, }: {
|
|
145
|
-
cluster?:
|
|
152
|
+
cluster?: "devnet" | "mainnet" | undefined;
|
|
146
153
|
endedAt: any;
|
|
147
154
|
fetchImpl?: typeof fetch | undefined;
|
|
148
155
|
game: any;
|
|
@@ -35,7 +35,7 @@ export declare function holds({ rpc, spec, wallet, item, atLeast, attribute, min
|
|
|
35
35
|
}): Promise<number>;
|
|
36
36
|
/** The exact text a wallet signs to prove it is its owner's: fixed lines, so nothing else can be passed off as it. */
|
|
37
37
|
export declare const proofText: ({ cluster, game, wallet, purpose, nonce, expires }: {
|
|
38
|
-
cluster?:
|
|
38
|
+
cluster?: "devnet" | "mainnet" | undefined;
|
|
39
39
|
expires: any;
|
|
40
40
|
game: any;
|
|
41
41
|
nonce: any;
|
|
@@ -47,7 +47,7 @@ export declare const proofText: ({ cluster, game, wallet, purpose, nonce, expire
|
|
|
47
47
|
* (unix seconds, `seconds` from now) and takes each nonce once, so a signed proof can't be replayed.
|
|
48
48
|
*/
|
|
49
49
|
export declare function proofRequest({ cluster, game, wallet, purpose, seconds, now, }: {
|
|
50
|
-
cluster?:
|
|
50
|
+
cluster?: "devnet" | "mainnet" | undefined;
|
|
51
51
|
game: any;
|
|
52
52
|
now?: number | undefined;
|
|
53
53
|
purpose?: string | undefined;
|
|
@@ -69,7 +69,7 @@ export declare function readProof(text: any): {
|
|
|
69
69
|
* `fields.nonce` against the ones the server handed out and not yet used.
|
|
70
70
|
*/
|
|
71
71
|
export declare function verifyProof({ text, signature, wallet, game, purpose, cluster, now, }: {
|
|
72
|
-
cluster?:
|
|
72
|
+
cluster?: "devnet" | "mainnet" | undefined;
|
|
73
73
|
game: any;
|
|
74
74
|
now?: number | undefined;
|
|
75
75
|
purpose?: null | undefined;
|