@orangecheck/auth-client 2.28.0 → 2.30.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 +25 -1
- package/dist/index.d.ts +25 -1
- package/dist/index.js +319 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +317 -19
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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
|
@@ -1196,6 +1196,7 @@ var signinSize = (px) => `calc(${px}px * var(--oc-signin-scale, 1))`;
|
|
|
1196
1196
|
var signinRadius = (px) => `var(--oc-signin-radius, ${px}px)`;
|
|
1197
1197
|
var SIGNIN_BUTTON_RADIUS = "var(--oc-signin-button-radius, 6px)";
|
|
1198
1198
|
var SIGNIN_STRONG = "var(--oc-signin-strong, 600)";
|
|
1199
|
+
var SIGNIN_ARROW = "var(--oc-signin-arrow, inline)";
|
|
1199
1200
|
var DEFAULT_AUTH_ORIGIN = "https://ochk.io";
|
|
1200
1201
|
async function fetchOcLinkedIdentities(opts) {
|
|
1201
1202
|
const authOrigin = opts?.authOrigin ?? DEFAULT_AUTH_ORIGIN;
|
|
@@ -2371,7 +2372,7 @@ function OcSignIn({
|
|
|
2371
2372
|
{
|
|
2372
2373
|
active: path === "email",
|
|
2373
2374
|
onClick: () => setPath("email"),
|
|
2374
|
-
children: "
|
|
2375
|
+
children: "Email"
|
|
2375
2376
|
}
|
|
2376
2377
|
),
|
|
2377
2378
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2379,7 +2380,7 @@ function OcSignIn({
|
|
|
2379
2380
|
{
|
|
2380
2381
|
active: path === "wallet",
|
|
2381
2382
|
onClick: () => setPath("wallet"),
|
|
2382
|
-
children: "
|
|
2383
|
+
children: "Bitcoin wallet"
|
|
2383
2384
|
}
|
|
2384
2385
|
)
|
|
2385
2386
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -2388,7 +2389,7 @@ function OcSignIn({
|
|
|
2388
2389
|
{
|
|
2389
2390
|
active: path === "wallet",
|
|
2390
2391
|
onClick: () => setPath("wallet"),
|
|
2391
|
-
children: "
|
|
2392
|
+
children: "Bitcoin wallet"
|
|
2392
2393
|
}
|
|
2393
2394
|
),
|
|
2394
2395
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2396,7 +2397,7 @@ function OcSignIn({
|
|
|
2396
2397
|
{
|
|
2397
2398
|
active: path === "email",
|
|
2398
2399
|
onClick: () => setPath("email"),
|
|
2399
|
-
children: "
|
|
2400
|
+
children: "Email"
|
|
2400
2401
|
}
|
|
2401
2402
|
)
|
|
2402
2403
|
] })
|
|
@@ -2758,7 +2759,7 @@ function WalletFlow({
|
|
|
2758
2759
|
address.trim(),
|
|
2759
2760
|
", sign the text below, and paste the signature back here. Nothing is spent."
|
|
2760
2761
|
] }),
|
|
2761
|
-
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: ids.message, children: "
|
|
2762
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: ids.message, children: "Message to sign" }),
|
|
2762
2763
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2763
2764
|
"textarea",
|
|
2764
2765
|
{
|
|
@@ -2770,10 +2771,10 @@ function WalletFlow({
|
|
|
2770
2771
|
style: { ...inputStyle2, resize: "vertical" }
|
|
2771
2772
|
}
|
|
2772
2773
|
),
|
|
2773
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => void copyMessage(), style: linkButtonStyle, children: copied === "copied" ? "
|
|
2774
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => void copyMessage(), style: linkButtonStyle, children: copied === "copied" ? "Copied" : "Copy message" }),
|
|
2774
2775
|
copied === "failed" && /* @__PURE__ */ jsxRuntime.jsx(Hint, { children: "Couldn't copy here. Select the text above and copy it." }),
|
|
2775
2776
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: 14 }, children: [
|
|
2776
|
-
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: ids.signature, children: "
|
|
2777
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: ids.signature, children: "Signature" }),
|
|
2777
2778
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2778
2779
|
"textarea",
|
|
2779
2780
|
{
|
|
@@ -2799,7 +2800,7 @@ function WalletFlow({
|
|
|
2799
2800
|
type: "submit",
|
|
2800
2801
|
disabled: submitting || !pasted.trim(),
|
|
2801
2802
|
style: submitStyle(submitting || !pasted.trim()),
|
|
2802
|
-
children: submitting ? "
|
|
2803
|
+
children: submitting ? "Checking\u2026" : /* @__PURE__ */ jsxRuntime.jsx(Submit, { children: "Sign me in" })
|
|
2803
2804
|
}
|
|
2804
2805
|
),
|
|
2805
2806
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2813,7 +2814,7 @@ function WalletFlow({
|
|
|
2813
2814
|
setCopied("idle");
|
|
2814
2815
|
},
|
|
2815
2816
|
style: linkButtonStyle,
|
|
2816
|
-
children: "
|
|
2817
|
+
children: "Use a different address"
|
|
2817
2818
|
}
|
|
2818
2819
|
)
|
|
2819
2820
|
] });
|
|
@@ -2821,7 +2822,7 @@ function WalletFlow({
|
|
|
2821
2822
|
const noBrowserWallet = wallets !== null && wallets.length === 0;
|
|
2822
2823
|
return /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: signIn, "data-oc-signin-wallet": "", children: [
|
|
2823
2824
|
/* @__PURE__ */ jsxRuntime.jsx(FlowHeader, { children: "Your wallet signs a short message to prove you hold the address. Nothing is spent and your key never leaves the wallet. Works with browser wallets, or any wallet that can sign a message, like Sparrow." }),
|
|
2824
|
-
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: ids.address, children: "
|
|
2825
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: ids.address, children: "Bitcoin address" }),
|
|
2825
2826
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2826
2827
|
"input",
|
|
2827
2828
|
{
|
|
@@ -2842,7 +2843,7 @@ function WalletFlow({
|
|
|
2842
2843
|
}
|
|
2843
2844
|
),
|
|
2844
2845
|
wallets && wallets.length > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: 12 }, children: [
|
|
2845
|
-
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: ids.wallet, children: "
|
|
2846
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: ids.wallet, children: "Sign with" }),
|
|
2846
2847
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2847
2848
|
"select",
|
|
2848
2849
|
{
|
|
@@ -2861,7 +2862,7 @@ function WalletFlow({
|
|
|
2861
2862
|
type: "submit",
|
|
2862
2863
|
disabled: submitting || !address.trim(),
|
|
2863
2864
|
style: submitStyle(submitting || !address.trim()),
|
|
2864
|
-
children: submitting ? "
|
|
2865
|
+
children: submitting ? "Waiting for wallet\u2026" : noBrowserWallet ? /* @__PURE__ */ jsxRuntime.jsx(Submit, { children: "Get the message to sign" }) : /* @__PURE__ */ jsxRuntime.jsx(Submit, { children: "Sign in with wallet" })
|
|
2865
2866
|
}
|
|
2866
2867
|
),
|
|
2867
2868
|
noBrowserWallet && /* @__PURE__ */ jsxRuntime.jsx(Hint, { children: "No browser wallet found here. You can sign with any wallet and paste." })
|
|
@@ -2959,7 +2960,7 @@ function EmailFlow({ authOrigin, add, credentials, onSuccess }) {
|
|
|
2959
2960
|
if (stage === "enter") {
|
|
2960
2961
|
return /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: start, "data-oc-signin-email": "", children: [
|
|
2961
2962
|
/* @__PURE__ */ jsxRuntime.jsx(FlowHeader, { children: "We email you a 6-digit code. No password, and no wallet needed to start. Link a Bitcoin address any time \u2014 that is the identity you hold yourself." }),
|
|
2962
|
-
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: `${uid}-email`, children: "
|
|
2963
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: `${uid}-email`, children: "Email" }),
|
|
2963
2964
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2964
2965
|
"input",
|
|
2965
2966
|
{
|
|
@@ -2978,7 +2979,7 @@ function EmailFlow({ authOrigin, add, credentials, onSuccess }) {
|
|
|
2978
2979
|
}
|
|
2979
2980
|
),
|
|
2980
2981
|
emailError && /* @__PURE__ */ jsxRuntime.jsx(ErrorLine2, { children: emailError }),
|
|
2981
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "submit", disabled: submitting, style: submitStyle(submitting), children: submitting ? "
|
|
2982
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "submit", disabled: submitting, style: submitStyle(submitting), children: submitting ? "Sending\u2026" : /* @__PURE__ */ jsxRuntime.jsx(Submit, { children: "Send one-time code" }) })
|
|
2982
2983
|
] });
|
|
2983
2984
|
}
|
|
2984
2985
|
return /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: verify, "data-oc-signin-email-verify": "", children: [
|
|
@@ -2987,7 +2988,7 @@ function EmailFlow({ authOrigin, add, credentials, onSuccess }) {
|
|
|
2987
2988
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--foreground, #fafafa)" }, children: email }),
|
|
2988
2989
|
". It expires in 10 minutes."
|
|
2989
2990
|
] }),
|
|
2990
|
-
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: `${uid}-code`, children: "
|
|
2991
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: `${uid}-code`, children: "One-time code" }),
|
|
2991
2992
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2992
2993
|
"input",
|
|
2993
2994
|
{
|
|
@@ -3016,7 +3017,7 @@ function EmailFlow({ authOrigin, add, credentials, onSuccess }) {
|
|
|
3016
3017
|
type: "submit",
|
|
3017
3018
|
disabled: submitting || code.length !== 6,
|
|
3018
3019
|
style: submitStyle(submitting || code.length !== 6),
|
|
3019
|
-
children: submitting ? "
|
|
3020
|
+
children: submitting ? "Verifying\u2026" : /* @__PURE__ */ jsxRuntime.jsx(Submit, { children: "Verify \xB7 sign me in" })
|
|
3020
3021
|
}
|
|
3021
3022
|
),
|
|
3022
3023
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
@@ -3027,7 +3028,7 @@ function EmailFlow({ authOrigin, add, credentials, onSuccess }) {
|
|
|
3027
3028
|
onClick: () => void resend(),
|
|
3028
3029
|
disabled: submitting,
|
|
3029
3030
|
style: linkButtonStyle,
|
|
3030
|
-
children: "
|
|
3031
|
+
children: "Send a new code"
|
|
3031
3032
|
}
|
|
3032
3033
|
),
|
|
3033
3034
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3041,12 +3042,18 @@ function EmailFlow({ authOrigin, add, credentials, onSuccess }) {
|
|
|
3041
3042
|
setResent(false);
|
|
3042
3043
|
},
|
|
3043
3044
|
style: linkButtonStyle,
|
|
3044
|
-
children: "
|
|
3045
|
+
children: "Use a different email"
|
|
3045
3046
|
}
|
|
3046
3047
|
)
|
|
3047
3048
|
] })
|
|
3048
3049
|
] });
|
|
3049
3050
|
}
|
|
3051
|
+
function Submit({ children }) {
|
|
3052
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3053
|
+
children,
|
|
3054
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", style: { display: SIGNIN_ARROW }, children: " \u2192" })
|
|
3055
|
+
] });
|
|
3056
|
+
}
|
|
3050
3057
|
function FlowHeader({
|
|
3051
3058
|
label,
|
|
3052
3059
|
children
|
|
@@ -3200,6 +3207,297 @@ function Hint({ children }) {
|
|
|
3200
3207
|
}
|
|
3201
3208
|
);
|
|
3202
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
|
+
}
|
|
3203
3501
|
function resolveAuthOrigin(opts) {
|
|
3204
3502
|
if (!opts) return resolveConfig(void 0).authOrigin;
|
|
3205
3503
|
return resolveConfig(opts).authOrigin;
|
|
@@ -3439,6 +3737,7 @@ exports.DISPLAY_IDENTITY_KINDS = DISPLAY_IDENTITY_KINDS;
|
|
|
3439
3737
|
exports.OcAccountChip = OcAccountChip;
|
|
3440
3738
|
exports.OcAccountPill = OcAccountPill;
|
|
3441
3739
|
exports.OcAddressInput = OcAddressInput;
|
|
3740
|
+
exports.OcBond = OcBond;
|
|
3442
3741
|
exports.OcLinkedIdentities = OcLinkedIdentities;
|
|
3443
3742
|
exports.OcSessionProvider = OcSessionProvider;
|
|
3444
3743
|
exports.OcSignIn = OcSignIn;
|
|
@@ -3448,12 +3747,14 @@ exports.TAB_ACCOUNT_HINT_KEY = TAB_ACCOUNT_HINT_KEY;
|
|
|
3448
3747
|
exports.TAB_ADOPT_HASH = TAB_ADOPT_HASH;
|
|
3449
3748
|
exports.TAB_SESSION_HEADER = TAB_SESSION_HEADER;
|
|
3450
3749
|
exports.TAB_SESSION_STORAGE_KEY = TAB_SESSION_STORAGE_KEY;
|
|
3750
|
+
exports.bondFloorsText = bondFloorsText;
|
|
3451
3751
|
exports.buildAddAccountUrl = buildAddAccountUrl;
|
|
3452
3752
|
exports.buildSignInUrl = buildSignInUrl;
|
|
3453
3753
|
exports.clearTabSession = clearTabSession;
|
|
3454
3754
|
exports.consumeTabAccountHint = consumeTabAccountHint;
|
|
3455
3755
|
exports.consumeTabAdoptMarker = consumeTabAdoptMarker;
|
|
3456
3756
|
exports.familyReturnTarget = familyReturnTarget;
|
|
3757
|
+
exports.fetchOcBond = fetchOcBond;
|
|
3457
3758
|
exports.fetchOcLinkedIdentities = fetchOcLinkedIdentities;
|
|
3458
3759
|
exports.handleSudoRequired = handleSudoRequired;
|
|
3459
3760
|
exports.installTabFetchInterceptor = installTabFetchInterceptor;
|