diff --git a/.github/workflows/sns_process.yml b/.github/workflows/sns_process.yml new file mode 100644 index 0000000..a8cdd75 --- /dev/null +++ b/.github/workflows/sns_process.yml @@ -0,0 +1,48 @@ +name: Build sns-process-image + +on: + push: + branches: + - main + +jobs: + build-image: + runs-on: ubuntu-latest + env: + REGISTRY: ghcr.io + IMAGE_NAME: web3bio/sns-process + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Log in to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Setup Docker BuildX + uses: docker/setup-buildx-action@v2 + - name: Cache Docker layers + uses: actions/cache@v3 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-docker-build-${{ hashFiles('**/requirements.txt') }} + - name: Extract metadata + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + - name: Build and push + uses: docker/build-push-action@v3 + with: + context: "./sns_process" + file: "./sns_process/Dockerfile" + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max + - name: Clean up post-build cache + run: | + rm -rf /tmp/.buildx-cache + mv /tmp/.buildx-cache-new /tmp/.buildx-cache diff --git a/.gitignore b/.gitignore index f2e1e98..b68e038 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ data .env .history src/config/*.toml -!src/config/main.sample.toml \ No newline at end of file +!src/config/main.sample.toml +sns_process/node_modules/ \ No newline at end of file diff --git a/sns_process/.dockerignore b/sns_process/.dockerignore new file mode 100644 index 0000000..0457296 --- /dev/null +++ b/sns_process/.dockerignore @@ -0,0 +1,5 @@ +/.dockerignore +/Dockerfile +/node_modules +/package-lock.json +/.env \ No newline at end of file diff --git a/sns_process/Dockerfile b/sns_process/Dockerfile new file mode 100644 index 0000000..673a8e9 --- /dev/null +++ b/sns_process/Dockerfile @@ -0,0 +1,20 @@ +# hhttps://hub.docker.com/_/node +FROM node:22 + +LABEL maintainer="Zella Zhong " + +RUN apt-get update -y && \ + apt-get upgrade -y --force-yes && \ + apt-get install -y --force-yes supervisor + +WORKDIR /node_app + +COPY package*.json ./ + +RUN npm install -g npm@10 + +RUN npm install --only=production + +COPY . . + +ENTRYPOINT ["./run.sh"] \ No newline at end of file diff --git a/sns_process/docker-compose.yml b/sns_process/docker-compose.yml new file mode 100644 index 0000000..5e9c0d9 --- /dev/null +++ b/sns_process/docker-compose.yml @@ -0,0 +1,8 @@ +services: + server: + image: ghcr.io/web3bio/data_process:main + container_name: data_process + volumes: + - ~/sns_process:/node_app/data + - ~/sns_process/.env:/node_app/.env + - ~/sns_process/log:/tmp \ No newline at end of file diff --git a/sns_process/index.js b/sns_process/index.js new file mode 100644 index 0000000..c288aad --- /dev/null +++ b/sns_process/index.js @@ -0,0 +1,344 @@ +import { Connection, clusterApiUrl, PublicKey } from '@solana/web3.js'; +import { getAllDomains, + getDomainKeysWithReverses, + getAllRegisteredDomains, + NameRegistryState, + getRecordV2Key, + Record, + getRecords, + getDomainKeySync, + getMultiplePrimaryDomains + } from '@bonfida/spl-name-service'; +import pgp from 'pg-promise'; +import dotenv from 'dotenv'; +import fs from 'fs'; +import readline from 'readline'; +import Bottleneck from 'bottleneck'; +import { N } from 'ethers'; + +// Load environment variables from the .env file +dotenv.config(); + + +const pg = pgp(); + +// PostgreSQL connection using DSN +const db = pg({ + connectionString: process.env.PG_DSN, + ssl: { + rejectUnauthorized: false, // Accept self-signed certificates + }, +}); + +const SOLANA_MAIN_CLIENT = new Connection(process.env.QUICKNODE_RPC); + +// Set up bottleneck limiter to control request rate (2 requests per second, 30 requests per minute) +const limiter = new Bottleneck({ + minTime: 3000, // 1 request every 3 seconds + maxConcurrent: 1, // Only allow 1 concurrent request at a time + reservoir: 30, // Limit to 30 requests per minute + reservoirRefreshAmount: 30, // Refill 30 tokens + reservoirRefreshInterval: 60 * 1000 // Refresh every minute (60000 ms) +}); + +const SOL_TLD = new PublicKey("58PwtjSDuFHuUkYjH9BYnnQKHfwo9reZhC2zMJv9JPkx"); // .sol TLD +const NAME_PROGRAM_ID = new PublicKey("namesLPneVptA9Z5rqUDD9tMTWEJwofgaYwp8cawRkX"); + + +// fetchAllDomains +// dumps all the domains namenode +// Fetch all registered .sol domains +const fetchAllDomains = async () => { + try { + console.log("Fetching all registered .sol domains..."); + const connection = new Connection(clusterApiUrl('mainnet-beta'), 'confirmed'); + const registeredDomains = await getAllRegisteredDomains(connection); + console.log("Total domains fetched:", registeredDomains.length); + const domainsList = registeredDomains.map(domain => domain.pubkey); + const filePath = "./data/domains.csv"; + await fs.promises.writeFile(filePath, domainsList.join("\n")); + console.log(`Domains successfully saved to ${filePath}`); + } catch (error) { + console.error("Error fetching domains:", error); + } +}; + +async function fetchDomainsAndUpsert() { + try { + console.log("Connected to PostgreSQL"); + + const batchSize = 1000; + let allCount = 0; + let batchCount = 0; + let lastId = 0; + let hasMoreRows = true; + + while (hasMoreRows) { + // Fetch 1000 rows from the database where owner is NULL and sorted by id + const query = ` + SELECT id, namenode + FROM sns_profile + WHERE owner IS NULL + AND id > $1 + ORDER BY id ASC + LIMIT $2`; + + const batch = await db.any(query, [lastId, batchSize]); + + if (batch.length > 0) { + for (const row of batch) { + // Call getDomainInfo and fetch domain details + const domainInfo = await retryGetDomainInfo(row.namenode); + if (domainInfo) { + allCount++; + // Prepare the SQL upsert query with the fetched domain details + const insertQuery = ` + INSERT INTO sns_profile (namenode, nft_owner, is_tokenized, parent_node, expire_time, owner, resolver, resolved_address, contenthash) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (namenode) DO UPDATE + SET nft_owner = EXCLUDED.nft_owner, + is_tokenized = EXCLUDED.is_tokenized, + parent_node = EXCLUDED.parent_node, + expire_time = EXCLUDED.expire_time, + owner = EXCLUDED.owner, + resolver = EXCLUDED.resolver, + resolved_address = EXCLUDED.resolved_address, + contenthash = EXCLUDED.contenthash;`; + + // Perform the upsert operation + await db.none(insertQuery, [ + domainInfo.namenode, + domainInfo.nft_owner, + domainInfo.is_tokenized, + domainInfo.parent_node, + domainInfo.expire_time, + domainInfo.owner, + domainInfo.resolver, + domainInfo.resolved_address, + domainInfo.contenthash + ]); + + console.log(`${allCount} upserted.`); + console.log(`Upserted domain: ${domainInfo.namenode}`); + } else { + console.log(`Failed to fetch domain info for ${row.namenode}. Skipping.`); + } + } + + // Update the last processed ID + lastId = batch[batch.length - 1].id; + + batchCount++; + console.log(`Batch ${batchCount} upserted.`); + } + + // Check if we fetched less than batchSize, which means no more rows left + if (batch.length < batchSize) { + hasMoreRows = false; + } + } + + console.log(`All batches completed. Batch count: ${batchCount}`); + } catch (error) { + console.error('Error:', error); + } finally { + console.log("Disconnected from PostgreSQL"); + } +} + +async function processAndUpsertBatchForloop(batch) { + try { + for (const domain_pubkey of batch) { + // Call getDomainInfo and fetch domain details + const domainInfo = await getDomainInfo(domain_pubkey); + + // Prepare the SQL upsert query with the fetched domain details + const insertQuery = ` + INSERT INTO sns_profile (namenode, nft_owner, is_tokenized, parent_node, expire_time, owner, resolver, resolved_address, contenthash) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (namenode) DO UPDATE + SET nft_owner = EXCLUDED.nft_owner, + is_tokenized = EXCLUDED.is_tokenized, + parent_node = EXCLUDED.parent_node, + expire_time = EXCLUDED.expire_time, + owner = EXCLUDED.owner, + resolver = EXCLUDED.resolver, + resolved_address = EXCLUDED.resolved_address, + contenthash = EXCLUDED.contenthash;`; + + // Perform the upsert operation + await db.none(insertQuery, [ + domainInfo.namenode, + domainInfo.nft_owner, + domainInfo.is_tokenized, + domainInfo.parent_node, + domainInfo.expire_time, + domainInfo.owner, + domainInfo.resolver, + domainInfo.resolved_address, + domainInfo.contenthash + ]); + + console.log(`Upserted domain: ${domainInfo.namenode}`); + } + console.log('Batch processed successfully.'); + } catch (error) { + console.error('Error in processAndUpsertBatch:', error); + } +} + +async function readDomainsAndUpsert() { + try { + console.log("Connected to PostgreSQL"); + + const filePath = './data/domains.csv'; + const fileStream = fs.createReadStream(filePath); + + const rl = readline.createInterface({ + input: fileStream, + crlfDelay: Infinity // Recognize CR LF sequences + }); + + const batchSize = 1000; + let batch = []; + let batchCount = 0; + + for await (const line of rl) { + if (line.trim() !== '') { + batch.push(line.trim()); + if (batch.length === batchSize) { + await processAndUpsertBatchForloop(batch); + batchCount++; + console.log(`Batch ${batchCount} upserted.`); + batch = []; + } + } + } + + // remaining lines + if (batch.length > 0) { + await processAndUpsertBatchForloop(batch); + batchCount++; + console.log(`Batch ${batchCount} upserted.`); + } + + console.log(`All batches completed. Batch count: ${batchCount}`); + } catch (error) { + console.error('Error:', error); + } finally { + console.log("Disconnected from PostgreSQL"); + } +} + +// Function to upsert a batch of domains using pg-promise +async function upsertBatch_Old(batch) { + const insertQuery = ` + INSERT INTO sns_profile (namenode) + VALUES ${batch.map((_, index) => `($${index + 1})`).join(', ')} + ON CONFLICT (namenode) DO UPDATE + SET namenode = EXCLUDED.namenode;`; + + await db.none(insertQuery, batch); +} + +async function processAndUpsertBatchConcurrent(batch) { + const processedBatch = await Promise.all(batch.map(async (domain_pubkey) => { + const domainInfo = await getDomainInfo(domain_pubkey); + if (domainInfo) { + return [ + domainInfo.namenode, + domainInfo.nft_owner, + domainInfo.is_tokenized, + domainInfo.parent_node, + domainInfo.expire_time, + domainInfo.owner, + domainInfo.resolver, + domainInfo.resolved_address, + domainInfo.contenthash + ]; + } else { + return null; + } + })); + + const validBatch = processedBatch.filter(Boolean); // Filter out null entries + + if (validBatch.length > 0) { + await upsertBatch(validBatch); + } +} + +async function upsertBatch(batch) { + const insertQuery = ` + INSERT INTO sns_profile + (namenode, nft_owner, is_tokenized, parent_node, expire_time, owner, resolver, resolved_address, contenthash) + VALUES ${batch.map((_, index) => `($${index * 8 + 1}, $${index * 8 + 2}, $${index * 8 + 3}, $${index * 8 + 4}, $${index * 8 + 5}, $${index * 8 + 6}, $${index * 8 + 7}, $${index * 8 + 8}, $${index * 8 + 9})`).join(', ')} + ON CONFLICT (namenode) DO UPDATE + SET nft_owner = EXCLUDED.nft_owner, + is_tokenized = EXCLUDED.is_tokenized, + parent_node = EXCLUDED.parent_node, + expire_time = EXCLUDED.expire_time, + owner = EXCLUDED.owner, + resolver = EXCLUDED.resolver, + resolved_address = EXCLUDED.resolved_address, + contenthash = EXCLUDED.contenthash; + `; + + const flattenedValues = batch.flat(); // Flatten batch array for parameterized query + await db.none(insertQuery, flattenedValues); +} + +async function retryGetDomainInfo(domain_pubkey, retries = 3) { + for (let attempt = 0; attempt < retries; attempt++) { + try { + return await getDomainInfo(domain_pubkey); // Call the getDomainInfo function here + } catch (error) { + console.error(`Attempt ${attempt + 1} failed for ${domain_pubkey}:`, error); + if (attempt === retries - 1) { + return null; // Return null after all attempts + } + // Optionally add a small delay before retrying + await new Promise(resolve => setTimeout(resolve, 3000)); // 1 second delay + } + } +} + + +const getDomainInfo = limiter.wrap(async (domain_pubkey) => { + try { + const pubkey = new PublicKey(domain_pubkey); + const { registry, nftOwner } = await NameRegistryState.retrieve(SOLANA_MAIN_CLIENT, pubkey); + let contenthash = registry.data.toString('utf-8').trim(); + contenthash = contenthash.replace(/\x00+$/, ''); + if (contenthash === '' || /^[\x00]+$/.test(contenthash)) { + contenthash = null; + } + return { + namenode: pubkey.toBase58(), + nft_owner: nftOwner ? nftOwner.toBase58() : null, + is_tokenized: !!nftOwner, + parent_node: registry.parentName.toBase58(), + expire_time: "2116-09-24 09:30:00", + owner: registry.owner.toBase58(), + resolver: NAME_PROGRAM_ID.toBase58(), + resolved_address: registry.owner.toBase58(), + contenthash: contenthash, + }; + } catch (error) { + console.error(`Error fetching domain info for ${domain_pubkey}:`, error); + return null; + } +}); + + +const run = async () => { + // await fetchAllDomains(); + // await readDomainsAndUpsert(); + await fetchDomainsAndUpsert(); +}; + +// Execute the run function +run().catch(console.error); + +// const result = await getDomainInfo("7yEEEjdSgeGfEGFb7ykEpErZ67ymvMDeofUVcCfKypxF") +// console.log(result.contenthash.length); \ No newline at end of file diff --git a/sns_process/index_1.js b/sns_process/index_1.js new file mode 100644 index 0000000..1de69fe --- /dev/null +++ b/sns_process/index_1.js @@ -0,0 +1,157 @@ +// import pkg from "@solana/web3.js"; +// const { Connection, clusterApiUrl, PublicKey } = pkg; + +// // Log the PublicKey input to verify it is correct +// const SOL_TLD = new PublicKey("58PwtjSDuFHuUkYjH9BYnnQKHfwo9reZhC2zMJv9JPkx"); // .sol TLD +// console.log(`Root Domain PublicKey: ${SOL_TLD}`); +// const NAME_PROGRAM_ID = new PublicKey("namesLPneVptA9Z5rqUDD9tMTWEJwofgaYwp8cawRkX"); + + +// // Add a delay to avoid overloading the call stack +// const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); + +// // Function to get slices of registered domains +// const getAllDomainSlices = async (connection, offset, length) => { +// const filters = [ +// { +// memcmp: { +// offset: 0, +// bytes: SOL_TLD.toBase58(), +// }, +// }, +// ]; + +// const dataSlice = { offset, length }; + +// const accounts = await connection.getProgramAccounts(NAME_PROGRAM_ID, { +// dataSlice, +// filters, +// }); + +// return accounts; +// }; + +// // Fetch all domains by slicing data in chunks with proper flow control +// const fetchAllDomains = async () => { +// const connection = new Connection(clusterApiUrl("mainnet-beta")); +// const sliceSize = 1; // Size of each slice +// const maxDataLength = 32; // Estimated max length of domain data +// const delayBetweenRequests = 100; // Delay in milliseconds to avoid overload + +// let allDomains = []; + +// try { +// for (let i = 0; i < maxDataLength; i += sliceSize) { +// console.log(`Fetching slice from offset: ${i} to ${i + sliceSize}`); + +// const domainSlice = await getAllDomainSlices(connection, i, sliceSize); + +// // If no more data, stop fetching +// if (domainSlice.length === 0) { +// console.log("No more domains to fetch, stopping."); +// break; +// } + +// allDomains.push(...domainSlice); + +// // Add delay to prevent overwhelming the system +// await delay(delayBetweenRequests); +// } + +// console.log("Total domains fetched:", allDomains.length); +// console.log("Domains:", allDomains); +// } catch (error) { +// console.error("Error fetching domains:", error); +// } +// }; + +// // Run the fetch function +// fetchAllDomains(); + +import { Connection, clusterApiUrl, PublicKey} from '@solana/web3.js'; +import { getAllRegisteredDomains } from '@bonfida/spl-name-service'; + + +// Given uint8 array +const uint8Array = [ + 0, + 6, + 3, + 37, + 156, + 186, + 47, + 178, + 159, + 88, + 193, + 124, + 39, + 135, + 173, + 49, + 227, + 251, + 240, + 125, + 235, + 84, + 233, + 214, + 199, + 28, + 27, + 116, + 220, + 40, + 157, + 36 +]; + +// Convert to string using TextDecoder +const decoder = new TextDecoder('utf-8'); // Specify the encoding if needed +const byteArray = new Uint8Array(uint8Array); // Create a Uint8Array +const decodedString = decoder.decode(byteArray); // Decode the byte array + +console.log(decodedString); + +const fetchAllDomains = async () => { + const connection = new Connection(clusterApiUrl("mainnet-beta")); // Solana mainnet connection + + try { + console.log("Fetching all registered .sol domains..."); + + // Fetch all registered .sol domains using Bonfida's spl-name-service + const registeredDomains = await getAllRegisteredDomains(connection); + + // Log the number of domains fetched + console.log("Total domains fetched:", registeredDomains.length); + + // Prepare to save base58 addresses and corresponding names to domains.txt + const domainsList = registeredDomains.map(domain => { + const pubkey = domain.pubkey; // The base58 address + const dataBuffer = domain.account.data; // The data buffer + + // Convert the data buffer to a string (you can customize this conversion) + const name = bufferToString(dataBuffer); + + return `${pubkey}, ${name}`; + }); + + // Save to domains.txt + const filePath = "./data/domains.csv"; + await fs.writeFile(filePath, domainsList.join("\n")); + console.log(`Domains successfully saved to ${filePath}`); + + } catch (error) { + console.error("Error fetching domains:", error); + } + }; + + // Example function to convert a Buffer to a name string + const bufferToString = (dataBuffer) => { + return dataBuffer.toString('utf-8').replace(/\0/g, ''); // Convert to string and remove null characters + }; + + // Run the fetch function + fetchAllDomains(); \ No newline at end of file diff --git a/sns_process/index_2.js b/sns_process/index_2.js new file mode 100644 index 0000000..378c8b8 --- /dev/null +++ b/sns_process/index_2.js @@ -0,0 +1,68 @@ +import { Connection, clusterApiUrl, PublicKey} from '@solana/web3.js'; +import { getDomainKeySync, getIpfsRecord, getTwitterRecord, getRecords, getRecordV2Key, Record, NameRegistryState } from '@bonfida/spl-name-service'; + +// // Define your domain and subdomain here +// const domainName = 'bonfida'; // Without the .sol at the end +// const subDomain = 'dex.bonfida'; // Without the .sol at the end +// const record = 'IPFS.bonfida'; // Without the .sol at the end + +const domainName = 'yoyodyne'; // Without the .sol at the end +const subDomain = 'dex.bonfida'; // Without the .sol at the end +// const record = 'IPFS.bonfida'; // Without the .sol at the end +const record = Record.Twitter + '.' + domainName + +const connection = new Connection(clusterApiUrl('mainnet-beta'), 'confirmed'); + +// Function to retrieve domain information +async function getDomainInfo(domain) { + try { + // Step 1: Get the domain key + const { pubkey } = getDomainKeySync(domain); + // const pubkey = new PublicKey('DuG7m1M7rnyDP3ErUmtHrvcA8CfaKNT6HEc7Py9StVBU') + + // Step 2: Retrieve the domain registry information + const { registry, nftOwner } = await NameRegistryState.retrieve(connection, pubkey); + + // Log the retrieved information + console.log(`Domain: ${registry.name}`); + console.log(`Public Key: ${pubkey.toBase58()}`); + console.log(`NFT Owner Origin: ${nftOwner ? nftOwner : 'None'}`); + console.log(`NFT Owner: ${nftOwner ? nftOwner.toBase58() : 'None'}`); + console.log(`Registry:`, registry); + console.log(`parentName:`, registry.parentName.toBase58()); + console.log(`Owner:`, registry.owner.toBase58()); + console.log(`class:`, registry.class.toBase58()); + console.log(`data:`, registry.data.toString()); + + } catch (error) { + console.error(`Error fetching domain info for ${domain}:`, error); + } +} + +// Function to retrieve subdomain and record information +async function getSubdomainAndRecordInfo(subDomain, record) { + try { + // Get subdomain key + const { pubkey: subKey } = getDomainKeySync(subDomain); + console.log(`Subdomain: ${subDomain}`); + console.log(`Subdomain Public Key: ${subKey.toBase58()}`); + + // Get record key + const records = await getRecords(connection, domainName, [Record.Twitter, Record.Telegram], true) + records.forEach((item) => { + console.log(`Record: ${item}`); + }); + + } catch (error) { + console.error(`Error fetching subdomain or record info:`, error); + } +} + +// Main function to run the script +async function main() { + await getDomainInfo(domainName); + await getSubdomainAndRecordInfo(subDomain, record); +} + +// Execute the main function +main().catch(error => console.error('Error in main execution:', error)); diff --git a/sns_process/index_3.js b/sns_process/index_3.js new file mode 100644 index 0000000..fab6e06 --- /dev/null +++ b/sns_process/index_3.js @@ -0,0 +1,183 @@ +import { Connection, clusterApiUrl, PublicKey } from '@solana/web3.js'; +import { getAllDomains, + getDomainKeysWithReverses, + getAllRegisteredDomains, + NameRegistryState, + getRecordV2Key, + Record, + getRecords, + getDomainKeySync, + getMultiplePrimaryDomains +} from '@bonfida/spl-name-service'; +import fs from "fs/promises"; +import Bottleneck from 'bottleneck'; + + +// Create a connection to the Solana devnet or mainnet +const SOLANA_MAIN_CLIENT = new Connection(clusterApiUrl('mainnet-beta'), 'confirmed'); + +// Set up bottleneck limiter to control request rate (2 requests per second, 30 requests per minute) +const limiter = new Bottleneck({ + minTime: 3000, // 1 request every 3 seconds + maxConcurrent: 1, // Only allow 1 concurrent request at a time + reservoir: 30, // Limit to 30 requests per minute + reservoirRefreshAmount: 30, // Refill 30 tokens + reservoirRefreshInterval: 60 * 1000 // Refresh every minute (60000 ms) +}); + + +const SOL_TLD = new PublicKey("58PwtjSDuFHuUkYjH9BYnnQKHfwo9reZhC2zMJv9JPkx"); // .sol TLD +const NAME_PROGRAM_ID = new PublicKey("namesLPneVptA9Z5rqUDD9tMTWEJwofgaYwp8cawRkX"); + + +// fetchAllDomains +// dumps all the domains namenode +const fetchAllDomains = async () => { + try { + console.log("Fetching all registered .sol domains..."); + + // Fetch all registered .sol domains using Bonfida's spl-name-service + const registeredDomains = await getAllRegisteredDomains(SOLANA_MAIN_CLIENT); + + // Log the number of domains fetched + console.log("Total domains fetched:", registeredDomains.length); + + // Prepare to save base58 addresses and corresponding names to domains.txt + const domainsList = registeredDomains.map(domain => { + const namenode = domain.pubkey; // The domain name base58 format + return `${namenode}`; + }); + + // Save to domains.csv + const filePath = "./data/domains.csv"; + await fs.writeFile(filePath, domainsList.join("\n")); + console.log(`Domains successfully saved to ${filePath}`); + + } catch (error) { + console.error("Error fetching domains:", error); + } +}; + +// Dumps the domains list to domain +// fetchAllDomains(); + +const getDomainInfo = limiter.wrap(async (input) => { + try { + // domain key + const { pubkey } = getDomainKeySync(input); + // const pubkey = new PublicKey(input) + + const { registry, nftOwner } = await NameRegistryState.retrieve(SOLANA_MAIN_CLIENT, pubkey); + + const namenode = pubkey.toBase58(); + const nft_owner = nftOwner ? nftOwner.toBase58() : null; + const is_tokenized = nftOwner ? true : false; + const parent_node = registry.parentName.toBase58(); + const owner = registry.owner.toBase58(); + const resolver = NAME_PROGRAM_ID.toBase58(); + const resolved_address = registry.owner.toBase58(); + const contenthash = registry.data.toString(); + + console.log("namenode:", namenode); + console.log("is_tokenized:", is_tokenized); + console.log("nft_owner:", nft_owner); + console.log("parent_node:", parent_node); + console.log("owner:", owner); + console.log("resolver:", resolver); + console.log("resolved_address:", resolved_address); + console.log("contenthash:", contenthash); + } catch (error) { + console.error(`Error fetching domain error:`, error); + } +}); + +const getTexts = limiter.wrap(async (domainName) => { + try { + const record_keys = [ + Record.IPNS, + Record.IPFS, + Record.ARWV, + Record.SOL, + Record.BTC, + Record.LTC, + Record.DOGE, + Record.BSC, + Record.Email, + Record.Url, + Record.Discord, + Record.Reddit, + Record.Twitter, + Record.Telegram, + Record.Pic, + Record.SHDW, + Record.POINT, + Record.Injective, + Record.Backpack + ]; + + const texts = {}; // json object + const records = await getRecords(SOLANA_MAIN_CLIENT, domainName, record_keys, true); + for (let i = 0; i < records.length; i++) { + if (records[i] !== undefined) { + if (record_keys[i]) { + texts[record_keys[i].toLowerCase()] = records[i]; + } + } + } + console.log("texts:", texts); + + } catch (error) { + console.error(`Error fetching texts error:`, error); + } +}); + +const getDomainKeysWithNames = limiter.wrap(async (wallet) => { + try { + const domainsWithReverses = await getDomainKeysWithReverses(connection, wallet); + domainsWithReverses.forEach((domain) => { + console.log(`Domain: ${domain.domain}, Public Key: ${domain.pubKey}`); + }); + } catch (error) { + console.error('Error fetching domain keys with names:', error); + } +}); + +const getPrimaryDomains = limiter.wrap(async (wallets) => { + try { + const primaryDomains = await getMultiplePrimaryDomains(SOLANA_MAIN_CLIENT, wallets); + primaryDomains.forEach((primary_name) => { + console.log(`primaryDomain: ${primary_name}`); + }); + } catch (error) { + console.error('Error fetching primary domains:', error); + } +}); + +const getPublicKeyFromSolDomain = limiter.wrap(async (domain) => { + const { pubkey } = getDomainKeySync(domain); + const owner = (await NameRegistryState.retrieve(SOLANA_MAIN_CLIENT, pubkey)).registry.owner.toBase58(); + console.log(`The owner of SNS Domain: ${domain} is: `,owner); + return owner; +}); + +// const DOMAIN_TO_SEARCH = 'bonfida'; +// getPublicKeyFromSolDomain(DOMAIN_TO_SEARCH); + + +const wallets = [ + new PublicKey("5k8SRiitUFPcUPLNB4eWwafXfYBP76iTx2P16xc99QYd"), + new PublicKey("HKKp49qGWXd639QsuH7JiLijfVW5UtCVY4s1n2HANwEA"), + new PublicKey("5WqqCfzNHhgLSkaR9QDbQnearFo616MP1EyxfZ69eED"), + new PublicKey("1DWMUS1qEWrNWnCAiybqg1sp9m1YqTTnJTYXfQpvSgs"), + new PublicKey("13L7R82JFtTpHeGKMs4Pnrh7ukYdPAPDUkSH7nZHL9A"), + // Public Keys of all the wallet addresses you're looking up a primary domain for (up to 100) +]; + +getPrimaryDomains(wallets) +// getDomainInfo("5xQahoFAt4wF5iC1EDYtMwC6tpy9fih4uWfKSDwexxsR") +// getDomainInfo("9i8Q8GWK6s1XUkczHgit7P3hakfxTT6bppjbNSjdLuNC") +// getDomainInfo("Cfn1chAwJcL1F4tfqDMJRb4d1pSZCC5jMaQMpBK8cd7G") +// getDomainInfo("cuba") +// getDomainInfo("vaxa") +// getTexts("bonfida") +// getTexts("vaxa") \ No newline at end of file diff --git a/sns_process/package-lock.json b/sns_process/package-lock.json new file mode 100644 index 0000000..b1ee018 --- /dev/null +++ b/sns_process/package-lock.json @@ -0,0 +1,1291 @@ +{ + "name": "sns_process", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "sns_process", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@bonfida/spl-name-service": "^3.0.3", + "bottleneck": "^2.19.5", + "dotenv": "^16.4.5", + "pg": "^8.13.0", + "pg-promise": "^11.10.1" + } + }, + "node_modules/@babel/runtime": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", + "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bonfida/sns-records": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@bonfida/sns-records/-/sns-records-0.0.1.tgz", + "integrity": "sha512-i28w9+BMFufhhpmLQCNx1CKKXTsEn+5RT18VFpPqdGO3sqaYlnUWC1m3wDpOvlzGk498dljgRpRo5wmcsnuEMg==", + "license": "MIT", + "dependencies": { + "borsh": "1.0.0", + "bs58": "5.0.0", + "buffer": "^6.0.3" + }, + "peerDependencies": { + "@solana/web3.js": "^1.87.3" + } + }, + "node_modules/@bonfida/sns-records/node_modules/borsh": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-1.0.0.tgz", + "integrity": "sha512-fSVWzzemnyfF89EPwlUNsrS5swF5CrtiN4e+h0/lLf4dz2he4L3ndM20PS9wj7ICSkXJe/TQUHdaPTq15b1mNQ==", + "license": "Apache-2.0" + }, + "node_modules/@bonfida/spl-name-service": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@bonfida/spl-name-service/-/spl-name-service-3.0.3.tgz", + "integrity": "sha512-1EErAqK7e1FPqQWdzD5rSbWye/BnSRP44Yiba6tkEnrHNKenICnV71zBoYCUrMLAkwWUKkHJLs6oAYlpCRL9pg==", + "license": "MIT", + "dependencies": { + "@bonfida/sns-records": "0.0.1", + "@noble/curves": "^1.4.0", + "@scure/base": "^1.1.6", + "@solana/spl-token": "0.4.6", + "borsh": "2.0.0", + "buffer": "^6.0.3", + "graphemesplit": "^2.4.4", + "ipaddr.js": "^2.2.0", + "punycode": "^2.3.1" + }, + "peerDependencies": { + "@solana/web3.js": "^1.87.3" + } + }, + "node_modules/@noble/curves": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.6.0.tgz", + "integrity": "sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.5.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.5.0.tgz", + "integrity": "sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@solana/buffer-layout": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz", + "integrity": "sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==", + "license": "MIT", + "dependencies": { + "buffer": "~6.0.3" + }, + "engines": { + "node": ">=5.10" + } + }, + "node_modules/@solana/buffer-layout-utils": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz", + "integrity": "sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==", + "license": "Apache-2.0", + "dependencies": { + "@solana/buffer-layout": "^4.0.0", + "@solana/web3.js": "^1.32.0", + "bigint-buffer": "^1.1.5", + "bignumber.js": "^9.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@solana/codecs": { + "version": "2.0.0-preview.2", + "resolved": "https://registry.npmjs.org/@solana/codecs/-/codecs-2.0.0-preview.2.tgz", + "integrity": "sha512-4HHzCD5+pOSmSB71X6w9ptweV48Zj1Vqhe732+pcAQ2cMNnN0gMPMdDq7j3YwaZDZ7yrILVV/3+HTnfT77t2yA==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.0.0-preview.2", + "@solana/codecs-data-structures": "2.0.0-preview.2", + "@solana/codecs-numbers": "2.0.0-preview.2", + "@solana/codecs-strings": "2.0.0-preview.2", + "@solana/options": "2.0.0-preview.2" + } + }, + "node_modules/@solana/codecs-core": { + "version": "2.0.0-preview.2", + "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.0.0-preview.2.tgz", + "integrity": "sha512-gLhCJXieSCrAU7acUJjbXl+IbGnqovvxQLlimztPoGgfLQ1wFYu+XJswrEVQqknZYK1pgxpxH3rZ+OKFs0ndQg==", + "license": "MIT", + "dependencies": { + "@solana/errors": "2.0.0-preview.2" + } + }, + "node_modules/@solana/codecs-data-structures": { + "version": "2.0.0-preview.2", + "resolved": "https://registry.npmjs.org/@solana/codecs-data-structures/-/codecs-data-structures-2.0.0-preview.2.tgz", + "integrity": "sha512-Xf5vIfromOZo94Q8HbR04TbgTwzigqrKII0GjYr21K7rb3nba4hUW2ir8kguY7HWFBcjHGlU5x3MevKBOLp3Zg==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.0.0-preview.2", + "@solana/codecs-numbers": "2.0.0-preview.2", + "@solana/errors": "2.0.0-preview.2" + } + }, + "node_modules/@solana/codecs-numbers": { + "version": "2.0.0-preview.2", + "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.0.0-preview.2.tgz", + "integrity": "sha512-aLZnDTf43z4qOnpTcDsUVy1Ci9im1Md8thWipSWbE+WM9ojZAx528oAql+Cv8M8N+6ALKwgVRhPZkto6E59ARw==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.0.0-preview.2", + "@solana/errors": "2.0.0-preview.2" + } + }, + "node_modules/@solana/codecs-strings": { + "version": "2.0.0-preview.2", + "resolved": "https://registry.npmjs.org/@solana/codecs-strings/-/codecs-strings-2.0.0-preview.2.tgz", + "integrity": "sha512-EgBwY+lIaHHgMJIqVOGHfIfpdmmUDNoNO/GAUGeFPf+q0dF+DtwhJPEMShhzh64X2MeCZcmSO6Kinx0Bvmmz2g==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.0.0-preview.2", + "@solana/codecs-numbers": "2.0.0-preview.2", + "@solana/errors": "2.0.0-preview.2" + }, + "peerDependencies": { + "fastestsmallesttextencoderdecoder": "^1.0.22" + } + }, + "node_modules/@solana/errors": { + "version": "2.0.0-preview.2", + "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-2.0.0-preview.2.tgz", + "integrity": "sha512-H2DZ1l3iYF5Rp5pPbJpmmtCauWeQXRJapkDg8epQ8BJ7cA2Ut/QEtC3CMmw/iMTcuS6uemFNLcWvlOfoQhvQuA==", + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "commander": "^12.0.0" + }, + "bin": { + "errors": "bin/cli.js" + } + }, + "node_modules/@solana/options": { + "version": "2.0.0-preview.2", + "resolved": "https://registry.npmjs.org/@solana/options/-/options-2.0.0-preview.2.tgz", + "integrity": "sha512-FAHqEeH0cVsUOTzjl5OfUBw2cyT8d5Oekx4xcn5hn+NyPAfQJgM3CEThzgRD6Q/4mM5pVUnND3oK/Mt1RzSE/w==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.0.0-preview.2", + "@solana/codecs-numbers": "2.0.0-preview.2" + } + }, + "node_modules/@solana/spl-token": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.4.6.tgz", + "integrity": "sha512-1nCnUqfHVtdguFciVWaY/RKcQz1IF4b31jnKgAmjU9QVN1q7dRUkTEWJZgTYIEtsULjVnC9jRqlhgGN39WbKKA==", + "license": "Apache-2.0", + "dependencies": { + "@solana/buffer-layout": "^4.0.0", + "@solana/buffer-layout-utils": "^0.2.0", + "@solana/spl-token-group": "^0.0.4", + "@solana/spl-token-metadata": "^0.1.4", + "buffer": "^6.0.3" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.91.6" + } + }, + "node_modules/@solana/spl-token-group": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@solana/spl-token-group/-/spl-token-group-0.0.4.tgz", + "integrity": "sha512-7+80nrEMdUKlK37V6kOe024+T7J4nNss0F8LQ9OOPYdWCCfJmsGUzVx2W3oeizZR4IHM6N4yC9v1Xqwc3BTPWw==", + "license": "Apache-2.0", + "dependencies": { + "@solana/codecs": "2.0.0-preview.2", + "@solana/spl-type-length-value": "0.1.0" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.91.6" + } + }, + "node_modules/@solana/spl-token-metadata": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@solana/spl-token-metadata/-/spl-token-metadata-0.1.6.tgz", + "integrity": "sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA==", + "license": "Apache-2.0", + "dependencies": { + "@solana/codecs": "2.0.0-rc.1" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.95.3" + } + }, + "node_modules/@solana/spl-token-metadata/node_modules/@solana/codecs": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs/-/codecs-2.0.0-rc.1.tgz", + "integrity": "sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-data-structures": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/codecs-strings": "2.0.0-rc.1", + "@solana/options": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/spl-token-metadata/node_modules/@solana/codecs-core": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.0.0-rc.1.tgz", + "integrity": "sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==", + "license": "MIT", + "dependencies": { + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/spl-token-metadata/node_modules/@solana/codecs-data-structures": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-data-structures/-/codecs-data-structures-2.0.0-rc.1.tgz", + "integrity": "sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/spl-token-metadata/node_modules/@solana/codecs-numbers": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.0.0-rc.1.tgz", + "integrity": "sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/spl-token-metadata/node_modules/@solana/codecs-strings": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-strings/-/codecs-strings-2.0.0-rc.1.tgz", + "integrity": "sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "fastestsmallesttextencoderdecoder": "^1.0.22", + "typescript": ">=5" + } + }, + "node_modules/@solana/spl-token-metadata/node_modules/@solana/errors": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-2.0.0-rc.1.tgz", + "integrity": "sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==", + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "commander": "^12.1.0" + }, + "bin": { + "errors": "bin/cli.mjs" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/spl-token-metadata/node_modules/@solana/options": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/options/-/options-2.0.0-rc.1.tgz", + "integrity": "sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-data-structures": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/codecs-strings": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/spl-type-length-value": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@solana/spl-type-length-value/-/spl-type-length-value-0.1.0.tgz", + "integrity": "sha512-JBMGB0oR4lPttOZ5XiUGyvylwLQjt1CPJa6qQ5oM+MBCndfjz2TKKkw0eATlLLcYmq1jBVsNlJ2cD6ns2GR7lA==", + "license": "Apache-2.0", + "dependencies": { + "buffer": "^6.0.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@solana/web3.js": { + "version": "1.95.4", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.95.4.tgz", + "integrity": "sha512-sdewnNEA42ZSMxqkzdwEWi6fDgzwtJHaQa5ndUGEJYtoOnM6X5cvPmjoTUp7/k7bRrVAxfBgDnvQQHD6yhlLYw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.25.0", + "@noble/curves": "^1.4.2", + "@noble/hashes": "^1.4.0", + "@solana/buffer-layout": "^4.0.1", + "agentkeepalive": "^4.5.0", + "bigint-buffer": "^1.1.5", + "bn.js": "^5.2.1", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.3", + "fast-stable-stringify": "^1.0.0", + "jayson": "^4.1.1", + "node-fetch": "^2.7.0", + "rpc-websockets": "^9.0.2", + "superstruct": "^2.0.2" + } + }, + "node_modules/@solana/web3.js/node_modules/base-x": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.10.tgz", + "integrity": "sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/@solana/web3.js/node_modules/borsh": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz", + "integrity": "sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==", + "license": "Apache-2.0", + "dependencies": { + "bn.js": "^5.2.0", + "bs58": "^4.0.0", + "text-encoding-utf-8": "^1.0.2" + } + }, + "node_modules/@solana/web3.js/node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "license": "MIT", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz", + "integrity": "sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "license": "MIT" + }, + "node_modules/@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "license": "MIT", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/assert-options": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/assert-options/-/assert-options-0.8.2.tgz", + "integrity": "sha512-XaXoMxY0zuwAb0YuZjxIm8FeWvNq0aWNIbrzHhFjme8Smxw4JlPoyrAKQ6808k5UvQdhvnWqHZCphq5mXd4TDA==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/base-x": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", + "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==", + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bigint-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", + "integrity": "sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "bindings": "^1.3.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "license": "MIT" + }, + "node_modules/borsh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-2.0.0.tgz", + "integrity": "sha512-kc9+BgR3zz9+cjbwM8ODoUB4fs3X3I5A/HtX7LZKxCLaMrEeDFoBpnhZY//DTS1VZBSs6S5v46RZRbZjRFspEg==", + "license": "Apache-2.0" + }, + "node_modules/bottleneck": { + "version": "2.19.5", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "license": "MIT" + }, + "node_modules/bs58": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "license": "MIT", + "dependencies": { + "base-x": "^4.0.0" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/bufferutil": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/delay": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", + "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "license": "MIT" + }, + "node_modules/es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", + "license": "MIT", + "dependencies": { + "es6-promise": "^4.0.3" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==", + "engines": { + "node": "> 0.1.90" + } + }, + "node_modules/fast-stable-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz", + "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==", + "license": "MIT" + }, + "node_modules/fastestsmallesttextencoderdecoder": { + "version": "1.0.22", + "resolved": "https://registry.npmjs.org/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.22.tgz", + "integrity": "sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==", + "license": "CC0-1.0", + "peer": true + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "license": "MIT" + }, + "node_modules/graphemesplit": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/graphemesplit/-/graphemesplit-2.4.4.tgz", + "integrity": "sha512-lKrpp1mk1NH26USxC/Asw4OHbhSQf5XfrWZ+CDv/dFVvd1j17kFgMotdJvOesmHkbFX9P9sBfpH8VogxOWLg8w==", + "license": "MIT", + "dependencies": { + "js-base64": "^3.6.0", + "unicode-trie": "^2.0.0" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/jayson": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-4.1.2.tgz", + "integrity": "sha512-5nzMWDHy6f+koZOuYsArh2AXs73NfWYVlFyJJuCedr93GpY+Ku8qq10ropSXVfHK+H0T6paA88ww+/dV+1fBNA==", + "license": "MIT", + "dependencies": { + "@types/connect": "^3.4.33", + "@types/node": "^12.12.54", + "@types/ws": "^7.4.4", + "commander": "^2.20.3", + "delay": "^5.0.0", + "es6-promisify": "^5.0.0", + "eyes": "^0.1.8", + "isomorphic-ws": "^4.0.1", + "json-stringify-safe": "^5.0.1", + "JSONStream": "^1.3.5", + "uuid": "^8.3.2", + "ws": "^7.5.10" + }, + "bin": { + "jayson": "bin/jayson.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jayson/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/js-base64": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.7.tgz", + "integrity": "sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==", + "license": "BSD-3-Clause" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "license": "ISC" + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", + "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", + "license": "MIT", + "optional": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==", + "license": "MIT" + }, + "node_modules/pg": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.13.0.tgz", + "integrity": "sha512-34wkUTh3SxTClfoHB3pQ7bIMvw9dpFU1audQQeZG837fmHfHpr14n/AELVDoOYVDW2h5RDWU78tFjkD+erSBsw==", + "license": "MIT", + "dependencies": { + "pg-connection-string": "^2.7.0", + "pg-pool": "^3.7.0", + "pg-protocol": "^1.7.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.1.1" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", + "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "license": "MIT", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.7.0.tgz", + "integrity": "sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==", + "license": "MIT" + }, + "node_modules/pg-cursor": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/pg-cursor/-/pg-cursor-2.12.0.tgz", + "integrity": "sha512-rppw54OnuYZfMUjiJI2zJMwAjjt2V9EtLUb+t7V5tqwSE5Jxod+7vA7Y0FI6Nq976jNLciA0hoVkwvjjB8qzEw==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "pg": "^8" + } + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-minify": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/pg-minify/-/pg-minify-1.6.5.tgz", + "integrity": "sha512-u0UE8veaCnMfJmoklqneeBBopOAPG3/6DHqGVHYAhz8DkJXh9dnjPlz25fRxn4e+6XVzdOp7kau63Rp52fZ3WQ==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.7.0.tgz", + "integrity": "sha512-ZOBQForurqh4zZWjrgSwwAtzJ7QiRX0ovFkZr2klsen3Nm0aoh33Ls0fzfv3imeH/nw/O27cjdz5kzYJfeGp/g==", + "license": "MIT", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-promise": { + "version": "11.10.1", + "resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-11.10.1.tgz", + "integrity": "sha512-TceugkypE+VkHTjlklMmLYLN5hUDbM9dIhKZQq2onxN9F//6X6Q5czQ7Ms5sCi0JB5pkbt8fgoC7OLHM2EVI7Q==", + "license": "MIT", + "dependencies": { + "assert-options": "0.8.2", + "pg": "8.13.0", + "pg-minify": "1.6.5", + "spex": "3.4.0" + }, + "engines": { + "node": ">=14.0" + }, + "peerDependencies": { + "pg-query-stream": "4.7.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.7.0.tgz", + "integrity": "sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ==", + "license": "MIT" + }, + "node_modules/pg-query-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/pg-query-stream/-/pg-query-stream-4.7.0.tgz", + "integrity": "sha512-aQpK8yfFTvOzvPmhXEzWfkwM24lv2Y3TfFY0HJYwx0YM/2fL4DhqpBhLni2Kd+l9p/XoDEi+HFvEvOCm7oqaLg==", + "license": "MIT", + "peer": true, + "dependencies": { + "pg-cursor": "^2.12.0" + }, + "peerDependencies": { + "pg": "^8" + } + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, + "node_modules/rpc-websockets": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-9.0.4.tgz", + "integrity": "sha512-yWZWN0M+bivtoNLnaDbtny4XchdAIF5Q4g/ZsC5UC61Ckbp0QczwO8fg44rV3uYmY4WHd+EZQbn90W1d8ojzqQ==", + "license": "LGPL-3.0-only", + "dependencies": { + "@swc/helpers": "^0.5.11", + "@types/uuid": "^8.3.4", + "@types/ws": "^8.2.2", + "buffer": "^6.0.3", + "eventemitter3": "^5.0.1", + "uuid": "^8.3.2", + "ws": "^8.5.0" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/kozjak" + }, + "optionalDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + } + }, + "node_modules/rpc-websockets/node_modules/@types/ws": { + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", + "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/rpc-websockets/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/spex": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/spex/-/spex-3.4.0.tgz", + "integrity": "sha512-8JeZJ7QlEBnSj1W1fKXgbB2KUPA8k4BxFMf6lZX/c1ZagU/1b9uZWZK0yD6yjfzqAIuTNG4YlRmtMpQiXuohsg==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/superstruct": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-2.0.2.tgz", + "integrity": "sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/text-encoding-utf-8": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", + "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "license": "MIT" + }, + "node_modules/tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", + "license": "MIT" + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", + "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unicode-trie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz", + "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==", + "license": "MIT", + "dependencies": { + "pako": "^0.2.5", + "tiny-inflate": "^1.0.0" + } + }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + } + } +} diff --git a/sns_process/package.json b/sns_process/package.json new file mode 100644 index 0000000..0dfe8ae --- /dev/null +++ b/sns_process/package.json @@ -0,0 +1,20 @@ +{ + "name": "sns_process", + "version": "1.0.0", + "main": "index.js", + "type": "module", + "scripts": { + "start": "node --no-deprecation index.js" + }, + "keywords": [], + "author": "Zella Zhong ", + "license": "ISC", + "description": "", + "dependencies": { + "@bonfida/spl-name-service": "^3.0.3", + "bottleneck": "^2.19.5", + "dotenv": "^16.4.5", + "pg": "^8.13.0", + "pg-promise": "^11.10.1" + } +} diff --git a/sns_process/run.sh b/sns_process/run.sh new file mode 100755 index 0000000..fe74cb6 --- /dev/null +++ b/sns_process/run.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +# use supervisor to start module sbin +supervisord -c /node_app/supervisord.conf + +# use supervisord +if [ $? -eq 0 ] +then + echo "supervisorctl restart all" + supervisorctl -c /node_app/supervisord.conf restart all + +# not use supervisord +else + echo "not use supervisord" +fi \ No newline at end of file diff --git a/sns_process/supervisord.conf b/sns_process/supervisord.conf new file mode 100644 index 0000000..8677d69 --- /dev/null +++ b/sns_process/supervisord.conf @@ -0,0 +1,26 @@ +[unix_http_server] +file=/var/tmp/sns_process.supervior.sock +chmod=0760 + +[supervisord] +nodaemon=true +logfile=/var/tmp/sns_process_supervisord.log +logfile_maxbytes=50MB +logfile_backups=10 +loglevel=info +user=root + +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface + +[supervisorctl] +serverurl = unix:///var/tmp/sns_process.supervior.sock + +; use nodaemon to start proc +[program:sns_process] +command=node --no-deprecation index.js +autostart=true +autorestart=true +stopsignal=KILL +stopasgroup=true +killasgroup=true diff --git a/src/jobs/basenames_process_job.py b/src/jobs/basenames_process_job.py index 0d545fb..6618870 100644 --- a/src/jobs/basenames_process_job.py +++ b/src/jobs/basenames_process_job.py @@ -4,7 +4,7 @@ Author: Zella Zhong Date: 2024-10-16 15:10:34 LastEditors: Zella Zhong -LastEditTime: 2024-10-21 14:35:12 +LastEditTime: 2024-10-21 14:49:53 FilePath: /data_process/src/jobs/basenames_process_job.py Description: ''' @@ -1851,12 +1851,12 @@ def process_pipeline(self): config = setting.load_settings(env=os.getenv("ENVIRONMENT")) logger.InitLogger(config) - txhash = "0xb288da4ff8e6123e2b29b5c5866f46ce5ebf17ef39b46e8a2df347574dfd649f" + # txhash = "0xb288da4ff8e6123e2b29b5c5866f46ce5ebf17ef39b46e8a2df347574dfd649f" # BasenamesProcess().test_single_transaction(txhash) # BasenamesProcess().process_pipeline() - name = 'vault.luc.eth' - # name = 'luc.eth' - namenode = compute_namehash_nowrapped(name) - print(namenode) + # name = 'web3.bio' + # # name = 'luc.eth' + # namenode = compute_namehash_nowrapped(name) + # print(namenode) diff --git a/src/script/create_sns_profile.sql b/src/script/create_sns_profile.sql new file mode 100644 index 0000000..91df13c --- /dev/null +++ b/src/script/create_sns_profile.sql @@ -0,0 +1,28 @@ +CREATE TABLE sns_profile ( + id SERIAL PRIMARY KEY, + namenode VARCHAR(66) NOT NULL, + name VARCHAR(1024), + label_name VARCHAR(1024), + parent_node VARCHAR(66), + is_tokenized BOOLEAN DEFAULT FALSE, + nft_owner VARCHAR(66), + registration_time TIMESTAMP WITHOUT TIME ZONE, + expire_time TIMESTAMP WITHOUT TIME ZONE, + owner VARCHAR(66), + resolver VARCHAR(66), + resolved_address VARCHAR(66), + reverse_address VARCHAR(66), + is_primary BOOLEAN DEFAULT FALSE, + contenthash TEXT, + update_time TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP, + texts JSONB default '{}'::jsonb, + resolved_records JSONB default '{}'::jsonb, + CONSTRAINT unique_sns_profile UNIQUE (namenode) +); + +CREATE INDEX sns_profile_name_index ON sns_profile (name); +CREATE INDEX sns_profile_label_name_index ON sns_profile (label_name); +CREATE INDEX sns_profile_nft_owner ON sns_profile (nft_owner); +CREATE INDEX sns_profile_owner_index ON sns_profile (owner); +CREATE INDEX sns_profile_resolved_index ON sns_profile (resolved_address); +CREATE INDEX sns_profile_reverse_index ON sns_profile (reverse_address);