@decdn/client 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,156 @@
1
+ import { type Fetch } from "./http.js";
2
+ import { type BundleManifest, type ManifestEntry } from "./manifest.js";
3
+ import { LoopbackApi } from "./loopback.js";
4
+ import { PointerApi, type PointerDomain } from "./pointer.js";
5
+ import { type DecdnUri } from "./uri.js";
6
+ /** Where the client runs and how it reaches the gateway. */
7
+ export type Context = "public" | "loopback" | "site";
8
+ /** `"auto"` verifies what can be verified; `true` refuses what cannot; `false` verifies nothing. */
9
+ export type VerifyMode = "auto" | boolean;
10
+ export interface OpenOptions {
11
+ /** The gateway's origin: `https://decdn.link`, or `http://127.0.0.1:8484` for a loopback gateway. */
12
+ gatewayUrl?: string;
13
+ /** The loopback gateway's token (`~/.decdn/gateway/token`). */
14
+ token?: string;
15
+ /** The host whose capability pays on a loopback gateway, sent as `x-decdn-host`. Required with `token`. */
16
+ host?: string;
17
+ /** The chain and registry pointers are signed for. Required by `pointer.set`. */
18
+ pointer?: PointerDomain;
19
+ /** The `fetch` to use. Default: the global one. */
20
+ fetch?: Fetch;
21
+ /** The default verification of `get`. Default `"auto"`. */
22
+ verify?: VerifyMode;
23
+ /** How many manifests the client keeps parsed, by hash. Default 64. */
24
+ manifestCacheSize?: number;
25
+ }
26
+ /** A byte window: `length` bytes from `offset`, or to the end without `length`. */
27
+ export interface ByteRange {
28
+ offset: number;
29
+ length?: number;
30
+ }
31
+ export interface GetOptions {
32
+ range?: ByteRange;
33
+ signal?: AbortSignal;
34
+ verify?: VerifyMode;
35
+ /** Wait out one `Retry-After` on 402, 429 or 503 and try once more. */
36
+ retry?: boolean;
37
+ }
38
+ /** What `head` knows about content without fetching it. */
39
+ export interface HeadInfo {
40
+ size?: number;
41
+ hash?: string;
42
+ contentType?: string;
43
+ }
44
+ /** What a URI names, once its manifest is read. */
45
+ export interface Resolved {
46
+ kind: DecdnUri["kind"];
47
+ /** The URI's hash: of the blob, or of the bundle manifest. */
48
+ hash: string;
49
+ /** The manifest entry an entry URI names. */
50
+ entry?: ManifestEntry;
51
+ /** The bundle or entry on its site origin. */
52
+ siteUrl?: string;
53
+ /** The URI on the gateway's bare host (or under `/_decdn/` on a site). */
54
+ bareUrl: string;
55
+ }
56
+ /** The gateway's answer: a stream that ends with an error rather than `done` when its bytes fail verification. */
57
+ export declare class DecdnResponse {
58
+ readonly status: number;
59
+ readonly headers: Headers;
60
+ readonly url: string;
61
+ readonly contentType: string;
62
+ readonly contentLength?: number;
63
+ readonly contentRange?: {
64
+ offset: number;
65
+ length: number;
66
+ size: number;
67
+ };
68
+ /**
69
+ * `true`: the body is hashed as it streams, and ends with `HASH_MISMATCH`
70
+ * instead of `done` unless it hashes to the hash that names it.
71
+ * `"skipped"`: the bytes cannot be verified (a range, a rewritten page, a
72
+ * bundle listing). `false`: verification was turned off.
73
+ */
74
+ readonly verified: boolean | "skipped";
75
+ readonly body: ReadableStream<Uint8Array>;
76
+ /** @internal */
77
+ constructor(response: Response, body: ReadableStream<Uint8Array>, verified: boolean | "skipped", contentType?: string);
78
+ /** The whole body. Rejects with `HASH_MISMATCH` or `TRUNCATED`. */
79
+ bytes(): Promise<Uint8Array>;
80
+ text(): Promise<string>;
81
+ json(): Promise<unknown>;
82
+ }
83
+ export declare class DecdnClient {
84
+ readonly context: Context;
85
+ /** Namespace pointers (public gateway). */
86
+ readonly pointer: PointerApi;
87
+ /** The delegate and capability API (loopback gateway). */
88
+ readonly loopback: LoopbackApi;
89
+ /** @internal */
90
+ readonly fetch: Fetch;
91
+ /** @internal The bare origin: the gateway URL's, or the site's own. */
92
+ readonly origin: string;
93
+ /** @internal */
94
+ readonly pointerDomain?: PointerDomain;
95
+ private readonly gateway?;
96
+ private readonly site?;
97
+ private readonly token?;
98
+ private readonly host?;
99
+ private readonly verify;
100
+ private readonly cacheSize;
101
+ private readonly manifests;
102
+ private constructor();
103
+ /**
104
+ * A client for the gateway at `gatewayUrl`, or, in a page served from a
105
+ * site origin (`[<ns>.]<hash32>.<host>`, or `<ns>.<host>` under the
106
+ * configured gateway), for that site. A loopback `gatewayUrl` opens the
107
+ * loopback gateway from any page; a page, which cannot send the token,
108
+ * reaches its delegate and capability API alone.
109
+ */
110
+ static open(opts?: OpenOptions): Promise<DecdnClient>;
111
+ /** @internal Headers every bare-host request carries. */
112
+ authHeaders(): Record<string, string>;
113
+ private parse;
114
+ /** The URI on the bare host, or under `/_decdn/` on a site. */
115
+ private bareUrl;
116
+ /** The site URL of a bundle or an entry. */
117
+ siteUrl(uri: string | DecdnUri): string;
118
+ /** The host a namespace's pointer serves at on a public gateway: `https://<ns>.<host>/`. */
119
+ namespaceUrl(namespace: bigint | number): string;
120
+ /** The hash a manifest call names, or the site's own. */
121
+ private manifestHash;
122
+ /** The bundle manifest a hash or URI names, parsed and verified; cached per client by hash. */
123
+ manifest(hashOrUri?: string | DecdnUri, signal?: AbortSignal): Promise<BundleManifest>;
124
+ /** The manifest entry `uri` names; `NOT_FOUND` when the bundle has none. */
125
+ private entryOf;
126
+ /** What `uri` names: for a bundle or an entry, after reading its manifest. */
127
+ resolve(uri: string | DecdnUri): Promise<Resolved>;
128
+ /** A request to the gateway; a non-2xx answer is thrown as a `DecdnError`. */
129
+ private request;
130
+ /** An entry by its own hash, as a blob: the bytes the manifest names, unrewritten. */
131
+ private entryBlobUrl;
132
+ /**
133
+ * Where an entry comes from, given its manifest entry (when verifying).
134
+ * `own` holds the query of a path on the site's own bundle: the site serves
135
+ * by path alone and leaves the query to the page, and its host already
136
+ * names the namespace.
137
+ */
138
+ private entryUrl;
139
+ private plan;
140
+ private planEntry;
141
+ /**
142
+ * Fetch what `uri` names: a `decdn:` URI, or on a site page a path of its
143
+ * own bundle. Verification follows `verify` (see {@link DecdnResponse.verified}).
144
+ */
145
+ get(uri: string | DecdnUri, opts?: GetOptions): Promise<DecdnResponse>;
146
+ /** A `GET` of `url`, once more after one `Retry-After` when `opts.retry` asks. */
147
+ private fetchRetrying;
148
+ /**
149
+ * What is known about `uri` without its bytes: on a public gateway from
150
+ * `HEAD`, elsewhere (where `HEAD` would cost a pull) from the manifest. A
151
+ * public `HEAD` of a raw blob whose size the gateway does not know yet
152
+ * pays for one chunk group, the proof of its size, and is refused or fails
153
+ * as its `GET` would be.
154
+ */
155
+ head(uri: string | DecdnUri): Promise<HeadInfo>;
156
+ }
@@ -0,0 +1,69 @@
1
+ /** What went wrong, as a stable code a caller can branch on. */
2
+ export type DecdnErrorCode =
3
+ /** 402: the gateway's allowance is spent, or the content does not fit what is left, or no capability covers the host. */
4
+ "PAYMENT_REQUIRED"
5
+ /** 503: the gateway's pool cannot pay. */
6
+ | "POOL_UNFUNDED"
7
+ /** 404. */
8
+ | "NOT_FOUND"
9
+ /** 416: the range starts past the end; `size` holds the entry's size. */
10
+ | "RANGE_NOT_SATISFIABLE"
11
+ /** 401: the loopback token is missing or wrong. */
12
+ | "UNAUTHORIZED"
13
+ /** 403. */
14
+ | "FORBIDDEN"
15
+ /** 400, or a `decdn:` URI that does not parse. */
16
+ | "BAD_URI"
17
+ /** 429. */
18
+ | "RATE_LIMITED"
19
+ /** 502: the gateway's pull failed upstream. */
20
+ | "UPSTREAM"
21
+ /** 413. */
22
+ | "PAYLOAD_TOO_LARGE"
23
+ /** 409: a pointer `seq` that is not newer, or a capability already registered. */
24
+ | "CONFLICT"
25
+ /** 422. */
26
+ | "UNPROCESSABLE"
27
+ /** The bytes do not hash to the hash that names them. */
28
+ | "HASH_MISMATCH"
29
+ /** The body is shorter or longer than declared, or the stream failed. */
30
+ | "TRUNCATED"
31
+ /** A bundle manifest that does not parse. */
32
+ | "MALFORMED_MANIFEST"
33
+ /** A `dcap1:` capability token that does not decode. */
34
+ | "BAD_CAPABILITY"
35
+ /** The gateway could not be reached. */
36
+ | "NETWORK"
37
+ /** The client is not set up for the call, or the call cannot be honoured as asked. */
38
+ | "CONFIG"
39
+ /** A status the gateway contract does not name. */
40
+ | "HTTP";
41
+ /** Fields a {@link DecdnError} may carry besides its code and message. */
42
+ export interface DecdnErrorDetails {
43
+ /** The HTTP status, when the gateway answered. */
44
+ status?: number;
45
+ /** Seconds to wait before a retry, from `Retry-After` or the JSON body. */
46
+ retryAfterSecs?: number;
47
+ /** The canonical `decdn:` URI to fetch with a paying client instead. */
48
+ fallbackUri?: string;
49
+ /** The entry's size, on `RANGE_NOT_SATISFIABLE`. */
50
+ size?: number;
51
+ /** The highest stored `seq`, on a pointer `CONFLICT`. */
52
+ seq?: bigint;
53
+ /** The response body, as text. */
54
+ body?: string;
55
+ /** What caused this error. */
56
+ cause?: unknown;
57
+ }
58
+ /** Every failure the SDK reports. */
59
+ export declare class DecdnError extends Error {
60
+ readonly name = "DecdnError";
61
+ readonly code: DecdnErrorCode;
62
+ readonly status?: number;
63
+ readonly retryAfterSecs?: number;
64
+ readonly fallbackUri?: string;
65
+ readonly size?: number;
66
+ readonly seq?: bigint;
67
+ readonly body?: string;
68
+ constructor(code: DecdnErrorCode, message: string, details?: DecdnErrorDetails);
69
+ }
@@ -0,0 +1,10 @@
1
+ /** The BLAKE3 hash of `bytes`, as 64 lowercase hex characters. */
2
+ export declare function blake3Hex(bytes: Uint8Array): string;
3
+ /** An incremental BLAKE3 hasher, for bytes that arrive in chunks. */
4
+ export interface Blake3Hasher {
5
+ update(chunk: Uint8Array): void;
6
+ /** The hash of every chunk so far, as 64 lowercase hex characters. */
7
+ hex(): string;
8
+ }
9
+ /** A new incremental BLAKE3 hasher. */
10
+ export declare function createBlake3(): Blake3Hasher;
@@ -0,0 +1,6 @@
1
+ /** Lowercase hex of `bytes`. */
2
+ export declare function toHex(bytes: Uint8Array): string;
3
+ /** The bytes of an even-length hex string, or `undefined` if it is not hex. */
4
+ export declare function fromHex(hex: string): Uint8Array | undefined;
5
+ /** Whether `s` is a BLAKE3 hash spelled as 64 hex characters. */
6
+ export declare function isHash(s: string): boolean;
@@ -0,0 +1,12 @@
1
+ import { DecdnError } from "./errors.js";
2
+ export type Fetch = typeof globalThis.fetch;
3
+ /** `fetch`, with a failure to reach the gateway as `NETWORK` and an abort passed through. */
4
+ export declare function send(fetch: Fetch, url: string, init: RequestInit): Promise<Response>;
5
+ /** The error for a gateway answer that is not a success. Reads the body. */
6
+ export declare function errorOf(response: Response): Promise<DecdnError>;
7
+ /**
8
+ * `text` parsed as JSON with the integer values of `fields` read as `bigint`:
9
+ * the gateway writes u64 ids, caps and expiries as JSON numbers, which may
10
+ * exceed 2^53.
11
+ */
12
+ export declare function parseWithBigInts(text: string, fields: string[]): unknown;
@@ -0,0 +1,9 @@
1
+ export { DecdnError, type DecdnErrorCode, type DecdnErrorDetails, } from "./errors.js";
2
+ export { formatUri, parseUri, SCHEME, type DecdnUri } from "./uri.js";
3
+ export { base32ToHash, hashToBase32 } from "./base32.js";
4
+ export { blake3Hex, createBlake3, type Blake3Hasher } from "./hash.js";
5
+ export { MAX_MANIFEST_BYTES, parseManifest, type BundleManifest, type ManifestChunk, type ManifestEntry, } from "./manifest.js";
6
+ export { parseCapability, type Capability } from "./capability.js";
7
+ export { DecdnClient, DecdnResponse, type ByteRange, type Context, type GetOptions, type HeadInfo, type OpenOptions, type Resolved, type VerifyMode, } from "./client.js";
8
+ export { PointerApi, pointerSigningHash, pointerTypedData, recoverPointerSigner, signPointer, type Pointer, type PointerDomain, type PointerSet, type PointerSigner, type PointerTypedData, type TypedDataSigner, } from "./pointer.js";
9
+ export { LoopbackApi, type RegisteredCapability } from "./loopback.js";
@@ -0,0 +1,36 @@
1
+ import type { DecdnClient } from "./client.js";
2
+ /** A capability the gateway holds. */
3
+ export interface RegisteredCapability {
4
+ signer: string;
5
+ pool: string;
6
+ scope: string;
7
+ /** The page origin that registered it, or `null` for the token holder. */
8
+ origin: string | null;
9
+ /** The spending cap, in USDC base units. */
10
+ cap: bigint;
11
+ /** Unix-seconds expiry. */
12
+ expiry: bigint;
13
+ /** Whether a pull found it spent. */
14
+ spent: boolean;
15
+ }
16
+ export declare class LoopbackApi {
17
+ private readonly client;
18
+ /** @internal */
19
+ constructor(client: DecdnClient);
20
+ private call;
21
+ /** A fresh delegate key the gateway holds for 15 minutes unless a capability claims it. */
22
+ delegate(): Promise<{
23
+ address: string;
24
+ }>;
25
+ /** Register `capability` (a `dcap1:` issued to a delegate) for `scope`: `example.com`, `*.example.com` or `*`. */
26
+ registerCapability(args: {
27
+ capability: string;
28
+ scope: string;
29
+ }): Promise<{
30
+ signer: string;
31
+ scope: string;
32
+ expiry: bigint;
33
+ }>;
34
+ /** The capabilities the gateway holds. Needs the token. */
35
+ capabilities(): Promise<RegisteredCapability[]>;
36
+ }
@@ -0,0 +1,30 @@
1
+ /** The largest manifest the gateway pulls, and the SDK reads (64 MiB). */
2
+ export declare const MAX_MANIFEST_BYTES: number;
3
+ /** One chunk of an entry: an independently addressed run of its bytes. */
4
+ export interface ManifestChunk {
5
+ hash: string;
6
+ size: number;
7
+ }
8
+ /** One file of a bundle. */
9
+ export interface ManifestEntry {
10
+ /** The entry's relative POSIX path: what a `decdn:<hash>/<path>` URI names. */
11
+ path: string;
12
+ /** The BLAKE3 hash of the whole file, 64 lowercase hex characters. */
13
+ hash: string;
14
+ /** The file's size in bytes, when the manifest declares it. */
15
+ size?: number;
16
+ /** The file's chunk decomposition, a dedup hint. */
17
+ chunks?: ManifestChunk[];
18
+ }
19
+ /** A parsed bundle manifest. */
20
+ export interface BundleManifest {
21
+ /** The manifest blob's BLAKE3 hash: what `decdn:<hash>/` names. */
22
+ hash: string;
23
+ entries: ManifestEntry[];
24
+ }
25
+ /**
26
+ * Parse manifest bytes. With `expectedHash`, the bytes must hash to it first
27
+ * (`HASH_MISMATCH` otherwise). Anything that is not a v1 manifest is
28
+ * `MALFORMED_MANIFEST`.
29
+ */
30
+ export declare function parseManifest(bytes: Uint8Array, expectedHash?: string): BundleManifest;
@@ -0,0 +1,4 @@
1
+ /** Whether a site rewrites the entry at `path`, so its bytes need not hash to the entry hash. */
2
+ export declare function rewritten(path: string): boolean;
3
+ /** The type a site serves the entry at `path` as: text in UTF-8, bytes for an unknown extension. */
4
+ export declare function siteType(path: string): string;
@@ -0,0 +1,7 @@
1
+ /** The loopback gateway's default data dir, `~/.decdn/gateway`. */
2
+ export declare function defaultDataDir(): string;
3
+ /**
4
+ * The token a loopback `decdn gateway` keeps in `<dataDir>/token` (mode 0600),
5
+ * for `DecdnClient.open({ token })`. `dataDir` is the gateway's `--data-dir`.
6
+ */
7
+ export declare function readLoopbackToken(dataDir?: string): Promise<string>;
@@ -0,0 +1,82 @@
1
+ import type { DecdnClient } from "./client.js";
2
+ /** The chain a pointer is signed for: the EIP-712 domain of `PUT /_pointer`. */
3
+ export interface PointerDomain {
4
+ chainId: bigint | number;
5
+ /** The `PublisherRegistry` contract address. */
6
+ publisherRegistry: string;
7
+ }
8
+ /** A pointer from a namespace to the bundle whose manifest hash is `root`. */
9
+ export interface Pointer {
10
+ namespace: bigint;
11
+ /** The bundle's manifest hash, 64 hex characters. */
12
+ root: string;
13
+ seq: bigint;
14
+ }
15
+ /** The EIP-712 typed data of a pointer, in the shape viem's `signTypedData` takes. */
16
+ export interface PointerTypedData {
17
+ domain: {
18
+ name: "decdn-pointer";
19
+ version: "1";
20
+ chainId: bigint;
21
+ verifyingContract: string;
22
+ };
23
+ types: {
24
+ Pointer: {
25
+ name: string;
26
+ type: string;
27
+ }[];
28
+ };
29
+ primaryType: "Pointer";
30
+ message: {
31
+ namespaceId: bigint;
32
+ root: string;
33
+ seq: bigint;
34
+ };
35
+ }
36
+ /** Anything that signs EIP-712 typed data: a viem account, or a wallet behind the same call shape. */
37
+ export interface TypedDataSigner {
38
+ signTypedData(typedData: PointerTypedData): Promise<string>;
39
+ }
40
+ /** A signer: a typed-data signer, or a raw secp256k1 key (`0x` hex or bytes). */
41
+ export type PointerSigner = TypedDataSigner | {
42
+ privateKey: string | Uint8Array;
43
+ };
44
+ /** @internal `value` as a bigint; `CONFIG` for a number that is not a safe integer. */
45
+ export declare function integer(value: bigint | number, what: string): bigint;
46
+ /** The typed data a wallet signs for `pointer`. */
47
+ export declare function pointerTypedData(domain: PointerDomain, pointer: Pointer): PointerTypedData;
48
+ /** The EIP-712 signing hash of `pointer`, `0x` + 64 hex. */
49
+ export declare function pointerSigningHash(domain: PointerDomain, pointer: Pointer): string;
50
+ /** Sign `pointer` for `domain` with `signer`. */
51
+ export declare function signPointer(domain: PointerDomain, pointer: Pointer, signer: PointerSigner): Promise<string>;
52
+ /** The lowercase address that signed `pointer` with `signature`; `UNPROCESSABLE` for a malformed or high-`s` one. */
53
+ export declare function recoverPointerSigner(domain: PointerDomain, pointer: Pointer, signature: string): string;
54
+ /** What `pointer.set` stored. */
55
+ export interface PointerSet {
56
+ namespace: bigint;
57
+ /** The bundle's manifest hash. */
58
+ root: string;
59
+ seq: bigint;
60
+ /** The namespace's host on the gateway. */
61
+ url: string;
62
+ }
63
+ /** Namespace pointers on a public gateway. */
64
+ export declare class PointerApi {
65
+ private readonly client;
66
+ /** @internal */
67
+ constructor(client: DecdnClient);
68
+ /**
69
+ * Sign a pointer from `namespace` to the bundle `root` (`decdn:<hash>/` or
70
+ * its manifest hash) and `PUT` it. `seq` defaults to the current Unix
71
+ * second; the gateway takes only a `seq` above the one it holds from the
72
+ * same signer. The signer must own the namespace on the `PublisherRegistry`
73
+ * of `open({ pointer })`.
74
+ */
75
+ set(args: {
76
+ namespace: bigint | number;
77
+ root: string;
78
+ seq?: bigint | number;
79
+ signer: PointerSigner;
80
+ signal?: AbortSignal;
81
+ }): Promise<PointerSet>;
82
+ }
@@ -0,0 +1,20 @@
1
+ /** The scheme prefix of every `decdn:` URI. */
2
+ export declare const SCHEME = "decdn:";
3
+ /** A parsed `decdn:` URI. */
4
+ export interface DecdnUri {
5
+ /** The BLAKE3 hash, 64 lowercase hex characters: of the blob, or of the bundle manifest. */
6
+ hash: string;
7
+ /** What the hash names: a raw blob, a whole bundle, or one entry of a bundle. */
8
+ kind: "blob" | "bundle" | "entry";
9
+ /** The decoded manifest path of an entry. */
10
+ path?: string;
11
+ /** The namespace routing hint, never `0n`. */
12
+ namespace?: bigint;
13
+ }
14
+ /**
15
+ * Parse a `decdn:` URI. Throws a {@link DecdnError} with code `BAD_URI` for
16
+ * anything the Rust client would refuse.
17
+ */
18
+ export declare function parseUri(s: string): DecdnUri;
19
+ /** The canonical string of `uri`: lowercase hex, uppercase `%XX` escapes. */
20
+ export declare function formatUri(uri: DecdnUri): string;
@@ -0,0 +1,14 @@
1
+ export interface GuardOptions {
2
+ /** The hash the whole body must have, or `undefined` to skip the check. */
3
+ hash?: string;
4
+ /** The fewest bytes the body holds: the manifest's size, or Content-Length. */
5
+ length?: number;
6
+ /** The most bytes the body may hold: the manifest's size, or the window asked for. */
7
+ max?: number;
8
+ /** The request's signal: a read it aborts fails with its reason. */
9
+ signal?: AbortSignal;
10
+ }
11
+ /** `body`, guarded: a failed read is `TRUNCATED`, a short or long body `TRUNCATED`, a wrong hash `HASH_MISMATCH`. */
12
+ export declare function guard(body: ReadableStream<Uint8Array> | null, opts: GuardOptions): ReadableStream<Uint8Array>;
13
+ /** Every byte of `stream`, joined. */
14
+ export declare function collect(stream: ReadableStream<Uint8Array>, limit?: number): Promise<Uint8Array>;
package/package.json CHANGED
@@ -1,6 +1,100 @@
1
1
  {
2
2
  "name": "@decdn/client",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.0",
4
+ "description": "TypeScript client for deCDN over a decdn gateway: verified fetches, bundles, loopback capabilities and namespace pointers.",
5
+ "license": "MIT OR Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/decdn/sdk-typescript.git"
9
+ },
10
+ "homepage": "https://github.com/decdn/sdk-typescript#readme",
11
+ "bugs": "https://github.com/decdn/sdk-typescript/issues",
12
+ "keywords": [
13
+ "decdn",
14
+ "cdn",
15
+ "blake3",
16
+ "content-addressed",
17
+ "gateway"
18
+ ],
19
+ "type": "module",
20
+ "sideEffects": false,
21
+ "engines": {
22
+ "node": ">=20.19"
23
+ },
24
+ "decdn": {
25
+ "gatewayFloor": "0.3.0"
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "README.md"
30
+ ],
31
+ "main": "./dist/index.cjs",
32
+ "module": "./dist/index.js",
33
+ "types": "./dist/index.d.ts",
34
+ "exports": {
35
+ ".": {
36
+ "import": {
37
+ "types": "./dist/index.d.ts",
38
+ "default": "./dist/index.js"
39
+ },
40
+ "require": {
41
+ "types": "./dist/index.d.cts",
42
+ "default": "./dist/index.cjs"
43
+ }
44
+ },
45
+ "./node": {
46
+ "node": {
47
+ "import": {
48
+ "types": "./dist/node.d.ts",
49
+ "default": "./dist/node.js"
50
+ },
51
+ "require": {
52
+ "types": "./dist/node.d.cts",
53
+ "default": "./dist/node.cjs"
54
+ }
55
+ },
56
+ "types": "./dist/node.d.ts"
57
+ },
58
+ "./package.json": "./package.json"
59
+ },
60
+ "lint-staged": {
61
+ "*.{ts,mts,cts,js,mjs,cjs}": [
62
+ "eslint --fix",
63
+ "prettier --write"
64
+ ],
65
+ "*.{json,md,yaml,yml}": [
66
+ "prettier --write"
67
+ ]
68
+ },
69
+ "dependencies": {
70
+ "@noble/curves": "^2.4.0",
71
+ "@noble/hashes": "^2.4.0"
72
+ },
73
+ "devDependencies": {
74
+ "@arethetypeswrong/cli": "^0.18.5",
75
+ "@commitlint/cli": "^20.5.3",
76
+ "@commitlint/config-conventional": "^20.5.3",
77
+ "@eslint/js": "^9.39.0",
78
+ "@types/node": "^24",
79
+ "@vitest/browser-playwright": "^5.0.5",
80
+ "esbuild": "^0.28.2",
81
+ "eslint": "^9.39.0",
82
+ "eslint-config-prettier": "^10.1.8",
83
+ "husky": "^9.1.7",
84
+ "lint-staged": "^16.4.0",
85
+ "playwright": "^1.64.1",
86
+ "prettier": "^3.9.4",
87
+ "publint": "^0.3.25",
88
+ "typescript": "^6",
89
+ "typescript-eslint": "^8.72.0",
90
+ "vitest": "^5.0.5"
91
+ },
92
+ "scripts": {
93
+ "build": "node scripts/build.mjs",
94
+ "lint": "eslint . && prettier --check . && tsc --noEmit",
95
+ "format": "prettier --write .",
96
+ "test": "vitest run --project unit --project contract",
97
+ "test:contract": "vitest run --project contract",
98
+ "test:browser": "vitest run --project browser"
99
+ }
6
100
  }