Skip to content

Instantly share code, notes, and snippets.

@EnoF
Created April 13, 2023 08:59
Show Gist options
  • Save EnoF/8d9394621a0cc7514e30be53e0957341 to your computer and use it in GitHub Desktop.
Save EnoF/8d9394621a0cc7514e30be53e0957341 to your computer and use it in GitHub Desktop.
Helper for KDA-Tool (requires node v18+)
#!/usr/bin/env node
const fs = require("fs");
const acceptedArgs = ["--send", "--local", "--node"];
const { send, local, node } = process.argv.reduce((args, arg) => {
const [key, value] = arg.split("=");
if (!value) return args;
if (!acceptedArgs.includes(key)) return args;
return { ...args, [key.replace("--", "")]: value };
}, {});
if (!node) throw new Error("No node specified");
if (!local && !send) throw new Error("No local or send payload specified");
const getPath = (data) => {
const { meta, networkId } = JSON.parse(data.cmd);
return `/chainweb/0.0/${networkId}/chain/${meta.chainId}/pact/api/v1`;
};
const getData = (path) => {
if (!path.includes("*")) return [require(path)];
const dir = path.replace(/\/\w*-\*.*/, "");
const files = fs
.readdirSync(dir)
.filter((file) => /tx-\d*\.json$/.test(file))
.map((file) => require(`${dir}/${file}`));
return files;
};
const fetchLocal = async (data) => {
try {
const res = await fetch(`${node}${getPath(data)}/local?preflight=true`, {
method: "POST",
body: JSON.stringify(data),
headers: { "Content-Type": "application/json" },
});
console.log("local result:");
console.log(await res.json());
} catch (e) {
console.error(`Could not send local payload: ${e.message}`);
throw new Error(e);
}
};
const fetchSend = async (data) => {
try {
const base = `${node}${getPath(data)}`;
const res = await fetch(`${base}/send`, {
method: "POST",
body: JSON.stringify({ cmds: [data] }),
headers: { "Content-Type": "application/json" },
});
const { requestKeys } = await res.json();
console.log("requestKeys:", requestKeys);
await listen(base, requestKeys);
} catch (e) {
console.error(`Could not send local payload: ${e.message}`);
throw new Error(e);
}
};
const listen = async (base, requestKeys) => {
try {
const result = await Promise.all(
requestKeys.map((key) =>
fetch(`${base}/listen`, {
method: "POST",
body: JSON.stringify({ listen: key }),
headers: { "Content-Type": "application/json" },
})
)
);
console.log("Transactions mined");
console.log(result);
} catch (e) {
console.error(`Could not listen for requestKeys: ${e.message}`);
throw new Error(e);
}
};
const execLocal = async () => {
const data = getData(local);
await Promise.all(data.map((d) => fetchLocal(d)));
};
const execSend = async () => {
const data = getData(send);
await Promise.all(data.map((d) => fetchSend(d)));
};
const exec = async () => {
if (local) return execLocal();
return execSend();
};
exec();
@EnoF
Copy link
Author

EnoF commented Apr 13, 2023

KDA Tool helper for local devnet

Prereq

This script requires node 18 and relies on kda-tool output

Install

Download and make the script executable:

chmod +x kda-helper.js

Usage

To use this script first use kda-tool to generate and sign your requests:

kda gen -t my-template.ktpl -d my-template-data.yml
kda sign -k keys.kda tx-*.yml
# or
kda sign --chainweaver tx-*.yml

Then you can use this script to local/send:

./kda-help.js --node=http://localhost:8080 --local="./tx-*.json"
./kda-help.js --node=http://localhost:8080 --send="./tx-*.json"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment