@meddleware/nft-gate-gateway 0.0.1 → 0.0.3

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 CHANGED
@@ -1,6 +1,6 @@
1
- # @meddleware/nft-gate-gateway-workers
1
+ # @meddleware/nft-gate-gateway
2
2
 
3
- [![npm](https://img.shields.io/npm/v/%40meddleware%2Fnft-gate-gateway-workers)](https://www.npmjs.com/package/@meddleware/nft-gate-gateway-workers)
3
+ [![npm](https://img.shields.io/npm/v/%40meddleware%2Fnft-gate-gateway-workers)](https://www.npmjs.com/package/@meddleware/nft-gate-gateway)
4
4
  [![License: 0BSD](https://img.shields.io/badge/license-0BSD-blue)](LICENSE)
5
5
 
6
6
  Cloudflare Workers implementation of the [nft-gate](../README.md) NFT-gated reverse proxy.
@@ -32,7 +32,7 @@ npm install
32
32
  Alternatively, the package is published to npm for reference:
33
33
 
34
34
  ```bash
35
- npm install @meddleware/nft-gate-gateway-workers
35
+ npm install @meddleware/nft-gate-gateway
36
36
  ```
37
37
 
38
38
  ### 2. Configure `wrangler.toml`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meddleware/nft-gate-gateway",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "type": "module",
5
5
  "description": "Cloudflare Workers implementation of the nft-gate gateway: a wire-identical, drop-in sibling of the Rust gateway that gates any HTTP upstream behind an access_gate NFT.",
6
6
  "license": "0BSD",
@@ -21,7 +21,7 @@
21
21
  "generate:vectors": "node scripts/gen-vectors.mjs > ../conformance/vectors.json"
22
22
  },
23
23
  "dependencies": {
24
- "@meddleware/nft-gate-client": "^0.0.1",
24
+ "@meddleware/nft-gate-client": "^0.0.2",
25
25
  "@noble/curves": "~2.4.0",
26
26
  "@noble/hashes": "~2.4.0"
27
27
  },
package/src/chain.ts CHANGED
@@ -20,6 +20,7 @@ interface CacheEntry {
20
20
  expiry: number
21
21
  }
22
22
 
23
+ /** Production {@link ChainQuery} backed by Sui JSON-RPC, with an optional ownership cache. */
23
24
  export class SuiRpc implements ChainQuery {
24
25
  private readonly cache = new Map<string, CacheEntry>()
25
26
 
package/src/config.ts CHANGED
@@ -51,9 +51,12 @@ export interface Env {
51
51
  CF_ACCOUNT_ID?: string
52
52
  }
53
53
 
54
+ /** Which nonce/rate-limit backend to use: strongly-consistent Durable Objects or Workers KV. */
54
55
  export type NonceBackendKind = 'durable-object' | 'kv'
56
+ /** Nonce shard placement: one shard per region (near users) or a single global shard. */
55
57
  export type NonceShardMode = 'region' | 'global'
56
58
 
59
+ /** Fully-resolved gateway configuration derived from {@link Env} by {@link loadConfig}. */
57
60
  export interface Config {
58
61
  upstreamUrl: string
59
62
  suiRpcUrl: string
@@ -139,6 +142,7 @@ export function loadConfig(env: Env): Config {
139
142
  }
140
143
  }
141
144
 
145
+ /** Returns `true` if `path` is in the configured public-paths list (proxied without auth). */
142
146
  export function isPublicPath(cfg: Config, path: string): boolean {
143
147
  return cfg.publicPaths.some((p) => p === path)
144
148
  }
package/src/crypto.ts CHANGED
@@ -7,16 +7,19 @@
7
7
  import { blake2b } from '@noble/hashes/blake2.js'
8
8
  import { sha256 as nobleSha256 } from '@noble/hashes/sha2.js'
9
9
 
10
+ /** Compute a 32-byte Blake2b-256 digest of `data`. */
10
11
  export function blake2b256(data: Uint8Array): Uint8Array {
11
12
  return blake2b(data, { dkLen: 32 })
12
13
  }
13
14
 
15
+ /** Compute a 32-byte SHA-256 digest of `data`. */
14
16
  export function sha256(data: Uint8Array): Uint8Array {
15
17
  return nobleSha256(data)
16
18
  }
17
19
 
18
20
  const HEX = '0123456789abcdef'
19
21
 
22
+ /** Encode `bytes` as a lowercase hex string (no `0x` prefix). */
20
23
  export function bytesToHex(bytes: Uint8Array): string {
21
24
  let out = ''
22
25
  for (let i = 0; i < bytes.length; i++) {
@@ -25,6 +28,11 @@ export function bytesToHex(bytes: Uint8Array): string {
25
28
  return out
26
29
  }
27
30
 
31
+ /**
32
+ * Decode a hex string (with or without `0x` prefix) to bytes.
33
+ *
34
+ * @throws {Error} if `hex` has an odd number of characters.
35
+ */
28
36
  export function hexToBytes(hex: string): Uint8Array {
29
37
  const s = hex.startsWith('0x') ? hex.slice(2) : hex
30
38
  if (s.length % 2 !== 0) throw new Error('odd-length hex')
@@ -43,6 +51,7 @@ export function base64ToBytes(b64: string): Uint8Array {
43
51
  return out
44
52
  }
45
53
 
54
+ /** Encode `bytes` as standard base64. Uses `btoa` (present in the Workers runtime). */
46
55
  export function bytesToBase64(bytes: Uint8Array): string {
47
56
  let s = ''
48
57
  for (let i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i])
@@ -65,6 +74,7 @@ export function uleb128(v: number): Uint8Array {
65
74
  return Uint8Array.from(out)
66
75
  }
67
76
 
77
+ /** Concatenate multiple `Uint8Array` values into a single contiguous array. */
68
78
  export function concatBytes(...parts: Uint8Array[]): Uint8Array {
69
79
  let len = 0
70
80
  for (const p of parts) len += p.length
package/src/verify.ts CHANGED
@@ -30,6 +30,7 @@ export function deriveAddress(flag: number, pk: Uint8Array): string {
30
30
  return '0x' + bytesToHex(blake2b256(concatBytes(Uint8Array.from([flag]), pk)))
31
31
  }
32
32
 
33
+ /** Normalise a Sui address to lowercase, `0x`-prefixed, zero-padded to 64 hex digits. */
33
34
  export function normalizeAddress(a: string): string {
34
35
  const s = a.trim().replace(/^0x/i, '').toLowerCase()
35
36
  return '0x' + s.padStart(64, '0')
@@ -128,6 +129,7 @@ export interface ChainQuery {
128
129
  ): Promise<boolean>
129
130
  }
130
131
 
132
+ /** The reason a request was rejected by {@link verifyAccessRequest}. Mirror of Rust `Denied`. */
131
133
  export type Denied =
132
134
  | 'BadProof'
133
135
  | 'BadSignature'
@@ -136,6 +138,7 @@ export type Denied =
136
138
  | 'ConsumeMissing'
137
139
  | 'ChainError'
138
140
 
141
+ /** A short, client-visible description of why access was denied. */
139
142
  export function deniedReason(d: Denied): string {
140
143
  switch (d) {
141
144
  case 'BadProof':
@@ -153,6 +156,7 @@ export function deniedReason(d: Denied): string {
153
156
  }
154
157
  }
155
158
 
159
+ /** Result of {@link verifyAccessRequest}: the verified address on success, or a {@link Denied} reason. */
156
160
  export type VerifyResult = { ok: true; address: string } | { ok: false; denied: Denied }
157
161
 
158
162
  /**
package/wrangler.toml CHANGED
@@ -45,8 +45,8 @@ compatibility_flags = ["nodejs_compat"]
45
45
  # Public fullnode — safe to keep as a plain var (no sensitive information).
46
46
  SUI_RPC_URL = "https://fullnode.testnet.sui.io:443"
47
47
 
48
- GATE_ID = "" # operator: set to the access_gate registry object ID (single-registry mode)
49
- SINGLE_USE = "false"
48
+ GATE_ID = "0x0485c1fa80e4c355c85ab99c0281a328d8fb5c60ac50ab64f10be0f8be792aba"
49
+ SINGLE_USE = "true"
50
50
  PUBLIC_PATHS = "/v1/tip-config"
51
51
  RATE_LIMIT_PER_MIN = "30"
52
52
  MAX_BODY_BYTES = "262144"