@meshconnect/uwc-bridge-parent 0.0.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/BridgeParent.d.ts +58 -0
- package/dist/BridgeParent.d.ts.map +1 -0
- package/dist/BridgeParent.js +127 -0
- package/dist/BridgeParent.js.map +1 -0
- package/dist/bridge-parent.d.ts +27 -0
- package/dist/bridge-parent.d.ts.map +1 -0
- package/dist/bridge-parent.js +148 -0
- package/dist/bridge-parent.js.map +1 -0
- package/dist/comlink-bridge.d.ts +26 -0
- package/dist/comlink-bridge.d.ts.map +1 -0
- package/dist/comlink-bridge.js +126 -0
- package/dist/comlink-bridge.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/postmate-bridge.d.ts +37 -0
- package/dist/postmate-bridge.d.ts.map +1 -0
- package/dist/postmate-bridge.js +631 -0
- package/dist/postmate-bridge.js.map +1 -0
- package/dist/standard-wallet-adapter.d.ts +17 -0
- package/dist/standard-wallet-adapter.d.ts.map +1 -0
- package/dist/standard-wallet-adapter.js +53 -0
- package/dist/standard-wallet-adapter.js.map +1 -0
- package/dist/types.d.ts +30 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/wallet-bridge-parent.d.ts +41 -0
- package/dist/wallet-bridge-parent.d.ts.map +1 -0
- package/dist/wallet-bridge-parent.js +224 -0
- package/dist/wallet-bridge-parent.js.map +1 -0
- package/dist/wallet-bridge.d.ts +38 -0
- package/dist/wallet-bridge.d.ts.map +1 -0
- package/dist/wallet-bridge.js +71 -0
- package/dist/wallet-bridge.js.map +1 -0
- package/package.json +36 -0
- package/src/BridgeParent.ts +216 -0
- package/src/index.ts +2 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import * as Comlink from 'comlink'
|
|
2
|
+
import type { WalletAdapter } from '@solana/wallet-adapter-base'
|
|
3
|
+
import type { Wallet } from '@wallet-standard/base'
|
|
4
|
+
import { getWallets } from '@wallet-standard/app'
|
|
5
|
+
import { isWalletAdapterCompatibleStandardWallet } from '@solana/wallet-adapter-base'
|
|
6
|
+
import { StandardWalletAdapter } from '@solana/wallet-standard-wallet-adapter-base'
|
|
7
|
+
import { CoinbaseWalletAdapter } from '@solana/wallet-adapter-wallets'
|
|
8
|
+
|
|
9
|
+
export interface EthereumProvider {
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
11
|
+
request: (args: { method: string; params?: unknown[] }) => Promise<any>
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13
|
+
on?: (event: string, handler: (...args: any[]) => void) => void
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15
|
+
removeListener?: (event: string, handler: (...args: any[]) => void) => void
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface WalletStandardInfo {
|
|
19
|
+
uuid: string
|
|
20
|
+
name: string
|
|
21
|
+
chains: string[]
|
|
22
|
+
features: string[]
|
|
23
|
+
adapter: WalletAdapter | undefined
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface EIP6963ProviderInfo {
|
|
27
|
+
uuid: string
|
|
28
|
+
name: string
|
|
29
|
+
icon: string
|
|
30
|
+
rdns: string
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface EIP6963ProviderDetail {
|
|
34
|
+
info: EIP6963ProviderInfo
|
|
35
|
+
provider: EthereumProvider
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface EIP6963AnnounceProviderEvent extends CustomEvent {
|
|
39
|
+
type: 'eip6963:announceProvider'
|
|
40
|
+
detail: EIP6963ProviderDetail
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface EIP6963RequestProviderEvent extends Event {
|
|
44
|
+
type: 'eip6963:requestProvider'
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface DetectedWallet {
|
|
48
|
+
uuid: string
|
|
49
|
+
name: string
|
|
50
|
+
icon: string
|
|
51
|
+
rdns: string
|
|
52
|
+
provider: EthereumProvider
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface ParentAPI {
|
|
56
|
+
eip6963Wallets: DetectedWallet[]
|
|
57
|
+
eip6963WalletsReady: boolean
|
|
58
|
+
walletStandardWallets: WalletStandardInfo[]
|
|
59
|
+
walletStandardWalletsReady: boolean
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export class BridgeParent {
|
|
63
|
+
private iframe: HTMLIFrameElement
|
|
64
|
+
private handshakeComplete = false
|
|
65
|
+
|
|
66
|
+
constructor(iframe: HTMLIFrameElement) {
|
|
67
|
+
if (!iframe) {
|
|
68
|
+
throw new Error('BridgeParent requires an iframe element')
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
this.iframe = iframe
|
|
72
|
+
this.initializeConnection()
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private async initializeConnection(): Promise<void> {
|
|
76
|
+
// Wait for iframe to be ready
|
|
77
|
+
if (!this.iframe.contentWindow) {
|
|
78
|
+
return
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const eip6963Wallets = await this.discoverWallets()
|
|
82
|
+
const walletStandardWallets = this.getSolanaWallets()
|
|
83
|
+
// Expose the parent API directly
|
|
84
|
+
const parentAPI: ParentAPI = {
|
|
85
|
+
eip6963Wallets: eip6963Wallets,
|
|
86
|
+
eip6963WalletsReady: true,
|
|
87
|
+
walletStandardWallets: walletStandardWallets,
|
|
88
|
+
walletStandardWalletsReady: true
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Use Comlink's windowEndpoint with proper cross-origin support
|
|
92
|
+
// For cross-origin, we need to listen on the parent window, not access the iframe's window
|
|
93
|
+
Comlink.expose(
|
|
94
|
+
parentAPI,
|
|
95
|
+
Comlink.windowEndpoint(this.iframe.contentWindow, window, '*')
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
this.handshakeComplete = true
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
isConnected(): boolean {
|
|
102
|
+
return this.handshakeComplete
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
private async discoverWallets(): Promise<DetectedWallet[]> {
|
|
106
|
+
return new Promise(resolve => {
|
|
107
|
+
const detectedWallets: DetectedWallet[] = []
|
|
108
|
+
const timeout = 1000 // Wait up to 1 second for wallets to announce
|
|
109
|
+
|
|
110
|
+
// Set up listener for wallet announcements
|
|
111
|
+
const handleAnnouncement = (event: Event) => {
|
|
112
|
+
const announcementEvent = event as EIP6963AnnounceProviderEvent
|
|
113
|
+
const { info, provider } = announcementEvent.detail
|
|
114
|
+
|
|
115
|
+
// Check if wallet is already detected (by uuid)
|
|
116
|
+
const existingIndex = detectedWallets.findIndex(
|
|
117
|
+
w => w.uuid === info.uuid
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
if (existingIndex === -1) {
|
|
121
|
+
detectedWallets.push({
|
|
122
|
+
uuid: info.uuid,
|
|
123
|
+
name: info.name,
|
|
124
|
+
icon: info.icon,
|
|
125
|
+
rdns: info.rdns,
|
|
126
|
+
provider
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Listen for wallet announcements
|
|
132
|
+
window.addEventListener('eip6963:announceProvider', handleAnnouncement)
|
|
133
|
+
|
|
134
|
+
// Request wallets to announce themselves
|
|
135
|
+
window.dispatchEvent(new Event('eip6963:requestProvider'))
|
|
136
|
+
|
|
137
|
+
// Clean up and resolve after timeout
|
|
138
|
+
setTimeout(() => {
|
|
139
|
+
window.removeEventListener(
|
|
140
|
+
'eip6963:announceProvider',
|
|
141
|
+
handleAnnouncement
|
|
142
|
+
)
|
|
143
|
+
resolve(detectedWallets)
|
|
144
|
+
}, timeout)
|
|
145
|
+
})
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
private getSolanaWallets(): WalletStandardInfo[] {
|
|
149
|
+
const { get } = getWallets()
|
|
150
|
+
const wallets = get()
|
|
151
|
+
|
|
152
|
+
const solanaWallets: WalletStandardInfo[] = []
|
|
153
|
+
const walletNames = new Set<string>()
|
|
154
|
+
|
|
155
|
+
// First, get wallets from Wallet Standard
|
|
156
|
+
for (const wallet of wallets) {
|
|
157
|
+
// Check if this is a Solana wallet
|
|
158
|
+
if (this.isSolanaWallet(wallet)) {
|
|
159
|
+
let adapter: StandardWalletAdapter | undefined
|
|
160
|
+
|
|
161
|
+
if (isWalletAdapterCompatibleStandardWallet(wallet)) {
|
|
162
|
+
adapter = new StandardWalletAdapter({ wallet })
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
solanaWallets.push({
|
|
166
|
+
uuid: this.generateWalletId(wallet),
|
|
167
|
+
name: wallet.name,
|
|
168
|
+
chains: (wallet.chains || []) as string[],
|
|
169
|
+
features: Object.keys(wallet.features),
|
|
170
|
+
adapter: adapter
|
|
171
|
+
})
|
|
172
|
+
walletNames.add(wallet.name)
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Initialize traditional wallet adapters - Only import CBW for now, as it's not using Wallet Standard
|
|
177
|
+
const walletAdapters = [new CoinbaseWalletAdapter()]
|
|
178
|
+
|
|
179
|
+
// Add traditional wallet adapters (but skip duplicates)
|
|
180
|
+
for (const adapter of walletAdapters) {
|
|
181
|
+
if (walletNames.has(adapter.name)) {
|
|
182
|
+
// Skipping duplicate wallet already detected via Wallet Standard
|
|
183
|
+
continue
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const readyState = adapter.readyState
|
|
187
|
+
const isDetected = readyState === 'Installed' || readyState === 'Loadable'
|
|
188
|
+
|
|
189
|
+
// Only add if installed
|
|
190
|
+
if (isDetected) {
|
|
191
|
+
solanaWallets.push({
|
|
192
|
+
uuid: `${adapter.name}-traditional`
|
|
193
|
+
.toLowerCase()
|
|
194
|
+
.replace(/\s+/g, '-'),
|
|
195
|
+
name: adapter.name,
|
|
196
|
+
chains: ['solana:mainnet'],
|
|
197
|
+
features: [],
|
|
198
|
+
adapter: adapter
|
|
199
|
+
})
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return solanaWallets
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
private isSolanaWallet(wallet: Wallet): boolean {
|
|
206
|
+
const chains = wallet.chains || []
|
|
207
|
+
const hasSolanaChain = chains.some(chain => chain.startsWith('solana:'))
|
|
208
|
+
|
|
209
|
+
return hasSolanaChain
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
private generateWalletId(wallet: Wallet): string {
|
|
213
|
+
const chain = wallet.chains?.[0] || 'unknown'
|
|
214
|
+
return `${wallet.name}-${chain}`.toLowerCase().replace(/\s+/g, '-')
|
|
215
|
+
}
|
|
216
|
+
}
|
package/src/index.ts
ADDED