@orangecheck/auth-client 2.29.0 → 2.30.1

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
@@ -166,6 +166,30 @@ interface OcLinkedIdentitiesProps {
166
166
  }
167
167
  declare function OcLinkedIdentities({ authOrigin, className, onChange, attestationLink, }: OcLinkedIdentitiesProps): React.ReactElement;
168
168
 
169
+ interface Floors {
170
+ sats_floor: number;
171
+ days_floor: number;
172
+ }
173
+ interface OcBondView extends Floors {
174
+ address: string;
175
+ outpoint: string;
176
+ sats: number;
177
+ confirmed_height: number;
178
+ checked_at: string;
179
+ checked_height: number;
180
+ created_at: string;
181
+ }
182
+ interface OcBondProps {
183
+ authOrigin?: string;
184
+ onChange?: (bond: OcBondView | null) => void;
185
+ className?: string;
186
+ }
187
+ declare function bondFloorsText(f: Floors): string;
188
+ declare function fetchOcBond(opts?: {
189
+ authOrigin?: string;
190
+ }): Promise<OcBondView | null>;
191
+ declare function OcBond({ authOrigin, onChange, className, }: OcBondProps): React.ReactElement;
192
+
169
193
  declare const TAB_SESSION_HEADER = "x-oc-tab-session";
170
194
  declare const TAB_SESSION_STORAGE_KEY = "oc_tab_session";
171
195
  declare const TAB_ACCOUNT_HINT_KEY = "oc-as";
@@ -269,4 +293,4 @@ declare function isSudoAccountMismatch(body: {
269
293
  reason?: string;
270
294
  } | null | undefined): boolean;
271
295
 
272
- export { DEFAULT_CONFIG, DISPLAY_IDENTITY_KINDS, type DisplayIdentity, type DisplayIdentityKind, type OcAccount, OcAccountChip, type OcAccountChipProps, OcAccountPill, type OcAccountPillProps, type OcAccountSummary, OcAddressInput, type OcAddressInputProps, type OcAuthConfig, OcLinkedIdentities, type OcLinkedIdentitiesProps, type OcLinkedIdentity, OcSessionProvider, type OcSessionState, type OcSessionStatus, OcSignIn, OcSignInButton, type OcSignInButtonProps, type OcSignInProps, type OcSignOutScope, type OcTabSession, type RedirectToSudoArgs, SUDO_ACCOUNT_MISMATCH_MESSAGE, TAB_ACCOUNT_HINT_KEY, TAB_ADOPT_HASH, TAB_SESSION_HEADER, TAB_SESSION_STORAGE_KEY, type UseOcAddressSuggestionOptions, type UseOcAddressSuggestionReturn, type UseStepUpAuthReturn, type UseWebAuthnListReturn, type UseWebAuthnRegisterReturn, type WebAuthnAssertionStatus, type WebAuthnCredentialPublic, type WebAuthnListStatus, type WebAuthnRegisterResult, type WebAuthnRegisterStatus, type WebAuthnRemoveResult, type WebAuthnRenameResult, type WebAuthnStepUpResult, buildAddAccountUrl, buildSignInUrl, clearTabSession, consumeTabAccountHint, consumeTabAdoptMarker, familyReturnTarget, fetchOcLinkedIdentities, handleSudoRequired, installTabFetchInterceptor, installTabLinkDecorator, isSudoAccountMismatch, readTabSession, redirectToSudo, safeReturnTo, tabSessionHeader, useOcAddressSuggestion, useOcSession, useOptionalOcSession, useStepUpAuth, useWebAuthnList, useWebAuthnRegister, writeTabSession };
296
+ export { DEFAULT_CONFIG, DISPLAY_IDENTITY_KINDS, type DisplayIdentity, type DisplayIdentityKind, type OcAccount, OcAccountChip, type OcAccountChipProps, OcAccountPill, type OcAccountPillProps, type OcAccountSummary, OcAddressInput, type OcAddressInputProps, type OcAuthConfig, OcBond, type OcBondProps, type OcBondView, OcLinkedIdentities, type OcLinkedIdentitiesProps, type OcLinkedIdentity, OcSessionProvider, type OcSessionState, type OcSessionStatus, OcSignIn, OcSignInButton, type OcSignInButtonProps, type OcSignInProps, type OcSignOutScope, type OcTabSession, type RedirectToSudoArgs, SUDO_ACCOUNT_MISMATCH_MESSAGE, TAB_ACCOUNT_HINT_KEY, TAB_ADOPT_HASH, TAB_SESSION_HEADER, TAB_SESSION_STORAGE_KEY, type UseOcAddressSuggestionOptions, type UseOcAddressSuggestionReturn, type UseStepUpAuthReturn, type UseWebAuthnListReturn, type UseWebAuthnRegisterReturn, type WebAuthnAssertionStatus, type WebAuthnCredentialPublic, type WebAuthnListStatus, type WebAuthnRegisterResult, type WebAuthnRegisterStatus, type WebAuthnRemoveResult, type WebAuthnRenameResult, type WebAuthnStepUpResult, bondFloorsText, buildAddAccountUrl, buildSignInUrl, clearTabSession, consumeTabAccountHint, consumeTabAdoptMarker, familyReturnTarget, fetchOcBond, fetchOcLinkedIdentities, handleSudoRequired, installTabFetchInterceptor, installTabLinkDecorator, isSudoAccountMismatch, readTabSession, redirectToSudo, safeReturnTo, tabSessionHeader, useOcAddressSuggestion, useOcSession, useOptionalOcSession, useStepUpAuth, useWebAuthnList, useWebAuthnRegister, writeTabSession };
package/dist/index.d.ts CHANGED
@@ -166,6 +166,30 @@ interface OcLinkedIdentitiesProps {
166
166
  }
