diff --git a/__tests__/__snapshots__/ain.test.ts.snap b/__tests__/__snapshots__/ain.test.ts.snap index 799b26c..1ef7e02 100644 --- a/__tests__/__snapshots__/ain.test.ts.snap +++ b/__tests__/__snapshots__/ain.test.ts.snap @@ -171,6 +171,18 @@ Object { exports[`ain-js Database getProofHash 1`] = `"0x88496dfee3566db91f487aa4cbf69a0c42a3e2a5d0a65bfd4897d699e8734785"`; +exports[`ain-js Database getStateInfo 1`] = ` +Object { + "#num_children": 1, + "#state_ph": "0x985a1f057d5047b1dee392127eb776571fbbe79da7ae6114f8f8f18c4f786135", + "#tree_bytes": 1840, + "#tree_height": 2, + "#tree_max_siblings": 1, + "#tree_size": 3, + "#version": "erased", +} +`; + exports[`ain-js Database matchFunction 1`] = ` Object { "matched_config": Object { diff --git a/__tests__/ain.test.ts b/__tests__/ain.test.ts index 4d56315..1689557 100644 --- a/__tests__/ain.test.ts +++ b/__tests__/ain.test.ts @@ -3,7 +3,7 @@ import Ain from '../src/ain'; import Wallet from '../src/wallet'; import { TransactionBody, SetOperation, TransactionInput } from '../src/types'; import axios from 'axios'; -import { fail, eraseProtoVer } from './test_util'; +import { fail, eraseProtoVer, eraseStateVersion } from './test_util'; const { test_keystore, test_pw, @@ -73,6 +73,13 @@ describe('ain-js', function() { }); }); + describe('Provider', function() { + it('getAddress', async function() { + const address = await ain.provider.getAddress(); + expect(address).not.toBeNull(); + }); + }); + describe('Wallet', function() { it('countDecimals', function() { expect(Wallet.countDecimals(0)).toBe(0); // '0' @@ -267,6 +274,16 @@ describe('ain-js', function() { expect(balance).toBeGreaterThan(0); }); + it('getNonce', async function() { + const nonce = await ain.wallet.getNonce(); + expect(nonce).toBe(0); + }); + + it('getTimestamp', async function() { + const timestamp = await ain.wallet.getTimestamp(); + expect(timestamp).toBe(0); + }); + it('transfer with isDryrun = true', async function() { const balanceBefore = await ain.wallet.getBalance(); const response = await ain.wallet.transfer({ @@ -1262,6 +1279,17 @@ describe('ain-js', function() { }) }); + it('getStateInfo', async function() { + await ain.db.ref('/rules/transfer/$from/$to/$key/value').getStateInfo() + .then(res => { + expect(eraseStateVersion(res)).toMatchSnapshot(); + }) + .catch(error => { + console.log("error:", error); + fail('should not happen'); + }) + }); + /*it('on and off', function(done) { try { ain.db.ref().on('value', (snap:any) => console.log) diff --git a/__tests__/test_util.ts b/__tests__/test_util.ts index 473ad7a..8b9dd47 100644 --- a/__tests__/test_util.ts +++ b/__tests__/test_util.ts @@ -1,6 +1,16 @@ +import { set } from 'lodash'; + export declare function fail(error?: any): never; -export function eraseProtoVer(retVal) { - retVal.protoVer = 'erased'; - return retVal; +export function eraseProtoVer(result) { + const erased = JSON.parse(JSON.stringify(result)); + set(erased, 'protoVer', 'erased'); + return erased; +} + +export function eraseStateVersion(result) { + const erased = JSON.parse(JSON.stringify(result)); + set(erased, '#version', 'erased'); + return erased; } + diff --git a/src/ain-db/ref.ts b/src/ain-db/ref.ts index 16660f6..43ac5d5 100755 --- a/src/ain-db/ref.ts +++ b/src/ain-db/ref.ts @@ -372,6 +372,18 @@ export default class Reference { return this._ain.provider.send('ain_getProofHash', request); } + /** + * Fetches the state information of a global blockchain state path. + * @param {StateInfoInput} params The state info input. + * @returns {Promise} The return value of the blockchain API. + */ + getStateInfo(params?: StateInfoInput): Promise { + const request = { + ref: Reference.extendPath(this.path, params ? params.ref : undefined) + } + return this._ain.provider.send('ain_getStateInfo', request); + } + // TODO(liayoo): Add this function. ///** // * Attaches an listener for database events. diff --git a/src/provider.ts b/src/provider.ts index e1ec746..247a80e 100644 --- a/src/provider.ts +++ b/src/provider.ts @@ -37,6 +37,14 @@ export default class Provider { this.httpClient = axios.create(axiosConfig); } + /** + * Fetches the blockchain node's address. + * @returns {Promise} The address value. + */ + getAddress(): Promise { + return this.send('ain_getAddress', {}) + } + /** * Creates a JSON-RPC payload and sends it to the network. * @param {string} rpcMethod The JSON-RPC method. diff --git a/src/signer/default-signer.ts b/src/signer/default-signer.ts index cfa5a89..014f3bf 100644 --- a/src/signer/default-signer.ts +++ b/src/signer/default-signer.ts @@ -124,31 +124,11 @@ export class DefaultSigner implements Signer { } let nonce = transactionInput.nonce; if (nonce === undefined) { - nonce = await this.getNonce({ address, from: "pending" }); + nonce = await this.wallet.getNonce({ address, from: "pending" }); } const timestamp = transactionInput.timestamp ? transactionInput.timestamp : Date.now(); const gasPrice = transactionInput.gas_price || 0; const billing = transactionInput.billing; return Object.assign(tx, { nonce, timestamp, gas_price: gasPrice, billing }); } - - /** - * Fetches an account's nonce value, which is the current transaction count of the account. - * @param {object} args The ferch options. - * It may contain a string 'address' value and a string 'from' value. - * The 'address' is the address of the account to get the nonce of, - * and the 'from' is the source of the data. - * It could be either the pending transaction pool ("pending") or - * the committed blocks ("committed"). The default value is "committed". - * @returns {Promise} The nonce value. - */ - getNonce(args: { address?: string, from?: string }): Promise { - if (!args) { args = {}; } - const address = args.address ? Ain.utils.toChecksumAddress(args.address) - : this.getAddress(args.address); - if (args.from !== undefined && args.from !== 'pending' && args.from !== 'committed') { - throw Error("'from' should be either 'pending' or 'committed'"); - } - return this.provider.send('ain_getNonce', { address, from: args.from }) - } -} \ No newline at end of file + }; diff --git a/src/wallet.ts b/src/wallet.ts index d5ca73c..12512e2 100755 --- a/src/wallet.ts +++ b/src/wallet.ts @@ -248,6 +248,46 @@ export default class Wallet { return this.ain.db.ref(`/accounts/${addr}/balance`).getValue(); } + /** + * Fetches an account's nonce value, which is the current transaction count of the account. + * @param {object} args The ferch options. + * It may contain a string 'address' value and a string 'from' value. + * The 'address' is the address of the account to get the nonce of, + * and the 'from' is the source of the data. + * It could be either the pending transaction pool ("pending") or + * the committed blocks ("committed"). The default value is "committed". + * @returns {Promise} The nonce value. + */ + getNonce(args: { address?: string, from?: string }): Promise { + if (!args) { args = {}; } + const address = args.address ? Ain.utils.toChecksumAddress(args.address) + : this.getImpliedAddress(args.address); + if (args.from !== undefined && args.from !== 'pending' && args.from !== 'committed') { + throw Error("'from' should be either 'pending' or 'committed'"); + } + return this.ain.provider.send('ain_getNonce', { address, from: args.from }) + } + + /** + * Fetches an account's timestamp value, which is the current transaction count of the account. + * @param {object} args The ferch options. + * It may contain a string 'address' value and a string 'from' value. + * The 'address' is the address of the account to get the timestamp of, + * and the 'from' is the source of the data. + * It could be either the pending transaction pool ("pending") or + * the committed blocks ("committed"). The default value is "committed". + * @returns {Promise} The timestamp value. + */ + getTimestamp(args: { address?: string, from?: string }): Promise { + if (!args) { args = {}; } + const address = args.address ? Ain.utils.toChecksumAddress(args.address) + : this.getImpliedAddress(args.address); + if (args.from !== undefined && args.from !== 'pending' && args.from !== 'committed') { + throw Error("'from' should be either 'pending' or 'committed'"); + } + return this.ain.provider.send('ain_getTimestamp', { address, from: args.from }) + } + /** * Sends a transfer transaction to the network. * @param {{to: string, value: number, from?: string, nonce?: number, gas_price?: number}} input The input parameters of the transaction.