modifying b1 lint config to use 4 spaces and semicolons for readability

This commit is contained in:
Cody Douglass
2019-02-12 11:38:07 -05:00
parent f5ca3dd330
commit ed56a35e51
17 changed files with 2412 additions and 2409 deletions
+29 -30
View File
@@ -1,67 +1,66 @@
// copyright defined in eosjs/LICENSE.txt
import { Abi, PushTransactionArgs } from './eosjs-rpc-interfaces'
import { Abi, PushTransactionArgs } from './eosjs-rpc-interfaces';
/** Arguments to `getRequiredKeys` */
export interface AuthorityProviderArgs {
/** Transaction that needs to be signed */
transaction: any
/** Transaction that needs to be signed */
transaction: any;
/** Public keys associated with the private keys that the `SignatureProvider` holds */
availableKeys: string[]
/** Public keys associated with the private keys that the `SignatureProvider` holds */
availableKeys: string[];
}
/** Get subset of `availableKeys` needed to meet authorities in `transaction` */
export interface AuthorityProvider {
/** Get subset of `availableKeys` needed to meet authorities in `transaction` */
getRequiredKeys: (args: AuthorityProviderArgs) => Promise<string[]>
/** Get subset of `availableKeys` needed to meet authorities in `transaction` */
getRequiredKeys: (args: AuthorityProviderArgs) => Promise<string[]>;
}
/** Retrieves raw ABIs for a specified accountName */
export interface AbiProvider {
/** Retrieve the BinaryAbi */
getRawAbi: (accountName: string) => Promise<BinaryAbi>
/** Retrieve the BinaryAbi */
getRawAbi: (accountName: string) => Promise<BinaryAbi>;
}
/** Structure for the raw form of ABIs */
export interface BinaryAbi {
/** account which has deployed the ABI */
accountName: string;
/** account which has deployed the ABI */
accountName: string
/** abi in binary form */
abi: Uint8Array
/** abi in binary form */
abi: Uint8Array;
}
/** Holds a fetched abi */
export interface CachedAbi {
/** abi in binary form */
rawAbi: Uint8Array
/** abi in binary form */
rawAbi: Uint8Array;
/** abi in structured form */
abi: Abi
/** abi in structured form */
abi: Abi;
}
/** Arguments to `sign` */
export interface SignatureProviderArgs {
/** Chain transaction is for */
chainId: string
/** Chain transaction is for */
chainId: string;
/** Public keys associated with the private keys needed to sign the transaction */
requiredKeys: string[]
/** Public keys associated with the private keys needed to sign the transaction */
requiredKeys: string[];
/** Transaction to sign */
serializedTransaction: Uint8Array
/** Transaction to sign */
serializedTransaction: Uint8Array;
/** ABIs for all contracts with actions included in `serializedTransaction` */
abis: BinaryAbi[]
/** ABIs for all contracts with actions included in `serializedTransaction` */
abis: BinaryAbi[];
}
/** Signs transactions */
export interface SignatureProvider {
/** Public keys associated with the private keys that the `SignatureProvider` holds */
getAvailableKeys: () => Promise<string[]>
/** Public keys associated with the private keys that the `SignatureProvider` holds */
getAvailableKeys: () => Promise<string[]>;
/** Sign a transaction */
sign: (args: SignatureProviderArgs) => Promise<PushTransactionArgs>
/** Sign a transaction */
sign: (args: SignatureProviderArgs) => Promise<PushTransactionArgs>;
}
+177 -177
View File
@@ -3,44 +3,44 @@
*/
// copyright defined in eosjs/LICENSE.txt
import { AbiProvider, AuthorityProvider, BinaryAbi, CachedAbi, SignatureProvider } from './eosjs-api-interfaces'
import { JsonRpc } from './eosjs-jsonrpc'
import { Abi, GetInfoResult, PushTransactionArgs } from './eosjs-rpc-interfaces'
import * as ser from './eosjs-serialize'
import { AbiProvider, AuthorityProvider, BinaryAbi, CachedAbi, SignatureProvider } from './eosjs-api-interfaces';
import { JsonRpc } from './eosjs-jsonrpc';
import { Abi, GetInfoResult, PushTransactionArgs } from './eosjs-rpc-interfaces';
import * as ser from './eosjs-serialize';
const abiAbi = require('../src/abi.abi.json')
const transactionAbi = require('../src/transaction.abi.json')
const abiAbi = require('../src/abi.abi.json');
const transactionAbi = require('../src/transaction.abi.json');
export class Api {
/** Issues RPC calls */
public rpc: JsonRpc
public rpc: JsonRpc;
/** Get subset of `availableKeys` needed to meet authorities in a `transaction` */
public authorityProvider: AuthorityProvider
public authorityProvider: AuthorityProvider;
/** Supplies ABIs in raw form (binary) */
public abiProvider: AbiProvider
public abiProvider: AbiProvider;
/** Signs transactions */
public signatureProvider: SignatureProvider
public signatureProvider: SignatureProvider;
/** Identifies chain */
public chainId: string
public chainId: string;
public textEncoder: TextEncoder
public textDecoder: TextDecoder
public textEncoder: TextEncoder;
public textDecoder: TextDecoder;
/** Converts abi files between binary and structured form (`abi.abi.json`) */
public abiTypes: Map<string, ser.Type>
public abiTypes: Map<string, ser.Type>;
/** Converts transactions between binary and structured form (`transaction.abi.json`) */
public transactionTypes: Map<string, ser.Type>
public transactionTypes: Map<string, ser.Type>;
/** Holds information needed to serialize contract actions */
public contracts = new Map<string, ser.Contract>()
public contracts = new Map<string, ser.Contract>();
/** Fetched abis */
public cachedAbis = new Map<string, CachedAbi>()
public cachedAbis = new Map<string, CachedAbi>();
/**
* @param args
@@ -52,153 +52,153 @@ export class Api {
* * `textEncoder`: `TextEncoder` instance to use. Pass in `null` if running in a browser
* * `textDecoder`: `TextDecoder` instance to use. Pass in `null` if running in a browser
*/
constructor(args: {
rpc: JsonRpc,
authorityProvider?: AuthorityProvider,
abiProvider?: AbiProvider,
signatureProvider: SignatureProvider,
chainId?: string,
textEncoder?: TextEncoder,
textDecoder?: TextDecoder,
}) {
this.rpc = args.rpc
this.authorityProvider = args.authorityProvider || args.rpc
this.abiProvider = args.abiProvider || args.rpc
this.signatureProvider = args.signatureProvider
this.chainId = args.chainId
this.textEncoder = args.textEncoder
this.textDecoder = args.textDecoder
constructor(args: {
rpc: JsonRpc,
authorityProvider?: AuthorityProvider,
abiProvider?: AbiProvider,
signatureProvider: SignatureProvider,
chainId?: string,
textEncoder?: TextEncoder,
textDecoder?: TextDecoder,
}) {
this.rpc = args.rpc;
this.authorityProvider = args.authorityProvider || args.rpc;
this.abiProvider = args.abiProvider || args.rpc;
this.signatureProvider = args.signatureProvider;
this.chainId = args.chainId;
this.textEncoder = args.textEncoder;
this.textDecoder = args.textDecoder;
this.abiTypes = ser.getTypesFromAbi(ser.createInitialTypes(), abiAbi)
this.transactionTypes = ser.getTypesFromAbi(ser.createInitialTypes(), transactionAbi)
}
this.abiTypes = ser.getTypesFromAbi(ser.createInitialTypes(), abiAbi);
this.transactionTypes = ser.getTypesFromAbi(ser.createInitialTypes(), transactionAbi);
}
/** Decodes an abi as Uint8Array into json. */
public rawAbiToJson(rawAbi: Uint8Array): Abi {
const buffer = new ser.SerialBuffer({
textEncoder: this.textEncoder,
textDecoder: this.textDecoder,
array: rawAbi,
})
if (!ser.supportedAbiVersion(buffer.getString())) {
throw new Error('Unsupported abi version')
public rawAbiToJson(rawAbi: Uint8Array): Abi {
const buffer = new ser.SerialBuffer({
textEncoder: this.textEncoder,
textDecoder: this.textDecoder,
array: rawAbi,
});
if (!ser.supportedAbiVersion(buffer.getString())) {
throw new Error('Unsupported abi version');
}
buffer.restartRead();
return this.abiTypes.get('abi_def').deserialize(buffer);
}
buffer.restartRead()
return this.abiTypes.get('abi_def').deserialize(buffer)
}
/** Get abi in both binary and structured forms. Fetch when needed. */
public async getCachedAbi(accountName: string, reload = false): Promise<CachedAbi> {
if (!reload && this.cachedAbis.get(accountName)) {
return this.cachedAbis.get(accountName)
public async getCachedAbi(accountName: string, reload = false): Promise<CachedAbi> {
if (!reload && this.cachedAbis.get(accountName)) {
return this.cachedAbis.get(accountName);
}
let cachedAbi: CachedAbi;
try {
const rawAbi = (await this.abiProvider.getRawAbi(accountName)).abi;
const abi = this.rawAbiToJson(rawAbi);
cachedAbi = { rawAbi, abi };
} catch (e) {
e.message = `fetching abi for ${accountName}: ${e.message}`;
throw e;
}
if (!cachedAbi) {
throw new Error(`Missing abi for ${accountName}`);
}
this.cachedAbis.set(accountName, cachedAbi);
return cachedAbi;
}
let cachedAbi: CachedAbi
try {
const rawAbi = (await this.abiProvider.getRawAbi(accountName)).abi
const abi = this.rawAbiToJson(rawAbi)
cachedAbi = { rawAbi, abi }
} catch (e) {
e.message = `fetching abi for ${accountName}: ${e.message}`
throw e
}
if (!cachedAbi) {
throw new Error(`Missing abi for ${accountName}`)
}
this.cachedAbis.set(accountName, cachedAbi)
return cachedAbi
}
/** Get abi in structured form. Fetch when needed. */
public async getAbi(accountName: string, reload = false): Promise<Abi> {
return (await this.getCachedAbi(accountName, reload)).abi
}
public async getAbi(accountName: string, reload = false): Promise<Abi> {
return (await this.getCachedAbi(accountName, reload)).abi;
}
/** Get abis needed by a transaction */
public async getTransactionAbis(transaction: any, reload = false): Promise<BinaryAbi[]> {
const accounts: string[] = transaction.actions.map((action: ser.Action): string => action.account)
const uniqueAccounts: Set<string> = new Set(accounts)
const actionPromises: Array<Promise<BinaryAbi>> = [...uniqueAccounts].map(
public async getTransactionAbis(transaction: any, reload = false): Promise<BinaryAbi[]> {
const accounts: string[] = transaction.actions.map((action: ser.Action): string => action.account);
const uniqueAccounts: Set<string> = new Set(accounts);
const actionPromises: Array<Promise<BinaryAbi>> = [...uniqueAccounts].map(
async (account: string): Promise<BinaryAbi> => ({
accountName: account, abi: (await this.getCachedAbi(account, reload)).rawAbi,
}))
return Promise.all(actionPromises)
}
accountName: account, abi: (await this.getCachedAbi(account, reload)).rawAbi,
}));
return Promise.all(actionPromises);
}
/** Get data needed to serialize actions in a contract */
public async getContract(accountName: string, reload = false): Promise<ser.Contract> {
if (!reload && this.contracts.get(accountName)) {
return this.contracts.get(accountName)
public async getContract(accountName: string, reload = false): Promise<ser.Contract> {
if (!reload && this.contracts.get(accountName)) {
return this.contracts.get(accountName);
}
const abi = await this.getAbi(accountName, reload);
const types = ser.getTypesFromAbi(ser.createInitialTypes(), abi);
const actions = new Map<string, ser.Type>();
for (const { name, type } of abi.actions) {
actions.set(name, ser.getType(types, type));
}
const result = { types, actions };
this.contracts.set(accountName, result);
return result;
}
const abi = await this.getAbi(accountName, reload)
const types = ser.getTypesFromAbi(ser.createInitialTypes(), abi)
const actions = new Map<string, ser.Type>()
for (const { name, type } of abi.actions) {
actions.set(name, ser.getType(types, type))
}
const result = { types, actions }
this.contracts.set(accountName, result)
return result
}
/** Convert `value` to binary form. `type` must be a built-in abi type or in `transaction.abi.json`. */
public serialize(buffer: ser.SerialBuffer, type: string, value: any): void {
this.transactionTypes.get(type).serialize(buffer, value)
}
public serialize(buffer: ser.SerialBuffer, type: string, value: any): void {
this.transactionTypes.get(type).serialize(buffer, value);
}
/** Convert data in `buffer` to structured form. `type` must be a built-in abi type or in `transaction.abi.json`. */
public deserialize(buffer: ser.SerialBuffer, type: string): any {
return this.transactionTypes.get(type).deserialize(buffer)
}
public deserialize(buffer: ser.SerialBuffer, type: string): any {
return this.transactionTypes.get(type).deserialize(buffer);
}
/** Convert a transaction to binary */
public serializeTransaction(transaction: any): Uint8Array {
const buffer = new ser.SerialBuffer({ textEncoder: this.textEncoder, textDecoder: this.textDecoder })
this.serialize(buffer, 'transaction', {
max_net_usage_words: 0,
max_cpu_usage_ms: 0,
delay_sec: 0,
context_free_actions: [],
actions: [],
transaction_extensions: [],
...transaction,
})
return buffer.asUint8Array()
}
public serializeTransaction(transaction: any): Uint8Array {
const buffer = new ser.SerialBuffer({ textEncoder: this.textEncoder, textDecoder: this.textDecoder });
this.serialize(buffer, 'transaction', {
max_net_usage_words: 0,
max_cpu_usage_ms: 0,
delay_sec: 0,
context_free_actions: [],
actions: [],
transaction_extensions: [],
...transaction,
});
return buffer.asUint8Array();
}
/** Convert a transaction from binary. Leaves actions in hex. */
public deserializeTransaction(transaction: Uint8Array): any {
const buffer = new ser.SerialBuffer({ textEncoder: this.textEncoder, textDecoder: this.textDecoder })
buffer.pushArray(transaction)
return this.deserialize(buffer, 'transaction')
}
public deserializeTransaction(transaction: Uint8Array): any {
const buffer = new ser.SerialBuffer({ textEncoder: this.textEncoder, textDecoder: this.textDecoder });
buffer.pushArray(transaction);
return this.deserialize(buffer, 'transaction');
}
/** Convert actions to hex */
public async serializeActions(actions: ser.Action[]): Promise<ser.SerializedAction[]> {
return await Promise.all(actions.map(async ({ account, name, authorization, data }) => {
const contract = await this.getContract(account)
return ser.serializeAction(
contract, account, name, authorization, data, this.textEncoder, this.textDecoder)
}))
}
public async serializeActions(actions: ser.Action[]): Promise<ser.SerializedAction[]> {
return await Promise.all(actions.map(async ({ account, name, authorization, data }) => {
const contract = await this.getContract(account);
return ser.serializeAction(
contract, account, name, authorization, data, this.textEncoder, this.textDecoder);
}));
}
/** Convert actions from hex */
public async deserializeActions(actions: ser.Action[]): Promise<ser.Action[]> {
return await Promise.all(actions.map(async ({ account, name, authorization, data }) => {
const contract = await this.getContract(account)
return ser.deserializeAction(
contract, account, name, authorization, data, this.textEncoder, this.textDecoder)
}))
}
public async deserializeActions(actions: ser.Action[]): Promise<ser.Action[]> {
return await Promise.all(actions.map(async ({ account, name, authorization, data }) => {
const contract = await this.getContract(account);
return ser.deserializeAction(
contract, account, name, authorization, data, this.textEncoder, this.textDecoder);
}));
}
/** Convert a transaction from binary. Also deserializes actions. */
public async deserializeTransactionWithActions(transaction: Uint8Array | string): Promise<any> {
if (typeof transaction === 'string') {
transaction = ser.hexToUint8Array(transaction)
public async deserializeTransactionWithActions(transaction: Uint8Array | string): Promise<any> {
if (typeof transaction === 'string') {
transaction = ser.hexToUint8Array(transaction);
}
const deserializedTransaction = this.deserializeTransaction(transaction);
const deserializedActions = await this.deserializeActions(deserializedTransaction.actions);
return { ...deserializedTransaction, actions: deserializedActions };
}
const deserializedTransaction = this.deserializeTransaction(transaction)
const deserializedActions = await this.deserializeActions(deserializedTransaction.actions)
return { ...deserializedTransaction, actions: deserializedActions }
}
/**
* Create and optionally broadcast a transaction.
@@ -211,59 +211,59 @@ export class Api {
* use it as a reference for TAPoS, and expire the transaction `expireSeconds` after that block's time.
* @returns node response if `broadcast`, `{signatures, serializedTransaction}` if `!broadcast`
*/
public async transact(transaction: any, { broadcast = true, sign = true, blocksBehind, expireSeconds }:
public async transact(transaction: any, { broadcast = true, sign = true, blocksBehind, expireSeconds }:
{ broadcast?: boolean; sign?: boolean; blocksBehind?: number; expireSeconds?: number; } = {}): Promise<any> {
let info: GetInfoResult
let info: GetInfoResult;
if (!this.chainId) {
info = await this.rpc.get_info()
this.chainId = info.chain_id
}
if (!this.chainId) {
info = await this.rpc.get_info();
this.chainId = info.chain_id;
}
if (typeof blocksBehind === 'number' && expireSeconds) { // use config fields to generate TAPOS if they exist
if (!info) {
info = await this.rpc.get_info()
}
const refBlock = await this.rpc.get_block(info.head_block_num - blocksBehind)
transaction = { ...ser.transactionHeader(refBlock, expireSeconds), ...transaction }
}
if (typeof blocksBehind === 'number' && expireSeconds) { // use config fields to generate TAPOS if they exist
if (!info) {
info = await this.rpc.get_info();
}
const refBlock = await this.rpc.get_block(info.head_block_num - blocksBehind);
transaction = { ...ser.transactionHeader(refBlock, expireSeconds), ...transaction };
}
if (!this.hasRequiredTaposFields(transaction)) {
throw new Error('Required configuration or TAPOS fields are not present')
}
if (!this.hasRequiredTaposFields(transaction)) {
throw new Error('Required configuration or TAPOS fields are not present');
}
const abis: BinaryAbi[] = await this.getTransactionAbis(transaction)
transaction = { ...transaction, actions: await this.serializeActions(transaction.actions) }
const serializedTransaction = this.serializeTransaction(transaction)
let pushTransactionArgs: PushTransactionArgs = { serializedTransaction, signatures: [] }
const abis: BinaryAbi[] = await this.getTransactionAbis(transaction);
transaction = { ...transaction, actions: await this.serializeActions(transaction.actions) };
const serializedTransaction = this.serializeTransaction(transaction);
let pushTransactionArgs: PushTransactionArgs = { serializedTransaction, signatures: [] };
if (sign) {
const availableKeys = await this.signatureProvider.getAvailableKeys()
const requiredKeys = await this.authorityProvider.getRequiredKeys({ transaction, availableKeys })
pushTransactionArgs = await this.signatureProvider.sign({
chainId: this.chainId,
requiredKeys,
serializedTransaction,
abis,
})
if (sign) {
const availableKeys = await this.signatureProvider.getAvailableKeys();
const requiredKeys = await this.authorityProvider.getRequiredKeys({ transaction, availableKeys });
pushTransactionArgs = await this.signatureProvider.sign({
chainId: this.chainId,
requiredKeys,
serializedTransaction,
abis,
});
}
if (broadcast) {
return this.pushSignedTransaction(pushTransactionArgs);
}
return pushTransactionArgs;
}
if (broadcast) {
return this.pushSignedTransaction(pushTransactionArgs)
}
return pushTransactionArgs
}
/** Broadcast a signed transaction */
public async pushSignedTransaction({ signatures, serializedTransaction }: PushTransactionArgs): Promise<any> {
return this.rpc.push_transaction({
signatures,
serializedTransaction,
})
}
public async pushSignedTransaction({ signatures, serializedTransaction }: PushTransactionArgs): Promise<any> {
return this.rpc.push_transaction({
signatures,
serializedTransaction,
});
}
// eventually break out into TransactionValidator class
private hasRequiredTaposFields({ expiration, ref_block_num, ref_block_prefix, ...transaction }: any): boolean {
return !!(expiration && ref_block_num && ref_block_prefix)
}
private hasRequiredTaposFields({ expiration, ref_block_num, ref_block_prefix, ...transaction }: any): boolean {
return !!(expiration && ref_block_num && ref_block_prefix);
}
} // Api
+1 -1
View File
@@ -1 +1 @@
declare module "eosjs-ecc"
declare module "eosjs-ecc";
+145 -145
View File
@@ -3,130 +3,130 @@
*/
// copyright defined in eosjs/LICENSE.txt
import { AbiProvider, AuthorityProvider, AuthorityProviderArgs, BinaryAbi } from './eosjs-api-interfaces'
import { base64ToBinary, convertLegacyPublicKeys } from './eosjs-numeric'
import { AbiProvider, AuthorityProvider, AuthorityProviderArgs, BinaryAbi } from './eosjs-api-interfaces';
import { base64ToBinary, convertLegacyPublicKeys } from './eosjs-numeric';
import { GetAbiResult, GetBlockResult, GetCodeResult, GetInfoResult, GetRawCodeAndAbiResult, PushTransactionArgs } from "./eosjs-rpc-interfaces" // tslint:disable-line
import { RpcError } from './eosjs-rpcerror'
import { RpcError } from './eosjs-rpcerror';
function arrayToHex(data: Uint8Array) {
let result = ''
for (const x of data) {
result += ('00' + x.toString(16)).slice(-2)
}
return result
let result = '';
for (const x of data) {
result += ('00' + x.toString(16)).slice(-2);
}
return result;
}
/** Make RPC calls */
export class JsonRpc implements AuthorityProvider, AbiProvider {
public endpoint: string
public fetchBuiltin: (input?: Request | string, init?: RequestInit) => Promise<Response>
public endpoint: string;
public fetchBuiltin: (input?: Request | string, init?: RequestInit) => Promise<Response>;
/**
* @param args
* * `fetch`:
* * browsers: leave `null` or `undefined`
* * node: provide an implementation
*/
constructor(endpoint: string, args:
/**
* @param args
* * `fetch`:
* * browsers: leave `null` or `undefined`
* * node: provide an implementation
*/
constructor(endpoint: string, args:
{ fetch?: (input?: string | Request, init?: RequestInit) => Promise<Response> } = {},
) {
this.endpoint = endpoint
if (args.fetch) {
this.fetchBuiltin = args.fetch
} else {
this.fetchBuiltin = (global as any).fetch
this.endpoint = endpoint;
if (args.fetch) {
this.fetchBuiltin = args.fetch;
} else {
this.fetchBuiltin = (global as any).fetch;
}
}
}
/** Post `body` to `endpoint + path`. Throws detailed error information in `RpcError` when available. */
public async fetch(path: string, body: any) {
let response
let json
try {
const f = this.fetchBuiltin
response = await f(this.endpoint + path, {
body: JSON.stringify(body),
method: 'POST',
})
json = await response.json()
if (json.processed && json.processed.except) {
throw new RpcError(json)
}
} catch (e) {
e.isFetchError = true
throw e
/** Post `body` to `endpoint + path`. Throws detailed error information in `RpcError` when available. */
public async fetch(path: string, body: any) {
let response;
let json;
try {
const f = this.fetchBuiltin;
response = await f(this.endpoint + path, {
body: JSON.stringify(body),
method: 'POST',
});
json = await response.json();
if (json.processed && json.processed.except) {
throw new RpcError(json);
}
} catch (e) {
e.isFetchError = true;
throw e;
}
if (!response.ok) {
throw new RpcError(json);
}
return json;
}
if (!response.ok) {
throw new RpcError(json)
/** Raw call to `/v1/chain/get_abi` */
public async get_abi(accountName: string): Promise<GetAbiResult> {
return await this.fetch('/v1/chain/get_abi', { account_name: accountName });
}
return json
}
/** Raw call to `/v1/chain/get_abi` */
public async get_abi(accountName: string): Promise<GetAbiResult> {
return await this.fetch('/v1/chain/get_abi', { account_name: accountName })
}
/** Raw call to `/v1/chain/get_account` */
public async get_account(accountName: string): Promise<any> {
return await this.fetch('/v1/chain/get_account', { account_name: accountName });
}
/** Raw call to `/v1/chain/get_account` */
public async get_account(accountName: string): Promise<any> {
return await this.fetch('/v1/chain/get_account', { account_name: accountName })
}
/** Raw call to `/v1/chain/get_block_header_state` */
public async get_block_header_state(blockNumOrId: number | string): Promise<any> {
return await this.fetch('/v1/chain/get_block_header_state', { block_num_or_id: blockNumOrId });
}
/** Raw call to `/v1/chain/get_block_header_state` */
public async get_block_header_state(blockNumOrId: number | string): Promise<any> {
return await this.fetch('/v1/chain/get_block_header_state', { block_num_or_id: blockNumOrId })
}
/** Raw call to `/v1/chain/get_block` */
public async get_block(blockNumOrId: number | string): Promise<GetBlockResult> {
return await this.fetch('/v1/chain/get_block', { block_num_or_id: blockNumOrId });
}
/** Raw call to `/v1/chain/get_block` */
public async get_block(blockNumOrId: number | string): Promise<GetBlockResult> {
return await this.fetch('/v1/chain/get_block', { block_num_or_id: blockNumOrId })
}
/** Raw call to `/v1/chain/get_code` */
public async get_code(accountName: string): Promise<GetCodeResult> {
return await this.fetch('/v1/chain/get_code', { account_name: accountName });
}
/** Raw call to `/v1/chain/get_code` */
public async get_code(accountName: string): Promise<GetCodeResult> {
return await this.fetch('/v1/chain/get_code', { account_name: accountName })
}
/** Raw call to `/v1/chain/get_currency_balance` */
public async get_currency_balance(code: string, account: string, symbol: string = null): Promise<any> {
return await this.fetch('/v1/chain/get_currency_balance', { code, account, symbol });
}
/** Raw call to `/v1/chain/get_currency_balance` */
public async get_currency_balance(code: string, account: string, symbol: string = null): Promise<any> {
return await this.fetch('/v1/chain/get_currency_balance', { code, account, symbol })
}
/** Raw call to `/v1/chain/get_currency_stats` */
public async get_currency_stats(code: string, symbol: string): Promise<any> {
return await this.fetch('/v1/chain/get_currency_stats', { code, symbol });
}
/** Raw call to `/v1/chain/get_currency_stats` */
public async get_currency_stats(code: string, symbol: string): Promise<any> {
return await this.fetch('/v1/chain/get_currency_stats', { code, symbol })
}
/** Raw call to `/v1/chain/get_info` */
public async get_info(): Promise<GetInfoResult> {
return await this.fetch('/v1/chain/get_info', {});
}
/** Raw call to `/v1/chain/get_info` */
public async get_info(): Promise<GetInfoResult> {
return await this.fetch('/v1/chain/get_info', {})
}
/** Raw call to `/v1/chain/get_producer_schedule` */
public async get_producer_schedule(): Promise<any> {
return await this.fetch('/v1/chain/get_producer_schedule', {});
}
/** Raw call to `/v1/chain/get_producer_schedule` */
public async get_producer_schedule(): Promise<any> {
return await this.fetch('/v1/chain/get_producer_schedule', {})
}
/** Raw call to `/v1/chain/get_producers` */
public async get_producers(json = true, lowerBound = '', limit = 50): Promise<any> {
return await this.fetch('/v1/chain/get_producers', { json, lower_bound: lowerBound, limit });
}
/** Raw call to `/v1/chain/get_producers` */
public async get_producers(json = true, lowerBound = '', limit = 50): Promise<any> {
return await this.fetch('/v1/chain/get_producers', { json, lower_bound: lowerBound, limit })
}
/** Raw call to `/v1/chain/get_raw_code_and_abi` */
public async get_raw_code_and_abi(accountName: string): Promise<GetRawCodeAndAbiResult> {
return await this.fetch('/v1/chain/get_raw_code_and_abi', { account_name: accountName });
}
/** Raw call to `/v1/chain/get_raw_code_and_abi` */
public async get_raw_code_and_abi(accountName: string): Promise<GetRawCodeAndAbiResult> {
return await this.fetch('/v1/chain/get_raw_code_and_abi', { account_name: accountName })
}
/** calls `/v1/chain/get_raw_code_and_abi` and pulls out unneeded raw wasm code */
// TODO: use `/v1/chain/get_raw_abi` directly when it becomes available
public async getRawAbi(accountName: string): Promise<BinaryAbi> {
const rawCodeAndAbi = await this.get_raw_code_and_abi(accountName);
const abi = base64ToBinary(rawCodeAndAbi.abi);
return { accountName: rawCodeAndAbi.account_name, abi };
}
/** calls `/v1/chain/get_raw_code_and_abi` and pulls out unneeded raw wasm code */
// TODO: use `/v1/chain/get_raw_abi` directly when it becomes available
public async getRawAbi(accountName: string): Promise<BinaryAbi> {
const rawCodeAndAbi = await this.get_raw_code_and_abi(accountName)
const abi = base64ToBinary(rawCodeAndAbi.abi)
return { accountName: rawCodeAndAbi.account_name, abi }
}
/** Raw call to `/v1/chain/get_table_rows` */
public async get_table_rows({
/** Raw call to `/v1/chain/get_table_rows` */
public async get_table_rows({
json = true,
code,
scope,
@@ -138,59 +138,59 @@ export class JsonRpc implements AuthorityProvider, AbiProvider {
key_type = '',
limit = 10,
}: any): Promise<any> {
return await this.fetch(
return await this.fetch(
'/v1/chain/get_table_rows', {
json,
code,
scope,
table,
table_key,
lower_bound,
upper_bound,
index_position,
key_type,
limit,
})
}
json,
code,
scope,
table,
table_key,
lower_bound,
upper_bound,
index_position,
key_type,
limit,
});
}
/** Get subset of `availableKeys` needed to meet authorities in `transaction`. Implements `AuthorityProvider` */
public async getRequiredKeys(args: AuthorityProviderArgs): Promise<string[]> {
return convertLegacyPublicKeys((await this.fetch('/v1/chain/get_required_keys', {
transaction: args.transaction,
available_keys: args.availableKeys,
})).required_keys)
}
/** Get subset of `availableKeys` needed to meet authorities in `transaction`. Implements `AuthorityProvider` */
public async getRequiredKeys(args: AuthorityProviderArgs): Promise<string[]> {
return convertLegacyPublicKeys((await this.fetch('/v1/chain/get_required_keys', {
transaction: args.transaction,
available_keys: args.availableKeys,
})).required_keys);
}
/** Push a serialized transaction */
public async push_transaction({ signatures, serializedTransaction }: PushTransactionArgs): Promise<any> {
return await this.fetch('/v1/chain/push_transaction', {
signatures,
compression: 0,
packed_context_free_data: '',
packed_trx: arrayToHex(serializedTransaction),
})
}
/** Push a serialized transaction */
public async push_transaction({ signatures, serializedTransaction }: PushTransactionArgs): Promise<any> {
return await this.fetch('/v1/chain/push_transaction', {
signatures,
compression: 0,
packed_context_free_data: '',
packed_trx: arrayToHex(serializedTransaction),
});
}
/** Raw call to `/v1/db_size/get` */
public async db_size_get() { return await this.fetch('/v1/db_size/get', {}) }
/** Raw call to `/v1/db_size/get` */
public async db_size_get() { return await this.fetch('/v1/db_size/get', {}); }
/** Raw call to `/v1/history/get_actions` */
public async history_get_actions(accountName: string, pos: number = null, offset: number = null) {
return await this.fetch('/v1/history/get_actions', { account_name: accountName, pos, offset })
}
/** Raw call to `/v1/history/get_actions` */
public async history_get_actions(accountName: string, pos: number = null, offset: number = null) {
return await this.fetch('/v1/history/get_actions', { account_name: accountName, pos, offset });
}
/** Raw call to `/v1/history/get_transaction` */
public async history_get_transaction(id: string, blockNumHint: number = null) {
return await this.fetch('/v1/history/get_transaction', { id, block_num_hint: blockNumHint })
}
/** Raw call to `/v1/history/get_transaction` */
public async history_get_transaction(id: string, blockNumHint: number = null) {
return await this.fetch('/v1/history/get_transaction', { id, block_num_hint: blockNumHint });
}
/** Raw call to `/v1/history/get_key_accounts` */
public async history_get_key_accounts(publicKey: string) {
return await this.fetch('/v1/history/get_key_accounts', { public_key: publicKey })
}
/** Raw call to `/v1/history/get_key_accounts` */
public async history_get_key_accounts(publicKey: string) {
return await this.fetch('/v1/history/get_key_accounts', { public_key: publicKey });
}
/** Raw call to `/v1/history/get_controlled_accounts` */
public async history_get_controlled_accounts(controllingAccount: string) {
return await this.fetch('/v1/history/get_controlled_accounts', { controlling_account: controllingAccount })
}
/** Raw call to `/v1/history/get_controlled_accounts` */
public async history_get_controlled_accounts(controllingAccount: string) {
return await this.fetch('/v1/history/get_controlled_accounts', { controlling_account: controllingAccount });
}
} // JsonRpc
+22 -22
View File
@@ -3,40 +3,40 @@
*/
// copyright defined in eosjs/LICENSE.txt
import * as ecc from 'eosjs-ecc'
import { SignatureProvider, SignatureProviderArgs } from './eosjs-api-interfaces'
import { convertLegacyPublicKey } from './eosjs-numeric'
import * as ecc from 'eosjs-ecc';
import { SignatureProvider, SignatureProviderArgs } from './eosjs-api-interfaces';
import { convertLegacyPublicKey } from './eosjs-numeric';
/** Signs transactions using in-process private keys */
export class JsSignatureProvider implements SignatureProvider {
/** map public to private keys */
public keys = new Map<string, string>()
public keys = new Map<string, string>();
/** public keys */
public availableKeys = [] as string[]
public availableKeys = [] as string[];
/** @param privateKeys private keys to sign with */
constructor(privateKeys: string[]) {
for (const k of privateKeys) {
const pub = convertLegacyPublicKey(ecc.PrivateKey.fromString(k).toPublic().toString())
this.keys.set(pub, k)
this.availableKeys.push(pub)
constructor(privateKeys: string[]) {
for (const k of privateKeys) {
const pub = convertLegacyPublicKey(ecc.PrivateKey.fromString(k).toPublic().toString());
this.keys.set(pub, k);
this.availableKeys.push(pub);
}
}
}
/** Public keys associated with the private keys that the `SignatureProvider` holds */
public async getAvailableKeys() {
return this.availableKeys
}
public async getAvailableKeys() {
return this.availableKeys;
}
/** Sign a transaction */
public async sign({ chainId, requiredKeys, serializedTransaction }: SignatureProviderArgs) {
const signBuf = Buffer.concat([
new Buffer(chainId, 'hex'), new Buffer(serializedTransaction), new Buffer(new Uint8Array(32)),
])
const signatures = requiredKeys.map(
public async sign({ chainId, requiredKeys, serializedTransaction }: SignatureProviderArgs) {
const signBuf = Buffer.concat([
new Buffer(chainId, 'hex'), new Buffer(serializedTransaction), new Buffer(new Uint8Array(32)),
]);
const signatures = requiredKeys.map(
(pub) => ecc.Signature.sign(signBuf, this.keys.get(convertLegacyPublicKey(pub))).toString(),
)
return { signatures, serializedTransaction }
}
);
return { signatures, serializedTransaction };
}
}
+227 -227
View File
@@ -3,45 +3,45 @@
*/
// copyright defined in eosjs/LICENSE.txt
const ripemd160 = require('./ripemd').RIPEMD160.hash as (a: Uint8Array) => ArrayBuffer
const ripemd160 = require('./ripemd').RIPEMD160.hash as (a: Uint8Array) => ArrayBuffer;
const base58Chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
const base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
const base58Chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
const base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
function create_base58_map() {
const base58M = Array(256).fill(-1) as number[]
for (let i = 0; i < base58Chars.length; ++i) {
base58M[base58Chars.charCodeAt(i)] = i
}
return base58M
const base58M = Array(256).fill(-1) as number[];
for (let i = 0; i < base58Chars.length; ++i) {
base58M[base58Chars.charCodeAt(i)] = i;
}
return base58M;
}
const base58Map = create_base58_map()
const base58Map = create_base58_map();
function create_base64_map() {
const base64M = Array(256).fill(-1) as number[]
for (let i = 0; i < base64Chars.length; ++i) {
base64M[base64Chars.charCodeAt(i)] = i
}
base64M['='.charCodeAt(0)] = 0
return base64M
const base64M = Array(256).fill(-1) as number[];
for (let i = 0; i < base64Chars.length; ++i) {
base64M[base64Chars.charCodeAt(i)] = i;
}
base64M['='.charCodeAt(0)] = 0;
return base64M;
}
const base64Map = create_base64_map()
const base64Map = create_base64_map();
/** Is `bignum` a negative number? */
export function isNegative(bignum: Uint8Array) {
return (bignum[bignum.length - 1] & 0x80) !== 0
return (bignum[bignum.length - 1] & 0x80) !== 0;
}
/** Negate `bignum` */
export function negate(bignum: Uint8Array) {
let carry = 1
for (let i = 0; i < bignum.length; ++i) {
const x = (~bignum[i] & 0xff) + carry
bignum[i] = x
carry = x >> 8
}
let carry = 1;
for (let i = 0; i < bignum.length; ++i) {
const x = (~bignum[i] & 0xff) + carry;
bignum[i] = x;
carry = x >> 8;
}
}
/**
@@ -49,23 +49,23 @@ export function negate(bignum: Uint8Array) {
* @param size bignum size (bytes)
*/
export function decimalToBinary(size: number, s: string) {
const result = new Uint8Array(size)
for (let i = 0; i < s.length; ++i) {
const srcDigit = s.charCodeAt(i)
if (srcDigit < '0'.charCodeAt(0) || srcDigit > '9'.charCodeAt(0)) {
throw new Error('invalid number')
const result = new Uint8Array(size);
for (let i = 0; i < s.length; ++i) {
const srcDigit = s.charCodeAt(i);
if (srcDigit < '0'.charCodeAt(0) || srcDigit > '9'.charCodeAt(0)) {
throw new Error('invalid number');
}
let carry = srcDigit - '0'.charCodeAt(0);
for (let j = 0; j < size; ++j) {
const x = result[j] * 10 + carry;
result[j] = x;
carry = x >> 8;
}
if (carry) {
throw new Error('number is out of range');
}
}
let carry = srcDigit - '0'.charCodeAt(0)
for (let j = 0; j < size; ++j) {
const x = result[j] * 10 + carry
result[j] = x
carry = x >> 8
}
if (carry) {
throw new Error('number is out of range')
}
}
return result
return result;
}
/**
@@ -73,20 +73,20 @@ export function decimalToBinary(size: number, s: string) {
* @param size bignum size (bytes)
*/
export function signedDecimalToBinary(size: number, s: string) {
const negative = s[0] === '-'
if (negative) {
s = s.substr(1)
}
const result = decimalToBinary(size, s)
if (negative) {
negate(result)
if (!isNegative(result)) {
throw new Error('number is out of range')
const negative = s[0] === '-';
if (negative) {
s = s.substr(1);
}
} else if (isNegative(result)) {
throw new Error('number is out of range')
}
return result
const result = decimalToBinary(size, s);
if (negative) {
negate(result);
if (!isNegative(result)) {
throw new Error('number is out of range');
}
} else if (isNegative(result)) {
throw new Error('number is out of range');
}
return result;
}
/**
@@ -94,21 +94,21 @@ export function signedDecimalToBinary(size: number, s: string) {
* @param minDigits 0-pad result to this many digits
*/
export function binaryToDecimal(bignum: Uint8Array, minDigits = 1) {
const result = Array(minDigits).fill('0'.charCodeAt(0)) as number[]
for (let i = bignum.length - 1; i >= 0; --i) {
let carry = bignum[i]
for (let j = 0; j < result.length; ++j) {
const x = ((result[j] - '0'.charCodeAt(0)) << 8) + carry
result[j] = '0'.charCodeAt(0) + x % 10
carry = (x / 10) | 0
const result = Array(minDigits).fill('0'.charCodeAt(0)) as number[];
for (let i = bignum.length - 1; i >= 0; --i) {
let carry = bignum[i];
for (let j = 0; j < result.length; ++j) {
const x = ((result[j] - '0'.charCodeAt(0)) << 8) + carry;
result[j] = '0'.charCodeAt(0) + x % 10;
carry = (x / 10) | 0;
}
while (carry) {
result.push('0'.charCodeAt(0) + carry % 10);
carry = (carry / 10) | 0;
}
}
while (carry) {
result.push('0'.charCodeAt(0) + carry % 10)
carry = (carry / 10) | 0
}
}
result.reverse()
return String.fromCharCode(...result)
result.reverse();
return String.fromCharCode(...result);
}
/**
@@ -116,12 +116,12 @@ export function binaryToDecimal(bignum: Uint8Array, minDigits = 1) {
* @param minDigits 0-pad result to this many digits
*/
export function signedBinaryToDecimal(bignum: Uint8Array, minDigits = 1) {
if (isNegative(bignum)) {
const x = bignum.slice()
negate(x)
return '-' + binaryToDecimal(x, minDigits)
}
return binaryToDecimal(bignum, minDigits)
if (isNegative(bignum)) {
const x = bignum.slice();
negate(x);
return '-' + binaryToDecimal(x, minDigits);
}
return binaryToDecimal(bignum, minDigits);
}
/**
@@ -129,23 +129,23 @@ export function signedBinaryToDecimal(bignum: Uint8Array, minDigits = 1) {
* @param size bignum size (bytes)
*/
export function base58ToBinary(size: number, s: string) {
const result = new Uint8Array(size)
for (let i = 0; i < s.length; ++i) {
let carry = base58Map[s.charCodeAt(i)]
if (carry < 0) {
throw new Error('invalid base-58 value')
const result = new Uint8Array(size);
for (let i = 0; i < s.length; ++i) {
let carry = base58Map[s.charCodeAt(i)];
if (carry < 0) {
throw new Error('invalid base-58 value');
}
for (let j = 0; j < size; ++j) {
const x = result[j] * 58 + carry;
result[j] = x;
carry = x >> 8;
}
if (carry) {
throw new Error('base-58 value is out of range');
}
}
for (let j = 0; j < size; ++j) {
const x = result[j] * 58 + carry
result[j] = x
carry = x >> 8
}
if (carry) {
throw new Error('base-58 value is out of range')
}
}
result.reverse()
return result
result.reverse();
return result;
}
/**
@@ -153,64 +153,64 @@ export function base58ToBinary(size: number, s: string) {
* @param minDigits 0-pad result to this many digits
*/
export function binaryToBase58(bignum: Uint8Array, minDigits = 1) {
const result = [] as number[]
for (const byte of bignum) {
let carry = byte
for (let j = 0; j < result.length; ++j) {
const x = (base58Map[result[j]] << 8) + carry
result[j] = base58Chars.charCodeAt(x % 58)
carry = (x / 58) | 0
const result = [] as number[];
for (const byte of bignum) {
let carry = byte;
for (let j = 0; j < result.length; ++j) {
const x = (base58Map[result[j]] << 8) + carry;
result[j] = base58Chars.charCodeAt(x % 58);
carry = (x / 58) | 0;
}
while (carry) {
result.push(base58Chars.charCodeAt(carry % 58));
carry = (carry / 58) | 0;
}
}
while (carry) {
result.push(base58Chars.charCodeAt(carry % 58))
carry = (carry / 58) | 0
for (const byte of bignum) {
if (byte) {
break;
} else {
result.push('1'.charCodeAt(0));
}
}
}
for (const byte of bignum) {
if (byte) {
break
} else {
result.push('1'.charCodeAt(0))
}
}
result.reverse()
return String.fromCharCode(...result)
result.reverse();
return String.fromCharCode(...result);
}
/** Convert an unsigned base-64 number in `s` to a bignum */
export function base64ToBinary(s: string) {
let len = s.length
if ((len & 3) === 1 && s[len - 1] === '=') {
len -= 1
} // fc appends an extra '='
if ((len & 3) !== 0) {
throw new Error('base-64 value is not padded correctly')
}
const groups = len >> 2
let bytes = groups * 3
if (len > 0 && s[len - 1] === '=') {
if (s[len - 2] === '=') {
bytes -= 2
} else {
bytes -= 1
let len = s.length;
if ((len & 3) === 1 && s[len - 1] === '=') {
len -= 1;
} // fc appends an extra '='
if ((len & 3) !== 0) {
throw new Error('base-64 value is not padded correctly');
}
}
const result = new Uint8Array(bytes)
const groups = len >> 2;
let bytes = groups * 3;
if (len > 0 && s[len - 1] === '=') {
if (s[len - 2] === '=') {
bytes -= 2;
} else {
bytes -= 1;
}
}
const result = new Uint8Array(bytes);
for (let group = 0; group < groups; ++group) {
const digit0 = base64Map[s.charCodeAt(group * 4 + 0)]
const digit1 = base64Map[s.charCodeAt(group * 4 + 1)]
const digit2 = base64Map[s.charCodeAt(group * 4 + 2)]
const digit3 = base64Map[s.charCodeAt(group * 4 + 3)]
result[group * 3 + 0] = (digit0 << 2) | (digit1 >> 4)
if (group * 3 + 1 < bytes) {
result[group * 3 + 1] = ((digit1 & 15) << 4) | (digit2 >> 2)
for (let group = 0; group < groups; ++group) {
const digit0 = base64Map[s.charCodeAt(group * 4 + 0)];
const digit1 = base64Map[s.charCodeAt(group * 4 + 1)];
const digit2 = base64Map[s.charCodeAt(group * 4 + 2)];
const digit3 = base64Map[s.charCodeAt(group * 4 + 3)];
result[group * 3 + 0] = (digit0 << 2) | (digit1 >> 4);
if (group * 3 + 1 < bytes) {
result[group * 3 + 1] = ((digit1 & 15) << 4) | (digit2 >> 2);
}
if (group * 3 + 2 < bytes) {
result[group * 3 + 2] = ((digit2 & 3) << 6) | digit3;
}
}
if (group * 3 + 2 < bytes) {
result[group * 3 + 2] = ((digit2 & 3) << 6) | digit3
}
}
return result
return result;
}
/** Key types this library supports */
@@ -220,150 +220,150 @@ export const enum KeyType {
}
/** Public key data size, excluding type field */
export const publicKeyDataSize = 33
export const publicKeyDataSize = 33;
/** Private key data size, excluding type field */
export const privateKeyDataSize = 32
export const privateKeyDataSize = 32;
/** Signature data size, excluding type field */
export const signatureDataSize = 65
export const signatureDataSize = 65;
/** Public key, private key, or signature in binary form */
export interface Key {
type: KeyType
data: Uint8Array
type: KeyType;
data: Uint8Array;
}
function digestSuffixRipemd160(data: Uint8Array, suffix: string) {
const d = new Uint8Array(data.length + suffix.length)
for (let i = 0; i < data.length; ++i) {
d[i] = data[i]
}
for (let i = 0; i < suffix.length; ++i) {
d[data.length + i] = suffix.charCodeAt(i)
}
return ripemd160(d)
const d = new Uint8Array(data.length + suffix.length);
for (let i = 0; i < data.length; ++i) {
d[i] = data[i];
}
for (let i = 0; i < suffix.length; ++i) {
d[data.length + i] = suffix.charCodeAt(i);
}
return ripemd160(d);
}
function stringToKey(s: string, type: KeyType, size: number, suffix: string): Key {
const whole = base58ToBinary(size + 4, s)
const result = { type, data: new Uint8Array(whole.buffer, 0, size) }
const digest = new Uint8Array(digestSuffixRipemd160(result.data, suffix))
if (digest[0] !== whole[size + 0] || digest[1] !== whole[size + 1]
const whole = base58ToBinary(size + 4, s);
const result = { type, data: new Uint8Array(whole.buffer, 0, size) };
const digest = new Uint8Array(digestSuffixRipemd160(result.data, suffix));
if (digest[0] !== whole[size + 0] || digest[1] !== whole[size + 1]
|| digest[2] !== whole[size + 2] || digest[3] !== whole[size + 3]) {
throw new Error('checksum doesn\'t match')
}
return result
throw new Error('checksum doesn\'t match');
}
return result;
}
function keyToString(key: Key, suffix: string, prefix: string) {
const digest = new Uint8Array(digestSuffixRipemd160(key.data, suffix))
const whole = new Uint8Array(key.data.length + 4)
for (let i = 0; i < key.data.length; ++i) {
whole[i] = key.data[i]
}
for (let i = 0; i < 4; ++i) {
whole[i + key.data.length] = digest[i]
}
return prefix + binaryToBase58(whole)
const digest = new Uint8Array(digestSuffixRipemd160(key.data, suffix));
const whole = new Uint8Array(key.data.length + 4);
for (let i = 0; i < key.data.length; ++i) {
whole[i] = key.data[i];
}
for (let i = 0; i < 4; ++i) {
whole[i + key.data.length] = digest[i];
}
return prefix + binaryToBase58(whole);
}
/** Convert key in `s` to binary form */
export function stringToPublicKey(s: string): Key {
if (typeof s !== 'string') {
throw new Error('expected string containing public key')
}
if (s.substr(0, 3) === 'EOS') {
const whole = base58ToBinary(publicKeyDataSize + 4, s.substr(3))
const key = { type: KeyType.k1, data: new Uint8Array(publicKeyDataSize) }
for (let i = 0; i < publicKeyDataSize; ++i) {
key.data[i] = whole[i]
if (typeof s !== 'string') {
throw new Error('expected string containing public key');
}
const digest = new Uint8Array(ripemd160(key.data))
if (digest[0] !== whole[publicKeyDataSize] || digest[1] !== whole[34]
if (s.substr(0, 3) === 'EOS') {
const whole = base58ToBinary(publicKeyDataSize + 4, s.substr(3));
const key = { type: KeyType.k1, data: new Uint8Array(publicKeyDataSize) };
for (let i = 0; i < publicKeyDataSize; ++i) {
key.data[i] = whole[i];
}
const digest = new Uint8Array(ripemd160(key.data));
if (digest[0] !== whole[publicKeyDataSize] || digest[1] !== whole[34]
|| digest[2] !== whole[35] || digest[3] !== whole[36]) {
throw new Error('checksum doesn\'t match')
throw new Error('checksum doesn\'t match');
}
return key;
} else if (s.substr(0, 7) === 'PUB_K1_') {
return stringToKey(s.substr(7), KeyType.k1, publicKeyDataSize, 'K1');
} else if (s.substr(0, 7) === 'PUB_R1_') {
return stringToKey(s.substr(7), KeyType.r1, publicKeyDataSize, 'R1');
} else {
throw new Error('unrecognized public key format');
}
return key
} else if (s.substr(0, 7) === 'PUB_K1_') {
return stringToKey(s.substr(7), KeyType.k1, publicKeyDataSize, 'K1')
} else if (s.substr(0, 7) === 'PUB_R1_') {
return stringToKey(s.substr(7), KeyType.r1, publicKeyDataSize, 'R1')
} else {
throw new Error('unrecognized public key format')
}
}
/** Convert `key` to string (base-58) form */
export function publicKeyToString(key: Key) {
if (key.type === KeyType.k1 && key.data.length === publicKeyDataSize) {
return keyToString(key, 'K1', 'PUB_K1_')
} else if (key.type === KeyType.r1 && key.data.length === publicKeyDataSize) {
return keyToString(key, 'R1', 'PUB_R1_')
} else {
throw new Error('unrecognized public key format')
}
if (key.type === KeyType.k1 && key.data.length === publicKeyDataSize) {
return keyToString(key, 'K1', 'PUB_K1_');
} else if (key.type === KeyType.r1 && key.data.length === publicKeyDataSize) {
return keyToString(key, 'R1', 'PUB_R1_');
} else {
throw new Error('unrecognized public key format');
}
}
/** If a key is in the legacy format (`EOS` prefix), then convert it to the new format (`PUB_K1_`).
* Leaves other formats untouched
*/
export function convertLegacyPublicKey(s: string) {
if (s.substr(0, 3) === 'EOS') {
return publicKeyToString(stringToPublicKey(s))
}
return s
if (s.substr(0, 3) === 'EOS') {
return publicKeyToString(stringToPublicKey(s));
}
return s;
}
/** If a key is in the legacy format (`EOS` prefix), then convert it to the new format (`PUB_K1_`).
* Leaves other formats untouched
*/
export function convertLegacyPublicKeys(keys: string[]) {
return keys.map(convertLegacyPublicKey)
return keys.map(convertLegacyPublicKey);
}
/** Convert key in `s` to binary form */
export function stringToPrivateKey(s: string): Key {
if (typeof s !== 'string') {
throw new Error('expected string containing private key')
}
if (s.substr(0, 7) === 'PVT_R1_') {
return stringToKey(s.substr(7), KeyType.r1, privateKeyDataSize, 'R1')
} else {
throw new Error('unrecognized private key format')
}
if (typeof s !== 'string') {
throw new Error('expected string containing private key');
}
if (s.substr(0, 7) === 'PVT_R1_') {
return stringToKey(s.substr(7), KeyType.r1, privateKeyDataSize, 'R1');
} else {
throw new Error('unrecognized private key format');
}
}
/** Convert `key` to string (base-58) form */
export function privateKeyToString(key: Key) {
if (key.type === KeyType.r1) {
return keyToString(key, 'R1', 'PVT_R1_')
} else {
throw new Error('unrecognized private key format')
}
if (key.type === KeyType.r1) {
return keyToString(key, 'R1', 'PVT_R1_');
} else {
throw new Error('unrecognized private key format');
}
}
/** Convert key in `s` to binary form */
export function stringToSignature(s: string): Key {
if (typeof s !== 'string') {
throw new Error('expected string containing signature')
}
if (s.substr(0, 7) === 'SIG_K1_') {
return stringToKey(s.substr(7), KeyType.k1, signatureDataSize, 'K1')
} else if (s.substr(0, 7) === 'SIG_R1_') {
return stringToKey(s.substr(7), KeyType.r1, signatureDataSize, 'R1')
} else {
throw new Error('unrecognized signature format')
}
if (typeof s !== 'string') {
throw new Error('expected string containing signature');
}
if (s.substr(0, 7) === 'SIG_K1_') {
return stringToKey(s.substr(7), KeyType.k1, signatureDataSize, 'K1');
} else if (s.substr(0, 7) === 'SIG_R1_') {
return stringToKey(s.substr(7), KeyType.r1, signatureDataSize, 'R1');
} else {
throw new Error('unrecognized signature format');
}
}
/** Convert `signature` to string (base-58) form */
export function signatureToString(signature: Key) {
if (signature.type === KeyType.k1) {
return keyToString(signature, 'K1', 'SIG_K1_')
} else if (signature.type === KeyType.r1) {
return keyToString(signature, 'R1', 'SIG_R1_')
} else {
throw new Error('unrecognized signature format')
}
if (signature.type === KeyType.k1) {
return keyToString(signature, 'K1', 'SIG_K1_');
} else if (signature.type === KeyType.r1) {
return keyToString(signature, 'R1', 'SIG_R1_');
} else {
throw new Error('unrecognized signature format');
}
}
+47 -47
View File
@@ -2,79 +2,79 @@
/** Structured format for abis */
export interface Abi {
version: string
types: Array<{ new_type_name: string, type: string }>
structs: Array<{ name: string, base: string, fields: Array<{ name: string, type: string }> }>
actions: Array<{ name: string, type: string, ricardian_contract: string }>
tables: Array<{ name: string, type: string, index_type: string, key_names: string[], key_types: string[] }>
ricardian_clauses: Array<{ id: string, body: string }>
error_messages: Array<{ error_code: string, error_msg: string }>
abi_extensions: Array<{ tag: number, value: string }>
variants?: Array<{ name: string, types: string[] }>
version: string;
types: Array<{ new_type_name: string, type: string }>;
structs: Array<{ name: string, base: string, fields: Array<{ name: string, type: string }> }>;
actions: Array<{ name: string, type: string, ricardian_contract: string }>;
tables: Array<{ name: string, type: string, index_type: string, key_names: string[], key_types: string[] }>;
ricardian_clauses: Array<{ id: string, body: string }>;
error_messages: Array<{ error_code: string, error_msg: string }>;
abi_extensions: Array<{ tag: number, value: string }>;
variants?: Array<{ name: string, types: string[] }>;
}
/** Return value of `/v1/chain/get_abi` */
export interface GetAbiResult {
account_name: string
abi: Abi
account_name: string;
abi: Abi;
}
/** Subset of `GetBlockResult` needed to calculate TAPoS fields in transactions */
export interface BlockTaposInfo {
timestamp: string
block_num: number
ref_block_prefix: number
timestamp: string;
block_num: number;
ref_block_prefix: number;
}
/** Return value of `/v1/chain/get_block` */
export interface GetBlockResult {
timestamp: string
producer: string
confirmed: number
previous: string
transaction_mroot: string
action_mroot: string
schedule_version: number
producer_signature: string
id: string
block_num: number
ref_block_prefix: number
timestamp: string;
producer: string;
confirmed: number;
previous: string;
transaction_mroot: string;
action_mroot: string;
schedule_version: number;
producer_signature: string;
id: string;
block_num: number;
ref_block_prefix: number;
}
/** Return value of `/v1/chain/get_code` */
export interface GetCodeResult {
account_name: string
code_hash: string
wast: string
wasm: string
abi: Abi
account_name: string;
code_hash: string;
wast: string;
wasm: string;
abi: Abi;
}
/** Return value of `/v1/chain/get_info` */
export interface GetInfoResult {
server_version: string
chain_id: string
head_block_num: number
last_irreversible_block_num: number
last_irreversible_block_id: string
head_block_id: string
head_block_time: string
head_block_producer: string
virtual_block_cpu_limit: number
virtual_block_net_limit: number
block_cpu_limit: number
block_net_limit: number
server_version: string;
chain_id: string;
head_block_num: number;
last_irreversible_block_num: number;
last_irreversible_block_id: string;
head_block_id: string;
head_block_time: string;
head_block_producer: string;
virtual_block_cpu_limit: number;
virtual_block_net_limit: number;
block_cpu_limit: number;
block_net_limit: number;
}
/** Return value of `/v1/chain/get_raw_code_and_abi` */
export interface GetRawCodeAndAbiResult {
account_name: string
wasm: string
abi: string
account_name: string;
wasm: string;
abi: string;
}
/** Arguments for `push_transaction` */
export interface PushTransactionArgs {
signatures: string[]
serializedTransaction: Uint8Array
signatures: string[];
serializedTransaction: Uint8Array;
}
+11 -11
View File
@@ -6,17 +6,17 @@
/** Holds detailed error information */
export class RpcError extends Error {
/** Detailed error information */
public json: any
public json: any;
constructor(json: any) {
if (json.error && json.error.details && json.error.details.length && json.error.details[0].message) {
super(json.error.details[0].message)
} else if (json.processed && json.processed.except && json.processed.except.message) {
super(json.processed.except.message)
} else {
super(json.message)
constructor(json: any) {
if (json.error && json.error.details && json.error.details.length && json.error.details[0].message) {
super(json.error.details[0].message);
} else if (json.processed && json.processed.except && json.processed.except.message) {
super(json.processed.except.message);
} else {
super(json.message);
}
Object.setPrototypeOf(this, RpcError.prototype);
this.json = json;
}
Object.setPrototypeOf(this, RpcError.prototype)
this.json = json
}
}
+768 -768
View File
File diff suppressed because it is too large Load Diff
+7 -7
View File
@@ -1,8 +1,8 @@
import { Api } from './eosjs-api'
import * as ApiInterfaces from './eosjs-api-interfaces'
import { JsonRpc } from './eosjs-jsonrpc'
import * as RpcInterfaces from './eosjs-rpc-interfaces'
import { RpcError } from './eosjs-rpcerror'
import * as Serialize from './eosjs-serialize'
import { Api } from './eosjs-api';
import * as ApiInterfaces from './eosjs-api-interfaces';
import { JsonRpc } from './eosjs-jsonrpc';
import * as RpcInterfaces from './eosjs-rpc-interfaces';
import { RpcError } from './eosjs-rpcerror';
import * as Serialize from './eosjs-serialize';
export { Api, ApiInterfaces, JsonRpc, RpcInterfaces, RpcError, Serialize }
export { Api, ApiInterfaces, JsonRpc, RpcInterfaces, RpcError, Serialize };
+3 -3
View File
@@ -1,4 +1,4 @@
import { JsonRpc } from './eosjs-jsonrpc'
import { RpcError } from './eosjs-rpcerror'
import { JsonRpc } from './eosjs-jsonrpc';
import { RpcError } from './eosjs-rpcerror';
export { JsonRpc, RpcError }
export { JsonRpc, RpcError };
+160 -160
View File
@@ -1,194 +1,194 @@
import { TextDecoder, TextEncoder } from 'text-encoding'
import { Api } from '../eosjs-api'
import { JsonRpc } from '../eosjs-jsonrpc'
import { JsSignatureProvider } from '../eosjs-jssig'
import { TextDecoder, TextEncoder } from 'text-encoding';
import { Api } from '../eosjs-api';
import { JsonRpc } from '../eosjs-jsonrpc';
import { JsSignatureProvider } from '../eosjs-jssig';
const transaction = {
expiration: '2018-09-04T18:42:49',
ref_block_num: 38096,
ref_block_prefix: 505360011,
max_net_usage_words: 0,
max_cpu_usage_ms: 0,
delay_sec: 0,
context_free_actions: [] as any,
actions: [
{
account: 'testeostoken',
name: 'transfer',
authorization: [
expiration: '2018-09-04T18:42:49',
ref_block_num: 38096,
ref_block_prefix: 505360011,
max_net_usage_words: 0,
max_cpu_usage_ms: 0,
delay_sec: 0,
context_free_actions: [] as any,
actions: [
{
actor: 'thegazelle',
permission: 'active',
},
],
data: {
from: 'thegazelle',
to: 'remasteryoda',
quantity: '1.0000 EOS',
memo: 'For a secure future.',
},
hex_data: `00808a517dc354cb6012f557656ca4ba102700000000000004454f530000000014466f722
account: 'testeostoken',
name: 'transfer',
authorization: [
{
actor: 'thegazelle',
permission: 'active',
},
],
data: {
from: 'thegazelle',
to: 'remasteryoda',
quantity: '1.0000 EOS',
memo: 'For a secure future.',
},
hex_data: `00808a517dc354cb6012f557656ca4ba102700000000000004454f530000000014466f722
06120736563757265206675747572652e`,
},
{
account: 'testeostoken',
name: 'transfer',
authorization: [
{
actor: 'thegazelle',
permission: 'active',
},
],
data: {
from: 'thegazelle',
to: 'remasteryoda',
quantity: '2.0000 EOS',
memo: 'For a second secure future (multiverse?)',
},
hex_data: `00808a517dc354cb6012f557656ca4ba204e00000000000004454f530000000028466f722061207365636f6e642073656
{
account: 'testeostoken',
name: 'transfer',
authorization: [
{
actor: 'thegazelle',
permission: 'active',
},
],
data: {
from: 'thegazelle',
to: 'remasteryoda',
quantity: '2.0000 EOS',
memo: 'For a second secure future (multiverse?)',
},
hex_data: `00808a517dc354cb6012f557656ca4ba204e00000000000004454f530000000028466f722061207365636f6e642073656
37572652066757475726520286d756c746976657273653f29`,
},
],
transaction_extensions: [] as any,
}
},
],
transaction_extensions: [] as any,
};
const serializedTx = [
41, 210, 142, 91, 208, 148, 139, 46, 31, 30, 0, 0, 0, 0, 2, 48, 21, 164,
25, 83, 149, 177, 202, 0, 0, 0, 87, 45, 60, 205, 205, 1, 0, 128, 138, 81,
125, 195, 84, 203, 0, 0, 0, 0, 168, 237, 50, 50, 0, 48, 21, 164, 25, 83,
149, 177, 202, 0, 0, 0, 87, 45, 60, 205, 205, 1, 0, 128, 138, 81, 125,
195, 84, 203, 0, 0, 0, 0, 168, 237, 50, 50, 0, 0,
]
41, 210, 142, 91, 208, 148, 139, 46, 31, 30, 0, 0, 0, 0, 2, 48, 21, 164,
25, 83, 149, 177, 202, 0, 0, 0, 87, 45, 60, 205, 205, 1, 0, 128, 138, 81,
125, 195, 84, 203, 0, 0, 0, 0, 168, 237, 50, 50, 0, 48, 21, 164, 25, 83,
149, 177, 202, 0, 0, 0, 87, 45, 60, 205, 205, 1, 0, 128, 138, 81, 125,
195, 84, 203, 0, 0, 0, 0, 168, 237, 50, 50, 0, 0,
];
const deserializedTx = {
actions: [
{
account: 'testeostoken',
authorization: [{ actor: 'thegazelle', permission: 'active' }],
data: '',
name: 'transfer',
},
{
account: 'testeostoken',
authorization: [{ actor: 'thegazelle', permission: 'active' }],
data: '',
name: 'transfer',
},
],
context_free_actions: [] as any,
delay_sec: 0,
expiration: '2018-09-04T18:42:49.000',
max_cpu_usage_ms: 0,
max_net_usage_words: 0,
ref_block_num: 38096,
ref_block_prefix: 505360011,
transaction_extensions: [] as any,
}
actions: [
{
account: 'testeostoken',
authorization: [{ actor: 'thegazelle', permission: 'active' }],
data: '',
name: 'transfer',
},
{
account: 'testeostoken',
authorization: [{ actor: 'thegazelle', permission: 'active' }],
data: '',
name: 'transfer',
},
],
context_free_actions: [] as any,
delay_sec: 0,
expiration: '2018-09-04T18:42:49.000',
max_cpu_usage_ms: 0,
max_net_usage_words: 0,
ref_block_num: 38096,
ref_block_prefix: 505360011,
transaction_extensions: [] as any,
};
const serializedActions = [
{
account: 'testeostoken',
authorization: [{ actor: 'thegazelle', permission: 'active' }],
{
account: 'testeostoken',
authorization: [{ actor: 'thegazelle', permission: 'active' }],
data: "00808A517DC354CB6012F557656CA4BA102700000000000004454F530000000014466F72206120736563757265206675747572652E", // tslint:disable-line
name: 'transfer',
},
{
account: 'testeostoken',
authorization: [{ actor: 'thegazelle', permission: 'active' }],
name: 'transfer',
},
{
account: 'testeostoken',
authorization: [{ actor: 'thegazelle', permission: 'active' }],
data: "00808A517DC354CB6012F557656CA4BA204E00000000000004454F530000000028466F722061207365636F6E64207365637572652066757475726520286D756C746976657273653F29", // tslint:disable-line
name: 'transfer',
},
]
name: 'transfer',
},
];
const deserializedActions = [
{
account: 'testeostoken',
authorization: [{ actor: 'thegazelle', permission: 'active' }],
data: {
from: 'thegazelle',
memo: 'For a secure future.',
quantity: '1.0000 EOS',
to: 'remasteryoda',
{
account: 'testeostoken',
authorization: [{ actor: 'thegazelle', permission: 'active' }],
data: {
from: 'thegazelle',
memo: 'For a secure future.',
quantity: '1.0000 EOS',
to: 'remasteryoda',
},
name: 'transfer',
},
name: 'transfer',
},
{
account: 'testeostoken',
authorization: [{ actor: 'thegazelle', permission: 'active' }],
data: {
from: 'thegazelle',
memo: 'For a second secure future (multiverse?)',
quantity: '2.0000 EOS',
to: 'remasteryoda',
{
account: 'testeostoken',
authorization: [{ actor: 'thegazelle', permission: 'active' }],
data: {
from: 'thegazelle',
memo: 'For a second secure future (multiverse?)',
quantity: '2.0000 EOS',
to: 'remasteryoda',
},
name: 'transfer',
},
name: 'transfer',
},
]
];
describe('eosjs-api', () => {
let api: any
const fetch = async (input: any, init: any): Promise<any> => ({
ok: true,
json: async () => {
if (input === '/v1/chain/get_raw_code_and_abi') {
return {
account_name: 'testeostoken',
let api: any;
const fetch = async (input: any, init: any): Promise<any> => ({
ok: true,
json: async () => {
if (input === '/v1/chain/get_raw_code_and_abi') {
return {
account_name: 'testeostoken',
abi: "DmVvc2lvOjphYmkvMS4wAQxhY2NvdW50X25hbWUEbmFtZQUIdHJhbnNmZXIABARmcm9tDGFjY291bnRfbmFtZQJ0bwxhY2NvdW50X25hbWUIcXVhbnRpdHkFYXNzZXQEbWVtbwZzdHJpbmcGY3JlYXRlAAIGaXNzdWVyDGFjY291bnRfbmFtZQ5tYXhpbXVtX3N1cHBseQVhc3NldAVpc3N1ZQADAnRvDGFjY291bnRfbmFtZQhxdWFudGl0eQVhc3NldARtZW1vBnN0cmluZwdhY2NvdW50AAEHYmFsYW5jZQVhc3NldA5jdXJyZW5jeV9zdGF0cwADBnN1cHBseQVhc3NldAptYXhfc3VwcGx5BWFzc2V0Bmlzc3VlcgxhY2NvdW50X25hbWUDAAAAVy08zc0IdHJhbnNmZXLnBSMjIFRyYW5zZmVyIFRlcm1zICYgQ29uZGl0aW9ucwoKSSwge3tmcm9tfX0sIGNlcnRpZnkgdGhlIGZvbGxvd2luZyB0byBiZSB0cnVlIHRvIHRoZSBiZXN0IG9mIG15IGtub3dsZWRnZToKCjEuIEkgY2VydGlmeSB0aGF0IHt7cXVhbnRpdHl9fSBpcyBub3QgdGhlIHByb2NlZWRzIG9mIGZyYXVkdWxlbnQgb3IgdmlvbGVudCBhY3Rpdml0aWVzLgoyLiBJIGNlcnRpZnkgdGhhdCwgdG8gdGhlIGJlc3Qgb2YgbXkga25vd2xlZGdlLCB7e3RvfX0gaXMgbm90IHN1cHBvcnRpbmcgaW5pdGlhdGlvbiBvZiB2aW9sZW5jZSBhZ2FpbnN0IG90aGVycy4KMy4gSSBoYXZlIGRpc2Nsb3NlZCBhbnkgY29udHJhY3R1YWwgdGVybXMgJiBjb25kaXRpb25zIHdpdGggcmVzcGVjdCB0byB7e3F1YW50aXR5fX0gdG8ge3t0b319LgoKSSB1bmRlcnN0YW5kIHRoYXQgZnVuZHMgdHJhbnNmZXJzIGFyZSBub3QgcmV2ZXJzaWJsZSBhZnRlciB0aGUge3t0cmFuc2FjdGlvbi5kZWxheX19IHNlY29uZHMgb3Igb3RoZXIgZGVsYXkgYXMgY29uZmlndXJlZCBieSB7e2Zyb219fSdzIHBlcm1pc3Npb25zLgoKSWYgdGhpcyBhY3Rpb24gZmFpbHMgdG8gYmUgaXJyZXZlcnNpYmx5IGNvbmZpcm1lZCBhZnRlciByZWNlaXZpbmcgZ29vZHMgb3Igc2VydmljZXMgZnJvbSAne3t0b319JywgSSBhZ3JlZSB0byBlaXRoZXIgcmV0dXJuIHRoZSBnb29kcyBvciBzZXJ2aWNlcyBvciByZXNlbmQge3txdWFudGl0eX19IGluIGEgdGltZWx5IG1hbm5lci4KAAAAAAClMXYFaXNzdWUAAAAAAKhs1EUGY3JlYXRlAAIAAAA4T00RMgNpNjQBCGN1cnJlbmN5AQZ1aW50NjQHYWNjb3VudAAAAAAAkE3GA2k2NAEIY3VycmVuY3kBBnVpbnQ2NA5jdXJyZW5jeV9zdGF0cwAAAA===", // tslint:disable-line
}
}
};
}
return transaction
},
})
return transaction;
},
});
beforeEach(() => {
const rpc = new JsonRpc('', { fetch })
const signatureProvider = new JsSignatureProvider(['5JtUScZK2XEp3g9gh7F8bwtPTRAkASmNrrftmx4AxDKD5K4zDnr'])
const chainId = '038f4b0fc8ff18a4f0842a8f0564611f6e96e8535901dd45e43ac8691a1c4dca'
api = new Api({
rpc, signatureProvider, chainId, textDecoder: new TextDecoder(), textEncoder: new TextEncoder(),
})
})
beforeEach(() => {
const rpc = new JsonRpc('', { fetch });
const signatureProvider = new JsSignatureProvider(['5JtUScZK2XEp3g9gh7F8bwtPTRAkASmNrrftmx4AxDKD5K4zDnr']);
const chainId = '038f4b0fc8ff18a4f0842a8f0564611f6e96e8535901dd45e43ac8691a1c4dca';
api = new Api({
rpc, signatureProvider, chainId, textDecoder: new TextDecoder(), textEncoder: new TextEncoder(),
});
});
it('Doesnt crash', () => {
expect(api).toBeTruthy()
})
it('Doesnt crash', () => {
expect(api).toBeTruthy();
});
it('getAbi returns an abi', async () => {
const response = await api.getAbi('testeostoken')
expect(response).toBeTruthy()
})
it('getAbi returns an abi', async () => {
const response = await api.getAbi('testeostoken');
expect(response).toBeTruthy();
});
it('getTransactionAbis returns abis by transactions', async () => {
const response = await api.getTransactionAbis(transaction)
expect(response[0].abi.length).toBeGreaterThan(0)
})
it('getTransactionAbis returns abis by transactions', async () => {
const response = await api.getTransactionAbis(transaction);
expect(response[0].abi.length).toBeGreaterThan(0);
});
it('getContract returns a contract', async () => {
const response = await api.getContract('testeostoken')
expect(response.actions).toBeTruthy()
})
it('getContract returns a contract', async () => {
const response = await api.getContract('testeostoken');
expect(response.actions).toBeTruthy();
});
it('deserializeTransaction converts tx from binary', () => {
const tx = api.deserializeTransaction(serializedTx)
expect(tx).toEqual(deserializedTx)
})
it('deserializeTransaction converts tx from binary', () => {
const tx = api.deserializeTransaction(serializedTx);
expect(tx).toEqual(deserializedTx);
});
it('serializeActions converts actions to hex', async () => {
const response = await api.serializeActions(transaction.actions)
it('serializeActions converts actions to hex', async () => {
const response = await api.serializeActions(transaction.actions);
expect(response).toEqual(serializedActions)
})
expect(response).toEqual(serializedActions);
});
it('deserializeActions converts actions from hex', async () => {
const response = await api.deserializeActions(serializedActions)
it('deserializeActions converts actions from hex', async () => {
const response = await api.deserializeActions(serializedActions);
expect(response).toEqual(deserializedActions)
})
expect(response).toEqual(deserializedActions);
});
it('hasRequiredTaposFields returns true, if required fields are present', () => {
const response = api.hasRequiredTaposFields(transaction)
it('hasRequiredTaposFields returns true, if required fields are present', () => {
const response = api.hasRequiredTaposFields(transaction);
expect(response).toEqual(true)
})
})
expect(response).toEqual(true);
});
});
File diff suppressed because it is too large Load Diff
+34 -34
View File
@@ -1,42 +1,42 @@
import * as ecc from 'eosjs-ecc'
import { JsSignatureProvider } from '../eosjs-jssig'
import * as ecc from 'eosjs-ecc';
import { JsSignatureProvider } from '../eosjs-jssig';
describe('JsSignatureProvider', () => {
const privateKeys = ['key1', 'key2', 'key3']
const publicKeys = [
'PUB_K1_8iD9ABKFH5b9JyFgb5PE51BdCV74qGN9UMfg9V3TwaExCQWxJm',
'PUB_K1_8f2o2LLQ3phteqyazxirQZnQzQFpnjLnXiUFEJcsSYhnjWNvSX',
'PUB_K1_5imfbmmHC83VRxLRTcvovviAc6LPpyszcDuKtkwka9e9Jg37Hp',
]
const privateKeys = ['key1', 'key2', 'key3'];
const publicKeys = [
'PUB_K1_8iD9ABKFH5b9JyFgb5PE51BdCV74qGN9UMfg9V3TwaExCQWxJm',
'PUB_K1_8f2o2LLQ3phteqyazxirQZnQzQFpnjLnXiUFEJcsSYhnjWNvSX',
'PUB_K1_5imfbmmHC83VRxLRTcvovviAc6LPpyszcDuKtkwka9e9Jg37Hp',
];
it('builds public keys from private when constructed', async () => {
const eccPkFromString = jest.spyOn(ecc.PrivateKey, 'fromString')
eccPkFromString.mockImplementation((k) => ecc.PrivateKey.fromHex(ecc.sha256(k)))
const provider = new JsSignatureProvider(privateKeys)
const actualPublicKeys = await provider.getAvailableKeys()
it('builds public keys from private when constructed', async () => {
const eccPkFromString = jest.spyOn(ecc.PrivateKey, 'fromString');
eccPkFromString.mockImplementation((k) => ecc.PrivateKey.fromHex(ecc.sha256(k)));
const provider = new JsSignatureProvider(privateKeys);
const actualPublicKeys = await provider.getAvailableKeys();
expect(eccPkFromString).toHaveBeenCalledTimes(privateKeys.length)
expect(actualPublicKeys).toEqual(publicKeys)
})
expect(eccPkFromString).toHaveBeenCalledTimes(privateKeys.length);
expect(actualPublicKeys).toEqual(publicKeys);
});
it('signs a transaction', async () => {
const eccSignatureSign = jest.spyOn(ecc.Signature, 'sign')
eccSignatureSign.mockImplementation((buffer, signKey) => signKey)
it('signs a transaction', async () => {
const eccSignatureSign = jest.spyOn(ecc.Signature, 'sign');
eccSignatureSign.mockImplementation((buffer, signKey) => signKey);
const provider = new JsSignatureProvider(privateKeys)
const chainId = '12345'
const requiredKeys = [
publicKeys[0],
publicKeys[2],
]
const serializedTransaction = new Uint8Array([
0, 16, 32, 128, 255,
])
const abis: any[] = []
const provider = new JsSignatureProvider(privateKeys);
const chainId = '12345';
const requiredKeys = [
publicKeys[0],
publicKeys[2],
];
const serializedTransaction = new Uint8Array([
0, 16, 32, 128, 255,
]);
const abis: any[] = [];
const signOutput = await provider.sign({ chainId, requiredKeys, serializedTransaction, abis })
const signOutput = await provider.sign({ chainId, requiredKeys, serializedTransaction, abis });
expect(eccSignatureSign).toHaveBeenCalledTimes(2)
expect(signOutput).toEqual({ signatures: [privateKeys[0], privateKeys[2]], serializedTransaction })
})
})
expect(eccSignatureSign).toHaveBeenCalledTimes(2);
expect(signOutput).toEqual({ signatures: [privateKeys[0], privateKeys[2]], serializedTransaction });
});
});
+1 -1
View File
@@ -1 +1 @@
global.fetch = require("jest-fetch-mock")
global.fetch = require("jest-fetch-mock");
+145 -146
View File
@@ -4,154 +4,153 @@
<script src='../../dist-web/eosjs-jsonrpc.js'></script>
<script src='../../dist-web/eosjs-jssig.js'></script>
<script>
let pre = document.getElementsByTagName('pre')[0];
const privateKey = '5JuH9fCXmU3xbj8nRmhPZaVrxxXrdPaRmZLW1cznNTmTQR2Kg5Z'; // replace with "bob" account private key
/* new accounts for testing can be created by unlocking a cleos wallet then calling:
* 1) cleos create key --to-console (copy this privateKey & publicKey)
* 2) cleos wallet import
* 3) cleos create account bob publicKey
* 4) cleos create account alice publicKey
*/
let pre = document.getElementsByTagName('pre')[0];
const privateKey = '5JuH9fCXmU3xbj8nRmhPZaVrxxXrdPaRmZLW1cznNTmTQR2Kg5Z'; // replace with "bob" account private key
/* new accounts for testing can be created by unlocking a cleos wallet then calling:
* 1) cleos create key --to-console (copy this privateKey & publicKey)
* 2) cleos wallet import
* 3) cleos create account bob publicKey
* 4) cleos create account alice publicKey
*/
const rpc = new eosjs_jsonrpc.JsonRpc('http://localhost:8888');
const signatureProvider = new eosjs_jssig.JsSignatureProvider([privateKey]);
const api = new eosjs_api.Api({ rpc, signatureProvider });
const rpc = new eosjs_jsonrpc.JsonRpc('http://localhost:8888');
const signatureProvider = new eosjs_jssig.JsSignatureProvider([privateKey]);
const api = new eosjs_api.Api({ rpc, signatureProvider });
function waitTwoSeconds() {
return new Promise(resolve => setTimeout(resolve, 2000));
}
(async () => {
try {
const resultWithConfig = await api.transact({
actions: [{
account: 'eosio.token',
name: 'transfer',
authorization: [{
actor: 'bob',
permission: 'active',
}],
data: {
from: 'bob',
to: 'alice',
quantity: '0.0001 SYS',
memo: '',
},
}]
}, {
blocksBehind: 3,
expireSeconds: 30,
});
pre.textContent += '\n\nTransaction with configured TAPOS pushed!\n\n' + JSON.stringify(resultWithConfig, null, 2);
await waitTwoSeconds(); // run additional tests after 2 second delay
const resultWithoutBroadcast = await api.transact({
actions: [{
account: 'eosio.token',
name: 'transfer',
authorization: [{
actor: 'bob',
permission: 'active',
}],
data: {
from: 'bob',
to: 'alice',
quantity: '0.0001 SYS',
memo: '',
},
}]
}, {
broadcast: false,
blocksBehind: 3,
expireSeconds: 30,
});
pre.textContent = '\n\nTransaction serialized and signed but not pushed!\n\n' + JSON.stringify(resultWithoutBroadcast, null, 2);
await waitTwoSeconds();
const broadcastResult = await api.pushSignedTransaction(resultWithoutBroadcast);
pre.textContent = '\n\nSerialized Transaction and signatures pushed!\n\n' + JSON.stringify(broadcastResult, null, 2);
await waitTwoSeconds();
const blockInfo = await rpc.get_block(broadcastResult.processed.block_num)
const currentDate = new Date();
const timePlusTen = currentDate.getTime() + 10000;
const timeInISOString = (new Date(timePlusTen)).toISOString();
const expiration = timeInISOString.substr(0, timeInISOString.length - 1);
const resultWithoutConfig = await api.transact({
expiration,
ref_block_num: blockInfo.block_num & 0xffff,
ref_block_prefix: blockInfo.ref_block_prefix,
actions: [{
account: 'eosio.token',
name: 'transfer',
authorization: [{
actor: 'bob',
permission: 'active',
}],
data: {
from: 'bob',
to: 'alice',
quantity: '0.0001 SYS',
memo: '',
},
}]
});
pre.textContent = '\n\nTransaction with manual TAPOS pushed!\n\n' + JSON.stringify(resultWithoutConfig, null, 2);
function waitTwoSeconds() {
return new Promise(resolve => setTimeout(resolve, 2000));
}
catch(e) {
throw new Error('Web Integration Test Failed Unexpectedly: ' + e.message)
}
await waitTwoSeconds();
let failedAsPlanned;
try {
failedAsPlanned = true;
const resultShouldFail = await api.transact({
actions: [{
account: 'eosio.token',
name: 'transfer',
authorization: [{
actor: 'bob',
permission: 'active',
}],
data: {
from: 'bob',
to: 'alice',
quantity: '0.0001 SYS',
memo: '',
},
}]
});
failedAsPlanned = false;
} catch (e) {
if (e.message == 'Required configuration or TAPOS fields are not present') {
pre.textContent = '\n\nCaught Exception successfully: \n\n' + e;
}
else { failedAsPlanned = false }
}
if (!failedAsPlanned) {
throw new Error('The final transact call (lacking TAPoS and config) did not fail as expected');
}
await waitTwoSeconds();
try {
failedAsPlanned = true;
const invalidRpcCall = await rpc.get_block(-1);
failedAsPlanned = false;
}
catch(e) {
if (e instanceof eosjs_jsonrpc.RpcError) {
pre.textContent = '\n\nCaught RpcError successfully: \n\n' + JSON.stringify(e.json, null, 2);
}
else {
(async () => {
try {
const resultWithConfig = await api.transact({
actions: [{
account: 'eosio.token',
name: 'transfer',
authorization: [{
actor: 'bob',
permission: 'active',
}],
data: {
from: 'bob',
to: 'alice',
quantity: '0.0001 SYS',
memo: '',
},
}]
}, {
blocksBehind: 3,
expireSeconds: 30,
});
pre.textContent += '\n\nTransaction with configured TAPOS pushed!\n\n' + JSON.stringify(resultWithConfig, null, 2);
await waitTwoSeconds(); // run additional tests after 2 second delay
const resultWithoutBroadcast = await api.transact({
actions: [{
account: 'eosio.token',
name: 'transfer',
authorization: [{
actor: 'bob',
permission: 'active',
}],
data: {
from: 'bob',
to: 'alice',
quantity: '0.0001 SYS',
memo: '',
},
}]
}, {
broadcast: false,
blocksBehind: 3,
expireSeconds: 30,
});
pre.textContent = '\n\nTransaction serialized and signed but not pushed!\n\n' + JSON.stringify(resultWithoutBroadcast, null, 2);
await waitTwoSeconds();
const broadcastResult = await api.pushSignedTransaction(resultWithoutBroadcast);
pre.textContent = '\n\nSerialized Transaction and signatures pushed!\n\n' + JSON.stringify(broadcastResult, null, 2);
await waitTwoSeconds();
const blockInfo = await rpc.get_block(broadcastResult.processed.block_num)
const currentDate = new Date();
const timePlusTen = currentDate.getTime() + 10000;
const timeInISOString = (new Date(timePlusTen)).toISOString();
const expiration = timeInISOString.substr(0, timeInISOString.length - 1);
const resultWithoutConfig = await api.transact({
expiration,
ref_block_num: blockInfo.block_num & 0xffff,
ref_block_prefix: blockInfo.ref_block_prefix,
actions: [{
account: 'eosio.token',
name: 'transfer',
authorization: [{
actor: 'bob',
permission: 'active',
}],
data: {
from: 'bob',
to: 'alice',
quantity: '0.0001 SYS',
memo: '',
},
}]
});
pre.textContent = '\n\nTransaction with manual TAPOS pushed!\n\n' + JSON.stringify(resultWithoutConfig, null, 2);
}
catch(e) {
throw new Error('Web Integration Test Failed Unexpectedly: ' + e.message)
}
await waitTwoSeconds();
let failedAsPlanned;
try {
failedAsPlanned = true;
const resultShouldFail = await api.transact({
actions: [{
account: 'eosio.token',
name: 'transfer',
authorization: [{
actor: 'bob',
permission: 'active',
}],
data: {
from: 'bob',
to: 'alice',
quantity: '0.0001 SYS',
memo: '',
},
}]
});
failedAsPlanned = false;
}
}
if (!failedAsPlanned) {
throw new Error('An rpc error is not being thrown for invalid rpc calls');
}
await waitTwoSeconds();
})();
} catch (e) {
if (e.message == 'Required configuration or TAPOS fields are not present') {
pre.textContent = '\n\nCaught Exception successfully: \n\n' + e;
}
else { failedAsPlanned = false }
}
if (!failedAsPlanned) {
throw new Error('The final transact call (lacking TAPoS and config) did not fail as expected');
}
await waitTwoSeconds();
try {
failedAsPlanned = true;
const invalidRpcCall = await rpc.get_block(-1);
failedAsPlanned = false;
}
catch(e) {
if (e instanceof eosjs_jsonrpc.RpcError) {
pre.textContent = '\n\nCaught RpcError successfully: \n\n' + JSON.stringify(e.json, null, 2);
}
else {
failedAsPlanned = false;
}
}
if (!failedAsPlanned) {
throw new Error('An rpc error is not being thrown for invalid rpc calls');
}
await waitTwoSeconds();
})();
</script>
+12 -7
View File
@@ -1,9 +1,14 @@
{
"defaultSeverity": "error",
"extends": [
"@blockone/tslint-config-blockone/tslint-config"
],
"jsRules": {},
"rules": { "no-bitwise": false, "no-var-requires": false },
"rulesDirectory": []
"defaultSeverity": "error",
"extends": [
"@blockone/tslint-config-blockone/tslint-config"
],
"jsRules": {},
"rules": {
"no-bitwise": false,
"no-var-requires": false,
"semicolon": [true, "always"],
"ter-indent": [true, 4]
},
"rulesDirectory": []
}