@parity/product-sdk 0.22.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/chunk-7GM3HUZF.js +89 -0
  2. package/dist/chunk-7GM3HUZF.js.map +1 -0
  3. package/dist/{chunk-6BI66XUJ.js → chunk-JIO3OZSC.js} +9 -10
  4. package/dist/chunk-JIO3OZSC.js.map +1 -0
  5. package/dist/core/index.d.ts +2 -2
  6. package/dist/core/index.js +2 -2
  7. package/dist/dotns-CtmOwVQW.d.ts +136 -0
  8. package/dist/identity/index.d.ts +502 -45
  9. package/dist/identity/index.js +800 -32
  10. package/dist/identity/index.js.map +1 -1
  11. package/dist/index.d.ts +3 -3
  12. package/dist/index.js +2 -2
  13. package/dist/react/index.d.ts +2 -2
  14. package/dist/react/index.js +2 -2
  15. package/dist/testing/index.d.ts +2 -2
  16. package/dist/{types-DTgyMIi0.d.ts → types-CRYPRNYk.d.ts} +1 -1
  17. package/package.json +12 -12
  18. package/src/core/createApp.ts +10 -8
  19. package/src/identity/dotns-abis.test.ts +43 -0
  20. package/src/identity/dotns-abis.ts +309 -0
  21. package/src/identity/dotns-addresses.test.ts +536 -0
  22. package/src/identity/dotns-addresses.ts +320 -0
  23. package/src/identity/dotns-errors.ts +36 -0
  24. package/src/identity/dotns-namehash.test.ts +155 -0
  25. package/src/identity/dotns-namehash.ts +149 -0
  26. package/src/identity/dotns-owner.test.ts +92 -0
  27. package/src/identity/dotns-registry.test.ts +1309 -0
  28. package/src/identity/dotns-registry.ts +868 -0
  29. package/src/identity/dotns.test.ts +128 -0
  30. package/src/identity/dotns.ts +91 -78
  31. package/src/identity/index.test.ts +43 -0
  32. package/src/identity/index.ts +40 -10
  33. package/src/identity/types.ts +29 -25
  34. package/src/individuality/contract.test.ts +295 -3
  35. package/dist/chunk-6BI66XUJ.js.map +0 -1
  36. package/dist/chunk-BIKT6X54.js +0 -70
  37. package/dist/chunk-BIKT6X54.js.map +0 -1
  38. package/dist/dotns-DIaptENj.d.ts +0 -167
  39. package/src/identity/product-account.test.ts +0 -129
  40. package/src/identity/product-account.ts +0 -115
@@ -1,45 +1,813 @@
1
- export { accountIdHexToBytes, isDotNsAvailable, isValidDotNsName, normalizeDotNsName, resolveDotNs, resolvePeopleUsernameOwner, reverseDotNs } from '../chunk-BIKT6X54.js';
1
+ import { normalizeDotNsName, isResolvableDotNsName, namehash, isValidDotNsName, stripSuffix, isConsistentDotNsTld, DOT_TLD, dotNsTld } from '../chunk-7GM3HUZF.js';
2
+ export { DOT_NODE, DOT_TLD, accountIdHexToBytes, accountIdToHex, dotNsTld, isConsistentDotNsTld, isResolvableDotNsName, isValidDotNsName, namehash, normalizeDotNsName, resolvePeopleUsernameOwner, stripSuffix } from '../chunk-7GM3HUZF.js';
3
+ import { ok, err } from '@parity/result';
4
+ import { bytesToHex, randomBytes } from '@parity/product-sdk-crypto';
5
+ import { ss58ToH160 } from '@parity/product-sdk-address';
2
6
  import { createLogger } from '@parity/product-sdk-logger';
3
- import { blake2b256 } from '@parity/product-sdk-crypto';
4
- import { ss58Decode, ss58Encode, deriveH160 } from '@parity/product-sdk-address';
7
+ import { QUERY_FALLBACK_ORIGIN, createContract } from '@parity/product-sdk-contracts';
5
8
 
