Skip to content

Commit

Permalink
Handle 429 error (#102)
Browse files Browse the repository at this point in the history
* [handle-429-error] improve createProvider method

* [handle-429-error] improves
  • Loading branch information
Cast0001 authored Apr 25, 2024
1 parent f4e29d8 commit 636ef27
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ import './types/global'

export * from './utils/enums'
export { createContract } from './contracts'
export { BigDecimal, configs, getGas } from './utils'
export { default as StakeWiseSDK } from './StakeWiseSDK'
export { BigDecimal, configs, getGas, createProvider } from './utils'
2 changes: 2 additions & 0 deletions src/utils/apiUrls.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import configs from './configs'


const getWeb3Url = (options: StakeWise.Options) => options.endpoints?.web3 || configs[options.network].network.url
const getBackendUrl = (options: StakeWise.Options) => options.endpoints?.api || configs[options.network].api.backend
const getSubgraphqlUrl = (options: StakeWise.Options) => options.endpoints?.subgraph || configs[options.network].api.subgraph


export default {
getWeb3Url,
getBackendUrl,
getSubgraphqlUrl,
}
56 changes: 45 additions & 11 deletions src/utils/createProvider.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,60 @@
import { JsonRpcProvider, FallbackProvider } from 'ethers'
import { JsonRpcProvider, FallbackProvider, FetchRequest, FetchResponse } from 'ethers'

import configs from './configs'
import apiUrls from './apiUrls'


const createProvider = (options: StakeWise.Options) => {
const urls = options.endpoints?.web3
const { network } = options

if (!urls) {
return new JsonRpcProvider(configs[options.network].network.url)
}
const urls = apiUrls.getWeb3Url(options)

if (Array.isArray(urls)) {
if (urls.length === 1) {
return new JsonRpcProvider(urls[0])
}
else {
const providers: ConstructorParameters<typeof FallbackProvider>[0] = urls.map((url, index) => ({
provider: new JsonRpcProvider(url),
priority: index + 1,
}))
const providers: ConstructorParameters<typeof FallbackProvider>[0] = urls.map((url, index) => {
// Why do we use FetchRequest and change the behavior of the 429 error?
// Because inside ethers error 429 is handled only by resending the request
// and in this case no additional node is started. This is a problem for public nodes,
// so we think it is better to use an additional node in case of 429 error
const fetchRequest = new FetchRequest(url)

fetchRequest.setThrottleParams({
slotInterval: 2 * 1000,
maxAttempts: 2,
})

fetchRequest.processFunc = async (_, resp) => {
if (resp.statusCode === 429) {
// mutate the response to 500 to start an additional node
// https://github.com/ethers-io/ethers.js/blob/main/src.ts/utils/fetch.ts#L519
const newResponse = new FetchResponse(500, '', resp.headers, null)

return newResponse
}

return resp
}

fetchRequest.retryFunc = async (_, response) => {
if (response.statusCode === 429) {
// stop retry attempts
// https://github.com/ethers-io/ethers.js/blob/main/src.ts/utils/fetch.ts#L556
return false
}

return true
}

return {
provider: new JsonRpcProvider(fetchRequest, network),
priority: index + 1,
weight: 1,
}
})

const provider = new FallbackProvider(providers) as StakeWise.CustomFallbackProvider
const provider = new FallbackProvider(providers, network) as StakeWise.CustomFallbackProvider

provider.getSigner = () => {
throw new Error('Pass your provider to the SDK class instance to get a signer')
Expand Down

0 comments on commit 636ef27

Please sign in to comment.