@dexterai/connect 0.6.0 → 0.8.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/react.d.ts +38 -11
- package/dist/react.js +109 -72
- package/package.json +1 -1
package/dist/react.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DexterApiBrowserPasskeySigner } from '@dexterai/vault/signers/browser';
|
|
2
2
|
import { S as SignInResult, P as PasskeyLoginTokens, C as ConnectVault, a as ConnectError, c as StoredWallet, b as PasskeySignalSupport } from './signals-CkBFwCNw.js';
|
|
3
|
-
import { ReactElement } from 'react';
|
|
3
|
+
import { ReactElement, ReactNode } from 'react';
|
|
4
4
|
|
|
5
5
|
type ConnectStatus = 'idle' | 'pending' | 'done' | 'error';
|
|
6
6
|
interface UseSignInWithDexterConfig {
|
|
@@ -48,22 +48,49 @@ interface SignInWithDexterProps extends UseSignInWithDexterConfig {
|
|
|
48
48
|
onError?: (error: ConnectError) => void;
|
|
49
49
|
/** Button label when signed out. Default "Sign in with Dexter". */
|
|
50
50
|
label?: string;
|
|
51
|
-
/**
|
|
52
|
-
|
|
51
|
+
/** 'primary' = filled ember (default), 'secondary' = outline. */
|
|
52
|
+
variant?: 'primary' | 'secondary';
|
|
53
|
+
/** Full-width button. */
|
|
54
|
+
block?: boolean;
|
|
55
|
+
/** Extra className composed after the brand classes. Prefer overriding the
|
|
56
|
+
* `--dx-*` CSS variables for theming. */
|
|
53
57
|
className?: string;
|
|
54
|
-
/** Render the built-in connected chip (wallet + balance). Default true.
|
|
55
|
-
* Set false to render nothing once connected (consumer renders its own UI). */
|
|
58
|
+
/** Render the built-in connected chip (wallet + balance). Default true. */
|
|
56
59
|
showConnectedChip?: boolean;
|
|
57
60
|
}
|
|
58
61
|
/**
|
|
59
|
-
* Turnkey "Sign in with Dexter" element. Signed out →
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
62
|
+
* Turnkey "Sign in with Dexter" element. Signed out → the branded DexterButton
|
|
63
|
+
* (hover / focus / active / loading states, themeable via --dx-* CSS vars);
|
|
64
|
+
* signed in → a compact chip with the Dexter Wallet address + USD available.
|
|
65
|
+
* Wraps useSignInWithDexter; for the wallet CREATE flow use <DexterButton>
|
|
66
|
+
* wired to your create action. Brand voice: no emojis, "unlock" banned.
|
|
64
67
|
*/
|
|
65
68
|
declare function SignInWithDexter(props: SignInWithDexterProps): ReactElement | null;
|
|
66
69
|
|
|
70
|
+
/** The Dexter passkey mark — the brand glyph carried on the branded button. */
|
|
71
|
+
declare function DexterMark(): ReactElement;
|
|
72
|
+
interface DexterButtonProps {
|
|
73
|
+
/** Button content (e.g. "Sign in with Dexter", "Create your Dexter Wallet"). */
|
|
74
|
+
children?: ReactNode;
|
|
75
|
+
/** Loading state: shows the animated spinner + `loadingLabel`, disables click. */
|
|
76
|
+
loading?: boolean;
|
|
77
|
+
/** Label shown next to the spinner while loading. Default "Connecting…". */
|
|
78
|
+
loadingLabel?: string;
|
|
79
|
+
/** 'primary' = filled ember (default), 'secondary' = outline. */
|
|
80
|
+
variant?: 'primary' | 'secondary';
|
|
81
|
+
/** Full-width (fills its container). */
|
|
82
|
+
block?: boolean;
|
|
83
|
+
/** Render the Dexter mark before the children. Default true. */
|
|
84
|
+
withMark?: boolean;
|
|
85
|
+
onClick?: () => void;
|
|
86
|
+
disabled?: boolean;
|
|
87
|
+
/** Extra className composed after the brand classes. */
|
|
88
|
+
className?: string;
|
|
89
|
+
type?: 'button' | 'submit';
|
|
90
|
+
}
|
|
91
|
+
/** The branded Dexter button. Wire it to any action via `onClick`. */
|
|
92
|
+
declare function DexterButton(props: DexterButtonProps): ReactElement;
|
|
93
|
+
|
|
67
94
|
interface UseDexterWallet {
|
|
68
95
|
/** Active wallet handle, or null if this browser has no active wallet. */
|
|
69
96
|
activeHandle: string | null;
|
|
@@ -94,4 +121,4 @@ interface UseDexterWallet {
|
|
|
94
121
|
}
|
|
95
122
|
declare function useDexterWallet(): UseDexterWallet;
|
|
96
123
|
|
|
97
|
-
export { type ConnectStatus, SignInWithDexter, type SignInWithDexterProps, type UseDexterWallet, type UseSignInWithDexter, type UseSignInWithDexterConfig, useDexterWallet, useSignInWithDexter };
|
|
124
|
+
export { type ConnectStatus, DexterButton, type DexterButtonProps, DexterMark, SignInWithDexter, type SignInWithDexterProps, type UseDexterWallet, type UseSignInWithDexter, type UseSignInWithDexterConfig, useDexterWallet, useSignInWithDexter };
|
package/dist/react.js
CHANGED
|
@@ -116,23 +116,68 @@ function useSignInWithDexter(config = {}) {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
// src/SignInWithDexter.tsx
|
|
119
|
+
import { useEffect as useEffect3 } from "react";
|
|
120
|
+
|
|
121
|
+
// src/DexterButton.tsx
|
|
122
|
+
import { useEffect as useEffect2 } from "react";
|
|
119
123
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
120
|
-
|
|
121
|
-
|
|
124
|
+
var STYLE_ID = "dexter-connect-button-styles";
|
|
125
|
+
var BUTTON_CSS = `
|
|
126
|
+
@keyframes dx-spin { to { transform: rotate(360deg); } }
|
|
127
|
+
@keyframes dx-pulse { 0%,100% { opacity: 1; } 50% { opacity: .6; } }
|
|
128
|
+
.dx-btn{
|
|
129
|
+
--dx-ember:#f26c18; --dx-ember-2:#ba3a00; --dx-fg:#fff4ea; --dx-radius:0px;
|
|
130
|
+
position:relative; display:inline-flex; align-items:center; justify-content:center; gap:10px;
|
|
131
|
+
padding:11px 22px; border:1px solid color-mix(in srgb,var(--dx-ember) 55%,transparent);
|
|
132
|
+
border-radius:var(--dx-radius);
|
|
133
|
+
background:linear-gradient(135deg,var(--dx-ember),var(--dx-ember-2));
|
|
134
|
+
color:var(--dx-fg); font:inherit; font-weight:600; font-size:.78rem; letter-spacing:.12em;
|
|
135
|
+
text-transform:uppercase; cursor:pointer; -webkit-tap-highlight-color:transparent;
|
|
136
|
+
box-shadow:0 14px 26px color-mix(in srgb,var(--dx-ember) 24%,transparent);
|
|
137
|
+
transition:transform .16s ease, box-shadow .16s ease, filter .16s ease, background .16s ease;
|
|
122
138
|
}
|
|
123
|
-
|
|
124
|
-
|
|
139
|
+
.dx-btn:hover{ transform:translateY(-1px); filter:brightness(1.07); box-shadow:0 20px 34px color-mix(in srgb,var(--dx-ember) 32%,transparent); }
|
|
140
|
+
.dx-btn:active{ transform:translateY(0); filter:brightness(.97); box-shadow:0 8px 16px color-mix(in srgb,var(--dx-ember) 22%,transparent); }
|
|
141
|
+
.dx-btn:focus-visible{ outline:none; box-shadow:0 0 0 3px color-mix(in srgb,var(--dx-ember) 38%,transparent); }
|
|
142
|
+
.dx-btn:disabled{ cursor:default; filter:saturate(.85) brightness(.98); }
|
|
143
|
+
.dx-btn--secondary{ background:transparent; color:var(--dx-ember); box-shadow:none; border-color:color-mix(in srgb,var(--dx-ember) 45%,transparent); }
|
|
144
|
+
.dx-btn--secondary:hover{ background:color-mix(in srgb,var(--dx-ember) 9%,transparent); filter:none; box-shadow:none; }
|
|
145
|
+
.dx-btn--block{ width:100%; }
|
|
146
|
+
.dx-btn__mark{ flex-shrink:0; }
|
|
147
|
+
.dx-btn__spin{ width:15px; height:15px; flex-shrink:0; border-radius:50%;
|
|
148
|
+
border:2px solid color-mix(in srgb,currentColor 30%,transparent); border-top-color:currentColor;
|
|
149
|
+
animation:dx-spin .7s linear infinite; }
|
|
150
|
+
.dx-btn__doing{ animation:dx-pulse 1.4s ease-in-out infinite; }
|
|
151
|
+
.dx-chip{ display:inline-flex; align-items:center; gap:8px; padding:6px 10px; font:inherit;
|
|
152
|
+
font-variant-numeric:tabular-nums; border-radius:var(--dx-radius,0);
|
|
153
|
+
border:1px solid color-mix(in srgb,var(--dx-ember,#f26c18) 35%,transparent); }
|
|
154
|
+
.dx-chip__dot{ width:7px; height:7px; border-radius:50%; background:var(--dx-ember,#f26c18); }
|
|
155
|
+
.dx-chip__bal{ font-weight:600; opacity:.85; }
|
|
156
|
+
.dx-chip__x{ margin-left:2px; border:none; background:transparent; color:inherit; cursor:pointer; font-size:16px; line-height:1; opacity:.6; }
|
|
157
|
+
.dx-chip__x:hover{ opacity:1; }
|
|
158
|
+
`;
|
|
159
|
+
function ensureDexterButtonStyles() {
|
|
160
|
+
if (typeof document === "undefined") return;
|
|
161
|
+
if (document.getElementById(STYLE_ID)) return;
|
|
162
|
+
const el = document.createElement("style");
|
|
163
|
+
el.id = STYLE_ID;
|
|
164
|
+
el.textContent = BUTTON_CSS;
|
|
165
|
+
document.head.appendChild(el);
|
|
166
|
+
}
|
|
167
|
+
ensureDexterButtonStyles();
|
|
168
|
+
function cx(...parts) {
|
|
169
|
+
return parts.filter(Boolean).join(" ");
|
|
125
170
|
}
|
|
126
171
|
function DexterMark() {
|
|
127
172
|
return /* @__PURE__ */ jsxs(
|
|
128
173
|
"svg",
|
|
129
174
|
{
|
|
175
|
+
className: "dx-btn__mark",
|
|
130
176
|
width: "18",
|
|
131
177
|
height: "18",
|
|
132
178
|
viewBox: "0 0 300 300",
|
|
133
179
|
fill: "currentColor",
|
|
134
180
|
"aria-hidden": "true",
|
|
135
|
-
style: { flexShrink: 0 },
|
|
136
181
|
children: [
|
|
137
182
|
/* @__PURE__ */ jsx("path", { d: "M143.18,22.65c35.41,7.66,68.19,23.6,94.89,48.28,5.22,4.86,11.17,10.45,15.18,16.1,1.38,1.93,1.94,3.6.99,5.23-1.08,1.92-4.22,3.41-6.56,4.17-28.39,9.43-61.55,8.26-88.62-4.69-13.81-7.66-17.02-5.76-31.67-3.48-21.89,2.38-46.67.37-65.06-12.31-6.07-4.99-9.33-12.71-8.8-20.52-.16-9.4,4.25-18.12,11.47-24.06,21.29-17.85,52.64-14.45,78-8.77l.18.04h0Z" }),
|
|
138
183
|
/* @__PURE__ */ jsx("path", { d: "M46.08,129.98c1.06-1.03,3.52-1.07,5.29-1.04,48.98-.05,98.1-.06,146.83-.1,17.53.14,35.01-.31,52.49.18,2.13.18,3.89.74,4.73,2.05,1.46,2.38.35,6.09-1.98,7.6-3.66,2.05-8.62,1.33-12.86,1.74-2.85.12-5.45.13-7.02,2.02-.91,1.07-1.28,2.56-1.56,3.95-.57,3.23-1.16,6.52-1.89,9.62-2.81,12.43-8.68,24.65-19.76,31.56-9.49,5.59-20.42,6.86-31.2,5.75-11.88-1.69-22.15-8.81-29.11-18.28-3.51-4.81-4.92-10.5-5.8-16.29-.47-2.56-.51-5.87-1.35-8-1.16-3.38-6.14-2.59-9.25-1.92-4.21.95-4.39,5.7-5.14,9.19-2.25,11.18-6.84,20.68-16.15,27.65-1.31,1.05-2.91,2.03-2.12,3.66,2.5,3.21,6.65,4.49,10.44,5.97,3.26,1.17,6.86,2.41,7.18,6.06.05,8.18-11.97,3.46-16.32,1.85-3.95-1.55-7.4-4.27-10.42-7.26-3.92-4.28-9.66-4.5-15.16-4.45-3.45-.07-6.99-.19-10.45-.82-21.29-4-31.08-21.3-30.9-42.01-.08-4.63.03-9.32.09-13.91.04-1.69.07-3.46,1.28-4.67l.1-.09h0Z" }),
|
|
@@ -141,15 +186,59 @@ function DexterMark() {
|
|
|
141
186
|
}
|
|
142
187
|
);
|
|
143
188
|
}
|
|
189
|
+
function DexterButton(props) {
|
|
190
|
+
const {
|
|
191
|
+
children,
|
|
192
|
+
loading = false,
|
|
193
|
+
loadingLabel = "Connecting\u2026",
|
|
194
|
+
variant = "primary",
|
|
195
|
+
block = false,
|
|
196
|
+
withMark = true,
|
|
197
|
+
onClick,
|
|
198
|
+
disabled = false,
|
|
199
|
+
className,
|
|
200
|
+
type = "button"
|
|
201
|
+
} = props;
|
|
202
|
+
useEffect2(ensureDexterButtonStyles, []);
|
|
203
|
+
return /* @__PURE__ */ jsx(
|
|
204
|
+
"button",
|
|
205
|
+
{
|
|
206
|
+
type,
|
|
207
|
+
className: cx("dx-btn", variant === "secondary" && "dx-btn--secondary", block && "dx-btn--block", className),
|
|
208
|
+
onClick,
|
|
209
|
+
disabled: disabled || loading,
|
|
210
|
+
"aria-busy": loading,
|
|
211
|
+
children: loading ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
212
|
+
/* @__PURE__ */ jsx("span", { className: "dx-btn__spin", "aria-hidden": true }),
|
|
213
|
+
/* @__PURE__ */ jsx("span", { className: "dx-btn__doing", children: loadingLabel })
|
|
214
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
215
|
+
withMark && /* @__PURE__ */ jsx(DexterMark, {}),
|
|
216
|
+
children
|
|
217
|
+
] })
|
|
218
|
+
}
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// src/SignInWithDexter.tsx
|
|
223
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
224
|
+
function shortAddress(addr) {
|
|
225
|
+
return addr.length > 10 ? `${addr.slice(0, 4)}\u2026${addr.slice(-4)}` : addr;
|
|
226
|
+
}
|
|
227
|
+
function formatUsd(n) {
|
|
228
|
+
return n.toLocaleString("en-US", { style: "currency", currency: "USD" });
|
|
229
|
+
}
|
|
144
230
|
function SignInWithDexter(props) {
|
|
145
231
|
const {
|
|
146
232
|
onSuccess,
|
|
147
233
|
onError,
|
|
148
234
|
label = "Sign in with Dexter",
|
|
235
|
+
variant = "primary",
|
|
236
|
+
block = false,
|
|
149
237
|
className,
|
|
150
238
|
showConnectedChip = true,
|
|
151
239
|
...config
|
|
152
240
|
} = props;
|
|
241
|
+
useEffect3(ensureDexterButtonStyles, []);
|
|
153
242
|
const c = useSignInWithDexter(config);
|
|
154
243
|
const handleClick = async () => {
|
|
155
244
|
try {
|
|
@@ -160,91 +249,37 @@ function SignInWithDexter(props) {
|
|
|
160
249
|
};
|
|
161
250
|
if (c.isVaultConnected) {
|
|
162
251
|
if (!showConnectedChip) return null;
|
|
163
|
-
return /* @__PURE__ */
|
|
164
|
-
/* @__PURE__ */
|
|
165
|
-
/* @__PURE__ */
|
|
166
|
-
c.usdcBalance !== null && /* @__PURE__ */
|
|
252
|
+
return /* @__PURE__ */ jsxs2("span", { className: cx("dx-chip", className), children: [
|
|
253
|
+
/* @__PURE__ */ jsx2("span", { className: "dx-chip__dot", "aria-hidden": true }),
|
|
254
|
+
/* @__PURE__ */ jsx2("span", { children: c.vaultAddress ? shortAddress(c.vaultAddress) : "Connected" }),
|
|
255
|
+
c.usdcBalance !== null && /* @__PURE__ */ jsxs2("span", { className: "dx-chip__bal", children: [
|
|
167
256
|
formatUsd(c.usdcBalance),
|
|
168
257
|
" available"
|
|
169
258
|
] }),
|
|
170
|
-
/* @__PURE__ */
|
|
259
|
+
/* @__PURE__ */ jsx2("button", { type: "button", className: "dx-chip__x", onClick: c.disconnect, "aria-label": "Disconnect", children: "\xD7" })
|
|
171
260
|
] });
|
|
172
261
|
}
|
|
173
|
-
return /* @__PURE__ */
|
|
174
|
-
|
|
262
|
+
return /* @__PURE__ */ jsx2(
|
|
263
|
+
DexterButton,
|
|
175
264
|
{
|
|
176
|
-
|
|
265
|
+
loading: c.status === "pending",
|
|
266
|
+
variant,
|
|
267
|
+
block,
|
|
177
268
|
className,
|
|
178
269
|
onClick: handleClick,
|
|
179
|
-
|
|
180
|
-
style: BUTTON,
|
|
181
|
-
children: c.status === "pending" ? "Signing in\u2026" : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
182
|
-
/* @__PURE__ */ jsx(DexterMark, {}),
|
|
183
|
-
label
|
|
184
|
-
] })
|
|
270
|
+
children: label
|
|
185
271
|
}
|
|
186
272
|
);
|
|
187
273
|
}
|
|
188
|
-
var EMBER = "#ef6820";
|
|
189
|
-
var BUTTON = {
|
|
190
|
-
display: "inline-flex",
|
|
191
|
-
alignItems: "center",
|
|
192
|
-
justifyContent: "center",
|
|
193
|
-
gap: 10,
|
|
194
|
-
padding: "10px 22px",
|
|
195
|
-
border: "1px solid rgba(242, 108, 24, 0.55)",
|
|
196
|
-
borderRadius: 0,
|
|
197
|
-
// sharp corners — Dexter brand drops radius on structural elements
|
|
198
|
-
background: "linear-gradient(135deg, rgba(242, 108, 24, 0.95), rgba(186, 58, 0, 0.88))",
|
|
199
|
-
color: "#fff4ea",
|
|
200
|
-
font: "inherit",
|
|
201
|
-
fontWeight: 600,
|
|
202
|
-
fontSize: "0.78rem",
|
|
203
|
-
letterSpacing: "0.12em",
|
|
204
|
-
textTransform: "uppercase",
|
|
205
|
-
boxShadow: "0 16px 28px rgba(242, 108, 24, 0.25)",
|
|
206
|
-
cursor: "pointer"
|
|
207
|
-
};
|
|
208
|
-
var CHIP = {
|
|
209
|
-
display: "inline-flex",
|
|
210
|
-
alignItems: "center",
|
|
211
|
-
gap: 8,
|
|
212
|
-
padding: "6px 10px",
|
|
213
|
-
borderRadius: 0,
|
|
214
|
-
// sharp — match the brand
|
|
215
|
-
border: "1px solid rgba(239,104,32,0.35)",
|
|
216
|
-
font: "inherit",
|
|
217
|
-
fontVariantNumeric: "tabular-nums"
|
|
218
|
-
};
|
|
219
|
-
var DOT = {
|
|
220
|
-
width: 7,
|
|
221
|
-
height: 7,
|
|
222
|
-
borderRadius: "50%",
|
|
223
|
-
background: EMBER
|
|
224
|
-
};
|
|
225
|
-
var BALANCE = {
|
|
226
|
-
fontWeight: 600,
|
|
227
|
-
opacity: 0.85
|
|
228
|
-
};
|
|
229
|
-
var DISCONNECT = {
|
|
230
|
-
marginLeft: 2,
|
|
231
|
-
border: "none",
|
|
232
|
-
background: "transparent",
|
|
233
|
-
color: "inherit",
|
|
234
|
-
cursor: "pointer",
|
|
235
|
-
fontSize: 16,
|
|
236
|
-
lineHeight: 1,
|
|
237
|
-
opacity: 0.6
|
|
238
|
-
};
|
|
239
274
|
|
|
240
275
|
// src/useDexterWallet.ts
|
|
241
|
-
import { useCallback as useCallback2, useEffect as
|
|
276
|
+
import { useCallback as useCallback2, useEffect as useEffect4, useState as useState2 } from "react";
|
|
242
277
|
var NO_SUPPORT = { rename: false, prune: false, syncAccepted: false };
|
|
243
278
|
function useDexterWallet() {
|
|
244
279
|
const [activeHandle, setHandle] = useState2(() => getActiveHandle());
|
|
245
280
|
const [wallets, setWallets] = useState2(() => listWallets());
|
|
246
281
|
const [support, setSupport] = useState2(NO_SUPPORT);
|
|
247
|
-
|
|
282
|
+
useEffect4(() => {
|
|
248
283
|
const sync = () => {
|
|
249
284
|
setHandle(getActiveHandle());
|
|
250
285
|
setWallets(listWallets());
|
|
@@ -280,6 +315,8 @@ function useDexterWallet() {
|
|
|
280
315
|
};
|
|
281
316
|
}
|
|
282
317
|
export {
|
|
318
|
+
DexterButton,
|
|
319
|
+
DexterMark,
|
|
283
320
|
SignInWithDexter,
|
|
284
321
|
useDexterWallet,
|
|
285
322
|
useSignInWithDexter
|