live · mainnetme · ochk · io
federation-custodied · self-custody-ready
§ integrate

You set every price. We just operate the substrate.

Three lines of HTML, an SDK, a session policy, and an IntegratorPriceConfig with your per-event prices and user-share splits. OC retains 20% of every gross_fee — the rest is yours and your users'.

§ you choose the cost

every per-event price is set by you, per subtype. enable what fits your product. price each event to your economics. min floor: 5 sats.

§ flat platform fee

OC keeps 20% of gross. fixed, published, ratified per /charter. funds custody, signing, anchor pipeline, abuse review.

§ you split the rest

of the post-platform 80%, you choose how much flows to users vs. your rebate balance. 0% to user means you keep the cashback as your own rebate; 100% means users get every cent.

§ your users don't need to know about bitcoin

drop OC in alongside google, apple, magic-link. it's an OAuth peer.

Sign-in-with-OC is a peer drop-in next to your existing OAuth providers. A first-time user picking OC has a federation-custodied bitcoin wallet provisioned silently by the guardian set — no seed phrase, no key handling, no "what is a sat" conversation. They get an oc_session cookie and bounce back to your site signed in. Every billable event you emit credits sats to their balance. They never need to know any of that happened — until they choose to graduate to self-custody on /me/graduate.

// next.js · OC button alongside google + apple + magic-link
import { OcSignInButton } from '@orangecheck/me-client';
import { signIn } from 'next-auth/react';

export function SignInOptions() {
  return (
    <div className="auth-options">
      <button onClick={() => signIn('google')}>continue with google</button>
      <button onClick={() => signIn('apple')}>continue with apple</button>
      <button onClick={() => signIn('email')}>email magic link</button>

      {/* OC drop-in. zero crypto knowledge required. */}
      <OcSignInButton
        scope={['identity']}
        sessionPolicy={{ duration: '30d', refresh: 'sliding' }}
      >
        sign in with oc · earn sats
      </OcSignInButton>
    </div>
  );
}

// what happens when a first-time user picks OC:
//   1. redirect to me.ochk.io/signin
//   2. federation guardians provision a custodied bitcoin wallet (M-of-N
//      threshold, no seed phrase shown, no key handling for the user)
//   3. an oc_session cookie is set with Domain=.ochk.io
//   4. user is bounced back to your site, signed in
//   5. every event you bill (sessions, payments, etc.) credits sats to
//      their balance. they don't need to know any of this happened —
//      until they choose to graduate to self-custody.
§ what your user sees
  • > a button next to google/apple
  • > one redirect to me.ochk.io
  • > signed in on your site
  • > (eventually) a growing sat balance they didn't ask for
§ what your user does NOT see
  • > a seed phrase
  • > a wallet creation flow
  • > a "buy bitcoin" CTA
  • > any crypto vocabulary at all
§ when do they find out?

When they want to. /me on me.ochk.io shows their balance, /me/wallet shows receive/send/withdraw, /me/graduate offers self-custody. None of this is in the OAuth path. None of it surfaces unless the user explicitly visits.

§ drop-in · standalone

three lines, two languages.

