@ethereum-entity-registry/sdk 0.1.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 (3) hide show
  1. package/dist/index.d.ts +479 -0
  2. package/dist/index.js +7492 -0
  3. package/package.json +44 -0
@@ -0,0 +1,479 @@
1
+ import { Address, WalletClient, PublicClient, Abi, Hex } from 'viem';
2
+ import { Client, gql } from '@urql/core';
3
+ import { PropsWithChildren } from 'react';
4
+ import * as _tanstack_react_query from '@tanstack/react-query';
5
+ import { UseMutationOptions, UseQueryResult } from '@tanstack/react-query';
6
+
7
+ type SupportedChainId = 1 | 11155111 | 8453 | 84532 | 31337;
8
+ type ChainConfig = {
9
+ registry?: `0x${string}`;
10
+ indexer?: string;
11
+ };
12
+ declare const config: Record<SupportedChainId, ChainConfig>;
13
+
14
+ type Identifier = {
15
+ id: `0x${string}`;
16
+ namespace: string;
17
+ canonicalString: string;
18
+ owner: Address | null;
19
+ accountAddress: Address | null;
20
+ claimedAt: bigint | null;
21
+ revokedAt: bigint | null;
22
+ createdAt: bigint;
23
+ };
24
+ type IdentifierAlias = {
25
+ id: string;
26
+ aliasId: `0x${string}`;
27
+ primaryId: `0x${string}`;
28
+ linkedAt: bigint;
29
+ };
30
+ type Page<T> = {
31
+ items: T[];
32
+ totalCount: number;
33
+ pageInfo: {
34
+ hasNextPage: boolean;
35
+ endCursor?: string;
36
+ };
37
+ };
38
+ type IdentifierFilter = {
39
+ id?: string;
40
+ id_in?: string[];
41
+ namespace?: string;
42
+ owner?: string;
43
+ owner_in?: string[];
44
+ accountAddress?: string;
45
+ };
46
+ type AliasFilter = {
47
+ aliasId?: string;
48
+ primaryId?: string;
49
+ primaryId_in?: string[];
50
+ };
51
+ type QueryVariables<TFilter> = {
52
+ where?: TFilter;
53
+ orderBy?: string;
54
+ orderDirection?: "asc" | "desc";
55
+ limit?: number;
56
+ after?: string;
57
+ };
58
+ type RegistryStats = {
59
+ totalIdentifiers: number;
60
+ totalOwners: number;
61
+ };
62
+ type StatsResponse = {
63
+ data: RegistryStats;
64
+ };
65
+ type IndexerBase = {
66
+ client: Client;
67
+ gql: typeof gql;
68
+ baseUrl: string;
69
+ identifier: {
70
+ get: (id: `0x${string}`) => Promise<Identifier | null>;
71
+ query: (variables?: QueryVariables<IdentifierFilter>) => Promise<Page<Identifier> | null>;
72
+ };
73
+ alias: {
74
+ query: (variables?: QueryVariables<AliasFilter>) => Promise<Page<IdentifierAlias> | null>;
75
+ };
76
+ stats: () => Promise<RegistryStats>;
77
+ };
78
+ type Indexer = IndexerBase & {
79
+ extend<T>(extension: IndexerExtension<T>): Indexer & T;
80
+ };
81
+ type IndexerExtension<T> = (indexer: Indexer) => T;
82
+ declare function createIndexer(chainId: SupportedChainId): Indexer;
83
+
84
+ type IdentifierState = {
85
+ id: `0x${string}`;
86
+ depositAddress: Address;
87
+ owner: Address | null;
88
+ balance: bigint | null;
89
+ };
90
+ type ChainDeployments$1 = {
91
+ EntityRegistry: {
92
+ address: string;
93
+ abi: unknown;
94
+ };
95
+ beaconProxyBytecode?: string;
96
+ };
97
+ declare function createRegistryMethods(wallet: WalletClient | undefined, publicClient: PublicClient, deployments: ChainDeployments$1): {
98
+ /**
99
+ * Get the registered owner of an identifier (resolves through aliases).
100
+ * Returns null if unclaimed.
101
+ */
102
+ ownerOf: (id: `0x${string}`) => Promise<Address | null>;
103
+ /**
104
+ * Get the deterministic account address for an identifier.
105
+ */
106
+ predictAddress: (id: `0x${string}`) => Promise<Address>;
107
+ /**
108
+ * Claim ownership of an identifier with an oracle proof.
109
+ *
110
+ * @example
111
+ * sdk.registry.claim("github.com/org/repo", proof)
112
+ * sdk.registry.claim("example.com", proof)
113
+ * sdk.registry.claim("github:org/repo", proof)
114
+ */
115
+ claim: (input: string, proof: `0x${string}`) => Promise<{
116
+ hash: `0x${string}`;
117
+ }>;
118
+ /**
119
+ * Revoke ownership of an identifier.
120
+ *
121
+ * @example
122
+ * sdk.registry.revoke("github.com/org/repo")
123
+ * sdk.registry.revoke("example.com")
124
+ */
125
+ revoke: (input: string) => Promise<{
126
+ hash: `0x${string}`;
127
+ }>;
128
+ /**
129
+ * Link alias identifiers to a primary identifier.
130
+ */
131
+ linkIds: (primaryId: `0x${string}`, aliasIds: `0x${string}`[]) => Promise<{
132
+ hash: `0x${string}`;
133
+ }>;
134
+ /**
135
+ * Unlink alias identifiers from their primary.
136
+ */
137
+ unlinkIds: (primaryId: `0x${string}`, aliasIds: `0x${string}`[]) => Promise<{
138
+ hash: `0x${string}`;
139
+ }>;
140
+ /**
141
+ * Deploy the IdentityAccount proxy for an identifier (permissionless).
142
+ */
143
+ deployAccount: (id: `0x${string}`) => Promise<{
144
+ hash: `0x${string}`;
145
+ }>;
146
+ /**
147
+ * Admin: set or replace the verifier for a namespace.
148
+ */
149
+ setVerifier: (namespace: string, verifier: Address) => Promise<{
150
+ hash: `0x${string}`;
151
+ }>;
152
+ /**
153
+ * Compute the deterministic identifier for a namespace + canonical string.
154
+ */
155
+ toId: (namespace: string, canonicalString: string) => `0x${string}`;
156
+ /**
157
+ * Check whether the IdentityAccount for an identifier has been deployed.
158
+ * Returns false if the deposit address has no code (not yet deployed).
159
+ * The registry deploys it automatically during claim(), but funders can
160
+ * send tokens before it's deployed — the address is always the same.
161
+ */
162
+ isAccountDeployed: (id: `0x${string}`) => Promise<boolean>;
163
+ /**
164
+ * Resolve the full state of an identifier: owner, deposit address, and
165
+ * ERC-20 balance — all in a single parallel batch of RPC calls.
166
+ *
167
+ * @example
168
+ * const state = await sdk.registry.resolveIdentifier("github", "org/repo", tokenAddress)
169
+ * // state.depositAddress — where funders should send tokens
170
+ * // state.owner — null if unclaimed
171
+ * // state.balance — claimable token balance at the deposit address
172
+ */
173
+ resolveIdentifier: (namespace: string, rawCanonicalString: string, token?: Address) => Promise<IdentifierState>;
174
+ /**
175
+ * Resolve any free-form identifier string to its on-chain state.
176
+ * Accepts namespace:value, URLs, and domain names.
177
+ *
178
+ * @example
179
+ * sdk.registry.resolve("github:org/repo")
180
+ * sdk.registry.resolve("github.com/org/repo")
181
+ * sdk.registry.resolve("https://github.com/org/repo")
182
+ * sdk.registry.resolve("dns:example.com")
183
+ * sdk.registry.resolve("www.example.com")
184
+ * sdk.registry.resolve("npm:package-name")
185
+ * sdk.registry.resolve("npmjs.com/package/foo")
186
+ */
187
+ resolve: (input: string, token?: Address) => Promise<IdentifierState>;
188
+ };
189
+
190
+ type ChainDeployments = {
191
+ IdentityAccount: {
192
+ abi: unknown;
193
+ };
194
+ };
195
+ declare function createAccountMethods(wallet: WalletClient | undefined, publicClient: PublicClient, deployments: ChainDeployments): {
196
+ /**
197
+ * Execute an arbitrary call through an IdentityAccount.
198
+ * Only the registered owner of the identifier can call this.
199
+ */
200
+ execute: (accountAddress: Address, target: Address, data: `0x${string}`, value?: bigint) => Promise<{
201
+ hash: `0x${string}`;
202
+ }>;
203
+ /**
204
+ * Encode an ERC-20 transfer from the identity account to a recipient.
205
+ *
206
+ * @example
207
+ * const { target, data } = sdk.account.encodeERC20Transfer(tokenAddress, recipient, amount);
208
+ * await sdk.account.execute(accountAddress, target, data);
209
+ */
210
+ encodeERC20Transfer: (token: Address, to: Address, amount: bigint) => {
211
+ target: `0x${string}`;
212
+ data: `0x${string}`;
213
+ };
214
+ /**
215
+ * Encode a Splits Warehouse withdrawal to pull tokens owed to the identity account.
216
+ *
217
+ * @example
218
+ * const { target, data } = sdk.account.encodeWarehouseWithdraw(warehouseAddress, accountAddress, tokenAddress);
219
+ * await sdk.account.execute(accountAddress, target, data);
220
+ */
221
+ encodeWarehouseWithdraw: (warehouse: Address, owner: Address, token: Address) => {
222
+ target: `0x${string}`;
223
+ data: `0x${string}`;
224
+ };
225
+ /**
226
+ * Encode an ERC-721 transfer from the identity account.
227
+ *
228
+ * @example
229
+ * const { target, data } = sdk.account.encodeERC721Transfer(nftAddress, accountAddress, recipient, tokenId);
230
+ * await sdk.account.execute(accountAddress, target, data);
231
+ */
232
+ encodeERC721Transfer: (nft: Address, from: Address, to: Address, tokenId: bigint) => {
233
+ target: `0x${string}`;
234
+ data: `0x${string}`;
235
+ };
236
+ };
237
+
238
+ /**
239
+ * Execute a transaction and extract a specific event from the logs.
240
+ */
241
+ declare function writeAndParse<T>(wallet: WalletClient, hash: `0x${string}`, abi: Abi, eventName: string): Promise<T>;
242
+ /**
243
+ * Execute a transaction without parsing events, just wait for confirmation.
244
+ */
245
+ declare function writeAndWait(wallet: WalletClient, hash: `0x${string}`): Promise<{
246
+ hash: `0x${string}`;
247
+ }>;
248
+
249
+ type EntityRegistryProviderProps<T extends EntityRegistrySDK> = PropsWithChildren<{
250
+ client?: WalletClient;
251
+ defaultChain?: SupportedChainId;
252
+ }>;
253
+ declare function EntityRegistryProvider<T extends EntityRegistrySDK = EntityRegistrySDK>({ children, client, defaultChain, }: EntityRegistryProviderProps<T>): React.ReactNode;
254
+ declare function useEntityRegistrySDK<T extends EntityRegistrySDK = EntityRegistrySDK>(): {
255
+ sdk: T | null;
256
+ };
257
+
258
+ declare const INVALIDATION_TIMEOUT_MS = 3000;
259
+ declare function useInvalidate(): (queryKeys: unknown[][]) => void;
260
+
261
+ type QueryOptions$1 = {
262
+ enabled?: boolean;
263
+ refetchInterval?: number;
264
+ };
265
+ declare function useOwnerOf(id: `0x${string}` | undefined, opts?: QueryOptions$1): UseQueryResult<Address | null>;
266
+ declare function usePredictAddress(id: `0x${string}` | undefined, opts?: QueryOptions$1): UseQueryResult<Address | null>;
267
+ declare function useToId(namespace: string | undefined, canonicalString: string | undefined, opts?: QueryOptions$1): UseQueryResult<`0x${string}` | null>;
268
+ declare function useClaim(opts?: UseMutationOptions<{
269
+ hash: `0x${string}`;
270
+ }, Error, {
271
+ input: string;
272
+ proof: `0x${string}`;
273
+ }>): _tanstack_react_query.UseMutationResult<{
274
+ hash: `0x${string}`;
275
+ }, Error, {
276
+ input: string;
277
+ proof: `0x${string}`;
278
+ }, unknown>;
279
+ declare function useRevoke(opts?: UseMutationOptions<{
280
+ hash: `0x${string}`;
281
+ }, Error, {
282
+ input: string;
283
+ }>): _tanstack_react_query.UseMutationResult<{
284
+ hash: `0x${string}`;
285
+ }, Error, {
286
+ input: string;
287
+ }, unknown>;
288
+ declare function useLinkIds(opts?: UseMutationOptions<{
289
+ hash: `0x${string}`;
290
+ }, Error, {
291
+ primaryId: `0x${string}`;
292
+ aliasIds: `0x${string}`[];
293
+ }>): _tanstack_react_query.UseMutationResult<{
294
+ hash: `0x${string}`;
295
+ }, Error, {
296
+ primaryId: `0x${string}`;
297
+ aliasIds: `0x${string}`[];
298
+ }, unknown>;
299
+ declare function useUnlinkIds(opts?: UseMutationOptions<{
300
+ hash: `0x${string}`;
301
+ }, Error, {
302
+ primaryId: `0x${string}`;
303
+ aliasIds: `0x${string}`[];
304
+ }>): _tanstack_react_query.UseMutationResult<{
305
+ hash: `0x${string}`;
306
+ }, Error, {
307
+ primaryId: `0x${string}`;
308
+ aliasIds: `0x${string}`[];
309
+ }, unknown>;
310
+ declare function useDeployAccount(opts?: UseMutationOptions<{
311
+ hash: `0x${string}`;
312
+ }, Error, {
313
+ id: `0x${string}`;
314
+ }>): _tanstack_react_query.UseMutationResult<{
315
+ hash: `0x${string}`;
316
+ }, Error, {
317
+ id: `0x${string}`;
318
+ }, unknown>;
319
+
320
+ declare function useExecute(opts?: UseMutationOptions<{
321
+ hash: `0x${string}`;
322
+ }, Error, {
323
+ accountAddress: Address;
324
+ target: Address;
325
+ data: `0x${string}`;
326
+ value?: bigint;
327
+ }>): _tanstack_react_query.UseMutationResult<{
328
+ hash: `0x${string}`;
329
+ }, Error, {
330
+ accountAddress: Address;
331
+ target: Address;
332
+ data: `0x${string}`;
333
+ value?: bigint;
334
+ }, unknown>;
335
+
336
+ type QueryOptions = {
337
+ enabled?: boolean;
338
+ refetchInterval?: number;
339
+ };
340
+ declare function useIdentifiers(variables?: QueryVariables<IdentifierFilter>, opts?: QueryOptions): UseQueryResult<Page<Identifier> | null>;
341
+ declare function useIdentifier(id: `0x${string}` | undefined, opts?: QueryOptions): UseQueryResult<Identifier | null>;
342
+ declare function useAliases(variables?: QueryVariables<AliasFilter>, opts?: QueryOptions): UseQueryResult<Page<IdentifierAlias> | null>;
343
+ declare function useRegistryStats(opts?: QueryOptions): UseQueryResult<RegistryStats | null>;
344
+
345
+ type TokenConfig = {
346
+ address: Address;
347
+ symbol: string;
348
+ name: string;
349
+ decimals: number;
350
+ logoURI?: string;
351
+ };
352
+ /**
353
+ * Native ETH address per ERC-7528 standard
354
+ * Used throughout the system to represent native ETH
355
+ */
356
+ declare const NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
357
+ declare const isNativeToken: (token?: string) => boolean;
358
+ /**
359
+ * Native ETH token config
360
+ */
361
+ declare const ETH_TOKEN: TokenConfig;
362
+ /**
363
+ * Get all available tokens for a chain
364
+ */
365
+ declare function getTokens(chainId: number): TokenConfig[];
366
+ /**
367
+ * Get a token by symbol for a chain
368
+ */
369
+ declare function getToken(chainId: number, symbol: string): TokenConfig | undefined;
370
+ /**
371
+ * Get a token by address for a chain
372
+ */
373
+ declare function getTokenByAddress(chainId: number, address: Address): TokenConfig | undefined;
374
+ /**
375
+ * Get token addresses for a chain (useful for indexer)
376
+ */
377
+ declare function getTokenAddresses(chainId: number): Address[];
378
+
379
+ /**
380
+ * Default canonicalisation: lowercase, trim whitespace, strip trailing slash.
381
+ * Baseline for all namespaces (github, dns).
382
+ * The contract does not enforce any normalisation — consistency is the caller's
383
+ * responsibility.
384
+ */
385
+ declare function canonicalise(value: string): string;
386
+ /**
387
+ * Derive the bytes32 identifier for a (namespace, canonicalString) pair.
388
+ * Matches: keccak256(abi.encode(namespace, canonicalString))
389
+ *
390
+ * This is a pure local computation — no RPC call required.
391
+ */
392
+ declare function toId(namespace: string, canonicalString: string): Hex;
393
+ /**
394
+ * Format namespace + canonicalString into a human-readable identifier string.
395
+ * e.g. formatIdentifier("github", "org/repo") → "github:org/repo"
396
+ */
397
+ declare function formatIdentifier(namespace: string, canonicalString: string): string;
398
+ /**
399
+ * Parse a colon-separated identifier string into its parts.
400
+ * e.g. parseIdentifier("github:org/repo") → { namespace: "github", canonicalString: "org/repo" }
401
+ */
402
+ declare function parseIdentifier(identifier: string): {
403
+ namespace: string;
404
+ canonicalString: string;
405
+ };
406
+ type ParsedUrl = {
407
+ namespace: string;
408
+ canonicalString: string;
409
+ /** The normalised form, suitable for display: e.g. "github:org/repo" */
410
+ formatted: string;
411
+ };
412
+ /**
413
+ * Parse a free-form URL or handle into a registry identifier.
414
+ *
415
+ * Accepts all of the following for a GitHub repo:
416
+ * github.com/org/repo
417
+ * https://github.com/org/repo
418
+ * https://www.github.com/org/repo/tree/main (extra path segments ignored)
419
+ *
420
+ * Accepts all of the following for a DNS domain:
421
+ * example.com
422
+ * https://example.com
423
+ * https://www.example.com/some/path (path ignored)
424
+ *
425
+ * Throws if the input cannot be mapped to a known namespace.
426
+ */
427
+ declare function parseUrl(input: string): ParsedUrl;
428
+ /**
429
+ * Parse any free-form identifier string into namespace + canonicalString.
430
+ *
431
+ * Handles all of these forms:
432
+ * github:org/repo → namespace:value (explicit prefix)
433
+ * dns:example.com → namespace:value
434
+ * npm:package-name → namespace:value
435
+ * github.com/org/repo → URL-style
436
+ * https://github.com/... → URL-style
437
+ * www.example.com → URL-style
438
+ */
439
+ declare function parseAnyIdentifier(input: string): {
440
+ namespace: string;
441
+ canonicalString: string;
442
+ };
443
+ /**
444
+ * Derive the beacon address from the registry address.
445
+ *
446
+ * The beacon is deployed with `new UpgradeableBeacon(...)` as the first
447
+ * contract created in the EntityRegistry constructor. Per EIP-161, a new
448
+ * contract starts with nonce=1, so the beacon address is the CREATE address
449
+ * of (registryAddress, nonce=1).
450
+ *
451
+ * This is a pure local computation — no RPC call required.
452
+ */
453
+ declare function deriveBeaconAddress(registryAddress: Address): Address;
454
+ /**
455
+ * Compute the deterministic deposit address for any identifier.
456
+ * This is a pure local computation — no RPC call required.
457
+ *
458
+ * The address is stable whether or not the escrow proxy has been deployed,
459
+ * and does NOT change if the escrow implementation is upgraded via the beacon.
460
+ *
461
+ * @param id bytes32 identifier from toId()
462
+ * @param registryAddress deployed EntityRegistry address
463
+ * @param beaconProxyBytecode creation bytecode of OpenZeppelin BeaconProxy
464
+ * (available as deployments.beaconProxyBytecode)
465
+ */
466
+ declare function resolveDepositAddress(id: Hex, registryAddress: Address, beaconProxyBytecode: Hex): Address;
467
+
468
+ declare class EntityRegistrySDK {
469
+ #private;
470
+ registry: ReturnType<typeof createRegistryMethods>;
471
+ account: ReturnType<typeof createAccountMethods>;
472
+ constructor(wallet?: WalletClient, defaultChain?: SupportedChainId);
473
+ get wallet(): WalletClient | undefined;
474
+ get publicClient(): PublicClient;
475
+ get chainId(): SupportedChainId;
476
+ get indexer(): Indexer | null;
477
+ }
478
+
479
+ export { type AliasFilter, ETH_TOKEN, EntityRegistryProvider, EntityRegistrySDK, INVALIDATION_TIMEOUT_MS, type Identifier, type IdentifierAlias, type IdentifierFilter, type IdentifierState, type Indexer, type IndexerExtension, NATIVE_TOKEN, type Page, type ParsedUrl, type QueryVariables, type RegistryStats, type StatsResponse, type SupportedChainId, type TokenConfig, canonicalise, config, createIndexer, deriveBeaconAddress, formatIdentifier, getToken, getTokenAddresses, getTokenByAddress, getTokens, isNativeToken, parseAnyIdentifier, parseIdentifier, parseUrl, resolveDepositAddress, toId, useAliases, useClaim, useDeployAccount, useEntityRegistrySDK, useExecute, useIdentifier, useIdentifiers, useInvalidate, useLinkIds, useOwnerOf, usePredictAddress, useRegistryStats, useRevoke, useToId, useUnlinkIds, writeAndParse, writeAndWait };