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