| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- // SPDX-License-Identifier: Apache-2.0
- import { Connection, Keypair, LAMPORTS_PER_SOL, PublicKey, BpfLoader, Transaction, SystemProgram, BPF_LOADER_PROGRAM_ID, TransactionExpiredBlockheightExceededError } from '@solana/web3.js';
- import { AnchorProvider, Program } from '@coral-xyz/anchor';
- import fs from 'fs';
- const endpoint: string = process.env.RPC_URL || "http://127.0.0.1:8899";
- export async function loadContractAndCallConstructor(name: string, args: any[] = [], space: number = 8192):
- Promise<{ program: Program, payer: Keypair, provider: AnchorProvider, storage: Keypair, program_key: PublicKey }> {
- const {program, payer, provider, program_key} = await loadContract(name);
- const storage = Keypair.generate();
- await create_account(storage, program_key, space);
- await program.methods.new(...args)
- .accounts({ dataAccount: storage.publicKey })
- .rpc();
- return { provider, program, payer, storage, program_key: program_key };
- }
- export async function loadContract(name: string):
- Promise<{program: Program, payer: Keypair, provider: AnchorProvider, program_key: PublicKey}> {
- const idl = JSON.parse(fs.readFileSync(`${name}.json`, 'utf8'));
- const payer = loadKey('payer.key');
- process.env['ANCHOR_WALLET'] = 'payer.key';
- const provider = AnchorProvider.local(endpoint);
- const program_key = loadKey(`${name}.key`);
- const program = new Program(idl, program_key.publicKey, provider)
- return {program, payer, provider, program_key: program_key.publicKey};
- }
- export async function create_account(account: Keypair, programId: PublicKey, space: number) {
- const provider = AnchorProvider.local(endpoint);
- const lamports = await provider.connection.getMinimumBalanceForRentExemption(space);
- const transaction = new Transaction();
- transaction.add(
- SystemProgram.createAccount({
- fromPubkey: provider.wallet.publicKey,
- newAccountPubkey: account.publicKey,
- lamports,
- space,
- programId,
- }));
- await provider.sendAndConfirm(transaction, [account]);
- }
- export function newConnectionAndPayer(): [Connection, Keypair] {
- const connection = newConnection();
- const payerAccount = loadKey('payer.key');
- return [connection, payerAccount];
- }
- export async function loadContractWithProvider(provider: AnchorProvider, name: string, args: any[] = [], space: number = 8192):
- Promise<{ program: Program, storage: Keypair, program_key: PublicKey }> {
- const idl = JSON.parse(fs.readFileSync(`${name}.json`, 'utf8'));
- const storage = Keypair.generate();
- const program_key = loadKey(`${name}.key`);
- await create_account(storage, program_key.publicKey, space);
- const program = new Program(idl, program_key.publicKey, provider);
- await program.methods.new(...args)
- .accounts({ dataAccount: storage.publicKey })
- .rpc();
- return { program, storage, program_key: program_key.publicKey };
- }
- function loadKey(filename: string): Keypair {
- const contents = fs.readFileSync(filename).toString();
- const bs = Uint8Array.from(JSON.parse(contents));
- return Keypair.fromSecretKey(bs);
- }
- async function newAccountWithLamports(connection: Connection): Promise<Keypair> {
- const account = Keypair.generate();
- console.log('Airdropping SOL to a new wallet ...');
- let signature = await connection.requestAirdrop(account.publicKey, 100 * LAMPORTS_PER_SOL);
- const latestBlockHash = await connection.getLatestBlockhash();
- await connection.confirmTransaction({
- blockhash: latestBlockHash.blockhash,
- lastValidBlockHeight: latestBlockHash.lastValidBlockHeight,
- signature,
- }, 'confirmed');
- return account;
- }
- async function setup() {
- let write_key = (file_name: string, key: Keypair) => {
- fs.writeFileSync(file_name, JSON.stringify(Array.from(key.secretKey)));
- };
- let connection = newConnection();
- const payer = await newAccountWithLamports(connection);
- write_key('payer.key', payer);
- let files = fs.readdirSync(__dirname);
- for (let index in files) {
- let file = files[index];
- if (file.endsWith('.so')) {
- let name = file.slice(0, -3);
- let program;
- if (fs.existsSync(`${name}.key`)) {
- program = loadKey(`${name}.key`);
- } else {
- program = Keypair.generate();
- }
- console.log(`Loading ${name} at ${program.publicKey}...`);
- const program_so = fs.readFileSync(file);
- for (let retries = 5; retries > 0; retries -= 1) {
- try {
- await BpfLoader.load(connection, payer, program, program_so, BPF_LOADER_PROGRAM_ID);
- break;
- } catch (e) {
- if (e instanceof TransactionExpiredBlockheightExceededError) {
- console.log(e);
- console.log('retrying...');
- connection = newConnection();
- } else {
- throw e;
- }
- }
- }
- console.log(`Done loading ${name} ...`);
- write_key(`${name}.key`, program);
- }
- }
- // If there was a TransactionExpiredBlockheightExceededError exception, then
- // setup.ts does not exit. I have no idea why
- process.exit();
- }
- function newConnection(): Connection {
- return new Connection(endpoint, {
- commitment: "confirmed",
- confirmTransactionInitialTimeout: 1e6,
- });
- }
- if (require.main === module) {
- (async () => {
- await setup();
- })();
- }
|