Remove unused code and update CI (#9)
All checks were successful
Tests / sdk_tests (push) Successful in 19m43s

Part of https://www.notion.so/Create-laconic-registry-SDK-d3a636d4aba44f7cbba3bd99b7146811

Co-authored-by: neeraj <neeraj.rtly@gmail.com>
Reviewed-on: #9
Co-authored-by: Prathamesh Musale <prathamesh.musale0@gmail.com>
Co-committed-by: Prathamesh Musale <prathamesh.musale0@gmail.com>
This commit is contained in:
Prathamesh Musale 2024-03-14 09:15:48 +00:00 committed by nabarun
parent 409e6d5c6f
commit 911be08850
20 changed files with 102 additions and 1336 deletions

View File

@ -20,7 +20,7 @@ jobs:
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
path: "./laconic2d/" path: "./laconic2d/"
repository: deep-stack/laconic2d # TODO: Use cerc-io/laconic2d repository: cerc-io/laconic2d
fetch-depth: 0 fetch-depth: 0
ref: main ref: main
- name: Environment - name: Environment

View File

@ -1,6 +1,6 @@
# registry-sdk # registry-sdk
Client library used by TS/JS applications to communicate with laconicd. Client library used by TS/JS applications to communicate with laconic2d.
## Tests ## Tests
@ -38,7 +38,7 @@ Follow these steps to run the tests:
- Run the tests with auctions enabled - Run the tests with auctions enabled
- In laconicd repo run: - In laconic2d repo run:
```bash ```bash
TEST_AUCTION_ENABLED=true ./scripts/init.sh clean TEST_AUCTION_ENABLED=true ./scripts/init.sh clean
@ -58,7 +58,7 @@ Follow these steps to run the tests:
- Run the tests for record and authority expiry - Run the tests for record and authority expiry
- In laconicd repo run: - In laconic2d repo run:
```bash ```bash
TEST_REGISTRY_EXPIRY=true ./scripts/init.sh clean TEST_REGISTRY_EXPIRY=true ./scripts/init.sh clean
@ -87,7 +87,7 @@ Follow these steps to run the tests:
failed to execute message; message index: 0: Invalid signature.: unauthorized failed to execute message; message index: 0: Invalid signature.: unauthorized
``` ```
- When sending `setRecord` message, an integer value passed in watcher attributes is parsed as float type in laconicd while [unmarshalling json](https://pkg.go.dev/encoding/json#Unmarshal). - When sending `setRecord` message, an integer value passed in watcher attributes is parsed as float type in laconic2d while [unmarshalling json](https://pkg.go.dev/encoding/json#Unmarshal).
- `setRecord` message throws error when fileds in [Record](./src/types.ts) message are not assigned. - `setRecord` message throws error when fileds in [Record](./src/types.ts) message are not assigned.
``` ```

View File

@ -4,12 +4,9 @@ import * as ecc from 'tiny-secp256k1';
import * as bip39 from 'bip39'; import * as bip39 from 'bip39';
import canonicalStringify from 'canonical-json'; import canonicalStringify from 'canonical-json';
import secp256k1 from 'secp256k1'; import secp256k1 from 'secp256k1';
import { utils } from 'ethers';
import { sha256 } from 'js-sha256'; import { sha256 } from 'js-sha256';
import { MessageTypes, signTypedData, SignTypedDataVersion } from '@metamask/eth-sig-util';
import { Ripemd160 } from '@cosmjs/crypto'; import { toHex } from '@cosmjs/encoding';
import { fromHex, toHex } from '@cosmjs/encoding';
import { ethToEthermint } from '@tharsis/address-converter';
import { encodeSecp256k1Pubkey } from '@cosmjs/amino'; import { encodeSecp256k1Pubkey } from '@cosmjs/amino';
import { DirectSecp256k1Wallet } from '@cosmjs/proto-signing'; import { DirectSecp256k1Wallet } from '@cosmjs/proto-signing';
@ -19,14 +16,6 @@ const ACCOUNT_PREFIX = 'laconic';
const bip32 = BIP32Factory(ecc); const bip32 = BIP32Factory(ecc);
interface TypedMessageDomain {
name?: string;
version?: string;
chainId?: number;
verifyingContract?: string;
salt?: ArrayBuffer;
}
/** /**
* Registry account. * Registry account.
*/ */
@ -34,10 +23,7 @@ export class Account {
_privateKey: Buffer; _privateKey: Buffer;
_publicKey!: Uint8Array; _publicKey!: Uint8Array;
_encodedPubkey!: string; _encodedPubkey!: string;
_formattedCosmosAddress!: string;
_registryPublicKey!: string; _registryPublicKey!: string;
_registryAddress!: string;
_ethAddress!: string;
_wallet!: DirectSecp256k1Wallet; _wallet!: DirectSecp256k1Wallet;
_address!: string; _address!: string;
@ -79,18 +65,10 @@ export class Account {
return this._encodedPubkey; return this._encodedPubkey;
} }
get formattedCosmosAddress () {
return this._formattedCosmosAddress;
}
get registryPublicKey () { get registryPublicKey () {
return this._registryPublicKey; return this._registryPublicKey;
} }
get registryAddress () {
return this._registryAddress;
}
get address () { get address () {
return this._address; return this._address;
} }
@ -112,19 +90,9 @@ export class Account {
this._publicKey = secp256k1.publicKeyCreate(this._privateKey); this._publicKey = secp256k1.publicKeyCreate(this._privateKey);
this._encodedPubkey = encodeSecp256k1Pubkey(this._publicKey).value; this._encodedPubkey = encodeSecp256k1Pubkey(this._publicKey).value;
// 2. Generate eth address. // Generate registry formatted public key.
this._ethAddress = utils.computeAddress(this._publicKey);
// 3. Generate cosmos-sdk formatted address.
this._formattedCosmosAddress = ethToEthermint(this._ethAddress);
// 4. Generate registry formatted public key.
const publicKeyInHex = AMINO_PREFIX + toHex(account.pubkey); const publicKeyInHex = AMINO_PREFIX + toHex(account.pubkey);
this._registryPublicKey = Buffer.from(publicKeyInHex, 'hex').toString('base64'); this._registryPublicKey = Buffer.from(publicKeyInHex, 'hex').toString('base64');
// 5. Generate registry formatted address.
let publicKeySha256 = sha256(Buffer.from(publicKeyInHex, 'hex'));
this._registryAddress = new Ripemd160().update(fromHex(publicKeySha256)).digest().toString();
} }
/** /**
@ -134,13 +102,6 @@ export class Account {
return this._privateKey.toString('hex'); return this._privateKey.toString('hex');
} }
/**
* Get cosmos address.
*/
getCosmosAddress () {
return this._formattedCosmosAddress;
}
/** /**
* Get record signature. * Get record signature.
*/ */
@ -160,25 +121,4 @@ export class Account {
return Buffer.from(sigObj.signature); return Buffer.from(sigObj.signature);
} }
/**
* Sign message.
*/
sign (message: any) {
assert(message);
const eipMessageDomain: any = message.eipToSign.domain;
const signature = signTypedData({
data: {
types: message.eipToSign.types as MessageTypes,
primaryType: message.eipToSign.primaryType,
domain: eipMessageDomain as TypedMessageDomain,
message: message.eipToSign.message as Record<string, unknown>
},
privateKey: this._privateKey,
version: SignTypedDataVersion.V4
});
return signature;
}
} }

