diff --git a/src/api/routes/contract.ts b/src/api/routes/contract.ts index bc6e501e..71a60077 100644 --- a/src/api/routes/contract.ts +++ b/src/api/routes/contract.ts @@ -28,7 +28,11 @@ export function createContractRouter(db: DataStore): RouterWithAsync { res.status(404).json({ error: `cannot find contract for this trait` }); return; } - res.json({ limit, offset, results: smartContracts.result }); + const contractResults = smartContracts.result.map(contract => ({ + ...contract, + abi: JSON.stringify(contract.abi), + })); + res.json({ limit, offset, results: contractResults }); }); router.getAsync('/:contract_id', async (req, res) => { @@ -38,7 +42,11 @@ export function createContractRouter(db: DataStore): RouterWithAsync { res.status(404).json({ error: `cannot find contract by ID ${contract_id}` }); return; } - res.json(contractQuery.result); + const contractResult = { + ...contractQuery.result, + abi: JSON.stringify(contractQuery.result.abi), + }; + res.json(contractResult); }); router.getAsync('/:contract_id/events', async (req, res) => { diff --git a/src/datastore/common.ts b/src/datastore/common.ts index dccaca5e..bb3cb85a 100644 --- a/src/datastore/common.ts +++ b/src/datastore/common.ts @@ -235,6 +235,7 @@ export interface DbSmartContract { contract_id: string; block_height: number; source_code: string; + // TODO: this appears to be a parsed JSON object now when returned from the sql query abi: string; } diff --git a/src/tests/api-tests.ts b/src/tests/api-tests.ts index 09040811..8587f3fd 100644 --- a/src/tests/api-tests.ts +++ b/src/tests/api-tests.ts @@ -5100,6 +5100,103 @@ describe('api tests', () => { }); }); + test('get contract by ID', async () => { + const block1: DbBlock = { + block_hash: '0x1234', + index_block_hash: '0xdeadbeef', + parent_index_block_hash: '0x00', + parent_block_hash: '0xff0011', + parent_microblock_hash: '', + parent_microblock_sequence: 0, + block_height: 1, + burn_block_time: 1594647996, + burn_block_hash: '0x1234', + burn_block_height: 123, + miner_txid: '0x4321', + canonical: true, + execution_cost_read_count: 0, + execution_cost_read_length: 0, + execution_cost_runtime: 0, + execution_cost_write_count: 0, + execution_cost_write_length: 0, + }; + const txId1 = '0x421234'; + const smartContract1: DbSmartContract = { + tx_id: txId1, + canonical: true, + block_height: block1.block_height, + contract_id: 'some-contract-id', + source_code: '(some-contract-src)', + abi: '{"some-abi":1}', + }; + const tx1: DbTx = { + tx_id: txId1, + tx_index: 0, + anchor_mode: 3, + nonce: 0, + raw_tx: Buffer.alloc(0), + index_block_hash: '0x1234', + block_hash: '0x5678', + block_height: block1.block_height, + burn_block_time: 1594647995, + parent_burn_block_time: 1626122935, + type_id: DbTxTypeId.SmartContract, + status: 1, + raw_result: '0x0100000000000000000000000000000001', // u1 + canonical: true, + microblock_canonical: true, + microblock_sequence: I32_MAX, + microblock_hash: '', + parent_index_block_hash: '', + parent_block_hash: '', + post_conditions: Buffer.from([]), + fee_rate: 1234n, + sponsored: false, + sponsor_address: undefined, + sender_address: 'sender-addr', + origin_hash_mode: 1, + smart_contract_contract_id: smartContract1.contract_id, + smart_contract_source_code: smartContract1.source_code, + event_count: 0, + execution_cost_read_count: 0, + execution_cost_read_length: 0, + execution_cost_runtime: 0, + execution_cost_write_count: 0, + execution_cost_write_length: 0, + }; + + await db.update({ + block: block1, + microblocks: [], + minerRewards: [], + txs: [ + { + tx: tx1, + stxLockEvents: [], + stxEvents: [], + ftEvents: [], + nftEvents: [], + contractLogEvents: [], + smartContracts: [smartContract1], + names: [], + namespaces: [], + }, + ], + }); + + const fetchTx = await supertest(api.server).get('/extended/v1/contract/some-contract-id'); + expect(fetchTx.status).toBe(200); + expect(fetchTx.type).toBe('application/json'); + expect(JSON.parse(fetchTx.text)).toEqual({ + tx_id: '0x421234', + canonical: true, + contract_id: 'some-contract-id', + block_height: 1, + source_code: '(some-contract-src)', + abi: '{"some-abi":1}', + }); + }); + test('list contract with given trait', async () => { const block1: DbBlock = { block_hash: '0x1235', @@ -6278,7 +6375,7 @@ describe('api tests', () => { `/extended/v1/contract/by_trait?trait_abi=${JSON.stringify(traitJsonAbiRequest)}` ); expect(query.status).toBe(200); - expect(query.body.results[0].abi).toStrictEqual(contractJsonAbi); + expect(JSON.parse(query.body.results[0].abi)).toStrictEqual(contractJsonAbi); const traitJsonAbiRequest1 = { maps: [],