@meshconnect/uwc-wallet-connect-connector 0.2.0

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 (56) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +2 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/services/connection-service.d.ts +60 -0
  6. package/dist/services/connection-service.d.ts.map +1 -0
  7. package/dist/services/connection-service.js +235 -0
  8. package/dist/services/connection-service.js.map +1 -0
  9. package/dist/services/network-switch-service.d.ts +16 -0
  10. package/dist/services/network-switch-service.d.ts.map +1 -0
  11. package/dist/services/network-switch-service.js +71 -0
  12. package/dist/services/network-switch-service.js.map +1 -0
  13. package/dist/services/signature-service.d.ts +15 -0
  14. package/dist/services/signature-service.d.ts.map +1 -0
  15. package/dist/services/signature-service.js +102 -0
  16. package/dist/services/signature-service.js.map +1 -0
  17. package/dist/services/transaction-service.d.ts +33 -0
  18. package/dist/services/transaction-service.d.ts.map +1 -0
  19. package/dist/services/transaction-service.js +287 -0
  20. package/dist/services/transaction-service.js.map +1 -0
  21. package/dist/services/walletconnect-client.d.ts +28 -0
  22. package/dist/services/walletconnect-client.d.ts.map +1 -0
  23. package/dist/services/walletconnect-client.js +92 -0
  24. package/dist/services/walletconnect-client.js.map +1 -0
  25. package/dist/utils/account-utils.d.ts +41 -0
  26. package/dist/utils/account-utils.d.ts.map +1 -0
  27. package/dist/utils/account-utils.js +81 -0
  28. package/dist/utils/account-utils.js.map +1 -0
  29. package/dist/utils/encoding-utils.d.ts +6 -0
  30. package/dist/utils/encoding-utils.d.ts.map +1 -0
  31. package/dist/utils/encoding-utils.js +27 -0
  32. package/dist/utils/encoding-utils.js.map +1 -0
  33. package/dist/utils/error-utils.d.ts +6 -0
  34. package/dist/utils/error-utils.d.ts.map +1 -0
  35. package/dist/utils/error-utils.js +55 -0
  36. package/dist/utils/error-utils.js.map +1 -0
  37. package/dist/utils/solana-transactions.d.ts +4 -0
  38. package/dist/utils/solana-transactions.d.ts.map +1 -0
  39. package/dist/utils/solana-transactions.js +15 -0
  40. package/dist/utils/solana-transactions.js.map +1 -0
  41. package/dist/wallet-connect-connector.d.ts +17 -0
  42. package/dist/wallet-connect-connector.d.ts.map +1 -0
  43. package/dist/wallet-connect-connector.js +47 -0
  44. package/dist/wallet-connect-connector.js.map +1 -0
  45. package/package.json +41 -0
  46. package/src/index.ts +1 -0
  47. package/src/services/connection-service.ts +304 -0
  48. package/src/services/network-switch-service.ts +83 -0
  49. package/src/services/signature-service.ts +128 -0
  50. package/src/services/transaction-service.ts +397 -0
  51. package/src/services/walletconnect-client.ts +103 -0
  52. package/src/utils/account-utils.ts +116 -0
  53. package/src/utils/encoding-utils.ts +32 -0
  54. package/src/utils/error-utils.ts +62 -0
  55. package/src/utils/solana-transactions.ts +24 -0
  56. package/src/wallet-connect-connector.ts +83 -0