The OAuth-peer pattern above is the most common shape. If you want OC as the primary or only sign-in option (e.g. you're building a Lightning-native product), the same SDK works as a standalone:

§ html
<!-- drop-in sign-in button -->
<script src="https://me.ochk.io/sdk.js" async></script>
<button data-oc-signin
        data-scope="identity,attest_tier"
        data-session-policy="7d"
        data-on-signin="window.handleOcSignin">
  sign in with oc
</button>
§ react
import { OcSignInButton, useOcSession } from '@orangecheck/me-client';

export function SignIn() {
  const { account, status } = useOcSession();

  if (status === 'authenticated') {
    return <p>signed in as {account.address.slice(0, 8)}…</p>;
  }

  return (
    <OcSignInButton
      scope={['identity', 'attest_tier']}
      sessionPolicy={{ duration: '7d', refresh: 'rolling' }}
      onSignin={(envelope) => console.log('class C envelope:', envelope)}
    />
  );
}
§ full SDK reference

Every export from @orangecheck/me-client v0.4.0 — provider, hooks, oc.session, oc.payment, oc.config, oc.webhook, oc.delegation — with type signatures and code samples is at /sdk.

§ configure your prices

every per-event price is yours. the configurator is interactive.

Adjust the sliders below to see the four-way fee split (gross · OC platform fee · user cashback · your rebate) update live. The full configurator covers every event subtype; this demo shows three of twelve so the math stays legible. Both denominations at parity on every line.

// IntegratorPriceConfig — what every integrator declares.
// Posted to me.ochk.io once at integration time, mutable via the
// configurator UI or the SDK any time after.

import type { IntegratorPriceConfig } from '@orangecheck/me-client';

export const config: IntegratorPriceConfig = {
  project_key: 'pk_live_yourcompany',
  display_name: 'YourCompany',
  domain: 'yourcompany.example',
  updated_at: new Date().toISOString(),

  events: {
    // Class A — durable state transitions
    account_creation: {
      enabled: true,
      site_pays: { kind: 'fixed_sats', sats: 1300 },  // ~$1.24
      user_share_pct: 0.65,                           // 65% to user
    },

    // Class B — action-bound
    payment_authorization: {
      enabled: true,
      site_pays: { kind: 'percent_of_amount', pct: 0.0075 }, // 0.75%
      user_share_pct: 0.65,
    },

    // Class C — sessions
    session_creation: {
      enabled: true,
      site_pays: { kind: 'fixed_sats', sats: 55 },    // ~$0.05
      user_share_pct: 0.65,
    },

    // every other subtype defaults to enabled: false until you flip it on.
  },
};
§ price configurator · live

adjust prices. watch the math.

demo · 3 of 12 subtypes
account creation
site pays · sats
1,300 sats · $1.23
user share · % of post-platform
65% to user · max 80%
gross · site pays+1,300 sats$1.23
oc platform fee · 20%+260 sats$0.25
user earns+845 sats$0.80
site rebate+195 sats$0.19
session opened
site pays · sats
55 sats · $0.05
user share · % of post-platform
65% to user · max 80%
gross · site pays+55 sats$0.05
oc platform fee · 20%+11 sats$0.01
user earns+36 sats$0.03
site rebate+8 sats< $0.01
payment authorized
site pays · % of amount
0.75% of payment amount
user share · % of post-platform
65% to user · max 80%
on a 240,000 sat ($228) example payment:
gross · site pays+1,800 sats$1.71
oc platform fee · 20%+360 sats$0.34
user earns+1,170 sats$1.11
site rebate+270 sats$0.26
§ platform fee · fixed
oc retains 20% of every gross_fee.ratified 2026-04-30
§ try the full simulator

The configurator above lets you see the four-way split per event. The sandbox runs your config against a representative one-month event mix at three traffic tiers (1k / 10k / 100k MAU) and shows the resolved monthly aggregate vs. the legacy Auth0 + Stripe + Twilio + KYC stack.

§ what other integrators picked

five real archetypes. all on the same substrate.

Different unit economics produce different choices. A high-trust merchant SaaS prices account creation an order of magnitude higher than a community federation. A cashback-heavy fintech routes 78% of payment fees back to users; a Lightning-native social app routes only 50%. Both are correct for their model.

Breez

breez.example
  • account creation2,100 sats($1.99) · 70%
  • session opened80 sats($0.08) · 70%
  • payment authorized0.50% of amount · 75%
  • payment method connected420 sats($0.40) · 70%

Fold

fold.example
  • account creation1,600 sats($1.52) · 60%
  • session opened60 sats($0.06) · 65%
  • payment authorized0.95% of amount · 78%

Damus

damus.example
  • session opened40 sats($0.04) · 50%
  • stamp signed30 sats($0.03) · 65%
  • scoped action authorized80 sats($0.08) · 50%

Zaprite

zaprite.example
  • account creation5,300 sats($5.04) · 55%
  • kyc tier upgrade4,200 sats($3.99) · 35%
  • attest verification530 sats($0.50) · 65%
  • session opened75 sats($0.07) · 60%
  • payment authorized0.85% of amount · 65%
  • agent delegation issued480 sats($0.46) · 65%

Fedi

fedi.example
  • account creation850 sats($0.81) · 78%
  • session opened50 sats($0.05) · 78%
  • agent delegation issued200 sats($0.19) · 78%
§ suggested defaults

what the configurator pre-fills.

These are starting points. Override every value. Mirror table at /pricing surfaces the same data for users.

eventdefault · satsdefault · usdenabled?user share
account creation
1,300 sats$1.23 / event✓ on65%
account recovery
650 sats$0.62 / event✓ on65%
kyc tier upgrade
3,200 sats$3.04 / event◌ off40%
payment method connected
320 sats$0.30 / event✓ on65%
agent delegation issued
320 sats$0.30 / event◌ off65%
recovery method updated
160 sats$0.15 / event✓ on65%
payment authorized
0.75% of amount✓ on65%
scoped action authorized
100 sats$0.10 / event✓ on65%
attest verification
280 sats$0.27 / event◌ off65%
stamp signed
55 sats$0.05 / event◌ off65%
pledge resolved
1.00% of amount◌ off65%
session opened
55 sats$0.05 / event✓ on65%
§ session lifecycle

sessions are the billable atom. you choose the policy.

The SDK exposes oc.session.create(), oc.session.refresh(), oc.session.invalidate(). Declare the policy at integration time; the OC verifier enforces it client-side and server-side. You can't over-bill yourself; users can't game sessions by manipulating the client.

// session lifecycle hooks — explicit, server-enforced
import { oc } from '@orangecheck/me-client';

// open a session (Class C billable event — once per real session)
const session = await oc.session.create({
  identity: 'bc1q...e3lr',
  scope: ['identity', 'payment'],
  policy: {
    duration_seconds: 60 * 15,    // 15 minutes — banking-shaped
    refresh: 'sliding',
    sensitive_actions: 're-auth',
  },
});

// refresh inside the session — FREE, telemetry only
await oc.session.refresh(session.id);

// invalidate when the user signs out — FREE
await oc.session.invalidate(session.id);
§ typical session policies
banking-shaped
15–60 minute sessions
billable: every session
when: high-value transactions, regulated workflows, admin panels
standard saas
7–30 day sessions, sliding refresh
billable: session creation only
when: consumer SaaS, marketplaces, content platforms
mobile app
90-day session with refresh
billable: initial creation, sensitive-action re-auths
when: long-running mobile clients with periodic biometric re-auth
§ what you do not pay for

these events are free. visible. never billed.

The SDK emits these as developer telemetry so you have full observability of what your users are doing. Explicitly not billable. Transparency is the trust model.

event codewhat it representsbilled?
session.intra_signinUser pressed sign-in while a valid session was already open.no
session.token_refreshSession token rotated within the active window.no
session.navigationUser moved between pages of the integrating site.no
auth.signin_failedUser attempted to sign in but the attempt failed.no
auth.signin_cancelledUser cancelled the sign-in mid-flow.no
auth.signin_rejectedSite rejected the sign-in (wrong scope, blocked region, policy).no
verify.passive_checkSite verified a still-valid envelope without requiring re-auth.no
§ payments

payment authorization — Class B, percentage you choose.

// payment authorization — Class B billable event
const payment = await oc.payment.authorize({
  identity: session.identity,
  amount_sats: 240_000,
  description: 'breez · march invoice',
});
// site pays the configured % of the payment as the OC fee.
// 20% of that goes to OC; the rest splits per your user_share_pct config
// between the user (cashback on /me/earn) and your site rebate balance.

test mode and ramp

Sign up your site, get a project key, post your first IntegratorPriceConfig. The first 1,000 sessions are free — fully functional, just not invoiced. After that, you flip a switch and start paying. Lightning or Stripe at parity, monthly invoice in either denomination.

For the cross-product flow (a me.ochk.io user authorizing an AI agent inside a console.ochk.io-managed enterprise), see console.ochk.io/integrations. Same envelope substrate, two integration surfaces.