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

feat: show broken tx #1063

Merged
merged 12 commits into from
Jan 30, 2024
5 changes: 5 additions & 0 deletions .changeset/twelve-lemons-divide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'fuels-wallet': patch
---

Add an error message for a failed simulated tx
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,10 @@ export const transactionRequestMachine = createMachine(
// screen doesn't flash between states
await delay(600);
const { txResult } = await TxService.simulateTransaction(input);
if (txResult.isStatusFailure) {
// TODO: add reason for error failure if the sdk supports it
throw new Error(`The transaction will fail to run.`);
}
return { txResult };
},
}),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { cssObj } from '@fuel-ui/css';
import { Alert, Button } from '@fuel-ui/react';
import { TransactionStatus } from 'fuels';
import { useAssets } from '~/systems/Asset';
import { Layout, ConnectInfo } from '~/systems/Core';
import { TopBarType } from '~/systems/Core/components/Layout/TopBar';
Expand All @@ -25,12 +26,24 @@ export function TransactionRequest() {
title={ctx.input.title}
headerText="Requesting a transaction from:"
/>
<Alert status="warning" css={styles.alert}>
<Alert.Title>Confirm before approving</Alert.Title>
<Alert.Description>
Carefully check if all the details in your transaction are correct
</Alert.Description>
</Alert>
{txResult?.status === TransactionStatus.failure ? (
<Alert hideIcon status="error" css={styles.alert}>
<Alert.Title>
Simulating your transaction resulted in an error
</Alert.Title>
<Alert.Description>
{/* TODO: add a reason for the transaction failing if the sdk ever supports it */}
The transaction will fail to run.
</Alert.Description>
</Alert>
) : (
<Alert status="warning" css={styles.alert}>
<Alert.Title>Confirm before approving</Alert.Title>
<Alert.Description>
Carefully check if all the details in your transaction are correct
</Alert.Description>
</Alert>
)}
</>
);

Expand Down Expand Up @@ -91,6 +104,7 @@ export function TransactionRequest() {
intent="primary"
onPress={handlers.approve}
isLoading={ctx.isLoading || status('sending')}
isDisabled={txResult?.status === TransactionStatus.failure}
>
Approve
</Button>
Expand Down
11 changes: 11 additions & 0 deletions packages/app/src/systems/Transaction/services/transaction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
hexlify,
processGqlReceipt,
BN,
TransactionStatus,
} from 'fuels';
import { isEth } from '~/systems/Asset/utils/asset';
import { db, uniqueId, WalletLockedCustom } from '~/systems/Core';
Expand Down Expand Up @@ -189,6 +190,16 @@ export class TxService {
maxInputs,
});

// Workaround until https://github.com/FuelLabs/fuels-ts/issues/1674 is fixed
transactionSummary.isStatusFailure = transactionSummary.receipts.some(
(receipt) => {
return receipt.type === 3;
}
);
if (transactionSummary.isStatusFailure) {
transactionSummary.status = TransactionStatus.failure;
}

return transactionSummary;
}

Expand Down
13 changes: 13 additions & 0 deletions packages/e2e-contract-tests/contracts/custom_asset/src/main.sw
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use token::{
_total_supply,
}
};
use std::{tx::tx_witness_data};

use src20::SRC20;
use src3::SRC3;
Expand Down Expand Up @@ -88,9 +89,21 @@ abi CustomBehavior {
#[storage(read, write)]
#[payable]
fn deposit_half_and_mint_from_external_contract(recipient: Identity, sub_id: SubId, amount: u64, contract_id: ContractId) -> u64;

fn revert_tx();
fn panic_tx();
}

