Skip to content

Commit

Permalink
feat: [Sale Widget] Skip sending approve txn to wallet when allowance…
Browse files Browse the repository at this point in the history
… balance is sufficient (#1627)

Co-authored-by: Mimi Tran <[email protected]>
  • Loading branch information
jhesgodi and mimi-imtbl authored Mar 26, 2024
1 parent 003da5f commit 65cd502
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { BigNumber, ethers } from 'ethers';
import { Web3Provider } from '@ethersproject/providers';

import { SignedTransaction } from '../types';

export const filterAllowedTransactions = async (
transactions: SignedTransaction[],
provider: Web3Provider,
): Promise<SignedTransaction[]> => {
try {
const signer = provider.getSigner();
const signerAddress = await signer.getAddress();
const approveTxn = transactions.find((txn) => txn.methodCall.startsWith('approve'));

if (!approveTxn || !signer || !signerAddress) {
return transactions;
}

const contract = new ethers.Contract(
approveTxn.tokenAddress,
['function allowance(address,address) view returns (uint256)'],
signer,
);

const allowance = await signer?.call({
to: approveTxn.tokenAddress,
data: contract.interface.encodeFunctionData('allowance', [
signerAddress,
approveTxn.params.spender,
]),
});

const currentAmount = BigNumber.from(allowance);
const desiredAmount = approveTxn.params.amount ? BigNumber.from(approveTxn.params.amount) : BigNumber.from(0);

const isAllowed = currentAmount.gte(BigNumber.from('0')) && currentAmount.gte(desiredAmount);

if (isAllowed) {
return transactions.filter((txn) => txn.methodCall !== approveTxn.methodCall);
}
} catch {
/* Ignoring errors, as we don't need block wallet from
* sending the approve when it's not possible to check the allowance
*/
}

return transactions;
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from '../types';
import { PRIMARY_SALES_API_BASE_URL } from '../utils/config';
import { hexToText } from '../functions/utils';
import { filterAllowedTransactions } from '../functions/signUtils';

type SignApiTransaction = {
contract_address: string;
Expand Down Expand Up @@ -143,9 +144,8 @@ const toSignResponse = (
rawData: transaction.raw_data,
})),
transactionId: hexToText(
transactions
.find((txn) => txn.method_call.startsWith('execute'))
?.params.reference || '',
transactions.find((txn) => txn.method_call.startsWith('execute'))?.params
.reference || '',
),
};
};
Expand Down Expand Up @@ -327,7 +327,7 @@ export const useSignOrder = (input: SignOrderInput) => {
onTxnSuccess: (txn: ExecutedTransaction) => void,
onTxnError: (error: any, txns: ExecutedTransaction[]) => void,
): Promise<ExecutedTransaction[]> => {
if (!signData) {
if (!signData || !provider) {
setSignError({
type: SaleErrorTypes.DEFAULT,
data: { reason: 'No sign data' },
Expand All @@ -338,7 +338,13 @@ export const useSignOrder = (input: SignOrderInput) => {

let successful = true;
const execTransactions: ExecutedTransaction[] = [];
for (const transaction of signData.transactions) {

const transactions = await filterAllowedTransactions(
signData.transactions,
provider,
);

for (const transaction of transactions) {
const {
tokenAddress: to,
rawData: data,
Expand Down

0 comments on commit 65cd502

Please sign in to comment.