diff --git a/clients/bolt-sdk/idl/world.json b/clients/bolt-sdk/idl/world.json index 89e5aba4..7f63cef8 100644 --- a/clients/bolt-sdk/idl/world.json +++ b/clients/bolt-sdk/idl/world.json @@ -75,7 +75,7 @@ ], "args": [ { - "name": "seed", + "name": "extraSeed", "type": { "option": "string" } diff --git a/clients/bolt-sdk/src/generated/idl/world.json b/clients/bolt-sdk/src/generated/idl/world.json index 91e6cc3d..10ff4100 100644 --- a/clients/bolt-sdk/src/generated/idl/world.json +++ b/clients/bolt-sdk/src/generated/idl/world.json @@ -78,7 +78,7 @@ ], "args": [ { - "name": "seed", + "name": "extra_seed", "type": { "option": "bytes" } diff --git a/clients/bolt-sdk/src/generated/instructions/addEntity.ts b/clients/bolt-sdk/src/generated/instructions/addEntity.ts index 17041bbd..fb7914cd 100644 --- a/clients/bolt-sdk/src/generated/instructions/addEntity.ts +++ b/clients/bolt-sdk/src/generated/instructions/addEntity.ts @@ -14,7 +14,7 @@ import * as web3 from "@solana/web3.js"; * @category generated */ export interface AddEntityInstructionArgs { - seed: beet.COption; + extraSeed: beet.COption; } /** * @category Instructions @@ -28,7 +28,7 @@ export const addEntityStruct = new beet.FixableBeetArgsStruct< >( [ ["instructionDiscriminator", beet.uniformFixedSizeArray(beet.u8, 8)], - ["seed", beet.coption(beet.bytes)], + ["extraSeed", beet.coption(beet.bytes)], ], "AddEntityInstructionArgs", ); diff --git a/clients/bolt-sdk/src/generated/types/world.ts b/clients/bolt-sdk/src/generated/types/world.ts index e90d576b..210532f6 100644 --- a/clients/bolt-sdk/src/generated/types/world.ts +++ b/clients/bolt-sdk/src/generated/types/world.ts @@ -66,7 +66,7 @@ export type World = { ]; args: [ { - name: "seed"; + name: "extra_seed"; type: { option: "bytes"; }; diff --git a/clients/bolt-sdk/src/index.ts b/clients/bolt-sdk/src/index.ts index b64c026d..82182900 100644 --- a/clients/bolt-sdk/src/index.ts +++ b/clients/bolt-sdk/src/index.ts @@ -1,7 +1,7 @@ import { PublicKey } from "@solana/web3.js"; import type BN from "bn.js"; -import * as PROGRAM_IDL from "./world/idl.json"; import { PROGRAM_ID } from "./generated"; +import { World as PROGRAM_IDL } from "./generated/types/world"; export * from "./generated/accounts"; export * from "./generated/instructions"; export * from "./world/transactions"; @@ -42,22 +42,23 @@ export function FindWorldPda({ } export function FindEntityPda({ - world, + worldId, entityId, seed, programId, }: { - world: PublicKey; + worldId: BN; entityId?: BN; seed?: Uint8Array; programId?: PublicKey; }) { - const seeds = [Buffer.from("entity"), world.toBytes()]; + const worldIdBuffer = Buffer.from(worldId.toArrayLike(Buffer, "be", 8)); + const seeds = [Buffer.from("entity"), worldIdBuffer]; if (seed !== undefined) { seeds.push(Buffer.from(new Uint8Array(8))); seeds.push(Buffer.from(seed)); } else if (entityId !== undefined) { - const entityIdBuffer = entityId.toArrayLike(Buffer, "be", 8); + const entityIdBuffer = Buffer.from(entityId.toArrayLike(Buffer, "be", 8)); seeds.push(entityIdBuffer); } else { throw new Error("An entity must have either an Id or a Seed"); diff --git a/clients/bolt-sdk/src/world/idl.json b/clients/bolt-sdk/src/world/idl.json deleted file mode 100644 index 91e6cc3d..00000000 --- a/clients/bolt-sdk/src/world/idl.json +++ /dev/null @@ -1,698 +0,0 @@ -{ - "address": "WorLD15A7CrDwLcLy4fRqtaTb9fbd8o8iqiEMUDse2n", - "metadata": { - "name": "world", - "version": "0.1.12", - "spec": "0.1.0", - "description": "Bolt World program", - "repository": "https://github.com/magicblock-labs/bolt" - }, - "instructions": [ - { - "name": "add_authority", - "discriminator": [ - 229, - 9, - 106, - 73, - 91, - 213, - 109, - 183 - ], - "accounts": [ - { - "name": "authority", - "writable": true, - "signer": true - }, - { - "name": "new_authority" - }, - { - "name": "world", - "writable": true - }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - } - ], - "args": [ - { - "name": "world_id", - "type": "u64" - } - ] - }, - { - "name": "add_entity", - "discriminator": [ - 163, - 241, - 57, - 35, - 244, - 244, - 48, - 57 - ], - "accounts": [ - { - "name": "payer", - "writable": true, - "signer": true - }, - { - "name": "entity", - "writable": true - }, - { - "name": "world", - "writable": true - }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - } - ], - "args": [ - { - "name": "seed", - "type": { - "option": "bytes" - } - } - ] - }, - { - "name": "apply", - "discriminator": [ - 248, - 243, - 145, - 24, - 105, - 50, - 162, - 225 - ], - "accounts": [ - { - "name": "component_program" - }, - { - "name": "bolt_system" - }, - { - "name": "bolt_component", - "writable": true - }, - { - "name": "authority", - "signer": true - }, - { - "name": "instruction_sysvar_account", - "address": "Sysvar1nstructions1111111111111111111111111" - }, - { - "name": "world" - } - ], - "args": [ - { - "name": "args", - "type": "bytes" - } - ] - }, - { - "name": "apply2", - "discriminator": [ - 120, - 32, - 116, - 154, - 158, - 159, - 208, - 73 - ], - "accounts": [ - { - "name": "bolt_system" - }, - { - "name": "component_program_1" - }, - { - "name": "bolt_component_1", - "writable": true - }, - { - "name": "component_program_2" - }, - { - "name": "bolt_component_2", - "writable": true - }, - { - "name": "authority", - "signer": true - }, - { - "name": "instruction_sysvar_account", - "address": "Sysvar1nstructions1111111111111111111111111" - }, - { - "name": "world" - } - ], - "args": [ - { - "name": "args", - "type": "bytes" - } - ] - }, - { - "name": "apply3", - "discriminator": [ - 254, - 146, - 49, - 7, - 236, - 131, - 105, - 221 - ], - "accounts": [ - { - "name": "bolt_system" - }, - { - "name": "component_program_1" - }, - { - "name": "bolt_component_1", - "writable": true - }, - { - "name": "component_program_2" - }, - { - "name": "bolt_component_2", - "writable": true - }, - { - "name": "component_program_3" - }, - { - "name": "bolt_component_3", - "writable": true - }, - { - "name": "authority", - "signer": true - }, - { - "name": "instruction_sysvar_account", - "address": "Sysvar1nstructions1111111111111111111111111" - }, - { - "name": "world" - } - ], - "args": [ - { - "name": "args", - "type": "bytes" - } - ] - }, - { - "name": "apply4", - "discriminator": [ - 223, - 104, - 24, - 79, - 252, - 196, - 14, - 109 - ], - "accounts": [ - { - "name": "bolt_system" - }, - { - "name": "component_program_1" - }, - { - "name": "bolt_component_1", - "writable": true - }, - { - "name": "component_program_2" - }, - { - "name": "bolt_component_2", - "writable": true - }, - { - "name": "component_program_3" - }, - { - "name": "bolt_component_3", - "writable": true - }, - { - "name": "component_program_4" - }, - { - "name": "bolt_component_4", - "writable": true - }, - { - "name": "authority", - "signer": true - }, - { - "name": "instruction_sysvar_account", - "address": "Sysvar1nstructions1111111111111111111111111" - }, - { - "name": "world" - } - ], - "args": [ - { - "name": "args", - "type": "bytes" - } - ] - }, - { - "name": "apply5", - "discriminator": [ - 70, - 164, - 214, - 28, - 136, - 116, - 84, - 153 - ], - "accounts": [ - { - "name": "bolt_system" - }, - { - "name": "component_program_1" - }, - { - "name": "bolt_component_1", - "writable": true - }, - { - "name": "component_program_2" - }, - { - "name": "bolt_component_2", - "writable": true - }, - { - "name": "component_program_3" - }, - { - "name": "bolt_component_3", - "writable": true - }, - { - "name": "component_program_4" - }, - { - "name": "bolt_component_4", - "writable": true - }, - { - "name": "component_program_5" - }, - { - "name": "bolt_component_5", - "writable": true - }, - { - "name": "authority", - "signer": true - }, - { - "name": "instruction_sysvar_account", - "address": "Sysvar1nstructions1111111111111111111111111" - }, - { - "name": "world" - } - ], - "args": [ - { - "name": "args", - "type": "bytes" - } - ] - }, - { - "name": "approve_system", - "discriminator": [ - 114, - 165, - 105, - 68, - 52, - 67, - 207, - 121 - ], - "accounts": [ - { - "name": "authority", - "writable": true, - "signer": true - }, - { - "name": "world", - "writable": true - }, - { - "name": "system" - }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - } - ], - "args": [] - }, - { - "name": "initialize_component", - "discriminator": [ - 36, - 143, - 233, - 113, - 12, - 234, - 61, - 30 - ], - "accounts": [ - { - "name": "payer", - "writable": true, - "signer": true - }, - { - "name": "data", - "writable": true - }, - { - "name": "entity" - }, - { - "name": "component_program" - }, - { - "name": "authority" - }, - { - "name": "instruction_sysvar_account", - "address": "Sysvar1nstructions1111111111111111111111111" - }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - } - ], - "args": [] - }, - { - "name": "initialize_new_world", - "discriminator": [ - 23, - 96, - 88, - 194, - 200, - 203, - 200, - 98 - ], - "accounts": [ - { - "name": "payer", - "writable": true, - "signer": true - }, - { - "name": "world", - "writable": true - }, - { - "name": "registry", - "writable": true - }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - } - ], - "args": [] - }, - { - "name": "initialize_registry", - "discriminator": [ - 189, - 181, - 20, - 17, - 174, - 57, - 249, - 59 - ], - "accounts": [ - { - "name": "registry", - "writable": true - }, - { - "name": "payer", - "writable": true, - "signer": true - }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - } - ], - "args": [] - }, - { - "name": "remove_authority", - "discriminator": [ - 242, - 104, - 208, - 132, - 190, - 250, - 74, - 216 - ], - "accounts": [ - { - "name": "authority", - "writable": true, - "signer": true - }, - { - "name": "authority_to_delete" - }, - { - "name": "world", - "writable": true - }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - } - ], - "args": [ - { - "name": "world_id", - "type": "u64" - } - ] - }, - { - "name": "remove_system", - "discriminator": [ - 218, - 80, - 71, - 80, - 161, - 130, - 149, - 120 - ], - "accounts": [ - { - "name": "authority", - "writable": true, - "signer": true - }, - { - "name": "world", - "writable": true - }, - { - "name": "system" - }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - } - ], - "args": [] - } - ], - "accounts": [ - { - "name": "Entity", - "discriminator": [ - 46, - 157, - 161, - 161, - 254, - 46, - 79, - 24 - ] - }, - { - "name": "Registry", - "discriminator": [ - 47, - 174, - 110, - 246, - 184, - 182, - 252, - 218 - ] - }, - { - "name": "World", - "discriminator": [ - 145, - 45, - 170, - 174, - 122, - 32, - 155, - 124 - ] - } - ], - "errors": [ - { - "code": 6000, - "name": "InvalidAuthority", - "msg": "Invalid authority for instruction" - }, - { - "code": 6001, - "name": "WorldAccountMismatch", - "msg": "The provided world account does not match the expected PDA." - }, - { - "code": 6002, - "name": "TooManyAuthorities", - "msg": "Exceed the maximum number of authorities." - }, - { - "code": 6003, - "name": "AuthorityNotFound", - "msg": "The provided authority not found" - }, - { - "code": 6004, - "name": "SystemNotApproved", - "msg": "The system is not approved in this world instance" - } - ], - "types": [ - { - "name": "Entity", - "type": { - "kind": "struct", - "fields": [ - { - "name": "id", - "type": "u64" - } - ] - } - }, - { - "name": "Registry", - "type": { - "kind": "struct", - "fields": [ - { - "name": "worlds", - "type": "u64" - } - ] - } - }, - { - "name": "World", - "type": { - "kind": "struct", - "fields": [ - { - "name": "id", - "type": "u64" - }, - { - "name": "entities", - "type": "u64" - }, - { - "name": "authorities", - "type": { - "vec": "pubkey" - } - }, - { - "name": "permissionless", - "type": "bool" - }, - { - "name": "systems", - "type": "bytes" - } - ] - } - } - ] -} \ No newline at end of file diff --git a/clients/bolt-sdk/src/world/transactions.ts b/clients/bolt-sdk/src/world/transactions.ts index 43b38ab9..a7c999c6 100644 --- a/clients/bolt-sdk/src/world/transactions.ts +++ b/clients/bolt-sdk/src/world/transactions.ts @@ -65,6 +65,7 @@ export async function InitializeNewWorld({ instruction: TransactionInstruction; transaction: Transaction; worldPda: PublicKey; + worldId: BN; }> { const registryPda = FindRegistryPda({}); const registry = await Registry.fromAccountAddress(connection, registryPda); @@ -80,6 +81,7 @@ export async function InitializeNewWorld({ instruction, transaction, worldPda, + worldId, }; } @@ -263,21 +265,19 @@ export async function AddEntity({ transaction: Transaction; entityPda: PublicKey; }> { - let entityPda: PublicKey; - if (seed !== undefined) { - entityPda = FindEntityPda({ world, seed }); - } else { - const worldData = await World.fromAccountAddress(connection, world); - const entityId = new BN(worldData.entities); - entityPda = FindEntityPda({ world, entityId }); - } + const worldInstance = await World.fromAccountAddress(connection, world); + const worldId = new BN(worldInstance.id); + const entityPda = + seed !== undefined + ? FindEntityPda({ worldId, seed }) + : FindEntityPda({ worldId, entityId: new BN(worldInstance.entities) }); const instruction = createAddEntityInstruction( { world, payer, entity: entityPda, }, - { seed: seed ?? null }, + { extraSeed: seed ?? null }, ); const transaction = new Transaction().add(instruction); return { @@ -322,7 +322,7 @@ export async function InitializeComponent({ entity, data: componentPda, componentProgram: componentId, - authority: authority ?? PROGRAM_ID, // TODO: Should this be handled on the program side? + authority: authority ?? PROGRAM_ID, instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY, anchorRemainingAccounts, }); diff --git a/crates/programs/world/src/lib.rs b/crates/programs/world/src/lib.rs index df499f1a..20829176 100644 --- a/crates/programs/world/src/lib.rs +++ b/crates/programs/world/src/lib.rs @@ -248,7 +248,7 @@ pub mod world { } #[allow(unused_variables)] - pub fn add_entity(ctx: Context, seed: Option>) -> Result<()> { + pub fn add_entity(ctx: Context, extra_seed: Option>) -> Result<()> { require!( ctx.accounts.world.key() == ctx.accounts.world.pda().0, WorldError::WorldAccountMismatch @@ -404,16 +404,16 @@ pub struct RemoveSystem<'info> { } #[derive(Accounts)] -#[instruction(seed: Option>)] +#[instruction(extra_seed: Option>)] pub struct AddEntity<'info> { #[account(mut)] pub payer: Signer<'info>, - #[account(init, payer = payer, space = World::size(), seeds = [Entity::seed(), &world.key().to_bytes(), - &match seed { + #[account(init, payer = payer, space = World::size(), seeds = [Entity::seed(), &world.id.to_be_bytes(), + &match extra_seed { Some(ref seed) => [0; 8], None => world.entities.to_be_bytes() }, - match seed { + match extra_seed { Some(ref seed) => seed, None => &[], }], bump)] diff --git a/tests/bolt.low-level.api.ts b/tests/bolt.low-level.api.ts index 14647f7e..5dc0b3cf 100644 --- a/tests/bolt.low-level.api.ts +++ b/tests/bolt.low-level.api.ts @@ -209,7 +209,7 @@ describe("bolt", () => { it("Add entity 1", async () => { const world = await worldProgram.account.world.fetch(worldPda); - entity1Pda = FindEntityPda({ world: worldPda, entityId: world.entities }); + entity1Pda = FindEntityPda({ worldId: world.id, entityId: world.entities }); const instruction = await worldProgram.methods .addEntity(null) .accounts({ @@ -225,7 +225,7 @@ describe("bolt", () => { it("Add entity 2", async () => { const world = await worldProgram.account.world.fetch(worldPda); - entity2Pda = FindEntityPda({ world: worldPda, entityId: world.entities }); + entity2Pda = FindEntityPda({ worldId: world.id, entityId: world.entities }); const instruction = await worldProgram.methods .addEntity(null) .accounts({ @@ -242,7 +242,7 @@ describe("bolt", () => { it("Add entity 3", async () => { const world = await worldProgram.account.world.fetch(worldPda); const entity3Pda = FindEntityPda({ - world: worldPda, + worldId: world.id, entityId: world.entities, }); const instruction = await worldProgram.methods @@ -259,8 +259,9 @@ describe("bolt", () => { }); it("Add entity 4 (with seed)", async () => { + const world = await worldProgram.account.world.fetch(worldPda); const seed = Buffer.from("custom-seed"); - entity4Pda = FindEntityPda({ world: worldPda, seed }); + entity4Pda = FindEntityPda({ worldId: world.id, seed }); const instruction = await worldProgram.methods .addEntity(seed) .accounts({ @@ -276,7 +277,7 @@ describe("bolt", () => { it("Add entity 5", async () => { const world = await worldProgram.account.world.fetch(worldPda); - entity5Pda = FindEntityPda({ world: worldPda, entityId: world.entities }); + entity5Pda = FindEntityPda({ worldId: world.id, entityId: world.entities }); const instruction = await worldProgram.methods .addEntity(null) .accounts({