UNPKG

@dinolab/crypto-mm

Version:

Crypto Market Maker

238 lines 11.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const web3_js_1 = require("@solana/web3.js"); const spl_token_1 = require("@solana/spl-token"); const umi_bundle_defaults_1 = require("@metaplex-foundation/umi-bundle-defaults"); const mpl_token_metadata_1 = require("@metaplex-foundation/mpl-token-metadata"); const umi_1 = require("@metaplex-foundation/umi"); const pinata_1 = require("pinata"); class SolTokenCreator { constructor(rpcUrl) { // this.rpcUrl = rpcUrl; this.rpcUrl = (0, web3_js_1.clusterApiUrl)('devnet'); // HM - Test this.connection = new web3_js_1.Connection(this.rpcUrl); } async createToken(tokenInfo, ownerKeypair, revokeMintAuthority, revokeFreezeAuthority) { try { console.log('⏳ Generating token address...'); const tokenKeypair = web3_js_1.Keypair.generate(); console.log('⏳ Mining token...'); const mintAddress = await this.mintToken(tokenKeypair, ownerKeypair); console.log(`✅ Token created: ${mintAddress.toString()}`); const tokenAccount = await this.createTokenAccount(mintAddress, ownerKeypair); await this.supplyToken(mintAddress, tokenAccount, ownerKeypair, tokenInfo.totalSupply); await this.createTokenMetadata(mintAddress.toString(), tokenInfo, ownerKeypair); if (revokeMintAuthority) { await this.revokeMintAuthority(mintAddress, ownerKeypair); } if (revokeFreezeAuthority) { await this.revokeFreezeAuthority(mintAddress, ownerKeypair); } console.log('Completely create'); return mintAddress.toString(); } catch (e) { console.error('❌ Error creating token'); throw e; } } async mintToken(tokenKeypair, ownerKeypair) { try { const mintAddress = await (0, spl_token_1.createMint)(this.connection, ownerKeypair, ownerKeypair.publicKey, // mint authority ownerKeypair.publicKey, // freeze authority 9, tokenKeypair, { commitment: 'confirmed' }); return mintAddress; } catch (error) { console.error('❌ Error minting token:', error.message); throw error; } } async createTokenAccount(mintAddress, ownerKeypair) { try { console.log('📋 Creating token account...'); const tokenAccount = await (0, spl_token_1.createAccount)(this.connection, ownerKeypair, mintAddress, ownerKeypair.publicKey, undefined, { commitment: 'confirmed' }); console.log(`✅ Token account created: ${tokenAccount}`); return tokenAccount; } catch (error) { console.error('❌ Error creating token account:', error.message); throw error; } } async supplyToken(mintAddress, tokenAccount, ownerKeypair, amount) { try { const signature = await (0, spl_token_1.mintTo)(this.connection, ownerKeypair, mintAddress, tokenAccount, ownerKeypair, amount, [], { commitment: 'confirmed' }); console.log(`✅ Tokens supplied. Signature: ${signature}`); return signature; } catch (error) { console.error('❌ Error supplying tokens:', error.message); throw error; } } // Function mới để tạo metadata với UMI async createTokenMetadata(mintAddress, tokenInfo, ownerKeypair) { try { // 3. Upload metadata JSON đơn giản const metadataUri = await this.uploadMetadataToStorage({ name: tokenInfo.name, symbol: tokenInfo.symbol, description: tokenInfo.description, image: tokenInfo.imageUrl || '', website: tokenInfo.social?.website, twitter: tokenInfo.social?.twitter, telegram: tokenInfo.social?.telegram, extensions: { website: tokenInfo.social?.website, twitter: tokenInfo.social?.twitter, telegram: tokenInfo.social?.telegram, } }); if (!metadataUri) { throw new Error('Metadata was not uploaded'); } let result = undefined; const delayTime = 10000; console.log(`Delay ${(delayTime / 1000).toFixed(2)}s to update token metadata...`); await new Promise(resolve => { setTimeout(async () => { result = await this.updateTokenMetadata(ownerKeypair, mintAddress.toString(), tokenInfo.name, tokenInfo.symbol, 9, metadataUri); resolve(result); }, delayTime); }); return result; } catch (error) { console.error('❌ Error creating metadata:', error.message); throw error; } } async uploadMetadataToStorage(metadata) { try { console.log('📤 Uploading metadata JSON: ', metadata); const pinata = new pinata_1.PinataSDK({ pinataJwt: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mb3JtYXRpb24iOnsiaWQiOiJlM2RkYjM3OC02NzUyLTRhYjUtYTcyYi0xOGU0M2U3YzhjNGMiLCJlbWFpbCI6Im5nb2NodW5nMTI0M0BnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwicGluX3BvbGljeSI6eyJyZWdpb25zIjpbeyJkZXNpcmVkUmVwbGljYXRpb25Db3VudCI6MSwiaWQiOiJGUkExIn0seyJkZXNpcmVkUmVwbGljYXRpb25Db3VudCI6MSwiaWQiOiJOWUMxIn1dLCJ2ZXJzaW9uIjoxfSwibWZhX2VuYWJsZWQiOmZhbHNlLCJzdGF0dXMiOiJBQ1RJVkUifSwiYXV0aGVudGljYXRpb25UeXBlIjoic2NvcGVkS2V5Iiwic2NvcGVkS2V5S2V5IjoiNWY0ZGVkZDI1ZGU4OTBiYmZkZGYiLCJzY29wZWRLZXlTZWNyZXQiOiI5OWRjYzJjNjkxNmVmOWE0OGUxM2FkMzEyNTRlMmMzZDBhZjljOGM4NDMwZGIxOTY0ZTdkMDI3NTY1NDYxYmM4IiwiZXhwIjoxNzgxNjQ0ODk4fQ.w0rGl2cDRmpWr1hmX4Qx4sw_5jMW9jzRtKRoc3p6w5Y', pinataGateway: 'white-effective-tarantula-591.mypinata.cloud' }); const ts = Date.now(); const file = new File([JSON.stringify(metadata)], `${metadata.symbol}_${ts}`, { type: 'text/plain' }); const upload = await pinata.upload.public.file(file); const url = `https://gateway.pinata.cloud/ipfs/${upload.cid}`; console.log(`✅ Metadata uploaded to Pinata: ${url}`); return url; } catch (error) { console.log(`❌ Error uploading metadata to storage. Error: ${error.message}`); } } async updateTokenMetadata(keypair, mintAddress, name, symbol, decimals, uri) { try { const umi = (0, umi_bundle_defaults_1.createUmi)(this.rpcUrl).use((0, mpl_token_metadata_1.mplTokenMetadata)()); // Setup keypair và signer const umiKeypair = umi.eddsa.createKeypairFromSecretKey(keypair.secretKey); const signer = (0, umi_1.createSignerFromKeypair)(umi, umiKeypair); umi.use((0, umi_1.signerIdentity)(signer)); // Convert mint address string to PublicKey const mint = (0, umi_1.publicKey)(mintAddress); // Lấy metadata PDA const [metadataAddress] = (0, mpl_token_metadata_1.findMetadataPda)(umi, { mint: mint }); console.log('Processing metadata...'); try { await (0, mpl_token_metadata_1.fetchMetadata)(umi, metadataAddress); console.log('Existing metadata found. Updating...'); // Update metadata const tx = (0, mpl_token_metadata_1.updateV1)(umi, { mint: mint, authority: signer, data: (0, umi_1.some)({ name: name, symbol: symbol, uri: uri, sellerFeeBasisPoints: 0, creators: (0, umi_1.some)([{ address: keypair.publicKey, verified: true, share: 100 }]), }), collection: (0, mpl_token_metadata_1.collectionToggle)('None'), uses: (0, mpl_token_metadata_1.usesToggle)('None'), }); const result = await tx.sendAndConfirm(umi); console.log('Update metadata successful!'); return { metadataAddress, uri, signature: result.signature.toString(), }; } catch (error) { if (error.name === 'AccountNotFoundError') { console.log('Metadata account not found. Creating new metadata...'); // Create new metadata const tx = (0, mpl_token_metadata_1.createV1)(umi, { mint: mint, authority: signer, name: name, symbol: symbol, decimals: decimals, uri: uri, sellerFeeBasisPoints: (0, umi_1.percentAmount)(0), creators: (0, umi_1.some)([{ address: keypair.publicKey.toBase58(), verified: true, share: 100 }]), collection: (0, umi_1.none)(), uses: (0, umi_1.none)(), tokenStandard: mpl_token_metadata_1.TokenStandard.Fungible, isMutable: true, }); const result = await tx.sendAndConfirm(umi); console.log('Creation metadata successful!'); return { metadataAddress, uri, signature: result.signature.toString(), }; } else { throw error; } } } catch (error) { console.error('Error:', error); if (error.logs) { console.error('Transaction logs:', error.logs); } } } async revokeMintAuthority(mintAddress, ownerKeypair) { try { console.log('🔒 Revoking mint authority...'); const signature = await (0, spl_token_1.setAuthority)(this.connection, ownerKeypair, mintAddress, ownerKeypair, spl_token_1.AuthorityType.MintTokens, null, [], { commitment: 'confirmed' }); console.log(`✅ Mint authority revoked. Signature: ${signature}`); return signature; } catch (error) { console.error('❌ Error revoking mint authority:', error.message); throw error; } } async revokeFreezeAuthority(mintAddress, ownerKeypair) { try { console.log('🔒 Revoking freeze authority...'); const signature = await (0, spl_token_1.setAuthority)(this.connection, ownerKeypair, mintAddress, ownerKeypair, spl_token_1.AuthorityType.FreezeAccount, null, [], { commitment: 'confirmed' }); console.log(`✅ Freeze authority revoked. Signature: ${signature}`); return signature; } catch (error) { console.error('❌ Error revoking freeze authority:', error.message); throw error; } } } exports.default = SolTokenCreator; //# sourceMappingURL=sol.token.creator.js.map