Skip to content

Commit e806393

Browse files
authored
fix(WalletConnectConnection): fix wallet connect uri parsing (#2626)
1 parent 0394eb2 commit e806393

File tree

6 files changed

+110
-6
lines changed

6 files changed

+110
-6
lines changed

.changeset/heavy-hats-fold.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
fix wallet connect uri parsing

.github/workflows/build-test-lint.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ env:
1919
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
2020
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
2121
TW_SECRET_KEY: ${{ secrets.TW_SECRET_KEY }}
22+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
2223

2324
jobs:
2425
build:
@@ -120,7 +121,7 @@ jobs:
120121
- name: Upload coverage reports to Codecov
121122
uses: codecov/codecov-action@v4
122123
with:
123-
files: ./packages/thirdweb/coverage/lcov.info
124+
directory: ./legacy_packages
124125

125126
test_legacy:
126127
timeout-minutes: 15
@@ -156,7 +157,7 @@ jobs:
156157
- name: Upload coverage reports to Codecov
157158
uses: codecov/codecov-action@v4
158159
with:
159-
files: ./legacy_packages/sdk/coverage/evm/lcov.info
160+
directory: ./legacy_packages
160161

161162
e2e:
162163
timeout-minutes: 15

packages/thirdweb/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@
225225
"push": "yalc push",
226226
"size": "size-limit",
227227
"test:watch": "vitest -c ./test/vitest.config.ts dev",
228-
"test": "CI=true vitest -c ./test/vitest.config.ts --coverage --bail=1",
228+
"test": "vitest run -c ./test/vitest.config.ts --coverage --bail=1",
229229
"test:cov": "vitest dev -c ./test/vitest.config.ts --coverage",
230230
"test:dev": "vitest dev -c ./test/vitest.config.ts",
231231
"typedoc": "node scripts/typedoc.mjs",

packages/thirdweb/src/react/web/wallets/shared/WalletConnectConnection.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type { WCSupportedWalletIds } from "../../../../wallets/__generated__/wal
99
import { isMobile, isAndroid, isIOS } from "../../../../utils/web/isMobile.js";
1010
import { openWindow } from "../../../../utils/web/openWindow.js";
1111
import { wait } from "../../../../utils/promise/wait.js";
12+
import { formatWalletConnectUrl } from "../../../../utils/url.js";
1213

1314
/**
1415
* QR Scan UI for connecting a specific wallet on desktop.
@@ -49,15 +50,15 @@ export const WalletConnectConnection: React.FC<{
4950
if (isMobile()) {
5051
if (isAndroid()) {
5152
openWindow(
52-
`${platformUris.android}wc?uri=${encodeURIComponent(uri)}`,
53+
formatWalletConnectUrl(platformUris.android, uri).redirect,
5354
);
5455
} else if (isIOS()) {
5556
openWindow(
56-
`${platformUris.ios}wc?uri=${encodeURIComponent(uri)}`,
57+
formatWalletConnectUrl(platformUris.ios, uri).redirect,
5758
);
5859
} else {
5960
openWindow(
60-
`${platformUris.other}wc?uri=${encodeURIComponent(uri)}`,
61+
formatWalletConnectUrl(platformUris.other, uri).redirect,
6162
);
6263
}
6364
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { describe, expect, it } from "vitest";
2+
import { formatWalletConnectUrl } from "./url.js";
3+
4+
describe("formatWalletConnectUrl", () => {
5+
it("should format a wallet connect URL for an HTTP app URL", () => {
6+
const appUrl = "https://example.com";
7+
const wcUri = "wc:1234567890";
8+
9+
const result = formatWalletConnectUrl(appUrl, wcUri);
10+
11+
expect(result).toMatchInlineSnapshot(`
12+
{
13+
"href": "https://example.com/",
14+
"redirect": "https://example.com/wc?uri=wc%3A1234567890",
15+
}
16+
`);
17+
});
18+
19+
it("should format a wallet connect URL for a native app URL", () => {
20+
const appUrl = "myapp://example";
21+
const wcUri = "wc:1234567890";
22+
23+
const result = formatWalletConnectUrl(appUrl, wcUri);
24+
25+
expect(result).toMatchInlineSnapshot(`
26+
{
27+
"href": "myapp://example/",
28+
"redirect": "myapp://example/wc?uri=wc%3A1234567890",
29+
}
30+
`);
31+
});
32+
});

packages/thirdweb/src/utils/url.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* @internal
3+
*/
4+
export function isHttpUrl(url: string) {
5+
return url.startsWith("http://") || url.startsWith("https://");
6+
}
7+
8+
type LinkingRecord = {
9+
redirect: string;
10+
href: string;
11+
};
12+
13+
/**
14+
* @internal
15+
*/
16+
function formatUniversalUrl(appUrl: string, wcUri: string): LinkingRecord {
17+
if (!isHttpUrl(appUrl)) {
18+
return formatNativeUrl(appUrl, wcUri);
19+
}
20+
let safeAppUrl = appUrl;
21+
if (!safeAppUrl.endsWith("/")) {
22+
safeAppUrl = `${safeAppUrl}/`;
23+
}
24+
const encodedWcUrl = encodeURIComponent(wcUri);
25+
26+
return {
27+
redirect: `${safeAppUrl}wc?uri=${encodedWcUrl}`,
28+
href: safeAppUrl,
29+
};
30+
}
31+
32+
/**
33+
* @internal
34+
*/
35+
function formatNativeUrl(appUrl: string, wcUri: string): LinkingRecord {
36+
if (isHttpUrl(appUrl)) {
37+
return formatUniversalUrl(appUrl, wcUri);
38+
}
39+
let safeAppUrl = appUrl;
40+
if (!safeAppUrl.includes("://")) {
41+
safeAppUrl = appUrl.replaceAll("/", "").replaceAll(":", "");
42+
safeAppUrl = `${safeAppUrl}://`;
43+
}
44+
if (!safeAppUrl.endsWith("/")) {
45+
safeAppUrl = `${safeAppUrl}/`;
46+
}
47+
const encodedWcUrl = encodeURIComponent(wcUri);
48+
49+
return {
50+
redirect: `${safeAppUrl}wc?uri=${encodedWcUrl}`,
51+
href: safeAppUrl,
52+
};
53+
}
54+
55+
/**
56+
* @internal
57+
*/
58+
export function formatWalletConnectUrl(
59+
appUrl: string,
60+
wcUri: string,
61+
): LinkingRecord {
62+
return isHttpUrl(appUrl)
63+
? formatUniversalUrl(appUrl, wcUri)
64+
: formatNativeUrl(appUrl, wcUri);
65+
}

0 commit comments

Comments
 (0)