Add a method to get registered participants (#6)

* Add getParticipant query method for getting participants list

* Add check to verify the list of registered participants in onboarding-test

* Modify test messages

* Add updated proto files and regenerate ts bindings

* Update proto files and regenerate ts bindings

* Fix imports
This commit is contained in:
Isha Venikar 2024-07-04 19:33:10 +05:30 committed by GitHub
parent f2e1a1bd4a
commit 51fed6aa62
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 357 additions and 35 deletions

View File

@ -7,7 +7,11 @@ import "gogoproto/gogo.proto";
option go_package = "git.vdb.to/cerc-io/laconicd/x/onboarding"; option go_package = "git.vdb.to/cerc-io/laconicd/x/onboarding";
// Params defines the parameters of the onboarding module. // Params defines the parameters of the onboarding module.
message Params {} message Params {
bool onboarding_enabled = 1 [
(gogoproto.moretags) = "json:\"onboarding_enabled\" yaml:\"onboarding_enabled\""
];
}
// Participant defines the data that will be stored for each enrolled participant // Participant defines the data that will be stored for each enrolled participant
message Participant { message Participant {

View File

@ -2,4 +2,32 @@ syntax = "proto3";
package cerc.onboarding.v1; package cerc.onboarding.v1;
import "gogoproto/gogo.proto";
import "cosmos/base/query/v1beta1/pagination.proto";
import "cerc/onboarding/v1/onboarding.proto";
import "google/api/annotations.proto";
option go_package = "git.vdb.to/cerc-io/laconicd/x/onboarding"; option go_package = "git.vdb.to/cerc-io/laconicd/x/onboarding";
// Query defines the gRPC querier service for onboarding module
service Query {
// Participants queries Participants list
rpc Participants(QueryParticipantsRequest) returns (QueryParticipantsResponse) {
option (google.api.http).get = "/cerc/onboarding/v1/participants";
}
}
// QueryParticipantsRequest queries participants
message QueryParticipantsRequest {
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 1;
}
// QueryParticipantsResponse is response type for get the participants
message QueryParticipantsResponse {
repeated Participant participants = 1
[ (gogoproto.moretags) = "json:\"participants\" yaml:\"participants\"" ];
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

View File

@ -3,8 +3,8 @@ syntax = "proto3";
package cerc.onboarding.v1; package cerc.onboarding.v1;
import "cosmos/msg/v1/msg.proto"; import "cosmos/msg/v1/msg.proto";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto"; import "google/api/annotations.proto";
import "gogoproto/gogo.proto";
import "cerc/onboarding/v1/onboarding.proto"; import "cerc/onboarding/v1/onboarding.proto";
option go_package = "git.vdb.to/cerc-io/laconicd/x/onboarding"; option go_package = "git.vdb.to/cerc-io/laconicd/x/onboarding";
@ -28,7 +28,6 @@ message MsgOnboardParticipant {
string participant = 1; string participant = 1;
EthPayload eth_payload = 2 [ (gogoproto.nullable) = false ]; EthPayload eth_payload = 2 [ (gogoproto.nullable) = false ];
string eth_signature = 3; string eth_signature = 3;
string message = 4;
} }
// MsgOnboardParticipantResponse defines the Msg/OnboardParticipant response type. // MsgOnboardParticipantResponse defines the Msg/OnboardParticipant response type.

View File

@ -453,6 +453,13 @@ export class Registry {
fee fee
); );
} }
/**
* Query participants.
*/
async getParticipants () {
return this._client.getParticipants();
}
} }
export { Account }; export { Account };

View File

