mirror of
https://github.com/EvernodeXRPL/hp-devkit.git
synced 2026-04-29 15:37:58 +00:00
Added new contract templates (#31)
This commit is contained in:
98
docker/code-templates/nodejs/file-contract/src/_projname_.js
Normal file
98
docker/code-templates/nodejs/file-contract/src/_projname_.js
Normal file
@@ -0,0 +1,98 @@
|
||||
const fs = require('fs');
|
||||
const bson = require('bson');
|
||||
|
||||
export class _projname_ {
|
||||
sendOutput; // This function must be wired up by the caller.
|
||||
|
||||
async handleRequest(user, msg, isReadOnly) {
|
||||
|
||||
// This sample application defines simple file operations.
|
||||
// It's up to the application to decide the structure and contents of messages.
|
||||
|
||||
if (msg.type == "upload") {
|
||||
// Check already exist.
|
||||
if (fs.existsSync(msg.fileName)) {
|
||||
await user.send(bson.serialize({
|
||||
type: "uploadResult",
|
||||
status: "already_exists",
|
||||
fileName: msg.fileName
|
||||
}));
|
||||
}
|
||||
// Error is too large.
|
||||
else if (msg.content.length > 10 * 1024 * 1024) { // 10MB
|
||||
await user.send(bson.serialize({
|
||||
type: "uploadResult",
|
||||
status: "too_large",
|
||||
fileName: msg.fileName
|
||||
}));
|
||||
}
|
||||
else {
|
||||
// Do not write in read only mode.
|
||||
if (!isReadOnly) {
|
||||
// Save the file.
|
||||
fs.writeFileSync(msg.fileName, msg.content.buffer);
|
||||
|
||||
await user.send(bson.serialize({
|
||||
type: "uploadResult",
|
||||
status: "ok",
|
||||
fileName: msg.fileName
|
||||
}));
|
||||
}
|
||||
else {
|
||||
await this.sendOutput(user, {
|
||||
type: "uploadResult",
|
||||
status: "error",
|
||||
error: 'Write is not supported in readonly mode'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (msg.type == "delete") {
|
||||
// Delete if exist.
|
||||
if (fs.existsSync(msg.fileName)) {
|
||||
// Do not delete in read only mode.
|
||||
if (!isReadOnly) {
|
||||
fs.unlinkSync(msg.fileName);
|
||||
await user.send(bson.serialize({
|
||||
type: "deleteResult",
|
||||
status: "ok",
|
||||
fileName: msg.fileName
|
||||
}));
|
||||
}
|
||||
else {
|
||||
await this.sendOutput(user, {
|
||||
type: "deleteResult",
|
||||
status: "error",
|
||||
error: 'Delete is not supported in readonly mode'
|
||||
})
|
||||
}
|
||||
}
|
||||
else {
|
||||
await user.send(bson.serialize({
|
||||
type: "deleteResult",
|
||||
status: "not_found",
|
||||
fileName: msg.fileName
|
||||
}));
|
||||
}
|
||||
}
|
||||
// Send file if exist.
|
||||
else if (msg.type == "download") {
|
||||
if (fs.existsSync(msg.fileName)) {
|
||||
const fileContent = fs.readFileSync(msg.fileName);
|
||||
await user.send(bson.serialize({
|
||||
type: "downloadResult",
|
||||
status: "ok",
|
||||
fileName: msg.fileName,
|
||||
content: fileContent
|
||||
}));
|
||||
}
|
||||
else {
|
||||
await user.send(bson.serialize({
|
||||
type: "downloadResult",
|
||||
status: "not_found",
|
||||
fileName: msg.fileName
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
48
docker/code-templates/nodejs/file-contract/src/contract.js
Normal file
48
docker/code-templates/nodejs/file-contract/src/contract.js
Normal file
@@ -0,0 +1,48 @@
|
||||
const HotPocket = require('hotpocket-nodejs-contract');
|
||||
const bson = require('bson');
|
||||
const { _projname_ } = require('./_projname_');
|
||||
|
||||
// HotPocket smart contract is defined as a function which takes the HotPocket contract context 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 HotPocket.
|
||||
const app = new _projname_();
|
||||
|
||||
// Wire-up output emissions from the application before we pass user inputs to it.
|
||||
app.sendOutput = async (user, output) => {
|
||||
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 binary.
|
||||
// In real-world apps, we need to gracefully filter out invalid data formats for our contract.
|
||||
const msg = bson.deserialize(buf);
|
||||
|
||||
// Pass the JSON message to our application logic component.
|
||||
await app.handleRequest(user, msg, isReadOnly);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const hpc = new HotPocket.Contract();
|
||||
hpc.init(contract);
|
||||
Reference in New Issue
Block a user