diff --git a/watcher/src/consts.ts b/watcher/src/consts.ts index 74041d16..d462c1c7 100644 --- a/watcher/src/consts.ts +++ b/watcher/src/consts.ts @@ -136,8 +136,12 @@ export const ALGORAND_INFO: { [key in Environment]: AlgorandInfo } = { }, }; -export const SEI_EXPLORER_GRAPHQL = 'https://pacific-1-graphql.alleslabs.dev/v1/graphql'; -export const SEI_EXPLORER_TXS = 'https://celatone-api-prod.alleslabs.dev/v1/sei/pacific-1/txs/'; +export const SEI_EXPLORER_GRAPHQL_MAINNET = 'https://pacific-1-graphql.alleslabs.dev/v1/graphql'; +export const SEI_EXPLORER_TXS_MAINNET = + 'https://celatone-api-prod.alleslabs.dev/v1/sei/pacific-1/txs/'; +export const SEI_EXPLORER_GRAPHQL_TESTNET = 'https://atlantic-2-graphql.alleslabs.dev/v1/graphql'; +export const SEI_EXPLORER_TXS_TESTNET = + 'https://celatone-api-prod.alleslabs.dev/v1/sei/atlantic-2/txs/'; export const DB_SOURCE = process.env.NODE_ENV === 'test' ? 'local' : process.env.DB_SOURCE || 'local'; diff --git a/watcher/src/watchers/SeiExplorerWatcher.ts b/watcher/src/watchers/SeiExplorerWatcher.ts index 54b02605..1ddb71da 100644 --- a/watcher/src/watchers/SeiExplorerWatcher.ts +++ b/watcher/src/watchers/SeiExplorerWatcher.ts @@ -1,6 +1,12 @@ -import { CONTRACTS } from '@certusone/wormhole-sdk/lib/cjs/utils/consts'; +import { CONTRACTS, Contracts } from '@certusone/wormhole-sdk/lib/cjs/utils/consts'; import axios from 'axios'; -import { AXIOS_CONFIG_JSON, SEI_EXPLORER_GRAPHQL, SEI_EXPLORER_TXS } from '../consts'; +import { + AXIOS_CONFIG_JSON, + SEI_EXPLORER_GRAPHQL_MAINNET, + SEI_EXPLORER_GRAPHQL_TESTNET, + SEI_EXPLORER_TXS_MAINNET, + SEI_EXPLORER_TXS_TESTNET, +} from '../consts'; import { VaasByBlock } from '../databases/types'; import { makeBlockKey, makeVaaKey } from '../databases/utils'; import { CosmwasmHashResult, CosmwasmWatcher } from './CosmwasmWatcher'; @@ -29,33 +35,65 @@ type SeiExplorerAccountTransactionsResponse = { }; export class SeiExplorerWatcher extends CosmwasmWatcher { + explorerGraphql: string; + explorerTxs: string; + accountId: number; + constructor(network: Environment) { super(network, 'sei'); // arbitrarily large since the code here is capable of pulling all logs from all via indexer pagination this.maximumBatchSize = 1_000_000; + this.explorerGraphql = + network === 'mainnet' + ? SEI_EXPLORER_GRAPHQL_MAINNET + : network === 'testnet' + ? SEI_EXPLORER_GRAPHQL_TESTNET + : ''; + this.explorerTxs = + network === 'mainnet' + ? SEI_EXPLORER_TXS_MAINNET + : network === 'testnet' + ? SEI_EXPLORER_TXS_TESTNET + : ''; + this.accountId = network === 'mainnet' ? 42 : network === 'testnet' ? 3254150 : 0; + // 42 is the account id of sei1gjrrme22cyha4ht2xapn3f08zzw6z3d4uxx6fyy9zd5dyr3yxgzqqncdqn <-- mainnet + // MAINNET: + // curl https://pacific-1-graphql.alleslabs.dev/v1/graphql \ + // -X POST \ + // -H "Content-Type: application/json" \ + // --data '{"query":"query getAccountIdByAddressQueryDocument($address: String!) {accounts_by_pk(address: $address) {id}}", "variables":{"address":"sei1gjrrme22cyha4ht2xapn3f08zzw6z3d4uxx6fyy9zd5dyr3yxgzqqncdqn"}, "operationName":"getAccountIdByAddressQueryDocument"}' + // {"data":{"accounts_by_pk":{"id":42}}} + // + // 3254150 is the account number of sei1nna9mzp274djrgzhzkac2gvm3j27l402s4xzr08chq57pjsupqnqaj0d5s <-- testnet + // TESTNET: + // curl https://atlantic-2-graphql.alleslabs.dev/v1/graphql \ + // -X POST \ + // -H "Content-Type: application/json" \ + // --data '{"query":"query getAccountIdByAddressQueryDocument($address: String!) {accounts_by_pk(address: $address) {id}}", "variables":{"address":"sei1nna9mzp274djrgzhzkac2gvm3j27l402s4xzr08chq57pjsupqnqaj0d5s"}, "operationName":"getAccountIdByAddressQueryDocument"}' + // {"data":{"accounts_by_pk":{"id":3254150}}} + // returned by getAccountIdByAddressQueryDocument } makeGraphQLQuery(offset: number, pageSize: number) { return { query: 'query getTxsByAddressPagination($expression: account_transactions_bool_exp, $offset: Int!, $pageSize: Int!) {\n account_transactions(\n where: $expression\n order_by: {block_height: desc}\n offset: $offset\n limit: $pageSize\n ) {\n block {\n height\n timestamp\n }\n transaction {\n account {\n address\n }\n hash\n success\n messages\n is_clear_admin\n is_execute\n is_ibc\n is_instantiate\n is_migrate\n is_send\n is_store_code\n is_update_admin\n }\n is_signer\n }\n}', - variables: { expression: { account_id: { _eq: 42 } }, offset, pageSize }, - // 42 is the account id of sei1gjrrme22cyha4ht2xapn3f08zzw6z3d4uxx6fyy9zd5dyr3yxgzqqncdqn - // returned by getAccountIdByAddressQueryDocument + variables: { expression: { account_id: { _eq: this.accountId } }, offset, pageSize }, operationName: 'getTxsByAddressPagination', }; } async getFinalizedBlockNumber(): Promise { const query = this.makeGraphQLQuery(0, 1); - this.logger.debug(`Query string = ${JSON.stringify(query)}`); + // this.logger.debug(`Query string = ${JSON.stringify(query)}`); const bulkTxnResult = ( await axios.post( - SEI_EXPLORER_GRAPHQL, + this.explorerGraphql, query, AXIOS_CONFIG_JSON ) ).data; + this.logger.debug(`bulkTxnResult = ${JSON.stringify(bulkTxnResult)}`); const blockHeight = bulkTxnResult?.data?.account_transactions?.[0]?.block?.height; if (blockHeight) { if (blockHeight !== this.latestBlockHeight) { @@ -70,7 +108,13 @@ export class SeiExplorerWatcher extends CosmwasmWatcher { // retrieve blocks for core contract // compare block height with what is passed in async getMessagesForBlocks(fromBlock: number, toBlock: number): Promise { - const address = CONTRACTS.MAINNET[this.chain].core; + const contracts: Contracts = + this.network === 'mainnet' + ? CONTRACTS.MAINNET[this.chain] + : this.network === 'testnet' + ? CONTRACTS.TESTNET[this.chain] + : CONTRACTS.DEVNET[this.chain]; + const address = contracts.core; if (!address) { throw new Error(`Core contract not defined for ${this.chain}`); } @@ -83,10 +127,10 @@ export class SeiExplorerWatcher extends CosmwasmWatcher { let skip: number = 0; while (!done) { const query = this.makeGraphQLQuery(skip, limit); - this.logger.debug(`Query string = ${JSON.stringify(query)}`); + // this.logger.debug(`Query string = ${JSON.stringify(query)}`); const bulkTxnResult = ( await axios.post( - SEI_EXPLORER_GRAPHQL, + this.explorerGraphql, query, AXIOS_CONFIG_JSON ) @@ -130,7 +174,7 @@ export class SeiExplorerWatcher extends CosmwasmWatcher { } catch (e: any) { if (e?.response?.status === 404) { // the node is mysteriously missing some transactions, but so is this ='( - hashResult = (await axios.get(`${SEI_EXPLORER_TXS}${hash}`, AXIOS_CONFIG_JSON)) + hashResult = (await axios.get(`${this.explorerTxs}${hash}`, AXIOS_CONFIG_JSON)) .data; } }