bcnmy / bcnmy/abstractjs

[BUG] toNexusAccount fails when the user has no wallet extensions installed

Open
#212 0 comments 0 reactions 0 assignees View on GitHub
bug help wanted
Dominant language
TypeScript
Stars
8
Forks
12
Avg merge
2h 15m
Merged PRs (30d)
1

Description

### Is there an existing issue for this?

- [x] I have searched the existing issues

### Package Version

1.2.4

### Current Behavior

The library expects an Ethereum wallet extension installed, so if a user has no wallet extensions installed (`window.ethereum` === `undefined`), for example by connecting using a 3rd party connector via email or their web2 account, `toNexusAccount` fails with the following error:
```
TypeError: Cannot read properties of undefined (reading 'request')
at Object.transport (_esm-BSwfxQyV.js?v=4ff14d18:5862:21)
at createClient (parseSignature-BmMoHAM7.js?v=4ff14d18:25:48)
at createWalletClient (_esm-BSwfxQyV.js?v=4ff14d18:5816:9)
at toWalletClient (@biconomy_abstractjs.js?v=4ff14d18:70507:9)
at toNexusAccount (@biconomy_abstractjs.js?v=4ff14d18:70643:23)
```
```js
const walletClient = toWalletClient({
unresolvedSigner: _signer,
resolvedSigner: signer,
chain,
transport: transportConfig
});
```
```js
//#region node_modules/.pnpm/@biconomy+abstractjs@1.2.4_@metamask+delegation-toolkit@0.11.0_viem@2.52.2_bufferutil@4_2a944230c8f4986aa78e4c29ea8e997a/node_modules/@biconomy/abstractjs/dist/_esm/account/utils/toWalletClient.js
var toWalletClient = ({ unresolvedSigner, resolvedSigner, chain, transport }) => {
return createWalletClient(unresolvedSigner?.transport?.key === "custom" ? {
account: resolvedSigner.address,
chain,
transport: custom(window?.ethereum)
} : {
account: resolvedSigner,
chain,
transport
}).extend(publicActions);
};
//#endregion
```
```js
//#region node_modules/.pnpm/viem@2.52.2_bufferutil@4.1.0_typescript@6.0.3_utf-8-validate@6.0.6_zod@4.4.3/node_modules/viem/_esm/clients/createWalletClient.js
function createWalletClient(parameters) {
const { key = "wallet", name = "Wallet Client", transport } = parameters;
return createClient({
...parameters,
key,
name,
transport,
type: "walletClient"
}).extend(walletActions);
}
//#endregion
```
```js
//#region node_modules/.pnpm/viem@2.52.2_bufferutil@4.1.0_typescript@6.0.3_utf-8-validate@6.0.6_zod@4.4.3/node_modules/viem/_esm/clients/transports/custom.js
/**
* @description Creates a custom transport given an EIP-1193 compliant `request` attribute.
*/
function custom(provider, config = {}) {
const { key = "custom", methods, name = "Custom Provider", retryDelay } = config;
return ({ retryCount: defaultRetryCount }) => createTransport({
key,
methods,
name,
request: provider.request.bind(provider),
retryCount: config.retryCount ?? defaultRetryCount,
retryDelay,
type: "custom"
});
}
//#endregion
```

### Expected Behavior

_No response_

### Steps To Reproduce

Run a working app on incognito (no Ethereum wallet extensions enabled)

### Package.json (or lockfile) content

```json
{
"name": "xxx",
"private": true,
"version": "1.0.0",
"type": "module",
"scripts": { "xxx": "xxx" },
"dependencies": {
"@biconomy/abstractjs": "^1.2.4",
"@dynamic-labs/ethereum": "^4.88.6",
"@dynamic-labs/sdk-react-core": "^4.88.6",
"@dynamic-labs/wagmi-connector": "^4.88.6",
"@tailwindcss/vite": "^4.3.1",
"@tanstack/react-query": "^5.101.0",
"alchemy-sdk": "^3.6.5",
"daisyui": "^5.5.23",
"firebase": "^12.14.0",
"permissionless": "^0.3.6",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"react-icons": "^5.6.0",
"react-router": "^7.17.0",
"react-toastify": "^11.1.0",
"tailwindcss": "^4.3.1",
"viem": "^2.52.2",
"wagmi": "^3.6.16"
},
"devDependencies": {
"@eslint/js": "^10.0.1",
"@types/node": "^24.13.2",
"@types/react": "^19.2.17",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.2",
"eslint": "^10.5.0",
"eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-react-refresh": "^0.5.2",
"globals": "^17.6.0",
"typescript": "~6.0.3",
"typescript-eslint": "^8.61.0",
"vite": "^8.0.16"
}
}
```

### Link to Minimal Reproducible Example (StackBlitz, CodeSandbox, GitHub repo etc.)

_No response_

### Anything else?

My workaround now is by doing:
```ts
if (!window.ethereum) {
window.ethereum = {
async request(_: any): Promise {},
} as any;
}

toNexusAccount({
chainConfiguration: {
chain,
transport: http(import.meta.env.VITE_BASE_SEPOLIA_RPC_URL),
version: getMEEVersion(MEEVersion.V2_3_0),
versionCheck: false,
},
...
});
```
This works, but it would be great if abstractjs doesn't assume a wallet client / handle the case for `transport: custom(window?.ethereum)` when `window?.ethereum` is `undefined`

Thanks

Contributor guide

No contributing guide indexed for this repository

Research direction

Start at the toWalletClient call shown in the report and reproduce with no window.ethereum, using the supplied transport. Trace how toNexusAccount selects custom(window?.ethereum), then add coverage for the no-extension path and verify that toNexusAccount completes without reading request from undefined.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
blockchain
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.