@rhinestone/1auth 0.1.2 → 0.4.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-TACK3LJN.mjs → chunk-X73ALCGW.mjs} +46 -20
- package/dist/chunk-X73ALCGW.mjs.map +1 -0
- package/dist/{client-DyYGKWj3.d.mts → client-DKuPEx83.d.mts} +164 -9
- package/dist/{client-DyYGKWj3.d.ts → client-DKuPEx83.d.ts} +164 -9
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +515 -125
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +471 -107
- package/dist/index.mjs.map +1 -1
- package/dist/{provider-Ctr7HQHR.d.mts → provider-CmJarV7y.d.mts} +2 -2
- package/dist/{provider-CNTZPPFz.d.ts → provider-Dj5l4bWn.d.ts} +2 -2
- package/dist/react.d.mts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +16 -9
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +16 -9
- package/dist/react.mjs.map +1 -1
- package/dist/wagmi.d.mts +2 -2
- package/dist/wagmi.d.ts +2 -2
- package/dist/wagmi.js +45 -19
- package/dist/wagmi.js.map +1 -1
- package/dist/wagmi.mjs +1 -1
- package/package.json +7 -6
- package/dist/chunk-TACK3LJN.mjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -71,12 +71,15 @@ var import_viem = require("viem");
|
|
|
71
71
|
var viemChains = __toESM(require("viem/chains"));
|
|
72
72
|
var import_sdk = require("@rhinestone/sdk");
|
|
73
73
|
var env = typeof process !== "undefined" ? process.env : {};
|
|
74
|
-
var
|
|
75
|
-
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
)
|
|
74
|
+
var VIEM_CHAIN_BY_ID = /* @__PURE__ */ new Map();
|
|
75
|
+
for (const value of Object.values(viemChains)) {
|
|
76
|
+
if (typeof value !== "object" || value === null || !("id" in value) || !("name" in value)) continue;
|
|
77
|
+
const chain = value;
|
|
78
|
+
const existing = VIEM_CHAIN_BY_ID.get(chain.id);
|
|
79
|
+
if (!existing || existing.testnet && !chain.testnet) {
|
|
80
|
+
VIEM_CHAIN_BY_ID.set(chain.id, chain);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
80
83
|
var SUPPORTED_CHAIN_IDS = new Set(
|
|
81
84
|
(0, import_sdk.getAllSupportedChainsAndTokens)().map((entry) => entry.chainId)
|
|
82
85
|
);
|
|
@@ -197,7 +200,7 @@ var POPUP_WIDTH = 450;
|
|
|
197
200
|
var POPUP_HEIGHT = 600;
|
|
198
201
|
var DEFAULT_EMBED_WIDTH = "400px";
|
|
199
202
|
var DEFAULT_EMBED_HEIGHT = "500px";
|
|
200
|
-
var MODAL_WIDTH =
|
|
203
|
+
var MODAL_WIDTH = 340;
|
|
201
204
|
var DEFAULT_PROVIDER_URL = "https://passkey.1auth.box";
|
|
202
205
|
var OneAuthClient = class {
|
|
203
206
|
constructor(config) {
|
|
@@ -205,6 +208,12 @@ var OneAuthClient = class {
|
|
|
205
208
|
const dialogUrl = config.dialogUrl || providerUrl;
|
|
206
209
|
this.config = { ...config, providerUrl, dialogUrl };
|
|
207
210
|
this.theme = this.config.theme || {};
|
|
211
|
+
if (typeof document !== "undefined") {
|
|
212
|
+
this.injectPreconnect(providerUrl);
|
|
213
|
+
if (dialogUrl !== providerUrl) {
|
|
214
|
+
this.injectPreconnect(dialogUrl);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
208
217
|
}
|
|
209
218
|
/**
|
|
210
219
|
* Update the theme configuration at runtime
|
|
@@ -359,6 +368,133 @@ var OneAuthClient = class {
|
|
|
359
368
|
}
|
|
360
369
|
return this.waitForConnectResponse(dialog, iframe, cleanup);
|
|
361
370
|
}
|
|
371
|
+
/**
|
|
372
|
+
* Check if a user has already granted consent for the requested fields.
|
|
373
|
+
* This is a read-only check — no dialog is shown.
|
|
374
|
+
*
|
|
375
|
+
* @example
|
|
376
|
+
* ```typescript
|
|
377
|
+
* const result = await client.checkConsent({
|
|
378
|
+
* username: "alice",
|
|
379
|
+
* fields: ["email"],
|
|
380
|
+
* });
|
|
381
|
+
* if (result.hasConsent) {
|
|
382
|
+
* console.log(result.data?.email);
|
|
383
|
+
* }
|
|
384
|
+
* ```
|
|
385
|
+
*/
|
|
386
|
+
async checkConsent(options) {
|
|
387
|
+
const clientId = options.clientId ?? this.config.clientId;
|
|
388
|
+
if (!clientId) {
|
|
389
|
+
return {
|
|
390
|
+
hasConsent: false
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
const username = options.username ?? options.accountAddress;
|
|
394
|
+
if (!username) {
|
|
395
|
+
return {
|
|
396
|
+
hasConsent: false
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
try {
|
|
400
|
+
const res = await fetch(`${this.config.providerUrl || "https://passkey.1auth.box"}/api/consent`, {
|
|
401
|
+
method: "POST",
|
|
402
|
+
headers: {
|
|
403
|
+
"Content-Type": "application/json",
|
|
404
|
+
...clientId ? { "x-client-id": clientId } : {}
|
|
405
|
+
},
|
|
406
|
+
body: JSON.stringify({
|
|
407
|
+
username,
|
|
408
|
+
requestedFields: options.fields,
|
|
409
|
+
clientId
|
|
410
|
+
})
|
|
411
|
+
});
|
|
412
|
+
if (!res.ok) {
|
|
413
|
+
return { hasConsent: false };
|
|
414
|
+
}
|
|
415
|
+
const data = await res.json();
|
|
416
|
+
return {
|
|
417
|
+
hasConsent: data.hasConsent ?? false,
|
|
418
|
+
data: data.data,
|
|
419
|
+
grantedAt: data.grantedAt
|
|
420
|
+
};
|
|
421
|
+
} catch {
|
|
422
|
+
return { hasConsent: false };
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Request consent from the user to share their data.
|
|
427
|
+
*
|
|
428
|
+
* First checks if consent was already granted (returns cached data immediately).
|
|
429
|
+
* If not, opens the consent dialog where the user can review and approve sharing.
|
|
430
|
+
*
|
|
431
|
+
* @example
|
|
432
|
+
* ```typescript
|
|
433
|
+
* const result = await client.requestConsent({
|
|
434
|
+
* username: "alice",
|
|
435
|
+
* fields: ["email", "deviceNames"],
|
|
436
|
+
* });
|
|
437
|
+
* if (result.success) {
|
|
438
|
+
* console.log(result.data?.email);
|
|
439
|
+
* console.log(result.cached); // true if no dialog was shown
|
|
440
|
+
* }
|
|
441
|
+
* ```
|
|
442
|
+
*/
|
|
443
|
+
async requestConsent(options) {
|
|
444
|
+
const clientId = options.clientId ?? this.config.clientId;
|
|
445
|
+
if (!clientId) {
|
|
446
|
+
return {
|
|
447
|
+
success: false,
|
|
448
|
+
error: { code: "INVALID_REQUEST", message: "clientId is required (set in config or options)" }
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
const username = options.username ?? options.accountAddress;
|
|
452
|
+
if (!username) {
|
|
453
|
+
return {
|
|
454
|
+
success: false,
|
|
455
|
+
error: { code: "INVALID_REQUEST", message: "username or accountAddress is required" }
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
if (!options.fields || options.fields.length === 0) {
|
|
459
|
+
return {
|
|
460
|
+
success: false,
|
|
461
|
+
error: { code: "INVALID_REQUEST", message: "At least one field is required" }
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
const existing = await this.checkConsent({ ...options, clientId });
|
|
465
|
+
if (existing.hasConsent && existing.data) {
|
|
466
|
+
return {
|
|
467
|
+
success: true,
|
|
468
|
+
data: existing.data,
|
|
469
|
+
grantedAt: existing.grantedAt,
|
|
470
|
+
cached: true
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
const dialogUrl = this.getDialogUrl();
|
|
474
|
+
const params = new URLSearchParams({
|
|
475
|
+
mode: "iframe",
|
|
476
|
+
username,
|
|
477
|
+
clientId,
|
|
478
|
+
fields: options.fields.join(",")
|
|
479
|
+
});
|
|
480
|
+
const themeParams = this.getThemeParams(options.theme);
|
|
481
|
+
if (themeParams) {
|
|
482
|
+
const themeParsed = new URLSearchParams(themeParams);
|
|
483
|
+
themeParsed.forEach((value, key) => params.set(key, value));
|
|
484
|
+
}
|
|
485
|
+
const url = `${dialogUrl}/dialog/consent?${params.toString()}`;
|
|
486
|
+
const { dialog, iframe, cleanup } = this.createModalDialog(url);
|
|
487
|
+
const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {
|
|
488
|
+
mode: "iframe"
|
|
489
|
+
});
|
|
490
|
+
if (!ready) {
|
|
491
|
+
return {
|
|
492
|
+
success: false,
|
|
493
|
+
error: { code: "USER_CANCELLED", message: "User closed the dialog" }
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
return this.waitForConsentResponse(dialog, iframe, cleanup);
|
|
497
|
+
}
|
|
362
498
|
/**
|
|
363
499
|
* Authenticate a user with an optional challenge to sign.
|
|
364
500
|
*
|
|
@@ -486,7 +622,8 @@ var OneAuthClient = class {
|
|
|
486
622
|
}
|
|
487
623
|
};
|
|
488
624
|
}
|
|
489
|
-
|
|
625
|
+
const accountAddress = signedIntent?.accountAddress || options.accountAddress;
|
|
626
|
+
if (!username && !accountAddress) {
|
|
490
627
|
return {
|
|
491
628
|
success: false,
|
|
492
629
|
intentId: "",
|
|
@@ -515,6 +652,7 @@ var OneAuthClient = class {
|
|
|
515
652
|
let prepareResponse;
|
|
516
653
|
const requestBody = signedIntent || {
|
|
517
654
|
username: options.username,
|
|
655
|
+
accountAddress: options.accountAddress,
|
|
518
656
|
targetChain: options.targetChain,
|
|
519
657
|
calls: options.calls,
|
|
520
658
|
tokenRequests: serializedTokenRequests,
|
|
@@ -522,48 +660,35 @@ var OneAuthClient = class {
|
|
|
522
660
|
sourceChainId: options.sourceChainId,
|
|
523
661
|
...this.config.clientId && { clientId: this.config.clientId }
|
|
524
662
|
};
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
const errorData = await response.json().catch(() => ({}));
|
|
535
|
-
const errorMessage = errorData.error || "Failed to prepare intent";
|
|
536
|
-
if (errorMessage.includes("User not found")) {
|
|
537
|
-
localStorage.removeItem("1auth-user");
|
|
538
|
-
}
|
|
539
|
-
return {
|
|
540
|
-
success: false,
|
|
541
|
-
intentId: "",
|
|
542
|
-
status: "failed",
|
|
543
|
-
error: {
|
|
544
|
-
code: errorMessage.includes("User not found") ? "USER_NOT_FOUND" : "PREPARE_FAILED",
|
|
545
|
-
message: errorMessage
|
|
546
|
-
}
|
|
547
|
-
};
|
|
548
|
-
}
|
|
549
|
-
prepareResponse = await response.json();
|
|
550
|
-
} catch (error) {
|
|
663
|
+
const dialogUrl = this.getDialogUrl();
|
|
664
|
+
const themeParams = this.getThemeParams();
|
|
665
|
+
const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ""}`;
|
|
666
|
+
const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);
|
|
667
|
+
const [prepareResult, dialogResult] = await Promise.all([
|
|
668
|
+
this.prepareIntent(requestBody),
|
|
669
|
+
this.waitForDialogReadyDeferred(dialog, iframe, cleanup)
|
|
670
|
+
]);
|
|
671
|
+
if (!dialogResult.ready) {
|
|
551
672
|
return {
|
|
552
673
|
success: false,
|
|
553
674
|
intentId: "",
|
|
554
675
|
status: "failed",
|
|
555
|
-
error: {
|
|
556
|
-
code: "NETWORK_ERROR",
|
|
557
|
-
message: error instanceof Error ? error.message : "Network error"
|
|
558
|
-
}
|
|
676
|
+
error: { code: "USER_CANCELLED", message: "User closed the dialog" }
|
|
559
677
|
};
|
|
560
678
|
}
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
679
|
+
if (!prepareResult.success) {
|
|
680
|
+
this.sendPrepareError(iframe, prepareResult.error.message);
|
|
681
|
+
await this.waitForDialogClose(dialog, cleanup);
|
|
682
|
+
return {
|
|
683
|
+
success: false,
|
|
684
|
+
intentId: "",
|
|
685
|
+
status: "failed",
|
|
686
|
+
error: prepareResult.error
|
|
687
|
+
};
|
|
688
|
+
}
|
|
689
|
+
prepareResponse = prepareResult.data;
|
|
565
690
|
const dialogOrigin = this.getDialogOrigin();
|
|
566
|
-
const
|
|
691
|
+
const initPayload = {
|
|
567
692
|
mode: "iframe",
|
|
568
693
|
calls,
|
|
569
694
|
chainId: targetChain,
|
|
@@ -575,16 +700,21 @@ var OneAuthClient = class {
|
|
|
575
700
|
tokenRequests: serializedTokenRequests,
|
|
576
701
|
expiresAt: prepareResponse.expiresAt,
|
|
577
702
|
userId: prepareResponse.userId,
|
|
578
|
-
intentOp: prepareResponse.intentOp
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
703
|
+
intentOp: prepareResponse.intentOp,
|
|
704
|
+
digestResult: prepareResponse.digestResult,
|
|
705
|
+
tier: prepareResult.tier
|
|
706
|
+
};
|
|
707
|
+
dialogResult.sendInit(initPayload);
|
|
708
|
+
const handleReReady = (event) => {
|
|
709
|
+
if (event.origin !== dialogOrigin) return;
|
|
710
|
+
if (event.data?.type === "PASSKEY_READY") {
|
|
711
|
+
iframe.contentWindow?.postMessage(
|
|
712
|
+
{ type: "PASSKEY_INIT", ...initPayload },
|
|
713
|
+
dialogOrigin
|
|
714
|
+
);
|
|
715
|
+
}
|
|
716
|
+
};
|
|
717
|
+
window.addEventListener("message", handleReReady);
|
|
588
718
|
const signingResult = await this.waitForSigningWithRefresh(
|
|
589
719
|
dialog,
|
|
590
720
|
iframe,
|
|
@@ -611,7 +741,8 @@ var OneAuthClient = class {
|
|
|
611
741
|
expiresAt: refreshedData.expiresAt,
|
|
612
742
|
challenge: refreshedData.challenge,
|
|
613
743
|
originMessages: refreshedData.originMessages,
|
|
614
|
-
transaction: refreshedData.transaction
|
|
744
|
+
transaction: refreshedData.transaction,
|
|
745
|
+
digestResult: refreshedData.digestResult
|
|
615
746
|
};
|
|
616
747
|
} catch (error) {
|
|
617
748
|
console.error("[SDK] Quote refresh error:", error);
|
|
@@ -619,6 +750,7 @@ var OneAuthClient = class {
|
|
|
619
750
|
}
|
|
620
751
|
}
|
|
621
752
|
);
|
|
753
|
+
window.removeEventListener("message", handleReReady);
|
|
622
754
|
if (!signingResult.success) {
|
|
623
755
|
return {
|
|
624
756
|
success: false,
|
|
@@ -650,6 +782,7 @@ var OneAuthClient = class {
|
|
|
650
782
|
targetChain: prepareResponse.targetChain,
|
|
651
783
|
calls: prepareResponse.calls,
|
|
652
784
|
expiresAt: prepareResponse.expiresAt,
|
|
785
|
+
digestResult: prepareResponse.digestResult,
|
|
653
786
|
// Signature from dialog
|
|
654
787
|
signature: signingResult.signature,
|
|
655
788
|
passkey: signingResult.passkey
|
|
@@ -691,10 +824,21 @@ var OneAuthClient = class {
|
|
|
691
824
|
let finalTxHash = executeResponse.transactionHash;
|
|
692
825
|
if (finalStatus === "pending") {
|
|
693
826
|
this.sendTransactionStatus(iframe, "pending");
|
|
827
|
+
let userClosedEarly = false;
|
|
828
|
+
const dialogOrigin2 = this.getDialogOrigin();
|
|
829
|
+
const earlyCloseHandler = (event) => {
|
|
830
|
+
if (event.origin !== dialogOrigin2) return;
|
|
831
|
+
if (event.data?.type === "PASSKEY_CLOSE") {
|
|
832
|
+
userClosedEarly = true;
|
|
833
|
+
cleanup();
|
|
834
|
+
}
|
|
835
|
+
};
|
|
836
|
+
window.addEventListener("message", earlyCloseHandler);
|
|
694
837
|
const maxAttempts = 120;
|
|
695
838
|
const pollIntervalMs = 1500;
|
|
696
839
|
let lastStatus = "pending";
|
|
697
840
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
841
|
+
if (userClosedEarly) break;
|
|
698
842
|
try {
|
|
699
843
|
const statusResponse = await fetch(
|
|
700
844
|
`${this.config.providerUrl}/api/intent/status/${executeResponse.intentId}`,
|
|
@@ -729,6 +873,21 @@ var OneAuthClient = class {
|
|
|
729
873
|
}
|
|
730
874
|
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
731
875
|
}
|
|
876
|
+
window.removeEventListener("message", earlyCloseHandler);
|
|
877
|
+
if (userClosedEarly) {
|
|
878
|
+
cleanup();
|
|
879
|
+
return {
|
|
880
|
+
success: false,
|
|
881
|
+
intentId: executeResponse.intentId,
|
|
882
|
+
status: finalStatus,
|
|
883
|
+
transactionHash: finalTxHash,
|
|
884
|
+
operationId: executeResponse.operationId,
|
|
885
|
+
error: {
|
|
886
|
+
code: "USER_CANCELLED",
|
|
887
|
+
message: "User closed the dialog"
|
|
888
|
+
}
|
|
889
|
+
};
|
|
890
|
+
}
|
|
732
891
|
}
|
|
733
892
|
const closeOn = options.closeOn || "preconfirmed";
|
|
734
893
|
const successStatuses = {
|
|
@@ -739,8 +898,9 @@ var OneAuthClient = class {
|
|
|
739
898
|
};
|
|
740
899
|
const isSuccessStatus = successStatuses[closeOn]?.includes(finalStatus) ?? false;
|
|
741
900
|
const displayStatus = isSuccessStatus ? "confirmed" : finalStatus;
|
|
901
|
+
const closePromise = this.waitForDialogClose(dialog, cleanup);
|
|
742
902
|
this.sendTransactionStatus(iframe, displayStatus, finalTxHash);
|
|
743
|
-
await
|
|
903
|
+
await closePromise;
|
|
744
904
|
if (options.waitForHash && !finalTxHash) {
|
|
745
905
|
const hash = await this.waitForTransactionHash(executeResponse.intentId, {
|
|
746
906
|
timeoutMs: options.hashTimeoutMs,
|
|
@@ -801,7 +961,7 @@ var OneAuthClient = class {
|
|
|
801
961
|
* ```
|
|
802
962
|
*/
|
|
803
963
|
async sendBatchIntent(options) {
|
|
804
|
-
if (!options.username) {
|
|
964
|
+
if (!options.username && !options.accountAddress) {
|
|
805
965
|
return {
|
|
806
966
|
success: false,
|
|
807
967
|
results: [],
|
|
@@ -825,35 +985,24 @@ var OneAuthClient = class {
|
|
|
825
985
|
amount: r.amount.toString()
|
|
826
986
|
})),
|
|
827
987
|
sourceAssets: intent.sourceAssets,
|
|
828
|
-
sourceChainId: intent.sourceChainId
|
|
988
|
+
sourceChainId: intent.sourceChainId,
|
|
989
|
+
moduleInstall: intent.moduleInstall
|
|
829
990
|
}));
|
|
830
991
|
const requestBody = {
|
|
831
|
-
username: options.username,
|
|
992
|
+
...options.username && { username: options.username },
|
|
993
|
+
...options.accountAddress && { accountAddress: options.accountAddress },
|
|
832
994
|
intents: serializedIntents,
|
|
833
995
|
...this.config.clientId && { clientId: this.config.clientId }
|
|
834
996
|
};
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
const errorMessage = errorData.error || "Failed to prepare batch intent";
|
|
845
|
-
if (errorMessage.includes("User not found")) {
|
|
846
|
-
localStorage.removeItem("1auth-user");
|
|
847
|
-
}
|
|
848
|
-
return {
|
|
849
|
-
success: false,
|
|
850
|
-
results: [],
|
|
851
|
-
successCount: 0,
|
|
852
|
-
failureCount: 0
|
|
853
|
-
};
|
|
854
|
-
}
|
|
855
|
-
prepareResponse = await response.json();
|
|
856
|
-
} catch {
|
|
997
|
+
const dialogUrl = this.getDialogUrl();
|
|
998
|
+
const themeParams = this.getThemeParams();
|
|
999
|
+
const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ""}`;
|
|
1000
|
+
const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);
|
|
1001
|
+
const [prepareResult, dialogResult] = await Promise.all([
|
|
1002
|
+
this.prepareBatchIntent(requestBody),
|
|
1003
|
+
this.waitForDialogReadyDeferred(dialog, iframe, cleanup)
|
|
1004
|
+
]);
|
|
1005
|
+
if (!dialogResult.ready) {
|
|
857
1006
|
return {
|
|
858
1007
|
success: false,
|
|
859
1008
|
results: [],
|
|
@@ -861,29 +1010,50 @@ var OneAuthClient = class {
|
|
|
861
1010
|
failureCount: 0
|
|
862
1011
|
};
|
|
863
1012
|
}
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
1013
|
+
if (!prepareResult.success) {
|
|
1014
|
+
const failedIntents = prepareResult.failedIntents;
|
|
1015
|
+
const failureResults = failedIntents?.map((f) => ({
|
|
1016
|
+
index: f.index,
|
|
1017
|
+
success: false,
|
|
1018
|
+
intentId: "",
|
|
1019
|
+
status: "failed",
|
|
1020
|
+
error: { message: f.error, code: "PREPARE_FAILED" }
|
|
1021
|
+
})) ?? [];
|
|
1022
|
+
this.sendPrepareError(iframe, prepareResult.error);
|
|
1023
|
+
await this.waitForDialogClose(dialog, cleanup);
|
|
1024
|
+
return {
|
|
1025
|
+
success: false,
|
|
1026
|
+
results: failureResults,
|
|
1027
|
+
successCount: 0,
|
|
1028
|
+
failureCount: failureResults.length,
|
|
1029
|
+
error: prepareResult.error
|
|
1030
|
+
};
|
|
1031
|
+
}
|
|
1032
|
+
let prepareResponse = prepareResult.data;
|
|
868
1033
|
const dialogOrigin = this.getDialogOrigin();
|
|
869
|
-
const
|
|
1034
|
+
const batchInitPayload = {
|
|
870
1035
|
mode: "iframe",
|
|
871
1036
|
batchMode: true,
|
|
872
1037
|
batchIntents: prepareResponse.intents,
|
|
1038
|
+
batchFailedIntents: prepareResponse.failedIntents,
|
|
873
1039
|
challenge: prepareResponse.challenge,
|
|
874
1040
|
username: options.username,
|
|
875
1041
|
accountAddress: prepareResponse.accountAddress,
|
|
876
1042
|
userId: prepareResponse.userId,
|
|
877
|
-
expiresAt: prepareResponse.expiresAt
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
1043
|
+
expiresAt: prepareResponse.expiresAt,
|
|
1044
|
+
tier: prepareResult.tier
|
|
1045
|
+
};
|
|
1046
|
+
dialogResult.sendInit(batchInitPayload);
|
|
1047
|
+
const handleBatchReReady = (event) => {
|
|
1048
|
+
if (event.origin !== dialogOrigin) return;
|
|
1049
|
+
if (event.data?.type === "PASSKEY_READY") {
|
|
1050
|
+
iframe.contentWindow?.postMessage(
|
|
1051
|
+
{ type: "PASSKEY_INIT", ...batchInitPayload },
|
|
1052
|
+
dialogOrigin
|
|
1053
|
+
);
|
|
1054
|
+
}
|
|
1055
|
+
};
|
|
1056
|
+
window.addEventListener("message", handleBatchReReady);
|
|
887
1057
|
const batchResult = await new Promise((resolve) => {
|
|
888
1058
|
const handleMessage = async (event) => {
|
|
889
1059
|
if (event.origin !== dialogOrigin) return;
|
|
@@ -930,13 +1100,21 @@ var OneAuthClient = class {
|
|
|
930
1100
|
status: r.status === "FAILED" ? "failed" : "pending",
|
|
931
1101
|
error: r.error ? { code: "EXECUTE_FAILED", message: r.error } : void 0
|
|
932
1102
|
}));
|
|
933
|
-
const
|
|
1103
|
+
const prepareFailures = (prepareResponse.failedIntents ?? []).map((f) => ({
|
|
1104
|
+
index: f.index,
|
|
1105
|
+
success: false,
|
|
1106
|
+
intentId: "",
|
|
1107
|
+
status: "failed",
|
|
1108
|
+
error: { code: "PREPARE_FAILED", message: f.error }
|
|
1109
|
+
}));
|
|
1110
|
+
const allResults = [...results, ...prepareFailures].sort((a, b) => a.index - b.index);
|
|
1111
|
+
const successCount = allResults.filter((r) => r.success).length;
|
|
934
1112
|
await this.waitForDialogClose(dialog, cleanup);
|
|
935
1113
|
resolve({
|
|
936
|
-
success: successCount ===
|
|
937
|
-
results,
|
|
1114
|
+
success: successCount === allResults.length,
|
|
1115
|
+
results: allResults,
|
|
938
1116
|
successCount,
|
|
939
|
-
failureCount:
|
|
1117
|
+
failureCount: allResults.length - successCount
|
|
940
1118
|
});
|
|
941
1119
|
} else {
|
|
942
1120
|
cleanup();
|
|
@@ -961,6 +1139,7 @@ var OneAuthClient = class {
|
|
|
961
1139
|
};
|
|
962
1140
|
window.addEventListener("message", handleMessage);
|
|
963
1141
|
});
|
|
1142
|
+
window.removeEventListener("message", handleBatchReReady);
|
|
964
1143
|
return batchResult;
|
|
965
1144
|
}
|
|
966
1145
|
/**
|
|
@@ -1164,6 +1343,143 @@ var OneAuthClient = class {
|
|
|
1164
1343
|
dialog.addEventListener("close", handleClose);
|
|
1165
1344
|
});
|
|
1166
1345
|
}
|
|
1346
|
+
/**
|
|
1347
|
+
* Inject a preconnect link tag to pre-warm DNS + TLS for a given URL.
|
|
1348
|
+
*/
|
|
1349
|
+
injectPreconnect(url) {
|
|
1350
|
+
try {
|
|
1351
|
+
const origin = new URL(url).origin;
|
|
1352
|
+
if (document.querySelector(`link[rel="preconnect"][href="${origin}"]`)) return;
|
|
1353
|
+
const link = document.createElement("link");
|
|
1354
|
+
link.rel = "preconnect";
|
|
1355
|
+
link.href = origin;
|
|
1356
|
+
link.crossOrigin = "anonymous";
|
|
1357
|
+
document.head.appendChild(link);
|
|
1358
|
+
} catch {
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
/**
|
|
1362
|
+
* Wait for the dialog iframe to signal ready without sending init data.
|
|
1363
|
+
* Returns a sendInit function the caller uses once prepare data is available.
|
|
1364
|
+
*/
|
|
1365
|
+
waitForDialogReadyDeferred(dialog, iframe, cleanup) {
|
|
1366
|
+
const dialogOrigin = this.getDialogOrigin();
|
|
1367
|
+
return new Promise((resolve) => {
|
|
1368
|
+
let settled = false;
|
|
1369
|
+
const teardown = () => {
|
|
1370
|
+
if (settled) return;
|
|
1371
|
+
settled = true;
|
|
1372
|
+
clearTimeout(readyTimeout);
|
|
1373
|
+
window.removeEventListener("message", handleMessage);
|
|
1374
|
+
dialog.removeEventListener("close", handleClose);
|
|
1375
|
+
};
|
|
1376
|
+
const handleMessage = (event) => {
|
|
1377
|
+
if (event.origin !== dialogOrigin) return;
|
|
1378
|
+
if (event.data?.type === "PASSKEY_READY") {
|
|
1379
|
+
teardown();
|
|
1380
|
+
resolve({
|
|
1381
|
+
ready: true,
|
|
1382
|
+
sendInit: (initMessage) => {
|
|
1383
|
+
iframe.contentWindow?.postMessage(
|
|
1384
|
+
{ type: "PASSKEY_INIT", ...initMessage },
|
|
1385
|
+
dialogOrigin
|
|
1386
|
+
);
|
|
1387
|
+
}
|
|
1388
|
+
});
|
|
1389
|
+
} else if (event.data?.type === "PASSKEY_CLOSE") {
|
|
1390
|
+
teardown();
|
|
1391
|
+
cleanup();
|
|
1392
|
+
resolve({ ready: false });
|
|
1393
|
+
}
|
|
1394
|
+
};
|
|
1395
|
+
const handleClose = () => {
|
|
1396
|
+
teardown();
|
|
1397
|
+
resolve({ ready: false });
|
|
1398
|
+
};
|
|
1399
|
+
const readyTimeout = setTimeout(() => {
|
|
1400
|
+
teardown();
|
|
1401
|
+
cleanup();
|
|
1402
|
+
resolve({ ready: false });
|
|
1403
|
+
}, 1e4);
|
|
1404
|
+
window.addEventListener("message", handleMessage);
|
|
1405
|
+
dialog.addEventListener("close", handleClose);
|
|
1406
|
+
});
|
|
1407
|
+
}
|
|
1408
|
+
/**
|
|
1409
|
+
* Prepare an intent by calling the orchestrator for a quote.
|
|
1410
|
+
* Returns the prepare response and the origin tier from the response header.
|
|
1411
|
+
*/
|
|
1412
|
+
async prepareIntent(requestBody) {
|
|
1413
|
+
try {
|
|
1414
|
+
const response = await fetch(`${this.config.providerUrl}/api/intent/prepare`, {
|
|
1415
|
+
method: "POST",
|
|
1416
|
+
headers: { "Content-Type": "application/json" },
|
|
1417
|
+
body: JSON.stringify(requestBody)
|
|
1418
|
+
});
|
|
1419
|
+
if (!response.ok) {
|
|
1420
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1421
|
+
const errorMessage = errorData.error || "Failed to prepare intent";
|
|
1422
|
+
if (errorMessage.includes("User not found")) {
|
|
1423
|
+
localStorage.removeItem("1auth-user");
|
|
1424
|
+
}
|
|
1425
|
+
return {
|
|
1426
|
+
success: false,
|
|
1427
|
+
error: {
|
|
1428
|
+
code: errorMessage.includes("User not found") ? "USER_NOT_FOUND" : "PREPARE_FAILED",
|
|
1429
|
+
message: errorMessage
|
|
1430
|
+
}
|
|
1431
|
+
};
|
|
1432
|
+
}
|
|
1433
|
+
const tier = response.headers.get("X-Origin-Tier");
|
|
1434
|
+
return { success: true, data: await response.json(), tier };
|
|
1435
|
+
} catch (error) {
|
|
1436
|
+
return {
|
|
1437
|
+
success: false,
|
|
1438
|
+
error: {
|
|
1439
|
+
code: "NETWORK_ERROR",
|
|
1440
|
+
message: error instanceof Error ? error.message : "Network error"
|
|
1441
|
+
}
|
|
1442
|
+
};
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
/**
|
|
1446
|
+
* Prepare a batch intent by calling the orchestrator for quotes on all intents.
|
|
1447
|
+
*/
|
|
1448
|
+
async prepareBatchIntent(requestBody) {
|
|
1449
|
+
try {
|
|
1450
|
+
const response = await fetch(`${this.config.providerUrl}/api/intent/batch-prepare`, {
|
|
1451
|
+
method: "POST",
|
|
1452
|
+
headers: { "Content-Type": "application/json" },
|
|
1453
|
+
body: JSON.stringify(requestBody)
|
|
1454
|
+
});
|
|
1455
|
+
if (!response.ok) {
|
|
1456
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1457
|
+
const errorMessage = errorData.error || "Failed to prepare batch intent";
|
|
1458
|
+
if (errorMessage.includes("User not found")) {
|
|
1459
|
+
localStorage.removeItem("1auth-user");
|
|
1460
|
+
}
|
|
1461
|
+
return {
|
|
1462
|
+
success: false,
|
|
1463
|
+
error: errorMessage,
|
|
1464
|
+
failedIntents: errorData.failedIntents
|
|
1465
|
+
};
|
|
1466
|
+
}
|
|
1467
|
+
const tier = response.headers.get("X-Origin-Tier");
|
|
1468
|
+
return { success: true, data: await response.json(), tier };
|
|
1469
|
+
} catch {
|
|
1470
|
+
return { success: false, error: "Network error" };
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
/**
|
|
1474
|
+
* Send a prepare error message to the dialog iframe.
|
|
1475
|
+
*/
|
|
1476
|
+
sendPrepareError(iframe, error) {
|
|
1477
|
+
const dialogOrigin = this.getDialogOrigin();
|
|
1478
|
+
iframe.contentWindow?.postMessage(
|
|
1479
|
+
{ type: "PASSKEY_PREPARE_ERROR", error },
|
|
1480
|
+
dialogOrigin
|
|
1481
|
+
);
|
|
1482
|
+
}
|
|
1167
1483
|
/**
|
|
1168
1484
|
* Poll for intent status
|
|
1169
1485
|
*
|
|
@@ -1475,6 +1791,7 @@ var OneAuthClient = class {
|
|
|
1475
1791
|
message: options.message,
|
|
1476
1792
|
challenge: options.challenge || options.message,
|
|
1477
1793
|
username: options.username,
|
|
1794
|
+
accountAddress: options.accountAddress,
|
|
1478
1795
|
description: options.description,
|
|
1479
1796
|
metadata: options.metadata
|
|
1480
1797
|
});
|
|
@@ -1566,6 +1883,7 @@ var OneAuthClient = class {
|
|
|
1566
1883
|
},
|
|
1567
1884
|
challenge: signedHash,
|
|
1568
1885
|
username: options.username,
|
|
1886
|
+
accountAddress: options.accountAddress,
|
|
1569
1887
|
description: options.description
|
|
1570
1888
|
});
|
|
1571
1889
|
if (!ready) {
|
|
@@ -1639,7 +1957,7 @@ var OneAuthClient = class {
|
|
|
1639
1957
|
iframe.style.borderRadius = "12px";
|
|
1640
1958
|
iframe.style.boxShadow = "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)";
|
|
1641
1959
|
iframe.id = `passkey-embed-${requestId}`;
|
|
1642
|
-
iframe.allow = "publickey-credentials-get *; publickey-credentials-create
|
|
1960
|
+
iframe.allow = "publickey-credentials-get *; publickey-credentials-create *; identity-credentials-get";
|
|
1643
1961
|
iframe.onload = () => {
|
|
1644
1962
|
options.onReady?.();
|
|
1645
1963
|
};
|
|
@@ -1787,6 +2105,7 @@ var OneAuthClient = class {
|
|
|
1787
2105
|
const teardown = () => {
|
|
1788
2106
|
if (settled) return;
|
|
1789
2107
|
settled = true;
|
|
2108
|
+
clearTimeout(readyTimeout);
|
|
1790
2109
|
window.removeEventListener("message", handleMessage);
|
|
1791
2110
|
dialog.removeEventListener("close", handleClose);
|
|
1792
2111
|
};
|
|
@@ -1809,6 +2128,11 @@ var OneAuthClient = class {
|
|
|
1809
2128
|
teardown();
|
|
1810
2129
|
resolve(false);
|
|
1811
2130
|
};
|
|
2131
|
+
const readyTimeout = setTimeout(() => {
|
|
2132
|
+
teardown();
|
|
2133
|
+
cleanup();
|
|
2134
|
+
resolve(false);
|
|
2135
|
+
}, 1e4);
|
|
1812
2136
|
window.addEventListener("message", handleMessage);
|
|
1813
2137
|
dialog.addEventListener("close", handleClose);
|
|
1814
2138
|
});
|
|
@@ -1849,7 +2173,9 @@ var OneAuthClient = class {
|
|
|
1849
2173
|
border-radius: 14px;
|
|
1850
2174
|
border: none;
|
|
1851
2175
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.08);
|
|
1852
|
-
transition:
|
|
2176
|
+
transition: height 0.15s ease-out;
|
|
2177
|
+
max-height: calc(100vh - 100px);
|
|
2178
|
+
max-height: calc(100dvh - 100px);
|
|
1853
2179
|
}
|
|
1854
2180
|
|
|
1855
2181
|
@media (min-width: 769px) {
|
|
@@ -1911,14 +2237,10 @@ var OneAuthClient = class {
|
|
|
1911
2237
|
const iframe = document.createElement("iframe");
|
|
1912
2238
|
iframe.setAttribute(
|
|
1913
2239
|
"allow",
|
|
1914
|
-
"publickey-credentials-get *; publickey-credentials-create *; clipboard-write"
|
|
2240
|
+
"publickey-credentials-get *; publickey-credentials-create *; clipboard-write; identity-credentials-get"
|
|
1915
2241
|
);
|
|
1916
2242
|
iframe.setAttribute("aria-label", "Passkey Authentication");
|
|
1917
2243
|
iframe.setAttribute("tabindex", "0");
|
|
1918
|
-
iframe.setAttribute(
|
|
1919
|
-
"sandbox",
|
|
1920
|
-
"allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox"
|
|
1921
|
-
);
|
|
1922
2244
|
iframe.setAttribute("src", url);
|
|
1923
2245
|
iframe.setAttribute("title", "Passkey");
|
|
1924
2246
|
iframe.style.border = "none";
|
|
@@ -1928,10 +2250,8 @@ var OneAuthClient = class {
|
|
|
1928
2250
|
const handleMessage = (event) => {
|
|
1929
2251
|
if (event.origin !== hostUrl.origin) return;
|
|
1930
2252
|
if (event.data?.type === "PASSKEY_RESIZE") {
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
iframe.style.width = `${event.data.width}px`;
|
|
1934
|
-
}
|
|
2253
|
+
const maxHeight = window.innerHeight - 100;
|
|
2254
|
+
iframe.style.height = `${Math.min(event.data.height, maxHeight)}px`;
|
|
1935
2255
|
} else if (event.data?.type === "PASSKEY_DISCONNECT") {
|
|
1936
2256
|
localStorage.removeItem("1auth-user");
|
|
1937
2257
|
}
|
|
@@ -1949,7 +2269,10 @@ var OneAuthClient = class {
|
|
|
1949
2269
|
}
|
|
1950
2270
|
});
|
|
1951
2271
|
dialog.showModal();
|
|
2272
|
+
let cleanedUp = false;
|
|
1952
2273
|
const cleanup = () => {
|
|
2274
|
+
if (cleanedUp) return;
|
|
2275
|
+
cleanedUp = true;
|
|
1953
2276
|
window.removeEventListener("message", handleMessage);
|
|
1954
2277
|
document.removeEventListener("keydown", handleEscape);
|
|
1955
2278
|
dialog.close();
|
|
@@ -1982,6 +2305,7 @@ var OneAuthClient = class {
|
|
|
1982
2305
|
resolve({
|
|
1983
2306
|
success: true,
|
|
1984
2307
|
username: data.data?.username,
|
|
2308
|
+
address: data.data?.address,
|
|
1985
2309
|
user: data.data?.user
|
|
1986
2310
|
});
|
|
1987
2311
|
} else {
|
|
@@ -1996,7 +2320,8 @@ var OneAuthClient = class {
|
|
|
1996
2320
|
if (data.success) {
|
|
1997
2321
|
resolve({
|
|
1998
2322
|
success: true,
|
|
1999
|
-
username: data.data?.username
|
|
2323
|
+
username: data.data?.username,
|
|
2324
|
+
address: data.data?.address
|
|
2000
2325
|
});
|
|
2001
2326
|
} else {
|
|
2002
2327
|
resolve({
|
|
@@ -2056,6 +2381,7 @@ var OneAuthClient = class {
|
|
|
2056
2381
|
resolve({
|
|
2057
2382
|
success: true,
|
|
2058
2383
|
username: data.data?.username,
|
|
2384
|
+
address: data.data?.address,
|
|
2059
2385
|
user: data.data?.user
|
|
2060
2386
|
});
|
|
2061
2387
|
} else {
|
|
@@ -2071,7 +2397,8 @@ var OneAuthClient = class {
|
|
|
2071
2397
|
if (data.success) {
|
|
2072
2398
|
resolve({
|
|
2073
2399
|
success: true,
|
|
2074
|
-
username: data.data?.username
|
|
2400
|
+
username: data.data?.username,
|
|
2401
|
+
address: data.data?.address
|
|
2075
2402
|
});
|
|
2076
2403
|
} else {
|
|
2077
2404
|
resolve({
|
|
@@ -2147,6 +2474,7 @@ var OneAuthClient = class {
|
|
|
2147
2474
|
resolve({
|
|
2148
2475
|
success: true,
|
|
2149
2476
|
username: data.data?.username,
|
|
2477
|
+
address: data.data?.address,
|
|
2150
2478
|
autoConnected: data.data?.autoConnected
|
|
2151
2479
|
});
|
|
2152
2480
|
} else {
|
|
@@ -2172,6 +2500,45 @@ var OneAuthClient = class {
|
|
|
2172
2500
|
window.addEventListener("message", handleMessage);
|
|
2173
2501
|
});
|
|
2174
2502
|
}
|
|
2503
|
+
waitForConsentResponse(_dialog, _iframe, cleanup) {
|
|
2504
|
+
const dialogOrigin = this.getDialogOrigin();
|
|
2505
|
+
return new Promise((resolve) => {
|
|
2506
|
+
const handleMessage = (event) => {
|
|
2507
|
+
if (event.origin !== dialogOrigin) return;
|
|
2508
|
+
const data = event.data;
|
|
2509
|
+
if (data?.type === "PASSKEY_CONSENT_RESULT") {
|
|
2510
|
+
window.removeEventListener("message", handleMessage);
|
|
2511
|
+
cleanup();
|
|
2512
|
+
if (data.success) {
|
|
2513
|
+
resolve({
|
|
2514
|
+
success: true,
|
|
2515
|
+
data: data.data,
|
|
2516
|
+
grantedAt: data.data?.grantedAt
|
|
2517
|
+
});
|
|
2518
|
+
} else {
|
|
2519
|
+
resolve({
|
|
2520
|
+
success: false,
|
|
2521
|
+
error: data.error ?? {
|
|
2522
|
+
code: "USER_REJECTED",
|
|
2523
|
+
message: "User denied the consent request"
|
|
2524
|
+
}
|
|
2525
|
+
});
|
|
2526
|
+
}
|
|
2527
|
+
} else if (data?.type === "PASSKEY_CLOSE") {
|
|
2528
|
+
window.removeEventListener("message", handleMessage);
|
|
2529
|
+
cleanup();
|
|
2530
|
+
resolve({
|
|
2531
|
+
success: false,
|
|
2532
|
+
error: {
|
|
2533
|
+
code: "USER_CANCELLED",
|
|
2534
|
+
message: "User closed the dialog"
|
|
2535
|
+
}
|
|
2536
|
+
});
|
|
2537
|
+
}
|
|
2538
|
+
};
|
|
2539
|
+
window.addEventListener("message", handleMessage);
|
|
2540
|
+
});
|
|
2541
|
+
}
|
|
2175
2542
|
waitForModalSigningResponse(requestId, _dialog, _iframe, cleanup) {
|
|
2176
2543
|
const dialogOrigin = this.getDialogOrigin();
|
|
2177
2544
|
return new Promise((resolve) => {
|
|
@@ -2380,7 +2747,7 @@ function createOneAuthProvider(options) {
|
|
|
2380
2747
|
const raw = localStorage.getItem(storageKey);
|
|
2381
2748
|
if (!raw) return null;
|
|
2382
2749
|
const parsed = JSON.parse(raw);
|
|
2383
|
-
if (!parsed?.
|
|
2750
|
+
if (!parsed?.address) return null;
|
|
2384
2751
|
return parsed;
|
|
2385
2752
|
} catch {
|
|
2386
2753
|
return null;
|
|
@@ -2416,18 +2783,26 @@ function createOneAuthProvider(options) {
|
|
|
2416
2783
|
}
|
|
2417
2784
|
const connectResult = await client.connectWithModal();
|
|
2418
2785
|
let username;
|
|
2419
|
-
|
|
2786
|
+
let address;
|
|
2787
|
+
if (connectResult.success) {
|
|
2420
2788
|
username = connectResult.username;
|
|
2789
|
+
address = connectResult.address;
|
|
2421
2790
|
} else if (connectResult.action === "switch") {
|
|
2422
2791
|
const authResult = await client.authWithModal();
|
|
2423
|
-
if (!authResult.success
|
|
2792
|
+
if (!authResult.success) {
|
|
2424
2793
|
throw new Error(authResult.error?.message || "Authentication failed");
|
|
2425
2794
|
}
|
|
2426
2795
|
username = authResult.username;
|
|
2796
|
+
address = authResult.address;
|
|
2427
2797
|
} else {
|
|
2428
2798
|
throw new Error(connectResult.error?.message || "Connection cancelled");
|
|
2429
2799
|
}
|
|
2430
|
-
|
|
2800
|
+
if (!address && username) {
|
|
2801
|
+
address = await resolveAccountAddress(username);
|
|
2802
|
+
}
|
|
2803
|
+
if (!address) {
|
|
2804
|
+
throw new Error("No account address available");
|
|
2805
|
+
}
|
|
2431
2806
|
setStoredUser({ username, address });
|
|
2432
2807
|
emit("accountsChanged", [address]);
|
|
2433
2808
|
emit("connect", { chainId: (0, import_viem4.numberToHex)(chainId) });
|
|
@@ -2442,11 +2817,11 @@ function createOneAuthProvider(options) {
|
|
|
2442
2817
|
const stored = getStoredUser();
|
|
2443
2818
|
if (stored) return stored;
|
|
2444
2819
|
const [address] = await connect();
|
|
2445
|
-
|
|
2446
|
-
if (!username || !address) {
|
|
2820
|
+
if (!address) {
|
|
2447
2821
|
throw new Error("Failed to resolve user session");
|
|
2448
2822
|
}
|
|
2449
|
-
|
|
2823
|
+
const user = getStoredUser();
|
|
2824
|
+
return user || { address };
|
|
2450
2825
|
};
|
|
2451
2826
|
const parseChainId = (value) => {
|
|
2452
2827
|
if (typeof value === "number") return value;
|
|
@@ -2504,9 +2879,13 @@ function createOneAuthProvider(options) {
|
|
|
2504
2879
|
}
|
|
2505
2880
|
};
|
|
2506
2881
|
const signMessage = async (message) => {
|
|
2507
|
-
const
|
|
2882
|
+
const user = await ensureUser();
|
|
2883
|
+
if (!user.username && !user.address) {
|
|
2884
|
+
throw new Error("Username or address required for signing.");
|
|
2885
|
+
}
|
|
2508
2886
|
const result = await client.signMessage({
|
|
2509
|
-
username,
|
|
2887
|
+
username: user.username,
|
|
2888
|
+
accountAddress: user.address,
|
|
2510
2889
|
message
|
|
2511
2890
|
});
|
|
2512
2891
|
if (!result.success || !result.signature) {
|
|
@@ -2515,10 +2894,14 @@ function createOneAuthProvider(options) {
|
|
|
2515
2894
|
return encodeWebAuthnSignature(result.signature);
|
|
2516
2895
|
};
|
|
2517
2896
|
const signTypedData = async (typedData) => {
|
|
2518
|
-
const
|
|
2897
|
+
const user = await ensureUser();
|
|
2898
|
+
if (!user.username && !user.address) {
|
|
2899
|
+
throw new Error("Username or address required for signing.");
|
|
2900
|
+
}
|
|
2519
2901
|
const data = typeof typedData === "string" ? JSON.parse(typedData) : typedData;
|
|
2520
2902
|
const result = await client.signTypedData({
|
|
2521
|
-
username,
|
|
2903
|
+
username: user.username,
|
|
2904
|
+
accountAddress: user.address,
|
|
2522
2905
|
domain: data.domain,
|
|
2523
2906
|
types: data.types,
|
|
2524
2907
|
primaryType: data.primaryType,
|
|
@@ -2533,11 +2916,15 @@ function createOneAuthProvider(options) {
|
|
|
2533
2916
|
if (!options.signIntent) {
|
|
2534
2917
|
return {
|
|
2535
2918
|
username: payload.username,
|
|
2919
|
+
accountAddress: payload.accountAddress,
|
|
2536
2920
|
targetChain: payload.targetChain,
|
|
2537
2921
|
calls: payload.calls,
|
|
2538
2922
|
tokenRequests: payload.tokenRequests
|
|
2539
2923
|
};
|
|
2540
2924
|
}
|
|
2925
|
+
if (!payload.username) {
|
|
2926
|
+
throw new Error("Username required for signed intents. Set a username first.");
|
|
2927
|
+
}
|
|
2541
2928
|
const signedIntent = await options.signIntent({
|
|
2542
2929
|
username: payload.username,
|
|
2543
2930
|
accountAddress: payload.accountAddress,
|
|
@@ -2663,10 +3050,13 @@ function createOneAuthProvider(options) {
|
|
|
2663
3050
|
return capabilities;
|
|
2664
3051
|
}
|
|
2665
3052
|
case "wallet_getAssets": {
|
|
2666
|
-
const
|
|
3053
|
+
const user = await ensureUser();
|
|
3054
|
+
if (!user.username) {
|
|
3055
|
+
throw new Error("Username required to fetch assets. Set a username first.");
|
|
3056
|
+
}
|
|
2667
3057
|
const clientId = client.getClientId();
|
|
2668
3058
|
const response = await fetch(
|
|
2669
|
-
`${client.getProviderUrl()}/api/users/${encodeURIComponent(username)}/portfolio`,
|
|
3059
|
+
`${client.getProviderUrl()}/api/users/${encodeURIComponent(user.username)}/portfolio`,
|
|
2670
3060
|
{
|
|
2671
3061
|
headers: clientId ? { "x-client-id": clientId } : {}
|
|
2672
3062
|
}
|