dnsofmoney 0.4.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/README.md ADDED
@@ -0,0 +1,110 @@
1
+ # dnsofmoney — TypeScript SDK
2
+
3
+ Resolve, register, send to, and check availability of `pay:` aliases using the DNS of Money API.
4
+
5
+ **No external dependencies** — uses only the built-in `fetch()` API.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install dnsofmoney
11
+ ```
12
+
13
+ > Not yet on npm — coming soon. For now, clone the repo and build from source:
14
+ > ```bash
15
+ > cd sdk/typescript && npm install && npm run build
16
+ > ```
17
+
18
+ ## Quick Start
19
+
20
+ ### Resolve a pay: alias
21
+
22
+ ```typescript
23
+ import { resolve } from "dnsofmoney";
24
+
25
+ const result = await resolve("pay:vendor.alpha");
26
+ console.log(result.entity?.display_name);
27
+ console.log(result.endpoints[0].rail);
28
+ console.log(result.resolution_status);
29
+ ```
30
+
31
+ ### Register a pay: alias
32
+
33
+ ```typescript
34
+ import { register } from "dnsofmoney";
35
+
36
+ const result = await register(
37
+ "pay:your.name",
38
+ "Your Name",
39
+ "fednow",
40
+ "fas_live_...",
41
+ );
42
+ console.log(result.alias_name);
43
+ console.log(result.registration_number);
44
+ ```
45
+
46
+ ### Check availability
47
+
48
+ ```typescript
49
+ import { checkAvailability } from "dnsofmoney";
50
+
51
+ const available = await checkAvailability("pay:desired.name");
52
+ console.log(available ? "Available!" : "Taken.");
53
+ ```
54
+
55
+ ### Preview a payment (dry-run, no API key)
56
+
57
+ ```typescript
58
+ import { sendPreview } from "dnsofmoney";
59
+
60
+ const preview = await sendPreview("pay:vendor.alpha");
61
+ console.log(preview.resolved, preview.rail, preview.destination_address);
62
+ ```
63
+
64
+ ### Send money to a pay: alias
65
+
66
+ ```typescript
67
+ import { send } from "dnsofmoney";
68
+
69
+ const receipt = await send("pay:vendor.alpha", 5.0, "fas_live_...", {
70
+ currency: "XRP",
71
+ memo: "invoice 1234",
72
+ // idempotencyKey auto-generated if omitted — safe to retry
73
+ });
74
+ console.log(receipt.status, receipt.rail, receipt.tx_hash);
75
+ ```
76
+
77
+ ### Client instance (reuse connections)
78
+
79
+ ```typescript
80
+ import { DNSOfMoneyClient } from "dnsofmoney";
81
+
82
+ const client = new DNSOfMoneyClient({ apiKey: "fas_live_..." });
83
+ const result = await client.resolve("pay:vendor.alpha");
84
+ const available = await client.checkAvailability("pay:new.name");
85
+ const preview = await client.sendPreview("pay:vendor.alpha");
86
+ const receipt = await client.send("pay:vendor.alpha", 5.0, { currency: "XRP" });
87
+ ```
88
+
89
+ ## Error Handling
90
+
91
+ ```typescript
92
+ import { resolve, AliasNotFoundError, AuthenticationError } from "dnsofmoney";
93
+
94
+ try {
95
+ const result = await resolve("pay:nonexistent.alias");
96
+ } catch (err) {
97
+ if (err instanceof AliasNotFoundError) {
98
+ console.log("Alias does not exist");
99
+ } else if (err instanceof AuthenticationError) {
100
+ console.log("Invalid API key");
101
+ }
102
+ }
103
+ ```
104
+
105
+ ## Links
106
+
107
+ - [Full documentation](https://docs.dnsofmoney.com)
108
+ - [FAS-1 specification](https://github.com/dnsofmoney/dns-of-money/blob/main/docs/FAS-1-spec.md)
109
+ - [Examples](https://github.com/dnsofmoney/dns-of-money/tree/main/examples)
110
+ - [JSON schemas](https://github.com/dnsofmoney/dns-of-money/tree/main/schemas)
@@ -0,0 +1,100 @@
1
+ /**
2
+ * DNS of Money SDK — TypeScript client.
3
+ *
4
+ * Resolve, register, and check availability of pay: aliases.
5
+ * Uses only the built-in fetch() API — no external dependencies.
6
+ *
7
+ * Usage:
8
+ * import { DNSOfMoneyClient } from "dnsofmoney";
9
+ *
10
+ * const client = new DNSOfMoneyClient({ apiKey: "fas_live_..." });
11
+ * const result = await client.resolve("pay:vendor.alpha");
12
+ */
13
+ import type { RegistrationResponse, ResolutionResponse, SendOptions, SendPreview, SendResult } from "./models";
14
+ export interface ClientOptions {
15
+ apiKey?: string;
16
+ baseUrl?: string;
17
+ timeout?: number;
18
+ }
19
+ export declare class DNSOfMoneyClient {
20
+ private readonly apiKey?;
21
+ private readonly baseUrl;
22
+ private readonly timeout;
23
+ constructor(options?: ClientOptions);
24
+ /**
25
+ * Resolve a pay: alias to payment credentials.
26
+ *
27
+ * No API key required for public aliases. Authenticated callers
28
+ * receive higher-tier responses with additional fields.
29
+ *
30
+ * @param aliasUri - A FAS-1 pay: URI (e.g., "pay:vendor.alpha").
31
+ * @throws {AliasNotFoundError} If the alias does not exist.
32
+ */
33
+ resolve(aliasUri: string): Promise<ResolutionResponse>;
34
+ /**
35
+ * Register a new pay: alias.
36
+ *
37
+ * Requires API key. The alias must not already be taken or reserved.
38
+ *
39
+ * @throws {AliasTakenError} If the alias is already registered.
40
+ * @throws {CapReachedError} If the founding tier cap has been reached.
41
+ * @throws {AuthenticationError} If the API key is missing or invalid.
42
+ */
43
+ register(aliasName: string, displayName: string, preferredRail: string, extra?: Record<string, unknown>): Promise<RegistrationResponse>;
44
+ /**
45
+ * Check if a pay: alias is available to register.
46
+ *
47
+ * No API key required.
48
+ *
49
+ * @returns true if available, false if taken or reserved.
50
+ */
51
+ checkAvailability(aliasName: string): Promise<boolean>;
52
+ /**
53
+ * Preview where a payment would go without executing.
54
+ *
55
+ * No API key required. Returns the destination address (masked),
56
+ * rail, fee estimate, and identity info.
57
+ *
58
+ * @param alias - A pay: alias (e.g., "pay:vendor.alpha") or bare name ("vendor.alpha").
59
+ * @throws {AliasNotFoundError} If the alias does not exist.
60
+ */
61
+ sendPreview(alias: string): Promise<SendPreview>;
62
+ /**
63
+ * Send money to a pay: alias.
64
+ *
65
+ * Requires API key. Resolves the alias globally, routes to the best
66
+ * payment rail, generates an ISO 20022 message, and executes settlement.
67
+ *
68
+ * @param alias - Target pay: alias (e.g., "pay:vendor.alpha").
69
+ * @param amount - Amount in currency units.
70
+ * @param options - Optional currency, memo, and idempotencyKey. An
71
+ * idempotency key is auto-generated if not provided.
72
+ * @throws {AliasNotFoundError} If the alias does not exist.
73
+ * @throws {AuthenticationError} If the API key is missing or invalid.
74
+ */
75
+ send(alias: string, amount: number, options?: SendOptions): Promise<SendResult>;
76
+ private headers;
77
+ private get;
78
+ private post;
79
+ private handleResponse;
80
+ }
81
+ /**
82
+ * Resolve a pay: alias. See DNSOfMoneyClient.resolve for full docs.
83
+ */
84
+ export declare function resolve(aliasUri: string, apiKey?: string, baseUrl?: string): Promise<ResolutionResponse>;
85
+ /**
86
+ * Register a pay: alias. See DNSOfMoneyClient.register for full docs.
87
+ */
88
+ export declare function register(aliasName: string, displayName: string, preferredRail: string, apiKey: string, baseUrl?: string, extra?: Record<string, unknown>): Promise<RegistrationResponse>;
89
+ /**
90
+ * Check alias availability. See DNSOfMoneyClient.checkAvailability for full docs.
91
+ */
92
+ export declare function checkAvailability(aliasName: string, baseUrl?: string): Promise<boolean>;
93
+ /**
94
+ * Preview a send-to-alias payment. See DNSOfMoneyClient.sendPreview for full docs.
95
+ */
96
+ export declare function sendPreview(alias: string, baseUrl?: string): Promise<SendPreview>;
97
+ /**
98
+ * Send money to a pay: alias. See DNSOfMoneyClient.send for full docs.
99
+ */
100
+ export declare function send(alias: string, amount: number, apiKey: string, options?: SendOptions, baseUrl?: string): Promise<SendResult>;
package/dist/client.js ADDED
@@ -0,0 +1,357 @@
1
+ "use strict";
2
+ /**
3
+ * DNS of Money SDK — TypeScript client.
4
+ *
5
+ * Resolve, register, and check availability of pay: aliases.
6
+ * Uses only the built-in fetch() API — no external dependencies.
7
+ *
8
+ * Usage:
9
+ * import { DNSOfMoneyClient } from "dnsofmoney";
10
+ *
11
+ * const client = new DNSOfMoneyClient({ apiKey: "fas_live_..." });
12
+ * const result = await client.resolve("pay:vendor.alpha");
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.DNSOfMoneyClient = void 0;
16
+ exports.resolve = resolve;
17
+ exports.register = register;
18
+ exports.checkAvailability = checkAvailability;
19
+ exports.sendPreview = sendPreview;
20
+ exports.send = send;
21
+ const exceptions_1 = require("./exceptions");
22
+ const DEFAULT_BASE_URL = "https://api.dnsofmoney.com";
23
+ class DNSOfMoneyClient {
24
+ constructor(options = {}) {
25
+ this.apiKey = options.apiKey;
26
+ this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
27
+ this.timeout = options.timeout ?? 10000;
28
+ }
29
+ /**
30
+ * Resolve a pay: alias to payment credentials.
31
+ *
32
+ * No API key required for public aliases. Authenticated callers
33
+ * receive higher-tier responses with additional fields.
34
+ *
35
+ * @param aliasUri - A FAS-1 pay: URI (e.g., "pay:vendor.alpha").
36
+ * @throws {AliasNotFoundError} If the alias does not exist.
37
+ */
38
+ async resolve(aliasUri) {
39
+ const raw = await this.get(`/resolve/${aliasUri}`);
40
+ const data = raw.success !== undefined ? (raw.data ?? raw) : raw;
41
+ return parseResolution(data);
42
+ }
43
+ /**
44
+ * Register a new pay: alias.
45
+ *
46
+ * Requires API key. The alias must not already be taken or reserved.
47
+ *
48
+ * @throws {AliasTakenError} If the alias is already registered.
49
+ * @throws {CapReachedError} If the founding tier cap has been reached.
50
+ * @throws {AuthenticationError} If the API key is missing or invalid.
51
+ */
52
+ async register(aliasName, displayName, preferredRail, extra = {}) {
53
+ const body = {
54
+ alias_name: aliasName,
55
+ display_name: displayName,
56
+ preferred_rail: preferredRail,
57
+ ...extra,
58
+ };
59
+ const data = await this.post("/v1/aliases", body);
60
+ return {
61
+ alias_name: data.alias_name ?? aliasName,
62
+ registration_number: data.registration_number,
63
+ anchor_status: data.anchor_status,
64
+ proof: data.proof,
65
+ created_at: data.created_at,
66
+ };
67
+ }
68
+ /**
69
+ * Check if a pay: alias is available to register.
70
+ *
71
+ * No API key required.
72
+ *
73
+ * @returns true if available, false if taken or reserved.
74
+ */
75
+ async checkAvailability(aliasName) {
76
+ const data = await this.get(`/v1/aliases/check/${aliasName}`);
77
+ return data.status === "available";
78
+ }
79
+ /**
80
+ * Preview where a payment would go without executing.
81
+ *
82
+ * No API key required. Returns the destination address (masked),
83
+ * rail, fee estimate, and identity info.
84
+ *
85
+ * @param alias - A pay: alias (e.g., "pay:vendor.alpha") or bare name ("vendor.alpha").
86
+ * @throws {AliasNotFoundError} If the alias does not exist.
87
+ */
88
+ async sendPreview(alias) {
89
+ const data = await this.get(`/api/v1/send/preview/${alias}`);
90
+ return {
91
+ alias: data.alias ?? alias,
92
+ resolved: data.resolved ?? false,
93
+ destination_address: data.destination_address,
94
+ display_name: data.display_name,
95
+ rail: data.rail,
96
+ currency: data.currency ?? "USD",
97
+ fee_estimate: data.fee_estimate,
98
+ identity: data.identity,
99
+ };
100
+ }
101
+ /**
102
+ * Send money to a pay: alias.
103
+ *
104
+ * Requires API key. Resolves the alias globally, routes to the best
105
+ * payment rail, generates an ISO 20022 message, and executes settlement.
106
+ *
107
+ * @param alias - Target pay: alias (e.g., "pay:vendor.alpha").
108
+ * @param amount - Amount in currency units.
109
+ * @param options - Optional currency, memo, and idempotencyKey. An
110
+ * idempotency key is auto-generated if not provided.
111
+ * @throws {AliasNotFoundError} If the alias does not exist.
112
+ * @throws {AuthenticationError} If the API key is missing or invalid.
113
+ */
114
+ async send(alias, amount, options = {}) {
115
+ const currency = options.currency ?? "USD";
116
+ const body = {
117
+ alias,
118
+ amount,
119
+ currency,
120
+ idempotency_key: options.idempotencyKey ?? generateIdempotencyKey(),
121
+ };
122
+ if (options.memo !== undefined) {
123
+ body.memo = options.memo;
124
+ }
125
+ const data = await this.post("/api/v1/send", body);
126
+ return {
127
+ transaction_id: data.transaction_id ?? "",
128
+ status: data.status ?? "",
129
+ alias: data.alias ?? alias,
130
+ amount: data.amount ?? amount,
131
+ currency: data.currency ?? currency,
132
+ rail: data.rail ?? "",
133
+ tx_hash: data.tx_hash,
134
+ settle_time_seconds: data.settle_time_seconds,
135
+ memo: data.memo,
136
+ created_at: data.created_at,
137
+ };
138
+ }
139
+ // ── Internal HTTP helpers ─────────────────────────────────────────────
140
+ headers() {
141
+ const h = { Accept: "application/json" };
142
+ if (this.apiKey) {
143
+ h["X-API-Key"] = this.apiKey;
144
+ }
145
+ return h;
146
+ }
147
+ async get(path) {
148
+ const controller = new AbortController();
149
+ const timer = setTimeout(() => controller.abort(), this.timeout);
150
+ try {
151
+ const resp = await fetch(`${this.baseUrl}${path}`, {
152
+ method: "GET",
153
+ headers: this.headers(),
154
+ signal: controller.signal,
155
+ });
156
+ return this.handleResponse(resp);
157
+ }
158
+ finally {
159
+ clearTimeout(timer);
160
+ }
161
+ }
162
+ async post(path, body) {
163
+ const controller = new AbortController();
164
+ const timer = setTimeout(() => controller.abort(), this.timeout);
165
+ try {
166
+ const resp = await fetch(`${this.baseUrl}${path}`, {
167
+ method: "POST",
168
+ headers: { ...this.headers(), "Content-Type": "application/json" },
169
+ body: JSON.stringify(body),
170
+ signal: controller.signal,
171
+ });
172
+ return this.handleResponse(resp);
173
+ }
174
+ finally {
175
+ clearTimeout(timer);
176
+ }
177
+ }
178
+ async handleResponse(resp) {
179
+ if (resp.ok) {
180
+ return resp.json();
181
+ }
182
+ let body = {};
183
+ try {
184
+ body = await resp.json();
185
+ }
186
+ catch {
187
+ // non-JSON error body — ignore
188
+ }
189
+ const errorCode = body.error_code ?? "";
190
+ const detail = body.detail ?? "";
191
+ if (resp.status === 401)
192
+ throw new exceptions_1.AuthenticationError();
193
+ if (resp.status === 404)
194
+ throw new exceptions_1.AliasNotFoundError(detail || "unknown alias");
195
+ if (resp.status === 409) {
196
+ if (errorCode === "CAP_EXCEEDED")
197
+ throw new exceptions_1.CapReachedError();
198
+ throw new exceptions_1.AliasTakenError(detail || "alias taken");
199
+ }
200
+ if (resp.status === 429) {
201
+ throw new exceptions_1.RateLimitError(body.retry_after);
202
+ }
203
+ throw new exceptions_1.DNSOfMoneyError(`HTTP ${resp.status}: ${resp.statusText}`, resp.status);
204
+ }
205
+ }
206
+ exports.DNSOfMoneyClient = DNSOfMoneyClient;
207
+ // ── Helpers ────────────────────────────────────────────────────────────────
208
+ /**
209
+ * Generate a unique idempotency key for a send. Prefers crypto.randomUUID
210
+ * (Node 19+, all modern browsers); falls back to a timestamp+random hex token.
211
+ */
212
+ function generateIdempotencyKey() {
213
+ const c = globalThis.crypto;
214
+ if (c?.randomUUID) {
215
+ return `sdk-${c.randomUUID()}`;
216
+ }
217
+ const rand = Math.random().toString(16).slice(2);
218
+ return `sdk-${Date.now().toString(16)}${rand}`;
219
+ }
220
+ // ── Module-level convenience functions ────────────────────────────────────
221
+ /**
222
+ * Resolve a pay: alias. See DNSOfMoneyClient.resolve for full docs.
223
+ */
224
+ async function resolve(aliasUri, apiKey, baseUrl = DEFAULT_BASE_URL) {
225
+ return new DNSOfMoneyClient({ apiKey, baseUrl }).resolve(aliasUri);
226
+ }
227
+ /**
228
+ * Register a pay: alias. See DNSOfMoneyClient.register for full docs.
229
+ */
230
+ async function register(aliasName, displayName, preferredRail, apiKey, baseUrl = DEFAULT_BASE_URL, extra = {}) {
231
+ return new DNSOfMoneyClient({ apiKey, baseUrl }).register(aliasName, displayName, preferredRail, extra);
232
+ }
233
+ /**
234
+ * Check alias availability. See DNSOfMoneyClient.checkAvailability for full docs.
235
+ */
236
+ async function checkAvailability(aliasName, baseUrl = DEFAULT_BASE_URL) {
237
+ return new DNSOfMoneyClient({ baseUrl }).checkAvailability(aliasName);
238
+ }
239
+ /**
240
+ * Preview a send-to-alias payment. See DNSOfMoneyClient.sendPreview for full docs.
241
+ */
242
+ async function sendPreview(alias, baseUrl = DEFAULT_BASE_URL) {
243
+ return new DNSOfMoneyClient({ baseUrl }).sendPreview(alias);
244
+ }
245
+ /**
246
+ * Send money to a pay: alias. See DNSOfMoneyClient.send for full docs.
247
+ */
248
+ async function send(alias, amount, apiKey, options = {}, baseUrl = DEFAULT_BASE_URL) {
249
+ return new DNSOfMoneyClient({ apiKey, baseUrl }).send(alias, amount, options);
250
+ }
251
+ // ── Response parsing ──────────────────────────────────────────────────────
252
+ function parseResolution(data) {
253
+ // Entity — may be nested object or top-level fields
254
+ let entity;
255
+ if (data.entity) {
256
+ entity = {
257
+ display_name: data.entity.display_name ?? "",
258
+ entity_type: data.entity.entity_type,
259
+ jurisdiction: data.entity.jurisdiction,
260
+ kyc_status: data.entity.kyc_status,
261
+ };
262
+ }
263
+ else if (data.display_name) {
264
+ entity = {
265
+ display_name: data.display_name ?? "",
266
+ entity_type: data.entity_type,
267
+ };
268
+ }
269
+ // Endpoints — handle both flat array and preferred_endpoint + fallback
270
+ const endpoints = [];
271
+ if (data.preferred_endpoint) {
272
+ const ep = data.preferred_endpoint;
273
+ endpoints.push({
274
+ rail: ep.rail_type ?? ep.rail ?? "",
275
+ currency: ep.currency ?? "USD",
276
+ address: ep.address,
277
+ priority: ep.priority ?? 1,
278
+ fee_estimate: ep.fee_estimate,
279
+ settlement_latency: ep.settlement_latency,
280
+ routing_metadata: ep.routing_metadata,
281
+ });
282
+ for (const fb of data.fallback_endpoints ?? []) {
283
+ endpoints.push({
284
+ rail: fb.rail_type ?? fb.rail ?? "",
285
+ currency: fb.currency ?? "USD",
286
+ address: fb.address,
287
+ priority: fb.priority ?? 2,
288
+ fee_estimate: fb.fee_estimate,
289
+ settlement_latency: fb.settlement_latency,
290
+ routing_metadata: fb.routing_metadata,
291
+ });
292
+ }
293
+ }
294
+ else {
295
+ for (const ep of data.endpoints ?? []) {
296
+ endpoints.push({
297
+ rail: ep.rail ?? "",
298
+ currency: ep.currency ?? "USD",
299
+ address: ep.address,
300
+ priority: ep.priority ?? 1,
301
+ fee_estimate: ep.fee_estimate,
302
+ settlement_latency: ep.settlement_latency,
303
+ routing_metadata: ep.routing_metadata,
304
+ });
305
+ }
306
+ }
307
+ // Compliance
308
+ let compliance;
309
+ if (data.compliance) {
310
+ const c = data.compliance;
311
+ compliance = {
312
+ sanctions_checked: c.sanctions_checked ?? c.screened ?? false,
313
+ fatf_risk_rating: c.fatf_risk_rating,
314
+ requires_purpose_code: c.requires_purpose_code ?? false,
315
+ screened: c.screened,
316
+ result: c.result,
317
+ provider: c.provider,
318
+ screened_at: c.screened_at,
319
+ cached: c.cached,
320
+ };
321
+ }
322
+ // Identity (NFT + generative art)
323
+ let identity;
324
+ if (data.identity) {
325
+ const i = data.identity;
326
+ identity = {
327
+ nft_token_id: i.nft_token_id,
328
+ image_uri: i.image_uri,
329
+ metadata_uri: i.metadata_uri,
330
+ image_url: i.image_url,
331
+ nft_explorer_url: i.nft_explorer_url,
332
+ generation: i.generation,
333
+ identity_status: i.identity_status,
334
+ tier: i.tier,
335
+ };
336
+ }
337
+ return {
338
+ resolution_id: data.resolution_id ?? "",
339
+ alias_uri: data.alias ?? "",
340
+ resolved_at: data.resolved_at ?? "",
341
+ ttl_seconds: data.ttl_seconds ?? 300,
342
+ message_id: data.message_id,
343
+ entity_id: data.entity_id,
344
+ entity,
345
+ endpoints,
346
+ compliance,
347
+ iso20022_hint: data.iso20022_hint,
348
+ identity,
349
+ rail_score: data.rail_score,
350
+ resolution_status: data.status ?? data.resolution_status ?? "resolved",
351
+ caller_tier: data.caller_tier,
352
+ resolved_from: data.resolved_from ?? "origin",
353
+ cache_hit: data.cache_hit ?? false,
354
+ agent_commerce: data.agent_commerce,
355
+ warnings: data.warnings ?? [],
356
+ };
357
+ }
@@ -0,0 +1,26 @@
1
+ /** Base error for all DNS of Money SDK errors. */
2
+ export declare class DNSOfMoneyError extends Error {
3
+ readonly statusCode?: number;
4
+ constructor(message: string, statusCode?: number);
5
+ }
6
+ /** Raised when a pay: alias does not exist (HTTP 404). */
7
+ export declare class AliasNotFoundError extends DNSOfMoneyError {
8
+ constructor(alias: string);
9
+ }
10
+ /** Raised when a pay: alias is already registered (HTTP 409). */
11
+ export declare class AliasTakenError extends DNSOfMoneyError {
12
+ constructor(alias: string);
13
+ }
14
+ /** Raised when the API key is missing or invalid (HTTP 401). */
15
+ export declare class AuthenticationError extends DNSOfMoneyError {
16
+ constructor();
17
+ }
18
+ /** Raised when the API rate limit is exceeded (HTTP 429). */
19
+ export declare class RateLimitError extends DNSOfMoneyError {
20
+ readonly retryAfter?: number;
21
+ constructor(retryAfter?: number);
22
+ }
23
+ /** Raised when the founding tier cap (500) has been reached. */
24
+ export declare class CapReachedError extends DNSOfMoneyError {
25
+ constructor();
26
+ }
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CapReachedError = exports.RateLimitError = exports.AuthenticationError = exports.AliasTakenError = exports.AliasNotFoundError = exports.DNSOfMoneyError = void 0;
4
+ /** Base error for all DNS of Money SDK errors. */
5
+ class DNSOfMoneyError extends Error {
6
+ constructor(message, statusCode) {
7
+ super(message);
8
+ this.name = "DNSOfMoneyError";
9
+ this.statusCode = statusCode;
10
+ }
11
+ }
12
+ exports.DNSOfMoneyError = DNSOfMoneyError;
13
+ /** Raised when a pay: alias does not exist (HTTP 404). */
14
+ class AliasNotFoundError extends DNSOfMoneyError {
15
+ constructor(alias) {
16
+ super(`Alias not found: ${alias}`, 404);
17
+ this.name = "AliasNotFoundError";
18
+ }
19
+ }
20
+ exports.AliasNotFoundError = AliasNotFoundError;
21
+ /** Raised when a pay: alias is already registered (HTTP 409). */
22
+ class AliasTakenError extends DNSOfMoneyError {
23
+ constructor(alias) {
24
+ super(`Alias already taken: ${alias}`, 409);
25
+ this.name = "AliasTakenError";
26
+ }
27
+ }
28
+ exports.AliasTakenError = AliasTakenError;
29
+ /** Raised when the API key is missing or invalid (HTTP 401). */
30
+ class AuthenticationError extends DNSOfMoneyError {
31
+ constructor() {
32
+ super("Invalid or missing API key", 401);
33
+ this.name = "AuthenticationError";
34
+ }
35
+ }
36
+ exports.AuthenticationError = AuthenticationError;
37
+ /** Raised when the API rate limit is exceeded (HTTP 429). */
38
+ class RateLimitError extends DNSOfMoneyError {
39
+ constructor(retryAfter) {
40
+ const msg = retryAfter
41
+ ? `Rate limit exceeded — retry after ${retryAfter}s`
42
+ : "Rate limit exceeded";
43
+ super(msg, 429);
44
+ this.name = "RateLimitError";
45
+ this.retryAfter = retryAfter;
46
+ }
47
+ }
48
+ exports.RateLimitError = RateLimitError;
49
+ /** Raised when the founding tier cap (500) has been reached. */
50
+ class CapReachedError extends DNSOfMoneyError {
51
+ constructor() {
52
+ super("Founding tier cap reached (500/500)", 409);
53
+ this.name = "CapReachedError";
54
+ }
55
+ }
56
+ exports.CapReachedError = CapReachedError;
@@ -0,0 +1,4 @@
1
+ export { DNSOfMoneyClient, resolve, register, checkAvailability, sendPreview, send, } from "./client";
2
+ export type { ClientOptions } from "./client";
3
+ export { DNSOfMoneyError, AliasNotFoundError, AliasTakenError, AuthenticationError, RateLimitError, CapReachedError, } from "./exceptions";
4
+ export type { Entity, Endpoint, Compliance, Identity, AgentCard, ResolutionResponse, RegistrationResponse, SendPreview, SendResult, SendOptions, } from "./models";
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CapReachedError = exports.RateLimitError = exports.AuthenticationError = exports.AliasTakenError = exports.AliasNotFoundError = exports.DNSOfMoneyError = exports.send = exports.sendPreview = exports.checkAvailability = exports.register = exports.resolve = exports.DNSOfMoneyClient = void 0;
4
+ var client_1 = require("./client");
5
+ Object.defineProperty(exports, "DNSOfMoneyClient", { enumerable: true, get: function () { return client_1.DNSOfMoneyClient; } });
6
+ Object.defineProperty(exports, "resolve", { enumerable: true, get: function () { return client_1.resolve; } });
7
+ Object.defineProperty(exports, "register", { enumerable: true, get: function () { return client_1.register; } });
8
+ Object.defineProperty(exports, "checkAvailability", { enumerable: true, get: function () { return client_1.checkAvailability; } });
9
+ Object.defineProperty(exports, "sendPreview", { enumerable: true, get: function () { return client_1.sendPreview; } });
10
+ Object.defineProperty(exports, "send", { enumerable: true, get: function () { return client_1.send; } });
11
+ var exceptions_1 = require("./exceptions");
12
+ Object.defineProperty(exports, "DNSOfMoneyError", { enumerable: true, get: function () { return exceptions_1.DNSOfMoneyError; } });
13
+ Object.defineProperty(exports, "AliasNotFoundError", { enumerable: true, get: function () { return exceptions_1.AliasNotFoundError; } });
14
+ Object.defineProperty(exports, "AliasTakenError", { enumerable: true, get: function () { return exceptions_1.AliasTakenError; } });
15
+ Object.defineProperty(exports, "AuthenticationError", { enumerable: true, get: function () { return exceptions_1.AuthenticationError; } });
16
+ Object.defineProperty(exports, "RateLimitError", { enumerable: true, get: function () { return exceptions_1.RateLimitError; } });
17
+ Object.defineProperty(exports, "CapReachedError", { enumerable: true, get: function () { return exceptions_1.CapReachedError; } });
@@ -0,0 +1,108 @@
1
+ /** The entity (person, business, agent) that owns a pay: alias. */
2
+ export interface Entity {
3
+ display_name: string;
4
+ entity_type?: string;
5
+ jurisdiction?: string;
6
+ kyc_status?: string;
7
+ }
8
+ /** A single payment endpoint returned by resolution. */
9
+ export interface Endpoint {
10
+ rail: string;
11
+ currency: string;
12
+ address?: string;
13
+ priority: number;
14
+ fee_estimate?: string;
15
+ settlement_latency?: string;
16
+ routing_metadata?: Record<string, unknown>;
17
+ }
18
+ /** Compliance screening result attached to a resolution. */
19
+ export interface Compliance {
20
+ sanctions_checked: boolean;
21
+ fatf_risk_rating?: string;
22
+ requires_purpose_code: boolean;
23
+ screened?: boolean;
24
+ result?: string;
25
+ provider?: string;
26
+ screened_at?: string;
27
+ cached?: boolean;
28
+ }
29
+ /** On-chain identity linked to a pay: alias (NFT + generative art). */
30
+ export interface Identity {
31
+ nft_token_id?: string;
32
+ image_uri?: string;
33
+ metadata_uri?: string;
34
+ image_url?: string;
35
+ nft_explorer_url?: string;
36
+ generation?: number;
37
+ identity_status?: string;
38
+ tier?: string;
39
+ }
40
+ /** AP2/A2A-003 agent capability manifest. */
41
+ export interface AgentCard {
42
+ name: string;
43
+ endpoint: string;
44
+ capabilities: string[];
45
+ authentication?: string;
46
+ domains: string[];
47
+ protocol_versions: string[];
48
+ }
49
+ /** Full resolution response from the DNS of Money API. */
50
+ export interface ResolutionResponse {
51
+ resolution_id: string;
52
+ alias_uri: string;
53
+ resolved_at: string;
54
+ ttl_seconds: number;
55
+ message_id?: string;
56
+ entity_id?: string;
57
+ entity?: Entity;
58
+ endpoints: Endpoint[];
59
+ compliance?: Compliance;
60
+ iso20022_hint?: Record<string, unknown>;
61
+ identity?: Identity;
62
+ rail_score?: Record<string, unknown>;
63
+ resolution_status: string;
64
+ caller_tier?: number;
65
+ resolved_from: string;
66
+ cache_hit: boolean;
67
+ agent_commerce?: Record<string, unknown>;
68
+ warnings: string[];
69
+ }
70
+ /** Response from a successful alias registration. */
71
+ export interface RegistrationResponse {
72
+ alias_name: string;
73
+ registration_number?: number;
74
+ anchor_status?: string;
75
+ proof?: Record<string, unknown>;
76
+ created_at?: string;
77
+ }
78
+ /** Preview of where a payment would go (dry-run, no execution). */
79
+ export interface SendPreview {
80
+ alias: string;
81
+ resolved: boolean;
82
+ destination_address?: string;
83
+ display_name?: string;
84
+ rail?: string;
85
+ currency: string;
86
+ fee_estimate?: string;
87
+ identity?: Record<string, unknown>;
88
+ }
89
+ /** Result of a send-to-alias payment execution. */
90
+ export interface SendResult {
91
+ transaction_id: string;
92
+ status: string;
93
+ alias: string;
94
+ amount: number;
95
+ currency: string;
96
+ rail: string;
97
+ tx_hash?: string;
98
+ settle_time_seconds?: number;
99
+ memo?: string;
100
+ created_at?: string;
101
+ }
102
+ /** Optional parameters for a send-to-alias payment. */
103
+ export interface SendOptions {
104
+ currency?: string;
105
+ memo?: string;
106
+ /** Unique key to prevent double-send. Auto-generated if not provided. */
107
+ idempotencyKey?: string;
108
+ }
package/dist/models.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "dnsofmoney",
3
+ "version": "0.4.0",
4
+ "description": "DNS of Money — pay: alias resolution + send SDK",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": ["dist"],
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "test": "echo 'Tests coming soon'"
11
+ },
12
+ "keywords": ["payments", "dns", "fintech", "xrpl", "iso20022", "fas-1"],
13
+ "license": "MIT",
14
+ "dependencies": {},
15
+ "devDependencies": {
16
+ "typescript": "^5.0.0"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/dnsofmoney/dns-of-money"
21
+ },
22
+ "homepage": "https://dnsofmoney.com"
23
+ }