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

Mahmoud/eng 3111 integrate with stacks raw hex signing on extension #652

Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d3d7da9
init tx hex handling
m-aboelenein Nov 2, 2023
9a299ef
Merge branch 'develop' into mahmoud/eng-3111-integrate-with-stacks-ra…
m-aboelenein Nov 9, 2023
3c4dbce
added stx hex tx signing support
m-aboelenein Nov 9, 2023
ce32d7b
Merge branch 'develop' into mahmoud/eng-3111-integrate-with-stacks-ra…
m-aboelenein Nov 15, 2023
257853a
integrate with connect core utils
m-aboelenein Nov 16, 2023
c236db2
fix stx tx serialization
m-aboelenein Nov 16, 2023
7d7ec42
handle sign-hex for dapp interactions
m-aboelenein Nov 16, 2023
18051f4
update core version
m-aboelenein Nov 16, 2023
308588b
add auh to tx-creation
m-aboelenein Nov 17, 2023
2250045
Merge remote-tracking branch 'origin/develop' into mahmoud/eng-3111-i…
m-aboelenein Nov 22, 2023
4fcd9f6
Merge remote-tracking branch 'origin/develop' into mahmoud/eng-3111-i…
m-aboelenein Nov 22, 2023
d596b0d
Merge remote-tracking branch 'refs/remotes/origin/develop'
m-aboelenein Nov 30, 2023
156fd64
fix pending txs handling
m-aboelenein Nov 30, 2023
a5103b2
fix type issues
m-aboelenein Dec 1, 2023
4171497
Merge remote-tracking branch 'origin/develop' into mahmoud/eng-3111-i…
m-aboelenein Dec 4, 2023
fef354f
update core version
m-aboelenein Dec 4, 2023
0d0a5c4
Merge remote-tracking branch 'origin/develop' into mahmoud/eng-3111-i…
m-aboelenein Dec 18, 2023
d3d8657
revert removing signMultipleTransactions
m-aboelenein Dec 18, 2023
38b5a92
update core version
m-aboelenein Dec 18, 2023
06b05aa
Merge remote-tracking branch 'origin/develop' into mahmoud/eng-3111-i…
m-aboelenein Dec 20, 2023
5e33c8d
remove unused package aliases
m-aboelenein Dec 27, 2023
45d9f63
Tim/eng 3475 nonce not updating correctly after switching accounts (#…
teebszet Dec 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,087 changes: 406 additions & 1,681 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@
"@ledgerhq/hw-transport-webusb": "^6.27.13",
"@phosphor-icons/react": "^2.0.10",
"@react-spring/web": "^9.6.1",
"@secretkeylabs/xverse-core": "6.0.1",
"@stacks/connect": "^6.10.2",
"@stacks/encryption": "4.3.5",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like we currently still include @stacks/encryption in webpack/webpack.config.js, so I think it would make sense to remove it from there as well

"@secretkeylabs/xverse-core": "6.0.1-3d747a3",
"@stacks/connect": "7.4.1",
"@stacks/stacks-blockchain-api-types": "6.1.1",
"@stacks/transactions": "4.3.8",
"@stacks/transactions": "6.9.0",
"@tanstack/query-sync-storage-persister": "^4.29.1",
"@tanstack/react-query": "^4.29.3",
"@tanstack/react-query-devtools": "^4.29.3",
Expand Down
22 changes: 13 additions & 9 deletions src/app/components/confirmStxTransactionComponent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,10 @@ interface Props {
isAsset?: boolean;
title?: string;
subTitle?: string;
hasSignatures?: boolean;
}

function ConfirmStxTransationComponent({
function ConfirmStxTransactionComponent({
initialStxTransactions,
loading,
isSponsored,
Expand All @@ -142,6 +143,7 @@ function ConfirmStxTransationComponent({
onConfirmClick,
onCancelClick,
skipModal = false,
hasSignatures = false,
}: Props) {
const { t } = useTranslation('translation', { keyPrefix: 'CONFIRM_TRANSACTION' });
const { t: signatureRequestTranslate } = useTranslation('translation', {
Expand Down Expand Up @@ -280,7 +282,7 @@ function ConfirmStxTransationComponent({
try {
const signedTxs = await signLedgerStxTransaction({
transport,
transactionBuffer: initialStxTransactions[0].serialize(),
transactionBuffer: Buffer.from(initialStxTransactions[0].serialize()),
addressIndex: selectedAccount.deviceAccountIndex,
});
setIsTxApproved(true);
Expand Down Expand Up @@ -334,12 +336,14 @@ function ConfirmStxTransationComponent({
{isSponsored ? (
<SponsoredInfoText>{t('SPONSORED_TX_INFO')}</SponsoredInfoText>
) : (
<Button onClick={onAdvancedSettingClick}>
<>
<ButtonImage src={SettingIcon} />
<ButtonText>{t('ADVANCED_SETTING')}</ButtonText>
</>
</Button>
!hasSignatures && (
<Button onClick={onAdvancedSettingClick}>
<>
<ButtonImage src={SettingIcon} />
<ButtonText>{t('ADVANCED_SETTING')}</ButtonText>
</>
</Button>
)
)}
<TransactionSettingAlert
visible={openTransactionSettingModal}
Expand Down Expand Up @@ -407,4 +411,4 @@ function ConfirmStxTransationComponent({
);
}

export default ConfirmStxTransationComponent;
export default ConfirmStxTransactionComponent;
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/* eslint-disable no-nested-ternary */
import { StoreState } from '@stores/index';
import { useSelector } from 'react-redux';
import {
addressToString,
FungibleConditionCode,
NonFungibleConditionCode,
PostCondition,
} from '@stacks/transactions';
import { StoreState } from '@stores/index';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';

import TransferAmountComponent from '@components/transferAmountComponent';
import { getNameFromPostCondition, getSymbolFromPostCondition } from './helper';
Expand Down Expand Up @@ -36,9 +36,9 @@ function PostConditionsView({ postCondition, amount, icon }: Props) {
return t('TRANSFER_LESS');
case FungibleConditionCode.LessEqual:
return t('TRANSFER_LESS_EQUAL');
case NonFungibleConditionCode.DoesNotOwn:
case NonFungibleConditionCode.Sends:
return t('TRANSFER_DOES_NOT_OWN');
case NonFungibleConditionCode.Owns:
case NonFungibleConditionCode.DoesNotSend:
return t('TRANSFER_OWN');
default:
return '';
Expand Down
25 changes: 21 additions & 4 deletions src/app/components/transactionsRequests/ContractCallRequest.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import AccountHeaderComponent from '@components/accountHeader';
import ConfirmStxTransationComponent from '@components/confirmStxTransactionComponent';
import ConfirmStxTransactionComponent from '@components/confirmStxTransactionComponent';
import InfoContainer from '@components/infoContainer';
import FtPostConditionCard from '@components/postCondition/ftPostConditionCard';
import NftPostConditionCard from '@components/postCondition/nftPostConditionCard';
Expand All @@ -11,15 +11,18 @@ import {
addressToString,
Args,
broadcastSignedTransaction,
buf2hex,
Coin,
ContractFunction,
extractFromPayload,
isMultiSig,
} from '@secretkeylabs/xverse-core';
import { ContractCallPayload } from '@stacks/connect';
import {
ClarityType,
cvToJSON,
cvToString,
MultiSigSpendingCondition,
PostConditionType,
SomeCV,
StacksTransaction,
Expand Down Expand Up @@ -85,6 +88,12 @@ export default function ContractCallRequest(props: ContractCallRequestProps) {
const [hasTabClosed, setHasTabClosed] = useState(false);
const { t } = useTranslation('translation');

// SignTransaction Params
const isMultiSigTx = isMultiSig(unsignedTx);
const hasSignatures =
isMultiSigTx &&
(unsignedTx.auth.spendingCondition as MultiSigSpendingCondition).fields?.length > 0;

useOnOriginTabClose(tabId, () => {
setHasTabClosed(true);
window.scrollTo({ top: 0, behavior: 'smooth' });
Expand Down Expand Up @@ -175,7 +184,7 @@ export default function ContractCallRequest(props: ContractCallRequestProps) {
finalizeTxSignature({
requestPayload: requestToken,
tabId,
data: { txId: broadcastResult, txRaw: tx[0].serialize().toString('hex') },
data: { txId: broadcastResult, txRaw: buf2hex(tx[0].serialize()) },
});
navigate('/tx-status', {
state: {
Expand Down Expand Up @@ -208,6 +217,13 @@ export default function ContractCallRequest(props: ContractCallRequestProps) {
browserTx: true,
},
});
} else if (isMultiSigTx) {
finalizeTxSignature({
requestPayload: requestToken,
tabId,
data: { txId: '', txRaw: buf2hex(unsignedTx.serialize()) },
});
window.close();
} else {
broadcastTx(transactions, attachment);
}
Expand Down Expand Up @@ -248,13 +264,14 @@ export default function ContractCallRequest(props: ContractCallRequestProps) {
return (
<>
<AccountHeaderComponent disableMenuOption disableAccountSwitch />
<ConfirmStxTransationComponent
<ConfirmStxTransactionComponent
initialStxTransactions={[unsignedTx]}
onConfirmClick={confirmCallback}
onCancelClick={cancelCallback}
loading={false}
title={request.functionName}
subTitle={`Requested by ${request.appDetails?.name}`}
hasSignatures={hasSignatures}
>
<>
{hasTabClosed && (
Expand All @@ -272,7 +289,7 @@ export default function ContractCallRequest(props: ContractCallRequestProps) {
/>
{functionArgsView()}
</>
</ConfirmStxTransationComponent>
</ConfirmStxTransactionComponent>
</>
);
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import DownloadImage from '@assets/img/webInteractions/ArrowLineDown.svg';
import AccountHeaderComponent from '@components/accountHeader';
import ConfirmStxTransationComponent from '@components/confirmStxTransactionComponent';
import ConfirmStxTransactionComponent from '@components/confirmStxTransactionComponent';
import InfoContainer from '@components/infoContainer';
import StxPostConditionCard from '@components/postCondition/stxPostConditionCard';
import TransactionDetailComponent from '@components/transactionDetailComponent';
import useNetworkSelector from '@hooks/useNetwork';
import useOnOriginTabClose from '@hooks/useOnTabClosed';
import { broadcastSignedTransaction } from '@secretkeylabs/xverse-core';
import { PostCondition, StacksTransaction } from '@stacks/transactions';
import { broadcastSignedTransaction, buf2hex, isMultiSig } from '@secretkeylabs/xverse-core';
import { MultiSigSpendingCondition, PostCondition, StacksTransaction } from '@stacks/transactions';
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
Expand Down Expand Up @@ -111,6 +111,12 @@ export default function ContractDeployRequest(props: ContractDeployRequestProps)
const [loaderForBroadcastingTx, setLoaderForBroadcastingTx] = useState<boolean>(false);
const navigate = useNavigate();

// SignTransaction Params
const isMultiSigTx = isMultiSig(unsignedTx);
const hasSignatures =
isMultiSigTx &&
(unsignedTx.auth.spendingCondition as MultiSigSpendingCondition).fields?.length > 0;

useOnOriginTabClose(tabId, () => {
setHasTabClosed(true);
window.scrollTo({ top: 0, behavior: 'smooth' });
Expand All @@ -124,7 +130,7 @@ export default function ContractDeployRequest(props: ContractDeployRequestProps)
finalizeTxSignature({
requestPayload: requestToken,
tabId,
data: { txId: broadcastResult, txRaw: tx[0].serialize().toString('hex') },
data: { txId: broadcastResult, txRaw: buf2hex(tx[0].serialize()) },
});
navigate('/tx-status', {
state: {
Expand Down Expand Up @@ -160,6 +166,13 @@ export default function ContractDeployRequest(props: ContractDeployRequestProps)
browserTx: true,
},
});
} else if (isMultiSigTx) {
finalizeTxSignature({
requestPayload: requestToken,
tabId,
data: { txId: '', txRaw: buf2hex(unsignedTx.serialize()) },
});
window.close();
} else {
broadcastTx(txs);
}
Expand Down Expand Up @@ -199,13 +212,14 @@ export default function ContractDeployRequest(props: ContractDeployRequestProps)
return (
<>
<AccountHeaderComponent disableMenuOption disableAccountSwitch />
<ConfirmStxTransationComponent
<ConfirmStxTransactionComponent
initialStxTransactions={[unsignedTx!]}
onConfirmClick={confirmCallback}
onCancelClick={cancelCallback}
loading={loaderForBroadcastingTx}
isSponsored={sponsored}
title={t('DEPLOY_CONTRACT_REQUEST.DEPLOY_CONTRACT')}
hasSignatures={hasSignatures}
>
{hasTabClosed && (
<InfoContainer
Expand Down Expand Up @@ -233,7 +247,7 @@ export default function ContractDeployRequest(props: ContractDeployRequestProps)
</Button>
</DownloadButtonContainer>
</DownloadContainer>
</ConfirmStxTransationComponent>
</ConfirmStxTransactionComponent>
</>
);
}
4 changes: 2 additions & 2 deletions src/app/hooks/queries/useStxPendingTxData.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { fetchStxPendingTxData } from '@secretkeylabs/xverse-core';
import { fetchStxPendingTxData, StxPendingTxData } from '@secretkeylabs/xverse-core';
import { StoreState } from '@stores/index';
import { useQuery } from '@tanstack/react-query';
import { useSelector } from 'react-redux';
Expand All @@ -9,7 +9,7 @@ const useStxPendingTxData = () => {
const selectedNetwork = useNetworkSelector();
const result = useQuery({
queryKey: ['stx-pending-transaction', { stxAddress, selectedNetwork }],
queryFn: () => fetchStxPendingTxData(stxAddress, selectedNetwork),
queryFn: (): Promise<StxPendingTxData> => fetchStxPendingTxData(stxAddress, selectedNetwork),
});
return result;
};
Expand Down
41 changes: 41 additions & 0 deletions src/app/hooks/useStxTransactionRequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { txPayloadToRequest } from '@secretkeylabs/xverse-core';
import { deserializeTransaction } from '@stacks/transactions';
import { decodeToken } from 'jsontokens';
import { useLocation } from 'react-router-dom';

const useStxTransactionRequest = () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be good to have a return type here. related to the core code review on txPayloadToRequest

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an issue with strictly typing this hook since the types that are exposed from the @stacks/connect lib have errors with the types themselves so until that's resolved loosely typing here is our only solution.

I will open an issue on the @stacks/connect repo and add a follow-up issue.

const { search } = useLocation();
const params = new URLSearchParams(search);
const requestToken = params.get('request') ?? '';
const request = decodeToken(requestToken) as any;
const tabId = params.get('tabId') ?? '0';
const stacksTransaction = request.payload.txHex
? deserializeTransaction(request.payload.txHex!)
: undefined;

const getPayload = () => {
if (stacksTransaction) {
const txPayload = txPayloadToRequest(
stacksTransaction,
request.payload.stxAddress,
request.payload.attachment,
);
return {
...request.payload,
...txPayload,
};
}
return request.payload;
};

const txPayload = getPayload();

return {
payload: txPayload,
stacksTransaction,
tabId,
requestToken,
};
};

export default useStxTransactionRequest;
17 changes: 0 additions & 17 deletions src/app/hooks/useTransationRequest.ts

This file was deleted.

8 changes: 4 additions & 4 deletions src/app/screens/confirmFtTransaction/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ConfirmStxTransactionState, LedgerTransactionType } from '@common/types/ledger';
import ConfirmStxTransationComponent from '@components/confirmStxTransactionComponent';
import ConfirmStxTransactionComponent from '@components/confirmStxTransactionComponent';
import TransferMemoView from '@components/confirmStxTransactionComponent/transferMemoView';
import RecipientComponent from '@components/recipientComponent';
import BottomBar from '@components/tabBar';
Expand Down Expand Up @@ -73,7 +73,7 @@ function ConfirmFtTransaction() {
if (isLedgerAccount(selectedAccount)) {
const type: LedgerTransactionType = 'STX';
const state: ConfirmStxTransactionState = {
unsignedTx: unsignedTx.serialize(),
unsignedTx: Buffer.from(unsignedTx.serialize()),
type,
recipients: [{ address: recepientAddress, amountMicrostacks: new BigNumber(amount) }],
fee: new BigNumber(unsignedTx.auth.spendingCondition.fee.toString()),
Expand All @@ -100,7 +100,7 @@ function ConfirmFtTransaction() {
return (
<>
<TopRow title={t('CONFIRM_TX')} onClick={handleBackButtonClick} />
<ConfirmStxTransationComponent
<ConfirmStxTransactionComponent
initialStxTransactions={[unsignedTx]}
loading={isLoading}
onConfirmClick={handleOnConfirmClick}
Expand All @@ -116,7 +116,7 @@ function ConfirmFtTransaction() {
/>
<TransactionDetailComponent title={t('NETWORK')} value={network.type} />
{memo && <TransferMemoView memo={memo} />}
</ConfirmStxTransationComponent>
</ConfirmStxTransactionComponent>
<BottomBar tab="dashboard" />
</>
);
Expand Down
Loading
Loading