@1sat/sweep-ui 0.0.18 → 0.0.20

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.
Files changed (60) hide show
  1. package/dist/components/SweepApp.d.ts +3 -3
  2. package/dist/components/SweepApp.d.ts.map +1 -1
  3. package/dist/components/asset-preview.d.ts +5 -5
  4. package/dist/components/asset-preview.d.ts.map +1 -1
  5. package/dist/components/connect-wallet.d.ts +1 -1
  6. package/dist/components/connect-wallet.d.ts.map +1 -1
  7. package/dist/components/opns-section.d.ts +2 -2
  8. package/dist/components/opns-section.d.ts.map +1 -1
  9. package/dist/components/sweep-progress.d.ts +1 -1
  10. package/dist/components/sweep-progress.d.ts.map +1 -1
  11. package/dist/components/tx-history.d.ts.map +1 -1
  12. package/dist/components/ui/badge.d.ts +3 -3
  13. package/dist/components/ui/badge.d.ts.map +1 -1
  14. package/dist/components/ui/button.d.ts +3 -3
  15. package/dist/components/ui/button.d.ts.map +1 -1
  16. package/dist/components/ui/card.d.ts +9 -9
  17. package/dist/components/ui/card.d.ts.map +1 -1
  18. package/dist/components/ui/input.d.ts +2 -2
  19. package/dist/components/ui/input.d.ts.map +1 -1
  20. package/dist/components/ui/tabs.d.ts +5 -5
  21. package/dist/components/ui/tabs.d.ts.map +1 -1
  22. package/dist/components/wif-input.d.ts +1 -1
  23. package/dist/components/wif-input.d.ts.map +1 -1
  24. package/dist/index.d.ts +19 -19
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +1911 -1757
  27. package/dist/lib/legacy-send.d.ts +2 -2
  28. package/dist/lib/legacy-send.d.ts.map +1 -1
  29. package/dist/lib/scanner.d.ts +3 -3
  30. package/dist/lib/scanner.d.ts.map +1 -1
  31. package/dist/lib/services.d.ts +1 -1
  32. package/dist/lib/services.d.ts.map +1 -1
  33. package/dist/lib/sweeper.d.ts +3 -3
  34. package/dist/lib/sweeper.d.ts.map +1 -1
  35. package/dist/lib/utils.d.ts +1 -1
  36. package/dist/lib/utils.d.ts.map +1 -1
  37. package/dist/lib/wallet.d.ts +2 -2
  38. package/dist/lib/wallet.d.ts.map +1 -1
  39. package/dist/types.d.ts.map +1 -1
  40. package/package.json +53 -44
  41. package/src/components/SweepApp.tsx +480 -222
  42. package/src/components/asset-preview.tsx +380 -97
  43. package/src/components/connect-wallet.tsx +50 -25
  44. package/src/components/opns-section.tsx +167 -60
  45. package/src/components/sweep-progress.tsx +40 -17
  46. package/src/components/tx-history.tsx +30 -17
  47. package/src/components/ui/badge.tsx +17 -14
  48. package/src/components/ui/button.tsx +26 -22
  49. package/src/components/ui/card.tsx +76 -17
  50. package/src/components/ui/input.tsx +7 -7
  51. package/src/components/ui/tabs.tsx +51 -12
  52. package/src/components/wif-input.tsx +243 -135
  53. package/src/index.ts +54 -19
  54. package/src/lib/legacy-send.ts +110 -106
  55. package/src/lib/scanner.ts +45 -40
  56. package/src/lib/services.ts +11 -9
  57. package/src/lib/sweeper.ts +67 -54
  58. package/src/lib/utils.ts +11 -11
  59. package/src/lib/wallet.ts +16 -13
  60. package/src/types.ts +3 -3
