A minimal Cloudflare Worker that demonstrates how to integrate the GuildPass SDK in an edge runtime.
| Feature | Where |
|---|---|
Module-scope GuildPassClient (reused across requests) |
src/index.ts — getClient() |
KV-backed CacheAdapter wiring |
src/index.ts — KVCacheAdapter class |
Access-check endpoint (GET /check-access) |
src/index.ts — handleCheckAccess() |
| Wrangler config with KV binding and env var declarations | wrangler.toml |
The example is intentionally minimal — no extra dependencies beyond @guildpass/sdk and Wrangler.
- Node.js 18+
- Wrangler CLI v3+
# Install Wrangler globally (or use npx)
npm install -g wrangler
# Authenticate with your Cloudflare account
wrangler loginFrom the repository root:
pnpm installOr from this example directory directly (requires the SDK to be built first):
# Build the SDK
pnpm --filter @guildpass/sdk build
# Install example deps
cd examples/cloudflare-worker
npm installWorkers KV is used as the cache backend. Create a namespace once:
npx wrangler kv:namespace create GUILDPASS_KVCopy the id printed to the terminal and paste it into wrangler.toml:
[[kv_namespaces]]
binding = "GUILDPASS_KV"
id = "paste-your-id-here"For local development, also create a preview namespace:
npx wrangler kv:namespace create GUILDPASS_KV --previewUncomment and fill in preview_id in wrangler.toml.
Non-secret variables (GUILDPASS_API_URL, GUILDPASS_CHAIN_ID, GUILDPASS_CACHE_TTL) are already set in wrangler.toml. Adjust them for your deployment target.
The API key is a secret and must never be committed to source control.
For local development, create a .dev.vars file in this directory (it is gitignored):
GUILDPASS_API_KEY=your-dev-api-key
For deployed Workers, use the Wrangler CLI:
npx wrangler secret put GUILDPASS_API_KEY
# Enter the value when promptedOr set it in the Workers dashboard under Settings → Variables → Secret variables.
| Variable | Type | Required | Description |
|---|---|---|---|
GUILDPASS_API_URL |
string |
✅ | GuildPass API base URL (e.g. https://api.guildpass.xyz) |
GUILDPASS_API_KEY |
string (secret) |
✅ | Your GuildPass API key |
GUILDPASS_CHAIN_ID |
string |
✅ | Numeric chain ID (e.g. 8453 for Base Mainnet, 1 for Ethereum) |
GUILDPASS_CACHE_TTL |
string |
✅ | Response cache TTL in milliseconds (e.g. 30000 = 30 s) |
GUILDPASS_KV |
KVNamespace |
✅ | Workers KV binding — configured via wrangler.toml, not a plain env var |
npx wrangler devWrangler starts a local dev server (default http://localhost:8787). Test the endpoint:
# Access check
curl "http://localhost:8787/check-access?wallet=0x1234567890123456789012345678901234567890&guild=prime-guild&resource=premium-docs"
# Health probe
curl "http://localhost:8787/health"Access granted:
{
"hasAccess": true,
"reason": null,
"matchedRoles": ["member"],
"requiredRoles": ["member"]
}Access denied:
{
"hasAccess": false,
"reason": "No matching role",
"matchedRoles": [],
"requiredRoles": ["member"]
}Missing parameters (400):
{ "error": "Missing required query parameters: guild, resource" }# Deploy to the default environment
npx wrangler deploy
# Deploy to the production environment
npx wrangler deploy --env productionlet _client: GuildPassClient | null = null;
function getClient(env: Env): GuildPassClient {
if (_client) return _client;
_client = new GuildPassClient({ ... });
return _client;
}Cloudflare Workers reuse the same V8 isolate — and therefore the same module scope — across multiple requests until the isolate is evicted. Initialising the client once at module scope avoids redundant config validation and connection overhead on every request. This is a standard Workers best practice for any long-lived resource.
class KVCacheAdapter implements CacheAdapter {
constructor(private readonly kv: KVNamespace) {}
async get<T>(key: string): Promise<T | null> { /* ... */ }
async set<T>(key: string, value: T, ttl?: number): Promise<void> { /* ... */ }
async delete(key: string): Promise<void> { /* ... */ }
async clear(): Promise<void> { /* no-op — KV doesn't support flush from Workers */ }
}The adapter implements the CacheAdapter interface. All methods swallow errors silently so a KV failure never prevents a live access check — the SDK falls through to the network automatically.
KV TTL note: Workers KV enforces a minimum expirationTtl of 60 seconds. If your GUILDPASS_CACHE_TTL is shorter (e.g. for local dev), the adapter clamps to 60 s. For sub-minute freshness, consider pairing the KV adapter with an in-process InMemoryCacheAdapter in front of it.
Use the built-in client helpers when you need to evict stale entries:
// Evict all entries for a specific guild (e.g. after an admin config change)
await client.invalidateGuildCache('prime-guild');
// Evict all entries for a wallet
await client.invalidateWalletCache('0x1234...5678');
// Full cache wipe (no-op on KV adapter — use Wrangler CLI instead)
await client.clearCache();Because Workers KV does not expose a prefix-delete API from within Workers code,
invalidateGuildCache and invalidateWalletCache fall back to deleting known
exact keys. For production use, consider adding a management endpoint that calls
the KV REST API to bulk-delete by prefix.