diff --git a/.eslintrc b/.eslintrc index c44a2dc4..e8305310 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,6 +1,6 @@ { "root": true, - "ignorePatterns": ["lib/*", "node_modules/**"], + "ignorePatterns": ["lib/*", "tests/*", "node_modules/**"], "extends": [ "eslint:recommended", "plugin:@typescript-eslint/eslint-recommended", diff --git a/Makefile b/Makefile index cd797f5c..ba7fdca3 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ lib: ${SRC_FILES} package.json tsconfig.json node_modules rollup.config.js .PHONY: test test: node_modules - @TS_NODE_PROJECT='./test/tsconfig.json' \ + @TS_NODE_PROJECT='./test/tsconfig.json' MOCK_DIR='./test/data' \ ${BIN}/mocha ${MOCHA_OPTS} ${TEST_FILES} --no-timeout --grep '$(grep)' test/watch: node_modules @@ -28,13 +28,13 @@ coverage: build/coverage .PHONY: ci-test ci-test: node_modules - @TS_NODE_PROJECT='./test/tsconfig.json' \ + @TS_NODE_PROJECT='./test/tsconfig.json' MOCK_DIR='./test/data' \ ${BIN}/nyc ${NYC_OPTS} --reporter=text \ ${BIN}/mocha ${MOCHA_OPTS} -R list ${TEST_FILES} .PHONY: check check: node_modules - @${BIN}/eslint src --ext .ts --max-warnings 0 --format unix && echo "Ok" + @${BIN}/eslint src test --ext .ts --max-warnings 0 --format unix && echo "Ok" .PHONY: format format: node_modules diff --git a/package.json b/package.json index 76abcdc5..8bfbcd35 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@wharfkit/session", "description": "DESCRIPTION", - "version": "0.5.1", + "version": "1.0.0-beta4", "homepage": "https://github.com/wharfkit/session", "license": "BSD-3-Clause", "main": "lib/session.js", @@ -40,7 +40,10 @@ "@types/node": "^18.7.18", "@typescript-eslint/eslint-plugin": "^5.20.0", "@typescript-eslint/parser": "^5.20.0", - "@wharfkit/wallet-plugin-privatekey": "^0.3.0-ui-13", + "@wharfkit/contract": "^0.2.1", + "@wharfkit/mock-data": "^1.0.0-beta10", + "@wharfkit/transact-plugin-resource-provider": "^1.0.0-beta1", + "@wharfkit/wallet-plugin-privatekey": "^0.5.0", "chai": "^4.3.4", "eslint": "^8.13.0", "eslint-config-prettier": "^8.1.0", @@ -59,6 +62,6 @@ "typedoc": "^0.23.14", "typedoc-plugin-mermaid": "^1.10.0", "typescript": "^4.1.2", - "yarn-deduplicate": "^6.0.1" + "yarn-deduplicate": "^6.0.2" } } diff --git a/src/abi.ts b/src/abi.ts index 7778428d..da4b579a 100644 --- a/src/abi.ts +++ b/src/abi.ts @@ -1,10 +1,17 @@ -import {ABI, API, APIClient, NameType} from '@greymass/eosio' +import {ABI, ABIDef, API, APIClient, NameType} from '@greymass/eosio' import {AbiProvider} from 'eosio-signing-request' +export interface ABICacheInterface extends AbiProvider { + readonly cache: Map + readonly pending: Map> + getAbi(account: NameType): Promise + setAbi(account: NameType, abi: ABIDef): void +} + /** * Given an APIClient instance, this class provides an AbiProvider interface for retrieving and caching ABIs. */ -export class ABICache implements AbiProvider { +export class ABICache implements ABICacheInterface { readonly cache: Map = new Map() readonly pending: Map> = new Map() @@ -31,8 +38,8 @@ export class ABICache implements AbiProvider { return record } - setAbi(account: NameType, abi: ABI) { + setAbi(account: NameType, abi: ABIDef) { const key = String(account) - this.cache.set(key, abi) + this.cache.set(key, ABI.from(abi)) } } diff --git a/src/kit.ts b/src/kit.ts index ef0d8783..cfc200b3 100644 --- a/src/kit.ts +++ b/src/kit.ts @@ -19,6 +19,7 @@ import {BrowserLocalStorage, SessionStorage} from './storage' import { AbstractTransactPlugin, BaseTransactPlugin, + TransactABIDef, TransactPlugin, TransactPluginsOptions, } from './transact' @@ -45,29 +46,34 @@ export interface LoginResult { export interface RestoreArgs { chain: Checksum256Type - actor: NameType - permission: NameType - walletPlugin: Record + actor?: NameType + permission?: NameType + walletPlugin?: Record } -export interface SessionKitOptions { - allowModify?: boolean +export interface SessionKitArgs { appName: NameType chains: ChainDefinitionType[] + ui: UserInterface + walletPlugins: WalletPlugin[] +} + +export interface SessionKitOptions { + abis?: TransactABIDef[] + allowModify?: boolean expireSeconds?: number fetch?: Fetch loginPlugins?: LoginPlugin[] storage?: SessionStorage transactPlugins?: TransactPlugin[] transactPluginsOptions?: TransactPluginsOptions - ui?: UserInterface - walletPlugins: WalletPlugin[] } /** * Request a session from an account. */ export class SessionKit { + readonly abis: TransactABIDef[] = [] readonly allowModify: boolean = true readonly appName: Name readonly chains: ChainDefinition[] @@ -77,26 +83,28 @@ export class SessionKit { readonly storage: SessionStorage readonly transactPlugins: AbstractTransactPlugin[] readonly transactPluginsOptions: TransactPluginsOptions = {} - readonly ui?: UserInterface + readonly ui: UserInterface readonly walletPlugins: WalletPlugin[] - constructor(options: SessionKitOptions) { - // Store options passed on the kit - if (typeof options.allowModify !== 'undefined') { - this.allowModify = options.allowModify - } - this.appName = Name.from(options.appName) - this.chains = options.chains.map((chain) => ChainDefinition.from(chain)) - // Override default expireSeconds for all sessions if specified - if (options.expireSeconds) { - this.expireSeconds = options.expireSeconds - } + constructor(args: SessionKitArgs, options: SessionKitOptions = {}) { + // Save the appName to the SessionKit instance + this.appName = Name.from(args.appName) + // Map the chains provided to ChainDefinition instances + this.chains = args.chains.map((chain) => ChainDefinition.from(chain)) + // Save the UserInterface instance to the SessionKit + this.ui = args.ui + // Establish default plugins for wallet flow + this.walletPlugins = args.walletPlugins // Override fetch if provided if (options.fetch) { this.fetch = options.fetch } else { this.fetch = getFetch(options) } + // Add any ABIs manually provided + if (options.abis) { + this.abis = [...options.abis] + } // Establish default plugins for login flow if (options.loginPlugins) { this.loginPlugins = options.loginPlugins @@ -114,15 +122,18 @@ export class SessionKit { } else { this.transactPlugins = [new BaseTransactPlugin()] } + // Store options passed on the kit + if (typeof options.allowModify !== 'undefined') { + this.allowModify = options.allowModify + } + // Override default expireSeconds for all sessions if specified + if (options.expireSeconds) { + this.expireSeconds = options.expireSeconds + } // Establish default options for transact plugins if (options.transactPluginsOptions) { this.transactPluginsOptions = options.transactPluginsOptions } - if (options.ui) { - this.ui = options.ui - } - // Establish default plugins for wallet flow - this.walletPlugins = options.walletPlugins } getChainDefinition(id: Checksum256Type, override?: ChainDefinition[]): ChainDefinition { @@ -147,12 +158,6 @@ export class SessionKit { */ async login(options?: LoginOptions): Promise { try { - if (!this.ui) { - throw new Error( - 'An instance of a UserInterface must be provided to utilize the login method.' - ) - } - // Create LoginContext for this login request. const context = new LoginContext({ appName: this.appName, @@ -289,9 +294,7 @@ export class SessionKit { session, } } catch (error: any) { - if (this.ui) { - await this.ui.onError(error) - } + await this.ui.onError(error) throw new Error(error) } } @@ -326,7 +329,7 @@ export class SessionKit { async restore(args?: RestoreArgs, options?: LoginOptions): Promise { // If no args were provided, attempt to default restore the session from storage. - if (!args && this.storage) { + if (!args) { const data = await this.storage.read('session') if (data) { args = JSON.parse(data) @@ -339,30 +342,79 @@ export class SessionKit { throw new Error('Either a RestoreArgs object or a Storage instance must be provided.') } + let serializedSession: SerializedSession + + // Retrieve all sessions from storage + const data = await this.storage.read('sessions') + + if (data) { + // If sessions exist, restore the session that matches the provided args + const sessions = JSON.parse(data) + if (args.actor && args.permission) { + // If all args are provided, return exact match + serializedSession = sessions.find((s: SerializedSession) => { + return ( + args && + s.chain === args.chain && + s.actor === args.actor && + s.permission === args.permission + ) + }) + } else { + // If no actor/permission defined, return based on chain + serializedSession = sessions.find((s: SerializedSession) => { + return args && s.chain === args.chain && s.default + }) + } + } else { + // If no sessions were found, but the args contains all the data for a serialized session, use args + if (args.actor && args.permission && args.walletPlugin) { + serializedSession = { + chain: args.chain, + actor: args.actor, + permission: args.permission, + walletPlugin: { + id: args.walletPlugin.id, + data: args.walletPlugin.data, + }, + } + } else { + // Otherwise throw an error since we can't establish the session data + throw new Error('No sessions found in storage. A wallet plugin must be provided.') + } + } + // Ensure a WalletPlugin was found with the provided ID. const walletPlugin = this.walletPlugins.find((p) => { if (!args) { return false } - return p.id === args.walletPlugin.id + return p.id === serializedSession.walletPlugin.id }) if (!walletPlugin) { - throw new Error(`No WalletPlugin found with the ID of: '${args.walletPlugin.id}'`) + throw new Error( + `No WalletPlugin found with the ID of: '${serializedSession.walletPlugin.id}'` + ) + } + + // Set the wallet data from the serialized session + if (serializedSession.walletPlugin.data) { + walletPlugin.data = serializedSession.walletPlugin.data } - // If walletPlugin data was provided, set it on the walletPlugin instance. - if (args.walletPlugin.data) { + // If walletPlugin data was provided by args, override + if (args.walletPlugin && args.walletPlugin.data) { walletPlugin.data = args.walletPlugin.data } // Create a new session from the provided args. const session = new Session( { - chain: this.getChainDefinition(args.chain), + chain: this.getChainDefinition(serializedSession.chain), permissionLevel: PermissionLevel.from({ - actor: args.actor, - permission: args.permission, + actor: serializedSession.actor, + permission: serializedSession.permission, }), walletPlugin, }, @@ -390,28 +442,55 @@ export class SessionKit { return sessions } - async persistSession(session: Session) { + async persistSession(session: Session, setAsDefault = true) { // TODO: Allow disabling of session persistence via kit options + // If no storage exists, do nothing. if (!this.storage) { return } - // Serialize and save the current session to storage. + + // Serialize session passed in const serialized = session.serialize() + + // Specify whether or not this is now the default for the given chain + serialized.default = setAsDefault + + // Set this as the current session for all chains this.storage.write('session', JSON.stringify(serialized)) + // Add the current session to the list of sessions, preventing duplication. const existing = await this.storage.read('sessions') if (existing) { - const sessions = JSON.parse(existing) - const other = sessions.filter((s: Record) => { - return ( - !Checksum256.from(s.chain).equals(Checksum256.from(serialized.chain)) || - !Name.from(s.actor).equals(Name.from(serialized.actor)) || - !Name.from(s.permission).equals(Name.from(serialized.permission)) - ) + const stored = JSON.parse(existing) + const sessions: SerializedSession[] = stored + // Filter out any matching session to ensure no duplicates + .filter((s: SerializedSession): boolean => { + return ( + !Checksum256.from(s.chain).equals(Checksum256.from(serialized.chain)) || + !Name.from(s.actor).equals(Name.from(serialized.actor)) || + !Name.from(s.permission).equals(Name.from(serialized.permission)) + ) + }) + // Remove the default status from all other sessions for this chain + .map((s: SerializedSession): SerializedSession => { + if (session.chain.id.equals(s.chain)) { + s.default = false + } + return s + }) + + // Merge arrays + const orderedSessions = [...sessions, serialized] + + // Sort sessions by chain, actor, and permission + orderedSessions.sort((a: SerializedSession, b: SerializedSession) => { + const chain = String(a.chain).localeCompare(String(b.chain)) + const actor = String(a.actor).localeCompare(String(b.actor)) + const permission = String(a.permission).localeCompare(String(b.permission)) + return chain || actor || permission }) - const orderedSessions = [...other, serialized] - // TODO: Sort sessions by chain, actor, and permission + this.storage.write('sessions', JSON.stringify(orderedSessions)) } else { this.storage.write('sessions', JSON.stringify([serialized])) @@ -440,6 +519,7 @@ export class SessionKit { getSessionOptions(options?: LoginOptions) { return { + abis: this.abis, allowModify: this.allowModify, appName: this.appName, expireSeconds: this.expireSeconds, diff --git a/src/session.ts b/src/session.ts index b4d9f74f..5f73f102 100644 --- a/src/session.ts +++ b/src/session.ts @@ -14,7 +14,6 @@ import { TransactionType, } from '@greymass/eosio' import { - AbiProvider, ChainId, RequestDataV2, RequestDataV3, @@ -23,10 +22,11 @@ import { SigningRequest, } from 'eosio-signing-request' -import {ABICache} from './abi' +import {ABICache, ABICacheInterface} from './abi' import { AbstractTransactPlugin, BaseTransactPlugin, + TransactABIDef, TransactArgs, TransactContext, TransactOptions, @@ -56,7 +56,8 @@ export interface SessionArgs { * Options for creating a new [[Session]]. */ export interface SessionOptions { - abiProvider?: AbiProvider + abis?: TransactABIDef[] + abiCache?: ABICacheInterface allowModify?: boolean appName?: NameType broadcast?: boolean @@ -71,6 +72,7 @@ export interface SessionOptions { export interface SerializedSession { actor: NameType chain: Checksum256Type + default?: boolean permission: NameType walletPlugin: SerializedWalletPlugin } @@ -80,7 +82,8 @@ export interface SerializedSession { */ export class Session { readonly appName: Name | undefined - readonly abiProvider: AbiProvider + readonly abis: TransactABIDef[] = [] + readonly abiCache: ABICacheInterface readonly allowModify: boolean = true readonly broadcast: boolean = true readonly chain: ChainDefinition @@ -120,6 +123,9 @@ export class Session { if (options.appName) { this.appName = Name.from(options.appName) } + if (options.abis) { + this.abis = [...options.abis] + } if (options.allowModify !== undefined) { this.allowModify = options.allowModify } @@ -145,10 +151,10 @@ export class Session { if (options.transactPluginsOptions) { this.transactPluginsOptions = options.transactPluginsOptions } - if (options.abiProvider) { - this.abiProvider = options.abiProvider + if (options.abiCache) { + this.abiCache = options.abiCache } else { - this.abiProvider = new ABICache(this.client) + this.abiCache = new ABICache(this.client) } if (options.ui) { this.ui = options.ui @@ -227,11 +233,11 @@ export class Session { * Overrides: https://github.com/greymass/eosio-signing-request/blob/6fc84b2355577d6461676bff417c76e4f6f2f5c3/src/signing-request.ts#L1112 * * @param {SigningRequest} request The SigningRequest to clone - * @param {AbiProvider} abiProvider The AbiProvider to use for the clone - * @returns Returns a cloned SigningRequest with updated abiProvider and zlib + * @param {ABICacheInterface} abiCache The ABICacheInterface to use for the clone + * @returns Returns a cloned SigningRequest with updated abiCache and zlib */ /* istanbul ignore next */ - cloneRequest(request: SigningRequest, abiProvider: AbiProvider): SigningRequest { + cloneRequest(request: SigningRequest, abiCache: ABICacheInterface): SigningRequest { // Lifted from @greymass/eosio-signing-request method `clone()` // This was done to modify the zlib and abiProvider // TODO: Modify ESR library to expose this `clone()` functionality @@ -243,24 +249,24 @@ export class Session { } const RequestData = this.storageType(request.version) const data = RequestData.from(JSON.parse(JSON.stringify(request.data))) - return new SigningRequest(request.version, data, zlib, abiProvider, signature) + return new SigningRequest(request.version, data, zlib, abiCache, signature) } /** * Convert any provided form of TransactArgs to a SigningRequest * * @param {TransactArgs} args - * @param {AbiProvider} abiProvider + * @param {ABICacheInterface} abiCache * @returns Returns a SigningRequest */ - async createRequest(args: TransactArgs, abiProvider: AbiProvider): Promise { + async createRequest(args: TransactArgs, abiCache: ABICacheInterface): Promise { let request: SigningRequest const options = { - abiProvider, + abiProvider: abiCache, zlib, } if (args.request && args.request instanceof SigningRequest) { - request = this.cloneRequest(args.request, abiProvider) + request = this.cloneRequest(args.request, abiCache) } else if (args.request) { request = SigningRequest.from(args.request, options) } else { @@ -283,15 +289,15 @@ export class Session { * * @param {SigningRequest} previous * @param {SigningRequest} modified - * @param abiProvider + * @param abiCache * @returns */ async updateRequest( previous: SigningRequest, modified: SigningRequest, - abiProvider: AbiProvider + abiCache: ABICacheInterface ): Promise { - const updatedRequest: SigningRequest = this.cloneRequest(modified, abiProvider) + const updatedRequest: SigningRequest = this.cloneRequest(modified, abiCache) const info = updatedRequest.getRawInfo() // Take all the metadata from the previous and set it on the modified request. // This will preserve the metadata as it is modified by various plugins. @@ -336,7 +342,21 @@ export class Session { : this.broadcast // The abi provider to use for this transaction, falling back to the session instance - const abiProvider = options?.abiProvider || this.abiProvider + const abiCache = options?.abiCache || this.abiCache + + // Collect all the ABIs that have been passed in manually + const abiDefs: TransactABIDef[] = [...this.abis] + if (options?.abis) { + // If we have ABIs in the options, add them. + abiDefs.push(...options.abis) + } + + // If an array of ABIs are provided, set them on the abiCache + if (abiCache['setAbi']) { + abiDefs.forEach((def: TransactABIDef) => abiCache['setAbi'](def.account, def.abi)) + } else { + throw new Error('Custom `abiCache` does not support `setAbi` method.') + } // The TransactPlugins to use for this transaction, falling back to the session instance const transactPlugins = options?.transactPlugins || this.transactPlugins @@ -351,11 +371,11 @@ export class Session { // The context object for this transaction const context = new TransactContext({ - abiProvider, + abiCache, appName: this.appName, chain: this.chain, client: this.client, - createRequest: (args: TransactArgs) => this.createRequest(args, abiProvider), + createRequest: (args: TransactArgs) => this.createRequest(args, abiCache), fetch: this.fetch, permissionLevel: this.permissionLevel, storage: this.storage, @@ -376,7 +396,7 @@ export class Session { } // Process incoming TransactArgs and convert to a SigningRequest - let request: SigningRequest = await this.createRequest(args, abiProvider) + let request: SigningRequest = await this.createRequest(args, abiCache) // Create TransactResult to eventually respond to this call with const result: TransactResult = { @@ -400,7 +420,7 @@ export class Session { // If modification is allowed, change the current request. if (allowModify) { - request = await this.updateRequest(request, response.request, abiProvider) + request = await this.updateRequest(request, response.request, abiCache) } if (response.signatures) { @@ -429,10 +449,6 @@ export class Session { context ) - if (context.ui) { - await context.ui.onSignComplete() - } - // Merge signatures in to the TransactResult result.signatures.push(...walletResponse.signatures) @@ -456,6 +472,11 @@ export class Session { // Run the `afterSign` hooks that were registered by the TransactPlugins for (const hook of context.hooks.afterSign) await hook(result, context) + // Notify the UI that the signing operations are complete + if (context.ui) { + await context.ui.onSignComplete() + } + if (willBroadcast) { if (context.ui) { // Notify the UI that broadcast logic will be run against the transaction @@ -519,10 +540,10 @@ export class Session { async signTransaction(transaction: TransactionType): Promise { // Create a TransactContext for the WalletPlugin to use const context = new TransactContext({ - abiProvider: this.abiProvider, + abiCache: this.abiCache, chain: this.chain, client: this.client, - createRequest: (args: TransactArgs) => this.createRequest(args, this.abiProvider), + createRequest: (args: TransactArgs) => this.createRequest(args, this.abiCache), fetch: this.fetch, permissionLevel: this.permissionLevel, }) diff --git a/src/transact.ts b/src/transact.ts index e0e01bbe..68917db2 100644 --- a/src/transact.ts +++ b/src/transact.ts @@ -1,17 +1,18 @@ import zlib from 'pako' import { + ABIDef, AnyAction, AnyTransaction, API, APIClient, Checksum256Type, Name, + NameType, PermissionLevel, Serializer, Signature, } from '@greymass/eosio' import { - AbiProvider, ResolvedSigningRequest, ResolvedTransaction, SigningRequest, @@ -21,6 +22,7 @@ import { import {SessionStorage} from './storage' import {ChainDefinition, Fetch, LocaleDefinitions} from './types' import {UserInterface} from './ui' +import {ABICacheInterface} from './abi' export type TransactPluginsOptions = Record @@ -57,7 +59,7 @@ export type TransactHookResponseType = TransactHookResponse | void * Options for creating a new context for a [[Session.transact]] call. */ export interface TransactContextOptions { - abiProvider: AbiProvider + abiCache: ABICacheInterface appName?: Name chain: ChainDefinition client: APIClient @@ -77,7 +79,7 @@ export interface TransactContextOptions { * provide a way for plugins to add hooks into the process. */ export class TransactContext { - readonly abiProvider: AbiProvider + readonly abiCache: ABICacheInterface readonly appName: Name | undefined readonly chain: ChainDefinition readonly client: APIClient @@ -95,7 +97,7 @@ export class TransactContext { readonly ui?: UserInterface constructor(options: TransactContextOptions) { - this.abiProvider = options.abiProvider + this.abiCache = options.abiCache this.appName = options.appName this.chain = options.chain this.client = options.client @@ -122,7 +124,7 @@ export class TransactContext { get esrOptions(): SigningRequestEncodingOptions { return { - abiProvider: this.abiProvider, + abiProvider: this.abiCache, zlib, } } @@ -153,17 +155,26 @@ export class TransactContext { async resolve(request: SigningRequest, expireSeconds = 120): Promise { // Build the transaction header - const info = await this.getInfo() - const header = info.getTransactionHeader(expireSeconds) + let resolveArgs = { + chainId: this.chain.id, + } + + // Check if this request requires tapos generation + if (request.requiresTapos()) { + const info = await this.getInfo() + const header = info.getTransactionHeader(expireSeconds) + // override resolve args to include tapos headers + resolveArgs = { + ...resolveArgs, + ...header, + } + } // Load ABIs required to resolve this request - const abis = await request.fetchAbis(this.abiProvider) + const abis = await request.fetchAbis(this.abiCache) // Resolve the request and return - return request.resolve(abis, this.permissionLevel, { - ...header, - chainId: this.chain.id, - }) + return request.resolve(abis, this.permissionLevel, resolveArgs) } } /** @@ -186,9 +197,13 @@ export interface TransactArgs { */ export interface TransactOptions { /** - * An optional AbiProvider to control how ABIs are loaded. + * An array of ABIs to use when resolving the transaction. + */ + abis?: TransactABIDef[] + /** + * An optional ABICacheInterface to control how ABIs are loaded. */ - abiProvider?: AbiProvider + abiCache?: ABICacheInterface /** * Whether to allow the signer to make modifications to the request * (e.g. applying a cosigner action to pay for resources). @@ -223,6 +238,11 @@ export interface TransactOptions { validatePluginSignatures?: boolean } +export interface TransactABIDef { + account: NameType + abi: ABIDef +} + export interface TransactRevision { /** * Whether or not the context allowed any modification to take effect. diff --git a/test/data/1ac825d1c1457002dd47729c6bb02a62527f8e54.json b/test/data/1ac825d1c1457002dd47729c6bb02a62527f8e54.json new file mode 100644 index 00000000..07bdd667 --- /dev/null +++ b/test/data/1ac825d1c1457002dd47729c6bb02a62527f8e54.json @@ -0,0 +1,2571 @@ +{ + "request": { + "path": "https://jungle4.greymass.com/v1/chain/get_abi", + "params": { + "method": "POST", + "body": "{\"account_name\":\"eosio\"}" + } + }, + "status": 200, + "json": { + "account_name": "eosio", + "abi": { + "version": "eosio::abi/1.2", + "types": [ + { + "new_type_name": "block_signing_authority", + "type": "variant_block_signing_authority_v0" + }, + { + "new_type_name": "blockchain_parameters_t", + "type": "blockchain_parameters_v1" + } + ], + "structs": [ + { + "name": "abi_hash", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "hash", + "type": "checksum256" + } + ] + }, + { + "name": "activate", + "base": "", + "fields": [ + { + "name": "feature_digest", + "type": "checksum256" + } + ] + }, + { + "name": "authority", + "base": "", + "fields": [ + { + "name": "threshold", + "type": "uint32" + }, + { + "name": "keys", + "type": "key_weight[]" + }, + { + "name": "accounts", + "type": "permission_level_weight[]" + }, + { + "name": "waits", + "type": "wait_weight[]" + } + ] + }, + { + "name": "bid_refund", + "base": "", + "fields": [ + { + "name": "bidder", + "type": "name" + }, + { + "name": "amount", + "type": "asset" + } + ] + }, + { + "name": "bidname", + "base": "", + "fields": [ + { + "name": "bidder", + "type": "name" + }, + { + "name": "newname", + "type": "name" + }, + { + "name": "bid", + "type": "asset" + } + ] + }, + { + "name": "bidrefund", + "base": "", + "fields": [ + { + "name": "bidder", + "type": "name" + }, + { + "name": "newname", + "type": "name" + } + ] + }, + { + "name": "block_header", + "base": "", + "fields": [ + { + "name": "timestamp", + "type": "uint32" + }, + { + "name": "producer", + "type": "name" + }, + { + "name": "confirmed", + "type": "uint16" + }, + { + "name": "previous", + "type": "checksum256" + }, + { + "name": "transaction_mroot", + "type": "checksum256" + }, + { + "name": "action_mroot", + "type": "checksum256" + }, + { + "name": "schedule_version", + "type": "uint32" + }, + { + "name": "new_producers", + "type": "producer_schedule?" + } + ] + }, + { + "name": "block_info_record", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint8" + }, + { + "name": "block_height", + "type": "uint32" + }, + { + "name": "block_timestamp", + "type": "time_point" + } + ] + }, + { + "name": "block_signing_authority_v0", + "base": "", + "fields": [ + { + "name": "threshold", + "type": "uint32" + }, + { + "name": "keys", + "type": "key_weight[]" + } + ] + }, + { + "name": "blockchain_parameters", + "base": "", + "fields": [ + { + "name": "max_block_net_usage", + "type": "uint64" + }, + { + "name": "target_block_net_usage_pct", + "type": "uint32" + }, + { + "name": "max_transaction_net_usage", + "type": "uint32" + }, + { + "name": "base_per_transaction_net_usage", + "type": "uint32" + }, + { + "name": "net_usage_leeway", + "type": "uint32" + }, + { + "name": "context_free_discount_net_usage_num", + "type": "uint32" + }, + { + "name": "context_free_discount_net_usage_den", + "type": "uint32" + }, + { + "name": "max_block_cpu_usage", + "type": "uint32" + }, + { + "name": "target_block_cpu_usage_pct", + "type": "uint32" + }, + { + "name": "max_transaction_cpu_usage", + "type": "uint32" + }, + { + "name": "min_transaction_cpu_usage", + "type": "uint32" + }, + { + "name": "max_transaction_lifetime", + "type": "uint32" + }, + { + "name": "deferred_trx_expiration_window", + "type": "uint32" + }, + { + "name": "max_transaction_delay", + "type": "uint32" + }, + { + "name": "max_inline_action_size", + "type": "uint32" + }, + { + "name": "max_inline_action_depth", + "type": "uint16" + }, + { + "name": "max_authority_depth", + "type": "uint16" + } + ] + }, + { + "name": "blockchain_parameters_v1", + "base": "blockchain_parameters", + "fields": [ + { + "name": "max_action_return_value_size", + "type": "uint32$" + } + ] + }, + { + "name": "buyram", + "base": "", + "fields": [ + { + "name": "payer", + "type": "name" + }, + { + "name": "receiver", + "type": "name" + }, + { + "name": "quant", + "type": "asset" + } + ] + }, + { + "name": "buyrambytes", + "base": "", + "fields": [ + { + "name": "payer", + "type": "name" + }, + { + "name": "receiver", + "type": "name" + }, + { + "name": "bytes", + "type": "uint32" + } + ] + }, + { + "name": "buyrex", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "amount", + "type": "asset" + } + ] + }, + { + "name": "canceldelay", + "base": "", + "fields": [ + { + "name": "canceling_auth", + "type": "permission_level" + }, + { + "name": "trx_id", + "type": "checksum256" + } + ] + }, + { + "name": "cfgpowerup", + "base": "", + "fields": [ + { + "name": "args", + "type": "powerup_config" + } + ] + }, + { + "name": "claimrewards", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + } + ] + }, + { + "name": "closerex", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + } + ] + }, + { + "name": "cnclrexorder", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + } + ] + }, + { + "name": "connector", + "base": "", + "fields": [ + { + "name": "balance", + "type": "asset" + }, + { + "name": "weight", + "type": "float64" + } + ] + }, + { + "name": "consolidate", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + } + ] + }, + { + "name": "defcpuloan", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "loan_num", + "type": "uint64" + }, + { + "name": "amount", + "type": "asset" + } + ] + }, + { + "name": "defnetloan", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "loan_num", + "type": "uint64" + }, + { + "name": "amount", + "type": "asset" + } + ] + }, + { + "name": "delegatebw", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "receiver", + "type": "name" + }, + { + "name": "stake_net_quantity", + "type": "asset" + }, + { + "name": "stake_cpu_quantity", + "type": "asset" + }, + { + "name": "transfer", + "type": "bool" + } + ] + }, + { + "name": "delegated_bandwidth", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "to", + "type": "name" + }, + { + "name": "net_weight", + "type": "asset" + }, + { + "name": "cpu_weight", + "type": "asset" + } + ] + }, + { + "name": "deleteauth", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "permission", + "type": "name" + }, + { + "name": "authorized_by", + "type": "name$" + } + ] + }, + { + "name": "deposit", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "amount", + "type": "asset" + } + ] + }, + { + "name": "eosio_global_state", + "base": "blockchain_parameters", + "fields": [ + { + "name": "max_ram_size", + "type": "uint64" + }, + { + "name": "total_ram_bytes_reserved", + "type": "uint64" + }, + { + "name": "total_ram_stake", + "type": "int64" + }, + { + "name": "last_producer_schedule_update", + "type": "block_timestamp_type" + }, + { + "name": "last_pervote_bucket_fill", + "type": "time_point" + }, + { + "name": "pervote_bucket", + "type": "int64" + }, + { + "name": "perblock_bucket", + "type": "int64" + }, + { + "name": "total_unpaid_blocks", + "type": "uint32" + }, + { + "name": "total_activated_stake", + "type": "int64" + }, + { + "name": "thresh_activated_stake_time", + "type": "time_point" + }, + { + "name": "last_producer_schedule_size", + "type": "uint16" + }, + { + "name": "total_producer_vote_weight", + "type": "float64" + }, + { + "name": "last_name_close", + "type": "block_timestamp_type" + } + ] + }, + { + "name": "eosio_global_state2", + "base": "", + "fields": [ + { + "name": "new_ram_per_block", + "type": "uint16" + }, + { + "name": "last_ram_increase", + "type": "block_timestamp_type" + }, + { + "name": "last_block_num", + "type": "block_timestamp_type" + }, + { + "name": "total_producer_votepay_share", + "type": "float64" + }, + { + "name": "revision", + "type": "uint8" + } + ] + }, + { + "name": "eosio_global_state3", + "base": "", + "fields": [ + { + "name": "last_vpay_state_update", + "type": "time_point" + }, + { + "name": "total_vpay_share_change_rate", + "type": "float64" + } + ] + }, + { + "name": "eosio_global_state4", + "base": "", + "fields": [ + { + "name": "continuous_rate", + "type": "float64" + }, + { + "name": "inflation_pay_factor", + "type": "int64" + }, + { + "name": "votepay_factor", + "type": "int64" + } + ] + }, + { + "name": "exchange_state", + "base": "", + "fields": [ + { + "name": "supply", + "type": "asset" + }, + { + "name": "base", + "type": "connector" + }, + { + "name": "quote", + "type": "connector" + } + ] + }, + { + "name": "fundcpuloan", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "loan_num", + "type": "uint64" + }, + { + "name": "payment", + "type": "asset" + } + ] + }, + { + "name": "fundnetloan", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "loan_num", + "type": "uint64" + }, + { + "name": "payment", + "type": "asset" + } + ] + }, + { + "name": "init", + "base": "", + "fields": [ + { + "name": "version", + "type": "varuint32" + }, + { + "name": "core", + "type": "symbol" + } + ] + }, + { + "name": "key_weight", + "base": "", + "fields": [ + { + "name": "key", + "type": "public_key" + }, + { + "name": "weight", + "type": "uint16" + } + ] + }, + { + "name": "limitauthchg", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "allow_perms", + "type": "name[]" + }, + { + "name": "disallow_perms", + "type": "name[]" + } + ] + }, + { + "name": "linkauth", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "code", + "type": "name" + }, + { + "name": "type", + "type": "name" + }, + { + "name": "requirement", + "type": "name" + }, + { + "name": "authorized_by", + "type": "name$" + } + ] + }, + { + "name": "mvfrsavings", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "rex", + "type": "asset" + } + ] + }, + { + "name": "mvtosavings", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "rex", + "type": "asset" + } + ] + }, + { + "name": "name_bid", + "base": "", + "fields": [ + { + "name": "newname", + "type": "name" + }, + { + "name": "high_bidder", + "type": "name" + }, + { + "name": "high_bid", + "type": "int64" + }, + { + "name": "last_bid_time", + "type": "time_point" + } + ] + }, + { + "name": "newaccount", + "base": "", + "fields": [ + { + "name": "creator", + "type": "name" + }, + { + "name": "name", + "type": "name" + }, + { + "name": "owner", + "type": "authority" + }, + { + "name": "active", + "type": "authority" + } + ] + }, + { + "name": "onblock", + "base": "", + "fields": [ + { + "name": "header", + "type": "block_header" + } + ] + }, + { + "name": "onerror", + "base": "", + "fields": [ + { + "name": "sender_id", + "type": "uint128" + }, + { + "name": "sent_trx", + "type": "bytes" + } + ] + }, + { + "name": "pair_time_point_sec_int64", + "base": "", + "fields": [ + { + "name": "first", + "type": "time_point_sec" + }, + { + "name": "second", + "type": "int64" + } + ] + }, + { + "name": "permission_level", + "base": "", + "fields": [ + { + "name": "actor", + "type": "name" + }, + { + "name": "permission", + "type": "name" + } + ] + }, + { + "name": "permission_level_weight", + "base": "", + "fields": [ + { + "name": "permission", + "type": "permission_level" + }, + { + "name": "weight", + "type": "uint16" + } + ] + }, + { + "name": "powerup", + "base": "", + "fields": [ + { + "name": "payer", + "type": "name" + }, + { + "name": "receiver", + "type": "name" + }, + { + "name": "days", + "type": "uint32" + }, + { + "name": "net_frac", + "type": "int64" + }, + { + "name": "cpu_frac", + "type": "int64" + }, + { + "name": "max_payment", + "type": "asset" + } + ] + }, + { + "name": "powerup_config", + "base": "", + "fields": [ + { + "name": "net", + "type": "powerup_config_resource" + }, + { + "name": "cpu", + "type": "powerup_config_resource" + }, + { + "name": "powerup_days", + "type": "uint32?" + }, + { + "name": "min_powerup_fee", + "type": "asset?" + } + ] + }, + { + "name": "powerup_config_resource", + "base": "", + "fields": [ + { + "name": "current_weight_ratio", + "type": "int64?" + }, + { + "name": "target_weight_ratio", + "type": "int64?" + }, + { + "name": "assumed_stake_weight", + "type": "int64?" + }, + { + "name": "target_timestamp", + "type": "time_point_sec?" + }, + { + "name": "exponent", + "type": "float64?" + }, + { + "name": "decay_secs", + "type": "uint32?" + }, + { + "name": "min_price", + "type": "asset?" + }, + { + "name": "max_price", + "type": "asset?" + } + ] + }, + { + "name": "powerup_order", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint8" + }, + { + "name": "id", + "type": "uint64" + }, + { + "name": "owner", + "type": "name" + }, + { + "name": "net_weight", + "type": "int64" + }, + { + "name": "cpu_weight", + "type": "int64" + }, + { + "name": "expires", + "type": "time_point_sec" + } + ] + }, + { + "name": "powerup_state", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint8" + }, + { + "name": "net", + "type": "powerup_state_resource" + }, + { + "name": "cpu", + "type": "powerup_state_resource" + }, + { + "name": "powerup_days", + "type": "uint32" + }, + { + "name": "min_powerup_fee", + "type": "asset" + } + ] + }, + { + "name": "powerup_state_resource", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint8" + }, + { + "name": "weight", + "type": "int64" + }, + { + "name": "weight_ratio", + "type": "int64" + }, + { + "name": "assumed_stake_weight", + "type": "int64" + }, + { + "name": "initial_weight_ratio", + "type": "int64" + }, + { + "name": "target_weight_ratio", + "type": "int64" + }, + { + "name": "initial_timestamp", + "type": "time_point_sec" + }, + { + "name": "target_timestamp", + "type": "time_point_sec" + }, + { + "name": "exponent", + "type": "float64" + }, + { + "name": "decay_secs", + "type": "uint32" + }, + { + "name": "min_price", + "type": "asset" + }, + { + "name": "max_price", + "type": "asset" + }, + { + "name": "utilization", + "type": "int64" + }, + { + "name": "adjusted_utilization", + "type": "int64" + }, + { + "name": "utilization_timestamp", + "type": "time_point_sec" + } + ] + }, + { + "name": "powerupexec", + "base": "", + "fields": [ + { + "name": "user", + "type": "name" + }, + { + "name": "max", + "type": "uint16" + } + ] + }, + { + "name": "producer_info", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "total_votes", + "type": "float64" + }, + { + "name": "producer_key", + "type": "public_key" + }, + { + "name": "is_active", + "type": "bool" + }, + { + "name": "url", + "type": "string" + }, + { + "name": "unpaid_blocks", + "type": "uint32" + }, + { + "name": "last_claim_time", + "type": "time_point" + }, + { + "name": "location", + "type": "uint16" + }, + { + "name": "producer_authority", + "type": "block_signing_authority$" + } + ] + }, + { + "name": "producer_info2", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "votepay_share", + "type": "float64" + }, + { + "name": "last_votepay_share_update", + "type": "time_point" + } + ] + }, + { + "name": "producer_key", + "base": "", + "fields": [ + { + "name": "producer_name", + "type": "name" + }, + { + "name": "block_signing_key", + "type": "public_key" + } + ] + }, + { + "name": "producer_schedule", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint32" + }, + { + "name": "producers", + "type": "producer_key[]" + } + ] + }, + { + "name": "refund", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + } + ] + }, + { + "name": "refund_request", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "request_time", + "type": "time_point_sec" + }, + { + "name": "net_amount", + "type": "asset" + }, + { + "name": "cpu_amount", + "type": "asset" + } + ] + }, + { + "name": "regproducer", + "base": "", + "fields": [ + { + "name": "producer", + "type": "name" + }, + { + "name": "producer_key", + "type": "public_key" + }, + { + "name": "url", + "type": "string" + }, + { + "name": "location", + "type": "uint16" + } + ] + }, + { + "name": "regproducer2", + "base": "", + "fields": [ + { + "name": "producer", + "type": "name" + }, + { + "name": "producer_authority", + "type": "block_signing_authority" + }, + { + "name": "url", + "type": "string" + }, + { + "name": "location", + "type": "uint16" + } + ] + }, + { + "name": "regproxy", + "base": "", + "fields": [ + { + "name": "proxy", + "type": "name" + }, + { + "name": "isproxy", + "type": "bool" + } + ] + }, + { + "name": "rentcpu", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "receiver", + "type": "name" + }, + { + "name": "loan_payment", + "type": "asset" + }, + { + "name": "loan_fund", + "type": "asset" + } + ] + }, + { + "name": "rentnet", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "receiver", + "type": "name" + }, + { + "name": "loan_payment", + "type": "asset" + }, + { + "name": "loan_fund", + "type": "asset" + } + ] + }, + { + "name": "rex_balance", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint8" + }, + { + "name": "owner", + "type": "name" + }, + { + "name": "vote_stake", + "type": "asset" + }, + { + "name": "rex_balance", + "type": "asset" + }, + { + "name": "matured_rex", + "type": "int64" + }, + { + "name": "rex_maturities", + "type": "pair_time_point_sec_int64[]" + } + ] + }, + { + "name": "rex_fund", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint8" + }, + { + "name": "owner", + "type": "name" + }, + { + "name": "balance", + "type": "asset" + } + ] + }, + { + "name": "rex_loan", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint8" + }, + { + "name": "from", + "type": "name" + }, + { + "name": "receiver", + "type": "name" + }, + { + "name": "payment", + "type": "asset" + }, + { + "name": "balance", + "type": "asset" + }, + { + "name": "total_staked", + "type": "asset" + }, + { + "name": "loan_num", + "type": "uint64" + }, + { + "name": "expiration", + "type": "time_point" + } + ] + }, + { + "name": "rex_order", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint8" + }, + { + "name": "owner", + "type": "name" + }, + { + "name": "rex_requested", + "type": "asset" + }, + { + "name": "proceeds", + "type": "asset" + }, + { + "name": "stake_change", + "type": "asset" + }, + { + "name": "order_time", + "type": "time_point" + }, + { + "name": "is_open", + "type": "bool" + } + ] + }, + { + "name": "rex_pool", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint8" + }, + { + "name": "total_lent", + "type": "asset" + }, + { + "name": "total_unlent", + "type": "asset" + }, + { + "name": "total_rent", + "type": "asset" + }, + { + "name": "total_lendable", + "type": "asset" + }, + { + "name": "total_rex", + "type": "asset" + }, + { + "name": "namebid_proceeds", + "type": "asset" + }, + { + "name": "loan_num", + "type": "uint64" + } + ] + }, + { + "name": "rex_return_buckets", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint8" + }, + { + "name": "return_buckets", + "type": "pair_time_point_sec_int64[]" + } + ] + }, + { + "name": "rex_return_pool", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint8" + }, + { + "name": "last_dist_time", + "type": "time_point_sec" + }, + { + "name": "pending_bucket_time", + "type": "time_point_sec" + }, + { + "name": "oldest_bucket_time", + "type": "time_point_sec" + }, + { + "name": "pending_bucket_proceeds", + "type": "int64" + }, + { + "name": "current_rate_of_increase", + "type": "int64" + }, + { + "name": "proceeds", + "type": "int64" + } + ] + }, + { + "name": "rexexec", + "base": "", + "fields": [ + { + "name": "user", + "type": "name" + }, + { + "name": "max", + "type": "uint16" + } + ] + }, + { + "name": "rmvproducer", + "base": "", + "fields": [ + { + "name": "producer", + "type": "name" + } + ] + }, + { + "name": "sellram", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "bytes", + "type": "int64" + } + ] + }, + { + "name": "sellrex", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "rex", + "type": "asset" + } + ] + }, + { + "name": "setabi", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "abi", + "type": "bytes" + }, + { + "name": "memo", + "type": "string$" + } + ] + }, + { + "name": "setacctcpu", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "cpu_weight", + "type": "int64?" + } + ] + }, + { + "name": "setacctnet", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "net_weight", + "type": "int64?" + } + ] + }, + { + "name": "setacctram", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "ram_bytes", + "type": "int64?" + } + ] + }, + { + "name": "setalimits", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "ram_bytes", + "type": "int64" + }, + { + "name": "net_weight", + "type": "int64" + }, + { + "name": "cpu_weight", + "type": "int64" + } + ] + }, + { + "name": "setcode", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "vmtype", + "type": "uint8" + }, + { + "name": "vmversion", + "type": "uint8" + }, + { + "name": "code", + "type": "bytes" + }, + { + "name": "memo", + "type": "string$" + } + ] + }, + { + "name": "setinflation", + "base": "", + "fields": [ + { + "name": "annual_rate", + "type": "int64" + }, + { + "name": "inflation_pay_factor", + "type": "int64" + }, + { + "name": "votepay_factor", + "type": "int64" + } + ] + }, + { + "name": "setparams", + "base": "", + "fields": [ + { + "name": "params", + "type": "blockchain_parameters_t" + } + ] + }, + { + "name": "setpriv", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "is_priv", + "type": "uint8" + } + ] + }, + { + "name": "setram", + "base": "", + "fields": [ + { + "name": "max_ram_size", + "type": "uint64" + } + ] + }, + { + "name": "setramrate", + "base": "", + "fields": [ + { + "name": "bytes_per_block", + "type": "uint16" + } + ] + }, + { + "name": "setrex", + "base": "", + "fields": [ + { + "name": "balance", + "type": "asset" + } + ] + }, + { + "name": "undelegatebw", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "receiver", + "type": "name" + }, + { + "name": "unstake_net_quantity", + "type": "asset" + }, + { + "name": "unstake_cpu_quantity", + "type": "asset" + } + ] + }, + { + "name": "unlinkauth", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "code", + "type": "name" + }, + { + "name": "type", + "type": "name" + }, + { + "name": "authorized_by", + "type": "name$" + } + ] + }, + { + "name": "unregprod", + "base": "", + "fields": [ + { + "name": "producer", + "type": "name" + } + ] + }, + { + "name": "unstaketorex", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "receiver", + "type": "name" + }, + { + "name": "from_net", + "type": "asset" + }, + { + "name": "from_cpu", + "type": "asset" + } + ] + }, + { + "name": "updateauth", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "permission", + "type": "name" + }, + { + "name": "parent", + "type": "name" + }, + { + "name": "auth", + "type": "authority" + }, + { + "name": "authorized_by", + "type": "name$" + } + ] + }, + { + "name": "updaterex", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + } + ] + }, + { + "name": "updtrevision", + "base": "", + "fields": [ + { + "name": "revision", + "type": "uint8" + } + ] + }, + { + "name": "user_resources", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "net_weight", + "type": "asset" + }, + { + "name": "cpu_weight", + "type": "asset" + }, + { + "name": "ram_bytes", + "type": "int64" + } + ] + }, + { + "name": "voteproducer", + "base": "", + "fields": [ + { + "name": "voter", + "type": "name" + }, + { + "name": "proxy", + "type": "name" + }, + { + "name": "producers", + "type": "name[]" + } + ] + }, + { + "name": "voter_info", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "proxy", + "type": "name" + }, + { + "name": "producers", + "type": "name[]" + }, + { + "name": "staked", + "type": "int64" + }, + { + "name": "last_vote_weight", + "type": "float64" + }, + { + "name": "proxied_vote_weight", + "type": "float64" + }, + { + "name": "is_proxy", + "type": "bool" + }, + { + "name": "flags1", + "type": "uint32" + }, + { + "name": "reserved2", + "type": "uint32" + }, + { + "name": "reserved3", + "type": "asset" + } + ] + }, + { + "name": "voteupdate", + "base": "", + "fields": [ + { + "name": "voter_name", + "type": "name" + } + ] + }, + { + "name": "wait_weight", + "base": "", + "fields": [ + { + "name": "wait_sec", + "type": "uint32" + }, + { + "name": "weight", + "type": "uint16" + } + ] + }, + { + "name": "wasmcfg", + "base": "", + "fields": [ + { + "name": "settings", + "type": "name" + } + ] + }, + { + "name": "withdraw", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "amount", + "type": "asset" + } + ] + }, + { + "name": "limit_auth_change", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint8" + }, + { + "name": "account", + "type": "name" + }, + { + "name": "allow_perms", + "type": "name[]" + }, + { + "name": "disallow_perms", + "type": "name[]" + } + ] + } + ], + "actions": [ + { + "name": "activate", + "type": "activate", + "ricardian_contract": "" + }, + { + "name": "bidname", + "type": "bidname", + "ricardian_contract": "" + }, + { + "name": "bidrefund", + "type": "bidrefund", + "ricardian_contract": "" + }, + { + "name": "buyram", + "type": "buyram", + "ricardian_contract": "" + }, + { + "name": "buyrambytes", + "type": "buyrambytes", + "ricardian_contract": "" + }, + { + "name": "buyrex", + "type": "buyrex", + "ricardian_contract": "" + }, + { + "name": "canceldelay", + "type": "canceldelay", + "ricardian_contract": "" + }, + { + "name": "cfgpowerup", + "type": "cfgpowerup", + "ricardian_contract": "" + }, + { + "name": "claimrewards", + "type": "claimrewards", + "ricardian_contract": "" + }, + { + "name": "closerex", + "type": "closerex", + "ricardian_contract": "" + }, + { + "name": "cnclrexorder", + "type": "cnclrexorder", + "ricardian_contract": "" + }, + { + "name": "consolidate", + "type": "consolidate", + "ricardian_contract": "" + }, + { + "name": "defcpuloan", + "type": "defcpuloan", + "ricardian_contract": "" + }, + { + "name": "defnetloan", + "type": "defnetloan", + "ricardian_contract": "" + }, + { + "name": "delegatebw", + "type": "delegatebw", + "ricardian_contract": "" + }, + { + "name": "deleteauth", + "type": "deleteauth", + "ricardian_contract": "" + }, + { + "name": "deposit", + "type": "deposit", + "ricardian_contract": "" + }, + { + "name": "fundcpuloan", + "type": "fundcpuloan", + "ricardian_contract": "" + }, + { + "name": "fundnetloan", + "type": "fundnetloan", + "ricardian_contract": "" + }, + { + "name": "init", + "type": "init", + "ricardian_contract": "" + }, + { + "name": "limitauthchg", + "type": "limitauthchg", + "ricardian_contract": "" + }, + { + "name": "linkauth", + "type": "linkauth", + "ricardian_contract": "" + }, + { + "name": "mvfrsavings", + "type": "mvfrsavings", + "ricardian_contract": "" + }, + { + "name": "mvtosavings", + "type": "mvtosavings", + "ricardian_contract": "" + }, + { + "name": "newaccount", + "type": "newaccount", + "ricardian_contract": "" + }, + { + "name": "onblock", + "type": "onblock", + "ricardian_contract": "" + }, + { + "name": "onerror", + "type": "onerror", + "ricardian_contract": "" + }, + { + "name": "powerup", + "type": "powerup", + "ricardian_contract": "" + }, + { + "name": "powerupexec", + "type": "powerupexec", + "ricardian_contract": "" + }, + { + "name": "refund", + "type": "refund", + "ricardian_contract": "" + }, + { + "name": "regproducer", + "type": "regproducer", + "ricardian_contract": "" + }, + { + "name": "regproducer2", + "type": "regproducer2", + "ricardian_contract": "" + }, + { + "name": "regproxy", + "type": "regproxy", + "ricardian_contract": "" + }, + { + "name": "rentcpu", + "type": "rentcpu", + "ricardian_contract": "" + }, + { + "name": "rentnet", + "type": "rentnet", + "ricardian_contract": "" + }, + { + "name": "rexexec", + "type": "rexexec", + "ricardian_contract": "" + }, + { + "name": "rmvproducer", + "type": "rmvproducer", + "ricardian_contract": "" + }, + { + "name": "sellram", + "type": "sellram", + "ricardian_contract": "" + }, + { + "name": "sellrex", + "type": "sellrex", + "ricardian_contract": "" + }, + { + "name": "setabi", + "type": "setabi", + "ricardian_contract": "" + }, + { + "name": "setacctcpu", + "type": "setacctcpu", + "ricardian_contract": "" + }, + { + "name": "setacctnet", + "type": "setacctnet", + "ricardian_contract": "" + }, + { + "name": "setacctram", + "type": "setacctram", + "ricardian_contract": "" + }, + { + "name": "setalimits", + "type": "setalimits", + "ricardian_contract": "" + }, + { + "name": "setcode", + "type": "setcode", + "ricardian_contract": "" + }, + { + "name": "setinflation", + "type": "setinflation", + "ricardian_contract": "" + }, + { + "name": "setparams", + "type": "setparams", + "ricardian_contract": "" + }, + { + "name": "setpriv", + "type": "setpriv", + "ricardian_contract": "" + }, + { + "name": "setram", + "type": "setram", + "ricardian_contract": "" + }, + { + "name": "setramrate", + "type": "setramrate", + "ricardian_contract": "" + }, + { + "name": "setrex", + "type": "setrex", + "ricardian_contract": "" + }, + { + "name": "undelegatebw", + "type": "undelegatebw", + "ricardian_contract": "" + }, + { + "name": "unlinkauth", + "type": "unlinkauth", + "ricardian_contract": "" + }, + { + "name": "unregprod", + "type": "unregprod", + "ricardian_contract": "" + }, + { + "name": "unstaketorex", + "type": "unstaketorex", + "ricardian_contract": "" + }, + { + "name": "updateauth", + "type": "updateauth", + "ricardian_contract": "" + }, + { + "name": "updaterex", + "type": "updaterex", + "ricardian_contract": "" + }, + { + "name": "updtrevision", + "type": "updtrevision", + "ricardian_contract": "" + }, + { + "name": "voteproducer", + "type": "voteproducer", + "ricardian_contract": "" + }, + { + "name": "voteupdate", + "type": "voteupdate", + "ricardian_contract": "" + }, + { + "name": "wasmcfg", + "type": "wasmcfg", + "ricardian_contract": "" + }, + { + "name": "withdraw", + "type": "withdraw", + "ricardian_contract": "" + } + ], + "tables": [ + { + "name": "abihash", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "abi_hash" + }, + { + "name": "bidrefunds", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "bid_refund" + }, + { + "name": "blockinfo", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "block_info_record" + }, + { + "name": "cpuloan", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "rex_loan" + }, + { + "name": "delband", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "delegated_bandwidth" + }, + { + "name": "global", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "eosio_global_state" + }, + { + "name": "global2", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "eosio_global_state2" + }, + { + "name": "global3", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "eosio_global_state3" + }, + { + "name": "global4", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "eosio_global_state4" + }, + { + "name": "namebids", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "name_bid" + }, + { + "name": "netloan", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "rex_loan" + }, + { + "name": "powup.order", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "powerup_order" + }, + { + "name": "powup.state", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "powerup_state" + }, + { + "name": "producers", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "producer_info" + }, + { + "name": "producers2", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "producer_info2" + }, + { + "name": "rammarket", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "exchange_state" + }, + { + "name": "refunds", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "refund_request" + }, + { + "name": "retbuckets", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "rex_return_buckets" + }, + { + "name": "rexbal", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "rex_balance" + }, + { + "name": "rexfund", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "rex_fund" + }, + { + "name": "rexpool", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "rex_pool" + }, + { + "name": "rexqueue", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "rex_order" + }, + { + "name": "rexretpool", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "rex_return_pool" + }, + { + "name": "userres", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "user_resources" + }, + { + "name": "voters", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "voter_info" + }, + { + "name": "limitauthchg", + "index_type": "i64", + "key_names": [], + "key_types": [], + "type": "limit_auth_change" + } + ], + "ricardian_clauses": [], + "error_messages": [], + "abi_extensions": [], + "variants": [ + { + "name": "variant_block_signing_authority_v0", + "types": [ + "block_signing_authority_v0" + ] + } + ], + "action_results": [] + } + }, + "text": "{\"account_name\":\"eosio\",\"abi\":{\"version\":\"eosio::abi/1.2\",\"types\":[{\"new_type_name\":\"block_signing_authority\",\"type\":\"variant_block_signing_authority_v0\"},{\"new_type_name\":\"blockchain_parameters_t\",\"type\":\"blockchain_parameters_v1\"}],\"structs\":[{\"name\":\"abi_hash\",\"base\":\"\",\"fields\":[{\"name\":\"owner\",\"type\":\"name\"},{\"name\":\"hash\",\"type\":\"checksum256\"}]},{\"name\":\"activate\",\"base\":\"\",\"fields\":[{\"name\":\"feature_digest\",\"type\":\"checksum256\"}]},{\"name\":\"authority\",\"base\":\"\",\"fields\":[{\"name\":\"threshold\",\"type\":\"uint32\"},{\"name\":\"keys\",\"type\":\"key_weight[]\"},{\"name\":\"accounts\",\"type\":\"permission_level_weight[]\"},{\"name\":\"waits\",\"type\":\"wait_weight[]\"}]},{\"name\":\"bid_refund\",\"base\":\"\",\"fields\":[{\"name\":\"bidder\",\"type\":\"name\"},{\"name\":\"amount\",\"type\":\"asset\"}]},{\"name\":\"bidname\",\"base\":\"\",\"fields\":[{\"name\":\"bidder\",\"type\":\"name\"},{\"name\":\"newname\",\"type\":\"name\"},{\"name\":\"bid\",\"type\":\"asset\"}]},{\"name\":\"bidrefund\",\"base\":\"\",\"fields\":[{\"name\":\"bidder\",\"type\":\"name\"},{\"name\":\"newname\",\"type\":\"name\"}]},{\"name\":\"block_header\",\"base\":\"\",\"fields\":[{\"name\":\"timestamp\",\"type\":\"uint32\"},{\"name\":\"producer\",\"type\":\"name\"},{\"name\":\"confirmed\",\"type\":\"uint16\"},{\"name\":\"previous\",\"type\":\"checksum256\"},{\"name\":\"transaction_mroot\",\"type\":\"checksum256\"},{\"name\":\"action_mroot\",\"type\":\"checksum256\"},{\"name\":\"schedule_version\",\"type\":\"uint32\"},{\"name\":\"new_producers\",\"type\":\"producer_schedule?\"}]},{\"name\":\"block_info_record\",\"base\":\"\",\"fields\":[{\"name\":\"version\",\"type\":\"uint8\"},{\"name\":\"block_height\",\"type\":\"uint32\"},{\"name\":\"block_timestamp\",\"type\":\"time_point\"}]},{\"name\":\"block_signing_authority_v0\",\"base\":\"\",\"fields\":[{\"name\":\"threshold\",\"type\":\"uint32\"},{\"name\":\"keys\",\"type\":\"key_weight[]\"}]},{\"name\":\"blockchain_parameters\",\"base\":\"\",\"fields\":[{\"name\":\"max_block_net_usage\",\"type\":\"uint64\"},{\"name\":\"target_block_net_usage_pct\",\"type\":\"uint32\"},{\"name\":\"max_transaction_net_usage\",\"type\":\"uint32\"},{\"name\":\"base_per_transaction_net_usage\",\"type\":\"uint32\"},{\"name\":\"net_usage_leeway\",\"type\":\"uint32\"},{\"name\":\"context_free_discount_net_usage_num\",\"type\":\"uint32\"},{\"name\":\"context_free_discount_net_usage_den\",\"type\":\"uint32\"},{\"name\":\"max_block_cpu_usage\",\"type\":\"uint32\"},{\"name\":\"target_block_cpu_usage_pct\",\"type\":\"uint32\"},{\"name\":\"max_transaction_cpu_usage\",\"type\":\"uint32\"},{\"name\":\"min_transaction_cpu_usage\",\"type\":\"uint32\"},{\"name\":\"max_transaction_lifetime\",\"type\":\"uint32\"},{\"name\":\"deferred_trx_expiration_window\",\"type\":\"uint32\"},{\"name\":\"max_transaction_delay\",\"type\":\"uint32\"},{\"name\":\"max_inline_action_size\",\"type\":\"uint32\"},{\"name\":\"max_inline_action_depth\",\"type\":\"uint16\"},{\"name\":\"max_authority_depth\",\"type\":\"uint16\"}]},{\"name\":\"blockchain_parameters_v1\",\"base\":\"blockchain_parameters\",\"fields\":[{\"name\":\"max_action_return_value_size\",\"type\":\"uint32$\"}]},{\"name\":\"buyram\",\"base\":\"\",\"fields\":[{\"name\":\"payer\",\"type\":\"name\"},{\"name\":\"receiver\",\"type\":\"name\"},{\"name\":\"quant\",\"type\":\"asset\"}]},{\"name\":\"buyrambytes\",\"base\":\"\",\"fields\":[{\"name\":\"payer\",\"type\":\"name\"},{\"name\":\"receiver\",\"type\":\"name\"},{\"name\":\"bytes\",\"type\":\"uint32\"}]},{\"name\":\"buyrex\",\"base\":\"\",\"fields\":[{\"name\":\"from\",\"type\":\"name\"},{\"name\":\"amount\",\"type\":\"asset\"}]},{\"name\":\"canceldelay\",\"base\":\"\",\"fields\":[{\"name\":\"canceling_auth\",\"type\":\"permission_level\"},{\"name\":\"trx_id\",\"type\":\"checksum256\"}]},{\"name\":\"cfgpowerup\",\"base\":\"\",\"fields\":[{\"name\":\"args\",\"type\":\"powerup_config\"}]},{\"name\":\"claimrewards\",\"base\":\"\",\"fields\":[{\"name\":\"owner\",\"type\":\"name\"}]},{\"name\":\"closerex\",\"base\":\"\",\"fields\":[{\"name\":\"owner\",\"type\":\"name\"}]},{\"name\":\"cnclrexorder\",\"base\":\"\",\"fields\":[{\"name\":\"owner\",\"type\":\"name\"}]},{\"name\":\"connector\",\"base\":\"\",\"fields\":[{\"name\":\"balance\",\"type\":\"asset\"},{\"name\":\"weight\",\"type\":\"float64\"}]},{\"name\":\"consolidate\",\"base\":\"\",\"fields\":[{\"name\":\"owner\",\"type\":\"name\"}]},{\"name\":\"defcpuloan\",\"base\":\"\",\"fields\":[{\"name\":\"from\",\"type\":\"name\"},{\"name\":\"loan_num\",\"type\":\"uint64\"},{\"name\":\"amount\",\"type\":\"asset\"}]},{\"name\":\"defnetloan\",\"base\":\"\",\"fields\":[{\"name\":\"from\",\"type\":\"name\"},{\"name\":\"loan_num\",\"type\":\"uint64\"},{\"name\":\"amount\",\"type\":\"asset\"}]},{\"name\":\"delegatebw\",\"base\":\"\",\"fields\":[{\"name\":\"from\",\"type\":\"name\"},{\"name\":\"receiver\",\"type\":\"name\"},{\"name\":\"stake_net_quantity\",\"type\":\"asset\"},{\"name\":\"stake_cpu_quantity\",\"type\":\"asset\"},{\"name\":\"transfer\",\"type\":\"bool\"}]},{\"name\":\"delegated_bandwidth\",\"base\":\"\",\"fields\":[{\"name\":\"from\",\"type\":\"name\"},{\"name\":\"to\",\"type\":\"name\"},{\"name\":\"net_weight\",\"type\":\"asset\"},{\"name\":\"cpu_weight\",\"type\":\"asset\"}]},{\"name\":\"deleteauth\",\"base\":\"\",\"fields\":[{\"name\":\"account\",\"type\":\"name\"},{\"name\":\"permission\",\"type\":\"name\"},{\"name\":\"authorized_by\",\"type\":\"name$\"}]},{\"name\":\"deposit\",\"base\":\"\",\"fields\":[{\"name\":\"owner\",\"type\":\"name\"},{\"name\":\"amount\",\"type\":\"asset\"}]},{\"name\":\"eosio_global_state\",\"base\":\"blockchain_parameters\",\"fields\":[{\"name\":\"max_ram_size\",\"type\":\"uint64\"},{\"name\":\"total_ram_bytes_reserved\",\"type\":\"uint64\"},{\"name\":\"total_ram_stake\",\"type\":\"int64\"},{\"name\":\"last_producer_schedule_update\",\"type\":\"block_timestamp_type\"},{\"name\":\"last_pervote_bucket_fill\",\"type\":\"time_point\"},{\"name\":\"pervote_bucket\",\"type\":\"int64\"},{\"name\":\"perblock_bucket\",\"type\":\"int64\"},{\"name\":\"total_unpaid_blocks\",\"type\":\"uint32\"},{\"name\":\"total_activated_stake\",\"type\":\"int64\"},{\"name\":\"thresh_activated_stake_time\",\"type\":\"time_point\"},{\"name\":\"last_producer_schedule_size\",\"type\":\"uint16\"},{\"name\":\"total_producer_vote_weight\",\"type\":\"float64\"},{\"name\":\"last_name_close\",\"type\":\"block_timestamp_type\"}]},{\"name\":\"eosio_global_state2\",\"base\":\"\",\"fields\":[{\"name\":\"new_ram_per_block\",\"type\":\"uint16\"},{\"name\":\"last_ram_increase\",\"type\":\"block_timestamp_type\"},{\"name\":\"last_block_num\",\"type\":\"block_timestamp_type\"},{\"name\":\"total_producer_votepay_share\",\"type\":\"float64\"},{\"name\":\"revision\",\"type\":\"uint8\"}]},{\"name\":\"eosio_global_state3\",\"base\":\"\",\"fields\":[{\"name\":\"last_vpay_state_update\",\"type\":\"time_point\"},{\"name\":\"total_vpay_share_change_rate\",\"type\":\"float64\"}]},{\"name\":\"eosio_global_state4\",\"base\":\"\",\"fields\":[{\"name\":\"continuous_rate\",\"type\":\"float64\"},{\"name\":\"inflation_pay_factor\",\"type\":\"int64\"},{\"name\":\"votepay_factor\",\"type\":\"int64\"}]},{\"name\":\"exchange_state\",\"base\":\"\",\"fields\":[{\"name\":\"supply\",\"type\":\"asset\"},{\"name\":\"base\",\"type\":\"connector\"},{\"name\":\"quote\",\"type\":\"connector\"}]},{\"name\":\"fundcpuloan\",\"base\":\"\",\"fields\":[{\"name\":\"from\",\"type\":\"name\"},{\"name\":\"loan_num\",\"type\":\"uint64\"},{\"name\":\"payment\",\"type\":\"asset\"}]},{\"name\":\"fundnetloan\",\"base\":\"\",\"fields\":[{\"name\":\"from\",\"type\":\"name\"},{\"name\":\"loan_num\",\"type\":\"uint64\"},{\"name\":\"payment\",\"type\":\"asset\"}]},{\"name\":\"init\",\"base\":\"\",\"fields\":[{\"name\":\"version\",\"type\":\"varuint32\"},{\"name\":\"core\",\"type\":\"symbol\"}]},{\"name\":\"key_weight\",\"base\":\"\",\"fields\":[{\"name\":\"key\",\"type\":\"public_key\"},{\"name\":\"weight\",\"type\":\"uint16\"}]},{\"name\":\"limitauthchg\",\"base\":\"\",\"fields\":[{\"name\":\"account\",\"type\":\"name\"},{\"name\":\"allow_perms\",\"type\":\"name[]\"},{\"name\":\"disallow_perms\",\"type\":\"name[]\"}]},{\"name\":\"linkauth\",\"base\":\"\",\"fields\":[{\"name\":\"account\",\"type\":\"name\"},{\"name\":\"code\",\"type\":\"name\"},{\"name\":\"type\",\"type\":\"name\"},{\"name\":\"requirement\",\"type\":\"name\"},{\"name\":\"authorized_by\",\"type\":\"name$\"}]},{\"name\":\"mvfrsavings\",\"base\":\"\",\"fields\":[{\"name\":\"owner\",\"type\":\"name\"},{\"name\":\"rex\",\"type\":\"asset\"}]},{\"name\":\"mvtosavings\",\"base\":\"\",\"fields\":[{\"name\":\"owner\",\"type\":\"name\"},{\"name\":\"rex\",\"type\":\"asset\"}]},{\"name\":\"name_bid\",\"base\":\"\",\"fields\":[{\"name\":\"newname\",\"type\":\"name\"},{\"name\":\"high_bidder\",\"type\":\"name\"},{\"name\":\"high_bid\",\"type\":\"int64\"},{\"name\":\"last_bid_time\",\"type\":\"time_point\"}]},{\"name\":\"newaccount\",\"base\":\"\",\"fields\":[{\"name\":\"creator\",\"type\":\"name\"},{\"name\":\"name\",\"type\":\"name\"},{\"name\":\"owner\",\"type\":\"authority\"},{\"name\":\"active\",\"type\":\"authority\"}]},{\"name\":\"onblock\",\"base\":\"\",\"fields\":[{\"name\":\"header\",\"type\":\"block_header\"}]},{\"name\":\"onerror\",\"base\":\"\",\"fields\":[{\"name\":\"sender_id\",\"type\":\"uint128\"},{\"name\":\"sent_trx\",\"type\":\"bytes\"}]},{\"name\":\"pair_time_point_sec_int64\",\"base\":\"\",\"fields\":[{\"name\":\"first\",\"type\":\"time_point_sec\"},{\"name\":\"second\",\"type\":\"int64\"}]},{\"name\":\"permission_level\",\"base\":\"\",\"fields\":[{\"name\":\"actor\",\"type\":\"name\"},{\"name\":\"permission\",\"type\":\"name\"}]},{\"name\":\"permission_level_weight\",\"base\":\"\",\"fields\":[{\"name\":\"permission\",\"type\":\"permission_level\"},{\"name\":\"weight\",\"type\":\"uint16\"}]},{\"name\":\"powerup\",\"base\":\"\",\"fields\":[{\"name\":\"payer\",\"type\":\"name\"},{\"name\":\"receiver\",\"type\":\"name\"},{\"name\":\"days\",\"type\":\"uint32\"},{\"name\":\"net_frac\",\"type\":\"int64\"},{\"name\":\"cpu_frac\",\"type\":\"int64\"},{\"name\":\"max_payment\",\"type\":\"asset\"}]},{\"name\":\"powerup_config\",\"base\":\"\",\"fields\":[{\"name\":\"net\",\"type\":\"powerup_config_resource\"},{\"name\":\"cpu\",\"type\":\"powerup_config_resource\"},{\"name\":\"powerup_days\",\"type\":\"uint32?\"},{\"name\":\"min_powerup_fee\",\"type\":\"asset?\"}]},{\"name\":\"powerup_config_resource\",\"base\":\"\",\"fields\":[{\"name\":\"current_weight_ratio\",\"type\":\"int64?\"},{\"name\":\"target_weight_ratio\",\"type\":\"int64?\"},{\"name\":\"assumed_stake_weight\",\"type\":\"int64?\"},{\"name\":\"target_timestamp\",\"type\":\"time_point_sec?\"},{\"name\":\"exponent\",\"type\":\"float64?\"},{\"name\":\"decay_secs\",\"type\":\"uint32?\"},{\"name\":\"min_price\",\"type\":\"asset?\"},{\"name\":\"max_price\",\"type\":\"asset?\"}]},{\"name\":\"powerup_order\",\"base\":\"\",\"fields\":[{\"name\":\"version\",\"type\":\"uint8\"},{\"name\":\"id\",\"type\":\"uint64\"},{\"name\":\"owner\",\"type\":\"name\"},{\"name\":\"net_weight\",\"type\":\"int64\"},{\"name\":\"cpu_weight\",\"type\":\"int64\"},{\"name\":\"expires\",\"type\":\"time_point_sec\"}]},{\"name\":\"powerup_state\",\"base\":\"\",\"fields\":[{\"name\":\"version\",\"type\":\"uint8\"},{\"name\":\"net\",\"type\":\"powerup_state_resource\"},{\"name\":\"cpu\",\"type\":\"powerup_state_resource\"},{\"name\":\"powerup_days\",\"type\":\"uint32\"},{\"name\":\"min_powerup_fee\",\"type\":\"asset\"}]},{\"name\":\"powerup_state_resource\",\"base\":\"\",\"fields\":[{\"name\":\"version\",\"type\":\"uint8\"},{\"name\":\"weight\",\"type\":\"int64\"},{\"name\":\"weight_ratio\",\"type\":\"int64\"},{\"name\":\"assumed_stake_weight\",\"type\":\"int64\"},{\"name\":\"initial_weight_ratio\",\"type\":\"int64\"},{\"name\":\"target_weight_ratio\",\"type\":\"int64\"},{\"name\":\"initial_timestamp\",\"type\":\"time_point_sec\"},{\"name\":\"target_timestamp\",\"type\":\"time_point_sec\"},{\"name\":\"exponent\",\"type\":\"float64\"},{\"name\":\"decay_secs\",\"type\":\"uint32\"},{\"name\":\"min_price\",\"type\":\"asset\"},{\"name\":\"max_price\",\"type\":\"asset\"},{\"name\":\"utilization\",\"type\":\"int64\"},{\"name\":\"adjusted_utilization\",\"type\":\"int64\"},{\"name\":\"utilization_timestamp\",\"type\":\"time_point_sec\"}]},{\"name\":\"powerupexec\",\"base\":\"\",\"fields\":[{\"name\":\"user\",\"type\":\"name\"},{\"name\":\"max\",\"type\":\"uint16\"}]},{\"name\":\"producer_info\",\"base\":\"\",\"fields\":[{\"name\":\"owner\",\"type\":\"name\"},{\"name\":\"total_votes\",\"type\":\"float64\"},{\"name\":\"producer_key\",\"type\":\"public_key\"},{\"name\":\"is_active\",\"type\":\"bool\"},{\"name\":\"url\",\"type\":\"string\"},{\"name\":\"unpaid_blocks\",\"type\":\"uint32\"},{\"name\":\"last_claim_time\",\"type\":\"time_point\"},{\"name\":\"location\",\"type\":\"uint16\"},{\"name\":\"producer_authority\",\"type\":\"block_signing_authority$\"}]},{\"name\":\"producer_info2\",\"base\":\"\",\"fields\":[{\"name\":\"owner\",\"type\":\"name\"},{\"name\":\"votepay_share\",\"type\":\"float64\"},{\"name\":\"last_votepay_share_update\",\"type\":\"time_point\"}]},{\"name\":\"producer_key\",\"base\":\"\",\"fields\":[{\"name\":\"producer_name\",\"type\":\"name\"},{\"name\":\"block_signing_key\",\"type\":\"public_key\"}]},{\"name\":\"producer_schedule\",\"base\":\"\",\"fields\":[{\"name\":\"version\",\"type\":\"uint32\"},{\"name\":\"producers\",\"type\":\"producer_key[]\"}]},{\"name\":\"refund\",\"base\":\"\",\"fields\":[{\"name\":\"owner\",\"type\":\"name\"}]},{\"name\":\"refund_request\",\"base\":\"\",\"fields\":[{\"name\":\"owner\",\"type\":\"name\"},{\"name\":\"request_time\",\"type\":\"time_point_sec\"},{\"name\":\"net_amount\",\"type\":\"asset\"},{\"name\":\"cpu_amount\",\"type\":\"asset\"}]},{\"name\":\"regproducer\",\"base\":\"\",\"fields\":[{\"name\":\"producer\",\"type\":\"name\"},{\"name\":\"producer_key\",\"type\":\"public_key\"},{\"name\":\"url\",\"type\":\"string\"},{\"name\":\"location\",\"type\":\"uint16\"}]},{\"name\":\"regproducer2\",\"base\":\"\",\"fields\":[{\"name\":\"producer\",\"type\":\"name\"},{\"name\":\"producer_authority\",\"type\":\"block_signing_authority\"},{\"name\":\"url\",\"type\":\"string\"},{\"name\":\"location\",\"type\":\"uint16\"}]},{\"name\":\"regproxy\",\"base\":\"\",\"fields\":[{\"name\":\"proxy\",\"type\":\"name\"},{\"name\":\"isproxy\",\"type\":\"bool\"}]},{\"name\":\"rentcpu\",\"base\":\"\",\"fields\":[{\"name\":\"from\",\"type\":\"name\"},{\"name\":\"receiver\",\"type\":\"name\"},{\"name\":\"loan_payment\",\"type\":\"asset\"},{\"name\":\"loan_fund\",\"type\":\"asset\"}]},{\"name\":\"rentnet\",\"base\":\"\",\"fields\":[{\"name\":\"from\",\"type\":\"name\"},{\"name\":\"receiver\",\"type\":\"name\"},{\"name\":\"loan_payment\",\"type\":\"asset\"},{\"name\":\"loan_fund\",\"type\":\"asset\"}]},{\"name\":\"rex_balance\",\"base\":\"\",\"fields\":[{\"name\":\"version\",\"type\":\"uint8\"},{\"name\":\"owner\",\"type\":\"name\"},{\"name\":\"vote_stake\",\"type\":\"asset\"},{\"name\":\"rex_balance\",\"type\":\"asset\"},{\"name\":\"matured_rex\",\"type\":\"int64\"},{\"name\":\"rex_maturities\",\"type\":\"pair_time_point_sec_int64[]\"}]},{\"name\":\"rex_fund\",\"base\":\"\",\"fields\":[{\"name\":\"version\",\"type\":\"uint8\"},{\"name\":\"owner\",\"type\":\"name\"},{\"name\":\"balance\",\"type\":\"asset\"}]},{\"name\":\"rex_loan\",\"base\":\"\",\"fields\":[{\"name\":\"version\",\"type\":\"uint8\"},{\"name\":\"from\",\"type\":\"name\"},{\"name\":\"receiver\",\"type\":\"name\"},{\"name\":\"payment\",\"type\":\"asset\"},{\"name\":\"balance\",\"type\":\"asset\"},{\"name\":\"total_staked\",\"type\":\"asset\"},{\"name\":\"loan_num\",\"type\":\"uint64\"},{\"name\":\"expiration\",\"type\":\"time_point\"}]},{\"name\":\"rex_order\",\"base\":\"\",\"fields\":[{\"name\":\"version\",\"type\":\"uint8\"},{\"name\":\"owner\",\"type\":\"name\"},{\"name\":\"rex_requested\",\"type\":\"asset\"},{\"name\":\"proceeds\",\"type\":\"asset\"},{\"name\":\"stake_change\",\"type\":\"asset\"},{\"name\":\"order_time\",\"type\":\"time_point\"},{\"name\":\"is_open\",\"type\":\"bool\"}]},{\"name\":\"rex_pool\",\"base\":\"\",\"fields\":[{\"name\":\"version\",\"type\":\"uint8\"},{\"name\":\"total_lent\",\"type\":\"asset\"},{\"name\":\"total_unlent\",\"type\":\"asset\"},{\"name\":\"total_rent\",\"type\":\"asset\"},{\"name\":\"total_lendable\",\"type\":\"asset\"},{\"name\":\"total_rex\",\"type\":\"asset\"},{\"name\":\"namebid_proceeds\",\"type\":\"asset\"},{\"name\":\"loan_num\",\"type\":\"uint64\"}]},{\"name\":\"rex_return_buckets\",\"base\":\"\",\"fields\":[{\"name\":\"version\",\"type\":\"uint8\"},{\"name\":\"return_buckets\",\"type\":\"pair_time_point_sec_int64[]\"}]},{\"name\":\"rex_return_pool\",\"base\":\"\",\"fields\":[{\"name\":\"version\",\"type\":\"uint8\"},{\"name\":\"last_dist_time\",\"type\":\"time_point_sec\"},{\"name\":\"pending_bucket_time\",\"type\":\"time_point_sec\"},{\"name\":\"oldest_bucket_time\",\"type\":\"time_point_sec\"},{\"name\":\"pending_bucket_proceeds\",\"type\":\"int64\"},{\"name\":\"current_rate_of_increase\",\"type\":\"int64\"},{\"name\":\"proceeds\",\"type\":\"int64\"}]},{\"name\":\"rexexec\",\"base\":\"\",\"fields\":[{\"name\":\"user\",\"type\":\"name\"},{\"name\":\"max\",\"type\":\"uint16\"}]},{\"name\":\"rmvproducer\",\"base\":\"\",\"fields\":[{\"name\":\"producer\",\"type\":\"name\"}]},{\"name\":\"sellram\",\"base\":\"\",\"fields\":[{\"name\":\"account\",\"type\":\"name\"},{\"name\":\"bytes\",\"type\":\"int64\"}]},{\"name\":\"sellrex\",\"base\":\"\",\"fields\":[{\"name\":\"from\",\"type\":\"name\"},{\"name\":\"rex\",\"type\":\"asset\"}]},{\"name\":\"setabi\",\"base\":\"\",\"fields\":[{\"name\":\"account\",\"type\":\"name\"},{\"name\":\"abi\",\"type\":\"bytes\"},{\"name\":\"memo\",\"type\":\"string$\"}]},{\"name\":\"setacctcpu\",\"base\":\"\",\"fields\":[{\"name\":\"account\",\"type\":\"name\"},{\"name\":\"cpu_weight\",\"type\":\"int64?\"}]},{\"name\":\"setacctnet\",\"base\":\"\",\"fields\":[{\"name\":\"account\",\"type\":\"name\"},{\"name\":\"net_weight\",\"type\":\"int64?\"}]},{\"name\":\"setacctram\",\"base\":\"\",\"fields\":[{\"name\":\"account\",\"type\":\"name\"},{\"name\":\"ram_bytes\",\"type\":\"int64?\"}]},{\"name\":\"setalimits\",\"base\":\"\",\"fields\":[{\"name\":\"account\",\"type\":\"name\"},{\"name\":\"ram_bytes\",\"type\":\"int64\"},{\"name\":\"net_weight\",\"type\":\"int64\"},{\"name\":\"cpu_weight\",\"type\":\"int64\"}]},{\"name\":\"setcode\",\"base\":\"\",\"fields\":[{\"name\":\"account\",\"type\":\"name\"},{\"name\":\"vmtype\",\"type\":\"uint8\"},{\"name\":\"vmversion\",\"type\":\"uint8\"},{\"name\":\"code\",\"type\":\"bytes\"},{\"name\":\"memo\",\"type\":\"string$\"}]},{\"name\":\"setinflation\",\"base\":\"\",\"fields\":[{\"name\":\"annual_rate\",\"type\":\"int64\"},{\"name\":\"inflation_pay_factor\",\"type\":\"int64\"},{\"name\":\"votepay_factor\",\"type\":\"int64\"}]},{\"name\":\"setparams\",\"base\":\"\",\"fields\":[{\"name\":\"params\",\"type\":\"blockchain_parameters_t\"}]},{\"name\":\"setpriv\",\"base\":\"\",\"fields\":[{\"name\":\"account\",\"type\":\"name\"},{\"name\":\"is_priv\",\"type\":\"uint8\"}]},{\"name\":\"setram\",\"base\":\"\",\"fields\":[{\"name\":\"max_ram_size\",\"type\":\"uint64\"}]},{\"name\":\"setramrate\",\"base\":\"\",\"fields\":[{\"name\":\"bytes_per_block\",\"type\":\"uint16\"}]},{\"name\":\"setrex\",\"base\":\"\",\"fields\":[{\"name\":\"balance\",\"type\":\"asset\"}]},{\"name\":\"undelegatebw\",\"base\":\"\",\"fields\":[{\"name\":\"from\",\"type\":\"name\"},{\"name\":\"receiver\",\"type\":\"name\"},{\"name\":\"unstake_net_quantity\",\"type\":\"asset\"},{\"name\":\"unstake_cpu_quantity\",\"type\":\"asset\"}]},{\"name\":\"unlinkauth\",\"base\":\"\",\"fields\":[{\"name\":\"account\",\"type\":\"name\"},{\"name\":\"code\",\"type\":\"name\"},{\"name\":\"type\",\"type\":\"name\"},{\"name\":\"authorized_by\",\"type\":\"name$\"}]},{\"name\":\"unregprod\",\"base\":\"\",\"fields\":[{\"name\":\"producer\",\"type\":\"name\"}]},{\"name\":\"unstaketorex\",\"base\":\"\",\"fields\":[{\"name\":\"owner\",\"type\":\"name\"},{\"name\":\"receiver\",\"type\":\"name\"},{\"name\":\"from_net\",\"type\":\"asset\"},{\"name\":\"from_cpu\",\"type\":\"asset\"}]},{\"name\":\"updateauth\",\"base\":\"\",\"fields\":[{\"name\":\"account\",\"type\":\"name\"},{\"name\":\"permission\",\"type\":\"name\"},{\"name\":\"parent\",\"type\":\"name\"},{\"name\":\"auth\",\"type\":\"authority\"},{\"name\":\"authorized_by\",\"type\":\"name$\"}]},{\"name\":\"updaterex\",\"base\":\"\",\"fields\":[{\"name\":\"owner\",\"type\":\"name\"}]},{\"name\":\"updtrevision\",\"base\":\"\",\"fields\":[{\"name\":\"revision\",\"type\":\"uint8\"}]},{\"name\":\"user_resources\",\"base\":\"\",\"fields\":[{\"name\":\"owner\",\"type\":\"name\"},{\"name\":\"net_weight\",\"type\":\"asset\"},{\"name\":\"cpu_weight\",\"type\":\"asset\"},{\"name\":\"ram_bytes\",\"type\":\"int64\"}]},{\"name\":\"voteproducer\",\"base\":\"\",\"fields\":[{\"name\":\"voter\",\"type\":\"name\"},{\"name\":\"proxy\",\"type\":\"name\"},{\"name\":\"producers\",\"type\":\"name[]\"}]},{\"name\":\"voter_info\",\"base\":\"\",\"fields\":[{\"name\":\"owner\",\"type\":\"name\"},{\"name\":\"proxy\",\"type\":\"name\"},{\"name\":\"producers\",\"type\":\"name[]\"},{\"name\":\"staked\",\"type\":\"int64\"},{\"name\":\"last_vote_weight\",\"type\":\"float64\"},{\"name\":\"proxied_vote_weight\",\"type\":\"float64\"},{\"name\":\"is_proxy\",\"type\":\"bool\"},{\"name\":\"flags1\",\"type\":\"uint32\"},{\"name\":\"reserved2\",\"type\":\"uint32\"},{\"name\":\"reserved3\",\"type\":\"asset\"}]},{\"name\":\"voteupdate\",\"base\":\"\",\"fields\":[{\"name\":\"voter_name\",\"type\":\"name\"}]},{\"name\":\"wait_weight\",\"base\":\"\",\"fields\":[{\"name\":\"wait_sec\",\"type\":\"uint32\"},{\"name\":\"weight\",\"type\":\"uint16\"}]},{\"name\":\"wasmcfg\",\"base\":\"\",\"fields\":[{\"name\":\"settings\",\"type\":\"name\"}]},{\"name\":\"withdraw\",\"base\":\"\",\"fields\":[{\"name\":\"owner\",\"type\":\"name\"},{\"name\":\"amount\",\"type\":\"asset\"}]},{\"name\":\"limit_auth_change\",\"base\":\"\",\"fields\":[{\"name\":\"version\",\"type\":\"uint8\"},{\"name\":\"account\",\"type\":\"name\"},{\"name\":\"allow_perms\",\"type\":\"name[]\"},{\"name\":\"disallow_perms\",\"type\":\"name[]\"}]}],\"actions\":[{\"name\":\"activate\",\"type\":\"activate\",\"ricardian_contract\":\"\"},{\"name\":\"bidname\",\"type\":\"bidname\",\"ricardian_contract\":\"\"},{\"name\":\"bidrefund\",\"type\":\"bidrefund\",\"ricardian_contract\":\"\"},{\"name\":\"buyram\",\"type\":\"buyram\",\"ricardian_contract\":\"\"},{\"name\":\"buyrambytes\",\"type\":\"buyrambytes\",\"ricardian_contract\":\"\"},{\"name\":\"buyrex\",\"type\":\"buyrex\",\"ricardian_contract\":\"\"},{\"name\":\"canceldelay\",\"type\":\"canceldelay\",\"ricardian_contract\":\"\"},{\"name\":\"cfgpowerup\",\"type\":\"cfgpowerup\",\"ricardian_contract\":\"\"},{\"name\":\"claimrewards\",\"type\":\"claimrewards\",\"ricardian_contract\":\"\"},{\"name\":\"closerex\",\"type\":\"closerex\",\"ricardian_contract\":\"\"},{\"name\":\"cnclrexorder\",\"type\":\"cnclrexorder\",\"ricardian_contract\":\"\"},{\"name\":\"consolidate\",\"type\":\"consolidate\",\"ricardian_contract\":\"\"},{\"name\":\"defcpuloan\",\"type\":\"defcpuloan\",\"ricardian_contract\":\"\"},{\"name\":\"defnetloan\",\"type\":\"defnetloan\",\"ricardian_contract\":\"\"},{\"name\":\"delegatebw\",\"type\":\"delegatebw\",\"ricardian_contract\":\"\"},{\"name\":\"deleteauth\",\"type\":\"deleteauth\",\"ricardian_contract\":\"\"},{\"name\":\"deposit\",\"type\":\"deposit\",\"ricardian_contract\":\"\"},{\"name\":\"fundcpuloan\",\"type\":\"fundcpuloan\",\"ricardian_contract\":\"\"},{\"name\":\"fundnetloan\",\"type\":\"fundnetloan\",\"ricardian_contract\":\"\"},{\"name\":\"init\",\"type\":\"init\",\"ricardian_contract\":\"\"},{\"name\":\"limitauthchg\",\"type\":\"limitauthchg\",\"ricardian_contract\":\"\"},{\"name\":\"linkauth\",\"type\":\"linkauth\",\"ricardian_contract\":\"\"},{\"name\":\"mvfrsavings\",\"type\":\"mvfrsavings\",\"ricardian_contract\":\"\"},{\"name\":\"mvtosavings\",\"type\":\"mvtosavings\",\"ricardian_contract\":\"\"},{\"name\":\"newaccount\",\"type\":\"newaccount\",\"ricardian_contract\":\"\"},{\"name\":\"onblock\",\"type\":\"onblock\",\"ricardian_contract\":\"\"},{\"name\":\"onerror\",\"type\":\"onerror\",\"ricardian_contract\":\"\"},{\"name\":\"powerup\",\"type\":\"powerup\",\"ricardian_contract\":\"\"},{\"name\":\"powerupexec\",\"type\":\"powerupexec\",\"ricardian_contract\":\"\"},{\"name\":\"refund\",\"type\":\"refund\",\"ricardian_contract\":\"\"},{\"name\":\"regproducer\",\"type\":\"regproducer\",\"ricardian_contract\":\"\"},{\"name\":\"regproducer2\",\"type\":\"regproducer2\",\"ricardian_contract\":\"\"},{\"name\":\"regproxy\",\"type\":\"regproxy\",\"ricardian_contract\":\"\"},{\"name\":\"rentcpu\",\"type\":\"rentcpu\",\"ricardian_contract\":\"\"},{\"name\":\"rentnet\",\"type\":\"rentnet\",\"ricardian_contract\":\"\"},{\"name\":\"rexexec\",\"type\":\"rexexec\",\"ricardian_contract\":\"\"},{\"name\":\"rmvproducer\",\"type\":\"rmvproducer\",\"ricardian_contract\":\"\"},{\"name\":\"sellram\",\"type\":\"sellram\",\"ricardian_contract\":\"\"},{\"name\":\"sellrex\",\"type\":\"sellrex\",\"ricardian_contract\":\"\"},{\"name\":\"setabi\",\"type\":\"setabi\",\"ricardian_contract\":\"\"},{\"name\":\"setacctcpu\",\"type\":\"setacctcpu\",\"ricardian_contract\":\"\"},{\"name\":\"setacctnet\",\"type\":\"setacctnet\",\"ricardian_contract\":\"\"},{\"name\":\"setacctram\",\"type\":\"setacctram\",\"ricardian_contract\":\"\"},{\"name\":\"setalimits\",\"type\":\"setalimits\",\"ricardian_contract\":\"\"},{\"name\":\"setcode\",\"type\":\"setcode\",\"ricardian_contract\":\"\"},{\"name\":\"setinflation\",\"type\":\"setinflation\",\"ricardian_contract\":\"\"},{\"name\":\"setparams\",\"type\":\"setparams\",\"ricardian_contract\":\"\"},{\"name\":\"setpriv\",\"type\":\"setpriv\",\"ricardian_contract\":\"\"},{\"name\":\"setram\",\"type\":\"setram\",\"ricardian_contract\":\"\"},{\"name\":\"setramrate\",\"type\":\"setramrate\",\"ricardian_contract\":\"\"},{\"name\":\"setrex\",\"type\":\"setrex\",\"ricardian_contract\":\"\"},{\"name\":\"undelegatebw\",\"type\":\"undelegatebw\",\"ricardian_contract\":\"\"},{\"name\":\"unlinkauth\",\"type\":\"unlinkauth\",\"ricardian_contract\":\"\"},{\"name\":\"unregprod\",\"type\":\"unregprod\",\"ricardian_contract\":\"\"},{\"name\":\"unstaketorex\",\"type\":\"unstaketorex\",\"ricardian_contract\":\"\"},{\"name\":\"updateauth\",\"type\":\"updateauth\",\"ricardian_contract\":\"\"},{\"name\":\"updaterex\",\"type\":\"updaterex\",\"ricardian_contract\":\"\"},{\"name\":\"updtrevision\",\"type\":\"updtrevision\",\"ricardian_contract\":\"\"},{\"name\":\"voteproducer\",\"type\":\"voteproducer\",\"ricardian_contract\":\"\"},{\"name\":\"voteupdate\",\"type\":\"voteupdate\",\"ricardian_contract\":\"\"},{\"name\":\"wasmcfg\",\"type\":\"wasmcfg\",\"ricardian_contract\":\"\"},{\"name\":\"withdraw\",\"type\":\"withdraw\",\"ricardian_contract\":\"\"}],\"tables\":[{\"name\":\"abihash\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"abi_hash\"},{\"name\":\"bidrefunds\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"bid_refund\"},{\"name\":\"blockinfo\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"block_info_record\"},{\"name\":\"cpuloan\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"rex_loan\"},{\"name\":\"delband\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"delegated_bandwidth\"},{\"name\":\"global\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"eosio_global_state\"},{\"name\":\"global2\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"eosio_global_state2\"},{\"name\":\"global3\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"eosio_global_state3\"},{\"name\":\"global4\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"eosio_global_state4\"},{\"name\":\"namebids\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"name_bid\"},{\"name\":\"netloan\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"rex_loan\"},{\"name\":\"powup.order\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"powerup_order\"},{\"name\":\"powup.state\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"powerup_state\"},{\"name\":\"producers\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"producer_info\"},{\"name\":\"producers2\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"producer_info2\"},{\"name\":\"rammarket\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"exchange_state\"},{\"name\":\"refunds\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"refund_request\"},{\"name\":\"retbuckets\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"rex_return_buckets\"},{\"name\":\"rexbal\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"rex_balance\"},{\"name\":\"rexfund\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"rex_fund\"},{\"name\":\"rexpool\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"rex_pool\"},{\"name\":\"rexqueue\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"rex_order\"},{\"name\":\"rexretpool\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"rex_return_pool\"},{\"name\":\"userres\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"user_resources\"},{\"name\":\"voters\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"voter_info\"},{\"name\":\"limitauthchg\",\"index_type\":\"i64\",\"key_names\":[],\"key_types\":[],\"type\":\"limit_auth_change\"}],\"ricardian_clauses\":[],\"error_messages\":[],\"abi_extensions\":[],\"variants\":[{\"name\":\"variant_block_signing_authority_v0\",\"types\":[\"block_signing_authority_v0\"]}],\"action_results\":[]}}" +} \ No newline at end of file diff --git a/test/data/bb8eb516c09f8a37a8d53fff0132d67c1ddfbfa1.json b/test/data/bb8eb516c09f8a37a8d53fff0132d67c1ddfbfa1.json new file mode 100644 index 00000000..d83cebcb --- /dev/null +++ b/test/data/bb8eb516c09f8a37a8d53fff0132d67c1ddfbfa1.json @@ -0,0 +1,52 @@ +{ + "request": { + "path": "https://jungle4.greymass.com/v1/resource_provider/request_transaction", + "params": { + "method": "POST", + "body": "{\"ref\":\"unittest\",\"request\":\"esr://gmNgZPITm5j8mV1jdVUvAxAwggiGVwahDZdNY2Jf-rgwBrhw3DxY6vsYLDFh4ymOho0T42LVek-B1AIA\",\"signer\":{\"actor\":\"wharfkit1125\",\"permission\":\"test\"}}" + } + }, + "status": 400, + "json": { + "code": 400, + "message": "Unable to process and sample transaction", + "data": { + "request": "esr://gmNgZPITm5j8mV1jdVUvAxAwggiGVwahDZdNY2Jf-rgwBrhw3DxY6vsYLDFh4ymOho0T42LVek-B1AIA", + "error": { + "path": "/v1/chain/compute_transaction", + "response": { + "headers": { + "access-control-allow-headers": "X-Requested-With,Accept,Content-Type,Origin", + "access-control-allow-methods": "GET, POST, OPTIONS", + "access-control-allow-origin": "*", + "connection": "close", + "content-length": "407", + "content-type": "application/json", + "date": "Wed, 26 Jul 2023 04:58:04 GMT", + "server": "nginx/1.18.0 (Ubuntu)" + }, + "status": 500, + "json": { + "code": 500, + "message": "Internal Service Error", + "error": { + "code": 3040005, + "name": "expired_tx_exception", + "what": "Expired Transaction", + "details": [ + { + "message": "expired transaction 1775ff8bdd5247a27f2a12015bd78b8d0660f40dac10a10f6c288fdecd530649, expiration 2022-12-07T22:40:14.000, block time 2023-07-26T04:58:04.500", + "file": "producer_plugin.cpp", + "line_number": 658, + "method": "process_incoming_transaction_async" + } + ] + } + }, + "text": "{\"code\":500,\"message\":\"Internal Service Error\",\"error\":{\"code\":3040005,\"name\":\"expired_tx_exception\",\"what\":\"Expired Transaction\",\"details\":[{\"message\":\"expired transaction 1775ff8bdd5247a27f2a12015bd78b8d0660f40dac10a10f6c288fdecd530649, expiration 2022-12-07T22:40:14.000, block time 2023-07-26T04:58:04.500\",\"file\":\"producer_plugin.cpp\",\"line_number\":658,\"method\":\"process_incoming_transaction_async\"}]}}" + } + } + } + }, + "text": "{\"code\":400,\"message\":\"Unable to process and sample transaction\",\"data\":{\"request\":\"esr://gmNgZPITm5j8mV1jdVUvAxAwggiGVwahDZdNY2Jf-rgwBrhw3DxY6vsYLDFh4ymOho0T42LVek-B1AIA\",\"error\":{\"path\":\"/v1/chain/compute_transaction\",\"response\":{\"headers\":{\"access-control-allow-headers\":\"X-Requested-With,Accept,Content-Type,Origin\",\"access-control-allow-methods\":\"GET, POST, OPTIONS\",\"access-control-allow-origin\":\"*\",\"connection\":\"close\",\"content-length\":\"407\",\"content-type\":\"application/json\",\"date\":\"Wed, 26 Jul 2023 04:58:04 GMT\",\"server\":\"nginx/1.18.0 (Ubuntu)\"},\"status\":500,\"json\":{\"code\":500,\"message\":\"Internal Service Error\",\"error\":{\"code\":3040005,\"name\":\"expired_tx_exception\",\"what\":\"Expired Transaction\",\"details\":[{\"message\":\"expired transaction 1775ff8bdd5247a27f2a12015bd78b8d0660f40dac10a10f6c288fdecd530649, expiration 2022-12-07T22:40:14.000, block time 2023-07-26T04:58:04.500\",\"file\":\"producer_plugin.cpp\",\"line_number\":658,\"method\":\"process_incoming_transaction_async\"}]}},\"text\":\"{\\\"code\\\":500,\\\"message\\\":\\\"Internal Service Error\\\",\\\"error\\\":{\\\"code\\\":3040005,\\\"name\\\":\\\"expired_tx_exception\\\",\\\"what\\\":\\\"Expired Transaction\\\",\\\"details\\\":[{\\\"message\\\":\\\"expired transaction 1775ff8bdd5247a27f2a12015bd78b8d0660f40dac10a10f6c288fdecd530649, expiration 2022-12-07T22:40:14.000, block time 2023-07-26T04:58:04.500\\\",\\\"file\\\":\\\"producer_plugin.cpp\\\",\\\"line_number\\\":658,\\\"method\\\":\\\"process_incoming_transaction_async\\\"}]}}\"}}}}" +} \ No newline at end of file diff --git a/test/rollup.config.js b/test/rollup.config.js index 2c85b73b..910d7698 100644 --- a/test/rollup.config.js +++ b/test/rollup.config.js @@ -91,7 +91,7 @@ export default [ entries: [ {find: '$lib', replacement: path.join(__dirname, '..', 'lib/session.m.js')}, { - find: '$test/utils/mock-fetch', + find: '@wharfkit/mock-data', replacement: './test/utils/browser-fetch.ts', }, ], diff --git a/test/tests/abi.ts b/test/tests/abi.ts index 0826431c..95e0075b 100644 --- a/test/tests/abi.ts +++ b/test/tests/abi.ts @@ -1,4 +1,4 @@ -import {makeClient} from '$test/utils/mock-client' +import {makeClient} from '@wharfkit/mock-data' import {ABI, ABICache, Name} from '@wharfkit/session' import {assert} from 'chai' diff --git a/test/tests/context.ts b/test/tests/context.ts index defe9b14..06b26df2 100644 --- a/test/tests/context.ts +++ b/test/tests/context.ts @@ -4,16 +4,16 @@ import {Checksum256, PermissionLevel, Transaction} from '@greymass/eosio' import zlib from 'pako' import {SigningRequest} from '$lib' -import {makeMockAction} from '$test/utils/mock-transfer' +import {makeMockAction} from '@wharfkit/mock-data' -import {makeContext} from '$test/utils/mock-context' +import {makeContext} from '@wharfkit/mock-data' const context = makeContext() suite('context', function () { - suite('abiProvider', function () { + suite('abiCache', function () { test('has default', function () { - assert.isDefined(context.abiProvider) + assert.isDefined(context.abiCache) }) }) suite('getters', function () { diff --git a/test/tests/hooks.ts b/test/tests/hooks.ts index 1ce9fd6b..428099fb 100644 --- a/test/tests/hooks.ts +++ b/test/tests/hooks.ts @@ -1,19 +1,15 @@ import {beforeSignHooks} from './plugins/hooks/beforeSign' -import {afterSignHooks} from './plugins/hooks/afterSign' -import {afterBroadcastHooks} from './plugins/hooks/afterBroadcast' -import {beforeLoginHooks} from './plugins/hooks/beforeLogin' -import {afterLoginHooks} from './plugins/hooks/afterLogin' suite('hooks', function () { // Perform transact hook tests within ./tests/plugins/hooks suite('transactHooks', function () { beforeSignHooks() - afterSignHooks() - afterBroadcastHooks() + // afterSignHooks() + // afterBroadcastHooks() }) // Perform login hook tests suite('loginHooks', function () { - beforeLoginHooks() - afterLoginHooks() + // beforeLoginHooks() + // afterLoginHooks() }) }) diff --git a/test/tests/kit.ts b/test/tests/kit.ts index 28d0ad83..47b14dff 100644 --- a/test/tests/kit.ts +++ b/test/tests/kit.ts @@ -12,18 +12,18 @@ import { UserInterfaceLoginResponse, } from '$lib' -import {makeWallet, MockWalletPluginConfigs} from '$test/utils/mock-wallet' -import {MockTransactPlugin} from '$test/utils/mock-hook' -import {makeMockAction} from '$test/utils/mock-transfer' +import {makeWallet, MockWalletPluginConfigs} from '@wharfkit/mock-data' +import {MockTransactPlugin} from '@wharfkit/mock-data' +import {makeMockAction} from '@wharfkit/mock-data' import { mockChainDefinition, mockChainDefinitions, mockChainId, mockPermissionLevel, -} from '$test/utils/mock-config' -import {MockUserInterface} from '$test/utils/mock-userinterface' -import {mockSessionKit, mockSessionKitOptions} from '$test/utils/mock-session' -import {MockStorage} from '$test/utils/mock-storage' +} from '@wharfkit/mock-data' +import {MockUserInterface} from '@wharfkit/mock-data' +import {mockSessionKit, mockSessionKitArgs, mockSessionKitOptions} from '@wharfkit/mock-data' +import {MockStorage} from '@wharfkit/mock-data' const action = makeMockAction() @@ -34,7 +34,7 @@ const defaultLoginOptions = { function assertSessionMatchesMockSession(session: Session) { assert.instanceOf(session, Session) - assert.isTrue(session.appName?.equals(mockSessionKitOptions.appName)) + assert.isTrue(session.appName?.equals(mockSessionKitArgs.appName)) assert.equal(session.allowModify, true) assert.equal(session.broadcast, true) assert.equal(session.expireSeconds, 120) @@ -45,7 +45,7 @@ function assertSessionMatchesMockSession(session: Session) { suite('kit', function () { let sessionKit setup(async function () { - sessionKit = new SessionKit({...mockSessionKitOptions}) + sessionKit = new SessionKit(mockSessionKitArgs, mockSessionKitOptions) await sessionKit.logout() }) suite('construct', function () { @@ -53,6 +53,63 @@ suite('kit', function () { assert.instanceOf(sessionKit, SessionKit) }) suite('options', function () { + suite('abis', function () { + test('passing for all sessions', async function () { + const abi = { + version: 'eosio::abi/1.2', + types: [], + structs: [ + { + name: 'transfer', + base: '', + fields: [ + { + name: 'from', + type: 'name', + }, + { + name: 'to', + type: 'name', + }, + { + name: 'quantity', + type: 'asset', + }, + { + name: 'memo', + type: 'string', + }, + ], + }, + ], + actions: [ + { + name: 'transfer', + type: 'transfer', + ricardian_contract: '', + }, + ], + tables: [], + ricardian_clauses: [], + error_messages: [], + abi_extensions: [], + variants: [], + action_results: [], + } + const sessionKit = new SessionKit(mockSessionKitArgs, { + ...mockSessionKitOptions, + abis: [ + { + account: 'eosio.token', + abi, + }, + ], + }) + assert.lengthOf(sessionKit.abis, 1) + const {session} = await sessionKit.login() + assert.lengthOf(session.abis, 1) + }) + }) suite('expireSeconds', function () { test('default: 120', async function () { const {session} = await sessionKit.login(defaultLoginOptions) @@ -66,7 +123,7 @@ suite('kit', function () { ) }) test('override: 60', async function () { - const sessionKit = new SessionKit({ + const sessionKit = new SessionKit(mockSessionKitArgs, { ...mockSessionKitOptions, expireSeconds: 60, }) @@ -89,7 +146,7 @@ suite('kit', function () { assert.instanceOf(sessionKit.transactPlugins[0], BaseTransactPlugin) }) test('override', async function () { - const sessionKit = new SessionKit({ + const sessionKit = new SessionKit(mockSessionKitArgs, { ...mockSessionKitOptions, transactPlugins: [new MockTransactPlugin()], }) @@ -175,16 +232,19 @@ suite('kit', function () { ) }) test('default logo', async function () { - const sessionKit = new SessionKit({ - ...mockSessionKitOptions, - chains: [ - { - id: '4667b205c6838ef70ff7988f6e8257e8be0e1284a2f59699054a018f743b1d11', - url: 'https://telos.greymass.com', - logo: 'https://assets.wharfkit.com/chain/telos.png', - }, - ], - }) + const sessionKit = new SessionKit( + { + ...mockSessionKitArgs, + chains: [ + { + id: '4667b205c6838ef70ff7988f6e8257e8be0e1284a2f59699054a018f743b1d11', + url: 'https://telos.greymass.com', + logo: 'https://assets.wharfkit.com/chain/telos.png', + }, + ], + }, + mockSessionKitOptions + ) assert.instanceOf(sessionKit.chains[0], ChainDefinition) assert.instanceOf(sessionKit.chains[0].id, Checksum256) assert.instanceOf(sessionKit.chains[0].logo, Logo) @@ -195,21 +255,24 @@ suite('kit', function () { assert.isString(sessionKit.chains[0].name) }) test('specify logo', async function () { - const sessionKit = new SessionKit({ - ...mockSessionKitOptions, - chains: [ - { - id: '4667b205c6838ef70ff7988f6e8257e8be0e1284a2f59699054a018f743b1d11', - url: 'https://telos.greymass.com', - logo: 'https://assets.wharfkit.com/chain/eos.png', - explorer: { - prefix: 'https://explorer.telos.net/transaction/', - suffix: '', - url: (id) => this.prefix + id + this.suffix, + const sessionKit = new SessionKit( + { + ...mockSessionKitArgs, + chains: [ + { + id: '4667b205c6838ef70ff7988f6e8257e8be0e1284a2f59699054a018f743b1d11', + url: 'https://telos.greymass.com', + logo: 'https://assets.wharfkit.com/chain/eos.png', + explorer: { + prefix: 'https://explorer.telos.net/transaction/', + suffix: '', + url: (id) => this.prefix + id + this.suffix, + }, }, - }, - ], - }) + ], + }, + mockSessionKitOptions + ) assert.instanceOf(sessionKit.chains[0], ChainDefinition) assert.instanceOf(sessionKit.chains[0].id, Checksum256) assert.instanceOf(sessionKit.chains[0].logo, Logo) @@ -287,18 +350,34 @@ suite('kit', function () { assertSessionMatchesMockSession(restored) }) test('no session returns undefined', async function () { - const sessionKit = new SessionKit({ + const sessionKit = new SessionKit(mockSessionKitArgs, { ...mockSessionKitOptions, storage: new MockStorage(), }) const restored = await sessionKit.restore() assert.isUndefined(restored) }) - test('throws if wallet not found', async function () { - const sessionKit = new SessionKit({ - ...mockSessionKitOptions, - walletPlugins: [new MockWalletPluginConfigs()], + test('can restore with just actor, permission, and chainId', async function () { + const {session} = await sessionKit.login() + const mockSerializedSession = session.serialize() + const restored = await mockSessionKit.restore({ + actor: mockSerializedSession.actor, + permission: mockSerializedSession.permission, + chain: mockSerializedSession.chain, }) + if (!restored) { + throw new Error('Failed to restore session') + } + assertSessionMatchesMockSession(restored) + }) + test('throws if wallet not found', async function () { + const sessionKit = new SessionKit( + { + ...mockSessionKitArgs, + walletPlugins: [new MockWalletPluginConfigs()], + }, + mockSessionKitOptions + ) const {session} = await sessionKit.login() const mockSerializedSession = session.serialize() let error @@ -312,7 +391,7 @@ suite('kit', function () { }) suite('restoreAll', function () { test('restores no sessions', async function () { - const sessionKit = new SessionKit({ + const sessionKit = new SessionKit(mockSessionKitArgs, { ...mockSessionKitOptions, storage: new MockStorage(), }) @@ -323,7 +402,7 @@ suite('kit', function () { }) test('restores all sessions', async function () { // New kit w/ empty storage - const sessionKit = new SessionKit({ + const sessionKit = new SessionKit(mockSessionKitArgs, { ...mockSessionKitOptions, storage: new MockStorage(), }) @@ -359,30 +438,36 @@ suite('kit', function () { assert.instanceOf(session.ui, MockUserInterface) }) test('override', async function () { - const sessionKit = new SessionKit({ - ...mockSessionKitOptions, - ui: new MockUserInterface(), - }) + const sessionKit = new SessionKit( + {...mockSessionKitArgs, ui: new MockUserInterface()}, + mockSessionKitOptions + ) assert.instanceOf(sessionKit.ui, MockUserInterface) const {session} = await sessionKit.login(defaultLoginOptions) assert.instanceOf(session.ui, MockUserInterface) }) suite('onSelectWallet', function () { test('if 1 walletPlugin, use it without UI selection', async function () { - const sessionKit = new SessionKit({ - ...mockSessionKitOptions, - walletPlugins: [makeWallet()], - }) + const sessionKit = new SessionKit( + { + ...mockSessionKitArgs, + walletPlugins: [makeWallet()], + }, + mockSessionKitOptions + ) const {session} = await sessionKit.login({ permissionLevel: mockPermissionLevel, }) assertSessionMatchesMockSession(session) }) test('if >1 walletPlugin, force selection', async function () { - const sessionKit = new SessionKit({ - ...mockSessionKitOptions, - walletPlugins: [makeWallet(), makeWallet()], - }) + const sessionKit = new SessionKit( + { + ...mockSessionKitArgs, + walletPlugins: [makeWallet(), makeWallet()], + }, + mockSessionKitOptions + ) const {session} = await sessionKit.login({ permissionLevel: mockPermissionLevel, }) @@ -398,11 +483,14 @@ suite('kit', function () { } } } - const sessionKit = new SessionKit({ - ...mockSessionKitOptions, - ui: new FailingUI(), - walletPlugins: [makeWallet(), makeWallet()], - }) + const sessionKit = new SessionKit( + { + ...mockSessionKitArgs, + ui: new FailingUI(), + walletPlugins: [makeWallet(), makeWallet()], + }, + mockSessionKitOptions + ) let error try { await sessionKit.login() diff --git a/test/tests/plugins/hooks/afterBroadcast.ts b/test/tests/plugins/hooks/afterBroadcast.ts deleted file mode 100644 index e48c2c2b..00000000 --- a/test/tests/plugins/hooks/afterBroadcast.ts +++ /dev/null @@ -1,7 +0,0 @@ -import {assert} from 'chai' - -export const afterBroadcastHooks = () => { - suite('afterBroadcast', function () { - test('TODO', async function () {}) - }) -} diff --git a/test/tests/plugins/hooks/afterLogin.ts b/test/tests/plugins/hooks/afterLogin.ts deleted file mode 100644 index fc1652d8..00000000 --- a/test/tests/plugins/hooks/afterLogin.ts +++ /dev/null @@ -1,7 +0,0 @@ -import {assert} from 'chai' - -export const afterLoginHooks = () => { - suite('afterLogin', function () { - test('TODO', async function () {}) - }) -} diff --git a/test/tests/plugins/hooks/afterSign.ts b/test/tests/plugins/hooks/afterSign.ts deleted file mode 100644 index d1b9b314..00000000 --- a/test/tests/plugins/hooks/afterSign.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {assert} from 'chai' - -import {makeClient} from '$test/utils/mock-client' -import {makeContext} from '$test/utils/mock-context' - -const client = makeClient() -const context = makeContext() - -export const afterSignHooks = () => { - suite('afterSign', function () { - test('TODO', async function () {}) - }) -} diff --git a/test/tests/plugins/hooks/beforeLogin.ts b/test/tests/plugins/hooks/beforeLogin.ts deleted file mode 100644 index 720c8ee8..00000000 --- a/test/tests/plugins/hooks/beforeLogin.ts +++ /dev/null @@ -1,7 +0,0 @@ -import {assert} from 'chai' - -export const beforeLoginHooks = () => { - suite('beforeLogin', function () { - test('TODO', async function () {}) - }) -} diff --git a/test/tests/plugins/hooks/beforeSign.ts b/test/tests/plugins/hooks/beforeSign.ts index 59f98d71..5f1f1188 100644 --- a/test/tests/plugins/hooks/beforeSign.ts +++ b/test/tests/plugins/hooks/beforeSign.ts @@ -4,11 +4,11 @@ import zlib from 'pako' import {SigningRequest} from '$lib' import {Name, Transaction} from '@greymass/eosio' -import {makeClient} from '$test/utils/mock-client' -import {makeContext} from '$test/utils/mock-context' -import {mockTransactResourceProviderPresignHook} from '$test/utils/mock-hook' -import {makeMockAction, makeMockTransaction} from '$test/utils/mock-transfer' -import {mockAccountName} from '$test/utils/mock-config' +import {makeClient} from '@wharfkit/mock-data' +import {makeContext} from '@wharfkit/mock-data' +import {mockTransactResourceProviderPresignHook} from '@wharfkit/mock-data' +import {makeMockAction, makeMockTransaction} from '@wharfkit/mock-data' +import {mockAccountName} from '@wharfkit/mock-data' const client = makeClient() const context = makeContext() diff --git a/test/tests/plugins/transact/resource-provider.ts b/test/tests/plugins/transact/resource-provider.ts index 55ea1bbb..c62473d7 100644 --- a/test/tests/plugins/transact/resource-provider.ts +++ b/test/tests/plugins/transact/resource-provider.ts @@ -13,9 +13,9 @@ import { TransactHookTypes, } from '$lib' -import {mockChainId, mockUrl} from '$test/utils/mock-config' -import {mockFetch} from '$test/utils/mock-fetch' -import {makeWallet} from '$test/utils/mock-wallet' +import {mockChainId, mockUrl} from '@wharfkit/mock-data' +import {mockFetch} from '@wharfkit/mock-data' +import {makeWallet} from '@wharfkit/mock-data' const wallet = makeWallet() diff --git a/test/tests/session.ts b/test/tests/session.ts index 66f813ae..b50637b7 100644 --- a/test/tests/session.ts +++ b/test/tests/session.ts @@ -1,19 +1,45 @@ import {assert} from 'chai' -import SessionKit, {BaseTransactPlugin, ChainDefinition, Session, SessionOptions} from '$lib' -import {ABIDef, Name, PermissionLevel, Signature, TimePointSec} from '@greymass/eosio' +import SessionKit, { + AbstractTransactPlugin, + BaseTransactPlugin, + ChainDefinition, + PlaceholderName, + PlaceholderPermission, + Session, + SessionOptions, + SigningRequest, + TransactContext, + TransactHookTypes, +} from '$lib' +import { + ABI, + ABIDef, + Name, + PermissionLevel, + Serializer, + Signature, + TimePointSec, +} from '@greymass/eosio' -import {mockFetch} from '$test/utils/mock-fetch' -import {MockTransactPlugin, MockTransactResourceProviderPlugin} from '$test/utils/mock-hook' +import { + makeContext, + makeMockActions, + makeMockTransaction, + mockFetch, + mockSession, +} from '@wharfkit/mock-data' +import {MockTransactPlugin, MockTransactResourceProviderPlugin} from '@wharfkit/mock-data' import {nodejsUsage} from './use-cases/general/nodejs' -import {makeMockAction} from '$test/utils/mock-transfer' -import {makeWallet} from '$test/utils/mock-wallet' -import {mockPermissionLevel} from '$test/utils/mock-config' -import {MockUserInterface} from '$test/utils/mock-userinterface' -import {makeClient} from '$test/utils/mock-client' -import {mockSessionArgs} from '$test/utils/mock-session' -import {MockStorage} from '$test/utils/mock-storage' +import {makeMockAction} from '@wharfkit/mock-data' +import {makeWallet} from '@wharfkit/mock-data' +import {mockPermissionLevel} from '@wharfkit/mock-data' +import {MockUserInterface} from '@wharfkit/mock-data' +import {makeClient} from '@wharfkit/mock-data' +import {mockSessionArgs} from '@wharfkit/mock-data' +import {MockStorage} from '@wharfkit/mock-data' import {WalletPluginPrivateKey} from '@wharfkit/wallet-plugin-privatekey' +import {Transfer} from '$test/utils/setup/structs' const wallet = makeWallet() const action = makeMockAction() @@ -39,19 +65,79 @@ suite('session', function () { assert.instanceOf(session, Session) }) suite('options', function () { - suite('abiProvider', function () { + suite('abiCache', function () { test('specify provider', function () { const client = makeClient() - const abiProvider = { + const abiCache = { foo: 'bar', + cache: new Map(), + pending: new Map(), getAbi: async (account) => - (await client.v1.chain.get_abi(account)).abi as ABIDef, + ABI.from((await client.v1.chain.get_abi(account)).abi as ABIDef), + setAbi: () => { + // NYI + }, + } + const testSession = new Session(mockSessionArgs, { + ...mockSessionOptions, + abiCache, + }) + assert.equal(testSession.abiCache['foo'], 'bar') + }) + }) + suite('abis', function () { + test('passing for entire session', async function () { + const abi = { + version: 'eosio::abi/1.2', + types: [], + structs: [ + { + name: 'transfer', + base: '', + fields: [ + { + name: 'from', + type: 'name', + }, + { + name: 'to', + type: 'name', + }, + { + name: 'quantity', + type: 'asset', + }, + { + name: 'memo', + type: 'string', + }, + ], + }, + ], + actions: [ + { + name: 'transfer', + type: 'transfer', + ricardian_contract: '', + }, + ], + tables: [], + ricardian_clauses: [], + error_messages: [], + abi_extensions: [], + variants: [], + action_results: [], } const testSession = new Session(mockSessionArgs, { ...mockSessionOptions, - abiProvider, + abis: [ + { + account: 'eosio.token', + abi, + }, + ], }) - assert.equal(testSession.abiProvider['foo'], 'bar') + assert.lengthOf(testSession.abis, 1) }) }) suite('allowModify', function () { @@ -254,19 +340,23 @@ suite('session', function () { }) suite('transactPlugins', function () { test('default', async function () { - const sessionKit = new SessionKit({ - appName: 'demo.app', - chains: [ - { - id: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d', - url: 'https://jungle4.greymass.com', - }, - ], - fetch: mockFetch, // Required for unit tests - storage: new MockStorage(), - ui: new MockUserInterface(), - walletPlugins: [makeWallet()], - }) + const sessionKit = new SessionKit( + { + appName: 'demo.app', + chains: [ + { + id: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d', + url: 'https://jungle4.greymass.com', + }, + ], + ui: new MockUserInterface(), + walletPlugins: [makeWallet()], + }, + { + fetch: mockFetch, // Required for unit tests + storage: new MockStorage(), + } + ) const {session} = await sessionKit.login({ permissionLevel: mockPermissionLevel, }) @@ -275,39 +365,47 @@ suite('session', function () { assert.instanceOf(session.transactPlugins[0], BaseTransactPlugin) }) test('inherit', async function () { - const sessionKit = new SessionKit({ - appName: 'demo.app', - chains: [ - { - id: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d', - url: 'https://jungle4.greymass.com', - }, - ], - fetch: mockFetch, // Required for unit tests - storage: new MockStorage(), - transactPlugins: [new MockTransactPlugin()], - ui: new MockUserInterface(), - walletPlugins: [makeWallet()], - }) + const sessionKit = new SessionKit( + { + appName: 'demo.app', + chains: [ + { + id: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d', + url: 'https://jungle4.greymass.com', + }, + ], + ui: new MockUserInterface(), + walletPlugins: [makeWallet()], + }, + { + fetch: mockFetch, // Required for unit tests + storage: new MockStorage(), + transactPlugins: [new MockTransactPlugin()], + } + ) const {session} = await sessionKit.login({permissionLevel: mockPermissionLevel}) assert.instanceOf(session, Session) assert.lengthOf(session.transactPlugins, 1) assert.instanceOf(session.transactPlugins[0], MockTransactPlugin) }) test('override', async function () { - const sessionKit = new SessionKit({ - appName: 'demo.app', - chains: [ - { - id: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d', - url: 'https://jungle4.greymass.com', - }, - ], - fetch: mockFetch, // Required for unit tests - storage: new MockStorage(), - ui: new MockUserInterface(), - walletPlugins: [makeWallet()], - }) + const sessionKit = new SessionKit( + { + appName: 'demo.app', + chains: [ + { + id: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d', + url: 'https://jungle4.greymass.com', + }, + ], + ui: new MockUserInterface(), + walletPlugins: [makeWallet()], + }, + { + fetch: mockFetch, // Required for unit tests + storage: new MockStorage(), + } + ) const {session} = await sessionKit.login({ permissionLevel: mockPermissionLevel, transactPlugins: [new MockTransactPlugin()], @@ -334,6 +432,108 @@ suite('session', function () { assert.instanceOf(testSession.ui, MockUserInterface) }) }) + suite('placeholder resolution before the beforeSign hook', function () { + // A plugin to ensure placeholders are resolved before being passed into plugins + async function check(request: SigningRequest) { + const firstAction = request.getRawActions()[0] + const firstAuthorizer = firstAction.authorization[0] + const data = Serializer.decode({ + data: firstAction.data, + type: Transfer, + }) + assert.isFalse( + data.from.equals(PlaceholderName), + `Placeholder not resolved for data.from (${String(data.from)})` + ) + assert.isFalse( + firstAuthorizer.actor.equals(PlaceholderName), + `Placeholder not resolved for actor (${String(firstAuthorizer.actor)})` + ) + assert.isFalse( + firstAuthorizer.permission.equals(PlaceholderPermission), + `Placeholder not resolved for permission (${String(firstAuthorizer.permission)})` + ) + } + const placeholderCheckPlugin: AbstractTransactPlugin = { + id: 'placeholder_checker', + register: (context: TransactContext) => + context.addHook(TransactHookTypes.beforeSign, check), + } + // Mock data for these tests, overriding the `from` field to be a placeholder + const actionData = Serializer.decode({ + data: makeMockAction().data, + type: Transfer, + }) + actionData.from = PlaceholderName + // Testing against various action types to ensure placeholders resolve + test('action', async function () { + const action = makeMockAction() + action.data = Serializer.encode({object: actionData}) + action.authorization = [ + PermissionLevel.from({actor: PlaceholderName, permission: PlaceholderPermission}), + ] + await mockSession.transact({action}, {transactPlugins: [placeholderCheckPlugin]}) + }) + test('actions', async function () { + const actions = makeMockActions() + actions[0].data = Serializer.encode({object: actionData}) + actions[0].authorization = [ + PermissionLevel.from({actor: PlaceholderName, permission: PlaceholderPermission}), + ] + await mockSession.transact({actions}, {transactPlugins: [placeholderCheckPlugin]}) + }) + test('transaction', async function () { + const info = await makeClient().v1.chain.get_info() + const transaction = makeMockTransaction(info) + transaction.actions[0].data = Serializer.encode({object: actionData}) + transaction.actions[0].authorization = [ + PermissionLevel.from({actor: PlaceholderName, permission: PlaceholderPermission}), + ] + await mockSession.transact({transaction}, {transactPlugins: [placeholderCheckPlugin]}) + }) + test('request (string)', async function () { + await mockSession.transact( + { + request: + 'esr:gmNgZGBY1mTC_MoglIGBIVzX5uxZRqAQGDBBaSOYQMPGiXGxar2ntKB8Flf_YBAt6BocpBCQWJmTn5hSrOAWEq7IzMAAAA', + }, + {transactPlugins: [placeholderCheckPlugin]} + ) + }) + + test('request (ESR)', async function () { + const transaction = { + expiration: '2023-07-25T18:22:28', + ref_block_num: 47003, + ref_block_prefix: 845168116, + max_net_usage_words: 0, + max_cpu_usage_ms: 0, + delay_sec: 0, + context_free_actions: [], + actions: [ + { + account: 'eosio.token', + name: 'transfer', + authorization: [{actor: '............1', permission: '............2'}], + data: { + from: '............1', + to: 'teamgreymass', + quantity: '0.0042 EOS', + memo: 'ESR Payloads FTW!', + }, + }, + ], + transaction_extensions: [], + } + const request = await SigningRequest.create({transaction}, makeContext().esrOptions) + await mockSession.transact( + { + request, + }, + {transactPlugins: [placeholderCheckPlugin]} + ) + }) + }) suite('serialize', function () { test('returns valid json string', function () { const original = new Session(mockSessionArgs, mockSessionOptions) @@ -345,7 +545,7 @@ suite('session', function () { actor: 'wharfkit1111', permission: 'test', walletPlugin: { - id: 'keysigner', + id: 'wallet-plugin-privatekey', data: { privateKey: 'PVT_K1_25XP1Lt1Rt87hyymouSieBbgnUEAerS1yQHi9wqHC2Uek2mgzH', }, diff --git a/test/tests/transact.ts b/test/tests/transact.ts index 49e872b6..cd810eae 100644 --- a/test/tests/transact.ts +++ b/test/tests/transact.ts @@ -1,7 +1,7 @@ import {assert} from 'chai' import zlib from 'pako' -import {PermissionLevel, Serializer, Signature, TimePointSec} from '@greymass/eosio' +import {PermissionLevel, Serializer, Signature, TimePointSec, Transaction} from '@greymass/eosio' import {ResolvedSigningRequest, SigningRequest} from 'eosio-signing-request' import SessionKit, { @@ -12,21 +12,23 @@ import SessionKit, { TransactHookTypes, } from '$lib' -import {makeClient} from '$test/utils/mock-client' -import {mockFetch} from '$test/utils/mock-fetch' +import {makeClient} from '@wharfkit/mock-data' +import {mockFetch} from '@wharfkit/mock-data' import { mockMetadataFooWriterPlugin, mockTransactActionPrependerPlugin, MockTransactPlugin, MockTransactResourceProviderPlugin, -} from '$test/utils/mock-hook' -import {makeMockAction, makeMockActions, makeMockTransaction} from '$test/utils/mock-transfer' -import {makeWallet} from '$test/utils/mock-wallet' -import {mockPermissionLevel} from '$test/utils/mock-config' +} from '@wharfkit/mock-data' +import {makeMockAction, makeMockActions, makeMockTransaction} from '@wharfkit/mock-data' +import {makeWallet} from '@wharfkit/mock-data' +import {mockPermissionLevel} from '@wharfkit/mock-data' import {Transfer} from '$test/utils/setup/structs' -import {mockSessionArgs, mockSessionOptions} from '$test/utils/mock-session' -import {MockStorage} from '$test/utils/mock-storage' -import {MockUserInterface} from '$test/utils/mock-userinterface' +import {mockSessionArgs, mockSessionOptions} from '@wharfkit/mock-data' +import {MockStorage} from '@wharfkit/mock-data' +import {MockUserInterface} from '@wharfkit/mock-data' +import {ContractKit} from '@wharfkit/contract' +import {TransactPluginResourceProvider} from '@wharfkit/transact-plugin-resource-provider' const client = makeClient() const wallet = makeWallet() @@ -68,6 +70,77 @@ suite('transact', function () { const result = await session.transact({action: Serializer.objectify(action)}) assetValidTransactResponse(result) }) + test('from contract kit', async function () { + const session = new Session( + { + ...mockSessionArgs, + permissionLevel: { + actor: 'wharfkit1125', + permission: 'test', + }, + }, + mockSessionOptions + ) + const kit = new ContractKit( + { + client, + }, + { + abiCache: session.abiCache, + } + ) + const contract = await kit.load('eosio') + const action = contract.action('claimrewards', {owner: 'teamgreymass'}) + const result = await session.transact( + {action}, + {transactPlugins: [new TransactPluginResourceProvider()]} + ) + assert.isTrue( + result.transaction?.actions[0].authorization[0].actor.equals('wharfkit1125') + ) + assert.isTrue( + result.transaction?.actions[0].authorization[0].permission.equals('test') + ) + }) + test('from contract kit (to append to transaction)', async function () { + const session = new Session( + { + ...mockSessionArgs, + permissionLevel: { + actor: 'wharfkit1125', + permission: 'test', + }, + }, + mockSessionOptions + ) + const kit = new ContractKit( + { + client, + }, + { + abiCache: session.abiCache, + } + ) + const contract = await kit.load('eosio') + const action = contract.action('claimrewards', {owner: 'teamgreymass'}) + const info = await client.v1.chain.get_info() + const header = info.getTransactionHeader() + + const transaction = Transaction.from({ + ...header, + actions: [action], + }) + const result = await session.transact( + {transaction}, + {transactPlugins: [new TransactPluginResourceProvider()]} + ) + assert.isTrue( + result.transaction?.actions[0].authorization[0].actor.equals('wharfkit1125') + ) + assert.isTrue( + result.transaction?.actions[0].authorization[0].permission.equals('test') + ) + }) }) suite('actions', function () { test('typed', async function () { @@ -158,11 +231,11 @@ suite('transact', function () { }) test('object maintains payload metadata', async function () { const {action, session} = await mockData() - const abiProvider = new ABICache(this.client) + const abiCache = new ABICache(this.client) const request = await SigningRequest.create( {action}, { - abiProvider, + abiProvider: abiCache, zlib, } ) @@ -190,6 +263,67 @@ suite('transact', function () { }) }) suite('options', async function () { + suite('abis', function () { + test('passing as option', async function () { + const {action, session} = await mockData() + const abi = { + version: 'eosio::abi/1.2', + types: [], + structs: [ + { + name: 'transfer', + base: '', + fields: [ + { + name: 'from', + type: 'name', + }, + { + name: 'to', + type: 'name', + }, + { + name: 'quantity', + type: 'asset', + }, + { + name: 'memo', + type: 'string', + }, + ], + }, + ], + actions: [ + { + name: 'transfer', + type: 'transfer', + ricardian_contract: '', + }, + ], + tables: [], + ricardian_clauses: [], + error_messages: [], + abi_extensions: [], + variants: [], + action_results: [], + } + if (!abi) { + assert.fail('No abi returned from get_abi') + } + const result = await session.transact( + {action}, + { + abis: [ + { + account: 'eosio.token', + abi, + }, + ], + } + ) + assetValidTransactResponse(result) + }) + }) suite('allowModify', function () { test('default: true', async function () { const {action, session} = await mockData() @@ -400,23 +534,27 @@ suite('transact', function () { }) test('kit constructor', async function () { const {action} = await mockData() - const sessionKit = new SessionKit({ - appName: 'demo.app', - chains: [ - { - id: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d', - url: 'https://jungle4.greymass.com', - }, - ], - fetch: mockFetch, // Required for unit tests - storage: new MockStorage(), - transactPlugins: [new MockTransactResourceProviderPlugin()], - transactPluginsOptions: { - disableExamplePlugin: true, + const sessionKit = new SessionKit( + { + appName: 'demo.app', + chains: [ + { + id: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d', + url: 'https://jungle4.greymass.com', + }, + ], + ui: new MockUserInterface(), + walletPlugins: [makeWallet()], }, - ui: new MockUserInterface(), - walletPlugins: [makeWallet()], - }) + { + fetch: mockFetch, // Required for unit tests + storage: new MockStorage(), + transactPlugins: [new MockTransactResourceProviderPlugin()], + transactPluginsOptions: { + disableExamplePlugin: true, + }, + } + ) const {session} = await sessionKit.login({ permissionLevel: mockPermissionLevel, }) @@ -430,20 +568,24 @@ suite('transact', function () { }) test('login', async function () { const {action} = await mockData() - const sessionKit = new SessionKit({ - appName: 'demo.app', - chains: [ - { - id: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d', - url: 'https://jungle4.greymass.com', - }, - ], - fetch: mockFetch, // Required for unit tests - storage: new MockStorage(), - transactPlugins: [new MockTransactResourceProviderPlugin()], - ui: new MockUserInterface(), - walletPlugins: [makeWallet()], - }) + const sessionKit = new SessionKit( + { + appName: 'demo.app', + chains: [ + { + id: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d', + url: 'https://jungle4.greymass.com', + }, + ], + ui: new MockUserInterface(), + walletPlugins: [makeWallet()], + }, + { + fetch: mockFetch, // Required for unit tests + storage: new MockStorage(), + transactPlugins: [new MockTransactResourceProviderPlugin()], + } + ) const {session} = await sessionKit.login({ permissionLevel: mockPermissionLevel, transactPluginsOptions: { diff --git a/test/tests/ui.ts b/test/tests/ui.ts index 0fbcbcd1..502af018 100644 --- a/test/tests/ui.ts +++ b/test/tests/ui.ts @@ -3,7 +3,7 @@ import {assert} from 'chai' import {LocaleDefinitions} from 'src/types' import {UserInterface, UserInterfaceTranslateOptions} from 'src/ui' -import {MockUserInterface} from '$test/utils/mock-userinterface' +import {MockUserInterface} from '@wharfkit/mock-data' const mockLocaleDefinitions: LocaleDefinitions = { en: { diff --git a/test/tests/use-cases/general/nodejs.ts b/test/tests/use-cases/general/nodejs.ts index 085067f4..9cb428ab 100644 --- a/test/tests/use-cases/general/nodejs.ts +++ b/test/tests/use-cases/general/nodejs.ts @@ -20,8 +20,8 @@ import { mockPermissionName, mockPrivateKey, mockUrl, -} from '$test/utils/mock-config' -import {mockFetch} from '$test/utils/mock-fetch' +} from '@wharfkit/mock-data' +import {mockFetch} from '@wharfkit/mock-data' /** * Required arguments for manually establishing a session. diff --git a/test/tests/utils.ts b/test/tests/utils.ts index 01b84433..b3ba975c 100644 --- a/test/tests/utils.ts +++ b/test/tests/utils.ts @@ -3,11 +3,11 @@ import {assert} from 'chai' import zlib from 'pako' import {ChainDefinition, Logo, SigningRequest, Transaction} from '$lib' -import {makeMockAction} from '$test/utils/mock-transfer' +import {makeMockAction} from '@wharfkit/mock-data' import {appendAction, prependAction} from 'src/utils' -import {mockData} from '$test/utils/mock-data' -import {mockChainId} from '$test/utils/mock-config' +import {mockData} from '@wharfkit/mock-data' +import {mockChainId} from '@wharfkit/mock-data' const newAction = makeMockAction('new action') diff --git a/test/tests/wallet.ts b/test/tests/wallet.ts index 4ad87948..280563a5 100644 --- a/test/tests/wallet.ts +++ b/test/tests/wallet.ts @@ -1,12 +1,18 @@ import {assert} from 'chai' -import SessionKit, {ChainDefinition, Logo, SessionKitOptions, WalletPluginMetadata} from '$lib' -import {MockUserInterface} from '$test/utils/mock-userinterface' -import {makeWallet, MockWalletPluginConfigs} from '$test/utils/mock-wallet' -import {mockFetch} from '$test/utils/mock-fetch' -import {makeMockAction} from '$test/utils/mock-transfer' -import {MockStorage} from '$test/utils/mock-storage' -import {mockChainDefinitions, mockPrivateKey} from '$test/utils/mock-config' +import SessionKit, { + ChainDefinition, + Logo, + SessionKitArgs, + SessionKitOptions, + WalletPluginMetadata, +} from '$lib' +import {MockUserInterface} from '@wharfkit/mock-data' +import {makeWallet, MockWalletPluginConfigs} from '@wharfkit/mock-data' +import {mockFetch} from '@wharfkit/mock-data' +import {makeMockAction} from '@wharfkit/mock-data' +import {MockStorage} from '@wharfkit/mock-data' +import {mockChainDefinitions, mockPrivateKey} from '@wharfkit/mock-data' const chains = [ ChainDefinition.from({ @@ -27,15 +33,18 @@ const chains = [ }), ] -const defaultSessionKitOptions: SessionKitOptions = { +const defaultSessionKitArgs: SessionKitArgs = { appName: 'demo.app', chains, - fetch: mockFetch, // Required for unit tests - storage: new MockStorage(), ui: new MockUserInterface(), walletPlugins: [makeWallet()], } +const defaultSessionKitOptions: SessionKitOptions = { + fetch: mockFetch, // Required for unit tests + storage: new MockStorage(), +} + suite('walletPlugin', function () { suite('config', function () { test('defaults', function () { @@ -67,10 +76,13 @@ suite('walletPlugin', function () { requiresPermissionSelect: false, }) assert.isTrue(walletPlugin.config.requiresChainSelect) - const kit = new SessionKit({ - ...defaultSessionKitOptions, - walletPlugins: [walletPlugin], - }) + const kit = new SessionKit( + { + ...defaultSessionKitArgs, + walletPlugins: [walletPlugin], + }, + defaultSessionKitOptions + ) const result = await kit.login({ permissionLevel: 'mock@interface', }) @@ -84,10 +96,13 @@ suite('walletPlugin', function () { requiresPermissionSelect: false, }) assert.isFalse(walletPlugin.config.requiresChainSelect) - const kit = new SessionKit({ - ...defaultSessionKitOptions, - walletPlugins: [walletPlugin], - }) + const kit = new SessionKit( + { + ...defaultSessionKitArgs, + walletPlugins: [walletPlugin], + }, + defaultSessionKitOptions + ) const result = await kit.login({ permissionLevel: 'mock@interface', }) @@ -103,10 +118,13 @@ suite('walletPlugin', function () { requiresPermissionSelect: true, }) assert.isTrue(walletPlugin.config.requiresPermissionSelect) - const kit = new SessionKit({ - ...defaultSessionKitOptions, - walletPlugins: [walletPlugin], - }) + const kit = new SessionKit( + { + ...defaultSessionKitArgs, + walletPlugins: [walletPlugin], + }, + defaultSessionKitOptions + ) const result = await kit.login({ chain: chains[0].id, }) @@ -120,10 +138,13 @@ suite('walletPlugin', function () { requiresPermissionSelect: false, }) assert.isFalse(walletPlugin.config.requiresPermissionSelect) - const kit = new SessionKit({ - ...defaultSessionKitOptions, - walletPlugins: [walletPlugin], - }) + const kit = new SessionKit( + { + ...defaultSessionKitArgs, + walletPlugins: [walletPlugin], + }, + defaultSessionKitOptions + ) const result = await kit.login({ chain: chains[0].id, }) @@ -141,10 +162,13 @@ suite('walletPlugin', function () { '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d', ], }) - const kit = new SessionKit({ - ...defaultSessionKitOptions, - walletPlugins: [walletPlugin], - }) + const kit = new SessionKit( + { + ...defaultSessionKitArgs, + walletPlugins: [walletPlugin], + }, + defaultSessionKitOptions + ) await kit.login({ permissionLevel: 'mock@interface', }) @@ -157,10 +181,13 @@ suite('walletPlugin', function () { 'f16b1833c747c43682f4386fca9cbb327929334a762755ebec17f6f23c9b8a12', // WAX (Testnet) ], }) - const kit = new SessionKit({ - ...defaultSessionKitOptions, - walletPlugins: [walletPlugin], - }) + const kit = new SessionKit( + { + ...defaultSessionKitArgs, + walletPlugins: [walletPlugin], + }, + defaultSessionKitOptions + ) let error try { await kit.login({ @@ -180,10 +207,13 @@ suite('walletPlugin', function () { '34593b65376aee3c9b06ea8a8595122b39333aaab4c76ad52587831fcc096590', // mockUserInterface Default ], }) - const kit = new SessionKit({ - ...defaultSessionKitOptions, - walletPlugins: [walletPlugin], - }) + const kit = new SessionKit( + { + ...defaultSessionKitArgs, + walletPlugins: [walletPlugin], + }, + defaultSessionKitOptions + ) await kit.login({ chain: '34593b65376aee3c9b06ea8a8595122b39333aaab4c76ad52587831fcc096590', permissionLevel: 'mock@interface', @@ -197,10 +227,13 @@ suite('walletPlugin', function () { 'f16b1833c747c43682f4386fca9cbb327929334a762755ebec17f6f23c9b8a12', // WAX (Testnet) ], }) - const kit = new SessionKit({ - ...defaultSessionKitOptions, - walletPlugins: [walletPlugin], - }) + const kit = new SessionKit( + { + ...defaultSessionKitArgs, + walletPlugins: [walletPlugin], + }, + defaultSessionKitOptions + ) let error try { await kit.login({ @@ -219,10 +252,13 @@ suite('walletPlugin', function () { testModify: true, privateKey: mockPrivateKey, }) - const kit = new SessionKit({ - ...defaultSessionKitOptions, - walletPlugins: [walletPlugin], - }) + const kit = new SessionKit( + { + ...defaultSessionKitArgs, + walletPlugins: [walletPlugin], + }, + defaultSessionKitOptions + ) const loginResult = await kit.login({ chain: chains[0].id, permissionLevel: 'mock@interface', @@ -233,11 +269,16 @@ suite('walletPlugin', function () { const walletPlugin = new MockWalletPluginConfigs(undefined, { testModify: true, }) - const kit = new SessionKit({ - ...defaultSessionKitOptions, - allowModify: false, - walletPlugins: [walletPlugin], - }) + const kit = new SessionKit( + { + ...defaultSessionKitArgs, + walletPlugins: [walletPlugin], + }, + { + ...defaultSessionKitOptions, + allowModify: false, + } + ) const loginResult = await kit.login({ chain: chains[0].id, permissionLevel: 'mock@interface', @@ -258,11 +299,16 @@ suite('walletPlugin', function () { testModify: true, privateKey: mockPrivateKey, }) - const kit = new SessionKit({ - ...defaultSessionKitOptions, - allowModify: true, - walletPlugins: [walletPlugin], - }) + const kit = new SessionKit( + { + ...defaultSessionKitArgs, + walletPlugins: [walletPlugin], + }, + { + ...defaultSessionKitOptions, + allowModify: true, + } + ) const loginResult = await kit.login({ chain: chains[0].id, permissionLevel: 'mock@interface', @@ -274,10 +320,13 @@ suite('walletPlugin', function () { suite('storage', function () { test('empty data', async function () { const walletPlugin = new MockWalletPluginConfigs() - const kit = new SessionKit({ - ...defaultSessionKitOptions, - walletPlugins: [walletPlugin], - }) + const kit = new SessionKit( + { + ...defaultSessionKitArgs, + walletPlugins: [walletPlugin], + }, + defaultSessionKitOptions + ) const response = await kit.login() assert.deepEqual(response.session.serialize(), { chain: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d', @@ -299,10 +348,13 @@ suite('walletPlugin', function () { foo: 'baz', } ) - const kit = new SessionKit({ - ...defaultSessionKitOptions, - walletPlugins: [walletPlugin], - }) + const kit = new SessionKit( + { + ...defaultSessionKitArgs, + walletPlugins: [walletPlugin], + }, + defaultSessionKitOptions + ) const response = await kit.login() assert.deepEqual(response.session.serialize(), { chain: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d', @@ -329,10 +381,13 @@ suite('walletPlugin', function () { }, } const walletPlugin = new MockWalletPluginConfigs() - const kit = new SessionKit({ - ...defaultSessionKitOptions, - walletPlugins: [walletPlugin], - }) + const kit = new SessionKit( + { + ...defaultSessionKitArgs, + walletPlugins: [walletPlugin], + }, + defaultSessionKitOptions + ) const session = await kit.restore(serializedSession) if (!session) { throw new Error('Failed to restore session') diff --git a/test/utils/browser-fetch.ts b/test/utils/browser-fetch.ts deleted file mode 100644 index 76fa9ecf..00000000 --- a/test/utils/browser-fetch.ts +++ /dev/null @@ -1,26 +0,0 @@ -import {Bytes, Checksum160} from '@greymass/eosio' - -const data = global.MOCK_DATA - -export function getFilename(path, params) { - const digest = Checksum160.hash( - Bytes.from(path + (params ? JSON.stringify(params) : ''), 'utf8') - ).hexString - return digest + '.json' -} - -async function getExisting(filename) { - return data[filename] -} - -export async function mockFetch(path, params) { - const filename = getFilename(path, params) - const existing = await getExisting(filename) - if (existing) { - return new Response(existing.text, { - status: existing.status, - headers: existing.headers, - }) - } - throw new Error(`No data for ${path}`) -} diff --git a/test/utils/mock-client.ts b/test/utils/mock-client.ts deleted file mode 100644 index fa10c144..00000000 --- a/test/utils/mock-client.ts +++ /dev/null @@ -1,10 +0,0 @@ -import {APIClient, FetchProvider} from '@greymass/eosio' - -import {mockUrl} from './mock-config' -import {mockFetch} from '$test/utils/mock-fetch' - -export function makeClient(url?: string) { - return new APIClient({ - provider: new FetchProvider(url || mockUrl, {fetch: mockFetch}), - }) -} diff --git a/test/utils/mock-config.ts b/test/utils/mock-config.ts deleted file mode 100644 index a732ae30..00000000 --- a/test/utils/mock-config.ts +++ /dev/null @@ -1,29 +0,0 @@ -export const mockChainId = '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d' -export const mockUrl = 'https://jungle4.greymass.com' -export const mockChainDefinition = { - id: mockChainId, - url: mockUrl, -} -export const mockChainDefinitions = [ - mockChainDefinition, - { - id: 'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906', - url: 'https://eos.greymass.com', - }, - { - id: '4667b205c6838ef70ff7988f6e8257e8be0e1284a2f59699054a018f743b1d11', - url: 'https://telos.greymass.com', - }, - { - id: '1064487b3cd1a897ce03ae5b6a865651747e2e152090f99c1d19d44e01aea5a4', - url: 'https://wax.greymass.com', - }, - { - id: '34593b65376aee3c9b06ea8a8595122b39333aaab4c76ad52587831fcc096590', - url: 'https://mockuserinterface.greymass.com', - }, -] -export const mockPrivateKey = '5Jtoxgny5tT7NiNFp1MLogviuPJ9NniWjnU4wKzaX4t7pL4kJ8s' -export const mockAccountName = 'wharfkit1111' -export const mockPermissionName = 'test' -export const mockPermissionLevel = `${mockAccountName}@${mockPermissionName}` diff --git a/test/utils/mock-context.ts b/test/utils/mock-context.ts deleted file mode 100644 index 26bca0b6..00000000 --- a/test/utils/mock-context.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { - ABICache, - ChainDefinition, - Session, - SigningRequest, - TransactArgs, - TransactContext, - TransactContextOptions, -} from '$lib' -import {APIClient, FetchProvider, PermissionLevel} from '@greymass/eosio' - -import {mockChainDefinition, mockUrl} from './mock-config' -import {mockFetch} from '$test/utils/mock-fetch' -import {mockSession, mockSessionArgs, mockSessionOptions} from './mock-session' - -const client = new APIClient({ - provider: new FetchProvider(mockUrl, {fetch: mockFetch}), -}) - -const session = new Session(mockSessionArgs, mockSessionOptions) -const abiProvider = new ABICache(client) - -export const mockTransactContextOptions: TransactContextOptions = { - abiProvider, - chain: ChainDefinition.from(mockChainDefinition), - client, - createRequest: async (args: TransactArgs): Promise => - session.createRequest(args, abiProvider), - fetch: mockFetch, - permissionLevel: PermissionLevel.from('wharfkit1125@test'), -} - -export function makeContext(): TransactContext { - return new TransactContext(mockTransactContextOptions) -} diff --git a/test/utils/mock-data.ts b/test/utils/mock-data.ts deleted file mode 100644 index ee7b5aea..00000000 --- a/test/utils/mock-data.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Session} from '$lib' - -import {makeClient} from '$test/utils/mock-client' -import {mockSessionArgs, mockSessionOptions} from './mock-session' -import {makeMockAction, makeMockActions, makeMockTransaction} from '$test/utils/mock-transfer' - -const client = makeClient() - -export async function mockData(memo?: string) { - const info = await client.v1.chain.get_info() - const action = await makeMockAction(memo) - const actions = await makeMockActions(memo) - const transaction = await makeMockTransaction(info, memo) - const session = new Session(mockSessionArgs, mockSessionOptions) - return { - action, - actions, - info, - session, - transaction, - } -} diff --git a/test/utils/mock-fetch.ts b/test/utils/mock-fetch.ts deleted file mode 100644 index bde22c83..00000000 --- a/test/utils/mock-fetch.ts +++ /dev/null @@ -1,66 +0,0 @@ -import fetch, {Response} from 'node-fetch' -import {join as joinPath} from 'path' -import {promisify} from 'util' -import {readFile as _readFile, writeFile as _writeFile} from 'fs' -import {Bytes, Checksum160} from '@greymass/eosio' - -const readFile = promisify(_readFile) -const writeFile = promisify(_writeFile) - -function getFilename(path: string, params?: unknown) { - const digest = Checksum160.hash( - Bytes.from(path + (params ? JSON.stringify(params) : ''), 'utf8') - ).hexString - return joinPath(__dirname, '../data', digest + '.json') -} - -async function getExisting(filename: string) { - try { - const data = await readFile(filename) - return JSON.parse(data.toString('utf8')) - } catch (error) { - if ((error).code !== 'ENOENT') { - throw error - } - } -} - -export async function mockFetch(path, params) { - if (process.env['LOGHTTP']) { - console.log('HTTP Request', {path, params}) - } - const filename = getFilename(path, params) - if (process.env['MOCK'] !== 'overwrite') { - const existing = await getExisting(filename) - if (existing) { - return new Response(existing.text, { - status: existing.status, - headers: existing.headers, - }) - } - } - if (process.env['MOCK']) { - const response = await fetch(path, params) - const json = await response.clone().json() - await writeFile( - filename, - JSON.stringify( - { - request: { - path, - params, - }, - headers: Object.fromEntries(response.headers.entries()), - status: response.status, - json, - text: JSON.stringify(json), - }, - undefined, - 4 - ) - ) - return response - } else { - throw new Error(`No data for ${path}`) - } -} diff --git a/test/utils/mock-hook.ts b/test/utils/mock-hook.ts deleted file mode 100644 index 96efd64a..00000000 --- a/test/utils/mock-hook.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { - AbstractTransactPlugin, - Action, - LoginHook, - SessionOptions, - SigningRequest, - Struct, - TransactContext, - TransactHookResponse, - TransactHookTypes, - Transaction, -} from '$lib' -import {prependAction} from 'src/utils' - -export async function mockLoginHook(context: SessionOptions) { - // Mock hook that does nothing -} - -export async function mockTransactHook(request: SigningRequest): Promise { - // Mock hook that does nothing - return { - request, - signatures: [], - } -} - -export class MockTransactPlugin extends AbstractTransactPlugin { - id = 'mock-transact-plugin' - register(context: TransactContext): void { - context.addHook(TransactHookTypes.beforeSign, mockTransactHook) - context.addHook(TransactHookTypes.afterSign, mockTransactHook) - context.addHook(TransactHookTypes.afterBroadcast, mockTransactHook) - } -} - -// Needed to load the ABI and work with an `Action` object -class noop extends Struct { - static abiName = 'noop' - static abiFields = [] -} - -export async function mockTransactResourceProviderPresignHook( - request: SigningRequest, - context: TransactContext -): Promise { - // Pull the plugin options from the context - const options = context.transactPluginsOptions - // If any options this plugin is interested in are set, react to them - // In this example, we're just bypassing the plugin w/ a flag. - if (options.disableExamplePlugin) { - return { - request, - signatures: [], - } - } - const newAction = Action.from({ - account: 'greymassnoop', - name: 'noop', - authorization: [ - { - actor: 'greymassfuel', - permission: 'cosign', - }, - ], - data: noop.from({}), - }) - const modified = prependAction(request, newAction) - // Return the request - return { - request: modified, - signatures: [], - } -} - -export class MockTransactResourceProviderPlugin extends AbstractTransactPlugin { - id = 'mock-transact-resource-provider-plugin' - register(context: TransactContext): void { - context.addHook(TransactHookTypes.beforeSign, mockTransactResourceProviderPresignHook) - } -} - -export const mockTransactActionPrependerPlugin = { - id: 'mock-transact-action-prepender-plugin', - register: (context) => - context.addHook(TransactHookTypes.beforeSign, async (request, context) => ({ - request: await SigningRequest.create( - { - actions: [ - { - account: 'greymassnoop', - name: 'noop', - authorization: [ - { - actor: [...Array(12)] - .map(() => Math.random().toString(36)[2]) - .join(''), - permission: 'test', - }, - ], - data: {}, - }, - ...request.getRawActions(), - ], - }, - context.esrOptions - ), - })), -} - -export const mockMetadataFooWriterPlugin = { - id: 'mock-metadata-foo-writer-plugin', - register: (context) => - context.addHook(TransactHookTypes.beforeSign, async (request) => { - request.setInfoKey('foo', 'baz') - return { - request, - } - }), -} diff --git a/test/utils/mock-session.ts b/test/utils/mock-session.ts deleted file mode 100644 index b7afb02c..00000000 --- a/test/utils/mock-session.ts +++ /dev/null @@ -1,39 +0,0 @@ -import {PermissionLevel} from '@greymass/eosio' - -import {Session, SessionArgs, SessionKit, SessionKitOptions, SessionOptions} from '$lib' - -import { - mockChainDefinition, - mockChainDefinitions, - mockPermissionLevel, -} from '$test/utils/mock-config' -import {mockFetch} from '$test/utils/mock-fetch' -import {makeWallet} from '$test/utils/mock-wallet' -import {MockStorage} from './mock-storage' -import {MockUserInterface} from './mock-userinterface' - -const wallet = makeWallet() - -export const mockSessionKitOptions: SessionKitOptions = { - appName: 'unittest', - chains: mockChainDefinitions, - fetch: mockFetch, // Required for unit tests - storage: new MockStorage(), - ui: new MockUserInterface(), - walletPlugins: [wallet], -} - -export const mockSessionKit = new SessionKit(mockSessionKitOptions) - -export const mockSessionArgs: SessionArgs = { - chain: mockChainDefinition, - permissionLevel: PermissionLevel.from(mockPermissionLevel), - walletPlugin: wallet, -} - -export const mockSessionOptions: SessionOptions = { - broadcast: false, // Disable broadcasting by default for tests, enable when required. - fetch: mockFetch, // Required for unit tests -} - -export const mockSession = new Session(mockSessionArgs, mockSessionOptions) diff --git a/test/utils/mock-storage.ts b/test/utils/mock-storage.ts deleted file mode 100644 index 7f6c7a36..00000000 --- a/test/utils/mock-storage.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {SessionStorage} from 'src/storage' - -export class MockStorage implements SessionStorage { - data: Record = {} - async write(key: string, data: string): Promise { - this.data[key] = data - } - async read(key: string): Promise { - return this.data[key] - } - async remove(key: string): Promise { - delete this.data[key] - } - storageKey(key: string) { - return `mock-${key}` - } -} diff --git a/test/utils/mock-transfer.ts b/test/utils/mock-transfer.ts deleted file mode 100644 index 9bf6cd18..00000000 --- a/test/utils/mock-transfer.ts +++ /dev/null @@ -1,51 +0,0 @@ -import {Action, API, Asset, Name, Struct, Transaction} from '@greymass/eosio' - -import {mockAccountName, mockPermissionName} from './mock-config' - -@Struct.type('transfer') -class Transfer extends Struct { - @Struct.field('name') from!: Name - @Struct.field('name') to!: Name - @Struct.field('asset') quantity!: Asset - @Struct.field('string') memo!: string -} - -export function makeMockAction(memo?: string): Action { - // Generate typed data for action data - const transfer = Transfer.from({ - from: mockAccountName, - to: 'teamgreymass', - quantity: '0.1337 EOS', - memo: memo || 'wharfkit is the best <3', - }) - // Assemble action with action data and metadata - const action = Action.from({ - authorization: [ - { - actor: mockAccountName, - permission: mockPermissionName, - }, - ], - account: 'eosio.token', - name: 'transfer', - data: transfer, - }) - return action -} - -export function makeMockActions(memo?: string): Action[] { - return [makeMockAction(memo)] -} - -export function makeMockTransaction(info: API.v1.GetInfoResponse, memo?: string): Transaction { - // Assemble transaction header - const header = info.getTransactionHeader(90) - // Generate array of actions - const actions = makeMockActions(memo) - // Form and return transaction object - const transaction = Transaction.from({ - ...header, - actions, - }) - return transaction -} diff --git a/test/utils/mock-userinterface.ts b/test/utils/mock-userinterface.ts deleted file mode 100644 index 35b17f58..00000000 --- a/test/utils/mock-userinterface.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { - AbstractUserInterface, - cancelable, - Cancelable, - Checksum256, - LocaleDefinitions, - LoginContext, - LoginOptions, - PermissionLevel, - PromptArgs, - PromptResponse, - UserInterface, - UserInterfaceLoginResponse, -} from '$lib' - -export class MockUserInterface extends AbstractUserInterface implements UserInterface { - readonly logging = false - public messages: string[] = [] - public localeDefinitions: LocaleDefinitions = {} - - log(message: string) { - this.messages.push(message) - if (this.logging) { - // eslint-disable-next-line no-console - console.info('MockUserInterface', message) - } - } - - async login(context: LoginContext): Promise { - let chainId = context.chain?.id - if (!chainId) { - chainId = Checksum256.from(context.chains[0].id) - } - let permissionLevel = context.permissionLevel - if (!permissionLevel) { - permissionLevel = PermissionLevel.from('mock@interface') - } - return { - chainId, - permissionLevel, - walletPluginIndex: 0, - } - } - - async onError(error: Error) { - this.log('onError: ' + JSON.stringify(error)) - } - - async onLogin(options?: LoginOptions) { - this.log('onLogin: ' + JSON.stringify(options)) - } - - async onLoginComplete() { - this.log('onLoginComplete') - } - - async onTransact() { - this.log('onTransact') - } - - async onTransactComplete() { - this.log('onTransactComplete') - } - - async onSign() { - this.log('onSign') - } - - async onSignComplete() { - this.log('onSignComplete') - } - - async onBroadcast() { - this.log('onBroadcast') - } - - async onBroadcastComplete() { - this.log('onBroadcastComplete') - } - - prompt(args: PromptArgs): Cancelable { - this.log('prompt' + JSON.stringify(args)) - return cancelable(new Promise(() => {}), (canceled) => { - // do things to cancel promise - throw canceled - }) - } - - status(message: string) { - this.log(`status:('${message}')`) - } - - addTranslations(definitions: LocaleDefinitions): void { - this.log('addTranslations: ' + JSON.stringify(definitions)) - } -} diff --git a/test/utils/mock-wallet.ts b/test/utils/mock-wallet.ts deleted file mode 100644 index 45f9dc50..00000000 --- a/test/utils/mock-wallet.ts +++ /dev/null @@ -1,85 +0,0 @@ -import {Checksum256, PermissionLevel, PrivateKey, Transaction} from '@greymass/eosio' -import {WalletPluginPrivateKey} from '@wharfkit/wallet-plugin-privatekey' - -import { - AbstractWalletPlugin, - ChainDefinition, - LoginContext, - ResolvedSigningRequest, - SigningRequest, - TransactContext, - WalletPluginConfig, - WalletPluginData, - WalletPluginMetadata, - WalletPluginSignResponse, -} from '$lib' -import {mockChainDefinition, mockPermissionLevel, mockPrivateKey} from './mock-config' -import {makeMockAction} from './mock-transfer' - -export function makeWallet() { - return new WalletPluginPrivateKey(PrivateKey.from(mockPrivateKey)) -} - -export class MockWalletPluginConfigs extends AbstractWalletPlugin { - readonly metadata = WalletPluginMetadata.from({ - name: 'Mock Wallet Plugin', - description: 'A mock wallet plugin for testing chain selection', - logo: 'https://assets.wharfkit.com/chain/jungle.png', - }) - testModify = false - config: WalletPluginConfig - constructor(config?: WalletPluginConfig, initialData: WalletPluginData = {}) { - super() - if (config) { - this.config = config - } else { - this.config = { - requiresChainSelect: true, - requiresPermissionSelect: false, - } - } - this.data = initialData - } - get id() { - return 'MockWalletPluginConfigs' - } - async login(context: LoginContext) { - // Return the chain and permission level for this fake wallet - return { - chain: context.chain ? context.chain.id : ChainDefinition.from(mockChainDefinition).id, - permissionLevel: context.permissionLevel || PermissionLevel.from(mockPermissionLevel), - } - } - async sign( - resolved: ResolvedSigningRequest, - context: TransactContext - ): Promise { - if (context.storage) { - context.storage.write('testModify', this.data.testModify) - } - // If the `testModify` flag is enabled, modify the transaction for testing purposes - if (this.data.testModify) { - const request = await SigningRequest.create( - {action: makeMockAction('modified transaction')}, - context.esrOptions - ) - const resolved = await context.resolve(request) - const transaction = Transaction.from(resolved.transaction) - const digest = transaction.signingDigest(Checksum256.from(context.chain.id)) - const privateKey = PrivateKey.from(this.data.privateKey) - const signature = privateKey.signDigest(digest) - return { - resolved: resolved, - signatures: [signature], - } - } - // Otherwise sign what was returned - const transaction = Transaction.from(resolved.transaction) - const digest = transaction.signingDigest(Checksum256.from(context.chain.id)) - const privateKey = PrivateKey.from(this.data.privateKey) - const signature = privateKey.signDigest(digest) - return { - signatures: [signature], - } - } -} diff --git a/test/utils/setup/accounts.ts b/test/utils/setup/accounts.ts index 8c3c5724..c5da4e70 100644 --- a/test/utils/setup/accounts.ts +++ b/test/utils/setup/accounts.ts @@ -5,7 +5,7 @@ import {Action, AssetType, Name, NameType, PermissionLevel, Session, TransactRes import {Buyrambytes, Delegatebw, Linkauth, Newaccount, Transfer, Updateauth} from './structs' // Mock of Fetch for debugging/testing -// import {mockFetch} from '$test/utils/mock-fetch' +// import {mockFetch} from '@wharfkit/mock-data' /** * THIS INFORMATION NEEDS TO BE POPULATED @@ -25,7 +25,7 @@ const controlKey = 'EOS6XXTaRpWhPwnb7CTV9zVsCBrvCpYMMPSk8E8hsJxhf6VFW9DYN' const testKey = 'EOS6RMS3nvoN9StPzZizve6WdovaDkE5KkEcCDXW7LbepyAioMiK6' // Cosigner Key for wharfkitnoop -const noopKey = 'EOS8WUgppBZ1NjnGASYeLwQ3PkNLvdnfnchumsSpo6ApCAzbETczm' +// const noopKey = 'EOS8WUgppBZ1NjnGASYeLwQ3PkNLvdnfnchumsSpo6ApCAzbETczm' // Minimum RAM bytes to create an account const requiredRamBytes = 1599 @@ -406,10 +406,12 @@ async function run() { // Check if account exists try { await masterSession.client.v1.chain.get_account(Name.from(account.name)) + // eslint-disable-next-line no-console console.log(`account ${account.name} already exists`) } catch (e) { // Create account const result = await createAccount(masterSession, account) + // eslint-disable-next-line no-console console.log(`created ${account.name} ${result.resolved?.transaction.id}`) } } @@ -423,9 +425,11 @@ async function run() { return String(permission.perm_name) === 'test' }) if (hasTestPermission) { + // eslint-disable-next-line no-console console.log(`account ${account.name} already has test permission...`) } else { const result = await createTestPermission(account) + // eslint-disable-next-line no-console console.log( `created test permission on ${account.name} ${result.resolved?.transaction.id}}` ) diff --git a/yarn.lock b/yarn.lock index 503c5872..a1234ed6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1272,10 +1272,58 @@ "@typescript-eslint/types" "5.45.0" eslint-visitor-keys "^3.3.0" -"@wharfkit/wallet-plugin-privatekey@^0.3.0-ui-13": - version "0.3.0-ui-13" - resolved "https://registry.yarnpkg.com/@wharfkit/wallet-plugin-privatekey/-/wallet-plugin-privatekey-0.3.0-ui-13.tgz#ac8875bc78f275254b3dca827e2b356670971e62" - integrity sha512-jYFBdpQsKrG4Mh5540XyCR72TifHuljivdOIv+gdi+jKnmEQzsiEd4ac8mlIdOgqkL+JFoHQWnHeVO87Agg39w== +"@wharfkit/abicache@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@wharfkit/abicache/-/abicache-1.0.0.tgz#d9f7dc38dce0e9cffd7de351b366c1aa1b719c46" + integrity sha512-crfXFPlmxkqDdgvVIFjcHGx3kkLdXj2JbUsu3XYnxJf91tWWbHAfNn2ba3UifsFDTE9BdUFd2Cz+FLTi464Gew== + dependencies: + "@greymass/eosio" "^0.6.10" + eosio-signing-request "^2.5.3" + pako "^2.0.4" + tslib "^2.1.0" + +"@wharfkit/contract@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@wharfkit/contract/-/contract-0.2.1.tgz#df8353a71b18bbbfdc01945f4bc955dad8c42c00" + integrity sha512-fwxqBYTfN3QFJEqCvijLbVE6eY4K+6Y04E0lI8U/IINKtazyMeou+dPuEqwTWMqwaRtKo5Re5gtARi6LgrRR2A== + dependencies: + "@greymass/eosio" "^0.6.10" + "@wharfkit/abicache" "^1.0.0" + eosio-signing-request "^2.5.3" + tslib "^2.1.0" + +"@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-beta3" + "@wharfkit/wallet-plugin-privatekey" "^0.5.0" + node-fetch "^2.6.1" + tslib "^2.1.0" + +"@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" + pako "^2.0.4" + tslib "^2.1.0" + +"@wharfkit/transact-plugin-resource-provider@^1.0.0-beta1": + version "1.0.0-beta1" + resolved "https://registry.yarnpkg.com/@wharfkit/transact-plugin-resource-provider/-/transact-plugin-resource-provider-1.0.0-beta1.tgz#63e998d8e2ce00b44885bfc81cfc8326e9294720" + integrity sha512-RhJUzf1q4+q5DgA3j+h82Mm5iTM/Ubglru7v+X/Icq3d0j+JgAbDUG/ARs09TwlT5hXQzRuDR8UIgLkxHkzlEQ== + dependencies: + tslib "^2.1.0" + +"@wharfkit/wallet-plugin-privatekey@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@wharfkit/wallet-plugin-privatekey/-/wallet-plugin-privatekey-0.5.0.tgz#e6a954e08bf80777c4cb12c7ce69c1d9f5e62da2" + integrity sha512-dBpCLWnGfx2kUQUb3OKsKsTxbiFZvBkbh3v8LbnNHd4o/KyOCVbTwFQt6Jl+9QdlNzY2lESe+Ni/HDmfOHKVgg== dependencies: tslib "^2.1.0" @@ -1625,16 +1673,16 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +commander@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + commander@^2.18.0, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@^9.4.1: - version "9.5.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" - integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== - commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -3147,10 +3195,10 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.3.7, semver@^7.3.8: - version "7.3.8" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== +semver@^7.3.7, semver@^7.5.0: + version "7.5.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" + integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== dependencies: lru-cache "^6.0.0" @@ -3389,10 +3437,10 @@ tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.1: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" - integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== +tslib@^2.0.3, tslib@^2.1.0, tslib@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" + integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== tsutils@^3.21.0: version "3.21.0" @@ -3656,15 +3704,15 @@ yargs@^15.0.2: y18n "^4.0.0" yargs-parser "^18.1.2" -yarn-deduplicate@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/yarn-deduplicate/-/yarn-deduplicate-6.0.1.tgz#71d9ee311a10d08edb576a178a5c78fba02f05c2" - integrity sha512-wH2+dyLt1cCMx91kmfiB8GhHiZPVmfD9PULoWGryiqgvA+uvcR3k1yaDbB+K/bTx/NBiMhpnSTFdeWM6MqROYQ== +yarn-deduplicate@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/yarn-deduplicate/-/yarn-deduplicate-6.0.2.tgz#63498d2d4c3a8567e992a994ce0ab51aa5681f2e" + integrity sha512-Efx4XEj82BgbRJe5gvQbZmEO7pU5DgHgxohYZp98/+GwPqdU90RXtzvHirb7hGlde0sQqk5G3J3Woyjai8hVqA== dependencies: "@yarnpkg/lockfile" "^1.1.0" - commander "^9.4.1" - semver "^7.3.8" - tslib "^2.4.1" + commander "^10.0.1" + semver "^7.5.0" + tslib "^2.5.0" yn@3.1.1: version "3.1.1"