@ensnode/ensrainbow-sdk 0.33.0 → 0.34.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/client.d.ts +48 -15
- package/dist/client.js +51 -19
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +1 -3
- package/dist/index.js +55 -46
- package/dist/index.js.map +1 -1
- package/package.json +4 -8
- package/dist/label-utils.d.ts +0 -3
- package/dist/label-utils.js +0 -29
- package/dist/label-utils.js.map +0 -1
- package/dist/labelUtils.d.ts +0 -12
- package/dist/labelUtils.js +0 -29
- package/dist/labelUtils.js.map +0 -1
package/dist/client.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { LabelHash, Label } from '@ensnode/ensnode-sdk';
|
|
1
|
+
import { EnsRainbowClientLabelSet, LabelHash, Label, EnsRainbowServerLabelSet } from '@ensnode/ensnode-sdk';
|
|
2
2
|
|
|
3
3
|
declare namespace EnsRainbow {
|
|
4
4
|
export type ApiClientOptions = EnsRainbowApiClientOptions;
|
|
5
5
|
export interface ApiClient {
|
|
6
6
|
count(): Promise<CountResponse>;
|
|
7
|
+
/**
|
|
8
|
+
* Heal a labelhash to its original label
|
|
9
|
+
* @param labelHash The labelhash to heal
|
|
10
|
+
*/
|
|
7
11
|
heal(labelHash: LabelHash): Promise<HealResponse>;
|
|
8
12
|
health(): Promise<HealthResponse>;
|
|
9
13
|
version(): Promise<VersionResponse>;
|
|
@@ -59,7 +63,8 @@ declare namespace EnsRainbow {
|
|
|
59
63
|
}
|
|
60
64
|
export interface CountSuccess extends BaseCountResponse<typeof StatusCode.Success, never> {
|
|
61
65
|
status: typeof StatusCode.Success;
|
|
62
|
-
/** The total count of labels that can be healed by the ENSRainbow instance. Always a
|
|
66
|
+
/** The total count of labels that can be healed by the ENSRainbow instance. Always a
|
|
67
|
+
* non-negative integer. */
|
|
63
68
|
count: number;
|
|
64
69
|
timestamp: string;
|
|
65
70
|
error?: never;
|
|
@@ -82,9 +87,13 @@ declare namespace EnsRainbow {
|
|
|
82
87
|
*/
|
|
83
88
|
version: string;
|
|
84
89
|
/**
|
|
85
|
-
* ENSRainbow schema version.
|
|
90
|
+
* ENSRainbow database schema version.
|
|
86
91
|
*/
|
|
87
|
-
|
|
92
|
+
dbSchemaVersion: number;
|
|
93
|
+
/**
|
|
94
|
+
* The EnsRainbowServerLabelSet managed by the ENSRainbow server.
|
|
95
|
+
*/
|
|
96
|
+
labelSet: EnsRainbowServerLabelSet;
|
|
88
97
|
}
|
|
89
98
|
/**
|
|
90
99
|
* Interface for the version endpoint response
|
|
@@ -106,6 +115,22 @@ interface EnsRainbowApiClientOptions {
|
|
|
106
115
|
* The URL of an ENSRainbow API endpoint.
|
|
107
116
|
*/
|
|
108
117
|
endpointUrl: URL;
|
|
118
|
+
/**
|
|
119
|
+
* Optional label set preferences that the ENSRainbow server at endpointUrl is expected to
|
|
120
|
+
* support. If provided, enables deterministic heal results across time, such that only
|
|
121
|
+
* labels from label sets with versions less than or equal to this value will be returned.
|
|
122
|
+
* Therefore, even if the ENSRainbow server later ingests label sets with greater versions
|
|
123
|
+
* than this value, the results returned across time can be deterministic. If
|
|
124
|
+
* provided, heal operations with this EnsRainbowApiClient will validate the ENSRainbow
|
|
125
|
+
* server manages a compatible label set. If not provided no specific labelSetId validation
|
|
126
|
+
* will be performed during heal operations.
|
|
127
|
+
* If `labelSetId` is provided without `labelSetVersion`, the server will use the latest
|
|
128
|
+
* available version.
|
|
129
|
+
* If `labelSetVersion` is defined, only labels from sets less than or equal to this value
|
|
130
|
+
* will be returned.
|
|
131
|
+
* When `labelSetVersion` is defined, `labelSetId` must also be defined.
|
|
132
|
+
*/
|
|
133
|
+
labelSet?: EnsRainbowClientLabelSet;
|
|
109
134
|
}
|
|
110
135
|
/**
|
|
111
136
|
* ENSRainbow API client
|
|
@@ -123,6 +148,7 @@ interface EnsRainbowApiClientOptions {
|
|
|
123
148
|
declare class EnsRainbowApiClient implements EnsRainbow.ApiClient {
|
|
124
149
|
private readonly options;
|
|
125
150
|
private readonly cache;
|
|
151
|
+
private readonly labelSetSearchParams;
|
|
126
152
|
static readonly DEFAULT_CACHE_CAPACITY = 1000;
|
|
127
153
|
/**
|
|
128
154
|
* Create default client options.
|
|
@@ -143,8 +169,8 @@ declare class EnsRainbowApiClient implements EnsRainbow.ApiClient {
|
|
|
143
169
|
*
|
|
144
170
|
* @param labelHash all lowercase 64-digit hex string with 0x prefix (total length of 66 characters)
|
|
145
171
|
* @returns a `HealResponse` indicating the result of the request and the healed label if successful
|
|
146
|
-
* @throws if the request fails due to network failures, DNS lookup failures, request timeouts,
|
|
147
|
-
*
|
|
172
|
+
* @throws if the request fails due to network failures, DNS lookup failures, request timeouts,
|
|
173
|
+
* CORS violations, or Invalid URLs
|
|
148
174
|
* @example
|
|
149
175
|
* ```typescript
|
|
150
176
|
* const response = await client.heal(
|
|
@@ -177,9 +203,10 @@ declare class EnsRainbowApiClient implements EnsRainbow.ApiClient {
|
|
|
177
203
|
/**
|
|
178
204
|
* Get Count of Healable Labels
|
|
179
205
|
*
|
|
180
|
-
* @returns a `CountResponse` indicating the result and the timestamp of the request and the
|
|
181
|
-
*
|
|
182
|
-
*
|
|
206
|
+
* @returns a `CountResponse` indicating the result and the timestamp of the request and the
|
|
207
|
+
* number of healable labels if successful
|
|
208
|
+
* @throws if the request fails due to network failures, DNS lookup failures, request timeouts,
|
|
209
|
+
* CORS violations, or Invalid URLs
|
|
183
210
|
* @example
|
|
184
211
|
*
|
|
185
212
|
* const response = await client.count();
|
|
@@ -196,8 +223,8 @@ declare class EnsRainbowApiClient implements EnsRainbow.ApiClient {
|
|
|
196
223
|
count(): Promise<EnsRainbow.CountResponse>;
|
|
197
224
|
/**
|
|
198
225
|
*
|
|
199
|
-
* Simple verification that the service is running, either in your local setup or for the
|
|
200
|
-
*
|
|
226
|
+
* Simple verification that the service is running, either in your local setup or for the
|
|
227
|
+
* provided hosted instance.
|
|
201
228
|
* @returns a status of ENS Rainbow service
|
|
202
229
|
* @example
|
|
203
230
|
*
|
|
@@ -214,8 +241,8 @@ declare class EnsRainbowApiClient implements EnsRainbow.ApiClient {
|
|
|
214
241
|
* Get the version information of the ENSRainbow service
|
|
215
242
|
*
|
|
216
243
|
* @returns the version information of the ENSRainbow service
|
|
217
|
-
* @throws if the request fails due to network failures, DNS lookup failures, request
|
|
218
|
-
*
|
|
244
|
+
* @throws if the request fails due to network failures, DNS lookup failures, request
|
|
245
|
+
* timeouts, CORS violations, or invalid URLs
|
|
219
246
|
* @example
|
|
220
247
|
* ```typescript
|
|
221
248
|
* const response = await client.version();
|
|
@@ -224,8 +251,14 @@ declare class EnsRainbowApiClient implements EnsRainbow.ApiClient {
|
|
|
224
251
|
*
|
|
225
252
|
* // {
|
|
226
253
|
* // "status": "success",
|
|
227
|
-
* // "
|
|
228
|
-
* //
|
|
254
|
+
* // "versionInfo": {
|
|
255
|
+
* // "version": "0.1.0",
|
|
256
|
+
* // "dbSchemaVersion": 2,
|
|
257
|
+
* // "labelSet": {
|
|
258
|
+
* // "labelSetId": "subgraph",
|
|
259
|
+
* // "labelSetVersion": 0
|
|
260
|
+
* // }
|
|
261
|
+
* // }
|
|
229
262
|
* // }
|
|
230
263
|
* ```
|
|
231
264
|
*/
|
package/dist/client.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
// src/client.ts
|
|
2
2
|
import { LruCache } from "@ensnode/ensnode-sdk";
|
|
3
|
+
import {
|
|
4
|
+
buildEnsRainbowClientLabelSet
|
|
5
|
+
} from "@ensnode/ensnode-sdk";
|
|
3
6
|
|
|
4
7
|
// src/consts.ts
|
|
5
8
|
var DEFAULT_ENSRAINBOW_URL = "https://api.ensrainbow.io";
|
|
@@ -17,6 +20,7 @@ var ErrorCode = {
|
|
|
17
20
|
var EnsRainbowApiClient = class _EnsRainbowApiClient {
|
|
18
21
|
options;
|
|
19
22
|
cache;
|
|
23
|
+
labelSetSearchParams;
|
|
20
24
|
static DEFAULT_CACHE_CAPACITY = 1e3;
|
|
21
25
|
/**
|
|
22
26
|
* Create default client options.
|
|
@@ -26,17 +30,35 @@ var EnsRainbowApiClient = class _EnsRainbowApiClient {
|
|
|
26
30
|
static defaultOptions() {
|
|
27
31
|
return {
|
|
28
32
|
endpointUrl: new URL(DEFAULT_ENSRAINBOW_URL),
|
|
29
|
-
cacheCapacity: _EnsRainbowApiClient.DEFAULT_CACHE_CAPACITY
|
|
33
|
+
cacheCapacity: _EnsRainbowApiClient.DEFAULT_CACHE_CAPACITY,
|
|
34
|
+
labelSet: buildEnsRainbowClientLabelSet()
|
|
30
35
|
};
|
|
31
36
|
}
|
|
32
37
|
constructor(options = {}) {
|
|
38
|
+
const { labelSet: optionsLabelSet, ...rest } = options;
|
|
39
|
+
const defaultOptions = _EnsRainbowApiClient.defaultOptions();
|
|
40
|
+
const copiedLabelSet = buildEnsRainbowClientLabelSet(
|
|
41
|
+
optionsLabelSet?.labelSetId,
|
|
42
|
+
optionsLabelSet?.labelSetVersion
|
|
43
|
+
);
|
|
33
44
|
this.options = {
|
|
34
|
-
...
|
|
35
|
-
...
|
|
45
|
+
...defaultOptions,
|
|
46
|
+
...rest,
|
|
47
|
+
labelSet: copiedLabelSet
|
|
36
48
|
};
|
|
37
49
|
this.cache = new LruCache(
|
|
38
50
|
this.options.cacheCapacity
|
|
39
51
|
);
|
|
52
|
+
this.labelSetSearchParams = new URLSearchParams();
|
|
53
|
+
if (this.options.labelSet?.labelSetId !== void 0) {
|
|
54
|
+
this.labelSetSearchParams.append("label_set_id", this.options.labelSet.labelSetId);
|
|
55
|
+
}
|
|
56
|
+
if (this.options.labelSet?.labelSetVersion !== void 0) {
|
|
57
|
+
this.labelSetSearchParams.append(
|
|
58
|
+
"label_set_version",
|
|
59
|
+
this.options.labelSet.labelSetVersion.toString()
|
|
60
|
+
);
|
|
61
|
+
}
|
|
40
62
|
}
|
|
41
63
|
/**
|
|
42
64
|
* Attempt to heal a labelHash to its original label.
|
|
@@ -50,8 +72,8 @@ var EnsRainbowApiClient = class _EnsRainbowApiClient {
|
|
|
50
72
|
*
|
|
51
73
|
* @param labelHash all lowercase 64-digit hex string with 0x prefix (total length of 66 characters)
|
|
52
74
|
* @returns a `HealResponse` indicating the result of the request and the healed label if successful
|
|
53
|
-
* @throws if the request fails due to network failures, DNS lookup failures, request timeouts,
|
|
54
|
-
*
|
|
75
|
+
* @throws if the request fails due to network failures, DNS lookup failures, request timeouts,
|
|
76
|
+
* CORS violations, or Invalid URLs
|
|
55
77
|
* @example
|
|
56
78
|
* ```typescript
|
|
57
79
|
* const response = await client.heal(
|
|
@@ -82,10 +104,12 @@ var EnsRainbowApiClient = class _EnsRainbowApiClient {
|
|
|
82
104
|
*/
|
|
83
105
|
async heal(labelHash) {
|
|
84
106
|
const cachedResult = this.cache.get(labelHash);
|
|
85
|
-
if (cachedResult)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
107
|
+
if (cachedResult) return cachedResult;
|
|
108
|
+
const url = new URL(`/v1/heal/${labelHash}`, this.options.endpointUrl);
|
|
109
|
+
this.labelSetSearchParams.forEach((value, key) => {
|
|
110
|
+
url.searchParams.append(key, value);
|
|
111
|
+
});
|
|
112
|
+
const response = await fetch(url);
|
|
89
113
|
const healResponse = await response.json();
|
|
90
114
|
if (isCacheableHealResponse(healResponse)) {
|
|
91
115
|
this.cache.set(labelHash, healResponse);
|
|
@@ -95,9 +119,10 @@ var EnsRainbowApiClient = class _EnsRainbowApiClient {
|
|
|
95
119
|
/**
|
|
96
120
|
* Get Count of Healable Labels
|
|
97
121
|
*
|
|
98
|
-
* @returns a `CountResponse` indicating the result and the timestamp of the request and the
|
|
99
|
-
*
|
|
100
|
-
*
|
|
122
|
+
* @returns a `CountResponse` indicating the result and the timestamp of the request and the
|
|
123
|
+
* number of healable labels if successful
|
|
124
|
+
* @throws if the request fails due to network failures, DNS lookup failures, request timeouts,
|
|
125
|
+
* CORS violations, or Invalid URLs
|
|
101
126
|
* @example
|
|
102
127
|
*
|
|
103
128
|
* const response = await client.count();
|
|
@@ -117,8 +142,8 @@ var EnsRainbowApiClient = class _EnsRainbowApiClient {
|
|
|
117
142
|
}
|
|
118
143
|
/**
|
|
119
144
|
*
|
|
120
|
-
* Simple verification that the service is running, either in your local setup or for the
|
|
121
|
-
*
|
|
145
|
+
* Simple verification that the service is running, either in your local setup or for the
|
|
146
|
+
* provided hosted instance.
|
|
122
147
|
* @returns a status of ENS Rainbow service
|
|
123
148
|
* @example
|
|
124
149
|
*
|
|
@@ -138,8 +163,8 @@ var EnsRainbowApiClient = class _EnsRainbowApiClient {
|
|
|
138
163
|
* Get the version information of the ENSRainbow service
|
|
139
164
|
*
|
|
140
165
|
* @returns the version information of the ENSRainbow service
|
|
141
|
-
* @throws if the request fails due to network failures, DNS lookup failures, request
|
|
142
|
-
*
|
|
166
|
+
* @throws if the request fails due to network failures, DNS lookup failures, request
|
|
167
|
+
* timeouts, CORS violations, or invalid URLs
|
|
143
168
|
* @example
|
|
144
169
|
* ```typescript
|
|
145
170
|
* const response = await client.version();
|
|
@@ -148,8 +173,14 @@ var EnsRainbowApiClient = class _EnsRainbowApiClient {
|
|
|
148
173
|
*
|
|
149
174
|
* // {
|
|
150
175
|
* // "status": "success",
|
|
151
|
-
* // "
|
|
152
|
-
* //
|
|
176
|
+
* // "versionInfo": {
|
|
177
|
+
* // "version": "0.1.0",
|
|
178
|
+
* // "dbSchemaVersion": 2,
|
|
179
|
+
* // "labelSet": {
|
|
180
|
+
* // "labelSetId": "subgraph",
|
|
181
|
+
* // "labelSetVersion": 0
|
|
182
|
+
* // }
|
|
183
|
+
* // }
|
|
153
184
|
* // }
|
|
154
185
|
* ```
|
|
155
186
|
*/
|
|
@@ -165,7 +196,8 @@ var EnsRainbowApiClient = class _EnsRainbowApiClient {
|
|
|
165
196
|
getOptions() {
|
|
166
197
|
const deepCopy = {
|
|
167
198
|
cacheCapacity: this.options.cacheCapacity,
|
|
168
|
-
endpointUrl: new URL(this.options.endpointUrl.href)
|
|
199
|
+
endpointUrl: new URL(this.options.endpointUrl.href),
|
|
200
|
+
labelSet: this.options.labelSet ? { ...this.options.labelSet } : void 0
|
|
169
201
|
};
|
|
170
202
|
return Object.freeze(deepCopy);
|
|
171
203
|
}
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/consts.ts"],"sourcesContent":["import { type Cache, Label, type LabelHash, LruCache } from \"@ensnode/ensnode-sdk\";\nimport { DEFAULT_ENSRAINBOW_URL, ErrorCode, StatusCode } from \"./consts\";\n\nexport namespace EnsRainbow {\n export type ApiClientOptions = EnsRainbowApiClientOptions;\n\n export interface ApiClient {\n count(): Promise<CountResponse>;\n\n heal(labelHash: LabelHash): Promise<HealResponse>;\n\n health(): Promise<HealthResponse>;\n\n version(): Promise<VersionResponse>;\n\n getOptions(): Readonly<EnsRainbowApiClientOptions>;\n }\n\n type StatusCode = (typeof StatusCode)[keyof typeof StatusCode];\n\n type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];\n\n export interface HealthResponse {\n status: \"ok\";\n }\n\n export interface BaseHealResponse<Status extends StatusCode, Error extends ErrorCode> {\n status: Status;\n label?: Label | never;\n error?: string | never;\n errorCode?: Error | never;\n }\n\n export interface HealSuccess extends BaseHealResponse<typeof StatusCode.Success, never> {\n status: typeof StatusCode.Success;\n label: Label;\n error?: never;\n errorCode?: never;\n }\n\n export interface HealNotFoundError\n extends BaseHealResponse<typeof StatusCode.Error, typeof ErrorCode.NotFound> {\n status: typeof StatusCode.Error;\n label?: never;\n error: string;\n errorCode: typeof ErrorCode.NotFound;\n }\n\n export interface HealServerError\n extends BaseHealResponse<typeof StatusCode.Error, typeof ErrorCode.ServerError> {\n status: typeof StatusCode.Error;\n label?: never;\n error: string;\n errorCode: typeof ErrorCode.ServerError;\n }\n\n export interface HealBadRequestError\n extends BaseHealResponse<typeof StatusCode.Error, typeof ErrorCode.BadRequest> {\n status: typeof StatusCode.Error;\n label?: never;\n error: string;\n errorCode: typeof ErrorCode.BadRequest;\n }\n\n export type HealResponse =\n | HealSuccess\n | HealNotFoundError\n | HealServerError\n | HealBadRequestError;\n export type HealError = Exclude<HealResponse, HealSuccess>;\n\n /**\n * Server errors should not be cached.\n */\n export type CacheableHealResponse = Exclude<HealResponse, HealServerError>;\n\n export interface BaseCountResponse<Status extends StatusCode, Error extends ErrorCode> {\n status: Status;\n count?: number | never;\n timestamp?: string | never;\n error?: string | never;\n errorCode?: Error | never;\n }\n\n export interface CountSuccess extends BaseCountResponse<typeof StatusCode.Success, never> {\n status: typeof StatusCode.Success;\n /** The total count of labels that can be healed by the ENSRainbow instance. Always a non-negative integer. */\n count: number;\n timestamp: string;\n error?: never;\n errorCode?: never;\n }\n\n export interface CountServerError\n extends BaseCountResponse<typeof StatusCode.Error, typeof ErrorCode.ServerError> {\n status: typeof StatusCode.Error;\n count?: never;\n timestamp?: never;\n error: string;\n errorCode: typeof ErrorCode.ServerError;\n }\n\n export type CountResponse = CountSuccess | CountServerError;\n\n /**\n * ENSRainbow version information.\n */\n export interface VersionInfo {\n /**\n * ENSRainbow version.\n */\n version: string;\n\n /**\n * ENSRainbow schema version.\n */\n schema_version: number;\n }\n\n /**\n * Interface for the version endpoint response\n */\n export interface VersionResponse {\n status: typeof StatusCode.Success;\n versionInfo: VersionInfo;\n }\n}\n\nexport interface EnsRainbowApiClientOptions {\n /**\n * The maximum number of `HealResponse` values to cache.\n * Must be a non-negative integer.\n * Setting to 0 will disable caching.\n */\n cacheCapacity: number;\n\n /**\n * The URL of an ENSRainbow API endpoint.\n */\n endpointUrl: URL;\n}\n\n/**\n * ENSRainbow API client\n *\n * @example\n * ```typescript\n * // default options\n * const client = new EnsRainbowApiClient();\n * // custom options\n * const client = new EnsRainbowApiClient({\n * endpointUrl: new URL(\"https://api.ensrainbow.io\"),\n * });\n * ```\n */\nexport class EnsRainbowApiClient implements EnsRainbow.ApiClient {\n private readonly options: EnsRainbowApiClientOptions;\n private readonly cache: Cache<LabelHash, EnsRainbow.CacheableHealResponse>;\n\n public static readonly DEFAULT_CACHE_CAPACITY = 1000;\n\n /**\n * Create default client options.\n *\n * @returns default options\n */\n static defaultOptions(): EnsRainbow.ApiClientOptions {\n return {\n endpointUrl: new URL(DEFAULT_ENSRAINBOW_URL),\n cacheCapacity: EnsRainbowApiClient.DEFAULT_CACHE_CAPACITY,\n };\n }\n\n constructor(options: Partial<EnsRainbow.ApiClientOptions> = {}) {\n this.options = {\n ...EnsRainbowApiClient.defaultOptions(),\n ...options,\n };\n\n this.cache = new LruCache<LabelHash, EnsRainbow.CacheableHealResponse>(\n this.options.cacheCapacity,\n );\n }\n\n /**\n * Attempt to heal a labelHash to its original label.\n *\n * Note on returned labels: ENSRainbow returns labels exactly as they are\n * represented in source rainbow table data. This means:\n *\n * - Labels may or may not be ENS-normalized\n * - Labels can contain any valid string, including dots, null bytes, or be empty\n * - Clients should handle all possible string values appropriately\n *\n * @param labelHash all lowercase 64-digit hex string with 0x prefix (total length of 66 characters)\n * @returns a `HealResponse` indicating the result of the request and the healed label if successful\n * @throws if the request fails due to network failures, DNS lookup failures, request timeouts, CORS violations, or Invalid URLs\n *\n * @example\n * ```typescript\n * const response = await client.heal(\n * \"0xaf2caa1c2ca1d027f1ac823b529d0a67cd144264b2789fa2ea4d63a67c7103cc\"\n * );\n *\n * console.log(response);\n *\n * // Output:\n * // {\n * // status: \"success\",\n * // label: \"vitalik\"\n * // }\n *\n * const notFoundResponse = await client.heal(\n * \"0xf64dc17ae2e2b9b16dbcb8cb05f35a2e6080a5ff1dc53ac0bc48f0e79111f264\"\n * );\n *\n * console.log(notFoundResponse);\n *\n * // Output:\n * // {\n * // status: \"error\",\n * // error: \"Label not found\",\n * // errorCode: 404\n * // }\n * ```\n */\n async heal(labelHash: LabelHash): Promise<EnsRainbow.HealResponse> {\n const cachedResult = this.cache.get(labelHash);\n\n if (cachedResult) {\n return cachedResult;\n }\n\n const response = await fetch(new URL(`/v1/heal/${labelHash}`, this.options.endpointUrl));\n const healResponse = (await response.json()) as EnsRainbow.HealResponse;\n\n if (isCacheableHealResponse(healResponse)) {\n this.cache.set(labelHash, healResponse);\n }\n\n return healResponse;\n }\n\n /**\n * Get Count of Healable Labels\n *\n * @returns a `CountResponse` indicating the result and the timestamp of the request and the number of healable labels if successful\n * @throws if the request fails due to network failures, DNS lookup failures, request timeouts, CORS violations, or Invalid URLs\n *\n * @example\n *\n * const response = await client.count();\n *\n * console.log(response);\n *\n * // {\n * // \"status\": \"success\",\n * // \"count\": 133856894,\n * // \"timestamp\": \"2024-01-30T11:18:56Z\"\n * // }\n *\n */\n async count(): Promise<EnsRainbow.CountResponse> {\n const response = await fetch(new URL(\"/v1/labels/count\", this.options.endpointUrl));\n\n return response.json() as Promise<EnsRainbow.CountResponse>;\n }\n\n /**\n *\n * Simple verification that the service is running, either in your local setup or for the provided hosted instance\n *\n * @returns a status of ENS Rainbow service\n * @example\n *\n * const response = await client.health();\n *\n * console.log(response);\n *\n * // {\n * // \"status\": \"ok\",\n * // }\n */\n async health(): Promise<EnsRainbow.HealthResponse> {\n const response = await fetch(new URL(\"/health\", this.options.endpointUrl));\n\n return response.json() as Promise<EnsRainbow.HealthResponse>;\n }\n\n /**\n * Get the version information of the ENSRainbow service\n *\n * @returns the version information of the ENSRainbow service\n * @throws if the request fails due to network failures, DNS lookup failures, request timeouts, CORS violations, or Invalid URLs\n *\n * @example\n * ```typescript\n * const response = await client.version();\n *\n * console.log(response);\n *\n * // {\n * // \"status\": \"success\",\n * // \"version\": \"0.1.0\",\n * // \"schema_version\": 2\n * // }\n * ```\n */\n async version(): Promise<EnsRainbow.VersionResponse> {\n const response = await fetch(new URL(\"/v1/version\", this.options.endpointUrl));\n\n return response.json() as Promise<EnsRainbow.VersionResponse>;\n }\n\n /**\n * Get a copy of the current client options.\n *\n * @returns a copy of the current client options.\n */\n getOptions(): Readonly<EnsRainbowApiClientOptions> {\n // build a deep copy to prevent modification\n const deepCopy = {\n cacheCapacity: this.options.cacheCapacity,\n endpointUrl: new URL(this.options.endpointUrl.href),\n } satisfies EnsRainbowApiClientOptions;\n\n return Object.freeze(deepCopy);\n }\n}\n\n/**\n * Determine if a heal response is an error.\n *\n * @param response the heal response to check\n * @returns true if the response is an error, false otherwise\n */\nexport const isHealError = (\n response: EnsRainbow.HealResponse,\n): response is EnsRainbow.HealError => {\n return response.status === StatusCode.Error;\n};\n\n/**\n * Determine if a heal response is cacheable.\n *\n * Server errors at not cachable and should be retried.\n *\n * @param response the heal response to check\n * @returns true if the response is cacheable, false otherwise\n */\nexport const isCacheableHealResponse = (\n response: EnsRainbow.HealResponse,\n): response is EnsRainbow.CacheableHealResponse => {\n return response.status === StatusCode.Success || response.errorCode !== ErrorCode.ServerError;\n};\n","export const DEFAULT_ENSRAINBOW_URL = \"https://api.ensrainbow.io\" as const;\n\nexport const StatusCode = {\n Success: \"success\",\n Error: \"error\",\n} as const;\n\nexport const ErrorCode = {\n BadRequest: 400,\n NotFound: 404,\n ServerError: 500,\n} as const;\n"],"mappings":";AAAA,SAA4C,gBAAgB;;;ACArD,IAAM,yBAAyB;AAE/B,IAAM,aAAa;AAAA,EACxB,SAAS;AAAA,EACT,OAAO;AACT;AAEO,IAAM,YAAY;AAAA,EACvB,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,aAAa;AACf;;;ADgJO,IAAM,sBAAN,MAAM,qBAAoD;AAAA,EAC9C;AAAA,EACA;AAAA,EAEjB,OAAuB,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhD,OAAO,iBAA8C;AACnD,WAAO;AAAA,MACL,aAAa,IAAI,IAAI,sBAAsB;AAAA,MAC3C,eAAe,qBAAoB;AAAA,IACrC;AAAA,EACF;AAAA,EAEA,YAAY,UAAgD,CAAC,GAAG;AAC9D,SAAK,UAAU;AAAA,MACb,GAAG,qBAAoB,eAAe;AAAA,MACtC,GAAG;AAAA,IACL;AAEA,SAAK,QAAQ,IAAI;AAAA,MACf,KAAK,QAAQ;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4CA,MAAM,KAAK,WAAwD;AACjE,UAAM,eAAe,KAAK,MAAM,IAAI,SAAS;AAE7C,QAAI,cAAc;AAChB,aAAO;AAAA,IACT;AAEA,UAAM,WAAW,MAAM,MAAM,IAAI,IAAI,YAAY,SAAS,IAAI,KAAK,QAAQ,WAAW,CAAC;AACvF,UAAM,eAAgB,MAAM,SAAS,KAAK;AAE1C,QAAI,wBAAwB,YAAY,GAAG;AACzC,WAAK,MAAM,IAAI,WAAW,YAAY;AAAA,IACxC;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,QAA2C;AAC/C,UAAM,WAAW,MAAM,MAAM,IAAI,IAAI,oBAAoB,KAAK,QAAQ,WAAW,CAAC;AAElF,WAAO,SAAS,KAAK;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAM,SAA6C;AACjD,UAAM,WAAW,MAAM,MAAM,IAAI,IAAI,WAAW,KAAK,QAAQ,WAAW,CAAC;AAEzE,WAAO,SAAS,KAAK;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,UAA+C;AACnD,UAAM,WAAW,MAAM,MAAM,IAAI,IAAI,eAAe,KAAK,QAAQ,WAAW,CAAC;AAE7E,WAAO,SAAS,KAAK;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAmD;AAEjD,UAAM,WAAW;AAAA,MACf,eAAe,KAAK,QAAQ;AAAA,MAC5B,aAAa,IAAI,IAAI,KAAK,QAAQ,YAAY,IAAI;AAAA,IACpD;AAEA,WAAO,OAAO,OAAO,QAAQ;AAAA,EAC/B;AACF;AAQO,IAAM,cAAc,CACzB,aACqC;AACrC,SAAO,SAAS,WAAW,WAAW;AACxC;AAUO,IAAM,0BAA0B,CACrC,aACiD;AACjD,SAAO,SAAS,WAAW,WAAW,WAAW,SAAS,cAAc,UAAU;AACpF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/consts.ts"],"sourcesContent":["import { type Cache, Label, type LabelHash, LruCache } from \"@ensnode/ensnode-sdk\";\nimport {\n type EnsRainbowClientLabelSet,\n type EnsRainbowServerLabelSet,\n buildEnsRainbowClientLabelSet,\n} from \"@ensnode/ensnode-sdk\";\nimport { DEFAULT_ENSRAINBOW_URL, ErrorCode, StatusCode } from \"./consts\";\n\nexport namespace EnsRainbow {\n export type ApiClientOptions = EnsRainbowApiClientOptions;\n\n export interface ApiClient {\n count(): Promise<CountResponse>;\n\n /**\n * Heal a labelhash to its original label\n * @param labelHash The labelhash to heal\n */\n heal(labelHash: LabelHash): Promise<HealResponse>;\n\n health(): Promise<HealthResponse>;\n\n version(): Promise<VersionResponse>;\n\n getOptions(): Readonly<EnsRainbowApiClientOptions>;\n }\n\n type StatusCode = (typeof StatusCode)[keyof typeof StatusCode];\n\n type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];\n\n export interface HealthResponse {\n status: \"ok\";\n }\n\n export interface BaseHealResponse<Status extends StatusCode, Error extends ErrorCode> {\n status: Status;\n label?: Label | never;\n error?: string | never;\n errorCode?: Error | never;\n }\n\n export interface HealSuccess extends BaseHealResponse<typeof StatusCode.Success, never> {\n status: typeof StatusCode.Success;\n label: Label;\n error?: never;\n errorCode?: never;\n }\n\n export interface HealNotFoundError\n extends BaseHealResponse<typeof StatusCode.Error, typeof ErrorCode.NotFound> {\n status: typeof StatusCode.Error;\n label?: never;\n error: string;\n errorCode: typeof ErrorCode.NotFound;\n }\n\n export interface HealServerError\n extends BaseHealResponse<typeof StatusCode.Error, typeof ErrorCode.ServerError> {\n status: typeof StatusCode.Error;\n label?: never;\n error: string;\n errorCode: typeof ErrorCode.ServerError;\n }\n\n export interface HealBadRequestError\n extends BaseHealResponse<typeof StatusCode.Error, typeof ErrorCode.BadRequest> {\n status: typeof StatusCode.Error;\n label?: never;\n error: string;\n errorCode: typeof ErrorCode.BadRequest;\n }\n\n export type HealResponse =\n | HealSuccess\n | HealNotFoundError\n | HealServerError\n | HealBadRequestError;\n export type HealError = Exclude<HealResponse, HealSuccess>;\n\n /**\n * Server errors should not be cached.\n */\n export type CacheableHealResponse = Exclude<HealResponse, HealServerError>;\n\n export interface BaseCountResponse<Status extends StatusCode, Error extends ErrorCode> {\n status: Status;\n count?: number | never;\n timestamp?: string | never;\n error?: string | never;\n errorCode?: Error | never;\n }\n\n export interface CountSuccess extends BaseCountResponse<typeof StatusCode.Success, never> {\n status: typeof StatusCode.Success;\n /** The total count of labels that can be healed by the ENSRainbow instance. Always a\n * non-negative integer. */\n count: number;\n timestamp: string;\n error?: never;\n errorCode?: never;\n }\n\n export interface CountServerError\n extends BaseCountResponse<typeof StatusCode.Error, typeof ErrorCode.ServerError> {\n status: typeof StatusCode.Error;\n count?: never;\n timestamp?: never;\n error: string;\n errorCode: typeof ErrorCode.ServerError;\n }\n\n export type CountResponse = CountSuccess | CountServerError;\n\n /**\n * ENSRainbow version information.\n */\n export interface VersionInfo {\n /**\n * ENSRainbow version.\n */\n version: string;\n\n /**\n * ENSRainbow database schema version.\n */\n dbSchemaVersion: number;\n\n /**\n * The EnsRainbowServerLabelSet managed by the ENSRainbow server.\n */\n labelSet: EnsRainbowServerLabelSet;\n }\n\n /**\n * Interface for the version endpoint response\n */\n export interface VersionResponse {\n status: typeof StatusCode.Success;\n versionInfo: VersionInfo;\n }\n}\n\nexport interface EnsRainbowApiClientOptions {\n /**\n * The maximum number of `HealResponse` values to cache.\n * Must be a non-negative integer.\n * Setting to 0 will disable caching.\n */\n cacheCapacity: number;\n\n /**\n * The URL of an ENSRainbow API endpoint.\n */\n endpointUrl: URL;\n\n /**\n * Optional label set preferences that the ENSRainbow server at endpointUrl is expected to\n * support. If provided, enables deterministic heal results across time, such that only\n * labels from label sets with versions less than or equal to this value will be returned.\n * Therefore, even if the ENSRainbow server later ingests label sets with greater versions\n * than this value, the results returned across time can be deterministic. If\n * provided, heal operations with this EnsRainbowApiClient will validate the ENSRainbow\n * server manages a compatible label set. If not provided no specific labelSetId validation\n * will be performed during heal operations.\n * If `labelSetId` is provided without `labelSetVersion`, the server will use the latest\n * available version.\n * If `labelSetVersion` is defined, only labels from sets less than or equal to this value\n * will be returned.\n * When `labelSetVersion` is defined, `labelSetId` must also be defined.\n */\n labelSet?: EnsRainbowClientLabelSet;\n}\n\n/**\n * ENSRainbow API client\n *\n * @example\n * ```typescript\n * // default options\n * const client = new EnsRainbowApiClient();\n * // custom options\n * const client = new EnsRainbowApiClient({\n * endpointUrl: new URL(\"https://api.ensrainbow.io\"),\n * });\n * ```\n */\nexport class EnsRainbowApiClient implements EnsRainbow.ApiClient {\n private readonly options: EnsRainbowApiClientOptions;\n private readonly cache: Cache<LabelHash, EnsRainbow.CacheableHealResponse>;\n private readonly labelSetSearchParams: URLSearchParams;\n\n public static readonly DEFAULT_CACHE_CAPACITY = 1000;\n\n /**\n * Create default client options.\n *\n * @returns default options\n */\n static defaultOptions(): EnsRainbow.ApiClientOptions {\n return {\n endpointUrl: new URL(DEFAULT_ENSRAINBOW_URL),\n cacheCapacity: EnsRainbowApiClient.DEFAULT_CACHE_CAPACITY,\n labelSet: buildEnsRainbowClientLabelSet(),\n };\n }\n\n constructor(options: Partial<EnsRainbow.ApiClientOptions> = {}) {\n const { labelSet: optionsLabelSet, ...rest } = options;\n const defaultOptions = EnsRainbowApiClient.defaultOptions();\n\n const copiedLabelSet = buildEnsRainbowClientLabelSet(\n optionsLabelSet?.labelSetId,\n optionsLabelSet?.labelSetVersion,\n );\n\n this.options = {\n ...defaultOptions,\n ...rest,\n labelSet: copiedLabelSet,\n };\n\n this.cache = new LruCache<LabelHash, EnsRainbow.CacheableHealResponse>(\n this.options.cacheCapacity,\n );\n\n // Pre-compute query parameters for label set options\n this.labelSetSearchParams = new URLSearchParams();\n if (this.options.labelSet?.labelSetId !== undefined) {\n this.labelSetSearchParams.append(\"label_set_id\", this.options.labelSet.labelSetId);\n }\n if (this.options.labelSet?.labelSetVersion !== undefined) {\n this.labelSetSearchParams.append(\n \"label_set_version\",\n this.options.labelSet.labelSetVersion.toString(),\n );\n }\n }\n\n /**\n * Attempt to heal a labelHash to its original label.\n *\n * Note on returned labels: ENSRainbow returns labels exactly as they are\n * represented in source rainbow table data. This means:\n *\n * - Labels may or may not be ENS-normalized\n * - Labels can contain any valid string, including dots, null bytes, or be empty\n * - Clients should handle all possible string values appropriately\n *\n * @param labelHash all lowercase 64-digit hex string with 0x prefix (total length of 66 characters)\n * @returns a `HealResponse` indicating the result of the request and the healed label if successful\n * @throws if the request fails due to network failures, DNS lookup failures, request timeouts,\n * CORS violations, or Invalid URLs\n * @example\n * ```typescript\n * const response = await client.heal(\n * \"0xaf2caa1c2ca1d027f1ac823b529d0a67cd144264b2789fa2ea4d63a67c7103cc\"\n * );\n *\n * console.log(response);\n *\n * // Output:\n * // {\n * // status: \"success\",\n * // label: \"vitalik\"\n * // }\n *\n * const notFoundResponse = await client.heal(\n * \"0xf64dc17ae2e2b9b16dbcb8cb05f35a2e6080a5ff1dc53ac0bc48f0e79111f264\"\n * );\n *\n * console.log(notFoundResponse);\n *\n * // Output:\n * // {\n * // status: \"error\",\n * // error: \"Label not found\",\n * // errorCode: 404\n * // }\n * ```\n */\n async heal(labelHash: LabelHash): Promise<EnsRainbow.HealResponse> {\n const cachedResult = this.cache.get(labelHash);\n if (cachedResult) return cachedResult;\n\n const url = new URL(`/v1/heal/${labelHash}`, this.options.endpointUrl);\n\n // Apply pre-computed label set query parameters\n this.labelSetSearchParams.forEach((value, key) => {\n url.searchParams.append(key, value);\n });\n\n const response = await fetch(url);\n const healResponse = (await response.json()) as EnsRainbow.HealResponse;\n\n if (isCacheableHealResponse(healResponse)) {\n this.cache.set(labelHash, healResponse);\n }\n\n return healResponse;\n }\n\n /**\n * Get Count of Healable Labels\n *\n * @returns a `CountResponse` indicating the result and the timestamp of the request and the\n * number of healable labels if successful\n * @throws if the request fails due to network failures, DNS lookup failures, request timeouts,\n * CORS violations, or Invalid URLs\n * @example\n *\n * const response = await client.count();\n *\n * console.log(response);\n *\n * // {\n * // \"status\": \"success\",\n * // \"count\": 133856894,\n * // \"timestamp\": \"2024-01-30T11:18:56Z\"\n * // }\n *\n */\n async count(): Promise<EnsRainbow.CountResponse> {\n const response = await fetch(new URL(\"/v1/labels/count\", this.options.endpointUrl));\n\n return response.json() as Promise<EnsRainbow.CountResponse>;\n }\n\n /**\n *\n * Simple verification that the service is running, either in your local setup or for the\n * provided hosted instance.\n * @returns a status of ENS Rainbow service\n * @example\n *\n * const response = await client.health();\n *\n * console.log(response);\n *\n * // {\n * // \"status\": \"ok\",\n * // }\n */\n async health(): Promise<EnsRainbow.HealthResponse> {\n const response = await fetch(new URL(\"/health\", this.options.endpointUrl));\n\n return response.json() as Promise<EnsRainbow.HealthResponse>;\n }\n\n /**\n * Get the version information of the ENSRainbow service\n *\n * @returns the version information of the ENSRainbow service\n * @throws if the request fails due to network failures, DNS lookup failures, request\n * timeouts, CORS violations, or invalid URLs\n * @example\n * ```typescript\n * const response = await client.version();\n *\n * console.log(response);\n *\n * // {\n * // \"status\": \"success\",\n * // \"versionInfo\": {\n * // \"version\": \"0.1.0\",\n * // \"dbSchemaVersion\": 2,\n * // \"labelSet\": {\n * // \"labelSetId\": \"subgraph\",\n * // \"labelSetVersion\": 0\n * // }\n * // }\n * // }\n * ```\n */\n async version(): Promise<EnsRainbow.VersionResponse> {\n const response = await fetch(new URL(\"/v1/version\", this.options.endpointUrl));\n\n return response.json() as Promise<EnsRainbow.VersionResponse>;\n }\n\n /**\n * Get a copy of the current client options.\n *\n * @returns a copy of the current client options.\n */\n getOptions(): Readonly<EnsRainbowApiClientOptions> {\n // build a deep copy to prevent modification\n const deepCopy = {\n cacheCapacity: this.options.cacheCapacity,\n endpointUrl: new URL(this.options.endpointUrl.href),\n labelSet: this.options.labelSet ? { ...this.options.labelSet } : undefined,\n } satisfies EnsRainbowApiClientOptions;\n\n return Object.freeze(deepCopy);\n }\n}\n\n/**\n * Determine if a heal response is an error.\n *\n * @param response the heal response to check\n * @returns true if the response is an error, false otherwise\n */\nexport const isHealError = (\n response: EnsRainbow.HealResponse,\n): response is EnsRainbow.HealError => {\n return response.status === StatusCode.Error;\n};\n\n/**\n * Determine if a heal response is cacheable.\n *\n * Server errors at not cachable and should be retried.\n *\n * @param response the heal response to check\n * @returns true if the response is cacheable, false otherwise\n */\nexport const isCacheableHealResponse = (\n response: EnsRainbow.HealResponse,\n): response is EnsRainbow.CacheableHealResponse => {\n return response.status === StatusCode.Success || response.errorCode !== ErrorCode.ServerError;\n};\n","export const DEFAULT_ENSRAINBOW_URL = \"https://api.ensrainbow.io\" as const;\n\nexport const StatusCode = {\n Success: \"success\",\n Error: \"error\",\n} as const;\n\nexport const ErrorCode = {\n BadRequest: 400,\n NotFound: 404,\n ServerError: 500,\n} as const;\n"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
1
|
export { EnsRainbow, EnsRainbowApiClient, EnsRainbowApiClientOptions, isCacheableHealResponse, isHealError } from './client.js';
|
|
2
2
|
export { DEFAULT_ENSRAINBOW_URL, ErrorCode, StatusCode } from './consts.js';
|
|
3
|
-
export {
|
|
4
|
-
import '@ensnode/ensnode-sdk';
|
|
5
|
-
import 'viem';
|
|
3
|
+
export { EnsRainbowClientLabelSet, EnsRainbowServerLabelSet, LabelSetId, LabelSetVersion, buildEnsRainbowClientLabelSet } from '@ensnode/ensnode-sdk';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
// src/client.ts
|
|
2
2
|
import { LruCache } from "@ensnode/ensnode-sdk";
|
|
3
|
+
import {
|
|
4
|
+
buildEnsRainbowClientLabelSet
|
|
5
|
+
} from "@ensnode/ensnode-sdk";
|
|
3
6
|
|
|
4
7
|
// src/consts.ts
|
|
5
8
|
var DEFAULT_ENSRAINBOW_URL = "https://api.ensrainbow.io";
|
|
@@ -17,6 +20,7 @@ var ErrorCode = {
|
|
|
17
20
|
var EnsRainbowApiClient = class _EnsRainbowApiClient {
|
|
18
21
|
options;
|
|
19
22
|
cache;
|
|
23
|
+
labelSetSearchParams;
|
|
20
24
|
static DEFAULT_CACHE_CAPACITY = 1e3;
|
|
21
25
|
/**
|
|
22
26
|
* Create default client options.
|
|
@@ -26,17 +30,35 @@ var EnsRainbowApiClient = class _EnsRainbowApiClient {
|
|
|
26
30
|
static defaultOptions() {
|
|
27
31
|
return {
|
|
28
32
|
endpointUrl: new URL(DEFAULT_ENSRAINBOW_URL),
|
|
29
|
-
cacheCapacity: _EnsRainbowApiClient.DEFAULT_CACHE_CAPACITY
|
|
33
|
+
cacheCapacity: _EnsRainbowApiClient.DEFAULT_CACHE_CAPACITY,
|
|
34
|
+
labelSet: buildEnsRainbowClientLabelSet()
|
|
30
35
|
};
|
|
31
36
|
}
|
|
32
37
|
constructor(options = {}) {
|
|
38
|
+
const { labelSet: optionsLabelSet, ...rest } = options;
|
|
39
|
+
const defaultOptions = _EnsRainbowApiClient.defaultOptions();
|
|
40
|
+
const copiedLabelSet = buildEnsRainbowClientLabelSet(
|
|
41
|
+
optionsLabelSet?.labelSetId,
|
|
42
|
+
optionsLabelSet?.labelSetVersion
|
|
43
|
+
);
|
|
33
44
|
this.options = {
|
|
34
|
-
...
|
|
35
|
-
...
|
|
45
|
+
...defaultOptions,
|
|
46
|
+
...rest,
|
|
47
|
+
labelSet: copiedLabelSet
|
|
36
48
|
};
|
|
37
49
|
this.cache = new LruCache(
|
|
38
50
|
this.options.cacheCapacity
|
|
39
51
|
);
|
|
52
|
+
this.labelSetSearchParams = new URLSearchParams();
|
|
53
|
+
if (this.options.labelSet?.labelSetId !== void 0) {
|
|
54
|
+
this.labelSetSearchParams.append("label_set_id", this.options.labelSet.labelSetId);
|
|
55
|
+
}
|
|
56
|
+
if (this.options.labelSet?.labelSetVersion !== void 0) {
|
|
57
|
+
this.labelSetSearchParams.append(
|
|
58
|
+
"label_set_version",
|
|
59
|
+
this.options.labelSet.labelSetVersion.toString()
|
|
60
|
+
);
|
|
61
|
+
}
|
|
40
62
|
}
|
|
41
63
|
/**
|
|
42
64
|
* Attempt to heal a labelHash to its original label.
|
|
@@ -50,8 +72,8 @@ var EnsRainbowApiClient = class _EnsRainbowApiClient {
|
|
|
50
72
|
*
|
|
51
73
|
* @param labelHash all lowercase 64-digit hex string with 0x prefix (total length of 66 characters)
|
|
52
74
|
* @returns a `HealResponse` indicating the result of the request and the healed label if successful
|
|
53
|
-
* @throws if the request fails due to network failures, DNS lookup failures, request timeouts,
|
|
54
|
-
*
|
|
75
|
+
* @throws if the request fails due to network failures, DNS lookup failures, request timeouts,
|
|
76
|
+
* CORS violations, or Invalid URLs
|
|
55
77
|
* @example
|
|
56
78
|
* ```typescript
|
|
57
79
|
* const response = await client.heal(
|
|
@@ -82,10 +104,12 @@ var EnsRainbowApiClient = class _EnsRainbowApiClient {
|
|
|
82
104
|
*/
|
|
83
105
|
async heal(labelHash) {
|
|
84
106
|
const cachedResult = this.cache.get(labelHash);
|
|
85
|
-
if (cachedResult)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
107
|
+
if (cachedResult) return cachedResult;
|
|
108
|
+
const url = new URL(`/v1/heal/${labelHash}`, this.options.endpointUrl);
|
|
109
|
+
this.labelSetSearchParams.forEach((value, key) => {
|
|
110
|
+
url.searchParams.append(key, value);
|
|
111
|
+
});
|
|
112
|
+
const response = await fetch(url);
|
|
89
113
|
const healResponse = await response.json();
|
|
90
114
|
if (isCacheableHealResponse(healResponse)) {
|
|
91
115
|
this.cache.set(labelHash, healResponse);
|
|
@@ -95,9 +119,10 @@ var EnsRainbowApiClient = class _EnsRainbowApiClient {
|
|
|
95
119
|
/**
|
|
96
120
|
* Get Count of Healable Labels
|
|
97
121
|
*
|
|
98
|
-
* @returns a `CountResponse` indicating the result and the timestamp of the request and the
|
|
99
|
-
*
|
|
100
|
-
*
|
|
122
|
+
* @returns a `CountResponse` indicating the result and the timestamp of the request and the
|
|
123
|
+
* number of healable labels if successful
|
|
124
|
+
* @throws if the request fails due to network failures, DNS lookup failures, request timeouts,
|
|
125
|
+
* CORS violations, or Invalid URLs
|
|
101
126
|
* @example
|
|
102
127
|
*
|
|
103
128
|
* const response = await client.count();
|
|
@@ -117,8 +142,8 @@ var EnsRainbowApiClient = class _EnsRainbowApiClient {
|
|
|
117
142
|
}
|
|
118
143
|
/**
|
|
119
144
|
*
|
|
120
|
-
* Simple verification that the service is running, either in your local setup or for the
|
|
121
|
-
*
|
|
145
|
+
* Simple verification that the service is running, either in your local setup or for the
|
|
146
|
+
* provided hosted instance.
|
|
122
147
|
* @returns a status of ENS Rainbow service
|
|
123
148
|
* @example
|
|
124
149
|
*
|
|
@@ -138,8 +163,8 @@ var EnsRainbowApiClient = class _EnsRainbowApiClient {
|
|
|
138
163
|
* Get the version information of the ENSRainbow service
|
|
139
164
|
*
|
|
140
165
|
* @returns the version information of the ENSRainbow service
|
|
141
|
-
* @throws if the request fails due to network failures, DNS lookup failures, request
|
|
142
|
-
*
|
|
166
|
+
* @throws if the request fails due to network failures, DNS lookup failures, request
|
|
167
|
+
* timeouts, CORS violations, or invalid URLs
|
|
143
168
|
* @example
|
|
144
169
|
* ```typescript
|
|
145
170
|
* const response = await client.version();
|
|
@@ -148,8 +173,14 @@ var EnsRainbowApiClient = class _EnsRainbowApiClient {
|
|
|
148
173
|
*
|
|
149
174
|
* // {
|
|
150
175
|
* // "status": "success",
|
|
151
|
-
* // "
|
|
152
|
-
* //
|
|
176
|
+
* // "versionInfo": {
|
|
177
|
+
* // "version": "0.1.0",
|
|
178
|
+
* // "dbSchemaVersion": 2,
|
|
179
|
+
* // "labelSet": {
|
|
180
|
+
* // "labelSetId": "subgraph",
|
|
181
|
+
* // "labelSetVersion": 0
|
|
182
|
+
* // }
|
|
183
|
+
* // }
|
|
153
184
|
* // }
|
|
154
185
|
* ```
|
|
155
186
|
*/
|
|
@@ -165,7 +196,8 @@ var EnsRainbowApiClient = class _EnsRainbowApiClient {
|
|
|
165
196
|
getOptions() {
|
|
166
197
|
const deepCopy = {
|
|
167
198
|
cacheCapacity: this.options.cacheCapacity,
|
|
168
|
-
endpointUrl: new URL(this.options.endpointUrl.href)
|
|
199
|
+
endpointUrl: new URL(this.options.endpointUrl.href),
|
|
200
|
+
labelSet: this.options.labelSet ? { ...this.options.labelSet } : void 0
|
|
169
201
|
};
|
|
170
202
|
return Object.freeze(deepCopy);
|
|
171
203
|
}
|
|
@@ -177,38 +209,15 @@ var isCacheableHealResponse = (response) => {
|
|
|
177
209
|
return response.status === StatusCode.Success || response.errorCode !== ErrorCode.ServerError;
|
|
178
210
|
};
|
|
179
211
|
|
|
180
|
-
// src/
|
|
181
|
-
import {
|
|
182
|
-
function labelHashToBytes(labelHash) {
|
|
183
|
-
try {
|
|
184
|
-
if (labelHash.length !== 66) {
|
|
185
|
-
throw new Error(`Invalid labelHash length ${labelHash.length} characters (expected 66)`);
|
|
186
|
-
}
|
|
187
|
-
if (labelHash !== labelHash.toLowerCase()) {
|
|
188
|
-
throw new Error("Labelhash must be in lowercase");
|
|
189
|
-
}
|
|
190
|
-
if (!labelHash.startsWith("0x")) {
|
|
191
|
-
throw new Error("Labelhash must be 0x-prefixed");
|
|
192
|
-
}
|
|
193
|
-
const bytes = hexToBytes(labelHash);
|
|
194
|
-
if (bytes.length !== 32) {
|
|
195
|
-
throw new Error(`Invalid labelHash length ${bytes.length} bytes (expected 32)`);
|
|
196
|
-
}
|
|
197
|
-
return bytes;
|
|
198
|
-
} catch (e) {
|
|
199
|
-
if (e instanceof Error) {
|
|
200
|
-
throw e;
|
|
201
|
-
}
|
|
202
|
-
throw new Error("Invalid hex format");
|
|
203
|
-
}
|
|
204
|
-
}
|
|
212
|
+
// src/index.ts
|
|
213
|
+
import { buildEnsRainbowClientLabelSet as buildEnsRainbowClientLabelSet2 } from "@ensnode/ensnode-sdk";
|
|
205
214
|
export {
|
|
206
215
|
DEFAULT_ENSRAINBOW_URL,
|
|
207
216
|
EnsRainbowApiClient,
|
|
208
217
|
ErrorCode,
|
|
209
218
|
StatusCode,
|
|
219
|
+
buildEnsRainbowClientLabelSet2 as buildEnsRainbowClientLabelSet,
|
|
210
220
|
isCacheableHealResponse,
|
|
211
|
-
isHealError
|
|
212
|
-
labelHashToBytes
|
|
221
|
+
isHealError
|
|
213
222
|
};
|
|
214
223
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/consts.ts","../src/label-utils.ts"],"sourcesContent":["import { type Cache, Label, type LabelHash, LruCache } from \"@ensnode/ensnode-sdk\";\nimport { DEFAULT_ENSRAINBOW_URL, ErrorCode, StatusCode } from \"./consts\";\n\nexport namespace EnsRainbow {\n export type ApiClientOptions = EnsRainbowApiClientOptions;\n\n export interface ApiClient {\n count(): Promise<CountResponse>;\n\n heal(labelHash: LabelHash): Promise<HealResponse>;\n\n health(): Promise<HealthResponse>;\n\n version(): Promise<VersionResponse>;\n\n getOptions(): Readonly<EnsRainbowApiClientOptions>;\n }\n\n type StatusCode = (typeof StatusCode)[keyof typeof StatusCode];\n\n type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];\n\n export interface HealthResponse {\n status: \"ok\";\n }\n\n export interface BaseHealResponse<Status extends StatusCode, Error extends ErrorCode> {\n status: Status;\n label?: Label | never;\n error?: string | never;\n errorCode?: Error | never;\n }\n\n export interface HealSuccess extends BaseHealResponse<typeof StatusCode.Success, never> {\n status: typeof StatusCode.Success;\n label: Label;\n error?: never;\n errorCode?: never;\n }\n\n export interface HealNotFoundError\n extends BaseHealResponse<typeof StatusCode.Error, typeof ErrorCode.NotFound> {\n status: typeof StatusCode.Error;\n label?: never;\n error: string;\n errorCode: typeof ErrorCode.NotFound;\n }\n\n export interface HealServerError\n extends BaseHealResponse<typeof StatusCode.Error, typeof ErrorCode.ServerError> {\n status: typeof StatusCode.Error;\n label?: never;\n error: string;\n errorCode: typeof ErrorCode.ServerError;\n }\n\n export interface HealBadRequestError\n extends BaseHealResponse<typeof StatusCode.Error, typeof ErrorCode.BadRequest> {\n status: typeof StatusCode.Error;\n label?: never;\n error: string;\n errorCode: typeof ErrorCode.BadRequest;\n }\n\n export type HealResponse =\n | HealSuccess\n | HealNotFoundError\n | HealServerError\n | HealBadRequestError;\n export type HealError = Exclude<HealResponse, HealSuccess>;\n\n /**\n * Server errors should not be cached.\n */\n export type CacheableHealResponse = Exclude<HealResponse, HealServerError>;\n\n export interface BaseCountResponse<Status extends StatusCode, Error extends ErrorCode> {\n status: Status;\n count?: number | never;\n timestamp?: string | never;\n error?: string | never;\n errorCode?: Error | never;\n }\n\n export interface CountSuccess extends BaseCountResponse<typeof StatusCode.Success, never> {\n status: typeof StatusCode.Success;\n /** The total count of labels that can be healed by the ENSRainbow instance. Always a non-negative integer. */\n count: number;\n timestamp: string;\n error?: never;\n errorCode?: never;\n }\n\n export interface CountServerError\n extends BaseCountResponse<typeof StatusCode.Error, typeof ErrorCode.ServerError> {\n status: typeof StatusCode.Error;\n count?: never;\n timestamp?: never;\n error: string;\n errorCode: typeof ErrorCode.ServerError;\n }\n\n export type CountResponse = CountSuccess | CountServerError;\n\n /**\n * ENSRainbow version information.\n */\n export interface VersionInfo {\n /**\n * ENSRainbow version.\n */\n version: string;\n\n /**\n * ENSRainbow schema version.\n */\n schema_version: number;\n }\n\n /**\n * Interface for the version endpoint response\n */\n export interface VersionResponse {\n status: typeof StatusCode.Success;\n versionInfo: VersionInfo;\n }\n}\n\nexport interface EnsRainbowApiClientOptions {\n /**\n * The maximum number of `HealResponse` values to cache.\n * Must be a non-negative integer.\n * Setting to 0 will disable caching.\n */\n cacheCapacity: number;\n\n /**\n * The URL of an ENSRainbow API endpoint.\n */\n endpointUrl: URL;\n}\n\n/**\n * ENSRainbow API client\n *\n * @example\n * ```typescript\n * // default options\n * const client = new EnsRainbowApiClient();\n * // custom options\n * const client = new EnsRainbowApiClient({\n * endpointUrl: new URL(\"https://api.ensrainbow.io\"),\n * });\n * ```\n */\nexport class EnsRainbowApiClient implements EnsRainbow.ApiClient {\n private readonly options: EnsRainbowApiClientOptions;\n private readonly cache: Cache<LabelHash, EnsRainbow.CacheableHealResponse>;\n\n public static readonly DEFAULT_CACHE_CAPACITY = 1000;\n\n /**\n * Create default client options.\n *\n * @returns default options\n */\n static defaultOptions(): EnsRainbow.ApiClientOptions {\n return {\n endpointUrl: new URL(DEFAULT_ENSRAINBOW_URL),\n cacheCapacity: EnsRainbowApiClient.DEFAULT_CACHE_CAPACITY,\n };\n }\n\n constructor(options: Partial<EnsRainbow.ApiClientOptions> = {}) {\n this.options = {\n ...EnsRainbowApiClient.defaultOptions(),\n ...options,\n };\n\n this.cache = new LruCache<LabelHash, EnsRainbow.CacheableHealResponse>(\n this.options.cacheCapacity,\n );\n }\n\n /**\n * Attempt to heal a labelHash to its original label.\n *\n * Note on returned labels: ENSRainbow returns labels exactly as they are\n * represented in source rainbow table data. This means:\n *\n * - Labels may or may not be ENS-normalized\n * - Labels can contain any valid string, including dots, null bytes, or be empty\n * - Clients should handle all possible string values appropriately\n *\n * @param labelHash all lowercase 64-digit hex string with 0x prefix (total length of 66 characters)\n * @returns a `HealResponse` indicating the result of the request and the healed label if successful\n * @throws if the request fails due to network failures, DNS lookup failures, request timeouts, CORS violations, or Invalid URLs\n *\n * @example\n * ```typescript\n * const response = await client.heal(\n * \"0xaf2caa1c2ca1d027f1ac823b529d0a67cd144264b2789fa2ea4d63a67c7103cc\"\n * );\n *\n * console.log(response);\n *\n * // Output:\n * // {\n * // status: \"success\",\n * // label: \"vitalik\"\n * // }\n *\n * const notFoundResponse = await client.heal(\n * \"0xf64dc17ae2e2b9b16dbcb8cb05f35a2e6080a5ff1dc53ac0bc48f0e79111f264\"\n * );\n *\n * console.log(notFoundResponse);\n *\n * // Output:\n * // {\n * // status: \"error\",\n * // error: \"Label not found\",\n * // errorCode: 404\n * // }\n * ```\n */\n async heal(labelHash: LabelHash): Promise<EnsRainbow.HealResponse> {\n const cachedResult = this.cache.get(labelHash);\n\n if (cachedResult) {\n return cachedResult;\n }\n\n const response = await fetch(new URL(`/v1/heal/${labelHash}`, this.options.endpointUrl));\n const healResponse = (await response.json()) as EnsRainbow.HealResponse;\n\n if (isCacheableHealResponse(healResponse)) {\n this.cache.set(labelHash, healResponse);\n }\n\n return healResponse;\n }\n\n /**\n * Get Count of Healable Labels\n *\n * @returns a `CountResponse` indicating the result and the timestamp of the request and the number of healable labels if successful\n * @throws if the request fails due to network failures, DNS lookup failures, request timeouts, CORS violations, or Invalid URLs\n *\n * @example\n *\n * const response = await client.count();\n *\n * console.log(response);\n *\n * // {\n * // \"status\": \"success\",\n * // \"count\": 133856894,\n * // \"timestamp\": \"2024-01-30T11:18:56Z\"\n * // }\n *\n */\n async count(): Promise<EnsRainbow.CountResponse> {\n const response = await fetch(new URL(\"/v1/labels/count\", this.options.endpointUrl));\n\n return response.json() as Promise<EnsRainbow.CountResponse>;\n }\n\n /**\n *\n * Simple verification that the service is running, either in your local setup or for the provided hosted instance\n *\n * @returns a status of ENS Rainbow service\n * @example\n *\n * const response = await client.health();\n *\n * console.log(response);\n *\n * // {\n * // \"status\": \"ok\",\n * // }\n */\n async health(): Promise<EnsRainbow.HealthResponse> {\n const response = await fetch(new URL(\"/health\", this.options.endpointUrl));\n\n return response.json() as Promise<EnsRainbow.HealthResponse>;\n }\n\n /**\n * Get the version information of the ENSRainbow service\n *\n * @returns the version information of the ENSRainbow service\n * @throws if the request fails due to network failures, DNS lookup failures, request timeouts, CORS violations, or Invalid URLs\n *\n * @example\n * ```typescript\n * const response = await client.version();\n *\n * console.log(response);\n *\n * // {\n * // \"status\": \"success\",\n * // \"version\": \"0.1.0\",\n * // \"schema_version\": 2\n * // }\n * ```\n */\n async version(): Promise<EnsRainbow.VersionResponse> {\n const response = await fetch(new URL(\"/v1/version\", this.options.endpointUrl));\n\n return response.json() as Promise<EnsRainbow.VersionResponse>;\n }\n\n /**\n * Get a copy of the current client options.\n *\n * @returns a copy of the current client options.\n */\n getOptions(): Readonly<EnsRainbowApiClientOptions> {\n // build a deep copy to prevent modification\n const deepCopy = {\n cacheCapacity: this.options.cacheCapacity,\n endpointUrl: new URL(this.options.endpointUrl.href),\n } satisfies EnsRainbowApiClientOptions;\n\n return Object.freeze(deepCopy);\n }\n}\n\n/**\n * Determine if a heal response is an error.\n *\n * @param response the heal response to check\n * @returns true if the response is an error, false otherwise\n */\nexport const isHealError = (\n response: EnsRainbow.HealResponse,\n): response is EnsRainbow.HealError => {\n return response.status === StatusCode.Error;\n};\n\n/**\n * Determine if a heal response is cacheable.\n *\n * Server errors at not cachable and should be retried.\n *\n * @param response the heal response to check\n * @returns true if the response is cacheable, false otherwise\n */\nexport const isCacheableHealResponse = (\n response: EnsRainbow.HealResponse,\n): response is EnsRainbow.CacheableHealResponse => {\n return response.status === StatusCode.Success || response.errorCode !== ErrorCode.ServerError;\n};\n","export const DEFAULT_ENSRAINBOW_URL = \"https://api.ensrainbow.io\" as const;\n\nexport const StatusCode = {\n Success: \"success\",\n Error: \"error\",\n} as const;\n\nexport const ErrorCode = {\n BadRequest: 400,\n NotFound: 404,\n ServerError: 500,\n} as const;\n","import type { LabelHash } from \"@ensnode/ensnode-sdk\";\nimport { ByteArray, hexToBytes } from \"viem\";\n\n/**\n * Converts a Labelhash to bytes, with validation\n * @param labelHash The Labelhash to convert\n * @returns A ByteArray containing the bytes\n * @throws Error if `labelHash` is not a valid 32-byte hex string\n */\nexport function labelHashToBytes(labelHash: LabelHash): ByteArray {\n try {\n if (labelHash.length !== 66) {\n throw new Error(`Invalid labelHash length ${labelHash.length} characters (expected 66)`);\n }\n if (labelHash !== labelHash.toLowerCase()) {\n throw new Error(\"Labelhash must be in lowercase\");\n }\n if (!labelHash.startsWith(\"0x\")) {\n throw new Error(\"Labelhash must be 0x-prefixed\");\n }\n const bytes = hexToBytes(labelHash);\n if (bytes.length !== 32) {\n // should be redundant but keeping it for the principle of defensive programming\n throw new Error(`Invalid labelHash length ${bytes.length} bytes (expected 32)`);\n }\n return bytes;\n } catch (e) {\n if (e instanceof Error) {\n throw e;\n }\n throw new Error(\"Invalid hex format\");\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/consts.ts","../src/index.ts"],"sourcesContent":["import { type Cache, Label, type LabelHash, LruCache } from \"@ensnode/ensnode-sdk\";\nimport {\n type EnsRainbowClientLabelSet,\n type EnsRainbowServerLabelSet,\n buildEnsRainbowClientLabelSet,\n} from \"@ensnode/ensnode-sdk\";\nimport { DEFAULT_ENSRAINBOW_URL, ErrorCode, StatusCode } from \"./consts\";\n\nexport namespace EnsRainbow {\n export type ApiClientOptions = EnsRainbowApiClientOptions;\n\n export interface ApiClient {\n count(): Promise<CountResponse>;\n\n /**\n * Heal a labelhash to its original label\n * @param labelHash The labelhash to heal\n */\n heal(labelHash: LabelHash): Promise<HealResponse>;\n\n health(): Promise<HealthResponse>;\n\n version(): Promise<VersionResponse>;\n\n getOptions(): Readonly<EnsRainbowApiClientOptions>;\n }\n\n type StatusCode = (typeof StatusCode)[keyof typeof StatusCode];\n\n type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];\n\n export interface HealthResponse {\n status: \"ok\";\n }\n\n export interface BaseHealResponse<Status extends StatusCode, Error extends ErrorCode> {\n status: Status;\n label?: Label | never;\n error?: string | never;\n errorCode?: Error | never;\n }\n\n export interface HealSuccess extends BaseHealResponse<typeof StatusCode.Success, never> {\n status: typeof StatusCode.Success;\n label: Label;\n error?: never;\n errorCode?: never;\n }\n\n export interface HealNotFoundError\n extends BaseHealResponse<typeof StatusCode.Error, typeof ErrorCode.NotFound> {\n status: typeof StatusCode.Error;\n label?: never;\n error: string;\n errorCode: typeof ErrorCode.NotFound;\n }\n\n export interface HealServerError\n extends BaseHealResponse<typeof StatusCode.Error, typeof ErrorCode.ServerError> {\n status: typeof StatusCode.Error;\n label?: never;\n error: string;\n errorCode: typeof ErrorCode.ServerError;\n }\n\n export interface HealBadRequestError\n extends BaseHealResponse<typeof StatusCode.Error, typeof ErrorCode.BadRequest> {\n status: typeof StatusCode.Error;\n label?: never;\n error: string;\n errorCode: typeof ErrorCode.BadRequest;\n }\n\n export type HealResponse =\n | HealSuccess\n | HealNotFoundError\n | HealServerError\n | HealBadRequestError;\n export type HealError = Exclude<HealResponse, HealSuccess>;\n\n /**\n * Server errors should not be cached.\n */\n export type CacheableHealResponse = Exclude<HealResponse, HealServerError>;\n\n export interface BaseCountResponse<Status extends StatusCode, Error extends ErrorCode> {\n status: Status;\n count?: number | never;\n timestamp?: string | never;\n error?: string | never;\n errorCode?: Error | never;\n }\n\n export interface CountSuccess extends BaseCountResponse<typeof StatusCode.Success, never> {\n status: typeof StatusCode.Success;\n /** The total count of labels that can be healed by the ENSRainbow instance. Always a\n * non-negative integer. */\n count: number;\n timestamp: string;\n error?: never;\n errorCode?: never;\n }\n\n export interface CountServerError\n extends BaseCountResponse<typeof StatusCode.Error, typeof ErrorCode.ServerError> {\n status: typeof StatusCode.Error;\n count?: never;\n timestamp?: never;\n error: string;\n errorCode: typeof ErrorCode.ServerError;\n }\n\n export type CountResponse = CountSuccess | CountServerError;\n\n /**\n * ENSRainbow version information.\n */\n export interface VersionInfo {\n /**\n * ENSRainbow version.\n */\n version: string;\n\n /**\n * ENSRainbow database schema version.\n */\n dbSchemaVersion: number;\n\n /**\n * The EnsRainbowServerLabelSet managed by the ENSRainbow server.\n */\n labelSet: EnsRainbowServerLabelSet;\n }\n\n /**\n * Interface for the version endpoint response\n */\n export interface VersionResponse {\n status: typeof StatusCode.Success;\n versionInfo: VersionInfo;\n }\n}\n\nexport interface EnsRainbowApiClientOptions {\n /**\n * The maximum number of `HealResponse` values to cache.\n * Must be a non-negative integer.\n * Setting to 0 will disable caching.\n */\n cacheCapacity: number;\n\n /**\n * The URL of an ENSRainbow API endpoint.\n */\n endpointUrl: URL;\n\n /**\n * Optional label set preferences that the ENSRainbow server at endpointUrl is expected to\n * support. If provided, enables deterministic heal results across time, such that only\n * labels from label sets with versions less than or equal to this value will be returned.\n * Therefore, even if the ENSRainbow server later ingests label sets with greater versions\n * than this value, the results returned across time can be deterministic. If\n * provided, heal operations with this EnsRainbowApiClient will validate the ENSRainbow\n * server manages a compatible label set. If not provided no specific labelSetId validation\n * will be performed during heal operations.\n * If `labelSetId` is provided without `labelSetVersion`, the server will use the latest\n * available version.\n * If `labelSetVersion` is defined, only labels from sets less than or equal to this value\n * will be returned.\n * When `labelSetVersion` is defined, `labelSetId` must also be defined.\n */\n labelSet?: EnsRainbowClientLabelSet;\n}\n\n/**\n * ENSRainbow API client\n *\n * @example\n * ```typescript\n * // default options\n * const client = new EnsRainbowApiClient();\n * // custom options\n * const client = new EnsRainbowApiClient({\n * endpointUrl: new URL(\"https://api.ensrainbow.io\"),\n * });\n * ```\n */\nexport class EnsRainbowApiClient implements EnsRainbow.ApiClient {\n private readonly options: EnsRainbowApiClientOptions;\n private readonly cache: Cache<LabelHash, EnsRainbow.CacheableHealResponse>;\n private readonly labelSetSearchParams: URLSearchParams;\n\n public static readonly DEFAULT_CACHE_CAPACITY = 1000;\n\n /**\n * Create default client options.\n *\n * @returns default options\n */\n static defaultOptions(): EnsRainbow.ApiClientOptions {\n return {\n endpointUrl: new URL(DEFAULT_ENSRAINBOW_URL),\n cacheCapacity: EnsRainbowApiClient.DEFAULT_CACHE_CAPACITY,\n labelSet: buildEnsRainbowClientLabelSet(),\n };\n }\n\n constructor(options: Partial<EnsRainbow.ApiClientOptions> = {}) {\n const { labelSet: optionsLabelSet, ...rest } = options;\n const defaultOptions = EnsRainbowApiClient.defaultOptions();\n\n const copiedLabelSet = buildEnsRainbowClientLabelSet(\n optionsLabelSet?.labelSetId,\n optionsLabelSet?.labelSetVersion,\n );\n\n this.options = {\n ...defaultOptions,\n ...rest,\n labelSet: copiedLabelSet,\n };\n\n this.cache = new LruCache<LabelHash, EnsRainbow.CacheableHealResponse>(\n this.options.cacheCapacity,\n );\n\n // Pre-compute query parameters for label set options\n this.labelSetSearchParams = new URLSearchParams();\n if (this.options.labelSet?.labelSetId !== undefined) {\n this.labelSetSearchParams.append(\"label_set_id\", this.options.labelSet.labelSetId);\n }\n if (this.options.labelSet?.labelSetVersion !== undefined) {\n this.labelSetSearchParams.append(\n \"label_set_version\",\n this.options.labelSet.labelSetVersion.toString(),\n );\n }\n }\n\n /**\n * Attempt to heal a labelHash to its original label.\n *\n * Note on returned labels: ENSRainbow returns labels exactly as they are\n * represented in source rainbow table data. This means:\n *\n * - Labels may or may not be ENS-normalized\n * - Labels can contain any valid string, including dots, null bytes, or be empty\n * - Clients should handle all possible string values appropriately\n *\n * @param labelHash all lowercase 64-digit hex string with 0x prefix (total length of 66 characters)\n * @returns a `HealResponse` indicating the result of the request and the healed label if successful\n * @throws if the request fails due to network failures, DNS lookup failures, request timeouts,\n * CORS violations, or Invalid URLs\n * @example\n * ```typescript\n * const response = await client.heal(\n * \"0xaf2caa1c2ca1d027f1ac823b529d0a67cd144264b2789fa2ea4d63a67c7103cc\"\n * );\n *\n * console.log(response);\n *\n * // Output:\n * // {\n * // status: \"success\",\n * // label: \"vitalik\"\n * // }\n *\n * const notFoundResponse = await client.heal(\n * \"0xf64dc17ae2e2b9b16dbcb8cb05f35a2e6080a5ff1dc53ac0bc48f0e79111f264\"\n * );\n *\n * console.log(notFoundResponse);\n *\n * // Output:\n * // {\n * // status: \"error\",\n * // error: \"Label not found\",\n * // errorCode: 404\n * // }\n * ```\n */\n async heal(labelHash: LabelHash): Promise<EnsRainbow.HealResponse> {\n const cachedResult = this.cache.get(labelHash);\n if (cachedResult) return cachedResult;\n\n const url = new URL(`/v1/heal/${labelHash}`, this.options.endpointUrl);\n\n // Apply pre-computed label set query parameters\n this.labelSetSearchParams.forEach((value, key) => {\n url.searchParams.append(key, value);\n });\n\n const response = await fetch(url);\n const healResponse = (await response.json()) as EnsRainbow.HealResponse;\n\n if (isCacheableHealResponse(healResponse)) {\n this.cache.set(labelHash, healResponse);\n }\n\n return healResponse;\n }\n\n /**\n * Get Count of Healable Labels\n *\n * @returns a `CountResponse` indicating the result and the timestamp of the request and the\n * number of healable labels if successful\n * @throws if the request fails due to network failures, DNS lookup failures, request timeouts,\n * CORS violations, or Invalid URLs\n * @example\n *\n * const response = await client.count();\n *\n * console.log(response);\n *\n * // {\n * // \"status\": \"success\",\n * // \"count\": 133856894,\n * // \"timestamp\": \"2024-01-30T11:18:56Z\"\n * // }\n *\n */\n async count(): Promise<EnsRainbow.CountResponse> {\n const response = await fetch(new URL(\"/v1/labels/count\", this.options.endpointUrl));\n\n return response.json() as Promise<EnsRainbow.CountResponse>;\n }\n\n /**\n *\n * Simple verification that the service is running, either in your local setup or for the\n * provided hosted instance.\n * @returns a status of ENS Rainbow service\n * @example\n *\n * const response = await client.health();\n *\n * console.log(response);\n *\n * // {\n * // \"status\": \"ok\",\n * // }\n */\n async health(): Promise<EnsRainbow.HealthResponse> {\n const response = await fetch(new URL(\"/health\", this.options.endpointUrl));\n\n return response.json() as Promise<EnsRainbow.HealthResponse>;\n }\n\n /**\n * Get the version information of the ENSRainbow service\n *\n * @returns the version information of the ENSRainbow service\n * @throws if the request fails due to network failures, DNS lookup failures, request\n * timeouts, CORS violations, or invalid URLs\n * @example\n * ```typescript\n * const response = await client.version();\n *\n * console.log(response);\n *\n * // {\n * // \"status\": \"success\",\n * // \"versionInfo\": {\n * // \"version\": \"0.1.0\",\n * // \"dbSchemaVersion\": 2,\n * // \"labelSet\": {\n * // \"labelSetId\": \"subgraph\",\n * // \"labelSetVersion\": 0\n * // }\n * // }\n * // }\n * ```\n */\n async version(): Promise<EnsRainbow.VersionResponse> {\n const response = await fetch(new URL(\"/v1/version\", this.options.endpointUrl));\n\n return response.json() as Promise<EnsRainbow.VersionResponse>;\n }\n\n /**\n * Get a copy of the current client options.\n *\n * @returns a copy of the current client options.\n */\n getOptions(): Readonly<EnsRainbowApiClientOptions> {\n // build a deep copy to prevent modification\n const deepCopy = {\n cacheCapacity: this.options.cacheCapacity,\n endpointUrl: new URL(this.options.endpointUrl.href),\n labelSet: this.options.labelSet ? { ...this.options.labelSet } : undefined,\n } satisfies EnsRainbowApiClientOptions;\n\n return Object.freeze(deepCopy);\n }\n}\n\n/**\n * Determine if a heal response is an error.\n *\n * @param response the heal response to check\n * @returns true if the response is an error, false otherwise\n */\nexport const isHealError = (\n response: EnsRainbow.HealResponse,\n): response is EnsRainbow.HealError => {\n return response.status === StatusCode.Error;\n};\n\n/**\n * Determine if a heal response is cacheable.\n *\n * Server errors at not cachable and should be retried.\n *\n * @param response the heal response to check\n * @returns true if the response is cacheable, false otherwise\n */\nexport const isCacheableHealResponse = (\n response: EnsRainbow.HealResponse,\n): response is EnsRainbow.CacheableHealResponse => {\n return response.status === StatusCode.Success || response.errorCode !== ErrorCode.ServerError;\n};\n","export const DEFAULT_ENSRAINBOW_URL = \"https://api.ensrainbow.io\" as const;\n\nexport const StatusCode = {\n Success: \"success\",\n Error: \"error\",\n} as const;\n\nexport const ErrorCode = {\n BadRequest: 400,\n NotFound: 404,\n ServerError: 500,\n} as const;\n","export * from \"./client\";\nexport * from \"./consts\";\n\n// Re-export types from ensnode-sdk that are needed by consumers\nexport type {\n EnsRainbowClientLabelSet,\n EnsRainbowServerLabelSet,\n LabelSetId,\n LabelSetVersion,\n} from \"@ensnode/ensnode-sdk\";\n\n// Re-export utility functions and classes from ensnode-sdk that are needed by consumers\nexport { buildEnsRainbowClientLabelSet } from \"@ensnode/ensnode-sdk\";\n"],"mappings":"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","names":["buildEnsRainbowClientLabelSet"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ensnode/ensrainbow-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "ENSRainbow SDK for interacting with the ENSRainbow API.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,10 +30,6 @@
|
|
|
30
30
|
"./consts": {
|
|
31
31
|
"types": "./dist/consts.d.ts",
|
|
32
32
|
"default": "./dist/consts.js"
|
|
33
|
-
},
|
|
34
|
-
"./label-utils": {
|
|
35
|
-
"types": "./dist/label-utils.d.ts",
|
|
36
|
-
"default": "./dist/label-utils.js"
|
|
37
33
|
}
|
|
38
34
|
},
|
|
39
35
|
"publishConfig": {
|
|
@@ -47,14 +43,14 @@
|
|
|
47
43
|
"tsup": "^8.3.6",
|
|
48
44
|
"typescript": "^5.7.3",
|
|
49
45
|
"vitest": "^3.1.1",
|
|
50
|
-
"@ensnode/shared-configs": "0.
|
|
51
|
-
"@ensnode/ensnode-sdk": "0.
|
|
46
|
+
"@ensnode/shared-configs": "0.34.0",
|
|
47
|
+
"@ensnode/ensnode-sdk": "0.34.0"
|
|
52
48
|
},
|
|
53
49
|
"scripts": {
|
|
54
50
|
"prepublish": "tsup",
|
|
55
51
|
"test": "vitest",
|
|
56
52
|
"typecheck": "tsc --noEmit",
|
|
57
|
-
"lint": "biome check --write",
|
|
53
|
+
"lint": "biome check --write .",
|
|
58
54
|
"lint:ci": "biome ci"
|
|
59
55
|
},
|
|
60
56
|
"main": "./dist/index.js",
|
package/dist/label-utils.d.ts
DELETED
package/dist/label-utils.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
// src/label-utils.ts
|
|
2
|
-
import { hexToBytes } from "viem";
|
|
3
|
-
function labelHashToBytes(labelHash) {
|
|
4
|
-
try {
|
|
5
|
-
if (labelHash.length !== 66) {
|
|
6
|
-
throw new Error(`Invalid labelHash length ${labelHash.length} characters (expected 66)`);
|
|
7
|
-
}
|
|
8
|
-
if (labelHash !== labelHash.toLowerCase()) {
|
|
9
|
-
throw new Error("Labelhash must be in lowercase");
|
|
10
|
-
}
|
|
11
|
-
if (!labelHash.startsWith("0x")) {
|
|
12
|
-
throw new Error("Labelhash must be 0x-prefixed");
|
|
13
|
-
}
|
|
14
|
-
const bytes = hexToBytes(labelHash);
|
|
15
|
-
if (bytes.length !== 32) {
|
|
16
|
-
throw new Error(`Invalid labelHash length ${bytes.length} bytes (expected 32)`);
|
|
17
|
-
}
|
|
18
|
-
return bytes;
|
|
19
|
-
} catch (e) {
|
|
20
|
-
if (e instanceof Error) {
|
|
21
|
-
throw e;
|
|
22
|
-
}
|
|
23
|
-
throw new Error("Invalid hex format");
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
export {
|
|
27
|
-
labelHashToBytes
|
|
28
|
-
};
|
|
29
|
-
//# sourceMappingURL=label-utils.js.map
|
package/dist/label-utils.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/label-utils.ts"],"sourcesContent":["import type { LabelHash } from \"@ensnode/ensnode-sdk\";\nimport { ByteArray, hexToBytes } from \"viem\";\n\n/**\n * Converts a Labelhash to bytes, with validation\n * @param labelHash The Labelhash to convert\n * @returns A ByteArray containing the bytes\n * @throws Error if `labelHash` is not a valid 32-byte hex string\n */\nexport function labelHashToBytes(labelHash: LabelHash): ByteArray {\n try {\n if (labelHash.length !== 66) {\n throw new Error(`Invalid labelHash length ${labelHash.length} characters (expected 66)`);\n }\n if (labelHash !== labelHash.toLowerCase()) {\n throw new Error(\"Labelhash must be in lowercase\");\n }\n if (!labelHash.startsWith(\"0x\")) {\n throw new Error(\"Labelhash must be 0x-prefixed\");\n }\n const bytes = hexToBytes(labelHash);\n if (bytes.length !== 32) {\n // should be redundant but keeping it for the principle of defensive programming\n throw new Error(`Invalid labelHash length ${bytes.length} bytes (expected 32)`);\n }\n return bytes;\n } catch (e) {\n if (e instanceof Error) {\n throw e;\n }\n throw new Error(\"Invalid hex format\");\n }\n}\n"],"mappings":";AACA,SAAoB,kBAAkB;AAQ/B,SAAS,iBAAiB,WAAiC;AAChE,MAAI;AACF,QAAI,UAAU,WAAW,IAAI;AAC3B,YAAM,IAAI,MAAM,4BAA4B,UAAU,MAAM,2BAA2B;AAAA,IACzF;AACA,QAAI,cAAc,UAAU,YAAY,GAAG;AACzC,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AACA,QAAI,CAAC,UAAU,WAAW,IAAI,GAAG;AAC/B,YAAM,IAAI,MAAM,+BAA+B;AAAA,IACjD;AACA,UAAM,QAAQ,WAAW,SAAS;AAClC,QAAI,MAAM,WAAW,IAAI;AAEvB,YAAM,IAAI,MAAM,4BAA4B,MAAM,MAAM,sBAAsB;AAAA,IAChF;AACA,WAAO;AAAA,EACT,SAAS,GAAG;AACV,QAAI,aAAa,OAAO;AACtB,YAAM;AAAA,IACR;AACA,UAAM,IAAI,MAAM,oBAAoB;AAAA,EACtC;AACF;","names":[]}
|
package/dist/labelUtils.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { LabelHash } from '@ensnode/ensnode-sdk';
|
|
2
|
-
import { ByteArray } from 'viem';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Converts a Labelhash to bytes, with validation
|
|
6
|
-
* @param labelHash The Labelhash to convert
|
|
7
|
-
* @returns A ByteArray containing the bytes
|
|
8
|
-
* @throws Error if `labelHash` is not a valid 32-byte hex string
|
|
9
|
-
*/
|
|
10
|
-
declare function labelHashToBytes(labelHash: LabelHash): ByteArray;
|
|
11
|
-
|
|
12
|
-
export { labelHashToBytes };
|
package/dist/labelUtils.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
// src/label-utils.ts
|
|
2
|
-
import { hexToBytes } from "viem";
|
|
3
|
-
function labelHashToBytes(labelHash) {
|
|
4
|
-
try {
|
|
5
|
-
if (labelHash.length !== 66) {
|
|
6
|
-
throw new Error(`Invalid labelHash length ${labelHash.length} characters (expected 66)`);
|
|
7
|
-
}
|
|
8
|
-
if (labelHash !== labelHash.toLowerCase()) {
|
|
9
|
-
throw new Error("Labelhash must be in lowercase");
|
|
10
|
-
}
|
|
11
|
-
if (!labelHash.startsWith("0x")) {
|
|
12
|
-
throw new Error("Labelhash must be 0x-prefixed");
|
|
13
|
-
}
|
|
14
|
-
const bytes = hexToBytes(labelHash);
|
|
15
|
-
if (bytes.length !== 32) {
|
|
16
|
-
throw new Error(`Invalid labelHash length ${bytes.length} bytes (expected 32)`);
|
|
17
|
-
}
|
|
18
|
-
return bytes;
|
|
19
|
-
} catch (e) {
|
|
20
|
-
if (e instanceof Error) {
|
|
21
|
-
throw e;
|
|
22
|
-
}
|
|
23
|
-
throw new Error("Invalid hex format");
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
export {
|
|
27
|
-
labelHashToBytes
|
|
28
|
-
};
|
|
29
|
-
//# sourceMappingURL=labelUtils.js.map
|
package/dist/labelUtils.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/label-utils.ts"],"sourcesContent":["import type { LabelHash } from \"@ensnode/ensnode-sdk\";\nimport { ByteArray, hexToBytes } from \"viem\";\n\n/**\n * Converts a Labelhash to bytes, with validation\n * @param labelHash The Labelhash to convert\n * @returns A ByteArray containing the bytes\n * @throws Error if `labelHash` is not a valid 32-byte hex string\n */\nexport function labelHashToBytes(labelHash: LabelHash): ByteArray {\n try {\n if (labelHash.length !== 66) {\n throw new Error(`Invalid labelHash length ${labelHash.length} characters (expected 66)`);\n }\n if (labelHash !== labelHash.toLowerCase()) {\n throw new Error(\"Labelhash must be in lowercase\");\n }\n if (!labelHash.startsWith(\"0x\")) {\n throw new Error(\"Labelhash must be 0x-prefixed\");\n }\n const bytes = hexToBytes(labelHash);\n if (bytes.length !== 32) {\n // should be redundant but keeping it for the principle of defensive programming\n throw new Error(`Invalid labelHash length ${bytes.length} bytes (expected 32)`);\n }\n return bytes;\n } catch (e) {\n if (e instanceof Error) {\n throw e;\n }\n throw new Error(\"Invalid hex format\");\n }\n}\n"],"mappings":";AACA,SAAoB,kBAAkB;AAQ/B,SAAS,iBAAiB,WAAiC;AAChE,MAAI;AACF,QAAI,UAAU,WAAW,IAAI;AAC3B,YAAM,IAAI,MAAM,4BAA4B,UAAU,MAAM,2BAA2B;AAAA,IACzF;AACA,QAAI,cAAc,UAAU,YAAY,GAAG;AACzC,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AACA,QAAI,CAAC,UAAU,WAAW,IAAI,GAAG;AAC/B,YAAM,IAAI,MAAM,+BAA+B;AAAA,IACjD;AACA,UAAM,QAAQ,WAAW,SAAS;AAClC,QAAI,MAAM,WAAW,IAAI;AAEvB,YAAM,IAAI,MAAM,4BAA4B,MAAM,MAAM,sBAAsB;AAAA,IAChF;AACA,WAAO;AAAA,EACT,SAAS,GAAG;AACV,QAAI,aAAa,OAAO;AACtB,YAAM;AAAA,IACR;AACA,UAAM,IAAI,MAAM,oBAAoB;AAAA,EACtC;AACF;","names":[]}
|