bolt.ts 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. import { Keypair, type PublicKey } from "@solana/web3.js";
  2. import { type Position } from "../target/types/position";
  3. import { type Velocity } from "../target/types/velocity";
  4. import { type BoltComponent } from "../target/types/bolt_component";
  5. import { type SystemSimpleMovement } from "../target/types/system_simple_movement";
  6. import { type World } from "../target/types/world";
  7. import { type SystemFly } from "../target/types/system_fly";
  8. import { type SystemApplyVelocity } from "../target/types/system_apply_velocity";
  9. import { expect } from "chai";
  10. import type BN from "bn.js";
  11. import {
  12. AddEntity,
  13. createInitializeRegistryInstruction,
  14. DELEGATION_PROGRAM_ID,
  15. FindRegistryPda,
  16. InitializeComponent,
  17. InitializeNewWorld,
  18. ApplySystem,
  19. Apply,
  20. DelegateComponent,
  21. AddAuthority,
  22. RemoveAuthority,
  23. ApproveSystem,
  24. RemoveSystem,
  25. type Program,
  26. anchor,
  27. web3,
  28. SerializeArgs,
  29. } from "../clients/bolt-sdk";
  30. enum Direction {
  31. Left = "Left",
  32. Right = "Right",
  33. Up = "Up",
  34. Down = "Down",
  35. }
  36. function padCenter(value: string, width: number) {
  37. const length = value.length;
  38. if (width <= length) {
  39. return value;
  40. }
  41. const padding = (width - length) / 2;
  42. const align = width - padding;
  43. return value.padStart(align, " ").padEnd(width, " ");
  44. }
  45. function logPosition(title: string, { x, y, z }: { x: BN; y: BN; z: BN }) {
  46. console.log(" +----------------------------------+");
  47. console.log(` | ${padCenter(title, 32)} |`);
  48. console.log(" +-----------------+----------------+");
  49. console.log(` | X Position | ${String(x).padEnd(14, " ")} |`);
  50. console.log(` | Y Position | ${String(y).padEnd(14, " ")} |`);
  51. console.log(` | Z Position | ${String(z).padEnd(14, " ")} |`);
  52. console.log(" +-----------------+----------------+");
  53. }
  54. function logVelocity(
  55. title: string,
  56. { x, y, z, lastApplied }: { x: BN; y: BN; z: BN; lastApplied: BN },
  57. ) {
  58. console.log(" +----------------------------------+");
  59. console.log(` | ${padCenter(title, 32)} |`);
  60. console.log(" +-----------------+----------------+");
  61. console.log(` | X Velocity | ${String(x).padEnd(14, " ")} |`);
  62. console.log(` | Y Velocity | ${String(y).padEnd(14, " ")} |`);
  63. console.log(` | Z Velocity | ${String(z).padEnd(14, " ")} |`);
  64. console.log(` | Last Applied | ${String(lastApplied).padEnd(14, " ")} |`);
  65. console.log(" +-----------------+----------------+");
  66. }
  67. describe("bolt", () => {
  68. const provider = anchor.AnchorProvider.env();
  69. anchor.setProvider(provider);
  70. const worldProgram = anchor.workspace.World as Program<World>;
  71. const boltComponentProgram = anchor.workspace
  72. .BoltComponent as Program<BoltComponent>;
  73. const exampleComponentPosition = anchor.workspace
  74. .Position as Program<Position>;
  75. const exampleComponentVelocity = anchor.workspace
  76. .Velocity as Program<Velocity>;
  77. const exampleSystemSimpleMovement = (
  78. anchor.workspace.SystemSimpleMovement as Program<SystemSimpleMovement>
  79. ).programId;
  80. const exampleSystemFly = (anchor.workspace.SystemFly as Program<SystemFly>)
  81. .programId;
  82. const exampleSystemApplyVelocity = (
  83. anchor.workspace.SystemApplyVelocity as Program<SystemApplyVelocity>
  84. ).programId;
  85. let worldPda: PublicKey;
  86. let entity1Pda: PublicKey;
  87. let entity2Pda: PublicKey;
  88. let entity4Pda: PublicKey;
  89. let entity5Pda: PublicKey;
  90. let componentPositionEntity1Pda: PublicKey;
  91. let componentVelocityEntity1Pda: PublicKey;
  92. let componentPositionEntity4Pda: PublicKey;
  93. let componentPositionEntity5Pda: PublicKey;
  94. const secondAuthority = Keypair.generate().publicKey;
  95. it("InitializeRegistry", async () => {
  96. const registryPda = FindRegistryPda({});
  97. const initializeRegistryIx = createInitializeRegistryInstruction({
  98. registry: registryPda,
  99. payer: provider.wallet.publicKey,
  100. });
  101. const tx = new anchor.web3.Transaction().add(initializeRegistryIx);
  102. await provider.sendAndConfirm(tx);
  103. });
  104. it("InitializeNewWorld", async () => {
  105. const initializeNewWorld = await InitializeNewWorld({
  106. payer: provider.wallet.publicKey,
  107. connection: provider.connection,
  108. });
  109. const signature = await provider.sendAndConfirm(
  110. initializeNewWorld.transaction,
  111. );
  112. console.log("InitializeNewWorld signature: ", signature);
  113. worldPda = initializeNewWorld.worldPda; // Saved for later
  114. });
  115. it("Add authority", async () => {
  116. const addAuthority = await AddAuthority({
  117. authority: provider.wallet.publicKey,
  118. newAuthority: provider.wallet.publicKey,
  119. world: worldPda,
  120. connection: provider.connection,
  121. });
  122. await provider.sendAndConfirm(addAuthority.transaction, [], {
  123. skipPreflight: true,
  124. });
  125. const worldAccount = await worldProgram.account.world.fetch(worldPda);
  126. expect(
  127. worldAccount.authorities.some((auth) =>
  128. auth.equals(provider.wallet.publicKey),
  129. ),
  130. );
  131. });
  132. it("Add a second authority", async () => {
  133. const addAuthority = await AddAuthority({
  134. authority: provider.wallet.publicKey,
  135. newAuthority: secondAuthority,
  136. world: worldPda,
  137. connection: provider.connection,
  138. });
  139. const signature = await provider.sendAndConfirm(addAuthority.transaction);
  140. console.log(`Add Authority signature: ${signature}`);
  141. const worldAccount = await worldProgram.account.world.fetch(worldPda);
  142. expect(
  143. worldAccount.authorities.some((auth) => auth.equals(secondAuthority)),
  144. );
  145. });
  146. it("Remove an authority", async () => {
  147. const addAuthority = await RemoveAuthority({
  148. authority: provider.wallet.publicKey,
  149. authorityToDelete: secondAuthority,
  150. world: worldPda,
  151. connection: provider.connection,
  152. });
  153. const signature = await provider.sendAndConfirm(addAuthority.transaction);
  154. console.log(`Add Authority signature: ${signature}`);
  155. const worldAccount = await worldProgram.account.world.fetch(worldPda);
  156. expect(
  157. !worldAccount.authorities.some((auth) => auth.equals(secondAuthority)),
  158. );
  159. });
  160. it("InitializeNewWorld 2", async () => {
  161. const initializeNewWorld = await InitializeNewWorld({
  162. payer: provider.wallet.publicKey,
  163. connection: provider.connection,
  164. });
  165. await provider.sendAndConfirm(initializeNewWorld.transaction);
  166. });
  167. it("Add entity 1", async () => {
  168. const addEntity = await AddEntity({
  169. payer: provider.wallet.publicKey,
  170. world: worldPda,
  171. connection: provider.connection,
  172. });
  173. await provider.sendAndConfirm(addEntity.transaction);
  174. entity1Pda = addEntity.entityPda; // Saved for later
  175. });
  176. it("Add entity 2", async () => {
  177. const addEntity = await AddEntity({
  178. payer: provider.wallet.publicKey,
  179. world: worldPda,
  180. connection: provider.connection,
  181. });
  182. await provider.sendAndConfirm(addEntity.transaction);
  183. entity2Pda = addEntity.entityPda; // Saved for later
  184. });
  185. it("Add entity 3", async () => {
  186. const addEntity = await AddEntity({
  187. payer: provider.wallet.publicKey,
  188. world: worldPda,
  189. connection: provider.connection,
  190. });
  191. await provider.sendAndConfirm(addEntity.transaction);
  192. });
  193. it("Add entity 4 (with seed)", async () => {
  194. const addEntity = await AddEntity({
  195. payer: provider.wallet.publicKey,
  196. world: worldPda,
  197. seed: Buffer.from("extra-seed"),
  198. connection: provider.connection,
  199. });
  200. await provider.sendAndConfirm(addEntity.transaction);
  201. entity4Pda = addEntity.entityPda;
  202. });
  203. it("Add entity 5", async () => {
  204. const addEntity = await AddEntity({
  205. payer: provider.wallet.publicKey,
  206. world: worldPda,
  207. connection: provider.connection,
  208. });
  209. await provider.sendAndConfirm(addEntity.transaction);
  210. entity5Pda = addEntity.entityPda; // Saved for later
  211. });
  212. it("Initialize Original Component on Entity 1, trough the world instance", async () => {
  213. const initializeComponent = await InitializeComponent({
  214. payer: provider.wallet.publicKey,
  215. entity: entity1Pda,
  216. seed: "origin-component",
  217. componentId: boltComponentProgram.programId,
  218. });
  219. await provider.sendAndConfirm(initializeComponent.transaction);
  220. });
  221. it("Initialize Original Component on Entity 2, trough the world instance", async () => {
  222. const initializeComponent = await InitializeComponent({
  223. payer: provider.wallet.publicKey,
  224. entity: entity2Pda,
  225. seed: "origin-component",
  226. componentId: boltComponentProgram.programId,
  227. });
  228. await provider.sendAndConfirm(initializeComponent.transaction);
  229. });
  230. it("Initialize Position Component on Entity 1", async () => {
  231. const initializeComponent = await InitializeComponent({
  232. payer: provider.wallet.publicKey,
  233. entity: entity1Pda,
  234. componentId: exampleComponentPosition.programId,
  235. });
  236. await provider.sendAndConfirm(initializeComponent.transaction);
  237. componentPositionEntity1Pda = initializeComponent.componentPda; // Saved for later
  238. });
  239. it("Initialize Velocity Component on Entity 1 (with seed)", async () => {
  240. const initializeComponent = await InitializeComponent({
  241. payer: provider.wallet.publicKey,
  242. entity: entity1Pda,
  243. componentId: exampleComponentVelocity.programId,
  244. seed: "component-velocity",
  245. });
  246. await provider.sendAndConfirm(initializeComponent.transaction);
  247. componentVelocityEntity1Pda = initializeComponent.componentPda; // Saved for later
  248. });
  249. it("Initialize Position Component on Entity 2", async () => {
  250. const initializeComponent = await InitializeComponent({
  251. payer: provider.wallet.publicKey,
  252. entity: entity2Pda,
  253. componentId: exampleComponentPosition.programId,
  254. });
  255. await provider.sendAndConfirm(initializeComponent.transaction);
  256. });
  257. it("Initialize Position Component on Entity 4", async () => {
  258. const initializeComponent = await InitializeComponent({
  259. payer: provider.wallet.publicKey,
  260. entity: entity4Pda,
  261. componentId: exampleComponentPosition.programId,
  262. });
  263. await provider.sendAndConfirm(initializeComponent.transaction);
  264. componentPositionEntity4Pda = initializeComponent.componentPda; // Saved for later
  265. });
  266. it("Initialize Position Component on Entity 5 (with authority)", async () => {
  267. const initializeComponent = await InitializeComponent({
  268. payer: provider.wallet.publicKey,
  269. entity: entity5Pda,
  270. componentId: exampleComponentPosition.programId,
  271. authority: provider.wallet.publicKey,
  272. });
  273. await provider.sendAndConfirm(initializeComponent.transaction);
  274. componentPositionEntity5Pda = initializeComponent.componentPda; // Saved for later
  275. });
  276. it("Check Position on Entity 1 is default", async () => {
  277. const position = await exampleComponentPosition.account.position.fetch(
  278. componentPositionEntity1Pda,
  279. );
  280. logPosition("Default State: Entity 1", position);
  281. expect(position.x.toNumber()).to.equal(0);
  282. expect(position.y.toNumber()).to.equal(0);
  283. expect(position.z.toNumber()).to.equal(0);
  284. });
  285. it("Apply Simple Movement System (Up) on Entity 1 using Apply", async () => {
  286. console.log("Apply", Apply);
  287. const apply = await Apply({
  288. authority: provider.wallet.publicKey,
  289. boltSystem: exampleSystemSimpleMovement,
  290. boltComponent: componentPositionEntity1Pda,
  291. componentProgram: exampleComponentPosition.programId,
  292. world: worldPda,
  293. args: SerializeArgs({
  294. direction: Direction.Up,
  295. }),
  296. });
  297. await provider.sendAndConfirm(apply.transaction);
  298. const position = await exampleComponentPosition.account.position.fetch(
  299. componentPositionEntity1Pda,
  300. );
  301. logPosition("Movement System: Entity 1", position);
  302. expect(position.x.toNumber()).to.equal(0);
  303. expect(position.y.toNumber()).to.equal(1);
  304. expect(position.z.toNumber()).to.equal(0);
  305. });
  306. it("Apply Simple Movement System (Up) on Entity 1", async () => {
  307. const applySystem = await ApplySystem({
  308. authority: provider.wallet.publicKey,
  309. systemId: exampleSystemSimpleMovement,
  310. world: worldPda,
  311. entities: [
  312. {
  313. entity: entity1Pda,
  314. components: [{ componentId: exampleComponentPosition.programId }],
  315. },
  316. ],
  317. args: {
  318. direction: Direction.Up,
  319. },
  320. });
  321. const signature = await provider.sendAndConfirm(
  322. applySystem.transaction,
  323. [],
  324. { skipPreflight: true },
  325. );
  326. console.log(`Signature: ${signature}`);
  327. const position = await exampleComponentPosition.account.position.fetch(
  328. componentPositionEntity1Pda,
  329. );
  330. logPosition("Movement System: Entity 1", position);
  331. expect(position.x.toNumber()).to.equal(0);
  332. expect(position.y.toNumber()).to.equal(2);
  333. expect(position.z.toNumber()).to.equal(0);
  334. });
  335. it("Apply Simple Movement System (Right) on Entity 1", async () => {
  336. const applySystem = await ApplySystem({
  337. authority: provider.wallet.publicKey,
  338. systemId: exampleSystemSimpleMovement,
  339. world: worldPda,
  340. entities: [
  341. {
  342. entity: entity1Pda,
  343. components: [{ componentId: exampleComponentPosition.programId }],
  344. },
  345. ],
  346. args: {
  347. direction: Direction.Right,
  348. },
  349. });
  350. await provider.sendAndConfirm(applySystem.transaction);
  351. const position = await exampleComponentPosition.account.position.fetch(
  352. componentPositionEntity1Pda,
  353. );
  354. logPosition("Movement System: Entity 1", position);
  355. expect(position.x.toNumber()).to.equal(1);
  356. expect(position.y.toNumber()).to.equal(2);
  357. expect(position.z.toNumber()).to.equal(0);
  358. });
  359. it("Apply Fly System on Entity 1", async () => {
  360. const applySystem = await ApplySystem({
  361. authority: provider.wallet.publicKey,
  362. systemId: exampleSystemFly,
  363. world: worldPda,
  364. entities: [
  365. {
  366. entity: entity1Pda,
  367. components: [{ componentId: exampleComponentPosition.programId }],
  368. },
  369. ],
  370. });
  371. await provider.sendAndConfirm(applySystem.transaction);
  372. const position = await exampleComponentPosition.account.position.fetch(
  373. componentPositionEntity1Pda,
  374. );
  375. logPosition("Fly System: Entity 1", position);
  376. expect(position.x.toNumber()).to.equal(1);
  377. expect(position.y.toNumber()).to.equal(2);
  378. expect(position.z.toNumber()).to.equal(1);
  379. });
  380. it("Apply System Velocity on Entity 1", async () => {
  381. const applySystem = await ApplySystem({
  382. authority: provider.wallet.publicKey,
  383. systemId: exampleSystemApplyVelocity,
  384. world: worldPda,
  385. entities: [
  386. {
  387. entity: entity1Pda,
  388. components: [
  389. {
  390. componentId: exampleComponentVelocity.programId,
  391. seed: "component-velocity",
  392. },
  393. { componentId: exampleComponentPosition.programId },
  394. ],
  395. },
  396. ],
  397. });
  398. await provider.sendAndConfirm(applySystem.transaction);
  399. const velocity = await exampleComponentVelocity.account.velocity.fetch(
  400. componentVelocityEntity1Pda,
  401. );
  402. logVelocity("Apply System Velocity: Entity 1", velocity);
  403. expect(velocity.x.toNumber()).to.equal(10);
  404. expect(velocity.y.toNumber()).to.equal(0);
  405. expect(velocity.z.toNumber()).to.equal(0);
  406. expect(velocity.lastApplied.toNumber()).to.not.equal(0);
  407. const position = await exampleComponentPosition.account.position.fetch(
  408. componentPositionEntity1Pda,
  409. );
  410. logPosition("Apply System Velocity: Entity 1", position);
  411. expect(position.x.toNumber()).to.greaterThan(1);
  412. expect(position.y.toNumber()).to.equal(2);
  413. expect(position.z.toNumber()).to.equal(1);
  414. });
  415. it("Apply System Velocity on Entity 1, with Clock external account", async () => {
  416. const applySystem = await ApplySystem({
  417. authority: provider.wallet.publicKey,
  418. systemId: exampleSystemApplyVelocity,
  419. world: worldPda,
  420. entities: [
  421. {
  422. entity: entity1Pda,
  423. components: [
  424. {
  425. componentId: exampleComponentVelocity.programId,
  426. seed: "component-velocity",
  427. },
  428. { componentId: exampleComponentPosition.programId },
  429. ],
  430. },
  431. ],
  432. extraAccounts: [
  433. {
  434. pubkey: new web3.PublicKey(
  435. "SysvarC1ock11111111111111111111111111111111",
  436. ),
  437. isWritable: false,
  438. isSigner: false,
  439. },
  440. ],
  441. });
  442. await provider.sendAndConfirm(applySystem.transaction);
  443. const position = await exampleComponentPosition.account.position.fetch(
  444. componentPositionEntity1Pda,
  445. );
  446. logPosition("Apply System Velocity: Entity 1", position);
  447. expect(position.x.toNumber()).to.greaterThan(1);
  448. expect(position.y.toNumber()).to.equal(2);
  449. expect(position.z.toNumber()).to.equal(300);
  450. });
  451. it("Apply Fly System on Entity 4", async () => {
  452. const applySystem = await ApplySystem({
  453. authority: provider.wallet.publicKey,
  454. systemId: exampleSystemFly,
  455. world: worldPda,
  456. entities: [
  457. {
  458. entity: entity4Pda,
  459. components: [{ componentId: exampleComponentPosition.programId }],
  460. },
  461. ],
  462. });
  463. await provider.sendAndConfirm(applySystem.transaction);
  464. const position = await exampleComponentPosition.account.position.fetch(
  465. componentPositionEntity4Pda,
  466. );
  467. logPosition("Fly System: Entity 4", position);
  468. expect(position.x.toNumber()).to.equal(0);
  469. expect(position.y.toNumber()).to.equal(0);
  470. expect(position.z.toNumber()).to.equal(1);
  471. });
  472. it("Apply Fly System on Entity 5 (should fail with wrong authority)", async () => {
  473. const positionBefore =
  474. await exampleComponentPosition.account.position.fetch(
  475. componentPositionEntity5Pda,
  476. );
  477. const applySystem = await ApplySystem({
  478. authority: provider.wallet.publicKey,
  479. systemId: exampleSystemFly,
  480. world: worldPda,
  481. entities: [
  482. {
  483. entity: entity5Pda,
  484. components: [{ componentId: exampleComponentPosition.programId }],
  485. },
  486. ],
  487. });
  488. let failed = false;
  489. try {
  490. await provider.sendAndConfirm(applySystem.transaction);
  491. } catch (error) {
  492. failed = true;
  493. // console.log("error", error);
  494. expect(error.logs.join("\n")).to.contain("Error Code: InvalidAuthority");
  495. }
  496. expect(failed).to.equal(true);
  497. const positionAfter = await exampleComponentPosition.account.position.fetch(
  498. componentPositionEntity5Pda,
  499. );
  500. expect(positionBefore.x.toNumber()).to.equal(positionAfter.x.toNumber());
  501. expect(positionBefore.y.toNumber()).to.equal(positionAfter.y.toNumber());
  502. expect(positionBefore.z.toNumber()).to.equal(positionAfter.z.toNumber());
  503. });
  504. it("Whitelist System", async () => {
  505. const approveSystem = await ApproveSystem({
  506. authority: provider.wallet.publicKey,
  507. systemToApprove: exampleSystemFly,
  508. world: worldPda,
  509. });
  510. const signature = await provider.sendAndConfirm(
  511. approveSystem.transaction,
  512. [],
  513. { skipPreflight: true },
  514. );
  515. console.log(`Whitelist 2 system approval signature: ${signature}`);
  516. // Get World and check permissionless and systems
  517. const worldAccount = await worldProgram.account.world.fetch(worldPda);
  518. expect(worldAccount.permissionless).to.equal(false);
  519. expect(worldAccount.systems.length).to.be.greaterThan(0);
  520. });
  521. it("Whitelist System 2", async () => {
  522. const approveSystem = await ApproveSystem({
  523. authority: provider.wallet.publicKey,
  524. systemToApprove: exampleSystemApplyVelocity,
  525. world: worldPda,
  526. });
  527. const signature = await provider.sendAndConfirm(
  528. approveSystem.transaction,
  529. [],
  530. { skipPreflight: true },
  531. );
  532. console.log(`Whitelist 2 system approval signature: ${signature}`);
  533. // Get World and check permissionless and systems
  534. const worldAccount = await worldProgram.account.world.fetch(worldPda);
  535. expect(worldAccount.permissionless).to.equal(false);
  536. expect(worldAccount.systems.length).to.be.greaterThan(0);
  537. });
  538. it("Apply Fly System on Entity 1", async () => {
  539. const applySystem = await ApplySystem({
  540. authority: provider.wallet.publicKey,
  541. systemId: exampleSystemFly,
  542. world: worldPda,
  543. entities: [
  544. {
  545. entity: entity1Pda,
  546. components: [{ componentId: exampleComponentPosition.programId }],
  547. },
  548. ],
  549. });
  550. await provider.sendAndConfirm(applySystem.transaction);
  551. });
  552. it("Remove System 1", async () => {
  553. const approveSystem = await RemoveSystem({
  554. authority: provider.wallet.publicKey,
  555. systemToRemove: exampleSystemFly,
  556. world: worldPda,
  557. });
  558. const signature = await provider.sendAndConfirm(
  559. approveSystem.transaction,
  560. [],
  561. { skipPreflight: true },
  562. );
  563. console.log(`Whitelist 2 system approval signature: ${signature}`);
  564. // Get World and check permissionless and systems
  565. const worldAccount = await worldProgram.account.world.fetch(worldPda);
  566. expect(worldAccount.permissionless).to.equal(false);
  567. expect(worldAccount.systems.length).to.be.greaterThan(0);
  568. });
  569. it("Apply Invalid Fly System on Entity 1", async () => {
  570. const applySystem = await ApplySystem({
  571. authority: provider.wallet.publicKey,
  572. systemId: exampleSystemFly,
  573. world: worldPda,
  574. entities: [
  575. {
  576. entity: entity1Pda,
  577. components: [{ componentId: exampleComponentPosition.programId }],
  578. },
  579. ],
  580. });
  581. let invalid = false;
  582. try {
  583. await provider.sendAndConfirm(applySystem.transaction);
  584. } catch (error) {
  585. expect(error.logs.join(" ")).to.contain("Error Code: SystemNotApproved");
  586. invalid = true;
  587. }
  588. expect(invalid).to.equal(true);
  589. });
  590. it("Check invalid component init without CPI", async () => {
  591. let invalid = false;
  592. try {
  593. await exampleComponentPosition.methods
  594. .initialize()
  595. .accounts({
  596. payer: provider.wallet.publicKey,
  597. data: componentPositionEntity5Pda,
  598. entity: entity5Pda,
  599. authority: provider.wallet.publicKey,
  600. })
  601. .rpc();
  602. } catch (error) {
  603. // console.log("error", error);
  604. expect(error.message).to.contain("Error Code: InvalidCaller");
  605. invalid = true;
  606. }
  607. expect(invalid).to.equal(true);
  608. });
  609. it("Check invalid component update without CPI", async () => {
  610. let invalid = false;
  611. try {
  612. await boltComponentProgram.methods
  613. .update(Buffer.from(""))
  614. .accounts({
  615. boltComponent: componentPositionEntity4Pda,
  616. authority: provider.wallet.publicKey,
  617. })
  618. .rpc();
  619. } catch (error) {
  620. // console.log("error", error);
  621. expect(error.message).to.contain(
  622. "bolt_component. Error Code: AccountOwnedByWrongProgram",
  623. );
  624. invalid = true;
  625. }
  626. expect(invalid).to.equal(true);
  627. });
  628. it("Check component delegation", async () => {
  629. const delegateComponent = await DelegateComponent({
  630. payer: provider.wallet.publicKey,
  631. entity: entity1Pda,
  632. componentId: exampleComponentPosition.programId,
  633. });
  634. const txSign = await provider.sendAndConfirm(
  635. delegateComponent.transaction,
  636. [],
  637. { skipPreflight: true, commitment: "confirmed" },
  638. );
  639. console.log(`Delegation signature: ${txSign}`);
  640. const acc = await provider.connection.getAccountInfo(
  641. delegateComponent.componentPda,
  642. );
  643. expect(acc?.owner.toString()).to.equal(DELEGATION_PROGRAM_ID);
  644. });
  645. });