@dynamic-labs-wallet/evm 0.0.28

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/index.cjs.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./src/index";
package/index.cjs.js ADDED
@@ -0,0 +1,296 @@
1
+ 'use strict';
2
+
3
+ var browser = require('@dynamic-labs-wallet/browser');
4
+ var viem = require('viem');
5
+ var chains = require('viem/chains');
6
+
7
+ function _extends() {
8
+ _extends = Object.assign || function assign(target) {
9
+ for(var i = 1; i < arguments.length; i++){
10
+ var source = arguments[i];
11
+ for(var key in source)if (Object.prototype.hasOwnProperty.call(source, key)) target[key] = source[key];
12
+ }
13
+ return target;
14
+ };
15
+ return _extends.apply(this, arguments);
16
+ }
17
+
18
+ const EVM_SIGN_MESSAGE_PREFIX = `\x19Ethereum Signed Message:\n`;
19
+ // Error messages
20
+ const ERROR_KEYGEN_FAILED = 'Error with keygen';
21
+ const ERROR_CREATE_WALLET_ACCOUNT = 'Error creating evm wallet account';
22
+ const ERROR_SIGN_MESSAGE = 'Error signing message';
23
+ const ERROR_ACCOUNT_ADDRESS_REQUIRED = 'Account address is required';
24
+ const ERROR_VERIFY_MESSAGE_SIGNATURE = 'Error verifying message signature';
25
+
26
+ const formatEVMMessage = (message)=>{
27
+ return `${EVM_SIGN_MESSAGE_PREFIX}${message.length}${message}`;
28
+ };
29
+ const serializeECDSASignature = (signature)=>{
30
+ return viem.serializeSignature({
31
+ r: `0x${Buffer.from(signature.r).toString('hex')}`,
32
+ s: `0x${Buffer.from(signature.s).toString('hex')}`,
33
+ v: BigInt(signature.v)
34
+ });
35
+ };
36
+
37
+ class DynamicEvmWalletClient extends browser.DynamicWalletClient {
38
+ createViemPublicClient({ chain, rpcUrl }) {
39
+ return viem.createPublicClient({
40
+ chain,
41
+ transport: viem.http(rpcUrl)
42
+ });
43
+ }
44
+ async createWalletAccount({ thresholdSignatureScheme }) {
45
+ try {
46
+ // Generate key shares for given threshold signature scheme (TSS)
47
+ const { rawPublicKey, clientKeyShares } = await this.keyGen({
48
+ chainName: this.chainName,
49
+ thresholdSignatureScheme
50
+ });
51
+ if (!rawPublicKey || !clientKeyShares) {
52
+ throw new Error(ERROR_KEYGEN_FAILED);
53
+ }
54
+ // Get EVM address from public key
55
+ const { accountAddress, publicKeyHex } = await this.deriveAccountAddress({
56
+ rawPublicKey: rawPublicKey
57
+ });
58
+ // Refresh user to get the latest user data
59
+ const refreshedUser = await this.apiClient.refreshUser();
60
+ // Find the new wallet in the user's verified credentials
61
+ const newWallet = refreshedUser.user.verifiedCredentials.find((wallet)=>wallet.address.toLowerCase() === accountAddress.toLowerCase());
62
+ const newWalletId = newWallet.id;
63
+ // Store the new wallet in the wallet map
64
+ this.walletMap[accountAddress] = {
65
+ accountAddress,
66
+ walletId: newWalletId,
67
+ chainName: this.chainName,
68
+ clientKeyShares: clientKeyShares,
69
+ thresholdSignatureScheme
70
+ };
71
+ // Backup the new wallet
72
+ await this.storeEncryptedBackupByWallet({
73
+ accountAddress,
74
+ password: undefined
75
+ });
76
+ return {
77
+ accountAddress,
78
+ rawPublicKey,
79
+ publicKeyHex,
80
+ clientKeyShares
81
+ };
82
+ } catch (error) {
83
+ this.logger.error(ERROR_CREATE_WALLET_ACCOUNT, error);
84
+ throw new Error(ERROR_CREATE_WALLET_ACCOUNT);
85
+ }
86
+ }
87
+ async signMessage({ message, accountAddress }) {
88
+ try {
89
+ if (!accountAddress) {
90
+ throw new Error(ERROR_ACCOUNT_ADDRESS_REQUIRED);
91
+ }
92
+ // Format the message for EVM signing
93
+ const formattedMessage = formatEVMMessage(message);
94
+ // Sign the message using MPC
95
+ const signatureEcdsa = await this.sign({
96
+ message: formattedMessage,
97
+ accountAddress: accountAddress,
98
+ chainName: this.chainName
99
+ });
100
+ // Serialize the signature
101
+ const serializedSignature = serializeECDSASignature(signatureEcdsa);
102
+ return serializedSignature;
103
+ } catch (error) {
104
+ this.logger.error(ERROR_SIGN_MESSAGE, error);
105
+ throw new Error(ERROR_SIGN_MESSAGE);
106
+ }
107
+ }
108
+ async verifyMessageSignature({ accountAddress, message, signature }) {
109
+ try {
110
+ // Verify the signature using the public client
111
+ const publicClient = this.createViemPublicClient({
112
+ chain: chains.mainnet
113
+ });
114
+ const verified = await publicClient.verifyMessage({
115
+ address: accountAddress,
116
+ message,
117
+ signature: signature
118
+ });
119
+ return verified;
120
+ } catch (error) {
121
+ this.logger.error(ERROR_VERIFY_MESSAGE_SIGNATURE, error);
122
+ throw new Error(ERROR_VERIFY_MESSAGE_SIGNATURE);
123
+ }
124
+ }
125
+ async signTransaction({ chain, senderAddress, toAddress, value, gas, maxFeePerGas, maxPriorityFeePerGas, rpcUrl, broadcastTxn = false }) {
126
+ const publicClient = this.createViemPublicClient({
127
+ chain,
128
+ rpcUrl
129
+ });
130
+ // Get the balance of the sender address
131
+ const balance = await publicClient.getBalance({
132
+ address: senderAddress
133
+ });
134
+ // Calculate total cost (gas * maxFeePerGas + value)
135
+ const totalCost = gas * maxFeePerGas + value;
136
+ if (balance < totalCost) {
137
+ throw new Error(`Insufficient funds. Required: ${totalCost}, Available: ${balance}`);
138
+ }
139
+ const walletClient = viem.createWalletClient({
140
+ chain,
141
+ transport: viem.http(rpcUrl),
142
+ account: senderAddress
143
+ });
144
+ const nonce = await publicClient.getTransactionCount({
145
+ address: senderAddress
146
+ });
147
+ const transactionRequest = {
148
+ to: toAddress,
149
+ value,
150
+ chainId: chain.id,
151
+ type: 'eip1559',
152
+ gas,
153
+ maxFeePerGas,
154
+ maxPriorityFeePerGas,
155
+ nonce,
156
+ from: senderAddress,
157
+ accessList: []
158
+ };
159
+ const preparedTx = await walletClient.prepareTransactionRequest(transactionRequest);
160
+ // Get the transaction hash that needs to be signed
161
+ const unsignedTx = _extends({}, preparedTx, {
162
+ type: 'eip1559'
163
+ });
164
+ // Get the keccak256 hash of the transaction
165
+ const serializedTx = viem.serializeTransaction(unsignedTx);
166
+ const serializedTxBytes = Uint8Array.from(Buffer.from(serializedTx.slice(2), 'hex'));
167
+ if (!(serializedTxBytes instanceof Uint8Array)) {
168
+ throw new Error('Invalid serializedTxBytes');
169
+ }
170
+ // Get signature using MPC (this will coordinate with server party)
171
+ const signatureEcdsa = await this.sign({
172
+ message: serializedTxBytes,
173
+ accountAddress: senderAddress,
174
+ chainName: this.chainName
175
+ });
176
+ if (!('r' in signatureEcdsa && 's' in signatureEcdsa && 'v' in signatureEcdsa)) {
177
+ throw new Error('Invalid signature format returned from MPC signing');
178
+ }
179
+ try {
180
+ const r = `0x${Buffer.from(signatureEcdsa.r).toString('hex')}`;
181
+ const s = `0x${Buffer.from(signatureEcdsa.s).toString('hex')}`;
182
+ const v = BigInt(signatureEcdsa.v);
183
+ const signedTx = {
184
+ to: unsignedTx.to,
185
+ value: unsignedTx.value,
186
+ chainId: chain.id,
187
+ type: 'eip1559',
188
+ gas: unsignedTx.gas,
189
+ maxFeePerGas: unsignedTx.maxFeePerGas,
190
+ maxPriorityFeePerGas: unsignedTx.maxPriorityFeePerGas,
191
+ nonce: unsignedTx.nonce,
192
+ r: r,
193
+ s: s,
194
+ v: v
195
+ };
196
+ // Serialize the signed transaction
197
+ const serializedSignedTx = viem.serializeTransaction(signedTx);
198
+ let txHash;
199
+ // Send the raw transaction
200
+ if (broadcastTxn) {
201
+ const sentTxHash = await walletClient.sendRawTransaction({
202
+ serializedTransaction: serializedSignedTx
203
+ });
204
+ this.logger.info('Transaction broadcasted! Hash:', sentTxHash);
205
+ txHash = sentTxHash;
206
+ }
207
+ return {
208
+ txHash,
209
+ signedTx: serializedSignedTx
210
+ };
211
+ } catch (error) {
212
+ this.logger.error('Error signing transaction:', error);
213
+ throw error;
214
+ }
215
+ }
216
+ async deriveAccountAddress({ rawPublicKey }) {
217
+ const serializedUncompressed = rawPublicKey.serializeUncompressed();
218
+ const firstByteRemoved = serializedUncompressed.slice(1);
219
+ const hashed = browser.MessageHash.keccak256(firstByteRemoved).bytes;
220
+ const lastTwentyBytes = hashed.slice(-20);
221
+ const accountAddress = '0x' + Buffer.from(lastTwentyBytes).toString('hex');
222
+ const publicKeyHex = rawPublicKey.pubKeyAsHex();
223
+ return {
224
+ accountAddress,
225
+ publicKeyHex
226
+ };
227
+ }
228
+ async exportPrivateKey({ accountAddress }) {
229
+ const { derivedPrivateKey } = await this.exportKey({
230
+ accountAddress,
231
+ chainName: this.chainName
232
+ });
233
+ return {
234
+ derivedPrivateKey
235
+ };
236
+ }
237
+ async offlineExportPrivateKey({ keyShares }) {
238
+ const { derivedPrivateKey } = await this.offlineExportKey({
239
+ chainName: this.chainName,
240
+ keyShares
241
+ });
242
+ return {
243
+ derivedPrivateKey
244
+ };
245
+ }
246
+ async importPrivateKey({ privateKey, chainName, thresholdSignatureScheme }) {
247
+ // TODO: validate private key for EVM
248
+ const { rawPublicKey, clientKeyShares } = await this.importRawPrivateKey({
249
+ chainName,
250
+ privateKey,
251
+ thresholdSignatureScheme
252
+ });
253
+ if (!rawPublicKey || !clientKeyShares) {
254
+ throw new Error('Error creating wallet account');
255
+ }
256
+ const { accountAddress, publicKeyHex } = await this.deriveAccountAddress({
257
+ rawPublicKey: rawPublicKey
258
+ });
259
+ const refreshedUser = await this.apiClient.refreshUser();
260
+ const newWallet = refreshedUser.user.verifiedCredentials.find((wallet)=>wallet.address.toLowerCase() === accountAddress.toLowerCase());
261
+ const newWalletId = newWallet.id;
262
+ this.walletMap[accountAddress] = {
263
+ accountAddress,
264
+ walletId: newWalletId,
265
+ chainName: this.chainName,
266
+ clientKeyShares,
267
+ thresholdSignatureScheme
268
+ };
269
+ await this.storeEncryptedBackupByWallet({
270
+ accountAddress
271
+ });
272
+ return {
273
+ accountAddress,
274
+ rawPublicKey,
275
+ publicKeyHex,
276
+ clientKeyShares
277
+ };
278
+ }
279
+ async getEvmWallets() {
280
+ const wallets = await this.getWallets();
281
+ const evmWallets = wallets.filter((wallet)=>wallet.chainName === 'eip155');
282
+ return evmWallets;
283
+ }
284
+ constructor({ environmentId, authToken, baseApiUrl, baseMPCRelayApiUrl, storageKey, debug }){
285
+ super({
286
+ environmentId,
287
+ authToken,
288
+ baseApiUrl,
289
+ baseMPCRelayApiUrl,
290
+ storageKey,
291
+ debug
292
+ }), this.chainName = 'EVM';
293
+ }
294
+ }
295
+
296
+ exports.DynamicEvmWalletClient = DynamicEvmWalletClient;
package/index.esm.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./src/index";
package/index.esm.js ADDED
@@ -0,0 +1,294 @@
1
+ import { DynamicWalletClient, MessageHash } from '@dynamic-labs-wallet/browser';
2
+ import { serializeSignature, createPublicClient, http, createWalletClient, serializeTransaction } from 'viem';
3
+ import { mainnet } from 'viem/chains';
4
+
5
+ function _extends() {
6
+ _extends = Object.assign || function assign(target) {
7
+ for(var i = 1; i < arguments.length; i++){
8
+ var source = arguments[i];
9
+ for(var key in source)if (Object.prototype.hasOwnProperty.call(source, key)) target[key] = source[key];
10
+ }
11
+ return target;
12
+ };
13
+ return _extends.apply(this, arguments);
14
+ }
15
+
16
+ const EVM_SIGN_MESSAGE_PREFIX = `\x19Ethereum Signed Message:\n`;
17
+ // Error messages
18
+ const ERROR_KEYGEN_FAILED = 'Error with keygen';
19
+ const ERROR_CREATE_WALLET_ACCOUNT = 'Error creating evm wallet account';
20
+ const ERROR_SIGN_MESSAGE = 'Error signing message';
21
+ const ERROR_ACCOUNT_ADDRESS_REQUIRED = 'Account address is required';
22
+ const ERROR_VERIFY_MESSAGE_SIGNATURE = 'Error verifying message signature';
23
+
24
+ const formatEVMMessage = (message)=>{
25
+ return `${EVM_SIGN_MESSAGE_PREFIX}${message.length}${message}`;
26
+ };
27
+ const serializeECDSASignature = (signature)=>{
28
+ return serializeSignature({
29
+ r: `0x${Buffer.from(signature.r).toString('hex')}`,
30
+ s: `0x${Buffer.from(signature.s).toString('hex')}`,
31
+ v: BigInt(signature.v)
32
+ });
33
+ };
34
+
35
+ class DynamicEvmWalletClient extends DynamicWalletClient {
36
+ createViemPublicClient({ chain, rpcUrl }) {
37
+ return createPublicClient({
38
+ chain,
39
+ transport: http(rpcUrl)
40
+ });
41
+ }
42
+ async createWalletAccount({ thresholdSignatureScheme }) {
43
+ try {
44
+ // Generate key shares for given threshold signature scheme (TSS)
45
+ const { rawPublicKey, clientKeyShares } = await this.keyGen({
46
+ chainName: this.chainName,
47
+ thresholdSignatureScheme
48
+ });
49
+ if (!rawPublicKey || !clientKeyShares) {
50
+ throw new Error(ERROR_KEYGEN_FAILED);
51
+ }
52
+ // Get EVM address from public key
53
+ const { accountAddress, publicKeyHex } = await this.deriveAccountAddress({
54
+ rawPublicKey: rawPublicKey
55
+ });
56
+ // Refresh user to get the latest user data
57
+ const refreshedUser = await this.apiClient.refreshUser();
58
+ // Find the new wallet in the user's verified credentials
59
+ const newWallet = refreshedUser.user.verifiedCredentials.find((wallet)=>wallet.address.toLowerCase() === accountAddress.toLowerCase());
60
+ const newWalletId = newWallet.id;
61
+ // Store the new wallet in the wallet map
62
+ this.walletMap[accountAddress] = {
63
+ accountAddress,
64
+ walletId: newWalletId,
65
+ chainName: this.chainName,
66
+ clientKeyShares: clientKeyShares,
67
+ thresholdSignatureScheme
68
+ };
69
+ // Backup the new wallet
70
+ await this.storeEncryptedBackupByWallet({
71
+ accountAddress,
72
+ password: undefined
73
+ });
74
+ return {
75
+ accountAddress,
76
+ rawPublicKey,
77
+ publicKeyHex,
78
+ clientKeyShares
79
+ };
80
+ } catch (error) {
81
+ this.logger.error(ERROR_CREATE_WALLET_ACCOUNT, error);
82
+ throw new Error(ERROR_CREATE_WALLET_ACCOUNT);
83
+ }
84
+ }
85
+ async signMessage({ message, accountAddress }) {
86
+ try {
87
+ if (!accountAddress) {
88
+ throw new Error(ERROR_ACCOUNT_ADDRESS_REQUIRED);
89
+ }
90
+ // Format the message for EVM signing
91
+ const formattedMessage = formatEVMMessage(message);
92
+ // Sign the message using MPC
93
+ const signatureEcdsa = await this.sign({
94
+ message: formattedMessage,
95
+ accountAddress: accountAddress,
96
+ chainName: this.chainName
97
+ });
98
+ // Serialize the signature
99
+ const serializedSignature = serializeECDSASignature(signatureEcdsa);
100
+ return serializedSignature;
101
+ } catch (error) {
102
+ this.logger.error(ERROR_SIGN_MESSAGE, error);
103
+ throw new Error(ERROR_SIGN_MESSAGE);
104
+ }
105
+ }
106
+ async verifyMessageSignature({ accountAddress, message, signature }) {
107
+ try {
108
+ // Verify the signature using the public client
109
+ const publicClient = this.createViemPublicClient({
110
+ chain: mainnet
111
+ });
112
+ const verified = await publicClient.verifyMessage({
113
+ address: accountAddress,
114
+ message,
115
+ signature: signature
116
+ });
117
+ return verified;
118
+ } catch (error) {
119
+ this.logger.error(ERROR_VERIFY_MESSAGE_SIGNATURE, error);
120
+ throw new Error(ERROR_VERIFY_MESSAGE_SIGNATURE);
121
+ }
122
+ }
123
+ async signTransaction({ chain, senderAddress, toAddress, value, gas, maxFeePerGas, maxPriorityFeePerGas, rpcUrl, broadcastTxn = false }) {
124
+ const publicClient = this.createViemPublicClient({
125
+ chain,
126
+ rpcUrl
127
+ });
128
+ // Get the balance of the sender address
129
+ const balance = await publicClient.getBalance({
130
+ address: senderAddress
131
+ });
132
+ // Calculate total cost (gas * maxFeePerGas + value)
133
+ const totalCost = gas * maxFeePerGas + value;
134
+ if (balance < totalCost) {
135
+ throw new Error(`Insufficient funds. Required: ${totalCost}, Available: ${balance}`);
136
+ }
137
+ const walletClient = createWalletClient({
138
+ chain,
139
+ transport: http(rpcUrl),
140
+ account: senderAddress
141
+ });
142
+ const nonce = await publicClient.getTransactionCount({
143
+ address: senderAddress
144
+ });
145
+ const transactionRequest = {
146
+ to: toAddress,
147
+ value,
148
+ chainId: chain.id,
149
+ type: 'eip1559',
150
+ gas,
151
+ maxFeePerGas,
152
+ maxPriorityFeePerGas,
153
+ nonce,
154
+ from: senderAddress,
155
+ accessList: []
156
+ };
157
+ const preparedTx = await walletClient.prepareTransactionRequest(transactionRequest);
158
+ // Get the transaction hash that needs to be signed
159
+ const unsignedTx = _extends({}, preparedTx, {
160
+ type: 'eip1559'
161
+ });
162
+ // Get the keccak256 hash of the transaction
163
+ const serializedTx = serializeTransaction(unsignedTx);
164
+ const serializedTxBytes = Uint8Array.from(Buffer.from(serializedTx.slice(2), 'hex'));
165
+ if (!(serializedTxBytes instanceof Uint8Array)) {
166
+ throw new Error('Invalid serializedTxBytes');
167
+ }
168
+ // Get signature using MPC (this will coordinate with server party)
169
+ const signatureEcdsa = await this.sign({
170
+ message: serializedTxBytes,
171
+ accountAddress: senderAddress,
172
+ chainName: this.chainName
173
+ });
174
+ if (!('r' in signatureEcdsa && 's' in signatureEcdsa && 'v' in signatureEcdsa)) {
175
+ throw new Error('Invalid signature format returned from MPC signing');
176
+ }
177
+ try {
178
+ const r = `0x${Buffer.from(signatureEcdsa.r).toString('hex')}`;
179
+ const s = `0x${Buffer.from(signatureEcdsa.s).toString('hex')}`;
180
+ const v = BigInt(signatureEcdsa.v);
181
+ const signedTx = {
182
+ to: unsignedTx.to,
183
+ value: unsignedTx.value,
184
+ chainId: chain.id,
185
+ type: 'eip1559',
186
+ gas: unsignedTx.gas,
187
+ maxFeePerGas: unsignedTx.maxFeePerGas,
188
+ maxPriorityFeePerGas: unsignedTx.maxPriorityFeePerGas,
189
+ nonce: unsignedTx.nonce,
190
+ r: r,
191
+ s: s,
192
+ v: v
193
+ };
194
+ // Serialize the signed transaction
195
+ const serializedSignedTx = serializeTransaction(signedTx);
196
+ let txHash;
197
+ // Send the raw transaction
198
+ if (broadcastTxn) {
199
+ const sentTxHash = await walletClient.sendRawTransaction({
200
+ serializedTransaction: serializedSignedTx
201
+ });
202
+ this.logger.info('Transaction broadcasted! Hash:', sentTxHash);
203
+ txHash = sentTxHash;
204
+ }
205
+ return {
206
+ txHash,
207
+ signedTx: serializedSignedTx
208
+ };
209
+ } catch (error) {
210
+ this.logger.error('Error signing transaction:', error);
211
+ throw error;
212
+ }
213
+ }
214
+ async deriveAccountAddress({ rawPublicKey }) {
215
+ const serializedUncompressed = rawPublicKey.serializeUncompressed();
216
+ const firstByteRemoved = serializedUncompressed.slice(1);
217
+ const hashed = MessageHash.keccak256(firstByteRemoved).bytes;
218
+ const lastTwentyBytes = hashed.slice(-20);
219
+ const accountAddress = '0x' + Buffer.from(lastTwentyBytes).toString('hex');
220
+ const publicKeyHex = rawPublicKey.pubKeyAsHex();
221
+ return {
222
+ accountAddress,
223
+ publicKeyHex
224
+ };
225
+ }
226
+ async exportPrivateKey({ accountAddress }) {
227
+ const { derivedPrivateKey } = await this.exportKey({
228
+ accountAddress,
229
+ chainName: this.chainName
230
+ });
231
+ return {
232
+ derivedPrivateKey
233
+ };
234
+ }
235
+ async offlineExportPrivateKey({ keyShares }) {
236
+ const { derivedPrivateKey } = await this.offlineExportKey({
237
+ chainName: this.chainName,
238
+ keyShares
239
+ });
240
+ return {
241
+ derivedPrivateKey
242
+ };
243
+ }
244
+ async importPrivateKey({ privateKey, chainName, thresholdSignatureScheme }) {
245
+ // TODO: validate private key for EVM
246
+ const { rawPublicKey, clientKeyShares } = await this.importRawPrivateKey({
247
+ chainName,
248
+ privateKey,
249
+ thresholdSignatureScheme
250
+ });
251
+ if (!rawPublicKey || !clientKeyShares) {
252
+ throw new Error('Error creating wallet account');
253
+ }
254
+ const { accountAddress, publicKeyHex } = await this.deriveAccountAddress({
255
+ rawPublicKey: rawPublicKey
256
+ });
257
+ const refreshedUser = await this.apiClient.refreshUser();
258
+ const newWallet = refreshedUser.user.verifiedCredentials.find((wallet)=>wallet.address.toLowerCase() === accountAddress.toLowerCase());
259
+ const newWalletId = newWallet.id;
260
+ this.walletMap[accountAddress] = {
261
+ accountAddress,
262
+ walletId: newWalletId,
263
+ chainName: this.chainName,
264
+ clientKeyShares,
265
+ thresholdSignatureScheme
266
+ };
267
+ await this.storeEncryptedBackupByWallet({
268
+ accountAddress
269
+ });
270
+ return {
271
+ accountAddress,
272
+ rawPublicKey,
273
+ publicKeyHex,
274
+ clientKeyShares
275
+ };
276
+ }
277
+ async getEvmWallets() {
278
+ const wallets = await this.getWallets();
279
+ const evmWallets = wallets.filter((wallet)=>wallet.chainName === 'eip155');
280
+ return evmWallets;
281
+ }
282
+ constructor({ environmentId, authToken, baseApiUrl, baseMPCRelayApiUrl, storageKey, debug }){
283
+ super({
284
+ environmentId,
285
+ authToken,
286
+ baseApiUrl,
287
+ baseMPCRelayApiUrl,
288
+ storageKey,
289
+ debug
290
+ }), this.chainName = 'EVM';
291
+ }
292
+ }
293
+
294
+ export { DynamicEvmWalletClient };
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@dynamic-labs-wallet/evm",
3
+ "version": "0.0.28",
4
+ "dependencies": {
5
+ "@dynamic-labs-wallet/browser": "0.0.28"
6
+ },
7
+ "peerDependencies": {
8
+ "viem": "^2.22.1"
9
+ },
10
+ "nx": {
11
+ "sourceRoot": "packages/evm/src",
12
+ "projectType": "library",
13
+ "name": "evm",
14
+ "targets": {
15
+ "build": {}
16
+ }
17
+ },
18
+ "type": "module",
19
+ "main": "./index.cjs.js",
20
+ "module": "./index.esm.js",
21
+ "types": "./index.esm.d.ts",
22
+ "exports": {
23
+ "./package.json": "./package.json",
24
+ ".": {
25
+ "types": "./index.esm.d.ts",
26
+ "import": "./index.esm.js",
27
+ "require": "./index.cjs.js",
28
+ "default": "./index.cjs.js"
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,69 @@
1
+ import { ClientKeyShare, DynamicWalletClient, EcdsaKeygenResult, EcdsaPublicKey, Ed25519KeygenResult, ThresholdSignatureScheme, DynamicWalletClientProps } from '@dynamic-labs-wallet/browser';
2
+ import { type PublicClient, type Chain, type SignableMessage } from 'viem';
3
+ export declare class DynamicEvmWalletClient extends DynamicWalletClient {
4
+ readonly chainName = "EVM";
5
+ constructor({ environmentId, authToken, baseApiUrl, baseMPCRelayApiUrl, storageKey, debug, }: DynamicWalletClientProps);
6
+ createViemPublicClient({ chain, rpcUrl, }: {
7
+ chain: Chain;
8
+ rpcUrl?: string;
9
+ }): PublicClient;
10
+ createWalletAccount({ thresholdSignatureScheme, }: {
11
+ thresholdSignatureScheme: ThresholdSignatureScheme;
12
+ }): Promise<{
13
+ accountAddress: string;
14
+ publicKeyHex: string;
15
+ rawPublicKey: EcdsaPublicKey | Uint8Array | undefined;
16
+ clientKeyShares: ClientKeyShare[];
17
+ }>;
18
+ signMessage({ message, accountAddress, }: {
19
+ message: string;
20
+ accountAddress: string;
21
+ }): Promise<`0x${string}`>;
22
+ verifyMessageSignature({ accountAddress, message, signature, }: {
23
+ accountAddress: string;
24
+ message: SignableMessage;
25
+ signature: any;
26
+ }): Promise<boolean>;
27
+ signTransaction({ chain, senderAddress, toAddress, value, gas, maxFeePerGas, maxPriorityFeePerGas, rpcUrl, broadcastTxn, }: {
28
+ chain: Chain;
29
+ senderAddress: string;
30
+ toAddress: string;
31
+ value: bigint;
32
+ gas: bigint;
33
+ maxFeePerGas: bigint;
34
+ maxPriorityFeePerGas: bigint;
35
+ rpcUrl?: string;
36
+ broadcastTxn?: boolean;
37
+ }): Promise<{
38
+ txHash?: string;
39
+ signedTx: string;
40
+ }>;
41
+ deriveAccountAddress({ rawPublicKey, }: {
42
+ rawPublicKey: EcdsaPublicKey;
43
+ }): Promise<{
44
+ accountAddress: string;
45
+ publicKeyHex: any;
46
+ }>;
47
+ exportPrivateKey({ accountAddress }: {
48
+ accountAddress: string;
49
+ }): Promise<{
50
+ derivedPrivateKey: string | undefined;
51
+ }>;
52
+ offlineExportPrivateKey({ keyShares, }: {
53
+ keyShares: (EcdsaKeygenResult | Ed25519KeygenResult)[];
54
+ }): Promise<{
55
+ derivedPrivateKey: string | undefined;
56
+ }>;
57
+ importPrivateKey({ privateKey, chainName, thresholdSignatureScheme, }: {
58
+ privateKey: string;
59
+ chainName: string;
60
+ thresholdSignatureScheme: ThresholdSignatureScheme;
61
+ }): Promise<{
62
+ accountAddress: string;
63
+ publicKeyHex: string;
64
+ rawPublicKey: EcdsaPublicKey | Uint8Array | undefined;
65
+ clientKeyShares: ClientKeyShare[];
66
+ }>;
67
+ getEvmWallets(): Promise<any>;
68
+ }
69
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EAEd,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EAEzB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,KAAK,EAEV,KAAK,eAAe,EACrB,MAAM,MAAM,CAAC;AAWd,qBAAa,sBAAuB,SAAQ,mBAAmB;IAC7D,QAAQ,CAAC,SAAS,SAAS;gBAEf,EACV,aAAa,EACb,SAAS,EACT,UAAU,EACV,kBAAkB,EAClB,UAAU,EACV,KAAK,GACN,EAAE,wBAAwB;IAW3B,sBAAsB,CAAC,EACrB,KAAK,EACL,MAAM,GACP,EAAE;QACD,KAAK,EAAE,KAAK,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,YAAY;IAOV,mBAAmB,CAAC,EACxB,wBAAwB,GACzB,EAAE;QACD,wBAAwB,EAAE,wBAAwB,CAAC;KACpD,GAAG,OAAO,CAAC;QACV,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,cAAc,GAAG,UAAU,GAAG,SAAS,CAAC;QACtD,eAAe,EAAE,cAAc,EAAE,CAAC;KACnC,CAAC;IAqDI,WAAW,CAAC,EAChB,OAAO,EACP,cAAc,GACf,EAAE;QACD,OAAO,EAAE,MAAM,CAAC;QAChB,cAAc,EAAE,MAAM,CAAC;KACxB;IA0BK,sBAAsB,CAAC,EAC3B,cAAc,EACd,OAAO,EACP,SAAS,GACV,EAAE;QACD,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,eAAe,CAAC;QACzB,SAAS,EAAE,GAAG,CAAC;KAChB;IAmBK,eAAe,CAAC,EACpB,KAAK,EACL,aAAa,EACb,SAAS,EACT,KAAK,EACL,GAAG,EACH,YAAY,EACZ,oBAAoB,EACpB,MAAM,EACN,YAAoB,GACrB,EAAE;QACD,KAAK,EAAE,KAAK,CAAC;QACb,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,YAAY,EAAE,MAAM,CAAC;QACrB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,GAAG,OAAO,CAAC;QACV,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IAoHI,oBAAoB,CAAC,EACzB,YAAY,GACb,EAAE;QACD,YAAY,EAAE,cAAc,CAAC;KAC9B;;;;IAUK,gBAAgB,CAAC,EAAE,cAAc,EAAE,EAAE;QAAE,cAAc,EAAE,MAAM,CAAA;KAAE;;;IAQ/D,uBAAuB,CAAC,EAC5B,SAAS,GACV,EAAE;QACD,SAAS,EAAE,CAAC,iBAAiB,GAAG,mBAAmB,CAAC,EAAE,CAAC;KACxD;;;IAQK,gBAAgB,CAAC,EACrB,UAAU,EACV,SAAS,EACT,wBAAwB,GACzB,EAAE;QACD,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,wBAAwB,EAAE,wBAAwB,CAAC;KACpD,GAAG,OAAO,CAAC;QACV,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,cAAc,GAAG,UAAU,GAAG,SAAS,CAAC;QACtD,eAAe,EAAE,cAAc,EAAE,CAAC;KACnC,CAAC;IAyCI,aAAa;CAOpB"}
@@ -0,0 +1,7 @@
1
+ export declare const EVM_SIGN_MESSAGE_PREFIX = "\u0019Ethereum Signed Message:\n";
2
+ export declare const ERROR_KEYGEN_FAILED = "Error with keygen";
3
+ export declare const ERROR_CREATE_WALLET_ACCOUNT = "Error creating evm wallet account";
4
+ export declare const ERROR_SIGN_MESSAGE = "Error signing message";
5
+ export declare const ERROR_ACCOUNT_ADDRESS_REQUIRED = "Account address is required";
6
+ export declare const ERROR_VERIFY_MESSAGE_SIGNATURE = "Error verifying message signature";
7
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/client/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB,qCAAmC,CAAC;AAGxE,eAAO,MAAM,mBAAmB,sBAAsB,CAAC;AAEvD,eAAO,MAAM,2BAA2B,sCAAsC,CAAC;AAE/E,eAAO,MAAM,kBAAkB,0BAA0B,CAAC;AAE1D,eAAO,MAAM,8BAA8B,gCAAgC,CAAC;AAE5E,eAAO,MAAM,8BAA8B,sCAAsC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './client';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC"}
package/src/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './client';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC"}
package/src/utils.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { EcdsaSignature } from '@dynamic-labs-wallet/browser';
2
+ export declare const formatEVMMessage: (message: string) => string;
3
+ export declare const serializeECDSASignature: (signature: EcdsaSignature) => `0x${string}`;
4
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../packages/src/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,eAAO,MAAM,gBAAgB,YAAa,MAAM,WAE/C,CAAC;AAEF,eAAO,MAAM,uBAAuB,cAAe,cAAc,kBAMhE,CAAC"}