@aztec/wallet-sdk 0.0.1-commit.7d4e6cd → 0.0.1-commit.8afd444

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.
Files changed (69) hide show
  1. package/README.md +218 -355
  2. package/dest/base-wallet/base_wallet.d.ts +33 -10
  3. package/dest/base-wallet/base_wallet.d.ts.map +1 -1
  4. package/dest/base-wallet/base_wallet.js +53 -16
  5. package/dest/crypto.d.ts +73 -27
  6. package/dest/crypto.d.ts.map +1 -1
  7. package/dest/crypto.js +219 -41
  8. package/dest/emoji_alphabet.d.ts +35 -0
  9. package/dest/emoji_alphabet.d.ts.map +1 -0
  10. package/dest/emoji_alphabet.js +299 -0
  11. package/dest/extension/handlers/background_connection_handler.d.ts +158 -0
  12. package/dest/extension/handlers/background_connection_handler.d.ts.map +1 -0
  13. package/dest/extension/handlers/background_connection_handler.js +258 -0
  14. package/dest/extension/handlers/content_script_connection_handler.d.ts +56 -0
  15. package/dest/extension/handlers/content_script_connection_handler.d.ts.map +1 -0
  16. package/dest/extension/handlers/content_script_connection_handler.js +174 -0
  17. package/dest/extension/handlers/index.d.ts +12 -0
  18. package/dest/extension/handlers/index.d.ts.map +1 -0
  19. package/dest/extension/handlers/index.js +10 -0
  20. package/dest/extension/handlers/internal_message_types.d.ts +63 -0
  21. package/dest/extension/handlers/internal_message_types.d.ts.map +1 -0
  22. package/dest/extension/handlers/internal_message_types.js +22 -0
  23. package/dest/extension/provider/extension_provider.d.ts +107 -0
  24. package/dest/extension/provider/extension_provider.d.ts.map +1 -0
  25. package/dest/extension/provider/extension_provider.js +160 -0
  26. package/dest/extension/provider/extension_wallet.d.ts +131 -0
  27. package/dest/extension/provider/extension_wallet.d.ts.map +1 -0
  28. package/dest/extension/provider/extension_wallet.js +271 -0
  29. package/dest/extension/provider/index.d.ts +3 -0
  30. package/dest/extension/provider/index.d.ts.map +1 -0
  31. package/dest/{providers/extension → extension/provider}/index.js +0 -1
  32. package/dest/manager/index.d.ts +2 -7
  33. package/dest/manager/index.d.ts.map +1 -1
  34. package/dest/manager/index.js +0 -4
  35. package/dest/manager/types.d.ts +108 -5
  36. package/dest/manager/types.d.ts.map +1 -1
  37. package/dest/manager/types.js +17 -1
  38. package/dest/manager/wallet_manager.d.ts +50 -7
  39. package/dest/manager/wallet_manager.d.ts.map +1 -1
  40. package/dest/manager/wallet_manager.js +178 -29
  41. package/dest/types.d.ts +55 -15
  42. package/dest/types.d.ts.map +1 -1
  43. package/dest/types.js +10 -2
  44. package/package.json +11 -10
  45. package/src/base-wallet/base_wallet.ts +74 -28
  46. package/src/crypto.ts +263 -47
  47. package/src/emoji_alphabet.ts +317 -0
  48. package/src/extension/handlers/background_connection_handler.ts +423 -0
  49. package/src/extension/handlers/content_script_connection_handler.ts +246 -0
  50. package/src/extension/handlers/index.ts +25 -0
  51. package/src/extension/handlers/internal_message_types.ts +69 -0
  52. package/src/extension/provider/extension_provider.ts +233 -0
  53. package/src/extension/provider/extension_wallet.ts +321 -0
  54. package/src/extension/provider/index.ts +7 -0
  55. package/src/manager/index.ts +3 -9
  56. package/src/manager/types.ts +112 -4
  57. package/src/manager/wallet_manager.ts +204 -31
  58. package/src/types.ts +57 -14
  59. package/dest/providers/extension/extension_provider.d.ts +0 -17
  60. package/dest/providers/extension/extension_provider.d.ts.map +0 -1
  61. package/dest/providers/extension/extension_provider.js +0 -56
  62. package/dest/providers/extension/extension_wallet.d.ts +0 -95
  63. package/dest/providers/extension/extension_wallet.d.ts.map +0 -1
  64. package/dest/providers/extension/extension_wallet.js +0 -225
  65. package/dest/providers/extension/index.d.ts +0 -5
  66. package/dest/providers/extension/index.d.ts.map +0 -1
  67. package/src/providers/extension/extension_provider.ts +0 -72
  68. package/src/providers/extension/extension_wallet.ts +0 -275
  69. package/src/providers/extension/index.ts +0 -11
