Skip to content

autoSelect is typed as optional but validated as required #1745

@wbt

Description

@wbt

Current Behavior

Using https://www.npmjs.com/package/@web3-onboard/react the documentation there lists:

type ConnectOptions = {
  autoSelect?: string // wallet name to auto-select for user
}

Note that autoSelect is marked optional in the type definition.
I have code using the as-documented line const [{ wallet, connecting }, connect, disconnect] = useConnectWallet();
and pass connect as a functional prop of type (() => void) which is used as a click handler in a subcomponent.

This produces an uncaught validation error in a promise stating that autoSelect is required:
useConnectWallet.js:14 Uncaught (in promise) {value: SyntheticBaseEvent, error: ValidationError: "autoSelect" is required}

This suggests an error in types somewhere in the application, in particular whatever code checks for "autoSelect" as if it is required.

Expected Behavior

If connect is passed an object which does not contain autoSelect as a key, it is treated the same as if no object was passed (given that autoSelect is the only used key). An object without that key (e.g. the empty object) is acceptable, as it matches the documented & described type for ConnectOptions.

Steps To Reproduce

Demonstrating with a simple wrapper function passing an empty object instead of an Event object:

const [{ wallet, connecting }, connect, disconnect] = useConnectWallet();
const connectWallet = async () => {
	const wallets = await connect({});
}

Then make either connect or connectWallet the onClick handler of a button or other element, and click on it.
View the error in the console.

Workaround: Have the wrapper function pass no object as a parameter and make the wrapper function the onClick handler. (Better practice: always use wrapper functions when passing props especially as event handlers).

This could also be an issue for code that builds up an options object, like this:

const [{ wallet, connecting }, connect, disconnect] = useConnectWallet();
const connectWallet = async () => {
	let options : ConnectOptions = {};
	if(someCondition) {
		options.autoSelect = myString;
	}
	const wallets = await connect(options);
}

or a wrapper function that takes a parameter:

const [{ wallet, connecting }, connect, disconnect] = useConnectWallet();
const connectWallet = async (options : ConnectOptions) => {
	const wallets = await connect(options);
}

Either one of these will validate TypeScript perfectly fine but then have a runtime-crashing type validation error because the types being validated don't match the types as declared.

What package is effected by this issue?

@web3-onboard/react

Is this a build or a runtime issue?

Runtime

Package Version

2.8.4

Node Version

18.5.0

What browsers are you seeing the problem on?

Chrome

Relevant log output

Uncaught (in promise) {value: {…}, error: ValidationError: "autoSelect" is required}
error: ValidationError: "autoSelect" is required
details: Array(1)
    0: {message: '"autoSelect" is required', path: Array(1), type: 'any.required', context: {…}}
    length: 1
    [[Prototype]]: Array(0)
original: {}
message: "\"autoSelect\" is required"
stack: "ValidationError: \"autoSelect\" is required"
[[Prototype]]: Error
value: {}
[[Prototype]]: Object

Anything else?

The stack shows the error originating in the call to connectWallet here but not in any greater detail; the rest of the stack appears to be about dispatching/handling the click event.

Sanity Check

  • If this is a build issue, I have included my build config. If this is a runtime issue, I have included reproduction steps and/or a Minimal, Reproducible Example.

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions