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