@aephia/atlas-kit 0.6.0-next.11 → 0.6.0-next.110
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 +1 -1
- package/dist/cargo/actions/deposit.d.ts.map +1 -1
- package/dist/cargo/actions/deposit.js +26 -115
- package/dist/cargo/actions/deposit.js.map +1 -1
- package/dist/cargo/actions/index.d.ts.map +1 -1
- package/dist/cargo/actions/index.js +15 -37
- package/dist/cargo/actions/index.js.map +1 -1
- package/dist/cargo/actions/wallet-context.d.ts +51 -2
- package/dist/cargo/actions/wallet-context.d.ts.map +1 -1
- package/dist/cargo/actions/wallet-context.js +125 -2
- 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.map +1 -1
- package/dist/cargo/actions/withdrawal.js +37 -162
- package/dist/cargo/actions/withdrawal.js.map +1 -1
- package/dist/claim-stakes/actions/index.d.ts +13 -0
- package/dist/claim-stakes/actions/index.d.ts.map +1 -1
- package/dist/claim-stakes/actions/index.js +373 -544
- 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 +23 -2
- 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 +2 -2
- package/dist/combat/actions/index.d.ts.map +1 -1
- package/dist/combat/actions/index.js +192 -224
- package/dist/combat/actions/index.js.map +1 -1
- package/dist/combat/index.d.ts +4 -3
- package/dist/combat/index.d.ts.map +1 -1
- package/dist/combat/index.js +3 -2
- package/dist/combat/index.js.map +1 -1
- package/dist/crafting/actions/index.d.ts +11 -0
- package/dist/crafting/actions/index.d.ts.map +1 -1
- package/dist/crafting/actions/index.js +175 -283
- 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 +45 -16
- package/dist/crafting/index.js.map +1 -1
- package/dist/factions/actions/index.d.ts +1 -0
- package/dist/factions/actions/index.d.ts.map +1 -1
- package/dist/factions/actions/index.js +2 -1
- 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 +14 -8
- 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 +149 -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 +138 -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 +114 -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 +37 -16
- package/dist/fleets/actions/index.d.ts.map +1 -1
- package/dist/fleets/actions/index.js +303 -284
- 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 +122 -0
- package/dist/fleets/actions/respawn.js.map +1 -0
- package/dist/fleets/actions/ship-import.d.ts.map +1 -1
- package/dist/fleets/actions/ship-import.js +59 -76
- 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 +52 -2
- 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/index.d.ts +3 -3
- package/dist/identity/actions/index.d.ts.map +1 -1
- package/dist/identity/actions/index.js +50 -28
- package/dist/identity/actions/index.js.map +1 -1
- package/dist/identity/index.d.ts +12 -2
- package/dist/identity/index.d.ts.map +1 -1
- package/dist/identity/index.js +10 -1
- package/dist/identity/index.js.map +1 -1
- package/dist/identity/permissions.d.ts +11 -2
- package/dist/identity/permissions.d.ts.map +1 -1
- package/dist/identity/permissions.js +13 -4
- package/dist/identity/permissions.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 +12 -0
- package/dist/internal/c4/account-decoding.d.ts.map +1 -0
- package/dist/internal/c4/account-decoding.js +36 -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/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 +155 -0
- package/dist/internal/c4/character.d.ts.map +1 -0
- package/dist/internal/c4/character.js +79 -0
- package/dist/internal/c4/character.js.map +1 -0
- package/dist/internal/c4/claim-stake-configuration.js +4 -2
- 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.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 +30 -41
- 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 +10 -171
- 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 +61 -49
- 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 +30 -0
- package/dist/internal/c4/currency-cache.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-adapter.d.ts +12 -0
- package/dist/internal/c4/faction-adapter.d.ts.map +1 -0
- package/dist/internal/c4/faction-adapter.js +52 -0
- package/dist/internal/c4/faction-adapter.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 +31 -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 +48 -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 +9 -57
- package/dist/internal/c4/factions.d.ts.map +1 -1
- package/dist/internal/c4/factions.js +29 -156
- 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 +180 -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 +20 -3
- 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 +45 -19
- package/dist/internal/c4/fleet.d.ts.map +1 -1
- package/dist/internal/c4/fleet.js +37 -29
- 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 +47 -12
- package/dist/internal/c4/game.d.ts.map +1 -1
- package/dist/internal/c4/game.js +110 -21
- package/dist/internal/c4/game.js.map +1 -1
- package/dist/internal/c4/identity.d.ts +2 -152
- package/dist/internal/c4/identity.d.ts.map +1 -1
- package/dist/internal/c4/identity.js +6 -110
- package/dist/internal/c4/identity.js.map +1 -1
- package/dist/internal/c4/local-market-order.d.ts +31 -0
- package/dist/internal/c4/local-market-order.d.ts.map +1 -0
- package/dist/internal/c4/local-market-order.js +47 -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 +58 -0
- package/dist/internal/c4/loot.d.ts.map +1 -0
- package/dist/internal/c4/loot.js +130 -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 +14 -43
- 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 +13 -51
- 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.js +1 -1
- package/dist/internal/c4/pda.js.map +1 -1
- package/dist/internal/c4/profile-faction.d.ts.map +1 -1
- package/dist/internal/c4/profile-faction.js +11 -21
- package/dist/internal/c4/profile-faction.js.map +1 -1
- package/dist/internal/c4/profile-permissions.d.ts +5 -3
- package/dist/internal/c4/profile-permissions.d.ts.map +1 -1
- package/dist/internal/c4/profile-permissions.js +61 -8
- 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 +14 -115
- 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 +261 -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 +7 -36
- 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 +25 -21
- 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 +12 -62
- package/dist/internal/c4/starbase.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 +67 -48
- 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/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 +171 -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 +165 -76
- 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 +58 -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 +32 -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 +198 -0
- package/dist/internal/planning/democracy-history.js.map +1 -0
- package/dist/internal/planning/faction-enrollment.d.ts +0 -2
- package/dist/internal/planning/faction-enrollment.d.ts.map +1 -1
- package/dist/internal/planning/faction-enrollment.js +1 -22
- 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 +106 -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 +110 -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 +109 -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 +47 -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 +132 -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 +208 -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 +42 -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 +85 -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 +167 -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 +138 -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 +239 -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 +127 -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 +138 -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 +41 -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 +103 -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 +31 -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 +86 -0
- package/dist/internal/planning/open-signal.js.map +1 -0
- package/dist/internal/planning/original-token.d.ts +34 -0
- package/dist/internal/planning/original-token.d.ts.map +1 -0
- package/dist/internal/planning/original-token.js +98 -0
- package/dist/internal/planning/original-token.js.map +1 -0
- package/dist/internal/planning/plan-fields.d.ts +59 -0
- package/dist/internal/planning/plan-fields.d.ts.map +1 -0
- package/dist/internal/planning/plan-fields.js +153 -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/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 +41 -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 +635 -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 +94 -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 +93 -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 +15 -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 +126 -0
- package/dist/internal/planning/xp-runtime.js.map +1 -0
- 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.map +1 -1
- package/dist/loyalty/actions/index.js +8 -21
- package/dist/loyalty/actions/index.js.map +1 -1
- package/dist/loyalty/index.d.ts.map +1 -1
- package/dist/loyalty/index.js +2 -6
- package/dist/loyalty/index.js.map +1 -1
- package/dist/markets/actions/index.d.ts +61 -3
- package/dist/markets/actions/index.d.ts.map +1 -1
- package/dist/markets/actions/index.js +227 -160
- 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 +282 -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 +57 -10
- 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 +7 -2
- 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 +5 -0
- package/dist/planning/assembly.d.ts.map +1 -1
- package/dist/planning/assembly.js +8 -4
- package/dist/planning/assembly.js.map +1 -1
- package/dist/planning/execution.d.ts +18 -3
- package/dist/planning/execution.d.ts.map +1 -1
- package/dist/planning/execution.js +492 -40
- 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 +44 -292
- package/dist/planning/index.js.map +1 -1
- 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 -30
- 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 +14 -0
- package/dist/planning/plan-validation.d.ts.map +1 -0
- package/dist/planning/plan-validation.js +124 -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 +19 -19
- 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.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.map +1 -1
- package/dist/rewards/index.js +5 -4
- 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 +185 -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 +13 -9
- 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.map +1 -1
- package/dist/starbases/actions/index.js +3 -14
- package/dist/starbases/actions/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 +109 -4
- 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,41 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { deriveCurrencyCache, validateCurrencyCache, } from '../../internal/c4/currency-cache.js';
|
|
2
|
+
import { getAddressEncoder, 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 {
|
|
19
|
+
import { cargoStorageUnits } from '../../internal/cargo.js';
|
|
20
|
+
import { adaptCancelClaimStakeBuildingChangesInstruction, adaptClaimStakeBuildingChangesInstruction, adaptDeconstructClaimStakeInstruction, adaptFinalizeClaimStakeBuildingChangesInstruction, adaptPlaceClaimStakeInstruction, adaptRecoverClaimStakeFleetTransferInstruction, adaptStartClaimStakeFleetTransferInstruction, adaptTopUpClaimStakeRentInstruction, readPlanAuthorization, } from '../../internal/planning/authorization-adapter.js';
|
|
16
21
|
import { createPlan, } from '../../planning/index.js';
|
|
17
22
|
import { readFreshGameCargoDefinitions } from '../../registry/cargo.js';
|
|
18
23
|
import { resolveCargo } from '../../registry/index.js';
|
|
24
|
+
async function resolveClaimStakeXp(ctx, game, structure, character) {
|
|
25
|
+
const xp = await resolveXpRuntime(ctx, {
|
|
26
|
+
game,
|
|
27
|
+
structure,
|
|
28
|
+
...(character === undefined ? {} : { character }),
|
|
29
|
+
});
|
|
30
|
+
const guard = {
|
|
31
|
+
kind: 'xp-runtime',
|
|
32
|
+
address: game,
|
|
33
|
+
intent: xp.intent,
|
|
34
|
+
accounts: xp.accounts,
|
|
35
|
+
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.',
|
|
36
|
+
};
|
|
37
|
+
return { accounts: xp.accounts, guard };
|
|
38
|
+
}
|
|
19
39
|
const U64_MAX = (1n << 64n) - 1n;
|
|
20
40
|
const U16_MAX = 65_535;
|
|
21
41
|
const I32_MAX = 2_147_483_647;
|
|
@@ -31,13 +51,13 @@ const LEVEL_INDEX = Object.freeze({
|
|
|
31
51
|
css: 6,
|
|
32
52
|
});
|
|
33
53
|
const CLAIM_STAKE_PLOT_LEVELS = Object.freeze([
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
54
|
+
StarbaseLevel.Level0,
|
|
55
|
+
StarbaseLevel.Level1,
|
|
56
|
+
StarbaseLevel.Level2,
|
|
57
|
+
StarbaseLevel.Level3,
|
|
58
|
+
StarbaseLevel.Level4,
|
|
59
|
+
StarbaseLevel.Level5,
|
|
60
|
+
StarbaseLevel.Css,
|
|
41
61
|
]);
|
|
42
62
|
const TIER_INDEX = Object.freeze({
|
|
43
63
|
one: 0,
|
|
@@ -90,15 +110,7 @@ function validateOptions(value) {
|
|
|
90
110
|
'hubBuildingId',
|
|
91
111
|
'initialRentAmount',
|
|
92
112
|
]);
|
|
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);
|
|
113
|
+
const authorization = readPlanAuthorization(options.authorization);
|
|
102
114
|
if (typeof options.initialRentAmount !== 'bigint' ||
|
|
103
115
|
options.initialRentAmount <= 0n ||
|
|
104
116
|
options.initialRentAmount > U64_MAX) {
|
|
@@ -112,22 +124,10 @@ function validateOptions(value) {
|
|
|
112
124
|
initialRentAmount: options.initialRentAmount,
|
|
113
125
|
};
|
|
114
126
|
}
|
|
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
127
|
function validateBuildingChangeOptions(value) {
|
|
128
128
|
const options = record(value, 'options');
|
|
129
129
|
exactKeys(options, 'options', ['authorization', 'buildingChanges']);
|
|
130
|
-
const authorization =
|
|
130
|
+
const authorization = readPlanAuthorization(options.authorization);
|
|
131
131
|
const values = options.buildingChanges;
|
|
132
132
|
if (!Array.isArray(values) || values.length === 0) {
|
|
133
133
|
invalid('buildingChanges', values, 'a non-empty dense array of add/remove building changes', 'Provide at least one exact building change before retrying.');
|
|
@@ -168,22 +168,22 @@ function validateBuildingChangeOptions(value) {
|
|
|
168
168
|
function validateFinalizeBuildingChangeOptions(value) {
|
|
169
169
|
const options = record(value, 'options');
|
|
170
170
|
exactKeys(options, 'options', ['authorization']);
|
|
171
|
-
return { authorization:
|
|
171
|
+
return { authorization: readPlanAuthorization(options.authorization) };
|
|
172
172
|
}
|
|
173
173
|
function validateCancelBuildingChangeOptions(value) {
|
|
174
174
|
const options = record(value, 'options');
|
|
175
175
|
exactKeys(options, 'options', ['authorization']);
|
|
176
|
-
return { authorization:
|
|
176
|
+
return { authorization: readPlanAuthorization(options.authorization) };
|
|
177
177
|
}
|
|
178
178
|
function validateDeconstructOptions(value) {
|
|
179
179
|
const options = record(value, 'options');
|
|
180
180
|
exactKeys(options, 'options', ['authorization']);
|
|
181
|
-
return { authorization:
|
|
181
|
+
return { authorization: readPlanAuthorization(options.authorization) };
|
|
182
182
|
}
|
|
183
183
|
function validateTopUpRentOptions(value) {
|
|
184
184
|
const options = record(value, 'options');
|
|
185
185
|
exactKeys(options, 'options', ['amount', 'authorization']);
|
|
186
|
-
const authorization =
|
|
186
|
+
const authorization = readPlanAuthorization(options.authorization);
|
|
187
187
|
if (typeof options.amount !== 'bigint' ||
|
|
188
188
|
options.amount <= 0n ||
|
|
189
189
|
options.amount > U64_MAX) {
|
|
@@ -220,7 +220,7 @@ function validateCargoRequests(value, field, seen) {
|
|
|
220
220
|
function validateStartFleetTransferOptions(value) {
|
|
221
221
|
const options = record(value, 'options');
|
|
222
222
|
exactKeys(options, 'options', ['authorization', 'load', 'unload']);
|
|
223
|
-
const authorization =
|
|
223
|
+
const authorization = readPlanAuthorization(options.authorization);
|
|
224
224
|
const seen = new Set();
|
|
225
225
|
const load = validateCargoRequests(options.load, 'load', seen);
|
|
226
226
|
const unload = validateCargoRequests(options.unload, 'unload', seen);
|
|
@@ -232,7 +232,7 @@ function validateStartFleetTransferOptions(value) {
|
|
|
232
232
|
function validateRecoverFleetTransferOptions(value) {
|
|
233
233
|
const options = record(value, 'options');
|
|
234
234
|
exactKeys(options, 'options', ['atUnixSeconds', 'authorization']);
|
|
235
|
-
const authorization =
|
|
235
|
+
const authorization = readPlanAuthorization(options.authorization);
|
|
236
236
|
if (typeof options.atUnixSeconds !== 'bigint' ||
|
|
237
237
|
options.atUnixSeconds < 0n ||
|
|
238
238
|
options.atUnixSeconds > U64_MAX) {
|
|
@@ -240,27 +240,6 @@ function validateRecoverFleetTransferOptions(value) {
|
|
|
240
240
|
}
|
|
241
241
|
return { atUnixSeconds: options.atUnixSeconds, authorization };
|
|
242
242
|
}
|
|
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
243
|
function requireAccount(account, accountAddress, message) {
|
|
265
244
|
return account ?? fail(message, accountAddress);
|
|
266
245
|
}
|
|
@@ -332,17 +311,7 @@ export async function planPlaceClaimStake(ctx, body, player, input) {
|
|
|
332
311
|
if (canonicalBody !== body.address) {
|
|
333
312
|
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
313
|
}
|
|
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
|
-
}
|
|
314
|
+
const character = await requireProfileStarbasePlayer(player, options.authorization.profile, game);
|
|
346
315
|
if (body.system.address !== player.system.address) {
|
|
347
316
|
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
317
|
}
|
|
@@ -385,11 +354,10 @@ export async function planPlaceClaimStake(ctx, body, player, input) {
|
|
|
385
354
|
}
|
|
386
355
|
const currentBodyAccount = requireAccount(bodyAccount, body.address, `Celestial Body ${body.address} is missing. Refresh the Body and retry placement.`);
|
|
387
356
|
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
357
|
const currentSystemAccount = requireAccount(systemAccount, body.system.address, `Star System ${body.system.address} is missing. Refresh the System and retry placement.`);
|
|
390
358
|
const currentBody = celestialBodyAccountDefinition.decode(currentBodyAccount);
|
|
391
359
|
const currentPlayer = starbasePlayerAccountDefinition.decode(currentPlayerAccount);
|
|
392
|
-
const
|
|
360
|
+
const { account: currentCharacterAccount } = requireProfileCharacter(characterAccount, character, options.authorization.profile, game, 'placement');
|
|
393
361
|
const currentSystem = starSystemAccountDefinition.decode(currentSystemAccount);
|
|
394
362
|
const canonicalSystem = await deriveStarSystemAddress(game, currentSystem.systemId);
|
|
395
363
|
if (canonicalSystem !== body.system.address ||
|
|
@@ -411,10 +379,6 @@ export async function planPlaceClaimStake(ctx, body, player, input) {
|
|
|
411
379
|
currentPlayer.totalCrew - currentPlayer.busyCrew !== player.availableCrew) {
|
|
412
380
|
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
381
|
}
|
|
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
382
|
const currentCargo = currentPlayer.cargo.amounts.find(({ cargoId }) => cargoId === definition.cargoId)?.amount ?? 0n;
|
|
419
383
|
if (currentCargo !== cargoQuantity || currentCargo < 1n) {
|
|
420
384
|
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,7 +396,7 @@ export async function planPlaceClaimStake(ctx, body, player, input) {
|
|
|
432
396
|
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
397
|
}
|
|
434
398
|
const profileFaction = await deriveProfileFactionAddress(options.authorization.profile);
|
|
435
|
-
const currencyCache = await
|
|
399
|
+
const currencyCache = await deriveCurrencyCache(game).then(([address]) => address);
|
|
436
400
|
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
401
|
return createPlan({
|
|
438
402
|
kind: 'claim-stakes.place',
|
|
@@ -441,7 +405,7 @@ export async function planPlaceClaimStake(ctx, body, player, input) {
|
|
|
441
405
|
precondition(freshGame.account, `The configured Game retains Claim Stake definition ${String(definition.id)} and bundled hub ${String(hub.id)} eligibility.`),
|
|
442
406
|
precondition(currentBodyAccount, `Planet ${body.name} retains an available ${definition.name} plot and its configured Game/System relationship.`),
|
|
443
407
|
precondition(currentPlayerAccount, `Starbase Player ${player.address} retains its Profile, Character, System, available crew, and ${cargoName} balance.`),
|
|
444
|
-
|
|
408
|
+
characterPrecondition(currentCharacterAccount, options.authorization.profile),
|
|
445
409
|
precondition(currentSystemAccount, `Star System ${currentSystem.name} retains its configured Game, sequence, and active Starbase level.`),
|
|
446
410
|
])),
|
|
447
411
|
absentPrecondition(options.claimStake, 'The caller-supplied Claim Stake signer address remains unallocated.'),
|
|
@@ -492,12 +456,165 @@ function sameStakeState(left, right) {
|
|
|
492
456
|
sameQuantities(left.buildings, right.buildings));
|
|
493
457
|
}
|
|
494
458
|
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
459
|
+
// Common facts for planners acting on an owned, placed Claim Stake. Each
|
|
460
|
+
// planner keeps its own eligibility checks and Plan wording at its call site;
|
|
461
|
+
// `action` completes the shared remedies ("retry <action>").
|
|
462
|
+
/** Requires the loaded Claim Stake to belong to the configured Game and to the
|
|
463
|
+
* authorization Profile's canonical Character, which it returns. */
|
|
464
|
+
async function requireOwnedStake(stake, game, profile) {
|
|
465
|
+
if (stake.game !== game) {
|
|
466
|
+
fail(`Claim Stake ${stake.address} does not match the configured Game ${game}. Refresh it through this context and retry.`, stake.address);
|
|
467
|
+
}
|
|
468
|
+
const character = await findCharacterPda(profile, game);
|
|
469
|
+
if (stake.ownerCharacter.address !== character) {
|
|
470
|
+
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);
|
|
471
|
+
}
|
|
472
|
+
return character;
|
|
473
|
+
}
|
|
474
|
+
/** Reads and decodes the fresh Claim Stake and Body, with `extra` accounts in
|
|
475
|
+
* the same batch. */
|
|
476
|
+
async function readOwnedStake(ctx, stake, action, extra = []) {
|
|
477
|
+
const [stakeCandidate, bodyCandidate, ...extraAccounts] = await readContextRawAccounts(ctx, [
|
|
478
|
+
stake.address,
|
|
479
|
+
stake.body.address,
|
|
480
|
+
...extra,
|
|
481
|
+
]);
|
|
482
|
+
const stakeAccount = requireAccount(stakeCandidate, stake.address, `Claim Stake ${stake.address} is missing. Refresh it and retry ${action}.`);
|
|
483
|
+
const bodyAccount = requireAccount(bodyCandidate, stake.body.address, `Celestial Body ${stake.body.address} is missing. Refresh the Claim Stake Body and retry ${action}.`);
|
|
484
|
+
return {
|
|
485
|
+
bodyAccount,
|
|
486
|
+
currentBody: celestialBodyAccountDefinition.decode(bodyAccount),
|
|
487
|
+
currentStake: claimStakeAccountDefinition.decode(stakeAccount),
|
|
488
|
+
extraAccounts,
|
|
489
|
+
stakeAccount,
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
/** Whether the fresh Claim Stake keeps the loaded ownership, Body,
|
|
493
|
+
* definitions, buildings and System generation. */
|
|
494
|
+
function sameOwnedStake(current, stake, game, character) {
|
|
495
|
+
return (current.game === game &&
|
|
496
|
+
current.body === stake.body.address &&
|
|
497
|
+
current.ownerCharacter === character &&
|
|
498
|
+
current.claimStakeDefinitionId === stake.claimStakeDefinitionId &&
|
|
499
|
+
current.claimStakeDefinitionSeqId === stake.claimStakeDefinitionSeqId &&
|
|
500
|
+
current.buildingDefinitionSeqId === stake.buildingDefinitionSeqId &&
|
|
501
|
+
current.systemSeqId === stake.systemSeqId &&
|
|
502
|
+
sameQuantities(current.buildings, stake.buildings));
|
|
503
|
+
}
|
|
504
|
+
/** Whether the fresh Claim Stake keeps the loaded transfer facts: ownership,
|
|
505
|
+
* Body, active state, System generation, resources and capacity. */
|
|
506
|
+
function sameTransferStake(current, stake, game, character) {
|
|
507
|
+
return (current.game === game &&
|
|
508
|
+
current.ownerCharacter === character &&
|
|
509
|
+
current.body === stake.body.address &&
|
|
510
|
+
current.systemSeqId === stake.systemSeqId &&
|
|
511
|
+
current.state.kind === 'active' &&
|
|
512
|
+
current.production.cargoPod.storageCost ===
|
|
513
|
+
stake.resources.capacity.usedRaw &&
|
|
514
|
+
current.production.resourceCapacityRaw ===
|
|
515
|
+
stake.resources.capacity.totalRaw &&
|
|
516
|
+
sameCargoAmounts(current.production.cargoPod.amounts, stake.resources.inventory.items.map(({ id, quantityRaw }) => ({
|
|
517
|
+
amount: quantityRaw,
|
|
518
|
+
id,
|
|
519
|
+
}))));
|
|
520
|
+
}
|
|
521
|
+
/** Whether the fresh Fleet keeps the loaded Game, owner, name, cargo and
|
|
522
|
+
* capacities. */
|
|
523
|
+
function sameTransferFleet(current, fleet, game, profile) {
|
|
524
|
+
return (current.game === game &&
|
|
525
|
+
current.ownerProfile === profile &&
|
|
526
|
+
current.name === fleet.name &&
|
|
527
|
+
current.ammoBank.cargoId === fleet.ammo.id &&
|
|
528
|
+
current.ammoBank.amount === fleet.ammo.amount &&
|
|
529
|
+
current.fuelTank.cargoId === fleet.fuel.id &&
|
|
530
|
+
current.fuelTank.amount === fleet.fuel.amount &&
|
|
531
|
+
current.cargoHold.storageCost === fleet.cargoHold.storageCost &&
|
|
532
|
+
sameCargoAmounts(current.cargoHold.amounts, fleet.cargoHold.items) &&
|
|
533
|
+
current.stats.cargo.ammoCapacity === fleet.capacities.ammo.total &&
|
|
534
|
+
current.stats.cargo.fuelCapacity === fleet.capacities.fuel.total &&
|
|
535
|
+
current.stats.cargo.cargoCapacity === fleet.capacities.cargo.total);
|
|
536
|
+
}
|
|
537
|
+
/** Requires the fresh Body to be the Claim Stake's canonical Planet in the
|
|
538
|
+
* configured Game at the Claim Stake's System generation. */
|
|
539
|
+
async function requireStakePlanet(currentBody, stake, game, action) {
|
|
540
|
+
if (currentBody.kind !== 'planet' ||
|
|
541
|
+
currentBody.game !== game ||
|
|
542
|
+
currentBody.systemSequenceId !== stake.systemSeqId ||
|
|
543
|
+
(await deriveCelestialBodyAddress(game, currentBody.id)) !==
|
|
544
|
+
stake.body.address) {
|
|
545
|
+
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);
|
|
546
|
+
}
|
|
547
|
+
return currentBody;
|
|
548
|
+
}
|
|
549
|
+
/** Requires and decodes the canonical Character of the authorization Profile in
|
|
550
|
+
* the configured Game. */
|
|
551
|
+
function requireProfileCharacter(candidate, character, profile, game, action) {
|
|
552
|
+
const account = requireAccount(candidate, character, `Canonical Character ${character} is missing. Refresh the Profile Character and retry ${action}.`);
|
|
553
|
+
const current = characterAccountDefinition.decode(account);
|
|
554
|
+
if (current.playerProfile !== profile || current.game !== game) {
|
|
555
|
+
fail(`Character ${character} does not match authorization Profile ${profile} and configured Game ${game}. Refresh the Character and retry ${action}.`, character);
|
|
556
|
+
}
|
|
557
|
+
return { account, current };
|
|
558
|
+
}
|
|
559
|
+
/** Reads the Claim Stake's System and the authorization Profile's canonical
|
|
560
|
+
* Starbase Player there, with `extra` accounts in the same batch. Requires a
|
|
561
|
+
* canonical, current System with an active Starbase that lists the Body, and a
|
|
562
|
+
* Starbase Player of the Profile, Character and System. */
|
|
563
|
+
async function readStakeStarbase(ctx, stake, game, system, character, profile, action, extra = []) {
|
|
564
|
+
const player = await deriveStarbasePlayerAddress(system, character);
|
|
565
|
+
const [systemCandidate, playerCandidate, ...extraAccounts] = await readContextRawAccounts(ctx, [system, player, ...extra]);
|
|
566
|
+
const systemAccount = requireAccount(systemCandidate, system, `Star System ${system} is missing. Refresh the Claim Stake's System and retry ${action}.`);
|
|
567
|
+
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}.`);
|
|
568
|
+
const currentSystem = starSystemAccountDefinition.decode(systemAccount);
|
|
569
|
+
const currentPlayer = starbasePlayerAccountDefinition.decode(playerAccount);
|
|
570
|
+
if (currentSystem.game !== game ||
|
|
571
|
+
currentSystem.sequenceId !== stake.systemSeqId ||
|
|
572
|
+
currentSystem.starbase === undefined ||
|
|
573
|
+
!currentSystem.celestialBodyAddresses.includes(stake.body.address) ||
|
|
574
|
+
(await deriveStarSystemAddress(game, currentSystem.systemId)) !== system) {
|
|
575
|
+
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);
|
|
576
|
+
}
|
|
577
|
+
if (currentPlayer.playerProfile !== profile ||
|
|
578
|
+
currentPlayer.character !== character ||
|
|
579
|
+
currentPlayer.system !== system) {
|
|
580
|
+
fail(`Starbase Player ${player} does not match the authorization Profile, canonical Character, and Claim Stake System. Refresh it and retry ${action}.`, player);
|
|
581
|
+
}
|
|
582
|
+
return {
|
|
583
|
+
currentPlayer,
|
|
584
|
+
currentSystem,
|
|
585
|
+
extraAccounts,
|
|
586
|
+
player,
|
|
587
|
+
playerAccount,
|
|
588
|
+
starbase: currentSystem.starbase,
|
|
589
|
+
systemAccount,
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
async function claimStakeCurrencyCache(game) {
|
|
593
|
+
const [currencyCache] = await deriveCurrencyCache(game);
|
|
594
|
+
return currencyCache;
|
|
595
|
+
}
|
|
596
|
+
/** Requires the canonical CurrencyCache and returns its Plan guard. */
|
|
597
|
+
async function requireCurrencyCache(candidate, currencyCache, game, action, planName) {
|
|
598
|
+
await validateCurrencyCache(requireAccount(candidate, currencyCache, `Canonical CurrencyCache ${currencyCache} is missing for configured Game ${game}. Refresh the Game currency configuration and retry ${action}.`), game, planName);
|
|
599
|
+
return {
|
|
600
|
+
kind: 'currency-cache',
|
|
601
|
+
address: currencyCache,
|
|
602
|
+
game,
|
|
603
|
+
describes: 'The canonical CurrencyCache remains assigned to the configured Game; shared accounting may change.',
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
function planetPrecondition(account, system) {
|
|
607
|
+
return precondition(account, `The Claim Stake Planet remains assigned to System ${system} at the current generation.`);
|
|
608
|
+
}
|
|
609
|
+
function characterPrecondition(account, profile) {
|
|
610
|
+
return precondition(account, `The canonical Character remains assigned to Profile ${profile} in the configured Game.`);
|
|
611
|
+
}
|
|
612
|
+
function systemPrecondition(account, name) {
|
|
613
|
+
return precondition(account, `Star System ${name} retains its configured Game, sequence, nested Starbase, and Claim Stake Body relationship.`);
|
|
614
|
+
}
|
|
615
|
+
function playerPrecondition(account, player, facts = 'Profile, Character, and System') {
|
|
616
|
+
return precondition(account, `Starbase Player ${player} retains its ${facts}.`);
|
|
617
|
+
}
|
|
501
618
|
function buildingDescription(change, name) {
|
|
502
619
|
return `${change.kind} ${String(change.quantity)} ${name}`;
|
|
503
620
|
}
|
|
@@ -509,6 +626,9 @@ function buildingDescription(change, name) {
|
|
|
509
626
|
* construction cargo. Rent synchronization and the final concurrent sequence
|
|
510
627
|
* race remain chain-authoritative.
|
|
511
628
|
*
|
|
629
|
+
* Requires Game 2 and its existing canonical Claim Stake XP ledger.
|
|
630
|
+
* Missing XP state must be repaired outside this Plan; no accounts are created.
|
|
631
|
+
*
|
|
512
632
|
* @example
|
|
513
633
|
* ```ts
|
|
514
634
|
* declare const ctx: SageContext;
|
|
@@ -521,85 +641,37 @@ function buildingDescription(change, name) {
|
|
|
521
641
|
export async function planClaimStakeBuildingChanges(ctx, stake, input) {
|
|
522
642
|
const options = validateBuildingChangeOptions(input);
|
|
523
643
|
const game = requireGameAddress(ctx);
|
|
644
|
+
const { profile } = options.authorization;
|
|
524
645
|
if (stake.state.kind === 'deactivated') {
|
|
525
646
|
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
647
|
}
|
|
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([
|
|
648
|
+
const character = await requireOwnedStake(stake, game, profile);
|
|
649
|
+
const action = 'building changes';
|
|
650
|
+
const [freshGame, loaded] = await Promise.all([
|
|
535
651
|
readFreshGameClaimStakeConfiguration(ctx),
|
|
536
|
-
|
|
652
|
+
readOwnedStake(ctx, stake, action, [character]),
|
|
537
653
|
]);
|
|
538
654
|
if (freshGame === undefined) {
|
|
539
655
|
fail(`Configured Game ${game} is missing. Refresh the Game catalog and retry building changes.`, game);
|
|
540
656
|
}
|
|
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) ||
|
|
657
|
+
const { bodyAccount, currentStake, stakeAccount } = loaded;
|
|
658
|
+
if (!sameOwnedStake(currentStake, stake, game, character) ||
|
|
556
659
|
currentStake.neededCrew !== stake.neededCrew) {
|
|
557
660
|
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
661
|
}
|
|
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),
|
|
662
|
+
const { system } = await requireStakePlanet(loaded.currentBody, stake, game, action);
|
|
663
|
+
const { account: characterAccount } = requireProfileCharacter(loaded.extraAccounts[0], character, profile, game, action);
|
|
664
|
+
const [ownership, profileFaction] = await Promise.all([
|
|
573
665
|
deriveFactionOwnershipAddress(game, 'starbase', system),
|
|
574
|
-
deriveProfileFactionAddress(
|
|
575
|
-
]);
|
|
576
|
-
const [systemAccountCandidate, playerAccountCandidate, ownershipAccount, profileFactionAccountCandidate,] = await readContextRawAccounts(ctx, [
|
|
577
|
-
system,
|
|
578
|
-
player,
|
|
579
|
-
ownership,
|
|
580
|
-
profileFaction,
|
|
666
|
+
deriveProfileFactionAddress(profile),
|
|
581
667
|
]);
|
|
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);
|
|
668
|
+
const { currentPlayer, currentSystem, extraAccounts: [ownershipAccount, profileFactionCandidate], player, playerAccount, starbase, systemAccount, } = await readStakeStarbase(ctx, stake, game, system, character, profile, action, [ownership, profileFaction]);
|
|
669
|
+
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
670
|
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);
|
|
671
|
+
if (currentProfileFaction.profile !== profile) {
|
|
672
|
+
fail(`ProfileFaction ${profileFaction} does not match authorization Profile ${profile}. Refresh or repair the Profile faction before retrying building changes.`, profileFaction);
|
|
598
673
|
}
|
|
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];
|
|
674
|
+
let controllerFactionId = factionValue(starbase.owner);
|
|
603
675
|
let ownershipPrecondition;
|
|
604
676
|
if (ownershipAccount === undefined) {
|
|
605
677
|
ownershipPrecondition = absentPrecondition(ownership, `The canonical Starbase FactionOwnership ${ownership} remains unallocated so the chain applies its legacy controller gate.`);
|
|
@@ -744,26 +816,29 @@ export async function planClaimStakeBuildingChanges(ctx, stake, input) {
|
|
|
744
816
|
if (currentStake.production.cargoPod.storageCost > resourceStorageRaw) {
|
|
745
817
|
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
818
|
}
|
|
747
|
-
const currencyCache = await
|
|
819
|
+
const currencyCache = await claimStakeCurrencyCache(game);
|
|
748
820
|
const description = `Change buildings on Claim Stake ${stake.address}: ${descriptions.join('; ')}.`;
|
|
821
|
+
const xp = await resolveClaimStakeXp(ctx, game, stake.address);
|
|
749
822
|
return createPlan({
|
|
750
823
|
kind: 'claim-stakes.building-changes',
|
|
751
824
|
preconditions: [
|
|
752
825
|
...(await Promise.all([
|
|
753
826
|
precondition(freshGame.account, 'The configured Game retains the exact Claim Stake and building definitions.'),
|
|
754
827
|
precondition(stakeAccount, `Claim Stake ${stake.address} retains its ownership, design sequence, buildings, cargo, crew, and Body relationship.`),
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
precondition(profileFactionAccount, `ProfileFaction ${profileFaction} remains assigned to Profile ${
|
|
828
|
+
planetPrecondition(bodyAccount, system),
|
|
829
|
+
characterPrecondition(characterAccount, profile),
|
|
830
|
+
systemPrecondition(systemAccount, currentSystem.name),
|
|
831
|
+
playerPrecondition(playerAccount, player, 'Profile, Character, System, and available crew'),
|
|
832
|
+
precondition(profileFactionAccount, `ProfileFaction ${profileFaction} remains assigned to Profile ${profile} and aligned with the current Starbase controller.`),
|
|
760
833
|
])),
|
|
761
834
|
ownershipPrecondition,
|
|
835
|
+
xp.guard,
|
|
762
836
|
],
|
|
763
837
|
steps: [
|
|
764
838
|
{
|
|
765
839
|
describes: description,
|
|
766
840
|
instruction: adaptClaimStakeBuildingChangesInstruction({
|
|
841
|
+
...xp.accounts,
|
|
767
842
|
authorization: options.authorization,
|
|
768
843
|
buildingChanges: options.buildingChanges.map(({ buildingId, kind, quantity }) => [buildingId, kind === 'add' ? quantity : -quantity]),
|
|
769
844
|
celestialBody: stake.body.address,
|
|
@@ -789,6 +864,10 @@ export async function planClaimStakeBuildingChanges(ctx, stake, input) {
|
|
|
789
864
|
* CurrencyCache, and a known positive rent balance. Rent timing and the final
|
|
790
865
|
* crew/building validation remain chain-authoritative.
|
|
791
866
|
*
|
|
867
|
+
* Requires Game 2 and its existing canonical Claim Stake XP ledger.
|
|
868
|
+
* The Character XP budget and configuration must also be reconciled.
|
|
869
|
+
* Missing XP state must be repaired outside this Plan; no accounts are created.
|
|
870
|
+
*
|
|
792
871
|
* @example
|
|
793
872
|
* ```ts
|
|
794
873
|
* declare const ctx: SageContext;
|
|
@@ -804,22 +883,18 @@ export async function planClaimStakeBuildingChanges(ctx, stake, input) {
|
|
|
804
883
|
export async function planFinalizeClaimStakeBuildingChanges(ctx, stake, input) {
|
|
805
884
|
const options = validateFinalizeBuildingChangeOptions(input);
|
|
806
885
|
const game = requireGameAddress(ctx);
|
|
886
|
+
const { profile } = options.authorization;
|
|
807
887
|
if (stake.state.kind !== 'design') {
|
|
808
888
|
fail(`Claim Stake ${stake.address} is not in design state. Refresh it and finalize only a pending building design.`, stake.address);
|
|
809
889
|
}
|
|
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
|
-
}
|
|
890
|
+
const character = await requireOwnedStake(stake, game, profile);
|
|
817
891
|
if (stake.rentBalanceRaw <= 0n) {
|
|
818
892
|
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
893
|
}
|
|
820
|
-
const
|
|
894
|
+
const action = 'finalization';
|
|
895
|
+
const [freshGame, loaded] = await Promise.all([
|
|
821
896
|
readFreshGameClaimStakeConfiguration(ctx),
|
|
822
|
-
|
|
897
|
+
readOwnedStake(ctx, stake, action, [character]),
|
|
823
898
|
]);
|
|
824
899
|
if (freshGame === undefined) {
|
|
825
900
|
fail(`Configured Game ${game} is missing. Refresh the Game catalog and retry finalization.`, game);
|
|
@@ -828,75 +903,40 @@ export async function planFinalizeClaimStakeBuildingChanges(ctx, stake, input) {
|
|
|
828
903
|
freshGame.data.buildings.sequenceId !== stake.buildingDefinitionSeqId) {
|
|
829
904
|
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
905
|
}
|
|
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 ||
|
|
906
|
+
const { bodyAccount, currentStake, stakeAccount } = loaded;
|
|
907
|
+
if (!sameOwnedStake(currentStake, stake, game, character) ||
|
|
845
908
|
currentStake.rentBalanceRaw !== stake.rentBalanceRaw ||
|
|
846
|
-
!sameQuantities(currentStake.buildings, stake.buildings) ||
|
|
847
909
|
currentStake.state.kind !== 'design' ||
|
|
848
910
|
currentStake.state.sequenceId !== stake.state.sequenceId ||
|
|
849
911
|
!sameQuantities(currentStake.state.buildings, stake.state.buildings)) {
|
|
850
912
|
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
913
|
}
|
|
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');
|
|
914
|
+
const { system } = await requireStakePlanet(loaded.currentBody, stake, game, action);
|
|
915
|
+
const { account: characterAccount } = requireProfileCharacter(loaded.extraAccounts[0], character, profile, game, action);
|
|
916
|
+
const currencyCache = await claimStakeCurrencyCache(game);
|
|
917
|
+
const { currentSystem, extraAccounts: [currencyCandidate], player, playerAccount, systemAccount, } = await readStakeStarbase(ctx, stake, game, system, character, profile, action, [currencyCache]);
|
|
918
|
+
const currencyGuard = await requireCurrencyCache(currencyCandidate, currencyCache, game, action, 'Claim Stake finalization');
|
|
884
919
|
const description = `Finalize building changes on Claim Stake ${stake.address}.`;
|
|
920
|
+
const xp = await resolveClaimStakeXp(ctx, game, stake.address, character);
|
|
885
921
|
return createPlan({
|
|
886
922
|
kind: 'claim-stakes.finalize-building-changes',
|
|
887
|
-
preconditions:
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
923
|
+
preconditions: [
|
|
924
|
+
xp.guard,
|
|
925
|
+
...(await Promise.all([
|
|
926
|
+
precondition(freshGame.account, 'The configured Game remains current.'),
|
|
927
|
+
precondition(stakeAccount, `Claim Stake ${stake.address} retains its ownership, design sequence, rent balance, Body, and System generation.`),
|
|
928
|
+
characterPrecondition(characterAccount, profile),
|
|
929
|
+
planetPrecondition(bodyAccount, system),
|
|
930
|
+
systemPrecondition(systemAccount, currentSystem.name),
|
|
931
|
+
playerPrecondition(playerAccount, player),
|
|
932
|
+
])),
|
|
933
|
+
currencyGuard,
|
|
934
|
+
],
|
|
896
935
|
steps: [
|
|
897
936
|
{
|
|
898
937
|
describes: description,
|
|
899
938
|
instruction: adaptFinalizeClaimStakeBuildingChangesInstruction({
|
|
939
|
+
...xp.accounts,
|
|
900
940
|
authorization: options.authorization,
|
|
901
941
|
celestialBody: stake.body.address,
|
|
902
942
|
character,
|
|
@@ -920,6 +960,9 @@ export async function planFinalizeClaimStakeBuildingChanges(ctx, stake, input) {
|
|
|
920
960
|
* state; rent arithmetic and concurrent state transitions remain
|
|
921
961
|
* chain-authoritative.
|
|
922
962
|
*
|
|
963
|
+
* Requires Game 2 and its existing canonical Claim Stake XP ledger.
|
|
964
|
+
* Missing XP state must be repaired outside this Plan; no accounts are created.
|
|
965
|
+
*
|
|
923
966
|
* @example
|
|
924
967
|
* ```ts
|
|
925
968
|
* declare const ctx: SageContext;
|
|
@@ -934,80 +977,42 @@ export async function planFinalizeClaimStakeBuildingChanges(ctx, stake, input) {
|
|
|
934
977
|
export async function planCancelClaimStakeBuildingChanges(ctx, stake, input) {
|
|
935
978
|
const options = validateCancelBuildingChangeOptions(input);
|
|
936
979
|
const game = requireGameAddress(ctx);
|
|
980
|
+
const { profile } = options.authorization;
|
|
937
981
|
if (stake.state.kind !== 'design') {
|
|
938
982
|
fail(`Claim Stake ${stake.address} is not in design state. Refresh it and cancel only a pending building design.`, stake.address);
|
|
939
983
|
}
|
|
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) ||
|
|
984
|
+
const character = await requireOwnedStake(stake, game, profile);
|
|
985
|
+
const action = 'cancellation';
|
|
986
|
+
const { bodyAccount, currentBody, currentStake, stakeAccount } = await readOwnedStake(ctx, stake, action);
|
|
987
|
+
if (!sameOwnedStake(currentStake, stake, game, character) ||
|
|
964
988
|
currentStake.state.kind !== 'design' ||
|
|
965
989
|
currentStake.state.sequenceId !== stake.state.sequenceId ||
|
|
966
990
|
!sameQuantities(currentStake.state.buildings, stake.state.buildings)) {
|
|
967
991
|
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
992
|
}
|
|
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');
|
|
993
|
+
const { system } = await requireStakePlanet(currentBody, stake, game, action);
|
|
994
|
+
const currencyCache = await claimStakeCurrencyCache(game);
|
|
995
|
+
const { currentSystem, extraAccounts: [currencyCandidate], player, playerAccount, systemAccount, } = await readStakeStarbase(ctx, stake, game, system, character, profile, action, [currencyCache]);
|
|
996
|
+
const currencyGuard = await requireCurrencyCache(currencyCandidate, currencyCache, game, action, 'Claim Stake cancellation');
|
|
997
997
|
const description = `Cancel the pending building design on Claim Stake ${stake.address} and return it to active state.`;
|
|
998
|
+
const xp = await resolveClaimStakeXp(ctx, game, stake.address);
|
|
998
999
|
return createPlan({
|
|
999
1000
|
kind: 'claim-stakes.cancel-building-changes',
|
|
1000
|
-
preconditions:
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1001
|
+
preconditions: [
|
|
1002
|
+
xp.guard,
|
|
1003
|
+
...(await Promise.all([
|
|
1004
|
+
precondition(stakeAccount, `Claim Stake ${stake.address} retains its ownership, design sequence, buildings, Body, and System generation.`),
|
|
1005
|
+
planetPrecondition(bodyAccount, system),
|
|
1006
|
+
systemPrecondition(systemAccount, currentSystem.name),
|
|
1007
|
+
playerPrecondition(playerAccount, player),
|
|
1008
|
+
])),
|
|
1009
|
+
currencyGuard,
|
|
1010
|
+
],
|
|
1007
1011
|
steps: [
|
|
1008
1012
|
{
|
|
1009
1013
|
describes: description,
|
|
1010
1014
|
instruction: adaptCancelClaimStakeBuildingChangesInstruction({
|
|
1015
|
+
...xp.accounts,
|
|
1011
1016
|
authorization: options.authorization,
|
|
1012
1017
|
celestialBody: stake.body.address,
|
|
1013
1018
|
claimStakeInstance: stake.address,
|
|
@@ -1043,46 +1048,25 @@ export async function planCancelClaimStakeBuildingChanges(ctx, stake, input) {
|
|
|
1043
1048
|
export async function planDeconstructClaimStake(ctx, stake, input) {
|
|
1044
1049
|
const options = validateDeconstructOptions(input);
|
|
1045
1050
|
const game = requireGameAddress(ctx);
|
|
1051
|
+
const { profile } = options.authorization;
|
|
1046
1052
|
if (stake.state.kind !== 'active') {
|
|
1047
1053
|
fail(`Claim Stake ${stake.address} is not in active state. Refresh it, finalize or cancel any pending design, and retry deconstruction.`, stake.address);
|
|
1048
1054
|
}
|
|
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([
|
|
1055
|
+
const character = await requireOwnedStake(stake, game, profile);
|
|
1056
|
+
const action = 'deconstruction';
|
|
1057
|
+
const [freshGame, { bodyAccount, currentBody, currentStake, stakeAccount }] = await Promise.all([
|
|
1057
1058
|
readFreshGameClaimStakeConfiguration(ctx),
|
|
1058
|
-
|
|
1059
|
+
readOwnedStake(ctx, stake, action),
|
|
1059
1060
|
]);
|
|
1060
1061
|
if (freshGame === undefined) {
|
|
1061
1062
|
fail(`Configured Game ${game} is missing. Refresh the Game definitions and retry deconstruction.`, game);
|
|
1062
1063
|
}
|
|
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) ||
|
|
1064
|
+
if (!sameOwnedStake(currentStake, stake, game, character) ||
|
|
1076
1065
|
currentStake.state.kind !== 'active') {
|
|
1077
1066
|
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
1067
|
}
|
|
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
|
-
}
|
|
1068
|
+
const planet = await requireStakePlanet(currentBody, stake, game, action);
|
|
1069
|
+
const { system } = planet;
|
|
1086
1070
|
if (freshGame.data.claimStakes.sequenceId !== stake.claimStakeDefinitionSeqId) {
|
|
1087
1071
|
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
1072
|
}
|
|
@@ -1104,18 +1088,19 @@ export async function planDeconstructClaimStake(ctx, stake, input) {
|
|
|
1104
1088
|
bundledHub.hubValue !== claimDefinition.hubValue ||
|
|
1105
1089
|
bundledHub.minimumTier !== claimDefinition.tier ||
|
|
1106
1090
|
bundledHub.constructionCost.length !== 0) {
|
|
1091
|
+
// Only a building with a construction cost is player-funded; a zero-cost
|
|
1092
|
+
// hub from another definition family is a foreign bundled hub.
|
|
1107
1093
|
const hasPlayerFundedBuilding = stake.buildings.some((building) => {
|
|
1108
1094
|
const definition = definitions.get(building.buildingId);
|
|
1109
|
-
return (definition
|
|
1110
|
-
definition.hubValue !== claimDefinition.hubValue ||
|
|
1111
|
-
definition.minimumTier !== claimDefinition.tier ||
|
|
1112
|
-
definition.constructionCost.length !== 0);
|
|
1095
|
+
return (definition !== undefined && definition.constructionCost.length !== 0);
|
|
1113
1096
|
});
|
|
1114
1097
|
fail(hasPlayerFundedBuilding
|
|
1115
1098
|
? `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
|
-
:
|
|
1099
|
+
: bundledHub === undefined
|
|
1100
|
+
? `Claim Stake ${stake.address} does not contain exactly one verified bundled hub. Refresh it and restore the definition-compatible bundled hub before retrying deconstruction.`
|
|
1101
|
+
: `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
1102
|
}
|
|
1118
|
-
const groups =
|
|
1103
|
+
const groups = planet.details.claimedPlots.filter(({ key }) => key === claimDefinition.id);
|
|
1119
1104
|
if (groups.length !== 1) {
|
|
1120
1105
|
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
1106
|
}
|
|
@@ -1132,7 +1117,7 @@ export async function planDeconstructClaimStake(ctx, stake, input) {
|
|
|
1132
1117
|
}
|
|
1133
1118
|
const claimStakeIndex = chronologyMatches[0].index;
|
|
1134
1119
|
const tierIndex = TIER_INDEX[claimDefinition.tier];
|
|
1135
|
-
const plotCapacities =
|
|
1120
|
+
const plotCapacities = planet.details.claimStakePlots.map((row) => row[tierIndex]);
|
|
1136
1121
|
if (plotCapacities.some((capacity, index) => index > 0 && capacity < plotCapacities[index - 1])) {
|
|
1137
1122
|
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
1123
|
}
|
|
@@ -1141,31 +1126,8 @@ export async function planDeconstructClaimStake(ctx, stake, input) {
|
|
|
1141
1126
|
}
|
|
1142
1127
|
const plotLevelIndex = plotCapacities.findIndex((capacity) => claimStakeIndex < capacity);
|
|
1143
1128
|
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
|
-
}
|
|
1129
|
+
const { currentSystem, extraAccounts: [characterCandidate], player, playerAccount, systemAccount, } = await readStakeStarbase(ctx, stake, game, system, character, profile, action, [character]);
|
|
1130
|
+
const { account: characterAccount } = requireProfileCharacter(characterCandidate, character, profile, game, action);
|
|
1169
1131
|
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
1132
|
return createPlan({
|
|
1171
1133
|
kind: 'claim-stakes.deconstruct',
|
|
@@ -1173,9 +1135,9 @@ export async function planDeconstructClaimStake(ctx, stake, input) {
|
|
|
1173
1135
|
precondition(freshGame.account, `The configured Game retains Claim Stake definition ${String(claimDefinition.id)}, bundled hub ${String(bundledHub.id)}, and their current generations.`),
|
|
1174
1136
|
precondition(stakeAccount, `Claim Stake ${stake.address} retains its ownership, active state, definitions, bundled hub, Body, and System generation.`),
|
|
1175
1137
|
precondition(bodyAccount, `The Planet retains Claim Stake ${stake.address} at chronology index ${String(claimStakeIndex)} in definition group ${String(claimDefinition.id)}.`),
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1138
|
+
characterPrecondition(characterAccount, profile),
|
|
1139
|
+
systemPrecondition(systemAccount, currentSystem.name),
|
|
1140
|
+
playerPrecondition(playerAccount, player),
|
|
1179
1141
|
]),
|
|
1180
1142
|
steps: [
|
|
1181
1143
|
{
|
|
@@ -1219,86 +1181,34 @@ export async function planDeconstructClaimStake(ctx, stake, input) {
|
|
|
1219
1181
|
export async function planTopUpClaimStakeRent(ctx, stake, input) {
|
|
1220
1182
|
const options = validateTopUpRentOptions(input);
|
|
1221
1183
|
const game = requireGameAddress(ctx);
|
|
1184
|
+
const { profile } = options.authorization;
|
|
1222
1185
|
const loadedState = stake.state;
|
|
1223
1186
|
if (loadedState.kind === 'deactivated') {
|
|
1224
1187
|
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
1188
|
}
|
|
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 ||
|
|
1189
|
+
const character = await requireOwnedStake(stake, game, profile);
|
|
1190
|
+
const action = 'the rent top-up';
|
|
1191
|
+
const { bodyAccount, currentBody, currentStake, extraAccounts: [characterCandidate], stakeAccount, } = await readOwnedStake(ctx, stake, action, [character]);
|
|
1192
|
+
if (!sameOwnedStake(currentStake, stake, game, character) ||
|
|
1252
1193
|
currentStake.rentBalanceRaw !== stake.rentBalanceRaw ||
|
|
1253
|
-
!sameQuantities(currentStake.buildings, stake.buildings) ||
|
|
1254
1194
|
!sameStakeState(currentStake.state, loadedState)) {
|
|
1255
1195
|
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
1196
|
}
|
|
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
|
-
}
|
|
1197
|
+
const { system } = await requireStakePlanet(currentBody, stake, game, action);
|
|
1198
|
+
const { account: characterAccount, current: currentCharacter } = requireProfileCharacter(characterCandidate, character, profile, game, action);
|
|
1268
1199
|
if (currentCharacter.atlasRaw < options.amount) {
|
|
1269
1200
|
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
1201
|
}
|
|
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
|
-
}
|
|
1202
|
+
const { currentSystem, player, playerAccount, systemAccount } = await readStakeStarbase(ctx, stake, game, system, character, profile, action);
|
|
1293
1203
|
const description = `Top up Claim Stake ${stake.address} rent with ${String(options.amount)} raw rent units; rent arithmetic remains chain-authoritative.`;
|
|
1294
1204
|
return createPlan({
|
|
1295
1205
|
kind: 'claim-stakes.top-up-rent',
|
|
1296
1206
|
preconditions: await Promise.all([
|
|
1297
1207
|
precondition(stakeAccount, `Claim Stake ${stake.address} retains its ownership, rent balance, placed state, Body, and System generation.`),
|
|
1298
|
-
|
|
1299
|
-
precondition(characterAccount, `The canonical Character remains assigned to Profile ${
|
|
1300
|
-
|
|
1301
|
-
|
|
1208
|
+
planetPrecondition(bodyAccount, system),
|
|
1209
|
+
precondition(characterAccount, `The canonical Character remains assigned to Profile ${profile} with at least ${String(options.amount)} known raw ATLAS.`),
|
|
1210
|
+
systemPrecondition(systemAccount, currentSystem.name),
|
|
1211
|
+
playerPrecondition(playerAccount, player),
|
|
1302
1212
|
]),
|
|
1303
1213
|
steps: [
|
|
1304
1214
|
{
|
|
@@ -1357,6 +1267,9 @@ function describeCargoRequests(direction, requests) {
|
|
|
1357
1267
|
* FleetCrewBinding. The chain remains authoritative for range, duration,
|
|
1358
1268
|
* permission bits, concurrent state changes, and transfer arithmetic.
|
|
1359
1269
|
*
|
|
1270
|
+
* Requires Game 2 and its existing canonical Claim Stake XP ledger.
|
|
1271
|
+
* Missing XP state must be repaired outside this Plan; no accounts are created.
|
|
1272
|
+
*
|
|
1360
1273
|
* @example
|
|
1361
1274
|
* ```ts
|
|
1362
1275
|
* declare const ctx: SageContext;
|
|
@@ -1374,119 +1287,53 @@ function describeCargoRequests(direction, requests) {
|
|
|
1374
1287
|
export async function planStartClaimStakeFleetTransfer(ctx, fleet, stake, input) {
|
|
1375
1288
|
const options = validateStartFleetTransferOptions(input);
|
|
1376
1289
|
const game = requireGameAddress(ctx);
|
|
1290
|
+
const { profile } = options.authorization;
|
|
1377
1291
|
if (fleet.game !== game || stake.game !== game) {
|
|
1378
1292
|
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
1293
|
}
|
|
1380
|
-
if (fleet.ownerProfile.address !==
|
|
1381
|
-
fail(`Fleet ${fleet.name} belongs to Profile ${fleet.ownerProfile.address}, not authorization Profile ${
|
|
1294
|
+
if (fleet.ownerProfile.address !== profile) {
|
|
1295
|
+
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
1296
|
}
|
|
1383
1297
|
if (fleet.state.kind !== 'idle') {
|
|
1384
1298
|
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
1299
|
}
|
|
1300
|
+
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
1301
|
if (!Number.isSafeInteger(fleet.crewCount) || fleet.crewCount <= 0) {
|
|
1387
|
-
fail(
|
|
1302
|
+
fail(crewFailure, fleet.address);
|
|
1388
1303
|
}
|
|
1389
1304
|
if (stake.state.kind !== 'active') {
|
|
1390
1305
|
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
1306
|
}
|
|
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.`);
|
|
1307
|
+
const character = await requireOwnedStake(stake, game, profile);
|
|
1308
|
+
const action = 'the Fleet transfer';
|
|
1309
|
+
const { bodyAccount, currentBody, currentStake, extraAccounts: [fleetCandidate, characterCandidate], stakeAccount, } = await readOwnedStake(ctx, stake, action, [fleet.address, character]);
|
|
1310
|
+
const fleetAccount = requireAccount(fleetCandidate, fleet.address, `Fleet ${fleet.name} is missing. Refresh it and retry the Fleet transfer.`);
|
|
1406
1311
|
const currentFleet = fleetAccountDefinition.decode(fleetAccount);
|
|
1407
|
-
const currentStake = claimStakeAccountDefinition.decode(stakeAccount);
|
|
1408
|
-
const currentBody = celestialBodyAccountDefinition.decode(bodyAccount);
|
|
1409
|
-
const currentCharacter = characterAccountDefinition.decode(characterAccount);
|
|
1410
1312
|
if (!Number.isSafeInteger(currentFleet.crewCount) ||
|
|
1411
1313
|
currentFleet.crewCount <= 0) {
|
|
1412
|
-
fail(
|
|
1314
|
+
fail(crewFailure, fleet.address);
|
|
1413
1315
|
}
|
|
1414
|
-
if (currentFleet
|
|
1415
|
-
currentFleet.ownerProfile !== options.authorization.profile ||
|
|
1416
|
-
currentFleet.name !== fleet.name ||
|
|
1316
|
+
if (!sameTransferFleet(currentFleet, fleet, game, profile) ||
|
|
1417
1317
|
currentFleet.state.kind !== 'idle' ||
|
|
1418
1318
|
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) {
|
|
1319
|
+
(await deriveFleetAddress(currentFleet)) !== fleet.address) {
|
|
1429
1320
|
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
1321
|
}
|
|
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
|
-
})))) {
|
|
1322
|
+
if (!sameTransferStake(currentStake, stake, game, character)) {
|
|
1444
1323
|
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
1324
|
}
|
|
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,
|
|
1325
|
+
const { system } = await requireStakePlanet(currentBody, stake, game, action);
|
|
1326
|
+
const { account: characterAccount } = requireProfileCharacter(characterCandidate, character, profile, game, action);
|
|
1327
|
+
const [currencyCache, crewBinding] = await Promise.all([
|
|
1328
|
+
claimStakeCurrencyCache(game),
|
|
1329
|
+
deriveFleetCrewBindingAddress(fleet.address),
|
|
1466
1330
|
]);
|
|
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');
|
|
1331
|
+
const { currentSystem, extraAccounts: [currencyCandidate, crewCandidate], player, playerAccount, systemAccount, } = await readStakeStarbase(ctx, stake, game, system, character, profile, action, [currencyCache, crewBinding]);
|
|
1332
|
+
const currencyGuard = await requireCurrencyCache(currencyCandidate, currencyCache, game, action, 'Claim Stake Fleet transfer');
|
|
1485
1333
|
if (crewCandidate !== undefined) {
|
|
1486
1334
|
const currentCrewBinding = fleetCrewBindingAccountDefinition.decode(crewCandidate);
|
|
1487
1335
|
if (crewCandidate.address !== crewBinding ||
|
|
1488
|
-
currentCrewBinding
|
|
1489
|
-
currentCrewBinding.ownerProfile !== options.authorization.profile) {
|
|
1336
|
+
!matchesFleetCrewBindingIdentity(currentCrewBinding, fleet.address, profile)) {
|
|
1490
1337
|
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
1338
|
}
|
|
1492
1339
|
}
|
|
@@ -1509,37 +1356,43 @@ export async function planStartClaimStakeFleetTransfer(ctx, fleet, stake, input)
|
|
|
1509
1356
|
const loadCargoStorage = options.load
|
|
1510
1357
|
.filter(({ cargoId }) => cargoId !== currentFleet.ammoBank.cargoId &&
|
|
1511
1358
|
cargoId !== currentFleet.fuelTank.cargoId)
|
|
1512
|
-
.reduce((total, { amount, cargoId }) => total +
|
|
1359
|
+
.reduce((total, { amount, cargoId }) => total +
|
|
1360
|
+
cargoStorageUnits(amount, definitions.get(cargoId).storageCost), 0n);
|
|
1513
1361
|
requireTransferCapacity(`Fleet ${fleet.name} ammo destination`, fleet.address, currentFleet.ammoBank.amount, loadAmmo, currentFleet.stats.cargo.ammoCapacity);
|
|
1514
1362
|
requireTransferCapacity(`Fleet ${fleet.name} fuel destination`, fleet.address, currentFleet.fuelTank.amount, loadFuel, currentFleet.stats.cargo.fuelCapacity);
|
|
1515
1363
|
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
|
|
1364
|
+
const unloadStorage = options.unload.reduce((total, { amount, cargoId }) => total + cargoStorageUnits(amount, definitions.get(cargoId).storageCost), 0n);
|
|
1517
1365
|
requireTransferCapacity(`Claim Stake ${stake.address} resource destination`, stake.address, currentStake.production.cargoPod.storageCost, unloadStorage, currentStake.production.resourceCapacityRaw);
|
|
1518
1366
|
const descriptions = [
|
|
1519
1367
|
...describeCargoRequests('load', options.load),
|
|
1520
1368
|
...describeCargoRequests('unload', options.unload),
|
|
1521
1369
|
];
|
|
1522
1370
|
const description = `Start fleet ${fleet.name}'s transfer to Claim Stake ${stake.address}: ${descriptions.join('; ')}. Range and transfer duration remain chain-authoritative.`;
|
|
1371
|
+
const xp = await resolveClaimStakeXp(ctx, game, stake.address);
|
|
1523
1372
|
return createPlan({
|
|
1524
1373
|
kind: 'claim-stakes.start-fleet-transfer',
|
|
1525
|
-
preconditions:
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1374
|
+
preconditions: [
|
|
1375
|
+
xp.guard,
|
|
1376
|
+
...(await Promise.all([
|
|
1377
|
+
precondition(fleetAccount, `Fleet ${fleet.name} retains its owner, name, idle state, normalized crew, cargo balances, and destination capacities.`),
|
|
1378
|
+
precondition(stakeAccount, `Claim Stake ${stake.address} retains its owner, active state, cargo balances, destination capacity, Body, and System generation.`),
|
|
1379
|
+
planetPrecondition(bodyAccount, system),
|
|
1380
|
+
characterPrecondition(characterAccount, profile),
|
|
1381
|
+
systemPrecondition(systemAccount, currentSystem.name),
|
|
1382
|
+
playerPrecondition(playerAccount, player),
|
|
1383
|
+
...(crewCandidate === undefined
|
|
1384
|
+
? []
|
|
1385
|
+
: [
|
|
1386
|
+
precondition(crewCandidate, `Fleet ${fleet.name}'s optional FleetCrewBinding remains assigned to the Fleet and owner Profile.`),
|
|
1387
|
+
]),
|
|
1388
|
+
])),
|
|
1389
|
+
currencyGuard,
|
|
1390
|
+
],
|
|
1539
1391
|
steps: [
|
|
1540
1392
|
{
|
|
1541
1393
|
describes: description,
|
|
1542
1394
|
instruction: adaptStartClaimStakeFleetTransferInstruction({
|
|
1395
|
+
...xp.accounts,
|
|
1543
1396
|
authorization: options.authorization,
|
|
1544
1397
|
celestialBody: stake.body.address,
|
|
1545
1398
|
character,
|
|
@@ -1606,10 +1459,7 @@ export async function planRecoverClaimStakeFleetTransfer(ctx, fleet, stake, inpu
|
|
|
1606
1459
|
if (options.atUnixSeconds < fleet.state.endAtUnixSeconds) {
|
|
1607
1460
|
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
1461
|
}
|
|
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
|
-
}
|
|
1462
|
+
const character = await requireOwnedStake(stake, game, options.authorization.profile);
|
|
1613
1463
|
const [fleetCandidate, stakeCandidate] = await readContextRawAccounts(ctx, [
|
|
1614
1464
|
fleet.address,
|
|
1615
1465
|
stake.address,
|
|
@@ -1618,40 +1468,17 @@ export async function planRecoverClaimStakeFleetTransfer(ctx, fleet, stake, inpu
|
|
|
1618
1468
|
const stakeAccount = requireAccount(stakeCandidate, stake.address, `Claim Stake ${stake.address} is missing. Refresh it and retry Fleet transfer recovery.`);
|
|
1619
1469
|
const currentFleet = fleetAccountDefinition.decode(fleetAccount);
|
|
1620
1470
|
const currentStake = claimStakeAccountDefinition.decode(stakeAccount);
|
|
1621
|
-
if (currentFleet
|
|
1622
|
-
currentFleet.ownerProfile !== options.authorization.profile ||
|
|
1623
|
-
currentFleet.name !== fleet.name ||
|
|
1471
|
+
if (!sameTransferFleet(currentFleet, fleet, game, options.authorization.profile) ||
|
|
1624
1472
|
currentFleet.state.kind !== 'claimStakeTransfer' ||
|
|
1625
1473
|
currentFleet.state.claimStake !== stake.address ||
|
|
1626
1474
|
currentFleet.state.planet !== stake.body.address ||
|
|
1627
1475
|
currentFleet.state.endAtUnixSeconds !== fleet.state.endAtUnixSeconds ||
|
|
1628
1476
|
!sameCargoAmounts(currentFleet.state.load, fleet.state.load) ||
|
|
1629
1477
|
!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) {
|
|
1478
|
+
(await deriveFleetAddress(currentFleet)) !== fleet.address) {
|
|
1640
1479
|
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
1480
|
}
|
|
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
|
-
})))) {
|
|
1481
|
+
if (!sameTransferStake(currentStake, stake, game, character)) {
|
|
1655
1482
|
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
1483
|
}
|
|
1657
1484
|
let reason;
|
|
@@ -1695,8 +1522,10 @@ export async function planRecoverClaimStakeFleetTransfer(ctx, fleet, stake, inpu
|
|
|
1695
1522
|
const loadCargoStorage = currentFleet.state.load
|
|
1696
1523
|
.filter(({ cargoId }) => cargoId !== currentFleet.ammoBank.cargoId &&
|
|
1697
1524
|
cargoId !== currentFleet.fuelTank.cargoId)
|
|
1698
|
-
.reduce((total, { amount, cargoId }) => total +
|
|
1699
|
-
|
|
1525
|
+
.reduce((total, { amount, cargoId }) => total +
|
|
1526
|
+
cargoStorageUnits(amount, queuedDefinitions.get(cargoId).storageCost), 0n);
|
|
1527
|
+
const unloadStorage = currentFleet.state.unload.reduce((total, { amount, cargoId }) => total +
|
|
1528
|
+
cargoStorageUnits(amount, queuedDefinitions.get(cargoId).storageCost), 0n);
|
|
1700
1529
|
if (currentFleet.ammoBank.amount + loadAmmo >
|
|
1701
1530
|
currentFleet.stats.cargo.ammoCapacity) {
|
|
1702
1531
|
reason = 'Fleet ammo destination overflow';
|