diff --git a/package.json b/package.json index 1b454b8..8308526 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cerc-io/registry-sdk", - "version": "0.2.5", + "version": "0.2.6", "main": "dist/index.js", "types": "dist/index.d.ts", "repository": "git@github.com:cerc-io/registry-sdk.git", diff --git a/src/index.ts b/src/index.ts index 692ebc5..17047ff 100644 --- a/src/index.ts +++ b/src/index.ts @@ -389,6 +389,13 @@ export class Registry { return this._client.getAuctionsByIds(ids); } + /** + * List authorities by owner. + */ + async getAuthorities (owner?: string, auction = false) { + return this._client.getAuthorities(owner, auction); + } + /** * Lookup authorities by names. */ diff --git a/src/nameservice-expiry.test.ts b/src/nameservice-expiry.test.ts index a8627e7..c19de2a 100644 --- a/src/nameservice-expiry.test.ts +++ b/src/nameservice-expiry.test.ts @@ -60,7 +60,11 @@ const nameserviceExpiryTests = () => { }); test('Wait for expiry duration', (done) => { - setTimeout(done, 60 * 1000); + // Wait for expiry time + time for a block to be executed + const expiryTime = 60 * 1000; + const waitTime = expiryTime + (3 * 1000); + + setTimeout(done, waitTime); }); test('Check record expiry time', async () => { @@ -84,7 +88,11 @@ const nameserviceExpiryTests = () => { }); test('Wait for expiry duration', (done) => { - setTimeout(done, 60 * 1000); + // Wait for expiry time + time for a block to be executed + const expiryTime = 60 * 1000; + const waitTime = expiryTime + (3 * 1000); + + setTimeout(done, waitTime); }); test('Check record deleted without bond balance', async () => { diff --git a/src/naming.test.ts b/src/naming.test.ts index 4c40225..1bac15b 100644 --- a/src/naming.test.ts +++ b/src/naming.test.ts @@ -1,6 +1,8 @@ import assert from 'assert'; import path from 'path'; +import { DirectSecp256k1Wallet, AccountData as CosmosAccount } from '@cosmjs/proto-signing'; + import { Account } from './account'; import { Registry } from './index'; import { ensureUpdatedConfig, getConfig } from './testing/helper'; @@ -19,6 +21,18 @@ const namingTests = () => { let watcher: any; let watcherId: string; + let otherAccount1: Account; + + let reservedAuthorities: { + name: string; + entry: { + ownerAddress: string; + status: string; + }; + }[] = []; + + let account: CosmosAccount; + beforeAll(async () => { registry = new Registry(gqlEndpoint, rpcEndpoint, chainId); @@ -39,12 +53,26 @@ const namingTests = () => { ); watcherId = result.id; + + const accountWallet = await DirectSecp256k1Wallet.fromKey(Buffer.from(privateKey, 'hex'), 'laconic'); + [account] = await accountWallet.getAccounts(); + + const mnenonic1 = Account.generateMnemonic(); + otherAccount1 = await Account.generateFromMnemonic(mnenonic1); + await otherAccount1.init(); }); describe('Authority tests', () => { test('Reserve authority.', async () => { const authorityName = `laconic-${Date.now()}`; await registry.reserveAuthority({ name: authorityName }, privateKey, fee); + reservedAuthorities.push({ + name: authorityName, + entry: { + ownerAddress: account.address, + status: 'active' + } + }); }); describe('With authority reserved', () => { @@ -56,6 +84,13 @@ const namingTests = () => { lrn = `lrn://${authorityName}/app/test`; await registry.reserveAuthority({ name: authorityName }, privateKey, fee); + reservedAuthorities.push({ + name: authorityName, + entry: { + ownerAddress: account.address, + status: 'active' + } + }); }); test('Lookup authority.', async () => { @@ -80,6 +115,13 @@ const namingTests = () => { test('Reserve sub-authority.', async () => { const subAuthority = `echo.${authorityName}`; await registry.reserveAuthority({ name: subAuthority }, privateKey, fee); + reservedAuthorities.push({ + name: subAuthority, + entry: { + ownerAddress: account.address, + status: 'active' + } + }); const [record] = await registry.lookupAuthorities([subAuthority]); expect(record).toBeDefined(); @@ -90,18 +132,22 @@ const namingTests = () => { test('Reserve sub-authority with different owner.', async () => { // Create another account, send tx to set public key on the account. - const mnenonic1 = Account.generateMnemonic(); - const otherAccount1 = await Account.generateFromMnemonic(mnenonic1); - await otherAccount1.init(); - await registry.sendCoins({ denom: DENOM, amount: '1000000000', destinationAddress: otherAccount1.address }, privateKey, fee); - const mnenonic2 = Account.generateMnemonic(); const otherAccount2 = await Account.generateFromMnemonic(mnenonic2); await otherAccount2.init(); + + await registry.sendCoins({ denom: DENOM, amount: '1000000000', destinationAddress: otherAccount1.address }, privateKey, fee); await registry.sendCoins({ denom: DENOM, amount: '1000', destinationAddress: otherAccount2.address }, otherAccount1.getPrivateKey(), fee); const subAuthority = `halo.${authorityName}`; await registry.reserveAuthority({ name: subAuthority, owner: otherAccount1.address }, privateKey, fee); + reservedAuthorities.push({ + name: subAuthority, + entry: { + ownerAddress: otherAccount1.address, + status: 'active' + } + }); const [record] = await registry.lookupAuthorities([subAuthority]); expect(record).toBeDefined(); @@ -120,6 +166,39 @@ const namingTests = () => { test('Set authority bond', async () => { await registry.setAuthorityBond({ name: authorityName, bondId }, privateKey, fee); }); + + test('List authorities.', async () => { + const authorities = await registry.getAuthorities(undefined, true); + reservedAuthorities.sort((a, b) => a.name.localeCompare(b.name)); + const expectedEntryKeys = [ + 'ownerAddress', + 'ownerPublicKey', + 'height', + 'status', + 'bondId', + 'expiryTime', + 'auction' + ]; + + expect(authorities.length).toEqual(4); + expectedEntryKeys.forEach(key => { + authorities.forEach((authority: any) => { + expect(authority).toHaveProperty('name'); + expect(authority.entry).toHaveProperty(key); + }); + }); + authorities.forEach((authority: any, index: number) => { + expect(authority).toMatchObject(reservedAuthorities[index]); + }); + }); + + test('List authorities by owner.', async () => { + const authorities = await registry.getAuthorities(otherAccount1.address); + + expect(authorities.length).toEqual(1); + expect(authorities[0].entry.ownerAddress).toBe(otherAccount1.address); + expect(authorities[0].entry.ownerPublicKey).toBe(otherAccount1.encodedPubkey); + }); }); }); diff --git a/src/onboarding.test.ts b/src/onboarding.test.ts index ca51fd9..25e6f51 100644 --- a/src/onboarding.test.ts +++ b/src/onboarding.test.ts @@ -25,9 +25,8 @@ const onboardingEnabledTests = () => { const mnemonic = Account.generateMnemonic(); ethWallet = Wallet.fromMnemonic(mnemonic); - const account = new Account(Buffer.from(privateKey, 'hex')); - const cosmosAccount = await DirectSecp256k1Wallet.fromKey(account._privateKey, 'laconic'); - [cosmosWallet] = await cosmosAccount.getAccounts(); + const accountWallet = await DirectSecp256k1Wallet.fromKey(Buffer.from(privateKey, 'hex'), 'laconic'); + [cosmosWallet] = await accountWallet.getAccounts(); expectedParticipants = [ { diff --git a/src/registry-client.ts b/src/registry-client.ts index 31d8073..23c7776 100644 --- a/src/registry-client.ts +++ b/src/registry-client.ts @@ -270,6 +270,34 @@ export class RegistryClient { return result; } + /** + * List authorities by owner. + */ + async getAuthorities (owner?: string, auction = false) { + const query = `query ($owner: String) { + getAuthorities(owner: $owner) { + name + entry { + ownerAddress + ownerPublicKey + height + status + bondId + expiryTime + ${auction ? ('auction { ' + auctionFields + ' }') : ''} + } + } + }`; + + const variables = { + owner + }; + + const result = await this._graph(query)(variables); + + return result.getAuthorities; + } + /** * Lookup authorities by names. */