@@ -0,0 +1,158 @@
1
+ import type { ChainInfo } from '@aztec/aztec.js/account';
2
+ import { type EncryptedPayload } from '../../crypto.js';
3
+ import { type DiscoveryRequest, type KeyExchangeRequest, type WalletInfo, type WalletMessage, type WalletResponse } from '../../types.js';
4
+ import { type BackgroundMessage, type MessageSender } from './internal_message_types.js';
5
+ /**
6
+ * Status of a pending discovery request.
7
+ */
8
+ export type DiscoveryStatus = 'pending' | 'approved' | 'rejected';
9
+ /**
10
+ * A pending discovery request from a dApp.
11
+ */
12
+ export interface PendingDiscovery {
13
+ /** Unique request identifier. */
14
+ requestId: string;
15
+ /** Application identifier. */
16
+ appId: string;
17
+ /** Optional application name. */
18
+ appName?: string;
19
+ /** Origin URL of the requesting page. */
20
+ origin: string;
21
+ /** Network information. */
22
+ chainInfo: ChainInfo;
23
+ /** Browser tab ID. */
24
+ tabId: number;
25
+ /** Request timestamp. */
26
+ timestamp: number;
27
+ /** Current status. */
28
+ status: DiscoveryStatus;
29
+ }
30
+ /**
31
+ * An active session with a connected dApp.
32
+ * Created after key exchange completes.
33
+ */
34
+ export interface ActiveSession {
35
+ /** Unique session identifier. */
36
+ sessionId: string;
37
+ /** Derived AES-GCM encryption key. */
38
+ sharedKey: CryptoKey;
39
+ /** Hex-encoded verification hash for visual comparison. */
40
+ verificationHash: string;
41
+ /** Browser tab ID. */
42
+ tabId: number;
43
+ /** Origin URL of the connected app. */
44
+ origin: string;
45
+ /** Application identifier. */
46
+ appId: string;
47
+ /** Connection timestamp. */
48
+ connectedAt: number;
49
+ /** Network information. */
50
+ chainInfo: ChainInfo;
51
+ }
52
+ /**
53
+ * Transport interface for background script communication.
54
+ */
55
+ export interface BackgroundTransport {
56
+ /**
57
+ * Send a message to a specific tab.
58
+ * Typically `(tabId, message) => browser.tabs.sendMessage(tabId, message)`.
59
+ */
60
+ sendToTab: (tabId: number, message: BackgroundMessage) => void;
61
+ /**
62
+ * Register a listener for messages from content scripts.
63
+ * Typically `browser.runtime.onMessage.addListener`.
64
+ */
65
+ addContentListener: (handler: (message: unknown, sender: MessageSender) => void) => void;
66
+ }
67
+ /**
68
+ * Event callbacks for the background connection handler.
69
+ * All callbacks are optional.
70
+ */
71
+ export interface BackgroundConnectionCallbacks {
72
+ /**
73
+ * Called when a new discovery request is received and stored as pending.
74
+ */
75
+ onPendingDiscovery?: (discovery: PendingDiscovery) => void;
76
+ /**
77
+ * Called when a session is established (key exchange complete).
78
+ */
79
+ onSessionEstablished?: (session: ActiveSession) => void;
80
+ /**
81
+ * Called when a session is terminated.
82
+ */
83
+ onSessionTerminated?: (sessionId: string) => void;
84
+ /**
85
+ * Called when a decrypted wallet message is received.
86
+ */
87
+ onWalletMessage?: (session: ActiveSession, message: WalletMessage) => void;
88
+ }
89
+ /**
90
+ * Configuration for the background connection handler.
91
+ */
92
+ export interface BackgroundConnectionConfig {
93
+ /** Unique wallet identifier. */
94
+ walletId: string;
95
+ /** Display name for the wallet. */
96
+ walletName: string;
97
+ /** Wallet version string. */
98
+ walletVersion: string;
99
+ /** Optional wallet icon URL. */
100
+ walletIcon?: string;
101
+ }
102
+ /**
103
+ * Handles wallet session flow in the extension background script.
104
+ *
105
+ * This class manages:
106
+ * - Pending discovery requests (before user approval)
107
+ * - Active sessions (after key exchange)
108
+ * - Per-session ECDH key exchange
109
+ * - Message encryption/decryption
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * const handler = new BackgroundConnectionHandler(
114
+ * {
115
+ * walletId: 'my-wallet',
116
+ * walletName: 'My Wallet',
117
+ * walletVersion: '1.0.0',
118
+ * },
119
+ * {
120
+ * sendToTab: (tabId, message) => browser.tabs.sendMessage(tabId, message),
121
+ * addContentListener: (handler) => browser.runtime.onMessage.addListener(handler),
122
+ * },
123
+ * {
124
+ * onPendingDiscovery: (discovery) => updateBadge(),
125
+ * onSessionEstablished: (session) => console.log('Connected:', session.sessionId),
126
+ * onWalletMessage: (session, message) => nativePort.postMessage(message),
127
+ * }
128
+ * );
129
+ *
130
+ * handler.initialize();
131
+ * ```
132
+ */
133
+ export declare class BackgroundConnectionHandler {
134
+ private config;
135
+ private transport;
136
+ private callbacks;
137
+ private pendingDiscoveries;
138
+ private activeSessions;
139
+ constructor(config: BackgroundConnectionConfig, transport: BackgroundTransport, callbacks?: BackgroundConnectionCallbacks);
140
+ initialize(): void;
141
+ private handleMessage;
142
+ getWalletInfo(): WalletInfo;
143
+ handleDiscoveryRequest(request: DiscoveryRequest, tabId: number, origin: string): void;
144
+ approveDiscovery(requestId: string): boolean;
145
+ rejectDiscovery(requestId: string): boolean;
146
+ handleKeyExchangeRequest(sessionId: string, request: KeyExchangeRequest): Promise<void>;
147
+ handleEncryptedMessage(sessionId: string, encrypted: EncryptedPayload): Promise<void>;
148
+ sendResponse(sessionId: string, response: WalletResponse): Promise<void>;
149
+ terminateSession(sessionId: string): void;
150
+ terminateForTab(tabId: number): void;
151
+ clearAll(): void;
152
+ getPendingDiscoveries(): PendingDiscovery[];
153
+ getPendingDiscoveryCount(): number;
154
+ getActiveSessions(): ActiveSession[];
155
+ getSession(sessionId: string): ActiveSession | undefined;
156
+ getPendingDiscovery(requestId: string): PendingDiscovery | undefined;
157
+ }
158
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFja2dyb3VuZF9jb25uZWN0aW9uX2hhbmRsZXIuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9leHRlbnNpb24vaGFuZGxlcnMvYmFja2dyb3VuZF9jb25uZWN0aW9uX2hhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFekQsT0FBTyxFQUNMLEtBQUssZ0JBQWdCLEVBT3RCLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUNMLEtBQUssZ0JBQWdCLEVBQ3JCLEtBQUssa0JBQWtCLEVBRXZCLEtBQUssVUFBVSxFQUNmLEtBQUssYUFBYSxFQUVsQixLQUFLLGNBQWMsRUFDcEIsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQ0wsS0FBSyxpQkFBaUIsRUFJdEIsS0FBSyxhQUFhLEVBQ25CLE1BQU0sNkJBQTZCLENBQUM7QUFFckM7O0dBRUc7QUFDSCxNQUFNLE1BQU0sZUFBZSxHQUFHLFNBQVMsR0FBRyxVQUFVLEdBQUcsVUFBVSxDQUFDO0FBRWxFOztHQUVHO0FBQ0gsTUFBTSxXQUFXLGdCQUFnQjtJQUMvQixpQ0FBaUM7SUFDakMsU0FBUyxFQUFFLE1BQU0sQ0FBQztJQUNsQiw4QkFBOEI7SUFDOUIsS0FBSyxFQUFFLE1BQU0sQ0FBQztJQUNkLGlDQUFpQztJQUNqQyxPQUFPLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDakIseUNBQXlDO0lBQ3pDLE1BQU0sRUFBRSxNQUFNLENBQUM7SUFDZiwyQkFBMkI7SUFDM0IsU0FBUyxFQUFFLFNBQVMsQ0FBQztJQUNyQixzQkFBc0I7SUFDdEIsS0FBSyxFQUFFLE1BQU0sQ0FBQztJQUNkLHlCQUF5QjtJQUN6QixTQUFTLEVBQUUsTUFBTSxDQUFDO0lBQ2xCLHNCQUFzQjtJQUN0QixNQUFNLEVBQUUsZUFBZSxDQUFDO0NBQ3pCO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxX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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"background_connection_handler.d.ts","sourceRoot":"","sources":["../../../src/extension/handlers/background_connection_handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EACL,KAAK,gBAAgB,EAOtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EAEvB,KAAK,UAAU,EACf,KAAK,aAAa,EAElB,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,KAAK,iBAAiB,EAItB,KAAK,aAAa,EACnB,MAAM,6BAA6B,CAAC;AAErC;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AAElE;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,2BAA2B;IAC3B,SAAS,EAAE,SAAS,CAAC;IACrB,sBAAsB;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,MAAM,EAAE,eAAe,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,SAAS,EAAE,SAAS,CAAC;IACrB,2DAA2D;IAC3D,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,2BAA2B;IAC3B,SAAS,EAAE,SAAS,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAE/D;;;OAGG;IACH,kBAAkB,EAAE,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,KAAK,IAAI,KAAK,IAAI,CAAC;CAC1F;AAED;;;GAGG;AACH,MAAM,WAAW,6BAA6B;IAC5C;;OAEG;IACH,kBAAkB,CAAC,EAAE,CAAC,SAAS,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAE3D;;OAEG;IACH,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;IAExD;;OAEG;IACH,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAElD;;OAEG;IACH,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;CAC5E;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,gCAAgC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,2BAA2B;IAKpC,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,SAAS;IANnB,OAAO,CAAC,kBAAkB,CAAuC;IACjE,OAAO,CAAC,cAAc,CAAoC;IAE1D,YACU,MAAM,EAAE,0BAA0B,EAClC,SAAS,EAAE,mBAAmB,EAC9B,SAAS,GAAE,6BAAkC,EACnD;IAEJ,UAAU,IAAI,IAAI,CAEjB;IAED,OAAO,CAAC,aAAa,CAoCnB;IAEF,aAAa,IAAI,UAAU,CAO1B;IAED,sBAAsB,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAarF;IAED,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAoB3C;IAED,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAU1C;IAEK,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4C5F;IAEK,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAY1F;IAEK,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB7E;IAED,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAyBxC;IAED,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAWnC;IAED,QAAQ,IAAI,IAAI,CAMf;IAED,qBAAqB,IAAI,gBAAgB,EAAE,CAE1C;IAED,wBAAwB,IAAI,MAAM,CAEjC;IAED,iBAAiB,IAAI,aAAa,EAAE,CAEnC;IAED,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAEvD;IAED,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAEnE;CACF"}
@@ -0,0 +1,258 @@
1
+ import { decrypt, deriveSessionKeys, encrypt, exportPublicKey, generateKeyPair, importPublicKey } from '../../crypto.js';
2
+ import { WalletMessageType } from '../../types.js';
3
+ import { InternalMessageType, MessageOrigin } from './internal_message_types.js';
4
+ /**
5
+ * Handles wallet session flow in the extension background script.
6
+ *
7
+ * This class manages:
8
+ * - Pending discovery requests (before user approval)
9
+ * - Active sessions (after key exchange)
10
+ * - Per-session ECDH key exchange
11
+ * - Message encryption/decryption
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const handler = new BackgroundConnectionHandler(
16
+ * {
17
+ * walletId: 'my-wallet',
18
+ * walletName: 'My Wallet',
19
+ * walletVersion: '1.0.0',
20
+ * },
21
+ * {
22
+ * sendToTab: (tabId, message) => browser.tabs.sendMessage(tabId, message),
23
+ * addContentListener: (handler) => browser.runtime.onMessage.addListener(handler),
24
+ * },
25
+ * {
26
+ * onPendingDiscovery: (discovery) => updateBadge(),
27
+ * onSessionEstablished: (session) => console.log('Connected:', session.sessionId),
28
+ * onWalletMessage: (session, message) => nativePort.postMessage(message),
29
+ * }
30
+ * );
31
+ *
32
+ * handler.initialize();
33
+ * ```
34
+ */ export class BackgroundConnectionHandler {
35
+ config;
36
+ transport;
37
+ callbacks;
38
+ pendingDiscoveries;
39
+ activeSessions;
40
+ constructor(config, transport, callbacks = {}){
41
+ this.config = config;
42
+ this.transport = transport;
43
+ this.callbacks = callbacks;
44
+ this.pendingDiscoveries = new Map();
45
+ this.activeSessions = new Map();
46
+ this.handleMessage = (message, sender)=>{
47
+ const msg = message;
48
+ if (msg.origin !== MessageOrigin.CONTENT_SCRIPT) {
49
+ return;
50
+ }
51
+ const tabId = sender.tab?.id;
52
+ const tabOrigin = sender.tab?.url ? new URL(sender.tab.url).origin : 'unknown';
53
+ if (!tabId) {
54
+ return;
55
+ }
56
+ const { type, sessionId, content } = msg;
57
+ switch(type){
58
+ case InternalMessageType.DISCOVERY_REQUEST:
59
+ this.handleDiscoveryRequest(content, tabId, tabOrigin);
60
+ break;
61
+ case InternalMessageType.KEY_EXCHANGE_REQUEST:
62
+ if (sessionId) {
63
+ this.handleKeyExchangeRequest(sessionId, content).catch(()=>{
64
+ // Key exchange failed - session won't be established
65
+ });
66
+ }
67
+ break;
68
+ case InternalMessageType.DISCONNECT_REQUEST:
69
+ if (sessionId) {
70
+ this.terminateSession(sessionId);
71
+ }
72
+ break;
73
+ case InternalMessageType.SECURE_MESSAGE:
74
+ if (sessionId) {
75
+ void this.handleEncryptedMessage(sessionId, content);
76
+ }
77
+ break;
78
+ }
79
+ };
80
+ }
81
+ initialize() {
82
+ this.transport.addContentListener(this.handleMessage);
83
+ }
84
+ handleMessage;
85
+ getWalletInfo() {
86
+ return {
87
+ id: this.config.walletId,
88
+ name: this.config.walletName,
89
+ version: this.config.walletVersion,
90
+ icon: this.config.walletIcon
91
+ };
92
+ }
93
+ handleDiscoveryRequest(request, tabId, origin) {
94
+ const discovery = {
95
+ requestId: request.requestId,
96
+ appId: request.appId,
97
+ origin,
98
+ chainInfo: request.chainInfo,
99
+ tabId,
100
+ timestamp: Date.now(),
101
+ status: 'pending'
102
+ };
103
+ this.pendingDiscoveries.set(request.requestId, discovery);
104
+ this.callbacks.onPendingDiscovery?.(discovery);
105
+ }
106
+ approveDiscovery(requestId) {
107
+ const discovery = this.pendingDiscoveries.get(requestId);
108
+ if (!discovery || discovery.status !== 'pending') {
109
+ return false;
110
+ }
111
+ // The discovery requestId becomes our sessionId
112
+ // This is what will be used internally to correlate
113
+ // content<->background messages
114
+ const sessionId = requestId;
115
+ discovery.status = 'approved';
116
+ this.transport.sendToTab(discovery.tabId, {
117
+ origin: MessageOrigin.BACKGROUND,
118
+ type: InternalMessageType.DISCOVERY_APPROVED,
119
+ sessionId,
120
+ content: this.getWalletInfo()
121
+ });
122
+ return true;
123
+ }
124
+ rejectDiscovery(requestId) {
125
+ const discovery = this.pendingDiscoveries.get(requestId);
126
+ if (!discovery || discovery.status !== 'pending') {
127
+ return false;
128
+ }
129
+ discovery.status = 'rejected';
130
+ this.pendingDiscoveries.delete(requestId);
131
+ return true;
132
+ }
133
+ async handleKeyExchangeRequest(sessionId, request) {
134
+ const discovery = this.pendingDiscoveries.get(sessionId);
135
+ if (!discovery || discovery.status !== 'approved') {
136
+ return;
137
+ }
138
+ try {
139
+ const keyPair = await generateKeyPair();
140
+ const publicKey = await exportPublicKey(keyPair.publicKey);
141
+ const appPublicKey = await importPublicKey(request.publicKey);
142
+ const sessionKeys = await deriveSessionKeys(keyPair, appPublicKey, false);
143
+ const session = {
144
+ sessionId,
145
+ sharedKey: sessionKeys.encryptionKey,
146
+ verificationHash: sessionKeys.verificationHash,
147
+ tabId: discovery.tabId,
148
+ origin: discovery.origin,
149
+ appId: discovery.appId,
150
+ connectedAt: Date.now(),
151
+ chainInfo: discovery.chainInfo
152
+ };
153
+ this.activeSessions.set(sessionId, session);
154
+ this.pendingDiscoveries.delete(sessionId);
155
+ const response = {
156
+ type: WalletMessageType.KEY_EXCHANGE_RESPONSE,
157
+ requestId: sessionId,
158
+ publicKey
159
+ };
160
+ this.transport.sendToTab(discovery.tabId, {
161
+ origin: MessageOrigin.BACKGROUND,
162
+ type: InternalMessageType.KEY_EXCHANGE_RESPONSE,
163
+ sessionId,
164
+ content: response
165
+ });
166
+ this.callbacks.onSessionEstablished?.(session);
167
+ } catch {
168
+ // Key exchange failed silently - session won't be established
169
+ }
170
+ }
171
+ async handleEncryptedMessage(sessionId, encrypted) {
172
+ const session = this.activeSessions.get(sessionId);
173
+ if (!session) {
174
+ return;
175
+ }
176
+ try {
177
+ const message = await decrypt(session.sharedKey, encrypted);
178
+ this.callbacks.onWalletMessage?.(session, message);
179
+ } catch {
180
+ // Decryption failed - ignore malformed message
181
+ }
182
+ }
183
+ async sendResponse(sessionId, response) {
184
+ const session = this.activeSessions.get(sessionId);
185
+ if (!session) {
186
+ return;
187
+ }
188
+ try {
189
+ const encrypted = await encrypt(session.sharedKey, JSON.stringify(response));
190
+ this.transport.sendToTab(session.tabId, {
191
+ origin: MessageOrigin.BACKGROUND,
192
+ type: InternalMessageType.SECURE_RESPONSE,
193
+ sessionId,
194
+ content: encrypted
195
+ });
196
+ } catch {
197
+ // Encryption failed - response won't be sent
198
+ }
199
+ }
200
+ terminateSession(sessionId) {
201
+ const session = this.activeSessions.get(sessionId);
202
+ if (session) {
203
+ // Notify the content script (and ultimately the dApp) that the session is disconnected
204
+ this.transport.sendToTab(session.tabId, {
205
+ origin: MessageOrigin.BACKGROUND,
206
+ type: InternalMessageType.SESSION_DISCONNECTED,
207
+ sessionId
208
+ });
209
+ this.activeSessions.delete(sessionId);
210
+ this.callbacks.onSessionTerminated?.(sessionId);
211
+ // Restore discovery to approved state so user can retry key exchange
212
+ const discovery = {
213
+ requestId: sessionId,
214
+ appId: session.appId,
215
+ origin: session.origin,
216
+ chainInfo: session.chainInfo,
217
+ tabId: session.tabId,
218
+ timestamp: Date.now(),
219
+ status: 'approved'
220
+ };
221
+ this.pendingDiscoveries.set(sessionId, discovery);
222
+ }
223
+ }
224
+ terminateForTab(tabId) {
225
+ for (const [sessionId, session] of this.activeSessions){
226
+ if (session.tabId === tabId) {
227
+ this.terminateSession(sessionId);
228
+ }
229
+ }
230
+ for (const [requestId, discovery] of this.pendingDiscoveries){
231
+ if (discovery.tabId === tabId) {
232
+ this.pendingDiscoveries.delete(requestId);
233
+ }
234
+ }
235
+ }
236
+ clearAll() {
237
+ for (const sessionId of this.activeSessions.keys()){
238
+ this.callbacks.onSessionTerminated?.(sessionId);
239
+ }
240
+ this.activeSessions.clear();
241
+ this.pendingDiscoveries.clear();
242
+ }
243
+ getPendingDiscoveries() {
244
+ return Array.from(this.pendingDiscoveries.values()).filter((d)=>d.status === 'pending');
245
+ }
246
+ getPendingDiscoveryCount() {
247
+ return this.getPendingDiscoveries().length;
248
+ }
249
+ getActiveSessions() {
250
+ return Array.from(this.activeSessions.values());
251
+ }
252
+ getSession(sessionId) {
253
+ return this.activeSessions.get(sessionId);
254
+ }
255
+ getPendingDiscovery(requestId) {
256
+ return this.pendingDiscoveries.get(requestId);
257
+ }
258
+ }
@@ -0,0 +1,56 @@
1
+ import { type BackgroundMessage, type ContentScriptMessage } from './internal_message_types.js';
2
+ /**
3
+ * Transport interface for content script communication.
4
+ */
5
+ export interface ContentScriptTransport {
6
+ /**
7
+ * Send a message to the background script.
8
+ * Typically `browser.runtime.sendMessage`.
9
+ */
10
+ sendToBackground: (message: ContentScriptMessage) => void;
11
+ /**
12
+ * Register a listener for messages from the background script.
13
+ * Typically `browser.runtime.onMessage.addListener`.
14
+ */
15
+ addBackgroundListener: (handler: (message: BackgroundMessage) => void) => void;
16
+ }
17
+ /**
18
+ * Handles wallet connection flow in the extension content script.
19
+ *
20
+ * This class manages:
21
+ * - Listening for discovery requests from the page
22
+ * - Creating MessageChannels after discovery approval
23
+ * - Relaying key exchange messages between page and background
24
+ * - Relaying encrypted messages between page and background
25
+ *
26
+ * The content script acts as a pure relay - it never has access to
27
+ * private keys or shared secrets.
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * const handler = new ContentScriptConnectionHandler({
32
+ * sendToBackground: (message) => browser.runtime.sendMessage(message),
33
+ * addBackgroundListener: (handler) => browser.runtime.onMessage.addListener(handler),
34
+ * });
35
+ *
36
+ * handler.start();
37
+ * ```
38
+ */
39
+ export declare class ContentScriptConnectionHandler {
40
+ private transport;
41
+ private ports;
42
+ private listening;
43
+ private pageMessageHandler;
44
+ constructor(transport: ContentScriptTransport);
45
+ start(): void;
46
+ private handleBackgroundMessage;
47
+ private handleDiscoveryRequest;
48
+ private handleDiscoveryApproved;
49
+ private handleKeyExchangeResponse;
50
+ private handleSecureResponse;
51
+ private handleSessionDisconnected;
52
+ closeConnection(sessionId: string): void;
53
+ closeAllConnections(): void;
54
+ getConnectionCount(): number;
55
+ }
56
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGVudF9zY3JpcHRfY29ubmVjdGlvbl9oYW5kbGVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZXh0ZW5zaW9uL2hhbmRsZXJzL2NvbnRlbnRfc2NyaXB0X2Nvbm5lY3Rpb25faGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQ0wsS0FBSyxpQkFBaUIsRUFDdEIsS0FBSyxvQkFBb0IsRUFHMUIsTUFBTSw2QkFBNkIsQ0FBQztBQW9DckM7O0dBRUc7QUFDSCxNQUFNLFdBQVcsc0JBQXNCO0lBQ3JDOzs7T0FHRztJQUNILGdCQUFnQixFQUFFLENBQUMsT0FBTyxFQUFFLG9CQUFvQixLQUFLLElBQUksQ0FBQztJQUUxRDs7O09BR0c7SUFDSCxxQkFBcUIsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLE9BQU8sRUFBRSxpQkFBaUIsS0FBSyxJQUFJLEtBQUssSUFBSSxDQUFDO0NBQ2hGO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUNILHFCQUFhLDhCQUE4QjtJQUs3QixPQUFPLENBQUMsU0FBUztJQUo3QixPQUFPLENBQUMsS0FBSyxDQUFxQztJQUNsRCxPQUFPLENBQUMsU0FBUyxDQUFTO0lBQzFCLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBZ0Q7SUFFMUUsWUFBb0IsU0FBUyxFQUFFLHNCQUFzQixFQUFJO0lBRXpELEtBQUssSUFBSSxJQUFJLENBOEJaO0lBRUQsT0FBTyxDQUFDLHVCQUF1QixDQXFCN0I7SUFFRixPQUFPLENBQUMsc0JBQXNCO0lBUTlCLE9BQU8sQ0FBQyx1QkFBdUI7SUFpRC9CLE9BQU8sQ0FBQyx5QkFBeUI7SUFRakMsT0FBTyxDQUFDLG9CQUFvQjtJQVE1QixPQUFPLENBQUMseUJBQXlCO0lBVWpDLGVBQWUsQ0FBQyxTQUFTLEVBQUUsTUFBTSxHQUFHLElBQUksQ0FNdkM7SUFFRCxtQkFBbUIsSUFBSSxJQUFJLENBSzFCO0lBRUQsa0JBQWtCLElBQUksTUFBTSxDQUUzQjtDQUNGIn0=
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content_script_connection_handler.d.ts","sourceRoot":"","sources":["../../../src/extension/handlers/content_script_connection_handler.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EAG1B,MAAM,6BAA6B,CAAC;AAoCrC;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,gBAAgB,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAE1D;;;OAGG;IACH,qBAAqB,EAAE,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,KAAK,IAAI,CAAC;CAChF;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,8BAA8B;IAK7B,OAAO,CAAC,SAAS;IAJ7B,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,kBAAkB,CAAgD;IAE1E,YAAoB,SAAS,EAAE,sBAAsB,EAAI;IAEzD,KAAK,IAAI,IAAI,CA8BZ;IAED,OAAO,CAAC,uBAAuB,CAqB7B;IAEF,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,uBAAuB;IAiD/B,OAAO,CAAC,yBAAyB;IAQjC,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,yBAAyB;IAUjC,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAMvC;IAED,mBAAmB,IAAI,IAAI,CAK1B;IAED,kBAAkB,IAAI,MAAM,CAE3B;CACF"}
@@ -0,0 +1,174 @@
1
+ import { WalletMessageType } from '../../types.js';
2
+ import { InternalMessageType, MessageOrigin } from './internal_message_types.js';
3
+ /**
4
+ * Handles wallet connection flow in the extension content script.
5
+ *
6
+ * This class manages:
7
+ * - Listening for discovery requests from the page
8
+ * - Creating MessageChannels after discovery approval
9
+ * - Relaying key exchange messages between page and background
10
+ * - Relaying encrypted messages between page and background
11
+ *
12
+ * The content script acts as a pure relay - it never has access to
13
+ * private keys or shared secrets.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const handler = new ContentScriptConnectionHandler({
18
+ * sendToBackground: (message) => browser.runtime.sendMessage(message),
19
+ * addBackgroundListener: (handler) => browser.runtime.onMessage.addListener(handler),
20
+ * });
21
+ *
22
+ * handler.start();
23
+ * ```
24
+ */ export class ContentScriptConnectionHandler {
25
+ transport;
26
+ ports;
27
+ listening;
28
+ pageMessageHandler;
29
+ constructor(transport){
30
+ this.transport = transport;
31
+ this.ports = new Map();
32
+ this.listening = false;
33
+ this.pageMessageHandler = null;
34
+ this.handleBackgroundMessage = (message)=>{
35
+ if (message.origin !== MessageOrigin.BACKGROUND) {
36
+ return;
37
+ }
38
+ const { type, sessionId, content } = message;
39
+ switch(type){
40
+ case InternalMessageType.DISCOVERY_APPROVED:
41
+ this.handleDiscoveryApproved(sessionId, content);
42
+ break;
43
+ case InternalMessageType.KEY_EXCHANGE_RESPONSE:
44
+ this.handleKeyExchangeResponse(sessionId, content);
45
+ break;
46
+ case InternalMessageType.SECURE_RESPONSE:
47
+ this.handleSecureResponse(sessionId, content);
48
+ break;
49
+ case InternalMessageType.SESSION_DISCONNECTED:
50
+ this.handleSessionDisconnected(sessionId);
51
+ break;
52
+ }
53
+ };
54
+ }
55
+ start() {
56
+ if (this.listening) {
57
+ return;
58
+ }
59
+ this.transport.addBackgroundListener(this.handleBackgroundMessage);
60
+ this.pageMessageHandler = (event)=>{
61
+ if (event.source !== window) {
62
+ return;
63
+ }
64
+ let data;
65
+ try {
66
+ data = JSON.parse(event.data);
67
+ } catch {
68
+ return;
69
+ }
70
+ if (!data?.type) {
71
+ return;
72
+ }
73
+ if (data.type === WalletMessageType.DISCOVERY) {
74
+ this.handleDiscoveryRequest(data);
75
+ }
76
+ };
77
+ window.addEventListener('message', this.pageMessageHandler);
78
+ this.listening = true;
79
+ }
80
+ handleBackgroundMessage;
81
+ handleDiscoveryRequest(request) {
82
+ this.transport.sendToBackground({
83
+ origin: MessageOrigin.CONTENT_SCRIPT,
84
+ type: InternalMessageType.DISCOVERY_REQUEST,
85
+ content: request
86
+ });
87
+ }
88
+ handleDiscoveryApproved(sessionId, walletInfo) {
89
+ const channel = new MessageChannel();
90
+ this.ports.set(sessionId, {
91
+ port: channel.port1,
92
+ sessionId
93
+ });
94
+ channel.port1.onmessage = (event)=>{
95
+ const data = event.data;
96
+ switch(data?.type){
97
+ case WalletMessageType.KEY_EXCHANGE_REQUEST:
98
+ this.transport.sendToBackground({
99
+ origin: MessageOrigin.CONTENT_SCRIPT,
100
+ type: InternalMessageType.KEY_EXCHANGE_REQUEST,
101
+ sessionId,
102
+ content: data
103
+ });
104
+ break;
105
+ case WalletMessageType.DISCONNECT:
106
+ this.transport.sendToBackground({
107
+ origin: MessageOrigin.CONTENT_SCRIPT,
108
+ type: InternalMessageType.DISCONNECT_REQUEST,
109
+ sessionId,
110
+ content: data
111
+ });
112
+ break;
113
+ default:
114
+ this.transport.sendToBackground({
115
+ origin: MessageOrigin.CONTENT_SCRIPT,
116
+ type: InternalMessageType.SECURE_MESSAGE,
117
+ sessionId,
118
+ content: data
119
+ });
120
+ break;
121
+ }
122
+ };
123
+ channel.port1.start();
124
+ const response = {
125
+ type: WalletMessageType.DISCOVERY_RESPONSE,
126
+ requestId: sessionId,
127
+ walletInfo
128
+ };
129
+ window.postMessage(JSON.stringify(response), '*', [
130
+ channel.port2
131
+ ]);
132
+ }
133
+ handleKeyExchangeResponse(sessionId, response) {
134
+ const connection = this.ports.get(sessionId);
135
+ if (!connection) {
136
+ return;
137
+ }
138
+ connection.port.postMessage(response);
139
+ }
140
+ handleSecureResponse(sessionId, content) {
141
+ const connection = this.ports.get(sessionId);
142
+ if (!connection) {
143
+ return;
144
+ }
145
+ connection.port.postMessage(content);
146
+ }
147
+ handleSessionDisconnected(sessionId) {
148
+ const connection = this.ports.get(sessionId);
149
+ if (!connection) {
150
+ return;
151
+ }
152
+ connection.port.postMessage({
153
+ type: WalletMessageType.DISCONNECT
154
+ });
155
+ connection.port.close();
156
+ this.ports.delete(sessionId);
157
+ }
158
+ closeConnection(sessionId) {
159
+ const connection = this.ports.get(sessionId);
160
+ if (connection) {
161
+ connection.port.close();
162
+ this.ports.delete(sessionId);
163
+ }
164
+ }
165
+ closeAllConnections() {
166
+ for (const [sessionId, connection] of this.ports){
167
+ connection.port.close();
168
+ this.ports.delete(sessionId);
169
+ }
170
+ }
171
+ getConnectionCount() {
172
+ return this.ports.size;
173
+ }
174
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Browser-safe exports for extension background and content scripts.
3
+ *
4
+ * This module contains ONLY handlers that work in service worker/content script
5
+ * environments without Node.js polyfills.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export { BackgroundConnectionHandler, type PendingDiscovery, type ActiveSession, type DiscoveryStatus, type BackgroundConnectionCallbacks, type BackgroundConnectionConfig, type BackgroundTransport, } from './background_connection_handler.js';
10
+ export { ContentScriptConnectionHandler, type ContentScriptTransport } from './content_script_connection_handler.js';
11
+ export { type ContentScriptMessage, type BackgroundMessage, type MessageSender, type MessageOriginType, MessageOrigin, } from './internal_message_types.js';
12
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9leHRlbnNpb24vaGFuZGxlcnMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7R0FPRztBQUNILE9BQU8sRUFDTCwyQkFBMkIsRUFDM0IsS0FBSyxnQkFBZ0IsRUFDckIsS0FBSyxhQUFhLEVBQ2xCLEtBQUssZUFBZSxFQUNwQixLQUFLLDZCQUE2QixFQUNsQyxLQUFLLDBCQUEwQixFQUMvQixLQUFLLG1CQUFtQixHQUN6QixNQUFNLG9DQUFvQyxDQUFDO0FBQzVDLE9BQU8sRUFBRSw4QkFBOEIsRUFBRSxLQUFLLHNCQUFzQixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDckgsT0FBTyxFQUNMLEtBQUssb0JBQW9CLEVBQ3pCLEtBQUssaUJBQWlCLEVBQ3RCLEtBQUssYUFBYSxFQUNsQixLQUFLLGlCQUFpQixFQUN0QixhQUFhLEdBQ2QsTUFBTSw2QkFBNkIsQ0FBQyJ9
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extension/handlers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,2BAA2B,EAC3B,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,6BAA6B,EAClC,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,GACzB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,8BAA8B,EAAE,KAAK,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AACrH,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,aAAa,GACd,MAAM,6BAA6B,CAAC"}