@dynamic-labs-wallet/node-svm 0.0.0-pr384.2 → 0.0.0-pr526.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.
package/index.cjs.js CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  var node = require('@dynamic-labs-wallet/node');
4
4
  var web3_js = require('@solana/web3.js');
5
+ var logger$1 = require('@dynamic-labs/logger');
6
+ var axios = require('axios');
7
+ var core = require('@dynamic-labs-wallet/core');
5
8
 
6
9
  function _extends() {
7
10
  _extends = Object.assign || function assign(target) {
@@ -16,45 +19,86 @@ function _extends() {
16
19
 
17
20
  const ERROR_CREATE_WALLET_ACCOUNT = 'Error creating svm wallet account';
18
21
 
19
- async function getBalance({ address, rpcUrl = node.SOLANA_RPC_URL }) {
20
- const connection = new web3_js.Connection(rpcUrl != null ? rpcUrl : 'https://api.devnet.solana.com');
21
- const balance = await connection.getBalance(new web3_js.PublicKey(address));
22
- return balance;
22
+ // Base58 encoding/decoding (Bitcoin alphabet) without external dependencies
23
+ // Implementation adapted from the reference algorithm; suitable for keys/signatures
24
+ const ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
25
+ const ALPHABET_MAP = {};
26
+ for(let i = 0; i < ALPHABET.length; i++)ALPHABET_MAP[ALPHABET[i]] = i;
27
+ function encodeBase58(source) {
28
+ const bytes = source instanceof Uint8Array ? source : new Uint8Array(source);
29
+ if (bytes.length === 0) return '';
30
+ // Count leading zeros
31
+ let zeros = 0;
32
+ while(zeros < bytes.length && bytes[zeros] === 0)zeros++;
33
+ // Allocate enough space in big-endian base58 representation.
34
+ // log(256) / log(58), rounded up.
35
+ const size = (bytes.length - zeros) * 138 / 100 + 1 >>> 0;
36
+ const b58 = new Uint8Array(size);
37
+ let length = 0;
38
+ for(let i = zeros; i < bytes.length; i++){
39
+ let carry = bytes[i];
40
+ let j = 0;
41
+ for(let k = size - 1; (carry !== 0 || j < length) && k >= 0; k--, j++){
42
+ carry += 256 * b58[k] >>> 0;
43
+ b58[k] = carry % 58 >>> 0;
44
+ carry = carry / 58 >>> 0;
45
+ }
46
+ length = j;
47
+ }
48
+ // Skip leading zeros in base58 result
49
+ let it = size - length;
50
+ while(it < size && b58[it] === 0)it++;
51
+ // Translate the result into a string.
52
+ let str = '';
53
+ for(let i = 0; i < zeros; i++)str += '1';
54
+ for(; it < size; it++)str += ALPHABET[b58[it]];
55
+ return str;
23
56
  }
24
- async function createSolanaTransaction({ senderSolanaAddress, amount, to, rpcUrl = 'https://api.devnet.solana.com' }) {
25
- const connection = new web3_js.Connection(rpcUrl != null ? rpcUrl : 'https://api.devnet.solana.com');
26
- const balance = await getBalance({
27
- address: senderSolanaAddress,
28
- rpcUrl
29
- });
30
- if (balance < amount * 1e9) {
31
- throw new Error('Insufficient balance');
57
+ function decodeBase58(str) {
58
+ if (str.length === 0) return new Uint8Array();
59
+ // Count leading zeros
60
+ let zeros = 0;
61
+ while(zeros < str.length && str[zeros] === '1')zeros++;
62
+ // Allocate enough space in big-endian base256 representation.
63
+ // log(58) / log(256), rounded up.
64
+ const size = (str.length - zeros) * 733 / 1000 + 1 >>> 0;
65
+ const b256 = new Uint8Array(size);
66
+ let length = 0;
67
+ for(let i = zeros; i < str.length; i++){
68
+ const value = ALPHABET_MAP[str[i]];
69
+ if (value === undefined) throw new Error('Invalid base58 character');
70
+ let carry = value;
71
+ let j = 0;
72
+ for(let k = size - 1; (carry !== 0 || j < length) && k >= 0; k--, j++){
73
+ carry += 58 * b256[k] >>> 0;
74
+ b256[k] = (carry & 0xff) >>> 0;
75
+ carry = carry >> 8 >>> 0;
76
+ }
77
+ length = j;
32
78
  }
33
- const fromPubkey = new web3_js.PublicKey(senderSolanaAddress);
34
- const transaction = new web3_js.Transaction().add(web3_js.SystemProgram.transfer({
35
- fromPubkey: fromPubkey,
36
- toPubkey: new web3_js.PublicKey(to),
37
- lamports: amount * 1e9
38
- }));
39
- const { blockhash } = await connection.getLatestBlockhash();
40
- transaction.recentBlockhash = blockhash;
41
- transaction.feePayer = fromPubkey;
42
- const serializedTransaction = transaction.serializeMessage();
43
- return {
44
- transaction,
45
- serializedTransaction
46
- };
79
+ // Skip leading zeros in b256
80
+ let it = size - length;
81
+ while(it < size && b256[it] === 0)it++;
82
+ const out = new Uint8Array(zeros + (size - it));
83
+ out.fill(0, 0, zeros);
84
+ let j = zeros;
85
+ while(it < size)out[j++] = b256[it++];
86
+ return out;
47
87
  }
48
- const addSignatureToTransaction = ({ transaction, signature, signerPublicKey })=>{
49
- transaction.addSignature(signerPublicKey, Buffer.from(signature));
50
- return transaction;
88
+
89
+ const logger = new logger$1.Logger('DynamicWaasWalletClient');
90
+ const logError = ({ message, error, context })=>{
91
+ if (error instanceof axios.AxiosError) {
92
+ core.handleAxiosError(error, message, context, logger);
93
+ }
94
+ logger.error('[DynamicWaasWalletClient] Error in node-svm client', {
95
+ error: error instanceof Error ? error.message : String(error),
96
+ context
97
+ });
51
98
  };
52
- async function sendTransaction({ signedTransaction, rpcUrl = 'https://api.devnet.solana.com' }) {
53
- const connection = new web3_js.Connection(rpcUrl != null ? rpcUrl : 'https://api.devnet.solana.com');
54
- const txid = await connection.sendRawTransaction(Buffer.from(signedTransaction));
55
- return txid;
56
- }
57
99
 
100
+ // Helper: normalize bytes to hex without triggering Buffer.from(string, encoding) overload
101
+ const toHex = (bytes)=>(Buffer.isBuffer(bytes) ? bytes : Buffer.from(bytes)).toString('hex');
58
102
  class DynamicSvmWalletClient extends node.DynamicWalletClient {
59
103
  /**
60
104
  * Creates a wallet account on the Solana chain
@@ -73,11 +117,16 @@ class DynamicSvmWalletClient extends node.DynamicWalletClient {
73
117
  onError,
74
118
  onCeremonyComplete: (accountAddress, walletId)=>{
75
119
  // update wallet map
120
+ const chainConfig = node.getMPCChainConfig(this.chainName);
76
121
  this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress] || {}, {
77
122
  accountAddress,
78
123
  walletId,
79
124
  chainName: this.chainName,
80
125
  thresholdSignatureScheme,
126
+ derivationPath: JSON.stringify(Object.fromEntries(chainConfig.derivationPath.map((value, index)=>[
127
+ index,
128
+ value
129
+ ]))),
81
130
  externalServerKeySharesBackupInfo: node.getExternalServerKeyShareBackupInfo()
82
131
  });
83
132
  this.logger.debug('walletMap updated for wallet', {
@@ -111,16 +160,22 @@ class DynamicSvmWalletClient extends node.DynamicWalletClient {
111
160
  externalServerKeyShares
112
161
  };
113
162
  } catch (error) {
114
- this.logger.error('Error in createWalletAccount:', error);
163
+ logError({
164
+ message: ERROR_CREATE_WALLET_ACCOUNT,
165
+ error: error,
166
+ context: {}
167
+ });
115
168
  throw new Error(ERROR_CREATE_WALLET_ACCOUNT);
116
169
  }
117
170
  }
118
171
  // Function to properly derive account address
119
172
  async deriveAccountAddress(rawPublicKey) {
120
- const pubKeyBytes = typeof rawPublicKey === 'string' ? Buffer.from(rawPublicKey, 'hex') : rawPublicKey;
121
- // Create PublicKey from bytes and convert to base58
122
- const pubKey = new web3_js.PublicKey(pubKeyBytes);
123
- const accountAddress = pubKey.toBase58();
173
+ function ensure32(u8) {
174
+ if (u8.length !== 32) throw new Error(`Invalid pubkey length: ${u8.length}`);
175
+ return u8;
176
+ }
177
+ const pubKeyBytes = typeof rawPublicKey === 'string' ? new Uint8Array(Buffer.from(rawPublicKey, 'hex')) : rawPublicKey;
178
+ const accountAddress = new web3_js.PublicKey(ensure32(pubKeyBytes)).toBase58();
124
179
  return {
125
180
  accountAddress
126
181
  };
@@ -132,47 +187,69 @@ class DynamicSvmWalletClient extends node.DynamicWalletClient {
132
187
  * @param accountAddress Solana address (base58 encoded)
133
188
  * @param password The password for encrypted backup shares
134
189
  */ async signMessage({ message, accountAddress, password = undefined, externalServerKeyShares }) {
135
- await this.verifyPassword({
136
- accountAddress,
137
- password,
138
- walletOperation: node.WalletOperation.SIGN_MESSAGE
139
- });
190
+ // Validate inputs early
140
191
  if (!accountAddress) {
141
192
  throw new Error('Account address is required');
142
193
  }
143
194
  try {
195
+ // Attempt to recover key shares from backup if not provided
196
+ await this.ensureKeySharesRecovered({
197
+ accountAddress,
198
+ password,
199
+ walletOperation: node.WalletOperation.SIGN_MESSAGE,
200
+ externalServerKeyShares,
201
+ errorMessage: 'External server key shares are required to sign a message. No backup shares available for recovery.'
202
+ });
203
+ const messageBytes = typeof message === 'string' ? new TextEncoder().encode(message) : message;
204
+ const messageHex = toHex(messageBytes);
144
205
  const signatureEd25519 = await this.sign({
145
- message,
146
- accountAddress: accountAddress,
206
+ message: messageHex,
207
+ accountAddress,
147
208
  chainName: this.chainName,
148
209
  password,
149
210
  externalServerKeyShares
150
211
  });
151
- // Use PublicKey to encode signature
152
- const base58Signature = new web3_js.PublicKey(signatureEd25519).toBase58();
153
- return base58Signature;
212
+ return encodeBase58(signatureEd25519);
154
213
  } catch (error) {
155
- this.logger.error('Error signing message:', error);
214
+ logError({
215
+ message: 'Error signing message:',
216
+ error: error,
217
+ context: {
218
+ accountAddress
219
+ }
220
+ });
156
221
  throw error;
157
222
  }
158
223
  }
159
224
  //todo:should txn just be a string?
160
225
  async signTransaction({ senderAddress, transaction, password = undefined, externalServerKeyShares }) {
226
+ // Validate inputs early
227
+ if (!senderAddress) {
228
+ throw new Error('Sender address is required');
229
+ }
161
230
  await this.verifyPassword({
162
231
  accountAddress: senderAddress,
163
232
  password,
164
233
  walletOperation: node.WalletOperation.SIGN_TRANSACTION
165
234
  });
166
235
  try {
236
+ // Attempt to recover key shares from backup if not provided
237
+ await this.ensureKeySharesRecovered({
238
+ accountAddress: senderAddress,
239
+ password,
240
+ walletOperation: node.WalletOperation.SIGN_TRANSACTION,
241
+ externalServerKeyShares,
242
+ errorMessage: 'External server key shares are required to sign transaction. No backup shares available for recovery.'
243
+ });
167
244
  let messageToSign;
168
- if (transaction instanceof web3_js.VersionedTransaction) {
169
- // For versioned transactions, we need to sign the message directly
245
+ if (typeof transaction === 'string') {
246
+ messageToSign = transaction.startsWith('0x') ? transaction.slice(2) : transaction;
247
+ } else if (transaction instanceof web3_js.VersionedTransaction) {
170
248
  const messageBytes = transaction.message.serialize();
171
- messageToSign = Buffer.from(messageBytes).toString('hex');
249
+ messageToSign = toHex(messageBytes);
172
250
  } else {
173
- // For legacy transactions, serialize the message
174
251
  const messageBytes = transaction.serializeMessage();
175
- messageToSign = Buffer.from(messageBytes).toString('hex');
252
+ messageToSign = toHex(Buffer.isBuffer(messageBytes) ? messageBytes : messageBytes);
176
253
  }
177
254
  const signatureEd25519 = await this.sign({
178
255
  message: messageToSign,
@@ -184,18 +261,15 @@ class DynamicSvmWalletClient extends node.DynamicWalletClient {
184
261
  if (!signatureEd25519) {
185
262
  throw new Error('Signature is undefined');
186
263
  }
187
- const senderPublicKey = new web3_js.PublicKey(senderAddress);
188
- const signedTransaction = addSignatureToTransaction({
189
- transaction,
190
- signature: signatureEd25519,
191
- signerPublicKey: senderPublicKey
192
- });
193
- return signedTransaction;
264
+ return encodeBase58(signatureEd25519);
194
265
  } catch (error) {
195
- this.logger.error('Error in signTransaction:', error);
196
- if (error instanceof Error) {
197
- this.logger.error('Error details:', error);
198
- }
266
+ logError({
267
+ message: 'Error in signTransaction:',
268
+ error: error,
269
+ context: {
270
+ senderAddress
271
+ }
272
+ });
199
273
  throw error;
200
274
  }
201
275
  }
@@ -238,18 +312,19 @@ class DynamicSvmWalletClient extends node.DynamicWalletClient {
238
312
  * @param privateKey The private key to convert
239
313
  * @returns The hex string
240
314
  */ decodePrivateKeyForSolana(privateKey) {
241
- const decoded = new web3_js.PublicKey(privateKey).toBuffer();
242
- const slicedBytes = decoded.slice(0, 32);
243
- return Buffer.from(slicedBytes).toString('hex');
315
+ const decoded = decodeBase58(privateKey); // 64 bytes
316
+ if (decoded.length !== 64) throw new Error('Invalid Solana secret key length');
317
+ return Buffer.from(decoded.slice(0, 32)).toString('hex');
244
318
  }
245
319
  getPublicKeyFromPrivateKey(privateKey) {
246
- const privateKeyBytes = new web3_js.PublicKey(privateKey).toBuffer();
247
- const keypair = web3_js.Keypair.fromSecretKey(privateKeyBytes);
248
- const publicKeyBase58 = keypair.publicKey.toBase58();
249
- return publicKeyBase58;
320
+ const secret = decodeBase58(privateKey);
321
+ const keypair = web3_js.Keypair.fromSecretKey(secret);
322
+ return keypair.publicKey.toBase58();
250
323
  }
251
324
  encodePublicKey(publicKey) {
252
- return new web3_js.PublicKey(publicKey).toBase58();
325
+ // Ensure a plain Uint8Array is passed to PublicKey
326
+ const bytes = publicKey instanceof Uint8Array ? publicKey : new Uint8Array(publicKey);
327
+ return new web3_js.PublicKey(bytes).toBase58();
253
328
  }
254
329
  /**
255
330
  * Imports the private key for a given account address
@@ -274,11 +349,16 @@ class DynamicSvmWalletClient extends node.DynamicWalletClient {
274
349
  onError,
275
350
  onCeremonyComplete: (accountAddress, walletId)=>{
276
351
  // update wallet map
352
+ const chainConfig = node.getMPCChainConfig(this.chainName);
277
353
  this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress] || {}, {
278
354
  accountAddress,
279
355
  walletId,
280
356
  chainName: this.chainName,
281
357
  thresholdSignatureScheme,
358
+ derivationPath: JSON.stringify(Object.fromEntries(chainConfig.derivationPath.map((value, index)=>[
359
+ index,
360
+ value
361
+ ]))),
282
362
  externalServerKeySharesBackupInfo: node.getExternalServerKeyShareBackupInfo()
283
363
  });
284
364
  ceremonyCeremonyCompleteResolver(undefined);
@@ -310,17 +390,222 @@ class DynamicSvmWalletClient extends node.DynamicWalletClient {
310
390
  const svmWallets = wallets.filter((wallet)=>wallet.chainName === 'solana');
311
391
  return svmWallets;
312
392
  }
313
- constructor({ environmentId, baseApiUrl, baseMPCRelayApiUrl }){
393
+ constructor({ environmentId, baseApiUrl, baseMPCRelayApiUrl, enableMPCAccelerator }){
314
394
  super({
315
395
  environmentId,
316
396
  baseApiUrl,
317
- baseMPCRelayApiUrl
397
+ baseMPCRelayApiUrl,
398
+ enableMPCAccelerator
318
399
  }), this.chainName = 'SVM';
319
400
  }
320
401
  }
321
402
 
403
+ async function getBalance({ address, rpcUrl = node.SOLANA_RPC_URL }) {
404
+ const connection = new web3_js.Connection(rpcUrl != null ? rpcUrl : 'https://api.devnet.solana.com');
405
+ const balance = await connection.getBalance(new web3_js.PublicKey(address));
406
+ return balance;
407
+ }
408
+ async function createSolanaTransaction({ senderSolanaAddress, amount, to, rpcUrl = 'https://api.devnet.solana.com' }) {
409
+ const connection = new web3_js.Connection(rpcUrl != null ? rpcUrl : 'https://api.devnet.solana.com');
410
+ const balance = await getBalance({
411
+ address: senderSolanaAddress,
412
+ rpcUrl
413
+ });
414
+ if (balance < amount * 1e9) {
415
+ throw new Error('Insufficient balance');
416
+ }
417
+ const fromPubkey = new web3_js.PublicKey(senderSolanaAddress);
418
+ const transaction = new web3_js.Transaction().add(web3_js.SystemProgram.transfer({
419
+ fromPubkey: fromPubkey,
420
+ toPubkey: new web3_js.PublicKey(to),
421
+ lamports: amount * 1e9
422
+ }));
423
+ const { blockhash } = await connection.getLatestBlockhash();
424
+ transaction.recentBlockhash = blockhash;
425
+ transaction.feePayer = fromPubkey;
426
+ const serializedTransaction = transaction.serializeMessage();
427
+ return {
428
+ transaction,
429
+ serializedTransaction
430
+ };
431
+ }
432
+ const addSignatureToTransaction = ({ transaction, signature, signerPublicKey })=>{
433
+ transaction.addSignature(signerPublicKey, Buffer.from(signature));
434
+ return transaction;
435
+ };
436
+ function attachSignature({ transaction, signatureBase58, senderAddress }) {
437
+ const sigBytes = decodeBase58(signatureBase58);
438
+ const signerPubkey = new web3_js.PublicKey(senderAddress);
439
+ return addSignatureToTransaction({
440
+ transaction,
441
+ signature: sigBytes,
442
+ signerPublicKey: signerPubkey
443
+ });
444
+ }
445
+ async function sendTransaction({ signedTransaction, rpcUrl = 'https://api.devnet.solana.com' }) {
446
+ const connection = new web3_js.Connection(rpcUrl != null ? rpcUrl : 'https://api.devnet.solana.com');
447
+ const txid = await connection.sendRawTransaction(Buffer.from(signedTransaction));
448
+ return txid;
449
+ }
450
+
451
+ /**
452
+ * Creates a delegated SVM wallet client for functional operations
453
+ */ const createDelegatedSvmWalletClient = ({ environmentId, baseApiUrl, baseMPCRelayApiUrl, apiKey, debug = false })=>{
454
+ const baseClient = node.createDelegatedWalletClient({
455
+ environmentId,
456
+ baseApiUrl,
457
+ baseMPCRelayApiUrl,
458
+ apiKey,
459
+ debug
460
+ });
461
+ const svmClient = _extends({}, baseClient, {
462
+ chainName: 'SVM'
463
+ });
464
+ return svmClient;
465
+ };
466
+ /**
467
+ * Signs a message using delegated signing for SVM
468
+ */ const delegatedSignMessage = async (client, { walletId, walletApiKey, keyShare, message, isFormatted = false })=>{
469
+ try {
470
+ // Use the delegated sign message function from node package
471
+ const signatureEd25519 = await node.delegatedSignMessage(client, {
472
+ walletId,
473
+ walletApiKey,
474
+ keyShare,
475
+ message,
476
+ chainName: client.chainName,
477
+ isFormatted
478
+ });
479
+ // Use PublicKey to encode signature as base58 (SVM format)
480
+ const base58Signature = encodeBase58(signatureEd25519);
481
+ return base58Signature;
482
+ } catch (error) {
483
+ logError({
484
+ message: 'Error in delegatedSignMessage',
485
+ error: error,
486
+ context: {
487
+ walletId
488
+ }
489
+ });
490
+ throw error;
491
+ }
492
+ };
493
+ /**
494
+ * Signs a transaction using delegated signing for SVM
495
+ *
496
+ * @param client - The delegated SVM wallet client
497
+ * @param options - Signing options
498
+ * @param options.walletId - The wallet ID
499
+ * @param options.walletApiKey - The wallet API key
500
+ * @param options.keyShare - The server key share
501
+ * @param options.transaction - The transaction to sign (VersionedTransaction or Transaction)
502
+ * @param options.signerAddress - Optional. The address that should sign the transaction.
503
+ * If not provided, defaults to the first signer (VersionedTransaction)
504
+ * or fee payer (Transaction). Use this for gasless transactions where
505
+ * a separate fee payer pays the fees.
506
+ *
507
+ * @returns The partially signed transaction with the signature attached for the specified signer
508
+ *
509
+ * @example
510
+ * // Standard transaction where sender is also fee payer
511
+ * const signedTx = await delegatedSignTransaction(client, {
512
+ * walletId,
513
+ * walletApiKey,
514
+ * keyShare,
515
+ * transaction,
516
+ * });
517
+ *
518
+ * @example
519
+ * // Gasless transaction with separate fee payer
520
+ * const transaction = new Transaction();
521
+ * transaction.feePayer = feePayerPublicKey; // Set the actual fee payer
522
+ * transaction.add(instruction); // Instruction that requires sender signature
523
+ *
524
+ * const signedTx = await delegatedSignTransaction(client, {
525
+ * walletId,
526
+ * walletApiKey,
527
+ * keyShare,
528
+ * transaction,
529
+ * signerAddress: senderAddress, // Explicitly specify who signs
530
+ * });
531
+ *
532
+ */ const delegatedSignTransaction = async (client, { walletId, walletApiKey, keyShare, transaction, signerAddress })=>{
533
+ try {
534
+ let messageToSign;
535
+ if (transaction instanceof web3_js.VersionedTransaction) {
536
+ // For versioned transactions, we need to sign the message directly
537
+ const messageBytes = transaction.message.serialize();
538
+ messageToSign = Buffer.from(Array.from(messageBytes)).toString('hex');
539
+ } else {
540
+ // For legacy transactions, serialize the message
541
+ const messageBytes = transaction.serializeMessage();
542
+ messageToSign = messageBytes.toString('hex');
543
+ }
544
+ // Use the delegated sign message function from node package
545
+ const signatureEd25519 = await node.delegatedSignMessage(client, {
546
+ walletId,
547
+ walletApiKey,
548
+ keyShare,
549
+ message: messageToSign,
550
+ chainName: client.chainName,
551
+ isFormatted: false
552
+ });
553
+ if (!signatureEd25519) {
554
+ throw new Error('Signature is undefined');
555
+ }
556
+ const resolvedSignerAddress = signerAddress != null ? signerAddress : (()=>{
557
+ var _transaction_feePayer;
558
+ if (transaction instanceof web3_js.VersionedTransaction) {
559
+ var _signers_;
560
+ const signers = transaction.message.staticAccountKeys;
561
+ var _signers__toBase58;
562
+ return (_signers__toBase58 = (_signers_ = signers[0]) == null ? void 0 : _signers_.toBase58()) != null ? _signers__toBase58 : '';
563
+ }
564
+ var _transaction_feePayer_toBase58;
565
+ return (_transaction_feePayer_toBase58 = (_transaction_feePayer = transaction.feePayer) == null ? void 0 : _transaction_feePayer.toBase58()) != null ? _transaction_feePayer_toBase58 : '';
566
+ })();
567
+ if (!resolvedSignerAddress) {
568
+ throw new Error('Could not determine signer address. Provide signerAddress explicitly or ensure transaction has a fee payer.');
569
+ }
570
+ let signerPublicKey;
571
+ try {
572
+ signerPublicKey = new web3_js.PublicKey(resolvedSignerAddress);
573
+ } catch (error) {
574
+ throw new Error(`Invalid signer address: ${resolvedSignerAddress}. ${error instanceof Error ? error.message : 'Unknown error'}`);
575
+ }
576
+ const signedTransaction = addSignatureToTransaction({
577
+ transaction,
578
+ signature: signatureEd25519,
579
+ signerPublicKey
580
+ });
581
+ return signedTransaction;
582
+ } catch (error) {
583
+ logError({
584
+ message: 'Error in delegatedSignTransaction',
585
+ error: error,
586
+ context: {
587
+ walletId
588
+ }
589
+ });
590
+ throw error;
591
+ }
592
+ };
593
+ /**
594
+ * Revoke delegation - delegates to the node package
595
+ */ const revokeDelegation = async (client, params)=>{
596
+ return node.revokeDelegation(client, params);
597
+ };
598
+
322
599
  exports.DynamicSvmWalletClient = DynamicSvmWalletClient;
600
+ exports.ERROR_CREATE_WALLET_ACCOUNT = ERROR_CREATE_WALLET_ACCOUNT;
323
601
  exports.addSignatureToTransaction = addSignatureToTransaction;
602
+ exports.attachSignature = attachSignature;
603
+ exports.createDelegatedSvmWalletClient = createDelegatedSvmWalletClient;
324
604
  exports.createSolanaTransaction = createSolanaTransaction;
605
+ exports.decodeBase58 = decodeBase58;
606
+ exports.delegatedSignMessage = delegatedSignMessage;
607
+ exports.delegatedSignTransaction = delegatedSignTransaction;
608
+ exports.encodeBase58 = encodeBase58;
325
609
  exports.getBalance = getBalance;
610
+ exports.revokeDelegation = revokeDelegation;
326
611
  exports.sendTransaction = sendTransaction;