Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .changeset/sixty-bobcats-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"thirdweb": patch
---

Fix cb wallet transaction desktop popup when logged in via mobile QR code
12 changes: 11 additions & 1 deletion packages/thirdweb/src/wallets/coinbase/coinbase-web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,17 @@ function createAccount({
onTransactionRequested: async () => {
// make sure to show the coinbase popup BEFORE doing any transaction preprocessing
// otherwise the popup might get blocked in safari
await showCoinbasePopup(provider);
// but only if using cb smart wallet (web based)
if (window.localStorage) {
// this is the local storage key for the signer type in the cb web sdk
// value can be "scw" (web) or "walletlink" (mobile wallet)
const signerType = window.localStorage.getItem(
"-CBWSDK:SignerConfigurator:SignerType",
);
if (signerType === "scw") {
await showCoinbasePopup(provider);
}
Comment on lines +192 to +200
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Verify the stability of the internal localStorage key.

The code relies on the hardcoded localStorage key "-CBWSDK:SignerConfigurator:SignerType", which appears to be an internal implementation detail of the Coinbase Web SDK. If Coinbase changes this key in a future SDK version, the conditional popup logic will silently fail.

Consider:

  1. Wrapping the localStorage access in a try-catch to handle potential exceptions (e.g., in private browsing mode)
  2. Defining the key and valid values as constants for better maintainability

Run the following script to check if there's an official SDK API or documentation for determining signer type:

Additionally, search the web for official Coinbase Web SDK documentation:


🏁 Script executed:

#!/bin/bash
# Search for any official API or types related to signer type in the codebase
rg -nP --type=ts -C3 'SignerType|signerType|signer.*type' --glob '!node_modules/**'

Length of output: 27989


🌐 Web query:

Coinbase Web SDK SignerConfigurator SignerType official API documentation

💡 Result:

I searched Coinbase's official developer docs and repositories but could not find any official API documentation referencing "SignerConfigurator" or "SignerType" in a Coinbase Web SDK.

Sources I checked:

  • Coinbase developer docs (CDP / Wallet SDK pages). [1]
  • Coinbase Node/JS SDK documentation (Coinbase SDK GitHub/pages). [2]

If you have a link, code snippet, or the package name (npm/GitHub) where you saw those identifiers, share it and I’ll search that source and return the exact official docs or types.

References:
[1] Coinbase Developer Documentation (wallet / CDP docs).
[2] @coinbase/coinbase-sdk Node.js docs (Coinbase GitHub pages).


Extract the localStorage key and values into constants and wrap access in try-catch
The hardcoded key "-CBWSDK:SignerConfigurator:SignerType" is an internal SDK detail and may change. Define constants for the key and its valid values (“scw”, “walletlink”), and wrap window.localStorage.getItem in a try-catch to handle errors (e.g., private-browsing) and avoid silent failures.

🤖 Prompt for AI Agents
In packages/thirdweb/src/wallets/coinbase/coinbase-web.ts around lines 192 to
200, extract the hardcoded localStorage key
"-CBWSDK:SignerConfigurator:SignerType" and the valid values "scw" and
"walletlink" into top-level constants, then replace the inline string uses with
those constants; wrap the window.localStorage.getItem call in a try-catch (and
guard for window.localStorage presence) so any errors (e.g. private browsing)
are caught and handled by falling back to a safe default (treat as unknown / do
not call showCoinbasePopup), and ensure the signerType comparison uses the
defined constant for "scw".

}
},
async sendTransaction(tx: SendTransactionOption) {
const transactionHash = (await provider.request({
Expand Down
4 changes: 3 additions & 1 deletion packages/thirdweb/src/x402/fetchWithPayment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export function wrapFetchWithPayment(
parsedPaymentRequirements,
chain.id,
"exact",
error,
);

if (!selectedPaymentRequirements) {
Expand Down Expand Up @@ -141,10 +142,11 @@ function defaultPaymentRequirementsSelector(
paymentRequirements: RequestedPaymentRequirements[],
chainId: number,
scheme: "exact",
error?: string,
) {
if (!paymentRequirements.length) {
throw new Error(
"No valid payment requirements found in server 402 response",
`No valid payment requirements found in server 402 response. ${error}`,
);
}
const currentWalletNetwork = ChainIdToNetwork[chainId] || `eip155:${chainId}`;
Expand Down
Loading