@parity/product-sdk 0.22.0 → 0.23.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/dist/chunk-BRZNHTLQ.js +89 -0
- package/dist/chunk-BRZNHTLQ.js.map +1 -0
- package/dist/{chunk-6BI66XUJ.js → chunk-DHRCWMY5.js} +9 -10
- package/dist/chunk-DHRCWMY5.js.map +1 -0
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +2 -2
- package/dist/dotns-bswWAmR2.d.ts +136 -0
- package/dist/identity/index.d.ts +502 -45
- package/dist/identity/index.js +800 -32
- package/dist/identity/index.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +2 -2
- package/dist/testing/index.d.ts +2 -2
- package/dist/{types-DTgyMIi0.d.ts → types-B5Zx4RNq.d.ts} +1 -1
- package/package.json +10 -10
- package/src/core/createApp.ts +10 -8
- package/src/identity/dotns-abis.test.ts +43 -0
- package/src/identity/dotns-abis.ts +309 -0
- package/src/identity/dotns-addresses.test.ts +536 -0
- package/src/identity/dotns-addresses.ts +320 -0
- package/src/identity/dotns-errors.ts +36 -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 +1309 -0
- package/src/identity/dotns-registry.ts +868 -0
- package/src/identity/dotns.test.ts +128 -0
- package/src/identity/dotns.ts +91 -78
- package/src/identity/index.test.ts +43 -0
- package/src/identity/index.ts +40 -10
- package/src/identity/types.ts +29 -25
- package/src/individuality/contract.test.ts +272 -2
- package/dist/chunk-6BI66XUJ.js.map +0 -1
- package/dist/chunk-BIKT6X54.js +0 -70
- package/dist/chunk-BIKT6X54.js.map +0 -1
- package/dist/dotns-DIaptENj.d.ts +0 -167
- package/src/identity/product-account.test.ts +0 -129
- package/src/identity/product-account.ts +0 -115
|
@@ -10,7 +10,16 @@
|
|
|
10
10
|
* it by construction.
|
|
11
11
|
*
|
|
12
12
|
* This file closes that gap: if a descriptor regeneration changes a key or a
|
|
13
|
-
* value type, `pnpm typecheck` fails here.
|
|
13
|
+
* value type, `pnpm typecheck` fails here. It guards both of that package's
|
|
14
|
+
* chain contracts, `IndividualityChain` for the personhood batch and
|
|
15
|
+
* `ConsumersChain` for the account to username read.
|
|
16
|
+
*
|
|
17
|
+
* **It checks the built `dist`, not the sibling's `src`.** The contracts resolve
|
|
18
|
+
* through `@parity/product-sdk-individuality`'s `types` field, so editing a
|
|
19
|
+
* contract and running this typecheck without rebuilding that package asserts
|
|
20
|
+
* against the previous build. Run `pnpm -r build` first, or the guard silently
|
|
21
|
+
* checks stale types. Verified 2026-08-19 by mutating a contract and watching
|
|
22
|
+
* the typecheck pass until the sibling was rebuilt.
|
|
14
23
|
*
|
|
15
24
|
* **It lives in the umbrella package deliberately.** Inside the individuality
|
|
16
25
|
* package the same assertion is vacuous, passing even against a contract that
|
|
@@ -22,7 +31,23 @@
|
|
|
22
31
|
* `@ts-expect-error` would report as unused and this file would fail.
|
|
23
32
|
*/
|
|
24
33
|
import type { getChainAPI } from "@parity/product-sdk-chain-client";
|
|
25
|
-
import type {
|
|
34
|
+
import type {
|
|
35
|
+
RingVRFProof as HostRingVRFProof,
|
|
36
|
+
VrfSignature as HostVrfSignature,
|
|
37
|
+
VrfTranscriptItem as HostVrfTranscriptItem,
|
|
38
|
+
} from "@parity/product-sdk-host";
|
|
39
|
+
import type {
|
|
40
|
+
AirdropChain,
|
|
41
|
+
ClaimChain,
|
|
42
|
+
ConsumersChain,
|
|
43
|
+
GameChain,
|
|
44
|
+
IndividualityChain,
|
|
45
|
+
PrizeStatusChain,
|
|
46
|
+
SignUpChain,
|
|
47
|
+
AccountVrfSignature,
|
|
48
|
+
VrfTranscriptItem as IndividualityVrfTranscriptItem,
|
|
49
|
+
RingVRFProof as AsPersonRingVRFProof,
|
|
50
|
+
} from "@parity/product-sdk-individuality";
|
|
26
51
|
import { expect, test } from "vitest";
|
|
27
52
|
|
|
28
53
|
// The false branch must be `false`, not `never`. `never` is assignable to
|
|
@@ -37,6 +62,29 @@ type DevnetClient = Awaited<ReturnType<typeof getChainAPI<"devnet">>>;
|
|
|
37
62
|
type PaseoSatisfiesContract = Assert<PaseoClient extends IndividualityChain ? true : false>;
|
|
38
63
|
type DevnetSatisfiesContract = Assert<DevnetClient extends IndividualityChain ? true : false>;
|
|
39
64
|
|
|
65
|
+
// `ConsumersChain` needs this more than the batch contract does: its value shape
|
|
66
|
+
// was derived from the pallet and the codegen rather than read off the emitted
|
|
67
|
+
// descriptor, so these two lines are what make that derivation a checked fact.
|
|
68
|
+
type PaseoSatisfiesConsumers = Assert<PaseoClient extends ConsumersChain ? true : false>;
|
|
69
|
+
type DevnetSatisfiesConsumers = Assert<DevnetClient extends ConsumersChain ? true : false>;
|
|
70
|
+
|
|
71
|
+
// Separate from the personhood contract: reading draws needs neither `Resources`
|
|
72
|
+
// nor `PeopleLite`. Both chains satisfy it, which is weaker than it looks — devnet's
|
|
73
|
+
// event-id base is 28 bytes to paseo's 27, and `SizedHex<N>` erases `N`, so only the
|
|
74
|
+
// length check in `airdrop-ids.ts` catches that.
|
|
75
|
+
type PaseoSatisfiesAirdropContract = Assert<PaseoClient extends AirdropChain ? true : false>;
|
|
76
|
+
type DevnetSatisfiesAirdropContract = Assert<DevnetClient extends AirdropChain ? true : false>;
|
|
77
|
+
|
|
78
|
+
// Same again for the current-game contract, which shares no entry with either of
|
|
79
|
+
// the other two — but paseo only, and that asymmetry is the point.
|
|
80
|
+
type PaseoSatisfiesGameContract = Assert<PaseoClient extends GameChain ? true : false>;
|
|
81
|
+
|
|
82
|
+
// Devnet's metadata predates the multi-airdrop game work — the 28-byte base above is
|
|
83
|
+
// one symptom, `game-types.ts` lists the rest — so the game surface is paseo-only.
|
|
84
|
+
// Asserted negatively on purpose: a devnet re-pin breaks this line, which is the
|
|
85
|
+
// prompt to flip it positive and check the read against it.
|
|
86
|
+
type DevnetPredatesTheGameContract = Assert<DevnetClient extends GameChain ? false : true>;
|
|
87
|
+
|
|
40
88
|
// Negative control, kept type-only so it emits no runtime code. If
|
|
41
89
|
// `IndividualityChain` ever stopped constraining, this flips to `false` and the
|
|
42
90
|
// file fails to typecheck, which is what keeps the assertions above honest.
|
|
@@ -48,6 +96,228 @@ type ClientWithoutIndividuality = {
|
|
|
48
96
|
type RejectsBogusClient = Assert<
|
|
49
97
|
ClientWithoutIndividuality extends IndividualityChain ? false : true
|
|
50
98
|
>;
|
|
99
|
+
type RejectsBogusAirdropClient = Assert<
|
|
100
|
+
ClientWithoutIndividuality extends AirdropChain ? false : true
|
|
101
|
+
>;
|
|
102
|
+
type RejectsBogusGameClient = Assert<ClientWithoutIndividuality extends GameChain ? false : true>;
|
|
103
|
+
|
|
104
|
+
// `Game.Game` being optional is what makes "between games" representable at all,
|
|
105
|
+
// and `GameIndex` / `GameSchedules` being `ValueQuery` is what lets the read treat
|
|
106
|
+
// them as always answering. The structural contract pins the latter two by typing
|
|
107
|
+
// them non-optional; this pins the first, which no assignability check would
|
|
108
|
+
// catch — a suddenly-required `Game` would still satisfy an optional contract.
|
|
109
|
+
type GameStorage = PaseoClient["individuality"]["query"]["Game"];
|
|
110
|
+
type GameValue = Awaited<ReturnType<GameStorage["Game"]["getValue"]>>;
|
|
111
|
+
type GameIsOptional = Assert<undefined extends GameValue ? true : false>;
|
|
112
|
+
// Negative control: `GameIndex` is `ValueQuery`, so it must *not* admit undefined.
|
|
113
|
+
type GameIndexValue = Awaited<ReturnType<GameStorage["GameIndex"]["getValue"]>>;
|
|
114
|
+
type GameIndexIsNotOptional = Assert<undefined extends GameIndexValue ? false : true>;
|
|
115
|
+
|
|
116
|
+
// The event id is derived from a runtime constant rather than a storage entry, so
|
|
117
|
+
// the constant has to exist and still be a plain string. Its *width* cannot be
|
|
118
|
+
// asserted here: PAPI's `SizedHex<N>` is `string & { __hexString?: N | unknown }`,
|
|
119
|
+
// and the `| unknown` collapses every width to the same type, so `SizedHex<32>`
|
|
120
|
+
// and `SizedHex<27>` are mutually assignable and any such assertion would pass
|
|
121
|
+
// vacuously. The 27-byte expectation is enforced at runtime instead, by the
|
|
122
|
+
// length check in `airdrop-ids.ts` and the pinned vectors beside it.
|
|
123
|
+
type GameConstants = PaseoClient["individuality"]["constants"]["Game"];
|
|
124
|
+
type EventIdBaseExists = Assert<"airdrop_event_id_base" extends keyof GameConstants ? true : false>;
|
|
125
|
+
type AirdropEventIdBase = Awaited<ReturnType<GameConstants["airdrop_event_id_base"]>>;
|
|
126
|
+
type EventIdBaseIsAString = Assert<AirdropEventIdBase extends string ? true : false>;
|
|
127
|
+
|
|
128
|
+
// The composed prize-status read spans both pallets, so it is the intersection
|
|
129
|
+
// that has to hold — and on paseo only, since it inherits `GameChain`.
|
|
130
|
+
type PaseoSatisfiesPrizeStatusContract = Assert<
|
|
131
|
+
PaseoClient extends PrizeStatusChain ? true : false
|
|
132
|
+
>;
|
|
133
|
+
type DevnetPredatesThePrizeStatusContract = Assert<
|
|
134
|
+
DevnetClient extends PrizeStatusChain ? false : true
|
|
135
|
+
>;
|
|
136
|
+
|
|
137
|
+
// `Registrations` is keyed by the entropy slot with the entry as its *value*, so
|
|
138
|
+
// `readDrawRegistration` can only work by scanning the event's prefix. Pinning the
|
|
139
|
+
// arity here is what would catch a descriptor regeneration that added a reverse
|
|
140
|
+
// index and made the scan unnecessary.
|
|
141
|
+
type RegistrationsEntries = Awaited<
|
|
142
|
+
ReturnType<PaseoClient["individuality"]["query"]["Airdrop"]["Registrations"]["getEntries"]>
|
|
143
|
+
>;
|
|
144
|
+
type RegistrationsKeyIsEventIdAndSlot = Assert<
|
|
145
|
+
RegistrationsEntries[number]["keyArgs"] extends [unknown, unknown] ? true : false
|
|
146
|
+
>;
|
|
147
|
+
|
|
148
|
+
// `Winners` is a double map keyed by the registration entry, which is what makes
|
|
149
|
+
// "did I win" a point lookup instead of a scan of every winner. If a descriptor
|
|
150
|
+
// regeneration ever collapsed it to a single key, the read layer would silently
|
|
151
|
+
// need rewriting, so the arity is pinned.
|
|
152
|
+
type WinnersKey = Parameters<
|
|
153
|
+
PaseoClient["individuality"]["query"]["Airdrop"]["Winners"]["getValue"]
|
|
154
|
+
>;
|
|
155
|
+
type WinnersTakesTwoKeys = Assert<
|
|
156
|
+
WinnersKey extends [unknown, unknown, ...unknown[]] ? true : false
|
|
157
|
+
>;
|
|
158
|
+
|
|
159
|
+
type RejectsBogusConsumersClient = Assert<
|
|
160
|
+
ClientWithoutIndividuality extends ConsumersChain ? false : true
|
|
161
|
+
>;
|
|
162
|
+
|
|
163
|
+
// The write half declares its own `RingVRFProof` rather than importing the
|
|
164
|
+
// host's, for the same reason `IndividualityChain` is structural: it keeps the
|
|
165
|
+
// individuality package free of a dependency on `@parity/product-sdk-host`. The
|
|
166
|
+
// cost is that a field rename on the host side would go unnoticed there, since
|
|
167
|
+
// nothing in that package resolves the host type. Here both are direct
|
|
168
|
+
// dependencies, so this is where the two can be tied together.
|
|
169
|
+
type HostProofSatisfiesLocal = Assert<HostRingVRFProof extends AsPersonRingVRFProof ? true : false>;
|
|
170
|
+
|
|
171
|
+
// Negative control for the same assertion. If `AsPersonRingVRFProof` ever
|
|
172
|
+
// stopped constraining, this flips to `false` and the file fails to typecheck.
|
|
173
|
+
type ProofWithoutRingIndex = {
|
|
174
|
+
proof: Uint8Array;
|
|
175
|
+
contextualAlias: { context: Uint8Array; alias: Uint8Array };
|
|
176
|
+
ringRevision: number;
|
|
177
|
+
};
|
|
178
|
+
type RejectsProofMissingRingIndex = Assert<
|
|
179
|
+
ProofWithoutRingIndex extends AsPersonRingVRFProof ? false : true
|
|
180
|
+
>;
|
|
181
|
+
|
|
182
|
+
// `AliasWithProof` is only ever accepted for `People.set_alias_account`, so the
|
|
183
|
+
// call has to exist on the real chain with the two arguments the extension's
|
|
184
|
+
// validation reads. A descriptor regeneration that renames either fails here.
|
|
185
|
+
type PeopleTx = PaseoClient["individuality"]["tx"]["People"];
|
|
186
|
+
type SetAliasAccountExists = Assert<"set_alias_account" extends keyof PeopleTx ? true : false>;
|
|
187
|
+
type SetAliasAccountArgs = Parameters<PeopleTx["set_alias_account"]>[0];
|
|
188
|
+
type SetAliasAccountTakesAccountAndValidAt = Assert<
|
|
189
|
+
"account" extends keyof SetAliasAccountArgs
|
|
190
|
+
? "call_valid_at" extends keyof SetAliasAccountArgs
|
|
191
|
+
? true
|
|
192
|
+
: false
|
|
193
|
+
: false
|
|
194
|
+
>;
|
|
195
|
+
|
|
196
|
+
// The JSDoc examples in the individuality package submit
|
|
197
|
+
// `Game.sign_up_with_alias` under a person origin. A person origin supplies only
|
|
198
|
+
// the origin, never the call arguments, so those snippets go stale the moment
|
|
199
|
+
// this call's parameters change — and nothing else in the repo compiles them.
|
|
200
|
+
type GameTx = PaseoClient["individuality"]["tx"]["Game"];
|
|
201
|
+
type SignUpWithAliasExists = Assert<"sign_up_with_alias" extends keyof GameTx ? true : false>;
|
|
202
|
+
type SignUpWithAliasArgs = Parameters<GameTx["sign_up_with_alias"]>[0];
|
|
203
|
+
type SignUpWithAliasTakesTheDocumentedArgs = Assert<
|
|
204
|
+
"identifier_key" extends keyof SignUpWithAliasArgs
|
|
205
|
+
? "statement_account" extends keyof SignUpWithAliasArgs
|
|
206
|
+
? "sig" extends keyof SignUpWithAliasArgs
|
|
207
|
+
? true
|
|
208
|
+
: false
|
|
209
|
+
: false
|
|
210
|
+
: false
|
|
211
|
+
>;
|
|
212
|
+
|
|
213
|
+
// Negative control for the assertion above. The `extends keyof` chain would pass
|
|
214
|
+
// vacuously if `SignUpWithAliasArgs` ever resolved to something permissive such
|
|
215
|
+
// as `any`, so this pins a shape that is missing `sig` and requires it to fail.
|
|
216
|
+
type SignUpArgsWithoutSig = Pick<SignUpWithAliasArgs, "identifier_key" | "statement_account">;
|
|
217
|
+
type RejectsSignUpArgsMissingSig = Assert<"sig" extends keyof SignUpArgsWithoutSig ? false : true>;
|
|
218
|
+
|
|
219
|
+
// The claim is the one contract here that touches `tx` as well as storage. Paseo
|
|
220
|
+
// only, like the game surface it composes with.
|
|
221
|
+
type PaseoSatisfiesClaimContract = Assert<PaseoClient extends ClaimChain ? true : false>;
|
|
222
|
+
type RejectsBogusClaimClient = Assert<ClientWithoutIndividuality extends ClaimChain ? false : true>;
|
|
223
|
+
|
|
224
|
+
// `claim_airdrop`'s three arguments, pinned by name. `ClaimChain` types them
|
|
225
|
+
// structurally, and PAPI encodes whatever object it is handed — so a renamed field
|
|
226
|
+
// would encode as `undefined` and fail on chain with nothing local to point at it.
|
|
227
|
+
type ClaimAirdropArgs = Parameters<GameTx["claim_airdrop"]>[0];
|
|
228
|
+
type ClaimAirdropTakesTheDocumentedArgs = Assert<
|
|
229
|
+
"game_index" extends keyof ClaimAirdropArgs
|
|
230
|
+
? "airdrop_index" extends keyof ClaimAirdropArgs
|
|
231
|
+
? "beneficiary" extends keyof ClaimAirdropArgs
|
|
232
|
+
? true
|
|
233
|
+
: false
|
|
234
|
+
: false
|
|
235
|
+
: false
|
|
236
|
+
>;
|
|
237
|
+
|
|
238
|
+
// Game sign-up.
|
|
239
|
+
type PaseoSatisfiesSignUpContract = Assert<PaseoClient extends SignUpChain ? true : false>;
|
|
240
|
+
type RejectsBogusSignUpClient = Assert<
|
|
241
|
+
ClientWithoutIndividuality extends SignUpChain ? false : true
|
|
242
|
+
>;
|
|
243
|
+
|
|
244
|
+
// `SignUpChain` alone does not reject devnet and cannot: a `tx` argument is
|
|
245
|
+
// checked contravariantly and excess-property checking does not apply between
|
|
246
|
+
// named types, so an interface naming `airdrops` is satisfied by devnet's call,
|
|
247
|
+
// which has only `airdrop`. `identifier_key` does not separate them either, since
|
|
248
|
+
// `SizedHex<N>`'s brand is optional. Assert on the intersection the read takes,
|
|
249
|
+
// where `GameChain` is the half that rejects devnet.
|
|
250
|
+
type PaseoSatisfiesSignUpRead = Assert<PaseoClient extends GameChain & SignUpChain ? true : false>;
|
|
251
|
+
type DevnetPredatesTheSignUpRead = Assert<
|
|
252
|
+
DevnetClient extends GameChain & SignUpChain ? false : true
|
|
253
|
+
>;
|
|
254
|
+
|
|
255
|
+
// The divergence itself: devnet's argument is `airdrop`, so `signUpWithAccountTx`
|
|
256
|
+
// emitting `airdrops` would encode as `undefined` and enter no draw at all.
|
|
257
|
+
type DevnetGameTx = DevnetClient["individuality"]["tx"]["Game"];
|
|
258
|
+
type DevnetSignUpArgs = Parameters<DevnetGameTx["sign_up_with_account"]>[0];
|
|
259
|
+
type DevnetHasNoAirdropsArg = Assert<"airdrops" extends keyof DevnetSignUpArgs ? false : true>;
|
|
260
|
+
type DevnetHasTheSingularArg = Assert<"airdrop" extends keyof DevnetSignUpArgs ? true : false>;
|
|
261
|
+
|
|
262
|
+
// Pinned by name for the same reason `claim_airdrop`'s are: PAPI encodes the
|
|
263
|
+
// object it is handed, so a renamed field silently encodes as `undefined`.
|
|
264
|
+
type SignUpWithAccountArgs = Parameters<GameTx["sign_up_with_account"]>[0];
|
|
265
|
+
type SignUpWithAccountTakesTheDocumentedArgs = Assert<
|
|
266
|
+
"identifier_key" extends keyof SignUpWithAccountArgs
|
|
267
|
+
? "airdrops" extends keyof SignUpWithAccountArgs
|
|
268
|
+
? true
|
|
269
|
+
: false
|
|
270
|
+
: false
|
|
271
|
+
>;
|
|
272
|
+
|
|
273
|
+
// `None` is how a player enters no draw, and the only form a recognized player
|
|
274
|
+
// can use at all.
|
|
275
|
+
type AirdropsArg = SignUpWithAccountArgs["airdrops"];
|
|
276
|
+
type AirdropsIsOptional = Assert<undefined extends AirdropsArg ? true : false>;
|
|
277
|
+
|
|
278
|
+
// Extracted from the enum rather than restated, so a renamed field fails here
|
|
279
|
+
// instead of on chain.
|
|
280
|
+
type AccountVrfs = Extract<NonNullable<AirdropsArg>, { type: "Account" }>["value"][number];
|
|
281
|
+
type AccountVrfHasPreOutputAndProof = Assert<
|
|
282
|
+
"pre_output" extends keyof AccountVrfs
|
|
283
|
+
? "proof" extends keyof AccountVrfs
|
|
284
|
+
? true
|
|
285
|
+
: false
|
|
286
|
+
: false
|
|
287
|
+
>;
|
|
288
|
+
|
|
289
|
+
// The VRF types are local copies of the host's, declared here for the same reason
|
|
290
|
+
// `AsPersonRingVRFProof` is: so the package keeps no host dependency. Those host
|
|
291
|
+
// types are mapped straight off truapi's wire types, so a rename there changes them
|
|
292
|
+
// with no line of this repo touched, and the break would land as a runtime
|
|
293
|
+
// TypeError rather than a failed typecheck.
|
|
294
|
+
type HostVrfSignatureSatisfiesLocal = Assert<
|
|
295
|
+
HostVrfSignature extends AccountVrfSignature ? true : false
|
|
296
|
+
>;
|
|
297
|
+
type HostVrfItemSatisfiesLocal = Assert<
|
|
298
|
+
HostVrfTranscriptItem extends IndividualityVrfTranscriptItem ? true : false
|
|
299
|
+
>;
|
|
300
|
+
|
|
301
|
+
// Negative controls, so the two above cannot pass vacuously.
|
|
302
|
+
type RejectsSignatureMissingProof = Assert<
|
|
303
|
+
{ preOutput: Uint8Array } extends AccountVrfSignature ? false : true
|
|
304
|
+
>;
|
|
305
|
+
type RejectsItemMissingValue = Assert<
|
|
306
|
+
{ label: Uint8Array } extends IndividualityVrfTranscriptItem ? false : true
|
|
307
|
+
>;
|
|
308
|
+
|
|
309
|
+
// `Game.Players`: the variant spelling the read keys by, and the one field it uses.
|
|
310
|
+
// Sibling reads got exactly these pins.
|
|
311
|
+
type PlayersEntry = PaseoClient["individuality"]["query"]["Game"]["Players"];
|
|
312
|
+
type PlayersKey = Parameters<PlayersEntry["getValue"]>[0];
|
|
313
|
+
type PlayersKeyIsAccountOrPerson = Assert<
|
|
314
|
+
PlayersKey extends { type: "Account" | "Person" } ? true : false
|
|
315
|
+
>;
|
|
316
|
+
type RejectsAliasSpelling = Assert<
|
|
317
|
+
{ type: "Alias"; value: string } extends PlayersKey ? false : true
|
|
318
|
+
>;
|
|
319
|
+
type PlayersValue = NonNullable<Awaited<ReturnType<PlayersEntry["getValue"]>>>;
|
|
320
|
+
type PlayersHasRegistered = Assert<"registered" extends keyof PlayersValue ? true : false>;
|
|
51
321
|
|
|
52
322
|
test("the individuality chain contract is asserted at compile time", () => {
|
|
53
323
|
// The type assertions above are the test. This keeps vitest from reporting
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/createApp.ts"],"names":["err"],"mappings":"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","file":"chunk-6BI66XUJ.js","sourcesContent":["// Copyright 2026 Parity Technologies (UK) Ltd.\n// SPDX-License-Identifier: Apache-2.0\n/**\n * createApp - Main entry point for the Product SDK\n *\n * Creates an App instance with wallet, storage, chain, and cloud storage APIs.\n */\n\nimport type { ChainDefinition } from \"polkadot-api\";\nimport type {\n App,\n AppConfig,\n WalletApi,\n ChainApi,\n Account,\n CloudStorageApi,\n LocalStorageApi,\n} from \"./types.js\";\nimport { configure, createLogger } from \"@parity/product-sdk-logger\";\nimport { createLocalKvStore } from \"@parity/product-sdk-local-storage\";\nimport { SignerManager } from \"@parity/product-sdk-signer\";\nimport {\n CloudStorageClient,\n ProductCloudStorageError,\n calculateCid,\n createLazySigner,\n} from \"@parity/product-sdk-cloud-storage\";\nimport { err, ok } from \"@parity/result\";\nimport {\n createChainClient,\n getClient,\n isConnected,\n destroyAll,\n} from \"@parity/product-sdk-chain-client\";\nimport { getAccountsProvider } from \"@parity/product-sdk-host\";\nimport {\n accountIdHexToBytes,\n type PeopleUsernameQueryApi,\n resolvePeopleUsernameOwner,\n} from \"../identity/dotns.js\";\n\nconst log = createLogger(\"app\");\n\n/**\n * Create a new Product SDK app instance\n *\n * @param config - Application configuration\n * @returns App instance with all APIs\n *\n * @example\n * ```ts\n * import { createApp } from '@parity/product-sdk';\n *\n * // Default: cloud storage enabled with paseo environment\n * const app = await createApp({\n * name: 'my-app',\n * logLevel: 'info',\n * });\n *\n * // Custom cloud storage environment\n * const prodApp = await createApp({\n * name: 'my-app',\n * cloudStorage: { environment: 'polkadot' },\n * });\n *\n * // Disable cloud storage entirely\n * const noCloudStorageApp = await createApp({\n * name: 'my-app',\n * cloudStorage: false,\n * });\n *\n * // Connect wallet\n * const { accounts } = await app.wallet.connect();\n *\n * // Use storage\n * await app.localStorage.set('key', 'value');\n *\n * // Use cloud storage (check for null if it might be disabled)\n * if (app.cloudStorage) {\n * const cid = await app.cloudStorage.upload('hello world');\n * }\n * ```\n */\nexport async function createApp(config: AppConfig): Promise<App> {\n // Set log level if specified\n if (config.logLevel) {\n configure({ level: config.logLevel });\n }\n\n log.info(\"Creating Product SDK app\", { name: config.name });\n\n // Initialize storage (container-only - will throw if not in container)\n const localKvStore = await createLocalKvStore({ prefix: config.name });\n\n // Initialize signer manager\n const signerManager = new SignerManager({\n dappName: config.name,\n });\n\n // Initialize cloud storage client (configurable, defaults to paseo).\n //\n // The signer is wrapped lazily so the cloud storage client can be built before\n // an account is selected. Uploads will throw a clear error if no signer\n // is available at submission time. Reads (fetch / fetchJson) don't need\n // a signer, so they work regardless of whether an account is selected --\n // but they are container-only and throw CloudStorageHostUnavailableError\n // outside a host container (no IPFS-gateway fallback).\n const cloudStorageEnabled = config.cloudStorage !== false;\n const cloudStorageEnvironment =\n typeof config.cloudStorage === \"object\" ? config.cloudStorage.environment : \"paseo\";\n const cloudStorageClient = cloudStorageEnabled\n ? await CloudStorageClient.create({\n environment: cloudStorageEnvironment,\n signer: createLazySigner(() => signerManager.getSigner()),\n })\n : null;\n\n if (cloudStorageEnabled) {\n log.debug(\"Cloud Storage client (Bulletin) initialized\", {\n environment: cloudStorageEnvironment,\n });\n } else {\n log.debug(\"Cloud Storage client disabled\");\n }\n\n // Create storage API adapter\n const localStorageApi: LocalStorageApi = {\n get: (key) => localKvStore.get(key),\n set: (key, value) => localKvStore.set(key, value),\n getJSON: <T>(key: string) => localKvStore.getJSON<T>(key),\n setJSON: <T>(key: string, value: T) => localKvStore.setJSON(key, value),\n remove: (key) => localKvStore.remove(key),\n clear: async () => {\n // LocalKvStore doesn't have clear - this is a no-op\n log.debug(\"clear() is not supported in container storage mode\");\n },\n };\n\n // Create wallet API adapter\n const walletApi = createWalletApi(signerManager);\n\n // Create chain API\n const chainApi: ChainApi = {\n getClient(descriptor) {\n log.debug(\"getClient called\", { genesis: descriptor.genesis });\n const client = getClient(descriptor);\n return client.getTypedApi(descriptor);\n },\n\n getRawClient(descriptor) {\n log.debug(\"getRawClient called\", { genesis: descriptor.genesis });\n return getClient(descriptor);\n },\n\n async connect<T extends Record<string, ChainDefinition>>(chains: T) {\n log.debug(\"connect called\", { chains: Object.keys(chains) });\n return createChainClient({ chains });\n },\n\n isConnected(descriptor) {\n return isConnected(descriptor);\n },\n\n destroyAll() {\n log.debug(\"destroyAll called\");\n destroyAll();\n },\n };\n\n // Create Cloud Storage API adapter (null if disabled)\n const cloudStorageApi: CloudStorageApi | null = cloudStorageClient\n ? {\n upload: async (data) => {\n const bytes = typeof data === \"string\" ? new TextEncoder().encode(data) : data;\n try {\n // Explicitly request a DAG-PB manifest so chunked uploads always\n // resolve to a single root CID. Without this, AsyncBulletinClient\n // can return `result.cid: undefined` for chunked-without-manifest\n // uploads — but app consumers expect a CID they can hand to\n // `fetch(cid)`, so treat a missing CID as an error.\n const uploaded = await cloudStorageClient\n .store(bytes)\n .withManifest(true)\n .send();\n if (!uploaded.cid) {\n return err(\n new ProductCloudStorageError(\n \"Cloud storage upload returned no CID despite .withManifest(true). Upstream contract may have shifted — file an issue.\",\n ),\n );\n }\n return ok(uploaded.cid.toString());\n } catch (cause) {\n const message = cause instanceof Error ? cause.message : String(cause);\n return err(new ProductCloudStorageError(message, { cause }));\n }\n },\n fetch: (cid) => cloudStorageClient.fetchBytes(cid),\n computeCid: async (data) => {\n const bytes = typeof data === \"string\" ? new TextEncoder().encode(data) : data;\n const cid = await calculateCid(bytes);\n return cid.toString();\n },\n }\n : null;\n\n log.info(\"Product SDK app created\", {\n name: config.name,\n cloudStorage: cloudStorageEnabled ? cloudStorageEnvironment : \"disabled\",\n });\n\n return {\n wallet: walletApi,\n localStorage: localStorageApi,\n chain: chainApi,\n cloudStorage: cloudStorageApi,\n getAppInfo: () => ({ ...config }),\n };\n}\n\n/**\n * Create wallet API adapter using SignerManager from leaf package\n */\nfunction createWalletApi(signerManager: SignerManager): WalletApi {\n // Track account change subscribers\n const accountChangeSubscribers = new Set<(account: Account | null) => void>();\n\n // Subscribe to signer manager state changes\n signerManager.subscribe((state) => {\n const account = state.selectedAccount\n ? {\n address: state.selectedAccount.address,\n name: state.selectedAccount.name ?? undefined,\n source: state.selectedAccount.source,\n }\n : null;\n for (const callback of accountChangeSubscribers) {\n try {\n callback(account);\n } catch (e) {\n log.warn(\"Account change callback threw\", { error: e });\n }\n }\n });\n\n return {\n async connect(): Promise<{ accounts: Account[] }> {\n const result = await signerManager.connect();\n if (!result.ok) {\n throw new Error(result.error.message);\n }\n return {\n accounts: result.value.map((a) => ({\n address: a.address,\n name: a.name ?? undefined,\n source: a.source,\n })),\n };\n },\n\n async disconnect(): Promise<void> {\n signerManager.disconnect();\n },\n\n getAccounts(): Account[] {\n return signerManager.getState().accounts.map((a) => ({\n address: a.address,\n name: a.name ?? undefined,\n source: a.source,\n }));\n },\n\n getSelectedAccount(): Account | null {\n const selected = signerManager.getState().selectedAccount;\n if (!selected) return null;\n return {\n address: selected.address,\n name: selected.name ?? undefined,\n source: selected.source,\n };\n },\n\n selectAccount(address: string): void {\n signerManager.selectAccount(address);\n },\n\n async signMessage(message: string | Uint8Array): Promise<Uint8Array> {\n const bytes = typeof message === \"string\" ? new TextEncoder().encode(message) : message;\n const result = await signerManager.signRaw(bytes);\n if (!result.ok) {\n throw new Error(result.error.message);\n }\n return result.value;\n },\n\n async signMessageWithDotNsIdentity(args) {\n const message =\n typeof args.message === \"string\"\n ? new TextEncoder().encode(args.message)\n : args.message;\n const accountsProvider = await getHostAccountsProvider();\n const username = args.username ?? (await getPrimaryUsername(accountsProvider));\n\n // Reuse an already-connected People chain when the caller has\n // wired one up via `app.chain.connect({ ..., <name>: peopleChain })`.\n // Fall back to opening a transient connection so first-time users\n // don't have to think about chain lifecycles. The chain-client\n // module caches by genesis fingerprint, so subsequent\n // signMessageWithDotNsIdentity calls share whichever connection\n // got established first.\n const peopleClient = isConnected(args.peopleChain)\n ? getClient(args.peopleChain)\n : await createChainClient({ chains: { people: args.peopleChain } }).then(\n (c) => c.raw.people,\n );\n // PAPI's `TypedApi.query.X.Y.getValue` is variadic\n // (`...args: [...WithCallOptions<Args>]`) so it's not assignable\n // to our deliberately-narrow `(key) => Promise<...>` shape. The\n // resolver only ever passes the storage key; the cast adapts the\n // wider PAPI surface to the minimum we depend on.\n const peopleApi = peopleClient.getTypedApi(\n args.peopleChain,\n ) as unknown as PeopleUsernameQueryApi;\n const accountId = await resolvePeopleUsernameOwner(username, peopleApi);\n if (!accountId) {\n throw new Error(`No account owns DotNS username \"${username}\"`);\n }\n\n const owner = accountIdHexToBytes(accountId);\n const signer = accountsProvider.getLegacyAccountSigner({\n publicKey: owner,\n name: username,\n });\n\n try {\n return {\n username,\n accountId,\n signature: await signer.signBytes(message),\n };\n } catch (cause) {\n throw new Error(\n `Failed to sign with DotNS username \"${username}\": ${\n cause instanceof Error ? cause.message : String(cause)\n }`,\n { cause },\n );\n }\n },\n\n onAccountChange(callback: (account: Account | null) => void): () => void {\n accountChangeSubscribers.add(callback);\n return () => accountChangeSubscribers.delete(callback);\n },\n\n getProductAccount(): Account | null {\n // Product accounts require async call - this sync API can't support it properly\n // Users should use SignerManager.getProductAccount() directly\n log.warn(\n \"getProductAccount() is deprecated - use SignerManager.getProductAccount() directly\",\n );\n return null;\n },\n\n getAnonymousAlias(): string | null {\n // Anonymous aliases require async call - this sync API can't support it properly\n // Users should use SignerManager.getProductAccountAlias() directly\n log.warn(\n \"getAnonymousAlias() is deprecated - use SignerManager.getProductAccountAlias() directly\",\n );\n return null;\n },\n\n async createProof(_message: Uint8Array): Promise<Uint8Array> {\n // Ring VRF proofs require SignerManager.createRingVRFProof() directly\n throw new Error(\n \"createProof() is not implemented in the App API. \" +\n \"Use SignerManager.createRingVRFProof() directly.\",\n );\n },\n };\n}\n\ntype HostAccountsProvider = NonNullable<Awaited<ReturnType<typeof getAccountsProvider>>>;\n\nasync function getHostAccountsProvider(): Promise<HostAccountsProvider> {\n const provider = await getAccountsProvider();\n if (!provider) {\n throw new Error(\"Host accounts provider is not available\");\n }\n return provider;\n}\n\nasync function getPrimaryUsername(accountsProvider: HostAccountsProvider): Promise<string> {\n const result = await accountsProvider.getUserId().match(\n (value) => value,\n (err) => {\n throw err;\n },\n );\n const username = result.primaryUsername.trim();\n if (!username) {\n throw new Error(\"Host identity did not provide a primary DotNS username\");\n }\n return username;\n}\n"]}
|
package/dist/chunk-BIKT6X54.js
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { accountIdBytes } from '@parity/product-sdk-address';
|
|
2
|
-
import { hexToBytes, bytesToHex } from '@parity/product-sdk-crypto';
|
|
3
|
-
import { createLogger } from '@parity/product-sdk-logger';
|
|
4
|
-
|
|
5
|
-
// src/identity/dotns.ts
|
|
6
|
-
var log = createLogger("identity");
|
|
7
|
-
function isValidDotNsName(name) {
|
|
8
|
-
if (!name.endsWith(".dot")) return false;
|
|
9
|
-
const label = name.slice(0, -4);
|
|
10
|
-
if (label.length < 3 || label.length > 63) return false;
|
|
11
|
-
return /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(label);
|
|
12
|
-
}
|
|
13
|
-
function normalizeDotNsName(name) {
|
|
14
|
-
let normalized = name.toLowerCase().trim();
|
|
15
|
-
if (!normalized.endsWith(".dot")) {
|
|
16
|
-
normalized += ".dot";
|
|
17
|
-
}
|
|
18
|
-
return normalized;
|
|
19
|
-
}
|
|
20
|
-
async function resolveDotNs(name) {
|
|
21
|
-
const normalized = normalizeDotNsName(name);
|
|
22
|
-
if (!isValidDotNsName(normalized)) {
|
|
23
|
-
log.warn("Invalid DotNS name", { name });
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
log.debug("Resolving DotNS name", { name: normalized });
|
|
27
|
-
throw new Error(
|
|
28
|
-
"resolveDotNs() is not yet implemented. This is a skeleton for the Product SDK structure."
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
async function reverseDotNs(address) {
|
|
32
|
-
log.debug("Reverse resolving address", { address });
|
|
33
|
-
throw new Error(
|
|
34
|
-
"reverseDotNs() is not yet implemented. This is a skeleton for the Product SDK structure."
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
async function isDotNsAvailable(name) {
|
|
38
|
-
const record = await resolveDotNs(name).catch(() => null);
|
|
39
|
-
return record === null;
|
|
40
|
-
}
|
|
41
|
-
async function resolvePeopleUsernameOwner(username, peopleApi) {
|
|
42
|
-
const owner = await peopleApi.query.Resources.UsernameOwnerOf.getValue(
|
|
43
|
-
new TextEncoder().encode(username)
|
|
44
|
-
);
|
|
45
|
-
if (!owner) return null;
|
|
46
|
-
return accountIdBytesToHex(accountIdBytes(owner));
|
|
47
|
-
}
|
|
48
|
-
function assertHex(value) {
|
|
49
|
-
if (!/^0x[0-9a-fA-F]*$/.test(value)) {
|
|
50
|
-
throw new Error(`Expected 0x-prefixed hex string, got ${value}`);
|
|
51
|
-
}
|
|
52
|
-
return value;
|
|
53
|
-
}
|
|
54
|
-
function accountIdHexToBytes(accountId) {
|
|
55
|
-
const bytes = hexToBytes(assertHex(accountId).slice(2));
|
|
56
|
-
if (bytes.length !== 32) {
|
|
57
|
-
throw new Error(`Expected 32-byte AccountId, got ${bytes.length} bytes`);
|
|
58
|
-
}
|
|
59
|
-
return bytes;
|
|
60
|
-
}
|
|
61
|
-
function accountIdBytesToHex(bytes) {
|
|
62
|
-
if (bytes.length !== 32) {
|
|
63
|
-
throw new Error(`Expected 32-byte AccountId, got ${bytes.length} bytes`);
|
|
64
|
-
}
|
|
65
|
-
return `0x${bytesToHex(bytes)}`;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export { accountIdHexToBytes, isDotNsAvailable, isValidDotNsName, normalizeDotNsName, resolveDotNs, resolvePeopleUsernameOwner, reverseDotNs };
|
|
69
|
-
//# sourceMappingURL=chunk-BIKT6X54.js.map
|
|
70
|
-
//# sourceMappingURL=chunk-BIKT6X54.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/identity/dotns.ts"],"names":[],"mappings":"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","file":"chunk-BIKT6X54.js","sourcesContent":["// Copyright 2026 Parity Technologies (UK) Ltd.\n// SPDX-License-Identifier: Apache-2.0\n/**\n * DotNS (Polkadot Name Service) utilities\n *\n * Provides name resolution for .dot domains\n */\n\nimport { accountIdBytes } from \"@parity/product-sdk-address\";\nimport { bytesToHex, hexToBytes } from \"@parity/product-sdk-crypto\";\nimport { createLogger } from \"@parity/product-sdk-logger\";\nimport type {\n ChainDefinition,\n PalletsTypedef,\n PlainDescriptor,\n RuntimeDescriptor,\n SS58String,\n StorageDescriptor,\n TxDescriptor,\n} from \"polkadot-api\";\nimport type { DotNsRecord } from \"./types.js\";\n\nconst log = createLogger(\"identity\");\n\ntype AnyDescriptorEntry<T> = Record<string, Record<string, T>>;\n\ntype PeopleUsernameStorage = {\n Resources: {\n UsernameOwnerOf: StorageDescriptor<[Uint8Array], SS58String, true, never>;\n };\n};\n\ntype PeopleUsernamePallets = PalletsTypedef<\n PeopleUsernameStorage,\n AnyDescriptorEntry<TxDescriptor<any>>,\n AnyDescriptorEntry<PlainDescriptor<any>>,\n AnyDescriptorEntry<PlainDescriptor<any>>,\n AnyDescriptorEntry<PlainDescriptor<any>>,\n AnyDescriptorEntry<RuntimeDescriptor<any, any>>\n>;\n\n/**\n * Descriptor narrowed to \"any chain that exposes `Resources.UsernameOwnerOf`\".\n *\n * Used as the input to `signMessageWithDotNsIdentity` so the SDK doesn't pin\n * a specific People-chain genesis — anything with the right storage shape\n * (paseo-individuality today, future People Lite, etc.) is accepted.\n */\nexport type PeopleUsernameChain = ChainDefinition & {\n descriptors: Promise<unknown> & {\n pallets: PeopleUsernamePallets;\n };\n};\n\n/**\n * Minimal typed-api shape required to resolve a username on a People chain.\n *\n * This is a narrow structural type — anything with the right\n * `query.Resources.UsernameOwnerOf.getValue` shape works, including a real\n * `TypedApi<PeopleUsernameChain>` slice of a `ChainClient` or a hand-rolled\n * test double.\n */\nexport type PeopleUsernameQueryApi = {\n query: {\n Resources: {\n UsernameOwnerOf: {\n getValue: (key: Uint8Array) => Promise<SS58String | undefined>;\n };\n };\n };\n};\n\n/**\n * Check if a string is a valid DotNS name\n *\n * @param name - Name to validate\n * @returns True if valid DotNS name\n */\nexport function isValidDotNsName(name: string): boolean {\n // Basic validation: alphanumeric, hyphens, ends with .dot\n if (!name.endsWith(\".dot\")) return false;\n const label = name.slice(0, -4);\n if (label.length < 3 || label.length > 63) return false;\n return /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(label);\n}\n\n/**\n * Normalize a DotNS name (lowercase, trim whitespace)\n *\n * @param name - Name to normalize\n * @returns Normalized name\n */\nexport function normalizeDotNsName(name: string): string {\n let normalized = name.toLowerCase().trim();\n if (!normalized.endsWith(\".dot\")) {\n normalized += \".dot\";\n }\n return normalized;\n}\n\n/**\n * Resolve a DotNS name to an address.\n *\n * @deprecated Not implemented — throws at runtime. Use\n * `wallet.signMessageWithDotNsIdentity({ peopleChain, username })` (which\n * internally calls {@link resolvePeopleUsernameOwner}) for the supported\n * People-chain username flow.\n *\n * @param name - DotNS name (e.g., \"alice.dot\")\n * @returns Resolved record or null if not found\n */\nexport async function resolveDotNs(name: string): Promise<DotNsRecord | null> {\n const normalized = normalizeDotNsName(name);\n\n if (!isValidDotNsName(normalized)) {\n log.warn(\"Invalid DotNS name\", { name });\n return null;\n }\n\n log.debug(\"Resolving DotNS name\", { name: normalized });\n\n // TODO: Implement via PAPI query to DotNS pallet\n throw new Error(\n \"resolveDotNs() is not yet implemented. \" +\n \"This is a skeleton for the Product SDK structure.\",\n );\n}\n\n/**\n * Reverse resolve an address to a DotNS name.\n *\n * @deprecated Not implemented — throws at runtime. Reverse lookup will land\n * alongside future identity work; for now resolve forward via\n * `wallet.signMessageWithDotNsIdentity`.\n *\n * @param address - SS58 address\n * @returns Primary name or null if none set\n */\nexport async function reverseDotNs(address: string): Promise<string | null> {\n log.debug(\"Reverse resolving address\", { address });\n\n // TODO: Implement via PAPI query to DotNS pallet\n throw new Error(\n \"reverseDotNs() is not yet implemented. \" +\n \"This is a skeleton for the Product SDK structure.\",\n );\n}\n\n/**\n * Check if a DotNS name is available for registration.\n *\n * @deprecated Not implemented — depends on {@link resolveDotNs} which throws.\n *\n * @param name - Name to check\n * @returns True if available\n */\nexport async function isDotNsAvailable(name: string): Promise<boolean> {\n const record = await resolveDotNs(name).catch(() => null);\n return record === null;\n}\n\n/**\n * Resolve a People / People Lite username to its owning `AccountId32`.\n *\n * Queries `Resources.UsernameOwnerOf` on the caller-supplied typed-api fragment.\n * The returned value is the raw 32-byte account id as a `0x`-prefixed hex\n * string, or `null` when no owner is registered for that username.\n *\n * The `username` is UTF-8 encoded as-is — no normalization is applied. Pass\n * the exact byte string the chain stores (typically with the `.dot` suffix).\n *\n * @internal Exposed for unit testing. Consumers should use\n * `wallet.signMessageWithDotNsIdentity` instead, which orchestrates the\n * chain-connection lifecycle.\n */\nexport async function resolvePeopleUsernameOwner(\n username: string,\n peopleApi: PeopleUsernameQueryApi,\n): Promise<`0x${string}` | null> {\n const owner = await peopleApi.query.Resources.UsernameOwnerOf.getValue(\n new TextEncoder().encode(username),\n );\n if (!owner) return null;\n\n return accountIdBytesToHex(accountIdBytes(owner));\n}\n\nfunction assertHex(value: string): `0x${string}` {\n if (!/^0x[0-9a-fA-F]*$/.test(value)) {\n throw new Error(`Expected 0x-prefixed hex string, got ${value}`);\n }\n return value as `0x${string}`;\n}\n\nexport function accountIdHexToBytes(accountId: `0x${string}`): Uint8Array {\n const bytes = hexToBytes(assertHex(accountId).slice(2));\n if (bytes.length !== 32) {\n throw new Error(`Expected 32-byte AccountId, got ${bytes.length} bytes`);\n }\n return bytes;\n}\n\nfunction accountIdBytesToHex(bytes: Uint8Array): `0x${string}` {\n if (bytes.length !== 32) {\n throw new Error(`Expected 32-byte AccountId, got ${bytes.length} bytes`);\n }\n return `0x${bytesToHex(bytes)}`;\n}\n"]}
|
package/dist/dotns-DIaptENj.d.ts
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import { ChainDefinition, PalletsTypedef, StorageDescriptor, SS58String, TxDescriptor, PlainDescriptor, RuntimeDescriptor } from 'polkadot-api';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Identity module types
|
|
5
|
-
*
|
|
6
|
-
* Types for DotNS name resolution and context-alias derivation
|
|
7
|
-
*/
|
|
8
|
-
/** DotNS name resolution result */
|
|
9
|
-
interface DotNsRecord {
|
|
10
|
-
/** Resolved SS58 address */
|
|
11
|
-
address: string;
|
|
12
|
-
/** Name that was resolved */
|
|
13
|
-
name: string;
|
|
14
|
-
/** Owner address */
|
|
15
|
-
owner: string;
|
|
16
|
-
/** Expiration timestamp (if applicable) */
|
|
17
|
-
expiresAt?: number;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Context alias info: a deterministic, context-bound alias derived from a parent account
|
|
21
|
-
*
|
|
22
|
-
* @deprecated Returned by `deriveContextAlias`, whose addresses no key can spend.
|
|
23
|
-
* Removal: `@parity/product-sdk` 0.23.0.
|
|
24
|
-
*/
|
|
25
|
-
interface ContextAliasInfo {
|
|
26
|
-
/** Alias SS58 address */
|
|
27
|
-
address: string;
|
|
28
|
-
/** H160 EVM address */
|
|
29
|
-
h160Address: `0x${string}`;
|
|
30
|
-
/** Parent account address */
|
|
31
|
-
parentAddress: string;
|
|
32
|
-
/** Context string used for derivation */
|
|
33
|
-
context: string;
|
|
34
|
-
}
|
|
35
|
-
/** Identity verification result */
|
|
36
|
-
interface VerificationResult {
|
|
37
|
-
/** Whether identity is verified */
|
|
38
|
-
verified: boolean;
|
|
39
|
-
/** Verification method used */
|
|
40
|
-
method: "on-chain" | "judgement" | "social";
|
|
41
|
-
/** Verification details */
|
|
42
|
-
details?: Record<string, unknown>;
|
|
43
|
-
}
|
|
44
|
-
/** On-chain identity info */
|
|
45
|
-
interface OnChainIdentity {
|
|
46
|
-
/** Display name */
|
|
47
|
-
display?: string;
|
|
48
|
-
/** Legal name */
|
|
49
|
-
legal?: string;
|
|
50
|
-
/** Web URL */
|
|
51
|
-
web?: string;
|
|
52
|
-
/** Email */
|
|
53
|
-
email?: string;
|
|
54
|
-
/** Twitter handle */
|
|
55
|
-
twitter?: string;
|
|
56
|
-
/** Riot/Matrix handle */
|
|
57
|
-
riot?: string;
|
|
58
|
-
/** Additional fields */
|
|
59
|
-
additional: Array<[string, string]>;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* DotNS (Polkadot Name Service) utilities
|
|
64
|
-
*
|
|
65
|
-
* Provides name resolution for .dot domains
|
|
66
|
-
*/
|
|
67
|
-
|
|
68
|
-
type AnyDescriptorEntry<T> = Record<string, Record<string, T>>;
|
|
69
|
-
type PeopleUsernameStorage = {
|
|
70
|
-
Resources: {
|
|
71
|
-
UsernameOwnerOf: StorageDescriptor<[Uint8Array], SS58String, true, never>;
|
|
72
|
-
};
|
|
73
|
-
};
|
|
74
|
-
type PeopleUsernamePallets = PalletsTypedef<PeopleUsernameStorage, AnyDescriptorEntry<TxDescriptor<any>>, AnyDescriptorEntry<PlainDescriptor<any>>, AnyDescriptorEntry<PlainDescriptor<any>>, AnyDescriptorEntry<PlainDescriptor<any>>, AnyDescriptorEntry<RuntimeDescriptor<any, any>>>;
|
|
75
|
-
/**
|
|
76
|
-
* Descriptor narrowed to "any chain that exposes `Resources.UsernameOwnerOf`".
|
|
77
|
-
*
|
|
78
|
-
* Used as the input to `signMessageWithDotNsIdentity` so the SDK doesn't pin
|
|
79
|
-
* a specific People-chain genesis — anything with the right storage shape
|
|
80
|
-
* (paseo-individuality today, future People Lite, etc.) is accepted.
|
|
81
|
-
*/
|
|
82
|
-
type PeopleUsernameChain = ChainDefinition & {
|
|
83
|
-
descriptors: Promise<unknown> & {
|
|
84
|
-
pallets: PeopleUsernamePallets;
|
|
85
|
-
};
|
|
86
|
-
};
|
|
87
|
-
/**
|
|
88
|
-
* Minimal typed-api shape required to resolve a username on a People chain.
|
|
89
|
-
*
|
|
90
|
-
* This is a narrow structural type — anything with the right
|
|
91
|
-
* `query.Resources.UsernameOwnerOf.getValue` shape works, including a real
|
|
92
|
-
* `TypedApi<PeopleUsernameChain>` slice of a `ChainClient` or a hand-rolled
|
|
93
|
-
* test double.
|
|
94
|
-
*/
|
|
95
|
-
type PeopleUsernameQueryApi = {
|
|
96
|
-
query: {
|
|
97
|
-
Resources: {
|
|
98
|
-
UsernameOwnerOf: {
|
|
99
|
-
getValue: (key: Uint8Array) => Promise<SS58String | undefined>;
|
|
100
|
-
};
|
|
101
|
-
};
|
|
102
|
-
};
|
|
103
|
-
};
|
|
104
|
-
/**
|
|
105
|
-
* Check if a string is a valid DotNS name
|
|
106
|
-
*
|
|
107
|
-
* @param name - Name to validate
|
|
108
|
-
* @returns True if valid DotNS name
|
|
109
|
-
*/
|
|
110
|
-
declare function isValidDotNsName(name: string): boolean;
|
|
111
|
-
/**
|
|
112
|
-
* Normalize a DotNS name (lowercase, trim whitespace)
|
|
113
|
-
*
|
|
114
|
-
* @param name - Name to normalize
|
|
115
|
-
* @returns Normalized name
|
|
116
|
-
*/
|
|
117
|
-
declare function normalizeDotNsName(name: string): string;
|
|
118
|
-
/**
|
|
119
|
-
* Resolve a DotNS name to an address.
|
|
120
|
-
*
|
|
121
|
-
* @deprecated Not implemented — throws at runtime. Use
|
|
122
|
-
* `wallet.signMessageWithDotNsIdentity({ peopleChain, username })` (which
|
|
123
|
-
* internally calls {@link resolvePeopleUsernameOwner}) for the supported
|
|
124
|
-
* People-chain username flow.
|
|
125
|
-
*
|
|
126
|
-
* @param name - DotNS name (e.g., "alice.dot")
|
|
127
|
-
* @returns Resolved record or null if not found
|
|
128
|
-
*/
|
|
129
|
-
declare function resolveDotNs(name: string): Promise<DotNsRecord | null>;
|
|
130
|
-
/**
|
|
131
|
-
* Reverse resolve an address to a DotNS name.
|
|
132
|
-
*
|
|
133
|
-
* @deprecated Not implemented — throws at runtime. Reverse lookup will land
|
|
134
|
-
* alongside future identity work; for now resolve forward via
|
|
135
|
-
* `wallet.signMessageWithDotNsIdentity`.
|
|
136
|
-
*
|
|
137
|
-
* @param address - SS58 address
|
|
138
|
-
* @returns Primary name or null if none set
|
|
139
|
-
*/
|
|
140
|
-
declare function reverseDotNs(address: string): Promise<string | null>;
|
|
141
|
-
/**
|
|
142
|
-
* Check if a DotNS name is available for registration.
|
|
143
|
-
*
|
|
144
|
-
* @deprecated Not implemented — depends on {@link resolveDotNs} which throws.
|
|
145
|
-
*
|
|
146
|
-
* @param name - Name to check
|
|
147
|
-
* @returns True if available
|
|
148
|
-
*/
|
|
149
|
-
declare function isDotNsAvailable(name: string): Promise<boolean>;
|
|
150
|
-
/**
|
|
151
|
-
* Resolve a People / People Lite username to its owning `AccountId32`.
|
|
152
|
-
*
|
|
153
|
-
* Queries `Resources.UsernameOwnerOf` on the caller-supplied typed-api fragment.
|
|
154
|
-
* The returned value is the raw 32-byte account id as a `0x`-prefixed hex
|
|
155
|
-
* string, or `null` when no owner is registered for that username.
|
|
156
|
-
*
|
|
157
|
-
* The `username` is UTF-8 encoded as-is — no normalization is applied. Pass
|
|
158
|
-
* the exact byte string the chain stores (typically with the `.dot` suffix).
|
|
159
|
-
*
|
|
160
|
-
* @internal Exposed for unit testing. Consumers should use
|
|
161
|
-
* `wallet.signMessageWithDotNsIdentity` instead, which orchestrates the
|
|
162
|
-
* chain-connection lifecycle.
|
|
163
|
-
*/
|
|
164
|
-
declare function resolvePeopleUsernameOwner(username: string, peopleApi: PeopleUsernameQueryApi): Promise<`0x${string}` | null>;
|
|
165
|
-
declare function accountIdHexToBytes(accountId: `0x${string}`): Uint8Array;
|
|
166
|
-
|
|
167
|
-
export { type ContextAliasInfo as C, type DotNsRecord as D, type OnChainIdentity as O, type PeopleUsernameChain as P, type VerificationResult as V, type PeopleUsernameQueryApi as a, accountIdHexToBytes as b, isValidDotNsName as c, resolvePeopleUsernameOwner as d, reverseDotNs as e, isDotNsAvailable as i, normalizeDotNsName as n, resolveDotNs as r };
|