zcashname-sdk 0.2.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/index.cjs ADDED
@@ -0,0 +1,281 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ CLAIM_PRICES: () => CLAIM_PRICES,
24
+ DEFAULT_CLAIM_PRICE: () => DEFAULT_CLAIM_PRICE,
25
+ DEFAULT_URL: () => DEFAULT_URL,
26
+ ErrorType: () => ErrorType,
27
+ UFVK: () => UFVK,
28
+ ZNSError: () => ZNSError,
29
+ buildBuyMemo: () => buildBuyMemo,
30
+ buildClaimMemo: () => buildClaimMemo,
31
+ buildDelistMemo: () => buildDelistMemo,
32
+ buildListMemo: () => buildListMemo,
33
+ buildUpdateMemo: () => buildUpdateMemo,
34
+ buildZcashUri: () => buildZcashUri,
35
+ claimCost: () => claimCost,
36
+ createClient: () => createClient,
37
+ decodeBase64Url: () => decodeBase64Url,
38
+ delistPayload: () => delistPayload,
39
+ getNonce: () => getNonce,
40
+ isAvailable: () => isAvailable,
41
+ isValidName: () => isValidName,
42
+ listPayload: () => listPayload,
43
+ listings: () => listings,
44
+ parseZip321Uri: () => parseZip321Uri,
45
+ resolve: () => resolve,
46
+ status: () => status,
47
+ toBase64Url: () => toBase64Url,
48
+ updatePayload: () => updatePayload
49
+ });
50
+ module.exports = __toCommonJS(index_exports);
51
+
52
+ // src/errors.ts
53
+ var ErrorType = /* @__PURE__ */ ((ErrorType2) => {
54
+ ErrorType2[ErrorType2["ParseError"] = -32700] = "ParseError";
55
+ ErrorType2[ErrorType2["InvalidRequest"] = -32600] = "InvalidRequest";
56
+ ErrorType2[ErrorType2["MethodNotFound"] = -32601] = "MethodNotFound";
57
+ ErrorType2[ErrorType2["InvalidParams"] = -32602] = "InvalidParams";
58
+ ErrorType2[ErrorType2["InternalError"] = -32603] = "InternalError";
59
+ ErrorType2[ErrorType2["HttpError"] = -1] = "HttpError";
60
+ ErrorType2[ErrorType2["UfvkMismatch"] = -2] = "UfvkMismatch";
61
+ return ErrorType2;
62
+ })(ErrorType || {});
63
+ var ZNSError = class extends Error {
64
+ constructor(type, message) {
65
+ super(message ?? ErrorType[type]);
66
+ this.name = "ZNSError";
67
+ this.type = type;
68
+ }
69
+ };
70
+
71
+ // src/constants.ts
72
+ var DEFAULT_URL = "https://names.zcash.me";
73
+ var UFVK = "uviewtest1h075nwxk0s66hyw0gmy5l2gmr37eahe9ewzgu2lff90rc85mazdhc66udklmd2p7cqm3mg2up8487pusvh78dh89y7mzlfgdl57tncqxrwshhc2kf26js0ymdwd476r0v7qn6es0etgjeg3g0y3pngvvf8zdawg6nlwca7jqy2fv82rc5skauw05ptfuf5twj67u0gzzvhakvkxpvx8rvf2rlh5yh560fdr6p28368kjxez5gu9azam5cm08ygre0uqwhvrkz7sr7ld0nyv05a0xrqeffdvhujafq3ke860skmxzshtjlrlew72vycu54pkgjtyp2phr6fmmkqlxvsan54jh7mc59r7kazgwwrcfnmqjm5pt40kjeafp6lwtx2lp4gm5pzg9c9ugphrsclfnz50spnsrersk34ht5mrevw9yvspkfjg9mjhusc588d855hdch0z82pr5fhkvaz3p4cmjlxujxqw2w20tpgyt3rzkwuuwl4r7";
74
+ var CLAIM_PRICES = {
75
+ 1: 6e8,
76
+ 2: 425e6,
77
+ 3: 3e8,
78
+ 4: 15e7,
79
+ 5: 75e6,
80
+ 6: 5e7
81
+ };
82
+ var DEFAULT_CLAIM_PRICE = 25e6;
83
+
84
+ // src/validation.ts
85
+ function isValidName(name) {
86
+ return /^[a-z0-9](?:[a-z0-9-]{0,60}[a-z0-9])?$/.test(name) && !name.includes("--");
87
+ }
88
+
89
+ // src/pricing.ts
90
+ function claimCost(nameLength) {
91
+ return CLAIM_PRICES[nameLength] ?? DEFAULT_CLAIM_PRICE;
92
+ }
93
+
94
+ // src/memo.ts
95
+ function listPayload(name, price, nonce) {
96
+ return `LIST:${name}:${price}:${nonce}`;
97
+ }
98
+ function delistPayload(name, nonce) {
99
+ return `DELIST:${name}:${nonce}`;
100
+ }
101
+ function updatePayload(name, newUa, nonce) {
102
+ return `UPDATE:${name}:${newUa}:${nonce}`;
103
+ }
104
+ function buildClaimMemo(name, ua) {
105
+ if (!isValidName(name)) throw new Error(`Invalid name: ${name}`);
106
+ return `ZNS:CLAIM:${name}:${ua}`;
107
+ }
108
+ function buildBuyMemo(name, buyerUa) {
109
+ if (!isValidName(name)) throw new Error(`Invalid name: ${name}`);
110
+ return `ZNS:BUY:${name}:${buyerUa}`;
111
+ }
112
+ function buildListMemo(name, price, nonce, signature) {
113
+ if (!isValidName(name)) throw new Error(`Invalid name: ${name}`);
114
+ return `ZNS:LIST:${name}:${price}:${nonce}:${signature}`;
115
+ }
116
+ function buildDelistMemo(name, nonce, signature) {
117
+ if (!isValidName(name)) throw new Error(`Invalid name: ${name}`);
118
+ return `ZNS:DELIST:${name}:${nonce}:${signature}`;
119
+ }
120
+ function buildUpdateMemo(name, newUa, nonce, signature) {
121
+ if (!isValidName(name)) throw new Error(`Invalid name: ${name}`);
122
+ return `ZNS:UPDATE:${name}:${newUa}:${nonce}:${signature}`;
123
+ }
124
+
125
+ // src/zip321.ts
126
+ function toBase64Url(text) {
127
+ try {
128
+ return btoa(unescape(encodeURIComponent(text))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
129
+ } catch {
130
+ return "";
131
+ }
132
+ }
133
+ function decodeBase64Url(value) {
134
+ try {
135
+ const normalized = String(value).replace(/-/g, "+").replace(/_/g, "/");
136
+ const paddingLength = normalized.length % 4 === 0 ? 0 : 4 - normalized.length % 4;
137
+ const padded = normalized + "=".repeat(paddingLength);
138
+ const binary = atob(padded);
139
+ const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));
140
+ return new TextDecoder().decode(bytes);
141
+ } catch {
142
+ return "";
143
+ }
144
+ }
145
+ function buildZcashUri(address, amount, memo) {
146
+ if (!address) return "";
147
+ const base = `zcash:${address}`;
148
+ const params = [];
149
+ if (amount !== void 0 && Number(amount) > 0) params.push(`amount=${amount}`);
150
+ if (memo) params.push(`memo=${toBase64Url(memo)}`);
151
+ return params.length ? `${base}?${params.join("&")}` : base;
152
+ }
153
+ function parseZip321Uri(uri) {
154
+ const withoutScheme = String(uri ?? "").replace(/^zcash:/i, "");
155
+ const [addressPart, queryPart = ""] = withoutScheme.split("?");
156
+ const address = addressPart.trim();
157
+ const params = new URLSearchParams(queryPart);
158
+ const amount = String(params.get("amount") ?? "").trim();
159
+ const memoRaw = String(params.get("memo") ?? "").trim();
160
+ const memoDecoded = memoRaw ? decodeBase64Url(memoRaw) : "";
161
+ return { address, amount, memoRaw, memoDecoded };
162
+ }
163
+
164
+ // src/rpc.ts
165
+ async function rpc(url, method, params = {}, id = 1) {
166
+ const body = JSON.stringify({ jsonrpc: "2.0", id, method, params });
167
+ const res = await fetch(url, {
168
+ method: "POST",
169
+ headers: { "Content-Type": "application/json" },
170
+ body
171
+ });
172
+ if (!res.ok) {
173
+ throw new ZNSError(-1 /* HttpError */, `HTTP ${res.status}: ${res.statusText}`);
174
+ }
175
+ const json = await res.json();
176
+ if (json.error) {
177
+ const type = Object.values(ErrorType).includes(json.error.code) ? json.error.code : -32603 /* InternalError */;
178
+ throw new ZNSError(type, json.error.message);
179
+ }
180
+ return json.result;
181
+ }
182
+
183
+ // src/client.ts
184
+ async function createClient(url = DEFAULT_URL, options = {}) {
185
+ let nextId = 1;
186
+ let verified = false;
187
+ async function call(method, params = {}) {
188
+ return rpc(url, method, params, nextId++);
189
+ }
190
+ if (!options.skipVerify) {
191
+ const s = await call("status");
192
+ if (s.ufvk !== UFVK) {
193
+ throw new ZNSError(
194
+ -2 /* UfvkMismatch */,
195
+ `UFVK mismatch: indexer returned "${s.ufvk.slice(0, 20)}..." but expected "${UFVK.slice(0, 20)}..."`
196
+ );
197
+ }
198
+ verified = true;
199
+ }
200
+ const client = {
201
+ url,
202
+ verified,
203
+ async resolve(query) {
204
+ return call("resolve", { query });
205
+ },
206
+ async listings() {
207
+ const result = await call("list_for_sale");
208
+ return result.listings;
209
+ },
210
+ async status() {
211
+ return call("status");
212
+ },
213
+ async isAvailable(name) {
214
+ const result = await client.resolve(name);
215
+ return result === null;
216
+ },
217
+ async getNonce(name) {
218
+ const result = await client.resolve(name);
219
+ return result?.nonce ?? null;
220
+ }
221
+ };
222
+ return client;
223
+ }
224
+
225
+ // src/index.ts
226
+ var defaultClient = null;
227
+ var defaultClientPromise = null;
228
+ function getDefaultClient() {
229
+ if (defaultClient) return Promise.resolve(defaultClient);
230
+ if (!defaultClientPromise) {
231
+ defaultClientPromise = createClient(DEFAULT_URL).then((c) => {
232
+ defaultClient = c;
233
+ return c;
234
+ });
235
+ }
236
+ return defaultClientPromise;
237
+ }
238
+ async function resolve(query) {
239
+ return (await getDefaultClient()).resolve(query);
240
+ }
241
+ async function listings() {
242
+ return (await getDefaultClient()).listings();
243
+ }
244
+ async function status() {
245
+ return (await getDefaultClient()).status();
246
+ }
247
+ async function isAvailable(name) {
248
+ return (await getDefaultClient()).isAvailable(name);
249
+ }
250
+ async function getNonce(name) {
251
+ return (await getDefaultClient()).getNonce(name);
252
+ }
253
+ // Annotate the CommonJS export names for ESM import in node:
254
+ 0 && (module.exports = {
255
+ CLAIM_PRICES,
256
+ DEFAULT_CLAIM_PRICE,
257
+ DEFAULT_URL,
258
+ ErrorType,
259
+ UFVK,
260
+ ZNSError,
261
+ buildBuyMemo,
262
+ buildClaimMemo,
263
+ buildDelistMemo,
264
+ buildListMemo,
265
+ buildUpdateMemo,
266
+ buildZcashUri,
267
+ claimCost,
268
+ createClient,
269
+ decodeBase64Url,
270
+ delistPayload,
271
+ getNonce,
272
+ isAvailable,
273
+ isValidName,
274
+ listPayload,
275
+ listings,
276
+ parseZip321Uri,
277
+ resolve,
278
+ status,
279
+ toBase64Url,
280
+ updatePayload
281
+ });
@@ -0,0 +1,93 @@
1
+ interface Registration {
2
+ name: string;
3
+ address: string;
4
+ txid: string;
5
+ height: number;
6
+ nonce: number;
7
+ signature: string | null;
8
+ }
9
+ interface Listing {
10
+ name: string;
11
+ price: number;
12
+ txid: string;
13
+ height: number;
14
+ signature: string;
15
+ }
16
+ interface ResolveResult extends Registration {
17
+ listing: Listing | null;
18
+ }
19
+ interface ListForSaleResult {
20
+ listings: Listing[];
21
+ }
22
+ interface StatusResult {
23
+ synced_height: number;
24
+ admin_pubkey: string;
25
+ ufvk: string;
26
+ registered: number;
27
+ listed: number;
28
+ }
29
+
30
+ declare enum ErrorType {
31
+ ParseError = -32700,
32
+ InvalidRequest = -32600,
33
+ MethodNotFound = -32601,
34
+ InvalidParams = -32602,
35
+ InternalError = -32603,
36
+ HttpError = -1,
37
+ UfvkMismatch = -2
38
+ }
39
+ declare class ZNSError extends Error {
40
+ type: ErrorType;
41
+ constructor(type: ErrorType, message?: string);
42
+ }
43
+
44
+ declare const DEFAULT_URL = "https://names.zcash.me";
45
+ declare const UFVK = "uviewtest1h075nwxk0s66hyw0gmy5l2gmr37eahe9ewzgu2lff90rc85mazdhc66udklmd2p7cqm3mg2up8487pusvh78dh89y7mzlfgdl57tncqxrwshhc2kf26js0ymdwd476r0v7qn6es0etgjeg3g0y3pngvvf8zdawg6nlwca7jqy2fv82rc5skauw05ptfuf5twj67u0gzzvhakvkxpvx8rvf2rlh5yh560fdr6p28368kjxez5gu9azam5cm08ygre0uqwhvrkz7sr7ld0nyv05a0xrqeffdvhujafq3ke860skmxzshtjlrlew72vycu54pkgjtyp2phr6fmmkqlxvsan54jh7mc59r7kazgwwrcfnmqjm5pt40kjeafp6lwtx2lp4gm5pzg9c9ugphrsclfnz50spnsrersk34ht5mrevw9yvspkfjg9mjhusc588d855hdch0z82pr5fhkvaz3p4cmjlxujxqw2w20tpgyt3rzkwuuwl4r7";
46
+ declare const CLAIM_PRICES: Record<number, number>;
47
+ declare const DEFAULT_CLAIM_PRICE = 25000000;
48
+
49
+ declare function isValidName(name: string): boolean;
50
+
51
+ declare function claimCost(nameLength: number): number;
52
+
53
+ declare function listPayload(name: string, price: number, nonce: number): string;
54
+ declare function delistPayload(name: string, nonce: number): string;
55
+ declare function updatePayload(name: string, newUa: string, nonce: number): string;
56
+ declare function buildClaimMemo(name: string, ua: string): string;
57
+ declare function buildBuyMemo(name: string, buyerUa: string): string;
58
+ declare function buildListMemo(name: string, price: number, nonce: number, signature: string): string;
59
+ declare function buildDelistMemo(name: string, nonce: number, signature: string): string;
60
+ declare function buildUpdateMemo(name: string, newUa: string, nonce: number, signature: string): string;
61
+
62
+ declare function toBase64Url(text: string): string;
63
+ declare function decodeBase64Url(value: string): string;
64
+ interface Zip321Parts {
65
+ address: string;
66
+ amount: string;
67
+ memoRaw: string;
68
+ memoDecoded: string;
69
+ }
70
+ declare function buildZcashUri(address: string, amount?: string | number, memo?: string): string;
71
+ declare function parseZip321Uri(uri: string): Zip321Parts;
72
+
73
+ interface ClientOptions {
74
+ skipVerify?: boolean;
75
+ }
76
+ interface ZNSClient {
77
+ readonly url: string;
78
+ readonly verified: boolean;
79
+ resolve(query: string): Promise<ResolveResult | null>;
80
+ listings(): Promise<Listing[]>;
81
+ status(): Promise<StatusResult>;
82
+ isAvailable(name: string): Promise<boolean>;
83
+ getNonce(name: string): Promise<number | null>;
84
+ }
85
+ declare function createClient(url?: string, options?: ClientOptions): Promise<ZNSClient>;
86
+
87
+ declare function resolve(query: string): Promise<ResolveResult | null>;
88
+ declare function listings(): Promise<Listing[]>;
89
+ declare function status(): Promise<StatusResult>;
90
+ declare function isAvailable(name: string): Promise<boolean>;
91
+ declare function getNonce(name: string): Promise<number | null>;
92
+
93
+ export { CLAIM_PRICES, type ClientOptions, DEFAULT_CLAIM_PRICE, DEFAULT_URL, ErrorType, type ListForSaleResult, type Listing, type Registration, type ResolveResult, type StatusResult, UFVK, type ZNSClient, ZNSError, type Zip321Parts, buildBuyMemo, buildClaimMemo, buildDelistMemo, buildListMemo, buildUpdateMemo, buildZcashUri, claimCost, createClient, decodeBase64Url, delistPayload, getNonce, isAvailable, isValidName, listPayload, listings, parseZip321Uri, resolve, status, toBase64Url, updatePayload };
@@ -0,0 +1,46 @@
1
+ interface Registration {
2
+ name: string;
3
+ address: string;
4
+ txid: string;
5
+ height: number;
6
+ nonce: number;
7
+ signature: string | null;
8
+ }
9
+ interface Listing {
10
+ name: string;
11
+ price: number;
12
+ txid: string;
13
+ height: number;
14
+ signature: string;
15
+ }
16
+ interface ResolveResult extends Registration {
17
+ listing: Listing | null;
18
+ }
19
+ interface ListForSaleResult {
20
+ listings: Listing[];
21
+ }
22
+ interface StatusResult {
23
+ synced_height: number;
24
+ admin_pubkey: string;
25
+ ufvk: string;
26
+ registered: number;
27
+ listed: number;
28
+ }
29
+ declare class ZNSError extends Error {
30
+ code: number;
31
+ constructor(code: number, message: string);
32
+ }
33
+ declare class ZNSClient {
34
+ private url;
35
+ private nextId;
36
+ constructor(url?: string);
37
+ /** Look up a ZNS name or Zcash address. Returns null if not found. */
38
+ resolve(query: string): Promise<ResolveResult | null>;
39
+ /** Get all names currently listed for sale. */
40
+ listForSale(): Promise<Listing[]>;
41
+ /** Get indexer status. */
42
+ status(): Promise<StatusResult>;
43
+ private call;
44
+ }
45
+
46
+ export { type ListForSaleResult, type Listing, type Registration, type ResolveResult, type StatusResult, ZNSClient, ZNSError, ZNSClient as default };
@@ -0,0 +1,93 @@
1
+ interface Registration {
2
+ name: string;
3
+ address: string;
4
+ txid: string;
5
+ height: number;
6
+ nonce: number;
7
+ signature: string | null;
8
+ }
9
+ interface Listing {
10
+ name: string;
11
+ price: number;
12
+ txid: string;
13
+ height: number;
14
+ signature: string;
15
+ }
16
+ interface ResolveResult extends Registration {
17
+ listing: Listing | null;
18
+ }
19
+ interface ListForSaleResult {
20
+ listings: Listing[];
21
+ }
22
+ interface StatusResult {
23
+ synced_height: number;
24
+ admin_pubkey: string;
25
+ ufvk: string;
26
+ registered: number;
27
+ listed: number;
28
+ }
29
+
30
+ declare enum ErrorType {
31
+ ParseError = -32700,
32
+ InvalidRequest = -32600,
33
+ MethodNotFound = -32601,
34
+ InvalidParams = -32602,
35
+ InternalError = -32603,
36
+ HttpError = -1,
37
+ UfvkMismatch = -2
38
+ }
39
+ declare class ZNSError extends Error {
40
+ type: ErrorType;
41
+ constructor(type: ErrorType, message?: string);
42
+ }
43
+
44
+ declare const DEFAULT_URL = "https://names.zcash.me";
45
+ declare const UFVK = "uviewtest1h075nwxk0s66hyw0gmy5l2gmr37eahe9ewzgu2lff90rc85mazdhc66udklmd2p7cqm3mg2up8487pusvh78dh89y7mzlfgdl57tncqxrwshhc2kf26js0ymdwd476r0v7qn6es0etgjeg3g0y3pngvvf8zdawg6nlwca7jqy2fv82rc5skauw05ptfuf5twj67u0gzzvhakvkxpvx8rvf2rlh5yh560fdr6p28368kjxez5gu9azam5cm08ygre0uqwhvrkz7sr7ld0nyv05a0xrqeffdvhujafq3ke860skmxzshtjlrlew72vycu54pkgjtyp2phr6fmmkqlxvsan54jh7mc59r7kazgwwrcfnmqjm5pt40kjeafp6lwtx2lp4gm5pzg9c9ugphrsclfnz50spnsrersk34ht5mrevw9yvspkfjg9mjhusc588d855hdch0z82pr5fhkvaz3p4cmjlxujxqw2w20tpgyt3rzkwuuwl4r7";
46
+ declare const CLAIM_PRICES: Record<number, number>;
47
+ declare const DEFAULT_CLAIM_PRICE = 25000000;
48
+
49
+ declare function isValidName(name: string): boolean;
50
+
51
+ declare function claimCost(nameLength: number): number;
52
+
53
+ declare function listPayload(name: string, price: number, nonce: number): string;
54
+ declare function delistPayload(name: string, nonce: number): string;
55
+ declare function updatePayload(name: string, newUa: string, nonce: number): string;
56
+ declare function buildClaimMemo(name: string, ua: string): string;
57
+ declare function buildBuyMemo(name: string, buyerUa: string): string;
58
+ declare function buildListMemo(name: string, price: number, nonce: number, signature: string): string;
59
+ declare function buildDelistMemo(name: string, nonce: number, signature: string): string;
60
+ declare function buildUpdateMemo(name: string, newUa: string, nonce: number, signature: string): string;
61
+
62
+ declare function toBase64Url(text: string): string;
63
+ declare function decodeBase64Url(value: string): string;
64
+ interface Zip321Parts {
65
+ address: string;
66
+ amount: string;
67
+ memoRaw: string;
68
+ memoDecoded: string;
69
+ }
70
+ declare function buildZcashUri(address: string, amount?: string | number, memo?: string): string;
71
+ declare function parseZip321Uri(uri: string): Zip321Parts;
72
+
73
+ interface ClientOptions {
74
+ skipVerify?: boolean;
75
+ }
76
+ interface ZNSClient {
77
+ readonly url: string;
78
+ readonly verified: boolean;
79
+ resolve(query: string): Promise<ResolveResult | null>;
80
+ listings(): Promise<Listing[]>;
81
+ status(): Promise<StatusResult>;
82
+ isAvailable(name: string): Promise<boolean>;
83
+ getNonce(name: string): Promise<number | null>;
84
+ }
85
+ declare function createClient(url?: string, options?: ClientOptions): Promise<ZNSClient>;
86
+
87
+ declare function resolve(query: string): Promise<ResolveResult | null>;
88
+ declare function listings(): Promise<Listing[]>;
89
+ declare function status(): Promise<StatusResult>;
90
+ declare function isAvailable(name: string): Promise<boolean>;
91
+ declare function getNonce(name: string): Promise<number | null>;
92
+
93
+ export { CLAIM_PRICES, type ClientOptions, DEFAULT_CLAIM_PRICE, DEFAULT_URL, ErrorType, type ListForSaleResult, type Listing, type Registration, type ResolveResult, type StatusResult, UFVK, type ZNSClient, ZNSError, type Zip321Parts, buildBuyMemo, buildClaimMemo, buildDelistMemo, buildListMemo, buildUpdateMemo, buildZcashUri, claimCost, createClient, decodeBase64Url, delistPayload, getNonce, isAvailable, isValidName, listPayload, listings, parseZip321Uri, resolve, status, toBase64Url, updatePayload };
package/dist/index.js ADDED
@@ -0,0 +1,229 @@
1
+ // src/errors.ts
2
+ var ErrorType = /* @__PURE__ */ ((ErrorType2) => {
3
+ ErrorType2[ErrorType2["ParseError"] = -32700] = "ParseError";
4
+ ErrorType2[ErrorType2["InvalidRequest"] = -32600] = "InvalidRequest";
5
+ ErrorType2[ErrorType2["MethodNotFound"] = -32601] = "MethodNotFound";
6
+ ErrorType2[ErrorType2["InvalidParams"] = -32602] = "InvalidParams";
7
+ ErrorType2[ErrorType2["InternalError"] = -32603] = "InternalError";
8
+ ErrorType2[ErrorType2["HttpError"] = -1] = "HttpError";
9
+ ErrorType2[ErrorType2["UfvkMismatch"] = -2] = "UfvkMismatch";
10
+ return ErrorType2;
11
+ })(ErrorType || {});
12
+ var ZNSError = class extends Error {
13
+ constructor(type, message) {
14
+ super(message ?? ErrorType[type]);
15
+ this.name = "ZNSError";
16
+ this.type = type;
17
+ }
18
+ };
19
+
20
+ // src/constants.ts
21
+ var DEFAULT_URL = "https://names.zcash.me";
22
+ var UFVK = "uviewtest1h075nwxk0s66hyw0gmy5l2gmr37eahe9ewzgu2lff90rc85mazdhc66udklmd2p7cqm3mg2up8487pusvh78dh89y7mzlfgdl57tncqxrwshhc2kf26js0ymdwd476r0v7qn6es0etgjeg3g0y3pngvvf8zdawg6nlwca7jqy2fv82rc5skauw05ptfuf5twj67u0gzzvhakvkxpvx8rvf2rlh5yh560fdr6p28368kjxez5gu9azam5cm08ygre0uqwhvrkz7sr7ld0nyv05a0xrqeffdvhujafq3ke860skmxzshtjlrlew72vycu54pkgjtyp2phr6fmmkqlxvsan54jh7mc59r7kazgwwrcfnmqjm5pt40kjeafp6lwtx2lp4gm5pzg9c9ugphrsclfnz50spnsrersk34ht5mrevw9yvspkfjg9mjhusc588d855hdch0z82pr5fhkvaz3p4cmjlxujxqw2w20tpgyt3rzkwuuwl4r7";
23
+ var CLAIM_PRICES = {
24
+ 1: 6e8,
25
+ 2: 425e6,
26
+ 3: 3e8,
27
+ 4: 15e7,
28
+ 5: 75e6,
29
+ 6: 5e7
30
+ };
31
+ var DEFAULT_CLAIM_PRICE = 25e6;
32
+
33
+ // src/validation.ts
34
+ function isValidName(name) {
35
+ return /^[a-z0-9](?:[a-z0-9-]{0,60}[a-z0-9])?$/.test(name) && !name.includes("--");
36
+ }
37
+
38
+ // src/pricing.ts
39
+ function claimCost(nameLength) {
40
+ return CLAIM_PRICES[nameLength] ?? DEFAULT_CLAIM_PRICE;
41
+ }
42
+
43
+ // src/memo.ts
44
+ function listPayload(name, price, nonce) {
45
+ return `LIST:${name}:${price}:${nonce}`;
46
+ }
47
+ function delistPayload(name, nonce) {
48
+ return `DELIST:${name}:${nonce}`;
49
+ }
50
+ function updatePayload(name, newUa, nonce) {
51
+ return `UPDATE:${name}:${newUa}:${nonce}`;
52
+ }
53
+ function buildClaimMemo(name, ua) {
54
+ if (!isValidName(name)) throw new Error(`Invalid name: ${name}`);
55
+ return `ZNS:CLAIM:${name}:${ua}`;
56
+ }
57
+ function buildBuyMemo(name, buyerUa) {
58
+ if (!isValidName(name)) throw new Error(`Invalid name: ${name}`);
59
+ return `ZNS:BUY:${name}:${buyerUa}`;
60
+ }
61
+ function buildListMemo(name, price, nonce, signature) {
62
+ if (!isValidName(name)) throw new Error(`Invalid name: ${name}`);
63
+ return `ZNS:LIST:${name}:${price}:${nonce}:${signature}`;
64
+ }
65
+ function buildDelistMemo(name, nonce, signature) {
66
+ if (!isValidName(name)) throw new Error(`Invalid name: ${name}`);
67
+ return `ZNS:DELIST:${name}:${nonce}:${signature}`;
68
+ }
69
+ function buildUpdateMemo(name, newUa, nonce, signature) {
70
+ if (!isValidName(name)) throw new Error(`Invalid name: ${name}`);
71
+ return `ZNS:UPDATE:${name}:${newUa}:${nonce}:${signature}`;
72
+ }
73
+
74
+ // src/zip321.ts
75
+ function toBase64Url(text) {
76
+ try {
77
+ return btoa(unescape(encodeURIComponent(text))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
78
+ } catch {
79
+ return "";
80
+ }
81
+ }
82
+ function decodeBase64Url(value) {
83
+ try {
84
+ const normalized = String(value).replace(/-/g, "+").replace(/_/g, "/");
85
+ const paddingLength = normalized.length % 4 === 0 ? 0 : 4 - normalized.length % 4;
86
+ const padded = normalized + "=".repeat(paddingLength);
87
+ const binary = atob(padded);
88
+ const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));
89
+ return new TextDecoder().decode(bytes);
90
+ } catch {
91
+ return "";
92
+ }
93
+ }
94
+ function buildZcashUri(address, amount, memo) {
95
+ if (!address) return "";
96
+ const base = `zcash:${address}`;
97
+ const params = [];
98
+ if (amount !== void 0 && Number(amount) > 0) params.push(`amount=${amount}`);
99
+ if (memo) params.push(`memo=${toBase64Url(memo)}`);
100
+ return params.length ? `${base}?${params.join("&")}` : base;
101
+ }
102
+ function parseZip321Uri(uri) {
103
+ const withoutScheme = String(uri ?? "").replace(/^zcash:/i, "");
104
+ const [addressPart, queryPart = ""] = withoutScheme.split("?");
105
+ const address = addressPart.trim();
106
+ const params = new URLSearchParams(queryPart);
107
+ const amount = String(params.get("amount") ?? "").trim();
108
+ const memoRaw = String(params.get("memo") ?? "").trim();
109
+ const memoDecoded = memoRaw ? decodeBase64Url(memoRaw) : "";
110
+ return { address, amount, memoRaw, memoDecoded };
111
+ }
112
+
113
+ // src/rpc.ts
114
+ async function rpc(url, method, params = {}, id = 1) {
115
+ const body = JSON.stringify({ jsonrpc: "2.0", id, method, params });
116
+ const res = await fetch(url, {
117
+ method: "POST",
118
+ headers: { "Content-Type": "application/json" },
119
+ body
120
+ });
121
+ if (!res.ok) {
122
+ throw new ZNSError(-1 /* HttpError */, `HTTP ${res.status}: ${res.statusText}`);
123
+ }
124
+ const json = await res.json();
125
+ if (json.error) {
126
+ const type = Object.values(ErrorType).includes(json.error.code) ? json.error.code : -32603 /* InternalError */;
127
+ throw new ZNSError(type, json.error.message);
128
+ }
129
+ return json.result;
130
+ }
131
+
132
+ // src/client.ts
133
+ async function createClient(url = DEFAULT_URL, options = {}) {
134
+ let nextId = 1;
135
+ let verified = false;
136
+ async function call(method, params = {}) {
137
+ return rpc(url, method, params, nextId++);
138
+ }
139
+ if (!options.skipVerify) {
140
+ const s = await call("status");
141
+ if (s.ufvk !== UFVK) {
142
+ throw new ZNSError(
143
+ -2 /* UfvkMismatch */,
144
+ `UFVK mismatch: indexer returned "${s.ufvk.slice(0, 20)}..." but expected "${UFVK.slice(0, 20)}..."`
145
+ );
146
+ }
147
+ verified = true;
148
+ }
149
+ const client = {
150
+ url,
151
+ verified,
152
+ async resolve(query) {
153
+ return call("resolve", { query });
154
+ },
155
+ async listings() {
156
+ const result = await call("list_for_sale");
157
+ return result.listings;
158
+ },
159
+ async status() {
160
+ return call("status");
161
+ },
162
+ async isAvailable(name) {
163
+ const result = await client.resolve(name);
164
+ return result === null;
165
+ },
166
+ async getNonce(name) {
167
+ const result = await client.resolve(name);
168
+ return result?.nonce ?? null;
169
+ }
170
+ };
171
+ return client;
172
+ }
173
+
174
+ // src/index.ts
175
+ var defaultClient = null;
176
+ var defaultClientPromise = null;
177
+ function getDefaultClient() {
178
+ if (defaultClient) return Promise.resolve(defaultClient);
179
+ if (!defaultClientPromise) {
180
+ defaultClientPromise = createClient(DEFAULT_URL).then((c) => {
181
+ defaultClient = c;
182
+ return c;
183
+ });
184
+ }
185
+ return defaultClientPromise;
186
+ }
187
+ async function resolve(query) {
188
+ return (await getDefaultClient()).resolve(query);
189
+ }
190
+ async function listings() {
191
+ return (await getDefaultClient()).listings();
192
+ }
193
+ async function status() {
194
+ return (await getDefaultClient()).status();
195
+ }
196
+ async function isAvailable(name) {
197
+ return (await getDefaultClient()).isAvailable(name);
198
+ }
199
+ async function getNonce(name) {
200
+ return (await getDefaultClient()).getNonce(name);
201
+ }
202
+ export {
203
+ CLAIM_PRICES,
204
+ DEFAULT_CLAIM_PRICE,
205
+ DEFAULT_URL,
206
+ ErrorType,
207
+ UFVK,
208
+ ZNSError,
209
+ buildBuyMemo,
210
+ buildClaimMemo,
211
+ buildDelistMemo,
212
+ buildListMemo,
213
+ buildUpdateMemo,
214
+ buildZcashUri,
215
+ claimCost,
216
+ createClient,
217
+ decodeBase64Url,
218
+ delistPayload,
219
+ getNonce,
220
+ isAvailable,
221
+ isValidName,
222
+ listPayload,
223
+ listings,
224
+ parseZip321Uri,
225
+ resolve,
226
+ status,
227
+ toBase64Url,
228
+ updatePayload
229
+ };
package/dist/index.mjs ADDED
@@ -0,0 +1,51 @@
1
+ // src/index.ts
2
+ var ZNSError = class extends Error {
3
+ constructor(code, message) {
4
+ super(message);
5
+ this.code = code;
6
+ this.name = "ZNSError";
7
+ }
8
+ };
9
+ var ZNSClient = class {
10
+ constructor(url = "http://127.0.0.1:3000") {
11
+ this.nextId = 1;
12
+ this.url = url;
13
+ }
14
+ /** Look up a ZNS name or Zcash address. Returns null if not found. */
15
+ async resolve(query) {
16
+ return this.call("resolve", { query });
17
+ }
18
+ /** Get all names currently listed for sale. */
19
+ async listForSale() {
20
+ const result = await this.call("list_for_sale", {});
21
+ return result.listings;
22
+ }
23
+ /** Get indexer status. */
24
+ async status() {
25
+ return this.call("status", {});
26
+ }
27
+ // ── JSON-RPC transport ──────────────────────────────────────────────────
28
+ async call(method, params) {
29
+ const id = this.nextId++;
30
+ const body = JSON.stringify({ jsonrpc: "2.0", id, method, params });
31
+ const res = await fetch(this.url, {
32
+ method: "POST",
33
+ headers: { "Content-Type": "application/json" },
34
+ body
35
+ });
36
+ if (!res.ok) {
37
+ throw new ZNSError(-1, `HTTP ${res.status}: ${res.statusText}`);
38
+ }
39
+ const json = await res.json();
40
+ if (json.error) {
41
+ throw new ZNSError(json.error.code, json.error.message);
42
+ }
43
+ return json.result;
44
+ }
45
+ };
46
+ var index_default = ZNSClient;
47
+ export {
48
+ ZNSClient,
49
+ ZNSError,
50
+ index_default as default
51
+ };
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "zcashname-sdk",
3
+ "version": "0.2.0",
4
+ "type": "module",
5
+ "description": "TypeScript SDK for the Zcash Name System (ZNS) JSON-RPC API",
6
+ "main": "dist/index.js",
7
+ "module": "dist/index.mjs",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": ["dist"],
17
+ "scripts": {
18
+ "build": "tsup src/index.ts --format cjs,esm --dts",
19
+ "test": "vitest run",
20
+ "test:watch": "vitest"
21
+ },
22
+ "license": "MIT",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "https://github.com/zcashme/ZNS.git",
26
+ "directory": "sdk/typescript"
27
+ },
28
+ "devDependencies": {
29
+ "tsup": "^8.0.0",
30
+ "typescript": "^5.4.0",
31
+ "vitest": "^2.0.0"
32
+ }
33
+ }