167
167
  declare function OcLinkedIdentities({ authOrigin, className, onChange, attestationLink, }: OcLinkedIdentitiesProps): React.ReactElement;
168
168
 
169
+ interface Floors {
170
+ sats_floor: number;
171
+ days_floor: number;
172
+ }
173
+ interface OcBondView extends Floors {
174
+ address: string;
175
+ outpoint: string;
176
+ sats: number;
177
+ confirmed_height: number;
178
+ checked_at: string;
179
+ checked_height: number;
180
+ created_at: string;
181
+ }
182
+ interface OcBondProps {
183
+ authOrigin?: string;
184
+ onChange?: (bond: OcBondView | null) => void;
185
+ className?: string;
186
+ }
187
+ declare function bondFloorsText(f: Floors): string;
188
+ declare function fetchOcBond(opts?: {
189
+ authOrigin?: string;
190
+ }): Promise<OcBondView | null>;
191
+ declare function OcBond({ authOrigin, onChange, className, }: OcBondProps): React.ReactElement;
192
+
169
193
  declare const TAB_SESSION_HEADER = "x-oc-tab-session";
170
194
  declare const TAB_SESSION_STORAGE_KEY = "oc_tab_session";
171
195
  declare const TAB_ACCOUNT_HINT_KEY = "oc-as";
@@ -269,4 +293,4 @@ declare function isSudoAccountMismatch(body: {
269
293
  reason?: string;
270
294
  } | null | undefined): boolean;
271
295
 
