@meshconnect/uwc-injected-connector 0.2.7 → 0.2.9

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 (31) hide show
  1. package/dist/injected-connector.js +2 -2
  2. package/dist/injected-connector.js.map +1 -1
  3. package/dist/services/ethereum-transaction-service.d.ts.map +1 -1
  4. package/dist/services/ethereum-transaction-service.js +11 -20
  5. package/dist/services/ethereum-transaction-service.js.map +1 -1
  6. package/dist/services/signature-service.d.ts +2 -2
  7. package/dist/services/signature-service.d.ts.map +1 -1
  8. package/dist/services/signature-service.js +3 -10
  9. package/dist/services/signature-service.js.map +1 -1
  10. package/dist/services/solana/solana-transaction-service.d.ts +14 -2
  11. package/dist/services/solana/solana-transaction-service.d.ts.map +1 -1
  12. package/dist/services/solana/solana-transaction-service.js +87 -47
  13. package/dist/services/solana/solana-transaction-service.js.map +1 -1
  14. package/dist/services/solana/solana-wallet-service.d.ts +6 -7
  15. package/dist/services/solana/solana-wallet-service.d.ts.map +1 -1
  16. package/dist/services/solana/solana-wallet-service.js +13 -15
  17. package/dist/services/solana/solana-wallet-service.js.map +1 -1
  18. package/dist/services/transaction-service.d.ts +2 -2
  19. package/dist/services/transaction-service.d.ts.map +1 -1
  20. package/dist/services/transaction-service.js.map +1 -1
  21. package/dist/wallet-standard-discovery.d.ts +11 -9
  22. package/dist/wallet-standard-discovery.d.ts.map +1 -1
  23. package/dist/wallet-standard-discovery.js +47 -23
  24. package/dist/wallet-standard-discovery.js.map +1 -1
  25. package/package.json +2 -2
  26. package/src/injected-connector.ts +2 -2
  27. package/src/services/signature-service.ts +5 -17
  28. package/src/services/solana/solana-transaction-service.ts +121 -60
  29. package/src/services/solana/solana-wallet-service.ts +21 -23
  30. package/src/services/transaction-service.ts +3 -3
  31. package/src/wallet-standard-discovery.ts +77 -32
@@ -3,22 +3,24 @@
3
3
  *
4
4
  * Simple implementation to get Solana wallets using the Wallet Standard API
5
5
  */
6
- import type { Wallet } from '@wallet-standard/base';
7
- import type { WalletAdapter } from '@solana/wallet-adapter-base';
6
+ import { StandardWalletAdapter } from '@solana/wallet-standard-wallet-adapter-base';
7
+ import type { Transaction } from '@solana/web3.js';
8
+ export interface ExtendedStandardWalletAdapter extends StandardWalletAdapter {
9
+ customFunctions: ('sendSerializedTransaction' | 'signSerializedTransaction' | 'signAllSerializedTransactions')[];
10
+ sendSerializedTransaction: (transaction: unknown, rpcUrl: string) => Promise<string>;
11
+ signSerializedTransaction: (transaction: unknown) => Promise<Error | Transaction>;
12
+ signAllSerializedTransactions: (transactions: unknown[]) => Promise<Error | Transaction[]>;
13
+ }
14
+ export type SolanaAdapter = ExtendedStandardWalletAdapter | StandardWalletAdapter;
8
15
  export interface WalletStandardInfo {
9
16
  uuid: string;
10
17
  name: string;
11
18
  chains: string[];
12
19
  features: string[];
13
- adapter: WalletAdapter | undefined;
14
- }
15
- export interface SolanaWalletWithAdapter {
16
- info: WalletStandardInfo;
17
- wallet: Wallet;
18
- adapter?: WalletAdapter;
20
+ adapter: SolanaAdapter | undefined;
19
21
  }
20
22
  /**
21
23
  * Gets all available Solana wallets using Wallet Standard
22
24
  */
