@pollar/react 0.10.0-rc.8 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,17 +3,19 @@
3
3
  React bindings for [Pollar](https://pollar.xyz) — drop-in authentication UI, transaction modals, and hooks for
4
4
  Stellar-based applications.
5
5
 
6
- > **0.9.0** requires `@pollar/core@^0.9.0`. `usePollar().walletAddress` is
7
- > unchanged (now derived from `session.wallet.address` internally no consumer
8
- > change), and provider/modal logs route through the client's configured
9
- > `logLevel` / `logger`. Read the [CHANGELOG](../../CHANGELOG.md) before upgrading.
6
+ > **0.10.0** requires `@pollar/core@^0.10.0`. Headline features: on-chain swaps
7
+ > via `<SwapModal>` + `usePollar().swap` / `getSwapQuote` / `openSwapModal`;
8
+ > live SEP-24 on/off-ramps through `<RampWidget>` (now wired to
9
+ > `client.createOnRamp` / `client.createOffRamp`); and a self-driving Privy
10
+ > adapter (registered interactive adapters are auto-driven to completion before
11
+ > `login({ provider })`). Read the [CHANGELOG](../../CHANGELOG.md) before
12
+ > upgrading.
10
13
  >
11
- > **0.8.0 reshapes `<PollarProvider>` props (breaking).** `config` `client`
14
+ > **0.8.0 reshapes `<PollarProvider>` props (breaking).** `config` > `client`
12
15
  > (now accepts a `PollarClient` instance or a `PollarClientConfig`); `styles`
13
16
  > moves under `appConfig.styles`; new `appConfig` prop is the opt-out switch
14
- > for the remote `/applications/config` fetch (pass it even `{}` to skip
15
- > the fetch); new `ui.renderWallets` slot replaces the default Freighter/Albedo
16
- > picker. Read the [CHANGELOG](../../CHANGELOG.md) and
17
+ > for the remote `/applications/config` fetch (pass it - even `{}` - to skip
18
+ > the fetch). Read the [CHANGELOG](../../CHANGELOG.md) and
17
19
  > [UPGRADE.md](../../UPGRADE.md) before upgrading.
18
20
 
19
21
  ## Installation
@@ -45,18 +47,18 @@ export default function App({ children }: { children: React.ReactNode }) {
45
47
  import { usePollar } from '@pollar/react';
46
48
 
47
49
  export function Profile() {
48
- const { isAuthenticated, walletAddress, login, logout, getClient } = usePollar();
50
+ const { isAuthenticated, wallet, login, logout, getClient } = usePollar();
49
51
 
50
52
  if (!isAuthenticated) {
51
53
  return <button onClick={() => login({ provider: 'google' })}>Sign in with Google</button>;
52
54
  }
53
55
 
54
- // PII (email, name, avatar, providers) lives in memory only fetch it from the client.
56
+ // PII (email, name, avatar, providers) lives in memory only - fetch it from the client.
55
57
  const profile = getClient().getUserProfile();
56
58
 
57
59
  return (
58
60
  <div>
59
- <p>Wallet: {walletAddress}</p>
61
+ <p>Wallet: {wallet?.address}</p>
60
62
  <p>Email: {profile?.mail}</p>
61
63
  <button onClick={logout}>Sign out</button>
62
64
  </div>
@@ -89,11 +91,6 @@ Context provider that initialises the Pollar client and makes it available to ch
89
91
  /* optional style overrides */
90
92
  },
91
93
  }}
92
- ui={{
93
- // Optional: replace the default Freighter/Albedo wallet picker.
94
- // See "External wallet stacks" below for a kit-powered example.
95
- renderWallets: undefined,
96
- }}
97
94
  adapters={
98
95
  {
99
96
  /* optional named adapter set */
@@ -104,12 +101,11 @@ Context provider that initialises the Pollar client and makes it available to ch
104
101
  </PollarProvider>
105
102
  ```
106
103
 
107
- | Prop | Type | Required | Description |
108
- | ----------- | --------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
109
- | `client` | `PollarClient \| PollarClientConfig` | Yes | Either a pre-built `PollarClient` (testing, reuse outside React) or a `PollarClientConfig` the provider will construct one from. **Locked at first render** — swapping after mount is ignored |
110
- | `appConfig` | `PollarConfig` | No | Local override of `/applications/config`. **Presence is the opt-out switch**: pass it (even `{}`) and the remote fetch is skipped. Omit it to keep the existing remote-fetch-on-mount behaviour |
111
- | `ui` | `{ renderWallets?: RenderWalletsSlot }` | No | UI customisation slots. `renderWallets` replaces the default Freighter/Albedo buttons in `LoginModal`'s wallet picker. Receives `{ onConnect, authState }` and is expected to call `onConnect(walletId)` |
112
- | `adapters` | `PollarAdapters` | No | Named set of `PollarAdapter` objects (e.g. Trustless Work). See below |
104
+ | Prop | Type | Required | Description |
105
+ | ----------- | ------------------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
106
+ | `client` | `PollarClient \| PollarClientConfig` | Yes | Either a pre-built `PollarClient` (testing, reuse outside React) or a `PollarClientConfig` the provider will construct one from. **Locked at first render** — swapping after mount is ignored |
107
+ | `appConfig` | `PollarConfig` | No | Local override of `/applications/config`. **Presence is the opt-out switch**: pass it (even `{}`) and the remote fetch is skipped. Omit it to keep the existing remote-fetch-on-mount behaviour |
108
+ | `adapters` | `PollarAdapters` | No | Named set of `PollarAdapter` objects (e.g. Trustless Work). See below |
113
109
 
114
110
  > **Renamed in 0.8.0** — `config` → `client`, `styles` → `appConfig.styles`.
115
111
  > If you were passing `styles={{ ... }}` directly, move it to
@@ -127,25 +123,30 @@ needed.
127
123
  ```ts
128
124
  const {
129
125
  // Session
130
- isAuthenticated, // boolean true when a wallet public key is present
131
- walletAddress, // string '' until authenticated
132
- walletType, // WalletId | null
126
+ isAuthenticated, // boolean - true when a wallet address is present
127
+ wallet, // WalletInfo | null - read wallet?.address for the on-chain address
128
+ verified, // boolean - true once the server has confirmed the session
133
129
 
134
130
  // Client escape hatch
135
- getClient, // () => PollarClient for getUserProfile(), listSessions(), …
131
+ getClient, // () => PollarClient - for getUserProfile(), listSessions(), …
136
132
 
137
133
  // Auth
138
134
  login, // (options: PollarLoginOptions) => void
139
135
  logout, // () => void (fire-and-forget; await getClient().logout() if you need the promise)
140
136
  openLoginModal, // () => void
141
137
 
142
- // Sessions (new in 0.7.0)
138
+ // Sessions
139
+ sessions, // SessionsState
143
140
  openSessionsModal, // () => void
144
141
 
145
142
  // Transactions
146
143
  tx, // TransactionState
147
- buildTx, // (operation, params, options?) => Promise<void>
148
- signAndSubmitTx, // (unsignedXdr: string) => Promise<void>
144
+ buildTx, // (operation, params, options?) => Promise<BuildOutcome>
145
+ signAndSubmitTx, // (unsignedXdr?: string) => Promise<SubmitOutcome> (custodial; XDR optional)
146
+ signTx, // (unsignedXdr: string) => Promise<SignOutcome> (external-wallet only)
147
+ submitTx, // (signedXdr: string) => Promise<SubmitOutcome>
148
+ buildAndSignAndSubmitTx, // (operation, params, options?) => Promise<SubmitOutcome> (one-shot)
149
+ runTx, // alias of buildAndSignAndSubmitTx
149
150
  openTxModal, // () => void
150
151
 
151
152
  // Transaction history
@@ -157,18 +158,32 @@ const {
157
158
  refreshWalletBalance, // () => Promise<void>
158
159
  openWalletBalanceModal, // () => void
159
160
 
161
+ // Enabled assets / trustlines
162
+ enabledAssets, // EnabledAssetsState
163
+ refreshAssets, // () => Promise<void>
164
+ setTrustline, // (asset, opts?) => Promise<TrustlineOutcome>
165
+ openEnabledAssetsModal, // () => void
166
+
167
+ // Swap (DEX/AMM)
168
+ getSwapQuote, // (params: SwapQuoteParams) => Promise<SwapQuote[]>
169
+ swap, // (quote: SwapQuote, opts?) => Promise<SubmitOutcome>
170
+ openSwapModal, // () => void
171
+
172
+ // Distribution rules
173
+ openDistributionRulesModal, // () => void
174
+
160
175
  // Send / Receive
161
176
  openSendModal, // () => void
162
177
  openReceiveModal, // () => void
163
178
 
164
179
  // Network
165
- network, // StellarNetwork 'mainnet' | 'testnet'
180
+ network, // StellarNetwork - 'mainnet' | 'testnet'
166
181
  setNetwork, // (network: StellarNetwork) => void
167
182
 
168
- // KYC (UI ready backend coming soon)
183
+ // KYC (UI ready - backend coming soon)
169
184
  openKycModal, // (options?: { country?, level?, onApproved? }) => void
170
185
 
171
- // Ramp (UI ready backend coming soon)
186
+ // Ramp (SEP-24 on/off-ramps, wired through core)
172
187
  openRampModal, // () => void
173
188
 
174
189
  // App config / styles served by the Pollar API
@@ -180,8 +195,11 @@ const {
180
195
  } = usePollar();
181
196
  ```
182
197
 
183
- > **0.6.0 renames** `transaction` → `tx`, `openTransactionModal` `openTxModal`, `config` `appConfig`,
184
- > `openRampWidget` `openRampModal`, `refreshBalance` → `refreshWalletBalance`. Existing code on 0.5.x must update.
198
+ Custody is derived from `wallet`, not a separate field - e.g.
199
+ `wallet?.custody === 'external' ? wallet.provider : null`.
200
+
201
+ > **0.6.0 renames** - `transaction` > `tx`, `openTransactionModal` > `openTxModal`, `config` > `appConfig`,
202
+ > `openRampWidget` > `openRampModal`, `refreshBalance` > `refreshWalletBalance`. Existing code on 0.5.x must update.
185
203
 
186
204
  #### Login options
187
205
 
@@ -193,16 +211,32 @@ login({ provider: 'github' });
193
211
  // Email OTP
194
212
  login({ provider: 'email', email: 'user@example.com' });
195
213
 
196
- // Built-in Stellar wallet adapters
214
+ // Built-in Stellar wallet adapters (the adapter's `type` IS the provider)
197
215
  import { WalletType } from '@pollar/core';
198
- login({ provider: 'wallet', type: WalletType.FREIGHTER });
199
- login({ provider: 'wallet', type: WalletType.ALBEDO });
216
+ login({ provider: WalletType.FREIGHTER }); // 'freighter-native'
217
+ login({ provider: WalletType.ALBEDO }); // 'albedo-native'
200
218
 
201
- // Any external adapter (e.g. Stellar Wallets Kit) when `walletAdapter` is set on config
202
- login({ provider: 'wallet', type: 'xbull' });
203
- login({ provider: 'wallet', type: 'lobstr' });
219
+ // Any external adapter (e.g. Stellar Wallets Kit) registered via `walletAdapters`
220
+ login({ provider: 'xbull' });
221
+ login({ provider: 'lobstr' });
204
222
  ```
205
223
 
224
+ #### Self-driving interactive adapters (Privy, …)
225
+
226
+ Registered adapters that opt into the interactive-auth contract
227
+ (`isInteractiveAuthAdapter` + `onProviderAuthChange`) are auto-driven by the
228
+ provider:
229
+
230
+ - `LoginModal` renders a login entry per registered wallet adapter, so each
231
+ interactive provider gets its own button.
232
+ - Picking one opens `PrivyLoginSubmodal`, which drives the adapter's own login
233
+ (email code / OAuth) to completion, then hands off to `login({ provider })`
234
+ (which runs `connect()` + SEP-10).
235
+ - If the provider authenticates outside the sub-modal - after an OAuth redirect
236
+ that reloaded the page, or a persisted provider session on load - the
237
+ provider's `onProviderAuthChange` subscription fires `login({ provider })`
238
+ automatically when Pollar has no session yet.
239
+
206
240
  ---
207
241
 
208
242
  ### Components
@@ -212,14 +246,17 @@ already wired inside `<PollarProvider>` — but they're exported in case you wan
212
246
 
213
247
  | Component | Purpose |
214
248
  | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
215
- | `<WalletButton>` | Drop-in button. Opens login when signed out; signed in, shows the wallet address with a dropdown (Send, Receive, balance, history, sign out). Inline arc spinner during in-progress transactions |
216
- | `<SendModal>` | Full send flow: asset picker, amount, destination, inline build sign success/error |
217
- | `<ReceiveModal>` | Wallet address as QR code with copy-to-clipboard (no external QR dependency required) |
218
- | `<TxHistoryModal>` | Paginated transaction history with auto-fetch on open and stellar.expert explorer links |
219
- | `<WalletBalanceModal>` | Stellar account balances with refresh button |
220
- | `<SessionsModal>` | **New in 0.7.0.** Lists every active refresh-token family for the current user with device metadata, marks the local session, per-row revoke, and a "Sign out everywhere" button |
221
- | `<KycModal>` | Identity verification flow provider selection + status polling _(UI preview — backend coming soon)_ |
222
- | `<RampWidget>` | Buy/sell crypto direction tabs, route comparison, payment instructions _(UI preview — backend coming soon)_ |
249
+ | `<WalletButton>` | Drop-in button. Opens login when signed out; signed in, shows the wallet address with a dropdown (Send, Receive, copy address, balance, history, ramp, KYC, distribution rules, sessions, sign out). Inline arc spinner during in-progress transactions |
250
+ | `<SendModal>` | Full send flow: asset picker, amount, destination, inline build > sign > success/error |
251
+ | `<SwapModal>` | On-chain asset-to-asset swap: pick from/to assets and amount, quote across venues, execute (auto-trustline on the buy asset when needed) |
252
+ | `<ReceiveModal>` | Wallet address as QR code with copy-to-clipboard (no external QR dependency required) |
253
+ | `<TxHistoryModal>` | Paginated transaction history with auto-fetch on open and stellar.expert explorer links |
254
+ | `<WalletBalanceModal>` | Stellar account balances with refresh button |
255
+ | `<EnabledAssetsModal>` | The application's dashboard-enabled assets with per-asset trustline state; establish/remove trustlines |
256
+ | `<DistributionRulesModal>` | Manage the wallet's distribution rules |
257
+ | `<SessionsModal>` | **New in 0.7.0.** Lists every active refresh-token family for the current user with device metadata, marks the local session, per-row revoke, and a "Sign out everywhere" button |
258
+ | `<KycModal>` | Identity verification flow - provider selection + status polling _(UI preview - backend coming soon)_ |
259
+ | `<RampWidget>` | Buy/sell crypto via SEP-24 - direction tabs, route comparison, payment instructions (wired to `client.createOnRamp` / `client.createOffRamp`) |
223
260
 
224
261
  ```tsx
225
262
  import { WalletButton } from '@pollar/react';
@@ -241,10 +278,13 @@ want to swap the chrome but keep the data wiring from `usePollar()`.
241
278
  | `<WalletButton>` | `<WalletButtonTemplate>` |
242
279
  | _(internal LoginModal)_ | `<LoginModalTemplate>` |
243
280
  | `<SendModal>` | `<SendModalTemplate>` |
281
+ | `<SwapModal>` | `<SwapModalTemplate>` |
244
282
  | `<ReceiveModal>` | `<ReceiveModalTemplate>` |
245
283
  | `<TransactionModal>` | `<TransactionModalTemplate>` |
246
284
  | `<TxHistoryModal>` | `<TxHistoryModalTemplate>` |
247
285
  | `<WalletBalanceModal>` | `<WalletBalanceModalTemplate>` |
286
+ | `<EnabledAssetsModal>` | `<EnabledAssetsModalTemplate>` |
287
+ | `<DistributionRulesModal>` | `<DistributionRulesModalTemplate>` |
248
288
  | `<KycModal>` | `<KycModalTemplate>` |
249
289
  | `<RampWidget>` | `<RampWidgetTemplate>` |
250
290
  | `<SessionsModal>` | `<SessionsModalTemplate>` |
@@ -252,8 +292,7 @@ want to swap the chrome but keep the data wiring from `usePollar()`.
252
292
  `<TxStatusView>` is the shared status component (build → sign → success/error) reused by `TransactionModal` and
253
293
  `SendModal`; it's exported on its own for consumers that want to embed the lifecycle elsewhere.
254
294
 
255
- > **0.8.1** — `onWalletConnect` is now **optional** on `<LoginModalTemplate>` (defaults to a no-op). If you drive the
256
- > wallet picker entirely through `ui.renderWallets`, you no longer have to pass a handler you don't use.
295
+ > **0.8.1** — `onWalletConnect` is now **optional** on `<LoginModalTemplate>` (defaults to a no-op).
257
296
 
258
297
  ---
259
298
 
@@ -299,68 +338,33 @@ function MyComponent() {
299
338
 
300
339
  ### External wallet stacks (Stellar Wallets Kit, …)
301
340
 
302
- Pass a `WalletAdapterResolver` to `client.walletAdapter` so Pollar can reach
303
- wallets that live outside `@pollar/core`. The signing path alone (no UI
304
- changes):
341
+ Register adapters for wallets that live outside `@pollar/core` by passing a
342
+ `walletAdapters: WalletAdapter[]` array. `LoginModal` auto-renders one button per
343
+ registered adapter, and each is reachable via `login({ provider: adapter.type })`.
344
+ `stellarWalletsKitAdapters()` returns that array (one adapter per kit module):
305
345
 
306
346
  ```tsx
307
347
  import { PollarProvider } from '@pollar/react';
308
- import { stellarWalletsKit } from '@pollar/stellar-wallets-kit-adapter';
348
+ import { stellarWalletsKitAdapters } from '@pollar/stellar-wallets-kit-adapter';
309
349
  import { Networks } from '@creit.tech/stellar-wallets-kit';
310
350
 
311
351
  <PollarProvider
312
352
  client={{
313
353
  apiKey: 'your-api-key',
314
- walletAdapter: stellarWalletsKit({ network: Networks.PUBLIC }),
354
+ walletAdapters: stellarWalletsKitAdapters({
355
+ network: Networks.PUBLIC,
356
+ picker: { wallets: ['xbull', 'lobstr', 'freighter'] }, // subset, optional
357
+ }),
315
358
  }}
316
359
  >
317
360
  {children}
318
361
  </PollarProvider>;
319
362
  ```
320
363
 
321
- Then any `login({ provider: 'wallet', type: '<kit wallet id>' })` is routed
322
- through the kit. The built-in `LoginModal` still shows only Freighter / Albedo
323
- unless you also wire `ui.renderWallets` (next section).
324
-
325
- #### Showing every kit wallet in `LoginModal`
326
-
327
- The `ui.renderWallets` slot replaces the hardcoded Freighter+Albedo buttons.
328
- `@pollar/stellar-wallets-kit-adapter/picker` ships a bundle that builds both
329
- halves (signing + picker UI) from a single options object — drop both into
330
- `<PollarProvider>` and the kit's full wallet list (xBull, Lobstr, Rabet, …)
331
- renders in `LoginModal`:
332
-
333
- ```tsx
334
- import { PollarProvider } from '@pollar/react';
335
- import { createStellarWalletsKitBundle } from '@pollar/stellar-wallets-kit-adapter/picker';
336
- import { Networks } from '@creit.tech/stellar-wallets-kit';
337
-
338
- const bundle = createStellarWalletsKitBundle({
339
- network: Networks.PUBLIC,
340
- picker: { wallets: ['xbull', 'lobstr', 'freighter'] }, // subset, optional
341
- });
342
-
343
- <PollarProvider
344
- client={{ apiKey: 'your-api-key', walletAdapter: bundle.walletAdapter }}
345
- ui={{ renderWallets: bundle.renderWallets }}
346
- >
347
- {children}
348
- </PollarProvider>;
349
- ```
350
-
351
- If you only want a custom picker (no kit), `renderWallets` is just a function
352
- of `{ onConnect, authState }` — return whatever JSX you want and call
353
- `onConnect(walletId)` when the user picks a wallet:
354
-
355
- ```tsx
356
- ui={{
357
- renderWallets: ({ onConnect, authState }) => (
358
- <button disabled={authState.step !== 'idle'} onClick={() => onConnect('xbull')}>
359
- xBull
360
- </button>
361
- ),
362
- }}
363
- ```
364
+ Each adapter's `meta.group` controls placement: adapters sharing a group label
365
+ collapse behind one gateway button (the kit wallets default to `'Wallet'`),
366
+ while adapters with no group — e.g. Privy — render as their own button in the
367
+ root view. Pass `picker.groupLabel` to give the kit wallets a distinct gateway.
364
368
 
365
369
  ---
366
370
 
@@ -382,23 +386,25 @@ All class names are prefixed with `pollar-` to avoid conflicts.
382
386
 
383
387
  ```ts
384
388
  import type {
385
- AuthProviderProps,
386
- AuthContextValue,
387
389
  LoginButtonProps,
388
390
  AuthModalProps,
389
391
  PollarConfig,
390
392
  PollarStyles,
391
393
 
392
- // 0.8.0 wallet picker slot
393
- RenderWalletsProps,
394
- RenderWalletsSlot,
394
+ // Custom-provider contracts (re-exported from @pollar/core)
395
+ PollarAuthProvider,
396
+ AuthProviderContext,
395
397
 
396
398
  // Template props
399
+ WalletButtonTemplateProps,
397
400
  SendModalTemplateProps,
401
+ SwapModalTemplateProps,
402
+ SwapAssetOption,
398
403
  ReceiveModalTemplateProps,
399
404
  TransactionModalTemplateProps,
400
405
  TxStatusViewProps,
401
406
  WalletBalanceModalTemplateProps,
407
+ EnabledAssetsModalTemplateProps,
402
408
  SessionsModalTemplateProps,
403
409
  SessionsState,
404
410
 
package/dist/index.css CHANGED
@@ -19,6 +19,9 @@
19
19
  display: flex;
20
20
  align-items: center;
21
21
  justify-content: center;
22
+ overflow-y: auto;
23
+ padding: 1rem;
24
+ box-sizing: border-box;
22
25
  background-color: rgba(0, 0, 0, 0.5);
23
26
  }
24
27
  .pollar-modal-card {
@@ -31,6 +34,8 @@
31
34
  background-color: var(--pollar-bg);
32
35
  box-sizing: border-box;
33
36
  font-family: inherit;
37
+ max-height: calc(100dvh - 2rem);
38
+ overflow-y: auto;
34
39
  }
35
40
  .pollar-input {
36
41
  width: 100%;
@@ -142,6 +147,7 @@
142
147
  flex: 1;
143
148
  }
144
149
  .pollar-btn-primary {
150
+ width: 100%;
145
151
  height: var(--pollar-buttons-height, 44px);
146
152
  border: none;
147
153
  border-radius: var(--pollar-buttons-border-radius, 0.5rem);
@@ -1019,26 +1025,29 @@
1019
1025
  .pollar-wallet-list {
1020
1026
  display: flex;
1021
1027
  flex-direction: column;
1022
- gap: 0.25rem;
1028
+ gap: 0.625rem;
1023
1029
  margin-top: 0.5rem;
1024
1030
  }
1025
1031
  .pollar-wallet-list-btn {
1026
1032
  display: flex;
1027
1033
  width: 100%;
1028
1034
  align-items: center;
1029
- gap: 1rem;
1030
- padding: 0.75rem 0.75rem;
1035
+ justify-content: center;
1036
+ gap: 0.75rem;
1037
+ min-height: var(--pollar-buttons-height, 44px);
1038
+ padding: 0 1rem;
1031
1039
  border-radius: var(--pollar-buttons-border-radius, 0.5rem);
1032
- border: 1px solid transparent;
1033
- background-color: transparent;
1040
+ border: 1px solid var(--pollar-border);
1041
+ background-color: var(--pollar-input-bg);
1034
1042
  color: var(--pollar-text);
1043
+ font-size: 1rem;
1044
+ font-weight: 500;
1035
1045
  cursor: pointer;
1036
1046
  transition: all 0.15s;
1037
1047
  box-sizing: border-box;
1038
- text-align: left;
1048
+ text-align: center;
1039
1049
  }
1040
1050
  .pollar-wallet-list-btn:hover:not(:disabled) {
1041
- background-color: var(--pollar-input-bg);
1042
1051
  border-color: var(--pollar-accent);
1043
1052
  color: var(--pollar-accent);
1044
1053
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
@@ -1051,9 +1060,9 @@
1051
1060
  cursor: not-allowed;
1052
1061
  }
1053
1062
  .pollar-wallet-list-icon {
1054
- width: 2.75rem;
1055
- height: 2.75rem;
1056
- border-radius: 0.625rem;
1063
+ width: 1.5rem;
1064
+ height: 1.5rem;
1065
+ border-radius: 0.375rem;
1057
1066
  flex-shrink: 0;
1058
1067
  object-fit: contain;
1059
1068
  }
@@ -1105,7 +1114,7 @@
1105
1114
  height: var(--pollar-buttons-height, 44px);
1106
1115
  align-items: center;
1107
1116
  justify-content: center;
1108
- gap: 0.625rem;
1117
+ gap: 0.75rem;
1109
1118
  border-radius: var(--pollar-buttons-border-radius, 0.5rem);
1110
1119
  border: 1px solid var(--pollar-border);
1111
1120
  background-color: var(--pollar-input-bg);
@@ -1755,6 +1764,26 @@
1755
1764
  animation: pollar-pulse 1.4s ease-in-out infinite;
1756
1765
  }
1757
1766
 
1767
+ /* src/components/swap-modal/SwapModal.css */
1768
+ .pollar-swap-quote {
1769
+ display: flex;
1770
+ flex-direction: column;
1771
+ gap: 8px;
1772
+ padding: 12px;
1773
+ margin-bottom: 12px;
1774
+ border: 1px solid var(--pollar-border);
1775
+ border-radius: var(--pollar-card-border-radius);
1776
+ background: var(--pollar-input-bg);
1777
+ color: var(--pollar-text);
1778
+ font-size: 14px;
1779
+ }
1780
+ .pollar-swap-quote-row {
1781
+ display: flex;
1782
+ align-items: center;
1783
+ justify-content: space-between;
1784
+ gap: 12px;
1785
+ }
1786
+
1758
1787
  /* src/components/sessions-modal/SessionsModal.css */
1759
1788
  .pollar-sessions-modal {
1760
1789
  max-width: 480px;