272
- export { DEFAULT_CONFIG, DISPLAY_IDENTITY_KINDS, type DisplayIdentity, type DisplayIdentityKind, type OcAccount, OcAccountChip, type OcAccountChipProps, OcAccountPill, type OcAccountPillProps, type OcAccountSummary, OcAddressInput, type OcAddressInputProps, type OcAuthConfig, OcLinkedIdentities, type OcLinkedIdentitiesProps, type OcLinkedIdentity, OcSessionProvider, type OcSessionState, type OcSessionStatus, OcSignIn, OcSignInButton, type OcSignInButtonProps, type OcSignInProps, type OcSignOutScope, type OcTabSession, type RedirectToSudoArgs, SUDO_ACCOUNT_MISMATCH_MESSAGE, TAB_ACCOUNT_HINT_KEY, TAB_ADOPT_HASH, TAB_SESSION_HEADER, TAB_SESSION_STORAGE_KEY, type UseOcAddressSuggestionOptions, type UseOcAddressSuggestionReturn, type UseStepUpAuthReturn, type UseWebAuthnListReturn, type UseWebAuthnRegisterReturn, type WebAuthnAssertionStatus, type WebAuthnCredentialPublic, type WebAuthnListStatus, type WebAuthnRegisterResult, type WebAuthnRegisterStatus, type WebAuthnRemoveResult, type WebAuthnRenameResult, type WebAuthnStepUpResult, buildAddAccountUrl, buildSignInUrl, clearTabSession, consumeTabAccountHint, consumeTabAdoptMarker, familyReturnTarget, fetchOcLinkedIdentities, handleSudoRequired, installTabFetchInterceptor, installTabLinkDecorator, isSudoAccountMismatch, readTabSession, redirectToSudo, safeReturnTo, tabSessionHeader, useOcAddressSuggestion, useOcSession, useOptionalOcSession, useStepUpAuth, useWebAuthnList, useWebAuthnRegister, writeTabSession };
296
+ export { DEFAULT_CONFIG, DISPLAY_IDENTITY_KINDS, type DisplayIdentity, type DisplayIdentityKind, type OcAccount, OcAccountChip, type OcAccountChipProps, OcAccountPill, type OcAccountPillProps, type OcAccountSummary, OcAddressInput, type OcAddressInputProps, type OcAuthConfig, OcBond, type OcBondProps, type OcBondView, OcLinkedIdentities, type OcLinkedIdentitiesProps, type OcLinkedIdentity, OcSessionProvider, type OcSessionState, type OcSessionStatus, OcSignIn, OcSignInButton, type OcSignInButtonProps, type OcSignInProps, type OcSignOutScope, type OcTabSession, type RedirectToSudoArgs, SUDO_ACCOUNT_MISMATCH_MESSAGE, TAB_ACCOUNT_HINT_KEY, TAB_ADOPT_HASH, TAB_SESSION_HEADER, TAB_SESSION_STORAGE_KEY, type UseOcAddressSuggestionOptions, type UseOcAddressSuggestionReturn, type UseStepUpAuthReturn, type UseWebAuthnListReturn, type UseWebAuthnRegisterReturn, type WebAuthnAssertionStatus, type WebAuthnCredentialPublic, type WebAuthnListStatus, type WebAuthnRegisterResult, type WebAuthnRegisterStatus, type WebAuthnRemoveResult, type WebAuthnRenameResult, type WebAuthnStepUpResult, bondFloorsText, buildAddAccountUrl, buildSignInUrl, clearTabSession, consumeTabAccountHint, consumeTabAdoptMarker, familyReturnTarget, fetchOcBond, fetchOcLinkedIdentities, handleSudoRequired, installTabFetchInterceptor, installTabLinkDecorator, isSudoAccountMismatch, readTabSession, redirectToSudo, safeReturnTo, tabSessionHeader, useOcAddressSuggestion, useOcSession, useOptionalOcSession, useStepUpAuth, useWebAuthnList, useWebAuthnRegister, writeTabSession };
package/dist/index.js CHANGED
@@ -3207,6 +3207,297 @@ function Hint({ children }) {
3207
3207
  }
3208
3208
  );
3209
3209
  }
