@keyringnetwork/keyring-connect-sdk 3.1.0 → 4.1.0-alpha.1
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/core/VerificationSession.d.ts +62 -0
- package/dist/core/VerificationSession.js +404 -0
- package/dist/core/errors.d.ts +49 -0
- package/dist/core/errors.js +81 -0
- package/dist/core/htppClient.d.ts +17 -0
- package/dist/core/htppClient.js +160 -0
- package/dist/{main.d.ts → core/keyringConnectExtension.d.ts} +9 -7
- package/dist/{main.js → core/keyringConnectExtension.js} +53 -46
- package/dist/core/websocketClient.d.ts +23 -0
- package/dist/core/websocketClient.js +220 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/types/api.d.ts +24 -0
- package/dist/types/api.js +2 -0
- package/dist/types/core.d.ts +78 -0
- package/dist/types/core.js +2 -0
- package/dist/types/extension.d.ts +59 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.js +20 -0
- package/dist/types/websocket.d.ts +68 -0
- package/dist/types/websocket.js +3 -0
- package/dist/ui/UIManager.d.ts +52 -0
- package/dist/ui/UIManager.js +257 -0
- package/dist/ui/components/keyring-button.d.ts +12 -0
- package/dist/ui/components/keyring-button.js +140 -0
- package/dist/ui/components/keyring-text.d.ts +12 -0
- package/dist/ui/components/keyring-text.js +169 -0
- package/dist/ui/composites/keyring-complete-modal.d.ts +19 -0
- package/dist/ui/composites/keyring-complete-modal.js +200 -0
- package/dist/ui/composites/keyring-mobile-modal.d.ts +25 -0
- package/dist/ui/composites/keyring-mobile-modal.js +308 -0
- package/dist/ui/composites/keyring-qr-modal.d.ts +32 -0
- package/dist/ui/composites/keyring-qr-modal.js +464 -0
- package/dist/ui/composites/keyring-selection-modal.d.ts +25 -0
- package/dist/ui/composites/keyring-selection-modal.js +342 -0
- package/dist/ui/composites/keyring-terminated-modal.d.ts +14 -0
- package/dist/ui/composites/keyring-terminated-modal.js +121 -0
- package/dist/ui/icons/apple-icon.d.ts +4 -0
- package/dist/ui/icons/apple-icon.js +47 -0
- package/dist/ui/icons/check-circle.d.ts +4 -0
- package/dist/ui/icons/check-circle.js +35 -0
- package/dist/ui/icons/checkmark.d.ts +4 -0
- package/dist/ui/icons/checkmark.js +37 -0
- package/dist/ui/icons/close-circle.d.ts +4 -0
- package/dist/ui/icons/close-circle.js +35 -0
- package/dist/ui/icons/error-circle.d.ts +4 -0
- package/dist/ui/icons/error-circle.js +48 -0
- package/dist/ui/icons/extension-grid.d.ts +4 -0
- package/dist/ui/icons/extension-grid.js +79 -0
- package/dist/ui/icons/google-icon.d.ts +4 -0
- package/dist/ui/icons/google-icon.js +55 -0
- package/dist/ui/icons/gradient-donut.d.ts +8 -0
- package/dist/ui/icons/gradient-donut.js +85 -0
- package/dist/ui/icons/keyring.d.ts +4 -0
- package/dist/ui/icons/keyring.js +71 -0
- package/dist/ui/icons/mobile-grid.d.ts +4 -0
- package/dist/ui/icons/mobile-grid.js +68 -0
- package/dist/ui/icons/success.d.ts +4 -0
- package/dist/ui/icons/success.js +54 -0
- package/dist/utils/environment.d.ts +34 -0
- package/dist/utils/environment.js +67 -0
- package/dist/utils/logger.d.ts +7 -0
- package/dist/utils/logger.js +40 -0
- package/dist/utils/platformUtils.d.ts +24 -0
- package/dist/utils/platformUtils.js +64 -0
- package/package.json +32 -9
- package/readme.md +57 -105
- package/dist/types.d.ts +0 -159
- /package/dist/{types.js → types/extension.js} +0 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { MobileConnectedMessage, ProcessingCompletedMessage, ProcessingFailedMessage, ProcessingStartedMessage, SessionCreatedMessage, SessionExpiredMessage } from "./websocket";
|
|
2
|
+
export interface SessionConfig {
|
|
3
|
+
/**
|
|
4
|
+
* The name of the client.
|
|
5
|
+
*/
|
|
6
|
+
name: string;
|
|
7
|
+
/**
|
|
8
|
+
* The URL of the client app which the chrome extension will communicate with.
|
|
9
|
+
*/
|
|
10
|
+
app_url: string;
|
|
11
|
+
/**
|
|
12
|
+
* The URL of the client logo.
|
|
13
|
+
*/
|
|
14
|
+
logo_url: string;
|
|
15
|
+
/**
|
|
16
|
+
* The onchain policy ID of the client.
|
|
17
|
+
*/
|
|
18
|
+
policy_id: number;
|
|
19
|
+
/**
|
|
20
|
+
* The wallet address and chain ID of the user.
|
|
21
|
+
*/
|
|
22
|
+
credential_config: {
|
|
23
|
+
chain_id: number;
|
|
24
|
+
wallet_address: string;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* The API key of the client.
|
|
28
|
+
*/
|
|
29
|
+
api_key: string;
|
|
30
|
+
/**
|
|
31
|
+
* Keyring Network configuration for the extension.
|
|
32
|
+
* @note this is meant to be used for internal testing and development purposes.
|
|
33
|
+
*/
|
|
34
|
+
krn_config?: {
|
|
35
|
+
keyring_api_url?: string;
|
|
36
|
+
keyring_user_app_url?: string;
|
|
37
|
+
analytics_api_url?: string;
|
|
38
|
+
notaryUrl?: string;
|
|
39
|
+
websocketProxyUrl?: string;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export interface CredentialData {
|
|
43
|
+
trader: `0x${string}`;
|
|
44
|
+
policyId: number;
|
|
45
|
+
chainId: number;
|
|
46
|
+
validUntil: number;
|
|
47
|
+
cost: number;
|
|
48
|
+
key: string;
|
|
49
|
+
signature: string;
|
|
50
|
+
backdoor: string;
|
|
51
|
+
}
|
|
52
|
+
export interface SDKError {
|
|
53
|
+
code: string;
|
|
54
|
+
message: string;
|
|
55
|
+
details?: any;
|
|
56
|
+
}
|
|
57
|
+
export type SDKErrorCode = "BACKEND_UNAVAILABLE" | "SESSION_CREATION_FAILED" | "SESSION_NOT_FOUND" | "SESSION_EXPIRED" | "WEBSOCKET_CONNECTION_FAILED" | "WEBSOCKET_DISCONNECTED" | "MOBILE_PROCESSING_FAILED" | "NETWORK_ERROR" | "VALIDATION_ERROR" | "TIMEOUT_ERROR" | "QR_DISPLAY_NOT_SUPPORTED";
|
|
58
|
+
export interface SDKCallbacks {
|
|
59
|
+
onSessionCreated?: (data: SessionCreatedMessage["data"]) => void;
|
|
60
|
+
onMobileConnected?: (data: MobileConnectedMessage["data"]) => void;
|
|
61
|
+
onProcessingStarted?: (data: ProcessingStartedMessage["data"]) => void;
|
|
62
|
+
onProcessingCompleted?: (data: ProcessingCompletedMessage["data"]) => void;
|
|
63
|
+
onProcessingFailed?: (data: ProcessingFailedMessage["data"]) => void;
|
|
64
|
+
onSessionExpired?: (data: SessionExpiredMessage["data"]) => void;
|
|
65
|
+
onError?: (error: SDKError) => void;
|
|
66
|
+
onConnectionStatusChanged?: (connected: boolean) => void;
|
|
67
|
+
}
|
|
68
|
+
export type SDKEventTypes = "sessionCreated" | "mobileConnected" | "processingStarted" | "processingCompleted" | "processingFailed" | "sessionExpired" | "error" | "connectionStatusChanged";
|
|
69
|
+
export type SDKEventData = {
|
|
70
|
+
sessionCreated: SessionCreatedMessage["data"];
|
|
71
|
+
mobileConnected: MobileConnectedMessage["data"];
|
|
72
|
+
processingStarted: ProcessingStartedMessage["data"];
|
|
73
|
+
processingCompleted: ProcessingCompletedMessage["data"];
|
|
74
|
+
processingFailed: ProcessingFailedMessage["data"];
|
|
75
|
+
sessionExpired: SessionExpiredMessage["data"];
|
|
76
|
+
error: SDKError;
|
|
77
|
+
connectionStatusChanged: boolean;
|
|
78
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { CredentialData } from "./core";
|
|
2
|
+
export declare enum EVENT_ACTIONS {
|
|
3
|
+
LAUNCH_KEYRING_CONNECT = "LAUNCH_KEYRING_CONNECT",
|
|
4
|
+
GET_STATUS = "GET_STATUS",
|
|
5
|
+
KEYRING_CONNECT_STATUS = "KEYRING_CONNECT_STATUS"
|
|
6
|
+
}
|
|
7
|
+
export type ExtensionLaunchConfig = {
|
|
8
|
+
client: {
|
|
9
|
+
client_name: string;
|
|
10
|
+
client_app_url: string;
|
|
11
|
+
client_logo_url: string;
|
|
12
|
+
client_policy_id: number;
|
|
13
|
+
client_entity_id?: string;
|
|
14
|
+
credential_config: {
|
|
15
|
+
chain_id: number;
|
|
16
|
+
wallet_address: string;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
krn_config?: {
|
|
20
|
+
keyring_api_url?: string;
|
|
21
|
+
keyring_user_app_url?: string;
|
|
22
|
+
analytics_api_url?: string;
|
|
23
|
+
notaryUrl?: string;
|
|
24
|
+
websocketProxyUrl?: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
export type ExtensionStatus = "idle" | "mounted" | "proving" | "prove_error" | "prove_success" | "generate_credential" | "credential_success" | "error";
|
|
28
|
+
export type AttestationStatus = "onboarding_required" | "onboarding_pending" | "attestation_ready" | "non_compliant";
|
|
29
|
+
export type CredentialStatus = "expired" | "valid" | "none";
|
|
30
|
+
export type User = {
|
|
31
|
+
/**
|
|
32
|
+
* Off-chain attestation status.
|
|
33
|
+
*/
|
|
34
|
+
attestation_status: AttestationStatus;
|
|
35
|
+
/**
|
|
36
|
+
* On-chain keyring credential status.
|
|
37
|
+
*/
|
|
38
|
+
credential_status: CredentialStatus;
|
|
39
|
+
/**
|
|
40
|
+
* Connected wallet address of the user.
|
|
41
|
+
*/
|
|
42
|
+
wallet_address: string;
|
|
43
|
+
/**
|
|
44
|
+
* Keyring User ID.
|
|
45
|
+
*/
|
|
46
|
+
user_id: string;
|
|
47
|
+
/**
|
|
48
|
+
* Keyring Entity ID.
|
|
49
|
+
*/
|
|
50
|
+
entity_id: string;
|
|
51
|
+
};
|
|
52
|
+
export interface ExtensionState {
|
|
53
|
+
status: ExtensionStatus;
|
|
54
|
+
manifest?: any;
|
|
55
|
+
error?: string;
|
|
56
|
+
user?: User;
|
|
57
|
+
tlsn_proof?: string;
|
|
58
|
+
credentialData?: CredentialData;
|
|
59
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./api"), exports);
|
|
18
|
+
__exportStar(require("./core"), exports);
|
|
19
|
+
__exportStar(require("./extension"), exports);
|
|
20
|
+
__exportStar(require("./websocket"), exports);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { DataSource } from "@keyringnetwork/keyring-dtos";
|
|
2
|
+
import { CredentialData } from "./core";
|
|
3
|
+
/**
|
|
4
|
+
* Base structure for all WebSocket messages
|
|
5
|
+
*/
|
|
6
|
+
interface BaseMessage {
|
|
7
|
+
type: string;
|
|
8
|
+
session_id: string;
|
|
9
|
+
timestamp: number;
|
|
10
|
+
data?: any;
|
|
11
|
+
}
|
|
12
|
+
export interface SessionCreatedMessage extends BaseMessage {
|
|
13
|
+
type: "session_created";
|
|
14
|
+
data: {
|
|
15
|
+
session_id: string;
|
|
16
|
+
qr_code_data: string;
|
|
17
|
+
expires_at: number | string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export interface MobileConnectedMessage extends BaseMessage {
|
|
21
|
+
type: "mobile_connected";
|
|
22
|
+
data: {
|
|
23
|
+
device_info: {
|
|
24
|
+
platform: "ios" | "android";
|
|
25
|
+
app_version: string;
|
|
26
|
+
};
|
|
27
|
+
connection_id: string;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export interface ProcessingStartedMessage extends BaseMessage {
|
|
31
|
+
type: "processing_started";
|
|
32
|
+
data: any;
|
|
33
|
+
}
|
|
34
|
+
export interface ProcessingCompletedMessage extends BaseMessage {
|
|
35
|
+
type: "processing_completed";
|
|
36
|
+
data: {
|
|
37
|
+
result: {
|
|
38
|
+
credential_data: CredentialData;
|
|
39
|
+
entity_type: string;
|
|
40
|
+
datasource: DataSource;
|
|
41
|
+
};
|
|
42
|
+
status: "success" | "error" | "cancelled";
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export interface ProcessingFailedMessage extends BaseMessage {
|
|
46
|
+
type: "processing_failed" | "error";
|
|
47
|
+
data: {
|
|
48
|
+
error: string;
|
|
49
|
+
[key: string]: any;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export interface SessionExpiredMessage extends BaseMessage {
|
|
53
|
+
type: "session_expired";
|
|
54
|
+
data: {
|
|
55
|
+
reason: "timeout" | "manual";
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Union of all WebSocket message types
|
|
60
|
+
* Used for type-safe message handling
|
|
61
|
+
*/
|
|
62
|
+
export type WebSocketMessage = SessionCreatedMessage | MobileConnectedMessage | ProcessingStartedMessage | ProcessingCompletedMessage | ProcessingFailedMessage | SessionExpiredMessage | {
|
|
63
|
+
type: string;
|
|
64
|
+
session_id: string;
|
|
65
|
+
timestamp: number;
|
|
66
|
+
data?: any;
|
|
67
|
+
};
|
|
68
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import "./components/keyring-button";
|
|
2
|
+
import "./components/keyring-text";
|
|
3
|
+
import "./composites/keyring-complete-modal";
|
|
4
|
+
import "./composites/keyring-mobile-modal";
|
|
5
|
+
import "./composites/keyring-qr-modal";
|
|
6
|
+
import "./composites/keyring-selection-modal";
|
|
7
|
+
import "./composites/keyring-terminated-modal";
|
|
8
|
+
import { DataSource } from "@keyringnetwork/keyring-dtos";
|
|
9
|
+
export declare class UIManager {
|
|
10
|
+
private currentModal;
|
|
11
|
+
private onCancel;
|
|
12
|
+
private onExtensionSelected;
|
|
13
|
+
private onMobileSelected;
|
|
14
|
+
private isExtensionInstalled;
|
|
15
|
+
private readonly STATUS_MODALS;
|
|
16
|
+
/**
|
|
17
|
+
* Show platform selection modal for desktop users
|
|
18
|
+
*/
|
|
19
|
+
showSelectionModal(): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Show QR code modal with app launch button for mobile
|
|
22
|
+
*/
|
|
23
|
+
showMobileModal(qrCodeData: string, expiresAt: number | string): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Show QR code modal with session information
|
|
26
|
+
*/
|
|
27
|
+
showQRModal(qrCodeData: string, sessionId: string, expiresAt: number | string): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Show completion modal with verification results
|
|
30
|
+
*/
|
|
31
|
+
showCompleteModal(entityType: string, dataSource: DataSource): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Show terminated modal with session termination reason
|
|
34
|
+
*/
|
|
35
|
+
showTerminatedModal(): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Update the status display in the modal
|
|
38
|
+
*/
|
|
39
|
+
updateStatus(message: string, status: "pending" | "connected" | "processing" | "completed" | "failed" | "expired"): void;
|
|
40
|
+
/**
|
|
41
|
+
* Hide and clean up the current modal
|
|
42
|
+
*/
|
|
43
|
+
hideModal(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Set callback handlers
|
|
46
|
+
*/
|
|
47
|
+
setCallbacks(onCancel: () => void, onExtensionSelected?: () => void, onMobileSelected?: () => void): void;
|
|
48
|
+
/**
|
|
49
|
+
* Generate QR code using the qr-code-styling library
|
|
50
|
+
*/
|
|
51
|
+
private generateQRCode;
|
|
52
|
+
}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.UIManager = void 0;
|
|
16
|
+
// import * as QRCode from "qrcode";
|
|
17
|
+
const qr_code_styling_1 = __importDefault(require("qr-code-styling"));
|
|
18
|
+
const logger_1 = require("../utils/logger");
|
|
19
|
+
// Import components to register them
|
|
20
|
+
require("./components/keyring-button");
|
|
21
|
+
require("./components/keyring-text");
|
|
22
|
+
require("./composites/keyring-complete-modal");
|
|
23
|
+
require("./composites/keyring-mobile-modal");
|
|
24
|
+
require("./composites/keyring-qr-modal");
|
|
25
|
+
require("./composites/keyring-selection-modal");
|
|
26
|
+
require("./composites/keyring-terminated-modal");
|
|
27
|
+
const keyringConnectExtension_1 = require("../core/keyringConnectExtension");
|
|
28
|
+
const logger = logger_1.KeyringLogger.init("UIManager");
|
|
29
|
+
class UIManager {
|
|
30
|
+
constructor() {
|
|
31
|
+
this.currentModal = null;
|
|
32
|
+
this.onCancel = () => { };
|
|
33
|
+
this.onExtensionSelected = () => { };
|
|
34
|
+
this.onMobileSelected = () => { };
|
|
35
|
+
this.isExtensionInstalled = false;
|
|
36
|
+
this.STATUS_MODALS = ["KEYRING-QR-MODAL", "KEYRING-MOBILE-MODAL"];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Show platform selection modal for desktop users
|
|
40
|
+
*/
|
|
41
|
+
showSelectionModal() {
|
|
42
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
+
this.hideModal(); // Clean up any existing modal
|
|
44
|
+
this.isExtensionInstalled = yield keyringConnectExtension_1.KeyringConnectExtension.isKeyringConnectInstalled();
|
|
45
|
+
const modal = document.createElement("keyring-selection-modal");
|
|
46
|
+
modal.isExtensionInstalled = this.isExtensionInstalled;
|
|
47
|
+
// Set up event listeners
|
|
48
|
+
modal.addEventListener("cancel", () => {
|
|
49
|
+
this.hideModal();
|
|
50
|
+
this.onCancel();
|
|
51
|
+
});
|
|
52
|
+
modal.addEventListener("extension-selected", () => {
|
|
53
|
+
this.hideModal();
|
|
54
|
+
this.onExtensionSelected();
|
|
55
|
+
});
|
|
56
|
+
modal.addEventListener("mobile-selected", () => {
|
|
57
|
+
this.onMobileSelected();
|
|
58
|
+
});
|
|
59
|
+
// Handle backdrop clicks
|
|
60
|
+
modal.addEventListener("click", (e) => {
|
|
61
|
+
if (e.target === modal) {
|
|
62
|
+
this.hideModal();
|
|
63
|
+
this.onCancel();
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
// Add to DOM
|
|
67
|
+
document.body.appendChild(modal);
|
|
68
|
+
this.currentModal = modal;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Show QR code modal with app launch button for mobile
|
|
73
|
+
*/
|
|
74
|
+
showMobileModal(qrCodeData, expiresAt) {
|
|
75
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
+
this.hideModal(); // Clean up any existing modal
|
|
77
|
+
const modal = document.createElement("keyring-mobile-modal");
|
|
78
|
+
// Convert expiresAt to timestamp if it's a string
|
|
79
|
+
const expiresAtTimestamp = typeof expiresAt === "string" ? new Date(expiresAt).getTime() : expiresAt;
|
|
80
|
+
// Set attributes
|
|
81
|
+
modal.qrData = qrCodeData;
|
|
82
|
+
modal.expiresAt = expiresAtTimestamp;
|
|
83
|
+
// Set up event listeners
|
|
84
|
+
modal.addEventListener("cancel", () => {
|
|
85
|
+
this.hideModal();
|
|
86
|
+
this.onCancel();
|
|
87
|
+
});
|
|
88
|
+
// Handle backdrop clicks - don't close the modal
|
|
89
|
+
modal.addEventListener("click", (e) => {
|
|
90
|
+
if (e.target === modal) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
// Add to DOM
|
|
95
|
+
document.body.appendChild(modal);
|
|
96
|
+
this.currentModal = modal;
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Show QR code modal with session information
|
|
101
|
+
*/
|
|
102
|
+
showQRModal(qrCodeData, sessionId, expiresAt) {
|
|
103
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
104
|
+
this.hideModal(); // Clean up any existing modal
|
|
105
|
+
const modal = document.createElement("keyring-qr-modal");
|
|
106
|
+
// Convert expiresAt to timestamp if it's a string
|
|
107
|
+
const expiresAtTimestamp = typeof expiresAt === "string" ? new Date(expiresAt).getTime() : expiresAt;
|
|
108
|
+
// Set attributes
|
|
109
|
+
modal.sessionId = sessionId;
|
|
110
|
+
modal.expiresAt = expiresAtTimestamp;
|
|
111
|
+
modal.qrData = qrCodeData;
|
|
112
|
+
// Generate and add QR code
|
|
113
|
+
const qrCanvas = yield this.generateQRCode(qrCodeData);
|
|
114
|
+
if (qrCanvas) {
|
|
115
|
+
qrCanvas.slot = "qr-code";
|
|
116
|
+
modal.appendChild(qrCanvas);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
modal.qrCodeError = true;
|
|
120
|
+
}
|
|
121
|
+
// Set up event listeners
|
|
122
|
+
modal.addEventListener("cancel", () => {
|
|
123
|
+
this.hideModal();
|
|
124
|
+
this.onCancel();
|
|
125
|
+
});
|
|
126
|
+
modal.addEventListener("back", () => {
|
|
127
|
+
this.onCancel();
|
|
128
|
+
this.showSelectionModal();
|
|
129
|
+
});
|
|
130
|
+
// Handle backdrop clicks - don't close the modal
|
|
131
|
+
modal.addEventListener("click", (e) => {
|
|
132
|
+
if (e.target === modal) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
modal.addEventListener("close", () => {
|
|
137
|
+
this.hideModal();
|
|
138
|
+
});
|
|
139
|
+
// Add to DOM
|
|
140
|
+
document.body.appendChild(modal);
|
|
141
|
+
this.currentModal = modal;
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Show completion modal with verification results
|
|
146
|
+
*/
|
|
147
|
+
showCompleteModal(entityType, dataSource) {
|
|
148
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
149
|
+
this.hideModal(); // Clean up any existing modal
|
|
150
|
+
const modal = document.createElement("keyring-complete-modal");
|
|
151
|
+
// Set attributes
|
|
152
|
+
modal.entityType = entityType;
|
|
153
|
+
modal.dataSource = dataSource.name;
|
|
154
|
+
modal.dataSourceIcon = dataSource.image;
|
|
155
|
+
// Set up event listeners
|
|
156
|
+
modal.addEventListener("close", () => {
|
|
157
|
+
this.hideModal();
|
|
158
|
+
});
|
|
159
|
+
// Handle backdrop clicks
|
|
160
|
+
modal.addEventListener("click", (e) => {
|
|
161
|
+
if (e.target === modal) {
|
|
162
|
+
this.hideModal();
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
// Add to DOM
|
|
166
|
+
document.body.appendChild(modal);
|
|
167
|
+
this.currentModal = modal;
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Show terminated modal with session termination reason
|
|
172
|
+
*/
|
|
173
|
+
showTerminatedModal() {
|
|
174
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
175
|
+
this.hideModal(); // Clean up any existing modal
|
|
176
|
+
const modal = document.createElement("keyring-terminated-modal");
|
|
177
|
+
// Set up event listeners
|
|
178
|
+
modal.addEventListener("close", () => {
|
|
179
|
+
this.hideModal();
|
|
180
|
+
});
|
|
181
|
+
// Handle backdrop clicks
|
|
182
|
+
modal.addEventListener("click", (e) => {
|
|
183
|
+
if (e.target === modal) {
|
|
184
|
+
this.hideModal();
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
// Add to DOM
|
|
188
|
+
document.body.appendChild(modal);
|
|
189
|
+
this.currentModal = modal;
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Update the status display in the modal
|
|
194
|
+
*/
|
|
195
|
+
updateStatus(message, status) {
|
|
196
|
+
if (this.currentModal && this.STATUS_MODALS.includes(this.currentModal.tagName)) {
|
|
197
|
+
this.currentModal.updateStatus(message, status);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Hide and clean up the current modal
|
|
202
|
+
*/
|
|
203
|
+
hideModal() {
|
|
204
|
+
if (this.currentModal && this.currentModal.parentNode) {
|
|
205
|
+
this.currentModal.parentNode.removeChild(this.currentModal);
|
|
206
|
+
}
|
|
207
|
+
this.currentModal = null;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Set callback handlers
|
|
211
|
+
*/
|
|
212
|
+
setCallbacks(onCancel, onExtensionSelected, onMobileSelected) {
|
|
213
|
+
this.onCancel = onCancel;
|
|
214
|
+
if (onExtensionSelected) {
|
|
215
|
+
this.onExtensionSelected = onExtensionSelected;
|
|
216
|
+
}
|
|
217
|
+
if (onMobileSelected) {
|
|
218
|
+
this.onMobileSelected = onMobileSelected;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Generate QR code using the qr-code-styling library
|
|
223
|
+
*/
|
|
224
|
+
generateQRCode(data) {
|
|
225
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
226
|
+
const canvasContainer = document.createElement("div");
|
|
227
|
+
try {
|
|
228
|
+
const qrCode = new qr_code_styling_1.default({
|
|
229
|
+
width: 200,
|
|
230
|
+
height: 200,
|
|
231
|
+
data,
|
|
232
|
+
image: "https://uploads-ssl.webflow.com/65df8e71bab45b70f5433fba/664359927ac82d0c110ff6be_Keyring%20Icon%20Square.svg",
|
|
233
|
+
dotsOptions: {
|
|
234
|
+
color: "#0F2830",
|
|
235
|
+
type: "dots",
|
|
236
|
+
},
|
|
237
|
+
cornersDotOptions: {
|
|
238
|
+
type: "extra-rounded",
|
|
239
|
+
},
|
|
240
|
+
cornersSquareOptions: {
|
|
241
|
+
type: "extra-rounded",
|
|
242
|
+
},
|
|
243
|
+
imageOptions: {
|
|
244
|
+
crossOrigin: "anonymous",
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
qrCode.append(canvasContainer);
|
|
248
|
+
return canvasContainer;
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
logger.error({ error }, "Failed to generate QR code");
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
exports.UIManager = UIManager;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { LitElement } from "lit";
|
|
2
|
+
export type ButtonVariant = "primary" | "secondary" | "ghost";
|
|
3
|
+
export type ButtonSize = "sm" | "md" | "lg";
|
|
4
|
+
export declare class KeyringButton extends LitElement {
|
|
5
|
+
variant: ButtonVariant;
|
|
6
|
+
size: ButtonSize;
|
|
7
|
+
disabled: boolean;
|
|
8
|
+
loading: boolean;
|
|
9
|
+
static styles: import("lit").CSSResult;
|
|
10
|
+
render(): import("lit").TemplateResult<1>;
|
|
11
|
+
private handleClick;
|
|
12
|
+
}
|