@bsv/wallet-toolbox 1.2.31 → 1.2.33
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/docs/client.md +115 -10
- package/docs/wallet.md +115 -10
- package/out/src/WalletSettingsManager.d.ts +2 -9
- package/out/src/WalletSettingsManager.d.ts.map +1 -1
- package/out/src/WalletSettingsManager.js +7 -113
- package/out/src/WalletSettingsManager.js.map +1 -1
- package/out/src/storage/methods/attemptToPostReqsToNetwork.js +1 -1
- package/out/src/storage/methods/attemptToPostReqsToNetwork.js.map +1 -1
- package/out/tsconfig.all.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/WalletSettingsManager.ts +12 -144
- package/src/storage/methods/attemptToPostReqsToNetwork.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bsv/wallet-toolbox",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.33",
|
|
4
4
|
"description": "BRC100 conforming wallet, wallet storage and wallet signer components",
|
|
5
5
|
"main": "./out/src/index.js",
|
|
6
6
|
"types": "./out/src/index.d.ts",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@bsv/auth-express-middleware": "^1.1.2",
|
|
34
34
|
"@bsv/payment-express-middleware": "^1.0.4",
|
|
35
|
-
"@bsv/sdk": "^1.4.
|
|
35
|
+
"@bsv/sdk": "^1.4.17",
|
|
36
36
|
"express": "^4.21.2",
|
|
37
37
|
"knex": "^3.1.0",
|
|
38
38
|
"mysql2": "^3.12.0",
|
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CreateActionInput,
|
|
3
|
-
LockingScript,
|
|
4
|
-
PubKeyHex,
|
|
5
|
-
PushDrop,
|
|
6
|
-
Transaction,
|
|
7
|
-
Utils,
|
|
8
|
-
WalletInterface,
|
|
9
|
-
WalletProtocol
|
|
10
|
-
} from '@bsv/sdk'
|
|
1
|
+
import { LocalKVStore, PubKeyHex, WalletInterface } from '@bsv/sdk'
|
|
11
2
|
|
|
12
3
|
export interface Certifier {
|
|
13
4
|
name: string
|
|
@@ -33,10 +24,7 @@ export interface WalletSettingsManagerConfig {
|
|
|
33
24
|
defaultSettings: WalletSettings
|
|
34
25
|
}
|
|
35
26
|
|
|
36
|
-
const PROTOCOL_ID: WalletProtocol = [2, 'wallet settings']
|
|
37
|
-
const KEY_ID = '1'
|
|
38
27
|
const SETTINGS_BASKET = 'wallet settings'
|
|
39
|
-
const TOKEN_AMOUNT = 1
|
|
40
28
|
|
|
41
29
|
// Defaults can be overridden as needed
|
|
42
30
|
export const DEFAULT_SETTINGS = {
|
|
@@ -44,19 +32,12 @@ export const DEFAULT_SETTINGS = {
|
|
|
44
32
|
trustLevel: 2,
|
|
45
33
|
trustedCertifiers: [
|
|
46
34
|
{
|
|
47
|
-
name: '
|
|
48
|
-
description: '
|
|
49
|
-
iconUrl: 'https://
|
|
35
|
+
name: 'Metanet Trust Services',
|
|
36
|
+
description: 'Registry for protocols, baskets, and certificates types',
|
|
37
|
+
iconUrl: 'https://bsvblockchain.org/favicon.ico',
|
|
50
38
|
identityKey: '03daf815fe38f83da0ad83b5bedc520aa488aef5cbc93a93c67a7fe60406cbffe8',
|
|
51
39
|
trust: 4
|
|
52
40
|
},
|
|
53
|
-
{
|
|
54
|
-
name: 'IdentiCert',
|
|
55
|
-
description: 'Certifies legal first and last name, and photos',
|
|
56
|
-
iconUrl: 'https://identicert.me/favicon.ico',
|
|
57
|
-
trust: 5,
|
|
58
|
-
identityKey: '0295bf1c7842d14babf60daf2c733956c331f9dcb2c79e41f85fd1dda6a3fa4549'
|
|
59
|
-
},
|
|
60
41
|
{
|
|
61
42
|
name: 'SocialCert',
|
|
62
43
|
description: 'Certifies social media handles, phone numbers and emails',
|
|
@@ -93,12 +74,16 @@ export const TESTNET_DEFAULT_SETTINGS: WalletSettings = {
|
|
|
93
74
|
* Manages wallet settings
|
|
94
75
|
*/
|
|
95
76
|
export class WalletSettingsManager {
|
|
77
|
+
kv: LocalKVStore
|
|
78
|
+
|
|
96
79
|
constructor(
|
|
97
80
|
private wallet: WalletInterface,
|
|
98
81
|
private config: WalletSettingsManagerConfig = {
|
|
99
82
|
defaultSettings: DEFAULT_SETTINGS
|
|
100
83
|
}
|
|
101
|
-
) {
|
|
84
|
+
) {
|
|
85
|
+
this.kv = new LocalKVStore(wallet, SETTINGS_BASKET, true)
|
|
86
|
+
}
|
|
102
87
|
|
|
103
88
|
/**
|
|
104
89
|
* Returns a user's wallet settings
|
|
@@ -106,23 +91,7 @@ export class WalletSettingsManager {
|
|
|
106
91
|
* @returns - Wallet settings object
|
|
107
92
|
*/
|
|
108
93
|
async get(): Promise<WalletSettings> {
|
|
109
|
-
|
|
110
|
-
// There should only be one settings token
|
|
111
|
-
const results = await this.wallet.listOutputs({
|
|
112
|
-
basket: SETTINGS_BASKET,
|
|
113
|
-
include: 'locking scripts'
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
// Return defaults if no settings token is found
|
|
117
|
-
if (!results.outputs.length) {
|
|
118
|
-
return this.config.defaultSettings
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const { fields } = PushDrop.decode(
|
|
122
|
-
LockingScript.fromHex(results.outputs[results.outputs.length - 1].lockingScript!)
|
|
123
|
-
)
|
|
124
|
-
// Parse and return settings token
|
|
125
|
-
return JSON.parse(Utils.toUTF8(fields[0]))
|
|
94
|
+
return JSON.parse((await this.kv.get('settings', JSON.stringify(this.config.defaultSettings))) as string)
|
|
126
95
|
}
|
|
127
96
|
|
|
128
97
|
/**
|
|
@@ -131,114 +100,13 @@ export class WalletSettingsManager {
|
|
|
131
100
|
* @param settings - The wallet settings to be stored.
|
|
132
101
|
*/
|
|
133
102
|
async set(settings: WalletSettings): Promise<void> {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
// Build the new locking script with the updated settings JSON.
|
|
137
|
-
const lockingScript = await pushdrop.lock(
|
|
138
|
-
[Utils.toArray(JSON.stringify(settings), 'utf8')],
|
|
139
|
-
PROTOCOL_ID,
|
|
140
|
-
KEY_ID,
|
|
141
|
-
'self'
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
// Consume any existing token and create a new one with the new locking script.
|
|
145
|
-
await this.updateToken(lockingScript)
|
|
103
|
+
await this.kv.set('settings', JSON.stringify(settings))
|
|
146
104
|
}
|
|
147
105
|
|
|
148
106
|
/**
|
|
149
107
|
* Deletes the user's settings token.
|
|
150
108
|
*/
|
|
151
109
|
async delete(): Promise<void> {
|
|
152
|
-
|
|
153
|
-
await this.updateToken()
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Updates a settings token. Any previous token is consumed, and if a new locking script
|
|
158
|
-
* is provided, it replaces what (if anything) was there before.
|
|
159
|
-
*
|
|
160
|
-
* @param newLockingScript - Optional locking script for replacing the settings token.
|
|
161
|
-
* @returns {Promise<boolean>} - True if operation succeeded, throws an error otherwise.
|
|
162
|
-
*/
|
|
163
|
-
private async updateToken(newLockingScript?: LockingScript): Promise<boolean> {
|
|
164
|
-
const pushdrop = new PushDrop(this.wallet)
|
|
165
|
-
|
|
166
|
-
// 1. List the existing token UTXO(s) for the settings basket.
|
|
167
|
-
const existingUtxos = await this.wallet.listOutputs({
|
|
168
|
-
basket: SETTINGS_BASKET,
|
|
169
|
-
include: 'entire transactions'
|
|
170
|
-
})
|
|
171
|
-
|
|
172
|
-
// This is the "create a new token" path — no signAction, just a new locking script.
|
|
173
|
-
if (!existingUtxos.outputs.length) {
|
|
174
|
-
if (!newLockingScript) {
|
|
175
|
-
return true
|
|
176
|
-
}
|
|
177
|
-
await this.wallet.createAction({
|
|
178
|
-
description: 'Create a user settings token',
|
|
179
|
-
outputs: [
|
|
180
|
-
{
|
|
181
|
-
satoshis: TOKEN_AMOUNT,
|
|
182
|
-
lockingScript: newLockingScript.toHex(),
|
|
183
|
-
outputDescription: 'Wallet settings token',
|
|
184
|
-
basket: SETTINGS_BASKET
|
|
185
|
-
}
|
|
186
|
-
],
|
|
187
|
-
options: {
|
|
188
|
-
randomizeOutputs: false,
|
|
189
|
-
acceptDelayedBroadcast: false
|
|
190
|
-
}
|
|
191
|
-
})
|
|
192
|
-
return true
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// 2. Prepare the token UTXO for consumption.
|
|
196
|
-
const tokenOutput = existingUtxos.outputs[existingUtxos.outputs.length - 1]
|
|
197
|
-
const inputToConsume: CreateActionInput = {
|
|
198
|
-
outpoint: tokenOutput.outpoint,
|
|
199
|
-
unlockingScriptLength: 73,
|
|
200
|
-
inputDescription: 'Consume old wallet settings token'
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// 3. Build the outputs array: if a new locking script is provided, add an output.
|
|
204
|
-
const outputs = newLockingScript
|
|
205
|
-
? [
|
|
206
|
-
{
|
|
207
|
-
satoshis: TOKEN_AMOUNT,
|
|
208
|
-
lockingScript: newLockingScript.toHex(),
|
|
209
|
-
outputDescription: 'Wallet settings token',
|
|
210
|
-
basket: SETTINGS_BASKET
|
|
211
|
-
}
|
|
212
|
-
]
|
|
213
|
-
: []
|
|
214
|
-
|
|
215
|
-
// 4. Create a signable transaction action using the inputs and (optionally) outputs.
|
|
216
|
-
const { signableTransaction } = await this.wallet.createAction({
|
|
217
|
-
description: `${newLockingScript ? 'Update' : 'Delete'} a user settings token`,
|
|
218
|
-
inputBEEF: existingUtxos.BEEF!,
|
|
219
|
-
inputs: [inputToConsume], // input index 0
|
|
220
|
-
outputs,
|
|
221
|
-
options: {
|
|
222
|
-
randomizeOutputs: false,
|
|
223
|
-
acceptDelayedBroadcast: false
|
|
224
|
-
}
|
|
225
|
-
})
|
|
226
|
-
const tx = Transaction.fromBEEF(signableTransaction!.tx)
|
|
227
|
-
|
|
228
|
-
// 5. Build and sign the unlocking script for the token being consumed.
|
|
229
|
-
const unlocker = pushdrop.unlock(PROTOCOL_ID, KEY_ID, 'self')
|
|
230
|
-
const unlockingScript = await unlocker.sign(tx, 0)
|
|
231
|
-
|
|
232
|
-
// 6. Sign the transaction using our unlocking script.
|
|
233
|
-
await this.wallet.signAction({
|
|
234
|
-
reference: signableTransaction!.reference,
|
|
235
|
-
spends: {
|
|
236
|
-
0: {
|
|
237
|
-
unlockingScript: unlockingScript.toHex()
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
})
|
|
241
|
-
|
|
242
|
-
return true
|
|
110
|
+
await this.kv.remove('settings')
|
|
243
111
|
}
|
|
244
112
|
}
|
|
@@ -319,7 +319,7 @@ async function confirmDoubleSpend(
|
|
|
319
319
|
}
|
|
320
320
|
}
|
|
321
321
|
}
|
|
322
|
-
ar.competingTxs = [...competingTxids].slice(-
|
|
322
|
+
ar.competingTxs = [...competingTxids].slice(-24) // keep at most 24, if they were sorted by time, keep newest
|
|
323
323
|
note.competingTxs = ar.competingTxs.join(',')
|
|
324
324
|
}
|
|
325
325
|
req.addHistoryNote(note)
|