@@ -0,0 +1,116 @@
1
+ import type { NetworkId, Namespace } from '@meshconnect/uwc-types'
2
+
3
+ /**
4
+ * Parse a WalletConnect account string into its components
5
+ * Account format: "namespace:chainId:address"
6
+ * Example: "eip155:1:0x1234..." or "solana:mainnet:ABC123..."
7
+ */
8
+ export function parseAccount(account: string): {
9
+ namespace: Namespace
10
+ chainId: string
11
+ networkId: NetworkId
12
+ address: string
13
+ } {
14
+ const parts = account.split(':')
15
+ if (parts.length < 3) {
16
+ throw new Error(`Invalid account format: ${account}`)
17
+ }
18
+
19
+ const namespace = parts[0] as Namespace
20
+ const chainId = parts[1]!
21
+ const networkId = `${namespace}:${chainId}` as NetworkId
22
+ // Handle addresses that might contain colons (like some Solana addresses)
23
+ const address = parts.slice(2).join(':')
24
+
25
+ return {
26
+ namespace,
27
+ chainId,
28
+ networkId,
29
+ address
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Build a WalletConnect account string from components
35
+ */
36
+ export function buildAccount(
37
+ namespace: Namespace,
38
+ chainId: string,
39
+ address: string
40
+ ): string {
41
+ return `${namespace}:${chainId}:${address}`
42
+ }
43
+
44
+ /**
45
+ * Extract namespace from a network ID
46
+ * Example: "eip155:1" -> "eip155"
47
+ */
48
+ export function getNamespaceFromNetworkId(networkId: NetworkId): Namespace {
49
+ const [namespace] = networkId.split(':')
50
+ return namespace as Namespace
51
+ }
52
+
53
+ /**
54
+ * Extract chain ID from a network ID
55
+ * Example: "eip155:1" -> "1"
56
+ */
57
+ export function getChainIdFromNetworkId(networkId: NetworkId): string {
58
+ const [, chainId] = networkId.split(':')
59
+ return chainId || ''
60
+ }
61
+
62
+ /**
63
+ * Find an account in session namespaces that matches the given network and address
64
+ */
65
+ export function findAccountInNamespaces(
66
+ namespaces: Record<string, any>,
67
+ targetNetworkId: NetworkId,
68
+ targetAddress: string
69
+ ): string | null {
70
+ for (const [, namespaceData] of Object.entries(namespaces)) {
71
+ for (const account of namespaceData.accounts || []) {
72
+ const { networkId, address } = parseAccount(account)
73
+ if (networkId === targetNetworkId && address === targetAddress) {
74
+ return account
75
+ }
76
+ }
77
+ }
78
+ return null
79
+ }
80
+
81
+ /**
82
+ * Extract all accounts from session namespaces
83
+ */
84
+ export function extractAccountsFromNamespaces(
85
+ namespaces: Record<string, any>
86
+ ): Array<{
87
+ account: string
88
+ namespace: Namespace
89
+ chainId: string
90
+ networkId: NetworkId
91
+ address: string
92
+ }> {
93
+ const accounts: Array<{
94
+ account: string
95
+ namespace: Namespace
96
+ chainId: string
97
+ networkId: NetworkId
98
+ address: string
99
+ }> = []
100
+
101
+ Object.entries(namespaces).forEach(([, namespaceData]) => {
102
+ ;(namespaceData.accounts || []).forEach((account: string) => {
103
+ try {
104
+ const parsed = parseAccount(account)
105
+ accounts.push({
106
+ account,
107
+ ...parsed
108
+ })
109
+ } catch {
110
+ // Skip invalid accounts
111
+ }
112
+ })
113
+ })
114
+
115
+ return accounts
116
+ }
@@ -0,0 +1,32 @@
1
+ import bs58 from 'bs58'
2
+
3
+ /**
4
+ * Encode a string message to base58 format (used for Solana message signing)
5
+ */
6
+ export const base58Encode = (message: string) => {
7
+ // Use TextEncoder for browser compatibility
8
+ const encoder = new TextEncoder()
9
+ const messageBytes = encoder.encode(message)
10
+ return bs58.encode(messageBytes)
11
+ }
12
+
13
+ export const standardizeSignature = (
14
+ rawSignature: string | Uint8Array
15
+ ): string => {
16
+ // First ensure we have a string
17
+ let signature =
18
+ typeof rawSignature === 'string' ? rawSignature : bs58.encode(rawSignature)
19
+
20
+ // If signature is longer than standard 88 chars, decode and re-encode
21
+ if (signature.length > 88) {
22
+ try {
23
+ const bytes = bs58.decode(signature)
24
+ const truncatedBytes = bytes.slice(0, 64)
25
+ signature = bs58.encode(truncatedBytes)
26
+ } catch {
27
+ throw new Error('Failed to normalize signature')
28
+ }
29
+ }
30
+
31
+ return signature
32
+ }
@@ -0,0 +1,62 @@
1
+ import type { WalletError } from '@meshconnect/uwc-types'
2
+ import { WalletConnectorError } from '@meshconnect/uwc-types'
3
+
4
+ /**
5
+ * Parse an error and throw a WalletConnectorError
6
+ * Detects if the error is a user rejection or an unknown error
7
+ */
8
+ export function parseError(error: unknown): never {
9
+ let message: string
10
+ let isRejected = false
11
+
12
+ // Handle different error formats
13
+ if (error && typeof error === 'object') {
14
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
+ const errorObj = error as any
16
+
17
+ // Check for EIP-1193 error code
18
+ if (errorObj.code === 4001 || errorObj.code === 'ACTION_REJECTED') {
19
+ isRejected = true
20
+ }
21
+
22
+ // Extract message
23
+ if (errorObj.message) {
24
+ message = errorObj.message
25
+ } else if (errorObj.error?.message) {
26
+ message = errorObj.error.message
27
+ } else {
28
+ message = String(error)
29
+ }
30
+ } else {
31
+ message = String(error)
32
+ }
33
+
34
+ // If not already marked as rejected, check message patterns
35
+ if (!isRejected) {
36
+ const rejectionPatterns = [
37
+ 'user rejected',
38
+ 'user denied',
39
+ 'user cancelled',
40
+ 'user canceled',
41
+ 'rejected by user',
42
+ 'denied by user',
43
+ 'cancelled by user',
44
+ 'canceled by user',
45
+ 'user disapproved',
46
+ 'user declined',
47
+ 'action_rejected'
48
+ ]
49
+
50
+ const lowerMessage = message.toLowerCase()
51
+ isRejected = rejectionPatterns.some(pattern =>
52
+ lowerMessage.includes(pattern.toLowerCase())
53
+ )
54
+ }
55
+
56
+ const walletError: WalletError = {
57
+ type: isRejected ? 'rejected' : 'unknown',
58
+ message
59
+ }
60
+
61
+ throw new WalletConnectorError(walletError)
62
+ }
@@ -0,0 +1,24 @@
1
+ import type { SolanaNativeTransferRequest } from '@meshconnect/uwc-types'
2
+ import {
3
+ PublicKey,
4
+ SystemProgram,
5
+ Transaction,
6
+ VersionedTransaction
7
+ } from '@solana/web3.js'
8
+
9
+ export function getSolanaTransaction(params: SolanaNativeTransferRequest) {
10
+ if (!params.blockhash) {
11
+ throw new Error('Blockhash is required for Solana transactions')
12
+ }
13
+
14
+ const transaction: Transaction | VersionedTransaction = new Transaction().add(
15
+ SystemProgram.transfer({
16
+ fromPubkey: new PublicKey(params.from),
17
+ toPubkey: new PublicKey(params.to),
18
+ lamports: Number(params.amount)
19
+ })
20
+ )
21
+ transaction.recentBlockhash = params.blockhash
22
+ transaction.feePayer = new PublicKey(params.from)
23
+ return transaction
24
+ }
@@ -0,0 +1,83 @@
1
+ import type {
2
+ Network,
3
+ Connector,
4
+ ConnectorResult,
5
+ SwitchNetworkResult,
6
+ WalletConnectConfig,
7
+ WalletConnectProvider,
8
+ TransactionRequest,
9
+ TransactionResult,
10
+ NetworkRpcMap
11
+ } from '@meshconnect/uwc-types'
12
+ import { WalletConnectClient } from './services/walletconnect-client'
13
+ import { ConnectionService } from './services/connection-service'
14
+ import { NetworkSwitchService } from './services/network-switch-service'
15
+ import { SignatureService } from './services/signature-service'
16
+ import { TransactionService } from './services/transaction-service'
17
+
18
+ export class WalletConnectConnector implements Connector {
19
+ private walletConnectClient: WalletConnectClient
20
+ private connectionService: ConnectionService
21
+ private networkSwitchService: NetworkSwitchService
22
+ private signatureService: SignatureService
23
+ private transactionService: TransactionService
24
+ private networkRpcMap: NetworkRpcMap
25
+
26
+ constructor(config: WalletConnectConfig, networkRpcMap: NetworkRpcMap = {}) {
27
+ this.walletConnectClient = new WalletConnectClient(config)
28
+ this.networkRpcMap = networkRpcMap
29
+ this.connectionService = new ConnectionService(this.walletConnectClient)
30
+ this.networkSwitchService = new NetworkSwitchService(
31
+ this.walletConnectClient,
32
+ this.connectionService
33
+ )
34
+ this.signatureService = new SignatureService(
35
+ this.walletConnectClient,
36
+ this.connectionService
37
+ )
38
+ this.transactionService = new TransactionService(
39
+ this.walletConnectClient,
40
+ this.connectionService,
41
+ this.networkRpcMap
42
+ )
43
+ }
44
+
45
+ async connect(
46
+ network: Network,
47
+ provider?: WalletConnectProvider
48
+ ): Promise<ConnectorResult> {
49
+ if (!provider) {
50
+ throw new Error(
51
+ 'WalletConnectProvider is required for WalletConnect connection'
52
+ )
53
+ }
54
+
55
+ return this.connectionService.connect(network, provider)
56
+ }
57
+
58
+ getConnectionURI(): string {
59
+ const uri = this.connectionService.getConnectionURI()
60
+ if (!uri) {
61
+ throw new Error('No connection URI available. Call connect() first.')
62
+ }
63
+ return uri
64
+ }
65
+
66
+ async disconnect(): Promise<void> {
67
+ return this.connectionService.disconnect()
68
+ }
69
+
70
+ async switchNetwork(network: Network): Promise<SwitchNetworkResult> {
71
+ return this.networkSwitchService.switchNetwork(network)
72
+ }
73
+
74
+ async signMessage(message: string): Promise<string> {
75
+ return this.signatureService.signMessage(message)
76
+ }
77
+
78
+ async sendTransaction(
79
+ request: TransactionRequest
80
+ ): Promise<TransactionResult> {
81
+ return this.transactionService.sendTransaction(request)
82
+ }
83
+ }