3210
+ var DEFAULT_AUTH_ORIGIN2 = "https://ochk.io";
3211
+ var MIN_CONFIRMATIONS = 6;
3212
+ var n = (v) => v.toLocaleString("en-US");
3213
+ function bondFloorsText(f) {
3214
+ const sats = f.sats_floor > 0 ? `at least ${n(f.sats_floor)} sats` : "under 1,000 sats";
3215
+ const days = f.days_floor > 0 ? `held ${f.days_floor} days or more` : "held under 7 days";
3216
+ return `${sats}, ${days}`;
3217
+ }
3218
+ var short = (outpoint) => {
3219
+ const [txid = "", vout = ""] = outpoint.split(":");
3220
+ return `${txid.slice(0, 8)}\u2026${txid.slice(-4)}:${vout}`;
3221
+ };
3222
+ var REFUSAL = {
3223
+ invalid_address: "that isn't a Bitcoin address we can read",
3224
+ chain_unavailable: "couldn't read the chain just now \xB7 nothing changed, try again in a minute",
3225
+ sig_invalid: "that signature isn't from this coin's address \xB7 sign with the wallet that holds it",
3226
+ bond_expired: "the message expired \xB7 start again",
3227
+ bond_not_yet_valid: "your device's clock looks wrong",
3228
+ bond_subject_mismatch: "that message was for another account \xB7 start again",
3229
+ bond_malformed: "the signed message changed on the way \xB7 start again",
3230
+ coin_not_found: "that coin doesn't exist on-chain",
3231
+ coin_address_mismatch: "that coin isn't at this address",
3232
+ coin_unconfirmed: "that coin isn't confirmed yet",
3233
+ coin_too_recent: "that coin needs six confirmations first, about an hour",
3234
+ coin_spent: "that coin has been spent \xB7 pick one still in your wallet",
3235
+ coin_backs_another_account: "that coin already backs another orangecheck account",
3236
+ not_authenticated: "your session ended \xB7 sign in again"
3237
+ };
3238
+ var refusal = (reason) => reason && REFUSAL[reason] || "your backing didn't save \xB7 nothing changed, try again";
3239
+ async function fetchOcBond(opts) {
3240
+ const r = await fetch(`${opts?.authOrigin ?? DEFAULT_AUTH_ORIGIN2}/api/auth/bond`, {
3241
+ credentials: "include"
3242
+ });
3243
+ const j = await r.json().catch(() => ({}));
3244
+ if (!r.ok || !j.ok) throw new Error(`http_${r.status}`);
3245
+ return j.bond ?? null;
3246
+ }
3247
+ function OcBond({
3248
+ authOrigin = DEFAULT_AUTH_ORIGIN2,
3249
+ onChange,
3250
+ className
3251
+ }) {
3252
+ const [bond, setBond] = React4__namespace.useState(void 0);
3253
+ const [loadErr, setLoadErr] = React4__namespace.useState(false);
3254
+ const [nonce, setNonce] = React4__namespace.useState(0);
3255
+ const [adding, setAdding] = React4__namespace.useState(false);
3256
+ const [busy, setBusy] = React4__namespace.useState(false);
3257
+ const [err, setErr] = React4__namespace.useState(null);
3258
+ React4__namespace.useEffect(() => {
3259
+ let alive = true;
3260
+ fetchOcBond({ authOrigin }).then(
3261
+ (b) => alive && setBond(b),
3262
+ () => alive && setLoadErr(true)
3263
+ );
3264
+ return () => {
3265
+ alive = false;
3266
+ };
3267
+ }, [authOrigin, nonce]);
3268
+ const call = React4__namespace.useCallback(
3269
+ async (method, body) => {
3270
+ const r = await fetch(`${authOrigin}/api/auth/bond`, {
3271
+ method,
3272
+ credentials: "include",
3273
+ headers: body ? { "Content-Type": "application/json" } : void 0,
3274
+ body: body ? JSON.stringify(body) : void 0
3275
+ });
3276
+ const j = await r.json().catch(() => ({}));
3277
+ return { ok: r.ok && j.ok === true, ...j };
3278
+ },
3279
+ [authOrigin]
3280
+ );
3281
+ async function release() {
3282
+ setBusy(true);
3283
+ setErr(null);
3284
+ const j = await call("DELETE").catch(() => ({ ok: false, reason: "network" }));
3285
+ setBusy(false);
3286
+ if (!j.ok) return setErr(refusal(j.reason));
3287
+ setBond(null);
3288
+ onChange?.(null);
3289
+ }
3290
+ if (loadErr) {
3291
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, "data-oc-bond": "", style: panelStyle("warn"), role: "alert", children: [
3292
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: bodyStyle, children: "couldn't read your backing \xB7 nothing was changed" }),
3293
+ /* @__PURE__ */ jsxRuntime.jsx(
3294
+ "button",
3295
+ {
3296
+ type: "button",
3297
+ style: ghostBtnStyle(false),
3298
+ onClick: () => {
3299
+ setLoadErr(false);
3300
+ setNonce((x) => x + 1);
3301
+ },
3302
+ children: "try again"
3303
+ }
3304
+ )
3305
+ ] });
3306
+ }
3307
+ if (bond === void 0) {
3308
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, "data-oc-bond": "", style: panelStyle(), children: /* @__PURE__ */ jsxRuntime.jsxs("span", { style: hintStyle, children: [
3309
+ "> ",
3310
+ "reading your backing\u2026"
3311
+ ] }) });
3312
+ }
3313
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, "data-oc-bond": "", style: { display: "grid", gap: 16 }, children: [
3314
+ bond && !adding ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: panelStyle("success"), children: [
3315
+ /* @__PURE__ */ jsxRuntime.jsx(SectionLabel, { tone: "success", children: "\xA7 backed by bitcoin" }),
3316
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { style: { ...bodyStyle, color: V.foreground }, children: [
3317
+ "apps see a coin ",
3318
+ bondFloorsText(bond),
3319
+ "."
3320
+ ] }),
3321
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { style: bodyStyle, children: [
3322
+ "coin ",
3323
+ short(bond.outpoint),
3324
+ ", ",
3325
+ n(bond.sats),
3326
+ " sats \xB7 last found unspent at block ",
3327
+ n(bond.checked_height),
3328
+ " \xB7 only you and orangecheck see this line"
3329
+ ] }),
3330
+ /* @__PURE__ */ jsxRuntime.jsxs(FormButtons, { children: [
3331
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: ghostBtnStyle(busy), disabled: busy, onClick: () => setAdding(true), children: "use another coin" }),
3332
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: dangerBtnStyle(busy), disabled: busy, onClick: () => void release(), children: "stop backing" })
3333
+ ] }),
3334
+ err ? /* @__PURE__ */ jsxRuntime.jsx(ErrorLine, { children: err }) : null
3335
+ ] }) : null,
3336
+ !bond && !adding ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: panelStyle(), children: [
3337
+ /* @__PURE__ */ jsxRuntime.jsx(SectionLabel, { children: "\xA7 not backed" }),
3338
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: bodyStyle, children: "your account works everywhere as it is. apps that want to keep out bots can ask for a backed account: one coin you hold, that never moves and that they never see." }),
3339
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: primaryBtnStyle(false), onClick: () => setAdding(true), children: "back it with a coin" })
3340
+ ] }) : null,
3341
+ adding ? /* @__PURE__ */ jsxRuntime.jsx(
3342
+ BondForm,
3343
+ {
3344
+ call,
3345
+ onCancel: () => setAdding(false),
3346
+ onDone: (b) => {
3347
+ setBond(b);
3348
+ setAdding(false);
3349
+ onChange?.(b);
3350
+ }
3351
+ }
3352
+ ) : null,
3353
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { style: hintStyle, children: [
3354
+ "> ",
3355
+ "apps see that a coin backs you, in rough steps, and a number unique to each app, so they can't compare notes. an app can block that number; getting past it means moving the coin, and a moved coin starts its age again."
3356
+ ] })
3357
+ ] });
3358
+ }
3359
+ function BondForm({
3360
+ call,
3361
+ onCancel,
3362
+ onDone
3363
+ }) {
3364
+ const [address, setAddress] = React4__namespace.useState("");
3365
+ const [coins, setCoins] = React4__namespace.useState(null);
3366
+ const [chosen, setChosen] = React4__namespace.useState("");
3367
+ const [message, setMessage] = React4__namespace.useState(null);
3368
+ const [busy, setBusy] = React4__namespace.useState(false);
3369
+ const [err, setErr] = React4__namespace.useState(null);
3370
+ async function run(fn) {
3371
+ setBusy(true);
3372
+ setErr(null);
3373
+ try {
3374
+ await fn();
3375
+ } catch {
3376
+ setErr(refusal("chain_unavailable"));
3377
+ } finally {
3378
+ setBusy(false);
3379
+ }
3380
+ }
3381
+ const findCoins = () => run(async () => {
3382
+ const j = await call("POST", { action: "coins", address: address.trim() });
3383
+ if (!j.ok) return setErr(refusal(j.reason));
3384
+ const list = j.coins ?? [];
3385
+ setCoins(list);
3386
+ setChosen(list.find((c) => c.age_blocks >= MIN_CONFIRMATIONS)?.outpoint ?? "");
3387
+ });
3388
+ const getMessage = () => run(async () => {
3389
+ const j = await call("POST", { action: "message", address: address.trim(), outpoint: chosen });
3390
+ if (!j.ok || typeof j.message !== "string") return setErr(refusal(j.reason));
3391
+ setMessage(j.message);
3392
+ });
3393
+ const submit = (signature) => run(async () => {
3394
+ const j = await call("POST", { action: "bond", message, signature });
3395
+ if (!j.ok || !j.bond) return setErr(refusal(j.reason));
3396
+ onDone(j.bond);
3397
+ });
3398
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: panelStyle("accent"), "data-oc-bond-form": "", children: [
3399
+ /* @__PURE__ */ jsxRuntime.jsx(SectionLabel, { children: "\xA7 back your account with a coin" }),
3400
+ message ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3401
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { style: bodyStyle, children: [
3402
+ "sign with the wallet that holds",
3403
+ " ",
3404
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { wordBreak: "break-all", color: V.foreground }, children: address.trim() }),
3405
+ ". the coin doesn't move and nothing is spent."
3406
+ ] }),
3407
+ /* @__PURE__ */ jsxRuntime.jsx(
3408
+ LazyWalletButton,
3409
+ {
3410
+ address: address.trim(),
3411
+ message,
3412
+ showManual: true,
3413
+ onSigned: (sig) => void submit(sig),
3414
+ onError: (e) => setErr(e.message ?? "the wallet refused to sign")
3415
+ }
3416
+ )
3417
+ ] }) : coins ? coins.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: bodyStyle, children: "no confirmed coins at that address \xB7 send some sats there and wait for six confirmations, about an hour. the longer a coin sits, the more it says." }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "radiogroup", "aria-label": "pick one coin", style: { display: "grid", gap: 8 }, children: [
3418
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: bodyStyle, children: "pick one coin \xB7 value spread over several coins doesn't add up" }),
3419
+ coins.map((c) => {
3420
+ const young = c.age_blocks < MIN_CONFIRMATIONS;
3421
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3422
+ "label",
3423
+ {
3424
+ style: {
3425
+ ...panelStyle(chosen === c.outpoint ? "accent" : "default"),
3426
+ padding: "0.75rem",
3427
+ display: "flex",
3428
+ gap: 10,
3429
+ alignItems: "flex-start",
3430
+ cursor: young ? "not-allowed" : "pointer",
3431
+ opacity: young ? 0.6 : 1
3432
+ },
3433
+ children: [
3434
+ /* @__PURE__ */ jsxRuntime.jsx(
3435
+ "input",
3436
+ {
3437
+ type: "radio",
3438
+ name: "oc-bond-coin",
3439
+ value: c.outpoint,
3440
+ checked: chosen === c.outpoint,
3441
+ disabled: young,
3442
+ onChange: () => setChosen(c.outpoint)
3443
+ }
3444
+ ),
3445
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "grid", gap: 2, minWidth: 0 }, children: [
3446
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: V.foreground, fontSize: 13 }, children: [
3447
+ n(c.sats),
3448
+ " sats, held ",
3449
+ Math.floor(c.age_blocks / 144),
3450
+ " days"
3451
+ ] }),
3452
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: hintStyle, children: young ? "too recent: needs six confirmations" : `apps would see ${bondFloorsText(c)}` }),
3453
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...hintStyle, wordBreak: "break-all" }, children: short(c.outpoint) })
3454
+ ] })
3455
+ ]
3456
+ },
3457
+ c.outpoint
3458
+ );
3459
+ })
3460
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3461
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: bodyStyle, children: "which address holds the coin? use one that holds nothing else of yours: orangecheck learns its address and amount. apps never do." }),
3462
+ /* @__PURE__ */ jsxRuntime.jsx(
3463
+ "input",
3464
+ {
3465
+ style: inputStyle,
3466
+ value: address,
3467
+ onChange: (e) => setAddress(e.target.value),
3468
+ placeholder: "bc1q\u2026",
3469
+ spellCheck: false,
3470
+ autoComplete: "off",
3471
+ "aria-label": "Bitcoin address"
3472
+ }
3473
+ )
3474
+ ] }),
3475
+ err ? /* @__PURE__ */ jsxRuntime.jsx(ErrorLine, { children: err }) : null,
3476
+ /* @__PURE__ */ jsxRuntime.jsxs(FormButtons, { children: [
3477
+ !coins && !message ? /* @__PURE__ */ jsxRuntime.jsx(
3478
+ "button",
3479
+ {
3480
+ type: "button",
3481
+ style: primaryBtnStyle(busy || address.trim().length < 14),
3482
+ disabled: busy || address.trim().length < 14,
3483
+ onClick: () => void findCoins(),
3484
+ children: "find its coins"
3485
+ }
3486
+ ) : null,
3487
+ coins && coins.length > 0 && !message ? /* @__PURE__ */ jsxRuntime.jsx(
3488
+ "button",
3489
+ {
3490
+ type: "button",
3491
+ style: primaryBtnStyle(busy || !chosen),
3492
+ disabled: busy || !chosen,
3493
+ onClick: () => void getMessage(),
3494
+ children: "continue"
3495
+ }
3496
+ ) : null,
3497
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: ghostBtnStyle(busy), disabled: busy, onClick: onCancel, children: "cancel" })
3498
+ ] })
3499
+ ] });
3500
+ }
3210
3501
  function resolveAuthOrigin(opts) {
3211
3502
  if (!opts) return resolveConfig(void 0).authOrigin;
3212
3503
  return resolveConfig(opts).authOrigin;
@@ -3446,6 +3737,7 @@ exports.DISPLAY_IDENTITY_KINDS = DISPLAY_IDENTITY_KINDS;
3446
3737
  exports.OcAccountChip = OcAccountChip;
3447
3738
  exports.OcAccountPill = OcAccountPill;
3448
3739
  exports.OcAddressInput = OcAddressInput;
3740
+ exports.OcBond = OcBond;
3449
3741
  exports.OcLinkedIdentities = OcLinkedIdentities;
3450
3742
  exports.OcSessionProvider = OcSessionProvider;
3451
3743
  exports.OcSignIn = OcSignIn;
@@ -3455,12 +3747,14 @@ exports.TAB_ACCOUNT_HINT_KEY = TAB_ACCOUNT_HINT_KEY;
3455
3747
  exports.TAB_ADOPT_HASH = TAB_ADOPT_HASH;
3456
3748
  exports.TAB_SESSION_HEADER = TAB_SESSION_HEADER;
3457
3749
  exports.TAB_SESSION_STORAGE_KEY = TAB_SESSION_STORAGE_KEY;
3750
+ exports.bondFloorsText = bondFloorsText;
3458
3751
  exports.buildAddAccountUrl = buildAddAccountUrl;
3459
3752
  exports.buildSignInUrl = buildSignInUrl;
3460
3753
  exports.clearTabSession = clearTabSession;
3461
3754
  exports.consumeTabAccountHint = consumeTabAccountHint;
3462
3755
  exports.consumeTabAdoptMarker = consumeTabAdoptMarker;
3463
3756
  exports.familyReturnTarget = familyReturnTarget;
3757
+ exports.fetchOcBond = fetchOcBond;
3464
3758
  exports.fetchOcLinkedIdentities = fetchOcLinkedIdentities;
3465
3759
  exports.handleSudoRequired = handleSudoRequired;
3466
3760
  exports.installTabFetchInterceptor = installTabFetchInterceptor;