@meshconnect/uwc-wallet-connect-connector 0.2.14 → 0.3.1

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.
@@ -1,4 +1,4 @@
1
- import type { EVMNativeTransferRequest, EVMContractCallRequest } from '@meshconnect/uwc-types';
1
+ import type { EVMNativeTransferRequest, EVMContractCallRequest, EVMDataTransferRequest } from '@meshconnect/uwc-types';
2
2
  import type { TransactionRequest } from 'ethers';
3
3
  /**
4
4
  * Service for handling Ethereum/EVM transaction operations
@@ -6,6 +6,7 @@ import type { TransactionRequest } from 'ethers';
6
6
  export declare class EthereumTransactionBuilder {
7
7
  getContractTransaction(request: EVMContractCallRequest): Promise<TransactionRequest>;
8
8
  getNativeTransaction(request: EVMNativeTransferRequest): Promise<TransactionRequest>;
9
+ getDataTransaction(request: EVMDataTransferRequest): Promise<TransactionRequest>;
9
10
  /**
10
11
  * Helper to format gas configuration for ethers
11
12
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ethereum-transaction-builder.d.ts","sourceRoot":"","sources":["../../../src/services/ethereum/ethereum-transaction-builder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,wBAAwB,EACxB,sBAAsB,EACvB,MAAM,wBAAwB,CAAA;AAE/B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAA;AAEhD;;GAEG;AACH,qBAAa,0BAA0B;IAC/B,sBAAsB,CAC1B,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,kBAAkB,CAAC;IAiCxB,oBAAoB,CACxB,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC;IAa9B;;OAEG;IACH,OAAO,CAAC,eAAe;CAiBxB"}
1
+ {"version":3,"file":"ethereum-transaction-builder.d.ts","sourceRoot":"","sources":["../../../src/services/ethereum/ethereum-transaction-builder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,wBAAwB,EACxB,sBAAsB,EACtB,sBAAsB,EACvB,MAAM,wBAAwB,CAAA;AAE/B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAA;AAEhD;;GAEG;AACH,qBAAa,0BAA0B;IAC/B,sBAAsB,CAC1B,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,kBAAkB,CAAC;IAiCxB,oBAAoB,CACxB,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC;IAaxB,kBAAkB,CACtB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,kBAAkB,CAAC;IAgB9B;;OAEG;IACH,OAAO,CAAC,eAAe;CAiBxB"}
@@ -42,6 +42,21 @@ export class EthereumTransactionBuilder {
42
42
  parseError(error);
43
43
  }
44
44
  }
45
+ async getDataTransaction(request) {
46
+ try {
47
+ const txRequest = {
48
+ from: request.from,
49
+ to: request.to,
50
+ data: request.data,
51
+ chainId: BigInt(request.chainId),
52
+ ...this.formatGasConfig(request.gasConfig)
53
+ };
54
+ return txRequest;
55
+ }
56
+ catch (error) {
57
+ parseError(error);
58
+ }
59
+ }
45
60
  /**
46
61
  * Helper to format gas configuration for ethers
47
62
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ethereum-transaction-builder.js","sourceRoot":"","sources":["../../../src/services/ethereum/ethereum-transaction-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAM/B,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAGpD;;GAEG;AACH,MAAM,OAAO,0BAA0B;IACrC,KAAK,CAAC,sBAAsB,CAC1B,OAA+B;QAE/B,IAAI,CAAC;YACH,4BAA4B;YAC5B,MAAM,SAAS,GAAqB;gBAClC,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,CAAC;aAC3C,CAAA;YAED,kCAAkC;YAClC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBAClB,SAAS,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAA;YACjC,CAAC;YAED,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAE/C,MAAM,IAAI,GAAG,KAAK,CAAC,kBAAkB,CACnC,OAAO,CAAC,YAAY,EACpB,OAAO,CAAC,IAAI,IAAI,EAAE,CACnB,CAAA;YAED,MAAM,SAAS,GAAuB;gBACpC,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,EAAE,EAAE,OAAO,CAAC,eAAe;gBAC3B,IAAI;gBACJ,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;gBAC1B,GAAG,SAAS;aACb,CAAA;YAED,OAAO,SAAS,CAAA;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,UAAU,CAAC,KAAK,CAAC,CAAA;QACnB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,oBAAoB,CACxB,OAAiC;QAEjC,IAAI,CAAC;YACH,OAAO;gBACL,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,KAAK,EAAE,OAAO,CAAC,MAAM;gBACrB,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,CAAC;aAC3C,CAAA;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,UAAU,CAAC,KAAK,CAAC,CAAA;QACnB,CAAC;IACH,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,SAAwB;QAC9C,MAAM,SAAS,GAAqB,EAAE,CAAA;QAEtC,IAAI,SAAS,EAAE,QAAQ,EAAE,CAAC;YACxB,SAAS,CAAC,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAA;QAC7D,CAAC;QACD,IAAI,SAAS,EAAE,YAAY,EAAE,CAAC;YAC5B,SAAS,CAAC,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAA;QACrE,CAAC;QACD,IAAI,SAAS,EAAE,oBAAoB,EAAE,CAAC;YACpC,SAAS,CAAC,oBAAoB,GAAG,MAAM,CACrC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAC3C,CAAA;QACH,CAAC;QAED,OAAO,SAAS,CAAA;IAClB,CAAC;CACF"}
1
+ {"version":3,"file":"ethereum-transaction-builder.js","sourceRoot":"","sources":["../../../src/services/ethereum/ethereum-transaction-builder.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,10 @@ export declare class EthereumTransactionService {
16
16
  * Send smart contract transaction (including ERC-20 transfers)
17
17
  */
