Skip to content

Commit e870b1f

Browse files
Merge pull request #732 from blocknative/release/1.35.3
Release: 1.35.3 - Main
2 parents f066c09 + 81162a0 commit e870b1f

File tree

7 files changed

+460
-155
lines changed

7 files changed

+460
-155
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "bnc-onboard",
3-
"version": "1.35.2",
3+
"version": "1.35.3",
44
"description": "Onboard users to web3 by allowing them to select a wallet, get that wallet ready to transact and have access to synced wallet state.",
55
"keywords": [
66
"ethereum",

src/modules/select/index.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ const desktopDefaultWalletNames = [
1414
'frame',
1515
'torus',
1616
'opera',
17-
'liquality'
17+
'liquality',
18+
'blankwallet'
1819
]
1920

2021
const mobileDefaultWalletNames = [
@@ -65,7 +66,12 @@ function select(
6566
wallet?.display &&
6667
wallet?.display[isMobile ? 'mobile' : 'desktop'] === false
6768

68-
if (detectedWalletName) {
69+
// If the detected wallet is already listed as a wallet option then don't inject it
70+
const walletNotIncluded = wallets.every(
71+
wallet => isWalletInit(wallet) && wallet.walletName !== detectedWalletName
72+
)
73+
74+
if (detectedWalletName && walletNotIncluded) {
6975
// This wallet is built into onboard so add the walletName and
7076
// the code below will load it as a wallet module
7177
wallets.unshift({ walletName: detectedWalletName })
@@ -214,6 +220,8 @@ function getModule(name: string): Promise<{
214220
return import('./wallets/detectedwallet')
215221
case 'tp':
216222
return import('./wallets/tp')
223+
case 'blankwallet':
224+
return import('./wallets/blankwallet')
217225
// case 'mewwallet':
218226
// return import('./wallets/mewwallet')
219227
default:
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const blankwalletIcon = `
2+
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
3+
<path fill-rule="evenodd" clip-rule="evenodd" d="M15 30C23.2843 30 30 23.2843 30 15C30 6.71573 23.2843 0 15 0C6.71573 0 0 6.71573 0 15C0 23.2843 6.71573 30 15 30ZM23.125 6.875H6.875V23.125H23.125V6.875Z" fill="currentColor"/>
4+
</svg>
5+
`
6+
7+
export default blankwalletIcon
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { extensionInstallMessage } from '../content'
2+
import { WalletModule, Helpers, CommonWalletOptions } from '../../../interfaces'
3+
4+
import blankwalletIcon from '../wallet-icons/icon-blankwallet'
5+
6+
function blankwallet(options: CommonWalletOptions): WalletModule {
7+
const { preferred, label, iconSrc, svg } = options
8+
9+
return {
10+
name: label || 'Blank Wallet',
11+
iconSrc,
12+
svg: svg || blankwalletIcon,
13+
wallet: async (helpers: Helpers) => {
14+
const {
15+
getProviderName,
16+
createModernProviderInterface,
17+
createLegacyProviderInterface
18+
} = helpers
19+
20+
const provider =
21+
(window as any).ethereum ||
22+
((window as any).web3 && (window as any).web3.currentProvider)
23+
24+
return {
25+
provider,
26+
interface:
27+
provider && getProviderName(provider) === 'BlankWallet'
28+
? typeof provider.enable === 'function'
29+
? createModernProviderInterface(provider)
30+
: createLegacyProviderInterface(provider)
31+
: null
32+
}
33+
},
34+
type: 'injected',
35+
link: `https://www.goblank.io/`,
36+
installMessage: extensionInstallMessage,
37+
desktop: true,
38+
mobile: false,
39+
preferred
40+
}
41+
}
42+
43+
export default blankwallet

src/modules/select/wallets/ledger.ts

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,10 @@ async function ledgerProvider(options: LedgerProviderOptions) {
8686
const { generateAddresses, isValidPath } = await import('./hd-wallet')
8787
const { default: Eth } = await import('@ledgerhq/hw-app-eth')
8888

89-
const { Transaction } = await import('@ethereumjs/tx')
90-
const { default: Common } = await import('@ethereumjs/common')
89+
const { TransactionFactory: Transaction, Capability } = await import(
90+
'@ethereumjs/tx'
91+
)
92+
const { default: Common, Hardfork } = await import('@ethereumjs/common')
9193
const ethUtil = await import('ethereumjs-util')
9294
const { TypedDataUtils } = await import('eth-sig-util')
9395

@@ -403,38 +405,47 @@ async function ledgerProvider(options: LedgerProviderOptions) {
403405

404406
async function signTransaction(transactionData: any) {
405407
const path = [...addressToPath.values()][0]
406-
const { BN, toBuffer } = ethUtil
408+
const { rlp } = ethUtil
407409
const common = new Common({
408-
chain: customNetwork || networkName(networkId)
410+
chain: customNetwork || networkName(networkId),
411+
// Berlin is the minimum hardfork that will allow for EIP1559
412+
hardfork: Hardfork.Berlin,
413+
// List of supported EIPS
414+
eips: [1559]
409415
})
410416
try {
417+
// The below implemenation is adapted from:
418+
// https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/tx#signing-with-a-hardware-or-external-wallet
419+
transactionData.gasLimit = transactionData.gas ?? transactionData.gasLimit
411420
const transaction = Transaction.fromTxData(
412421
{
413-
...transactionData,
414-
gasLimit: transactionData.gas ?? transactionData.gasLimit
422+
...transactionData
415423
},
416-
{ common, freeze: false }
424+
{ common }
417425
)
418-
transaction.v = new BN(toBuffer(networkId))
419-
transaction.r = transaction.s = new BN(toBuffer(0))
420426

421-
const ledgerResult = await eth.signTransaction(
422-
path,
423-
transaction.serialize().toString('hex')
424-
)
425-
let v = ledgerResult.v.toString(16)
426-
// EIP155 support. check/recalc signature v value.
427-
const rv = parseInt(v, 16)
428-
let cv = networkId * 2 + 35
429-
if (rv !== cv && (rv & cv) !== rv) {
430-
cv += 1 // add signature v bit.
427+
let unsignedTx = transaction.getMessageToSign(false)
428+
429+
// If this is not an EIP1559 transaction then it is legacy and it needs to be
430+
// rlp encoded before being passed to ledger
431+
if (!transaction.supports(Capability.EIP1559FeeMarket)) {
432+
unsignedTx = rlp.encode(unsignedTx)
431433
}
432-
v = cv.toString(16)
433-
transaction.v = new BN(toBuffer(`0x${v}`))
434-
transaction.r = new BN(toBuffer(`0x${ledgerResult.r}`))
435-
transaction.s = new BN(toBuffer(`0x${ledgerResult.s}`))
436434

437-
return `0x${transaction.serialize().toString('hex')}`
435+
const { v, r, s } = await eth.signTransaction(path, unsignedTx)
436+
437+
// Reconstruct the signed transaction
438+
const signedTx = Transaction.fromTxData(
439+
{
440+
...transactionData,
441+
v: `0x${v}`,
442+
r: `0x${r}`,
443+
s: `0x${s}`
444+
},
445+
{ common }
446+
)
447+
448+
return `0x${signedTx.serialize().toString('hex')}`
438449
} catch (error) {
439450
throw error
440451
}

src/utilities.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,10 @@ export function getProviderName(provider: any): string | undefined {
345345
return 'tp'
346346
}
347347

348+
if (provider.isBlank) {
349+
return 'BlankWallet'
350+
}
351+
348352
// =====================================
349353
// When adding new wallet place above this metamask check as some providers
350354
// have an isMetaMask property in addition to the wallet's own `is[WalletName]`

0 commit comments

Comments
 (0)