@dynamic-labs-wallet/node-evm 0.0.321 → 0.0.323

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 (3) hide show
  1. package/index.cjs.js +90 -33
  2. package/index.esm.js +90 -35
  3. package/package.json +2 -2
package/index.cjs.js CHANGED
@@ -33,6 +33,7 @@ const ERROR_SIGN_MESSAGE = 'Error signing message';
33
33
  const ERROR_SIGN_TYPED_DATA = 'Error signing typed data';
34
34
  const ERROR_ACCOUNT_ADDRESS_REQUIRED = 'Account address is required';
35
35
  const ERROR_VERIFY_MESSAGE_SIGNATURE = 'Error verifying message signature';
36
+ const ERROR_SIGN_RAW_MESSAGE = 'Error signing raw message';
36
37
 
37
38
  const formatEVMMessage = (message_)=>{
38
39
  const message = (()=>{
@@ -227,6 +228,37 @@ const logError$1 = node.createLogError('node-evm');
227
228
  throw error;
228
229
  }
229
230
  };
231
+ /**
232
+ * Signs a pre-formatted (raw) message using delegated signing for EVM.
233
+ * The message must be a hex string representing already-hashed data.
234
+ */ const delegatedSignRawMessage = async (client, { walletId, walletApiKey, keyShare, message, context, onError })=>{
235
+ try {
236
+ if (!keyShare || !walletId || !walletApiKey) {
237
+ throw new Error('Delegated key share, wallet ID, and wallet API key are required to sign a raw message');
238
+ }
239
+ const prehashed = node.stripHexPrefix(message);
240
+ const signatureEcdsa = await node.delegatedSignMessage(client, {
241
+ walletId,
242
+ walletApiKey,
243
+ keyShare,
244
+ message: prehashed,
245
+ chainName: client.chainName,
246
+ isFormatted: true,
247
+ context,
248
+ onError
249
+ });
250
+ return serializeECDSASignature(signatureEcdsa);
251
+ } catch (error) {
252
+ logError$1({
253
+ message: 'Error in delegatedSignRawMessage',
254
+ error: error,
255
+ context: {
256
+ walletId
257
+ }
258
+ });
259
+ throw error;
260
+ }
261
+ };
230
262
  /**
231
263
  * Revoke delegation - delegates to the node package
232
264
  */ const revokeDelegation = async (client, params)=>{
@@ -328,6 +360,7 @@ const createAccountAdapter = ({ evmClient, accountAddress, password, externalSer
328
360
  };
329
361
 
330
362
  const logError = node.createLogError('node-evm');
363
+ const keySharesRequiredFor = (action)=>`External server key shares are required to ${action}. No backup shares available for recovery.`;
331
364
  class DynamicEvmWalletClient extends node.DynamicWalletClient {
332
365
  get jwtAuthToken() {
333
366
  return this.baseJWTAuthToken;
@@ -473,7 +506,7 @@ class DynamicEvmWalletClient extends node.DynamicWalletClient {
473
506
  password,
474
507
  walletOperation: node.WalletOperation.SIGN_MESSAGE,
475
508
  externalServerKeyShares,
476
- errorMessage: 'External server key shares are required to sign a message. No backup shares available for recovery.'
509
+ errorMessage: keySharesRequiredFor('sign a message')
477
510
  });
478
511
  const signatureEcdsa = await this.sign({
479
512
  message: formattedMessage,
@@ -501,6 +534,26 @@ class DynamicEvmWalletClient extends node.DynamicWalletClient {
501
534
  isSignAuthorizationSupported() {
502
535
  return true;
503
536
  }
537
+ async signPrehashedMessage({ prehashed, accountAddress, password, externalServerKeyShares, context, onError, recoverErrorMessage }) {
538
+ await this.ensureKeySharesRecovered({
539
+ accountAddress,
540
+ password,
541
+ walletOperation: node.WalletOperation.SIGN_MESSAGE,
542
+ externalServerKeyShares,
543
+ errorMessage: recoverErrorMessage
544
+ });
545
+ const signatureEcdsa = await this.sign({
546
+ message: prehashed,
547
+ accountAddress: accountAddress,
548
+ chainName: this.chainName,
549
+ password,
550
+ externalServerKeyShares,
551
+ isFormatted: true,
552
+ context,
553
+ onError
554
+ });
555
+ return serializeECDSASignature(signatureEcdsa);
556
+ }
504
557
  async signAuthorization({ authorization, accountAddress, password = undefined, externalServerKeyShares, onError }) {
505
558
  try {
506
559
  if (!accountAddress) {
@@ -508,29 +561,18 @@ class DynamicEvmWalletClient extends node.DynamicWalletClient {
508
561
  }
509
562
  const digest = utils.hashAuthorization(authorization);
510
563
  const prehashed = digest.startsWith('0x') ? digest.slice(2) : digest;
511
- // Attempt to recover key shares from backup if not provided
512
- await this.ensureKeySharesRecovered({
564
+ const serializedSignature = await this.signPrehashedMessage({
565
+ prehashed,
513
566
  accountAddress,
514
567
  password,
515
- walletOperation: node.WalletOperation.SIGN_MESSAGE,
516
- externalServerKeyShares,
517
- errorMessage: 'External server key shares are required to sign authorization. No backup shares available for recovery.'
518
- });
519
- const signatureEcdsa = await this.sign({
520
- message: prehashed,
521
- accountAddress: accountAddress,
522
- chainName: this.chainName,
523
- password,
524
568
  externalServerKeyShares,
525
- isFormatted: true,
526
569
  context: {
527
570
  eip7702Auth: authorization
528
571
  },
529
- onError
572
+ onError,
573
+ recoverErrorMessage: keySharesRequiredFor('sign authorization')
530
574
  });
531
- const serializedSignature = serializeECDSASignature(signatureEcdsa);
532
- const signature = viem.parseSignature(serializedSignature);
533
- return signature;
575
+ return viem.parseSignature(serializedSignature);
534
576
  } catch (error) {
535
577
  logError({
536
578
  message: ERROR_SIGN_MESSAGE,
@@ -542,34 +584,47 @@ class DynamicEvmWalletClient extends node.DynamicWalletClient {
542
584
  throw new Error(ERROR_SIGN_MESSAGE);
543
585
  }
544
586
  }
545
- async signTypedData({ accountAddress, typedData, password = undefined, externalServerKeyShares, onError }) {
587
+ async signRawMessage({ message, accountAddress, password = undefined, externalServerKeyShares, context, onError }) {
546
588
  try {
547
589
  if (!accountAddress) {
548
590
  throw new Error(ERROR_ACCOUNT_ADDRESS_REQUIRED);
549
591
  }
550
- const formattedTypedData = formatTypedData(typedData);
551
- // Attempt to recover key shares from backup if not provided
552
- await this.ensureKeySharesRecovered({
592
+ return await this.signPrehashedMessage({
593
+ prehashed: node.stripHexPrefix(message),
553
594
  accountAddress,
554
595
  password,
555
- walletOperation: node.WalletOperation.SIGN_MESSAGE,
556
596
  externalServerKeyShares,
557
- errorMessage: 'External server key shares are required to sign typed data. No backup shares available for recovery.'
597
+ context,
598
+ onError,
599
+ recoverErrorMessage: keySharesRequiredFor('sign a raw message')
558
600
  });
559
- const signatureEcdsa = await this.sign({
560
- message: formattedTypedData,
561
- accountAddress: accountAddress,
562
- chainName: this.chainName,
601
+ } catch (error) {
602
+ logError({
603
+ message: ERROR_SIGN_RAW_MESSAGE,
604
+ error: error,
605
+ context: {
606
+ accountAddress
607
+ }
608
+ });
609
+ throw new Error(ERROR_SIGN_RAW_MESSAGE);
610
+ }
611
+ }
612
+ async signTypedData({ accountAddress, typedData, password = undefined, externalServerKeyShares, onError }) {
613
+ try {
614
+ if (!accountAddress) {
615
+ throw new Error(ERROR_ACCOUNT_ADDRESS_REQUIRED);
616
+ }
617
+ return await this.signPrehashedMessage({
618
+ prehashed: formatTypedData(typedData),
619
+ accountAddress,
563
620
  password,
564
621
  externalServerKeyShares,
565
- isFormatted: true,
566
622
  context: {
567
623
  evmTypedData: typedData
568
624
  },
569
- onError
625
+ onError,
626
+ recoverErrorMessage: keySharesRequiredFor('sign typed data')
570
627
  });
571
- const serializedSignature = serializeECDSASignature(signatureEcdsa);
572
- return serializedSignature;
573
628
  } catch (error) {
574
629
  logError({
575
630
  message: ERROR_SIGN_TYPED_DATA,
@@ -615,7 +670,7 @@ class DynamicEvmWalletClient extends node.DynamicWalletClient {
615
670
  password,
616
671
  walletOperation: node.WalletOperation.SIGN_TRANSACTION,
617
672
  externalServerKeyShares,
618
- errorMessage: 'External server key shares are required to sign transaction. No backup shares available for recovery.'
673
+ errorMessage: keySharesRequiredFor('sign transaction')
619
674
  });
620
675
  const serializedTx = viem.serializeTransaction(transaction);
621
676
  const serializedTxBytes = Uint8Array.from(Buffer.from(serializedTx.slice(2), 'hex'));
@@ -665,7 +720,7 @@ class DynamicEvmWalletClient extends node.DynamicWalletClient {
665
720
  password,
666
721
  walletOperation: node.WalletOperation.EXPORT_PRIVATE_KEY,
667
722
  externalServerKeyShares,
668
- errorMessage: 'External server key shares are required to export private key. No backup shares available for recovery.'
723
+ errorMessage: keySharesRequiredFor('export private key')
669
724
  });
670
725
  const { derivedPrivateKey } = await this.exportKey({
671
726
  accountAddress,
@@ -959,6 +1014,7 @@ exports.ERROR_ACCOUNT_ADDRESS_REQUIRED = ERROR_ACCOUNT_ADDRESS_REQUIRED;
959
1014
  exports.ERROR_CREATE_WALLET_ACCOUNT = ERROR_CREATE_WALLET_ACCOUNT;
960
1015
  exports.ERROR_KEYGEN_FAILED = ERROR_KEYGEN_FAILED;
961
1016
  exports.ERROR_SIGN_MESSAGE = ERROR_SIGN_MESSAGE;
1017
+ exports.ERROR_SIGN_RAW_MESSAGE = ERROR_SIGN_RAW_MESSAGE;
962
1018
  exports.ERROR_SIGN_TYPED_DATA = ERROR_SIGN_TYPED_DATA;
963
1019
  exports.ERROR_VERIFY_MESSAGE_SIGNATURE = ERROR_VERIFY_MESSAGE_SIGNATURE;
964
1020
  exports.EVM_SIGN_MESSAGE_PREFIX = EVM_SIGN_MESSAGE_PREFIX;
@@ -967,6 +1023,7 @@ exports.createDelegatedEvmWalletClient = createDelegatedEvmWalletClient;
967
1023
  exports.createZerodevClient = createZerodevClient;
968
1024
  exports.delegatedSignAuthorization = delegatedSignAuthorization;
969
1025
  exports.delegatedSignMessage = delegatedSignMessage;
1026
+ exports.delegatedSignRawMessage = delegatedSignRawMessage;
970
1027
  exports.delegatedSignTransaction = delegatedSignTransaction;
971
1028
  exports.delegatedSignTypedData = delegatedSignTypedData;
972
1029
  exports.deriveAccountAddress = deriveAccountAddress;
package/index.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { toAccount } from 'viem/accounts';
2
- import { MessageHash, createLogError, createDelegatedWalletClient, delegatedSignMessage as delegatedSignMessage$1, revokeDelegation as revokeDelegation$1, DynamicWalletClient, getMPCChainConfig, getExternalServerKeyShareBackupInfo, WalletOperation } from '@dynamic-labs-wallet/node';
2
+ import { MessageHash, createLogError, createDelegatedWalletClient, delegatedSignMessage as delegatedSignMessage$1, stripHexPrefix, revokeDelegation as revokeDelegation$1, DynamicWalletClient, getMPCChainConfig, getExternalServerKeyShareBackupInfo, WalletOperation } from '@dynamic-labs-wallet/node';
3
3
  import { getAddress, stringToHex, bytesToHex, size, concat, hashTypedData, serializeSignature, parseSignature, serializeTransaction, createPublicClient, http, defineChain, createWalletClient } from 'viem';
4
4
  import { hashAuthorization } from 'viem/utils';
5
5
  import { mainnet } from 'viem/chains';
@@ -31,6 +31,7 @@ const ERROR_SIGN_MESSAGE = 'Error signing message';
31
31
  const ERROR_SIGN_TYPED_DATA = 'Error signing typed data';
32
32
  const ERROR_ACCOUNT_ADDRESS_REQUIRED = 'Account address is required';
33
33
  const ERROR_VERIFY_MESSAGE_SIGNATURE = 'Error verifying message signature';
34
+ const ERROR_SIGN_RAW_MESSAGE = 'Error signing raw message';
34
35
 
35
36
  const formatEVMMessage = (message_)=>{
36
37
  const message = (()=>{
@@ -225,6 +226,37 @@ const logError$1 = createLogError('node-evm');
225
226
  throw error;
226
227
  }
227
228
  };
229
+ /**
230
+ * Signs a pre-formatted (raw) message using delegated signing for EVM.
231
+ * The message must be a hex string representing already-hashed data.
232
+ */ const delegatedSignRawMessage = async (client, { walletId, walletApiKey, keyShare, message, context, onError })=>{
233
+ try {
234
+ if (!keyShare || !walletId || !walletApiKey) {
235
+ throw new Error('Delegated key share, wallet ID, and wallet API key are required to sign a raw message');
236
+ }
237
+ const prehashed = stripHexPrefix(message);
238
+ const signatureEcdsa = await delegatedSignMessage$1(client, {
239
+ walletId,
240
+ walletApiKey,
241
+ keyShare,
242
+ message: prehashed,
243
+ chainName: client.chainName,
244
+ isFormatted: true,
245
+ context,
246
+ onError
247
+ });
248
+ return serializeECDSASignature(signatureEcdsa);
249
+ } catch (error) {
250
+ logError$1({
251
+ message: 'Error in delegatedSignRawMessage',
252
+ error: error,
253
+ context: {
254
+ walletId
255
+ }
256
+ });
257
+ throw error;
258
+ }
259
+ };
228
260
  /**
229
261
  * Revoke delegation - delegates to the node package
230
262
  */ const revokeDelegation = async (client, params)=>{
@@ -326,6 +358,7 @@ const createAccountAdapter = ({ evmClient, accountAddress, password, externalSer
326
358
  };
327
359
 
328
360
  const logError = createLogError('node-evm');
361
+ const keySharesRequiredFor = (action)=>`External server key shares are required to ${action}. No backup shares available for recovery.`;
329
362
  class DynamicEvmWalletClient extends DynamicWalletClient {
330
363
  get jwtAuthToken() {
331
364
  return this.baseJWTAuthToken;
@@ -471,7 +504,7 @@ class DynamicEvmWalletClient extends DynamicWalletClient {
471
504
  password,
472
505
  walletOperation: WalletOperation.SIGN_MESSAGE,
473
506
  externalServerKeyShares,
474
- errorMessage: 'External server key shares are required to sign a message. No backup shares available for recovery.'
507
+ errorMessage: keySharesRequiredFor('sign a message')
475
508
  });
476
509
  const signatureEcdsa = await this.sign({
477
510
  message: formattedMessage,
@@ -499,6 +532,26 @@ class DynamicEvmWalletClient extends DynamicWalletClient {
499
532
  isSignAuthorizationSupported() {
500
533
  return true;
501
534
  }
535
+ async signPrehashedMessage({ prehashed, accountAddress, password, externalServerKeyShares, context, onError, recoverErrorMessage }) {
536
+ await this.ensureKeySharesRecovered({
537
+ accountAddress,
538
+ password,
539
+ walletOperation: WalletOperation.SIGN_MESSAGE,
540
+ externalServerKeyShares,
541
+ errorMessage: recoverErrorMessage
542
+ });
543
+ const signatureEcdsa = await this.sign({
544
+ message: prehashed,
545
+ accountAddress: accountAddress,
546
+ chainName: this.chainName,
547
+ password,
548
+ externalServerKeyShares,
549
+ isFormatted: true,
550
+ context,
551
+ onError
552
+ });
553
+ return serializeECDSASignature(signatureEcdsa);
554
+ }
502
555
  async signAuthorization({ authorization, accountAddress, password = undefined, externalServerKeyShares, onError }) {
503
556
  try {
504
557
  if (!accountAddress) {
@@ -506,29 +559,18 @@ class DynamicEvmWalletClient extends DynamicWalletClient {
506
559
  }
507
560
  const digest = hashAuthorization(authorization);
508
561
  const prehashed = digest.startsWith('0x') ? digest.slice(2) : digest;
509
- // Attempt to recover key shares from backup if not provided
510
- await this.ensureKeySharesRecovered({
562
+ const serializedSignature = await this.signPrehashedMessage({
563
+ prehashed,
511
564
  accountAddress,
512
565
  password,
513
- walletOperation: WalletOperation.SIGN_MESSAGE,
514
- externalServerKeyShares,
515
- errorMessage: 'External server key shares are required to sign authorization. No backup shares available for recovery.'
516
- });
517
- const signatureEcdsa = await this.sign({
518
- message: prehashed,
519
- accountAddress: accountAddress,
520
- chainName: this.chainName,
521
- password,
522
566
  externalServerKeyShares,
523
- isFormatted: true,
524
567
  context: {
525
568
  eip7702Auth: authorization
526
569
  },
527
- onError
570
+ onError,
571
+ recoverErrorMessage: keySharesRequiredFor('sign authorization')
528
572
  });
529
- const serializedSignature = serializeECDSASignature(signatureEcdsa);
530
- const signature = parseSignature(serializedSignature);
531
- return signature;
573
+ return parseSignature(serializedSignature);
532
574
  } catch (error) {
533
575
  logError({
534
576
  message: ERROR_SIGN_MESSAGE,
@@ -540,34 +582,47 @@ class DynamicEvmWalletClient extends DynamicWalletClient {
540
582
  throw new Error(ERROR_SIGN_MESSAGE);
541
583
  }
542
584
  }
543
- async signTypedData({ accountAddress, typedData, password = undefined, externalServerKeyShares, onError }) {
585
+ async signRawMessage({ message, accountAddress, password = undefined, externalServerKeyShares, context, onError }) {
544
586
  try {
545
587
  if (!accountAddress) {
546
588
  throw new Error(ERROR_ACCOUNT_ADDRESS_REQUIRED);
547
589
  }
548
- const formattedTypedData = formatTypedData(typedData);
549
- // Attempt to recover key shares from backup if not provided
550
- await this.ensureKeySharesRecovered({
590
+ return await this.signPrehashedMessage({
591
+ prehashed: stripHexPrefix(message),
551
592
  accountAddress,
552
593
  password,
553
- walletOperation: WalletOperation.SIGN_MESSAGE,
554
594
  externalServerKeyShares,
555
- errorMessage: 'External server key shares are required to sign typed data. No backup shares available for recovery.'
595
+ context,
596
+ onError,
597
+ recoverErrorMessage: keySharesRequiredFor('sign a raw message')
556
598
  });
557
- const signatureEcdsa = await this.sign({
558
- message: formattedTypedData,
559
- accountAddress: accountAddress,
560
- chainName: this.chainName,
599
+ } catch (error) {
600
+ logError({
601
+ message: ERROR_SIGN_RAW_MESSAGE,
602
+ error: error,
603
+ context: {
604
+ accountAddress
605
+ }
606
+ });
607
+ throw new Error(ERROR_SIGN_RAW_MESSAGE);
608
+ }
609
+ }
610
+ async signTypedData({ accountAddress, typedData, password = undefined, externalServerKeyShares, onError }) {
611
+ try {
612
+ if (!accountAddress) {
613
+ throw new Error(ERROR_ACCOUNT_ADDRESS_REQUIRED);
614
+ }
615
+ return await this.signPrehashedMessage({
616
+ prehashed: formatTypedData(typedData),
617
+ accountAddress,
561
618
  password,
562
619
  externalServerKeyShares,
563
- isFormatted: true,
564
620
  context: {
565
621
  evmTypedData: typedData
566
622
  },
567
- onError
623
+ onError,
624
+ recoverErrorMessage: keySharesRequiredFor('sign typed data')
568
625
  });
569
- const serializedSignature = serializeECDSASignature(signatureEcdsa);
570
- return serializedSignature;
571
626
  } catch (error) {
572
627
  logError({
573
628
  message: ERROR_SIGN_TYPED_DATA,
@@ -613,7 +668,7 @@ class DynamicEvmWalletClient extends DynamicWalletClient {
613
668
  password,
614
669
  walletOperation: WalletOperation.SIGN_TRANSACTION,
615
670
  externalServerKeyShares,
616
- errorMessage: 'External server key shares are required to sign transaction. No backup shares available for recovery.'
671
+ errorMessage: keySharesRequiredFor('sign transaction')
617
672
  });
618
673
  const serializedTx = serializeTransaction(transaction);
619
674
  const serializedTxBytes = Uint8Array.from(Buffer.from(serializedTx.slice(2), 'hex'));
@@ -663,7 +718,7 @@ class DynamicEvmWalletClient extends DynamicWalletClient {
663
718
  password,
664
719
  walletOperation: WalletOperation.EXPORT_PRIVATE_KEY,
665
720
  externalServerKeyShares,
666
- errorMessage: 'External server key shares are required to export private key. No backup shares available for recovery.'
721
+ errorMessage: keySharesRequiredFor('export private key')
667
722
  });
668
723
  const { derivedPrivateKey } = await this.exportKey({
669
724
  accountAddress,
@@ -952,4 +1007,4 @@ const createZerodevClient = async (evmClient)=>{
952
1007
  return client;
953
1008
  };
954
1009
 
955
- export { DynamicEvmWalletClient, ERROR_ACCOUNT_ADDRESS_REQUIRED, ERROR_CREATE_WALLET_ACCOUNT, ERROR_KEYGEN_FAILED, ERROR_SIGN_MESSAGE, ERROR_SIGN_TYPED_DATA, ERROR_VERIFY_MESSAGE_SIGNATURE, EVM_SIGN_MESSAGE_PREFIX, createAccountAdapter, createDelegatedEvmWalletClient, createZerodevClient, delegatedSignAuthorization, delegatedSignMessage, delegatedSignTransaction, delegatedSignTypedData, deriveAccountAddress, formatEVMMessage, formatTypedData, revokeDelegation, serializeECDSASignature };
1010
+ export { DynamicEvmWalletClient, ERROR_ACCOUNT_ADDRESS_REQUIRED, ERROR_CREATE_WALLET_ACCOUNT, ERROR_KEYGEN_FAILED, ERROR_SIGN_MESSAGE, ERROR_SIGN_RAW_MESSAGE, ERROR_SIGN_TYPED_DATA, ERROR_VERIFY_MESSAGE_SIGNATURE, EVM_SIGN_MESSAGE_PREFIX, createAccountAdapter, createDelegatedEvmWalletClient, createZerodevClient, delegatedSignAuthorization, delegatedSignMessage, delegatedSignRawMessage, delegatedSignTransaction, delegatedSignTypedData, deriveAccountAddress, formatEVMMessage, formatTypedData, revokeDelegation, serializeECDSASignature };
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@dynamic-labs-wallet/node-evm",
3
- "version": "0.0.321",
3
+ "version": "0.0.323",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "dependencies": {
7
- "@dynamic-labs-wallet/node": "0.0.321",
7
+ "@dynamic-labs-wallet/node": "0.0.323",
8
8
  "@dynamic-labs/sdk-api-core": "^0.0.900",
9
9
  "@dynamic-labs-sdk/client": "0.3.0",
10
10
  "@dynamic-labs-sdk/zerodev": "0.3.0",