From 5fc42e897aa96a6f2aded67c033f26f5744145b9 Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Mon, 29 Jul 2024 11:19:23 +0000 Subject: [PATCH] Add queries to get participant by laconic or nitro address (#16) Part of [laconicd testnet validator enrollment](https://www.notion.so/laconicd-testnet-validator-enrollment-6fc1d3cafcc64fef8c5ed3affa27c675) Co-authored-by: IshaVenikar Reviewed-on: https://git.vdb.to/cerc-io/registry-sdk/pulls/16 Co-authored-by: Prathamesh Musale Co-committed-by: Prathamesh Musale --- package.json | 2 +- proto/cerc/onboarding/v1/query.proto | 43 +++- src/index.ts | 14 ++ src/onboarding.test.ts | 43 ++-- src/proto/cerc/onboarding/v1/query.ts | 333 +++++++++++++++++++++++++- src/registry-client.ts | 40 ++++ 6 files changed, 456 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index 63a8da6..763e877 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cerc-io/registry-sdk", - "version": "0.2.3", + "version": "0.2.4", "main": "dist/index.js", "types": "dist/index.d.ts", "repository": "git@github.com:cerc-io/registry-sdk.git", diff --git a/proto/cerc/onboarding/v1/query.proto b/proto/cerc/onboarding/v1/query.proto index bbcfc87..f340d99 100644 --- a/proto/cerc/onboarding/v1/query.proto +++ b/proto/cerc/onboarding/v1/query.proto @@ -16,6 +16,19 @@ service Query { returns (QueryParticipantsResponse) { option (google.api.http).get = "/cerc/onboarding/v1/participants"; } + + // GetParticipantByAddress queries a participant by cosmos (laconic) address + rpc GetParticipantByAddress(QueryGetParticipantByAddressRequest) + returns (QueryGetParticipantByAddressResponse) { + option (google.api.http).get = "/cerc/onboarding/v1/participants/{address}"; + } + + // GetParticipantByNitroAddress queries a participant by nitro address + rpc GetParticipantByNitroAddress(QueryGetParticipantByNitroAddressRequest) + returns (QueryGetParticipantByNitroAddressResponse) { + option (google.api.http).get = + "/cerc/onboarding/v1/participants/{nitro_address}"; + } } // QueryParticipantsRequest queries participants @@ -24,7 +37,7 @@ message QueryParticipantsRequest { cosmos.base.query.v1beta1.PageRequest pagination = 1; } -// QueryParticipantsResponse is response type for get the participants +// QueryParticipantsResponse is response type for querying the participants message QueryParticipantsResponse { repeated Participant participants = 1 [ (gogoproto.moretags) = "json:\"participants\" yaml:\"participants\"" ]; @@ -32,3 +45,31 @@ message QueryParticipantsResponse { // pagination defines the pagination in the response. cosmos.base.query.v1beta1.PageResponse pagination = 2; } + +// QueryGetParticipantByAddressRequest queries participant by the laconic +// address +message QueryGetParticipantByAddressRequest { + // Laconic address + string address = 1; +} + +// QueryGetParticipantByAddressResponse is response type for querying +// participant by the laconic address +message QueryGetParticipantByAddressResponse { + // Participant details + Participant participant = 1; +} + +// QueryGetParticipantByNitroAddressRequest queries participant by the nitro +// address +message QueryGetParticipantByNitroAddressRequest { + // Nitro address + string nitro_address = 1; +} + +// QueryGetParticipantByNitroAddressResponse is response type for querying +// participant by the nitro address +message QueryGetParticipantByNitroAddressResponse { + // Participant details + Participant participant = 1; +} diff --git a/src/index.ts b/src/index.ts index cf586ae..692ebc5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -461,6 +461,20 @@ export class Registry { async getParticipants () { return this._client.getParticipants(); } + + /** + * Get participant by cosmos (laconic) address. + */ + async getParticipantByAddress (address: string) { + return this._client.getParticipantByAddress(address); + } + + /** + * Get participant by nitro address. + */ + async getParticipantByNitroAddress (nitroAddress: string) { + return this._client.getParticipantByNitroAddress(nitroAddress); + } } export { Account }; diff --git a/src/onboarding.test.ts b/src/onboarding.test.ts index 3c7c80e..ca51fd9 100644 --- a/src/onboarding.test.ts +++ b/src/onboarding.test.ts @@ -1,6 +1,6 @@ import { Wallet } from 'ethers'; -import { DirectSecp256k1Wallet } from '@cosmjs/proto-signing'; +import { DirectSecp256k1Wallet, AccountData as CosmosAccount } from '@cosmjs/proto-signing'; import { Registry, Account } from './index'; import { getConfig } from './testing/helper'; @@ -16,15 +16,30 @@ const DUMMY_KYC_ID = 'dummyKycId'; const onboardingEnabledTests = () => { let registry: Registry; let ethWallet: Wallet; + let cosmosWallet: CosmosAccount; + let expectedParticipants: Participant[] = []; beforeAll(async () => { registry = new Registry(gqlEndpoint, rpcEndpoint, chainId); - }); - test('Onboard participant.', async () => { const mnemonic = Account.generateMnemonic(); ethWallet = Wallet.fromMnemonic(mnemonic); + const account = new Account(Buffer.from(privateKey, 'hex')); + const cosmosAccount = await DirectSecp256k1Wallet.fromKey(account._privateKey, 'laconic'); + [cosmosWallet] = await cosmosAccount.getAccounts(); + + expectedParticipants = [ + { + cosmosAddress: cosmosWallet.address, + nitroAddress: ethWallet.address, + role: DUMMY_ROLE, + kycId: DUMMY_KYC_ID + } + ]; + }); + + test('Onboard participant.', async () => { const ethPayload = { address: ethWallet.address, msg: 'Message signed by ethereum private key' @@ -42,21 +57,19 @@ const onboardingEnabledTests = () => { }); test('Query participants.', async () => { - const account = new Account(Buffer.from(privateKey, 'hex')); - const cosmosAccount = await DirectSecp256k1Wallet.fromKey(account._privateKey, 'laconic'); - const [cosmosWallet] = await cosmosAccount.getAccounts(); - - const expectedParticipants: Participant[] = [ - { - cosmosAddress: cosmosWallet.address, - nitroAddress: ethWallet.address, - role: DUMMY_ROLE, - kycId: DUMMY_KYC_ID - } - ]; const participants = await registry.getParticipants(); expect(participants).toEqual(expectedParticipants); }); + + test('Query participant by address.', async () => { + const participant = await registry.getParticipantByAddress(cosmosWallet.address); + expect(participant).toEqual(expectedParticipants[0]); + }); + + test('Query participant by Nitro address.', async () => { + const participant = await registry.getParticipantByNitroAddress(ethWallet.address); + expect(participant).toEqual(expectedParticipants[0]); + }); }; const onboardingDisabledTests = () => { diff --git a/src/proto/cerc/onboarding/v1/query.ts b/src/proto/cerc/onboarding/v1/query.ts index 7c0d0e0..594be30 100644 --- a/src/proto/cerc/onboarding/v1/query.ts +++ b/src/proto/cerc/onboarding/v1/query.ts @@ -3,8 +3,8 @@ import { PageRequest, PageResponse, } from "../../../cosmos/base/query/v1beta1/pagination"; -import Long from "long"; import { Participant } from "./onboarding"; +import Long from "long"; import _m0 from "protobufjs/minimal"; export const protobufPackage = "cerc.onboarding.v1"; @@ -15,13 +15,49 @@ export interface QueryParticipantsRequest { pagination?: PageRequest; } -/** QueryParticipantsResponse is response type for get the participants */ +/** QueryParticipantsResponse is response type for querying the participants */ export interface QueryParticipantsResponse { participants: Participant[]; /** pagination defines the pagination in the response. */ pagination?: PageResponse; } +/** + * QueryGetParticipantByAddressRequest queries participant by the laconic + * address + */ +export interface QueryGetParticipantByAddressRequest { + /** Laconic address */ + address: string; +} + +/** + * QueryGetParticipantByAddressResponse is response type for querying + * participant by the laconic address + */ +export interface QueryGetParticipantByAddressResponse { + /** Participant details */ + participant?: Participant; +} + +/** + * QueryGetParticipantByNitroAddressRequest queries participant by the nitro + * address + */ +export interface QueryGetParticipantByNitroAddressRequest { + /** Nitro address */ + nitroAddress: string; +} + +/** + * QueryGetParticipantByNitroAddressResponse is response type for querying + * participant by the nitro address + */ +export interface QueryGetParticipantByNitroAddressResponse { + /** Participant details */ + participant?: Participant; +} + function createBaseQueryParticipantsRequest(): QueryParticipantsRequest { return { pagination: undefined }; } @@ -175,12 +211,273 @@ export const QueryParticipantsResponse = { }, }; +function createBaseQueryGetParticipantByAddressRequest(): QueryGetParticipantByAddressRequest { + return { address: "" }; +} + +export const QueryGetParticipantByAddressRequest = { + encode( + message: QueryGetParticipantByAddressRequest, + writer: _m0.Writer = _m0.Writer.create() + ): _m0.Writer { + if (message.address !== "") { + writer.uint32(10).string(message.address); + } + return writer; + }, + + decode( + input: _m0.Reader | Uint8Array, + length?: number + ): QueryGetParticipantByAddressRequest { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseQueryGetParticipantByAddressRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.address = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): QueryGetParticipantByAddressRequest { + return { + address: isSet(object.address) ? String(object.address) : "", + }; + }, + + toJSON(message: QueryGetParticipantByAddressRequest): unknown { + const obj: any = {}; + message.address !== undefined && (obj.address = message.address); + return obj; + }, + + fromPartial< + I extends Exact, I> + >(object: I): QueryGetParticipantByAddressRequest { + const message = createBaseQueryGetParticipantByAddressRequest(); + message.address = object.address ?? ""; + return message; + }, +}; + +function createBaseQueryGetParticipantByAddressResponse(): QueryGetParticipantByAddressResponse { + return { participant: undefined }; +} + +export const QueryGetParticipantByAddressResponse = { + encode( + message: QueryGetParticipantByAddressResponse, + writer: _m0.Writer = _m0.Writer.create() + ): _m0.Writer { + if (message.participant !== undefined) { + Participant.encode( + message.participant, + writer.uint32(10).fork() + ).ldelim(); + } + return writer; + }, + + decode( + input: _m0.Reader | Uint8Array, + length?: number + ): QueryGetParticipantByAddressResponse { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseQueryGetParticipantByAddressResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.participant = Participant.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): QueryGetParticipantByAddressResponse { + return { + participant: isSet(object.participant) + ? Participant.fromJSON(object.participant) + : undefined, + }; + }, + + toJSON(message: QueryGetParticipantByAddressResponse): unknown { + const obj: any = {}; + message.participant !== undefined && + (obj.participant = message.participant + ? Participant.toJSON(message.participant) + : undefined); + return obj; + }, + + fromPartial< + I extends Exact, I> + >(object: I): QueryGetParticipantByAddressResponse { + const message = createBaseQueryGetParticipantByAddressResponse(); + message.participant = + object.participant !== undefined && object.participant !== null + ? Participant.fromPartial(object.participant) + : undefined; + return message; + }, +}; + +function createBaseQueryGetParticipantByNitroAddressRequest(): QueryGetParticipantByNitroAddressRequest { + return { nitroAddress: "" }; +} + +export const QueryGetParticipantByNitroAddressRequest = { + encode( + message: QueryGetParticipantByNitroAddressRequest, + writer: _m0.Writer = _m0.Writer.create() + ): _m0.Writer { + if (message.nitroAddress !== "") { + writer.uint32(10).string(message.nitroAddress); + } + return writer; + }, + + decode( + input: _m0.Reader | Uint8Array, + length?: number + ): QueryGetParticipantByNitroAddressRequest { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseQueryGetParticipantByNitroAddressRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.nitroAddress = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): QueryGetParticipantByNitroAddressRequest { + return { + nitroAddress: isSet(object.nitroAddress) + ? String(object.nitroAddress) + : "", + }; + }, + + toJSON(message: QueryGetParticipantByNitroAddressRequest): unknown { + const obj: any = {}; + message.nitroAddress !== undefined && + (obj.nitroAddress = message.nitroAddress); + return obj; + }, + + fromPartial< + I extends Exact, I> + >(object: I): QueryGetParticipantByNitroAddressRequest { + const message = createBaseQueryGetParticipantByNitroAddressRequest(); + message.nitroAddress = object.nitroAddress ?? ""; + return message; + }, +}; + +function createBaseQueryGetParticipantByNitroAddressResponse(): QueryGetParticipantByNitroAddressResponse { + return { participant: undefined }; +} + +export const QueryGetParticipantByNitroAddressResponse = { + encode( + message: QueryGetParticipantByNitroAddressResponse, + writer: _m0.Writer = _m0.Writer.create() + ): _m0.Writer { + if (message.participant !== undefined) { + Participant.encode( + message.participant, + writer.uint32(10).fork() + ).ldelim(); + } + return writer; + }, + + decode( + input: _m0.Reader | Uint8Array, + length?: number + ): QueryGetParticipantByNitroAddressResponse { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseQueryGetParticipantByNitroAddressResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.participant = Participant.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): QueryGetParticipantByNitroAddressResponse { + return { + participant: isSet(object.participant) + ? Participant.fromJSON(object.participant) + : undefined, + }; + }, + + toJSON(message: QueryGetParticipantByNitroAddressResponse): unknown { + const obj: any = {}; + message.participant !== undefined && + (obj.participant = message.participant + ? Participant.toJSON(message.participant) + : undefined); + return obj; + }, + + fromPartial< + I extends Exact, I> + >(object: I): QueryGetParticipantByNitroAddressResponse { + const message = createBaseQueryGetParticipantByNitroAddressResponse(); + message.participant = + object.participant !== undefined && object.participant !== null + ? Participant.fromPartial(object.participant) + : undefined; + return message; + }, +}; + /** Query defines the gRPC querier service for onboarding module */ export interface Query { /** Participants queries Participants list */ Participants( request: QueryParticipantsRequest ): Promise; + /** GetParticipantByAddress queries a participant by cosmos (laconic) address */ + GetParticipantByAddress( + request: QueryGetParticipantByAddressRequest + ): Promise; + /** GetParticipantByNitroAddress queries a participant by nitro address */ + GetParticipantByNitroAddress( + request: QueryGetParticipantByNitroAddressRequest + ): Promise; } export class QueryClientImpl implements Query { @@ -188,6 +485,9 @@ export class QueryClientImpl implements Query { constructor(rpc: Rpc) { this.rpc = rpc; this.Participants = this.Participants.bind(this); + this.GetParticipantByAddress = this.GetParticipantByAddress.bind(this); + this.GetParticipantByNitroAddress = + this.GetParticipantByNitroAddress.bind(this); } Participants( request: QueryParticipantsRequest @@ -202,6 +502,35 @@ export class QueryClientImpl implements Query { QueryParticipantsResponse.decode(new _m0.Reader(data)) ); } + + GetParticipantByAddress( + request: QueryGetParticipantByAddressRequest + ): Promise { + const data = QueryGetParticipantByAddressRequest.encode(request).finish(); + const promise = this.rpc.request( + "cerc.onboarding.v1.Query", + "GetParticipantByAddress", + data + ); + return promise.then((data) => + QueryGetParticipantByAddressResponse.decode(new _m0.Reader(data)) + ); + } + + GetParticipantByNitroAddress( + request: QueryGetParticipantByNitroAddressRequest + ): Promise { + const data = + QueryGetParticipantByNitroAddressRequest.encode(request).finish(); + const promise = this.rpc.request( + "cerc.onboarding.v1.Query", + "GetParticipantByNitroAddress", + data + ); + return promise.then((data) => + QueryGetParticipantByNitroAddressResponse.decode(new _m0.Reader(data)) + ); + } } interface Rpc { diff --git a/src/registry-client.ts b/src/registry-client.ts index 5191be2..31d8073 100644 --- a/src/registry-client.ts +++ b/src/registry-client.ts @@ -435,4 +435,44 @@ export class RegistryClient { return RegistryClient.getResult(this._graph(query)(variables), 'getParticipants'); } + + /** + * Get participant by cosmos address. + */ + async getParticipantByAddress (address: string) { + const query = `query ($address: String!) { + getParticipantByAddress (address: $address) { + cosmosAddress + nitroAddress + role + kycId + } + }`; + + const variables = { + address + }; + + return RegistryClient.getResult(this._graph(query)(variables), 'getParticipantByAddress'); + } + + /** + * Get participant by nitro address. + */ + async getParticipantByNitroAddress (nitroAddress: string) { + const query = `query ($nitroAddress: String!) { + getParticipantByNitroAddress (nitroAddress: $nitroAddress) { + cosmosAddress + nitroAddress + role + kycId + } + }`; + + const variables = { + nitroAddress + }; + + return RegistryClient.getResult(this._graph(query)(variables), 'getParticipantByNitroAddress'); + } }