@aephia/atlas-kit 0.6.0-next.3 → 0.6.0-next.31

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 (226) hide show
  1. package/README.md +4 -1
  2. package/dist/cargo/actions/deposit.d.ts.map +1 -1
  3. package/dist/cargo/actions/deposit.js +51 -9
  4. package/dist/cargo/actions/deposit.js.map +1 -1
  5. package/dist/cargo/actions/wallet-context.d.ts +2 -3
  6. package/dist/cargo/actions/wallet-context.d.ts.map +1 -1
  7. package/dist/cargo/actions/wallet-context.js +6 -33
  8. package/dist/cargo/actions/wallet-context.js.map +1 -1
  9. package/dist/cargo/actions/wallet-token.d.ts +1 -1
  10. package/dist/cargo/actions/wallet-token.d.ts.map +1 -1
  11. package/dist/cargo/actions/wallet-token.js +1 -9
  12. package/dist/cargo/actions/wallet-token.js.map +1 -1
  13. package/dist/cargo/actions/withdrawal.d.ts.map +1 -1
  14. package/dist/cargo/actions/withdrawal.js +54 -11
  15. package/dist/cargo/actions/withdrawal.js.map +1 -1
  16. package/dist/client/errors.d.ts +4 -0
  17. package/dist/client/errors.d.ts.map +1 -1
  18. package/dist/client/errors.js +31 -1
  19. package/dist/client/errors.js.map +1 -1
  20. package/dist/client/index.d.ts +1 -0
  21. package/dist/client/index.d.ts.map +1 -1
  22. package/dist/client/index.js +1 -0
  23. package/dist/client/index.js.map +1 -1
  24. package/dist/client/rpc-subscription-provider.d.ts +35 -0
  25. package/dist/client/rpc-subscription-provider.d.ts.map +1 -0
  26. package/dist/client/rpc-subscription-provider.js +190 -0
  27. package/dist/client/rpc-subscription-provider.js.map +1 -0
  28. package/dist/factions/actions/index.d.ts +36 -0
  29. package/dist/factions/actions/index.d.ts.map +1 -0
  30. package/dist/factions/actions/index.js +136 -0
  31. package/dist/factions/actions/index.js.map +1 -0
  32. package/dist/factions/index.d.ts +1 -0
  33. package/dist/factions/index.d.ts.map +1 -1
  34. package/dist/factions/index.js +1 -0
  35. package/dist/factions/index.js.map +1 -1
  36. package/dist/factions/profile-faction.d.ts +58 -0
  37. package/dist/factions/profile-faction.d.ts.map +1 -0
  38. package/dist/factions/profile-faction.js +63 -0
  39. package/dist/factions/profile-faction.js.map +1 -0
  40. package/dist/fleets/actions/add-ship.d.ts +35 -0
  41. package/dist/fleets/actions/add-ship.d.ts.map +1 -0
  42. package/dist/fleets/actions/add-ship.js +149 -0
  43. package/dist/fleets/actions/add-ship.js.map +1 -0
  44. package/dist/fleets/actions/create-fleet.d.ts +36 -0
  45. package/dist/fleets/actions/create-fleet.d.ts.map +1 -0
  46. package/dist/fleets/actions/create-fleet.js +138 -0
  47. package/dist/fleets/actions/create-fleet.js.map +1 -0
  48. package/dist/fleets/actions/index.d.ts +3 -0
  49. package/dist/fleets/actions/index.d.ts.map +1 -1
  50. package/dist/fleets/actions/index.js +3 -0
  51. package/dist/fleets/actions/index.js.map +1 -1
  52. package/dist/fleets/actions/ship-import.d.ts +48 -0
  53. package/dist/fleets/actions/ship-import.d.ts.map +1 -0
  54. package/dist/fleets/actions/ship-import.js +309 -0
  55. package/dist/fleets/actions/ship-import.js.map +1 -0
  56. package/dist/identity/actions/create-profile.d.ts +56 -0
  57. package/dist/identity/actions/create-profile.d.ts.map +1 -0
  58. package/dist/identity/actions/create-profile.js +139 -0
  59. package/dist/identity/actions/create-profile.js.map +1 -0
  60. package/dist/identity/actions/index.d.ts +38 -0
  61. package/dist/identity/actions/index.d.ts.map +1 -0
  62. package/dist/identity/actions/index.js +109 -0
  63. package/dist/identity/actions/index.js.map +1 -0
  64. package/dist/identity/index.d.ts +15 -0
  65. package/dist/identity/index.d.ts.map +1 -1
  66. package/dist/identity/index.js +15 -0
  67. package/dist/identity/index.js.map +1 -1
  68. package/dist/identity/permissions.d.ts +124 -0
  69. package/dist/identity/permissions.d.ts.map +1 -0
  70. package/dist/identity/permissions.js +171 -0
  71. package/dist/identity/permissions.js.map +1 -0
  72. package/dist/internal/c4/cargo-bytes-config.d.ts +7 -0
  73. package/dist/internal/c4/cargo-bytes-config.d.ts.map +1 -0
  74. package/dist/internal/c4/cargo-bytes-config.js +19 -0
  75. package/dist/internal/c4/cargo-bytes-config.js.map +1 -0
  76. package/dist/internal/c4/character-registration.d.ts +9 -0
  77. package/dist/internal/c4/character-registration.d.ts.map +1 -0
  78. package/dist/internal/c4/character-registration.js +21 -0
  79. package/dist/internal/c4/character-registration.js.map +1 -0
  80. package/dist/internal/c4/faction-adapter.d.ts +12 -0
  81. package/dist/internal/c4/faction-adapter.d.ts.map +1 -0
  82. package/dist/internal/c4/faction-adapter.js +52 -0
  83. package/dist/internal/c4/faction-adapter.js.map +1 -0
  84. package/dist/internal/c4/faction-enrollment.d.ts +6 -0
  85. package/dist/internal/c4/faction-enrollment.d.ts.map +1 -0
  86. package/dist/internal/c4/faction-enrollment.js +8 -0
  87. package/dist/internal/c4/faction-enrollment.js.map +1 -0
  88. package/dist/internal/c4/faction-epoch-meter.d.ts +10 -0
  89. package/dist/internal/c4/faction-epoch-meter.d.ts.map +1 -0
  90. package/dist/internal/c4/faction-epoch-meter.js +31 -0
  91. package/dist/internal/c4/faction-epoch-meter.js.map +1 -0
  92. package/dist/internal/c4/faction-treasury.d.ts +23 -0
  93. package/dist/internal/c4/faction-treasury.d.ts.map +1 -0
  94. package/dist/internal/c4/faction-treasury.js +48 -0
  95. package/dist/internal/c4/faction-treasury.js.map +1 -0
  96. package/dist/internal/c4/factions.d.ts +9 -30
  97. package/dist/internal/c4/factions.d.ts.map +1 -1
  98. package/dist/internal/c4/factions.js +22 -107
  99. package/dist/internal/c4/factions.js.map +1 -1
  100. package/dist/internal/c4/fleet-creation.d.ts +7 -0
  101. package/dist/internal/c4/fleet-creation.d.ts.map +1 -0
  102. package/dist/internal/c4/fleet-creation.js +180 -0
  103. package/dist/internal/c4/fleet-creation.js.map +1 -0
  104. package/dist/internal/c4/fleet-crew-binding.d.ts +2 -0
  105. package/dist/internal/c4/fleet-crew-binding.d.ts.map +1 -1
  106. package/dist/internal/c4/fleet-crew-binding.js +5 -0
  107. package/dist/internal/c4/fleet-crew-binding.js.map +1 -1
  108. package/dist/internal/c4/fleet-ship-assembly.d.ts +11 -0
  109. package/dist/internal/c4/fleet-ship-assembly.d.ts.map +1 -0
  110. package/dist/internal/c4/fleet-ship-assembly.js +44 -0
  111. package/dist/internal/c4/fleet-ship-assembly.js.map +1 -0
  112. package/dist/internal/c4/game.d.ts +18 -6
  113. package/dist/internal/c4/game.d.ts.map +1 -1
  114. package/dist/internal/c4/game.js +34 -9
  115. package/dist/internal/c4/game.js.map +1 -1
  116. package/dist/internal/c4/identity.d.ts +2 -7
  117. package/dist/internal/c4/identity.d.ts.map +1 -1
  118. package/dist/internal/c4/identity.js +2 -23
  119. package/dist/internal/c4/identity.js.map +1 -1
  120. package/dist/internal/c4/legacy-cargo-config.d.ts +6 -0
  121. package/dist/internal/c4/legacy-cargo-config.d.ts.map +1 -0
  122. package/dist/internal/c4/legacy-cargo-config.js +26 -0
  123. package/dist/internal/c4/legacy-cargo-config.js.map +1 -0
  124. package/dist/internal/c4/market.js +10 -6
  125. package/dist/internal/c4/market.js.map +1 -1
  126. package/dist/internal/c4/profile-creation.d.ts +17 -0
  127. package/dist/internal/c4/profile-creation.d.ts.map +1 -0
  128. package/dist/internal/c4/profile-creation.js +36 -0
  129. package/dist/internal/c4/profile-creation.js.map +1 -0
  130. package/dist/internal/c4/profile-faction.d.ts.map +1 -1
  131. package/dist/internal/c4/profile-faction.js +2 -0
  132. package/dist/internal/c4/profile-faction.js.map +1 -1
  133. package/dist/internal/c4/profile-permissions.d.ts +14 -0
  134. package/dist/internal/c4/profile-permissions.d.ts.map +1 -0
  135. package/dist/internal/c4/profile-permissions.js +80 -0
  136. package/dist/internal/c4/profile-permissions.js.map +1 -0
  137. package/dist/internal/c4/starbase.js +4 -3
  138. package/dist/internal/c4/starbase.js.map +1 -1
  139. package/dist/internal/c4/wallet-cargo-cache.d.ts +3 -0
  140. package/dist/internal/c4/wallet-cargo-cache.d.ts.map +1 -0
  141. package/dist/internal/c4/wallet-cargo-cache.js +24 -0
  142. package/dist/internal/c4/wallet-cargo-cache.js.map +1 -0
  143. package/dist/internal/c4/world.js +2 -1
  144. package/dist/internal/c4/world.js.map +1 -1
  145. package/dist/internal/loyalty-atlas-bank-state.d.ts +16 -0
  146. package/dist/internal/loyalty-atlas-bank-state.d.ts.map +1 -0
  147. package/dist/internal/loyalty-atlas-bank-state.js +10 -0
  148. package/dist/internal/loyalty-atlas-bank-state.js.map +1 -0
  149. package/dist/internal/planning/account-state.d.ts +4 -0
  150. package/dist/internal/planning/account-state.d.ts.map +1 -0
  151. package/dist/internal/planning/account-state.js +11 -0
  152. package/dist/internal/planning/account-state.js.map +1 -0
  153. package/dist/internal/planning/authorization-adapter.d.ts +17 -0
  154. package/dist/internal/planning/authorization-adapter.d.ts.map +1 -1
  155. package/dist/internal/planning/authorization-adapter.js +50 -0
  156. package/dist/internal/planning/authorization-adapter.js.map +1 -1
  157. package/dist/internal/planning/faction-enrollment.d.ts +12 -0
  158. package/dist/internal/planning/faction-enrollment.d.ts.map +1 -0
  159. package/dist/internal/planning/faction-enrollment.js +67 -0
  160. package/dist/internal/planning/faction-enrollment.js.map +1 -0
  161. package/dist/internal/planning/faction-trade-state.d.ts +16 -0
  162. package/dist/internal/planning/faction-trade-state.d.ts.map +1 -0
  163. package/dist/internal/planning/faction-trade-state.js +39 -0
  164. package/dist/internal/planning/faction-trade-state.js.map +1 -0
  165. package/dist/internal/planning/fleet-creation.d.ts +29 -0
  166. package/dist/internal/planning/fleet-creation.d.ts.map +1 -0
  167. package/dist/internal/planning/fleet-creation.js +106 -0
  168. package/dist/internal/planning/fleet-creation.js.map +1 -0
  169. package/dist/internal/planning/fleet-ship-assembly.d.ts +35 -0
  170. package/dist/internal/planning/fleet-ship-assembly.d.ts.map +1 -0
  171. package/dist/internal/planning/fleet-ship-assembly.js +135 -0
  172. package/dist/internal/planning/fleet-ship-assembly.js.map +1 -0
  173. package/dist/internal/planning/ship-token.d.ts +10 -0
  174. package/dist/internal/planning/ship-token.d.ts.map +1 -0
  175. package/dist/internal/planning/ship-token.js +47 -0
  176. package/dist/internal/planning/ship-token.js.map +1 -0
  177. package/dist/internal/planning/token-mint.d.ts +4 -0
  178. package/dist/internal/planning/token-mint.d.ts.map +1 -0
  179. package/dist/internal/planning/token-mint.js +15 -0
  180. package/dist/internal/planning/token-mint.js.map +1 -0
  181. package/dist/internal/planning/trade-faction-market.d.ts +20 -0
  182. package/dist/internal/planning/trade-faction-market.d.ts.map +1 -0
  183. package/dist/internal/planning/trade-faction-market.js +56 -0
  184. package/dist/internal/planning/trade-faction-market.js.map +1 -0
  185. package/dist/loyalty/actions/index.d.ts.map +1 -1
  186. package/dist/loyalty/actions/index.js +4 -3
  187. package/dist/loyalty/actions/index.js.map +1 -1
  188. package/dist/loyalty/index.d.ts.map +1 -1
  189. package/dist/loyalty/index.js +2 -6
  190. package/dist/loyalty/index.js.map +1 -1
  191. package/dist/markets/actions/index.d.ts +1 -0
  192. package/dist/markets/actions/index.d.ts.map +1 -1
  193. package/dist/markets/actions/index.js +1 -0
  194. package/dist/markets/actions/index.js.map +1 -1
  195. package/dist/markets/actions/trade-faction-market.d.ts +43 -0
  196. package/dist/markets/actions/trade-faction-market.d.ts.map +1 -0
  197. package/dist/markets/actions/trade-faction-market.js +288 -0
  198. package/dist/markets/actions/trade-faction-market.js.map +1 -0
  199. package/dist/mining/actions/index.d.ts +86 -0
  200. package/dist/mining/actions/index.d.ts.map +1 -0
  201. package/dist/mining/actions/index.js +295 -0
  202. package/dist/mining/actions/index.js.map +1 -0
  203. package/dist/planning/execution.d.ts.map +1 -1
  204. package/dist/planning/execution.js +191 -16
  205. package/dist/planning/execution.js.map +1 -1
  206. package/dist/planning/index.d.ts +316 -4
  207. package/dist/planning/index.d.ts.map +1 -1
  208. package/dist/planning/index.js +528 -14
  209. package/dist/planning/index.js.map +1 -1
  210. package/dist/planning/simulation.d.ts +18 -1
  211. package/dist/planning/simulation.d.ts.map +1 -1
  212. package/dist/planning/simulation.js +56 -10
  213. package/dist/planning/simulation.js.map +1 -1
  214. package/dist/registry/cargo.d.ts +9 -6
  215. package/dist/registry/cargo.d.ts.map +1 -1
  216. package/dist/registry/cargo.js +30 -4
  217. package/dist/registry/cargo.js.map +1 -1
  218. package/dist/registry/onboarding.d.ts +6 -0
  219. package/dist/registry/onboarding.d.ts.map +1 -0
  220. package/dist/registry/onboarding.js +24 -0
  221. package/dist/registry/onboarding.js.map +1 -0
  222. package/dist/registry/ships.d.ts +28 -0
  223. package/dist/registry/ships.d.ts.map +1 -0
  224. package/dist/registry/ships.js +51 -0
  225. package/dist/registry/ships.js.map +1 -0
  226. package/package.json +13 -1
