mirror of
https://github.com/zhigang1992/wallet.git
synced 2026-04-24 04:45:58 +08:00
refactor: remove sha.js in favour of nobel hashes
This commit is contained in:
@@ -129,6 +129,7 @@
|
||||
"@emotion/react": "11.7.1",
|
||||
"@emotion/styled": "11.6.0",
|
||||
"@ledgerhq/hw-transport-webusb": "6.24.1",
|
||||
"@noble/hashes": "1.1.4",
|
||||
"@noble/secp256k1": "1.6.3",
|
||||
"@reach/alert": "0.15.3",
|
||||
"@reach/auto-id": "0.15.3",
|
||||
@@ -178,7 +179,7 @@
|
||||
"ecdsa-sig-formatter": "1.0.11",
|
||||
"formik": "2.2.9",
|
||||
"jotai": "1.5.3",
|
||||
"jsontokens": "3.0.0",
|
||||
"jsontokens": "4.0.1",
|
||||
"limiter": "2.1.0",
|
||||
"lodash.get": "4.4.2",
|
||||
"mdi-react": "7.5.0",
|
||||
@@ -199,7 +200,6 @@
|
||||
"react-virtuoso": "2.19.1",
|
||||
"redux-persist": "6.0.0",
|
||||
"rxjs": "7.5.7",
|
||||
"sha.js": "2.4.11",
|
||||
"ts-debounce": "4",
|
||||
"use-events": "1.4.2",
|
||||
"use-latest": "1.2.0",
|
||||
|
||||
@@ -34,9 +34,7 @@ export function LedgerScreenDetail(props: LedgerScreenDetailProps) {
|
||||
)}
|
||||
</Caption>
|
||||
<Flex alignItems="center" mt="base">
|
||||
<Text overflowWrap="break-word" maxWidth={['280px', '360px']}>
|
||||
{children}
|
||||
</Text>
|
||||
<Text overflowWrap="break-word">{children}</Text>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { sha256 } from '@noble/hashes/sha256';
|
||||
import { bytesToHex } from '@stacks/common';
|
||||
import StacksApp from '@zondax/ledger-stacks';
|
||||
import ecdsaFormat from 'ecdsa-sig-formatter';
|
||||
import { sha256 } from 'sha.js';
|
||||
|
||||
import { getIdentityDerivationPath } from '../../ledger-utils';
|
||||
|
||||
@@ -17,7 +18,7 @@ export function addSignatureToAuthResponseJwt(authResponse: string, signature: U
|
||||
}
|
||||
|
||||
export function getSha256HashOfJwtAuthPayload(payload: string) {
|
||||
return new sha256().update(payload).digest('hex');
|
||||
return bytesToHex(sha256(payload));
|
||||
}
|
||||
|
||||
export function signLedgerJwtHash(app: StacksApp) {
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { sha256 } from '@noble/hashes/sha256';
|
||||
import { bytesToHex } from '@stacks/common';
|
||||
import {
|
||||
ChainID,
|
||||
ClarityType,
|
||||
ClarityValue,
|
||||
cvToString,
|
||||
encodeStructuredData,
|
||||
} from '@stacks/transactions';
|
||||
|
||||
import { SignedMessageStructured } from '@shared/signature/signature-types';
|
||||
|
||||
import { whenStxChainId } from '@app/common/utils';
|
||||
|
||||
export function cvToDisplay(cv: ClarityValue): string {
|
||||
return cvToString(cv).replaceAll('"', '');
|
||||
}
|
||||
|
||||
export function chainIdToDisplay(chainIdCv: ClarityValue): string {
|
||||
if (chainIdCv.type !== ClarityType.UInt) return '';
|
||||
const chainIdString = cvToString(chainIdCv);
|
||||
const chainId = parseInt(chainIdString.replace('u', ''));
|
||||
if (!Object.values(ChainID).includes(chainId)) return '';
|
||||
|
||||
return whenStxChainId(chainId as ChainID)({
|
||||
[ChainID.Testnet]: 'Testnet',
|
||||
[ChainID.Mainnet]: 'Mainnet',
|
||||
});
|
||||
}
|
||||
|
||||
export function deriveStructuredMessageHash({
|
||||
domain,
|
||||
message,
|
||||
}: Omit<SignedMessageStructured, 'messageType'>) {
|
||||
return bytesToHex(sha256(encodeStructuredData({ message, domain })));
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { cvToString } from '@stacks/transactions';
|
||||
|
||||
import { logger } from '@shared/logger';
|
||||
import { whenSignedMessageOfType } from '@shared/signature/signature-types';
|
||||
|
||||
import { ApproveLedgerOperationLayout } from '../../../generic-steps';
|
||||
import { useHasApprovedOperation } from '../../../hooks/use-has-approved-transaction';
|
||||
import { ledgerMsgSigningContext } from '../ledger-sign-msg.context';
|
||||
import { cvToDisplay, deriveStructuredMessageHash } from '../message-signing.utils';
|
||||
|
||||
export function SignLedgerMessage() {
|
||||
const { message } = useContext(ledgerMsgSigningContext);
|
||||
@@ -26,16 +25,26 @@ export function SignLedgerMessage() {
|
||||
status={hasApprovedOperation ? 'approved' : 'awaiting-approval'}
|
||||
/>
|
||||
),
|
||||
structured: domain => (
|
||||
<ApproveLedgerOperationLayout
|
||||
description="Sign structured data on your Ledger"
|
||||
details={[
|
||||
['Chain ID', cvToString(domain.data['chain-id'])],
|
||||
['Name', cvToString(domain.data.name)],
|
||||
['Version', cvToString(domain.data.version)],
|
||||
]}
|
||||
status={hasApprovedOperation ? 'approved' : 'awaiting-approval'}
|
||||
/>
|
||||
),
|
||||
structured: (domain, message) => {
|
||||
const ledgerFirstHashPageInView = 34;
|
||||
const hash = deriveStructuredMessageHash({ domain, message });
|
||||
const [hashPart1, hashPart2] = [
|
||||
hash.slice(0, ledgerFirstHashPageInView),
|
||||
hash.slice(ledgerFirstHashPageInView),
|
||||
];
|
||||
return (
|
||||
<ApproveLedgerOperationLayout
|
||||
description="Sign structured data on your Ledger"
|
||||
details={[
|
||||
['Chain ID', cvToDisplay(domain.data['chain-id'])],
|
||||
['Name', cvToDisplay(domain.data.name)],
|
||||
['Version', cvToDisplay(domain.data.version)],
|
||||
['Message hash [1/2]', hashPart1],
|
||||
['Message hash [2/2]', hashPart2],
|
||||
]}
|
||||
status={hasApprovedOperation ? 'approved' : 'awaiting-approval'}
|
||||
/>
|
||||
);
|
||||
},
|
||||
}) as JSX.Element;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ import {
|
||||
chainIdToDisplay,
|
||||
cvToDisplay,
|
||||
deriveStructuredMessageHash,
|
||||
} from '../message-signing.utils';
|
||||
} from '@app/features/ledger/flows/message-signing/message-signing.utils';
|
||||
|
||||
import { ClarityValueListDisplayer } from './clarity-value-list';
|
||||
import { HashDrawer } from './hash-drawer';
|
||||
|
||||
|
||||
@@ -1,21 +1,10 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import {
|
||||
ChainID,
|
||||
ClarityType,
|
||||
ClarityValue,
|
||||
TupleCV,
|
||||
createStacksPrivateKey,
|
||||
cvToString,
|
||||
encodeStructuredData,
|
||||
} from '@stacks/transactions';
|
||||
import { sha256 } from 'sha.js';
|
||||
import { ClarityValue, TupleCV, createStacksPrivateKey } from '@stacks/transactions';
|
||||
|
||||
import { signMessage, signStructuredDataMessage } from '@shared/crypto/sign-message';
|
||||
import { SignedMessageStructured } from '@shared/signature/signature-types';
|
||||
import { isString } from '@shared/utils';
|
||||
|
||||
import { whenStxChainId } from '@app/common/utils';
|
||||
import { useCurrentAccount } from '@app/store/accounts/account.hooks';
|
||||
|
||||
export function useMessageSignerSoftwareWallet() {
|
||||
@@ -35,26 +24,3 @@ export function useMessageSignerSoftwareWallet() {
|
||||
[account]
|
||||
);
|
||||
}
|
||||
|
||||
export function cvToDisplay(cv: ClarityValue): string {
|
||||
return cvToString(cv).replaceAll('"', '');
|
||||
}
|
||||
|
||||
export function chainIdToDisplay(chainIdCv: ClarityValue): string {
|
||||
if (chainIdCv.type !== ClarityType.UInt) return '';
|
||||
const chainIdString = cvToString(chainIdCv);
|
||||
const chainId = parseInt(chainIdString.replace('u', ''));
|
||||
if (!Object.values(ChainID).includes(chainId)) return '';
|
||||
|
||||
return whenStxChainId(chainId as ChainID)({
|
||||
[ChainID.Testnet]: 'Testnet',
|
||||
[ChainID.Mainnet]: 'Mainnet',
|
||||
});
|
||||
}
|
||||
|
||||
export function deriveStructuredMessageHash({
|
||||
domain,
|
||||
message,
|
||||
}: Omit<SignedMessageStructured, 'messageType'>) {
|
||||
return new sha256().update(encodeStructuredData({ message, domain })).digest('hex');
|
||||
}
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Box, Button, Text } from '@stacks/ui';
|
||||
import {
|
||||
stacksMainnetNetwork,
|
||||
stacksTestnetNetwork as network,
|
||||
stacksTestnetNetwork,
|
||||
} from '@common/utils';
|
||||
import { SignatureData } from '@stacks/connect';
|
||||
|
||||
import {
|
||||
stacksTestnetNetwork as network,
|
||||
stacksMainnetNetwork,
|
||||
stacksTestnetNetwork,
|
||||
} from '@common/utils';
|
||||
import { sha256 } from '@noble/hashes/sha256';
|
||||
import { bytesToHex } from '@noble/hashes/utils';
|
||||
import { SignatureData } from '@stacks/connect';
|
||||
import { useConnect } from '@stacks/connect-react';
|
||||
import { hashMessage, verifyMessageSignatureRsv } from '@stacks/encryption';
|
||||
import { StacksNetwork } from '@stacks/network';
|
||||
import {
|
||||
ClarityValue,
|
||||
TupleCV,
|
||||
bufferCVFromString,
|
||||
contractPrincipalCV,
|
||||
encodeStructuredData,
|
||||
falseCV,
|
||||
intCV,
|
||||
listCV,
|
||||
@@ -23,14 +30,8 @@ import {
|
||||
trueCV,
|
||||
tupleCV,
|
||||
uintCV,
|
||||
ClarityValue,
|
||||
encodeStructuredData,
|
||||
TupleCV,
|
||||
} from '@stacks/transactions';
|
||||
import { useConnect } from '@stacks/connect-react';
|
||||
import { hashMessage, verifyMessageSignatureRsv } from '@stacks/encryption';
|
||||
import { sha256 } from 'sha.js';
|
||||
import { StacksNetwork } from '@stacks/network';
|
||||
import { Box, Button, Text } from '@stacks/ui';
|
||||
|
||||
export const Signature = () => {
|
||||
const [signature, setSignature] = useState<SignatureData | undefined>();
|
||||
@@ -90,7 +91,7 @@ export const Signature = () => {
|
||||
useEffect(() => {
|
||||
if (!signatureStructured || !currentStructuredData) return;
|
||||
const message = encodeStructuredData(currentStructuredData);
|
||||
const messageHash = new sha256().update(message).digest('hex');
|
||||
const messageHash = bytesToHex(sha256(message));
|
||||
const verified = verifyMessageSignatureRsv({
|
||||
...signatureStructured,
|
||||
message: Buffer.from(messageHash, 'hex'),
|
||||
|
||||
29
yarn.lock
29
yarn.lock
@@ -2281,6 +2281,11 @@
|
||||
strict-event-emitter "^0.2.0"
|
||||
xmldom "^0.6.0"
|
||||
|
||||
"@noble/hashes@1.1.4":
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.4.tgz#2611ebf5764c1bf754da7c7794de4fb30512336d"
|
||||
integrity sha512-+PYsVPrTSqtVjatKt2A/Proukn2Yrz61OBThOCKErc5w2/r1Fh37vbDv0Eah7pyNltrmacjwTvdw3JoR+WE4TA==
|
||||
|
||||
"@noble/hashes@^1.0.0", "@noble/hashes@^1.1.2", "@noble/hashes@^1.1.3", "@noble/hashes@~1.1.1", "@noble/hashes@~1.1.3":
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.3.tgz#360afc77610e0a61f3417e497dcf36862e4f8111"
|
||||
@@ -5865,7 +5870,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/dragula/-/dragula-3.7.1.tgz#79940c2b9a9f0bc5f7d0c486f2cb56651f73170c"
|
||||
integrity sha512-hbMEG5+wZEwV6NK4cbexldLWEvYNox8PywM9ICIeCTM99g8nJxccE3C8vvl66TCfnN+R8ioNdOrHWJT+5X0pvw==
|
||||
|
||||
"@types/elliptic@^6.4.12", "@types/elliptic@^6.4.9":
|
||||
"@types/elliptic@^6.4.12":
|
||||
version "6.4.14"
|
||||
resolved "https://registry.yarnpkg.com/@types/elliptic/-/elliptic-6.4.14.tgz#7bbaad60567a588c1f08b10893453e6b9b4de48e"
|
||||
integrity sha512-z4OBcDAU0GVwDTuwJzQCiL6188QvZMkvoERgcVjq0/mPM8jCfdwZ3x5zQEVoL9WCAru3aG5wl3Z5Ww5wBWn7ZQ==
|
||||
@@ -7493,7 +7498,7 @@ array.prototype.flat@^1.2.5:
|
||||
es-abstract "^1.19.2"
|
||||
es-shim-unscopables "^1.0.0"
|
||||
|
||||
asn1.js@^5.0.1, asn1.js@^5.2.0:
|
||||
asn1.js@^5.2.0:
|
||||
version "5.4.1"
|
||||
resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07"
|
||||
integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==
|
||||
@@ -7806,7 +7811,7 @@ base64id@1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6"
|
||||
integrity sha512-rz8L+d/xByiB/vLVftPkyY215fqNrmasrcJsYkVcm4TgJNz+YXKrFaFAWibSaHkiKoSgMDCb+lipOIRQNGYesw==
|
||||
|
||||
base64url@3.0.1, base64url@^3.0.1:
|
||||
base64url@3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d"
|
||||
integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==
|
||||
@@ -9899,7 +9904,7 @@ ecc-jsbn@~0.1.1:
|
||||
jsbn "~0.1.0"
|
||||
safer-buffer "^2.1.0"
|
||||
|
||||
ecdsa-sig-formatter@1.0.11, ecdsa-sig-formatter@^1.0.11:
|
||||
ecdsa-sig-formatter@1.0.11:
|
||||
version "1.0.11"
|
||||
resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
|
||||
integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
|
||||
@@ -9925,7 +9930,7 @@ electron@^18.0.1:
|
||||
"@types/node" "^16.11.26"
|
||||
extract-zip "^1.0.3"
|
||||
|
||||
elliptic@^6.4.0, elliptic@^6.4.1, elliptic@^6.5.2, elliptic@^6.5.3:
|
||||
elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3:
|
||||
version "6.5.4"
|
||||
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
|
||||
integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==
|
||||
@@ -13882,19 +13887,7 @@ jsonrpc-lite@^2.2.0:
|
||||
resolved "https://registry.yarnpkg.com/jsonrpc-lite/-/jsonrpc-lite-2.2.0.tgz#fb3aa9d292c8970eb7f83c6040c6554767bbc6a6"
|
||||
integrity sha512-/cbbSxtZWs1O7R4tWqabrCM/t3N8qKUZMAg9IUqpPvUs6UyRvm6pCNYkskyKN/XU0UgffW+NY2ZRr8t0AknX7g==
|
||||
|
||||
jsontokens@3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsontokens/-/jsontokens-3.0.0.tgz#629984d260a4081b11541313acdba708377314d3"
|
||||
integrity sha512-P0QZC5AjOkn3t1ej6OuI7+XqoEctYj83UK4pw0WpHY4/z6a5PpZCJSpp5NZodq94GFkw2PfB9DPFoDM5qpyp/g==
|
||||
dependencies:
|
||||
"@types/elliptic" "^6.4.9"
|
||||
asn1.js "^5.0.1"
|
||||
base64url "^3.0.1"
|
||||
ecdsa-sig-formatter "^1.0.11"
|
||||
elliptic "^6.4.1"
|
||||
sha.js "^2.4.11"
|
||||
|
||||
jsontokens@^4.0.1:
|
||||
jsontokens@4.0.1, jsontokens@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/jsontokens/-/jsontokens-4.0.1.tgz#c3edf74a01160b2ca6d62b021b288edd59d1184a"
|
||||
integrity sha512-+MO415LEN6M+3FGsRz4wU20g7N2JA+2j9d9+pGaNJHviG4L8N0qzavGyENw6fJqsq9CcrHOIL6iWX5yeTZ86+Q==
|
||||
|
||||
Reference in New Issue
Block a user