@@ -1,31 +1,34 @@
1
- import { useCallback, useRef, useState } from "react";
2
- import { KeyRound, Loader2, Search, Upload, X } from "lucide-react";
3
- import { Button } from "./ui/button";
4
- import { Card, CardContent, CardHeader, CardTitle } from "./ui/card";
5
- import { Input } from "./ui/input";
1
+ import { deriveIdentityKey } from '@1sat/utils'
6
2
  import {
3
+ type DecryptedBackup,
7
4
  decryptBackup,
5
+ getBackupType,
8
6
  isOneSatBackup,
9
- isYoursWalletBackup,
10
7
  isWifBackup,
11
- getBackupType,
12
- type DecryptedBackup,
13
- } from "bitcoin-backup";
14
- import { deriveAddress } from "../lib/scanner";
15
- import { deriveIdentityKey } from "@1sat/utils";
16
- import type { LegacyKeys } from "../types";
8
+ isYoursWalletBackup,
9
+ } from 'bitcoin-backup'
10
+ import { KeyRound, Loader2, Search, Upload, X } from 'lucide-react'
11
+ import { useCallback, useRef, useState } from 'react'
12
+ import { deriveAddress } from '../lib/scanner'
13
+ import type { LegacyKeys } from '../types'
14
+ import { Button } from './ui/button'
15
+ import { Card, CardContent, CardHeader, CardTitle } from './ui/card'
16
+ import { Input } from './ui/input'
17
17
 
18
18
  interface Props {
19
- onScan: (keys: LegacyKeys) => void;
20
- scanning: boolean;
21
- disabled: boolean;
19
+ onScan: (keys: LegacyKeys) => void
20
+ scanning: boolean
21
+ disabled: boolean
22
22
  }
23
23
 
24
- type InputMode = "choose" | "backup" | "wif";
24
+ type InputMode = 'choose' | 'backup' | 'wif'
25
25
 
26
26
  function withIdentityKey(keys: LegacyKeys): LegacyKeys {
27
- if (keys.identityPk) return keys;
28
- return { ...keys, identityPk: deriveIdentityKey(keys.payPk, keys.ordPk).toWif() };
27
+ if (keys.identityPk) return keys
28
+ return {
29
+ ...keys,
30
+ identityPk: deriveIdentityKey(keys.payPk, keys.ordPk).toWif(),
31
+ }
29
32
  }
30
33
 
31
34
  function extractKeys(backup: DecryptedBackup): LegacyKeys | null {
@@ -34,107 +37,108 @@ function extractKeys(backup: DecryptedBackup): LegacyKeys | null {
34
37
  payPk: backup.payPk,
35
38
  ordPk: backup.ordPk,
36
39
  identityPk: backup.identityPk,
37
- });
40
+ })
38
41
  }
39
42
  if (isYoursWalletBackup(backup)) {
40
43
  return withIdentityKey({
41
44
  payPk: backup.payPk,
42
45
  ordPk: backup.ordPk,
43
46
  identityPk: backup.identityPk,
44
- });
47
+ })
45
48
  }
46
49
  if (isWifBackup(backup)) {
47
50
  return withIdentityKey({
48
51
  payPk: backup.wif,
49
52
  ordPk: backup.wif,
50
- });
53
+ })
51
54
  }
52
- return null;
55
+ return null
53
56
  }
54
57
 
55
58
  function tryParseBackup(text: string): LegacyKeys | null {
56
59
  try {
57
- const parsed = JSON.parse(text);
60
+ const parsed = JSON.parse(text)
58
61
  if (parsed.payPk && parsed.ordPk) {
59
62
  return withIdentityKey({
60
63
  payPk: parsed.payPk,
61
64
  ordPk: parsed.ordPk,
62
65
  identityPk: parsed.identityPk,
63
- });
66
+ })
64
67
  }
65
68
  if (parsed.accounts && parsed.selectedAccount) {
66
- const account = parsed.accounts[parsed.selectedAccount];
69
+ const account = parsed.accounts[parsed.selectedAccount]
67
70
  if (account?.encryptedKeys) {
68
- return null;
71
+ return null
69
72
  }
70
73
  }
