@xgamesfun/solana 0.25.4 → 0.26.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.
Files changed (41) hide show
  1. package/README.md +8 -8
  2. package/js/approve/details.mjs +52 -2
  3. package/js/approve/live-check.mjs +0 -15
  4. package/js/approve/server.mjs +5 -4
  5. package/js/chain/token2022.js +3 -2
  6. package/js/client/accounts.js +67 -25
  7. package/js/client/grant.js +7 -2
  8. package/js/client/idl/loot.js +1 -1
  9. package/js/client/idl/loot.json +714 -182
  10. package/js/client/ix.js +617 -113
  11. package/js/client/sizes.js +35 -3
  12. package/js/economy/check.mjs +655 -242
  13. package/js/economy/cost.mjs +2 -4
  14. package/js/economy/explain.mjs +16 -2
  15. package/js/economy/guide.mjs +12 -12
  16. package/js/economy/model.mjs +133 -14
  17. package/js/economy/plan.mjs +36 -11
  18. package/js/economy/review.mjs +50 -8
  19. package/js/economy/schema.json +73 -29
  20. package/js/economy/simulate.mjs +116 -13
  21. package/js/mcp/tools.mjs +2 -2
  22. package/js/play/index.js +847 -296
  23. package/package.json +1 -1
  24. package/release.json +5 -5
  25. package/skills/xsolana-economy/SKILL.md +12 -4
  26. package/skills/xsolana-economy/references/after-launch.md +1 -1
  27. package/skills/xsolana-economy/references/apps.md +11 -2
  28. package/skills/xsolana-economy/references/sentence-to-spec.md +3 -3
  29. package/skills/xsolana-economy/references/telling-the-person.md +21 -4
  30. package/skills/xsolana-economy/references/trust-and-cheating.md +15 -5
  31. package/types/chain/token2022.d.ts +3 -2
  32. package/types/client/accounts.d.ts +34 -11
  33. package/types/client/idl/loot.d.ts +25 -4
  34. package/types/client/ix.d.ts +217 -45
  35. package/types/economy/check.d.mts +5 -0
  36. package/types/economy/model.d.mts +75 -12
  37. package/types/economy/plan.d.mts +22 -1
  38. package/types/economy/simulate.d.mts +12 -1
  39. package/types/mcp/server.d.mts +12 -1
  40. package/types/mcp/tools.d.mts +12 -1
  41. package/types/play/index.d.ts +210 -144
@@ -244,6 +244,27 @@ function borshLength(type, value) {
244
244
 
245
245
  const defined = name => ({ defined: { name } });
246
246
 
247
+ /** The heap reading a list of `n` values of `size` bytes takes (`order::list_bytes`): Borsh makes room for as many as
248
+ * 4,096 bytes hold, then doubles it each time it fills, and every room it outgrew stays used beside the last. */
249
+ function listBytes(n, size) {
250
+ if (n * size <= 4096) return n * size;
251
+ let room = Math.min(Math.max(1, Math.floor(4096 / size)), n);
252
+ let rooms = room;
253
+ while (room < n) {
254
+ room *= 2;
255
+ rooms += room;
256
+ }
257
+ return rooms * size;
258
+ }
259
+ /** What `listBytes` takes beyond the `n` values themselves (`order::outgrown`). */
260
+ const outgrown = (n, size) => listBytes(n, size) - n * size;
261
+ /** The bytes a program `String` and a `DropEntry` take in memory, and an address. */
262
+ const STRING_BYTES = 24;
263
+ const ENTRY_BYTES = 32;
264
+ const ADDRESS_BYTES = 32;
265
+ /** The heap a rule's "one of" list of texts takes, read whole. */
266
+ const textsBytes = rule => (rule?.test?.OneOf ? listBytes(rule.test.OneOf.texts.length, STRING_BYTES) : 0);
267
+
247
268
  /**
248
269
  * The heap reading a box takes beyond its entries (`order::box_bytes`): its odds, gate, shares, subject, slots and
249
270
  * fates, read whole with it, by their bytes and their number. `box`: the box's args, as `upsertBoxIx` takes them.
@@ -261,12 +282,20 @@ export function boxBytes({ odds = [], gate = null, shares = [], subject = null,
261
282
  borshLength({ option: defined('Rule') }, subject) +
262
283
  borshLength({ vec: defined('Slot') }, slotsWritten) +
263
284
  borshLength({ vec: defined('Fate') }, fatesWritten);
285
+ // Each "one of" list of texts (a gate's rule, each odds rule, the subject), read whole; a gate's wallets' room past
286
+ // what they fill.
287
+ const rules =
288
+ (gate?.Holds ? textsBytes(gate.Holds[0]) : 0) +
289
+ odds.reduce((n, o) => n + textsBytes(o.boost?.rule), 0) +
290
+ textsBytes(subject) +
291
+ (gate?.Wallets ? outgrown(gate.Wallets[0].length, ADDRESS_BYTES) : 0);
264
292
  return (
265
293
  BYTES.boxByte * BigInt(bytes) +
266
294
  BYTES.gateByte * BigInt(borshLength({ option: defined('Gate') }, gate)) +
267
295
  BYTES.odds * BigInt(odds.length) +
268
296
  BYTES.fate * BigInt(fates.length) +
269
- BYTES.slot * BigInt(slots.length)
297
+ BYTES.slot * BigInt(slots.length) +
298
+ BigInt(rules)
270
299
  );
271
300
  }
272
301
 
@@ -295,9 +324,11 @@ export function drawsFit(
295
324
  opens = 1,
296
325
  { odds = 0, shares = 0, fates = 0, bytes = 0n, oracle = false } = {},
297
326
  ) {
298
- const list = typeof slots === 'number' || typeof slots === 'bigint' ? [{ count: slots, only: [] }] : (slots ?? []);
327
+ const given = typeof slots === 'number' || typeof slots === 'bigint' ? [{ count: slots, only: [] }] : (slots ?? []);
328
+ // A box with no slots draws once among every entry.
329
+ const list = given.length ? given : [{ count: 1, only: [] }];
299
330
  const draws = list.reduce((n, s) => n + BigInt(s.count), 0n) * BigInt(opens);
300
- if (draws <= 1n) return true;
331
+ // A box of one draw is held to the same answer: one past it would be refused at every purchase.
301
332
  const n = BigInt(entries.length);
302
333
  const weigh = COST.weigh + COST.weighEntry * n;
303
334
  const reads = entries.map(e => e.prizes.map(accountOf));
@@ -332,6 +363,7 @@ export function drawsFit(
332
363
  entries.reduce((c, e) => c + (e.prizes.length ? COST.entry : COST.blank), 0n);
333
364
  let used =
334
365
  BYTES.start +
366
+ BigInt(outgrown(entries.length, ENTRY_BYTES)) +
335
367
  BigInt(bytes) +
336
368
  BYTES.entryRead * n +
337
369
  BYTES.prizeRead * BigInt(entries.reduce((c, e) => c + e.prizes.length, 0));