From f2156b425affd47dc09cc2047594eb12353045a4 Mon Sep 17 00:00:00 2001 From: Michael Xiao Date: Tue, 18 Feb 2025 10:47:18 -0500 Subject: [PATCH] Integrate with ETHEREUM_CL_INDEXER --- .changeset/fifty-suits-breathe.md | 5 ++ .../composites/proof-of-reserves/README.md | 65 ++++++++++--------- .../proof-of-reserves/schemas/env.json | 3 + .../proof-of-reserves/src/config/index.ts | 8 ++- .../src/endpoint/reserves.ts | 4 ++ .../src/utils/addressValidator.ts | 2 +- .../proof-of-reserves/src/utils/balance.ts | 5 +- .../proof-of-reserves/src/utils/index.ts | 4 +- .../proof-of-reserves/src/utils/reduce.ts | 20 +++++- 9 files changed, 78 insertions(+), 38 deletions(-) create mode 100644 .changeset/fifty-suits-breathe.md diff --git a/.changeset/fifty-suits-breathe.md b/.changeset/fifty-suits-breathe.md new file mode 100644 index 0000000000..93107e29b4 --- /dev/null +++ b/.changeset/fifty-suits-breathe.md @@ -0,0 +1,5 @@ +--- +'@chainlink/proof-of-reserves-adapter': minor +--- + +Integrate with ETHEREUM_CL_INDEXER diff --git a/packages/composites/proof-of-reserves/README.md b/packages/composites/proof-of-reserves/README.md index 6468051e50..d0ed5e82e2 100644 --- a/packages/composites/proof-of-reserves/README.md +++ b/packages/composites/proof-of-reserves/README.md @@ -29,26 +29,27 @@ At least one of each of the following categories must be set as an environment v 2. An indexer adapter to retrieve account balances for each custodial address - | Required? | Name | Description | Options | Defaults to | - | :-------: | :------------------------------: | :----------------------------------------------------------: | :-----: | :---------: | - | | `ADA_BALANCE_ADAPTER_URL` | The location of a Ada balance external adapter | | | - | | `AMBERDATA_ADAPTER_URL` | The location of an Amberdata external adapter | | | - | | `AVALANCHE_PLATFORM_ADAPTER_URL` | The location of an Avalance Platform external adapter | | | - | | `BITCOIN_JSON_RPC_ADAPTER_URL` | The location of an Bitcoin JSON RPC external adapter | | | - | | `BLOCKCHAIN_COM_ADAPTER_URL` | The location of a Blockchain.com external adapter | | | - | | `BLOCKCHAIR_ADAPTER_URL` | The location of a Blockchair external adapter | | | - | | `BLOCKCYPHER_ADAPTER_URL` | The location of a Blockcypher external adapter | | | - | | `BTC_COM_ADAPTER_URL` | The location of a BTC.com external adapter | | | - | | `CRYPTOAPIS_ADAPTER_URL` | The location of a Crypto APIs external adapter | | | - | | `ETH_BALANCE_ADAPTER_URL` | The location of a EthBalance external adapter | | | - | | `ETH_BEACON_ADAPTER_URL` | The location of an ETH Beacon external adapter | | | - | | `LOTUS_ADAPTER_URL` | The location of a Lotus external adapter | | | - | | `POLKADOT_BALANCE_ADAPTER_URL` | The location of a Polkadot Balance external adapter | | | - | | `POR_INDEXER_ADAPTER_URL` | The location of a Proof-of-Reserves Indexer external adapter | | | - | | `SOCHAIN_ADAPTER_URL` | The location of a SoChain external adapter | | | - | | `STADER_BALANCE_ADAPTER_URL` | The location of a Stader Balance external adapter | | | - | | `TOKEN_BALANCE_ADAPTER_URL` | The location of a Token Balance external adapter | | | - | | `CEFFU_ADAPTER_URL` | The location of a Ceffu external adapter | | | + | Required? | Name | Description | Options | Defaults to | + | :-------: | :-------------------------------: | :----------------------------------------------------------: | :-----: | :---------: | + | | `ADA_BALANCE_ADAPTER_URL` | The location of a Ada balance external adapter | | | + | | `AMBERDATA_ADAPTER_URL` | The location of an Amberdata external adapter | | | + | | `AVALANCHE_PLATFORM_ADAPTER_URL` | The location of an Avalance Platform external adapter | | | + | | `BITCOIN_JSON_RPC_ADAPTER_URL` | The location of an Bitcoin JSON RPC external adapter | | | + | | `BLOCKCHAIN_COM_ADAPTER_URL` | The location of a Blockchain.com external adapter | | | + | | `BLOCKCHAIR_ADAPTER_URL` | The location of a Blockchair external adapter | | | + | | `BLOCKCYPHER_ADAPTER_URL` | The location of a Blockcypher external adapter | | | + | | `BTC_COM_ADAPTER_URL` | The location of a BTC.com external adapter | | | + | | `CRYPTOAPIS_ADAPTER_URL` | The location of a Crypto APIs external adapter | | | + | | `ETH_BALANCE_ADAPTER_URL` | The location of a EthBalance external adapter | | | + | | `ETH_BEACON_ADAPTER_URL` | The location of an ETH Beacon external adapter | | | + | | `LOTUS_ADAPTER_URL` | The location of a Lotus external adapter | | | + | | `POLKADOT_BALANCE_ADAPTER_URL` | The location of a Polkadot Balance external adapter | | | + | | `POR_INDEXER_ADAPTER_URL` | The location of a Proof-of-Reserves Indexer external adapter | | | + | | `SOCHAIN_ADAPTER_URL` | The location of a SoChain external adapter | | | + | | `STADER_BALANCE_ADAPTER_URL` | The location of a Stader Balance external adapter | | | + | | `TOKEN_BALANCE_ADAPTER_URL` | The location of a Token Balance external adapter | | | + | | `CEFFU_ADAPTER_URL` | The location of a Ceffu external adapter | | | + | | `ETHEREUM_CL_INDEXER_ADAPTER_URL` | The location of a Ethereum Cl Indexer | | | ## Running @@ -56,18 +57,18 @@ See the [Composite Adapter README](../README.md) for more information on how to ### Input Params -| Required? | Name | Description | Options | Defaults to | -| :-------: | :--------------------------------: | :--------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------: | -| ✅ | `protocol` | The protocol external adapter to use | `celsius_address_list`, `chain_reserve_wallet`, `coinbase_prime`, `coinbase_prime_eth` `gemini`,`moonbeam_address_list`, `multi_address_list`, `ignition_address_list`, `list`, `por_address_list`, `renvm`, `stader_address_list`, `swell_address_list`, `wbtc`, `wrapped` | | -| | `protocolEndpoint` | Optional endpoint for the protocol external adapter to use | | | -| ✅ | `indexer` | The indexer external adapter to use | `ada_balance`, `amberdata`, `avalanche_platform`, `bitcoin_json_rpc`, `blockchain_com`. `blockchair`, `blockcypher`, `btc_com`, `cryptoapis`, `eth_balance`, `eth_beacon`, `lotus`, `polkadot_balance`, `por_indexer`, `sochain`, `stader_balance`, `token_balance`, `ceffu` | | -| | `indexerEndpoint` | Optional endpoint for the indexer external adapter to use | | | -| | `indexerParams` | Additional param for indexer external adapter to use | | | -| | `confirmations` | The number of confirmations required for a transaction to be counted when getting an address balance | | 6 | -| | `addresses` | An array of addresses to get the balance from, when "protocol" is set to `list` | | | -| | `disableAddressValidation` | if this parameter is set to `true` address validation will be turned off | `true`, `false` | `false` | -| | `disableDuplicateAddressFiltering` | if this parameter is set to `true` duplicate address filtering will be turned off | `true`, `false` | `false` | -| | `description` | Optional human readable description on what this request is about | | | +| Required? | Name | Description | Options | Defaults to | +| :-------: | :--------------------------------: | :--------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------: | +| ✅ | `protocol` | The protocol external adapter to use | `celsius_address_list`, `chain_reserve_wallet`, `coinbase_prime`, `coinbase_prime_eth` `gemini`,`moonbeam_address_list`, `multi_address_list`, `ignition_address_list`, `list`, `por_address_list`, `renvm`, `stader_address_list`, `swell_address_list`, `wbtc`, `wrapped` | | +| | `protocolEndpoint` | Optional endpoint for the protocol external adapter to use | | | +| ✅ | `indexer` | The indexer external adapter to use | `ada_balance`, `amberdata`, `avalanche_platform`, `bitcoin_json_rpc`, `blockchain_com`. `blockchair`, `blockcypher`, `btc_com`, `cryptoapis`, `eth_balance`, `eth_beacon`, `lotus`, `polkadot_balance`, `por_indexer`, `sochain`, `stader_balance`, `token_balance`, `ceffu`, `ethereum_cl_indexer` | | +| | `indexerEndpoint` | Optional endpoint for the indexer external adapter to use | | | +| | `indexerParams` | Additional param for indexer external adapter to use | | | +| | `confirmations` | The number of confirmations required for a transaction to be counted when getting an address balance | | 6 | +| | `addresses` | An array of addresses to get the balance from, when "protocol" is set to `list` | | | +| | `disableAddressValidation` | if this parameter is set to `true` address validation will be turned off | `true`, `false` | `false` | +| | `disableDuplicateAddressFiltering` | if this parameter is set to `true` duplicate address filtering will be turned off | `true`, `false` | `false` | +| | `description` | Optional human readable description on what this request is about | | | Additionally the first underlying adapter in the sequence, in this case the protocol adapter, may have parameters. diff --git a/packages/composites/proof-of-reserves/schemas/env.json b/packages/composites/proof-of-reserves/schemas/env.json index fc4c34f072..b2734467e3 100644 --- a/packages/composites/proof-of-reserves/schemas/env.json +++ b/packages/composites/proof-of-reserves/schemas/env.json @@ -101,6 +101,9 @@ }, { "required": ["CEFFU_ADAPTER_URL"] + }, + { + "required": ["ETHEREUM_CL_INDEXER_ADAPTER_URL"] } ] } diff --git a/packages/composites/proof-of-reserves/src/config/index.ts b/packages/composites/proof-of-reserves/src/config/index.ts index 9140db0083..90f789abfa 100644 --- a/packages/composites/proof-of-reserves/src/config/index.ts +++ b/packages/composites/proof-of-reserves/src/config/index.ts @@ -1,6 +1,10 @@ import { Requester, util } from '@chainlink/ea-bootstrap' import { DefaultConfig } from '@chainlink/ea-bootstrap' -import { adaptersV2 as BalanceAdaptersV2, adaptersV3 as BalanceAdaptersV3 } from '../utils/balance' +import { + adaptersV2 as BalanceAdaptersV2, + adaptersV3 as BalanceAdaptersV3, + ETHEREUM_CL_INDEXER, +} from '../utils/balance' import { adaptersV2 as ProtocolAdaptersV2, adaptersV3 as ProtocolAdaptersV3, @@ -60,5 +64,7 @@ export const makeOptions = (): Options => { } options.protocol.push(LIST_ADAPTER) options.protocol.push(LIST_ADAPTER.toLowerCase()) + options.indexer.push(ETHEREUM_CL_INDEXER) + options.indexer.push(ETHEREUM_CL_INDEXER.toLowerCase()) return options } diff --git a/packages/composites/proof-of-reserves/src/endpoint/reserves.ts b/packages/composites/proof-of-reserves/src/endpoint/reserves.ts index 99156278ba..07b995e6d8 100644 --- a/packages/composites/proof-of-reserves/src/endpoint/reserves.ts +++ b/packages/composites/proof-of-reserves/src/endpoint/reserves.ts @@ -4,6 +4,7 @@ import { adaptersV2 as indexerAdaptersV2, adaptersV3 as indexerAdaptersV3, runBalanceAdapter, + ETHEREUM_CL_INDEXER, } from '../utils/balance' import { adaptersV2 as protocolAdaptersV2, @@ -58,6 +59,7 @@ const inputParameters: InputParameters = { ...indexerAdaptersV2.map(({ NAME }) => NAME.toUpperCase()), ...indexerAdaptersV3.map(({ name }) => name.toLowerCase()), ...indexerAdaptersV3.map(({ name }) => name.toUpperCase()), + ETHEREUM_CL_INDEXER, ], }, indexerEndpoint: { @@ -118,7 +120,9 @@ export const execute: ExecuteWithConfig = async (input, context, config) config, validator.validated.data.protocolEndpoint, ) + const validatedAddresses = getValidAddresses(protocolOutput, validator) + const balanceOutput = await runBalanceAdapter( indexer, context, diff --git a/packages/composites/proof-of-reserves/src/utils/addressValidator.ts b/packages/composites/proof-of-reserves/src/utils/addressValidator.ts index 05c1565a95..c5396a6baf 100644 --- a/packages/composites/proof-of-reserves/src/utils/addressValidator.ts +++ b/packages/composites/proof-of-reserves/src/utils/addressValidator.ts @@ -51,7 +51,7 @@ export const validateAddresses = ( for (const addressObj of addresses) { const { address, network, chainId, contractAddress, wallets } = addressObj let validatedAddress: string | undefined = undefined - let validationNetwork = network || indexerToNetwork[indexer] + let validationNetwork = network || indexerToNetwork[indexer] || '' // If the indexer is eth_beacon, override the validationNetwork as it might contain a different value (goerli, ethereum, mainnet...) validationNetwork = indexer === 'eth_beacon' ? 'beacon' : validationNetwork diff --git a/packages/composites/proof-of-reserves/src/utils/balance.ts b/packages/composites/proof-of-reserves/src/utils/balance.ts index 6dd9870a71..02815a4706 100644 --- a/packages/composites/proof-of-reserves/src/utils/balance.ts +++ b/packages/composites/proof-of-reserves/src/utils/balance.ts @@ -28,6 +28,8 @@ import { adapter as porIndexer } from '@chainlink/por-indexer-adapter' import { adapter as tokenBalance } from '@chainlink/token-balance-adapter' import { adapter as ceffu } from '@chainlink/ceffu-adapter' +export const ETHEREUM_CL_INDEXER = 'ETHEREUM_CL_INDEXER' + // TODO: type export const adaptersV2: v2AdapterImplementation[] = [ amberdata as unknown as v2AdapterImplementation, @@ -63,7 +65,8 @@ export const runBalanceAdapter = async ( indexerEndpoint?: string, indexerParams?: Record, ): Promise => { - const execute = makeRequestFactory(config, indexer) + const postfix = indexer == ETHEREUM_CL_INDEXER ? '/' + indexerEndpoint : '' + const execute = makeRequestFactory(config, indexer, postfix) let next switch (indexer) { case bitcoinJsonRpc.NAME: diff --git a/packages/composites/proof-of-reserves/src/utils/index.ts b/packages/composites/proof-of-reserves/src/utils/index.ts index df08c6f0b5..3592c9011e 100644 --- a/packages/composites/proof-of-reserves/src/utils/index.ts +++ b/packages/composites/proof-of-reserves/src/utils/index.ts @@ -8,13 +8,13 @@ import { } from '@chainlink/ea-bootstrap' export const makeRequestFactory = - (config: Config, prefix: string): Execute => + (config: Config, prefix: string, postfix?: string): Execute => async (input: AdapterRequest) => ( await Requester.request({ ...config.api, method: 'post', - url: util.getURL(prefix, true), + url: (util.getURL(prefix, true) || '') + (postfix || ''), data: input, }) ).data as AdapterResponse diff --git a/packages/composites/proof-of-reserves/src/utils/reduce.ts b/packages/composites/proof-of-reserves/src/utils/reduce.ts index 730abce52c..6c8fe8f218 100644 --- a/packages/composites/proof-of-reserves/src/utils/reduce.ts +++ b/packages/composites/proof-of-reserves/src/utils/reduce.ts @@ -1,5 +1,5 @@ import * as reduce from '@chainlink/reduce-adapter' -import { AdapterContext, AdapterResponse } from '@chainlink/ea-bootstrap' +import { AdapterContext, AdapterError, AdapterResponse } from '@chainlink/ea-bootstrap' import { callAdapter } from '.' import * as bitcoinJsonRpc from '@chainlink/bitcoin-json-rpc-adapter' import { adapter as bitcoinPorIndexer } from '@chainlink/por-indexer-adapter' @@ -8,6 +8,7 @@ import { adapter as lotus } from '@chainlink/lotus-adapter' import { adapter as tokenBalance } from '@chainlink/token-balance-adapter' import { adapter as ceffu } from '@chainlink/ceffu-adapter' import { ethers } from 'ethers' +import { ETHEREUM_CL_INDEXER } from './balance' const returnParsedUnits = ( jobRunID: string, @@ -56,6 +57,23 @@ export const runReduceAdapter = async ( case adaBalance.NAME: // TODO: type makeExecute response return returnParsedUnits(input.jobRunID, input.data.result as string, 0) + case ETHEREUM_CL_INDEXER: + if (input.data.isValid) { + return { + jobRunID: input.jobRunID, + result: input.data.totalBalance as string, + statusCode: 200, + data: { + result: input.data.totalBalance as string, + statusCode: 200, + }, + } + } else { + throw new AdapterError({ + statusCode: 400, + message: `ETHEREUM_CL_INDEXER ripcord is true: ${JSON.stringify(input.data)}`, + }) + } } const next = {