123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675 |
- import * as anchor from "@coral-xyz/anchor";
- import { type Program, web3 } from "@coral-xyz/anchor";
- import { 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 { type World } from "../target/types/world";
- import { expect } from "chai";
- import BN from "bn.js";
- import {
- createDelegateInstruction,
- createInitializeRegistryInstruction,
- DELEGATION_PROGRAM_ID,
- FindComponentPda,
- FindEntityPda,
- FindWorldPda,
- FindWorldRegistryPda,
- SYSVAR_INSTRUCTIONS_PUBKEY,
- } from "../clients/bolt-sdk";
- import { createUndelegateInstruction } from "../clients/bolt-sdk/lib/delegation/undelegate";
- enum Direction {
- Left = "Left",
- Right = "Right",
- Up = "Up",
- Down = "Down",
- }
- function serializeArgs(args: any = {}) {
- const jsonString = JSON.stringify(args);
- const encoder = new TextEncoder();
- const binaryData = encoder.encode(jsonString);
- return Buffer.from(
- binaryData.buffer,
- binaryData.byteOffset,
- binaryData.byteLength
- );
- }
- describe("bolt", () => {
- const provider = anchor.AnchorProvider.env();
- anchor.setProvider(provider);
- const worldProgram = anchor.workspace.World as Program<World>;
- const boltComponentPositionProgram = anchor.workspace
- .Position as Program<Position>;
- const boltComponentVelocityProgram = anchor.workspace
- .Velocity as Program<Velocity>;
- const boltComponentProgramOrigin = anchor.workspace
- .BoltComponent as Program<BoltComponent>;
- const systemSimpleMovement = (
- anchor.workspace.SystemSimpleMovement as Program<SystemSimpleMovement>
- ).programId;
- const systemFly = (anchor.workspace.SystemFly as Program<SystemFly>)
- .programId;
- const applyVelocity = (
- anchor.workspace.SystemApplyVelocity as Program<SystemApplyVelocity>
- ).programId;
- let entity1: PublicKey;
- let entity2: PublicKey;
- let entity5: PublicKey;
- let componentPositionEntity1: PublicKey;
- let componentPositionEntity2: PublicKey;
- let componentPositionEntity5: PublicKey;
- let componentVelocityEntity1: PublicKey;
- it("InitializeWorldsRegistry", async () => {
- const registryPda = FindWorldRegistryPda(worldProgram.programId);
- const initializeRegistryIx = createInitializeRegistryInstruction({
- registry: registryPda,
- payer: provider.wallet.publicKey,
- });
- const tx = new anchor.web3.Transaction().add(initializeRegistryIx);
- await provider.sendAndConfirm(tx);
- });
- it("InitializeNewWorld", async () => {
- const registryPda = FindWorldRegistryPda(worldProgram.programId);
- const worldPda = FindWorldPda(new BN(0), worldProgram.programId);
- const res = await worldProgram.methods
- .initializeNewWorld()
- .accounts({
- world: worldPda,
- registry: registryPda,
- payer: provider.wallet.publicKey,
- })
- .rpc();
- console.log(res);
- });
- it("InitializeNewWorld 2", async () => {
- const registryPda = FindWorldRegistryPda(worldProgram.programId);
- const worldPda = FindWorldPda(new BN(1), worldProgram.programId);
- await worldProgram.methods
- .initializeNewWorld()
- .accounts({
- world: worldPda,
- registry: registryPda,
- payer: provider.wallet.publicKey,
- })
- .rpc();
- });
- it("Add entity 1", async () => {
- const worldPda = FindWorldPda(new BN(0), worldProgram.programId);
- entity1 = FindEntityPda(new BN(0), new BN(0), null, worldProgram.programId);
- await worldProgram.methods
- .addEntity(null)
- .accounts({
- world: worldPda,
- entity: entity1,
- payer: provider.wallet.publicKey,
- })
- .rpc();
- });
- it("Add entity 2", async () => {
- const worldPda = FindWorldPda(new BN(0), worldProgram.programId);
- entity2 = FindEntityPda(new BN(0), new BN(1), null, worldProgram.programId);
- await worldProgram.methods
- .addEntity(null)
- .accounts({
- world: worldPda,
- entity: entity2,
- payer: provider.wallet.publicKey,
- })
- .rpc();
- });
- it("Add entity 3", async () => {
- const worldPda = FindWorldPda(new BN(0), worldProgram.programId);
- const entityPda = FindEntityPda(
- new BN(0),
- new BN(2),
- null,
- worldProgram.programId
- );
- await worldProgram.methods
- .addEntity(null)
- .accounts({
- world: worldPda,
- entity: entityPda,
- payer: provider.wallet.publicKey,
- })
- .rpc();
- });
- it("Add entity 4 with extra seeds", async () => {
- const worldPda = FindWorldPda(new BN(0), worldProgram.programId);
- const seed = "extra-seed";
- const entity4 = FindEntityPda(
- new BN(0),
- new BN(3),
- seed,
- worldProgram.programId
- );
- await worldProgram.methods
- .addEntity(seed)
- .accounts({
- world: worldPda,
- entity: entity4,
- payer: provider.wallet.publicKey,
- })
- .rpc();
- });
- it("Add entity 5", async () => {
- const worldPda = FindWorldPda(new BN(0), worldProgram.programId);
- entity5 = FindEntityPda(new BN(0), new BN(4), null, worldProgram.programId);
- await worldProgram.methods
- .addEntity(null)
- .accounts({
- world: worldPda,
- entity: entity5,
- payer: provider.wallet.publicKey,
- })
- .rpc();
- });
- it("Initialize Original Component on Entity 1, trough the world instance", async () => {
- const componentEntity1 = FindComponentPda(
- boltComponentProgramOrigin.programId,
- entity1,
- "origin-component"
- );
- await worldProgram.methods
- .initializeComponent()
- .accounts({
- payer: provider.wallet.publicKey,
- data: componentEntity1,
- componentProgram: boltComponentProgramOrigin.programId,
- entity: entity1,
- instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
- authority: provider.wallet.publicKey,
- })
- .rpc();
- });
- it("Initialize Original Component on Entity 2, trough the world instance", async () => {
- const componentEntity2 = FindComponentPda(
- boltComponentProgramOrigin.programId,
- entity2,
- "origin-component"
- );
- await worldProgram.methods
- .initializeComponent()
- .accounts({
- payer: provider.wallet.publicKey,
- data: componentEntity2,
- componentProgram: boltComponentProgramOrigin.programId,
- entity: entity2,
- instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
- authority: provider.wallet.publicKey,
- })
- .rpc();
- });
- it("Initialize Position Component on Entity 1", async () => {
- componentPositionEntity1 = FindComponentPda(
- boltComponentPositionProgram.programId,
- entity1
- );
- await worldProgram.methods
- .initializeComponent()
- .accounts({
- payer: provider.wallet.publicKey,
- data: componentPositionEntity1,
- componentProgram: boltComponentPositionProgram.programId,
- entity: entity1,
- instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
- authority: worldProgram.programId,
- })
- .rpc();
- });
- it("Initialize Velocity Component on Entity 1", async () => {
- componentVelocityEntity1 = FindComponentPda(
- boltComponentVelocityProgram.programId,
- entity1,
- "component-velocity"
- );
- await worldProgram.methods
- .initializeComponent()
- .accounts({
- payer: provider.wallet.publicKey,
- data: componentVelocityEntity1,
- componentProgram: boltComponentVelocityProgram.programId,
- entity: entity1,
- instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
- authority: worldProgram.programId,
- })
- .rpc();
- });
- it("Initialize Position Component on Entity 2", async () => {
- componentPositionEntity2 = FindComponentPda(
- boltComponentPositionProgram.programId,
- entity2
- );
- await worldProgram.methods
- .initializeComponent()
- .accounts({
- payer: provider.wallet.publicKey,
- data: componentPositionEntity2,
- componentProgram: boltComponentPositionProgram.programId,
- entity: entity2,
- instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
- authority: worldProgram.programId,
- })
- .rpc();
- });
- it("Initialize Position Component on Entity 5", async () => {
- componentPositionEntity5 = FindComponentPda(
- boltComponentPositionProgram.programId,
- entity5
- );
- await worldProgram.methods
- .initializeComponent()
- .accounts({
- payer: provider.wallet.publicKey,
- data: componentPositionEntity5,
- componentProgram: boltComponentPositionProgram.programId,
- entity: entity5,
- instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
- authority: provider.wallet.publicKey,
- })
- .rpc();
- });
- it("Check Position on Entity 1 is default", async () => {
- expect(
- (
- await boltComponentPositionProgram.account.position.fetch(
- componentPositionEntity1
- )
- ).x.toNumber()
- ).to.equal(0);
- expect(
- (
- await boltComponentPositionProgram.account.position.fetch(
- componentPositionEntity1
- )
- ).y.toNumber()
- ).to.equal(0);
- expect(
- (
- await boltComponentPositionProgram.account.position.fetch(
- componentPositionEntity1
- )
- ).z.toNumber()
- ).to.equal(0);
- });
- it("Simple Movement System and Up direction on Entity 1", async () => {
- const args = {
- direction: Direction.Up,
- };
- await worldProgram.methods
- .apply(serializeArgs(args)) // Move Up
- .accounts({
- componentProgram: boltComponentPositionProgram.programId,
- boltSystem: systemSimpleMovement,
- boltComponent: componentPositionEntity1,
- instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
- authority: provider.wallet.publicKey,
- })
- .rpc();
- expect(
- (
- await boltComponentPositionProgram.account.position.fetch(
- componentPositionEntity1
- )
- ).y.toNumber()
- ).to.equal(1);
- const componentData =
- await boltComponentPositionProgram.account.position.fetch(
- componentPositionEntity1
- );
- const x = componentData.x.toNumber();
- const y = componentData.y.toNumber();
- const z = componentData.z.toNumber();
- console.log("+-----------------------------+");
- console.log("| Movement System: Entity 1 |");
- console.log("+----------------+------------+");
- console.log("| Coordinate | Value |");
- console.log("+----------------+------------+");
- console.log(`| X Position | ${String(x).padEnd(10, " ")} |`);
- console.log("| | |");
- console.log(`| Y Position | ${String(y).padEnd(10, " ")} |`);
- console.log("| | |");
- console.log(`| Z Position | ${String(z).padEnd(10, " ")} |`);
- console.log("+----------------+------------+");
- console.log("| |");
- console.log("+-----------------------------+");
- console.log("Component Position: ", componentPositionEntity1.toString());
- });
- it("Simple Movement System and Right direction on Entity 1", async () => {
- const args = {
- direction: Direction.Right,
- };
- await worldProgram.methods
- .apply(serializeArgs(args)) // Move Right
- .accounts({
- componentProgram: boltComponentPositionProgram.programId,
- boltSystem: systemSimpleMovement,
- boltComponent: componentPositionEntity1,
- instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
- authority: provider.wallet.publicKey,
- })
- .rpc();
- expect(
- (
- await boltComponentPositionProgram.account.position.fetch(
- componentPositionEntity1
- )
- ).y.toNumber()
- ).to.equal(1);
- expect(
- (
- await boltComponentPositionProgram.account.position.fetch(
- componentPositionEntity1
- )
- ).y.toNumber()
- ).to.equal(1);
- const componentData =
- await boltComponentPositionProgram.account.position.fetch(
- componentPositionEntity1
- );
- const x = componentData.x.toNumber();
- const y = componentData.y.toNumber();
- const z = componentData.z.toNumber();
- console.log("+-----------------------------+");
- console.log("| Movement System: Entity 1 |");
- console.log("+----------------+------------+");
- console.log("| Coordinate | Value |");
- console.log("+----------------+------------+");
- console.log(`| X Position | ${String(x).padEnd(10, " ")} |`);
- console.log("| | |");
- console.log(`| Y Position | ${String(y).padEnd(10, " ")} |`);
- console.log("| | |");
- console.log(`| Z Position | ${String(z).padEnd(10, " ")} |`);
- console.log("+----------------+------------+");
- console.log("| |");
- console.log("+-----------------------------+");
- });
- it("Fly System on Entity 1", async () => {
- await worldProgram.methods
- .apply(Buffer.alloc(0)) // Move Up
- .accounts({
- componentProgram: boltComponentPositionProgram.programId,
- boltSystem: systemFly,
- boltComponent: componentPositionEntity1,
- instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
- authority: provider.wallet.publicKey,
- })
- .rpc();
- expect(
- (
- await boltComponentPositionProgram.account.position.fetch(
- componentPositionEntity1
- )
- ).z.toNumber()
- ).to.equal(1);
- const componentData =
- await boltComponentPositionProgram.account.position.fetch(
- componentPositionEntity1
- );
- const x = componentData.x.toNumber();
- const y = componentData.y.toNumber();
- const z = componentData.z.toNumber();
- console.log("+-----------------------------+");
- console.log("| Fly: Position Entity 1 |");
- console.log("+----------------+------------+");
- console.log("| Coordinate | Value |");
- console.log("+----------------+------------+");
- console.log(`| X Position | ${String(x).padEnd(10, " ")} |`);
- console.log("| | |");
- console.log(`| Y Position | ${String(y).padEnd(10, " ")} |`);
- console.log("| | |");
- console.log(`| Z Position | ${String(z).padEnd(10, " ")} |`);
- console.log("+----------------+------------+");
- console.log("| |");
- console.log("+-----------------------------+");
- });
- it("Apply Velocity on Entity 1", async () => {
- await worldProgram.methods
- .apply2(Buffer.alloc(0))
- .accounts({
- componentProgram1: boltComponentVelocityProgram.programId,
- componentProgram2: boltComponentPositionProgram.programId,
- boltSystem: applyVelocity,
- boltComponent1: componentVelocityEntity1,
- boltComponent2: componentPositionEntity1,
- instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
- authority: provider.wallet.publicKey,
- })
- .rpc();
- const componentData =
- await boltComponentVelocityProgram.account.velocity.fetch(
- componentVelocityEntity1
- );
- let x = componentData.x.toNumber();
- let y = componentData.y.toNumber();
- let z = componentData.z.toNumber();
- const tmp = componentData.lastApplied.toNumber();
- console.log("+-----------------------------+");
- console.log("| Apply Velocity: Velocity Entity 1 |");
- console.log("+----------------+------------+");
- console.log("| Coordinate | Value |");
- console.log("+----------------+------------+");
- console.log(`| X Position | ${String(x).padEnd(10, " ")} |`);
- console.log("| | |");
- console.log(`| Y Position | ${String(y).padEnd(10, " ")} |`);
- console.log("| | |");
- console.log(`| Z Position | ${String(z).padEnd(10, " ")} |`);
- console.log("| | |");
- console.log(`| Timestamp | ${String(tmp).padEnd(10, " ")} |`);
- console.log("+----------------+------------+");
- console.log("| |");
- console.log("+-----------------------------+");
- const positionData =
- await boltComponentPositionProgram.account.position.fetch(
- componentPositionEntity1
- );
- x = positionData.x.toNumber();
- y = positionData.y.toNumber();
- z = positionData.z.toNumber();
- console.log("+-----------------------------+");
- console.log("| Apply Velocity: Position Entity 1 |");
- console.log("+----------------+------------+");
- console.log("| Coordinate | Value |");
- console.log("+----------------+------------+");
- console.log(`| X Position | ${String(x).padEnd(10, " ")} |`);
- console.log("| | |");
- console.log(`| Y Position | ${String(y).padEnd(10, " ")} |`);
- console.log("| | |");
- console.log(`| Z Position | ${String(z).padEnd(10, " ")} |`);
- console.log("+----------------+------------+");
- console.log("| |");
- console.log("+-----------------------------+");
- expect(positionData.z.toNumber()).to.not.equal(300);
- });
- it("Apply Velocity on Entity 1, with Clock external account", async () => {
- await worldProgram.methods
- .apply2(Buffer.alloc(0))
- .accounts({
- componentProgram1: boltComponentVelocityProgram.programId,
- componentProgram2: boltComponentPositionProgram.programId,
- boltSystem: applyVelocity,
- boltComponent1: componentVelocityEntity1,
- boltComponent2: componentPositionEntity1,
- instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
- authority: provider.wallet.publicKey,
- })
- .remainingAccounts([
- {
- pubkey: new web3.PublicKey(
- "SysvarC1ock11111111111111111111111111111111"
- ),
- isWritable: false,
- isSigner: false,
- },
- ])
- .rpc();
- const positionData =
- await boltComponentPositionProgram.account.position.fetch(
- componentPositionEntity1
- );
- // Check if the position has changed to 300 (which means the account clock was used)
- expect(positionData.z.toNumber()).to.equal(300);
- });
- // Check illegal authority usage
- it("Check invalid component update", async () => {
- const componentDataPrev =
- await boltComponentPositionProgram.account.position.fetch(
- componentPositionEntity5
- );
- try {
- await worldProgram.methods
- .apply(Buffer.alloc(0)) // Move Up
- .accounts({
- componentProgram: boltComponentPositionProgram.programId,
- boltSystem: systemFly,
- boltComponent: componentPositionEntity5,
- instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
- authority: provider.wallet.publicKey,
- })
- .rpc();
- } catch (e) {
- expect(e.message).to.contain("Invalid authority");
- }
- const componentData =
- await boltComponentPositionProgram.account.position.fetch(
- componentPositionEntity5
- );
- expect(
- componentDataPrev.x.toNumber() === componentData.x.toNumber() &&
- componentDataPrev.y.toNumber() === componentData.y.toNumber() &&
- componentDataPrev.z.toNumber() === componentData.z.toNumber()
- ).to.equal(true);
- });
- // Check illegal call, without CPI
- it("Check invalid init without CPI", async () => {
- let invalid = false;
- const componentVelocityEntity5 = FindComponentPda(
- boltComponentVelocityProgram.programId,
- entity5
- );
- try {
- await boltComponentProgramOrigin.methods
- .initialize()
- .accounts({
- payer: provider.wallet.publicKey,
- data: componentVelocityEntity5,
- entity: entity5,
- instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
- systemProgram: anchor.web3.SystemProgram.programId,
- authority: provider.wallet.publicKey,
- })
- .rpc();
- } catch (e) {
- invalid = true;
- }
- expect(invalid).to.equal(true);
- });
- // Check illegal call, without CPI
- it("Check invalid update without CPI", async () => {
- let invalid = false;
- const componentVelocityEntity5 = FindComponentPda(
- boltComponentVelocityProgram.programId,
- entity5
- );
- try {
- await boltComponentProgramOrigin.methods
- .update(null)
- .accounts({
- boltComponent: componentVelocityEntity5,
- instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
- authority: provider.wallet.publicKey,
- })
- .rpc();
- } catch (e) {
- invalid = true;
- }
- expect(invalid).to.equal(true);
- });
- // Check component delegation
- it("Check component delegation", async () => {
- const delegateIx = createDelegateInstruction({
- entity: entity1,
- account: componentPositionEntity1,
- ownerProgram: boltComponentPositionProgram.programId,
- payer: provider.wallet.publicKey,
- });
- const tx = new anchor.web3.Transaction().add(delegateIx);
- await provider.sendAndConfirm(tx, [], { skipPreflight: true });
- const acc = await provider.connection.getAccountInfo(
- componentPositionEntity1
- );
- expect(acc.owner.toString()).to.equal(DELEGATION_PROGRAM_ID);
- });
- // Check component undelegation
- it("Check component undelegation", async () => {
- const delegateIx = createUndelegateInstruction({
- payer: provider.wallet.publicKey,
- delegatedAccount: componentPositionEntity1,
- ownerProgram: boltComponentPositionProgram.programId,
- reimbursement: provider.wallet.publicKey,
- });
- const tx = new anchor.web3.Transaction().add(delegateIx);
- await provider.sendAndConfirm(tx, [], { skipPreflight: true });
- const acc = await provider.connection.getAccountInfo(
- componentPositionEntity1
- );
- expect(acc.owner).to.deep.equal(boltComponentPositionProgram.programId);
- });
- });
|