@orangecheck/auth-client 2.30.0 → 2.31.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.js CHANGED
@@ -3209,6 +3209,7 @@ function Hint({ children }) {
3209
3209
  }
3210
3210
  var DEFAULT_AUTH_ORIGIN2 = "https://ochk.io";
3211
3211
  var MIN_CONFIRMATIONS = 6;
3212
+ var MIN_SATS = 1e3;
3212
3213
  var n = (v) => v.toLocaleString("en-US");
3213
3214
  function bondFloorsText(f) {
3214
3215
  const sats = f.sats_floor > 0 ? `at least ${n(f.sats_floor)} sats` : "under 1,000 sats";
@@ -3219,23 +3220,56 @@ var short = (outpoint) => {
3219
3220
  const [txid = "", vout = ""] = outpoint.split(":");
3220
3221
  return `${txid.slice(0, 8)}\u2026${txid.slice(-4)}:${vout}`;
3221
3222
  };
3223
+ var usable = (c) => c.sats >= MIN_SATS && c.age_blocks >= MIN_CONFIRMATIONS;
3224
+ var dustText = (count) => `${n(count)} ${count === 1 ? "coin" : "coins"} under ${n(MIN_SATS)} sats, too small to back an account`;
3222
3225
  var REFUSAL = {
3223
3226
  invalid_address: "that isn't a Bitcoin address we can read",
3224
3227
  chain_unavailable: "couldn't read the chain just now \xB7 nothing changed, try again in a minute",
3225
3228
  sig_invalid: "that signature isn't from this coin's address \xB7 sign with the wallet that holds it",
3226
3229
  bond_expired: "the message expired \xB7 start again",
3227
- bond_not_yet_valid: "your device's clock looks wrong",
3230
+ bond_not_yet_valid: "your device's clock looks wrong \xB7 check it and start again",
3228
3231
  bond_subject_mismatch: "that message was for another account \xB7 start again",
3229
3232
  bond_malformed: "the signed message changed on the way \xB7 start again",
3233
+ bond_window_too_long: "that message's signing window is too long \xB7 start again",
3230
3234
  coin_not_found: "that coin doesn't exist on-chain",
3231
3235
  coin_address_mismatch: "that coin isn't at this address",
3232
3236
  coin_unconfirmed: "that coin isn't confirmed yet",
3233
3237
  coin_too_recent: "that coin needs six confirmations first, about an hour",
3234
3238
  coin_spent: "that coin has been spent \xB7 pick one still in your wallet",
3239
+ coin_too_small: `that coin is under ${n(MIN_SATS)} sats, too small to back an account`,
3235
3240
  coin_backs_another_account: "that coin already backs another orangecheck account",
3236
- not_authenticated: "your session ended \xB7 sign in again"
3241
+ coin_backed_another_recently: "that coin backed another account until recently \xB7 it can back this one 30 days after it was released",
3242
+ not_authenticated: "your session ended \xB7 sign in again",
3243
+ rate_limited: "too many tries \xB7 wait a minute, then try again"
3237
3244
  };
3238
- var refusal = (reason) => reason && REFUSAL[reason] || "your backing didn't save \xB7 nothing changed, try again";
3245
+ var bondRefusal = (reason) => reason && REFUSAL[reason] || "your backing didn't save \xB7 nothing changed, try again";
3246
+ var smallStyle = { ...bodyStyle, fontSize: 12, margin: 0 };
3247
+ var explainerStyle = {
3248
+ ...hintStyle,
3249
+ fontSize: 12,
3250
+ lineHeight: 1.55,
3251
+ opacity: 1,
3252
+ margin: 0
3253
+ };
3254
+ var fieldLabelStyle = {
3255
+ display: "block",
3256
+ color: V.foreground,
3257
+ fontSize: 13,
3258
+ fontWeight: 500,
3259
+ margin: "0 0 4px"
3260
+ };
3261
+ var addressStyle = { wordBreak: "break-all", color: V.foreground };
3262
+ function coinStyle(picked, young) {
3263
+ return {
3264
+ background: V.card,
3265
+ border: `1px ${young ? "dashed" : "solid"} ${picked ? V.primary : V.border}`,
3266
+ padding: "0.75rem",
3267
+ display: "flex",
3268
+ gap: 10,
3269
+ alignItems: "flex-start",
3270
+ cursor: young ? "not-allowed" : "pointer"
3271
+ };
3272
+ }
3239
3273
  async function fetchOcBond(opts) {
3240
3274
  const r = await fetch(`${opts?.authOrigin ?? DEFAULT_AUTH_ORIGIN2}/api/auth/bond`, {
3241
3275
  credentials: "include"
@@ -3253,6 +3287,7 @@ function OcBond({
3253
3287
  const [loadErr, setLoadErr] = React4__namespace.useState(false);
3254
3288
  const [nonce, setNonce] = React4__namespace.useState(0);
3255
3289
  const [adding, setAdding] = React4__namespace.useState(false);
3290
+ const [confirming, setConfirming] = React4__namespace.useState(false);
3256
3291
  const [busy, setBusy] = React4__namespace.useState(false);
3257
3292
  const [err, setErr] = React4__namespace.useState(null);
3258
3293
  React4__namespace.useEffect(() => {
@@ -3274,6 +3309,10 @@ function OcBond({
3274
3309
  body: body ? JSON.stringify(body) : void 0
3275
3310
  });
3276
3311
  const j = await r.json().catch(() => ({}));
3312
+ const pin = readTabSession();
3313
+ if (pin && r.ok && typeof j.token === "string") {
3314
+ writeTabSession({ token: j.token, didOc: pin.didOc });
3315
+ }
3277
3316
  return { ok: r.ok && j.ok === true, ...j };
3278
3317
  },
3279
3318
  [authOrigin]
@@ -3283,7 +3322,8 @@ function OcBond({
3283
3322
  setErr(null);
3284
3323
  const j = await call("DELETE").catch(() => ({ ok: false, reason: "network" }));
3285
3324
  setBusy(false);
3286
- if (!j.ok) return setErr(refusal(j.reason));
3325
+ if (!j.ok) return setErr(bondRefusal(j.reason));
3326
+ setConfirming(false);
3287
3327
  setBond(null);
3288
3328
  onChange?.(null);
3289
3329
  }
@@ -3327,16 +3367,71 @@ function OcBond({
3327
3367
  n(bond.checked_height),
3328
3368
  " \xB7 only you and orangecheck see this line"
3329
3369
  ] }),
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" })
3370
+ confirming ? /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "group", "aria-label": "stop backing", "data-oc-bond-confirm": "", children: [
3371
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { ...bodyStyle, color: V.foreground, margin: 0 }, children: "stop backing? apps that ask for a backed account may stop letting you in." }),
3372
+ /* @__PURE__ */ jsxRuntime.jsxs(FormButtons, { children: [
3373
+ /* @__PURE__ */ jsxRuntime.jsx(
3374
+ "button",
3375
+ {
3376
+ type: "button",
3377
+ style: dangerBtnStyle(busy),
3378
+ disabled: busy,
3379
+ onClick: () => void release(),
3380
+ children: "stop backing"
3381
+ }
3382
+ ),
3383
+ /* @__PURE__ */ jsxRuntime.jsx(
3384
+ "button",
3385
+ {
3386
+ type: "button",
3387
+ style: ghostBtnStyle(busy),
3388
+ disabled: busy,
3389
+ autoFocus: true,
3390
+ onClick: () => {
3391
+ setErr(null);
3392
+ setConfirming(false);
3393
+ },
3394
+ children: "keep"
3395
+ }
3396
+ )
3397
+ ] })
3398
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(FormButtons, { children: [
3399
+ /* @__PURE__ */ jsxRuntime.jsx(
3400
+ "button",
3401
+ {
3402
+ type: "button",
3403
+ style: ghostBtnStyle(false),
3404
+ onClick: () => {
3405
+ setErr(null);
3406
+ setAdding(true);
3407
+ },
3408
+ children: "use another coin"
3409
+ }
3410
+ ),
3411
+ /* @__PURE__ */ jsxRuntime.jsx(
3412
+ "button",
3413
+ {
3414
+ type: "button",
3415
+ style: dangerBtnStyle(false),
3416
+ onClick: () => setConfirming(true),
3417
+ children: "stop backing"
3418
+ }
3419
+ )
3333
3420
  ] }),
3334
3421
  err ? /* @__PURE__ */ jsxRuntime.jsx(ErrorLine, { children: err }) : null
3335
3422
  ] }) : null,
3336
3423
  !bond && !adding ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: panelStyle(), children: [
3337
3424
  /* @__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" })
3425
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: bodyStyle, children: "your account works everywhere as it is. some apps let in only accounts backed by a coin you hold. it stays in your wallet, and apps never see which coin." }),
3426
+ /* @__PURE__ */ jsxRuntime.jsx(
3427
+ "button",
3428
+ {
3429
+ type: "button",
3430
+ style: primaryBtnStyle(false),
3431
+ onClick: () => setAdding(true),
3432
+ children: "back your account"
3433
+ }
3434
+ )
3340
3435
  ] }) : null,
3341
3436
  adding ? /* @__PURE__ */ jsxRuntime.jsx(
3342
3437
  BondForm,
@@ -3350,9 +3445,9 @@ function OcBond({
3350
3445
  }
3351
3446
  }
3352
3447
  ) : null,
3353
- /* @__PURE__ */ jsxRuntime.jsxs("p", { style: hintStyle, children: [
3448
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { style: explainerStyle, children: [
3354
3449
  "> ",
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."
3450
+ "apps see only rough floors, like \u201Cat least 100,000 sats, held 30 days or more\u201D, and a number unique to that app. never the coin, your address or your balance. an app can block that number; only moving the coin gets past it, and a moved coin starts its age again."
3356
3451
  ] })
3357
3452
  ] });
