UNPKG

@hashgraph/solo

Version:

An opinionated CLI tool to deploy and manage private Hedera Networks.

164 lines (142 loc) 6.13 kB
// SPDX-License-Identifier: Apache-2.0 import { Wallet, LocalProvider, TopicCreateTransaction, TopicMessageSubmitTransaction, AccountCreateTransaction, PrivateKey, Hbar, TopicMessageQuery, Client, } from '@hashgraph/sdk'; import dotenv from 'dotenv'; import http from 'http'; dotenv.config(); async function main() { if (process.env.OPERATOR_ID === null || process.env.OPERATOR_KEY === null || process.env.HEDERA_NETWORK === null) { throw new Error('Environment variables OPERATOR_ID, HEDERA_NETWORK, and OPERATOR_KEY are required.'); } console.log(`Hedera network = ${process.env.HEDERA_NETWORK}`); const provider = new LocalProvider(); const mirrorNetwork = '127.0.0.1:5600'; provider._client.setMirrorNetwork(mirrorNetwork); const wallet = new Wallet(process.env.OPERATOR_ID, process.env.OPERATOR_KEY, provider); const TEST_MESSAGE = 'Hello World'; try { // if process.env.OPERATOR_KEY string size is 100, it is ECDSA key, if 96, it is ED25519 key const operatorKeySize = process.env.OPERATOR_KEY.length; // create topic const operatorKey = operatorKeySize === 100 ? PrivateKey.fromStringECDSA(process.env.OPERATOR_KEY) : PrivateKey.fromStringED25519(process.env.OPERATOR_KEY); let transaction = await new TopicCreateTransaction().setAdminKey(operatorKey).freezeWithSigner(wallet); transaction = await transaction.signWithSigner(wallet); const createResponse = await transaction.executeWithSigner(wallet); const createReceipt = await createResponse.getReceiptWithSigner(wallet); console.log(`topic id = ${createReceipt.topicId.toString()}`); console.log('Wait a few seconds to create subscribe to new topic'); await new Promise(resolve => setTimeout(resolve, 25000)); // Create a subscription to the topic const mirrorClient = ( await Client.forMirrorNetwork(mirrorNetwork) ).setOperator(process.env.OPERATOR_ID, process.env.OPERATOR_KEY); let expectedContents = ""; let finished = false; new TopicMessageQuery() .setTopicId(createReceipt.topicId) .setMaxAttempts(400) .setLimit(1) // eslint-disable-next-line no-unused-vars .subscribe(mirrorClient, (topic, error) => { if (error) { console.error(`Error : ${error}`); finished = true; return; } }, (topic)=>{ finished = true; expectedContents = Buffer.from(topic.contents).toString( "utf-8", ); console.log(`Subscription received message: ${topic.contents}`); }); // send one message let topicMessageSubmitTransaction = await new TopicMessageSubmitTransaction({ topicId: createReceipt.topicId, message: TEST_MESSAGE, }).freezeWithSigner(wallet); topicMessageSubmitTransaction = await topicMessageSubmitTransaction.signWithSigner(wallet); const sendResponse = await topicMessageSubmitTransaction.executeWithSigner(wallet); const sendReceipt = await sendResponse.getReceiptWithSigner(wallet); console.log(`topic sequence number = ${sendReceipt.topicSequenceNumber.toString()}`); await new Promise(resolve => setTimeout(resolve, 1000)); // send a create account transaction to push record stream files to mirror node const newKey = PrivateKey.generate(); let accountCreateTransaction = await new AccountCreateTransaction() .setInitialBalance(new Hbar(10)) .setKey(newKey.publicKey) .freezeWithSigner(wallet); accountCreateTransaction = await accountCreateTransaction.signWithSigner(wallet); const accountCreationResponse = await accountCreateTransaction.executeWithSigner(wallet); const accountCreationReceipt = await accountCreationResponse.getReceiptWithSigner(wallet); console.log(`account id = ${accountCreationReceipt.accountId.toString()}`); await new Promise(resolve => setTimeout(resolve, 1000)); // Check submit message result should success const queryURL = `http://localhost:8080/api/v1/topics/${createReceipt.topicId}/messages`; let received = false; let receivedMessage = ''; // wait until the transaction reached consensus and retrievable from the mirror node API let retry = 0; while (!received && retry < 10) { const req = http.request(queryURL, {method: 'GET', timeout: 100, headers: {Connection: 'close'}}, res => { res.setEncoding('utf8'); res.on('data', chunk => { // convert chunk to json object const obj = JSON.parse(chunk); if (obj.messages.length === 0) { console.log('No messages yet'); } else { if (obj.messages.length === 0) { console.error(`No messages found for the topic ${createReceipt.topicId}`); process.exit(1); } // convert message from base64 to utf-8 const base64 = obj.messages[0].message; const buff = Buffer.from(base64, 'base64'); receivedMessage = buff.toString('utf-8'); console.log(`Query received message: ${receivedMessage}`); received = true; } }); }); req.on('error', e => { console.log(`problem with request: ${e.message}`); }); req.end(); // make the request // wait and try again await new Promise(resolve => setTimeout(resolve, 1000)); retry++; } // wait a few seconds to receive subscription message await new Promise(resolve => setTimeout(resolve, 5000)); if (!finished) { console.error("Not received subscription message"); process.exit(1); } else if (expectedContents !== TEST_MESSAGE) { console.error('Message received from subscription but not match: ' + expectedContents); process.exit(1); } if (receivedMessage === TEST_MESSAGE) { console.log('Message received successfully'); } else { console.error('Message received but not match: ' + receivedMessage); process.exit(1); } } catch (error) { console.error(error); throw error; } provider.close(); process.exit(0); } void main();