@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 +89 -1
- package/dist/index.d.mts +92 -1
- package/dist/index.d.ts +92 -1
- package/dist/index.js +409 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +403 -7
- package/dist/index.mjs.map +1 -1
- package/dist/popup.js +1 -0
- package/dist/popup.js.map +1 -1
- package/dist/popup.mjs +1 -0
- package/dist/popup.mjs.map +1 -1
- package/dist/server.js +2 -0
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +2 -0
- package/dist/server.mjs.map +1 -1
- package/package.json +18 -2
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,
|
|
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 };
|