import type { Commitment , ConfirmOptions , Connection , KeyedAccountInfo , PublicKey , RpcResponseAndContext , Signer , SimulatedTransactionResponse , Transaction , TransactionInstruction , } from "@solana/web3.js" ; import type { Broadcaster , ReadonlyProvider } from "." ; import { MultipleConnectionBroadcaster , PendingTransaction , SignerWallet , } from "." ; import { SingleConnectionBroadcaster } from "./broadcaster" ; import type { Provider , SendTxRequest , TransactionSigner , Wallet , } from "./interfaces" ; import { TransactionEnvelope } from "./transaction/TransactionEnvelope" ; export const DEFAULT_PROVIDER_OPTIONS = { preflightCommitment : "processed" , commitment : "processed" , } ; /**
 * Provider that can only read.
 */ export class SolanaReadonlyProvider implements ReadonlyProvider { param connection param sendConnection param wallet param opts constructor ( readonly connection , readonly opts = DEFAULT_PROVIDER_OPTIONS ) { } param accountId returns async getAccountInfo ( accountId ) { const accountInfo = await this . connection . getAccountInfo ( accountId , this . opts . commitment ) ; if ( ! accountInfo ) { return null ; } return { accountId , accountInfo , } ; } } /**
 * Signs Solana transactions.
 */ export class SolanaTransactionSigner implements TransactionSigner { constructor ( readonly wallet , readonly broadcaster , readonly preflightCommitment = "processed" ) { } get publicKey ( ) : PublicKey { return this . wallet . publicKey ; } param tx param signers param opts async sign ( tx , signers = [ ] , opts = { preflightCommitment : this . preflightCommitment , } ) { tx . feePayer = this . wallet . publicKey ; tx . recentBlockhash = await this . broadcaster . getRecentBlockhash ( opts . preflightCommitment ) ; await this . wallet . signTransaction ( tx ) ; signers . filter ( ( s ) : s is Signer => s !== undefined ) . forEach ( ( kp ) => { tx . partialSign ( kp ) ; } ) ; return tx ; } /**
     * Similar to `send`, but for an array of transactions and signers.
     */ async signAll ( reqs , opts = { preflightCommitment : this . preflightCommitment , } ) { const blockhash = await this . broadcaster . getRecentBlockhash ( opts . preflightCommitment ) ; const txs = reqs . map ( ( r ) => { const tx = r . tx ; let signers = r . signers ; if ( signers === undefined ) { signers = [ ] ; } tx . feePayer = this . wallet . publicKey ; tx . recentBlockhash = blockhash ; signers . filter ( ( s ) : s is Signer => s !== undefined ) . forEach ( ( kp ) => { tx . partialSign ( kp ) ; } ) ; return tx ; } ) ; const signedTxs = await this . wallet . signAllTransactions ( txs ) ; return signedTxs ; } } /**
 * The network and wallet context used to send transactions paid for and signed
 * by the provider.
 *
 * This implementation was taken from Anchor.
 */ export class SolanaProvider extends SolanaReadonlyProvider implements Provider { readonly signer : TransactionSigner ; param connection param sendConnection param wallet param opts constructor ( override readonly connection , readonly broadcaster , readonly wallet , override readonly opts = DEFAULT_PROVIDER_OPTIONS ) { super ( connection , opts ) ; this . signer = new SolanaTransactionSigner ( wallet , broadcaster , opts . preflightCommitment ) ; } deprecated use  SolanaProvider . init static load ( { connection , sendConnection = connection , wallet , opts , } ) { return new SolanaProvider ( connection , new SingleConnectionBroadcaster ( sendConnection , opts ) , wallet , opts ) ; } /**
     * Initializes a new SolanaProvider.
     */ static init ( { connection , broadcastConnections = [ connection ] , wallet , opts = DEFAULT_PROVIDER_OPTIONS , } ) { return new SolanaProvider ( connection , new MultipleConnectionBroadcaster ( broadcastConnections , opts ) , wallet , opts ) ; } param tx param signers param opts async send ( tx , signers = [ ] , opts = this . opts ) { const theTx = await this . signer . sign ( tx , signers , opts ) ; const pending = await this . broadcaster . broadcast ( theTx , opts ) ; await pending . wait ( ) ; return pending ; } /**
     * Similar to `send`, but for an array of transactions and signers.
     */ async sendAll ( reqs , opts = this . opts ) { const txs = await this . signer . signAll ( reqs , opts ) ; return await Promise . all ( txs . map ( async ( tx ) => { const pending = await this . broadcaster . broadcast ( tx , opts ) ; await pending . wait ( ) ; return pending ; } ) ) ; } param tx param signers param opts async simulate ( tx , signers , opts = this . opts ) { let simTX = tx ; if ( signers !== undefined ) { simTX = await this . signer . sign ( tx , signers , opts ) ; } return await this . broadcaster . simulate ( simTX , { verifySigners : signers !== undefined , commitment : opts . commitment , } ) ; } } /**
 * Provider with utility functions.
 */ export interface AugmentedProvider extends Provider { param instructions param signers returns newTX : ( instructions : ( TransactionInstruction | null | undefined | boolean ) [ ] , signers ? : Signer [ ] ) => TransactionEnvelope ; param lamports returns requestAirdrop : ( lamports : number ) => Promise < PendingTransaction > ; param signer returns withSigner : ( signer : Signer ) => AugmentedProvider ; } /**
 * Wrapper for a Provider containing utility functions.
 */ export class SolanaAugmentedProvider implements AugmentedProvider { constructor ( readonly provider ) { } get connection ( ) : Connection { return this . provider . connection ; } get signer ( ) : TransactionSigner { return this . provider . signer ; } get broadcaster ( ) : Broadcaster { return this . provider . broadcaster ; } get opts ( ) : ConfirmOptions { return this . provider . opts ; } get wallet ( ) : Wallet { return this . provider . wallet ; } send ( tx , signers ? , opts ? ) { return this . provider . send ( tx , signers , opts ) ; } sendAll ( reqs , opts ? ) { return this . provider . sendAll ( reqs , opts ) ; } simulate ( tx , signers ? , opts ? ) { return this . provider . simulate ( tx , signers , opts ) ; } getAccountInfo ( accountId ) { return this . provider . getAccountInfo ( accountId ) ; } param instructions param signers returns newTX ( instructions , signers = [ ] ) { return TransactionEnvelope . create ( this , instructions , signers ) ; } param amount returns async requestAirdrop ( lamports , to = this . wallet . publicKey ) { return new PendingTransaction ( this . connection , await this . connection . requestAirdrop ( to , lamports ) ) ; } param signer returns withSigner ( signer ) { return new SolanaAugmentedProvider ( new SolanaProvider ( this . connection , this . broadcaster , new SignerWallet ( signer ) , this . opts ) ) ; } }