6
- var log = createLogger("identity");
7
- function deriveContextAlias(parentAddress, context, ss58Prefix = 42) {
8
- const { publicKey: parentPublicKey } = ss58Decode(parentAddress);
9
- const contextBytes = new TextEncoder().encode(context);
10
- const combined = new Uint8Array(parentPublicKey.length + contextBytes.length);
11
- combined.set(parentPublicKey, 0);
12
- combined.set(contextBytes, parentPublicKey.length);
13
- const aliasPublicKey = blake2b256(combined);
14
- const address = ss58Encode(aliasPublicKey, ss58Prefix);
15
- const h160Address = deriveH160(aliasPublicKey);
16
- log.debug("Derived context alias", {
17
- parentAddress,
18
- context,
19
- address
9
+ // src/identity/dotns-abis.ts
10
+ var DOTNS_REGISTRY_ABI = [
11
+ {
12
+ type: "function",
13
+ name: "resolver",
14
+ inputs: [{ name: "node", type: "bytes32" }],
15
+ outputs: [{ name: "", type: "address" }],
16
+ stateMutability: "view"
17
+ },
18
+ {
19
+ type: "function",
20
+ name: "owner",
21
+ inputs: [{ name: "node", type: "bytes32" }],
22
+ outputs: [{ name: "", type: "address" }],
23
+ stateMutability: "view"
24
+ },
25
+ {
26
+ type: "function",
27
+ name: "setResolver",
28
+ inputs: [
29
+ { name: "node", type: "bytes32" },
30
+ { name: "resolverAddr", type: "address" }
31
+ ],
32
+ outputs: [],
33
+ stateMutability: "nonpayable"
34
+ }
35
+ ];
36
+ var DOTNS_RESOLVER_ABI = [
37
+ {
38
+ type: "function",
39
+ name: "addressOf",
40
+ inputs: [{ name: "node", type: "bytes32" }],
41
+ outputs: [{ name: "value", type: "address" }],
42
+ stateMutability: "view"
43
+ }
44
+ ];
45
+ var DOTNS_REVERSE_RESOLVER_ABI = [
46
+ {
47
+ type: "function",
48
+ name: "nameOf",
49
+ inputs: [{ name: "addr", type: "address" }],
50
+ outputs: [{ name: "name", type: "string" }],
51
+ stateMutability: "view"
52
+ }
53
+ ];
54
+ var DOTNS_RESOLVER_WRITE_ABI = [
55
+ {
56
+ type: "function",
57
+ name: "setAddress",
58
+ inputs: [
59
+ { name: "node", type: "bytes32" },
60
+ { name: "value", type: "address" }
61
+ ],
62
+ outputs: [],
63
+ stateMutability: "nonpayable"
64
+ }
65
+ ];
66
+ var DOTNS_REGISTRAR_CONTROLLER_ABI = [
67
+ {
68
+ type: "function",
69
+ name: "available",
70
+ inputs: [{ name: "label", type: "string" }],
71
+ outputs: [{ name: "isAvailable", type: "bool" }],
72
+ stateMutability: "view"
73
+ },
74
+ {
75
+ type: "function",
76
+ name: "minCommitmentAge",
77
+ inputs: [],
78
+ outputs: [{ name: "", type: "uint256" }],
79
+ stateMutability: "view"
80
+ },
81
+ {
82
+ type: "function",
83
+ name: "maxCommitmentAge",
84
+ inputs: [],
85
+ outputs: [{ name: "", type: "uint256" }],
86
+ stateMutability: "view"
87
+ },
88
+ {
89
+ type: "function",
90
+ name: "makeCommitment",
91
+ inputs: [
92
+ {
93
+ name: "registration",
94
+ type: "tuple",
95
+ components: [
96
+ { name: "label", type: "string" },
97
+ { name: "owner", type: "address" },
98
+ { name: "secret", type: "bytes32" },
99
+ { name: "reserved", type: "bool" }
100
+ ]
101
+ }
102
+ ],
103
+ outputs: [{ name: "commitment", type: "bytes32" }],
104
+ stateMutability: "pure"
105
+ },
106
+ {
107
+ type: "function",
108
+ name: "commit",
109
+ inputs: [{ name: "commitment", type: "bytes32" }],
110
+ outputs: [],
111
+ stateMutability: "nonpayable"
112
+ },
113
+ {
114
+ type: "function",
115
+ name: "register",
116
+ inputs: [
117
+ {
118
+ name: "registration",
119
+ type: "tuple",
120
+ components: [
121
+ { name: "label", type: "string" },
122
+ { name: "owner", type: "address" },
123
+ { name: "secret", type: "bytes32" },
124
+ { name: "reserved", type: "bool" }
125
+ ]
126
+ }
127
+ ],
128
+ outputs: [],
129
+ stateMutability: "payable"
130
+ }
131
+ ];
132
+ var DOTNS_POP_RULES_ABI = [
133
+ {
134
+ type: "function",
135
+ name: "price",
136
+ inputs: [{ name: "name", type: "string" }],
137
+ outputs: [{ name: "cost", type: "uint256" }],
138
+ stateMutability: "view"
139
+ },
140
+ {
141
+ type: "function",
142
+ name: "priceWithoutCheck",
143
+ inputs: [
144
+ { name: "name", type: "string" },
145
+ { name: "userAddress", type: "address" }
146
+ ],
147
+ outputs: [
148
+ {
149
+ name: "metadata",
150
+ type: "tuple",
151
+ components: [
152
+ { name: "price", type: "uint256" },
153
+ { name: "status", type: "uint8" },
154
+ { name: "userStatus", type: "uint8" },
155
+ { name: "message", type: "string" }
156
+ ]
157
+ }
158
+ ],
159
+ stateMutability: "view"
160
+ },
161
+ {
162
+ type: "function",
163
+ name: "classifyName",
164
+ inputs: [{ name: "name", type: "string" }],
165
+ outputs: [
166
+ { name: "requirement", type: "uint8" },
167
+ { name: "message", type: "string" }
168
+ ],
169
+ stateMutability: "pure"
170
+ },
171
+ {
172
+ type: "function",
173
+ name: "transferFloor",
174
+ inputs: [
175
+ { name: "name", type: "string" },
176
+ { name: "from", type: "address" },
177
+ { name: "to", type: "address" }
178
+ ],
179
+ outputs: [{ name: "floor", type: "uint256" }],
180
+ stateMutability: "view"
181
+ }
182
+ ];
183
+ var DOTNS_PROTOCOL_REGISTRY_ABI = [
184
+ {
185
+ type: "function",
186
+ name: "tld",
187
+ inputs: [],
188
+ outputs: [{ name: "suffix", type: "string" }],
189
+ stateMutability: "view"
190
+ },
191
+ {
192
+ type: "function",
193
+ name: "tldNode",
194
+ inputs: [],
195
+ outputs: [{ name: "node", type: "bytes32" }],
196
+ stateMutability: "view"
197
+ },
198
+ {
199
+ type: "function",
200
+ name: "get",
201
+ inputs: [{ name: "key", type: "bytes32" }],
202
+ outputs: [{ name: "addr", type: "address" }],
203
+ stateMutability: "view"
204
+ }
205
+ ];
206
+ var DOTNS_ROOT_GATEWAY_DISPATCHER_ABI = [
207
+ {
208
+ type: "function",
209
+ name: "TARGET",
210
+ inputs: [],
211
+ outputs: [{ name: "", type: "address" }],
212
+ stateMutability: "view"
213
+ }
214
+ ];
215
+ var DOTNS_POP_CONTROLLER_ABI = [
216
+ {
217
+ type: "function",
218
+ name: "protocolRegistry",
219
+ inputs: [],
220
+ outputs: [{ name: "", type: "address" }],
221
+ stateMutability: "view"
222
+ }
223
+ ];
224
+ var POP_STATUS = { NoStatus: 0, PopLite: 1, PopFull: 2, Reserved: 3 };
225
+ var DOTNS_ADDRESSES = {
226
+ registry: "0xf34054fd76BbF85f216cf9908226D5f0A72E50CA",
227
+ reverseResolver: "0xee3883d7eB60Ee9BCD7F3bcD8f2f05302A9Cc035",
228
+ resolver: "0xbd1165E549DF96F083c0A16f61590927bC187009",
229
+ registrarController: "0xBdaA01bD1bA67d709F2b1fF286Da0d854977EA30",
230
+ popRules: "0x747B456bE03aec0b42bd85C51513730FBD45DA31",
231
+ protocolRegistry: "0xD19e3D0C97CF501125a04A97405e3e6592fa846E"
232
+ };
233
+
234
+ // src/identity/dotns-errors.ts
235
+ var DotNsError = class extends Error {
236
+ isSdkError = true;
237
+ source = "dotns";
238
+ reason;
239
+ constructor(reason, message, options) {
240
+ super(message, options);
241
+ this.name = "DotNsError";
242
+ this.reason = reason;
243
+ }
244
+ };
245
+ var DOTNS_REGISTRY_KEYS = {
246
+ registry: "0x7265676973747279000000000000000000000000000000000000000000000000",
247
+ registrarController: "0x636f6e74726f6c6c657200000000000000000000000000000000000000000000",
248
+ reverseResolver: "0x726576657273655265736f6c7665720000000000000000000000000000000000",
249
+ resolver: "0x7265736f6c766572000000000000000000000000000000000000000000000000",
250
+ popRules: "0x706f7052756c6573000000000000000000000000000000000000000000000000"
251
+ };
252
+ var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
253
+ function isZero(addr) {
254
+ return typeof addr === "string" && addr.toLowerCase() === ZERO_ADDRESS;
255
+ }
256
+ function sameAddress(a, b) {
257
+ return typeof a === "string" && typeof b === "string" && a.toLowerCase() === b.toLowerCase();
258
+ }
259
+ function cachedPerRuntime(cache, runtime, key, load) {
260
+ let byKey = cache.get(runtime);
261
+ if (!byKey) {
262
+ byKey = /* @__PURE__ */ new Map();
263
+ cache.set(runtime, byKey);
264
+ }
265
+ const cached = byKey.get(key);
266
+ if (cached) return cached;
267
+ const pending = load();
268
+ byKey.set(key, pending);
269
+ pending.then((result) => {
270
+ if (!result.ok) byKey?.delete(key);
20
271
  });
272
+ return pending;
273
+ }
274
+ function withOverrides(base, opts) {
21
275
  return {
22
- address,
23
- h160Address,
24
- parentAddress,
25
- context
276
+ registry: opts.registryAddress ?? base.registry,
277
+ reverseResolver: opts.reverseResolverAddress ?? base.reverseResolver,
278
+ resolver: opts.resolverAddress ?? base.resolver,
279
+ registrarController: opts.registrarControllerAddress ?? base.registrarController,
280
+ popRules: opts.popRulesAddress ?? base.popRules,
281
+ protocolRegistry: opts.protocolRegistryAddress ?? base.protocolRegistry
26
282
  };
27
283
  }
28
- function verifyContextAlias(aliasAddress, parentAddress, context) {
284
+ var walkCache = /* @__PURE__ */ new WeakMap();
285
+ var WALK_KEY = "discovered";
286
+ async function resolveDotNsAddresses(opts) {
287
+ if (opts.addressSource !== "discovered") return ok(withOverrides(DOTNS_ADDRESSES, opts));
288
+ const walked = await cachedPerRuntime(
289
+ walkCache,
290
+ opts.runtime,
291
+ WALK_KEY,
292
+ () => discoverDotNsAddresses(opts)
293
+ );
294
+ return walked.ok ? ok(withOverrides(walked.value, opts)) : walked;
295
+ }
296
+ var discoveryFailed = (step, cause) => err(new DotNsError("AddressDiscovery", `DotNS address discovery failed: ${step}`, { cause }));
297
+ function contractOf(runtime, address, abi) {
298
+ return createContract(runtime, address, abi);
299
+ }
300
+ function readOrigin(opts) {
301
+ return opts.origin ?? QUERY_FALLBACK_ORIGIN;
302
+ }
303
+ async function readAddress(contract, method, origin) {
304
+ const res = await contract[method].query({ origin });
305
+ if (!res.success) return discoveryFailed(`${method}() failed`, res.value);
306
+ const value = res.value;
307
+ if (typeof value !== "string" || isZero(value)) {
308
+ return discoveryFailed(`${method}() returned no address`);
309
+ }
310
+ return ok(value);
311
+ }
312
+ function asH160(value) {
313
+ if (typeof value === "string") return value;
314
+ if (value && typeof value.asHex === "function") {
315
+ return value.asHex();
316
+ }
317
+ return null;
318
+ }
319
+ function gatewayOf(opts) {
320
+ if (opts.gatewayApi) return opts.gatewayApi;
321
+ const api = opts.runtime?.api;
322
+ const getValue = api?.query?.DotnsGateway?.DispatcherAddress?.getValue;
323
+ return typeof getValue === "function" ? api : null;
324
+ }
325
+ async function discoverDotNsAddresses(opts) {
326
+ try {
327
+ const gateway = gatewayOf(opts);
328
+ if (!gateway) {
329
+ return discoveryFailed(
330
+ "no DotnsGateway.DispatcherAddress storage on this runtime; pass opts.gatewayApi"
331
+ );
332
+ }
333
+ const dispatcher = asH160(await gateway.query.DotnsGateway.DispatcherAddress.getValue());
334
+ if (!dispatcher || isZero(dispatcher)) {
335
+ return discoveryFailed("DotnsGateway.DispatcherAddress is unset");
336
+ }
337
+ const origin = readOrigin(opts);
338
+ const target = await readAddress(
339
+ contractOf(opts.runtime, dispatcher, DOTNS_ROOT_GATEWAY_DISPATCHER_ABI),
340
+ "TARGET",
341
+ origin
342
+ );
343
+ if (!target.ok) return target;
344
+ const protocolRegistry = await readAddress(
345
+ contractOf(opts.runtime, target.value, DOTNS_POP_CONTROLLER_ABI),
346
+ "protocolRegistry",
347
+ origin
348
+ );
349
+ if (!protocolRegistry.ok) return protocolRegistry;
350
+ const registry = contractOf(
351
+ opts.runtime,
352
+ protocolRegistry.value,
353
+ DOTNS_PROTOCOL_REGISTRY_ABI
354
+ );
355
+ const roles = Object.entries(DOTNS_REGISTRY_KEYS);
356
+ const found = await Promise.all(
357
+ roles.map(async ([role, key]) => {
358
+ const res = await registry.get.query(key, { origin });
359
+ if (!res.success) return discoveryFailed(`get(${role}) failed`, res.value);
360
+ const value = res.value;
361
+ if (typeof value !== "string" || isZero(value)) {
362
+ return discoveryFailed(`${role} is unset on the protocol registry`);
363
+ }
364
+ return ok([role, value]);
365
+ })
366
+ );
367
+ const failed = found.find((r) => !r.ok);
368
+ if (failed && !failed.ok) return failed;
369
+ const byRole = Object.fromEntries(found.flatMap((r) => r.ok ? [r.value] : []));
370
+ return ok({ ...byRole, protocolRegistry: protocolRegistry.value });
371
+ } catch (cause) {
372
+ return discoveryFailed("unexpected error", cause);
373
+ }
374
+ }
375
+ async function verifyDotNsAddresses(opts) {
376
+ const discovered = await cachedPerRuntime(
377
+ walkCache,
378
+ opts.runtime,
379
+ WALK_KEY,
380
+ () => discoverDotNsAddresses(opts)
381
+ );
382
+ if (!discovered.ok) return discovered;
383
+ const inUse = withOverrides(
384
+ opts.addressSource === "discovered" ? discovered.value : DOTNS_ADDRESSES,
385
+ opts
386
+ );
387
+ const drift = Object.keys(inUse).filter((role) => !sameAddress(inUse[role], discovered.value[role])).map((role) => `${role}: using ${inUse[role]}, chain says ${discovered.value[role]}`);
388
+ return drift.length ? err(
389
+ new DotNsError(
390
+ "AddressMismatch",
391
+ `DotNS addresses disagree with the deployment \u2014 ${drift.join("; ")}`
392
+ )
393
+ ) : ok(inUse);
394
+ }
395
+
396
+ // src/identity/dotns-registry.ts
397
+ var log = createLogger("identity:dotns");
398
+ var tldCache = /* @__PURE__ */ new WeakMap();
399
+ function isEmptyRevert(value) {
400
+ return typeof value === "object" && value !== null && value.type === "ContractRevertedWithPayload" && value.data === "0x";
401
+ }
402
+ async function resolveTld(opts) {
403
+ if (opts.tld) {
404
+ return isConsistentDotNsTld(opts.tld) ? ok(opts.tld) : err(
405
+ new DotNsError(
406
+ "InvalidTld",
407
+ `opts.tld is inconsistent: "${opts.tld.suffix}" does not hash to ${opts.tld.node}`
408
+ )
409
+ );
410
+ }
411
+ const addresses = await resolveDotNsAddresses(opts);
412
+ if (!addresses.ok) return addresses;
413
+ const address = addresses.value.protocolRegistry;
414
+ return cachedPerRuntime(tldCache, opts.runtime, address, () => readTld(opts, address));
415
+ }
416
+ async function readTld(opts, address) {
417
+ try {
418
+ const registry = contractOf(opts.runtime, address, DOTNS_PROTOCOL_REGISTRY_ABI);
419
+ const origin = readOrigin(opts);
420
+ const suffixRes = await registry.tld.query({ origin });
421
+ if (!suffixRes.success) {
422
+ if (isEmptyRevert(suffixRes.value)) {
423
+ log.warn(
424
+ "DotNS protocol registry has no tld() getter; treating this as a pre-b4096968 deployment, whose TLD was the compile-time .dot",
425
+ { protocolRegistry: address }
426
+ );
427
+ return ok(DOT_TLD);
428
+ }
429
+ return err(
430
+ new DotNsError("RegistryCall", "protocolRegistry.tld call failed", {
431
+ cause: suffixRes.value
432
+ })
433
+ );
434
+ }
435
+ const suffix = suffixRes.value;
436
+ const tld = dotNsTld(suffix);
437
+ if (!isConsistentDotNsTld(tld)) {
438
+ return err(
439
+ new DotNsError(
440
+ "InvalidTld",
441
+ `protocolRegistry.tld returned an unusable TLD: ${JSON.stringify(suffix)}`
442
+ )
443
+ );
444
+ }
445
+ const nodeRes = await registry.tldNode.query({ origin });
446
+ if (nodeRes.success && isNode(nodeRes.value) && !sameNode(nodeRes.value, tld.node)) {
447
+ return err(
448
+ new DotNsError(
449
+ "InvalidTld",
450
+ `protocolRegistry disagrees with itself: tld() ${suffix} derives ${tld.node} but tldNode() reports ${String(nodeRes.value)}`
451
+ )
452
+ );
453
+ }
454
+ log.debug("resolveTld", { protocolRegistry: address, suffix: tld.suffix, node: tld.node });
455
+ return ok(tld);
456
+ } catch (cause) {
457
+ return err(new DotNsError("RegistryCall", "DotNS TLD read failed", { cause }));
458
+ }
459
+ }
460
+ function nameError(input, normalized, tld) {
461
+ if (!normalized.endsWith(tld.suffix)) {
462
+ return new DotNsError(
463
+ "TldMismatch",
464
+ `DotNS name "${input}" is not on this deployment, which uses "${tld.suffix}"`
465
+ );
466
+ }
467
+ return new DotNsError("InvalidName", `Invalid DotNS name: "${input}"`);
468
+ }
469
+ function isNode(value) {
470
+ return typeof value === "string" && /^0x[0-9a-fA-F]{64}$/.test(value);
471
+ }
472
+ function sameNode(a, b) {
473
+ return a.toLowerCase() === b.toLowerCase();
474
+ }
475
+ async function resolveDotNs(name, opts) {
476
+ const tldRes = await resolveTld(opts);
477
+ if (!tldRes.ok) return tldRes;
478
+ const tld = tldRes.value;
479
+ const normalized = normalizeDotNsName(name, tld.suffix);
480
+ if (!isResolvableDotNsName(normalized, tld.suffix)) {
481
+ return err(nameError(name, normalized, tld));
482
+ }
483
+ const node = namehash(normalized, tld);
484
+ const addrs = await resolveDotNsAddresses(opts);
485
+ if (!addrs.ok) return addrs;
486
+ const registryAddr = addrs.value.registry;
487
+ const origin = readOrigin(opts);
488
+ log.debug("resolveDotNs", { name: normalized, node, registry: registryAddr });
29
489
  try {
30
- const derived = deriveContextAlias(parentAddress, context);
31
- const { publicKey: aliasKey } = ss58Decode(aliasAddress);
32
- const { publicKey: derivedKey } = ss58Decode(derived.address);
33
- if (aliasKey.length !== derivedKey.length) return false;
34
- for (let i = 0; i < aliasKey.length; i++) {
35
- if (aliasKey[i] !== derivedKey[i]) return false;
490
+ const registry = contractOf(opts.runtime, registryAddr, DOTNS_REGISTRY_ABI);
491
+ const [ownerRes, resolverRes] = await Promise.all([
492
+ registry.owner.query(node, { origin }),
493
+ registry.resolver.query(node, { origin })
494
+ ]);
495
+ if (!ownerRes.success) {
496
+ return err(
497
+ new DotNsError("RegistryCall", "registry.owner call failed", {
498
+ cause: ownerRes.value
499
+ })
500
+ );
501
+ }
502
+ if (!resolverRes.success) {
503
+ return err(
504
+ new DotNsError("RegistryCall", "registry.resolver call failed", {
505
+ cause: resolverRes.value
506
+ })
507
+ );
508
+ }
509
+ const owner = ownerRes.value;
510
+ if (isZero(owner)) return ok(null);
511
+ const resolverAddr = resolverRes.value;
512
+ const forwardAddr = addrs.value.resolver;
513
+ if (!sameAddress(resolverAddr, forwardAddr)) {
514
+ return ok({ name: normalized, owner });
515
+ }
516
+ const resolver = contractOf(opts.runtime, resolverAddr, DOTNS_RESOLVER_ABI);
517
+ const addrRes = await resolver.addressOf.query(node, { origin });
518
+ if (!addrRes.success) {
519
+ return err(
520
+ new DotNsError("RegistryCall", "resolver.addressOf call failed", {
521
+ cause: addrRes.value
522
+ })
523
+ );
524
+ }
525
+ const address = addrRes.value;
526
+ if (isZero(address)) return ok({ name: normalized, owner });
527
+ return ok({ address, name: normalized, owner });
528
+ } catch (cause) {
529
+ return err(
530
+ new DotNsError("RegistryCall", `DotNS resolve failed for "${normalized}"`, { cause })
531
+ );
532
+ }
533
+ }
534
+ async function reverseDotNs(address, opts) {
535
+ const addrs = await resolveDotNsAddresses(opts);
536
+ if (!addrs.ok) return addrs;
537
+ const reverseAddr = addrs.value.reverseResolver;
538
+ log.debug("reverseDotNs", { address, reverseResolver: reverseAddr });
539
+ try {
540
+ const reverse = contractOf(
541
+ opts.runtime,
542
+ reverseAddr,
543
+ DOTNS_REVERSE_RESOLVER_ABI
544
+ );
545
+ const res = await reverse.nameOf.query(address, { origin: readOrigin(opts) });
546
+ if (!res.success) {
547
+ return err(
548
+ new DotNsError("RegistryCall", "reverseResolver.nameOf call failed", {
549
+ cause: res.value
550
+ })
551
+ );
552
+ }
553
+ const name = res.value;
554
+ return ok(name && name.length > 0 ? name : null);
555
+ } catch (cause) {
556
+ return err(
557
+ new DotNsError("RegistryCall", `DotNS reverse failed for "${address}"`, { cause })
558
+ );
559
+ }
560
+ }
561
+ async function isDotNsAvailable(name, opts) {
562
+ const tldRes = await resolveTld(opts);
563
+ if (!tldRes.ok) return tldRes;
564
+ const tld = tldRes.value;
565
+ const normalized = normalizeDotNsName(name, tld.suffix);
566
+ if (!isValidDotNsName(normalized, tld.suffix)) {
567
+ return err(nameError(name, normalized, tld));
568
+ }
569
+ const label = stripSuffix(normalized, tld.suffix);
570
+ const addrs = await resolveDotNsAddresses(opts);
571
+ if (!addrs.ok) return addrs;
572
+ const controllerAddr = addrs.value.registrarController;
573
+ log.debug("isDotNsAvailable", { name: normalized, label, controller: controllerAddr });
574
+ try {
575
+ const controller = contractOf(
576
+ opts.runtime,
577
+ controllerAddr,
578
+ DOTNS_REGISTRAR_CONTROLLER_ABI
579
+ );
580
+ const popRules = contractOf(opts.runtime, addrs.value.popRules, DOTNS_POP_RULES_ABI);
581
+ const origin = readOrigin(opts);
582
+ const [res, classified] = await Promise.all([
583
+ controller.available.query(label, { origin }),
584
+ popRules.classifyName.query(label, { origin })
585
+ ]);
586
+ if (!res.success) {
587
+ return err(
588
+ new DotNsError("RegistryCall", "registrarController.available call failed", {
589
+ cause: res.value
590
+ })
591
+ );
592
+ }
593
+ if (res.value !== true) return ok(false);
594
+ if (!classified.success) {
595
+ return err(
596
+ new DotNsError("RegistryCall", "PopRules.classifyName call failed", {
597
+ cause: classified.value
598
+ })
599
+ );
600
+ }
601
+ const { requirement } = classified.value;
602
+ return ok(requirement !== POP_STATUS.Reserved);
603
+ } catch (cause) {
604
+ return err(
605
+ new DotNsError("RegistryCall", `DotNS availability check failed for "${normalized}"`, {
606
+ cause
607
+ })
608
+ );
609
+ }
610
+ }
611
+ async function setDotNsRecord(args, opts) {
612
+ const tldRes = await resolveTld(opts);
613
+ if (!tldRes.ok) return tldRes;
614
+ const tld = tldRes.value;
615
+ const normalized = normalizeDotNsName(args.name, tld.suffix);
616
+ if (!isResolvableDotNsName(normalized, tld.suffix)) {
617
+ return err(nameError(args.name, normalized, tld));
618
+ }
619
+ const origin = opts.origin;
620
+ if (!origin) {
621
+ return err(new DotNsError("MissingOrigin", "setDotNsRecord needs opts.origin (SS58)"));
622
+ }
623
+ const node = namehash(normalized, tld);
624
+ const addrs = await resolveDotNsAddresses(opts);
625
+ if (!addrs.ok) return addrs;
626
+ const registryAddr = addrs.value.registry;
627
+ const resolverAddr = addrs.value.resolver;
628
+ try {
629
+ const registry = contractOf(opts.runtime, registryAddr, DOTNS_REGISTRY_ABI);
630
+ const currentRes = await registry.resolver.query(node, { origin });
631
+ if (!currentRes.success) {
632
+ return err(
633
+ new DotNsError("RegistryCall", "registry.resolver call failed", {
634
+ cause: currentRes.value
635
+ })
636
+ );
637
+ }
638
+ const calls = [];
639
+ if (!sameAddress(currentRes.value, resolverAddr)) {
640
+ const pointer = await registry.setResolver.prepare(node, resolverAddr, { origin });
641
+ if (!pointer.ok) {
642
+ return err(
643
+ new DotNsError("RegistryCall", "registry.setResolver prepare failed", {
644
+ cause: pointer.error
645
+ })
646
+ );
647
+ }
648
+ calls.push(pointer.value);
649
+ }
650
+ const resolver = contractOf(
651
+ opts.runtime,
652
+ resolverAddr,
653
+ DOTNS_RESOLVER_WRITE_ABI
654
+ );
655
+ const prepared = await resolver.setAddress.prepare(node, args.address, { origin });
656
+ if (!prepared.ok) {
657
+ return err(
658
+ new DotNsError("RegistryCall", "resolver.setAddress prepare failed", {
659
+ cause: prepared.error
660
+ })
661
+ );
662
+ }
663
+ calls.push(prepared.value);
664
+ return ok(calls);
665
+ } catch (cause) {
666
+ return err(new DotNsError("RegistryCall", "DotNS setRecord failed", { cause }));
667
+ }
668
+ }
669
+ async function quoteRegistration(popRules, label, owner, payer, origin) {
670
+ const quote = await popRules.priceWithoutCheck.query(label, owner, { origin });
671
+ if (!quote.success) {
672
+ return err(
673
+ new DotNsError("RegistryCall", "PopRules.priceWithoutCheck failed", {
674
+ cause: quote.value
675
+ })
676
+ );
677
+ }
678
+ const { price, status, userStatus, message } = quote.value;
679
+ if (status === POP_STATUS.Reserved) {
680
+ return err(new DotNsError("NameReserved", `"${label}" is reserved: ${message}`));
681
+ }
682
+ if (userStatus < status) {
683
+ return err(
684
+ new DotNsError(
685
+ "OwnerStatusInsufficient",
686
+ `"${label}" requires personhood tier ${status}, owner has ${userStatus}: ${message}`
687
+ )
688
+ );
689
+ }
690
+ if (sameAddress(payer, owner)) return ok(BigInt(price));
691
+ const floor = await popRules.transferFloor.query(label, payer, owner, { origin });
692
+ if (!floor.success) {
693
+ return err(
694
+ new DotNsError("RegistryCall", "PopRules.transferFloor failed", {
695
+ cause: floor.value
696
+ })
697
+ );
698
+ }
699
+ const friction = BigInt(floor.value);
700
+ const base = BigInt(price);
701
+ return ok(base > friction ? base : friction);
702
+ }
703
+ async function prepareDotNsRegistration(args, opts) {
704
+ const tldRes = await resolveTld(opts);
705
+ if (!tldRes.ok) return tldRes;
706
+ const tld = tldRes.value;
707
+ const normalized = normalizeDotNsName(args.name, tld.suffix);
708
+ if (!isValidDotNsName(normalized, tld.suffix)) {
709
+ return err(nameError(args.name, normalized, tld));
710
+ }
711
+ const origin = opts.origin;
712
+ if (!origin) {
713
+ return err(
714
+ new DotNsError("MissingOrigin", "prepareDotNsRegistration needs opts.origin (SS58)")
715
+ );
716
+ }
717
+ const label = stripSuffix(normalized, tld.suffix);
718
+ const addrs = await resolveDotNsAddresses(opts);
719
+ if (!addrs.ok) return addrs;
720
+ const controllerAddr = addrs.value.registrarController;
721
+ const popRulesAddr = addrs.value.popRules;
722
+ const secret = `0x${bytesToHex(randomBytes(32))}`;
723
+ const registration = { label, owner: args.owner, secret, reserved: args.reserved ?? false };
724
+ let payer;
725
+ try {
726
+ payer = ss58ToH160(origin);
727
+ } catch (cause) {
728
+ return err(
729
+ new DotNsError("InvalidOrigin", `opts.origin is not a valid SS58 address: ${origin}`, {
730
+ cause
731
+ })
732
+ );
733
+ }
734
+ try {
735
+ const controller = contractOf(
736
+ opts.runtime,
737
+ controllerAddr,
738
+ DOTNS_REGISTRAR_CONTROLLER_ABI
739
+ );
740
+ const popRules = contractOf(opts.runtime, popRulesAddr, DOTNS_POP_RULES_ABI);
741
+ const [commitmentRes, availableRes, quote, minRes, maxRes] = await Promise.all([
742
+ controller.makeCommitment.query(registration, { origin }),
743
+ controller.available.query(label, { origin }),
744
+ quoteRegistration(popRules, label, args.owner, payer, origin),
745
+ controller.minCommitmentAge.query({ origin }),
746
+ controller.maxCommitmentAge.query({ origin })
747
+ ]);
748
+ if (!availableRes.success) {
749
+ return err(
750
+ new DotNsError("RegistryCall", "registrarController.available call failed", {
751
+ cause: availableRes.value
752
+ })
753
+ );
754
+ }
755
+ if (availableRes.value !== true) {
756
+ return err(new DotNsError("NameUnavailable", `"${label}" is already registered`));
757
+ }
758
+ if (!commitmentRes.success) {
759
+ return err(
760
+ new DotNsError("RegistryCall", "makeCommitment failed", {
761
+ cause: commitmentRes.value
762
+ })
763
+ );
764
+ }
765
+ if (!quote.ok) return quote;
766
+ if (!minRes.success || !maxRes.success) {
767
+ return err(
768
+ new DotNsError("RegistryCall", "commitment window read failed", {
769
+ cause: minRes.success ? maxRes.value : minRes.value
770
+ })
771
+ );
772
+ }
773
+ const commitment = commitmentRes.value;
774
+ const commitPrep = await controller.commit.prepare(commitment, { origin });
775
+ if (!commitPrep.ok) {
776
+ return err(
777
+ new DotNsError("RegistryCall", "controller.commit prepare failed", {
778
+ cause: commitPrep.error
779
+ })
780
+ );
36
781
  }
37
- return true;
38
- } catch {
39
- return false;
782
+ return ok({
783
+ secret,
784
+ commitment,
785
+ commitCall: commitPrep.value,
786
+ minCommitmentAge: BigInt(minRes.value),
787
+ maxCommitmentAge: BigInt(maxRes.value),
788
+ price: quote.value,
789
+ prepareRegisterCall: async () => {
790
+ const current = await quoteRegistration(popRules, label, args.owner, payer, origin);
791
+ if (!current.ok) return current;
792
+ const prep = await controller.register.prepare(registration, {
793
+ value: current.value,
794
+ origin
795
+ });
796
+ if (!prep.ok) {
797
+ return err(
798
+ new DotNsError("RegistryCall", "controller.register prepare failed", {
799
+ cause: prep.error
800
+ })
801
+ );
802
+ }
803
+ return ok(prep.value);
804
+ }
805
+ });
806
+ } catch (cause) {
807
+ return err(new DotNsError("RegistryCall", "DotNS registration prepare failed", { cause }));
40
808
  }
41
809
  }
42
810
 
43
- export { deriveContextAlias, verifyContextAlias };
811
+ export { DOTNS_ADDRESSES, DOTNS_REGISTRY_KEYS, DotNsError, POP_STATUS, discoverDotNsAddresses, isDotNsAvailable, prepareDotNsRegistration, resolveDotNs, resolveDotNsAddresses, reverseDotNs, setDotNsRecord, verifyDotNsAddresses };
44
812
  //# sourceMappingURL=index.js.map
45
813
  //# sourceMappingURL=index.js.map