solana-json
Version:
A library for storing and retrieving JSON data from the Solana blockchain
129 lines (114 loc) • 4.3 kB
JavaScript
/*
Solana JSON module for storing and retrieving data from the Solana blockchain
*/
const solanaWeb3 = require('@solana/web3.js');
const fs = require('fs').promises;
const BufferLayout = require('buffer-layout');
const solanaJSON = {
setupConnection: (network) => {
const connection = new solanaWeb3.Connection(network);
return connection;
},
createUser: async () => {
const user = new solanaWeb3.Account();
console.log(`New solana account created: ${user.publicKey}`);
return user;
},
loadUser: async (privateKeyBufferArray) => {
const user = new solanaWeb3.Account(privateKeyBufferArray);
console.log(`Loaded solana account: ${user.publicKey}`);
return user;
},
fundUser: async (connection,account) => {
console.log(`Requesting airdrop funds... (this will take 30 seconds)`);
const res = await connection.requestAirdrop(account.publicKey, 10000000000); // 1 SOL = 1,000,000,000 LAMPORTS
await new Promise(r => setTimeout(r, 30000));
const lamports = await connection.getBalance(account.publicKey);
console.log(`Payer account ${account.publicKey.toBase58()} containing ${(lamports / 1000000000).toFixed(2)}SOL`);
},
setDataStructure: (characterLength) => {
const structure = BufferLayout.struct([BufferLayout.blob(characterLength,'txt')]);
return structure;
},
loadProgram: async (connection,smartContract,payerAccount) => {
// Load the program
console.log('Loading program...');
const data = await fs.readFile(smartContract.pathToProgram);
const programAccount = new solanaWeb3.Account();
await solanaWeb3.BpfLoader.load(
connection,
payerAccount,
programAccount,
data,
solanaWeb3.BPF_LOADER_PROGRAM_ID,
);
programId = programAccount.publicKey;
console.log('Program loaded to account', programId.toBase58());
// Create the app account
const appAccount = new solanaWeb3.Account();
const appPubkey = appAccount.publicKey;
console.log('Creating app account', appPubkey.toBase58());
const space = smartContract.dataLayout.span;
const lamports = 10000000000;
console.log(`Lamports required ${lamports}`);
const transaction = new solanaWeb3.Transaction().add(
solanaWeb3.SystemProgram.createAccount({
fromPubkey: payerAccount.publicKey,
newAccountPubkey: appPubkey,
lamports,
space,
programId,
}),
);
await solanaWeb3.sendAndConfirmTransaction(
connection,
transaction,
[payerAccount, appAccount],
{
commitment: 'singleGossip',
preflightCommitment: 'singleGossip',
},
);
return { appAccount, programId };
},
pushJSON: async (connection,app,jsonString) => {
if (jsonString.length > 996) throw new Error({'e':'jsonString length greater than 996 chars'});
const paddedMsg = jsonString.padEnd(1000);
const buffer = Buffer.from(paddedMsg, 'utf8');
const instruction = new solanaWeb3.TransactionInstruction({
keys: [{pubkey: app.appAccount.publicKey, isSigner: false, isWritable: true}],
programId: app.programId,
data: buffer,
});
const confirmation = await solanaWeb3.sendAndConfirmTransaction(
connection,
new solanaWeb3.Transaction().add(instruction),
[payerAccount],
{
commitment: 'singleGossip',
preflightCommitment: 'singleGossip',
},
);
return confirmation;
},
pullJSON: async (connection,appPubKey) => {
const accountInfo = await connection.getAccountInfo(appPubKey);
return Buffer.from(accountInfo.data).toString().substr(4,1000).trim();
},
deploy: async () => {
console.log('deploying...');
const connection = solanaJSON.setupConnection('https://testnet.solana.com');
const payerAccount = await solanaJSON.createUser();
await solanaJSON.fundUser(connection,payerAccount);
const smartContract = {
pathToProgram: './solana-json.so',
dataLayout: solanaJSON.setDataStructure(1000),
}
const app = await solanaJSON.loadProgram(connection,smartContract,payerAccount);
console.log('app',app);
const confirmationTicket = await solanaJSON.pushJSON(connection,app,'{"abc":123}');
const testJSON = solanaJSON.pullJSON(connection,app.appAccount.publicKey);
console.log(`Test: ${JSON.parse(testJSON).abc}`);
},
}
module.exports = solanaJSON;