71
74
  } catch {
72
75
  // Not JSON
73
76
  }
74
- return null;
77
+ return null
75
78
  }
76
79
 
77
80
  function looksEncrypted(text: string): boolean {
78
- if (text.startsWith("{")) return false;
79
- if (text.startsWith("5") || text.startsWith("K") || text.startsWith("L")) return false;
80
- return text.length > 50;
81
+ if (text.startsWith('{')) return false
82
+ if (text.startsWith('5') || text.startsWith('K') || text.startsWith('L'))
83
+ return false
84
+ return text.length > 50
81
85
  }
82
86
 
83
87
  export function WifInput({ onScan, scanning, disabled }: Props) {
84
- const [mode, setMode] = useState<InputMode>("choose");
85
- const [keys, setKeys] = useState<LegacyKeys | null>(null);
86
- const [backupText, setBackupText] = useState("");
87
- const [password, setPassword] = useState("");
88
- const [needsPassword, setNeedsPassword] = useState(false);
89
- const [decrypting, setDecrypting] = useState(false);
90
- const [error, setError] = useState("");
91
- const [backupType, setBackupType] = useState("");
92
- const fileInputRef = useRef<HTMLInputElement>(null);
93
- const [payWif, setPayWif] = useState("");
94
- const [ordWif, setOrdWif] = useState("");
95
- const [sameKey, setSameKey] = useState(true);
88
+ const [mode, setMode] = useState<InputMode>('choose')
89
+ const [keys, setKeys] = useState<LegacyKeys | null>(null)
90
+ const [backupText, setBackupText] = useState('')
91
+ const [password, setPassword] = useState('')
92
+ const [needsPassword, setNeedsPassword] = useState(false)
93
+ const [decrypting, setDecrypting] = useState(false)
94
+ const [error, setError] = useState('')
95
+ const [backupType, setBackupType] = useState('')
96
+ const fileInputRef = useRef<HTMLInputElement>(null)
97
+ const [payWif, setPayWif] = useState('')
98
+ const [ordWif, setOrdWif] = useState('')
99
+ const [sameKey, setSameKey] = useState(true)
96
100
 
97
101
  const handleReset = useCallback(() => {
98
- setKeys(null);
99
- setBackupText("");
100
- setPassword("");
101
- setNeedsPassword(false);
102
- setError("");
103
- setBackupType("");
104
- setMode("choose");
105
- setPayWif("");
106
- setOrdWif("");
107
- }, []);
102
+ setKeys(null)
103
+ setBackupText('')
104
+ setPassword('')
105
+ setNeedsPassword(false)
106
+ setError('')
107
+ setBackupType('')
108
+ setMode('choose')
109
+ setPayWif('')
110
+ setOrdWif('')
111
+ }, [])
108
112
 
109
113
  const processBackupText = useCallback(async (text: string) => {
110
- setError("");
111
- setBackupText(text);
114
+ setError('')
115
+ setBackupText(text)
112
116
 
113
- const directKeys = tryParseBackup(text);
117
+ const directKeys = tryParseBackup(text)
114
118
  if (directKeys) {
115
- setKeys(directKeys);
116
- setBackupType("JSON");
117
- return;
119
+ setKeys(directKeys)
120
+ setBackupType('JSON')
121
+ return
118
122
  }
119
123
 
120
124
  try {
121
- const parsed = JSON.parse(text);
125
+ const parsed = JSON.parse(text)
122
126
  if (parsed.encryptedBackup) {
123
- setBackupText(parsed.encryptedBackup);
124
- setNeedsPassword(true);
125
- return;
127
+ setBackupText(parsed.encryptedBackup)
128
+ setNeedsPassword(true)
129
+ return
126
130
  }
127
131
  if (parsed.encryptedKeys) {
128
- setBackupText(parsed.encryptedKeys);
129
- setNeedsPassword(true);
130
- return;
132
+ setBackupText(parsed.encryptedKeys)
133
+ setNeedsPassword(true)
134
+ return
131
135
  }
132
136
  if (parsed.accounts && parsed.selectedAccount) {
133
- const account = parsed.accounts[parsed.selectedAccount];
137
+ const account = parsed.accounts[parsed.selectedAccount]
134
138
  if (account?.encryptedKeys) {
135
- setBackupText(account.encryptedKeys);
136
- setNeedsPassword(true);
137
- return;
139
+ setBackupText(account.encryptedKeys)
140
+ setNeedsPassword(true)
141
+ return
138
142
  }
139
143
  }
140
144
  } catch {
@@ -142,55 +146,58 @@ export function WifInput({ onScan, scanning, disabled }: Props) {
142
146
  }
143
147
 
144
148
  if (looksEncrypted(text)) {
145
- setNeedsPassword(true);
146
- return;
149
+ setNeedsPassword(true)
150
+ return
147
151
  }
148
152
 
149
- setError("Unrecognized backup format");
150
- }, []);
153
+ setError('Unrecognized backup format')
154
+ }, [])
151
155
 
