@parity/product-sdk 0.0.0-dev.312.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/dist/address/index.d.ts +9 -0
- package/dist/address/index.js +3 -0
- package/dist/address/index.js.map +1 -0
- package/dist/chain/index.d.ts +1 -0
- package/dist/chain/index.js +3 -0
- package/dist/chain/index.js.map +1 -0
- package/dist/chunk-BRZNHTLQ.js +89 -0
- package/dist/chunk-BRZNHTLQ.js.map +1 -0
- package/dist/chunk-DHRCWMY5.js +240 -0
- package/dist/chunk-DHRCWMY5.js.map +1 -0
- package/dist/chunk-JVJ552RU.js +3 -0
- package/dist/chunk-JVJ552RU.js.map +1 -0
- package/dist/cloud-storage/index.d.ts +1 -0
- package/dist/cloud-storage/index.js +3 -0
- package/dist/cloud-storage/index.js.map +1 -0
- package/dist/contracts/index.d.ts +1 -0
- package/dist/contracts/index.js +3 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/core/index.d.ts +12 -0
- package/dist/core/index.js +5 -0
- package/dist/core/index.js.map +1 -0
- package/dist/crypto/index.d.ts +1 -0
- package/dist/crypto/index.js +3 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/dotns-bswWAmR2.d.ts +136 -0
- package/dist/host/index.d.ts +1 -0
- package/dist/host/index.js +3 -0
- package/dist/host/index.js.map +1 -0
- package/dist/identity/index.d.ts +491 -0
- package/dist/identity/index.js +691 -0
- package/dist/identity/index.js.map +1 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/individuality/index.d.ts +1 -0
- package/dist/individuality/index.js +3 -0
- package/dist/individuality/index.js.map +1 -0
- package/dist/local-storage/index.d.ts +1 -0
- package/dist/local-storage/index.js +3 -0
- package/dist/local-storage/index.js.map +1 -0
- package/dist/react/index.d.ts +181 -0
- package/dist/react/index.js +198 -0
- package/dist/react/index.js.map +1 -0
- package/dist/testing/index.d.ts +61 -0
- package/dist/testing/index.js +149 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/types-B5Zx4RNq.d.ts +211 -0
- package/dist/wallet/index.d.ts +1 -0
- package/dist/wallet/index.js +3 -0
- package/dist/wallet/index.js.map +1 -0
- package/package.json +118 -0
- package/src/address/index.ts +8 -0
- package/src/chain/index.ts +8 -0
- package/src/cloud-storage/index.ts +8 -0
- package/src/contracts/index.ts +8 -0
- package/src/core/createApp.ts +408 -0
- package/src/core/index.ts +12 -0
- package/src/core/logger.ts +15 -0
- package/src/core/types.ts +233 -0
- package/src/crypto/index.ts +8 -0
- package/src/host/index.ts +8 -0
- package/src/identity/dotns-abis.test.ts +43 -0
- package/src/identity/dotns-abis.ts +274 -0
- package/src/identity/dotns-errors.ts +34 -0
- package/src/identity/dotns-namehash.test.ts +155 -0
- package/src/identity/dotns-namehash.ts +149 -0
- package/src/identity/dotns-owner.test.ts +92 -0
- package/src/identity/dotns-registry.test.ts +1154 -0
- package/src/identity/dotns-registry.ts +870 -0
- package/src/identity/dotns.test.ts +128 -0
- package/src/identity/dotns.ts +221 -0
- package/src/identity/index.ts +61 -0
- package/src/identity/product-account.test.ts +130 -0
- package/src/identity/product-account.ts +115 -0
- package/src/identity/types.ts +87 -0
- package/src/index.ts +61 -0
- package/src/individuality/contract.test.ts +135 -0
- package/src/individuality/index.ts +8 -0
- package/src/local-storage/index.ts +8 -0
- package/src/react/context.ts +35 -0
- package/src/react/index.ts +43 -0
- package/src/react/provider.tsx +78 -0
- package/src/react/useChain.ts +35 -0
- package/src/react/useLocalStorage.ts +127 -0
- package/src/react/useWallet.ts +156 -0
- package/src/testing.ts +297 -0
- package/src/wallet/index.ts +11 -0
|
@@ -0,0 +1,691 @@
|
|
|
1
|
+
import { normalizeDotNsName, isResolvableDotNsName, namehash, isValidDotNsName, stripSuffix, isConsistentDotNsTld, DOT_TLD, dotNsTld } from '../chunk-BRZNHTLQ.js';
|
|
2
|
+
export { DOT_NODE, DOT_TLD, accountIdHexToBytes, accountIdToHex, dotNsTld, isConsistentDotNsTld, isResolvableDotNsName, isValidDotNsName, namehash, normalizeDotNsName, resolvePeopleUsernameOwner, stripSuffix } from '../chunk-BRZNHTLQ.js';
|
|
3
|
+
import { err, ok } from '@parity/result';
|
|
4
|
+
import { QUERY_FALLBACK_ORIGIN, createContract } from '@parity/product-sdk-contracts';
|
|
5
|
+
import { bytesToHex, randomBytes, blake2b256 } from '@parity/product-sdk-crypto';
|
|
6
|
+
import { ss58ToH160, ss58Decode, ss58Encode, deriveH160 } from '@parity/product-sdk-address';
|
|
7
|
+
import { createLogger } from '@parity/product-sdk-logger';
|
|
8
|
+
|
|
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
|
+
var POP_STATUS = { NoStatus: 0, PopLite: 1, PopFull: 2, Reserved: 3 };
|
|
200
|
+
var DOTNS_ADDRESSES = {
|
|
201
|
+
registry: "0xf34054fd76BbF85f216cf9908226D5f0A72E50CA",
|
|
202
|
+
reverseResolver: "0xee3883d7eB60Ee9BCD7F3bcD8f2f05302A9Cc035",
|
|
203
|
+
resolver: "0xbd1165E549DF96F083c0A16f61590927bC187009",
|
|
204
|
+
registrarController: "0xBdaA01bD1bA67d709F2b1fF286Da0d854977EA30",
|
|
205
|
+
popRules: "0x747B456bE03aec0b42bd85C51513730FBD45DA31",
|
|
206
|
+
protocolRegistry: "0xD19e3D0C97CF501125a04A97405e3e6592fa846E"
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// src/identity/dotns-errors.ts
|
|
210
|
+
var DotNsError = class extends Error {
|
|
211
|
+
isSdkError = true;
|
|
212
|
+
source = "dotns";
|
|
213
|
+
reason;
|
|
214
|
+
constructor(reason, message, options) {
|
|
215
|
+
super(message, options);
|
|
216
|
+
this.name = "DotNsError";
|
|
217
|
+
this.reason = reason;
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
// src/identity/dotns-registry.ts
|
|
222
|
+
var log = createLogger("identity:dotns");
|
|
223
|
+
var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
224
|
+
function contractOf(runtime, address, abi) {
|
|
225
|
+
return createContract(runtime, address, abi);
|
|
226
|
+
}
|
|
227
|
+
function isZero(addr) {
|
|
228
|
+
return typeof addr === "string" && addr.toLowerCase() === ZERO_ADDRESS;
|
|
229
|
+
}
|
|
230
|
+
function readOrigin(opts) {
|
|
231
|
+
return opts.origin ?? QUERY_FALLBACK_ORIGIN;
|
|
232
|
+
}
|
|
233
|
+
function sameAddress(a, b) {
|
|
234
|
+
return typeof a === "string" && typeof b === "string" && a.toLowerCase() === b.toLowerCase();
|
|
235
|
+
}
|
|
236
|
+
var tldCache = /* @__PURE__ */ new WeakMap();
|
|
237
|
+
function isEmptyRevert(value) {
|
|
238
|
+
return typeof value === "object" && value !== null && value.type === "ContractRevertedWithPayload" && value.data === "0x";
|
|
239
|
+
}
|
|
240
|
+
async function resolveTld(opts) {
|
|
241
|
+
if (opts.tld) {
|
|
242
|
+
return isConsistentDotNsTld(opts.tld) ? ok(opts.tld) : err(
|
|
243
|
+
new DotNsError(
|
|
244
|
+
"InvalidTld",
|
|
245
|
+
`opts.tld is inconsistent: "${opts.tld.suffix}" does not hash to ${opts.tld.node}`
|
|
246
|
+
)
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
const address = opts.protocolRegistryAddress ?? DOTNS_ADDRESSES.protocolRegistry;
|
|
250
|
+
let perAddress = tldCache.get(opts.runtime);
|
|
251
|
+
if (!perAddress) {
|
|
252
|
+
perAddress = /* @__PURE__ */ new Map();
|
|
253
|
+
tldCache.set(opts.runtime, perAddress);
|
|
254
|
+
}
|
|
255
|
+
const cached = perAddress.get(address);
|
|
256
|
+
if (cached) return cached;
|
|
257
|
+
const pending = readTld(opts, address);
|
|
258
|
+
perAddress.set(address, pending);
|
|
259
|
+
pending.then((result) => {
|
|
260
|
+
if (!result.ok) perAddress?.delete(address);
|
|
261
|
+
});
|
|
262
|
+
return pending;
|
|
263
|
+
}
|
|
264
|
+
async function readTld(opts, address) {
|
|
265
|
+
try {
|
|
266
|
+
const registry = contractOf(opts.runtime, address, DOTNS_PROTOCOL_REGISTRY_ABI);
|
|
267
|
+
const origin = readOrigin(opts);
|
|
268
|
+
const suffixRes = await registry.tld.query({ origin });
|
|
269
|
+
if (!suffixRes.success) {
|
|
270
|
+
if (isEmptyRevert(suffixRes.value)) {
|
|
271
|
+
log.warn(
|
|
272
|
+
"DotNS protocol registry has no tld() getter; treating this as a pre-b4096968 deployment, whose TLD was the compile-time .dot",
|
|
273
|
+
{ protocolRegistry: address }
|
|
274
|
+
);
|
|
275
|
+
return ok(DOT_TLD);
|
|
276
|
+
}
|
|
277
|
+
return err(
|
|
278
|
+
new DotNsError("RegistryCall", "protocolRegistry.tld call failed", {
|
|
279
|
+
cause: suffixRes.value
|
|
280
|
+
})
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
const suffix = suffixRes.value;
|
|
284
|
+
const tld = dotNsTld(suffix);
|
|
285
|
+
if (!isConsistentDotNsTld(tld)) {
|
|
286
|
+
return err(
|
|
287
|
+
new DotNsError(
|
|
288
|
+
"InvalidTld",
|
|
289
|
+
`protocolRegistry.tld returned an unusable TLD: ${JSON.stringify(suffix)}`
|
|
290
|
+
)
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
const nodeRes = await registry.tldNode.query({ origin });
|
|
294
|
+
if (nodeRes.success && isNode(nodeRes.value) && !sameNode(nodeRes.value, tld.node)) {
|
|
295
|
+
return err(
|
|
296
|
+
new DotNsError(
|
|
297
|
+
"InvalidTld",
|
|
298
|
+
`protocolRegistry disagrees with itself: tld() ${suffix} derives ${tld.node} but tldNode() reports ${String(nodeRes.value)}`
|
|
299
|
+
)
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
log.debug("resolveTld", { protocolRegistry: address, suffix: tld.suffix, node: tld.node });
|
|
303
|
+
return ok(tld);
|
|
304
|
+
} catch (cause) {
|
|
305
|
+
return err(new DotNsError("RegistryCall", "DotNS TLD read failed", { cause }));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
function nameError(input, normalized, tld) {
|
|
309
|
+
if (!normalized.endsWith(tld.suffix)) {
|
|
310
|
+
return new DotNsError(
|
|
311
|
+
"TldMismatch",
|
|
312
|
+
`DotNS name "${input}" is not on this deployment, which uses "${tld.suffix}"`
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
return new DotNsError("InvalidName", `Invalid DotNS name: "${input}"`);
|
|
316
|
+
}
|
|
317
|
+
function isNode(value) {
|
|
318
|
+
return typeof value === "string" && /^0x[0-9a-fA-F]{64}$/.test(value);
|
|
319
|
+
}
|
|
320
|
+
function sameNode(a, b) {
|
|
321
|
+
return a.toLowerCase() === b.toLowerCase();
|
|
322
|
+
}
|
|
323
|
+
async function resolveDotNs(name, opts) {
|
|
324
|
+
const tldRes = await resolveTld(opts);
|
|
325
|
+
if (!tldRes.ok) return tldRes;
|
|
326
|
+
const tld = tldRes.value;
|
|
327
|
+
const normalized = normalizeDotNsName(name, tld.suffix);
|
|
328
|
+
if (!isResolvableDotNsName(normalized, tld.suffix)) {
|
|
329
|
+
return err(nameError(name, normalized, tld));
|
|
330
|
+
}
|
|
331
|
+
const node = namehash(normalized, tld);
|
|
332
|
+
const registryAddr = opts.registryAddress ?? DOTNS_ADDRESSES.registry;
|
|
333
|
+
const origin = readOrigin(opts);
|
|
334
|
+
log.debug("resolveDotNs", { name: normalized, node, registry: registryAddr });
|
|
335
|
+
try {
|
|
336
|
+
const registry = contractOf(opts.runtime, registryAddr, DOTNS_REGISTRY_ABI);
|
|
337
|
+
const [ownerRes, resolverRes] = await Promise.all([
|
|
338
|
+
registry.owner.query(node, { origin }),
|
|
339
|
+
registry.resolver.query(node, { origin })
|
|
340
|
+
]);
|
|
341
|
+
if (!ownerRes.success) {
|
|
342
|
+
return err(
|
|
343
|
+
new DotNsError("RegistryCall", "registry.owner call failed", {
|
|
344
|
+
cause: ownerRes.value
|
|
345
|
+
})
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
if (!resolverRes.success) {
|
|
349
|
+
return err(
|
|
350
|
+
new DotNsError("RegistryCall", "registry.resolver call failed", {
|
|
351
|
+
cause: resolverRes.value
|
|
352
|
+
})
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
const owner = ownerRes.value;
|
|
356
|
+
if (isZero(owner)) return ok(null);
|
|
357
|
+
const resolverAddr = resolverRes.value;
|
|
358
|
+
const forwardAddr = opts.resolverAddress ?? DOTNS_ADDRESSES.resolver;
|
|
359
|
+
if (!sameAddress(resolverAddr, forwardAddr)) {
|
|
360
|
+
return ok({ name: normalized, owner });
|
|
361
|
+
}
|
|
362
|
+
const resolver = contractOf(opts.runtime, resolverAddr, DOTNS_RESOLVER_ABI);
|
|
363
|
+
const addrRes = await resolver.addressOf.query(node, { origin });
|
|
364
|
+
if (!addrRes.success) {
|
|
365
|
+
return err(
|
|
366
|
+
new DotNsError("RegistryCall", "resolver.addressOf call failed", {
|
|
367
|
+
cause: addrRes.value
|
|
368
|
+
})
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
const address = addrRes.value;
|
|
372
|
+
if (isZero(address)) return ok({ name: normalized, owner });
|
|
373
|
+
return ok({ address, name: normalized, owner });
|
|
374
|
+
} catch (cause) {
|
|
375
|
+
return err(
|
|
376
|
+
new DotNsError("RegistryCall", `DotNS resolve failed for "${normalized}"`, { cause })
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
async function reverseDotNs(address, opts) {
|
|
381
|
+
const reverseAddr = opts.reverseResolverAddress ?? DOTNS_ADDRESSES.reverseResolver;
|
|
382
|
+
log.debug("reverseDotNs", { address, reverseResolver: reverseAddr });
|
|
383
|
+
try {
|
|
384
|
+
const reverse = contractOf(
|
|
385
|
+
opts.runtime,
|
|
386
|
+
reverseAddr,
|
|
387
|
+
DOTNS_REVERSE_RESOLVER_ABI
|
|
388
|
+
);
|
|
389
|
+
const res = await reverse.nameOf.query(address, { origin: readOrigin(opts) });
|
|
390
|
+
if (!res.success) {
|
|
391
|
+
return err(
|
|
392
|
+
new DotNsError("RegistryCall", "reverseResolver.nameOf call failed", {
|
|
393
|
+
cause: res.value
|
|
394
|
+
})
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
const name = res.value;
|
|
398
|
+
return ok(name && name.length > 0 ? name : null);
|
|
399
|
+
} catch (cause) {
|
|
400
|
+
return err(
|
|
401
|
+
new DotNsError("RegistryCall", `DotNS reverse failed for "${address}"`, { cause })
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
async function isDotNsAvailable(name, opts) {
|
|
406
|
+
const tldRes = await resolveTld(opts);
|
|
407
|
+
if (!tldRes.ok) return tldRes;
|
|
408
|
+
const tld = tldRes.value;
|
|
409
|
+
const normalized = normalizeDotNsName(name, tld.suffix);
|
|
410
|
+
if (!isValidDotNsName(normalized, tld.suffix)) {
|
|
411
|
+
return err(nameError(name, normalized, tld));
|
|
412
|
+
}
|
|
413
|
+
const label = stripSuffix(normalized, tld.suffix);
|
|
414
|
+
const controllerAddr = opts.registrarControllerAddress ?? DOTNS_ADDRESSES.registrarController;
|
|
415
|
+
log.debug("isDotNsAvailable", { name: normalized, label, controller: controllerAddr });
|
|
416
|
+
try {
|
|
417
|
+
const controller = contractOf(
|
|
418
|
+
opts.runtime,
|
|
419
|
+
controllerAddr,
|
|
420
|
+
DOTNS_REGISTRAR_CONTROLLER_ABI
|
|
421
|
+
);
|
|
422
|
+
const popRules = contractOf(
|
|
423
|
+
opts.runtime,
|
|
424
|
+
opts.popRulesAddress ?? DOTNS_ADDRESSES.popRules,
|
|
425
|
+
DOTNS_POP_RULES_ABI
|
|
426
|
+
);
|
|
427
|
+
const origin = readOrigin(opts);
|
|
428
|
+
const [res, classified] = await Promise.all([
|
|
429
|
+
controller.available.query(label, { origin }),
|
|
430
|
+
popRules.classifyName.query(label, { origin })
|
|
431
|
+
]);
|
|
432
|
+
if (!res.success) {
|
|
433
|
+
return err(
|
|
434
|
+
new DotNsError("RegistryCall", "registrarController.available call failed", {
|
|
435
|
+
cause: res.value
|
|
436
|
+
})
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
if (res.value !== true) return ok(false);
|
|
440
|
+
if (!classified.success) {
|
|
441
|
+
return err(
|
|
442
|
+
new DotNsError("RegistryCall", "PopRules.classifyName call failed", {
|
|
443
|
+
cause: classified.value
|
|
444
|
+
})
|
|
445
|
+
);
|
|
446
|
+
}
|
|
447
|
+
const { requirement } = classified.value;
|
|
448
|
+
return ok(requirement !== POP_STATUS.Reserved);
|
|
449
|
+
} catch (cause) {
|
|
450
|
+
return err(
|
|
451
|
+
new DotNsError("RegistryCall", `DotNS availability check failed for "${normalized}"`, {
|
|
452
|
+
cause
|
|
453
|
+
})
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
async function setDotNsRecord(args, opts) {
|
|
458
|
+
const tldRes = await resolveTld(opts);
|
|
459
|
+
if (!tldRes.ok) return tldRes;
|
|
460
|
+
const tld = tldRes.value;
|
|
461
|
+
const normalized = normalizeDotNsName(args.name, tld.suffix);
|
|
462
|
+
if (!isResolvableDotNsName(normalized, tld.suffix)) {
|
|
463
|
+
return err(nameError(args.name, normalized, tld));
|
|
464
|
+
}
|
|
465
|
+
const origin = opts.origin;
|
|
466
|
+
if (!origin) {
|
|
467
|
+
return err(new DotNsError("MissingOrigin", "setDotNsRecord needs opts.origin (SS58)"));
|
|
468
|
+
}
|
|
469
|
+
const node = namehash(normalized, tld);
|
|
470
|
+
const registryAddr = opts.registryAddress ?? DOTNS_ADDRESSES.registry;
|
|
471
|
+
const resolverAddr = opts.resolverAddress ?? DOTNS_ADDRESSES.resolver;
|
|
472
|
+
try {
|
|
473
|
+
const registry = contractOf(opts.runtime, registryAddr, DOTNS_REGISTRY_ABI);
|
|
474
|
+
const currentRes = await registry.resolver.query(node, { origin });
|
|
475
|
+
if (!currentRes.success) {
|
|
476
|
+
return err(
|
|
477
|
+
new DotNsError("RegistryCall", "registry.resolver call failed", {
|
|
478
|
+
cause: currentRes.value
|
|
479
|
+
})
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
const calls = [];
|
|
483
|
+
if (!sameAddress(currentRes.value, resolverAddr)) {
|
|
484
|
+
const pointer = await registry.setResolver.prepare(node, resolverAddr, { origin });
|
|
485
|
+
if (!pointer.ok) {
|
|
486
|
+
return err(
|
|
487
|
+
new DotNsError("RegistryCall", "registry.setResolver prepare failed", {
|
|
488
|
+
cause: pointer.error
|
|
489
|
+
})
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
calls.push(pointer.value);
|
|
493
|
+
}
|
|
494
|
+
const resolver = contractOf(
|
|
495
|
+
opts.runtime,
|
|
496
|
+
resolverAddr,
|
|
497
|
+
DOTNS_RESOLVER_WRITE_ABI
|
|
498
|
+
);
|
|
499
|
+
const prepared = await resolver.setAddress.prepare(node, args.address, { origin });
|
|
500
|
+
if (!prepared.ok) {
|
|
501
|
+
return err(
|
|
502
|
+
new DotNsError("RegistryCall", "resolver.setAddress prepare failed", {
|
|
503
|
+
cause: prepared.error
|
|
504
|
+
})
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
calls.push(prepared.value);
|
|
508
|
+
return ok(calls);
|
|
509
|
+
} catch (cause) {
|
|
510
|
+
return err(new DotNsError("RegistryCall", "DotNS setRecord failed", { cause }));
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
async function quoteRegistration(popRules, label, owner, payer, origin) {
|
|
514
|
+
const quote = await popRules.priceWithoutCheck.query(label, owner, { origin });
|
|
515
|
+
if (!quote.success) {
|
|
516
|
+
return err(
|
|
517
|
+
new DotNsError("RegistryCall", "PopRules.priceWithoutCheck failed", {
|
|
518
|
+
cause: quote.value
|
|
519
|
+
})
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
const { price, status, userStatus, message } = quote.value;
|
|
523
|
+
if (status === POP_STATUS.Reserved) {
|
|
524
|
+
return err(new DotNsError("NameReserved", `"${label}" is reserved: ${message}`));
|
|
525
|
+
}
|
|
526
|
+
if (userStatus < status) {
|
|
527
|
+
return err(
|
|
528
|
+
new DotNsError(
|
|
529
|
+
"OwnerStatusInsufficient",
|
|
530
|
+
`"${label}" requires personhood tier ${status}, owner has ${userStatus}: ${message}`
|
|
531
|
+
)
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
if (sameAddress(payer, owner)) return ok(BigInt(price));
|
|
535
|
+
const floor = await popRules.transferFloor.query(label, payer, owner, { origin });
|
|
536
|
+
if (!floor.success) {
|
|
537
|
+
return err(
|
|
538
|
+
new DotNsError("RegistryCall", "PopRules.transferFloor failed", {
|
|
539
|
+
cause: floor.value
|
|
540
|
+
})
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
const friction = BigInt(floor.value);
|
|
544
|
+
const base = BigInt(price);
|
|
545
|
+
return ok(base > friction ? base : friction);
|
|
546
|
+
}
|
|
547
|
+
async function prepareDotNsRegistration(args, opts) {
|
|
548
|
+
const tldRes = await resolveTld(opts);
|
|
549
|
+
if (!tldRes.ok) return tldRes;
|
|
550
|
+
const tld = tldRes.value;
|
|
551
|
+
const normalized = normalizeDotNsName(args.name, tld.suffix);
|
|
552
|
+
if (!isValidDotNsName(normalized, tld.suffix)) {
|
|
553
|
+
return err(nameError(args.name, normalized, tld));
|
|
554
|
+
}
|
|
555
|
+
const origin = opts.origin;
|
|
556
|
+
if (!origin) {
|
|
557
|
+
return err(
|
|
558
|
+
new DotNsError("MissingOrigin", "prepareDotNsRegistration needs opts.origin (SS58)")
|
|
559
|
+
);
|
|
560
|
+
}
|
|
561
|
+
const label = stripSuffix(normalized, tld.suffix);
|
|
562
|
+
const controllerAddr = opts.registrarControllerAddress ?? DOTNS_ADDRESSES.registrarController;
|
|
563
|
+
const popRulesAddr = opts.popRulesAddress ?? DOTNS_ADDRESSES.popRules;
|
|
564
|
+
const secret = `0x${bytesToHex(randomBytes(32))}`;
|
|
565
|
+
const registration = { label, owner: args.owner, secret, reserved: args.reserved ?? false };
|
|
566
|
+
let payer;
|
|
567
|
+
try {
|
|
568
|
+
payer = ss58ToH160(origin);
|
|
569
|
+
} catch (cause) {
|
|
570
|
+
return err(
|
|
571
|
+
new DotNsError("InvalidOrigin", `opts.origin is not a valid SS58 address: ${origin}`, {
|
|
572
|
+
cause
|
|
573
|
+
})
|
|
574
|
+
);
|
|
575
|
+
}
|
|
576
|
+
try {
|
|
577
|
+
const controller = contractOf(
|
|
578
|
+
opts.runtime,
|
|
579
|
+
controllerAddr,
|
|
580
|
+
DOTNS_REGISTRAR_CONTROLLER_ABI
|
|
581
|
+
);
|
|
582
|
+
const popRules = contractOf(opts.runtime, popRulesAddr, DOTNS_POP_RULES_ABI);
|
|
583
|
+
const [commitmentRes, availableRes, quote, minRes, maxRes] = await Promise.all([
|
|
584
|
+
controller.makeCommitment.query(registration, { origin }),
|
|
585
|
+
controller.available.query(label, { origin }),
|
|
586
|
+
quoteRegistration(popRules, label, args.owner, payer, origin),
|
|
587
|
+
controller.minCommitmentAge.query({ origin }),
|
|
588
|
+
controller.maxCommitmentAge.query({ origin })
|
|
589
|
+
]);
|
|
590
|
+
if (!availableRes.success) {
|
|
591
|
+
return err(
|
|
592
|
+
new DotNsError("RegistryCall", "registrarController.available call failed", {
|
|
593
|
+
cause: availableRes.value
|
|
594
|
+
})
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
if (availableRes.value !== true) {
|
|
598
|
+
return err(new DotNsError("NameUnavailable", `"${label}" is already registered`));
|
|
599
|
+
}
|
|
600
|
+
if (!commitmentRes.success) {
|
|
601
|
+
return err(
|
|
602
|
+
new DotNsError("RegistryCall", "makeCommitment failed", {
|
|
603
|
+
cause: commitmentRes.value
|
|
604
|
+
})
|
|
605
|
+
);
|
|
606
|
+
}
|
|
607
|
+
if (!quote.ok) return quote;
|
|
608
|
+
if (!minRes.success || !maxRes.success) {
|
|
609
|
+
return err(
|
|
610
|
+
new DotNsError("RegistryCall", "commitment window read failed", {
|
|
611
|
+
cause: minRes.success ? maxRes.value : minRes.value
|
|
612
|
+
})
|
|
613
|
+
);
|
|
614
|
+
}
|
|
615
|
+
const commitment = commitmentRes.value;
|
|
616
|
+
const commitPrep = await controller.commit.prepare(commitment, { origin });
|
|
617
|
+
if (!commitPrep.ok) {
|
|
618
|
+
return err(
|
|
619
|
+
new DotNsError("RegistryCall", "controller.commit prepare failed", {
|
|
620
|
+
cause: commitPrep.error
|
|
621
|
+
})
|
|
622
|
+
);
|
|
623
|
+
}
|
|
624
|
+
return ok({
|
|
625
|
+
secret,
|
|
626
|
+
commitment,
|
|
627
|
+
commitCall: commitPrep.value,
|
|
628
|
+
minCommitmentAge: BigInt(minRes.value),
|
|
629
|
+
maxCommitmentAge: BigInt(maxRes.value),
|
|
630
|
+
price: quote.value,
|
|
631
|
+
prepareRegisterCall: async () => {
|
|
632
|
+
const current = await quoteRegistration(popRules, label, args.owner, payer, origin);
|
|
633
|
+
if (!current.ok) return current;
|
|
634
|
+
const prep = await controller.register.prepare(registration, {
|
|
635
|
+
value: current.value,
|
|
636
|
+
origin
|
|
637
|
+
});
|
|
638
|
+
if (!prep.ok) {
|
|
639
|
+
return err(
|
|
640
|
+
new DotNsError("RegistryCall", "controller.register prepare failed", {
|
|
641
|
+
cause: prep.error
|
|
642
|
+
})
|
|
643
|
+
);
|
|
644
|
+
}
|
|
645
|
+
return ok(prep.value);
|
|
646
|
+
}
|
|
647
|
+
});
|
|
648
|
+
} catch (cause) {
|
|
649
|
+
return err(new DotNsError("RegistryCall", "DotNS registration prepare failed", { cause }));
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
var log2 = createLogger("identity");
|
|
653
|
+
function deriveContextAlias(parentAddress, context, ss58Prefix = 42) {
|
|
654
|
+
const { publicKey: parentPublicKey } = ss58Decode(parentAddress);
|
|
655
|
+
const contextBytes = new TextEncoder().encode(context);
|
|
656
|
+
const combined = new Uint8Array(parentPublicKey.length + contextBytes.length);
|
|
657
|
+
combined.set(parentPublicKey, 0);
|
|
658
|
+
combined.set(contextBytes, parentPublicKey.length);
|
|
659
|
+
const aliasPublicKey = blake2b256(combined);
|
|
660
|
+
const address = ss58Encode(aliasPublicKey, ss58Prefix);
|
|
661
|
+
const h160Address = deriveH160(aliasPublicKey);
|
|
662
|
+
log2.debug("Derived context alias", {
|
|
663
|
+
parentAddress,
|
|
664
|
+
context,
|
|
665
|
+
address
|
|
666
|
+
});
|
|
667
|
+
return {
|
|
668
|
+
address,
|
|
669
|
+
h160Address,
|
|
670
|
+
parentAddress,
|
|
671
|
+
context
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
function verifyContextAlias(aliasAddress, parentAddress, context) {
|
|
675
|
+
try {
|
|
676
|
+
const derived = deriveContextAlias(parentAddress, context);
|
|
677
|
+
const { publicKey: aliasKey } = ss58Decode(aliasAddress);
|
|
678
|
+
const { publicKey: derivedKey } = ss58Decode(derived.address);
|
|
679
|
+
if (aliasKey.length !== derivedKey.length) return false;
|
|
680
|
+
for (let i = 0; i < aliasKey.length; i++) {
|
|
681
|
+
if (aliasKey[i] !== derivedKey[i]) return false;
|
|
682
|
+
}
|
|
683
|
+
return true;
|
|
684
|
+
} catch {
|
|
685
|
+
return false;
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
export { DOTNS_ADDRESSES, DotNsError, POP_STATUS, deriveContextAlias, isDotNsAvailable, prepareDotNsRegistration, resolveDotNs, reverseDotNs, setDotNsRecord, verifyContextAlias };
|
|
690
|
+
//# sourceMappingURL=index.js.map
|
|
691
|
+
//# sourceMappingURL=index.js.map
|