diff --git a/src/components/tx-flow/flows/SafeAppsTx/ReviewSafeAppsTx.tsx b/src/components/tx-flow/flows/SafeAppsTx/ReviewSafeAppsTx.tsx
index d83a5d33ef..4580b6021f 100644
--- a/src/components/tx-flow/flows/SafeAppsTx/ReviewSafeAppsTx.tsx
+++ b/src/components/tx-flow/flows/SafeAppsTx/ReviewSafeAppsTx.tsx
@@ -50,12 +50,12 @@ const ReviewSafeAppsTx = ({
createSafeTx().then(setSafeTx).catch(setSafeTxError)
}, [txList, setSafeTx, setSafeTxError, params])
- const handleSubmit = async () => {
+ const handleSubmit = async (txId: string) => {
if (!safeTx || !onboard) return
trackSafeAppTxCount(Number(appId))
try {
- await dispatchSafeAppsTx(safeTx, requestId, onboard, safe.chainId)
+ await dispatchSafeAppsTx(safeTx, requestId, onboard, safe.chainId, txId)
} catch (error) {
setSafeTxError(asError(error))
}
diff --git a/src/components/tx/SignOrExecuteForm/ExecuteForm.tsx b/src/components/tx/SignOrExecuteForm/ExecuteForm.tsx
index 3afcb8ca1e..5056e3b5b9 100644
--- a/src/components/tx/SignOrExecuteForm/ExecuteForm.tsx
+++ b/src/components/tx/SignOrExecuteForm/ExecuteForm.tsx
@@ -88,9 +88,9 @@ const ExecuteForm = ({
const txOptions = getTxOptions(advancedParams, currentChain)
+ let executedTxId: string
try {
- const executedTxId = await executeTx(txOptions, safeTx, txId, origin, willRelay, tx)
- setTxFlow(, undefined, false)
+ executedTxId = await executeTx(txOptions, safeTx, txId, origin, willRelay, tx)
} catch (_err) {
const err = asError(_err)
trackError(Errors._804, err)
@@ -99,7 +99,9 @@ const ExecuteForm = ({
return
}
- onSubmit()
+ // On success
+ setTxFlow(, undefined, false)
+ onSubmit(executedTxId)
}
const cannotPropose = !isOwner && !onlyExecute
diff --git a/src/components/tx/SignOrExecuteForm/SignForm.tsx b/src/components/tx/SignOrExecuteForm/SignForm.tsx
index 7f9b48675f..34a96b9246 100644
--- a/src/components/tx/SignOrExecuteForm/SignForm.tsx
+++ b/src/components/tx/SignOrExecuteForm/SignForm.tsx
@@ -56,8 +56,9 @@ const SignForm = ({
setIsSubmittable(false)
setSubmitError(undefined)
+ let resultTxId: string
try {
- await (isAddingToBatch ? addToBatch(safeTx, origin) : signTx(safeTx, txId, origin, tx))
+ resultTxId = await (isAddingToBatch ? addToBatch(safeTx, origin) : signTx(safeTx, txId, origin, tx))
} catch (_err) {
const err = asError(_err)
trackError(Errors._805, err)
@@ -66,8 +67,9 @@ const SignForm = ({
return
}
+ // On success
setTxFlow(undefined)
- onSubmit()
+ onSubmit(resultTxId)
}
const onBatchClick = (e: SyntheticEvent) => {
diff --git a/src/components/tx/SignOrExecuteForm/index.tsx b/src/components/tx/SignOrExecuteForm/index.tsx
index 8f843169cf..d64f5fb0aa 100644
--- a/src/components/tx/SignOrExecuteForm/index.tsx
+++ b/src/components/tx/SignOrExecuteForm/index.tsx
@@ -22,7 +22,7 @@ import { isDelegateCall } from '@/services/tx/tx-sender/sdk'
export type SignOrExecuteProps = {
txId?: string
- onSubmit: () => void
+ onSubmit: (txId: string) => void
children?: ReactNode
isExecutable?: boolean
isRejection?: boolean
diff --git a/src/services/safe-wallet-provider/index.ts b/src/services/safe-wallet-provider/index.ts
index 9bf098533c..03177d9b5c 100644
--- a/src/services/safe-wallet-provider/index.ts
+++ b/src/services/safe-wallet-provider/index.ts
@@ -13,7 +13,10 @@ export type AppInfo = {
export type WalletSDK = {
signMessage: (message: string, appInfo: AppInfo) => Promise<{ signature?: string }>
signTypedMessage: (typedData: unknown, appInfo: AppInfo) => Promise<{ signature?: string }>
- send: (params: { txs: unknown[]; params: { safeTxGas: number } }, appInfo: AppInfo) => Promise<{ safeTxHash: string }>
+ send: (
+ params: { txs: unknown[]; params: { safeTxGas: number } },
+ appInfo: AppInfo,
+ ) => Promise<{ safeTxHash: string; txHash?: string }>
getBySafeTxHash: (safeTxHash: string) => Promise<{ txHash?: string }>
switchChain: (chainId: string, appInfo: AppInfo) => Promise
proxy: (method: string, params: unknown[]) => Promise
@@ -50,11 +53,11 @@ export class SafeWalletProvider {
this.sdk = sdk
}
- private async makeRequest(id: number, request: RpcRequest, appInfo: AppInfo): Promise {
+ private async makeRequest(request: RpcRequest, appInfo: AppInfo): Promise {
const { method, params = [] } = request
switch (method) {
- case 'wallet_switchEthereumChain':
+ case 'wallet_switchEthereumChain': {
const [{ chainId }] = params as [{ chainId: string }]
try {
await this.sdk.switchChain(chainId, appInfo)
@@ -62,13 +65,16 @@ export class SafeWalletProvider {
throw new RpcError(RpcErrorCode.UNSUPPORTED_CHAIN, 'Unsupported chain')
}
return null
+ }
- case 'eth_accounts':
+ case 'eth_accounts': {
return [this.safe.safeAddress]
+ }
case 'net_version':
- case 'eth_chainId':
+ case 'eth_chainId': {
return `0x${this.safe.chainId.toString(16)}`
+ }
case 'personal_sign': {
const [message, address] = params as [string, string]
@@ -110,7 +116,7 @@ export class SafeWalletProvider {
return signature || '0x'
}
- case 'eth_sendTransaction':
+ case 'eth_sendTransaction': {
const tx = {
value: '0',
data: '0x',
@@ -124,7 +130,7 @@ export class SafeWalletProvider {
tx.gas = parseInt(tx.gas, 16)
}
- const { safeTxHash } = await this.sdk.send(
+ const { safeTxHash, txHash } = await this.sdk.send(
{
txs: [tx],
params: { safeTxGas: Number(tx.gas) },
@@ -132,6 +138,8 @@ export class SafeWalletProvider {
appInfo,
)
+ if (txHash) return txHash
+
// Store fake transaction
this.submittedTxs.set(safeTxHash, {
from: this.safe.safeAddress,
@@ -148,8 +156,9 @@ export class SafeWalletProvider {
})
return safeTxHash
+ }
- case 'eth_getTransactionByHash':
+ case 'eth_getTransactionByHash': {
let txHash = params[0] as string
try {
const resp = await this.sdk.getBySafeTxHash(txHash)
@@ -161,6 +170,7 @@ export class SafeWalletProvider {
return this.submittedTxs.get(txHash)
}
return await this.sdk.proxy(method, [txHash])
+ }
case 'eth_getTransactionReceipt': {
let txHash = params[0] as string
@@ -171,8 +181,9 @@ export class SafeWalletProvider {
return this.sdk.proxy(method, params)
}
- default:
+ default: {
return await this.sdk.proxy(method, params)
+ }
}
}
@@ -199,7 +210,7 @@ export class SafeWalletProvider {
return {
jsonrpc: '2.0',
id,
- result: await this.makeRequest(id, request, appInfo),
+ result: await this.makeRequest(request, appInfo),
}
} catch (e) {
return {
diff --git a/src/services/safe-wallet-provider/useSafeWalletProvider.tsx b/src/services/safe-wallet-provider/useSafeWalletProvider.tsx
index 1f48ef2a2d..5396781ae8 100644
--- a/src/services/safe-wallet-provider/useSafeWalletProvider.tsx
+++ b/src/services/safe-wallet-provider/useSafeWalletProvider.tsx
@@ -1,4 +1,4 @@
-import { useContext, useMemo } from 'react'
+import { useContext, useEffect, useMemo, useRef } from 'react'
import { BigNumber } from 'ethers'
import { useRouter } from 'next/router'
@@ -22,6 +22,15 @@ export const _useTxFlowApi = (chainId: string, safeAddress: string): WalletSDK |
const web3ReadOnly = useWeb3ReadOnly()
const router = useRouter()
const { configs } = useChains()
+ const pendingTxs = useRef>({})
+
+ useEffect(() => {
+ const unsubscribe = txSubscribe(TxEvent.PROCESSING, async ({ txId, txHash }) => {
+ if (!txId) return
+ pendingTxs.current[txId] = txHash
+ })
+ return unsubscribe
+ }, [])
return useMemo(() => {
if (!chainId || !safeAddress) return
@@ -50,7 +59,7 @@ export const _useTxFlowApi = (chainId: string, safeAddress: string): WalletSDK |
},
async send(params: { txs: any[]; params: { safeTxGas: number } }, appInfo) {
- const id = Math.random().toString(36).slice(2) // TODO: use JsonRpc id
+ const id = Math.random().toString(36).slice(2)
const transactions = params.txs.map(({ to, value, data }) => {
return {
@@ -77,9 +86,10 @@ export const _useTxFlowApi = (chainId: string, safeAddress: string): WalletSDK |
)
return new Promise((resolve) => {
- const unsubscribe = txSubscribe(TxEvent.SAFE_APPS_REQUEST, async ({ safeAppRequestId, safeTxHash }) => {
+ const unsubscribe = txSubscribe(TxEvent.SAFE_APPS_REQUEST, async ({ safeAppRequestId, safeTxHash, txId }) => {
if (safeAppRequestId === id) {
- resolve({ safeTxHash })
+ const txHash = pendingTxs.current[txId]
+ resolve({ safeTxHash, txHash })
unsubscribe()
}
})
diff --git a/src/services/tx/tx-sender/dispatch.ts b/src/services/tx/tx-sender/dispatch.ts
index a5a885d0e5..81c1938e37 100644
--- a/src/services/tx/tx-sender/dispatch.ts
+++ b/src/services/tx/tx-sender/dispatch.ts
@@ -316,10 +316,11 @@ export const dispatchSafeAppsTx = async (
safeAppRequestId: RequestId,
onboard: OnboardAPI,
chainId: SafeInfo['chainId'],
+ txId: string,
) => {
const sdk = await getSafeSDKWithSigner(onboard, chainId)
const safeTxHash = await sdk.getTransactionHash(safeTx)
- txDispatch(TxEvent.SAFE_APPS_REQUEST, { safeAppRequestId, safeTxHash })
+ txDispatch(TxEvent.SAFE_APPS_REQUEST, { safeAppRequestId, safeTxHash, txId })
}
export const dispatchTxRelay = async (
diff --git a/src/services/tx/txEvents.ts b/src/services/tx/txEvents.ts
index 6e63e527b1..4417a25e62 100644
--- a/src/services/tx/txEvents.ts
+++ b/src/services/tx/txEvents.ts
@@ -44,7 +44,7 @@ interface TxEvents {
[TxEvent.RELAYING]: Id & { taskId: string }
[TxEvent.FAILED]: Id & HumanDescription & { error: Error }
[TxEvent.SUCCESS]: Id & HumanDescription
- [TxEvent.SAFE_APPS_REQUEST]: { safeAppRequestId: RequestId; safeTxHash: string }
+ [TxEvent.SAFE_APPS_REQUEST]: { txId: string; safeAppRequestId: RequestId; safeTxHash: string }
[TxEvent.BATCH_ADD]: Id
}