@getpara/core-sdk 2.0.0-dev.3 → 2.0.0-dev.7
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/dist/cjs/ParaCore.js +493 -146
- package/dist/cjs/constants.js +10 -1
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/shares/enclave.js +274 -0
- package/dist/cjs/shares/shareDistribution.js +16 -1
- package/dist/cjs/types/coreApi.js +3 -1
- package/dist/esm/ParaCore.js +493 -147
- package/dist/esm/constants.js +7 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/shares/enclave.js +234 -0
- package/dist/esm/shares/shareDistribution.js +16 -1
- package/dist/esm/types/coreApi.js +3 -1
- package/dist/types/ParaCore.d.ts +41 -8
- package/dist/types/PlatformUtils.d.ts +2 -1
- package/dist/types/constants.d.ts +3 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/shares/enclave.d.ts +81 -0
- package/dist/types/shares/shareDistribution.d.ts +4 -2
- package/dist/types/types/config.d.ts +2 -0
- package/dist/types/types/coreApi.d.ts +12 -3
- package/dist/types/types/methods.d.ts +37 -8
- package/dist/types/types/wallet.d.ts +2 -2
- package/package.json +3 -3
package/dist/esm/constants.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import "./chunk-7B52C2XE.js";
|
|
2
|
-
const PARA_CORE_VERSION = "2.0.0-
|
|
2
|
+
const PARA_CORE_VERSION = "2.0.0-alpha.50";
|
|
3
3
|
const PREFIX = "@CAPSULE/";
|
|
4
|
+
const PARA_PREFIX = "@PARA/";
|
|
4
5
|
const LOCAL_STORAGE_AUTH_INFO = `${PREFIX}authInfo`;
|
|
5
6
|
const LOCAL_STORAGE_EMAIL = `${PREFIX}e-mail`;
|
|
6
7
|
const LOCAL_STORAGE_PHONE = `${PREFIX}phone`;
|
|
@@ -14,6 +15,8 @@ const LOCAL_STORAGE_WALLETS = `${PREFIX}wallets`;
|
|
|
14
15
|
const LOCAL_STORAGE_EXTERNAL_WALLETS = `${PREFIX}externalWallets`;
|
|
15
16
|
const LOCAL_STORAGE_CURRENT_WALLET_IDS = `${PREFIX}currentWalletIds`;
|
|
16
17
|
const LOCAL_STORAGE_SESSION_COOKIE = `${PREFIX}sessionCookie`;
|
|
18
|
+
const LOCAL_STORAGE_ENCLAVE_JWT = `${PREFIX}enclaveJwt`;
|
|
19
|
+
const LOCAL_STORAGE_ENCLAVE_REFRESH_JWT = `${PREFIX}enclaveRefreshJwt`;
|
|
17
20
|
const SESSION_STORAGE_LOGIN_ENCRYPTION_KEY_PAIR = `${PREFIX}loginEncryptionKeyPair`;
|
|
18
21
|
const POLLING_INTERVAL_MS = 2e3;
|
|
19
22
|
const SHORT_POLLING_INTERVAL_MS = 1e3;
|
|
@@ -28,6 +31,8 @@ export {
|
|
|
28
31
|
LOCAL_STORAGE_CURRENT_WALLET_IDS,
|
|
29
32
|
LOCAL_STORAGE_ED25519_WALLETS,
|
|
30
33
|
LOCAL_STORAGE_EMAIL,
|
|
34
|
+
LOCAL_STORAGE_ENCLAVE_JWT,
|
|
35
|
+
LOCAL_STORAGE_ENCLAVE_REFRESH_JWT,
|
|
31
36
|
LOCAL_STORAGE_EXTERNAL_WALLETS,
|
|
32
37
|
LOCAL_STORAGE_EXTERNAL_WALLET_USER_ID,
|
|
33
38
|
LOCAL_STORAGE_FARCASTER_USERNAME,
|
|
@@ -37,6 +42,7 @@ export {
|
|
|
37
42
|
LOCAL_STORAGE_USER_ID,
|
|
38
43
|
LOCAL_STORAGE_WALLETS,
|
|
39
44
|
PARA_CORE_VERSION,
|
|
45
|
+
PARA_PREFIX,
|
|
40
46
|
POLLING_INTERVAL_MS,
|
|
41
47
|
POLLING_TIMEOUT_MS,
|
|
42
48
|
PREFIX,
|
package/dist/esm/index.js
CHANGED
|
@@ -33,7 +33,7 @@ export * from "./types/coreApi.js";
|
|
|
33
33
|
export * from "./types/events.js";
|
|
34
34
|
export * from "./types/config.js";
|
|
35
35
|
import { getPortalDomain, entityToWallet, constructUrl, shortenUrl } from "./utils/index.js";
|
|
36
|
-
import { PREFIX } from "./constants.js";
|
|
36
|
+
import { PREFIX, PARA_PREFIX } from "./constants.js";
|
|
37
37
|
import { distributeNewShare } from "./shares/shareDistribution.js";
|
|
38
38
|
import { KeyContainer } from "./shares/KeyContainer.js";
|
|
39
39
|
import { getBaseUrl, initClient } from "./external/userManagementClient.js";
|
|
@@ -85,6 +85,7 @@ export {
|
|
|
85
85
|
OnRampProvider,
|
|
86
86
|
OnRampPurchaseStatus,
|
|
87
87
|
OnRampPurchaseType,
|
|
88
|
+
PARA_PREFIX as PARA_STORAGE_PREFIX,
|
|
88
89
|
PREGEN_IDENTIFIER_TYPES,
|
|
89
90
|
PopupType,
|
|
90
91
|
PregenIdentifierType,
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__async
|
|
3
|
+
} from "../chunk-7B52C2XE.js";
|
|
4
|
+
class EnclaveClient {
|
|
5
|
+
constructor({
|
|
6
|
+
userManagementClient,
|
|
7
|
+
retrieveJwt,
|
|
8
|
+
persistJwt,
|
|
9
|
+
retrieveRefreshJwt,
|
|
10
|
+
persistRefreshJwt
|
|
11
|
+
}) {
|
|
12
|
+
this.enclavePublicKey = null;
|
|
13
|
+
this.frontendKeyPair = null;
|
|
14
|
+
this.userManagementClient = userManagementClient;
|
|
15
|
+
this.retrieveJwt = retrieveJwt;
|
|
16
|
+
this.persistJwt = persistJwt;
|
|
17
|
+
this.retrieveRefreshJwt = retrieveRefreshJwt;
|
|
18
|
+
this.persistRefreshJwt = persistRefreshJwt;
|
|
19
|
+
}
|
|
20
|
+
refreshJwt() {
|
|
21
|
+
return __async(this, null, function* () {
|
|
22
|
+
const frontendKeyPair = yield this.generateFrontendKeyPair();
|
|
23
|
+
const responsePublicKeyPEM = yield this.exportPublicKeyToPEM(frontendKeyPair.publicKey);
|
|
24
|
+
const payload = {
|
|
25
|
+
refreshJwt: this.retrieveRefreshJwt(),
|
|
26
|
+
responsePublicKey: responsePublicKeyPEM
|
|
27
|
+
};
|
|
28
|
+
const encryptedPayload = yield this.encryptForEnclave(JSON.stringify(payload));
|
|
29
|
+
const response = yield this.userManagementClient.refreshEnclaveJwt(JSON.stringify(encryptedPayload));
|
|
30
|
+
const decryptedResponse = yield this.decryptForFrontend(JSON.parse(response.payload));
|
|
31
|
+
this.persistJwt(decryptedResponse.jwt);
|
|
32
|
+
this.persistRefreshJwt(decryptedResponse.refreshJwt);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
withJwtRefreshRetry(fn) {
|
|
36
|
+
return __async(this, null, function* () {
|
|
37
|
+
try {
|
|
38
|
+
return yield fn();
|
|
39
|
+
} catch (error) {
|
|
40
|
+
yield this.refreshJwt();
|
|
41
|
+
return yield fn();
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
issueEnclaveJwt() {
|
|
46
|
+
return __async(this, null, function* () {
|
|
47
|
+
const frontendKeyPair = yield this.generateFrontendKeyPair();
|
|
48
|
+
const responsePublicKeyPEM = yield this.exportPublicKeyToPEM(frontendKeyPair.publicKey);
|
|
49
|
+
const payload = {
|
|
50
|
+
responsePublicKey: responsePublicKeyPEM
|
|
51
|
+
};
|
|
52
|
+
const encryptedPayload = yield this.encryptForEnclave(JSON.stringify(payload));
|
|
53
|
+
const response = yield this.userManagementClient.issueEnclaveJwt(JSON.stringify(encryptedPayload));
|
|
54
|
+
console.log(JSON.parse(response));
|
|
55
|
+
const decryptedResponse = yield this.decryptForFrontend(JSON.parse(response));
|
|
56
|
+
console.log("decryptedResponse", decryptedResponse);
|
|
57
|
+
this.persistJwt(decryptedResponse.jwt);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Generate a P-256 keypair for the frontend to receive encrypted responses
|
|
62
|
+
*/
|
|
63
|
+
generateFrontendKeyPair() {
|
|
64
|
+
return __async(this, null, function* () {
|
|
65
|
+
if (this.frontendKeyPair) {
|
|
66
|
+
return this.frontendKeyPair;
|
|
67
|
+
}
|
|
68
|
+
this.frontendKeyPair = yield crypto.subtle.generateKey({ name: "ECDH", namedCurve: "P-256" }, true, ["deriveBits"]);
|
|
69
|
+
return this.frontendKeyPair;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get the enclave's public key from the user-management service
|
|
74
|
+
*/
|
|
75
|
+
getEnclavePublicKey() {
|
|
76
|
+
return __async(this, null, function* () {
|
|
77
|
+
if (this.enclavePublicKey) {
|
|
78
|
+
return this.enclavePublicKey;
|
|
79
|
+
}
|
|
80
|
+
const response = yield this.userManagementClient.getEnclavePublicKey();
|
|
81
|
+
this.enclavePublicKey = response.publicKey;
|
|
82
|
+
return this.enclavePublicKey;
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Import a PEM-formatted public key for use with Web Crypto API
|
|
87
|
+
*/
|
|
88
|
+
importPublicKeyFromPEM(pemString) {
|
|
89
|
+
return __async(this, null, function* () {
|
|
90
|
+
const pemContents = pemString.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "").replace(/\s/g, "");
|
|
91
|
+
const keyData = Uint8Array.from(atob(pemContents), (c) => c.charCodeAt(0));
|
|
92
|
+
return yield crypto.subtle.importKey("spki", keyData, { name: "ECDH", namedCurve: "P-256" }, false, []);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Export a public key to PEM format
|
|
97
|
+
*/
|
|
98
|
+
exportPublicKeyToPEM(publicKey) {
|
|
99
|
+
return __async(this, null, function* () {
|
|
100
|
+
const exported = yield crypto.subtle.exportKey("spki", publicKey);
|
|
101
|
+
const exportedAsBase64 = btoa(String.fromCharCode(...new Uint8Array(exported)));
|
|
102
|
+
return `-----BEGIN PUBLIC KEY-----
|
|
103
|
+
${exportedAsBase64}
|
|
104
|
+
-----END PUBLIC KEY-----`;
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Encrypt data using P-256 ECIES for the enclave
|
|
109
|
+
*/
|
|
110
|
+
encryptForEnclave(plaintext) {
|
|
111
|
+
return __async(this, null, function* () {
|
|
112
|
+
const enclavePublicKeyPEM = yield this.getEnclavePublicKey();
|
|
113
|
+
const enclavePublicKey = yield this.importPublicKeyFromPEM(enclavePublicKeyPEM);
|
|
114
|
+
const ephemeralKeyPair = yield crypto.subtle.generateKey({ name: "ECDH", namedCurve: "P-256" }, true, ["deriveBits"]);
|
|
115
|
+
const sharedSecretBits = yield crypto.subtle.deriveBits(
|
|
116
|
+
{ name: "ECDH", public: enclavePublicKey },
|
|
117
|
+
ephemeralKeyPair.privateKey,
|
|
118
|
+
256
|
|
119
|
+
// 32 bytes = 256 bits
|
|
120
|
+
);
|
|
121
|
+
const encryptionKeyBuffer = yield crypto.subtle.digest("SHA-256", sharedSecretBits);
|
|
122
|
+
const encryptionKey = yield crypto.subtle.importKey("raw", encryptionKeyBuffer, { name: "AES-GCM" }, false, ["encrypt"]);
|
|
123
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
124
|
+
const encrypted = yield crypto.subtle.encrypt(
|
|
125
|
+
{ name: "AES-GCM", iv },
|
|
126
|
+
encryptionKey,
|
|
127
|
+
new TextEncoder().encode(plaintext)
|
|
128
|
+
);
|
|
129
|
+
const encryptedArray = new Uint8Array(encrypted);
|
|
130
|
+
const combined = new Uint8Array(iv.length + encryptedArray.length);
|
|
131
|
+
combined.set(iv);
|
|
132
|
+
combined.set(encryptedArray, iv.length);
|
|
133
|
+
const ephemeralPublicKeyBuffer = yield crypto.subtle.exportKey("spki", ephemeralKeyPair.publicKey);
|
|
134
|
+
return {
|
|
135
|
+
encryptedData: btoa(String.fromCharCode(...combined)),
|
|
136
|
+
keyId: "",
|
|
137
|
+
// Will be set by the enclave
|
|
138
|
+
algorithm: "ECIES-P256-AES256-SHA256",
|
|
139
|
+
ephemeral: btoa(String.fromCharCode(...new Uint8Array(ephemeralPublicKeyBuffer)))
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Decrypt response encrypted for the frontend
|
|
145
|
+
*/
|
|
146
|
+
decryptForFrontend(encryptedPayload) {
|
|
147
|
+
return __async(this, null, function* () {
|
|
148
|
+
if (!this.frontendKeyPair) {
|
|
149
|
+
throw new Error("Frontend keypair not available");
|
|
150
|
+
}
|
|
151
|
+
const encryptedData = Uint8Array.from(atob(encryptedPayload.encryptedData), (c) => c.charCodeAt(0));
|
|
152
|
+
const ephemeralPublicKeyData = Uint8Array.from(atob(encryptedPayload.ephemeral), (c) => c.charCodeAt(0));
|
|
153
|
+
const ephemeralPublicKey = yield crypto.subtle.importKey(
|
|
154
|
+
"spki",
|
|
155
|
+
ephemeralPublicKeyData,
|
|
156
|
+
{ name: "ECDH", namedCurve: "P-256" },
|
|
157
|
+
false,
|
|
158
|
+
[]
|
|
159
|
+
);
|
|
160
|
+
const sharedSecretBits = yield crypto.subtle.deriveBits(
|
|
161
|
+
{ name: "ECDH", public: ephemeralPublicKey },
|
|
162
|
+
this.frontendKeyPair.privateKey,
|
|
163
|
+
256
|
|
164
|
+
);
|
|
165
|
+
const encryptionKeyBuffer = yield crypto.subtle.digest("SHA-256", sharedSecretBits);
|
|
166
|
+
const encryptionKey = yield crypto.subtle.importKey("raw", encryptionKeyBuffer, { name: "AES-GCM" }, false, ["decrypt"]);
|
|
167
|
+
const iv = encryptedData.slice(0, 12);
|
|
168
|
+
const ciphertext = encryptedData.slice(12);
|
|
169
|
+
const decrypted = yield crypto.subtle.decrypt({ name: "AES-GCM", iv }, encryptionKey, ciphertext);
|
|
170
|
+
console.log("decryptForFrontend decrypted", decrypted);
|
|
171
|
+
return JSON.parse(new TextDecoder().decode(decrypted));
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Persist key shares to the enclave
|
|
176
|
+
* @param shares Array of share data to persist
|
|
177
|
+
*/
|
|
178
|
+
persistShares(shares) {
|
|
179
|
+
return __async(this, null, function* () {
|
|
180
|
+
console.log("persistShares about to call encryptForEnclave");
|
|
181
|
+
console.log("shares", shares);
|
|
182
|
+
const payload = {
|
|
183
|
+
shares,
|
|
184
|
+
jwt: this.retrieveJwt()
|
|
185
|
+
};
|
|
186
|
+
const encryptedPayload = yield this.encryptForEnclave(JSON.stringify(payload));
|
|
187
|
+
const encryptedPayloadStr = JSON.stringify(encryptedPayload);
|
|
188
|
+
return yield this.userManagementClient.persistEnclaveShares(encryptedPayloadStr);
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Retrieve key shares from the enclave
|
|
193
|
+
* @param query Query parameters for finding shares (single query or array of queries)
|
|
194
|
+
*/
|
|
195
|
+
retrieveShares(query) {
|
|
196
|
+
return __async(this, null, function* () {
|
|
197
|
+
yield this.issueEnclaveJwt();
|
|
198
|
+
const frontendKeyPair = yield this.generateFrontendKeyPair();
|
|
199
|
+
const responsePublicKeyPEM = yield this.exportPublicKeyToPEM(frontendKeyPair.publicKey);
|
|
200
|
+
const fullQuery = query.map((q) => ({
|
|
201
|
+
userId: q.userId
|
|
202
|
+
}));
|
|
203
|
+
const payload = {
|
|
204
|
+
query: fullQuery,
|
|
205
|
+
responsePublicKey: responsePublicKeyPEM,
|
|
206
|
+
jwt: this.retrieveJwt()
|
|
207
|
+
};
|
|
208
|
+
const encryptedPayload = yield this.encryptForEnclave(JSON.stringify(payload));
|
|
209
|
+
const encryptedPayloadStr = JSON.stringify(encryptedPayload);
|
|
210
|
+
const response = yield this.userManagementClient.retrieveEnclaveShares(encryptedPayloadStr);
|
|
211
|
+
const encryptedResponse = JSON.parse(response.payload);
|
|
212
|
+
const decryptedData = yield this.decryptForFrontend(encryptedResponse);
|
|
213
|
+
console.log("retrieveShares decryptedData", decryptedData);
|
|
214
|
+
return decryptedData;
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
retrieveSharesWithRetry(query) {
|
|
218
|
+
return __async(this, null, function* () {
|
|
219
|
+
return yield this.withJwtRefreshRetry(() => __async(this, null, function* () {
|
|
220
|
+
return this.retrieveShares(query);
|
|
221
|
+
}));
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
persistSharesWithRetry(shares) {
|
|
225
|
+
return __async(this, null, function* () {
|
|
226
|
+
return yield this.withJwtRefreshRetry(() => __async(this, null, function* () {
|
|
227
|
+
return this.persistShares(shares);
|
|
228
|
+
}));
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
export {
|
|
233
|
+
EnclaveClient
|
|
234
|
+
};
|
|
@@ -13,8 +13,23 @@ function distributeNewShare(_0) {
|
|
|
13
13
|
ignoreRedistributingBackupEncryptedShare = false,
|
|
14
14
|
emailProps = {},
|
|
15
15
|
partnerId,
|
|
16
|
-
protocolId
|
|
16
|
+
protocolId,
|
|
17
|
+
isEnclaveUser,
|
|
18
|
+
walletScheme
|
|
17
19
|
}) {
|
|
20
|
+
if (isEnclaveUser) {
|
|
21
|
+
yield ctx.enclaveClient.persistSharesWithRetry([
|
|
22
|
+
{
|
|
23
|
+
userId,
|
|
24
|
+
walletId,
|
|
25
|
+
walletScheme,
|
|
26
|
+
signer: userShare,
|
|
27
|
+
partnerId,
|
|
28
|
+
protocolId
|
|
29
|
+
}
|
|
30
|
+
]);
|
|
31
|
+
return "";
|
|
32
|
+
}
|
|
18
33
|
const publicKeysRes = yield ctx.client.getSessionPublicKeys(userId);
|
|
19
34
|
const biometricEncryptedShares = publicKeysRes.data.keys.map((key) => {
|
|
20
35
|
if (!key.publicKey) {
|
package/dist/types/ParaCore.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { AuthMethod, AuthExtras, CurrentWalletIds, EmailTheme, TWalletType, PregenIds, BiometricLocationHint, Auth, SupportedWalletTypes, AuthIdentifier, AuthType, ExternalWalletInfo, PrimaryAuthInfo, SessionInfo, PrimaryAuth, PrimaryAuthType, AccountMetadata, LinkedAccounts, VerifyLinkParams, VerifyExternalWalletParams, SupportedAccountLinks } from '@getpara/user-management-client';
|
|
1
|
+
import { AuthMethod, AuthExtras, CurrentWalletIds, EmailTheme, PartnerEntity, TWalletType, PregenIds, BiometricLocationHint, Auth, SupportedWalletTypes, AuthIdentifier, AuthType, ExternalWalletInfo, PrimaryAuthInfo, SessionInfo, PrimaryAuth, PrimaryAuthType, AccountMetadata, LinkedAccounts, VerifyLinkParams, VerifyExternalWalletParams, SupportedAccountLinks, OnRampPurchase } from '@getpara/user-management-client';
|
|
2
2
|
import type { pki as pkiType } from 'node-forge';
|
|
3
3
|
import { Ctx, Environment, Theme, WalletFilters, Wallet, PortalUrlOptions, ConstructorOpts, CoreAuthInfo, PortalUrlType, CoreMethodParams, CoreMethodResponse, NewCredentialUrlParams, LoginUrlParams, CoreInterface, ExternalWalletConnectionType, AccountLinkInProgress, InternalMethodParams, InternalMethodResponse } from './types/index.js';
|
|
4
4
|
import { PlatformUtils } from './PlatformUtils.js';
|
|
5
5
|
export declare abstract class ParaCore implements CoreInterface {
|
|
6
6
|
#private;
|
|
7
|
+
popupWindow: Window | null;
|
|
7
8
|
static version?: string;
|
|
8
9
|
ctx: Ctx;
|
|
9
10
|
protected isNativePasskey: boolean;
|
|
@@ -16,13 +17,18 @@ export declare abstract class ParaCore implements CoreInterface {
|
|
|
16
17
|
get telegramUserId(): AuthIdentifier<'telegram'> | undefined;
|
|
17
18
|
get externalWalletWithParaAuth(): Wallet | undefined;
|
|
18
19
|
get externalWalletConnectionType(): ExternalWalletConnectionType;
|
|
20
|
+
protected partner?: PartnerEntity;
|
|
19
21
|
userId?: string;
|
|
20
22
|
accountLinkInProgress: AccountLinkInProgress | undefined;
|
|
21
23
|
private sessionCookie?;
|
|
24
|
+
isEnclaveUser: boolean;
|
|
25
|
+
private enclaveJwt?;
|
|
26
|
+
private enclaveRefreshJwt?;
|
|
22
27
|
private isAwaitingAccountCreation;
|
|
23
28
|
private isAwaitingLogin;
|
|
24
29
|
private isAwaitingFarcaster;
|
|
25
30
|
private isAwaitingOAuth;
|
|
31
|
+
private isWorkerInitialized;
|
|
26
32
|
get isEmail(): boolean;
|
|
27
33
|
get isPhone(): boolean;
|
|
28
34
|
get isFarcaster(): boolean;
|
|
@@ -30,6 +36,8 @@ export declare abstract class ParaCore implements CoreInterface {
|
|
|
30
36
|
get isExternalWalletAuth(): boolean;
|
|
31
37
|
get isExternalWalletWithVerification(): boolean;
|
|
32
38
|
get partnerId(): string | undefined;
|
|
39
|
+
protected get partnerName(): string | undefined;
|
|
40
|
+
protected get partnerLogo(): string | undefined;
|
|
33
41
|
/**
|
|
34
42
|
* The IDs of the currently active wallets, for each supported wallet type. Any signer integrations will default to the first viable wallet ID in this dictionary.
|
|
35
43
|
*/
|
|
@@ -129,7 +137,11 @@ export declare abstract class ParaCore implements CoreInterface {
|
|
|
129
137
|
get cosmosPrefix(): string | undefined;
|
|
130
138
|
get supportedAccountLinks(): SupportedAccountLinks;
|
|
131
139
|
get isWalletTypeEnabled(): Partial<Record<TWalletType, boolean>>;
|
|
132
|
-
|
|
140
|
+
protected onRampPopup: {
|
|
141
|
+
window: Window;
|
|
142
|
+
onRampPurchase: OnRampPurchase;
|
|
143
|
+
} | undefined;
|
|
144
|
+
protected platformUtils: PlatformUtils;
|
|
133
145
|
private localStorageGetItem;
|
|
134
146
|
private localStorageSetItem;
|
|
135
147
|
private localStorageRemoveItem;
|
|
@@ -138,6 +150,10 @@ export declare abstract class ParaCore implements CoreInterface {
|
|
|
138
150
|
private sessionStorageRemoveItem;
|
|
139
151
|
retrieveSessionCookie: () => string | undefined;
|
|
140
152
|
persistSessionCookie: (cookie: string) => void;
|
|
153
|
+
retrieveEnclaveJwt: () => string;
|
|
154
|
+
persistEnclaveJwt: (jwt: string) => void;
|
|
155
|
+
retrieveEnclaveRefreshJwt: () => string;
|
|
156
|
+
persistEnclaveRefreshJwt: (jwt: string) => void;
|
|
141
157
|
/**
|
|
142
158
|
* Remove all local storage and prefixed session storage.
|
|
143
159
|
* @param {'local' | 'session' | 'secure' | 'all'} type - Type of storage to clear. Defaults to 'all'.
|
|
@@ -145,7 +161,7 @@ export declare abstract class ParaCore implements CoreInterface {
|
|
|
145
161
|
clearStorage: (type?: CoreMethodParams<"clearStorage">) => CoreMethodResponse<"clearStorage">;
|
|
146
162
|
private convertBigInt;
|
|
147
163
|
private convertEncryptionKeyPair;
|
|
148
|
-
|
|
164
|
+
protected isPortal(envOverride?: Environment): boolean;
|
|
149
165
|
private isParaConnect;
|
|
150
166
|
private requireApiKey;
|
|
151
167
|
private isWalletSupported;
|
|
@@ -179,24 +195,28 @@ export declare abstract class ParaCore implements CoreInterface {
|
|
|
179
195
|
protected abstract getPlatformUtils(): PlatformUtils;
|
|
180
196
|
abstract isPasskeySupported(): Promise<boolean>;
|
|
181
197
|
protected constructPortalUrl(type: PortalUrlType, opts?: PortalUrlOptions): Promise<string>;
|
|
198
|
+
static resolveEnvironment(env: Environment | undefined, apiKey: string | undefined): Environment;
|
|
182
199
|
/**
|
|
183
200
|
* Constructs a new `ParaCore` instance.
|
|
184
|
-
* @param env - `Environment` to use.
|
|
201
|
+
* @param env - `Environment` to use. Optional if the apiKey contains an environment prefix (e.g., "prod_your_api_key"). Updated API keys can be found at https://developer.getpara.com.
|
|
185
202
|
* @param apiKey - API key to use.
|
|
186
203
|
* @param opts - Additional constructor options; see `ConstructorOpts`.
|
|
187
204
|
* @returns - A new ParaCore instance.
|
|
188
205
|
*/
|
|
189
|
-
constructor(env: Environment, apiKey: string, opts?: ConstructorOpts);
|
|
206
|
+
constructor(env: Environment | undefined, apiKey: string, opts?: ConstructorOpts);
|
|
207
|
+
constructor(apiKey: string, opts?: ConstructorOpts);
|
|
190
208
|
private trackError;
|
|
191
209
|
private wrapMethodsWithErrorTracking;
|
|
192
210
|
private initializeFromStorage;
|
|
193
211
|
private updateAuthInfoFromStorage;
|
|
212
|
+
private updateEnclaveJwtFromStorage;
|
|
194
213
|
private updateUserIdFromStorage;
|
|
195
214
|
private updateWalletsFromStorage;
|
|
196
215
|
private updateWalletIdsFromStorage;
|
|
197
216
|
private updateSessionCookieFromStorage;
|
|
198
217
|
private updateLoginEncryptionKeyPairFromStorage;
|
|
199
218
|
private updateExternalWalletsFromStorage;
|
|
219
|
+
protected initializeWorker: () => Promise<void>;
|
|
200
220
|
touchSession(regenerate?: boolean): Promise<SessionInfo>;
|
|
201
221
|
private getVerificationEmailProps;
|
|
202
222
|
private getBackupKitEmailProps;
|
|
@@ -206,12 +226,19 @@ export declare abstract class ParaCore implements CoreInterface {
|
|
|
206
226
|
* Init only needs to be called for storage that is async.
|
|
207
227
|
*/
|
|
208
228
|
init(): Promise<void>;
|
|
209
|
-
|
|
229
|
+
/**
|
|
230
|
+
* Call this method to perform initial setup for the `ParaCore` instance.
|
|
231
|
+
*
|
|
232
|
+
* This method will be called automatically if you use the React `ParaProvider` or when you call any methods that request an updated session.
|
|
233
|
+
*/
|
|
234
|
+
abstract ready(): Promise<void>;
|
|
210
235
|
protected setAuth(auth: PrimaryAuth, { extras, userId }?: {
|
|
211
236
|
extras?: AuthExtras;
|
|
212
237
|
userId?: string;
|
|
213
238
|
}): Promise<typeof this.authInfo>;
|
|
214
|
-
protected assertUserId(
|
|
239
|
+
protected assertUserId({ allowGuestMode }?: {
|
|
240
|
+
allowGuestMode?: boolean;
|
|
241
|
+
}): string;
|
|
215
242
|
protected assertIsAuthSet(allowed?: AuthType[]): PrimaryAuthInfo;
|
|
216
243
|
/**
|
|
217
244
|
* Sets the email associated with the `ParaCore` instance.
|
|
@@ -240,6 +267,7 @@ export declare abstract class ParaCore implements CoreInterface {
|
|
|
240
267
|
* @param externalType - Type of external wallet to set.
|
|
241
268
|
*/
|
|
242
269
|
setExternalWallet(externalWallet: ExternalWalletInfo[] | ExternalWalletInfo): Promise<void>;
|
|
270
|
+
protected addExternalWallets(externalWallets: ExternalWalletInfo[]): Promise<void>;
|
|
243
271
|
/**
|
|
244
272
|
* Sets the user id associated with the `ParaCore` instance.
|
|
245
273
|
* @param userId - User id to set.
|
|
@@ -394,6 +422,9 @@ export declare abstract class ParaCore implements CoreInterface {
|
|
|
394
422
|
**/
|
|
395
423
|
isFullyLoggedIn(): CoreMethodResponse<'isFullyLoggedIn'>;
|
|
396
424
|
get isGuestMode(): boolean;
|
|
425
|
+
/**
|
|
426
|
+
* Get the auth methods available to an existing user
|
|
427
|
+
*/
|
|
397
428
|
protected supportedAuthMethods(auth: Auth<PrimaryAuthType | 'userId'>): Promise<Set<AuthMethod>>;
|
|
398
429
|
/**
|
|
399
430
|
* Get hints associated with the users stored biometrics.
|
|
@@ -668,7 +699,7 @@ export declare abstract class ParaCore implements CoreInterface {
|
|
|
668
699
|
url?: string;
|
|
669
700
|
}>;
|
|
670
701
|
/**
|
|
671
|
-
* Returns a Para Portal URL for logging in with a WebAuth passkey or
|
|
702
|
+
* Returns a Para Portal URL for logging in with a WebAuth passkey, password, PIN or OTP.
|
|
672
703
|
* @param {Object} opts the options object
|
|
673
704
|
* @param {String} opts.auth - the user auth to sign up or log in with, in the form ` { email: string } | { phone: `+${number}` } `
|
|
674
705
|
* @param {boolean} opts.useShortUrls - whether to shorten the generated portal URLs
|
|
@@ -676,6 +707,7 @@ export declare abstract class ParaCore implements CoreInterface {
|
|
|
676
707
|
* @returns {SignUpOrLogInResponse} an object in the form of either: `{ stage: 'verify' }` or `{ stage: 'login'; passkeyUrl?: string; passwordUrl?: string; biometricHints?: BiometricLocationHint[] }`
|
|
677
708
|
*/
|
|
678
709
|
protected getLoginUrl({ authMethod, shorten, portalTheme, sessionId, }: LoginUrlParams): Promise<string>;
|
|
710
|
+
protected prepareLogin(): InternalMethodResponse<'prepareLogin'>;
|
|
679
711
|
signUpOrLogIn({ auth, ...urlOptions }: CoreMethodParams<'signUpOrLogIn'>): CoreMethodResponse<'signUpOrLogIn'>;
|
|
680
712
|
verifyNewAccount({ verificationCode, ...urlOptions }: CoreMethodParams<'verifyNewAccount'>): CoreMethodResponse<'verifyNewAccount'>;
|
|
681
713
|
getLinkedAccounts({ withMetadata, }?: CoreMethodParams<'getLinkedAccounts'>): CoreMethodResponse<'getLinkedAccounts'>;
|
|
@@ -685,4 +717,5 @@ export declare abstract class ParaCore implements CoreInterface {
|
|
|
685
717
|
accountLinkInProgress?: AccountLinkInProgress;
|
|
686
718
|
} & Partial<Pick<VerifyLinkParams, 'verificationCode' | 'telegramAuthResponse'> & VerifyExternalWalletParams>): Promise<LinkedAccounts>;
|
|
687
719
|
protected verifyEmailOrPhoneLink({ verificationCode, }: InternalMethodParams<'verifyEmailOrPhoneLink'>): InternalMethodResponse<'verifyEmailOrPhoneLink'>;
|
|
720
|
+
protected sendLoginCode(): Promise<void>;
|
|
688
721
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare const PARA_CORE_VERSION: string;
|
|
2
2
|
export declare const PREFIX = "@CAPSULE/";
|
|
3
|
+
export declare const PARA_PREFIX = "@PARA/";
|
|
3
4
|
export declare const LOCAL_STORAGE_AUTH_INFO = "@CAPSULE/authInfo";
|
|
4
5
|
export declare const LOCAL_STORAGE_EMAIL = "@CAPSULE/e-mail";
|
|
5
6
|
export declare const LOCAL_STORAGE_PHONE = "@CAPSULE/phone";
|
|
@@ -13,6 +14,8 @@ export declare const LOCAL_STORAGE_WALLETS = "@CAPSULE/wallets";
|
|
|
13
14
|
export declare const LOCAL_STORAGE_EXTERNAL_WALLETS = "@CAPSULE/externalWallets";
|
|
14
15
|
export declare const LOCAL_STORAGE_CURRENT_WALLET_IDS = "@CAPSULE/currentWalletIds";
|
|
15
16
|
export declare const LOCAL_STORAGE_SESSION_COOKIE = "@CAPSULE/sessionCookie";
|
|
17
|
+
export declare const LOCAL_STORAGE_ENCLAVE_JWT = "@CAPSULE/enclaveJwt";
|
|
18
|
+
export declare const LOCAL_STORAGE_ENCLAVE_REFRESH_JWT = "@CAPSULE/enclaveRefreshJwt";
|
|
16
19
|
export declare const SESSION_STORAGE_LOGIN_ENCRYPTION_KEY_PAIR = "@CAPSULE/loginEncryptionKeyPair";
|
|
17
20
|
export declare const POLLING_INTERVAL_MS = 2000;
|
|
18
21
|
export declare const SHORT_POLLING_INTERVAL_MS = 1000;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export * from './types/coreApi.js';
|
|
|
5
5
|
export * from './types/events.js';
|
|
6
6
|
export * from './types/config.js';
|
|
7
7
|
export { getPortalDomain, entityToWallet, constructUrl, shortenUrl } from './utils/index.js';
|
|
8
|
-
export { PREFIX as STORAGE_PREFIX } from './constants.js';
|
|
8
|
+
export { PREFIX as STORAGE_PREFIX, PARA_PREFIX as PARA_STORAGE_PREFIX } from './constants.js';
|
|
9
9
|
export { distributeNewShare } from './shares/shareDistribution.js';
|
|
10
10
|
export { KeyContainer } from './shares/KeyContainer.js';
|
|
11
11
|
export type { PlatformUtils } from './PlatformUtils.js';
|
|
@@ -22,5 +22,6 @@ export { isWalletSupported } from './utils/wallet.js';
|
|
|
22
22
|
export { getNetworkPrefix, getOnRampAssets, getOnRampNetworks, toAssetInfoArray } from './utils/onRamps.js';
|
|
23
23
|
export { getPortalBaseURL } from './utils/url.js';
|
|
24
24
|
export { retrieve as transmissionUtilsRetrieve } from './transmission/transmissionUtils.js';
|
|
25
|
+
export type { ShareData } from './shares/enclave.js';
|
|
25
26
|
export declare const paraVersion: string;
|
|
26
27
|
export default ParaCore;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import UserManagementClient from '@getpara/user-management-client';
|
|
2
|
+
export interface ShareData {
|
|
3
|
+
userId: string;
|
|
4
|
+
walletId: string;
|
|
5
|
+
walletScheme: string;
|
|
6
|
+
partnerId?: string;
|
|
7
|
+
protocolId?: string;
|
|
8
|
+
signer: string;
|
|
9
|
+
createdAt?: string;
|
|
10
|
+
updatedAt?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ShareQuery {
|
|
13
|
+
userId: string;
|
|
14
|
+
walletId?: string;
|
|
15
|
+
partnerId?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface EncryptedPayload {
|
|
18
|
+
encryptedData: string;
|
|
19
|
+
keyId: string;
|
|
20
|
+
algorithm: string;
|
|
21
|
+
ephemeral: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Enclave client for secure key share operations
|
|
25
|
+
* Handles encryption/decryption and communication with the enclave service
|
|
26
|
+
*/
|
|
27
|
+
export declare class EnclaveClient {
|
|
28
|
+
private userManagementClient;
|
|
29
|
+
private enclavePublicKey;
|
|
30
|
+
private frontendKeyPair;
|
|
31
|
+
private retrieveJwt;
|
|
32
|
+
private persistJwt;
|
|
33
|
+
private retrieveRefreshJwt;
|
|
34
|
+
private persistRefreshJwt;
|
|
35
|
+
constructor({ userManagementClient, retrieveJwt, persistJwt, retrieveRefreshJwt, persistRefreshJwt, }: {
|
|
36
|
+
userManagementClient: UserManagementClient;
|
|
37
|
+
retrieveJwt: () => string;
|
|
38
|
+
persistJwt: (jwt: string) => void;
|
|
39
|
+
retrieveRefreshJwt: () => string;
|
|
40
|
+
persistRefreshJwt: (refreshJwt: string) => void;
|
|
41
|
+
});
|
|
42
|
+
private refreshJwt;
|
|
43
|
+
private withJwtRefreshRetry;
|
|
44
|
+
private issueEnclaveJwt;
|
|
45
|
+
/**
|
|
46
|
+
* Generate a P-256 keypair for the frontend to receive encrypted responses
|
|
47
|
+
*/
|
|
48
|
+
private generateFrontendKeyPair;
|
|
49
|
+
/**
|
|
50
|
+
* Get the enclave's public key from the user-management service
|
|
51
|
+
*/
|
|
52
|
+
private getEnclavePublicKey;
|
|
53
|
+
/**
|
|
54
|
+
* Import a PEM-formatted public key for use with Web Crypto API
|
|
55
|
+
*/
|
|
56
|
+
private importPublicKeyFromPEM;
|
|
57
|
+
/**
|
|
58
|
+
* Export a public key to PEM format
|
|
59
|
+
*/
|
|
60
|
+
private exportPublicKeyToPEM;
|
|
61
|
+
/**
|
|
62
|
+
* Encrypt data using P-256 ECIES for the enclave
|
|
63
|
+
*/
|
|
64
|
+
private encryptForEnclave;
|
|
65
|
+
/**
|
|
66
|
+
* Decrypt response encrypted for the frontend
|
|
67
|
+
*/
|
|
68
|
+
private decryptForFrontend;
|
|
69
|
+
/**
|
|
70
|
+
* Persist key shares to the enclave
|
|
71
|
+
* @param shares Array of share data to persist
|
|
72
|
+
*/
|
|
73
|
+
private persistShares;
|
|
74
|
+
/**
|
|
75
|
+
* Retrieve key shares from the enclave
|
|
76
|
+
* @param query Query parameters for finding shares (single query or array of queries)
|
|
77
|
+
*/
|
|
78
|
+
private retrieveShares;
|
|
79
|
+
retrieveSharesWithRetry(query: ShareQuery[]): Promise<ShareData[]>;
|
|
80
|
+
persistSharesWithRetry(shares: ShareData[]): Promise<any>;
|
|
81
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { BackupKitEmailProps } from '@getpara/user-management-client';
|
|
1
|
+
import { BackupKitEmailProps, TWalletScheme } from '@getpara/user-management-client';
|
|
2
2
|
import { Ctx } from '../types/index.js';
|
|
3
|
-
export declare function distributeNewShare({ ctx, userId, walletId, userShare, ignoreRedistributingBackupEncryptedShare, emailProps, partnerId, protocolId, }: {
|
|
3
|
+
export declare function distributeNewShare({ ctx, userId, walletId, userShare, ignoreRedistributingBackupEncryptedShare, emailProps, partnerId, protocolId, isEnclaveUser, walletScheme, }: {
|
|
4
4
|
ctx: Ctx;
|
|
5
5
|
userId: string;
|
|
6
6
|
walletId: string;
|
|
@@ -9,4 +9,6 @@ export declare function distributeNewShare({ ctx, userId, walletId, userShare, i
|
|
|
9
9
|
emailProps?: BackupKitEmailProps;
|
|
10
10
|
partnerId?: string;
|
|
11
11
|
protocolId?: string;
|
|
12
|
+
isEnclaveUser: boolean;
|
|
13
|
+
walletScheme: TWalletScheme;
|
|
12
14
|
}): Promise<string>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AxiosInstance } from 'axios';
|
|
2
2
|
import Client, { EmailTheme, Network, OnRampAsset, OnRampProvider, PregenAuth, TWalletScheme, TWalletType } from '@getpara/user-management-client';
|
|
3
3
|
import { Theme } from './theme.js';
|
|
4
|
+
import { EnclaveClient } from '../shares/enclave.js';
|
|
4
5
|
export declare enum Environment {
|
|
5
6
|
DEV = "DEV",
|
|
6
7
|
SANDBOX = "SANDBOX",
|
|
@@ -13,6 +14,7 @@ export interface Ctx {
|
|
|
13
14
|
env: Environment;
|
|
14
15
|
apiKey: string;
|
|
15
16
|
client: Client;
|
|
17
|
+
enclaveClient?: EnclaveClient;
|
|
16
18
|
disableWorkers?: boolean;
|
|
17
19
|
offloadMPCComputationURL?: string;
|
|
18
20
|
mpcComputationClient?: AxiosInstance;
|