base / base/account-sdk

Bug: Base App rejects valid Seaport EIP-712 criteria-order signatures with misleading insufficient-funds error

Open
#387 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
172
Forks
207
Avg merge
49m
Merged PRs (30d)
1

Description

### Describe the bug

Base App on iOS fails to sign valid OpenSea Seaport 1.6 trait-offer typed data using eth_signTypedData_v4. The Base App displays: Error Generating message Please make sure you have enough funds to complete this signature request.

### Steps

Base App on iOS fails to sign valid OpenSea Seaport 1.6 trait-offer typed data using `eth_signTypedData_v4`.

The Base App displays:

> Error Generating message
> Please make sure you have enough funds to complete this signature request.

The provider then rejects with:

```text
Provider.UserRejectedRequestError
code: 4001
message: The user rejected the request.
```

The user did not reject the request.

The same Trait Offer implementation works successfully through:

- Farcaster wallet
- Trust Wallet
- MetaMask/browser wallet

Base App can also sign a nearly identical OpenSea Collection Offer. The significant difference is that the Trait Offer contains a nonzero Seaport `identifierOrCriteria` Merkle root.

### Steps to reproduce

1. Connect a Base Account inside Base App.
2. Ensure the account has sufficient WETH, native ETH, and WETH allowance.
3. Prepare an OpenSea Seaport trait offer whose NFT consideration item is:

```json
{
"itemType": 4,
"token": "0x780446dd12e080ae0db762fcd4daf313f3e359de",
"identifierOrCriteria": "31543439137372029629788762898279123583003892896341457774606321223654009495127",
"startAmount": "1",
"endAmount": "1",
"recipient": ""
}
```

4. Request the signature:

```js
await provider.request({
method: "eth_signTypedData_v4",
params: [account, JSON.stringify(typedData)]
});
```

We also tested passing the typed-data object directly as the second parameter.

### Expected behavior

### Expected result

Base App should display the Seaport order and return a valid EIP-712 signature, as it does for a collection offer where `identifierOrCriteria` is `0`.

If the payload is unsupported, it should return an actionable format or unsupported-operation error.

### Actual result

Base App fails while generating the confirmation UI, displays an insufficient-funds message, and ultimately returns error `4001`, even though the user did not reject the request.

No request is submitted to OpenSea because the failure occurs during signing.

### Latest reproduction: single Trait Offer

Timestamp: `2026-08-16T11:44:37.884Z`

- Trait: Volume Level `10X`
- Offer amount: `0.0001 WETH`
- Total required including fees: `0.000111 WETH`
- Available WETH: `0.00591463 WETH`
- WETH allowance: `0.00111 WETH`
- Native ETH: approximately `0.00630691 ETH`
- Chain ID: `8453`
- Criteria source: OpenSea
- Nonzero criteria root:
`31543439137372029629788762898279123583003892896341457774606321223654009495127`

Signature request:

```json
{
"method": "eth_signTypedData_v4",
"payload": "structured",
"primaryType": "OrderComponents",
"domain": {
"name": "Seaport",
"version": "1.6",
"chainId": 8453,
"verifyingContract": "0x0000000000000068f116a894984e2db1123eb395"
}
}
```

Failure approximately 18.6 seconds later:

```json
{
"name": "Provider.UserRejectedRequestError",
"message": "The user rejected the request.",
"code": 4001
}
```

### Additional reproduction: 10 Trait Offers

All ten orders prepared successfully. Base App also successfully completed the required WETH approval transaction:

```text
0x286d9826593054af17fcc758b5475d5805c69f00254d9137e940f21a0eea760d
```

It then failed on the first Seaport signature with the same `4001` response.

This confirms that Base App could submit and confirm an onchain transaction from the same account immediately before rejecting the offchain typed-data signature.

### Control case

A Collection Offer succeeds using:

- The same Base Account
- The same network
- The same Seaport contract and domain
- The same WETH token and conduit
- The same `eth_signTypedData_v4` method
- The same general `OrderComponents` structure

The principal criteria difference is:

```text
Collection Offer: identifierOrCriteria = 0
Trait Offer: identifierOrCriteria = nonzero uint256 Merkle root
```

The trait criteria orders also sign successfully in Farcaster, Trust Wallet, and MetaMask.

### Formats and alternatives already tested

- Documented serialized `eth_signTypedData_v4` payload
- Structured typed-data payload
- Decimal-string `uint256` values
- Equivalent hexadecimal `uint256` values
- Base `wallet_sign`/EIP-7871 variants, which returned `-32603 Internal error`
- Single-trait and multi-trait offers
- Verified WETH balance, ETH balance, allowance, chain, account, domain and protocol address

### Version

2.5.8

### Additional info

### Request

Could the Base App team investigate whether its signature-rendering or simulation path rejects Seaport `OrderComponents` containing:

- `itemType: 4`
- A nonzero 256-bit `identifierOrCriteria`
- Nested `OfferItem[]` and `ConsiderationItem[]` arrays

Could you also confirm whether Base App intentionally imposes restrictions on Seaport criteria-order signatures, and why a wallet-generation failure is surfaced as `4001 UserRejectedRequest`?

### Desktop

N/A

### Smartphone

- Platform: Base App on iOS
- Base App version: `30.7.78`
- iOS version/device: `26.6`
- Base Account SDK: `@base-org/account@2.5.8`
- Network: Base Mainnet, chain ID `8453`
- Signing method: `eth_signTypedData_v4`
- Seaport version: `1.6`
- Seaport contract: `0x0000000000000068f116a894984e2db1123eb395`
- Application URL: `an internal testing app - sorry can't share publically`

Contributor guide

Open the contributing guide

Research direction

No source files or tests are named. Start at the eth_signTypedData_v4 handling and compare the successful Collection Offer path with the failing Seaport trait-order path, including the nonzero identifierOrCriteria and nested arrays. Done means valid criteria orders produce a confirmation and EIP-712 signature, or an actionable unsupported-operation error instead of 4001.

Written by the indexing model from the issue text.

Assessment

Tech stack
ios, typescript
Domain
blockchain, mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.