@dynamic-labs-wallet/browser 1.0.91 → 1.0.93
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 +203 -48
- package/index.esm.js +205 -51
- package/package.json +4 -3
- package/src/client.d.ts +44 -9
- package/src/client.d.ts.map +1 -1
- package/src/ed25519.d.ts +17 -0
- package/src/ed25519.d.ts.map +1 -0
- package/src/index.d.ts +1 -0
- package/src/index.d.ts.map +1 -1
- package/src/mpc/mpc.d.ts +13 -6
- package/src/mpc/mpc.d.ts.map +1 -1
- package/src/mpc/types.d.ts +5 -5
- package/src/mpc/types.d.ts.map +1 -1
- package/src/types.d.ts +9 -1
- package/src/types.d.ts.map +1 -1
package/index.cjs
CHANGED
|
@@ -9,6 +9,8 @@ var loadArgon2idWasm = require('argon2id');
|
|
|
9
9
|
var axios = require('axios');
|
|
10
10
|
var gte = require('semver/functions/gte');
|
|
11
11
|
var PQueue = require('p-queue');
|
|
12
|
+
var ed25519 = require('@noble/curves/ed25519');
|
|
13
|
+
var utils = require('@noble/curves/abstract/utils');
|
|
12
14
|
|
|
13
15
|
function _extends() {
|
|
14
16
|
_extends = Object.assign || function assign(target) {
|
|
@@ -78,12 +80,17 @@ function _extends() {
|
|
|
78
80
|
return undefined;
|
|
79
81
|
}
|
|
80
82
|
};
|
|
81
|
-
const getMPCSignatureScheme = ({ signingAlgorithm, baseRelayUrl = core.MPC_RELAY_PROD_API_URL })=>{
|
|
83
|
+
const getMPCSignatureScheme = ({ signingAlgorithm, baseRelayUrl = core.MPC_RELAY_PROD_API_URL, variant = core.DEFAULT_ED25519_VARIANT })=>{
|
|
82
84
|
switch(signingAlgorithm){
|
|
83
85
|
case primitives.SigningAlgorithm.ECDSA:
|
|
84
86
|
return new web.Ecdsa(baseRelayUrl);
|
|
85
87
|
case primitives.SigningAlgorithm.ED25519:
|
|
86
|
-
|
|
88
|
+
// `Ed25519` (non-exportable) and `ExportableEd25519` are distinct protocol
|
|
89
|
+
// classes with incompatible keyshare formats. Downstream `instanceof`
|
|
90
|
+
// dispatch (createWalletAccount / importPrivateKey / derive*) always tests
|
|
91
|
+
// `ExportableEd25519` before `Ed25519` — most-specific-first — so it stays
|
|
92
|
+
// correct even if `ExportableEd25519` were a subclass of `Ed25519`.
|
|
93
|
+
return variant === 'ed25519Standard' ? new web.Ed25519(baseRelayUrl) : new web.ExportableEd25519(baseRelayUrl);
|
|
87
94
|
case primitives.SigningAlgorithm.BIP340:
|
|
88
95
|
return new web.BIP340(baseRelayUrl);
|
|
89
96
|
case primitives.SigningAlgorithm.EDBLS12_377:
|
|
@@ -92,11 +99,12 @@ const getMPCSignatureScheme = ({ signingAlgorithm, baseRelayUrl = core.MPC_RELAY
|
|
|
92
99
|
throw new Error(`Unsupported signing algorithm: ${signingAlgorithm}`);
|
|
93
100
|
}
|
|
94
101
|
};
|
|
95
|
-
const getMPCSigner = ({ chainName, baseRelayUrl, bitcoinConfig })=>{
|
|
102
|
+
const getMPCSigner = ({ chainName, baseRelayUrl, bitcoinConfig, variant })=>{
|
|
96
103
|
const chainConfig = core.getMPCChainConfig(chainName, bitcoinConfig);
|
|
97
104
|
const signatureScheme = getMPCSignatureScheme({
|
|
98
105
|
signingAlgorithm: chainConfig.signingAlgorithm,
|
|
99
|
-
baseRelayUrl
|
|
106
|
+
baseRelayUrl,
|
|
107
|
+
variant
|
|
100
108
|
});
|
|
101
109
|
return signatureScheme;
|
|
102
110
|
};
|
|
@@ -3377,28 +3385,34 @@ class DynamicWalletClient {
|
|
|
3377
3385
|
}, this.getTraceContext(traceContext))));
|
|
3378
3386
|
throw new Error('Timed out waiting for wallet creation ceremony to complete');
|
|
3379
3387
|
}
|
|
3380
|
-
async clientInitializeKeyGen({ chainName, thresholdSignatureScheme, bitcoinConfig }) {
|
|
3388
|
+
async clientInitializeKeyGen({ chainName, thresholdSignatureScheme, bitcoinConfig, variant }) {
|
|
3381
3389
|
// Get the mpc signer
|
|
3382
3390
|
const mpcSigner = getMPCSigner({
|
|
3383
3391
|
chainName,
|
|
3384
3392
|
baseRelayUrl: this.baseMPCRelayApiUrl,
|
|
3385
|
-
bitcoinConfig
|
|
3393
|
+
bitcoinConfig,
|
|
3394
|
+
variant
|
|
3386
3395
|
});
|
|
3387
3396
|
const clientThreshold = core.getClientThreshold(thresholdSignatureScheme);
|
|
3388
3397
|
const keygenInitResults = await Promise.all(Array(clientThreshold).fill(null).map(()=>mpcSigner.initKeygen()));
|
|
3389
3398
|
return keygenInitResults;
|
|
3390
3399
|
}
|
|
3391
|
-
async derivePublicKey({ chainName, keyShare, derivationPath, bitcoinConfig }) {
|
|
3400
|
+
async derivePublicKey({ chainName, keyShare, derivationPath, bitcoinConfig, variant }) {
|
|
3392
3401
|
const mpcSigner = getMPCSigner({
|
|
3393
3402
|
chainName,
|
|
3394
3403
|
baseRelayUrl: this.baseMPCRelayApiUrl,
|
|
3395
|
-
bitcoinConfig
|
|
3404
|
+
bitcoinConfig,
|
|
3405
|
+
variant
|
|
3396
3406
|
});
|
|
3397
3407
|
let publicKey;
|
|
3398
3408
|
if (mpcSigner instanceof web.Ecdsa) {
|
|
3399
3409
|
publicKey = await mpcSigner.derivePubkey(keyShare, derivationPath);
|
|
3400
3410
|
} else if (mpcSigner instanceof web.ExportableEd25519) {
|
|
3401
3411
|
publicKey = await mpcSigner.getPubkey(keyShare);
|
|
3412
|
+
} else if (mpcSigner instanceof web.Ed25519) {
|
|
3413
|
+
// Non-exportable Ed25519 (raw-scalar-imported wallets). Derivation is not
|
|
3414
|
+
// standardized for ed25519, so the root pubkey is taken with an undefined path.
|
|
3415
|
+
publicKey = await mpcSigner.derivePubkey(keyShare, derivationPath);
|
|
3402
3416
|
} else if (mpcSigner instanceof web.BIP340) {
|
|
3403
3417
|
publicKey = await mpcSigner.deriveTweakPubkey(keyShare, derivationPath);
|
|
3404
3418
|
}
|
|
@@ -3762,7 +3776,7 @@ class DynamicWalletClient {
|
|
|
3762
3776
|
shouldRetry: (error)=>!isNonRetryableCeremonyError(error)
|
|
3763
3777
|
});
|
|
3764
3778
|
}
|
|
3765
|
-
async runImportRawPrivateKeyAttempt({ chainName, privateKey, thresholdSignatureScheme, bitcoinConfig, onError, onCeremonyComplete, traceContext, legacyWalletId, password, signedSessionId }) {
|
|
3779
|
+
async runImportRawPrivateKeyAttempt({ chainName, privateKey, thresholdSignatureScheme, bitcoinConfig, onError, onCeremonyComplete, traceContext, legacyWalletId, password, signedSessionId, isRawScalarImport }) {
|
|
3766
3780
|
const dynamicRequestId = uuid.v4();
|
|
3767
3781
|
try {
|
|
3768
3782
|
this.assertPasswordRequired(password);
|
|
@@ -3770,15 +3784,21 @@ class DynamicWalletClient {
|
|
|
3770
3784
|
password,
|
|
3771
3785
|
signedSessionId
|
|
3772
3786
|
});
|
|
3787
|
+
// A raw-scalar import must run on the non-exportable `Ed25519` protocol for
|
|
3788
|
+
// the whole ceremony (init keygen, import, pubkey derivation) so the produced
|
|
3789
|
+
// key shares are consistent. Non-raw imports keep the default ('ed25519Exportable').
|
|
3790
|
+
const variant = isRawScalarImport ? 'ed25519Standard' : undefined;
|
|
3773
3791
|
const mpcSigner = getMPCSigner({
|
|
3774
3792
|
chainName,
|
|
3775
3793
|
baseRelayUrl: this.baseMPCRelayApiUrl,
|
|
3776
|
-
bitcoinConfig
|
|
3794
|
+
bitcoinConfig,
|
|
3795
|
+
variant
|
|
3777
3796
|
});
|
|
3778
3797
|
const clientKeygenInitResults = await this.clientInitializeKeyGen({
|
|
3779
3798
|
chainName,
|
|
3780
3799
|
thresholdSignatureScheme,
|
|
3781
|
-
bitcoinConfig
|
|
3800
|
+
bitcoinConfig,
|
|
3801
|
+
variant
|
|
3782
3802
|
});
|
|
3783
3803
|
const clientKeygenIds = clientKeygenInitResults.map((result)=>result.keygenId);
|
|
3784
3804
|
this.logger.info('[DynamicWaasWalletClient] Client key generation initialized', _extends({
|
|
@@ -3796,7 +3816,9 @@ class DynamicWalletClient {
|
|
|
3796
3816
|
bitcoinConfig,
|
|
3797
3817
|
onError,
|
|
3798
3818
|
onCeremonyComplete,
|
|
3799
|
-
legacyWalletId
|
|
3819
|
+
legacyWalletId,
|
|
3820
|
+
// Persist the protocol variant server-side so later sign/reshare read it back.
|
|
3821
|
+
variant
|
|
3800
3822
|
});
|
|
3801
3823
|
this.logger.info('[DynamicWaasWalletClient] Server key generation initialized', _extends({
|
|
3802
3824
|
roomId,
|
|
@@ -3814,7 +3836,9 @@ class DynamicWalletClient {
|
|
|
3814
3836
|
...serverKeygenIds,
|
|
3815
3837
|
...otherClientKeygenIds
|
|
3816
3838
|
];
|
|
3817
|
-
const importerKeygenResult =
|
|
3839
|
+
const importerKeygenResult = isRawScalarImport ? // uses the 32 bytes directly as the signing scalar instead of
|
|
3840
|
+
// SHA-512-expanding them as an RFC-8032 seed.
|
|
3841
|
+
await mpcSigner.importPrivateKeyImporter(roomId, threshold, privateKey, currentInit, otherKeyGenIds, true) : await mpcSigner.importPrivateKeyImporter(roomId, threshold, privateKey, currentInit, otherKeyGenIds);
|
|
3818
3842
|
return importerKeygenResult;
|
|
3819
3843
|
} else {
|
|
3820
3844
|
const recipientKeygenResult = await mpcSigner.importPrivateKeyRecipient(roomId, threshold, currentInit, [
|
|
@@ -3831,7 +3855,8 @@ class DynamicWalletClient {
|
|
|
3831
3855
|
chainName,
|
|
3832
3856
|
keyShare: clientKeygenResult,
|
|
3833
3857
|
derivationPath,
|
|
3834
|
-
bitcoinConfig
|
|
3858
|
+
bitcoinConfig,
|
|
3859
|
+
variant
|
|
3835
3860
|
});
|
|
3836
3861
|
this.logger.info('[DynamicWaasWalletClient] Completed import of raw private key', _extends({
|
|
3837
3862
|
rawPublicKey,
|
|
@@ -3866,6 +3891,8 @@ class DynamicWalletClient {
|
|
|
3866
3891
|
if (typeof message !== 'string') {
|
|
3867
3892
|
message = `0x${Buffer.from(message).toString('hex')}`;
|
|
3868
3893
|
}
|
|
3894
|
+
// Note: the server signing party (wallet-service) selects the ed25519
|
|
3895
|
+
// protocol variant from its own persisted EAC, so it is NOT threaded here.
|
|
3869
3896
|
const serializedContext = context ? JSON.parse(JSON.stringify(context, (_key, value)=>typeof value === 'bigint' ? value.toString() : value)) : undefined;
|
|
3870
3897
|
const useHttpTransport = this.featureFlags[core.FEATURE_FLAGS.ENABLE_HTTP_WAAS_TRANSPORT] === true && this.featureFlags[core.FEATURE_FLAGS.ENABLE_HTTP_WAAS_TRANSPORT_SIGNMESSAGE] === true;
|
|
3871
3898
|
const params = {
|
|
@@ -3929,7 +3956,7 @@ class DynamicWalletClient {
|
|
|
3929
3956
|
}
|
|
3930
3957
|
return signatureBytes;
|
|
3931
3958
|
}
|
|
3932
|
-
async forwardMPCClientSign({ chainName, message, roomId, keyShare, derivationPath, formattedMessage, dynamicRequestId, isFormatted, traceContext, bitcoinConfig }) {
|
|
3959
|
+
async forwardMPCClientSign({ chainName, message, roomId, keyShare, derivationPath, formattedMessage, dynamicRequestId, isFormatted, traceContext, bitcoinConfig, variant }) {
|
|
3933
3960
|
try {
|
|
3934
3961
|
const chainConfig = core.getMPCChainConfig(chainName, bitcoinConfig);
|
|
3935
3962
|
const signingAlgo = chainConfig.signingAlgorithm;
|
|
@@ -3942,7 +3969,7 @@ class DynamicWalletClient {
|
|
|
3942
3969
|
});
|
|
3943
3970
|
const tweak = this.convertTweakForBIP340(bitcoinConfig == null ? void 0 : bitcoinConfig.tweak);
|
|
3944
3971
|
this.logger.info('Forward MPC enabled, signing message with forward MPC (new)', this.getTraceContext(traceContext));
|
|
3945
|
-
const { signature: signatureBytes } = await this.apiClient.forwardMPCClient.signMessage({
|
|
3972
|
+
const { signature: signatureBytes } = await this.apiClient.forwardMPCClient.signMessage(_extends({
|
|
3946
3973
|
keyshare: keyShare,
|
|
3947
3974
|
message: messageToSign,
|
|
3948
3975
|
relayDomain: this.baseMPCRelayApiUrl || '',
|
|
@@ -3954,7 +3981,9 @@ class DynamicWalletClient {
|
|
|
3954
3981
|
traceContext,
|
|
3955
3982
|
userId: this.userId,
|
|
3956
3983
|
environmentId: this.environmentId
|
|
3957
|
-
}
|
|
3984
|
+
}, variant === 'ed25519Standard' ? {
|
|
3985
|
+
ed25519Variant: 'standard'
|
|
3986
|
+
} : {}));
|
|
3958
3987
|
if (!(signatureBytes instanceof Uint8Array)) {
|
|
3959
3988
|
throw new TypeError(`Invalid signature format: expected Uint8Array, got ${typeof signatureBytes}`);
|
|
3960
3989
|
}
|
|
@@ -3974,15 +4003,22 @@ class DynamicWalletClient {
|
|
|
3974
4003
|
throw error;
|
|
3975
4004
|
}
|
|
3976
4005
|
}
|
|
3977
|
-
async clientSign({ chainName, message, roomId: initialRoomId, keyShare, derivationPath, isFormatted, dynamicRequestId, traceContext, bitcoinConfig, refreshRoom }) {
|
|
4006
|
+
async clientSign({ chainName, message, roomId: initialRoomId, keyShare, derivationPath, isFormatted, dynamicRequestId, traceContext, bitcoinConfig, variant, refreshRoom }) {
|
|
3978
4007
|
// Reassigned when forward MPC fails and we mint a fresh room for the
|
|
3979
4008
|
// relay-based fallback below.
|
|
3980
4009
|
let roomId = initialRoomId;
|
|
4010
|
+
// Non-exportable Ed25519 (raw-scalar import) derives its address at the
|
|
4011
|
+
// root — see derivePrivateKeyFromExport's identical guard. Unlike
|
|
4012
|
+
// ExportableEd25519 (which ignores this arg), Ed25519.sign() *applies* a
|
|
4013
|
+
// non-undefined path, so forwarding the wallet's stored derivation path
|
|
4014
|
+
// here would sign under a derived child key instead of the wallet's own.
|
|
4015
|
+
const effectiveDerivationPath = variant === 'ed25519Standard' ? undefined : derivationPath;
|
|
3981
4016
|
try {
|
|
3982
4017
|
const mpcSigner = getMPCSigner({
|
|
3983
4018
|
chainName,
|
|
3984
4019
|
baseRelayUrl: this.baseMPCRelayApiUrl,
|
|
3985
|
-
bitcoinConfig
|
|
4020
|
+
bitcoinConfig,
|
|
4021
|
+
variant
|
|
3986
4022
|
});
|
|
3987
4023
|
const formattedMessage = isFormatted ? new web.MessageHash(message) : formatMessage(chainName, message);
|
|
3988
4024
|
this.logger.debug('[DynamicWaasWalletClient] Starting client sign', _extends({
|
|
@@ -4006,12 +4042,13 @@ class DynamicWalletClient {
|
|
|
4006
4042
|
message,
|
|
4007
4043
|
roomId,
|
|
4008
4044
|
keyShare,
|
|
4009
|
-
derivationPath,
|
|
4045
|
+
derivationPath: effectiveDerivationPath,
|
|
4010
4046
|
formattedMessage,
|
|
4011
4047
|
dynamicRequestId,
|
|
4012
4048
|
isFormatted,
|
|
4013
4049
|
traceContext,
|
|
4014
|
-
bitcoinConfig
|
|
4050
|
+
bitcoinConfig,
|
|
4051
|
+
variant
|
|
4015
4052
|
});
|
|
4016
4053
|
} catch (error) {
|
|
4017
4054
|
const errorInfo = core.classifyForwardMpcError(error);
|
|
@@ -4055,7 +4092,7 @@ class DynamicWalletClient {
|
|
|
4055
4092
|
if (!('sign' in mpcSigner)) {
|
|
4056
4093
|
throw new TypeError(`Message signing is not supported for chain ${chainName} — use signTransaction instead`);
|
|
4057
4094
|
}
|
|
4058
|
-
const signature = await mpcSigner.sign(roomId, keyShare, messageToSign,
|
|
4095
|
+
const signature = await mpcSigner.sign(roomId, keyShare, messageToSign, effectiveDerivationPath, tweak);
|
|
4059
4096
|
return signature;
|
|
4060
4097
|
} catch (error) {
|
|
4061
4098
|
logError({
|
|
@@ -4139,7 +4176,8 @@ class DynamicWalletClient {
|
|
|
4139
4176
|
chainName,
|
|
4140
4177
|
localShares,
|
|
4141
4178
|
recordedKeygenIds,
|
|
4142
|
-
bitcoinConfig
|
|
4179
|
+
bitcoinConfig,
|
|
4180
|
+
variant: this.ed25519VariantForWallet(accountAddress)
|
|
4143
4181
|
});
|
|
4144
4182
|
localKeygenIds = comparison.localKeygenIds;
|
|
4145
4183
|
staleness = comparison.fresh ? 'fresh' : 'stale';
|
|
@@ -4205,11 +4243,14 @@ class DynamicWalletClient {
|
|
|
4205
4243
|
* the server recorded for the wallet's Dynamic backups. Shared by the
|
|
4206
4244
|
* stale-share heal (verifyAndRecoverStaleShare) and the backup preflight
|
|
4207
4245
|
* (ensureLocalSharesAreFresh).
|
|
4208
|
-
*/ async compareShareGenerations({ accountAddress, chainName, localShares, recordedKeygenIds, bitcoinConfig }) {
|
|
4246
|
+
*/ async compareShareGenerations({ accountAddress, chainName, localShares, recordedKeygenIds, bitcoinConfig, variant }) {
|
|
4209
4247
|
const mpcSigner = getMPCSigner({
|
|
4210
4248
|
chainName,
|
|
4211
4249
|
baseRelayUrl: this.baseMPCRelayApiUrl,
|
|
4212
|
-
bitcoinConfig: bitcoinConfig != null ? bitcoinConfig : this.getBitcoinConfigForChain(chainName, accountAddress)
|
|
4250
|
+
bitcoinConfig: bitcoinConfig != null ? bitcoinConfig : this.getBitcoinConfigForChain(chainName, accountAddress),
|
|
4251
|
+
// Raw-scalar (non-exportable Ed25519) wallets: build the matching signer so
|
|
4252
|
+
// getKeygenIdForShare deserializes the Ed25519 share (else "Invalid discriminant").
|
|
4253
|
+
variant
|
|
4213
4254
|
});
|
|
4214
4255
|
const localKeygenIds = await Promise.all(localShares.map((share)=>this.getKeygenIdForShare(mpcSigner, share)));
|
|
4215
4256
|
const recordedSet = new Set(recordedKeygenIds);
|
|
@@ -4367,6 +4408,7 @@ class DynamicWalletClient {
|
|
|
4367
4408
|
dynamicRequestId,
|
|
4368
4409
|
traceContext,
|
|
4369
4410
|
bitcoinConfig,
|
|
4411
|
+
variant: wallet.variant,
|
|
4370
4412
|
// On forward-MPC fallback, re-run the server sign with no roomId so a
|
|
4371
4413
|
// brand-new server-joined room is created for the relay ceremony.
|
|
4372
4414
|
refreshRoom: async ()=>{
|
|
@@ -4666,7 +4708,11 @@ class DynamicWalletClient {
|
|
|
4666
4708
|
const mpcSigner = getMPCSigner({
|
|
4667
4709
|
chainName,
|
|
4668
4710
|
baseRelayUrl: this.baseMPCRelayApiUrl,
|
|
4669
|
-
bitcoinConfig
|
|
4711
|
+
bitcoinConfig,
|
|
4712
|
+
// Raw-scalar (non-exportable Ed25519) wallets must refresh on the same
|
|
4713
|
+
// protocol their shares were created with, or the ceremony fails to
|
|
4714
|
+
// deserialize them ("Invalid discriminant").
|
|
4715
|
+
variant: this.ed25519VariantForWallet(accountAddress)
|
|
4670
4716
|
});
|
|
4671
4717
|
// Ensure client key shares exist before hitting the API
|
|
4672
4718
|
const clientKeyShares = await this.ensureClientShare(accountAddress);
|
|
@@ -4848,11 +4894,26 @@ class DynamicWalletClient {
|
|
|
4848
4894
|
}
|
|
4849
4895
|
return mpcSigner.exportID(share);
|
|
4850
4896
|
}
|
|
4851
|
-
|
|
4897
|
+
/**
|
|
4898
|
+
* The ed25519 protocol variant for an existing wallet, read from the wallet map
|
|
4899
|
+
* (sourced from `walletProperties.settings.variant`, persisted at import).
|
|
4900
|
+
*
|
|
4901
|
+
* It is per-wallet protocol metadata — like `thresholdSignatureScheme` or
|
|
4902
|
+
* `addressType` — and the single source of truth for which signer to build when
|
|
4903
|
+
* operating on a wallet's key shares. Wallets imported from a raw ed25519 scalar
|
|
4904
|
+
* (e.g. Fireblocks Embedded Wallets) are `'ed25519Standard'` (non-exportable `Ed25519`);
|
|
4905
|
+
* everything else is `undefined` → the default exportable protocol. Using the
|
|
4906
|
+
* wrong one fails to deserialize the key share with "Invalid discriminant".
|
|
4907
|
+
*/ ed25519VariantForWallet(accountAddress) {
|
|
4908
|
+
var _this_getWalletFromMap;
|
|
4909
|
+
return (_this_getWalletFromMap = this.getWalletFromMap(accountAddress)) == null ? void 0 : _this_getWalletFromMap.variant;
|
|
4910
|
+
}
|
|
4911
|
+
async getExportId({ chainName, clientKeyShare, bitcoinConfig, accountAddress }) {
|
|
4852
4912
|
const mpcSigner = getMPCSigner({
|
|
4853
4913
|
chainName,
|
|
4854
4914
|
baseRelayUrl: this.baseMPCRelayApiUrl,
|
|
4855
|
-
bitcoinConfig
|
|
4915
|
+
bitcoinConfig,
|
|
4916
|
+
variant: accountAddress ? this.ed25519VariantForWallet(accountAddress) : undefined
|
|
4856
4917
|
});
|
|
4857
4918
|
try {
|
|
4858
4919
|
const exportId = await this.getKeygenIdForShare(mpcSigner, clientKeyShare);
|
|
@@ -4900,7 +4961,8 @@ class DynamicWalletClient {
|
|
|
4900
4961
|
return this.getExportId({
|
|
4901
4962
|
chainName,
|
|
4902
4963
|
clientKeyShare,
|
|
4903
|
-
bitcoinConfig
|
|
4964
|
+
bitcoinConfig,
|
|
4965
|
+
accountAddress
|
|
4904
4966
|
});
|
|
4905
4967
|
}
|
|
4906
4968
|
/**
|
|
@@ -4941,7 +5003,8 @@ class DynamicWalletClient {
|
|
|
4941
5003
|
const existingClientKeygenIds = await Promise.all(existingClientKeyShares.map(async (keyShare)=>await this.getExportId({
|
|
4942
5004
|
chainName,
|
|
4943
5005
|
clientKeyShare: keyShare,
|
|
4944
|
-
bitcoinConfig
|
|
5006
|
+
bitcoinConfig,
|
|
5007
|
+
accountAddress
|
|
4945
5008
|
})));
|
|
4946
5009
|
return {
|
|
4947
5010
|
newClientInitKeygenResults,
|
|
@@ -4979,7 +5042,7 @@ class DynamicWalletClient {
|
|
|
4979
5042
|
}));
|
|
4980
5043
|
}
|
|
4981
5044
|
/** Reshare into a new 2/2 share set for the target signer; seed it to CKS
|
|
4982
|
-
* on their behalf via a single-use grant. Does not touch the caller's set. */ async reshareToNewSignerShareSet({ chainName, accountAddress, businessAccountId, signerType = 'endUser', targetSignerIdentity, password = undefined, signedSessionId }) {
|
|
5045
|
+
* on their behalf via a single-use grant. Does not touch the caller's set. */ async reshareToNewSignerShareSet({ chainName, accountAddress, businessAccountId, signerType = 'endUser', targetSignerIdentity, password = undefined, signedSessionId, elevatedAccessToken }) {
|
|
4983
5046
|
var _backup_keyShareIds;
|
|
4984
5047
|
const dynamicRequestId = uuid.v4();
|
|
4985
5048
|
const ceremonyStartTime = Date.now();
|
|
@@ -5010,7 +5073,8 @@ class DynamicWalletClient {
|
|
|
5010
5073
|
const existingClientKeygenId = await this.getExportId({
|
|
5011
5074
|
chainName,
|
|
5012
5075
|
clientKeyShare: existingClientShare,
|
|
5013
|
-
bitcoinConfig
|
|
5076
|
+
bitcoinConfig,
|
|
5077
|
+
accountAddress
|
|
5014
5078
|
});
|
|
5015
5079
|
// Gate matches internalRefresh/Reshare — SSE error rejects awaitTerminal.
|
|
5016
5080
|
let newShareSetId;
|
|
@@ -5042,6 +5106,7 @@ class DynamicWalletClient {
|
|
|
5042
5106
|
identifier: targetSignerIdentity.identifier,
|
|
5043
5107
|
identifierType: targetSignerIdentity.identifierType,
|
|
5044
5108
|
dynamicRequestId,
|
|
5109
|
+
elevatedAccessToken,
|
|
5045
5110
|
onError: ceremonyGate.onError,
|
|
5046
5111
|
onCeremonyComplete: ceremonyGate.onCeremonyComplete
|
|
5047
5112
|
});
|
|
@@ -5618,7 +5683,11 @@ class DynamicWalletClient {
|
|
|
5618
5683
|
const mpcSigner = getMPCSigner({
|
|
5619
5684
|
chainName,
|
|
5620
5685
|
baseRelayUrl: this.baseMPCRelayApiUrl,
|
|
5621
|
-
bitcoinConfig
|
|
5686
|
+
bitcoinConfig,
|
|
5687
|
+
// Raw-scalar (non-exportable Ed25519) wallets must reshare on the same
|
|
5688
|
+
// protocol their shares were created with, or the ceremony fails to
|
|
5689
|
+
// deserialize them ("Invalid discriminant").
|
|
5690
|
+
variant: this.ed25519VariantForWallet(accountAddress)
|
|
5622
5691
|
});
|
|
5623
5692
|
let existingReshareResults;
|
|
5624
5693
|
let newReshareResults;
|
|
@@ -5982,6 +6051,9 @@ class DynamicWalletClient {
|
|
|
5982
6051
|
if (mpcSigner instanceof web.ExportableEd25519) {
|
|
5983
6052
|
return new web.ExportableEd25519KeygenResult(extractedPubkey, secretShare);
|
|
5984
6053
|
}
|
|
6054
|
+
if (mpcSigner instanceof web.Ed25519) {
|
|
6055
|
+
return new web.Ed25519KeygenResult(extractedPubkey, secretShare);
|
|
6056
|
+
}
|
|
5985
6057
|
return new web.BIP340KeygenResult(extractedPubkey, secretShare);
|
|
5986
6058
|
}
|
|
5987
6059
|
async exportKey({ accountAddress, chainName, bitcoinConfig, password = undefined, signedSessionId, mfaToken, elevatedAccessToken, traceContext }) {
|
|
@@ -6012,13 +6084,15 @@ class DynamicWalletClient {
|
|
|
6012
6084
|
const mpcSigner = getMPCSigner({
|
|
6013
6085
|
chainName,
|
|
6014
6086
|
baseRelayUrl: this.baseMPCRelayApiUrl,
|
|
6015
|
-
bitcoinConfig
|
|
6087
|
+
bitcoinConfig,
|
|
6088
|
+
variant: wallet.variant
|
|
6016
6089
|
});
|
|
6017
6090
|
const reconstructedKeyShare = await this.getReconstructedKeyShare(accountAddress, mpcSigner);
|
|
6018
6091
|
const exportId = await this.getExportId({
|
|
6019
6092
|
chainName,
|
|
6020
6093
|
clientKeyShare: reconstructedKeyShare,
|
|
6021
|
-
bitcoinConfig
|
|
6094
|
+
bitcoinConfig,
|
|
6095
|
+
accountAddress: wallet.accountAddress
|
|
6022
6096
|
});
|
|
6023
6097
|
const data = await this.apiClient.exportKey({
|
|
6024
6098
|
walletId: wallet.walletId,
|
|
@@ -6161,20 +6235,35 @@ class DynamicWalletClient {
|
|
|
6161
6235
|
if (mpcSigner instanceof web.Ecdsa) {
|
|
6162
6236
|
return mpcSigner.derivePrivateKeyFromXpriv(keyExportRaw, derivationPath);
|
|
6163
6237
|
} else if (mpcSigner instanceof web.ExportableEd25519) {
|
|
6238
|
+
// ExportableEd25519's exportFullPrivateKey already returns the RFC-8032
|
|
6239
|
+
// form (hex of seed||pubkey); pass it straight through.
|
|
6164
6240
|
return keyExportRaw;
|
|
6241
|
+
} else if (mpcSigner instanceof web.Ed25519) {
|
|
6242
|
+
// Non-exportable Ed25519's exportFullPrivateKey returns an `spriv`
|
|
6243
|
+
// (extended private key), NOT a raw hex key — it must be parsed to the
|
|
6244
|
+
// actual private scalar. Returning the spriv verbatim makes the chain
|
|
6245
|
+
// client hex-decode it into an empty buffer (blank export field).
|
|
6246
|
+
//
|
|
6247
|
+
// This protocol is only used for raw-scalar import, whose public key is
|
|
6248
|
+
// the ROOT scalar (`A = s·B`, derived at import via derivePubkey(_, undefined)).
|
|
6249
|
+
// The chain-config derivation path stored on the wallet (e.g. Solana's
|
|
6250
|
+
// [44,501,0,0,0]) must NOT be applied here — deriving a child scalar would
|
|
6251
|
+
// export a key that doesn't correspond to the wallet's address.
|
|
6252
|
+
return mpcSigner.derivePrivateKeyFromSpriv(keyExportRaw);
|
|
6165
6253
|
} else if (mpcSigner instanceof web.BIP340) {
|
|
6166
6254
|
return mpcSigner.derivePrivateKeyFromXpriv(keyExportRaw, derivationPath);
|
|
6167
6255
|
}
|
|
6168
6256
|
return undefined;
|
|
6169
6257
|
}
|
|
6170
|
-
async offlineExportKey({ chainName, keyShares, derivationPath }) {
|
|
6258
|
+
async offlineExportKey({ chainName, keyShares, derivationPath, variant }) {
|
|
6171
6259
|
try {
|
|
6172
6260
|
if (!keyShares || keyShares.length < 2) {
|
|
6173
6261
|
throw new Error(`Must provide at least min threshold of key shares`);
|
|
6174
6262
|
}
|
|
6175
6263
|
const mpcSigner = getMPCSigner({
|
|
6176
6264
|
chainName,
|
|
6177
|
-
baseRelayUrl: this.baseMPCRelayApiUrl
|
|
6265
|
+
baseRelayUrl: this.baseMPCRelayApiUrl,
|
|
6266
|
+
variant
|
|
6178
6267
|
});
|
|
6179
6268
|
const walletKeyShares = keyShares.map((keyShare)=>{
|
|
6180
6269
|
if (!('pubkey' in keyShare)) {
|
|
@@ -6193,6 +6282,10 @@ class DynamicWalletClient {
|
|
|
6193
6282
|
derivedPrivateKey = await mpcSigner.derivePrivateKeyFromXpriv(keyExportRaw, walletDerivationPath);
|
|
6194
6283
|
} else if (mpcSigner instanceof web.ExportableEd25519) {
|
|
6195
6284
|
derivedPrivateKey = keyExportRaw;
|
|
6285
|
+
} else if (mpcSigner instanceof web.Ed25519) {
|
|
6286
|
+
// Non-exportable Ed25519 (raw-scalar) returns an `spriv`, not raw hex —
|
|
6287
|
+
// parse it to the root scalar (see derivePrivateKeyFromExport).
|
|
6288
|
+
derivedPrivateKey = await mpcSigner.derivePrivateKeyFromSpriv(keyExportRaw);
|
|
6196
6289
|
} else if (mpcSigner instanceof web.BIP340) {
|
|
6197
6290
|
derivedPrivateKey = await mpcSigner.derivePrivateKeyFromXpriv(keyExportRaw, walletDerivationPath);
|
|
6198
6291
|
}
|
|
@@ -6398,7 +6491,7 @@ class DynamicWalletClient {
|
|
|
6398
6491
|
* @param thresholdSignatureScheme - The TSS scheme used
|
|
6399
6492
|
* @param derivationPath - Optional derivation path (will be computed from chainConfig if not provided)
|
|
6400
6493
|
* @param additionalProps - Any chain-specific additional properties to merge
|
|
6401
|
-
*/ initializeWalletMapEntry({ accountAddress, walletId, chainName, thresholdSignatureScheme, derivationPath, shareSetId, shareSetType, otherShareSets, additionalProps = {} }) {
|
|
6494
|
+
*/ initializeWalletMapEntry({ accountAddress, walletId, chainName, thresholdSignatureScheme, derivationPath, shareSetId, shareSetType, otherShareSets, variant, additionalProps = {} }) {
|
|
6402
6495
|
this.updateWalletMap(accountAddress, _extends({
|
|
6403
6496
|
accountAddress,
|
|
6404
6497
|
walletId,
|
|
@@ -6412,6 +6505,8 @@ class DynamicWalletClient {
|
|
|
6412
6505
|
shareSetType
|
|
6413
6506
|
} : {}, otherShareSets ? {
|
|
6414
6507
|
otherShareSets
|
|
6508
|
+
} : {}, variant ? {
|
|
6509
|
+
variant
|
|
6415
6510
|
} : {}, {
|
|
6416
6511
|
clientKeySharesBackupInfo: getClientKeyShareBackupInfo()
|
|
6417
6512
|
}, additionalProps));
|
|
@@ -6631,7 +6726,7 @@ class DynamicWalletClient {
|
|
|
6631
6726
|
tokenSource: googleDriveTokenSource
|
|
6632
6727
|
} : {});
|
|
6633
6728
|
}
|
|
6634
|
-
async publishDelegatedShare({ walletId, shareSetId, delegatedShare, signedSessionId, dynamicRequestId, chainName, bitcoinConfig, isPasswordEncrypted }) {
|
|
6729
|
+
async publishDelegatedShare({ walletId, shareSetId, delegatedShare, signedSessionId, dynamicRequestId, chainName, accountAddress, bitcoinConfig, isPasswordEncrypted }) {
|
|
6635
6730
|
var _publicKey_key, _publicKey_key1, _publicKey_key2;
|
|
6636
6731
|
const publicKey = await this.apiClient.getDelegatedEncryptionKey({
|
|
6637
6732
|
environmentId: this.environmentId
|
|
@@ -6656,7 +6751,8 @@ class DynamicWalletClient {
|
|
|
6656
6751
|
chainName,
|
|
6657
6752
|
clientKeyShare: delegatedShare,
|
|
6658
6753
|
bitcoinConfig,
|
|
6659
|
-
walletId
|
|
6754
|
+
walletId,
|
|
6755
|
+
accountAddress
|
|
6660
6756
|
});
|
|
6661
6757
|
return {
|
|
6662
6758
|
location: core.BackupLocation.DELEGATED,
|
|
@@ -6822,6 +6918,7 @@ class DynamicWalletClient {
|
|
|
6822
6918
|
signedSessionId: resolvedSignedSessionId,
|
|
6823
6919
|
dynamicRequestId,
|
|
6824
6920
|
chainName: walletData.chainName,
|
|
6921
|
+
accountAddress,
|
|
6825
6922
|
bitcoinConfig,
|
|
6826
6923
|
isPasswordEncrypted
|
|
6827
6924
|
}), {
|
|
@@ -6990,7 +7087,8 @@ class DynamicWalletClient {
|
|
|
6990
7087
|
accountAddress,
|
|
6991
7088
|
chainName,
|
|
6992
7089
|
localShares,
|
|
6993
|
-
recordedKeygenIds
|
|
7090
|
+
recordedKeygenIds,
|
|
7091
|
+
variant: walletData.variant
|
|
6994
7092
|
});
|
|
6995
7093
|
if (fresh) return;
|
|
6996
7094
|
this.logger.warn('[storeEncryptedBackupByWallet] Stale local shares detected; refreshing local storage', {
|
|
@@ -8415,9 +8513,17 @@ class DynamicWalletClient {
|
|
|
8415
8513
|
const user = await this.getUserWithEnvCheck(dynamicRequestId);
|
|
8416
8514
|
const waasWallets = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.filter((vc)=>vc.walletName === 'dynamicwaas');
|
|
8417
8515
|
for (const vc of waasWallets != null ? waasWallets : []){
|
|
8516
|
+
var _props_settings, _this_getWalletFromMap;
|
|
8418
8517
|
const addr = vc.address;
|
|
8419
8518
|
const props = vc.walletProperties;
|
|
8420
|
-
|
|
8519
|
+
var _props_settings_variant, _ref;
|
|
8520
|
+
// Resolve the ed25519 protocol variant: server-surfaced (walletProperties
|
|
8521
|
+
// .settings or top-level) first, then any locally-seeded value (set at raw
|
|
8522
|
+
// import). Required on a fresh session (no local seed) so recover/sign
|
|
8523
|
+
// rebuild the non-exportable Ed25519 signer for raw-scalar wallets instead
|
|
8524
|
+
// of defaulting to exportable → "Invalid discriminant".
|
|
8525
|
+
const resolvedVariant = (_ref = (_props_settings_variant = props == null ? void 0 : (_props_settings = props.settings) == null ? void 0 : _props_settings.variant) != null ? _props_settings_variant : props == null ? void 0 : props.variant) != null ? _ref : (_this_getWalletFromMap = this.getWalletFromMap(addr)) == null ? void 0 : _this_getWalletFromMap.variant;
|
|
8526
|
+
this.updateWalletMap(addr, _extends({
|
|
8421
8527
|
walletId: vc.id,
|
|
8422
8528
|
chainName: core.verifiedCredentialNameToChainEnum[vc.chain],
|
|
8423
8529
|
accountAddress: addr,
|
|
@@ -8430,7 +8536,9 @@ class DynamicWalletClient {
|
|
|
8430
8536
|
shareSetId: props == null ? void 0 : props.shareSetId,
|
|
8431
8537
|
shareSetType: props == null ? void 0 : props.shareSetType,
|
|
8432
8538
|
otherShareSets: props == null ? void 0 : props.otherShareSets
|
|
8433
|
-
}
|
|
8539
|
+
}, resolvedVariant ? {
|
|
8540
|
+
variant: resolvedVariant
|
|
8541
|
+
} : {}));
|
|
8434
8542
|
}
|
|
8435
8543
|
if (walletOperation !== core.WalletOperation.NO_OPERATION && await this.requiresRestoreBackupSharesForOperation({
|
|
8436
8544
|
accountAddress,
|
|
@@ -8808,8 +8916,8 @@ class DynamicWalletClient {
|
|
|
8808
8916
|
this.userId = user.id;
|
|
8809
8917
|
const waasWallets = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.filter((vc)=>vc.walletName === 'dynamicwaas');
|
|
8810
8918
|
const wallets = waasWallets.map((vc)=>{
|
|
8811
|
-
var _this_getWalletFromMap, _vc_walletProperties, _vc_walletProperties1, _vc_walletProperties2, _vc_walletProperties3, _vc_walletProperties4, _vc_walletProperties5, _vc_walletProperties6;
|
|
8812
|
-
var _this_getWalletFromMap_derivationPath;
|
|
8919
|
+
var _this_getWalletFromMap, _vc_walletProperties, _vc_walletProperties1, _vc_walletProperties2, _vc_walletProperties3, _vc_walletProperties4, _vc_walletProperties5, _vc_walletProperties6, _vc_walletProperties_settings, _vc_walletProperties7, _vc_walletProperties8, _this_getWalletFromMap1;
|
|
8920
|
+
var _this_getWalletFromMap_derivationPath, _vc_walletProperties_settings_variant, _ref;
|
|
8813
8921
|
return {
|
|
8814
8922
|
walletId: vc.id,
|
|
8815
8923
|
chainName: core.verifiedCredentialNameToChainEnum[vc.chain],
|
|
@@ -8827,14 +8935,18 @@ class DynamicWalletClient {
|
|
|
8827
8935
|
// On-sign-on settings (shouldRefreshOnNextSignOn / reshareOnNextSignOn /
|
|
8828
8936
|
// revokeOnNextSignOn). Surfaced so the SDK can self-drive the on-sign-on
|
|
8829
8937
|
// orchestration instead of the host reading these flags.
|
|
8830
|
-
settings: (_vc_walletProperties6 = vc.walletProperties) == null ? void 0 : _vc_walletProperties6.settings
|
|
8938
|
+
settings: (_vc_walletProperties6 = vc.walletProperties) == null ? void 0 : _vc_walletProperties6.settings,
|
|
8939
|
+
// Prefer the server-persisted variant (surfaced via walletProperties.settings),
|
|
8940
|
+
// then the locally-known value (set at raw import) so same-session
|
|
8941
|
+
// import → sign works before the server has surfaced it.
|
|
8942
|
+
variant: (_ref = (_vc_walletProperties_settings_variant = (_vc_walletProperties7 = vc.walletProperties) == null ? void 0 : (_vc_walletProperties_settings = _vc_walletProperties7.settings) == null ? void 0 : _vc_walletProperties_settings.variant) != null ? _vc_walletProperties_settings_variant : (_vc_walletProperties8 = vc.walletProperties) == null ? void 0 : _vc_walletProperties8.variant) != null ? _ref : (_this_getWalletFromMap1 = this.getWalletFromMap(vc.address)) == null ? void 0 : _this_getWalletFromMap1.variant
|
|
8831
8943
|
};
|
|
8832
8944
|
});
|
|
8833
8945
|
const existingWalletMap = this.walletMap;
|
|
8834
8946
|
this.walletMap = wallets.reduce((acc, wallet)=>{
|
|
8835
8947
|
const normalizedAddress = normalizeAddress(wallet.accountAddress);
|
|
8836
8948
|
const existingWallet = existingWalletMap[normalizedAddress];
|
|
8837
|
-
acc[normalizedAddress] = {
|
|
8949
|
+
acc[normalizedAddress] = _extends({
|
|
8838
8950
|
walletId: wallet.walletId,
|
|
8839
8951
|
chainName: wallet.chainName,
|
|
8840
8952
|
accountAddress: wallet.accountAddress,
|
|
@@ -8847,7 +8959,9 @@ class DynamicWalletClient {
|
|
|
8847
8959
|
shareSetType: wallet.shareSetType,
|
|
8848
8960
|
businessAccountId: wallet.businessAccountId,
|
|
8849
8961
|
otherShareSets: wallet.otherShareSets
|
|
8850
|
-
}
|
|
8962
|
+
}, wallet.variant ? {
|
|
8963
|
+
variant: wallet.variant
|
|
8964
|
+
} : {});
|
|
8851
8965
|
return acc;
|
|
8852
8966
|
}, {});
|
|
8853
8967
|
this.logger.info('[walletMap] getWallets: walletMap updated from API', {
|
|
@@ -9301,6 +9415,46 @@ DynamicWalletClient.roomsPersistDirty = false;
|
|
|
9301
9415
|
// rooms back into the new user's storage (TOCTOU on the create→merge gap).
|
|
9302
9416
|
DynamicWalletClient.roomsGeneration = 0;
|
|
9303
9417
|
|
|
9418
|
+
/**
|
|
9419
|
+
* Derive the 32-byte ed25519 public key from a **raw** 32-byte signing scalar
|
|
9420
|
+
* (`A = s·B`).
|
|
9421
|
+
*
|
|
9422
|
+
* This is NOT the same as deriving a public key from an RFC-8032 seed: the
|
|
9423
|
+
* standard ed25519 key-generation step takes a 32-byte seed and SHA-512-expands
|
|
9424
|
+
* it (then clamps) to obtain the scalar. A scalar exported from an external MPC
|
|
9425
|
+
* system (e.g. Fireblocks Embedded Wallets) has no preimage seed, so it must be
|
|
9426
|
+
* used directly as the scalar. Using `Keypair.fromSecretKey` / `keyPairFromSeed`
|
|
9427
|
+
* on such bytes would re-expand them and produce the wrong public key/address.
|
|
9428
|
+
*
|
|
9429
|
+
* @param scalar Raw 32-byte ed25519 scalar, little-endian, as hex (with or
|
|
9430
|
+
* without a `0x` prefix) or as raw bytes.
|
|
9431
|
+
* @returns The compressed 32-byte ed25519 public key.
|
|
9432
|
+
*/ const getEd25519PublicKeyFromRawScalar = (scalar)=>{
|
|
9433
|
+
let bytes;
|
|
9434
|
+
if (typeof scalar === 'string') {
|
|
9435
|
+
const hex = scalar.replace(/^0x/, '');
|
|
9436
|
+
// Validate before hexToBytes so malformed input fails with a clear, own
|
|
9437
|
+
// error rather than an opaque/implementation-specific one from the decoder.
|
|
9438
|
+
if (!/^[0-9a-fA-F]+$/.test(hex)) {
|
|
9439
|
+
throw new Error('Invalid raw ed25519 scalar: expected a hex string');
|
|
9440
|
+
}
|
|
9441
|
+
bytes = utils.hexToBytes(hex);
|
|
9442
|
+
} else {
|
|
9443
|
+
bytes = scalar;
|
|
9444
|
+
}
|
|
9445
|
+
if (bytes.length !== 32) {
|
|
9446
|
+
throw new Error(`Invalid raw ed25519 scalar length: ${bytes.length}, expected 32`);
|
|
9447
|
+
}
|
|
9448
|
+
// Interpret the scalar little-endian and reduce mod the curve order. We do NOT
|
|
9449
|
+
// clamp here: the caller provides the actual signing scalar `s`, and the public
|
|
9450
|
+
// key is exactly `s·B`.
|
|
9451
|
+
const reduced = utils.bytesToNumberLE(bytes) % ed25519.ed25519.CURVE.n;
|
|
9452
|
+
if (reduced === 0n) {
|
|
9453
|
+
throw new Error('Invalid raw ed25519 scalar: reduces to zero mod the curve order');
|
|
9454
|
+
}
|
|
9455
|
+
return ed25519.ed25519.ExtendedPoint.BASE.multiply(reduced).toRawBytes();
|
|
9456
|
+
};
|
|
9457
|
+
|
|
9304
9458
|
Object.defineProperty(exports, "Logger", {
|
|
9305
9459
|
enumerable: true,
|
|
9306
9460
|
get: function () { return core.Logger; }
|
|
@@ -9415,6 +9569,7 @@ exports.getBitcoinAddressTypeFromDerivationPath = getBitcoinAddressTypeFromDeriv
|
|
|
9415
9569
|
exports.getClientKeyShareBackupInfo = getClientKeyShareBackupInfo;
|
|
9416
9570
|
exports.getClientKeyShareExportFileName = getClientKeyShareExportFileName;
|
|
9417
9571
|
exports.getDelegatedShareSet = getDelegatedShareSet;
|
|
9572
|
+
exports.getEd25519PublicKeyFromRawScalar = getEd25519PublicKeyFromRawScalar;
|
|
9418
9573
|
exports.getGoogleOAuthAccountId = getGoogleOAuthAccountId;
|
|
9419
9574
|
exports.getHttpStatus = getHttpStatus;
|
|
9420
9575
|
exports.getICloudBackup = getICloudBackup;
|