Skip to content

Commit f31c508

Browse files
authored
Merge pull request #97 from cruxprotocol/feature/shift-to-infunction-init-calls
Init call transferred to constructor as a promise
2 parents cba68a4 + eae31e8 commit f31c508

File tree

5 files changed

+638
-612
lines changed

5 files changed

+638
-612
lines changed

README.md

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ To initialize the sdk, you need to minimally pass a javascript object with follo
2929

3030
`**Note:** Cruxprotocol JS SDK is case insensetive for cryptocurrency symbols and will always output lowercase symbols.`
3131

32-
Example below shows how to a cruxClient instance. Note that all [SDK Operation](#sdk-operation) can oly be run after `.init()` is called.
32+
Example below shows how to a cruxClient instance. These are the [SDK Operation](#sdk-operation) exposed.
3333
```javascript
3434
import crypto from "crypto";
3535

@@ -45,12 +45,6 @@ let cruxClientOptions = {
4545
}
4646

4747
let cruxClient = new CruxClient(cruxClientOptions);
48-
cruxClient.init()
49-
.then(() => {
50-
console.log('CruxClient initialized');
51-
}).catch((err) => {
52-
console.log('CruxClient error', err);
53-
})
5448
```
5549
That's it! now you can use the cruxClient object to perform operations defined in [SDK Operation](#sdk-operation).
5650
```javascript
@@ -64,7 +58,6 @@ Wallet clients are encouraged to surface the respective `ERROR_CODE` of the `Cru
6458
Refer [error-handling.md](https://github.com/cruxprotocol/js-sdk/blob/master/error-handling.md) for more information on Error handling.
6559

6660

67-
6861
### SDK Operation
6962

7063
1. ##### isCruxIDAvailable(cruxID<onlySubdomain>)
@@ -76,7 +69,7 @@ Refer [error-handling.md](https://github.com/cruxprotocol/js-sdk/blob/master/err
7669
2. ##### getAssetMap()
7770
- Description: Get Wallet's asset map with currency symbols as the keys and asset object as the value.
7871
- Params: None
79-
- Returns: [IResolvedClientAssetMapping](#iresolvedclientassetmapping) which has symbols and asset objects.
72+
- Returns: Promise resolving to [IResolvedClientAssetMapping](#iresolvedclientassetmapping) which has symbols and asset objects.
8073

8174
3. ##### registerCruxID(cruxID<onlySubdomain>)
8275
- Description: Reserves/registers the cruxID for the user. The user can link any blockchain address to his CruxID immediately after registration using [putAddressMap](#putaddressmap).
@@ -315,4 +308,4 @@ Running the above command will build a [demo page](https://localhost:1234), here
315308

316309
### How can I contribute?
317310

318-
See [CONTRIBUTING.md](CONTRIBUTING.md) file.
311+
See [CONTRIBUTING.md](CONTRIBUTING.md) file.

src/index.ts

Lines changed: 133 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ export class CruxClient {
165165
protected _nameService?: nameService.NameService;
166166
protected _payIDClaim?: PayIDClaim;
167167
protected _configService?: configurationService.ConfigurationService;
168+
private initPromise: Promise<void>;
168169

169170
constructor(options: ICruxPayPeerOptions) {
170171
this._options = Object.assign({}, options);
@@ -184,46 +185,13 @@ export class CruxClient {
184185
cacheStorage = this._storage;
185186

186187
log.info(`Config mode:`, config.CONFIG_MODE);
187-
log.info(`CruxPayPeer Initialised`);
188+
log.info(`CruxPayClient: constructor called`);
189+
this.initPromise = this._init();
188190
}
189191

190192
public init = async (): Promise<void> => {
191-
await this._setupConfigService();
192-
if (!this._configService) {
193-
throw errors.ErrorHelper.getPackageError(errors.PackageErrorCode.ClientNotInitialized);
194-
}
195-
if (await this._hasPayIDClaimStored()) {
196-
log.debug("using the stored payIDClaim");
197-
const payIDClaim = (await this._storage.getJSON("payIDClaim") as ICruxPayClaim);
198-
// log.debug(`Local payIDClaim:`, payIDClaim)
199-
200-
// if a keyPair is provided, add a validation check on the cruxID stored
201-
if (this._keyPair) {
202-
const registeredCruxID = await getCruxIDByAddress(this.walletClientName, this._keyPair.address, this._configService.getBnsNodes(), this._configService.getSubdomainRegistrar());
203-
if (registeredCruxID) {
204-
CruxClient.validateCruxIDByWallet(this.walletClientName, registeredCruxID);
205-
if (registeredCruxID !== payIDClaim.virtualAddress) {
206-
throw errors.ErrorHelper.getPackageError(errors.PackageErrorCode.KeyPairMismatch);
207-
}
208-
} else {
209-
throw errors.ErrorHelper.getPackageError(errors.PackageErrorCode.KeyPairMismatch);
210-
}
211-
}
212-
this._setPayIDClaim(new PayIDClaim(payIDClaim, { getEncryptionKey: this._getEncryptionKey }));
213-
} else if (this._keyPair) {
214-
log.debug("using the keyPair provided");
215-
const registeredCruxID = await getCruxIDByAddress(this.walletClientName, this._keyPair.address, this._configService.getBnsNodes(), this._configService.getSubdomainRegistrar());
216-
if (registeredCruxID) {
217-
CruxClient.validateCruxIDByWallet(this.walletClientName, registeredCruxID);
218-
const payIDClaim = {identitySecrets: {identityKeyPair: this._keyPair}, virtualAddress: registeredCruxID || undefined};
219-
this._setPayIDClaim(new PayIDClaim(payIDClaim, { getEncryptionKey: this._getEncryptionKey }));
220-
}
221-
}
222-
223-
await this._initializeNameService().then(() => this._restoreIdentity());
224-
225-
log.info(`CruxPayPeer: Done init`);
226-
}
193+
return await this.initPromise;
194+
} // For backward compatibility
227195

228196
public hasPayIDClaim = (): boolean => {
229197
return Boolean(this._payIDClaim);
@@ -234,6 +202,7 @@ export class CruxClient {
234202
}
235203

236204
public updatePassword = async (oldEncryptionKey: string, newEncryptionKey: string): Promise<boolean> => {
205+
await this.initPromise;
237206
try {
238207
if (await this._hasPayIDClaimStored()) {
239208
await (this._payIDClaim as PayIDClaim).decrypt(oldEncryptionKey);
@@ -253,41 +222,44 @@ export class CruxClient {
253222
}
254223
}
255224

256-
public isCruxIDAvailable = (cruxIDSubdomain: string): Promise<boolean> => {
225+
public isCruxIDAvailable = async (cruxIDSubdomain: string): Promise<boolean> => {
226+
await this.initPromise;
257227
try {
258-
identityUtils.validateSubdomain(cruxIDSubdomain);
259-
return (this._nameService as nameService.NameService).getNameAvailability(cruxIDSubdomain);
260-
} catch (err) {
261-
throw errors.CruxClientError.fromError(err);
262-
}
228+
identityUtils.validateSubdomain(cruxIDSubdomain);
229+
return (this._nameService as nameService.NameService).getNameAvailability(cruxIDSubdomain);
230+
} catch (err) {
231+
throw errors.CruxClientError.fromError(err);
232+
}
263233
}
264234

265235
public resolveCurrencyAddressForCruxID = async (fullCruxID: string, walletCurrencySymbol: string): Promise<IAddress> => {
236+
await this.initPromise;
266237
try {
267-
if (!(this._configService && this._nameService)) {
268-
throw errors.ErrorHelper.getPackageError(errors.PackageErrorCode.ClientNotInitialized);
269-
}
270-
walletCurrencySymbol = walletCurrencySymbol.toLowerCase();
271-
let correspondingAssetId: string = "";
272-
correspondingAssetId = await this._translateSymbolToAssetId(walletCurrencySymbol);
273-
if (!correspondingAssetId) {
274-
throw errors.ErrorHelper.getPackageError(errors.PackageErrorCode.AssetIDNotAvailable);
275-
}
238+
if (!(this._configService && this._nameService)) {
239+
throw errors.ErrorHelper.getPackageError(errors.PackageErrorCode.ClientNotInitialized);
240+
}
241+
walletCurrencySymbol = walletCurrencySymbol.toLowerCase();
242+
let correspondingAssetId: string = "";
243+
correspondingAssetId = await this._translateSymbolToAssetId(walletCurrencySymbol);
244+
if (!correspondingAssetId) {
245+
throw errors.ErrorHelper.getPackageError(errors.PackageErrorCode.AssetIDNotAvailable);
246+
}
276247

277-
const addressMap = await this._nameService.getAddressMapping(fullCruxID);
278-
log.debug(`Address map: `, addressMap);
279-
if (!addressMap[correspondingAssetId]) {
280-
throw errors.ErrorHelper.getPackageError(errors.PackageErrorCode.AddressNotAvailable);
248+
const addressMap = await this._nameService.getAddressMapping(fullCruxID);
249+
log.debug(`Address map: `, addressMap);
250+
if (!addressMap[correspondingAssetId]) {
251+
throw errors.ErrorHelper.getPackageError(errors.PackageErrorCode.AddressNotAvailable);
252+
}
253+
const address: IAddress = addressMap[correspondingAssetId] || addressMap[correspondingAssetId.toLowerCase()];
254+
log.debug(`Address:`, address);
255+
return address;
256+
} catch (err) {
257+
throw errors.CruxClientError.fromError(err);
281258
}
282-
const address: IAddress = addressMap[correspondingAssetId] || addressMap[correspondingAssetId.toLowerCase()];
283-
log.debug(`Address:`, address);
284-
return address;
285-
} catch (err) {
286-
throw errors.CruxClientError.fromError(err);
287-
}
288259
}
289260

290261
public getCruxIDState = async (): Promise<ICruxIDState> => {
262+
await this.initPromise;
291263
try {
292264
const fullCruxID = this.hasPayIDClaim() ? this.getPayIDClaim().virtualAddress : undefined;
293265
if (!fullCruxID) {
@@ -311,90 +283,90 @@ export class CruxClient {
311283

312284
public registerCruxID = async (cruxIDSubdomain: string): Promise<void> => {
313285
// TODO: add isCruxIDAvailable check before
286+
await this.initPromise;
314287
try {
315-
// Subdomain validation
316-
identityUtils.validateSubdomain(cruxIDSubdomain);
288+
// Subdomain validation
289+
identityUtils.validateSubdomain(cruxIDSubdomain);
317290

318-
// Validate if the subdomain is available
319-
if (!(await this.isCruxIDAvailable(cruxIDSubdomain))) {
320-
throw errors.ErrorHelper.getPackageError(errors.PackageErrorCode.CruxIDUnavailable, cruxIDSubdomain);
321-
}
291+
// Validate if the subdomain is available
292+
if (!(await this.isCruxIDAvailable(cruxIDSubdomain))) {
293+
throw errors.ErrorHelper.getPackageError(errors.PackageErrorCode.CruxIDUnavailable, cruxIDSubdomain);
294+
}
322295

323-
// Generating the identityClaim
324-
if (this._payIDClaim) {
325-
if (this._payIDClaim.virtualAddress) {
326-
// Do not allow multiple registrations using same payIDClaim
327-
throw errors.ErrorHelper.getPackageError(errors.PackageErrorCode.ExistingCruxIDFound, this._payIDClaim.virtualAddress);
296+
// Generating the identityClaim
297+
if (this._payIDClaim) {
298+
if (this._payIDClaim.virtualAddress) {
299+
// Do not allow multiple registrations using same payIDClaim
300+
throw errors.ErrorHelper.getPackageError(errors.PackageErrorCode.ExistingCruxIDFound, this._payIDClaim.virtualAddress);
301+
}
302+
await (this._payIDClaim as PayIDClaim).decrypt();
328303
}
329-
await (this._payIDClaim as PayIDClaim).decrypt();
330-
}
331304

332-
let identityClaim: nameService.IIdentityClaim;
333-
if (this._payIDClaim) {
334-
identityClaim = {secrets: this._payIDClaim.identitySecrets};
335-
} else if (this._keyPair) {
336-
identityClaim = {secrets: {identityKeyPair: this._keyPair}};
337-
} else {
338-
identityClaim = await (this._nameService as nameService.NameService).generateIdentity(this._storage, await this._getEncryptionKey());
339-
}
305+
let identityClaim: nameService.IIdentityClaim;
306+
if (this._payIDClaim) {
307+
identityClaim = {secrets: this._payIDClaim.identitySecrets};
308+
} else if (this._keyPair) {
309+
identityClaim = {secrets: {identityKeyPair: this._keyPair}};
310+
} else {
311+
identityClaim = await (this._nameService as nameService.NameService).generateIdentity(this._storage, await this._getEncryptionKey());
312+
}
340313

341-
const registeredPublicID = await (this._nameService as nameService.NameService).registerName(identityClaim, cruxIDSubdomain);
314+
const registeredPublicID = await (this._nameService as nameService.NameService).registerName(identityClaim, cruxIDSubdomain);
342315

343-
// Setup the payIDClaim locally
344-
this._setPayIDClaim(new PayIDClaim({virtualAddress: registeredPublicID, identitySecrets: identityClaim.secrets}, { getEncryptionKey: this._getEncryptionKey }));
345-
// await this._payIDClaim.setPasscode(passcode)
346-
await (this._payIDClaim as PayIDClaim).encrypt();
347-
await (this._payIDClaim as PayIDClaim).save(this._storage);
348-
return;
349-
} catch (err) {
350-
throw errors.CruxClientError.fromError(err);
351-
}
316+
// Setup the payIDClaim locally
317+
this._setPayIDClaim(new PayIDClaim({virtualAddress: registeredPublicID, identitySecrets: identityClaim.secrets}, { getEncryptionKey: this._getEncryptionKey }));
318+
// await this._payIDClaim.setPasscode(passcode)
319+
await (this._payIDClaim as PayIDClaim).encrypt();
320+
await (this._payIDClaim as PayIDClaim).save(this._storage);
321+
return;
322+
} catch (err) {
323+
throw errors.CruxClientError.fromError(err);
324+
}
352325
}
353326

354327
public putAddressMap = async (newAddressMap: IAddressMapping): Promise<{success: IPutAddressMapSuccess, failures: IPutAddressMapFailures}> => {
328+
await this.initPromise;
355329
try {
356-
const {assetAddressMap, success, failures} = await this._getAssetAddressMapFromCurrencyAddressMap(newAddressMap);
357-
await (this._payIDClaim as PayIDClaim).decrypt();
358-
await (this._nameService as nameService.NameService).putAddressMapping({secrets: (this._payIDClaim as PayIDClaim).identitySecrets}, assetAddressMap);
359-
await (this._payIDClaim as PayIDClaim).encrypt();
360-
return {success, failures};
361-
} catch (err) {
362-
throw errors.CruxClientError.fromError(err);
363-
}
330+
const {assetAddressMap, success, failures} = await this._getAssetAddressMapFromCurrencyAddressMap(newAddressMap);
331+
await (this._payIDClaim as PayIDClaim).decrypt();
332+
await (this._nameService as nameService.NameService).putAddressMapping({secrets: (this._payIDClaim as PayIDClaim).identitySecrets}, assetAddressMap);
333+
await (this._payIDClaim as PayIDClaim).encrypt();
334+
return {success, failures};
335+
} catch (err) {
336+
throw errors.CruxClientError.fromError(err);
337+
}
364338
}
365339

366340
public getAddressMap = async (): Promise<IAddressMapping> => {
341+
await this.initPromise;
367342
try {
368-
const currencyAddressMap: IAddressMapping = {};
369-
if (this._payIDClaim && this._payIDClaim.virtualAddress && this._configService) {
370-
const userAssetIdToAddressMap = await (this._nameService as nameService.NameService).getAddressMapping(this._payIDClaim.virtualAddress);
343+
const currencyAddressMap: IAddressMapping = {};
344+
if (this._payIDClaim && this._payIDClaim.virtualAddress && this._configService) {
345+
const userAssetIdToAddressMap = await (this._nameService as nameService.NameService).getAddressMapping(this._payIDClaim.virtualAddress);
371346

372-
for (const assetId of Object.keys(userAssetIdToAddressMap)) {
373-
currencyAddressMap[(await (this._translateAssetIdToSymbol(assetId)))] = userAssetIdToAddressMap[assetId];
347+
for (const assetId of Object.keys(userAssetIdToAddressMap)) {
348+
currencyAddressMap[(await (this._translateAssetIdToSymbol(assetId)))] = userAssetIdToAddressMap[assetId];
349+
}
350+
return currencyAddressMap;
351+
} else {
352+
return {};
374353
}
375-
return currencyAddressMap;
376-
377-
} else {
378-
return {};
379-
}
380-
} catch (err) {
381-
if (err.errorCode && err.errorCode === errors.PackageErrorCode.GaiaEmptyResponse) {
382-
return {};
354+
} catch (err) {
355+
if (err.errorCode && err.errorCode === errors.PackageErrorCode.GaiaEmptyResponse) {
356+
return {};
357+
}
358+
throw errors.CruxClientError.fromError(err);
383359
}
384-
throw errors.CruxClientError.fromError(err);
385-
}
386360
}
387361

388-
public getAssetMap = (): configurationService.IResolvedClientAssetMap => {
362+
public getAssetMap = async (): Promise<configurationService.IResolvedClientAssetMap> => {
363+
await this.initPromise;
389364
try {
390-
if (this._configService) {
365+
// @ts-ignore
391366
return this._configService.resolvedClientAssetMap as configurationService.IResolvedClientAssetMap;
392-
} else {
393-
throw errors.ErrorHelper.getPackageError(errors.PackageErrorCode.ClientNotInitialized);
367+
} catch (err) {
368+
throw errors.CruxClientError.fromError(err);
394369
}
395-
} catch (err) {
396-
throw errors.CruxClientError.fromError(err);
397-
}
398370
}
399371

400372
public getAssetMapping = () => this.getAssetMap; // For backward compatibility
@@ -404,6 +376,44 @@ export class CruxClient {
404376
delete this._keyPair;
405377
}
406378

379+
private _init = async (): Promise<void> => {
380+
await this._setupConfigService();
381+
if (!this._configService) {
382+
throw errors.ErrorHelper.getPackageError(errors.PackageErrorCode.ClientNotInitialized);
383+
}
384+
if (await this._hasPayIDClaimStored()) {
385+
log.debug("using the stored payIDClaim");
386+
const payIDClaim = (await this._storage.getJSON("payIDClaim") as ICruxPayClaim);
387+
// log.debug(`Local payIDClaim:`, payIDClaim)
388+
389+
// if a keyPair is provided, add a validation check on the cruxID stored
390+
if (this._keyPair) {
391+
const registeredCruxID = await getCruxIDByAddress(this.walletClientName, this._keyPair.address, this._configService.getBnsNodes(), this._configService.getSubdomainRegistrar());
392+
if (registeredCruxID) {
393+
CruxClient.validateCruxIDByWallet(this.walletClientName, registeredCruxID);
394+
if (registeredCruxID !== payIDClaim.virtualAddress) {
395+
throw errors.ErrorHelper.getPackageError(errors.PackageErrorCode.KeyPairMismatch);
396+
}
397+
} else {
398+
throw errors.ErrorHelper.getPackageError(errors.PackageErrorCode.KeyPairMismatch);
399+
}
400+
}
401+
this._setPayIDClaim(new PayIDClaim(payIDClaim, { getEncryptionKey: this._getEncryptionKey }));
402+
} else if (this._keyPair) {
403+
log.debug("using the keyPair provided");
404+
const registeredCruxID = await getCruxIDByAddress(this.walletClientName, this._keyPair.address, this._configService.getBnsNodes(), this._configService.getSubdomainRegistrar());
405+
if (registeredCruxID) {
406+
CruxClient.validateCruxIDByWallet(this.walletClientName, registeredCruxID);
407+
const payIDClaim = {identitySecrets: {identityKeyPair: this._keyPair}, virtualAddress: registeredCruxID || undefined};
408+
this._setPayIDClaim(new PayIDClaim(payIDClaim, { getEncryptionKey: this._getEncryptionKey }));
409+
}
410+
}
411+
412+
await this._initializeNameService().then(() => this._restoreIdentity());
413+
414+
log.info(`CruxPayClient: _init complete`);
415+
}
416+
407417
private _getIDStatus = async (): Promise<nameService.CruxIDRegistrationStatus> => {
408418
await (this._payIDClaim as PayIDClaim).decrypt();
409419
const result = await (this._nameService as nameService.NameService).getRegistrationStatus({secrets: (this._payIDClaim as PayIDClaim).identitySecrets});

0 commit comments

Comments
 (0)