forked from cerc-io/registry-sdk
452 lines
13 KiB
TypeScript
452 lines
13 KiB
TypeScript
import Long from 'long';
|
|
|
|
import { GeneratedType, OfflineSigner, Registry } from '@cosmjs/proto-signing';
|
|
import {
|
|
defaultRegistryTypes,
|
|
DeliverTxResponse,
|
|
SigningStargateClient,
|
|
SigningStargateClientOptions,
|
|
StdFee
|
|
} from '@cosmjs/stargate';
|
|
import { Comet38Client } from '@cosmjs/tendermint-rpc';
|
|
|
|
import { MsgCancelBondEncodeObject, MsgCreateBondEncodeObject, MsgRefillBondEncodeObject, MsgWithdrawBondEncodeObject, bondTypes, typeUrlMsgCancelBond, typeUrlMsgCreateBond, typeUrlMsgRefillBond, typeUrlMsgWithdrawBond } from './types/cerc/bond/message';
|
|
import { Coin } from './proto/cosmos/base/v1beta1/coin';
|
|
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, MsgCreateAuctionEncodeObject, MsgRevealBidEncodeObject, auctionTypes, typeUrlMsgCommitBid, typeUrlMsgCreateAuction, typeUrlMsgRevealBid } from './types/cerc/auction/message';
|
|
import { MsgOnboardParticipantEncodeObject, ONBOARDING_DISABLED_ERROR, onboardingTypes, typeUrlMsgOnboardParticipant } from './types/cerc/onboarding/message';
|
|
import { MsgAssociateBondResponse, MsgDeleteNameResponse, MsgDissociateBondResponse, MsgDissociateRecordsResponse, MsgReassociateRecordsResponse, MsgReserveAuthorityResponse, MsgSetAuthorityBondResponse, MsgSetNameResponse, MsgSetRecordResponse, Payload } from './proto/cerc/registry/v1/tx';
|
|
import { Record, Signature } from './proto/cerc/registry/v1/registry';
|
|
import { Account } from './account';
|
|
import { Util } from './util';
|
|
import { MsgCommitBidResponse, MsgCreateAuction, MsgCreateAuctionResponse, MsgRevealBidResponse } from './proto/cerc/auction/v1/tx';
|
|
import { MsgCancelBondResponse, MsgCreateBondResponse, MsgRefillBondResponse, MsgWithdrawBondResponse } from './proto/cerc/bond/v1/tx';
|
|
import { MsgOnboardParticipantResponse } from './proto/cerc/onboarding/v1/tx';
|
|
import { bankTypes } from './types/cosmos/bank/message';
|
|
import { EthPayload } from './proto/cerc/onboarding/v1/onboarding';
|
|
import { Duration } from './proto/google/protobuf/duration';
|
|
|
|
const DEFAULT_WRITE_ERROR = 'Unable to write to laconicd.';
|
|
|
|
export const laconicDefaultRegistryTypes: ReadonlyArray<[string, GeneratedType]> = [
|
|
...defaultRegistryTypes,
|
|
...bondTypes,
|
|
...registryTypes,
|
|
...auctionTypes,
|
|
...bankTypes,
|
|
...onboardingTypes
|
|
];
|
|
|
|
function createDefaultRegistry (): Registry {
|
|
return new Registry(laconicDefaultRegistryTypes);
|
|
}
|
|
|
|
export class LaconicClient extends SigningStargateClient {
|
|
public static async connectWithSigner (
|
|
endpoint: string,
|
|
signer: OfflineSigner,
|
|
options: SigningStargateClientOptions = {}
|
|
): Promise<LaconicClient> {
|
|
const cometClient = await Comet38Client.connect(endpoint);
|
|
return new LaconicClient(cometClient, signer, {
|
|
registry: createDefaultRegistry(),
|
|
...options
|
|
});
|
|
}
|
|
|
|
public async createBond (
|
|
signer: string,
|
|
denom: string,
|
|
amount: string,
|
|
fee: StdFee | 'auto' | number,
|
|
memo = ''
|
|
) {
|
|
const createMsg: MsgCreateBondEncodeObject = {
|
|
typeUrl: typeUrlMsgCreateBond,
|
|
value: {
|
|
signer,
|
|
coins: [
|
|
Coin.fromPartial({
|
|
denom,
|
|
amount
|
|
})
|
|
]
|
|
}
|
|
};
|
|
|
|
const response = await this.signAndBroadcast(signer, [createMsg], fee, memo);
|
|
return this.parseResponse<MsgCreateBondResponse>(response);
|
|
}
|
|
|
|
public async refillBond (
|
|
signer: string,
|
|
denom: string,
|
|
amount: string,
|
|
id: string,
|
|
fee: StdFee | 'auto' | number,
|
|
memo = ''
|
|
) {
|
|
const createMsg: MsgRefillBondEncodeObject = {
|
|
typeUrl: typeUrlMsgRefillBond,
|
|
value: {
|
|
id,
|
|
signer,
|
|
coins: [
|
|
Coin.fromPartial({
|
|
denom,
|
|
amount
|
|
})
|
|
]
|
|
}
|
|
};
|
|
|
|
const response = await this.signAndBroadcast(signer, [createMsg], fee, memo);
|
|
return this.parseResponse<MsgRefillBondResponse>(response);
|
|
}
|
|
|
|
public async withdrawBond (
|
|
signer: string,
|
|
denom: string,
|
|
amount: string,
|
|
id: string,
|
|
fee: StdFee | 'auto' | number,
|
|
memo = ''
|
|
) {
|
|
const createMsg: MsgWithdrawBondEncodeObject = {
|
|
typeUrl: typeUrlMsgWithdrawBond,
|
|
value: {
|
|
id,
|
|
signer,
|
|
coins: [
|
|
Coin.fromPartial({
|
|
denom,
|
|
amount
|
|
})
|
|
]
|
|
}
|
|
};
|
|
|
|
const response = await this.signAndBroadcast(signer, [createMsg], fee, memo);
|
|
return this.parseResponse<MsgWithdrawBondResponse>(response);
|
|
}
|
|
|
|
public async cancelBond (
|
|
signer: string,
|
|
id: string,
|
|
fee: StdFee | 'auto' | number,
|
|
memo = ''
|
|
) {
|
|
const createMsg: MsgCancelBondEncodeObject = {
|
|
typeUrl: typeUrlMsgCancelBond,
|
|
value: {
|
|
id,
|
|
signer
|
|
}
|
|
};
|
|
|
|
const response = await this.signAndBroadcast(signer, [createMsg], fee, memo);
|
|
return this.parseResponse<MsgCancelBondResponse>(response);
|
|
}
|
|
|
|
public async associateBond (
|
|
signer: string,
|
|
recordId: string,
|
|
bondId: string,
|
|
fee: StdFee | 'auto' | number,
|
|
memo = ''
|
|
) {
|
|
const createMsg: MsgAssociateBondEncodeObject = {
|
|
typeUrl: typeUrlMsgAssociateBond,
|
|
value: {
|
|
recordId,
|
|
bondId,
|
|
signer
|
|
}
|
|
};
|
|
|
|
const response = await this.signAndBroadcast(signer, [createMsg], fee, memo);
|
|
return this.parseResponse<MsgAssociateBondResponse>(response);
|
|
}
|
|
|
|
public async dissociateBond (
|
|
signer: string,
|
|
recordId: string,
|
|
fee: StdFee | 'auto' | number,
|
|
memo = ''
|
|
) {
|
|
const createMsg: MsgDissociateBondEncodeObject = {
|
|
typeUrl: typeUrlMsgDissociateBond,
|
|
value: {
|
|
recordId,
|
|
signer
|
|
}
|
|
};
|
|
|
|
const response = await this.signAndBroadcast(signer, [createMsg], fee, memo);
|
|
return this.parseResponse<MsgDissociateBondResponse>(response);
|
|
}
|
|
|
|
public async dissociateRecords (
|
|
signer: string,
|
|
bondId: string,
|
|
fee: StdFee | 'auto' | number,
|
|
memo = ''
|
|
) {
|
|
const createMsg: MsgDissociateRecordsEncodeObject = {
|
|
typeUrl: typeUrlMsgDissociateRecords,
|
|
value: {
|
|
signer,
|
|
bondId
|
|
}
|
|
};
|
|
|
|
const response = await this.signAndBroadcast(signer, [createMsg], fee, memo);
|
|
return this.parseResponse<MsgDissociateRecordsResponse>(response);
|
|
}
|
|
|
|
public async reassociateRecords (
|
|
signer: string,
|
|
oldBondId: string,
|
|
newBondId: string,
|
|
fee: StdFee | 'auto' | number,
|
|
memo = ''
|
|
) {
|
|
const createMsg: MsgReassociateRecordsEncodeObject = {
|
|
typeUrl: typeUrlMsgReassociateRecords,
|
|
value: {
|
|
signer,
|
|
oldBondId,
|
|
newBondId
|
|
}
|
|
};
|
|
|
|
const response = await this.signAndBroadcast(signer, [createMsg], fee, memo);
|
|
return this.parseResponse<MsgReassociateRecordsResponse>(response);
|
|
}
|
|
|
|
public async reserveAuthority (
|
|
signer: string,
|
|
name: string,
|
|
owner: string,
|
|
fee: StdFee | 'auto' | number,
|
|
memo = ''
|
|
) {
|
|
const createMsg: MsgReserveAuthorityEncodeObject = {
|
|
typeUrl: typeUrlMsgReserveAuthority,
|
|
value: {
|
|
name,
|
|
signer,
|
|
owner
|
|
}
|
|
};
|
|
|
|
const response = await this.signAndBroadcast(signer, [createMsg], fee, memo);
|
|
return this.parseResponse<MsgReserveAuthorityResponse>(response);
|
|
}
|
|
|
|
public async commitBid (
|
|
signer: string,
|
|
auctionId: string,
|
|
commitHash: string,
|
|
fee: StdFee | 'auto' | number,
|
|
memo = ''
|
|
) {
|
|
const createMsg: MsgCommitBidEncodeObject = {
|
|
typeUrl: typeUrlMsgCommitBid,
|
|
value: {
|
|
signer,
|
|
auctionId,
|
|
commitHash
|
|
}
|
|
};
|
|
|
|
const response = await this.signAndBroadcast(signer, [createMsg], fee, memo);
|
|
return this.parseResponse<MsgCommitBidResponse>(response);
|
|
}
|
|
|
|
public async revealBid (
|
|
signer: string,
|
|
auctionId: string,
|
|
reveal: string,
|
|
fee: StdFee | 'auto' | number,
|
|
memo = ''
|
|
) {
|
|
const createMsg: MsgRevealBidEncodeObject = {
|
|
typeUrl: typeUrlMsgRevealBid,
|
|
value: {
|
|
signer,
|
|
auctionId,
|
|
reveal
|
|
}
|
|
};
|
|
|
|
const response = await this.signAndBroadcast(signer, [createMsg], fee, memo);
|
|
return this.parseResponse<MsgRevealBidResponse>(response);
|
|
}
|
|
|
|
public async setRecord (
|
|
params: { privateKey: string, record: any, bondId: string },
|
|
signer: string,
|
|
fee: StdFee | 'auto' | number,
|
|
memo = ''
|
|
) {
|
|
const registryRecord = Record.fromPartial({ attributes: Buffer.from(JSON.stringify(params.record), 'binary') });
|
|
|
|
// Sign record.
|
|
const recordSignerAccount = new Account(Buffer.from(params.privateKey, 'hex'));
|
|
await recordSignerAccount.init();
|
|
const messageToSign = Util.sortJSON(params.record);
|
|
const sig = await recordSignerAccount.signRecord(messageToSign);
|
|
|
|
const signature = Signature.fromJSON({ sig: sig.toString('base64'), pubKey: recordSignerAccount.registryPublicKey });
|
|
|
|
const payload = Payload.fromJSON({ record: registryRecord, signatures: [signature] });
|
|
|
|
const createMsg: MsgSetRecordEncodeObject = {
|
|
typeUrl: typeUrlMsgSetRecord,
|
|
value: {
|
|
signer,
|
|
bondId: params.bondId,
|
|
payload
|
|
}
|
|
};
|
|
|
|
const response = await this.signAndBroadcast(signer, [createMsg], fee, memo);
|
|
return this.parseResponse<MsgSetRecordResponse>(response);
|
|
}
|
|
|
|
public async setAuthorityBond (
|
|
signer: string,
|
|
bondId: string,
|
|
name: string,
|
|
fee: StdFee | 'auto' | number,
|
|
memo = ''
|
|
) {
|
|
const createMsg: MsgSetAuthorityBondEncodeObject = {
|
|
typeUrl: typeUrlMsgSetAuthorityBond,
|
|
value: {
|
|
signer,
|
|
bondId,
|
|
name
|
|
}
|
|
};
|
|
|
|
const response = await this.signAndBroadcast(signer, [createMsg], fee, memo);
|
|
return this.parseResponse<MsgSetAuthorityBondResponse>(response);
|
|
}
|
|
|
|
public async setName (
|
|
signer: string,
|
|
lrn: string,
|
|
cid: string,
|
|
fee: StdFee | 'auto' | number,
|
|
memo = ''
|
|
) {
|
|
const createMsg: MsgSetNameEncodeObject = {
|
|
typeUrl: typeUrlMsgSetName,
|
|
value: {
|
|
signer,
|
|
lrn,
|
|
cid
|
|
}
|
|
};
|
|
|
|
const response = await this.signAndBroadcast(signer, [createMsg], fee, memo);
|
|
return this.parseResponse<MsgSetNameResponse>(response);
|
|
}
|
|
|
|
public async deleteName (
|
|
signer: string,
|
|
lrn: string,
|
|
fee: StdFee | 'auto' | number,
|
|
memo = ''
|
|
) {
|
|
const createMsg: MsgDeleteNameEncodeObject = {
|
|
typeUrl: typeUrlMsgDeleteName,
|
|
value: {
|
|
signer,
|
|
lrn
|
|
}
|
|
};
|
|
|
|
const response = await this.signAndBroadcast(signer, [createMsg], fee, memo);
|
|
return this.parseResponse<MsgDeleteNameResponse>(response);
|
|
}
|
|
|
|
parseResponse<T> (response: DeliverTxResponse): T {
|
|
if (response.code !== 0) {
|
|
// Throw error when transaction is not successful.
|
|
throw new Error(this.processWriteError(response.rawLog || 'No raw log in response'));
|
|
}
|
|
|
|
return this.registry.decode(response.msgResponses[0]) as T;
|
|
}
|
|
|
|
processWriteError (error: string) {
|
|
const errorMessage = [...NAMESERVICE_ERRORS, ONBOARDING_DISABLED_ERROR].find(message => error.includes(message));
|
|
|
|
if (!errorMessage) {
|
|
console.error(error);
|
|
}
|
|
|
|
return `${errorMessage || DEFAULT_WRITE_ERROR}: ${error}`;
|
|
}
|
|
|
|
public async onboardParticipant (
|
|
signer: string,
|
|
ethPayload: EthPayload,
|
|
ethSignature: string,
|
|
role: string,
|
|
kycId: string,
|
|
fee: StdFee | 'auto' | number,
|
|
memo = ''
|
|
) {
|
|
const onboardParticipantMsg: MsgOnboardParticipantEncodeObject = {
|
|
typeUrl: typeUrlMsgOnboardParticipant,
|
|
value: {
|
|
participant: signer,
|
|
ethPayload,
|
|
ethSignature,
|
|
role,
|
|
kycId
|
|
}
|
|
};
|
|
|
|
const response = await this.signAndBroadcast(signer, [onboardParticipantMsg], fee, memo);
|
|
return this.parseResponse<MsgOnboardParticipantResponse>(response);
|
|
}
|
|
|
|
public async createAuction (
|
|
signer: string,
|
|
kind: string,
|
|
commitsDuration: string,
|
|
revealsDuration: string,
|
|
denom: string,
|
|
commitFee: string,
|
|
revealFee: string,
|
|
minimumBid: string,
|
|
maxPrice: string,
|
|
numProviders: number,
|
|
fee: StdFee | 'auto' | number,
|
|
memo = ''
|
|
) {
|
|
const createAuctionMsg: MsgCreateAuctionEncodeObject = {
|
|
typeUrl: typeUrlMsgCreateAuction,
|
|
value: {
|
|
signer,
|
|
kind,
|
|
commitsDuration: Duration.fromPartial({ seconds: Long.fromString(commitsDuration) }),
|
|
revealsDuration: Duration.fromPartial({ seconds: Long.fromString(revealsDuration) }),
|
|
commitFee: Coin.fromPartial({ amount: commitFee, denom }),
|
|
revealFee: Coin.fromPartial({ amount: revealFee, denom }),
|
|
minimumBid: Coin.fromPartial({ amount: minimumBid, denom }),
|
|
maxPrice: Coin.fromPartial({ amount: maxPrice, denom }),
|
|
numProviders
|
|
}
|
|
};
|
|
|
|
const response = await this.signAndBroadcast(signer, [createAuctionMsg], fee, memo);
|
|
return this.parseResponse<MsgCreateAuctionResponse>(response);
|
|
}
|
|
}
|