@1sat/sweep-ui 0.0.19 → 0.0.21
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 +3 -3
- package/dist/components/SweepApp.d.ts.map +1 -1
- package/dist/components/asset-preview.d.ts +5 -5
- package/dist/components/asset-preview.d.ts.map +1 -1
- package/dist/components/connect-wallet.d.ts +1 -1
- package/dist/components/connect-wallet.d.ts.map +1 -1
- package/dist/components/opns-section.d.ts +2 -2
- package/dist/components/opns-section.d.ts.map +1 -1
- package/dist/components/sweep-progress.d.ts +1 -1
- package/dist/components/sweep-progress.d.ts.map +1 -1
- package/dist/components/tx-history.d.ts.map +1 -1
- package/dist/components/ui/badge.d.ts +3 -3
- package/dist/components/ui/badge.d.ts.map +1 -1
- package/dist/components/ui/button.d.ts +3 -3
- package/dist/components/ui/button.d.ts.map +1 -1
- package/dist/components/ui/card.d.ts +9 -9
- package/dist/components/ui/card.d.ts.map +1 -1
- package/dist/components/ui/input.d.ts +2 -2
- package/dist/components/ui/input.d.ts.map +1 -1
- package/dist/components/ui/tabs.d.ts +5 -5
- package/dist/components/ui/tabs.d.ts.map +1 -1
- package/dist/components/wif-input.d.ts +1 -1
- package/dist/components/wif-input.d.ts.map +1 -1
- package/dist/index.d.ts +19 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1911 -1757
- package/dist/lib/legacy-send.d.ts +2 -2
- package/dist/lib/legacy-send.d.ts.map +1 -1
- package/dist/lib/scanner.d.ts +3 -3
- package/dist/lib/scanner.d.ts.map +1 -1
- package/dist/lib/services.d.ts +1 -1
- package/dist/lib/services.d.ts.map +1 -1
- package/dist/lib/sweeper.d.ts +3 -3
- package/dist/lib/sweeper.d.ts.map +1 -1
- package/dist/lib/utils.d.ts +1 -1
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/wallet.d.ts +2 -2
- package/dist/lib/wallet.d.ts.map +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +53 -44
- package/src/components/SweepApp.tsx +480 -222
- package/src/components/asset-preview.tsx +380 -97
- package/src/components/connect-wallet.tsx +50 -25
- package/src/components/opns-section.tsx +167 -60
- package/src/components/sweep-progress.tsx +40 -17
- package/src/components/tx-history.tsx +30 -17
- package/src/components/ui/badge.tsx +17 -14
- package/src/components/ui/button.tsx +26 -22
- package/src/components/ui/card.tsx +76 -17
- package/src/components/ui/input.tsx +7 -7
- package/src/components/ui/tabs.tsx +51 -12
- package/src/components/wif-input.tsx +243 -135
- package/src/index.ts +54 -19
- package/src/lib/legacy-send.ts +110 -106
- package/src/lib/scanner.ts +45 -40
- package/src/lib/services.ts +11 -9
- package/src/lib/sweeper.ts +67 -54
- package/src/lib/utils.ts +11 -11
- package/src/lib/wallet.ts +16 -13
- package/src/types.ts +3 -3
package/src/lib/legacy-send.ts
CHANGED
|
@@ -1,234 +1,238 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import { OP, P2PKH, PrivateKey, Script, Transaction, Utils } from
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
1
|
+
import type { IndexedOutput } from '@1sat/types'
|
|
2
|
+
import { MAP_PREFIX } from '@1sat/types'
|
|
3
|
+
import { parseOutpoint } from '@1sat/utils'
|
|
4
|
+
import { OP, P2PKH, PrivateKey, Script, Transaction, Utils } from '@bsv/sdk'
|
|
5
|
+
import type { LegacyKeys } from '../types'
|
|
6
|
+
import { deriveAddress } from './scanner'
|
|
7
|
+
import { getServices } from './services'
|
|
8
8
|
|
|
9
9
|
export interface LegacySendResult {
|
|
10
|
-
txid: string
|
|
11
|
-
rawtx: string
|
|
10
|
+
txid: string
|
|
11
|
+
rawtx: string
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
async function fetchSourceTx(txid: string): Promise<Transaction> {
|
|
15
|
-
const services = getServices()
|
|
16
|
-
const beef = await services.getBeefForTxid(txid)
|
|
17
|
-
const found = beef.findTxid(txid)
|
|
18
|
-
if (!found?.tx) throw new Error(`Transaction ${txid} not found in BEEF`)
|
|
19
|
-
return found.tx
|
|
15
|
+
const services = getServices()
|
|
16
|
+
const beef = await services.getBeefForTxid(txid)
|
|
17
|
+
const found = beef.findTxid(txid)
|
|
18
|
+
if (!found?.tx) throw new Error(`Transaction ${txid} not found in BEEF`)
|
|
19
|
+
return found.tx
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
function buildKeyMap(keys: LegacyKeys): Map<string, PrivateKey> {
|
|
23
|
-
const map = new Map<string, PrivateKey>()
|
|
24
|
-
const payKey = PrivateKey.fromWif(keys.payPk)
|
|
25
|
-
const ordKey = PrivateKey.fromWif(keys.ordPk)
|
|
26
|
-
map.set(deriveAddress(keys.payPk), payKey)
|
|
27
|
-
map.set(deriveAddress(keys.ordPk), ordKey)
|
|
23
|
+
const map = new Map<string, PrivateKey>()
|
|
24
|
+
const payKey = PrivateKey.fromWif(keys.payPk)
|
|
25
|
+
const ordKey = PrivateKey.fromWif(keys.ordPk)
|
|
26
|
+
map.set(deriveAddress(keys.payPk), payKey)
|
|
27
|
+
map.set(deriveAddress(keys.ordPk), ordKey)
|
|
28
28
|
if (keys.identityPk) {
|
|
29
|
-
map.set(deriveAddress(keys.identityPk), PrivateKey.fromWif(keys.identityPk))
|
|
29
|
+
map.set(deriveAddress(keys.identityPk), PrivateKey.fromWif(keys.identityPk))
|
|
30
30
|
}
|
|
31
|
-
return map
|
|
31
|
+
return map
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
function keyForOutput(
|
|
34
|
+
function keyForOutput(
|
|
35
|
+
output: IndexedOutput,
|
|
36
|
+
keyMap: Map<string, PrivateKey>,
|
|
37
|
+
fallback: PrivateKey,
|
|
38
|
+
): PrivateKey {
|
|
35
39
|
if (output.events) {
|
|
36
40
|
for (const event of output.events) {
|
|
37
|
-
if (event.startsWith(
|
|
38
|
-
const addr = event.split(
|
|
39
|
-
const key = keyMap.get(addr)
|
|
40
|
-
if (key) return key
|
|
41
|
+
if (event.startsWith('own:') || event.startsWith('p2pkh:')) {
|
|
42
|
+
const addr = event.split(':')[1]
|
|
43
|
+
const key = keyMap.get(addr)
|
|
44
|
+
if (key) return key
|
|
41
45
|
}
|
|
42
46
|
}
|
|
43
47
|
}
|
|
44
|
-
return fallback
|
|
48
|
+
return fallback
|
|
45
49
|
}
|
|
46
50
|
|
|
47
51
|
export async function legacySendBsv(params: {
|
|
48
|
-
funding: IndexedOutput[]
|
|
49
|
-
keys: LegacyKeys
|
|
50
|
-
destination: string
|
|
51
|
-
amount?: number
|
|
52
|
+
funding: IndexedOutput[]
|
|
53
|
+
keys: LegacyKeys
|
|
54
|
+
destination: string
|
|
55
|
+
amount?: number
|
|
52
56
|
}): Promise<LegacySendResult> {
|
|
53
|
-
const { funding, keys, destination, amount } = params
|
|
54
|
-
if (!funding.length) throw new Error(
|
|
55
|
-
if (!destination) throw new Error(
|
|
57
|
+
const { funding, keys, destination, amount } = params
|
|
58
|
+
if (!funding.length) throw new Error('No funding UTXOs')
|
|
59
|
+
if (!destination) throw new Error('No destination address')
|
|
56
60
|
|
|
57
|
-
const keyMap = buildKeyMap(keys)
|
|
58
|
-
const payKey = PrivateKey.fromWif(keys.payPk)
|
|
59
|
-
const sourceAddress = payKey.toPublicKey().toAddress()
|
|
60
|
-
const p2pkh = new P2PKH()
|
|
61
|
-
const tx = new Transaction()
|
|
61
|
+
const keyMap = buildKeyMap(keys)
|
|
62
|
+
const payKey = PrivateKey.fromWif(keys.payPk)
|
|
63
|
+
const sourceAddress = payKey.toPublicKey().toAddress()
|
|
64
|
+
const p2pkh = new P2PKH()
|
|
65
|
+
const tx = new Transaction()
|
|
62
66
|
|
|
63
67
|
for (const utxo of funding) {
|
|
64
|
-
const { txid, vout } = parseOutpoint(utxo.outpoint)
|
|
65
|
-
const key = keyForOutput(utxo, keyMap, payKey)
|
|
68
|
+
const { txid, vout } = parseOutpoint(utxo.outpoint)
|
|
69
|
+
const key = keyForOutput(utxo, keyMap, payKey)
|
|
66
70
|
tx.addInput({
|
|
67
71
|
sourceTXID: txid,
|
|
68
72
|
sourceOutputIndex: vout,
|
|
69
73
|
sourceTransaction: await fetchSourceTx(txid),
|
|
70
74
|
unlockingScriptTemplate: p2pkh.unlock(key),
|
|
71
75
|
sequence: 0xffffffff,
|
|
72
|
-
})
|
|
76
|
+
})
|
|
73
77
|
}
|
|
74
78
|
|
|
75
79
|
if (amount) {
|
|
76
80
|
tx.addOutput({
|
|
77
81
|
lockingScript: p2pkh.lock(destination),
|
|
78
82
|
satoshis: amount,
|
|
79
|
-
})
|
|
83
|
+
})
|
|
80
84
|
tx.addOutput({
|
|
81
85
|
lockingScript: p2pkh.lock(sourceAddress),
|
|
82
86
|
change: true,
|
|
83
|
-
})
|
|
87
|
+
})
|
|
84
88
|
} else {
|
|
85
89
|
tx.addOutput({
|
|
86
90
|
lockingScript: p2pkh.lock(destination),
|
|
87
91
|
change: true,
|
|
88
|
-
})
|
|
92
|
+
})
|
|
89
93
|
}
|
|
90
94
|
|
|
91
|
-
await tx.fee()
|
|
92
|
-
await tx.sign()
|
|
95
|
+
await tx.fee()
|
|
96
|
+
await tx.sign()
|
|
93
97
|
|
|
94
|
-
const rawTx = tx.toBinary()
|
|
95
|
-
const result = await getServices().arcade.submitTransaction(rawTx)
|
|
98
|
+
const rawTx = tx.toBinary()
|
|
99
|
+
const result = await getServices().arcade.submitTransaction(rawTx)
|
|
96
100
|
|
|
97
101
|
return {
|
|
98
102
|
txid: result.txid,
|
|
99
103
|
rawtx: Utils.toHex(rawTx),
|
|
100
|
-
}
|
|
104
|
+
}
|
|
101
105
|
}
|
|
102
106
|
|
|
103
107
|
export async function legacySendOrdinals(params: {
|
|
104
|
-
ordinals: IndexedOutput[]
|
|
105
|
-
funding: IndexedOutput[]
|
|
106
|
-
keys: LegacyKeys
|
|
107
|
-
destination: string
|
|
108
|
+
ordinals: IndexedOutput[]
|
|
109
|
+
funding: IndexedOutput[]
|
|
110
|
+
keys: LegacyKeys
|
|
111
|
+
destination: string
|
|
108
112
|
}): Promise<LegacySendResult> {
|
|
109
|
-
const { ordinals, funding, keys, destination } = params
|
|
110
|
-
if (!ordinals.length) throw new Error(
|
|
111
|
-
if (!funding.length) throw new Error(
|
|
112
|
-
if (!destination) throw new Error(
|
|
113
|
+
const { ordinals, funding, keys, destination } = params
|
|
114
|
+
if (!ordinals.length) throw new Error('No ordinals to send')
|
|
115
|
+
if (!funding.length) throw new Error('No funding UTXOs for fees')
|
|
116
|
+
if (!destination) throw new Error('No destination address')
|
|
113
117
|
|
|
114
|
-
const keyMap = buildKeyMap(keys)
|
|
115
|
-
const payKey = PrivateKey.fromWif(keys.payPk)
|
|
116
|
-
const sourceAddress = payKey.toPublicKey().toAddress()
|
|
117
|
-
const p2pkh = new P2PKH()
|
|
118
|
-
const tx = new Transaction()
|
|
118
|
+
const keyMap = buildKeyMap(keys)
|
|
119
|
+
const payKey = PrivateKey.fromWif(keys.payPk)
|
|
120
|
+
const sourceAddress = payKey.toPublicKey().toAddress()
|
|
121
|
+
const p2pkh = new P2PKH()
|
|
122
|
+
const tx = new Transaction()
|
|
119
123
|
|
|
120
124
|
for (const ord of ordinals) {
|
|
121
|
-
const { txid, vout } = parseOutpoint(ord.outpoint)
|
|
122
|
-
const key = keyForOutput(ord, keyMap, payKey)
|
|
125
|
+
const { txid, vout } = parseOutpoint(ord.outpoint)
|
|
126
|
+
const key = keyForOutput(ord, keyMap, payKey)
|
|
123
127
|
tx.addInput({
|
|
124
128
|
sourceTXID: txid,
|
|
125
129
|
sourceOutputIndex: vout,
|
|
126
130
|
sourceTransaction: await fetchSourceTx(txid),
|
|
127
131
|
unlockingScriptTemplate: p2pkh.unlock(key),
|
|
128
132
|
sequence: 0xffffffff,
|
|
129
|
-
})
|
|
133
|
+
})
|
|
130
134
|
}
|
|
131
135
|
|
|
132
136
|
for (const _ord of ordinals) {
|
|
133
137
|
tx.addOutput({
|
|
134
138
|
lockingScript: p2pkh.lock(destination),
|
|
135
139
|
satoshis: 1,
|
|
136
|
-
})
|
|
140
|
+
})
|
|
137
141
|
}
|
|
138
142
|
|
|
139
143
|
for (const utxo of funding) {
|
|
140
|
-
const { txid, vout } = parseOutpoint(utxo.outpoint)
|
|
141
|
-
const key = keyForOutput(utxo, keyMap, payKey)
|
|
144
|
+
const { txid, vout } = parseOutpoint(utxo.outpoint)
|
|
145
|
+
const key = keyForOutput(utxo, keyMap, payKey)
|
|
142
146
|
tx.addInput({
|
|
143
147
|
sourceTXID: txid,
|
|
144
148
|
sourceOutputIndex: vout,
|
|
145
149
|
sourceTransaction: await fetchSourceTx(txid),
|
|
146
150
|
unlockingScriptTemplate: p2pkh.unlock(key),
|
|
147
151
|
sequence: 0xffffffff,
|
|
148
|
-
})
|
|
152
|
+
})
|
|
149
153
|
}
|
|
150
154
|
|
|
151
155
|
tx.addOutput({
|
|
152
156
|
lockingScript: p2pkh.lock(sourceAddress),
|
|
153
157
|
change: true,
|
|
154
|
-
})
|
|
158
|
+
})
|
|
155
159
|
|
|
156
|
-
await tx.fee()
|
|
157
|
-
await tx.sign()
|
|
160
|
+
await tx.fee()
|
|
161
|
+
await tx.sign()
|
|
158
162
|
|
|
159
|
-
const rawTx = tx.toBinary()
|
|
160
|
-
const result = await getServices().arcade.submitTransaction(rawTx)
|
|
163
|
+
const rawTx = tx.toBinary()
|
|
164
|
+
const result = await getServices().arcade.submitTransaction(rawTx)
|
|
161
165
|
|
|
162
166
|
return {
|
|
163
167
|
txid: result.txid,
|
|
164
168
|
rawtx: Utils.toHex(rawTx),
|
|
165
|
-
}
|
|
169
|
+
}
|
|
166
170
|
}
|
|
167
171
|
|
|
168
172
|
export async function legacyBurnOrdinals(params: {
|
|
169
|
-
ordinals: IndexedOutput[]
|
|
170
|
-
funding: IndexedOutput[]
|
|
171
|
-
keys: LegacyKeys
|
|
173
|
+
ordinals: IndexedOutput[]
|
|
174
|
+
funding: IndexedOutput[]
|
|
175
|
+
keys: LegacyKeys
|
|
172
176
|
}): Promise<LegacySendResult> {
|
|
173
|
-
const { ordinals, funding, keys } = params
|
|
174
|
-
if (!ordinals.length) throw new Error(
|
|
177
|
+
const { ordinals, funding, keys } = params
|
|
178
|
+
if (!ordinals.length) throw new Error('No ordinals to burn')
|
|
175
179
|
|
|
176
|
-
const keyMap = buildKeyMap(keys)
|
|
177
|
-
const payKey = PrivateKey.fromWif(keys.payPk)
|
|
178
|
-
const sourceAddress = payKey.toPublicKey().toAddress()
|
|
179
|
-
const p2pkh = new P2PKH()
|
|
180
|
-
const tx = new Transaction()
|
|
180
|
+
const keyMap = buildKeyMap(keys)
|
|
181
|
+
const payKey = PrivateKey.fromWif(keys.payPk)
|
|
182
|
+
const sourceAddress = payKey.toPublicKey().toAddress()
|
|
183
|
+
const p2pkh = new P2PKH()
|
|
184
|
+
const tx = new Transaction()
|
|
181
185
|
|
|
182
186
|
for (const ord of ordinals) {
|
|
183
|
-
const { txid, vout } = parseOutpoint(ord.outpoint)
|
|
184
|
-
const key = keyForOutput(ord, keyMap, payKey)
|
|
187
|
+
const { txid, vout } = parseOutpoint(ord.outpoint)
|
|
188
|
+
const key = keyForOutput(ord, keyMap, payKey)
|
|
185
189
|
tx.addInput({
|
|
186
190
|
sourceTXID: txid,
|
|
187
191
|
sourceOutputIndex: vout,
|
|
188
192
|
sourceTransaction: await fetchSourceTx(txid),
|
|
189
193
|
unlockingScriptTemplate: p2pkh.unlock(key),
|
|
190
194
|
sequence: 0xffffffff,
|
|
191
|
-
})
|
|
195
|
+
})
|
|
192
196
|
}
|
|
193
197
|
|
|
194
198
|
for (const utxo of funding) {
|
|
195
|
-
const { txid, vout } = parseOutpoint(utxo.outpoint)
|
|
196
|
-
const key = keyForOutput(utxo, keyMap, payKey)
|
|
199
|
+
const { txid, vout } = parseOutpoint(utxo.outpoint)
|
|
200
|
+
const key = keyForOutput(utxo, keyMap, payKey)
|
|
197
201
|
tx.addInput({
|
|
198
202
|
sourceTXID: txid,
|
|
199
203
|
sourceOutputIndex: vout,
|
|
200
204
|
sourceTransaction: await fetchSourceTx(txid),
|
|
201
205
|
unlockingScriptTemplate: p2pkh.unlock(key),
|
|
202
206
|
sequence: 0xffffffff,
|
|
203
|
-
})
|
|
207
|
+
})
|
|
204
208
|
}
|
|
205
209
|
|
|
206
210
|
const burnScript = new Script()
|
|
207
211
|
.writeOpCode(OP.OP_FALSE)
|
|
208
212
|
.writeOpCode(OP.OP_RETURN)
|
|
209
213
|
.writeBin(Utils.toArray(MAP_PREFIX))
|
|
210
|
-
.writeBin(Utils.toArray(
|
|
211
|
-
.writeBin(Utils.toArray(
|
|
212
|
-
.writeBin(Utils.toArray(
|
|
213
|
-
.writeBin(Utils.toArray(
|
|
214
|
-
.writeBin(Utils.toArray(
|
|
215
|
-
.writeBin(Utils.toArray(
|
|
216
|
-
.writeBin(Utils.toArray(
|
|
217
|
-
tx.addOutput({ satoshis: 0, lockingScript: burnScript })
|
|
214
|
+
.writeBin(Utils.toArray('SET'))
|
|
215
|
+
.writeBin(Utils.toArray('app'))
|
|
216
|
+
.writeBin(Utils.toArray('1sat-sweep'))
|
|
217
|
+
.writeBin(Utils.toArray('type'))
|
|
218
|
+
.writeBin(Utils.toArray('ord'))
|
|
219
|
+
.writeBin(Utils.toArray('op'))
|
|
220
|
+
.writeBin(Utils.toArray('burn'))
|
|
221
|
+
tx.addOutput({ satoshis: 0, lockingScript: burnScript })
|
|
218
222
|
|
|
219
223
|
tx.addOutput({
|
|
220
224
|
lockingScript: p2pkh.lock(sourceAddress),
|
|
221
225
|
change: true,
|
|
222
|
-
})
|
|
226
|
+
})
|
|
223
227
|
|
|
224
|
-
await tx.fee()
|
|
225
|
-
await tx.sign()
|
|
228
|
+
await tx.fee()
|
|
229
|
+
await tx.sign()
|
|
226
230
|
|
|
227
|
-
const rawTx = tx.toBinary()
|
|
228
|
-
const result = await getServices().arcade.submitTransaction(rawTx)
|
|
231
|
+
const rawTx = tx.toBinary()
|
|
232
|
+
const result = await getServices().arcade.submitTransaction(rawTx)
|
|
229
233
|
|
|
230
234
|
return {
|
|
231
235
|
txid: result.txid,
|
|
232
236
|
rawtx: Utils.toHex(rawTx),
|
|
233
|
-
}
|
|
237
|
+
}
|
|
234
238
|
}
|
package/src/lib/scanner.ts
CHANGED
|
@@ -1,85 +1,90 @@
|
|
|
1
|
-
import { PrivateKey } from "@bsv/sdk";
|
|
2
|
-
import type { IndexedOutput } from "@1sat/types";
|
|
3
1
|
import {
|
|
4
|
-
scanAddresses as coreScanAddresses,
|
|
5
|
-
type ScanResult,
|
|
6
2
|
type ScanProgress,
|
|
3
|
+
type ScanResult,
|
|
7
4
|
type TokenBalance,
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
scanAddresses as coreScanAddresses,
|
|
6
|
+
} from '@1sat/actions'
|
|
7
|
+
import type { IndexedOutput } from '@1sat/types'
|
|
8
|
+
import { PrivateKey } from '@bsv/sdk'
|
|
9
|
+
import { getServices } from './services'
|
|
10
10
|
|
|
11
|
-
export type { TokenBalance, ScanProgress, ScanResult }
|
|
11
|
+
export type { TokenBalance, ScanProgress, ScanResult }
|
|
12
12
|
|
|
13
13
|
export interface EnrichedOrdinal extends IndexedOutput {
|
|
14
|
-
origin?: string
|
|
15
|
-
contentType?: string
|
|
16
|
-
name?: string
|
|
17
|
-
contentUrl: string
|
|
14
|
+
origin?: string
|
|
15
|
+
contentType?: string
|
|
16
|
+
name?: string
|
|
17
|
+
contentUrl: string
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
export interface ScannedAssets
|
|
21
|
-
ordinals
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
export interface ScannedAssets
|
|
21
|
+
extends Omit<ScanResult, 'ordinals' | 'opnsNames'> {
|
|
22
|
+
ordinals: EnrichedOrdinal[]
|
|
23
|
+
opnsNames: EnrichedOrdinal[]
|
|
24
|
+
bsv21Tokens: TokenBalance[]
|
|
25
|
+
totalBsv: number
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
export function deriveAddress(wif: string): string {
|
|
28
|
-
return PrivateKey.fromWif(wif.trim()).toPublicKey().toAddress()
|
|
29
|
+
return PrivateKey.fromWif(wif.trim()).toPublicKey().toAddress()
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
function getEvent(events: string[], prefix: string): string | undefined {
|
|
32
|
-
const e = events.find((ev) => ev.startsWith(prefix))
|
|
33
|
-
return e ? e.slice(prefix.length) : undefined
|
|
33
|
+
const e = events.find((ev) => ev.startsWith(prefix))
|
|
34
|
+
return e ? e.slice(prefix.length) : undefined
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
function getEvents(events: string[], prefix: string): string[] {
|
|
37
|
-
return events
|
|
38
|
+
return events
|
|
39
|
+
.filter((e) => e.startsWith(prefix))
|
|
40
|
+
.map((e) => e.slice(prefix.length))
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
function enrichOrdinal(out: IndexedOutput): EnrichedOrdinal {
|
|
41
|
-
const events = out.events ?? []
|
|
42
|
-
const origin = getEvent(events,
|
|
43
|
-
const types = getEvents(events,
|
|
44
|
-
const contentType = types.find((t) => t.includes(
|
|
45
|
-
const name = getEvent(events,
|
|
46
|
-
const contentUrl = getServices().ordfs.getContentUrl(origin ?? out.outpoint, {
|
|
44
|
+
const events = out.events ?? []
|
|
45
|
+
const origin = getEvent(events, 'origin:')
|
|
46
|
+
const types = getEvents(events, 'type:')
|
|
47
|
+
const contentType = types.find((t) => t.includes('/')) ?? types[0]
|
|
48
|
+
const name = getEvent(events, 'name:')
|
|
49
|
+
const contentUrl = getServices().ordfs.getContentUrl(origin ?? out.outpoint, {
|
|
50
|
+
raw: true,
|
|
51
|
+
})
|
|
47
52
|
|
|
48
|
-
return { ...out, origin, contentType, name, contentUrl }
|
|
53
|
+
return { ...out, origin, contentType, name, contentUrl }
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
function resolveIconUrl(tokenId: string, icon?: string): string {
|
|
52
|
-
if (!icon) return
|
|
53
|
-
let outpoint = icon
|
|
54
|
-
if (icon.startsWith(
|
|
55
|
-
const txid = tokenId.split(
|
|
56
|
-
outpoint = `${txid}${icon}
|
|
57
|
+
if (!icon) return ''
|
|
58
|
+
let outpoint = icon
|
|
59
|
+
if (icon.startsWith('_')) {
|
|
60
|
+
const txid = tokenId.split('_')[0]
|
|
61
|
+
outpoint = `${txid}${icon}`
|
|
57
62
|
}
|
|
58
|
-
return getServices().ordfs.getContentUrl(outpoint)
|
|
63
|
+
return getServices().ordfs.getContentUrl(outpoint)
|
|
59
64
|
}
|
|
60
65
|
|
|
61
66
|
function enrichTokenBalances(tokens: TokenBalance[]): TokenBalance[] {
|
|
62
67
|
return tokens.map((t) => ({
|
|
63
68
|
...t,
|
|
64
69
|
icon: resolveIconUrl(t.tokenId, t.icon),
|
|
65
|
-
}))
|
|
70
|
+
}))
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
export async function scanAddress(
|
|
69
74
|
address: string,
|
|
70
75
|
onProgress?: (p: ScanProgress) => void,
|
|
71
76
|
): Promise<ScannedAssets> {
|
|
72
|
-
const result = await coreScanAddresses(getServices(), [address], onProgress)
|
|
73
|
-
return toScannedAssets(result)
|
|
77
|
+
const result = await coreScanAddresses(getServices(), [address], onProgress)
|
|
78
|
+
return toScannedAssets(result)
|
|
74
79
|
}
|
|
75
80
|
|
|
76
81
|
export async function scanAddresses(
|
|
77
82
|
addresses: string[],
|
|
78
83
|
onProgress?: (p: ScanProgress) => void,
|
|
79
84
|
): Promise<ScannedAssets> {
|
|
80
|
-
const unique = [...new Set(addresses)]
|
|
81
|
-
const result = await coreScanAddresses(getServices(), unique, onProgress)
|
|
82
|
-
return toScannedAssets(result)
|
|
85
|
+
const unique = [...new Set(addresses)]
|
|
86
|
+
const result = await coreScanAddresses(getServices(), unique, onProgress)
|
|
87
|
+
return toScannedAssets(result)
|
|
83
88
|
}
|
|
84
89
|
|
|
85
90
|
function toScannedAssets(result: ScanResult): ScannedAssets {
|
|
@@ -93,5 +98,5 @@ function toScannedAssets(result: ScanResult): ScannedAssets {
|
|
|
93
98
|
run: result.run,
|
|
94
99
|
totalFundingSats: result.totalFundingSats,
|
|
95
100
|
totalBsv: result.totalFundingSats,
|
|
96
|
-
}
|
|
101
|
+
}
|
|
97
102
|
}
|
package/src/lib/services.ts
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
import { OneSatServices } from
|
|
1
|
+
import { OneSatServices } from '@1sat/client'
|
|
2
2
|
|
|
3
|
-
let _services: OneSatServices | null = null
|
|
4
|
-
let _baseUrl: string | undefined
|
|
3
|
+
let _services: OneSatServices | null = null
|
|
4
|
+
let _baseUrl: string | undefined
|
|
5
5
|
|
|
6
6
|
export function configureServices(baseUrl: string): void {
|
|
7
|
-
_baseUrl = baseUrl
|
|
8
|
-
_services = null
|
|
7
|
+
_baseUrl = baseUrl
|
|
8
|
+
_services = null
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export function getServices(): OneSatServices {
|
|
12
12
|
if (!_services) {
|
|
13
|
-
const url =
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
const url =
|
|
14
|
+
_baseUrl ?? (typeof window !== 'undefined' ? window.location.origin : '')
|
|
15
|
+
if (!url)
|
|
16
|
+
throw new Error('No base URL configured. Call configureServices() first.')
|
|
17
|
+
_services = new OneSatServices('main', url)
|
|
16
18
|
}
|
|
17
|
-
return _services
|
|
19
|
+
return _services
|
|
18
20
|
}
|