Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
38 changes: 38 additions & 0 deletions yarn-project/cli-wallet/src/cmds/default_mnemonic_guard.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { describe, expect, it } from '@jest/globals';

import { DEFAULT_TEST_MNEMONIC, assertSafeL1Signer } from './default_mnemonic_guard.js';

describe('assertSafeL1Signer', () => {
const implicitDefault = {
mnemonic: DEFAULT_TEST_MNEMONIC,
mnemonicWasExplicit: false,
privateKey: undefined,
allowDefaultMnemonic: false,
};

it.each([31337, 1337])('allows the implicit test mnemonic on local chain %i', chainId => {
expect(() => assertSafeL1Signer({ ...implicitDefault, chainId })).not.toThrow();
});

it.each([1, 11155111, 42])('rejects the implicit test mnemonic on non-local chain %i', chainId => {
expect(() => assertSafeL1Signer({ ...implicitDefault, chainId })).toThrow(
`--l1-chain-id ${chainId} is not a local network`,
);
});

it('allows an explicit private key on a non-local chain', () => {
expect(() => assertSafeL1Signer({ ...implicitDefault, chainId: 1, privateKey: '0x1234' })).not.toThrow();
});

it('allows a custom mnemonic on a non-local chain', () => {
expect(() => assertSafeL1Signer({ ...implicitDefault, chainId: 1, mnemonic: 'custom mnemonic' })).not.toThrow();
});

it('allows an explicitly supplied test mnemonic on a non-local chain', () => {
expect(() => assertSafeL1Signer({ ...implicitDefault, chainId: 1, mnemonicWasExplicit: true })).not.toThrow();
});

it('allows an explicit unsafe opt-in on a non-local chain', () => {
expect(() => assertSafeL1Signer({ ...implicitDefault, chainId: 1, allowDefaultMnemonic: true })).not.toThrow();
});
});
29 changes: 29 additions & 0 deletions yarn-project/cli-wallet/src/cmds/default_mnemonic_guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export const DEFAULT_TEST_MNEMONIC = 'test test test test test test test test test test test junk';

const LOCAL_L1_CHAIN_IDS = new Set([1337, 31337]);

export function assertSafeL1Signer({
chainId,
privateKey,
mnemonic,
mnemonicWasExplicit,
allowDefaultMnemonic,
}: {
chainId: number;
privateKey?: string;
mnemonic: string;
mnemonicWasExplicit: boolean;
allowDefaultMnemonic: boolean;
}) {
const usesImplicitTestMnemonic =
!privateKey && mnemonic === DEFAULT_TEST_MNEMONIC && !mnemonicWasExplicit && !allowDefaultMnemonic;
if (LOCAL_L1_CHAIN_IDS.has(chainId) || !usesImplicitTestMnemonic) {
return;
}

throw new Error(
`--l1-chain-id ${chainId} is not a local network, but no --l1-private-key or explicit --mnemonic was provided. ` +
'Refusing to sign with the public default test mnemonic. Pass --l1-private-key, an explicit --mnemonic, ' +
'or --i-know-this-uses-the-public-test-mnemonic to proceed.',
);
}
32 changes: 28 additions & 4 deletions yarn-project/cli-wallet/src/cmds/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
createVerboseOption,
integerArgParser,
} from '../utils/options/index.js';
import { DEFAULT_TEST_MNEMONIC, assertSafeL1Signer } from './default_mnemonic_guard.js';

function parseWaitForStatus(status: string): TxStatus {
switch (status) {
Expand Down Expand Up @@ -496,11 +497,16 @@ export function injectCommands(
.option(
'-m, --mnemonic <string>',
'The mnemonic to use for deriving the Ethereum address that will mint and bridge',
'test test test test test test test test test test test junk',
DEFAULT_TEST_MNEMONIC,
)
.option('--mint', 'Mint the tokens on L1', false)
.option('--l1-private-key <string>', 'The private key to the eth account bridging', PRIVATE_KEY)
.addOption(l1ChainIdOption)
.option(
'--i-know-this-uses-the-public-test-mnemonic',
'Allow the public default test mnemonic on a non-local L1 network',
false,
)
.option('--json', 'Output the claim in JSON format')
// `options.wait` is default true. Passing `--no-wait` will set it to false.
// https://github.com/tj/commander.js#other-option-types-negatable-boolean-and-booleanvalue
Expand All @@ -510,10 +516,28 @@ export function injectCommands(
.default('60')
.conflicts('wait'),
)
.action(async (amount, recipient, options) => {
const { bridgeL1FeeJuice } = await import('./bridge_fee_juice.js');
const { l1ChainId, l1RpcUrls, l1PrivateKey, mnemonic, mint, json, wait, interval: intervalS } = options;
.action(async (amount, recipient, options, command) => {
const {
l1ChainId,
l1RpcUrls,
l1PrivateKey,
mnemonic,
mint,
json,
wait,
interval: intervalS,
iKnowThisUsesThePublicTestMnemonic,
} = options;

assertSafeL1Signer({
chainId: l1ChainId,
privateKey: l1PrivateKey,
mnemonic,
mnemonicWasExplicit: command.getOptionValueSource('mnemonic') !== 'default',
allowDefaultMnemonic: iKnowThisUsesThePublicTestMnemonic,
});

const { bridgeL1FeeJuice } = await import('./bridge_fee_juice.js');
const [secret, messageLeafIndex] = await bridgeL1FeeJuice(
amount,
recipient,
Expand Down
Loading