solana.test.ts 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. import {
  2. afterAll,
  3. beforeAll,
  4. describe,
  5. expect,
  6. jest,
  7. test,
  8. } from "@jest/globals";
  9. import Web3, { ETH_DATA_FORMAT } from "web3";
  10. import axios from "axios";
  11. import { AxiosResponse } from "axios";
  12. import base58 from "bs58";
  13. import {
  14. ChainQueryType,
  15. SolanaAccountQueryRequest,
  16. SolanaAccountQueryResponse,
  17. SolanaAccountResult,
  18. SolanaPdaEntry,
  19. SolanaPdaQueryRequest,
  20. SolanaPdaQueryResponse,
  21. PerChainQueryRequest,
  22. QueryRequest,
  23. sign,
  24. QueryResponse,
  25. } from "..";
  26. jest.setTimeout(125000);
  27. const CI = process.env.CI;
  28. const ENV = "DEVNET";
  29. const SERVER_URL = CI ? "http://query-server:" : "http://localhost:";
  30. const CCQ_SERVER_URL = SERVER_URL + "6069/v1";
  31. const QUERY_URL = CCQ_SERVER_URL + "/query";
  32. const SOLANA_NODE_URL = CI
  33. ? "http://solana-devnet:8899"
  34. : "http://localhost:8899";
  35. const PRIVATE_KEY =
  36. "cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0";
  37. const ACCOUNTS = [
  38. "2WDq7wSs9zYrpx2kbHDA4RUTRch2CCTP6ZWaH4GNfnQQ", // Example token in devnet
  39. "BVxyYhm498L79r4HMQ9sxZ5bi41DmJmeWZ7SCS7Cyvna", // Example NFT in devnet
  40. ];
  41. const PDAS: SolanaPdaEntry[] = [
  42. {
  43. programAddress: Uint8Array.from(
  44. base58.decode("Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o")
  45. ), // Core Bridge address
  46. seeds: [
  47. new Uint8Array(Buffer.from("GuardianSet")),
  48. new Uint8Array(Buffer.alloc(4)),
  49. ], // Use index zero in tilt.
  50. },
  51. ];
  52. async function getSolanaSlot(comm: string): Promise<bigint> {
  53. const response = await axios.post(SOLANA_NODE_URL, {
  54. jsonrpc: "2.0",
  55. id: 1,
  56. method: "getSlot",
  57. params: [{ commitment: comm, transactionDetails: "none" }],
  58. });
  59. return response.data.result;
  60. }
  61. describe("solana", () => {
  62. test("serialize and deserialize sol_account request with defaults", () => {
  63. const solAccountReq = new SolanaAccountQueryRequest("finalized", ACCOUNTS);
  64. expect(solAccountReq.minContextSlot).toEqual(BigInt(0));
  65. expect(solAccountReq.dataSliceOffset).toEqual(BigInt(0));
  66. expect(solAccountReq.dataSliceLength).toEqual(BigInt(0));
  67. const serialized = solAccountReq.serialize();
  68. expect(Buffer.from(serialized).toString("hex")).toEqual(
  69. "0000000966696e616c697a656400000000000000000000000000000000000000000000000002165809739240a0ac03b98440fe8985548e3aa683cd0d4d9df5b5659669faa3019c006c48c8cbf33849cb07a3f936159cc523f9591cb1999abd45890ec5fee9b7"
  70. );
  71. const solAccountReq2 = SolanaAccountQueryRequest.from(serialized);
  72. expect(solAccountReq2).toEqual(solAccountReq);
  73. });
  74. test("serialize and deserialize sol_account request no defaults", () => {
  75. const minContextSlot = BigInt(123456);
  76. const dataSliceOffset = BigInt(12);
  77. const dataSliceLength = BigInt(100);
  78. const solAccountReq = new SolanaAccountQueryRequest(
  79. "finalized",
  80. ACCOUNTS,
  81. minContextSlot,
  82. dataSliceOffset,
  83. dataSliceLength
  84. );
  85. expect(solAccountReq.minContextSlot).toEqual(minContextSlot);
  86. expect(solAccountReq.dataSliceOffset).toEqual(dataSliceOffset);
  87. expect(solAccountReq.dataSliceLength).toEqual(dataSliceLength);
  88. const serialized = solAccountReq.serialize();
  89. expect(Buffer.from(serialized).toString("hex")).toEqual(
  90. "0000000966696e616c697a6564000000000001e240000000000000000c000000000000006402165809739240a0ac03b98440fe8985548e3aa683cd0d4d9df5b5659669faa3019c006c48c8cbf33849cb07a3f936159cc523f9591cb1999abd45890ec5fee9b7"
  91. );
  92. const solAccountReq2 = SolanaAccountQueryRequest.from(serialized);
  93. expect(solAccountReq2).toEqual(solAccountReq);
  94. });
  95. test("serialize and deserialize sol_account response", () => {
  96. const slotNumber = BigInt(240866260);
  97. const blockTime = BigInt(1704770509);
  98. const blockHash = Uint8Array.from(
  99. Buffer.from(
  100. "9999bac44d09a7f69ee7941819b0a19c59ccb1969640cc513be09ef95ed2d8e3",
  101. "hex"
  102. )
  103. );
  104. const results: SolanaAccountResult[] = [
  105. {
  106. lamports: BigInt(1141440),
  107. rentEpoch: BigInt(123456),
  108. executable: false,
  109. owner: Uint8Array.from(
  110. Buffer.from(
  111. "02a8f6914e88a16e395ae128948ffa695693376818dd47435221f3c600000000",
  112. "hex"
  113. )
  114. ),
  115. data: Uint8Array.from(
  116. Buffer.from(
  117. "0200000062d14b7d0e121f8575cce871896548fe26d2899b0578ec92117440cda609b010",
  118. "hex"
  119. )
  120. ),
  121. },
  122. {
  123. lamports: BigInt(1141441),
  124. rentEpoch: BigInt(123457),
  125. executable: true,
  126. owner: Uint8Array.from(
  127. Buffer.from(
  128. "02a8f6914e88a16e395ae128948ffa695693376818dd47435221f3c600000000",
  129. "hex"
  130. )
  131. ),
  132. data: Uint8Array.from(
  133. Buffer.from(
  134. "0200000083f7752f3b75f905f040f0087c67c47a52272fcfa90e691ea6e8d4362039ecd5",
  135. "hex"
  136. )
  137. ),
  138. },
  139. ];
  140. const solAccountResp = new SolanaAccountQueryResponse(
  141. slotNumber,
  142. blockTime,
  143. blockHash,
  144. results
  145. );
  146. expect(solAccountResp.slotNumber).toEqual(slotNumber);
  147. expect(solAccountResp.blockTime).toEqual(blockTime);
  148. expect(solAccountResp.results).toEqual(results);
  149. const serialized = solAccountResp.serialize();
  150. expect(Buffer.from(serialized).toString("hex")).toEqual(
  151. "000000000e5b53d400000000659cbbcd9999bac44d09a7f69ee7941819b0a19c59ccb1969640cc513be09ef95ed2d8e3020000000000116ac0000000000001e2400002a8f6914e88a16e395ae128948ffa695693376818dd47435221f3c600000000000000240200000062d14b7d0e121f8575cce871896548fe26d2899b0578ec92117440cda609b0100000000000116ac1000000000001e2410102a8f6914e88a16e395ae128948ffa695693376818dd47435221f3c600000000000000240200000083f7752f3b75f905f040f0087c67c47a52272fcfa90e691ea6e8d4362039ecd5"
  152. );
  153. const solAccountResp2 = SolanaAccountQueryResponse.from(serialized);
  154. expect(solAccountResp2).toEqual(solAccountResp);
  155. });
  156. test("successful sol_account query", async () => {
  157. const solAccountReq = new SolanaAccountQueryRequest("finalized", ACCOUNTS);
  158. const nonce = 42;
  159. const query = new PerChainQueryRequest(1, solAccountReq);
  160. const request = new QueryRequest(nonce, [query]);
  161. const serialized = request.serialize();
  162. const digest = QueryRequest.digest(ENV, serialized);
  163. const signature = sign(PRIVATE_KEY, digest);
  164. const response = await axios.put(
  165. QUERY_URL,
  166. {
  167. signature,
  168. bytes: Buffer.from(serialized).toString("hex"),
  169. },
  170. { headers: { "X-API-Key": "my_secret_key" } }
  171. );
  172. expect(response.status).toBe(200);
  173. const queryResponse = QueryResponse.from(response.data.bytes);
  174. expect(queryResponse.version).toEqual(1);
  175. expect(queryResponse.requestChainId).toEqual(0);
  176. expect(queryResponse.request.version).toEqual(1);
  177. expect(queryResponse.request.requests.length).toEqual(1);
  178. expect(queryResponse.request.requests[0].chainId).toEqual(1);
  179. expect(queryResponse.request.requests[0].query.type()).toEqual(
  180. ChainQueryType.SolanaAccount
  181. );
  182. const sar = queryResponse.responses[0]
  183. .response as SolanaAccountQueryResponse;
  184. expect(Number(sar.slotNumber)).not.toEqual(0);
  185. expect(Number(sar.blockTime)).not.toEqual(0);
  186. expect(sar.results.length).toEqual(2);
  187. expect(Number(sar.results[0].lamports)).toEqual(1461600);
  188. expect(Number(sar.results[0].rentEpoch)).toEqual(0);
  189. expect(sar.results[0].executable).toEqual(false);
  190. expect(base58.encode(Buffer.from(sar.results[0].owner))).toEqual(
  191. "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
  192. );
  193. expect(Buffer.from(sar.results[0].data).toString("hex")).toEqual(
  194. "01000000574108aed69daf7e625a361864b1f74d13702f2ca56de9660e566d1d8691848d0000e8890423c78a0901000000000000000000000000000000000000000000000000000000000000000000000000"
  195. );
  196. expect(Number(sar.results[1].lamports)).toEqual(1461600);
  197. expect(Number(sar.results[1].rentEpoch)).toEqual(0);
  198. expect(sar.results[1].executable).toEqual(false);
  199. expect(base58.encode(Buffer.from(sar.results[1].owner))).toEqual(
  200. "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
  201. );
  202. expect(Buffer.from(sar.results[1].data).toString("hex")).toEqual(
  203. "01000000574108aed69daf7e625a361864b1f74d13702f2ca56de9660e566d1d8691848d01000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000"
  204. );
  205. });
  206. test("sol_account query with future min context slot", async () => {
  207. const currSlot = await getSolanaSlot("finalized");
  208. const minContextSlot = BigInt(currSlot) + BigInt(10);
  209. const solAccountReq = new SolanaAccountQueryRequest(
  210. "finalized",
  211. ACCOUNTS,
  212. minContextSlot
  213. );
  214. const nonce = 42;
  215. const query = new PerChainQueryRequest(1, solAccountReq);
  216. const request = new QueryRequest(nonce, [query]);
  217. const serialized = request.serialize();
  218. const digest = QueryRequest.digest(ENV, serialized);
  219. const signature = sign(PRIVATE_KEY, digest);
  220. const response = await axios.put(
  221. QUERY_URL,
  222. {
  223. signature,
  224. bytes: Buffer.from(serialized).toString("hex"),
  225. },
  226. { headers: { "X-API-Key": "my_secret_key" } }
  227. );
  228. expect(response.status).toBe(200);
  229. const queryResponse = QueryResponse.from(response.data.bytes);
  230. expect(queryResponse.version).toEqual(1);
  231. expect(queryResponse.requestChainId).toEqual(0);
  232. expect(queryResponse.request.version).toEqual(1);
  233. expect(queryResponse.request.requests.length).toEqual(1);
  234. expect(queryResponse.request.requests[0].chainId).toEqual(1);
  235. expect(queryResponse.request.requests[0].query.type()).toEqual(
  236. ChainQueryType.SolanaAccount
  237. );
  238. const sar = queryResponse.responses[0]
  239. .response as SolanaAccountQueryResponse;
  240. expect(sar.slotNumber).toEqual(minContextSlot);
  241. expect(Number(sar.blockTime)).not.toEqual(0);
  242. expect(sar.results.length).toEqual(2);
  243. expect(Number(sar.results[0].lamports)).toEqual(1461600);
  244. expect(Number(sar.results[0].rentEpoch)).toEqual(0);
  245. expect(sar.results[0].executable).toEqual(false);
  246. expect(base58.encode(Buffer.from(sar.results[0].owner))).toEqual(
  247. "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
  248. );
  249. expect(Buffer.from(sar.results[0].data).toString("hex")).toEqual(
  250. "01000000574108aed69daf7e625a361864b1f74d13702f2ca56de9660e566d1d8691848d0000e8890423c78a0901000000000000000000000000000000000000000000000000000000000000000000000000"
  251. );
  252. expect(Number(sar.results[1].lamports)).toEqual(1461600);
  253. expect(Number(sar.results[1].rentEpoch)).toEqual(0);
  254. expect(sar.results[1].executable).toEqual(false);
  255. expect(base58.encode(Buffer.from(sar.results[1].owner))).toEqual(
  256. "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
  257. );
  258. expect(Buffer.from(sar.results[1].data).toString("hex")).toEqual(
  259. "01000000574108aed69daf7e625a361864b1f74d13702f2ca56de9660e566d1d8691848d01000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000"
  260. );
  261. });
  262. test("serialize and deserialize sol_pda request with defaults", () => {
  263. const solPdaReq = new SolanaPdaQueryRequest(
  264. "finalized",
  265. PDAS,
  266. BigInt(123456),
  267. BigInt(12),
  268. BigInt(20)
  269. );
  270. expect(Number(solPdaReq.minContextSlot)).toEqual(123456);
  271. expect(Number(solPdaReq.dataSliceOffset)).toEqual(12);
  272. expect(Number(solPdaReq.dataSliceLength)).toEqual(20);
  273. const serialized = solPdaReq.serialize();
  274. expect(Buffer.from(serialized).toString("hex")).toEqual(
  275. "0000000966696e616c697a6564000000000001e240000000000000000c00000000000000140102c806312cbe5b79ef8aa6c17e3f423d8fdfe1d46909fb1f6cdf65ee8e2e6faa020000000b477561726469616e5365740000000400000000"
  276. );
  277. const solPdaReq2 = SolanaPdaQueryRequest.from(serialized);
  278. expect(solPdaReq2).toEqual(solPdaReq);
  279. });
  280. test("deserialize sol_pda response", () => {
  281. const respBytes = Buffer.from(
  282. "0100000c8418d81c00aad6283ba3eb30e141ccdd9296e013ca44e5cc713418921253004b93107ba0d858a548ce989e2bca4132e4c2f9a57a9892e3a87a8304cdb36d8f000000006b010000002b010001050000005e0000000966696e616c697a656400000000000008ff000000000000000c00000000000000140102c806312cbe5b79ef8aa6c17e3f423d8fdfe1d46909fb1f6cdf65ee8e2e6faa020000000b477561726469616e5365740000000400000000010001050000009b00000000000008ff0006115e3f6d7540e05035785e15056a8559815e71343ce31db2abf23f65b19c982b68aee7bf207b014fa9188b339cfd573a0778c5deaeeee94d4bcfb12b345bf8e417e5119dae773efd0000000000116ac000000000000000000002c806312cbe5b79ef8aa6c17e3f423d8fdfe1d46909fb1f6cdf65ee8e2e6faa0000001457cd18b7f8a4d91a2da9ab4af05d0fbece2dcd65",
  283. "hex"
  284. );
  285. const queryResponse = QueryResponse.from(respBytes);
  286. expect(queryResponse.version).toEqual(1);
  287. expect(queryResponse.requestChainId).toEqual(0);
  288. expect(queryResponse.request.version).toEqual(1);
  289. expect(queryResponse.request.requests.length).toEqual(1);
  290. expect(queryResponse.request.requests[0].chainId).toEqual(1);
  291. expect(queryResponse.request.requests[0].query.type()).toEqual(
  292. ChainQueryType.SolanaPda
  293. );
  294. const sar = queryResponse.responses[0].response as SolanaPdaQueryResponse;
  295. expect(Number(sar.slotNumber)).toEqual(2303);
  296. expect(Number(sar.blockTime)).toEqual(0x0006115e3f6d7540);
  297. expect(sar.results.length).toEqual(1);
  298. expect(Buffer.from(sar.results[0].account).toString("hex")).toEqual(
  299. "4fa9188b339cfd573a0778c5deaeeee94d4bcfb12b345bf8e417e5119dae773e"
  300. );
  301. expect(sar.results[0].bump).toEqual(253);
  302. expect(Number(sar.results[0].lamports)).not.toEqual(0);
  303. expect(Number(sar.results[0].rentEpoch)).toEqual(0);
  304. expect(sar.results[0].executable).toEqual(false);
  305. expect(Buffer.from(sar.results[0].owner).toString("hex")).toEqual(
  306. "02c806312cbe5b79ef8aa6c17e3f423d8fdfe1d46909fb1f6cdf65ee8e2e6faa"
  307. );
  308. expect(Buffer.from(sar.results[0].data).toString("hex")).toEqual(
  309. "57cd18b7f8a4d91a2da9ab4af05d0fbece2dcd65"
  310. );
  311. });
  312. test("successful sol_pda query", async () => {
  313. const solPdaReq = new SolanaPdaQueryRequest(
  314. "finalized",
  315. PDAS,
  316. BigInt(0),
  317. BigInt(12),
  318. BigInt(16) // After this, things can change.
  319. );
  320. const nonce = 43;
  321. const query = new PerChainQueryRequest(1, solPdaReq);
  322. const request = new QueryRequest(nonce, [query]);
  323. const serialized = request.serialize();
  324. const digest = QueryRequest.digest(ENV, serialized);
  325. const signature = sign(PRIVATE_KEY, digest);
  326. const response = await axios.put(
  327. QUERY_URL,
  328. {
  329. signature,
  330. bytes: Buffer.from(serialized).toString("hex"),
  331. },
  332. { headers: { "X-API-Key": "my_secret_key" } }
  333. );
  334. expect(response.status).toBe(200);
  335. const queryResponse = QueryResponse.from(response.data.bytes);
  336. expect(queryResponse.version).toEqual(1);
  337. expect(queryResponse.requestChainId).toEqual(0);
  338. expect(queryResponse.request.version).toEqual(1);
  339. expect(queryResponse.request.requests.length).toEqual(1);
  340. expect(queryResponse.request.requests[0].chainId).toEqual(1);
  341. expect(queryResponse.request.requests[0].query.type()).toEqual(
  342. ChainQueryType.SolanaPda
  343. );
  344. const sar = queryResponse.responses[0].response as SolanaPdaQueryResponse;
  345. expect(Number(sar.slotNumber)).not.toEqual(0);
  346. expect(Number(sar.blockTime)).not.toEqual(0);
  347. expect(sar.results.length).toEqual(1);
  348. expect(Buffer.from(sar.results[0].account).toString("hex")).toEqual(
  349. "4fa9188b339cfd573a0778c5deaeeee94d4bcfb12b345bf8e417e5119dae773e"
  350. );
  351. expect(sar.results[0].bump).toEqual(253);
  352. expect(Number(sar.results[0].lamports)).not.toEqual(0);
  353. expect(Number(sar.results[0].rentEpoch)).toEqual(0);
  354. expect(sar.results[0].executable).toEqual(false);
  355. expect(Buffer.from(sar.results[0].owner).toString("hex")).toEqual(
  356. "02c806312cbe5b79ef8aa6c17e3f423d8fdfe1d46909fb1f6cdf65ee8e2e6faa"
  357. );
  358. expect(Buffer.from(sar.results[0].data).toString("hex")).toEqual(
  359. "57cd18b7f8a4d91a2da9ab4af05d0fbe"
  360. );
  361. });
  362. test("successful sol_pda query with future min context slot", async () => {
  363. const currSlot = await getSolanaSlot("finalized");
  364. const minContextSlot = BigInt(currSlot) + BigInt(10);
  365. const solPdaReq = new SolanaPdaQueryRequest(
  366. "finalized",
  367. PDAS,
  368. minContextSlot,
  369. BigInt(12),
  370. BigInt(16) // After this, things can change.
  371. );
  372. const nonce = 43;
  373. const query = new PerChainQueryRequest(1, solPdaReq);
  374. const request = new QueryRequest(nonce, [query]);
  375. const serialized = request.serialize();
  376. const digest = QueryRequest.digest(ENV, serialized);
  377. const signature = sign(PRIVATE_KEY, digest);
  378. const response = await axios.put(
  379. QUERY_URL,
  380. {
  381. signature,
  382. bytes: Buffer.from(serialized).toString("hex"),
  383. },
  384. { headers: { "X-API-Key": "my_secret_key" } }
  385. );
  386. expect(response.status).toBe(200);
  387. const queryResponse = QueryResponse.from(response.data.bytes);
  388. expect(queryResponse.version).toEqual(1);
  389. expect(queryResponse.requestChainId).toEqual(0);
  390. expect(queryResponse.request.version).toEqual(1);
  391. expect(queryResponse.request.requests.length).toEqual(1);
  392. expect(queryResponse.request.requests[0].chainId).toEqual(1);
  393. expect(queryResponse.request.requests[0].query.type()).toEqual(
  394. ChainQueryType.SolanaPda
  395. );
  396. const sar = queryResponse.responses[0].response as SolanaPdaQueryResponse;
  397. expect(sar.slotNumber).toEqual(minContextSlot);
  398. expect(Number(sar.blockTime)).not.toEqual(0);
  399. expect(sar.results.length).toEqual(1);
  400. expect(Buffer.from(sar.results[0].account).toString("hex")).toEqual(
  401. "4fa9188b339cfd573a0778c5deaeeee94d4bcfb12b345bf8e417e5119dae773e"
  402. );
  403. expect(sar.results[0].bump).toEqual(253);
  404. expect(Number(sar.results[0].lamports)).not.toEqual(0);
  405. expect(Number(sar.results[0].rentEpoch)).toEqual(0);
  406. expect(sar.results[0].executable).toEqual(false);
  407. expect(Buffer.from(sar.results[0].owner).toString("hex")).toEqual(
  408. "02c806312cbe5b79ef8aa6c17e3f423d8fdfe1d46909fb1f6cdf65ee8e2e6faa"
  409. );
  410. expect(Buffer.from(sar.results[0].data).toString("hex")).toEqual(
  411. "57cd18b7f8a4d91a2da9ab4af05d0fbe"
  412. );
  413. });
  414. test("concurrent queries", async () => {
  415. const solAccountReq = new SolanaAccountQueryRequest("finalized", ACCOUNTS);
  416. const query = new PerChainQueryRequest(1, solAccountReq);
  417. let nonce = 42;
  418. let promises: Promise<AxiosResponse<any, any>>[] = [];
  419. for (let count = 0; count < 20; count++) {
  420. nonce += 1;
  421. const request = new QueryRequest(nonce, [query]);
  422. const serialized = request.serialize();
  423. const digest = QueryRequest.digest(ENV, serialized);
  424. const signature = sign(PRIVATE_KEY, digest);
  425. const response = axios.put(
  426. QUERY_URL,
  427. {
  428. signature,
  429. bytes: Buffer.from(serialized).toString("hex"),
  430. },
  431. { headers: { "X-API-Key": "my_secret_key" } }
  432. );
  433. promises.push(response);
  434. }
  435. const responses = await Promise.all(promises);
  436. expect(responses.length).toEqual(promises.length);
  437. for (let idx = 0; idx < responses.length; idx++) {
  438. const response = responses[idx];
  439. expect(response.status).toBe(200);
  440. const queryResponse = QueryResponse.from(response.data.bytes);
  441. expect(queryResponse.version).toEqual(1);
  442. expect(queryResponse.requestChainId).toEqual(0);
  443. expect(queryResponse.request.version).toEqual(1);
  444. expect(queryResponse.request.requests.length).toEqual(1);
  445. expect(queryResponse.request.requests[0].chainId).toEqual(1);
  446. expect(queryResponse.request.requests[0].query.type()).toEqual(
  447. ChainQueryType.SolanaAccount
  448. );
  449. const sar = queryResponse.responses[0]
  450. .response as SolanaAccountQueryResponse;
  451. expect(Number(sar.slotNumber)).not.toEqual(0);
  452. expect(Number(sar.blockTime)).not.toEqual(0);
  453. expect(sar.results.length).toEqual(2);
  454. expect(Number(sar.results[0].lamports)).toEqual(1461600);
  455. expect(Number(sar.results[0].rentEpoch)).toEqual(0);
  456. expect(sar.results[0].executable).toEqual(false);
  457. expect(base58.encode(Buffer.from(sar.results[0].owner))).toEqual(
  458. "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
  459. );
  460. expect(Buffer.from(sar.results[0].data).toString("hex")).toEqual(
  461. "01000000574108aed69daf7e625a361864b1f74d13702f2ca56de9660e566d1d8691848d0000e8890423c78a0901000000000000000000000000000000000000000000000000000000000000000000000000"
  462. );
  463. expect(Number(sar.results[1].lamports)).toEqual(1461600);
  464. expect(Number(sar.results[1].rentEpoch)).toEqual(0);
  465. expect(sar.results[1].executable).toEqual(false);
  466. expect(base58.encode(Buffer.from(sar.results[1].owner))).toEqual(
  467. "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
  468. );
  469. expect(Buffer.from(sar.results[1].data).toString("hex")).toEqual(
  470. "01000000574108aed69daf7e625a361864b1f74d13702f2ca56de9660e566d1d8691848d01000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000"
  471. );
  472. }
  473. });
  474. });