@aephia/atlas-kit 0.6.0-next.12 → 0.6.0-next.121
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 +3 -1
- package/dist/cargo/actions/deposit.d.ts +2 -2
- package/dist/cargo/actions/deposit.d.ts.map +1 -1
- package/dist/cargo/actions/deposit.js +28 -117
- package/dist/cargo/actions/deposit.js.map +1 -1
- package/dist/cargo/actions/index.d.ts +1 -1
- package/dist/cargo/actions/index.d.ts.map +1 -1
- package/dist/cargo/actions/index.js +28 -84
- package/dist/cargo/actions/index.js.map +1 -1
- package/dist/cargo/actions/wallet-context.d.ts +52 -3
- package/dist/cargo/actions/wallet-context.d.ts.map +1 -1
- package/dist/cargo/actions/wallet-context.js +118 -7
- package/dist/cargo/actions/wallet-context.js.map +1 -1
- package/dist/cargo/actions/wallet-token.d.ts +1 -6
- package/dist/cargo/actions/wallet-token.d.ts.map +1 -1
- package/dist/cargo/actions/wallet-token.js +0 -53
- package/dist/cargo/actions/wallet-token.js.map +1 -1
- package/dist/cargo/actions/withdrawal.d.ts +1 -1
- package/dist/cargo/actions/withdrawal.d.ts.map +1 -1
- package/dist/cargo/actions/withdrawal.js +39 -164
- package/dist/cargo/actions/withdrawal.js.map +1 -1
- package/dist/cargo/index.d.ts.map +1 -1
- package/dist/cargo/index.js +2 -10
- package/dist/cargo/index.js.map +1 -1
- package/dist/claim-stakes/actions/index.d.ts +14 -1
- package/dist/claim-stakes/actions/index.d.ts.map +1 -1
- package/dist/claim-stakes/actions/index.js +399 -592
- package/dist/claim-stakes/actions/index.js.map +1 -1
- package/dist/claim-stakes/index.d.ts +14 -0
- package/dist/claim-stakes/index.d.ts.map +1 -1
- package/dist/claim-stakes/index.js +25 -12
- package/dist/claim-stakes/index.js.map +1 -1
- package/dist/client/context.d.ts.map +1 -1
- package/dist/client/context.js +1 -1
- package/dist/client/context.js.map +1 -1
- package/dist/client/contracts.d.ts +16 -6
- package/dist/client/contracts.d.ts.map +1 -1
- package/dist/client/errors.d.ts +6 -2
- package/dist/client/errors.d.ts.map +1 -1
- package/dist/client/errors.js +31 -1
- package/dist/client/errors.js.map +1 -1
- package/dist/client/index.d.ts +35 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +35 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/rpc-subscription-provider.d.ts +35 -0
- package/dist/client/rpc-subscription-provider.d.ts.map +1 -0
- package/dist/client/rpc-subscription-provider.js +190 -0
- package/dist/client/rpc-subscription-provider.js.map +1 -0
- package/dist/combat/actions/index.d.ts +4 -4
- package/dist/combat/actions/index.d.ts.map +1 -1
- package/dist/combat/actions/index.js +207 -261
- package/dist/combat/actions/index.js.map +1 -1
- package/dist/combat/index.d.ts +13 -3
- package/dist/combat/index.d.ts.map +1 -1
- package/dist/combat/index.js +9 -16
- package/dist/combat/index.js.map +1 -1
- package/dist/crafting/actions/index.d.ts +12 -1
- package/dist/crafting/actions/index.d.ts.map +1 -1
- package/dist/crafting/actions/index.js +181 -303
- package/dist/crafting/actions/index.js.map +1 -1
- package/dist/crafting/index.d.ts +33 -3
- package/dist/crafting/index.d.ts.map +1 -1
- package/dist/crafting/index.js +49 -28
- package/dist/crafting/index.js.map +1 -1
- package/dist/factions/actions/index.d.ts +2 -1
- package/dist/factions/actions/index.d.ts.map +1 -1
- package/dist/factions/actions/index.js +6 -4
- package/dist/factions/actions/index.js.map +1 -1
- package/dist/factions/index.d.ts +1 -1
- package/dist/factions/index.d.ts.map +1 -1
- package/dist/factions/index.js +16 -18
- package/dist/factions/index.js.map +1 -1
- package/dist/factions/profile-faction.d.ts +20 -8
- package/dist/factions/profile-faction.d.ts.map +1 -1
- package/dist/factions/profile-faction.js +20 -8
- package/dist/factions/profile-faction.js.map +1 -1
- package/dist/fleets/actions/add-ship.d.ts +35 -0
- package/dist/fleets/actions/add-ship.d.ts.map +1 -0
- package/dist/fleets/actions/add-ship.js +120 -0
- package/dist/fleets/actions/add-ship.js.map +1 -0
- package/dist/fleets/actions/create-fleet.d.ts +36 -0
- package/dist/fleets/actions/create-fleet.d.ts.map +1 -0
- package/dist/fleets/actions/create-fleet.js +108 -0
- package/dist/fleets/actions/create-fleet.js.map +1 -0
- package/dist/fleets/actions/crew-transfer.d.ts +41 -0
- package/dist/fleets/actions/crew-transfer.d.ts.map +1 -0
- package/dist/fleets/actions/crew-transfer.js +94 -0
- package/dist/fleets/actions/crew-transfer.js.map +1 -0
- package/dist/fleets/actions/dock-bounds.d.ts +38 -0
- package/dist/fleets/actions/dock-bounds.d.ts.map +1 -0
- package/dist/fleets/actions/dock-bounds.js +46 -0
- package/dist/fleets/actions/dock-bounds.js.map +1 -0
- package/dist/fleets/actions/index.d.ts +64 -24
- package/dist/fleets/actions/index.d.ts.map +1 -1
- package/dist/fleets/actions/index.js +385 -334
- package/dist/fleets/actions/index.js.map +1 -1
- package/dist/fleets/actions/respawn.d.ts +38 -0
- package/dist/fleets/actions/respawn.d.ts.map +1 -0
- package/dist/fleets/actions/respawn.js +93 -0
- package/dist/fleets/actions/respawn.js.map +1 -0
- package/dist/fleets/actions/ship-import.d.ts +1 -1
- package/dist/fleets/actions/ship-import.d.ts.map +1 -1
- package/dist/fleets/actions/ship-import.js +67 -91
- package/dist/fleets/actions/ship-import.js.map +1 -1
- package/dist/fleets/cooldown.d.ts +44 -0
- package/dist/fleets/cooldown.d.ts.map +1 -0
- package/dist/fleets/cooldown.js +43 -0
- package/dist/fleets/cooldown.js.map +1 -0
- package/dist/fleets/coordinate-warp-estimate.d.ts +70 -0
- package/dist/fleets/coordinate-warp-estimate.d.ts.map +1 -0
- package/dist/fleets/coordinate-warp-estimate.js +46 -0
- package/dist/fleets/coordinate-warp-estimate.js.map +1 -0
- package/dist/fleets/index.d.ts +35 -0
- package/dist/fleets/index.d.ts.map +1 -1
- package/dist/fleets/index.js +54 -12
- package/dist/fleets/index.js.map +1 -1
- package/dist/fleets/movement-arithmetic.d.ts +21 -0
- package/dist/fleets/movement-arithmetic.d.ts.map +1 -0
- package/dist/fleets/movement-arithmetic.js +41 -0
- package/dist/fleets/movement-arithmetic.js.map +1 -0
- package/dist/fleets/subwarp-estimate.d.ts +70 -0
- package/dist/fleets/subwarp-estimate.d.ts.map +1 -0
- package/dist/fleets/subwarp-estimate.js +38 -0
- package/dist/fleets/subwarp-estimate.js.map +1 -0
- package/dist/fleets/travel-profile.d.ts +102 -0
- package/dist/fleets/travel-profile.d.ts.map +1 -0
- package/dist/fleets/travel-profile.js +120 -0
- package/dist/fleets/travel-profile.js.map +1 -0
- package/dist/fleets/warp-lane-estimate.d.ts +59 -0
- package/dist/fleets/warp-lane-estimate.d.ts.map +1 -0
- package/dist/fleets/warp-lane-estimate.js +36 -0
- package/dist/fleets/warp-lane-estimate.js.map +1 -0
- package/dist/fleets/warp-lane-policy.d.ts +68 -0
- package/dist/fleets/warp-lane-policy.d.ts.map +1 -0
- package/dist/fleets/warp-lane-policy.js +91 -0
- package/dist/fleets/warp-lane-policy.js.map +1 -0
- package/dist/fleets/warp-lane-toll.d.ts +55 -0
- package/dist/fleets/warp-lane-toll.d.ts.map +1 -0
- package/dist/fleets/warp-lane-toll.js +79 -0
- package/dist/fleets/warp-lane-toll.js.map +1 -0
- package/dist/identity/actions/create-profile.d.ts +1 -1
- package/dist/identity/actions/create-profile.d.ts.map +1 -1
- package/dist/identity/actions/create-profile.js +2 -2
- package/dist/identity/actions/create-profile.js.map +1 -1
- package/dist/identity/actions/index.d.ts +4 -4
- package/dist/identity/actions/index.d.ts.map +1 -1
- package/dist/identity/actions/index.js +51 -29
- package/dist/identity/actions/index.js.map +1 -1
- package/dist/identity/index.d.ts +5 -2
- package/dist/identity/index.d.ts.map +1 -1
- package/dist/identity/index.js +6 -12
- package/dist/identity/index.js.map +1 -1
- package/dist/identity/research-state.d.ts +60 -0
- package/dist/identity/research-state.d.ts.map +1 -0
- package/dist/identity/research-state.js +68 -0
- package/dist/identity/research-state.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -3
- package/dist/index.js.map +1 -1
- package/dist/internal/c4/account-decoding.d.ts +49 -0
- package/dist/internal/c4/account-decoding.d.ts.map +1 -0
- package/dist/internal/c4/account-decoding.js +74 -0
- package/dist/internal/c4/account-decoding.js.map +1 -0
- package/dist/internal/c4/cargo-bytes-config.d.ts +7 -0
- package/dist/internal/c4/cargo-bytes-config.d.ts.map +1 -0
- package/dist/internal/c4/cargo-bytes-config.js +19 -0
- package/dist/internal/c4/cargo-bytes-config.js.map +1 -0
- package/dist/internal/c4/cargo-pod.d.ts +15 -0
- package/dist/internal/c4/cargo-pod.d.ts.map +1 -0
- package/dist/internal/c4/cargo-pod.js +13 -0
- package/dist/internal/c4/cargo-pod.js.map +1 -0
- package/dist/internal/c4/character-modifier.d.ts +1 -1
- package/dist/internal/c4/character-modifier.d.ts.map +1 -1
- package/dist/internal/c4/character-registration.d.ts +2 -0
- package/dist/internal/c4/character-registration.d.ts.map +1 -1
- package/dist/internal/c4/character-registration.js +2 -0
- package/dist/internal/c4/character-registration.js.map +1 -1
- package/dist/internal/c4/character.d.ts +157 -0
- package/dist/internal/c4/character.d.ts.map +1 -0
- package/dist/internal/c4/character.js +64 -0
- package/dist/internal/c4/character.js.map +1 -0
- package/dist/internal/c4/claim-stake-building-definitions.d.ts.map +1 -1
- package/dist/internal/c4/claim-stake-building-definitions.js +2 -1
- package/dist/internal/c4/claim-stake-building-definitions.js.map +1 -1
- package/dist/internal/c4/claim-stake-configuration.d.ts.map +1 -1
- package/dist/internal/c4/claim-stake-configuration.js +5 -36
- package/dist/internal/c4/claim-stake-configuration.js.map +1 -1
- package/dist/internal/c4/claim-stake-definitions.d.ts +4 -4
- package/dist/internal/c4/claim-stake-definitions.d.ts.map +1 -1
- package/dist/internal/c4/claim-stake-definitions.js +2 -1
- package/dist/internal/c4/claim-stake-definitions.js.map +1 -1
- package/dist/internal/c4/claim-stake.d.ts +4 -27
- package/dist/internal/c4/claim-stake.d.ts.map +1 -1
- package/dist/internal/c4/claim-stake.js +38 -83
- package/dist/internal/c4/claim-stake.js.map +1 -1
- package/dist/internal/c4/combat.d.ts +1 -82
- package/dist/internal/c4/combat.d.ts.map +1 -1
- package/dist/internal/c4/combat.js +16 -213
- package/dist/internal/c4/combat.js.map +1 -1
- package/dist/internal/c4/crafting-process-codec.d.ts +13 -0
- package/dist/internal/c4/crafting-process-codec.d.ts.map +1 -0
- package/dist/internal/c4/crafting-process-codec.js +34 -0
- package/dist/internal/c4/crafting-process-codec.js.map +1 -0
- package/dist/internal/c4/crafting.d.ts +25 -33
- package/dist/internal/c4/crafting.d.ts.map +1 -1
- package/dist/internal/c4/crafting.js +76 -127
- package/dist/internal/c4/crafting.js.map +1 -1
- package/dist/internal/c4/currency-cache.d.ts +6 -0
- package/dist/internal/c4/currency-cache.d.ts.map +1 -0
- package/dist/internal/c4/currency-cache.js +27 -0
- package/dist/internal/c4/currency-cache.js.map +1 -0
- package/dist/internal/c4/discriminators.d.ts +81 -0
- package/dist/internal/c4/discriminators.d.ts.map +1 -0
- package/dist/internal/c4/discriminators.js +166 -0
- package/dist/internal/c4/discriminators.js.map +1 -0
- package/dist/internal/c4/docking-funding.d.ts +4 -0
- package/dist/internal/c4/docking-funding.d.ts.map +1 -0
- package/dist/internal/c4/docking-funding.js +11 -0
- package/dist/internal/c4/docking-funding.js.map +1 -0
- package/dist/internal/c4/faction-epoch-meter.d.ts +10 -0
- package/dist/internal/c4/faction-epoch-meter.d.ts.map +1 -0
- package/dist/internal/c4/faction-epoch-meter.js +26 -0
- package/dist/internal/c4/faction-epoch-meter.js.map +1 -0
- package/dist/internal/c4/faction-treasury.d.ts +23 -0
- package/dist/internal/c4/faction-treasury.d.ts.map +1 -0
- package/dist/internal/c4/faction-treasury.js +41 -0
- package/dist/internal/c4/faction-treasury.js.map +1 -0
- package/dist/internal/c4/faction.d.ts +21 -0
- package/dist/internal/c4/faction.d.ts.map +1 -0
- package/dist/internal/c4/faction.js +23 -0
- package/dist/internal/c4/faction.js.map +1 -0
- package/dist/internal/c4/factions.d.ts +13 -57
- package/dist/internal/c4/factions.d.ts.map +1 -1
- package/dist/internal/c4/factions.js +79 -222
- package/dist/internal/c4/factions.js.map +1 -1
- package/dist/internal/c4/fleet-arrival.d.ts +28 -0
- package/dist/internal/c4/fleet-arrival.d.ts.map +1 -0
- package/dist/internal/c4/fleet-arrival.js +42 -0
- package/dist/internal/c4/fleet-arrival.js.map +1 -0
- package/dist/internal/c4/fleet-creation.d.ts +7 -0
- package/dist/internal/c4/fleet-creation.d.ts.map +1 -0
- package/dist/internal/c4/fleet-creation.js +171 -0
- package/dist/internal/c4/fleet-creation.js.map +1 -0
- package/dist/internal/c4/fleet-crew-binding.d.ts +9 -0
- package/dist/internal/c4/fleet-crew-binding.d.ts.map +1 -1
- package/dist/internal/c4/fleet-crew-binding.js +31 -44
- package/dist/internal/c4/fleet-crew-binding.js.map +1 -1
- package/dist/internal/c4/fleet-respawn.d.ts +17 -0
- package/dist/internal/c4/fleet-respawn.d.ts.map +1 -0
- package/dist/internal/c4/fleet-respawn.js +62 -0
- package/dist/internal/c4/fleet-respawn.js.map +1 -0
- package/dist/internal/c4/fleet-ship-assembly.d.ts +11 -0
- package/dist/internal/c4/fleet-ship-assembly.d.ts.map +1 -0
- package/dist/internal/c4/fleet-ship-assembly.js +44 -0
- package/dist/internal/c4/fleet-ship-assembly.js.map +1 -0
- package/dist/internal/c4/fleet.d.ts +48 -19
- package/dist/internal/c4/fleet.d.ts.map +1 -1
- package/dist/internal/c4/fleet.js +50 -87
- package/dist/internal/c4/fleet.js.map +1 -1
- package/dist/internal/c4/game-definition-layout.d.ts +2 -0
- package/dist/internal/c4/game-definition-layout.d.ts.map +1 -1
- package/dist/internal/c4/game-definition-layout.js +4 -0
- package/dist/internal/c4/game-definition-layout.js.map +1 -1
- package/dist/internal/c4/game.d.ts +76 -30
- package/dist/internal/c4/game.d.ts.map +1 -1
- package/dist/internal/c4/game.js +173 -124
- package/dist/internal/c4/game.js.map +1 -1
- package/dist/internal/c4/identity.d.ts +3 -152
- package/dist/internal/c4/identity.d.ts.map +1 -1
- package/dist/internal/c4/identity.js +19 -126
- package/dist/internal/c4/identity.js.map +1 -1
- package/dist/internal/c4/local-market-order.d.ts +29 -0
- package/dist/internal/c4/local-market-order.d.ts.map +1 -0
- package/dist/internal/c4/local-market-order.js +46 -0
- package/dist/internal/c4/local-market-order.js.map +1 -0
- package/dist/internal/c4/loot-layout.js +1 -1
- package/dist/internal/c4/loot-layout.js.map +1 -1
- package/dist/internal/c4/loot.d.ts +87 -0
- package/dist/internal/c4/loot.d.ts.map +1 -0
- package/dist/internal/c4/loot.js +108 -0
- package/dist/internal/c4/loot.js.map +1 -0
- package/dist/internal/c4/loyalty.d.ts +0 -27
- package/dist/internal/c4/loyalty.d.ts.map +1 -1
- package/dist/internal/c4/loyalty.js +32 -160
- package/dist/internal/c4/loyalty.js.map +1 -1
- package/dist/internal/c4/market.d.ts +2 -38
- package/dist/internal/c4/market.d.ts.map +1 -1
- package/dist/internal/c4/market.js +26 -120
- package/dist/internal/c4/market.js.map +1 -1
- package/dist/internal/c4/mining-instructions.d.ts +2 -0
- package/dist/internal/c4/mining-instructions.d.ts.map +1 -0
- package/dist/internal/c4/mining-instructions.js +3 -0
- package/dist/internal/c4/mining-instructions.js.map +1 -0
- package/dist/internal/c4/open-signal.d.ts +8 -0
- package/dist/internal/c4/open-signal.d.ts.map +1 -0
- package/dist/internal/c4/open-signal.js +37 -0
- package/dist/internal/c4/open-signal.js.map +1 -0
- package/dist/internal/c4/pda.d.ts +31 -0
- package/dist/internal/c4/pda.d.ts.map +1 -1
- package/dist/internal/c4/pda.js +60 -17
- package/dist/internal/c4/pda.js.map +1 -1
- package/dist/internal/c4/profile-faction.d.ts +2 -1
- package/dist/internal/c4/profile-faction.d.ts.map +1 -1
- package/dist/internal/c4/profile-faction.js +36 -72
- package/dist/internal/c4/profile-faction.js.map +1 -1
- package/dist/internal/c4/profile-permissions.d.ts +1 -1
- package/dist/internal/c4/profile-permissions.d.ts.map +1 -1
- package/dist/internal/c4/profile-permissions.js +2 -1
- package/dist/internal/c4/profile-permissions.js.map +1 -1
- package/dist/internal/c4/region-geometry.d.ts +8 -0
- package/dist/internal/c4/region-geometry.d.ts.map +1 -0
- package/dist/internal/c4/region-geometry.js +43 -0
- package/dist/internal/c4/region-geometry.js.map +1 -0
- package/dist/internal/c4/rewards.d.ts +1 -61
- package/dist/internal/c4/rewards.d.ts.map +1 -1
- package/dist/internal/c4/rewards.js +23 -203
- package/dist/internal/c4/rewards.js.map +1 -1
- package/dist/internal/c4/runtime-bindings.d.ts +4 -0
- package/dist/internal/c4/runtime-bindings.d.ts.map +1 -0
- package/dist/internal/c4/runtime-bindings.js +4 -0
- package/dist/internal/c4/runtime-bindings.js.map +1 -0
- package/dist/internal/c4/scan-detection-codecs.d.ts +3 -0
- package/dist/internal/c4/scan-detection-codecs.d.ts.map +1 -0
- package/dist/internal/c4/scan-detection-codecs.js +3 -0
- package/dist/internal/c4/scan-detection-codecs.js.map +1 -0
- package/dist/internal/c4/scan-lifecycle.d.ts +306 -0
- package/dist/internal/c4/scan-lifecycle.d.ts.map +1 -0
- package/dist/internal/c4/scan-lifecycle.js +235 -0
- package/dist/internal/c4/scan-lifecycle.js.map +1 -0
- package/dist/internal/c4/scanning.d.ts +1 -28
- package/dist/internal/c4/scanning.d.ts.map +1 -1
- package/dist/internal/c4/scanning.js +32 -103
- package/dist/internal/c4/scanning.js.map +1 -1
- package/dist/internal/c4/ship-import.d.ts +4 -0
- package/dist/internal/c4/ship-import.d.ts.map +1 -0
- package/dist/internal/c4/ship-import.js +13 -0
- package/dist/internal/c4/ship-import.js.map +1 -0
- package/dist/internal/c4/ship-stats.d.ts.map +1 -1
- package/dist/internal/c4/ship-stats.js +45 -43
- package/dist/internal/c4/ship-stats.js.map +1 -1
- package/dist/internal/c4/starbase.d.ts +0 -32
- package/dist/internal/c4/starbase.d.ts.map +1 -1
- package/dist/internal/c4/starbase.js +26 -136
- package/dist/internal/c4/starbase.js.map +1 -1
- package/dist/internal/c4/wallet-cargo-cache.js +2 -1
- package/dist/internal/c4/wallet-cargo-cache.js.map +1 -1
- package/dist/internal/c4/world.d.ts +36 -7
- package/dist/internal/c4/world.d.ts.map +1 -1
- package/dist/internal/c4/world.js +87 -129
- package/dist/internal/c4/world.js.map +1 -1
- package/dist/internal/cargo.d.ts +2 -0
- package/dist/internal/cargo.d.ts.map +1 -1
- package/dist/internal/cargo.js +8 -0
- package/dist/internal/cargo.js.map +1 -1
- package/dist/internal/fleet.d.ts +1 -0
- package/dist/internal/fleet.d.ts.map +1 -1
- package/dist/internal/fleet.js +3 -1
- package/dist/internal/fleet.js.map +1 -1
- package/dist/internal/loyalty-atlas-bank-state.d.ts +16 -0
- package/dist/internal/loyalty-atlas-bank-state.d.ts.map +1 -0
- package/dist/internal/loyalty-atlas-bank-state.js +10 -0
- package/dist/internal/loyalty-atlas-bank-state.js.map +1 -0
- package/dist/internal/planning/account-state.d.ts +6 -0
- package/dist/internal/planning/account-state.d.ts.map +1 -1
- package/dist/internal/planning/account-state.js +13 -0
- package/dist/internal/planning/account-state.js.map +1 -1
- package/dist/internal/planning/action-runtime.d.ts +38 -0
- package/dist/internal/planning/action-runtime.d.ts.map +1 -0
- package/dist/internal/planning/action-runtime.js +63 -0
- package/dist/internal/planning/action-runtime.js.map +1 -0
- package/dist/internal/planning/arrival-guards.d.ts +19 -0
- package/dist/internal/planning/arrival-guards.d.ts.map +1 -0
- package/dist/internal/planning/arrival-guards.js +172 -0
- package/dist/internal/planning/arrival-guards.js.map +1 -0
- package/dist/internal/planning/authorization-adapter.d.ts +45 -37
- package/dist/internal/planning/authorization-adapter.d.ts.map +1 -1
- package/dist/internal/planning/authorization-adapter.js +169 -81
- package/dist/internal/planning/authorization-adapter.js.map +1 -1
- package/dist/internal/planning/character-registration-guard.d.ts +4 -0
- package/dist/internal/planning/character-registration-guard.d.ts.map +1 -0
- package/dist/internal/planning/character-registration-guard.js +59 -0
- package/dist/internal/planning/character-registration-guard.js.map +1 -0
- package/dist/internal/planning/character-registration.d.ts +23 -0
- package/dist/internal/planning/character-registration.d.ts.map +1 -0
- package/dist/internal/planning/character-registration.js +87 -0
- package/dist/internal/planning/character-registration.js.map +1 -0
- package/dist/internal/planning/currency-cache-guard.d.ts +4 -0
- package/dist/internal/planning/currency-cache-guard.d.ts.map +1 -0
- package/dist/internal/planning/currency-cache-guard.js +33 -0
- package/dist/internal/planning/currency-cache-guard.js.map +1 -0
- package/dist/internal/planning/democracy-history.d.ts +50 -0
- package/dist/internal/planning/democracy-history.d.ts.map +1 -0
- package/dist/internal/planning/democracy-history.js +189 -0
- package/dist/internal/planning/democracy-history.js.map +1 -0
- package/dist/internal/planning/direct-options.d.ts +17 -0
- package/dist/internal/planning/direct-options.d.ts.map +1 -0
- package/dist/internal/planning/direct-options.js +43 -0
- package/dist/internal/planning/direct-options.js.map +1 -0
- package/dist/internal/planning/faction-enrollment.d.ts +0 -4
- package/dist/internal/planning/faction-enrollment.d.ts.map +1 -1
- package/dist/internal/planning/faction-enrollment.js +1 -31
- package/dist/internal/planning/faction-enrollment.js.map +1 -1
- package/dist/internal/planning/faction-trade-guards.d.ts +30 -0
- package/dist/internal/planning/faction-trade-guards.d.ts.map +1 -0
- package/dist/internal/planning/faction-trade-guards.js +15 -0
- package/dist/internal/planning/faction-trade-guards.js.map +1 -0
- package/dist/internal/planning/faction-trade-state.d.ts +16 -0
- package/dist/internal/planning/faction-trade-state.d.ts.map +1 -0
- package/dist/internal/planning/faction-trade-state.js +43 -0
- package/dist/internal/planning/faction-trade-state.js.map +1 -0
- package/dist/internal/planning/fleet-arrival.d.ts +40 -0
- package/dist/internal/planning/fleet-arrival.d.ts.map +1 -0
- package/dist/internal/planning/fleet-arrival.js +107 -0
- package/dist/internal/planning/fleet-arrival.js.map +1 -0
- package/dist/internal/planning/fleet-attack-xp.d.ts +20 -0
- package/dist/internal/planning/fleet-attack-xp.d.ts.map +1 -0
- package/dist/internal/planning/fleet-attack-xp.js +104 -0
- package/dist/internal/planning/fleet-attack-xp.js.map +1 -0
- package/dist/internal/planning/fleet-creation.d.ts +30 -0
- package/dist/internal/planning/fleet-creation.d.ts.map +1 -0
- package/dist/internal/planning/fleet-creation.js +89 -0
- package/dist/internal/planning/fleet-creation.js.map +1 -0
- package/dist/internal/planning/fleet-crew-guard.d.ts +28 -0
- package/dist/internal/planning/fleet-crew-guard.d.ts.map +1 -0
- package/dist/internal/planning/fleet-crew-guard.js +48 -0
- package/dist/internal/planning/fleet-crew-guard.js.map +1 -0
- package/dist/internal/planning/fleet-crew-transfer.d.ts +7 -0
- package/dist/internal/planning/fleet-crew-transfer.d.ts.map +1 -0
- package/dist/internal/planning/fleet-crew-transfer.js +123 -0
- package/dist/internal/planning/fleet-crew-transfer.js.map +1 -0
- package/dist/internal/planning/fleet-dock-funding-guard.d.ts +42 -0
- package/dist/internal/planning/fleet-dock-funding-guard.d.ts.map +1 -0
- package/dist/internal/planning/fleet-dock-funding-guard.js +209 -0
- package/dist/internal/planning/fleet-dock-funding-guard.js.map +1 -0
- package/dist/internal/planning/fleet-dock-funding.d.ts +9 -0
- package/dist/internal/planning/fleet-dock-funding.d.ts.map +1 -0
- package/dist/internal/planning/fleet-dock-funding.js +154 -0
- package/dist/internal/planning/fleet-dock-funding.js.map +1 -0
- package/dist/internal/planning/fleet-docking-guard.d.ts +4 -0
- package/dist/internal/planning/fleet-docking-guard.d.ts.map +1 -0
- package/dist/internal/planning/fleet-docking-guard.js +43 -0
- package/dist/internal/planning/fleet-docking-guard.js.map +1 -0
- package/dist/internal/planning/fleet-docking.d.ts +10 -0
- package/dist/internal/planning/fleet-docking.d.ts.map +1 -0
- package/dist/internal/planning/fleet-docking.js +71 -0
- package/dist/internal/planning/fleet-docking.js.map +1 -0
- package/dist/internal/planning/fleet-respawn.d.ts +28 -0
- package/dist/internal/planning/fleet-respawn.d.ts.map +1 -0
- package/dist/internal/planning/fleet-respawn.js +164 -0
- package/dist/internal/planning/fleet-respawn.js.map +1 -0
- package/dist/internal/planning/fleet-ship-assembly.d.ts +36 -0
- package/dist/internal/planning/fleet-ship-assembly.d.ts.map +1 -0
- package/dist/internal/planning/fleet-ship-assembly.js +118 -0
- package/dist/internal/planning/fleet-ship-assembly.js.map +1 -0
- package/dist/internal/planning/fleet-state.d.ts +25 -0
- package/dist/internal/planning/fleet-state.d.ts.map +1 -0
- package/dist/internal/planning/fleet-state.js +28 -0
- package/dist/internal/planning/fleet-state.js.map +1 -0
- package/dist/internal/planning/governance-fees.d.ts +64 -0
- package/dist/internal/planning/governance-fees.d.ts.map +1 -0
- package/dist/internal/planning/governance-fees.js +231 -0
- package/dist/internal/planning/governance-fees.js.map +1 -0
- package/dist/internal/planning/local-market-order-funding.d.ts +8 -0
- package/dist/internal/planning/local-market-order-funding.d.ts.map +1 -0
- package/dist/internal/planning/local-market-order-funding.js +128 -0
- package/dist/internal/planning/local-market-order-funding.js.map +1 -0
- package/dist/internal/planning/local-market-order.d.ts +40 -0
- package/dist/internal/planning/local-market-order.d.ts.map +1 -0
- package/dist/internal/planning/local-market-order.js +139 -0
- package/dist/internal/planning/local-market-order.js.map +1 -0
- package/dist/internal/planning/mining-stop.d.ts +14 -0
- package/dist/internal/planning/mining-stop.d.ts.map +1 -0
- package/dist/internal/planning/mining-stop.js +42 -0
- package/dist/internal/planning/mining-stop.js.map +1 -0
- package/dist/internal/planning/movement-character.d.ts +7 -0
- package/dist/internal/planning/movement-character.d.ts.map +1 -0
- package/dist/internal/planning/movement-character.js +41 -0
- package/dist/internal/planning/movement-character.js.map +1 -0
- package/dist/internal/planning/movement-xp-guard.d.ts +4 -0
- package/dist/internal/planning/movement-xp-guard.d.ts.map +1 -0
- package/dist/internal/planning/movement-xp-guard.js +104 -0
- package/dist/internal/planning/movement-xp-guard.js.map +1 -0
- package/dist/internal/planning/open-signal-guard.d.ts +3 -0
- package/dist/internal/planning/open-signal-guard.d.ts.map +1 -0
- package/dist/internal/planning/open-signal-guard.js +32 -0
- package/dist/internal/planning/open-signal-guard.js.map +1 -0
- package/dist/internal/planning/open-signal.d.ts +31 -0
- package/dist/internal/planning/open-signal.d.ts.map +1 -0
- package/dist/internal/planning/open-signal.js +85 -0
- package/dist/internal/planning/open-signal.js.map +1 -0
- package/dist/internal/planning/original-token.d.ts +40 -0
- package/dist/internal/planning/original-token.d.ts.map +1 -0
- package/dist/internal/planning/original-token.js +112 -0
- package/dist/internal/planning/original-token.js.map +1 -0
- package/dist/internal/planning/own-starbase-facts.d.ts +33 -0
- package/dist/internal/planning/own-starbase-facts.d.ts.map +1 -0
- package/dist/internal/planning/own-starbase-facts.js +49 -0
- package/dist/internal/planning/own-starbase-facts.js.map +1 -0
- package/dist/internal/planning/plan-fields.d.ts +60 -0
- package/dist/internal/planning/plan-fields.d.ts.map +1 -0
- package/dist/internal/planning/plan-fields.js +159 -0
- package/dist/internal/planning/plan-fields.js.map +1 -0
- package/dist/internal/planning/plan-guards.d.ts +4 -0
- package/dist/internal/planning/plan-guards.d.ts.map +1 -0
- package/dist/internal/planning/plan-guards.js +168 -0
- package/dist/internal/planning/plan-guards.js.map +1 -0
- package/dist/internal/planning/profile-key.d.ts +13 -0
- package/dist/internal/planning/profile-key.d.ts.map +1 -0
- package/dist/internal/planning/profile-key.js +20 -0
- package/dist/internal/planning/profile-key.js.map +1 -0
- package/dist/internal/planning/recipe-state.d.ts +6 -0
- package/dist/internal/planning/recipe-state.d.ts.map +1 -0
- package/dist/internal/planning/recipe-state.js +20 -0
- package/dist/internal/planning/recipe-state.js.map +1 -0
- package/dist/internal/planning/rent.d.ts +19 -0
- package/dist/internal/planning/rent.d.ts.map +1 -0
- package/dist/internal/planning/rent.js +35 -0
- package/dist/internal/planning/rent.js.map +1 -0
- package/dist/internal/planning/respawn-guards.d.ts +3 -0
- package/dist/internal/planning/respawn-guards.d.ts.map +1 -0
- package/dist/internal/planning/respawn-guards.js +42 -0
- package/dist/internal/planning/respawn-guards.js.map +1 -0
- package/dist/internal/planning/runtime-guards.d.ts +41 -0
- package/dist/internal/planning/runtime-guards.d.ts.map +1 -0
- package/dist/internal/planning/runtime-guards.js +640 -0
- package/dist/internal/planning/runtime-guards.js.map +1 -0
- package/dist/internal/planning/scan-completion-guard.d.ts +43 -0
- package/dist/internal/planning/scan-completion-guard.d.ts.map +1 -0
- package/dist/internal/planning/scan-completion-guard.js +95 -0
- package/dist/internal/planning/scan-completion-guard.js.map +1 -0
- package/dist/internal/planning/scan-completion.d.ts +20 -0
- package/dist/internal/planning/scan-completion.d.ts.map +1 -0
- package/dist/internal/planning/scan-completion.js +197 -0
- package/dist/internal/planning/scan-completion.js.map +1 -0
- package/dist/internal/planning/scan-detect-guard.d.ts +34 -0
- package/dist/internal/planning/scan-detect-guard.d.ts.map +1 -0
- package/dist/internal/planning/scan-detect-guard.js +77 -0
- package/dist/internal/planning/scan-detect-guard.js.map +1 -0
- package/dist/internal/planning/scan-detect.d.ts +24 -0
- package/dist/internal/planning/scan-detect.d.ts.map +1 -0
- package/dist/internal/planning/scan-detect.js +245 -0
- package/dist/internal/planning/scan-detect.js.map +1 -0
- package/dist/internal/planning/scan-input.d.ts +9 -0
- package/dist/internal/planning/scan-input.d.ts.map +1 -0
- package/dist/internal/planning/scan-input.js +58 -0
- package/dist/internal/planning/scan-input.js.map +1 -0
- package/dist/internal/planning/ship-import-funding.d.ts +22 -0
- package/dist/internal/planning/ship-import-funding.d.ts.map +1 -0
- package/dist/internal/planning/ship-import-funding.js +53 -0
- package/dist/internal/planning/ship-import-funding.js.map +1 -0
- package/dist/internal/planning/ship-token.d.ts +1 -6
- package/dist/internal/planning/ship-token.d.ts.map +1 -1
- package/dist/internal/planning/ship-token.js +2 -41
- package/dist/internal/planning/ship-token.js.map +1 -1
- package/dist/internal/planning/starbase-player-owner.d.ts +21 -0
- package/dist/internal/planning/starbase-player-owner.d.ts.map +1 -0
- package/dist/internal/planning/starbase-player-owner.js +17 -0
- package/dist/internal/planning/starbase-player-owner.js.map +1 -0
- package/dist/internal/planning/starbase-system-guard.d.ts +6 -0
- package/dist/internal/planning/starbase-system-guard.d.ts.map +1 -0
- package/dist/internal/planning/starbase-system-guard.js +94 -0
- package/dist/internal/planning/starbase-system-guard.js.map +1 -0
- package/dist/internal/planning/starbase-system.d.ts +15 -0
- package/dist/internal/planning/starbase-system.d.ts.map +1 -0
- package/dist/internal/planning/starbase-system.js +25 -0
- package/dist/internal/planning/starbase-system.js.map +1 -0
- package/dist/internal/planning/token-mint.d.ts +4 -0
- package/dist/internal/planning/token-mint.d.ts.map +1 -0
- package/dist/internal/planning/token-mint.js +16 -0
- package/dist/internal/planning/token-mint.js.map +1 -0
- package/dist/internal/planning/trade-faction-market.d.ts +20 -0
- package/dist/internal/planning/trade-faction-market.d.ts.map +1 -0
- package/dist/internal/planning/trade-faction-market.js +56 -0
- package/dist/internal/planning/trade-faction-market.js.map +1 -0
- package/dist/internal/planning/wallet-starbase.d.ts +34 -0
- package/dist/internal/planning/wallet-starbase.d.ts.map +1 -0
- package/dist/internal/planning/wallet-starbase.js +39 -0
- package/dist/internal/planning/wallet-starbase.js.map +1 -0
- package/dist/internal/planning/xp-runtime.d.ts +36 -0
- package/dist/internal/planning/xp-runtime.d.ts.map +1 -0
- package/dist/internal/planning/xp-runtime.js +117 -0
- package/dist/internal/planning/xp-runtime.js.map +1 -0
- package/dist/internal/read-meta.d.ts +12 -0
- package/dist/internal/read-meta.d.ts.map +1 -1
- package/dist/internal/read-meta.js +10 -0
- package/dist/internal/read-meta.js.map +1 -1
- package/dist/internal/system-program.d.ts +4 -0
- package/dist/internal/system-program.d.ts.map +1 -0
- package/dist/internal/system-program.js +3 -0
- package/dist/internal/system-program.js.map +1 -0
- package/dist/loyalty/actions/index.d.ts +1 -1
- package/dist/loyalty/actions/index.d.ts.map +1 -1
- package/dist/loyalty/actions/index.js +15 -45
- package/dist/loyalty/actions/index.js.map +1 -1
- package/dist/loyalty/index.d.ts.map +1 -1
- package/dist/loyalty/index.js +6 -18
- package/dist/loyalty/index.js.map +1 -1
- package/dist/markets/actions/index.d.ts +62 -4
- package/dist/markets/actions/index.d.ts.map +1 -1
- package/dist/markets/actions/index.js +230 -178
- package/dist/markets/actions/index.js.map +1 -1
- package/dist/markets/actions/trade-faction-market.d.ts +43 -0
- package/dist/markets/actions/trade-faction-market.d.ts.map +1 -0
- package/dist/markets/actions/trade-faction-market.js +277 -0
- package/dist/markets/actions/trade-faction-market.js.map +1 -0
- package/dist/markets/index.d.ts +38 -7
- package/dist/markets/index.d.ts.map +1 -1
- package/dist/markets/index.js +59 -20
- package/dist/markets/index.js.map +1 -1
- package/dist/mining/actions/index.d.ts +87 -0
- package/dist/mining/actions/index.d.ts.map +1 -0
- package/dist/mining/actions/index.js +319 -0
- package/dist/mining/actions/index.js.map +1 -0
- package/dist/mining/estimate.d.ts +114 -0
- package/dist/mining/estimate.d.ts.map +1 -0
- package/dist/mining/estimate.js +127 -0
- package/dist/mining/estimate.js.map +1 -0
- package/dist/mining/index.d.ts +9 -2
- package/dist/mining/index.d.ts.map +1 -1
- package/dist/mining/index.js +10 -13
- package/dist/mining/index.js.map +1 -1
- package/dist/mining/profile.d.ts +82 -0
- package/dist/mining/profile.d.ts.map +1 -0
- package/dist/mining/profile.js +109 -0
- package/dist/mining/profile.js.map +1 -0
- package/dist/planning/assembly.d.ts +6 -1
- package/dist/planning/assembly.d.ts.map +1 -1
- package/dist/planning/assembly.js +12 -8
- package/dist/planning/assembly.js.map +1 -1
- package/dist/planning/execution.d.ts +19 -3
- package/dist/planning/execution.d.ts.map +1 -1
- package/dist/planning/execution.js +504 -72
- package/dist/planning/execution.js.map +1 -1
- package/dist/planning/index.d.ts +196 -149
- package/dist/planning/index.d.ts.map +1 -1
- package/dist/planning/index.js +31 -355
- package/dist/planning/index.js.map +1 -1
- package/dist/planning/plan-construction.d.ts +25 -0
- package/dist/planning/plan-construction.d.ts.map +1 -0
- package/dist/planning/plan-construction.js +143 -0
- package/dist/planning/plan-construction.js.map +1 -0
- package/dist/planning/plan-sequence-checkpoint.d.ts +9 -0
- package/dist/planning/plan-sequence-checkpoint.d.ts.map +1 -1
- package/dist/planning/plan-sequence-checkpoint.js +16 -7
- package/dist/planning/plan-sequence-checkpoint.js.map +1 -1
- package/dist/planning/plan-sequence-execution.d.ts +5 -0
- package/dist/planning/plan-sequence-execution.d.ts.map +1 -1
- package/dist/planning/plan-sequence-execution.js +74 -40
- package/dist/planning/plan-sequence-execution.js.map +1 -1
- package/dist/planning/plan-sequence.d.ts +2 -1
- package/dist/planning/plan-sequence.d.ts.map +1 -1
- package/dist/planning/plan-sequence.js +8 -1
- package/dist/planning/plan-sequence.js.map +1 -1
- package/dist/planning/plan-validation.d.ts +17 -0
- package/dist/planning/plan-validation.d.ts.map +1 -0
- package/dist/planning/plan-validation.js +127 -0
- package/dist/planning/plan-validation.js.map +1 -0
- package/dist/planning/simulation.d.ts +25 -1
- package/dist/planning/simulation.d.ts.map +1 -1
- package/dist/planning/simulation.js +111 -11
- package/dist/planning/simulation.js.map +1 -1
- package/dist/registry/cargo.d.ts +7 -12
- package/dist/registry/cargo.d.ts.map +1 -1
- package/dist/registry/cargo.js +20 -20
- package/dist/registry/cargo.js.map +1 -1
- package/dist/registry/docking.d.ts +10 -0
- package/dist/registry/docking.d.ts.map +1 -0
- package/dist/registry/docking.js +12 -0
- package/dist/registry/docking.js.map +1 -0
- package/dist/registry/index.d.ts +4 -0
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/index.js +190 -224
- package/dist/registry/index.js.map +1 -1
- package/dist/registry/onboarding.d.ts +10 -2
- package/dist/registry/onboarding.d.ts.map +1 -1
- package/dist/registry/onboarding.js +20 -7
- package/dist/registry/onboarding.js.map +1 -1
- package/dist/registry/scanning.d.ts +7 -0
- package/dist/registry/scanning.d.ts.map +1 -0
- package/dist/registry/scanning.js +13 -0
- package/dist/registry/scanning.js.map +1 -0
- package/dist/registry/ship-stats-snapshot.js +19 -19
- package/dist/registry/ship-stats-snapshot.js.map +1 -1
- package/dist/registry/ships.d.ts +22 -2
- package/dist/registry/ships.d.ts.map +1 -1
- package/dist/registry/ships.js +31 -4
- package/dist/registry/ships.js.map +1 -1
- package/dist/registry/xp-runtime.d.ts +4 -0
- package/dist/registry/xp-runtime.d.ts.map +1 -0
- package/dist/registry/xp-runtime.js +14 -0
- package/dist/registry/xp-runtime.js.map +1 -0
- package/dist/rewards/index.d.ts +11 -5
- package/dist/rewards/index.d.ts.map +1 -1
- package/dist/rewards/index.js +10 -21
- package/dist/rewards/index.js.map +1 -1
- package/dist/scanning/actions/index.d.ts +116 -0
- package/dist/scanning/actions/index.d.ts.map +1 -0
- package/dist/scanning/actions/index.js +191 -0
- package/dist/scanning/actions/index.js.map +1 -0
- package/dist/scanning/index.d.ts +5 -2
- package/dist/scanning/index.d.ts.map +1 -1
- package/dist/scanning/index.js +17 -21
- package/dist/scanning/index.js.map +1 -1
- package/dist/scanning/lifecycle.d.ts +77 -0
- package/dist/scanning/lifecycle.d.ts.map +1 -0
- package/dist/scanning/lifecycle.js +93 -0
- package/dist/scanning/lifecycle.js.map +1 -0
- package/dist/scanning/odds.d.ts +111 -0
- package/dist/scanning/odds.d.ts.map +1 -0
- package/dist/scanning/odds.js +294 -0
- package/dist/scanning/odds.js.map +1 -0
- package/dist/scanning/signals.d.ts +121 -0
- package/dist/scanning/signals.d.ts.map +1 -0
- package/dist/scanning/signals.js +171 -0
- package/dist/scanning/signals.js.map +1 -0
- package/dist/starbases/actions/index.d.ts +1 -1
- package/dist/starbases/actions/index.d.ts.map +1 -1
- package/dist/starbases/actions/index.js +16 -58
- package/dist/starbases/actions/index.js.map +1 -1
- package/dist/starbases/index.d.ts.map +1 -1
- package/dist/starbases/index.js +3 -11
- package/dist/starbases/index.js.map +1 -1
- package/dist/world/index.d.ts +110 -5
- package/dist/world/index.d.ts.map +1 -1
- package/dist/world/index.js +112 -15
- package/dist/world/index.js.map +1 -1
- package/dist/world/planet-claim-stake-plots.d.ts +130 -0
- package/dist/world/planet-claim-stake-plots.d.ts.map +1 -0
- package/dist/world/planet-claim-stake-plots.js +110 -0
- package/dist/world/planet-claim-stake-plots.js.map +1 -0
- package/dist/world/starbase-status.d.ts +176 -0
- package/dist/world/starbase-status.d.ts.map +1 -0
- package/dist/world/starbase-status.js +153 -0
- package/dist/world/starbase-status.js.map +1 -0
- package/package.json +10 -2
|
@@ -1,21 +1,42 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { deriveCurrencyCache, validateCurrencyCache, } from '../../internal/c4/currency-cache.js';
|
|
2
|
+
import { isAddress } from '@solana/kit';
|
|
2
3
|
import { InvalidActionInputError, SageSdkError } from '../../client/errors.js';
|
|
3
4
|
import { readContextRawAccounts } from '../../client/reconciliation.js';
|
|
4
|
-
import {
|
|
5
|
+
import { StarbaseLevel } from '../../internal/c4/runtime-bindings.js';
|
|
5
6
|
import { readFreshGameClaimStakeConfiguration, } from '../../registry/claim-stakes.js';
|
|
6
|
-
import { characterAccountDefinition, findCharacterPda, } from '../../internal/c4/
|
|
7
|
+
import { characterAccountDefinition, findCharacterPda, } from '../../internal/c4/character.js';
|
|
7
8
|
import { deriveFactionOwnershipAddress, factionOwnershipAccountDefinition, } from '../../internal/c4/factions.js';
|
|
8
9
|
import { claimStakeAccountDefinition } from '../../internal/c4/claim-stake.js';
|
|
9
|
-
import {
|
|
10
|
+
import { factionValue } from '../../internal/c4/faction.js';
|
|
11
|
+
import { deriveFleetCrewBindingAddress, fleetCrewBindingAccountDefinition, matchesFleetCrewBindingIdentity, } from '../../internal/c4/fleet-crew-binding.js';
|
|
10
12
|
import { deriveFleetAddress, fleetAccountDefinition, } from '../../internal/c4/fleet.js';
|
|
11
13
|
import { deriveProfileFactionAddress, profileFactionIdentityAccountDefinition, } from '../../internal/c4/profile-faction.js';
|
|
12
14
|
import { deriveStarbasePlayerAddress, starbasePlayerAccountDefinition, } from '../../internal/c4/starbase.js';
|
|
13
|
-
import { celestialBodyAccountDefinition,
|
|
15
|
+
import { celestialBodyAccountDefinition, deriveCelestialBodyAddress, deriveStarSystemAddress, starSystemAccountDefinition, } from '../../internal/c4/world.js';
|
|
16
|
+
import { resolveXpRuntime } from '../../internal/planning/xp-runtime.js';
|
|
17
|
+
import { requireProfileStarbasePlayer } from '../../internal/planning/starbase-player-owner.js';
|
|
14
18
|
import { requireGameAddress } from '../../internal/game-context.js';
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
19
|
+
import { cargoStorageUnits } from '../../internal/cargo.js';
|
|
20
|
+
import { adaptCancelClaimStakeBuildingChangesInstruction, adaptClaimStakeBuildingChangesInstruction, adaptDeconstructClaimStakeInstruction, adaptFinalizeClaimStakeBuildingChangesInstruction, adaptPlaceClaimStakeInstruction, adaptRecoverClaimStakeFleetTransferInstruction, adaptStartClaimStakeFleetTransferInstruction, adaptTopUpClaimStakeRentInstruction, readPlanAuthorization, } from '../../internal/planning/authorization-adapter.js';
|
|
21
|
+
import { buildPlannerPlan } from '../../planning/plan-construction.js';
|
|
17
22
|
import { readFreshGameCargoDefinitions } from '../../registry/cargo.js';
|
|
18
23
|
import { resolveCargo } from '../../registry/index.js';
|
|
24
|
+
import { accountAbsentPrecondition, accountStatePrecondition, } from '../../internal/planning/account-state.js';
|
|
25
|
+
async function resolveClaimStakeXp(ctx, game, structure, character) {
|
|
26
|
+
const xp = await resolveXpRuntime(ctx, {
|
|
27
|
+
game,
|
|
28
|
+
structure,
|
|
29
|
+
...(character === undefined ? {} : { character }),
|
|
30
|
+
});
|
|
31
|
+
const guard = {
|
|
32
|
+
kind: 'xp-runtime',
|
|
33
|
+
address: game,
|
|
34
|
+
intent: xp.intent,
|
|
35
|
+
accounts: xp.accounts,
|
|
36
|
+
describes: 'The Game and canonical Claim Stake XP accounts remain supported; accrued XP may change. Initialize or repair missing XP state using the game client, then recreate the Plan.',
|
|
37
|
+
};
|
|
38
|
+
return { accounts: xp.accounts, guard };
|
|
39
|
+
}
|
|
19
40
|
const U64_MAX = (1n << 64n) - 1n;
|
|
20
41
|
const U16_MAX = 65_535;
|
|
21
42
|
const I32_MAX = 2_147_483_647;
|
|
@@ -31,13 +52,13 @@ const LEVEL_INDEX = Object.freeze({
|
|
|
31
52
|
css: 6,
|
|
32
53
|
});
|
|
33
54
|
const CLAIM_STAKE_PLOT_LEVELS = Object.freeze([
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
55
|
+
StarbaseLevel.Level0,
|
|
56
|
+
StarbaseLevel.Level1,
|
|
57
|
+
StarbaseLevel.Level2,
|
|
58
|
+
StarbaseLevel.Level3,
|
|
59
|
+
StarbaseLevel.Level4,
|
|
60
|
+
StarbaseLevel.Level5,
|
|
61
|
+
StarbaseLevel.Css,
|
|
41
62
|
]);
|
|
42
63
|
const TIER_INDEX = Object.freeze({
|
|
43
64
|
one: 0,
|
|
@@ -90,15 +111,7 @@ function validateOptions(value) {
|
|
|
90
111
|
'hubBuildingId',
|
|
91
112
|
'initialRentAmount',
|
|
92
113
|
]);
|
|
93
|
-
const
|
|
94
|
-
exactKeys(authorizationRecord, 'authorization', ['profile', 'authority', 'keyIndex'], ['certificate']);
|
|
95
|
-
const authorization = authorizationRecord;
|
|
96
|
-
address(authorization.profile, 'authorization.profile');
|
|
97
|
-
address(authorization.authority, 'authorization.authority');
|
|
98
|
-
if (authorization.certificate !== undefined) {
|
|
99
|
-
address(authorization.certificate, 'authorization.certificate');
|
|
100
|
-
}
|
|
101
|
-
validatePlanAuthorization(authorization);
|
|
114
|
+
const authorization = readPlanAuthorization(options.authorization);
|
|
102
115
|
if (typeof options.initialRentAmount !== 'bigint' ||
|
|
103
116
|
options.initialRentAmount <= 0n ||
|
|
104
117
|
options.initialRentAmount > U64_MAX) {
|
|
@@ -112,22 +125,10 @@ function validateOptions(value) {
|
|
|
112
125
|
initialRentAmount: options.initialRentAmount,
|
|
113
126
|
};
|
|
114
127
|
}
|
|
115
|
-
function validateAuthorization(value) {
|
|
116
|
-
const authorizationRecord = record(value, 'authorization');
|
|
117
|
-
exactKeys(authorizationRecord, 'authorization', ['profile', 'authority', 'keyIndex'], ['certificate']);
|
|
118
|
-
const authorization = authorizationRecord;
|
|
119
|
-
address(authorization.profile, 'authorization.profile');
|
|
120
|
-
address(authorization.authority, 'authorization.authority');
|
|
121
|
-
if (authorization.certificate !== undefined) {
|
|
122
|
-
address(authorization.certificate, 'authorization.certificate');
|
|
123
|
-
}
|
|
124
|
-
validatePlanAuthorization(authorization);
|
|
125
|
-
return authorization;
|
|
126
|
-
}
|
|
127
128
|
function validateBuildingChangeOptions(value) {
|
|
128
129
|
const options = record(value, 'options');
|
|
129
130
|
exactKeys(options, 'options', ['authorization', 'buildingChanges']);
|
|
130
|
-
const authorization =
|
|
131
|
+
const authorization = readPlanAuthorization(options.authorization);
|
|
131
132
|
const values = options.buildingChanges;
|
|
132
133
|
if (!Array.isArray(values) || values.length === 0) {
|
|
133
134
|
invalid('buildingChanges', values, 'a non-empty dense array of add/remove building changes', 'Provide at least one exact building change before retrying.');
|
|
@@ -168,22 +169,22 @@ function validateBuildingChangeOptions(value) {
|
|
|
168
169
|
function validateFinalizeBuildingChangeOptions(value) {
|
|
169
170
|
const options = record(value, 'options');
|
|
170
171
|
exactKeys(options, 'options', ['authorization']);
|
|
171
|
-
return { authorization:
|
|
172
|
+
return { authorization: readPlanAuthorization(options.authorization) };
|
|
172
173
|
}
|
|
173
174
|
function validateCancelBuildingChangeOptions(value) {
|
|
174
175
|
const options = record(value, 'options');
|
|
175
176
|
exactKeys(options, 'options', ['authorization']);
|
|
176
|
-
return { authorization:
|
|
177
|
+
return { authorization: readPlanAuthorization(options.authorization) };
|
|
177
178
|
}
|
|
178
179
|
function validateDeconstructOptions(value) {
|
|
179
180
|
const options = record(value, 'options');
|
|
180
181
|
exactKeys(options, 'options', ['authorization']);
|
|
181
|
-
return { authorization:
|
|
182
|
+
return { authorization: readPlanAuthorization(options.authorization) };
|
|
182
183
|
}
|
|
183
184
|
function validateTopUpRentOptions(value) {
|
|
184
185
|
const options = record(value, 'options');
|
|
185
186
|
exactKeys(options, 'options', ['amount', 'authorization']);
|
|
186
|
-
const authorization =
|
|
187
|
+
const authorization = readPlanAuthorization(options.authorization);
|
|
187
188
|
if (typeof options.amount !== 'bigint' ||
|
|
188
189
|
options.amount <= 0n ||
|
|
189
190
|
options.amount > U64_MAX) {
|
|
@@ -220,7 +221,7 @@ function validateCargoRequests(value, field, seen) {
|
|
|
220
221
|
function validateStartFleetTransferOptions(value) {
|
|
221
222
|
const options = record(value, 'options');
|
|
222
223
|
exactKeys(options, 'options', ['authorization', 'load', 'unload']);
|
|
223
|
-
const authorization =
|
|
224
|
+
const authorization = readPlanAuthorization(options.authorization);
|
|
224
225
|
const seen = new Set();
|
|
225
226
|
const load = validateCargoRequests(options.load, 'load', seen);
|
|
226
227
|
const unload = validateCargoRequests(options.unload, 'unload', seen);
|
|
@@ -232,7 +233,7 @@ function validateStartFleetTransferOptions(value) {
|
|
|
232
233
|
function validateRecoverFleetTransferOptions(value) {
|
|
233
234
|
const options = record(value, 'options');
|
|
234
235
|
exactKeys(options, 'options', ['atUnixSeconds', 'authorization']);
|
|
235
|
-
const authorization =
|
|
236
|
+
const authorization = readPlanAuthorization(options.authorization);
|
|
236
237
|
if (typeof options.atUnixSeconds !== 'bigint' ||
|
|
237
238
|
options.atUnixSeconds < 0n ||
|
|
238
239
|
options.atUnixSeconds > U64_MAX) {
|
|
@@ -240,53 +241,9 @@ function validateRecoverFleetTransferOptions(value) {
|
|
|
240
241
|
}
|
|
241
242
|
return { atUnixSeconds: options.atUnixSeconds, authorization };
|
|
242
243
|
}
|
|
243
|
-
async function deriveCurrencyCacheAddress(game) {
|
|
244
|
-
const [derived] = await getProgramDerivedAddress({
|
|
245
|
-
programAddress: sage.SAGE_PROGRAM_ADDRESS,
|
|
246
|
-
seeds: [
|
|
247
|
-
getBytesEncoder().encode(new TextEncoder().encode('CurrencyConfig')),
|
|
248
|
-
getAddressEncoder().encode(game),
|
|
249
|
-
],
|
|
250
|
-
});
|
|
251
|
-
return derived;
|
|
252
|
-
}
|
|
253
|
-
function validateCurrencyCache(account, game, canonicalAddress, action) {
|
|
254
|
-
const decoder = sage.getCurrencyConfigCacheDecoder();
|
|
255
|
-
const validDiscriminator = sage.CURRENCY_CONFIG_CACHE_DISCRIMINATOR.every((byte, index) => account.data[index] === byte);
|
|
256
|
-
if (account.address !== canonicalAddress ||
|
|
257
|
-
account.owner !== sage.SAGE_PROGRAM_ADDRESS ||
|
|
258
|
-
account.data.length !== decoder.fixedSize ||
|
|
259
|
-
!validDiscriminator ||
|
|
260
|
-
decoder.decode(account.data).gameId !== game) {
|
|
261
|
-
fail(`CurrencyCache ${account.address} does not match the configured Game, canonical PDA, owner, or pinned account layout. Refresh the Game currency configuration and retry ${action}.`, account.address);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
244
|
function requireAccount(account, accountAddress, message) {
|
|
265
245
|
return account ?? fail(message, accountAddress);
|
|
266
246
|
}
|
|
267
|
-
async function hashAccountState(account) {
|
|
268
|
-
const owner = getAddressEncoder().encode(account.owner);
|
|
269
|
-
const canonical = new Uint8Array(owner.length + account.data.length);
|
|
270
|
-
canonical.set(owner);
|
|
271
|
-
canonical.set(account.data, owner.length);
|
|
272
|
-
const digest = new Uint8Array(await globalThis.crypto.subtle.digest('SHA-256', canonical));
|
|
273
|
-
return [...digest].map((byte) => byte.toString(16).padStart(2, '0')).join('');
|
|
274
|
-
}
|
|
275
|
-
async function precondition(account, describes) {
|
|
276
|
-
return Object.freeze({
|
|
277
|
-
address: account.address,
|
|
278
|
-
dataHash: await hashAccountState(account),
|
|
279
|
-
describes,
|
|
280
|
-
kind: 'account-state',
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
function absentPrecondition(accountAddress, describes) {
|
|
284
|
-
return Object.freeze({
|
|
285
|
-
address: accountAddress,
|
|
286
|
-
describes,
|
|
287
|
-
kind: 'account-absent',
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
247
|
function findDefinition(configuration, id, game) {
|
|
291
248
|
const definition = configuration.claimStakes.definitions.find((candidate) => candidate.id === id);
|
|
292
249
|
return (definition ??
|
|
@@ -332,17 +289,7 @@ export async function planPlaceClaimStake(ctx, body, player, input) {
|
|
|
332
289
|
if (canonicalBody !== body.address) {
|
|
333
290
|
fail(`Celestial Body ${body.address} is not the canonical Body ${String(body.id)} for the configured Game. Refresh the Body and retry.`, body.address);
|
|
334
291
|
}
|
|
335
|
-
|
|
336
|
-
fail(`Starbase Player ${player.address} does not belong to authorization Profile ${options.authorization.profile}. Refresh the Starbase Player for that Profile and retry.`, player.address);
|
|
337
|
-
}
|
|
338
|
-
const character = await findCharacterPda(options.authorization.profile, game);
|
|
339
|
-
if (player.character.address !== character) {
|
|
340
|
-
fail(`Starbase Player ${player.address} does not reference the canonical Character ${character} for authorization Profile ${options.authorization.profile}. Refresh the Starbase Player and retry.`, player.address);
|
|
341
|
-
}
|
|
342
|
-
const canonicalPlayer = await deriveStarbasePlayerAddress(player.system.address, character);
|
|
343
|
-
if (canonicalPlayer !== player.address) {
|
|
344
|
-
fail(`Starbase Player ${player.address} is not canonical for its Character and System. Refresh the Starbase Player and retry.`, player.address);
|
|
345
|
-
}
|
|
292
|
+
const character = await requireProfileStarbasePlayer(player, options.authorization.profile, game);
|
|
346
293
|
if (body.system.address !== player.system.address) {
|
|
347
294
|
fail(`Celestial Body ${body.address} belongs to System ${body.system.address}, but Starbase Player ${player.address} belongs to System ${player.system.address}. Choose both snapshots from the same System and retry.`, body.address);
|
|
348
295
|
}
|
|
@@ -385,11 +332,10 @@ export async function planPlaceClaimStake(ctx, body, player, input) {
|
|
|
385
332
|
}
|
|
386
333
|
const currentBodyAccount = requireAccount(bodyAccount, body.address, `Celestial Body ${body.address} is missing. Refresh the Body and retry placement.`);
|
|
387
334
|
const currentPlayerAccount = requireAccount(playerAccount, player.address, `Starbase Player ${player.address} is missing. Refresh it and retry placement.`);
|
|
388
|
-
const currentCharacterAccount = requireAccount(characterAccount, character, `Canonical Character ${character} is missing. Refresh the Profile Character and retry placement.`);
|
|
389
335
|
const currentSystemAccount = requireAccount(systemAccount, body.system.address, `Star System ${body.system.address} is missing. Refresh the System and retry placement.`);
|
|
390
336
|
const currentBody = celestialBodyAccountDefinition.decode(currentBodyAccount);
|
|
391
337
|
const currentPlayer = starbasePlayerAccountDefinition.decode(currentPlayerAccount);
|
|
392
|
-
const
|
|
338
|
+
const { account: currentCharacterAccount } = requireProfileCharacter(characterAccount, character, options.authorization.profile, game, 'placement');
|
|
393
339
|
const currentSystem = starSystemAccountDefinition.decode(currentSystemAccount);
|
|
394
340
|
const canonicalSystem = await deriveStarSystemAddress(game, currentSystem.systemId);
|
|
395
341
|
if (canonicalSystem !== body.system.address ||
|
|
@@ -411,10 +357,6 @@ export async function planPlaceClaimStake(ctx, body, player, input) {
|
|
|
411
357
|
currentPlayer.totalCrew - currentPlayer.busyCrew !== player.availableCrew) {
|
|
412
358
|
fail(`Starbase Player ${player.address} changed or does not match the authorization Profile, canonical Character, System, or available crew. Refresh it and retry.`, player.address);
|
|
413
359
|
}
|
|
414
|
-
if (currentCharacter.playerProfile !== options.authorization.profile ||
|
|
415
|
-
currentCharacter.game !== game) {
|
|
416
|
-
fail(`Character ${character} does not match authorization Profile ${options.authorization.profile} and configured Game ${game}. Refresh the Character and retry.`, character);
|
|
417
|
-
}
|
|
418
360
|
const currentCargo = currentPlayer.cargo.amounts.find(({ cargoId }) => cargoId === definition.cargoId)?.amount ?? 0n;
|
|
419
361
|
if (currentCargo !== cargoQuantity || currentCargo < 1n) {
|
|
420
362
|
fail(`Starbase Player ${player.address} Claim Stake cargo changed from the loaded snapshot or is no longer sufficient. Refresh its cargo and retry.`, player.address);
|
|
@@ -432,19 +374,19 @@ export async function planPlaceClaimStake(ctx, body, player, input) {
|
|
|
432
374
|
fail(`Planet ${body.name} (${body.address}) has no available ${definition.name} plot at Starbase ${currentSystem.starbase.level}; ${String(usedPlots)} of ${String(plotLimit)} known plots are occupied. Choose another eligible Planet or tier, refresh it, and retry.`, body.address);
|
|
433
375
|
}
|
|
434
376
|
const profileFaction = await deriveProfileFactionAddress(options.authorization.profile);
|
|
435
|
-
const currencyCache = await
|
|
377
|
+
const currencyCache = await deriveCurrencyCache(game).then(([address]) => address);
|
|
436
378
|
const description = `Place ${definition.name} on Planet ${body.name} (${body.address}) with bundled hub ${hub.name}, ${String(hub.neededCrew)} crew, and ${String(options.initialRentAmount)} raw initial rent.`;
|
|
437
|
-
return
|
|
379
|
+
return buildPlannerPlan({
|
|
438
380
|
kind: 'claim-stakes.place',
|
|
439
381
|
preconditions: [
|
|
440
382
|
...(await Promise.all([
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
383
|
+
accountStatePrecondition(freshGame.account, `The configured Game retains Claim Stake definition ${String(definition.id)} and bundled hub ${String(hub.id)} eligibility.`),
|
|
384
|
+
accountStatePrecondition(currentBodyAccount, `Planet ${body.name} retains an available ${definition.name} plot and its configured Game/System relationship.`),
|
|
385
|
+
accountStatePrecondition(currentPlayerAccount, `Starbase Player ${player.address} retains its Profile, Character, System, available crew, and ${cargoName} balance.`),
|
|
386
|
+
characterPrecondition(currentCharacterAccount, options.authorization.profile),
|
|
387
|
+
accountStatePrecondition(currentSystemAccount, `Star System ${currentSystem.name} retains its configured Game, sequence, and active Starbase level.`),
|
|
446
388
|
])),
|
|
447
|
-
|
|
389
|
+
accountAbsentPrecondition(options.claimStake, 'The caller-supplied Claim Stake signer address remains unallocated.'),
|
|
448
390
|
],
|
|
449
391
|
steps: [
|
|
450
392
|
{
|
|
@@ -492,12 +434,165 @@ function sameStakeState(left, right) {
|
|
|
492
434
|
sameQuantities(left.buildings, right.buildings));
|
|
493
435
|
}
|
|
494
436
|
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
437
|
+
// Common facts for planners acting on an owned, placed Claim Stake. Each
|
|
438
|
+
// planner keeps its own eligibility checks and Plan wording at its call site;
|
|
439
|
+
// `action` completes the shared remedies ("retry <action>").
|
|
440
|
+
/** Requires the loaded Claim Stake to belong to the configured Game and to the
|
|
441
|
+
* authorization Profile's canonical Character, which it returns. */
|
|
442
|
+
async function requireOwnedStake(stake, game, profile) {
|
|
443
|
+
if (stake.game !== game) {
|
|
444
|
+
fail(`Claim Stake ${stake.address} does not match the configured Game ${game}. Refresh it through this context and retry.`, stake.address);
|
|
445
|
+
}
|
|
446
|
+
const character = await findCharacterPda(profile, game);
|
|
447
|
+
if (stake.ownerCharacter.address !== character) {
|
|
448
|
+
fail(`Claim Stake ${stake.address} does not belong to authorization Profile ${profile}'s canonical Character ${character}. Choose an owned Claim Stake, refresh it, and retry.`, stake.address);
|
|
449
|
+
}
|
|
450
|
+
return character;
|
|
451
|
+
}
|
|
452
|
+
/** Reads and decodes the fresh Claim Stake and Body, with `extra` accounts in
|
|
453
|
+
* the same batch. */
|
|
454
|
+
async function readOwnedStake(ctx, stake, action, extra = []) {
|
|
455
|
+
const [stakeCandidate, bodyCandidate, ...extraAccounts] = await readContextRawAccounts(ctx, [
|
|
456
|
+
stake.address,
|
|
457
|
+
stake.body.address,
|
|
458
|
+
...extra,
|
|
459
|
+
]);
|
|
460
|
+
const stakeAccount = requireAccount(stakeCandidate, stake.address, `Claim Stake ${stake.address} is missing. Refresh it and retry ${action}.`);
|
|
461
|
+
const bodyAccount = requireAccount(bodyCandidate, stake.body.address, `Celestial Body ${stake.body.address} is missing. Refresh the Claim Stake Body and retry ${action}.`);
|
|
462
|
+
return {
|
|
463
|
+
bodyAccount,
|
|
464
|
+
currentBody: celestialBodyAccountDefinition.decode(bodyAccount),
|
|
465
|
+
currentStake: claimStakeAccountDefinition.decode(stakeAccount),
|
|
466
|
+
extraAccounts,
|
|
467
|
+
stakeAccount,
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
/** Whether the fresh Claim Stake keeps the loaded ownership, Body,
|
|
471
|
+
* definitions, buildings and System generation. */
|
|
472
|
+
function sameOwnedStake(current, stake, game, character) {
|
|
473
|
+
return (current.game === game &&
|
|
474
|
+
current.body === stake.body.address &&
|
|
475
|
+
current.ownerCharacter === character &&
|
|
476
|
+
current.claimStakeDefinitionId === stake.claimStakeDefinitionId &&
|
|
477
|
+
current.claimStakeDefinitionSeqId === stake.claimStakeDefinitionSeqId &&
|
|
478
|
+
current.buildingDefinitionSeqId === stake.buildingDefinitionSeqId &&
|
|
479
|
+
current.systemSeqId === stake.systemSeqId &&
|
|
480
|
+
sameQuantities(current.buildings, stake.buildings));
|
|
481
|
+
}
|
|
482
|
+
/** Whether the fresh Claim Stake keeps the loaded transfer facts: ownership,
|
|
483
|
+
* Body, active state, System generation, resources and capacity. */
|
|
484
|
+
function sameTransferStake(current, stake, game, character) {
|
|
485
|
+
return (current.game === game &&
|
|
486
|
+
current.ownerCharacter === character &&
|
|
487
|
+
current.body === stake.body.address &&
|
|
488
|
+
current.systemSeqId === stake.systemSeqId &&
|
|
489
|
+
current.state.kind === 'active' &&
|
|
490
|
+
current.production.cargoPod.storageCost ===
|
|
491
|
+
stake.resources.capacity.usedRaw &&
|
|
492
|
+
current.production.resourceCapacityRaw ===
|
|
493
|
+
stake.resources.capacity.totalRaw &&
|
|
494
|
+
sameCargoAmounts(current.production.cargoPod.amounts, stake.resources.inventory.items.map(({ id, quantityRaw }) => ({
|
|
495
|
+
amount: quantityRaw,
|
|
496
|
+
id,
|
|
497
|
+
}))));
|
|
498
|
+
}
|
|
499
|
+
/** Whether the fresh Fleet keeps the loaded Game, owner, name, cargo and
|
|
500
|
+
* capacities. */
|
|
501
|
+
function sameTransferFleet(current, fleet, game, profile) {
|
|
502
|
+
return (current.game === game &&
|
|
503
|
+
current.ownerProfile === profile &&
|
|
504
|
+
current.name === fleet.name &&
|
|
505
|
+
current.ammoBank.cargoId === fleet.ammo.id &&
|
|
506
|
+
current.ammoBank.amount === fleet.ammo.amount &&
|
|
507
|
+
current.fuelTank.cargoId === fleet.fuel.id &&
|
|
508
|
+
current.fuelTank.amount === fleet.fuel.amount &&
|
|
509
|
+
current.cargoHold.storageCost === fleet.cargoHold.storageCost &&
|
|
510
|
+
sameCargoAmounts(current.cargoHold.amounts, fleet.cargoHold.items) &&
|
|
511
|
+
current.stats.cargo.ammoCapacity === fleet.capacities.ammo.total &&
|
|
512
|
+
current.stats.cargo.fuelCapacity === fleet.capacities.fuel.total &&
|
|
513
|
+
current.stats.cargo.cargoCapacity === fleet.capacities.cargo.total);
|
|
514
|
+
}
|
|
515
|
+
/** Requires the fresh Body to be the Claim Stake's canonical Planet in the
|
|
516
|
+
* configured Game at the Claim Stake's System generation. */
|
|
517
|
+
async function requireStakePlanet(currentBody, stake, game, action) {
|
|
518
|
+
if (currentBody.kind !== 'planet' ||
|
|
519
|
+
currentBody.game !== game ||
|
|
520
|
+
currentBody.systemSequenceId !== stake.systemSeqId ||
|
|
521
|
+
(await deriveCelestialBodyAddress(game, currentBody.id)) !==
|
|
522
|
+
stake.body.address) {
|
|
523
|
+
fail(`Celestial Body ${stake.body.address} does not match the Claim Stake's configured Game, canonical Planet identity, or System generation. Refresh the Body and Claim Stake before retrying ${action}.`, stake.body.address);
|
|
524
|
+
}
|
|
525
|
+
return currentBody;
|
|
526
|
+
}
|
|
527
|
+
/** Requires and decodes the canonical Character of the authorization Profile in
|
|
528
|
+
* the configured Game. */
|
|
529
|
+
function requireProfileCharacter(candidate, character, profile, game, action) {
|
|
530
|
+
const account = requireAccount(candidate, character, `Canonical Character ${character} is missing. Refresh the Profile Character and retry ${action}.`);
|
|
531
|
+
const current = characterAccountDefinition.decode(account);
|
|
532
|
+
if (current.playerProfile !== profile || current.game !== game) {
|
|
533
|
+
fail(`Character ${character} does not match authorization Profile ${profile} and configured Game ${game}. Refresh the Character and retry ${action}.`, character);
|
|
534
|
+
}
|
|
535
|
+
return { account, current };
|
|
536
|
+
}
|
|
537
|
+
/** Reads the Claim Stake's System and the authorization Profile's canonical
|
|
538
|
+
* Starbase Player there, with `extra` accounts in the same batch. Requires a
|
|
539
|
+
* canonical, current System with an active Starbase that lists the Body, and a
|
|
540
|
+
* Starbase Player of the Profile, Character and System. */
|
|
541
|
+
async function readStakeStarbase(ctx, stake, game, system, character, profile, action, extra = []) {
|
|
542
|
+
const player = await deriveStarbasePlayerAddress(system, character);
|
|
543
|
+
const [systemCandidate, playerCandidate, ...extraAccounts] = await readContextRawAccounts(ctx, [system, player, ...extra]);
|
|
544
|
+
const systemAccount = requireAccount(systemCandidate, system, `Star System ${system} is missing. Refresh the Claim Stake's System and retry ${action}.`);
|
|
545
|
+
const playerAccount = requireAccount(playerCandidate, player, `Starbase Player ${player} is missing for authorization Profile ${profile}. Register or refresh it in the Claim Stake's System before retrying ${action}.`);
|
|
546
|
+
const currentSystem = starSystemAccountDefinition.decode(systemAccount);
|
|
547
|
+
const currentPlayer = starbasePlayerAccountDefinition.decode(playerAccount);
|
|
548
|
+
if (currentSystem.game !== game ||
|
|
549
|
+
currentSystem.sequenceId !== stake.systemSeqId ||
|
|
550
|
+
currentSystem.starbase === undefined ||
|
|
551
|
+
!currentSystem.celestialBodyAddresses.includes(stake.body.address) ||
|
|
552
|
+
(await deriveStarSystemAddress(game, currentSystem.systemId)) !== system) {
|
|
553
|
+
fail(`Star System ${system} does not match the configured Game, canonical identity, Claim Stake generation, active nested Starbase, or Claim Stake Body relationship. Refresh the System and retry ${action}.`, system);
|
|
554
|
+
}
|
|
555
|
+
if (currentPlayer.playerProfile !== profile ||
|
|
556
|
+
currentPlayer.character !== character ||
|
|
557
|
+
currentPlayer.system !== system) {
|
|
558
|
+
fail(`Starbase Player ${player} does not match the authorization Profile, canonical Character, and Claim Stake System. Refresh it and retry ${action}.`, player);
|
|
559
|
+
}
|
|
560
|
+
return {
|
|
561
|
+
currentPlayer,
|
|
562
|
+
currentSystem,
|
|
563
|
+
extraAccounts,
|
|
564
|
+
player,
|
|
565
|
+
playerAccount,
|
|
566
|
+
starbase: currentSystem.starbase,
|
|
567
|
+
systemAccount,
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
async function claimStakeCurrencyCache(game) {
|
|
571
|
+
const [currencyCache] = await deriveCurrencyCache(game);
|
|
572
|
+
return currencyCache;
|
|
573
|
+
}
|
|
574
|
+
/** Requires the canonical CurrencyCache and returns its Plan guard. */
|
|
575
|
+
async function requireCurrencyCache(candidate, currencyCache, game, action, planName) {
|
|
576
|
+
await validateCurrencyCache(requireAccount(candidate, currencyCache, `Canonical CurrencyCache ${currencyCache} is missing for configured Game ${game}. Refresh the Game currency configuration and retry ${action}.`), game, planName);
|
|
577
|
+
return {
|
|
578
|
+
kind: 'currency-cache',
|
|
579
|
+
address: currencyCache,
|
|
580
|
+
game,
|
|
581
|
+
describes: 'The canonical CurrencyCache remains assigned to the configured Game; shared accounting may change.',
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
function planetPrecondition(account, system) {
|
|
585
|
+
return accountStatePrecondition(account, `The Claim Stake Planet remains assigned to System ${system} at the current generation.`);
|
|
586
|
+
}
|
|
587
|
+
function characterPrecondition(account, profile) {
|
|
588
|
+
return accountStatePrecondition(account, `The canonical Character remains assigned to Profile ${profile} in the configured Game.`);
|
|
589
|
+
}
|
|
590
|
+
function systemPrecondition(account, name) {
|
|
591
|
+
return accountStatePrecondition(account, `Star System ${name} retains its configured Game, sequence, nested Starbase, and Claim Stake Body relationship.`);
|
|
592
|
+
}
|
|
593
|
+
function playerPrecondition(account, player, facts = 'Profile, Character, and System') {
|
|
594
|
+
return accountStatePrecondition(account, `Starbase Player ${player} retains its ${facts}.`);
|
|
595
|
+
}
|
|
501
596
|
function buildingDescription(change, name) {
|
|
502
597
|
return `${change.kind} ${String(change.quantity)} ${name}`;
|
|
503
598
|
}
|
|
@@ -509,6 +604,9 @@ function buildingDescription(change, name) {
|
|
|
509
604
|
* construction cargo. Rent synchronization and the final concurrent sequence
|
|
510
605
|
* race remain chain-authoritative.
|
|
511
606
|
*
|
|
607
|
+
* Requires Game 2 and its existing canonical Claim Stake XP ledger.
|
|
608
|
+
* Missing XP state must be repaired outside this Plan; no accounts are created.
|
|
609
|
+
*
|
|
512
610
|
* @example
|
|
513
611
|
* ```ts
|
|
514
612
|
* declare const ctx: SageContext;
|
|
@@ -521,88 +619,40 @@ function buildingDescription(change, name) {
|
|
|
521
619
|
export async function planClaimStakeBuildingChanges(ctx, stake, input) {
|
|
522
620
|
const options = validateBuildingChangeOptions(input);
|
|
523
621
|
const game = requireGameAddress(ctx);
|
|
622
|
+
const { profile } = options.authorization;
|
|
524
623
|
if (stake.state.kind === 'deactivated') {
|
|
525
624
|
fail(`Claim Stake ${stake.address} is deactivated; building changes require an active or design Claim Stake. Refresh it or choose another owned Claim Stake before retrying.`, stake.address);
|
|
526
625
|
}
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
const character = await findCharacterPda(options.authorization.profile, game);
|
|
531
|
-
if (stake.ownerCharacter.address !== character) {
|
|
532
|
-
fail(`Claim Stake ${stake.address} does not belong to authorization Profile ${options.authorization.profile}'s canonical Character ${character}. Choose an owned Claim Stake, refresh it, and retry.`, stake.address);
|
|
533
|
-
}
|
|
534
|
-
const [freshGame, firstAccounts] = await Promise.all([
|
|
626
|
+
const character = await requireOwnedStake(stake, game, profile);
|
|
627
|
+
const action = 'building changes';
|
|
628
|
+
const [freshGame, loaded] = await Promise.all([
|
|
535
629
|
readFreshGameClaimStakeConfiguration(ctx),
|
|
536
|
-
|
|
630
|
+
readOwnedStake(ctx, stake, action, [character]),
|
|
537
631
|
]);
|
|
538
632
|
if (freshGame === undefined) {
|
|
539
633
|
fail(`Configured Game ${game} is missing. Refresh the Game catalog and retry building changes.`, game);
|
|
540
634
|
}
|
|
541
|
-
const
|
|
542
|
-
|
|
543
|
-
const characterAccount = requireAccount(firstAccounts[2], character, `Canonical Character ${character} is missing. Refresh the Profile Character and retry building changes.`);
|
|
544
|
-
const currentStake = claimStakeAccountDefinition.decode(stakeAccount);
|
|
545
|
-
const currentBody = celestialBodyAccountDefinition.decode(bodyAccount);
|
|
546
|
-
const currentCharacter = characterAccountDefinition.decode(characterAccount);
|
|
547
|
-
if (currentStake.game !== game ||
|
|
548
|
-
currentStake.body !== stake.body.address ||
|
|
549
|
-
currentStake.ownerCharacter !== character ||
|
|
550
|
-
currentStake.claimStakeDefinitionId !== stake.claimStakeDefinitionId ||
|
|
551
|
-
currentStake.claimStakeDefinitionSeqId !==
|
|
552
|
-
stake.claimStakeDefinitionSeqId ||
|
|
553
|
-
currentStake.buildingDefinitionSeqId !== stake.buildingDefinitionSeqId ||
|
|
554
|
-
currentStake.systemSeqId !== stake.systemSeqId ||
|
|
555
|
-
!sameQuantities(currentStake.buildings, stake.buildings) ||
|
|
635
|
+
const { bodyAccount, currentStake, stakeAccount } = loaded;
|
|
636
|
+
if (!sameOwnedStake(currentStake, stake, game, character) ||
|
|
556
637
|
currentStake.neededCrew !== stake.neededCrew) {
|
|
557
638
|
fail(`Claim Stake ${stake.address} changed or does not match its loaded ownership, Body, definitions, buildings, crew, or System generation. Refresh it and retry building changes.`, stake.address);
|
|
558
639
|
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
}
|
|
563
|
-
if (currentBody.kind !== 'planet' ||
|
|
564
|
-
currentBody.game !== game ||
|
|
565
|
-
currentBody.systemSequenceId !== stake.systemSeqId ||
|
|
566
|
-
(await deriveCelestialBodyAddress(game, currentBody.id)) !==
|
|
567
|
-
stake.body.address) {
|
|
568
|
-
fail(`Celestial Body ${stake.body.address} does not match the Claim Stake's configured Game, canonical Planet identity, or System generation. Refresh the Body and Claim Stake before retrying.`, stake.body.address);
|
|
569
|
-
}
|
|
570
|
-
const system = currentBody.system;
|
|
571
|
-
const [player, ownership, profileFaction] = await Promise.all([
|
|
572
|
-
deriveStarbasePlayerAddress(system, character),
|
|
640
|
+
const { system } = await requireStakePlanet(loaded.currentBody, stake, game, action);
|
|
641
|
+
const { account: characterAccount } = requireProfileCharacter(loaded.extraAccounts[0], character, profile, game, action);
|
|
642
|
+
const [ownership, profileFaction] = await Promise.all([
|
|
573
643
|
deriveFactionOwnershipAddress(game, 'starbase', system),
|
|
574
|
-
deriveProfileFactionAddress(
|
|
575
|
-
]);
|
|
576
|
-
const [systemAccountCandidate, playerAccountCandidate, ownershipAccount, profileFactionAccountCandidate,] = await readContextRawAccounts(ctx, [
|
|
577
|
-
system,
|
|
578
|
-
player,
|
|
579
|
-
ownership,
|
|
580
|
-
profileFaction,
|
|
644
|
+
deriveProfileFactionAddress(profile),
|
|
581
645
|
]);
|
|
582
|
-
const
|
|
583
|
-
const
|
|
584
|
-
const profileFactionAccount = requireAccount(profileFactionAccountCandidate, profileFaction, `ProfileFaction ${profileFaction} is missing for authorization Profile ${options.authorization.profile}. Choose or repair the Profile faction, refresh it, and retry building changes.`);
|
|
585
|
-
const currentSystem = starSystemAccountDefinition.decode(systemAccount);
|
|
586
|
-
const currentPlayer = starbasePlayerAccountDefinition.decode(playerAccount);
|
|
646
|
+
const { currentPlayer, currentSystem, extraAccounts: [ownershipAccount, profileFactionCandidate], player, playerAccount, starbase, systemAccount, } = await readStakeStarbase(ctx, stake, game, system, character, profile, action, [ownership, profileFaction]);
|
|
647
|
+
const profileFactionAccount = requireAccount(profileFactionCandidate, profileFaction, `ProfileFaction ${profileFaction} is missing for authorization Profile ${profile}. Choose or repair the Profile faction, refresh it, and retry building changes.`);
|
|
587
648
|
const currentProfileFaction = profileFactionIdentityAccountDefinition.decode(profileFactionAccount);
|
|
588
|
-
if (
|
|
589
|
-
|
|
590
|
-
currentSystem.starbase === undefined ||
|
|
591
|
-
(await deriveStarSystemAddress(game, currentSystem.systemId)) !== system) {
|
|
592
|
-
fail(`Star System ${system} does not match the configured Game, canonical identity, Claim Stake generation, or an active nested Starbase. Refresh the System and retry building changes.`, system);
|
|
593
|
-
}
|
|
594
|
-
if (currentPlayer.playerProfile !== options.authorization.profile ||
|
|
595
|
-
currentPlayer.character !== character ||
|
|
596
|
-
currentPlayer.system !== system) {
|
|
597
|
-
fail(`Starbase Player ${player} does not match the authorization Profile, canonical Character, and Claim Stake System. Refresh it and retry building changes.`, player);
|
|
649
|
+
if (currentProfileFaction.profile !== profile) {
|
|
650
|
+
fail(`ProfileFaction ${profileFaction} does not match authorization Profile ${profile}. Refresh or repair the Profile faction before retrying building changes.`, profileFaction);
|
|
598
651
|
}
|
|
599
|
-
|
|
600
|
-
fail(`ProfileFaction ${profileFaction} does not match authorization Profile ${options.authorization.profile}. Refresh or repair the Profile faction before retrying building changes.`, profileFaction);
|
|
601
|
-
}
|
|
602
|
-
let controllerFactionId = LEGACY_CONTROLLER_ID[currentSystem.starbase.owner];
|
|
652
|
+
let controllerFactionId = factionValue(starbase.owner);
|
|
603
653
|
let ownershipPrecondition;
|
|
604
654
|
if (ownershipAccount === undefined) {
|
|
605
|
-
ownershipPrecondition =
|
|
655
|
+
ownershipPrecondition = accountAbsentPrecondition(ownership, `The canonical Starbase FactionOwnership ${ownership} remains unallocated so the chain applies its legacy controller gate.`);
|
|
606
656
|
}
|
|
607
657
|
else {
|
|
608
658
|
const currentOwnership = factionOwnershipAccountDefinition.decode(ownershipAccount);
|
|
@@ -614,7 +664,7 @@ export async function planClaimStakeBuildingChanges(ctx, stake, input) {
|
|
|
614
664
|
}
|
|
615
665
|
controllerFactionId =
|
|
616
666
|
currentOwnership.controllingFactionId ?? controllerFactionId;
|
|
617
|
-
ownershipPrecondition = await
|
|
667
|
+
ownershipPrecondition = await accountStatePrecondition(ownershipAccount, `The Starbase FactionOwnership remains assigned to System ${system} at its current generation.`);
|
|
618
668
|
}
|
|
619
669
|
if (currentProfileFaction.factionId !== controllerFactionId) {
|
|
620
670
|
fail(`ProfileFaction ${profileFaction} faction ${String(currentProfileFaction.factionId)} does not match the current Starbase controller faction ${String(controllerFactionId)}. Use a Profile aligned with the current controller, refresh the faction relationship, and retry building changes.`, profileFaction);
|
|
@@ -744,26 +794,29 @@ export async function planClaimStakeBuildingChanges(ctx, stake, input) {
|
|
|
744
794
|
if (currentStake.production.cargoPod.storageCost > resourceStorageRaw) {
|
|
745
795
|
fail(`The resulting Claim Stake design provides ${String(resourceStorageRaw)} raw storage capacity, below the fresh known cargo usage of ${String(currentStake.production.cargoPod.storageCost)}. Keep enough storage buildings, remove cargo, refresh the Claim Stake, and retry building changes.`, stake.address);
|
|
746
796
|
}
|
|
747
|
-
const currencyCache = await
|
|
797
|
+
const currencyCache = await claimStakeCurrencyCache(game);
|
|
748
798
|
const description = `Change buildings on Claim Stake ${stake.address}: ${descriptions.join('; ')}.`;
|
|
749
|
-
|
|
799
|
+
const xp = await resolveClaimStakeXp(ctx, game, stake.address);
|
|
800
|
+
return buildPlannerPlan({
|
|
750
801
|
kind: 'claim-stakes.building-changes',
|
|
751
802
|
preconditions: [
|
|
752
803
|
...(await Promise.all([
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
804
|
+
accountStatePrecondition(freshGame.account, 'The configured Game retains the exact Claim Stake and building definitions.'),
|
|
805
|
+
accountStatePrecondition(stakeAccount, `Claim Stake ${stake.address} retains its ownership, design sequence, buildings, cargo, crew, and Body relationship.`),
|
|
806
|
+
planetPrecondition(bodyAccount, system),
|
|
807
|
+
characterPrecondition(characterAccount, profile),
|
|
808
|
+
systemPrecondition(systemAccount, currentSystem.name),
|
|
809
|
+
playerPrecondition(playerAccount, player, 'Profile, Character, System, and available crew'),
|
|
810
|
+
accountStatePrecondition(profileFactionAccount, `ProfileFaction ${profileFaction} remains assigned to Profile ${profile} and aligned with the current Starbase controller.`),
|
|
760
811
|
])),
|
|
761
812
|
ownershipPrecondition,
|
|
813
|
+
xp.guard,
|
|
762
814
|
],
|
|
763
815
|
steps: [
|
|
764
816
|
{
|
|
765
817
|
describes: description,
|
|
766
818
|
instruction: adaptClaimStakeBuildingChangesInstruction({
|
|
819
|
+
...xp.accounts,
|
|
767
820
|
authorization: options.authorization,
|
|
768
821
|
buildingChanges: options.buildingChanges.map(({ buildingId, kind, quantity }) => [buildingId, kind === 'add' ? quantity : -quantity]),
|
|
769
822
|
celestialBody: stake.body.address,
|
|
@@ -789,6 +842,10 @@ export async function planClaimStakeBuildingChanges(ctx, stake, input) {
|
|
|
789
842
|
* CurrencyCache, and a known positive rent balance. Rent timing and the final
|
|
790
843
|
* crew/building validation remain chain-authoritative.
|
|
791
844
|
*
|
|
845
|
+
* Requires Game 2 and its existing canonical Claim Stake XP ledger.
|
|
846
|
+
* The Character XP budget and configuration must also be reconciled.
|
|
847
|
+
* Missing XP state must be repaired outside this Plan; no accounts are created.
|
|
848
|
+
*
|
|
792
849
|
* @example
|
|
793
850
|
* ```ts
|
|
794
851
|
* declare const ctx: SageContext;
|
|
@@ -804,22 +861,18 @@ export async function planClaimStakeBuildingChanges(ctx, stake, input) {
|
|
|
804
861
|
export async function planFinalizeClaimStakeBuildingChanges(ctx, stake, input) {
|
|
805
862
|
const options = validateFinalizeBuildingChangeOptions(input);
|
|
806
863
|
const game = requireGameAddress(ctx);
|
|
864
|
+
const { profile } = options.authorization;
|
|
807
865
|
if (stake.state.kind !== 'design') {
|
|
808
866
|
fail(`Claim Stake ${stake.address} is not in design state. Refresh it and finalize only a pending building design.`, stake.address);
|
|
809
867
|
}
|
|
810
|
-
|
|
811
|
-
fail(`Claim Stake ${stake.address} does not match the configured Game ${game}. Refresh it through this context and retry.`, stake.address);
|
|
812
|
-
}
|
|
813
|
-
const character = await findCharacterPda(options.authorization.profile, game);
|
|
814
|
-
if (stake.ownerCharacter.address !== character) {
|
|
815
|
-
fail(`Claim Stake ${stake.address} does not belong to authorization Profile ${options.authorization.profile}'s canonical Character ${character}. Choose an owned Claim Stake, refresh it, and retry.`, stake.address);
|
|
816
|
-
}
|
|
868
|
+
const character = await requireOwnedStake(stake, game, profile);
|
|
817
869
|
if (stake.rentBalanceRaw <= 0n) {
|
|
818
870
|
fail(`Claim Stake ${stake.address} has a known delinquent rent balance of ${String(stake.rentBalanceRaw)} raw units. Top up rent, refresh the Claim Stake, and retry finalization.`, stake.address);
|
|
819
871
|
}
|
|
820
|
-
const
|
|
872
|
+
const action = 'finalization';
|
|
873
|
+
const [freshGame, loaded] = await Promise.all([
|
|
821
874
|
readFreshGameClaimStakeConfiguration(ctx),
|
|
822
|
-
|
|
875
|
+
readOwnedStake(ctx, stake, action, [character]),
|
|
823
876
|
]);
|
|
824
877
|
if (freshGame === undefined) {
|
|
825
878
|
fail(`Configured Game ${game} is missing. Refresh the Game catalog and retry finalization.`, game);
|
|
@@ -828,75 +881,40 @@ export async function planFinalizeClaimStakeBuildingChanges(ctx, stake, input) {
|
|
|
828
881
|
freshGame.data.buildings.sequenceId !== stake.buildingDefinitionSeqId) {
|
|
829
882
|
fail(`Claim Stake ${stake.address} definition sequence is stale against the current Game catalog. Refresh the Claim Stake and definitions to rule out stale local data. If the on-chain generation still differs, use a Claim Stake matching the current catalog before retrying finalization.`, stake.address);
|
|
830
883
|
}
|
|
831
|
-
const
|
|
832
|
-
|
|
833
|
-
const characterAccount = requireAccount(firstAccounts[2], character, `Canonical Character ${character} is missing. Refresh the Profile Character and retry finalization.`);
|
|
834
|
-
const currentStake = claimStakeAccountDefinition.decode(stakeAccount);
|
|
835
|
-
const currentBody = celestialBodyAccountDefinition.decode(bodyAccount);
|
|
836
|
-
const currentCharacter = characterAccountDefinition.decode(characterAccount);
|
|
837
|
-
if (currentStake.game !== game ||
|
|
838
|
-
currentStake.body !== stake.body.address ||
|
|
839
|
-
currentStake.ownerCharacter !== character ||
|
|
840
|
-
currentStake.claimStakeDefinitionId !== stake.claimStakeDefinitionId ||
|
|
841
|
-
currentStake.claimStakeDefinitionSeqId !==
|
|
842
|
-
stake.claimStakeDefinitionSeqId ||
|
|
843
|
-
currentStake.buildingDefinitionSeqId !== stake.buildingDefinitionSeqId ||
|
|
844
|
-
currentStake.systemSeqId !== stake.systemSeqId ||
|
|
884
|
+
const { bodyAccount, currentStake, stakeAccount } = loaded;
|
|
885
|
+
if (!sameOwnedStake(currentStake, stake, game, character) ||
|
|
845
886
|
currentStake.rentBalanceRaw !== stake.rentBalanceRaw ||
|
|
846
|
-
!sameQuantities(currentStake.buildings, stake.buildings) ||
|
|
847
887
|
currentStake.state.kind !== 'design' ||
|
|
848
888
|
currentStake.state.sequenceId !== stake.state.sequenceId ||
|
|
849
889
|
!sameQuantities(currentStake.state.buildings, stake.state.buildings)) {
|
|
850
890
|
fail(`Claim Stake ${stake.address} changed or does not match its loaded ownership, Body, definitions, buildings, design sequence, rent, or System generation. Refresh it and retry finalization.`, stake.address);
|
|
851
891
|
}
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
currentBody.game !== game ||
|
|
858
|
-
currentBody.systemSequenceId !== stake.systemSeqId ||
|
|
859
|
-
(await deriveCelestialBodyAddress(game, currentBody.id)) !==
|
|
860
|
-
stake.body.address) {
|
|
861
|
-
fail(`Celestial Body ${stake.body.address} does not match the Claim Stake's configured Game, canonical Planet identity, or System generation. Refresh the Body and Claim Stake before retrying finalization.`, stake.body.address);
|
|
862
|
-
}
|
|
863
|
-
const system = currentBody.system;
|
|
864
|
-
const player = await deriveStarbasePlayerAddress(system, character);
|
|
865
|
-
const currencyCache = await deriveCurrencyCacheAddress(game);
|
|
866
|
-
const [systemCandidate, playerCandidate, currencyCandidate] = await readContextRawAccounts(ctx, [system, player, currencyCache]);
|
|
867
|
-
const systemAccount = requireAccount(systemCandidate, system, `Star System ${system} is missing. Refresh the Claim Stake's System and retry finalization.`);
|
|
868
|
-
const playerAccount = requireAccount(playerCandidate, player, `Starbase Player ${player} is missing for authorization Profile ${options.authorization.profile}. Register or refresh it in the Claim Stake's System before retrying finalization.`);
|
|
869
|
-
const currencyAccount = requireAccount(currencyCandidate, currencyCache, `Canonical CurrencyCache ${currencyCache} is missing for configured Game ${game}. Refresh the Game currency configuration and retry finalization.`);
|
|
870
|
-
const currentSystem = starSystemAccountDefinition.decode(systemAccount);
|
|
871
|
-
const currentPlayer = starbasePlayerAccountDefinition.decode(playerAccount);
|
|
872
|
-
if (currentSystem.game !== game ||
|
|
873
|
-
currentSystem.sequenceId !== stake.systemSeqId ||
|
|
874
|
-
currentSystem.starbase === undefined ||
|
|
875
|
-
(await deriveStarSystemAddress(game, currentSystem.systemId)) !== system) {
|
|
876
|
-
fail(`Star System ${system} does not match the configured Game, canonical identity, Claim Stake generation, or an active nested Starbase. Refresh the System and retry finalization.`, system);
|
|
877
|
-
}
|
|
878
|
-
if (currentPlayer.playerProfile !== options.authorization.profile ||
|
|
879
|
-
currentPlayer.character !== character ||
|
|
880
|
-
currentPlayer.system !== system) {
|
|
881
|
-
fail(`Starbase Player ${player} does not match the authorization Profile, canonical Character, and Claim Stake System. Refresh it and retry finalization.`, player);
|
|
882
|
-
}
|
|
883
|
-
validateCurrencyCache(currencyAccount, game, currencyCache, 'finalization');
|
|
892
|
+
const { system } = await requireStakePlanet(loaded.currentBody, stake, game, action);
|
|
893
|
+
const { account: characterAccount } = requireProfileCharacter(loaded.extraAccounts[0], character, profile, game, action);
|
|
894
|
+
const currencyCache = await claimStakeCurrencyCache(game);
|
|
895
|
+
const { currentSystem, extraAccounts: [currencyCandidate], player, playerAccount, systemAccount, } = await readStakeStarbase(ctx, stake, game, system, character, profile, action, [currencyCache]);
|
|
896
|
+
const currencyGuard = await requireCurrencyCache(currencyCandidate, currencyCache, game, action, 'Claim Stake finalization');
|
|
884
897
|
const description = `Finalize building changes on Claim Stake ${stake.address}.`;
|
|
885
|
-
|
|
898
|
+
const xp = await resolveClaimStakeXp(ctx, game, stake.address, character);
|
|
899
|
+
return buildPlannerPlan({
|
|
886
900
|
kind: 'claim-stakes.finalize-building-changes',
|
|
887
|
-
preconditions:
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
901
|
+
preconditions: [
|
|
902
|
+
xp.guard,
|
|
903
|
+
...(await Promise.all([
|
|
904
|
+
accountStatePrecondition(freshGame.account, 'The configured Game remains current.'),
|
|
905
|
+
accountStatePrecondition(stakeAccount, `Claim Stake ${stake.address} retains its ownership, design sequence, rent balance, Body, and System generation.`),
|
|
906
|
+
characterPrecondition(characterAccount, profile),
|
|
907
|
+
planetPrecondition(bodyAccount, system),
|
|
908
|
+
systemPrecondition(systemAccount, currentSystem.name),
|
|
909
|
+
playerPrecondition(playerAccount, player),
|
|
910
|
+
])),
|
|
911
|
+
currencyGuard,
|
|
912
|
+
],
|
|
896
913
|
steps: [
|
|
897
914
|
{
|
|
898
915
|
describes: description,
|
|
899
916
|
instruction: adaptFinalizeClaimStakeBuildingChangesInstruction({
|
|
917
|
+
...xp.accounts,
|
|
900
918
|
authorization: options.authorization,
|
|
901
919
|
celestialBody: stake.body.address,
|
|
902
920
|
character,
|
|
@@ -920,6 +938,9 @@ export async function planFinalizeClaimStakeBuildingChanges(ctx, stake, input) {
|
|
|
920
938
|
* state; rent arithmetic and concurrent state transitions remain
|
|
921
939
|
* chain-authoritative.
|
|
922
940
|
*
|
|
941
|
+
* Requires Game 2 and its existing canonical Claim Stake XP ledger.
|
|
942
|
+
* Missing XP state must be repaired outside this Plan; no accounts are created.
|
|
943
|
+
*
|
|
923
944
|
* @example
|
|
924
945
|
* ```ts
|
|
925
946
|
* declare const ctx: SageContext;
|
|
@@ -934,80 +955,42 @@ export async function planFinalizeClaimStakeBuildingChanges(ctx, stake, input) {
|
|
|
934
955
|
export async function planCancelClaimStakeBuildingChanges(ctx, stake, input) {
|
|
935
956
|
const options = validateCancelBuildingChangeOptions(input);
|
|
936
957
|
const game = requireGameAddress(ctx);
|
|
958
|
+
const { profile } = options.authorization;
|
|
937
959
|
if (stake.state.kind !== 'design') {
|
|
938
960
|
fail(`Claim Stake ${stake.address} is not in design state. Refresh it and cancel only a pending building design.`, stake.address);
|
|
939
961
|
}
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
}
|
|
943
|
-
|
|
944
|
-
if (stake.ownerCharacter.address !== character) {
|
|
945
|
-
fail(`Claim Stake ${stake.address} does not belong to authorization Profile ${options.authorization.profile}'s canonical Character ${character}. Choose an owned Claim Stake, refresh it, and retry.`, stake.address);
|
|
946
|
-
}
|
|
947
|
-
const firstAccounts = await readContextRawAccounts(ctx, [
|
|
948
|
-
stake.address,
|
|
949
|
-
stake.body.address,
|
|
950
|
-
]);
|
|
951
|
-
const stakeAccount = requireAccount(firstAccounts[0], stake.address, `Claim Stake ${stake.address} is missing. Refresh it and retry cancellation.`);
|
|
952
|
-
const bodyAccount = requireAccount(firstAccounts[1], stake.body.address, `Celestial Body ${stake.body.address} is missing. Refresh the Claim Stake Body and retry cancellation.`);
|
|
953
|
-
const currentStake = claimStakeAccountDefinition.decode(stakeAccount);
|
|
954
|
-
const currentBody = celestialBodyAccountDefinition.decode(bodyAccount);
|
|
955
|
-
if (currentStake.game !== game ||
|
|
956
|
-
currentStake.body !== stake.body.address ||
|
|
957
|
-
currentStake.ownerCharacter !== character ||
|
|
958
|
-
currentStake.claimStakeDefinitionId !== stake.claimStakeDefinitionId ||
|
|
959
|
-
currentStake.claimStakeDefinitionSeqId !==
|
|
960
|
-
stake.claimStakeDefinitionSeqId ||
|
|
961
|
-
currentStake.buildingDefinitionSeqId !== stake.buildingDefinitionSeqId ||
|
|
962
|
-
currentStake.systemSeqId !== stake.systemSeqId ||
|
|
963
|
-
!sameQuantities(currentStake.buildings, stake.buildings) ||
|
|
962
|
+
const character = await requireOwnedStake(stake, game, profile);
|
|
963
|
+
const action = 'cancellation';
|
|
964
|
+
const { bodyAccount, currentBody, currentStake, stakeAccount } = await readOwnedStake(ctx, stake, action);
|
|
965
|
+
if (!sameOwnedStake(currentStake, stake, game, character) ||
|
|
964
966
|
currentStake.state.kind !== 'design' ||
|
|
965
967
|
currentStake.state.sequenceId !== stake.state.sequenceId ||
|
|
966
968
|
!sameQuantities(currentStake.state.buildings, stake.state.buildings)) {
|
|
967
969
|
fail(`Claim Stake ${stake.address} changed or does not match its loaded ownership, Body, definitions, buildings, design sequence, or System generation. Refresh it and retry cancellation.`, stake.address);
|
|
968
970
|
}
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
stake.body.address) {
|
|
974
|
-
fail(`Celestial Body ${stake.body.address} does not match the Claim Stake's configured Game, canonical Planet identity, or System generation. Refresh the Body and Claim Stake before retrying cancellation.`, stake.body.address);
|
|
975
|
-
}
|
|
976
|
-
const system = currentBody.system;
|
|
977
|
-
const player = await deriveStarbasePlayerAddress(system, character);
|
|
978
|
-
const currencyCache = await deriveCurrencyCacheAddress(game);
|
|
979
|
-
const [systemCandidate, playerCandidate, currencyCandidate] = await readContextRawAccounts(ctx, [system, player, currencyCache]);
|
|
980
|
-
const systemAccount = requireAccount(systemCandidate, system, `Star System ${system} is missing. Refresh the Claim Stake's System and retry cancellation.`);
|
|
981
|
-
const playerAccount = requireAccount(playerCandidate, player, `Starbase Player ${player} is missing for authorization Profile ${options.authorization.profile}. Register or refresh it in the Claim Stake's System before retrying cancellation.`);
|
|
982
|
-
const currencyAccount = requireAccount(currencyCandidate, currencyCache, `Canonical CurrencyCache ${currencyCache} is missing for configured Game ${game}. Refresh the Game currency configuration and retry cancellation.`);
|
|
983
|
-
const currentSystem = starSystemAccountDefinition.decode(systemAccount);
|
|
984
|
-
const currentPlayer = starbasePlayerAccountDefinition.decode(playerAccount);
|
|
985
|
-
if (currentSystem.game !== game ||
|
|
986
|
-
currentSystem.sequenceId !== stake.systemSeqId ||
|
|
987
|
-
currentSystem.starbase === undefined ||
|
|
988
|
-
(await deriveStarSystemAddress(game, currentSystem.systemId)) !== system) {
|
|
989
|
-
fail(`Star System ${system} does not match the configured Game, canonical identity, Claim Stake generation, or an active nested Starbase. Refresh the System and retry cancellation.`, system);
|
|
990
|
-
}
|
|
991
|
-
if (currentPlayer.playerProfile !== options.authorization.profile ||
|
|
992
|
-
currentPlayer.character !== character ||
|
|
993
|
-
currentPlayer.system !== system) {
|
|
994
|
-
fail(`Starbase Player ${player} does not match the authorization Profile, canonical Character, and Claim Stake System. Refresh it and retry cancellation.`, player);
|
|
995
|
-
}
|
|
996
|
-
validateCurrencyCache(currencyAccount, game, currencyCache, 'cancellation');
|
|
971
|
+
const { system } = await requireStakePlanet(currentBody, stake, game, action);
|
|
972
|
+
const currencyCache = await claimStakeCurrencyCache(game);
|
|
973
|
+
const { currentSystem, extraAccounts: [currencyCandidate], player, playerAccount, systemAccount, } = await readStakeStarbase(ctx, stake, game, system, character, profile, action, [currencyCache]);
|
|
974
|
+
const currencyGuard = await requireCurrencyCache(currencyCandidate, currencyCache, game, action, 'Claim Stake cancellation');
|
|
997
975
|
const description = `Cancel the pending building design on Claim Stake ${stake.address} and return it to active state.`;
|
|
998
|
-
|
|
976
|
+
const xp = await resolveClaimStakeXp(ctx, game, stake.address);
|
|
977
|
+
return buildPlannerPlan({
|
|
999
978
|
kind: 'claim-stakes.cancel-building-changes',
|
|
1000
|
-
preconditions:
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
979
|
+
preconditions: [
|
|
980
|
+
xp.guard,
|
|
981
|
+
...(await Promise.all([
|
|
982
|
+
accountStatePrecondition(stakeAccount, `Claim Stake ${stake.address} retains its ownership, design sequence, buildings, Body, and System generation.`),
|
|
983
|
+
planetPrecondition(bodyAccount, system),
|
|
984
|
+
systemPrecondition(systemAccount, currentSystem.name),
|
|
985
|
+
playerPrecondition(playerAccount, player),
|
|
986
|
+
])),
|
|
987
|
+
currencyGuard,
|
|
988
|
+
],
|
|
1007
989
|
steps: [
|
|
1008
990
|
{
|
|
1009
991
|
describes: description,
|
|
1010
992
|
instruction: adaptCancelClaimStakeBuildingChangesInstruction({
|
|
993
|
+
...xp.accounts,
|
|
1011
994
|
authorization: options.authorization,
|
|
1012
995
|
celestialBody: stake.body.address,
|
|
1013
996
|
claimStakeInstance: stake.address,
|
|
@@ -1043,46 +1026,25 @@ export async function planCancelClaimStakeBuildingChanges(ctx, stake, input) {
|
|
|
1043
1026
|
export async function planDeconstructClaimStake(ctx, stake, input) {
|
|
1044
1027
|
const options = validateDeconstructOptions(input);
|
|
1045
1028
|
const game = requireGameAddress(ctx);
|
|
1029
|
+
const { profile } = options.authorization;
|
|
1046
1030
|
if (stake.state.kind !== 'active') {
|
|
1047
1031
|
fail(`Claim Stake ${stake.address} is not in active state. Refresh it, finalize or cancel any pending design, and retry deconstruction.`, stake.address);
|
|
1048
1032
|
}
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
}
|
|
1052
|
-
const character = await findCharacterPda(options.authorization.profile, game);
|
|
1053
|
-
if (stake.ownerCharacter.address !== character) {
|
|
1054
|
-
fail(`Claim Stake ${stake.address} does not belong to authorization Profile ${options.authorization.profile}'s canonical Character ${character}. Choose an owned Claim Stake, refresh it, and retry.`, stake.address);
|
|
1055
|
-
}
|
|
1056
|
-
const [freshGame, firstAccounts] = await Promise.all([
|
|
1033
|
+
const character = await requireOwnedStake(stake, game, profile);
|
|
1034
|
+
const action = 'deconstruction';
|
|
1035
|
+
const [freshGame, { bodyAccount, currentBody, currentStake, stakeAccount }] = await Promise.all([
|
|
1057
1036
|
readFreshGameClaimStakeConfiguration(ctx),
|
|
1058
|
-
|
|
1037
|
+
readOwnedStake(ctx, stake, action),
|
|
1059
1038
|
]);
|
|
1060
1039
|
if (freshGame === undefined) {
|
|
1061
1040
|
fail(`Configured Game ${game} is missing. Refresh the Game definitions and retry deconstruction.`, game);
|
|
1062
1041
|
}
|
|
1063
|
-
|
|
1064
|
-
const bodyAccount = requireAccount(firstAccounts[1], stake.body.address, `Celestial Body ${stake.body.address} is missing. Refresh the Claim Stake Body and retry deconstruction.`);
|
|
1065
|
-
const currentStake = claimStakeAccountDefinition.decode(stakeAccount);
|
|
1066
|
-
const currentBody = decodeIndexedCelestialBodyAccount(bodyAccount);
|
|
1067
|
-
if (currentStake.game !== game ||
|
|
1068
|
-
currentStake.body !== stake.body.address ||
|
|
1069
|
-
currentStake.ownerCharacter !== character ||
|
|
1070
|
-
currentStake.claimStakeDefinitionId !== stake.claimStakeDefinitionId ||
|
|
1071
|
-
currentStake.claimStakeDefinitionSeqId !==
|
|
1072
|
-
stake.claimStakeDefinitionSeqId ||
|
|
1073
|
-
currentStake.buildingDefinitionSeqId !== stake.buildingDefinitionSeqId ||
|
|
1074
|
-
currentStake.systemSeqId !== stake.systemSeqId ||
|
|
1075
|
-
!sameQuantities(currentStake.buildings, stake.buildings) ||
|
|
1042
|
+
if (!sameOwnedStake(currentStake, stake, game, character) ||
|
|
1076
1043
|
currentStake.state.kind !== 'active') {
|
|
1077
1044
|
fail(`Claim Stake ${stake.address} changed or does not match its loaded ownership, Body, definitions, buildings, active state, or System generation. Refresh it and retry deconstruction.`, stake.address);
|
|
1078
1045
|
}
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
currentBody.systemSequenceId !== stake.systemSeqId ||
|
|
1082
|
-
(await deriveCelestialBodyAddress(game, currentBody.id)) !==
|
|
1083
|
-
stake.body.address) {
|
|
1084
|
-
fail(`Celestial Body ${stake.body.address} does not match the Claim Stake's configured Game, canonical Planet identity, or System generation. Refresh the Body and Claim Stake before retrying deconstruction.`, stake.body.address);
|
|
1085
|
-
}
|
|
1046
|
+
const planet = await requireStakePlanet(currentBody, stake, game, action);
|
|
1047
|
+
const { system } = planet;
|
|
1086
1048
|
if (freshGame.data.claimStakes.sequenceId !== stake.claimStakeDefinitionSeqId) {
|
|
1087
1049
|
fail(`Claim Stake ${stake.address} definition generation is stale against the current Game catalog. Refresh the Claim Stake and definitions to rule out stale local data. If the on-chain generation still differs, use a Claim Stake matching the current catalog before retrying deconstruction.`, stake.address);
|
|
1088
1050
|
}
|
|
@@ -1104,18 +1066,19 @@ export async function planDeconstructClaimStake(ctx, stake, input) {
|
|
|
1104
1066
|
bundledHub.hubValue !== claimDefinition.hubValue ||
|
|
1105
1067
|
bundledHub.minimumTier !== claimDefinition.tier ||
|
|
1106
1068
|
bundledHub.constructionCost.length !== 0) {
|
|
1069
|
+
// Only a building with a construction cost is player-funded; a zero-cost
|
|
1070
|
+
// hub from another definition family is a foreign bundled hub.
|
|
1107
1071
|
const hasPlayerFundedBuilding = stake.buildings.some((building) => {
|
|
1108
1072
|
const definition = definitions.get(building.buildingId);
|
|
1109
|
-
return (definition
|
|
1110
|
-
definition.hubValue !== claimDefinition.hubValue ||
|
|
1111
|
-
definition.minimumTier !== claimDefinition.tier ||
|
|
1112
|
-
definition.constructionCost.length !== 0);
|
|
1073
|
+
return (definition !== undefined && definition.constructionCost.length !== 0);
|
|
1113
1074
|
});
|
|
1114
1075
|
fail(hasPlayerFundedBuilding
|
|
1115
1076
|
? `Claim Stake ${stake.address} still contains a player-funded building. Remove and finalize every player-funded building so only its verified bundled hub remains before retrying deconstruction.`
|
|
1116
|
-
:
|
|
1077
|
+
: bundledHub === undefined
|
|
1078
|
+
? `Claim Stake ${stake.address} does not contain exactly one verified bundled hub. Refresh it and restore the definition-compatible bundled hub before retrying deconstruction.`
|
|
1079
|
+
: `Claim Stake ${stake.address} holds ${bundledHub.name} (${String(bundledHub.id)}), which is not the zero-cost ${claimDefinition.tier} bundled hub for Claim Stake definition ${String(claimDefinition.id)} (${claimDefinition.name}). Refresh the Claim Stake and Game definitions so the recorded hub matches its definition before retrying deconstruction.`, stake.address);
|
|
1117
1080
|
}
|
|
1118
|
-
const groups =
|
|
1081
|
+
const groups = planet.details.claimedPlots.filter(({ key }) => key === claimDefinition.id);
|
|
1119
1082
|
if (groups.length !== 1) {
|
|
1120
1083
|
fail(`Claim Stake definition ${String(claimDefinition.id)} does not have exactly one coherent group in Planet ${stake.body.address}'s Claim Stake Body data. Refresh the Body before retrying deconstruction.`, stake.body.address);
|
|
1121
1084
|
}
|
|
@@ -1132,7 +1095,7 @@ export async function planDeconstructClaimStake(ctx, stake, input) {
|
|
|
1132
1095
|
}
|
|
1133
1096
|
const claimStakeIndex = chronologyMatches[0].index;
|
|
1134
1097
|
const tierIndex = TIER_INDEX[claimDefinition.tier];
|
|
1135
|
-
const plotCapacities =
|
|
1098
|
+
const plotCapacities = planet.details.claimStakePlots.map((row) => row[tierIndex]);
|
|
1136
1099
|
if (plotCapacities.some((capacity, index) => index > 0 && capacity < plotCapacities[index - 1])) {
|
|
1137
1100
|
fail(`Planet ${stake.body.address} Claim Stake plot capacity is not coherent across Starbase levels for definition tier ${claimDefinition.tier}. Refresh the Body and verify the pinned binding version before retrying deconstruction.`, stake.body.address);
|
|
1138
1101
|
}
|
|
@@ -1141,41 +1104,18 @@ export async function planDeconstructClaimStake(ctx, stake, input) {
|
|
|
1141
1104
|
}
|
|
1142
1105
|
const plotLevelIndex = plotCapacities.findIndex((capacity) => claimStakeIndex < capacity);
|
|
1143
1106
|
const claimStakeLevel = CLAIM_STAKE_PLOT_LEVELS[plotLevelIndex];
|
|
1144
|
-
const
|
|
1145
|
-
const
|
|
1146
|
-
const [characterCandidate, systemCandidate, playerCandidate] = await readContextRawAccounts(ctx, [character, system, player]);
|
|
1147
|
-
const characterAccount = requireAccount(characterCandidate, character, `Canonical Character ${character} is missing. Refresh the Profile Character and retry deconstruction.`);
|
|
1148
|
-
const systemAccount = requireAccount(systemCandidate, system, `Star System ${system} is missing. Refresh the Claim Stake's System and retry deconstruction.`);
|
|
1149
|
-
const playerAccount = requireAccount(playerCandidate, player, `Starbase Player ${player} is missing for authorization Profile ${options.authorization.profile}. Register or refresh it in the Claim Stake's System before retrying deconstruction.`);
|
|
1150
|
-
const currentCharacter = characterAccountDefinition.decode(characterAccount);
|
|
1151
|
-
const currentSystem = starSystemAccountDefinition.decode(systemAccount);
|
|
1152
|
-
const currentPlayer = starbasePlayerAccountDefinition.decode(playerAccount);
|
|
1153
|
-
if (currentCharacter.playerProfile !== options.authorization.profile ||
|
|
1154
|
-
currentCharacter.game !== game) {
|
|
1155
|
-
fail(`Character ${character} does not match authorization Profile ${options.authorization.profile} and configured Game ${game}. Refresh the Character and retry deconstruction.`, character);
|
|
1156
|
-
}
|
|
1157
|
-
if (currentSystem.game !== game ||
|
|
1158
|
-
currentSystem.sequenceId !== stake.systemSeqId ||
|
|
1159
|
-
currentSystem.starbase === undefined ||
|
|
1160
|
-
!currentSystem.celestialBodyAddresses.includes(stake.body.address) ||
|
|
1161
|
-
(await deriveStarSystemAddress(game, currentSystem.systemId)) !== system) {
|
|
1162
|
-
fail(`Star System ${system} does not match the configured Game, canonical identity, Claim Stake generation, or an active nested Starbase. Refresh the System and retry deconstruction.`, system);
|
|
1163
|
-
}
|
|
1164
|
-
if (currentPlayer.playerProfile !== options.authorization.profile ||
|
|
1165
|
-
currentPlayer.character !== character ||
|
|
1166
|
-
currentPlayer.system !== system) {
|
|
1167
|
-
fail(`Starbase Player ${player} does not match the authorization Profile, canonical Character, and Claim Stake System. Refresh it and retry deconstruction.`, player);
|
|
1168
|
-
}
|
|
1107
|
+
const { currentSystem, extraAccounts: [characterCandidate], player, playerAccount, systemAccount, } = await readStakeStarbase(ctx, stake, game, system, character, profile, action, [character]);
|
|
1108
|
+
const { account: characterAccount } = requireProfileCharacter(characterCandidate, character, profile, game, action);
|
|
1169
1109
|
const description = `Deconstruct Claim Stake ${stake.address} and discard its bundled hub ${bundledHub.name}; rent settlement, cargo return, account closure, and any refund remain chain-authoritative.`;
|
|
1170
|
-
return
|
|
1110
|
+
return buildPlannerPlan({
|
|
1171
1111
|
kind: 'claim-stakes.deconstruct',
|
|
1172
1112
|
preconditions: await Promise.all([
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1113
|
+
accountStatePrecondition(freshGame.account, `The configured Game retains Claim Stake definition ${String(claimDefinition.id)}, bundled hub ${String(bundledHub.id)}, and their current generations.`),
|
|
1114
|
+
accountStatePrecondition(stakeAccount, `Claim Stake ${stake.address} retains its ownership, active state, definitions, bundled hub, Body, and System generation.`),
|
|
1115
|
+
accountStatePrecondition(bodyAccount, `The Planet retains Claim Stake ${stake.address} at chronology index ${String(claimStakeIndex)} in definition group ${String(claimDefinition.id)}.`),
|
|
1116
|
+
characterPrecondition(characterAccount, profile),
|
|
1117
|
+
systemPrecondition(systemAccount, currentSystem.name),
|
|
1118
|
+
playerPrecondition(playerAccount, player),
|
|
1179
1119
|
]),
|
|
1180
1120
|
steps: [
|
|
1181
1121
|
{
|
|
@@ -1219,86 +1159,34 @@ export async function planDeconstructClaimStake(ctx, stake, input) {
|
|
|
1219
1159
|
export async function planTopUpClaimStakeRent(ctx, stake, input) {
|
|
1220
1160
|
const options = validateTopUpRentOptions(input);
|
|
1221
1161
|
const game = requireGameAddress(ctx);
|
|
1162
|
+
const { profile } = options.authorization;
|
|
1222
1163
|
const loadedState = stake.state;
|
|
1223
1164
|
if (loadedState.kind === 'deactivated') {
|
|
1224
1165
|
fail(`Claim Stake ${stake.address} is not placed. Refresh it and choose an active Claim Stake or pending building design before topping up rent.`, stake.address);
|
|
1225
1166
|
}
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
}
|
|
1229
|
-
|
|
1230
|
-
if (stake.ownerCharacter.address !== character) {
|
|
1231
|
-
fail(`Claim Stake ${stake.address} does not belong to authorization Profile ${options.authorization.profile}'s canonical Character ${character}. Choose an owned Claim Stake, refresh it, and retry.`, stake.address);
|
|
1232
|
-
}
|
|
1233
|
-
const firstAccounts = await readContextRawAccounts(ctx, [
|
|
1234
|
-
stake.address,
|
|
1235
|
-
stake.body.address,
|
|
1236
|
-
character,
|
|
1237
|
-
]);
|
|
1238
|
-
const stakeAccount = requireAccount(firstAccounts[0], stake.address, `Claim Stake ${stake.address} is missing. Refresh it and retry the rent top-up.`);
|
|
1239
|
-
const bodyAccount = requireAccount(firstAccounts[1], stake.body.address, `Celestial Body ${stake.body.address} is missing. Refresh the Claim Stake Body and retry the rent top-up.`);
|
|
1240
|
-
const characterAccount = requireAccount(firstAccounts[2], character, `Canonical Character ${character} is missing. Refresh the Profile Character and retry the rent top-up.`);
|
|
1241
|
-
const currentStake = claimStakeAccountDefinition.decode(stakeAccount);
|
|
1242
|
-
const currentBody = celestialBodyAccountDefinition.decode(bodyAccount);
|
|
1243
|
-
const currentCharacter = characterAccountDefinition.decode(characterAccount);
|
|
1244
|
-
if (currentStake.game !== game ||
|
|
1245
|
-
currentStake.body !== stake.body.address ||
|
|
1246
|
-
currentStake.ownerCharacter !== character ||
|
|
1247
|
-
currentStake.claimStakeDefinitionId !== stake.claimStakeDefinitionId ||
|
|
1248
|
-
currentStake.claimStakeDefinitionSeqId !==
|
|
1249
|
-
stake.claimStakeDefinitionSeqId ||
|
|
1250
|
-
currentStake.buildingDefinitionSeqId !== stake.buildingDefinitionSeqId ||
|
|
1251
|
-
currentStake.systemSeqId !== stake.systemSeqId ||
|
|
1167
|
+
const character = await requireOwnedStake(stake, game, profile);
|
|
1168
|
+
const action = 'the rent top-up';
|
|
1169
|
+
const { bodyAccount, currentBody, currentStake, extraAccounts: [characterCandidate], stakeAccount, } = await readOwnedStake(ctx, stake, action, [character]);
|
|
1170
|
+
if (!sameOwnedStake(currentStake, stake, game, character) ||
|
|
1252
1171
|
currentStake.rentBalanceRaw !== stake.rentBalanceRaw ||
|
|
1253
|
-
!sameQuantities(currentStake.buildings, stake.buildings) ||
|
|
1254
1172
|
!sameStakeState(currentStake.state, loadedState)) {
|
|
1255
1173
|
fail(`Claim Stake ${stake.address} changed or does not match its loaded ownership, Body, definitions, buildings, rent balance, placed state, or System generation. Refresh it and retry the rent top-up.`, stake.address);
|
|
1256
1174
|
}
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
currentBody.systemSequenceId !== stake.systemSeqId ||
|
|
1260
|
-
(await deriveCelestialBodyAddress(game, currentBody.id)) !==
|
|
1261
|
-
stake.body.address) {
|
|
1262
|
-
fail(`Celestial Body ${stake.body.address} does not match the Claim Stake's configured Game, canonical Planet identity, or System generation. Refresh the Body and Claim Stake before retrying the rent top-up.`, stake.body.address);
|
|
1263
|
-
}
|
|
1264
|
-
if (currentCharacter.playerProfile !== options.authorization.profile ||
|
|
1265
|
-
currentCharacter.game !== game) {
|
|
1266
|
-
fail(`Character ${character} does not match authorization Profile ${options.authorization.profile} and configured Game ${game}. Refresh the Character and retry the rent top-up.`, character);
|
|
1267
|
-
}
|
|
1175
|
+
const { system } = await requireStakePlanet(currentBody, stake, game, action);
|
|
1176
|
+
const { account: characterAccount, current: currentCharacter } = requireProfileCharacter(characterCandidate, character, profile, game, action);
|
|
1268
1177
|
if (currentCharacter.atlasRaw < options.amount) {
|
|
1269
1178
|
fail(`Character ${character} has only ${String(currentCharacter.atlasRaw)} known raw ATLAS, below the requested ${String(options.amount)} raw rent top-up. Reduce the amount or add ATLAS, refresh the Character, and retry.`, character);
|
|
1270
1179
|
}
|
|
1271
|
-
const
|
|
1272
|
-
const player = await deriveStarbasePlayerAddress(system, character);
|
|
1273
|
-
const [systemCandidate, playerCandidate] = await readContextRawAccounts(ctx, [
|
|
1274
|
-
system,
|
|
1275
|
-
player,
|
|
1276
|
-
]);
|
|
1277
|
-
const systemAccount = requireAccount(systemCandidate, system, `Star System ${system} is missing. Refresh the Claim Stake's System and retry the rent top-up.`);
|
|
1278
|
-
const playerAccount = requireAccount(playerCandidate, player, `Starbase Player ${player} is missing for authorization Profile ${options.authorization.profile}. Register or refresh it in the Claim Stake's System before retrying the rent top-up.`);
|
|
1279
|
-
const currentSystem = starSystemAccountDefinition.decode(systemAccount);
|
|
1280
|
-
const currentPlayer = starbasePlayerAccountDefinition.decode(playerAccount);
|
|
1281
|
-
if (currentSystem.game !== game ||
|
|
1282
|
-
currentSystem.sequenceId !== stake.systemSeqId ||
|
|
1283
|
-
currentSystem.starbase === undefined ||
|
|
1284
|
-
!currentSystem.celestialBodyAddresses.includes(stake.body.address) ||
|
|
1285
|
-
(await deriveStarSystemAddress(game, currentSystem.systemId)) !== system) {
|
|
1286
|
-
fail(`Star System ${system} does not match the configured Game, canonical identity, Claim Stake generation, active nested Starbase, or Claim Stake Body relationship. Refresh the System and retry the rent top-up.`, system);
|
|
1287
|
-
}
|
|
1288
|
-
if (currentPlayer.playerProfile !== options.authorization.profile ||
|
|
1289
|
-
currentPlayer.character !== character ||
|
|
1290
|
-
currentPlayer.system !== system) {
|
|
1291
|
-
fail(`Starbase Player ${player} does not match the authorization Profile, canonical Character, and Claim Stake System. Refresh it and retry the rent top-up.`, player);
|
|
1292
|
-
}
|
|
1180
|
+
const { currentSystem, player, playerAccount, systemAccount } = await readStakeStarbase(ctx, stake, game, system, character, profile, action);
|
|
1293
1181
|
const description = `Top up Claim Stake ${stake.address} rent with ${String(options.amount)} raw rent units; rent arithmetic remains chain-authoritative.`;
|
|
1294
|
-
return
|
|
1182
|
+
return buildPlannerPlan({
|
|
1295
1183
|
kind: 'claim-stakes.top-up-rent',
|
|
1296
1184
|
preconditions: await Promise.all([
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1185
|
+
accountStatePrecondition(stakeAccount, `Claim Stake ${stake.address} retains its ownership, rent balance, placed state, Body, and System generation.`),
|
|
1186
|
+
planetPrecondition(bodyAccount, system),
|
|
1187
|
+
accountStatePrecondition(characterAccount, `The canonical Character remains assigned to Profile ${profile} with at least ${String(options.amount)} known raw ATLAS.`),
|
|
1188
|
+
systemPrecondition(systemAccount, currentSystem.name),
|
|
1189
|
+
playerPrecondition(playerAccount, player),
|
|
1302
1190
|
]),
|
|
1303
1191
|
steps: [
|
|
1304
1192
|
{
|
|
@@ -1357,6 +1245,9 @@ function describeCargoRequests(direction, requests) {
|
|
|
1357
1245
|
* FleetCrewBinding. The chain remains authoritative for range, duration,
|
|
1358
1246
|
* permission bits, concurrent state changes, and transfer arithmetic.
|
|
1359
1247
|
*
|
|
1248
|
+
* Requires Game 2 and its existing canonical Claim Stake XP ledger.
|
|
1249
|
+
* Missing XP state must be repaired outside this Plan; no accounts are created.
|
|
1250
|
+
*
|
|
1360
1251
|
* @example
|
|
1361
1252
|
* ```ts
|
|
1362
1253
|
* declare const ctx: SageContext;
|
|
@@ -1374,119 +1265,53 @@ function describeCargoRequests(direction, requests) {
|
|
|
1374
1265
|
export async function planStartClaimStakeFleetTransfer(ctx, fleet, stake, input) {
|
|
1375
1266
|
const options = validateStartFleetTransferOptions(input);
|
|
1376
1267
|
const game = requireGameAddress(ctx);
|
|
1268
|
+
const { profile } = options.authorization;
|
|
1377
1269
|
if (fleet.game !== game || stake.game !== game) {
|
|
1378
1270
|
fail(`Fleet ${fleet.address} and Claim Stake ${stake.address} must both belong to configured Game ${game}. Refresh both snapshots through this context and retry.`, fleet.game !== game ? fleet.address : stake.address);
|
|
1379
1271
|
}
|
|
1380
|
-
if (fleet.ownerProfile.address !==
|
|
1381
|
-
fail(`Fleet ${fleet.name} belongs to Profile ${fleet.ownerProfile.address}, not authorization Profile ${
|
|
1272
|
+
if (fleet.ownerProfile.address !== profile) {
|
|
1273
|
+
fail(`Fleet ${fleet.name} belongs to Profile ${fleet.ownerProfile.address}, not authorization Profile ${profile}. Use the owning Profile, refresh the Fleet, and retry.`, fleet.address);
|
|
1382
1274
|
}
|
|
1383
1275
|
if (fleet.state.kind !== 'idle') {
|
|
1384
1276
|
fail(`Fleet ${fleet.name} is ${fleet.state.kind}, but starting a Claim Stake transfer requires an idle Fleet. Return it to idle state, refresh it, and retry.`, fleet.address);
|
|
1385
1277
|
}
|
|
1278
|
+
const crewFailure = `Fleet ${fleet.name} has no valid normalized crew and cannot start a Claim Stake transfer. Crew the Fleet, refresh it, and retry.`;
|
|
1386
1279
|
if (!Number.isSafeInteger(fleet.crewCount) || fleet.crewCount <= 0) {
|
|
1387
|
-
fail(
|
|
1280
|
+
fail(crewFailure, fleet.address);
|
|
1388
1281
|
}
|
|
1389
1282
|
if (stake.state.kind !== 'active') {
|
|
1390
1283
|
fail(`Claim Stake ${stake.address} is ${stake.state.kind}, but starting a Fleet transfer requires an active Claim Stake. Activate or restore it, refresh it, and retry.`, stake.address);
|
|
1391
1284
|
}
|
|
1392
|
-
const character = await
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
}
|
|
1396
|
-
const [fleetCandidate, stakeCandidate, bodyCandidate, characterCandidate] = await readContextRawAccounts(ctx, [
|
|
1397
|
-
fleet.address,
|
|
1398
|
-
stake.address,
|
|
1399
|
-
stake.body.address,
|
|
1400
|
-
character,
|
|
1401
|
-
]);
|
|
1402
|
-
const fleetAccount = requireAccount(fleetCandidate, fleet.address, `Fleet ${fleet.name} is missing. Refresh it and retry the Claim Stake transfer.`);
|
|
1403
|
-
const stakeAccount = requireAccount(stakeCandidate, stake.address, `Claim Stake ${stake.address} is missing. Refresh it and retry the Fleet transfer.`);
|
|
1404
|
-
const bodyAccount = requireAccount(bodyCandidate, stake.body.address, `Celestial Body ${stake.body.address} is missing. Refresh the Claim Stake Body and retry the Fleet transfer.`);
|
|
1405
|
-
const characterAccount = requireAccount(characterCandidate, character, `Canonical Character ${character} is missing. Refresh the Profile Character and retry the Claim Stake transfer.`);
|
|
1285
|
+
const character = await requireOwnedStake(stake, game, profile);
|
|
1286
|
+
const action = 'the Fleet transfer';
|
|
1287
|
+
const { bodyAccount, currentBody, currentStake, extraAccounts: [fleetCandidate, characterCandidate], stakeAccount, } = await readOwnedStake(ctx, stake, action, [fleet.address, character]);
|
|
1288
|
+
const fleetAccount = requireAccount(fleetCandidate, fleet.address, `Fleet ${fleet.name} is missing. Refresh it and retry the Fleet transfer.`);
|
|
1406
1289
|
const currentFleet = fleetAccountDefinition.decode(fleetAccount);
|
|
1407
|
-
const currentStake = claimStakeAccountDefinition.decode(stakeAccount);
|
|
1408
|
-
const currentBody = celestialBodyAccountDefinition.decode(bodyAccount);
|
|
1409
|
-
const currentCharacter = characterAccountDefinition.decode(characterAccount);
|
|
1410
1290
|
if (!Number.isSafeInteger(currentFleet.crewCount) ||
|
|
1411
1291
|
currentFleet.crewCount <= 0) {
|
|
1412
|
-
fail(
|
|
1292
|
+
fail(crewFailure, fleet.address);
|
|
1413
1293
|
}
|
|
1414
|
-
if (currentFleet
|
|
1415
|
-
currentFleet.ownerProfile !== options.authorization.profile ||
|
|
1416
|
-
currentFleet.name !== fleet.name ||
|
|
1294
|
+
if (!sameTransferFleet(currentFleet, fleet, game, profile) ||
|
|
1417
1295
|
currentFleet.state.kind !== 'idle' ||
|
|
1418
1296
|
currentFleet.crewCount !== fleet.crewCount ||
|
|
1419
|
-
(await deriveFleetAddress(currentFleet)) !== fleet.address
|
|
1420
|
-
currentFleet.ammoBank.cargoId !== fleet.ammo.id ||
|
|
1421
|
-
currentFleet.ammoBank.amount !== fleet.ammo.amount ||
|
|
1422
|
-
currentFleet.fuelTank.cargoId !== fleet.fuel.id ||
|
|
1423
|
-
currentFleet.fuelTank.amount !== fleet.fuel.amount ||
|
|
1424
|
-
currentFleet.cargoHold.storageCost !== fleet.cargoHold.storageCost ||
|
|
1425
|
-
!sameCargoAmounts(currentFleet.cargoHold.amounts, fleet.cargoHold.items) ||
|
|
1426
|
-
currentFleet.stats.cargo.ammoCapacity !== fleet.capacities.ammo.total ||
|
|
1427
|
-
currentFleet.stats.cargo.fuelCapacity !== fleet.capacities.fuel.total ||
|
|
1428
|
-
currentFleet.stats.cargo.cargoCapacity !== fleet.capacities.cargo.total) {
|
|
1297
|
+
(await deriveFleetAddress(currentFleet)) !== fleet.address) {
|
|
1429
1298
|
fail(`Fleet ${fleet.name} changed or no longer matches its loaded Game, owner, canonical address, name, idle state, normalized crew, cargo, or capacities. Refresh it and create a new Claim Stake transfer Plan.`, fleet.address);
|
|
1430
1299
|
}
|
|
1431
|
-
if (currentStake
|
|
1432
|
-
currentStake.ownerCharacter !== character ||
|
|
1433
|
-
currentStake.body !== stake.body.address ||
|
|
1434
|
-
currentStake.systemSeqId !== stake.systemSeqId ||
|
|
1435
|
-
currentStake.state.kind !== 'active' ||
|
|
1436
|
-
currentStake.production.cargoPod.storageCost !==
|
|
1437
|
-
stake.resources.capacity.usedRaw ||
|
|
1438
|
-
currentStake.production.resourceCapacityRaw !==
|
|
1439
|
-
stake.resources.capacity.totalRaw ||
|
|
1440
|
-
!sameCargoAmounts(currentStake.production.cargoPod.amounts, stake.resources.inventory.items.map(({ id, quantityRaw }) => ({
|
|
1441
|
-
amount: quantityRaw,
|
|
1442
|
-
id,
|
|
1443
|
-
})))) {
|
|
1300
|
+
if (!sameTransferStake(currentStake, stake, game, character)) {
|
|
1444
1301
|
fail(`Claim Stake ${stake.address} changed or no longer matches its loaded Game, owner, Body, active state, resources, capacity, or System generation. Refresh it and create a new Fleet transfer Plan.`, stake.address);
|
|
1445
1302
|
}
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
(
|
|
1450
|
-
|
|
1451
|
-
fail(`Celestial Body ${stake.body.address} does not match the Claim Stake's configured Game, canonical Planet identity, or System generation. Refresh the Body and Claim Stake before retrying the Fleet transfer.`, stake.body.address);
|
|
1452
|
-
}
|
|
1453
|
-
if (currentCharacter.playerProfile !== options.authorization.profile ||
|
|
1454
|
-
currentCharacter.game !== game) {
|
|
1455
|
-
fail(`Character ${character} does not match authorization Profile ${options.authorization.profile} and configured Game ${game}. Refresh the Character and retry the Claim Stake transfer.`, character);
|
|
1456
|
-
}
|
|
1457
|
-
const system = currentBody.system;
|
|
1458
|
-
const player = await deriveStarbasePlayerAddress(system, character);
|
|
1459
|
-
const currencyCache = await deriveCurrencyCacheAddress(game);
|
|
1460
|
-
const crewBinding = await deriveFleetCrewBindingAddress(fleet.address);
|
|
1461
|
-
const [systemCandidate, playerCandidate, currencyCandidate, crewCandidate] = await readContextRawAccounts(ctx, [
|
|
1462
|
-
system,
|
|
1463
|
-
player,
|
|
1464
|
-
currencyCache,
|
|
1465
|
-
crewBinding,
|
|
1303
|
+
const { system } = await requireStakePlanet(currentBody, stake, game, action);
|
|
1304
|
+
const { account: characterAccount } = requireProfileCharacter(characterCandidate, character, profile, game, action);
|
|
1305
|
+
const [currencyCache, crewBinding] = await Promise.all([
|
|
1306
|
+
claimStakeCurrencyCache(game),
|
|
1307
|
+
deriveFleetCrewBindingAddress(fleet.address),
|
|
1466
1308
|
]);
|
|
1467
|
-
const
|
|
1468
|
-
const
|
|
1469
|
-
const currencyAccount = requireAccount(currencyCandidate, currencyCache, `Canonical CurrencyCache ${currencyCache} is missing for configured Game ${game}. Refresh the Game currency configuration and retry the Fleet transfer.`);
|
|
1470
|
-
const currentSystem = starSystemAccountDefinition.decode(systemAccount);
|
|
1471
|
-
const currentPlayer = starbasePlayerAccountDefinition.decode(playerAccount);
|
|
1472
|
-
if (currentSystem.game !== game ||
|
|
1473
|
-
currentSystem.sequenceId !== stake.systemSeqId ||
|
|
1474
|
-
currentSystem.starbase === undefined ||
|
|
1475
|
-
!currentSystem.celestialBodyAddresses.includes(stake.body.address) ||
|
|
1476
|
-
(await deriveStarSystemAddress(game, currentSystem.systemId)) !== system) {
|
|
1477
|
-
fail(`Star System ${system} does not match the configured Game, canonical identity, Claim Stake generation, nested Starbase, or Claim Stake Body relationship. Refresh the System and retry the Fleet transfer.`, system);
|
|
1478
|
-
}
|
|
1479
|
-
if (currentPlayer.playerProfile !== options.authorization.profile ||
|
|
1480
|
-
currentPlayer.character !== character ||
|
|
1481
|
-
currentPlayer.system !== system) {
|
|
1482
|
-
fail(`Starbase Player ${player} does not match the authorization Profile, canonical Character, and Claim Stake System. Refresh it and retry the Fleet transfer.`, player);
|
|
1483
|
-
}
|
|
1484
|
-
validateCurrencyCache(currencyAccount, game, currencyCache, 'the Claim Stake Fleet transfer');
|
|
1309
|
+
const { currentSystem, extraAccounts: [currencyCandidate, crewCandidate], player, playerAccount, systemAccount, } = await readStakeStarbase(ctx, stake, game, system, character, profile, action, [currencyCache, crewBinding]);
|
|
1310
|
+
const currencyGuard = await requireCurrencyCache(currencyCandidate, currencyCache, game, action, 'Claim Stake Fleet transfer');
|
|
1485
1311
|
if (crewCandidate !== undefined) {
|
|
1486
1312
|
const currentCrewBinding = fleetCrewBindingAccountDefinition.decode(crewCandidate);
|
|
1487
1313
|
if (crewCandidate.address !== crewBinding ||
|
|
1488
|
-
currentCrewBinding
|
|
1489
|
-
currentCrewBinding.ownerProfile !== options.authorization.profile) {
|
|
1314
|
+
!matchesFleetCrewBindingIdentity(currentCrewBinding, fleet.address, profile)) {
|
|
1490
1315
|
fail(`FleetCrewBinding ${crewCandidate.address} does not match Fleet ${fleet.address}, its owner Profile, or its canonical PDA. Refresh the Fleet crew registration or remove the invalid binding before retrying.`, crewCandidate.address);
|
|
1491
1316
|
}
|
|
1492
1317
|
}
|
|
@@ -1509,37 +1334,43 @@ export async function planStartClaimStakeFleetTransfer(ctx, fleet, stake, input)
|
|
|
1509
1334
|
const loadCargoStorage = options.load
|
|
1510
1335
|
.filter(({ cargoId }) => cargoId !== currentFleet.ammoBank.cargoId &&
|
|
1511
1336
|
cargoId !== currentFleet.fuelTank.cargoId)
|
|
1512
|
-
.reduce((total, { amount, cargoId }) => total +
|
|
1337
|
+
.reduce((total, { amount, cargoId }) => total +
|
|
1338
|
+
cargoStorageUnits(amount, definitions.get(cargoId).storageCost), 0n);
|
|
1513
1339
|
requireTransferCapacity(`Fleet ${fleet.name} ammo destination`, fleet.address, currentFleet.ammoBank.amount, loadAmmo, currentFleet.stats.cargo.ammoCapacity);
|
|
1514
1340
|
requireTransferCapacity(`Fleet ${fleet.name} fuel destination`, fleet.address, currentFleet.fuelTank.amount, loadFuel, currentFleet.stats.cargo.fuelCapacity);
|
|
1515
1341
|
requireTransferCapacity(`Fleet ${fleet.name} cargo destination`, fleet.address, currentFleet.cargoHold.storageCost, loadCargoStorage, currentFleet.stats.cargo.cargoCapacity);
|
|
1516
|
-
const unloadStorage = options.unload.reduce((total, { amount, cargoId }) => total + amount
|
|
1342
|
+
const unloadStorage = options.unload.reduce((total, { amount, cargoId }) => total + cargoStorageUnits(amount, definitions.get(cargoId).storageCost), 0n);
|
|
1517
1343
|
requireTransferCapacity(`Claim Stake ${stake.address} resource destination`, stake.address, currentStake.production.cargoPod.storageCost, unloadStorage, currentStake.production.resourceCapacityRaw);
|
|
1518
1344
|
const descriptions = [
|
|
1519
1345
|
...describeCargoRequests('load', options.load),
|
|
1520
1346
|
...describeCargoRequests('unload', options.unload),
|
|
1521
1347
|
];
|
|
1522
1348
|
const description = `Start fleet ${fleet.name}'s transfer to Claim Stake ${stake.address}: ${descriptions.join('; ')}. Range and transfer duration remain chain-authoritative.`;
|
|
1523
|
-
|
|
1349
|
+
const xp = await resolveClaimStakeXp(ctx, game, stake.address);
|
|
1350
|
+
return buildPlannerPlan({
|
|
1524
1351
|
kind: 'claim-stakes.start-fleet-transfer',
|
|
1525
|
-
preconditions:
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1352
|
+
preconditions: [
|
|
1353
|
+
xp.guard,
|
|
1354
|
+
...(await Promise.all([
|
|
1355
|
+
accountStatePrecondition(fleetAccount, `Fleet ${fleet.name} retains its owner, name, idle state, normalized crew, cargo balances, and destination capacities.`),
|
|
1356
|
+
accountStatePrecondition(stakeAccount, `Claim Stake ${stake.address} retains its owner, active state, cargo balances, destination capacity, Body, and System generation.`),
|
|
1357
|
+
planetPrecondition(bodyAccount, system),
|
|
1358
|
+
characterPrecondition(characterAccount, profile),
|
|
1359
|
+
systemPrecondition(systemAccount, currentSystem.name),
|
|
1360
|
+
playerPrecondition(playerAccount, player),
|
|
1361
|
+
...(crewCandidate === undefined
|
|
1362
|
+
? []
|
|
1363
|
+
: [
|
|
1364
|
+
accountStatePrecondition(crewCandidate, `Fleet ${fleet.name}'s optional FleetCrewBinding remains assigned to the Fleet and owner Profile.`),
|
|
1365
|
+
]),
|
|
1366
|
+
])),
|
|
1367
|
+
currencyGuard,
|
|
1368
|
+
],
|
|
1539
1369
|
steps: [
|
|
1540
1370
|
{
|
|
1541
1371
|
describes: description,
|
|
1542
1372
|
instruction: adaptStartClaimStakeFleetTransferInstruction({
|
|
1373
|
+
...xp.accounts,
|
|
1543
1374
|
authorization: options.authorization,
|
|
1544
1375
|
celestialBody: stake.body.address,
|
|
1545
1376
|
character,
|
|
@@ -1606,10 +1437,7 @@ export async function planRecoverClaimStakeFleetTransfer(ctx, fleet, stake, inpu
|
|
|
1606
1437
|
if (options.atUnixSeconds < fleet.state.endAtUnixSeconds) {
|
|
1607
1438
|
fail(`Fleet ${fleet.name}'s Claim Stake transfer lock has not elapsed at Unix timestamp ${String(options.atUnixSeconds)}; it ends at ${String(fleet.state.endAtUnixSeconds)}. Wait until the lock elapses, provide a current timestamp, and retry recovery.`, fleet.address);
|
|
1608
1439
|
}
|
|
1609
|
-
const character = await
|
|
1610
|
-
if (stake.ownerCharacter.address !== character) {
|
|
1611
|
-
fail(`Claim Stake ${stake.address} does not belong to authorization Profile ${options.authorization.profile}'s canonical Character ${character}. Supply the owned current Claim Stake and retry recovery.`, stake.address);
|
|
1612
|
-
}
|
|
1440
|
+
const character = await requireOwnedStake(stake, game, options.authorization.profile);
|
|
1613
1441
|
const [fleetCandidate, stakeCandidate] = await readContextRawAccounts(ctx, [
|
|
1614
1442
|
fleet.address,
|
|
1615
1443
|
stake.address,
|
|
@@ -1618,40 +1446,17 @@ export async function planRecoverClaimStakeFleetTransfer(ctx, fleet, stake, inpu
|
|
|
1618
1446
|
const stakeAccount = requireAccount(stakeCandidate, stake.address, `Claim Stake ${stake.address} is missing. Refresh it and retry Fleet transfer recovery.`);
|
|
1619
1447
|
const currentFleet = fleetAccountDefinition.decode(fleetAccount);
|
|
1620
1448
|
const currentStake = claimStakeAccountDefinition.decode(stakeAccount);
|
|
1621
|
-
if (currentFleet
|
|
1622
|
-
currentFleet.ownerProfile !== options.authorization.profile ||
|
|
1623
|
-
currentFleet.name !== fleet.name ||
|
|
1449
|
+
if (!sameTransferFleet(currentFleet, fleet, game, options.authorization.profile) ||
|
|
1624
1450
|
currentFleet.state.kind !== 'claimStakeTransfer' ||
|
|
1625
1451
|
currentFleet.state.claimStake !== stake.address ||
|
|
1626
1452
|
currentFleet.state.planet !== stake.body.address ||
|
|
1627
1453
|
currentFleet.state.endAtUnixSeconds !== fleet.state.endAtUnixSeconds ||
|
|
1628
1454
|
!sameCargoAmounts(currentFleet.state.load, fleet.state.load) ||
|
|
1629
1455
|
!sameCargoAmounts(currentFleet.state.unload, fleet.state.unload) ||
|
|
1630
|
-
(await deriveFleetAddress(currentFleet)) !== fleet.address
|
|
1631
|
-
currentFleet.ammoBank.cargoId !== fleet.ammo.id ||
|
|
1632
|
-
currentFleet.ammoBank.amount !== fleet.ammo.amount ||
|
|
1633
|
-
currentFleet.fuelTank.cargoId !== fleet.fuel.id ||
|
|
1634
|
-
currentFleet.fuelTank.amount !== fleet.fuel.amount ||
|
|
1635
|
-
currentFleet.cargoHold.storageCost !== fleet.cargoHold.storageCost ||
|
|
1636
|
-
!sameCargoAmounts(currentFleet.cargoHold.amounts, fleet.cargoHold.items) ||
|
|
1637
|
-
currentFleet.stats.cargo.ammoCapacity !== fleet.capacities.ammo.total ||
|
|
1638
|
-
currentFleet.stats.cargo.fuelCapacity !== fleet.capacities.fuel.total ||
|
|
1639
|
-
currentFleet.stats.cargo.cargoCapacity !== fleet.capacities.cargo.total) {
|
|
1456
|
+
(await deriveFleetAddress(currentFleet)) !== fleet.address) {
|
|
1640
1457
|
fail(`Fleet ${fleet.name} changed or no longer matches its loaded owner, Game, canonical address, Claim Stake transfer snapshot, cargo, or capacities. Refresh it and retry recovery.`, fleet.address);
|
|
1641
1458
|
}
|
|
1642
|
-
if (currentStake
|
|
1643
|
-
currentStake.ownerCharacter !== character ||
|
|
1644
|
-
currentStake.body !== stake.body.address ||
|
|
1645
|
-
currentStake.systemSeqId !== stake.systemSeqId ||
|
|
1646
|
-
currentStake.state.kind !== 'active' ||
|
|
1647
|
-
currentStake.production.cargoPod.storageCost !==
|
|
1648
|
-
stake.resources.capacity.usedRaw ||
|
|
1649
|
-
currentStake.production.resourceCapacityRaw !==
|
|
1650
|
-
stake.resources.capacity.totalRaw ||
|
|
1651
|
-
!sameCargoAmounts(currentStake.production.cargoPod.amounts, stake.resources.inventory.items.map(({ id, quantityRaw }) => ({
|
|
1652
|
-
amount: quantityRaw,
|
|
1653
|
-
id,
|
|
1654
|
-
})))) {
|
|
1459
|
+
if (!sameTransferStake(currentStake, stake, game, character)) {
|
|
1655
1460
|
fail(`Claim Stake ${stake.address} changed or no longer matches its loaded owner, Game, Body, active state, resources, capacity, or System generation. Refresh it and retry Fleet transfer recovery.`, stake.address);
|
|
1656
1461
|
}
|
|
1657
1462
|
let reason;
|
|
@@ -1695,8 +1500,10 @@ export async function planRecoverClaimStakeFleetTransfer(ctx, fleet, stake, inpu
|
|
|
1695
1500
|
const loadCargoStorage = currentFleet.state.load
|
|
1696
1501
|
.filter(({ cargoId }) => cargoId !== currentFleet.ammoBank.cargoId &&
|
|
1697
1502
|
cargoId !== currentFleet.fuelTank.cargoId)
|
|
1698
|
-
.reduce((total, { amount, cargoId }) => total +
|
|
1699
|
-
|
|
1503
|
+
.reduce((total, { amount, cargoId }) => total +
|
|
1504
|
+
cargoStorageUnits(amount, queuedDefinitions.get(cargoId).storageCost), 0n);
|
|
1505
|
+
const unloadStorage = currentFleet.state.unload.reduce((total, { amount, cargoId }) => total +
|
|
1506
|
+
cargoStorageUnits(amount, queuedDefinitions.get(cargoId).storageCost), 0n);
|
|
1700
1507
|
if (currentFleet.ammoBank.amount + loadAmmo >
|
|
1701
1508
|
currentFleet.stats.cargo.ammoCapacity) {
|
|
1702
1509
|
reason = 'Fleet ammo destination overflow';
|
|
@@ -1718,15 +1525,15 @@ export async function planRecoverClaimStakeFleetTransfer(ctx, fleet, stake, inpu
|
|
|
1718
1525
|
fail(`Fleet ${fleet.name}'s Claim Stake transfer is currently executable. Use the permissionless normal exit path; recovery is only for a locally proven non-executable transfer.`, fleet.address);
|
|
1719
1526
|
}
|
|
1720
1527
|
const description = `Recover fleet ${fleet.name} from its stuck Claim Stake transfer (${reason}); no cargo moves and the Fleet returns to idle.`;
|
|
1721
|
-
return
|
|
1528
|
+
return buildPlannerPlan({
|
|
1722
1529
|
kind: 'claim-stakes.recover-fleet-transfer',
|
|
1723
1530
|
preconditions: await Promise.all([
|
|
1724
|
-
|
|
1725
|
-
|
|
1531
|
+
accountStatePrecondition(fleetAccount, `Fleet ${fleet.name} retains its owner and exact elapsed, non-executable Claim Stake transfer snapshot.`),
|
|
1532
|
+
accountStatePrecondition(stakeAccount, `Claim Stake ${stake.address} remains active with the current owner, cargo, and capacity used to prove non-executability.`),
|
|
1726
1533
|
...(gameAccount === undefined
|
|
1727
1534
|
? []
|
|
1728
1535
|
: [
|
|
1729
|
-
|
|
1536
|
+
accountStatePrecondition(gameAccount, `Game ${game} retains the cargo definitions used to prove the transfer is non-executable.`),
|
|
1730
1537
|
]),
|
|
1731
1538
|
]),
|
|
1732
1539
|
steps: [
|