@valve-tech/tx-flight-react 0.0.1
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/CHANGELOG.md +17 -0
- package/LICENSE +21 -0
- package/README.md +283 -0
- package/dist/components/actions.d.ts +32 -0
- package/dist/components/actions.d.ts.map +1 -0
- package/dist/components/actions.js +10 -0
- package/dist/components/actions.js.map +1 -0
- package/dist/components/age.d.ts +21 -0
- package/dist/components/age.d.ts.map +1 -0
- package/dist/components/age.js +29 -0
- package/dist/components/age.js.map +1 -0
- package/dist/components/hash-link.d.ts +26 -0
- package/dist/components/hash-link.d.ts.map +1 -0
- package/dist/components/hash-link.js +20 -0
- package/dist/components/hash-link.js.map +1 -0
- package/dist/components/item.d.ts +27 -0
- package/dist/components/item.d.ts.map +1 -0
- package/dist/components/item.js +18 -0
- package/dist/components/item.js.map +1 -0
- package/dist/components/list.d.ts +27 -0
- package/dist/components/list.d.ts.map +1 -0
- package/dist/components/list.js +14 -0
- package/dist/components/list.js.map +1 -0
- package/dist/components/status-icon.d.ts +20 -0
- package/dist/components/status-icon.d.ts.map +1 -0
- package/dist/components/status-icon.js +28 -0
- package/dist/components/status-icon.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/tx-tracker.d.ts +48 -0
- package/dist/integrations/tx-tracker.d.ts.map +1 -0
- package/dist/integrations/tx-tracker.js +169 -0
- package/dist/integrations/tx-tracker.js.map +1 -0
- package/dist/integrations/wallet-adapter.d.ts +34 -0
- package/dist/integrations/wallet-adapter.d.ts.map +1 -0
- package/dist/integrations/wallet-adapter.js +97 -0
- package/dist/integrations/wallet-adapter.js.map +1 -0
- package/dist/provider.d.ts +67 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +182 -0
- package/dist/provider.js.map +1 -0
- package/dist/storage/index.d.ts +7 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +7 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/indexed-db.d.ts +21 -0
- package/dist/storage/indexed-db.d.ts.map +1 -0
- package/dist/storage/indexed-db.js +58 -0
- package/dist/storage/indexed-db.js.map +1 -0
- package/dist/storage/local-storage.d.ts +18 -0
- package/dist/storage/local-storage.d.ts.map +1 -0
- package/dist/storage/local-storage.js +39 -0
- package/dist/storage/local-storage.js.map +1 -0
- package/dist/storage/memory.d.ts +7 -0
- package/dist/storage/memory.d.ts.map +1 -0
- package/dist/storage/memory.js +17 -0
- package/dist/storage/memory.js.map +1 -0
- package/dist/storage/serialize.d.ts +13 -0
- package/dist/storage/serialize.d.ts.map +1 -0
- package/dist/storage/serialize.js +29 -0
- package/dist/storage/serialize.js.map +1 -0
- package/dist/store/reducers.d.ts +53 -0
- package/dist/store/reducers.d.ts.map +1 -0
- package/dist/store/reducers.js +135 -0
- package/dist/store/reducers.js.map +1 -0
- package/dist/store/store.d.ts +56 -0
- package/dist/store/store.d.ts.map +1 -0
- package/dist/store/store.js +93 -0
- package/dist/store/store.js.map +1 -0
- package/dist/types.d.ts +96 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +21 -0
- package/dist/types.js.map +1 -0
- package/dist/use-tx-flight.d.ts +31 -0
- package/dist/use-tx-flight.d.ts.map +1 -0
- package/dist/use-tx-flight.js +47 -0
- package/dist/use-tx-flight.js.map +1 -0
- package/package.json +83 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@valve-tech/tx-flight-react` are documented in
|
|
4
|
+
this file.
|
|
5
|
+
|
|
6
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
7
|
+
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
8
|
+
|
|
9
|
+
## [Unreleased]
|
|
10
|
+
|
|
11
|
+
Full v0.9.0 surface ships in the synchronized toolkit release.
|
|
12
|
+
|
|
13
|
+
## [0.0.1] — 2026-05-08
|
|
14
|
+
|
|
15
|
+
Name-claim publish so the npm trusted-publisher record can be wired
|
|
16
|
+
before the synced v0.9.0 release. No usable surface — the package
|
|
17
|
+
exports its types but the implementation lands at v0.9.0.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Valve Tech
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# `@valve-tech/tx-flight-react`
|
|
2
|
+
|
|
3
|
+
React UI primitives for an in-flight transaction strip. Provider,
|
|
4
|
+
hook, atomic + layout components, pluggable storage. Sits on top of
|
|
5
|
+
[`@valve-tech/wallet-adapter`](../wallet-adapter) (the lifecycle
|
|
6
|
+
vocabulary) and
|
|
7
|
+
[`@valve-tech/tx-tracker`](../tx-tracker) (the per-tx state machine);
|
|
8
|
+
both are **optional** peer deps so the package supports either or
|
|
9
|
+
both integration shapes without forcing a hard dependency.
|
|
10
|
+
|
|
11
|
+
Part of the
|
|
12
|
+
[`valve-tech/evm-toolkit`](https://github.com/valve-tech/evm-toolkit)
|
|
13
|
+
synchronized release line.
|
|
14
|
+
|
|
15
|
+
## Why
|
|
16
|
+
|
|
17
|
+
Every dapp ends up rebuilding the same "in-flight strip": a list of
|
|
18
|
+
recently-submitted txs that show pending → confirmed | failed |
|
|
19
|
+
dropped | replaced, with a hash link to the explorer, an age display,
|
|
20
|
+
and (sometimes) speed-up / cancel buttons. The pieces are simple
|
|
21
|
+
individually but stitching them together — Provider state, storage,
|
|
22
|
+
debounce, eviction, reorg handling, persisting across reload — is
|
|
23
|
+
several hundred lines of boilerplate per app.
|
|
24
|
+
|
|
25
|
+
This package ships those pieces as headless components and a single
|
|
26
|
+
hook. Bring your own styles, bring your own wallet, optionally bring
|
|
27
|
+
your own tracker. The strip handles the lifecycle wiring.
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
npm install @valve-tech/tx-flight-react viem
|
|
33
|
+
# Optional peers — install only the integration shape(s) you need:
|
|
34
|
+
npm install @valve-tech/wallet-adapter # for addWithWalletAdapter
|
|
35
|
+
npm install @valve-tech/tx-tracker @valve-tech/chain-source # for addByHash
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
React 18 or 19, viem ^2.
|
|
39
|
+
|
|
40
|
+
## 30-second quickstart
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import {
|
|
44
|
+
TxFlightProvider,
|
|
45
|
+
TxFlightList,
|
|
46
|
+
useTxFlight,
|
|
47
|
+
} from '@valve-tech/tx-flight-react'
|
|
48
|
+
|
|
49
|
+
// 1. Wrap your app
|
|
50
|
+
function App() {
|
|
51
|
+
return (
|
|
52
|
+
<TxFlightProvider>
|
|
53
|
+
<Header />
|
|
54
|
+
<TxFlightList /> {/* renders the strip */}
|
|
55
|
+
<YourApp />
|
|
56
|
+
</TxFlightProvider>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 2. Use the hook from anywhere inside the Provider tree
|
|
61
|
+
function SubmitButton() {
|
|
62
|
+
const flight = useTxFlight()
|
|
63
|
+
return (
|
|
64
|
+
<button onClick={() => {
|
|
65
|
+
flight.addManual({
|
|
66
|
+
tx: {
|
|
67
|
+
id: crypto.randomUUID(),
|
|
68
|
+
chainId: 1,
|
|
69
|
+
flow: 'send',
|
|
70
|
+
submittedAt: Date.now(),
|
|
71
|
+
submittedTier: 'standard',
|
|
72
|
+
status: 'pending',
|
|
73
|
+
},
|
|
74
|
+
})
|
|
75
|
+
}}>
|
|
76
|
+
Submit
|
|
77
|
+
</button>
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
That's a working strip with persistence to localStorage, eviction
|
|
83
|
+
after 60s of terminal lifetime, and a 50-item cap.
|
|
84
|
+
|
|
85
|
+
## Public surface
|
|
86
|
+
|
|
87
|
+
### Provider
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
<TxFlightProvider
|
|
91
|
+
id="default" // string — scopes state + storage key
|
|
92
|
+
storage={localStorageAdapter()} // TxFlightStorage | null — null disables persistence
|
|
93
|
+
maxItems={50} // cap on retained entries
|
|
94
|
+
terminalRetentionMs={60_000} // how long terminals linger
|
|
95
|
+
onError={(method, err) => ...} // surfaced for storage / watcher errors
|
|
96
|
+
clientFactory={(chainId) => client} // optional: enable rehydrate watcher revival
|
|
97
|
+
>
|
|
98
|
+
...
|
|
99
|
+
</TxFlightProvider>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Hook
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
const flight = useTxFlight() // ambient id
|
|
106
|
+
const flight = useTxFlight('settings-page') // explicit id
|
|
107
|
+
|
|
108
|
+
flight.txs // ReadonlyArray<TrackedTx>
|
|
109
|
+
flight.addWithWalletAdapter(input) // { id, hooks: WriteHookParams }
|
|
110
|
+
flight.addByHash(input) // Promise<string>
|
|
111
|
+
flight.addManual(input) // string
|
|
112
|
+
flight.remove(id) // void
|
|
113
|
+
flight.clear() // void
|
|
114
|
+
flight.get(id) // TrackedTx | null
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Throws if no `<TxFlightProvider>` for the resolved id is in the tree.
|
|
118
|
+
|
|
119
|
+
### Components
|
|
120
|
+
|
|
121
|
+
| Component | RSC-safe | Purpose |
|
|
122
|
+
|---|---|---|
|
|
123
|
+
| `<TxFlightList>` | no (uses hook) | Reactive list. Defaults to newest-first by `submittedAt`, optional `filter` / `sort` / `render` / `empty` props. |
|
|
124
|
+
| `<TxFlightItem>` | yes | Default per-tx layout (icon + hash + age + actions). `render` prop swaps the layout while keeping the four atomic children. |
|
|
125
|
+
| `<TxFlightStatusIcon>` | yes | Colored dot per status. `size` (default 16). |
|
|
126
|
+
| `<TxFlightHashLink>` | yes | `<a>` to explorer (or plain `<span>` fallback when no `explorer` is supplied). Truncation modes: `'middle'` \| `'end'` \| `'none'`. |
|
|
127
|
+
| `<TxFlightAge>` | no (uses `useEffect`) | Periodic relative-time display. `format` swaps the wording. |
|
|
128
|
+
| `<TxFlightActions>` | yes | Speed-up / cancel / dismiss button slots. Renders nothing when no callbacks are wired. |
|
|
129
|
+
|
|
130
|
+
Every component accepts `className` and `style`.
|
|
131
|
+
|
|
132
|
+
### Storage adapters
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
import {
|
|
136
|
+
localStorageAdapter,
|
|
137
|
+
indexedDBAdapter,
|
|
138
|
+
memoryAdapter,
|
|
139
|
+
} from '@valve-tech/tx-flight-react/storage'
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
| Adapter | When to use |
|
|
143
|
+
|---|---|
|
|
144
|
+
| `localStorageAdapter({ keyPrefix? })` | Default. Sync API; SSR-safe (no-op when `window` is undefined). |
|
|
145
|
+
| `indexedDBAdapter({ dbName?, storeName? })` | Larger payloads, async. |
|
|
146
|
+
| `memoryAdapter()` | Tests, or "explicit no persistence". |
|
|
147
|
+
|
|
148
|
+
A consumer-built adapter just satisfies the two-method `TxFlightStorage`
|
|
149
|
+
interface (`load(id) → Promise<TrackedTx[] | null>`,
|
|
150
|
+
`save(id, txs) → Promise<void>`).
|
|
151
|
+
|
|
152
|
+
## Three add shapes
|
|
153
|
+
|
|
154
|
+
The strip's lifecycle starts when you call one of three add methods.
|
|
155
|
+
Each has its own input type and return; there is no overloaded
|
|
156
|
+
discriminated `via:` field.
|
|
157
|
+
|
|
158
|
+
### `addWithWalletAdapter` — when you're using `@valve-tech/wallet-adapter`
|
|
159
|
+
|
|
160
|
+
```tsx
|
|
161
|
+
import { sendTransactionWithHooks } from '@valve-tech/wallet-adapter'
|
|
162
|
+
|
|
163
|
+
const flight = useTxFlight()
|
|
164
|
+
|
|
165
|
+
const userHooks = {
|
|
166
|
+
onConfirmed: (info) => myToast(`tx ${info.hash} confirmed`),
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const { id, hooks } = flight.addWithWalletAdapter({
|
|
170
|
+
hooks: userHooks,
|
|
171
|
+
flow: 'mint',
|
|
172
|
+
chainId: 1,
|
|
173
|
+
request: { to: contract, data, value: 0n, chainId: 1 },
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
// Pipe the wrapped hooks straight into wallet-adapter's helper.
|
|
177
|
+
// Each phase fires BOTH your original callback AND a store update.
|
|
178
|
+
await sendTransactionWithHooks({ wallet, request, hooks })
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Sync. Wallet-adapter is statically imported (only types — no runtime
|
|
182
|
+
bundle cost).
|
|
183
|
+
|
|
184
|
+
### `addByHash` — when you have a hash and a viem `PublicClient`
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
const id = await flight.addByHash({
|
|
188
|
+
hash: '0xabc...',
|
|
189
|
+
chainId: 1,
|
|
190
|
+
client: publicClient,
|
|
191
|
+
flow: 'claim',
|
|
192
|
+
withReceipts: true, // opt into reverted-receipt detection
|
|
193
|
+
confirmations: 3,
|
|
194
|
+
})
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Async — `@valve-tech/tx-tracker` and `@valve-tech/chain-source` are
|
|
198
|
+
**dynamic-imported** so wallet-adapter-only consumers don't pay the
|
|
199
|
+
bundle cost. The strip builds a private ChainSource + TxTracker
|
|
200
|
+
internally; `flight.remove(id)` (or unmount) cleans up the
|
|
201
|
+
subscription.
|
|
202
|
+
|
|
203
|
+
### `addManual` — when you already have a fully-formed `TrackedTx`
|
|
204
|
+
|
|
205
|
+
```tsx
|
|
206
|
+
const id = flight.addManual({
|
|
207
|
+
tx: {
|
|
208
|
+
id: crypto.randomUUID(),
|
|
209
|
+
hash: '0xabc...',
|
|
210
|
+
chainId: 1,
|
|
211
|
+
flow: 'observed-elsewhere',
|
|
212
|
+
submittedAt: Date.now(),
|
|
213
|
+
submittedTier: 'standard',
|
|
214
|
+
status: 'pending',
|
|
215
|
+
},
|
|
216
|
+
})
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Sync. Useful for back-fill (server push, observed-elsewhere txs). The
|
|
220
|
+
strip stores the entry verbatim; subsequent updates are the consumer's
|
|
221
|
+
responsibility (call `addManual` again with the same `tx.id` to
|
|
222
|
+
overwrite, or `flight.remove(id)` to drop).
|
|
223
|
+
|
|
224
|
+
## Persistence + rehydrate
|
|
225
|
+
|
|
226
|
+
By default state persists to `localStorage` under the key
|
|
227
|
+
`tx-flight:${id}`, debounced ~250ms. On Provider mount, persisted
|
|
228
|
+
entries are seeded back into state.
|
|
229
|
+
|
|
230
|
+
Rehydrate semantics:
|
|
231
|
+
- `pending` with `hash` set, **and** `clientFactory` is wired: a fresh
|
|
232
|
+
tx-tracker watcher is async-attached so the entry continues
|
|
233
|
+
advancing toward terminal.
|
|
234
|
+
- `pending` without `clientFactory`: stays `pending` until you
|
|
235
|
+
manually re-issue `addByHash`.
|
|
236
|
+
- `preparing` / `awaiting-signature`: translated to `failed` with
|
|
237
|
+
`notes: 'lost during reload'` — wallet interactions cannot resume
|
|
238
|
+
across reloads.
|
|
239
|
+
- Terminal entries (`confirmed` / `failed` / `dropped` / `replaced`):
|
|
240
|
+
preserved verbatim until the eviction interval prunes them past
|
|
241
|
+
`terminalRetentionMs`.
|
|
242
|
+
|
|
243
|
+
Set `clientFactory` if you want pending entries to keep advancing
|
|
244
|
+
after a reload:
|
|
245
|
+
|
|
246
|
+
```tsx
|
|
247
|
+
<TxFlightProvider
|
|
248
|
+
clientFactory={(chainId) => myPublicClients[chainId]}
|
|
249
|
+
>
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Multi-instance
|
|
253
|
+
|
|
254
|
+
Two providers with the same `id` share one underlying store via
|
|
255
|
+
refCount; useful for nested layouts where the same logical strip is
|
|
256
|
+
mounted in more than one place. Different `id`s are fully independent
|
|
257
|
+
(different in-memory state, different storage key).
|
|
258
|
+
|
|
259
|
+
```tsx
|
|
260
|
+
<TxFlightProvider id="main">
|
|
261
|
+
<Layout>
|
|
262
|
+
<TxFlightProvider id="settings-page">
|
|
263
|
+
...
|
|
264
|
+
</TxFlightProvider>
|
|
265
|
+
</Layout>
|
|
266
|
+
</TxFlightProvider>
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## SSR / RSC
|
|
270
|
+
|
|
271
|
+
The Provider is a `'use client'` component. Atomic components without
|
|
272
|
+
hooks (`StatusIcon`, `HashLink`, `Actions`, `Item`) are RSC-safe.
|
|
273
|
+
`<TxFlightAge>` and `<TxFlightList>` use hooks (`useEffect`,
|
|
274
|
+
`useTxFlight`) and are client-only.
|
|
275
|
+
|
|
276
|
+
`localStorageAdapter` no-ops on the server (`typeof window ===
|
|
277
|
+
'undefined'`). The Provider's heavyweight side effects (eviction
|
|
278
|
+
interval, storage IO, watcher subscriptions) live inside `useEffect`
|
|
279
|
+
and never run during `renderToString`.
|
|
280
|
+
|
|
281
|
+
## License
|
|
282
|
+
|
|
283
|
+
MIT
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `<TxFlightActions>` — button slots for speed-up,
|
|
3
|
+
* cancel, and dismiss. Renders nothing when no callbacks are wired
|
|
4
|
+
* (forces consumers to opt in; no orphan buttons).
|
|
5
|
+
*
|
|
6
|
+
* The actual `replaceTransaction` plumbing is the consumer's
|
|
7
|
+
* responsibility (different wallets, different gas-recommendation
|
|
8
|
+
* strategies). This component just exposes click handlers carrying
|
|
9
|
+
* the relevant `tx`.
|
|
10
|
+
*/
|
|
11
|
+
import type { CSSProperties, ReactNode } from 'react';
|
|
12
|
+
import type { TrackedTx } from '@valve-tech/wallet-adapter';
|
|
13
|
+
export interface TxFlightActionsShow {
|
|
14
|
+
speedUp?: boolean;
|
|
15
|
+
cancel?: boolean;
|
|
16
|
+
dismiss?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface TxFlightActionsProps {
|
|
19
|
+
tx: TrackedTx;
|
|
20
|
+
onSpeedUp?: (tx: TrackedTx) => void;
|
|
21
|
+
onCancel?: (tx: TrackedTx) => void;
|
|
22
|
+
onDismiss?: (tx: TrackedTx) => void;
|
|
23
|
+
/**
|
|
24
|
+
* Per-button visibility override. Default: each button is shown iff
|
|
25
|
+
* the matching callback is supplied.
|
|
26
|
+
*/
|
|
27
|
+
show?: TxFlightActionsShow;
|
|
28
|
+
className?: string;
|
|
29
|
+
style?: CSSProperties;
|
|
30
|
+
}
|
|
31
|
+
export declare const TxFlightActions: ({ tx, onSpeedUp, onCancel, onDismiss, show, className, style, }: TxFlightActionsProps) => ReactNode;
|
|
32
|
+
//# sourceMappingURL=actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/components/actions.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAErD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AAE3D,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,SAAS,CAAA;IACb,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,CAAA;IAClC,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC;;;OAGG;IACH,IAAI,CAAC,EAAE,mBAAmB,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,aAAa,CAAA;CACtB;AAED,eAAO,MAAM,eAAe,oEAQzB,oBAAoB,KAAG,SAsCzB,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export const TxFlightActions = ({ tx, onSpeedUp, onCancel, onDismiss, show, className, style, }) => {
|
|
3
|
+
const showSpeedUp = (show?.speedUp ?? true) && onSpeedUp !== undefined;
|
|
4
|
+
const showCancel = (show?.cancel ?? true) && onCancel !== undefined;
|
|
5
|
+
const showDismiss = (show?.dismiss ?? true) && onDismiss !== undefined;
|
|
6
|
+
if (!showSpeedUp && !showCancel && !showDismiss)
|
|
7
|
+
return null;
|
|
8
|
+
return (_jsxs("div", { className: className, style: style, "data-tx-id": tx.id, children: [showSpeedUp && (_jsx("button", { type: "button", "data-action": "speed-up", onClick: () => onSpeedUp?.(tx), children: "Speed up" })), showCancel && (_jsx("button", { type: "button", "data-action": "cancel", onClick: () => onCancel?.(tx), children: "Cancel" })), showDismiss && (_jsx("button", { type: "button", "data-action": "dismiss", onClick: () => onDismiss?.(tx), children: "Dismiss" }))] }));
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/components/actions.tsx"],"names":[],"mappings":";AAmCA,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,EAC9B,EAAE,EACF,SAAS,EACT,QAAQ,EACR,SAAS,EACT,IAAI,EACJ,SAAS,EACT,KAAK,GACgB,EAAa,EAAE;IACpC,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,OAAO,IAAI,IAAI,CAAC,IAAI,SAAS,KAAK,SAAS,CAAA;IACtE,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,IAAI,IAAI,CAAC,IAAI,QAAQ,KAAK,SAAS,CAAA;IACnE,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,OAAO,IAAI,IAAI,CAAC,IAAI,SAAS,KAAK,SAAS,CAAA;IAEtE,IAAI,CAAC,WAAW,IAAI,CAAC,UAAU,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAA;IAE5D,OAAO,CACL,eAAK,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,gBAAc,EAAE,CAAC,EAAE,aACvD,WAAW,IAAI,CACd,iBACE,IAAI,EAAC,QAAQ,iBACD,UAAU,EACtB,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,yBAGvB,CACV,EACA,UAAU,IAAI,CACb,iBACE,IAAI,EAAC,QAAQ,iBACD,QAAQ,EACpB,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,uBAGtB,CACV,EACA,WAAW,IAAI,CACd,iBACE,IAAI,EAAC,QAAQ,iBACD,SAAS,EACrB,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,wBAGvB,CACV,IACG,CACP,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `<TxFlightAge>` — relative-time display that
|
|
3
|
+
* auto-refreshes on a periodic tick.
|
|
4
|
+
*
|
|
5
|
+
* Client-only because of the `useEffect` interval. The default format
|
|
6
|
+
* yields English copy: 'just now', '12s ago', '3m ago', '4h ago'.
|
|
7
|
+
* Consumer-supplied `format` swaps in any locale / wording.
|
|
8
|
+
*/
|
|
9
|
+
import { type CSSProperties, type ReactNode } from 'react';
|
|
10
|
+
export interface TxFlightAgeProps {
|
|
11
|
+
/** Submission time (ms since epoch). */
|
|
12
|
+
submittedAt: number;
|
|
13
|
+
/** How often to re-render. Default: 1000ms. */
|
|
14
|
+
refreshIntervalMs?: number;
|
|
15
|
+
/** Custom relative-time formatter. Default: English. */
|
|
16
|
+
format?: (deltaMs: number) => string;
|
|
17
|
+
className?: string;
|
|
18
|
+
style?: CSSProperties;
|
|
19
|
+
}
|
|
20
|
+
export declare const TxFlightAge: ({ submittedAt, refreshIntervalMs, format, className, style, }: TxFlightAgeProps) => ReactNode;
|
|
21
|
+
//# sourceMappingURL=age.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"age.d.ts","sourceRoot":"","sources":["../../src/components/age.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,EAAuB,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAS/E,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAA;IACnB,+CAA+C;IAC/C,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,wDAAwD;IACxD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAA;IACpC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,aAAa,CAAA;CACtB;AAED,eAAO,MAAM,WAAW,kEAMrB,gBAAgB,KAAG,SAWrB,CAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview `<TxFlightAge>` — relative-time display that
|
|
5
|
+
* auto-refreshes on a periodic tick.
|
|
6
|
+
*
|
|
7
|
+
* Client-only because of the `useEffect` interval. The default format
|
|
8
|
+
* yields English copy: 'just now', '12s ago', '3m ago', '4h ago'.
|
|
9
|
+
* Consumer-supplied `format` swaps in any locale / wording.
|
|
10
|
+
*/
|
|
11
|
+
import { useEffect, useState } from 'react';
|
|
12
|
+
const defaultFormat = (deltaMs) => {
|
|
13
|
+
if (deltaMs < 5000)
|
|
14
|
+
return 'just now';
|
|
15
|
+
if (deltaMs < 60000)
|
|
16
|
+
return `${Math.floor(deltaMs / 1000)}s ago`;
|
|
17
|
+
if (deltaMs < 3600000)
|
|
18
|
+
return `${Math.floor(deltaMs / 60000)}m ago`;
|
|
19
|
+
return `${Math.floor(deltaMs / 3600000)}h ago`;
|
|
20
|
+
};
|
|
21
|
+
export const TxFlightAge = ({ submittedAt, refreshIntervalMs = 1000, format = defaultFormat, className, style, }) => {
|
|
22
|
+
const [now, setNow] = useState(() => Date.now());
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const t = setInterval(() => setNow(Date.now()), refreshIntervalMs);
|
|
25
|
+
return () => clearInterval(t);
|
|
26
|
+
}, [refreshIntervalMs]);
|
|
27
|
+
return (_jsx("span", { className: className, style: style, children: format(now - submittedAt) }));
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=age.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"age.js","sourceRoot":"","sources":["../../src/components/age.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAsC,MAAM,OAAO,CAAA;AAE/E,MAAM,aAAa,GAAG,CAAC,OAAe,EAAU,EAAE;IAChD,IAAI,OAAO,GAAG,IAAK;QAAE,OAAO,UAAU,CAAA;IACtC,IAAI,OAAO,GAAG,KAAM;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;IACjE,IAAI,OAAO,GAAG,OAAS;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,KAAM,CAAC,OAAO,CAAA;IACtE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,OAAS,CAAC,OAAO,CAAA;AAClD,CAAC,CAAA;AAaD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,EAC1B,WAAW,EACX,iBAAiB,GAAG,IAAI,EACxB,MAAM,GAAG,aAAa,EACtB,SAAS,EACT,KAAK,GACY,EAAa,EAAE;IAChC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;IAChD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,CAAC,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,iBAAiB,CAAC,CAAA;QAClE,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAA;IAC/B,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAA;IACvB,OAAO,CACL,eAAM,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,YACrC,MAAM,CAAC,GAAG,GAAG,WAAW,CAAC,GACrB,CACR,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `<TxFlightHashLink>` — renders a tx hash with optional
|
|
3
|
+
* explorer URL. RSC-safe (no hooks, no `'use client'`).
|
|
4
|
+
*
|
|
5
|
+
* If `explorer` is supplied, returns an `<a>` to the URL it builds; if
|
|
6
|
+
* not, returns a plain `<span>`. When `tx.hash` is undefined (preparing
|
|
7
|
+
* / awaiting-signature), renders an em-dash placeholder.
|
|
8
|
+
*/
|
|
9
|
+
import type { CSSProperties, ReactNode } from 'react';
|
|
10
|
+
import type { TrackedTx } from '@valve-tech/wallet-adapter';
|
|
11
|
+
export type HashTruncate = 'middle' | 'end' | 'none';
|
|
12
|
+
export interface TxFlightHashLinkProps {
|
|
13
|
+
tx: TrackedTx;
|
|
14
|
+
/**
|
|
15
|
+
* URL builder. When omitted, the hash renders as plain text (no
|
|
16
|
+
* anchor) — silent graceful degradation. Provider-level default
|
|
17
|
+
* lives at a separate `defaultExplorer` prop (see spec §4.2).
|
|
18
|
+
*/
|
|
19
|
+
explorer?: (tx: TrackedTx) => string;
|
|
20
|
+
/** Truncation style for the displayed hash. Default: 'middle'. */
|
|
21
|
+
truncate?: HashTruncate;
|
|
22
|
+
className?: string;
|
|
23
|
+
style?: CSSProperties;
|
|
24
|
+
}
|
|
25
|
+
export declare const TxFlightHashLink: ({ tx, explorer, truncate, className, style, }: TxFlightHashLinkProps) => ReactNode;
|
|
26
|
+
//# sourceMappingURL=hash-link.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash-link.d.ts","sourceRoot":"","sources":["../../src/components/hash-link.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAErD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AAE3D,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAA;AAEpD,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,SAAS,CAAA;IACb;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,MAAM,CAAA;IACpC,kEAAkE;IAClE,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,aAAa,CAAA;CACtB;AAQD,eAAO,MAAM,gBAAgB,kDAM1B,qBAAqB,KAAG,SA6B1B,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
const truncateHash = (hash, mode) => {
|
|
3
|
+
if (mode === 'none')
|
|
4
|
+
return hash;
|
|
5
|
+
if (mode === 'end')
|
|
6
|
+
return `${hash.slice(0, 10)}…`;
|
|
7
|
+
return `${hash.slice(0, 6)}…${hash.slice(-4)}`;
|
|
8
|
+
};
|
|
9
|
+
export const TxFlightHashLink = ({ tx, explorer, truncate = 'middle', className, style, }) => {
|
|
10
|
+
if (tx.hash === undefined) {
|
|
11
|
+
return (_jsx("span", { className: className, style: style, "data-tx-hash": "", children: "\u2014" }));
|
|
12
|
+
}
|
|
13
|
+
const display = truncateHash(tx.hash, truncate);
|
|
14
|
+
const url = explorer?.(tx);
|
|
15
|
+
if (url === undefined) {
|
|
16
|
+
return (_jsx("span", { className: className, style: style, "data-tx-hash": tx.hash, children: display }));
|
|
17
|
+
}
|
|
18
|
+
return (_jsx("a", { href: url, target: "_blank", rel: "noopener noreferrer", className: className, style: style, "data-tx-hash": tx.hash, children: display }));
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=hash-link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash-link.js","sourceRoot":"","sources":["../../src/components/hash-link.tsx"],"names":[],"mappings":";AA6BA,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,IAAkB,EAAU,EAAE;IAChE,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,IAAI,CAAA;IAChC,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAA;IAClD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AAChD,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAC/B,EAAE,EACF,QAAQ,EACR,QAAQ,GAAG,QAAQ,EACnB,SAAS,EACT,KAAK,GACiB,EAAa,EAAE;IACrC,IAAI,EAAE,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,CACL,eAAM,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,kBAAe,EAAE,uBAElD,CACR,CAAA;IACH,CAAC;IACD,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;IAC/C,MAAM,GAAG,GAAG,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAA;IAC1B,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,CACL,eAAM,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,kBAAgB,EAAE,CAAC,IAAI,YAC5D,OAAO,GACH,CACR,CAAA;IACH,CAAC;IACD,OAAO,CACL,YACE,IAAI,EAAE,GAAG,EACT,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,qBAAqB,EACzB,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,KAAK,kBACE,EAAE,CAAC,IAAI,YAEpB,OAAO,GACN,CACL,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `<TxFlightItem>` — default per-tx layout. Composes the
|
|
3
|
+
* atomic primitives (StatusIcon, HashLink, Age, Actions). The `render`
|
|
4
|
+
* prop replaces the default layout entirely while still receiving the
|
|
5
|
+
* pre-built atomic ReactNodes; consumers can rearrange or wrap them.
|
|
6
|
+
*/
|
|
7
|
+
import type { CSSProperties, ReactNode } from 'react';
|
|
8
|
+
import type { TrackedTx } from '@valve-tech/wallet-adapter';
|
|
9
|
+
export interface TxFlightItemRenderParts {
|
|
10
|
+
icon: ReactNode;
|
|
11
|
+
hash: ReactNode;
|
|
12
|
+
age: ReactNode;
|
|
13
|
+
actions: ReactNode;
|
|
14
|
+
}
|
|
15
|
+
export interface TxFlightItemProps {
|
|
16
|
+
tx: TrackedTx;
|
|
17
|
+
/**
|
|
18
|
+
* Replace the default layout. Receives the four atomic primitives
|
|
19
|
+
* pre-built — the consumer rearranges them or wraps them in their
|
|
20
|
+
* own markup.
|
|
21
|
+
*/
|
|
22
|
+
render?: (parts: TxFlightItemRenderParts) => ReactNode;
|
|
23
|
+
className?: string;
|
|
24
|
+
style?: CSSProperties;
|
|
25
|
+
}
|
|
26
|
+
export declare const TxFlightItem: ({ tx, render, className, style, }: TxFlightItemProps) => ReactNode;
|
|
27
|
+
//# sourceMappingURL=item.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"item.d.ts","sourceRoot":"","sources":["../../src/components/item.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAErD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AAO3D,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,SAAS,CAAA;IACf,IAAI,EAAE,SAAS,CAAA;IACf,GAAG,EAAE,SAAS,CAAA;IACd,OAAO,EAAE,SAAS,CAAA;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,SAAS,CAAA;IACb;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,SAAS,CAAA;IACtD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,aAAa,CAAA;CACtB;AAED,eAAO,MAAM,YAAY,sCAKtB,iBAAiB,KAAG,SAsBtB,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { TxFlightActions } from './actions.js';
|
|
3
|
+
import { TxFlightAge } from './age.js';
|
|
4
|
+
import { TxFlightHashLink } from './hash-link.js';
|
|
5
|
+
import { TxFlightStatusIcon } from './status-icon.js';
|
|
6
|
+
export const TxFlightItem = ({ tx, render, className, style, }) => {
|
|
7
|
+
const parts = {
|
|
8
|
+
icon: _jsx(TxFlightStatusIcon, { status: tx.status }),
|
|
9
|
+
hash: _jsx(TxFlightHashLink, { tx: tx }),
|
|
10
|
+
age: _jsx(TxFlightAge, { submittedAt: tx.submittedAt }),
|
|
11
|
+
actions: _jsx(TxFlightActions, { tx: tx }),
|
|
12
|
+
};
|
|
13
|
+
if (render) {
|
|
14
|
+
return (_jsx("div", { className: className, style: style, "data-tx-id": tx.id, "data-status": tx.status, children: render(parts) }));
|
|
15
|
+
}
|
|
16
|
+
return (_jsxs("div", { className: className, style: style, "data-tx-id": tx.id, "data-status": tx.status, children: [parts.icon, parts.hash, parts.age, parts.actions] }));
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=item.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"item.js","sourceRoot":"","sources":["../../src/components/item.tsx"],"names":[],"mappings":";AAWA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAqBrD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAC3B,EAAE,EACF,MAAM,EACN,SAAS,EACT,KAAK,GACa,EAAa,EAAE;IACjC,MAAM,KAAK,GAA4B;QACrC,IAAI,EAAE,KAAC,kBAAkB,IAAC,MAAM,EAAE,EAAE,CAAC,MAAM,GAAI;QAC/C,IAAI,EAAE,KAAC,gBAAgB,IAAC,EAAE,EAAE,EAAE,GAAI;QAClC,GAAG,EAAE,KAAC,WAAW,IAAC,WAAW,EAAE,EAAE,CAAC,WAAW,GAAI;QACjD,OAAO,EAAE,KAAC,eAAe,IAAC,EAAE,EAAE,EAAE,GAAI;KACrC,CAAA;IACD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CACL,cAAK,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,gBAAc,EAAE,CAAC,EAAE,iBAAe,EAAE,CAAC,MAAM,YAC/E,MAAM,CAAC,KAAK,CAAC,GACV,CACP,CAAA;IACH,CAAC;IACD,OAAO,CACL,eAAK,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,gBAAc,EAAE,CAAC,EAAE,iBAAe,EAAE,CAAC,MAAM,aAC/E,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,GAAG,EACT,KAAK,CAAC,OAAO,IACV,CACP,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `<TxFlightList>` — reactive list of tracked txs.
|
|
3
|
+
* Reads the strip's state via `useTxFlight(id)` (so client-only).
|
|
4
|
+
*
|
|
5
|
+
* Defaults to newest-first by `submittedAt`, no filter, default
|
|
6
|
+
* per-tx layout via `<TxFlightItem>`. Every prop is opt-in
|
|
7
|
+
* customization; bare `<TxFlightList />` is enough for a working
|
|
8
|
+
* strip in the ambient Provider.
|
|
9
|
+
*/
|
|
10
|
+
import type { CSSProperties, ReactNode } from 'react';
|
|
11
|
+
import type { TrackedTx } from '@valve-tech/wallet-adapter';
|
|
12
|
+
export interface TxFlightListProps {
|
|
13
|
+
/** Provider id to read from. Defaults to the ambient context's id. */
|
|
14
|
+
id?: string;
|
|
15
|
+
/** Filter predicate. Default: include all. */
|
|
16
|
+
filter?: (tx: TrackedTx) => boolean;
|
|
17
|
+
/** Sort comparator. Default: newest-first by `submittedAt`. */
|
|
18
|
+
sort?: (a: TrackedTx, b: TrackedTx) => number;
|
|
19
|
+
/** Per-tx renderer. Default: `<TxFlightItem tx={tx} />`. */
|
|
20
|
+
render?: (tx: TrackedTx) => ReactNode;
|
|
21
|
+
/** Shown when the visible set is empty. */
|
|
22
|
+
empty?: ReactNode;
|
|
23
|
+
className?: string;
|
|
24
|
+
style?: CSSProperties;
|
|
25
|
+
}
|
|
26
|
+
export declare const TxFlightList: ({ id, filter, sort, render, empty, className, style, }: TxFlightListProps) => ReactNode;
|
|
27
|
+
//# sourceMappingURL=list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/components/list.tsx"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAErD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AAK3D,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,8CAA8C;IAC9C,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,OAAO,CAAA;IACnC,+DAA+D;IAC/D,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,KAAK,MAAM,CAAA;IAC7C,4DAA4D;IAC5D,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,SAAS,CAAA;IACrC,2CAA2C;IAC3C,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,aAAa,CAAA;CACtB;AASD,eAAO,MAAM,YAAY,2DAQtB,iBAAiB,KAAG,SAStB,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useTxFlight } from '../use-tx-flight.js';
|
|
4
|
+
import { TxFlightItem } from './item.js';
|
|
5
|
+
const defaultSort = (a, b) => b.submittedAt - a.submittedAt;
|
|
6
|
+
const defaultRender = (tx) => (_jsx(TxFlightItem, { tx: tx }, tx.id));
|
|
7
|
+
export const TxFlightList = ({ id, filter, sort = defaultSort, render = defaultRender, empty, className, style, }) => {
|
|
8
|
+
const { txs } = useTxFlight(id);
|
|
9
|
+
const visible = (filter ? txs.filter(filter) : [...txs]).sort(sort);
|
|
10
|
+
if (visible.length === 0)
|
|
11
|
+
return empty !== undefined ? _jsx(_Fragment, { children: empty }) : null;
|
|
12
|
+
return (_jsx("div", { className: className, style: style, "data-tx-flight-list": "", children: visible.map(render) }));
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/components/list.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAgBZ,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAiBxC,MAAM,WAAW,GAAG,CAAC,CAAY,EAAE,CAAY,EAAU,EAAE,CACzD,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAA;AAE/B,MAAM,aAAa,GAAG,CAAC,EAAa,EAAa,EAAE,CAAC,CAClD,KAAC,YAAY,IAAa,EAAE,EAAE,EAAE,IAAb,EAAE,CAAC,EAAE,CAAY,CACrC,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAC3B,EAAE,EACF,MAAM,EACN,IAAI,GAAG,WAAW,EAClB,MAAM,GAAG,aAAa,EACtB,KAAK,EACL,SAAS,EACT,KAAK,GACa,EAAa,EAAE;IACjC,MAAM,EAAE,GAAG,EAAE,GAAG,WAAW,CAAC,EAAE,CAAC,CAAA;IAC/B,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACnE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,4BAAG,KAAK,GAAI,CAAC,CAAC,CAAC,IAAI,CAAA;IAC1E,OAAO,CACL,cAAK,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,yBAAsB,EAAE,YAC5D,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAChB,CACP,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `<TxFlightStatusIcon>` — single-glyph indicator for a
|
|
3
|
+
* tracked tx's status. RSC-safe (no hooks, no `'use client'`).
|
|
4
|
+
*
|
|
5
|
+
* Visual: a colored dot, sized via the `size` prop. Consumer styles
|
|
6
|
+
* any further treatment via `className` / `style`. Defaults provide
|
|
7
|
+
* a sensible, opinionated look so the bare component looks intentional
|
|
8
|
+
* out of the box without consumer CSS.
|
|
9
|
+
*/
|
|
10
|
+
import type { CSSProperties, ReactNode } from 'react';
|
|
11
|
+
import type { TrackedTxStatus } from '@valve-tech/wallet-adapter';
|
|
12
|
+
export interface TxFlightStatusIconProps {
|
|
13
|
+
status: TrackedTxStatus;
|
|
14
|
+
/** Pixel size of the dot. Default: 16. */
|
|
15
|
+
size?: number;
|
|
16
|
+
className?: string;
|
|
17
|
+
style?: CSSProperties;
|
|
18
|
+
}
|
|
19
|
+
export declare const TxFlightStatusIcon: ({ status, size, className, style, }: TxFlightStatusIconProps) => ReactNode;
|
|
20
|
+
//# sourceMappingURL=status-icon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-icon.d.ts","sourceRoot":"","sources":["../../src/components/status-icon.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAErD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAsBjE,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,eAAe,CAAA;IACvB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,aAAa,CAAA;CACtB;AAED,eAAO,MAAM,kBAAkB,wCAK5B,uBAAuB,KAAG,SAe5B,CAAA"}
|