-
-
Notifications
You must be signed in to change notification settings - Fork 903
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add celo fee.estimateFeePerGas (#2041)
* Add celo fee.estimateFeePerGas (#10) * missed changeset (#12) * chore: tweak * chore: tweak * Update nervous-cows-agree.md --------- Co-authored-by: Aaron DeRuvo <aaron.deruvo@gmail.com> Co-authored-by: jxom <jakemoxey@gmail.com>
- Loading branch information
1 parent
ea6e0f5
commit 29eea54
Showing
8 changed files
with
209 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"viem": patch | ||
--- | ||
|
||
Added custom Celo fees estimation function for cases when feeCurrency is used to send a transaction. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
import { fees } from './fees.js' | ||
import { formatters } from './formatters.js' | ||
import { serializers } from './serializers.js' | ||
|
||
export const chainConfig = { | ||
formatters, | ||
serializers, | ||
fees, | ||
} as const |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { describe, expect, test, vi } from 'vitest' | ||
import { celo } from '~viem/chains/index.js' | ||
import { http, createTestClient } from '~viem/index.js' | ||
import type { ChainEstimateFeesPerGasFn } from '~viem/types/chain.js' | ||
|
||
const client = createTestClient({ | ||
transport: http(), | ||
chain: celo, | ||
mode: 'anvil', | ||
}) | ||
|
||
describe('celo/fees', () => { | ||
const celoestimateFeesPerGasFn = celo.fees | ||
.estimateFeesPerGas as ChainEstimateFeesPerGasFn | ||
|
||
test("doesn't call the client when feeCurrency is not provided", async () => { | ||
const requestMock = vi.spyOn(client, 'request') | ||
|
||
expect(celo.fees.estimateFeesPerGas).toBeTypeOf('function') | ||
|
||
const fees = await celoestimateFeesPerGasFn({ | ||
client, | ||
request: {}, | ||
} as any) | ||
|
||
expect(fees).toBeNull() | ||
expect(requestMock).not.toHaveBeenCalled() | ||
}) | ||
|
||
test('calls the client when feeCurrency is provided', async () => { | ||
const requestMock = vi.spyOn(client, 'request') | ||
requestMock.mockImplementation((request) => { | ||
switch (request.method) { | ||
case 'eth_gasPrice': | ||
return '11619349802' | ||
case 'eth_maxPriorityFeePerGas': | ||
return '2323869960' | ||
} | ||
}) | ||
|
||
expect(celo.fees.estimateFeesPerGas).toBeTypeOf('function') | ||
|
||
const fees = await celoestimateFeesPerGasFn({ | ||
client, | ||
request: { | ||
feeCurrency: '0xfee', | ||
}, | ||
} as any) | ||
|
||
expect(fees).toMatchInlineSnapshot(` | ||
{ | ||
"maxFeePerGas": 11619349802n, | ||
"maxPriorityFeePerGas": 2323869960n, | ||
} | ||
`) | ||
expect(requestMock).toHaveBeenCalledWith({ | ||
method: 'eth_maxPriorityFeePerGas', | ||
params: ['0xfee'], | ||
}) | ||
expect(requestMock).toHaveBeenCalledWith({ | ||
method: 'eth_gasPrice', | ||
params: ['0xfee'], | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import type { Client } from '../clients/createClient.js' | ||
import { | ||
type Address, | ||
type ChainEstimateFeesPerGasFnParameters, | ||
type ChainFees, | ||
type Hex, | ||
} from '../index.js' | ||
|
||
import { formatters } from './formatters.js' | ||
|
||
export const fees: ChainFees<typeof formatters> = { | ||
/* | ||
* Estimates the fees per gas for a transaction. | ||
* If the transaction is to be paid in a token (feeCurrency is present) then the fees | ||
* are estimated in the value of the token. Otherwise falls back to the default | ||
* estimation by returning null. | ||
* | ||
* @param params fee estimation function parameters | ||
*/ | ||
estimateFeesPerGas: async ( | ||
params: ChainEstimateFeesPerGasFnParameters<typeof formatters>, | ||
) => { | ||
if (!params.request?.feeCurrency) return null | ||
|
||
const [maxFeePerGas, maxPriorityFeePerGas] = await Promise.all([ | ||
estimateFeePerGasInFeeCurrency(params.client, params.request.feeCurrency), | ||
estimateMaxPriorityFeePerGasInFeeCurrency( | ||
params.client, | ||
params.request.feeCurrency, | ||
), | ||
]) | ||
|
||
return { | ||
maxFeePerGas, | ||
maxPriorityFeePerGas, | ||
} | ||
}, | ||
} | ||
|
||
type RequestGasPriceInFeeCurrencyParams = { | ||
Method: 'eth_gasPrice' | ||
Parameters: [Address] | ||
ReturnType: Hex | ||
} | ||
|
||
/* | ||
* Estimate the fee per gas in the value of the fee token | ||
* | ||
* @param client - Client to use | ||
* @param feeCurrency - Address of a whitelisted fee token | ||
* @returns The fee per gas in wei in the value of the fee token | ||
* | ||
*/ | ||
async function estimateFeePerGasInFeeCurrency( | ||
client: Client, | ||
feeCurrency: Address, | ||
) { | ||
const fee = await client.request<RequestGasPriceInFeeCurrencyParams>({ | ||
method: 'eth_gasPrice', | ||
params: [feeCurrency], | ||
}) | ||
return BigInt(fee) | ||
} | ||
|
||
type RequestMaxGasPriceInFeeCurrencyParams = { | ||
Method: 'eth_maxPriorityFeePerGas' | ||
Parameters: [Address] | ||
ReturnType: Hex | ||
} | ||
|
||
/* | ||
* Estimate the max priority fee per gas in the value of the fee token | ||
* | ||
* @param client - Client to use | ||
* @param feeCurrency - Address of a whitelisted fee token | ||
* @returns The fee per gas in wei in the value of the fee token | ||
* | ||
*/ | ||
async function estimateMaxPriorityFeePerGasInFeeCurrency( | ||
client: Client, | ||
feeCurrency: Address, | ||
) { | ||
const feesPerGas = | ||
await client.request<RequestMaxGasPriceInFeeCurrencyParams>({ | ||
method: 'eth_maxPriorityFeePerGas', | ||
params: [feeCurrency], | ||
}) | ||
return BigInt(feesPerGas) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters