@dexterai/connect 0.18.0 → 0.20.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/{chunk-Y22JFT53.js → chunk-2QZ5QLGI.js} +54 -7
- package/dist/{chunk-S7G2ZZOO.js → chunk-2WETR5DJ.js} +11 -12
- package/dist/index.d.ts +3 -29
- package/dist/index.js +9 -3
- package/dist/react.d.ts +35 -3
- package/dist/react.js +238 -14
- package/dist/{signals-BaXobUfB.d.ts → signals-qc4rDyQ6.d.ts} +50 -1
- package/dist/worldid.js +1 -1
- package/package.json +3 -1
|
@@ -124,6 +124,24 @@ function onStorageEvent(e) {
|
|
|
124
124
|
}
|
|
125
125
|
var ACTIVE_WALLET_STORAGE_KEY = ACTIVE_HANDLE_KEY;
|
|
126
126
|
|
|
127
|
+
// src/policy.ts
|
|
128
|
+
var SESSION_TTL_30D = "2592000";
|
|
129
|
+
function usdToAtomic(input) {
|
|
130
|
+
const cleaned = input.trim().replace(/^\$/, "").replace(/,/g, "");
|
|
131
|
+
if (!/^\d+(\.\d{1,6})?$/.test(cleaned)) return null;
|
|
132
|
+
const [whole, frac = ""] = cleaned.split(".");
|
|
133
|
+
try {
|
|
134
|
+
return BigInt(whole) * 1000000n + BigInt((frac + "000000").slice(0, 6));
|
|
135
|
+
} catch {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function authoredPolicy(usdInput) {
|
|
140
|
+
const atomic = usdToAtomic(usdInput);
|
|
141
|
+
if (atomic === null || atomic <= 0n) return null;
|
|
142
|
+
return { spendLimitAtomic: atomic.toString(), sessionTtlSeconds: SESSION_TTL_30D };
|
|
143
|
+
}
|
|
144
|
+
|
|
127
145
|
// src/enroll.ts
|
|
128
146
|
import { startRegistration } from "@simplewebauthn/browser";
|
|
129
147
|
|
|
@@ -218,11 +236,13 @@ var DEFAULT_RP_ID = "dexter.cash";
|
|
|
218
236
|
var DEFAULT_WALLET_NAME = "Dexter Wallet";
|
|
219
237
|
async function createWallet(config = {}) {
|
|
220
238
|
if (shouldUsePopup(config.transport)) {
|
|
221
|
-
|
|
239
|
+
const result = await openCeremonyPopup("create", {
|
|
222
240
|
connectHost: config.connectHost,
|
|
223
241
|
name: config.name,
|
|
224
242
|
apiBase: config.apiBase
|
|
225
243
|
});
|
|
244
|
+
setActiveHandle(result.handle, config.name, result.credentialId);
|
|
245
|
+
return result;
|
|
226
246
|
}
|
|
227
247
|
if (typeof navigator === "undefined" || !navigator.credentials) {
|
|
228
248
|
throw new ConnectError("webauthn_unsupported", "WebAuthn unavailable in this environment");
|
|
@@ -247,7 +267,12 @@ async function createWallet(config = {}) {
|
|
|
247
267
|
config.onPhase?.("verifying");
|
|
248
268
|
const enrolled = await submitEnrollComplete(apiBase, regResponse);
|
|
249
269
|
config.onPhase?.("finalizing");
|
|
250
|
-
const init = await initializeVault(
|
|
270
|
+
const init = await initializeVault(
|
|
271
|
+
apiBase,
|
|
272
|
+
enrolled.userHandle,
|
|
273
|
+
enrolled.credentialId,
|
|
274
|
+
config.spendPolicy
|
|
275
|
+
);
|
|
251
276
|
setActiveHandle(enrolled.userHandle, name, enrolled.credentialId);
|
|
252
277
|
return {
|
|
253
278
|
handle: enrolled.userHandle,
|
|
@@ -288,11 +313,16 @@ async function submitEnrollComplete(apiBase, response) {
|
|
|
288
313
|
if (!res.ok) throw new ConnectError(await readErrorCode(res), `enroll/complete ${res.status}`);
|
|
289
314
|
return await res.json();
|
|
290
315
|
}
|
|
291
|
-
async function initializeVault(apiBase, userHandle, credentialId) {
|
|
316
|
+
async function initializeVault(apiBase, userHandle, credentialId, spendPolicy) {
|
|
317
|
+
const body = { userHandle, credentialId, coolingOffSeconds: 0 };
|
|
318
|
+
if (spendPolicy) {
|
|
319
|
+
body.spendLimitAtomic = spendPolicy.spendLimitAtomic;
|
|
320
|
+
body.sessionTtlSeconds = SESSION_TTL_30D;
|
|
321
|
+
}
|
|
292
322
|
const res = await fetch(`${apiBase}/api/passkey-vault-anon/initialize`, {
|
|
293
323
|
method: "POST",
|
|
294
324
|
headers: { "content-type": "application/json" },
|
|
295
|
-
body: JSON.stringify(
|
|
325
|
+
body: JSON.stringify(body)
|
|
296
326
|
});
|
|
297
327
|
if (!res.ok) throw new ConnectError(await readErrorCode(res), `initialize ${res.status}`);
|
|
298
328
|
return await res.json();
|
|
@@ -312,10 +342,14 @@ var DEFAULT_API_BASE2 = "https://api.dexter.cash";
|
|
|
312
342
|
var ANON_SIGN_BASE = "/api/passkey-anon/sign";
|
|
313
343
|
async function passkeyLogin(config = {}, onPhase) {
|
|
314
344
|
if (shouldUsePopup(config.transport)) {
|
|
315
|
-
|
|
345
|
+
const result2 = await openCeremonyPopup("signin", {
|
|
316
346
|
connectHost: config.connectHost,
|
|
317
347
|
apiBase: config.apiBase
|
|
318
348
|
});
|
|
349
|
+
if (result2.vault) {
|
|
350
|
+
setActiveHandle(result2.vault.userHandle, void 0, result2.vault.credentialId);
|
|
351
|
+
}
|
|
352
|
+
return result2;
|
|
319
353
|
}
|
|
320
354
|
if (!browserSupportsWebAuthn()) {
|
|
321
355
|
throw new ConnectError("webauthn_unsupported", "WebAuthn unavailable in this environment");
|
|
@@ -331,15 +365,25 @@ async function passkeyLogin(config = {}, onPhase) {
|
|
|
331
365
|
throw new ConnectError("webauthn_failed", err instanceof Error ? err.message : String(err));
|
|
332
366
|
}
|
|
333
367
|
onPhase?.("verifying");
|
|
334
|
-
|
|
368
|
+
const result = await submitLogin(apiBase, response);
|
|
369
|
+
if (result.vault) {
|
|
370
|
+
setActiveHandle(result.vault.userHandle, void 0, result.vault.credentialId);
|
|
371
|
+
}
|
|
372
|
+
return result;
|
|
335
373
|
}
|
|
336
374
|
async function continueWithDexter(config = {}, onPhase) {
|
|
337
375
|
if (shouldUsePopup(config.transport)) {
|
|
338
|
-
|
|
376
|
+
const result2 = await openCeremonyPopup("continue", {
|
|
339
377
|
connectHost: config.connectHost,
|
|
340
378
|
name: config.name,
|
|
341
379
|
apiBase: config.apiBase
|
|
342
380
|
});
|
|
381
|
+
if (result2.kind === "create") {
|
|
382
|
+
setActiveHandle(result2.handle, config.name, result2.credentialId);
|
|
383
|
+
} else if (result2.vault) {
|
|
384
|
+
setActiveHandle(result2.vault.userHandle, void 0, result2.vault.credentialId);
|
|
385
|
+
}
|
|
386
|
+
return result2;
|
|
343
387
|
}
|
|
344
388
|
if (getActiveHandle()) {
|
|
345
389
|
const result2 = await passkeyLogin(config, onPhase);
|
|
@@ -623,6 +667,9 @@ export {
|
|
|
623
667
|
forgetWallet,
|
|
624
668
|
subscribe,
|
|
625
669
|
ACTIVE_WALLET_STORAGE_KEY,
|
|
670
|
+
SESSION_TTL_30D,
|
|
671
|
+
usdToAtomic,
|
|
672
|
+
authoredPolicy,
|
|
626
673
|
createWallet,
|
|
627
674
|
passkeyLogin,
|
|
628
675
|
continueWithDexter,
|
|
@@ -6,22 +6,21 @@ var BUTTON_CSS = `
|
|
|
6
6
|
@keyframes dx-spin { to { transform: rotate(360deg); } }
|
|
7
7
|
@keyframes dx-pulse { 0%,100% { opacity: 1; } 50% { opacity: .6; } }
|
|
8
8
|
.dx-btn{
|
|
9
|
-
--dx-ember:#f26c18; --dx-ember-2:#ba3a00; --dx-fg:#fff4ea; --dx-radius:0px;
|
|
10
9
|
position:relative; display:inline-flex; align-items:center; justify-content:center; gap:10px;
|
|
11
|
-
padding:11px 22px; border:1px solid color-mix(in srgb,var(--dx-ember) 55%,transparent);
|
|
12
|
-
border-radius:var(--dx-radius);
|
|
13
|
-
background:linear-gradient(135deg,var(--dx-ember),var(--dx-ember-2));
|
|
14
|
-
color:var(--dx-fg); font:inherit; font-weight:600; font-size:.78rem; letter-spacing:.12em;
|
|
10
|
+
padding:11px 22px; border:1px solid color-mix(in srgb,var(--dx-ember,#f26c18) 55%,transparent);
|
|
11
|
+
border-radius:var(--dx-radius,0px);
|
|
12
|
+
background:linear-gradient(135deg,var(--dx-ember,#f26c18),var(--dx-ember-2,#ba3a00));
|
|
13
|
+
color:var(--dx-fg,#fff4ea); font:inherit; font-weight:600; font-size:.78rem; letter-spacing:.12em;
|
|
15
14
|
text-transform:uppercase; cursor:pointer; -webkit-tap-highlight-color:transparent;
|
|
16
|
-
box-shadow:0 14px 26px color-mix(in srgb,var(--dx-ember) 24%,transparent);
|
|
15
|
+
box-shadow:0 14px 26px color-mix(in srgb,var(--dx-ember,#f26c18) 24%,transparent);
|
|
17
16
|
transition:transform .16s ease, box-shadow .16s ease, filter .16s ease, background .16s ease;
|
|
18
17
|
}
|
|
19
|
-
.dx-btn:hover{ transform:translateY(-1px); filter:brightness(1.07); box-shadow:0 20px 34px color-mix(in srgb,var(--dx-ember) 32%,transparent); }
|
|
20
|
-
.dx-btn:active{ transform:translateY(0); filter:brightness(.97); box-shadow:0 8px 16px color-mix(in srgb,var(--dx-ember) 22%,transparent); }
|
|
21
|
-
.dx-btn:focus-visible{ outline:none; box-shadow:0 0 0 3px color-mix(in srgb,var(--dx-ember) 38%,transparent); }
|
|
18
|
+
.dx-btn:hover{ transform:translateY(-1px); filter:brightness(1.07); box-shadow:0 20px 34px color-mix(in srgb,var(--dx-ember,#f26c18) 32%,transparent); }
|
|
19
|
+
.dx-btn:active{ transform:translateY(0); filter:brightness(.97); box-shadow:0 8px 16px color-mix(in srgb,var(--dx-ember,#f26c18) 22%,transparent); }
|
|
20
|
+
.dx-btn:focus-visible{ outline:none; box-shadow:0 0 0 3px color-mix(in srgb,var(--dx-ember,#f26c18) 38%,transparent); }
|
|
22
21
|
.dx-btn:disabled{ cursor:default; filter:saturate(.85) brightness(.98); }
|
|
23
|
-
.dx-btn--secondary{ background:transparent; color:var(--dx-ember); box-shadow:none; border-color:color-mix(in srgb,var(--dx-ember) 45%,transparent); }
|
|
24
|
-
.dx-btn--secondary:hover{ background:color-mix(in srgb,var(--dx-ember) 9%,transparent); filter:none; box-shadow:none; }
|
|
22
|
+
.dx-btn--secondary{ background:transparent; color:var(--dx-ember,#f26c18); box-shadow:none; border-color:color-mix(in srgb,var(--dx-ember,#f26c18) 45%,transparent); }
|
|
23
|
+
.dx-btn--secondary:hover{ background:color-mix(in srgb,var(--dx-ember,#f26c18) 9%,transparent); filter:none; box-shadow:none; }
|
|
25
24
|
.dx-btn--block{ width:100%; }
|
|
26
25
|
.dx-btn__mark{ flex-shrink:0; }
|
|
27
26
|
.dx-btn__spin{ width:15px; height:15px; flex-shrink:0; border-radius:50%;
|
|
@@ -29,7 +28,7 @@ var BUTTON_CSS = `
|
|
|
29
28
|
animation:dx-spin .7s linear infinite; }
|
|
30
29
|
.dx-btn__doing{ animation:dx-pulse 1.4s ease-in-out infinite; }
|
|
31
30
|
.dx-chip{ display:inline-flex; align-items:center; gap:8px; padding:6px 10px; font:inherit;
|
|
32
|
-
font-variant-numeric:tabular-nums; border-radius:var(--dx-radius,
|
|
31
|
+
font-variant-numeric:tabular-nums; border-radius:var(--dx-radius,0px);
|
|
33
32
|
border:1px solid color-mix(in srgb,var(--dx-ember,#f26c18) 35%,transparent); }
|
|
34
33
|
.dx-chip__dot{ width:7px; height:7px; border-radius:50%; background:var(--dx-ember,#f26c18); }
|
|
35
34
|
.dx-chip__bal{ font-weight:600; opacity:.85; }
|
package/dist/index.d.ts
CHANGED
|
@@ -1,33 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { A as ACTIVE_WALLET_STORAGE_KEY,
|
|
1
|
+
import { S as SignInResult, C as CreateWalletResult, a as CreateWalletConfig, b as CeremonyPhase, D as DexterConnectConfig, c as ConnectVault, I as IdentityKind } from './signals-qc4rDyQ6.js';
|
|
2
|
+
export { A as ACTIVE_WALLET_STORAGE_KEY, d as ConnectError, e as IdentityInput, P as PasskeyLoginTokens, f as PasskeySignalSupport, R as ResolvedIdentity, g as SESSION_TTL_30D, h as SpendPolicy, i as StoredWallet, j as authoredPolicy, k as createWallet, l as ejectActiveWallet, m as forgetWallet, n as getActiveHandle, o as getCredentialId, p as listWallets, q as passkeySignalSupport, r as prunePasskey, s as renamePasskey, t as resolveIdentity, u as setActiveHandle, v as subscribeWallet, w as switchWallet, x as syncAcceptedPasskeys, y as usdToAtomic } from './signals-qc4rDyQ6.js';
|
|
3
3
|
import { DexterApiBrowserPasskeySigner } from '@dexterai/vault/signers/browser';
|
|
4
4
|
|
|
5
|
-
interface CreateWalletConfig extends DexterConnectConfig {
|
|
6
|
-
/** Label for the passkey in the OS keychain AND the wallet roster. Set at
|
|
7
|
-
* creation — the only moment naming is guaranteed to stick. Default "Dexter Wallet". */
|
|
8
|
-
name?: string;
|
|
9
|
-
/** RP id for the new credential. Default "dexter.cash". */
|
|
10
|
-
rpId?: string;
|
|
11
|
-
/** Called as the ceremony progresses, for live "connecting steps" UI:
|
|
12
|
-
* challenge → passkey → verifying → finalizing. */
|
|
13
|
-
onPhase?: (phase: CeremonyPhase) => void;
|
|
14
|
-
}
|
|
15
|
-
interface CreateWalletResult {
|
|
16
|
-
/** Server-minted 16-byte user handle, base64url — the vault identity. */
|
|
17
|
-
handle: string;
|
|
18
|
-
/** base64url credential id of the new passkey. */
|
|
19
|
-
credentialId: string;
|
|
20
|
-
/** The freshly initialized vault (swig not yet deployed; deploys lazily). */
|
|
21
|
-
vault: ConnectVault;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Mint a brand-new Dexter wallet (passkey + vault) and make it the active wallet.
|
|
25
|
-
*
|
|
26
|
-
* One passkey approval. Throws ConnectError on any failed leg (the `code` is the
|
|
27
|
-
* server's error string, or webauthn_failed / no_credential for the ceremony).
|
|
28
|
-
*/
|
|
29
|
-
declare function createWallet(config?: CreateWalletConfig): Promise<CreateWalletResult>;
|
|
30
|
-
|
|
31
5
|
/**
|
|
32
6
|
* "Sign in with Dexter" — the discoverable-credential login ceremony.
|
|
33
7
|
*
|
|
@@ -247,4 +221,4 @@ interface EnableAgentSpendResult {
|
|
|
247
221
|
*/
|
|
248
222
|
declare function enableAgentSpend(id: AgentSpendIdentity, vaultPda: string, apiOrigin: string, credentialId?: string | null): Promise<EnableAgentSpendResult>;
|
|
249
223
|
|
|
250
|
-
export { AgentSpendError, type AgentSpendIdentity, type AgentSpendStatus, type AgentSpendTab, type AnonChallengeResult, type AnonServerPolicy, type AutomaticAgentSpend, CeremonyPhase, ConnectVault, type ContinueResult,
|
|
224
|
+
export { AgentSpendError, type AgentSpendIdentity, type AgentSpendStatus, type AgentSpendTab, type AnonChallengeResult, type AnonServerPolicy, type AutomaticAgentSpend, CeremonyPhase, ConnectVault, type ContinueResult, CreateWalletConfig, CreateWalletResult, DexterConnectConfig, type EnableAgentSpendResult, IdentityKind, type RawAgentSpendSession, type RawAgentSpendStatus, type RevokeAgentSpendResult, SignInResult, assembleAgentSpendStatus, ceremonyPhaseLabel, continueWithDexter, createAnonServerPolicy, createPasskeySigner, describeAgentSpendError, enableAgentSpend, passkeyLogin, revokeAgentSpend };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ACTIVE_WALLET_STORAGE_KEY,
|
|
3
3
|
ConnectError,
|
|
4
|
+
SESSION_TTL_30D,
|
|
5
|
+
authoredPolicy,
|
|
4
6
|
base64urlToBase64,
|
|
5
7
|
bytesToBase64url,
|
|
6
8
|
ceremonyPhaseLabel,
|
|
@@ -21,8 +23,9 @@ import {
|
|
|
21
23
|
setActiveHandle,
|
|
22
24
|
subscribe,
|
|
23
25
|
switchWallet,
|
|
24
|
-
syncAcceptedPasskeys
|
|
25
|
-
|
|
26
|
+
syncAcceptedPasskeys,
|
|
27
|
+
usdToAtomic
|
|
28
|
+
} from "./chunk-2QZ5QLGI.js";
|
|
26
29
|
|
|
27
30
|
// src/agentSpend.ts
|
|
28
31
|
import { PublicKey } from "@solana/web3.js";
|
|
@@ -175,7 +178,9 @@ export {
|
|
|
175
178
|
ACTIVE_WALLET_STORAGE_KEY,
|
|
176
179
|
AgentSpendError,
|
|
177
180
|
ConnectError,
|
|
181
|
+
SESSION_TTL_30D,
|
|
178
182
|
assembleAgentSpendStatus,
|
|
183
|
+
authoredPolicy,
|
|
179
184
|
ceremonyPhaseLabel,
|
|
180
185
|
continueWithDexter,
|
|
181
186
|
createAnonServerPolicy,
|
|
@@ -197,5 +202,6 @@ export {
|
|
|
197
202
|
setActiveHandle,
|
|
198
203
|
subscribe as subscribeWallet,
|
|
199
204
|
switchWallet,
|
|
200
|
-
syncAcceptedPasskeys
|
|
205
|
+
syncAcceptedPasskeys,
|
|
206
|
+
usdToAtomic
|
|
201
207
|
};
|
package/dist/react.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DexterApiBrowserPasskeySigner } from '@dexterai/vault/signers/browser';
|
|
2
|
-
import {
|
|
2
|
+
import { b as CeremonyPhase, S as SignInResult, P as PasskeyLoginTokens, c as ConnectVault, d as ConnectError, i as StoredWallet, f as PasskeySignalSupport, R as ResolvedIdentity, C as CreateWalletResult } from './signals-qc4rDyQ6.js';
|
|
3
3
|
import { ReactElement, ReactNode } from 'react';
|
|
4
4
|
|
|
5
5
|
type ConnectStatus = 'idle' | 'pending' | 'done' | 'error';
|
|
@@ -149,8 +149,10 @@ interface DexterWalletMenuProps {
|
|
|
149
149
|
avatarInitial?: string;
|
|
150
150
|
/** "Manage wallet" → the consumer's wallet page. Row hidden if omitted. */
|
|
151
151
|
onManageWallet?: () => void;
|
|
152
|
-
/**
|
|
152
|
+
/** Eject row → the consumer ejects/resets (guard + perform on its side). Row hidden if omitted. */
|
|
153
153
|
onStartFresh?: () => void;
|
|
154
|
+
/** Label for the eject/reset row. Default "Eject wallet". */
|
|
155
|
+
startFreshLabel?: string;
|
|
154
156
|
/** Sign-in/save UI revealed when "Save your wallet" is tapped (e.g. <SignInWithDexter/>). Row hidden if omitted. */
|
|
155
157
|
saveSlot?: ReactNode;
|
|
156
158
|
/** Short hint shown above the save UI. */
|
|
@@ -168,4 +170,34 @@ interface UseIdentityConfig {
|
|
|
168
170
|
}
|
|
169
171
|
declare function useIdentity({ accountToken }: UseIdentityConfig): ResolvedIdentity;
|
|
170
172
|
|
|
171
|
-
|
|
173
|
+
interface AllowanceChipsProps {
|
|
174
|
+
/** The authored USD amount as a raw string, or null when nothing is chosen.
|
|
175
|
+
* NONE selected initially → pass null. Preset chips echo '5' / '20' / '50';
|
|
176
|
+
* Custom echoes whatever the user types. */
|
|
177
|
+
value: string | null;
|
|
178
|
+
/** Fired with the raw USD string (or null when Custom is opened empty). */
|
|
179
|
+
onChange: (usd: string | null) => void;
|
|
180
|
+
/** Extra className composed after the brand classes. */
|
|
181
|
+
className?: string;
|
|
182
|
+
}
|
|
183
|
+
/** The consent-at-birth allowance chips. */
|
|
184
|
+
declare function AllowanceChips(props: AllowanceChipsProps): ReactElement;
|
|
185
|
+
|
|
186
|
+
interface CreateWalletPanelProps {
|
|
187
|
+
/** Fired with the minted wallet the moment creation succeeds. */
|
|
188
|
+
onCreated?: (result: CreateWalletResult) => void;
|
|
189
|
+
/** Fired with the typed error if the ceremony fails. */
|
|
190
|
+
onError?: (error: ConnectError) => void;
|
|
191
|
+
/** dexter-api base. Default https://api.dexter.cash (createWallet's default). */
|
|
192
|
+
apiBase?: string;
|
|
193
|
+
/** Where the WebAuthn ceremony runs. Default 'auto' (createWallet's default). */
|
|
194
|
+
transport?: 'auto' | 'popup' | 'inline';
|
|
195
|
+
/** Render the optional "Name your wallet" field. Default true. */
|
|
196
|
+
showName?: boolean;
|
|
197
|
+
/** Extra className composed after the brand classes. */
|
|
198
|
+
className?: string;
|
|
199
|
+
}
|
|
200
|
+
/** The turnkey consent-at-birth create panel. */
|
|
201
|
+
declare function CreateWalletPanel(props: CreateWalletPanelProps): ReactElement;
|
|
202
|
+
|
|
203
|
+
export { AllowanceChips, type AllowanceChipsProps, type ConnectStatus, CreateWalletPanel, type CreateWalletPanelProps, DexterButton, type DexterButtonProps, DexterMark, DexterWalletChip, type DexterWalletChipProps, DexterWalletMenu, type DexterWalletMenuProps, SignInWithDexter, type SignInWithDexterProps, type UseDexterWallet, type UseIdentityConfig, type UseSignInWithDexter, type UseSignInWithDexterConfig, useDexterWallet, useIdentity, useSignInWithDexter };
|
package/dist/react.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ConnectError,
|
|
3
|
+
authoredPolicy,
|
|
3
4
|
ceremonyPhaseLabel,
|
|
4
5
|
createPasskeySigner,
|
|
6
|
+
createWallet,
|
|
5
7
|
ejectActiveWallet,
|
|
6
8
|
getActiveHandle,
|
|
7
9
|
getCredentialId,
|
|
@@ -14,13 +16,13 @@ import {
|
|
|
14
16
|
setActiveHandle,
|
|
15
17
|
subscribe,
|
|
16
18
|
switchWallet
|
|
17
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-2QZ5QLGI.js";
|
|
18
20
|
import {
|
|
19
21
|
DexterButton,
|
|
20
22
|
DexterMark,
|
|
21
23
|
cx,
|
|
22
24
|
ensureDexterButtonStyles
|
|
23
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-2WETR5DJ.js";
|
|
24
26
|
|
|
25
27
|
// src/useSignInWithDexter.ts
|
|
26
28
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
@@ -233,35 +235,34 @@ import { useEffect as useEffect4 } from "react";
|
|
|
233
235
|
var STYLE_ID = "dexter-connect-wallet-kit-styles";
|
|
234
236
|
var WALLET_KIT_CSS = `
|
|
235
237
|
.dx-wchip{
|
|
236
|
-
--dx-ember:#f26c18; --dx-ember-2:#ba3a00; --dx-fg:#fff4ea; --dx-radius:0px;
|
|
237
238
|
display:inline-flex; align-items:center; gap:9px; max-width:240px;
|
|
238
239
|
padding:6px 12px 6px 7px; font:inherit; font-weight:600; font-size:.74rem;
|
|
239
240
|
letter-spacing:.1em; text-transform:uppercase; cursor:pointer; background:transparent;
|
|
240
|
-
color:inherit; border:1px solid color-mix(in srgb,var(--dx-ember) 42%,transparent);
|
|
241
|
-
border-radius:var(--dx-radius); -webkit-tap-highlight-color:transparent;
|
|
241
|
+
color:inherit; border:1px solid color-mix(in srgb,var(--dx-ember,#f26c18) 42%,transparent);
|
|
242
|
+
border-radius:var(--dx-radius,0px); -webkit-tap-highlight-color:transparent;
|
|
242
243
|
transition:filter .16s ease, box-shadow .16s ease, border-color .16s ease;
|
|
243
244
|
}
|
|
244
|
-
.dx-wchip:hover{ filter:brightness(1.08); box-shadow:0 8px 18px color-mix(in srgb,var(--dx-ember) 18%,transparent); }
|
|
245
|
-
.dx-wchip:focus-visible{ outline:none; box-shadow:0 0 0 3px color-mix(in srgb,var(--dx-ember) 34%,transparent); }
|
|
245
|
+
.dx-wchip:hover{ filter:brightness(1.08); box-shadow:0 8px 18px color-mix(in srgb,var(--dx-ember,#f26c18) 18%,transparent); }
|
|
246
|
+
.dx-wchip:focus-visible{ outline:none; box-shadow:0 0 0 3px color-mix(in srgb,var(--dx-ember,#f26c18) 34%,transparent); }
|
|
246
247
|
.dx-wchip--signedout{ border-color:color-mix(in srgb,currentColor 22%,transparent); padding-left:12px; }
|
|
247
248
|
.dx-wchip__avatar{
|
|
248
249
|
width:22px; height:22px; flex-shrink:0; display:inline-flex; align-items:center; justify-content:center;
|
|
249
250
|
border-radius:50%; overflow:hidden; font-size:.72rem; font-weight:700; letter-spacing:0; line-height:1;
|
|
250
|
-
background:linear-gradient(135deg,var(--dx-ember),var(--dx-ember-2)); color:var(--dx-fg);
|
|
251
|
+
background:linear-gradient(135deg,var(--dx-ember,#f26c18),var(--dx-ember-2,#ba3a00)); color:var(--dx-fg,#fff4ea);
|
|
251
252
|
}
|
|
252
253
|
.dx-wchip__avatar img{ width:100%; height:100%; object-fit:cover; }
|
|
253
254
|
.dx-wchip__label{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
254
255
|
|
|
255
|
-
.dx-wmenu{
|
|
256
|
+
.dx-wmenu{ display:flex; flex-direction:column; min-width:248px; }
|
|
256
257
|
.dx-wmenu__id{ display:flex; align-items:center; gap:10px; padding:13px 15px; border-bottom:1px solid color-mix(in srgb,currentColor 12%,transparent); }
|
|
257
|
-
.dx-wmenu__avatar{ width:32px; height:32px; flex-shrink:0; display:inline-flex; align-items:center; justify-content:center; border-radius:50%; font-weight:700; font-size:.85rem; line-height:1; background:linear-gradient(135deg,var(--dx-ember),var(--dx-ember-2)); color:var(--dx-fg); }
|
|
258
|
+
.dx-wmenu__avatar{ width:32px; height:32px; flex-shrink:0; display:inline-flex; align-items:center; justify-content:center; border-radius:50%; font-weight:700; font-size:.85rem; line-height:1; background:linear-gradient(135deg,var(--dx-ember,#f26c18),var(--dx-ember-2,#ba3a00)); color:var(--dx-fg,#fff4ea); }
|
|
258
259
|
.dx-wmenu__meta{ display:flex; flex-direction:column; gap:2px; min-width:0; }
|
|
259
260
|
.dx-wmenu__name{ font-weight:700; font-size:.9rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
260
261
|
.dx-wmenu__sub{ font-size:.66rem; letter-spacing:.12em; text-transform:uppercase; opacity:.55; }
|
|
261
262
|
.dx-wmenu__list{ display:flex; flex-direction:column; padding:6px; }
|
|
262
263
|
.dx-wmenu__item{ display:flex; align-items:center; justify-content:space-between; gap:10px; width:100%; padding:10px 12px; font:inherit; font-size:.82rem; font-weight:600; text-align:left; background:transparent; border:none; color:inherit; cursor:pointer; transition:background .12s ease; }
|
|
263
|
-
.dx-wmenu__item:hover{ background:color-mix(in srgb,var(--dx-ember) 10%,transparent); }
|
|
264
|
-
.dx-wmenu__item--danger{ color
|
|
264
|
+
.dx-wmenu__item:hover{ background:color-mix(in srgb,var(--dx-ember,#f26c18) 10%,transparent); }
|
|
265
|
+
.dx-wmenu__item--danger{ color:var(--dx-danger,#e5552e); }
|
|
265
266
|
.dx-wmenu__icon{ opacity:.45; font-size:.9rem; }
|
|
266
267
|
.dx-wmenu__back{ border-bottom:1px solid color-mix(in srgb,currentColor 10%,transparent); opacity:.85; }
|
|
267
268
|
.dx-wmenu__save{ display:flex; flex-direction:column; gap:9px; padding:13px 15px; }
|
|
@@ -302,7 +303,16 @@ function DexterWalletChip(props) {
|
|
|
302
303
|
import { useEffect as useEffect5, useState as useState3 } from "react";
|
|
303
304
|
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
304
305
|
function DexterWalletMenu(props) {
|
|
305
|
-
const {
|
|
306
|
+
const {
|
|
307
|
+
walletLabel,
|
|
308
|
+
avatarInitial,
|
|
309
|
+
onManageWallet,
|
|
310
|
+
onStartFresh,
|
|
311
|
+
startFreshLabel = "Eject wallet",
|
|
312
|
+
saveSlot,
|
|
313
|
+
saveHint,
|
|
314
|
+
className
|
|
315
|
+
} = props;
|
|
306
316
|
useEffect5(ensureWalletKitStyles, []);
|
|
307
317
|
const [showSave, setShowSave] = useState3(false);
|
|
308
318
|
const initial = (avatarInitial ?? walletLabel.trim().charAt(0) ?? "D").toUpperCase();
|
|
@@ -347,7 +357,7 @@ function DexterWalletMenu(props) {
|
|
|
347
357
|
className: "dx-wmenu__item dx-wmenu__item--danger",
|
|
348
358
|
onClick: onStartFresh,
|
|
349
359
|
children: [
|
|
350
|
-
/* @__PURE__ */ jsx3("span", { children:
|
|
360
|
+
/* @__PURE__ */ jsx3("span", { children: startFreshLabel }),
|
|
351
361
|
/* @__PURE__ */ jsx3("span", { className: "dx-wmenu__icon", "aria-hidden": "true", children: "\u27F5" })
|
|
352
362
|
]
|
|
353
363
|
}
|
|
@@ -368,7 +378,221 @@ function useIdentity({ accountToken }) {
|
|
|
368
378
|
[accountToken, activeHandle]
|
|
369
379
|
);
|
|
370
380
|
}
|
|
381
|
+
|
|
382
|
+
// src/AllowanceChips.tsx
|
|
383
|
+
import { useEffect as useEffect6, useState as useState4 } from "react";
|
|
384
|
+
|
|
385
|
+
// src/consentStyles.ts
|
|
386
|
+
var STYLE_ID2 = "dexter-connect-consent-styles";
|
|
387
|
+
var CONSENT_CSS = `
|
|
388
|
+
.dx-allow{
|
|
389
|
+
display:flex; flex-wrap:wrap; gap:8px; align-items:center;
|
|
390
|
+
}
|
|
391
|
+
.dx-allow__chip{
|
|
392
|
+
display:inline-flex; align-items:center; justify-content:center; padding:9px 15px;
|
|
393
|
+
font:inherit; font-weight:600; font-size:.78rem; letter-spacing:.12em; text-transform:uppercase;
|
|
394
|
+
font-variant-numeric:tabular-nums; cursor:pointer; background:transparent; color:inherit;
|
|
395
|
+
border:1px solid color-mix(in srgb,var(--dx-ember,#f26c18) 45%,transparent);
|
|
396
|
+
border-radius:var(--dx-radius,0px); -webkit-tap-highlight-color:transparent;
|
|
397
|
+
transition:filter .16s ease, box-shadow .16s ease, border-color .16s ease, background .16s ease, color .16s ease;
|
|
398
|
+
}
|
|
399
|
+
.dx-allow__chip:hover{ border-color:color-mix(in srgb,var(--dx-ember,#f26c18) 70%,transparent); filter:brightness(1.05); }
|
|
400
|
+
.dx-allow__chip:focus-visible{ outline:none; box-shadow:0 0 0 3px color-mix(in srgb,var(--dx-ember,#f26c18) 34%,transparent); }
|
|
401
|
+
.dx-allow__chip--active{
|
|
402
|
+
background:linear-gradient(135deg,var(--dx-ember,#f26c18),var(--dx-ember-2,#ba3a00));
|
|
403
|
+
color:var(--dx-fg,#fff4ea); border-color:color-mix(in srgb,var(--dx-ember,#f26c18) 55%,transparent);
|
|
404
|
+
box-shadow:0 10px 22px color-mix(in srgb,var(--dx-ember,#f26c18) 22%,transparent);
|
|
405
|
+
}
|
|
406
|
+
.dx-allow__input{
|
|
407
|
+
flex:1 1 130px; min-width:120px; padding:9px 13px; font:inherit; font-size:.9rem;
|
|
408
|
+
font-variant-numeric:tabular-nums; color:inherit; background:transparent;
|
|
409
|
+
border:1px solid color-mix(in srgb,var(--dx-ember,#f26c18) 45%,transparent);
|
|
410
|
+
border-radius:var(--dx-radius,0px); -webkit-tap-highlight-color:transparent;
|
|
411
|
+
transition:border-color .16s ease, box-shadow .16s ease;
|
|
412
|
+
}
|
|
413
|
+
.dx-allow__input:focus, .dx-allow__input:focus-visible{
|
|
414
|
+
outline:none; border-color:color-mix(in srgb,var(--dx-ember,#f26c18) 70%,transparent);
|
|
415
|
+
box-shadow:0 0 0 3px color-mix(in srgb,var(--dx-ember,#f26c18) 30%,transparent);
|
|
416
|
+
}
|
|
417
|
+
.dx-allow__input::placeholder{ color:currentColor; opacity:.5; letter-spacing:.02em; text-transform:none; }
|
|
418
|
+
|
|
419
|
+
.dx-cwp{
|
|
420
|
+
display:flex; flex-direction:column; gap:16px; font:inherit;
|
|
421
|
+
}
|
|
422
|
+
.dx-cwp__field{ display:flex; flex-direction:column; gap:8px; }
|
|
423
|
+
.dx-cwp__label{ font-size:.7rem; font-weight:700; letter-spacing:.14em; text-transform:uppercase; opacity:.62; }
|
|
424
|
+
.dx-cwp__name{
|
|
425
|
+
padding:10px 13px; font:inherit; font-size:.95rem; color:inherit; background:transparent;
|
|
426
|
+
border:1px solid color-mix(in srgb,currentColor 22%,transparent); border-radius:var(--dx-radius,0px);
|
|
427
|
+
-webkit-tap-highlight-color:transparent; transition:border-color .16s ease, box-shadow .16s ease;
|
|
428
|
+
}
|
|
429
|
+
.dx-cwp__name:focus, .dx-cwp__name:focus-visible{
|
|
430
|
+
outline:none; border-color:color-mix(in srgb,var(--dx-ember,#f26c18) 60%,transparent);
|
|
431
|
+
box-shadow:0 0 0 3px color-mix(in srgb,var(--dx-ember,#f26c18) 26%,transparent);
|
|
432
|
+
}
|
|
433
|
+
.dx-cwp__name::placeholder{ color:currentColor; opacity:.42; }
|
|
434
|
+
.dx-cwp__fine{ font-size:.76rem; line-height:1.5; opacity:.66; }
|
|
435
|
+
.dx-cwp__err{ font-size:.78rem; line-height:1.45; color:var(--dx-danger,#e5552e); }
|
|
436
|
+
`;
|
|
437
|
+
function ensureConsentStyles() {
|
|
438
|
+
if (typeof document === "undefined") return;
|
|
439
|
+
if (document.getElementById(STYLE_ID2)) return;
|
|
440
|
+
const el = document.createElement("style");
|
|
441
|
+
el.id = STYLE_ID2;
|
|
442
|
+
el.textContent = CONSENT_CSS;
|
|
443
|
+
document.head.appendChild(el);
|
|
444
|
+
}
|
|
445
|
+
ensureConsentStyles();
|
|
446
|
+
|
|
447
|
+
// src/AllowanceChips.tsx
|
|
448
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
449
|
+
var PRESETS = [
|
|
450
|
+
{ label: "$5", num: "5" },
|
|
451
|
+
{ label: "$20", num: "20" },
|
|
452
|
+
{ label: "$50", num: "50" }
|
|
453
|
+
];
|
|
454
|
+
var PRESET_NUMS = PRESETS.map((p) => p.num);
|
|
455
|
+
var isPreset = (v) => v !== null && PRESET_NUMS.includes(v);
|
|
456
|
+
function AllowanceChips(props) {
|
|
457
|
+
const { value, onChange, className } = props;
|
|
458
|
+
useEffect6(ensureConsentStyles, []);
|
|
459
|
+
const [customOpen, setCustomOpen] = useState4(false);
|
|
460
|
+
const customActive = customOpen || value !== null && !isPreset(value);
|
|
461
|
+
const selectPreset = (num) => {
|
|
462
|
+
setCustomOpen(false);
|
|
463
|
+
onChange(num);
|
|
464
|
+
};
|
|
465
|
+
const selectCustom = () => {
|
|
466
|
+
setCustomOpen(true);
|
|
467
|
+
onChange(isPreset(value) ? null : value);
|
|
468
|
+
};
|
|
469
|
+
const onChipKeyDown = (e, select) => {
|
|
470
|
+
if (e.key === "Enter" || e.key === " " || e.key === "Spacebar") {
|
|
471
|
+
e.preventDefault();
|
|
472
|
+
select();
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
return /* @__PURE__ */ jsxs4("div", { className: cx("dx-allow", className), role: "radiogroup", "aria-label": "Monthly agent allowance", children: [
|
|
476
|
+
PRESETS.map(({ label, num }) => {
|
|
477
|
+
const checked = !customActive && value === num;
|
|
478
|
+
return /* @__PURE__ */ jsx4(
|
|
479
|
+
"div",
|
|
480
|
+
{
|
|
481
|
+
role: "radio",
|
|
482
|
+
"aria-checked": checked,
|
|
483
|
+
tabIndex: 0,
|
|
484
|
+
className: cx("dx-allow__chip", checked && "dx-allow__chip--active"),
|
|
485
|
+
onClick: () => selectPreset(num),
|
|
486
|
+
onKeyDown: (e) => onChipKeyDown(e, () => selectPreset(num)),
|
|
487
|
+
children: label
|
|
488
|
+
},
|
|
489
|
+
num
|
|
490
|
+
);
|
|
491
|
+
}),
|
|
492
|
+
/* @__PURE__ */ jsx4(
|
|
493
|
+
"div",
|
|
494
|
+
{
|
|
495
|
+
role: "radio",
|
|
496
|
+
"aria-checked": customActive,
|
|
497
|
+
tabIndex: 0,
|
|
498
|
+
className: cx("dx-allow__chip", customActive && "dx-allow__chip--active"),
|
|
499
|
+
onClick: selectCustom,
|
|
500
|
+
onKeyDown: (e) => onChipKeyDown(e, selectCustom),
|
|
501
|
+
children: "Custom"
|
|
502
|
+
}
|
|
503
|
+
),
|
|
504
|
+
customActive && /* @__PURE__ */ jsx4(
|
|
505
|
+
"input",
|
|
506
|
+
{
|
|
507
|
+
className: "dx-allow__input",
|
|
508
|
+
inputMode: "decimal",
|
|
509
|
+
placeholder: "$ amount",
|
|
510
|
+
"aria-label": "Custom monthly allowance in USD",
|
|
511
|
+
value: value ?? "",
|
|
512
|
+
autoFocus: true,
|
|
513
|
+
onChange: (e) => onChange(e.target.value)
|
|
514
|
+
}
|
|
515
|
+
)
|
|
516
|
+
] });
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// src/CreateWalletPanel.tsx
|
|
520
|
+
import { useEffect as useEffect7, useState as useState5 } from "react";
|
|
521
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
522
|
+
var FINE_PRINT = "Your number, your tap. Agents can never spend past it, and you can revoke any time.";
|
|
523
|
+
function CreateWalletPanel(props) {
|
|
524
|
+
const { onCreated, onError, apiBase, transport, showName = true, className } = props;
|
|
525
|
+
useEffect7(ensureConsentStyles, []);
|
|
526
|
+
useEffect7(ensureDexterButtonStyles, []);
|
|
527
|
+
const [name, setName] = useState5("");
|
|
528
|
+
const [value, setValue] = useState5(null);
|
|
529
|
+
const [running, setRunning] = useState5(false);
|
|
530
|
+
const [phase, setPhase] = useState5(null);
|
|
531
|
+
const [error, setError] = useState5(null);
|
|
532
|
+
const policy = authoredPolicy(value ?? "");
|
|
533
|
+
const handleCreate = async () => {
|
|
534
|
+
if (running) return;
|
|
535
|
+
if (!policy) return;
|
|
536
|
+
setError(null);
|
|
537
|
+
setRunning(true);
|
|
538
|
+
setPhase(null);
|
|
539
|
+
try {
|
|
540
|
+
const result = await createWallet({
|
|
541
|
+
name: name.trim() || "Dexter Wallet",
|
|
542
|
+
spendPolicy: policy,
|
|
543
|
+
apiBase,
|
|
544
|
+
transport,
|
|
545
|
+
onPhase: setPhase
|
|
546
|
+
});
|
|
547
|
+
onCreated?.(result);
|
|
548
|
+
} catch (e) {
|
|
549
|
+
const err = e instanceof ConnectError ? e : new ConnectError("create_failed", e instanceof Error ? e.message : String(e));
|
|
550
|
+
setError(err);
|
|
551
|
+
onError?.(err);
|
|
552
|
+
} finally {
|
|
553
|
+
setRunning(false);
|
|
554
|
+
setPhase(null);
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
return /* @__PURE__ */ jsxs5("div", { className: cx("dx-cwp", className), children: [
|
|
558
|
+
showName && /* @__PURE__ */ jsxs5("div", { className: "dx-cwp__field", children: [
|
|
559
|
+
/* @__PURE__ */ jsx5("label", { className: "dx-cwp__label", htmlFor: "dx-cwp-name", children: "Name your wallet" }),
|
|
560
|
+
/* @__PURE__ */ jsx5(
|
|
561
|
+
"input",
|
|
562
|
+
{
|
|
563
|
+
id: "dx-cwp-name",
|
|
564
|
+
className: "dx-cwp__name",
|
|
565
|
+
maxLength: 40,
|
|
566
|
+
placeholder: "Dexter Wallet",
|
|
567
|
+
value: name,
|
|
568
|
+
disabled: running,
|
|
569
|
+
onChange: (e) => setName(e.target.value)
|
|
570
|
+
}
|
|
571
|
+
)
|
|
572
|
+
] }),
|
|
573
|
+
/* @__PURE__ */ jsxs5("div", { className: "dx-cwp__field", children: [
|
|
574
|
+
/* @__PURE__ */ jsx5("span", { className: "dx-cwp__label", children: "What agents may spend, per 30 days" }),
|
|
575
|
+
/* @__PURE__ */ jsx5(AllowanceChips, { value, onChange: setValue })
|
|
576
|
+
] }),
|
|
577
|
+
/* @__PURE__ */ jsx5("p", { className: "dx-cwp__fine", children: FINE_PRINT }),
|
|
578
|
+
error && /* @__PURE__ */ jsx5("div", { className: "dx-cwp__err", role: "alert", children: error.message || error.code }),
|
|
579
|
+
/* @__PURE__ */ jsx5(
|
|
580
|
+
DexterButton,
|
|
581
|
+
{
|
|
582
|
+
block: true,
|
|
583
|
+
className: "dx-cwp__cta",
|
|
584
|
+
loading: running,
|
|
585
|
+
loadingLabel: phase ? ceremonyPhaseLabel(phase) : "Creating\u2026",
|
|
586
|
+
disabled: !policy,
|
|
587
|
+
onClick: handleCreate,
|
|
588
|
+
children: error ? "Retry" : "Create your Dexter Wallet"
|
|
589
|
+
}
|
|
590
|
+
)
|
|
591
|
+
] });
|
|
592
|
+
}
|
|
371
593
|
export {
|
|
594
|
+
AllowanceChips,
|
|
595
|
+
CreateWalletPanel,
|
|
372
596
|
DexterButton,
|
|
373
597
|
DexterMark,
|
|
374
598
|
DexterWalletChip,
|
|
@@ -60,6 +60,55 @@ declare class ConnectError extends Error {
|
|
|
60
60
|
constructor(code: string, message?: string);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
/** Consent-at-birth allowance (Branch rulings 2026-07-02/03).
|
|
64
|
+
* The user authors the number; zero is not consent; TTL is fixed 30d and
|
|
65
|
+
* never user-editable; no caller may invent a default. */
|
|
66
|
+
declare const SESSION_TTL_30D = "2592000";
|
|
67
|
+
interface SpendPolicy {
|
|
68
|
+
/** Role-2 allowance, atomic USDC (6dp), decimal string. User-authored. */
|
|
69
|
+
spendLimitAtomic: string;
|
|
70
|
+
/** Fixed 30d. Present for wire compatibility; always SESSION_TTL_30D. */
|
|
71
|
+
sessionTtlSeconds: string;
|
|
72
|
+
}
|
|
73
|
+
/** Parse user-entered USD ("5", "$20", "1,000", "20.5") to atomic USDC.
|
|
74
|
+
* Null on anything invalid — callers must not invent a fallback. */
|
|
75
|
+
declare function usdToAtomic(input: string): bigint | null;
|
|
76
|
+
/** Null when invalid or zero (zero is not consent). */
|
|
77
|
+
declare function authoredPolicy(usdInput: string): SpendPolicy | null;
|
|
78
|
+
|
|
79
|
+
interface CreateWalletConfig extends DexterConnectConfig {
|
|
80
|
+
/** Label for the passkey in the OS keychain AND the wallet roster. Set at
|
|
81
|
+
* creation — the only moment naming is guaranteed to stick. Default "Dexter Wallet". */
|
|
82
|
+
name?: string;
|
|
83
|
+
/** RP id for the new credential. Default "dexter.cash". */
|
|
84
|
+
rpId?: string;
|
|
85
|
+
/** Consent-at-birth allowance the user authored at creation (chips $5/$20/$50
|
|
86
|
+
* or Custom; zero is not consent; build it with authoredPolicy()). When
|
|
87
|
+
* present it rides the /initialize body so the number becomes the server-side
|
|
88
|
+
* write-once consent record. The TTL is ruled fixed 30d — whatever the object
|
|
89
|
+
* carries, the wire always sends SESSION_TTL_30D. Absent → no policy authored
|
|
90
|
+
* (the vault initializes without one; nothing invents a default). */
|
|
91
|
+
spendPolicy?: SpendPolicy;
|
|
92
|
+
/** Called as the ceremony progresses, for live "connecting steps" UI:
|
|
93
|
+
* challenge → passkey → verifying → finalizing. */
|
|
94
|
+
onPhase?: (phase: CeremonyPhase) => void;
|
|
95
|
+
}
|
|
96
|
+
interface CreateWalletResult {
|
|
97
|
+
/** Server-minted 16-byte user handle, base64url — the vault identity. */
|
|
98
|
+
handle: string;
|
|
99
|
+
/** base64url credential id of the new passkey. */
|
|
100
|
+
credentialId: string;
|
|
101
|
+
/** The freshly initialized vault (swig not yet deployed; deploys lazily). */
|
|
102
|
+
vault: ConnectVault;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Mint a brand-new Dexter wallet (passkey + vault) and make it the active wallet.
|
|
106
|
+
*
|
|
107
|
+
* One passkey approval. Throws ConnectError on any failed leg (the `code` is the
|
|
108
|
+
* server's error string, or webauthn_failed / no_credential for the ceremony).
|
|
109
|
+
*/
|
|
110
|
+
declare function createWallet(config?: CreateWalletConfig): Promise<CreateWalletResult>;
|
|
111
|
+
|
|
63
112
|
type IdentityKind = 'passkey-vault' | 'account' | 'none';
|
|
64
113
|
interface IdentityInput {
|
|
65
114
|
/** An account session token (e.g. Supabase access_token) when present, else null. */
|
|
@@ -180,4 +229,4 @@ declare function syncAcceptedPasskeys(args: {
|
|
|
180
229
|
rpId?: string;
|
|
181
230
|
}): Promise<boolean>;
|
|
182
231
|
|
|
183
|
-
export { ACTIVE_WALLET_STORAGE_KEY as A, type
|
|
232
|
+
export { ACTIVE_WALLET_STORAGE_KEY as A, type CreateWalletResult as C, type DexterConnectConfig as D, type IdentityKind as I, type PasskeyLoginTokens as P, type ResolvedIdentity as R, type SignInResult as S, type CreateWalletConfig as a, type CeremonyPhase as b, type ConnectVault as c, ConnectError as d, type IdentityInput as e, type PasskeySignalSupport as f, SESSION_TTL_30D as g, type SpendPolicy as h, type StoredWallet as i, authoredPolicy as j, createWallet as k, ejectActiveWallet as l, forgetWallet as m, getActiveHandle as n, getCredentialId as o, listWallets as p, passkeySignalSupport as q, prunePasskey as r, renamePasskey as s, resolveIdentity as t, setActiveHandle as u, subscribe as v, switchWallet as w, syncAcceptedPasskeys as x, usdToAtomic as y };
|
package/dist/worldid.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dexterai/connect",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "Sign in with Dexter — passkey connector. Composes @dexterai/vault.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -47,7 +47,9 @@
|
|
|
47
47
|
"@dexterai/vault": "^0.30.0",
|
|
48
48
|
"@solana/web3.js": "^1.98.4",
|
|
49
49
|
"@types/react": "^19.1.12",
|
|
50
|
+
"@types/react-dom": "^19.2.3",
|
|
50
51
|
"@worldcoin/idkit": "^4.1.8",
|
|
52
|
+
"happy-dom": "^15.11.7",
|
|
51
53
|
"react": "^19.2.5",
|
|
52
54
|
"tsup": "^8.5.0",
|
|
53
55
|
"typescript": "^5.6.2",
|