@xgamesfun/solana 0.26.3 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -9
- package/js/approve/live-check.mjs +106 -1
- package/js/approve/page.html +1 -1
- package/js/approve/page.js +19 -5
- package/js/approve/server.mjs +192 -33
- package/js/chain/metadata.js +92 -0
- package/js/client/compressed.js +12 -5
- package/js/client/idl/loot.js +1 -1
- package/js/client/idl/loot.json +53 -7
- package/js/client/ix.js +44 -9
- package/js/economy/check.mjs +12 -4
- package/js/economy/cost.mjs +6 -5
- package/js/economy/explain.mjs +3 -2
- package/js/economy/guide.mjs +2 -2
- package/js/economy/live.mjs +27 -7
- package/js/economy/model.mjs +13 -2
- package/js/economy/plan.mjs +84 -27
- package/js/economy/schema.json +7 -1
- package/js/mcp/tools.mjs +31 -11
- package/js/play/index.js +519 -193
- package/package.json +1 -1
- package/release.json +5 -5
- package/skills/xsolana-economy/SKILL.md +4 -4
- package/skills/xsolana-economy/references/apps.md +6 -0
- package/skills/xsolana-economy/references/telling-the-person.md +4 -2
- package/skills/xsolana-economy/references/trust-and-cheating.md +4 -3
- package/types/chain/metadata.d.ts +45 -0
- package/types/client/compressed.d.ts +5 -2
- package/types/client/ix.d.ts +38 -7
- package/types/economy/cost.d.mts +11 -3
- package/types/economy/live.d.mts +29 -5
- package/types/economy/model.d.mts +6 -0
- package/types/economy/plan.d.mts +22 -5
- package/types/play/index.d.ts +214 -129
package/js/economy/schema.json
CHANGED
|
@@ -363,7 +363,7 @@
|
|
|
363
363
|
"type": "object",
|
|
364
364
|
"required": ["key", "source"],
|
|
365
365
|
"additionalProperties": false,
|
|
366
|
-
"description": "A currency. `sol`: SOL (players pay in wrapped SOL). `existing`: any mint by address, launched anywhere, classic or Token-2022, pump.fun included (xgames.fun takes no share of its fees). `project` (`game` is its older spelling): a token made when the economy goes live: the project mints it as its rules say (points, tickets, shards), or, with `supply`, a fixed supply minted once to the owner (a community token you keep). A token made this way is named on chain as it is made (its `name`, `symbol` and `uri`), which is what wallets show. Only the owner's wallet can change that later
|
|
366
|
+
"description": "A currency. `sol`: SOL (players pay in wrapped SOL). `existing`: any mint by address, launched anywhere, classic or Token-2022, pump.fun included (xgames.fun takes no share of its fees). `project` (`game` is its older spelling): a token made when the economy goes live: the project mints it as its rules say (points, tickets, shards), or, with `supply`, a fixed supply minted once to the owner (a community token you keep). A token made this way is named on chain as it is made (its `name`, `symbol` and `uri`), which is what wallets show. Only the owner's wallet can change that later: a change to them in a spec that is live is written to the token's name record at the next approve, when it has one its owner can still change (a token that went live before setups named tokens has none).",
|
|
367
367
|
"properties": {
|
|
368
368
|
"key": {
|
|
369
369
|
"$ref": "#/$defs/key"
|
|
@@ -2037,6 +2037,12 @@
|
|
|
2037
2037
|
"tree": {
|
|
2038
2038
|
"$ref": "#/$defs/address"
|
|
2039
2039
|
},
|
|
2040
|
+
"tables": {
|
|
2041
|
+
"type": "array",
|
|
2042
|
+
"items": {
|
|
2043
|
+
"$ref": "#/$defs/address"
|
|
2044
|
+
}
|
|
2045
|
+
},
|
|
2040
2046
|
"mints": {
|
|
2041
2047
|
"type": "object",
|
|
2042
2048
|
"additionalProperties": {
|
package/js/mcp/tools.mjs
CHANGED
|
@@ -16,7 +16,7 @@ import { LOOT_PROGRAM, pda } from '../client/pda.js';
|
|
|
16
16
|
import { check, describe } from '../economy/check.mjs';
|
|
17
17
|
import { legalFlags } from '../economy/legal.mjs';
|
|
18
18
|
import { cost, explainCost } from '../economy/cost.mjs';
|
|
19
|
-
import { changedParts } from '../economy/live.mjs';
|
|
19
|
+
import { changedParts, renamesNote } from '../economy/live.mjs';
|
|
20
20
|
import { example, examples, ideas, search, partsUsed } from '../economy/examples.mjs';
|
|
21
21
|
import { explainEconomy } from '../economy/explain.mjs';
|
|
22
22
|
import { describeReview, review } from '../economy/review.mjs';
|
|
@@ -247,10 +247,11 @@ function flagsToTell(economy, now) {
|
|
|
247
247
|
* what can't change or was taken out.
|
|
248
248
|
*/
|
|
249
249
|
function liveChange(economy) {
|
|
250
|
-
if (!economy.live?.project || !economy.live?.published) return { scope: {}, notes: '', settings: [] };
|
|
251
|
-
const { only, fixed, removed, settings } = changedParts(economy);
|
|
250
|
+
if (!economy.live?.project || !economy.live?.published) return { scope: {}, notes: '', settings: [], changes: 0 };
|
|
251
|
+
const { only, fixed, removed, settings, renames } = changedParts(economy);
|
|
252
252
|
const notes = [
|
|
253
253
|
settings.length ? `\n${settingsNote(settings, economy.live)}` : '',
|
|
254
|
+
renames.length ? `\n${renamesNote(renames)}` : '',
|
|
254
255
|
fixed.length
|
|
255
256
|
? `\nThese can't change once live, and stay as they were: ${fixed.join(', ')} (a farm, an auction or a pool's token).`
|
|
256
257
|
: '',
|
|
@@ -258,7 +259,8 @@ function liveChange(economy) {
|
|
|
258
259
|
? `\nTaken out of the spec but still on chain: ${removed.join(', ')}. To stop one, keep it and set "active": false.`
|
|
259
260
|
: '',
|
|
260
261
|
].join('');
|
|
261
|
-
|
|
262
|
+
// (`changes`: whether anything is to be published at all: a part, or a token's name)
|
|
263
|
+
return { scope: { only, live: economy.live, renames }, notes, settings, changes: only.size + renames.length };
|
|
262
264
|
}
|
|
263
265
|
|
|
264
266
|
/** In words: the spec changes the project's own settings, which publishing never writes. */
|
|
@@ -428,11 +430,20 @@ export const tools = [
|
|
|
428
430
|
const c = cost(economy, { now: nowOf(ctx), ...change.scope });
|
|
429
431
|
if (!c.ok) return refused(c, from);
|
|
430
432
|
const head = change.scope.live
|
|
431
|
-
? change.
|
|
432
|
-
? `This economy is live: this prices only the change (${[...change.scope.only].join(', ')}).\n`
|
|
433
|
+
? change.changes
|
|
434
|
+
? `This economy is live: this prices only the change (${[...change.scope.only, ...change.scope.renames.map(key => `the name of ${key}`)].join(', ')}).\n`
|
|
433
435
|
: 'This economy is live and nothing has changed since it went live: publishing costs nothing.\n'
|
|
434
436
|
: '';
|
|
435
|
-
|
|
437
|
+
// (a name's price is a transaction's, if it is sent at all: only approving reads the token's record)
|
|
438
|
+
const names = change.scope.renames?.length ? `\n${renamesNote(change.scope.renames)}` : '';
|
|
439
|
+
return {
|
|
440
|
+
ok: true,
|
|
441
|
+
from,
|
|
442
|
+
setup: c.setup,
|
|
443
|
+
actions: c.actions,
|
|
444
|
+
fees: c.fees,
|
|
445
|
+
text: head + explainCost(c) + names + footer,
|
|
446
|
+
};
|
|
436
447
|
},
|
|
437
448
|
},
|
|
438
449
|
{
|
|
@@ -559,7 +570,7 @@ export const tools = [
|
|
|
559
570
|
async handler(input, ctx) {
|
|
560
571
|
const { economy, from, file } = await load(input, ctx);
|
|
561
572
|
const change = liveChange(economy);
|
|
562
|
-
if (change.scope.live && !change.
|
|
573
|
+
if (change.scope.live && !change.changes && change.settings.length)
|
|
563
574
|
return {
|
|
564
575
|
ok: false,
|
|
565
576
|
transactions: 0,
|
|
@@ -567,7 +578,7 @@ export const tools = [
|
|
|
567
578
|
steps: [],
|
|
568
579
|
text: `${from} is live, and its parts are as they are on chain. ${settingsNote(change.settings, economy.live)}${footer}`,
|
|
569
580
|
};
|
|
570
|
-
if (change.scope.live && !change.
|
|
581
|
+
if (change.scope.live && !change.changes)
|
|
571
582
|
return {
|
|
572
583
|
ok: true,
|
|
573
584
|
transactions: 0,
|
|
@@ -578,7 +589,15 @@ export const tools = [
|
|
|
578
589
|
const p = plan(economy, { now: nowOf(ctx), ...change.scope });
|
|
579
590
|
if (!p.ok) return refused(p, from);
|
|
580
591
|
const c = cost(economy, { now: nowOf(ctx), ...change.scope });
|
|
581
|
-
|
|
592
|
+
// A token's new name is listed as the file has it: whether it is sent is the chain's to say, as approving reads it.
|
|
593
|
+
const steps = p.transactions.flatMap(t =>
|
|
594
|
+
t.steps.map(s =>
|
|
595
|
+
s.id.startsWith('name:')
|
|
596
|
+
? `${s.says} (sent only if the token has a name record its owner can still change, read when approving)`
|
|
597
|
+
: s.says,
|
|
598
|
+
),
|
|
599
|
+
);
|
|
600
|
+
const renaming = Boolean(change.scope.renames?.length);
|
|
582
601
|
// the file as the approve command names it, relative to the project folder (projectFile's), and plain (plainName)
|
|
583
602
|
const target = file ? path.relative(realPath(path.resolve(cwdOf(ctx))), file) || DEFAULT_FILE : DEFAULT_FILE;
|
|
584
603
|
if (plainName(target) === null)
|
|
@@ -592,7 +611,7 @@ export const tools = [
|
|
|
592
611
|
const command = approveCommand(target);
|
|
593
612
|
const text = [
|
|
594
613
|
...flagsToTell(economy, nowOf(ctx)),
|
|
595
|
-
`${change.scope.live ? 'Publishing this change to the live economy' : 'Going live'}: ${plural(p.transactions.length, 'transaction')}, ${plural(p.approvals, 'wallet approval')}, about ${c.setup.totalSol} SOL on devnet:`,
|
|
614
|
+
`${change.scope.live ? 'Publishing this change to the live economy' : 'Going live'}: ${renaming ? 'at most ' : ''}${plural(p.transactions.length, 'transaction')}, ${plural(p.approvals, 'wallet approval')}, about ${c.setup.totalSol} SOL on devnet:`,
|
|
596
615
|
...steps.map((s, i) => `${i + 1}. ${s}`),
|
|
597
616
|
'',
|
|
598
617
|
`To put it live, the person runs this in a terminal in the project folder (not you): ${command}`,
|
|
@@ -862,6 +881,7 @@ export const tools = [
|
|
|
862
881
|
' app.listForSale(asset, { price }), app.listForRent(asset, { price, lasts, maxPeriods }), app.listing(asset), app.listings(),',
|
|
863
882
|
' app.buyListing(asset, { listing }), app.rentListing(asset, { periods, listing }) (`listing`: what listing() or listings()',
|
|
864
883
|
' showed the player), app.unlist(asset), app.rentedTo(asset) (one account read) listings, sale and rent',
|
|
884
|
+
' app.closeGone(asset) anyone closes the holds and the listing of an NFT the project no longer holds (its collection took it back or burned it): nothing is sent or paid; claims() lists such a hold or loan flagged `gone`, and listing() flags such a listing',
|
|
865
885
|
' app.raffle(id, nft, { price, drawsAt, minSold }), app.unraffle(id, nft) a raffle from the lottery’s own stash',
|
|
866
886
|
' app.compound(key), app.runSchedule(key) compound, send a schedule that is due (a run missed is missed: only a sealed fixed amount pays every run due)',
|
|
867
887
|
' app.farmWalk(key), app.walkFarm(key) a farm idle past many end times: how many it must walk, and walking them in parts (anyone, free; moves ask for the compute to walk a few themselves)',
|