@seams/wallet 0.14.0 → 0.15.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/.build-inputs.sha256 +1 -1
- package/dist/esm/SeamsWeb/publicApi/keyExport.js +0 -2
- package/dist/esm/SeamsWeb/walletIframe/client/router.js +0 -4
- package/dist/esm/SeamsWeb/walletIframe/shared/facadeBoundary.js +0 -4
- package/dist/esm/core/signingEngine/routerAb/ecdsaDerivation/presignaturePool.js +24 -27
- package/dist/esm/plugins/plugin-utils.js +2 -142
- package/dist/esm/react/components/AccountMenuButton/AccountMenuDialog.js +13 -89
- package/dist/esm/react/components/AccountMenuButton/AuthenticationMethodsModal.js +4 -17
- package/dist/esm/react/components/AccountMenuButton/LinkedDevicesModal.css +0 -68
- package/dist/esm/react/components/AccountMenuButton/LinkedDevicesModal.js +2 -11
- package/dist/esm/react/components/AccountMenuButton/index.js +4 -4
- package/dist/esm/sdk/ecdsaDerivationExport-DOGzq0qC.js +1 -0
- package/dist/esm/sdk/exportKeypairOperation-DzbjKbnk.js +1 -0
- package/dist/esm/sdk/{host-D3Q_NsmE.js → host-DYuu07E5.js} +1 -1
- package/dist/{public/sdk/presignaturePool-DX_hqZ6Z.js → esm/sdk/presignaturePool-V10fZpG3.js} +1 -1
- package/dist/esm/sdk/{runtime-auth-DDOPe7LO.js → runtime-auth-BNR1wI8E.js} +1 -1
- package/dist/esm/sdk/{runtime-device-link-Bkt5AJAI.js → runtime-device-link-Dq8g_UNb.js} +1 -1
- package/dist/{public/sdk/runtime-ecdsa-tempo-DUOkCNFT.js → esm/sdk/runtime-ecdsa-tempo-AGjT7Xpa.js} +1 -1
- package/dist/esm/sdk/{runtime-email-otp-Bsv55Gin.js → runtime-email-otp-BpBOuSsT.js} +1 -1
- package/dist/esm/sdk/{runtime-export-D7QKXvdg.js → runtime-export-CBsacCPY.js} +1 -1
- package/dist/esm/sdk/{runtime-near-Bl7bBU2g.js → runtime-near-J3hKjC7G.js} +1 -1
- package/dist/esm/sdk/{runtime-preferences-C2Rqmp7q.js → runtime-preferences-CVt5sLvm.js} +1 -1
- package/dist/esm/sdk/{runtime-recovery-BMY7AkJq.js → runtime-recovery-BzewdcoT.js} +1 -1
- package/dist/{public/sdk/secp256k1-CL273JMp.js → esm/sdk/secp256k1-CKq7_HD-.js} +1 -1
- package/dist/esm/sdk/shared-BywEqTsd.js +6 -0
- package/dist/esm/sdk/{signEvmFamily-BE0a14MT.js → signEvmFamily-Cpm3e6Zs.js} +1 -1
- package/dist/esm/sdk/wallet-iframe-host-ecdsa.js +1 -1
- package/dist/esm/sdk/wallet-iframe-host-full.js +1 -1
- package/dist/esm/sdk/wallet-iframe-host-near.js +1 -1
- package/dist/esm/sdk/wallet-iframe-host-runtime.js +1 -1
- package/dist/public/headers.manifest.json +1 -1
- package/dist/public/sdk/ecdsaDerivationExport-DOGzq0qC.js +1 -0
- package/dist/public/sdk/exportKeypairOperation-DzbjKbnk.js +1 -0
- package/dist/public/sdk/{host-D3Q_NsmE.js → host-DYuu07E5.js} +1 -1
- package/dist/{esm/sdk/presignaturePool-DX_hqZ6Z.js → public/sdk/presignaturePool-V10fZpG3.js} +1 -1
- package/dist/public/sdk/{runtime-auth-DDOPe7LO.js → runtime-auth-BNR1wI8E.js} +1 -1
- package/dist/public/sdk/{runtime-device-link-Bkt5AJAI.js → runtime-device-link-Dq8g_UNb.js} +1 -1
- package/dist/{esm/sdk/runtime-ecdsa-tempo-DUOkCNFT.js → public/sdk/runtime-ecdsa-tempo-AGjT7Xpa.js} +1 -1
- package/dist/public/sdk/{runtime-email-otp-Bsv55Gin.js → runtime-email-otp-BpBOuSsT.js} +1 -1
- package/dist/public/sdk/{runtime-export-D7QKXvdg.js → runtime-export-CBsacCPY.js} +1 -1
- package/dist/public/sdk/{runtime-near-Bl7bBU2g.js → runtime-near-J3hKjC7G.js} +1 -1
- package/dist/public/sdk/{runtime-preferences-C2Rqmp7q.js → runtime-preferences-CVt5sLvm.js} +1 -1
- package/dist/public/sdk/{runtime-recovery-BMY7AkJq.js → runtime-recovery-BzewdcoT.js} +1 -1
- package/dist/{esm/sdk/secp256k1-CL273JMp.js → public/sdk/secp256k1-CKq7_HD-.js} +1 -1
- package/dist/public/sdk/shared-BywEqTsd.js +6 -0
- package/dist/public/sdk/{signEvmFamily-BE0a14MT.js → signEvmFamily-Cpm3e6Zs.js} +1 -1
- package/dist/public/sdk/wallet-iframe-host-ecdsa.js +1 -1
- package/dist/public/sdk/wallet-iframe-host-full.js +1 -1
- package/dist/public/sdk/wallet-iframe-host-near.js +1 -1
- package/dist/public/sdk/wallet-iframe-host-runtime.js +1 -1
- package/dist/public/wallet-assets.manifest.json +32 -32
- package/dist/public/wallet-service/index.html +4 -4
- package/dist/types/shared-ts/src/device-linking/contracts.d.ts +0 -9
- package/dist/types/shared-ts/src/utils/routerAbEcdsaDerivation.d.ts +0 -1
- package/dist/types/wallet/src/SeamsWeb/operations/auth/login.d.ts +1 -2
- package/dist/types/wallet/src/SeamsWeb/publicApi/types.d.ts +2 -11
- package/dist/types/wallet/src/core/signingEngine/flows/recovery/keyExportFlow.d.ts +0 -3
- package/dist/types/wallet/src/core/signingEngine/routerAb/ecdsaDerivation/presignaturePool.d.ts +0 -19
- package/dist/types/wallet/src/core/signingEngine/session/identity/ownerLaneScope.d.ts +0 -27
- package/dist/types/wallet/src/plugins/plugin-utils.d.ts +0 -30
- package/dist/types/wallet/src/react/components/AccountMenuButton/AccountMenuDialog.d.ts +1 -9
- package/dist/types/wallet/src/react/components/AccountMenuButton/AuthenticationMethodsModal.d.ts +1 -1
- package/dist/types/wallet/src/react/components/AccountMenuButton/LinkedDevicesModal.d.ts +1 -1
- package/package.json +1 -1
- package/dist/esm/plugins/headers.js +0 -55
- package/dist/esm/plugins/next.js +0 -196
- package/dist/esm/plugins/shared-ts/src/utils/normalize.js +0 -31
- package/dist/esm/plugins/vite.js +0 -293
- package/dist/esm/react/components/AccountMenuButton/icons/LayersIcon.js +0 -8
- package/dist/esm/sdk/ecdsaDerivationExport-CuNIssOt.js +0 -1
- package/dist/esm/sdk/exportKeypairOperation-Bql0I-8U.js +0 -1
- package/dist/esm/sdk/shared-CNT5EU_h.js +0 -6
- package/dist/public/sdk/ecdsaDerivationExport-CuNIssOt.js +0 -1
- package/dist/public/sdk/exportKeypairOperation-Bql0I-8U.js +0 -1
- package/dist/public/sdk/shared-CNT5EU_h.js +0 -6
- package/dist/types/wallet/src/plugins/headers.d.ts +0 -25
- package/dist/types/wallet/src/plugins/next.d.ts +0 -66
- package/dist/types/wallet/src/plugins/vite.d.ts +0 -74
- package/dist/types/wallet/src/react/components/AccountMenuButton/icons/LayersIcon.d.ts +0 -2
- /package/dist/esm/plugins/{wallet/src/core → core}/browser/walletIframe/hostVariant.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
9f6cfefb8440e96d1b81504ee0d7e6ac3d60177f8489eb6c94686037c4861834
|
|
@@ -32,7 +32,6 @@ async function exportKey(deps, input) {
|
|
|
32
32
|
};
|
|
33
33
|
requireKeyExportCapability(deps.configs, laneInput);
|
|
34
34
|
const lane = await deps.domain.resolveExactKeyExportLane(laneInput);
|
|
35
|
-
if (lane.kind === "relink_required") return lane;
|
|
36
35
|
if (lane.kind !== "ed25519") throw new Error(`[key-export] expected an Ed25519 lane, received ${lane.kind}`);
|
|
37
36
|
await deps.domain.exportKeypairWithUI({
|
|
38
37
|
...laneInput,
|
|
@@ -49,7 +48,6 @@ async function exportKey(deps, input) {
|
|
|
49
48
|
};
|
|
50
49
|
requireKeyExportCapability(deps.configs, laneInput);
|
|
51
50
|
const lane = await deps.domain.resolveExactKeyExportLane(laneInput);
|
|
52
|
-
if (lane.kind === "relink_required") return lane;
|
|
53
51
|
if (lane.kind !== "ecdsa") throw new Error(`[key-export] expected an ECDSA lane, received ${lane.kind}`);
|
|
54
52
|
await deps.domain.exportKeypairWithUI({
|
|
55
53
|
...laneInput,
|
|
@@ -242,10 +242,6 @@ function walletIframeLoginStatusFromExactSession(state) {
|
|
|
242
242
|
}
|
|
243
243
|
function parseResolveExactKeyExportLaneResult(result) {
|
|
244
244
|
switch (result.kind) {
|
|
245
|
-
case "relink_required": return {
|
|
246
|
-
kind: "relink_required",
|
|
247
|
-
reason: result.reason
|
|
248
|
-
};
|
|
249
245
|
case "ecdsa": return {
|
|
250
246
|
kind: "ecdsa",
|
|
251
247
|
laneIdentity: parseExactEcdsaSigningLaneIdentity(result.laneIdentity)
|
|
@@ -19,10 +19,6 @@ function normalizeResolveExactKeyExportLaneInput(input) {
|
|
|
19
19
|
}
|
|
20
20
|
function normalizeResolveExactKeyExportLaneResult(result) {
|
|
21
21
|
switch (result.kind) {
|
|
22
|
-
case "relink_required": return {
|
|
23
|
-
kind: "relink_required",
|
|
24
|
-
reason: result.reason
|
|
25
|
-
};
|
|
26
22
|
case "ecdsa": return {
|
|
27
23
|
kind: "ecdsa",
|
|
28
24
|
laneIdentity: parseExactEcdsaSigningLaneIdentity(result.laneIdentity)
|
|
@@ -704,7 +704,7 @@ function resolveSigningRequestExpiresAtMs(input) {
|
|
|
704
704
|
const expiresAtMs = Math.min(materialExpiresAtMs, authorizationExpiresAtMs, input.nowMs + ROUTER_AB_ECDSA_DERIVATION_SIGNING_TTL_MS);
|
|
705
705
|
return Number.isSafeInteger(expiresAtMs) && expiresAtMs > input.nowMs ? expiresAtMs : null;
|
|
706
706
|
}
|
|
707
|
-
async function signRouterAbEcdsaDerivationDigestWithPoolHitAttempt(args, retryCount,
|
|
707
|
+
async function signRouterAbEcdsaDerivationDigestWithPoolHitAttempt(args, retryCount, refillInput) {
|
|
708
708
|
let poolKey = null;
|
|
709
709
|
let poolIdentity = null;
|
|
710
710
|
let presignature = null;
|
|
@@ -792,16 +792,16 @@ async function signRouterAbEcdsaDerivationDigestWithPoolHitAttempt(args, retryCo
|
|
|
792
792
|
workerCtx: args.workerCtx
|
|
793
793
|
});
|
|
794
794
|
}
|
|
795
|
-
if (!presignature
|
|
795
|
+
if (!presignature) {
|
|
796
796
|
const foregroundRefillStartedAt = performance.now();
|
|
797
797
|
startForegroundRefill(poolKey);
|
|
798
798
|
try {
|
|
799
799
|
let refill = await refillRouterAbEcdsaDerivationClientPresignaturePool({
|
|
800
|
-
...
|
|
800
|
+
...refillInput,
|
|
801
801
|
trafficClass: "foreground"
|
|
802
802
|
});
|
|
803
803
|
if (!refill.ok && refill.code === "invalidated") refill = await refillRouterAbEcdsaDerivationClientPresignaturePool({
|
|
804
|
-
...
|
|
804
|
+
...refillInput,
|
|
805
805
|
trafficClass: "foreground"
|
|
806
806
|
});
|
|
807
807
|
if (!refill.ok && refill.code !== "pool_full") return refill;
|
|
@@ -884,7 +884,7 @@ async function signRouterAbEcdsaDerivationDigestWithPoolHitAttempt(args, retryCo
|
|
|
884
884
|
emitEcdsaSigningTiming(args.operationId, "presignature_reserve", reserveStartedAt);
|
|
885
885
|
if (reservation.kind === "unavailable") {
|
|
886
886
|
if (reservation.reason === "claimed_elsewhere") clientPresignatureCleanupState = { kind: "owned_elsewhere" };
|
|
887
|
-
if (retryCount < MAX_CLIENT_PRESIGNATURE_CLAIM_RETRIES) return await signRouterAbEcdsaDerivationDigestWithPoolHitAttempt(args, retryCount + 1,
|
|
887
|
+
if (retryCount < MAX_CLIENT_PRESIGNATURE_CLAIM_RETRIES) return await signRouterAbEcdsaDerivationDigestWithPoolHitAttempt(args, retryCount + 1, refillInput);
|
|
888
888
|
return {
|
|
889
889
|
ok: false,
|
|
890
890
|
code: reservation.reason === "expired" ? "pool_entry_expired" : "pool_entry_unavailable",
|
|
@@ -1066,29 +1066,26 @@ async function signRouterAbEcdsaDerivationDigestWithPool(args) {
|
|
|
1066
1066
|
code: "invalid_pool_fill_expiry",
|
|
1067
1067
|
message: "Router A/B ECDSA derivation pool fill expiry is unavailable or expired"
|
|
1068
1068
|
};
|
|
1069
|
-
const
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
workerCtx: args.workerCtx,
|
|
1087
|
-
...ecdsaPoolFillAuthorization(args)
|
|
1088
|
-
}
|
|
1069
|
+
const refillInput = {
|
|
1070
|
+
relayerUrl: args.relayerUrl,
|
|
1071
|
+
keyHandle: args.keyHandle,
|
|
1072
|
+
ecdsaThresholdKeyId: signingIdentity.ecdsaThresholdKeyId,
|
|
1073
|
+
clientVerifyingShareB64u: signingIdentity.clientVerifyingShareB64u,
|
|
1074
|
+
clientSigningMaterial: args.clientSigningMaterial,
|
|
1075
|
+
thresholdEcdsaPublicKeyB64u: signingIdentity.thresholdEcdsaPublicKeyB64u,
|
|
1076
|
+
credential: args.credential,
|
|
1077
|
+
materialActivation: args.materialActivation,
|
|
1078
|
+
routerAbEcdsaDerivationPoolFill: {
|
|
1079
|
+
kind: "router_ab_ecdsa_derivation_signing_worker_pool",
|
|
1080
|
+
scope: args.scope,
|
|
1081
|
+
ceremonyExpiresAtMs: Math.min(expiresAtMs, Date.now() + ROUTER_AB_ECDSA_PRESIGN_CEREMONY_MAX_LIFETIME_MS - PRESIGN_CEREMONY_CLOCK_SKEW_MARGIN_MS),
|
|
1082
|
+
materialExpiresAtMs: args.authorization.kind === "operation_step_up" ? expiresAtMs : Date.now() + MAX_DURABLE_CLIENT_PRESIGNATURE_LIFETIME_MS
|
|
1083
|
+
},
|
|
1084
|
+
workerCtx: args.workerCtx,
|
|
1085
|
+
...ecdsaPoolFillAuthorization(args)
|
|
1089
1086
|
};
|
|
1090
|
-
const result = await signRouterAbEcdsaDerivationDigestWithPoolHitAttempt(args, 0,
|
|
1091
|
-
if (!result.ok && (result.code === "pool_entry_expired" || result.code === "pool_entry_unavailable")) return await signRouterAbEcdsaDerivationDigestWithPoolHitAttempt(args, 0,
|
|
1087
|
+
const result = await signRouterAbEcdsaDerivationDigestWithPoolHitAttempt(args, 0, refillInput);
|
|
1088
|
+
if (!result.ok && (result.code === "pool_entry_expired" || result.code === "pool_entry_unavailable")) return await signRouterAbEcdsaDerivationDigestWithPoolHitAttempt(args, 0, refillInput);
|
|
1092
1089
|
return result;
|
|
1093
1090
|
}
|
|
1094
1091
|
async function refillRouterAbEcdsaDerivationClientPresignaturePool(args) {
|
|
@@ -1,27 +1,5 @@
|
|
|
1
|
-
import "./
|
|
2
|
-
import { normalizeWalletHostVariant, walletHostScriptFileForVariant } from "./wallet/src/core/browser/walletIframe/hostVariant.js";
|
|
3
|
-
import * as fs from "node:fs";
|
|
4
|
-
import * as path from "node:path";
|
|
5
|
-
import { createRequire } from "node:module";
|
|
1
|
+
import { normalizeWalletHostVariant, walletHostScriptFileForVariant } from "./core/browser/walletIframe/hostVariant.js";
|
|
6
2
|
//#region src/plugins/plugin-utils.ts
|
|
7
|
-
function addPreconnectLink(res, origin) {
|
|
8
|
-
if (!origin) return;
|
|
9
|
-
try {
|
|
10
|
-
const link = `<${origin}>; rel=preconnect; crossorigin`;
|
|
11
|
-
const existing = res.getHeader?.("Link");
|
|
12
|
-
if (!existing) {
|
|
13
|
-
res.setHeader?.("Link", link);
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
if (typeof existing === "string") {
|
|
17
|
-
if (!existing.includes(link)) res.setHeader?.("Link", existing + ", " + link);
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
if (Array.isArray(existing)) {
|
|
21
|
-
if (!existing.includes(link)) res.setHeader?.("Link", [...existing, link]);
|
|
22
|
-
}
|
|
23
|
-
} catch {}
|
|
24
|
-
}
|
|
25
3
|
function withAssetVersion(url, assetVersion) {
|
|
26
4
|
const version = String(assetVersion || "").trim();
|
|
27
5
|
if (!version) return url;
|
|
@@ -50,125 +28,7 @@ function buildWalletServiceHtml(sdkBasePath = "/sdk", assetVersion, walletHostVa
|
|
|
50
28
|
</body>
|
|
51
29
|
</html>`;
|
|
52
30
|
}
|
|
53
|
-
function resolveCoepMode(explicit) {
|
|
54
|
-
if (explicit === "strict" || explicit === "off") return explicit;
|
|
55
|
-
const raw = String(globalThis?.process?.env?.VITE_COEP_MODE || "").trim().toLowerCase();
|
|
56
|
-
if (raw === "strict" || raw === "on" || raw === "1" || raw === "require-corp") return "strict";
|
|
57
|
-
if (raw === "off" || raw === "0" || raw === "false") return "off";
|
|
58
|
-
return "off";
|
|
59
|
-
}
|
|
60
|
-
function applyCoepCorp(res) {
|
|
61
|
-
res.setHeader?.("Cross-Origin-Embedder-Policy", "require-corp");
|
|
62
|
-
res.setHeader?.("Cross-Origin-Resource-Policy", "cross-origin");
|
|
63
|
-
}
|
|
64
|
-
function applyCoepCorpIfNeeded(res, coepMode) {
|
|
65
|
-
if (resolveCoepMode(coepMode) !== "off") applyCoepCorp(res);
|
|
66
|
-
}
|
|
67
|
-
function echoCorsFromRequest(res, req, opts = {}) {
|
|
68
|
-
const honorExisting = opts.honorExistingAcaOrigin === true;
|
|
69
|
-
const allowCreds = opts.allowCredentialsWhenExplicit !== false;
|
|
70
|
-
const methods = opts.methods || "GET,OPTIONS";
|
|
71
|
-
const headers = opts.headers || "Content-Type,Authorization";
|
|
72
|
-
const handlePreflight = opts.handlePreflight === true;
|
|
73
|
-
const origin = req?.headers && req.headers.origin || "*";
|
|
74
|
-
const hasExisting = typeof res.getHeader === "function" && !!res.getHeader("Access-Control-Allow-Origin");
|
|
75
|
-
if (!honorExisting || !hasExisting) res.setHeader?.("Access-Control-Allow-Origin", origin);
|
|
76
|
-
res.setHeader?.("Vary", "Origin");
|
|
77
|
-
res.setHeader?.("Access-Control-Allow-Methods", methods);
|
|
78
|
-
res.setHeader?.("Access-Control-Allow-Headers", headers);
|
|
79
|
-
if (origin !== "*" && allowCreds) res.setHeader?.("Access-Control-Allow-Credentials", "true");
|
|
80
|
-
if (handlePreflight) {
|
|
81
|
-
if ((req?.method && String(req.method).toUpperCase()) === "OPTIONS") {
|
|
82
|
-
res.statusCode = 204;
|
|
83
|
-
res.end?.();
|
|
84
|
-
return true;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Log and validate Related Origin Requests (ROR) configuration.
|
|
91
|
-
* - Prints the well-known endpoint and the configured origins list.
|
|
92
|
-
* - Warns if any origins are not absolute (e.g., missing protocol/hostname).
|
|
93
|
-
*/
|
|
94
|
-
function logRorConfig(origins, endpoint = "/.well-known/webauthn") {
|
|
95
|
-
if (!Array.isArray(origins) || origins.length === 0) return;
|
|
96
|
-
const invalid = [];
|
|
97
|
-
for (const o of origins) try {
|
|
98
|
-
const u = new URL(o);
|
|
99
|
-
if (!u.protocol || !u.hostname) invalid.push(o);
|
|
100
|
-
} catch {
|
|
101
|
-
invalid.push(o);
|
|
102
|
-
}
|
|
103
|
-
const msg = `[seams] ROR enabled: GET ${endpoint} -> { origins: [${origins.join(", ")}] }`;
|
|
104
|
-
console.log(msg);
|
|
105
|
-
if (invalid.length > 0) console.warn(`[seams] ROR warning: invalid origins: ${invalid.join(", ")} (expected absolute origins like https://app.example.com)`);
|
|
106
|
-
}
|
|
107
|
-
function sanitizeOrigins(values) {
|
|
108
|
-
const out = /* @__PURE__ */ new Set();
|
|
109
|
-
if (Array.isArray(values)) for (const v of values) {
|
|
110
|
-
if (typeof v !== "string") continue;
|
|
111
|
-
try {
|
|
112
|
-
const u = new URL(v.trim());
|
|
113
|
-
const scheme = u.protocol;
|
|
114
|
-
const host = u.hostname.toLowerCase();
|
|
115
|
-
const port = u.port ? `:${u.port}` : "";
|
|
116
|
-
if (!(scheme === "https:") && !(scheme === "http:" && host === "localhost")) continue;
|
|
117
|
-
if (u.pathname && u.pathname !== "/" || u.search || u.hash) continue;
|
|
118
|
-
out.add(`${scheme}//${host}${port}`);
|
|
119
|
-
} catch {}
|
|
120
|
-
}
|
|
121
|
-
return Array.from(out);
|
|
122
|
-
}
|
|
123
|
-
function parseConfiguredRorOrigins(value) {
|
|
124
|
-
return value.split(",").map((s) => s.trim()).filter(Boolean);
|
|
125
|
-
}
|
|
126
|
-
function resolveRorOrigins(input) {
|
|
127
|
-
return sanitizeOrigins([
|
|
128
|
-
...input.configuredOrigins,
|
|
129
|
-
input.docsOrigin.trim(),
|
|
130
|
-
input.walletOrigin.trim()
|
|
131
|
-
]);
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Infer and set a proper Content-Type header for a given file path.
|
|
135
|
-
* Shared by both app and wallet-iframe dev servers.
|
|
136
|
-
*/
|
|
137
|
-
function setContentType(res, filePath) {
|
|
138
|
-
switch (path.extname(filePath)) {
|
|
139
|
-
case ".js":
|
|
140
|
-
res.setHeader("Content-Type", "application/javascript; charset=utf-8");
|
|
141
|
-
break;
|
|
142
|
-
case ".css":
|
|
143
|
-
res.setHeader("Content-Type", "text/css; charset=utf-8");
|
|
144
|
-
break;
|
|
145
|
-
case ".map":
|
|
146
|
-
case ".json":
|
|
147
|
-
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
148
|
-
break;
|
|
149
|
-
case ".wasm":
|
|
150
|
-
res.setHeader("Content-Type", "application/wasm");
|
|
151
|
-
break;
|
|
152
|
-
case ".html":
|
|
153
|
-
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
154
|
-
break;
|
|
155
|
-
default: res.setHeader("Content-Type", "application/octet-stream");
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
const requireCjs = createRequire(import.meta.url);
|
|
159
|
-
function resolveSdkDistRoot(explicit) {
|
|
160
|
-
if (explicit) return path.resolve(explicit);
|
|
161
|
-
const pkgPath = requireCjs.resolve("@seams/wallet/package.json");
|
|
162
|
-
const pkgDir = path.dirname(pkgPath);
|
|
163
|
-
try {
|
|
164
|
-
const esmEntry = JSON.parse(fs.readFileSync(pkgPath, "utf8")).module || "dist/esm/index.js";
|
|
165
|
-
const esmAbs = path.resolve(pkgDir, esmEntry);
|
|
166
|
-
return path.resolve(path.dirname(esmAbs), "..");
|
|
167
|
-
} catch {
|
|
168
|
-
return path.join(pkgDir, "dist");
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
31
|
//#endregion
|
|
172
|
-
export {
|
|
32
|
+
export { buildWalletServiceHtml };
|
|
173
33
|
|
|
174
34
|
//# sourceMappingURL=plugin-utils.js.map
|
|
@@ -1,58 +1,9 @@
|
|
|
1
1
|
import { Theme, useTheme } from "../theme/ThemeProvider.js";
|
|
2
2
|
import { AccountMenuScreen } from "./AccountMenuScreen.js";
|
|
3
|
-
import
|
|
4
|
-
import { LayersIcon } from "./icons/LayersIcon.js";
|
|
5
|
-
import React, { useEffect } from "react";
|
|
3
|
+
import React from "react";
|
|
6
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
5
|
//#region src/react/components/AccountMenuButton/AccountMenuDialog.tsx
|
|
8
|
-
|
|
9
|
-
const { isOpen, presentation, onClose, dialogRef, focusableSelector } = input;
|
|
10
|
-
const previousFocusRef = React.useRef(null);
|
|
11
|
-
const handleDialogKeyDown = React.useCallback((event) => {
|
|
12
|
-
if (event.key === "Escape" || event.key === "Esc") {
|
|
13
|
-
event.preventDefault();
|
|
14
|
-
onClose();
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
if (event.key !== "Tab" || !dialogRef.current) return;
|
|
18
|
-
const focusable = Array.from(dialogRef.current.querySelectorAll(focusableSelector));
|
|
19
|
-
if (focusable.length === 0) {
|
|
20
|
-
event.preventDefault();
|
|
21
|
-
dialogRef.current.focus();
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
const first = focusable[0];
|
|
25
|
-
const last = focusable[focusable.length - 1];
|
|
26
|
-
if (event.shiftKey && document.activeElement === first) {
|
|
27
|
-
event.preventDefault();
|
|
28
|
-
last.focus();
|
|
29
|
-
} else if (!event.shiftKey && document.activeElement === last) {
|
|
30
|
-
event.preventDefault();
|
|
31
|
-
first.focus();
|
|
32
|
-
}
|
|
33
|
-
}, [
|
|
34
|
-
dialogRef,
|
|
35
|
-
focusableSelector,
|
|
36
|
-
onClose
|
|
37
|
-
]);
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
if (!isOpen || presentation !== "modal") return;
|
|
40
|
-
previousFocusRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
41
|
-
dialogRef.current?.focus({ preventScroll: true });
|
|
42
|
-
window.addEventListener("keydown", handleDialogKeyDown);
|
|
43
|
-
return () => {
|
|
44
|
-
window.removeEventListener("keydown", handleDialogKeyDown);
|
|
45
|
-
previousFocusRef.current?.focus();
|
|
46
|
-
previousFocusRef.current = null;
|
|
47
|
-
};
|
|
48
|
-
}, [
|
|
49
|
-
dialogRef,
|
|
50
|
-
handleDialogKeyDown,
|
|
51
|
-
isOpen,
|
|
52
|
-
presentation
|
|
53
|
-
]);
|
|
54
|
-
}
|
|
55
|
-
const AccountMenuDialogFrame = ({ presentation, onClose, dialogRef, contentClassName, titleId, title, closeLabel, children }) => {
|
|
6
|
+
const AccountMenuDialogFrame = ({ presentation, onClose, dialogRef, contentClassName, titleId, title, children }) => {
|
|
56
7
|
const { theme, tokens } = useTheme();
|
|
57
8
|
const scopedTokens = React.useMemo(() => theme === "dark" ? { dark: tokens } : { light: tokens }, [theme, tokens]);
|
|
58
9
|
if (presentation === "embedded") return /* @__PURE__ */ jsx(AccountMenuScreen, {
|
|
@@ -68,52 +19,25 @@ const AccountMenuDialogFrame = ({ presentation, onClose, dialogRef, contentClass
|
|
|
68
19
|
className: `seams-linked-devices-modal-backdrop theme-${theme}`,
|
|
69
20
|
"data-presentation": presentation,
|
|
70
21
|
role: "presentation",
|
|
71
|
-
|
|
72
|
-
if (presentation === "modal" && event.target === event.currentTarget) onClose();
|
|
73
|
-
},
|
|
74
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
22
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
75
23
|
ref: dialogRef,
|
|
76
24
|
className: `seams-linked-devices-modal-content ${contentClassName}`,
|
|
77
|
-
role:
|
|
78
|
-
"aria-modal": presentation === "modal" ? true : void 0,
|
|
25
|
+
role: "region",
|
|
79
26
|
"aria-labelledby": titleId,
|
|
80
27
|
tabIndex: -1,
|
|
81
|
-
children:
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}),
|
|
90
|
-
/* @__PURE__ */ jsx("button", {
|
|
91
|
-
type: "button",
|
|
92
|
-
className: "seams-linked-devices-modal-close",
|
|
93
|
-
onClick: onClose,
|
|
94
|
-
"aria-label": closeLabel,
|
|
95
|
-
children: "✕"
|
|
96
|
-
})
|
|
97
|
-
]
|
|
98
|
-
}) : null,
|
|
99
|
-
/* @__PURE__ */ jsxs("div", {
|
|
100
|
-
className: "seams-account-menu-dialog-main",
|
|
101
|
-
children: [/* @__PURE__ */ jsx("h2", {
|
|
102
|
-
id: titleId,
|
|
103
|
-
className: "seams-linked-devices-modal-title",
|
|
104
|
-
children: title
|
|
105
|
-
}), children]
|
|
106
|
-
}),
|
|
107
|
-
presentation === "modal" ? /* @__PURE__ */ jsxs("footer", {
|
|
108
|
-
className: "seams-account-menu-dialog-footer",
|
|
109
|
-
children: [/* @__PURE__ */ jsx(LayersIcon, { size: 13 }), "Powered by seams"]
|
|
110
|
-
}) : null
|
|
111
|
-
]
|
|
28
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
29
|
+
className: "seams-account-menu-dialog-main",
|
|
30
|
+
children: [/* @__PURE__ */ jsx("h2", {
|
|
31
|
+
id: titleId,
|
|
32
|
+
className: "seams-linked-devices-modal-title",
|
|
33
|
+
children: title
|
|
34
|
+
}), children]
|
|
35
|
+
})
|
|
112
36
|
})
|
|
113
37
|
})
|
|
114
38
|
});
|
|
115
39
|
};
|
|
116
40
|
//#endregion
|
|
117
|
-
export { AccountMenuDialogFrame
|
|
41
|
+
export { AccountMenuDialogFrame };
|
|
118
42
|
|
|
119
43
|
//# sourceMappingURL=AccountMenuDialog.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useSeams } from "../../context/index.js";
|
|
2
|
-
import { AccountMenuDialogFrame
|
|
2
|
+
import { AccountMenuDialogFrame } from "./AccountMenuDialog.js";
|
|
3
3
|
import { AuthenticationMethodRow } from "./AuthenticationMethodRow.js";
|
|
4
4
|
import { AuthenticationMethodsView } from "./AuthenticationMethodsView.js";
|
|
5
5
|
import { PlusIcon } from "./icons/PlusIcon.js";
|
|
@@ -95,7 +95,6 @@ function currentAuthorityInventory(input) {
|
|
|
95
95
|
}
|
|
96
96
|
throw new Error("The selected authentication method is unavailable on this device authority.");
|
|
97
97
|
}
|
|
98
|
-
const FOCUSABLE_DIALOG_ELEMENTS = "button:not([disabled]), input:not([disabled]), [href], [tabindex]:not([tabindex=\"-1\"])";
|
|
99
98
|
function methodTitle(method) {
|
|
100
99
|
return method.kind === "passkey" ? "Passkey" : "Email OTP";
|
|
101
100
|
}
|
|
@@ -113,7 +112,7 @@ function inventoryStatus(state) {
|
|
|
113
112
|
case "loaded": return state.inventory.kind === "local_selection" ? "Unlock to manage" : "Active";
|
|
114
113
|
}
|
|
115
114
|
}
|
|
116
|
-
const AuthenticationMethodsModal = ({ walletId, isOpen, onClose, presentation
|
|
115
|
+
const AuthenticationMethodsModal = ({ walletId, isOpen, onClose, presentation }) => {
|
|
117
116
|
const { seams, loginState, refreshSession } = useSeams();
|
|
118
117
|
const [loadState, setLoadState] = React.useState({ kind: "idle" });
|
|
119
118
|
const [actionState, setActionState] = React.useState({ kind: "idle" });
|
|
@@ -184,13 +183,6 @@ const AuthenticationMethodsModal = ({ walletId, isOpen, onClose, presentation =
|
|
|
184
183
|
});
|
|
185
184
|
}
|
|
186
185
|
}, [selectedWalletAuthMethodId, walletId]);
|
|
187
|
-
useAccountMenuDialogKeyboard({
|
|
188
|
-
isOpen,
|
|
189
|
-
presentation,
|
|
190
|
-
onClose,
|
|
191
|
-
dialogRef,
|
|
192
|
-
focusableSelector: FOCUSABLE_DIALOG_ELEMENTS
|
|
193
|
-
});
|
|
194
186
|
useEffect(() => {
|
|
195
187
|
if (!isOpen) {
|
|
196
188
|
loadSequence.current += 1;
|
|
@@ -280,10 +272,8 @@ const AuthenticationMethodsModal = ({ walletId, isOpen, onClose, presentation =
|
|
|
280
272
|
walletAuthMethodId: method.walletAuthMethodId
|
|
281
273
|
});
|
|
282
274
|
await refreshSessionRef.current(walletId);
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
await loadInventory();
|
|
286
|
-
} else onClose();
|
|
275
|
+
setActionState({ kind: "idle" });
|
|
276
|
+
await loadInventory();
|
|
287
277
|
} catch (error) {
|
|
288
278
|
setActionState({
|
|
289
279
|
kind: "error",
|
|
@@ -293,8 +283,6 @@ const AuthenticationMethodsModal = ({ walletId, isOpen, onClose, presentation =
|
|
|
293
283
|
}, [
|
|
294
284
|
actionState,
|
|
295
285
|
loadInventory,
|
|
296
|
-
onClose,
|
|
297
|
-
presentation,
|
|
298
286
|
walletId
|
|
299
287
|
]);
|
|
300
288
|
if (!isOpen) return null;
|
|
@@ -311,7 +299,6 @@ const AuthenticationMethodsModal = ({ walletId, isOpen, onClose, presentation =
|
|
|
311
299
|
contentClassName: "seams-auth-methods-modal-content",
|
|
312
300
|
titleId: "seams-auth-methods-modal-title",
|
|
313
301
|
title: "Authentication methods",
|
|
314
|
-
closeLabel: "Close authentication methods",
|
|
315
302
|
children: /* @__PURE__ */ jsx(AuthenticationMethodsView, {
|
|
316
303
|
walletLabel: walletId ?? "Wallet",
|
|
317
304
|
status: inventoryStatus(loadState),
|
|
@@ -50,36 +50,6 @@
|
|
|
50
50
|
outline: none;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
/* Modal chrome: the page's host above the content, "Powered by seams" below. */
|
|
54
|
-
.seams-account-menu-dialog-header,
|
|
55
|
-
.seams-account-menu-dialog-footer {
|
|
56
|
-
display: flex;
|
|
57
|
-
flex-shrink: 0;
|
|
58
|
-
align-items: center;
|
|
59
|
-
gap: 0.4375rem;
|
|
60
|
-
color: var(--seams-colors-textSecondary);
|
|
61
|
-
font-size: 0.75rem;
|
|
62
|
-
line-height: 1.5;
|
|
63
|
-
}
|
|
64
|
-
.seams-account-menu-dialog-header {
|
|
65
|
-
padding: 0 0.375rem 0 1.375rem;
|
|
66
|
-
border-bottom: 1px solid var(--seams-colors-borderPrimary);
|
|
67
|
-
}
|
|
68
|
-
.seams-account-menu-dialog-host {
|
|
69
|
-
min-width: 0;
|
|
70
|
-
overflow: hidden;
|
|
71
|
-
text-overflow: ellipsis;
|
|
72
|
-
white-space: nowrap;
|
|
73
|
-
}
|
|
74
|
-
.seams-account-menu-dialog-footer {
|
|
75
|
-
padding: 0.875rem 1.375rem;
|
|
76
|
-
border-top: 1px solid var(--seams-colors-borderPrimary);
|
|
77
|
-
background: var(--seams-colors-surface);
|
|
78
|
-
}
|
|
79
|
-
.seams-account-menu-dialog-header > svg,
|
|
80
|
-
.seams-account-menu-dialog-footer > svg {
|
|
81
|
-
flex-shrink: 0;
|
|
82
|
-
}
|
|
83
53
|
.seams-account-menu-dialog-main {
|
|
84
54
|
display: flex;
|
|
85
55
|
flex: 1 1 auto;
|
|
@@ -119,36 +89,6 @@
|
|
|
119
89
|
line-height: 1.5;
|
|
120
90
|
}
|
|
121
91
|
|
|
122
|
-
.seams-linked-devices-modal-close {
|
|
123
|
-
margin-inline-start: auto;
|
|
124
|
-
background: none;
|
|
125
|
-
border: none;
|
|
126
|
-
font-size: 0.875rem;
|
|
127
|
-
font-weight: 600;
|
|
128
|
-
color: var(--seams-colors-textMuted);
|
|
129
|
-
cursor: pointer;
|
|
130
|
-
box-sizing: border-box;
|
|
131
|
-
padding: 0;
|
|
132
|
-
border-radius: 50%;
|
|
133
|
-
width: 44px;
|
|
134
|
-
min-width: 44px;
|
|
135
|
-
height: 44px;
|
|
136
|
-
min-height: 44px;
|
|
137
|
-
display: inline-flex;
|
|
138
|
-
align-items: center;
|
|
139
|
-
justify-content: center;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
.seams-linked-devices-modal-close:hover {
|
|
143
|
-
color: var(--seams-colors-textPrimary);
|
|
144
|
-
background: var(--seams-colors-surface);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
.seams-linked-devices-modal-close:focus-visible {
|
|
148
|
-
outline: 2px solid currentColor;
|
|
149
|
-
outline-offset: 2px;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
92
|
.seams-linked-devices-modal-body {
|
|
153
93
|
display: grid;
|
|
154
94
|
min-height: 0;
|
|
@@ -551,14 +491,6 @@
|
|
|
551
491
|
padding: var(--seams-spacing-md, 1rem);
|
|
552
492
|
}
|
|
553
493
|
|
|
554
|
-
.seams-account-menu-dialog-header {
|
|
555
|
-
padding-inline-start: var(--seams-spacing-md, 1rem);
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
.seams-account-menu-dialog-footer {
|
|
559
|
-
padding-inline: var(--seams-spacing-md, 1rem);
|
|
560
|
-
}
|
|
561
|
-
|
|
562
494
|
.seams-linked-devices-modal-item-main {
|
|
563
495
|
align-items: flex-start;
|
|
564
496
|
flex-direction: column;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useSeams } from "../../context/index.js";
|
|
2
2
|
import { AccountMenuDeviceDetails } from "./AccountMenuDeviceDetails.js";
|
|
3
|
-
import { AccountMenuDialogFrame
|
|
3
|
+
import { AccountMenuDialogFrame } from "./AccountMenuDialog.js";
|
|
4
4
|
import { MailIcon } from "./icons/MailIcon.js";
|
|
5
5
|
import { AuthenticationMethodRow } from "./AuthenticationMethodRow.js";
|
|
6
6
|
import { LaptopIcon } from "./icons/LaptopIcon.js";
|
|
@@ -200,8 +200,7 @@ function withLinkedDevicesLoadTimeout(promise) {
|
|
|
200
200
|
});
|
|
201
201
|
});
|
|
202
202
|
}
|
|
203
|
-
const
|
|
204
|
-
const LinkedDevicesModal = ({ walletId, isOpen, onClose, presentation = "modal" }) => {
|
|
203
|
+
const LinkedDevicesModal = ({ walletId, isOpen, onClose, presentation }) => {
|
|
205
204
|
const { seams, loginState } = useSeams();
|
|
206
205
|
const [loadState, setLoadState] = React.useState({ kind: "idle" });
|
|
207
206
|
const [revokeState, setRevokeState] = React.useState({ kind: "idle" });
|
|
@@ -239,13 +238,6 @@ const LinkedDevicesModal = ({ walletId, isOpen, onClose, presentation = "modal"
|
|
|
239
238
|
});
|
|
240
239
|
}
|
|
241
240
|
}, [walletId]);
|
|
242
|
-
useAccountMenuDialogKeyboard({
|
|
243
|
-
isOpen,
|
|
244
|
-
presentation,
|
|
245
|
-
onClose,
|
|
246
|
-
dialogRef,
|
|
247
|
-
focusableSelector: FOCUSABLE_DIALOG_ELEMENTS
|
|
248
|
-
});
|
|
249
241
|
useEffect(() => {
|
|
250
242
|
if (!isOpen) {
|
|
251
243
|
loadSeq.current += 1;
|
|
@@ -301,7 +293,6 @@ const LinkedDevicesModal = ({ walletId, isOpen, onClose, presentation = "modal"
|
|
|
301
293
|
contentClassName: "seams-linked-devices-inventory-content",
|
|
302
294
|
titleId: "seams-linked-devices-modal-title",
|
|
303
295
|
title: selectedDevice ? "Device details" : "Linked devices",
|
|
304
|
-
closeLabel: "Close linked devices",
|
|
305
296
|
children: [selectedDevice ? /* @__PURE__ */ jsx(AccountMenuDeviceDetails, {
|
|
306
297
|
title: credentialDescription(viewCredential(selectedDevice.view)),
|
|
307
298
|
description: deviceMetaLine(selectedDevice.view, selectedDevice.deviceNumber, false, Date.now()),
|
|
@@ -207,21 +207,21 @@ const AccountMenuButtonInner = ({ presentation, nearAccountId: nearAccountIdProp
|
|
|
207
207
|
sessionNearAccountId: nearAccountId,
|
|
208
208
|
getNearAccountState: seams.registration.getNearAccountState
|
|
209
209
|
});
|
|
210
|
-
|
|
210
|
+
await seams.keys.exportKey({
|
|
211
211
|
kind: "ed25519",
|
|
212
212
|
walletSession: walletId,
|
|
213
213
|
nearAccount: exportNearAccountId,
|
|
214
214
|
options: { onEvent: onExportKeyEvent }
|
|
215
|
-
})
|
|
215
|
+
});
|
|
216
216
|
return;
|
|
217
217
|
}
|
|
218
218
|
const chainTarget = thresholdEcdsaChainTargetFromConfig(requirePrimaryChainByFamily(seams.configs.network.chains, "evm"));
|
|
219
|
-
|
|
219
|
+
await seams.keys.exportKey({
|
|
220
220
|
kind: "ecdsa",
|
|
221
221
|
walletSession: walletId,
|
|
222
222
|
chainTarget,
|
|
223
223
|
options: { onEvent: onExportKeyEvent }
|
|
224
|
-
})
|
|
224
|
+
});
|
|
225
225
|
} catch (error) {
|
|
226
226
|
setSettingsError(formatExportKeyErrorMessage(error));
|
|
227
227
|
console.error("[AccountMenuButton] Key export failed:", error);
|