Skip to content

Commit 18626ce

Browse files
ci(release): publish latest release
1 parent eaf0377 commit 18626ce

File tree

549 files changed

+30650
-12138
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

549 files changed

+30650
-12138
lines changed

.env.defaults

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ FIREBASE_APP_CHECK_DEBUG_TOKEN=stored-in-.env.local
2525
INCLUDE_PROTOTYPE_FEATURES=stored-in-.env.local
2626
GH_TOKEN_RN_CLI=
2727
NPM_READ_ONLY_TOKEN=stored-in-.env.local
28+
PRIVY_APP_ID=stored-in-.env.local
2829
IS_E2E_TEST=false
2930
ENABLE_SESSION_SERVICE=false
3031
ENABLE_SESSION_UPGRADE_AUTO=false

.husky/post-checkout

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ call_lefthook()
3939
elif bundle exec lefthook -h >/dev/null 2>&1
4040
then
4141
bundle exec lefthook "$@"
42-
elif yarn lefthook -h >/dev/null 2>&1
42+
elif bun lefthook -h >/dev/null 2>&1
4343
then
44-
yarn lefthook "$@"
44+
bun lefthook "$@"
4545
elif pnpm lefthook -h >/dev/null 2>&1
4646
then
4747
pnpm lefthook "$@"

.husky/pre-commit

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ call_lefthook()
3939
elif bundle exec lefthook -h >/dev/null 2>&1
4040
then
4141
bundle exec lefthook "$@"
42-
elif yarn lefthook -h >/dev/null 2>&1
42+
elif bun lefthook -h >/dev/null 2>&1
4343
then
44-
yarn lefthook "$@"
44+
bun lefthook "$@"
4545
elif pnpm lefthook -h >/dev/null 2>&1
4646
then
4747
pnpm lefthook "$@"

.husky/prepare-commit-msg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ call_lefthook()
3939
elif bundle exec lefthook -h >/dev/null 2>&1
4040
then
4141
bundle exec lefthook "$@"
42-
elif yarn lefthook -h >/dev/null 2>&1
42+
elif bun lefthook -h >/dev/null 2>&1
4343
then
44-
yarn lefthook "$@"
44+
bun lefthook "$@"
4545
elif pnpm lefthook -h >/dev/null 2>&1
4646
then
4747
pnpm lefthook "$@"

AGENTS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ bun extension build:production # Extension production
4444

4545
```bash
4646
bun g:test # Run all tests
47-
bun g:test:coverage # With coverage
47+
bun g:test:changed # Run tests for changed packages
4848
bun web playwright:test # Web E2E tests
4949
bun mobile e2e # Mobile E2E tests
5050
```
@@ -87,7 +87,7 @@ bun i18n:extract # Extract localized strings (run after changing
8787
#### State Management
8888

8989
- **Redux** for complex global state
90-
- **Jotai** for simple state
90+
- **Zustand** for simple global/shared state — do not use Jotai, we are migrating away from it. Flag any new Jotai usage in PRs and require Zustand instead.
9191
- Keep state as local as possible
9292
- No custom hooks for simple data fetching - use `useQuery`/`useMutation` directly
9393

RELEASE

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
IPFS hash of the deployment:
2-
- CIDv0: `QmQG5W29KDrMdK5VzuMo4AdVSK2nFGhzcjJnZuzUuJuBof`
3-
- CIDv1: `bafybeia4roahjkbzzq5doa6oeop6s6hrl4ivhqkp6y5aksxhg6bmfh7p5i`
2+
- CIDv0: `QmVC4WhmppfmiCEHRPVduXaureggHB1cUJuCDZ4XqAKvrD`
3+
- CIDv1: `bafybeidfzz7oyo32bihvpmxfx5bkl2aenadpwn3wghz766iqvz3qtrnm7i`
44

