Skip to content

Commit

Permalink
feat(tests): Added stable round of SDK tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Eengineer1 committed Jul 18, 2022
1 parent 441bfa3 commit fa31daa
Show file tree
Hide file tree
Showing 11 changed files with 297 additions and 38 deletions.
6 changes: 6 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
modulePathIgnorePatterns: ["tests/testutils.test.ts"],
};
130 changes: 123 additions & 7 deletions package-lock.json

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

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "A JavaScript SDK built with cosmjs to interact with cheqd network Cosmos-SDK Node & other compatible vendors.",
"main": "index.js",
"scripts": {
"test": "jest --verbose ./tests/unit"
"test": "jest"
},
"repository": {
"type": "git",
Expand All @@ -28,11 +28,12 @@
"@types/jest": "^28.1.4",
"@types/node": "^18.0.3",
"jest": "^28.1.2",
"ts-jest": "^28.0.6",
"ts-node": "^10.8.2",
"typescript": "^4.7.4"
},
"dependencies": {
"@cheqd/ts-proto": "1.0.0",
"@cheqd/ts-proto": "^1.0.1",
"@cosmjs/proto-signing": "^0.28.10",
"@cosmjs/stargate": "^0.28.10",
"@cosmjs/tendermint-rpc": "^0.28.10",
Expand Down
49 changes: 39 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { OfflineSigner } from '@cosmjs/proto-signing'
import { DIDModule } from './modules/did'
import { ResourcesModule } from './modules/resources'
import { AbstractCheqdSDKModule, applyMixins, } from './modules/_'
import { DIDModule, MinimalImportableDIDModule } from './modules/did'
import { MinimalImportableResourcesModule, ResourcesModule } from './modules/resources'
import { AbstractCheqdSDKModule, applyMixins, instantiateCheqdSDKModule, } from './modules/_'
import { CheqdSigningStargateClient } from './signer'
import { CheqdNetwork } from './types'
import { CheqdNetwork, IContext, IModuleMethodMap } from './types'

export interface ICheqdSDKOptions {
modules: AbstractCheqdSDKModule[]
Expand All @@ -13,13 +13,15 @@ export interface ICheqdSDKOptions {
readonly wallet: OfflineSigner
}

export interface CheqdSDK extends DIDModule, ResourcesModule {}
export type DefaultCheqdSDKModules = MinimalImportableDIDModule & MinimalImportableResourcesModule

export interface CheqdSDK extends DefaultCheqdSDKModules {}

export class CheqdSDK {
methods: string[]
methods: IModuleMethodMap
signer: CheqdSigningStargateClient
options: ICheqdSDKOptions
private protectedMethods: string[] = ['build', 'loadModules']
private protectedMethods: string[] = ['constructor', 'build', 'loadModules']

constructor(options: ICheqdSDKOptions) {
if (!options?.wallet) {
Expand All @@ -32,13 +34,29 @@ export class CheqdSDK {
...options
}

this.methods = this.options.authorizedMethods || []
this.methods = {}
this.signer = new CheqdSigningStargateClient(undefined, this.options.wallet, {})
}

async execute<P = any, R = any>(method: string, ...params: P[]): Promise<R> {
if (!Object.keys(this.methods).includes(method)) {
throw new Error(`Method ${method} is not authorized`)
}
return await this.methods[method](...params, { sdk: this } as IContext)
}

private loadModules(modules: AbstractCheqdSDKModule[]): CheqdSDK {
this.options.modules = this.options.modules.map((module: any) => instantiateCheqdSDKModule(module, this.signer, { sdk: this } as IContext) as unknown as AbstractCheqdSDKModule)

const methods = applyMixins(this, modules)
this.methods = this.methods.concat(methods)
this.methods = { ...this.methods, ...filterUnauthorizedMethods(methods, this.options.authorizedMethods || [], this.protectedMethods) }

for(const method of Object.keys(this.methods)) {
// @ts-ignore
this[method] = async (...params: any[]) => {
return await this.execute(method, ...params)
}
}

return this
}
Expand All @@ -48,12 +66,23 @@ export class CheqdSDK {
this.options.rpcUrl,
this.options.wallet
)
this.options.modules = this.options.modules.map(module => module.constructor(this.signer)) || []

return this.loadModules(this.options.modules)
}
}

export function filterUnauthorizedMethods(methods: IModuleMethodMap, authorizedMethods: string[], protectedMethods: string[]): IModuleMethodMap {
let _methods = Object.keys(methods)
if (authorizedMethods.length === 0)
return _methods
.filter(method => !protectedMethods.includes(method))
.reduce((acc, method) => ({ ...acc, [method]: methods[method] }), {})

return _methods
.filter(method => authorizedMethods.includes(method) && !protectedMethods.includes(method))
.reduce((acc, method) => ({ ...acc, [method]: methods[method] }), {})
}

export async function createCheqdSDK(options: ICheqdSDKOptions): Promise<CheqdSDK> {
return await (new CheqdSDK(options)).build()
}
Expand Down
33 changes: 20 additions & 13 deletions src/modules/_.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,41 @@
import { GeneratedType, Registry } from "@cosmjs/proto-signing";
import { QueryClient } from "@cosmjs/stargate";
import { CheqdSigningStargateClient } from '../signer'
import { IModuleMethodMap } from "../types";
import { setupDidExtension } from './did'

export abstract class AbstractCheqdSDKModule {
_signer: CheqdSigningStargateClient
methods: IModuleMethodMap = {}
readonly _protectedMethods: string[] = ['constructor', 'exportMethods', 'registryTypes']

constructor(signer: CheqdSigningStargateClient) {
if (!signer) {
throw new Error("signer is required");
throw new Error("signer is required")
}
this._signer = signer
}

static registryTypes(): Iterable<[string, GeneratedType]> {
return []
}
}

export type MinimalImportableCheqdSDKModule<T extends AbstractCheqdSDKModule> = Omit<T, '_signer' | '_protectedMethods'>

export function instantiateCheqdSDKModule<T extends new (...args: any[]) => T>(module: T, ...args: ConstructorParameters<T>): T {
return new module(...args)
}

export function applyMixins(derivedCtor: any, constructors: any[]): string[] {
let methods: string[] = []
export function applyMixins(derivedCtor: any, constructors: any[]): IModuleMethodMap {
let methods: IModuleMethodMap = {}

constructors.forEach((baseCtor) => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
const property = Object.getOwnPropertyDescriptor(baseCtor.prototype, name)
if (typeof property !== 'function' || name in derivedCtor.prototype || derivedCtor?.protectedMethods.includes(name)) return

Object.defineProperty(
derivedCtor.prototype,
name,
property ||
Object.create(null)
);
const property = baseCtor.prototype[name]
if (typeof property !== 'function' || derivedCtor.hasOwnProperty(name) || derivedCtor?.protectedMethods.includes(name) || baseCtor.prototype?._protectedMethods?.includes(name)) return

methods.push(name)
methods = { ...methods, [name]: property }
});
});

Expand Down

0 comments on commit fa31daa

Please sign in to comment.