forked from cerc-io/registry-sdk
Add tests for reserving authority with different owner
This commit is contained in:
+45
-1
@@ -1,6 +1,15 @@
|
||||
import assert from 'assert';
|
||||
import BIP32Factory from 'bip32';
|
||||
import * as ecc from 'tiny-secp256k1';
|
||||
import * as bip39 from 'bip39';
|
||||
import { MessageTypes, signTypedData, SignTypedDataVersion } from '@metamask/eth-sig-util';
|
||||
import { Secp256k1 } from "@cosmjs/crypto";
|
||||
import { Ripemd160, Secp256k1 } from "@cosmjs/crypto";
|
||||
import { toBech32, toHex } from '@cosmjs/encoding';
|
||||
import { rawSecp256k1PubkeyToRawAddress } from "@cosmjs/amino";
|
||||
|
||||
const HDPATH = "m/44'/60'/0'/0";
|
||||
|
||||
const bip32 = BIP32Factory(ecc);
|
||||
|
||||
interface TypedMessageDomain {
|
||||
name?: string;
|
||||
@@ -17,6 +26,30 @@ interface TypedMessageDomain {
|
||||
export class Account {
|
||||
_privateKey: Buffer
|
||||
_publicKey?: Uint8Array
|
||||
_cosmosAddress?: string
|
||||
_formattedCosmosAddress?: string
|
||||
|
||||
/**
|
||||
* Generate bip39 mnemonic.
|
||||
*/
|
||||
static generateMnemonic() {
|
||||
return bip39.generateMnemonic();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate private key from mnemonic.
|
||||
*/
|
||||
static async generateFromMnemonic(mnemonic: string) {
|
||||
assert(mnemonic);
|
||||
|
||||
const seed = await bip39.mnemonicToSeed(mnemonic);
|
||||
const wallet = bip32.fromSeed(seed);
|
||||
const account = wallet.derivePath(HDPATH);
|
||||
const { privateKey } = account;
|
||||
assert(privateKey);
|
||||
|
||||
return new Account(privateKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* New Account.
|
||||
@@ -32,12 +65,23 @@ export class Account {
|
||||
return this._privateKey;
|
||||
}
|
||||
|
||||
get formattedCosmosAddress() {
|
||||
return this._formattedCosmosAddress;
|
||||
}
|
||||
|
||||
async init () {
|
||||
// Generate public key.
|
||||
const keypair = await Secp256k1.makeKeypair(this._privateKey);
|
||||
|
||||
const compressed = Secp256k1.compressPubkey(keypair.pubkey);
|
||||
this._publicKey = compressed
|
||||
|
||||
// 2. Generate cosmos-sdk address.
|
||||
// let publicKeySha256 = sha256(this._publicKey);
|
||||
this._cosmosAddress = new Ripemd160().update(keypair.pubkey).digest().toString();
|
||||
|
||||
// 3. Generate cosmos-sdk formatted address.
|
||||
this._formattedCosmosAddress = toBech32('ethm', rawSecp256k1PubkeyToRawAddress(this._publicKey));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,6 +6,8 @@ import {
|
||||
Chain,
|
||||
Sender,
|
||||
Fee,
|
||||
createMessageSend,
|
||||
MessageSendParams
|
||||
} from '@tharsis/transactions'
|
||||
|
||||
import { createTxMsgCancelBond, createTxMsgCreateBond, createTxMsgRefillBond, createTxMsgWithdrawBond, MessageMsgCancelBond, MessageMsgCreateBond, MessageMsgRefillBond, MessageMsgWithdrawBond } from "./bond";
|
||||
@@ -78,6 +80,36 @@ export class Registry {
|
||||
return this._client.getAccount(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send coins.
|
||||
* @param {object[]} amount
|
||||
* @param {string} toAddress
|
||||
* @param {string} privateKey
|
||||
* @param {object} fee
|
||||
*/
|
||||
async sendCoins(params: MessageSendParams, 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 = createMessageSend(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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the next bondId for the given account private key.
|
||||
*/
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import assert from 'assert';
|
||||
|
||||
import { Account } from './account';
|
||||
import { Registry } from './index';
|
||||
import { getConfig, wait } from './testing/helper';
|
||||
|
||||
@@ -43,6 +46,50 @@ const namingTests = () => {
|
||||
expect(record.ownerPublicKey).toBe('');
|
||||
expect(Number(record.height)).toBe(0);
|
||||
});
|
||||
|
||||
xtest('Reserve already reserved authority', async () => {
|
||||
await expect(registry.reserveAuthority({ name: authorityName, owner: accountAddress }, accountAddress, privateKey, fee)).rejects.toThrow('Name already reserved.');
|
||||
});
|
||||
|
||||
test('Reserve sub-authority.', async () => {
|
||||
const subAuthority = `echo.${authorityName}`;
|
||||
await registry.reserveAuthority({ name: subAuthority, owner: accountAddress }, accountAddress, privateKey, fee);
|
||||
await wait(5000)
|
||||
|
||||
const [record] = await registry.lookupAuthorities([subAuthority]);
|
||||
expect(record).toBeDefined();
|
||||
expect(record.ownerAddress).not.toBe('');
|
||||
expect(record.ownerPublicKey).not.toBe('');
|
||||
expect(Number(record.height)).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
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()
|
||||
assert(otherAccount1.formattedCosmosAddress)
|
||||
await registry.sendCoins({ denom: 'aphoton', amount: '1000000000', destinationAddress: otherAccount1.formattedCosmosAddress }, accountAddress, privateKey, fee);
|
||||
|
||||
const mnenonic2 = Account.generateMnemonic();
|
||||
const otherAccount2 = await Account.generateFromMnemonic(mnenonic2);
|
||||
await otherAccount2.init()
|
||||
assert(otherAccount2.formattedCosmosAddress)
|
||||
await registry.sendCoins({ denom: 'aphoton', amount: '10', destinationAddress: otherAccount2.formattedCosmosAddress }, accountAddress, privateKey, fee);
|
||||
|
||||
await wait(5000)
|
||||
|
||||
const subAuthority = `halo.${authorityName}`;
|
||||
await registry.reserveAuthority({ name: subAuthority, owner: otherAccount1.formattedCosmosAddress }, accountAddress, privateKey, fee);
|
||||
await wait(5000)
|
||||
|
||||
const [record] = await registry.lookupAuthorities([subAuthority]);
|
||||
expect(record).toBeDefined();
|
||||
expect(record.ownerAddress).toBeDefined();
|
||||
expect(record.ownerAddress).toBe(otherAccount1.formattedCosmosAddress);
|
||||
expect(record.ownerPublicKey).toBeDefined();
|
||||
expect(Number(record.height)).toBeGreaterThan(0);
|
||||
});
|
||||
};
|
||||
|
||||
if (mockServer || process.env.WIRE_AUCTIONS_ENABLED) {
|
||||
|
||||
Reference in New Issue
Block a user