152
156
  const handleDecrypt = useCallback(async () => {
153
- if (!backupText || !password) return;
154
- setDecrypting(true);
155
- setError("");
157
+ if (!backupText || !password) return
158
+ setDecrypting(true)
159
+ setError('')
156
160
 
157
161
  try {
158
- const decrypted = await decryptBackup(backupText, password);
159
- const extracted = extractKeys(decrypted);
162
+ const decrypted = await decryptBackup(backupText, password)
163
+ const extracted = extractKeys(decrypted)
160
164
  if (!extracted) {
161
- setError(`Unsupported backup type: ${getBackupType(decrypted)}`);
162
- return;
165
+ setError(`Unsupported backup type: ${getBackupType(decrypted)}`)
166
+ return
163
167
  }
164
- setKeys(extracted);
165
- setBackupType(getBackupType(decrypted));
166
- setNeedsPassword(false);
168
+ setKeys(extracted)
169
+ setBackupType(getBackupType(decrypted))
170
+ setNeedsPassword(false)
167
171
  } catch (e) {
168
- setError(e instanceof Error ? e.message : "Decryption failed");
172
+ setError(e instanceof Error ? e.message : 'Decryption failed')
169
173
  } finally {
170
- setDecrypting(false);
174
+ setDecrypting(false)
171
175
  }
172
- }, [backupText, password]);
176
+ }, [backupText, password])
173
177
 
174
- const handleFileUpload = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
175
- const file = e.target.files?.[0];
176
- if (!file) return;
177
- const reader = new FileReader();
178
- reader.onload = () => {
179
- processBackupText((reader.result as string).trim());
180
- };
181
- reader.readAsText(file);
182
- e.target.value = "";
183
- }, [processBackupText]);
178
+ const handleFileUpload = useCallback(
179
+ (e: React.ChangeEvent<HTMLInputElement>) => {
180
+ const file = e.target.files?.[0]
181
+ if (!file) return
182
+ const reader = new FileReader()
183
+ reader.onload = () => {
184
+ processBackupText((reader.result as string).trim())
185
+ }
186
+ reader.readAsText(file)
187
+ e.target.value = ''
188
+ },
189
+ [processBackupText],
190
+ )
184
191
 
185
192
  const handleScan = useCallback(() => {
186
193
  if (keys) {
187
- onScan(keys);
188
- } else if (mode === "wif") {
189
- const pay = payWif.trim();
190
- const ord = sameKey ? pay : ordWif.trim();
191
- if (pay) onScan({ payPk: pay, ordPk: ord });
194
+ onScan(keys)
195
+ } else if (mode === 'wif') {
196
+ const pay = payWif.trim()
197
+ const ord = sameKey ? pay : ordWif.trim()
198
+ if (pay) onScan({ payPk: pay, ordPk: ord })
192
199
  }
193
- }, [keys, mode, payWif, ordWif, sameKey, onScan]);
200
+ }, [keys, mode, payWif, ordWif, sameKey, onScan])
194
201
 