3358
3453
  }
@@ -3367,135 +3462,212 @@ function BondForm({
3367
3462
  const [message, setMessage] = React4__namespace.useState(null);
3368
3463
  const [busy, setBusy] = React4__namespace.useState(false);
3369
3464
  const [err, setErr] = React4__namespace.useState(null);
3465
+ const id = React4__namespace.useId();
3466
+ const addr = address.trim();
3467
+ const canFind = addr.length >= 14;
3370
3468
  async function run(fn) {
3371
3469
  setBusy(true);
3372
3470
  setErr(null);
3373
3471
  try {
3374
3472
  await fn();
3375
3473
  } catch {
3376
- setErr(refusal("chain_unavailable"));
3474
+ setErr(bondRefusal("chain_unavailable"));
3377
3475
  } finally {
3378
3476
  setBusy(false);
3379
3477
  }
3380
3478
  }
3381
3479
  const findCoins = () => run(async () => {
3382
- const j = await call("POST", { action: "coins", address: address.trim() });
3383
- if (!j.ok) return setErr(refusal(j.reason));
3480
+ const j = await call("POST", { action: "coins", address: addr });
3481
+ if (!j.ok) return setErr(bondRefusal(j.reason));
3384
3482
  const list = j.coins ?? [];
3385
3483
  setCoins(list);
3386
- setChosen(list.find((c) => c.age_blocks >= MIN_CONFIRMATIONS)?.outpoint ?? "");
3484
+ setChosen(list.find(usable)?.outpoint ?? "");
3387
3485
  });
3388
3486
  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));
