-
-
Notifications
You must be signed in to change notification settings - Fork 657
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add basic WIP integration to test with * Setup SignTx component * Fix a few small issues * Fix wrong wallet id * Add connections slice * Move HD wallet session to Redux * Use saved credentials if possible * Use saved credentials for signing * Use default ETH path for testnets with GridPlus * Fix some types and tests * Fix wrong import * Merge legacy HW components * Use saved credentials for legacy flow * Update copy and add icon * Add action to grab wallet connection * Fix more copy and layout * Dispatch connectWallet more often * Add GridPlus illustration * Remove accidental commit + unused copy * Unify Hardware sign with Web3 sign page * Update wallets lib * Add tests * Fix circular dep issue * Add more timeout * Try to fix tests on CI * Fix E2E * Detect if tx was signed by wrong account * Fix some PR comments * Reduce code duplication for HW scanning * Fix PR comments and tests * Update copy and fix tests * Add unlock test for HWLegacy * Use ETH path for every network using GridPlus * Bump wallets lib * Add type guard * Update DPaths
- Loading branch information
1 parent
92051ca
commit e9b5c88
Showing
64 changed files
with
1,545 additions
and
792 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import { arrayify, splitSignature } from '@ethersproject/bytes'; | ||
import { HDNode } from '@ethersproject/hdnode'; | ||
import type { Transaction } from '@ethersproject/transactions'; | ||
import { parse } from '@ethersproject/transactions'; | ||
import { Wallet } from '@ethersproject/wallet'; | ||
import { getPathPrefix, toChecksumAddress } from '@mycrypto/wallets'; | ||
import type { | ||
AddressesOpts, | ||
SignMessageOpts, | ||
SignOpts, | ||
SignResult, | ||
SignTxOpts | ||
} from 'gridplus-sdk'; | ||
|
||
import { stripHexPrefix } from '@utils'; | ||
|
||
const hdNode = HDNode.fromMnemonic('test test test test test test test test test test test ball'); | ||
|
||
const convertPathToString = (path: number[]): string => | ||
path | ||
.map((p) => { | ||
const withoutHardening = p - 0x80000000; | ||
const index = withoutHardening >= 0 ? Math.min(p, withoutHardening) : p; | ||
const isHardened = index === withoutHardening; | ||
return `${index}${isHardened ? "'" : ''}`; | ||
}) | ||
.join('/'); | ||
|
||
export class Client { | ||
isPaired = false; | ||
hasActiveWallet = jest.fn().mockReturnValue(true); | ||
connect = jest | ||
.fn() | ||
.mockImplementation( | ||
(_deviceID: string, callback: (err: Error | null, isPaired: boolean) => void) => { | ||
this.isPaired = true; | ||
callback(null, true); | ||
} | ||
); | ||
sign = jest | ||
.fn() | ||
.mockImplementation( | ||
async (opts: SignOpts, callback: (err: Error | null, data: SignResult) => void) => { | ||
const path = convertPathToString(opts.data.signerPath); | ||
const childNode = hdNode.derivePath(path); | ||
const wallet = new Wallet(childNode.privateKey); | ||
if (opts.currency === 'ETH') { | ||
const { signerPath, chainId, ...transaction } = opts.data as SignTxOpts; | ||
|
||
const isEIP1559 = | ||
transaction.maxFeePerGas !== undefined && | ||
transaction.maxPriorityFeePerGas !== undefined; | ||
|
||
const signedTransaction = await wallet.signTransaction({ | ||
...transaction, | ||
chainId: parseInt((chainId as unknown) as string, 16), | ||
type: isEIP1559 ? 2 : 0 | ||
}); | ||
const { v, r, s } = parse(signedTransaction) as Required<Transaction>; | ||
callback(null, { | ||
sig: { | ||
// eslint-disable-next-line no-restricted-globals | ||
v: v === 0 ? Buffer.from([]) : Buffer.from([v]), | ||
r: stripHexPrefix(r), | ||
s: stripHexPrefix(s) | ||
} | ||
}); | ||
} else if (opts.currency === 'ETH_MSG') { | ||
const signMessageOpts = opts.data as SignMessageOpts; | ||
const signature = await wallet.signMessage(arrayify(signMessageOpts.payload)); | ||
const { v, r, s } = splitSignature(signature); | ||
|
||
callback(null, { | ||
sig: { | ||
// eslint-disable-next-line no-restricted-globals | ||
v: v === 0 ? Buffer.from([]) : Buffer.from([v]), | ||
r: stripHexPrefix(r), | ||
s: stripHexPrefix(s) | ||
} | ||
}); | ||
} | ||
} | ||
); | ||
getAddresses = jest | ||
.fn() | ||
.mockImplementation( | ||
(opts: AddressesOpts, callback: (err: Error | null, data: string[]) => void) => { | ||
const path = convertPathToString(opts.startPath); | ||
const indices = path.split('/'); | ||
const offset = parseInt(indices[indices.length - 1]); | ||
|
||
const masterNode = hdNode.derivePath(getPathPrefix(path)); | ||
const result = new Array(opts.n).fill(undefined).map((_, i) => { | ||
const index = offset + i; | ||
const node = masterNode.derivePath(index.toString(10)); | ||
return toChecksumAddress(node.address); | ||
}); | ||
callback(null, result); | ||
} | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { TIcon } from '@components/Icon'; | ||
import { HARDWARE_CONFIG } from '@config'; | ||
import { translateRaw } from '@translations'; | ||
import { ISignComponentProps, WalletId } from '@types'; | ||
|
||
import HardwareSignTransaction from './Hardware'; | ||
|
||
export default function SignTransactionGridPlus({ | ||
senderAccount, | ||
rawTransaction, | ||
onSuccess | ||
}: ISignComponentProps) { | ||
const walletIconType = HARDWARE_CONFIG[WalletId.GRIDPLUS].iconId as TIcon; | ||
return ( | ||
<HardwareSignTransaction | ||
signerDescription={translateRaw('SIGN_TX_GRIDPLUS_DESCRIPTION')} | ||
walletIconType={walletIconType} | ||
senderAccount={senderAccount} | ||
rawTransaction={rawTransaction} | ||
onSuccess={onSuccess} | ||
/> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.