195
202
  if (keys) {
196
203
  return (
@@ -201,30 +208,49 @@ export function WifInput({ onScan, scanning, disabled }: Props) {
201
208
  <KeyRound className="h-5 w-5" />
202
209
  Legacy Keys
203
210
  </CardTitle>
204
- <Button variant="ghost" size="sm" className="h-6 w-6 p-0" onClick={handleReset}>
211
+ <Button
212
+ variant="ghost"
213
+ size="sm"
214
+ className="h-6 w-6 p-0"
215
+ onClick={handleReset}
216
+ >
205
217
  <X className="h-3 w-3" />
206
218
  </Button>
207
219
  </div>
208
220
  </CardHeader>
209
221
  <CardContent className="space-y-3">
210
222
  {backupType && (
211
- <span className="text-xs px-2 py-0.5 rounded bg-blue-500/20 text-blue-400">{backupType}</span>
223
+ <span className="text-xs px-2 py-0.5 rounded bg-blue-500/20 text-blue-400">
224
+ {backupType}
225
+ </span>
212
226
  )}
213
227
  <div className="space-y-1 text-xs text-muted-foreground font-mono">
214
228
  <div>Pay: {deriveAddress(keys.payPk)}</div>
215
- {keys.ordPk !== keys.payPk && <div>Ord: {deriveAddress(keys.ordPk)}</div>}
216
- {keys.identityPk && keys.identityPk !== keys.payPk && <div>ID: {deriveAddress(keys.identityPk)}</div>}
229
+ {keys.ordPk !== keys.payPk && (
230
+ <div>Ord: {deriveAddress(keys.ordPk)}</div>
231
+ )}
232
+ {keys.identityPk && keys.identityPk !== keys.payPk && (
233
+ <div>ID: {deriveAddress(keys.identityPk)}</div>
234
+ )}
217
235
  </div>
218
- <Button onClick={handleScan} disabled={disabled || scanning} className="w-full">
219
- {scanning ? <Loader2 className="h-4 w-4 animate-spin mr-2" /> : <Search className="h-4 w-4 mr-2" />}
220
- {scanning ? "Scanning..." : "Scan for Assets"}
236
+ <Button
237
+ onClick={handleScan}
238
+ disabled={disabled || scanning}
239
+ className="w-full"
240
+ >
241
+ {scanning ? (
242
+ <Loader2 className="h-4 w-4 animate-spin mr-2" />
243
+ ) : (
244
+ <Search className="h-4 w-4 mr-2" />
245
+ )}
246
+ {scanning ? 'Scanning...' : 'Scan for Assets'}
221
247
  </Button>
222
248
  </CardContent>
223
249
  </Card>
224
- );
250
+ )
225
251
  }
226
252
 
