@keyringnetwork/keyring-connect-sdk 3.2.0 → 4.1.0-alpha.2
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} +6 -4
- package/dist/{main.js → core/keyringConnectExtension.js} +33 -16
- 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.d.ts → types/extension.d.ts} +2 -49
- 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 +29 -14
- package/readme.md +57 -105
- /package/dist/{types.js → types/extension.js} +0 -0
|
@@ -1,46 +1,9 @@
|
|
|
1
|
+
import { CredentialData } from "./core";
|
|
1
2
|
export declare enum EVENT_ACTIONS {
|
|
2
3
|
LAUNCH_KEYRING_CONNECT = "LAUNCH_KEYRING_CONNECT",
|
|
3
4
|
GET_STATUS = "GET_STATUS",
|
|
4
5
|
KEYRING_CONNECT_STATUS = "KEYRING_CONNECT_STATUS"
|
|
5
6
|
}
|
|
6
|
-
export type ExtensionSDKConfig = {
|
|
7
|
-
/**
|
|
8
|
-
* The name of the client.
|
|
9
|
-
*/
|
|
10
|
-
name: string;
|
|
11
|
-
/**
|
|
12
|
-
* The URL of the client app which the chrome extension will communicate with.
|
|
13
|
-
*/
|
|
14
|
-
app_url: string;
|
|
15
|
-
/**
|
|
16
|
-
* The URL of the client logo.
|
|
17
|
-
*/
|
|
18
|
-
logo_url: string;
|
|
19
|
-
/**
|
|
20
|
-
* The onchain policy ID of the client.
|
|
21
|
-
*/
|
|
22
|
-
policy_id: number;
|
|
23
|
-
/**
|
|
24
|
-
* The wallet address and chain ID of the user.
|
|
25
|
-
*/
|
|
26
|
-
credential_config: {
|
|
27
|
-
chain_id: number;
|
|
28
|
-
wallet_address: string;
|
|
29
|
-
};
|
|
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
|
-
keyring_access_token?: string;
|
|
39
|
-
entity_id?: string;
|
|
40
|
-
notaryUrl?: string;
|
|
41
|
-
websocketProxyUrl?: string;
|
|
42
|
-
};
|
|
43
|
-
};
|
|
44
7
|
export type ExtensionLaunchConfig = {
|
|
45
8
|
client: {
|
|
46
9
|
client_name: string;
|
|
@@ -61,7 +24,7 @@ export type ExtensionLaunchConfig = {
|
|
|
61
24
|
websocketProxyUrl?: string;
|
|
62
25
|
};
|
|
63
26
|
};
|
|
64
|
-
export type ExtensionStatus = "idle" | "mounted" | "proving" | "prove_error" | "prove_success" | "error";
|
|
27
|
+
export type ExtensionStatus = "idle" | "mounted" | "proving" | "prove_error" | "prove_success" | "generate_credential" | "credential_success" | "error";
|
|
65
28
|
export type AttestationStatus = "onboarding_required" | "onboarding_pending" | "attestation_ready" | "non_compliant";
|
|
66
29
|
export type CredentialStatus = "expired" | "valid" | "none";
|
|
67
30
|
export type User = {
|
|
@@ -94,13 +57,3 @@ export interface ExtensionState {
|
|
|
94
57
|
tlsn_proof?: string;
|
|
95
58
|
credentialData?: CredentialData;
|
|
96
59
|
}
|
|
97
|
-
export interface CredentialData {
|
|
98
|
-
trader: `0x${string}`;
|
|
99
|
-
policyId: number;
|
|
100
|
-
chainId: number;
|
|
101
|
-
validUntil: number;
|
|
102
|
-
cost: number;
|
|
103
|
-
key: string;
|
|
104
|
-
signature: string;
|
|
105
|
-
backdoor: string;
|
|
106
|
-
}
|
|
@@ -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 { DatasourceTypes } 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
|
+
datasourceObject: DatasourceTypes.DatasourceObject;
|
|
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 { DatasourceTypes } 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, dataSourceObject: DatasourceTypes.DatasourceObject): 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, dataSourceObject) {
|
|
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 = dataSourceObject.datasource.name;
|
|
154
|
+
modal.dataSourceIcon = dataSourceObject.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
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.KeyringButton = void 0;
|
|
10
|
+
const lit_1 = require("lit");
|
|
11
|
+
const decorators_js_1 = require("lit/decorators.js");
|
|
12
|
+
let KeyringButton = class KeyringButton extends lit_1.LitElement {
|
|
13
|
+
constructor() {
|
|
14
|
+
super(...arguments);
|
|
15
|
+
this.variant = "primary";
|
|
16
|
+
this.size = "md";
|
|
17
|
+
this.disabled = false;
|
|
18
|
+
this.loading = false;
|
|
19
|
+
}
|
|
20
|
+
render() {
|
|
21
|
+
return (0, lit_1.html) `
|
|
22
|
+
<button
|
|
23
|
+
class="button ${this.variant} ${this.size}"
|
|
24
|
+
?disabled=${this.disabled || this.loading}
|
|
25
|
+
@click=${this.handleClick}
|
|
26
|
+
>
|
|
27
|
+
${this.loading ? (0, lit_1.html) `<div class="loading-spinner"></div>` : ""}
|
|
28
|
+
<slot></slot>
|
|
29
|
+
</button>
|
|
30
|
+
`;
|
|
31
|
+
}
|
|
32
|
+
handleClick(e) {
|
|
33
|
+
if (this.disabled || this.loading) {
|
|
34
|
+
e.preventDefault();
|
|
35
|
+
e.stopPropagation();
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
this.dispatchEvent(new CustomEvent("click", {
|
|
39
|
+
bubbles: true,
|
|
40
|
+
composed: true,
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
exports.KeyringButton = KeyringButton;
|
|
45
|
+
KeyringButton.styles = (0, lit_1.css) `
|
|
46
|
+
:host {
|
|
47
|
+
display: inline-block;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.button {
|
|
51
|
+
display: inline-flex;
|
|
52
|
+
align-items: center;
|
|
53
|
+
justify-content: center;
|
|
54
|
+
gap: 8px;
|
|
55
|
+
border: none;
|
|
56
|
+
border-radius: 8px;
|
|
57
|
+
font-weight: 500;
|
|
58
|
+
cursor: pointer;
|
|
59
|
+
transition: all 0.2s ease;
|
|
60
|
+
font-family: inherit;
|
|
61
|
+
width: 100%;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.button:disabled {
|
|
65
|
+
cursor: not-allowed;
|
|
66
|
+
opacity: 0.6;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/* Sizes */
|
|
70
|
+
|
|
71
|
+
.xs {
|
|
72
|
+
padding: 6px 10px;
|
|
73
|
+
font-size: 12px;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.sm {
|
|
77
|
+
padding: 8px 12px;
|
|
78
|
+
font-size: 14px;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.md {
|
|
82
|
+
padding: 10px 16px;
|
|
83
|
+
font-size: 14px;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.lg {
|
|
87
|
+
padding: 12px 20px;
|
|
88
|
+
font-size: 16px;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* Variants */
|
|
92
|
+
.primary {
|
|
93
|
+
background: #0f2830;
|
|
94
|
+
color: #fff;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.primary:hover:not(:disabled) {
|
|
98
|
+
background: #1a3d48;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.ghost {
|
|
102
|
+
background: transparent;
|
|
103
|
+
color: #6b7280;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.ghost:hover:not(:disabled) {
|
|
107
|
+
color: #374151;
|
|
108
|
+
background: #f9fafb;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.loading-spinner {
|
|
112
|
+
width: 16px;
|
|
113
|
+
height: 16px;
|
|
114
|
+
border: 2px solid transparent;
|
|
115
|
+
border-top: 2px solid currentColor;
|
|
116
|
+
border-radius: 50%;
|
|
117
|
+
animation: spin 1s linear infinite;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@keyframes spin {
|
|
121
|
+
to {
|
|
122
|
+
transform: rotate(360deg);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
`;
|
|
126
|
+
__decorate([
|
|
127
|
+
(0, decorators_js_1.property)()
|
|
128
|
+
], KeyringButton.prototype, "variant", void 0);
|
|
129
|
+
__decorate([
|
|
130
|
+
(0, decorators_js_1.property)()
|
|
131
|
+
], KeyringButton.prototype, "size", void 0);
|
|
132
|
+
__decorate([
|
|
133
|
+
(0, decorators_js_1.property)({ type: Boolean })
|
|
134
|
+
], KeyringButton.prototype, "disabled", void 0);
|
|
135
|
+
__decorate([
|
|
136
|
+
(0, decorators_js_1.property)({ type: Boolean })
|
|
137
|
+
], KeyringButton.prototype, "loading", void 0);
|
|
138
|
+
exports.KeyringButton = KeyringButton = __decorate([
|
|
139
|
+
(0, decorators_js_1.customElement)("keyring-button")
|
|
140
|
+
], KeyringButton);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { LitElement } from "lit";
|
|
2
|
+
export type TextVariant = "text-xs" | "text-sm" | "text-base" | "text-lg" | "text-xl" | "text-2xl";
|
|
3
|
+
export type TextColor = "primary" | "secondary" | "success" | "warning" | "error";
|
|
4
|
+
export type FontWeight = "light" | "normal" | "medium" | "semibold" | "bold";
|
|
5
|
+
export declare class KeyringText extends LitElement {
|
|
6
|
+
variant: TextVariant;
|
|
7
|
+
color: TextColor;
|
|
8
|
+
align: "left" | "center" | "right";
|
|
9
|
+
weight: FontWeight;
|
|
10
|
+
static styles: import("lit").CSSResult;
|
|
11
|
+
render(): import("lit").TemplateResult<1>;
|
|
12
|
+
}
|