@orangecheck/me-client 0.1.0 → 0.2.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/dist/index.d.mts CHANGED
@@ -1,12 +1,44 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
 
4
+ declare const PLATFORM_FEE_POLICY: {
5
+ readonly pct: 0.2;
6
+ readonly min_floor_sats: 1;
7
+ readonly ratified: "2026-04-30";
8
+ };
9
+ declare const MIN_INTEGRATOR_PRICE_SATS = 5;
4
10
  type EventClass = 'A' | 'B' | 'C';
5
11
  type ClassASubtype = 'account_creation' | 'account_recovery' | 'kyc_tier_upgrade' | 'payment_method_connected' | 'agent_delegation_issued' | 'recovery_method_updated';
6
12
  type ClassBSubtype = 'payment_authorization' | 'scoped_action_authorization' | 'attest_verification_at_gate' | 'stamp_signing' | 'pledge_resolution';
7
13
  type ClassCSubtype = 'session_creation';
8
14
  type EventSubtype = ClassASubtype | ClassBSubtype | ClassCSubtype;
9
15
  type AttestTier = 'anonymous' | 'bonded' | 'kyc_light' | 'kyc_strong';
16
+ type SiteFeeShape = {
17
+ kind: 'fixed_sats';
18
+ sats: number;
19
+ } | {
20
+ kind: 'percent_of_amount';
21
+ pct: number;
22
+ };
23
+ interface IntegratorEventConfig {
24
+ enabled: boolean;
25
+ site_pays: SiteFeeShape;
26
+ user_share_pct: number;
27
+ }
28
+ interface IntegratorPriceConfig {
29
+ project_key: string;
30
+ display_name: string;
31
+ domain: string;
32
+ updated_at: string;
33
+ events: Partial<Record<EventSubtype, IntegratorEventConfig>>;
34
+ }
35
+ interface ComputedFees {
36
+ gross_fee_sats: number;
37
+ platform_fee_sats: number;
38
+ user_earned_sats: number;
39
+ site_rebate_sats: number;
40
+ }
41
+ declare function computeFees(cfg: IntegratorEventConfig, payment_amount_sats?: number): ComputedFees;
10
42
  interface BillableEvent {
11
43
  id: string;
12
44
  occurred_at: string;
@@ -19,6 +51,7 @@ interface BillableEvent {
19
51
  gross_fee_sats: number;
20
52
  platform_fee_sats: number;
21
53
  user_earned_sats: number;
54
+ site_rebate_sats: number;
22
55
  verify_url: string;
23
56
  }
24
57
  interface SessionPolicy {
@@ -102,4 +135,4 @@ declare const oc: {
102
135
  };
103
136
  };
104
137
 
105
- export { type AttestTier, type BillableEvent, type ClassASubtype, type ClassBSubtype, type ClassCSubtype, type EventClass, type EventSubtype, MeClientError, OcSignInButton, type OcSignInButtonProps, type PaymentAuthorizeOptions, type PaymentResult, type Session, type SessionPolicy, type SignInOptions, type TelemetryEvent, getOrigin, oc, onTelemetry, payment, session, setOrigin };
138
+ 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, computeFees, getOrigin, oc, onTelemetry, payment, session, setOrigin };
package/dist/index.d.ts CHANGED
@@ -1,12 +1,44 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
 
4
+ declare const PLATFORM_FEE_POLICY: {
5
+ readonly pct: 0.2;
6
+ readonly min_floor_sats: 1;
7
+ readonly ratified: "2026-04-30";
8
+ };
9
+ declare const MIN_INTEGRATOR_PRICE_SATS = 5;
4
10
  type EventClass = 'A' | 'B' | 'C';
5
11
  type ClassASubtype = 'account_creation' | 'account_recovery' | 'kyc_tier_upgrade' | 'payment_method_connected' | 'agent_delegation_issued' | 'recovery_method_updated';
6
12
  type ClassBSubtype = 'payment_authorization' | 'scoped_action_authorization' | 'attest_verification_at_gate' | 'stamp_signing' | 'pledge_resolution';
7
13
  type ClassCSubtype = 'session_creation';
8
14
  type EventSubtype = ClassASubtype | ClassBSubtype | ClassCSubtype;
9
15
  type AttestTier = 'anonymous' | 'bonded' | 'kyc_light' | 'kyc_strong';
16
+ type SiteFeeShape = {
17
+ kind: 'fixed_sats';
18
+ sats: number;
19
+ } | {
20
+ kind: 'percent_of_amount';
21
+ pct: number;
22
+ };
23
+ interface IntegratorEventConfig {
24
+ enabled: boolean;
25
+ site_pays: SiteFeeShape;
26
+ user_share_pct: number;
27
+ }
28
+ interface IntegratorPriceConfig {
29
+ project_key: string;
30
+ display_name: string;
31
+ domain: string;
32
+ updated_at: string;
33
+ events: Partial<Record<EventSubtype, IntegratorEventConfig>>;
34
+ }
35
+ interface ComputedFees {
36
+ gross_fee_sats: number;
37
+ platform_fee_sats: number;
38
+ user_earned_sats: number;
39
+ site_rebate_sats: number;
40
+ }
41
+ declare function computeFees(cfg: IntegratorEventConfig, payment_amount_sats?: number): ComputedFees;
10
42
  interface BillableEvent {
11
43
  id: string;
12
44
  occurred_at: string;
@@ -19,6 +51,7 @@ interface BillableEvent {
19
51
  gross_fee_sats: number;
20
52
  platform_fee_sats: number;
21
53
  user_earned_sats: number;
54
+ site_rebate_sats: number;
22
55
  verify_url: string;
23
56
  }
24
57
  interface SessionPolicy {
@@ -102,4 +135,4 @@ declare const oc: {
102
135
  };
103
136
  };
104
137
 
105
- export { type AttestTier, type BillableEvent, type ClassASubtype, type ClassBSubtype, type ClassCSubtype, type EventClass, type EventSubtype, MeClientError, OcSignInButton, type OcSignInButtonProps, type PaymentAuthorizeOptions, type PaymentResult, type Session, type SessionPolicy, type SignInOptions, type TelemetryEvent, getOrigin, oc, onTelemetry, payment, session, setOrigin };
138
+ 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, computeFees, getOrigin, oc, onTelemetry, payment, session, setOrigin };
package/dist/index.js CHANGED
@@ -195,11 +195,48 @@ async function authorize(opts) {
195
195
  }
196
196
  var payment = { authorize };
197
197
 
198
+ // src/types.ts
199
+ var PLATFORM_FEE_POLICY = {
200
+ /** Fraction of every gross_fee that OC retains. */
201
+ pct: 0.2,
202
+ /** Absolute minimum platform fee, in sats. */
203
+ min_floor_sats: 1,
204
+ /** Date this policy was last ratified. Changes require an oc-me-protocol PR. */
205
+ ratified: "2026-04-30"
206
+ };
207
+ var MIN_INTEGRATOR_PRICE_SATS = 5;
208
+ function computeFees(cfg, payment_amount_sats) {
209
+ let gross = 0;
210
+ if (cfg.site_pays.kind === "fixed_sats") {
211
+ gross = Math.max(MIN_INTEGRATOR_PRICE_SATS, Math.round(cfg.site_pays.sats));
212
+ } else {
213
+ if (payment_amount_sats == null) {
214
+ throw new Error("percent_of_amount config requires payment_amount_sats");
215
+ }
216
+ gross = Math.max(
217
+ MIN_INTEGRATOR_PRICE_SATS,
218
+ Math.round(payment_amount_sats * cfg.site_pays.pct)
219
+ );
220
+ }
221
+ const platform_fee_sats = Math.max(
222
+ PLATFORM_FEE_POLICY.min_floor_sats,
223
+ Math.round(gross * PLATFORM_FEE_POLICY.pct)
224
+ );
225
+ const post_platform = Math.max(0, gross - platform_fee_sats);
226
+ const user_share = Math.min(0.8, Math.max(0, cfg.user_share_pct));
227
+ const user_earned_sats = Math.round(post_platform * (user_share / 0.8));
228
+ const site_rebate_sats = Math.max(0, post_platform - user_earned_sats);
229
+ return { gross_fee_sats: gross, platform_fee_sats, user_earned_sats, site_rebate_sats };
230
+ }
231
+
198
232
  // src/index.ts
