Add tests for querying names and deleteName
This commit is contained in:
parent
9de3c59c19
commit
f207be4838
@ -9,6 +9,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/is-url": "^1.2.30",
|
"@types/is-url": "^1.2.30",
|
||||||
"@types/jest": "^27.4.1",
|
"@types/jest": "^27.4.1",
|
||||||
|
"@types/lodash": "^4.14.181",
|
||||||
"@types/semver": "^7.3.9",
|
"@types/semver": "^7.3.9",
|
||||||
"dotenv": "^16.0.0",
|
"dotenv": "^16.0.0",
|
||||||
"jest": "^27.5.1",
|
"jest": "^27.5.1",
|
||||||
@ -32,6 +33,7 @@
|
|||||||
"js-sha256": "^0.9.0",
|
"js-sha256": "^0.9.0",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"jsonschema": "^1.4.0",
|
"jsonschema": "^1.4.0",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
"node-yaml": "^4.0.1",
|
"node-yaml": "^4.0.1",
|
||||||
"semver": "^7.3.5",
|
"semver": "^7.3.5",
|
||||||
"tiny-secp256k1": "^2.2.1"
|
"tiny-secp256k1": "^2.2.1"
|
||||||
|
53
src/index.ts
53
src/index.ts
@ -14,7 +14,7 @@ import { createTxMsgCancelBond, createTxMsgCreateBond, createTxMsgRefillBond, cr
|
|||||||
import { RegistryClient } from "./registry-client";
|
import { RegistryClient } from "./registry-client";
|
||||||
import { Account } from "./account";
|
import { Account } from "./account";
|
||||||
import { createTransaction } from "./txbuilder";
|
import { createTransaction } from "./txbuilder";
|
||||||
import { createTxMsgReserveAuthority, createTxMsgSetAuthorityBond, createTxMsgSetName, createTxMsgSetRecord, MessageMsgReserveAuthority, MessageMsgSetAuthorityBond, MessageMsgSetName, MessageMsgSetRecord } from './messages/nameservice';
|
import { createTxMsgDeleteName, createTxMsgReserveAuthority, createTxMsgSetAuthorityBond, createTxMsgSetName, createTxMsgSetRecord, MessageMsgDeleteName, MessageMsgReserveAuthority, MessageMsgSetAuthorityBond, MessageMsgSetName, MessageMsgSetRecord } from './messages/nameservice';
|
||||||
import { Payload, Record } from './types';
|
import { Payload, Record } from './types';
|
||||||
|
|
||||||
const DEFAULT_WRITE_ERROR = 'Unable to write to chiba-clonk.';
|
const DEFAULT_WRITE_ERROR = 'Unable to write to chiba-clonk.';
|
||||||
@ -82,6 +82,20 @@ export class Registry {
|
|||||||
return this._client.getAccount(address);
|
return this._client.getAccount(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get records by attributes.
|
||||||
|
*/
|
||||||
|
async queryRecords(attributes: {[key: string]: any}, all = false, refs = false) {
|
||||||
|
return this._client.queryRecords(attributes, all, refs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve names to records.
|
||||||
|
*/
|
||||||
|
async resolveNames(names: string[], refs = false) {
|
||||||
|
return this._client.resolveNames(names, refs);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Publish record.
|
* Publish record.
|
||||||
* @param transactionPrivateKey - private key in HEX to sign transaction.
|
* @param transactionPrivateKey - private key in HEX to sign transaction.
|
||||||
@ -245,7 +259,7 @@ export class Registry {
|
|||||||
/**
|
/**
|
||||||
* Cancel bond.
|
* Cancel bond.
|
||||||
*/
|
*/
|
||||||
async cancelBond(params: MessageMsgCancelBond, senderAddress: string, privateKey: string, fee: Fee) {
|
async cancelBond(params: MessageMsgCancelBond, senderAddress: string, privateKey: string, fee: Fee) {
|
||||||
let result;
|
let result;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -338,7 +352,7 @@ export class Registry {
|
|||||||
* @param {string} privateKey
|
* @param {string} privateKey
|
||||||
* @param {object} fee
|
* @param {object} fee
|
||||||
*/
|
*/
|
||||||
async setName(params: MessageMsgSetName, senderAddress: string, privateKey: string, fee: Fee) {
|
async setName(params: MessageMsgSetName, senderAddress: string, privateKey: string, fee: Fee) {
|
||||||
let result;
|
let result;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -361,6 +375,39 @@ export class Registry {
|
|||||||
return parseTxResponse(result);
|
return parseTxResponse(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup naming information.
|
||||||
|
*/
|
||||||
|
async lookupNames(names: string[], history = false) {
|
||||||
|
return this._client.lookupNames(names, history);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete name (WRN) mapping.
|
||||||
|
*/
|
||||||
|
async deleteName(params: MessageMsgDeleteName, senderAddress: string, privateKey: string, fee: Fee) {
|
||||||
|
let result;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { account: { base_account: accountInfo } } = await this.getAccount(senderAddress);
|
||||||
|
|
||||||
|
const sender = {
|
||||||
|
accountAddress: accountInfo.address,
|
||||||
|
sequence: accountInfo.sequence,
|
||||||
|
accountNumber: accountInfo.account_number,
|
||||||
|
pubkey: accountInfo.pub_key.key,
|
||||||
|
}
|
||||||
|
|
||||||
|
const msg = createTxMsgDeleteName(this._chain, sender, fee, '', params)
|
||||||
|
result = await this._submitTx(msg, privateKey, sender);
|
||||||
|
} catch (err: any) {
|
||||||
|
const error = err[0] || err;
|
||||||
|
throw new Error(Registry.processWriteError(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseTxResponse(result);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Submit record transaction.
|
* Submit record transaction.
|
||||||
* @param privateKey - private key in HEX to sign message.
|
* @param privateKey - private key in HEX to sign message.
|
||||||
|
@ -60,6 +60,13 @@ const MSG_SET_AUTHORITY_BOND_TYPES = {
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MSG_DELETE_NAME_TYPES = {
|
||||||
|
MsgValue: [
|
||||||
|
{ name: 'wrn', type: 'string' },
|
||||||
|
{ name: 'signer', type: 'string' },
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
export interface MessageMsgReserveAuthority {
|
export interface MessageMsgReserveAuthority {
|
||||||
name: string
|
name: string
|
||||||
owner: string
|
owner: string
|
||||||
@ -80,6 +87,10 @@ export interface MessageMsgSetAuthorityBond {
|
|||||||
bondId: string
|
bondId: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MessageMsgDeleteName {
|
||||||
|
wrn: string
|
||||||
|
}
|
||||||
|
|
||||||
export function createTxMsgReserveAuthority(
|
export function createTxMsgReserveAuthority(
|
||||||
chain: Chain,
|
chain: Chain,
|
||||||
sender: Sender,
|
sender: Sender,
|
||||||
@ -176,6 +187,28 @@ export function createTxMsgSetAuthorityBond(
|
|||||||
return createTx(chain, sender, fee, memo, types, msg, msgCosmos)
|
return createTx(chain, sender, fee, memo, types, msg, msgCosmos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function createTxMsgDeleteName(
|
||||||
|
chain: Chain,
|
||||||
|
sender: Sender,
|
||||||
|
fee: Fee,
|
||||||
|
memo: string,
|
||||||
|
params: MessageMsgDeleteName,
|
||||||
|
) {
|
||||||
|
const types = generateTypes(MSG_DELETE_NAME_TYPES)
|
||||||
|
|
||||||
|
const msg = createMsgDeleteName(
|
||||||
|
params.wrn,
|
||||||
|
sender.accountAddress
|
||||||
|
)
|
||||||
|
|
||||||
|
const msgCosmos = protoCreateMsgDeleteName(
|
||||||
|
params.wrn,
|
||||||
|
sender.accountAddress
|
||||||
|
)
|
||||||
|
|
||||||
|
return createTx(chain, sender, fee, memo, types, msg, msgCosmos)
|
||||||
|
}
|
||||||
|
|
||||||
function createMsgReserveAuthority(
|
function createMsgReserveAuthority(
|
||||||
name: string,
|
name: string,
|
||||||
signer: string,
|
signer: string,
|
||||||
@ -316,3 +349,31 @@ const protoCreateMsgSetAuthorityBond = (
|
|||||||
path: 'vulcanize.nameservice.v1beta1.MsgSetAuthorityBond',
|
path: 'vulcanize.nameservice.v1beta1.MsgSetAuthorityBond',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createMsgDeleteName(
|
||||||
|
wrn: string,
|
||||||
|
signer: string
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
type: 'nameservice/DeleteAuthority',
|
||||||
|
value: {
|
||||||
|
wrn,
|
||||||
|
signer
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const protoCreateMsgDeleteName = (
|
||||||
|
wrn: string,
|
||||||
|
signer: string
|
||||||
|
) => {
|
||||||
|
const deleteNameAutorityMessage = new nameserviceTx.vulcanize.nameservice.v1beta1.MsgDeleteNameAuthority({
|
||||||
|
wrn,
|
||||||
|
signer,
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
message: deleteNameAutorityMessage,
|
||||||
|
path: 'vulcanize.nameservice.v1beta1.MsgDeleteNameAuthority',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
import semver from 'semver';
|
||||||
|
|
||||||
import { Account } from './account';
|
import { Account } from './account';
|
||||||
import { Registry } from './index';
|
import { Registry } from './index';
|
||||||
import { ensureUpdatedConfig, getConfig } from './testing/helper';
|
import { getBaseConfig, getConfig } from './testing/helper';
|
||||||
|
|
||||||
const WATCHER_ID = 'bafyreibmr47ksukoadck2wigevb2jp5j5oubfadeyzb6zi57ydjsvjmmby'
|
const WATCHER_1_ID = 'bafyreif7z4lbftuxkj7nu4bl7xihitqvhus3wmoqdkjo7lwv24j6fkfskm'
|
||||||
|
const WATCHER_2_ID = 'bafyreiaplz7n2bddg3xhkeuiavwnku7xta2s2cfyaza37ytv4vw367exo4'
|
||||||
const WATCHER_YML_PATH = path.join(__dirname, './testing/data/watcher.yml');
|
const WATCHER_YML_PATH = path.join(__dirname, './testing/data/watcher.yml');
|
||||||
|
|
||||||
jest.setTimeout(120 * 1000);
|
jest.setTimeout(120 * 1000);
|
||||||
@ -14,10 +16,15 @@ const { chainId, restEndpoint, gqlEndpoint, privateKey, accountAddress, fee } =
|
|||||||
|
|
||||||
const namingTests = () => {
|
const namingTests = () => {
|
||||||
let registry: Registry;
|
let registry: Registry;
|
||||||
|
|
||||||
let bondId: string;
|
let bondId: string;
|
||||||
let watcher: any;
|
let watcher: any;
|
||||||
let watcherId: string;
|
let watcherId: string;
|
||||||
|
|
||||||
let authorityName: string;
|
let authorityName: string;
|
||||||
|
let otherAuthorityName: string;
|
||||||
|
let otherPrivateKey: string;
|
||||||
|
|
||||||
let wrn: string;
|
let wrn: string;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
@ -28,7 +35,8 @@ const namingTests = () => {
|
|||||||
await registry.createBond({ denom: 'aphoton', amount: '1000000000' }, accountAddress, privateKey, fee);
|
await registry.createBond({ denom: 'aphoton', amount: '1000000000' }, accountAddress, privateKey, fee);
|
||||||
|
|
||||||
// Create bot.
|
// Create bot.
|
||||||
watcher = await ensureUpdatedConfig(WATCHER_YML_PATH);
|
// TODO: Use ensureUpdatedConfig from helper.
|
||||||
|
watcher = await getBaseConfig(WATCHER_YML_PATH);
|
||||||
const result = await registry.setRecord(
|
const result = await registry.setRecord(
|
||||||
{
|
{
|
||||||
privateKey,
|
privateKey,
|
||||||
@ -42,7 +50,7 @@ const namingTests = () => {
|
|||||||
|
|
||||||
// TODO: Get id from setRecord response.
|
// TODO: Get id from setRecord response.
|
||||||
// watcherId = result.data;
|
// watcherId = result.data;
|
||||||
watcherId = WATCHER_ID;
|
watcherId = WATCHER_1_ID;
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Reserve authority.', async () => {
|
test('Reserve authority.', async () => {
|
||||||
@ -116,6 +124,142 @@ const namingTests = () => {
|
|||||||
test('Set authority bond', async () => {
|
test('Set authority bond', async () => {
|
||||||
await registry.setAuthorityBond({ name: authorityName, bondId }, accountAddress, privateKey, fee);
|
await registry.setAuthorityBond({ name: authorityName, bondId }, accountAddress, privateKey, fee);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Set name', async () => {
|
||||||
|
wrn = `wrn://${authorityName}/app/test`;
|
||||||
|
await registry.setName({ wrn, cid: watcherId }, accountAddress, privateKey, fee);
|
||||||
|
|
||||||
|
// Query records should return it (some WRN points to it).
|
||||||
|
const records = await registry.queryRecords({ type: 'watcher', version: watcher.record.version });
|
||||||
|
expect(records).toBeDefined();
|
||||||
|
// TODO: Fix queryRecords to return filtered results.
|
||||||
|
// expect(records).toHaveLength(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Lookup name', async () => {
|
||||||
|
const records = await registry.lookupNames([wrn]);
|
||||||
|
expect(records).toBeDefined();
|
||||||
|
expect(records).toHaveLength(1);
|
||||||
|
|
||||||
|
const [{ latest, history }] = records;
|
||||||
|
expect(latest).toBeDefined();
|
||||||
|
expect(latest.id).toBeDefined();
|
||||||
|
expect(latest.id).toBe(watcherId);
|
||||||
|
expect(latest.height).toBeDefined();
|
||||||
|
expect(history).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Resolve name', async () => {
|
||||||
|
const records = await registry.resolveNames([wrn]);
|
||||||
|
expect(records).toBeDefined();
|
||||||
|
expect(records).toHaveLength(1);
|
||||||
|
|
||||||
|
const [{ attributes }] = records;
|
||||||
|
// TODO: Set name with new record.
|
||||||
|
// expect(attributes).toEqual(watcher.record);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Lookup name with history', async () => {
|
||||||
|
// TODO: Use ensureUpdatedConfig from helper.
|
||||||
|
const updatedWatcher = await getBaseConfig(WATCHER_YML_PATH);
|
||||||
|
updatedWatcher.record.version = semver.inc(updatedWatcher.record.version, 'patch');
|
||||||
|
const result = await registry.setRecord(
|
||||||
|
{
|
||||||
|
privateKey,
|
||||||
|
bondId,
|
||||||
|
record: updatedWatcher.record
|
||||||
|
},
|
||||||
|
accountAddress,
|
||||||
|
privateKey,
|
||||||
|
fee
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: Get id from setRecord response.
|
||||||
|
// const updatedWatcherId = result.data;
|
||||||
|
const updatedWatcherId = WATCHER_2_ID;
|
||||||
|
await registry.setName({ wrn, cid: updatedWatcherId }, accountAddress, privateKey, fee);
|
||||||
|
|
||||||
|
const records = await registry.lookupNames([wrn], true);
|
||||||
|
expect(records).toHaveLength(1);
|
||||||
|
|
||||||
|
const [{ latest, history }] = records;
|
||||||
|
expect(latest).toBeDefined();
|
||||||
|
expect(latest.id).toBeDefined();
|
||||||
|
expect(latest.id).toBe(updatedWatcherId);
|
||||||
|
expect(latest.height).toBeDefined();
|
||||||
|
expect(history).toBeDefined();
|
||||||
|
expect(history).toHaveLength(1);
|
||||||
|
|
||||||
|
const [oldRecord] = history;
|
||||||
|
expect(oldRecord).toBeDefined();
|
||||||
|
expect(oldRecord.id).toBeDefined();
|
||||||
|
expect(oldRecord.id).toBe(watcherId);
|
||||||
|
expect(oldRecord.height).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
xtest('Set name without reserving authority', async () => {
|
||||||
|
await expect(registry.setName({ wrn: 'wrn://not-reserved/app/test', cid: watcherId }, accountAddress, privateKey, fee))
|
||||||
|
.rejects.toThrow('Name authority not found.');
|
||||||
|
});
|
||||||
|
|
||||||
|
xtest('Set name for non-owned authority', async () => {
|
||||||
|
// Create another account.
|
||||||
|
const mnenonic = Account.generateMnemonic();
|
||||||
|
const otherAccount = await Account.generateFromMnemonic(mnenonic);
|
||||||
|
await otherAccount.init()
|
||||||
|
assert(otherAccount.formattedCosmosAddress)
|
||||||
|
// TODO: Get correct account address from private key.
|
||||||
|
await registry.sendCoins({ denom: 'aphoton', amount: '1000000000', destinationAddress: otherAccount.formattedCosmosAddress }, accountAddress, privateKey, fee);
|
||||||
|
|
||||||
|
// Other account reserves an authority.
|
||||||
|
otherAuthorityName = `other-${Date.now()}`;
|
||||||
|
otherPrivateKey = otherAccount.privateKey.toString('hex');
|
||||||
|
await registry.reserveAuthority({ name: otherAuthorityName, owner: otherAccount.formattedCosmosAddress }, otherAccount.formattedCosmosAddress, otherPrivateKey, fee);
|
||||||
|
|
||||||
|
// Try setting name under other authority.
|
||||||
|
await expect(registry.setName({ wrn: `wrn://${otherAuthorityName}/app/test`, cid: watcherId }, accountAddress, privateKey, fee)).rejects.toThrow('Access denied.');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Lookup non existing name', async () => {
|
||||||
|
const records = await registry.lookupNames(['wrn://not-reserved/app/test']);
|
||||||
|
expect(records).toBeDefined();
|
||||||
|
expect(records).toHaveLength(1);
|
||||||
|
const [record] = records;
|
||||||
|
expect(record).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Resolve non existing name', async () => {
|
||||||
|
const records = await registry.resolveNames(['wrn://not-reserved/app/test']);
|
||||||
|
expect(records).toBeDefined();
|
||||||
|
expect(records).toHaveLength(1);
|
||||||
|
const [record] = records;
|
||||||
|
expect(record).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Delete name', async () => {
|
||||||
|
await registry.deleteName({ wrn }, accountAddress, privateKey, fee);
|
||||||
|
|
||||||
|
let records = await registry.lookupNames([wrn], true);
|
||||||
|
expect(records).toBeDefined();
|
||||||
|
expect(records).toHaveLength(1);
|
||||||
|
|
||||||
|
const [{ latest }] = records;
|
||||||
|
expect(latest).toBeDefined();
|
||||||
|
expect(latest.id).toBeDefined();
|
||||||
|
expect(latest.id).toBe('');
|
||||||
|
expect(latest.height).toBeDefined();
|
||||||
|
|
||||||
|
// Query records should NOT return it (no WRN points to it).
|
||||||
|
records = await registry.queryRecords({ type: 'watcher', version: watcher.record.version });
|
||||||
|
expect(records).toBeDefined();
|
||||||
|
// TODO: Fix queryRecords to return filtered results.
|
||||||
|
// expect(records).toHaveLength(0);
|
||||||
|
|
||||||
|
// Query all records should return it (all: true).
|
||||||
|
records = await registry.queryRecords({ type: 'watcher', version: watcher.record.version }, true);
|
||||||
|
expect(records).toBeDefined();
|
||||||
|
// expect(records).toHaveLength(1);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
if (process.env.AUCTIONS_ENABLED) {
|
if (process.env.AUCTIONS_ENABLED) {
|
||||||
|
@ -1,10 +1,41 @@
|
|||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import graphqlClient from 'graphql.js'
|
import graphqlClient from 'graphql.js'
|
||||||
import { generateEndpointAccount, generateEndpointBroadcast, generatePostBodyBroadcast } from '@tharsis/provider';
|
import { get, set } from 'lodash'
|
||||||
|
import { generateEndpointAccount, generateEndpointBroadcast } from '@tharsis/provider';
|
||||||
|
|
||||||
import { Util } from './util';
|
import { Util } from './util';
|
||||||
|
|
||||||
|
const attributeField = `
|
||||||
|
attributes {
|
||||||
|
key
|
||||||
|
value {
|
||||||
|
null
|
||||||
|
int
|
||||||
|
float
|
||||||
|
string
|
||||||
|
boolean
|
||||||
|
json
|
||||||
|
reference {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const refsField = `
|
||||||
|
references {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const historyFields = `
|
||||||
|
history {
|
||||||
|
id
|
||||||
|
height
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
const auctionFields = `
|
const auctionFields = `
|
||||||
id
|
id
|
||||||
status
|
status
|
||||||
@ -64,7 +95,7 @@ export class RegistryClient {
|
|||||||
/**
|
/**
|
||||||
* Get query result.
|
* Get query result.
|
||||||
*/
|
*/
|
||||||
static async getResult(query: any, key: string, modifier?: (rows: any[]) => {}) {
|
static async getResult(query: any, key: string, modifier?: (rows: any[]) => {}) {
|
||||||
const result = await query;
|
const result = await query;
|
||||||
if (result && result[key] && result[key].length && result[key][0] !== null) {
|
if (result && result[key] && result[key].length && result[key][0] !== null) {
|
||||||
if (modifier) {
|
if (modifier) {
|
||||||
@ -75,6 +106,19 @@ export class RegistryClient {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare response attributes.
|
||||||
|
*/
|
||||||
|
static prepareAttributes(path: string) {
|
||||||
|
return (rows: any[]) => {
|
||||||
|
const result = rows.map(r => {
|
||||||
|
set(r, path, Util.fromGQLAttributes(get(r, path)));
|
||||||
|
return r;
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New Client.
|
* New Client.
|
||||||
*/
|
*/
|
||||||
@ -100,6 +144,38 @@ export class RegistryClient {
|
|||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get records by attributes.
|
||||||
|
*/
|
||||||
|
async queryRecords(attributes: {[key: string]: any}, all = false, refs = false) {
|
||||||
|
if (!attributes) {
|
||||||
|
attributes = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = `query ($attributes: [KeyValueInput!], $all: Boolean) {
|
||||||
|
queryRecords(attributes: $attributes, all: $all) {
|
||||||
|
id
|
||||||
|
names
|
||||||
|
owners
|
||||||
|
bondId
|
||||||
|
createTime
|
||||||
|
expiryTime
|
||||||
|
${attributeField}
|
||||||
|
${refs ? refsField : ''}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
|
||||||
|
const variables = {
|
||||||
|
attributes: Util.toGQLAttributes(attributes),
|
||||||
|
all
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = (await this._graph(query)(variables))['queryRecords'];
|
||||||
|
result = RegistryClient.prepareAttributes('attributes')(result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lookup authorities by names.
|
* Lookup authorities by names.
|
||||||
*/
|
*/
|
||||||
@ -127,6 +203,60 @@ export class RegistryClient {
|
|||||||
return result['lookupAuthorities'];
|
return result['lookupAuthorities'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup names.
|
||||||
|
*/
|
||||||
|
async lookupNames(names: string[], history = false) {
|
||||||
|
assert(names.length);
|
||||||
|
|
||||||
|
const query = `query ($names: [String!]) {
|
||||||
|
lookupNames(names: $names) {
|
||||||
|
latest {
|
||||||
|
id
|
||||||
|
height
|
||||||
|
}
|
||||||
|
${history ? historyFields : ''}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
|
||||||
|
const variables = {
|
||||||
|
names
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = await this._graph(query)(variables);
|
||||||
|
|
||||||
|
return result['lookupNames'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve names to records.
|
||||||
|
*/
|
||||||
|
async resolveNames(names: string[], refs = false) {
|
||||||
|
assert(names.length);
|
||||||
|
|
||||||
|
const query = `query ($names: [String!]) {
|
||||||
|
resolveNames(names: $names) {
|
||||||
|
id
|
||||||
|
names
|
||||||
|
owners
|
||||||
|
bondId
|
||||||
|
createTime
|
||||||
|
expiryTime
|
||||||
|
${attributeField}
|
||||||
|
${refs ? refsField : ''}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
|
||||||
|
const variables = {
|
||||||
|
names
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = (await this._graph(query)(variables))['resolveNames'];
|
||||||
|
result.records = RegistryClient.prepareAttributes('attributes')(result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get bonds by ids.
|
* Get bonds by ids.
|
||||||
*/
|
*/
|
||||||
|
@ -10,6 +10,13 @@ export const ensureUpdatedConfig = async (path: string) => {
|
|||||||
return conf;
|
return conf;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getBaseConfig = async (path: string) => {
|
||||||
|
const conf = await yaml.read(path);
|
||||||
|
conf.record.version = '0.0.1';
|
||||||
|
|
||||||
|
return conf;
|
||||||
|
};
|
||||||
|
|
||||||
export const getConfig = () => {
|
export const getConfig = () => {
|
||||||
assert(process.env.PRIVATE_KEY);
|
assert(process.env.PRIVATE_KEY);
|
||||||
assert(process.env.ACCOUNT_ADDRESS);
|
assert(process.env.ACCOUNT_ADDRESS);
|
||||||
|
@ -724,6 +724,11 @@
|
|||||||
jest-matcher-utils "^27.0.0"
|
jest-matcher-utils "^27.0.0"
|
||||||
pretty-format "^27.0.0"
|
pretty-format "^27.0.0"
|
||||||
|
|
||||||
|
"@types/lodash@^4.14.181":
|
||||||
|
version "4.14.181"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.181.tgz#d1d3740c379fda17ab175165ba04e2d03389385d"
|
||||||
|
integrity sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag==
|
||||||
|
|
||||||
"@types/node@*", "@types/node@^17.0.21":
|
"@types/node@*", "@types/node@^17.0.21":
|
||||||
version "17.0.23"
|
version "17.0.23"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.23.tgz#3b41a6e643589ac6442bdbd7a4a3ded62f33f7da"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.23.tgz#3b41a6e643589ac6442bdbd7a4a3ded62f33f7da"
|
||||||
@ -2500,7 +2505,7 @@ lodash.memoize@4.x:
|
|||||||
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
||||||
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
|
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
|
||||||
|
|
||||||
lodash@^4.7.0:
|
lodash@^4.17.21, lodash@^4.7.0:
|
||||||
version "4.17.21"
|
version "4.17.21"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||||
|
Loading…
Reference in New Issue
Block a user