Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/current forward flow fixes optimise #183

Merged
merged 10 commits into from
Jun 9, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const _abi = [
];

const _bytecode =
"0x608060405234801561001057600080fd5b5061023e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806325d9185c1461003b578063d1f9cf0e14610045575b600080fd5b610043610058565b005b6100436100533660046100e6565b610092565b60405162461bcd60e51b815260206004820152600b60248201526a1d195cdd081c995d995c9d60aa1b604482015260640160405180910390fd5b7f603c3fe9b00ecddbd86daa6cbfe9a7f26505792913b8d1dec79052d86b5f79df3233836040516100c593929190610197565b60405180910390a150565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156100f857600080fd5b813567ffffffffffffffff8082111561011057600080fd5b818401915084601f83011261012457600080fd5b813581811115610136576101366100d0565b604051601f8201601f19908116603f0116810190838211818310171561015e5761015e6100d0565b8160405282815287602084870101111561017757600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060018060a01b038086168352602081861681850152606060408501528451915081606085015260005b828110156101de578581018201518582016080015281016101c2565b828111156101f0576000608084870101525b5050601f01601f19169190910160800194935050505056fea26469706673582212202258db3067be70dc7bfd710a72216c79357b90810ae1fd2b7c88c194287ef80464736f6c634300080f0033";
"0x608060405234801561001057600080fd5b5061023e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806325d9185c1461003b578063d1f9cf0e14610045575b600080fd5b610043610058565b005b6100436100533660046100e6565b610092565b60405162461bcd60e51b815260206004820152600b60248201526a1d195cdd081c995d995c9d60aa1b604482015260640160405180910390fd5b7f603c3fe9b00ecddbd86daa6cbfe9a7f26505792913b8d1dec79052d86b5f79df3233836040516100c593929190610197565b60405180910390a150565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156100f857600080fd5b813567ffffffffffffffff8082111561011057600080fd5b818401915084601f83011261012457600080fd5b813581811115610136576101366100d0565b604051601f8201601f19908116603f0116810190838211818310171561015e5761015e6100d0565b8160405282815287602084870101111561017757600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060018060a01b038086168352602081861681850152606060408501528451915081606085015260005b828110156101de578581018201518582016080015281016101c2565b828111156101f0576000608084870101525b5050601f01601f19169190910160800194935050505056fea2646970667358221220adfdaf0f2a159497a5cd3bbb9c519d83cb218db6bf996bdd27b34d0ca957f5bd64736f6c634300080f0033";

type SampleRecipientConstructorParams =
| [signer?: Signer]
Expand Down

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/core-types/src/SmartAccountTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export type SmartAccountState = {
isDeployed: boolean // chain specific
entryPointAddress: string // chain specific?
implementationAddress: string
factoryAddress: string
fallbackHandlerAddress: string // chain specific?
}

