@dynamic-labs-wallet/sui 0.0.0-pr384.1 → 0.0.0-pr506.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 +22 -9
- package/index.esm.js +23 -10
- package/package.json +4 -4
- package/src/client/client.d.ts +3 -2
- package/src/client/client.d.ts.map +1 -1
package/index.cjs.js
CHANGED
|
@@ -50,11 +50,16 @@ class DynamicSuiWalletClient extends browser.DynamicWalletClient {
|
|
|
50
50
|
onError,
|
|
51
51
|
onCeremonyComplete: (accountAddress, walletId)=>{
|
|
52
52
|
// update wallet map
|
|
53
|
+
const chainConfig = browser.getMPCChainConfig(this.chainName);
|
|
53
54
|
this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress] || {}, {
|
|
54
55
|
accountAddress: accountAddress,
|
|
55
56
|
walletId,
|
|
56
57
|
chainName: this.chainName,
|
|
57
58
|
thresholdSignatureScheme,
|
|
59
|
+
derivationPath: JSON.stringify(Object.fromEntries(chainConfig.derivationPath.map((value, index)=>[
|
|
60
|
+
index,
|
|
61
|
+
value
|
|
62
|
+
]))),
|
|
58
63
|
clientKeySharesBackupInfo: browser.getClientKeyShareBackupInfo()
|
|
59
64
|
});
|
|
60
65
|
this.logger.debug('walletMap updated for wallet', {
|
|
@@ -77,10 +82,11 @@ class DynamicSuiWalletClient extends browser.DynamicWalletClient {
|
|
|
77
82
|
});
|
|
78
83
|
// Update client key shares in wallet map
|
|
79
84
|
// warning: this might result in race condition if `onCeremonyComplete` executes at the same time
|
|
80
|
-
await this.
|
|
85
|
+
await this.setClientKeySharesToStorage({
|
|
81
86
|
accountAddress,
|
|
82
87
|
clientKeyShares,
|
|
83
|
-
overwriteOrMerge: 'overwrite'
|
|
88
|
+
overwriteOrMerge: 'overwrite',
|
|
89
|
+
chainName: this.chainName
|
|
84
90
|
});
|
|
85
91
|
await this.storeEncryptedBackupByWalletWithRetry({
|
|
86
92
|
accountAddress,
|
|
@@ -114,8 +120,9 @@ class DynamicSuiWalletClient extends browser.DynamicWalletClient {
|
|
|
114
120
|
try {
|
|
115
121
|
// get public key from keyshare
|
|
116
122
|
// TODO: handle this more gracefully from the client key shares if possible
|
|
117
|
-
const clientKeyShares = await this.
|
|
118
|
-
accountAddress
|
|
123
|
+
const clientKeyShares = await this.getClientKeySharesFromStorage({
|
|
124
|
+
accountAddress,
|
|
125
|
+
chainName: this.chainName
|
|
119
126
|
});
|
|
120
127
|
const rawPublicKey = await this.getRawPublicKeyFromClientKeyShares({
|
|
121
128
|
chainName: this.chainName,
|
|
@@ -291,7 +298,7 @@ class DynamicSuiWalletClient extends browser.DynamicWalletClient {
|
|
|
291
298
|
* @param thresholdSignatureScheme The threshold signature scheme to use
|
|
292
299
|
* @param password The password for encrypted backup shares
|
|
293
300
|
* @returns The account address, raw public key, and client key shares
|
|
294
|
-
*/ async importPrivateKey({ privateKey, chainName, thresholdSignatureScheme, password = undefined, signedSessionId, onError }) {
|
|
301
|
+
*/ async importPrivateKey({ privateKey, chainName, thresholdSignatureScheme, password = undefined, signedSessionId, onError, publicAddressCheck }) {
|
|
295
302
|
try {
|
|
296
303
|
let ceremonyCeremonyCompleteResolver;
|
|
297
304
|
const ceremonyCompletePromise = new Promise((resolve)=>{
|
|
@@ -299,6 +306,9 @@ class DynamicSuiWalletClient extends browser.DynamicWalletClient {
|
|
|
299
306
|
});
|
|
300
307
|
const { privateKey: formattedPrivateKey, privateKeyBytes } = await this.convertSuiPrivateKey(privateKey);
|
|
301
308
|
const publicKey = this.getPublicKeyFromPrivateKey(privateKeyBytes);
|
|
309
|
+
if (publicAddressCheck && publicKey !== publicAddressCheck) {
|
|
310
|
+
throw new Error(`Public address mismatch: derived address ${publicKey} !== public address ${publicAddressCheck}`);
|
|
311
|
+
}
|
|
302
312
|
const { rawPublicKey, clientKeyShares } = await this.importRawPrivateKey({
|
|
303
313
|
chainName,
|
|
304
314
|
privateKey: formattedPrivateKey,
|
|
@@ -336,10 +346,11 @@ class DynamicSuiWalletClient extends browser.DynamicWalletClient {
|
|
|
336
346
|
}
|
|
337
347
|
// Update client key shares in wallet map
|
|
338
348
|
// warning: this might result in race condition if `onCeremonyComplete` executes at the same time
|
|
339
|
-
await this.
|
|
349
|
+
await this.setClientKeySharesToStorage({
|
|
340
350
|
accountAddress,
|
|
341
351
|
clientKeyShares,
|
|
342
|
-
overwriteOrMerge: 'overwrite'
|
|
352
|
+
overwriteOrMerge: 'overwrite',
|
|
353
|
+
chainName: this.chainName
|
|
343
354
|
});
|
|
344
355
|
await this.storeEncryptedBackupByWalletWithRetry({
|
|
345
356
|
accountAddress,
|
|
@@ -388,17 +399,19 @@ class DynamicSuiWalletClient extends browser.DynamicWalletClient {
|
|
|
388
399
|
const suiWallets = wallets.filter((wallet)=>wallet.chainName === 'sui');
|
|
389
400
|
return suiWallets;
|
|
390
401
|
}
|
|
391
|
-
constructor({ environmentId, authToken, baseApiUrl, baseMPCRelayApiUrl, storageKey, debug, featureFlags, authMode = browser.AuthMode.HEADER, sdkVersion }){
|
|
402
|
+
constructor({ environmentId, authToken, backupServiceAuthToken, baseApiUrl, baseMPCRelayApiUrl, storageKey, debug, featureFlags, authMode = browser.AuthMode.HEADER, sdkVersion, forwardMPCClient }){
|
|
392
403
|
super({
|
|
393
404
|
environmentId,
|
|
394
405
|
authToken,
|
|
406
|
+
backupServiceAuthToken,
|
|
395
407
|
baseApiUrl,
|
|
396
408
|
baseMPCRelayApiUrl,
|
|
397
409
|
storageKey,
|
|
398
410
|
debug,
|
|
399
411
|
featureFlags,
|
|
400
412
|
authMode,
|
|
401
|
-
sdkVersion
|
|
413
|
+
sdkVersion,
|
|
414
|
+
forwardMPCClient
|
|
402
415
|
}), this.chainName = 'SUI';
|
|
403
416
|
}
|
|
404
417
|
}
|
package/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DynamicWalletClient, getClientKeyShareBackupInfo, ERROR_KEYGEN_FAILED, ERROR_CREATE_WALLET_ACCOUNT,
|
|
1
|
+
import { DynamicWalletClient, getMPCChainConfig, getClientKeyShareBackupInfo, ERROR_KEYGEN_FAILED, ERROR_CREATE_WALLET_ACCOUNT, ERROR_VERIFY_MESSAGE_SIGNATURE, ERROR_VERIFY_TRANSACTION_SIGNATURE, ERROR_ACCOUNT_ADDRESS_REQUIRED, ERROR_SIGN_MESSAGE, ERROR_IMPORT_PRIVATE_KEY, ERROR_EXPORT_PRIVATE_KEY, AuthMode } from '@dynamic-labs-wallet/browser';
|
|
2
2
|
import { messageWithIntent, toSerializedSignature } from '@mysten/sui/cryptography';
|
|
3
3
|
import { Ed25519PublicKey, Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
|
|
4
4
|
import { verifyPersonalMessageSignature, verifyTransactionSignature } from '@mysten/sui/verify';
|
|
@@ -48,11 +48,16 @@ class DynamicSuiWalletClient extends DynamicWalletClient {
|
|
|
48
48
|
onError,
|
|
49
49
|
onCeremonyComplete: (accountAddress, walletId)=>{
|
|
50
50
|
// update wallet map
|
|
51
|
+
const chainConfig = getMPCChainConfig(this.chainName);
|
|
51
52
|
this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress] || {}, {
|
|
52
53
|
accountAddress: accountAddress,
|
|
53
54
|
walletId,
|
|
54
55
|
chainName: this.chainName,
|
|
55
56
|
thresholdSignatureScheme,
|
|
57
|
+
derivationPath: JSON.stringify(Object.fromEntries(chainConfig.derivationPath.map((value, index)=>[
|
|
58
|
+
index,
|
|
59
|
+
value
|
|
60
|
+
]))),
|
|
56
61
|
clientKeySharesBackupInfo: getClientKeyShareBackupInfo()
|
|
57
62
|
});
|
|
58
63
|
this.logger.debug('walletMap updated for wallet', {
|
|
@@ -75,10 +80,11 @@ class DynamicSuiWalletClient extends DynamicWalletClient {
|
|
|
75
80
|
});
|
|
76
81
|
// Update client key shares in wallet map
|
|
77
82
|
// warning: this might result in race condition if `onCeremonyComplete` executes at the same time
|
|
78
|
-
await this.
|
|
83
|
+
await this.setClientKeySharesToStorage({
|
|
79
84
|
accountAddress,
|
|
80
85
|
clientKeyShares,
|
|
81
|
-
overwriteOrMerge: 'overwrite'
|
|
86
|
+
overwriteOrMerge: 'overwrite',
|
|
87
|
+
chainName: this.chainName
|
|
82
88
|
});
|
|
83
89
|
await this.storeEncryptedBackupByWalletWithRetry({
|
|
84
90
|
accountAddress,
|
|
@@ -112,8 +118,9 @@ class DynamicSuiWalletClient extends DynamicWalletClient {
|
|
|
112
118
|
try {
|
|
113
119
|
// get public key from keyshare
|
|
114
120
|
// TODO: handle this more gracefully from the client key shares if possible
|
|
115
|
-
const clientKeyShares = await this.
|
|
116
|
-
accountAddress
|
|
121
|
+
const clientKeyShares = await this.getClientKeySharesFromStorage({
|
|
122
|
+
accountAddress,
|
|
123
|
+
chainName: this.chainName
|
|
117
124
|
});
|
|
118
125
|
const rawPublicKey = await this.getRawPublicKeyFromClientKeyShares({
|
|
119
126
|
chainName: this.chainName,
|
|
@@ -289,7 +296,7 @@ class DynamicSuiWalletClient extends DynamicWalletClient {
|
|
|
289
296
|
* @param thresholdSignatureScheme The threshold signature scheme to use
|
|
290
297
|
* @param password The password for encrypted backup shares
|
|
291
298
|
* @returns The account address, raw public key, and client key shares
|
|
292
|
-
*/ async importPrivateKey({ privateKey, chainName, thresholdSignatureScheme, password = undefined, signedSessionId, onError }) {
|
|
299
|
+
*/ async importPrivateKey({ privateKey, chainName, thresholdSignatureScheme, password = undefined, signedSessionId, onError, publicAddressCheck }) {
|
|
293
300
|
try {
|
|
294
301
|
let ceremonyCeremonyCompleteResolver;
|
|
295
302
|
const ceremonyCompletePromise = new Promise((resolve)=>{
|
|
@@ -297,6 +304,9 @@ class DynamicSuiWalletClient extends DynamicWalletClient {
|
|
|
297
304
|
});
|
|
298
305
|
const { privateKey: formattedPrivateKey, privateKeyBytes } = await this.convertSuiPrivateKey(privateKey);
|
|
299
306
|
const publicKey = this.getPublicKeyFromPrivateKey(privateKeyBytes);
|
|
307
|
+
if (publicAddressCheck && publicKey !== publicAddressCheck) {
|
|
308
|
+
throw new Error(`Public address mismatch: derived address ${publicKey} !== public address ${publicAddressCheck}`);
|
|
309
|
+
}
|
|
300
310
|
const { rawPublicKey, clientKeyShares } = await this.importRawPrivateKey({
|
|
301
311
|
chainName,
|
|
302
312
|
privateKey: formattedPrivateKey,
|
|
@@ -334,10 +344,11 @@ class DynamicSuiWalletClient extends DynamicWalletClient {
|
|
|
334
344
|
}
|
|
335
345
|
// Update client key shares in wallet map
|
|
336
346
|
// warning: this might result in race condition if `onCeremonyComplete` executes at the same time
|
|
337
|
-
await this.
|
|
347
|
+
await this.setClientKeySharesToStorage({
|
|
338
348
|
accountAddress,
|
|
339
349
|
clientKeyShares,
|
|
340
|
-
overwriteOrMerge: 'overwrite'
|
|
350
|
+
overwriteOrMerge: 'overwrite',
|
|
351
|
+
chainName: this.chainName
|
|
341
352
|
});
|
|
342
353
|
await this.storeEncryptedBackupByWalletWithRetry({
|
|
343
354
|
accountAddress,
|
|
@@ -386,17 +397,19 @@ class DynamicSuiWalletClient extends DynamicWalletClient {
|
|
|
386
397
|
const suiWallets = wallets.filter((wallet)=>wallet.chainName === 'sui');
|
|
387
398
|
return suiWallets;
|
|
388
399
|
}
|
|
389
|
-
constructor({ environmentId, authToken, baseApiUrl, baseMPCRelayApiUrl, storageKey, debug, featureFlags, authMode = AuthMode.HEADER, sdkVersion }){
|
|
400
|
+
constructor({ environmentId, authToken, backupServiceAuthToken, baseApiUrl, baseMPCRelayApiUrl, storageKey, debug, featureFlags, authMode = AuthMode.HEADER, sdkVersion, forwardMPCClient }){
|
|
390
401
|
super({
|
|
391
402
|
environmentId,
|
|
392
403
|
authToken,
|
|
404
|
+
backupServiceAuthToken,
|
|
393
405
|
baseApiUrl,
|
|
394
406
|
baseMPCRelayApiUrl,
|
|
395
407
|
storageKey,
|
|
396
408
|
debug,
|
|
397
409
|
featureFlags,
|
|
398
410
|
authMode,
|
|
399
|
-
sdkVersion
|
|
411
|
+
sdkVersion,
|
|
412
|
+
forwardMPCClient
|
|
400
413
|
}), this.chainName = 'SUI';
|
|
401
414
|
}
|
|
402
415
|
}
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs-wallet/sui",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-pr506.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@dynamic-labs-wallet/browser": "0.0.0-
|
|
7
|
+
"@dynamic-labs-wallet/browser": "0.0.0-pr506.0",
|
|
8
8
|
"@mysten/sui": "1.26.0",
|
|
9
9
|
"@noble/hashes": "1.7.1",
|
|
10
|
-
"
|
|
11
|
-
"
|
|
10
|
+
"bech32-converting": "^1.0.9",
|
|
11
|
+
"@dynamic-labs/sdk-api-core": "^0.0.801"
|
|
12
12
|
},
|
|
13
13
|
"publishConfig": {
|
|
14
14
|
"access": "public"
|
package/src/client/client.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { type ClientKeyShare, DynamicWalletClient, type DynamicWalletClientProps
|
|
|
2
2
|
import type { SignMessageContext } from '@dynamic-labs/sdk-api-core';
|
|
3
3
|
export declare class DynamicSuiWalletClient extends DynamicWalletClient {
|
|
4
4
|
readonly chainName = "SUI";
|
|
5
|
-
constructor({ environmentId, authToken, baseApiUrl, baseMPCRelayApiUrl, storageKey, debug, featureFlags, authMode, sdkVersion, }: DynamicWalletClientProps);
|
|
5
|
+
constructor({ environmentId, authToken, backupServiceAuthToken, baseApiUrl, baseMPCRelayApiUrl, storageKey, debug, featureFlags, authMode, sdkVersion, forwardMPCClient, }: DynamicWalletClientProps);
|
|
6
6
|
createWalletAccount({ thresholdSignatureScheme, password, onError, signedSessionId, }: {
|
|
7
7
|
thresholdSignatureScheme: ThresholdSignatureScheme;
|
|
8
8
|
password?: string;
|
|
@@ -73,13 +73,14 @@ export declare class DynamicSuiWalletClient extends DynamicWalletClient {
|
|
|
73
73
|
* @param password The password for encrypted backup shares
|
|
74
74
|
* @returns The account address, raw public key, and client key shares
|
|
75
75
|
*/
|
|
76
|
-
importPrivateKey({ privateKey, chainName, thresholdSignatureScheme, password, signedSessionId, onError, }: {
|
|
76
|
+
importPrivateKey({ privateKey, chainName, thresholdSignatureScheme, password, signedSessionId, onError, publicAddressCheck, }: {
|
|
77
77
|
privateKey: string;
|
|
78
78
|
chainName: string;
|
|
79
79
|
thresholdSignatureScheme: ThresholdSignatureScheme;
|
|
80
80
|
password?: string;
|
|
81
81
|
signedSessionId: string;
|
|
82
82
|
onError?: (error: Error) => void;
|
|
83
|
+
publicAddressCheck?: string;
|
|
83
84
|
}): Promise<{
|
|
84
85
|
accountAddress: string;
|
|
85
86
|
rawPublicKey: string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACnB,mBAAmB,EACnB,KAAK,wBAAwB,EAW7B,KAAK,wBAAwB,EAC9B,MAAM,8BAA8B,CAAC;AAWtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAErE,qBAAa,sBAAuB,SAAQ,mBAAmB;IAC7D,QAAQ,CAAC,SAAS,SAAS;gBAEf,EACV,aAAa,EACb,SAAS,EACT,UAAU,EACV,kBAAkB,EAClB,UAAU,EACV,KAAK,EACL,YAAY,EACZ,QAA0B,EAC1B,UAAU,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"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"}
|