impl CustomBehavior for Contract {
fn revert_tx() {
let signature = tx_witness_data::<b256>(100);
log(signature);
}

fn panic_tx() {
revert(1);
}

#[storage(read, write)]
#[payable]
fn deposit() -> u64 {
Expand Down
2 changes: 2 additions & 0 deletions packages/e2e-contract-tests/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ForwardEthCard,
Header,
MintAssetCard,
RevertCard,
Providers,
DepositHalfEthCard,
ForwardCustomAssetCard,
Expand All @@ -28,6 +29,7 @@ function App() {
<ForwardHalfAndMintCard />
<DepositAndMintMultiCalls />
<AssetConfigurationCard />
<RevertCard />
</div>
<Toaster />
</Providers>
Expand Down
10 changes: 9 additions & 1 deletion packages/e2e-contract-tests/src/components/Providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,13 @@ type ProviderProps = {
};

export const Providers = ({ children }: ProviderProps) => {
return <FuelProvider>{children}</FuelProvider>;
return (
<FuelProvider
fuelConfig={{
devMode: true,
}}
>
{children}
</FuelProvider>
);
};
41 changes: 41 additions & 0 deletions packages/e2e-contract-tests/src/components/RevertCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useAccount, useWallet } from '@fuel-wallet/react';

import { panicTx, revertTx } from '../contract_interactions';

export const RevertCard = () => {
const { account } = useAccount();
const { wallet } = useWallet(account);

return (
<div>
<p>Panic TX</p>
<div aria-label="Panic asset card">
<button
onClick={async () => {
if (wallet) {
await panicTx({
wallet,
});
}
}}
>
Panic
</button>
</div>
<p>Revert TX</p>
<div aria-label="Revert asset card">
<button
onClick={async () => {
if (wallet) {
await revertTx({
wallet,
});
}
}}
>
Revert
</button>
</div>
</div>
);
};
1 change: 1 addition & 0 deletions packages/e2e-contract-tests/src/components/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './Providers';
export * from './Header';
export * from './RevertCard';
export * from './MintAssetCard';
export * from './ForwardEthCard';
export * from './DepositHalfEthCard';
Expand Down
4 changes: 2 additions & 2 deletions packages/e2e-contract-tests/src/contract-ids.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"ExternalContract": "0x2b8b998aabd0ba2792af458022df56e156f78a7e823ee96169882cfe8fd457c6",
"MainContract": "0x210fe0ed3837c987967ed4fd408fb915eb8b1e6da7f6a018f81f88d1dcd49f0c"
"ExternalContract": "0x7c1936543c56af5f490bc830e96c6151b1e464c56146043b6623e241f5a09f83",
"MainContract": "0x88397740fbabaf21f01cf66c22bdfdeae134cbc94d4361af4c6df697542ff8c4"
}
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,21 @@ export const depositAndMintMultiCall = async ({
toast.success('Transaction successful.');
}
};

export const panicTx = async ({ wallet }: { wallet: FuelWalletLocked }) => {
const contract = CustomAssetAbi__factory.connect(MAIN_CONTRACT_ID, wallet);
try {
await contract.functions.panic_tx().txParams(TX_PARAMS).call();
} catch (err) {
toast.error((err as Error).message);
}
};

export const revertTx = async ({ wallet }: { wallet: FuelWalletLocked }) => {
const contract = CustomAssetAbi__factory.connect(MAIN_CONTRACT_ID, wallet);
try {
await contract.functions.revert_tx().txParams(TX_PARAMS).call();
} catch (err) {
toast.error((err as Error).message);
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ interface CustomAssetAbiInterface extends Interface {
deposit_half: FunctionFragment;
deposit_half_and_mint: FunctionFragment;
deposit_half_and_mint_from_external_contract: FunctionFragment;
panic_tx: FunctionFragment;
revert_tx: FunctionFragment;
};

encodeFunctionData(
Expand Down Expand Up @@ -98,6 +100,8 @@ interface CustomAssetAbiInterface extends Interface {
functionFragment: 'deposit_half_and_mint_from_external_contract',
values: [IdentityInput, string, BigNumberish, ContractIdInput]
): Uint8Array;
encodeFunctionData(functionFragment: 'panic_tx', values: []): Uint8Array;
encodeFunctionData(functionFragment: 'revert_tx', values: []): Uint8Array;

decodeFunctionData(
functionFragment: 'decimals',
Expand Down Expand Up @@ -131,6 +135,14 @@ interface CustomAssetAbiInterface extends Interface {
functionFragment: 'deposit_half_and_mint_from_external_contract',
data: BytesLike
): DecodedValue;
decodeFunctionData(
functionFragment: 'panic_tx',
data: BytesLike
): DecodedValue;
decodeFunctionData(
functionFragment: 'revert_tx',
data: BytesLike
): DecodedValue;
}

export class CustomAssetAbi extends Contract {
Expand Down Expand Up @@ -161,5 +173,7 @@ export class CustomAssetAbi extends Contract {
],
BN
>;
panic_tx: InvokeFunction<[], void>;
revert_tx: InvokeFunction<[], void>;
};
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -474,16 +474,36 @@ const _abi = {
typeArguments: null,
},
attributes: [
{
name: 'storage',
arguments: ['read', 'write'],
},
{
name: 'payable',
arguments: [],
},
{
name: 'storage',
arguments: ['read', 'write'],
},
],
},
{
inputs: [],
name: 'panic_tx',
output: {
name: '',
type: 0,
typeArguments: null,
},
attributes: null,
},
{
inputs: [],
name: 'revert_tx',
output: {
name: '',
type: 0,
typeArguments: null,
},
attributes: null,
},
],
loggedTypes: [
{
Expand All @@ -494,6 +514,14 @@ const _abi = {
typeArguments: [],
},
},
{
logId: 1,
loggedType: {
name: '',
type: 1,
typeArguments: null,
},
},
],
messagesTypes: [],
configurables: [],
Expand Down
Loading