Skip to content

Commit a4b2d2f

Browse files
enesozturkclaude
andauthored
feat: expose headless wallet list imperatively on the AppKit client (#5695)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 1c17897 commit a4b2d2f

12 files changed

Lines changed: 925 additions & 32 deletions

File tree

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
'@reown/appkit-utils': patch
3+
'@reown/appkit': patch
4+
'@reown/appkit-cdn': patch
5+
'@reown/appkit-cli': patch
6+
'@reown/appkit-codemod': patch
7+
'@reown/appkit-common': patch
8+
'@reown/appkit-core': patch
9+
'@reown/appkit-experimental': patch
10+
'@reown/appkit-pay': patch
11+
'@reown/appkit-polyfills': patch
12+
'@reown/appkit-scaffold-ui': patch
13+
'@reown/appkit-siwe': patch
14+
'@reown/appkit-siwx': patch
15+
'@reown/appkit-testing': patch
16+
'@reown/appkit-ui': patch
17+
'@reown/appkit-universal-connector': patch
18+
'@reown/appkit-wallet-button': patch
19+
'@reown/appkit-wallet': patch
20+
'@reown/appkit-controllers': patch
21+
'@reown/appkit-adapter-bitcoin': patch
22+
'@reown/appkit-adapter-ethers': patch
23+
'@reown/appkit-adapter-ethers5': patch
24+
'@reown/appkit-adapter-solana': patch
25+
'@reown/appkit-adapter-ton': patch
26+
'@reown/appkit-adapter-tron': patch
27+
'@reown/appkit-adapter-wagmi': patch
28+
---
29+
30+
Expose the headless wallet list imperatively on the AppKit client, so a non-React host can list / search / connect wallets without the `useAppKitWallets` React hook.
31+
32+
New `AppKit` instance methods: `fetchWallets(options?)`, `getWalletList()`, `subscribeWalletList(cb)`, `getWalletConnectUri(options?)`, and `connectWallet(wallet, namespace?, options?)`. The shared imperative logic lives in a new `HeadlessWalletUtil` (`@reown/appkit-controllers`), which both the client methods and the React hook can use — one tested code path for headless wallet listing, search, pagination, the WalletConnect URI, and programmatic connect (injected / API / mobile-deeplink).

examples/html-headless/index.html

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>AppKit Headless (vanilla) Example</title>
7+
<link rel="stylesheet" href="/src/main.css" />
8+
</head>
9+
<body>
10+
<main class="page">
11+
<h1 class="title">AppKit Headless — vanilla JS</h1>
12+
<p class="subtitle">
13+
A custom wallet modal driven entirely by the imperative AppKit client API (<code
14+
>appKit.fetchWallets</code
15+
>
16+
/ <code>getWalletList</code> / <code>subscribeWalletList</code> /
17+
<code>connectWallet</code>) — no React, no AppKit modal.
18+
</p>
19+
20+
<!-- Connected account -->
21+
<section id="account" class="account" hidden>
22+
<span id="account-address" class="account__address"></span>
23+
<button id="disconnect" class="btn btn--outline">Disconnect</button>
24+
</section>
25+
26+
<!-- Open the custom wallet modal -->
27+
<button id="open" class="btn">Connect wallet</button>
28+
29+
<!-- Custom headless wallet modal -->
30+
<div id="modal" class="modal" hidden>
31+
<div class="modal__backdrop" data-close></div>
32+
<div class="modal__card">
33+
<div class="modal__header">
34+
<h2>Select a wallet</h2>
35+
<button class="modal__close" data-close>&times;</button>
36+
</div>
37+
<!-- Wallet list with infinite loading -->
38+
<div id="wallet-list" class="wallet-list"></div>
39+
<p id="list-status" class="wallet-list__status"></p>
40+
</div>
41+
</div>
42+
</main>
43+
44+
<script type="module" src="/src/main.js"></script>
45+
</body>
46+
</html>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "@examples/html-headless",
3+
"private": true,
4+
"version": "1.2.0",
5+
"scripts": {
6+
"dev": "vite --port 3013",
7+
"build": "vite build"
8+
},
9+
"dependencies": {
10+
"@reown/appkit-adapter-wagmi": "workspace:*",
11+
"@reown/appkit": "workspace:*"
12+
},
13+
"devDependencies": {
14+
"vite": "5.4.20"
15+
}
16+
}
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
:root {
2+
--bg: #0b0d12;
3+
--panel: #151821;
4+
--border: #262b38;
5+
--text: #e7e9ee;
6+
--muted: #9aa3b2;
7+
--accent: #3396ff;
8+
font-family:
9+
ui-sans-serif,
10+
system-ui,
11+
-apple-system,
12+
sans-serif;
13+
}
14+
15+
* {
16+
box-sizing: border-box;
17+
}
18+
19+
body {
20+
margin: 0;
21+
min-height: 100vh;
22+
background: var(--bg);
23+
color: var(--text);
24+
display: flex;
25+
justify-content: center;
26+
padding: 3rem 1rem;
27+
}
28+
29+
.page {
30+
width: 100%;
31+
max-width: 30rem;
32+
}
33+
34+
.title {
35+
margin: 0;
36+
font-size: 1.5rem;
37+
}
38+
39+
.subtitle {
40+
color: var(--muted);
41+
font-size: 0.9rem;
42+
line-height: 1.5;
43+
}
44+
45+
.subtitle code {
46+
color: var(--accent);
47+
font-size: 0.82rem;
48+
}
49+
50+
.btn {
51+
padding: 0.7rem 1.1rem;
52+
border: 0;
53+
border-radius: 10px;
54+
background: var(--accent);
55+
color: #fff;
56+
font-size: 0.95rem;
57+
cursor: pointer;
58+
}
59+
60+
.btn--outline {
61+
background: transparent;
62+
border: 1px solid var(--border);
63+
color: var(--text);
64+
padding: 0.4rem 0.75rem;
65+
font-size: 0.85rem;
66+
}
67+
68+
.account {
69+
display: flex;
70+
align-items: center;
71+
justify-content: space-between;
72+
gap: 0.75rem;
73+
padding: 0.85rem 1rem;
74+
margin-bottom: 1rem;
75+
background: var(--panel);
76+
border: 1px solid var(--border);
77+
border-radius: 12px;
78+
}
79+
80+
.account__address {
81+
font-family: ui-monospace, monospace;
82+
}
83+
84+
/* -- Modal ----------------------------------------------------------------- */
85+
.modal {
86+
position: fixed;
87+
inset: 0;
88+
display: flex;
89+
align-items: center;
90+
justify-content: center;
91+
padding: 1rem;
92+
}
93+
94+
.modal__backdrop {
95+
position: absolute;
96+
inset: 0;
97+
background: rgba(0, 0, 0, 0.55);
98+
}
99+
100+
.modal__card {
101+
position: relative;
102+
width: 100%;
103+
max-width: 24rem;
104+
background: var(--panel);
105+
border: 1px solid var(--border);
106+
border-radius: 16px;
107+
padding: 1.25rem;
108+
}
109+
110+
.modal__header {
111+
display: flex;
112+
align-items: center;
113+
justify-content: space-between;
114+
margin-bottom: 0.75rem;
115+
}
116+
117+
.modal__header h2 {
118+
margin: 0;
119+
font-size: 1.1rem;
120+
}
121+
122+
.modal__close {
123+
background: none;
124+
border: 0;
125+
color: var(--muted);
126+
font-size: 1.4rem;
127+
cursor: pointer;
128+
line-height: 1;
129+
}
130+
131+
.wallet-list {
132+
max-height: 22rem;
133+
overflow-y: auto;
134+
display: flex;
135+
flex-direction: column;
136+
gap: 0.35rem;
137+
}
138+
139+
.wallet {
140+
display: flex;
141+
align-items: center;
142+
gap: 0.75rem;
143+
width: 100%;
144+
padding: 0.6rem 0.7rem;
145+
background: transparent;
146+
border: 1px solid var(--border);
147+
border-radius: 10px;
148+
color: var(--text);
149+
cursor: pointer;
150+
font-size: 0.95rem;
151+
text-align: left;
152+
}
153+
154+
.wallet:hover {
155+
border-color: var(--accent);
156+
}
157+
158+
.wallet__icon {
159+
width: 2rem;
160+
height: 2rem;
161+
border-radius: 8px;
162+
object-fit: cover;
163+
background: var(--bg);
164+
flex-shrink: 0;
165+
}
166+
167+
.wallet-list__status {
168+
margin: 0.75rem 0 0;
169+
text-align: center;
170+
font-size: 0.8rem;
171+
color: var(--muted);
172+
}

0 commit comments

Comments
 (0)