Expand Down
2 changes: 2 additions & 0 deletions packages/relayer/src/RestRelayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ export class RestRelayer implements IRelayer {

Logger.log('finalRawTx', finalRawRx)

Logger.log('gas limit being sent to the relayer', gasLimit)

// based on the flag make rpc call to relayer code service with necessary rawTx data
/* eslint-disable @typescript-eslint/no-explicit-any */
const response: any = await sendRequest({
Expand Down
244 changes: 76 additions & 168 deletions packages/smart-account/src/SmartAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import {
ZERO_ADDRESS,
IFallbackAPI
} from '@biconomy/core-types'
import EvmNetworkManager from '@biconomy/ethers-lib'

import NodeClient, {
ISmartAccount,
ChainConfig,
Expand All @@ -46,6 +48,7 @@ import { JsonRpcProvider, Provider, Web3Provider } from '@ethersproject/provider
import { IRelayer, RestRelayer, FallbackRelayer, IFallbackRelayer } from '@biconomy/relayer'
import * as _ from 'lodash'
import TransactionManager, {
getSmartWalletFactoryContract,
ContractUtils,
encodeMultiSend,
smartAccountSignMessage,
Expand Down Expand Up @@ -246,7 +249,6 @@ class SmartAccount extends EventEmitter {
chainId: network.chainId,
version: this.DEFAULT_VERSION
})
this.address = walletInfo.smartAccountAddress
Logger.log('smart wallet address is ', this.address)

const readProvider = new ethers.providers.JsonRpcProvider(providerUrl)
Expand Down Expand Up @@ -325,126 +327,6 @@ class SmartAccount extends EventEmitter {
// Optional methods for connecting paymaster
// Optional methods for connecting another bundler

async sendFallbackTransaction(transactionDto: TransactionDto): Promise<TransactionResponse> {
let { version, chainId } = transactionDto
chainId = chainId ? chainId : this.#smartAccountConfig.activeNetworkId
version = version ? version : this.DEFAULT_VERSION

await this.initializeAtChain(chainId)

// create IWalletTransaction instance
const transaction = await this.createTransaction(transactionDto)

// create instance of SmartWallet contracts
const walletContract = this.contractUtils.attachWalletContract(
chainId,
this.DEFAULT_VERSION,
this.address
)

const signature = await this.signUserPaidTransaction({
version: this.DEFAULT_VERSION,
tx: transaction,
chainId,
signer: this.signer
})
const refundInfo: IFeeRefundV1_0_0 | IFeeRefundV1_0_1 = {
baseGas: transaction.baseGas,
gasPrice: transaction.gasPrice,
tokenGasPriceFactor: transaction.tokenGasPriceFactor,
gasToken: transaction.gasToken,
refundReceiver: transaction.refundReceiver
}

const execTransactionData = await walletContract.interface.encodeFunctionData(
'execTransaction',
[transaction, refundInfo, signature]
)

// create instance of fallbackGasTank contracts to get nonce
const fallbackGasTank =
this.contractUtils.fallbackGasTankContract[chainId][version].getContract()
const gasTankNonce = await fallbackGasTank.getNonce(this.address)

const isDeployed = await this.contractUtils.isDeployed(chainId, this.address)
// dappIdentifier and signature will be added by signing service
const fallbackUserOp = {
sender: this.address,
target: this.address,
nonce: gasTankNonce,
callData: execTransactionData || '',
callGasLimit: BigNumber.from(800000), // will be updated below
dappIdentifier: '',
signature: ''
}
if (!isDeployed) {
const network = this.chainConfig.find((element: ChainConfig) => element.chainId === chainId)
if (!network) throw new Error('No Network Found for given chainid')

const { multiSendCall, walletFactory } = this.getSmartAccountContext(chainId)
const deployWalletEncodedData = await deployCounterFactualEncodedData({
chainId: (await this.provider.getNetwork())?.chainId,
owner: await this.owner,
txServiceUrl: this.#smartAccountConfig.backendUrl,
index: 0
})
const txs = [
{
to: walletFactory.getAddress(),
value: 0,
data: deployWalletEncodedData,
operation: 0
},
{
to: this.address,
value: 0,
data: execTransactionData || '',
operation: 0
}
]
const txnData = multiSendCall
.getInterface()
.encodeFunctionData('multiSend', [encodeMultiSend(txs)])
Logger.log('txnData', txnData)

// update fallbackUserOp with target and multiSend call data
fallbackUserOp.target = multiSendCall.getAddress()
fallbackUserOp.callData = txnData
}

Logger.log('fallbackUserOp before', fallbackUserOp)
// send fallback user operation to signing service to get signature and dappIdentifier
const signingServiceResponse = await this.signingService.getDappIdentifierAndSign(
fallbackUserOp
)
fallbackUserOp.dappIdentifier = signingServiceResponse.dappIdentifier
fallbackUserOp.signature = signingServiceResponse.signature
Logger.log('fallbackUserOp after', fallbackUserOp)

const handleFallBackData = await fallbackGasTank.populateTransaction.handleFallbackUserOp(
fallbackUserOp
)

const rawTrx: RawTransactionType = {
to: fallbackGasTank.address, // gas tank address
data: handleFallBackData.data, // populateTransaction by fallbackGasTank contract handleFallbackUserop
value: 0, // tx value
chainId: chainId
}
const signedTx: SignedTransaction = {
rawTx: rawTrx,
tx: transaction
}
const state = await this.contractUtils.getSmartAccountState()
const relayTrx: RelayTransaction = {
signedTx,
config: state,
context: this.getSmartAccountContext(chainId)
}
const relayResponse = await this.fallbackRelayer.relay(relayTrx, this)
return relayResponse
}

/**
* @description this function will make complete transaction data for updateImplementationTrx
* @param chainId
Expand Down Expand Up @@ -531,18 +413,6 @@ class SmartAccount extends EventEmitter {
transactionDto: TransactionDto // TODO: revise DTO as per above
// isUpdateImpTrx?: Boolean
): Promise<TransactionResponse> {
let isFallbackEnabled = false
try {
const { data } = await this.nodeClient.isFallbackEnabled()
isFallbackEnabled = data.enable_fallback_flow
Logger.log('isFallbackEnabled', data.enable_fallback_flow)
} catch (error) {
console.error('isFallbackEnabled', error)
}

if (isFallbackEnabled) {
return this.sendFallbackTransaction(transactionDto)
}

let { chainId } = transactionDto
chainId = chainId ? chainId : this.#smartAccountConfig.activeNetworkId
Expand Down Expand Up @@ -617,13 +487,11 @@ class SmartAccount extends EventEmitter {
*/
async setSmartAccountVersion(smartAccountVersion: SmartAccountVersion): Promise<SmartAccount> {
this.DEFAULT_VERSION = smartAccountVersion
this.address = (
await this.getAddress({
index: 0,
chainId: this.#smartAccountConfig.activeNetworkId,
version: this.DEFAULT_VERSION
})
).smartAccountAddress
await this.getAddress({
index: 0,
chainId: this.#smartAccountConfig.activeNetworkId,
version: this.DEFAULT_VERSION
})
return this
}

Expand Down Expand Up @@ -732,7 +600,6 @@ class SmartAccount extends EventEmitter {
const { tx } = sendUserPaidTransactionDto
chainId = chainId ? chainId : this.#smartAccountConfig.activeNetworkId
const { gasLimit } = sendUserPaidTransactionDto
const isDeployed = await this.contractUtils.isDeployed(chainId, this.address)
const rawTx: RawTransactionType = {
to: tx.to,
data: tx.data,
Expand Down Expand Up @@ -778,7 +645,11 @@ class SmartAccount extends EventEmitter {
rawTx.data = execTransaction.data

const state = await this.contractUtils.getSmartAccountState()

if ( !state.isDeployed ){
const isDeployed = await this.isDeployed(chainId)
state.isDeployed = isDeployed
this.contractUtils.setSmartAccountState(state)
}
const signedTx: SignedTransaction = {
rawTx,
tx
Expand All @@ -790,19 +661,19 @@ class SmartAccount extends EventEmitter {
}
if (gasLimit) {
relayTrx.gasLimit = gasLimit
} else {
} /*else {
relayTrx.gasLimit = {
hex: '0x16E360',
type: 'hex'
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can remove the commented code too

}
}*/

if (!isDeployed) {
/*if (!isDeployed) {
relayTrx.gasLimit = {
hex: '0x1E8480',
type: 'hex'
}
}
}*/
const relayResponse: RelayResponse = await this.relayer.relay(relayTrx, this)
if (relayResponse.transactionId) {
return relayResponse.transactionId
Expand Down Expand Up @@ -862,6 +733,11 @@ class SmartAccount extends EventEmitter {
rawTx.data = execTransaction.data

const state = await this.contractUtils.getSmartAccountState()
if ( !state.isDeployed ){
const isDeployed = await this.isDeployed(chainId)
state.isDeployed = isDeployed
this.contractUtils.setSmartAccountState(state)
}

const signedTx: SignedTransaction = {
rawTx,
Expand Down Expand Up @@ -1062,34 +938,66 @@ class SmartAccount extends EventEmitter {

async getAddress(
addressForCounterFactualWalletDto: AddressForCounterFactualWalletDto
): Promise<ISmartAccount> {
const { index, chainId } = addressForCounterFactualWalletDto

const walletInfo = await getWalletInfo({
chainId,
owner: this.owner,
txServiceUrl: this.#smartAccountConfig.backendUrl,
index
})

Logger.log('walletInfo ', walletInfo)

this.address = walletInfo.smartAccountAddress

): Promise<SmartAccountState> {
const { index, chainId, version } = addressForCounterFactualWalletDto

// const walletInfo = await getWalletInfo({
// chainId,
// owner: this.owner,
// txServiceUrl: this.#smartAccountConfig.backendUrl,
// index
// })

console.log(version, index, chainId);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove console.log

const network = this.chainConfig.find((element: ChainConfig) => element.chainId === chainId)
if (!network) throw new Error("Could not found network")
const smartAccountState = {
chainId: chainId,
version: walletInfo.version,
address: walletInfo.smartAccountAddress,
version: version,
address: this.address,
owner: this.owner,
isDeployed: walletInfo.isDeployed, // could be set as state in init
entryPointAddress: walletInfo.entryPointAddress,
implementationAddress: walletInfo.implementationAddress,
fallbackHandlerAddress: walletInfo.fallBackHandlerAddress,
factoryAddress: walletInfo.factoryAddress
isDeployed: false, // could be set as state in init
entryPointAddress: network.entryPoint[network.entryPoint.length - 1].address,
implementationAddress: network.wallet[network.wallet.length - 1].address,
fallbackHandlerAddress: network.fallBackHandler[network.fallBackHandler.length - 1].address,
factoryAddress: network.walletFactory[network.walletFactory.length - 1].address
}

let exist
try {
exist = this.contractUtils.smartWalletContract[chainId][this.DEFAULT_VERSION].getContract()
const address = await this.contractUtils.smartWalletFactoryContract[chainId][
version
].getAddressForCounterFactualAccount(this.owner, index)
this.address = address
smartAccountState.isDeployed = await this.isDeployed(chainId)
} catch (err) {
Logger.log('Chain config contract not loaded ', chainId)
const providerUrl = this.getProviderUrl(network)
const evmManager = new EvmNetworkManager({
ethers,
signer: this.signer,
provider: new ethers.providers.JsonRpcProvider(providerUrl)
})
const sVersionType = version as SmartAccountVersion
const factoryContract = getSmartWalletFactoryContract(
sVersionType,
evmManager,
smartAccountState.factoryAddress
)
const address = await factoryContract.getAddressForCounterFactualAccount(this.owner, index)
const isDeployed = await evmManager.isContractDeployed(address)
console.log(' isDeployed ', isDeployed)
smartAccountState.isDeployed = isDeployed
this.address = address
}
smartAccountState.address = this.address

this.contractUtils.setSmartAccountState(smartAccountState)

return walletInfo

return smartAccountState
}

/**
Expand Down
8 changes: 4 additions & 4 deletions packages/transactions/src/ContractUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class ContractUtils {
initializeContracts(
signer: Signer,
readProvider: ethers.providers.JsonRpcProvider,
walletInfo: ISmartAccount,
walletInfo: SmartAccountState,
chaininfo: ChainConfig
) {
this.ethAdapter[walletInfo.chainId] = new EvmNetworkManager({
Expand All @@ -66,7 +66,7 @@ class ContractUtils {
this.multiSendCallOnlyContract[walletInfo.chainId] = {}
this.fallbackGasTankContract[walletInfo.chainId] = {}
//this.defaultCallbackHandlerContract[walletInfo.chainId] = {}
const version = walletInfo.version
const version = walletInfo.version as SmartAccountVersion
Logger.log('version ', version)

this.smartWalletFactoryContract[walletInfo.chainId][version] = getSmartWalletFactoryContract(
Expand All @@ -79,9 +79,9 @@ class ContractUtils {
this.smartWalletContract[walletInfo.chainId][version] = getSmartWalletContract(
version,
this.ethAdapter[walletInfo.chainId],
walletInfo.smartAccountAddress
walletInfo.address
)
Logger.log('SmartAccount Address ', walletInfo.smartAccountAddress)
Logger.log('SmartAccount Address ', walletInfo.address)

this.multiSendContract[walletInfo.chainId][version] = getMultiSendContract(
version,
Expand Down
Loading