β½Scale by Solana at Solana
Dispersing SOL to 10,000 users in <120 seconds
import { Commitment, Keypair, LAMPORTS_PER_SOL, Signer, Transaction, } from "@solana/web3.js"; import { ConnectionManager, Disperse, TransactionBuilder, TransactionWrapper, Logger } from "@solworks/soltoolkit-sdk";
const COMMITMENT: Commitment = "confirmed"; const NO_OF_RECEIVERS = 10_000; const CHUNK_SIZE = 30; const TOTAL_SOL = 10;
const SKIP_AIRDROP = true; const SKIP_SENDING = false; const SKIP_BALANCE_CHECK = true;
// generate keypair for example const sender = Keypair.fromSecretKey( Uint8Array.from([ 36, 50, 153, 146, 147, 239, 210, 72, 199, 68, 75, 220, 42, 139, 105, 61, 148, 117, 55, 75, 23, 144, 30, 206, 138, 255, 51, 206, 102, 239, 73, 28, 240, 73, 69, 190, 238, 27, 112, 36, 151, 255, 182, 64, 13, 173, 94, 115, 111, 45, 2, 154, 250, 93, 100, 44, 251, 111, 229, 34, 193, 249, 199, 238, ]) );
(async () => { const logger = new Logger("example");
// create connection manager const cm = await ConnectionManager.getInstance({ commitment: COMMITMENT, endpoints: [ "https://mango.devnet.rpcpool.com",
// https://docs.solana.com/cluster/rpc-endpoints
// Maximum number of requests per 10 seconds per IP: 100 (10/s)
// Maximum number of requests per 10 seconds per IP for a single RPC: 40 (4/s)
// Maximum concurrent connections per IP: 40
// Maximum connection rate per 10 seconds per IP: 40
// Maximum amount of data per 30 second: 100 MB
// "https://api.devnet.solana.com",
// https://shdw.genesysgo.com/genesysgo/the-genesysgo-rpc-network
// SendTransaction Limit: 10 RPS + 200 Burst
// getProgramAccounts Limit: 15 RPS + 5 burst
// Global Limit on the rest of the calls: 200 RPS
"https://devnet.genesysgo.net",
],
mode: "round-robin",
network: "devnet",});
if (!SKIP_AIRDROP) { // airdrop 1 sol to new addresses, confirm and send sol to SENDER for (let i = 0; i < Math.ceil((TOTAL_SOL + 1) / 1); i++) { // generate new keypair const keypair = Keypair.generate();
}
// fetch balance of the generated address logger.debug("Fetching balance of", sender.publicKey.toBase58()); let senderBal = await cm // default value for changeConn = true .connSync({ changeConn: true }) .getBalance(sender.publicKey, COMMITMENT); logger.debug(Sender balance: ${senderBal});
// generate receivers logger.debug(Generating ${NO_OF_RECEIVERS} receivers...); const receivers: Keypair[] = []; for (let i = 0; i < NO_OF_RECEIVERS; i++) { receivers.push(Keypair.generate()); } logger.debug("Receivers generated");
// generate transactions const transfers: { amount: number; recipient: string; }[] = [];
const rentCost = (NO_OF_RECEIVERS+1) * 5_000; const transferAmount = Math.floor( (senderBal - rentCost) / NO_OF_RECEIVERS ); logger.debug(Sending ${transferAmount} to ${NO_OF_RECEIVERS} receivers); for (let i = 0; i < NO_OF_RECEIVERS; i++) { transfers.push({ amount: transferAmount, recipient: receivers[i].publicKey.toBase58(), }); }
// send transactions if (!SKIP_SENDING) { const transactions = await Disperse.create({ tokenType: "SOL", sender: sender.publicKey, transfers, }).generateTransactions();
}
if (!SKIP_BALANCE_CHECK) { // fetch balance of the generated address logger.debug("Fetching balance of:", sender.publicKey.toBase58()); senderBal = await cm .connSync({ changeConn: true }) .getBalance(sender.publicKey, COMMITMENT); logger.debug(Sender balance: ${senderBal});
} })();
function chunk(arr: any[], len: number) { var chunks: any[] = [], i = 0, n = arr.length;
while (i < n) { chunks.push(arr.slice(i, (i += len))); } return chunks; }
function sleep(ms: number) { return new Promise((resolve) => setTimeout(resolve, ms)); }
Last updated