bulletin-deploy 0.7.21 → 0.7.22-rc.1
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/dist/bug-report.js +4 -4
- package/dist/chunk-74ETPOKH.js +284 -0
- package/dist/chunk-A5IQ5MKO.js +207 -0
- package/dist/{chunk-VTTN4BX7.js → chunk-CIXT75OF.js} +151 -2
- package/dist/chunk-EJ5TNGAY.js +24 -0
- package/dist/{chunk-RJAFD4LO.js → chunk-FSSKFXTZ.js} +1 -1
- package/dist/{chunk-ZY6QLNKQ.js → chunk-KFHGT4A2.js} +1 -1
- package/dist/{chunk-MJTQOXBC.js → chunk-LEYQOOWC.js} +3 -2
- package/dist/chunk-QHOZEY5X.js +231 -0
- package/dist/{chunk-BFXHVC23.js → chunk-SPWQNU3F.js} +21 -17
- package/dist/chunk-T7EEVWNU.js +32 -0
- package/dist/chunk-UPWEOGLQ.js +37 -0
- package/dist/{chunk-SA37SLYF.js → chunk-V5NUBOEX.js} +2 -2
- package/dist/{chunk-2VNGK2MU.js → chunk-WNUWAA6F.js} +26 -3
- package/dist/{chunk-4TS6R26J.js → chunk-WVCIU6WM.js} +22 -9
- package/dist/{chunk-G2P5UIPX.js → chunk-XWA3NPMX.js} +4 -3
- package/dist/chunk-ZYVGHDMU.js +117 -0
- package/dist/chunk-probe.js +3 -3
- package/dist/deploy.d.ts +4 -2
- package/dist/deploy.js +9 -9
- package/dist/dotns.d.ts +74 -1
- package/dist/dotns.js +8 -4
- package/dist/incremental-stats.d.ts +3 -1
- package/dist/incremental-stats.js +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +9 -9
- package/dist/memory-report.js +2 -2
- package/dist/merkle.js +9 -9
- package/dist/personhood/bind-paid-alias.d.ts +43 -0
- package/dist/personhood/bind-paid-alias.js +10 -0
- package/dist/personhood/bind-personal-id.d.ts +55 -0
- package/dist/personhood/bind-personal-id.js +12 -0
- package/dist/personhood/bootstrap.d.ts +85 -0
- package/dist/personhood/bootstrap.js +245 -0
- package/dist/personhood/claim-pgas.d.ts +61 -0
- package/dist/personhood/claim-pgas.js +12 -0
- package/dist/personhood/constants.d.ts +23 -0
- package/dist/personhood/constants.js +22 -0
- package/dist/personhood/encoding.d.ts +49 -0
- package/dist/personhood/encoding.js +24 -0
- package/dist/personhood/hashing.d.ts +4 -0
- package/dist/personhood/hashing.js +8 -0
- package/dist/personhood/member-key.d.ts +12 -0
- package/dist/personhood/member-key.js +10 -0
- package/dist/personhood/people-client.d.ts +14 -0
- package/dist/personhood/people-client.js +48 -0
- package/dist/personhood/reprove.d.ts +43 -0
- package/dist/personhood/reprove.js +225 -0
- package/dist/pool.d.ts +7 -2
- package/dist/pool.js +3 -1
- package/dist/run-state.js +1 -1
- package/dist/telemetry.d.ts +7 -1
- package/dist/telemetry.js +8 -2
- package/dist/version-check.js +3 -3
- package/docs/e2e-bootstrap.md +36 -10
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
deploy,
|
|
6
6
|
merkleizeJS,
|
|
7
7
|
merkleizeWithStableOrder
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-SPWQNU3F.js";
|
|
9
9
|
import {
|
|
10
10
|
computeStats,
|
|
11
11
|
renderSummary,
|
|
12
12
|
telemetryAttributes
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-LEYQOOWC.js";
|
|
14
14
|
import {
|
|
15
15
|
finaliseEmbeddedManifest,
|
|
16
16
|
writeEmbeddedManifestPlaceholder
|
|
@@ -27,24 +27,24 @@ import {
|
|
|
27
27
|
isVolatilePath,
|
|
28
28
|
parseManifest
|
|
29
29
|
} from "./chunk-S7EM5VMW.js";
|
|
30
|
-
import "./chunk-
|
|
31
|
-
import "./chunk-
|
|
30
|
+
import "./chunk-V5NUBOEX.js";
|
|
31
|
+
import "./chunk-FSSKFXTZ.js";
|
|
32
32
|
import {
|
|
33
33
|
probeChunks
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-KFHGT4A2.js";
|
|
35
35
|
import "./chunk-C2TS5MER.js";
|
|
36
36
|
import {
|
|
37
37
|
DotNS,
|
|
38
38
|
parseDomainName
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-CIXT75OF.js";
|
|
40
40
|
import {
|
|
41
41
|
bootstrapPool,
|
|
42
42
|
derivePoolAccounts,
|
|
43
43
|
ensureAuthorized,
|
|
44
44
|
fetchPoolAuthorizations,
|
|
45
45
|
selectAccount
|
|
46
|
-
} from "./chunk-
|
|
47
|
-
import "./chunk-
|
|
46
|
+
} from "./chunk-WVCIU6WM.js";
|
|
47
|
+
import "./chunk-WNUWAA6F.js";
|
|
48
48
|
import {
|
|
49
49
|
VERSION,
|
|
50
50
|
loadRunState,
|
|
@@ -54,7 +54,7 @@ import {
|
|
|
54
54
|
shouldSkipStaleWarning,
|
|
55
55
|
stateFilePath,
|
|
56
56
|
writeRunState
|
|
57
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-XWA3NPMX.js";
|
|
58
58
|
import {
|
|
59
59
|
DEFAULT_ENV_ID,
|
|
60
60
|
defaultBundledPath,
|
package/dist/memory-report.js
CHANGED
package/dist/merkle.js
CHANGED
|
@@ -6,19 +6,19 @@ import {
|
|
|
6
6
|
merkleizeKuboBackend,
|
|
7
7
|
merkleizeWithStableOrder,
|
|
8
8
|
rebuildOrderedCarFromBytes
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-SPWQNU3F.js";
|
|
10
|
+
import "./chunk-LEYQOOWC.js";
|
|
11
11
|
import "./chunk-KOSF5FDO.js";
|
|
12
12
|
import "./chunk-5MRZ3V4A.js";
|
|
13
13
|
import "./chunk-S7EM5VMW.js";
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-V5NUBOEX.js";
|
|
15
|
+
import "./chunk-FSSKFXTZ.js";
|
|
16
|
+
import "./chunk-KFHGT4A2.js";
|
|
17
17
|
import "./chunk-C2TS5MER.js";
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
20
|
-
import "./chunk-
|
|
21
|
-
import "./chunk-
|
|
18
|
+
import "./chunk-CIXT75OF.js";
|
|
19
|
+
import "./chunk-WVCIU6WM.js";
|
|
20
|
+
import "./chunk-WNUWAA6F.js";
|
|
21
|
+
import "./chunk-XWA3NPMX.js";
|
|
22
22
|
import "./chunk-F36C363Y.js";
|
|
23
23
|
import "./chunk-ZOC4GITL.js";
|
|
24
24
|
import "./chunk-HOTQDYHD.js";
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { SS58String, PolkadotSigner } from 'polkadot-api';
|
|
2
|
+
|
|
3
|
+
type PaidAliasBindingErrorKind = "NotARecognizedPerson" | "RingRootNotFound" | "PaidAliasFeeUnset" | "InsufficientPgas" | "BadProof" | "DispatchError" | "RpcError" | "ClientError" | "Unknown";
|
|
4
|
+
declare class PaidAliasBindingError extends Error {
|
|
5
|
+
readonly kind: PaidAliasBindingErrorKind;
|
|
6
|
+
readonly dispatchError?: unknown;
|
|
7
|
+
constructor(message: string, options?: ErrorOptions & {
|
|
8
|
+
kind?: PaidAliasBindingErrorKind;
|
|
9
|
+
dispatchError?: unknown;
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
type RingExponent = 9 | 10 | 14;
|
|
13
|
+
interface BuildRingProofInput {
|
|
14
|
+
ringExponent: RingExponent;
|
|
15
|
+
members: Uint8Array;
|
|
16
|
+
context: Uint8Array;
|
|
17
|
+
msg: Uint8Array;
|
|
18
|
+
}
|
|
19
|
+
type BuildRingProof = (input: BuildRingProofInput) => Promise<{
|
|
20
|
+
proof: Uint8Array;
|
|
21
|
+
alias: Uint8Array;
|
|
22
|
+
}>;
|
|
23
|
+
interface PaidAliasBindingProgress {
|
|
24
|
+
onBroadcasted?: () => void;
|
|
25
|
+
onBestBlock?: (blockHash: string) => void;
|
|
26
|
+
}
|
|
27
|
+
interface BindPaidAliasParams {
|
|
28
|
+
peopleUnsafeApi: unknown;
|
|
29
|
+
ahUnsafeApi: unknown;
|
|
30
|
+
account: SS58String;
|
|
31
|
+
memberKey: Uint8Array;
|
|
32
|
+
contextBytes: Uint8Array;
|
|
33
|
+
signCall: PolkadotSigner;
|
|
34
|
+
buildRingProof: BuildRingProof;
|
|
35
|
+
progress?: PaidAliasBindingProgress;
|
|
36
|
+
}
|
|
37
|
+
interface BindPaidAliasResult {
|
|
38
|
+
blockHash: string;
|
|
39
|
+
alias: Uint8Array;
|
|
40
|
+
}
|
|
41
|
+
declare const bindPaidAliasToAccount: ({ peopleUnsafeApi, ahUnsafeApi, account, memberKey, contextBytes, signCall, buildRingProof, progress, }: BindPaidAliasParams) => Promise<BindPaidAliasResult>;
|
|
42
|
+
|
|
43
|
+
export { type BindPaidAliasParams, type BindPaidAliasResult, type BuildRingProof, type BuildRingProofInput, PaidAliasBindingError, type PaidAliasBindingErrorKind, type PaidAliasBindingProgress, type RingExponent, bindPaidAliasToAccount };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { PolkadotClient, SS58String } from 'polkadot-api';
|
|
2
|
+
|
|
3
|
+
type BindingErrorKind = "dispatch_error" | "rpc_error" | "client_error" | "unknown";
|
|
4
|
+
declare class PersonalIdBindingError extends Error {
|
|
5
|
+
readonly dispatchError?: unknown;
|
|
6
|
+
readonly kind: BindingErrorKind;
|
|
7
|
+
constructor(message: string, options?: ErrorOptions & {
|
|
8
|
+
kind?: BindingErrorKind;
|
|
9
|
+
dispatchError?: unknown;
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
type SignMember = (message: Uint8Array) => Uint8Array | Promise<Uint8Array>;
|
|
13
|
+
interface BindPersonalIdToAccountParams {
|
|
14
|
+
/** Untyped papi API for the People chain. */
|
|
15
|
+
typedApi: unknown;
|
|
16
|
+
/** Polkadot client used to submit the unsigned extrinsic. */
|
|
17
|
+
client: PolkadotClient;
|
|
18
|
+
/** Numeric PersonalId of the personhood being bound. */
|
|
19
|
+
personalId: bigint;
|
|
20
|
+
/** SS58 address to bind to the PersonalId. */
|
|
21
|
+
account: SS58String;
|
|
22
|
+
/**
|
|
23
|
+
* Signs `blake2_256(implication)` with the personhood bandersnatch member
|
|
24
|
+
* key. Must return a 96-byte signature.
|
|
25
|
+
*/
|
|
26
|
+
signMember: SignMember;
|
|
27
|
+
/**
|
|
28
|
+
* Override the `call_valid_at` block number. Defaults to the current best
|
|
29
|
+
* block number queried from the chain.
|
|
30
|
+
*/
|
|
31
|
+
callValidAt?: number;
|
|
32
|
+
progress?: BindingProgress;
|
|
33
|
+
}
|
|
34
|
+
interface BindPersonalIdToAccountResult {
|
|
35
|
+
extrinsicHex: `0x${string}`;
|
|
36
|
+
blockHash: string;
|
|
37
|
+
}
|
|
38
|
+
interface BindingProgress {
|
|
39
|
+
onBestBlock?: (blockHash: string) => void;
|
|
40
|
+
onBroadcasted?: () => void;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build the AsPerson extension value for a `set_personal_id_account` General
|
|
44
|
+
* extrinsic. Exported so unit tests can assert that the Bandersnatch signature
|
|
45
|
+
* is encoded as a hex string (papi 2.x `SizedBytes(96)` contract).
|
|
46
|
+
*
|
|
47
|
+
* @test-only — production callers use `bindPersonalIdToAccount` directly.
|
|
48
|
+
*/
|
|
49
|
+
declare function buildAsPersonExtensionValue(signature: Uint8Array, personalId: bigint): {
|
|
50
|
+
type: string;
|
|
51
|
+
value: [string, bigint];
|
|
52
|
+
};
|
|
53
|
+
declare const bindPersonalIdToAccount: ({ typedApi, client, personalId, account, signMember, callValidAt, progress, }: BindPersonalIdToAccountParams) => Promise<BindPersonalIdToAccountResult>;
|
|
54
|
+
|
|
55
|
+
export { type BindPersonalIdToAccountParams, type BindPersonalIdToAccountResult, type BindingErrorKind, type BindingProgress, PersonalIdBindingError, type SignMember, bindPersonalIdToAccount, buildAsPersonExtensionValue };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PersonalIdBindingError,
|
|
3
|
+
bindPersonalIdToAccount,
|
|
4
|
+
buildAsPersonExtensionValue
|
|
5
|
+
} from "../chunk-A5IQ5MKO.js";
|
|
6
|
+
import "../chunk-ZYVGHDMU.js";
|
|
7
|
+
import "../chunk-T7EEVWNU.js";
|
|
8
|
+
export {
|
|
9
|
+
PersonalIdBindingError,
|
|
10
|
+
bindPersonalIdToAccount,
|
|
11
|
+
buildAsPersonExtensionValue
|
|
12
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { SS58String } from 'polkadot-api';
|
|
2
|
+
import { bindPersonalIdToAccount } from './bind-personal-id.js';
|
|
3
|
+
import { claimPgas } from './claim-pgas.js';
|
|
4
|
+
import { bindPaidAliasToAccount } from './bind-paid-alias.js';
|
|
5
|
+
|
|
6
|
+
interface BootstrapState {
|
|
7
|
+
recognized: boolean;
|
|
8
|
+
personalIdBound: boolean;
|
|
9
|
+
pgasBalance: bigint;
|
|
10
|
+
paidAliasFee: bigint;
|
|
11
|
+
aliasBound: {
|
|
12
|
+
paid: boolean;
|
|
13
|
+
contextHex: string;
|
|
14
|
+
revision: number;
|
|
15
|
+
} | null;
|
|
16
|
+
reviveMapped: boolean;
|
|
17
|
+
}
|
|
18
|
+
interface BootstrapResult {
|
|
19
|
+
initialState: BootstrapState;
|
|
20
|
+
actionsExecuted: Array<"bind-personal-id" | "claim-pgas" | "bind-paid-alias" | "map-account">;
|
|
21
|
+
finalState: BootstrapState;
|
|
22
|
+
}
|
|
23
|
+
declare class RecognizeRequiredError extends Error {
|
|
24
|
+
constructor();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Probe the current bootstrap state from chain for a given account.
|
|
28
|
+
* All reads are at "best" block — suitable for sequential flow decisions.
|
|
29
|
+
*/
|
|
30
|
+
declare function probeBootstrapState({ peopleUnsafeApi, ahUnsafeApi, memberKey, account, }: {
|
|
31
|
+
peopleUnsafeApi: unknown;
|
|
32
|
+
ahUnsafeApi: unknown;
|
|
33
|
+
memberKey: Uint8Array;
|
|
34
|
+
account: SS58String;
|
|
35
|
+
}): Promise<BootstrapState>;
|
|
36
|
+
/**
|
|
37
|
+
* Determine the next action needed given the current bootstrap state.
|
|
38
|
+
* Returns null when the flow is complete.
|
|
39
|
+
*/
|
|
40
|
+
declare function nextBootstrapAction(state: BootstrapState): "bind-personal-id" | "claim-pgas" | "bind-paid-alias" | null;
|
|
41
|
+
/**
|
|
42
|
+
* Test-only injection seam for `runBootstrap`. When provided, the real WS
|
|
43
|
+
* connections and environment lookup are bypassed entirely.
|
|
44
|
+
*
|
|
45
|
+
* @internal — not part of the public API.
|
|
46
|
+
*/
|
|
47
|
+
interface RunBootstrapTestApis {
|
|
48
|
+
/** Pre-built AH unsafe API (replaces `ahClient.getUnsafeApi()`). */
|
|
49
|
+
ahUnsafeApi: unknown;
|
|
50
|
+
/** Pre-built People unsafe API (replaces `peopleClient.getUnsafeApi()`). */
|
|
51
|
+
peopleUnsafeApi: unknown;
|
|
52
|
+
/**
|
|
53
|
+
* Mock AH client. Only `destroy` and `submitAndWatch` are used by bootstrap;
|
|
54
|
+
* a no-op `destroy` is sufficient when the test step doesn't submit.
|
|
55
|
+
*/
|
|
56
|
+
ahClient: {
|
|
57
|
+
destroy: () => void;
|
|
58
|
+
submitAndWatch?: unknown;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Mock People client. Only `destroy` and `submitAndWatch` are used.
|
|
62
|
+
*/
|
|
63
|
+
peopleClient: {
|
|
64
|
+
destroy: () => void;
|
|
65
|
+
submitAndWatch?: unknown;
|
|
66
|
+
};
|
|
67
|
+
/** Override `bindPersonalIdToAccount` (defaults to the real import). */
|
|
68
|
+
bindPersonalIdToAccount?: typeof bindPersonalIdToAccount;
|
|
69
|
+
/** Override `claimPgas` (defaults to the real import). */
|
|
70
|
+
claimPgas?: typeof claimPgas;
|
|
71
|
+
/** Override `bindPaidAliasToAccount` (defaults to the real import). */
|
|
72
|
+
bindPaidAliasToAccount?: typeof bindPaidAliasToAccount;
|
|
73
|
+
}
|
|
74
|
+
declare function runBootstrap({ mnemonic, environmentId, requireRecognized, _testApis, }: {
|
|
75
|
+
mnemonic: string;
|
|
76
|
+
environmentId: string;
|
|
77
|
+
requireRecognized?: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Test-only: inject pre-built API objects and function overrides.
|
|
80
|
+
* When set the real WS connections and environment lookup are skipped.
|
|
81
|
+
*/
|
|
82
|
+
_testApis?: RunBootstrapTestApis;
|
|
83
|
+
}): Promise<BootstrapResult>;
|
|
84
|
+
|
|
85
|
+
export { type BootstrapResult, type BootstrapState, RecognizeRequiredError, type RunBootstrapTestApis, nextBootstrapAction, probeBootstrapState, runBootstrap };
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import {
|
|
2
|
+
claimPgas
|
|
3
|
+
} from "../chunk-74ETPOKH.js";
|
|
4
|
+
import {
|
|
5
|
+
deriveMemberEntropy,
|
|
6
|
+
deriveMemberKey
|
|
7
|
+
} from "../chunk-EJ5TNGAY.js";
|
|
8
|
+
import "../chunk-UPWEOGLQ.js";
|
|
9
|
+
import {
|
|
10
|
+
bindPaidAliasToAccount
|
|
11
|
+
} from "../chunk-QHOZEY5X.js";
|
|
12
|
+
import {
|
|
13
|
+
bindPersonalIdToAccount
|
|
14
|
+
} from "../chunk-A5IQ5MKO.js";
|
|
15
|
+
import {
|
|
16
|
+
bytesToHex
|
|
17
|
+
} from "../chunk-ZYVGHDMU.js";
|
|
18
|
+
import {
|
|
19
|
+
DOTNS_CONTEXT_BYTES,
|
|
20
|
+
PGAS_ASSET_ID
|
|
21
|
+
} from "../chunk-T7EEVWNU.js";
|
|
22
|
+
import {
|
|
23
|
+
WS_HEARTBEAT_TIMEOUT_MS
|
|
24
|
+
} from "../chunk-CIXT75OF.js";
|
|
25
|
+
import "../chunk-WVCIU6WM.js";
|
|
26
|
+
import "../chunk-WNUWAA6F.js";
|
|
27
|
+
import "../chunk-XWA3NPMX.js";
|
|
28
|
+
import {
|
|
29
|
+
loadEnvironments
|
|
30
|
+
} from "../chunk-F36C363Y.js";
|
|
31
|
+
import "../chunk-ZOC4GITL.js";
|
|
32
|
+
|
|
33
|
+
// src/personhood/bootstrap.ts
|
|
34
|
+
import { createClient } from "polkadot-api";
|
|
35
|
+
import { getPolkadotSigner } from "polkadot-api/signer";
|
|
36
|
+
import { getWsProvider } from "polkadot-api/ws";
|
|
37
|
+
import { Keyring } from "@polkadot/keyring";
|
|
38
|
+
import { cryptoWaitReady } from "@polkadot/util-crypto";
|
|
39
|
+
import * as verifiable from "verifiablejs/nodejs";
|
|
40
|
+
var RecognizeRequiredError = class extends Error {
|
|
41
|
+
constructor() {
|
|
42
|
+
super(
|
|
43
|
+
"This account has not been recognised by the personhood faucet. Visit https://sudo.personhood.dev/personhood-faucet to request recognition, then re-run the bootstrap."
|
|
44
|
+
);
|
|
45
|
+
this.name = "RecognizeRequiredError";
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
async function probeBootstrapState({
|
|
49
|
+
peopleUnsafeApi,
|
|
50
|
+
ahUnsafeApi,
|
|
51
|
+
memberKey,
|
|
52
|
+
account
|
|
53
|
+
}) {
|
|
54
|
+
const { PEOPLE_MEMBER_IDENTIFIER_HEX } = await import("./constants.js");
|
|
55
|
+
const people = peopleUnsafeApi;
|
|
56
|
+
const ah = ahUnsafeApi;
|
|
57
|
+
const [memberPosition, pgasAcct, feeRaw, aliasRow] = await Promise.all([
|
|
58
|
+
people.query.Members.Members.getValue(PEOPLE_MEMBER_IDENTIFIER_HEX, bytesToHex(memberKey), { at: "best" }),
|
|
59
|
+
ah.query.Assets.Account.getValue(PGAS_ASSET_ID, account, { at: "best" }),
|
|
60
|
+
ah.query.AliasAccounts.PaidAliasFee.getValue({ at: "best" }),
|
|
61
|
+
ah.query.AliasAccounts.AccountToAlias.getValue(account, { at: "best" })
|
|
62
|
+
]);
|
|
63
|
+
const recognized = memberPosition?.type === "Included";
|
|
64
|
+
let personalIdBound = false;
|
|
65
|
+
const peoplePersonal = people.query.People;
|
|
66
|
+
if (peoplePersonal?.AccountToPersonalId) {
|
|
67
|
+
const personalId = await peoplePersonal.AccountToPersonalId.getValue(account, { at: "best" });
|
|
68
|
+
personalIdBound = personalId !== void 0;
|
|
69
|
+
}
|
|
70
|
+
const pgasBalance = pgasAcct?.balance ?? 0n;
|
|
71
|
+
const paidAliasFee = feeRaw ?? 0n;
|
|
72
|
+
const aliasBound = aliasRow ? {
|
|
73
|
+
paid: aliasRow.paid,
|
|
74
|
+
contextHex: aliasRow.ca.context,
|
|
75
|
+
revision: aliasRow.revision
|
|
76
|
+
} : null;
|
|
77
|
+
const reviveMapped = aliasRow !== void 0 && aliasRow !== null;
|
|
78
|
+
return {
|
|
79
|
+
recognized,
|
|
80
|
+
personalIdBound,
|
|
81
|
+
pgasBalance,
|
|
82
|
+
paidAliasFee,
|
|
83
|
+
aliasBound,
|
|
84
|
+
reviveMapped
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function nextBootstrapAction(state) {
|
|
88
|
+
if (!state.personalIdBound) return "bind-personal-id";
|
|
89
|
+
if (state.pgasBalance < state.paidAliasFee) return "claim-pgas";
|
|
90
|
+
if (!state.aliasBound?.paid) return "bind-paid-alias";
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
async function runBootstrap({
|
|
94
|
+
mnemonic,
|
|
95
|
+
environmentId,
|
|
96
|
+
requireRecognized = true,
|
|
97
|
+
_testApis
|
|
98
|
+
}) {
|
|
99
|
+
await cryptoWaitReady();
|
|
100
|
+
let ahClient;
|
|
101
|
+
let peopleClient;
|
|
102
|
+
let ahUnsafeApiResolved;
|
|
103
|
+
let peopleUnsafeApiResolved;
|
|
104
|
+
if (_testApis) {
|
|
105
|
+
ahClient = _testApis.ahClient;
|
|
106
|
+
peopleClient = _testApis.peopleClient;
|
|
107
|
+
ahUnsafeApiResolved = _testApis.ahUnsafeApi;
|
|
108
|
+
peopleUnsafeApiResolved = _testApis.peopleUnsafeApi;
|
|
109
|
+
} else {
|
|
110
|
+
const { doc } = await loadEnvironments();
|
|
111
|
+
const ahChain = doc.chains.find((c) => c.id === "asset-hub");
|
|
112
|
+
const peopleChain = doc.chains.find((c) => c.id === "people");
|
|
113
|
+
if (!ahChain || !peopleChain) {
|
|
114
|
+
throw new Error("environments.json missing asset-hub or people chain");
|
|
115
|
+
}
|
|
116
|
+
const ahEntry = ahChain.endpoints[environmentId];
|
|
117
|
+
const peopleEntry = peopleChain.endpoints[environmentId];
|
|
118
|
+
if (!ahEntry || !peopleEntry) {
|
|
119
|
+
throw new Error(
|
|
120
|
+
`No endpoints for environment '${environmentId}'. Bootstrap is only available on paseo-next-v2.`
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
const ahWss = Array.isArray(ahEntry.wss) ? ahEntry.wss[0] : ahEntry.wss;
|
|
124
|
+
const peopleWss = Array.isArray(peopleEntry.wss) ? peopleEntry.wss[0] : peopleEntry.wss;
|
|
125
|
+
const realAhClient = createClient(
|
|
126
|
+
getWsProvider(ahWss, { heartbeatTimeout: WS_HEARTBEAT_TIMEOUT_MS })
|
|
127
|
+
);
|
|
128
|
+
const realPeopleClient = createClient(
|
|
129
|
+
getWsProvider(peopleWss, { heartbeatTimeout: WS_HEARTBEAT_TIMEOUT_MS })
|
|
130
|
+
);
|
|
131
|
+
ahClient = realAhClient;
|
|
132
|
+
peopleClient = realPeopleClient;
|
|
133
|
+
ahUnsafeApiResolved = realAhClient.getUnsafeApi();
|
|
134
|
+
peopleUnsafeApiResolved = realPeopleClient.getUnsafeApi();
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
const keyring = new Keyring({ type: "sr25519" });
|
|
138
|
+
const account = keyring.addFromMnemonic(mnemonic);
|
|
139
|
+
const ss58 = account.address;
|
|
140
|
+
const signer = getPolkadotSigner(
|
|
141
|
+
account.publicKey,
|
|
142
|
+
"Sr25519",
|
|
143
|
+
async (input) => account.sign(input)
|
|
144
|
+
);
|
|
145
|
+
const memberKey = deriveMemberKey(mnemonic);
|
|
146
|
+
const memberEntropy = deriveMemberEntropy(mnemonic);
|
|
147
|
+
const ahUnsafeApi = ahUnsafeApiResolved;
|
|
148
|
+
const peopleUnsafeApi = peopleUnsafeApiResolved;
|
|
149
|
+
const initialState = await probeBootstrapState({
|
|
150
|
+
peopleUnsafeApi,
|
|
151
|
+
ahUnsafeApi,
|
|
152
|
+
memberKey,
|
|
153
|
+
account: ss58
|
|
154
|
+
});
|
|
155
|
+
if (requireRecognized && !initialState.recognized) {
|
|
156
|
+
throw new RecognizeRequiredError();
|
|
157
|
+
}
|
|
158
|
+
const actionsExecuted = [];
|
|
159
|
+
let currentState = { ...initialState };
|
|
160
|
+
if (!currentState.personalIdBound) {
|
|
161
|
+
const memberKeyHex = "0x" + Array.from(memberKey, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
162
|
+
const peoplePeopleStore = peopleUnsafeApi.query.People;
|
|
163
|
+
const personalId = await peoplePeopleStore?.Keys?.getValue(memberKeyHex, { at: "best" });
|
|
164
|
+
if (personalId === void 0 || personalId === null) {
|
|
165
|
+
throw new Error(
|
|
166
|
+
`cannot bind personal id: People.Keys[${memberKeyHex}] is not set on this chain. Visit the personhood faucet first.`
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
const _bindPersonalId = _testApis?.bindPersonalIdToAccount ?? bindPersonalIdToAccount;
|
|
170
|
+
await _bindPersonalId({
|
|
171
|
+
typedApi: peopleUnsafeApi,
|
|
172
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
173
|
+
client: peopleClient,
|
|
174
|
+
personalId,
|
|
175
|
+
account: ss58,
|
|
176
|
+
signMember: (msg) => verifiable.sign(memberEntropy, msg)
|
|
177
|
+
});
|
|
178
|
+
actionsExecuted.push("bind-personal-id");
|
|
179
|
+
currentState = await probeBootstrapState({
|
|
180
|
+
peopleUnsafeApi,
|
|
181
|
+
ahUnsafeApi,
|
|
182
|
+
memberKey,
|
|
183
|
+
account: ss58
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
const buildRingProof = async ({ members, context, msg }) => {
|
|
187
|
+
const result = verifiable.one_shot(memberEntropy, members, context, msg);
|
|
188
|
+
return { proof: result.proof, alias: result.alias };
|
|
189
|
+
};
|
|
190
|
+
if (currentState.pgasBalance < currentState.paidAliasFee) {
|
|
191
|
+
const _claimPgas = _testApis?.claimPgas ?? claimPgas;
|
|
192
|
+
await _claimPgas({
|
|
193
|
+
peopleUnsafeApi,
|
|
194
|
+
ahUnsafeApi,
|
|
195
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
196
|
+
ahClient,
|
|
197
|
+
target: ss58,
|
|
198
|
+
memberKey,
|
|
199
|
+
buildRingProof
|
|
200
|
+
});
|
|
201
|
+
actionsExecuted.push("claim-pgas");
|
|
202
|
+
currentState = await probeBootstrapState({
|
|
203
|
+
peopleUnsafeApi,
|
|
204
|
+
ahUnsafeApi,
|
|
205
|
+
memberKey,
|
|
206
|
+
account: ss58
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
if (!currentState.aliasBound?.paid) {
|
|
210
|
+
const _bindPaidAlias = _testApis?.bindPaidAliasToAccount ?? bindPaidAliasToAccount;
|
|
211
|
+
await _bindPaidAlias({
|
|
212
|
+
peopleUnsafeApi,
|
|
213
|
+
ahUnsafeApi,
|
|
214
|
+
account: ss58,
|
|
215
|
+
memberKey,
|
|
216
|
+
contextBytes: DOTNS_CONTEXT_BYTES,
|
|
217
|
+
signCall: signer,
|
|
218
|
+
buildRingProof
|
|
219
|
+
});
|
|
220
|
+
actionsExecuted.push("bind-paid-alias");
|
|
221
|
+
currentState = await probeBootstrapState({
|
|
222
|
+
peopleUnsafeApi,
|
|
223
|
+
ahUnsafeApi,
|
|
224
|
+
memberKey,
|
|
225
|
+
account: ss58
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
return { initialState, actionsExecuted, finalState: currentState };
|
|
229
|
+
} finally {
|
|
230
|
+
try {
|
|
231
|
+
ahClient.destroy();
|
|
232
|
+
} catch {
|
|
233
|
+
}
|
|
234
|
+
try {
|
|
235
|
+
peopleClient.destroy();
|
|
236
|
+
} catch {
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
export {
|
|
241
|
+
RecognizeRequiredError,
|
|
242
|
+
nextBootstrapAction,
|
|
243
|
+
probeBootstrapState,
|
|
244
|
+
runBootstrap
|
|
245
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { PolkadotClient, SS58String } from 'polkadot-api';
|
|
2
|
+
|
|
3
|
+
type PgasClaimErrorKind = "PgasAssetNotCreated" | "AlreadyClaimedToday" | "InvalidClaimSlot" | "InvalidClaimDay" | "BadProof" | "RingRootNotFound" | "NotARecognizedPerson" | "DispatchError" | "RpcError" | "ClientError" | "Unknown";
|
|
4
|
+
declare class PgasClaimError extends Error {
|
|
5
|
+
readonly kind: PgasClaimErrorKind;
|
|
6
|
+
readonly dispatchError?: unknown;
|
|
7
|
+
constructor(message: string, options?: ErrorOptions & {
|
|
8
|
+
kind?: PgasClaimErrorKind;
|
|
9
|
+
dispatchError?: unknown;
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
type RingExponent = 9 | 10 | 14;
|
|
13
|
+
interface BuildRingProofInput {
|
|
14
|
+
ringExponent: RingExponent;
|
|
15
|
+
members: Uint8Array;
|
|
16
|
+
context: Uint8Array;
|
|
17
|
+
msg: Uint8Array;
|
|
18
|
+
}
|
|
19
|
+
type BuildRingProof = (input: BuildRingProofInput) => Promise<{
|
|
20
|
+
proof: Uint8Array;
|
|
21
|
+
alias: Uint8Array;
|
|
22
|
+
}>;
|
|
23
|
+
interface PgasClaimProgress {
|
|
24
|
+
onBroadcasted?: () => void;
|
|
25
|
+
onBestBlock?: (blockHash: string) => void;
|
|
26
|
+
}
|
|
27
|
+
interface ClaimPgasParams {
|
|
28
|
+
peopleUnsafeApi: unknown;
|
|
29
|
+
ahUnsafeApi: unknown;
|
|
30
|
+
ahClient: PolkadotClient;
|
|
31
|
+
target: SS58String;
|
|
32
|
+
memberKey: Uint8Array;
|
|
33
|
+
buildRingProof: BuildRingProof;
|
|
34
|
+
slotIndex?: number;
|
|
35
|
+
progress?: PgasClaimProgress;
|
|
36
|
+
}
|
|
37
|
+
interface ClaimPgasResult {
|
|
38
|
+
blockHash: string;
|
|
39
|
+
amount: bigint;
|
|
40
|
+
alias: Uint8Array;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build the AsPgas::Claim extension value for a `claim_pgas` General extrinsic.
|
|
44
|
+
* Exported so unit tests can assert that the ring-VRF proof is encoded as a hex
|
|
45
|
+
* string (papi 2.x `FixedSizeBinary<788>` / SizedBytes contract).
|
|
46
|
+
*
|
|
47
|
+
* @test-only — production callers use `claimPgas` directly.
|
|
48
|
+
*/
|
|
49
|
+
declare function buildAsPgasClaimExtensionValue(proof: Uint8Array, ringIndex: number, revision: number, day: number): {
|
|
50
|
+
type: string;
|
|
51
|
+
value: {
|
|
52
|
+
proof: string;
|
|
53
|
+
ring_index: number;
|
|
54
|
+
revision: number;
|
|
55
|
+
collection: unknown;
|
|
56
|
+
day: number;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
declare const claimPgas: ({ peopleUnsafeApi, ahUnsafeApi, ahClient, target, memberKey, buildRingProof, slotIndex, progress, }: ClaimPgasParams) => Promise<ClaimPgasResult>;
|
|
60
|
+
|
|
61
|
+
export { type BuildRingProof, type BuildRingProofInput, type ClaimPgasParams, type ClaimPgasResult, PgasClaimError, type PgasClaimErrorKind, type PgasClaimProgress, type RingExponent, buildAsPgasClaimExtensionValue, claimPgas };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
declare const DOTNS_CONTEXT_HEX = "0x646f746e73000000000000000000000000000000000000000000000000000000";
|
|
2
|
+
declare const DOTNS_CONTEXT_BYTES: Uint8Array;
|
|
3
|
+
declare const PGAS_ASSET_ID = 2000000000;
|
|
4
|
+
declare const PGAS_ASSET_LOCATION: {
|
|
5
|
+
parents: 0;
|
|
6
|
+
interior: {
|
|
7
|
+
type: "X2";
|
|
8
|
+
value: readonly [{
|
|
9
|
+
readonly type: "PalletInstance";
|
|
10
|
+
readonly value: 50;
|
|
11
|
+
}, {
|
|
12
|
+
readonly type: "GeneralIndex";
|
|
13
|
+
readonly value: bigint;
|
|
14
|
+
}];
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
declare const PROOF_BYTES = 788;
|
|
18
|
+
declare const BANDERSNATCH_SIGNATURE_BYTES = 96;
|
|
19
|
+
declare const PEOPLE_MEMBER_IDENTIFIER_HEX = "0x70656f706c652020202020202020202020202020202020202020202020202020";
|
|
20
|
+
declare const MEMBER_ENTROPY_KEY: Uint8Array<ArrayBuffer>;
|
|
21
|
+
declare const PAID_PROOF_TAG: Uint8Array<ArrayBuffer>;
|
|
22
|
+
|
|
23
|
+
export { BANDERSNATCH_SIGNATURE_BYTES, DOTNS_CONTEXT_BYTES, DOTNS_CONTEXT_HEX, MEMBER_ENTROPY_KEY, PAID_PROOF_TAG, PEOPLE_MEMBER_IDENTIFIER_HEX, PGAS_ASSET_ID, PGAS_ASSET_LOCATION, PROOF_BYTES };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BANDERSNATCH_SIGNATURE_BYTES,
|
|
3
|
+
DOTNS_CONTEXT_BYTES,
|
|
4
|
+
DOTNS_CONTEXT_HEX,
|
|
5
|
+
MEMBER_ENTROPY_KEY,
|
|
6
|
+
PAID_PROOF_TAG,
|
|
7
|
+
PEOPLE_MEMBER_IDENTIFIER_HEX,
|
|
8
|
+
PGAS_ASSET_ID,
|
|
9
|
+
PGAS_ASSET_LOCATION,
|
|
10
|
+
PROOF_BYTES
|
|
11
|
+
} from "../chunk-T7EEVWNU.js";
|
|
12
|
+
export {
|
|
13
|
+
BANDERSNATCH_SIGNATURE_BYTES,
|
|
14
|
+
DOTNS_CONTEXT_BYTES,
|
|
15
|
+
DOTNS_CONTEXT_HEX,
|
|
16
|
+
MEMBER_ENTROPY_KEY,
|
|
17
|
+
PAID_PROOF_TAG,
|
|
18
|
+
PEOPLE_MEMBER_IDENTIFIER_HEX,
|
|
19
|
+
PGAS_ASSET_ID,
|
|
20
|
+
PGAS_ASSET_LOCATION,
|
|
21
|
+
PROOF_BYTES
|
|
22
|
+
};
|