18
18
  private sendContractCall;
19
+ /**
20
+ * Send transaction with raw data
21
+ */
22
+ private sendDataTransfer;
19
23
  private parseTransaction;
20
24
  }
21
25
  //# sourceMappingURL=ethereum-transaction-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ethereum-transaction-service.d.ts","sourceRoot":"","sources":["../../../src/services/ethereum/ethereum-transaction-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0BAA0B,EAI3B,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,UAAU,MAAM,4BAA4B,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAMxD,qBAAa,0BAA0B;IACrC,OAAO,CAAC,OAAO,CAA4B;;IAI3C;;OAEG;IACG,eAAe,CACnB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,YAAY,CAAC,MAAM,EAC5B,OAAO,EAAE,0BAA0B,EACnC,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,MAAM,CAAC;IAgClB;;OAEG;YACW,qBAAqB;IA6BnC;;OAEG;YACW,gBAAgB;IA6B9B,OAAO,CAAC,gBAAgB;CA6BzB"}
1
+ {"version":3,"file":"ethereum-transaction-service.d.ts","sourceRoot":"","sources":["../../../src/services/ethereum/ethereum-transaction-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0BAA0B,EAK3B,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,UAAU,MAAM,4BAA4B,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAMxD,qBAAa,0BAA0B;IACrC,OAAO,CAAC,OAAO,CAA4B;;IAI3C;;OAEG;IACG,eAAe,CACnB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,YAAY,CAAC,MAAM,EAC5B,OAAO,EAAE,0BAA0B,EACnC,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,MAAM,CAAC;IAwClB;;OAEG;YACW,qBAAqB;IA6BnC;;OAEG;YACW,gBAAgB;IA6B9B;;OAEG;YACW,gBAAgB;IA6B9B,OAAO,CAAC,gBAAgB;CA6BzB"}
@@ -20,6 +20,10 @@ export class EthereumTransactionService {
20
20
  // Batch transaction - not yet supported
21
21
  throw new Error('Batch transactions are not yet supported for WalletConnect');
22
22
  }
23
+ else if ('data' in request && 'chainId' in request) {
24
+ // Data transfer (raw transaction data)
25
+ return await this.sendDataTransfer(client, session, request, activeNetworkId);
26
+ }
23
27
  else if ('amount' in request && typeof request.amount === 'bigint') {
24
28
  // Native transfer
25
29
  return await this.sendNativeTransaction(client, session, request, activeNetworkId);
@@ -76,6 +80,28 @@ export class EthereumTransactionService {
76
80
  throw parseError(error);
77
81
  }
78
82
  }
83
+ /**
84
+ * Send transaction with raw data
85
+ */
86
+ async sendDataTransfer(client, session, request, activeNetworkId) {
87
+ try {
88
+ // Use the active network chainId
89
+ const chainId = getChainIdFromNetworkId(activeNetworkId);
90
+ const params = this.parseTransaction(await this.builder.getDataTransaction(request));
91
+ const hash = await client.request({
92
+ topic: session.topic,
93
+ chainId: `eip155:${chainId}`,
94
+ request: {
95
+ method: 'eth_sendTransaction',
96
+ params: [params]
97
+ }
98
+ });
99
+ return hash;
100
+ }
101
+ catch (error) {
102
+ throw parseError(error);
103
+ }
104
+ }
79
105
  parseTransaction(tx) {
80
106
  // Convert to hex format for WalletConnect
81
107
  const txParams = {
@@ -1 +1 @@
1
- {"version":3,"file":"ethereum-transaction-service.js","sourceRoot":"","sources":["../../../src/services/ethereum/ethereum-transaction-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ethereum-transaction-service.js","sourceRoot":"","sources":["../../../src/services/ethereum/ethereum-transaction-service.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meshconnect/uwc-wallet-connect-connector",
3
- "version": "0.2.14",
3
+ "version": "0.3.1",
4
4
  "description": "WalletConnect connector for Universal Wallet Connector",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -25,7 +25,7 @@
25
25
  "buffer": "^6.0.3",
26
26
  "ethers": "^6.15.0",
27
27
  "tronweb": "^6.0.4",
28
- "@meshconnect/uwc-types": "0.3.2"
28
+ "@meshconnect/uwc-types": "0.4.1"
29
29
  },
30
30
  "devDependencies": {
31
31
  "typescript": "^5.9.2"
@@ -0,0 +1,286 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest'
2
+ import { EthereumTransactionBuilder } from './ethereum-transaction-builder'
3
+ import type {
4
+ EVMNativeTransferRequest,
5
+ EVMContractCallRequest,
6
+ EVMDataTransferRequest
7
+ } from '@meshconnect/uwc-types'
8
+
9
+ describe('WalletConnect EthereumTransactionBuilder', () => {
10
+ let builder: EthereumTransactionBuilder
11
+
12
+ beforeEach(() => {
13
+ builder = new EthereumTransactionBuilder()
14
+ })
15
+
16
+ describe('getNativeTransaction', () => {
17
+ it('should build a native transaction request with from field', async () => {
18
+ const request: EVMNativeTransferRequest = {
19
+ from: '0x1234567890123456789012345678901234567890',
20
+ to: '0x0987654321098765432109876543210987654321',
21
+ amount: BigInt('1000000000000000000'), // 1 ETH
22
+ gasConfig: {
23
+ gasLimit: 21000,
24
+ maxFeePerGas: 50000000000,
25
+ maxPriorityFeePerGas: 2000000000
26
+ }
27
+ }
28
+
29
+ const result = await builder.getNativeTransaction(request)
30
+
31
+ expect(result).toEqual({
32
+ from: request.from,
33
+ to: request.to,
34
+ value: request.amount,
35
+ gasLimit: BigInt(21000),
36
+ maxFeePerGas: BigInt(50000000000),
37
+ maxPriorityFeePerGas: BigInt(2000000000)
38
+ })
39
+ })
40
+
41
+ it('should build a native transaction without gas config', async () => {
42
+ const request: EVMNativeTransferRequest = {
43
+ from: '0x1234567890123456789012345678901234567890',
44
+ to: '0x0987654321098765432109876543210987654321',
45
+ amount: BigInt('500000000000000000') // 0.5 ETH
46
+ }
47
+
48
+ const result = await builder.getNativeTransaction(request)
49
+
50
+ expect(result).toEqual({
51
+ from: request.from,
52
+ to: request.to,
53
+ value: request.amount
54
+ })
55
+ })
56
+ })
57
+
58
+ describe('getContractTransaction', () => {
59
+ it('should build a contract transaction request with from field', async () => {
60
+ const erc20ABI = [
61
+ {
62
+ inputs: [
63
+ { name: 'recipient', type: 'address' },
64
+ { name: 'amount', type: 'uint256' }
65
+ ],
66
+ name: 'transfer',
67
+ outputs: [{ name: '', type: 'bool' }],
68
+ stateMutability: 'nonpayable',
69
+ type: 'function'
70
+ }
71
+ ]
72
+
73
+ const request: EVMContractCallRequest = {
74
+ from: '0x1234567890123456789012345678901234567890',
75
+ contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
76
+ abi: erc20ABI,
77
+ functionName: 'transfer',
78
+ args: ['0x0987654321098765432109876543210987654321', BigInt(1000000)],
79
+ gasConfig: {
80
+ gasLimit: 100000
81
+ }
82
+ }
83
+
84
+ const result = await builder.getContractTransaction(request)
85
+
86
+ expect(result.from).toBe(request.from)
87
+ expect(result.to).toBe(request.contractAddress)
88
+ expect(result.data).toBeDefined()
89
+ expect(result.data).toContain('0xa9059cbb') // transfer function selector
90
+ expect(result.value).toBe(0n)
91
+ expect(result.gasLimit).toBe(BigInt(100000))
92
+ })
93
+
94
+ it('should build a payable contract transaction with value', async () => {
95
+ const payableABI = [
96
+ {
97
+ inputs: [],
98
+ name: 'deposit',
99
+ outputs: [],
100
+ stateMutability: 'payable',
101
+ type: 'function'
102
+ }
103
+ ]
104
+
105
+ const request: EVMContractCallRequest = {
106
+ from: '0x1234567890123456789012345678901234567890',
107
+ contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
108
+ abi: payableABI,
109
+ functionName: 'deposit',
110
+ args: [],
111
+ value: BigInt('1000000000000000000') // 1 ETH
112
+ }
113
+
114
+ const result = await builder.getContractTransaction(request)
115
+
116
+ expect(result.from).toBe(request.from)
117
+ expect(result.to).toBe(request.contractAddress)
118
+ expect(result.data).toBeDefined()
119
+ expect(result.value).toBe(request.value)
120
+ })
121
+ })
122
+
123
+ describe('getDataTransaction', () => {
124
+ it('should build a data transaction request with all fields', async () => {
125
+ const request: EVMDataTransferRequest = {
126
+ from: '0x1234567890123456789012345678901234567890',
127
+ to: '0x0987654321098765432109876543210987654321',
128
+ data: '0xa9059cbb000000000000000000000000123456789012345678901234567890123456789000000000000000000000000000000000000000000000000000000000000f4240',
129
+ chainId: '1',
130
+ value: BigInt('500000000000000000'), // 0.5 ETH
131
+ gasConfig: {
132
+ gasLimit: 100000,
133
+ maxFeePerGas: 50000000000,
134
+ maxPriorityFeePerGas: 2000000000
135
+ }
136
+ }
137
+
138
+ const result = await builder.getDataTransaction(request)
139
+
140
+ expect(result).toEqual({
141
+ from: request.from,
142
+ to: request.to,
143
+ data: request.data,
144
+ chainId: BigInt(1),
145
+ gasLimit: BigInt(100000),
146
+ maxFeePerGas: BigInt(50000000000),
147
+ maxPriorityFeePerGas: BigInt(2000000000)
148
+ })
149
+ })
150
+
151
+ it('should build a data transaction without value', async () => {
152
+ const request: EVMDataTransferRequest = {
153
+ from: '0x1234567890123456789012345678901234567890',
154
+ to: '0x0987654321098765432109876543210987654321',
155
+ data: '0xa9059cbb',
156
+ chainId: '137' // Polygon
157
+ }
158
+
159
+ const result = await builder.getDataTransaction(request)
160
+
161
+ expect(result).toEqual({
162
+ from: request.from,
163
+ to: request.to,
164
+ data: request.data,
165
+ chainId: BigInt(137)
166
+ })
167
+ })
168
+
169
+ it('should build a data transaction with partial gas config', async () => {
170
+ const request: EVMDataTransferRequest = {
171
+ from: '0x1234567890123456789012345678901234567890',
172
+ to: '0x0987654321098765432109876543210987654321',
173
+ data: '0x00',
174
+ chainId: '8453', // Base
175
+ gasConfig: {
176
+ gasLimit: 50000
177
+ }
178
+ }
179
+
180
+ const result = await builder.getDataTransaction(request)
181
+
182
+ expect(result.from).toBe(request.from)
183
+ expect(result.gasLimit).toBe(BigInt(50000))
184
+ expect(result.maxFeePerGas).toBeUndefined()
185
+ expect(result.maxPriorityFeePerGas).toBeUndefined()
186
+ })
187
+
188
+ it('should handle empty data field', async () => {
189
+ const request: EVMDataTransferRequest = {
190
+ from: '0x1234567890123456789012345678901234567890',
191
+ to: '0x0987654321098765432109876543210987654321',
192
+ data: '0x',
193
+ chainId: '1'
194
+ }
195
+
196
+ const result = await builder.getDataTransaction(request)
197
+
198
+ expect(result.from).toBe(request.from)
199
+ expect(result.data).toBe('0x')
200
+ expect(result.to).toBe(request.to)
201
+ expect(result.chainId).toBe(BigInt(1))
202
+ })
203
+
204
+ it('should handle complex encoded data', async () => {
205
+ const complexData = '0x' + 'a'.repeat(1000) // Long hex string
206
+
207
+ const request: EVMDataTransferRequest = {
208
+ from: '0x1234567890123456789012345678901234567890',
209
+ to: '0x0987654321098765432109876543210987654321',
210
+ data: complexData,
211
+ chainId: '42161' // Arbitrum
212
+ }
213
+
214
+ const result = await builder.getDataTransaction(request)
215
+
216
+ expect(result.from).toBe(request.from)
217
+ expect(result.data).toBe(complexData)
218
+ expect(result.chainId).toBe(BigInt(42161))
219
+ })
220
+
221
+ it('should handle different chain IDs', async () => {
222
+ const chains = [
223
+ { id: '1', name: 'Ethereum' },
224
+ { id: '137', name: 'Polygon' },
225
+ { id: '8453', name: 'Base' },
226
+ { id: '42161', name: 'Arbitrum' },
227
+ { id: '10', name: 'Optimism' }
228
+ ]
229
+
230
+ for (const chain of chains) {
231
+ const request: EVMDataTransferRequest = {
232
+ from: '0x1234567890123456789012345678901234567890',
233
+ to: '0x0987654321098765432109876543210987654321',
234
+ data: '0xa9059cbb',
235
+ chainId: chain.id
236
+ }
237
+
238
+ const result = await builder.getDataTransaction(request)
239
+
240
+ expect(result.chainId).toBe(BigInt(chain.id))
241
+ }
242
+ })
243
+ })
244
+
245
+ describe('formatGasConfig', () => {
246
+ it('should handle null gas config values', async () => {
247
+ const request: EVMDataTransferRequest = {
248
+ from: '0x1234567890123456789012345678901234567890',
249
+ to: '0x0987654321098765432109876543210987654321',
250
+ data: '0x00',
251
+ chainId: '1',
252
+ gasConfig: {
253
+ gasLimit: null,
254
+ maxFeePerGas: null,
255
+ maxPriorityFeePerGas: null
256
+ }
257
+ }
258
+
259
+ const result = await builder.getDataTransaction(request)
260
+
261
+ expect(result.gasLimit).toBeUndefined()
262
+ expect(result.maxFeePerGas).toBeUndefined()
263
+ expect(result.maxPriorityFeePerGas).toBeUndefined()
264
+ })
265
+
266
+ it('should floor decimal gas values', async () => {
267
+ const request: EVMDataTransferRequest = {
268
+ from: '0x1234567890123456789012345678901234567890',
269
+ to: '0x0987654321098765432109876543210987654321',
270
+ data: '0x00',
271
+ chainId: '1',
272
+ gasConfig: {
273
+ gasLimit: 100000.7,
274
+ maxFeePerGas: 50000000000.9,
275
+ maxPriorityFeePerGas: 2000000000.1
276
+ }
277
+ }
278
+
279
+ const result = await builder.getDataTransaction(request)
280
+
281
+ expect(result.gasLimit).toBe(BigInt(100000))
282
+ expect(result.maxFeePerGas).toBe(BigInt(50000000000))
283
+ expect(result.maxPriorityFeePerGas).toBe(BigInt(2000000000))
284
+ })
285
+ })
286
+ })
@@ -2,7 +2,8 @@ import { ethers } from 'ethers'
2
2
  import type {
3
3
  EVMGasConfig,
4
4
  EVMNativeTransferRequest,
5
- EVMContractCallRequest
5
+ EVMContractCallRequest,
6
+ EVMDataTransferRequest
6
7
  } from '@meshconnect/uwc-types'
7
8
  import { parseError } from '../../utils/error-utils'
8
9
  import type { TransactionRequest } from 'ethers'
@@ -61,6 +62,24 @@ export class EthereumTransactionBuilder {
61
62
  }
62
63
  }
63
64
 
65
+ async getDataTransaction(
66
+ request: EVMDataTransferRequest
67
+ ): Promise<TransactionRequest> {
68
+ try {
69
+ const txRequest: TransactionRequest = {
70
+ from: request.from,
71
+ to: request.to,
72
+ data: request.data,
73
+ chainId: BigInt(request.chainId),
74
+ ...this.formatGasConfig(request.gasConfig)
75
+ }
76
+
77
+ return txRequest
78
+ } catch (error) {
79
+ parseError(error)
80
+ }
81
+ }
82
+
64
83
  /**
65
84
  * Helper to format gas configuration for ethers
66
85
  */
@@ -0,0 +1,450 @@
1
+ import { describe, it, expect, beforeEach, vi } from 'vitest'
2
+ import { EthereumTransactionService } from './ethereum-transaction-service'
3
+ import type {
4
+ EVMNativeTransferRequest,
5
+ EVMContractCallRequest,
6
+ EVMDataTransferRequest,
7
+ NetworkId
8
+ } from '@meshconnect/uwc-types'
9
+ import type SignClient from '@walletconnect/sign-client'
10
+ import type { SessionTypes } from '@walletconnect/types'
11
+
12
+ // Mock dependencies
13
+ vi.mock('../../utils/account-utils', () => ({
14
+ getChainIdFromNetworkId: vi.fn((networkId: NetworkId) => {
15
+ const chainMap: Record<string, number> = {
16
+ 'eip155:1': 1,
17
+ 'eip155:137': 137,
18
+ 'eip155:8453': 8453,
19
+ 'eip155:42161': 42161,
20
+ 'eip155:10': 10
21
+ }
22
+ return chainMap[networkId] || 1
23
+ })
24
+ }))
25
+
26
+ vi.mock('ethers', () => ({
27
+ ethers: {
28
+ Interface: vi.fn().mockImplementation(() => ({
29
+ encodeFunctionData: vi.fn().mockReturnValue('0xencodeddata')
30
+ }))
31
+ }
32
+ }))
33
+
34
+ describe('WalletConnect EthereumTransactionService', () => {
35
+ let service: EthereumTransactionService
36
+ let mockClient: SignClient
37
+ let mockSession: SessionTypes.Struct
38
+
39
+ beforeEach(() => {
40
+ vi.clearAllMocks()
41
+ service = new EthereumTransactionService()
42
+
43
+ mockClient = {
44
+ request: vi.fn().mockResolvedValue('0xtxhash')
45
+ } as any
46
+
47
+ mockSession = {
48
+ topic: 'test-topic',
49
+ pairingTopic: 'pairing-topic',
50
+ relay: { protocol: 'irn' },
51
+ expiry: Date.now() + 86400,
52
+ acknowledged: true,
53
+ controller: 'test-controller',
54
+ namespaces: {},
55
+ requiredNamespaces: {},
56
+ optionalNamespaces: {},
57
+ self: {
58
+ publicKey: 'test-public-key',
59
+ metadata: {
60
+ name: 'Test dApp',
61
+ description: 'Test',
62
+ url: 'https://test.com',
63
+ icons: []
64
+ }
65
+ },
66
+ peer: {
67
+ publicKey: 'peer-public-key',
68
+ metadata: {
69
+ name: 'Test Wallet',
70
+ description: 'Test',
71
+ url: 'https://wallet.com',
72
+ icons: []
73
+ }
74
+ }
75
+ }
76
+ })
77
+
78
+ describe('sendTransaction routing', () => {
79
+ it('should route native transfer to sendNativeTransaction', async () => {
80
+ const request: EVMNativeTransferRequest = {
81
+ from: '0x1234567890123456789012345678901234567890',
82
+ to: '0x0987654321098765432109876543210987654321',
83
+ amount: BigInt('1000000000000000000'),
84
+ gasConfig: { gasLimit: 21000 }
85
+ }
86
+
87
+ const result = await service.sendTransaction(
88
+ mockClient,
89
+ mockSession,
90
+ request,
91
+ 'eip155:1'
92
+ )
93
+
94
+ expect(result).toBe('0xtxhash')
95
+ expect(mockClient.request).toHaveBeenCalledWith(
96
+ expect.objectContaining({
97
+ topic: mockSession.topic,
98
+ chainId: 'eip155:1'
99
+ })
100
+ )
101
+ })
102
+
103
+ it('should route contract call to sendContractCall', async () => {
104
+ const request: EVMContractCallRequest = {
105
+ from: '0x1234567890123456789012345678901234567890',
106
+ contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
107
+ abi: [
108
+ {
109
+ inputs: [
110
+ { name: 'recipient', type: 'address' },
111
+ { name: 'amount', type: 'uint256' }
112
+ ],
113
+ name: 'transfer',
114
+ outputs: [{ name: '', type: 'bool' }],
115
+ stateMutability: 'nonpayable',
116
+ type: 'function'
117
+ }
118
+ ],
119
+ functionName: 'transfer',
120
+ args: ['0x0987654321098765432109876543210987654321', BigInt(1000000)]
121
+ }
122
+
123
+ const result = await service.sendTransaction(
124
+ mockClient,
125
+ mockSession,
126
+ request,
127
+ 'eip155:1'
128
+ )
129
+
130
+ expect(result).toBe('0xtxhash')
131
+ })
132
+
133
+ it('should route data transfer to sendDataTransfer', async () => {
134
+ const request: EVMDataTransferRequest = {
135
+ from: '0x1234567890123456789012345678901234567890',
136
+ to: '0x0987654321098765432109876543210987654321',
137
+ data: '0xa9059cbb',
138
+ chainId: '1'
139
+ }
140
+
141
+ const result = await service.sendTransaction(
142
+ mockClient,
143
+ mockSession,
144
+ request,
145
+ 'eip155:1'
146
+ )
147
+
148
+ expect(result).toBe('0xtxhash')
149
+ })
150
+
151
+ it('should throw error for batch transactions', async () => {
152
+ const request = {
153
+ from: '0x1234567890123456789012345678901234567890',
154
+ calls: []
155
+ } as any
156
+
157
+ await expect(
158
+ service.sendTransaction(mockClient, mockSession, request, 'eip155:1')
159
+ ).rejects.toThrow('Batch transactions are not yet supported')
160
+ })
161
+
162
+ it('should throw error for invalid request type', async () => {
163
+ const invalidRequest = {
164
+ from: '0x1234567890123456789012345678901234567890'
165
+ } as any
166
+
167
+ await expect(
168
+ service.sendTransaction(
169
+ mockClient,
170
+ mockSession,
171
+ invalidRequest,
172
+ 'eip155:1'
173
+ )
174
+ ).rejects.toThrow('Invalid transaction request type')
175
+ })
176
+ })
177
+
178
+ describe('sendDataTransfer', () => {
179
+ it('should send data transfer successfully', async () => {
180
+ const request: EVMDataTransferRequest = {
181
+ from: '0x1234567890123456789012345678901234567890',
182
+ to: '0x0987654321098765432109876543210987654321',
183
+ data: '0xa9059cbb000000000000000000000000123456789012345678901234567890123456789000000000000000000000000000000000000000000000000000000000000f4240',
184
+ chainId: '1'
185
+ }
186
+
187
+ const result = await service.sendTransaction(
188
+ mockClient,
189
+ mockSession,
190
+ request,
191
+ 'eip155:1'
192
+ )
193
+
194
+ expect(result).toBe('0xtxhash')
195
+ expect(mockClient.request).toHaveBeenCalledWith({
196
+ topic: mockSession.topic,
197
+ chainId: 'eip155:1',
198
+ request: {
199
+ method: 'eth_sendTransaction',
200
+ params: [
201
+ expect.objectContaining({
202
+ from: request.from,
203
+ to: request.to,
204
+ data: request.data
205
+ })
206
+ ]
207
+ }
208
+ })
209
+ })
210
+
211
+ it('should send data transfer with value', async () => {
212
+ const request: EVMDataTransferRequest = {
213
+ from: '0x1234567890123456789012345678901234567890',
214
+ to: '0x0987654321098765432109876543210987654321',
215
+ data: '0xa9059cbb',
216
+ chainId: '1',
217
+ value: BigInt('500000000000000000')
218
+ }
219
+
220
+ const result = await service.sendTransaction(
221
+ mockClient,
222
+ mockSession,
223
+ request,
224
+ 'eip155:1'
225
+ )
226
+
227
+ expect(result).toBe('0xtxhash')
228
+ })
229
+
230
+ it('should send data transfer with gas config', async () => {
231
+ const request: EVMDataTransferRequest = {
232
+ from: '0x1234567890123456789012345678901234567890',
233
+ to: '0x0987654321098765432109876543210987654321',
234
+ data: '0x00',
235
+ chainId: '137',
236
+ gasConfig: {
237
+ gasLimit: 100000,
238
+ maxFeePerGas: 50000000000,
239
+ maxPriorityFeePerGas: 2000000000
240
+ }
241
+ }
242
+
243
+ const result = await service.sendTransaction(
244
+ mockClient,
245
+ mockSession,
246
+ request,
247
+ 'eip155:137'
248
+ )
249
+
250
+ expect(result).toBe('0xtxhash')
251
+ expect(mockClient.request).toHaveBeenCalledWith(
252
+ expect.objectContaining({
253
+ chainId: 'eip155:137'
254
+ })
255
+ )
256
+ })
257
+
258
+ it('should send data transfer on different networks', async () => {
259
+ const networks = [
260
+ 'eip155:1',
261
+ 'eip155:137',
262
+ 'eip155:8453',
263
+ 'eip155:42161',
264
+ 'eip155:10'
265
+ ]
266
+
267
+ for (const networkId of networks) {
268
+ vi.mocked(mockClient.request).mockClear()
269
+
270
+ const request: EVMDataTransferRequest = {
271
+ from: '0x1234567890123456789012345678901234567890',
272
+ to: '0x0987654321098765432109876543210987654321',
273
+ data: '0xa9059cbb',
274
+ chainId: networkId.split(':')[1]
275
+ }
276
+
277
+ const result = await service.sendTransaction(
278
+ mockClient,
279
+ mockSession,
280
+ request,
281
+ networkId
282
+ )
283
+
284
+ expect(result).toBe('0xtxhash')
285
+ expect(mockClient.request).toHaveBeenCalledWith(
286
+ expect.objectContaining({
287
+ chainId: networkId
288
+ })
289
+ )
290
+ }
291
+ })
292
+
293
+ it('should handle empty data field', async () => {
294
+ const request: EVMDataTransferRequest = {
295
+ from: '0x1234567890123456789012345678901234567890',
296
+ to: '0x0987654321098765432109876543210987654321',
297
+ data: '0x',
298
+ chainId: '1'
299
+ }
300
+
301
+ const result = await service.sendTransaction(
302
+ mockClient,
303
+ mockSession,
304
+ request,
305
+ 'eip155:1'
306
+ )
307
+
308
+ expect(result).toBe('0xtxhash')
309
+ expect(mockClient.request).toHaveBeenCalledWith(
310
+ expect.objectContaining({
311
+ request: {
312
+ method: 'eth_sendTransaction',
313
+ params: [
314
+ expect.objectContaining({
315
+ data: '0x'
316
+ })
317
+ ]
318
+ }
319
+ })
320
+ )
321
+ })
322
+
323
+ it('should handle complex encoded data', async () => {
324
+ const complexData = '0x' + 'a'.repeat(1000)
325
+
326
+ const request: EVMDataTransferRequest = {
327
+ from: '0x1234567890123456789012345678901234567890',
328
+ to: '0x0987654321098765432109876543210987654321',
329
+ data: complexData,
330
+ chainId: '1'
331
+ }
332
+
333
+ const result = await service.sendTransaction(
334
+ mockClient,
335
+ mockSession,
336
+ request,
337
+ 'eip155:1'
338
+ )
339
+
340
+ expect(result).toBe('0xtxhash')
341
+ })
342
+ })
343
+
344
+ describe('parseTransaction', () => {
345
+ it('should convert BigInt values to hex format', async () => {
346
+ const request: EVMDataTransferRequest = {
347
+ from: '0x1234567890123456789012345678901234567890',
348
+ to: '0x0987654321098765432109876543210987654321',
349
+ data: '0xa9059cbb',
350
+ chainId: '1',
351
+ value: BigInt('1000000000000000000'),
352
+ gasConfig: {
353
+ gasLimit: 21000,
354
+ maxFeePerGas: 50000000000,
355
+ maxPriorityFeePerGas: 2000000000
356
+ }
357
+ }
358
+
359
+ await service.sendTransaction(
360
+ mockClient,
361
+ mockSession,
362
+ request,
363
+ 'eip155:1'
364
+ )
365
+
366
+ expect(mockClient.request).toHaveBeenCalledWith(
367
+ expect.objectContaining({
368
+ request: {
369
+ method: 'eth_sendTransaction',
370
+ params: [
371
+ expect.objectContaining({
372
+ from: request.from,
373
+ to: request.to,
374
+ data: request.data,
375
+ gasLimit: expect.stringMatching(/^0x/),
376
+ maxFeePerGas: expect.stringMatching(/^0x/),
377
+ maxPriorityFeePerGas: expect.stringMatching(/^0x/)
378
+ })
379
+ ]
380
+ }
381
+ })
382
+ )
383
+ })
384
+
385
+ it('should handle missing value field', async () => {
386
+ const request: EVMDataTransferRequest = {
387
+ from: '0x1234567890123456789012345678901234567890',
388
+ to: '0x0987654321098765432109876543210987654321',
389
+ data: '0xa9059cbb',
390
+ chainId: '1'
391
+ }
392
+
393
+ await service.sendTransaction(
394
+ mockClient,
395
+ mockSession,
396
+ request,
397
+ 'eip155:1'
398
+ )
399
+
400
+ const callArgs = vi.mocked(mockClient.request).mock.calls[0][0]
401
+ const params = (callArgs.request as any).params[0]
402
+
403
+ // Value should either not exist or be undefined/deleted
404
+ expect(params.value === undefined || !('value' in params)).toBe(true)
405
+ })
406
+ })
407
+
408
+ describe('error handling', () => {
409
+ it('should handle WalletConnect request errors', async () => {
410
+ const mockError = new Error('User rejected')
411
+ vi.mocked(mockClient.request).mockRejectedValueOnce(mockError)
412
+
413
+ const request: EVMDataTransferRequest = {
414
+ from: '0x1234567890123456789012345678901234567890',
415
+ to: '0x0987654321098765432109876543210987654321',
416
+ data: '0xa9059cbb',
417
+ chainId: '1'
418
+ }
419
+
420
+ await expect(
421
+ service.sendTransaction(mockClient, mockSession, request, 'eip155:1')
422
+ ).rejects.toThrow()
423
+ })
424
+
425
+ it('should handle network mismatch', async () => {
426
+ const request: EVMDataTransferRequest = {
427
+ from: '0x1234567890123456789012345678901234567890',
428
+ to: '0x0987654321098765432109876543210987654321',
429
+ data: '0xa9059cbb',
430
+ chainId: '137' // Polygon
431
+ }
432
+
433
+ // Send on Ethereum network
434
+ const result = await service.sendTransaction(
435
+ mockClient,
436
+ mockSession,
437
+ request,
438
+ 'eip155:1'
439
+ )
440
+
441
+ expect(result).toBe('0xtxhash')
442
+ // Should use the activeNetworkId for chainId in request
443
+ expect(mockClient.request).toHaveBeenCalledWith(
444
+ expect.objectContaining({
445
+ chainId: 'eip155:1'
446
+ })
447
+ )
448
+ })
449
+ })
450
+ })
@@ -2,6 +2,7 @@ import type {
2
2
  EthereumTransactionRequest,
3
3
  EVMContractCallRequest,
4
4
  EVMNativeTransferRequest,
5
+ EVMDataTransferRequest,
5
6
  NetworkId
6
7
  } from '@meshconnect/uwc-types'
7
8
  import type SignClient from '@walletconnect/sign-client'
@@ -40,6 +41,14 @@ export class EthereumTransactionService {
40
41
  throw new Error(
41
42
  'Batch transactions are not yet supported for WalletConnect'
42
43
  )
44
+ } else if ('data' in request && 'chainId' in request) {
45
+ // Data transfer (raw transaction data)
46
+ return await this.sendDataTransfer(
47
+ client,
48
+ session,
49
+ request as EVMDataTransferRequest,
50
+ activeNetworkId
51
+ )
43
52
  } else if ('amount' in request && typeof request.amount === 'bigint') {
44
53
  // Native transfer
45
54
  return await this.sendNativeTransaction(
@@ -120,6 +129,38 @@ export class EthereumTransactionService {
120
129
  }
121
130
  }
122
131
 
132
+ /**
133
+ * Send transaction with raw data
134
+ */
135
+ private async sendDataTransfer(
136
+ client: SignClient,
137
+ session: SessionTypes.Struct,
138
+ request: EVMDataTransferRequest,
139
+ activeNetworkId: string
140
+ ): Promise<string> {
141
+ try {
142
+ // Use the active network chainId
143
+ const chainId = getChainIdFromNetworkId(activeNetworkId as NetworkId)
144
+
145
+ const params = this.parseTransaction(
146
+ await this.builder.getDataTransaction(request)
147
+ )
148
+
149
+ const hash = await client.request({
150
+ topic: session.topic,
151
+ chainId: `eip155:${chainId}`,
152
+ request: {
153
+ method: 'eth_sendTransaction',
154
+ params: [params]
155
+ }
156
+ })
157
+
158
+ return hash as string
159
+ } catch (error) {
160
+ throw parseError(error)
161
+ }
162
+ }
163
+
123
164
  private parseTransaction(tx: TransactionRequest): Record<string, string> {
124
165
  // Convert to hex format for WalletConnect
125
166
  const txParams: Record<string, string> = {