docs / @orangecheck/react

@orangecheck/react

Three focused React components. Zero styling framework required — inline styles so they render correctly in any host app.

yarn add @orangecheck/react

React 18 or 19. @orangecheck/sdk is a peer dependency (pulled in automatically).

<OcBadge>

Render a proof using data from check() or verify():

import { OcBadge } from '@orangecheck/react';
import { check } from '@orangecheck/sdk';

const r = await check({ addr });
return (
  <OcBadge
    address={r.address!}
    sats={r.sats}
    days={r.days}
    score={r.score}
    variant="card"   // or "compact" (default)
    theme="dark"     // or "light" (default)
  />
);
PropTypeDefault
addressstring
satsnumber
daysnumber
scorenumbercomputed if omitted
algorithm'v0' | 'tier' | 'none''v0'
variant'compact' | 'card''compact'
theme'light' | 'dark''light'
hideScorebooleanfalse

<OcGate>

Client-side conditional render based on OrangeCheck status.

<OcGate
  address={userBtcAddress}
  minSats={100_000}
  minDays={30}
  loading={<Spinner />}
  fallback={<Callout>You need at least 100k sats bonded for 30 days.</Callout>}
>
  <CommentForm />
</OcGate>

Render-prop form:

<OcGate address={addr} minSats={100_000}>
  {(result) => <p>You have {result.sats.toLocaleString()} sats bonded.</p>}
</OcGate>

<OcChallengeButton>

End-to-end signed-challenge flow in one button. Issues the challenge, calls your wallet adapter, verifies, and fires onVerified with the proven address.

import { OcChallengeButton } from '@orangecheck/react';

<OcChallengeButton
  address={userAddr}
  sign={(msg) => window.unisat.signMessage(msg, 'bip322-simple')}
  audience="https://example.com"
  purpose="login"
  onVerified={({ address, nonce }) => {
    // address is cryptographically proven — attach to session
    console.log('verified:', address);
  }}
  onError={(e) => console.error(e)}
>
  Sign in with Bitcoin
</OcChallengeButton>

The sign prop takes any adapter — UniSat, Xverse, Leather, Alby, paste-from-Sparrow. For auto-detection of all four browser wallets in one component, use @orangecheck/wallet-adapter's <OcWalletButton>.

Adapter examples:

// UniSat
(msg) => (window as any).unisat.signMessage(msg, 'bip322-simple')

// Xverse
async (msg) => {
  const r = await signMessage({
    payload: { network: { type: 'Mainnet' }, address: userAddr, message: msg }
  });
  return r.signature;
}

// Alby / WebLN
(msg) => (window as any).webln.signMessage(msg)

// Hardware — pop a dialog, user pastes a signature
async (msg) => {
  const sig = prompt(`Sign this in your wallet:\n\n${msg}`);
  if (!sig) throw new Error('cancelled');
  return sig;
}

Subpath imports

import { OcBadge }             from '@orangecheck/react/badge';
import { OcGate }              from '@orangecheck/react/gate';
import { OcChallengeButton }   from '@orangecheck/react/challenge';

License

MIT.