diff --git a/.gitignore b/.gitignore index 986a686..ed57c18 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ scripts/mainnet.pairs-catchups.sh scripts/testnet.pairs-catchups.sh .dev.* +.temp* diff --git a/README.md b/README.md index 39587d1..a3d9af6 100644 --- a/README.md +++ b/README.md @@ -175,6 +175,15 @@ For local development tables in `.dev.tables` run yarn test:dev ``` +## Get Tables in the `.temp` folder +You can get all the tables, in order to inspect them. +``` +yarn get:tables mainnet +``` + +``` +yarn get:tables testnet +``` ## Fast Way 1.- Deploy ALL Zephyr Programs in both Mainnet and Testnet at once diff --git a/package.json b/package.json index 46d85a4..b763caa 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "scripts": { "build": "tsc", "pairs:catchups:generate": "yarn build && ENVIRONMENT=prod node --trace-deprecation dist/pairs-catchups-generator.js", + "get:tables": "yarn build && ENVIRONMENT=prod node --trace-deprecation dist/get-tables.js", "pairs:catchups:generate:dev": "yarn build && ENVIRONMENT=dev node --trace-deprecation dist/pairs-catchups-generator.js", "test:dev": "ENVIRONMENT=dev jest", "test": "ENVIRONMENT=prod jest" diff --git a/scripts/__tests__/events.test.ts b/scripts/__tests__/events.test.ts index dc4fc55..ae7f104 100644 --- a/scripts/__tests__/events.test.ts +++ b/scripts/__tests__/events.test.ts @@ -3,6 +3,8 @@ import { zephyrTableToGraphQLParser} from "mercury-sdk"; import { getSoroswapEvents } from "../utils/get-soroswap-events"; import { getZephyrTable } from "../utils/get-table"; +jest.setTimeout(30000); // Set timeout to 30 seconds + test("soroswap events in MAINNET return non empty array", async () => { let soroswapEventsTable = getZephyrTable('soroswap_events', "MAINNET") const zephyrTableGraphQL = zephyrTableToGraphQLParser(soroswapEventsTable); @@ -11,6 +13,29 @@ test("soroswap events in MAINNET return non empty array", async () => { expect(events.length).toBeGreaterThan(0); }); +test("soroswap events in MAINNET return no duplicate events", async () => { + let soroswapEventsTable = getZephyrTable("soroswap_events", "MAINNET"); + const zephyrTableGraphQL = zephyrTableToGraphQLParser(soroswapEventsTable); + const events = await getSoroswapEvents(zephyrTableGraphQL.address, "MAINNET"); + + + // Check for duplicates + const seen = new Map(); + const duplicates = []; + + events.forEach((event) => { + const eventKey = JSON.stringify(event); // Serialize the event to a unique key + if (seen.has(eventKey)) { + duplicates.push(event); + } else { + seen.set(eventKey, true); + } + }); + + // Expect no duplicates + expect(duplicates.length).toBe(0); +}); + test("soroswap events in TESTNET return non empty array", async () => { let soroswapEventsTable = getZephyrTable('soroswap_events', "TESTNET") diff --git a/scripts/__tests__/pairs.test.ts b/scripts/__tests__/pairs.test.ts index 5083627..36e7fc2 100644 --- a/scripts/__tests__/pairs.test.ts +++ b/scripts/__tests__/pairs.test.ts @@ -5,6 +5,7 @@ import { getTotalPairs } from "../utils/get-total-pairs"; import { getZephyrTable } from "../utils/get-table"; import fs from "fs"; +jest.setTimeout(30000); // Set timeout to 30 seconds test("soroswap pairs in MAINNET return non empty array", async () => { let soroswapPairsTable = getZephyrTable('soroswap_pairs', "MAINNET") diff --git a/scripts/__tests__/rsv.test.ts b/scripts/__tests__/rsv.test.ts index bdb30b6..3f35f9d 100644 --- a/scripts/__tests__/rsv.test.ts +++ b/scripts/__tests__/rsv.test.ts @@ -5,6 +5,7 @@ import { getZephyrTable } from "../utils/get-table"; import { getReservesFromPair } from "../utils/get-reserves-from-pair"; import fs from "fs"; +jest.setTimeout(30000); // Set timeout to 30 seconds test("soroswap rsv_ch in MAINNET return non empty array", async () => { let soroswapEventsTable = getZephyrTable('soroswap_rsv_ch', "MAINNET") @@ -13,7 +14,7 @@ test("soroswap rsv_ch in MAINNET return non empty array", async () => { expect(rsv_ch).toBeDefined(); expect(rsv_ch.length).toBeGreaterThan(0); console.log("🚀 ~ test ~ Soroswap mainnet rsv_ch.length:", rsv_ch.length) -}); +}, 30000); // Set timeout to 30 seconds for this test test("soroswap rsv_ch in TESTNET return non empty array", async () => { @@ -24,7 +25,7 @@ test("soroswap rsv_ch in TESTNET return non empty array", async () => { expect(rsv_ch.length).toBeGreaterThan(0); console.log("🚀 ~ test ~ Soroswap testnet rsv_ch.length:", rsv_ch.length) -}); +}, 30000); // Set timeout to 30 seconds for this test test("Last Soroswap rsv_ch in MAINNET reflects current reserve on that pair", async () => { let soroswapEventsTable = getZephyrTable('soroswap_rsv_ch', "MAINNET") @@ -49,7 +50,7 @@ test("Last Soroswap rsv_ch in MAINNET reflects current reserve on that pair", a expect(onChainReserveA.toString()).toBe(last_rsv_ch.reserveA); expect(onChainReserveB.toString()).toBe(last_rsv_ch.reserveB); -}); +}, 30000); // Set timeout to 30 seconds for this test @@ -72,4 +73,4 @@ test("Last Soroswap rsv_ch in TESTNET reflects current reserve on that pair", a expect(onChainReserveA.toString()).toBe(last_rsv_ch.reserveA); expect(onChainReserveB.toString()).toBe(last_rsv_ch.reserveB); -}); +}, 30000); // Set timeout to 30 seconds for this test diff --git a/scripts/__tests__/tables.test.ts b/scripts/__tests__/tables.test.ts index 568c5fb..3a07958 100644 --- a/scripts/__tests__/tables.test.ts +++ b/scripts/__tests__/tables.test.ts @@ -1,6 +1,8 @@ import { getZephyrTable } from "../utils/get-table"; +jest.setTimeout(30000); // Set timeout to 30 seconds + test('soroswap zephyr tables should exist in MAINNET with correct format', () => { let soroswapTablesNames=["soroswap_pairs", "soroswap_events", "soroswap_rsv_ch"]; for (let tableName of soroswapTablesNames) { diff --git a/scripts/get-tables.ts b/scripts/get-tables.ts new file mode 100644 index 0000000..9e29658 --- /dev/null +++ b/scripts/get-tables.ts @@ -0,0 +1,67 @@ +import fs from "fs"; +import path from "path"; // For handling paths +import { zephyrTableToGraphQLParser, ZephyrTableOriginal } from "mercury-sdk"; +import { getPairs } from "./utils/get-pairs.js"; +import { getSoroswapEvents } from "./utils/get-soroswap-events"; +import { getZephyrTable } from "./utils/get-table.js"; + + + +(async () => { + const network = process.argv[2] === "mainnet" ? "MAINNET" : "TESTNET"; + console.log("🚀 ~ network:", network); + + console.log("Getting the Pairs Table:"); + + let soroswapPairsTable = getZephyrTable('soroswap_pairs', network) + let zephyrTableGraphQL = zephyrTableToGraphQLParser(soroswapPairsTable); + const pairs = await getPairs(zephyrTableGraphQL.address, network); + + console.log("🚀 ~ pairs:", pairs); + + let pairsTablePath; + if (network === "MAINNET") { + pairsTablePath = "/workspace/.temp/mainnet.pairs.json"; + } else { + pairsTablePath = "/workspace/.temp/testnet.pairs.json"; + } + + // Ensure the folder exists + const folderPath = path.dirname(pairsTablePath); + if (!fs.existsSync(folderPath)) { + fs.mkdirSync(folderPath, { recursive: true }); // Create the folder if it doesn't exist + } + + // write json into file + + fs.writeFileSync(pairsTablePath, JSON.stringify(pairs, (key, value) => + typeof value === "bigint" ? value.toString() : value, 2)); + + + + console.log("Getting the Soroswap Events Table:"); + + let soroswapEventsTable = getZephyrTable('soroswap_events', network); + zephyrTableGraphQL = zephyrTableToGraphQLParser(soroswapEventsTable); + const events = await getSoroswapEvents(zephyrTableGraphQL.address, network); + + console.log("🚀 ~ events:", events); + + let eventsTablePath; + if (network === "MAINNET") { + eventsTablePath = "/workspace/.temp/mainnet.events.json"; + } else { + eventsTablePath = "/workspace/.temp/testnet.events.json"; + } + + + // write json into file + + fs.writeFileSync(eventsTablePath, JSON.stringify(events, (key, value) => + typeof value === "bigint" ? value.toString() : value, 2)); + + + + + +})(); diff --git a/scripts/utils/get-soroswap-events.ts b/scripts/utils/get-soroswap-events.ts index 8783aba..c11a86c 100644 --- a/scripts/utils/get-soroswap-events.ts +++ b/scripts/utils/get-soroswap-events.ts @@ -9,6 +9,7 @@ export interface SoroswapEvent { amountB: string; account: string; timestamp: string; + txHash: string; } export const parseScvalValue = (value: any) => { const scval = StellarSdk.xdr.ScVal.fromXDR(value, "base64"); @@ -21,9 +22,12 @@ export const parseMercuryScvalResponse = (data: any) => { for (let key in d) { const value = parseScvalValue(d[key]); - if (typeof value === "bigint" || typeof value === "number") { n[key] = value.toString(); + } else if( key == 'txHash'){ + const txHash = StellarSdk.xdr.Hash.fromXDR(value, 'hex').toString('hex') + if(txHash.length != 64)throw new Error('Invalid txHash length'); + n[key] = txHash; } else { n[key] = value; } @@ -33,7 +37,6 @@ export const parseMercuryScvalResponse = (data: any) => { }); }; - export const getSoroswapEvents = async (tableName: string, network: "MAINNET" | "TESTNET") => { const mercuryInstance = getMercuryInstance(network); @@ -48,6 +51,7 @@ export const getSoroswapEvents = async (tableName: string, network: "MAINNET" | amountB account timestamp + txHash } } }`,