Quantcast
Channel: Recent Questions - Solana Stack Exchange
Viewing all articles
Browse latest Browse all 7906

i'm confused how did solana wallet works am I doing this right?

$
0
0

this is SolanaProvider.jsimport { Provider } from '@modules/core/provider/base/Provider';import axios from 'axios';import {Connection, PublicKey, clusterApiUrl, Transaction, SystemProgram, LAMPORTS_PER_SOL} from '@solana/web3.js';import {Cluster} from "@solana/web3.js";

export class SolanaProvider implements Provider {apiInstance: typeof axios; // Axios instance for HTTP requestsconnection: Connection; // Solana connection object

constructor({ rpcUrl, apiEndpoint, apiKey }) {    this.apiInstance = axios.create({        baseURL: `${apiEndpoint}` || 'https://api.mainnet-beta.solana.com', // Default to Solana mainnet API        headers: apiKey ? { 'Authorization': apiKey } : {}, // Optional API key    });    this.connection = new Connection(rpcUrl || clusterApiUrl('mainnet-beta')); // Establish connection to Solana network}async getNetwork(): Promise<Cluster> {    const connection = new Connection(process.env.SOLANA_RPC_URL || 'https://api.mainnet-beta.solana.com', 'confirmed'); // Or use your preferred RPC    try {        const version = await connection.getVersion(); // Get the Solana node's version information        const cluster = version['solana-core'].includes('testnet') ? 'testnet' : 'mainnet-beta'; // Basic cluster identification        return cluster;    } catch (error) {        console.error("Error fetching network information:", error);        throw new Error('Failed to get network information');    }}async getGasPrice(): Promise<number> {    // Solana doesn't have a gas price concept like Ethereum.    // Instead, you pay transaction fees in SOL.    // Here, you can fetch the recent blockhash to estimate fees:    const recentBlockhash = await this.connection.getRecentBlockhash();    return recentBlockhash.feeCalculator.lamportsPerSignature; // Lamports per signature is the fee unit in Solana}async getFeeData(): Promise<{ lamportsPerSignature: number }> {    const connection = new Connection(process.env.SOLANA_RPC_URL || 'https://api.mainnet-beta.solana.com', 'confirmed'); // Or your preferred RPC endpoint    try {        const feeCalculator = await connection.getFeeCalculatorForBlockhash(            await connection.getRecentBlockhash('confirmed'), // Get the recent blockhash        );        return { lamportsPerSignature: feeCalculator.value.lamportsPerSignature };    } catch (error) {        console.error("Error fetching fee data:", error);        throw new Error("Failed to get fee data");    }}async estimateGas({ from, to, data }) {    // In Solana, transaction size influences fees, not gas.    // You can estimate transaction size here:    const transaction = new Transaction().add(        SystemProgram.transfer({            fromPubkey: new PublicKey(from),            toPubkey: new PublicKey(to),            lamports: LAMPORTS_PER_SOL / 100, // Example: Transfer 0.01 SOL        })    );    transaction.recentBlockhash = (await this.connection.getRecentBlockhash('finalized')).blockhash;    const transactionSize = transaction.serialize({requireAllSignatures: false}).length;    const estimatedFee = transactionSize * await this.getGasPrice();    return {success: true, data: estimatedFee};}async getTransactions(    address: string,    limit: number = 10, // Default to fetching 10 transactions    before?: string, // Optional parameter for pagination    until?: string, // Optional parameter for pagination): Promise<Array<any>> { // Adjust type as needed for your transaction representation    const connection = new Connection(process.env.SOLANA_RPC_URL || 'https://api.mainnet-beta.solana.com', 'confirmed');    const pubKey = new PublicKey(address);    try {        let transactions: Array<any> = [];        // Fetch signatures first for efficiency (can be batched if needed)        const signatures = await connection.getSignaturesForAddress(            pubKey,            { limit, before, until }        );        // Fetch transaction details for each signature        for (const signature of signatures) {            const transaction = await connection.getTransaction(signature.signature, { commitment: 'confirmed' });            if (transaction) {                transactions.push(transaction); // Add to the results            }        }        return transactions;    } catch (error) {        console.error("Error fetching transactions:", error);        throw new Error("Failed to get transactions");    }}

}

and this is SolanaWallet.js

import 'react-native-get-random-values';import {Logs} from '@modules/log/logs';import {Keypair, PublicKey, SystemProgram, Transaction} from '@solana/web3.js';import * as Bip39 from 'bip39';import {derivePath} from 'ed25519-hd-key';import bs58 from 'bs58';import {SolanaProvider} from '@modules/core/provider/solana/SolanaProvider'; // Assuming you have thisimport {Wallet} from "ethers";import { mnemonicToSeedSync } from '@scure/bip39';

export const SOLANA_BIP39_PATH = "m/44'/501'/0'/0'";

export class SolanaWallet implements Wallet{provider: SolanaProvider;keypair: Keypair;

constructor(provider: SolanaProvider) {    this.provider = provider;}async mnemonicToSeed(mnemonic: string): Promise<Buffer> {    // Solana uses the "m/44'/501'/0'/0'" derivation path (hardened)    const path = "m/44'/501'/0'/0'";    const seed = mnemonicToSeedSync(mnemonic);    return derivePath(path, seed.toString('hex')).key;}async fromMnemonic(data, mnemonic): Promise<Object> {    try {        const seed = await this.mnemonicToSeed(mnemonic);        const derivedSeed = derivePath(SOLANA_BIP39_PATH, seed.toString('hex')).key;        this.keypair = Keypair.fromSeed(derivedSeed);        return {            success: true,            data: {                ...data,                walletAddress: this.keypair.publicKey.toString(),                privateKey: bs58.encode(this.keypair.secretKey), // Encode to Base58            },        };    } catch (e) {        Logs.info('SolanaWallet: fromMnemonic', e);        // ... (Error handling)    }}async fromPrivateKey(data, privateKey): Promise<Object> {    try {        this.keypair = Keypair.fromSecretKey(bs58.decode(privateKey)); // Decode from Base58        return {            success: true,            data: {                ...data,                walletAddress: this.keypair.publicKey.toString(),            },        };    } catch (e) {        Logs.info('SolanaWallet: fromPrivateKey', e);        // ... (Error handling)    }}async sendTransaction({to, value, feePayer}): Promise<Object> {    try {        const transaction = new Transaction().add(            SystemProgram.transfer({                fromPubkey: this.keypair.publicKey,                toPubkey: new PublicKey(to),                lamports: value, // Value should be in lamports            })        );        transaction.feePayer = feePayer || this.keypair.publicKey; // Optionally specify a fee payer        const blockhash = await this.provider.connection.getRecentBlockhash();        transaction.recentBlockhash = blockhash.blockhash;        transaction.sign(this.keypair);        const txid = await this.provider.connection.sendRawTransaction(transaction.serialize());        return {            success: true,            data: { txid },        };    } catch (e) {        Logs.info('SolanaWallet: sendTransaction', e);        // ... (Error handling)    }}async getTransactions(wallet, limit = 20, before = null): Promise<Object> {    try {        const signatures = await this.provider.connection.getSignaturesForAddress(            new PublicKey(wallet.walletAddress),            { limit, before }        );        const transactions = await this.provider.connection.getParsedConfirmedTransactions(signatures.map(s => s.signature));        return {            success: true,            data: transactions.filter(tx => tx !== null).map(tx => { // Filter out null transactions (might occur if not yet confirmed)                return {                    signature: tx.transaction.signatures[0],                    blockTime: tx.blockTime,                    from: tx.transaction.message.accountKeys[0].pubkey, // Assuming simple transfer                    to: tx.transaction.message.instructions[0]?.parsed.info.destination,                    value: tx.transaction.message.instructions[0]?.parsed.info.lamports,                    fee: tx.meta.fee,                    status: tx.meta.err ? 'Failed' : 'Success',                    // ... (Add other relevant fields as needed)                };            }),        };    } catch (e) {        Logs.info('SolanaWallet: getTransactions', e);        return {            success: false,            data: [],        };    }}

}


Viewing all articles
Browse latest Browse all 7906

Trending Articles