├── .gitignore ├── 0.1.chain-block.ts ├── 1.1.wallet-generate.ts ├── 1.2.wallet-privatekey.ts ├── 1.3.wallet-balance.ts ├── 2.1.token-decimals.ts ├── 2.2.token-symbol.ts ├── 2.3.token-balance.ts ├── 2.4.token-all-balances.ts ├── 3.1.transaction-sol-raw.ts ├── 3.1.transaction-sol.ts ├── 3.2.transaction-confirm.ts ├── 3.3.transaction-waiter.ts ├── README.md ├── env ├── package.json └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore 2 | 3 | # Logs 4 | 5 | logs 6 | _.log 7 | npm-debug.log_ 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | .pnpm-debug.log* 12 | 13 | # Caches 14 | 15 | .cache 16 | 17 | # Diagnostic reports (https://nodejs.org/api/report.html) 18 | 19 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 20 | 21 | # Runtime data 22 | 23 | pids 24 | _.pid 25 | _.seed 26 | *.pid.lock 27 | 28 | # Directory for instrumented libs generated by jscoverage/JSCover 29 | 30 | lib-cov 31 | 32 | # Coverage directory used by tools like istanbul 33 | 34 | coverage 35 | *.lcov 36 | 37 | # nyc test coverage 38 | 39 | .nyc_output 40 | 41 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 42 | 43 | .grunt 44 | 45 | # Bower dependency directory (https://bower.io/) 46 | 47 | bower_components 48 | 49 | # node-waf configuration 50 | 51 | .lock-wscript 52 | 53 | # Compiled binary addons (https://nodejs.org/api/addons.html) 54 | 55 | build/Release 56 | 57 | # Dependency directories 58 | 59 | node_modules/ 60 | jspm_packages/ 61 | 62 | # Snowpack dependency directory (https://snowpack.dev/) 63 | 64 | web_modules/ 65 | 66 | # TypeScript cache 67 | 68 | *.tsbuildinfo 69 | 70 | # Optional npm cache directory 71 | 72 | .npm 73 | 74 | # Optional eslint cache 75 | 76 | .eslintcache 77 | 78 | # Optional stylelint cache 79 | 80 | .stylelintcache 81 | 82 | # Microbundle cache 83 | 84 | .rpt2_cache/ 85 | .rts2_cache_cjs/ 86 | .rts2_cache_es/ 87 | .rts2_cache_umd/ 88 | 89 | # Optional REPL history 90 | 91 | .node_repl_history 92 | 93 | # Output of 'npm pack' 94 | 95 | *.tgz 96 | 97 | # Yarn Integrity file 98 | 99 | .yarn-integrity 100 | 101 | # dotenv environment variable files 102 | 103 | .env 104 | .env.development.local 105 | .env.test.local 106 | .env.production.local 107 | .env.local 108 | 109 | # parcel-bundler cache (https://parceljs.org/) 110 | 111 | .parcel-cache 112 | 113 | # Next.js build output 114 | 115 | .next 116 | out 117 | 118 | # Nuxt.js build / generate output 119 | 120 | .nuxt 121 | dist 122 | 123 | # Gatsby files 124 | 125 | # Comment in the public line in if your project uses Gatsby and not Next.js 126 | 127 | # https://nextjs.org/blog/next-9-1#public-directory-support 128 | 129 | # public 130 | 131 | # vuepress build output 132 | 133 | .vuepress/dist 134 | 135 | # vuepress v2.x temp and cache directory 136 | 137 | .temp 138 | 139 | # Docusaurus cache and generated files 140 | 141 | .docusaurus 142 | 143 | # Serverless directories 144 | 145 | .serverless/ 146 | 147 | # FuseBox cache 148 | 149 | .fusebox/ 150 | 151 | # DynamoDB Local files 152 | 153 | .dynamodb/ 154 | 155 | # TernJS port file 156 | 157 | .tern-port 158 | 159 | # Stores VSCode versions used for testing VSCode extensions 160 | 161 | .vscode-test 162 | 163 | # yarn v2 164 | 165 | .yarn/cache 166 | .yarn/unplugged 167 | .yarn/build-state.yml 168 | .yarn/install-state.gz 169 | .pnp.* 170 | 171 | # IntelliJ based IDEs 172 | .idea 173 | 174 | # Finder (MacOS) folder config 175 | .DS_Store 176 | 177 | bun.lockb 178 | -------------------------------------------------------------------------------- /0.1.chain-block.ts: -------------------------------------------------------------------------------- 1 | import { Connection } from "@solana/web3.js"; 2 | 3 | const connection = new Connection(process.env.RPC); 4 | 5 | let res = await connection.getBlockHeight(); 6 | console.log("block height res", res, new Date()); 7 | 8 | // let resBlock = await connection.getBlock(269332927, { 9 | // maxSupportedTransactionVersion: 0, 10 | // }); 11 | // console.log("block res", resBlock); 12 | -------------------------------------------------------------------------------- /1.1.wallet-generate.ts: -------------------------------------------------------------------------------- 1 | import web3 from "@solana/web3.js"; 2 | import { createPrivateKey } from "crypto"; 3 | import bs58 from "bs58"; 4 | 5 | let keypair = web3.Keypair.generate(); 6 | console.log("generate wallet account"); 7 | 8 | let address = keypair.publicKey.toBase58(); 9 | console.log("wallet address : ", address); 10 | 11 | let secretKey = keypair.secretKey; 12 | console.log("wallet privateKey: ", secretKey); 13 | console.log("wallet privateKey base58:", bs58.encode(secretKey)); 14 | -------------------------------------------------------------------------------- /1.2.wallet-privatekey.ts: -------------------------------------------------------------------------------- 1 | import web3 from "@solana/web3.js"; 2 | import bs58 from "bs58"; 3 | 4 | let wallet = web3.Keypair.fromSecretKey( 5 | bs58.decode(process.env.PRIVATE_KEY || ""), 6 | ); 7 | 8 | console.log("wallet", wallet.publicKey.toBase58()); 9 | -------------------------------------------------------------------------------- /1.3.wallet-balance.ts: -------------------------------------------------------------------------------- 1 | import { Connection, PublicKey } from "@solana/web3.js"; 2 | 3 | const connection = new Connection(process.env.RPC); 4 | 5 | const mintAddress = new PublicKey( 6 | "So11111111111111111111111111111111111111112", 7 | ); 8 | 9 | let balance = await connection.getBalance(mintAddress); 10 | console.log("sol balance", balance); 11 | 12 | const pubkey = new PublicKey(process.env.PUBLIC_KEY); 13 | await connection.requestAirdrop(pubkey, 1 * 10 ** 9); 14 | console.log("pubkey balance", await connection.getBalance(pubkey)); 15 | // console.log("pubkey account", await connection.getAccountInfo(pubkey)); 16 | -------------------------------------------------------------------------------- /2.1.token-decimals.ts: -------------------------------------------------------------------------------- 1 | import { Connection, PublicKey } from "@solana/web3.js"; 2 | 3 | const connection = new Connection(process.env.RPC); 4 | const mintAddress = new PublicKey( 5 | "So11111111111111111111111111111111111111112", 6 | ); 7 | 8 | const tokenInfo = await connection.getParsedAccountInfo(mintAddress); 9 | console.log("token decimals", tokenInfo.value.data.parsed.info.decimals); 10 | -------------------------------------------------------------------------------- /2.2.token-symbol.ts: -------------------------------------------------------------------------------- 1 | import { Connection, PublicKey } from "@solana/web3.js"; 2 | import { Metaplex } from "@metaplex-foundation/js"; 3 | import meta from "@metaplex-foundation/mpl-token-metadata"; 4 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 5 | 6 | const connection = new Connection(process.env.RPC); 7 | const mintAddress = new PublicKey( 8 | "So11111111111111111111111111111111111111112", 9 | ); 10 | 11 | const metaplex = Metaplex.make(connection); 12 | console.log("mint", mintAddress.toBase58()); 13 | 14 | const umi = createUmi("https://api.mainnet-beta.solana.com"); 15 | 16 | const metadataPda = metaplex.nfts().pdas().metadata({ mint: mintAddress }); 17 | console.log("pda", metadataPda.toBase58()); 18 | 19 | let ret = await meta.fetchMetadata(umi, metadataPda); 20 | console.log("symbol", ret.symbol); 21 | console.log("name", ret.name); 22 | -------------------------------------------------------------------------------- /2.3.token-balance.ts: -------------------------------------------------------------------------------- 1 | import { Connection, PublicKey } from "@solana/web3.js"; 2 | 3 | const connection = new Connection("https://api.mainnet-beta.solana.com"); 4 | 5 | const pubkey = new PublicKey("J3y4VWneyFZEqvemxi7uUViPjkmXzsZ8r9d4YwgwHTFh"); 6 | 7 | const mintAddress = new PublicKey( 8 | "8wXtPeU6557ETkp9WHFY1n1EcU6NxDvbAggHGsMYiHsB", 9 | ); 10 | 11 | let accounts = await connection.getTokenAccountsByOwner(pubkey, { 12 | mint: mintAddress, 13 | }); 14 | 15 | console.log("token accounts ", accounts.value[0].pubkey.toBase58()); 16 | 17 | let balance = await connection.getTokenAccountBalance(accounts.value[0].pubkey); 18 | console.log("token accounts balance", balance.value.uiAmount); 19 | -------------------------------------------------------------------------------- /2.4.token-all-balances.ts: -------------------------------------------------------------------------------- 1 | import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; 2 | import { Connection, PublicKey } from "@solana/web3.js"; 3 | 4 | const connection = new Connection("https://api.mainnet-beta.solana.com"); 5 | 6 | const pubkey = new PublicKey("J3y4VWneyFZEqvemxi7uUViPjkmXzsZ8r9d4YwgwHTFh"); 7 | 8 | let accounts = await connection.getTokenAccountsByOwner(pubkey, { 9 | programId: TOKEN_PROGRAM_ID, 10 | }); 11 | 12 | console.log("token accounts ", accounts); 13 | console.log("token accounts ", accounts.value[0].pubkey.toBase58()); 14 | 15 | let balance = await connection.getTokenAccountBalance(accounts.value[0].pubkey); 16 | console.log("token accounts balance", balance.value.uiAmount); 17 | -------------------------------------------------------------------------------- /3.1.transaction-sol-raw.ts: -------------------------------------------------------------------------------- 1 | import web3, { Connection } from "@solana/web3.js"; 2 | import base58 from "bs58"; 3 | 4 | const connection = new Connection(process.env.RPC); 5 | const fromWallet = web3.Keypair.fromSecretKey( 6 | base58.decode(process.env.PRIVATE_KEY), 7 | ); 8 | console.log("from wallet", fromWallet.publicKey.toBase58()); 9 | 10 | // request airdop 1 sol to fromWallet 11 | 12 | // try { 13 | // let txhash = await connection.requestAirdrop(fromWallet.publicKey, 1e9); 14 | // console.log(`airdrop txhash: ${txhash}`); 15 | // } catch (err) { 16 | // console.error(err); 17 | // } 18 | 19 | const toPublicKey = new web3.PublicKey(process.env.PUBLIC_KEY); 20 | 21 | let oldBalance = await connection.getBalance(fromWallet.publicKey); 22 | console.log("old balance", oldBalance); 23 | 24 | const addPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({ 25 | microLamports: 1, 26 | }); 27 | 28 | const transaction = new web3.Transaction().add( 29 | web3.SystemProgram.transfer({ 30 | fromPubkey: fromWallet.publicKey, 31 | toPubkey: toPublicKey, 32 | lamports: 10 ** 9 * 0.003, 33 | }), 34 | ); 35 | transaction.sign(fromWallet); 36 | const signature = await connection.sendRawTransaction(transaction.serialize()); 37 | console.log("signature", signature); 38 | 39 | await connection.confirmTransaction(signature, "confirmed"); 40 | // let tx = await connection.getTransaction(signature); 41 | // console.log("transaction", tx); 42 | 43 | let newBalance = await connection.getBalance(fromWallet.publicKey); 44 | console.log("new balance", newBalance); 45 | 46 | await Bun.sleep(1000); 47 | newBalance = await connection.getBalance(fromWallet.publicKey); 48 | console.log("new balance", newBalance); 49 | 50 | await Bun.sleep(1000); 51 | newBalance = await connection.getBalance(fromWallet.publicKey); 52 | console.log("new balance", newBalance); 53 | -------------------------------------------------------------------------------- /3.1.transaction-sol.ts: -------------------------------------------------------------------------------- 1 | import web3, { Connection } from "@solana/web3.js"; 2 | import base58 from "bs58"; 3 | 4 | const connection = new Connection(process.env.RPC); 5 | const fromWallet = web3.Keypair.fromSecretKey( 6 | base58.decode(process.env.PRIVATE_KEY), 7 | ); 8 | console.log("from wallet", fromWallet.publicKey.toBase58()); 9 | 10 | // request airdop 1 sol to fromWallet 11 | 12 | // try { 13 | // let txhash = await connection.requestAirdrop(fromWallet.publicKey, 1e9); 14 | // console.log(`airdrop txhash: ${txhash}`); 15 | // } catch (err) { 16 | // console.error(err); 17 | // } 18 | 19 | const toPublicKey = new web3.PublicKey(process.env.PUBLIC_KEY); 20 | 21 | let oldBalance = await connection.getBalance(fromWallet.publicKey); 22 | console.log("old balance", oldBalance); 23 | 24 | const modifyComputeUnits = ComputeBudgetProgram.setComputeUnitLimit({ 25 | units: 1000000, 26 | }); 27 | 28 | const addPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({ 29 | microLamports: 1, 30 | }); 31 | 32 | const transaction = new web3.Transaction().add( 33 | web3.SystemProgram.transfer({ 34 | fromPubkey: fromWallet.publicKey, 35 | toPubkey: toPublicKey, 36 | lamports: 10 ** 9 * 0.003, 37 | }), 38 | ); 39 | 40 | const { value: simulatedTransactionResponse } = 41 | await connection.simulateTransaction(transaction, [fromWallet]); 42 | const { err, logs } = simulatedTransactionResponse; 43 | console.log("sim logs", logs); 44 | 45 | const signature = await connection.sendTransaction(transaction, [fromWallet]); 46 | console.log("signature", signature); 47 | 48 | await connection.confirmTransaction(signature, "confirmed"); 49 | // let tx = await connection.getTransaction(signature); 50 | // console.log("transaction", tx); 51 | 52 | let newBalance = await connection.getBalance(fromWallet.publicKey); 53 | console.log("new balance", newBalance); 54 | 55 | await Bun.sleep(1000); 56 | newBalance = await connection.getBalance(fromWallet.publicKey); 57 | console.log("new balance", newBalance); 58 | 59 | await Bun.sleep(1000); 60 | newBalance = await connection.getBalance(fromWallet.publicKey); 61 | console.log("new balance", newBalance); 62 | -------------------------------------------------------------------------------- /3.2.transaction-confirm.ts: -------------------------------------------------------------------------------- 1 | import web3, { Connection } from "@solana/web3.js"; 2 | import base58 from "bs58"; 3 | const connection = new Connection(process.env.RPC); 4 | 5 | let signature = 6 | "3kzj4DLm7HUf2yHs4umYcJBbXWM2hzF1VkgT1HKRQAXUw3FkPL9u37CUMuWidCfVHrxtryE4JL4TquaYA1e8ZNA2"; 7 | let status = await connection.getSignatureStatus(signature, { 8 | searchTransactionHistory: true, 9 | }); 10 | 11 | console.log("signature", status?.value?.confirmationStatus || status); 12 | 13 | let tx = await connection.getTransaction(signature, { 14 | maxSupportedTransactionVersion: 0, 15 | }); 16 | console.log("confirmed tx", tx); 17 | -------------------------------------------------------------------------------- /3.3.transaction-waiter.ts: -------------------------------------------------------------------------------- 1 | import { Connection } from "@solana/web3.js"; 2 | 3 | const connection = new Connection(process.env.RPC); 4 | 5 | // await Promise.race([connection.confirmTransaction({ 6 | // blockhash: 7 | // })]); 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # useful solana-web3 script 2 | 3 | `copy and paste` Or `run in shell` 4 | 5 | 常用solana web3脚本(可复用或直接运行) 6 | 7 | 1. account manage & balance - 帐号管理和余额查询 8 | 2. token info & balance - token信息和余额查询 9 | 3. transaction - 交易 10 | 11 | ## how to use 12 | 1. To install dependencies: 13 | 14 | ```bash 15 | bun install 16 | ``` 17 | 18 | 2. Set Env 19 | ```bash 20 | cp env .env 21 | ``` 22 | 23 | 24 | ``` 25 | # 私钥,用于发送交易 26 | PRIVATE_KEY= 27 | # 另一个钱包公钥,接收交易 28 | PUBLIC_KEY=92U3aM8kRqihutqFWNDGxmWXxMHDrnAyFEMYXcKmvKcD 29 | # 开发或测试网rpc 30 | RPC=https://api.devnet.solana.com 31 | ``` 32 | 33 | 3. To run: 34 | 35 | ```bash 36 | bun run ***.ts 37 | ``` 38 | -------------------------------------------------------------------------------- /env: -------------------------------------------------------------------------------- 1 | PRIVATE_KEY= 2 | PUBLIC_KEY=92U3aM8kRqihutqFWNDGxmWXxMHDrnAyFEMYXcKmvKcD 3 | RPC=https://api.devnet.solana.com 4 | #RPC=https://api.mainnet-beta.solana.com 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "solana-web3", 3 | "module": "index.ts", 4 | "type": "module", 5 | "devDependencies": { 6 | "@types/bun": "latest" 7 | }, 8 | "peerDependencies": { 9 | "typescript": "^5.0.0" 10 | }, 11 | "dependencies": { 12 | "@metaplex-foundation/js": "^0.20.1", 13 | "@metaplex-foundation/mpl-token-metadata": "^3.2.1", 14 | "@metaplex-foundation/umi": "^0.9.1", 15 | "@metaplex-foundation/umi-bundle-defaults": "^0.9.1", 16 | "@solana/spl-token": "^0.4.6", 17 | "@solana/web3.js": "^1.91.8", 18 | "bs58": "^5.0.0" 19 | } 20 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | // Enable latest features 4 | "lib": ["ESNext", "DOM"], 5 | "target": "ESNext", 6 | "module": "ESNext", 7 | "moduleDetection": "force", 8 | "jsx": "react-jsx", 9 | "allowJs": true, 10 | 11 | // Bundler mode 12 | "moduleResolution": "bundler", 13 | "allowImportingTsExtensions": true, 14 | "verbatimModuleSyntax": true, 15 | "noEmit": true, 16 | 17 | // Best practices 18 | "strict": true, 19 | "skipLibCheck": true, 20 | "noFallthroughCasesInSwitch": true, 21 | 22 | // Some stricter flags (disabled by default) 23 | "noUnusedLocals": false, 24 | "noUnusedParameters": false, 25 | "noPropertyAccessFromIndexSignature": false 26 | } 27 | } 28 | --------------------------------------------------------------------------------