From 0bebb083dcb914aba0183bf75f4046665bf64002 Mon Sep 17 00:00:00 2001 From: Aaron Cox Date: Thu, 6 Jul 2023 00:00:32 -0700 Subject: [PATCH] Initial kit implementation --- Makefile | 2 +- package.json | 4 +- src/kit.ts | 79 ++++++++++++++++++++++++++++++++++++++- test/tests/kit.ts | 94 +++++++++++++++++++++++++++++++++++++++++++++++ yarn.lock | 18 ++++----- 5 files changed, 184 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index c33d96b..5120ea3 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ test/watch: node_modules ${BIN}/mocha --watch ${MOCHA_OPTS} ${TEST_FILES} --no-timeout --grep '$(grep)' build/coverage: ${SRC_FILES} ${TEST_FILES} node_modules - @TS_NODE_PROJECT='./test/tsconfig.json' \ + @TS_NODE_PROJECT='./test/tsconfig.json' MOCK_DIR='./test/data/requests' \ ${BIN}/nyc ${NYC_OPTS} --reporter=html \ ${BIN}/mocha ${MOCHA_OPTS} -R nyan ${TEST_FILES} diff --git a/package.json b/package.json index cf49a24..0d7b440 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,8 @@ "wharf-generate": "./scripts/codegen-cli.js" }, "dependencies": { - "@wharfkit/mock-data": "^1.0.0-beta8", - "@wharfkit/session": "^1.0.0-beta1", + "@wharfkit/mock-data": "^1.0.0-beta10", + "@wharfkit/session": "^1.0.0-beta3", "rollup-plugin-cleanup": "^3.2.1", "tslib": "^2.1.0" }, diff --git a/src/kit.ts b/src/kit.ts index a306664..ad5419a 100644 --- a/src/kit.ts +++ b/src/kit.ts @@ -1 +1,78 @@ -export class ContractKit {} +import { + ABI, + ABICache, + ABICacheInterface, + ABIDef, + APIClient, + Name, + NameType, + Session, +} from '@wharfkit/session' +import {Contract} from './contract' + +export interface ContractKitArgs { + client?: APIClient + session?: Session +} + +export interface ABIDefinition { + name: NameType + abi: ABIDef +} + +export interface ContractKitOptions { + abiCache?: ABICacheInterface + abis?: ABIDefinition[] +} + +const defaultContractKitOptions: ContractKitOptions = {} + +export class ContractKit { + readonly abiCache: ABICacheInterface + readonly client: APIClient + + constructor(args: ContractKitArgs, options: ContractKitOptions = defaultContractKitOptions) { + // Use either the client given or get it from the session. + if (args.client) { + this.client = args.client + } else if (args.session) { + this.client = args.session.client + } else { + throw new Error( + 'Either a `client` or `session` must be passed when initializing the ContractKit.' + ) + } + + // Use either the specified cache, the cache from the session, or create one + if (options.abiCache) { + this.abiCache = options.abiCache + } else if (args.session) { + this.abiCache = args.session.abiCache + } else { + this.abiCache = new ABICache(this.client) + } + + // If any ABIs are provided during construction, inject them into the cache + if (options.abis) { + options.abis.forEach(({name, abi}) => + this.abiCache.setAbi(Name.from(name), ABI.from(abi)) + ) + } + } + + /** + * Load a contract by name from an API endpoint + * + * @param contract The name of the contract to load + * @returns + */ + async load(contract: NameType): Promise { + const name = Name.from(contract) + const abiDef = await this.abiCache.getAbi(name) + return new Contract({ + abi: ABI.from(abiDef), + client: this.client, + name, + }) + } +} diff --git a/test/tests/kit.ts b/test/tests/kit.ts index e69de29..9bcc50f 100644 --- a/test/tests/kit.ts +++ b/test/tests/kit.ts @@ -0,0 +1,94 @@ +import {assert} from 'chai' + +import {Contract, ContractKit, ContractKitArgs, ContractKitOptions} from '$lib' +import {makeClient, mockSession} from '@wharfkit/mock-data' +import {ABI, ABICache, Name} from '@wharfkit/session' + +const mockClient = makeClient('https://jungle4.greymass.com') +const mockContractKitArgs: ContractKitArgs = { + client: mockClient, +} +const mockContractKitOptions: ContractKitOptions = {} + +suite('kit', function () { + suite('construct', function () { + test('defaults', function () { + const kit = new ContractKit(mockContractKitArgs) + assert.instanceOf(kit, ContractKit) + }) + test('throws if no client/session', function () { + assert.throws(() => new ContractKit({})) + }) + test('args: client', function () { + assert.doesNotThrow(() => { + const kit = new ContractKit({client: mockClient}) + assert.instanceOf(kit, ContractKit) + }) + }) + test('args: session', function () { + assert.doesNotThrow(() => { + const kit = new ContractKit({session: mockSession}) + assert.instanceOf(kit, ContractKit) + }) + }) + test('options: abiCache', function () { + const kit = new ContractKit(mockContractKitArgs, { + abiCache: new ABICache(mockClient), + }) + assert.instanceOf(kit, ContractKit) + assert.instanceOf(kit.abiCache, ABICache) + }) + suite('options: abis', function () { + test('untyped', async function () { + const kit = new ContractKit(mockContractKitArgs, { + abis: [ + { + name: 'foo', + abi: {version: 'eosio::abi/1.2'}, + }, + { + name: 'bar', + abi: {version: 'eosio::abi/1.2'}, + }, + ], + }) + assert.instanceOf(kit, ContractKit) + assert.equal(kit.abiCache.cache.size, 2) + const foo = await kit.load('foo') + assert.instanceOf(foo, Contract) + const bar = await kit.load('bar') + assert.instanceOf(bar, Contract) + }) + test('typed', async function () { + const kit = new ContractKit(mockContractKitArgs, { + abis: [ + { + name: Name.from('foo'), + abi: ABI.from({version: 'eosio::abi/1.2'}), + }, + { + name: Name.from('bar'), + abi: ABI.from({version: 'eosio::abi/1.2'}), + }, + ], + }) + assert.instanceOf(kit, ContractKit) + assert.equal(kit.abiCache.cache.size, 2) + const foo = await kit.load('foo') + assert.instanceOf(foo, Contract) + const bar = await kit.load('bar') + assert.instanceOf(bar, Contract) + }) + }) + }) + suite('load', function () { + let contractKit + setup(() => { + contractKit = new ContractKit(mockContractKitArgs) + }) + test('fetches abi', async function () { + const contract = await contractKit.load('eosio.token') + assert.instanceOf(contract, Contract) + }) + }) +}) diff --git a/yarn.lock b/yarn.lock index 0723bd3..15f8903 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1500,21 +1500,21 @@ "@typescript-eslint/types" "5.41.0" eslint-visitor-keys "^3.3.0" -"@wharfkit/mock-data@^1.0.0-beta8": - version "1.0.0-beta8" - resolved "https://registry.yarnpkg.com/@wharfkit/mock-data/-/mock-data-1.0.0-beta8.tgz#630c97630dbb3bbefdc3399ba8b2e550bd324f1c" - integrity sha512-YMPcHZDCdmhB0sG+jGrsE0BfdUlcEs7QQP+xLRp8/GrOAo7dbSJz3bftydlrgRKWbbDkFMYmFZlRtomgTps7vg== +"@wharfkit/mock-data@^1.0.0-beta10": + version "1.0.0-beta10" + resolved "https://registry.yarnpkg.com/@wharfkit/mock-data/-/mock-data-1.0.0-beta10.tgz#7271c3c397bffaa3b6b2f4726bff8d1917928f3f" + integrity sha512-zx4+X6NlHuvDV+0T00W3p3Ligwm8qREKO9focLhFSJ3Vwq/TOKv/wjUh8ZUowcBRixAnpnfIzbQpqQBlY+5VZw== dependencies: "@greymass/eosio" "^0.6.10" - "@wharfkit/session" "^1.0.0-beta1" + "@wharfkit/session" "^1.0.0-beta3" "@wharfkit/wallet-plugin-privatekey" "^0.5.0" node-fetch "^2.6.1" tslib "^2.1.0" -"@wharfkit/session@^1.0.0-beta1": - version "1.0.0-beta1" - resolved "https://registry.yarnpkg.com/@wharfkit/session/-/session-1.0.0-beta1.tgz#7ef02ee5beb237f4f6a84bd4cd27769468624c6d" - integrity sha512-GMYzoMHB/fh7i4N4J31t8k7HTU+Gq3rTlK8gX1D+bkfIAblkT4nIIK0K10p91NyaIwzyw/UQ/5DByojTDyBgPg== +"@wharfkit/session@^1.0.0-beta3": + version "1.0.0-beta3" + resolved "https://registry.yarnpkg.com/@wharfkit/session/-/session-1.0.0-beta3.tgz#b13b16d35529b7e79680805814b2c5197d3404e3" + integrity sha512-of/XBi0Cw9yIg19xxRi/uFDxAU5hR+YoX47Gm1ctAMMpALYA44lzVvudVHaY+qqwucNMtm0RxRLhqMHSNenxwA== dependencies: "@greymass/eosio" "^0.6.10" eosio-signing-request "^2.5.3"