@bsv/wallet-toolbox 1.3.23 → 1.3.25
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 +99 -59
- package/docs/storage.md +55 -75
- package/docs/wallet.md +99 -59
- package/mobile/out/src/Wallet.d.ts +1 -1
- package/mobile/out/src/Wallet.d.ts.map +1 -1
- package/mobile/out/src/Wallet.js +16 -6
- package/mobile/out/src/Wallet.js.map +1 -1
- package/mobile/out/src/monitor/Monitor.d.ts.map +1 -1
- package/mobile/out/src/monitor/Monitor.js +6 -4
- package/mobile/out/src/monitor/Monitor.js.map +1 -1
- package/mobile/out/src/monitor/tasks/TaskNewHeader.d.ts +1 -1
- package/mobile/out/src/monitor/tasks/TaskNewHeader.d.ts.map +1 -1
- package/mobile/out/src/monitor/tasks/TaskServiceCallHistory.d.ts +12 -0
- package/mobile/out/src/monitor/tasks/TaskServiceCallHistory.d.ts.map +1 -0
- package/mobile/out/src/monitor/tasks/TaskServiceCallHistory.js +23 -0
- package/mobile/out/src/monitor/tasks/TaskServiceCallHistory.js.map +1 -0
- package/mobile/out/src/sdk/WalletServices.interfaces.d.ts +2 -0
- package/mobile/out/src/sdk/WalletServices.interfaces.d.ts.map +1 -1
- package/mobile/out/src/sdk/WalletStorage.interfaces.d.ts +19 -1
- package/mobile/out/src/sdk/WalletStorage.interfaces.d.ts.map +1 -1
- package/mobile/out/src/services/ServiceCollection.d.ts +38 -0
- package/mobile/out/src/services/ServiceCollection.d.ts.map +1 -1
- package/mobile/out/src/services/ServiceCollection.js +85 -0
- package/mobile/out/src/services/ServiceCollection.js.map +1 -1
- package/mobile/out/src/services/Services.d.ts +11 -2
- package/mobile/out/src/services/Services.d.ts.map +1 -1
- package/mobile/out/src/services/Services.js +159 -68
- package/mobile/out/src/services/Services.js.map +1 -1
- package/mobile/out/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.d.ts.map +1 -0
- package/mobile/out/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.js.map +1 -0
- package/mobile/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.d.ts +1 -1
- package/mobile/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.d.ts.map +1 -1
- package/mobile/out/src/services/chaintracker/chaintracks/index.d.ts +1 -1
- package/mobile/out/src/services/chaintracker/chaintracks/index.d.ts.map +1 -1
- package/mobile/out/src/services/chaintracker/chaintracks/index.js +1 -1
- package/mobile/out/src/services/chaintracker/chaintracks/index.js.map +1 -1
- package/mobile/out/src/services/createDefaultWalletServicesOptions.d.ts +1 -0
- package/mobile/out/src/services/createDefaultWalletServicesOptions.d.ts.map +1 -1
- package/mobile/out/src/services/createDefaultWalletServicesOptions.js +15 -1
- package/mobile/out/src/services/createDefaultWalletServicesOptions.js.map +1 -1
- package/mobile/out/src/services/providers/ARC.d.ts +3 -2
- package/mobile/out/src/services/providers/ARC.d.ts.map +1 -1
- package/mobile/out/src/services/providers/ARC.js +5 -4
- package/mobile/out/src/services/providers/ARC.js.map +1 -1
- package/mobile/out/src/signer/methods/internalizeAction.d.ts +2 -2
- package/mobile/out/src/signer/methods/internalizeAction.d.ts.map +1 -1
- package/mobile/out/src/signer/methods/internalizeAction.js +3 -13
- package/mobile/out/src/signer/methods/internalizeAction.js.map +1 -1
- package/mobile/out/src/storage/StorageProvider.d.ts +5 -6
- package/mobile/out/src/storage/StorageProvider.d.ts.map +1 -1
- package/mobile/out/src/storage/StorageProvider.js +75 -101
- package/mobile/out/src/storage/StorageProvider.js.map +1 -1
- package/mobile/out/src/storage/WalletStorageManager.d.ts +2 -2
- package/mobile/out/src/storage/WalletStorageManager.d.ts.map +1 -1
- package/mobile/out/src/storage/methods/createAction.d.ts.map +1 -1
- package/mobile/out/src/storage/methods/createAction.js +5 -1
- package/mobile/out/src/storage/methods/createAction.js.map +1 -1
- package/mobile/out/src/storage/methods/generateChange.d.ts +0 -24
- package/mobile/out/src/storage/methods/generateChange.d.ts.map +1 -1
- package/mobile/out/src/storage/methods/generateChange.js +2 -50
- package/mobile/out/src/storage/methods/generateChange.js.map +1 -1
- package/mobile/out/src/storage/methods/getBeefForTransaction.js +3 -2
- package/mobile/out/src/storage/methods/getBeefForTransaction.js.map +1 -1
- package/mobile/out/src/storage/methods/internalizeAction.d.ts +2 -10
- package/mobile/out/src/storage/methods/internalizeAction.d.ts.map +1 -1
- package/mobile/out/src/storage/methods/internalizeAction.js +17 -1
- package/mobile/out/src/storage/methods/internalizeAction.js.map +1 -1
- package/mobile/out/src/storage/methods/processAction.d.ts +16 -1
- package/mobile/out/src/storage/methods/processAction.d.ts.map +1 -1
- package/mobile/out/src/storage/methods/processAction.js +4 -1
- package/mobile/out/src/storage/methods/processAction.js.map +1 -1
- package/mobile/out/src/storage/methods/utils.d.ts +25 -0
- package/mobile/out/src/storage/methods/utils.d.ts.map +1 -0
- package/mobile/out/src/storage/methods/utils.js +53 -0
- package/mobile/out/src/storage/methods/utils.js.map +1 -0
- package/mobile/out/src/storage/remoting/StorageClient.d.ts +2 -2
- package/mobile/out/src/storage/remoting/StorageClient.d.ts.map +1 -1
- package/mobile/out/src/storage/remoting/StorageClient.js.map +1 -1
- package/mobile/out/src/storage/remoting/StorageMobile.d.ts +2 -2
- package/mobile/out/src/storage/remoting/StorageMobile.d.ts.map +1 -1
- package/mobile/out/src/storage/remoting/StorageMobile.js.map +1 -1
- package/mobile/out/src/utility/utilityHelpers.d.ts +1 -1
- package/mobile/out/src/utility/utilityHelpers.d.ts.map +1 -1
- package/mobile/out/src/utility/utilityHelpers.js +3 -3
- package/mobile/out/src/utility/utilityHelpers.js.map +1 -1
- package/mobile/package-lock.json +7 -6
- package/mobile/package.json +2 -2
- package/out/src/Wallet.d.ts +1 -1
- package/out/src/Wallet.d.ts.map +1 -1
- package/out/src/Wallet.js +16 -6
- package/out/src/Wallet.js.map +1 -1
- package/out/src/monitor/Monitor.d.ts.map +1 -1
- package/out/src/monitor/Monitor.js +6 -4
- package/out/src/monitor/Monitor.js.map +1 -1
- package/out/src/monitor/tasks/TaskNewHeader.d.ts +1 -1
- package/out/src/monitor/tasks/TaskNewHeader.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskServiceCallHistory.d.ts +12 -0
- package/out/src/monitor/tasks/TaskServiceCallHistory.d.ts.map +1 -0
- package/out/src/monitor/tasks/TaskServiceCallHistory.js +23 -0
- package/out/src/monitor/tasks/TaskServiceCallHistory.js.map +1 -0
- package/out/src/sdk/WalletServices.interfaces.d.ts +2 -0
- package/out/src/sdk/WalletServices.interfaces.d.ts.map +1 -1
- package/out/src/sdk/WalletStorage.interfaces.d.ts +19 -1
- package/out/src/sdk/WalletStorage.interfaces.d.ts.map +1 -1
- package/out/src/services/ServiceCollection.d.ts +38 -0
- package/out/src/services/ServiceCollection.d.ts.map +1 -1
- package/out/src/services/ServiceCollection.js +85 -0
- package/out/src/services/ServiceCollection.js.map +1 -1
- package/out/src/services/Services.d.ts +11 -2
- package/out/src/services/Services.d.ts.map +1 -1
- package/out/src/services/Services.js +159 -68
- package/out/src/services/Services.js.map +1 -1
- package/out/src/services/__tests/ArcGorillaPool.man.test.d.ts +2 -0
- package/out/src/services/__tests/ArcGorillaPool.man.test.d.ts.map +1 -0
- package/out/src/services/__tests/ArcGorillaPool.man.test.js +93 -0
- package/out/src/services/__tests/ArcGorillaPool.man.test.js.map +1 -0
- package/out/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.d.ts.map +1 -0
- package/out/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.js.map +1 -0
- package/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.d.ts +1 -1
- package/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/index.d.ts +1 -1
- package/out/src/services/chaintracker/chaintracks/index.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/index.js +1 -1
- package/out/src/services/chaintracker/chaintracks/index.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.d.ts +144 -0
- package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.d.ts.map +1 -0
- package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.js +463 -0
- package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.js.map +1 -0
- package/out/src/services/chaintracker/chaintracks/util/dirtyHashes.d.ts +20 -0
- package/out/src/services/chaintracker/chaintracks/util/dirtyHashes.d.ts.map +1 -0
- package/out/src/services/chaintracker/chaintracks/util/dirtyHashes.js +31 -0
- package/out/src/services/chaintracker/chaintracks/util/dirtyHashes.js.map +1 -0
- package/out/src/services/createDefaultWalletServicesOptions.d.ts +1 -0
- package/out/src/services/createDefaultWalletServicesOptions.d.ts.map +1 -1
- package/out/src/services/createDefaultWalletServicesOptions.js +15 -1
- package/out/src/services/createDefaultWalletServicesOptions.js.map +1 -1
- package/out/src/services/providers/ARC.d.ts +3 -2
- package/out/src/services/providers/ARC.d.ts.map +1 -1
- package/out/src/services/providers/ARC.js +5 -4
- package/out/src/services/providers/ARC.js.map +1 -1
- package/out/src/signer/methods/internalizeAction.d.ts +2 -2
- package/out/src/signer/methods/internalizeAction.d.ts.map +1 -1
- package/out/src/signer/methods/internalizeAction.js +3 -13
- package/out/src/signer/methods/internalizeAction.js.map +1 -1
- package/out/src/storage/StorageKnex.d.ts.map +1 -1
- package/out/src/storage/StorageKnex.js +50 -2
- package/out/src/storage/StorageKnex.js.map +1 -1
- package/out/src/storage/StorageProvider.d.ts +5 -6
- package/out/src/storage/StorageProvider.d.ts.map +1 -1
- package/out/src/storage/StorageProvider.js +75 -101
- package/out/src/storage/StorageProvider.js.map +1 -1
- package/out/src/storage/WalletStorageManager.d.ts +2 -2
- package/out/src/storage/WalletStorageManager.d.ts.map +1 -1
- package/out/src/storage/__test/StorageIdb.test.js +1 -0
- package/out/src/storage/__test/StorageIdb.test.js.map +1 -1
- package/out/src/storage/__test/adminStats.man.test.js +2 -0
- package/out/src/storage/__test/adminStats.man.test.js.map +1 -1
- package/out/src/storage/methods/createAction.d.ts.map +1 -1
- package/out/src/storage/methods/createAction.js +5 -1
- package/out/src/storage/methods/createAction.js.map +1 -1
- package/out/src/storage/methods/generateChange.d.ts +0 -24
- package/out/src/storage/methods/generateChange.d.ts.map +1 -1
- package/out/src/storage/methods/generateChange.js +2 -50
- package/out/src/storage/methods/generateChange.js.map +1 -1
- package/out/src/storage/methods/getBeefForTransaction.js +3 -2
- package/out/src/storage/methods/getBeefForTransaction.js.map +1 -1
- package/out/src/storage/methods/internalizeAction.d.ts +2 -10
- package/out/src/storage/methods/internalizeAction.d.ts.map +1 -1
- package/out/src/storage/methods/internalizeAction.js +17 -1
- package/out/src/storage/methods/internalizeAction.js.map +1 -1
- package/out/src/storage/methods/processAction.d.ts +16 -1
- package/out/src/storage/methods/processAction.d.ts.map +1 -1
- package/out/src/storage/methods/processAction.js +4 -1
- package/out/src/storage/methods/processAction.js.map +1 -1
- package/out/src/storage/methods/utils.Buffer.d.ts +21 -0
- package/out/src/storage/methods/utils.Buffer.d.ts.map +1 -0
- package/out/src/storage/methods/utils.Buffer.js +37 -0
- package/out/src/storage/methods/utils.Buffer.js.map +1 -0
- package/out/src/storage/methods/utils.d.ts +25 -0
- package/out/src/storage/methods/utils.d.ts.map +1 -0
- package/out/src/storage/methods/utils.js +53 -0
- package/out/src/storage/methods/utils.js.map +1 -0
- package/out/src/storage/remoting/StorageClient.d.ts +2 -2
- package/out/src/storage/remoting/StorageClient.d.ts.map +1 -1
- package/out/src/storage/remoting/StorageClient.js.map +1 -1
- package/out/src/storage/remoting/StorageMobile.d.ts +2 -2
- package/out/src/storage/remoting/StorageMobile.d.ts.map +1 -1
- package/out/src/storage/remoting/StorageMobile.js.map +1 -1
- package/out/src/storage/schema/KnexMigrations.d.ts.map +1 -1
- package/out/src/storage/schema/KnexMigrations.js +12 -0
- package/out/src/storage/schema/KnexMigrations.js.map +1 -1
- package/out/src/utility/Format.d.ts +14 -0
- package/out/src/utility/Format.d.ts.map +1 -0
- package/out/src/utility/Format.js +167 -0
- package/out/src/utility/Format.js.map +1 -0
- package/out/src/utility/utilityHelpers.d.ts +1 -1
- package/out/src/utility/utilityHelpers.d.ts.map +1 -1
- package/out/src/utility/utilityHelpers.js +3 -3
- package/out/src/utility/utilityHelpers.js.map +1 -1
- package/out/test/Wallet/local/localWallet.man.test.js +12 -16
- package/out/test/Wallet/local/localWallet.man.test.js.map +1 -1
- package/out/test/Wallet/support/operations.man.test.js +105 -135
- package/out/test/Wallet/support/operations.man.test.js.map +1 -1
- package/out/test/Wallet/support/reqErrorReview.2025.05.06.man.test.d.ts +2 -0
- package/out/test/Wallet/support/reqErrorReview.2025.05.06.man.test.d.ts.map +1 -0
- package/out/test/Wallet/support/reqErrorReview.2025.05.06.man.test.js +385 -0
- package/out/test/Wallet/support/reqErrorReview.2025.05.06.man.test.js.map +1 -0
- package/out/test/storage/KnexMigrations.test.js +1 -1
- package/out/test/storage/KnexMigrations.test.js.map +1 -1
- package/out/test/utils/TestUtilsWalletStorage.d.ts +5 -0
- package/out/test/utils/TestUtilsWalletStorage.d.ts.map +1 -1
- package/out/test/utils/TestUtilsWalletStorage.js +20 -0
- package/out/test/utils/TestUtilsWalletStorage.js.map +1 -1
- package/out/tsconfig.all.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/Wallet.ts +25 -10
- package/src/monitor/Monitor.ts +6 -4
- package/src/monitor/tasks/TaskNewHeader.ts +1 -1
- package/src/monitor/tasks/TaskServiceCallHistory.ts +26 -0
- package/src/sdk/WalletServices.interfaces.ts +2 -0
- package/src/sdk/WalletStorage.interfaces.ts +21 -1
- package/src/services/ServiceCollection.ts +121 -0
- package/src/services/Services.ts +157 -71
- package/src/services/__tests/ArcGorillaPool.man.test.ts +108 -0
- package/src/services/chaintracker/chaintracks/ChaintracksServiceClient.ts +1 -1
- package/src/services/chaintracker/chaintracks/index.ts +1 -1
- package/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.ts +490 -0
- package/src/services/chaintracker/chaintracks/util/dirtyHashes.ts +29 -0
- package/src/services/createDefaultWalletServicesOptions.ts +16 -1
- package/src/services/providers/ARC.ts +8 -6
- package/src/signer/methods/internalizeAction.ts +6 -16
- package/src/storage/StorageKnex.ts +25 -1
- package/src/storage/StorageProvider.ts +44 -32
- package/src/storage/WalletStorageManager.ts +1 -1
- package/src/storage/__test/StorageIdb.test.ts +1 -0
- package/src/storage/__test/adminStats.man.test.ts +2 -0
- package/src/storage/methods/createAction.ts +5 -3
- package/src/storage/methods/generateChange.ts +1 -54
- package/src/storage/methods/getBeefForTransaction.ts +10 -2
- package/src/storage/methods/internalizeAction.ts +23 -14
- package/src/storage/methods/processAction.ts +5 -2
- package/src/storage/methods/utils.Buffer.ts +33 -0
- package/src/storage/methods/utils.ts +56 -0
- package/src/storage/remoting/StorageClient.ts +2 -2
- package/src/storage/remoting/StorageMobile.ts +2 -2
- package/src/storage/schema/KnexMigrations.ts +13 -0
- package/src/utility/Format.ts +133 -0
- package/src/utility/utilityHelpers.ts +2 -2
- package/test/Wallet/local/localWallet.man.test.ts +13 -16
- package/test/Wallet/support/operations.man.test.ts +118 -123
- package/test/Wallet/support/reqErrorReview.2025.05.06.man.test.ts +359 -0
- package/test/storage/KnexMigrations.test.ts +1 -1
- package/test/utils/TestUtilsWalletStorage.ts +23 -0
- package/mobile/out/src/services/chaintracker/chaintracks/BlockHeaderApi.d.ts.map +0 -1
- package/mobile/out/src/services/chaintracker/chaintracks/BlockHeaderApi.js.map +0 -1
- package/out/src/services/chaintracker/chaintracks/BlockHeaderApi.d.ts.map +0 -1
- package/out/src/services/chaintracker/chaintracks/BlockHeaderApi.js.map +0 -1
- /package/mobile/out/src/services/chaintracker/chaintracks/{BlockHeaderApi.d.ts → Api/BlockHeaderApi.d.ts} +0 -0
- /package/mobile/out/src/services/chaintracker/chaintracks/{BlockHeaderApi.js → Api/BlockHeaderApi.js} +0 -0
- /package/out/src/services/chaintracker/chaintracks/{BlockHeaderApi.d.ts → Api/BlockHeaderApi.d.ts} +0 -0
- /package/out/src/services/chaintracker/chaintracks/{BlockHeaderApi.js → Api/BlockHeaderApi.js} +0 -0
- /package/src/services/chaintracker/chaintracks/{BlockHeaderApi.ts → Api/BlockHeaderApi.ts} +0 -0
|
@@ -14,6 +14,9 @@ import {
|
|
|
14
14
|
AbortActionArgs
|
|
15
15
|
} from '@bsv/sdk'
|
|
16
16
|
import {
|
|
17
|
+
asArray,
|
|
18
|
+
asString,
|
|
19
|
+
sdk,
|
|
17
20
|
TableCertificateX,
|
|
18
21
|
TableMonitorEvent,
|
|
19
22
|
TableOutput,
|
|
@@ -23,11 +26,12 @@ import {
|
|
|
23
26
|
TableProvenTxReq,
|
|
24
27
|
TableProvenTxReqDynamics,
|
|
25
28
|
TableTransaction,
|
|
26
|
-
TableTxLabel
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
TableTxLabel,
|
|
30
|
+
verifyId,
|
|
31
|
+
verifyOne,
|
|
32
|
+
verifyOneOrNone,
|
|
33
|
+
verifyTruthy
|
|
34
|
+
} from '../index.client'
|
|
31
35
|
import { getBeefForTransaction } from './methods/getBeefForTransaction'
|
|
32
36
|
import { GetReqsAndBeefDetail, GetReqsAndBeefResult, processAction } from './methods/processAction'
|
|
33
37
|
import { attemptToPostReqsToNetwork, PostReqsToNetworkResult } from './methods/attemptToPostReqsToNetwork'
|
|
@@ -166,7 +170,7 @@ export abstract class StorageProvider extends StorageReaderWriter implements sdk
|
|
|
166
170
|
return r
|
|
167
171
|
}
|
|
168
172
|
|
|
169
|
-
async internalizeAction(auth: sdk.AuthId, args: InternalizeActionArgs): Promise<
|
|
173
|
+
async internalizeAction(auth: sdk.AuthId, args: InternalizeActionArgs): Promise<sdk.StorageInternalizeActionResult> {
|
|
170
174
|
return await internalizeAction(this, auth, args)
|
|
171
175
|
}
|
|
172
176
|
|
|
@@ -409,10 +413,11 @@ export abstract class StorageProvider extends StorageReaderWriter implements sdk
|
|
|
409
413
|
mergeToBeef?: Beef,
|
|
410
414
|
trustSelf?: TrustSelf,
|
|
411
415
|
knownTxids?: string[],
|
|
412
|
-
trx?: sdk.TrxToken
|
|
416
|
+
trx?: sdk.TrxToken,
|
|
417
|
+
requiredLevels?: number
|
|
413
418
|
): Promise<Beef> {
|
|
414
|
-
const beef = await this.getValidBeefForTxid(txid, mergeToBeef, trustSelf, knownTxids, trx)
|
|
415
|
-
if (!beef) throw new sdk.WERR_INVALID_PARAMETER('txid',
|
|
419
|
+
const beef = await this.getValidBeefForTxid(txid, mergeToBeef, trustSelf, knownTxids, trx, requiredLevels)
|
|
420
|
+
if (!beef) throw new sdk.WERR_INVALID_PARAMETER('txid', `known to storage. ${txid} is not known.`)
|
|
416
421
|
return beef
|
|
417
422
|
}
|
|
418
423
|
|
|
@@ -421,43 +426,50 @@ export abstract class StorageProvider extends StorageReaderWriter implements sdk
|
|
|
421
426
|
mergeToBeef?: Beef,
|
|
422
427
|
trustSelf?: TrustSelf,
|
|
423
428
|
knownTxids?: string[],
|
|
424
|
-
trx?: sdk.TrxToken
|
|
429
|
+
trx?: sdk.TrxToken,
|
|
430
|
+
requiredLevels?: number
|
|
425
431
|
): Promise<Beef | undefined> {
|
|
426
432
|
const beef = mergeToBeef || new Beef()
|
|
427
433
|
|
|
428
434
|
const r = await this.getProvenOrRawTx(txid, trx)
|
|
429
435
|
if (r.proven) {
|
|
430
|
-
if (
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
+
if (requiredLevels) {
|
|
437
|
+
r.rawTx = r.proven.rawTx
|
|
438
|
+
} else {
|
|
439
|
+
if (trustSelf === 'known') beef.mergeTxidOnly(txid)
|
|
440
|
+
else {
|
|
441
|
+
beef.mergeRawTx(r.proven.rawTx)
|
|
442
|
+
const mp = new EntityProvenTx(r.proven).getMerklePath()
|
|
443
|
+
beef.mergeBump(mp)
|
|
444
|
+
return beef
|
|
445
|
+
}
|
|
436
446
|
}
|
|
437
447
|
}
|
|
438
448
|
|
|
439
|
-
if (r.rawTx
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
449
|
+
if (!r.rawTx) return undefined
|
|
450
|
+
|
|
451
|
+
if (trustSelf === 'known') {
|
|
452
|
+
beef.mergeTxidOnly(txid)
|
|
453
|
+
} else {
|
|
454
|
+
beef.mergeRawTx(r.rawTx)
|
|
455
|
+
if (r.inputBEEF) beef.mergeBeef(r.inputBEEF)
|
|
456
|
+
const tx = Transaction.fromBinary(r.rawTx)
|
|
457
|
+
if (requiredLevels) requiredLevels--
|
|
458
|
+
for (const input of tx.inputs) {
|
|
459
|
+
const btx = beef.findTxid(input.sourceTXID!)
|
|
460
|
+
if (!btx) {
|
|
461
|
+
if (!requiredLevels && knownTxids && knownTxids.indexOf(input.sourceTXID!) > -1)
|
|
462
|
+
beef.mergeTxidOnly(input.sourceTXID!)
|
|
463
|
+
else await this.getValidBeefForKnownTxid(input.sourceTXID!, beef, trustSelf, knownTxids, trx, requiredLevels)
|
|
451
464
|
}
|
|
452
|
-
return beef
|
|
453
465
|
}
|
|
454
466
|
}
|
|
455
|
-
|
|
456
|
-
return undefined
|
|
467
|
+
return beef
|
|
457
468
|
}
|
|
458
469
|
|
|
459
470
|
async getBeefForTransaction(txid: string, options: sdk.StorageGetBeefOptions): Promise<Beef> {
|
|
460
|
-
|
|
471
|
+
const beef = await getBeefForTransaction(this, txid, options)
|
|
472
|
+
return beef
|
|
461
473
|
}
|
|
462
474
|
|
|
463
475
|
async findMonitorEventById(id: number, trx?: sdk.TrxToken): Promise<TableMonitorEvent | undefined> {
|
|
@@ -438,7 +438,7 @@ export class WalletStorageManager implements sdk.WalletStorage {
|
|
|
438
438
|
return await writer.createAction(auth, vargs)
|
|
439
439
|
})
|
|
440
440
|
}
|
|
441
|
-
async internalizeAction(args: InternalizeActionArgs): Promise<
|
|
441
|
+
async internalizeAction(args: InternalizeActionArgs): Promise<sdk.StorageInternalizeActionResult> {
|
|
442
442
|
sdk.validateInternalizeActionArgs(args)
|
|
443
443
|
return await this.runAsWriter(async writer => {
|
|
444
444
|
const auth = await this.getAuth(true)
|
|
@@ -17,6 +17,7 @@ describe('StorageIdb tests', () => {
|
|
|
17
17
|
})
|
|
18
18
|
|
|
19
19
|
test('1', async () => {
|
|
20
|
+
// TODO: THIS TEST PASSES WHEN Describe is run alone, but fails to exit cleanly when run with `npm run test`
|
|
20
21
|
if (Setup.noEnv('test')) return
|
|
21
22
|
const env = Setup.getEnv('test')
|
|
22
23
|
const wallet = await SetupClient.createWalletClientNoEnv({
|
|
@@ -4,6 +4,7 @@ import { Setup } from '../../Setup'
|
|
|
4
4
|
import { StorageKnex } from '../StorageKnex'
|
|
5
5
|
import { AuthFetch, WalletInterface } from '@bsv/sdk'
|
|
6
6
|
import { StorageAdminStats, StorageClient } from '../index.client'
|
|
7
|
+
import { Format } from '../../utility/Format'
|
|
7
8
|
|
|
8
9
|
describe('storage adminStats tests', () => {
|
|
9
10
|
jest.setTimeout(99999999)
|
|
@@ -36,6 +37,7 @@ describe('storage adminStats tests', () => {
|
|
|
36
37
|
|
|
37
38
|
test('0 adminStats StorageKnex', async () => {
|
|
38
39
|
const r = await storage.adminStats(env.identityKey)
|
|
40
|
+
console.log(Format.toLogStringAdminStats(r))
|
|
39
41
|
expect(r.requestedBy).toBe(env.identityKey)
|
|
40
42
|
expect(r.usersTotal).toBeGreaterThan(0)
|
|
41
43
|
})
|
|
@@ -18,8 +18,6 @@ import {
|
|
|
18
18
|
randomBytesBase64,
|
|
19
19
|
sdk,
|
|
20
20
|
sha256Hash,
|
|
21
|
-
stampLog,
|
|
22
|
-
stampLogFormat,
|
|
23
21
|
StorageProvider,
|
|
24
22
|
TableOutput,
|
|
25
23
|
TableOutputBasket,
|
|
@@ -552,7 +550,8 @@ async function validateRequiredInputs(
|
|
|
552
550
|
...input,
|
|
553
551
|
vin,
|
|
554
552
|
satoshis: -1,
|
|
555
|
-
lockingScript: new Script()
|
|
553
|
+
lockingScript: new Script(),
|
|
554
|
+
output: undefined
|
|
556
555
|
}))
|
|
557
556
|
|
|
558
557
|
const trustSelf = vargs.options.trustSelf === 'known'
|
|
@@ -603,6 +602,9 @@ async function validateRequiredInputs(
|
|
|
603
602
|
const { txid, vout } = input.outpoint
|
|
604
603
|
const output = verifyOneOrNone(await storage.findOutputs({ partial: { userId, txid, vout } }))
|
|
605
604
|
if (output) {
|
|
605
|
+
if (output.change) {
|
|
606
|
+
throw new sdk.WERR_INVALID_PARAMETER(`inputs[${input.vin}]`, 'an unmanaged input. Change outputs are managed by your wallet.')
|
|
607
|
+
}
|
|
606
608
|
input.output = output
|
|
607
609
|
if (!Array.isArray(output.lockingScript) || !Number.isInteger(output.satoshis))
|
|
608
610
|
throw new sdk.WERR_INVALID_PARAMETER(`${txid}.${vout}`, 'output with valid lockingScript and satoshis')
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { sdk, validateStorageFeeModel } from '../../index.client'
|
|
2
|
+
import { transactionSize } from './utils'
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* An output of this satoshis amount will be adjusted to the largest fundable amount.
|
|
@@ -545,57 +546,3 @@ export function generateChangeSdkMakeStorage(availableChange: GenerateChangeSdkC
|
|
|
545
546
|
|
|
546
547
|
return { allocateChangeInput, releaseChangeInput, getLog }
|
|
547
548
|
}
|
|
548
|
-
|
|
549
|
-
/**
|
|
550
|
-
* Returns the byte size required to encode number as Bitcoin VarUint
|
|
551
|
-
* @publicbody
|
|
552
|
-
*/
|
|
553
|
-
export function varUintSize(val: number): 1 | 3 | 5 | 9 {
|
|
554
|
-
if (val < 0) throw new sdk.WERR_INVALID_PARAMETER('varUint', 'non-negative')
|
|
555
|
-
return val <= 0xfc ? 1 : val <= 0xffff ? 3 : val <= 0xffffffff ? 5 : 9
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
/**
|
|
559
|
-
* @param scriptSize byte length of input script
|
|
560
|
-
* @returns serialized byte length a transaction input
|
|
561
|
-
*/
|
|
562
|
-
export function transactionInputSize(scriptSize: number): number {
|
|
563
|
-
return (
|
|
564
|
-
32 + // txid
|
|
565
|
-
4 + // vout
|
|
566
|
-
varUintSize(scriptSize) + // script length, this is already in bytes
|
|
567
|
-
scriptSize + // script
|
|
568
|
-
4
|
|
569
|
-
) // sequence number
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
/**
|
|
573
|
-
* @param scriptSize byte length of output script
|
|
574
|
-
* @returns serialized byte length a transaction output
|
|
575
|
-
*/
|
|
576
|
-
export function transactionOutputSize(scriptSize: number): number {
|
|
577
|
-
return (
|
|
578
|
-
varUintSize(scriptSize) + // output script length, from script encoded as hex string
|
|
579
|
-
scriptSize + // output script
|
|
580
|
-
8
|
|
581
|
-
) // output amount (satoshis)
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
/**
|
|
585
|
-
* Compute the serialized binary transaction size in bytes
|
|
586
|
-
* given the number of inputs and outputs,
|
|
587
|
-
* and the size of each script.
|
|
588
|
-
* @param inputs array of input script lengths, in bytes
|
|
589
|
-
* @param outputs array of output script lengths, in bytes
|
|
590
|
-
* @returns total transaction size in bytes
|
|
591
|
-
*/
|
|
592
|
-
export function transactionSize(inputs: number[], outputs: number[]): number {
|
|
593
|
-
return (
|
|
594
|
-
4 + // Version
|
|
595
|
-
varUintSize(inputs.length) + // Number of inputs
|
|
596
|
-
inputs.reduce((a, e) => a + transactionInputSize(e), 0) + // all inputs
|
|
597
|
-
varUintSize(outputs.length) + // Number of outputs
|
|
598
|
-
outputs.reduce((a, e) => a + transactionOutputSize(e), 0) + // all outputs
|
|
599
|
-
4
|
|
600
|
-
) // lock time
|
|
601
|
-
}
|
|
@@ -71,7 +71,15 @@ async function mergeBeefForTransactionRecurse(
|
|
|
71
71
|
|
|
72
72
|
if (!options.ignoreStorage) {
|
|
73
73
|
// if we can use storage, ask storage if it has the txid
|
|
74
|
-
const
|
|
74
|
+
const requiredLevels = options.minProofLevel === undefined ? undefined : options.minProofLevel + recursionDepth
|
|
75
|
+
const knownBeef = await storage.getValidBeefForTxid(
|
|
76
|
+
txid,
|
|
77
|
+
beef,
|
|
78
|
+
options.trustSelf,
|
|
79
|
+
options.knownTxids,
|
|
80
|
+
undefined,
|
|
81
|
+
requiredLevels
|
|
82
|
+
)
|
|
75
83
|
if (knownBeef) return knownBeef
|
|
76
84
|
}
|
|
77
85
|
|
|
@@ -82,7 +90,7 @@ async function mergeBeefForTransactionRecurse(
|
|
|
82
90
|
// to find it and if it has a proof, remember it.
|
|
83
91
|
const r = await getProvenOrRawTxFromServices(storage, txid, options)
|
|
84
92
|
|
|
85
|
-
if (r.proven && options.minProofLevel && options.minProofLevel > recursionDepth) {
|
|
93
|
+
if (r.proven && options.minProofLevel !== undefined && options.minProofLevel > recursionDepth) {
|
|
86
94
|
// ignore proof at this recursion depth
|
|
87
95
|
r.proven = undefined
|
|
88
96
|
}
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
WalletPayment,
|
|
6
6
|
BasketInsertion,
|
|
7
7
|
InternalizeActionArgs,
|
|
8
|
-
InternalizeActionResult,
|
|
9
8
|
TransactionOutput,
|
|
10
9
|
Beef
|
|
11
10
|
} from '@bsv/sdk'
|
|
@@ -13,7 +12,6 @@ import {
|
|
|
13
12
|
EntityProvenTxReq,
|
|
14
13
|
randomBytesBase64,
|
|
15
14
|
sdk,
|
|
16
|
-
stampLog,
|
|
17
15
|
StorageProvider,
|
|
18
16
|
TableOutput,
|
|
19
17
|
TableOutputBasket,
|
|
@@ -22,15 +20,7 @@ import {
|
|
|
22
20
|
verifyOne,
|
|
23
21
|
verifyOneOrNone
|
|
24
22
|
} from '../../index.client'
|
|
25
|
-
|
|
26
|
-
export interface StorageInternalizeActionResult extends InternalizeActionResult {
|
|
27
|
-
/** true if internalizing outputs on an existing storage transaction */
|
|
28
|
-
isMerge: boolean
|
|
29
|
-
/** txid of transaction being internalized */
|
|
30
|
-
txid: string
|
|
31
|
-
/** net change in change balance for user due to this internalization */
|
|
32
|
-
satoshis: number
|
|
33
|
-
}
|
|
23
|
+
import { shareReqsWithWorld } from './processAction'
|
|
34
24
|
|
|
35
25
|
/**
|
|
36
26
|
* Internalize Action allows a wallet to take ownership of outputs in a pre-existing transaction.
|
|
@@ -62,7 +52,7 @@ export async function internalizeAction(
|
|
|
62
52
|
storage: StorageProvider,
|
|
63
53
|
auth: sdk.AuthId,
|
|
64
54
|
args: InternalizeActionArgs
|
|
65
|
-
): Promise<
|
|
55
|
+
): Promise<sdk.StorageInternalizeActionResult> {
|
|
66
56
|
const ctx = new InternalizeActionContext(storage, auth, args)
|
|
67
57
|
await ctx.asyncSetup()
|
|
68
58
|
|
|
@@ -94,7 +84,7 @@ interface WalletPaymentX extends WalletPayment {
|
|
|
94
84
|
|
|
95
85
|
class InternalizeActionContext {
|
|
96
86
|
/** result to be returned */
|
|
97
|
-
r: StorageInternalizeActionResult
|
|
87
|
+
r: sdk.StorageInternalizeActionResult
|
|
98
88
|
/** the parsed input AtomicBEEF */
|
|
99
89
|
ab: Beef
|
|
100
90
|
/** the incoming transaction extracted from AtomicBEEF */
|
|
@@ -356,11 +346,30 @@ class InternalizeActionContext {
|
|
|
356
346
|
// transaction record for user is new, but the txid may not be new to storage
|
|
357
347
|
// make sure storage pursues getting a proof for it.
|
|
358
348
|
const newReq = EntityProvenTxReq.fromTxid(this.txid, this.tx.toBinary(), this.args.tx)
|
|
359
|
-
|
|
349
|
+
// this status is only relevant if the transaction is new to storage.
|
|
350
|
+
newReq.status = 'unsent'
|
|
351
|
+
// this history and notify will be merged into an existing req if it exists.
|
|
360
352
|
newReq.addHistoryNote({ what: 'internalizeAction', userId: this.userId })
|
|
361
353
|
newReq.addNotifyTransactionId(transactionId)
|
|
362
354
|
const pr = await this.storage.getProvenOrReq(this.txid, newReq.toApi())
|
|
363
355
|
|
|
356
|
+
if (pr.isNew) {
|
|
357
|
+
// This storage doesn't know about this txid yet.
|
|
358
|
+
|
|
359
|
+
// TODO Can we immediately prove this txid?
|
|
360
|
+
// TODO Do full validation on the transaction?
|
|
361
|
+
|
|
362
|
+
// Attempt to broadcast it to the network, throwing an error if it fails.
|
|
363
|
+
|
|
364
|
+
const { swr, ndr } = await shareReqsWithWorld(this.storage, this.userId, [this.txid], false)
|
|
365
|
+
if (ndr![0].status !== 'success') {
|
|
366
|
+
this.r.sendWithResults = swr
|
|
367
|
+
this.r.notDelayedResults = ndr
|
|
368
|
+
// abort the internalize action, WERR_REVIEW_ACTIONS exception will be thrown
|
|
369
|
+
return
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
364
373
|
await this.addLabels(transactionId)
|
|
365
374
|
|
|
366
375
|
for (const payment of this.walletPayments) {
|
|
@@ -108,7 +108,7 @@ export interface PostBeefResultForTxidApi {
|
|
|
108
108
|
* @param txids
|
|
109
109
|
* @param isDelayed
|
|
110
110
|
*/
|
|
111
|
-
async function shareReqsWithWorld(
|
|
111
|
+
export async function shareReqsWithWorld(
|
|
112
112
|
storage: StorageProvider,
|
|
113
113
|
userId: number,
|
|
114
114
|
txids: string[],
|
|
@@ -154,7 +154,10 @@ async function shareReqsWithWorld(
|
|
|
154
154
|
// If isDelayed, this (or a different beef) will have to be rebuilt at the time of sending.
|
|
155
155
|
if (readyToSendReqs.length > 0) {
|
|
156
156
|
const beefIsValid = await r.beef.verify(await storage.getServices().getChainTracker())
|
|
157
|
-
if (!beefIsValid)
|
|
157
|
+
if (!beefIsValid) {
|
|
158
|
+
console.log(`VERIFY FALSE BEEF: ${r.beef.toLogString()}`)
|
|
159
|
+
throw new sdk.WERR_INTERNAL(`merged Beef failed validation.`)
|
|
160
|
+
}
|
|
158
161
|
}
|
|
159
162
|
|
|
160
163
|
// Set req batch property for the reqs being sent
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a copy of a Buffer with byte order reversed.
|
|
3
|
+
* @returns new buffer with byte order reversed.
|
|
4
|
+
* @publicbody
|
|
5
|
+
*/
|
|
6
|
+
export function swapByteOrder(buffer: Buffer): Buffer {
|
|
7
|
+
return Buffer.from(buffer).reverse()
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @param num a number value in the Uint32 value range
|
|
12
|
+
* @param littleEndian true for little-endian byte order in Buffer
|
|
13
|
+
* @returns four byte buffer with Uint32 number encoded
|
|
14
|
+
* @publicbody
|
|
15
|
+
*/
|
|
16
|
+
export function convertUint32ToBuffer(num: number, littleEndian = true): Buffer {
|
|
17
|
+
const arr = new ArrayBuffer(4)
|
|
18
|
+
const view = new DataView(arr)
|
|
19
|
+
view.setUint32(0, num, littleEndian) // byteOffset = 0
|
|
20
|
+
return Buffer.from(arr)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param buffer four byte buffer with Uint32 number encoded
|
|
25
|
+
* @param littleEndian true for little-endian byte order in Buffer
|
|
26
|
+
* @returns a number value in the Uint32 value range
|
|
27
|
+
* @publicbody
|
|
28
|
+
*/
|
|
29
|
+
export function convertBufferToUint32(buffer: Buffer, littleEndian = true): number {
|
|
30
|
+
const arr = buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength)
|
|
31
|
+
const view = new DataView(arr)
|
|
32
|
+
return view.getUint32(0, littleEndian)
|
|
33
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { sdk } from '../../index.client'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns the byte size required to encode number as Bitcoin VarUint
|
|
5
|
+
* @publicbody
|
|
6
|
+
*/
|
|
7
|
+
export function varUintSize(val: number): 1 | 3 | 5 | 9 {
|
|
8
|
+
if (val < 0) throw new sdk.WERR_INVALID_PARAMETER('varUint', 'non-negative')
|
|
9
|
+
return val <= 0xfc ? 1 : val <= 0xffff ? 3 : val <= 0xffffffff ? 5 : 9
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param scriptSize byte length of input script
|
|
14
|
+
* @returns serialized byte length a transaction input
|
|
15
|
+
*/
|
|
16
|
+
export function transactionInputSize(scriptSize: number): number {
|
|
17
|
+
return (
|
|
18
|
+
32 + // txid
|
|
19
|
+
4 + // vout
|
|
20
|
+
varUintSize(scriptSize) + // script length, this is already in bytes
|
|
21
|
+
scriptSize + // script
|
|
22
|
+
4
|
|
23
|
+
) // sequence number
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param scriptSize byte length of output script
|
|
28
|
+
* @returns serialized byte length a transaction output
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
export function transactionOutputSize(scriptSize: number): number {
|
|
32
|
+
return (
|
|
33
|
+
varUintSize(scriptSize) + // output script length, from script encoded as hex string
|
|
34
|
+
scriptSize + // output script
|
|
35
|
+
8
|
|
36
|
+
) // output amount (satoshis)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Compute the serialized binary transaction size in bytes
|
|
41
|
+
* given the number of inputs and outputs,
|
|
42
|
+
* and the size of each script.
|
|
43
|
+
* @param inputs array of input script lengths, in bytes
|
|
44
|
+
* @param outputs array of output script lengths, in bytes
|
|
45
|
+
* @returns total transaction size in bytes
|
|
46
|
+
*/
|
|
47
|
+
export function transactionSize(inputs: number[], outputs: number[]): number {
|
|
48
|
+
return (
|
|
49
|
+
4 + // Version
|
|
50
|
+
varUintSize(inputs.length) + // Number of inputs
|
|
51
|
+
inputs.reduce((a, e) => a + transactionInputSize(e), 0) + // all inputs
|
|
52
|
+
varUintSize(outputs.length) + // Number of outputs
|
|
53
|
+
outputs.reduce((a, e) => a + transactionOutputSize(e), 0) + // all outputs
|
|
54
|
+
4
|
|
55
|
+
) // lock time
|
|
56
|
+
}
|
|
@@ -195,8 +195,8 @@ export class StorageClient implements sdk.WalletStorageProvider {
|
|
|
195
195
|
* @param args Original wallet `internalizeAction` arguments.
|
|
196
196
|
* @returns `internalizeAction` results
|
|
197
197
|
*/
|
|
198
|
-
async internalizeAction(auth: sdk.AuthId, args: InternalizeActionArgs): Promise<
|
|
199
|
-
return this.rpcCall<
|
|
198
|
+
async internalizeAction(auth: sdk.AuthId, args: InternalizeActionArgs): Promise<sdk.StorageInternalizeActionResult> {
|
|
199
|
+
return this.rpcCall<sdk.StorageInternalizeActionResult>('internalizeAction', [auth, args])
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
/**
|
|
@@ -195,8 +195,8 @@ export class StorageClient implements sdk.WalletStorageProvider {
|
|
|
195
195
|
* @param args Original wallet `internalizeAction` arguments.
|
|
196
196
|
* @returns `internalizeAction` results
|
|
197
197
|
*/
|
|
198
|
-
async internalizeAction(auth: sdk.AuthId, args: InternalizeActionArgs): Promise<
|
|
199
|
-
return this.rpcCall<
|
|
198
|
+
async internalizeAction(auth: sdk.AuthId, args: InternalizeActionArgs): Promise<sdk.StorageInternalizeActionResult> {
|
|
199
|
+
return this.rpcCall<sdk.StorageInternalizeActionResult>('internalizeAction', [auth, args])
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
/**
|
|
@@ -70,6 +70,19 @@ export class KnexMigrations implements MigrationSource<string> {
|
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
migrations['2025-05-13-001 add monitor events event index'] = {
|
|
74
|
+
async up(knex) {
|
|
75
|
+
await knex.schema.alterTable('monitor_events', table => {
|
|
76
|
+
table.index('event')
|
|
77
|
+
})
|
|
78
|
+
},
|
|
79
|
+
async down(knex) {
|
|
80
|
+
await knex.schema.alterTable('monitor_events', table => {
|
|
81
|
+
table.dropIndex('event')
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
73
86
|
migrations['2025-03-03-001 descriptions to 2000'] = {
|
|
74
87
|
async up(knex) {
|
|
75
88
|
await knex.schema.alterTable('transactions', table => {
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { Beef, Transaction } from '@bsv/sdk'
|
|
2
|
+
import * as sdk from '../sdk'
|
|
3
|
+
import { TableTransaction } from '../storage/schema/tables'
|
|
4
|
+
import { StorageAdminStats, StorageProvider } from '../storage/StorageProvider'
|
|
5
|
+
|
|
6
|
+
export abstract class Format {
|
|
7
|
+
static alignLeft(v: string | number, fixedWidth: number): string {
|
|
8
|
+
v = v.toString()
|
|
9
|
+
if (v.length > fixedWidth) {
|
|
10
|
+
return v.slice(0, fixedWidth - 1) + '…'
|
|
11
|
+
}
|
|
12
|
+
return v.toString().padEnd(fixedWidth)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
static alignRight(v: string | number, fixedWidth: number): string {
|
|
16
|
+
v = v.toString()
|
|
17
|
+
if (v.length > fixedWidth) {
|
|
18
|
+
return '…' + v.slice(-fixedWidth + 1)
|
|
19
|
+
}
|
|
20
|
+
return v.toString().padStart(fixedWidth)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static alignMiddle(v: string | number, fixedWidth: number): string {
|
|
24
|
+
v = v.toString()
|
|
25
|
+
if (v.length === fixedWidth) return v
|
|
26
|
+
const l = Math.ceil(fixedWidth / 2)
|
|
27
|
+
const r = Math.floor(fixedWidth / 2)
|
|
28
|
+
if (v.length > fixedWidth) {
|
|
29
|
+
return `${al(v, l)}${ar(v, r)}`
|
|
30
|
+
}
|
|
31
|
+
const pl = Math.ceil(v.length / 2)
|
|
32
|
+
const pr = Math.floor(v.length / 2)
|
|
33
|
+
return `${ar(v.slice(0, pl), l)}${al(v.slice(-pr), r)}`
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static satoshis(s: number): string {
|
|
37
|
+
const minus = s < 0 ? '-' : ''
|
|
38
|
+
s = Math.abs(s)
|
|
39
|
+
let a = s.toString().split('')
|
|
40
|
+
if (a.length > 2) a.splice(-2, 0, '_')
|
|
41
|
+
if (a.length > 6) a.splice(-6, 0, '_')
|
|
42
|
+
if (a.length > 10) a.splice(-10, 0, '.')
|
|
43
|
+
if (a.length > 14) a.splice(-14, 0, '_')
|
|
44
|
+
if (a.length > 18) a.splice(-18, 0, '_')
|
|
45
|
+
let v = a.join('')
|
|
46
|
+
return minus + v
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static toLogStringTransaction(tx: Transaction): string {
|
|
50
|
+
const txid = tx.id('hex')
|
|
51
|
+
try {
|
|
52
|
+
let log = ''
|
|
53
|
+
let totalIn = 0,
|
|
54
|
+
totalOut = 0
|
|
55
|
+
for (let i = 0; i < Math.max(tx.inputs.length, tx.outputs.length); i++) {
|
|
56
|
+
let ilog: string = ''
|
|
57
|
+
let olog: string = ''
|
|
58
|
+
if (i < tx.inputs.length) {
|
|
59
|
+
const input = tx.inputs[i]
|
|
60
|
+
const satoshis = input.sourceTransaction?.outputs[input.sourceOutputIndex].satoshis || 0
|
|
61
|
+
totalIn += satoshis
|
|
62
|
+
ilog = `${al(`${am(input.sourceTXID || '', 12)}.${input.sourceOutputIndex}`, 17)} ${ar(sa(satoshis), 12)}`
|
|
63
|
+
}
|
|
64
|
+
if (i < tx.outputs.length) {
|
|
65
|
+
const output = tx.outputs[i]
|
|
66
|
+
totalOut += output.satoshis || 0
|
|
67
|
+
const script = output.lockingScript.toHex()
|
|
68
|
+
olog = `${ar(sa(output.satoshis || 0), 12)} (${script.length})${am(script, 13)}`
|
|
69
|
+
}
|
|
70
|
+
log += `${al(ilog, 30)} ${ar('' + i, 5)} ${olog}\n`
|
|
71
|
+
}
|
|
72
|
+
let h = `txid ${txid}\n`
|
|
73
|
+
h += `total in:${sa(totalIn)} out:${sa(totalOut)} fee:${sa(totalIn - totalOut)}\n`
|
|
74
|
+
h += `${al('Inputs', 30)} ${ar('Vin/', 5)} ${'Outputs'}\n`
|
|
75
|
+
h += `${al('Outpoint', 17)} ${ar('Satoshis', 12)} ${ar('Vout', 5)} ${ar('Satoshis', 12)} ${al('Lock Script', 23)}\n`
|
|
76
|
+
return h + log
|
|
77
|
+
} catch (eu: unknown) {
|
|
78
|
+
const e = sdk.WalletError.fromUnknown(eu)
|
|
79
|
+
return `Transaction with txid ${txid} is invalid`
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
static toLogStringBeefTxid(beef: Beef, txid: string): string {
|
|
84
|
+
const tx = beef.findAtomicTransaction(txid)
|
|
85
|
+
if (!tx) return `Transaction ${txid} not found in beef`
|
|
86
|
+
return Format.toLogStringTransaction(tx)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
static async toLogStringTableTransaction(tx: TableTransaction, storage: StorageProvider): Promise<string> {
|
|
90
|
+
if (!tx.txid) return `Transaction ${tx.transactionId} has no txid`
|
|
91
|
+
try {
|
|
92
|
+
const beef = await storage.getBeefForTransaction(tx.txid, { minProofLevel: 1 })
|
|
93
|
+
const log = Format.toLogStringBeefTxid(beef, tx.txid)
|
|
94
|
+
const h = `transactionId:${tx.transactionId} userId:${tx.userId} ${tx.status} satoshis:${sa(tx.satoshis)}\n`
|
|
95
|
+
return h + log
|
|
96
|
+
} catch (eu: unknown) {
|
|
97
|
+
const e = sdk.WalletError.fromUnknown(eu)
|
|
98
|
+
return `Transaction ${tx.transactionId} with txid ${tx.txid} is invalid`
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
static toLogStringAdminStats(s: StorageAdminStats): string {
|
|
103
|
+
let log = `StorageAdminStats: ${s.when} ${s.requestedBy}\n`
|
|
104
|
+
log += ` ${al('', 13)} ${ar('Day', 15)} ${ar('Month', 15)} ${ar('Total', 15)}\n`
|
|
105
|
+
log += dmt('users', s.usersDay, s.usersMonth, s.usersTotal)
|
|
106
|
+
log += dmt('change sats', sa(s.satoshisDefaultDay), sa(s.satoshisDefaultMonth), sa(s.satoshisDefaultTotal))
|
|
107
|
+
log += dmt('other sats', sa(s.satoshisOtherDay), sa(s.satoshisOtherMonth), sa(s.satoshisOtherTotal))
|
|
108
|
+
log += dmt('labels', s.labelsDay, s.labelsMonth, s.labelsTotal)
|
|
109
|
+
log += dmt('tags', s.tagsDay, s.tagsMonth, s.tagsTotal)
|
|
110
|
+
log += dmt('baskets', s.basketsDay, s.basketsMonth, s.basketsTotal)
|
|
111
|
+
log += dmt('transactions', s.transactionsDay, s.transactionsMonth, s.transactionsTotal)
|
|
112
|
+
log += dmt(' completed', s.txCompletedDay, s.txCompletedMonth, s.txCompletedTotal)
|
|
113
|
+
log += dmt(' failed', s.txFailedDay, s.txFailedMonth, s.txFailedTotal)
|
|
114
|
+
log += dmt(' nosend', s.txNosendDay, s.txNosendMonth, s.txNosendTotal)
|
|
115
|
+
log += dmt(' unproven', s.txUnprovenDay, s.txUnprovenMonth, s.txUnprovenTotal)
|
|
116
|
+
log += dmt(' sending', s.txSendingDay, s.txSendingMonth, s.txSendingTotal)
|
|
117
|
+
log += dmt(' unprocessed', s.txUnprocessedDay, s.txUnprocessedMonth, s.txUnprocessedTotal)
|
|
118
|
+
log += dmt(' unsigned', s.txUnsignedDay, s.txUnsignedMonth, s.txUnsignedTotal)
|
|
119
|
+
log += dmt(' nonfinal', s.txNonfinalDay, s.txNonfinalMonth, s.txNonfinalTotal)
|
|
120
|
+
log += dmt(' unfail', s.txUnfailDay, s.txUnfailMonth, s.txUnfailTotal)
|
|
121
|
+
|
|
122
|
+
return log
|
|
123
|
+
|
|
124
|
+
function dmt(l: string, d: number | string, m: number | string, t: number | string): string {
|
|
125
|
+
return ` ${al(l, 13)} ${ar(d, 15)} ${ar(m, 15)} ${ar(t, 15)}\n`
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const al = Format.alignLeft
|
|
131
|
+
const ar = Format.alignRight
|
|
132
|
+
const am = Format.alignMiddle
|
|
133
|
+
const sa = Format.satoshis
|
|
@@ -231,7 +231,7 @@ export function sha256Hash(data: number[]): number[] {
|
|
|
231
231
|
* @returns double sha256 hash of data, byte 0 of hash first.
|
|
232
232
|
* @publicbody
|
|
233
233
|
*/
|
|
234
|
-
export function
|
|
234
|
+
export function doubleSha256LE(data: number[]): number[] {
|
|
235
235
|
const first = new Hash.SHA256().update(data).digest()
|
|
236
236
|
const second = new Hash.SHA256().update(first).digest()
|
|
237
237
|
return second
|
|
@@ -244,5 +244,5 @@ export function doubleSha256HashLE(data: number[]): number[] {
|
|
|
244
244
|
* @publicbody
|
|
245
245
|
*/
|
|
246
246
|
export function doubleSha256BE(data: number[]): number[] {
|
|
247
|
-
return
|
|
247
|
+
return doubleSha256LE(data).reverse()
|
|
248
248
|
}
|