227
- if (mode === "choose") {
253
+ if (mode === 'choose') {
228
254
  return (
229
255
  <Card>
230
256
  <CardHeader>
@@ -234,23 +260,41 @@ export function WifInput({ onScan, scanning, disabled }: Props) {
234
260
  </CardTitle>
235
261
  </CardHeader>
236
262
  <CardContent className="space-y-3">
237
- <input ref={fileInputRef} type="file" accept=".json,.bep,.txt" className="hidden" onChange={handleFileUpload} />
238
- <Button variant="outline" className="w-full gap-2" onClick={() => fileInputRef.current?.click()}>
263
+ <input
264
+ ref={fileInputRef}
265
+ type="file"
266
+ accept=".json,.bep,.txt"
267
+ className="hidden"
268
+ onChange={handleFileUpload}
269
+ />
270
+ <Button
271
+ variant="outline"
272
+ className="w-full gap-2"
273
+ onClick={() => fileInputRef.current?.click()}
274
+ >
239
275
  <Upload className="h-4 w-4" />
240
276
  Import Backup File
241
277
  </Button>
242
- <Button variant="outline" className="w-full gap-2" onClick={() => setMode("backup")}>
278
+ <Button
279
+ variant="outline"
280
+ className="w-full gap-2"
281
+ onClick={() => setMode('backup')}
282
+ >
243
283
  Paste Backup Data
244
284
  </Button>
245
- <Button variant="ghost" className="w-full text-xs text-muted-foreground" onClick={() => setMode("wif")}>
285
+ <Button
286
+ variant="ghost"
287
+ className="w-full text-xs text-muted-foreground"
288
+ onClick={() => setMode('wif')}
289
+ >
246
290
  Enter WIF keys manually
247
291
  </Button>
248
292
  </CardContent>
249
293
  </Card>
250
- );
294
+ )
251
295
  }
252
296
 
253
- if (mode === "backup") {
297
+ if (mode === 'backup') {
254
298
  return (
255
299
  <Card>
256
300
  <CardHeader>
@@ -259,7 +303,12 @@ export function WifInput({ onScan, scanning, disabled }: Props) {
259
303
  <KeyRound className="h-5 w-5" />
260
304
  Import Backup
261
305
  </CardTitle>
262
- <Button variant="ghost" size="sm" className="h-6 w-6 p-0" onClick={handleReset}>
306
+ <Button
307
+ variant="ghost"
308
+ size="sm"
309
+ className="h-6 w-6 p-0"
310
+ onClick={handleReset}
311
+ >
263
312
  <X className="h-3 w-3" />
264
313
  </Button>
265
314
  </div>
@@ -272,26 +321,53 @@ export function WifInput({ onScan, scanning, disabled }: Props) {
272
321
  className="w-full h-24 rounded-md border border-input bg-transparent px-3 py-2 text-sm font-mono resize-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
273
322
  onChange={(e) => processBackupText(e.target.value.trim())}
274
323
  />
275
- <input ref={fileInputRef} type="file" accept=".json,.bep,.txt" className="hidden" onChange={handleFileUpload} />
276
- <Button variant="outline" size="sm" className="w-full gap-2" onClick={() => fileInputRef.current?.click()}>
324
+ <input
325
+ ref={fileInputRef}
326
+ type="file"
327
+ accept=".json,.bep,.txt"
328
+ className="hidden"
329
+ onChange={handleFileUpload}
330
+ />
331
+ <Button
332
+ variant="outline"
333
+ size="sm"
334
+ className="w-full gap-2"
335
+ onClick={() => fileInputRef.current?.click()}
336
+ >
277
337
  <Upload className="h-4 w-4" />
278
338
  Or upload a file
279
339
  </Button>
280
340
  </>
281
341
  ) : (
282
342
  <>
283
- <p className="text-sm text-muted-foreground">This backup is encrypted. Enter the password to decrypt.</p>
284
- <Input type="password" placeholder="Backup password..." value={password} onChange={(e) => setPassword(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") handleDecrypt(); }} />
285
- <Button onClick={handleDecrypt} disabled={!password || decrypting} className="w-full">
286
- {decrypting ? <Loader2 className="h-4 w-4 animate-spin mr-2" /> : null}
287
- {decrypting ? "Decrypting..." : "Decrypt"}
343
+ <p className="text-sm text-muted-foreground">
344
+ This backup is encrypted. Enter the password to decrypt.
345
+ </p>
346
+ <Input
347
+ type="password"
348
+ placeholder="Backup password..."
349
+ value={password}
350
+ onChange={(e) => setPassword(e.target.value)}
351
+ onKeyDown={(e) => {
352
+ if (e.key === 'Enter') handleDecrypt()
353
+ }}
354
+ />
355
+ <Button
356
+ onClick={handleDecrypt}
357
+ disabled={!password || decrypting}
358
+ className="w-full"
359
+ >
360
+ {decrypting ? (
361
+ <Loader2 className="h-4 w-4 animate-spin mr-2" />
362
+ ) : null}
363
+ {decrypting ? 'Decrypting...' : 'Decrypt'}
288
364
  </Button>
289
365
  </>
290
366
  )}
291
367
  {error && <p className="text-sm text-destructive">{error}</p>}
292
368
  </CardContent>
293
369
  </Card>
294
- );
370
+ )
295
371
  }
296
372
 
297
373
  return (
@@ -302,31 +378,63 @@ export function WifInput({ onScan, scanning, disabled }: Props) {
302
378
  <KeyRound className="h-5 w-5" />
303
379
  Manual WIF Entry
304
380
  </CardTitle>
305
- <Button variant="ghost" size="sm" className="h-6 w-6 p-0" onClick={handleReset}>
381
+ <Button
382
+ variant="ghost"
383
+ size="sm"
384
+ className="h-6 w-6 p-0"
385
+ onClick={handleReset}
386
+ >
306
387
  <X className="h-3 w-3" />
307
388
  </Button>
308
389
  </div>
309
390
  </CardHeader>
310
391
  <CardContent className="space-y-4">
311
392
  <div className="space-y-2">
312
- <label className="text-sm font-medium">{sameKey ? "Private Key (WIF)" : "Pay Key (WIF)"}</label>
313
- <Input type="password" placeholder="Enter WIF private key..." value={payWif} onChange={(e) => setPayWif(e.target.value)} disabled={disabled || scanning} />
393
+ <label className="text-sm font-medium">
394
+ {sameKey ? 'Private Key (WIF)' : 'Pay Key (WIF)'}
395
+ </label>
396
+ <Input
397
+ type="password"
398
+ placeholder="Enter WIF private key..."
399
+ value={payWif}
400
+ onChange={(e) => setPayWif(e.target.value)}
401
+ disabled={disabled || scanning}
402
+ />
314
403
  </div>
315
404
  <label className="flex items-center gap-2 text-sm">
316
- <input type="checkbox" checked={sameKey} onChange={(e) => setSameKey(e.target.checked)} disabled={disabled || scanning} />
405
+ <input
406
+ type="checkbox"
407
+ checked={sameKey}
408
+ onChange={(e) => setSameKey(e.target.checked)}
409
+ disabled={disabled || scanning}
410
+ />
317
411
  Same key for pay and ordinals
318
412
  </label>
319
413
  {!sameKey && (
320
414
  <div className="space-y-2">
321
415
  <label className="text-sm font-medium">Ordinals Key (WIF)</label>
322
- <Input type="password" placeholder="Enter ordinals WIF..." value={ordWif} onChange={(e) => setOrdWif(e.target.value)} disabled={disabled || scanning} />
416
+ <Input
417
+ type="password"
418
+ placeholder="Enter ordinals WIF..."
419
+ value={ordWif}
420
+ onChange={(e) => setOrdWif(e.target.value)}
421
+ disabled={disabled || scanning}
422
+ />
323
423
  </div>
324
424
  )}
325
- <Button onClick={handleScan} disabled={disabled || scanning || !payWif.trim()} className="w-full">
326
- {scanning ? <Loader2 className="h-4 w-4 animate-spin mr-2" /> : <Search className="h-4 w-4 mr-2" />}
327
- {scanning ? "Scanning..." : "Scan for Assets"}
425
+ <Button
426
+ onClick={handleScan}
427
+ disabled={disabled || scanning || !payWif.trim()}
428
+ className="w-full"
429
+ >
430
+ {scanning ? (
431
+ <Loader2 className="h-4 w-4 animate-spin mr-2" />
432
+ ) : (
433
+ <Search className="h-4 w-4 mr-2" />
434
+ )}
435
+ {scanning ? 'Scanning...' : 'Scan for Assets'}
328
436
  </Button>
329
437
  </CardContent>
330
438
  </Card>
331
- );
439
+ )
332
440
  }
package/src/index.ts CHANGED
@@ -1,28 +1,63 @@
1
1
  // Main app component
2
- export { SweepApp, type SweepAppProps } from "./components/SweepApp";
2
+ export { SweepApp, type SweepAppProps } from './components/SweepApp'
3
3
 
4
4
  // Feature components
5
- export { ConnectWallet } from "./components/connect-wallet";
6
- export { WifInput } from "./components/wif-input";
7
- export { FundingSection, OrdinalsSection, Bsv21Section, Bsv20Section, LockedSection, RunSection } from "./components/asset-preview";
8
- export { OpnsSection } from "./components/opns-section";
9
- export { TxHistory, type TxRecord } from "./components/tx-history";
10
- export { SweepProgress } from "./components/sweep-progress";
5
+ export { ConnectWallet } from './components/connect-wallet'
6
+ export { WifInput } from './components/wif-input'
7
+ export {
8
+ FundingSection,
9
+ OrdinalsSection,
10
+ Bsv21Section,
11
+ Bsv20Section,
12
+ LockedSection,
13
+ RunSection,
14
+ } from './components/asset-preview'
15
+ export { OpnsSection } from './components/opns-section'
16
+ export { TxHistory, type TxRecord } from './components/tx-history'
17
+ export { SweepProgress } from './components/sweep-progress'
11
18
 
12
19
  // UI primitives
13
- export { Badge, badgeVariants } from "./components/ui/badge";
14
- export { Button, buttonVariants } from "./components/ui/button";
15
- export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent } from "./components/ui/card";
16
- export { Input } from "./components/ui/input";
17
- export { Tabs, TabsList, TabsTrigger, TabsContent } from "./components/ui/tabs";
20
+ export { Badge, badgeVariants } from './components/ui/badge'
21
+ export { Button, buttonVariants } from './components/ui/button'
22
+ export {
23
+ Card,
24
+ CardHeader,
25
+ CardFooter,
26
+ CardTitle,
27
+ CardAction,
28
+ CardDescription,
29
+ CardContent,
30
+ } from './components/ui/card'
31
+ export { Input } from './components/ui/input'
32
+ export { Tabs, TabsList, TabsTrigger, TabsContent } from './components/ui/tabs'
18
33
 
19
34
  // Lib
20
- export { configureServices, getServices } from "./lib/services";
21
- export { connectWallet, getWallet, getIdentityKey, getProvider, disconnectWallet, isConnected } from "./lib/wallet";
22
- export { deriveAddress, scanAddress, scanAddresses, type ScannedAssets, type EnrichedOrdinal, type TokenBalance, type ScanProgress } from "./lib/scanner";
23
- export { executeSweep, type SweepResult } from "./lib/sweeper";
24
- export { legacySendBsv, legacySendOrdinals, legacyBurnOrdinals, type LegacySendResult } from "./lib/legacy-send";
25
- export { cn, formatSats, formatTokenAmount, truncate } from "./lib/utils";
35
+ export { configureServices, getServices } from './lib/services'
36
+ export {
37
+ connectWallet,
38
+ getWallet,
39
+ getIdentityKey,
40
+ getProvider,
41
+ disconnectWallet,
42
+ isConnected,
43
+ } from './lib/wallet'
44
+ export {
45
+ deriveAddress,
46
+ scanAddress,
47
+ scanAddresses,
48
+ type ScannedAssets,
49
+ type EnrichedOrdinal,
50
+ type TokenBalance,
51
+ type ScanProgress,
52
+ } from './lib/scanner'
53
+ export { executeSweep, type SweepResult } from './lib/sweeper'
54
+ export {
55
+ legacySendBsv,
56
+ legacySendOrdinals,
57
+ legacyBurnOrdinals,
58
+ type LegacySendResult,
59
+ } from './lib/legacy-send'
60
+ export { cn, formatSats, formatTokenAmount, truncate } from './lib/utils'
26
61
 
27
62
  // Types
28
- export type { LegacyKeys } from "./types";
63
+ export type { LegacyKeys } from './types'