@polkadot-api/cli 0.0.1-0a3edb2e805b29fa7d3ebb02c2084a125c4ee78b.1.0

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/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@polkadot-api/cli",
3
+ "version": "0.0.1-0a3edb2e805b29fa7d3ebb02c2084a125c4ee78b.1.0",
4
+ "license": "MIT",
5
+ "sideEffects": true,
6
+ "type": "module",
7
+ "prettier": {
8
+ "printWidth": 80,
9
+ "semi": false,
10
+ "trailingComma": "all"
11
+ },
12
+ "dependencies": {
13
+ "@inquirer/prompts": "^3.0.2",
14
+ "@substrate/connect": "^0.7.31",
15
+ "as-table": "^1.0.55",
16
+ "chalk": "^5.3.0",
17
+ "commander": "^11.0.0",
18
+ "fp-ts": "^2.16.1",
19
+ "fs.promises.exists": "^1.1.4",
20
+ "ora": "^7.0.1",
21
+ "rxjs": "^7.8.1",
22
+ "type-fest": "^4.3.1",
23
+ "write-pkg": "^6.0.0",
24
+ "zod": "^3.22.2",
25
+ "@polkadot-api/sc-provider": "0.0.1-0a3edb2e805b29fa7d3ebb02c2084a125c4ee78b.1.0",
26
+ "@polkadot-api/substrate-bindings": "0.0.1-0a3edb2e805b29fa7d3ebb02c2084a125c4ee78b.1.0",
27
+ "@polkadot-api/substrate-client": "0.0.1-0a3edb2e805b29fa7d3ebb02c2084a125c4ee78b.1.0",
28
+ "@polkadot-api/substrate-codegen": "0.0.1-0a3edb2e805b29fa7d3ebb02c2084a125c4ee78b.1.0",
29
+ "@polkadot-api/utils": "0.0.1-0a3edb2e805b29fa7d3ebb02c2084a125c4ee78b.1.0"
30
+ },
31
+ "scripts": {
32
+ "build": "tsup-node src/main.ts --clean --out-dir build --sourcemap --platform node --format esm",
33
+ "start": "pnpm build && node --enable-source-maps build/main.js",
34
+ "start:interactive": "pnpm start -- -i",
35
+ "test": "echo 'no tests'",
36
+ "lint": "prettier --check README.md \"src/**/*.{js,jsx,ts,tsx,json,md}\"",
37
+ "format": "prettier --write README.md \"src/**/*.{js,jsx,ts,tsx,json,md}\""
38
+ }
39
+ }
@@ -0,0 +1,38 @@
1
+ import { checkbox } from "@inquirer/prompts"
2
+ import { ReadonlyRecord } from "fp-ts/lib/ReadonlyRecord"
3
+ import util from "util"
4
+
5
+ export class CheckboxData {
6
+ #data: Record<string, bigint>
7
+
8
+ constructor(data?: Record<string, bigint>) {
9
+ this.#data = data ?? {}
10
+ }
11
+
12
+ get data(): ReadonlyRecord<string, bigint> {
13
+ return this.#data
14
+ }
15
+
16
+ async prompt(message: string, items: [string, bigint][]) {
17
+ const selected = await checkbox({
18
+ message,
19
+ choices: items.map(([s, checksum]) => ({
20
+ name: s,
21
+ value: [s, checksum] as const,
22
+ checked: s in this.#data,
23
+ })),
24
+ })
25
+
26
+ for (const [s, checksum] of selected) {
27
+ this.#data[s] = checksum
28
+ }
29
+ }
30
+
31
+ [util.inspect.custom]() {
32
+ return this.toJSON()
33
+ }
34
+
35
+ toJSON() {
36
+ return this.#data
37
+ }
38
+ }
@@ -0,0 +1,119 @@
1
+ import { select, checkbox, confirm } from "@inquirer/prompts"
2
+ import type { ReadonlyRecord } from "fp-ts/lib/ReadonlyRecord"
3
+ import util from "util"
4
+
5
+ type Data = Record<
6
+ string,
7
+ {
8
+ checksum: bigint
9
+ events: Record<string, Set<string>>
10
+ errors: Record<string, Set<string>>
11
+ }
12
+ >
13
+
14
+ export class ExtrinsicData {
15
+ #data: Data
16
+
17
+ constructor(data?: Data) {
18
+ this.#data = data ?? {}
19
+ }
20
+
21
+ get data(): ReadonlyRecord<
22
+ string,
23
+ Readonly<{
24
+ events: ReadonlyRecord<string, ReadonlySet<string>>
25
+ errors: ReadonlyRecord<string, ReadonlySet<string>>
26
+ }>
27
+ > {
28
+ return this.#data
29
+ }
30
+
31
+ async prompt(
32
+ extrinsics: [name: string, checksum: bigint][],
33
+ events: ReadonlyArray<readonly [pallet: string, event: string]>,
34
+ errors: ReadonlyArray<readonly [pallet: string, event: string]>,
35
+ ) {
36
+ const [ext, checksum] = await select({
37
+ message: "Select an extrinsic",
38
+ choices: extrinsics.map(([s, checksum]) => ({
39
+ name: s,
40
+ value: [s, checksum],
41
+ })),
42
+ })
43
+
44
+ if (ext in this.#data) {
45
+ const deleteExt = await confirm({ message: "Delete extrinsic?" })
46
+ if (deleteExt) {
47
+ delete this.#data[ext]
48
+ return
49
+ }
50
+ }
51
+
52
+ if (!this.#data[ext]) {
53
+ this.#data[ext] = { events: {}, errors: {}, checksum }
54
+ }
55
+ for (const [pallet, _] of events) {
56
+ if (!this.#data[ext].events[pallet]) {
57
+ this.#data[ext].events[pallet] = new Set()
58
+ }
59
+ }
60
+ for (const [pallet, _] of errors) {
61
+ if (!this.#data[ext].errors[pallet]) {
62
+ this.#data[ext].errors[pallet] = new Set()
63
+ }
64
+ }
65
+ const selectedEvents = this.#data[ext].events
66
+ const selectedErrors = this.#data[ext].errors
67
+
68
+ const newSelectedEvents = await checkbox({
69
+ message: "Select Events for this extrinsic",
70
+ choices: events.map(([pallet, event]) => ({
71
+ name: `${pallet} - ${event}`,
72
+ value: [pallet, event] as [pallet: string, event: string],
73
+ checked: selectedEvents[pallet].has(event),
74
+ })),
75
+ })
76
+ const newSelectedErrors = await checkbox({
77
+ message: "Select Errors for this extrinsic",
78
+ choices: errors.map(([pallet, error]) => ({
79
+ name: `${pallet} - ${error}`,
80
+ value: [pallet, error] as [pallet: string, event: string],
81
+ checked: selectedErrors[pallet].has(error),
82
+ })),
83
+ })
84
+
85
+ for (const [pallet, _] of newSelectedEvents) {
86
+ this.#data[ext].events[pallet].clear()
87
+ }
88
+ for (const [pallet, _] of newSelectedErrors) {
89
+ this.#data[ext].errors[pallet].clear()
90
+ }
91
+ for (const [pallet, event] of newSelectedEvents) {
92
+ this.#data[ext].events[pallet].add(event)
93
+ }
94
+ for (const [pallet, error] of newSelectedErrors) {
95
+ this.#data[ext].errors[pallet].add(error)
96
+ }
97
+ }
98
+
99
+ [util.inspect.custom]() {
100
+ return this.toJSON()
101
+ }
102
+
103
+ toJSON() {
104
+ return Object.fromEntries(
105
+ Object.entries(this.#data).map(([k, v]) => [
106
+ k,
107
+ {
108
+ checksum: v.checksum,
109
+ events: Object.fromEntries(
110
+ Object.entries(v.events).map(([k, v]) => [k, Array.from(v)]),
111
+ ),
112
+ errors: Object.fromEntries(
113
+ Object.entries(v.errors).map(([k, v]) => [k, Array.from(v)]),
114
+ ),
115
+ },
116
+ ]),
117
+ )
118
+ }
119
+ }
@@ -0,0 +1,3 @@
1
+ ;(BigInt.prototype as any).toJSON = function () {
2
+ return this.toString()
3
+ }
@@ -0,0 +1,48 @@
1
+ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
2
+ // This module is browser compatible.
3
+
4
+ // TODO(ry) It'd be better to make Deferred a class that inherits from
5
+ // Promise, rather than an interface. This is possible in ES2016, however
6
+ // typescript produces broken code when targeting ES5 code.
7
+ // See https://github.com/Microsoft/TypeScript/issues/15202
8
+ // At the time of writing, the github issue is closed but the problem remains.
9
+ export interface Deferred<T> extends Promise<T> {
10
+ readonly state: "pending" | "fulfilled" | "rejected"
11
+ resolve(value?: T | PromiseLike<T>): void
12
+ // deno-lint-ignore no-explicit-any
13
+ reject(reason?: any): void
14
+ }
15
+
16
+ /**
17
+ * Creates a Promise with the `reject` and `resolve` functions placed as methods
18
+ * on the promise object itself.
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * import { deferred } from "https://deno.land/std@$STD_VERSION/async/deferred.ts";
23
+ *
24
+ * const p = deferred<number>();
25
+ * // ...
26
+ * p.resolve(42);
27
+ * ```
28
+ */
29
+ export function deferred<T>(): Deferred<T> {
30
+ let methods
31
+ let state = "pending"
32
+ const promise = new Promise<T>((resolve, reject) => {
33
+ methods = {
34
+ async resolve(value: T | PromiseLike<T>) {
35
+ await value
36
+ state = "fulfilled"
37
+ resolve(value)
38
+ },
39
+ // deno-lint-ignore no-explicit-any
40
+ reject(reason?: any) {
41
+ state = "rejected"
42
+ reject(reason)
43
+ },
44
+ }
45
+ })
46
+ Object.defineProperty(promise, "state", { get: () => state })
47
+ return Object.assign(promise, methods) as Deferred<T>
48
+ }
@@ -0,0 +1,19 @@
1
+ import { z } from "zod"
2
+
3
+ export default z.record(
4
+ z.object({
5
+ constants: z.record(z.coerce.bigint()).optional(),
6
+ storage: z.record(z.coerce.bigint()).optional(),
7
+ events: z.record(z.coerce.bigint()).optional(),
8
+ errors: z.record(z.coerce.bigint()).optional(),
9
+ extrinsics: z
10
+ .record(
11
+ z.object({
12
+ checksum: z.coerce.bigint(),
13
+ events: z.record(z.array(z.string()).transform((s) => new Set(s))),
14
+ errors: z.record(z.array(z.string()).transform((s) => new Set(s))),
15
+ }),
16
+ )
17
+ .optional(),
18
+ }),
19
+ )
package/src/guards.ts ADDED
@@ -0,0 +1,20 @@
1
+ import { LookupEntry } from "@polkadot-api/substrate-codegen"
2
+ import { CodecType, metadata } from "@polkadot-api/substrate-bindings"
3
+
4
+ type Metadata = CodecType<typeof metadata>["metadata"]
5
+
6
+ export function assertMetadataIsv14(
7
+ metadata: Metadata,
8
+ ): asserts metadata is Metadata & { tag: "v14" } {
9
+ if (metadata.tag !== "v14") {
10
+ throw new Error("unreachable")
11
+ }
12
+ }
13
+
14
+ export function assertLookupEntryIsEnum(
15
+ lookupEntry: LookupEntry,
16
+ ): asserts lookupEntry is LookupEntry & { type: "enum" } {
17
+ if (lookupEntry.type !== "enum") {
18
+ throw new Error("not an enum")
19
+ }
20
+ }