From 9eaf27927bb8fee7dd8c76e1f47c90e6dfd8dcaf Mon Sep 17 00:00:00 2001 From: Sergey Date: Thu, 2 May 2024 17:27:33 +0300 Subject: [PATCH 1/2] feat: add custom user-agent to queries --- src/utils/CosmosDirectory.mjs | 14 +++++----- src/utils/Helpers.mjs | 27 ++++++++++++++++++++ src/utils/QueryClient.mjs | 48 +++++++++++++++-------------------- src/utils/SigningClient.mjs | 12 ++++----- src/utils/constants.mjs | 1 + 5 files changed, 60 insertions(+), 42 deletions(-) create mode 100644 src/utils/constants.mjs diff --git a/src/utils/CosmosDirectory.mjs b/src/utils/CosmosDirectory.mjs index 69e29899..3eab1827 100644 --- a/src/utils/CosmosDirectory.mjs +++ b/src/utils/CosmosDirectory.mjs @@ -1,4 +1,4 @@ -import axios from 'axios' +import { get } from './Helpers.mjs' function CosmosDirectory(testnet){ const protocol = process.env.DIRECTORY_PROTOCOL || 'https' @@ -19,34 +19,34 @@ function CosmosDirectory(testnet){ } function getChains(){ - return axios.get(chainsUrl) + return get(chainsUrl) .then(res => res.data) .then(data => Array.isArray(data) ? data : data.chains) // deprecate .then(data => data.reduce((a, v) => ({ ...a, [v.path]: v }), {})) } function getChainData(name) { - return axios.get([chainsUrl, name].join('/')) + return get([chainsUrl, name].join('/')) .then(res => res.data.chain) } async function getTokenData(name) { - return axios.get([chainsUrl, name, 'assetlist'].join('/')) + return get([chainsUrl, name, 'assetlist'].join('/')) .then(res => res.data) } function getValidators(chainName){ - return axios.get(validatorsUrl + '/chains/' + chainName) + return get(validatorsUrl + '/chains/' + chainName) .then(res => res.data.validators) } function getRegistryValidator(validatorName) { - return axios.get(validatorsUrl + '/' + validatorName) + return get(validatorsUrl + '/' + validatorName) .then(res => res.data.validator) } function getOperatorAddresses(){ - return axios.get(validatorsUrl) + return get(validatorsUrl) .then(res => res.data) .then(data => Array.isArray(data) ? data : data.validators) // deprecate .then(data => data.reduce((sum, validator) => { diff --git a/src/utils/Helpers.mjs b/src/utils/Helpers.mjs index 8be6f32e..72cbab7a 100644 --- a/src/utils/Helpers.mjs +++ b/src/utils/Helpers.mjs @@ -1,6 +1,9 @@ import _ from 'lodash' import { format, floor, bignumber } from 'mathjs' import { coin as _coin } from '@cosmjs/stargate' +import axios from 'axios' + +import { RESTAKE_USER_AGENT } from './constants.mjs' export function timeStamp(...args) { console.log('[' + new Date().toISOString().substring(11, 23) + ']', ...args); @@ -129,3 +132,27 @@ export async function executeSync(calls, count) { await mapAsync(batchCall, call => call()) } } + +export async function get(url, opts) { + const headers = opts?.headers ?? {} + + return axios.get(url, { + ...opts, + headers: { + ...headers, + 'User-Agent': RESTAKE_USER_AGENT, + } + }) +} + +export async function post(url, body, opts) { + const headers = opts?.headers ?? {} + + return axios.post(url, body, { + ...opts, + headers: { + ...headers, + 'User-Agent': RESTAKE_USER_AGENT, + } + }) +} diff --git a/src/utils/QueryClient.mjs b/src/utils/QueryClient.mjs index cc2c1b19..e5ca69d4 100644 --- a/src/utils/QueryClient.mjs +++ b/src/utils/QueryClient.mjs @@ -2,6 +2,8 @@ import axios from "axios"; import axiosRetry from 'axios-retry'; import _ from "lodash"; +import { get } from './Helpers.mjs'; + const QueryClient = async (chainId, restUrls, opts) => { const config = _.merge({ connectTimeout: 10000, @@ -29,8 +31,7 @@ const QueryClient = async (chainId, restUrls, opts) => { searchParams.append("pagination.limit", pageSize); if (nextKey) searchParams.append("pagination.key", nextKey); - return axios - .get( + return get( apiUrl('staking', `validators?${searchParams.toString()}`), { timeout: opts.timeout || 10000, }) @@ -57,14 +58,12 @@ const QueryClient = async (chainId, restUrls, opts) => { if (nextKey) searchParams.append("pagination.key", nextKey); - return axios - .get(apiUrl('staking', `validators/${validatorAddress}/delegations?${searchParams.toString()}`), opts) + return get(apiUrl('staking', `validators/${validatorAddress}/delegations?${searchParams.toString()}`), opts) .then((res) => res.data); } function getBalance(address, denom, opts) { - return axios - .get(apiUrl('bank', `balances/${address}`), opts) + return get(apiUrl('bank', `balances/${address}`), opts) .then((res) => res.data) .then((result) => { if (!denom) @@ -78,8 +77,7 @@ const QueryClient = async (chainId, restUrls, opts) => { } function getDelegations(address) { - return axios - .get(apiUrl('staking', `delegations/${address}`)) + return get(apiUrl('staking', `delegations/${address}`)) .then((res) => res.data) .then((result) => { const delegations = result.delegation_responses.reduce( @@ -91,8 +89,7 @@ const QueryClient = async (chainId, restUrls, opts) => { } function getRewards(address, opts) { - return axios - .get(apiUrl('distribution', `delegators/${address}/rewards`), opts) + return get(apiUrl('distribution', `delegators/${address}/rewards`), opts) .then((res) => res.data) .then((result) => { const rewards = result.rewards.reduce( @@ -104,8 +101,7 @@ const QueryClient = async (chainId, restUrls, opts) => { } function getCommission(validatorAddress, opts) { - return axios - .get(apiUrl('distribution', `validators/${validatorAddress}/commission`), opts) + return get(apiUrl('distribution', `validators/${validatorAddress}/commission`), opts) .then((res) => res.data) .then((result) => { return result.commission; @@ -120,8 +116,7 @@ const QueryClient = async (chainId, restUrls, opts) => { if (nextKey) searchParams.append("pagination.key", nextKey); - return axios - .get(apiUrl('gov', `proposals?${searchParams.toString()}`), opts) + return get(apiUrl('gov', `proposals?${searchParams.toString()}`), opts) .then((res) => res.data); }).then((pages) => { return pages.map(el => el.proposals).flat(); @@ -129,14 +124,12 @@ const QueryClient = async (chainId, restUrls, opts) => { } function getProposalTally(proposal_id, opts) { - return axios - .get(apiUrl('gov', `proposals/${proposal_id}/tally`), opts) + return get(apiUrl('gov', `proposals/${proposal_id}/tally`), opts) .then((res) => res.data); } function getProposalVote(proposal_id, address, opts) { - return axios - .get(apiUrl('gov', `proposals/${proposal_id}/votes/${address}`), opts) + return get(apiUrl('gov', `proposals/${proposal_id}/votes/${address}`), opts) .then((res) => res.data); } @@ -148,8 +141,7 @@ const QueryClient = async (chainId, restUrls, opts) => { if (nextKey) searchParams.append("pagination.key", nextKey); - return axios - .get(apiUrl('authz', `grants/grantee/${grantee}?${searchParams.toString()}`), opts) + return get(apiUrl('authz', `grants/grantee/${grantee}?${searchParams.toString()}`), opts) .then((res) => res.data); }, pageCallback).then((pages) => { return pages.map(el => el.grants).flat(); @@ -164,8 +156,7 @@ const QueryClient = async (chainId, restUrls, opts) => { if (nextKey) searchParams.append("pagination.key", nextKey); - return axios - .get(apiUrl('authz', `grants/granter/${granter}?${searchParams.toString()}`), opts) + return get(apiUrl('authz', `grants/granter/${granter}?${searchParams.toString()}`), opts) .then((res) => res.data); }, pageCallback).then((pages) => { return pages.map(el => el.grants).flat(); @@ -178,8 +169,7 @@ const QueryClient = async (chainId, restUrls, opts) => { searchParams.append("grantee", grantee); if (granter) searchParams.append("granter", granter); - return axios - .get(apiUrl('authz', `grants?${searchParams.toString()}`), opts) + return get(apiUrl('authz', `grants?${searchParams.toString()}`), opts) .then((res) => res.data) .then((result) => { return result.grants; @@ -187,8 +177,7 @@ const QueryClient = async (chainId, restUrls, opts) => { } function getWithdrawAddress(address, opts) { - return axios - .get(apiUrl('distribution', `delegators/${address}/withdraw_address`)) + return get(apiUrl('distribution', `delegators/${address}/withdraw_address`)) .then((res) => res.data) .then((result) => { return result.withdraw_address; @@ -205,7 +194,10 @@ const QueryClient = async (chainId, restUrls, opts) => { searchParams.append('pagination.limit', pageSize); if (order) searchParams.append('order_by', order); - const client = axios.create({ baseURL: restUrl }); + const client = axios.create({ + baseURL: restUrl, + headers: { 'User-Agent': RESTAKE_USER_AGENT } + }); axiosRetry(client, { retries: retries || 0, shouldResetTimeout: true, retryCondition: (e) => true }); return client.get(apiPath('tx', `txs?${searchParams.toString()}`), opts).then((res) => res.data); } @@ -249,7 +241,7 @@ const QueryClient = async (chainId, restUrls, opts) => { async function getLatestBlock(url, type, path, opts){ const { timeout } = opts || {} try { - return await axios.get(url + path, { timeout }) + return await get(url + path, { timeout }) .then((res) => res.data) } catch (error) { const fallback = type === 'rest' && '/blocks/latest' diff --git a/src/utils/SigningClient.mjs b/src/utils/SigningClient.mjs index 8683ecec..ad1c75a4 100644 --- a/src/utils/SigningClient.mjs +++ b/src/utils/SigningClient.mjs @@ -1,5 +1,4 @@ import _ from 'lodash' -import axios from 'axios' import { multiply, ceil, bignumber } from 'mathjs' import Long from "long"; @@ -15,7 +14,7 @@ import { PubKey } from "cosmjs-types/cosmos/crypto/secp256k1/keys.js"; import { SignMode } from "cosmjs-types/cosmos/tx/signing/v1beta1/signing.js"; import { AuthInfo, Fee, TxBody, TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx.js"; -import { coin } from './Helpers.mjs' +import { coin, get, post } from './Helpers.mjs' function SigningClient(network, signer) { @@ -25,8 +24,7 @@ function SigningClient(network, signer) { const registry = new Registry(defaultStargateTypes); function getAccount(address) { - return axios - .get(restUrl + "/cosmos/auth/v1beta1/accounts/" + address) + return get(restUrl + "/cosmos/auth/v1beta1/accounts/" + address) .then((res) => res.data.account) .then((value) => { // see https://github.com/chainapsis/keplr-wallet/blob/7ca025d32db7873b7a870e69a4a42b525e379132/packages/cosmos/src/account/index.ts#L73 @@ -122,7 +120,7 @@ function SigningClient(network, signer) { } await sleep(pollIntervalMs); try { - const response = await axios.get(restUrl + '/cosmos/tx/v1beta1/txs/' + txId); + const response = await get(restUrl + '/cosmos/tx/v1beta1/txs/' + txId); const result = parseTxResult(response.data.tx_response) return result } catch { @@ -130,7 +128,7 @@ function SigningClient(network, signer) { } }; - const response = await axios.post(restUrl + '/cosmos/tx/v1beta1/txs', { + const response = await post(restUrl + '/cosmos/tx/v1beta1/txs', { tx_bytes: toBase64(TxRaw.encode(txBody).finish()), mode: "BROADCAST_MODE_SYNC" }) @@ -180,7 +178,7 @@ function SigningClient(network, signer) { } try { - const estimate = await axios.post(restUrl + '/cosmos/tx/v1beta1/simulate', { + const estimate = await post(restUrl + '/cosmos/tx/v1beta1/simulate', { tx_bytes: toBase64(TxRaw.encode(txBody).finish()), }).then(el => el.data.gas_info.gas_used) return (parseInt(estimate * (modifier || defaultGasModifier))); diff --git a/src/utils/constants.mjs b/src/utils/constants.mjs new file mode 100644 index 00000000..ba905773 --- /dev/null +++ b/src/utils/constants.mjs @@ -0,0 +1 @@ +export const RESTAKE_USER_AGENT = 'ReStake' From b927f8c96a7ee49a66331c37ae69c8bb45d3327f Mon Sep 17 00:00:00 2001 From: Tom Beynon Date: Thu, 2 May 2024 19:42:05 +0100 Subject: [PATCH 2/2] Update src/utils/constants.mjs --- src/utils/constants.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/constants.mjs b/src/utils/constants.mjs index ba905773..ce43174e 100644 --- a/src/utils/constants.mjs +++ b/src/utils/constants.mjs @@ -1 +1 @@ -export const RESTAKE_USER_AGENT = 'ReStake' +export const RESTAKE_USER_AGENT = 'REStake'