forked from cerc-io/laconic-sdk
Add tests for reserving authority with different owner
This commit is contained in:
parent
65e90e7af0
commit
252665512d
@ -15,7 +15,7 @@ Follow these steps to run the tests:
|
||||
- Checkout to appropriate branch for running tests.
|
||||
|
||||
```bash
|
||||
git checkout ng-chiba-clonk-client
|
||||
git checkout ng-v12-chiba-clonk-client
|
||||
```
|
||||
|
||||
- Run the chain using `./init.sh`.
|
||||
|
@ -24,13 +24,17 @@
|
||||
"@cosmjs/stargate": "^0.28.0",
|
||||
"@metamask/eth-sig-util": "^4.0.0",
|
||||
"axios": "^0.26.1",
|
||||
"bech32": "^2.0.0",
|
||||
"bip32": "^3.0.1",
|
||||
"bip39": "^3.0.4",
|
||||
"ethers": "^5.6.1",
|
||||
"evmosjs": "^0.2.2",
|
||||
"graphql.js": "^0.6.8",
|
||||
"is-url": "^1.2.4",
|
||||
"js-sha256": "^0.9.0",
|
||||
"ripemd160": "^2.0.2",
|
||||
"secp256k1": "^4.0.3"
|
||||
"secp256k1": "^4.0.3",
|
||||
"tiny-secp256k1": "^2.2.1"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jest --runInBand",
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
32
src/index.ts
32
src/index.ts
@ -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) {
|
||||
|
62
yarn.lock
62
yarn.lock
@ -1256,6 +1256,16 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.23.tgz#3b41a6e643589ac6442bdbd7a4a3ded62f33f7da"
|
||||
integrity sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==
|
||||
|
||||
"@types/node@10.12.18":
|
||||
version "10.12.18"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67"
|
||||
integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==
|
||||
|
||||
"@types/node@11.11.6":
|
||||
version "11.11.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a"
|
||||
integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==
|
||||
|
||||
"@types/node@^13.7.0":
|
||||
version "13.13.52"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.52.tgz#03c13be70b9031baaed79481c0c0cfb0045e53f7"
|
||||
@ -1512,6 +1522,28 @@ big-integer@1.6.36:
|
||||
resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.36.tgz#78631076265d4ae3555c04f85e7d9d2f3a071a36"
|
||||
integrity sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==
|
||||
|
||||
bip32@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/bip32/-/bip32-3.0.1.tgz#1d1121469cce6e910e0ec3a5a1990dd62687e2a3"
|
||||
integrity sha512-Uhpp9aEx3iyiO7CpbNGFxv9WcMIVdGoHG04doQ5Ln0u60uwDah7jUSc3QMV/fSZGm/Oo01/OeAmYevXV+Gz5jQ==
|
||||
dependencies:
|
||||
"@types/node" "10.12.18"
|
||||
bs58check "^2.1.1"
|
||||
create-hash "^1.2.0"
|
||||
create-hmac "^1.1.7"
|
||||
typeforce "^1.11.5"
|
||||
wif "^2.0.6"
|
||||
|
||||
bip39@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.0.4.tgz#5b11fed966840b5e1b8539f0f54ab6392969b2a0"
|
||||
integrity sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw==
|
||||
dependencies:
|
||||
"@types/node" "11.11.6"
|
||||
create-hash "^1.1.0"
|
||||
pbkdf2 "^3.0.9"
|
||||
randombytes "^2.0.1"
|
||||
|
||||
blakejs@^1.1.0:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814"
|
||||
@ -1589,7 +1621,7 @@ bs58@^4.0.0, bs58@^4.0.1:
|
||||
dependencies:
|
||||
base-x "^3.0.2"
|
||||
|
||||
bs58check@^2.1.2:
|
||||
bs58check@<3.0.0, bs58check@^2.1.1, bs58check@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc"
|
||||
integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==
|
||||
@ -3217,7 +3249,7 @@ path-parse@^1.0.7:
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
||||
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||
|
||||
pbkdf2@^3.0.17:
|
||||
pbkdf2@^3.0.17, pbkdf2@^3.0.9:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075"
|
||||
integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==
|
||||
@ -3325,7 +3357,7 @@ punycode@^2.1.1:
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
||||
|
||||
randombytes@^2.1.0:
|
||||
randombytes@^2.0.1, randombytes@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
|
||||
integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
|
||||
@ -3682,6 +3714,13 @@ throat@^6.0.1:
|
||||
resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375"
|
||||
integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==
|
||||
|
||||
tiny-secp256k1@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-2.2.1.tgz#a61d4791b7031aa08a9453178a131349c3e10f9b"
|
||||
integrity sha512-/U4xfVqnVxJXN4YVsru0E6t5wVncu2uunB8+RVR40fYUxkKYUPS10f+ePQZgFBoE/Jbf9H1NBveupF2VmB58Ng==
|
||||
dependencies:
|
||||
uint8array-tools "0.0.7"
|
||||
|
||||
tmpl@1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc"
|
||||
@ -3782,11 +3821,21 @@ typedarray-to-buffer@^3.1.5:
|
||||
dependencies:
|
||||
is-typedarray "^1.0.0"
|
||||
|
||||
typeforce@^1.11.5:
|
||||
version "1.18.0"
|
||||
resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc"
|
||||
integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==
|
||||
|
||||
typescript@^4.6.2:
|
||||
version "4.6.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.2.tgz#fe12d2727b708f4eef40f51598b3398baa9611d4"
|
||||
integrity sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==
|
||||
|
||||
uint8array-tools@0.0.7:
|
||||
version "0.0.7"
|
||||
resolved "https://registry.yarnpkg.com/uint8array-tools/-/uint8array-tools-0.0.7.tgz#a7a2bb5d8836eae2fade68c771454e6a438b390d"
|
||||
integrity sha512-vrrNZJiusLWoFWBqz5Y5KMCgP9W9hnjZHzZiZRT8oNAkq3d5Z5Oe76jAvVVSRh4U8GGR90N2X1dWtrhvx6L8UQ==
|
||||
|
||||
universalify@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
||||
@ -3870,6 +3919,13 @@ which@^2.0.1:
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
wif@^2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/wif/-/wif-2.0.6.tgz#08d3f52056c66679299726fade0d432ae74b4704"
|
||||
integrity sha1-CNP1IFbGZnkplyb63g1DKudLRwQ=
|
||||
dependencies:
|
||||
bs58check "<3.0.0"
|
||||
|
||||
word-wrap@~1.2.3:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
|
||||
|
Loading…
Reference in New Issue
Block a user