Added nodejs code generator. (#1)

This commit is contained in:
Ravin Perera
2022-06-18 23:23:31 +05:30
committed by GitHub
parent 87354cad69
commit f5c366fbd6
8 changed files with 260 additions and 40 deletions

View File

@@ -0,0 +1,60 @@
const fs = require('fs').promises;
// This sample application writes and reads from a simple text file to serve user requests.
// Real-world applications may use a proper local database like sqlite.
const dataFile = 'datafile.txt'
export class _projname_ {
sendOutput; // This function must be wired up by the caller.
async handleRequest(userPubKey, message, isReadOnly) {
// This sample application defines two simple messages. 'get' and 'set'.
// It's up to the application to decide the structure and contents of messages.
if (message.type == 'get') {
// Retrieved previously saved data and return to the user.
const data = await this.getData();
await this.sendOutput(userPubKey, {
type: 'data_result',
data: data
})
}
else if (message.type == 'set') {
if (!isReadOnly) {
// Save the provided data into storage.
await this.setData(message.data);
}
else {
await this.sendOutput(userPubKey, {
type: 'error',
error: 'Set data not supported in readonly mode'
})
}
}
else {
await this.sendOutput(userPubKey, {
type: 'error',
error: 'Unknown message type'
})
}
}
async setData(data) {
// Hot Pocket subjects data on-disk to consensus.
await fs.writeFile(dataFile, data);
}
async getData() {
try {
return (await fs.readFile(dataFile)).toString();
}
catch {
console.log('Data file not created yet. Returning empty data.');
return '';
}
}
}

View File

@@ -0,0 +1,49 @@
const HotPocket = require('hotpocket-nodejs-contract');
const { _projname_ } = require('./_projname_');
// Hot Pocket smart contract is defined as a function which takes the Hot Pocket ExecutionContext as an argument.
// This function gets invoked every consensus round and whenever a user sends a out-of-concensus read-request.
async function contract(ctx) {
// Create our application logic component.
// This pattern allows us to test the application logic independently of Hot Pocket.
const app = new _projname_();
// Wire-up output emissions from the application before we pass user inputs to it.
app.sendOutput = async (userPubKey, output) => {
// In Hot Pocket, each user is represented by their Ed25519 public key.
const user = ctx.users.find(userPubKey);
await user.send(output)
}
// In 'readonly' mode, nothing our contract does will get persisted on the ledger. The benefit is
// readonly messages gets processed much faster due to not being subjected to consensus.
// We should only use readonly mode for returning/replying data for the requesting user.
//
// In consensus mode (NOT read-only), we can do anything like persisting to data storage and/or
// sending data to any connected user at the time. Everything will get subjected to consensus so
// there is a time-penalty.
const isReadOnly = ctx.readonly;
// Process user inputs.
// Loop through list of users who have sent us inputs.
for (const user of ctx.users.list()) {
// Loop through inputs sent by each user.
for (const input of user.inputs) {
// Read the data buffer sent by user (this can be any kind of data like string, json or binary data).
const buf = await ctx.users.read(input);
// Let's assume all data buffers for this contract are JSON.
// In real-world apps, we need to gracefully fitler out invalid data formats for our contract.
const message = JSON.parse(buf);
// Pass the JSON message to our application logic component.
await app.handleRequest(userPubKey, message, isReadOnly);
}
}
}
const hpc = new HotPocket.Contract();
hpc.init(contract);