@ethersproject/abstract-provider#Filter TypeScript Examples
The following examples show how to use
@ethersproject/abstract-provider#Filter.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: logs.ts From bodhi.js with Apache License 2.0 | 6 votes |
getLogsQueryFilter = (filter: Filter): string => {
const { fromBlock, toBlock, address, topics } = filter;
if (!isAnyDefined([fromBlock, toBlock, address, topics])) {
return '';
}
const addressFilter = _getAddressFilter(address);
const blockNumberFilter = _getBlockNumberFilter(fromBlock, toBlock);
const topicsFilter = _getTopicsFilter(topics);
const queryFilter = `(filter: {
${addressFilter}
${blockNumberFilter}
${topicsFilter}
})`;
return queryFilter;
}
Example #2
Source File: subqlProvider.ts From bodhi.js with Apache License 2.0 | 6 votes |
getFilteredLogs = async (filter: Filter & FilterByBlockHash): Promise<Log[]> => {
const queryFilter = getLogsQueryFilter(filter);
const res = await this.queryGraphql(`
query {
logs${queryFilter} {
${LOGS_NODES}
}
}
`);
return adaptLogs(res.logs!.nodes as LogGQL[]);
};
Example #3
Source File: useRawLogs.ts From useDApp with MIT License | 6 votes |
/**
* @public
*/
export function useRawLogs(
filter: Filter | FilterByBlockHash | Promise<Filter | FilterByBlockHash> | Falsy,
queryParams: QueryParams = {}
): Log[] | undefined {
const { library } = useEthers()
const providers = useReadonlyNetworks()
const _blockNumber = useBlockNumber()
const blockNumbers = useBlockNumbers()
const [logs, setLogs] = useState<Log[] | undefined>()
const { chainId } = queryParams
const [provider, blockNumber] = useMemo(
() => (chainId ? [providers[chainId], blockNumbers[chainId]] : [library, _blockNumber]),
[providers, library, blockNumbers, _blockNumber, chainId]
)
async function updateLogs() {
setLogs(!filter ? undefined : await provider?.getLogs(filter))
}
useEffect(() => {
void updateLogs()
}, [provider, blockNumber])
return logs
}
Example #4
Source File: Provider.ts From evm-provider.js with Apache License 2.0 | 6 votes |
/**
* Get an array of filtered logs from the chain's head.
* @param filter The filter to apply to the logs
* @returns A promise that resolves to an array of filtered logs
*/
async getLogs(filter: Filter): Promise<Array<Log>> {
if (!this.dataProvider) return this._fail('getLogs');
return this.dataProvider.getLogs(filter, this._resolveBlockNumber);
}
Example #5
Source File: base-provider.ts From bodhi.js with Apache License 2.0 | 5 votes |
// Bloom-filter Queries
getLogs = async (rawFilter: Filter & FilterByBlockHash): Promise<Log[]> => {
if (!this.subql) {
return logger.throwError(
'missing subql url to fetch logs, to initialize base provider with subql, please provide a subqlUrl param.'
);
}
const { fromBlock, toBlock, blockHash } = rawFilter;
const filter = { ...rawFilter };
if (blockHash && (fromBlock || toBlock)) {
return logger.throwError(
'`fromBlock` and `toBlock` is not allowed in params when `blockHash` is present',
Logger.errors.INVALID_ARGUMENT,
{
blockHash,
fromBlock,
toBlock
}
);
}
if (blockHash) {
const blockNumber = (await this._getBlockHeader(blockHash)).number.toNumber();
filter.fromBlock = blockNumber;
filter.toBlock = blockNumber;
} else {
const fromBlockNumber = await this._getBlockNumberFromTag(fromBlock ?? 'latest');
const toBlockNumber = await this._getBlockNumberFromTag(toBlock ?? 'latest');
filter.fromBlock = fromBlockNumber;
filter.toBlock = toBlockNumber;
}
const filteredLogs = await this.subql.getFilteredLogs(filter);
return filteredLogs.map((log) => this.formatter.filterLog(log));
};
Example #6
Source File: logs.ts From useDApp with MIT License | 5 votes |
/**
* @internal Intended for internal use - use it on your own risk
*/
export function encodeFilterData(
filter: TypedFilter | Falsy,
fromBlock?: BlockTag,
toBlock?: BlockTag,
blockHash?: string
): Filter | FilterByBlockHash | Falsy | Error {
if (!filter) {
return undefined
}
const { contract, event, args } = filter
if (!contract.address || !event) {
warnOnInvalidFilter(filter)
return undefined
}
try {
const encodedTopics = contract.interface.encodeFilterTopics((event as unknown) as utils.EventFragment, args)
if (blockHash) {
return {
address: contract.address,
topics: encodedTopics,
blockHash: blockHash,
} as FilterByBlockHash
} else {
return {
address: contract.address,
topics: encodedTopics,
fromBlock: fromBlock ?? 0,
toBlock: toBlock ?? 'latest',
} as Filter
}
} catch (e) {
if (e instanceof Error) {
return e as Error
} else {
warnOnInvalidFilter(filter)
return undefined
}
}
}
Example #7
Source File: logs.test.ts From useDApp with MIT License | 4 votes |
describe('encodeFilterData', () => {
const mockProvider = new MockProvider()
const [deployer] = mockProvider.getWallets()
let token: Contract
beforeEach(async () => {
token = await deployMockToken(deployer)
})
it('Returns undefined if the filter is undefined', () => {
expect(encodeFilterData(undefined)).to.be.undefined
})
it('Returns FilterByBlockHash when blockHash is valid', () => {
const filter: TypedFilter = {
contract: token,
event: 'Transfer',
args: [],
}
const encodedFilterData = encodeFilterData(filter, undefined, undefined, '0x0') as FilterByBlockHash
expect(encodedFilterData['blockHash']).to.not.be.undefined
})
it('Returns FilterByBlockHash when blockHash, toBlock, and fromBlock are valid', () => {
const filter: TypedFilter = {
contract: token,
event: 'Transfer',
args: [],
}
const encodedFilterData = encodeFilterData(filter, 0, 'latest', '0x0') as FilterByBlockHash
expect(encodedFilterData['blockHash']).to.not.be.undefined
})
it('Returns Filter when toBlock and fromBlock are valid but blockHash is invalid', () => {
const filter: TypedFilter = {
contract: token,
event: 'Transfer',
args: [],
}
const encodedFilterData = encodeFilterData(filter, 0, 'latest', undefined) as Filter
expect(encodedFilterData['toBlock']).to.not.be.undefined
})
it('Returns an error when passed a non-existant event', () => {
const filter: TypedFilter = {
contract: token,
event: 'Transfer2',
args: [],
}
const encodedFilterData = encodeFilterData(filter, 0, 'latest')
expect(encodedFilterData).to.be.a('Error')
})
it('Returns an error when passed an arg for an un-indexed parameter', () => {
const filter: TypedFilter = {
contract: token,
event: 'Transfer',
args: [AddressZero, AddressZero, 10],
}
const encodedFilterData = encodeFilterData(filter, 0, 'latest')
expect(encodedFilterData).to.be.a('Error')
})
it('Returns an error when passed too many args', () => {
const filter: TypedFilter = {
contract: token,
event: 'Transfer',
args: [AddressZero, AddressZero, null, AddressZero],
}
const encodedFilterData = encodeFilterData(filter, 0, 'latest')
expect(encodedFilterData).to.be.a('Error')
})
})
Example #8
Source File: useRawLogs.test.ts From useDApp with MIT License | 4 votes |
describe('useRawLogs', () => {
const mockProvider = new MockProvider()
const secondMockProvider = new MockProvider({ ganacheOptions: { _chainIdRpc: SECOND_TEST_CHAIN_ID } as any })
const [deployer, receiver] = mockProvider.getWallets()
const [secondDeployer] = secondMockProvider.getWallets()
const eventTopic = ethers.utils.id('Transfer(address,address,uint256)')
let token: Contract
let secondToken: Contract
beforeEach(async () => {
token = await deployMockToken(deployer)
secondToken = await deployMockToken(secondDeployer, SECOND_MOCK_TOKEN_INITIAL_BALANCE)
})
async function sendToken(signer: ethers.Wallet, to: string, amount: BigNumber) {
const { result, waitForCurrent, waitForNextUpdate } = await renderWeb3Hook(
() =>
useSendTransaction({
signer,
}),
{ mockProvider }
)
await waitForNextUpdate()
const txData = ERC20MockInterface.encodeFunctionData('transfer(address,uint)', [to, amount])
const tx: TransactionRequest = {
to: token.address,
value: BigNumber.from(0),
data: txData,
gasPrice: 0,
}
await result.current.sendTransaction(tx)
await waitForCurrent((val) => val.state !== undefined)
expect(result.current.state.status).to.eq('Success')
}
function extractAddress(address: string) {
let result: string
result = hexStripZeros(address)
while (result.length != 42) result = '0x0' + result.substring(2)
return result
}
it('Can get only the recent token transfer log', async () => {
const blockNumber = await mockProvider.getBlockNumber()
const from = deployer
const to = receiver
const fromAddress = from.address
const toAddress = to.address
const amount = BigNumber.from(1)
await sendToken(from, toAddress, amount)
const filter: Filter = {
address: token.address,
fromBlock: blockNumber + 1,
toBlock: blockNumber + 2,
topics: [eventTopic],
}
const { result, waitForCurrent } = await renderWeb3Hook(() => useRawLogs(filter), { mockProvider })
await waitForCurrent((val) => val !== undefined)
expect(result.error).to.be.undefined
expect(result.current?.length).to.equal(1, 'Number of logs')
const log = result.current![0]
expect(log.topics[0]).to.equal(eventTopic, 'Event topic')
expect(getAddress(extractAddress(log.topics[1]))).to.equal(getAddress(fromAddress), 'From')
expect(getAddress(extractAddress(log.topics[2]))).to.equal(getAddress(toAddress), 'To')
const decodedData = defaultAbiCoder.decode(['uint'], log.data)
expect(decodedData[0]).to.equal(amount, 'Amount')
})
it('Can get all token transfer logs', async () => {
const from = deployer
const to = receiver
const fromAddress = from.address
const toAddress = to.address
const amount = BigNumber.from(1)
await sendToken(from, toAddress, amount)
const filter: Filter = {
address: token.address,
fromBlock: 0,
toBlock: 'latest',
topics: [eventTopic],
}
const { result, waitForCurrent } = await renderWeb3Hook(() => useRawLogs(filter), { mockProvider })
await waitForCurrent((val) => val !== undefined)
expect(result.error).to.be.undefined
expect(result.current?.length).to.equal(2, 'Number of logs')
// Mint transfer event
const log1 = result.current![0]
expect(log1.topics[0]).to.equal(eventTopic, 'Event topic')
expect(getAddress(extractAddress(log1.topics[1]))).to.equal(getAddress(AddressZero), 'From')
expect(getAddress(extractAddress(log1.topics[2]))).to.equal(getAddress(deployer.address), 'To')
const decodedData1 = defaultAbiCoder.decode(['uint'], log1.data)
expect(decodedData1[0]).to.equal(MOCK_TOKEN_INITIAL_BALANCE, 'Amount')
// Recent transfer transaction log
const log = result.current![1]
expect(log.topics[0]).to.equal(eventTopic, 'Event topic')
expect(getAddress(extractAddress(log.topics[1]))).to.equal(getAddress(fromAddress), 'From')
expect(getAddress(extractAddress(log.topics[2]))).to.equal(getAddress(toAddress), 'To')
const decodedData = defaultAbiCoder.decode(['uint'], log.data)
expect(decodedData[0]).to.equal(amount, 'Amount')
})
it('Can get the mint transfer log', async () => {
const filter: Filter = {
address: token.address,
fromBlock: 0,
toBlock: 'latest',
topics: [eventTopic],
}
const { result, waitForCurrent } = await renderWeb3Hook(() => useRawLogs(filter), { mockProvider })
await waitForCurrent((val) => val !== undefined)
expect(result.error).to.be.undefined
expect(result.current?.length).to.equal(1, 'Number of logs')
const log = result.current![0]
expect(log.topics[0]).to.equal(eventTopic, 'Event topic')
expect(getAddress(extractAddress(log.topics[1]))).to.equal(getAddress(AddressZero), 'From')
expect(getAddress(extractAddress(log.topics[2]))).to.equal(getAddress(deployer.address), 'To')
const decodedData = defaultAbiCoder.decode(['uint'], log.data)
expect(decodedData[0]).to.equal(MOCK_TOKEN_INITIAL_BALANCE, 'Amount')
})
it('Can get the mint transfer log on the alternative chain', async () => {
const filter: Filter = {
address: secondToken.address,
fromBlock: 0,
toBlock: 'latest',
topics: [eventTopic],
}
const { result, waitForCurrent } = await renderWeb3Hook(() => useRawLogs(filter), {
mockProvider: secondMockProvider,
})
await waitForCurrent((val) => val !== undefined)
expect(result.error).to.be.undefined
expect(result.current?.length).to.equal(1, 'Number of logs')
const log = result.current![0]
expect(log.topics[0]).to.equal(eventTopic, 'Event topic')
expect(getAddress(extractAddress(log.topics[1]))).to.equal(getAddress(AddressZero), 'From')
expect(getAddress(extractAddress(log.topics[2]))).to.equal(getAddress(secondDeployer.address), 'To')
const decodedData = defaultAbiCoder.decode(['uint'], log.data)
expect(decodedData[0]).to.equal(SECOND_MOCK_TOKEN_INITIAL_BALANCE, 'Amount')
})
it('Works if there are no logs', async () => {
const filter: Filter = {
address: secondToken.address, // Token on the other chain... doesn't exist so there should be no logs
fromBlock: 0,
toBlock: 'latest',
topics: [eventTopic],
}
const { result, waitForCurrent } = await renderWeb3Hook(() => useRawLogs(filter), { mockProvider })
await waitForCurrent((val) => val !== undefined)
expect(result.error).to.be.undefined
expect(result.current?.length).to.equal(0, 'Number of logs')
})
})