3487
+ const j = await call("POST", { action: "message", address: addr, outpoint: chosen });
3488
+ if (!j.ok || typeof j.message !== "string") return setErr(bondRefusal(j.reason));
3391
3489
  setMessage(j.message);
3392
3490
  });
3393
3491
  const submit = (signature) => run(async () => {
3394
3492
  const j = await call("POST", { action: "bond", message, signature });
3395
- if (!j.ok || !j.bond) return setErr(refusal(j.reason));
3493
+ if (!j.ok || !j.bond) return setErr(bondRefusal(j.reason));
3396
3494
  onDone(j.bond);
3397
3495
  });
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: [
3496
+ function back() {
3497
+ setErr(null);
3498
+ if (message) setMessage(null);
3499
+ else setCoins(null);
3500
+ }
3501
+ const error = err ? /* @__PURE__ */ jsxRuntime.jsx(ErrorLine, { children: err }) : null;
3502
+ const backButton = /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: ghostBtnStyle(busy), disabled: busy, onClick: back, children: "back" });
3503
+ const cancelButton = /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: ghostBtnStyle(busy), disabled: busy, onClick: onCancel, children: "cancel" });
3504
+ let step;
3505
+ if (message) {
3506
+ step = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3401
3507
  /* @__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."
3508
+ "sign with the wallet that holds ",
3509
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: addressStyle, children: addr }),
3510
+ ". signing spends nothing, and the coin stays in your wallet."
3406
3511
  ] }),
3407
3512
  /* @__PURE__ */ jsxRuntime.jsx(
3408
3513
  LazyWalletButton,
3409
3514
  {
3410
- address: address.trim(),
3515
+ address: addr,
3411
3516
  message,
3412
3517
  showManual: true,
3413
3518
  onSigned: (sig) => void submit(sig),
3414
3519
  onError: (e) => setErr(e.message ?? "the wallet refused to sign")
3415
3520
  }
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",
3521
+ ),
3522
+ error,
3523
+ /* @__PURE__ */ jsxRuntime.jsxs(FormButtons, { children: [
3524
+ backButton,
3525
+ cancelButton
3526
+ ] })
3527
+ ] });
3528
+ } else if (coins) {
3529
+ const eligible = coins.filter((c) => c.sats >= MIN_SATS);
3530
+ const dust = coins.length - eligible.length;
3531
+ step = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3532
+ coins.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("p", { style: bodyStyle, children: [
3533
+ "no confirmed coins at that address \xB7 send at least ",
3534
+ n(MIN_SATS),
3535
+ " sats there and wait for six confirmations, about an hour. the longer a coin sits, the more it says."
3536
+ ] }) : eligible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3537
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { ...bodyStyle, color: V.foreground }, children: dustText(dust) }),
3538
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { style: bodyStyle, children: [
3539
+ "send at least ",
3540
+ n(MIN_SATS),
3541
+ " sats there in one payment and wait for six confirmations, about an hour. coins aren't added together."
3542
+ ] })
3543
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3544
+ /* @__PURE__ */ jsxRuntime.jsx("p", { id: `${id}-pick`, style: bodyStyle, children: "pick one coin \xB7 coins aren't added together" }),
3545
+ /* @__PURE__ */ jsxRuntime.jsx(
3546
+ "div",
3423
3547
  {
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",
3548
+ role: "radiogroup",
3549
+ "aria-labelledby": `${id}-pick`,
3550
+ style: { display: "grid", gap: 8 },
3551
+ children: eligible.map((c) => {
3552
+ const young = c.age_blocks < MIN_CONFIRMATIONS;
3553
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3554
+ "label",
3436
3555
  {
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
- ] })
3556
+ style: coinStyle(chosen === c.outpoint, young),
3557
+ children: [
3558
+ /* @__PURE__ */ jsxRuntime.jsx(
3559
+ "input",
3560
+ {
3561
+ type: "radio",
3562
+ name: "oc-bond-coin",
3563
+ value: c.outpoint,
3564
+ checked: chosen === c.outpoint,
3565
+ disabled: young,
3566
+ onChange: () => setChosen(c.outpoint),
3567
+ style: { accentColor: V.primary, margin: "2px 0 0" }
3568
+ }
3569
+ ),
3570
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "grid", gap: 2, minWidth: 0 }, children: [
3571
+ /* @__PURE__ */ jsxRuntime.jsxs(
3572
+ "span",
3573
+ {
3574
+ style: {
3575
+ color: young ? V.muted : V.foreground,
3576
+ fontSize: 13
3577
+ },
3578
+ children: [
3579
+ n(c.sats),
3580
+ " sats, held",
3581
+ " ",
3582
+ Math.floor(c.age_blocks / 144),
3583
+ " days"
3584
+ ]
3585
+ }
3586
+ ),
3587
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: smallStyle, children: young ? "too recent: needs six confirmations" : `apps would see ${bondFloorsText(c)}` }),
3588
+ /* @__PURE__ */ jsxRuntime.jsx(
3589
+ "span",
3590
+ {
3591
+ style: {
3592
+ ...smallStyle,
3593
+ fontFamily: SIGNIN_FONT,
3594
+ wordBreak: "break-all"
3595
+ },
3596
+ children: short(c.outpoint)
3597
+ }
3598
+ )
3599
+ ] })
3600
+ ]
3601
+ },
3602
+ c.outpoint
3603
+ );
3604
+ })
3605
+ }
3606
+ ),
3607
+ dust > 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { ...smallStyle, marginTop: 8 }, children: dustText(dust) }) : null
3608
+ ] }),
3609
+ error,
3610
+ /* @__PURE__ */ jsxRuntime.jsxs(FormButtons, { children: [
3611
+ eligible.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
3612
+ "button",
3613
+ {
3614
+ type: "button",
3615
+ style: primaryBtnStyle(busy || !chosen),
3616
+ disabled: busy || !chosen,
3617
+ onClick: () => void getMessage(),
3618
+ children: "continue"
3619
+ }
3620
+ ) : null,
3621
+ backButton,
3622
+ cancelButton
3623
+ ] })
3624
+ ] });
3625
+ } else {
3626
+ step = /* @__PURE__ */ jsxRuntime.jsxs(
3627
+ "form",
3628
+ {
3629
+ style: { margin: 0 },
3630
+ onSubmit: (e) => {
3631
+ e.preventDefault();
3632
+ if (canFind && !busy) void findCoins();
3633
+ },
3634
+ children: [
3635
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: `${id}-address`, style: fieldLabelStyle, children: "bitcoin address that holds the coin" }),
3636
+ /* @__PURE__ */ jsxRuntime.jsx("p", { id: `${id}-advice`, style: { ...bodyStyle, margin: "0 0 8px" }, children: "use one that holds nothing else of yours: orangecheck learns its address and amount. apps never do." }),
3637
+ /* @__PURE__ */ jsxRuntime.jsx(
3638
+ "input",
3639
+ {
3640
+ id: `${id}-address`,
3641
+ "aria-describedby": `${id}-advice`,
3642
+ style: inputStyle,
3643
+ value: address,
3644
+ onChange: (e) => setAddress(e.target.value),
3645
+ placeholder: "bc1q\u2026",
3646
+ spellCheck: false,
3647
+ autoComplete: "off",
3648
+ autoCapitalize: "off"
3649
+ }
3650
+ ),
3651
+ error,
3652
+ /* @__PURE__ */ jsxRuntime.jsxs(FormButtons, { children: [
3653
+ /* @__PURE__ */ jsxRuntime.jsx(
3654
+ "button",
3655
+ {
3656
+ type: "submit",
3657
+ style: primaryBtnStyle(busy || !canFind),
3658
+ disabled: busy || !canFind,
3659
+ children: "find its coins"
3660
+ }
3661
+ ),
3662
+ cancelButton
3663
+ ] })
3664
+ ]
3665
+ }
3666
+ );
3667
+ }
3668
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: panelStyle("accent"), "data-oc-bond-form": "", children: [
3669
+ /* @__PURE__ */ jsxRuntime.jsx(SectionLabel, { children: "\xA7 back your account" }),
3670
+ step
3499
3671
  ] });
3500
3672
  }
3501
3673
  function resolveAuthOrigin(opts) {