UNPKG

@drift-labs/sdk-browser

Version:
211 lines (210 loc) 8.28 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RevenueShareEscrowMap = void 0; const web3_js_1 = require("@solana/web3.js"); const pda_1 = require("../addresses/pda"); const memcmp_1 = require("../memcmp"); class RevenueShareEscrowMap { /** * Creates a new RevenueShareEscrowMap instance. * * @param {DriftClient} driftClient - The DriftClient instance. * @param {boolean} parallelSync - Whether to sync accounts in parallel. */ constructor(driftClient, parallelSync) { /** * map from authority pubkey to RevenueShareEscrow account data. */ this.authorityEscrowMap = new Map(); this.driftClient = driftClient; this.parallelSync = parallelSync !== undefined ? parallelSync : true; } /** * Subscribe to all RevenueShareEscrow accounts. */ async subscribe() { if (this.size() > 0) { return; } await this.driftClient.subscribe(); await this.sync(); } has(authorityPublicKey) { return this.authorityEscrowMap.has(authorityPublicKey); } get(authorityPublicKey) { return this.authorityEscrowMap.get(authorityPublicKey); } /** * Enforce that a RevenueShareEscrow will exist for the given authorityPublicKey, * reading one from the blockchain if necessary. * @param authorityPublicKey * @returns */ async mustGet(authorityPublicKey) { if (!this.has(authorityPublicKey)) { await this.addRevenueShareEscrow(authorityPublicKey); } return this.get(authorityPublicKey); } async addRevenueShareEscrow(authority) { const escrowAccountPublicKey = (0, pda_1.getRevenueShareEscrowAccountPublicKey)(this.driftClient.program.programId, new web3_js_1.PublicKey(authority)); try { const accountInfo = await this.driftClient.connection.getAccountInfo(escrowAccountPublicKey, 'processed'); if (accountInfo && accountInfo.data) { const escrow = this.driftClient.program.account.revenueShareEscrow.coder.accounts.decode('RevenueShareEscrow', accountInfo.data); this.authorityEscrowMap.set(authority, escrow); } } catch (error) { // RevenueShareEscrow account doesn't exist for this authority, which is normal console.debug(`No RevenueShareEscrow account found for authority: ${authority}`); } } size() { return this.authorityEscrowMap.size; } async sync() { if (this.fetchPromise) { return this.fetchPromise; } this.fetchPromise = new Promise((resolver) => { this.fetchPromiseResolver = resolver; }); try { await this.syncAll(); } finally { this.fetchPromiseResolver(); this.fetchPromise = undefined; } } /** * A slow, bankrun test friendly version of sync(), uses getAccountInfo on every cached account to refresh data * @returns */ async slowSync() { if (this.fetchPromise) { return this.fetchPromise; } for (const authority of this.authorityEscrowMap.keys()) { const accountInfo = await this.driftClient.connection.getAccountInfo((0, pda_1.getRevenueShareEscrowAccountPublicKey)(this.driftClient.program.programId, new web3_js_1.PublicKey(authority)), 'confirmed'); const escrowNew = this.driftClient.program.account.revenueShareEscrow.coder.accounts.decode('RevenueShareEscrow', accountInfo.data); this.authorityEscrowMap.set(authority, escrowNew); } } async syncAll() { const rpcRequestArgs = [ this.driftClient.program.programId.toBase58(), { commitment: this.driftClient.opts.commitment, filters: [(0, memcmp_1.getRevenueShareEscrowFilter)()], encoding: 'base64', withContext: true, }, ]; const rpcJSONResponse = // @ts-ignore await this.driftClient.connection._rpcRequest('getProgramAccounts', rpcRequestArgs); const rpcResponseAndContext = rpcJSONResponse.result; const batchSize = 100; for (let i = 0; i < rpcResponseAndContext.value.length; i += batchSize) { const batch = rpcResponseAndContext.value.slice(i, i + batchSize); if (this.parallelSync) { await Promise.all(batch.map(async (programAccount) => { try { // @ts-ignore const buffer = Buffer.from(programAccount.account.data[0], programAccount.account.data[1]); const escrow = this.driftClient.program.account.revenueShareEscrow.coder.accounts.decode('RevenueShareEscrow', buffer); // Extract authority from the account data const authorityKey = escrow.authority.toBase58(); this.authorityEscrowMap.set(authorityKey, escrow); } catch (error) { console.warn(`Failed to decode RevenueShareEscrow account ${programAccount.pubkey}:`, error); } })); } else { for (const programAccount of batch) { try { // @ts-ignore const buffer = Buffer.from(programAccount.account.data[0], programAccount.account.data[1]); const escrow = this.driftClient.program.account.revenueShareEscrow.coder.accounts.decode('RevenueShareEscrow', buffer); // Extract authority from the account data const authorityKey = escrow.authority.toBase58(); this.authorityEscrowMap.set(authorityKey, escrow); } catch (error) { console.warn(`Failed to decode RevenueShareEscrow account ${programAccount.pubkey}:`, error); } } } // Add a small delay between batches to avoid overwhelming the RPC await new Promise((resolve) => setTimeout(resolve, 10)); } } /** * Get all RevenueShareEscrow accounts */ getAll() { return new Map(this.authorityEscrowMap); } /** * Get all authorities that have RevenueShareEscrow accounts */ getAuthorities() { return Array.from(this.authorityEscrowMap.keys()); } /** * Get RevenueShareEscrow accounts that have approved referrers */ getEscrowsWithApprovedReferrers() { const result = new Map(); for (const [authority, escrow] of this.authorityEscrowMap) { if (escrow.approvedBuilders && escrow.approvedBuilders.length > 0) { result.set(authority, escrow); } } return result; } /** * Get RevenueShareEscrow accounts that have active orders */ getEscrowsWithOrders() { const result = new Map(); for (const [authority, escrow] of this.authorityEscrowMap) { if (escrow.orders && escrow.orders.length > 0) { result.set(authority, escrow); } } return result; } /** * Get RevenueShareEscrow account by referrer */ getByReferrer(referrerPublicKey) { for (const escrow of this.authorityEscrowMap.values()) { if (escrow.referrer.toBase58() === referrerPublicKey) { return escrow; } } return undefined; } /** * Get all RevenueShareEscrow accounts for a specific referrer */ getAllByReferrer(referrerPublicKey) { const result = []; for (const escrow of this.authorityEscrowMap.values()) { if (escrow.referrer.toBase58() === referrerPublicKey) { result.push(escrow); } } return result; } async unsubscribe() { this.authorityEscrowMap.clear(); } } exports.RevenueShareEscrowMap = RevenueShareEscrowMap;