@ -1,5 +1,7 @@
import { Wallet } from 'ethers'; import { Wallet } from 'ethers';
import { DirectSecp256k1Wallet } from '@cosmjs/proto-signing';
import { Registry, Account } from './index'; import { Registry, Account } from './index';
import { getConfig } from './testing/helper'; import { getConfig } from './testing/helper';
@ -9,31 +11,46 @@ jest.setTimeout(90 * 1000);
const onboardingTests = () => { const onboardingTests = () => {
let registry: Registry; let registry: Registry;
let ethWallet: Wallet;
beforeAll(async () => { beforeAll(async () => {
registry = new Registry(gqlEndpoint, rpcEndpoint, chainId); registry = new Registry(gqlEndpoint, rpcEndpoint, chainId);
}); });
test('Onboard participant.', async () => { test('Onboard participant.', async () => {
const mnenonic = Account.generateMnemonic(); const mnemonic = Account.generateMnemonic();
let wallet = Wallet.fromMnemonic(mnenonic); ethWallet = Wallet.fromMnemonic(mnemonic);
const ethPayload = { const ethPayload = {
address: wallet.address, address: ethWallet.address,
msg: 'Message signed by ethereum private key' msg: 'Message signed by ethereum private key'
}; };
const message = JSON.stringify(ethPayload); const message = JSON.stringify(ethPayload);
const ethSignature = await ethWallet.signMessage(message);
const ethSignature = await wallet.signMessage(message);
await registry.onboardParticipant({ await registry.onboardParticipant({
ethPayload, ethPayload,
ethSignature, ethSignature,
message: 'Message signed by cosmos private key' message: 'Message signed by cosmos private key'
}, privateKey, fee); }, privateKey, fee);
});
// TODO: Verify participant getting stored in state describe('With participants enrolled', () => {
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 = [
{
cosmos_address: cosmosWallet.address,
ethereum_address: ethWallet.address
}
];
const participants = await registry.getParticipants();
expect(participants).toEqual(expectedParticipants);
});
}); });
}; };

View File

