@orangecheck/me-client 0.6.0 → 0.8.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 CHANGED
@@ -1,9 +1,23 @@
1
1
  # @orangecheck/me-client
2
2
 
3
- Drop-in client for [me.ochk.io](https://me.ochk.io). Sign-in-with-OC button, session lifecycle hooks, payment authorization, developer telemetry, and the canonical billable-event taxonomy as TypeScript types.
3
+ Drop-in client for [me.ochk.io](https://me.ochk.io). Sign-in-with-OC button, popup signin orchestrator, framework-agnostic server-side verification, session lifecycle hooks, payment authorization, webhook signature verification, the canonical billable-event taxonomy as TypeScript types.
4
4
 
5
5
  > You pay for sessions and actions, not for clicks.
6
6
 
7
+ ## Three entry points, three audiences
8
+
9
+ ```ts
10
+ // React surface (provider, hook, button, oc.session/payment/event/config/webhook)
11
+ import { useOcSession, oc } from '@orangecheck/me-client';
12
+
13
+ // Server-side verification — Next.js, Express, Hono. Zero env vars,
14
+ // zero JWK handling. SDK lazy-fetches and caches the JWKS.
15
+ import { withOcAuth, ocAuthExpress, ocAuthHono } from '@orangecheck/me-client/server';
16
+
17
+ // Browser-only popup orchestrator — same shape Google / GitHub use.
18
+ import { signInWithOc } from '@orangecheck/me-client/popup';
19
+ ```
20
+
7
21
  ## Install
8
22
 
9
23
  ```sh
@@ -120,6 +134,80 @@ import type {
120
134
 
121
135
  The canonical source of truth lives at [oc-me-web/src/lib/events/types.ts](https://github.com/orangecheck/oc-me-web/blob/main/src/lib/events/types.ts). This package mirrors that shape — any change there ships here in the next minor.
122
136
 
137
+ ## Server-side verification
138
+
139
+ Verify the OC session on your backend without writing a JWK fetcher, an env-var loader, or a cache. The SDK does that internally.
140
+
141
+ ### Next.js Pages Router
142
+
143
+ ```ts
144
+ // pages/api/me.ts
145
+ import { withOcAuth } from '@orangecheck/me-client/server';
146
+
147
+ export default withOcAuth(async (req, res) => {
148
+ if (!req.ocSession) return res.status(401).json({ ok: false });
149
+ res.status(200).json({
150
+ account: {
151
+ id: req.ocSession.sub,
152
+ address: req.ocSession.addr,
153
+ display_name: req.ocSession.name ?? null,
154
+ },
155
+ });
156
+ });
157
+ ```
158
+
159
+ Pass `{ required: true }` to short-circuit unauthenticated requests with a 401 before your handler runs.
160
+
161
+ ### Express
162
+
163
+ ```ts
164
+ import express from 'express';
165
+ import { ocAuthExpress } from '@orangecheck/me-client/server';
166
+
167
+ const app = express();
168
+ app.use(ocAuthExpress());
169
+
170
+ app.get('/api/profile', (req, res) => {
171
+ if (!req.ocSession) return res.status(401).json({ error: 'sign in' });
172
+ res.json({ address: req.ocSession.addr });
173
+ });
174
+ ```
175
+
176
+ ### Hono / Cloudflare Workers / Bun / Deno
177
+
178
+ ```ts
179
+ import { Hono } from 'hono';
180
+ import { ocAuthHono } from '@orangecheck/me-client/server';
181
+
182
+ const app = new Hono();
183
+ app.use('*', ocAuthHono());
184
+
185
+ app.get('/api/me', (c) => {
186
+ const session = c.get('ocSession');
187
+ if (!session) return c.json({ ok: false }, 401);
188
+ return c.json({ address: session.addr });
189
+ });
190
+ ```
191
+
192
+ `getOcSession(headers)` is the framework-agnostic primitive: pass a Web `Headers` object or a plain `{ cookie, authorization }` object. Cookie auth (family `*.ochk.io`) and Bearer auth (cross-domain) are handled identically.
193
+
194
+ ## Browser popup signin
195
+
196
+ ```tsx
197
+ import { signInWithOc } from '@orangecheck/me-client/popup';
198
+
199
+ button.addEventListener('click', async () => {
200
+ const result = await signInWithOc();
201
+ if (!result) return; // user cancelled or popup blocked
202
+ // Cross-domain integrators only — same-origin family integrators
203
+ // (.ochk.io) skip this; the cookie rides automatically.
204
+ localStorage.setItem('oc-token', result.token);
205
+ location.assign('/dashboard');
206
+ });
207
+ ```
208
+
209
+ `signInWithOc()` MUST be called inside a user-gesture handler (browsers block `window.open` outside of gestures). Returns `{ account, token }` on success, `null` on cancel / popup block / abort. Pins both `event.origin` AND `event.source === popup` on the postMessage handler so a same-origin attacker can't settle the promise.
210
+
123
211
  ## Custom origin
124
212
 
125
213
  For staging, self-hosted me-equivalents, or local dev:
package/dist/index.d.mts CHANGED
@@ -1,6 +1,30 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
 
4
+ interface VerifyResult {
5
+ ok: boolean;
6
+ reason?: string;
7
+ }
8
+ interface OcPublicJwk {
9
+ kty: 'OKP';
10
+ crv: 'Ed25519';
11
+ x: string;
12
+ kid: string;
13
+ alg?: 'EdDSA';
14
+ use?: 'sig';
15
+ }
16
+ interface VerifyOptions {
17
+ issuer?: string;
18
+ jwk?: OcPublicJwk;
19
+ jwksCacheTtlMs?: number;
20
+ }
21
+ declare function verify(rawBody: string | Uint8Array, sigHex: string, kid: string, options?: VerifyOptions): Promise<VerifyResult>;
22
+ declare function fetchJwksForce(issuer?: string): Promise<void>;
23
+ declare const webhook: {
24
+ verify: typeof verify;
25
+ fetchJwks: typeof fetchJwksForce;
26
+ };
27
+
4
28
  declare const PLATFORM_FEE_POLICY: {
5
29
  readonly pct: 0.2;
6
30
  readonly min_floor_sats: 1;
@@ -99,6 +123,38 @@ interface TelemetryEvent {
99
123
  timestamp: string;
100
124
  session_id?: string;
101
125
  }
126
+ type FederationStatus = 'recruiting' | 'forming' | 'binding' | 'live';
127
+ interface Federation {
128
+ slug: string;
129
+ name: string;
130
+ status: FederationStatus;
131
+ threshold: string;
132
+ target_guardian_count: number;
133
+ invite: string | null;
134
+ charter_hash: string | null;
135
+ last_attestation_at: string | null;
136
+ geography_hint: string;
137
+ geography_requirements?: string;
138
+ charter_status?: string;
139
+ ceremony_window?: string;
140
+ why_this_one?: string;
141
+ apply_cta?: string;
142
+ apply_href?: string;
143
+ }
144
+ type SigningMethod = 'fedimint_threshold' | 'fedimint_client' | 'bip322';
145
+
146
+ interface FireEventOptions {
147
+ project_key: string;
148
+ subtype: EventSubtype;
149
+ action_label?: string;
150
+ payment_amount_sats?: number;
151
+ user_address?: string;
152
+ metadata?: Record<string, unknown>;
153
+ }
154
+ declare function fire(options: FireEventOptions): Promise<BillableEvent>;
155
+ declare const event: {
156
+ fire: typeof fire;
157
+ };
102
158
 
103
159
  interface OcSignInButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onError'> {
104
160
  scope: string[];
@@ -125,8 +181,27 @@ declare const payment: {
125
181
  authorize: typeof authorize;
126
182
  };
127
183
 
184
+ declare function validate(cfg: IntegratorPriceConfig): ValidationResult;
185
+ declare const config: {
186
+ validate: typeof validate;
187
+ };
188
+
189
+ declare function list(): Promise<Federation[]>;
190
+ declare function live(): Promise<Federation[]>;
191
+ declare function get(slug: string): Promise<Federation | null>;
192
+ declare function defaultLive(): Promise<Federation | null>;
193
+ declare const federations: {
194
+ list: typeof list;
195
+ live: typeof live;
196
+ get: typeof get;
197
+ defaultLive: typeof defaultLive;
198
+ };
199
+
128
200
  declare function setOrigin(url: string): void;
129
201
  declare function getOrigin(): string;
202
+ declare function setBearerToken(token: string | null): void;
203
+ declare function getBearerToken(): string | null;
204
+ declare function clearBearerToken(): void;
130
205
  declare class MeClientError extends Error {
131
206
  readonly status: number;
132
207
  constructor(message: string, status: number);
@@ -141,6 +216,22 @@ declare const oc: {
141
216
  payment: {
142
217
  authorize: (opts: PaymentAuthorizeOptions) => Promise<PaymentResult>;
143
218
  };
219
+ event: {
220
+ fire: (options: FireEventOptions) => Promise<BillableEvent>;
221
+ };
222
+ config: {
223
+ validate: (cfg: IntegratorPriceConfig) => ValidationResult;
224
+ };
225
+ webhook: {
226
+ verify: typeof verify;
227
+ fetchJwks: typeof fetchJwksForce;
228
+ };
229
+ federations: {
230
+ list: () => Promise<Federation[]>;
231
+ live: () => Promise<Federation[]>;
232
+ get: (slug: string) => Promise<Federation | null>;
233
+ defaultLive: () => Promise<Federation | null>;
234
+ };
144
235
  };
145
236
 
146
- export { type AttestTier, type BillableEvent, type ClassASubtype, type ClassBSubtype, type ClassCSubtype, type ComputedFees, type EventClass, type EventSubtype, type IntegratorEventConfig, type IntegratorPriceConfig, MIN_INTEGRATOR_PRICE_SATS, MeClientError, OcSignInButton, type OcSignInButtonProps, PLATFORM_FEE_POLICY, type PaymentAuthorizeOptions, type PaymentResult, type Session, type SessionPolicy, type SignInOptions, type SiteFeeShape, type TelemetryEvent, type ValidationResult, computeFees, getOrigin, oc, onTelemetry, payment, session, setOrigin, validateIntegratorConfig };
237
+ export { type AttestTier, type BillableEvent, type ClassASubtype, type ClassBSubtype, type ClassCSubtype, type ComputedFees, type EventClass, type EventSubtype, type Federation, type FederationStatus, type FireEventOptions, type IntegratorEventConfig, type IntegratorPriceConfig, MIN_INTEGRATOR_PRICE_SATS, MeClientError, type OcPublicJwk, OcSignInButton, type OcSignInButtonProps, PLATFORM_FEE_POLICY, type PaymentAuthorizeOptions, type PaymentResult, type Session, type SessionPolicy, type SignInOptions, type SigningMethod, type SiteFeeShape, type TelemetryEvent, type ValidationResult, type VerifyOptions, type VerifyResult, clearBearerToken, computeFees, config, event, federations, getBearerToken, getOrigin, oc, onTelemetry, payment, session, setBearerToken, setOrigin, validateIntegratorConfig, webhook };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,30 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
 
4
+ interface VerifyResult {
5
+ ok: boolean;
6
+ reason?: string;
7
+ }
8
+ interface OcPublicJwk {
9
+ kty: 'OKP';
10
+ crv: 'Ed25519';
11
+ x: string;
12
+ kid: string;
13
+ alg?: 'EdDSA';
14
+ use?: 'sig';
15
+ }
16
+ interface VerifyOptions {
17
+ issuer?: string;
18
+ jwk?: OcPublicJwk;
19
+ jwksCacheTtlMs?: number;
20
+ }
21
+ declare function verify(rawBody: string | Uint8Array, sigHex: string, kid: string, options?: VerifyOptions): Promise<VerifyResult>;
22
+ declare function fetchJwksForce(issuer?: string): Promise<void>;
23
+ declare const webhook: {
24
+ verify: typeof verify;
25
+ fetchJwks: typeof fetchJwksForce;
26
+ };
27
+
4
28
  declare const PLATFORM_FEE_POLICY: {
5
29
  readonly pct: 0.2;
6
30
  readonly min_floor_sats: 1;
@@ -99,6 +123,38 @@ interface TelemetryEvent {
99
123
  timestamp: string;
100
124
  session_id?: string;
101
125
  }
126
+ type FederationStatus = 'recruiting' | 'forming' | 'binding' | 'live';
127
+ interface Federation {
128
+ slug: string;
129
+ name: string;
130
+ status: FederationStatus;
131
+ threshold: string;
132
+ target_guardian_count: number;
133
+ invite: string | null;
134
+ charter_hash: string | null;
135
+ last_attestation_at: string | null;
136
+ geography_hint: string;
137
+ geography_requirements?: string;
138
+ charter_status?: string;
139
+ ceremony_window?: string;
140
+ why_this_one?: string;
141
+ apply_cta?: string;
142
+ apply_href?: string;
143
+ }
144
+ type SigningMethod = 'fedimint_threshold' | 'fedimint_client' | 'bip322';
145
+
146
+ interface FireEventOptions {
147
+ project_key: string;
148
+ subtype: EventSubtype;
149
+ action_label?: string;
150
+ payment_amount_sats?: number;
151
+ user_address?: string;
152
+ metadata?: Record<string, unknown>;
153
+ }
154
+ declare function fire(options: FireEventOptions): Promise<BillableEvent>;
155
+ declare const event: {
156
+ fire: typeof fire;
157
+ };
102
158
 
103
159
  interface OcSignInButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onError'> {
104
160
  scope: string[];
@@ -125,8 +181,27 @@ declare const payment: {
125
181
  authorize: typeof authorize;
126
182
  };
127
183
 
184
+ declare function validate(cfg: IntegratorPriceConfig): ValidationResult;
185
+ declare const config: {
186
+ validate: typeof validate;
187
+ };
188
+
189
+ declare function list(): Promise<Federation[]>;
190
+ declare function live(): Promise<Federation[]>;
191
+ declare function get(slug: string): Promise<Federation | null>;
192
+ declare function defaultLive(): Promise<Federation | null>;
193
+ declare const federations: {
194
+ list: typeof list;
195
+ live: typeof live;
196
+ get: typeof get;
197
+ defaultLive: typeof defaultLive;
198
+ };
199
+
128
200
  declare function setOrigin(url: string): void;
129
201
  declare function getOrigin(): string;
202
+ declare function setBearerToken(token: string | null): void;
203
+ declare function getBearerToken(): string | null;
204
+ declare function clearBearerToken(): void;
130
205
  declare class MeClientError extends Error {
131
206
  readonly status: number;
132
207
  constructor(message: string, status: number);
@@ -141,6 +216,22 @@ declare const oc: {
141
216
  payment: {
142
217
  authorize: (opts: PaymentAuthorizeOptions) => Promise<PaymentResult>;
143
218
  };
219
+ event: {
220
+ fire: (options: FireEventOptions) => Promise<BillableEvent>;
221
+ };
222
+ config: {
223
+ validate: (cfg: IntegratorPriceConfig) => ValidationResult;
224
+ };
225
+ webhook: {
226
+ verify: typeof verify;
227
+ fetchJwks: typeof fetchJwksForce;
228
+ };
229
+ federations: {
230
+ list: () => Promise<Federation[]>;
231
+ live: () => Promise<Federation[]>;
232
+ get: (slug: string) => Promise<Federation | null>;
233
+ defaultLive: () => Promise<Federation | null>;
234
+ };
144
235
  };
145
236
 
146
- export { type AttestTier, type BillableEvent, type ClassASubtype, type ClassBSubtype, type ClassCSubtype, type ComputedFees, type EventClass, type EventSubtype, type IntegratorEventConfig, type IntegratorPriceConfig, MIN_INTEGRATOR_PRICE_SATS, MeClientError, OcSignInButton, type OcSignInButtonProps, PLATFORM_FEE_POLICY, type PaymentAuthorizeOptions, type PaymentResult, type Session, type SessionPolicy, type SignInOptions, type SiteFeeShape, type TelemetryEvent, type ValidationResult, computeFees, getOrigin, oc, onTelemetry, payment, session, setOrigin, validateIntegratorConfig };
237
+ export { type AttestTier, type BillableEvent, type ClassASubtype, type ClassBSubtype, type ClassCSubtype, type ComputedFees, type EventClass, type EventSubtype, type Federation, type FederationStatus, type FireEventOptions, type IntegratorEventConfig, type IntegratorPriceConfig, MIN_INTEGRATOR_PRICE_SATS, MeClientError, type OcPublicJwk, OcSignInButton, type OcSignInButtonProps, PLATFORM_FEE_POLICY, type PaymentAuthorizeOptions, type PaymentResult, type Session, type SessionPolicy, type SignInOptions, type SigningMethod, type SiteFeeShape, type TelemetryEvent, type ValidationResult, type VerifyOptions, type VerifyResult, clearBearerToken, computeFees, config, event, federations, getBearerToken, getOrigin, oc, onTelemetry, payment, session, setBearerToken, setOrigin, validateIntegratorConfig, webhook };