bolt.ts 22 KB

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