@@ -1,5 +1,5 @@
1
1
  import { AccountRole, getBase64Decoder, getBase64Encoder, isAddress, isWritableRole, } from '@solana/kit';
2
- import { InvalidActionInputError } from '../client/errors.js';
2
+ import { InvalidActionInputError, SageSdkError } from '../client/errors.js';
3
3
  import { deepFreeze } from '../internal/immutable-tree.js';
4
4
  import { validatePlanComposition } from './composition.js';
5
5
  import { isPlanInstance, registerPlanInstance } from './plan-instances.js';
@@ -159,9 +159,278 @@ function normalizeSemanticFact(value, field) {
159
159
  }
160
160
  return invalid(`${field}.kind`, semantic.kind, 'one of exclusive, requires, invalidates, or transition');
161
161
  }
162
- function normalizePrecondition(value, field, version = 3) {
162
+ function normalizePrecondition(value, field, version = 12) {
163
163
  const precondition = readRecord(value, field);
164
- if (precondition.kind === 'token-account-or-absent' && version === 3) {
164
+ if (version >= 12 &&
165
+ (precondition.kind === 'faction-treasury-buy' ||
166
+ precondition.kind === 'faction-treasury-sell' ||
167
+ precondition.kind === 'faction-epoch-meter')) {
168
+ const { kind } = precondition;
169
+ assertKeys(precondition, field, [
170
+ 'kind',
171
+ 'address',
172
+ 'game',
173
+ 'factionId',
174
+ 'describes',
175
+ ...(kind === 'faction-treasury-buy'
176
+ ? ['cargoId', 'floorRaw']
177
+ : kind === 'faction-treasury-sell'
178
+ ? ['atlasOutCapPerEpochRaw', 'epochLengthSeconds']
179
+ : []),
180
+ ]);
181
+ const u16 = (key) => {
182
+ const n = precondition[key];
183
+ if (typeof n !== 'number' || !Number.isInteger(n) || n < 0 || n > 65535)
184
+ invalid(`${field}.${key}`, n, 'an unsigned u16 integer');
185
+ return n;
186
+ };
187
+ const integer = (key, signed = false) => {
188
+ const n = precondition[key];
189
+ const min = signed ? -(1n << 63n) : 0n;
190
+ const max = signed ? (1n << 63n) - 1n : (1n << 64n) - 1n;
191
+ if (typeof n !== 'bigint' || n < min || n > max)
192
+ invalid(`${field}.${key}`, n, signed ? 'an i64 bigint' : 'a u64 bigint');
193
+ return n;
194
+ };
195
+ const common = {
196
+ address: readAddress(precondition.address, `${field}.address`),
197
+ game: readAddress(precondition.game, `${field}.game`),
198
+ factionId: u16('factionId'),
199
+ describes: readString(precondition.describes, `${field}.describes`),
200
+ };
201
+ if (kind === 'faction-treasury-buy')
202
+ return Object.freeze({
203
+ kind,
204
+ ...common,
205
+ cargoId: u16('cargoId'),
206
+ floorRaw: integer('floorRaw'),
207
+ });
208
+ if (kind === 'faction-treasury-sell')
209
+ return Object.freeze({
210
+ kind,
211
+ ...common,
212
+ atlasOutCapPerEpochRaw: integer('atlasOutCapPerEpochRaw'),
213
+ epochLengthSeconds: integer('epochLengthSeconds', true),
214
+ });
215
+ return Object.freeze({ kind, ...common });
216
+ }
217
+ if (version >= 11 && precondition.kind === 'fleet-add-ship') {
218
+ assertKeys(precondition, field, [
219
+ 'kind',
220
+ 'address',
221
+ 'game',
222
+ 'profile',
223
+ 'authority',
224
+ 'system',
225
+ 'shipId',
226
+ 'amount',
227
+ 'keyIndex',
228
+ 'configHash',
229
+ 'maximumProfileDebit',
230
+ 'describes',
231
+ ]);
232
+ const keyIndex = precondition.keyIndex;
233
+ if (typeof keyIndex !== 'number' ||
234
+ !Number.isInteger(keyIndex) ||
235
+ keyIndex < 0 ||
236
+ keyIndex > 65535)
237
+ invalid(`${field}.keyIndex`, keyIndex, 'an integer from 0 through 65535');
238
+ const shipId = precondition.shipId;
239
+ if (typeof shipId !== 'number' ||
240
+ !Number.isInteger(shipId) ||
241
+ shipId < 0 ||
242
+ shipId > 65535)
243
+ invalid(`${field}.shipId`, shipId, 'a u16 ship configuration ID');
244
+ const amount = precondition.amount;
245
+ if (typeof amount !== 'bigint' || amount < 1n || amount > 255n)
246
+ invalid(`${field}.amount`, amount, 'a whole ship quantity from 1n through 255n');
247
+ const maximumProfileDebit = precondition.maximumProfileDebit;
248
+ if (typeof maximumProfileDebit !== 'bigint' || maximumProfileDebit < 0n)
249
+ invalid(`${field}.maximumProfileDebit`, maximumProfileDebit, 'a nonnegative bigint');
250
+ return Object.freeze({
251
+ kind: 'fleet-add-ship',
252
+ address: readAddress(precondition.address, `${field}.address`),
253
+ game: readAddress(precondition.game, `${field}.game`),
254
+ profile: readAddress(precondition.profile, `${field}.profile`),
255
+ authority: readAddress(precondition.authority, `${field}.authority`),
256
+ system: readAddress(precondition.system, `${field}.system`),
257
+ keyIndex,
258
+ shipId,
259
+ amount,
260
+ maximumProfileDebit,
261
+ configHash: readDataHash(precondition.configHash, `${field}.configHash`),
262
+ describes: readString(precondition.describes, `${field}.describes`),
263
+ });
264
+ }
265
+ if (version >= 10 && precondition.kind === 'fleet-create') {
266
+ assertKeys(precondition, field, [
267
+ 'kind',
268
+ 'address',
269
+ 'game',
270
+ 'profile',
271
+ 'authority',
272
+ 'system',
273
+ 'keyIndex',
274
+ 'label',
275
+ 'maximumProfileDebit',
276
+ 'describes',
277
+ ]);
278
+ const keyIndex = precondition.keyIndex;
279
+ if (typeof keyIndex !== 'number' ||
280
+ !Number.isSafeInteger(keyIndex) ||
281
+ keyIndex < 0 ||
282
+ keyIndex > 65_535)
283
+ invalid(`${field}.keyIndex`, keyIndex, 'an integer from 0 through 65535');
284
+ const label = readString(precondition.label, `${field}.label`);
285
+ const bytes = new TextEncoder().encode(label);
286
+ if (label.trim().length === 0 ||
287
+ label.includes('\0') ||
288
+ bytes.length > 64 ||
289
+ new TextDecoder('utf-8', { ignoreBOM: true }).decode(bytes) !== label)
290
+ invalid(`${field}.label`, label, 'a nonblank, NUL-free Unicode label of at most 64 UTF-8 bytes');
291
+ const maximumProfileDebit = precondition.maximumProfileDebit;
292
+ if (typeof maximumProfileDebit !== 'bigint' || maximumProfileDebit < 0n)
293
+ invalid(`${field}.maximumProfileDebit`, maximumProfileDebit, 'a nonnegative bigint');
294
+ return Object.freeze({
295
+ kind: 'fleet-create',
296
+ address: readAddress(precondition.address, `${field}.address`),
297
+ game: readAddress(precondition.game, `${field}.game`),
298
+ profile: readAddress(precondition.profile, `${field}.profile`),
299
+ authority: readAddress(precondition.authority, `${field}.authority`),
300
+ system: readAddress(precondition.system, `${field}.system`),
301
+ keyIndex,
302
+ label,
303
+ maximumProfileDebit,
304
+ describes: readString(precondition.describes, `${field}.describes`),
305
+ });
306
+ }
307
+ if (version >= 8 && precondition.kind === 'system-account-or-absent') {
308
+ assertKeys(precondition, field, ['kind', 'address', 'describes']);
309
+ return Object.freeze({
310
+ kind: 'system-account-or-absent',
311
+ address: readAddress(precondition.address, `${field}.address`),
312
+ describes: readString(precondition.describes, `${field}.describes`),
313
+ });
314
+ }
315
+ if (version >= 7 && precondition.kind === 'token-mint') {
316
+ assertKeys(precondition, field, [
317
+ 'kind',
318
+ 'address',
319
+ 'decimals',
320
+ 'describes',
321
+ ]);
322
+ const decimals = precondition.decimals;
323
+ if (typeof decimals !== 'number' ||
324
+ !Number.isInteger(decimals) ||
325
+ decimals < 0 ||
326
+ decimals > 255)
327
+ invalid(`${field}.decimals`, decimals, 'an unsigned u8 mint decimals value');
328
+ return Object.freeze({
329
+ kind: 'token-mint',
330
+ address: readAddress(precondition.address, `${field}.address`),
331
+ decimals,
332
+ describes: readString(precondition.describes, `${field}.describes`),
333
+ });
334
+ }
335
+ if (version >= 6 && precondition.kind === 'game-ship-config') {
336
+ assertKeys(precondition, field, [
337
+ 'kind',
338
+ 'address',
339
+ 'shipId',
340
+ 'configHash',
341
+ 'describes',
342
+ ]);
343
+ const id = precondition.shipId;
344
+ if (typeof id !== 'number' || !Number.isInteger(id) || id < 0 || id > 65535)
345
+ invalid(`${field}.shipId`, id, 'a u16 ship configuration ID');
346
+ return Object.freeze({
347
+ kind: 'game-ship-config',
348
+ address: readAddress(precondition.address, `${field}.address`),
349
+ shipId: id,
350
+ configHash: readDataHash(precondition.configHash, `${field}.configHash`),
351
+ describes: readString(precondition.describes, `${field}.describes`),
352
+ });
353
+ }
354
+ if (version >= 5 && precondition.kind === 'game-account') {
355
+ assertKeys(precondition, field, ['kind', 'address', 'describes']);
356
+ return Object.freeze({
357
+ kind: 'game-account',
358
+ address: readAddress(precondition.address, `${field}.address`),
359
+ describes: readString(precondition.describes, `${field}.describes`),
360
+ });
361
+ }
362
+ if ((version >= 9 && precondition.kind === 'game-cargo-bytes-config') ||
363
+ (version >= 4 &&
364
+ ['token-account', 'game-cargo-config', 'cargo-cache'].includes(String(precondition.kind)))) {
365
+ const base = {
366
+ address: readAddress(precondition.address, `${field}.address`),
367
+ describes: readString(precondition.describes, `${field}.describes`),
368
+ };
369
+ if (precondition.kind === 'token-account') {
370
+ assertKeys(precondition, field, [
371
+ 'kind',
372
+ 'address',
373
+ 'mint',
374
+ 'owner',
375
+ 'minimumBalance',
376
+ 'describes',
377
+ ]);
378
+ const amount = precondition.minimumBalance;
379
+ if (typeof amount !== 'bigint' ||
380
+ amount < 0n ||
381
+ amount > (1n << 64n) - 1n)
382
+ invalid(`${field}.minimumBalance`, amount, 'an unsigned u64 bigint');
383
+ return Object.freeze({
384
+ ...base,
385
+ kind: 'token-account',
386
+ mint: readAddress(precondition.mint, `${field}.mint`),
387
+ owner: readAddress(precondition.owner, `${field}.owner`),
388
+ minimumBalance: amount,
389
+ });
390
+ }
391
+ if (precondition.kind === 'game-cargo-config' ||
392
+ precondition.kind === 'game-cargo-bytes-config') {
393
+ assertKeys(precondition, field, [
394
+ 'kind',
395
+ 'address',
396
+ 'cargoId',
397
+ 'configHash',
398
+ 'describes',
399
+ ]);
400
+ const id = precondition.cargoId;
401
+ if (typeof id !== 'number' ||
402
+ !Number.isInteger(id) ||
403
+ id < 0 ||
404
+ id > 65535)
405
+ invalid(`${field}.cargoId`, id, 'a u16 cargo ID');
406
+ return Object.freeze({
407
+ ...base,
408
+ kind: precondition.kind,
409
+ cargoId: id,
410
+ configHash: readDataHash(precondition.configHash, `${field}.configHash`),
411
+ });
412
+ }
413
+ assertKeys(precondition, field, [
414
+ 'kind',
415
+ 'address',
416
+ 'game',
417
+ 'bump',
418
+ 'describes',
419
+ ]);
420
+ const bump = precondition.bump;
421
+ if (typeof bump !== 'number' ||
422
+ !Number.isInteger(bump) ||
423
+ bump < 0 ||
424
+ bump > 255)
425
+ invalid(`${field}.bump`, bump, 'a u8 PDA bump');
426
+ return Object.freeze({
427
+ ...base,
428
+ kind: 'cargo-cache',
429
+ game: readAddress(precondition.game, `${field}.game`),
430
+ bump,
431
+ });
432
+ }
433
+ if (precondition.kind === 'token-account-or-absent' && version >= 3) {
165
434
  assertKeys(precondition, field, [
166
435
  'kind',
167
436
  'address',
@@ -186,11 +455,32 @@ function normalizePrecondition(value, field, version = 3) {
186
455
  });
187
456
  }
188
457
  if (precondition.kind !== 'account-state') {
189
- invalid(`${field}.kind`, precondition.kind, version === 3
190
- ? 'one of account-state, account-absent, or token-account-or-absent'
191
- : version === 2
192
- ? 'one of account-state or account-absent'
193
- : 'the value account-state');
458
+ invalid(`${field}.kind`, precondition.kind, version === 1
459
+ ? 'the value account-state'
460
+ : `one of ${[
461
+ ...(version >= 12
462
+ ? [
463
+ 'faction-treasury-buy',
464
+ 'faction-treasury-sell',
465
+ 'faction-epoch-meter',
466
+ ]
467
+ : []),
468
+ ...(version >= 11 ? ['fleet-add-ship'] : []),
469
+ ...(version >= 10 ? ['fleet-create'] : []),
470
+ 'account-state',
471
+ 'account-absent',
472
+ ...(version >= 8 ? ['system-account-or-absent'] : []),
473
+ ...(version >= 3 ? ['token-account-or-absent'] : []),
474
+ ...(version >= 4 ? ['token-account'] : []),
475
+ ...(version >= 7 ? ['token-mint'] : []),
476
+ ...(version >= 4 ? ['game-cargo-config'] : []),
477
+ ...(version >= 9 ? ['game-cargo-bytes-config'] : []),
478
+ ...(version >= 4 ? ['cargo-cache'] : []),
479
+ ...(version >= 5 ? ['game-account'] : []),
480
+ ...(version >= 6 ? ['game-ship-config'] : []),
481
+ ]
482
+ .join(', ')
483
+ .replace(/, ([^,]+)$/u, version === 2 ? ' or $1' : ', or $1')}`);
194
484
  }
195
485
  assertKeys(precondition, field, ['kind', 'address', 'dataHash', 'describes']);
196
486
  return Object.freeze({
@@ -242,12 +532,142 @@ function planToJSON(plan) {
242
532
  : {}),
243
533
  signers: [...step.signers],
244
534
  }));
535
+ if (plan.preconditions.some(({ kind }) => kind === 'faction-treasury-buy' ||
536
+ kind === 'faction-treasury-sell' ||
537
+ kind === 'faction-epoch-meter')) {
538
+ return deepFreeze({
539
+ v: 12,
540
+ ...common,
541
+ steps,
542
+ preconditions: plan.preconditions.map((guard) => {
543
+ if (guard.kind === 'faction-treasury-buy')
544
+ return { ...guard, floorRaw: String(guard.floorRaw) };
545
+ if (guard.kind === 'faction-treasury-sell')
546
+ return {
547
+ ...guard,
548
+ atlasOutCapPerEpochRaw: String(guard.atlasOutCapPerEpochRaw),
549
+ epochLengthSeconds: String(guard.epochLengthSeconds),
550
+ };
551
+ if (guard.kind === 'fleet-add-ship')
552
+ return {
553
+ ...guard,
554
+ amount: String(guard.amount),
555
+ maximumProfileDebit: String(guard.maximumProfileDebit),
556
+ };
557
+ if (guard.kind === 'fleet-create')
558
+ return {
559
+ ...guard,
560
+ maximumProfileDebit: String(guard.maximumProfileDebit),
561
+ };
562
+ if (guard.kind === 'token-account')
563
+ return { ...guard, minimumBalance: String(guard.minimumBalance) };
564
+ return { ...guard };
565
+ }),
566
+ });
567
+ }
568
+ if (plan.preconditions.some(({ kind }) => kind === 'fleet-add-ship')) {
569
+ return deepFreeze({
570
+ v: 11,
571
+ ...common,
572
+ steps,
573
+ preconditions: plan.preconditions.map((guard) => guard.kind === 'fleet-add-ship'
574
+ ? {
575
+ ...guard,
576
+ amount: String(guard.amount),
577
+ maximumProfileDebit: String(guard.maximumProfileDebit),
578
+ }
579
+ : guard.kind === 'fleet-create'
580
+ ? {
581
+ ...guard,
582
+ maximumProfileDebit: String(guard.maximumProfileDebit),
583
+ }
584
+ : guard.kind === 'token-account'
585
+ ? { ...guard, minimumBalance: String(guard.minimumBalance) }
586
+ : { ...guard }),
587
+ });
588
+ }
589
+ if (plan.preconditions.some(({ kind }) => kind === 'fleet-create')) {
590
+ return deepFreeze({
591
+ v: 10,
592
+ ...common,
593
+ steps,
594
+ preconditions: plan.preconditions.map((guard) => guard.kind === 'fleet-create'
595
+ ? { ...guard, maximumProfileDebit: String(guard.maximumProfileDebit) }
596
+ : guard.kind === 'token-account'
597
+ ? { ...guard, minimumBalance: String(guard.minimumBalance) }
598
+ : { ...guard }),
599
+ });
600
+ }
601
+ if (plan.preconditions.some(({ kind }) => kind === 'game-cargo-bytes-config')) {
602
+ return deepFreeze({
603
+ v: 9,
604
+ ...common,
605
+ steps,
606
+ preconditions: plan.preconditions.map((guard) => guard.kind === 'token-account'
607
+ ? { ...guard, minimumBalance: String(guard.minimumBalance) }
608
+ : { ...guard }),
609
+ });
610
+ }
611
+ if (plan.preconditions.some(({ kind }) => kind === 'system-account-or-absent')) {
612
+ return deepFreeze({
613
+ v: 8,
614
+ ...common,
615
+ steps,
616
+ preconditions: plan.preconditions.map((guard) => guard.kind === 'token-account'
617
+ ? { ...guard, minimumBalance: String(guard.minimumBalance) }
618
+ : { ...guard }),
619
+ });
620
+ }
621
+ if (plan.preconditions.some(({ kind }) => kind === 'token-mint')) {
622
+ return deepFreeze({
623
+ v: 7,
624
+ ...common,
625
+ steps,
626
+ preconditions: plan.preconditions.map((guard) => guard.kind === 'token-account'
627
+ ? { ...guard, minimumBalance: String(guard.minimumBalance) }
628
+ : { ...guard }),
629
+ });
630
+ }
631
+ if (plan.preconditions.some(({ kind }) => kind === 'game-ship-config')) {
632
+ return deepFreeze({
633
+ v: 6,
634
+ ...common,
635
+ steps,
636
+ preconditions: plan.preconditions.map((guard) => guard.kind === 'token-account'
637
+ ? { ...guard, minimumBalance: String(guard.minimumBalance) }
638
+ : { ...guard }),
639
+ });
640
+ }
641
+ if (plan.preconditions.some(({ kind }) => kind === 'game-account')) {
642
+ return deepFreeze({
643
+ v: 5,
644
+ ...common,
645
+ steps,
646
+ preconditions: plan.preconditions.map((guard) => guard.kind === 'token-account'
647
+ ? { ...guard, minimumBalance: String(guard.minimumBalance) }
648
+ : { ...guard }),
649
+ });
650
+ }
651
+ if (plan.preconditions.some(({ kind }) => kind === 'token-account' ||
652
+ kind === 'game-cargo-config' ||
653
+ kind === 'cargo-cache')) {
654
+ return deepFreeze({
655
+ v: 4,
656
+ ...common,
657
+ steps,
658
+ preconditions: plan.preconditions.map((guard) => guard.kind === 'token-account'
659
+ ? { ...guard, minimumBalance: String(guard.minimumBalance) }
660
+ : { ...guard }),
661
+ });
662
+ }
245
663
  if (plan.preconditions.some(({ kind }) => kind === 'token-account-or-absent')) {
246
664
  return deepFreeze({
247
665
  v: 3,
248
666
  ...common,
249
667
  steps,
250
- preconditions: plan.preconditions.map((guard) => ({ ...guard })),
668
+ preconditions: plan.preconditions.map((guard) => ({
669
+ ...guard,
670
+ })),
251
671
  });
252
672
  }
253
673
  if (hasSemantics || hasAbsentPrecondition) {
@@ -337,13 +757,13 @@ function sameAddresses(actual, encoded) {
337
757
  *
338
758
  * @example
339
759
  * ```ts
340
- * declare const wire: PlanJsonV1 | PlanJsonV2 | PlanJsonV3;
760
+ * declare const wire: PlanJsonV1 | PlanJsonV2 | PlanJsonV3 | PlanJsonV4 | PlanJsonV5 | PlanJsonV6 | PlanJsonV7 | PlanJsonV8 | PlanJsonV9 | PlanJsonV10 | PlanJsonV11 | PlanJsonV12;
341
761
  * const plan = planFromJSON(wire);
342
762
  * console.log(plan.describe());
343
763
  * ```
344
764
  */
345
765
  export function planFromJSON(json) {
346
- const value = readRecord(json, 'planJson');
766
+ const value = { ...readRecord(json, 'planJson') };
347
767
  assertKeys(value, 'planJson', [
348
768
  'v',
349
769
  'kind',
@@ -353,10 +773,70 @@ export function planFromJSON(json) {
353
773
  'affected',
354
774
  'requiredSigners',
355
775
  ]);
356
- if (value.v !== 1 && value.v !== 2 && value.v !== 3) {
357
- invalid('planJson.v', value.v, 'the Plan wire version 1, 2, or 3');
776
+ if (value.v !== 1 &&
777
+ value.v !== 2 &&
778
+ value.v !== 3 &&
779
+ value.v !== 4 &&
780
+ value.v !== 5 &&
781
+ value.v !== 6 &&
782
+ value.v !== 7 &&
783
+ value.v !== 8 &&
784
+ value.v !== 9 &&
785
+ value.v !== 10 &&
786
+ value.v !== 11 &&
787
+ value.v !== 12) {
788
+ invalid('planJson.v', value.v, 'the Plan wire version 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, or 12');
358
789
  }
359
790
  const version = value.v;
791
+ if (version >= 4 && Array.isArray(value.preconditions)) {
792
+ value.preconditions = value.preconditions.map((entry) => {
793
+ const guard = readRecord(entry, 'precondition');
794
+ if (version >= 12 &&
795
+ (guard.kind === 'faction-treasury-buy' ||
796
+ guard.kind === 'faction-treasury-sell')) {
797
+ const keys = guard.kind === 'faction-treasury-buy'
798
+ ? ['floorRaw']
799
+ : ['atlasOutCapPerEpochRaw', 'epochLengthSeconds'];
800
+ const decoded = { ...guard };
801
+ for (const key of keys) {
802
+ const raw = guard[key];
803
+ const pattern = key === 'epochLengthSeconds'
804
+ ? /^(0|[1-9][0-9]*|-[1-9][0-9]*)$/
805
+ : /^(0|[1-9][0-9]*)$/;
806
+ if (typeof raw !== 'string' || !pattern.test(raw))
807
+ invalid(key, raw, 'a canonical decimal string');
808
+ decoded[key] = BigInt(raw);
809
+ }
810
+ return decoded;
811
+ }
812
+ if (version >= 11 && guard.kind === 'fleet-add-ship') {
813
+ for (const field of ['amount', 'maximumProfileDebit'])
814
+ if (typeof guard[field] !== 'string' ||
815
+ !/^(0|[1-9][0-9]*)$/.test(guard[field]))
816
+ invalid(field, guard[field], 'a canonical unsigned decimal string');
817
+ return {
818
+ ...guard,
819
+ amount: BigInt(guard.amount),
820
+ maximumProfileDebit: BigInt(guard.maximumProfileDebit),
821
+ };
822
+ }
823
+ if (version >= 10 && guard.kind === 'fleet-create') {
824
+ if (typeof guard.maximumProfileDebit !== 'string' ||
825
+ !/^(0|[1-9][0-9]*)$/.test(guard.maximumProfileDebit))
826
+ invalid('maximumProfileDebit', guard.maximumProfileDebit, 'a canonical unsigned decimal string');
827
+ return {
828
+ ...guard,
829
+ maximumProfileDebit: BigInt(guard.maximumProfileDebit),
830
+ };
831
+ }
832
+ if (guard.kind !== 'token-account')
833
+ return guard;
834
+ if (typeof guard.minimumBalance !== 'string' ||
835
+ !/^(0|[1-9][0-9]*)$/.test(guard.minimumBalance))
836
+ invalid('minimumBalance', guard.minimumBalance, 'a canonical unsigned decimal string');
837
+ return { ...guard, minimumBalance: BigInt(guard.minimumBalance) };
838
+ });
839
+ }
360
840
  const steps = readArray(value.steps, 'planJson.steps').map((candidate, index) => {
361
841
  const field = `planJson.steps[${String(index)}]`;
362
842
  const step = readRecord(candidate, field);
@@ -397,6 +877,38 @@ function assertPlan(value, index) {
397
877
  function combinedSummary(steps) {
398
878
  return steps.map((step) => step.describes).join(' ');
399
879
  }
880
+ function validateFactionGuardComposition(guards) {
881
+ const retained = new Map();
882
+ for (const guard of guards) {
883
+ if (guard.kind !== 'faction-treasury-buy' &&
884
+ guard.kind !== 'faction-treasury-sell' &&
885
+ guard.kind !== 'faction-epoch-meter')
886
+ continue;
887
+ const constraints = [
888
+ [
889
+ `${guard.kind === 'faction-epoch-meter' ? 'meter' : 'treasury'}:${guard.address}:identity`,
890
+ `${guard.game}:${String(guard.factionId)}`,
891
+ ],
892
+ ];
893
+ if (guard.kind !== 'faction-epoch-meter') {
894
+ constraints.push(guard.kind === 'faction-treasury-buy'
895
+ ? [
896
+ `${guard.address}:buy:${String(guard.cargoId)}`,
897
+ String(guard.floorRaw),
898
+ ]
899
+ : [
900
+ `${guard.address}:sell`,
901
+ `${String(guard.atlasOutCapPerEpochRaw)}:${String(guard.epochLengthSeconds)}`,
902
+ ]);
903
+ }
904
+ for (const [key, value] of constraints) {
905
+ const previous = retained.get(key);
906
+ if (previous !== undefined && previous !== value)
907
+ throw new SageSdkError('INCOMPATIBLE_PLAN_COMPOSITION', 'Faction Market Plans retain incompatible Treasury policy or shared account identity. Refresh the affected Markets and prepare compatible Plans, or use separate confirmed transactions.');
908
+ retained.set(key, value);
909
+ }
910
+ }
911
+ }
400
912
  /** Combines one or more Plans with deterministic associative flattening.
401
913
  *
402
914
  * Semantic validation is eager. Conflict indices are relative to the flattened
@@ -417,11 +929,13 @@ export function combinePlans(...plans) {
417
929
  plans.forEach(assertPlan);
418
930
  const steps = plans.flatMap((plan) => plan.steps);
419
931
  validatePlanComposition(steps);
932
+ const preconditions = plans.flatMap((plan) => plan.preconditions);
933
+ validateFactionGuardComposition(preconditions);
420
934
  return createPlan({
421
935
  kind: 'combined',
422
936
  summary: combinedSummary(steps),
423
937
  steps,
424
- preconditions: plans.flatMap((plan) => plan.preconditions),
938
+ preconditions,
425
939
  });
426
940
  }
427
941
  export { assemblePlan } from './assembly.js';