Skip to content

Commit

Permalink
fix: nonce error
Browse files Browse the repository at this point in the history
  • Loading branch information
guanbinrui committed Dec 27, 2022
1 parent 893eb7a commit 4514b6e
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 29 deletions.
59 changes: 38 additions & 21 deletions packages/mask/src/plugins/Wallet/services/send.ts
@@ -1,17 +1,19 @@
import { isNil } from 'lodash-es'
import type { JsonRpcPayload, JsonRpcResponse } from 'web3-core-helpers'
import { defer } from '@masknet/kit'
import { Web3 } from '@masknet/web3-providers'
import { SmartPayAccount, Web3 } from '@masknet/web3-providers'
import type { ECKeyIdentifier } from '@masknet/shared-base'
import {
ChainId,
createJsonRpcPayload,
createJsonRpcResponse,
ErrorEditor,
EthereumMethodType,
PayloadEditor,
} from '@masknet/web3-shared-evm'
import { WalletRPC } from '../messages.js'
import { openPopupWindow, removePopupWindow } from '../../../../background/services/helper/index.js'
import { generateSignResult } from '../../../../background/services/identity/index.js'

interface Options {
account?: string
Expand All @@ -22,6 +24,19 @@ interface Options {
popupsWindow?: boolean
}

function getSigner(options: Options) {
const { owner, identifier } = options
if (!owner) throw new Error('Failed to sign transaction.')

return async (message: string) => {
if (identifier) {
const { signature } = await generateSignResult('message', identifier, message)
return signature
}
return WalletRPC.signPersonalMessage(message, owner)
}
}

/**
* Send to built-in RPC endpoints.
*/
Expand All @@ -39,18 +54,23 @@ async function internalSend(
const config = PayloadEditor.fromPayload(payload).signableConfig
if (!config?.from || !config.to) return

const signed = await WalletRPC.signTransaction(config.from as string, {
chainId,
...config,
})
await provider.send(
{
...payload,
method: EthereumMethodType.ETH_SEND_RAW_TRANSACTION,
params: [signed],
},
callback,
)
if (options?.owner) {
const hash = await SmartPayAccount.sendTransaction(chainId, options.owner, config, getSigner(options))
callback(null, createJsonRpcResponse(payload.id as number, hash))
} else {
const signed = await WalletRPC.signTransaction(config.from as string, {
chainId,
...config,
})
await provider.send(
createJsonRpcPayload(payload.id as number, {
method: EthereumMethodType.ETH_SEND_RAW_TRANSACTION,
params: [signed],
}),
callback,
)
}

break
case EthereumMethodType.ETH_SIGN_TYPED_DATA:
const [address, dataToSign] = payload.params as [string, string]
Expand Down Expand Up @@ -125,18 +145,15 @@ export async function confirmRequest(payload: JsonRpcPayload, options?: Options)
payload,
(error, response) => {
UNCONFIRMED_CALLBACK_MAP.get(pid)?.(error, response)
if (error) {
reject(error)
return
}
if (response?.error) {
reject(new Error(`Failed to send transaction: ${response.error?.message ?? response.error}`))
return
}
if (!response) {
reject(new Error('No response.'))
return
}
const editor = ErrorEditor.from(error, response)
if (editor.presence) {
reject(editor.error)
return
}
WalletRPC.deleteUnconfirmedRequest(payload)
.then(() => {
if (!options?.disableClose) removePopupWindow()
Expand Down
11 changes: 6 additions & 5 deletions packages/web3-providers/src/SmartPay/apis/SmartPayAccountAPI.ts
Expand Up @@ -266,14 +266,15 @@ export class SmartPayAccountAPI implements AbstractAccountAPI.Provider<NetworkPl
) {
// fill in initCode
if (isEmptyHex(userTransaction.initCode) && userTransaction.nonce === 0) {
const initCode = await this.getInitCode(chainId, owner)
const accounts = await this.getAccountsByOwner(chainId, owner)
const accountsDeployed = accounts.filter((x) => isSameAddress(x.creator, owner) && x.deployed)

await userTransaction.fill(this.web3.createWeb3(chainId), {
initCode,
nonce: accountsDeployed.length,
})
if (!accountsDeployed.length) {
await userTransaction.fill(this.web3.createWeb3(chainId), {
initCode: await this.getInitCode(chainId, owner),
nonce: accountsDeployed.length,
})
}
}

// sign user operation
Expand Down
7 changes: 4 additions & 3 deletions packages/web3-shared/evm/src/libs/UserTransaction.ts
Expand Up @@ -175,10 +175,11 @@ export class UserTransaction {

// caution: the creator needs to set the latest index of the contract account.
// otherwise, always treat the operation to create the initial account.
if (!nonce) {
if (!walletContract) throw new Error('Failed to create wallet contract.')
if (walletContract) {
const nonce_ = await walletContract.methods.nonce().call()
this.userOperation.nonce = toNumber(nonce_) + 1
this.userOperation.nonce = toNumber(nonce_)
} else {
throw new Error('Failed to create wallet contract.')
}

if (!isEmptyHex(callData)) {
Expand Down

0 comments on commit 4514b6e

Please sign in to comment.