Skip to content

Commit

Permalink
feat: add dynamic evm gas estimation (#7449)
Browse files Browse the repository at this point in the history
* feat: add the ShimmerEVM details

* feat: add new encoding WIP

* feat: Split getOutputParameters logic into l1 and l2 related

* feat: Introduce Output (and related models) serialization code from iota.js

* feat: add new encoding

* feat: Add logic for gas estimation [WiP]

* feat: Fix gas estimation request (seams to work now) [WiP]

* chore: cleanup code

* fix: test

* feat: add profile migration to update evm chains

* feat: Move iota.js Output building to helper function. Fix a type error.

* feat: Fix response parsing for gasEstimate

* feat: Add parsing recipient aliasId and sender pubKeyHash with iota-sdk in output serialization

* feat: Build output for gas estimation using @iota/sdk prepareOutput

* feat: Update gas estimation logic with help of Jorge

* revert: undo changes that cant go to develop

* fix: displayed gas estimation in send confirmation popup

* fix: Skip tests about layer2 as getOutputParameters now does prepareOutput which we can't do in test context

* feat: add gas estimation loading

---------

Co-authored-by: cpl121 <[email protected]>
Co-authored-by: Begoña Alvarez <[email protected]>
  • Loading branch information
3 people authored Sep 26, 2023
1 parent 410e0f2 commit c315744
Show file tree
Hide file tree
Showing 7 changed files with 491 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import {
ACCOUNTS_CONTRACT,
CONTRACT_FUNCTIONS,
GAS_BUDGET,
getDestinationNetworkFromAddress,
TARGET_CONTRACTS,
TRANSFER_ALLOWANCE,
Expand Down Expand Up @@ -99,7 +98,7 @@
ethereumAddress: getAddressFromSubject(recipient),
targetContract: TARGET_CONTRACTS[ACCOUNTS_CONTRACT],
contractFunction: CONTRACT_FUNCTIONS[TRANSFER_ALLOWANCE],
gasBudget: String(GAS_BUDGET),
gasBudget: layer2Parameters?.gasBudget ?? 0,
},
}),
}
Expand Down Expand Up @@ -270,7 +269,14 @@
</Button>
{/if}

<Button classes="w-full" onClick={onConfirmClick} disabled={isTransferring} isBusy={isTransferring}>
<Button
classes="w-full"
onClick={onConfirmClick}
disabled={isTransferring ||
(layer2Parameters?.networkAddress && !$newTransactionDetails?.layer2Parameters?.gasBudget)}
isBusy={isTransferring ||
(layer2Parameters?.networkAddress && !$newTransactionDetails?.layer2Parameters?.gasBudget)}
>
{localize('actions.send')}
</Button>
</popup-buttons>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,40 @@
import { GAS_BUDGET } from '../constants'
import BigInteger from 'big-integer'
import { getActiveProfile } from '@core/profile'

export function getEstimatedGasForTransferFromTransactionDetails(): Promise<number> {
// TODO: Add impl gas estimate with wasp API
return Promise.resolve(GAS_BUDGET.toJSNumber())
interface GasEstimatePayload {
gasBurned?: number
gasFeeCharged?: number
}

export async function getEstimatedGasForTransferFromTransactionDetails(
serializedOutputHex: string
): Promise<GasEstimatePayload> {
const profile = getActiveProfile()
const chainMetadata = profile.network?.chains?.[0] ?? null

if (chainMetadata) {
const URL = `${chainMetadata.iscpEndpoint}/estimategas-onledger`
const body = JSON.stringify({ outputBytes: serializedOutputHex })

const requestInit: RequestInit = {
method: 'POST',
body,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
}

const response = await fetch(URL, requestInit)

if (response.status === 200) {
const data = await response.json()
const gasBurned = BigInteger(data.gasBurned as string).toJSNumber()
const gasFeeCharged = BigInteger(data.gasFeeCharged as string).toJSNumber()

return { gasBurned, gasFeeCharged }
}
}

return {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@ import type { NewTransactionDetails } from '@core/wallet/types'
import { getAddressFromSubject } from '@core/wallet/utils'
import BigInteger from 'big-integer'
import { SpecialStream } from '../classes'
import { ACCOUNTS_CONTRACT, EXTERNALLY_OWNED_ACCOUNT, GAS_BUDGET, TRANSFER_ALLOWANCE } from '../constants'
import { ACCOUNTS_CONTRACT, EXTERNALLY_OWNED_ACCOUNT, TRANSFER_ALLOWANCE } from '../constants'
import { encodeAddress, encodeAssetAllowance, encodeSmartContractParameters } from '../helpers'
import { getEstimatedGasForTransferFromTransactionDetails } from './getEstimatedGasForTransferFromTransactionDetails'
import { evmAddressToAgentID } from './'

export async function getLayer2MetadataForTransfer(transactionDetails: NewTransactionDetails): Promise<string> {
export function getLayer2MetadataForTransfer(transactionDetails: NewTransactionDetails, estimatedGas?: number): string {
const metadataStream = new SpecialStream()

const address = getAddressFromSubject(transactionDetails.recipient)
const encodedAddress = encodeAddress(address.toLowerCase())

const estimatedGas = await getEstimatedGasForTransferFromTransactionDetails()

metadataStream.writeUInt8('senderContract', EXTERNALLY_OWNED_ACCOUNT)
metadataStream.writeUInt32('targetContract', ACCOUNTS_CONTRACT)
metadataStream.writeUInt32('contractFunction', TRANSFER_ALLOWANCE)
metadataStream.writeUInt64SpecialEncoding('gasBudget', BigInteger(estimatedGas) ?? GAS_BUDGET)
metadataStream.writeUInt64SpecialEncoding(
'gasBudget',
estimatedGas ? BigInteger(estimatedGas) : BigInteger(Number.MAX_SAFE_INTEGER)
)

// transactionDetails.layer2Parameters should never be undefined at this point
const aliasAddress = transactionDetails.layer2Parameters?.networkAddress ?? ''
Expand All @@ -28,6 +28,7 @@ export async function getLayer2MetadataForTransfer(transactionDetails: NewTransa
const parameters = encodeSmartContractParameters(smartContractParameters)
metadataStream.writeBytes('smartContractParameters', parameters.length, parameters)

// TODO Allowance also needs to be updated with estimated gas ???
const allowance = encodeAssetAllowance(transactionDetails)
metadataStream.writeBytes('allowance', allowance.length, allowance)

Expand Down
1 change: 1 addition & 0 deletions packages/shared/lib/core/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export * from './number'
export * from './object'
export * from './os'
export * from './random'
export * from './serializeOutput'
export * from './sort'
export * from './store'
export * from './string'
Expand Down
Loading

0 comments on commit c315744

Please sign in to comment.