@ -5,7 +5,9 @@ import _m0 from "protobufjs/minimal";
export const protobufPackage = "cerc.onboarding.v1"; export const protobufPackage = "cerc.onboarding.v1";
/** Params defines the parameters of the onboarding module. */ /** Params defines the parameters of the onboarding module. */
export interface Params {} export interface Params {
onboardingEnabled: boolean;
}
/** Participant defines the data that will be stored for each enrolled participant */ /** Participant defines the data that will be stored for each enrolled participant */
export interface Participant { export interface Participant {
@ -20,11 +22,17 @@ export interface EthPayload {
} }
function createBaseParams(): Params { function createBaseParams(): Params {
return {}; return { onboardingEnabled: false };
} }
export const Params = { export const Params = {
encode(_: Params, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { encode(
message: Params,
writer: _m0.Writer = _m0.Writer.create()
): _m0.Writer {
if (message.onboardingEnabled === true) {
writer.uint32(8).bool(message.onboardingEnabled);
}
return writer; return writer;
}, },
@ -35,6 +43,9 @@ export const Params = {
while (reader.pos < end) { while (reader.pos < end) {
const tag = reader.uint32(); const tag = reader.uint32();
switch (tag >>> 3) { switch (tag >>> 3) {
case 1:
message.onboardingEnabled = reader.bool();
break;
default: default:
reader.skipType(tag & 7); reader.skipType(tag & 7);
break; break;
@ -43,17 +54,24 @@ export const Params = {
return message; return message;
}, },
fromJSON(_: any): Params { fromJSON(object: any): Params {
return {}; return {
onboardingEnabled: isSet(object.onboardingEnabled)
? Boolean(object.onboardingEnabled)
: false,
};
}, },
toJSON(_: Params): unknown { toJSON(message: Params): unknown {
const obj: any = {}; const obj: any = {};
message.onboardingEnabled !== undefined &&
(obj.onboardingEnabled = message.onboardingEnabled);
return obj; return obj;
}, },
fromPartial<I extends Exact<DeepPartial<Params>, I>>(_: I): Params { fromPartial<I extends Exact<DeepPartial<Params>, I>>(object: I): Params {
const message = createBaseParams(); const message = createBaseParams();
message.onboardingEnabled = object.onboardingEnabled ?? false;
return message; return message;
}, },
}; };

View File

@ -1,2 +1,250 @@
/* eslint-disable */ /* eslint-disable */
import {
PageRequest,
PageResponse,
} from "../../../cosmos/base/query/v1beta1/pagination";
import Long from "long";
import { Participant } from "./onboarding";
import _m0 from "protobufjs/minimal";
export const protobufPackage = "cerc.onboarding.v1"; export const protobufPackage = "cerc.onboarding.v1";
/** QueryParticipantsRequest queries participants */
export interface QueryParticipantsRequest {
/** pagination defines an optional pagination for the request. */
pagination?: PageRequest;
}
/** QueryParticipantsResponse is response type for get the participants */
export interface QueryParticipantsResponse {
participants: Participant[];
/** pagination defines the pagination in the response. */
pagination?: PageResponse;
}
function createBaseQueryParticipantsRequest(): QueryParticipantsRequest {
return { pagination: undefined };
}
export const QueryParticipantsRequest = {
encode(
message: QueryParticipantsRequest,
writer: _m0.Writer = _m0.Writer.create()
): _m0.Writer {
if (message.pagination !== undefined) {
PageRequest.encode(message.pagination, writer.uint32(10).fork()).ldelim();
}
return writer;
},
decode(
input: _m0.Reader | Uint8Array,
length?: number
): QueryParticipantsRequest {
const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseQueryParticipantsRequest();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
message.pagination = PageRequest.decode(reader, reader.uint32());
break;
default:
reader.skipType(tag & 7);
break;
}
}
return message;
},
fromJSON(object: any): QueryParticipantsRequest {
return {
pagination: isSet(object.pagination)
? PageRequest.fromJSON(object.pagination)
: undefined,
};
},
toJSON(message: QueryParticipantsRequest): unknown {
const obj: any = {};
message.pagination !== undefined &&
(obj.pagination = message.pagination
? PageRequest.toJSON(message.pagination)
: undefined);
return obj;
},
fromPartial<I extends Exact<DeepPartial<QueryParticipantsRequest>, I>>(
object: I
): QueryParticipantsRequest {
const message = createBaseQueryParticipantsRequest();
message.pagination =
object.pagination !== undefined && object.pagination !== null
? PageRequest.fromPartial(object.pagination)
: undefined;
return message;
},
};
function createBaseQueryParticipantsResponse(): QueryParticipantsResponse {
return { participants: [], pagination: undefined };
}
export const QueryParticipantsResponse = {
encode(
message: QueryParticipantsResponse,
writer: _m0.Writer = _m0.Writer.create()
): _m0.Writer {
for (const v of message.participants) {
Participant.encode(v!, writer.uint32(10).fork()).ldelim();
}
if (message.pagination !== undefined) {
PageResponse.encode(
message.pagination,
writer.uint32(18).fork()
).ldelim();
}
return writer;
},
decode(
input: _m0.Reader | Uint8Array,
length?: number
): QueryParticipantsResponse {
const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseQueryParticipantsResponse();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
message.participants.push(
Participant.decode(reader, reader.uint32())
);
break;
case 2:
message.pagination = PageResponse.decode(reader, reader.uint32());
break;
default:
reader.skipType(tag & 7);
break;
}
}
return message;
},
fromJSON(object: any): QueryParticipantsResponse {
return {
participants: Array.isArray(object?.participants)
? object.participants.map((e: any) => Participant.fromJSON(e))
: [],
pagination: isSet(object.pagination)
? PageResponse.fromJSON(object.pagination)
: undefined,
};
},
toJSON(message: QueryParticipantsResponse): unknown {
const obj: any = {};
if (message.participants) {
obj.participants = message.participants.map((e) =>
e ? Participant.toJSON(e) : undefined
);
} else {
obj.participants = [];
}
message.pagination !== undefined &&
(obj.pagination = message.pagination
? PageResponse.toJSON(message.pagination)
: undefined);
return obj;
},
fromPartial<I extends Exact<DeepPartial<QueryParticipantsResponse>, I>>(
object: I
): QueryParticipantsResponse {
const message = createBaseQueryParticipantsResponse();
message.participants =
object.participants?.map((e) => Participant.fromPartial(e)) || [];
message.pagination =
object.pagination !== undefined && object.pagination !== null
? PageResponse.fromPartial(object.pagination)
: undefined;
return message;
},
};
/** Query defines the gRPC querier service for onboarding module */
export interface Query {
/** Participants queries Participants list */
Participants(
request: QueryParticipantsRequest
): Promise<QueryParticipantsResponse>;
}
export class QueryClientImpl implements Query {
private readonly rpc: Rpc;
constructor(rpc: Rpc) {
this.rpc = rpc;
this.Participants = this.Participants.bind(this);
}
Participants(
request: QueryParticipantsRequest
): Promise<QueryParticipantsResponse> {
const data = QueryParticipantsRequest.encode(request).finish();
const promise = this.rpc.request(
"cerc.onboarding.v1.Query",
"Participants",
data
);
return promise.then((data) =>
QueryParticipantsResponse.decode(new _m0.Reader(data))
);
}
}
interface Rpc {
request(
service: string,
method: string,
data: Uint8Array
): Promise<Uint8Array>;
}
type Builtin =
| Date
| Function
| Uint8Array
| string
| number
| boolean
| undefined;
export type DeepPartial<T> = T extends Builtin
? T
: T extends Long
? string | number | Long
: T extends Array<infer U>
? Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U>
? ReadonlyArray<DeepPartial<U>>
: T extends {}
? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
type KeysOfUnion<T> = T extends T ? keyof T : never;
export type Exact<P, I extends P> = P extends Builtin
? P
: P & { [K in keyof P]: Exact<P[K], I[K]> } & {
[K in Exclude<keyof I, KeysOfUnion<P>>]: never;
};
if (_m0.util.Long !== Long) {
_m0.util.Long = Long as any;
_m0.configure();
}
function isSet(value: any): boolean {
return value !== null && value !== undefined;
}

View File

@ -11,19 +11,13 @@ export interface MsgOnboardParticipant {
participant: string; participant: string;
ethPayload?: EthPayload; ethPayload?: EthPayload;
ethSignature: string; ethSignature: string;
message: string;
} }
/** MsgOnboardParticipantResponse defines the Msg/OnboardParticipant response type. */ /** MsgOnboardParticipantResponse defines the Msg/OnboardParticipant response type. */
export interface MsgOnboardParticipantResponse {} export interface MsgOnboardParticipantResponse {}
function createBaseMsgOnboardParticipant(): MsgOnboardParticipant { function createBaseMsgOnboardParticipant(): MsgOnboardParticipant {
return { return { participant: "", ethPayload: undefined, ethSignature: "" };
participant: "",
ethPayload: undefined,
ethSignature: "",
message: "",
};
} }
export const MsgOnboardParticipant = { export const MsgOnboardParticipant = {
@ -40,9 +34,6 @@ export const MsgOnboardParticipant = {
if (message.ethSignature !== "") { if (message.ethSignature !== "") {
writer.uint32(26).string(message.ethSignature); writer.uint32(26).string(message.ethSignature);
} }
if (message.message !== "") {
writer.uint32(34).string(message.message);
}
return writer; return writer;
}, },
@ -65,9 +56,6 @@ export const MsgOnboardParticipant = {
case 3: case 3:
message.ethSignature = reader.string(); message.ethSignature = reader.string();
break; break;
case 4:
message.message = reader.string();
break;
default: default:
reader.skipType(tag & 7); reader.skipType(tag & 7);
break; break;
@ -85,7 +73,6 @@ export const MsgOnboardParticipant = {
ethSignature: isSet(object.ethSignature) ethSignature: isSet(object.ethSignature)
? String(object.ethSignature) ? String(object.ethSignature)
: "", : "",
message: isSet(object.message) ? String(object.message) : "",
}; };
}, },
@ -99,7 +86,6 @@ export const MsgOnboardParticipant = {
: undefined); : undefined);
message.ethSignature !== undefined && message.ethSignature !== undefined &&
(obj.ethSignature = message.ethSignature); (obj.ethSignature = message.ethSignature);
message.message !== undefined && (obj.message = message.message);
return obj; return obj;
}, },
@ -113,7 +99,6 @@ export const MsgOnboardParticipant = {
? EthPayload.fromPartial(object.ethPayload) ? EthPayload.fromPartial(object.ethPayload)
: undefined; : undefined;
message.ethSignature = object.ethSignature ?? ""; message.ethSignature = object.ethSignature ?? "";
message.message = object.message ?? "";
return message; return message;
}, },
}; };

View File

@ -397,7 +397,7 @@ export class RegistryClient {
} }
/** /**
* Get records by attributes. * Get bonds by attributes.
*/ */
async queryBonds (attributes = {}) { async queryBonds (attributes = {}) {
const query = `query ($attributes: [KeyValueInput!]) { const query = `query ($attributes: [KeyValueInput!]) {
@ -417,4 +417,20 @@ export class RegistryClient {
return RegistryClient.getResult(this._graph(query)(variables), 'queryBonds'); return RegistryClient.getResult(this._graph(query)(variables), 'queryBonds');
} }
/**
* Get participants.
*/
async getParticipants () {
const query = `query {
getParticipants {
cosmos_address
ethereum_address
}
}`;
const variables = {};
return RegistryClient.getResult(this._graph(query)(variables), 'getParticipants');
}
} }

View File

@ -7,4 +7,4 @@ record:
/: QmP8jTG1m9GSDJLCbeWhVSVgEzCPPwXRdCRuJtQ5Tz9Kc9 /: QmP8jTG1m9GSDJLCbeWhVSVgEzCPPwXRdCRuJtQ5Tz9Kc9
tls_cert_cid: tls_cert_cid:
/: QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR /: QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR
version: 1.0.28 version: 1.0.30