Skip to content

Commit 0da7efd

Browse files
committed
feat: added paginated function to getContractState
Signed-off-by: Logan Nguyen <logan.nguyen@swirldslabs.com>
1 parent c43c8b0 commit 0da7efd

File tree

3 files changed

+78
-14
lines changed

3 files changed

+78
-14
lines changed

packages/relay/src/lib/clients/mirrorNodeClient.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1214,7 +1214,13 @@ export class MirrorNodeClient {
12141214
MirrorNodeClient.ADDRESS_PLACEHOLDER,
12151215
address,
12161216
);
1217-
return this.get(`${apiEndpoint}${queryParams}`, MirrorNodeClient.CONTRACT_ADDRESS_STATE_ENDPOINT, requestDetails);
1217+
1218+
return this.getPaginatedResults(
1219+
`${apiEndpoint}${queryParams}`,
1220+
MirrorNodeClient.CONTRACT_ADDRESS_STATE_ENDPOINT,
1221+
'state',
1222+
requestDetails,
1223+
);
12181224
}
12191225

12201226
public async getContractStateByAddressAndSlot(

packages/relay/src/lib/debug.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import {
1818
ICallTracerConfig,
1919
IOpcodeLoggerConfig,
2020
ITracerConfig,
21-
ITracerConfigWrapper,
2221
MirrorNodeContractResult,
2322
ParamType,
2423
RequestDetails,
@@ -541,7 +540,7 @@ export class DebugImpl implements Debug {
541540
this.mirrorNodeClient.getContractState(contractId, requestDetails, timestamp),
542541
]);
543542

544-
const storageMap = stateResponse.state.reduce((map, stateItem) => {
543+
const storageMap = stateResponse.reduce((map, stateItem) => {
545544
map[stateItem.slot] = stateItem.value;
546545
return map;
547546
}, {});

packages/relay/tests/lib/mirrorNodeClient.spec.ts

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,27 +1798,25 @@ describe('MirrorNodeClient', async function () {
17981798
mock.onGet(contractStatePath).reply(200, JSON.stringify(mockContractState));
17991799
const result = await mirrorNodeInstance.getContractState(contractAddress, requestDetails);
18001800
expect(result).to.exist;
1801-
expect(result.state).to.exist;
1802-
expect(result.state.length).to.equal(2);
1803-
expect(result.state[0].address).to.equal(contractAddress);
1804-
expect(result.state[0].slot).to.equal(mockContractState.state[0].slot);
1805-
expect(result.state[0].value).to.equal(mockContractState.state[0].value);
1801+
expect(result.length).to.equal(2);
1802+
expect(result[0].address).to.equal(contractAddress);
1803+
expect(result[0].slot).to.equal(mockContractState.state[0].slot);
1804+
expect(result[0].value).to.equal(mockContractState.state[0].value);
18061805
});
18071806

18081807
it('should fetch contract state with blockEndTimestamp', async () => {
18091808
mock.onGet(contractStatePathWithTimestamp).reply(200, JSON.stringify(mockContractState));
18101809
const result = await mirrorNodeInstance.getContractState(contractAddress, requestDetails, blockEndTimestamp);
18111810
expect(result).to.exist;
1812-
expect(result.state).to.exist;
1813-
expect(result.state.length).to.equal(2);
1814-
expect(result.state[0].address).to.equal(contractAddress);
1815-
expect(result.state[0].timestamp).to.equal(blockEndTimestamp);
1811+
expect(result.length).to.equal(2);
1812+
expect(result[0].address).to.equal(contractAddress);
1813+
expect(result[0].timestamp).to.equal(blockEndTimestamp);
18161814
});
18171815

1818-
it('should return null when contract state is not found', async () => {
1816+
it('should return empty array when contract state is not found', async () => {
18191817
mock.onGet(contractStatePath).reply(404, JSON.stringify(mockData.notFound));
18201818
const result = await mirrorNodeInstance.getContractState(contractAddress, requestDetails);
1821-
expect(result).to.be.null;
1819+
expect(result).to.be.empty;
18221820
});
18231821

18241822
it('should throw error for invalid contract address', async () => {
@@ -1845,5 +1843,66 @@ describe('MirrorNodeClient', async function () {
18451843
}
18461844
expect(errorRaised).to.be.true;
18471845
});
1846+
1847+
it('should handle pagination and consolidate results from multiple pages', async () => {
1848+
// Mock first page with a next link
1849+
const firstPageResponse = {
1850+
state: [
1851+
{
1852+
address: contractAddress,
1853+
contract_id: '0.0.5001',
1854+
timestamp: '1653077541.983983199',
1855+
slot: '0x0000000000000000000000000000000000000000000000000000000000000101',
1856+
value: '0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925',
1857+
},
1858+
{
1859+
address: contractAddress,
1860+
contract_id: '0.0.5001',
1861+
timestamp: '1653077541.983983199',
1862+
slot: '0x0000000000000000000000000000000000000000000000000000000000000102',
1863+
value: '0x9c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b926',
1864+
},
1865+
],
1866+
links: {
1867+
next: '/api/v1/contracts/results/0x7e08d3df45823dc56298a9a097f8cb9bde2f99c4e114b569a9aff3eb227e4d23/actions?limit=2&order=desc&index=lt:8',
1868+
},
1869+
};
1870+
1871+
// Mock second page with no next link (final page)
1872+
const secondPageResponse = {
1873+
state: [
1874+
{
1875+
address: contractAddress,
1876+
contract_id: '0.0.5001',
1877+
timestamp: '1653077541.983983199',
1878+
slot: '0x0000000000000000000000000000000000000000000000000000000000000103',
1879+
value: '0xac5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b927',
1880+
},
1881+
],
1882+
links: {
1883+
next: null,
1884+
},
1885+
};
1886+
1887+
// Setup mocks for both pages
1888+
mock.onGet(contractStatePath).reply(200, JSON.stringify(firstPageResponse));
1889+
mock
1890+
.onGet(
1891+
'contracts/results/0x7e08d3df45823dc56298a9a097f8cb9bde2f99c4e114b569a9aff3eb227e4d23/actions?limit=2&order=desc&index=lt:8',
1892+
)
1893+
.reply(200, JSON.stringify(secondPageResponse));
1894+
1895+
// Call the method
1896+
const result = await mirrorNodeInstance.getContractState(contractAddress, requestDetails);
1897+
1898+
// Verify the results are merged correctly
1899+
expect(result).to.exist;
1900+
expect(result.length).to.equal(3);
1901+
expect(result[0].address).to.equal(contractAddress);
1902+
expect(result[0].slot).to.equal(firstPageResponse.state[0].slot);
1903+
expect(result[0].value).to.equal(firstPageResponse.state[0].value);
1904+
expect(result[2].slot).to.equal(secondPageResponse.state[0].slot);
1905+
expect(result[2].value).to.equal(secondPageResponse.state[0].value);
1906+
});
18481907
});
18491908
});

0 commit comments

Comments
 (0)