UNPKG

delegate-framework

Version:

A TypeScript framework for building robust, production-ready blockchain workflows with comprehensive error handling, logging, and testing. Maintained by delegate.fun

187 lines 9.46 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Deployer = void 0; const web3_js_1 = require("@solana/web3.js"); const spl_token_1 = require("@solana/spl-token"); const raydium_sdk_v2_1 = require("@raydium-io/raydium-sdk-v2"); const base_delegate_1 = require("./base-delegate"); const BN = require("bn.js"); class Deployer extends base_delegate_1.BaseDelegate { constructor(connection, signerKeypair, metadataClient, feeTakerKeypair) { super(connection, signerKeypair, feeTakerKeypair); this.metadataClient = metadataClient; } async executeDelegate(delegateOptions) { const requestId = this.generateRequestId(); try { this.logOperation('deployer_execution_started', { requestId }); this.validateOptions(delegateOptions); const metadata = { name: delegateOptions.tokenName, symbol: delegateOptions.tokenSymbol, description: delegateOptions.tokenDescription || '', image: delegateOptions.tokenImage || '', externalUrl: delegateOptions.tokenWebsite || '', twitter: delegateOptions.tokenTwitter || '', telegram: delegateOptions.tokenTelegram || '', discord: delegateOptions.tokenDiscord || '', github: delegateOptions.tokenGithub || '' }; let metadataUri = ''; // Upload metadata with retry try { if (delegateOptions.tokenImage) { const imageResult = await this.retryOperation(async () => { const base64Data = delegateOptions.tokenImage.replace(/^data:image\/[a-z]+;base64,/, ''); const imageBuffer = Buffer.from(base64Data, 'base64'); const result = await this.metadataClient.uploadImage(imageBuffer); if (!result.success) { throw new Error(`Failed to upload token image: ${result.error}`); } return result; }, 3); metadata.image = imageResult.uri; } const metadataResult = await this.retryOperation(async () => { const result = await this.metadataClient.uploadMetadata(metadata); if (!result.success) { throw new Error(`Failed to upload token metadata: ${result.error}`); } return result; }, 3); metadataUri = metadataResult.uri || ''; this.logOperation('metadata_upload_completed', { requestId, metadataUri }); } catch (error) { await this.handleError(error instanceof Error ? error : new Error(String(error)), { requestId }); throw new Error(`Failed to upload token metadata: ${error}`); } const tokenParams = { name: delegateOptions.tokenName, symbol: delegateOptions.tokenSymbol, decimals: 6, supply: 1000000000, migrateType: delegateOptions.tokenMigrateType, uri: metadataUri, txVersion: raydium_sdk_v2_1.TxVersion.V0, buyAmount: new BN(delegateOptions.buyAmount ?? 0), createOnly: delegateOptions.buyAmount === 0, extraSigners: delegateOptions.extraSigners || [], platformId: delegateOptions.platformId, slippageBps: delegateOptions.buySlippageBps || 100, }; const raydiumComputeBudgetConfig = { units: 200000, microLamports: 1000000, }; const result = await this.retryOperation(async () => { return await this.raydiumCreateLaunchlabToken(tokenParams, raydiumComputeBudgetConfig); }, 2); this.logOperation('deployer_execution_completed', { requestId, signatures: result.signatures }); return { success: true, signatures: result.signatures, metadataUri }; } catch (error) { await this.handleError(error instanceof Error ? error : new Error(String(error)), { requestId }); throw error; } } validateOptions(delegateOptions) { this.validateStringField(delegateOptions.tokenName, 'tokenName'); this.validateStringField(delegateOptions.tokenSymbol, 'tokenSymbol'); this.validateStringField(delegateOptions.tokenMigrateType, 'tokenMigrateType'); this.validateNumberField(delegateOptions.buyAmount, 'buyAmount', 0); this.validateNumberField(delegateOptions.buySlippageBps || 100, 'buySlippageBps', 0, 10000); this.validatePublicKey(delegateOptions.platformId, 'platformId'); if (delegateOptions.tokenMigrateType !== "amm" && delegateOptions.tokenMigrateType !== "cpmm") { throw new Error("Invalid token migrate type, must be amm or cpmm"); } if (delegateOptions.tokenImage) { const base64Data = delegateOptions.tokenImage.replace(/^data:image\/[a-z]+;base64,/, ''); if (!base64Data) { throw new Error("Invalid token image, must be a valid base64 data URI"); } } } async raydiumCreateLaunchlabToken(tokenParams, computeBudgetConfig) { try { const raydium = await raydium_sdk_v2_1.Raydium.load({ connection: this.connection, owner: this.signerKeypair.publicKey, }); const newTokenKeypair = web3_js_1.Keypair.generate(); const newTokenMint = newTokenKeypair.publicKey; const configId = (0, raydium_sdk_v2_1.getPdaLaunchpadConfigId)(raydium_sdk_v2_1.LAUNCHPAD_PROGRAM, spl_token_1.NATIVE_MINT, 0, 0).publicKey; const configData = await this.retryOperation(async () => { const data = await raydium.connection.getAccountInfo(configId); if (!data) { throw new Error("Launchpad config not found"); } return data; }, 3); const configInfo = raydium_sdk_v2_1.LaunchpadConfig.decode(configData.data); const baseTokenInfo = await raydium.token.getTokenInfo(configInfo.mintB); const { transactions } = await raydium.launchpad.createLaunchpad({ programId: raydium_sdk_v2_1.LAUNCHPAD_PROGRAM, mintA: newTokenMint, decimals: tokenParams.decimals, name: tokenParams.name, symbol: tokenParams.symbol, migrateType: tokenParams.migrateType, uri: tokenParams.uri, feePayer: this.signerKeypair.publicKey, configId: new web3_js_1.PublicKey(configId.toBase58()), configInfo, mintBDecimals: baseTokenInfo.decimals, platformId: new web3_js_1.PublicKey(tokenParams.platformId), txVersion: tokenParams.txVersion || raydium_sdk_v2_1.TxVersion.V0, slippage: new BN(tokenParams.slippageBps ?? 100), buyAmount: tokenParams.createOnly ? new BN(1) : (tokenParams.buyAmount instanceof BN ? tokenParams.buyAmount : new BN(tokenParams.buyAmount || 0)), createOnly: tokenParams.createOnly, extraSigners: [newTokenKeypair, ...tokenParams.extraSigners], supply: new BN(tokenParams.supply * 10 ** tokenParams.decimals), computeBudgetConfig, }); const blockhash = await this.retryOperation(async () => { return (await this.connection.getLatestBlockhash()).blockhash; }, 3); transactions.forEach((tx) => { tx.message.recentBlockhash = blockhash; tx.sign([newTokenKeypair, ...tokenParams.extraSigners]); }); const signatures = []; for (const tx of transactions) { const signature = await this.retryOperation(async () => { if ('message' in tx) { tx.sign([newTokenKeypair, ...tokenParams.extraSigners]); return await this.connection.sendTransaction(tx, { skipPreflight: false, maxRetries: 3, }); } else { tx.sign([newTokenKeypair, ...tokenParams.extraSigners]); return await this.connection.sendTransaction(tx, [newTokenKeypair, ...tokenParams.extraSigners], { skipPreflight: false, maxRetries: 3, }); } }, 3); signatures.push(signature); } return { success: true, signatures, tokenMint: newTokenMint.toBase58() }; } catch (e) { throw new Error(`Failed to create Raydium Launchpad token: ${e instanceof Error ? e.message : String(e)}`); } } } exports.Deployer = Deployer; //# sourceMappingURL=deployer.js.map