diff --git a/__tests__/integration/nano-contracts.test.js b/__tests__/integration/nano-contracts.test.js index 17bae607..28ebb0c8 100644 --- a/__tests__/integration/nano-contracts.test.js +++ b/__tests__/integration/nano-contracts.test.js @@ -255,5 +255,63 @@ describe('nano contract routes', () => { for (const tx of responseHistory2.body.history) { expect(txIds).toContain(tx.hash); } + + // Get state in an old block hash, after the second bet + const responseStateOld = await TestUtils.request + .get('/wallet/nano-contracts/state') + .query({ id: tx1.hash, + fields: [ + 'token_uid', + 'total', + 'final_result', + 'oracle_script', + 'date_last_bet', + `address_details.a'${address2}'`, + `withdrawals.a'${address2}'`, + `address_details.a'${address3}'`, + `withdrawals.a'${address3}'` + ], + block_hash: responseHistory2.body.history[2].first_block }) + .set({ 'x-wallet-id': wallet.walletId }); + const ncStateOld = responseStateOld.body.state; + expect(ncStateOld.fields.token_uid.value).toBe(HATHOR_TOKEN_ID); + expect(ncStateOld.fields.date_last_bet.value).toBe(dateLastBet); + expect(ncStateOld.fields.oracle_script.value).toBe( + bufferUtils.bufferToHex(outputScriptBuffer1) + ); + expect(ncStateOld.fields.final_result.value).toBeNull(); + expect(ncStateOld.fields.total.value).toBe(300); + expect(ncStateOld.fields[`address_details.a'${address2}'`].value).toHaveProperty('1x0', 100); + expect(ncStateOld.fields[`withdrawals.a'${address2}'`].value).toBeUndefined(); + expect(ncStateOld.fields[`address_details.a'${address3}'`].value).toHaveProperty('2x0', 200); + expect(ncStateOld.fields[`withdrawals.a'${address3}'`].value).toBeUndefined(); + + // Now we will test the history with pagination + const history2 = responseHistory2.body.history; + + // Get history with count 2 + const responseHistory3 = await TestUtils.request + .get('/wallet/nano-contracts/history') + .query({ id: tx1.hash, count: 2 }) + .set({ 'x-wallet-id': wallet.walletId }); + expect(responseHistory3.body.history.length).toBe(2); + expect(responseHistory3.body.history).toStrictEqual([history2[0], history2[1]]); + + // Now the next page with after + const responseHistory4 = await TestUtils.request + .get('/wallet/nano-contracts/history') + .query({ id: tx1.hash, count: 2, after: responseHistory3.body.history[1].hash }) + .set({ 'x-wallet-id': wallet.walletId }); + expect(responseHistory4.body.history.length).toBe(2); + expect(responseHistory4.body.history).toStrictEqual([history2[2], history2[3]]); + + // Now the previous page with before + const responseHistory5 = await TestUtils.request + .get('/wallet/nano-contracts/history') + .query({ id: tx1.hash, count: 2, before: responseHistory4.body.history[0].hash }) + .set({ 'x-wallet-id': wallet.walletId }); + expect(responseHistory5.body.history.length).toBe(2); + // When using before, the order comes reverted + expect(responseHistory5.body.history).toStrictEqual([history2[1], history2[0]]); }); }); diff --git a/src/api-docs.js b/src/api-docs.js index 877abb2a..72973015 100644 --- a/src/api-docs.js +++ b/src/api-docs.js @@ -3750,6 +3750,24 @@ const defaultApiDocs = { }, } }, + { + name: 'block_hash', + in: 'query', + description: 'Hash of the block to get the state.', + required: false, + schema: { + type: 'string', + }, + }, + { + name: 'block_height', + in: 'query', + description: 'Height of the block to get the state.', + required: false, + schema: { + type: 'integer', + }, + }, ], responses: { 200: { @@ -3828,6 +3846,15 @@ const defaultApiDocs = { type: 'string', }, }, + { + name: 'before', + in: 'query', + description: 'Hash of transaction to offset the result for previous transactions.', + required: false, + schema: { + type: 'string', + }, + }, ], responses: { 200: { diff --git a/src/controllers/wallet/nano-contracts.controller.js b/src/controllers/wallet/nano-contracts.controller.js index b14e7892..9eec5088 100644 --- a/src/controllers/wallet/nano-contracts.controller.js +++ b/src/controllers/wallet/nano-contracts.controller.js @@ -21,10 +21,24 @@ async function getState(req, res) { return; } - const { id, fields, balances, calls } = req.query; + const { + id, + fields, + balances, + calls, + block_hash: blockHash, + block_height: blockHeight + } = req.query; try { - const state = await ncApi.getNanoContractState(id, fields, balances, calls); + const state = await ncApi.getNanoContractState( + id, + fields, + balances, + calls, + blockHash, + blockHeight + ); res.send({ success: true, @@ -45,10 +59,10 @@ async function getHistory(req, res) { return; } - const { id, count, after } = req.query; + const { id, count, after, before } = req.query; try { - const data = await ncApi.getNanoContractHistory(id, count, after); + const data = await ncApi.getNanoContractHistory(id, count, after, before); res.send({ success: true, diff --git a/src/routes/wallet/nano-contracts.routes.js b/src/routes/wallet/nano-contracts.routes.js index 776570a7..ce6377bc 100644 --- a/src/routes/wallet/nano-contracts.routes.js +++ b/src/routes/wallet/nano-contracts.routes.js @@ -30,6 +30,8 @@ nanoContractRouter.get( query('fields').isArray().optional().default([]), query('balances').isArray().optional().default([]), query('calls').isArray().optional().default([]), + query('block_hash').isString().optional(), + query('block_height').isInt({ min: 0 }).optional().toInt(), getState ); @@ -68,6 +70,7 @@ nanoContractRouter.get( query('id').isString(), query('count').isInt({ min: 0 }).optional().toInt(), query('after').isString().optional(), + query('before').isString().optional(), getHistory );