@1sat/sweep-ui 0.0.75 → 0.0.78
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/dist/components/SweepApp.d.ts.map +1 -1
- package/dist/components/asset-preview.d.ts +3 -2
- package/dist/components/asset-preview.d.ts.map +1 -1
- package/dist/components/opns-section.d.ts +3 -2
- package/dist/components/opns-section.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +252 -93
- package/dist/lib/sweeper.d.ts +5 -0
- package/dist/lib/sweeper.d.ts.map +1 -1
- package/package.json +52 -52
- package/src/components/SweepApp.tsx +101 -40
- package/src/components/asset-preview.tsx +82 -59
- package/src/components/opns-section.tsx +105 -50
- package/src/index.ts +5 -1
- package/src/lib/sweeper.ts +47 -13
package/package.json
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
2
|
+
"name": "@1sat/sweep-ui",
|
|
3
|
+
"version": "0.0.78",
|
|
4
|
+
"description": "Sweep UI components for migrating legacy BSV assets",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./src/index.ts",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./src/index.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"src"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "bun run build.ts && tsc --emitDeclarationOnly",
|
|
20
|
+
"dev": "tsc --watch"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"1sat",
|
|
24
|
+
"bsv",
|
|
25
|
+
"ordinals",
|
|
26
|
+
"sweep",
|
|
27
|
+
"migration",
|
|
28
|
+
"react"
|
|
29
|
+
],
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@1sat/actions": "0.0.191",
|
|
33
|
+
"@1sat/client": "0.0.46",
|
|
34
|
+
"@1sat/connect": "0.0.82",
|
|
35
|
+
"@1sat/types": "0.0.37",
|
|
36
|
+
"@1sat/utils": "0.0.30",
|
|
37
|
+
"bitcoin-backup": "^0.0.11",
|
|
38
|
+
"class-variance-authority": "^0.7.1",
|
|
39
|
+
"clsx": "^2.1.1",
|
|
40
|
+
"lucide-react": "^0.577.0",
|
|
41
|
+
"sonner": "^2.0.7",
|
|
42
|
+
"tailwind-merge": "^3.5.0"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@bsv/sdk": "^2.1.9",
|
|
46
|
+
"react": "^18.0.0 || ^19.0.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@bsv/sdk": "^2.1.9",
|
|
50
|
+
"@types/react": "^19.0.0",
|
|
51
|
+
"react": "^19.0.0",
|
|
52
|
+
"typescript": "~5.7.0"
|
|
53
|
+
}
|
|
54
54
|
}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
legacySendOrdinals,
|
|
8
8
|
} from '../lib/legacy-send'
|
|
9
9
|
import {
|
|
10
|
+
type EnrichedOrdinal,
|
|
10
11
|
type ScannedAssets,
|
|
11
12
|
deriveAddress,
|
|
12
13
|
scanAddresses,
|
|
@@ -122,10 +123,9 @@ export function SweepApp({
|
|
|
122
123
|
return next
|
|
123
124
|
})
|
|
124
125
|
}, [])
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}, [assets])
|
|
126
|
+
const handleSelectOrdinalPage = useCallback((outpoints: string[]) => {
|
|
127
|
+
setSelectedOrdinals(new Set(outpoints))
|
|
128
|
+
}, [])
|
|
129
129
|
const handleDeselectAllOrdinals = useCallback(
|
|
130
130
|
() => setSelectedOrdinals(new Set()),
|
|
131
131
|
[],
|
|
@@ -139,10 +139,9 @@ export function SweepApp({
|
|
|
139
139
|
return next
|
|
140
140
|
})
|
|
141
141
|
}, [])
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}, [assets])
|
|
142
|
+
const handleSelectOpnsPage = useCallback((outpoints: string[]) => {
|
|
143
|
+
setSelectedOpns(new Set(outpoints))
|
|
144
|
+
}, [])
|
|
146
145
|
const handleDeselectAllOpns = useCallback(
|
|
147
146
|
() => setSelectedOpns(new Set()),
|
|
148
147
|
[],
|
|
@@ -287,28 +286,58 @@ export function SweepApp({
|
|
|
287
286
|
[legacyKeys, assets, sweepAmount, getSelectedFunding, runOperation],
|
|
288
287
|
)
|
|
289
288
|
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
)
|
|
296
|
-
if (selected.length === 0) return
|
|
297
|
-
await runOperation(
|
|
298
|
-
`Sweep ${selected.length} ordinal${selected.length !== 1 ? 's' : ''}`,
|
|
299
|
-
async () => {
|
|
289
|
+
const sweepOrdinalList = useCallback(
|
|
290
|
+
async (list: EnrichedOrdinal[], label: string) => {
|
|
291
|
+
const wallet = resolveWallet()
|
|
292
|
+
if (!wallet || !legacyKeys || list.length === 0) return
|
|
293
|
+
await runOperation(label, async () => {
|
|
300
294
|
const result = await executeSweep({
|
|
301
295
|
wallet,
|
|
302
296
|
keys: keyMap,
|
|
303
297
|
funding: [],
|
|
304
|
-
ordinals:
|
|
298
|
+
ordinals: list,
|
|
305
299
|
onProgress: setSweepProgress,
|
|
306
300
|
})
|
|
307
|
-
if (result.
|
|
308
|
-
|
|
309
|
-
|
|
301
|
+
if (result.sweptOutpoints.length > 0) {
|
|
302
|
+
setSelectedOrdinals((prev) => {
|
|
303
|
+
const next = new Set(prev)
|
|
304
|
+
for (const op of result.sweptOutpoints) next.delete(op)
|
|
305
|
+
return next
|
|
306
|
+
})
|
|
307
|
+
}
|
|
308
|
+
if (result.errors.length > 0) {
|
|
309
|
+
for (const txid of result.ordinalTxids) addTx(label, txid)
|
|
310
|
+
if (result.sweptOutpoints.length > 0) await refreshAssets()
|
|
311
|
+
throw new Error(result.errors[0])
|
|
312
|
+
}
|
|
313
|
+
for (let i = 0; i < result.ordinalTxids.length - 1; i++) {
|
|
314
|
+
addTx(label, result.ordinalTxids[i])
|
|
315
|
+
}
|
|
316
|
+
return result.ordinalTxids[result.ordinalTxids.length - 1] ?? ''
|
|
317
|
+
})
|
|
318
|
+
},
|
|
319
|
+
[resolveWallet, legacyKeys, keyMap, runOperation, addTx, refreshAssets],
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
const handleSweepOrdinals = useCallback(async () => {
|
|
323
|
+
if (!assets) return
|
|
324
|
+
const selected = assets.ordinals.filter((o) =>
|
|
325
|
+
selectedOrdinals.has(o.outpoint),
|
|
326
|
+
)
|
|
327
|
+
if (selected.length === 0) return
|
|
328
|
+
await sweepOrdinalList(
|
|
329
|
+
selected,
|
|
330
|
+
`Sweep ${selected.length} ordinal${selected.length !== 1 ? 's' : ''}`,
|
|
310
331
|
)
|
|
311
|
-
}, [
|
|
332
|
+
}, [assets, selectedOrdinals, sweepOrdinalList])
|
|
333
|
+
|
|
334
|
+
const handleSweepAllOrdinals = useCallback(async () => {
|
|
335
|
+
if (!assets || assets.ordinals.length === 0) return
|
|
336
|
+
await sweepOrdinalList(
|
|
337
|
+
assets.ordinals,
|
|
338
|
+
`Sweep all ${assets.ordinals.length} ordinal${assets.ordinals.length !== 1 ? 's' : ''}`,
|
|
339
|
+
)
|
|
340
|
+
}, [assets, sweepOrdinalList])
|
|
312
341
|
|
|
313
342
|
const handleSendOrdinals = useCallback(
|
|
314
343
|
async (destination: string) => {
|
|
@@ -352,28 +381,58 @@ export function SweepApp({
|
|
|
352
381
|
)
|
|
353
382
|
}, [legacyKeys, assets, selectedOrdinals, runOperation])
|
|
354
383
|
|
|
355
|
-
const
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
)
|
|
361
|
-
if (selected.length === 0) return
|
|
362
|
-
await runOperation(
|
|
363
|
-
`Sweep ${selected.length} domain${selected.length !== 1 ? 's' : ''}`,
|
|
364
|
-
async () => {
|
|
384
|
+
const sweepOpnsList = useCallback(
|
|
385
|
+
async (list: EnrichedOrdinal[], label: string) => {
|
|
386
|
+
const wallet = resolveWallet()
|
|
387
|
+
if (!wallet || !legacyKeys || list.length === 0) return
|
|
388
|
+
await runOperation(label, async () => {
|
|
365
389
|
const result = await executeSweep({
|
|
366
390
|
wallet,
|
|
367
391
|
keys: keyMap,
|
|
368
392
|
funding: [],
|
|
369
|
-
ordinals:
|
|
393
|
+
ordinals: list,
|
|
370
394
|
onProgress: setSweepProgress,
|
|
371
395
|
})
|
|
372
|
-
if (result.
|
|
373
|
-
|
|
374
|
-
|
|
396
|
+
if (result.sweptOutpoints.length > 0) {
|
|
397
|
+
setSelectedOpns((prev) => {
|
|
398
|
+
const next = new Set(prev)
|
|
399
|
+
for (const op of result.sweptOutpoints) next.delete(op)
|
|
400
|
+
return next
|
|
401
|
+
})
|
|
402
|
+
}
|
|
403
|
+
if (result.errors.length > 0) {
|
|
404
|
+
for (const txid of result.ordinalTxids) addTx(label, txid)
|
|
405
|
+
if (result.sweptOutpoints.length > 0) await refreshAssets()
|
|
406
|
+
throw new Error(result.errors[0])
|
|
407
|
+
}
|
|
408
|
+
for (let i = 0; i < result.ordinalTxids.length - 1; i++) {
|
|
409
|
+
addTx(label, result.ordinalTxids[i])
|
|
410
|
+
}
|
|
411
|
+
return result.ordinalTxids[result.ordinalTxids.length - 1] ?? ''
|
|
412
|
+
})
|
|
413
|
+
},
|
|
414
|
+
[resolveWallet, legacyKeys, keyMap, runOperation, addTx, refreshAssets],
|
|
415
|
+
)
|
|
416
|
+
|
|
417
|
+
const handleSweepOpns = useCallback(async () => {
|
|
418
|
+
if (!assets) return
|
|
419
|
+
const selected = assets.opnsNames.filter((o) =>
|
|
420
|
+
selectedOpns.has(o.outpoint),
|
|
421
|
+
)
|
|
422
|
+
if (selected.length === 0) return
|
|
423
|
+
await sweepOpnsList(
|
|
424
|
+
selected,
|
|
425
|
+
`Sweep ${selected.length} domain${selected.length !== 1 ? 's' : ''}`,
|
|
426
|
+
)
|
|
427
|
+
}, [assets, selectedOpns, sweepOpnsList])
|
|
428
|
+
|
|
429
|
+
const handleSweepAllOpns = useCallback(async () => {
|
|
430
|
+
if (!assets || assets.opnsNames.length === 0) return
|
|
431
|
+
await sweepOpnsList(
|
|
432
|
+
assets.opnsNames,
|
|
433
|
+
`Sweep all ${assets.opnsNames.length} domain${assets.opnsNames.length !== 1 ? 's' : ''}`,
|
|
375
434
|
)
|
|
376
|
-
}, [
|
|
435
|
+
}, [assets, sweepOpnsList])
|
|
377
436
|
|
|
378
437
|
const handleSendOpns = useCallback(
|
|
379
438
|
async (destination: string) => {
|
|
@@ -512,9 +571,10 @@ export function SweepApp({
|
|
|
512
571
|
ordinals={assets.ordinals}
|
|
513
572
|
selectedOrdinals={selectedOrdinals}
|
|
514
573
|
onToggle={handleToggleOrdinal}
|
|
515
|
-
|
|
574
|
+
onSelectPage={handleSelectOrdinalPage}
|
|
516
575
|
onDeselectAll={handleDeselectAllOrdinals}
|
|
517
576
|
onSweep={handleSweepOrdinals}
|
|
577
|
+
onSweepAll={handleSweepAllOrdinals}
|
|
518
578
|
onSend={sweepOnly ? undefined : handleSendOrdinals}
|
|
519
579
|
onBurn={sweepOnly ? undefined : handleBurnOrdinals}
|
|
520
580
|
walletConnected={walletConnected}
|
|
@@ -525,9 +585,10 @@ export function SweepApp({
|
|
|
525
585
|
opnsNames={assets.opnsNames}
|
|
526
586
|
selectedOpns={selectedOpns}
|
|
527
587
|
onToggle={handleToggleOpns}
|
|
528
|
-
|
|
588
|
+
onSelectPage={handleSelectOpnsPage}
|
|
529
589
|
onDeselectAll={handleDeselectAllOpns}
|
|
530
590
|
onSweep={handleSweepOpns}
|
|
591
|
+
onSweepAll={handleSweepAllOpns}
|
|
531
592
|
onSend={sweepOnly ? undefined : handleSendOpns}
|
|
532
593
|
onBurn={sweepOnly ? undefined : handleBurnOpns}
|
|
533
594
|
walletConnected={walletConnected}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import type { IndexedOutput } from '@1sat/types'
|
|
2
2
|
import { useState } from 'react'
|
|
3
3
|
import type { EnrichedOrdinal, TokenBalance } from '../lib/scanner'
|
|
4
|
+
import { SWEEP_BATCH_SIZE } from '../lib/sweeper'
|
|
4
5
|
import { formatSats, formatTokenAmount } from '../lib/utils'
|
|
5
6
|
import { Badge } from './ui/badge'
|
|
6
7
|
import { Button } from './ui/button'
|
|
7
8
|
import { Input } from './ui/input'
|
|
8
9
|
|
|
9
|
-
const ORDINALS_PER_PAGE = 20
|
|
10
|
-
|
|
11
10
|
function isImageType(ct: string): boolean {
|
|
12
11
|
return ct.startsWith('image/') && ct !== 'image/svg+xml'
|
|
13
12
|
}
|
|
@@ -200,9 +199,10 @@ export function OrdinalsSection({
|
|
|
200
199
|
ordinals,
|
|
201
200
|
selectedOrdinals,
|
|
202
201
|
onToggle,
|
|
203
|
-
|
|
202
|
+
onSelectPage,
|
|
204
203
|
onDeselectAll,
|
|
205
204
|
onSweep,
|
|
205
|
+
onSweepAll,
|
|
206
206
|
onSend,
|
|
207
207
|
onBurn,
|
|
208
208
|
walletConnected,
|
|
@@ -210,9 +210,10 @@ export function OrdinalsSection({
|
|
|
210
210
|
ordinals: EnrichedOrdinal[]
|
|
211
211
|
selectedOrdinals: Set<string>
|
|
212
212
|
onToggle: (outpoint: string) => void
|
|
213
|
-
|
|
213
|
+
onSelectPage: (outpoints: string[]) => void
|
|
214
214
|
onDeselectAll: () => void
|
|
215
215
|
onSweep: () => void
|
|
216
|
+
onSweepAll: () => void
|
|
216
217
|
onSend?: (destination: string) => void
|
|
217
218
|
onBurn?: () => void
|
|
218
219
|
walletConnected: boolean
|
|
@@ -220,9 +221,13 @@ export function OrdinalsSection({
|
|
|
220
221
|
const [page, setPage] = useState(0)
|
|
221
222
|
const [address, setAddress] = useState('')
|
|
222
223
|
if (ordinals.length === 0) return null
|
|
223
|
-
const totalPages = Math.ceil(ordinals.length /
|
|
224
|
-
const
|
|
225
|
-
const
|
|
224
|
+
const totalPages = Math.ceil(ordinals.length / SWEEP_BATCH_SIZE)
|
|
225
|
+
const safePage = Math.min(page, totalPages - 1)
|
|
226
|
+
const start = safePage * SWEEP_BATCH_SIZE
|
|
227
|
+
const pageItems = ordinals.slice(start, start + SWEEP_BATCH_SIZE)
|
|
228
|
+
const pageOutpoints = pageItems.map((o) => o.outpoint)
|
|
229
|
+
const selectedCount = selectedOrdinals.size
|
|
230
|
+
const batchCount = Math.ceil(ordinals.length / SWEEP_BATCH_SIZE)
|
|
226
231
|
|
|
227
232
|
return (
|
|
228
233
|
<div className="border border-blue-500/20 bg-blue-500/5 p-4 rounded-lg">
|
|
@@ -236,11 +241,14 @@ export function OrdinalsSection({
|
|
|
236
241
|
</div>
|
|
237
242
|
<div className="text-xs text-muted-foreground">
|
|
238
243
|
{ordinals.length} inscription{ordinals.length !== 1 ? 's' : ''}
|
|
239
|
-
{
|
|
244
|
+
{selectedCount > 0 && (
|
|
240
245
|
<span className="text-blue-400 ml-1">
|
|
241
|
-
({
|
|
246
|
+
({selectedCount} selected)
|
|
242
247
|
</span>
|
|
243
248
|
)}
|
|
249
|
+
<span className="ml-1 text-muted-foreground/80">
|
|
250
|
+
· {SWEEP_BATCH_SIZE}/page
|
|
251
|
+
</span>
|
|
244
252
|
</div>
|
|
245
253
|
</div>
|
|
246
254
|
<div className="flex gap-2">
|
|
@@ -248,16 +256,16 @@ export function OrdinalsSection({
|
|
|
248
256
|
variant="outline"
|
|
249
257
|
size="sm"
|
|
250
258
|
className="h-7 text-[11px]"
|
|
251
|
-
onClick={
|
|
259
|
+
onClick={() => onSelectPage(pageOutpoints)}
|
|
252
260
|
>
|
|
253
|
-
Select
|
|
261
|
+
Select page
|
|
254
262
|
</Button>
|
|
255
263
|
<Button
|
|
256
264
|
variant="outline"
|
|
257
265
|
size="sm"
|
|
258
266
|
className="h-7 text-[11px]"
|
|
259
267
|
onClick={onDeselectAll}
|
|
260
|
-
disabled={
|
|
268
|
+
disabled={selectedCount === 0}
|
|
261
269
|
>
|
|
262
270
|
Deselect
|
|
263
271
|
</Button>
|
|
@@ -279,79 +287,94 @@ export function OrdinalsSection({
|
|
|
279
287
|
variant="ghost"
|
|
280
288
|
size="sm"
|
|
281
289
|
className="text-xs"
|
|
282
|
-
onClick={() => setPage(
|
|
283
|
-
disabled={
|
|
290
|
+
onClick={() => setPage(safePage - 1)}
|
|
291
|
+
disabled={safePage === 0}
|
|
284
292
|
>
|
|
285
293
|
Prev
|
|
286
294
|
</Button>
|
|
287
295
|
<span className="text-xs text-muted-foreground">
|
|
288
|
-
Page {
|
|
296
|
+
Page {safePage + 1} of {totalPages}
|
|
289
297
|
</span>
|
|
290
298
|
<Button
|
|
291
299
|
variant="ghost"
|
|
292
300
|
size="sm"
|
|
293
301
|
className="text-xs"
|
|
294
|
-
onClick={() => setPage(
|
|
295
|
-
disabled={
|
|
302
|
+
onClick={() => setPage(safePage + 1)}
|
|
303
|
+
disabled={safePage >= totalPages - 1}
|
|
296
304
|
>
|
|
297
305
|
Next
|
|
298
306
|
</Button>
|
|
299
307
|
</div>
|
|
300
308
|
)}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
309
|
+
<div className="mt-3 space-y-2">
|
|
310
|
+
{selectedCount > 0 && onSend && (
|
|
311
|
+
<Input
|
|
312
|
+
type="text"
|
|
313
|
+
placeholder="Destination address..."
|
|
314
|
+
value={address}
|
|
315
|
+
onChange={(e) => setAddress(e.target.value)}
|
|
316
|
+
className="font-mono text-xs"
|
|
317
|
+
/>
|
|
318
|
+
)}
|
|
319
|
+
<div className="flex flex-wrap gap-2">
|
|
320
|
+
{selectedCount > 0 && onSend && (
|
|
321
|
+
<Button
|
|
322
|
+
variant="outline"
|
|
323
|
+
size="sm"
|
|
324
|
+
className="flex-1 min-w-[6rem]"
|
|
325
|
+
disabled={!address.trim()}
|
|
326
|
+
onClick={() => onSend(address.trim())}
|
|
327
|
+
>
|
|
328
|
+
Send {selectedCount}
|
|
329
|
+
</Button>
|
|
311
330
|
)}
|
|
312
|
-
|
|
313
|
-
{onSend && (
|
|
314
|
-
<Button
|
|
315
|
-
variant="outline"
|
|
316
|
-
size="sm"
|
|
317
|
-
className="flex-1"
|
|
318
|
-
disabled={!address.trim()}
|
|
319
|
-
onClick={() => onSend(address.trim())}
|
|
320
|
-
>
|
|
321
|
-
Send {selectedOrdinals.size} Ordinal
|
|
322
|
-
{selectedOrdinals.size !== 1 ? 's' : ''}
|
|
323
|
-
</Button>
|
|
324
|
-
)}
|
|
331
|
+
{selectedCount > 0 && (
|
|
325
332
|
<Button
|
|
326
333
|
size="sm"
|
|
327
|
-
className="flex-1"
|
|
334
|
+
className="flex-1 min-w-[6rem]"
|
|
328
335
|
onClick={onSweep}
|
|
329
336
|
disabled={!walletConnected}
|
|
330
337
|
title={
|
|
331
338
|
walletConnected ? undefined : 'Connect BRC-100 wallet to sweep'
|
|
332
339
|
}
|
|
333
340
|
>
|
|
334
|
-
Sweep
|
|
341
|
+
Sweep {selectedCount}
|
|
342
|
+
{selectedCount > SWEEP_BATCH_SIZE
|
|
343
|
+
? ` (${Math.ceil(selectedCount / SWEEP_BATCH_SIZE)} batches)`
|
|
344
|
+
: ''}
|
|
335
345
|
</Button>
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
346
|
+
)}
|
|
347
|
+
<Button
|
|
348
|
+
variant={selectedCount > 0 ? 'outline' : 'default'}
|
|
349
|
+
size="sm"
|
|
350
|
+
className="flex-1 min-w-[6rem]"
|
|
351
|
+
onClick={onSweepAll}
|
|
352
|
+
disabled={!walletConnected}
|
|
353
|
+
title={
|
|
354
|
+
walletConnected ? undefined : 'Connect BRC-100 wallet to sweep'
|
|
355
|
+
}
|
|
356
|
+
>
|
|
357
|
+
Sweep all
|
|
358
|
+
{batchCount > 1 ? ` (${batchCount} batches)` : ''}
|
|
359
|
+
</Button>
|
|
360
|
+
{selectedCount > 0 && onBurn && (
|
|
361
|
+
<Button
|
|
362
|
+
size="sm"
|
|
363
|
+
className="bg-red-600 hover:bg-red-700 text-white"
|
|
364
|
+
onClick={() => {
|
|
365
|
+
if (
|
|
366
|
+
window.confirm(
|
|
367
|
+
`Permanently burn ${selectedCount} ordinal${selectedCount !== 1 ? 's' : ''}? This cannot be undone.`,
|
|
345
368
|
)
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
369
|
+
)
|
|
370
|
+
onBurn()
|
|
371
|
+
}}
|
|
372
|
+
>
|
|
373
|
+
Burn
|
|
374
|
+
</Button>
|
|
375
|
+
)}
|
|
353
376
|
</div>
|
|
354
|
-
|
|
377
|
+
</div>
|
|
355
378
|
</div>
|
|
356
379
|
)
|
|
357
380
|
}
|