55
The latest release is always mirrored at [app.uniswap.org](https://app.uniswap.org).
66

@@ -10,5 +10,5 @@ You can also access the Uniswap Interface from an IPFS gateway.
1010
Your Uniswap settings are never remembered across different URLs.
1111

1212
IPFS gateways:
13-
- https://bafybeia4roahjkbzzq5doa6oeop6s6hrl4ivhqkp6y5aksxhg6bmfh7p5i.ipfs.dweb.link/
14-
- [ipfs://QmQG5W29KDrMdK5VzuMo4AdVSK2nFGhzcjJnZuzUuJuBof/](ipfs://QmQG5W29KDrMdK5VzuMo4AdVSK2nFGhzcjJnZuzUuJuBof/)
13+
- https://bafybeidfzz7oyo32bihvpmxfx5bkl2aenadpwn3wghz766iqvz3qtrnm7i.ipfs.dweb.link/
14+
- [ipfs://QmVC4WhmppfmiCEHRPVduXaureggHB1cUJuCDZ4XqAKvrD/](ipfs://QmVC4WhmppfmiCEHRPVduXaureggHB1cUJuCDZ4XqAKvrD/)

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
web/5.138.1
1+
web/5.139.0
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Sandbox Child Frame</title>
6+
<style>
7+
body { font-family: monospace; padding: 8px; margin: 0; background: #1a1a2e; color: #e0e0e0; font-size: 11px; }
8+
.status { padding: 4px 8px; border-radius: 4px; margin: 2px 0; }
9+
.pass { background: #0f5132; color: #75b798; }
10+
.fail { background: #842029; color: #ea868f; }
11+
.neutral { background: #333; color: #aaa; }
12+
</style>
13+
</head>
14+
<body>
15+
<div id="info">Detecting providers...</div>
16+
<script>
17+
const origin = window.origin;
18+
const hasEthereum = typeof window.ethereum !== 'undefined' && window.ethereum !== null;
19+
20+
// Listen for Uniswap's EIP-6963 announceProvider event
21+
let hasUniswapProvider = false;
22+
const UNISWAP_RDNS = 'org.uniswap.app';
23+
24+
window.addEventListener('eip6963:announceProvider', (event) => {
25+
if (event.detail && event.detail.info && event.detail.info.rdns === UNISWAP_RDNS) {
26+
hasUniswapProvider = true;
27+
updateDisplay();
28+
}
29+
});
30+
31+
// Request providers via EIP-6963
32+
window.dispatchEvent(new Event('eip6963:requestProvider'));
33+
34+
// Give providers time to respond, then report
35+
setTimeout(() => {
36+
updateDisplay();
37+
report();
38+
}, 500);
39+
40+
function updateDisplay() {
41+
const otherWallet = hasEthereum && !hasUniswapProvider;
42+
document.getElementById('info').innerHTML = `
43+
<div class="status">origin: <strong>${origin}</strong></div>
44+
<div class="status ${hasUniswapProvider ? 'pass' : 'fail'}">
45+
Uniswap provider (EIP-6963): <strong>${hasUniswapProvider ? 'PRESENT' : 'ABSENT'}</strong>
46+
</div>
47+
${otherWallet ? '<div class="status neutral">window.ethereum present from another wallet (ignored)</div>' : ''}
48+
`;
49+
}
50+
51+
function report() {
52+
try {
53+
window.parent.postMessage({
54+
type: 'sandbox-test-report',
55+
origin: origin,
56+
hasUniswapProvider: hasUniswapProvider,
57+
}, '*');
58+
} catch (e) {
59+
// postMessage may fail in some sandbox configurations
60+
}
61+
}
62+
</script>
63+
</body>
64+
</html>
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Extension Sandbox Origin Validation Test</title>
6+
<style>
7+
* { box-sizing: border-box; }
8+
body { font-family: system-ui, -apple-system, sans-serif; background: #0f0f23; color: #e0e0e0; padding: 24px; margin: 0; }
9+
h1 { color: #ff79c6; margin-bottom: 4px; }
10+
.subtitle { color: #888; margin-bottom: 24px; }
11+
.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-bottom: 24px; }
12+
.card { background: #1a1a2e; border: 1px solid #333; border-radius: 8px; padding: 16px; }
13+
.card h3 { margin: 0 0 8px; font-size: 14px; color: #bd93f9; }
14+
.card .detail { font-size: 12px; color: #888; margin-bottom: 12px; }
15+
.card iframe { width: 100%; height: 100px; border: 1px solid #444; border-radius: 4px; }
16+
.result { margin-top: 12px; padding: 8px; border-radius: 4px; font-size: 13px; font-weight: 600; }
17+
.result.pass { background: #0f5132; color: #75b798; border: 1px solid #0f5132; }
18+
.result.fail { background: #842029; color: #ea868f; border: 1px solid #842029; }
19+
.result.waiting { background: #332701; color: #ffda6a; border: 1px solid #332701; }
20+
.instructions { background: #1a1a2e; border: 1px solid #333; border-radius: 8px; padding: 16px; font-size: 13px; line-height: 1.6; }
21+
.instructions code { background: #2a2a3e; padding: 2px 6px; border-radius: 3px; font-size: 12px; }
22+
</style>
23+
</head>
24+
<body>
25+
<h1>Sandbox Origin Validation Test</h1>
26+
<p class="subtitle">Bug bounty #621 — Verify sandboxed frames cannot receive the Uniswap provider</p>
27+
28+
<div class="grid">
29+
<div class="card">
30+
<h3>1. Normal Frame (no sandbox)</h3>
31+
<div class="detail">Expected: origin = http://localhost:*, Uniswap provider = PRESENT</div>
32+
<iframe id="frame-normal" src="child.html"></iframe>
33+
<div id="result-normal" class="result waiting">Waiting for report...</div>
34+
</div>
35+
36+
<div class="card">
37+
<h3>2. Sandboxed (allow-scripts only)</h3>
38+
<div class="detail">Expected: origin = "null", Uniswap provider = ABSENT</div>
39+
<iframe id="frame-sandboxed" src="child.html" sandbox="allow-scripts"></iframe>
40+
<div id="result-sandboxed" class="result waiting">Waiting for report...</div>
41+
</div>
42+
43+
<div class="card">
44+
<h3>3. Sandboxed (allow-scripts + allow-same-origin)</h3>
45+
<div class="detail">Expected: origin = http://localhost:*, Uniswap provider = PRESENT</div>
46+
<iframe id="frame-same-origin" src="child.html" sandbox="allow-scripts allow-same-origin"></iframe>
47+
<div id="result-same-origin" class="result waiting">Waiting for report...</div>
48+
</div>
49+
</div>
50+
51+
<div class="instructions">
52+
<strong>How to use:</strong><br>
53+
1. Serve this directory: <code>python3 -m http.server 8080</code><br>
54+
2. Load the extension in Chrome (webpack dev build via <code>bun start:webpack</code>)<br>
55+
3. Open <code>http://localhost:8080</code> in Chrome<br>
56+
4. All three cards should show their expected results (green = pass, red = fail)<br>
57+
<br>
58+
<strong>Note:</strong> This test detects the <strong>Uniswap provider specifically</strong> via EIP-6963 (<code>rdns: org.uniswap.app</code>),
59+
so other wallet extensions (MetaMask, etc.) won't cause false positives.
60+
</div>
61+
62+
<script>
63+
const expectations = {
64+
normal: { originIsNull: false, hasUniswapProvider: true },
65+
sandboxed: { originIsNull: true, hasUniswapProvider: false },
66+
'same-origin': { originIsNull: false, hasUniswapProvider: true },
67+
};
68+
69+
const received = {};
70+
71+
window.addEventListener('message', (event) => {
72+
if (!event.data || event.data.type !== 'sandbox-test-report') {
73+
return;
74+
}
75+
76+
const { origin, hasUniswapProvider } = event.data;
77+
const isNull = origin === 'null';
78+
79+
// Determine which frame sent this
80+
let frameId = null;
81+
for (const [id, expect] of Object.entries(expectations)) {
82+
if (received[id]) continue;
83+
if (expect.originIsNull === isNull) {
84+
frameId = id;
85+
break;
86+
}
87+
}
88+
89+
// Fallback: match by source iframe
90+
if (!frameId) {
91+
const frames = ['normal', 'sandboxed', 'same-origin'];
92+
for (const id of frames) {
93+
if (received[id]) continue;
94+
const iframe = document.getElementById('frame-' + id);
95+
try {
96+
if (event.source === iframe.contentWindow) {
97+
frameId = id;
98+
break;
99+
}
100+
} catch (e) { /* cross-origin access may throw */ }
101+
}
102+
}
103+
104+
if (!frameId) return;
105+
received[frameId] = true;
106+
107+
const expect = expectations[frameId];
108+
const originPass = expect.originIsNull === isNull;
109+
const providerPass = expect.hasUniswapProvider === hasUniswapProvider;
110+
const allPass = originPass && providerPass;
111+
112+
const el = document.getElementById('result-' + frameId);
113+
el.className = 'result ' + (allPass ? 'pass' : 'fail');
114+
el.innerHTML = `
115+
${allPass ? 'PASS' : 'FAIL'} &mdash;
116+
origin: ${origin} (${originPass ? 'ok' : 'WRONG'}),
117+
Uniswap provider: ${hasUniswapProvider ? 'present' : 'absent'} (${providerPass ? 'ok' : 'WRONG'})
118+
`;
119+
});
120+
121+
// Timeout fallback
122+
setTimeout(() => {
123+
for (const id of Object.keys(expectations)) {
124+
if (!received[id]) {
125+
const el = document.getElementById('result-' + id);
126+
if (el.classList.contains('waiting')) {
127+
el.className = 'result fail';
128+
el.textContent = 'No report received (frame may be blocked)';
129+
}
130+
}
131+
}
132+
}, 5000);
133+
</script>
134+
</body>
135+
</html>

apps/extension/e2e/tests/smoke/basic-setup.test.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,10 @@ test.describe('Basic Extension Setup', () => {
3030
})
3131

3232
test('background script loads', async ({ context }) => {
33-
// Wait for background script/service worker to load
33+
// Wait for service worker to load (MV3 extensions use service workers)
3434
await sleep(ONE_SECOND_MS * 2)
3535

36-
// Check for background pages or service workers
37-
const backgroundPages = context.backgroundPages()
3836
const serviceWorkers = context.serviceWorkers()
39-
40-
// Either background pages or service workers should exist
41-
const hasBackground = backgroundPages.length > 0 || serviceWorkers.length > 0
42-
expect(hasBackground).toBeTruthy()
37+
expect(serviceWorkers.length).toBeGreaterThan(0)
4338
})
4439
})

0 commit comments

Comments
 (0)