@getpara/core-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/ParaCore.js +2600 -0
- package/dist/cjs/PlatformUtils.js +2 -0
- package/dist/cjs/StorageUtils.js +2 -0
- package/dist/cjs/cryptography/utils.js +251 -0
- package/dist/cjs/definitions.js +155 -0
- package/dist/cjs/errors.js +27 -0
- package/dist/cjs/external/mpcComputationClient.js +33 -0
- package/dist/cjs/external/userManagementClient.js +51 -0
- package/dist/cjs/index.js +81 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/shares/KeyContainer.js +84 -0
- package/dist/cjs/shares/recovery.js +62 -0
- package/dist/cjs/shares/shareDistribution.js +67 -0
- package/dist/cjs/transmission/transmissionUtils.js +73 -0
- package/dist/cjs/types/index.js +20 -0
- package/dist/cjs/types/params.js +2 -0
- package/dist/cjs/types/popupTypes.js +12 -0
- package/dist/cjs/types/theme.js +2 -0
- package/dist/cjs/types/walletTypes.js +2 -0
- package/dist/cjs/utils/formattingUtils.js +71 -0
- package/dist/cjs/utils/pollingUtils.js +25 -0
- package/dist/esm/ParaCore.js +2563 -0
- package/dist/esm/PlatformUtils.js +1 -0
- package/dist/esm/StorageUtils.js +1 -0
- package/dist/esm/cryptography/utils.js +226 -0
- package/dist/esm/definitions.js +142 -0
- package/dist/esm/errors.js +21 -0
- package/dist/esm/external/mpcComputationClient.js +26 -0
- package/dist/esm/external/userManagementClient.js +42 -0
- package/dist/esm/index.js +19 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/shares/KeyContainer.js +57 -0
- package/dist/esm/shares/recovery.js +58 -0
- package/dist/esm/shares/shareDistribution.js +63 -0
- package/dist/esm/transmission/transmissionUtils.js +45 -0
- package/dist/esm/types/index.js +4 -0
- package/dist/esm/types/params.js +1 -0
- package/dist/esm/types/popupTypes.js +9 -0
- package/dist/esm/types/theme.js +1 -0
- package/dist/esm/types/walletTypes.js +1 -0
- package/dist/esm/utils/formattingUtils.js +58 -0
- package/dist/esm/utils/pollingUtils.js +21 -0
- package/dist/types/ParaCore.d.ts +1021 -0
- package/dist/types/PlatformUtils.d.ts +48 -0
- package/dist/types/StorageUtils.d.ts +20 -0
- package/dist/types/cryptography/utils.d.ts +51 -0
- package/dist/types/definitions.d.ts +88 -0
- package/dist/types/errors.d.ts +12 -0
- package/dist/types/external/mpcComputationClient.d.ts +2 -0
- package/dist/types/external/userManagementClient.d.ts +13 -0
- package/dist/types/index.d.ts +22 -0
- package/dist/types/shares/KeyContainer.d.ts +14 -0
- package/dist/types/shares/recovery.d.ts +12 -0
- package/dist/types/shares/shareDistribution.d.ts +12 -0
- package/dist/types/transmission/transmissionUtils.d.ts +3 -0
- package/dist/types/types/index.d.ts +4 -0
- package/dist/types/types/params.d.ts +24 -0
- package/dist/types/types/popupTypes.d.ts +8 -0
- package/dist/types/types/theme.d.ts +12 -0
- package/dist/types/types/walletTypes.d.ts +11 -0
- package/dist/types/utils/formattingUtils.d.ts +16 -0
- package/dist/types/utils/pollingUtils.d.ts +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,2563 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
11
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
12
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
13
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
14
|
+
};
|
|
15
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
16
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
17
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
18
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
19
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
20
|
+
};
|
|
21
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
22
|
+
var t = {};
|
|
23
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
24
|
+
t[p] = s[p];
|
|
25
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
26
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
27
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
28
|
+
t[p[i]] = s[p[i]];
|
|
29
|
+
}
|
|
30
|
+
return t;
|
|
31
|
+
};
|
|
32
|
+
var _ParaCore_supportedWalletTypes, _ParaCore_supportedWalletTypesOpt;
|
|
33
|
+
import { AuthMethod, PublicKeyStatus, PublicKeyType, WalletType, WalletScheme, OAuthMethod, extractWalletRef, PasswordStatus, extractAuthInfo, } from '@getpara/user-management-client';
|
|
34
|
+
import forge from 'node-forge';
|
|
35
|
+
const { pki, jsbn } = forge;
|
|
36
|
+
import { decryptWithPrivateKey, getAsymmetricKeyPair, getPublicKeyHex } from './cryptography/utils.js';
|
|
37
|
+
import { CURRENT_WALLET_IDS_CHANGE_EVENT, EXTERNAL_WALLET_CHANGE_EVENT, WalletSchemeTypeMap, getPortalBaseURL, getParaConnectBaseUrl, } from './definitions.js';
|
|
38
|
+
import { getBaseUrl, initClient } from './external/userManagementClient.js';
|
|
39
|
+
import * as mpcComputationClient from './external/mpcComputationClient.js';
|
|
40
|
+
import { distributeNewShare } from './shares/shareDistribution.js';
|
|
41
|
+
import { PopupType, } from './types/index.js';
|
|
42
|
+
import * as transmissionUtils from './transmission/transmissionUtils.js';
|
|
43
|
+
import { sendRecoveryForShare } from './shares/recovery.js';
|
|
44
|
+
import parsePhoneNumberFromString from 'libphonenumber-js';
|
|
45
|
+
import { getCosmosAddress, truncateAddress } from './utils/formattingUtils.js';
|
|
46
|
+
import { TransactionReviewDenied, TransactionReviewError, TransactionReviewTimeout } from './errors.js';
|
|
47
|
+
const PARA_CORE_VERSION = '0.1.0';
|
|
48
|
+
function isPregenIdentifierMatch(a, b, type) {
|
|
49
|
+
if (!a || !b) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
switch (type) {
|
|
53
|
+
case 'EMAIL':
|
|
54
|
+
return a.toLowerCase() === b.toLowerCase();
|
|
55
|
+
case 'PHONE':
|
|
56
|
+
return stringToPhoneNumber(a) === stringToPhoneNumber(b);
|
|
57
|
+
case 'CUSTOM_ID':
|
|
58
|
+
return a === b;
|
|
59
|
+
default:
|
|
60
|
+
return a.replace(/^@/g, '').toLowerCase() === b.replace(/^@/g, '').toLowerCase();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export function entityToWallet(w) {
|
|
64
|
+
return Object.assign(Object.assign({}, w), { scheme: w.scheme, type: w.type, pregenIdentifierType: w.pregenIdentifierType });
|
|
65
|
+
}
|
|
66
|
+
function migrateWallet(obj) {
|
|
67
|
+
if (['USER', 'PREGEN'].includes(obj.type)) {
|
|
68
|
+
obj.isPregen = obj.type === 'PREGEN';
|
|
69
|
+
obj.type = obj.scheme === WalletScheme.ED25519 ? WalletType.SOLANA : WalletType.EVM;
|
|
70
|
+
}
|
|
71
|
+
if (!!obj.scheme && !obj.type) {
|
|
72
|
+
obj.type = obj.scheme === WalletScheme.ED25519 ? WalletType.SOLANA : WalletType.EVM;
|
|
73
|
+
}
|
|
74
|
+
return obj;
|
|
75
|
+
}
|
|
76
|
+
// Make sure to keep this in sync with capsule-org/src/entities/recoveryAttemptEntity.ts
|
|
77
|
+
export var RecoveryStatus;
|
|
78
|
+
(function (RecoveryStatus) {
|
|
79
|
+
RecoveryStatus["INITIATED"] = "INITIATED";
|
|
80
|
+
RecoveryStatus["READY"] = "READY";
|
|
81
|
+
RecoveryStatus["EXPIRED"] = "EXPIRED";
|
|
82
|
+
RecoveryStatus["FINISHED"] = "FINISHED";
|
|
83
|
+
RecoveryStatus["CANCELLED"] = "CANCELLED";
|
|
84
|
+
})(RecoveryStatus || (RecoveryStatus = {}));
|
|
85
|
+
/** @deprecated */
|
|
86
|
+
export var PregenIdentifierType;
|
|
87
|
+
(function (PregenIdentifierType) {
|
|
88
|
+
PregenIdentifierType["EMAIL"] = "EMAIL";
|
|
89
|
+
PregenIdentifierType["PHONE"] = "PHONE";
|
|
90
|
+
})(PregenIdentifierType || (PregenIdentifierType = {}));
|
|
91
|
+
export const PREFIX = '@CAPSULE/';
|
|
92
|
+
const LOCAL_STORAGE_EMAIL = `${PREFIX}e-mail`;
|
|
93
|
+
const LOCAL_STORAGE_PHONE = `${PREFIX}phone`;
|
|
94
|
+
const LOCAL_STORAGE_COUNTRY_CODE = `${PREFIX}countryCode`;
|
|
95
|
+
const LOCAL_STORAGE_FARCASTER_USERNAME = `${PREFIX}farcasterUsername`;
|
|
96
|
+
const LOCAL_STORAGE_TELEGRAM_USER_ID = `${PREFIX}telegramUserId`;
|
|
97
|
+
const LOCAL_STORAGE_USER_ID = `${PREFIX}userId`;
|
|
98
|
+
const LOCAL_STORAGE_ED25519_WALLETS = `${PREFIX}ed25519Wallets`;
|
|
99
|
+
const LOCAL_STORAGE_WALLETS = `${PREFIX}wallets`;
|
|
100
|
+
const LOCAL_STORAGE_EXTERNAL_WALLETS = `${PREFIX}externalWallets`;
|
|
101
|
+
const LOCAL_STORAGE_CURRENT_WALLET_IDS = `${PREFIX}currentWalletIds`;
|
|
102
|
+
const LOCAL_STORAGE_CURRENT_EXTERNAL_WALLET_ADDRESSES = `${PREFIX}currentExternalWalletAddresses`;
|
|
103
|
+
const LOCAL_STORAGE_SESSION_COOKIE = `${PREFIX}sessionCookie`;
|
|
104
|
+
const SESSION_STORAGE_LOGIN_ENCRYPTION_KEY_PAIR = `${PREFIX}loginEncryptionKeyPair`;
|
|
105
|
+
const POLLING_INTERVAL_MS = 2000;
|
|
106
|
+
const SHORT_POLLING_INTERVAL_MS = 1000;
|
|
107
|
+
export function stringToPhoneNumber(str) {
|
|
108
|
+
var _a;
|
|
109
|
+
return (_a = parsePhoneNumberFromString(str)) === null || _a === void 0 ? void 0 : _a.formatInternational().replace(/[^\d+]/g, '');
|
|
110
|
+
}
|
|
111
|
+
export function normalizePhoneNumber(countryCode, number) {
|
|
112
|
+
return stringToPhoneNumber(`${countryCode[0] !== '+' ? '+' : ''}${countryCode}${number}`);
|
|
113
|
+
}
|
|
114
|
+
export function isWalletSupported(types, wallet) {
|
|
115
|
+
return types.some((walletType) => !!WalletSchemeTypeMap[wallet.scheme][walletType]);
|
|
116
|
+
}
|
|
117
|
+
function getSchemes(types) {
|
|
118
|
+
return Object.keys(WalletSchemeTypeMap).filter(scheme => {
|
|
119
|
+
if (scheme === WalletScheme.CGGMP) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
return (Array.isArray(types) ? types : Object.keys(types)).some(type => WalletSchemeTypeMap[scheme][type]);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
export function getWalletTypes(schemes) {
|
|
126
|
+
return [
|
|
127
|
+
...new Set(schemes.reduce((acc, scheme) => {
|
|
128
|
+
return [...acc, ...Object.keys(WalletSchemeTypeMap[scheme]).filter(type => WalletSchemeTypeMap[scheme][type])];
|
|
129
|
+
}, [])),
|
|
130
|
+
];
|
|
131
|
+
}
|
|
132
|
+
export function getEquivalentTypes(types) {
|
|
133
|
+
return getWalletTypes(getSchemes((Array.isArray(types) ? types : [types]).map(t => WalletType[t])));
|
|
134
|
+
}
|
|
135
|
+
export function isCosmosRequired(supportedWalletTypes) {
|
|
136
|
+
return supportedWalletTypes.some(({ type, optional }) => type === WalletType.COSMOS && !optional);
|
|
137
|
+
}
|
|
138
|
+
function constructUrl({ base, path, params = {}, }) {
|
|
139
|
+
const url = new URL(path, base);
|
|
140
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
141
|
+
if (!!value && value !== 'undefined' && value !== 'null')
|
|
142
|
+
url.searchParams.set(key, value.toString());
|
|
143
|
+
});
|
|
144
|
+
return url.toString();
|
|
145
|
+
}
|
|
146
|
+
export class ParaCore {
|
|
147
|
+
get isEmail() {
|
|
148
|
+
return !!this.email && !this.phone && !this.countryCode && !this.farcasterUsername && !this.telegramUserId;
|
|
149
|
+
}
|
|
150
|
+
get isPhone() {
|
|
151
|
+
return !!this.phone && !!this.countryCode && !this.email && !this.farcasterUsername && !this.telegramUserId;
|
|
152
|
+
}
|
|
153
|
+
get isFarcaster() {
|
|
154
|
+
return !!this.farcasterUsername && !this.email && !this.phone && !this.countryCode && !this.telegramUserId;
|
|
155
|
+
}
|
|
156
|
+
get isTelegram() {
|
|
157
|
+
return !!this.telegramUserId && !this.email && !this.phone && !this.countryCode && !this.farcasterUsername;
|
|
158
|
+
}
|
|
159
|
+
get currentWalletIdsArray() {
|
|
160
|
+
return this.supportedWalletTypes.reduce((acc, { type }) => {
|
|
161
|
+
var _a;
|
|
162
|
+
return [
|
|
163
|
+
...acc,
|
|
164
|
+
...((_a = this.currentWalletIds[type]) !== null && _a !== void 0 ? _a : []).map(id => {
|
|
165
|
+
return [id, type];
|
|
166
|
+
}),
|
|
167
|
+
];
|
|
168
|
+
}, []);
|
|
169
|
+
}
|
|
170
|
+
get currentWalletIdsUnique() {
|
|
171
|
+
return [...new Set(Object.values(this.currentWalletIds).flat())];
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* A map of pre-generated wallet identifiers that can be claimed in the current instance.
|
|
175
|
+
*/
|
|
176
|
+
get pregenIds() {
|
|
177
|
+
return Object.assign({}, Object.values(this.wallets)
|
|
178
|
+
.filter(wallet => !this.userId || this.isPregenWalletClaimable(wallet))
|
|
179
|
+
.reduce((acc, wallet) => {
|
|
180
|
+
var _a, _b;
|
|
181
|
+
if (((_a = acc[wallet.pregenIdentifierType]) !== null && _a !== void 0 ? _a : []).includes(wallet.pregenIdentifier)) {
|
|
182
|
+
return acc;
|
|
183
|
+
}
|
|
184
|
+
return Object.assign(Object.assign({}, acc), { [wallet.pregenIdentifierType]: [
|
|
185
|
+
...new Set([...((_b = acc[wallet.pregenIdentifierType]) !== null && _b !== void 0 ? _b : []), wallet.pregenIdentifier]),
|
|
186
|
+
] });
|
|
187
|
+
}, {}));
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Whether the instance has multiple wallets connected.
|
|
191
|
+
*/
|
|
192
|
+
get isMultiWallet() {
|
|
193
|
+
return this.currentWalletIdsArray.length > 1;
|
|
194
|
+
}
|
|
195
|
+
get supportedWalletTypes() {
|
|
196
|
+
var _a;
|
|
197
|
+
return (_a = __classPrivateFieldGet(this, _ParaCore_supportedWalletTypes, "f")) !== null && _a !== void 0 ? _a : [];
|
|
198
|
+
}
|
|
199
|
+
get isWalletTypeEnabled() {
|
|
200
|
+
return this.supportedWalletTypes.reduce((acc, { type }) => {
|
|
201
|
+
return Object.assign(Object.assign({}, acc), { [type]: true });
|
|
202
|
+
}, {});
|
|
203
|
+
}
|
|
204
|
+
convertBigInt(bigInt) {
|
|
205
|
+
const convertedBigInt = new jsbn.BigInteger(null);
|
|
206
|
+
convertedBigInt.data = bigInt.data;
|
|
207
|
+
convertedBigInt.s = bigInt.s;
|
|
208
|
+
convertedBigInt.t = bigInt.t;
|
|
209
|
+
return convertedBigInt;
|
|
210
|
+
}
|
|
211
|
+
convertEncryptionKeyPair(jsonKeyPair) {
|
|
212
|
+
return {
|
|
213
|
+
privateKey: pki.setRsaPrivateKey(this.convertBigInt(jsonKeyPair.privateKey.n), this.convertBigInt(jsonKeyPair.privateKey.e), this.convertBigInt(jsonKeyPair.privateKey.d), this.convertBigInt(jsonKeyPair.privateKey.p), this.convertBigInt(jsonKeyPair.privateKey.q), this.convertBigInt(jsonKeyPair.privateKey.dP), this.convertBigInt(jsonKeyPair.privateKey.dQ), this.convertBigInt(jsonKeyPair.privateKey.qInv)),
|
|
214
|
+
publicKey: pki.setRsaPublicKey(this.convertBigInt(jsonKeyPair.publicKey.n), this.convertBigInt(jsonKeyPair.publicKey.e)),
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
isPortal(envOverride) {
|
|
218
|
+
return (typeof window !== 'undefined' &&
|
|
219
|
+
getPortalBaseURL(envOverride ? { env: envOverride } : this.ctx).includes(window.location.host));
|
|
220
|
+
}
|
|
221
|
+
isParaConnect() {
|
|
222
|
+
return typeof window !== 'undefined' && getParaConnectBaseUrl(this.ctx).includes(window.location.host);
|
|
223
|
+
}
|
|
224
|
+
requireApiKey() {
|
|
225
|
+
if (!this.ctx.apiKey) {
|
|
226
|
+
throw new Error(`in order to create a wallet or user with Para, you
|
|
227
|
+
must provide an API key to the Para instance`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
isWalletSupported(wallet) {
|
|
231
|
+
var _a;
|
|
232
|
+
return !__classPrivateFieldGet(this, _ParaCore_supportedWalletTypes, "f") || isWalletSupported((_a = this.supportedWalletTypes.map(({ type }) => type)) !== null && _a !== void 0 ? _a : [], wallet);
|
|
233
|
+
}
|
|
234
|
+
isWalletOwned(wallet) {
|
|
235
|
+
return (this.isWalletSupported(wallet) &&
|
|
236
|
+
!wallet.pregenIdentifier &&
|
|
237
|
+
!wallet.pregenIdentifierType &&
|
|
238
|
+
!!this.userId &&
|
|
239
|
+
wallet.userId === this.userId);
|
|
240
|
+
}
|
|
241
|
+
isPregenWalletUnclaimed(wallet) {
|
|
242
|
+
return (this.isWalletSupported(wallet) &&
|
|
243
|
+
(!wallet.userId || (wallet.isPregen && !!wallet.pregenIdentifier && !!wallet.pregenIdentifierType)));
|
|
244
|
+
}
|
|
245
|
+
isPregenWalletClaimable(wallet) {
|
|
246
|
+
return (this.isWalletSupported(wallet) &&
|
|
247
|
+
this.isPregenWalletUnclaimed(wallet) &&
|
|
248
|
+
(!['EMAIL', 'PHONE', 'TELEGRAM'].includes(wallet.pregenIdentifierType) ||
|
|
249
|
+
isPregenIdentifierMatch(wallet.pregenIdentifierType === 'EMAIL'
|
|
250
|
+
? this.email
|
|
251
|
+
: wallet.pregenIdentifierType === 'TELEGRAM'
|
|
252
|
+
? this.telegramUserId
|
|
253
|
+
: this.getPhoneNumber(), wallet.pregenIdentifier, wallet.pregenIdentifierType)));
|
|
254
|
+
}
|
|
255
|
+
isWalletUsable(walletId, { type: types, scheme: schemes, forbidPregen = false } = {}, throwError = false) {
|
|
256
|
+
let error;
|
|
257
|
+
if (!this.wallets[walletId]) {
|
|
258
|
+
error = `wallet with id ${walletId} does not exist`;
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
const wallet = this.wallets[walletId];
|
|
262
|
+
const [isUnclaimed, isOwned] = [this.isPregenWalletUnclaimed(wallet), this.isWalletOwned(wallet)];
|
|
263
|
+
if (forbidPregen && isUnclaimed) {
|
|
264
|
+
error = `pre-generated wallet with id ${wallet.id} cannot be selected`;
|
|
265
|
+
}
|
|
266
|
+
else if (!isOwned && !isUnclaimed) {
|
|
267
|
+
error = `wallet with id ${wallet.id} is not owned by the current user`;
|
|
268
|
+
}
|
|
269
|
+
else if (!this.isWalletSupported(wallet)) {
|
|
270
|
+
error = `wallet with id ${wallet.id} and type ${wallet.type} is not supported, supported types are: ${this.supportedWalletTypes.map(({ type }) => type).join(', ')}`;
|
|
271
|
+
}
|
|
272
|
+
else if (types &&
|
|
273
|
+
(!getEquivalentTypes(types).includes(wallet.type) ||
|
|
274
|
+
(isOwned && !types.some(type => { var _a; return ((_a = this.currentWalletIds[type]) !== null && _a !== void 0 ? _a : []).includes(walletId); })))) {
|
|
275
|
+
error = `wallet with id ${wallet.id} and type ${wallet.type} cannot be selected`;
|
|
276
|
+
}
|
|
277
|
+
else if (schemes && !schemes.includes(wallet.scheme)) {
|
|
278
|
+
error = `wallet with id ${wallet.id} and scheme ${wallet.scheme} cannot be selected`;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (error) {
|
|
282
|
+
if (throwError) {
|
|
283
|
+
throw new Error(error);
|
|
284
|
+
}
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Returns the formatted address for the desired wallet ID, depending on your app settings.
|
|
291
|
+
* @param {string} walletId the ID of the wallet address to display.
|
|
292
|
+
* @param {object} options additional options for formatting the address.
|
|
293
|
+
* @param {boolean} options.truncate whether to truncate the address.
|
|
294
|
+
* @param {WalletType} options.addressType the type of address to display.
|
|
295
|
+
* @returns the formatted address
|
|
296
|
+
*/
|
|
297
|
+
getDisplayAddress(walletId, options = {}) {
|
|
298
|
+
var _a;
|
|
299
|
+
if (this.externalWallets[walletId]) {
|
|
300
|
+
const wallet = this.externalWallets[walletId];
|
|
301
|
+
return options.truncate ? truncateAddress(wallet.address, wallet.type, { prefix: this.cosmosPrefix }) : wallet.address;
|
|
302
|
+
}
|
|
303
|
+
const wallet = this.findWallet(walletId, options.addressType);
|
|
304
|
+
if (!wallet) {
|
|
305
|
+
return undefined;
|
|
306
|
+
}
|
|
307
|
+
let str;
|
|
308
|
+
switch (wallet.type) {
|
|
309
|
+
case WalletType.COSMOS:
|
|
310
|
+
str = getCosmosAddress(wallet.publicKey, (_a = this.cosmosPrefix) !== null && _a !== void 0 ? _a : 'cosmos');
|
|
311
|
+
break;
|
|
312
|
+
default:
|
|
313
|
+
str = wallet.address;
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
return options.truncate ? truncateAddress(str, wallet.type, { prefix: this.cosmosPrefix }) : str;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Returns a unique hash for a wallet suitable for use as an identicon seed.
|
|
320
|
+
* @param {string} walletId the ID of the wallet.
|
|
321
|
+
* @param {boolean} options.addressType used to format the hash for another wallet type.
|
|
322
|
+
* @returns the identicon hash string
|
|
323
|
+
*/
|
|
324
|
+
getIdenticonHash(walletId, overrideType) {
|
|
325
|
+
if (this.externalWallets[walletId]) {
|
|
326
|
+
const wallet = this.externalWallets[walletId];
|
|
327
|
+
return `${wallet.id}-${wallet.address}-${wallet.type}`;
|
|
328
|
+
}
|
|
329
|
+
const wallet = this.findWallet(walletId, overrideType);
|
|
330
|
+
return wallet ? `${wallet.id}-${wallet.address}-${wallet.type}` : undefined;
|
|
331
|
+
}
|
|
332
|
+
getWallets() {
|
|
333
|
+
return this.wallets;
|
|
334
|
+
}
|
|
335
|
+
getAddress(walletId) {
|
|
336
|
+
var _a, _b;
|
|
337
|
+
return walletId ? this.wallets[walletId].address : (_b = (_a = Object.values(this.wallets)) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.address;
|
|
338
|
+
}
|
|
339
|
+
constructPortalUrl(type, opts = {}) {
|
|
340
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
341
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
342
|
+
const base = type === 'onRamp' ? getPortalBaseURL(this.ctx) : yield this.getPortalURL(opts.partnerId);
|
|
343
|
+
let path;
|
|
344
|
+
switch (type) {
|
|
345
|
+
case 'createPassword': {
|
|
346
|
+
path = `/web/users/${this.userId}/passwords/${opts.pathId}`;
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
case 'createAuth': {
|
|
350
|
+
path = `/web/users/${this.userId}/biometrics/${opts.pathId}`;
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
case 'loginPassword': {
|
|
354
|
+
path = '/web/passwords/login';
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
case 'loginAuth': {
|
|
358
|
+
path = '/web/biometrics/login';
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
case 'txReview': {
|
|
362
|
+
path = `/web/users/${this.userId}/transaction-review/${opts.pathId}`;
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
case 'onRamp': {
|
|
366
|
+
path = `/web/users/${this.userId}/on-ramp-transaction/${opts.pathId}`;
|
|
367
|
+
break;
|
|
368
|
+
}
|
|
369
|
+
default: {
|
|
370
|
+
throw new Error(`invalid URL type ${type}`);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
const [isCreate, isLogin, isOnRamp] = [
|
|
374
|
+
['createAuth', 'createPassword'].includes(type),
|
|
375
|
+
['loginAuth', 'loginPassword'].includes(type),
|
|
376
|
+
type === 'onRamp',
|
|
377
|
+
];
|
|
378
|
+
const partner = opts.partnerId
|
|
379
|
+
? (_a = (yield this.ctx.client.getPartner(opts.partnerId)).data) === null || _a === void 0 ? void 0 : _a.partner
|
|
380
|
+
: undefined;
|
|
381
|
+
const params = Object.assign(Object.assign(Object.assign(Object.assign({ apiKey: this.ctx.apiKey, partnerId: opts.partnerId, portalFont: ((_b = opts.theme) === null || _b === void 0 ? void 0 : _b.font) || (partner === null || partner === void 0 ? void 0 : partner.font) || ((_c = this.portalTheme) === null || _c === void 0 ? void 0 : _c.font), portalBorderRadius: ((_d = opts.theme) === null || _d === void 0 ? void 0 : _d.borderRadius) || ((_e = this.portalTheme) === null || _e === void 0 ? void 0 : _e.borderRadius), portalThemeMode: ((_f = opts.theme) === null || _f === void 0 ? void 0 : _f.mode) || (partner === null || partner === void 0 ? void 0 : partner.themeMode) || ((_g = this.portalTheme) === null || _g === void 0 ? void 0 : _g.mode), portalAccentColor: ((_h = opts.theme) === null || _h === void 0 ? void 0 : _h.accentColor) || (partner === null || partner === void 0 ? void 0 : partner.accentColor) || ((_j = this.portalTheme) === null || _j === void 0 ? void 0 : _j.accentColor), portalForegroundColor: ((_k = opts.theme) === null || _k === void 0 ? void 0 : _k.foregroundColor) || (partner === null || partner === void 0 ? void 0 : partner.foregroundColor) || ((_l = this.portalTheme) === null || _l === void 0 ? void 0 : _l.foregroundColor), portalBackgroundColor: ((_m = opts.theme) === null || _m === void 0 ? void 0 : _m.backgroundColor) ||
|
|
382
|
+
(partner === null || partner === void 0 ? void 0 : partner.backgroundColor) ||
|
|
383
|
+
this.portalBackgroundColor ||
|
|
384
|
+
((_o = this.portalTheme) === null || _o === void 0 ? void 0 : _o.backgroundColor), portalPrimaryButtonColor: this.portalPrimaryButtonColor, portalTextColor: this.portalTextColor, portalPrimaryButtonTextColor: this.portalPrimaryButtonTextColor, isForNewDevice: opts.isForNewDevice ? opts.isForNewDevice.toString() : undefined, supportedWalletTypes: __classPrivateFieldGet(this, _ParaCore_supportedWalletTypesOpt, "f") ? JSON.stringify(__classPrivateFieldGet(this, _ParaCore_supportedWalletTypesOpt, "f")) : undefined }, (isCreate || isLogin
|
|
385
|
+
? Object.assign(Object.assign(Object.assign(Object.assign({}, (opts.authType === 'email' ? { email: this.email } : {})), (opts.authType === 'phone' ? { phone: this.phone, countryCode: this.countryCode } : {})), (opts.authType === 'farcaster' ? { farcasterUsername: this.farcasterUsername } : {})), (opts.authType === 'telegram' ? { telegramUserId: this.telegramUserId } : {})) : {})), (isLogin || isOnRamp ? { sessionId: opts.sessionId } : {})), (isLogin
|
|
386
|
+
? {
|
|
387
|
+
encryptionKey: opts.loginEncryptionPublicKey,
|
|
388
|
+
newDeviceSessionLookupId: opts.newDeviceSessionId,
|
|
389
|
+
newDeviceEncryptionKey: opts.newDeviceEncryptionKey,
|
|
390
|
+
pregenIds: JSON.stringify(this.pregenIds),
|
|
391
|
+
displayName: opts.displayName,
|
|
392
|
+
pfpUrl: opts.pfpUrl,
|
|
393
|
+
}
|
|
394
|
+
: {})), (opts.params || {}));
|
|
395
|
+
return constructUrl({ base, path, params });
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Constructs a new `ParaCore` instance.
|
|
400
|
+
* @param env - `Environment` to use.
|
|
401
|
+
* @param apiKey - API key to use.
|
|
402
|
+
* @param opts - Additional constructor options; see `ConstructorOpts`.
|
|
403
|
+
* @returns - A new ParaCore instance.
|
|
404
|
+
*/
|
|
405
|
+
constructor(env, apiKey, opts) {
|
|
406
|
+
var _a;
|
|
407
|
+
this.isAwaitingAccountCreation = false;
|
|
408
|
+
this.isAwaitingLogin = false;
|
|
409
|
+
this.isAwaitingFarcaster = false;
|
|
410
|
+
this.isAwaitingOAuth = false;
|
|
411
|
+
/**
|
|
412
|
+
* 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.
|
|
413
|
+
*/
|
|
414
|
+
this.currentWalletIds = {};
|
|
415
|
+
_ParaCore_supportedWalletTypes.set(this, undefined);
|
|
416
|
+
_ParaCore_supportedWalletTypesOpt.set(this, undefined);
|
|
417
|
+
this.localStorageGetItem = (key) => {
|
|
418
|
+
return this.platformUtils.localStorage.get(key);
|
|
419
|
+
};
|
|
420
|
+
this.localStorageSetItem = (key, value) => {
|
|
421
|
+
return this.platformUtils.localStorage.set(key, value);
|
|
422
|
+
};
|
|
423
|
+
this.sessionStorageGetItem = (key) => {
|
|
424
|
+
return this.platformUtils.sessionStorage.get(key);
|
|
425
|
+
};
|
|
426
|
+
this.sessionStorageSetItem = (key, value) => {
|
|
427
|
+
return this.platformUtils.sessionStorage.set(key, value);
|
|
428
|
+
};
|
|
429
|
+
this.sessionStorageRemoveItem = (key) => {
|
|
430
|
+
return this.platformUtils.sessionStorage.removeItem(key);
|
|
431
|
+
};
|
|
432
|
+
this.retrieveSessionCookie = () => {
|
|
433
|
+
return this.sessionCookie;
|
|
434
|
+
};
|
|
435
|
+
/**
|
|
436
|
+
* Remove all local storage and prefixed session storage.
|
|
437
|
+
* @param {'local' | 'session' | 'secure' | 'all'} type - Type of storage to clear. Defaults to 'all'.
|
|
438
|
+
*/
|
|
439
|
+
this.clearStorage = (type = 'all') => __awaiter(this, void 0, void 0, function* () {
|
|
440
|
+
const isAll = type === 'all';
|
|
441
|
+
(isAll || type === 'local') && this.platformUtils.localStorage.clear(PREFIX);
|
|
442
|
+
(isAll || type === 'session') && this.platformUtils.sessionStorage.clear(PREFIX);
|
|
443
|
+
if ((isAll || type === 'secure') && this.platformUtils.secureStorage) {
|
|
444
|
+
this.platformUtils.secureStorage.clear(PREFIX);
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
/**
|
|
448
|
+
* Creates several new wallets with the desired types. If no types are provided, this method
|
|
449
|
+
* will create one for each of the non-optional types specified in the instance's `supportedWalletTypes`
|
|
450
|
+
* object that are not already present. This is automatically called upon account creation to ensure that
|
|
451
|
+
* the user has a wallet of each required type.
|
|
452
|
+
*
|
|
453
|
+
* @deprecated alias for `createWalletPerType`
|
|
454
|
+
**/
|
|
455
|
+
this.createWalletPerMissingType = this.createWalletPerType;
|
|
456
|
+
// TODO: consider using sessionStorage instead of localStorage
|
|
457
|
+
if (!opts)
|
|
458
|
+
opts = {};
|
|
459
|
+
this.emailPrimaryColor = opts.emailPrimaryColor;
|
|
460
|
+
this.emailTheme = opts.emailTheme;
|
|
461
|
+
this.homepageUrl = opts.homepageUrl;
|
|
462
|
+
this.supportUrl = opts.supportUrl;
|
|
463
|
+
this.xUrl = opts.xUrl;
|
|
464
|
+
this.githubUrl = opts.githubUrl;
|
|
465
|
+
this.linkedinUrl = opts.linkedinUrl;
|
|
466
|
+
this.portalBackgroundColor = opts.portalBackgroundColor;
|
|
467
|
+
this.portalPrimaryButtonColor = opts.portalPrimaryButtonColor;
|
|
468
|
+
this.portalTextColor = opts.portalTextColor;
|
|
469
|
+
this.portalPrimaryButtonTextColor = opts.portalPrimaryButtonTextColor;
|
|
470
|
+
this.portalTheme = opts.portalTheme;
|
|
471
|
+
this.platformUtils = this.getPlatformUtils();
|
|
472
|
+
this.disableProviderModal = this.platformUtils.disableProviderModal;
|
|
473
|
+
if (opts.useStorageOverrides) {
|
|
474
|
+
this.localStorageGetItem = opts.localStorageGetItemOverride;
|
|
475
|
+
this.localStorageSetItem = opts.localStorageSetItemOverride;
|
|
476
|
+
this.sessionStorageGetItem = opts.sessionStorageGetItemOverride;
|
|
477
|
+
this.sessionStorageSetItem = opts.sessionStorageSetItemOverride;
|
|
478
|
+
this.sessionStorageRemoveItem = opts.sessionStorageRemoveItemOverride;
|
|
479
|
+
this.clearStorage = opts.clearStorageOverride;
|
|
480
|
+
}
|
|
481
|
+
if (opts.useSessionStorage) {
|
|
482
|
+
this.localStorageGetItem = this.sessionStorageGetItem;
|
|
483
|
+
this.localStorageSetItem = this.sessionStorageSetItem;
|
|
484
|
+
}
|
|
485
|
+
this.persistSessionCookie = (cookie) => {
|
|
486
|
+
this.sessionCookie = cookie;
|
|
487
|
+
(opts.useSessionStorage ? this.sessionStorageSetItem : this.localStorageSetItem)(LOCAL_STORAGE_SESSION_COOKIE, cookie);
|
|
488
|
+
};
|
|
489
|
+
this.ctx = {
|
|
490
|
+
env,
|
|
491
|
+
apiKey,
|
|
492
|
+
client: initClient({
|
|
493
|
+
env,
|
|
494
|
+
version: ParaCore.version,
|
|
495
|
+
apiKey,
|
|
496
|
+
partnerId: this.isPortal(env) ? opts.portalPartnerId : undefined,
|
|
497
|
+
useFetchAdapter: !!opts.disableWorkers,
|
|
498
|
+
retrieveSessionCookie: this.retrieveSessionCookie,
|
|
499
|
+
persistSessionCookie: this.persistSessionCookie,
|
|
500
|
+
}),
|
|
501
|
+
disableWorkers: opts.disableWorkers,
|
|
502
|
+
offloadMPCComputationURL: opts.offloadMPCComputationURL,
|
|
503
|
+
useLocalFiles: opts.useLocalFiles,
|
|
504
|
+
useDKLS: opts.useDKLSForCreation || !opts.offloadMPCComputationURL,
|
|
505
|
+
disableWebSockets: !!opts.disableWebSockets,
|
|
506
|
+
wasmOverride: opts.wasmOverride,
|
|
507
|
+
cosmosPrefix: this.cosmosPrefix,
|
|
508
|
+
};
|
|
509
|
+
if (opts.offloadMPCComputationURL) {
|
|
510
|
+
this.ctx.mpcComputationClient = mpcComputationClient.initClient(opts.offloadMPCComputationURL, opts.disableWorkers);
|
|
511
|
+
}
|
|
512
|
+
// Support legacy supportedWalletTypes
|
|
513
|
+
try {
|
|
514
|
+
__classPrivateFieldSet(this, _ParaCore_supportedWalletTypes, opts.supportedWalletTypes
|
|
515
|
+
? (() => {
|
|
516
|
+
if (Object.values(opts.supportedWalletTypes).every(config => !!config && typeof config === 'object' && config.optional)) {
|
|
517
|
+
throw new Error('at least one wallet type must be non-optional');
|
|
518
|
+
}
|
|
519
|
+
if (!Object.keys(opts.supportedWalletTypes).every(type => Object.values(WalletType).includes(type))) {
|
|
520
|
+
throw new Error('unsupported wallet type');
|
|
521
|
+
}
|
|
522
|
+
__classPrivateFieldSet(this, _ParaCore_supportedWalletTypesOpt, opts.supportedWalletTypes, "f");
|
|
523
|
+
return Object.entries(opts.supportedWalletTypes).reduce((acc, [key, value]) => {
|
|
524
|
+
var _a;
|
|
525
|
+
if (!value) {
|
|
526
|
+
return acc;
|
|
527
|
+
}
|
|
528
|
+
if (key === WalletType.COSMOS &&
|
|
529
|
+
typeof value === 'object' &&
|
|
530
|
+
!!value.prefix) {
|
|
531
|
+
this.cosmosPrefix = value.prefix;
|
|
532
|
+
}
|
|
533
|
+
return [...acc, { type: key, optional: value === true ? false : ((_a = value.optional) !== null && _a !== void 0 ? _a : false) }];
|
|
534
|
+
}, []);
|
|
535
|
+
})()
|
|
536
|
+
: undefined, "f");
|
|
537
|
+
}
|
|
538
|
+
catch (e) {
|
|
539
|
+
__classPrivateFieldSet(this, _ParaCore_supportedWalletTypes, undefined, "f");
|
|
540
|
+
}
|
|
541
|
+
if (!this.platformUtils.isSyncStorage || opts.useStorageOverrides) {
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
this.email = this.localStorageGetItem(LOCAL_STORAGE_EMAIL) || undefined;
|
|
545
|
+
this.countryCode = this.localStorageGetItem(LOCAL_STORAGE_COUNTRY_CODE) || undefined;
|
|
546
|
+
this.phone = this.localStorageGetItem(LOCAL_STORAGE_PHONE) || undefined;
|
|
547
|
+
this.userId = this.localStorageGetItem(LOCAL_STORAGE_USER_ID) || undefined;
|
|
548
|
+
this.telegramUserId = this.localStorageGetItem(LOCAL_STORAGE_TELEGRAM_USER_ID) || undefined;
|
|
549
|
+
const stringWallets = this.platformUtils.secureStorage
|
|
550
|
+
? this.platformUtils.secureStorage.get(LOCAL_STORAGE_WALLETS)
|
|
551
|
+
: this.localStorageGetItem(LOCAL_STORAGE_WALLETS);
|
|
552
|
+
const _wallets = JSON.parse(stringWallets || '{}');
|
|
553
|
+
const stringEd25519Wallets = this.platformUtils.secureStorage
|
|
554
|
+
? this.platformUtils.secureStorage.get(LOCAL_STORAGE_ED25519_WALLETS)
|
|
555
|
+
: this.localStorageGetItem(LOCAL_STORAGE_ED25519_WALLETS);
|
|
556
|
+
const _ed25519Wallets = JSON.parse(stringEd25519Wallets || '{}');
|
|
557
|
+
const wallets = Object.assign(Object.assign({}, Object.keys(_wallets).reduce((res, key) => {
|
|
558
|
+
return Object.assign(Object.assign({}, res), { [key]: migrateWallet(_wallets[key]) });
|
|
559
|
+
}, {})), Object.keys(_ed25519Wallets).reduce((res, key) => {
|
|
560
|
+
return Object.assign(Object.assign({}, res), (!res[key] ? { [key]: migrateWallet(_ed25519Wallets[key]) } : {}));
|
|
561
|
+
}, {}));
|
|
562
|
+
this.setWallets(wallets);
|
|
563
|
+
// TODO: Improve not great check
|
|
564
|
+
const _currentWalletIds = (_a = this.localStorageGetItem(LOCAL_STORAGE_CURRENT_WALLET_IDS)) !== null && _a !== void 0 ? _a : undefined;
|
|
565
|
+
const currentWalletIds = [undefined, null, 'undefined'].includes(_currentWalletIds)
|
|
566
|
+
? {}
|
|
567
|
+
: (() => {
|
|
568
|
+
const fromJson = JSON.parse(_currentWalletIds);
|
|
569
|
+
return Array.isArray(fromJson)
|
|
570
|
+
? Object.keys(WalletType).reduce((acc, type) => {
|
|
571
|
+
const wallet = Object.values(this.wallets).find(w => fromJson.includes(w.id) && WalletSchemeTypeMap[w.scheme][type]);
|
|
572
|
+
return Object.assign(Object.assign({}, acc), (wallet && !acc[type] ? { [type]: [wallet.id] } : {}));
|
|
573
|
+
}, {})
|
|
574
|
+
: fromJson;
|
|
575
|
+
})();
|
|
576
|
+
this.setCurrentWalletIds(currentWalletIds);
|
|
577
|
+
// TODO: remove sessionStorageGetItem call once new version is being consumed
|
|
578
|
+
this.sessionCookie =
|
|
579
|
+
this.localStorageGetItem(LOCAL_STORAGE_SESSION_COOKIE) ||
|
|
580
|
+
this.sessionStorageGetItem(LOCAL_STORAGE_SESSION_COOKIE) ||
|
|
581
|
+
undefined;
|
|
582
|
+
// In case currentWalletIds was missing from storage
|
|
583
|
+
if (Object.values(this.wallets).filter(w => this.isWalletOwned(w)).length > 0 &&
|
|
584
|
+
this.currentWalletIdsArray.length === 0) {
|
|
585
|
+
this.findWalletId(undefined, { forbidPregen: true });
|
|
586
|
+
}
|
|
587
|
+
const loginEncryptionKey = this.sessionStorageGetItem(SESSION_STORAGE_LOGIN_ENCRYPTION_KEY_PAIR);
|
|
588
|
+
if (loginEncryptionKey && loginEncryptionKey !== 'undefined') {
|
|
589
|
+
this.loginEncryptionKeyPair = this.convertEncryptionKeyPair(JSON.parse(loginEncryptionKey));
|
|
590
|
+
}
|
|
591
|
+
const stringExternalWallets = this.localStorageGetItem(LOCAL_STORAGE_EXTERNAL_WALLETS);
|
|
592
|
+
const _externalWallets = JSON.parse(stringExternalWallets || '{}');
|
|
593
|
+
this.setExternalWallets(_externalWallets);
|
|
594
|
+
const _currentExternalWalletAddresses = this.localStorageGetItem(LOCAL_STORAGE_CURRENT_EXTERNAL_WALLET_ADDRESSES) || undefined;
|
|
595
|
+
this.currentExternalWalletAddresses = _currentExternalWalletAddresses
|
|
596
|
+
? JSON.parse(_currentExternalWalletAddresses)
|
|
597
|
+
: undefined;
|
|
598
|
+
}
|
|
599
|
+
touchSession(regenerate = false) {
|
|
600
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
601
|
+
const res = yield this.ctx.client.touchSession(regenerate);
|
|
602
|
+
this.setSupportedWalletTypes(res.data.supportedWalletTypes, res.data.cosmosPrefix);
|
|
603
|
+
return res;
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
setSupportedWalletTypes(supportedWalletTypes, cosmosPrefix) {
|
|
607
|
+
if (supportedWalletTypes && !__classPrivateFieldGet(this, _ParaCore_supportedWalletTypes, "f")) {
|
|
608
|
+
__classPrivateFieldSet(this, _ParaCore_supportedWalletTypes, supportedWalletTypes, "f");
|
|
609
|
+
Object.keys(this.currentWalletIds).forEach((type) => {
|
|
610
|
+
var _a;
|
|
611
|
+
if (!((_a = __classPrivateFieldGet(this, _ParaCore_supportedWalletTypes, "f")) === null || _a === void 0 ? void 0 : _a.some(({ type: supportedType }) => supportedType === type))) {
|
|
612
|
+
delete this.currentWalletIds[type];
|
|
613
|
+
}
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
if (cosmosPrefix && !this.cosmosPrefix) {
|
|
617
|
+
this.cosmosPrefix = cosmosPrefix;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
getVerificationEmailProps() {
|
|
621
|
+
return {
|
|
622
|
+
brandColor: this.emailPrimaryColor,
|
|
623
|
+
theme: this.emailTheme,
|
|
624
|
+
supportUrl: this.supportUrl,
|
|
625
|
+
homepageUrl: this.homepageUrl,
|
|
626
|
+
xUrl: this.xUrl,
|
|
627
|
+
githubUrl: this.githubUrl,
|
|
628
|
+
linkedinUrl: this.linkedinUrl,
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
getBackupKitEmailProps() {
|
|
632
|
+
return {
|
|
633
|
+
brandColor: this.emailPrimaryColor,
|
|
634
|
+
theme: this.emailTheme,
|
|
635
|
+
homepageUrl: this.homepageUrl,
|
|
636
|
+
xUrl: this.xUrl,
|
|
637
|
+
linkedinUrl: this.linkedinUrl,
|
|
638
|
+
githubUrl: this.githubUrl,
|
|
639
|
+
supportUrl: this.supportUrl,
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Initialize storage relating to a `ParaCore` instance.
|
|
644
|
+
*
|
|
645
|
+
* Init only needs to be called for storage that is async.
|
|
646
|
+
*/
|
|
647
|
+
init() {
|
|
648
|
+
var _a;
|
|
649
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
650
|
+
this.email = (yield this.localStorageGetItem(LOCAL_STORAGE_EMAIL)) || undefined;
|
|
651
|
+
this.countryCode = (yield this.localStorageGetItem(LOCAL_STORAGE_COUNTRY_CODE)) || undefined;
|
|
652
|
+
this.phone = (yield this.localStorageGetItem(LOCAL_STORAGE_PHONE)) || undefined;
|
|
653
|
+
this.userId = (yield this.localStorageGetItem(LOCAL_STORAGE_USER_ID)) || undefined;
|
|
654
|
+
this.telegramUserId = (yield this.localStorageGetItem(LOCAL_STORAGE_TELEGRAM_USER_ID)) || undefined;
|
|
655
|
+
const stringWallets = this.platformUtils.secureStorage
|
|
656
|
+
? yield this.platformUtils.secureStorage.get(LOCAL_STORAGE_WALLETS)
|
|
657
|
+
: yield this.localStorageGetItem(LOCAL_STORAGE_WALLETS);
|
|
658
|
+
const _wallets = JSON.parse(stringWallets || '{}');
|
|
659
|
+
const stringEd25519Wallets = this.platformUtils.secureStorage
|
|
660
|
+
? yield this.platformUtils.secureStorage.get(LOCAL_STORAGE_ED25519_WALLETS)
|
|
661
|
+
: yield this.localStorageGetItem(LOCAL_STORAGE_ED25519_WALLETS);
|
|
662
|
+
const _ed25519Wallets = JSON.parse(stringEd25519Wallets || '{}');
|
|
663
|
+
const wallets = Object.assign(Object.assign({}, Object.keys(_wallets).reduce((res, key) => {
|
|
664
|
+
return Object.assign(Object.assign({}, res), { [key]: migrateWallet(_wallets[key]) });
|
|
665
|
+
}, {})), Object.keys(_ed25519Wallets).reduce((res, key) => {
|
|
666
|
+
return Object.assign(Object.assign({}, res), (!res[key] ? { [key]: migrateWallet(_ed25519Wallets[key]) } : {}));
|
|
667
|
+
}, {}));
|
|
668
|
+
yield this.setWallets(wallets);
|
|
669
|
+
// TODO: Improve not great check
|
|
670
|
+
const _currentWalletIds = (_a = (yield this.localStorageGetItem(LOCAL_STORAGE_CURRENT_WALLET_IDS))) !== null && _a !== void 0 ? _a : undefined;
|
|
671
|
+
const currentWalletIds = [undefined, null, 'undefined', 'null'].includes(_currentWalletIds)
|
|
672
|
+
? {}
|
|
673
|
+
: (() => {
|
|
674
|
+
const fromJson = JSON.parse(_currentWalletIds);
|
|
675
|
+
return Array.isArray(fromJson)
|
|
676
|
+
? Object.keys(WalletType).reduce((acc, type) => {
|
|
677
|
+
const wallet = Object.values(this.wallets).find(w => fromJson.includes(w.id) && WalletSchemeTypeMap[w.scheme][type]);
|
|
678
|
+
return Object.assign(Object.assign({}, acc), (wallet && !acc[type] ? { [type]: [wallet.id] } : {}));
|
|
679
|
+
}, {})
|
|
680
|
+
: fromJson;
|
|
681
|
+
})();
|
|
682
|
+
yield this.setCurrentWalletIds(currentWalletIds);
|
|
683
|
+
// TODO: remove sessionStorageGetItem call once new version is being consumed
|
|
684
|
+
this.sessionCookie =
|
|
685
|
+
(yield this.localStorageGetItem(LOCAL_STORAGE_SESSION_COOKIE)) ||
|
|
686
|
+
(yield this.sessionStorageGetItem(LOCAL_STORAGE_SESSION_COOKIE)) ||
|
|
687
|
+
undefined;
|
|
688
|
+
// In case currentWalletIds was missing from storage
|
|
689
|
+
if (Object.values(this.wallets).filter(w => this.isWalletOwned(w)).length > 0 &&
|
|
690
|
+
this.currentWalletIdsArray.length === 0) {
|
|
691
|
+
this.findWalletId(undefined, { forbidPregen: true });
|
|
692
|
+
}
|
|
693
|
+
const loginEncryptionKey = (yield this.sessionStorageGetItem(SESSION_STORAGE_LOGIN_ENCRYPTION_KEY_PAIR));
|
|
694
|
+
if (loginEncryptionKey && loginEncryptionKey !== 'undefined') {
|
|
695
|
+
this.loginEncryptionKeyPair = this.convertEncryptionKeyPair(JSON.parse(loginEncryptionKey));
|
|
696
|
+
}
|
|
697
|
+
const stringExternalWallets = yield this.localStorageGetItem(LOCAL_STORAGE_EXTERNAL_WALLETS);
|
|
698
|
+
const _externalWallets = JSON.parse(stringExternalWallets || '{}');
|
|
699
|
+
yield this.setExternalWallets(_externalWallets);
|
|
700
|
+
const _currentExternalWalletAddresses = (yield this.localStorageGetItem(LOCAL_STORAGE_CURRENT_EXTERNAL_WALLET_ADDRESSES)) || undefined;
|
|
701
|
+
this.currentExternalWalletAddresses = _currentExternalWalletAddresses
|
|
702
|
+
? JSON.parse(_currentExternalWalletAddresses)
|
|
703
|
+
: undefined;
|
|
704
|
+
yield this.touchSession();
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* Sets the email associated with the `ParaCore` instance.
|
|
709
|
+
* @param email - Email to set.
|
|
710
|
+
*/
|
|
711
|
+
setEmail(email) {
|
|
712
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
713
|
+
this.email = email;
|
|
714
|
+
yield this.localStorageSetItem(LOCAL_STORAGE_EMAIL, email);
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Sets the Telegram user ID associated with the `ParaCore` instance.
|
|
719
|
+
* @param telegramUserId - Telegram user ID to set.
|
|
720
|
+
*/
|
|
721
|
+
setTelegramUserId(telegramUserId) {
|
|
722
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
723
|
+
this.telegramUserId = telegramUserId;
|
|
724
|
+
yield this.localStorageSetItem(LOCAL_STORAGE_TELEGRAM_USER_ID, telegramUserId);
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
728
|
+
* Sets the phone number associated with the `ParaCore` instance.
|
|
729
|
+
* @param phone - Phone number to set.
|
|
730
|
+
* @param countryCode - Country Code to set.
|
|
731
|
+
*/
|
|
732
|
+
setPhoneNumber(phone, countryCode) {
|
|
733
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
734
|
+
this.phone = phone;
|
|
735
|
+
this.countryCode = countryCode;
|
|
736
|
+
yield this.localStorageSetItem(LOCAL_STORAGE_PHONE, phone);
|
|
737
|
+
yield this.localStorageSetItem(LOCAL_STORAGE_COUNTRY_CODE, countryCode);
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Sets the farcaster username associated with the `ParaCore` instance.
|
|
742
|
+
* @param farcasterUsername - Farcaster Username to set.
|
|
743
|
+
*/
|
|
744
|
+
setFarcasterUsername(farcasterUsername) {
|
|
745
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
746
|
+
this.farcasterUsername = farcasterUsername;
|
|
747
|
+
yield this.localStorageSetItem(LOCAL_STORAGE_FARCASTER_USERNAME, farcasterUsername);
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Sets the external wallet address and type associated with the `ParaCore` instance.
|
|
752
|
+
* @param externalAddress - External wallet address to set.
|
|
753
|
+
* @param externalType - Type of external wallet to set.
|
|
754
|
+
*/
|
|
755
|
+
setExternalWallet({ address, type, provider, addressBech32 }) {
|
|
756
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
757
|
+
// Can change this to continue storing existing external wallets if/when we want to allow multiple connected external wallets
|
|
758
|
+
this.externalWallets = {
|
|
759
|
+
[address]: {
|
|
760
|
+
id: address,
|
|
761
|
+
address: addressBech32 !== null && addressBech32 !== void 0 ? addressBech32 : address,
|
|
762
|
+
type,
|
|
763
|
+
name: provider,
|
|
764
|
+
isExternal: true,
|
|
765
|
+
signer: '',
|
|
766
|
+
},
|
|
767
|
+
};
|
|
768
|
+
this.currentExternalWalletAddresses = [address];
|
|
769
|
+
this.setCurrentExternalWalletAddresses(this.currentExternalWalletAddresses);
|
|
770
|
+
this.setExternalWallets(this.externalWallets);
|
|
771
|
+
typeof window !== 'undefined' && !!window.dispatchEvent && window.dispatchEvent(new Event(EXTERNAL_WALLET_CHANGE_EVENT));
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* Sets the user id associated with the `ParaCore` instance.
|
|
776
|
+
* @param userId - User id to set.
|
|
777
|
+
*/
|
|
778
|
+
setUserId(userId) {
|
|
779
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
780
|
+
this.userId = userId;
|
|
781
|
+
yield this.localStorageSetItem(LOCAL_STORAGE_USER_ID, userId);
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Sets the wallets associated with the `ParaCore` instance.
|
|
786
|
+
* @param wallets - Wallets to set.
|
|
787
|
+
*/
|
|
788
|
+
setWallets(wallets) {
|
|
789
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
790
|
+
this.wallets = wallets;
|
|
791
|
+
if (this.platformUtils.secureStorage) {
|
|
792
|
+
yield this.platformUtils.secureStorage.set(LOCAL_STORAGE_WALLETS, JSON.stringify(wallets));
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
yield this.localStorageSetItem(LOCAL_STORAGE_WALLETS, JSON.stringify(wallets));
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
/**
|
|
799
|
+
* Sets the external wallets associated with the `ParaCore` instance.
|
|
800
|
+
* @param externalWallets - External wallets to set.
|
|
801
|
+
*/
|
|
802
|
+
setExternalWallets(externalWallets) {
|
|
803
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
804
|
+
this.externalWallets = externalWallets;
|
|
805
|
+
yield this.localStorageSetItem(LOCAL_STORAGE_EXTERNAL_WALLETS, JSON.stringify(externalWallets));
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
setCurrentExternalWalletAddresses(currentExternalWalletAddresses) {
|
|
809
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
810
|
+
this.currentExternalWalletAddresses = currentExternalWalletAddresses;
|
|
811
|
+
yield this.localStorageSetItem(LOCAL_STORAGE_CURRENT_EXTERNAL_WALLET_ADDRESSES, JSON.stringify(currentExternalWalletAddresses));
|
|
812
|
+
});
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* Sets the login encryption key pair associated with the `ParaCore` instance.
|
|
816
|
+
* @param keyPair - Encryption key pair generated from loginEncryptionKey.
|
|
817
|
+
*/
|
|
818
|
+
setLoginEncryptionKeyPair(keyPair) {
|
|
819
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
820
|
+
if (!keyPair) {
|
|
821
|
+
keyPair = yield getAsymmetricKeyPair(this.ctx);
|
|
822
|
+
}
|
|
823
|
+
this.loginEncryptionKeyPair = keyPair;
|
|
824
|
+
yield this.sessionStorageSetItem(SESSION_STORAGE_LOGIN_ENCRYPTION_KEY_PAIR, JSON.stringify(keyPair));
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
deleteLoginEncryptionKeyPair() {
|
|
828
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
829
|
+
this.loginEncryptionKeyPair = undefined;
|
|
830
|
+
yield this.sessionStorageRemoveItem(SESSION_STORAGE_LOGIN_ENCRYPTION_KEY_PAIR);
|
|
831
|
+
});
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* Gets the userId associated with the `ParaCore` instance.
|
|
835
|
+
* @returns - userId associated with the `ParaCore` instance.
|
|
836
|
+
*/
|
|
837
|
+
getUserId() {
|
|
838
|
+
return this.userId;
|
|
839
|
+
}
|
|
840
|
+
/**
|
|
841
|
+
* Gets the email associated with the `ParaCore` instance.
|
|
842
|
+
* @returns - email associated with the `ParaCore` instance.
|
|
843
|
+
*/
|
|
844
|
+
getEmail() {
|
|
845
|
+
return this.email;
|
|
846
|
+
}
|
|
847
|
+
/**
|
|
848
|
+
* Gets the phone object associated with the `ParaCore` instance.
|
|
849
|
+
* @returns - phone object with phone number and country code associated with the `ParaCore` instance.
|
|
850
|
+
*/
|
|
851
|
+
getPhone() {
|
|
852
|
+
return { phone: this.phone, countryCode: this.countryCode };
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Gets the formatted phone number associated with the `ParaCore` instance.
|
|
856
|
+
* @returns - formatted phone number associated with the `ParaCore` instance.
|
|
857
|
+
*/
|
|
858
|
+
getPhoneNumber() {
|
|
859
|
+
if (!this.phone || !this.countryCode) {
|
|
860
|
+
return undefined;
|
|
861
|
+
}
|
|
862
|
+
return normalizePhoneNumber(this.countryCode, this.phone);
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* Gets the farcaster username associated with the `ParaCore` instance.
|
|
866
|
+
* @returns - farcaster username associated with the `ParaCore` instance.
|
|
867
|
+
*/
|
|
868
|
+
getFarcasterUsername() {
|
|
869
|
+
return this.farcasterUsername;
|
|
870
|
+
}
|
|
871
|
+
setCurrentWalletIds(currentWalletIds, { needsWallet = false, sessionLookupId, newDeviceSessionLookupId, } = {}) {
|
|
872
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
873
|
+
this.currentWalletIds = currentWalletIds;
|
|
874
|
+
yield this.localStorageSetItem(LOCAL_STORAGE_CURRENT_WALLET_IDS, JSON.stringify(this.currentWalletIds));
|
|
875
|
+
if (sessionLookupId) {
|
|
876
|
+
yield this.ctx.client.setCurrentWalletIds(this.getUserId(), this.currentWalletIds, needsWallet, sessionLookupId, newDeviceSessionLookupId);
|
|
877
|
+
}
|
|
878
|
+
typeof window !== 'undefined' &&
|
|
879
|
+
!!window.dispatchEvent &&
|
|
880
|
+
window.dispatchEvent(new Event(CURRENT_WALLET_IDS_CHANGE_EVENT));
|
|
881
|
+
});
|
|
882
|
+
}
|
|
883
|
+
/**
|
|
884
|
+
* Validates that a wallet ID is present on the instance, usable, and matches the desired filters.
|
|
885
|
+
* If no ID is passed, this will instead return the first valid, usable wallet ID that matches the filters.
|
|
886
|
+
* @param {string} [walletId] the wallet ID to validate.
|
|
887
|
+
* @param {WalletFilters} [filter={}] a `WalletFilters` object specifying allowed types, schemes, and whether to forbid unclaimed pregen wallets.
|
|
888
|
+
* @returns {string} the wallet ID originally passed, or the one found.
|
|
889
|
+
*/
|
|
890
|
+
findWalletId(walletId, filter = {}) {
|
|
891
|
+
if (walletId) {
|
|
892
|
+
this.assertIsValidWalletId(walletId, filter);
|
|
893
|
+
}
|
|
894
|
+
else {
|
|
895
|
+
for (const id of [...this.currentWalletIdsUnique, ...Object.keys(this.wallets)]) {
|
|
896
|
+
if (this.isWalletUsable(id, filter)) {
|
|
897
|
+
walletId = id;
|
|
898
|
+
break;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
if (!walletId) {
|
|
902
|
+
throw new Error(`no valid wallet id found`);
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
return walletId;
|
|
906
|
+
}
|
|
907
|
+
/**
|
|
908
|
+
* Retrieves a wallet with the given address, if present.
|
|
909
|
+
* If no ID is passed, this will instead return the first valid, usable wallet ID that matches the filters.
|
|
910
|
+
* @param {string} [walletId] the wallet ID to validate.
|
|
911
|
+
* @param {WalletFilters} [filter={}] a `WalletFilters` object specifying allowed types, schemes, and whether to forbid unclaimed pregen wallets.
|
|
912
|
+
* @returns {string} the wallet ID originally passed, or the one found.
|
|
913
|
+
*/
|
|
914
|
+
findWalletByAddress(address, filter) {
|
|
915
|
+
if (this.externalWallets[address]) {
|
|
916
|
+
return this.externalWallets[address];
|
|
917
|
+
}
|
|
918
|
+
let wallet;
|
|
919
|
+
Object.entries(this.currentWalletIds).forEach(([type, walletIds]) => {
|
|
920
|
+
const pregenWalletIds = Object.keys(this.wallets).filter(id => this.wallets[id].type === type && this.isPregenWalletClaimable(this.wallets[id]));
|
|
921
|
+
[...walletIds, ...pregenWalletIds].forEach(id => {
|
|
922
|
+
if (address.toLowerCase() === this.getDisplayAddress(id, { addressType: type }).toLowerCase()) {
|
|
923
|
+
wallet = this.wallets[id];
|
|
924
|
+
}
|
|
925
|
+
});
|
|
926
|
+
});
|
|
927
|
+
if (!wallet) {
|
|
928
|
+
throw new Error(`wallet with address ${address} not found`);
|
|
929
|
+
}
|
|
930
|
+
this.assertIsValidWalletId(wallet.id, filter);
|
|
931
|
+
return wallet;
|
|
932
|
+
}
|
|
933
|
+
findWallet(idOrAddress, overrideType, filter = {}) {
|
|
934
|
+
var _a, _b;
|
|
935
|
+
if (!idOrAddress && Object.keys(this.externalWallets).length > 0) {
|
|
936
|
+
return Object.values(this.externalWallets)[0];
|
|
937
|
+
}
|
|
938
|
+
if (this.externalWallets[idOrAddress]) {
|
|
939
|
+
return this.externalWallets[idOrAddress];
|
|
940
|
+
}
|
|
941
|
+
try {
|
|
942
|
+
const walletId = this.findWalletId(idOrAddress, filter);
|
|
943
|
+
if (walletId && !!this.wallets[walletId]) {
|
|
944
|
+
const _c = this.wallets[walletId], { signer: _signer } = _c, wallet = __rest(_c, ["signer"]);
|
|
945
|
+
const type = (_b = overrideType !== null && overrideType !== void 0 ? overrideType : (_a = this.currentWalletIdsArray.find(([id]) => id === walletId)) === null || _a === void 0 ? void 0 : _a[1]) !== null && _b !== void 0 ? _b : wallet.type;
|
|
946
|
+
return Object.assign(Object.assign({}, wallet), { type: WalletType[type] });
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
catch (e) {
|
|
950
|
+
return undefined;
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
get availableWallets() {
|
|
954
|
+
var _a;
|
|
955
|
+
return [
|
|
956
|
+
...this.currentWalletIdsArray
|
|
957
|
+
.map(([address, type]) => [address, type, false])
|
|
958
|
+
.map(([id, type]) => {
|
|
959
|
+
const wallet = this.findWallet(id, type);
|
|
960
|
+
if (!wallet)
|
|
961
|
+
return null;
|
|
962
|
+
return {
|
|
963
|
+
id: wallet.id,
|
|
964
|
+
type,
|
|
965
|
+
address: this.getDisplayAddress(id, { addressType: type }),
|
|
966
|
+
name: wallet.name,
|
|
967
|
+
};
|
|
968
|
+
})
|
|
969
|
+
.filter(obj => obj !== null),
|
|
970
|
+
...Object.values((_a = this.externalWallets) !== null && _a !== void 0 ? _a : {}),
|
|
971
|
+
];
|
|
972
|
+
}
|
|
973
|
+
/**
|
|
974
|
+
* Retrieves all usable wallets with the provided type (`'EVM' | 'COSMOS' | 'SOLANA'`)
|
|
975
|
+
* @param {string} type the wallet type to filter by.
|
|
976
|
+
* @returns {Wallet[]} an array of matching wallets.
|
|
977
|
+
*/
|
|
978
|
+
getWalletsByType(type) {
|
|
979
|
+
return Object.values(this.wallets).filter(w => this.isWalletUsable(w.id, { type: [type] }));
|
|
980
|
+
}
|
|
981
|
+
assertIsValidWalletId(walletId, condition = {}) {
|
|
982
|
+
this.isWalletUsable(walletId, condition, true);
|
|
983
|
+
}
|
|
984
|
+
assertIsValidWalletType(type, walletTypes) {
|
|
985
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
986
|
+
if (!__classPrivateFieldGet(this, _ParaCore_supportedWalletTypes, "f")) {
|
|
987
|
+
yield this.touchSession();
|
|
988
|
+
}
|
|
989
|
+
if (!type ||
|
|
990
|
+
!Object.values(WalletType).includes(type) ||
|
|
991
|
+
!(walletTypes !== null && walletTypes !== void 0 ? walletTypes : this.supportedWalletTypes.map(({ type }) => type)).includes(type)) {
|
|
992
|
+
throw new Error(`wallet type ${type} is not supported`);
|
|
993
|
+
}
|
|
994
|
+
return type;
|
|
995
|
+
});
|
|
996
|
+
}
|
|
997
|
+
getMissingTypes() {
|
|
998
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
999
|
+
if (!__classPrivateFieldGet(this, _ParaCore_supportedWalletTypes, "f")) {
|
|
1000
|
+
yield this.touchSession();
|
|
1001
|
+
}
|
|
1002
|
+
return (this.supportedWalletTypes
|
|
1003
|
+
.filter(({ type: t, optional }) => !optional && Object.values(this.wallets).every(w => !this.isWalletOwned(w) || !WalletSchemeTypeMap[w.scheme][t]))
|
|
1004
|
+
.map(({ type }) => type));
|
|
1005
|
+
});
|
|
1006
|
+
}
|
|
1007
|
+
getTypesToCreate(types) {
|
|
1008
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1009
|
+
if (!__classPrivateFieldGet(this, _ParaCore_supportedWalletTypes, "f")) {
|
|
1010
|
+
yield this.touchSession();
|
|
1011
|
+
}
|
|
1012
|
+
return getSchemes(types !== null && types !== void 0 ? types : (yield this.getMissingTypes())).map(scheme => {
|
|
1013
|
+
switch (scheme) {
|
|
1014
|
+
case WalletScheme.ED25519:
|
|
1015
|
+
return WalletType.SOLANA;
|
|
1016
|
+
default:
|
|
1017
|
+
return this.supportedWalletTypes.some(({ type, optional }) => type === WalletType.COSMOS && !optional)
|
|
1018
|
+
? WalletType.COSMOS
|
|
1019
|
+
: WalletType.EVM;
|
|
1020
|
+
}
|
|
1021
|
+
});
|
|
1022
|
+
});
|
|
1023
|
+
}
|
|
1024
|
+
getPartnerURL(partnerId) {
|
|
1025
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1026
|
+
const res = yield this.ctx.client.getPartner(partnerId);
|
|
1027
|
+
return res.data.partner.portalUrl;
|
|
1028
|
+
});
|
|
1029
|
+
}
|
|
1030
|
+
/**
|
|
1031
|
+
* URL of the portal, which can be associated with a partner id
|
|
1032
|
+
* @param partnerId: string - id of the partner to get the portal URL for
|
|
1033
|
+
* @returns - portal URL
|
|
1034
|
+
*/
|
|
1035
|
+
getPortalURL(partnerId) {
|
|
1036
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1037
|
+
return (partnerId && (yield this.getPartnerURL(partnerId))) || getPortalBaseURL(this.ctx);
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
getWebAuthURLForCreate(_a) {
|
|
1041
|
+
var { webAuthId } = _a, options = __rest(_a, ["webAuthId"]);
|
|
1042
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1043
|
+
return this.constructPortalUrl('createAuth', Object.assign(Object.assign({}, options), { pathId: webAuthId }));
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
getPasswordURLForCreate(_a) {
|
|
1047
|
+
var { passwordId } = _a, options = __rest(_a, ["passwordId"]);
|
|
1048
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1049
|
+
return this.constructPortalUrl('createPassword', Object.assign(Object.assign({}, options), { pathId: passwordId }));
|
|
1050
|
+
});
|
|
1051
|
+
}
|
|
1052
|
+
getShortUrl(compressedUrl) {
|
|
1053
|
+
return constructUrl({
|
|
1054
|
+
base: getPortalBaseURL(this.ctx),
|
|
1055
|
+
path: `/short/${compressedUrl}`,
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
shortenLoginLink(link) {
|
|
1059
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1060
|
+
const url = yield transmissionUtils.upload(link, this.ctx.client);
|
|
1061
|
+
return this.getShortUrl(url);
|
|
1062
|
+
});
|
|
1063
|
+
}
|
|
1064
|
+
/**
|
|
1065
|
+
* Generates a URL that can be used to perform web auth
|
|
1066
|
+
* for creating a new credential.
|
|
1067
|
+
* @param sessionId - id of the session to use for web auth
|
|
1068
|
+
* @param loginEncryptionPublicKey - public key to use for encrypting the login encryption key
|
|
1069
|
+
* @param partnerId - id of the partner to get the portal URL for
|
|
1070
|
+
* @param newDeviceSessionId - id of the session to use for web auth for a new device
|
|
1071
|
+
* @param newDeviceEncryptionKey - public key to use for encrypting the login encryption key for a new device
|
|
1072
|
+
* @returns - web auth url
|
|
1073
|
+
*/
|
|
1074
|
+
getWebAuthURLForLogin(options) {
|
|
1075
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1076
|
+
return this.constructPortalUrl('loginAuth', options);
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1079
|
+
getPasswordURLForLogin(options) {
|
|
1080
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1081
|
+
return this.constructPortalUrl('loginPassword', options);
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
/**
|
|
1085
|
+
* Generates a URL that can be used to perform web auth for phone number
|
|
1086
|
+
* for creating a new credential.
|
|
1087
|
+
* @param sessionId - id of the session to use for web auth
|
|
1088
|
+
* @param loginEncryptionPublicKey - public key to use for encrypting the login encryption key
|
|
1089
|
+
* @param partnerId - id of the partner to get the portal URL for
|
|
1090
|
+
* @param newDeviceSessionId - id of the session to use for web auth for a new device
|
|
1091
|
+
* @param newDeviceEncryptionKey - public key to use for encrypting the login encryption key for a new device
|
|
1092
|
+
* @returns - web auth url
|
|
1093
|
+
*/
|
|
1094
|
+
getWebAuthURLForLoginForPhone(options) {
|
|
1095
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1096
|
+
return this.constructPortalUrl('loginAuth', Object.assign({ authType: 'phone' }, options));
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
1099
|
+
/**
|
|
1100
|
+
* Gets the private key for the given wallet.
|
|
1101
|
+
* @param walletId - (optional) id of the wallet to get the private key for. Will default to the first wallet if not provided.
|
|
1102
|
+
* @returns - private key string.
|
|
1103
|
+
*/
|
|
1104
|
+
getPrivateKey(walletId) {
|
|
1105
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1106
|
+
const wallets = Object.values(this.wallets);
|
|
1107
|
+
const wallet = walletId ? this.wallets[walletId] : wallets === null || wallets === void 0 ? void 0 : wallets[0];
|
|
1108
|
+
if (!wallet) {
|
|
1109
|
+
throw new Error('wallet not found');
|
|
1110
|
+
}
|
|
1111
|
+
// We can only build the private key for DKLS wallets
|
|
1112
|
+
if (wallet.scheme !== WalletScheme.DKLS) {
|
|
1113
|
+
throw new Error('invalid wallet scheme');
|
|
1114
|
+
}
|
|
1115
|
+
return yield this.platformUtils.getPrivateKey(this.ctx, this.userId, wallet.id, wallet.signer, this.retrieveSessionCookie());
|
|
1116
|
+
});
|
|
1117
|
+
}
|
|
1118
|
+
/**
|
|
1119
|
+
* Fetches the wallets associated with the user.
|
|
1120
|
+
* @returns - wallets that were fetched.
|
|
1121
|
+
*/
|
|
1122
|
+
fetchWallets() {
|
|
1123
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1124
|
+
const res = yield (this.isPortal() || this.isParaConnect()
|
|
1125
|
+
? this.ctx.client.getAllWallets(this.userId)
|
|
1126
|
+
: this.ctx.client.getWallets(this.userId, true));
|
|
1127
|
+
return res.data.wallets.filter(wallet => !!wallet.address &&
|
|
1128
|
+
(this.isParaConnect() || (!this.isParaConnect() && this.isWalletSupported(entityToWallet(wallet)))));
|
|
1129
|
+
});
|
|
1130
|
+
}
|
|
1131
|
+
populateWalletAddresses() {
|
|
1132
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1133
|
+
const res = yield this.ctx.client.getWallets(this.userId, true);
|
|
1134
|
+
const wallets = res.data.wallets;
|
|
1135
|
+
wallets.forEach(entity => {
|
|
1136
|
+
if (this.wallets[entity.id]) {
|
|
1137
|
+
this.wallets[entity.id] = Object.assign(Object.assign({}, entityToWallet(entity)), this.wallets[entity.id]);
|
|
1138
|
+
}
|
|
1139
|
+
});
|
|
1140
|
+
yield this.setWallets(this.wallets);
|
|
1141
|
+
});
|
|
1142
|
+
}
|
|
1143
|
+
populatePregenWalletAddresses() {
|
|
1144
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1145
|
+
const res = yield this.getPregenWallets();
|
|
1146
|
+
res.forEach(entity => {
|
|
1147
|
+
if (this.wallets[entity.id]) {
|
|
1148
|
+
this.wallets[entity.id] = Object.assign(Object.assign({}, entityToWallet(entity)), this.wallets[entity.id]);
|
|
1149
|
+
}
|
|
1150
|
+
});
|
|
1151
|
+
yield this.setWallets(this.wallets);
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1154
|
+
/**
|
|
1155
|
+
* Checks if a user exists.
|
|
1156
|
+
* @returns - true if user exists, false otherwise.
|
|
1157
|
+
*/
|
|
1158
|
+
checkIfUserExists(email) {
|
|
1159
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1160
|
+
const res = yield this.ctx.client.checkUserExists({ email });
|
|
1161
|
+
return res.data.exists;
|
|
1162
|
+
});
|
|
1163
|
+
}
|
|
1164
|
+
/**
|
|
1165
|
+
* Checks if a user exists by their phone number.
|
|
1166
|
+
* @returns - true if user exists, false otherwise.
|
|
1167
|
+
*/
|
|
1168
|
+
checkIfUserExistsByPhone(phone, countryCode) {
|
|
1169
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1170
|
+
const res = yield this.ctx.client.checkUserExists({ phone, countryCode });
|
|
1171
|
+
return res.data.exists;
|
|
1172
|
+
});
|
|
1173
|
+
}
|
|
1174
|
+
/*
|
|
1175
|
+
* Creates a new user.
|
|
1176
|
+
* @param email - email to use for creating the user.
|
|
1177
|
+
*/
|
|
1178
|
+
createUser({ email }) {
|
|
1179
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1180
|
+
this.requireApiKey();
|
|
1181
|
+
yield this.setEmail(email);
|
|
1182
|
+
const { userId } = yield this.ctx.client.createUser(Object.assign({ email: this.email }, this.getVerificationEmailProps()));
|
|
1183
|
+
yield this.setUserId(userId);
|
|
1184
|
+
});
|
|
1185
|
+
}
|
|
1186
|
+
/**
|
|
1187
|
+
* Creates a new user with a phone number.
|
|
1188
|
+
* @param phone - phone number to use for creating the user.
|
|
1189
|
+
* @param countryCode - country code to use for creating the user.
|
|
1190
|
+
*/
|
|
1191
|
+
createUserByPhone({ phone, countryCode }) {
|
|
1192
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1193
|
+
this.requireApiKey();
|
|
1194
|
+
yield this.setPhoneNumber(phone, countryCode);
|
|
1195
|
+
const { userId } = yield this.ctx.client.createUser({
|
|
1196
|
+
phone: this.phone,
|
|
1197
|
+
countryCode: this.countryCode,
|
|
1198
|
+
});
|
|
1199
|
+
yield this.setUserId(userId);
|
|
1200
|
+
});
|
|
1201
|
+
}
|
|
1202
|
+
/**
|
|
1203
|
+
* Logs in or creates a new user using an external wallet address.
|
|
1204
|
+
* @param externalAddress - external wallet address to use for identification.
|
|
1205
|
+
* @param type - type of external wallet to use for identification.
|
|
1206
|
+
* @param externalWalletProvider - name of provider for the external wallet.
|
|
1207
|
+
*/
|
|
1208
|
+
externalWalletLogin(wallet) {
|
|
1209
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1210
|
+
this.requireApiKey();
|
|
1211
|
+
const { userId } = yield this.ctx.client.externalWalletLogin({
|
|
1212
|
+
externalAddress: wallet.address,
|
|
1213
|
+
type: wallet.type,
|
|
1214
|
+
externalWalletProvider: wallet.provider,
|
|
1215
|
+
});
|
|
1216
|
+
yield this.setExternalWallet(wallet);
|
|
1217
|
+
yield this.setUserId(userId);
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1220
|
+
/**
|
|
1221
|
+
* Returns whether or not the user is connected with an external wallet.
|
|
1222
|
+
*/
|
|
1223
|
+
isUsingExternalWallet() {
|
|
1224
|
+
return !!Object.keys(this.externalWallets).length;
|
|
1225
|
+
}
|
|
1226
|
+
/**
|
|
1227
|
+
* Passes the email code obtained from the user for verification.
|
|
1228
|
+
* @param verificationCode
|
|
1229
|
+
* @returns - web auth url for creating a new credential
|
|
1230
|
+
*/
|
|
1231
|
+
verifyEmail(verificationCode) {
|
|
1232
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1233
|
+
yield this.ctx.client.verifyEmail(this.userId, { verificationCode });
|
|
1234
|
+
return this.getSetUpBiometricsURL();
|
|
1235
|
+
});
|
|
1236
|
+
}
|
|
1237
|
+
/**
|
|
1238
|
+
* Passes the phone code obtained from the user for verification.
|
|
1239
|
+
* @param verificationCode
|
|
1240
|
+
* @returns - web auth url for creating a new credential
|
|
1241
|
+
*/
|
|
1242
|
+
verifyPhone(verificationCode) {
|
|
1243
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1244
|
+
yield this.ctx.client.verifyPhone(this.userId, { verificationCode });
|
|
1245
|
+
return this.getSetUpBiometricsURLForPhone();
|
|
1246
|
+
});
|
|
1247
|
+
}
|
|
1248
|
+
/**
|
|
1249
|
+
* Validates the response received from an attempted Telegram login for authenticity, then
|
|
1250
|
+
* creates or retrieves the corresponding Para user and prepares the Para instance to sign in with that user.
|
|
1251
|
+
* @param authResponse - the response JSON object received from the Telegram widget.
|
|
1252
|
+
* @returns `{ isValid: boolean; telegramUserId?: string; userId?: string; isNewUser?: boolean; supportedAuthMethods?: AuthMethod[]; biometricHints?: BiometricLocationHint[] }`
|
|
1253
|
+
*/
|
|
1254
|
+
verifyTelegram(authObject) {
|
|
1255
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1256
|
+
const res = yield this.ctx.client.verifyTelegram(authObject);
|
|
1257
|
+
if (res.isValid) {
|
|
1258
|
+
yield this.setUserId(res.userId);
|
|
1259
|
+
yield this.setTelegramUserId(res.telegramUserId);
|
|
1260
|
+
yield this.touchSession(true);
|
|
1261
|
+
if (!this.loginEncryptionKeyPair) {
|
|
1262
|
+
yield this.setLoginEncryptionKeyPair();
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
return res;
|
|
1266
|
+
});
|
|
1267
|
+
}
|
|
1268
|
+
/**
|
|
1269
|
+
* Performs 2FA verification.
|
|
1270
|
+
* @param email - email to use for performing a 2FA verification.
|
|
1271
|
+
* @param verificationCode - verification code to received via 2FA.
|
|
1272
|
+
* @returns { address, initiatedAt, status, userId, walletId }
|
|
1273
|
+
*/
|
|
1274
|
+
verify2FA(email, verificationCode) {
|
|
1275
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1276
|
+
const res = yield this.ctx.client.verify2FA(email, verificationCode);
|
|
1277
|
+
return {
|
|
1278
|
+
initiatedAt: res.data.initiatedAt,
|
|
1279
|
+
status: res.data.status,
|
|
1280
|
+
userId: res.data.userId,
|
|
1281
|
+
wallets: res.data.wallets,
|
|
1282
|
+
};
|
|
1283
|
+
});
|
|
1284
|
+
}
|
|
1285
|
+
/**
|
|
1286
|
+
* Performs 2FA verification.
|
|
1287
|
+
* @param phone - phone to use for performing a 2FA verification.
|
|
1288
|
+
* @param verificationCode - verification code to received via 2FA.
|
|
1289
|
+
* @returns { address, initiatedAt, status, userId, walletId }
|
|
1290
|
+
*/
|
|
1291
|
+
verify2FAForPhone(phone, countryCode, verificationCode) {
|
|
1292
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1293
|
+
const res = yield this.ctx.client.verify2FAForPhone(phone, countryCode, verificationCode);
|
|
1294
|
+
return {
|
|
1295
|
+
initiatedAt: res.data.initiatedAt,
|
|
1296
|
+
status: res.data.status,
|
|
1297
|
+
userId: res.data.userId,
|
|
1298
|
+
wallets: res.data.wallets,
|
|
1299
|
+
};
|
|
1300
|
+
});
|
|
1301
|
+
}
|
|
1302
|
+
/**
|
|
1303
|
+
* Sets up 2FA.
|
|
1304
|
+
* @returns uri - uri to use for setting up 2FA
|
|
1305
|
+
* */
|
|
1306
|
+
setup2FA() {
|
|
1307
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1308
|
+
const res = yield this.ctx.client.setup2FA(this.userId);
|
|
1309
|
+
return {
|
|
1310
|
+
uri: res.data.uri,
|
|
1311
|
+
};
|
|
1312
|
+
});
|
|
1313
|
+
}
|
|
1314
|
+
/**
|
|
1315
|
+
* Enables 2FA.
|
|
1316
|
+
* @param verificationCode - verification code received via 2FA.
|
|
1317
|
+
*/
|
|
1318
|
+
enable2FA(verificationCode) {
|
|
1319
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1320
|
+
yield this.ctx.client.enable2FA(this.userId, verificationCode);
|
|
1321
|
+
});
|
|
1322
|
+
}
|
|
1323
|
+
/**
|
|
1324
|
+
* Determines if 2FA has been set up.
|
|
1325
|
+
* @returns { isSetup } - true if 2FA is setup, false otherwise
|
|
1326
|
+
*/
|
|
1327
|
+
check2FAStatus() {
|
|
1328
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1329
|
+
if (!this.userId) {
|
|
1330
|
+
return { isSetup: false };
|
|
1331
|
+
}
|
|
1332
|
+
const res = yield this.ctx.client.check2FAStatus(this.userId);
|
|
1333
|
+
return {
|
|
1334
|
+
isSetup: res.data.isSetup,
|
|
1335
|
+
};
|
|
1336
|
+
});
|
|
1337
|
+
}
|
|
1338
|
+
resendVerificationCode() {
|
|
1339
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1340
|
+
yield this.ctx.client.resendVerificationCode(Object.assign({ userId: this.userId }, this.getVerificationEmailProps()));
|
|
1341
|
+
});
|
|
1342
|
+
}
|
|
1343
|
+
resendVerificationCodeByPhone() {
|
|
1344
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1345
|
+
yield this.ctx.client.resendVerificationCodeByPhone({
|
|
1346
|
+
userId: this.userId,
|
|
1347
|
+
});
|
|
1348
|
+
});
|
|
1349
|
+
}
|
|
1350
|
+
// returns web auth url for creating a new credential
|
|
1351
|
+
getSetUpBiometricsURL({ authType = 'email', isForNewDevice = false, } = {}) {
|
|
1352
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1353
|
+
const res = yield this.ctx.client.addSessionPublicKey(this.userId, {
|
|
1354
|
+
status: PublicKeyStatus.PENDING,
|
|
1355
|
+
type: PublicKeyType.WEB,
|
|
1356
|
+
});
|
|
1357
|
+
return this.getWebAuthURLForCreate({
|
|
1358
|
+
authType,
|
|
1359
|
+
isForNewDevice,
|
|
1360
|
+
webAuthId: res.data.id,
|
|
1361
|
+
partnerId: res.data.partnerId,
|
|
1362
|
+
});
|
|
1363
|
+
});
|
|
1364
|
+
}
|
|
1365
|
+
// returns web auth url for creating a new credential
|
|
1366
|
+
getSetUpBiometricsURLForPhone({ isForNewDevice = false, } = {}) {
|
|
1367
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1368
|
+
const res = yield this.ctx.client.addSessionPublicKey(this.userId, {
|
|
1369
|
+
status: PublicKeyStatus.PENDING,
|
|
1370
|
+
type: PublicKeyType.WEB,
|
|
1371
|
+
});
|
|
1372
|
+
return this.getWebAuthURLForCreate({
|
|
1373
|
+
authType: 'phone',
|
|
1374
|
+
isForNewDevice,
|
|
1375
|
+
webAuthId: res.data.id,
|
|
1376
|
+
partnerId: res.data.partnerId,
|
|
1377
|
+
});
|
|
1378
|
+
});
|
|
1379
|
+
}
|
|
1380
|
+
getSetupPasswordURL({ authType = 'email', isForNewDevice = false, theme, } = {}) {
|
|
1381
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1382
|
+
const res = yield this.ctx.client.addSessionPasswordPublicKey(this.userId, {
|
|
1383
|
+
status: PasswordStatus.PENDING,
|
|
1384
|
+
});
|
|
1385
|
+
return this.getPasswordURLForCreate({
|
|
1386
|
+
authType,
|
|
1387
|
+
isForNewDevice,
|
|
1388
|
+
passwordId: res.data.id,
|
|
1389
|
+
partnerId: res.data.partnerId,
|
|
1390
|
+
theme,
|
|
1391
|
+
});
|
|
1392
|
+
});
|
|
1393
|
+
}
|
|
1394
|
+
isSessionActive() {
|
|
1395
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1396
|
+
if (this.isUsingExternalWallet()) {
|
|
1397
|
+
return true;
|
|
1398
|
+
}
|
|
1399
|
+
const res = yield this.touchSession();
|
|
1400
|
+
return !!res.data.isAuthenticated;
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
/**
|
|
1404
|
+
* Checks if a session is active and a wallet exists.
|
|
1405
|
+
*
|
|
1406
|
+
* @returns true if session is active and a wallet exists.
|
|
1407
|
+
**/
|
|
1408
|
+
isFullyLoggedIn() {
|
|
1409
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1410
|
+
if (this.isUsingExternalWallet()) {
|
|
1411
|
+
return true;
|
|
1412
|
+
}
|
|
1413
|
+
const isSessionActive = yield this.isSessionActive();
|
|
1414
|
+
return (isSessionActive &&
|
|
1415
|
+
this.currentWalletIdsArray.length > 0 &&
|
|
1416
|
+
this.currentWalletIdsArray.reduce((acc, [id]) => acc && !!this.wallets[id], true));
|
|
1417
|
+
});
|
|
1418
|
+
}
|
|
1419
|
+
supportedAuthMethods(auth) {
|
|
1420
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1421
|
+
const { supportedAuthMethods } = yield this.ctx.client.getSupportedAuthMethods(auth);
|
|
1422
|
+
const authMethods = new Set();
|
|
1423
|
+
for (const type of supportedAuthMethods) {
|
|
1424
|
+
switch (type) {
|
|
1425
|
+
case 'PASSWORD':
|
|
1426
|
+
authMethods.add(AuthMethod.PASSWORD);
|
|
1427
|
+
break;
|
|
1428
|
+
case 'BIOMETRIC':
|
|
1429
|
+
authMethods.add(AuthMethod.PASSKEY);
|
|
1430
|
+
break;
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
return authMethods;
|
|
1434
|
+
});
|
|
1435
|
+
}
|
|
1436
|
+
/**
|
|
1437
|
+
* Get hints associated with the users stored biometrics.
|
|
1438
|
+
* @returns Array containing useragents and AAGuids for stored biometrics
|
|
1439
|
+
*/
|
|
1440
|
+
getUserBiometricLocationHints() {
|
|
1441
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1442
|
+
if (!this.email && !this.phone && !this.farcasterUsername && !this.telegramUserId) {
|
|
1443
|
+
throw new Error('one of email, phone or farcaster username are required to get biometric location hints');
|
|
1444
|
+
}
|
|
1445
|
+
return yield this.ctx.client.getBiometricLocationHints({
|
|
1446
|
+
email: this.email,
|
|
1447
|
+
phone: this.phone,
|
|
1448
|
+
countryCode: this.countryCode,
|
|
1449
|
+
farcasterUsername: this.farcasterUsername,
|
|
1450
|
+
telegramUserId: this.telegramUserId,
|
|
1451
|
+
});
|
|
1452
|
+
});
|
|
1453
|
+
}
|
|
1454
|
+
setAuth(auth) {
|
|
1455
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1456
|
+
const authInfo = extractAuthInfo(auth);
|
|
1457
|
+
switch (authInfo.authType) {
|
|
1458
|
+
case 'email':
|
|
1459
|
+
yield this.setEmail(authInfo.identifier);
|
|
1460
|
+
break;
|
|
1461
|
+
case 'phone':
|
|
1462
|
+
yield this.setPhoneNumber(authInfo.auth.phone, authInfo.auth.countryCode);
|
|
1463
|
+
break;
|
|
1464
|
+
case 'farcaster':
|
|
1465
|
+
yield this.setFarcasterUsername(authInfo.identifier);
|
|
1466
|
+
break;
|
|
1467
|
+
case 'telegram':
|
|
1468
|
+
yield this.setTelegramUserId(authInfo.identifier);
|
|
1469
|
+
break;
|
|
1470
|
+
}
|
|
1471
|
+
return authInfo;
|
|
1472
|
+
});
|
|
1473
|
+
}
|
|
1474
|
+
/**
|
|
1475
|
+
* Initiates a login.
|
|
1476
|
+
* @param email - the email to login with
|
|
1477
|
+
* @param useShortURL - whether to shorten the link
|
|
1478
|
+
* @returns - web auth url for logging in
|
|
1479
|
+
**/
|
|
1480
|
+
initiateUserLogin(_a) {
|
|
1481
|
+
var { useShortUrl = false } = _a, auth = __rest(_a, ["useShortUrl"]);
|
|
1482
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1483
|
+
const { authType } = yield this.setAuth(auth);
|
|
1484
|
+
const res = yield this.touchSession(true);
|
|
1485
|
+
if (!this.loginEncryptionKeyPair) {
|
|
1486
|
+
yield this.setLoginEncryptionKeyPair();
|
|
1487
|
+
}
|
|
1488
|
+
const webAuthLoginURL = yield this.getWebAuthURLForLogin({
|
|
1489
|
+
authType,
|
|
1490
|
+
sessionId: res.data.sessionId,
|
|
1491
|
+
partnerId: res.data.partnerId,
|
|
1492
|
+
loginEncryptionPublicKey: getPublicKeyHex(this.loginEncryptionKeyPair),
|
|
1493
|
+
});
|
|
1494
|
+
if (!useShortUrl) {
|
|
1495
|
+
return webAuthLoginURL;
|
|
1496
|
+
}
|
|
1497
|
+
return this.shortenLoginLink(webAuthLoginURL);
|
|
1498
|
+
});
|
|
1499
|
+
}
|
|
1500
|
+
/**
|
|
1501
|
+
* Initiates a login.
|
|
1502
|
+
* @param email - the email to login with
|
|
1503
|
+
* @returns - a set of supported auth methods for the user
|
|
1504
|
+
**/
|
|
1505
|
+
initiateUserLoginV2(auth) {
|
|
1506
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1507
|
+
const authInfo = yield this.setAuth(auth);
|
|
1508
|
+
yield this.touchSession(true);
|
|
1509
|
+
if (!this.loginEncryptionKeyPair) {
|
|
1510
|
+
yield this.setLoginEncryptionKeyPair();
|
|
1511
|
+
}
|
|
1512
|
+
return yield this.supportedAuthMethods(authInfo.auth);
|
|
1513
|
+
});
|
|
1514
|
+
}
|
|
1515
|
+
/**
|
|
1516
|
+
* Initiates a login.
|
|
1517
|
+
* @param phone - the phone number to login with
|
|
1518
|
+
* @param countryCode
|
|
1519
|
+
* @param useShortURL - whether to shorten the link
|
|
1520
|
+
* @returns - web auth url for logging in
|
|
1521
|
+
**/
|
|
1522
|
+
initiateUserLoginForPhone(_a) {
|
|
1523
|
+
var { useShortUrl = false } = _a, auth = __rest(_a, ["useShortUrl"]);
|
|
1524
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1525
|
+
yield this.setAuth(auth);
|
|
1526
|
+
const res = yield this.touchSession(true);
|
|
1527
|
+
if (!this.loginEncryptionKeyPair) {
|
|
1528
|
+
yield this.setLoginEncryptionKeyPair();
|
|
1529
|
+
}
|
|
1530
|
+
const webAuthLoginURL = yield this.getWebAuthURLForLoginForPhone({
|
|
1531
|
+
sessionId: res.data.sessionId,
|
|
1532
|
+
loginEncryptionPublicKey: getPublicKeyHex(this.loginEncryptionKeyPair),
|
|
1533
|
+
partnerId: res.data.partnerId,
|
|
1534
|
+
});
|
|
1535
|
+
if (!useShortUrl) {
|
|
1536
|
+
return webAuthLoginURL;
|
|
1537
|
+
}
|
|
1538
|
+
return this.shortenLoginLink(webAuthLoginURL);
|
|
1539
|
+
});
|
|
1540
|
+
}
|
|
1541
|
+
/**
|
|
1542
|
+
* Waits for the session to be active.
|
|
1543
|
+
**/
|
|
1544
|
+
waitForAccountCreation() {
|
|
1545
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1546
|
+
yield this.touchSession();
|
|
1547
|
+
// Remove external wallets if creating an account with Para
|
|
1548
|
+
this.currentExternalWalletAddresses = undefined;
|
|
1549
|
+
this.externalWallets = {};
|
|
1550
|
+
this.isAwaitingAccountCreation = true;
|
|
1551
|
+
while (this.isAwaitingAccountCreation) {
|
|
1552
|
+
try {
|
|
1553
|
+
yield new Promise(resolve => setTimeout(resolve, POLLING_INTERVAL_MS));
|
|
1554
|
+
if (yield this.isSessionActive()) {
|
|
1555
|
+
this.isAwaitingAccountCreation = false;
|
|
1556
|
+
return true;
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
catch (err) {
|
|
1560
|
+
// want to continue polling on error
|
|
1561
|
+
console.error(err);
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
return false;
|
|
1565
|
+
});
|
|
1566
|
+
}
|
|
1567
|
+
waitForPasskeyAndCreateWallet() {
|
|
1568
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1569
|
+
yield this.waitForAccountCreation();
|
|
1570
|
+
const pregenWallets = yield this.getPregenWallets();
|
|
1571
|
+
let recoverySecret, walletIds = {};
|
|
1572
|
+
if (pregenWallets.length > 0) {
|
|
1573
|
+
recoverySecret = yield this.claimPregenWallets();
|
|
1574
|
+
walletIds = this.supportedWalletTypes.reduce((acc, { type }) => {
|
|
1575
|
+
var _a;
|
|
1576
|
+
return Object.assign(Object.assign({}, acc), { [type]: [(_a = pregenWallets.find(w => !!WalletSchemeTypeMap[w.scheme][type])) === null || _a === void 0 ? void 0 : _a.id] });
|
|
1577
|
+
}, {});
|
|
1578
|
+
}
|
|
1579
|
+
// After claiming any pregen wallets, create wallets for the remaining missing types
|
|
1580
|
+
const created = yield this.createWalletPerType();
|
|
1581
|
+
recoverySecret = recoverySecret !== null && recoverySecret !== void 0 ? recoverySecret : created.recoverySecret;
|
|
1582
|
+
walletIds = Object.assign(Object.assign({}, walletIds), created.walletIds);
|
|
1583
|
+
return { walletIds, recoverySecret };
|
|
1584
|
+
});
|
|
1585
|
+
}
|
|
1586
|
+
/**
|
|
1587
|
+
* Initiates a Farcaster login attempt and return the URI for the user to connect.
|
|
1588
|
+
* You can create a QR code with this URI that works with Farcaster's mobile app.
|
|
1589
|
+
*
|
|
1590
|
+
* @return {string}
|
|
1591
|
+
*/
|
|
1592
|
+
getFarcasterConnectURL() {
|
|
1593
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1594
|
+
yield this.logout();
|
|
1595
|
+
yield this.touchSession(true);
|
|
1596
|
+
const { data: { connect_uri }, } = yield this.ctx.client.initializeFarcasterLogin();
|
|
1597
|
+
return connect_uri;
|
|
1598
|
+
});
|
|
1599
|
+
}
|
|
1600
|
+
/**
|
|
1601
|
+
* Awaits the response from a user's attempt to log in with Farcaster.
|
|
1602
|
+
* If successful, this returns the user's Farcaster username and profile picture and indicates whether the user already exists.
|
|
1603
|
+
*
|
|
1604
|
+
* @param {Object} opts the options object.
|
|
1605
|
+
* @return {Object} the user's information and whether the user already exists.
|
|
1606
|
+
*/
|
|
1607
|
+
waitForFarcasterStatus() {
|
|
1608
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1609
|
+
this.isAwaitingFarcaster = true;
|
|
1610
|
+
while (this.isAwaitingFarcaster) {
|
|
1611
|
+
try {
|
|
1612
|
+
yield new Promise(resolve => setTimeout(resolve, POLLING_INTERVAL_MS));
|
|
1613
|
+
const res = yield this.ctx.client.getFarcasterAuthStatus();
|
|
1614
|
+
if (res.data.state === 'completed') {
|
|
1615
|
+
const { userId, userExists, username, pfpUrl } = res.data;
|
|
1616
|
+
yield this.setUserId(userId);
|
|
1617
|
+
yield this.setFarcasterUsername(username);
|
|
1618
|
+
return {
|
|
1619
|
+
userExists,
|
|
1620
|
+
username,
|
|
1621
|
+
pfpUrl,
|
|
1622
|
+
};
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
catch (err) {
|
|
1626
|
+
console.error(err);
|
|
1627
|
+
this.isAwaitingFarcaster = false;
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
});
|
|
1631
|
+
}
|
|
1632
|
+
/**
|
|
1633
|
+
* Generates a URL for the user to log in with OAuth using a desire method.
|
|
1634
|
+
*
|
|
1635
|
+
* @param {OAuthMethod} oAuthMethod the third-party service to use for OAuth.
|
|
1636
|
+
* @returns {string} the URL for the user to log in with OAuth.
|
|
1637
|
+
*/
|
|
1638
|
+
getOAuthURL(oAuthMethod) {
|
|
1639
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1640
|
+
yield this.logout();
|
|
1641
|
+
const res = yield this.touchSession(true);
|
|
1642
|
+
return constructUrl({
|
|
1643
|
+
base: oAuthMethod === OAuthMethod.TELEGRAM ? getPortalBaseURL(this.ctx, true) : getBaseUrl(this.ctx.env),
|
|
1644
|
+
path: `/auth/${oAuthMethod.toLowerCase()}`,
|
|
1645
|
+
params: {
|
|
1646
|
+
apiKey: this.ctx.apiKey,
|
|
1647
|
+
sessionLookupId: res.data.sessionLookupId,
|
|
1648
|
+
},
|
|
1649
|
+
});
|
|
1650
|
+
});
|
|
1651
|
+
}
|
|
1652
|
+
/**
|
|
1653
|
+
* Awaits the response from a user's attempt to log in with OAuth.
|
|
1654
|
+
* If successful, this returns the user's email address and indicates whether the user already exists.
|
|
1655
|
+
*
|
|
1656
|
+
* @param {Object} opts the options object.
|
|
1657
|
+
* @param {Window} [opts.popupWindow] the popup window being used for login.
|
|
1658
|
+
* @return {Object} the user's email address and whether the user already exists.
|
|
1659
|
+
*/
|
|
1660
|
+
waitForOAuth({ popupWindow } = {}) {
|
|
1661
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1662
|
+
this.isAwaitingOAuth = true;
|
|
1663
|
+
while (this.isAwaitingOAuth) {
|
|
1664
|
+
try {
|
|
1665
|
+
if (popupWindow === null || popupWindow === void 0 ? void 0 : popupWindow.closed) {
|
|
1666
|
+
return { isError: true, userExists: false };
|
|
1667
|
+
}
|
|
1668
|
+
yield new Promise(resolve => setTimeout(resolve, POLLING_INTERVAL_MS));
|
|
1669
|
+
if (this.isAwaitingOAuth) {
|
|
1670
|
+
const res = yield this.touchSession();
|
|
1671
|
+
if (res.data.userId) {
|
|
1672
|
+
const { userId, email } = res.data;
|
|
1673
|
+
yield this.setUserId(userId);
|
|
1674
|
+
yield this.setEmail(email);
|
|
1675
|
+
const userExists = yield this.checkIfUserExists(email);
|
|
1676
|
+
this.isAwaitingOAuth = false;
|
|
1677
|
+
return {
|
|
1678
|
+
userExists,
|
|
1679
|
+
email,
|
|
1680
|
+
};
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
catch (err) {
|
|
1685
|
+
console.error(err);
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
return { userExists: false };
|
|
1689
|
+
});
|
|
1690
|
+
}
|
|
1691
|
+
/**
|
|
1692
|
+
* Waits for the session to be active and sets up the user.
|
|
1693
|
+
*
|
|
1694
|
+
* @param {Object} opts the options object
|
|
1695
|
+
* @param {Window} [opts.popupWindow] the popup window being used for login.
|
|
1696
|
+
* @param {boolean} [opts.skipSessionRefresh] whether to skip refreshing the session.
|
|
1697
|
+
* @returns { needsWallet } - whether a wallet needs to be created
|
|
1698
|
+
**/
|
|
1699
|
+
waitForLoginAndSetup({ popupWindow, skipSessionRefresh = false, } = {}) {
|
|
1700
|
+
var _a;
|
|
1701
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1702
|
+
// Remove external wallets if logging in with Para
|
|
1703
|
+
this.currentExternalWalletAddresses = undefined;
|
|
1704
|
+
this.externalWallets = {};
|
|
1705
|
+
this.isAwaitingLogin = true;
|
|
1706
|
+
while (this.isAwaitingLogin) {
|
|
1707
|
+
try {
|
|
1708
|
+
yield new Promise(resolve => setTimeout(resolve, POLLING_INTERVAL_MS));
|
|
1709
|
+
if (!(yield this.isSessionActive())) {
|
|
1710
|
+
if (popupWindow === null || popupWindow === void 0 ? void 0 : popupWindow.closed) {
|
|
1711
|
+
return { isComplete: false, isError: true };
|
|
1712
|
+
}
|
|
1713
|
+
continue;
|
|
1714
|
+
}
|
|
1715
|
+
const postLoginData = yield this.userSetupAfterLogin();
|
|
1716
|
+
const needsWallet = (_a = postLoginData.data.needsWallet) !== null && _a !== void 0 ? _a : false;
|
|
1717
|
+
if (!needsWallet) {
|
|
1718
|
+
if (this.currentWalletIdsArray.length === 0) {
|
|
1719
|
+
if (popupWindow === null || popupWindow === void 0 ? void 0 : popupWindow.closed) {
|
|
1720
|
+
return { isComplete: false, isError: true };
|
|
1721
|
+
}
|
|
1722
|
+
else {
|
|
1723
|
+
continue;
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
const fetchedWallets = yield this.fetchWallets();
|
|
1728
|
+
const tempSharesRes = yield this.getTransmissionKeyShares();
|
|
1729
|
+
// need this check for the case where user has logged in but temp encrypted shares
|
|
1730
|
+
// haven't been sent to the backend yet
|
|
1731
|
+
if (tempSharesRes.data.temporaryShares.length === fetchedWallets.length) {
|
|
1732
|
+
yield this.setupAfterLogin({ temporaryShares: tempSharesRes.data.temporaryShares, skipSessionRefresh });
|
|
1733
|
+
yield this.claimPregenWallets();
|
|
1734
|
+
return {
|
|
1735
|
+
isComplete: true,
|
|
1736
|
+
needsWallet: needsWallet || Object.values(this.wallets).length === 0,
|
|
1737
|
+
partnerId: postLoginData.data.partnerId,
|
|
1738
|
+
};
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
catch (err) {
|
|
1742
|
+
// want to continue polling on error
|
|
1743
|
+
console.error(err);
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
return { isComplete: false };
|
|
1747
|
+
});
|
|
1748
|
+
}
|
|
1749
|
+
/**
|
|
1750
|
+
* Updates the session with the user management server, possibly
|
|
1751
|
+
* opening a popup to refresh the session.
|
|
1752
|
+
*
|
|
1753
|
+
* @param {Object} opts the options object.
|
|
1754
|
+
* @param {boolean} [shouldOpenPopup] - if `true`, the running device will open a popup to reauthenticate the user.
|
|
1755
|
+
* @returns - a URL for the user to reauthenticate.
|
|
1756
|
+
**/
|
|
1757
|
+
refreshSession({ shouldOpenPopup = false } = {}) {
|
|
1758
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1759
|
+
const res = yield this.touchSession(true);
|
|
1760
|
+
if (!this.loginEncryptionKeyPair) {
|
|
1761
|
+
yield this.setLoginEncryptionKeyPair();
|
|
1762
|
+
}
|
|
1763
|
+
const link = yield this.getWebAuthURLForLogin({
|
|
1764
|
+
sessionId: res.data.sessionId,
|
|
1765
|
+
loginEncryptionPublicKey: getPublicKeyHex(this.loginEncryptionKeyPair),
|
|
1766
|
+
});
|
|
1767
|
+
if (shouldOpenPopup) {
|
|
1768
|
+
this.platformUtils.openPopup(link);
|
|
1769
|
+
}
|
|
1770
|
+
return link;
|
|
1771
|
+
});
|
|
1772
|
+
}
|
|
1773
|
+
/**
|
|
1774
|
+
* Call this method after login to ensure that the user ID is set
|
|
1775
|
+
* internally.
|
|
1776
|
+
**/
|
|
1777
|
+
userSetupAfterLogin() {
|
|
1778
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1779
|
+
const res = yield this.touchSession();
|
|
1780
|
+
yield this.setUserId(res.data.userId);
|
|
1781
|
+
if (res.data.currentWalletIds && res.data.currentWalletIds !== this.currentWalletIds)
|
|
1782
|
+
yield this.setCurrentWalletIds(res.data.currentWalletIds, {
|
|
1783
|
+
sessionLookupId: this.isPortal() ? res.data.sessionLookupId : undefined,
|
|
1784
|
+
});
|
|
1785
|
+
return res;
|
|
1786
|
+
});
|
|
1787
|
+
}
|
|
1788
|
+
/**
|
|
1789
|
+
* Get transmission shares associated with session.
|
|
1790
|
+
*
|
|
1791
|
+
* @param isForNewDevice - true if this device is registering.
|
|
1792
|
+
* @returns - transmission keyshares.
|
|
1793
|
+
**/
|
|
1794
|
+
getTransmissionKeyShares({ isForNewDevice = false } = {}) {
|
|
1795
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1796
|
+
const res = yield this.touchSession();
|
|
1797
|
+
const sessionLookupId = isForNewDevice ? `${res.data.sessionLookupId}-new-device` : res.data.sessionLookupId;
|
|
1798
|
+
return this.ctx.client.getTransmissionKeyshares(this.userId, sessionLookupId);
|
|
1799
|
+
});
|
|
1800
|
+
}
|
|
1801
|
+
/**
|
|
1802
|
+
* Call this method after login to perform setup.
|
|
1803
|
+
*
|
|
1804
|
+
* @param temporaryShares - optional temporary shares to use for decryption.
|
|
1805
|
+
**/
|
|
1806
|
+
setupAfterLogin({ temporaryShares, skipSessionRefresh = false, } = {}) {
|
|
1807
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1808
|
+
if (!temporaryShares) {
|
|
1809
|
+
temporaryShares = (yield this.getTransmissionKeyShares()).data.temporaryShares;
|
|
1810
|
+
}
|
|
1811
|
+
temporaryShares.forEach(share => {
|
|
1812
|
+
const signer = decryptWithPrivateKey(this.loginEncryptionKeyPair.privateKey, share.encryptedShare, share.encryptedKey);
|
|
1813
|
+
this.wallets[share.walletId] = {
|
|
1814
|
+
id: share.walletId,
|
|
1815
|
+
signer,
|
|
1816
|
+
};
|
|
1817
|
+
});
|
|
1818
|
+
yield this.deleteLoginEncryptionKeyPair();
|
|
1819
|
+
yield this.populateWalletAddresses();
|
|
1820
|
+
yield this.touchSession(!skipSessionRefresh);
|
|
1821
|
+
});
|
|
1822
|
+
}
|
|
1823
|
+
/**
|
|
1824
|
+
* Distributes a new wallet recovery share.
|
|
1825
|
+
*
|
|
1826
|
+
* @param walletId - the wallet to distribute the recovery share for.
|
|
1827
|
+
* @param userShare - optional user share generate the recovery share from. Defaults to the signer from the passed in walletId
|
|
1828
|
+
* @param skipBiometricShareCreation - whether or not to skip biometric share creation. Used when regenerating recovery shares.
|
|
1829
|
+
* @param forceRefreshRecovery - whether or not to force recovery secret regeneration. Used when regenerating recovery shares.
|
|
1830
|
+
* @returns - recovery share.
|
|
1831
|
+
**/
|
|
1832
|
+
distributeNewWalletShare({ walletId, userShare, skipBiometricShareCreation = false, forceRefresh = false, }) {
|
|
1833
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1834
|
+
let userSigner = userShare;
|
|
1835
|
+
if (!userSigner) {
|
|
1836
|
+
userSigner = this.wallets[walletId].signer;
|
|
1837
|
+
}
|
|
1838
|
+
const recoveryShare = skipBiometricShareCreation
|
|
1839
|
+
? yield sendRecoveryForShare({
|
|
1840
|
+
ctx: this.ctx,
|
|
1841
|
+
userId: this.userId,
|
|
1842
|
+
walletId,
|
|
1843
|
+
userSigner,
|
|
1844
|
+
emailProps: this.getBackupKitEmailProps(),
|
|
1845
|
+
forceRefresh,
|
|
1846
|
+
})
|
|
1847
|
+
: yield distributeNewShare({
|
|
1848
|
+
ctx: this.ctx,
|
|
1849
|
+
userId: this.userId,
|
|
1850
|
+
walletId,
|
|
1851
|
+
userShare: userSigner,
|
|
1852
|
+
emailProps: this.getBackupKitEmailProps(),
|
|
1853
|
+
});
|
|
1854
|
+
return recoveryShare;
|
|
1855
|
+
});
|
|
1856
|
+
}
|
|
1857
|
+
waitForWalletAddress(walletId) {
|
|
1858
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1859
|
+
let maxPolls = 0;
|
|
1860
|
+
while (true) {
|
|
1861
|
+
try {
|
|
1862
|
+
if (maxPolls === 10) {
|
|
1863
|
+
break;
|
|
1864
|
+
}
|
|
1865
|
+
++maxPolls;
|
|
1866
|
+
const res = yield this.ctx.client.getWallets(this.userId);
|
|
1867
|
+
const wallet = res.data.wallets.find(w => w.id === walletId);
|
|
1868
|
+
if (wallet && wallet.address) {
|
|
1869
|
+
return;
|
|
1870
|
+
}
|
|
1871
|
+
yield new Promise(resolve => setTimeout(resolve, SHORT_POLLING_INTERVAL_MS));
|
|
1872
|
+
}
|
|
1873
|
+
catch (err) {
|
|
1874
|
+
// want to continue polling on error
|
|
1875
|
+
console.error(err);
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
throw new Error('timed out waiting for wallet address');
|
|
1879
|
+
});
|
|
1880
|
+
}
|
|
1881
|
+
/**
|
|
1882
|
+
* Waits for a pregen wallet address to be created.
|
|
1883
|
+
*
|
|
1884
|
+
* @param pregenIdentifier - the identifier of the user the pregen wallet is associated with.
|
|
1885
|
+
* @param walletId - the wallet id
|
|
1886
|
+
* @param pregenIdentifierType - the identifier type of the user the pregen wallet is associated with.
|
|
1887
|
+
* @returns - recovery share.
|
|
1888
|
+
**/
|
|
1889
|
+
waitForPregenWalletAddress(walletId) {
|
|
1890
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1891
|
+
let maxPolls = 0;
|
|
1892
|
+
while (true) {
|
|
1893
|
+
try {
|
|
1894
|
+
if (maxPolls === 10) {
|
|
1895
|
+
break;
|
|
1896
|
+
}
|
|
1897
|
+
++maxPolls;
|
|
1898
|
+
const res = yield this.getPregenWallets();
|
|
1899
|
+
const wallet = res.find(w => w.id === walletId);
|
|
1900
|
+
if (wallet && wallet.address) {
|
|
1901
|
+
return;
|
|
1902
|
+
}
|
|
1903
|
+
yield new Promise(resolve => setTimeout(resolve, SHORT_POLLING_INTERVAL_MS));
|
|
1904
|
+
}
|
|
1905
|
+
catch (err) {
|
|
1906
|
+
// want to continue polling on error
|
|
1907
|
+
console.error(err);
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
throw new Error('timed out waiting for wallet address');
|
|
1911
|
+
});
|
|
1912
|
+
}
|
|
1913
|
+
/**
|
|
1914
|
+
* Creates several new wallets with the desired types. If no types are provided, this method
|
|
1915
|
+
* will create one for each of the non-optional types specified in the instance's `supportedWalletTypes`
|
|
1916
|
+
* object that are not already present. This is automatically called upon account creation to ensure that
|
|
1917
|
+
* the user has a wallet of each required type.
|
|
1918
|
+
*
|
|
1919
|
+
* @param {Object} [opts] the options object.
|
|
1920
|
+
* @param {boolean} [opts.skipDistribute] if `true`, the wallets' recovery share will not be distributed.
|
|
1921
|
+
* @param {WalletType[]} [opts.types] the types of wallets to create.
|
|
1922
|
+
* @returns {Object} the wallets created, their ids, and the recovery secret.
|
|
1923
|
+
**/
|
|
1924
|
+
createWalletPerType({ skipDistribute = false, types, } = {}) {
|
|
1925
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1926
|
+
const wallets = [];
|
|
1927
|
+
const walletIds = {};
|
|
1928
|
+
let recoverySecret;
|
|
1929
|
+
for (const type of yield this.getTypesToCreate(types)) {
|
|
1930
|
+
const [wallet, recoveryShare] = yield this.createWallet({ type, skipDistribute });
|
|
1931
|
+
wallets.push(wallet);
|
|
1932
|
+
getEquivalentTypes(type)
|
|
1933
|
+
.filter(t => !!this.isWalletTypeEnabled[t])
|
|
1934
|
+
.forEach(t => {
|
|
1935
|
+
walletIds[t] = [wallet.id];
|
|
1936
|
+
});
|
|
1937
|
+
if (recoveryShare) {
|
|
1938
|
+
recoverySecret = recoveryShare;
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
return { wallets, walletIds, recoverySecret };
|
|
1942
|
+
});
|
|
1943
|
+
}
|
|
1944
|
+
/**
|
|
1945
|
+
* Refresh the current user share for a wallet.
|
|
1946
|
+
*
|
|
1947
|
+
* @param {Object} opts the options object.
|
|
1948
|
+
* @param {string} opts.walletId the wallet id to refresh.
|
|
1949
|
+
* @param {string} opts.share the current user share.
|
|
1950
|
+
* @param {string} [opts.oldPartnerId] the current partner id.
|
|
1951
|
+
* @param {string} [opts.newPartnerId] the new partner id to set, if any.
|
|
1952
|
+
* @param {string} [opts.keyShareProtocolId]
|
|
1953
|
+
* @param {boolean} [opts.redistributeBackupEncryptedShares] whether or not to redistribute backup encrypted shares.
|
|
1954
|
+
* @returns {Object} the new user share and recovery secret.
|
|
1955
|
+
**/
|
|
1956
|
+
refreshShare({ walletId, share, oldPartnerId, newPartnerId, keyShareProtocolId, redistributeBackupEncryptedShares, }) {
|
|
1957
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1958
|
+
const { signer, protocolId } = yield this.platformUtils.refresh(this.ctx, this.retrieveSessionCookie(), this.userId, walletId, share, oldPartnerId, newPartnerId, keyShareProtocolId);
|
|
1959
|
+
const recoverySecret = yield distributeNewShare({
|
|
1960
|
+
ctx: this.ctx,
|
|
1961
|
+
userId: this.userId,
|
|
1962
|
+
walletId,
|
|
1963
|
+
userShare: signer,
|
|
1964
|
+
ignoreRedistributingBackupEncryptedShare: !redistributeBackupEncryptedShares,
|
|
1965
|
+
emailProps: this.getBackupKitEmailProps(),
|
|
1966
|
+
partnerId: newPartnerId,
|
|
1967
|
+
protocolId,
|
|
1968
|
+
});
|
|
1969
|
+
return { signer, recoverySecret, protocolId };
|
|
1970
|
+
});
|
|
1971
|
+
}
|
|
1972
|
+
/**
|
|
1973
|
+
* Creates a new wallet.
|
|
1974
|
+
*
|
|
1975
|
+
* @param skipDistribute - if true, recovery share will not be distributed.
|
|
1976
|
+
* @param [customFunction] - {deprecated} method called when createWallet is done.
|
|
1977
|
+
* @returns [wallet, recoveryShare]
|
|
1978
|
+
**/
|
|
1979
|
+
createWallet({ type: _type, skipDistribute = false, } = {}) {
|
|
1980
|
+
var _a, _b;
|
|
1981
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1982
|
+
this.requireApiKey();
|
|
1983
|
+
const walletType = yield this.assertIsValidWalletType(_type !== null && _type !== void 0 ? _type : (_a = this.supportedWalletTypes.find(({ optional }) => !optional)) === null || _a === void 0 ? void 0 : _a.type);
|
|
1984
|
+
let signer;
|
|
1985
|
+
let wallet;
|
|
1986
|
+
let keygenRes;
|
|
1987
|
+
switch (walletType) {
|
|
1988
|
+
case WalletType.SOLANA: {
|
|
1989
|
+
keygenRes = yield this.platformUtils.ed25519Keygen(this.ctx, this.userId, this.retrieveSessionCookie(), this.getBackupKitEmailProps());
|
|
1990
|
+
break;
|
|
1991
|
+
}
|
|
1992
|
+
default: {
|
|
1993
|
+
keygenRes = yield this.platformUtils.keygen(this.ctx, this.userId, walletType, null, this.retrieveSessionCookie(), this.getBackupKitEmailProps());
|
|
1994
|
+
break;
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
const walletId = keygenRes.walletId;
|
|
1998
|
+
signer = keygenRes.signer;
|
|
1999
|
+
this.wallets[walletId] = {
|
|
2000
|
+
id: walletId,
|
|
2001
|
+
signer,
|
|
2002
|
+
scheme: walletType === WalletType.SOLANA ? WalletScheme.ED25519 : WalletScheme.DKLS,
|
|
2003
|
+
type: walletType,
|
|
2004
|
+
};
|
|
2005
|
+
wallet = this.wallets[walletId];
|
|
2006
|
+
yield this.waitForWalletAddress(wallet.id);
|
|
2007
|
+
yield this.populateWalletAddresses();
|
|
2008
|
+
let recoveryShare = null;
|
|
2009
|
+
if (!skipDistribute) {
|
|
2010
|
+
recoveryShare = yield distributeNewShare({
|
|
2011
|
+
ctx: this.ctx,
|
|
2012
|
+
userId: this.userId,
|
|
2013
|
+
walletId: wallet.id,
|
|
2014
|
+
userShare: signer,
|
|
2015
|
+
emailProps: this.getBackupKitEmailProps(),
|
|
2016
|
+
});
|
|
2017
|
+
}
|
|
2018
|
+
yield this.setCurrentWalletIds(Object.assign(Object.assign({}, this.currentWalletIds), { [walletType]: [...((_b = this.currentWalletIds[walletType]) !== null && _b !== void 0 ? _b : []), walletId] }));
|
|
2019
|
+
return [wallet, recoveryShare];
|
|
2020
|
+
});
|
|
2021
|
+
}
|
|
2022
|
+
/**
|
|
2023
|
+
* Creates a new pregenerated wallet.
|
|
2024
|
+
*
|
|
2025
|
+
* @param {Object} opts the options object.
|
|
2026
|
+
* @param {string} opts.pregenIdentifier the identifier associated with the new wallet.
|
|
2027
|
+
* @param {TPregenIdentifierType} [opts.pregenIdentifierType] the identifier type. Defaults to `EMAIL`.
|
|
2028
|
+
* @param {WalletType} [opts.type] the type of wallet to create. Defaults to the first non-optional type in the instance's `supportedWalletTypes` array.
|
|
2029
|
+
* @returns {Wallet} the created wallet.
|
|
2030
|
+
**/
|
|
2031
|
+
createWalletPreGen(opts) {
|
|
2032
|
+
var _a, _b;
|
|
2033
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2034
|
+
const { type: _type = (_a = this.supportedWalletTypes.find(({ optional }) => !optional)) === null || _a === void 0 ? void 0 : _a.type, pregenIdentifier, pregenIdentifierType = 'EMAIL', } = opts;
|
|
2035
|
+
this.requireApiKey();
|
|
2036
|
+
const walletType = yield this.assertIsValidWalletType(_type !== null && _type !== void 0 ? _type : (_b = this.supportedWalletTypes.find(({ optional }) => !optional)) === null || _b === void 0 ? void 0 : _b.type);
|
|
2037
|
+
let keygenRes;
|
|
2038
|
+
switch (walletType) {
|
|
2039
|
+
case WalletType.SOLANA:
|
|
2040
|
+
keygenRes = yield this.platformUtils.ed25519PreKeygen(this.ctx, pregenIdentifier, pregenIdentifierType, this.retrieveSessionCookie());
|
|
2041
|
+
break;
|
|
2042
|
+
default:
|
|
2043
|
+
keygenRes = yield this.platformUtils.preKeygen(this.ctx, undefined, pregenIdentifier, pregenIdentifierType, walletType, null, this.retrieveSessionCookie());
|
|
2044
|
+
break;
|
|
2045
|
+
}
|
|
2046
|
+
const { signer, walletId } = keygenRes;
|
|
2047
|
+
this.wallets[walletId] = {
|
|
2048
|
+
id: walletId,
|
|
2049
|
+
signer,
|
|
2050
|
+
scheme: walletType === WalletType.SOLANA ? WalletScheme.ED25519 : WalletScheme.DKLS,
|
|
2051
|
+
type: walletType,
|
|
2052
|
+
isPregen: true,
|
|
2053
|
+
pregenIdentifier,
|
|
2054
|
+
pregenIdentifierType,
|
|
2055
|
+
};
|
|
2056
|
+
yield this.waitForPregenWalletAddress(walletId);
|
|
2057
|
+
yield this.populatePregenWalletAddresses();
|
|
2058
|
+
return this.wallets[walletId];
|
|
2059
|
+
});
|
|
2060
|
+
}
|
|
2061
|
+
/**
|
|
2062
|
+
* Creates new pregenerated wallets for each desired type.
|
|
2063
|
+
* If no types are provided, this method will create one for each of the non-optional types
|
|
2064
|
+
* specified in the instance's `supportedWalletTypes` array that are not already present.
|
|
2065
|
+
*
|
|
2066
|
+
* @param {string} pregenIdentifier the identifier to associate each wallet with.
|
|
2067
|
+
* @param {TPregenIdentifierType} pregenIdentifierType - either `'EMAIL'` or `'PHONE'`.
|
|
2068
|
+
* @param {WalletType[]} [types] the wallet types to create. Defaults to any types the instance supports that are not already present.
|
|
2069
|
+
* @returns an array containing the created wallets.
|
|
2070
|
+
**/
|
|
2071
|
+
createPregenWalletPerType({ types, pregenIdentifier, pregenIdentifierType = 'EMAIL', }) {
|
|
2072
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2073
|
+
const wallets = [];
|
|
2074
|
+
for (const type of yield this.getTypesToCreate(types)) {
|
|
2075
|
+
const wallet = yield this.createWalletPreGen({ type, pregenIdentifier, pregenIdentifierType });
|
|
2076
|
+
wallets.push(wallet);
|
|
2077
|
+
}
|
|
2078
|
+
return wallets;
|
|
2079
|
+
});
|
|
2080
|
+
}
|
|
2081
|
+
/**
|
|
2082
|
+
* Claims a pregenerated wallet.
|
|
2083
|
+
*
|
|
2084
|
+
* @param pregenIdentifier string the identifier of the user claiming the wallet
|
|
2085
|
+
* @param pregenIdentifierType type of the identifier of the user claiming the wallet
|
|
2086
|
+
* @returns [wallet, recoveryShare]
|
|
2087
|
+
**/
|
|
2088
|
+
claimPregenWallets(pregenIdentifier, pregenIdentifierType = !!pregenIdentifier ? 'EMAIL' : undefined) {
|
|
2089
|
+
var _a;
|
|
2090
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2091
|
+
this.requireApiKey();
|
|
2092
|
+
const pregenWallets = pregenIdentifier && pregenIdentifierType
|
|
2093
|
+
? yield this.getPregenWallets({ pregenIdentifier, pregenIdentifierType })
|
|
2094
|
+
: yield this.getPregenWallets();
|
|
2095
|
+
if (pregenWallets.length === 0) {
|
|
2096
|
+
return undefined;
|
|
2097
|
+
}
|
|
2098
|
+
let newRecoverySecret;
|
|
2099
|
+
const { walletIds } = yield this.ctx.client.claimPregenWallets({
|
|
2100
|
+
userId: this.userId,
|
|
2101
|
+
walletIds: pregenWallets.map(w => w.id),
|
|
2102
|
+
});
|
|
2103
|
+
for (const walletId of walletIds) {
|
|
2104
|
+
const wallet = this.wallets[walletId];
|
|
2105
|
+
let refreshedShare;
|
|
2106
|
+
if (wallet.scheme === WalletScheme.ED25519) {
|
|
2107
|
+
const distributeRes = yield distributeNewShare({
|
|
2108
|
+
ctx: this.ctx,
|
|
2109
|
+
userId: this.userId,
|
|
2110
|
+
walletId: wallet.id,
|
|
2111
|
+
userShare: this.wallets[wallet.id].signer,
|
|
2112
|
+
emailProps: this.getBackupKitEmailProps(),
|
|
2113
|
+
partnerId: wallet.partnerId,
|
|
2114
|
+
});
|
|
2115
|
+
if (distributeRes.length > 0) {
|
|
2116
|
+
newRecoverySecret = distributeRes;
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2119
|
+
else {
|
|
2120
|
+
refreshedShare = yield this.refreshShare({
|
|
2121
|
+
walletId: wallet.id,
|
|
2122
|
+
share: this.wallets[wallet.id].signer,
|
|
2123
|
+
oldPartnerId: wallet.partnerId,
|
|
2124
|
+
newPartnerId: wallet.partnerId,
|
|
2125
|
+
redistributeBackupEncryptedShares: true,
|
|
2126
|
+
});
|
|
2127
|
+
if (refreshedShare.recoverySecret) {
|
|
2128
|
+
newRecoverySecret = refreshedShare.recoverySecret;
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
this.wallets[wallet.id] = Object.assign(Object.assign({}, this.wallets[wallet.id]), { signer: (_a = refreshedShare === null || refreshedShare === void 0 ? void 0 : refreshedShare.signer) !== null && _a !== void 0 ? _a : wallet.signer, userId: this.userId, pregenIdentifier: undefined, pregenIdentifierType: undefined });
|
|
2132
|
+
}
|
|
2133
|
+
yield this.setWallets(this.wallets);
|
|
2134
|
+
return newRecoverySecret;
|
|
2135
|
+
});
|
|
2136
|
+
}
|
|
2137
|
+
/**
|
|
2138
|
+
* Updates a pregenerated wallet identifier.
|
|
2139
|
+
*
|
|
2140
|
+
* @param newIdentifier - string
|
|
2141
|
+
* @param walletId - string
|
|
2142
|
+
* @returns Promise<void>
|
|
2143
|
+
**/
|
|
2144
|
+
updatePregenWalletIdentifier({ walletId, newPregenIdentifier, newPregenIdentifierType, }) {
|
|
2145
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2146
|
+
this.requireApiKey();
|
|
2147
|
+
yield this.ctx.client.updatePregenWallet(walletId, {
|
|
2148
|
+
pregenIdentifier: newPregenIdentifier,
|
|
2149
|
+
pregenIdentifierType: newPregenIdentifierType,
|
|
2150
|
+
});
|
|
2151
|
+
if (!!this.wallets[walletId]) {
|
|
2152
|
+
this.wallets[walletId] = Object.assign(Object.assign({}, this.wallets[walletId]), { pregenIdentifier: newPregenIdentifier, pregenIdentifierType: newPregenIdentifierType });
|
|
2153
|
+
yield this.setWallets(this.wallets);
|
|
2154
|
+
}
|
|
2155
|
+
});
|
|
2156
|
+
}
|
|
2157
|
+
/**
|
|
2158
|
+
* Checks if Pregen Wallet exists for the identifier and partnerId
|
|
2159
|
+
*
|
|
2160
|
+
* @param pregenIdentifier string the identifier of the user claiming the wallet
|
|
2161
|
+
* @param pregenIdentifierType type of the string of the identifier of the user claiming the wallet
|
|
2162
|
+
* @returns Promise<boolean>
|
|
2163
|
+
**/
|
|
2164
|
+
hasPregenWallet({ pregenIdentifier, pregenIdentifierType, }) {
|
|
2165
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2166
|
+
this.requireApiKey();
|
|
2167
|
+
// This function gets pregen wallets by identifier and partnerId
|
|
2168
|
+
const res = yield this.getPregenWallets({ pregenIdentifier, pregenIdentifierType });
|
|
2169
|
+
const wallet = res.find(w => w.pregenIdentifier === pregenIdentifier && w.pregenIdentifierType === pregenIdentifierType);
|
|
2170
|
+
if (!wallet) {
|
|
2171
|
+
return false;
|
|
2172
|
+
}
|
|
2173
|
+
return true;
|
|
2174
|
+
});
|
|
2175
|
+
}
|
|
2176
|
+
/**
|
|
2177
|
+
* Get pregen wallets for the identifier
|
|
2178
|
+
*
|
|
2179
|
+
* @param {string} pregenIdentifier - the identifier of the user claiming the wallet
|
|
2180
|
+
* @param {TPregenIdentifierType} pregenIdentifierType - type of the identifier of the user claiming the wallet
|
|
2181
|
+
* @returns {Promise<WalletEntity[]>} Promise of pregen wallets
|
|
2182
|
+
**/
|
|
2183
|
+
getPregenWallets({ pregenIdentifier, pregenIdentifierType = !!pregenIdentifier ? 'EMAIL' : undefined, } = {}) {
|
|
2184
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2185
|
+
this.requireApiKey();
|
|
2186
|
+
const res = yield this.ctx.client.getPregenWallets(pregenIdentifier && pregenIdentifierType ? { [pregenIdentifierType]: [pregenIdentifier] } : this.pregenIds, this.isPortal(), this.userId);
|
|
2187
|
+
return res.wallets.filter(w => this.isWalletSupported(entityToWallet(w)));
|
|
2188
|
+
});
|
|
2189
|
+
}
|
|
2190
|
+
encodeWalletBase64(wallet) {
|
|
2191
|
+
const walletJson = JSON.stringify(wallet);
|
|
2192
|
+
const base64Wallet = Buffer.from(walletJson).toString('base64');
|
|
2193
|
+
return base64Wallet;
|
|
2194
|
+
}
|
|
2195
|
+
/**
|
|
2196
|
+
* Returns a base64 encoded wallet
|
|
2197
|
+
*
|
|
2198
|
+
* @returns string base64 encoded wallet
|
|
2199
|
+
**/
|
|
2200
|
+
getUserShare() {
|
|
2201
|
+
if (Object.values(this.wallets).length === 0) {
|
|
2202
|
+
return null;
|
|
2203
|
+
}
|
|
2204
|
+
return Object.values(this.wallets)
|
|
2205
|
+
.map(wallet => this.encodeWalletBase64(wallet))
|
|
2206
|
+
.join('-');
|
|
2207
|
+
}
|
|
2208
|
+
/**
|
|
2209
|
+
* Sets a wallet from a base 64 encoded wallet
|
|
2210
|
+
*
|
|
2211
|
+
* @param base64Wallet
|
|
2212
|
+
* @returns Promise<void>
|
|
2213
|
+
**/
|
|
2214
|
+
setUserShare(base64Wallets) {
|
|
2215
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2216
|
+
if (!base64Wallets) {
|
|
2217
|
+
return;
|
|
2218
|
+
}
|
|
2219
|
+
const base64WalletsSplit = base64Wallets.split('-');
|
|
2220
|
+
for (const base64Wallet of base64WalletsSplit) {
|
|
2221
|
+
const walletJson = Buffer.from(base64Wallet, 'base64').toString();
|
|
2222
|
+
const wallet = migrateWallet(JSON.parse(walletJson));
|
|
2223
|
+
this.wallets[wallet.id] = wallet;
|
|
2224
|
+
yield this.setWallets(this.wallets);
|
|
2225
|
+
}
|
|
2226
|
+
});
|
|
2227
|
+
}
|
|
2228
|
+
getTransactionReviewUrl(transactionId, timeoutMs) {
|
|
2229
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2230
|
+
const res = yield this.touchSession();
|
|
2231
|
+
return this.constructPortalUrl('txReview', {
|
|
2232
|
+
partnerId: res.data.partnerId,
|
|
2233
|
+
pathId: transactionId,
|
|
2234
|
+
params: {
|
|
2235
|
+
email: this.email,
|
|
2236
|
+
timeoutMs: timeoutMs === null || timeoutMs === void 0 ? void 0 : timeoutMs.toString(),
|
|
2237
|
+
},
|
|
2238
|
+
});
|
|
2239
|
+
});
|
|
2240
|
+
}
|
|
2241
|
+
getOnRampTransactionUrl(_a) {
|
|
2242
|
+
var { purchaseId, providerKey } = _a, walletParams = __rest(_a, ["purchaseId", "providerKey"]);
|
|
2243
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2244
|
+
const res = yield this.touchSession();
|
|
2245
|
+
const [key, identifier] = extractWalletRef(walletParams);
|
|
2246
|
+
return this.constructPortalUrl('onRamp', {
|
|
2247
|
+
partnerId: res.data.partnerId,
|
|
2248
|
+
pathId: purchaseId,
|
|
2249
|
+
sessionId: res.data.sessionId,
|
|
2250
|
+
params: {
|
|
2251
|
+
[key]: identifier,
|
|
2252
|
+
providerKey,
|
|
2253
|
+
currentWalletIds: JSON.stringify(this.currentWalletIds),
|
|
2254
|
+
},
|
|
2255
|
+
});
|
|
2256
|
+
});
|
|
2257
|
+
}
|
|
2258
|
+
/**
|
|
2259
|
+
* Signs a message.
|
|
2260
|
+
*
|
|
2261
|
+
* If you want to sign the keccak256 hash of a message, hash the
|
|
2262
|
+
* message first and then pass in the base64 encoded hash.
|
|
2263
|
+
* @param walletId - id of the wallet to sign with.
|
|
2264
|
+
* @param messageBase64 - base64 encoding of exact message that should be signed
|
|
2265
|
+
* @param timeout - optional timeout in milliseconds. If not present, defaults to 30 seconds.
|
|
2266
|
+
**/
|
|
2267
|
+
signMessage({ walletId, messageBase64, timeoutMs = 30000, cosmosSignDocBase64, }) {
|
|
2268
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2269
|
+
this.assertIsValidWalletId(walletId);
|
|
2270
|
+
const wallet = this.wallets[walletId];
|
|
2271
|
+
let signerId = this.userId;
|
|
2272
|
+
if (wallet.partnerId && !wallet.userId) {
|
|
2273
|
+
signerId = wallet.partnerId;
|
|
2274
|
+
}
|
|
2275
|
+
let signRes = yield this.signMessageInner({ wallet, signerId, messageBase64, cosmosSignDocBase64 });
|
|
2276
|
+
let timeStart = Date.now();
|
|
2277
|
+
if (signRes.pendingTransactionId) {
|
|
2278
|
+
this.platformUtils.openPopup(yield this.getTransactionReviewUrl(signRes.pendingTransactionId, timeoutMs), { type: cosmosSignDocBase64 ? PopupType.SIGN_TRANSACTION_REVIEW : PopupType.SIGN_MESSAGE_REVIEW });
|
|
2279
|
+
}
|
|
2280
|
+
else {
|
|
2281
|
+
return signRes;
|
|
2282
|
+
}
|
|
2283
|
+
yield new Promise(resolve => setTimeout(resolve, POLLING_INTERVAL_MS));
|
|
2284
|
+
while (true) {
|
|
2285
|
+
if (Date.now() - timeStart > timeoutMs) {
|
|
2286
|
+
break;
|
|
2287
|
+
}
|
|
2288
|
+
try {
|
|
2289
|
+
yield this.ctx.client.getPendingTransaction(this.userId, signRes.pendingTransactionId);
|
|
2290
|
+
}
|
|
2291
|
+
catch (err) {
|
|
2292
|
+
throw new TransactionReviewDenied();
|
|
2293
|
+
}
|
|
2294
|
+
signRes = yield this.signMessageInner({ wallet, signerId, messageBase64, cosmosSignDocBase64 });
|
|
2295
|
+
if (signRes.pendingTransactionId) {
|
|
2296
|
+
yield new Promise(resolve => setTimeout(resolve, POLLING_INTERVAL_MS));
|
|
2297
|
+
}
|
|
2298
|
+
else {
|
|
2299
|
+
break;
|
|
2300
|
+
}
|
|
2301
|
+
}
|
|
2302
|
+
if (signRes.pendingTransactionId) {
|
|
2303
|
+
throw new TransactionReviewTimeout(yield this.getTransactionReviewUrl(signRes.pendingTransactionId), signRes.pendingTransactionId);
|
|
2304
|
+
}
|
|
2305
|
+
return signRes;
|
|
2306
|
+
});
|
|
2307
|
+
}
|
|
2308
|
+
signMessageInner({ wallet, signerId, messageBase64, cosmosSignDocBase64, }) {
|
|
2309
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2310
|
+
let signRes;
|
|
2311
|
+
switch (wallet.scheme) {
|
|
2312
|
+
case WalletScheme.ED25519:
|
|
2313
|
+
signRes = yield this.platformUtils.ed25519Sign(this.ctx, signerId, wallet.id, wallet.signer, messageBase64, this.retrieveSessionCookie());
|
|
2314
|
+
break;
|
|
2315
|
+
default:
|
|
2316
|
+
signRes = yield this.platformUtils.signMessage(this.ctx, signerId, wallet.id, wallet.signer, messageBase64, this.retrieveSessionCookie(), wallet.scheme === WalletScheme.DKLS, cosmosSignDocBase64);
|
|
2317
|
+
break;
|
|
2318
|
+
}
|
|
2319
|
+
return signRes;
|
|
2320
|
+
});
|
|
2321
|
+
}
|
|
2322
|
+
/**
|
|
2323
|
+
* Signs a transaction.
|
|
2324
|
+
* @param walletId - id of the wallet to sign the transaction from.
|
|
2325
|
+
* @param rlpEncodedTxBase64 - rlp encoded tx as base64 string
|
|
2326
|
+
* @param chainId - chain id of the chain the transaction is being sent on.
|
|
2327
|
+
**/
|
|
2328
|
+
signTransaction({ walletId, rlpEncodedTxBase64, chainId, timeoutMs = 30000, }) {
|
|
2329
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2330
|
+
this.assertIsValidWalletId(walletId);
|
|
2331
|
+
const wallet = this.wallets[walletId];
|
|
2332
|
+
let signerId = this.userId;
|
|
2333
|
+
if (wallet.partnerId && !wallet.userId) {
|
|
2334
|
+
signerId = wallet.partnerId;
|
|
2335
|
+
}
|
|
2336
|
+
let signRes = yield this.platformUtils.signTransaction(this.ctx, signerId, walletId, this.wallets[walletId].signer, rlpEncodedTxBase64, chainId, this.retrieveSessionCookie(), wallet.scheme === WalletScheme.DKLS);
|
|
2337
|
+
let timeStart = Date.now();
|
|
2338
|
+
if (signRes.pendingTransactionId) {
|
|
2339
|
+
this.platformUtils.openPopup(yield this.getTransactionReviewUrl(signRes.pendingTransactionId, timeoutMs), { type: PopupType.SIGN_TRANSACTION_REVIEW });
|
|
2340
|
+
}
|
|
2341
|
+
else {
|
|
2342
|
+
return signRes;
|
|
2343
|
+
}
|
|
2344
|
+
yield new Promise(resolve => setTimeout(resolve, POLLING_INTERVAL_MS));
|
|
2345
|
+
while (true) {
|
|
2346
|
+
if (Date.now() - timeStart > timeoutMs) {
|
|
2347
|
+
break;
|
|
2348
|
+
}
|
|
2349
|
+
try {
|
|
2350
|
+
yield this.ctx.client.getPendingTransaction(this.userId, signRes.pendingTransactionId);
|
|
2351
|
+
}
|
|
2352
|
+
catch (err) {
|
|
2353
|
+
throw new TransactionReviewDenied();
|
|
2354
|
+
}
|
|
2355
|
+
signRes = yield this.platformUtils.signTransaction(this.ctx, signerId, walletId, this.wallets[walletId].signer, rlpEncodedTxBase64, chainId, this.retrieveSessionCookie(), wallet.scheme === WalletScheme.DKLS);
|
|
2356
|
+
if (signRes.pendingTransactionId) {
|
|
2357
|
+
yield new Promise(resolve => setTimeout(resolve, POLLING_INTERVAL_MS));
|
|
2358
|
+
}
|
|
2359
|
+
else {
|
|
2360
|
+
break;
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2363
|
+
if (signRes.pendingTransactionId) {
|
|
2364
|
+
throw new TransactionReviewTimeout(yield this.getTransactionReviewUrl(signRes.pendingTransactionId), signRes.pendingTransactionId);
|
|
2365
|
+
}
|
|
2366
|
+
return signRes;
|
|
2367
|
+
});
|
|
2368
|
+
}
|
|
2369
|
+
/**
|
|
2370
|
+
* Sends a transaction.
|
|
2371
|
+
* @param walletId - id of the wallet to send the transaction from.
|
|
2372
|
+
* @param rlpEncodedTxBase64 - rlp encoded tx as base64 string
|
|
2373
|
+
* @param chainId - chain id of the chain the transaction is being sent on.
|
|
2374
|
+
**/
|
|
2375
|
+
sendTransaction({ walletId, rlpEncodedTxBase64, chainId, }) {
|
|
2376
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2377
|
+
this.assertIsValidWalletId(walletId);
|
|
2378
|
+
const wallet = this.wallets[walletId];
|
|
2379
|
+
const signRes = yield this.platformUtils.sendTransaction(this.ctx, this.userId, walletId, this.wallets[walletId].signer, rlpEncodedTxBase64, chainId, this.retrieveSessionCookie(), wallet.scheme === WalletScheme.DKLS);
|
|
2380
|
+
if (signRes.pendingTransactionId) {
|
|
2381
|
+
this.platformUtils.openPopup(yield this.getTransactionReviewUrl(signRes.pendingTransactionId), { type: PopupType.SIGN_TRANSACTION_REVIEW });
|
|
2382
|
+
throw new TransactionReviewError(yield this.getTransactionReviewUrl(signRes.pendingTransactionId));
|
|
2383
|
+
}
|
|
2384
|
+
return signRes;
|
|
2385
|
+
});
|
|
2386
|
+
}
|
|
2387
|
+
isProviderModalDisabled() {
|
|
2388
|
+
return !!this.disableProviderModal;
|
|
2389
|
+
}
|
|
2390
|
+
/**
|
|
2391
|
+
* Starts a on-ramp or off-ramp transaction and returns the Para Portal link for the user to finalize and complete it.
|
|
2392
|
+
* @param {Object} options - the options for the transaction.
|
|
2393
|
+
* @param {OnRampPurchaseCreateParams} options.params - the transaction settings.
|
|
2394
|
+
* @param {boolean} options.shouldOpenPopup - if `true`, a popup window with the link will be opened.
|
|
2395
|
+
* @param {string} options.walletId - the wallet ID to use for the transaction, where funds will be sent or withdrawn.
|
|
2396
|
+
* @param {string} options.externalWalletAddress - the external wallet address to send funds to or withdraw funds from, if using an external wallet.
|
|
2397
|
+
**/
|
|
2398
|
+
initiateOnRampTransaction(options) {
|
|
2399
|
+
var _a;
|
|
2400
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2401
|
+
const { params, shouldOpenPopup } = options, walletParams = __rest(options, ["params", "shouldOpenPopup"]);
|
|
2402
|
+
const onRampPurchase = yield this.ctx.client.createOnRampPurchase(Object.assign({ userId: this.userId, params: Object.assign(Object.assign({}, params), { address: (_a = walletParams.externalWalletAddress) !== null && _a !== void 0 ? _a : this.getDisplayAddress(walletParams.walletId, { addressType: params.walletType }) }) }, walletParams));
|
|
2403
|
+
const portalUrl = yield this.getOnRampTransactionUrl(Object.assign({ purchaseId: onRampPurchase.id, providerKey: onRampPurchase.providerKey }, walletParams));
|
|
2404
|
+
if (shouldOpenPopup) {
|
|
2405
|
+
this.platformUtils.openPopup(portalUrl, { type: PopupType.ON_RAMP_TRANSACTION });
|
|
2406
|
+
}
|
|
2407
|
+
return { onRampPurchase, portalUrl };
|
|
2408
|
+
});
|
|
2409
|
+
}
|
|
2410
|
+
/**
|
|
2411
|
+
* Returns true if session was successfully kept alive, false otherwise.
|
|
2412
|
+
**/
|
|
2413
|
+
keepSessionAlive() {
|
|
2414
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2415
|
+
try {
|
|
2416
|
+
yield this.ctx.client.keepSessionAlive(this.userId);
|
|
2417
|
+
return true;
|
|
2418
|
+
}
|
|
2419
|
+
catch (err) {
|
|
2420
|
+
return false;
|
|
2421
|
+
}
|
|
2422
|
+
});
|
|
2423
|
+
}
|
|
2424
|
+
exportSession() {
|
|
2425
|
+
const sessionInfo = {
|
|
2426
|
+
email: this.email,
|
|
2427
|
+
userId: this.userId,
|
|
2428
|
+
wallets: this.wallets,
|
|
2429
|
+
currentWalletIds: this.currentWalletIds,
|
|
2430
|
+
sessionCookie: this.sessionCookie,
|
|
2431
|
+
phone: this.phone,
|
|
2432
|
+
countryCode: this.countryCode,
|
|
2433
|
+
};
|
|
2434
|
+
return Buffer.from(JSON.stringify(sessionInfo)).toString('base64');
|
|
2435
|
+
}
|
|
2436
|
+
importSession(serializedInstanceBase64) {
|
|
2437
|
+
var _a;
|
|
2438
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2439
|
+
const serializedInstance = Buffer.from(serializedInstanceBase64, 'base64').toString('utf8');
|
|
2440
|
+
const sessionInfo = JSON.parse(serializedInstance);
|
|
2441
|
+
yield this.setEmail(sessionInfo.email);
|
|
2442
|
+
yield this.setUserId(sessionInfo.userId);
|
|
2443
|
+
yield this.setWallets(sessionInfo.wallets);
|
|
2444
|
+
for (const walletId of Object.keys(this.wallets)) {
|
|
2445
|
+
if (!this.wallets[walletId].userId) {
|
|
2446
|
+
this.wallets[walletId].userId = this.userId;
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2449
|
+
if (Object.keys(sessionInfo.currentWalletIds).length !== 0) {
|
|
2450
|
+
yield this.setCurrentWalletIds(sessionInfo.currentWalletIds);
|
|
2451
|
+
}
|
|
2452
|
+
else {
|
|
2453
|
+
const currentWalletIds = {};
|
|
2454
|
+
for (const walletId of Object.keys(sessionInfo.wallets)) {
|
|
2455
|
+
currentWalletIds[sessionInfo.wallets[walletId].type] = [
|
|
2456
|
+
...((_a = currentWalletIds[sessionInfo.wallets[walletId].type]) !== null && _a !== void 0 ? _a : []),
|
|
2457
|
+
walletId,
|
|
2458
|
+
];
|
|
2459
|
+
}
|
|
2460
|
+
yield this.setCurrentWalletIds(currentWalletIds);
|
|
2461
|
+
}
|
|
2462
|
+
this.persistSessionCookie(sessionInfo.sessionCookie);
|
|
2463
|
+
yield this.setPhoneNumber(sessionInfo.phone, sessionInfo.countryCode);
|
|
2464
|
+
});
|
|
2465
|
+
}
|
|
2466
|
+
exitAccountCreation() {
|
|
2467
|
+
this.isAwaitingAccountCreation = false;
|
|
2468
|
+
}
|
|
2469
|
+
exitLogin() {
|
|
2470
|
+
this.isAwaitingLogin = false;
|
|
2471
|
+
}
|
|
2472
|
+
exitFarcaster() {
|
|
2473
|
+
this.isAwaitingFarcaster = false;
|
|
2474
|
+
}
|
|
2475
|
+
exitOAuth() {
|
|
2476
|
+
this.isAwaitingOAuth = false;
|
|
2477
|
+
}
|
|
2478
|
+
exitLoops() {
|
|
2479
|
+
this.exitAccountCreation();
|
|
2480
|
+
this.exitLogin();
|
|
2481
|
+
this.exitFarcaster();
|
|
2482
|
+
this.exitOAuth();
|
|
2483
|
+
}
|
|
2484
|
+
/**
|
|
2485
|
+
* Logs the user out.
|
|
2486
|
+
*
|
|
2487
|
+
* @param preservePregenWallets - preserves the stored pregen wallets in memory after the logout.
|
|
2488
|
+
**/
|
|
2489
|
+
logout({ clearPregenWallets = false } = {}) {
|
|
2490
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2491
|
+
yield this.ctx.client.logout();
|
|
2492
|
+
yield this.clearStorage();
|
|
2493
|
+
if (!clearPregenWallets) {
|
|
2494
|
+
Object.entries(this.wallets).forEach(([id, wallet]) => {
|
|
2495
|
+
if (!wallet.pregenIdentifier) {
|
|
2496
|
+
delete this.wallets[id];
|
|
2497
|
+
}
|
|
2498
|
+
});
|
|
2499
|
+
yield this.setWallets(this.wallets);
|
|
2500
|
+
}
|
|
2501
|
+
else {
|
|
2502
|
+
this.wallets = {};
|
|
2503
|
+
}
|
|
2504
|
+
this.currentWalletIds = {};
|
|
2505
|
+
this.currentExternalWalletAddresses = undefined;
|
|
2506
|
+
this.externalWallets = {};
|
|
2507
|
+
this.loginEncryptionKeyPair = undefined;
|
|
2508
|
+
this.email = undefined;
|
|
2509
|
+
this.telegramUserId = undefined;
|
|
2510
|
+
this.phone = undefined;
|
|
2511
|
+
this.countryCode = undefined;
|
|
2512
|
+
this.userId = undefined;
|
|
2513
|
+
this.sessionCookie = undefined;
|
|
2514
|
+
});
|
|
2515
|
+
}
|
|
2516
|
+
getSupportedCreateAuthMethods() {
|
|
2517
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2518
|
+
const res = yield this.touchSession();
|
|
2519
|
+
const partnerId = res.data.partnerId;
|
|
2520
|
+
const partnerRes = yield this.ctx.client.getPartner(partnerId);
|
|
2521
|
+
let supportedAuthMethods = new Set();
|
|
2522
|
+
for (const authMethod of partnerRes.data.partner.supportedAuthMethods) {
|
|
2523
|
+
supportedAuthMethods.add(AuthMethod[authMethod]);
|
|
2524
|
+
}
|
|
2525
|
+
return supportedAuthMethods;
|
|
2526
|
+
});
|
|
2527
|
+
}
|
|
2528
|
+
/**
|
|
2529
|
+
* Converts to a string, removing sensitive data when logging this class.
|
|
2530
|
+
*
|
|
2531
|
+
* Doesn't work for all types of logging.
|
|
2532
|
+
**/
|
|
2533
|
+
toString() {
|
|
2534
|
+
const redactedWallets = Object.keys(this.wallets).reduce((acc, walletId) => (Object.assign(Object.assign({}, acc), { [walletId]: Object.assign(Object.assign({}, this.wallets[walletId]), { signer: this.wallets[walletId].signer ? '[REDACTED]' : undefined }) })), {});
|
|
2535
|
+
const obj = {
|
|
2536
|
+
supportedWalletTypes: this.supportedWalletTypes,
|
|
2537
|
+
cosmosPrefix: this.cosmosPrefix,
|
|
2538
|
+
email: this.email,
|
|
2539
|
+
phone: this.phone,
|
|
2540
|
+
countryCode: this.countryCode,
|
|
2541
|
+
telegramUserId: this.telegramUserId,
|
|
2542
|
+
farcasterUsername: this.farcasterUsername,
|
|
2543
|
+
userId: this.userId,
|
|
2544
|
+
pregenIds: this.pregenIds,
|
|
2545
|
+
currentWalletIds: this.currentWalletIds,
|
|
2546
|
+
wallets: redactedWallets,
|
|
2547
|
+
loginEncryptionKeyPair: this.loginEncryptionKeyPair ? '[REDACTED]' : undefined,
|
|
2548
|
+
ctx: {
|
|
2549
|
+
apiKey: this.ctx.apiKey,
|
|
2550
|
+
disableWorkers: this.ctx.disableWorkers,
|
|
2551
|
+
disableWebSockets: this.ctx.disableWebSockets,
|
|
2552
|
+
env: this.ctx.env,
|
|
2553
|
+
offloadMPCComputationURL: this.ctx.offloadMPCComputationURL,
|
|
2554
|
+
useLocalFiles: this.ctx.useLocalFiles,
|
|
2555
|
+
useDKLS: this.ctx.useDKLS,
|
|
2556
|
+
cosmosPrefix: this.ctx.cosmosPrefix,
|
|
2557
|
+
},
|
|
2558
|
+
};
|
|
2559
|
+
return `Para ${JSON.stringify(obj, null, 2)}`;
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2562
|
+
_ParaCore_supportedWalletTypes = new WeakMap(), _ParaCore_supportedWalletTypesOpt = new WeakMap();
|
|
2563
|
+
ParaCore.version = PARA_CORE_VERSION;
|