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:
6
docker/code-templates/nodejs/multisig-contract/dist/hp.cfg.override
vendored
Normal file
6
docker/code-templates/nodejs/multisig-contract/dist/hp.cfg.override
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"contract": {
|
||||
"bin_path": "/usr/bin/node",
|
||||
"bin_args": "index.js"
|
||||
}
|
||||
}
|
||||
14
docker/code-templates/nodejs/multisig-contract/package.json
Normal file
14
docker/code-templates/nodejs/multisig-contract/package.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "_projname_",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"build": "npx ncc build src/contract.js -o dist",
|
||||
"build:prod": "npx ncc build src/contract.js --minify -o dist",
|
||||
"start": "npm run build && hpdevkit deploy dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"hotpocket-nodejs-contract": "^0.7.3",
|
||||
"everpocket-nodejs-contract": "^0.1.3",
|
||||
"@vercel/ncc": "0.34.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
const evp = require('everpocket-nodejs-contract');
|
||||
|
||||
export class _projname_ {
|
||||
sendOutput; // This function must be wired up by the caller.
|
||||
voteContext;
|
||||
hpContext;
|
||||
|
||||
// This function will be called in each contract execution.
|
||||
async handleContractExecution(ctx) {
|
||||
this.voteContext = new evp.VoteContext(ctx);
|
||||
this.hpContext = new evp.HotPocketContext(ctx, { voteContext: this.voteContext });
|
||||
|
||||
if (!ctx.readonly) {
|
||||
// Listen to incoming unl messages and feed them to elector.
|
||||
ctx.unl.onMessage((node, msg) => {
|
||||
this.voteContext.feedUnlMessage(node, msg);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async handleRequest(user, 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 == 'makePayment') {
|
||||
if (isReadOnly) {
|
||||
await this.sendOutput(user, {
|
||||
type: 'makePaymentResult',
|
||||
status: 'error',
|
||||
error: 'Submit multisig not supported in readonly mode'
|
||||
})
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const sender = message.sender;
|
||||
const receiver = message.receiver;
|
||||
|
||||
try {
|
||||
const xrplContext = new evp.XrplContext(this.hpContext, sender);
|
||||
await xrplContext.init();
|
||||
const tx = await xrplContext.xrplAcc.prepareMakePayment(receiver, "1", "XRP")
|
||||
|
||||
console.log("----------- Multi-Signing Transaction");
|
||||
const res = await xrplContext.multiSignAndSubmitTransaction(tx);
|
||||
console.log("Transaction submitted");
|
||||
|
||||
await this.sendOutput(user, {
|
||||
type: 'makePaymentResult',
|
||||
status: 'ok',
|
||||
data: res
|
||||
})
|
||||
}
|
||||
catch (e) {
|
||||
console.error(e);
|
||||
|
||||
await this.sendOutput(user, {
|
||||
type: 'makePaymentResult',
|
||||
status: 'error',
|
||||
error: e
|
||||
})
|
||||
}
|
||||
}
|
||||
else {
|
||||
await this.sendOutput(user, {
|
||||
status: 'error',
|
||||
error: 'Unknown message type'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
const HotPocket = require('hotpocket-nodejs-contract');
|
||||
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;
|
||||
|
||||
// This function is executed per each contract round.
|
||||
await app.handleContractExecution(ctx);
|
||||
|
||||
// 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 filter out invalid data formats for our contract.
|
||||
const message = JSON.parse(buf);
|
||||
|
||||
// Pass the JSON message to our application logic component.
|
||||
await app.handleRequest(user, message, isReadOnly);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const hpc = new HotPocket.Contract();
|
||||
hpc.init(contract);
|
||||
Reference in New Issue
Block a user