View File

@ -115,7 +115,7 @@ if (!process.env.TEST_AUCTIONS_ENABLED) {
test('skipping auction tests', () => {}); test('skipping auction tests', () => {});
} else { } else {
/** /**
Running these tests requires name auctions enabled. In laconicd repo run: Running these tests requires name auctions enabled. In laconic2d repo run:
TEST_AUCTION_ENABLED=true ./init.sh TEST_AUCTION_ENABLED=true ./init.sh

View File

@ -1,22 +1,11 @@
import { sha256 } from 'js-sha256'; import { sha256 } from 'js-sha256';
import { generatePostBodyBroadcast, BroadcastMode } from '@tharsis/provider';
import {
Chain,
Sender,
Fee,
MessageSendParams
} from '@tharsis/transactions';
import { DeliverTxResponse, StdFee } from '@cosmjs/stargate'; import { DeliverTxResponse, StdFee } from '@cosmjs/stargate';
import { RegistryClient } from './registry-client'; import { RegistryClient } from './registry-client';
import { Account } from './account'; import { Account } from './account';
import { createTransaction } from './txbuilder';
import { Util } from './util'; import { Util } from './util';
import { import {
createTxMsgAssociateBond,
createTxMsgDissociateBond,
createTxMsgDissociateRecords,
createTxMsgReAssociateRecords,
MessageMsgAssociateBond, MessageMsgAssociateBond,
MessageMsgCancelBond, MessageMsgCancelBond,
MessageMsgCreateBond, MessageMsgCreateBond,
@ -25,42 +14,24 @@ import {
MessageMsgReAssociateRecords, MessageMsgReAssociateRecords,
MessageMsgRefillBond, MessageMsgRefillBond,
MessageMsgWithdrawBond MessageMsgWithdrawBond
} from './messages/bond'; } from './types/cerc/bond/message';
import { import {
MessageMsgDeleteName, MessageMsgDeleteName,
MessageMsgSetAuthorityBond, MessageMsgSetAuthorityBond,
MessageMsgSetName, MessageMsgSetName
NAMESERVICE_ERRORS } from './types/cerc/registry/message';
} from './messages/registry';
import { import {
MessageMsgCommitBid, MessageMsgCommitBid,
MessageMsgRevealBid MessageMsgRevealBid
} from './messages/auction'; } from './types/cerc/auction/message';
import { LaconicClient } from './laconic-client'; import { LaconicClient } from './laconic-client';
import { MsgCancelBondResponse, MsgCreateBondResponse, MsgRefillBondResponse, MsgWithdrawBondResponse } from './proto2/cerc/bond/v1/tx'; import { MsgCancelBondResponse, MsgCreateBondResponse, MsgRefillBondResponse, MsgWithdrawBondResponse } from './proto2/cerc/bond/v1/tx';
import { Coin } from './proto2/cosmos/base/v1beta1/coin'; import { Coin } from './proto2/cosmos/base/v1beta1/coin';
import { MsgSendResponse } from './proto2/cosmos/bank/v1beta1/tx'; import { MsgSendResponse } from './proto2/cosmos/bank/v1beta1/tx';
import { MessageMsgSendCoins } from './types/cosmos/bank/message';
export const DEFAULT_CHAIN_ID = 'laconic_9000-1'; export const DEFAULT_CHAIN_ID = 'laconic_9000-1';
// Parse Tx response from cosmos-sdk.
export const parseTxResponse = (result: any, parseResponse?: (data: string) => any) => {
const { txhash: hash, height, ...txResponse } = result;
if (parseResponse) {
txResponse.data = parseResponse(txResponse.data);
}
txResponse.events.forEach((event:any) => {
event.attributes = event.attributes.map(({ key, value }: { key: string, value: string }) => ({
key: Buffer.from(key, 'base64').toString('utf8'),
value: Buffer.from(value, 'base64').toString('utf8')
}));
});
return { hash, height, ...txResponse };
};
/** /**
* Create an auction bid. * Create an auction bid.
*/ */
@ -87,12 +58,9 @@ export const createBid = async (chainId: string, auctionId: string, bidderAddres
}; };
}; };
export const isKeyValid = (key: string) => key && key.match(/^[0-9a-fA-F]{64}$/);
export class Registry { export class Registry {
_endpoints: {[key: string]: string}; _endpoints: {[key: string]: string};
_chainID: string; _chainID: string;
_chain: Chain;
_client: RegistryClient; _client: RegistryClient;
constructor (gqlUrl: string, restUrl = '', chainId: string = DEFAULT_CHAIN_ID) { constructor (gqlUrl: string, restUrl = '', chainId: string = DEFAULT_CHAIN_ID) {
@ -103,11 +71,6 @@ export class Registry {
this._client = new RegistryClient(gqlUrl, restUrl); this._client = new RegistryClient(gqlUrl, restUrl);
this._chainID = chainId; this._chainID = chainId;
this._chain = {
cosmosChainId: chainId,
chainId: this._parseEthChainId(chainId)
};
} }
/** /**
@ -175,7 +138,7 @@ export class Registry {
/** /**
* Send coins. * Send coins.
*/ */
async sendCoins ({ amount, denom, destinationAddress }: MessageSendParams, privateKey: string, fee: StdFee) { async sendCoins ({ amount, denom, destinationAddress }: MessageMsgSendCoins, privateKey: string, fee: StdFee) {
const account = new Account(Buffer.from(privateKey, 'hex')); const account = new Account(Buffer.from(privateKey, 'hex'));
await account.init(); await account.init();
const laconicClient = await this.getLaconicClient(account); const laconicClient = await this.getLaconicClient(account);
@ -468,35 +431,6 @@ export class Registry {
); );
} }
/**
* https://evmos.dev/basics/chain_id.html
*/
_parseEthChainId (chainId: string) {
const [idWithChainNumber] = chainId.split('-');
const [_, ethChainId] = idWithChainNumber.split('_');
return Number(ethChainId);
}
/**
* Get sender used for creating message.
*/
async _getSender (account: Account) {
const accounts = await this.getAccounts([account.formattedCosmosAddress]);
if (!accounts.length) {
throw new Error('Account does not exist.');
}
const [{ number, sequence }] = accounts;
return {
accountAddress: account.formattedCosmosAddress,
sequence: sequence,
accountNumber: number,
pubkey: account.encodedPubkey
};
}
async getLaconicClient (account: Account) { async getLaconicClient (account: Account) {
return LaconicClient.connectWithSigner(this._endpoints.rest, account.wallet); return LaconicClient.connectWithSigner(this._endpoints.rest, account.wallet);
} }

View File

@ -11,18 +11,17 @@ import { Comet38Client } from '@cosmjs/tendermint-rpc';
import { MsgCancelBondEncodeObject, MsgCreateBondEncodeObject, MsgRefillBondEncodeObject, MsgWithdrawBondEncodeObject, bondTypes, typeUrlMsgCancelBond, typeUrlMsgCreateBond, typeUrlMsgRefillBond, typeUrlMsgWithdrawBond } from './types/cerc/bond/message'; import { MsgCancelBondEncodeObject, MsgCreateBondEncodeObject, MsgRefillBondEncodeObject, MsgWithdrawBondEncodeObject, bondTypes, typeUrlMsgCancelBond, typeUrlMsgCreateBond, typeUrlMsgRefillBond, typeUrlMsgWithdrawBond } from './types/cerc/bond/message';
import { Coin } from './proto2/cosmos/base/v1beta1/coin'; import { Coin } from './proto2/cosmos/base/v1beta1/coin';
import { MsgAssociateBondEncodeObject, MsgDeleteNameEncodeObject, MsgDissociateBondEncodeObject, MsgDissociateRecordsEncodeObject, MsgReassociateRecordsEncodeObject, MsgReserveAuthorityEncodeObject, MsgSetAuthorityBondEncodeObject, MsgSetNameEncodeObject, MsgSetRecordEncodeObject, registryTypes, typeUrlMsgAssociateBond, typeUrlMsgDeleteName, typeUrlMsgDissociateBond, typeUrlMsgDissociateRecords, typeUrlMsgReassociateRecords, typeUrlMsgReserveAuthority, typeUrlMsgSetAuthorityBond, typeUrlMsgSetName, typeUrlMsgSetRecord } from './types/cerc/registry/message'; import { MsgAssociateBondEncodeObject, MsgDeleteNameEncodeObject, MsgDissociateBondEncodeObject, MsgDissociateRecordsEncodeObject, MsgReassociateRecordsEncodeObject, MsgReserveAuthorityEncodeObject, MsgSetAuthorityBondEncodeObject, MsgSetNameEncodeObject, MsgSetRecordEncodeObject, registryTypes, typeUrlMsgAssociateBond, typeUrlMsgDeleteName, typeUrlMsgDissociateBond, typeUrlMsgDissociateRecords, typeUrlMsgReassociateRecords, typeUrlMsgReserveAuthority, typeUrlMsgSetAuthorityBond, typeUrlMsgSetName, typeUrlMsgSetRecord, NAMESERVICE_ERRORS } from './types/cerc/registry/message';
import { MsgCommitBidEncodeObject, MsgRevealBidEncodeObject, auctionTypes, typeUrlMsgCommitBid, typeUrlMsgRevealBid } from './types/cerc/auction/message'; import { MsgCommitBidEncodeObject, MsgRevealBidEncodeObject, auctionTypes, typeUrlMsgCommitBid, typeUrlMsgRevealBid } from './types/cerc/auction/message';
import { MsgAssociateBondResponse, MsgDeleteNameResponse, MsgDissociateBondResponse, MsgDissociateRecordsResponse, MsgReassociateRecordsResponse, MsgReserveAuthorityResponse, MsgSetAuthorityBondResponse, MsgSetNameResponse, MsgSetRecordResponse, Payload } from './proto2/cerc/registry/v1/tx'; import { MsgAssociateBondResponse, MsgDeleteNameResponse, MsgDissociateBondResponse, MsgDissociateRecordsResponse, MsgReassociateRecordsResponse, MsgReserveAuthorityResponse, MsgSetAuthorityBondResponse, MsgSetNameResponse, MsgSetRecordResponse, Payload } from './proto2/cerc/registry/v1/tx';
import { Record, Signature } from './proto2/cerc/registry/v1/registry'; import { Record, Signature } from './proto2/cerc/registry/v1/registry';
import { Account } from './account'; import { Account } from './account';
import { Util } from './util'; import { Util } from './util';
import { NAMESERVICE_ERRORS } from './messages/registry';
import { MsgCommitBidResponse, MsgRevealBidResponse } from './proto2/cerc/auction/v1/tx'; import { MsgCommitBidResponse, MsgRevealBidResponse } from './proto2/cerc/auction/v1/tx';
import { MsgCancelBondResponse, MsgCreateBondResponse, MsgRefillBondResponse, MsgWithdrawBondResponse } from './proto2/cerc/bond/v1/tx'; import { MsgCancelBondResponse, MsgCreateBondResponse, MsgRefillBondResponse, MsgWithdrawBondResponse } from './proto2/cerc/bond/v1/tx';
import { bankTypes } from './types/cosmos/bank/message'; import { bankTypes } from './types/cosmos/bank/message';
const DEFAULT_WRITE_ERROR = 'Unable to write to laconicd.'; const DEFAULT_WRITE_ERROR = 'Unable to write to laconic2d.';
export const laconicDefaultRegistryTypes: ReadonlyArray<[string, GeneratedType]> = [ export const laconicDefaultRegistryTypes: ReadonlyArray<[string, GeneratedType]> = [
...defaultRegistryTypes, ...defaultRegistryTypes,

View File

@ -1,149 +0,0 @@
import {
generateTypes
} from '@tharsis/eip712';
import {
Chain,
Sender,
Fee
} from '@tharsis/transactions';
import * as auctionTx from '../proto/vulcanize/auction/v1beta1/tx';
import { createTx } from './util';
const MSG_COMMIT_BID_TYPES = {
MsgValue: [
{ name: 'auction_id', type: 'string' },
{ name: 'commit_hash', type: 'string' },
{ name: 'signer', type: 'string' }
]
};
export interface MessageMsgCommitBid {
auctionId: string,
commitHash: string,
}
const MSG_REVEAL_BID_TYPES = {
MsgValue: [
{ name: 'auction_id', type: 'string' },
{ name: 'reveal', type: 'string' },
{ name: 'signer', type: 'string' }
]
};
export interface MessageMsgRevealBid {
auctionId: string,
reveal: string,
}
export function createTxMsgCommitBid (
chain: Chain,
sender: Sender,
fee: Fee,
memo: string,
params: MessageMsgCommitBid
) {
const types = generateTypes(MSG_COMMIT_BID_TYPES);
const msg = createMsgCommitBid(
params.auctionId,
params.commitHash,
sender.accountAddress
);
const msgCosmos = protoCreateMsgCommitBid(
params.auctionId,
params.commitHash,
sender.accountAddress
);
return createTx(chain, sender, fee, memo, types, msg, msgCosmos);
}
export function createTxMsgRevealBid (
chain: Chain,
sender: Sender,
fee: Fee,
memo: string,
params: MessageMsgRevealBid
) {
const types = generateTypes(MSG_REVEAL_BID_TYPES);
const msg = createMsgRevealBid(
params.auctionId,
params.reveal,
sender.accountAddress
);
const msgCosmos = protoCreateMsgRevealBid(
params.auctionId,
params.reveal,
sender.accountAddress
);
return createTx(chain, sender, fee, memo, types, msg, msgCosmos);
}
function createMsgCommitBid (
auctionId: string,
commitHash: string,
signer: string
) {
return {
type: 'auction/MsgCommitBid',
value: {
auction_id: auctionId,
commit_hash: commitHash,
signer
}
};
}
const protoCreateMsgCommitBid = (
auctionId: string,
commitHash: string,
signer: string
) => {
const commitBidMessage = new auctionTx.vulcanize.auction.v1beta1.MsgCommitBid({
auction_id: auctionId,
commit_hash: commitHash,
signer
});
return {
message: commitBidMessage,
path: 'vulcanize.auction.v1beta1.MsgCommitBid'
};
};
function createMsgRevealBid (
auctionId: string,
reveal: string,
signer: string
) {
return {
type: 'auction/MsgRevealBid',
value: {
auction_id: auctionId,
reveal,
signer
}
};
}
const protoCreateMsgRevealBid = (
auctionId: string,
reveal: string,
signer: string
) => {
const revealBidMessage = new auctionTx.vulcanize.auction.v1beta1.MsgRevealBid({
auction_id: auctionId,
reveal,
signer
});
return {
message: revealBidMessage,
path: 'vulcanize.auction.v1beta1.MsgRevealBid'
};
};

View File

@ -1,590 +0,0 @@
import {
generateTypes
} from '@tharsis/eip712';
import {
Chain,
Sender,
Fee
} from '@tharsis/transactions';
import * as bondTx from '../proto/vulcanize/bond/v1beta1/tx';
import * as registryTx from '../proto/vulcanize/registry/v1beta1/tx';
import * as coin from '../proto/cosmos/base/v1beta1/coin';
import { createTx } from './util';
const MSG_CREATE_BOND_TYPES = {
MsgValue: [
{ name: 'signer', type: 'string' },
{ name: 'coins', type: 'TypeCoins[]' }
],
TypeCoins: [
{ name: 'denom', type: 'string' },
{ name: 'amount', type: 'string' }
]
};
const MSG_REFILL_BOND_TYPES = {
MsgValue: [
{ name: 'id', type: 'string' },
{ name: 'signer', type: 'string' },
{ name: 'coins', type: 'TypeCoins[]' }
],
TypeCoins: [
{ name: 'denom', type: 'string' },
{ name: 'amount', type: 'string' }
]
};
const MSG_WITHDRAW_BOND_TYPES = {
MsgValue: [
{ name: 'id', type: 'string' },
{ name: 'signer', type: 'string' },
{ name: 'coins', type: 'TypeCoins[]' }
],
TypeCoins: [
{ name: 'denom', type: 'string' },
{ name: 'amount', type: 'string' }
]
};
const MSG_CANCEL_BOND_TYPES = {
MsgValue: [
{ name: 'id', type: 'string' },
{ name: 'signer', type: 'string' }
]
};
const MSG_ASSOCIATE_BOND_TYPES = {
MsgValue: [
{ name: 'record_id', type: 'string' },
{ name: 'bond_id', type: 'string' },
{ name: 'signer', type: 'string' }
]
};
const MSG_DISSOCIATE_BOND_TYPES = {
MsgValue: [
{ name: 'record_id', type: 'string' },
{ name: 'signer', type: 'string' }
]
};
const MSG_DISSOCIATE_RECORDS_TYPES = {
MsgValue: [
{ name: 'bond_id', type: 'string' },
{ name: 'signer', type: 'string' }
]
};
const MSG_REASSOCIATE_RECORDS_TYPES = {
MsgValue: [
{ name: 'new_bond_id', type: 'string' },
{ name: 'old_bond_id', type: 'string' },
{ name: 'signer', type: 'string' }
]
};
export interface MessageMsgCreateBond {
amount: string
denom: string
}
export interface MessageMsgRefillBond {
id: string,
amount: string
denom: string
}
export interface MessageMsgWithdrawBond {
id: string
amount: string
denom: string
}
export interface MessageMsgCancelBond {
id: string
}
export interface MessageMsgAssociateBond {
bondId: string,
recordId: string
}
export interface MessageMsgDissociateBond {
recordId: string
}
export interface MessageMsgDissociateRecords {
bondId: string
}
export interface MessageMsgReAssociateRecords {
newBondId: string
oldBondId: string
}
export function createTxMsgCreateBond (
chain: Chain,
sender: Sender,
fee: Fee,
memo: string,
params: MessageMsgCreateBond
) {
const types = generateTypes(MSG_CREATE_BOND_TYPES);
const msg = createMsgCreateBond(
sender.accountAddress,
params.amount,
params.denom
);
const msgCosmos = protoCreateMsgCreateBond(
sender.accountAddress,
params.amount,
params.denom
);
return createTx(chain, sender, fee, memo, types, msg, msgCosmos);
}
export function createTxMsgRefillBond (
chain: Chain,
sender: Sender,
fee: Fee,
memo: string,
params: MessageMsgRefillBond
) {
const types = generateTypes(MSG_REFILL_BOND_TYPES);
const msg = createMsgRefillBond(
params.id,
sender.accountAddress,
params.amount,
params.denom
);
const msgCosmos = protoCreateMsgRefillBond(
params.id,
sender.accountAddress,
params.amount,
params.denom
);
return createTx(chain, sender, fee, memo, types, msg, msgCosmos);
}
export function createTxMsgWithdrawBond (
chain: Chain,
sender: Sender,
fee: Fee,
memo: string,
params: MessageMsgWithdrawBond
) {
const types = generateTypes(MSG_WITHDRAW_BOND_TYPES);
const msg = createMsgWithdrawBond(
params.id,
sender.accountAddress,
params.amount,
params.denom
);
const msgCosmos = protoCreateMsgWithdrawBond(
params.id,
sender.accountAddress,
params.amount,
params.denom
);
return createTx(chain, sender, fee, memo, types, msg, msgCosmos);
}
export function createTxMsgCancelBond (
chain: Chain,
sender: Sender,
fee: Fee,
memo: string,
params: MessageMsgCancelBond
) {
const types = generateTypes(MSG_CANCEL_BOND_TYPES);
const msg = createMsgCancelBond(
params.id,
sender.accountAddress
);
const msgCosmos = protoCreateMsgCancelBond(
params.id,
sender.accountAddress
);
return createTx(chain, sender, fee, memo, types, msg, msgCosmos);
}
export function createTxMsgAssociateBond (
chain: Chain,
sender: Sender,
fee: Fee,
memo: string,
params: MessageMsgAssociateBond
) {
const types = generateTypes(MSG_ASSOCIATE_BOND_TYPES);
const msg = createMsgAssociateBond(
params.recordId,
params.bondId,
sender.accountAddress
);
const msgCosmos = protoCreateMsgAssociateBond(
params.recordId,
params.bondId,
sender.accountAddress
);
return createTx(chain, sender, fee, memo, types, msg, msgCosmos);
}
export function createTxMsgDissociateBond (
chain: Chain,
sender: Sender,
fee: Fee,
memo: string,
params: MessageMsgDissociateBond
) {
const types = generateTypes(MSG_DISSOCIATE_BOND_TYPES);
const msg = createMsgDissociateBond(
params.recordId,
sender.accountAddress
);
const msgCosmos = protoCreateMsgDissociateBond(
params.recordId,
sender.accountAddress
);
return createTx(chain, sender, fee, memo, types, msg, msgCosmos);
}
export function createTxMsgDissociateRecords (
chain: Chain,
sender: Sender,
fee: Fee,
memo: string,
params: MessageMsgDissociateRecords
) {
const types = generateTypes(MSG_DISSOCIATE_RECORDS_TYPES);
const msg = createMsgDissociateRecords(
params.bondId,
sender.accountAddress
);
const msgCosmos = protoCreateMsgDissociateRecords(
params.bondId,
sender.accountAddress
);
return createTx(chain, sender, fee, memo, types, msg, msgCosmos);
}
export function createTxMsgReAssociateRecords (
chain: Chain,
sender: Sender,
fee: Fee,
memo: string,
params: MessageMsgReAssociateRecords
) {
const types = generateTypes(MSG_REASSOCIATE_RECORDS_TYPES);
const msg = createMsgReAssociateRecords(
params.newBondId,
params.oldBondId,
sender.accountAddress
);
const msgCosmos = protoCreateMsgReAssociateRecords(
params.newBondId,
params.oldBondId,
sender.accountAddress
);
return createTx(chain, sender, fee, memo, types, msg, msgCosmos);
}
function createMsgCreateBond (
signer: string,
amount: string,
denom: string
) {
return {
type: 'bond/MsgCreateBond',
value: {
coins: [
{
amount,
denom
}
],
signer
}
};
}
const protoCreateMsgCreateBond = (
signer: string,
amount: string,
denom: string
) => {
const value = new coin.cosmos.base.v1beta1.Coin({
denom,
amount
});
const createBondMessage = new bondTx.vulcanize.bond.v1beta1.MsgCreateBond({
signer,
coins: [value]
});
return {
message: createBondMessage,
path: 'vulcanize.bond.v1beta1.MsgCreateBond'
};
};
function createMsgRefillBond (
id: string,
signer: string,
amount: string,
denom: string
) {
return {
type: 'bond/MsgRefillBond',
value: {
coins: [
{
amount,
denom
}
],
id,
signer
}
};
}
const protoCreateMsgRefillBond = (
id: string,
signer: string,
amount: string,
denom: string
) => {
const value = new coin.cosmos.base.v1beta1.Coin({
denom,
amount
});
const refillBondMessage = new bondTx.vulcanize.bond.v1beta1.MsgRefillBond({
id,
signer,
coins: [value]
});
return {
message: refillBondMessage,
path: 'vulcanize.bond.v1beta1.MsgRefillBond'
};
};
function createMsgWithdrawBond (
id: string,
signer: string,
amount: string,
denom: string
) {
return {
type: 'bond/MsgWithdrawBond',
value: {
id,
coins: [
{
amount,
denom
}
],
signer
}
};
}
const protoCreateMsgWithdrawBond = (
id: string,
signer: string,
amount: string,
denom: string
) => {
const value = new coin.cosmos.base.v1beta1.Coin({
denom,
amount
});
const withdrawBondMessage = new bondTx.vulcanize.bond.v1beta1.MsgWithdrawBond({
id,
signer,
coins: [value]
});
return {
message: withdrawBondMessage,
path: 'vulcanize.bond.v1beta1.MsgWithdrawBond'
};
};
function createMsgCancelBond (
id: string,
signer: string
) {
return {
type: 'bond/MsgCancelBond',
value: {
id,
signer
}
};
}
const protoCreateMsgCancelBond = (
id: string,
signer: string
) => {
const cancelBondMessage = new bondTx.vulcanize.bond.v1beta1.MsgCancelBond({
id,
signer
});
return {
message: cancelBondMessage,
path: 'vulcanize.bond.v1beta1.MsgCancelBond'
};
};
function createMsgAssociateBond (
recordId: string,
bondId: string,
signer: string
) {
return {
type: 'registry/AssociateBond',
value: {
record_id: recordId,
bond_id: bondId,
signer
}
};
}
const protoCreateMsgAssociateBond = (
recordId: string,
bondId: string,
signer: string
) => {
const associateBondMessage = new registryTx.vulcanize.registry.v1beta1.MsgAssociateBond({
record_id: recordId,
bond_id: bondId,
signer
});
return {
message: associateBondMessage,
path: 'vulcanize.registry.v1beta1.MsgAssociateBond'
};
};
function createMsgDissociateBond (
recordId: string,
signer: string
) {
return {
type: 'registry/DissociateBond',
value: {
record_id: recordId,
signer
}
};
}
const protoCreateMsgDissociateBond = (
recordId: string,
signer: string
) => {
const dissociateBondMessage = new registryTx.vulcanize.registry.v1beta1.MsgDissociateBond({
record_id: recordId,
signer
});
return {
message: dissociateBondMessage,
path: 'vulcanize.registry.v1beta1.MsgDissociateBond'
};
};
function createMsgDissociateRecords (
bondId: string,
signer: string
) {
return {
type: 'registry/DissociateRecords',
value: {
bond_id: bondId,
signer
}
};
}
const protoCreateMsgDissociateRecords = (
bondId: string,
signer: string
) => {
const dissociateRecordsMessage = new registryTx.vulcanize.registry.v1beta1.MsgDissociateRecords({
bond_id: bondId,
signer
});
return {
message: dissociateRecordsMessage,
path: 'vulcanize.registry.v1beta1.MsgDissociateRecords'
};
};
function createMsgReAssociateRecords (
newBondId: string,
oldBondId: string,
signer: string
) {
return {
type: 'registry/ReassociateRecords',
value: {
new_bond_id: newBondId,
old_bond_id: oldBondId,
signer
}
};
}
const protoCreateMsgReAssociateRecords = (
newBondId: string,
oldBondId: string,
signer: string
) => {
const reAssociateRecordsMessage = new registryTx.vulcanize.registry.v1beta1.MsgReAssociateRecords({
new_bond_id: newBondId,
old_bond_id: oldBondId,
signer
});
return {
message: reAssociateRecordsMessage,
path: 'vulcanize.registry.v1beta1.MsgReAssociateRecords'
};
};

View File

@ -1,323 +0,0 @@
import {
generateTypes
} from '@tharsis/eip712';
import {
Chain,
Sender,
Fee
} from '@tharsis/transactions';
import * as registryTx from '../proto/vulcanize/registry/v1beta1/tx';
import { createTx } from './util';
const MSG_RESERVE_AUTHORITY_TYPES = {
MsgValue: [
{ name: 'name', type: 'string' },
{ name: 'signer', type: 'string' },
{ name: 'owner', type: 'string' }
]
};
const MSG_SET_NAME_TYPES = {
MsgValue: [
{ name: 'crn', type: 'string' },
{ name: 'cid', type: 'string' },
{ name: 'signer', type: 'string' }
]
};
const MSG_SET_RECORD_TYPES = {
MsgValue: [
{ name: 'bond_id', type: 'string' },
{ name: 'signer', type: 'string' },
{ name: 'payload', type: 'TypePayload' }
],
TypePayload: [
{ name: 'record', type: 'TypePayloadRecord' },
{ name: 'signatures', type: 'TypePayloadSignatures[]' }
],
TypePayloadRecord: [
{ name: 'id', type: 'string' },
{ name: 'bond_id', type: 'string' },
{ name: 'create_time', type: 'string' },
{ name: 'expiry_time', type: 'string' },
{ name: 'deleted', type: 'bool' },
{ name: 'attributes', type: 'bytes' }
],
TypePayloadSignatures: [
{ name: 'sig', type: 'string' },
{ name: 'pub_key', type: 'string' }
]
};
const MSG_SET_AUTHORITY_BOND_TYPES = {
MsgValue: [
{ name: 'name', type: 'string' },
{ name: 'bond_id', type: 'string' },
{ name: 'signer', type: 'string' }
]
};
const MSG_DELETE_NAME_TYPES = {
MsgValue: [
{ name: 'crn', type: 'string' },
{ name: 'signer', type: 'string' }
]
};
export const parseMsgSetRecordResponse = (data: string) => {
const responseBytes = Buffer.from(data, 'hex');
// TODO: Decode response using protobuf.
// const msgSetRecordResponse = nameserviceTx.vulcanize.nameservice.v1beta1.MsgSetRecordResponse.deserialize(responseBytes);
// return msgSetRecordResponse.toObject();
// Workaround as proto based decoding is not working.
const [_, id] = responseBytes.toString().split(';');
return { id };
};
export const NAMESERVICE_ERRORS = [
'Name already reserved.',
'Authority bond not found.',
'Name authority not found.',
'Access denied.'
];
export interface MessageMsgReserveAuthority {
name: string
owner: string
}
export interface MessageMsgSetName {
lrn: string
cid: string
}
export interface MessageMsgSetAuthorityBond {
name: string
bondId: string
}
export interface MessageMsgDeleteName {
lrn: string
}
export function createTxMsgReserveAuthority (
chain: Chain,
sender: Sender,
fee: Fee,
memo: string,
params: MessageMsgReserveAuthority
) {
const types = generateTypes(MSG_RESERVE_AUTHORITY_TYPES);
const msg = createMsgReserveAuthority(
params.name,
sender.accountAddress,
params.owner
);
const msgCosmos = protoCreateMsgReserveAuthority(
params.name,
sender.accountAddress,
params.owner
);
return createTx(chain, sender, fee, memo, types, msg, msgCosmos);
}
export function createTxMsgSetName (
chain: Chain,
sender: Sender,
fee: Fee,
memo: string,
params: MessageMsgSetName
) {
const types = generateTypes(MSG_SET_NAME_TYPES);
const msg = createMsgSetName(
params.lrn,
params.cid,
sender.accountAddress
);
const msgCosmos = protoCreateMsgSetName(
params.lrn,
params.cid,
sender.accountAddress
);
return createTx(chain, sender, fee, memo, types, msg, msgCosmos);
}
export function createTxMsgSetAuthorityBond (
chain: Chain,
sender: Sender,
fee: Fee,
memo: string,
params: MessageMsgSetAuthorityBond
) {
const types = generateTypes(MSG_SET_AUTHORITY_BOND_TYPES);
const msg = createMsgSetAuthorityBond(
params.name,
params.bondId,
sender.accountAddress
);
const msgCosmos = protoCreateMsgSetAuthorityBond(
params.name,
params.bondId,
sender.accountAddress
);
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.lrn,
sender.accountAddress
);
const msgCosmos = protoCreateMsgDeleteName(
params.lrn,
sender.accountAddress
);
return createTx(chain, sender, fee, memo, types, msg, msgCosmos);
}
function createMsgReserveAuthority (
name: string,
signer: string,
owner: string
) {
return {
type: 'registry/ReserveAuthority',
value: {
name,
signer,
owner
}
};
}
const protoCreateMsgReserveAuthority = (
name: string,
signer: string,
owner: string
) => {
const reserveAuthorityMessage = new registryTx.vulcanize.registry.v1beta1.MsgReserveAuthority({
name,
signer,
owner
});
return {
message: reserveAuthorityMessage,
path: 'vulcanize.registry.v1beta1.MsgReserveAuthority'
};
};
function createMsgSetName (
crn: string,
cid: string,
signer: string
) {
return {
type: 'registry/SetName',
value: {
crn,
cid,
signer
}
};
}
const protoCreateMsgSetName = (
crn: string,
cid: string,
signer: string
) => {
const setNameMessage = new registryTx.vulcanize.registry.v1beta1.MsgSetName({
crn,
cid,
signer
});
return {
message: setNameMessage,
path: 'vulcanize.registry.v1beta1.MsgSetName'
};
};
function createMsgSetAuthorityBond (
name: string,
bondId: string,
signer: string
) {
return {
type: 'registry/SetAuthorityBond',
value: {
name,
bond_id: bondId,
signer
}
};
}
const protoCreateMsgSetAuthorityBond = (
name: string,
bondId: string,
signer: string
) => {
const setAuthorityBondMessage = new registryTx.vulcanize.registry.v1beta1.MsgSetAuthorityBond({
name,
bond_id: bondId,
signer
});
return {
message: setAuthorityBondMessage,
path: 'vulcanize.registry.v1beta1.MsgSetAuthorityBond'
};
};
function createMsgDeleteName (
crn: string,
signer: string
) {
return {
type: 'registry/DeleteAuthority',
value: {
crn,
signer
}
};
}
const protoCreateMsgDeleteName = (
crn: string,
signer: string
) => {
const deleteNameAutorityMessage = new registryTx.vulcanize.registry.v1beta1.MsgDeleteNameAuthority({
crn,
signer
});
return {
message: deleteNameAutorityMessage,
path: 'vulcanize.registry.v1beta1.MsgDeleteNameAuthority'
};
};

View File

@ -1,79 +0,0 @@
import { Message } from 'google-protobuf';
import {
createEIP712,
generateFee,
generateMessage,
generateTypes
} from '@tharsis/eip712';
import {
Chain,
Sender,
Fee
} from '@tharsis/transactions';
import { createTransaction } from '@tharsis/proto';
interface Msg {
type: string
value: any
}
interface MsgCosmos {
message: Message
path: string
}
interface Types {
[key: string]: Array<{
name: string
type: string
}>
}
export const createTx = (
chain: Chain,
sender: Sender,
fee: Fee,
memo: string,
messageTypes: Types,
msg: Msg,
msgCosmos: MsgCosmos
) => {
// EIP712
const feeObject = generateFee(
fee.amount,
fee.denom,
fee.gas,
sender.accountAddress
);
const types = generateTypes(messageTypes);
const messages = generateMessage(
sender.accountNumber.toString(),
sender.sequence.toString(),
chain.cosmosChainId,
memo,
feeObject,
msg
);
const eipToSign = createEIP712(types, chain.chainId, messages);
// Cosmos
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
};
};

View File

@ -103,7 +103,7 @@ if (!process.env.TEST_NAMESERVICE_EXPIRY) {
test('skipping nameservice expiry tests', () => {}); test('skipping nameservice expiry tests', () => {});
} else { } else {
/** /**
Running these tests requires timers to be set. In laconicd repo run: Running these tests requires timers to be set. In laconic2d repo run:
TEST_REGISTRY_EXPIRY=true ./init.sh TEST_REGISTRY_EXPIRY=true ./init.sh

View File

@ -1,8 +1,6 @@
import assert from 'assert'; import assert from 'assert';
import axios from 'axios';
import graphqlClient from 'graphql.js'; import graphqlClient from 'graphql.js';
import { get, set } from 'lodash'; import { get, set } from 'lodash';
import { generateEndpointAccount, generateEndpointBroadcast } from '@tharsis/provider';
import { Util } from './util'; import { Util } from './util';
@ -419,19 +417,4 @@ export class RegistryClient {
return RegistryClient.getResult(this._graph(query)(variables), 'queryBonds'); return RegistryClient.getResult(this._graph(query)(variables), 'queryBonds');
} }
/**
* Submit transaction.
*/
async submit (tx: string) {
assert(tx);
// Broadcast transaction.
const { data } = await axios.post(
`${this._restEndpoint}${generateEndpointBroadcast()}`,
tx
);
return data;
}
} }

View File

@ -1,5 +0,0 @@
{
"$schema": "http://json-schema.org/schema#",
"id": "/Record",
"type": "object"
}

View File

@ -1,9 +1,8 @@
import assert from 'assert'; import assert from 'assert';
import yaml from 'node-yaml'; import yaml from 'node-yaml';
import semver from 'semver'; import semver from 'semver';
import { Fee } from '@tharsis/transactions';
import { DEFAULT_CHAIN_ID, Registry } from '../index'; import { DEFAULT_CHAIN_ID } from '../index';
export const ensureUpdatedConfig = async (path: string) => { export const ensureUpdatedConfig = async (path: string) => {
const conf = await yaml.read(path); const conf = await yaml.read(path);

View File

@ -1,25 +0,0 @@
import assert from 'assert';
import {
createTxRawEIP712,
signatureToWeb3Extension,
Chain,
Sender
} from '@tharsis/transactions';
import { Account } from './account';
/**
* Generate a cosmos-sdk transaction.
*/
export const createTransaction = (message: any, account: Account, sender: Sender, chain: Chain) => {
assert(message);
assert(account);
// Sign transaction.
const signature = account.sign(message);
let extension = signatureToWeb3Extension(chain, sender, signature);
// Create the txRaw.
return createTxRawEIP712(message.legacyAmino.body, message.legacyAmino.authInfo, extension);
};

View File

@ -23,3 +23,13 @@ export interface MsgRevealBidEncodeObject extends EncodeObject {
readonly typeUrl: '/cerc.auction.v1.MsgRevealBid'; readonly typeUrl: '/cerc.auction.v1.MsgRevealBid';
readonly value: Partial<MsgRevealBid>; readonly value: Partial<MsgRevealBid>;
} }
export interface MessageMsgCommitBid {
auctionId: string,
commitHash: string,
}
export interface MessageMsgRevealBid {
auctionId: string,
reveal: string,
}

View File

@ -50,3 +50,42 @@ export interface MsgCancelBondEncodeObject extends EncodeObject {
readonly typeUrl: '/cerc.bond.v1.MsgCancelBond'; readonly typeUrl: '/cerc.bond.v1.MsgCancelBond';
readonly value: Partial<MsgCancelBond>; readonly value: Partial<MsgCancelBond>;
} }
export interface MessageMsgCreateBond {
amount: string
denom: string
}
export interface MessageMsgRefillBond {
id: string,
amount: string
denom: string
}
export interface MessageMsgWithdrawBond {
id: string
amount: string
denom: string
}
export interface MessageMsgCancelBond {
id: string
}
export interface MessageMsgAssociateBond {
bondId: string,
recordId: string
}
export interface MessageMsgDissociateBond {
recordId: string
}
export interface MessageMsgDissociateRecords {
bondId: string
}
export interface MessageMsgReAssociateRecords {
newBondId: string
oldBondId: string
}

View File

@ -86,3 +86,29 @@ export interface MsgReassociateRecordsEncodeObject extends EncodeObject {
readonly typeUrl: '/cerc.registry.v1.MsgReassociateRecords'; readonly typeUrl: '/cerc.registry.v1.MsgReassociateRecords';
readonly value: Partial<MsgReassociateRecords>; readonly value: Partial<MsgReassociateRecords>;
} }
export const NAMESERVICE_ERRORS = [
'Name already reserved.',
'Authority bond not found.',
'Name authority not found.',
'Access denied.'
];
export interface MessageMsgReserveAuthority {
name: string
owner: string
}
export interface MessageMsgSetName {
lrn: string
cid: string
}
export interface MessageMsgSetAuthorityBond {
name: string
bondId: string
}
export interface MessageMsgDeleteName {
lrn: string
}

View File

@ -9,3 +9,9 @@ export const typeUrlMsgSendResponse = '/cosmos.bank.v1beta1.MsgSendResponse';
export const bankTypes: ReadonlyArray<[string, GeneratedType]> = [ export const bankTypes: ReadonlyArray<[string, GeneratedType]> = [
[typeUrlMsgSendResponse, MsgSendResponse] [typeUrlMsgSendResponse, MsgSendResponse]
]; ];
export interface MessageMsgSendCoins {
destinationAddress: string;
amount: string;
denom: string;
}

View File

@ -1,5 +1,6 @@
import * as Block from 'multiformats/block'; import * as Block from 'multiformats/block';
import { sha256 as hasher } from 'multiformats/hashes/sha2'; import { sha256 as hasher } from 'multiformats/hashes/sha2';
import * as dagCBOR from '@ipld/dag-cbor'; import * as dagCBOR from '@ipld/dag-cbor';
import * as dagJSON from '@ipld/dag-json'; import * as dagJSON from '@ipld/dag-json';