import { Keypair, type PublicKey } from "@solana/web3.js"; import { type Position } from "../target/types/position"; import { type Velocity } from "../target/types/velocity"; import { type BoltComponent } from "../target/types/bolt_component"; import { type SystemSimpleMovement } from "../target/types/system_simple_movement"; import { type SystemFly } from "../target/types/system_fly"; import { type SystemApplyVelocity } from "../target/types/system_apply_velocity"; import { expect } from "chai"; import BN from "bn.js"; import { DELEGATION_PROGRAM_ID, DelegateComponent, type Program, anchor, web3, FindRegistryPda, FindWorldPda, FindEntityPda, FindComponentPda, SerializeArgs, WORLD_PROGRAM_IDL as World, } from "../clients/bolt-sdk"; enum Direction { Left = "Left", Right = "Right", Up = "Up", Down = "Down", } function padCenter(value: string, width: number) { const length = value.length; if (width <= length) { return value; } const padding = (width - length) / 2; const align = width - padding; return value.padStart(align, " ").padEnd(width, " "); } function logPosition(title: string, { x, y, z }: { x: BN; y: BN; z: BN }) { console.log(" +----------------------------------+"); console.log(` | ${padCenter(title, 32)} |`); console.log(" +-----------------+----------------+"); console.log(` | X Position | ${String(x).padEnd(14, " ")} |`); console.log(` | Y Position | ${String(y).padEnd(14, " ")} |`); console.log(` | Z Position | ${String(z).padEnd(14, " ")} |`); console.log(" +-----------------+----------------+"); } function logVelocity( title: string, { x, y, z, lastApplied }: { x: BN; y: BN; z: BN; lastApplied: BN }, ) { console.log(" +----------------------------------+"); console.log(` | ${padCenter(title, 32)} |`); console.log(" +-----------------+----------------+"); console.log(` | X Velocity | ${String(x).padEnd(14, " ")} |`); console.log(` | Y Velocity | ${String(y).padEnd(14, " ")} |`); console.log(` | Z Velocity | ${String(z).padEnd(14, " ")} |`); console.log(` | Last Applied | ${String(lastApplied).padEnd(14, " ")} |`); console.log(" +-----------------+----------------+"); } describe("bolt", () => { const provider = anchor.AnchorProvider.env(); anchor.setProvider(provider); const worldProgram = anchor.workspace.World as Program; const boltComponentProgram = anchor.workspace .BoltComponent as Program; const exampleComponentPosition = anchor.workspace .Position as Program; const exampleComponentVelocity = anchor.workspace .Velocity as Program; const exampleSystemSimpleMovement = ( anchor.workspace.SystemSimpleMovement as Program ).programId; const exampleSystemFly = (anchor.workspace.SystemFly as Program) .programId; const exampleSystemApplyVelocity = ( anchor.workspace.SystemApplyVelocity as Program ).programId; let worldPda: PublicKey; let worldId: BN; let entity1Pda: PublicKey; let entity2Pda: PublicKey; let entity4Pda: PublicKey; let entity5Pda: PublicKey; let componentPositionEntity1Pda: PublicKey; let componentVelocityEntity1Pda: PublicKey; let componentPositionEntity4Pda: PublicKey; let componentPositionEntity5Pda: PublicKey; const secondAuthority = Keypair.generate().publicKey; it("InitializeRegistry", async () => { const registryPda = FindRegistryPda({}); const instruction = await worldProgram.methods .initializeRegistry() .accounts({ registry: registryPda, payer: provider.wallet.publicKey, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); await provider.sendAndConfirm(transaction); }); it("InitializeNewWorld", async () => { const registryPda = FindRegistryPda({}); const registry = await worldProgram.account.registry.fetch(registryPda); worldId = new BN(registry.worlds); worldPda = FindWorldPda({ worldId }); const instruction = await worldProgram.methods .initializeNewWorld() .accounts({ payer: provider.wallet.publicKey, world: worldPda, registry: registryPda, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log("InitializeNewWorld signature: ", signature); }); it("Add authority", async () => { const instruction = await worldProgram.methods .addAuthority(worldId) .accounts({ authority: provider.wallet.publicKey, newAuthority: provider.wallet.publicKey, world: worldPda, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); await provider.sendAndConfirm(transaction, [], { skipPreflight: true }); const worldAccount = await worldProgram.account.world.fetch(worldPda); expect( worldAccount.authorities.some((auth) => auth.equals(provider.wallet.publicKey), ), ); }); it("Add a second authority", async () => { const instruction = await worldProgram.methods .addAuthority(worldId) .accounts({ authority: provider.wallet.publicKey, newAuthority: secondAuthority, world: worldPda, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log(`Add Authority signature: ${signature}`); const worldAccount = await worldProgram.account.world.fetch(worldPda); expect( worldAccount.authorities.some((auth) => auth.equals(secondAuthority)), ); }); it("Remove an authority", async () => { const instruction = await worldProgram.methods .removeAuthority(worldId) .accounts({ authority: provider.wallet.publicKey, authorityToDelete: secondAuthority, world: worldPda, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log(`Remove Authority signature: ${signature}`); const worldAccount = await worldProgram.account.world.fetch(worldPda); expect( !worldAccount.authorities.some((auth) => auth.equals(secondAuthority)), ); }); it("InitializeNewWorld 2", async () => { const registryPda = FindRegistryPda({}); const registry = await worldProgram.account.registry.fetch(registryPda); const worldId = new BN(registry.worlds); const worldPda = FindWorldPda({ worldId }); const instruction = await worldProgram.methods .initializeNewWorld() .accounts({ payer: provider.wallet.publicKey, world: worldPda, registry: registryPda, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log("InitializeNewWorld 2 signature: ", signature); }); it("Add entity 1", async () => { const world = await worldProgram.account.world.fetch(worldPda); entity1Pda = FindEntityPda({ worldId: world.id, entityId: world.entities }); const instruction = await worldProgram.methods .addEntity(null) .accounts({ payer: provider.wallet.publicKey, world: worldPda, entity: entity1Pda, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log("Add Entity 1 signature: ", signature); }); it("Add entity 2", async () => { const world = await worldProgram.account.world.fetch(worldPda); entity2Pda = FindEntityPda({ worldId: world.id, entityId: world.entities }); const instruction = await worldProgram.methods .addEntity(null) .accounts({ payer: provider.wallet.publicKey, world: worldPda, entity: entity2Pda, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log("Add Entity 2 signature: ", signature); }); it("Add entity 3", async () => { const world = await worldProgram.account.world.fetch(worldPda); const entity3Pda = FindEntityPda({ worldId: world.id, entityId: world.entities, }); const instruction = await worldProgram.methods .addEntity(null) .accounts({ payer: provider.wallet.publicKey, world: worldPda, entity: entity3Pda, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log("Add Entity 3 signature: ", signature); }); it("Add entity 4 (with seed)", async () => { const world = await worldProgram.account.world.fetch(worldPda); const seed = Buffer.from("custom-seed"); entity4Pda = FindEntityPda({ worldId: world.id, seed }); const instruction = await worldProgram.methods .addEntity(seed) .accounts({ payer: provider.wallet.publicKey, world: worldPda, entity: entity4Pda, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log("Add Entity 4 signature: ", signature); }); it("Add entity 5", async () => { const world = await worldProgram.account.world.fetch(worldPda); entity5Pda = FindEntityPda({ worldId: world.id, entityId: world.entities }); const instruction = await worldProgram.methods .addEntity(null) .accounts({ payer: provider.wallet.publicKey, world: worldPda, entity: entity5Pda, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log("Add Entity 5 signature: ", signature); }); it("Initialize Original Component on Entity 1, through the world instance", async () => { const componentId = boltComponentProgram.programId; const componentPda = FindComponentPda({ componentId, entity: entity1Pda, seed: "origin-component", }); const instruction = await worldProgram.methods .initializeComponent() .accounts({ payer: provider.wallet.publicKey, entity: entity1Pda, data: componentPda, componentProgram: componentId, authority: provider.wallet.publicKey, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log( "Initialize Original Component on Entity 1 signature: ", signature, ); }); it("Initialize Original Component on Entity 2, trough the world instance", async () => { const componentId = boltComponentProgram.programId; const componentPda = FindComponentPda({ componentId, entity: entity2Pda, seed: "origin-component", }); const instruction = await worldProgram.methods .initializeComponent() .accounts({ payer: provider.wallet.publicKey, entity: entity2Pda, data: componentPda, componentProgram: componentId, authority: provider.wallet.publicKey, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log( "Initialize Original Component on Entity 2 signature: ", signature, ); }); it("Initialize Position Component on Entity 1", async () => { const componentId = exampleComponentPosition.programId; componentPositionEntity1Pda = FindComponentPda({ componentId, entity: entity1Pda, }); const instruction = await worldProgram.methods .initializeComponent() .accounts({ payer: provider.wallet.publicKey, entity: entity1Pda, data: componentPositionEntity1Pda, componentProgram: componentId, authority: worldProgram.programId, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log( "Initialize Position Component on Entity 1 signature: ", signature, ); }); it("Initialize Velocity Component on Entity 1 (with seed)", async () => { const componentId = exampleComponentVelocity.programId; componentVelocityEntity1Pda = FindComponentPda({ componentId, entity: entity1Pda, seed: "component-velocity", }); const instruction = await worldProgram.methods .initializeComponent() .accounts({ payer: provider.wallet.publicKey, entity: entity1Pda, data: componentVelocityEntity1Pda, componentProgram: componentId, authority: worldProgram.programId, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log( "Initialize Velocity Component on Entity 1 signature: ", signature, ); }); it("Initialize Position Component on Entity 2", async () => { const componentId = exampleComponentPosition.programId; const componentPositionEntity2Pda = FindComponentPda({ componentId, entity: entity2Pda, }); const instruction = await worldProgram.methods .initializeComponent() .accounts({ payer: provider.wallet.publicKey, entity: entity2Pda, data: componentPositionEntity2Pda, componentProgram: componentId, authority: worldProgram.programId, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log( "Initialize Position Component on Entity 2 signature: ", signature, ); }); it("Initialize Position Component on Entity 4", async () => { const componentId = exampleComponentPosition.programId; componentPositionEntity4Pda = FindComponentPda({ componentId, entity: entity4Pda, }); const instruction = await worldProgram.methods .initializeComponent() .accounts({ payer: provider.wallet.publicKey, entity: entity4Pda, data: componentPositionEntity4Pda, componentProgram: componentId, authority: worldProgram.programId, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log( "Initialize Position Component on Entity 4 signature: ", signature, ); }); it("Initialize Position Component on Entity 5 (with authority)", async () => { const componentId = exampleComponentPosition.programId; componentPositionEntity5Pda = FindComponentPda({ componentId, entity: entity5Pda, }); const instruction = await worldProgram.methods .initializeComponent() .accounts({ payer: provider.wallet.publicKey, entity: entity5Pda, data: componentPositionEntity5Pda, componentProgram: componentId, authority: provider.wallet.publicKey, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log( "Initialize Position Component on Entity 5 signature: ", signature, ); }); it("Check Position on Entity 1 is default", async () => { const position = await exampleComponentPosition.account.position.fetch( componentPositionEntity1Pda, ); logPosition("Default State: Entity 1", position); expect(position.x.toNumber()).to.equal(0); expect(position.y.toNumber()).to.equal(0); expect(position.z.toNumber()).to.equal(0); }); it("Apply Simple Movement System (Up) on Entity 1 using Apply", async () => { const instruction = await worldProgram.methods .apply(SerializeArgs({ direction: Direction.Up })) .accounts({ authority: provider.wallet.publicKey, boltSystem: exampleSystemSimpleMovement, world: worldPda, }) .remainingAccounts([ { pubkey: exampleComponentPosition.programId, isSigner: false, isWritable: false, }, { pubkey: componentPositionEntity1Pda, isSigner: false, isWritable: true, }, ]) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log( "Apply Simple Movement System (Up) on Entity 1 signature: ", signature, ); const position = await exampleComponentPosition.account.position.fetch( componentPositionEntity1Pda, ); logPosition("Movement System: Entity 1", position); expect(position.x.toNumber()).to.equal(0); expect(position.y.toNumber()).to.equal(1); expect(position.z.toNumber()).to.equal(0); }); it("Apply Simple Movement System (Up) on Entity 1", async () => { const instruction = await worldProgram.methods .apply(SerializeArgs({ direction: Direction.Up })) .accounts({ authority: provider.wallet.publicKey, boltSystem: exampleSystemSimpleMovement, world: worldPda, }) .remainingAccounts([ { pubkey: exampleComponentPosition.programId, isSigner: false, isWritable: false, }, { pubkey: componentPositionEntity1Pda, isSigner: false, isWritable: true, }, ]) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log( "Apply Simple Movement System (Up) on Entity 1 signature: ", signature, ); const position = await exampleComponentPosition.account.position.fetch( componentPositionEntity1Pda, ); logPosition("Movement System: Entity 1", position); expect(position.x.toNumber()).to.equal(0); expect(position.y.toNumber()).to.equal(2); expect(position.z.toNumber()).to.equal(0); }); it("Apply Simple Movement System (Right) on Entity 1", async () => { const instruction = await worldProgram.methods .apply(SerializeArgs({ direction: Direction.Right })) .accounts({ authority: provider.wallet.publicKey, boltSystem: exampleSystemSimpleMovement, world: worldPda, }) .remainingAccounts([ { pubkey: exampleComponentPosition.programId, isSigner: false, isWritable: false, }, { pubkey: componentPositionEntity1Pda, isSigner: false, isWritable: true, }, ]) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log( "Apply Simple Movement System (Right) on Entity 1 signature: ", signature, ); const position = await exampleComponentPosition.account.position.fetch( componentPositionEntity1Pda, ); logPosition("Movement System: Entity 1", position); expect(position.x.toNumber()).to.equal(1); expect(position.y.toNumber()).to.equal(2); expect(position.z.toNumber()).to.equal(0); }); it("Apply Fly System on Entity 1", async () => { const instruction = await worldProgram.methods .apply(SerializeArgs()) .accounts({ authority: provider.wallet.publicKey, boltSystem: exampleSystemFly, world: worldPda, }) .remainingAccounts([ { pubkey: exampleComponentPosition.programId, isSigner: false, isWritable: false, }, { pubkey: componentPositionEntity1Pda, isSigner: false, isWritable: true, }, ]) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log("Apply Fly System on Entity 1 signature: ", signature); const position = await exampleComponentPosition.account.position.fetch( componentPositionEntity1Pda, ); logPosition("Fly System: Entity 1", position); expect(position.x.toNumber()).to.equal(1); expect(position.y.toNumber()).to.equal(2); expect(position.z.toNumber()).to.equal(1); }); it("Apply System Velocity on Entity 1", async () => { const instruction = await worldProgram.methods .apply(SerializeArgs()) .accounts({ authority: provider.wallet.publicKey, boltSystem: exampleSystemApplyVelocity, world: worldPda, }) .remainingAccounts([ { pubkey: exampleComponentVelocity.programId, isSigner: false, isWritable: false, }, { pubkey: componentVelocityEntity1Pda, isSigner: false, isWritable: true, }, { pubkey: exampleComponentPosition.programId, isSigner: false, isWritable: false, }, { pubkey: componentPositionEntity1Pda, isSigner: false, isWritable: true, }, ]) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction); console.log("Apply System Velocity on Entity 1 signature: ", signature); const velocity = await exampleComponentVelocity.account.velocity.fetch( componentVelocityEntity1Pda, ); logVelocity("Apply System Velocity: Entity 1", velocity); expect(velocity.x.toNumber()).to.equal(10); expect(velocity.y.toNumber()).to.equal(0); expect(velocity.z.toNumber()).to.equal(0); expect(velocity.lastApplied.toNumber()).to.not.equal(0); const position = await exampleComponentPosition.account.position.fetch( componentPositionEntity1Pda, ); logPosition("Apply System Velocity: Entity 1", position); expect(position.x.toNumber()).to.greaterThan(1); expect(position.y.toNumber()).to.equal(2); expect(position.z.toNumber()).to.equal(1); }); it("Apply System Velocity on Entity 1, with Clock external account", async () => { const instruction = await worldProgram.methods .apply(SerializeArgs()) .accounts({ authority: provider.wallet.publicKey, boltSystem: exampleSystemApplyVelocity, world: worldPda, }) .remainingAccounts([ { pubkey: exampleComponentVelocity.programId, isSigner: false, isWritable: false, }, { pubkey: componentVelocityEntity1Pda, isSigner: false, isWritable: true, }, { pubkey: exampleComponentPosition.programId, isSigner: false, isWritable: false, }, { pubkey: componentPositionEntity1Pda, isSigner: false, isWritable: true, }, { pubkey: worldProgram.programId, // world program ID is the end of components delimiter isSigner: false, isWritable: false, }, { pubkey: new web3.PublicKey( "SysvarC1ock11111111111111111111111111111111", ), isWritable: false, isSigner: false, }, ]) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); await provider.sendAndConfirm(transaction); const position = await exampleComponentPosition.account.position.fetch( componentPositionEntity1Pda, ); logPosition("Apply System Velocity: Entity 1", position); expect(position.x.toNumber()).to.greaterThan(1); expect(position.y.toNumber()).to.equal(2); expect(position.z.toNumber()).to.equal(300); }); it("Apply Fly System on Entity 4", async () => { const instruction = await worldProgram.methods .apply(SerializeArgs()) .accounts({ authority: provider.wallet.publicKey, boltSystem: exampleSystemFly, world: worldPda, }) .remainingAccounts([ { pubkey: exampleComponentPosition.programId, isSigner: false, isWritable: false, }, { pubkey: componentPositionEntity4Pda, isSigner: false, isWritable: true, }, ]) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); await provider.sendAndConfirm(transaction); const position = await exampleComponentPosition.account.position.fetch( componentPositionEntity4Pda, ); logPosition("Fly System: Entity 4", position); expect(position.x.toNumber()).to.equal(0); expect(position.y.toNumber()).to.equal(0); expect(position.z.toNumber()).to.equal(1); }); it("Apply Fly System on Entity 5 (should fail with wrong authority)", async () => { const positionBefore = await exampleComponentPosition.account.position.fetch( componentPositionEntity5Pda, ); const instruction = await worldProgram.methods .apply(SerializeArgs()) .accounts({ authority: provider.wallet.publicKey, boltSystem: exampleSystemFly, world: worldPda, }) .remainingAccounts([ { pubkey: exampleComponentPosition.programId, isSigner: false, isWritable: false, }, { pubkey: componentPositionEntity5Pda, isSigner: false, isWritable: true, }, ]) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); let failed = false; try { await provider.sendAndConfirm(transaction); } catch (error) { failed = true; // console.log("error", error); expect(error.logs.join("\n")).to.contain("Error Code: InvalidAuthority"); } expect(failed).to.equal(true); const positionAfter = await exampleComponentPosition.account.position.fetch( componentPositionEntity5Pda, ); expect(positionBefore.x.toNumber()).to.equal(positionAfter.x.toNumber()); expect(positionBefore.y.toNumber()).to.equal(positionAfter.y.toNumber()); expect(positionBefore.z.toNumber()).to.equal(positionAfter.z.toNumber()); }); it("Whitelist System", async () => { const instruction = await worldProgram.methods .approveSystem() .accounts({ authority: provider.wallet.publicKey, system: exampleSystemFly, world: worldPda, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction, [], { skipPreflight: true, }); console.log(`Whitelist 2 system approval signature: ${signature}`); // Get World and check permissionless and systems const worldAccount = await worldProgram.account.world.fetch(worldPda); expect(worldAccount.permissionless).to.equal(false); expect(worldAccount.systems.length).to.be.greaterThan(0); }); it("Whitelist System 2", async () => { const instruction = await worldProgram.methods .approveSystem() .accounts({ authority: provider.wallet.publicKey, system: exampleSystemApplyVelocity, world: worldPda, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction, [], { skipPreflight: true, }); console.log(`Whitelist 2 system approval signature: ${signature}`); // Get World and check permissionless and systems const worldAccount = await worldProgram.account.world.fetch(worldPda); expect(worldAccount.permissionless).to.equal(false); expect(worldAccount.systems.length).to.be.greaterThan(0); }); it("Apply Fly System on Entity 1", async () => { const instruction = await worldProgram.methods .apply(SerializeArgs()) .accounts({ authority: provider.wallet.publicKey, boltSystem: exampleSystemFly, world: worldPda, }) .remainingAccounts([ { pubkey: exampleComponentPosition.programId, isSigner: false, isWritable: false, }, { pubkey: componentPositionEntity1Pda, isSigner: false, isWritable: true, }, ]) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); await provider.sendAndConfirm(transaction); }); it("Remove System 1", async () => { const instruction = await worldProgram.methods .removeSystem() .accounts({ authority: provider.wallet.publicKey, system: exampleSystemFly, world: worldPda, }) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); const signature = await provider.sendAndConfirm(transaction, [], { skipPreflight: true, }); console.log(`Remove System 1 signature: ${signature}`); // Get World and check permissionless and systems const worldAccount = await worldProgram.account.world.fetch(worldPda); expect(worldAccount.permissionless).to.equal(false); expect(worldAccount.systems.length).to.be.greaterThan(0); }); it("Apply Invalid Fly System on Entity 1", async () => { const instruction = await worldProgram.methods .apply(SerializeArgs()) .accounts({ authority: provider.wallet.publicKey, boltSystem: exampleSystemFly, world: worldPda, }) .remainingAccounts([ { pubkey: exampleComponentPosition.programId, isSigner: false, isWritable: false, }, { pubkey: componentPositionEntity1Pda, isSigner: false, isWritable: true, }, ]) .instruction(); const transaction = new anchor.web3.Transaction().add(instruction); let invalid = false; try { await provider.sendAndConfirm(transaction); } catch (error) { expect(error.logs.join(" ")).to.contain("Error Code: SystemNotApproved"); invalid = true; } expect(invalid).to.equal(true); }); it("Check invalid component init without CPI", async () => { let invalid = false; try { await exampleComponentPosition.methods .initialize() .accounts({ payer: provider.wallet.publicKey, data: componentPositionEntity5Pda, entity: entity5Pda, authority: provider.wallet.publicKey, }) .rpc(); } catch (error) { // console.log("error", error); expect(error.message).to.contain("Error Code: InvalidCaller"); invalid = true; } expect(invalid).to.equal(true); }); it("Check invalid component update without CPI", async () => { let invalid = false; try { await boltComponentProgram.methods .update(Buffer.from("")) .accounts({ boltComponent: componentPositionEntity4Pda, authority: provider.wallet.publicKey, }) .rpc(); } catch (error) { // console.log("error", error); expect(error.message).to.contain( "bolt_component. Error Code: AccountOwnedByWrongProgram", ); invalid = true; } expect(invalid).to.equal(true); }); it("Check component delegation", async () => { const delegateComponent = await DelegateComponent({ payer: provider.wallet.publicKey, entity: entity1Pda, componentId: exampleComponentPosition.programId, }); const instruction = delegateComponent.transaction; const transaction = new anchor.web3.Transaction().add(instruction); const txSign = await provider.sendAndConfirm(transaction, [], { skipPreflight: true, commitment: "confirmed", }); console.log(`Delegation signature: ${txSign}`); const acc = await provider.connection.getAccountInfo( delegateComponent.componentPda, ); expect(acc?.owner.toBase58()).to.equal(DELEGATION_PROGRAM_ID.toBase58()); }); });