Compare commits
9 Commits
quantus-si
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
b66b0a65c8
|
|||
|
9d7b002464
|
|||
|
ad670842b3
|
|||
|
32d8a6ecab
|
|||
|
2c8cefab07
|
|||
|
6358367b61
|
|||
|
84f60959d9
|
|||
|
0448d9df7a
|
|||
|
40927fa910
|
@@ -28,9 +28,23 @@ env:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# fedora-44 carries node + npm + pnpm (gitea-runners.md §4) and nothing else
|
||||
# is needed — there is no Rust half here.
|
||||
runs-on: fedora-44
|
||||
# `rust`, not `fedora-44`, despite there being no Rust here.
|
||||
#
|
||||
# The fedora-4x images list pnpm (gitea-runners.md §4) but their pnpm cannot
|
||||
# run: `@pnpm/exe` is a native binary and the images lack libatomic, so the
|
||||
# very first step dies with
|
||||
#
|
||||
# pnpm: error while loading shared libraries: libatomic.so.1
|
||||
#
|
||||
# `runner-rust` is built on `runner-fedora-44` and adds gcc, musl-gcc and
|
||||
# cmake, which pull libatomic in as a side effect — which is why
|
||||
# blackbeard.observer builds its SPA there and this one now does too.
|
||||
#
|
||||
# This is a workaround for a runner-image bug, not the fix. The fix is
|
||||
# libatomic in the fedora-4x Containerfiles (gitea-runners.md §5: bake build
|
||||
# dependencies into the image, not the workflow). Move back when that lands;
|
||||
# a 4 CPU / 4 GiB image to run `vite build` is more than this needs.
|
||||
runs-on: rust
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -44,7 +58,7 @@ jobs:
|
||||
# shipping a console that rejects every Quantus signature at run time.
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: the patch is applied
|
||||
- name: verify the signers-common patch
|
||||
# Cheap, and it is the one thing about this fork that a normal build
|
||||
# would not notice going missing. Without it every signing attempt dies
|
||||
# with `Unkown signer` — in the browser, after deploy, to a user.
|
||||
|
||||
@@ -30,7 +30,7 @@ signing attempt raised `Unkown signer` before reaching code that would have work
|
||||
straight in.
|
||||
|
||||
`patches/@polkadot-api__signers-common.patch` drops the names and keeps the structural
|
||||
check. See [quantus/papi-console#1](https://git.lair.cafe/quantus/papi-console/issues/1).
|
||||
check. See [quantus/papi-console#1](https://git.lair.cafe/blackbeard/qapi/issues/1).
|
||||
|
||||
## Develop
|
||||
|
||||
|
||||
112
patches/@polkadot-api__substrate-bindings@0.21.0.patch
Normal file
112
patches/@polkadot-api__substrate-bindings@0.21.0.patch
Normal file
@@ -0,0 +1,112 @@
|
||||
diff --git a/dist/codecs/blockHeader.js b/dist/codecs/blockHeader.js
|
||||
index 0675e59633a14c34148e90aa8c32bcfbc437330c..3cb9f47e889827d3b9d2c8490418176eda2d7590 100644
|
||||
--- a/dist/codecs/blockHeader.js
|
||||
+++ b/dist/codecs/blockHeader.js
|
||||
@@ -1,4 +1,4 @@
|
||||
-import { enhanceCodec, Bytes, _void } from 'scale-ts';
|
||||
+import { enhanceCodec, Bytes, _void, u32 } from 'scale-ts';
|
||||
import '../utils/ss58-util.js';
|
||||
import './scale/Binary.js';
|
||||
import './scale/bitSequence.js';
|
||||
@@ -33,7 +33,23 @@ const diggest = Variant(
|
||||
[0, 4, 5, 6, 8]
|
||||
);
|
||||
const hex32 = Hex(32);
|
||||
-const blockHeader = Struct({
|
||||
+
|
||||
+// Quantus patch: this console serves two header layouts.
|
||||
+//
|
||||
+// `sp_runtime::generic::Header` encodes `number` with #[codec(compact)] and has
|
||||
+// no field between `extrinsics_root` and `digest`. Quantus's `qp_header::Header`
|
||||
+// does neither: `number` is a plain u32, and a `zk_tree_root: H256` sits before
|
||||
+// the digest — deliberately, so the ZK root has a fixed offset in the header
|
||||
+// preimage that miners cannot shift by manipulating the digest.
|
||||
+//
|
||||
+// Reading a Quantus header as a Substrate one consumes 2 bytes where 4 were
|
||||
+// written; every field after shifts, and the digest vector eventually reads a
|
||||
+// byte that is not a known DigestItem index. That surfaces three layers away as
|
||||
+// `TypeError: innerDecoder is not a function`, papi retries the subfollow
|
||||
+// forever, `runtime$` never emits, and the page renders nothing at all.
|
||||
+//
|
||||
+// See quantus/papi-console#4.
|
||||
+const substrateHeader = Struct({
|
||||
parentHash: hex32,
|
||||
number: compactNumber,
|
||||
stateRoot: hex32,
|
||||
@@ -41,5 +57,76 @@ const blockHeader = Struct({
|
||||
digests: Vector(diggest)
|
||||
});
|
||||
|
||||
+const quantusHeader = Struct({
|
||||
+ parentHash: hex32,
|
||||
+ number: u32,
|
||||
+ stateRoot: hex32,
|
||||
+ extrinsicRoot: hex32,
|
||||
+ zkTreeRoot: hex32,
|
||||
+ digests: Vector(diggest)
|
||||
+});
|
||||
+
|
||||
+const asBytes = (input) =>
|
||||
+ typeof input === "string"
|
||||
+ ? Uint8Array.from(
|
||||
+ input
|
||||
+ .slice(2)
|
||||
+ .match(/../g)
|
||||
+ ?.map((b) => parseInt(b, 16)) ?? []
|
||||
+ )
|
||||
+ : input;
|
||||
+
|
||||
+const sameBytes = (a, b) =>
|
||||
+ a.length === b.length && a.every((x, i) => x === b[i]);
|
||||
+
|
||||
+// Decide by round trip, not by guessing. A layout is right only if decoding and
|
||||
+// re-encoding reproduces the input byte for byte — which also catches a short
|
||||
+// read, trailing bytes, and a non-canonical compact. Trying the layouts in a
|
||||
+// fixed order and taking the first that survives that check is deterministic;
|
||||
+// picking one by inspecting a byte would not be.
|
||||
+const decodeEitherLayout = (input) => {
|
||||
+ // `archive.header$` in @polkadot-api/observable-client maps the RPC result
|
||||
+ // straight through this decoder with no null check, and `archive_v1_header`
|
||||
+ // answers `null` for any hash the node does not know. scale-ts then reaches
|
||||
+ // `new DataView(null)`, which V8 reports as "First argument to DataView
|
||||
+ // constructor must be an ArrayBuffer" and Firefox as "e is not an object" —
|
||||
+ // neither of which mentions blocks, headers, or the node.
|
||||
+ //
|
||||
+ // It happens in bursts on a chain switch: the block list still holds the
|
||||
+ // previous chain's hashes, and every one of them is unknown to the new node.
|
||||
+ // Harmless, but it needs to say so.
|
||||
+ if (input == null)
|
||||
+ throw new Error("no block header: the node does not know this block");
|
||||
+
|
||||
+ const bytes = asBytes(input);
|
||||
+ let firstError;
|
||||
+
|
||||
+ for (const codec of [substrateHeader, quantusHeader]) {
|
||||
+ try {
|
||||
+ const value = codec.dec(bytes);
|
||||
+
|
||||
+ if (sameBytes(codec.enc(value), bytes)) return value;
|
||||
+ } catch (error) {
|
||||
+ firstError ??= error;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ throw firstError ?? new Error("block header matches no known layout");
|
||||
+};
|
||||
+
|
||||
+// Keep every property the original codec carried and override only the decoder.
|
||||
+// A scale-ts Struct exposes `inner` — its field codecs — and consumers reach for
|
||||
+// it: this console's own block.state.ts does `blockHeader.inner.digests.inner`.
|
||||
+// Replacing the codec with a bare [enc, dec] pair drops that, block.state.ts
|
||||
+// throws while its module is evaluating, `createRoot().render()` never runs, and
|
||||
+// the page is blank with no error on screen — the same symptom as the bug this
|
||||
+// patch exists to fix, from the opposite cause.
|
||||
+const blockHeader = Object.assign([], substrateHeader, {
|
||||
+ 0: substrateHeader.enc,
|
||||
+ 1: decodeEitherLayout,
|
||||
+ enc: substrateHeader.enc,
|
||||
+ dec: decodeEitherLayout
|
||||
+});
|
||||
+
|
||||
export { blockHeader };
|
||||
//# sourceMappingURL=blockHeader.js.map
|
||||
112
patches/@polkadot-api__substrate-bindings@0.21.1.patch
Normal file
112
patches/@polkadot-api__substrate-bindings@0.21.1.patch
Normal file
@@ -0,0 +1,112 @@
|
||||
diff --git a/dist/codecs/blockHeader.js b/dist/codecs/blockHeader.js
|
||||
index 0675e59633a14c34148e90aa8c32bcfbc437330c..3cb9f47e889827d3b9d2c8490418176eda2d7590 100644
|
||||
--- a/dist/codecs/blockHeader.js
|
||||
+++ b/dist/codecs/blockHeader.js
|
||||
@@ -1,4 +1,4 @@
|
||||
-import { enhanceCodec, Bytes, _void } from 'scale-ts';
|
||||
+import { enhanceCodec, Bytes, _void, u32 } from 'scale-ts';
|
||||
import '../utils/ss58-util.js';
|
||||
import './scale/Binary.js';
|
||||
import './scale/bitSequence.js';
|
||||
@@ -33,7 +33,23 @@ const diggest = Variant(
|
||||
[0, 4, 5, 6, 8]
|
||||
);
|
||||
const hex32 = Hex(32);
|
||||
-const blockHeader = Struct({
|
||||
+
|
||||
+// Quantus patch: this console serves two header layouts.
|
||||
+//
|
||||
+// `sp_runtime::generic::Header` encodes `number` with #[codec(compact)] and has
|
||||
+// no field between `extrinsics_root` and `digest`. Quantus's `qp_header::Header`
|
||||
+// does neither: `number` is a plain u32, and a `zk_tree_root: H256` sits before
|
||||
+// the digest — deliberately, so the ZK root has a fixed offset in the header
|
||||
+// preimage that miners cannot shift by manipulating the digest.
|
||||
+//
|
||||
+// Reading a Quantus header as a Substrate one consumes 2 bytes where 4 were
|
||||
+// written; every field after shifts, and the digest vector eventually reads a
|
||||
+// byte that is not a known DigestItem index. That surfaces three layers away as
|
||||
+// `TypeError: innerDecoder is not a function`, papi retries the subfollow
|
||||
+// forever, `runtime$` never emits, and the page renders nothing at all.
|
||||
+//
|
||||
+// See quantus/papi-console#4.
|
||||
+const substrateHeader = Struct({
|
||||
parentHash: hex32,
|
||||
number: compactNumber,
|
||||
stateRoot: hex32,
|
||||
@@ -41,5 +57,76 @@ const blockHeader = Struct({
|
||||
digests: Vector(diggest)
|
||||
});
|
||||
|
||||
+const quantusHeader = Struct({
|
||||
+ parentHash: hex32,
|
||||
+ number: u32,
|
||||
+ stateRoot: hex32,
|
||||
+ extrinsicRoot: hex32,
|
||||
+ zkTreeRoot: hex32,
|
||||
+ digests: Vector(diggest)
|
||||
+});
|
||||
+
|
||||
+const asBytes = (input) =>
|
||||
+ typeof input === "string"
|
||||
+ ? Uint8Array.from(
|
||||
+ input
|
||||
+ .slice(2)
|
||||
+ .match(/../g)
|
||||
+ ?.map((b) => parseInt(b, 16)) ?? []
|
||||
+ )
|
||||
+ : input;
|
||||
+
|
||||
+const sameBytes = (a, b) =>
|
||||
+ a.length === b.length && a.every((x, i) => x === b[i]);
|
||||
+
|
||||
+// Decide by round trip, not by guessing. A layout is right only if decoding and
|
||||
+// re-encoding reproduces the input byte for byte — which also catches a short
|
||||
+// read, trailing bytes, and a non-canonical compact. Trying the layouts in a
|
||||
+// fixed order and taking the first that survives that check is deterministic;
|
||||
+// picking one by inspecting a byte would not be.
|
||||
+const decodeEitherLayout = (input) => {
|
||||
+ // `archive.header$` in @polkadot-api/observable-client maps the RPC result
|
||||
+ // straight through this decoder with no null check, and `archive_v1_header`
|
||||
+ // answers `null` for any hash the node does not know. scale-ts then reaches
|
||||
+ // `new DataView(null)`, which V8 reports as "First argument to DataView
|
||||
+ // constructor must be an ArrayBuffer" and Firefox as "e is not an object" —
|
||||
+ // neither of which mentions blocks, headers, or the node.
|
||||
+ //
|
||||
+ // It happens in bursts on a chain switch: the block list still holds the
|
||||
+ // previous chain's hashes, and every one of them is unknown to the new node.
|
||||
+ // Harmless, but it needs to say so.
|
||||
+ if (input == null)
|
||||
+ throw new Error("no block header: the node does not know this block");
|
||||
+
|
||||
+ const bytes = asBytes(input);
|
||||
+ let firstError;
|
||||
+
|
||||
+ for (const codec of [substrateHeader, quantusHeader]) {
|
||||
+ try {
|
||||
+ const value = codec.dec(bytes);
|
||||
+
|
||||
+ if (sameBytes(codec.enc(value), bytes)) return value;
|
||||
+ } catch (error) {
|
||||
+ firstError ??= error;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ throw firstError ?? new Error("block header matches no known layout");
|
||||
+};
|
||||
+
|
||||
+// Keep every property the original codec carried and override only the decoder.
|
||||
+// A scale-ts Struct exposes `inner` — its field codecs — and consumers reach for
|
||||
+// it: this console's own block.state.ts does `blockHeader.inner.digests.inner`.
|
||||
+// Replacing the codec with a bare [enc, dec] pair drops that, block.state.ts
|
||||
+// throws while its module is evaluating, `createRoot().render()` never runs, and
|
||||
+// the page is blank with no error on screen — the same symptom as the bug this
|
||||
+// patch exists to fix, from the opposite cause.
|
||||
+const blockHeader = Object.assign([], substrateHeader, {
|
||||
+ 0: substrateHeader.enc,
|
||||
+ 1: decodeEitherLayout,
|
||||
+ enc: substrateHeader.enc,
|
||||
+ dec: decodeEitherLayout
|
||||
+});
|
||||
+
|
||||
export { blockHeader };
|
||||
//# sourceMappingURL=blockHeader.js.map
|
||||
89
patches/@polkahub__pjs-wallet@0.9.1.patch
Normal file
89
patches/@polkahub__pjs-wallet@0.9.1.patch
Normal file
@@ -0,0 +1,89 @@
|
||||
diff --git a/dist/ManagePjsWallet.js b/dist/ManagePjsWallet.js
|
||||
index ec891b30a0bda8eb60b0ec647262ad334c04db89..03c93af0448018b58ef8abc2395e56b330d64038 100644
|
||||
--- a/dist/ManagePjsWallet.js
|
||||
+++ b/dist/ManagePjsWallet.js
|
||||
@@ -4,38 +4,16 @@ import { cn, SourceButton } from '@polkahub/ui-components';
|
||||
import { state, useStateObservable } from '@react-rxjs/core';
|
||||
import { CircleQuestionMark } from 'lucide-react';
|
||||
import { filter, switchMap } from 'rxjs';
|
||||
-import nova from './assets/nova.webp.js';
|
||||
-import pjs from './assets/pjs.webp.js';
|
||||
-import subwallet from './assets/subwallet.webp.js';
|
||||
-import talisman from './assets/talisman.webp.js';
|
||||
-import polkagate from './assets/polkagate.webp.js';
|
||||
-import fearless from './assets/fearless.webp.js';
|
||||
+import blackbeard from './assets/blackbeard.svg.js';
|
||||
import { pjsWalletProviderId } from './provider.js';
|
||||
|
||||
+// Only extensions that sign ML-DSA are listed: the Quantus runtime accepts no
|
||||
+// other signature, so offering polkadot{.js}, Talisman and the rest would
|
||||
+// connect wallets that can never sign here. Patched in qapi.
|
||||
const knownExtensions = {
|
||||
- "polkadot-js": {
|
||||
- name: "Polkadot JS",
|
||||
- logo: pjs
|
||||
- },
|
||||
- "nova-wallet": {
|
||||
- name: "Nova Wallet",
|
||||
- logo: nova
|
||||
- },
|
||||
- talisman: {
|
||||
- name: "Talisman",
|
||||
- logo: talisman
|
||||
- },
|
||||
- "subwallet-js": {
|
||||
- name: "Subwallet",
|
||||
- logo: subwallet
|
||||
- },
|
||||
- polkagate: {
|
||||
- name: "Polkagate",
|
||||
- logo: polkagate
|
||||
- },
|
||||
- "fearless-wallet": {
|
||||
- name: "Fearless Wallet",
|
||||
- logo: fearless
|
||||
+ blackbeard: {
|
||||
+ name: "blackbeard",
|
||||
+ logo: blackbeard
|
||||
}
|
||||
};
|
||||
const [pjsWalletPlugin$, useExternalizedPlugin] = externalizePlugin(pjsWalletProviderId);
|
||||
diff --git a/dist/assets/blackbeard.svg.js b/dist/assets/blackbeard.svg.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..4dfb32200a16b6c32b258d0519cd6c820a3bf9ab
|
||||
--- /dev/null
|
||||
+++ b/dist/assets/blackbeard.svg.js
|
||||
@@ -0,0 +1,4 @@
|
||||
+// blackbeard's sigil, the Quantus post-quantum wallet (quantus/extension#15)
|
||||
+var blackbeard = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MCA0MCIgd2lkdGg9IjQwIiBoZWlnaHQ9IjQwIj4KICA8IS0tIGJsYWNrYmVhcmQub2JzZXJ2ZXIncyBzaWdpbCwgY2VudHJlZCBvbiBhIHNxdWFyZSBmb3IgaWNvbnMgLS0+CiAgPHJlY3Qgd2lkdGg9IjQwIiBoZWlnaHQ9IjQwIiByeD0iNiIgZmlsbD0iIzBkMGIwOSIvPgogIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMgMCkiPgogICAgPHBhdGggZD0iTTE3IDEgTDMyIDcgVjIwIEMzMiAyOSAyNSAzNSAxNyAzOSBDOSAzNSAyIDI5IDIgMjAgVjcgWiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYmQ4ODI5IiBzdHJva2Utd2lkdGg9IjEuNiIvPgogICAgPHBhdGggZD0iTTE3IDggTDI0IDEyIFYyMSBDMjQgMjYgMjAuNSAyOS41IDE3IDMxLjUgQzEzLjUgMjkuNSAxMCAyNiAxMCAyMSBWMTIgWiIgZmlsbD0iI2JkODgyOTIyIi8+CiAgICA8cGF0aCBkPSJNMTcgMTEgVjI4IiBzdHJva2U9IiNkODQ1M2EiIHN0cm9rZS13aWR0aD0iMS42Ii8+CiAgICA8cGF0aCBkPSJNMTMgMTUgTDE3IDExIEwyMSAxNSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZDg0NTNhIiBzdHJva2Utd2lkdGg9IjEuNiIvPgogIDwvZz4KPC9zdmc+Cg==";
|
||||
+
|
||||
+export { blackbeard as default };
|
||||
diff --git a/dist/provider.js b/dist/provider.js
|
||||
index a0a44532893fc9b9b3d9c449c40362e60cfa3b95..d8f90bf491ea5fc4f708d456d2c3037255bc6dc8 100644
|
||||
--- a/dist/provider.js
|
||||
+++ b/dist/provider.js
|
||||
@@ -6,6 +6,10 @@ import { getSs58AddressInfo } from 'polkadot-api';
|
||||
import { concat, timer, map, filter, take, interval, switchMap, defer, retry, fromEventPattern, startWith, catchError, tap, ignoreElements, NEVER, shareReplay, firstValueFrom, scan } from 'rxjs';
|
||||
|
||||
const pjsWalletProviderId = "pjs-wallet";
|
||||
+// Patched in qapi: only extensions that can sign for a post-quantum chain are
|
||||
+// offered or connected. Anything else injected into the page is ignored.
|
||||
+const PQ_EXTENSIONS = ["blackbeard"];
|
||||
+const getPqExtensions = () => getInjectedExtensions().filter((name) => PQ_EXTENSIONS.includes(name));
|
||||
const createPjsWalletProvider = (opts) => {
|
||||
const { persist, accountFormat } = {
|
||||
persist: localStorageProvider("pjs-wallet-plugin"),
|
||||
@@ -15,11 +19,11 @@ const createPjsWalletProvider = (opts) => {
|
||||
const availableExtensions$ = state(
|
||||
concat(
|
||||
timer(0, 100).pipe(
|
||||
- map(getInjectedExtensions),
|
||||
+ map(getPqExtensions),
|
||||
filter((v) => v.length > 0),
|
||||
take(1)
|
||||
),
|
||||
- interval(2e3).pipe(map(getInjectedExtensions))
|
||||
+ interval(2e3).pipe(map(getPqExtensions))
|
||||
),
|
||||
[]
|
||||
);
|
||||
87
pnpm-lock.yaml
generated
87
pnpm-lock.yaml
generated
@@ -6,6 +6,9 @@ settings:
|
||||
|
||||
patchedDependencies:
|
||||
'@polkadot-api/signers-common': 365a34617de2ae3ad2f7e009f7f3e20e0078448fbfc93c395d323f0e21b75d37
|
||||
'@polkadot-api/substrate-bindings@0.21.0': 44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537
|
||||
'@polkadot-api/substrate-bindings@0.21.1': 44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537
|
||||
'@polkahub/pjs-wallet@0.9.1': f359348c980dcf8a9f7077a067ffbc79e23c166172a4fa1be36de5340072104d
|
||||
react18-json-view: 962696fac5fe7ad3e94fd36dad07521c6c3eafd52f219ab335d52438387f6b66
|
||||
|
||||
importers:
|
||||
@@ -50,7 +53,7 @@ importers:
|
||||
version: 0.3.1(patch_hash=365a34617de2ae3ad2f7e009f7f3e20e0078448fbfc93c395d323f0e21b75d37)(rxjs@7.8.2)
|
||||
'@polkadot-api/substrate-bindings':
|
||||
specifier: ^0.21.1
|
||||
version: 0.21.1
|
||||
version: 0.21.1(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/tx-creator':
|
||||
specifier: ^0.2.0
|
||||
version: 0.2.0(rxjs@7.8.2)
|
||||
@@ -5024,7 +5027,7 @@ snapshots:
|
||||
'@paraspell/descriptors': 14.3.4(polkadot-api@3.1.0(esbuild@0.28.1)(rxjs@7.8.2))
|
||||
'@paraspell/sdk-core': 14.3.4(typescript@7.0.2)(zod@3.25.76)
|
||||
'@polkadot-api/signers-common': 0.3.1(patch_hash=365a34617de2ae3ad2f7e009f7f3e20e0078448fbfc93c395d323f0e21b75d37)(rxjs@7.8.2)
|
||||
'@polkadot-api/substrate-bindings': 0.21.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-labs/hdkd': 0.0.31
|
||||
'@polkadot-labs/hdkd-helpers': 0.0.33
|
||||
polkadot-api: 3.1.0(esbuild@0.28.1)(rxjs@7.8.2)
|
||||
@@ -5053,7 +5056,7 @@ snapshots:
|
||||
'@polkadot-api/observable-client': 0.19.0(rxjs@7.8.2)
|
||||
'@polkadot-api/sm-provider': 0.3.8(@polkadot-api/smoldot@0.4.7)
|
||||
'@polkadot-api/smoldot': 0.4.7
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/substrate-client': 0.7.0
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
'@polkadot-api/wasm-executor': 0.2.3
|
||||
@@ -5088,7 +5091,7 @@ snapshots:
|
||||
'@polkadot-api/observable-client': 0.19.1(rxjs@7.8.2)
|
||||
'@polkadot-api/sm-provider': 0.3.8(@polkadot-api/smoldot@0.4.7)
|
||||
'@polkadot-api/smoldot': 0.4.7
|
||||
'@polkadot-api/substrate-bindings': 0.21.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/substrate-client': 0.7.0
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
'@polkadot-api/wasm-executor': 0.2.3
|
||||
@@ -5117,7 +5120,7 @@ snapshots:
|
||||
'@polkadot-api/ink-contracts': 0.7.0
|
||||
'@polkadot-api/metadata-builders': 0.15.0
|
||||
'@polkadot-api/metadata-compatibility': 0.7.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
|
||||
'@polkadot-api/codegen@0.23.1':
|
||||
@@ -5125,7 +5128,7 @@ snapshots:
|
||||
'@polkadot-api/ink-contracts': 0.7.1
|
||||
'@polkadot-api/metadata-builders': 0.15.1
|
||||
'@polkadot-api/metadata-compatibility': 0.7.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
|
||||
'@polkadot-api/descriptors@file:.papi/descriptors(polkadot-api@3.1.0(esbuild@0.28.1)(rxjs@7.8.2))':
|
||||
@@ -5137,7 +5140,7 @@ snapshots:
|
||||
'@acala-network/chopsticks-executor': 1.5.1
|
||||
'@polkadot-api/metadata-builders': 0.15.0
|
||||
'@polkadot-api/observable-client': 0.19.0(rxjs@7.8.2)
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/substrate-client': 0.7.0
|
||||
'@polkadot-api/tx-utils': 0.6.0(rxjs@7.8.2)
|
||||
'@polkadot-api/ws-middleware': 0.4.0(rxjs@7.8.2)
|
||||
@@ -5164,13 +5167,13 @@ snapshots:
|
||||
'@polkadot-api/ink-contracts@0.7.0':
|
||||
dependencies:
|
||||
'@polkadot-api/metadata-builders': 0.15.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
|
||||
'@polkadot-api/ink-contracts@0.7.1':
|
||||
dependencies:
|
||||
'@polkadot-api/metadata-builders': 0.15.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
|
||||
'@polkadot-api/json-rpc-provider-proxy@0.1.0':
|
||||
@@ -5192,7 +5195,7 @@ snapshots:
|
||||
'@ledgerhq/hw-transport': 6.35.5
|
||||
'@polkadot-api/merkleize-metadata': 1.3.0
|
||||
'@polkadot-api/signers-common': 0.3.0(patch_hash=365a34617de2ae3ad2f7e009f7f3e20e0078448fbfc93c395d323f0e21b75d37)(rxjs@7.8.2)
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/tx-creator': 0.2.0(rxjs@7.8.2)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
transitivePeerDependencies:
|
||||
@@ -5205,32 +5208,32 @@ snapshots:
|
||||
'@polkadot-api/merkleize-metadata@1.3.0':
|
||||
dependencies:
|
||||
'@polkadot-api/metadata-builders': 0.15.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
|
||||
'@polkadot-api/merkleize-metadata@1.3.1':
|
||||
dependencies:
|
||||
'@polkadot-api/metadata-builders': 0.15.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
|
||||
'@polkadot-api/meta-signers@0.3.0':
|
||||
dependencies:
|
||||
'@polkadot-api/metadata-builders': 0.15.0
|
||||
'@polkadot-api/signers-common': 0.3.0(patch_hash=365a34617de2ae3ad2f7e009f7f3e20e0078448fbfc93c395d323f0e21b75d37)(rxjs@7.8.2)
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/tx-creator': 0.2.0(rxjs@7.8.2)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
rxjs: 7.8.2
|
||||
|
||||
'@polkadot-api/metadata-builders@0.15.0':
|
||||
dependencies:
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
|
||||
'@polkadot-api/metadata-builders@0.15.1':
|
||||
dependencies:
|
||||
'@polkadot-api/substrate-bindings': 0.21.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
|
||||
'@polkadot-api/metadata-builders@0.3.2':
|
||||
@@ -5242,17 +5245,17 @@ snapshots:
|
||||
'@polkadot-api/metadata-compatibility@0.7.0':
|
||||
dependencies:
|
||||
'@polkadot-api/metadata-builders': 0.15.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
|
||||
'@polkadot-api/metadata-compatibility@0.7.1':
|
||||
dependencies:
|
||||
'@polkadot-api/metadata-builders': 0.15.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
|
||||
'@polkadot-api/observable-client@0.19.0(rxjs@7.8.2)':
|
||||
dependencies:
|
||||
'@polkadot-api/metadata-builders': 0.15.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/substrate-client': 0.7.0
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
rxjs: 7.8.2
|
||||
@@ -5260,7 +5263,7 @@ snapshots:
|
||||
'@polkadot-api/observable-client@0.19.1(rxjs@7.8.2)':
|
||||
dependencies:
|
||||
'@polkadot-api/metadata-builders': 0.15.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/substrate-client': 0.7.0
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
rxjs: 7.8.2
|
||||
@@ -5278,7 +5281,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@polkadot-api/metadata-builders': 0.15.0
|
||||
'@polkadot-api/signers-common': 0.3.0(patch_hash=365a34617de2ae3ad2f7e009f7f3e20e0078448fbfc93c395d323f0e21b75d37)(rxjs@7.8.2)
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/tx-creator': 0.2.0(rxjs@7.8.2)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
transitivePeerDependencies:
|
||||
@@ -5288,7 +5291,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@polkadot-api/metadata-builders': 0.15.1
|
||||
'@polkadot-api/signers-common': 0.3.1(patch_hash=365a34617de2ae3ad2f7e009f7f3e20e0078448fbfc93c395d323f0e21b75d37)(rxjs@7.8.2)
|
||||
'@polkadot-api/substrate-bindings': 0.21.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/tx-creator': 0.2.0(rxjs@7.8.2)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
transitivePeerDependencies:
|
||||
@@ -5304,7 +5307,7 @@ snapshots:
|
||||
'@polkadot-api/merkleize-metadata': 1.3.0
|
||||
'@polkadot-api/metadata-builders': 0.15.0
|
||||
'@polkadot-api/signers-common': 0.3.0(patch_hash=365a34617de2ae3ad2f7e009f7f3e20e0078448fbfc93c395d323f0e21b75d37)(rxjs@7.8.2)
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/tx-creator': 0.2.0(rxjs@7.8.2)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
rxjs: 7.8.2
|
||||
@@ -5315,7 +5318,7 @@ snapshots:
|
||||
'@polkadot-api/merkleize-metadata': 1.3.1
|
||||
'@polkadot-api/metadata-builders': 0.15.1
|
||||
'@polkadot-api/signers-common': 0.3.1(patch_hash=365a34617de2ae3ad2f7e009f7f3e20e0078448fbfc93c395d323f0e21b75d37)(rxjs@7.8.2)
|
||||
'@polkadot-api/substrate-bindings': 0.21.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/tx-creator': 0.2.0(rxjs@7.8.2)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
rxjs: 7.8.2
|
||||
@@ -5323,7 +5326,7 @@ snapshots:
|
||||
'@polkadot-api/react-builder@0.6.1(react@19.2.8)':
|
||||
dependencies:
|
||||
'@polkadot-api/metadata-builders': 0.15.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
react: 19.2.8
|
||||
|
||||
@@ -5339,7 +5342,7 @@ snapshots:
|
||||
'@polkadot-api/signers-common@0.3.0(patch_hash=365a34617de2ae3ad2f7e009f7f3e20e0078448fbfc93c395d323f0e21b75d37)(rxjs@7.8.2)':
|
||||
dependencies:
|
||||
'@polkadot-api/metadata-builders': 0.15.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/tx-creator': 0.2.0(rxjs@7.8.2)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
rxjs: 7.8.2
|
||||
@@ -5347,7 +5350,7 @@ snapshots:
|
||||
'@polkadot-api/signers-common@0.3.1(patch_hash=365a34617de2ae3ad2f7e009f7f3e20e0078448fbfc93c395d323f0e21b75d37)(rxjs@7.8.2)':
|
||||
dependencies:
|
||||
'@polkadot-api/metadata-builders': 0.15.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/tx-creator': 0.2.0(rxjs@7.8.2)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
rxjs: 7.8.2
|
||||
@@ -5373,14 +5376,14 @@ snapshots:
|
||||
'@scure/base': 2.4.0
|
||||
scale-ts: 1.6.1
|
||||
|
||||
'@polkadot-api/substrate-bindings@0.21.0':
|
||||
'@polkadot-api/substrate-bindings@0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)':
|
||||
dependencies:
|
||||
'@noble/hashes': 2.4.0
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
'@scure/base': 2.4.0
|
||||
scale-ts: 1.6.1
|
||||
|
||||
'@polkadot-api/substrate-bindings@0.21.1':
|
||||
'@polkadot-api/substrate-bindings@0.21.1(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)':
|
||||
dependencies:
|
||||
'@noble/hashes': 2.4.0
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
@@ -5416,7 +5419,7 @@ snapshots:
|
||||
'@polkadot-api/merkleize-metadata': 1.3.0
|
||||
'@polkadot-api/metadata-builders': 0.15.0
|
||||
'@polkadot-api/signers-common': 0.3.0(patch_hash=365a34617de2ae3ad2f7e009f7f3e20e0078448fbfc93c395d323f0e21b75d37)(rxjs@7.8.2)
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
transitivePeerDependencies:
|
||||
- rxjs
|
||||
@@ -5426,7 +5429,7 @@ snapshots:
|
||||
'@polkadot-api/merkleize-metadata': 1.3.1
|
||||
'@polkadot-api/metadata-builders': 0.15.1
|
||||
'@polkadot-api/signers-common': 0.3.1(patch_hash=365a34617de2ae3ad2f7e009f7f3e20e0078448fbfc93c395d323f0e21b75d37)(rxjs@7.8.2)
|
||||
'@polkadot-api/substrate-bindings': 0.21.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
transitivePeerDependencies:
|
||||
- rxjs
|
||||
@@ -5445,7 +5448,7 @@ snapshots:
|
||||
'@polkadot-api/json-rpc-provider': 0.2.0
|
||||
'@polkadot-api/json-rpc-provider-proxy': 0.4.1
|
||||
'@polkadot-api/raw-client': 0.3.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
rxjs: 7.8.2
|
||||
|
||||
@@ -5454,7 +5457,7 @@ snapshots:
|
||||
'@polkadot-api/json-rpc-provider': 0.2.0
|
||||
'@polkadot-api/json-rpc-provider-proxy': 0.4.1
|
||||
'@polkadot-api/raw-client': 0.3.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
rxjs: 7.8.2
|
||||
|
||||
@@ -5718,7 +5721,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@polkadot-api/meta-signers': 0.3.0
|
||||
'@polkadot-api/metadata-builders': 0.15.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkahub/context': 0.9.1(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
'@polkahub/plugin': 0.9.1(@react-rxjs/core@0.10.8(react@19.2.8)(rxjs@7.8.2))(esbuild@0.28.1)(react@19.2.8)
|
||||
'@polkahub/proxy': 0.9.1(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
@@ -5739,7 +5742,7 @@ snapshots:
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
'@polkahub/pjs-wallet@0.9.1(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
|
||||
'@polkahub/pjs-wallet@0.9.1(patch_hash=f359348c980dcf8a9f7077a067ffbc79e23c166172a4fa1be36de5340072104d)(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
|
||||
dependencies:
|
||||
'@polkadot-api/pjs-signer': 0.8.0(rxjs@7.8.2)
|
||||
'@polkahub/context': 0.9.1(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
@@ -5800,7 +5803,7 @@ snapshots:
|
||||
|
||||
'@polkahub/read-only@0.9.1(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
|
||||
dependencies:
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkahub/context': 0.9.1(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
'@polkahub/plugin': 0.9.1(@react-rxjs/core@0.10.8(react@19.2.8)(rxjs@7.8.2))(esbuild@0.28.1)(react@19.2.8)
|
||||
'@polkahub/select-account': 0.9.1(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
@@ -5823,7 +5826,7 @@ snapshots:
|
||||
'@polkahub/select-account@0.9.1(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
|
||||
dependencies:
|
||||
'@polkadot-api/react-components': 0.4.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkahub/context': 0.9.1(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
'@polkahub/plugin': 0.9.1(@react-rxjs/core@0.10.8(react@19.2.8)(rxjs@7.8.2))(esbuild@0.28.1)(react@19.2.8)
|
||||
'@polkahub/ui-components': 0.9.1(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
@@ -5860,7 +5863,7 @@ snapshots:
|
||||
'@polkahub/ui-components@0.9.1(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
|
||||
dependencies:
|
||||
'@polkadot-api/react-components': 0.4.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
'@radix-ui/primitive': 1.1.7
|
||||
'@radix-ui/react-checkbox': 1.3.11(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
@@ -5894,7 +5897,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@polkadot-api/merkleize-metadata': 1.3.1
|
||||
'@polkadot-api/signers-common': 0.3.0(patch_hash=365a34617de2ae3ad2f7e009f7f3e20e0078448fbfc93c395d323f0e21b75d37)(rxjs@7.8.2)
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkahub/context': 0.9.1(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
'@polkahub/plugin': 0.9.1(@react-rxjs/core@0.10.8(react@19.2.8)(rxjs@7.8.2))(esbuild@0.28.1)(react@19.2.8)
|
||||
'@polkahub/select-account': 0.9.1(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
@@ -5916,7 +5919,7 @@ snapshots:
|
||||
|
||||
'@polkahub/wallet-connect@0.9.1(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(debug@4.4.3)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(typescript@7.0.2)(use-sync-external-store@1.6.0(react@19.2.8))(zod@3.25.76)':
|
||||
dependencies:
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkahub/context': 0.9.1(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
'@polkahub/plugin': 0.9.1(@react-rxjs/core@0.10.8(react@19.2.8)(rxjs@7.8.2))(esbuild@0.28.1)(react@19.2.8)
|
||||
'@polkahub/select-account': 0.9.1(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
@@ -9238,7 +9241,7 @@ snapshots:
|
||||
'@polkadot-api/signers-common': 0.3.0(patch_hash=365a34617de2ae3ad2f7e009f7f3e20e0078448fbfc93c395d323f0e21b75d37)(rxjs@7.8.2)
|
||||
'@polkadot-api/sm-provider': 0.3.8(@polkadot-api/smoldot@0.4.7)
|
||||
'@polkadot-api/smoldot': 0.4.7
|
||||
'@polkadot-api/substrate-bindings': 0.21.0
|
||||
'@polkadot-api/substrate-bindings': 0.21.0(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/substrate-client': 0.7.0
|
||||
'@polkadot-api/tx-creator': 0.2.0(rxjs@7.8.2)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
@@ -9267,7 +9270,7 @@ snapshots:
|
||||
'@polkadot-api/signers-common': 0.3.1(patch_hash=365a34617de2ae3ad2f7e009f7f3e20e0078448fbfc93c395d323f0e21b75d37)(rxjs@7.8.2)
|
||||
'@polkadot-api/sm-provider': 0.3.8(@polkadot-api/smoldot@0.4.7)
|
||||
'@polkadot-api/smoldot': 0.4.7
|
||||
'@polkadot-api/substrate-bindings': 0.21.1
|
||||
'@polkadot-api/substrate-bindings': 0.21.1(patch_hash=44a839dff72a3f1f9334c05ea6c72f29757e5d7168e8fee564f12de216710537)
|
||||
'@polkadot-api/substrate-client': 0.7.0
|
||||
'@polkadot-api/tx-creator': 0.2.0(rxjs@7.8.2)
|
||||
'@polkadot-api/utils': 0.4.0
|
||||
@@ -9286,7 +9289,7 @@ snapshots:
|
||||
'@polkahub/context': 0.9.1(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
'@polkahub/ledger': 0.9.1(@ledgerhq/hw-transport@6.35.5)(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
'@polkahub/multisig': 0.9.1(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
'@polkahub/pjs-wallet': 0.9.1(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
'@polkahub/pjs-wallet': 0.9.1(patch_hash=f359348c980dcf8a9f7077a067ffbc79e23c166172a4fa1be36de5340072104d)(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
'@polkahub/plugin': 0.9.1(@react-rxjs/core@0.10.8(react@19.2.8)(rxjs@7.8.2))(esbuild@0.28.1)(react@19.2.8)
|
||||
'@polkahub/proxy': 0.9.1(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
'@polkahub/read-only': 0.9.1(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(esbuild@0.28.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
|
||||
@@ -10,4 +10,13 @@ minimumReleaseAgeExclude:
|
||||
- '@paraspell/sdk@14.3.0 || 14.3.4'
|
||||
patchedDependencies:
|
||||
'@polkadot-api/signers-common': patches/@polkadot-api__signers-common.patch
|
||||
# Pinned per version, unlike the signers-common patch which is keyed on the
|
||||
# bare name. Four copies of substrate-bindings resolve in this tree and their
|
||||
# blockHeader.js is NOT identical across majors — 0.19.0 and 0.6.0 differ, and
|
||||
# a bare-name key fails the whole install trying to patch them. 0.21.1 is what
|
||||
# the console and observable-client actually import; 0.21.0 is byte-identical
|
||||
# and patched too so a minor bump does not silently drop the fix.
|
||||
'@polkadot-api/substrate-bindings@0.21.0': patches/@polkadot-api__substrate-bindings@0.21.0.patch
|
||||
'@polkadot-api/substrate-bindings@0.21.1': patches/@polkadot-api__substrate-bindings@0.21.1.patch
|
||||
'@polkahub/pjs-wallet@0.9.1': patches/@polkahub__pjs-wallet@0.9.1.patch
|
||||
react18-json-view: patches/react18-json-view.patch
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { VaultTxModal } from "polkahub"
|
||||
import { lazy } from "react"
|
||||
import { Navigate, Route, Routes } from "react-router-dom"
|
||||
import { ConnectionState } from "./components/ConnectionState"
|
||||
@@ -35,7 +34,6 @@ export default function App() {
|
||||
<Route path="*" element={<Navigate to="/explorer" replace />} />
|
||||
</Routes>
|
||||
</AppShell>
|
||||
<VaultTxModal />
|
||||
<ConnectionState />
|
||||
</div>
|
||||
)
|
||||
|
||||
81
src/components/BootSplash.tsx
Normal file
81
src/components/BootSplash.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
import { FC, useEffect, useState } from "react"
|
||||
|
||||
/**
|
||||
* What the page shows while the chain is being reached.
|
||||
*
|
||||
* `main.tsx` wraps the entire app in `<Subscribe source$={dynamicBuilder$ …}>`,
|
||||
* and `Subscribe`'s fallback defaults to `null` — "it will render null until the
|
||||
* subscription exists". `dynamicBuilder$` does not emit until a chain has been
|
||||
* followed and its metadata decoded, so until then the document body is empty
|
||||
* and a visitor sees a bare black page with nothing but the tab spinner to
|
||||
* suggest it is not simply broken.
|
||||
*
|
||||
* That is indistinguishable from a crash, and on a chain the console cannot read
|
||||
* it never resolves at all. So: say what is happening, and say it louder the
|
||||
* longer it takes.
|
||||
*/
|
||||
|
||||
const SLOW_MS = 8_000
|
||||
const STUCK_MS = 25_000
|
||||
|
||||
export const BootSplash: FC<{ endpoint?: string; network?: string }> = ({
|
||||
endpoint,
|
||||
network,
|
||||
}) => {
|
||||
const [elapsed, setElapsed] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
const started = Date.now()
|
||||
const id = setInterval(() => setElapsed(Date.now() - started), 500)
|
||||
|
||||
return () => clearInterval(id)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="flex h-screen w-full flex-col items-center justify-center gap-4 bg-background px-6 text-center">
|
||||
<div className="text-base">
|
||||
<span className="poppins-regular">qapi</span>{" "}
|
||||
<span className="poppins-extralight">console</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="h-6 w-6 animate-spin rounded-full border-2 border-muted-foreground border-t-transparent"
|
||||
role="status"
|
||||
aria-label="connecting"
|
||||
/>
|
||||
|
||||
<div className="text-sm text-muted-foreground">
|
||||
Connecting to {network ?? "the chain"}
|
||||
{endpoint ? (
|
||||
<>
|
||||
{" "}
|
||||
at <code className="break-all">{endpoint}</code>
|
||||
</>
|
||||
) : null}
|
||||
…
|
||||
</div>
|
||||
|
||||
{elapsed > SLOW_MS && elapsed <= STUCK_MS ? (
|
||||
<div className="max-w-md text-sm text-muted-foreground">
|
||||
Still going. The console downloads the chain's metadata and decodes it
|
||||
before it can render anything, which takes a moment on a first visit.
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{elapsed > STUCK_MS ? (
|
||||
<div className="max-w-md space-y-2 text-sm">
|
||||
<p className="text-destructive">
|
||||
This is taking much longer than it should.
|
||||
</p>
|
||||
<p className="text-muted-foreground">
|
||||
Either the node is unreachable, or the console cannot read this
|
||||
chain. Check the browser console for the reason, and try another
|
||||
network — the switcher is in the header once any chain loads, and{" "}
|
||||
<code>#networkId=polkadot&endpoint=wss://rpc.polkadot.io</code>{" "}
|
||||
in the URL will force one.
|
||||
</p>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
22
src/main.tsx
22
src/main.tsx
@@ -1,6 +1,6 @@
|
||||
import { dynamicBuilder$ } from "@/state/chains/chain.state"
|
||||
import { dynamicBuilder$, getDefaultChain } from "@/state/chains/chain.state"
|
||||
import { RemoveSubscribe, Subscribe } from "@react-rxjs/core"
|
||||
import { MultisigExternalSignerModal, PolkaHubProvider } from "polkahub"
|
||||
import { PolkaHubProvider } from "polkahub"
|
||||
import { StrictMode } from "react"
|
||||
import { createRoot } from "react-dom/client"
|
||||
import { BrowserRouter } from "react-router-dom"
|
||||
@@ -8,6 +8,7 @@ import { merge } from "rxjs"
|
||||
import App from "./App.tsx"
|
||||
import { TooltipProvider } from "./components/ui/tooltip.tsx"
|
||||
import "./index.css"
|
||||
import { BootSplash } from "./components/BootSplash.tsx"
|
||||
import { codeSplit$ } from "./lib/externalState.ts"
|
||||
import { explorer$ } from "./pages/Explorer"
|
||||
import { polkaHub } from "./state/polkahub.ts"
|
||||
@@ -17,8 +18,22 @@ const metrics$ = codeSplit$(() =>
|
||||
import("./pages/Metrics/metrics.state.ts").then((r) => r.blockStats$),
|
||||
)
|
||||
|
||||
// Without a fallback, `Subscribe` renders null until `dynamicBuilder$` emits —
|
||||
// which is after a chain has been followed and its metadata decoded. On a slow
|
||||
// connection that is seconds of empty black page; on a chain the console cannot
|
||||
// read, it is forever, and indistinguishable from a crash.
|
||||
const initial = getDefaultChain()
|
||||
|
||||
createRoot(document.getElementById("root")!).render(
|
||||
<Subscribe source$={merge(dynamicBuilder$, explorer$, metrics$)}>
|
||||
<Subscribe
|
||||
fallback={
|
||||
<BootSplash
|
||||
endpoint={initial.endpoint}
|
||||
network={initial.network.display}
|
||||
/>
|
||||
}
|
||||
source$={merge(dynamicBuilder$, explorer$, metrics$)}
|
||||
>
|
||||
<RemoveSubscribe>
|
||||
<StrictMode>
|
||||
<ThemeProvider>
|
||||
@@ -28,7 +43,6 @@ createRoot(document.getElementById("root")!).render(
|
||||
<App />
|
||||
</TooltipProvider>
|
||||
</BrowserRouter>
|
||||
<MultisigExternalSignerModal />
|
||||
</PolkaHubProvider>
|
||||
</ThemeProvider>
|
||||
</StrictMode>
|
||||
|
||||
@@ -16,12 +16,9 @@ import { CompatibilityLevel, SS58String } from "polkadot-api"
|
||||
import { toHex } from "polkadot-api/utils"
|
||||
import {
|
||||
Account,
|
||||
ledgerProviderId,
|
||||
PjsWalletAccount,
|
||||
polkadotVaultProviderId,
|
||||
readOnlyProviderId,
|
||||
useAvailableAccounts,
|
||||
walletConnectProviderId,
|
||||
} from "polkahub"
|
||||
import { FC } from "react"
|
||||
import {
|
||||
@@ -34,15 +31,11 @@ import {
|
||||
|
||||
const knownGroupsNames: Record<string, string> = {
|
||||
"pjs-wallet": "Browser Extensions",
|
||||
[ledgerProviderId]: "Ledger",
|
||||
[readOnlyProviderId]: "Read Only",
|
||||
[polkadotVaultProviderId]: "Polkadot Vault",
|
||||
[walletConnectProviderId]: "Wallet Connect",
|
||||
}
|
||||
const knownGroupsColors: Record<string, string> = {
|
||||
"pjs-wallet": "var(--color-lime-700)",
|
||||
[readOnlyProviderId]: "var(--color-orange-700)",
|
||||
[walletConnectProviderId]: "var(--color-blue-700)",
|
||||
}
|
||||
|
||||
export const AccountList = () => {
|
||||
@@ -95,10 +88,7 @@ const AccountCard: FC<{
|
||||
)
|
||||
}
|
||||
export const knownExtensions: Record<string, string> = {
|
||||
"polkadot-js": "Polkadot JS",
|
||||
"nova-wallet": "Nova Wallet",
|
||||
talisman: "Talisman",
|
||||
"subwallet-js": "Subwallet",
|
||||
blackbeard: "blackbeard",
|
||||
}
|
||||
const getExtensionName = (id: string) => knownExtensions[id] ?? id
|
||||
const getGroupName = (id: string) => knownGroupsNames[id] ?? id
|
||||
|
||||
@@ -8,15 +8,11 @@ import {
|
||||
} from "@polkahub/ui-components"
|
||||
import { ChevronLeft } from "lucide-react"
|
||||
import {
|
||||
ManageLedger,
|
||||
ManageMultisig,
|
||||
ManageProxy,
|
||||
ManageReadOnly,
|
||||
ManageVault,
|
||||
ModalContext,
|
||||
PjsWalletButtons,
|
||||
usePolkaHubModalState,
|
||||
WalletConnectButton,
|
||||
} from "polkahub"
|
||||
import { FC, PropsWithChildren } from "react"
|
||||
|
||||
@@ -71,15 +67,9 @@ const ManageToDialog: FC<PropsWithChildren> = ({ children }) => {
|
||||
|
||||
export const PolkahubModalBasedManagers = () => (
|
||||
<>
|
||||
<ul className="flex gap-2 flex-wrap items-center justify-center">
|
||||
<ManageLedger />
|
||||
<ManageVault />
|
||||
<WalletConnectButton />
|
||||
</ul>
|
||||
<ul className="flex gap-2 flex-wrap items-center justify-center">
|
||||
<ManageReadOnly />
|
||||
<ManageProxy />
|
||||
<ManageMultisig />
|
||||
</ul>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -195,7 +195,7 @@ const SidebarContent: FC<{ mobile?: boolean; onNavigate?: () => void }> = ({
|
||||
<div className="shrink-0 border-t p-3">
|
||||
<ThemeToggle />
|
||||
<a
|
||||
href="https://git.lair.cafe/quantus/papi-console"
|
||||
href="https://git.lair.cafe/blackbeard/qapi"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="mt-2 flex items-center gap-2 rounded-md px-3 py-2 text-sm text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground"
|
||||
|
||||
@@ -8,10 +8,8 @@ import {
|
||||
import { FC } from "react"
|
||||
|
||||
const groupLabels: Record<string, string> = {
|
||||
ledger: "Ledger",
|
||||
"pjs-wallet": "Browser Extensions",
|
||||
readonly: "Read Only",
|
||||
"polkadot-vault": "Vault",
|
||||
walletconnect: "Wallet Connect",
|
||||
}
|
||||
|
||||
export const SelectAccount: FC<{
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { CopyText } from "@/components/Copy"
|
||||
import {
|
||||
Chopsticks,
|
||||
Forklift,
|
||||
ForkMethodIcon,
|
||||
Spinner,
|
||||
} from "@/components/Icons"
|
||||
@@ -28,7 +26,6 @@ import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
|
||||
import {
|
||||
AUTO_RPC_ENDPOINT,
|
||||
currentWsStatus$,
|
||||
ForkMethod,
|
||||
LIGHT_CLIENT_ENDPOINT,
|
||||
Network,
|
||||
networkCategories,
|
||||
@@ -85,10 +82,21 @@ const NetworkSwitchDialogContent: FC<{
|
||||
const [query, setQuery] = useState("")
|
||||
const [network, setNetwork] = useState(selectedChain.network)
|
||||
const [endpoint, setEndpoint] = useState(selectedChain.endpoint)
|
||||
const [forkMethod, setForkMethod] = useState(selectedChain.forkMethod)
|
||||
const customUrl = normalizeWsUrl(query)
|
||||
const canFork = endpoint !== LIGHT_CLIENT_ENDPOINT
|
||||
const selectedForkMethod = canFork ? forkMethod : "none"
|
||||
// Forking is not offered.
|
||||
//
|
||||
// Chopsticks is built on `@polkadot/types`, which cannot decode a Quantus
|
||||
// block at all: it caps fixed arrays at 2048 bytes where ML-DSA signatures are
|
||||
// 5261 and 7219, reads the extrinsic preamble byte as a version, and knows
|
||||
// nothing of this chain's header layout. Forklift resolves its own unpatched
|
||||
// copy of `@polkadot-api/substrate-bindings`, so it hits the very header bug
|
||||
// this console patches around.
|
||||
//
|
||||
// Neither can fork a chain in this list, so the two buttons offered things
|
||||
// that could only fail, and fail without saying why. `forkMethod` stays in
|
||||
// SelectedChain — the hash params and chain.state still read it — but nothing
|
||||
// in the UI can now set it to anything other than "none".
|
||||
const selectedForkMethod = "none" as const
|
||||
const hasChanged =
|
||||
network.id !== selectedChain.network.id ||
|
||||
endpoint !== selectedChain.endpoint ||
|
||||
@@ -100,9 +108,6 @@ const NetworkSwitchDialogContent: FC<{
|
||||
) => {
|
||||
setNetwork(next)
|
||||
setEndpoint(nextEndpoint)
|
||||
if (nextEndpoint === LIGHT_CLIENT_ENDPOINT) {
|
||||
setForkMethod("none")
|
||||
}
|
||||
}
|
||||
|
||||
const selectCustomUrl = (url: string) => {
|
||||
@@ -112,14 +117,8 @@ const NetworkSwitchDialogContent: FC<{
|
||||
|
||||
const setConnection = (nextEndpoint: string) => {
|
||||
setEndpoint(nextEndpoint)
|
||||
if (nextEndpoint === LIGHT_CLIENT_ENDPOINT) {
|
||||
setForkMethod("none")
|
||||
}
|
||||
}
|
||||
|
||||
const toggleForkMethod = (method: ForkMethod) => {
|
||||
setForkMethod((current) => (current === method ? "none" : method))
|
||||
}
|
||||
|
||||
const confirm = () => {
|
||||
if (network.id === "custom") {
|
||||
@@ -185,32 +184,7 @@ const NetworkSwitchDialogContent: FC<{
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex shrink-0 items-center justify-between gap-3 border-t pt-3">
|
||||
{canFork ? (
|
||||
<div className="flex min-w-0 items-center gap-3">
|
||||
<div className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
|
||||
Fork with
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<ForkMethodOption
|
||||
value="chopsticks"
|
||||
title="Chopsticks"
|
||||
selected={selectedForkMethod === "chopsticks"}
|
||||
icon={<Chopsticks size={18} />}
|
||||
onSelect={toggleForkMethod}
|
||||
/>
|
||||
<ForkMethodOption
|
||||
value="forklift"
|
||||
title="Forklift"
|
||||
selected={selectedForkMethod === "forklift"}
|
||||
icon={<Forklift size={18} />}
|
||||
onSelect={toggleForkMethod}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div />
|
||||
)}
|
||||
<div className="flex shrink-0 items-center justify-end gap-3 border-t pt-3">
|
||||
<Button
|
||||
className="min-w-28"
|
||||
onClick={confirm}
|
||||
@@ -227,26 +201,6 @@ const NetworkSwitchDialogContent: FC<{
|
||||
)
|
||||
}
|
||||
|
||||
const ForkMethodOption: FC<{
|
||||
value: Exclude<ForkMethod, "none">
|
||||
title: string
|
||||
selected: boolean
|
||||
icon?: React.ReactNode
|
||||
onSelect: (value: ForkMethod) => void
|
||||
}> = ({ value, title, selected, icon, onSelect }) => (
|
||||
<button
|
||||
type="button"
|
||||
className={twMerge(
|
||||
"flex items-center gap-1.5 rounded-md border border-transparent px-2 py-1.5 text-sm",
|
||||
selected && "border-polkadot bg-polkadot/5",
|
||||
)}
|
||||
aria-pressed={selected}
|
||||
onClick={() => onSelect(value)}
|
||||
>
|
||||
{icon}
|
||||
{title}
|
||||
</button>
|
||||
)
|
||||
|
||||
const NetworkList: FC<{
|
||||
query: string
|
||||
|
||||
@@ -145,10 +145,17 @@ export const isValidUri = (input: string): boolean => {
|
||||
|
||||
const defaultSelectedChain: SelectedChain = {
|
||||
network: defaultNetwork,
|
||||
endpoint: LIGHT_CLIENT_ENDPOINT,
|
||||
// AUTO_RPC, not LIGHT_CLIENT. A light client needs a chain spec, and the
|
||||
// Quantus networks have none (`hasChainSpecs: false`), so defaulting to
|
||||
// smoldot asks it to follow a chain it has never heard of — which fails
|
||||
// before a single byte is fetched, and with `Subscribe`'s null fallback it
|
||||
// failed as a bare black page.
|
||||
endpoint: defaultNetwork.lightclient
|
||||
? LIGHT_CLIENT_ENDPOINT
|
||||
: AUTO_RPC_ENDPOINT,
|
||||
forkMethod: "none",
|
||||
}
|
||||
const getDefaultChain = (): SelectedChain => {
|
||||
export const getDefaultChain = (): SelectedChain => {
|
||||
const hashParams = getHashParams()
|
||||
if (hashParams.has("networkId") && hashParams.has("endpoint")) {
|
||||
const networkId = hashParams.get("networkId")!
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
import ksmRawNetworks from "./kusama.json"
|
||||
import paseoRawNetworks from "./paseo.json"
|
||||
import polkadotRawNetworks from "./polkadot.json"
|
||||
import quantusRawNetworks from "./quantus.json"
|
||||
import westendRawNetworks from "./westend.json"
|
||||
|
||||
export type Network = {
|
||||
id: string
|
||||
@@ -17,38 +13,45 @@ export type NetworkCategory = {
|
||||
networks: Network[]
|
||||
}
|
||||
|
||||
const [Polkadot, Kusama, Paseo, Westend, Quantus] = (
|
||||
[
|
||||
polkadotRawNetworks,
|
||||
ksmRawNetworks,
|
||||
paseoRawNetworks,
|
||||
westendRawNetworks,
|
||||
quantusRawNetworks,
|
||||
] as const
|
||||
).map((n): Network[] =>
|
||||
n.map((x) => ({
|
||||
endpoints: x.rpcs as any,
|
||||
lightclient: !!x.hasChainSpecs,
|
||||
id: x.id,
|
||||
display: x.display,
|
||||
// Quantus is a solo chain and its entries carry no `relayChainInfo`, so the
|
||||
// union of the imported JSON literals no longer has the property on every
|
||||
// arm. Narrowed rather than cast: a typo in one of the relay-chain files
|
||||
// should still be a type error.
|
||||
relayChain: "relayChainInfo" in x ? x.relayChainInfo?.id : undefined,
|
||||
})),
|
||||
)
|
||||
// Quantus only.
|
||||
//
|
||||
// Upstream ships Polkadot, Kusama, Paseo, Westend and their parachains. Every
|
||||
// one of them signs with sr25519, ed25519 or ecdsa — discrete-log schemes that
|
||||
// Shor's algorithm breaks together — so none has a quantum-safe account type to
|
||||
// offer, and this console cannot sign for them anyway: polkadot-api rejected
|
||||
// Quantus's DilithiumSignatureScheme until the patch in patches/, and that patch
|
||||
// widened a check rather than adding support for anything else.
|
||||
//
|
||||
// Offering them would make the console look like a general-purpose Substrate
|
||||
// tool that happens to include Quantus. It is the other way round.
|
||||
//
|
||||
// The patched header codec still carries both the Substrate and the Quantus
|
||||
// layouts, and still has a test for each: Localhost and Custom below can point
|
||||
// at anything, so the disambiguation has to keep working even with no Substrate
|
||||
// chain in this list.
|
||||
// Typed once here rather than per-field. TypeScript infers a union of object
|
||||
// literals from the JSON, and because the endpoint keys differ per chain
|
||||
// (rpc1/rpc2 vs a1/a2) every key is `?: undefined` on the arms that lack it —
|
||||
// which is not assignable to Record<string, string>. The double assertion is
|
||||
// the narrowest way through and is what upstream did too (`x.rpcs as any`);
|
||||
// the shape is checked by the build the moment quantus.json drifts from it.
|
||||
type RawNetwork = {
|
||||
id: string
|
||||
display: string
|
||||
rpcs: Record<string, string>
|
||||
hasChainSpecs: boolean
|
||||
}
|
||||
|
||||
const Quantus: Network[] = (quantusRawNetworks as unknown as RawNetwork[]).map((x) => ({
|
||||
endpoints: x.rpcs,
|
||||
lightclient: !!x.hasChainSpecs,
|
||||
id: x.id,
|
||||
display: x.display,
|
||||
relayChain: undefined,
|
||||
}))
|
||||
|
||||
// Quantus first, and the default below. This console exists to exercise a
|
||||
// post-quantum chain; the Substrate networks stay because a signature that works
|
||||
// on both is the only evidence that the patch in patches/ widened a check rather
|
||||
// than broke one.
|
||||
const networks = {
|
||||
Quantus,
|
||||
Polkadot,
|
||||
Kusama,
|
||||
Paseo,
|
||||
Westend,
|
||||
Localhost: [
|
||||
{
|
||||
id: "localhost",
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
"id": "quantus",
|
||||
"display": "Quantus",
|
||||
"rpcs": {
|
||||
"Quantus": "wss://rpc1-mainnet.quantus.com"
|
||||
},
|
||||
"nativeToken": {
|
||||
"symbol": "QTC",
|
||||
"decimals": 12
|
||||
"rpc1": "wss://rpc1-mainnet.quantus.com",
|
||||
"rpc2": "wss://rpc2-mainnet.quantus.com"
|
||||
},
|
||||
"nativeToken": { "symbol": "QTC", "decimals": 12 },
|
||||
"hasChainSpecs": false
|
||||
},
|
||||
{
|
||||
@@ -18,10 +16,7 @@
|
||||
"a1": "wss://a1-heisenberg.quantus.cat",
|
||||
"a2": "wss://a2-heisenberg.quantus.cat"
|
||||
},
|
||||
"nativeToken": {
|
||||
"symbol": "HEI",
|
||||
"decimals": 12
|
||||
},
|
||||
"nativeToken": { "symbol": "HEI", "decimals": 12 },
|
||||
"hasChainSpecs": false
|
||||
},
|
||||
{
|
||||
@@ -31,10 +26,7 @@
|
||||
"a1": "wss://a1-planck.quantus.cat",
|
||||
"a2": "wss://a2-planck.quantus.cat"
|
||||
},
|
||||
"nativeToken": {
|
||||
"symbol": "PLK",
|
||||
"decimals": 12
|
||||
},
|
||||
"nativeToken": { "symbol": "PLK", "decimals": 12 },
|
||||
"hasChainSpecs": false
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
import { polkadot_people } from "@polkadot-api/descriptors"
|
||||
import { liftSuspense, state, SUSPENSE, withDefault } from "@react-rxjs/core"
|
||||
import { AccountId, Binary, HexString, SS58String } from "polkadot-api"
|
||||
import { WsEvent } from "polkadot-api/ws"
|
||||
import {
|
||||
Account,
|
||||
createLedgerProvider,
|
||||
createMultisigProvider,
|
||||
createPjsWalletProvider,
|
||||
createPolkadotVaultProvider,
|
||||
createPolkaHub,
|
||||
createProxyProvider,
|
||||
createReadOnlyProvider,
|
||||
createSelectedAccountPlugin,
|
||||
createWalletConnectProvider,
|
||||
knownChains,
|
||||
multisigExternalSigner,
|
||||
Plugin,
|
||||
} from "polkahub"
|
||||
import {
|
||||
@@ -23,20 +16,15 @@ import {
|
||||
firstValueFrom,
|
||||
map,
|
||||
pipe,
|
||||
startWith,
|
||||
switchMap,
|
||||
} from "rxjs"
|
||||
import { chainProperties$ } from "./chain-props.state"
|
||||
import {
|
||||
canSetStorage$,
|
||||
client$,
|
||||
currentWsStatus$,
|
||||
getChainSource,
|
||||
selectedChain$,
|
||||
unsafeApi$,
|
||||
} from "./chains/chain.state"
|
||||
import { identity$, isVerified } from "./identity.state"
|
||||
import { WebsocketSource } from "./chains/websocket"
|
||||
|
||||
const removeSuspense = <T>() =>
|
||||
pipe(
|
||||
@@ -44,23 +32,8 @@ const removeSuspense = <T>() =>
|
||||
filter<T | SUSPENSE, T>((v): v is T => v !== SUSPENSE),
|
||||
)
|
||||
|
||||
const getNetworkInfo = () =>
|
||||
firstValueFrom(
|
||||
chainProperties$.pipe(
|
||||
removeSuspense(),
|
||||
filter((v) => v != null),
|
||||
map(({ tokenDecimals, tokenSymbol }) => ({
|
||||
decimals: tokenDecimals!,
|
||||
tokenSymbol: tokenSymbol!,
|
||||
})),
|
||||
),
|
||||
)
|
||||
|
||||
const selectedAccountPlugin = createSelectedAccountPlugin()
|
||||
const pjsWalletProvider = createPjsWalletProvider()
|
||||
const polkadotVaultProvider = createPolkadotVaultProvider({
|
||||
getNetworkInfo,
|
||||
})
|
||||
const readOnlyProvider$ = canSetStorage$.pipe(
|
||||
liftSuspense(),
|
||||
filter((v) => v !== SUSPENSE),
|
||||
@@ -70,21 +43,6 @@ const readOnlyProvider$ = canSetStorage$.pipe(
|
||||
}),
|
||||
),
|
||||
)
|
||||
const ledgerAccountProvider = createLedgerProvider(async () => {
|
||||
const module = await import("@ledgerhq/hw-transport-webusb")
|
||||
return module.default.create()
|
||||
}, getNetworkInfo)
|
||||
const walletConnectProvider = createWalletConnectProvider(
|
||||
import.meta.env.VITE_REOWN_PROJECT_ID,
|
||||
[
|
||||
knownChains.polkadot,
|
||||
knownChains.polkadotAh,
|
||||
knownChains.kusama,
|
||||
knownChains.kusamaAh,
|
||||
knownChains.paseo,
|
||||
knownChains.paseoAh,
|
||||
],
|
||||
)
|
||||
const proxyProvider = createProxyProvider((address) =>
|
||||
firstValueFrom(
|
||||
unsafeApi$.pipe(
|
||||
@@ -95,61 +53,18 @@ const proxyProvider = createProxyProvider((address) =>
|
||||
),
|
||||
),
|
||||
)
|
||||
const multisigProvider$ = selectedChain$.pipe(
|
||||
switchMap((chain) =>
|
||||
combineLatest([getChainSource(chain), currentWsStatus$]),
|
||||
),
|
||||
map(([source, wsStatus]) => {
|
||||
if (source.type === "websocket" && source.forkMethod !== "none") {
|
||||
return null
|
||||
}
|
||||
|
||||
if (
|
||||
source.type === "chainSpec" &&
|
||||
![
|
||||
"polkadot",
|
||||
"westend",
|
||||
"kusama",
|
||||
"paseo",
|
||||
"polkadot_asset_hub",
|
||||
"westend_asset_hub",
|
||||
"kusama_asset_hub",
|
||||
"paseo_asset_hub",
|
||||
].includes(source.id)
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
const getWsUri = (source: WebsocketSource) => {
|
||||
if (wsStatus?.type === WsEvent.CONNECTED) return wsStatus.uri
|
||||
return typeof source.endpoint === "string"
|
||||
? source.endpoint
|
||||
: source.endpoint[0]
|
||||
}
|
||||
|
||||
const chain =
|
||||
source.type === "chainSpec" ? `sm-${source.id}` : `ws-${getWsUri(source)}`
|
||||
|
||||
return createMultisigProvider(
|
||||
multisigExternalSigner(
|
||||
(info, callData) =>
|
||||
`https://multisig.usepapi.app/?chain=${chain}&calldata=${callData}&signatories=${info.signatories.join("_")}&threshold=${info.threshold}`,
|
||||
),
|
||||
)
|
||||
}),
|
||||
startWith(null),
|
||||
)
|
||||
|
||||
// Signers that cannot sign for Quantus are not offered. Polkadot Vault, Ledger
|
||||
// and WalletConnect produce sr25519/ed25519/ecdsa signatures, and the external
|
||||
// multisig signer hands signing to multisig.usepapi.app; the runtime accepts
|
||||
// only ML-DSA. What remains: browser extensions (blackbeard, the only one that
|
||||
// signs ML-DSA), read-only accounts, and proxies, which sign through whichever
|
||||
// of those they wrap.
|
||||
export const polkaHub = createPolkaHub(
|
||||
combineLatest([
|
||||
[selectedAccountPlugin],
|
||||
[pjsWalletProvider],
|
||||
[polkadotVaultProvider],
|
||||
readOnlyProvider$,
|
||||
[ledgerAccountProvider],
|
||||
[walletConnectProvider],
|
||||
[proxyProvider],
|
||||
multisigProvider$,
|
||||
]).pipe(map((v: (Plugin<any> | null)[]) => v.filter((v) => v != null))),
|
||||
{
|
||||
getIdentity: (address) =>
|
||||
|
||||
Reference in New Issue
Block a user