Skip to content

Commit

Permalink
fix(ledger): stacks contract call signing, closes #4478
Browse files Browse the repository at this point in the history
  • Loading branch information
kyranjamie committed Nov 4, 2023
1 parent e813e55 commit e7b2b6a
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 50 deletions.
33 changes: 17 additions & 16 deletions src/app/pages/transaction-request/transaction-request.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import get from 'lodash.get';
import * as yup from 'yup';

import { HIGH_FEE_WARNING_LEARN_MORE_URL_STX } from '@shared/constants';
import { logger } from '@shared/logger';
import { FeeTypes } from '@shared/models/fees/fees.model';
import { StacksTransactionFormValues } from '@shared/models/form.model';
import { RouteUrls } from '@shared/route-urls';
Expand All @@ -15,15 +16,13 @@ import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { LoadingKeys, useLoading } from '@app/common/hooks/use-loading';
import { useOnMount } from '@app/common/hooks/use-on-mount';
import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { useWalletType } from '@app/common/use-wallet-type';
import { stxFeeValidator } from '@app/common/validation/forms/fee-validators';
import { nonceValidator } from '@app/common/validation/nonce-validators';
import { EditNonceButton } from '@app/components/edit-nonce-button';
import { NonceSetter } from '@app/components/nonce-setter';
import { PopupHeader } from '@app/features/current-account/popup-header';
import { RequestingTabClosedWarningMessage } from '@app/features/errors/requesting-tab-closed-error-msg';
import { HighFeeDrawer } from '@app/features/high-fee-drawer/high-fee-drawer';
import { useLedgerNavigate } from '@app/features/ledger/hooks/use-ledger-navigate';
import { ContractCallDetails } from '@app/features/stacks-transaction-request/contract-call-details/contract-call-details';
import { ContractDeployDetails } from '@app/features/stacks-transaction-request/contract-deploy-details/contract-deploy-details';
import { FeeForm } from '@app/features/stacks-transaction-request/fee-form';
Expand All @@ -40,41 +39,43 @@ import { useNextNonce } from '@app/query/stacks/nonce/account-nonces.hooks';
import { useTransactionRequestState } from '@app/store/transactions/requests.hooks';
import {
useGenerateUnsignedStacksTransaction,
useSoftwareWalletTransactionRequestBroadcast,
useSignStacksTransaction,
useStacksTransactionBroadcast,
useUnsignedStacksTransactionBaseState,
} from '@app/store/transactions/transaction.hooks';

function TransactionRequestBase() {
const transactionRequest = useTransactionRequestState();
const { setIsLoading, setIsIdle } = useLoading(LoadingKeys.SUBMIT_TRANSACTION_REQUEST);
const handleBroadcastTransaction = useSoftwareWalletTransactionRequestBroadcast();
// const handleBroadcastTransaction = useSoftwareWalletTransactionRequestBroadcast();
const unsignedTx = useUnsignedStacksTransactionBaseState();
const { data: stxFees } = useCalculateStacksTxFees(unsignedTx.transaction);
const analytics = useAnalytics();
const { walletType } = useWalletType();
const generateUnsignedTx = useGenerateUnsignedStacksTransaction();
const { data: stacksBalances } = useCurrentStacksAccountAnchoredBalances();
const ledgerNavigate = useLedgerNavigate();
const { data: nextNonce } = useNextNonce();
const navigate = useNavigate();
const signStacksTransaction = useSignStacksTransaction();
const txBroadcast = useStacksTransactionBroadcast();

useRouteHeader(<PopupHeader />);

useOnMount(() => {
void analytics.track('view_transaction_signing'), [analytics];
});
useOnMount(() => void analytics.track('view_transaction_signing'));

const onSubmit = async (values: StacksTransactionFormValues) => {
if (walletType === 'ledger') {
const tx = await generateUnsignedTx(values);
if (!tx) return;
ledgerNavigate.toConnectAndSignTransactionStep(tx);
return;
}
const unsignedTx = await generateUnsignedTx(values);

if (!unsignedTx)
return logger.error('Failed to generate unsigned transaction in transaction-request');

const signedTx = await signStacksTransaction(unsignedTx);

if (!signedTx) return logger.error('Failed to sign transaction in transaction-request');

setIsLoading();

try {
await handleBroadcastTransaction(values);
await txBroadcast({ signedTx });
setIsIdle();
} catch (e) {
navigate(RouteUrls.TransactionBroadcastError, { state: { message: get(e, 'message') } });
Expand Down
35 changes: 1 addition & 34 deletions src/app/store/transactions/transaction.hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export function useUnsignedPrepareTransactionDetails(values: StacksTransactionFo
return useMemo(() => unsignedStacksTransaction, [unsignedStacksTransaction]);
}

function useStacksTransactionBroadcast() {
export function useStacksTransactionBroadcast() {
const submittedTransactionsActions = useSubmittedTransactionsActions();
const { tabId } = useDefaultRequestParams();
const requestToken = useTransactionRequest();
Expand Down Expand Up @@ -133,39 +133,6 @@ function useStacksTransactionBroadcast() {
};
}

export function useSoftwareWalletTransactionRequestBroadcast() {
const { data: nextNonce } = useNextNonce();
const signSoftwareWalletTx = useSignTransactionSoftwareWallet();
const stacksTxBaseState = useUnsignedStacksTransactionBaseState();
const { tabId } = useDefaultRequestParams();
const requestToken = useTransactionRequest();
const account = useCurrentStacksAccount();
const txBroadcast = useStacksTransactionBroadcast();

return async (values: StacksTransactionFormValues) => {
if (!stacksTxBaseState) return;
const { options } = stacksTxBaseState as any;
const unsignedStacksTransaction = await generateUnsignedTransaction({
...options,
fee: stxToMicroStx(values.fee).toNumber(),
nonce: Number(values.nonce) ?? nextNonce?.nonce,
});

if (!account || !requestToken || !unsignedStacksTransaction) {
return { error: { message: 'No pending transaction' } };
}

if (!tabId) throw new Error('tabId not defined');

const signedTx = signSoftwareWalletTx(unsignedStacksTransaction);
if (!signedTx) {
logger.error('Cannot sign transaction, no account in state');
return;
}
return txBroadcast({ signedTx });
};
}

interface PostConditionsOptions {
contractAddress: string;
contractAssetName: string;
Expand Down

0 comments on commit e7b2b6a

Please sign in to comment.