Skip to content

Commit

Permalink
Merge pull request #40 from cosmos-client/recursive-unpack
Browse files Browse the repository at this point in the history
feat: unpack-spec
  • Loading branch information
kimurayu45z authored Jul 19, 2021
2 parents df5655b + b45f8d3 commit 583dfac
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 12 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe('bank', () => {
// get account info
const account = await rest.cosmos.auth
.account(sdk, fromAddress)
.then((res) => res.data.account && cosmosclient.codec.unpackAny(res.data.account))
.then((res) => res.data.account && cosmosclient.codec.unpackCosmosAny(res.data.account))
.catch((_) => undefined);

if (!(account instanceof cosmos.auth.v1beta1.BaseAccount)) {
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "cosmos-client",
"description": "REST API Client for Cosmos SDK Blockchain",
"version": "0.42.10",
"version": "0.42.11",
"author": "LCNEM, Inc.",
"bugs": {
"url": "https://github.com/cosmos-client/cosmos-client-ts/issues"
Expand Down
2 changes: 1 addition & 1 deletion src/rest/cosmos/bank/bank.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('bank', () => {
// get account info
const account = await rest.cosmos.auth
.account(sdk, fromAddress)
.then((res) => res.data.account && cosmosclient.codec.unpackAny(res.data.account))
.then((res) => res.data.account && cosmosclient.codec.unpackCosmosAny(res.data.account))
.catch((_) => undefined);

if (!(account instanceof cosmos.auth.v1beta1.BaseAccount)) {
Expand Down
72 changes: 72 additions & 0 deletions src/types/codec/codec.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { codec } from '.';
import { cosmos } from '../../proto';
import '../..';

describe('codec', () => {
it('unpack', () => {
expect.hasAssertions();
const res = {
data: {
account: {
'@type': '/cosmos.auth.v1beta1.BaseAccount',
address: 'jpyx10lcj22kzftvnduchatmnsnhfljeky5ghd398wt',
pub_key: { '@type': '/cosmos.crypto.secp256k1.PubKey', key: 'AvSf2U/B23UZKvLTD0E4xqJ33Nn0Z552nXCkkwEfleiu' },
account_number: '0',
sequence: '13',
},
},
status: 200,
statusText: 'OK',
headers: { 'content-length': '315', 'content-type': 'application/json' },
config: {
url: 'http://a.test.jpyx.lcnem.net:1317/cosmos/auth/v1beta1/accounts/jpyx10lcj22kzftvnduchatmnsnhfljeky5ghd398wt',
method: 'get',
headers: { Accept: 'application/json, text/plain, */*' },
transformRequest: [null],
transformResponse: [null],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
},
request: {
__zone_symbol__xhrSync: false,
__zone_symbol__xhrURL: 'http://a.test.jpyx.lcnem.net:1317/cosmos/auth/v1beta1/accounts/jpyx10lcj22kzftvnduchatmnsnhfljeky5ghd398wt',
__zone_symbol__readystatechangefalse: [
{
type: 'eventTask',
state: 'scheduled',
source: 'XMLHttpRequest.addEventListener:readystatechange',
zone: 'angular',
runCount: 6,
},
],
__zone_symbol__abortfalse: [
{ type: 'eventTask', state: 'scheduled', source: 'XMLHttpRequest.addEventListener:abort', zone: 'angular', runCount: 0 },
],
__zone_symbol__errorfalse: [
{ type: 'eventTask', state: 'scheduled', source: 'XMLHttpRequest.addEventListener:error', zone: 'angular', runCount: 0 },
],
__zone_symbol__timeoutfalse: [
{ type: 'eventTask', state: 'scheduled', source: 'XMLHttpRequest.addEventListener:timeout', zone: 'angular', runCount: 0 },
],
__zone_symbol__xhrScheduled: true,
__zone_symbol__xhrErrorBeforeScheduled: false,
__zone_symbol__xhrTask: { type: 'macroTask', state: 'notScheduled', source: 'XMLHttpRequest.send', zone: 'angular', runCount: 0 },
},
};

const unpacked = codec.unpackCosmosAny(res.data.account);
if (!(unpacked instanceof cosmos.auth.v1beta1.BaseAccount)) {
throw Error('');
}

console.log(unpacked);

const key = codec.unpackAny(unpacked.pub_key);
console.log(key)

expect(true).toBeTruthy();
});
});
4 changes: 4 additions & 0 deletions src/types/codec/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import * as $protobuf from 'protobufjs';

export const codecMaps = {
inv: new Map<Function, string>(),
encode: {} as { [type: string]: (value: any) => $protobuf.Writer },
decode: {} as { [type: string]: (value: Uint8Array) => unknown },
fromObject: {} as { [type: string]: (value: any) => unknown },
};
72 changes: 65 additions & 7 deletions src/types/codec/module.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,83 @@
import { config } from '../../config';
import { google } from '../../proto';
import * as $protobuf from 'protobufjs';

export function register(type: string, constructor: Function & { fromObject(object: any): any }) {
export function register(
type: string,
constructor: Function & { encode(value: any): $protobuf.Writer; decode(value: Uint8Array): unknown; fromObject(object: any): any },
) {
config.codecMaps.inv.set(constructor, type);
config.codecMaps.encode[type] = constructor.encode;
config.codecMaps.decode[type] = constructor.decode;
config.codecMaps.fromObject[type] = constructor.fromObject;
}

export function unpackAny(value: any) {
/**
* CosmosAny -> Instance
* @param value
* @returns
*/
export function unpackCosmosAny(value: any): unknown {
const newValue: { [key: string]: any } = {};

for (const key in value) {
newValue[key] = packCosmosAny(value[key]);
}

const typeURL = value && value['@type'];

if (!typeURL) {
throw Error("The field '@type' is undefined");
if (!typeURL || !config.codecMaps.fromObject[typeURL]) {
return newValue;
}

if (!config.codecMaps.fromObject[typeURL]) {
throw Error('This type is not registered');
return config.codecMaps.fromObject[typeURL](newValue);
}

/**
* CosmosAny -> Any
* @param value
*/
export function packCosmosAny(value: any) {
const typeURL = value && value['@type'];

if (!typeURL || !config.codecMaps.fromObject[typeURL]) {
return value;
}

return config.codecMaps.fromObject[typeURL](value);
const newValue: { [key: string]: any } = {};

for (const key in value) {
newValue[key] = packCosmosAny(value[key]);
}

return new google.protobuf.Any({
type_url: typeURL,
value: config.codecMaps.encode[typeURL](config.codecMaps.fromObject[typeURL](newValue)).finish(),
});
}

/**
* Any -> Instance
* @param value
*/
export function unpackAny(value?: google.protobuf.IAny | null) {
if (!value) {
throw Error("Object 'value' is undefined");
}
if (!value.type_url) {
throw Error("The field 'type_url' is undefined");
}
if (!value.value) {
throw Error("The field 'value' is undefined");
}
return config.codecMaps.decode[value.type_url](value.value);
}

/**
* Instance -> Any
* @param value
* @returns
*/
export function packAny(value: any) {
const constructor = value?.constructor;

Expand Down

0 comments on commit 583dfac

Please sign in to comment.