23
- export declare function getSolanaWallets(): WalletStandardInfo[];
25
+ export declare function getSolanaWallets(): Promise<WalletStandardInfo[]>;
24
26
  //# sourceMappingURL=wallet-standard-discovery.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wallet-standard-discovery.d.ts","sourceRoot":"","sources":["../src/wallet-standard-discovery.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAGnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAIhE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,OAAO,EAAE,aAAa,GAAG,SAAS,CAAA;CACnC;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,kBAAkB,CAAA;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,aAAa,CAAA;CACxB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,kBAAkB,EAAE,CAqDvD"}
1
+ {"version":3,"file":"wallet-standard-discovery.d.ts","sourceRoot":"","sources":["../src/wallet-standard-discovery.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAA;AACnF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAElD,MAAM,WAAW,6BAA8B,SAAQ,qBAAqB;IAC1E,eAAe,EAAE,CACb,2BAA2B,GAC3B,2BAA2B,GAC3B,+BAA+B,CAClC,EAAE,CAAA;IACH,yBAAyB,EAAE,CACzB,WAAW,EAAE,OAAO,EACpB,MAAM,EAAE,MAAM,KACX,OAAO,CAAC,MAAM,CAAC,CAAA;IACpB,yBAAyB,EAAE,CACzB,WAAW,EAAE,OAAO,KACjB,OAAO,CAAC,KAAK,GAAG,WAAW,CAAC,CAAA;IACjC,6BAA6B,EAAE,CAC7B,YAAY,EAAE,OAAO,EAAE,KACpB,OAAO,CAAC,KAAK,GAAG,WAAW,EAAE,CAAC,CAAA;CACpC;AAED,MAAM,MAAM,aAAa,GACrB,6BAA6B,GAC7B,qBAAqB,CAAA;AAEzB,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,OAAO,EAAE,aAAa,GAAG,SAAS,CAAA;CACnC;AA6CD;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAwCtE"}
@@ -6,11 +6,56 @@
6
6
  import { getWallets } from '@wallet-standard/app';
7
7
  import { isWalletAdapterCompatibleStandardWallet } from '@solana/wallet-adapter-base';
8
8
  import { StandardWalletAdapter } from '@solana/wallet-standard-wallet-adapter-base';
9
- import { CoinbaseWalletAdapter } from '@solana/wallet-adapter-wallets';
9
+ /**
10
+ * Polls for bridge wallets when UWCBridgeInitialized is true
11
+ * @returns Promise that resolves to an array of detected wallets from the bridge
12
+ */
13
+ async function pollForBridgeWallets() {
14
+ const pollInterval = 100; // Poll every 100ms
15
+ const maxPollTime = 3000; // Poll for maximum 3 seconds
16
+ const startTime = Date.now();
17
+ return new Promise(resolve => {
18
+ const poll = () => {
19
+ // Check if we've exceeded the max poll time
20
+ if (Date.now() - startTime > maxPollTime) {
21
+ resolve([]);
22
+ return;
23
+ }
24
+ // Check if window.walletStandardWallets is available
25
+ if (
26
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
27
+ // @ts-ignore - window.eip6963Wallets is set by the bridge
28
+ window.walletStandardWallets &&
29
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
30
+ // @ts-ignore - window.eip6963Wallets is set by the bridge
31
+ Array.isArray(window.walletStandardWallets)) {
32
+ const bridgeWallets =
33
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
34
+ // @ts-ignore
35
+ window.walletStandardWallets;
36
+ resolve(bridgeWallets);
37
+ return;
38
+ }
39
+ // Continue polling
40
+ setTimeout(poll, pollInterval);
41
+ };
42
+ // Start polling
43
+ poll();
44
+ });
45
+ }
10
46
  /**
11
47
  * Gets all available Solana wallets using Wallet Standard
12
48
  */
13
- export function getSolanaWallets() {
49
+ export async function getSolanaWallets() {
50
+ // UWCBridgeChildInitialized is only initialized if app runs in an iframe. We can skip checking for bridge proxy providers when it's not necessary.
51
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
52
+ // @ts-ignore - window.UWCBridgeInitialized is set by the bridge
53
+ if (window.UWCBridgeChildInitialized === true) {
54
+ const wallets = await pollForBridgeWallets();
55
+ if (wallets.length > 0) {
56
+ return wallets;
57
+ }
58
+ }
14
59
  const { get } = getWallets();
15
60
  const wallets = get();
16
61
  const solanaWallets = [];
@@ -33,27 +78,6 @@ export function getSolanaWallets() {
33
78
  walletNames.add(wallet.name);
34
79
  }
35
80
  }
36
- // Initialize traditional wallet adapters - Only import CBW for now, as it's not using Wallet Standard
37
- const walletAdapters = [new CoinbaseWalletAdapter()];
38
- // Add traditional wallet adapters (but skip duplicates)
39
- for (const adapter of walletAdapters) {
40
- if (walletNames.has(adapter.name)) {
41
- // Skipping duplicate wallet already detected via Wallet Standard
42
- continue;
43
- }
44
- const readyState = adapter.readyState;
45
- const isDetected = readyState === 'Installed' || readyState === 'Loadable';
46
- // Only add if installed
47
- if (isDetected) {
48
- solanaWallets.push({
49
- uuid: `${adapter.name}-traditional`.toLowerCase().replace(/\s+/g, '-'),
50
- name: adapter.name,
51
- chains: ['solana:mainnet'],
52
- features: [],
53
- adapter: adapter
54
- });
55
- }
56
- }
57
81
  return solanaWallets;
58
82
  }
59
83
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"wallet-standard-discovery.js","sourceRoot":"","sources":["../src/wallet-standard-discovery.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wallet-standard-discovery.js","sourceRoot":"","sources":["../src/wallet-standard-discovery.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meshconnect/uwc-injected-connector",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "Injected connector for Universal Wallet Connector",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -26,7 +26,7 @@
26
26
  "bs58": "^6.0.0",
27
27
  "buffer": "^6.0.3",
28
28
  "ethers": "^6.15.0",
29
- "@meshconnect/uwc-types": "0.2.5"
29
+ "@meshconnect/uwc-types": "0.2.6"
30
30
  },
31
31
  "devDependencies": {
32
32
  "typescript": "^5.9.2"
@@ -55,7 +55,7 @@ export class InjectedConnector implements Connector {
55
55
  */
56
56
  private async initializeWalletDiscovery(): Promise<void> {
57
57
  await this.ethereumService.initializeDiscovery()
58
- this.solanaService.initializeDiscovery()
58
+ await this.solanaService.initializeDiscovery()
59
59
  }
60
60
 
61
61
  /**
@@ -84,7 +84,7 @@ export class InjectedConnector implements Connector {
84
84
 
85
85
  case 'solana': {
86
86
  // Re-fetch Solana wallets
87
- this.solanaService.initializeDiscovery()
87
+ await this.solanaService.initializeDiscovery()
88
88
 
89
89
  // Convert to DetectedWalletInfo format
90
90
  return this.solanaService.getDetectedWallets().map(wallet => ({
@@ -1,7 +1,7 @@
1
1
  import type { EthereumProvider } from '../eip6963-discovery'
2
- import type { WalletAdapter } from '@solana/wallet-adapter-base'
3
2
  import bs58 from 'bs58'
4
3
  import { parseError } from '../utils/error-utils'
4
+ import type { SolanaAdapter } from '../wallet-standard-discovery'
5
5
 
6
6
  /**
7
7
  * Service for handling message signing operations for injected wallets
@@ -45,32 +45,20 @@ export class SignatureService {
45
45
  */
46
46
  async signSolanaMessage(
47
47
  message: string,
48
- adapter: WalletAdapter
48
+ adapter: SolanaAdapter
49
49
  ): Promise<string> {
50
- if (!adapter) {
51
- throw new Error('Adapter is required for Solana message signing')
52
- }
53
-
54
50
  if (!message) {
55
51
  throw new Error('Message is required for signing')
56
52
  }
57
53
 
58
- // Check if adapter supports signMessage
59
- const signingAdapter = adapter as WalletAdapter & {
60
- signMessage?: (message: Uint8Array) => Promise<Uint8Array>
61
- }
62
-
63
- if (!signingAdapter.signMessage) {
64
- throw new Error('Solana adapter does not support message signing')
65
- }
66
-
67
54
  try {
68
55
  // Convert message to Uint8Array for Solana
69
56
  const encoder = new TextEncoder()
70
57
  const messageBytes = encoder.encode(message)
71
58
 
72
- // Sign the message
73
- const signedMessage = await signingAdapter.signMessage(messageBytes)
59
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
60
+ // @ts-ignore
61
+ const signedMessage = await adapter.signMessage(messageBytes)
74
62
 
75
63
  // Encode signature using base58 for Solana (standard encoding for Solana)
76
64
  // The signature is returned as a Uint8Array, encode it to base58 string
@@ -1,5 +1,4 @@
1
- import { Transaction, Connection } from '@solana/web3.js'
2
- import type { WalletAdapter } from '@solana/wallet-adapter-base'
1
+ import { Transaction, Connection, PublicKey } from '@solana/web3.js'
3
2
  import type {
4
3
  SolanaNativeTransferRequest,
5
4
  NetworkRpcMap,
@@ -10,6 +9,10 @@ import type {
10
9
  } from '@meshconnect/uwc-types'
11
10
  import { parseError } from '../../utils/error-utils'
12
11
  import { SolanaTransactionBuilder } from './solana-transaction-builder'
12
+ import type {
13
+ ExtendedStandardWalletAdapter,
14
+ SolanaAdapter
15
+ } from '../../wallet-standard-discovery'
13
16
 
14
17
  /**
15
18
  * Service for handling Solana transaction operations
@@ -28,7 +31,7 @@ export class SolanaTransactionService {
28
31
  */
29
32
  async sendTransaction(
30
33
  request: SolanaTransactionRequest,
31
- adapter: WalletAdapter
34
+ adapter: SolanaAdapter
32
35
  ): Promise<string> {
33
36
  try {
34
37
  // Handle different types of Solana transactions
@@ -55,23 +58,82 @@ export class SolanaTransactionService {
55
58
  }
56
59
  }
57
60
 
61
+ /**
62
+ * Helper: Validate wallet address matches
63
+ */
64
+ private async validateWalletMatch(
65
+ adapter: SolanaAdapter,
66
+ expectedAddress: string
67
+ ): Promise<string> {
68
+ const base58PublicKey = await adapter.publicKey?.toBase58()
69
+ if (base58PublicKey !== expectedAddress) {
70
+ throw new Error('From address does not match connected wallet')
71
+ }
72
+ return base58PublicKey
73
+ }
74
+
75
+ /**
76
+ * Helper: Get RPC URL with fallback
77
+ */
78
+ private getRpcUrl(networkId?: NetworkId): string {
79
+ return networkId && this.networkRpcMap[networkId]
80
+ ? this.networkRpcMap[networkId]
81
+ : 'https://api.mainnet-beta.solana.com'
82
+ }
83
+
84
+ /**
85
+ * Helper: Execute transaction with sendSerializedTransaction fallback
86
+ */
87
+ private async executeTransaction(
88
+ adapter: SolanaAdapter,
89
+ transaction: Transaction,
90
+ rpcUrl: string
91
+ ): Promise<string> {
92
+ let transactionSignature: string | undefined
93
+
94
+ // Try to use sendSerializedTransaction if available
95
+ try {
96
+ const extendedAdapter = adapter as ExtendedStandardWalletAdapter
97
+ const serializedTx = transaction.serialize({
98
+ requireAllSignatures: false,
99
+ verifySignatures: false
100
+ })
101
+ if (extendedAdapter.sendSerializedTransaction) {
102
+ transactionSignature = await extendedAdapter.sendSerializedTransaction(
103
+ serializedTx,
104
+ rpcUrl
105
+ )
106
+ }
107
+ } catch {
108
+ // Fallback to regular sendTransaction
109
+ }
110
+
111
+ // If sendSerializedTransaction didn't work or wasn't available
112
+ if (!transactionSignature) {
113
+ const connection = new Connection(rpcUrl)
114
+ transactionSignature = await adapter.sendTransaction(
115
+ transaction,
116
+ connection
117
+ )
118
+ }
119
+
120
+ if (transactionSignature === undefined) {
121
+ throw new Error(`Couldn't get the transaction signature`)
122
+ }
123
+ return transactionSignature
124
+ }
125
+
58
126
  /**
59
127
  * Send native SOL transfer
60
128
  */
61
129
  private async sendNativeTransaction(
62
- adapter: WalletAdapter,
130
+ adapter: SolanaAdapter,
63
131
  request: SolanaNativeTransferRequest,
64
132
  networkId?: NetworkId
65
133
  ): Promise<string> {
66
134
  try {
67
- if (!adapter.publicKey) {
68
- throw new Error('Wallet not connected')
69
- }
70
-
71
- // Verify the from address matches connected wallet
72
- if (adapter.publicKey.toBase58() !== request.from) {
73
- throw new Error('From address does not match connected wallet')
74
- }
135
+ // Validate wallet
136
+ await this.validateWalletMatch(adapter, request.from)
75
137
 
76
138
  // Blockhash is required
77
139
  if (!request.blockhash) {
@@ -84,17 +146,11 @@ export class SolanaTransactionService {
84
146
  await this.builder.buildTransferInstructions(request)
85
147
 
86
148
  transaction.recentBlockhash = request.blockhash
87
- transaction.feePayer = adapter.publicKey
149
+ transaction.feePayer = new PublicKey(request.from)
88
150
 
89
- // Get RPC URL from the network RPC map or fall back to public endpoint
90
- const rpcUrl =
91
- networkId && this.networkRpcMap[networkId]
92
- ? this.networkRpcMap[networkId]
93
- : 'https://api.mainnet-beta.solana.com'
94
- const connection = new Connection(rpcUrl)
95
-
96
- const signature = await adapter.sendTransaction(transaction, connection)
97
- return signature
151
+ // Execute with helpers
152
+ const rpcUrl = this.getRpcUrl(networkId)
153
+ return await this.executeTransaction(adapter, transaction, rpcUrl)
98
154
  } catch (error) {
99
155
  parseError(error)
100
156
  }
@@ -104,19 +160,13 @@ export class SolanaTransactionService {
104
160
  * Send SPL token transfer
105
161
  */
106
162
  private async sendSplTokenTransaction(
107
- adapter: WalletAdapter,
163
+ adapter: SolanaAdapter,
108
164
  request: SolanaTokenTransferRequest,
109
165
  networkId?: NetworkId
110
166
  ): Promise<string> {
111
167
  try {
112
- if (!adapter.publicKey) {
113
- throw new Error('Wallet not connected')
114
- }
115
-
116
- // Verify the from address matches connected wallet
117
- if (adapter.publicKey.toBase58() !== request.from) {
118
- throw new Error('From address does not match connected wallet')
119
- }
168
+ // Validate wallet
169
+ await this.validateWalletMatch(adapter, request.from)
120
170
 
121
171
  // Blockhash is required
122
172
  if (!request.blockhash) {
@@ -129,17 +179,11 @@ export class SolanaTransactionService {
129
179
  await this.builder.buildTransferInstructions(request)
130
180
 
131
181
  transaction.recentBlockhash = request.blockhash
132
- transaction.feePayer = adapter.publicKey
182
+ transaction.feePayer = new PublicKey(request.from)
133
183
 
134
- // Get RPC URL from the network RPC map or fall back to public endpoint
135
- const rpcUrl =
136
- networkId && this.networkRpcMap[networkId]
137
- ? this.networkRpcMap[networkId]
138
- : 'https://api.mainnet-beta.solana.com'
139
- const connection = new Connection(rpcUrl)
140
-
141
- const signature = await adapter.sendTransaction(transaction, connection)
142
- return signature
184
+ // Execute with helpers
185
+ const rpcUrl = this.getRpcUrl(networkId)
186
+ return await this.executeTransaction(adapter, transaction, rpcUrl)
143
187
  } catch (error) {
144
188
  parseError(error)
145
189
  }
@@ -149,40 +193,57 @@ export class SolanaTransactionService {
149
193
  * Send native SOL transfer
150
194
  */
151
195
  private async sendGenericTransferWithInstructions(
152
- adapter: WalletAdapter,
196
+ adapter: SolanaAdapter,
153
197
  request: SolanaGenericTransferRequest,
154
198
  networkId?: NetworkId
155
199
  ): Promise<string> {
156
200
  try {
157
- if (!adapter.publicKey) {
158
- throw new Error('Wallet not connected')
159
- }
160
-
161
- // Verify the from address matches connected wallet
162
- if (adapter.publicKey.toBase58() !== request.feePayer) {
163
- throw new Error('From address does not match connected wallet')
164
- }
201
+ // Validate wallet
202
+ await this.validateWalletMatch(adapter, request.feePayer)
165
203
 
166
204
  // Blockhash is required
167
205
  if (!request.blockhash) {
168
206
  throw new Error('Blockhash is required for Solana transactions')
169
207
  }
170
208
 
171
- // Create transaction
209
+ // Create versioned transaction
172
210
  const transaction = await this.builder.getVersionedTransaction(
173
- adapter.publicKey,
211
+ new PublicKey(request.feePayer),
174
212
  request
175
213
  )
176
214
 
177
- // Get RPC URL from the network RPC map or fall back to public endpoint
178
- const rpcUrl =
179
- networkId && this.networkRpcMap[networkId]
180
- ? this.networkRpcMap[networkId]
181
- : 'https://api.mainnet-beta.solana.com'
182
- const connection = new Connection(rpcUrl)
215
+ // Get RPC URL
216
+ const rpcUrl = this.getRpcUrl(networkId)
217
+
218
+ // VersionedTransaction can't use our helper method, handle directly
219
+ let transactionSignature: string | undefined
220
+
221
+ try {
222
+ const extendedAdapter = adapter as ExtendedStandardWalletAdapter
223
+ const serializedTx = transaction.serialize()
224
+ if (extendedAdapter.sendSerializedTransaction) {
225
+ transactionSignature =
226
+ await extendedAdapter.sendSerializedTransaction(
227
+ serializedTx,
228
+ rpcUrl
229
+ )
230
+ }
231
+ } catch {
232
+ // Fallback to regular sendTransaction
233
+ }
183
234
 
184
- const signature = await adapter.sendTransaction(transaction, connection)
185
- return signature
235
+ if (!transactionSignature) {
236
+ const connection = new Connection(rpcUrl)
237
+ transactionSignature = await adapter.sendTransaction(
238
+ transaction,
239
+ connection
240
+ )
241
+ }
242
+
243
+ if (transactionSignature === undefined) {
244
+ throw new Error(`Couldn't get the transaction signature`)
245
+ }
246
+ return transactionSignature
186
247
  } catch (error) {
187
248
  parseError(error)
188
249
  }
@@ -1,7 +1,7 @@
1
1
  import type { NetworkId, AvailableAddress } from '@meshconnect/uwc-types'
2
- import type { WalletAdapter } from '@solana/wallet-adapter-base'
3
2
  import {
4
3
  getSolanaWallets,
4
+ type SolanaAdapter,
5
5
  type WalletStandardInfo
6
6
  } from '../../wallet-standard-discovery'
7
7
  import { StorageService } from '../storage-service'
@@ -11,7 +11,7 @@ import { StorageService } from '../storage-service'
11
11
  */
12
12
  export class SolanaWalletService {
13
13
  private detectedWallets: WalletStandardInfo[] = []
14
- private connectedAdapter: WalletAdapter | null = null
14
+ private connectedAdapter: SolanaAdapter | null = null
15
15
  private account: string | null = null
16
16
  private storageService: StorageService
17
17
 
@@ -22,8 +22,8 @@ export class SolanaWalletService {
22
22
  /**
23
23
  * Initialize wallet discovery
24
24
  */
25
- initializeDiscovery(): void {
26
- this.detectedWallets = getSolanaWallets()
25
+ async initializeDiscovery(): Promise<void> {
26
+ this.detectedWallets = await getSolanaWallets()
27
27
  }
28
28
 
29
29
  /**
@@ -44,30 +44,27 @@ export class SolanaWalletService {
44
44
  * Check if a Solana wallet is already connected
45
45
  */
46
46
  async checkExistingConnection(
47
- adapter: WalletAdapter,
47
+ adapter: SolanaAdapter,
48
48
  walletUuid: string
49
49
  ): Promise<string | null> {
50
50
  try {
51
+ const base58PublicKey = await adapter.publicKey?.toBase58()
51
52
  // Check if adapter has a publicKey (means it's connected)
52
- if (adapter.publicKey) {
53
- return adapter.publicKey.toBase58()
53
+ if (base58PublicKey) {
54
+ return base58PublicKey
54
55
  }
55
56
 
56
57
  // If this wallet was previously connected, try to reconnect
57
58
  // This should work without prompting for wallets that support it
58
59
  if (this.storageService.wasSolanaWalletPreviouslyConnected(walletUuid)) {
59
- if (
60
- 'connecting' in adapter &&
61
- !adapter.connecting &&
62
- 'connect' in adapter
63
- ) {
60
+ const walletIsConnecting = await adapter.connecting
61
+ if (!walletIsConnecting) {
64
62
  try {
65
- // Type assertion needed because TypeScript can't narrow the type properly
66
63
  await adapter.connect()
67
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
68
- const publicKey = (adapter as any).publicKey
69
- if (publicKey && 'toBase58' in publicKey) {
70
- return publicKey.toBase58()
64
+
65
+ const base58PublicKey = await adapter.publicKey?.toBase58()
66
+ if (base58PublicKey) {
67
+ return base58PublicKey
71
68
  }
72
69
  } catch {
73
70
  // Silent fail - wallet requires user interaction or doesn't support silent reconnect
@@ -83,15 +80,16 @@ export class SolanaWalletService {
83
80
  /**
84
81
  * Connect to wallet
85
82
  */
86
- async connect(adapter: WalletAdapter, walletUuid: string): Promise<string> {
83
+ async connect(adapter: SolanaAdapter, walletUuid: string): Promise<string> {
87
84
  // Connect to the Solana wallet
88
85
  await adapter.connect()
89
86
 
90
- if (!adapter.publicKey) {
91
- throw new Error('No public key returned from wallet')
87
+ const address = await adapter.publicKey?.toBase58()
88
+
89
+ if (!address) {
90
+ throw new Error('No address returned from wallet')
92
91
  }
93
92
 
94
- const address = adapter.publicKey.toBase58()
95
93
  this.connectedAdapter = adapter
96
94
  this.account = address
97
95
 
@@ -124,7 +122,7 @@ export class SolanaWalletService {
124
122
  * Set connection state
125
123
  */
126
124
  setConnectionState(
127
- adapter: WalletAdapter | null,
125
+ adapter: SolanaAdapter | null,
128
126
  account: string | null,
129
127
  walletUuid?: string
130
128
  ): void {
@@ -147,7 +145,7 @@ export class SolanaWalletService {
147
145
  /**
148
146
  * Get connected adapter
149
147
  */
150
- getConnectedAdapter(): WalletAdapter | null {
148
+ getConnectedAdapter(): SolanaAdapter | null {
151
149
  return this.connectedAdapter
152
150
  }
153
151
 
@@ -1,5 +1,4 @@
1
1
  import type { EthereumProvider } from '../eip6963-discovery'
2
- import type { WalletAdapter } from '@solana/wallet-adapter-base'
3
2
  import type {
4
3
  TransactionRequest,
5
4
  TransactionResult,
@@ -10,6 +9,7 @@ import type {
10
9
  import { EthereumTransactionService } from './ethereum/ethereum-transaction-service'
11
10
  import { SolanaTransactionService } from './solana/solana-transaction-service'
12
11
  import { parseError } from '../utils/error-utils'
12
+ import type { SolanaAdapter } from '../wallet-standard-discovery'
13
13
 
14
14
  /**
15
15
  * Service for handling transaction operations across different wallet types
@@ -29,7 +29,7 @@ export class TransactionService {
29
29
  async sendTransaction(
30
30
  request: TransactionRequest,
31
31
  namespace: 'eip155' | 'solana',
32
- provider: EthereumProvider | WalletAdapter
32
+ provider: EthereumProvider | SolanaAdapter
33
33
  ): Promise<TransactionResult> {
34
34
  if (namespace === 'eip155') {
35
35
  return await this.ethereumService.sendTransaction(
@@ -39,7 +39,7 @@ export class TransactionService {
39
39
  } else if (namespace === 'solana') {
40
40
  return await this.solanaService.sendTransaction(
41
41
  request as SolanaTransactionRequest,
42
- provider as WalletAdapter
42
+ provider as SolanaAdapter
43
43
  )
44
44
  } else {
45
45
  throw parseError(new Error(`Unsupported namespace: ${namespace}`))