@xgamesfun/solana 0.25.0 → 0.25.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/DISCLAIMER.md +1 -1
- package/NOTICE +4 -4
- package/README.md +81 -31
- package/bin/xsolana.mjs +19 -5
- package/examples/stakers-draw.json +1 -0
- package/js/client/index.js +1 -0
- package/js/client/kit.js +36 -0
- package/js/client/random.js +1 -1
- package/js/economy/check.mjs +11 -0
- package/js/economy/cost.mjs +1 -1
- package/js/economy/explain.mjs +10 -3
- package/js/economy/guide.mjs +1 -1
- package/js/economy/live.mjs +2 -1
- package/js/economy/review.mjs +760 -0
- package/js/economy/schema.json +8 -4
- package/js/economy/trust.mjs +15 -0
- package/js/index.js +1 -0
- package/js/mcp/http.mjs +136 -0
- package/js/mcp/server.mjs +34 -10
- package/js/mcp/tools.mjs +50 -2
- package/js/play/index.js +116 -2
- package/js/play/sponsor.js +302 -0
- package/js/results/index.js +2 -2
- package/package.json +35 -8
- package/release.json +1 -1
- package/skills/xsolana-economy/SKILL.md +32 -13
- package/skills/xsolana-economy/references/after-launch.md +2 -1
- package/skills/xsolana-economy/references/apps.md +28 -0
- package/skills/xsolana-economy/references/sentence-to-spec.md +1 -0
- package/skills/xsolana-economy/references/telling-the-person.md +6 -0
- package/skills/xsolana-economy/references/trust-and-cheating.md +126 -0
- package/types/client/index.d.ts +1 -0
- package/types/client/kit.d.ts +49 -0
- package/types/economy/cost.d.mts +1 -1
- package/types/economy/explain.d.mts +3 -0
- package/types/economy/plan.d.mts +14 -14
- package/types/economy/review.d.mts +45 -0
- package/types/economy/trust.d.mts +8 -0
- package/types/index.d.ts +1 -0
- package/types/mcp/http.d.mts +30 -0
- package/types/mcp/server.d.mts +321 -0
- package/types/mcp/tools.d.mts +71 -1
- package/types/play/index.d.ts +3 -1
- package/types/play/sponsor.d.ts +149 -0
- package/types/results/index.d.ts +1 -1
- package/examples/holder-den.json +0 -38
- package/examples/holders-drop.json +0 -105
- package/examples/match-predictions.json +0 -24
- package/examples/pack-league.json +0 -108
- package/examples/stride-sneakers.json +0 -164
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Trust and cheating
|
|
2
|
+
|
|
3
|
+
The program enforces its own rules: a cheater can't take more than a route's limits, move a voucher to another
|
|
4
|
+
wallet, harvest someone else's seat or mint into the project's collection. What a cheater can still take is what the
|
|
5
|
+
economy's design and its servers leave open: a result the server never really checked, a person counted as many
|
|
6
|
+
wallets, a reward that keeps earning for good. This page is how to read an economy for that, and how to tell the
|
|
7
|
+
person what they are choosing. `xsolana_review` does the reading for a spec; this page says why.
|
|
8
|
+
|
|
9
|
+
## How far a result can be trusted
|
|
10
|
+
|
|
11
|
+
A result is worth paying only as far as the server that signs the voucher can tell it happened. Strongest first:
|
|
12
|
+
|
|
13
|
+
- **The server decides it.** A turn game played on the server, or a room whose server runs the match: the page sends
|
|
14
|
+
inputs, never results. The result is what the server saw.
|
|
15
|
+
- **The server replays it.** A deterministic game (a fixed time step, seeded randomness): the page sends its inputs,
|
|
16
|
+
and the server runs them again and reads the result itself. Mind CPU limits: replay short runs, or a long one in
|
|
17
|
+
pieces as it is played. Never hand the page the whole run's randomness up front: with the seed and the rules, a
|
|
18
|
+
script searches for the best run offline and sends only that. Reveal randomness as the run goes, or keep the seed on
|
|
19
|
+
the server; one open run per player, and count abandoned runs toward the day's.
|
|
20
|
+
- **The server bounds it.** Any game the browser simulates: the server starts each run (an id and its own clock),
|
|
21
|
+
takes each checkpoint in order, refuses what is faster than the game allows, caps what one player earns a day, and
|
|
22
|
+
can ban. A script that plays at human speed still gets through: this limits what a cheater earns, it does not stop
|
|
23
|
+
one.
|
|
24
|
+
|
|
25
|
+
| Level | What it costs to build | CPU and latency | What a cheater gets | Fits |
|
|
26
|
+
| ------- | ------------------------------------------------------------------------------------- | --------------------------------------------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
|
|
27
|
+
| decides | the most: the game's rules run on the server (or in a room that runs the match) | every move waits on the server | what a bot that plays well earns; nothing forged | turn games, card and board games, matches in a room, anything with hidden information |
|
|
28
|
+
| replays | a deterministic game (fixed step, seeded randomness the server keeps) and a replayer | a replay per run, after the fact; short runs or in pieces | what a bot that plays well earns; with the seed up front, the best run found | puzzles, runners, arcade games with short runs |
|
|
29
|
+
| bounds | the least: a run id, the server's clock, checkpoints in order, daily caps, a ban list | almost none | every reward a script claims at human speed, up to the limits | anything the browser simulates; prizes that are cosmetic, small or capped |
|
|
30
|
+
|
|
31
|
+
Even a result the server decided is worth what a good bot can earn. Pay a bounded or replayed result only what you would
|
|
32
|
+
accept losing to a patient script (small amounts, capped a day), and keep entry fees and prize pools for results the
|
|
33
|
+
server decided and for chance (the oracle). Tell players which one your game is.
|
|
34
|
+
|
|
35
|
+
**Say it in the spec.** Every grant paid on vouchers says what its server checks: `"trust": "decides"`, `"replays"` or
|
|
36
|
+
`"bounds"`. It is the spec's own note (it never goes on chain, and changing it publishes nothing), and it must be
|
|
37
|
+
honest: a server that takes the page's word within a pace is `bounds`, whatever else it does. `xsolana_review` reads a
|
|
38
|
+
voucher grant that says nothing as `bounds`, the weakest.
|
|
39
|
+
|
|
40
|
+
## Who gets paid: wallets are not people
|
|
41
|
+
|
|
42
|
+
- **A wallet is free.** Any limit per wallet (`perWallet`, a gate's one claim per collectible shown) limits wallets,
|
|
43
|
+
never a person. What bounds a reward is its totals: `perDay` and `total` are the most it can ever pay, whatever
|
|
44
|
+
happens to a key or how many wallets come.
|
|
45
|
+
- **Count people through vouchers.** `perPerson` counts the person the voucher names (a person hash), which only the
|
|
46
|
+
server chooses: the player can't pick or change it, and an open grant has none. So it is exactly as good as the
|
|
47
|
+
server's choice: a real outside identity (an X account) counts people; a wallet, or a voucher with no person, counts
|
|
48
|
+
nobody. For rewards worth farming, pay only players signed in with X.
|
|
49
|
+
- **Make farming cost something.** Gate on holding a collectible the game sells or a locked stake (`gate`), pay only
|
|
50
|
+
wallets a player proved (`proofRequest` / `verifyProof`), and keep prizes for results small.
|
|
51
|
+
- **Bots play well.** Even a verified result pays a bot what it pays a good player.
|
|
52
|
+
|
|
53
|
+
## What the program guarantees
|
|
54
|
+
|
|
55
|
+
These were attacked on devnet and refused by the program; there is nothing to build for them:
|
|
56
|
+
|
|
57
|
+
- **A voucher is bound to its claim.** It signs the program, the grant, the grant's incarnation, the wallet, the person,
|
|
58
|
+
an expiry and its rounds. It can't be moved to another wallet, or replayed on another grant or a re-made one. A key
|
|
59
|
+
not among the grant's voucher keys is refused, and so is a claim with no voucher on a grant that isn't open.
|
|
60
|
+
- **The winning wallet signs its own claim.** Anyone may pay its fees; nobody claims for it.
|
|
61
|
+
- **A round pays a wallet once** per grant incarnation, whoever signs it again and whenever; `perWallet`,
|
|
62
|
+
`perPerson`, `perKey`, `perDay` and `total` are kept by the program.
|
|
63
|
+
- **A farm's gate can't be forged.** It checks the project's collection and the item number the program writes at mint
|
|
64
|
+
and never lets change: an NFT of another collection, one in no collection, an attribute written by hand, or a mint
|
|
65
|
+
into the project's collection by anyone but the project are refused. Boosts read the staked NFT's own item number.
|
|
66
|
+
- **One seat per NFT, ever.** In escrow, an NFT can't leave before its lock or be staked twice. Watched, an NFT sold
|
|
67
|
+
while staked earns its old staker nothing more, and its new holder takes the seat over. Nobody harvests or unstakes
|
|
68
|
+
someone else's seat.
|
|
69
|
+
- **The project's keys.** A token the project mints has the project as its only minter and no freeze authority. Only
|
|
70
|
+
the authority mints or moves pool funds; only the owner changes mechanics or closes records. Money held for a
|
|
71
|
+
record (a farm's stakes and rewards, a pot, an order, a bid) leaves only by that record's rules.
|
|
72
|
+
- **Chance is the oracle's.** Nobody, the project included, steers a roll or a draw.
|
|
73
|
+
|
|
74
|
+
## What is still yours to get right: the checklist
|
|
75
|
+
|
|
76
|
+
Run `xsolana_review` and go through what it reports; these are the points behind its findings.
|
|
77
|
+
|
|
78
|
+
1. **The signer decides who is paid.** The program checks a voucher's signature, wallet and limits, never what
|
|
79
|
+
happened in the game. Declare `trust` honestly on every voucher grant, and make the server's checks match it.
|
|
80
|
+
2. **Person counting.** `perPerson` holds only when the server names a real person (an X account) in every voucher,
|
|
81
|
+
never a wallet. Without it, each free wallet claims again: set `perDay` and `total` as if every claim were a new
|
|
82
|
+
wallet.
|
|
83
|
+
3. **Sybil wallets.** Open grants (no voucher, code or list) pay any wallet that asks: gate them on something a sybil
|
|
84
|
+
must pay for, keep their prizes small or soulbound, and set `perDay`.
|
|
85
|
+
4. **Voucher key custody.** The key's secret lives only on the server: never in a page, a repository, a spec or a
|
|
86
|
+
chat. Anyone holding it pays anyone, up to the grant's limits, which is why `perDay` and `total` matter. To rotate
|
|
87
|
+
it, put the new public key in the grant's `vouchers` and publish. Use a different key on each cluster: a voucher's
|
|
88
|
+
bytes don't name the cluster.
|
|
89
|
+
5. **Re-made grants pay again.** Closing and making a grant again starts a new incarnation: a new campaign whose
|
|
90
|
+
limits start from zero, and whose list pays every listed round again. Give a re-made grant fresh rounds.
|
|
91
|
+
6. **Emission without an end.** A farm whose rate is minted, with no `runs`, no term on every tier (`earnsFor`), no
|
|
92
|
+
upkeep and no halving, mints for as long as anything is staked. Every way to get what it takes is then worth that
|
|
93
|
+
stream: a cheatable claim of a staked NFT compounds into tokens for good. Give it an end, or pay its rate from its
|
|
94
|
+
vault.
|
|
95
|
+
7. **Prizes worth farming.** A tradeable prize (tokens, an NFT that can be sold, a roll) on a route a script can reach
|
|
96
|
+
is what a cheater farms. Keep such prizes for results the server decides, or small and capped.
|
|
97
|
+
8. **Entry fees and prize pools.** Players' money (a payment, a box's or a lottery's share into a pool) paid out on a
|
|
98
|
+
bounded or replayed result goes to whoever scripts it. Keep those for decided results and chance.
|
|
99
|
+
9. **NFT farm custody.** Escrow moves the NFT to the project while staked; freeze locks it in the wallet; watch leaves
|
|
100
|
+
it free, so it can be sold while staked and its buyer takes the seat. The issuer's own controls still apply to
|
|
101
|
+
NFTs of other collections.
|
|
102
|
+
10. **The gate.** A farm or a route gated on the project's items (`items`, `item_id`, `rarity`) is as strong as the
|
|
103
|
+
ways those items are had. A gate on another collection's attributes trusts whoever can write them.
|
|
104
|
+
11. **The authority and the treasury.** The owner's wallet alone changes every price, rate, grant, limit and voucher
|
|
105
|
+
key; the authority mints, moves pool funds, decides contests and releases holds, with no caps. Keep them in a
|
|
106
|
+
hardware wallet or a multisig; a server that signs gets an authority key of its own, never the owner's.
|
|
107
|
+
12. **The page is untrusted.** A page builds the player's transactions, and a cheater builds their own: the program's
|
|
108
|
+
checks are what count, never the page's. Anything the page decides (a score, a reward amount, who won) is only as
|
|
109
|
+
good as the server that checks it.
|
|
110
|
+
13. **Ordering.** A lottery's tickets are not weighted by time: one buyer can take most of a round right before the
|
|
111
|
+
draw. Anyone, the seller included, can bid an auction up. A box that keeps selling when an outcome runs out
|
|
112
|
+
(`drawLeft`) lets someone watching the stock empty a common outcome to make a rare likelier.
|
|
113
|
+
14. **Contests.** Players' stakes go to the side the authority or a decider key names: keep contests for results the
|
|
114
|
+
server decides, or that anyone can check outside the game.
|
|
115
|
+
|
|
116
|
+
## Telling the person
|
|
117
|
+
|
|
118
|
+
After `xsolana_review`, before the owner approves, say in plain words:
|
|
119
|
+
|
|
120
|
+
- for each signed route, which level its server uses and what a cheater gets ("A script that waits long enough gets
|
|
121
|
+
a Legendary per wallet, up to 100 a day, and each earns 50 tokens a day for good");
|
|
122
|
+
- what the next level would cost to build ("replaying runs needs the game to be deterministic and a server that re-runs
|
|
123
|
+
each run");
|
|
124
|
+
- every high finding, and its fix, or that they accept it.
|
|
125
|
+
|
|
126
|
+
They choose the trade-off, not you.
|
package/types/client/index.d.ts
CHANGED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** @solana/kit's AccountRole: bit 1 is a signer, bit 0 is writable. */
|
|
2
|
+
export declare const KIT_ACCOUNT_ROLE: Readonly<{
|
|
3
|
+
READONLY: 0;
|
|
4
|
+
WRITABLE: 1;
|
|
5
|
+
READONLY_SIGNER: 2;
|
|
6
|
+
WRITABLE_SIGNER: 3;
|
|
7
|
+
}>;
|
|
8
|
+
/**
|
|
9
|
+
* One instruction from a builder here, as @solana/kit takes it: `appendTransactionMessageInstruction(toKitInstruction(ix), m)`.
|
|
10
|
+
* @param {{ programId: string, keys: { pubkey: string, isSigner: boolean, isWritable: boolean }[], data: Uint8Array }} ix
|
|
11
|
+
* @returns {{ programAddress: string, accounts: { address: string, role: number }[], data: Uint8Array }}
|
|
12
|
+
*/
|
|
13
|
+
export declare function toKitInstruction(ix: {
|
|
14
|
+
programId: string;
|
|
15
|
+
keys: {
|
|
16
|
+
pubkey: string;
|
|
17
|
+
isSigner: boolean;
|
|
18
|
+
isWritable: boolean;
|
|
19
|
+
}[];
|
|
20
|
+
data: Uint8Array;
|
|
21
|
+
}): {
|
|
22
|
+
programAddress: string;
|
|
23
|
+
accounts: {
|
|
24
|
+
address: string;
|
|
25
|
+
role: number;
|
|
26
|
+
}[];
|
|
27
|
+
data: Uint8Array;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* A @solana/kit instruction in the shape this package's transactions take (js/chain/tx.js, js/play).
|
|
31
|
+
* @param {{ programAddress: string, accounts?: { address: string, role: number }[], data?: Uint8Array }} ix
|
|
32
|
+
* @returns {{ programId: string, keys: { pubkey: string, isSigner: boolean, isWritable: boolean }[], data: Uint8Array }}
|
|
33
|
+
*/
|
|
34
|
+
export declare function fromKitInstruction(ix: {
|
|
35
|
+
programAddress: string;
|
|
36
|
+
accounts?: {
|
|
37
|
+
address: string;
|
|
38
|
+
role: number;
|
|
39
|
+
}[];
|
|
40
|
+
data?: Uint8Array;
|
|
41
|
+
}): {
|
|
42
|
+
programId: string;
|
|
43
|
+
keys: {
|
|
44
|
+
pubkey: string;
|
|
45
|
+
isSigner: boolean;
|
|
46
|
+
isWritable: boolean;
|
|
47
|
+
}[];
|
|
48
|
+
data: Uint8Array;
|
|
49
|
+
};
|
package/types/economy/cost.d.mts
CHANGED
|
@@ -11,7 +11,7 @@ export declare function setupCost(plan: any, economy: any): {
|
|
|
11
11
|
notes: string[];
|
|
12
12
|
};
|
|
13
13
|
/**
|
|
14
|
-
* What each action costs whoever signs it while the economy runs:
|
|
14
|
+
* What each action costs whoever signs it while the economy runs: xgames.fun's fee, the network's, and for anything
|
|
15
15
|
* that asks MagicBlock's oracle for a random number (a box's open, a lottery's draw, the authority's `roll`) the
|
|
16
16
|
* oracle's own fee (`oracleSol`, model.mjs ORACLE_FEE).
|
|
17
17
|
*/
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
export declare const ruleWords: (r: any) => string;
|
|
2
|
+
/** A gate in a sentence: "Only players who show …", "Only the wallets it names …", "Only wallets with … staked …". */
|
|
3
|
+
export declare const gateWords: (gate: any, verb: any, m: any) => string;
|
|
1
4
|
export declare function explainEconomy(economy: any, { now }?: {
|
|
2
5
|
now?: number | undefined;
|
|
3
6
|
}): {
|
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;
|
|
@@ -512,8 +512,8 @@ export declare function lotteryArgs(l: any, m: any): {
|
|
|
512
512
|
Item: any[];
|
|
513
513
|
Collection?: undefined;
|
|
514
514
|
} | {
|
|
515
|
-
Collection: any[];
|
|
516
515
|
Item?: undefined;
|
|
516
|
+
Collection: any[];
|
|
517
517
|
};
|
|
518
518
|
key: any;
|
|
519
519
|
test: any;
|
|
@@ -587,8 +587,8 @@ export declare function contestArgs(c: any, m: any, at?: any): {
|
|
|
587
587
|
Item: any[];
|
|
588
588
|
Collection?: undefined;
|
|
589
589
|
} | {
|
|
590
|
-
Collection: any[];
|
|
591
590
|
Item?: undefined;
|
|
591
|
+
Collection: any[];
|
|
592
592
|
};
|
|
593
593
|
key: any;
|
|
594
594
|
test: any;
|
|
@@ -598,11 +598,11 @@ export declare function contestArgs(c: any, m: any, at?: any): {
|
|
|
598
598
|
min_pot: bigint;
|
|
599
599
|
stake: bigint;
|
|
600
600
|
prize: string | {
|
|
601
|
+
Item?: undefined;
|
|
601
602
|
Compressed: {
|
|
602
603
|
item: any;
|
|
603
604
|
tree: string;
|
|
604
605
|
};
|
|
605
|
-
Item?: undefined;
|
|
606
606
|
Held?: undefined;
|
|
607
607
|
Nft?: undefined;
|
|
608
608
|
Roll?: undefined;
|
|
@@ -661,8 +661,8 @@ export declare function contestArgs(c: any, m: any, at?: any): {
|
|
|
661
661
|
Item: any[];
|
|
662
662
|
Collection?: undefined;
|
|
663
663
|
} | {
|
|
664
|
-
Collection: any[];
|
|
665
664
|
Item?: undefined;
|
|
665
|
+
Collection: any[];
|
|
666
666
|
};
|
|
667
667
|
key: any;
|
|
668
668
|
test: any;
|
|
@@ -679,8 +679,8 @@ export declare function farmArgs(f: any, m: any): {
|
|
|
679
679
|
Item: any[];
|
|
680
680
|
Collection?: undefined;
|
|
681
681
|
} | {
|
|
682
|
-
Collection: any[];
|
|
683
682
|
Item?: undefined;
|
|
683
|
+
Collection: any[];
|
|
684
684
|
};
|
|
685
685
|
key: any;
|
|
686
686
|
test: any;
|
|
@@ -759,8 +759,8 @@ export declare function auctionArgs(a: any, m: any): {
|
|
|
759
759
|
Item: any[];
|
|
760
760
|
Collection?: undefined;
|
|
761
761
|
} | {
|
|
762
|
-
Collection: any[];
|
|
763
762
|
Item?: undefined;
|
|
763
|
+
Collection: any[];
|
|
764
764
|
};
|
|
765
765
|
key: any;
|
|
766
766
|
test: any;
|
|
@@ -771,8 +771,8 @@ export declare function auctionArgs(a: any, m: any): {
|
|
|
771
771
|
Item: any[];
|
|
772
772
|
Collection?: undefined;
|
|
773
773
|
} | {
|
|
774
|
-
Collection: any[];
|
|
775
774
|
Item?: undefined;
|
|
775
|
+
Collection: any[];
|
|
776
776
|
};
|
|
777
777
|
key: any;
|
|
778
778
|
test: any;
|
|
@@ -780,11 +780,11 @@ export declare function auctionArgs(a: any, m: any): {
|
|
|
780
780
|
};
|
|
781
781
|
export declare function grantArgs(g: any, m: any): {
|
|
782
782
|
gives: string | {
|
|
783
|
+
Item?: undefined;
|
|
783
784
|
Compressed: {
|
|
784
785
|
item: any;
|
|
785
786
|
tree: string;
|
|
786
787
|
};
|
|
787
|
-
Item?: undefined;
|
|
788
788
|
Held?: undefined;
|
|
789
789
|
Nft?: undefined;
|
|
790
790
|
Roll?: undefined;
|
|
@@ -890,8 +890,8 @@ export declare function grantArgs(g: any, m: any): {
|
|
|
890
890
|
Item: any[];
|
|
891
891
|
Collection?: undefined;
|
|
892
892
|
} | {
|
|
893
|
-
Collection: any[];
|
|
894
893
|
Item?: undefined;
|
|
894
|
+
Collection: any[];
|
|
895
895
|
};
|
|
896
896
|
key: any;
|
|
897
897
|
test: any;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { TRUST_LEVELS, TRUST_WORDS } from './trust.mjs';
|
|
2
|
+
/** Severities, most serious first. */
|
|
3
|
+
export declare const SEVERITIES: readonly string[];
|
|
4
|
+
export { TRUST_LEVELS, TRUST_WORDS };
|
|
5
|
+
/**
|
|
6
|
+
* The review of an economy: { ok, routes, findings, tradeoffs }. `ok` is false when there is a high finding, or when
|
|
7
|
+
* the spec does not check (then `refusals` says why, and the rest is empty).
|
|
8
|
+
*/
|
|
9
|
+
export declare function review(economy: any, { now }?: {
|
|
10
|
+
now?: number | undefined;
|
|
11
|
+
}): {
|
|
12
|
+
ok: boolean;
|
|
13
|
+
refusals: any[];
|
|
14
|
+
routes: never[];
|
|
15
|
+
findings: never[];
|
|
16
|
+
tradeoffs: string;
|
|
17
|
+
} | {
|
|
18
|
+
refusals?: undefined;
|
|
19
|
+
ok: boolean;
|
|
20
|
+
routes: ({
|
|
21
|
+
kind: string;
|
|
22
|
+
key: any;
|
|
23
|
+
name: any;
|
|
24
|
+
trigger: string;
|
|
25
|
+
enforced: any[];
|
|
26
|
+
trusts: any[];
|
|
27
|
+
trust: any;
|
|
28
|
+
ceiling: string;
|
|
29
|
+
feeds: any[];
|
|
30
|
+
} | {
|
|
31
|
+
kind: string;
|
|
32
|
+
key: any;
|
|
33
|
+
name: any;
|
|
34
|
+
trigger: string;
|
|
35
|
+
enforced: any[];
|
|
36
|
+
trusts: any;
|
|
37
|
+
trust: null;
|
|
38
|
+
ceiling: string;
|
|
39
|
+
feeds: any[];
|
|
40
|
+
})[];
|
|
41
|
+
findings: any[];
|
|
42
|
+
tradeoffs: string;
|
|
43
|
+
};
|
|
44
|
+
/** A review in words, for the terminal and the tool's text. */
|
|
45
|
+
export declare function describeReview(r: any, name?: string): string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** The trust levels a voucher grant declares, strongest first. */
|
|
2
|
+
export declare const TRUST_LEVELS: readonly string[];
|
|
3
|
+
/** Each trust level in words: what the server does, and what a cheater still gets. */
|
|
4
|
+
export declare const TRUST_WORDS: Readonly<{
|
|
5
|
+
decides: "the server decides the result itself (it runs the game or the match; the page sends only inputs): nothing the page says can forge one, though a bot that plays well still earns what a good player does";
|
|
6
|
+
replays: "the server runs the page’s inputs again and reads the result itself: a forged result fails, though a bot that plays well still earns, and one that knows the run’s randomness up front can search for the best run offline";
|
|
7
|
+
bounds: "the page runs the game and reports the result, and the server checks only its pace, order and daily caps: a script that waits as long as a person would gets every reward, up to the limits";
|
|
8
|
+
}>;
|
package/types/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export { simulate, explain } from './economy/simulate.mjs';
|
|
|
3
3
|
export { plan, setupSteps, playSteps } from './economy/plan.mjs';
|
|
4
4
|
export { cost, explainCost } from './economy/cost.mjs';
|
|
5
5
|
export { explainEconomy } from './economy/explain.mjs';
|
|
6
|
+
export { review, describeReview, SEVERITIES, TRUST_LEVELS, TRUST_WORDS } from './economy/review.mjs';
|
|
6
7
|
export { model } from './economy/model.mjs';
|
|
7
8
|
export { prepare, recordLanded, changedParts } from './economy/live.mjs';
|
|
8
9
|
export { guideText, catalog, CANNOT } from './economy/guide.mjs';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** The largest request body read: a spec is a few kilobytes; a megabyte is far more than any. */
|
|
2
|
+
export declare const MAX_BODY_BYTES = 1000000;
|
|
3
|
+
/**
|
|
4
|
+
* One HTTP request to the MCP endpoint, answered. `allowOrigin(origin)` decides which browser origins may call it (a
|
|
5
|
+
* request with no Origin header, from a server or a desktop app, always may); by default every origin, since the
|
|
6
|
+
* endpoint holds no session, no cookie and nothing private.
|
|
7
|
+
* @param {Request} request
|
|
8
|
+
* @param {{ allowOrigin?: (origin: string) => boolean, maxBodyBytes?: number, ctx?: object }} [options]
|
|
9
|
+
* @returns {Promise<Response>}
|
|
10
|
+
*/
|
|
11
|
+
export declare function mcpHttp(request: Request, { allowOrigin, maxBodyBytes, ctx }?: {
|
|
12
|
+
allowOrigin?: (origin: string) => boolean;
|
|
13
|
+
maxBodyBytes?: number;
|
|
14
|
+
ctx?: object;
|
|
15
|
+
}): Promise<Response>;
|
|
16
|
+
/**
|
|
17
|
+
* Serves mcpHttp at `path` on this machine (`xsolana mcp --http`). It listens on 127.0.0.1 unless told otherwise, and
|
|
18
|
+
* then answers only pages on localhost: a site in the browser can't reach it by renaming its host (DNS rebinding).
|
|
19
|
+
* @returns {Promise<{ address(): { port: number } | string | null, close(done?: () => void): unknown }>} the node:http server
|
|
20
|
+
*/
|
|
21
|
+
export declare function serveHttp({ port, host, path }?: {
|
|
22
|
+
host?: string | undefined;
|
|
23
|
+
path?: string | undefined;
|
|
24
|
+
port?: number | undefined;
|
|
25
|
+
}): Promise<{
|
|
26
|
+
address(): {
|
|
27
|
+
port: number;
|
|
28
|
+
} | string | null;
|
|
29
|
+
close(done?: () => void): unknown;
|
|
30
|
+
}>;
|