@bopen-io/wallet-toolbox 2.15.0-bopen.1 → 2.15.0
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/CHANGELOG.md +183 -45
- package/README.md +134 -98
- package/docs/client.md +2947 -3080
- package/docs/monitor.md +154 -165
- package/docs/no-send-expiry.md +7 -2
- package/docs/services.md +822 -885
- package/docs/setup.md +1 -46
- package/docs/storage.md +1636 -1654
- package/docs/wallet.md +1975 -2132
- package/out/src/CWIStyleWalletManager.d.ts +36 -5
- package/out/src/CWIStyleWalletManager.d.ts.map +1 -1
- package/out/src/CWIStyleWalletManager.js +356 -60
- package/out/src/CWIStyleWalletManager.js.map +1 -1
- package/out/src/Setup.d.ts +0 -10
- package/out/src/Setup.d.ts.map +1 -1
- package/out/src/Setup.js +0 -24
- package/out/src/Setup.js.map +1 -1
- package/out/src/Wallet.d.ts.map +1 -1
- package/out/src/Wallet.js +8 -3
- package/out/src/Wallet.js.map +1 -1
- package/out/src/WalletAuthenticationManager.d.ts +3 -0
- package/out/src/WalletAuthenticationManager.d.ts.map +1 -1
- package/out/src/WalletAuthenticationManager.js +86 -3
- package/out/src/WalletAuthenticationManager.js.map +1 -1
- package/out/src/WalletPermissionsManager.d.ts +63 -9
- package/out/src/WalletPermissionsManager.d.ts.map +1 -1
- package/out/src/WalletPermissionsManager.js +213 -49
- package/out/src/WalletPermissionsManager.js.map +1 -1
- package/out/src/monitor/Monitor.js +1 -1
- package/out/src/monitor/Monitor.js.map +1 -1
- package/out/src/monitor/MonitorDaemon.d.ts +0 -2
- package/out/src/monitor/MonitorDaemon.d.ts.map +1 -1
- package/out/src/monitor/MonitorDaemon.js +1 -9
- package/out/src/monitor/MonitorDaemon.js.map +1 -1
- package/out/src/monitor/monitorValidation.d.ts +2 -1
- package/out/src/monitor/monitorValidation.d.ts.map +1 -1
- package/out/src/monitor/monitorValidation.js +2 -2
- package/out/src/monitor/monitorValidation.js.map +1 -1
- package/out/src/monitor/tasks/TaskNewHeader.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskNewHeader.js +1 -1
- package/out/src/monitor/tasks/TaskNewHeader.js.map +1 -1
- package/out/src/monitor/tasks/TaskReviewUtxos.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskReviewUtxos.js +2 -1
- package/out/src/monitor/tasks/TaskReviewUtxos.js.map +1 -1
- package/out/src/sdk/WERR_errors.d.ts +4 -0
- package/out/src/sdk/WERR_errors.d.ts.map +1 -1
- package/out/src/sdk/WERR_errors.js +4 -0
- package/out/src/sdk/WERR_errors.js.map +1 -1
- package/out/src/sdk/WalletErrorFromJson.d.ts.map +1 -1
- package/out/src/sdk/WalletErrorFromJson.js +23 -2
- package/out/src/sdk/WalletErrorFromJson.js.map +1 -1
- package/out/src/sdk/WalletStorage.interfaces.d.ts +11 -0
- package/out/src/sdk/WalletStorage.interfaces.d.ts.map +1 -1
- package/out/src/sdk/types.d.ts +12 -1
- package/out/src/sdk/types.d.ts.map +1 -1
- package/out/src/sdk/types.js +19 -2
- package/out/src/sdk/types.js.map +1 -1
- package/out/src/services/Services.d.ts.map +1 -1
- package/out/src/services/Services.js +5 -3
- package/out/src/services/Services.js.map +1 -1
- package/out/src/services/chaintracker/BHServiceClient.js +2 -2
- package/out/src/services/chaintracker/BHServiceClient.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Chaintracks.js +2 -2
- package/out/src/services/chaintracker/chaintracks/Chaintracks.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.js +3 -1
- package/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/GoChaintracksServiceClient.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/GoChaintracksServiceClient.js +3 -1
- package/out/src/services/chaintracker/chaintracks/GoChaintracksServiceClient.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorBase.js +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/BulkIngestorBase.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorBase.js +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorBase.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorChaintracksSSE.js +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorChaintracksSSE.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainIngestorWs.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainIngestorWs.js +2 -0
- package/out/src/services/chaintracker/chaintracks/Ingest/WhatsOnChainIngestorWs.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/BulkStorageBase.js +2 -2
- package/out/src/services/chaintracker/chaintracks/Storage/BulkStorageBase.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageBase.js +6 -6
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageBase.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.js +2 -2
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageKnex.d.ts +0 -5
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageKnex.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageKnex.js +5 -13
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageKnex.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.d.ts +1 -0
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.js +11 -3
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.js +13 -9
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFilesReader.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFilesReader.js +2 -2
- package/out/src/services/chaintracker/chaintracks/util/BulkFilesReader.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/InlineBulkFileDataValidator.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/InlineBulkFileDataValidator.js +2 -2
- package/out/src/services/chaintracker/chaintracks/util/InlineBulkFileDataValidator.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.d.ts +23 -5
- package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.js +58 -16
- package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.js.map +1 -1
- package/out/src/services/createDefaultWalletServicesOptions.d.ts +6 -3
- package/out/src/services/createDefaultWalletServicesOptions.d.ts.map +1 -1
- package/out/src/services/createDefaultWalletServicesOptions.js +18 -6
- package/out/src/services/createDefaultWalletServicesOptions.js.map +1 -1
- package/out/src/services/networkConfig.d.ts +7 -0
- package/out/src/services/networkConfig.d.ts.map +1 -1
- package/out/src/services/networkConfig.js +25 -2
- package/out/src/services/networkConfig.js.map +1 -1
- package/out/src/services/providers/SdkWhatsOnChain.d.ts +8 -2
- package/out/src/services/providers/SdkWhatsOnChain.d.ts.map +1 -1
- package/out/src/services/providers/SdkWhatsOnChain.js +17 -6
- package/out/src/services/providers/SdkWhatsOnChain.js.map +1 -1
- package/out/src/services/validateMerklePathResult.d.ts +4 -3
- package/out/src/services/validateMerklePathResult.d.ts.map +1 -1
- package/out/src/services/validateMerklePathResult.js +6 -6
- package/out/src/services/validateMerklePathResult.js.map +1 -1
- package/out/src/signer/actionBatch/ActionBatchWorkspace.d.ts.map +1 -1
- package/out/src/signer/actionBatch/ActionBatchWorkspace.js +3 -2
- package/out/src/signer/actionBatch/ActionBatchWorkspace.js.map +1 -1
- package/out/src/signer/methods/createAction.d.ts +32 -1
- package/out/src/signer/methods/createAction.d.ts.map +1 -1
- package/out/src/signer/methods/createAction.js +56 -1
- package/out/src/signer/methods/createAction.js.map +1 -1
- package/out/src/signer/methods/internalizeAction.js +1 -1
- package/out/src/signer/methods/internalizeAction.js.map +1 -1
- package/out/src/signer/methods/signAction.js +8 -1
- package/out/src/signer/methods/signAction.js.map +1 -1
- package/out/src/storage/StorageIdb.js +4 -4
- package/out/src/storage/StorageIdb.js.map +1 -1
- package/out/src/storage/StorageKnex.d.ts +6 -5
- package/out/src/storage/StorageKnex.d.ts.map +1 -1
- package/out/src/storage/StorageKnex.js +321 -115
- package/out/src/storage/StorageKnex.js.map +1 -1
- package/out/src/storage/WalletStorageManager.d.ts.map +1 -1
- package/out/src/storage/WalletStorageManager.js +5 -0
- package/out/src/storage/WalletStorageManager.js.map +1 -1
- package/out/src/storage/adminServer/adminServer.d.ts.map +1 -1
- package/out/src/storage/adminServer/adminServer.js +41 -3
- package/out/src/storage/adminServer/adminServer.js.map +1 -1
- package/out/src/storage/index.all.d.ts +0 -1
- package/out/src/storage/index.all.d.ts.map +1 -1
- package/out/src/storage/index.all.js +0 -1
- package/out/src/storage/index.all.js.map +1 -1
- package/out/src/storage/methods/ListOutputsSpecOp.d.ts.map +1 -1
- package/out/src/storage/methods/ListOutputsSpecOp.js +84 -0
- package/out/src/storage/methods/ListOutputsSpecOp.js.map +1 -1
- package/out/src/storage/methods/attemptToPostReqsToNetwork.d.ts.map +1 -1
- package/out/src/storage/methods/attemptToPostReqsToNetwork.js +7 -3
- package/out/src/storage/methods/attemptToPostReqsToNetwork.js.map +1 -1
- package/out/src/storage/methods/createAction.d.ts +5 -0
- package/out/src/storage/methods/createAction.d.ts.map +1 -1
- package/out/src/storage/methods/createAction.js +13 -6
- package/out/src/storage/methods/createAction.js.map +1 -1
- package/out/src/storage/methods/generateChange.d.ts +6 -0
- package/out/src/storage/methods/generateChange.d.ts.map +1 -1
- package/out/src/storage/methods/generateChange.js +10 -3
- package/out/src/storage/methods/generateChange.js.map +1 -1
- package/out/src/storage/methods/internalizeAction.d.ts +8 -1
- package/out/src/storage/methods/internalizeAction.d.ts.map +1 -1
- package/out/src/storage/methods/internalizeAction.js +106 -42
- package/out/src/storage/methods/internalizeAction.js.map +1 -1
- package/out/src/storage/methods/listActionsKnex.d.ts.map +1 -1
- package/out/src/storage/methods/listActionsKnex.js +1 -0
- package/out/src/storage/methods/listActionsKnex.js.map +1 -1
- package/out/src/storage/methods/listOutputsKnex.d.ts.map +1 -1
- package/out/src/storage/methods/listOutputsKnex.js +2 -1
- package/out/src/storage/methods/listOutputsKnex.js.map +1 -1
- package/out/src/storage/methods/noSendExpiry.d.ts.map +1 -1
- package/out/src/storage/methods/noSendExpiry.js +14 -4
- package/out/src/storage/methods/noSendExpiry.js.map +1 -1
- package/out/src/storage/methods/purgeData.d.ts.map +1 -1
- package/out/src/storage/methods/purgeData.js +3 -0
- package/out/src/storage/methods/purgeData.js.map +1 -1
- package/out/src/storage/methods/reviewStatus.d.ts.map +1 -1
- package/out/src/storage/methods/reviewStatus.js +3 -0
- package/out/src/storage/methods/reviewStatus.js.map +1 -1
- package/out/src/storage/portable/index.js +12 -38
- package/out/src/storage/portable/index.js.map +1 -1
- package/out/src/storage/remoting/StorageClientBase.d.ts.map +1 -1
- package/out/src/storage/remoting/StorageClientBase.js +15 -5
- package/out/src/storage/remoting/StorageClientBase.js.map +1 -1
- package/out/src/storage/remoting/StorageServer.d.ts +4 -17
- package/out/src/storage/remoting/StorageServer.d.ts.map +1 -1
- package/out/src/storage/remoting/StorageServer.js +25 -23
- package/out/src/storage/remoting/StorageServer.js.map +1 -1
- package/out/src/storage/remoting/syncChunkBinary.d.ts +10 -0
- package/out/src/storage/remoting/syncChunkBinary.d.ts.map +1 -1
- package/out/src/storage/remoting/syncChunkBinary.js +15 -11
- package/out/src/storage/remoting/syncChunkBinary.js.map +1 -1
- package/out/src/storage/schema/KnexMigrations.d.ts +3 -7
- package/out/src/storage/schema/KnexMigrations.d.ts.map +1 -1
- package/out/src/storage/schema/KnexMigrations.js +86 -166
- package/out/src/storage/schema/KnexMigrations.js.map +1 -1
- package/out/src/storage/sync/liveSyncGuards.d.ts +11 -0
- package/out/src/storage/sync/liveSyncGuards.d.ts.map +1 -0
- package/out/src/storage/sync/liveSyncGuards.js +22 -0
- package/out/src/storage/sync/liveSyncGuards.js.map +1 -0
- package/out/src/utility/actionOutputAuthorizations.d.ts +10 -0
- package/out/src/utility/actionOutputAuthorizations.d.ts.map +1 -0
- package/out/src/utility/actionOutputAuthorizations.js +25 -0
- package/out/src/utility/actionOutputAuthorizations.js.map +1 -0
- package/out/src/utility/index.all.d.ts +1 -0
- package/out/src/utility/index.all.d.ts.map +1 -1
- package/out/src/utility/index.all.js +1 -0
- package/out/src/utility/index.all.js.map +1 -1
- package/out/src/utility/index.client.d.ts +1 -0
- package/out/src/utility/index.client.d.ts.map +1 -1
- package/out/src/utility/index.client.js +1 -0
- package/out/src/utility/index.client.js.map +1 -1
- package/out/src/utility/numericTotalOutputs.d.ts +7 -0
- package/out/src/utility/numericTotalOutputs.d.ts.map +1 -0
- package/out/src/utility/numericTotalOutputs.js +15 -0
- package/out/src/utility/numericTotalOutputs.js.map +1 -0
- package/out/src/utility/utilityHelpers.d.ts.map +1 -1
- package/out/src/utility/utilityHelpers.js +2 -0
- package/out/src/utility/utilityHelpers.js.map +1 -1
- package/package.json +19 -24
- package/out/src/storage/adminServer/reqReviewQuery.d.ts +0 -41
- package/out/src/storage/adminServer/reqReviewQuery.d.ts.map +0 -1
- package/out/src/storage/adminServer/reqReviewQuery.js +0 -67
- package/out/src/storage/adminServer/reqReviewQuery.js.map +0 -1
- package/out/src/storage/knexPostgres.d.ts +0 -16
- package/out/src/storage/knexPostgres.d.ts.map +0 -1
- package/out/src/storage/knexPostgres.js +0 -34
- package/out/src/storage/knexPostgres.js.map +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.StorageKnex = void 0;
|
|
4
|
+
const validationHelpers_1 = require("@bsv/sdk/wallet/validationHelpers");
|
|
4
5
|
const tables_1 = require("./schema/tables");
|
|
5
6
|
const KnexMigrations_1 = require("./schema/KnexMigrations");
|
|
6
7
|
const StorageProvider_1 = require("./StorageProvider");
|
|
@@ -10,9 +11,10 @@ const listOutputsKnex_1 = require("./methods/listOutputsKnex");
|
|
|
10
11
|
const reviewStatus_1 = require("./methods/reviewStatus");
|
|
11
12
|
const WERR_errors_1 = require("../sdk/WERR_errors");
|
|
12
13
|
const utilityHelpers_1 = require("../utility/utilityHelpers");
|
|
14
|
+
const canonicalizeAtomicBeef_1 = require("../utility/canonicalizeAtomicBeef");
|
|
15
|
+
const internalizeAction_1 = require("./methods/internalizeAction");
|
|
13
16
|
const managedChange_1 = require("./methods/managedChange");
|
|
14
17
|
const preparedBeef_1 = require("./methods/preparedBeef");
|
|
15
|
-
const knexPostgres_1 = require("./knexPostgres");
|
|
16
18
|
// Keep bulk statements below conservative SQLite/MySQL bind-parameter
|
|
17
19
|
// ceilings. The surrounding transaction still makes a complete pack atomic.
|
|
18
20
|
const ACTION_BATCH_BLOB_SQL_CHUNK = 500;
|
|
@@ -48,7 +50,7 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
48
50
|
if (options.knex == null)
|
|
49
51
|
throw new WERR_errors_1.WERR_INVALID_PARAMETER('options.knex', 'valid');
|
|
50
52
|
this.knex = options.knex;
|
|
51
|
-
(
|
|
53
|
+
parsePostgresInt8AsNumber(this.knex);
|
|
52
54
|
this.preparedBeefPolicy = (0, preparedBeef_1.validatePreparedBeefPolicy)(options.preparedBeef);
|
|
53
55
|
this.preparedBeefCoordinator = new preparedBeef_1.PreparedBeefCoordinator(this);
|
|
54
56
|
if (this.telemetry.enabled) {
|
|
@@ -57,6 +59,117 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
57
59
|
this.knex.on('query-error', this.onQueryError);
|
|
58
60
|
}
|
|
59
61
|
}
|
|
62
|
+
receiptClockMs() {
|
|
63
|
+
switch (this.dbtype) {
|
|
64
|
+
case 'MySQL':
|
|
65
|
+
return this.knex.raw('CAST(UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000 AS UNSIGNED)');
|
|
66
|
+
case 'Postgres':
|
|
67
|
+
return this.knex.raw('CAST(EXTRACT(EPOCH FROM clock_timestamp()) * 1000 AS BIGINT)');
|
|
68
|
+
case 'SQLite':
|
|
69
|
+
return this.knex.raw("CAST((julianday('now') - 2440587.5) * 86400000 AS INTEGER)");
|
|
70
|
+
default:
|
|
71
|
+
throw new WERR_errors_1.WERR_INTERNAL('wallet receipt claim requires a ready SQL storage provider');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
receiptLeaseMs() {
|
|
75
|
+
return this.knex.raw('(? + ?)', [this.receiptClockMs(), 120_000]);
|
|
76
|
+
}
|
|
77
|
+
async acquireInternalizeReceipt(userId, txid) {
|
|
78
|
+
const ownerToken = (0, utilityHelpers_1.randomBytesBase64)(18);
|
|
79
|
+
const deadline = Date.now() + 30_000;
|
|
80
|
+
while (Date.now() < deadline) {
|
|
81
|
+
await this.knex('internalize_receipts')
|
|
82
|
+
.insert({
|
|
83
|
+
userId,
|
|
84
|
+
txid,
|
|
85
|
+
ownerToken,
|
|
86
|
+
state: 'pending',
|
|
87
|
+
leaseUntil: this.receiptLeaseMs(),
|
|
88
|
+
needsNewReceipt: false
|
|
89
|
+
})
|
|
90
|
+
.onConflict(['userId', 'txid'])
|
|
91
|
+
.ignore();
|
|
92
|
+
const previous = await this.knex('internalize_receipts')
|
|
93
|
+
.where({ userId, txid })
|
|
94
|
+
.first('ownerToken', 'state', 'needsNewReceipt');
|
|
95
|
+
if (previous == null)
|
|
96
|
+
continue;
|
|
97
|
+
const retryNew = Boolean(previous.needsNewReceipt);
|
|
98
|
+
const preserveComplete = previous.state === 'complete';
|
|
99
|
+
if (previous.ownerToken !== ownerToken) {
|
|
100
|
+
const changed = await this.knex('internalize_receipts')
|
|
101
|
+
.where({ userId, txid, ownerToken: previous.ownerToken })
|
|
102
|
+
.where(builder => builder.whereIn('state', ['retryable', 'complete']).orWhere('leaseUntil', '<=', this.receiptClockMs()))
|
|
103
|
+
.update({ ownerToken, state: 'pending', leaseUntil: this.receiptLeaseMs() });
|
|
104
|
+
if (changed !== 1) {
|
|
105
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
const activeRow = (trx) => {
|
|
110
|
+
const query = trx('internalize_receipts')
|
|
111
|
+
.where({ userId, txid, ownerToken, state: 'pending' })
|
|
112
|
+
.where('leaseUntil', '>', this.receiptClockMs());
|
|
113
|
+
return this.dbtype === 'SQLite' ? query : query.forUpdate();
|
|
114
|
+
};
|
|
115
|
+
const claim = {
|
|
116
|
+
retryNew,
|
|
117
|
+
assertActive: async (trx) => {
|
|
118
|
+
const active = await activeRow(trx).first('ownerToken');
|
|
119
|
+
if (active == null)
|
|
120
|
+
throw new WERR_errors_1.WERR_INTERNAL('wallet receipt claim expired or was superseded');
|
|
121
|
+
},
|
|
122
|
+
markNew: async (trx) => {
|
|
123
|
+
const changed = await activeRow(trx).update({ needsNewReceipt: true });
|
|
124
|
+
if (changed !== 1)
|
|
125
|
+
throw new WERR_errors_1.WERR_INTERNAL('wallet receipt claim expired or was superseded');
|
|
126
|
+
},
|
|
127
|
+
complete: async (trx) => {
|
|
128
|
+
const changed = await activeRow(trx).update({
|
|
129
|
+
state: 'complete',
|
|
130
|
+
needsNewReceipt: false,
|
|
131
|
+
leaseUntil: 0
|
|
132
|
+
});
|
|
133
|
+
if (changed !== 1)
|
|
134
|
+
throw new WERR_errors_1.WERR_INTERNAL('wallet receipt claim expired or was superseded');
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
return { ownerToken, claim, preserveComplete };
|
|
138
|
+
}
|
|
139
|
+
throw new WERR_errors_1.WERR_INTERNAL('wallet receipt is already being processed; retry after the active request finishes');
|
|
140
|
+
}
|
|
141
|
+
async internalizeAction(auth, args) {
|
|
142
|
+
(0, validationHelpers_1.validateInternalizeActionArgs)(args);
|
|
143
|
+
const userId = auth.userId;
|
|
144
|
+
if (userId == null)
|
|
145
|
+
throw new WERR_errors_1.WERR_UNAUTHORIZED();
|
|
146
|
+
const txid = (0, canonicalizeAtomicBeef_1.canonicalizeAtomicBeef)(args.tx).atomicTxid;
|
|
147
|
+
if (txid == null)
|
|
148
|
+
throw new WERR_errors_1.WERR_INVALID_PARAMETER('tx', 'an AtomicBEEF transaction');
|
|
149
|
+
const { ownerToken, claim, preserveComplete } = await this.acquireInternalizeReceipt(userId, txid);
|
|
150
|
+
try {
|
|
151
|
+
return await (0, internalizeAction_1.internalizeAction)(this, auth, args, claim);
|
|
152
|
+
}
|
|
153
|
+
finally {
|
|
154
|
+
// A successful writer marked its claim complete in the same transaction
|
|
155
|
+
// as the output records. Preserve that durable key across later merges;
|
|
156
|
+
// release an uncompleted key only when no new receipt header was marked.
|
|
157
|
+
const noNewReceipt = this.knex('internalize_receipts').where({
|
|
158
|
+
userId,
|
|
159
|
+
txid,
|
|
160
|
+
ownerToken,
|
|
161
|
+
state: 'pending',
|
|
162
|
+
needsNewReceipt: false
|
|
163
|
+
});
|
|
164
|
+
if (preserveComplete)
|
|
165
|
+
await noNewReceipt.update({ state: 'complete', leaseUntil: 0 });
|
|
166
|
+
else
|
|
167
|
+
await noNewReceipt.delete();
|
|
168
|
+
await this.knex('internalize_receipts')
|
|
169
|
+
.where({ userId, txid, ownerToken, state: 'pending', needsNewReceipt: true })
|
|
170
|
+
.update({ state: 'retryable', leaseUntil: 0 });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
60
173
|
databaseSystem() {
|
|
61
174
|
const clientName = this.knex.client.config?.client ?? '';
|
|
62
175
|
if (clientName.includes('sqlite'))
|
|
@@ -261,6 +374,7 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
261
374
|
.whereNull('pb.preparedBeefId')
|
|
262
375
|
.select('o.userId', 'o.txid as rootTxid')
|
|
263
376
|
.groupBy('o.userId', 'o.txid')
|
|
377
|
+
// ?? quotes identifiers: Postgres lowercases unquoted names, so camelCase columns must be quoted.
|
|
264
378
|
.orderByRaw('MIN(??)', ['o.outputId'])
|
|
265
379
|
.limit(limit));
|
|
266
380
|
return rows;
|
|
@@ -387,6 +501,7 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
387
501
|
void this.whereExists(k
|
|
388
502
|
.select('*')
|
|
389
503
|
.from('transactions')
|
|
504
|
+
// ?? quotes identifiers: Postgres lowercases unquoted names, so camelCase columns must be quoted.
|
|
390
505
|
.whereRaw('?? = ?? and ?? = ?', [
|
|
391
506
|
'proven_txs.provenTxId',
|
|
392
507
|
'transactions.provenTxId',
|
|
@@ -414,6 +529,7 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
414
529
|
void this.whereExists(k
|
|
415
530
|
.select('*')
|
|
416
531
|
.from('transactions')
|
|
532
|
+
// ?? quotes identifiers: Postgres lowercases unquoted names, so camelCase columns must be quoted.
|
|
417
533
|
.whereRaw('proven_tx_reqs.txid = transactions.txid and ?? = ?', ['transactions.userId', args.userId]));
|
|
418
534
|
});
|
|
419
535
|
if (args.paged != null) {
|
|
@@ -435,6 +551,7 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
435
551
|
let q = k('tx_labels_map').whereExists(k
|
|
436
552
|
.select('*')
|
|
437
553
|
.from('tx_labels')
|
|
554
|
+
// ?? quotes identifiers: Postgres lowercases unquoted names, so camelCase columns must be quoted.
|
|
438
555
|
.whereRaw('?? = ?? and ?? = ?', [
|
|
439
556
|
'tx_labels.txLabelId',
|
|
440
557
|
'tx_labels_map.txLabelId',
|
|
@@ -460,6 +577,7 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
460
577
|
let q = k('output_tags_map').whereExists(k
|
|
461
578
|
.select('*')
|
|
462
579
|
.from('output_tags')
|
|
580
|
+
// ?? quotes identifiers: Postgres lowercases unquoted names, so camelCase columns must be quoted.
|
|
463
581
|
.whereRaw('?? = ?? and ?? = ?', [
|
|
464
582
|
'output_tags.outputTagId',
|
|
465
583
|
'output_tags_map.outputTagId',
|
|
@@ -532,20 +650,16 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
532
650
|
/**
|
|
533
651
|
* Insert one row and return its auto-increment primary key. MySQL and SQLite
|
|
534
652
|
* report the id as the insert result; Postgres requires a RETURNING clause.
|
|
535
|
-
*
|
|
536
|
-
* `recoverable` marks inserts that the findOrInsert helpers retry as a find
|
|
537
|
-
* after a duplicate-key error, in the same transaction; see `inSavepoint`.
|
|
538
653
|
*/
|
|
539
|
-
async insertReturningId(table, idColumn, row, trx
|
|
654
|
+
async insertReturningId(table, idColumn, row, trx) {
|
|
540
655
|
if (this.dbtype !== 'Postgres') {
|
|
541
656
|
const [id] = await this.toDb(trx)(table).insert(row);
|
|
542
657
|
return id;
|
|
543
658
|
}
|
|
544
|
-
|
|
659
|
+
return await this.inSavepoint(trx, async (db) => {
|
|
545
660
|
const [r] = await db(table).insert(row).returning(idColumn);
|
|
546
661
|
return r[idColumn];
|
|
547
|
-
};
|
|
548
|
-
return recoverable ? await this.inSavepoint(trx, insert) : await insert(this.toDb(trx));
|
|
662
|
+
});
|
|
549
663
|
}
|
|
550
664
|
/**
|
|
551
665
|
* The findOrInsert helpers catch a failed insert and find the row again in
|
|
@@ -562,7 +676,7 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
562
676
|
const e = await this.validateEntityForInsert(tx, trx);
|
|
563
677
|
if (e.provenTxId === 0)
|
|
564
678
|
delete e.provenTxId;
|
|
565
|
-
const id = await this.insertReturningId('proven_txs', 'provenTxId', e, trx
|
|
679
|
+
const id = await this.insertReturningId('proven_txs', 'provenTxId', e, trx);
|
|
566
680
|
tx.provenTxId = id;
|
|
567
681
|
return tx.provenTxId;
|
|
568
682
|
}
|
|
@@ -690,7 +804,7 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
690
804
|
const e = await this.validateEntityForInsert(tx, trx);
|
|
691
805
|
if (e.provenTxReqId === 0)
|
|
692
806
|
delete e.provenTxReqId;
|
|
693
|
-
const id = await this.insertReturningId('proven_tx_reqs', 'provenTxReqId', e, trx
|
|
807
|
+
const id = await this.insertReturningId('proven_tx_reqs', 'provenTxReqId', e, trx);
|
|
694
808
|
tx.provenTxReqId = id;
|
|
695
809
|
return tx.provenTxReqId;
|
|
696
810
|
}
|
|
@@ -737,7 +851,7 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
737
851
|
const e = await this.validateEntityForInsert(basket, trx, undefined, ['isDeleted']);
|
|
738
852
|
if (e.basketId === 0)
|
|
739
853
|
delete e.basketId;
|
|
740
|
-
const id = await this.insertReturningId('output_baskets', 'basketId', e, trx
|
|
854
|
+
const id = await this.insertReturningId('output_baskets', 'basketId', e, trx);
|
|
741
855
|
basket.basketId = id;
|
|
742
856
|
return basket.basketId;
|
|
743
857
|
}
|
|
@@ -745,7 +859,7 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
745
859
|
const e = await this.validateEntityForInsert(tx, trx);
|
|
746
860
|
if (e.transactionId === 0)
|
|
747
861
|
delete e.transactionId;
|
|
748
|
-
const id = await this.insertReturningId('transactions', 'transactionId', e, trx
|
|
862
|
+
const id = await this.insertReturningId('transactions', 'transactionId', e, trx);
|
|
749
863
|
tx.transactionId = id;
|
|
750
864
|
return tx.transactionId;
|
|
751
865
|
}
|
|
@@ -782,7 +896,7 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
782
896
|
const e = await this.validateEntityForInsert(tag, trx, undefined, ['isDeleted']);
|
|
783
897
|
if (e.outputTagId === 0)
|
|
784
898
|
delete e.outputTagId;
|
|
785
|
-
const id = await this.insertReturningId('output_tags', 'outputTagId', e, trx
|
|
899
|
+
const id = await this.insertReturningId('output_tags', 'outputTagId', e, trx);
|
|
786
900
|
tag.outputTagId = id;
|
|
787
901
|
return tag.outputTagId;
|
|
788
902
|
}
|
|
@@ -794,7 +908,7 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
794
908
|
const e = await this.validateEntityForInsert(label, trx, undefined, ['isDeleted']);
|
|
795
909
|
if (e.txLabelId === 0)
|
|
796
910
|
delete e.txLabelId;
|
|
797
|
-
const id = await this.insertReturningId('tx_labels', 'txLabelId', e, trx
|
|
911
|
+
const id = await this.insertReturningId('tx_labels', 'txLabelId', e, trx);
|
|
798
912
|
label.txLabelId = id;
|
|
799
913
|
return label.txLabelId;
|
|
800
914
|
}
|
|
@@ -1364,27 +1478,13 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
1364
1478
|
if (isSQLite) {
|
|
1365
1479
|
await this.knex.raw('PRAGMA foreign_keys = OFF;');
|
|
1366
1480
|
}
|
|
1367
|
-
const isPostgres = this.knex.client.dialect === 'postgresql';
|
|
1368
1481
|
try {
|
|
1369
1482
|
const config = {
|
|
1370
|
-
migrationSource: new KnexMigrations_1.KnexMigrations(this.chain, storageName, storageIdentityKey, 1024
|
|
1483
|
+
migrationSource: new KnexMigrations_1.KnexMigrations(this.chain, storageName, storageIdentityKey, 1024),
|
|
1371
1484
|
// Keep DDL and its migration journal entry in the same transaction.
|
|
1372
1485
|
disableTransactions: false
|
|
1373
1486
|
};
|
|
1374
|
-
|
|
1375
|
-
// Postgres index migrations run outside a transaction (CREATE INDEX
|
|
1376
|
-
// CONCURRENTLY). When any pending migration does, knex's latest()
|
|
1377
|
-
// journals every migration of the batch outside its transaction, so
|
|
1378
|
-
// run one migration per up() to keep the others atomic with their journal row.
|
|
1379
|
-
for (;;) {
|
|
1380
|
-
const [, applied] = (await this.knex.migrate.up(config));
|
|
1381
|
-
if (applied.length === 0)
|
|
1382
|
-
break;
|
|
1383
|
-
}
|
|
1384
|
-
}
|
|
1385
|
-
else {
|
|
1386
|
-
await this.knex.migrate.latest(config);
|
|
1387
|
-
}
|
|
1487
|
+
await this.knex.migrate.latest(config);
|
|
1388
1488
|
return await this.knex.migrate.currentVersion(config);
|
|
1389
1489
|
}
|
|
1390
1490
|
finally {
|
|
@@ -1619,6 +1719,7 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
1619
1719
|
void this.select(1)
|
|
1620
1720
|
.from('action_batch_outputs as abo')
|
|
1621
1721
|
.join('action_batches as ab', 'abo.actionBatchId', 'ab.actionBatchId')
|
|
1722
|
+
// ?? quotes identifiers: Postgres lowercases unquoted names, so camelCase columns must be quoted.
|
|
1622
1723
|
.whereRaw('?? = ??', ['abo.outputId', 'o.outputId'])
|
|
1623
1724
|
.whereIn('ab.status', ['active', 'prepared'])
|
|
1624
1725
|
.where('ab.expiresAt', '>', now)
|
|
@@ -1653,6 +1754,7 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
1653
1754
|
void this.select(1)
|
|
1654
1755
|
.from('action_batch_outputs as abo')
|
|
1655
1756
|
.join('action_batches as ab', 'abo.actionBatchId', 'ab.actionBatchId')
|
|
1757
|
+
// ?? quotes identifiers: Postgres lowercases unquoted names, so camelCase columns must be quoted.
|
|
1656
1758
|
.whereRaw('?? = ??', ['abo.outputId', 'o.outputId'])
|
|
1657
1759
|
.whereIn('ab.status', ['active', 'prepared'])
|
|
1658
1760
|
.where('ab.expiresAt', '>', now)
|
|
@@ -1687,6 +1789,7 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
1687
1789
|
void this.select(1)
|
|
1688
1790
|
.from('action_batch_outputs as abo')
|
|
1689
1791
|
.join('action_batches as ab', 'abo.actionBatchId', 'ab.actionBatchId')
|
|
1792
|
+
// ?? quotes identifiers: Postgres lowercases unquoted names, so camelCase columns must be quoted.
|
|
1690
1793
|
.whereRaw('?? = ??', ['abo.outputId', 'o.outputId'])
|
|
1691
1794
|
.whereIn('ab.status', ['active', 'prepared'])
|
|
1692
1795
|
.where('ab.expiresAt', '>', now)
|
|
@@ -1876,6 +1979,7 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
1876
1979
|
const status = ['completed', 'unproven'];
|
|
1877
1980
|
if (!excludeSending)
|
|
1878
1981
|
status.push('sending');
|
|
1982
|
+
let reservedConcurrently = false;
|
|
1879
1983
|
const r = await this.knex.transaction(async (trx) => {
|
|
1880
1984
|
const baseQuery = () => trx('outputs as o')
|
|
1881
1985
|
.join('transactions as t', 'o.transactionId', 't.transactionId')
|
|
@@ -1894,42 +1998,36 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
1894
1998
|
.whereNot('o.derivationSuffix', '')
|
|
1895
1999
|
.whereNull('o.spentBy')
|
|
1896
2000
|
.whereNotExists(function () {
|
|
2001
|
+
// ?? quotes identifiers: Postgres lowercases unquoted names, so camelCase columns must be quoted.
|
|
1897
2002
|
void this.select(1).from('action_batch_outputs as abo').whereRaw('?? = ??', ['abo.outputId', 'o.outputId']);
|
|
1898
2003
|
})
|
|
1899
2004
|
.whereIn('t.status', status)
|
|
1900
2005
|
.select('o.*')
|
|
1901
2006
|
.forUpdate();
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
.first();
|
|
1919
|
-
return output;
|
|
1920
|
-
};
|
|
1921
|
-
let output = await selectOutput();
|
|
2007
|
+
let output;
|
|
2008
|
+
if (exactSatoshis !== undefined) {
|
|
2009
|
+
output = await baseQuery().where('o.satoshis', exactSatoshis).orderBy('o.outputId', 'asc').first();
|
|
2010
|
+
}
|
|
2011
|
+
output ??= await baseQuery()
|
|
2012
|
+
.where('o.satoshis', '>=', targetSatoshis)
|
|
2013
|
+
.orderBy('o.satoshis', 'asc')
|
|
2014
|
+
.orderBy('o.outputId', 'asc')
|
|
2015
|
+
.first();
|
|
2016
|
+
output ??= await baseQuery()
|
|
2017
|
+
.where('o.satoshis', '<', targetSatoshis)
|
|
2018
|
+
.orderBy('o.satoshis', 'desc')
|
|
2019
|
+
.orderBy('o.outputId', 'desc')
|
|
2020
|
+
.first();
|
|
2021
|
+
if (output == null)
|
|
2022
|
+
return undefined;
|
|
1922
2023
|
// Under Postgres READ COMMITTED the NOT EXISTS above uses the statement's
|
|
1923
2024
|
// snapshot, so an action batch reservation committed while the statement
|
|
1924
|
-
// waited for the row lock is not visible to it.
|
|
1925
|
-
|
|
1926
|
-
this.dbtype === 'Postgres' &&
|
|
2025
|
+
// waited for the row lock is not visible to it. Retry in a new transaction.
|
|
2026
|
+
if (this.dbtype === 'Postgres' &&
|
|
1927
2027
|
(await this.findReservedActionBatchOutputIds([output.outputId], trx)).length > 0) {
|
|
1928
|
-
|
|
1929
|
-
output = await selectOutput();
|
|
1930
|
-
}
|
|
1931
|
-
if (output == null)
|
|
2028
|
+
reservedConcurrently = true;
|
|
1932
2029
|
return undefined;
|
|
2030
|
+
}
|
|
1933
2031
|
await this.updateOutput(output.outputId, {
|
|
1934
2032
|
spendable: false,
|
|
1935
2033
|
spentBy: transactionId
|
|
@@ -1941,6 +2039,8 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
1941
2039
|
output.spentBy = transactionId;
|
|
1942
2040
|
return output;
|
|
1943
2041
|
});
|
|
2042
|
+
if (reservedConcurrently)
|
|
2043
|
+
return await this.allocateChangeInput(userId, basketId, targetSatoshis, exactSatoshis, excludeSending, transactionId);
|
|
1944
2044
|
return r;
|
|
1945
2045
|
}
|
|
1946
2046
|
async markChangeInputsSpent(outputIds, transactionId, trx) {
|
|
@@ -2006,8 +2106,8 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
2006
2106
|
return entities;
|
|
2007
2107
|
}
|
|
2008
2108
|
async adminStats(adminIdentityKey) {
|
|
2009
|
-
if (this.dbtype !== 'MySQL'
|
|
2010
|
-
throw new WERR_errors_1.WERR_NOT_IMPLEMENTED('adminStats, only MySQL
|
|
2109
|
+
if (this.dbtype !== 'MySQL')
|
|
2110
|
+
throw new WERR_errors_1.WERR_NOT_IMPLEMENTED('adminStats, only MySQL is supported');
|
|
2011
2111
|
const monitorEvent = (0, utilityHelpers_1.verifyOneOrNone)(await this.findMonitorEvents({
|
|
2012
2112
|
partial: { event: 'MonitorCallHistory' },
|
|
2013
2113
|
orderDescending: true,
|
|
@@ -2015,66 +2115,153 @@ class StorageKnex extends StorageProvider_1.StorageProvider {
|
|
|
2015
2115
|
}));
|
|
2016
2116
|
const monitorStats = monitorEvent != null ? JSON.parse(monitorEvent.details) : undefined;
|
|
2017
2117
|
const servicesStats = this.getServices().getServicesCallHistory(true);
|
|
2018
|
-
const
|
|
2019
|
-
const
|
|
2020
|
-
const
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2118
|
+
const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
|
|
2119
|
+
const oneWeekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString();
|
|
2120
|
+
const oneMonthAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString();
|
|
2121
|
+
const [[{ usersDay, usersMonth, usersWeek, usersTotal, transactionsDay, transactionsMonth, transactionsWeek, transactionsTotal, txCompletedDay, txCompletedMonth, txCompletedWeek, txCompletedTotal, txFailedDay, txFailedMonth, txFailedWeek, txFailedTotal, txAbandonedDay, txAbandonedMonth, txAbandonedWeek, txAbandonedTotal, txUnprocessedDay, txUnprocessedMonth, txUnprocessedWeek, txUnprocessedTotal, txSendingDay, txSendingMonth, txSendingWeek, txSendingTotal, txUnprovenDay, txUnprovenMonth, txUnprovenWeek, txUnprovenTotal, txUnsignedDay, txUnsignedMonth, txUnsignedWeek, txUnsignedTotal, txNosendDay, txNosendMonth, txNosendWeek, txNosendTotal, txNonfinalDay, txNonfinalMonth, txNonfinalWeek, txNonfinalTotal, txUnfailDay, txUnfailMonth, txUnfailWeek, txUnfailTotal, satoshisDefaultDay, satoshisDefaultMonth, satoshisDefaultWeek, satoshisDefaultTotal, satoshisOtherDay, satoshisOtherMonth, satoshisOtherWeek, satoshisOtherTotal, basketsDay, basketsMonth, basketsWeek, basketsTotal, labelsDay, labelsMonth, labelsWeek, labelsTotal, tagsDay, tagsMonth, tagsWeek, tagsTotal }]] = await this.knex.raw(`
|
|
2122
|
+
select
|
|
2123
|
+
(select count(*) from users where created_at > '${oneDayAgo}') as usersDay,
|
|
2124
|
+
(select count(*) from users where created_at > '${oneWeekAgo}') as usersWeek,
|
|
2125
|
+
(select count(*) from users where created_at > '${oneMonthAgo}') as usersMonth,
|
|
2126
|
+
(select count(*) from users) as usersTotal,
|
|
2127
|
+
(select count(*) from transactions where created_at > '${oneDayAgo}') as transactionsDay,
|
|
2128
|
+
(select count(*) from transactions where created_at > '${oneWeekAgo}') as transactionsWeek,
|
|
2129
|
+
(select count(*) from transactions where created_at > '${oneMonthAgo}') as transactionsMonth,
|
|
2130
|
+
(select count(*) from transactions) as transactionsTotal,
|
|
2131
|
+
(select count(*) from transactions where status = 'completed' and created_at > '${oneDayAgo}') as txCompletedDay,
|
|
2132
|
+
(select count(*) from transactions where status = 'completed' and created_at > '${oneWeekAgo}') as txCompletedWeek,
|
|
2133
|
+
(select count(*) from transactions where status = 'completed' and created_at > '${oneMonthAgo}') as txCompletedMonth,
|
|
2134
|
+
(select count(*) from transactions where status = 'completed') as txCompletedTotal,
|
|
2135
|
+
(select count(*) from transactions where status = 'failed' and not txid is null and created_at > '${oneDayAgo}') as txFailedDay,
|
|
2136
|
+
(select count(*) from transactions where status = 'failed' and not txid is null and created_at > '${oneWeekAgo}') as txFailedWeek,
|
|
2137
|
+
(select count(*) from transactions where status = 'failed' and not txid is null and created_at > '${oneMonthAgo}') as txFailedMonth,
|
|
2138
|
+
(select count(*) from transactions where status = 'failed' and not txid is null) as txFailedTotal,
|
|
2139
|
+
(select count(*) from transactions where status = 'failed' and txid is null and created_at > '${oneDayAgo}') as txAbandonedDay,
|
|
2140
|
+
(select count(*) from transactions where status = 'failed' and txid is null and created_at > '${oneWeekAgo}') as txAbandonedWeek,
|
|
2141
|
+
(select count(*) from transactions where status = 'failed' and txid is null and created_at > '${oneMonthAgo}') as txAbandonedMonth,
|
|
2142
|
+
(select count(*) from transactions where status = 'failed' and txid is null) as txAbandonedTotal,
|
|
2143
|
+
(select count(*) from transactions where status = 'unprocessed' and created_at > '${oneDayAgo}') as txUnprocessedDay,
|
|
2144
|
+
(select count(*) from transactions where status = 'unprocessed' and created_at > '${oneWeekAgo}') as txUnprocessedWeek,
|
|
2145
|
+
(select count(*) from transactions where status = 'unprocessed' and created_at > '${oneMonthAgo}') as txUnprocessedMonth,
|
|
2146
|
+
(select count(*) from transactions where status = 'unprocessed') as txUnprocessedTotal,
|
|
2147
|
+
(select count(*) from transactions where status = 'sending' and created_at > '${oneDayAgo}') as txSendingDay,
|
|
2148
|
+
(select count(*) from transactions where status = 'sending' and created_at > '${oneWeekAgo}') as txSendingWeek,
|
|
2149
|
+
(select count(*) from transactions where status = 'sending' and created_at > '${oneMonthAgo}') as txSendingMonth,
|
|
2150
|
+
(select count(*) from transactions where status = 'sending') as txSendingTotal,
|
|
2151
|
+
(select count(*) from transactions where status = 'unproven' and created_at > '${oneDayAgo}') as txUnprovenDay,
|
|
2152
|
+
(select count(*) from transactions where status = 'unproven' and created_at > '${oneWeekAgo}') as txUnprovenWeek,
|
|
2153
|
+
(select count(*) from transactions where status = 'unproven' and created_at > '${oneMonthAgo}') as txUnprovenMonth,
|
|
2154
|
+
(select count(*) from transactions where status = 'unproven') as txUnprovenTotal,
|
|
2155
|
+
(select count(*) from transactions where status = 'unsigned' and created_at > '${oneDayAgo}') as txUnsignedDay,
|
|
2156
|
+
(select count(*) from transactions where status = 'unsigned' and created_at > '${oneWeekAgo}') as txUnsignedWeek,
|
|
2157
|
+
(select count(*) from transactions where status = 'unsigned' and created_at > '${oneMonthAgo}') as txUnsignedMonth,
|
|
2158
|
+
(select count(*) from transactions where status = 'unsigned') as txUnsignedTotal,
|
|
2159
|
+
(select count(*) from transactions where status = 'nosend' and created_at > '${oneDayAgo}') as txNosendDay,
|
|
2160
|
+
(select count(*) from transactions where status = 'nosend' and created_at > '${oneWeekAgo}') as txNosendWeek,
|
|
2161
|
+
(select count(*) from transactions where status = 'nosend' and created_at > '${oneMonthAgo}') as txNosendMonth,
|
|
2162
|
+
(select count(*) from transactions where status = 'nosend') as txNosendTotal,
|
|
2163
|
+
(select count(*) from transactions where status = 'nonfinal' and created_at > '${oneDayAgo}') as txNonfinalDay,
|
|
2164
|
+
(select count(*) from transactions where status = 'nonfinal' and created_at > '${oneWeekAgo}') as txNonfinalWeek,
|
|
2165
|
+
(select count(*) from transactions where status = 'nonfinal' and created_at > '${oneMonthAgo}') as txNonfinalMonth,
|
|
2166
|
+
(select count(*) from transactions where status = 'nonfinal') as txNonfinalTotal,
|
|
2167
|
+
(select count(*) from transactions where status = 'unfail' and created_at > '${oneDayAgo}') as txUnfailDay,
|
|
2168
|
+
(select count(*) from transactions where status = 'unfail' and created_at > '${oneWeekAgo}') as txUnfailWeek,
|
|
2169
|
+
(select count(*) from transactions where status = 'unfail' and created_at > '${oneMonthAgo}') as txUnfailMonth,
|
|
2170
|
+
(select count(*) from transactions where status = 'unfail') as txUnfailTotal,
|
|
2171
|
+
(select sum(o.satoshis) from outputs o, transactions t where o.transactionId = t.transactionId and t.status = 'completed' and o.spendable = 1 and o.change = 1 and o.created_at > '${oneDayAgo}') as satoshisDefaultDay,
|
|
2172
|
+
(select sum(o.satoshis) from outputs o, transactions t where o.transactionId = t.transactionId and t.status = 'completed' and o.spendable = 1 and o.change = 1 and o.created_at > '${oneWeekAgo}') as satoshisDefaultWeek,
|
|
2173
|
+
(select sum(o.satoshis) from outputs o, transactions t where o.transactionId = t.transactionId and t.status = 'completed' and o.spendable = 1 and o.change = 1 and o.created_at > '${oneMonthAgo}') as satoshisDefaultMonth,
|
|
2174
|
+
(select sum(o.satoshis) from outputs o, transactions t where o.transactionId = t.transactionId and t.status = 'completed' and o.spendable = 1 and o.change = 1) as satoshisDefaultTotal,
|
|
2175
|
+
(select sum(o.satoshis) from outputs o, transactions t where o.transactionId = t.transactionId and t.status = 'completed' and o.spendable = 1 and o.change = 0 and not o.basketId is null and o.created_at > '${oneDayAgo}') as satoshisOtherDay,
|
|
2176
|
+
(select sum(o.satoshis) from outputs o, transactions t where o.transactionId = t.transactionId and t.status = 'completed' and o.spendable = 1 and o.change = 0 and not o.basketId is null and o.created_at > '${oneWeekAgo}') as satoshisOtherWeek,
|
|
2177
|
+
(select sum(o.satoshis) from outputs o, transactions t where o.transactionId = t.transactionId and t.status = 'completed' and o.spendable = 1 and o.change = 0 and not o.basketId is null and o.created_at > '${oneMonthAgo}') as satoshisOtherMonth,
|
|
2178
|
+
(select sum(o.satoshis) from outputs o, transactions t where o.transactionId = t.transactionId and t.status = 'completed' and o.spendable = 1 and o.change = 0 and not o.basketId is null) as satoshisOtherTotal,
|
|
2179
|
+
(select count(*) from output_baskets where created_at > '${oneDayAgo}') as basketsDay,
|
|
2180
|
+
(select count(*) from output_baskets where created_at > '${oneWeekAgo}') as basketsWeek,
|
|
2181
|
+
(select count(*) from output_baskets where created_at > '${oneMonthAgo}') as basketsMonth,
|
|
2182
|
+
(select count(*) from output_baskets) as basketsTotal,
|
|
2183
|
+
(select count(*) from tx_labels where created_at > '${oneDayAgo}') as labelsDay,
|
|
2184
|
+
(select count(*) from tx_labels where created_at > '${oneWeekAgo}') as labelsWeek,
|
|
2185
|
+
(select count(*) from tx_labels where created_at > '${oneMonthAgo}') as labelsMonth,
|
|
2186
|
+
(select count(*) from tx_labels) as labelsTotal,
|
|
2187
|
+
(select count(*) from output_tags where created_at > '${oneDayAgo}') as tagsDay,
|
|
2188
|
+
(select count(*) from output_tags where created_at > '${oneWeekAgo}') as tagsWeek,
|
|
2189
|
+
(select count(*) from output_tags where created_at > '${oneMonthAgo}') as tagsMonth,
|
|
2190
|
+
(select count(*) from output_tags) as tagsTotal
|
|
2191
|
+
`);
|
|
2072
2192
|
const r = {
|
|
2073
2193
|
monitorStats,
|
|
2074
2194
|
servicesStats,
|
|
2075
2195
|
requestedBy: adminIdentityKey,
|
|
2076
2196
|
when: new Date().toISOString(),
|
|
2077
|
-
|
|
2197
|
+
usersDay,
|
|
2198
|
+
usersWeek,
|
|
2199
|
+
usersMonth,
|
|
2200
|
+
usersTotal,
|
|
2201
|
+
transactionsDay,
|
|
2202
|
+
transactionsWeek,
|
|
2203
|
+
transactionsMonth,
|
|
2204
|
+
transactionsTotal,
|
|
2205
|
+
txCompletedDay,
|
|
2206
|
+
txCompletedWeek,
|
|
2207
|
+
txCompletedMonth,
|
|
2208
|
+
txCompletedTotal,
|
|
2209
|
+
txFailedDay,
|
|
2210
|
+
txFailedWeek,
|
|
2211
|
+
txFailedMonth,
|
|
2212
|
+
txFailedTotal,
|
|
2213
|
+
txAbandonedDay,
|
|
2214
|
+
txAbandonedWeek,
|
|
2215
|
+
txAbandonedMonth,
|
|
2216
|
+
txAbandonedTotal,
|
|
2217
|
+
txUnprocessedDay,
|
|
2218
|
+
txUnprocessedWeek,
|
|
2219
|
+
txUnprocessedMonth,
|
|
2220
|
+
txUnprocessedTotal,
|
|
2221
|
+
txSendingDay,
|
|
2222
|
+
txSendingWeek,
|
|
2223
|
+
txSendingMonth,
|
|
2224
|
+
txSendingTotal,
|
|
2225
|
+
txUnprovenDay,
|
|
2226
|
+
txUnprovenWeek,
|
|
2227
|
+
txUnprovenMonth,
|
|
2228
|
+
txUnprovenTotal,
|
|
2229
|
+
txUnsignedDay,
|
|
2230
|
+
txUnsignedWeek,
|
|
2231
|
+
txUnsignedMonth,
|
|
2232
|
+
txUnsignedTotal,
|
|
2233
|
+
txNosendDay,
|
|
2234
|
+
txNosendWeek,
|
|
2235
|
+
txNosendMonth,
|
|
2236
|
+
txNosendTotal,
|
|
2237
|
+
txNonfinalDay,
|
|
2238
|
+
txNonfinalWeek,
|
|
2239
|
+
txNonfinalMonth,
|
|
2240
|
+
txNonfinalTotal,
|
|
2241
|
+
txUnfailDay,
|
|
2242
|
+
txUnfailWeek,
|
|
2243
|
+
txUnfailMonth,
|
|
2244
|
+
txUnfailTotal,
|
|
2245
|
+
satoshisDefaultDay: Number(satoshisDefaultDay),
|
|
2246
|
+
satoshisDefaultWeek: Number(satoshisDefaultWeek),
|
|
2247
|
+
satoshisDefaultMonth: Number(satoshisDefaultMonth),
|
|
2248
|
+
satoshisDefaultTotal: Number(satoshisDefaultTotal),
|
|
2249
|
+
satoshisOtherDay: Number(satoshisOtherDay),
|
|
2250
|
+
satoshisOtherWeek: Number(satoshisOtherWeek),
|
|
2251
|
+
satoshisOtherMonth: Number(satoshisOtherMonth),
|
|
2252
|
+
satoshisOtherTotal: Number(satoshisOtherTotal),
|
|
2253
|
+
basketsDay,
|
|
2254
|
+
basketsWeek,
|
|
2255
|
+
basketsMonth,
|
|
2256
|
+
basketsTotal,
|
|
2257
|
+
labelsDay,
|
|
2258
|
+
labelsWeek,
|
|
2259
|
+
labelsMonth,
|
|
2260
|
+
labelsTotal,
|
|
2261
|
+
tagsDay,
|
|
2262
|
+
tagsWeek,
|
|
2263
|
+
tagsMonth,
|
|
2264
|
+
tagsTotal
|
|
2078
2265
|
};
|
|
2079
2266
|
return r;
|
|
2080
2267
|
}
|
|
@@ -2124,4 +2311,23 @@ function pagingKey(table) {
|
|
|
2124
2311
|
return [];
|
|
2125
2312
|
}
|
|
2126
2313
|
}
|
|
2314
|
+
const pgInt8Parsed = Symbol('pgInt8Parsed');
|
|
2315
|
+
/**
|
|
2316
|
+
* node-postgres returns int8 values (bigint columns such as satoshis, `count(*)`)
|
|
2317
|
+
* as strings. Set a parser on each connection this knex acquires so they come
|
|
2318
|
+
* back as numbers, as with mysql2 and better-sqlite3. The process-wide `pg.types`
|
|
2319
|
+
* defaults are left unchanged.
|
|
2320
|
+
*/
|
|
2321
|
+
function parsePostgresInt8AsNumber(knex) {
|
|
2322
|
+
const client = knex.client;
|
|
2323
|
+
if (client?.dialect !== 'postgresql' || client[pgInt8Parsed] === true)
|
|
2324
|
+
return;
|
|
2325
|
+
client[pgInt8Parsed] = true;
|
|
2326
|
+
const acquireConnection = client.acquireConnection.bind(client);
|
|
2327
|
+
client.acquireConnection = async () => {
|
|
2328
|
+
const connection = await acquireConnection();
|
|
2329
|
+
connection.setTypeParser(20, (value) => Number.parseInt(value, 10));
|
|
2330
|
+
return connection;
|
|
2331
|
+
};
|
|
2332
|
+
}
|
|
2127
2333
|
//# sourceMappingURL=StorageKnex.js.map
|