199
233
  var oc = { session, payment };
200
234
 
235
+ exports.MIN_INTEGRATOR_PRICE_SATS = MIN_INTEGRATOR_PRICE_SATS;
201
236
  exports.MeClientError = MeClientError;
202
237
  exports.OcSignInButton = OcSignInButton;
238
+ exports.PLATFORM_FEE_POLICY = PLATFORM_FEE_POLICY;
239
+ exports.computeFees = computeFees;
203
240
  exports.getOrigin = getOrigin;
204
241
  exports.oc = oc;
205
242
  exports.onTelemetry = onTelemetry;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/transport.ts","../src/session.ts","../src/SignInButton.tsx","../src/payment.ts","../src/index.ts"],"names":["React","jsxs","jsx"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Tiny HTTP transport layer. The me.ochk.io origin is configurable so\n * staging deployments and self-hosted me-equivalents can swap it.\n */\n\nlet origin = 'https://me.ochk.io';\n\nexport function setOrigin(url: string): void {\n origin = url.replace(/\\/$/, '');\n}\n\nexport function getOrigin(): string {\n return origin;\n}\n\nexport interface FetchOptions {\n method?: 'GET' | 'POST' | 'PATCH' | 'DELETE';\n body?: unknown;\n signal?: AbortSignal;\n}\n\nexport async function api<T>(path: string, opts: FetchOptions = {}): Promise<T> {\n const res = await fetch(`${origin}${path}`, {\n method: opts.method ?? 'GET',\n credentials: 'include',\n headers: { 'content-type': 'application/json', accept: 'application/json' },\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\n signal: opts.signal,\n });\n if (!res.ok) {\n let message = `me.ochk.io ${res.status}`;\n try {\n const data = (await res.json()) as { error?: string };\n if (data?.error) message = data.error;\n } catch {\n /* ignore */\n }\n throw new MeClientError(message, res.status);\n }\n return (await res.json()) as T;\n}\n\nexport class MeClientError extends Error {\n public readonly status: number;\n constructor(message: string, status: number) {\n super(message);\n this.name = 'MeClientError';\n this.status = status;\n }\n}\n","import type { Session, SessionPolicy, SignInOptions, TelemetryEvent } from './types';\n\nimport { api } from './transport';\n\nconst DEFAULT_POLICY: SessionPolicy = {\n duration_seconds: 7 * 24 * 60 * 60, // 7 days, standard SaaS shape\n refresh: 'sliding',\n sensitive_actions: 're-auth',\n};\n\nconst telemetrySubscribers = new Set<(e: TelemetryEvent) => void>();\n\n/** Subscribe to non-billable developer telemetry events. Call the returned\n * function to unsubscribe. */\nexport function onTelemetry(listener: (e: TelemetryEvent) => void): () => void {\n telemetrySubscribers.add(listener);\n return () => {\n telemetrySubscribers.delete(listener);\n };\n}\n\nfunction emitTelemetry(code: TelemetryEvent['code'], session_id?: string): void {\n const e: TelemetryEvent = {\n code,\n timestamp: new Date().toISOString(),\n ...(session_id ? { session_id } : {}),\n };\n for (const fn of telemetrySubscribers) {\n try {\n fn(e);\n } catch {\n /* listener errors must not break the session flow */\n }\n }\n}\n\n/**\n * Open a sign-in flow at me.ochk.io. Returns the resulting Session once\n * the user consents (Class C billable event for the integrating site,\n * cashback for the user). Internally this opens the OC consent UI in a\n * popup; v1 implementations may also redirect.\n */\nasync function create(opts: SignInOptions): Promise<Session> {\n const policy: SessionPolicy = { ...DEFAULT_POLICY, ...(opts.sessionPolicy ?? {}) };\n return api<Session>('/api/session/create', {\n method: 'POST',\n body: {\n scope: opts.scope,\n policy,\n return_to: opts.returnTo ?? (typeof window !== 'undefined' ? window.location.href : undefined),\n },\n });\n}\n\n/**\n * Refresh a still-valid session inside its policy window. Free for the\n * integrating site (does NOT instantiate a billable event); emits a\n * `session.token_refresh` telemetry record.\n */\nasync function refresh(sessionId: string): Promise<Session> {\n emitTelemetry('session.token_refresh', sessionId);\n return api<Session>('/api/session/refresh', {\n method: 'POST',\n body: { session_id: sessionId },\n });\n}\n\n/** Invalidate a session. Free, telemetry-only. */\nasync function invalidate(sessionId: string): Promise<void> {\n emitTelemetry('session.intra_signin', sessionId);\n await api<{ ok: true }>('/api/session/invalidate', {\n method: 'POST',\n body: { session_id: sessionId },\n });\n}\n\nexport const session = { create, refresh, invalidate };\n","import * as React from 'react';\n\nimport { session } from './session';\nimport type { Session, SessionPolicy } from './types';\n\nexport interface OcSignInButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onError'> {\n scope: string[];\n sessionPolicy?: Partial<SessionPolicy>;\n returnTo?: string;\n onSignin?: (session: Session) => void;\n /** Called when the sign-in flow fails. Renamed from `onError` to avoid\n * shadowing the native button error handler. */\n onSignInError?: (error: Error) => void;\n /** Custom button text. Defaults to \"sign in with oc\". */\n label?: string;\n}\n\n/**\n * Drop-in Sign-in-with-OC button. Triggers the me.ochk.io consent flow\n * for the requested scope, opens (or refreshes) a session, and calls\n * onSignin(session) on success. Class C billable event for the\n * integrating site; cashback flows to the user.\n *\n * Mounting requires <OcSessionProvider> from @orangecheck/auth-client\n * somewhere up the React tree so the resulting session can be read by\n * useOcSession() across the rest of the app.\n */\nexport function OcSignInButton({\n scope,\n sessionPolicy,\n returnTo,\n onSignin,\n onSignInError,\n label = 'sign in with oc',\n children,\n onClick,\n style,\n ...rest\n}: OcSignInButtonProps) {\n const [pending, setPending] = React.useState(false);\n\n return (\n <button\n type=\"button\"\n onClick={async (event) => {\n onClick?.(event);\n if (event.defaultPrevented) return;\n setPending(true);\n try {\n const result = await session.create({ scope, sessionPolicy, returnTo });\n onSignin?.(result);\n } catch (err) {\n onSignInError?.(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setPending(false);\n }\n }}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 8,\n padding: '10px 16px',\n fontSize: 13,\n fontWeight: 600,\n fontFamily: 'ui-monospace, \"JetBrains Mono\", \"SF Mono\", Menlo, monospace',\n letterSpacing: '0.18em',\n textTransform: 'uppercase',\n background: '#f97316',\n color: '#0b0909',\n border: '1px solid #f97316',\n borderRadius: 4,\n cursor: pending ? 'progress' : 'pointer',\n opacity: pending ? 0.7 : 1,\n ...(style ?? {}),\n }}\n disabled={pending || rest.disabled}\n data-oc-signin\n {...rest}\n >\n {/* compact OC mark */}\n <span\n aria-hidden\n style={{\n display: 'inline-block',\n width: 12,\n height: 12,\n background: '#0b0909',\n }}\n />\n {children ?? (pending ? 'opening…' : label)}\n </button>\n );\n}\n","import type { PaymentAuthorizeOptions, PaymentResult } from './types';\n\nimport { api } from './transport';\n\n/**\n * Authorize a payment through the user's OC identity. Class B billable\n * event for the integrating site (sub-Stripe rate, percentage-based);\n * cashback flows to the user as Lightning credit on /me/earn.\n *\n * The user is prompted by me.ochk.io to consent to the specific payment\n * before this resolves. If the user declines or cancels, the result has\n * status `'cancelled'`, a non-billable telemetry record is emitted, and\n * NO billable event is created.\n */\nasync function authorize(opts: PaymentAuthorizeOptions): Promise<PaymentResult> {\n if (opts.amount_sats == null && opts.usd_cents == null) {\n throw new Error('payment.authorize requires amount_sats or usd_cents');\n }\n return api<PaymentResult>('/api/payment/authorize', {\n method: 'POST',\n body: opts,\n });\n}\n\nexport const payment = { authorize };\n","/**\n * @orangecheck/me-client\n *\n * Drop-in client for me.ochk.io. Exports the canonical billable-event\n * taxonomy as TypeScript types, session lifecycle hooks, payment\n * authorization, the developer telemetry stream, and the React sign-in\n * button.\n *\n * Sign-in-with-OC. You pay for sessions and actions, not for clicks.\n */\n\nexport { OcSignInButton } from './SignInButton';\nexport type { OcSignInButtonProps } from './SignInButton';\n\nexport { session, onTelemetry } from './session';\nexport { payment } from './payment';\nexport { setOrigin, getOrigin, MeClientError } from './transport';\n\nexport type {\n EventClass,\n EventSubtype,\n ClassASubtype,\n ClassBSubtype,\n ClassCSubtype,\n AttestTier,\n BillableEvent,\n Session,\n SessionPolicy,\n SignInOptions,\n PaymentAuthorizeOptions,\n PaymentResult,\n TelemetryEvent,\n} from './types';\n\nimport { session } from './session';\nimport { payment } from './payment';\n\n/** Convenience namespace mirroring the public API surface in /integrate\n * code samples — `oc.session.create()`, `oc.payment.authorize()`. */\nexport const oc = { session, payment };\n"]}
