A Clockify add-on that turns a saved Clockify invoice into a Request Finance USDC crypto invoice and writes the payment link back into the Clockify invoice note.
Legal: This repository is public for transparency and review. It is not open-source software. All rights reserved — see NOTICE.
Teams that use Clockify for invoicing and Request Finance for crypto payments, and want a self-hosted bridge between the two without manual copy-paste.
- Someone opens an invoice in Clockify and clicks the add-on action.
- The bridge reads the invoice from Clockify, exports the PDF, and creates a matching RF invoice.
- RF issues the invoice and returns a payment link.
- The bridge appends that link to the Clockify invoice note.
Each Clockify workspace gets its own isolated storage (a Cloudflare Durable Object), so tokens and invoice mappings never leak across workspaces.
flowchart LR
Clockify[Clockify iframe] --> Bridge[bridge Worker]
Bridge --> DO[WorkspaceStore DO]
Bridge --> RF[Request Finance API]
Bridge --> KV[KV cache]
Bridge --> Secrets[Secrets Store KEK]
DO --> DB[(per-workspace SQLite)]
git clone https://github.com/Quantumlyyy/clockify-rf-bridge.git
cd clockify-rf-bridge
pnpm install
cp .dev.vars.example apps/bridge/.dev.vars
# Edit apps/bridge/.dev.vars — set ADDON_KEY and RF_KEK (see file comments)
pnpm gen
pnpm devLocal manifest URL: http://localhost:5173/manifest
Point your Clockify add-on manifest at that URL while developing.
| Variable | Where | Purpose |
|---|---|---|
ADDON_KEY |
.dev.vars / wrangler vars |
Clockify add-on identifier (JWT sub check) |
RF_KEK |
.dev.vars (local) or Secrets Store (prod) |
32-byte hex key for encrypting stored API tokens |
RF_CLIENT_MAPPING_UI |
wrangler vars |
Set true to show RF client picker in settings |
Clockify install tokens and RF API keys are entered through the add-on UI and stored encrypted in the workspace Durable Object — not in environment variables.
apps/bridge/wrangler.jsonc is wired to Quantumly's Cloudflare account (KV, Secrets Store, ADDON_KEY). For your own deployment, start from apps/bridge/wrangler.jsonc.example instead:
- Create a KV namespace:
wrangler kv namespace create cache - Create a Secrets Store and add
RF_KEK(64-char hex fromopenssl rand -hex 32) - Paste those ids and your Clockify
ADDON_KEYinto wrangler config - Build and deploy:
pnpm build
wrangler deploy --config apps/bridge/wrangler.jsoncThe worker entry is apps/bridge/src/worker.ts. It re-exports the SvelteKit handler and the WorkspaceStore Durable Object class.
All per-workspace data lives in a WorkspaceStore Durable Object (keyed by Clockify workspace id):
| Table | What it stores |
|---|---|
encrypted_secrets |
Clockify install token and RF API token (encrypted) |
invoice_mappings |
Completed Clockify invoice → RF payment link (idempotency) |
invoice_runs |
In-flight orchestration state for resume after partial failure |
client_mappings |
Optional Clockify client → RF client mapping |
Schema: packages/db/src/schema.ts. Migrations run automatically inside each DO on first access.
If you still have data in the old D1 persistence database:
- Export
encrypted_secretsandinvoice_mappingsgrouped byworkspace_id. - For each workspace, seed the
WorkspaceStoreDO via its/tokenand/mappingRPC routes. - Remove the D1 binding once verified.
Fresh local installs can skip this entirely.
| Command | What it does |
|---|---|
pnpm dev |
Start the bridge dev server |
pnpm build |
Build all packages and the bridge app |
pnpm test |
Run tests in all workspaces |
pnpm lint |
Check formatting (oxfmt), oxlint, and ESLint |
pnpm check |
SvelteKit type-check |
pnpm format |
Auto-format with oxfmt |
pnpm gen |
Regenerate Wrangler types |
pnpm db:generate |
Generate a new DO SQLite migration |
See CONTRIBUTING.md for more detail on running and reviewing the code.
apps/bridge/ SvelteKit + Cloudflare Workers app
packages/request-finance/ RF HTTP client + Effect Schema types
packages/db/ Drizzle schema + DO SQLite migrations
packages/workspace-store/ Per-workspace Durable Object + RPC client
packages/invoice-core/ Invoice orchestration state machine
Package boundaries:
@clockify-rf-bridge/request-finance— rnf_invoice schemas and typed HTTP only.@clockify-rf-bridge/invoice-core— orchestration logic; Clockify client injected from bridge.@clockify-rf-bridge/workspace-store— DO actor and fetch-based RPC used by bridge routes.
Internal research notes live in docs/spikes/. They document decisions made during development, not end-user setup.
Report vulnerabilities privately — see SECURITY.md.