Add nameservice tests for reserve and lookup authority
This commit is contained in:
parent
36b633b908
commit
65e90e7af0
36
src/index.ts
36
src/index.ts
@ -12,6 +12,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, MessageMsgReserveAuthority } from './nameservice';
|
||||||
|
|
||||||
const DEFAULT_WRITE_ERROR = 'Unable to write to chiba-clonk.';
|
const DEFAULT_WRITE_ERROR = 'Unable to write to chiba-clonk.';
|
||||||
|
|
||||||
@ -215,6 +216,39 @@ export class Registry {
|
|||||||
return parseTxResponse(result);
|
return parseTxResponse(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reserve authority.
|
||||||
|
*/
|
||||||
|
async reserveAuthority(params: MessageMsgReserveAuthority, 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 = createTxMsgReserveAuthority(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup authorities by names.
|
||||||
|
*/
|
||||||
|
async lookupAuthorities(names: string[], auction = false) {
|
||||||
|
return this._client.lookupAuthorities(names, auction);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Submit a generic Tx to the chain.
|
* Submit a generic Tx to the chain.
|
||||||
*/
|
*/
|
||||||
@ -237,3 +271,5 @@ export class Registry {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export { Account }
|
||||||
|
118
src/nameservice.ts
Normal file
118
src/nameservice.ts
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
import {
|
||||||
|
createEIP712,
|
||||||
|
generateFee,
|
||||||
|
generateMessage,
|
||||||
|
generateTypes,
|
||||||
|
} from '@tharsis/eip712'
|
||||||
|
import {
|
||||||
|
Chain,
|
||||||
|
Sender,
|
||||||
|
Fee,
|
||||||
|
} from '@tharsis/transactions'
|
||||||
|
import { createTransaction } from '@tharsis/proto'
|
||||||
|
|
||||||
|
import * as nameserviceTx from './proto/vulcanize/nameservice/v1beta1/tx'
|
||||||
|
|
||||||
|
const MSG_RESERVE_AUTHORITY_TYPES = {
|
||||||
|
MsgValue: [
|
||||||
|
{ name: 'name', type: 'string' },
|
||||||
|
{ name: 'signer', type: 'string' },
|
||||||
|
{ name: 'owner', type: 'string' },
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MessageMsgReserveAuthority {
|
||||||
|
name: string
|
||||||
|
owner: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createTxMsgReserveAuthority(
|
||||||
|
chain: Chain,
|
||||||
|
sender: Sender,
|
||||||
|
fee: Fee,
|
||||||
|
memo: string,
|
||||||
|
params: MessageMsgReserveAuthority,
|
||||||
|
) {
|
||||||
|
// EIP712
|
||||||
|
const feeObject = generateFee(
|
||||||
|
fee.amount,
|
||||||
|
fee.denom,
|
||||||
|
fee.gas,
|
||||||
|
sender.accountAddress,
|
||||||
|
)
|
||||||
|
const types = generateTypes(MSG_RESERVE_AUTHORITY_TYPES)
|
||||||
|
|
||||||
|
const msg = createMsgReserveAuthority(
|
||||||
|
params.name,
|
||||||
|
sender.accountAddress,
|
||||||
|
params.owner
|
||||||
|
)
|
||||||
|
|
||||||
|
const messages = generateMessage(
|
||||||
|
sender.accountNumber.toString(),
|
||||||
|
sender.sequence.toString(),
|
||||||
|
chain.cosmosChainId,
|
||||||
|
memo,
|
||||||
|
feeObject,
|
||||||
|
msg,
|
||||||
|
)
|
||||||
|
const eipToSign = createEIP712(types, chain.chainId, messages)
|
||||||
|
|
||||||
|
// Cosmos
|
||||||
|
const msgCosmos = protoCreateMsgReserveAuthority(
|
||||||
|
params.name,
|
||||||
|
sender.accountAddress,
|
||||||
|
params.owner
|
||||||
|
)
|
||||||
|
|
||||||
|
const tx = createTransaction(
|
||||||
|
msgCosmos,
|
||||||
|
memo,
|
||||||
|
fee.amount,
|
||||||
|
fee.denom,
|
||||||
|
parseInt(fee.gas, 10),
|
||||||
|
'ethsecp256',
|
||||||
|
sender.pubkey,
|
||||||
|
sender.sequence,
|
||||||
|
sender.accountNumber,
|
||||||
|
chain.cosmosChainId,
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
signDirect: tx.signDirect,
|
||||||
|
legacyAmino: tx.legacyAmino,
|
||||||
|
eipToSign,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createMsgReserveAuthority(
|
||||||
|
name: string,
|
||||||
|
signer: string,
|
||||||
|
owner: string
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
type: 'nameservice/ReserveAuthority',
|
||||||
|
value: {
|
||||||
|
name,
|
||||||
|
signer,
|
||||||
|
owner
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const protoCreateMsgReserveAuthority = (
|
||||||
|
name: string,
|
||||||
|
signer: string,
|
||||||
|
owner: string,
|
||||||
|
) => {
|
||||||
|
const reserveAuthorityMessage = new nameserviceTx.vulcanize.nameservice.v1beta1.MsgReserveAuthority({
|
||||||
|
name,
|
||||||
|
signer,
|
||||||
|
owner
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
message: reserveAuthorityMessage,
|
||||||
|
path: 'vulcanize.nameservice.v1beta1.MsgReserveAuthority',
|
||||||
|
}
|
||||||
|
}
|
53
src/naming.test.ts
Normal file
53
src/naming.test.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { Registry } from './index';
|
||||||
|
import { getConfig, wait } from './testing/helper';
|
||||||
|
|
||||||
|
jest.setTimeout(120 * 1000);
|
||||||
|
|
||||||
|
const { mockServer, chibaClonk: { chainId, restEndpoint, gqlEndpoint, privateKey, accountAddress, fee } } = getConfig();
|
||||||
|
|
||||||
|
const namingTests = () => {
|
||||||
|
let registry: Registry;
|
||||||
|
|
||||||
|
let bondId: string;
|
||||||
|
|
||||||
|
let authorityName: string;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
registry = new Registry(restEndpoint, gqlEndpoint, chainId);
|
||||||
|
|
||||||
|
// Create bond.
|
||||||
|
bondId = await registry.getNextBondId(accountAddress);
|
||||||
|
await registry.createBond({ denom: 'aphoton', amount: '1000000000' }, accountAddress, privateKey, fee);
|
||||||
|
await wait(5000)
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Reserve authority.', async () => {
|
||||||
|
authorityName = `dxos-${Date.now()}`;
|
||||||
|
await registry.reserveAuthority({ name: authorityName, owner: accountAddress }, accountAddress, privateKey, fee);
|
||||||
|
await wait(5000)
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Lookup authority.', async () => {
|
||||||
|
const [record] = await registry.lookupAuthorities([authorityName]);
|
||||||
|
|
||||||
|
expect(record).toBeDefined();
|
||||||
|
expect(record.ownerAddress).not.toBe('');
|
||||||
|
expect(record.ownerPublicKey).not.toBe('');
|
||||||
|
expect(Number(record.height)).toBeGreaterThan(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Lookup non existing authority', async () => {
|
||||||
|
const [record] = await registry.lookupAuthorities(['does-not-exist']);
|
||||||
|
|
||||||
|
expect(record.ownerAddress).toBe('');
|
||||||
|
expect(record.ownerPublicKey).toBe('');
|
||||||
|
expect(Number(record.height)).toBe(0);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (mockServer || process.env.WIRE_AUCTIONS_ENABLED) {
|
||||||
|
// Required as jest complains if file has no tests.
|
||||||
|
test('skipping naming tests', () => {});
|
||||||
|
} else {
|
||||||
|
describe('Naming', namingTests);
|
||||||
|
}
|
@ -5,6 +5,55 @@ import { generateEndpointAccount, generateEndpointBroadcast, generatePostBodyBro
|
|||||||
|
|
||||||
import { Util } from './util';
|
import { Util } from './util';
|
||||||
|
|
||||||
|
const auctionFields = `
|
||||||
|
id
|
||||||
|
status
|
||||||
|
ownerAddress
|
||||||
|
createTime
|
||||||
|
commitsEndTime
|
||||||
|
revealsEndTime
|
||||||
|
commitFee {
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
revealFee {
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
minimumBid {
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
winnerAddress
|
||||||
|
winnerBid {
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
winnerPrice {
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
bids {
|
||||||
|
bidderAddress
|
||||||
|
status
|
||||||
|
commitHash
|
||||||
|
commitTime
|
||||||
|
revealTime
|
||||||
|
commitFee {
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
revealFee {
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
bidAmount {
|
||||||
|
type
|
||||||
|
quantity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registry
|
* Registry
|
||||||
*/
|
*/
|
||||||
@ -51,6 +100,33 @@ export class RegistryClient {
|
|||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup authorities by names.
|
||||||
|
*/
|
||||||
|
async lookupAuthorities(names: string[], auction = false) {
|
||||||
|
assert(names.length);
|
||||||
|
|
||||||
|
const query = `query ($names: [String!]) {
|
||||||
|
lookupAuthorities(names: $names) {
|
||||||
|
ownerAddress
|
||||||
|
ownerPublicKey
|
||||||
|
height
|
||||||
|
status
|
||||||
|
bondId
|
||||||
|
expiryTime
|
||||||
|
${auction ? ('auction { ' + auctionFields + ' }') : ''}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
|
||||||
|
const variables = {
|
||||||
|
names
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = await this._graph(query)(variables);
|
||||||
|
|
||||||
|
return result['lookupAuthorities'];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get bonds by ids.
|
* Get bonds by ids.
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
const DEFAULT_PRIVATE_KEY = '3d8e23810daecb66ec4ca97805f6bbfc102015c3f22cdda1a783b1d074c43bdd';
|
const DEFAULT_PRIVATE_KEY = '39e06e1471f69a76491e60d1d22908789bf7801039a9ac2197ed432ad45d2daf';
|
||||||
const DEFAULT_ADDRESS = 'ethm1lrdrh056ce23h9d9d5rx34tp0uwj0u9zumynx3'
|
const DEFAULT_ADDRESS = 'ethm1p9fqwtlypqptuqgndpce5g6wncj4py9z30wfkt'
|
||||||
|
|
||||||
export const wait = (time: number) => new Promise(resolve => setTimeout(resolve, time))
|
export const wait = (time: number) => new Promise(resolve => setTimeout(resolve, time))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user