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/bug-report.js
CHANGED
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
offerBugReport,
|
|
10
10
|
scrubSecrets,
|
|
11
11
|
setDeployContext
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-V5NUBOEX.js";
|
|
13
|
+
import "./chunk-FSSKFXTZ.js";
|
|
14
|
+
import "./chunk-WNUWAA6F.js";
|
|
15
|
+
import "./chunk-XWA3NPMX.js";
|
|
16
16
|
export {
|
|
17
17
|
buildCliFlagsSummary,
|
|
18
18
|
buildLabels,
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildImplicationMessage,
|
|
3
|
+
buildV5GeneralExtrinsic,
|
|
4
|
+
bytesToHex,
|
|
5
|
+
encodeMembers,
|
|
6
|
+
hexToBytes,
|
|
7
|
+
readExtensionOrder,
|
|
8
|
+
toHex
|
|
9
|
+
} from "./chunk-ZYVGHDMU.js";
|
|
10
|
+
import {
|
|
11
|
+
PEOPLE_MEMBER_IDENTIFIER_HEX,
|
|
12
|
+
PGAS_ASSET_ID,
|
|
13
|
+
PROOF_BYTES
|
|
14
|
+
} from "./chunk-T7EEVWNU.js";
|
|
15
|
+
|
|
16
|
+
// src/personhood/claim-pgas.ts
|
|
17
|
+
import { Enum } from "polkadot-api";
|
|
18
|
+
var PgasClaimError = class extends Error {
|
|
19
|
+
kind;
|
|
20
|
+
dispatchError;
|
|
21
|
+
constructor(message, options = {}) {
|
|
22
|
+
super(message, options);
|
|
23
|
+
this.name = "PgasClaimError";
|
|
24
|
+
this.kind = options.kind ?? "Unknown";
|
|
25
|
+
this.dispatchError = options.dispatchError;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
var SECS_PER_DAY = 86400n;
|
|
29
|
+
var IMPLICATION_EXCLUDE = /* @__PURE__ */ new Set([
|
|
30
|
+
"AuthorizeCall",
|
|
31
|
+
"AsPgas",
|
|
32
|
+
"StorageWeightReclaim"
|
|
33
|
+
]);
|
|
34
|
+
var PGAS_CONTEXT_PREFIX = new TextEncoder().encode("pop:gas:");
|
|
35
|
+
function buildGasContext(day, slotIndex) {
|
|
36
|
+
const out = new Uint8Array(32);
|
|
37
|
+
out.set(PGAS_CONTEXT_PREFIX, 0);
|
|
38
|
+
const dv = new DataView(out.buffer);
|
|
39
|
+
dv.setUint32(8, day, true);
|
|
40
|
+
dv.setUint32(12, slotIndex, true);
|
|
41
|
+
return out;
|
|
42
|
+
}
|
|
43
|
+
function buildAsPgasClaimExtensionValue(proof, ringIndex, revision, day) {
|
|
44
|
+
return Enum("Claim", {
|
|
45
|
+
proof: bytesToHex(proof),
|
|
46
|
+
ring_index: ringIndex,
|
|
47
|
+
revision,
|
|
48
|
+
collection: Enum("People"),
|
|
49
|
+
day
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
var claimPgas = async ({
|
|
53
|
+
peopleUnsafeApi,
|
|
54
|
+
ahUnsafeApi,
|
|
55
|
+
ahClient,
|
|
56
|
+
target,
|
|
57
|
+
memberKey,
|
|
58
|
+
buildRingProof,
|
|
59
|
+
slotIndex = 0,
|
|
60
|
+
progress
|
|
61
|
+
}) => {
|
|
62
|
+
const people = peopleUnsafeApi;
|
|
63
|
+
const ah = ahUnsafeApi;
|
|
64
|
+
if (memberKey.length !== 32) {
|
|
65
|
+
throw new PgasClaimError("memberKey must be 32 bytes", { kind: "ClientError" });
|
|
66
|
+
}
|
|
67
|
+
const asset = await ah.query.Assets.Asset.getValue(PGAS_ASSET_ID, { at: "best" });
|
|
68
|
+
if (!asset) {
|
|
69
|
+
throw new PgasClaimError(
|
|
70
|
+
"PGAS asset (id 2_000_000_000) does not exist on AH",
|
|
71
|
+
{ kind: "PgasAssetNotCreated" }
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
const position = await people.query.Members.Members.getValue(
|
|
75
|
+
PEOPLE_MEMBER_IDENTIFIER_HEX,
|
|
76
|
+
bytesToHex(memberKey),
|
|
77
|
+
{ at: "best" }
|
|
78
|
+
);
|
|
79
|
+
if (!position) {
|
|
80
|
+
throw new PgasClaimError(
|
|
81
|
+
"member key not present on People \u2014 recognize first",
|
|
82
|
+
{ kind: "NotARecognizedPerson" }
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
if (position.type !== "Included") {
|
|
86
|
+
throw new PgasClaimError(
|
|
87
|
+
`member position is '${position.type}', expected 'Included'`,
|
|
88
|
+
{ kind: "NotARecognizedPerson" }
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
const ringIndex = position.value.ring_index;
|
|
92
|
+
const allEntries = await people.query.Members.RingKeys.getEntries({ at: "best" });
|
|
93
|
+
const pages = [];
|
|
94
|
+
const identHex = PEOPLE_MEMBER_IDENTIFIER_HEX.toLowerCase();
|
|
95
|
+
for (const entry of allEntries) {
|
|
96
|
+
if (entry.keyArgs[0].toLowerCase() !== identHex) continue;
|
|
97
|
+
if (Number(entry.keyArgs[1]) !== ringIndex) continue;
|
|
98
|
+
pages.push([Number(entry.keyArgs[2]), [...entry.value]]);
|
|
99
|
+
}
|
|
100
|
+
pages.sort((a, b) => a[0] - b[0]);
|
|
101
|
+
const ringKeys = pages.flatMap(([, ks]) => ks);
|
|
102
|
+
if (ringKeys.length === 0) {
|
|
103
|
+
throw new PgasClaimError("ring has no members on People", {
|
|
104
|
+
kind: "ClientError"
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
const membersBytes = encodeMembers(ringKeys.map((k) => hexToBytes(k)));
|
|
108
|
+
const collectionId = await ah.constants.AliasAccounts.PeopleCollectionIdentifier();
|
|
109
|
+
const ringExp = await ah.constants.AliasAccounts.PeopleRingExponent();
|
|
110
|
+
const ringExponent = ringExp.type === "R2e9" ? 9 : ringExp.type === "R2e10" ? 10 : 14;
|
|
111
|
+
const ringRoots = await ah.query.MembersSubscriber.RingRoots.getValue(
|
|
112
|
+
collectionId,
|
|
113
|
+
ringIndex,
|
|
114
|
+
{ at: "best" }
|
|
115
|
+
);
|
|
116
|
+
if (!ringRoots || ringRoots.length === 0) {
|
|
117
|
+
throw new PgasClaimError(
|
|
118
|
+
"AH has no RingRoots for this (collection, ring_index)",
|
|
119
|
+
{ kind: "RingRootNotFound" }
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
const latest = ringRoots[ringRoots.length - 1];
|
|
123
|
+
const revision = latest.revision;
|
|
124
|
+
const nowRaw = await ah.query.Timestamp.Now.getValue({ at: "best" });
|
|
125
|
+
const nowSec = nowRaw > 10000000000n ? nowRaw / 1000n : nowRaw;
|
|
126
|
+
const day = Number(nowSec / SECS_PER_DAY);
|
|
127
|
+
const contextBytes = buildGasContext(day, slotIndex);
|
|
128
|
+
const innerTx = ah.tx.Pgas.claim_pgas({ slot_index: slotIndex, target });
|
|
129
|
+
const callBytes = await innerTx.getEncodedData();
|
|
130
|
+
const passEmpty = await capturePass(innerTx, void 0);
|
|
131
|
+
const msg = buildImplicationMessage(
|
|
132
|
+
callBytes,
|
|
133
|
+
passEmpty.extensions,
|
|
134
|
+
IMPLICATION_EXCLUDE
|
|
135
|
+
);
|
|
136
|
+
const { proof, alias } = await buildRingProof({
|
|
137
|
+
ringExponent,
|
|
138
|
+
members: membersBytes,
|
|
139
|
+
context: contextBytes,
|
|
140
|
+
msg
|
|
141
|
+
});
|
|
142
|
+
if (proof.length !== PROOF_BYTES) {
|
|
143
|
+
throw new PgasClaimError(
|
|
144
|
+
`ring proof must be ${PROOF_BYTES} bytes, got ${proof.length}`,
|
|
145
|
+
{ kind: "ClientError" }
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
const asPgasValue = Enum("Claim", {
|
|
149
|
+
proof: bytesToHex(proof),
|
|
150
|
+
ring_index: ringIndex,
|
|
151
|
+
revision,
|
|
152
|
+
collection: Enum("People"),
|
|
153
|
+
day
|
|
154
|
+
});
|
|
155
|
+
const passProof = await capturePass(innerTx, asPgasValue);
|
|
156
|
+
const extrinsicBytes = buildV5GeneralExtrinsic(callBytes, passProof.extensions);
|
|
157
|
+
const extrinsicHex = toHex(extrinsicBytes);
|
|
158
|
+
const blockHash = await submitExtrinsic(ahClient, extrinsicHex, progress);
|
|
159
|
+
const amount = await ah.constants.Pgas.PgasClaimAmount();
|
|
160
|
+
return { blockHash, amount, alias };
|
|
161
|
+
};
|
|
162
|
+
var capturePass = async (innerTx, asPgasValue) => {
|
|
163
|
+
let captured = null;
|
|
164
|
+
const sentinel = new Error("__pgas_capture_sentinel__");
|
|
165
|
+
const signer = {
|
|
166
|
+
publicKey: new Uint8Array(32),
|
|
167
|
+
signTx: async (callData, signedExtensions, metadata) => {
|
|
168
|
+
const order = await readExtensionOrder(metadata);
|
|
169
|
+
const byIdentifier = {};
|
|
170
|
+
for (const id of order) {
|
|
171
|
+
const ext = signedExtensions[id];
|
|
172
|
+
byIdentifier[id] = {
|
|
173
|
+
value: ext.value,
|
|
174
|
+
additionalSigned: ext.additionalSigned
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
captured = { callData, extensions: { order, byIdentifier } };
|
|
178
|
+
throw sentinel;
|
|
179
|
+
},
|
|
180
|
+
signBytes: async () => new Uint8Array(64)
|
|
181
|
+
};
|
|
182
|
+
try {
|
|
183
|
+
await innerTx.sign(signer, {
|
|
184
|
+
mortality: { mortal: false },
|
|
185
|
+
customSignedExtensions: {
|
|
186
|
+
AsPgas: {
|
|
187
|
+
value: asPgasValue,
|
|
188
|
+
additionalSigned: new Uint8Array()
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
} catch (err) {
|
|
193
|
+
if (err !== sentinel) throw err;
|
|
194
|
+
}
|
|
195
|
+
if (captured === null) {
|
|
196
|
+
throw new PgasClaimError("extension capture failed", { kind: "ClientError" });
|
|
197
|
+
}
|
|
198
|
+
return captured;
|
|
199
|
+
};
|
|
200
|
+
var narrowDispatchError = (dispatchError) => {
|
|
201
|
+
if (typeof dispatchError === "object" && dispatchError !== null && "type" in dispatchError) {
|
|
202
|
+
const d = dispatchError;
|
|
203
|
+
if (d.type === "Invalid" && typeof d.value === "object" && d.value !== null) {
|
|
204
|
+
const v = d.value;
|
|
205
|
+
if (v.type === "BadProof") return "BadProof";
|
|
206
|
+
if (v.type === "Custom") {
|
|
207
|
+
switch (v.value) {
|
|
208
|
+
case 230:
|
|
209
|
+
return "InvalidClaimSlot";
|
|
210
|
+
case 231:
|
|
211
|
+
return "InvalidClaimDay";
|
|
212
|
+
case 232:
|
|
213
|
+
return "AlreadyClaimedToday";
|
|
214
|
+
case 233:
|
|
215
|
+
return "PgasAssetNotCreated";
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return "DispatchError";
|
|
221
|
+
};
|
|
222
|
+
var submitExtrinsic = (client, extrinsicHex, progress) => {
|
|
223
|
+
return new Promise((resolve, reject) => {
|
|
224
|
+
let settled = false;
|
|
225
|
+
const fail = (err) => {
|
|
226
|
+
if (settled) return;
|
|
227
|
+
settled = true;
|
|
228
|
+
reject(err);
|
|
229
|
+
};
|
|
230
|
+
const succeed = (h) => {
|
|
231
|
+
if (settled) return;
|
|
232
|
+
settled = true;
|
|
233
|
+
resolve(h);
|
|
234
|
+
};
|
|
235
|
+
client.submitAndWatch(hexToBytes(extrinsicHex)).subscribe({
|
|
236
|
+
next: (event) => {
|
|
237
|
+
if (settled) return;
|
|
238
|
+
if (event.type === "broadcasted") {
|
|
239
|
+
progress?.onBroadcasted?.();
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (event.type === "txBestBlocksState" && event.found) {
|
|
243
|
+
if (event.ok === false) {
|
|
244
|
+
fail(
|
|
245
|
+
new PgasClaimError("claim_pgas dispatched but failed in-block", {
|
|
246
|
+
kind: narrowDispatchError(event.dispatchError),
|
|
247
|
+
dispatchError: event.dispatchError
|
|
248
|
+
})
|
|
249
|
+
);
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
progress?.onBestBlock?.(event.block.hash);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (event.type === "finalized") {
|
|
256
|
+
if (event.ok === false) {
|
|
257
|
+
fail(
|
|
258
|
+
new PgasClaimError("claim_pgas failed at finalization", {
|
|
259
|
+
kind: narrowDispatchError(event.dispatchError),
|
|
260
|
+
dispatchError: event.dispatchError
|
|
261
|
+
})
|
|
262
|
+
);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
succeed(event.block.hash);
|
|
266
|
+
}
|
|
267
|
+
},
|
|
268
|
+
error: (err) => {
|
|
269
|
+
fail(
|
|
270
|
+
err instanceof PgasClaimError ? err : new PgasClaimError(
|
|
271
|
+
err instanceof Error ? `RPC rejected extrinsic: ${err.message}` : "RPC error during submitAndWatch",
|
|
272
|
+
{ cause: err, kind: "RpcError" }
|
|
273
|
+
)
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
export {
|
|
281
|
+
PgasClaimError,
|
|
282
|
+
buildAsPgasClaimExtensionValue,
|
|
283
|
+
claimPgas
|
|
284
|
+
};
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildImplicationMessage,
|
|
3
|
+
buildV5GeneralExtrinsic,
|
|
4
|
+
bytesToHex,
|
|
5
|
+
hexToBytes,
|
|
6
|
+
readExtensionOrder,
|
|
7
|
+
toHex
|
|
8
|
+
} from "./chunk-ZYVGHDMU.js";
|
|
9
|
+
import {
|
|
10
|
+
BANDERSNATCH_SIGNATURE_BYTES
|
|
11
|
+
} from "./chunk-T7EEVWNU.js";
|
|
12
|
+
|
|
13
|
+
// src/personhood/bind-personal-id.ts
|
|
14
|
+
import { Enum } from "polkadot-api";
|
|
15
|
+
var AS_PERSON_IDENTIFIER = "AsPerson";
|
|
16
|
+
var VERIFY_MULTI_SIGNATURE_IDENTIFIER = "VerifyMultiSignature";
|
|
17
|
+
var IMPLICATION_EXCLUDE = /* @__PURE__ */ new Set([
|
|
18
|
+
"VerifyMultiSignature",
|
|
19
|
+
AS_PERSON_IDENTIFIER,
|
|
20
|
+
"AuthorizeCall",
|
|
21
|
+
"StorageWeightReclaim"
|
|
22
|
+
]);
|
|
23
|
+
var PersonalIdBindingError = class extends Error {
|
|
24
|
+
dispatchError;
|
|
25
|
+
kind;
|
|
26
|
+
constructor(message, options = {}) {
|
|
27
|
+
super(message, options);
|
|
28
|
+
this.name = "PersonalIdBindingError";
|
|
29
|
+
this.kind = options.kind ?? "unknown";
|
|
30
|
+
this.dispatchError = options.dispatchError;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
function buildAsPersonExtensionValue(signature, personalId) {
|
|
34
|
+
return Enum("AsPersonalIdentityWithProof", [bytesToHex(signature), personalId]);
|
|
35
|
+
}
|
|
36
|
+
var bindPersonalIdToAccount = async ({
|
|
37
|
+
typedApi,
|
|
38
|
+
client,
|
|
39
|
+
personalId,
|
|
40
|
+
account,
|
|
41
|
+
signMember,
|
|
42
|
+
callValidAt,
|
|
43
|
+
progress
|
|
44
|
+
}) => {
|
|
45
|
+
const api = typedApi;
|
|
46
|
+
if (typeof api.tx?.People?.set_personal_id_account !== "function") {
|
|
47
|
+
throw new PersonalIdBindingError(
|
|
48
|
+
"typedApi does not expose People.set_personal_id_account \u2014 wrong chain or stale descriptors",
|
|
49
|
+
{ kind: "client_error" }
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
const block = callValidAt ?? await api.query.System.Number.getValue();
|
|
53
|
+
const innerTx = api.tx.People.set_personal_id_account({
|
|
54
|
+
account,
|
|
55
|
+
call_valid_at: block
|
|
56
|
+
});
|
|
57
|
+
const callBytes = await innerTx.getEncodedData();
|
|
58
|
+
const passEmpty = await capturePass({
|
|
59
|
+
innerTx,
|
|
60
|
+
asPersonValue: new Uint8Array()
|
|
61
|
+
});
|
|
62
|
+
const msgHash = buildImplicationMessage(
|
|
63
|
+
callBytes,
|
|
64
|
+
passEmpty.extensions,
|
|
65
|
+
IMPLICATION_EXCLUDE
|
|
66
|
+
);
|
|
67
|
+
const signature = await Promise.resolve(signMember(msgHash));
|
|
68
|
+
if (signature.length !== BANDERSNATCH_SIGNATURE_BYTES) {
|
|
69
|
+
throw new PersonalIdBindingError(
|
|
70
|
+
`Bandersnatch signature must be ${BANDERSNATCH_SIGNATURE_BYTES} bytes, got ${signature.length}`,
|
|
71
|
+
{ kind: "client_error" }
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
const asPersonProof = Enum("AsPersonalIdentityWithProof", [bytesToHex(signature), personalId]);
|
|
75
|
+
const passProof = await capturePass({
|
|
76
|
+
innerTx,
|
|
77
|
+
asPersonValue: asPersonProof
|
|
78
|
+
});
|
|
79
|
+
const extrinsicBytes = buildV5GeneralExtrinsic(callBytes, passProof.extensions);
|
|
80
|
+
const extrinsicHex = toHex(extrinsicBytes);
|
|
81
|
+
const blockHash = await submitExtrinsic(client, extrinsicHex, progress);
|
|
82
|
+
return { extrinsicHex, blockHash };
|
|
83
|
+
};
|
|
84
|
+
var capturePass = async ({
|
|
85
|
+
innerTx,
|
|
86
|
+
asPersonValue
|
|
87
|
+
}) => {
|
|
88
|
+
let captured = null;
|
|
89
|
+
const sentinel = new Error("__personhood_capture_sentinel__");
|
|
90
|
+
const signer = {
|
|
91
|
+
publicKey: new Uint8Array(32),
|
|
92
|
+
signTx: async (callData, signedExtensions, metadata) => {
|
|
93
|
+
const order = await readExtensionOrder(metadata);
|
|
94
|
+
const byIdentifier = {};
|
|
95
|
+
for (const id of order) {
|
|
96
|
+
const ext = signedExtensions[id];
|
|
97
|
+
if (!ext) {
|
|
98
|
+
throw new PersonalIdBindingError(
|
|
99
|
+
`papi did not produce signed extension '${id}'`
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
byIdentifier[id] = {
|
|
103
|
+
value: ext.value,
|
|
104
|
+
additionalSigned: ext.additionalSigned
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
captured = { callData, extensions: { order, byIdentifier } };
|
|
108
|
+
throw sentinel;
|
|
109
|
+
},
|
|
110
|
+
signBytes: async () => new Uint8Array(64)
|
|
111
|
+
};
|
|
112
|
+
try {
|
|
113
|
+
await innerTx.sign(signer, {
|
|
114
|
+
customSignedExtensions: {
|
|
115
|
+
[AS_PERSON_IDENTIFIER]: {
|
|
116
|
+
value: asPersonValue,
|
|
117
|
+
additionalSigned: new Uint8Array()
|
|
118
|
+
},
|
|
119
|
+
[VERIFY_MULTI_SIGNATURE_IDENTIFIER]: {
|
|
120
|
+
value: Enum("Disabled")
|
|
121
|
+
},
|
|
122
|
+
RestrictOrigins: {
|
|
123
|
+
value: new Uint8Array([1]),
|
|
124
|
+
additionalSigned: new Uint8Array()
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
} catch (err) {
|
|
129
|
+
if (err !== sentinel) throw err;
|
|
130
|
+
}
|
|
131
|
+
if (!captured) {
|
|
132
|
+
throw new PersonalIdBindingError(
|
|
133
|
+
"extension capture failed \u2014 papi never invoked signTx",
|
|
134
|
+
{ kind: "client_error" }
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
return captured;
|
|
138
|
+
};
|
|
139
|
+
var submitExtrinsic = (client, extrinsicHex, progress) => {
|
|
140
|
+
return new Promise((resolve, reject) => {
|
|
141
|
+
let settled = false;
|
|
142
|
+
const fail = (err) => {
|
|
143
|
+
if (settled) return;
|
|
144
|
+
settled = true;
|
|
145
|
+
reject(err);
|
|
146
|
+
};
|
|
147
|
+
const succeed = (blockHash) => {
|
|
148
|
+
if (settled) return;
|
|
149
|
+
settled = true;
|
|
150
|
+
resolve(blockHash);
|
|
151
|
+
};
|
|
152
|
+
client.submitAndWatch(hexToBytes(extrinsicHex)).subscribe({
|
|
153
|
+
next: (event) => {
|
|
154
|
+
if (settled) return;
|
|
155
|
+
if (event.type === "broadcasted") {
|
|
156
|
+
progress?.onBroadcasted?.();
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (event.type === "txBestBlocksState" && event.found) {
|
|
160
|
+
if (event.ok === false) {
|
|
161
|
+
fail(
|
|
162
|
+
new PersonalIdBindingError(
|
|
163
|
+
"set_personal_id_account dispatched but failed in-block",
|
|
164
|
+
{
|
|
165
|
+
kind: "dispatch_error",
|
|
166
|
+
dispatchError: event.dispatchError
|
|
167
|
+
}
|
|
168
|
+
)
|
|
169
|
+
);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
progress?.onBestBlock?.(event.block.hash);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (event.type === "finalized") {
|
|
176
|
+
if (event.ok === false) {
|
|
177
|
+
fail(
|
|
178
|
+
new PersonalIdBindingError(
|
|
179
|
+
"set_personal_id_account dispatch failed at finalization",
|
|
180
|
+
{
|
|
181
|
+
kind: "dispatch_error",
|
|
182
|
+
dispatchError: event.dispatchError
|
|
183
|
+
}
|
|
184
|
+
)
|
|
185
|
+
);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
succeed(event.block.hash);
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
error: (err) => {
|
|
192
|
+
fail(
|
|
193
|
+
err instanceof PersonalIdBindingError ? err : new PersonalIdBindingError(
|
|
194
|
+
err instanceof Error ? `RPC rejected extrinsic: ${err.message}` : "RPC error during submitAndWatch",
|
|
195
|
+
{ cause: err, kind: "rpc_error" }
|
|
196
|
+
)
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
export {
|
|
204
|
+
PersonalIdBindingError,
|
|
205
|
+
buildAsPersonExtensionValue,
|
|
206
|
+
bindPersonalIdToAccount
|
|
207
|
+
};
|