1
+ {"version":3,"sources":["../src/transport.ts","../src/session.ts","../src/SignInButton.tsx","../src/payment.ts","../src/types.ts","../src/index.ts"],"names":["React","jsxs","jsx"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Tiny HTTP transport layer. The me.ochk.io origin is configurable so\n * staging deployments and self-hosted me-equivalents can swap it.\n */\n\nlet origin = 'https://me.ochk.io';\n\nexport function setOrigin(url: string): void {\n origin = url.replace(/\\/$/, '');\n}\n\nexport function getOrigin(): string {\n return origin;\n}\n\nexport interface FetchOptions {\n method?: 'GET' | 'POST' | 'PATCH' | 'DELETE';\n body?: unknown;\n signal?: AbortSignal;\n}\n\nexport async function api<T>(path: string, opts: FetchOptions = {}): Promise<T> {\n const res = await fetch(`${origin}${path}`, {\n method: opts.method ?? 'GET',\n credentials: 'include',\n headers: { 'content-type': 'application/json', accept: 'application/json' },\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\n signal: opts.signal,\n });\n if (!res.ok) {\n let message = `me.ochk.io ${res.status}`;\n try {\n const data = (await res.json()) as { error?: string };\n if (data?.error) message = data.error;\n } catch {\n /* ignore */\n }\n throw new MeClientError(message, res.status);\n }\n return (await res.json()) as T;\n}\n\nexport class MeClientError extends Error {\n public readonly status: number;\n constructor(message: string, status: number) {\n super(message);\n this.name = 'MeClientError';\n this.status = status;\n }\n}\n","import type { Session, SessionPolicy, SignInOptions, TelemetryEvent } from './types';\n\nimport { api } from './transport';\n\nconst DEFAULT_POLICY: SessionPolicy = {\n duration_seconds: 7 * 24 * 60 * 60, // 7 days, standard SaaS shape\n refresh: 'sliding',\n sensitive_actions: 're-auth',\n};\n\nconst telemetrySubscribers = new Set<(e: TelemetryEvent) => void>();\n\n/** Subscribe to non-billable developer telemetry events. Call the returned\n * function to unsubscribe. */\nexport function onTelemetry(listener: (e: TelemetryEvent) => void): () => void {\n telemetrySubscribers.add(listener);\n return () => {\n telemetrySubscribers.delete(listener);\n };\n}\n\nfunction emitTelemetry(code: TelemetryEvent['code'], session_id?: string): void {\n const e: TelemetryEvent = {\n code,\n timestamp: new Date().toISOString(),\n ...(session_id ? { session_id } : {}),\n };\n for (const fn of telemetrySubscribers) {\n try {\n fn(e);\n } catch {\n /* listener errors must not break the session flow */\n }\n }\n}\n\n/**\n * Open a sign-in flow at me.ochk.io. Returns the resulting Session once\n * the user consents (Class C billable event for the integrating site,\n * cashback for the user). Internally this opens the OC consent UI in a\n * popup; v1 implementations may also redirect.\n */\nasync function create(opts: SignInOptions): Promise<Session> {\n const policy: SessionPolicy = { ...DEFAULT_POLICY, ...(opts.sessionPolicy ?? {}) };\n return api<Session>('/api/session/create', {\n method: 'POST',\n body: {\n scope: opts.scope,\n policy,\n return_to: opts.returnTo ?? (typeof window !== 'undefined' ? window.location.href : undefined),\n },\n });\n}\n\n/**\n * Refresh a still-valid session inside its policy window. Free for the\n * integrating site (does NOT instantiate a billable event); emits a\n * `session.token_refresh` telemetry record.\n */\nasync function refresh(sessionId: string): Promise<Session> {\n emitTelemetry('session.token_refresh', sessionId);\n return api<Session>('/api/session/refresh', {\n method: 'POST',\n body: { session_id: sessionId },\n });\n}\n\n/** Invalidate a session. Free, telemetry-only. */\nasync function invalidate(sessionId: string): Promise<void> {\n emitTelemetry('session.intra_signin', sessionId);\n await api<{ ok: true }>('/api/session/invalidate', {\n method: 'POST',\n body: { session_id: sessionId },\n });\n}\n\nexport const session = { create, refresh, invalidate };\n","import * as React from 'react';\n\nimport { session } from './session';\nimport type { Session, SessionPolicy } from './types';\n\nexport interface OcSignInButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onError'> {\n scope: string[];\n sessionPolicy?: Partial<SessionPolicy>;\n returnTo?: string;\n onSignin?: (session: Session) => void;\n /** Called when the sign-in flow fails. Renamed from `onError` to avoid\n * shadowing the native button error handler. */\n onSignInError?: (error: Error) => void;\n /** Custom button text. Defaults to \"sign in with oc\". */\n label?: string;\n}\n\n/**\n * Drop-in Sign-in-with-OC button. Triggers the me.ochk.io consent flow\n * for the requested scope, opens (or refreshes) a session, and calls\n * onSignin(session) on success. Class C billable event for the\n * integrating site; cashback flows to the user.\n *\n * Mounting requires <OcSessionProvider> from @orangecheck/auth-client\n * somewhere up the React tree so the resulting session can be read by\n * useOcSession() across the rest of the app.\n */\nexport function OcSignInButton({\n scope,\n sessionPolicy,\n returnTo,\n onSignin,\n onSignInError,\n label = 'sign in with oc',\n children,\n onClick,\n style,\n ...rest\n}: OcSignInButtonProps) {\n const [pending, setPending] = React.useState(false);\n\n return (\n <button\n type=\"button\"\n onClick={async (event) => {\n onClick?.(event);\n if (event.defaultPrevented) return;\n setPending(true);\n try {\n const result = await session.create({ scope, sessionPolicy, returnTo });\n onSignin?.(result);\n } catch (err) {\n onSignInError?.(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setPending(false);\n }\n }}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 8,\n padding: '10px 16px',\n fontSize: 13,\n fontWeight: 600,\n fontFamily: 'ui-monospace, \"JetBrains Mono\", \"SF Mono\", Menlo, monospace',\n letterSpacing: '0.18em',\n textTransform: 'uppercase',\n background: '#f97316',\n color: '#0b0909',\n border: '1px solid #f97316',\n borderRadius: 4,\n cursor: pending ? 'progress' : 'pointer',\n opacity: pending ? 0.7 : 1,\n ...(style ?? {}),\n }}\n disabled={pending || rest.disabled}\n data-oc-signin\n {...rest}\n >\n {/* compact OC mark */}\n <span\n aria-hidden\n style={{\n display: 'inline-block',\n width: 12,\n height: 12,\n background: '#0b0909',\n }}\n />\n {children ?? (pending ? 'opening…' : label)}\n </button>\n );\n}\n","import type { PaymentAuthorizeOptions, PaymentResult } from './types';\n\nimport { api } from './transport';\n\n/**\n * Authorize a payment through the user's OC identity. Class B billable\n * event for the integrating site (sub-Stripe rate, percentage-based);\n * cashback flows to the user as Lightning credit on /me/earn.\n *\n * The user is prompted by me.ochk.io to consent to the specific payment\n * before this resolves. If the user declines or cancels, the result has\n * status `'cancelled'`, a non-billable telemetry record is emitted, and\n * NO billable event is created.\n */\nasync function authorize(opts: PaymentAuthorizeOptions): Promise<PaymentResult> {\n if (opts.amount_sats == null && opts.usd_cents == null) {\n throw new Error('payment.authorize requires amount_sats or usd_cents');\n }\n return api<PaymentResult>('/api/payment/authorize', {\n method: 'POST',\n body: opts,\n });\n}\n\nexport const payment = { authorize };\n","/**\n * Canonical types for me.ochk.io integrators.\n *\n * Mirrors the source of truth at oc-me-web/src/lib/events/types.ts. Two\n * layers:\n * - Platform-level (PLATFORM_FEE_POLICY, MIN_INTEGRATOR_PRICE_SATS) —\n * fixed by OC, surfaced as constants here so integrators can validate\n * their config client-side before posting it.\n * - Integrator-level (IntegratorPriceConfig) — every integrator declares\n * their own per-event prices and user-share splits.\n *\n * Per Addendum 01: every chargeable event is in exactly one of three\n * classes. Sites pay for sessions and actions, not for clicks. Free\n * events never instantiate a BillableEvent.\n */\n\n// ── platform constants (fixed by OC) ──────────────────────────────────────\n\nexport const PLATFORM_FEE_POLICY = {\n /** Fraction of every gross_fee that OC retains. */\n pct: 0.2,\n /** Absolute minimum platform fee, in sats. */\n min_floor_sats: 1,\n /** Date this policy was last ratified. Changes require an oc-me-protocol PR. */\n ratified: '2026-04-30',\n} as const;\n\n/** Anti-spam price floor. No integrator can configure a per-event price\n * below this. */\nexport const MIN_INTEGRATOR_PRICE_SATS = 5;\n\n// ── event taxonomy ────────────────────────────────────────────────────────\n\nexport type EventClass = 'A' | 'B' | 'C';\n\nexport type ClassASubtype =\n | 'account_creation'\n | 'account_recovery'\n | 'kyc_tier_upgrade'\n | 'payment_method_connected'\n | 'agent_delegation_issued'\n | 'recovery_method_updated';\n\nexport type ClassBSubtype =\n | 'payment_authorization'\n | 'scoped_action_authorization'\n | 'attest_verification_at_gate'\n | 'stamp_signing'\n | 'pledge_resolution';\n\nexport type ClassCSubtype = 'session_creation';\n\nexport type EventSubtype = ClassASubtype | ClassBSubtype | ClassCSubtype;\n\nexport type AttestTier = 'anonymous' | 'bonded' | 'kyc_light' | 'kyc_strong';\n\n/** The shape of a per-event fee — either a fixed sats amount or a percent\n * of the underlying transaction amount (used for payments + pledges). */\nexport type SiteFeeShape =\n | { kind: 'fixed_sats'; sats: number }\n | { kind: 'percent_of_amount'; pct: number };\n\n/** What an integrator declares for a single event subtype. */\nexport interface IntegratorEventConfig {\n /** Whether this site bills this event subtype at all. */\n enabled: boolean;\n /** The per-event fee the site pays. */\n site_pays: SiteFeeShape;\n /** Fraction of post-platform-fee that flows to the user (0–0.8 since\n * platform_fee is 20%). The remainder is a rebate to the site's OC\n * project balance. */\n user_share_pct: number;\n}\n\n/** A complete integrator pricing config. Posted to me.ochk.io once at\n * integration time, mutable via the configurator UI or this SDK any time\n * after. */\nexport interface IntegratorPriceConfig {\n project_key: string;\n display_name: string;\n domain: string;\n /** ISO-8601 timestamp the config was last updated. */\n updated_at: string;\n /** Per-subtype configs. Subtypes not listed are disabled by default. */\n events: Partial<Record<EventSubtype, IntegratorEventConfig>>;\n}\n\n/** A computed fee breakdown for a single event. site_rebate_sats is what\n * flows back to the integrator's OC balance after OC's platform fee and\n * the user's cashback. */\nexport interface ComputedFees {\n gross_fee_sats: number;\n platform_fee_sats: number;\n user_earned_sats: number;\n site_rebate_sats: number;\n}\n\n/** Compute the four-way fee split for an event given an integrator's\n * config and (for percent_of_amount events) the underlying payment\n * amount. Mirrors the canonical computeFees in oc-me-web. */\nexport function computeFees(\n cfg: IntegratorEventConfig,\n payment_amount_sats?: number\n): ComputedFees {\n let gross = 0;\n if (cfg.site_pays.kind === 'fixed_sats') {\n gross = Math.max(MIN_INTEGRATOR_PRICE_SATS, Math.round(cfg.site_pays.sats));\n } else {\n if (payment_amount_sats == null) {\n throw new Error('percent_of_amount config requires payment_amount_sats');\n }\n gross = Math.max(\n MIN_INTEGRATOR_PRICE_SATS,\n Math.round(payment_amount_sats * cfg.site_pays.pct)\n );\n }\n const platform_fee_sats = Math.max(\n PLATFORM_FEE_POLICY.min_floor_sats,\n Math.round(gross * PLATFORM_FEE_POLICY.pct)\n );\n const post_platform = Math.max(0, gross - platform_fee_sats);\n const user_share = Math.min(0.8, Math.max(0, cfg.user_share_pct));\n const user_earned_sats = Math.round(post_platform * (user_share / 0.8));\n const site_rebate_sats = Math.max(0, post_platform - user_earned_sats);\n return { gross_fee_sats: gross, platform_fee_sats, user_earned_sats, site_rebate_sats };\n}\n\n// ── canonical envelope ────────────────────────────────────────────────────\n\nexport interface BillableEvent {\n id: string;\n occurred_at: string;\n class: EventClass;\n subtype: EventSubtype;\n site: { domain: string; display_name: string };\n gross_fee_sats: number;\n platform_fee_sats: number;\n user_earned_sats: number;\n site_rebate_sats: number;\n verify_url: string;\n}\n\n// ── session lifecycle ────────────────────────────────────────────────────\n\nexport interface SessionPolicy {\n duration_seconds: number;\n refresh: 'sliding' | 'rolling' | 'none';\n sensitive_actions?: 're-auth' | 'none';\n}\n\nexport interface Session {\n id: string;\n identity: string;\n opens_at: string;\n expires_at: string;\n policy: SessionPolicy;\n scope: string[];\n}\n\nexport interface SignInOptions {\n scope: string[];\n sessionPolicy?: Partial<SessionPolicy>;\n returnTo?: string;\n}\n\nexport interface PaymentAuthorizeOptions {\n identity: string;\n amount_sats?: number;\n usd_cents?: number;\n description: string;\n external_ref?: string;\n}\n\nexport interface PaymentResult {\n id: string;\n status: 'authorized' | 'failed' | 'cancelled';\n sats_charged?: number;\n user_envelope_id?: string;\n verify_url?: string;\n}\n\nexport interface TelemetryEvent {\n code:\n | 'session.intra_signin'\n | 'session.token_refresh'\n | 'session.navigation'\n | 'auth.signin_failed'\n | 'auth.signin_cancelled'\n | 'auth.signin_rejected'\n | 'verify.passive_check';\n timestamp: string;\n session_id?: string;\n}\n","/**\n * @orangecheck/me-client\n *\n * Drop-in client for me.ochk.io. Exports the canonical billable-event\n * taxonomy as TypeScript types, session lifecycle hooks, payment\n * authorization, the developer telemetry stream, and the React sign-in\n * button.\n *\n * Sign-in-with-OC. You pay for sessions and actions, not for clicks.\n */\n\nexport { OcSignInButton } from './SignInButton';\nexport type { OcSignInButtonProps } from './SignInButton';\n\nexport { session, onTelemetry } from './session';\nexport { payment } from './payment';\nexport { setOrigin, getOrigin, MeClientError } from './transport';\n\nexport {\n PLATFORM_FEE_POLICY,\n MIN_INTEGRATOR_PRICE_SATS,\n computeFees,\n} from './types';\n\nexport type {\n EventClass,\n EventSubtype,\n ClassASubtype,\n ClassBSubtype,\n ClassCSubtype,\n AttestTier,\n SiteFeeShape,\n IntegratorEventConfig,\n IntegratorPriceConfig,\n ComputedFees,\n BillableEvent,\n Session,\n SessionPolicy,\n SignInOptions,\n PaymentAuthorizeOptions,\n PaymentResult,\n TelemetryEvent,\n} from './types';\n\nimport { session } from './session';\nimport { payment } from './payment';\n\n/** Convenience namespace mirroring the public API surface in /integrate\n * code samples — `oc.session.create()`, `oc.payment.authorize()`. */\nexport const oc = { session, payment };\n"]}
package/dist/index.mjs CHANGED
@@ -173,9 +173,43 @@ async function authorize(opts) {
173
173
  }
174
174
  var payment = { authorize };
175
175
 
176
+ // src/types.ts
177
+ var PLATFORM_FEE_POLICY = {
178
+ /** Fraction of every gross_fee that OC retains. */
179
+ pct: 0.2,
180
+ /** Absolute minimum platform fee, in sats. */
181
+ min_floor_sats: 1,
182
+ /** Date this policy was last ratified. Changes require an oc-me-protocol PR. */
183
+ ratified: "2026-04-30"
184
+ };
185
+ var MIN_INTEGRATOR_PRICE_SATS = 5;
186
+ function computeFees(cfg, payment_amount_sats) {
187
+ let gross = 0;
188
+ if (cfg.site_pays.kind === "fixed_sats") {
189
+ gross = Math.max(MIN_INTEGRATOR_PRICE_SATS, Math.round(cfg.site_pays.sats));
190
+ } else {
191
+ if (payment_amount_sats == null) {
192
+ throw new Error("percent_of_amount config requires payment_amount_sats");
193
+ }
194
+ gross = Math.max(
195
+ MIN_INTEGRATOR_PRICE_SATS,
196
+ Math.round(payment_amount_sats * cfg.site_pays.pct)
197
+ );
198
+ }
199
+ const platform_fee_sats = Math.max(
200
+ PLATFORM_FEE_POLICY.min_floor_sats,
201
+ Math.round(gross * PLATFORM_FEE_POLICY.pct)
202
+ );
203
+ const post_platform = Math.max(0, gross - platform_fee_sats);
204
+ const user_share = Math.min(0.8, Math.max(0, cfg.user_share_pct));
205
+ const user_earned_sats = Math.round(post_platform * (user_share / 0.8));
206
+ const site_rebate_sats = Math.max(0, post_platform - user_earned_sats);
207
+ return { gross_fee_sats: gross, platform_fee_sats, user_earned_sats, site_rebate_sats };
208
+ }
209
+
176
210
  // src/index.ts
177
211
  var oc = { session, payment };
178
212
 
179
- export { MeClientError, OcSignInButton, getOrigin, oc, onTelemetry, payment, session, setOrigin };
213
+ export { MIN_INTEGRATOR_PRICE_SATS, MeClientError, OcSignInButton, PLATFORM_FEE_POLICY, computeFees, getOrigin, oc, onTelemetry, payment, session, setOrigin };
180
214
  //# sourceMappingURL=index.mjs.map
181
215
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/transport.ts","../src/session.ts","../src/SignInButton.tsx","../src/payment.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Tiny HTTP transport layer. The me.ochk.io origin is configurable so\n * staging deployments and self-hosted me-equivalents can swap it.\n */\n\nlet origin = 'https://me.ochk.io';\n\nexport function setOrigin(url: string): void {\n origin = url.replace(/\\/$/, '');\n}\n\nexport function getOrigin(): string {\n return origin;\n}\n\nexport interface FetchOptions {\n method?: 'GET' | 'POST' | 'PATCH' | 'DELETE';\n body?: unknown;\n signal?: AbortSignal;\n}\n\nexport async function api<T>(path: string, opts: FetchOptions = {}): Promise<T> {\n const res = await fetch(`${origin}${path}`, {\n method: opts.method ?? 'GET',\n credentials: 'include',\n headers: { 'content-type': 'application/json', accept: 'application/json' },\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\n signal: opts.signal,\n });\n if (!res.ok) {\n let message = `me.ochk.io ${res.status}`;\n try {\n const data = (await res.json()) as { error?: string };\n if (data?.error) message = data.error;\n } catch {\n /* ignore */\n }\n throw new MeClientError(message, res.status);\n }\n return (await res.json()) as T;\n}\n\nexport class MeClientError extends Error {\n public readonly status: number;\n constructor(message: string, status: number) {\n super(message);\n this.name = 'MeClientError';\n this.status = status;\n }\n}\n","import type { Session, SessionPolicy, SignInOptions, TelemetryEvent } from './types';\n\nimport { api } from './transport';\n\nconst DEFAULT_POLICY: SessionPolicy = {\n duration_seconds: 7 * 24 * 60 * 60, // 7 days, standard SaaS shape\n refresh: 'sliding',\n sensitive_actions: 're-auth',\n};\n\nconst telemetrySubscribers = new Set<(e: TelemetryEvent) => void>();\n\n/** Subscribe to non-billable developer telemetry events. Call the returned\n * function to unsubscribe. */\nexport function onTelemetry(listener: (e: TelemetryEvent) => void): () => void {\n telemetrySubscribers.add(listener);\n return () => {\n telemetrySubscribers.delete(listener);\n };\n}\n\nfunction emitTelemetry(code: TelemetryEvent['code'], session_id?: string): void {\n const e: TelemetryEvent = {\n code,\n timestamp: new Date().toISOString(),\n ...(session_id ? { session_id } : {}),\n };\n for (const fn of telemetrySubscribers) {\n try {\n fn(e);\n } catch {\n /* listener errors must not break the session flow */\n }\n }\n}\n\n/**\n * Open a sign-in flow at me.ochk.io. Returns the resulting Session once\n * the user consents (Class C billable event for the integrating site,\n * cashback for the user). Internally this opens the OC consent UI in a\n * popup; v1 implementations may also redirect.\n */\nasync function create(opts: SignInOptions): Promise<Session> {\n const policy: SessionPolicy = { ...DEFAULT_POLICY, ...(opts.sessionPolicy ?? {}) };\n return api<Session>('/api/session/create', {\n method: 'POST',\n body: {\n scope: opts.scope,\n policy,\n return_to: opts.returnTo ?? (typeof window !== 'undefined' ? window.location.href : undefined),\n },\n });\n}\n\n/**\n * Refresh a still-valid session inside its policy window. Free for the\n * integrating site (does NOT instantiate a billable event); emits a\n * `session.token_refresh` telemetry record.\n */\nasync function refresh(sessionId: string): Promise<Session> {\n emitTelemetry('session.token_refresh', sessionId);\n return api<Session>('/api/session/refresh', {\n method: 'POST',\n body: { session_id: sessionId },\n });\n}\n\n/** Invalidate a session. Free, telemetry-only. */\nasync function invalidate(sessionId: string): Promise<void> {\n emitTelemetry('session.intra_signin', sessionId);\n await api<{ ok: true }>('/api/session/invalidate', {\n method: 'POST',\n body: { session_id: sessionId },\n });\n}\n\nexport const session = { create, refresh, invalidate };\n","import * as React from 'react';\n\nimport { session } from './session';\nimport type { Session, SessionPolicy } from './types';\n\nexport interface OcSignInButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onError'> {\n scope: string[];\n sessionPolicy?: Partial<SessionPolicy>;\n returnTo?: string;\n onSignin?: (session: Session) => void;\n /** Called when the sign-in flow fails. Renamed from `onError` to avoid\n * shadowing the native button error handler. */\n onSignInError?: (error: Error) => void;\n /** Custom button text. Defaults to \"sign in with oc\". */\n label?: string;\n}\n\n/**\n * Drop-in Sign-in-with-OC button. Triggers the me.ochk.io consent flow\n * for the requested scope, opens (or refreshes) a session, and calls\n * onSignin(session) on success. Class C billable event for the\n * integrating site; cashback flows to the user.\n *\n * Mounting requires <OcSessionProvider> from @orangecheck/auth-client\n * somewhere up the React tree so the resulting session can be read by\n * useOcSession() across the rest of the app.\n */\nexport function OcSignInButton({\n scope,\n sessionPolicy,\n returnTo,\n onSignin,\n onSignInError,\n label = 'sign in with oc',\n children,\n onClick,\n style,\n ...rest\n}: OcSignInButtonProps) {\n const [pending, setPending] = React.useState(false);\n\n return (\n <button\n type=\"button\"\n onClick={async (event) => {\n onClick?.(event);\n if (event.defaultPrevented) return;\n setPending(true);\n try {\n const result = await session.create({ scope, sessionPolicy, returnTo });\n onSignin?.(result);\n } catch (err) {\n onSignInError?.(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setPending(false);\n }\n }}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 8,\n padding: '10px 16px',\n fontSize: 13,\n fontWeight: 600,\n fontFamily: 'ui-monospace, \"JetBrains Mono\", \"SF Mono\", Menlo, monospace',\n letterSpacing: '0.18em',\n textTransform: 'uppercase',\n background: '#f97316',\n color: '#0b0909',\n border: '1px solid #f97316',\n borderRadius: 4,\n cursor: pending ? 'progress' : 'pointer',\n opacity: pending ? 0.7 : 1,\n ...(style ?? {}),\n }}\n disabled={pending || rest.disabled}\n data-oc-signin\n {...rest}\n >\n {/* compact OC mark */}\n <span\n aria-hidden\n style={{\n display: 'inline-block',\n width: 12,\n height: 12,\n background: '#0b0909',\n }}\n />\n {children ?? (pending ? 'opening…' : label)}\n </button>\n );\n}\n","import type { PaymentAuthorizeOptions, PaymentResult } from './types';\n\nimport { api } from './transport';\n\n/**\n * Authorize a payment through the user's OC identity. Class B billable\n * event for the integrating site (sub-Stripe rate, percentage-based);\n * cashback flows to the user as Lightning credit on /me/earn.\n *\n * The user is prompted by me.ochk.io to consent to the specific payment\n * before this resolves. If the user declines or cancels, the result has\n * status `'cancelled'`, a non-billable telemetry record is emitted, and\n * NO billable event is created.\n */\nasync function authorize(opts: PaymentAuthorizeOptions): Promise<PaymentResult> {\n if (opts.amount_sats == null && opts.usd_cents == null) {\n throw new Error('payment.authorize requires amount_sats or usd_cents');\n }\n return api<PaymentResult>('/api/payment/authorize', {\n method: 'POST',\n body: opts,\n });\n}\n\nexport const payment = { authorize };\n","/**\n * @orangecheck/me-client\n *\n * Drop-in client for me.ochk.io. Exports the canonical billable-event\n * taxonomy as TypeScript types, session lifecycle hooks, payment\n * authorization, the developer telemetry stream, and the React sign-in\n * button.\n *\n * Sign-in-with-OC. You pay for sessions and actions, not for clicks.\n */\n\nexport { OcSignInButton } from './SignInButton';\nexport type { OcSignInButtonProps } from './SignInButton';\n\nexport { session, onTelemetry } from './session';\nexport { payment } from './payment';\nexport { setOrigin, getOrigin, MeClientError } from './transport';\n\nexport type {\n EventClass,\n EventSubtype,\n ClassASubtype,\n ClassBSubtype,\n ClassCSubtype,\n AttestTier,\n BillableEvent,\n Session,\n SessionPolicy,\n SignInOptions,\n PaymentAuthorizeOptions,\n PaymentResult,\n TelemetryEvent,\n} from './types';\n\nimport { session } from './session';\nimport { payment } from './payment';\n\n/** Convenience namespace mirroring the public API surface in /integrate\n * code samples — `oc.session.create()`, `oc.payment.authorize()`. */\nexport const oc = { session, payment };\n"]}
1
+ {"version":3,"sources":["../src/transport.ts","../src/session.ts","../src/SignInButton.tsx","../src/payment.ts","../src/types.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Tiny HTTP transport layer. The me.ochk.io origin is configurable so\n * staging deployments and self-hosted me-equivalents can swap it.\n */\n\nlet origin = 'https://me.ochk.io';\n\nexport function setOrigin(url: string): void {\n origin = url.replace(/\\/$/, '');\n}\n\nexport function getOrigin(): string {\n return origin;\n}\n\nexport interface FetchOptions {\n method?: 'GET' | 'POST' | 'PATCH' | 'DELETE';\n body?: unknown;\n signal?: AbortSignal;\n}\n\nexport async function api<T>(path: string, opts: FetchOptions = {}): Promise<T> {\n const res = await fetch(`${origin}${path}`, {\n method: opts.method ?? 'GET',\n credentials: 'include',\n headers: { 'content-type': 'application/json', accept: 'application/json' },\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\n signal: opts.signal,\n });\n if (!res.ok) {\n let message = `me.ochk.io ${res.status}`;\n try {\n const data = (await res.json()) as { error?: string };\n if (data?.error) message = data.error;\n } catch {\n /* ignore */\n }\n throw new MeClientError(message, res.status);\n }\n return (await res.json()) as T;\n}\n\nexport class MeClientError extends Error {\n public readonly status: number;\n constructor(message: string, status: number) {\n super(message);\n this.name = 'MeClientError';\n this.status = status;\n }\n}\n","import type { Session, SessionPolicy, SignInOptions, TelemetryEvent } from './types';\n\nimport { api } from './transport';\n\nconst DEFAULT_POLICY: SessionPolicy = {\n duration_seconds: 7 * 24 * 60 * 60, // 7 days, standard SaaS shape\n refresh: 'sliding',\n sensitive_actions: 're-auth',\n};\n\nconst telemetrySubscribers = new Set<(e: TelemetryEvent) => void>();\n\n/** Subscribe to non-billable developer telemetry events. Call the returned\n * function to unsubscribe. */\nexport function onTelemetry(listener: (e: TelemetryEvent) => void): () => void {\n telemetrySubscribers.add(listener);\n return () => {\n telemetrySubscribers.delete(listener);\n };\n}\n\nfunction emitTelemetry(code: TelemetryEvent['code'], session_id?: string): void {\n const e: TelemetryEvent = {\n code,\n timestamp: new Date().toISOString(),\n ...(session_id ? { session_id } : {}),\n };\n for (const fn of telemetrySubscribers) {\n try {\n fn(e);\n } catch {\n /* listener errors must not break the session flow */\n }\n }\n}\n\n/**\n * Open a sign-in flow at me.ochk.io. Returns the resulting Session once\n * the user consents (Class C billable event for the integrating site,\n * cashback for the user). Internally this opens the OC consent UI in a\n * popup; v1 implementations may also redirect.\n */\nasync function create(opts: SignInOptions): Promise<Session> {\n const policy: SessionPolicy = { ...DEFAULT_POLICY, ...(opts.sessionPolicy ?? {}) };\n return api<Session>('/api/session/create', {\n method: 'POST',\n body: {\n scope: opts.scope,\n policy,\n return_to: opts.returnTo ?? (typeof window !== 'undefined' ? window.location.href : undefined),\n },\n });\n}\n\n/**\n * Refresh a still-valid session inside its policy window. Free for the\n * integrating site (does NOT instantiate a billable event); emits a\n * `session.token_refresh` telemetry record.\n */\nasync function refresh(sessionId: string): Promise<Session> {\n emitTelemetry('session.token_refresh', sessionId);\n return api<Session>('/api/session/refresh', {\n method: 'POST',\n body: { session_id: sessionId },\n });\n}\n\n/** Invalidate a session. Free, telemetry-only. */\nasync function invalidate(sessionId: string): Promise<void> {\n emitTelemetry('session.intra_signin', sessionId);\n await api<{ ok: true }>('/api/session/invalidate', {\n method: 'POST',\n body: { session_id: sessionId },\n });\n}\n\nexport const session = { create, refresh, invalidate };\n","import * as React from 'react';\n\nimport { session } from './session';\nimport type { Session, SessionPolicy } from './types';\n\nexport interface OcSignInButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onError'> {\n scope: string[];\n sessionPolicy?: Partial<SessionPolicy>;\n returnTo?: string;\n onSignin?: (session: Session) => void;\n /** Called when the sign-in flow fails. Renamed from `onError` to avoid\n * shadowing the native button error handler. */\n onSignInError?: (error: Error) => void;\n /** Custom button text. Defaults to \"sign in with oc\". */\n label?: string;\n}\n\n/**\n * Drop-in Sign-in-with-OC button. Triggers the me.ochk.io consent flow\n * for the requested scope, opens (or refreshes) a session, and calls\n * onSignin(session) on success. Class C billable event for the\n * integrating site; cashback flows to the user.\n *\n * Mounting requires <OcSessionProvider> from @orangecheck/auth-client\n * somewhere up the React tree so the resulting session can be read by\n * useOcSession() across the rest of the app.\n */\nexport function OcSignInButton({\n scope,\n sessionPolicy,\n returnTo,\n onSignin,\n onSignInError,\n label = 'sign in with oc',\n children,\n onClick,\n style,\n ...rest\n}: OcSignInButtonProps) {\n const [pending, setPending] = React.useState(false);\n\n return (\n <button\n type=\"button\"\n onClick={async (event) => {\n onClick?.(event);\n if (event.defaultPrevented) return;\n setPending(true);\n try {\n const result = await session.create({ scope, sessionPolicy, returnTo });\n onSignin?.(result);\n } catch (err) {\n onSignInError?.(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setPending(false);\n }\n }}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 8,\n padding: '10px 16px',\n fontSize: 13,\n fontWeight: 600,\n fontFamily: 'ui-monospace, \"JetBrains Mono\", \"SF Mono\", Menlo, monospace',\n letterSpacing: '0.18em',\n textTransform: 'uppercase',\n background: '#f97316',\n color: '#0b0909',\n border: '1px solid #f97316',\n borderRadius: 4,\n cursor: pending ? 'progress' : 'pointer',\n opacity: pending ? 0.7 : 1,\n ...(style ?? {}),\n }}\n disabled={pending || rest.disabled}\n data-oc-signin\n {...rest}\n >\n {/* compact OC mark */}\n <span\n aria-hidden\n style={{\n display: 'inline-block',\n width: 12,\n height: 12,\n background: '#0b0909',\n }}\n />\n {children ?? (pending ? 'opening…' : label)}\n </button>\n );\n}\n","import type { PaymentAuthorizeOptions, PaymentResult } from './types';\n\nimport { api } from './transport';\n\n/**\n * Authorize a payment through the user's OC identity. Class B billable\n * event for the integrating site (sub-Stripe rate, percentage-based);\n * cashback flows to the user as Lightning credit on /me/earn.\n *\n * The user is prompted by me.ochk.io to consent to the specific payment\n * before this resolves. If the user declines or cancels, the result has\n * status `'cancelled'`, a non-billable telemetry record is emitted, and\n * NO billable event is created.\n */\nasync function authorize(opts: PaymentAuthorizeOptions): Promise<PaymentResult> {\n if (opts.amount_sats == null && opts.usd_cents == null) {\n throw new Error('payment.authorize requires amount_sats or usd_cents');\n }\n return api<PaymentResult>('/api/payment/authorize', {\n method: 'POST',\n body: opts,\n });\n}\n\nexport const payment = { authorize };\n","/**\n * Canonical types for me.ochk.io integrators.\n *\n * Mirrors the source of truth at oc-me-web/src/lib/events/types.ts. Two\n * layers:\n * - Platform-level (PLATFORM_FEE_POLICY, MIN_INTEGRATOR_PRICE_SATS) —\n * fixed by OC, surfaced as constants here so integrators can validate\n * their config client-side before posting it.\n * - Integrator-level (IntegratorPriceConfig) — every integrator declares\n * their own per-event prices and user-share splits.\n *\n * Per Addendum 01: every chargeable event is in exactly one of three\n * classes. Sites pay for sessions and actions, not for clicks. Free\n * events never instantiate a BillableEvent.\n */\n\n// ── platform constants (fixed by OC) ──────────────────────────────────────\n\nexport const PLATFORM_FEE_POLICY = {\n /** Fraction of every gross_fee that OC retains. */\n pct: 0.2,\n /** Absolute minimum platform fee, in sats. */\n min_floor_sats: 1,\n /** Date this policy was last ratified. Changes require an oc-me-protocol PR. */\n ratified: '2026-04-30',\n} as const;\n\n/** Anti-spam price floor. No integrator can configure a per-event price\n * below this. */\nexport const MIN_INTEGRATOR_PRICE_SATS = 5;\n\n// ── event taxonomy ────────────────────────────────────────────────────────\n\nexport type EventClass = 'A' | 'B' | 'C';\n\nexport type ClassASubtype =\n | 'account_creation'\n | 'account_recovery'\n | 'kyc_tier_upgrade'\n | 'payment_method_connected'\n | 'agent_delegation_issued'\n | 'recovery_method_updated';\n\nexport type ClassBSubtype =\n | 'payment_authorization'\n | 'scoped_action_authorization'\n | 'attest_verification_at_gate'\n | 'stamp_signing'\n | 'pledge_resolution';\n\nexport type ClassCSubtype = 'session_creation';\n\nexport type EventSubtype = ClassASubtype | ClassBSubtype | ClassCSubtype;\n\nexport type AttestTier = 'anonymous' | 'bonded' | 'kyc_light' | 'kyc_strong';\n\n/** The shape of a per-event fee — either a fixed sats amount or a percent\n * of the underlying transaction amount (used for payments + pledges). */\nexport type SiteFeeShape =\n | { kind: 'fixed_sats'; sats: number }\n | { kind: 'percent_of_amount'; pct: number };\n\n/** What an integrator declares for a single event subtype. */\nexport interface IntegratorEventConfig {\n /** Whether this site bills this event subtype at all. */\n enabled: boolean;\n /** The per-event fee the site pays. */\n site_pays: SiteFeeShape;\n /** Fraction of post-platform-fee that flows to the user (0–0.8 since\n * platform_fee is 20%). The remainder is a rebate to the site's OC\n * project balance. */\n user_share_pct: number;\n}\n\n/** A complete integrator pricing config. Posted to me.ochk.io once at\n * integration time, mutable via the configurator UI or this SDK any time\n * after. */\nexport interface IntegratorPriceConfig {\n project_key: string;\n display_name: string;\n domain: string;\n /** ISO-8601 timestamp the config was last updated. */\n updated_at: string;\n /** Per-subtype configs. Subtypes not listed are disabled by default. */\n events: Partial<Record<EventSubtype, IntegratorEventConfig>>;\n}\n\n/** A computed fee breakdown for a single event. site_rebate_sats is what\n * flows back to the integrator's OC balance after OC's platform fee and\n * the user's cashback. */\nexport interface ComputedFees {\n gross_fee_sats: number;\n platform_fee_sats: number;\n user_earned_sats: number;\n site_rebate_sats: number;\n}\n\n/** Compute the four-way fee split for an event given an integrator's\n * config and (for percent_of_amount events) the underlying payment\n * amount. Mirrors the canonical computeFees in oc-me-web. */\nexport function computeFees(\n cfg: IntegratorEventConfig,\n payment_amount_sats?: number\n): ComputedFees {\n let gross = 0;\n if (cfg.site_pays.kind === 'fixed_sats') {\n gross = Math.max(MIN_INTEGRATOR_PRICE_SATS, Math.round(cfg.site_pays.sats));\n } else {\n if (payment_amount_sats == null) {\n throw new Error('percent_of_amount config requires payment_amount_sats');\n }\n gross = Math.max(\n MIN_INTEGRATOR_PRICE_SATS,\n Math.round(payment_amount_sats * cfg.site_pays.pct)\n );\n }\n const platform_fee_sats = Math.max(\n PLATFORM_FEE_POLICY.min_floor_sats,\n Math.round(gross * PLATFORM_FEE_POLICY.pct)\n );\n const post_platform = Math.max(0, gross - platform_fee_sats);\n const user_share = Math.min(0.8, Math.max(0, cfg.user_share_pct));\n const user_earned_sats = Math.round(post_platform * (user_share / 0.8));\n const site_rebate_sats = Math.max(0, post_platform - user_earned_sats);\n return { gross_fee_sats: gross, platform_fee_sats, user_earned_sats, site_rebate_sats };\n}\n\n// ── canonical envelope ────────────────────────────────────────────────────\n\nexport interface BillableEvent {\n id: string;\n occurred_at: string;\n class: EventClass;\n subtype: EventSubtype;\n site: { domain: string; display_name: string };\n gross_fee_sats: number;\n platform_fee_sats: number;\n user_earned_sats: number;\n site_rebate_sats: number;\n verify_url: string;\n}\n\n// ── session lifecycle ────────────────────────────────────────────────────\n\nexport interface SessionPolicy {\n duration_seconds: number;\n refresh: 'sliding' | 'rolling' | 'none';\n sensitive_actions?: 're-auth' | 'none';\n}\n\nexport interface Session {\n id: string;\n identity: string;\n opens_at: string;\n expires_at: string;\n policy: SessionPolicy;\n scope: string[];\n}\n\nexport interface SignInOptions {\n scope: string[];\n sessionPolicy?: Partial<SessionPolicy>;\n returnTo?: string;\n}\n\nexport interface PaymentAuthorizeOptions {\n identity: string;\n amount_sats?: number;\n usd_cents?: number;\n description: string;\n external_ref?: string;\n}\n\nexport interface PaymentResult {\n id: string;\n status: 'authorized' | 'failed' | 'cancelled';\n sats_charged?: number;\n user_envelope_id?: string;\n verify_url?: string;\n}\n\nexport interface TelemetryEvent {\n code:\n | 'session.intra_signin'\n | 'session.token_refresh'\n | 'session.navigation'\n | 'auth.signin_failed'\n | 'auth.signin_cancelled'\n | 'auth.signin_rejected'\n | 'verify.passive_check';\n timestamp: string;\n session_id?: string;\n}\n","/**\n * @orangecheck/me-client\n *\n * Drop-in client for me.ochk.io. Exports the canonical billable-event\n * taxonomy as TypeScript types, session lifecycle hooks, payment\n * authorization, the developer telemetry stream, and the React sign-in\n * button.\n *\n * Sign-in-with-OC. You pay for sessions and actions, not for clicks.\n */\n\nexport { OcSignInButton } from './SignInButton';\nexport type { OcSignInButtonProps } from './SignInButton';\n\nexport { session, onTelemetry } from './session';\nexport { payment } from './payment';\nexport { setOrigin, getOrigin, MeClientError } from './transport';\n\nexport {\n PLATFORM_FEE_POLICY,\n MIN_INTEGRATOR_PRICE_SATS,\n computeFees,\n} from './types';\n\nexport type {\n EventClass,\n EventSubtype,\n ClassASubtype,\n ClassBSubtype,\n ClassCSubtype,\n AttestTier,\n SiteFeeShape,\n IntegratorEventConfig,\n IntegratorPriceConfig,\n ComputedFees,\n BillableEvent,\n Session,\n SessionPolicy,\n SignInOptions,\n PaymentAuthorizeOptions,\n PaymentResult,\n TelemetryEvent,\n} from './types';\n\nimport { session } from './session';\nimport { payment } from './payment';\n\n/** Convenience namespace mirroring the public API surface in /integrate\n * code samples — `oc.session.create()`, `oc.payment.authorize()`. */\nexport const oc = { session, payment };\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orangecheck/me-client",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Drop-in client for me.ochk.io. Sign-in-with-OC button, session lifecycle hooks (oc.session.create / refresh / invalidate), payment authorization, and the canonical billable-event taxonomy as types.",
5
5
  "keywords": [
6
6
  "orangecheck",