@xgamesfun/solana 0.0.0-stage → 0.20.1
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 +41 -0
- package/LICENSE +202 -0
- package/NOTICE +13 -0
- package/README.md +172 -2
- package/bin/xsolana.mjs +189 -0
- package/examples/artwork-auction.json +51 -0
- package/examples/blind-forge.json +128 -0
- package/examples/coin-flip-arena.json +108 -0
- package/examples/duel-arena.json +137 -0
- package/examples/elements-set.json +281 -0
- package/examples/event-badges.json +67 -0
- package/examples/expedition-guild.json +161 -0
- package/examples/fair-presale.json +48 -0
- package/examples/falling-drop.json +90 -0
- package/examples/guild-missions.json +144 -0
- package/examples/halving-seasons.json +112 -0
- package/examples/hero-trials.json +96 -0
- package/examples/ideas.json +789 -0
- package/examples/level-ladder.json +65 -0
- package/examples/merge-2048.json +128 -0
- package/examples/nft-raffle.json +33 -0
- package/examples/paper-hands-farm.json +56 -0
- package/examples/partner-vault.json +115 -0
- package/examples/sacrifice-raffle.json +118 -0
- package/examples/scorched-treasury.json +84 -0
- package/examples/shelter-fair.json +164 -0
- package/examples/spark-pity.json +153 -0
- package/examples/stakers-draw.json +125 -0
- package/examples/star-fleet.json +157 -0
- package/examples/starforce.json +116 -0
- package/examples/stud-farm.json +134 -0
- package/examples/team-vesting.json +70 -0
- package/examples/trade-in-shop.json +168 -0
- package/js/approve/details.mjs +262 -0
- package/js/approve/ed25519.mjs +36 -0
- package/js/approve/live-check.mjs +144 -0
- package/js/approve/page.html +86 -0
- package/js/approve/page.js +203 -0
- package/js/approve/server.mjs +711 -0
- package/js/chain/base58.js +73 -0
- package/js/chain/borsh.js +261 -0
- package/js/chain/bytes.js +141 -0
- package/js/chain/core.js +169 -0
- package/js/chain/curve.js +52 -0
- package/js/chain/lookup.js +273 -0
- package/js/chain/mint.js +96 -0
- package/js/chain/pda.js +66 -0
- package/js/chain/programs.js +102 -0
- package/js/chain/rpc.js +217 -0
- package/js/chain/sha256.js +68 -0
- package/js/chain/token.js +85 -0
- package/js/chain/token2022.js +247 -0
- package/js/chain/tx.js +224 -0
- package/js/client/accounts.js +347 -0
- package/js/client/compressed.js +46 -0
- package/js/client/grant.js +240 -0
- package/js/client/idl/loot.js +2 -0
- package/js/client/idl/loot.json +17064 -0
- package/js/client/index.js +9 -0
- package/js/client/ix.js +2156 -0
- package/js/client/pda.js +110 -0
- package/js/client/policy.js +48 -0
- package/js/client/sizes.js +54 -0
- package/js/client/traits.js +44 -0
- package/js/connect/connect.mjs +182 -0
- package/js/economy/check.mjs +1991 -0
- package/js/economy/cost.mjs +170 -0
- package/js/economy/examples.mjs +114 -0
- package/js/economy/explain.mjs +235 -0
- package/js/economy/guide.mjs +231 -0
- package/js/economy/legal.mjs +15 -0
- package/js/economy/live.mjs +107 -0
- package/js/economy/model.mjs +583 -0
- package/js/economy/plan.mjs +887 -0
- package/js/economy/schema.json +2923 -0
- package/js/economy/secrets.mjs +60 -0
- package/js/economy/simulate.mjs +952 -0
- package/js/economy/txsize.mjs +45 -0
- package/js/economy/validate.mjs +85 -0
- package/js/index.js +10 -0
- package/js/mcp/server.mjs +113 -0
- package/js/mcp/tools.mjs +479 -0
- package/js/play/index.js +2109 -0
- package/js/results/index.js +184 -0
- package/js/results/wire.js +90 -0
- package/package.json +100 -4
- package/release.json +8 -0
- package/skills/xsolana-economy/SKILL.md +105 -0
- package/skills/xsolana-economy/references/after-launch.md +114 -0
- package/skills/xsolana-economy/references/apps.md +157 -0
- package/skills/xsolana-economy/references/sentence-to-spec.md +172 -0
- package/skills/xsolana-economy/references/telling-the-person.md +93 -0
- package/types/chain/base58.d.ts +10 -0
- package/types/chain/borsh.d.ts +23 -0
- package/types/chain/bytes.d.ts +45 -0
- package/types/chain/core.d.ts +50 -0
- package/types/chain/curve.d.ts +1 -0
- package/types/chain/lookup.d.ts +191 -0
- package/types/chain/mint.d.ts +25 -0
- package/types/chain/pda.d.ts +25 -0
- package/types/chain/programs.d.ts +65 -0
- package/types/chain/rpc.d.ts +66 -0
- package/types/chain/sha256.d.ts +1 -0
- package/types/chain/token.d.ts +141 -0
- package/types/chain/token2022.d.ts +53 -0
- package/types/chain/tx.d.ts +60 -0
- package/types/client/accounts.d.ts +178 -0
- package/types/client/compressed.d.ts +29 -0
- package/types/client/grant.d.ts +125 -0
- package/types/client/idl/loot.d.ts +4467 -0
- package/types/client/index.d.ts +8 -0
- package/types/client/ix.d.ts +1687 -0
- package/types/client/pda.d.ts +91 -0
- package/types/client/policy.d.ts +23 -0
- package/types/client/sizes.d.ts +13 -0
- package/types/client/traits.d.ts +12 -0
- package/types/economy/check.d.mts +105 -0
- package/types/economy/cost.d.mts +68 -0
- package/types/economy/examples.d.mts +27 -0
- package/types/economy/explain.d.mts +19 -0
- package/types/economy/guide.d.mts +140 -0
- package/types/economy/legal.d.mts +12 -0
- package/types/economy/live.d.mts +109 -0
- package/types/economy/model.d.mts +363 -0
- package/types/economy/plan.d.mts +1013 -0
- package/types/economy/secrets.d.mts +4 -0
- package/types/economy/simulate.d.mts +156 -0
- package/types/economy/txsize.d.mts +17 -0
- package/types/economy/validate.d.mts +3 -0
- package/types/index.d.ts +9 -0
- package/types/mcp/tools.d.mts +627 -0
- package/types/play/index.d.ts +469 -0
- package/types/results/index.d.ts +155 -0
- package/types/results/wire.d.ts +122 -0
package/DISCLAIMER.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Disclaimer
|
|
2
|
+
|
|
3
|
+
Read this before you use this package, its tools or the loot program. Using them means you accept it.
|
|
4
|
+
|
|
5
|
+
## No warranty, use at your own risk
|
|
6
|
+
|
|
7
|
+
- This package (`@xgamesfun/solana`, its CLI, MCP server, skill and plugin) and the loot program are provided **"as
|
|
8
|
+
is" and "as available"**, without warranties of any kind, express or implied, including merchantability, fitness
|
|
9
|
+
for a particular purpose, title and non-infringement. The [license](LICENSE) (Apache-2.0, sections 7 and 8) applies
|
|
10
|
+
in full.
|
|
11
|
+
- **The loot program has not been independently audited.** It may contain bugs or vulnerabilities. We make no
|
|
12
|
+
guarantee that it, or anything this package builds, sends or signs for, is safe, secure, correct or available.
|
|
13
|
+
Tokens, NFTs and SOL sent to it can be lost, locked or taken, permanently.
|
|
14
|
+
- Blockchain transactions cannot be undone. You are responsible for every transaction you approve, for your wallet
|
|
15
|
+
and its keys, and for checking what you sign.
|
|
16
|
+
- The numbers the tools give (simulations, costs, odds, how long a pool lasts) are estimates from the spec and its
|
|
17
|
+
assumptions, not promises of what will happen.
|
|
18
|
+
- The package relies on services nobody here controls: Solana itself and its RPC providers, the randomness oracle,
|
|
19
|
+
wallets, token and NFT programs, npm and any results server. Any of them can fail, change or stop.
|
|
20
|
+
- The public results server (`https://play.xgames.fun/xsolana`) is offered as is, may change or stop at any time, and
|
|
21
|
+
carries no promise of uptime or of what it vouches for.
|
|
22
|
+
- **Devnet only.** Nothing here is meant for real money until the program has been independently audited.
|
|
23
|
+
|
|
24
|
+
## Use it legally
|
|
25
|
+
|
|
26
|
+
- **Nothing here is legal, financial, tax or investment advice.** The legal flags the checker raises (chance at
|
|
27
|
+
money, resellable random items, revenue sharing, shill bidding) are reminders, not a complete list and not a legal
|
|
28
|
+
opinion. A spec with no flag is not therefore legal.
|
|
29
|
+
- **You are solely responsible for making sure what you build, and how you run it, is legal everywhere it is
|
|
30
|
+
offered.** Depending on where you and your players are, that may include laws on gambling, lotteries, sweepstakes
|
|
31
|
+
and prize promotions, securities and commodities, money transmission and payments, consumer protection and odds
|
|
32
|
+
disclosure, age limits and children's privacy, data protection, tax, sanctions and anti-money-laundering.
|
|
33
|
+
- Do not use this package or the program for anything unlawful, to evade sanctions, or where it is prohibited. Ask a
|
|
34
|
+
qualified lawyer before you offer anything with real value.
|
|
35
|
+
|
|
36
|
+
## Limitation of liability
|
|
37
|
+
|
|
38
|
+
To the fullest extent the law allows, games.fun, XGamesFun and the contributors to this package are not liable for any
|
|
39
|
+
loss or damage of any kind, direct or indirect, including lost funds, tokens, NFTs, profits or data, arising from the
|
|
40
|
+
use of, or inability to use, this package, the loot program, the results server or anything built with them, even if
|
|
41
|
+
told such loss was possible.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
|
|
2
|
+
Apache License
|
|
3
|
+
Version 2.0, January 2004
|
|
4
|
+
http://www.apache.org/licenses/
|
|
5
|
+
|
|
6
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
7
|
+
|
|
8
|
+
1. Definitions.
|
|
9
|
+
|
|
10
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
11
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
12
|
+
|
|
13
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
14
|
+
the copyright owner that is granting the License.
|
|
15
|
+
|
|
16
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
17
|
+
other entities that control, are controlled by, or are under common
|
|
18
|
+
control with that entity. For the purposes of this definition,
|
|
19
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
20
|
+
direction or management of such entity, whether by contract or
|
|
21
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
22
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
23
|
+
|
|
24
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
25
|
+
exercising permissions granted by this License.
|
|
26
|
+
|
|
27
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
28
|
+
including but not limited to software source code, documentation
|
|
29
|
+
source, and configuration files.
|
|
30
|
+
|
|
31
|
+
"Object" form shall mean any form resulting from mechanical
|
|
32
|
+
transformation or translation of a Source form, including but
|
|
33
|
+
not limited to compiled object code, generated documentation,
|
|
34
|
+
and conversions to other media types.
|
|
35
|
+
|
|
36
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
37
|
+
Object form, made available under the License, as indicated by a
|
|
38
|
+
copyright notice that is included in or attached to the work
|
|
39
|
+
(an example is provided in the Appendix below).
|
|
40
|
+
|
|
41
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
42
|
+
form, that is based on (or derived from) the Work and for which the
|
|
43
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
44
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
45
|
+
of this License, Derivative Works shall not include works that remain
|
|
46
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
47
|
+
the Work and Derivative Works thereof.
|
|
48
|
+
|
|
49
|
+
"Contribution" shall mean any work of authorship, including
|
|
50
|
+
the original version of the Work and any modifications or additions
|
|
51
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
52
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
53
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
54
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
55
|
+
means any form of electronic, verbal, or written communication sent
|
|
56
|
+
to the Licensor or its representatives, including but not limited to
|
|
57
|
+
communication on electronic mailing lists, source code control systems,
|
|
58
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
59
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
60
|
+
excluding communication that is conspicuously marked or otherwise
|
|
61
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
62
|
+
|
|
63
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
64
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
65
|
+
subsequently incorporated within the Work.
|
|
66
|
+
|
|
67
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
68
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
69
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
70
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
71
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
72
|
+
Work and such Derivative Works in Source or Object form.
|
|
73
|
+
|
|
74
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
75
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
76
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
77
|
+
(except as stated in this section) patent license to make, have made,
|
|
78
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
79
|
+
where such license applies only to those patent claims licensable
|
|
80
|
+
by such Contributor that are necessarily infringed by their
|
|
81
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
82
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
83
|
+
institute patent litigation against any entity (including a
|
|
84
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
85
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
86
|
+
or contributory patent infringement, then any patent licenses
|
|
87
|
+
granted to You under this License for that Work shall terminate
|
|
88
|
+
as of the date such litigation is filed.
|
|
89
|
+
|
|
90
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
91
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
92
|
+
modifications, and in Source or Object form, provided that You
|
|
93
|
+
meet the following conditions:
|
|
94
|
+
|
|
95
|
+
(a) You must give any other recipients of the Work or
|
|
96
|
+
Derivative Works a copy of this License; and
|
|
97
|
+
|
|
98
|
+
(b) You must cause any modified files to carry prominent notices
|
|
99
|
+
stating that You changed the files; and
|
|
100
|
+
|
|
101
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
102
|
+
that You distribute, all copyright, patent, trademark, and
|
|
103
|
+
attribution notices from the Source form of the Work,
|
|
104
|
+
excluding those notices that do not pertain to any part of
|
|
105
|
+
the Derivative Works; and
|
|
106
|
+
|
|
107
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
108
|
+
distribution, then any Derivative Works that You distribute must
|
|
109
|
+
include a readable copy of the attribution notices contained
|
|
110
|
+
within such NOTICE file, excluding those notices that do not
|
|
111
|
+
pertain to any part of the Derivative Works, in at least one
|
|
112
|
+
of the following places: within a NOTICE text file distributed
|
|
113
|
+
as part of the Derivative Works; within the Source form or
|
|
114
|
+
documentation, if provided along with the Derivative Works; or,
|
|
115
|
+
within a display generated by the Derivative Works, if and
|
|
116
|
+
wherever such third-party notices normally appear. The contents
|
|
117
|
+
of the NOTICE file are for informational purposes only and
|
|
118
|
+
do not modify the License. You may add Your own attribution
|
|
119
|
+
notices within Derivative Works that You distribute, alongside
|
|
120
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
121
|
+
that such additional attribution notices cannot be construed
|
|
122
|
+
as modifying the License.
|
|
123
|
+
|
|
124
|
+
You may add Your own copyright statement to Your modifications and
|
|
125
|
+
may provide additional or different license terms and conditions
|
|
126
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
127
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
128
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
129
|
+
the conditions stated in this License.
|
|
130
|
+
|
|
131
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
132
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
133
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
134
|
+
this License, without any additional terms or conditions.
|
|
135
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
136
|
+
the terms of any separate license agreement you may have executed
|
|
137
|
+
with Licensor regarding such Contributions.
|
|
138
|
+
|
|
139
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
140
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
141
|
+
except as required for reasonable and customary use in describing the
|
|
142
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
143
|
+
|
|
144
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
145
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
146
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
147
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
148
|
+
implied, including, without limitation, any warranties or conditions
|
|
149
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
150
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
151
|
+
appropriateness of using or redistributing the Work and assume any
|
|
152
|
+
risks associated with Your exercise of permissions under this License.
|
|
153
|
+
|
|
154
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
155
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
156
|
+
unless required by applicable law (such as deliberate and grossly
|
|
157
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
158
|
+
liable to You for damages, including any direct, indirect, special,
|
|
159
|
+
incidental, or consequential damages of any character arising as a
|
|
160
|
+
result of this License or out of the use or inability to use the
|
|
161
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
162
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
163
|
+
other commercial damages or losses), even if such Contributor
|
|
164
|
+
has been advised of the possibility of such damages.
|
|
165
|
+
|
|
166
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
167
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
168
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
169
|
+
or other liability obligations and/or rights consistent with this
|
|
170
|
+
License. However, in accepting such obligations, You may act only
|
|
171
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
172
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
173
|
+
defend, and hold each Contributor harmless for any liability
|
|
174
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
175
|
+
of your accepting any such warranty or additional liability.
|
|
176
|
+
|
|
177
|
+
END OF TERMS AND CONDITIONS
|
|
178
|
+
|
|
179
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
180
|
+
|
|
181
|
+
To apply the Apache License to your work, attach the following
|
|
182
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
183
|
+
replaced with your own identifying information. (Don't include
|
|
184
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
185
|
+
comment syntax for the file format. We also recommend that a
|
|
186
|
+
file or class name and description of purpose be included on the
|
|
187
|
+
same "printed page" as the copyright notice for easier
|
|
188
|
+
identification within third-party archives.
|
|
189
|
+
|
|
190
|
+
Copyright [yyyy] [name of copyright owner]
|
|
191
|
+
|
|
192
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
|
+
you may not use this file except in compliance with the License.
|
|
194
|
+
You may obtain a copy of the License at
|
|
195
|
+
|
|
196
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
197
|
+
|
|
198
|
+
Unless required by applicable law or agreed to in writing, software
|
|
199
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
200
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
201
|
+
See the License for the specific language governing permissions and
|
|
202
|
+
limitations under the License.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
loot
|
|
2
|
+
Copyright 2026 games.fun
|
|
3
|
+
|
|
4
|
+
This product includes software developed at games.fun.
|
|
5
|
+
|
|
6
|
+
Parts of the JavaScript client and tools (js/) are adapted from the games.fun kit,
|
|
7
|
+
MIT License, Copyright (c) 2026 games.fun.
|
|
8
|
+
|
|
9
|
+
The tests run upstream Solana programs (SPL Token, Token-2022, Associated Token, Memo,
|
|
10
|
+
Metaplex Core, Token Metadata, Bubblegum, Account Compression, Noop, MagicBlock VRF) as
|
|
11
|
+
the clusters run them. Those binaries are downloaded by scripts/fetch-fixtures.mjs, checked
|
|
12
|
+
against the hashes in js/test/fixtures/pinned.txt, and are not part of this repository or
|
|
13
|
+
of the npm package. Each is licensed by its own authors.
|
package/README.md
CHANGED
|
@@ -1,3 +1,173 @@
|
|
|
1
|
-
#
|
|
1
|
+
# solana-kit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The tools for **loot**, one shared Solana program for game and community economies. This repository is the npm
|
|
4
|
+
package `@xgamesfun/solana`:
|
|
5
|
+
|
|
6
|
+
- a JavaScript client with no Solana SDK (`@xgamesfun/solana/client`), a player module for apps (`/play`) and a results
|
|
7
|
+
client (`/results`);
|
|
8
|
+
- the economy spec and its checker, quick simulation, cost and plain-words explainer;
|
|
9
|
+
- the `xsolana` CLI and an MCP server with ten `xsolana_*` tools;
|
|
10
|
+
- the `xsolana-economy` skill, and one plugin that carries the tools and the skill to Claude Code and Codex;
|
|
11
|
+
- a local approval page where a project's owner approves going live in their own wallet.
|
|
12
|
+
|
|
13
|
+
An economy is a JSON spec, not a new smart contract. Every project shares the one program, and none writes its own.
|
|
14
|
+
|
|
15
|
+
> **Status:** loot 0.20.1, program ID `9cwqM1TXytPnFZsLfmUyv2dg4uW6Ch9C6UJVPns7NFQ`, **devnet only**. The program is
|
|
16
|
+
> not independently audited, and nothing runs on mainnet until it is. See [SECURITY.md](SECURITY.md).
|
|
17
|
+
|
|
18
|
+
> **Disclaimer:** provided as is, with no warranty and no guarantee that the program or the tools are safe. Use them
|
|
19
|
+
> at your own risk; you are responsible for every transaction you approve and for making sure what you build is legal
|
|
20
|
+
> where it runs. Nothing here is legal or financial advice. Read [DISCLAIMER.md](DISCLAIMER.md) before you use it.
|
|
21
|
+
|
|
22
|
+
## What an economy can be made of
|
|
23
|
+
|
|
24
|
+
- payments and splits, in tokens or with an NFT
|
|
25
|
+
- shops (a purchase in one transaction) and loot boxes
|
|
26
|
+
- pools and timed schedules, sealed or not
|
|
27
|
+
- lotteries and raffles, including no-loss lotteries
|
|
28
|
+
- prizes of any kind on every route, random or not: items, tokens, and NFTs the project holds in a stash
|
|
29
|
+
- an NFT as the price on every route that takes money
|
|
30
|
+
- staking farms with lock tiers, boosts, early exits and tolls
|
|
31
|
+
- crafting recipes
|
|
32
|
+
- holds and contests, with prizes by rank or by stake
|
|
33
|
+
- auctions: the highest bid wins, the outbid refunded at once
|
|
34
|
+
- listings for sale or rent, and bids and loans between players
|
|
35
|
+
- perks, staking and holds for any NFT, whether the project has authority over it or not
|
|
36
|
+
- allowlists of any size (a Merkle list) on every gated route
|
|
37
|
+
- capped rewards and grants that a server vouches for
|
|
38
|
+
- rules on what a collectible says
|
|
39
|
+
|
|
40
|
+
Every move leaves a public receipt. [`docs/program.md`](docs/program.md) describes how the program behaves.
|
|
41
|
+
|
|
42
|
+
## Use it from an AI coding agent
|
|
43
|
+
|
|
44
|
+
The MCP server and the skill let Claude Code, Codex or any MCP agent turn a one-line idea into a checked, simulated
|
|
45
|
+
economy and hand you the command that puts it live in your own wallet.
|
|
46
|
+
|
|
47
|
+
**Claude Code**
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
/plugin marketplace add XGamesFun/solana-kit
|
|
51
|
+
/plugin install xsolana@xgamesfun
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Codex**
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
codex plugin marketplace add XGamesFun/solana-kit
|
|
58
|
+
codex plugin add xsolana@xgamesfun
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Any agent with MCP** (Cursor, opencode, Cline…): run the server with
|
|
62
|
+
`npx -y --package=@xgamesfun/solana@0.20.1 xsolana mcp`. Or let `npx -y @xgamesfun/solana@0.20.1 connect` register it, with
|
|
63
|
+
the skill, for Claude Code and Codex.
|
|
64
|
+
|
|
65
|
+
Then ask for an economy, for example *"a fishing game where each cast costs 0.02 SOL, with a rare golden fish and a
|
|
66
|
+
monthly draw"*.
|
|
67
|
+
|
|
68
|
+
Going live is always yours: `npx -y @xgamesfun/solana@0.20.1 approve` opens a page on your computer where you connect a
|
|
69
|
+
devnet wallet and approve each transaction. The agent never signs and never asks for a key.
|
|
70
|
+
|
|
71
|
+
## Use it from a terminal
|
|
72
|
+
|
|
73
|
+
Every tool runs from the CLI too, on a spec file (`xsolana.json` by default):
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npx -y @xgamesfun/solana@0.20.1 examples shop with loot boxes # the nearest worked examples
|
|
77
|
+
npx -y @xgamesfun/solana@0.20.1 check xsolana.json # refusals and warnings
|
|
78
|
+
npx -y @xgamesfun/solana@0.20.1 simulate xsolana.json # where the money goes, day by day
|
|
79
|
+
npx -y @xgamesfun/solana@0.20.1 cost xsolana.json # what going live and each action cost
|
|
80
|
+
npx -y @xgamesfun/solana@0.20.1 explain xsolana.json # the economy in plain words
|
|
81
|
+
npx -y @xgamesfun/solana@0.20.1 approve xsolana.json # go live, approved in your own wallet
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
`xsolana help` lists every command. Every command names the exact version, so `npx` runs that release and never whatever
|
|
85
|
+
is newest under the name.
|
|
86
|
+
|
|
87
|
+
## Use it from code
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npm install @xgamesfun/solana
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```js
|
|
94
|
+
import * as loot from '@xgamesfun/solana/client';
|
|
95
|
+
const ix = loot.openBoxIx({ player, project, box, nonce }); // one builder per instruction, no Solana SDK
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
| Import | What |
|
|
99
|
+
| --- | --- |
|
|
100
|
+
| `@xgamesfun/solana` | the economy tools: `check`, `simulate`, `plan`, `cost`, `explainEconomy`, `model` |
|
|
101
|
+
| `@xgamesfun/solana/client` | every PDA, one builder per instruction, account and receipt decoders, grant vouchers |
|
|
102
|
+
| `@xgamesfun/solana/play` | `solanaApp`: what a player does with a live economy, from a browser app |
|
|
103
|
+
| `@xgamesfun/solana/results` | results and vouchers a game's server signs |
|
|
104
|
+
| `@xgamesfun/solana/chain/*` | browser-safe Solana primitives: base58, Borsh, transactions, PDAs, tokens, Core |
|
|
105
|
+
| `@xgamesfun/solana/idl.json` | the program's IDL, the authority for account and argument layouts |
|
|
106
|
+
| `@xgamesfun/solana/release.json` | the program build, IDL and client this release is pinned to |
|
|
107
|
+
|
|
108
|
+
The client, chain and play modules run in browsers and Node 22 or later, with no bundler required. The package
|
|
109
|
+
ships TypeScript declarations for every entry point.
|
|
110
|
+
|
|
111
|
+
## Documentation
|
|
112
|
+
|
|
113
|
+
| | |
|
|
114
|
+
| --- | --- |
|
|
115
|
+
| [`docs/program.md`](docs/program.md) | the program: who signs, accounts, every instruction, fees, limits, receipts, costs |
|
|
116
|
+
| [`docs/nfts.md`](docs/nfts.md) | NFTs and tokens, with and without the project's authority |
|
|
117
|
+
| [`docs/harnesses.md`](docs/harnesses.md) | how the plugin reaches Claude Code and Codex, and the release checklist |
|
|
118
|
+
| [`skills/xsolana-economy`](skills/xsolana-economy/SKILL.md) | the skill an agent follows |
|
|
119
|
+
| [`examples/`](examples) | whole economies that check and go live in the tests; `ideas.json`, 112 real economies rated |
|
|
120
|
+
| [`evals/`](evals/README.md) | fresh-session evals of agents building on loot |
|
|
121
|
+
| [`CHANGELOG.md`](CHANGELOG.md), [`SECURITY.md`](SECURITY.md) | versions, the trust model, reporting a vulnerability |
|
|
122
|
+
|
|
123
|
+
## Layout
|
|
124
|
+
|
|
125
|
+
| Path | What |
|
|
126
|
+
| --- | --- |
|
|
127
|
+
| `js/chain/` | browser-safe Solana primitives, no SDK |
|
|
128
|
+
| `js/client/` | the client; `idl/` is the program's IDL |
|
|
129
|
+
| `js/economy/` | the economy spec (version 2, `schema.json`), checker, simulation, setup plan, cost, explainer, guide |
|
|
130
|
+
| `js/play/`, `js/results/` | a player's side of a live economy; results a server vouches for |
|
|
131
|
+
| `js/approve/`, `js/mcp/`, `js/connect/` | the approval page, the MCP server and its tools, `xsolana connect` |
|
|
132
|
+
| `js/sim/`, `js/test/` | LiteSVM running the real program; the tests and their pinned fixtures |
|
|
133
|
+
| `bin/xsolana.mjs` | the CLI |
|
|
134
|
+
| `skills/`, `plugin/` | the skill (copied to `plugin/skills`, `.claude/skills`, `.agents/skills`) and the plugin |
|
|
135
|
+
| `scripts/` | fixtures, skill sync, IDL sync, release manifest, a devnet end-to-end run |
|
|
136
|
+
| `release.json` | the program binary, IDL and client hashes this version is pinned to |
|
|
137
|
+
|
|
138
|
+
## Development
|
|
139
|
+
|
|
140
|
+
Node 22 or later.
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
npm ci
|
|
144
|
+
npm run fixtures # downloads the loot program from devnet and the programs it calls from mainnet, each checked by hash
|
|
145
|
+
npm test # every instruction the client builds, and every example's whole setup, against the real program in LiteSVM
|
|
146
|
+
npm run lint # ESLint
|
|
147
|
+
npm run check # fixtures, skill copies and release.json in step, lint, then the tests
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Nothing in the tests deploys or spends SOL.
|
|
151
|
+
|
|
152
|
+
| Variable | What it does |
|
|
153
|
+
| --- | --- |
|
|
154
|
+
| `XSOLANA_RPC_URL` | a devnet RPC of your own for `xsolana approve` and `xsolana status` (a mainnet URL is refused) |
|
|
155
|
+
| `XSOLANA_NO_OPEN` | `xsolana approve` prints its link without opening a browser |
|
|
156
|
+
| `XSOLANA_DEBUG` | the CLI prints a failure's whole stack, not one line |
|
|
157
|
+
| `XSOLANA_PROGRAM_DIR` | the tests run that program build's `target/deploy/loot.so`, and check the IDL against it | To try the tools in your own agent from a clone,
|
|
158
|
+
`node bin/xsolana.mjs connect --local` registers this checkout's MCP server and the skill with Claude Code and Codex
|
|
159
|
+
(`--remove` takes them out again).
|
|
160
|
+
|
|
161
|
+
After editing `skills/`, run `npm run sync-skills`. Changes to tool texts, the skill or the plugin are best measured
|
|
162
|
+
with the evals before and after ([`evals/README.md`](evals/README.md)). [`AGENTS.md`](AGENTS.md) has the rules for
|
|
163
|
+
working in this repository, for people and coding agents alike.
|
|
164
|
+
|
|
165
|
+
## Contributing
|
|
166
|
+
|
|
167
|
+
Issues and pull requests are welcome: see [CONTRIBUTING.md](CONTRIBUTING.md). Please run `npm run check` before
|
|
168
|
+
sending a change, and report a vulnerability privately as [SECURITY.md](SECURITY.md) describes.
|
|
169
|
+
|
|
170
|
+
## License
|
|
171
|
+
|
|
172
|
+
[Apache-2.0](LICENSE). See [NOTICE](NOTICE) and [DISCLAIMER.md](DISCLAIMER.md): provided as is, without warranty, at your
|
|
173
|
+
own risk.
|
package/bin/xsolana.mjs
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// xsolana: the command line of @xgamesfun/solana. Every tool the MCP server has runs here too, with the same arguments and
|
|
3
|
+
// the same answer, for an agent (or a person) without MCP.
|
|
4
|
+
//
|
|
5
|
+
// xsolana mcp serve the tools over stdio (what a plugin's MCP config runs)
|
|
6
|
+
// xsolana guide [part] [--json] what an economy can be made of, and what loot cannot do
|
|
7
|
+
// xsolana examples [words…] [--json] the nearest worked examples and rated economies
|
|
8
|
+
// xsolana check|simulate|cost|explain|publish|status [file] [--json] one tool on a spec file (default xsolana.json)
|
|
9
|
+
// xsolana approve [file] [--port n] [--no-open] open the local page where the owner approves going live in their wallet
|
|
10
|
+
// xsolana connect [--agent claude|codex] [--scope user|project] [--local] [--remove] [--dry-run] register the MCP server and the skill
|
|
11
|
+
// xsolana tool --list | xsolana tool <name> '<json>' [--args-file f] [--json] any tool by name
|
|
12
|
+
// xsolana version
|
|
13
|
+
//
|
|
14
|
+
// A flag with a value is written either way: --agent claude or --agent=claude; a flag the command doesn't take is
|
|
15
|
+
// refused. A command that fails says why on stderr and exits 1: a usage error in one line (XSOLANA_DEBUG=1 prints the
|
|
16
|
+
// whole stack), a tool's refusal with the tool's own answer. `--json` prints a tool's whole answer on stdout, whatever
|
|
17
|
+
// it is, and the exit code still says whether it failed.
|
|
18
|
+
import { readFile } from 'node:fs/promises';
|
|
19
|
+
|
|
20
|
+
const USAGE = `xsolana: the tools for loot, one shared Solana program for game and community economies.
|
|
21
|
+
|
|
22
|
+
xsolana guide [part] what an economy can be made of
|
|
23
|
+
xsolana examples [words…] where to start
|
|
24
|
+
xsolana check [file] refusals and warnings (default xsolana.json)
|
|
25
|
+
xsolana simulate [file] the quick simulation
|
|
26
|
+
xsolana cost [file] what going live and each action cost
|
|
27
|
+
xsolana explain [file] the economy in plain words
|
|
28
|
+
xsolana publish [file] what going live does, and how to approve it
|
|
29
|
+
xsolana approve [file] approve going live in your own wallet (a local page; --port n, --no-open)
|
|
30
|
+
xsolana status [file] a live economy on chain
|
|
31
|
+
xsolana connect add the xsolana tools to Claude Code or Codex (--agent claude|codex, --scope user|project, --local, --remove, --dry-run)
|
|
32
|
+
xsolana mcp serve the tools over MCP (stdio)
|
|
33
|
+
xsolana tool --list every tool; xsolana tool <name> '<json>' runs one (--args-file f)
|
|
34
|
+
xsolana version this package's xsolana version and program
|
|
35
|
+
|
|
36
|
+
A tool's command (guide, examples, check … status, tool) takes --json for its whole answer as JSON.`;
|
|
37
|
+
|
|
38
|
+
/** A failure the person caused (a bad flag, a missing file): said in one line, without a stack. */
|
|
39
|
+
class UsageError extends Error {}
|
|
40
|
+
|
|
41
|
+
/** The flags that take a value: `--name value` or `--name=value`. */
|
|
42
|
+
const VALUED = new Set(['--args-file', '--agent', '--scope', '--port']);
|
|
43
|
+
/** The flags each command takes; any other is refused. */
|
|
44
|
+
const TOOL_FLAGS = ['--json'];
|
|
45
|
+
const FLAGS = {
|
|
46
|
+
mcp: [],
|
|
47
|
+
guide: TOOL_FLAGS,
|
|
48
|
+
examples: TOOL_FLAGS,
|
|
49
|
+
check: TOOL_FLAGS,
|
|
50
|
+
simulate: TOOL_FLAGS,
|
|
51
|
+
cost: TOOL_FLAGS,
|
|
52
|
+
explain: TOOL_FLAGS,
|
|
53
|
+
publish: TOOL_FLAGS,
|
|
54
|
+
status: TOOL_FLAGS,
|
|
55
|
+
approve: ['--port', '--no-open'],
|
|
56
|
+
connect: ['--agent', '--scope', '--local', '--remove', '--dry-run'],
|
|
57
|
+
tool: ['--list', '--args-file', ...TOOL_FLAGS],
|
|
58
|
+
version: [],
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/** The arguments after the command: { flags (every --name given), values (--name → value), positional }. */
|
|
62
|
+
function parseArgs(rest) {
|
|
63
|
+
const flags = new Set();
|
|
64
|
+
const values = new Map();
|
|
65
|
+
const positional = [];
|
|
66
|
+
for (let i = 0; i < rest.length; i++) {
|
|
67
|
+
const a = rest[i];
|
|
68
|
+
if (!a.startsWith('--') || a === '--') {
|
|
69
|
+
positional.push(a);
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const eq = a.indexOf('=');
|
|
73
|
+
const name = eq > 0 ? a.slice(0, eq) : a;
|
|
74
|
+
flags.add(name);
|
|
75
|
+
if (eq > 0) values.set(name, a.slice(eq + 1));
|
|
76
|
+
else if (VALUED.has(name)) {
|
|
77
|
+
if (i + 1 >= rest.length || rest[i + 1].startsWith('--')) throw new UsageError(`${name} needs a value (${name} <value> or ${name}=<value>).`);
|
|
78
|
+
values.set(name, rest[++i]);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return { flags, values, positional };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** The port `xsolana approve` listens on: a whole number from 1 to 65535, or undefined for any free one. */
|
|
85
|
+
function portOf(value) {
|
|
86
|
+
if (value === undefined) return undefined;
|
|
87
|
+
const n = Number(value);
|
|
88
|
+
if (!/^\d+$/.test(String(value)) || n < 1 || n > 65535) throw new UsageError(`--port must be a whole number from 1 to 65535, not ${JSON.stringify(value)}.`);
|
|
89
|
+
return n;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function main(argv) {
|
|
93
|
+
const [command, ...rest] = argv;
|
|
94
|
+
const { flags, values, positional } = parseArgs(rest);
|
|
95
|
+
const takes = Object.hasOwn(FLAGS, command) ? FLAGS[command] : null;
|
|
96
|
+
const unknown = takes && [...flags].find((f) => !takes.includes(f));
|
|
97
|
+
if (unknown) throw new UsageError(`“${command}” takes no ${unknown} flag (${takes.length ? `only ${takes.join(', ')}` : 'it takes none'}).`);
|
|
98
|
+
|
|
99
|
+
async function tool(name, input) {
|
|
100
|
+
const { runTool } = await import('../js/mcp/server.mjs');
|
|
101
|
+
const r = await runTool(name, input, { cwd: process.cwd() });
|
|
102
|
+
const failed = Boolean(r.isError || r.ok === false);
|
|
103
|
+
if (flags.has('--json')) console.log(JSON.stringify(r, (_, v) => (typeof v === 'bigint' ? v.toString() : v), 2));
|
|
104
|
+
else (failed ? console.error : console.log)(r.text ?? JSON.stringify(r, null, 2));
|
|
105
|
+
if (failed) process.exitCode = 1;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const fileInput = () => (positional[0] ? { file: positional[0] } : {});
|
|
109
|
+
|
|
110
|
+
switch (command) {
|
|
111
|
+
case 'mcp': {
|
|
112
|
+
const { serveStdio } = await import('../js/mcp/server.mjs');
|
|
113
|
+
await serveStdio();
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
case 'guide':
|
|
117
|
+
await tool('xsolana_guide', positional[0] ? { part: positional[0] } : {});
|
|
118
|
+
break;
|
|
119
|
+
case 'examples':
|
|
120
|
+
await tool('xsolana_examples', positional.length ? { query: positional.join(' ') } : {});
|
|
121
|
+
break;
|
|
122
|
+
case 'check':
|
|
123
|
+
case 'simulate':
|
|
124
|
+
case 'cost':
|
|
125
|
+
case 'explain':
|
|
126
|
+
case 'publish':
|
|
127
|
+
case 'status':
|
|
128
|
+
await tool(`xsolana_${command}`, fileInput());
|
|
129
|
+
break;
|
|
130
|
+
case 'approve': {
|
|
131
|
+
const port = portOf(values.get('--port'));
|
|
132
|
+
const { approve } = await import('../js/approve/server.mjs');
|
|
133
|
+
await approve({ file: positional[0] ?? 'xsolana.json', port, open: !flags.has('--no-open') });
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
case 'connect': {
|
|
137
|
+
const { connect } = await import('../js/connect/connect.mjs');
|
|
138
|
+
process.exitCode = await connect({ agent: values.get('--agent'), local: flags.has('--local'), remove: flags.has('--remove'), dryRun: flags.has('--dry-run'), scope: values.get('--scope') });
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
case 'tool': {
|
|
142
|
+
const { tools } = await import('../js/mcp/tools.mjs');
|
|
143
|
+
if (flags.has('--list') || !positional[0]) {
|
|
144
|
+
for (const t of tools) console.log(`${t.name}\n ${t.description.split('. ')[0]}.`);
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
const from = values.get('--args-file');
|
|
148
|
+
const raw = from ? await readFile(from, 'utf8') : positional[1] ?? '{}';
|
|
149
|
+
let input;
|
|
150
|
+
try {
|
|
151
|
+
input = JSON.parse(raw);
|
|
152
|
+
} catch (e) {
|
|
153
|
+
throw new UsageError(`The arguments ${from ? `in ${from} ` : ''}are not JSON (${e.message}). Give them as one word, as in: xsolana tool xsolana_check '{"file":"xsolana.json"}'.`, { cause: e });
|
|
154
|
+
}
|
|
155
|
+
await tool(positional[0], input);
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
case 'version':
|
|
159
|
+
case '--version': {
|
|
160
|
+
const { VERSION, PROGRAM_INFO } = await import('../js/mcp/tools.mjs');
|
|
161
|
+
console.log(`@xgamesfun/solana · loot ${VERSION} · program ${PROGRAM_INFO.program} · ${PROGRAM_INFO.cluster}`);
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
case undefined:
|
|
165
|
+
case 'help':
|
|
166
|
+
case '--help':
|
|
167
|
+
case '-h':
|
|
168
|
+
console.log(USAGE);
|
|
169
|
+
break;
|
|
170
|
+
default:
|
|
171
|
+
console.error(`xsolana: there is no command “${command}”.\n\n${USAGE}`);
|
|
172
|
+
process.exitCode = 1;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/** One line for a failure: what went wrong, without a stack (a missing file names the file). */
|
|
177
|
+
function oneLine(e) {
|
|
178
|
+
if (e?.code === 'ENOENT' && e.path) return `${e.path} does not exist.`;
|
|
179
|
+
if (e?.code === 'EADDRINUSE') return `Port ${e.port} is in use: pick another with --port, or leave it out for any free one.`;
|
|
180
|
+
return String(e?.message ?? e);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
try {
|
|
184
|
+
await main(process.argv.slice(2));
|
|
185
|
+
} catch (e) {
|
|
186
|
+
if (process.env.XSOLANA_DEBUG) console.error(e);
|
|
187
|
+
else console.error(`xsolana: ${oneLine(e)}`);
|
|
188
|
+
process.exitCode = 1;
|
|
189
|
+
}
|