bolt.ts 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. import * as anchor from "@coral-xyz/anchor";
  2. import { Program } from "@coral-xyz/anchor";
  3. import { PublicKey } from "@solana/web3.js";
  4. import { ComponentPosition } from "../target/types/component_position";
  5. import { ComponentVelocity } from "../target/types/component_velocity";
  6. import { BoltComponent } from "../target/types/bolt_component";
  7. import { SystemSimpleMovement } from "../target/types/system_simple_movement";
  8. import { SystemFly } from "../target/types/system_fly";
  9. import { SystemApplyVelocity } from "../target/types/system_apply_velocity";
  10. import { World } from "../target/types/world";
  11. import { expect } from "chai";
  12. import BN from "bn.js";
  13. enum Direction {
  14. Left = "Left",
  15. Right = "Right",
  16. Up = "Up",
  17. Down = "Down",
  18. }
  19. function serializeArgs(args: any = {}) {
  20. const jsonString = JSON.stringify(args);
  21. const encoder = new TextEncoder();
  22. const binaryData = encoder.encode(jsonString);
  23. return Buffer.from(
  24. binaryData.buffer,
  25. binaryData.byteOffset,
  26. binaryData.byteLength
  27. );
  28. }
  29. describe("bolt", () => {
  30. const provider = anchor.AnchorProvider.env();
  31. anchor.setProvider(provider);
  32. const worldProgram = anchor.workspace.World as Program<World>;
  33. const boltComponentPositionProgram = anchor.workspace
  34. .ComponentPosition as Program<ComponentPosition>;
  35. const boltComponentVelocityProgram = anchor.workspace
  36. .ComponentVelocity as Program<ComponentVelocity>;
  37. const boltComponentProgramOrigin = anchor.workspace
  38. .BoltComponent as Program<BoltComponent>;
  39. const systemSimpleMovement = (
  40. anchor.workspace.SystemSimpleMovement as Program<SystemSimpleMovement>
  41. ).programId;
  42. const systemFly = (anchor.workspace.SystemFly as Program<SystemFly>)
  43. .programId;
  44. const applyVelocity = (
  45. anchor.workspace.SystemApplyVelocity as Program<SystemApplyVelocity>
  46. ).programId;
  47. let entity1: PublicKey;
  48. let entity2: PublicKey;
  49. let componentPositionEntity1: PublicKey;
  50. let componentPositionEntity2: PublicKey;
  51. let componentVelocityEntity1: PublicKey;
  52. it("InitializeWorldsRegistry", async () => {
  53. const registryPda = FindWorldRegistryPda(worldProgram);
  54. await worldProgram.methods
  55. .initializeRegistry()
  56. .accounts({
  57. registry: registryPda,
  58. payer: provider.wallet.publicKey,
  59. })
  60. .rpc();
  61. });
  62. it("InitializeNewWorld", async () => {
  63. const registryPda = FindWorldRegistryPda(worldProgram);
  64. const worldPda = FindWorldPda(worldProgram, new BN(0));
  65. await worldProgram.methods
  66. .initializeNewWorld()
  67. .accounts({
  68. world: worldPda,
  69. registry: registryPda,
  70. payer: provider.wallet.publicKey,
  71. })
  72. .rpc();
  73. });
  74. it("Add entity 1", async () => {
  75. const worldPda = FindWorldPda(worldProgram, new BN(0));
  76. entity1 = FindEntityPda(worldProgram, new BN(0), new BN(0));
  77. await worldProgram.methods
  78. .addEntity()
  79. .accounts({
  80. world: worldPda,
  81. entity: entity1,
  82. payer: provider.wallet.publicKey,
  83. })
  84. .rpc();
  85. });
  86. it("Add entity 2", async () => {
  87. const worldPda = FindWorldPda(worldProgram, new BN(0));
  88. entity2 = FindEntityPda(worldProgram, new BN(0), new BN(1));
  89. await worldProgram.methods
  90. .addEntity()
  91. .accounts({
  92. world: worldPda,
  93. entity: entity2,
  94. payer: provider.wallet.publicKey,
  95. })
  96. .rpc();
  97. });
  98. it("Add entity 3", async () => {
  99. const worldPda = FindWorldPda(worldProgram, new BN(0));
  100. const entityPda = FindEntityPda(worldProgram, new BN(0), new BN(2));
  101. await worldProgram.methods
  102. .addEntity()
  103. .accounts({
  104. world: worldPda,
  105. entity: entityPda,
  106. payer: provider.wallet.publicKey,
  107. })
  108. .rpc();
  109. });
  110. it("Initialize Original Component on Entity 1, trough the world instance", async () => {
  111. let componentEntity1 = FindComponentPda(
  112. boltComponentProgramOrigin.programId,
  113. entity1,
  114. "origin-component"
  115. );
  116. await worldProgram.methods
  117. .initializeComponent()
  118. .accounts({
  119. payer: provider.wallet.publicKey,
  120. data: componentEntity1,
  121. componentProgram: boltComponentProgramOrigin.programId,
  122. entity: entity1,
  123. })
  124. .rpc();
  125. });
  126. it("Initialize Original Component on Entity 2, trough the world instance", async () => {
  127. let componentEntity2 = FindComponentPda(
  128. boltComponentProgramOrigin.programId,
  129. entity2,
  130. "origin-component"
  131. );
  132. await worldProgram.methods
  133. .initializeComponent()
  134. .accounts({
  135. payer: provider.wallet.publicKey,
  136. data: componentEntity2,
  137. componentProgram: boltComponentProgramOrigin.programId,
  138. entity: entity2,
  139. })
  140. .rpc();
  141. });
  142. it("Initialize Position Component on Entity 1", async () => {
  143. componentPositionEntity1 = FindComponentPda(
  144. boltComponentPositionProgram.programId,
  145. entity1,
  146. "component-position"
  147. );
  148. console.log("Component Position E1: ", componentPositionEntity1.toBase58());
  149. await worldProgram.methods
  150. .initializeComponent()
  151. .accounts({
  152. payer: provider.wallet.publicKey,
  153. data: componentPositionEntity1,
  154. componentProgram: boltComponentPositionProgram.programId,
  155. entity: entity1,
  156. })
  157. .rpc();
  158. });
  159. it("Initialize Velocity Component on Entity 1", async () => {
  160. componentVelocityEntity1 = FindComponentPda(
  161. boltComponentVelocityProgram.programId,
  162. entity1,
  163. "component-velocity"
  164. );
  165. await worldProgram.methods
  166. .initializeComponent()
  167. .accounts({
  168. payer: provider.wallet.publicKey,
  169. data: componentVelocityEntity1,
  170. componentProgram: boltComponentVelocityProgram.programId,
  171. entity: entity1,
  172. })
  173. .rpc();
  174. });
  175. it("Initialize Position Component on Entity 2", async () => {
  176. componentPositionEntity2 = FindComponentPda(
  177. boltComponentPositionProgram.programId,
  178. entity2,
  179. "component-position"
  180. );
  181. await worldProgram.methods
  182. .initializeComponent()
  183. .accounts({
  184. payer: provider.wallet.publicKey,
  185. data: componentPositionEntity2,
  186. componentProgram: boltComponentPositionProgram.programId,
  187. entity: entity2,
  188. })
  189. .rpc();
  190. });
  191. it("Check Position on Entity 1 is default", async () => {
  192. expect(
  193. (
  194. await boltComponentPositionProgram.account.position.fetch(
  195. componentPositionEntity1
  196. )
  197. ).x.toNumber()
  198. ).to.equal(0);
  199. expect(
  200. (
  201. await boltComponentPositionProgram.account.position.fetch(
  202. componentPositionEntity1
  203. )
  204. ).y.toNumber()
  205. ).to.equal(0);
  206. expect(
  207. (
  208. await boltComponentPositionProgram.account.position.fetch(
  209. componentPositionEntity1
  210. )
  211. ).z.toNumber()
  212. ).to.equal(0);
  213. });
  214. it("Simple Movement System and Up direction on Entity 1", async () => {
  215. const args = {
  216. direction: Direction.Up,
  217. };
  218. await worldProgram.methods
  219. .apply(serializeArgs(args)) // Move Up
  220. .accounts({
  221. componentProgram: boltComponentPositionProgram.programId,
  222. boltSystem: systemSimpleMovement,
  223. boltComponent: componentPositionEntity1,
  224. })
  225. .rpc({ skipPreflight: true });
  226. expect(
  227. (
  228. await boltComponentPositionProgram.account.position.fetch(
  229. componentPositionEntity1
  230. )
  231. ).y.toNumber()
  232. ).to.equal(1);
  233. const componentData =
  234. await boltComponentPositionProgram.account.position.fetch(
  235. componentPositionEntity1
  236. );
  237. const x = componentData.x.toNumber();
  238. const y = componentData.y.toNumber();
  239. const z = componentData.z.toNumber();
  240. console.log("+-----------------------------+");
  241. console.log("| Movement System: Entity 1 |");
  242. console.log("+----------------+------------+");
  243. console.log("| Coordinate | Value |");
  244. console.log("+----------------+------------+");
  245. console.log(`| X Position | ${String(x).padEnd(10, " ")} |`);
  246. console.log("| | |");
  247. console.log(`| Y Position | ${String(y).padEnd(10, " ")} |`);
  248. console.log("| | |");
  249. console.log(`| Z Position | ${String(z).padEnd(10, " ")} |`);
  250. console.log("+----------------+------------+");
  251. console.log("| |");
  252. console.log("+-----------------------------+");
  253. });
  254. it("Simple Movement System and Right direction on Entity 1", async () => {
  255. const args = {
  256. direction: Direction.Right,
  257. };
  258. await worldProgram.methods
  259. .apply(serializeArgs(args)) // Move Right
  260. .accounts({
  261. componentProgram: boltComponentPositionProgram.programId,
  262. boltSystem: systemSimpleMovement,
  263. boltComponent: componentPositionEntity1,
  264. })
  265. .rpc({ skipPreflight: true });
  266. expect(
  267. (
  268. await boltComponentPositionProgram.account.position.fetch(
  269. componentPositionEntity1
  270. )
  271. ).y.toNumber()
  272. ).to.equal(1);
  273. expect(
  274. (
  275. await boltComponentPositionProgram.account.position.fetch(
  276. componentPositionEntity1
  277. )
  278. ).y.toNumber()
  279. ).to.equal(1);
  280. const componentData =
  281. await boltComponentPositionProgram.account.position.fetch(
  282. componentPositionEntity1
  283. );
  284. const x = componentData.x.toNumber();
  285. const y = componentData.y.toNumber();
  286. const z = componentData.z.toNumber();
  287. console.log("+-----------------------------+");
  288. console.log("| Movement System: Entity 1 |");
  289. console.log("+----------------+------------+");
  290. console.log("| Coordinate | Value |");
  291. console.log("+----------------+------------+");
  292. console.log(`| X Position | ${String(x).padEnd(10, " ")} |`);
  293. console.log("| | |");
  294. console.log(`| Y Position | ${String(y).padEnd(10, " ")} |`);
  295. console.log("| | |");
  296. console.log(`| Z Position | ${String(z).padEnd(10, " ")} |`);
  297. console.log("+----------------+------------+");
  298. console.log("| |");
  299. console.log("+-----------------------------+");
  300. });
  301. it("Fly System on Entity 1", async () => {
  302. await worldProgram.methods
  303. .apply(Buffer.alloc(0)) // Move Up
  304. .accounts({
  305. componentProgram: boltComponentPositionProgram.programId,
  306. boltSystem: systemFly,
  307. boltComponent: componentPositionEntity1,
  308. })
  309. .rpc();
  310. expect(
  311. (
  312. await boltComponentPositionProgram.account.position.fetch(
  313. componentPositionEntity1
  314. )
  315. ).z.toNumber()
  316. ).to.equal(1);
  317. const componentData =
  318. await boltComponentPositionProgram.account.position.fetch(
  319. componentPositionEntity1
  320. );
  321. const x = componentData.x.toNumber();
  322. const y = componentData.y.toNumber();
  323. const z = componentData.z.toNumber();
  324. console.log("+-----------------------------+");
  325. console.log("| Fly: Position Entity 1 |");
  326. console.log("+----------------+------------+");
  327. console.log("| Coordinate | Value |");
  328. console.log("+----------------+------------+");
  329. console.log(`| X Position | ${String(x).padEnd(10, " ")} |`);
  330. console.log("| | |");
  331. console.log(`| Y Position | ${String(y).padEnd(10, " ")} |`);
  332. console.log("| | |");
  333. console.log(`| Z Position | ${String(z).padEnd(10, " ")} |`);
  334. console.log("+----------------+------------+");
  335. console.log("| |");
  336. console.log("+-----------------------------+");
  337. });
  338. it("Apply Velocity on Entity 1", async () => {
  339. await worldProgram.methods
  340. .apply2(Buffer.alloc(0))
  341. .accounts({
  342. componentProgram1: boltComponentVelocityProgram.programId,
  343. componentProgram2: boltComponentPositionProgram.programId,
  344. boltSystem: applyVelocity,
  345. boltComponent1: componentVelocityEntity1,
  346. boltComponent2: componentPositionEntity1,
  347. })
  348. .remainingAccounts([
  349. {
  350. pubkey: componentPositionEntity1,
  351. isWritable: false,
  352. isSigner: false,
  353. },
  354. ])
  355. .rpc();
  356. console.log("Component Velocity: ", componentVelocityEntity1.toBase58());
  357. let componentData =
  358. await boltComponentVelocityProgram.account.velocity.fetch(
  359. componentVelocityEntity1
  360. );
  361. let x = componentData.x.toNumber();
  362. let y = componentData.y.toNumber();
  363. let z = componentData.z.toNumber();
  364. const tmp = componentData.lastApplied.toNumber();
  365. console.log("+-----------------------------+");
  366. console.log("| Apply Velocity: Velocity Entity 1 |");
  367. console.log("+----------------+------------+");
  368. console.log("| Coordinate | Value |");
  369. console.log("+----------------+------------+");
  370. console.log(`| X Position | ${String(x).padEnd(10, " ")} |`);
  371. console.log("| | |");
  372. console.log(`| Y Position | ${String(y).padEnd(10, " ")} |`);
  373. console.log("| | |");
  374. console.log(`| Z Position | ${String(z).padEnd(10, " ")} |`);
  375. console.log("| | |");
  376. console.log(`| Timestamp | ${String(tmp).padEnd(10, " ")} |`);
  377. console.log("+----------------+------------+");
  378. console.log("| |");
  379. console.log("+-----------------------------+");
  380. let positionData =
  381. await boltComponentPositionProgram.account.position.fetch(
  382. componentPositionEntity1
  383. );
  384. x = positionData.x.toNumber();
  385. y = positionData.y.toNumber();
  386. z = positionData.z.toNumber();
  387. console.log("+-----------------------------+");
  388. console.log("| Apply Velocity: Position Entity 1 |");
  389. console.log("+----------------+------------+");
  390. console.log("| Coordinate | Value |");
  391. console.log("+----------------+------------+");
  392. console.log(`| X Position | ${String(x).padEnd(10, " ")} |`);
  393. console.log("| | |");
  394. console.log(`| Y Position | ${String(y).padEnd(10, " ")} |`);
  395. console.log("| | |");
  396. console.log(`| Z Position | ${String(z).padEnd(10, " ")} |`);
  397. console.log("+----------------+------------+");
  398. console.log("| |");
  399. console.log("+-----------------------------+");
  400. });
  401. // Utils
  402. function FindWorldRegistryPda(program: Program<World>) {
  403. return PublicKey.findProgramAddressSync(
  404. [Buffer.from("registry")],
  405. program.programId
  406. )[0];
  407. }
  408. function FindWorldPda(program: Program<World>, id: BN) {
  409. return PublicKey.findProgramAddressSync(
  410. [Buffer.from("world"), id.toBuffer("le", 8)],
  411. program.programId
  412. )[0];
  413. }
  414. function FindEntityPda(program: Program<World>, worldId: BN, entityId: BN) {
  415. return PublicKey.findProgramAddressSync(
  416. [
  417. Buffer.from("entity"),
  418. worldId.toBuffer("be", 8),
  419. entityId.toBuffer("be", 8),
  420. ],
  421. program.programId
  422. )[0];
  423. }
  424. function FindComponentPda(
  425. program: PublicKey,
  426. entity: PublicKey,
  427. seed: string = "component"
  428. ) {
  429. return PublicKey.findProgramAddressSync(
  430. [Buffer.from(seed), entity.toBytes()],
  431. program
  432. )[0];
  433. }
  434. });