New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@wharfkit/contract

Package Overview
Dependencies
Maintainers
3
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@wharfkit/contract - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

172

lib/contract.d.ts

@@ -1,71 +0,69 @@

import { API, NameType, ABISerializableConstructor, ABI, Name, ABIDef, APIClient, Session, ABISerializableObject, TransactResult, ABICacheInterface } from '@wharfkit/session';
import { API, ABIDef, APIClient, ABI, NameType, Name, BytesType, ABISerializableObject, PermissionLevelType, Action } from '@greymass/eosio';
import { ABICacheInterface } from '@wharfkit/abicache';
interface TableCursorParams {
table: Table;
tableParams: API.v1.GetTableRowsParams;
next_key?: API.v1.TableIndexType | string;
indexPositionField?: string;
/** Mashup of valid types for an APIClient call to v1.chain.get_table_rows */
type TableRowParamsTypes = API.v1.GetTableRowsParams | API.v1.GetTableRowsParamsKeyed | API.v1.GetTableRowsParamsTyped;
interface TableCursorArgs {
/** The ABI for the contract this table belongs to */
abi: ABIDef;
/** The APIClient instance to use for API requests */
client: APIClient;
/** The parameters used for the v1/chain/get_table_rows call */
params: TableRowParamsTypes;
/** The maximum number of rows the cursor should retrieve */
maxRows?: number;
}
/**
* Represents a cursor for a table in the blockchain. Provides methods for
* iterating over the rows of the table.
*
* @typeparam TableRow The type of rows in the table.
*/
declare class TableCursor<TableRow> {
private table;
declare class TableCursor<RowType = any> {
/** The ABI for the contract this table belongs to */
readonly abi: ABI;
/** The type of the table, as defined in the ABI */
readonly type: string;
/** The parameters used for the v1/chain/get_table_rows call */
readonly params: TableRowParamsTypes;
/** The APIClient instance to use for API requests */
readonly client: APIClient;
/** For iterating on the cursor, the next key to query against lower_bounds */
private next_key;
private tableParams;
/** Whether or not the cursor believes it has reached the end of its results */
private endReached;
private indexPositionField?;
/** The number of rows the cursor has retrieved */
private rowsCount;
/** The maximum number of rows the cursor should retrieve */
private maxRows;
/**
* @param {TableCursorParams} params - Parameters for creating a new table cursor.
* Create a new TableCursor instance.
*
* @param {TableRow[]} params.rows - An array of rows that the cursor will iterate over.
* Each row represents an entry in the table.
*
* @param {Table} params.table - The table that the rows belong to.
*
* @param {API.v1.GetTableRowsParams} params.tableParams - Parameters for the `get_table_rows`
* API call, which are used to fetch the rows from the blockchain.
*
* @param {(Name | UInt64 | undefined)} [params.next_key] - The key for the next set of rows
* that the cursor can fetch. This is used for pagination when there are more rows than can be
* fetched in a single API call.
* @param args.abi The ABI for the contract.
* @param args.client The APIClient instance to use for API requests.
* @param args.params The parameters to use for the table query.
* @param args.maxRows The maximum number of rows to fetch.
* @returns A new TableCursor instance.
*/
constructor({ table, tableParams, indexPositionField, next_key }: TableCursorParams);
constructor(args: TableCursorArgs);
/**
* Implements the async iterator protocol for the cursor.
*
* @returns An iterator for the rows in the table.
* @returns An iterator for all rows in the table.
*/
[Symbol.asyncIterator](): AsyncGenerator<Awaited<TableRow>, void, unknown>;
[Symbol.asyncIterator](): AsyncGenerator<Awaited<RowType>, void, unknown>;
/**
* Fetches more rows from the table and appends them to the cursor.
* Fetch the next batch of rows from the cursor.
*
* @returns The new rows.
* @param rowsPerAPIRequest The number of rows to fetch per API request.
* @returns A promise containing the next batch of rows.
*/
next(): Promise<TableRow[]>;
next(rowsPerAPIRequest?: number): Promise<RowType[]>;
/**
* Resets the cursor to the beginning of the table and returns the first rows.
*
* @returns The first rows in the table.
* Reset the internal state of the cursor
*/
reset(): Promise<void>;
/**
* Returns all rows in the cursor query.
* Fetch all rows from the cursor by recursively calling next() until the end is reached.
*
* @returns All rows in the cursor query.
* @returns A promise containing all rows for the cursor.
*/
all(): Promise<TableRow[]>;
/**
* Returns a new cursor with updated parameters.
*
* @returns A new cursor with updated parameters.
*/
query(query: Query, { limit }?: QueryOptions): TableCursor<unknown>;
all(): Promise<RowType[]>;
}
interface FindOptions {
interface QueryOptions {
index?: string;

@@ -75,9 +73,7 @@ scope?: NameType;

}
interface QueryOptions extends FindOptions {
limit?: number;
interface Query extends QueryOptions {
from?: API.v1.TableIndexType | string | number;
to?: API.v1.TableIndexType | string | number;
rowsPerAPIRequest?: number;
}
interface Query {
from: API.v1.TableIndexType | string;
to: API.v1.TableIndexType | string;
}
interface FieldToIndex {

@@ -90,6 +86,9 @@ [key: string]: {

interface TableParams<TableRow = any> {
contract: Contract;
abi: ABIDef;
account: NameType;
client: APIClient;
name: NameType;
rowType?: TableRow;
fieldToIndex?: FieldToIndex;
defaultRowLimit?: number;
}

@@ -106,12 +105,15 @@ interface GetTableRowsOptions {

*/
declare class Table<TableRow extends ABISerializableConstructor = ABISerializableConstructor> {
readonly abi: ABI.Table;
declare class Table<RowType = any> {
readonly abi: ABI;
readonly account: Name;
readonly client: APIClient;
readonly name: Name;
readonly contract: Contract;
readonly rowType?: TableRow;
readonly rowType?: RowType;
readonly tableABI: ABI.Table;
private fieldToIndex?;
defaultRowLimit: number;
/**
* Constructs a new `Table` instance.
*
* @param {TableParams<TableRow>} tableParams - Parameters for the table.
* @param {TableParams} tableParams - Parameters for the table.
* The parameters should include:

@@ -124,3 +126,3 @@ * - `contract`: Name of the contract that this table is associated with.

*/
constructor({ contract, name, rowType, fieldToIndex }: TableParams<TableRow>);
constructor(args: TableParams);
/**

@@ -149,3 +151,3 @@ * Creates a new `Table` instance from the given parameters.

*/
query(query: Query, { limit, scope, index, key_type }?: QueryOptions): TableCursor<TableRow>;
query(query: Query): TableCursor<RowType>;
/**

@@ -158,3 +160,3 @@ * Retrieves the row from the table that matches the given parameters.

*/
get(queryValue: API.v1.TableIndexType | string, { scope, index, key_type }?: QueryOptions): Promise<TableRow>;
get(queryValue: API.v1.TableIndexType | string, { scope, index, key_type }?: QueryOptions): Promise<RowType>;
/**

@@ -168,8 +170,8 @@ * Retrieves all the rows from the table.

*/
first(limit: number): TableCursor<TableRow>;
first(maxRows: number, options?: QueryOptions): TableCursor<RowType>;
/**
* Returns a cursor to get every single rows on the table.
* @returns {TableCursor<TableRow>}
* @returns {TableCursor}
*/
cursor(): TableCursor<TableRow>;
cursor(): TableCursor<RowType>;
/**

@@ -179,6 +181,7 @@ * Returns all the rows from the table.

*/
all(): Promise<TableRow[]>;
all(): Promise<RowType[]>;
getFieldToIndex(): any;
}
type ActionDataType = BytesType | ABISerializableObject | Record<string, any>;
interface ContractArgs {

@@ -189,5 +192,10 @@ abi: ABIDef;

}
interface ContractOptions {
session?: Session;
interface ActionArgs {
name: NameType;
data: ActionDataType;
authorization?: PermissionLevelType[];
}
interface ActionOptions {
authorization?: PermissionLevelType[];
}
/**

@@ -202,3 +210,2 @@ * Represents a smart contract deployed to a specific blockchain.

readonly client: APIClient;
readonly session?: Session;
/**

@@ -210,22 +217,15 @@ * Constructs a new `Contract` instance.

*/
constructor(args: ContractArgs, options?: ContractOptions);
static from(args: ContractArgs, options?: ContractOptions): Contract;
get tables(): string[];
constructor(args: ContractArgs);
get tableNames(): string[];
hasTable(name: NameType): boolean;
table(name: NameType): Table<any>;
/**
* Calls a contract action.
*
* @param {NameType} name - The name of the action.
* @param {ABISerializableObject | {[key: string]: any}} data - The data for the action.
* @param {Session} session - The session object to use to sign the transaction.
* @return {Promise<TransactResult>} A promise that resolves with the transaction data.
*/
call(name: NameType, data: ABISerializableObject | {
[key: string]: any;
}, session: Session): Promise<TransactResult>;
get actionNames(): string[];
hasAction(name: NameType): boolean;
action(name: NameType, data: ActionDataType, options?: ActionOptions): Action;
actions(actions: ActionArgs[], options?: ActionOptions): Action[];
ricardian(name: NameType): string;
}
interface ContractKitArgs {
client?: APIClient;
session?: Session;
client: APIClient;
}

@@ -253,2 +253,2 @@ interface ABIDefinition {

export { ABIDefinition, Contract, ContractArgs, ContractKit, ContractKitArgs, ContractKitOptions, ContractOptions, FindOptions, GetTableRowsOptions, Query, QueryOptions, Table, TableCursor, ContractKit as default };
export { ABIDefinition, ActionArgs, ActionDataType, ActionOptions, Contract, ContractArgs, ContractKit, ContractKitArgs, ContractKitOptions, GetTableRowsOptions, Query, QueryOptions, Table, TableCursor, TableCursorArgs, TableRowParamsTypes, ContractKit as default };

@@ -5,4 +5,6 @@ 'use strict';

var eosio = require('@greymass/eosio');
var eosioSigningRequest = require('eosio-signing-request');
var tslib = require('tslib');
var session = require('@wharfkit/session');
var abicache = require('@wharfkit/abicache');

@@ -27,23 +29,35 @@ function indexPositionInWords(index) {

}
if (session.isInstanceOf(value, session.UInt128) ||
session.isInstanceOf(value, session.UInt64) ||
session.isInstanceOf(value, session.Float64) ||
session.isInstanceOf(value, session.Checksum256) ||
session.isInstanceOf(value, session.Checksum160)) {
if (eosio.isInstanceOf(value, eosio.UInt128) ||
eosio.isInstanceOf(value, eosio.UInt64) ||
eosio.isInstanceOf(value, eosio.Float64) ||
eosio.isInstanceOf(value, eosio.Checksum256) ||
eosio.isInstanceOf(value, eosio.Checksum160)) {
return value;
}
if (typeof value === 'number') {
return session.UInt64.from(value);
return eosio.UInt64.from(value);
}
return session.Name.from(value);
return eosio.Name.from(value);
}
const defaultParams = {
json: false,
limit: 1000,
};
class TableCursor {
constructor({ table, tableParams, indexPositionField, next_key }) {
constructor(args) {
this.endReached = false;
this.rowsCount = 0;
this.table = table;
this.tableParams = tableParams;
this.next_key = next_key;
this.indexPositionField = indexPositionField;
this.maxRows = Number.MAX_SAFE_INTEGER;
this.abi = eosio.ABI.from(args.abi);
this.client = args.client;
this.params = Object.assign(Object.assign({}, defaultParams), args.params);
if (args.maxRows) {
this.maxRows = args.maxRows;
}
const table = this.abi.tables.find((t) => t.name === String(this.params.table));
if (!table) {
throw new Error('Table not found');
}
this.type = table.type;
}

@@ -63,3 +77,3 @@ [Symbol.asyncIterator]() {

}
next() {
next(rowsPerAPIRequest = Number.MAX_SAFE_INTEGER) {
return tslib.__awaiter(this, void 0, void 0, function* () {

@@ -69,21 +83,23 @@ if (this.endReached) {

}
let lower_bound = this.tableParams.lower_bound;
const upper_bound = this.tableParams.upper_bound;
let lower_bound = this.params.lower_bound;
if (this.next_key) {
lower_bound = this.next_key;
}
let indexPosition = this.tableParams.index_position || 'primary';
if (this.indexPositionField) {
const fieldToIndexMapping = this.table.getFieldToIndex();
if (!fieldToIndexMapping[this.indexPositionField]) {
throw new Error(`Field ${this.indexPositionField} is not a valid index.`);
}
indexPosition = fieldToIndexMapping[this.indexPositionField].index_position;
}
const { rows, next_key } = yield this.table.contract.client.v1.chain.get_table_rows(Object.assign(Object.assign({}, this.tableParams), { limit: Math.min(this.tableParams.limit - this.rowsCount, 1000000), lower_bound: wrapIndexValue(lower_bound), upper_bound: wrapIndexValue(upper_bound), index_position: indexPosition }));
this.next_key = next_key;
if (!next_key || rows.length === 0 || this.rowsCount === this.tableParams.limit) {
const rowsRemaining = this.maxRows - this.rowsCount;
const limit = Math.min(rowsRemaining, rowsPerAPIRequest, this.params.limit);
const query = Object.assign(Object.assign({}, this.params), { limit, lower_bound: wrapIndexValue(lower_bound), upper_bound: wrapIndexValue(this.params.upper_bound) });
const result = yield this.client.v1.chain.get_table_rows(query);
const requiresDecoding = this.params.json === false && !query.type;
const rows = requiresDecoding
? result.rows.map((data) => eosio.Serializer.decode({
data,
abi: this.abi,
type: this.type,
}))
: result.rows;
this.next_key = result.next_key;
this.rowsCount += rows.length;
if (!result.next_key || rows.length === 0 || this.rowsCount === this.maxRows) {
this.endReached = true;
}
this.rowsCount += rows.length;
return rows;

@@ -126,21 +142,18 @@ });

}
query(query, { limit } = {}) {
return new TableCursor({
table: this.table,
tableParams: Object.assign(Object.assign({}, this.tableParams), { limit: limit || this.tableParams.limit, lower_bound: query.from || this.tableParams.lower_bound, upper_bound: query.to || this.tableParams.upper_bound }),
});
}
}
class Table {
constructor({ contract, name, rowType, fieldToIndex }) {
this.name = session.Name.from(name);
const abi = contract.abi.tables.find((table) => this.name.equals(table.name));
if (!abi) {
constructor(args) {
this.defaultRowLimit = 1000;
this.abi = eosio.ABI.from(args.abi);
this.account = eosio.Name.from(args.account);
this.name = eosio.Name.from(args.name);
this.client = args.client;
this.rowType = args.rowType;
this.fieldToIndex = args.fieldToIndex;
const tableABI = this.abi.tables.find((table) => this.name.equals(table.name));
if (!tableABI) {
throw new Error(`Table ${this.name} not found in ABI`);
}
this.abi = abi;
this.rowType = rowType;
this.fieldToIndex = fieldToIndex;
this.contract = contract;
this.tableABI = tableABI;
}

@@ -150,21 +163,28 @@ static from(tableParams) {

}
query(query, { limit = 10, scope = this.contract.account, index, key_type } = {}) {
const { from, to } = query;
query(query) {
const { from, to, rowsPerAPIRequest } = query;
const tableRowsParams = {
table: this.name,
code: this.contract.account,
scope,
code: this.account,
scope: query.scope || this.account,
type: this.rowType,
limit,
limit: rowsPerAPIRequest || this.defaultRowLimit,
lower_bound: wrapIndexValue(from),
upper_bound: wrapIndexValue(to),
key_type: key_type,
key_type: query.key_type,
};
if (query.index) {
const fieldToIndexMapping = this.getFieldToIndex();
if (!fieldToIndexMapping[query.index]) {
throw new Error(`Field ${query.index} is not a valid index.`);
}
tableRowsParams.index_position = fieldToIndexMapping[query.index].index_position;
}
return new TableCursor({
table: this,
tableParams: tableRowsParams,
indexPositionField: index,
abi: this.abi,
client: this.client,
params: tableRowsParams,
});
}
get(queryValue, { scope = this.contract.account, index, key_type } = {}) {
get(queryValue, { scope = this.account, index, key_type } = {}) {
return tslib.__awaiter(this, void 0, void 0, function* () {

@@ -174,3 +194,3 @@ const fieldToIndexMapping = this.getFieldToIndex();

table: this.name,
code: this.contract.account,
code: this.account,
scope,

@@ -183,17 +203,30 @@ type: this.rowType,

key_type: key_type,
json: false,
};
const { rows } = yield this.contract.client.v1.chain.get_table_rows(tableRowsParams);
let { rows } = yield this.client.v1.chain.get_table_rows(tableRowsParams);
if (!this.rowType) {
rows = [
eosio.Serializer.decode({
data: rows[0],
abi: this.abi,
type: this.tableABI.type,
}),
];
}
return rows[0];
});
}
first(limit) {
first(maxRows, options = {}) {
const tableRowsParams = {
table: this.name,
limit,
code: this.contract.account,
limit: maxRows,
code: this.account,
type: this.rowType,
scope: options.scope,
};
return new TableCursor({
table: this,
tableParams: tableRowsParams,
abi: this.abi,
client: this.client,
maxRows,
params: tableRowsParams,
});

@@ -204,9 +237,10 @@ }

table: this.name,
code: this.contract.account,
code: this.account,
type: this.rowType,
limit: 1000000,
limit: this.defaultRowLimit,
};
return new TableCursor({
table: this,
tableParams: tableRowsParams,
abi: this.abi,
client: this.client,
params: tableRowsParams,
});

@@ -224,5 +258,5 @@ }

const fieldToIndex = {};
for (let i = 0; i < this.abi.key_names.length; i++) {
fieldToIndex[this.abi.key_names[i]] = {
type: this.abi.key_types[i],
for (let i = 0; i < this.tableABI.key_names.length; i++) {
fieldToIndex[this.tableABI.key_names[i]] = {
type: this.tableABI.key_types[i],
index_position: indexPositionInWords(i),

@@ -236,36 +270,60 @@ };

class Contract {
constructor(args, options = {}) {
this.abi = session.ABI.from(args.abi);
this.account = session.Name.from(args.account);
constructor(args) {
this.abi = eosio.ABI.from(args.abi);
this.account = eosio.Name.from(args.account);
this.client = args.client;
if (options.session) {
this.session = options.session;
}
}
static from(args, options = {}) {
return new this(args, options);
}
get tables() {
get tableNames() {
return this.abi.tables.map((table) => String(table.name));
}
hasTable(name) {
return this.tableNames.includes(String(name));
}
table(name) {
if (!this.tables.includes(String(name))) {
if (!this.hasTable(name)) {
throw new Error(`Contract (${this.account}) does not have a table named (${name})`);
}
return Table.from({
contract: this,
abi: this.abi,
account: this.account,
client: this.client,
name,
});
}
call(name, data, session$1) {
return tslib.__awaiter(this, void 0, void 0, function* () {
const action = session.Action.from({
account: this.account,
name,
authorization: [],
data,
});
return session$1.transact({ action });
});
get actionNames() {
return this.abi.actions.map((action) => String(action.name));
}
hasAction(name) {
return this.actionNames.includes(String(name));
}
action(name, data, options) {
if (!this.hasAction(name)) {
throw new Error(`Contract (${this.account}) does not have an action named (${name})`);
}
let authorization = [eosioSigningRequest.PlaceholderAuth];
if (options && options.authorization) {
authorization = options.authorization.map((auth) => eosio.PermissionLevel.from(auth));
}
return eosio.Action.from({
account: this.account,
name,
authorization,
data,
}, this.abi);
}
actions(actions, options) {
return actions.map((action) => this.action(action.name, action.data, {
authorization: action.authorization || (options === null || options === void 0 ? void 0 : options.authorization),
}));
}
ricardian(name) {
if (!this.hasAction(name)) {
throw new Error(`Contract (${this.account}) does not have an action named (${name})`);
}
const action = this.abi.actions.find((action) => eosio.Name.from(action.name).equals(name));
if (!action || !action.ricardian_contract) {
throw new Error(`Contract (${this.account}) action named (${name}) does not have a defined ricardian contract`);
}
return action.ricardian_contract;
}
}

@@ -279,7 +337,4 @@

}
else if (args.session) {
this.client = args.session.client;
}
else {
throw new Error('Either a `client` or `session` must be passed when initializing the ContractKit.');
throw new Error('A `client` must be passed when initializing the ContractKit.');
}

@@ -289,10 +344,7 @@ if (options.abiCache) {

}
else if (args.session) {
this.abiCache = args.session.abiCache;
}
else {
this.abiCache = new session.ABICache(this.client);
this.abiCache = new abicache.ABICache(this.client);
}
if (options.abis) {
options.abis.forEach(({ name, abi }) => this.abiCache.setAbi(session.Name.from(name), session.ABI.from(abi)));
options.abis.forEach(({ name, abi }) => this.abiCache.setAbi(eosio.Name.from(name), eosio.ABI.from(abi)));
}

@@ -302,6 +354,6 @@ }

return tslib.__awaiter(this, void 0, void 0, function* () {
const account = session.Name.from(contract);
const account = eosio.Name.from(contract);
const abiDef = yield this.abiCache.getAbi(account);
return new Contract({
abi: session.ABI.from(abiDef),
abi: eosio.ABI.from(abiDef),
account,

@@ -308,0 +360,0 @@ client: this.client,

@@ -1,2 +0,4 @@

import { isInstanceOf, UInt128, UInt64, Float64, Checksum256, Checksum160, Name, ABI, Action, ABICache } from '@wharfkit/session';
import { isInstanceOf, UInt128, UInt64, Float64, Checksum256, Checksum160, Name, ABI, Serializer, PermissionLevel, Action } from '@greymass/eosio';
import { PlaceholderAuth } from 'eosio-signing-request';
import { ABICache } from '@wharfkit/abicache';

@@ -34,10 +36,25 @@ function indexPositionInWords(index) {

const defaultParams = {
json: false,
limit: 1000,
};
class TableCursor {
constructor({ table, tableParams, indexPositionField, next_key }) {
constructor(args) {
this.endReached = false;
this.rowsCount = 0;
this.table = table;
this.tableParams = tableParams;
this.next_key = next_key;
this.indexPositionField = indexPositionField;
this.maxRows = Number.MAX_SAFE_INTEGER;
this.abi = ABI.from(args.abi);
this.client = args.client;
this.params = {
...defaultParams,
...args.params,
};
if (args.maxRows) {
this.maxRows = args.maxRows;
}
const table = this.abi.tables.find((t) => t.name === String(this.params.table));
if (!table) {
throw new Error('Table not found');
}
this.type = table.type;
}

@@ -55,31 +72,32 @@ async *[Symbol.asyncIterator]() {

}
async next() {
async next(rowsPerAPIRequest = Number.MAX_SAFE_INTEGER) {
if (this.endReached) {
return [];
}
let lower_bound = this.tableParams.lower_bound;
const upper_bound = this.tableParams.upper_bound;
let lower_bound = this.params.lower_bound;
if (this.next_key) {
lower_bound = this.next_key;
}
let indexPosition = this.tableParams.index_position || 'primary';
if (this.indexPositionField) {
const fieldToIndexMapping = this.table.getFieldToIndex();
if (!fieldToIndexMapping[this.indexPositionField]) {
throw new Error(`Field ${this.indexPositionField} is not a valid index.`);
}
indexPosition = fieldToIndexMapping[this.indexPositionField].index_position;
}
const { rows, next_key } = await this.table.contract.client.v1.chain.get_table_rows({
...this.tableParams,
limit: Math.min(this.tableParams.limit - this.rowsCount, 1000000),
const rowsRemaining = this.maxRows - this.rowsCount;
const limit = Math.min(rowsRemaining, rowsPerAPIRequest, this.params.limit);
const query = {
...this.params,
limit,
lower_bound: wrapIndexValue(lower_bound),
upper_bound: wrapIndexValue(upper_bound),
index_position: indexPosition,
});
this.next_key = next_key;
if (!next_key || rows.length === 0 || this.rowsCount === this.tableParams.limit) {
upper_bound: wrapIndexValue(this.params.upper_bound),
};
const result = await this.client.v1.chain.get_table_rows(query);
const requiresDecoding = this.params.json === false && !query.type;
const rows = requiresDecoding
? result.rows.map((data) => Serializer.decode({
data,
abi: this.abi,
type: this.type,
}))
: result.rows;
this.next_key = result.next_key;
this.rowsCount += rows.length;
if (!result.next_key || rows.length === 0 || this.rowsCount === this.maxRows) {
this.endReached = true;
}
this.rowsCount += rows.length;
return rows;

@@ -99,26 +117,18 @@ }

}
query(query, { limit } = {}) {
return new TableCursor({
table: this.table,
tableParams: {
...this.tableParams,
limit: limit || this.tableParams.limit,
lower_bound: query.from || this.tableParams.lower_bound,
upper_bound: query.to || this.tableParams.upper_bound,
},
});
}
}
class Table {
constructor({ contract, name, rowType, fieldToIndex }) {
this.name = Name.from(name);
const abi = contract.abi.tables.find((table) => this.name.equals(table.name));
if (!abi) {
constructor(args) {
this.defaultRowLimit = 1000;
this.abi = ABI.from(args.abi);
this.account = Name.from(args.account);
this.name = Name.from(args.name);
this.client = args.client;
this.rowType = args.rowType;
this.fieldToIndex = args.fieldToIndex;
const tableABI = this.abi.tables.find((table) => this.name.equals(table.name));
if (!tableABI) {
throw new Error(`Table ${this.name} not found in ABI`);
}
this.abi = abi;
this.rowType = rowType;
this.fieldToIndex = fieldToIndex;
this.contract = contract;
this.tableABI = tableABI;
}

@@ -128,25 +138,32 @@ static from(tableParams) {

}
query(query, { limit = 10, scope = this.contract.account, index, key_type } = {}) {
const { from, to } = query;
query(query) {
const { from, to, rowsPerAPIRequest } = query;
const tableRowsParams = {
table: this.name,
code: this.contract.account,
scope,
code: this.account,
scope: query.scope || this.account,
type: this.rowType,
limit,
limit: rowsPerAPIRequest || this.defaultRowLimit,
lower_bound: wrapIndexValue(from),
upper_bound: wrapIndexValue(to),
key_type: key_type,
key_type: query.key_type,
};
if (query.index) {
const fieldToIndexMapping = this.getFieldToIndex();
if (!fieldToIndexMapping[query.index]) {
throw new Error(`Field ${query.index} is not a valid index.`);
}
tableRowsParams.index_position = fieldToIndexMapping[query.index].index_position;
}
return new TableCursor({
table: this,
tableParams: tableRowsParams,
indexPositionField: index,
abi: this.abi,
client: this.client,
params: tableRowsParams,
});
}
async get(queryValue, { scope = this.contract.account, index, key_type } = {}) {
async get(queryValue, { scope = this.account, index, key_type } = {}) {
const fieldToIndexMapping = this.getFieldToIndex();
const tableRowsParams = {
table: this.name,
code: this.contract.account,
code: this.account,
scope,

@@ -159,16 +176,29 @@ type: this.rowType,

key_type: key_type,
json: false,
};
const { rows } = await this.contract.client.v1.chain.get_table_rows(tableRowsParams);
let { rows } = await this.client.v1.chain.get_table_rows(tableRowsParams);
if (!this.rowType) {
rows = [
Serializer.decode({
data: rows[0],
abi: this.abi,
type: this.tableABI.type,
}),
];
}
return rows[0];
}
first(limit) {
first(maxRows, options = {}) {
const tableRowsParams = {
table: this.name,
limit,
code: this.contract.account,
limit: maxRows,
code: this.account,
type: this.rowType,
scope: options.scope,
};
return new TableCursor({
table: this,
tableParams: tableRowsParams,
abi: this.abi,
client: this.client,
maxRows,
params: tableRowsParams,
});

@@ -179,9 +209,10 @@ }

table: this.name,
code: this.contract.account,
code: this.account,
type: this.rowType,
limit: 1000000,
limit: this.defaultRowLimit,
};
return new TableCursor({
table: this,
tableParams: tableRowsParams,
abi: this.abi,
client: this.client,
params: tableRowsParams,
});

@@ -197,5 +228,5 @@ }

const fieldToIndex = {};
for (let i = 0; i < this.abi.key_names.length; i++) {
fieldToIndex[this.abi.key_names[i]] = {
type: this.abi.key_types[i],
for (let i = 0; i < this.tableABI.key_names.length; i++) {
fieldToIndex[this.tableABI.key_names[i]] = {
type: this.tableABI.key_types[i],
index_position: indexPositionInWords(i),

@@ -209,34 +240,60 @@ };

class Contract {
constructor(args, options = {}) {
constructor(args) {
this.abi = ABI.from(args.abi);
this.account = Name.from(args.account);
this.client = args.client;
if (options.session) {
this.session = options.session;
}
}
static from(args, options = {}) {
return new this(args, options);
}
get tables() {
get tableNames() {
return this.abi.tables.map((table) => String(table.name));
}
hasTable(name) {
return this.tableNames.includes(String(name));
}
table(name) {
if (!this.tables.includes(String(name))) {
if (!this.hasTable(name)) {
throw new Error(`Contract (${this.account}) does not have a table named (${name})`);
}
return Table.from({
contract: this,
abi: this.abi,
account: this.account,
client: this.client,
name,
});
}
async call(name, data, session) {
const action = Action.from({
get actionNames() {
return this.abi.actions.map((action) => String(action.name));
}
hasAction(name) {
return this.actionNames.includes(String(name));
}
action(name, data, options) {
if (!this.hasAction(name)) {
throw new Error(`Contract (${this.account}) does not have an action named (${name})`);
}
let authorization = [PlaceholderAuth];
if (options && options.authorization) {
authorization = options.authorization.map((auth) => PermissionLevel.from(auth));
}
return Action.from({
account: this.account,
name,
authorization: [],
authorization,
data,
});
return session.transact({ action });
}, this.abi);
}
actions(actions, options) {
return actions.map((action) => this.action(action.name, action.data, {
authorization: action.authorization || options?.authorization,
}));
}
ricardian(name) {
if (!this.hasAction(name)) {
throw new Error(`Contract (${this.account}) does not have an action named (${name})`);
}
const action = this.abi.actions.find((action) => Name.from(action.name).equals(name));
if (!action || !action.ricardian_contract) {
throw new Error(`Contract (${this.account}) action named (${name}) does not have a defined ricardian contract`);
}
return action.ricardian_contract;
}
}

@@ -250,7 +307,4 @@

}
else if (args.session) {
this.client = args.session.client;
}
else {
throw new Error('Either a `client` or `session` must be passed when initializing the ContractKit.');
throw new Error('A `client` must be passed when initializing the ContractKit.');
}

@@ -260,5 +314,2 @@ if (options.abiCache) {

}
else if (args.session) {
this.abiCache = args.session.abiCache;
}
else {

@@ -265,0 +316,0 @@ this.abiCache = new ABICache(this.client);

{
"name": "@wharfkit/contract",
"description": "ContractKit for Wharf",
"version": "0.1.0",
"version": "0.2.0",
"homepage": "https://github.com/wharfkit/contract",

@@ -22,7 +22,10 @@ "license": "BSD-3-Clause",

"dependencies": {
"@wharfkit/mock-data": "^1.0.0-beta11",
"@wharfkit/session": "^1.0.0-beta4",
"rollup-plugin-cleanup": "^3.2.1",
"@greymass/eosio": "^0.6.10",
"@wharfkit/abicache": "^1.0.0",
"eosio-signing-request": "^2.5.3",
"tslib": "^2.1.0"
},
"resolutions": {
"@greymass/eosio": "^0.6.10"
},
"devDependencies": {

@@ -43,2 +46,4 @@ "@babel/preset-env": "^7.20.2",

"@typescript-eslint/parser": "^5.20.0",
"@wharfkit/mock-data": "^1.0.0-beta11",
"@wharfkit/session": "^1.0.0-beta4",
"assert": "^2.0.0",

@@ -45,0 +50,0 @@ "chai": "^4.3.4",

# Contract Kit
Greymass TypeScript library template, intended for libraries that work in any JavaScript context (node.js, Browser, React native), `@types/node` are installed only for tests, don't rely on any node.js types or imports inside `src/` (no `buffer`, `crypto` imports etc, they can be filled for browser but will bloat the bundle 100x)
A library to simplify interactions with Antelope-based smart contracts.
Features:
- Instantiate instances of a `Contract` in your frontend application
- Retrieve smart contract data with `Table` instances.
- Create action data by accessing actions directly through the `.action` method of a `Contract`
- Retrieve Ricardian Contracts for specific actions through the `.ricardian` method of a `Contract`
- Cache and optimize ABI call patterns automatically in your application.
- Generate frontend code based on a smart contracts ABI.
## Installation
The `contract` package is distributed as a module on [npm](https://www.npmjs.com/package/contract).
The `@wharfkit/contract` package is distributed as a module on [npm](https://www.npmjs.com/package/@wharfkit/contract).
```
yarn add contract
yarn add @wharfkit/contract
# or
npm install --save contract
npm install --save @wharfkit/
```
## Usage
To generate the Contract helper for a specific Antelope contract, use the `generate` make target:
```bash
make generate contract=<CONTRACT_NAME_HERE>
```
and your contract helper will be added to `contracts/CONTRACT_NAME.ts`.
```typescript
## Developing

@@ -36,2 +33,1 @@

Made with ☕️ & ❤️ by [Greymass](https://greymass.com), if you find this useful please consider [supporting us](https://greymass.com/support-us).
```

@@ -6,3 +6,3 @@ import * as ts from 'typescript'

import {capitalize} from '../utils'
import {APIClient} from '@wharfkit/session'
import {APIClient} from '@greymass/eosio'

@@ -9,0 +9,0 @@ export async function generateTableClass(contractName, namespaceName, table, abi) {

@@ -7,10 +7,14 @@ import {

APIClient,
BytesType,
Name,
NameType,
Session,
TransactResult,
} from '@wharfkit/session'
PermissionLevel,
PermissionLevelType,
} from '@greymass/eosio'
import {PlaceholderAuth} from 'eosio-signing-request'
import {Table} from './contract/table'
export type ActionDataType = BytesType | ABISerializableObject | Record<string, any>
export interface ContractArgs {

@@ -22,6 +26,12 @@ abi: ABIDef

export interface ContractOptions {
session?: Session
export interface ActionArgs {
name: NameType
data: ActionDataType
authorization?: PermissionLevelType[]
}
export interface ActionOptions {
authorization?: PermissionLevelType[]
}
/**

@@ -36,3 +46,2 @@ * Represents a smart contract deployed to a specific blockchain.

readonly client: APIClient
readonly session?: Session

@@ -45,26 +54,24 @@ /**

*/
constructor(args: ContractArgs, options: ContractOptions = {}) {
constructor(args: ContractArgs) {
this.abi = ABI.from(args.abi)
this.account = Name.from(args.account)
this.client = args.client
if (options.session) {
this.session = options.session
}
}
static from(args: ContractArgs, options: ContractOptions = {}): Contract {
return new this(args, options)
public get tableNames(): string[] {
return this.abi.tables.map((table) => String(table.name))
}
get tables(): string[] {
return this.abi.tables.map((table) => String(table.name))
public hasTable(name: NameType): boolean {
return this.tableNames.includes(String(name))
}
public table(name: NameType) {
if (!this.tables.includes(String(name))) {
if (!this.hasTable(name)) {
throw new Error(`Contract (${this.account}) does not have a table named (${name})`)
}
return Table.from({
contract: this,
abi: this.abi,
account: this.account,
client: this.client,
name,

@@ -74,26 +81,51 @@ })

// TODO: reimplement call method
/**
* Calls a contract action.
*
* @param {NameType} name - The name of the action.
* @param {ABISerializableObject | {[key: string]: any}} data - The data for the action.
* @param {Session} session - The session object to use to sign the transaction.
* @return {Promise<TransactResult>} A promise that resolves with the transaction data.
*/
async call(
name: NameType,
data: ABISerializableObject | {[key: string]: any},
session: Session
): Promise<TransactResult> {
const action: Action = Action.from({
account: this.account,
name,
authorization: [],
data,
})
public get actionNames(): string[] {
return this.abi.actions.map((action) => String(action.name))
}
// Trigger the transaction using the session kit
return session.transact({action})
public hasAction(name: NameType): boolean {
return this.actionNames.includes(String(name))
}
public action(name: NameType, data: ActionDataType, options?: ActionOptions): Action {
if (!this.hasAction(name)) {
throw new Error(`Contract (${this.account}) does not have an action named (${name})`)
}
let authorization = [PlaceholderAuth]
if (options && options.authorization) {
authorization = options.authorization.map((auth) => PermissionLevel.from(auth))
}
return Action.from(
{
account: this.account,
name,
authorization,
data,
},
this.abi
)
}
public actions(actions: ActionArgs[], options?: ActionOptions): Action[] {
return actions.map((action) =>
this.action(action.name, action.data, {
authorization: action.authorization || options?.authorization,
})
)
}
public ricardian(name: NameType) {
if (!this.hasAction(name)) {
throw new Error(`Contract (${this.account}) does not have an action named (${name})`)
}
const action = this.abi.actions.find((action) => Name.from(action.name).equals(name))
if (!action || !action.ricardian_contract) {
throw new Error(
`Contract (${this.account}) action named (${name}) does not have a defined ricardian contract`
)
}
return action.ricardian_contract
}
}

@@ -1,46 +0,70 @@

import {API} from '@wharfkit/session'
import {ABI, ABIDef, API, APIClient, Serializer} from '@greymass/eosio'
import {wrapIndexValue} from '../utils'
import {Query, QueryOptions, Table} from './table'
interface TableCursorParams {
table: Table
tableParams: API.v1.GetTableRowsParams
next_key?: API.v1.TableIndexType | string
indexPositionField?: string
/** Mashup of valid types for an APIClient call to v1.chain.get_table_rows */
export type TableRowParamsTypes =
| API.v1.GetTableRowsParams
| API.v1.GetTableRowsParamsKeyed
| API.v1.GetTableRowsParamsTyped
export interface TableCursorArgs {
/** The ABI for the contract this table belongs to */
abi: ABIDef
/** The APIClient instance to use for API requests */
client: APIClient
/** The parameters used for the v1/chain/get_table_rows call */
params: TableRowParamsTypes
/** The maximum number of rows the cursor should retrieve */
maxRows?: number
}
/**
* Represents a cursor for a table in the blockchain. Provides methods for
* iterating over the rows of the table.
*
* @typeparam TableRow The type of rows in the table.
*/
export class TableCursor<TableRow> {
private table: Table
/** The default parameters to use on a v1/chain/get_table_rows call */
const defaultParams = {
json: false,
limit: 1000,
}
export class TableCursor<RowType = any> {
/** The ABI for the contract this table belongs to */
readonly abi: ABI
/** The type of the table, as defined in the ABI */
readonly type: string
/** The parameters used for the v1/chain/get_table_rows call */
readonly params: TableRowParamsTypes
/** The APIClient instance to use for API requests */
readonly client: APIClient
/** For iterating on the cursor, the next key to query against lower_bounds */
private next_key: API.v1.TableIndexType | string | undefined
private tableParams: API.v1.GetTableRowsParams
/** Whether or not the cursor believes it has reached the end of its results */
private endReached = false
private indexPositionField?: string
/** The number of rows the cursor has retrieved */
private rowsCount = 0
/** The maximum number of rows the cursor should retrieve */
private maxRows: number = Number.MAX_SAFE_INTEGER
/**
* @param {TableCursorParams} params - Parameters for creating a new table cursor.
* Create a new TableCursor instance.
*
* @param {TableRow[]} params.rows - An array of rows that the cursor will iterate over.
* Each row represents an entry in the table.
*
* @param {Table} params.table - The table that the rows belong to.
*
* @param {API.v1.GetTableRowsParams} params.tableParams - Parameters for the `get_table_rows`
* API call, which are used to fetch the rows from the blockchain.
*
* @param {(Name | UInt64 | undefined)} [params.next_key] - The key for the next set of rows
* that the cursor can fetch. This is used for pagination when there are more rows than can be
* fetched in a single API call.
* @param args.abi The ABI for the contract.
* @param args.client The APIClient instance to use for API requests.
* @param args.params The parameters to use for the table query.
* @param args.maxRows The maximum number of rows to fetch.
* @returns A new TableCursor instance.
*/
constructor({table, tableParams, indexPositionField, next_key}: TableCursorParams) {
this.table = table
this.tableParams = tableParams
this.next_key = next_key
this.indexPositionField = indexPositionField
constructor(args: TableCursorArgs) {
this.abi = ABI.from(args.abi)
this.client = args.client
this.params = {
...defaultParams,
...args.params,
}
if (args.maxRows) {
this.maxRows = args.maxRows
}
const table = this.abi.tables.find((t) => t.name === String(this.params.table))
if (!table) {
throw new Error('Table not found')
}
this.type = table.type
}

@@ -51,3 +75,3 @@

*
* @returns An iterator for the rows in the table.
* @returns An iterator for all rows in the table.
*/

@@ -62,3 +86,2 @@ async *[Symbol.asyncIterator]() {

// If no rows are returned or next_key is undefined, we have exhausted all rows
if (rows.length === 0 || !this.next_key) {

@@ -71,7 +94,9 @@ return

/**
* Fetches more rows from the table and appends them to the cursor.
* Fetch the next batch of rows from the cursor.
*
* @returns The new rows.
* @param rowsPerAPIRequest The number of rows to fetch per API request.
* @returns A promise containing the next batch of rows.
*/
async next(): Promise<TableRow[]> {
async next(rowsPerAPIRequest: number = Number.MAX_SAFE_INTEGER): Promise<RowType[]> {
// If the cursor has deemed its at the end, return an empty array
if (this.endReached) {

@@ -81,5 +106,4 @@ return []

let lower_bound = this.tableParams.lower_bound
const upper_bound = this.tableParams.upper_bound
// Set the lower_bound, and override if the cursor has a next_key value
let lower_bound = this.params.lower_bound
if (this.next_key) {

@@ -89,30 +113,44 @@ lower_bound = this.next_key

let indexPosition = this.tableParams.index_position || 'primary'
// Determine the maximum number of remaining rows for the cursor
const rowsRemaining = this.maxRows - this.rowsCount
if (this.indexPositionField) {
const fieldToIndexMapping = this.table.getFieldToIndex()
// Find the lowest amount between rows remaining, rows per request, or the provided query params limit
const limit = Math.min(rowsRemaining, rowsPerAPIRequest, this.params.limit)
if (!fieldToIndexMapping[this.indexPositionField]) {
throw new Error(`Field ${this.indexPositionField} is not a valid index.`)
}
indexPosition = fieldToIndexMapping[this.indexPositionField].index_position
// Assemble and perform the v1/chain/get_table_rows query
const query = {
...this.params,
limit,
lower_bound: wrapIndexValue(lower_bound),
upper_bound: wrapIndexValue(this.params.upper_bound),
}
const {rows, next_key} = await this.table.contract.client!.v1.chain.get_table_rows({
...this.tableParams,
limit: Math.min(this.tableParams.limit - this.rowsCount, 1000000),
lower_bound: wrapIndexValue(lower_bound),
upper_bound: wrapIndexValue(upper_bound),
index_position: indexPosition,
})
const result = await this.client!.v1.chain.get_table_rows(query)
this.next_key = next_key
// Determine if we need to decode the rows, based on if:
// - json parameter is false, meaning hex data will be returned
// - type parameter is not set, meaning the APIClient will not automatically decode
const requiresDecoding =
this.params.json === false && !(query as API.v1.GetTableRowsParamsTyped).type
if (!next_key || rows.length === 0 || this.rowsCount === this.tableParams.limit) {
// Retrieve the rows from the result, decoding if needed
const rows: RowType[] = requiresDecoding
? result.rows.map((data) =>
Serializer.decode({
data,
abi: this.abi,
type: this.type,
})
)
: result.rows
// Persist cursor state for subsequent calls
this.next_key = result.next_key
this.rowsCount += rows.length
// Determine if we've reached the end of the cursor
if (!result.next_key || rows.length === 0 || this.rowsCount === this.maxRows) {
this.endReached = true
}
this.rowsCount += rows.length
return rows

@@ -122,5 +160,3 @@ }

/**
* Resets the cursor to the beginning of the table and returns the first rows.
*
* @returns The first rows in the table.
* Reset the internal state of the cursor
*/

@@ -134,8 +170,8 @@ async reset() {

/**
* Returns all rows in the cursor query.
* Fetch all rows from the cursor by recursively calling next() until the end is reached.
*
* @returns All rows in the cursor query.
* @returns A promise containing all rows for the cursor.
*/
async all() {
const rows: TableRow[] = []
async all(): Promise<RowType[]> {
const rows: RowType[] = []
for await (const row of this) {

@@ -146,19 +182,2 @@ rows.push(row)

}
/**
* Returns a new cursor with updated parameters.
*
* @returns A new cursor with updated parameters.
*/
query(query: Query, {limit}: QueryOptions = {}) {
return new TableCursor({
table: this.table,
tableParams: {
...this.tableParams,
limit: limit || this.tableParams.limit,
lower_bound: query.from || this.tableParams.lower_bound,
upper_bound: query.to || this.tableParams.upper_bound,
},
})
}
}

@@ -1,7 +0,6 @@

import {ABI, ABISerializableConstructor, API, Name, NameType} from '@wharfkit/session'
import type {Contract} from '../contract'
import {ABI, ABIDef, API, APIClient, Name, NameType, Serializer} from '@greymass/eosio'
import {indexPositionInWords, wrapIndexValue} from '../utils'
import {TableCursor} from './table-cursor'
export interface FindOptions {
export interface QueryOptions {
index?: string

@@ -12,11 +11,8 @@ scope?: NameType

export interface QueryOptions extends FindOptions {
limit?: number
export interface Query extends QueryOptions {
from?: API.v1.TableIndexType | string | number
to?: API.v1.TableIndexType | string | number
rowsPerAPIRequest?: number
}
export interface Query {
from: API.v1.TableIndexType | string
to: API.v1.TableIndexType | string
}
interface FieldToIndex {

@@ -29,6 +25,9 @@ [key: string]: {

interface TableParams<TableRow = any> {
contract: Contract
abi: ABIDef
account: NameType
client: APIClient
name: NameType
rowType?: TableRow
fieldToIndex?: FieldToIndex
defaultRowLimit?: number
}

@@ -47,14 +46,18 @@

*/
export class Table<TableRow extends ABISerializableConstructor = ABISerializableConstructor> {
readonly abi: ABI.Table
export class Table<RowType = any> {
readonly abi: ABI
readonly account: Name
readonly client: APIClient
readonly name: Name
readonly contract: Contract
readonly rowType?: TableRow
readonly rowType?: RowType
readonly tableABI: ABI.Table
private fieldToIndex?: any
public defaultRowLimit = 1000
/**
* Constructs a new `Table` instance.
*
* @param {TableParams<TableRow>} tableParams - Parameters for the table.
* @param {TableParams} tableParams - Parameters for the table.
* The parameters should include:

@@ -67,14 +70,14 @@ * - `contract`: Name of the contract that this table is associated with.

*/
constructor({contract, name, rowType, fieldToIndex}: TableParams<TableRow>) {
this.name = Name.from(name)
const abi = contract.abi.tables.find((table) => this.name.equals(table.name))
if (!abi) {
constructor(args: TableParams) {
this.abi = ABI.from(args.abi)
this.account = Name.from(args.account)
this.name = Name.from(args.name)
this.client = args.client
this.rowType = args.rowType
this.fieldToIndex = args.fieldToIndex
const tableABI = this.abi.tables.find((table) => this.name.equals(table.name))
if (!tableABI) {
throw new Error(`Table ${this.name} not found in ABI`)
}
this.abi = abi
this.rowType = rowType
this.fieldToIndex = fieldToIndex
this.contract = contract
this.tableABI = tableABI
}

@@ -108,23 +111,30 @@

*/
query(
query: Query,
{limit = 10, scope = this.contract.account, index, key_type}: QueryOptions = {}
): TableCursor<TableRow> {
const {from, to} = query
query(query: Query): TableCursor<RowType> {
const {from, to, rowsPerAPIRequest} = query
const tableRowsParams = {
const tableRowsParams: any = {
table: this.name,
code: this.contract.account,
scope,
code: this.account,
scope: query.scope || this.account,
type: this.rowType,
limit,
limit: rowsPerAPIRequest || this.defaultRowLimit,
lower_bound: wrapIndexValue(from),
upper_bound: wrapIndexValue(to),
key_type: key_type,
key_type: query.key_type,
}
return new TableCursor({
table: this,
tableParams: tableRowsParams,
indexPositionField: index,
if (query.index) {
const fieldToIndexMapping = this.getFieldToIndex()
if (!fieldToIndexMapping[query.index]) {
throw new Error(`Field ${query.index} is not a valid index.`)
}
tableRowsParams.index_position = fieldToIndexMapping[query.index].index_position
}
return new TableCursor<RowType>({
abi: this.abi,
client: this.client,
params: tableRowsParams,
})

@@ -142,4 +152,4 @@ }

queryValue: API.v1.TableIndexType | string,
{scope = this.contract.account, index, key_type}: QueryOptions = {}
): Promise<TableRow> {
{scope = this.account, index, key_type}: QueryOptions = {}
): Promise<RowType> {
const fieldToIndexMapping = this.getFieldToIndex()

@@ -149,3 +159,3 @@

table: this.name,
code: this.contract.account,
code: this.account,
scope,

@@ -158,6 +168,17 @@ type: this.rowType!,

key_type: key_type,
json: false,
}
const {rows} = await this.contract.client!.v1.chain.get_table_rows(tableRowsParams)
let {rows} = await this.client!.v1.chain.get_table_rows(tableRowsParams)
if (!this.rowType) {
rows = [
Serializer.decode({
data: rows[0],
abi: this.abi,
type: this.tableABI.type,
}),
]
}
return rows[0]

@@ -174,13 +195,16 @@ }

*/
first(limit: number): TableCursor<TableRow> {
first(maxRows: number, options: QueryOptions = {}): TableCursor<RowType> {
const tableRowsParams = {
table: this.name,
limit,
code: this.contract.account,
limit: maxRows,
code: this.account,
type: this.rowType,
scope: options.scope,
}
return new TableCursor({
table: this,
tableParams: tableRowsParams,
return new TableCursor<RowType>({
abi: this.abi,
client: this.client,
maxRows,
params: tableRowsParams,
})

@@ -191,15 +215,16 @@ }

* Returns a cursor to get every single rows on the table.
* @returns {TableCursor<TableRow>}
* @returns {TableCursor}
*/
cursor(): TableCursor<TableRow> {
cursor(): TableCursor<RowType> {
const tableRowsParams = {
table: this.name,
code: this.contract.account,
code: this.account,
type: this.rowType,
limit: 1000000,
limit: this.defaultRowLimit,
}
return new TableCursor({
table: this,
tableParams: tableRowsParams,
return new TableCursor<RowType>({
abi: this.abi,
client: this.client,
params: tableRowsParams,
})

@@ -212,3 +237,3 @@ }

*/
async all(): Promise<TableRow[]> {
async all(): Promise<RowType[]> {
return this.cursor().all()

@@ -224,5 +249,5 @@ }

for (let i = 0; i < this.abi.key_names.length; i++) {
fieldToIndex[this.abi.key_names[i]] = {
type: this.abi.key_types[i],
for (let i = 0; i < this.tableABI.key_names.length; i++) {
fieldToIndex[this.tableABI.key_names[i]] = {
type: this.tableABI.key_types[i],
index_position: indexPositionInWords(i),

@@ -229,0 +254,0 @@ }

@@ -1,16 +0,8 @@

import {
ABI,
ABICache,
ABICacheInterface,
ABIDef,
APIClient,
Name,
NameType,
Session,
} from '@wharfkit/session'
import {ABI, ABIDef, APIClient, Name, NameType} from '@greymass/eosio'
import {ABICache} from '@wharfkit/abicache'
import type {ABICacheInterface} from '@wharfkit/abicache'
import {Contract} from './contract'
export interface ContractKitArgs {
client?: APIClient
session?: Session
client: APIClient
}

@@ -35,18 +27,11 @@

constructor(args: ContractKitArgs, options: ContractKitOptions = defaultContractKitOptions) {
// Use either the client given or get it from the session.
if (args.client) {
this.client = args.client
} else if (args.session) {
this.client = args.session.client
} else {
throw new Error(
'Either a `client` or `session` must be passed when initializing the ContractKit.'
)
throw new Error('A `client` must be passed when initializing the ContractKit.')
}
// Use either the specified cache, the cache from the session, or create one
// Use either the specified cache or create one
if (options.abiCache) {
this.abiCache = options.abiCache
} else if (args.session) {
this.abiCache = args.session.abiCache
} else {

@@ -53,0 +38,0 @@ this.abiCache = new ABICache(this.client)

@@ -10,3 +10,3 @@ import {

UInt64,
} from '@wharfkit/session'
} from '@greymass/eosio'

@@ -13,0 +13,0 @@ export function pascalCase(value: string): string {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc