@everyprotocol/every-cli 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.every.toml +8 -10
- package/abis/ElementRegistry.json +1 -1
- package/abis/IObjectMinter.json +1 -1
- package/abis/IObjectMinterAdmin.json +1 -1
- package/abis/IOmniRegistry.json +1 -1
- package/abis/ISet.json +1 -1
- package/abis/ISetRegistry.json +1 -1
- package/abis/ISetRegistryAdmin.json +1 -1
- package/abis/KindRegistry.json +1 -1
- package/abis/ObjectMinter.json +1 -1
- package/abis/OmniRegistry.json +1 -1
- package/abis/SetRegistry.json +1 -1
- package/dist/abi.js +6 -0
- package/dist/cmdgen.js +51 -139
- package/dist/cmds/balance.js +43 -0
- package/dist/cmds/config.js +46 -0
- package/dist/cmds/kind.js +14 -0
- package/dist/cmds/matter.js +82 -0
- package/dist/cmds/minter.js +31 -0
- package/dist/cmds/object.js +175 -0
- package/dist/cmds/relation.js +16 -0
- package/dist/cmds/set.js +31 -0
- package/dist/cmds/unique.js +14 -0
- package/dist/cmds/universe.js +21 -0
- package/dist/cmds/value.js +14 -0
- package/dist/cmds/wallet.js +90 -0
- package/dist/commander-patch.js +64 -0
- package/dist/config.js +62 -51
- package/dist/ethereum.js +33 -0
- package/dist/from-opts.js +161 -0
- package/dist/index.js +2 -1
- package/dist/keystore.js +120 -0
- package/dist/logger.js +39 -0
- package/dist/parsers.js +59 -0
- package/dist/program.js +28 -39
- package/dist/substrate.js +63 -0
- package/dist/utils.js +150 -147
- package/package.json +4 -1
- package/dist/cmds.js +0 -132
- package/dist/matter.js +0 -152
- package/dist/mint.js +0 -64
- package/dist/relate.js +0 -104
- package/dist/wallet.js +0 -108
package/dist/cmds.js
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import { Argument, Command, Option } from "commander";
|
|
2
|
-
import { createPublicClient, http, parseEventLogs, stringify } from "viem";
|
|
3
|
-
import { getUniverseConfig } from "./config.js";
|
|
4
|
-
import { checkArguments, getClientsEth } from "./utils.js";
|
|
5
|
-
export function defaultReadFunctionOptions() {
|
|
6
|
-
const options = [];
|
|
7
|
-
options.push(new Option("-u, --universe <universe>", "universe name").default("local"));
|
|
8
|
-
options.push(new Option("--dry-run", "Simulate the command without sending a transaction"));
|
|
9
|
-
return options;
|
|
10
|
-
}
|
|
11
|
-
export function defaultWriteFunctionOptions() {
|
|
12
|
-
const options = [];
|
|
13
|
-
options.push(new Option("-u, --universe <universe>", "universe name").default("local"));
|
|
14
|
-
options.push(new Option("-k, --private-key <key>", "private key to sign the transaction"));
|
|
15
|
-
options.push(new Option("-a, --account <account>", "name of the keystore to sign the transaction"));
|
|
16
|
-
options.push(new Option("-p, --password [password]", "password to decrypt the keystore"));
|
|
17
|
-
options.push(new Option("--password-file <file>", "file containing the password to decrypt the keystore"));
|
|
18
|
-
options.push(new Option("-f, --foundry", "use keystore from Foundry directory (~/.foundry/keystores)"));
|
|
19
|
-
options.push(new Option("--dry-run", "Simulate the command without sending a transaction"));
|
|
20
|
-
return options;
|
|
21
|
-
}
|
|
22
|
-
const defaultConfig = {
|
|
23
|
-
cmdAbi: (txnAbi) => txnAbi,
|
|
24
|
-
cmdName: (cmdAbi) => cmdAbi.name,
|
|
25
|
-
cmdDescription: (cmdAbi) => cmdAbi._metadata?.notice || cmdAbi.name,
|
|
26
|
-
cmdOptions: (cmdAbi) => {
|
|
27
|
-
const read = cmdAbi.stateMutability == "view" || cmdAbi.stateMutability == "pure";
|
|
28
|
-
return read ? defaultReadFunctionOptions() : defaultWriteFunctionOptions();
|
|
29
|
-
},
|
|
30
|
-
cmdArguments: (cmdAbi) => cmdAbi.inputs.map((input) => {
|
|
31
|
-
const argDesc = cmdAbi._metadata?.params?.[input.name] || `${input.type} parameter`;
|
|
32
|
-
return new Argument(`<${input.name}>`, argDesc);
|
|
33
|
-
}),
|
|
34
|
-
cmdAction: async function (ctx) {
|
|
35
|
-
const isRead = ctx.cmdAbi.stateMutability == "view" || ctx.cmdAbi.stateMutability == "pure";
|
|
36
|
-
const opts = ctx.cmd.opts();
|
|
37
|
-
const args0 = ctx.cmd.args;
|
|
38
|
-
console.log({ args0 });
|
|
39
|
-
const { address, tag, args } = await ctx.txnPrepare(ctx);
|
|
40
|
-
const abi = [ctx.txnAbi, ...ctx.nonFuncs];
|
|
41
|
-
const functionName = ctx.txnAbi.name;
|
|
42
|
-
if (isRead) {
|
|
43
|
-
const publicClient = createPublicClient({ transport: http(ctx.conf.rpc) });
|
|
44
|
-
const result = await publicClient.readContract({ address, abi, functionName, args });
|
|
45
|
-
console.log(`Result:`, result);
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
const { publicClient, walletClient } = await getClientsEth(ctx.conf, opts);
|
|
49
|
-
const account = walletClient.account;
|
|
50
|
-
console.log({
|
|
51
|
-
isRead,
|
|
52
|
-
address: `${address} (${tag})`,
|
|
53
|
-
account: account?.address,
|
|
54
|
-
signature: ctx.txnAbi._metadata.signature,
|
|
55
|
-
args,
|
|
56
|
-
});
|
|
57
|
-
const { request } = await publicClient.simulateContract({ address, abi, functionName, args, account });
|
|
58
|
-
const hash = await walletClient.writeContract(request);
|
|
59
|
-
console.log(`Transaction sent: ${hash}`);
|
|
60
|
-
console.log("Transaction mining...");
|
|
61
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
62
|
-
console.log("Transaction mined");
|
|
63
|
-
if (receipt.logs && receipt.logs.length > 0) {
|
|
64
|
-
const parsedLogs = parseEventLogs({ abi, logs: receipt.logs });
|
|
65
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
66
|
-
parsedLogs.forEach((log) => {
|
|
67
|
-
console.log(" - Event", log.eventName, stringify(log.args));
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
console.log({ isRead, address: `${address} (${tag})`, signature: ctx.txnAbi._metadata.signature, args });
|
|
72
|
-
return;
|
|
73
|
-
},
|
|
74
|
-
txnPrepare: function (ctx) {
|
|
75
|
-
const args = checkArguments(ctx.cmd.args, ctx.cmdAbi);
|
|
76
|
-
return { address: ctx.conf.contracts[ctx.contract], tag: ctx.contract, args };
|
|
77
|
-
},
|
|
78
|
-
};
|
|
79
|
-
export function configureCommand(txnAbi, config) {
|
|
80
|
-
const cmdAbi = (config.cmdAbi || defaultConfig.cmdAbi)(txnAbi);
|
|
81
|
-
const name = (config.cmdName || defaultConfig.cmdName)(cmdAbi);
|
|
82
|
-
const desc = (config.cmdDescription || defaultConfig.cmdDescription)(cmdAbi);
|
|
83
|
-
const opts = (config.cmdOptions || defaultConfig.cmdOptions)(cmdAbi);
|
|
84
|
-
const args = (config.cmdArguments || defaultConfig.cmdArguments)(cmdAbi);
|
|
85
|
-
const action = async function () {
|
|
86
|
-
const ctx = {
|
|
87
|
-
conf: getUniverseConfig(this.opts()),
|
|
88
|
-
contract: config.contract,
|
|
89
|
-
cmdAbi,
|
|
90
|
-
txnAbi,
|
|
91
|
-
nonFuncs: config.nonFuncs,
|
|
92
|
-
cmd: this,
|
|
93
|
-
txnPrepare: config.txnPrepare || defaultConfig.txnPrepare,
|
|
94
|
-
};
|
|
95
|
-
await (config.cmdAction || defaultConfig.cmdAction)(ctx);
|
|
96
|
-
};
|
|
97
|
-
const cmd = new Command();
|
|
98
|
-
cmd.name(name);
|
|
99
|
-
cmd.description(desc);
|
|
100
|
-
opts.forEach((opt) => cmd.addOption(opt));
|
|
101
|
-
args.forEach((arg) => cmd.addArgument(arg));
|
|
102
|
-
cmd.action(action);
|
|
103
|
-
return cmd;
|
|
104
|
-
}
|
|
105
|
-
export class RenamingCommand extends Command {
|
|
106
|
-
nameCounts = new Map();
|
|
107
|
-
addCommand(cmd, opts) {
|
|
108
|
-
const originalName = cmd.name();
|
|
109
|
-
const uniqueName = this.getUniqueName(originalName);
|
|
110
|
-
if (originalName !== uniqueName) {
|
|
111
|
-
cmd.name(uniqueName);
|
|
112
|
-
}
|
|
113
|
-
return super.addCommand(cmd, opts);
|
|
114
|
-
}
|
|
115
|
-
addCommands(cmds) {
|
|
116
|
-
cmds.forEach((cmd) => this.addCommand(cmd));
|
|
117
|
-
return this;
|
|
118
|
-
}
|
|
119
|
-
resetCounts(name) {
|
|
120
|
-
if (name) {
|
|
121
|
-
this.nameCounts.delete(name);
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
this.nameCounts.clear();
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
getUniqueName(baseName) {
|
|
128
|
-
const count = this.nameCounts.get(baseName) || 0;
|
|
129
|
-
this.nameCounts.set(baseName, count + 1);
|
|
130
|
-
return count === 0 ? baseName : `${baseName}${count + 1}`;
|
|
131
|
-
}
|
|
132
|
-
}
|
package/dist/matter.js
DELETED
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import { ApiPromise, WsProvider } from "@polkadot/api";
|
|
3
|
-
import "@polkadot/api-augment/substrate";
|
|
4
|
-
import * as fs from "fs";
|
|
5
|
-
import * as path from "path";
|
|
6
|
-
import { getUniverseConfig } from "./config.js";
|
|
7
|
-
import { getSubstrateAccountPair } from "./utils.js";
|
|
8
|
-
import { decodeAddress } from "@polkadot/util-crypto";
|
|
9
|
-
import { u8aFixLength } from "@polkadot/util";
|
|
10
|
-
function createDeferred() {
|
|
11
|
-
let resolve;
|
|
12
|
-
let reject;
|
|
13
|
-
const promise = new Promise((res, rej) => {
|
|
14
|
-
resolve = res;
|
|
15
|
-
reject = rej;
|
|
16
|
-
});
|
|
17
|
-
return { promise, resolve, reject };
|
|
18
|
-
}
|
|
19
|
-
async function submitTransaction(api, tx, pair) {
|
|
20
|
-
// const pTxn = Promise.withResolvers<Transaction>();
|
|
21
|
-
// const pReceipt = Promise.withResolvers<Receipt>();
|
|
22
|
-
const pTxn = createDeferred();
|
|
23
|
-
const pReceipt = createDeferred();
|
|
24
|
-
const accountId = u8aFixLength(decodeAddress(pair.address), 256);
|
|
25
|
-
const nonce = await api.rpc.system.accountNextIndex(accountId);
|
|
26
|
-
const unsub = await tx.signAndSend(pair, { nonce }, ({ events = [], status, txHash, txIndex, blockNumber }) => {
|
|
27
|
-
if (status.isReady) {
|
|
28
|
-
pTxn.resolve({ txHash: txHash.toHex(), receipt: pReceipt.promise });
|
|
29
|
-
}
|
|
30
|
-
else if (status.isFinalized) {
|
|
31
|
-
pReceipt.resolve({
|
|
32
|
-
txHash: txHash.toHex(),
|
|
33
|
-
blockHash: status.asFinalized.toHex(),
|
|
34
|
-
txIndex,
|
|
35
|
-
blockNumber,
|
|
36
|
-
events: events,
|
|
37
|
-
});
|
|
38
|
-
unsub();
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
return await pTxn.promise;
|
|
42
|
-
}
|
|
43
|
-
function findEvent(events, name) {
|
|
44
|
-
for (const record of events) {
|
|
45
|
-
if (record.event && record.event.method === name) {
|
|
46
|
-
return record.event;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
function guessContentType(filePath) {
|
|
52
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
53
|
-
switch (ext) {
|
|
54
|
-
case ".txt":
|
|
55
|
-
return "text/plain";
|
|
56
|
-
case ".json":
|
|
57
|
-
return "application/json";
|
|
58
|
-
case ".wasm":
|
|
59
|
-
return "application/wasm";
|
|
60
|
-
case ".jpg":
|
|
61
|
-
case ".jpeg":
|
|
62
|
-
return "image/jpeg";
|
|
63
|
-
case ".png":
|
|
64
|
-
return "image/png";
|
|
65
|
-
default:
|
|
66
|
-
return "application/octet-stream";
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
export function genMatterCommand() {
|
|
70
|
-
const cmd = new Command().name("matter").description("Manage matters");
|
|
71
|
-
cmd
|
|
72
|
-
.command("register")
|
|
73
|
-
.description("Register matter on the Substrate chain")
|
|
74
|
-
.argument("<files...>", "Path to the file(s) containing the matter content")
|
|
75
|
-
.option("-c, --content-type <type>", "Default content type")
|
|
76
|
-
.option("-h, --hasher <number>", "Default hasher", "1")
|
|
77
|
-
.option("-u, --universe <universe>", "Universe name", "local")
|
|
78
|
-
.option("-a, --account <account>", "Name of the keystore to sign the transaction")
|
|
79
|
-
.option("-p, --password [password]", "Password to decrypt the keystore")
|
|
80
|
-
.option("--password-file <file>", "File containing the password to decrypt the keystore")
|
|
81
|
-
.action(async (files, options) => {
|
|
82
|
-
const materials = [];
|
|
83
|
-
// Process each file argument
|
|
84
|
-
for (const file of files) {
|
|
85
|
-
let [filePath, hasher_, contentType] = file.split(":");
|
|
86
|
-
const hasher = hasher_ ? Number(hasher_) : Number(options.hasher) || 1;
|
|
87
|
-
if (!contentType) {
|
|
88
|
-
if (options.contentType) {
|
|
89
|
-
contentType = options.contentType;
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
contentType = guessContentType(filePath);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
materials.push({ filePath, hasher, contentType });
|
|
96
|
-
}
|
|
97
|
-
// Get universe configuration
|
|
98
|
-
const conf = getUniverseConfig(options);
|
|
99
|
-
if (!conf.observer.rpc) {
|
|
100
|
-
throw new Error("pre_rpc_url not configured in universe");
|
|
101
|
-
}
|
|
102
|
-
// Get account pair for signing
|
|
103
|
-
if (!options.account) {
|
|
104
|
-
throw new Error("Account must be specified with --account");
|
|
105
|
-
}
|
|
106
|
-
// const keystorePath = resolveKeystoreFile(options.account, options);
|
|
107
|
-
// const keystore = loadKeystore(keystorePath);
|
|
108
|
-
// const password = getPassword(options);
|
|
109
|
-
const accountPair = getSubstrateAccountPair(options);
|
|
110
|
-
// Connect to the Substrate node
|
|
111
|
-
console.log(`Connecting to ${conf.observer.rpc}...`);
|
|
112
|
-
const provider = new WsProvider(conf.observer.rpc);
|
|
113
|
-
const api = await ApiPromise.create({ provider });
|
|
114
|
-
await api.isReady;
|
|
115
|
-
console.log("Connected to Substrate node");
|
|
116
|
-
const txns = [];
|
|
117
|
-
// Submit transactions for each material
|
|
118
|
-
for (const { filePath, hasher, contentType } of materials) {
|
|
119
|
-
console.log(`Processing ${filePath}: content-type=${contentType}, hasher=${hasher}`);
|
|
120
|
-
const content = fs.readFileSync(filePath);
|
|
121
|
-
const contentRaw = api.createType("Raw", content, content.length);
|
|
122
|
-
const call = api.tx.matter.register(hasher, contentType, contentRaw);
|
|
123
|
-
console.log(`Submitting transaction for ${filePath}...`);
|
|
124
|
-
const txn = await submitTransaction(api, call, accountPair);
|
|
125
|
-
console.log(`Transaction submitted: ${txn.txHash}`);
|
|
126
|
-
txns.push({ txn, filePath });
|
|
127
|
-
}
|
|
128
|
-
// Wait for all transactions to be finalized
|
|
129
|
-
for (const { txn, filePath } of txns) {
|
|
130
|
-
console.log(`Waiting for ${filePath} to be finalized...`);
|
|
131
|
-
const receipt = await txn.receipt;
|
|
132
|
-
const event = findEvent(receipt.events, "MaterialAdded");
|
|
133
|
-
if (event) {
|
|
134
|
-
const hash = event.data[0].toString();
|
|
135
|
-
console.log(`${filePath} finalized in block ${receipt.blockHash}`);
|
|
136
|
-
console.log(` Matter hash: ${hash}`);
|
|
137
|
-
if (conf.observer.gateway) {
|
|
138
|
-
console.log(` Preimage: ${conf.observer.gateway}/m/${hash}`);
|
|
139
|
-
}
|
|
140
|
-
if (conf.observer.explorer) {
|
|
141
|
-
console.log(` Transaction: ${conf.observer.explorer}/extrinsic/${receipt.blockNumber}-${receipt.txIndex}`);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
else {
|
|
145
|
-
console.log(`${filePath} finalized, but no MaterialAdded event found`);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
await api.disconnect();
|
|
149
|
-
console.log("Disconnected from Substrate node");
|
|
150
|
-
});
|
|
151
|
-
return cmd;
|
|
152
|
-
}
|
package/dist/mint.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import { defaultWriteFunctionOptions } from "./cmds.js";
|
|
3
|
-
import { getClientsEth, stringify } from "./utils.js";
|
|
4
|
-
import { getUniverseConfig } from "./config.js";
|
|
5
|
-
import { parseEventLogs, parseUnits } from "viem";
|
|
6
|
-
import { abi } from "./abi.js";
|
|
7
|
-
export function genMintCommand() {
|
|
8
|
-
const cmd = new Command()
|
|
9
|
-
.name("mint")
|
|
10
|
-
.description("Mint an object via ObjectMinter")
|
|
11
|
-
.option("--auth <data>", "authorization data, if needed for a permissioned mint", "0x")
|
|
12
|
-
.option("--policy <index>", "the index number of the mint policy", "0")
|
|
13
|
-
.option("--value <amount>", "the amount of ETH to send together", "0")
|
|
14
|
-
.argument("<sid>", "scoped object ID, in form of set.id (e.g., 17.1)")
|
|
15
|
-
.argument("<to>", "address of the recipient")
|
|
16
|
-
.argument("[data]", "additional mint data", "0x")
|
|
17
|
-
.action(action);
|
|
18
|
-
defaultWriteFunctionOptions().forEach((option) => cmd.addOption(option));
|
|
19
|
-
return cmd;
|
|
20
|
-
}
|
|
21
|
-
async function action() {
|
|
22
|
-
const opts = this.opts();
|
|
23
|
-
const args0 = this.args;
|
|
24
|
-
const conf = getUniverseConfig(opts);
|
|
25
|
-
const objectMinter = conf.contracts["ObjectMinter"];
|
|
26
|
-
const setRegistry = conf.contracts["SetRegistry"];
|
|
27
|
-
const { publicClient, walletClient } = await getClientsEth(conf, opts);
|
|
28
|
-
const account = walletClient.account;
|
|
29
|
-
const [set, id] = args0[0].split(".");
|
|
30
|
-
const setContract = (await publicClient.readContract({
|
|
31
|
-
address: setRegistry,
|
|
32
|
-
abi: abi.setContract,
|
|
33
|
-
functionName: "setContract",
|
|
34
|
-
args: [BigInt(set)],
|
|
35
|
-
}));
|
|
36
|
-
const value = parseUnits(opts.value || "0", 18);
|
|
37
|
-
const { request } = await publicClient.simulateContract({
|
|
38
|
-
address: objectMinter,
|
|
39
|
-
abi: abi.mint,
|
|
40
|
-
functionName: "mint",
|
|
41
|
-
args: [
|
|
42
|
-
args0[1],
|
|
43
|
-
setContract,
|
|
44
|
-
BigInt(id),
|
|
45
|
-
(args0[2] || "0x"),
|
|
46
|
-
opts.auth || "0x",
|
|
47
|
-
Number(opts.policy || "0"),
|
|
48
|
-
],
|
|
49
|
-
account,
|
|
50
|
-
value,
|
|
51
|
-
});
|
|
52
|
-
const hash = await walletClient.writeContract(request);
|
|
53
|
-
console.log(`Transaction sent: ${hash}`);
|
|
54
|
-
console.log("Transaction mining...");
|
|
55
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
56
|
-
console.log("Transaction mined");
|
|
57
|
-
if (receipt.logs && receipt.logs.length > 0) {
|
|
58
|
-
const parsedLogs = parseEventLogs({ abi: abi.mint, logs: receipt.logs });
|
|
59
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
60
|
-
parsedLogs.forEach((log) => {
|
|
61
|
-
console.log(" - Event", log.eventName, stringify(log.args));
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
}
|
package/dist/relate.js
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import { defaultWriteFunctionOptions } from "./cmds.js";
|
|
3
|
-
import { getClientsEth, stringify } from "./utils.js";
|
|
4
|
-
import { getUniverseConfig } from "./config.js";
|
|
5
|
-
import { parseEventLogs } from "viem";
|
|
6
|
-
import { abi } from "./abi.js";
|
|
7
|
-
export function genRelateCommand() {
|
|
8
|
-
const cmd = new Command()
|
|
9
|
-
.name("relate")
|
|
10
|
-
.description("Link a tail object to a head object through a relation")
|
|
11
|
-
.argument("<tail>", "tail node, in form of [[data.]grant.]set.id")
|
|
12
|
-
.argument("<rel>", "relation ID")
|
|
13
|
-
.argument("<head>", "head node in form of [grant.]set.id, ")
|
|
14
|
-
.action(async function () {
|
|
15
|
-
await action(this, "relate");
|
|
16
|
-
});
|
|
17
|
-
defaultWriteFunctionOptions().forEach((option) => cmd.addOption(option));
|
|
18
|
-
return cmd;
|
|
19
|
-
}
|
|
20
|
-
export function genUnrelateCommand() {
|
|
21
|
-
const cmd = new Command()
|
|
22
|
-
.name("unrelate")
|
|
23
|
-
.description("Unlinks a tail object from a head object")
|
|
24
|
-
.argument("<tail>", "tail node, in form of [[data.]grant.]set.id")
|
|
25
|
-
.argument("<rel>", "relation ID")
|
|
26
|
-
.argument("<head>", "head node in form of [grant.]set.id, ")
|
|
27
|
-
.action(async function () {
|
|
28
|
-
await action(this, "unrelate");
|
|
29
|
-
});
|
|
30
|
-
defaultWriteFunctionOptions().forEach((option) => cmd.addOption(option));
|
|
31
|
-
return cmd;
|
|
32
|
-
}
|
|
33
|
-
async function action(cmd, functionName) {
|
|
34
|
-
const opts = cmd.opts();
|
|
35
|
-
const args0 = cmd.args;
|
|
36
|
-
const conf = getUniverseConfig(opts);
|
|
37
|
-
const address = conf.contracts["OmniRegistry"];
|
|
38
|
-
const tail = parseNode4(args0[0]);
|
|
39
|
-
const rel = BigInt(args0[1]);
|
|
40
|
-
const head = parseNode3(args0[2]);
|
|
41
|
-
await sendTransaction(conf, opts, address, abi.relation, functionName, [tail, rel, head]);
|
|
42
|
-
}
|
|
43
|
-
async function sendTransaction(conf, opts, address, abi /* eslint-disable-line @typescript-eslint/no-explicit-any*/, functionName, args /* eslint-disable-line @typescript-eslint/no-explicit-any*/) {
|
|
44
|
-
const { publicClient, walletClient } = await getClientsEth(conf, opts);
|
|
45
|
-
const { request } = await publicClient.simulateContract({
|
|
46
|
-
address,
|
|
47
|
-
abi,
|
|
48
|
-
functionName: "relate",
|
|
49
|
-
args,
|
|
50
|
-
account: walletClient.account,
|
|
51
|
-
});
|
|
52
|
-
const hash = await walletClient.writeContract(request);
|
|
53
|
-
console.log(`Transaction sent: ${hash}`);
|
|
54
|
-
console.log("Transaction mining...");
|
|
55
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
56
|
-
console.log("Transaction mined");
|
|
57
|
-
if (receipt.logs && receipt.logs.length > 0) {
|
|
58
|
-
const parsedLogs = parseEventLogs({ abi: abi.relation, logs: receipt.logs });
|
|
59
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
60
|
-
parsedLogs.forEach((log) => {
|
|
61
|
-
console.log(" - Event", log.eventName, stringify(log.args));
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
function parseNode4(arg) {
|
|
66
|
-
const parts = arg.split(".");
|
|
67
|
-
let [data, grant, set, id] = [0n, 0n, 0n, 0n];
|
|
68
|
-
if (parts.length == 2) {
|
|
69
|
-
set = BigInt(parts[0]);
|
|
70
|
-
id = BigInt(parts[1]);
|
|
71
|
-
}
|
|
72
|
-
else if (parts.length == 3) {
|
|
73
|
-
grant = BigInt(parts[0]);
|
|
74
|
-
set = BigInt(parts[1]);
|
|
75
|
-
id = BigInt(parts[2]);
|
|
76
|
-
}
|
|
77
|
-
else if (parts.length == 4) {
|
|
78
|
-
data = BigInt(parts[0]);
|
|
79
|
-
grant = BigInt(parts[1]);
|
|
80
|
-
set = BigInt(parts[2]);
|
|
81
|
-
id = BigInt(parts[3]);
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
throw new Error("");
|
|
85
|
-
}
|
|
86
|
-
return (data << 192n) | (grant << 128n) | (set << 64n) | id;
|
|
87
|
-
}
|
|
88
|
-
function parseNode3(arg) {
|
|
89
|
-
const parts = arg.split(".");
|
|
90
|
-
let [grant, set, id] = [0n, 0n, 0n];
|
|
91
|
-
if (parts.length == 2) {
|
|
92
|
-
set = BigInt(parts[0]);
|
|
93
|
-
id = BigInt(parts[1]);
|
|
94
|
-
}
|
|
95
|
-
else if (parts.length == 3) {
|
|
96
|
-
grant = BigInt(parts[0]);
|
|
97
|
-
set = BigInt(parts[1]);
|
|
98
|
-
id = BigInt(parts[2]);
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
throw new Error("");
|
|
102
|
-
}
|
|
103
|
-
return (grant << 128n) | (set << 64n) | id;
|
|
104
|
-
}
|
package/dist/wallet.js
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import { Keyring } from "@polkadot/keyring";
|
|
3
|
-
import { mnemonicGenerate, cryptoWaitReady } from "@polkadot/util-crypto";
|
|
4
|
-
import { bytesToHex } from "viem";
|
|
5
|
-
import * as fs from "fs";
|
|
6
|
-
import { decodeSubstratePair, getPassword, getPasswordConfirm, loadKeystore, resolveKeystoreDir, resolveKeystoreFile, saveKeystore, } from "./utils.js";
|
|
7
|
-
// Wallet commands
|
|
8
|
-
export function genWalletCommands() {
|
|
9
|
-
const walletCmd = new Command().name("wallet").description("manage wallets");
|
|
10
|
-
// List command
|
|
11
|
-
const listCmd = new Command()
|
|
12
|
-
.name("list")
|
|
13
|
-
.description("List all wallets")
|
|
14
|
-
.option("--foundry", "use foundry keystore directory (~/.foundry/keystores)")
|
|
15
|
-
.option("--dir <dir>", "specify a custom keystore directory")
|
|
16
|
-
.action(async (options) => {
|
|
17
|
-
const dir = resolveKeystoreDir(options);
|
|
18
|
-
const files = fs.readdirSync(dir);
|
|
19
|
-
files.forEach((file) => console.log(file));
|
|
20
|
-
});
|
|
21
|
-
// Generate command
|
|
22
|
-
const generateCmd = new Command()
|
|
23
|
-
.name("new")
|
|
24
|
-
.description("Generate a new wallet")
|
|
25
|
-
.option("-t, --type <type>", "key type (ed25519, sr25519, ethereum)", "sr25519")
|
|
26
|
-
.option("-p, --password <password>", "password to encrypt the keystore")
|
|
27
|
-
.option("-P, --password-file <file>", "password file")
|
|
28
|
-
.option("--dir <dir>", "specify keystore directory")
|
|
29
|
-
.option("--foundry", "use foundry keystore directory (~/.foundry/keystores)")
|
|
30
|
-
.argument("<name>", "name of the wallet")
|
|
31
|
-
.action(async (name, options) => {
|
|
32
|
-
const password = getPasswordConfirm(options);
|
|
33
|
-
await cryptoWaitReady();
|
|
34
|
-
const keyring = new Keyring();
|
|
35
|
-
const mnemonic = mnemonicGenerate();
|
|
36
|
-
const pair = keyring.addFromUri(mnemonic, { name }, options.type);
|
|
37
|
-
const json = pair.toJson(password);
|
|
38
|
-
saveKeystore(json, name, options);
|
|
39
|
-
});
|
|
40
|
-
// Import command
|
|
41
|
-
const importCmd = new Command()
|
|
42
|
-
.name("import")
|
|
43
|
-
.description("Import a wallet from a secrete URI")
|
|
44
|
-
.option("-t, --type <type>", "key type (sr25519, ed25519, ethereum)", "sr25519")
|
|
45
|
-
.option("-p, --password <password>", "password to encrypt the keystore")
|
|
46
|
-
.option("-P, --password-file <file>", "password file")
|
|
47
|
-
.option("--dir <dir>", "specify a custom keystore directory")
|
|
48
|
-
.option("--foundry", "use foundry keystore directory (~/.foundry/keystores)")
|
|
49
|
-
.argument("<name>", "name of the wallet")
|
|
50
|
-
.argument("<suri>", "secret URI")
|
|
51
|
-
.action(async (name, suri, options) => {
|
|
52
|
-
const password = getPasswordConfirm(options);
|
|
53
|
-
await cryptoWaitReady();
|
|
54
|
-
const keyring = new Keyring({ type: options.type });
|
|
55
|
-
const pair = keyring.addFromUri(suri);
|
|
56
|
-
const json = pair.toJson(password);
|
|
57
|
-
saveKeystore(json, name, options);
|
|
58
|
-
});
|
|
59
|
-
// Inspect command
|
|
60
|
-
const inspectCmd = new Command()
|
|
61
|
-
.name("inspect")
|
|
62
|
-
.description("Inspect a wallet")
|
|
63
|
-
.option("-t, --type <type>", "key type (sr25519, ed25519, ethereum)", "sr25519")
|
|
64
|
-
.option("-p, --password <password>", "password to decrypt the keystore")
|
|
65
|
-
.option("-P, --password-file <file>", "file containing the password")
|
|
66
|
-
.option("-x, --decrypt", "also decrypt the private key", false)
|
|
67
|
-
.option("--dir <dir>", "specify a custom keystore directory")
|
|
68
|
-
.option("--foundry", "use foundry keystore directory (~/.foundry/keystores)")
|
|
69
|
-
.argument("<name>", "name of the wallet")
|
|
70
|
-
.action(async (name, options) => {
|
|
71
|
-
const file = resolveKeystoreFile(name, options);
|
|
72
|
-
const keyData = loadKeystore(file);
|
|
73
|
-
await cryptoWaitReady();
|
|
74
|
-
const keyring = new Keyring({ type: options.type });
|
|
75
|
-
const account = keyring.addFromJson(keyData);
|
|
76
|
-
let password;
|
|
77
|
-
if (account.isLocked) {
|
|
78
|
-
password = getPassword(options);
|
|
79
|
-
account.unlock(password);
|
|
80
|
-
}
|
|
81
|
-
let decoded;
|
|
82
|
-
if (options.decrypt) {
|
|
83
|
-
decoded = decodeSubstratePair(keyData, password);
|
|
84
|
-
}
|
|
85
|
-
let keystoreDisplay = "~/.every/keystores";
|
|
86
|
-
if (options.foundry) {
|
|
87
|
-
keystoreDisplay = "~/.foundry/keystores";
|
|
88
|
-
}
|
|
89
|
-
else if (options.dir) {
|
|
90
|
-
keystoreDisplay = options.dir;
|
|
91
|
-
}
|
|
92
|
-
console.log(` Keystore: ${keystoreDisplay}`);
|
|
93
|
-
console.log(` Wallet: ${name}`);
|
|
94
|
-
console.log(` Type: ${account.type}`);
|
|
95
|
-
console.log(` Meta: ${JSON.stringify(account.meta)}`);
|
|
96
|
-
console.log(` Address: ${account.address}`);
|
|
97
|
-
console.log(`AddressRaw: ${bytesToHex(account.addressRaw)}`);
|
|
98
|
-
console.log(` PublicKey: ${bytesToHex(account.publicKey)}`);
|
|
99
|
-
if (decoded) {
|
|
100
|
-
console.log(`SecretKey: ${bytesToHex(decoded.secretKey)}`);
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
walletCmd.addCommand(listCmd);
|
|
104
|
-
walletCmd.addCommand(generateCmd);
|
|
105
|
-
walletCmd.addCommand(importCmd);
|
|
106
|
-
walletCmd.addCommand(inspectCmd);
|
|
107
|
-
return walletCmd;
|
|
108
|
-
}
|