@dynamic-labs-wallet/svm 0.0.0-preview.57 → 0.0.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.
package/index.cjs.js CHANGED
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var browser = require('@dynamic-labs-wallet/browser');
4
- var bs58 = require('bs58');
5
4
  var web3_js = require('@solana/web3.js');
5
+ var bs58 = require('bs58');
6
6
 
7
7
  function _extends() {
8
8
  _extends = Object.assign || function assign(target) {
@@ -15,21 +15,18 @@ function _extends() {
15
15
  return _extends.apply(this, arguments);
16
16
  }
17
17
 
18
- const addSignatureToTransaction = ({ transaction, signature, signerPublicKey })=>{
19
- transaction.addSignature(signerPublicKey, Buffer.from(signature));
20
- return transaction;
21
- };
22
-
23
- const ERROR_CREATE_WALLET_ACCOUNT = 'Error creating svm wallet account';
24
-
25
18
  class DynamicSvmWalletClient extends browser.DynamicWalletClient {
26
19
  /**
27
20
  * Creates a wallet account on the Solana chain
28
21
  *
29
22
  * @param thresholdSignatureScheme The threshold signature scheme to use
30
23
  * @returns The account address, public key hex, raw public key, and client key shares
31
- */ async createWalletAccount({ thresholdSignatureScheme, password = undefined }) {
24
+ */ async createWalletAccount({ thresholdSignatureScheme, password = undefined, signedSessionId }) {
32
25
  try {
26
+ let ceremonyCeremonyCompleteResolver;
27
+ const ceremonyCompletePromise = new Promise((resolve)=>{
28
+ ceremonyCeremonyCompleteResolver = resolve;
29
+ });
33
30
  const { rawPublicKey, clientKeyShares } = await this.keyGen({
34
31
  chainName: this.chainName,
35
32
  thresholdSignatureScheme,
@@ -42,42 +39,49 @@ class DynamicSvmWalletClient extends browser.DynamicWalletClient {
42
39
  thresholdSignatureScheme,
43
40
  clientKeySharesBackupInfo: browser.getClientKeyShareBackupInfo()
44
41
  });
42
+ this.logger.debug('walletMap updated for wallet', {
43
+ context: {
44
+ accountAddress,
45
+ walletId,
46
+ walletMap: this.walletMap
47
+ }
48
+ });
49
+ ceremonyCeremonyCompleteResolver(undefined);
45
50
  }
46
51
  });
47
- if (!rawPublicKey || !(rawPublicKey instanceof Uint8Array)) {
48
- throw new Error('Raw public key is not a Uint8Array');
52
+ // Wait for the ceremony to complete before proceeding
53
+ await ceremonyCompletePromise;
54
+ if (!rawPublicKey || !(rawPublicKey instanceof Uint8Array || typeof rawPublicKey === 'string')) {
55
+ throw new Error('Raw public key is not a Uint8Array or string' + typeof rawPublicKey);
49
56
  }
50
57
  if (!clientKeyShares) {
51
- throw new Error('Error creating wallet account');
58
+ throw new Error(browser.ERROR_KEYGEN_FAILED);
52
59
  }
53
60
  const { accountAddress } = await this.deriveAccountAddress(rawPublicKey);
54
61
  // Update client key shares in wallet map
55
- // warning: this might result in race condition if `onCeremonyComplete` executes at the same time
56
- // TODO: remove this once iframe handling for secret shares is implemented
57
62
  await this.setClientKeySharesToLocalStorage({
58
63
  accountAddress,
59
64
  clientKeyShares,
60
65
  overwriteOrMerge: 'overwrite'
61
66
  });
62
- // Backup the new wallet without waiting for the promise to resolve
63
- void this.storeEncryptedBackupByWalletWithRetry({
67
+ await this.storeEncryptedBackupByWalletWithRetry({
64
68
  accountAddress,
65
69
  clientKeyShares,
66
- password
70
+ password,
71
+ signedSessionId
67
72
  });
68
73
  return {
69
74
  accountAddress,
70
- rawPublicKey: rawPublicKey,
71
- clientKeyShares
75
+ rawPublicKey
72
76
  };
73
77
  } catch (error) {
74
- this.logger.error(ERROR_CREATE_WALLET_ACCOUNT, error);
75
- throw new Error(ERROR_CREATE_WALLET_ACCOUNT);
78
+ this.logger.error(browser.ERROR_CREATE_WALLET_ACCOUNT, error);
79
+ throw new Error(browser.ERROR_CREATE_WALLET_ACCOUNT);
76
80
  }
77
81
  }
78
- // Function to properly derive account address
79
82
  async deriveAccountAddress(rawPublicKey) {
80
- const accountAddress = bs58.encode(rawPublicKey);
83
+ const pubKeyBytes = typeof rawPublicKey === 'string' ? new Uint8Array(Buffer.from(rawPublicKey, 'hex')) : rawPublicKey;
84
+ const accountAddress = bs58.encode(pubKeyBytes);
81
85
  return {
82
86
  accountAddress
83
87
  };
@@ -88,62 +92,55 @@ class DynamicSvmWalletClient extends browser.DynamicWalletClient {
88
92
  * @param message The message to sign (Uint8Array)
89
93
  * @param accountAddress Solana address (base58 encoded)
90
94
  * @param password The password for encrypted backup shares
91
- */ async signMessage({ message, accountAddress, password = undefined }) {
95
+ */ async signMessage({ message, accountAddress, password = undefined, signedSessionId, mfaToken }) {
92
96
  await this.verifyPassword({
93
97
  accountAddress,
94
98
  password,
95
- walletOperation: browser.WalletOperation.SIGN_MESSAGE
99
+ walletOperation: browser.WalletOperation.SIGN_MESSAGE,
100
+ signedSessionId
96
101
  });
97
102
  if (!accountAddress) {
98
- throw new Error('Account address is required');
103
+ throw new Error(browser.ERROR_ACCOUNT_ADDRESS_REQUIRED);
99
104
  }
100
105
  try {
101
106
  const signatureEd25519 = await this.sign({
102
107
  message,
103
108
  accountAddress: accountAddress,
104
109
  chainName: this.chainName,
105
- password
110
+ password,
111
+ signedSessionId,
112
+ mfaToken
106
113
  });
107
114
  const base58Signature = bs58.encode(signatureEd25519);
108
115
  return base58Signature;
109
116
  } catch (error) {
110
- this.logger.error('Error signing message:', error);
111
- throw error;
117
+ this.logger.error(browser.ERROR_SIGN_MESSAGE, error);
118
+ throw new Error(browser.ERROR_SIGN_MESSAGE);
112
119
  }
113
120
  }
114
- async signTransaction({ senderAddress, transaction, password = undefined }) {
121
+ async signTransaction({ senderAddress, transaction, password = undefined, signedSessionId, mfaToken, chainId }) {
115
122
  await this.verifyPassword({
116
123
  accountAddress: senderAddress,
117
124
  password,
118
- walletOperation: browser.WalletOperation.SIGN_TRANSACTION
125
+ walletOperation: browser.WalletOperation.SIGN_TRANSACTION,
126
+ signedSessionId
119
127
  });
120
128
  try {
121
- let messageToSign;
122
- if (transaction instanceof web3_js.VersionedTransaction) {
123
- // For versioned transactions, we need to sign the message directly
124
- const messageBytes = transaction.message.serialize();
125
- messageToSign = Buffer.from(messageBytes).toString('hex');
126
- } else {
127
- // For legacy transactions, serialize the message
128
- const messageBytes = transaction.serializeMessage();
129
- messageToSign = Buffer.from(messageBytes).toString('hex');
130
- }
131
- const signatureEd25519 = await this.sign({
132
- message: messageToSign,
133
- accountAddress: senderAddress,
134
- chainName: this.chainName,
135
- password
129
+ const base58SerializedTransaction = this.prepareTransactionForSigning(transaction);
130
+ const signParams = this.buildSignParams({
131
+ transaction,
132
+ senderAddress,
133
+ password,
134
+ signedSessionId,
135
+ mfaToken,
136
+ chainId,
137
+ base58SerializedTransaction
136
138
  });
139
+ const signatureEd25519 = await this.sign(signParams);
137
140
  if (!signatureEd25519) {
138
141
  throw new Error('Signature is undefined');
139
142
  }
140
- const senderPublicKey = new web3_js.PublicKey(senderAddress);
141
- const signedTransaction = addSignatureToTransaction({
142
- transaction,
143
- signature: signatureEd25519,
144
- signerPublicKey: senderPublicKey
145
- });
146
- return signedTransaction;
143
+ return Buffer.from(signatureEd25519).toString('hex');
147
144
  } catch (error) {
148
145
  this.logger.error('Error in signTransaction:', error);
149
146
  if (error instanceof Error) {
@@ -152,33 +149,59 @@ class DynamicSvmWalletClient extends browser.DynamicWalletClient {
152
149
  throw error;
153
150
  }
154
151
  }
152
+ prepareTransactionForSigning(transaction) {
153
+ const transactionBytes = new Uint8Array(Buffer.from(transaction, 'hex'));
154
+ const deserializedTransaction = web3_js.VersionedMessage.deserialize(transactionBytes);
155
+ const versionedTransaction = new web3_js.VersionedTransaction(deserializedTransaction);
156
+ const serializedTransaction = versionedTransaction.serialize();
157
+ return bs58.encode(serializedTransaction);
158
+ }
159
+ buildSignParams({ transaction, senderAddress, password, signedSessionId, mfaToken, chainId, base58SerializedTransaction }) {
160
+ const signParams = {
161
+ message: transaction,
162
+ accountAddress: senderAddress,
163
+ chainName: this.chainName,
164
+ password,
165
+ signedSessionId,
166
+ mfaToken
167
+ };
168
+ if (chainId !== undefined) {
169
+ signParams.context = {
170
+ svmTransaction: {
171
+ chainId,
172
+ method: 'signAndSendTransaction',
173
+ serializedTransactions: [
174
+ base58SerializedTransaction
175
+ ]
176
+ }
177
+ };
178
+ }
179
+ return signParams;
180
+ }
155
181
  /**
156
182
  * Exports the private key for a given account address
157
183
  *
158
184
  * @param accountAddress The account address to export the private key for
159
185
  * @param password The password for encrypted backup shares
160
186
  * @returns The private key
161
- */ async exportPrivateKey({ accountAddress, displayContainer, password = undefined }) {
187
+ */ async exportPrivateKey({ accountAddress, password = undefined, signedSessionId, mfaToken }) {
162
188
  await this.verifyPassword({
163
189
  accountAddress,
164
190
  password,
165
- walletOperation: browser.WalletOperation.EXPORT_PRIVATE_KEY
191
+ walletOperation: browser.WalletOperation.EXPORT_PRIVATE_KEY,
192
+ signedSessionId
166
193
  });
167
194
  const { derivedPrivateKey } = await this.exportKey({
168
195
  accountAddress,
169
196
  chainName: this.chainName,
170
197
  password,
171
- displayContainer
198
+ signedSessionId,
199
+ mfaToken
172
200
  });
173
201
  if (!derivedPrivateKey) {
174
202
  throw new Error('Derived private key is undefined');
175
203
  }
176
- const encodedPrivateKey = bs58.encode(Buffer.from(derivedPrivateKey));
177
- // Display the private key in the container via iframe
178
- const { iframeDisplay } = await this.initializeIframeDisplayForContainer({
179
- container: displayContainer
180
- });
181
- iframeDisplay.displayPrivateKey(accountAddress, encodedPrivateKey);
204
+ return derivedPrivateKey;
182
205
  }
183
206
  /**
184
207
  * Exports the private key for a given account address
@@ -222,65 +245,89 @@ class DynamicSvmWalletClient extends browser.DynamicWalletClient {
222
245
  * @param thresholdSignatureScheme The threshold signature scheme to use
223
246
  * @param password The password for encrypted backup shares
224
247
  * @returns The account address, raw public key, and client key shares
225
- */ async importPrivateKey({ privateKey, chainName, thresholdSignatureScheme, password = undefined, onError }) {
226
- //get public key from private key
227
- const publicKey = this.getPublicKeyFromPrivateKey(privateKey);
228
- const formattedPrivateKey = await this.decodePrivateKeyForSolana(privateKey);
229
- const { rawPublicKey, clientKeyShares } = await this.importRawPrivateKey({
230
- chainName,
231
- privateKey: formattedPrivateKey,
232
- thresholdSignatureScheme,
233
- onError,
234
- onCeremonyComplete: (accountAddress, walletId)=>{
235
- // update wallet map
236
- this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress] || {}, {
237
- accountAddress,
238
- walletId,
239
- chainName: this.chainName,
240
- thresholdSignatureScheme,
241
- clientKeySharesBackupInfo: browser.getClientKeyShareBackupInfo()
242
- });
248
+ */ async importPrivateKey({ privateKey, chainName, thresholdSignatureScheme, password = undefined, onError, signedSessionId }) {
249
+ try {
250
+ let ceremonyCeremonyCompleteResolver;
251
+ const ceremonyCompletePromise = new Promise((resolve)=>{
252
+ ceremonyCeremonyCompleteResolver = resolve;
253
+ });
254
+ //get public key from private key
255
+ const publicKey = this.getPublicKeyFromPrivateKey(privateKey);
256
+ const formattedPrivateKey = this.decodePrivateKeyForSolana(privateKey);
257
+ const { rawPublicKey, clientKeyShares } = await this.importRawPrivateKey({
258
+ chainName,
259
+ privateKey: formattedPrivateKey,
260
+ thresholdSignatureScheme,
261
+ onError: (error)=>{
262
+ this.logger.error(browser.ERROR_IMPORT_PRIVATE_KEY, error);
263
+ onError == null ? void 0 : onError(error);
264
+ },
265
+ onCeremonyComplete: (accountAddress, walletId)=>{
266
+ // update wallet map
267
+ this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress] || {}, {
268
+ accountAddress,
269
+ walletId,
270
+ chainName: this.chainName,
271
+ thresholdSignatureScheme,
272
+ clientKeySharesBackupInfo: browser.getClientKeyShareBackupInfo()
273
+ });
274
+ this.logger.debug('walletMap updated for wallet', {
275
+ context: {
276
+ accountAddress,
277
+ walletId,
278
+ walletMap: this.walletMap
279
+ }
280
+ });
281
+ ceremonyCeremonyCompleteResolver(undefined);
282
+ }
283
+ });
284
+ // Wait for the ceremony to complete before proceeding
285
+ await ceremonyCompletePromise;
286
+ if (!rawPublicKey || !clientKeyShares) {
287
+ throw new Error(browser.ERROR_IMPORT_PRIVATE_KEY);
243
288
  }
244
- });
245
- if (!rawPublicKey || !clientKeyShares) {
246
- throw new Error('Error creating wallet account');
247
- }
248
- const { accountAddress } = await this.deriveAccountAddress(rawPublicKey);
249
- if (accountAddress !== publicKey) {
250
- throw new Error(`Public key mismatch: derived address ${accountAddress} !== public key ${publicKey}`);
289
+ const { accountAddress } = await this.deriveAccountAddress(rawPublicKey);
290
+ if (accountAddress !== publicKey) {
291
+ throw new Error(`Public key mismatch: derived address ${accountAddress} !== public key ${publicKey}`);
292
+ }
293
+ // Update client key shares in wallet map
294
+ await this.setClientKeySharesToLocalStorage({
295
+ accountAddress,
296
+ clientKeyShares,
297
+ overwriteOrMerge: 'overwrite'
298
+ });
299
+ await this.storeEncryptedBackupByWalletWithRetry({
300
+ accountAddress,
301
+ clientKeyShares,
302
+ password,
303
+ signedSessionId
304
+ });
305
+ return {
306
+ accountAddress,
307
+ rawPublicKey: rawPublicKey
308
+ };
309
+ } catch (error) {
310
+ this.logger.error(browser.ERROR_IMPORT_PRIVATE_KEY, error);
311
+ throw new Error(browser.ERROR_IMPORT_PRIVATE_KEY);
251
312
  }
252
- // Update client key shares in wallet map
253
- // warning: this might result in race condition if `onCeremonyComplete` executes at the same time
254
- // TODO: remove this once iframe handling for secret shares is implemented
255
- await this.setClientKeySharesToLocalStorage({
256
- accountAddress,
257
- clientKeyShares,
258
- overwriteOrMerge: 'overwrite'
259
- });
260
- // Backup the new wallet without waiting for the promise to resolve
261
- void this.storeEncryptedBackupByWalletWithRetry({
262
- accountAddress,
263
- clientKeyShares,
264
- password
265
- });
266
- return {
267
- accountAddress,
268
- rawPublicKey: rawPublicKey,
269
- clientKeyShares
270
- };
271
313
  }
272
314
  async getSvmWallets() {
273
315
  const wallets = await this.getWallets();
274
316
  const svmWallets = wallets.filter((wallet)=>wallet.chainName === 'solana');
275
317
  return svmWallets;
276
318
  }
277
- constructor({ environmentId, authToken, baseApiUrl, baseMPCRelayApiUrl }){
319
+ constructor({ environmentId, authToken, baseApiUrl, baseMPCRelayApiUrl, storageKey, debug, featureFlags, authMode = browser.AuthMode.HEADER, sdkVersion }){
278
320
  super({
279
321
  environmentId,
280
322
  authToken,
281
323
  baseApiUrl,
282
- baseMPCRelayApiUrl
283
- }), this.chainName = 'SOL';
324
+ baseMPCRelayApiUrl,
325
+ storageKey,
326
+ debug,
327
+ featureFlags,
328
+ authMode,
329
+ sdkVersion
330
+ }), this.chainName = 'SVM';
284
331
  }
285
332
  }
286
333
 
package/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
- import { DynamicWalletClient, getClientKeyShareBackupInfo, WalletOperation } from '@dynamic-labs-wallet/browser';
1
+ import { DynamicWalletClient, getClientKeyShareBackupInfo, ERROR_KEYGEN_FAILED, ERROR_CREATE_WALLET_ACCOUNT, WalletOperation, ERROR_ACCOUNT_ADDRESS_REQUIRED, ERROR_SIGN_MESSAGE, ERROR_IMPORT_PRIVATE_KEY, AuthMode } from '@dynamic-labs-wallet/browser';
2
+ import { VersionedMessage, VersionedTransaction, Keypair } from '@solana/web3.js';
2
3
  import bs58 from 'bs58';
3
- import { VersionedTransaction, PublicKey, Keypair } from '@solana/web3.js';
4
4
 
5
5
  function _extends() {
6
6
  _extends = Object.assign || function assign(target) {
@@ -13,21 +13,18 @@ function _extends() {
13
13
  return _extends.apply(this, arguments);
14
14
  }
15
15
 
16
- const addSignatureToTransaction = ({ transaction, signature, signerPublicKey })=>{
17
- transaction.addSignature(signerPublicKey, Buffer.from(signature));
18
- return transaction;
19
- };
20
-
21
- const ERROR_CREATE_WALLET_ACCOUNT = 'Error creating svm wallet account';
22
-
23
16
  class DynamicSvmWalletClient extends DynamicWalletClient {
24
17
  /**
25
18
  * Creates a wallet account on the Solana chain
26
19
  *
27
20
  * @param thresholdSignatureScheme The threshold signature scheme to use
28
21
  * @returns The account address, public key hex, raw public key, and client key shares
29
- */ async createWalletAccount({ thresholdSignatureScheme, password = undefined }) {
22
+ */ async createWalletAccount({ thresholdSignatureScheme, password = undefined, signedSessionId }) {
30
23
  try {
24
+ let ceremonyCeremonyCompleteResolver;
25
+ const ceremonyCompletePromise = new Promise((resolve)=>{
26
+ ceremonyCeremonyCompleteResolver = resolve;
27
+ });
31
28
  const { rawPublicKey, clientKeyShares } = await this.keyGen({
32
29
  chainName: this.chainName,
33
30
  thresholdSignatureScheme,
@@ -40,42 +37,49 @@ class DynamicSvmWalletClient extends DynamicWalletClient {
40
37
  thresholdSignatureScheme,
41
38
  clientKeySharesBackupInfo: getClientKeyShareBackupInfo()
42
39
  });
40
+ this.logger.debug('walletMap updated for wallet', {
41
+ context: {
42
+ accountAddress,
43
+ walletId,
44
+ walletMap: this.walletMap
45
+ }
46
+ });
47
+ ceremonyCeremonyCompleteResolver(undefined);
43
48
  }
44
49
  });
45
- if (!rawPublicKey || !(rawPublicKey instanceof Uint8Array)) {
46
- throw new Error('Raw public key is not a Uint8Array');
50
+ // Wait for the ceremony to complete before proceeding
51
+ await ceremonyCompletePromise;
52
+ if (!rawPublicKey || !(rawPublicKey instanceof Uint8Array || typeof rawPublicKey === 'string')) {
53
+ throw new Error('Raw public key is not a Uint8Array or string' + typeof rawPublicKey);
47
54
  }
48
55
  if (!clientKeyShares) {
49
- throw new Error('Error creating wallet account');
56
+ throw new Error(ERROR_KEYGEN_FAILED);
50
57
  }
51
58
  const { accountAddress } = await this.deriveAccountAddress(rawPublicKey);
52
59
  // Update client key shares in wallet map
53
- // warning: this might result in race condition if `onCeremonyComplete` executes at the same time
54
- // TODO: remove this once iframe handling for secret shares is implemented
55
60
  await this.setClientKeySharesToLocalStorage({
56
61
  accountAddress,
57
62
  clientKeyShares,
58
63
  overwriteOrMerge: 'overwrite'
59
64
  });
60
- // Backup the new wallet without waiting for the promise to resolve
61
- void this.storeEncryptedBackupByWalletWithRetry({
65
+ await this.storeEncryptedBackupByWalletWithRetry({
62
66
  accountAddress,
63
67
  clientKeyShares,
64
- password
68
+ password,
69
+ signedSessionId
65
70
  });
66
71
  return {
67
72
  accountAddress,
68
- rawPublicKey: rawPublicKey,
69
- clientKeyShares
73
+ rawPublicKey
70
74
  };
71
75
  } catch (error) {
72
76
  this.logger.error(ERROR_CREATE_WALLET_ACCOUNT, error);
73
77
  throw new Error(ERROR_CREATE_WALLET_ACCOUNT);
74
78
  }
75
79
  }
76
- // Function to properly derive account address
77
80
  async deriveAccountAddress(rawPublicKey) {
78
- const accountAddress = bs58.encode(rawPublicKey);
81
+ const pubKeyBytes = typeof rawPublicKey === 'string' ? new Uint8Array(Buffer.from(rawPublicKey, 'hex')) : rawPublicKey;
82
+ const accountAddress = bs58.encode(pubKeyBytes);
79
83
  return {
80
84
  accountAddress
81
85
  };
@@ -86,62 +90,55 @@ class DynamicSvmWalletClient extends DynamicWalletClient {
86
90
  * @param message The message to sign (Uint8Array)
87
91
  * @param accountAddress Solana address (base58 encoded)
88
92
  * @param password The password for encrypted backup shares
89
- */ async signMessage({ message, accountAddress, password = undefined }) {
93
+ */ async signMessage({ message, accountAddress, password = undefined, signedSessionId, mfaToken }) {
90
94
  await this.verifyPassword({
91
95
  accountAddress,
92
96
  password,
93
- walletOperation: WalletOperation.SIGN_MESSAGE
97
+ walletOperation: WalletOperation.SIGN_MESSAGE,
98
+ signedSessionId
94
99
  });
95
100
  if (!accountAddress) {
96
- throw new Error('Account address is required');
101
+ throw new Error(ERROR_ACCOUNT_ADDRESS_REQUIRED);
97
102
  }
98
103
  try {
99
104
  const signatureEd25519 = await this.sign({
100
105
  message,
101
106
  accountAddress: accountAddress,
102
107
  chainName: this.chainName,
103
- password
108
+ password,
109
+ signedSessionId,
110
+ mfaToken
104
111
  });
105
112
  const base58Signature = bs58.encode(signatureEd25519);
106
113
  return base58Signature;
107
114
  } catch (error) {
108
- this.logger.error('Error signing message:', error);
109
- throw error;
115
+ this.logger.error(ERROR_SIGN_MESSAGE, error);
116
+ throw new Error(ERROR_SIGN_MESSAGE);
110
117
  }
111
118
  }
112
- async signTransaction({ senderAddress, transaction, password = undefined }) {
119
+ async signTransaction({ senderAddress, transaction, password = undefined, signedSessionId, mfaToken, chainId }) {
113
120
  await this.verifyPassword({
114
121
  accountAddress: senderAddress,
115
122
  password,
116
- walletOperation: WalletOperation.SIGN_TRANSACTION
123
+ walletOperation: WalletOperation.SIGN_TRANSACTION,
124
+ signedSessionId
117
125
  });
118
126
  try {
119
- let messageToSign;
120
- if (transaction instanceof VersionedTransaction) {
121
- // For versioned transactions, we need to sign the message directly
122
- const messageBytes = transaction.message.serialize();
123
- messageToSign = Buffer.from(messageBytes).toString('hex');
124
- } else {
125
- // For legacy transactions, serialize the message
126
- const messageBytes = transaction.serializeMessage();
127
- messageToSign = Buffer.from(messageBytes).toString('hex');
128
- }
129
- const signatureEd25519 = await this.sign({
130
- message: messageToSign,
131
- accountAddress: senderAddress,
132
- chainName: this.chainName,
133
- password
127
+ const base58SerializedTransaction = this.prepareTransactionForSigning(transaction);
128
+ const signParams = this.buildSignParams({
129
+ transaction,
130
+ senderAddress,
131
+ password,
132
+ signedSessionId,
133
+ mfaToken,
134
+ chainId,
135
+ base58SerializedTransaction
134
136
  });
137
+ const signatureEd25519 = await this.sign(signParams);
135
138
  if (!signatureEd25519) {
136
139
  throw new Error('Signature is undefined');
137
140
  }
138
- const senderPublicKey = new PublicKey(senderAddress);
139
- const signedTransaction = addSignatureToTransaction({
140
- transaction,
141
- signature: signatureEd25519,
142
- signerPublicKey: senderPublicKey
143
- });
144
- return signedTransaction;
141
+ return Buffer.from(signatureEd25519).toString('hex');
145
142
  } catch (error) {
146
143
  this.logger.error('Error in signTransaction:', error);
147
144
  if (error instanceof Error) {
@@ -150,33 +147,59 @@ class DynamicSvmWalletClient extends DynamicWalletClient {
150
147
  throw error;
151
148
  }
152
149
  }
150
+ prepareTransactionForSigning(transaction) {
151
+ const transactionBytes = new Uint8Array(Buffer.from(transaction, 'hex'));
152
+ const deserializedTransaction = VersionedMessage.deserialize(transactionBytes);
153
+ const versionedTransaction = new VersionedTransaction(deserializedTransaction);
154
+ const serializedTransaction = versionedTransaction.serialize();
155
+ return bs58.encode(serializedTransaction);
156
+ }
157
+ buildSignParams({ transaction, senderAddress, password, signedSessionId, mfaToken, chainId, base58SerializedTransaction }) {
158
+ const signParams = {
159
+ message: transaction,
160
+ accountAddress: senderAddress,
161
+ chainName: this.chainName,
162
+ password,
163
+ signedSessionId,
164
+ mfaToken
165
+ };
166
+ if (chainId !== undefined) {
167
+ signParams.context = {
168
+ svmTransaction: {
169
+ chainId,
170
+ method: 'signAndSendTransaction',
171
+ serializedTransactions: [
172
+ base58SerializedTransaction
173
+ ]
174
+ }
175
+ };
176
+ }
177
+ return signParams;
178
+ }
153
179
  /**
154
180
  * Exports the private key for a given account address
155
181
  *
156
182
  * @param accountAddress The account address to export the private key for
157
183
  * @param password The password for encrypted backup shares
158
184
  * @returns The private key
159
- */ async exportPrivateKey({ accountAddress, displayContainer, password = undefined }) {
185
+ */ async exportPrivateKey({ accountAddress, password = undefined, signedSessionId, mfaToken }) {
160
186
  await this.verifyPassword({
161
187
  accountAddress,
162
188
  password,
163
- walletOperation: WalletOperation.EXPORT_PRIVATE_KEY
189
+ walletOperation: WalletOperation.EXPORT_PRIVATE_KEY,
190
+ signedSessionId
164
191
  });
165
192
  const { derivedPrivateKey } = await this.exportKey({
166
193
  accountAddress,
167
194
  chainName: this.chainName,
168
195
  password,
169
- displayContainer
196
+ signedSessionId,
197
+ mfaToken
170
198
  });
171
199
  if (!derivedPrivateKey) {
172
200
  throw new Error('Derived private key is undefined');
173
201
  }
174
- const encodedPrivateKey = bs58.encode(Buffer.from(derivedPrivateKey));
175
- // Display the private key in the container via iframe
176
- const { iframeDisplay } = await this.initializeIframeDisplayForContainer({
177
- container: displayContainer
178
- });
179
- iframeDisplay.displayPrivateKey(accountAddress, encodedPrivateKey);
202
+ return derivedPrivateKey;
180
203
  }
181
204
  /**
182
205
  * Exports the private key for a given account address
@@ -220,65 +243,89 @@ class DynamicSvmWalletClient extends DynamicWalletClient {
220
243
  * @param thresholdSignatureScheme The threshold signature scheme to use
221
244
  * @param password The password for encrypted backup shares
222
245
  * @returns The account address, raw public key, and client key shares
223
- */ async importPrivateKey({ privateKey, chainName, thresholdSignatureScheme, password = undefined, onError }) {
224
- //get public key from private key
225
- const publicKey = this.getPublicKeyFromPrivateKey(privateKey);
226
- const formattedPrivateKey = await this.decodePrivateKeyForSolana(privateKey);
227
- const { rawPublicKey, clientKeyShares } = await this.importRawPrivateKey({
228
- chainName,
229
- privateKey: formattedPrivateKey,
230
- thresholdSignatureScheme,
231
- onError,
232
- onCeremonyComplete: (accountAddress, walletId)=>{
233
- // update wallet map
234
- this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress] || {}, {
235
- accountAddress,
236
- walletId,
237
- chainName: this.chainName,
238
- thresholdSignatureScheme,
239
- clientKeySharesBackupInfo: getClientKeyShareBackupInfo()
240
- });
246
+ */ async importPrivateKey({ privateKey, chainName, thresholdSignatureScheme, password = undefined, onError, signedSessionId }) {
247
+ try {
248
+ let ceremonyCeremonyCompleteResolver;
249
+ const ceremonyCompletePromise = new Promise((resolve)=>{
250
+ ceremonyCeremonyCompleteResolver = resolve;
251
+ });
252
+ //get public key from private key
253
+ const publicKey = this.getPublicKeyFromPrivateKey(privateKey);
254
+ const formattedPrivateKey = this.decodePrivateKeyForSolana(privateKey);
255
+ const { rawPublicKey, clientKeyShares } = await this.importRawPrivateKey({
256
+ chainName,
257
+ privateKey: formattedPrivateKey,
258
+ thresholdSignatureScheme,
259
+ onError: (error)=>{
260
+ this.logger.error(ERROR_IMPORT_PRIVATE_KEY, error);
261
+ onError == null ? void 0 : onError(error);
262
+ },
263
+ onCeremonyComplete: (accountAddress, walletId)=>{
264
+ // update wallet map
265
+ this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress] || {}, {
266
+ accountAddress,
267
+ walletId,
268
+ chainName: this.chainName,
269
+ thresholdSignatureScheme,
270
+ clientKeySharesBackupInfo: getClientKeyShareBackupInfo()
271
+ });
272
+ this.logger.debug('walletMap updated for wallet', {
273
+ context: {
274
+ accountAddress,
275
+ walletId,
276
+ walletMap: this.walletMap
277
+ }
278
+ });
279
+ ceremonyCeremonyCompleteResolver(undefined);
280
+ }
281
+ });
282
+ // Wait for the ceremony to complete before proceeding
283
+ await ceremonyCompletePromise;
284
+ if (!rawPublicKey || !clientKeyShares) {
285
+ throw new Error(ERROR_IMPORT_PRIVATE_KEY);
241
286
  }
242
- });
243
- if (!rawPublicKey || !clientKeyShares) {
244
- throw new Error('Error creating wallet account');
245
- }
246
- const { accountAddress } = await this.deriveAccountAddress(rawPublicKey);
247
- if (accountAddress !== publicKey) {
248
- throw new Error(`Public key mismatch: derived address ${accountAddress} !== public key ${publicKey}`);
287
+ const { accountAddress } = await this.deriveAccountAddress(rawPublicKey);
288
+ if (accountAddress !== publicKey) {
289
+ throw new Error(`Public key mismatch: derived address ${accountAddress} !== public key ${publicKey}`);
290
+ }
291
+ // Update client key shares in wallet map
292
+ await this.setClientKeySharesToLocalStorage({
293
+ accountAddress,
294
+ clientKeyShares,
295
+ overwriteOrMerge: 'overwrite'
296
+ });
297
+ await this.storeEncryptedBackupByWalletWithRetry({
298
+ accountAddress,
299
+ clientKeyShares,
300
+ password,
301
+ signedSessionId
302
+ });
303
+ return {
304
+ accountAddress,
305
+ rawPublicKey: rawPublicKey
306
+ };
307
+ } catch (error) {
308
+ this.logger.error(ERROR_IMPORT_PRIVATE_KEY, error);
309
+ throw new Error(ERROR_IMPORT_PRIVATE_KEY);
249
310
  }
250
- // Update client key shares in wallet map
251
- // warning: this might result in race condition if `onCeremonyComplete` executes at the same time
252
- // TODO: remove this once iframe handling for secret shares is implemented
253
- await this.setClientKeySharesToLocalStorage({
254
- accountAddress,
255
- clientKeyShares,
256
- overwriteOrMerge: 'overwrite'
257
- });
258
- // Backup the new wallet without waiting for the promise to resolve
259
- void this.storeEncryptedBackupByWalletWithRetry({
260
- accountAddress,
261
- clientKeyShares,
262
- password
263
- });
264
- return {
265
- accountAddress,
266
- rawPublicKey: rawPublicKey,
267
- clientKeyShares
268
- };
269
311
  }
270
312
  async getSvmWallets() {
271
313
  const wallets = await this.getWallets();
272
314
  const svmWallets = wallets.filter((wallet)=>wallet.chainName === 'solana');
273
315
  return svmWallets;
274
316
  }
275
- constructor({ environmentId, authToken, baseApiUrl, baseMPCRelayApiUrl }){
317
+ constructor({ environmentId, authToken, baseApiUrl, baseMPCRelayApiUrl, storageKey, debug, featureFlags, authMode = AuthMode.HEADER, sdkVersion }){
276
318
  super({
277
319
  environmentId,
278
320
  authToken,
279
321
  baseApiUrl,
280
- baseMPCRelayApiUrl
281
- }), this.chainName = 'SOL';
322
+ baseMPCRelayApiUrl,
323
+ storageKey,
324
+ debug,
325
+ featureFlags,
326
+ authMode,
327
+ sdkVersion
328
+ }), this.chainName = 'SVM';
282
329
  }
283
330
  }
284
331
 
package/package.json CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "name": "@dynamic-labs-wallet/svm",
3
- "version": "0.0.0-preview.57",
3
+ "version": "0.0.1",
4
4
  "license": "MIT",
5
+ "type": "commonjs",
5
6
  "dependencies": {
6
- "@dynamic-labs-wallet/browser": "0.0.0-preview.57",
7
- "@solana/web3.js": "^1.98.0",
7
+ "@dynamic-labs-wallet/browser": "0.0.1",
8
+ "@dynamic-labs/sdk-api-core": "^0.0.753",
9
+ "@solana/web3.js": "^1.98.2",
8
10
  "bs58": "^6.0.0"
9
11
  },
10
12
  "nx": {
@@ -15,7 +17,6 @@
15
17
  "build": {}
16
18
  }
17
19
  },
18
- "type": "module",
19
20
  "main": "./index.cjs.js",
20
21
  "module": "./index.esm.js",
21
22
  "types": "./index.esm.d.ts",
@@ -25,7 +26,7 @@
25
26
  "types": "./index.esm.d.ts",
26
27
  "import": "./index.esm.js",
27
28
  "require": "./index.cjs.js",
28
- "default": "./index.cjs.js"
29
+ "default": "./index.esm.js"
29
30
  }
30
31
  }
31
32
  }
@@ -1,29 +1,23 @@
1
- import { ClientKeyShare, DynamicWalletClient, Ed25519KeygenResult, ThresholdSignatureScheme } from '@dynamic-labs-wallet/browser';
2
- import { Transaction, VersionedTransaction } from '@solana/web3.js';
1
+ import { DynamicWalletClient, DynamicWalletClientProps, Ed25519KeygenResult, ThresholdSignatureScheme } from '@dynamic-labs-wallet/browser';
3
2
  export declare class DynamicSvmWalletClient extends DynamicWalletClient {
4
- readonly chainName = "SOL";
3
+ readonly chainName = "SVM";
5
4
  accountAddress?: string;
6
- constructor({ environmentId, authToken, baseApiUrl, baseMPCRelayApiUrl, }: {
7
- environmentId: string;
8
- authToken: string;
9
- baseApiUrl?: string;
10
- baseMPCRelayApiUrl?: string;
11
- });
5
+ constructor({ environmentId, authToken, baseApiUrl, baseMPCRelayApiUrl, storageKey, debug, featureFlags, authMode, sdkVersion, }: DynamicWalletClientProps);
12
6
  /**
13
7
  * Creates a wallet account on the Solana chain
14
8
  *
15
9
  * @param thresholdSignatureScheme The threshold signature scheme to use
16
10
  * @returns The account address, public key hex, raw public key, and client key shares
17
11
  */
18
- createWalletAccount({ thresholdSignatureScheme, password, }: {
12
+ createWalletAccount({ thresholdSignatureScheme, password, signedSessionId, }: {
19
13
  thresholdSignatureScheme: ThresholdSignatureScheme;
20
14
  password?: string;
15
+ signedSessionId: string;
21
16
  }): Promise<{
22
17
  accountAddress: string;
23
- rawPublicKey: Uint8Array;
24
- clientKeyShares: ClientKeyShare[];
18
+ rawPublicKey: Uint8Array | string;
25
19
  }>;
26
- deriveAccountAddress(rawPublicKey: Uint8Array): Promise<{
20
+ deriveAccountAddress(rawPublicKey: string | Uint8Array): Promise<{
27
21
  accountAddress: string;
28
22
  }>;
29
23
  /**
@@ -33,16 +27,23 @@ export declare class DynamicSvmWalletClient extends DynamicWalletClient {
33
27
  * @param accountAddress Solana address (base58 encoded)
34
28
  * @param password The password for encrypted backup shares
35
29
  */
36
- signMessage({ message, accountAddress, password, }: {
30
+ signMessage({ message, accountAddress, password, signedSessionId, mfaToken, }: {
37
31
  message: string;
38
32
  accountAddress: string;
39
33
  password?: string;
34
+ signedSessionId: string;
35
+ mfaToken?: string;
40
36
  }): Promise<string>;
41
- signTransaction({ senderAddress, transaction, password, }: {
37
+ signTransaction({ senderAddress, transaction, password, signedSessionId, mfaToken, chainId, }: {
42
38
  senderAddress: string;
43
- transaction: VersionedTransaction | Transaction;
39
+ transaction: string;
44
40
  password?: string;
45
- }): Promise<VersionedTransaction | Transaction>;
41
+ signedSessionId: string;
42
+ mfaToken?: string;
43
+ chainId?: string;
44
+ }): Promise<string>;
45
+ private prepareTransactionForSigning;
46
+ private buildSignParams;
46
47
  /**
47
48
  * Exports the private key for a given account address
48
49
  *
@@ -50,11 +51,12 @@ export declare class DynamicSvmWalletClient extends DynamicWalletClient {
50
51
  * @param password The password for encrypted backup shares
51
52
  * @returns The private key
52
53
  */
53
- exportPrivateKey({ accountAddress, displayContainer, password, }: {
54
+ exportPrivateKey({ accountAddress, password, signedSessionId, mfaToken, }: {
54
55
  accountAddress: string;
55
- displayContainer: HTMLElement;
56
56
  password?: string;
57
- }): Promise<void>;
57
+ signedSessionId: string;
58
+ mfaToken?: string;
59
+ }): Promise<string>;
58
60
  /**
59
61
  * Exports the private key for a given account address
60
62
  *
@@ -85,17 +87,17 @@ export declare class DynamicSvmWalletClient extends DynamicWalletClient {
85
87
  * @param password The password for encrypted backup shares
86
88
  * @returns The account address, raw public key, and client key shares
87
89
  */
88
- importPrivateKey({ privateKey, chainName, thresholdSignatureScheme, password, onError, }: {
90
+ importPrivateKey({ privateKey, chainName, thresholdSignatureScheme, password, onError, signedSessionId, }: {
89
91
  privateKey: string;
90
92
  chainName: string;
91
93
  thresholdSignatureScheme: ThresholdSignatureScheme;
92
94
  password?: string;
93
95
  onError?: (error: Error) => void;
96
+ signedSessionId: string;
94
97
  }): Promise<{
95
98
  accountAddress: string;
96
99
  rawPublicKey: Uint8Array | undefined;
97
- clientKeyShares: ClientKeyShare[];
98
100
  }>;
99
101
  getSvmWallets(): Promise<any>;
100
102
  }
101
- //# sourceMappingURL=svm.d.ts.map
103
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/svm/client.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export * from './svm';
1
+ export * from './client';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svm/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svm/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"svm.d.ts","sourceRoot":"","sources":["../../src/svm/svm.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,EAGzB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAEL,WAAW,EACX,oBAAoB,EAErB,MAAM,iBAAiB,CAAC;AAIzB,qBAAa,sBAAuB,SAAQ,mBAAmB;IAC7D,QAAQ,CAAC,SAAS,SAAS;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;gBAEZ,EACV,aAAa,EACb,SAAS,EACT,UAAU,EACV,kBAAkB,GACnB,EAAE;QACD,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC7B;IASD;;;;;OAKG;IACG,mBAAmB,CAAC,EACxB,wBAAwB,EACxB,QAAoB,GACrB,EAAE;QACD,wBAAwB,EAAE,wBAAwB,CAAC;QACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC;QACV,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,UAAU,CAAC;QACzB,eAAe,EAAE,cAAc,EAAE,CAAC;KACnC,CAAC;IA0DI,oBAAoB,CAAC,YAAY,EAAE,UAAU;;;IAOnD;;;;;;OAMG;IACG,WAAW,CAAC,EAChB,OAAO,EACP,cAAc,EACd,QAAoB,GACrB,EAAE;QACD,OAAO,EAAE,MAAM,CAAC;QAChB,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB;IA2BK,eAAe,CAAC,EACpB,aAAa,EACb,WAAW,EACX,QAAoB,GACrB,EAAE;QACD,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,oBAAoB,GAAG,WAAW,CAAC;QAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,oBAAoB,GAAG,WAAW,CAAC;IAgD/C;;;;;;OAMG;IACG,gBAAgB,CAAC,EACrB,cAAc,EACd,gBAAgB,EAChB,QAAoB,GACrB,EAAE;QACD,cAAc,EAAE,MAAM,CAAC;QACvB,gBAAgB,EAAE,WAAW,CAAC;QAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB;IAyBD;;;;;OAKG;IACG,uBAAuB,CAAC,EAC5B,SAAS,EACT,cAAc,GACf,EAAE;QACD,SAAS,EAAE,mBAAmB,EAAE,CAAC;QACjC,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB;;;IASD;;;;;OAKG;IACH,yBAAyB,CAAC,UAAU,EAAE,MAAM;IAM5C,0BAA0B,CAAC,UAAU,EAAE,MAAM;IAQ7C,eAAe,CAAC,SAAS,EAAE,UAAU,GAAG,MAAM;IAI9C;;;;;;;;OAQG;IACG,gBAAgB,CAAC,EACrB,UAAU,EACV,SAAS,EACT,wBAAwB,EACxB,QAAoB,EACpB,OAAO,GACR,EAAE;QACD,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,wBAAwB,EAAE,wBAAwB,CAAC;QACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;KAClC,GAAG,OAAO,CAAC;QACV,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,UAAU,GAAG,SAAS,CAAC;QACrC,eAAe,EAAE,cAAc,EAAE,CAAC;KACnC,CAAC;IA6DI,aAAa;CAOpB"}