Skip to content

Instantly share code, notes, and snippets.

@anonymoussprocket
Last active December 15, 2019 18:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymoussprocket/941a83d2e2395614d3db7c319087795b to your computer and use it in GitHub Desktop.
Save anonymoussprocket/941a83d2e2395614d3db7c319087795b to your computer and use it in GitHub Desktop.
Tezos testnet balance accumulator

Purpose

A quick way to transfer balances from multiple testnet faucet files to a target account. This is useful for example if you would like to run a baker.

Requirements

nodejs 10.17+.

Usage

  1. Save index.ts and package.json into a folder on your machine
  2. Set the tezosNode, conseilServer, baker params accordingly. Get an acccount on Nautilus Cloud if you do not have access to such infrastructure already.
  3. From the console in that same directory run npm install and then npm start.
  4. Wait for the process to complete and check the updated balance on mininax or your favorite block explorer.

You can run this process as many times as needed with a new set of files. Subsequent runs can be done with just npm start unless you're modifying any of the parameters.

Use delegateAccount instead of sendTransaction if you want to retain the balance in the accounts instead of transferring to the baker.

import * as fs from 'fs';
import * as glob from 'glob';
import { TezosConseilClient, TezosWalletUtil, TezosNodeWriter, TezosProtocolHelper, setLogLevel, TezosParameterFormat, KeyStore, OperationKindType, TezosNodeReader, ConseilDataClient, ConseilQueryBuilder, ConseilSortDirection, ConseilOperator } from 'conseiljs';
setLogLevel('error');
const tezosNode = '...';
const conseilServer = { url: '...', apiKey: '...', network: '...' };
const baker = '...';
const networkBlockTime = 30 + 1;
function clearRPCOperationGroupHash(hash: string) {
return hash.replace(/\"/g, '').replace(/\n/, '');
}
async function initAccount(faucetAccount): Promise<KeyStore> {
console.log('~~ initAccount');
const keystore = await TezosWalletUtil.unlockFundraiserIdentity(faucetAccount['mnemonic'].join(' '), faucetAccount['email'], faucetAccount['password'], faucetAccount['pkh']);
console.log(`public key: ${keystore.publicKey}`);
console.log(`secret key: ${keystore.privateKey}`);
console.log(`account hash: ${keystore.publicKeyHash}`);
return keystore;
}
async function activateAccount(keystore: KeyStore, secret: string): Promise<string> {
console.log(`~~ activateAccount`);
const accountRecord = await TezosConseilClient.getAccount(conseilServer, conseilServer.network, keystore.publicKeyHash);
if (accountRecord.length === 1) { return accountRecord[0]['account_id']; }
const nodeResult = await TezosNodeWriter.sendIdentityActivationOperation(tezosNode, keystore, secret);
const groupid = clearRPCOperationGroupHash(nodeResult.operationGroupID);
console.log(`Injected activation operation with ${groupid}`);
const conseilResult = await TezosConseilClient.awaitOperationConfirmation(conseilServer, conseilServer.network, groupid, 5, networkBlockTime);
console.log(`Activated account at ${conseilResult[0].pkh}`);
console.log(conseilResult[0]);
return conseilResult[0].pkh;
}
async function revealAccount(keystore: KeyStore): Promise<number> {
console.log(`~~ revealAccount`);
if (!(await TezosNodeReader.isManagerKeyRevealedForAccount(tezosNode, keystore.publicKeyHash))) {
const nodeResult = await TezosNodeWriter.sendKeyRevealOperation(tezosNode, keystore);
const groupid = clearRPCOperationGroupHash(nodeResult.operationGroupID);
console.log(`Injected reveal operation with ${groupid}`);
let conseilResult = await TezosConseilClient.awaitOperationConfirmation(conseilServer, conseilServer.network, groupid, 5, networkBlockTime);
console.log(`Revealed account at ${conseilResult[0].source}`);
}
let conseilResult = await TezosConseilClient.getAccount(conseilServer, conseilServer.network, keystore.publicKeyHash);
return conseilResult[0]['balance'];
}
async function sendTransaction(keystore: KeyStore, accountAddress: string, amount: number) {
console.log(`~~ sendTransaction: ${amount}µtz from ${keystore.publicKeyHash} into ${accountAddress}`);
const nodeResult = await TezosNodeWriter.sendTransactionOperation(tezosNode, keystore, accountAddress, amount, 15000, '');
const groupid = clearRPCOperationGroupHash(nodeResult.operationGroupID);
console.log(`Injected transaction operation with ${groupid}`);
const conseilResult = await TezosConseilClient.awaitOperationConfirmation(conseilServer, conseilServer.network, groupid, 5, networkBlockTime);
console.log(`Completed transfer of ${conseilResult[0].amount}µtz`);
}
async function delegateAccount(keystore: KeyStore, accountAddress: string) {
console.log(`~~ delegateAccount`);
const nodeResult = await TezosProtocolHelper.setDelegate(tezosNode, keystore, keystore.publicKeyHash, accountAddress, 20000);
const groupid = clearRPCOperationGroupHash(nodeResult.operationGroupID);
console.log(`Injected delegation operation with ${groupid}`);
await TezosConseilClient.awaitOperationConfirmation(conseilServer, conseilServer.network, groupid, 5, networkBlockTime);
}
async function run() {
let faucetFiles: string[] = glob.sync('tz1*.json');
if (faucetFiles.length === 0) {
throw new Error('Did not find any faucet files, please go to faucet.tzalpha.net to get one or 50');
} else {
console.log(`found ${faucetFiles.length} faucet files`);
}
await Promise.all(faucetFiles.map(async file => {
const faucetAccount = JSON.parse(fs.readFileSync(file, 'utf8'));
const keyStore = await initAccount(faucetAccount);
await activateAccount(keyStore, faucetAccount['secret']);
const amount = await revealAccount(keyStore);
await sendTransaction(keyStore, baker, amount - 1000000);
}));
}
run();
{
"name": "tezos-balance-accumulator",
"version": "0.0.1",
"description": "Tezos testnet balance accumulator",
"main": "index.ts",
"scripts": {
"postinstall": "npm run build",
"build": "tsc index.ts",
"start": "node index.js"
},
"author": "anonymoussprocket",
"license": "UNLICENSED",
"engines": {
"node": ">=10.17.x",
"npm": ">=6.11.x"
},
"homepage": "https://gist.github.com/anonymoussprocket",
"dependencies": {
"conseiljs": "0.3.2-beta",
"glob": "^7.1.5",
"typescript": "3.6.4"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment