@bsv/wallet-toolbox 1.3.24 → 1.3.26
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/mobile/out/src/monitor/Monitor.d.ts.map +1 -1
- package/mobile/out/src/monitor/Monitor.js +4 -0
- package/mobile/out/src/monitor/Monitor.js.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 +102 -0
- package/mobile/out/src/sdk/WalletServices.interfaces.d.ts.map +1 -1
- package/mobile/out/src/sdk/WalletStorage.interfaces.d.ts +5 -0
- package/mobile/out/src/sdk/WalletStorage.interfaces.d.ts.map +1 -1
- package/mobile/out/src/services/ServiceCollection.d.ts +49 -1
- package/mobile/out/src/services/ServiceCollection.d.ts.map +1 -1
- package/mobile/out/src/services/ServiceCollection.js +139 -2
- package/mobile/out/src/services/ServiceCollection.js.map +1 -1
- package/mobile/out/src/services/Services.d.ts +4 -2
- package/mobile/out/src/services/Services.d.ts.map +1 -1
- package/mobile/out/src/services/Services.js +168 -74
- package/mobile/out/src/services/Services.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.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 +6 -1
- package/mobile/out/src/storage/StorageProvider.d.ts.map +1 -1
- package/mobile/out/src/storage/StorageProvider.js +1 -1
- package/mobile/out/src/storage/StorageProvider.js.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/internalizeAction.js +2 -1
- package/mobile/out/src/storage/methods/internalizeAction.js.map +1 -1
- package/mobile/package-lock.json +7 -6
- package/mobile/package.json +2 -2
- package/out/src/monitor/Monitor.d.ts.map +1 -1
- package/out/src/monitor/Monitor.js +4 -0
- package/out/src/monitor/Monitor.js.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 +102 -0
- package/out/src/sdk/WalletServices.interfaces.d.ts.map +1 -1
- package/out/src/sdk/WalletStorage.interfaces.d.ts +5 -0
- package/out/src/sdk/WalletStorage.interfaces.d.ts.map +1 -1
- package/out/src/services/ServiceCollection.d.ts +49 -1
- package/out/src/services/ServiceCollection.d.ts.map +1 -1
- package/out/src/services/ServiceCollection.js +139 -2
- package/out/src/services/ServiceCollection.js.map +1 -1
- package/out/src/services/Services.d.ts +4 -2
- package/out/src/services/Services.d.ts.map +1 -1
- package/out/src/services/Services.js +168 -74
- 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/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.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 +2 -2
- package/out/src/storage/StorageKnex.d.ts.map +1 -1
- package/out/src/storage/StorageKnex.js +55 -2
- package/out/src/storage/StorageKnex.js.map +1 -1
- package/out/src/storage/StorageProvider.d.ts +6 -1
- package/out/src/storage/StorageProvider.d.ts.map +1 -1
- package/out/src/storage/StorageProvider.js +1 -1
- package/out/src/storage/StorageProvider.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/internalizeAction.js +2 -1
- package/out/src/storage/methods/internalizeAction.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/storage/schema/entities/__tests/ProvenTxTests.test.js +11 -1
- package/out/src/storage/schema/entities/__tests/ProvenTxTests.test.js.map +1 -1
- package/out/test/Wallet/local/localWallet.man.test.js +14 -16
- package/out/test/Wallet/local/localWallet.man.test.js.map +1 -1
- package/out/test/Wallet/support/operations.man.test.js +96 -6
- package/out/test/Wallet/support/operations.man.test.js.map +1 -1
- package/out/test/storage/KnexMigrations.test.js +1 -1
- package/out/test/storage/KnexMigrations.test.js.map +1 -1
- package/out/tsconfig.all.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/monitor/Monitor.ts +4 -0
- package/src/monitor/tasks/TaskServiceCallHistory.ts +26 -0
- package/src/sdk/WalletServices.interfaces.ts +105 -0
- package/src/sdk/WalletStorage.interfaces.ts +5 -0
- package/src/services/ServiceCollection.ts +183 -2
- package/src/services/Services.ts +166 -76
- package/src/services/__tests/ArcGorillaPool.man.test.ts +108 -0
- package/src/services/createDefaultWalletServicesOptions.ts +16 -1
- package/src/services/providers/ARC.ts +8 -6
- package/src/signer/methods/internalizeAction.ts +4 -14
- package/src/storage/StorageKnex.ts +35 -4
- package/src/storage/StorageProvider.ts +8 -2
- package/src/storage/methods/createAction.ts +5 -3
- package/src/storage/methods/internalizeAction.ts +2 -1
- package/src/storage/schema/KnexMigrations.ts +13 -0
- package/src/storage/schema/entities/__tests/ProvenTxTests.test.ts +12 -1
- package/test/Wallet/local/localWallet.man.test.ts +15 -17
- package/test/Wallet/support/operations.man.test.ts +107 -7
- package/test/storage/KnexMigrations.test.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bsv/wallet-toolbox",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.26",
|
|
4
4
|
"description": "BRC100 conforming wallet, wallet storage and wallet signer components",
|
|
5
5
|
"main": "./out/src/index.js",
|
|
6
6
|
"types": "./out/src/index.d.ts",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@bsv/auth-express-middleware": "^1.1.2",
|
|
34
34
|
"@bsv/payment-express-middleware": "^1.0.6",
|
|
35
|
-
"@bsv/sdk": "^1.
|
|
35
|
+
"@bsv/sdk": "^1.5.2",
|
|
36
36
|
"express": "^4.21.2",
|
|
37
37
|
"idb": "^8.0.2",
|
|
38
38
|
"knex": "^3.1.0",
|
package/src/monitor/Monitor.ts
CHANGED
|
@@ -13,6 +13,7 @@ import { TaskFailAbandoned } from './tasks/TaskFailAbandoned'
|
|
|
13
13
|
import { TaskCheckForProofs } from './tasks/TaskCheckForProofs'
|
|
14
14
|
import { TaskClock } from './tasks/TaskClock'
|
|
15
15
|
import { TaskNewHeader } from './tasks/TaskNewHeader'
|
|
16
|
+
import { TaskServiceCallHistory } from './tasks/TaskServiceCallHistory'
|
|
16
17
|
|
|
17
18
|
import { TaskSendWaiting } from './tasks/TaskSendWaiting'
|
|
18
19
|
import { TaskCheckNoSends } from './tasks/TaskCheckNoSends'
|
|
@@ -110,6 +111,7 @@ export class Monitor {
|
|
|
110
111
|
addAllTasksToOther(): void {
|
|
111
112
|
this._otherTasks.push(new TaskClock(this))
|
|
112
113
|
this._otherTasks.push(new TaskNewHeader(this))
|
|
114
|
+
this._otherTasks.push(new TaskServiceCallHistory(this))
|
|
113
115
|
this._otherTasks.push(new TaskPurge(this, this.defaultPurgeParams))
|
|
114
116
|
this._otherTasks.push(new TaskReviewStatus(this))
|
|
115
117
|
this._otherTasks.push(new TaskSendWaiting(this))
|
|
@@ -128,6 +130,7 @@ export class Monitor {
|
|
|
128
130
|
addDefaultTasks(): void {
|
|
129
131
|
this._tasks.push(new TaskClock(this))
|
|
130
132
|
this._tasks.push(new TaskNewHeader(this))
|
|
133
|
+
this._tasks.push(new TaskServiceCallHistory(this))
|
|
131
134
|
this._tasks.push(new TaskSendWaiting(this, 8 * this.oneSecond, 7 * this.oneSecond)) // Check every 8 seconds but must be 7 seconds old
|
|
132
135
|
this._tasks.push(new TaskCheckForProofs(this, 2 * this.oneHour)) // Every two hours if no block found
|
|
133
136
|
this._tasks.push(new TaskCheckNoSends(this))
|
|
@@ -144,6 +147,7 @@ export class Monitor {
|
|
|
144
147
|
addMultiUserTasks(): void {
|
|
145
148
|
this._tasks.push(new TaskClock(this))
|
|
146
149
|
this._tasks.push(new TaskNewHeader(this))
|
|
150
|
+
this._tasks.push(new TaskServiceCallHistory(this))
|
|
147
151
|
this._tasks.push(new TaskSendWaiting(this, 8 * this.oneSecond, 7 * this.oneSecond)) // Check every 8 seconds but must be 7 seconds old
|
|
148
152
|
this._tasks.push(new TaskCheckForProofs(this, 2 * this.oneHour)) // Every two hours if no block found
|
|
149
153
|
this._tasks.push(new TaskCheckNoSends(this))
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { TableMonitorEvent } from '../../storage/index.client'
|
|
2
|
+
import { Monitor } from '../Monitor'
|
|
3
|
+
import { WalletMonitorTask } from './WalletMonitorTask'
|
|
4
|
+
|
|
5
|
+
export class TaskServiceCallHistory extends WalletMonitorTask {
|
|
6
|
+
static taskName = 'ServiceCallHistory'
|
|
7
|
+
|
|
8
|
+
constructor(
|
|
9
|
+
monitor: Monitor,
|
|
10
|
+
public triggerMsecs = monitor.oneMinute * 12
|
|
11
|
+
) {
|
|
12
|
+
super(monitor, TaskServiceCallHistory.taskName)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
trigger(nowMsecsSinceEpoch: number): { run: boolean } {
|
|
16
|
+
return {
|
|
17
|
+
run: nowMsecsSinceEpoch > this.lastRunMsecsSinceEpoch + this.triggerMsecs
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async runTask(): Promise<string> {
|
|
22
|
+
const r = await this.monitor.services.getServicesCallHistory(true)
|
|
23
|
+
const log = JSON.stringify(r)
|
|
24
|
+
return log
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -168,6 +168,12 @@ export interface WalletServices {
|
|
|
168
168
|
* @param txid
|
|
169
169
|
*/
|
|
170
170
|
getBeefForTxid(txid: string): Promise<Beef>
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* @param reset if true, ends current interval and starts a new one.
|
|
174
|
+
* @returns a history of service calls made to the configured services.
|
|
175
|
+
*/
|
|
176
|
+
getServicesCallHistory(reset?: boolean) : ServicesCallHistory
|
|
171
177
|
}
|
|
172
178
|
|
|
173
179
|
export type ScriptHashFormat = 'hashLE' | 'hashBE' | 'script'
|
|
@@ -200,6 +206,8 @@ export interface WalletServicesOptions {
|
|
|
200
206
|
chaintracks?: ChaintracksServiceClient
|
|
201
207
|
arcUrl: string
|
|
202
208
|
arcConfig: ArcConfig
|
|
209
|
+
arcGorillaPoolUrl?: string
|
|
210
|
+
arcGorillaPoolConfig?: ArcConfig
|
|
203
211
|
}
|
|
204
212
|
|
|
205
213
|
export interface GetStatusForTxidsResult {
|
|
@@ -495,3 +503,100 @@ export type UpdateFiatExchangeRateService = (
|
|
|
495
503
|
targetCurrencies: string[],
|
|
496
504
|
options: WalletServicesOptions
|
|
497
505
|
) => Promise<FiatExchangeRates>
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Type for the service call history returned by Services.getServicesCallHistory.
|
|
509
|
+
*/
|
|
510
|
+
export type ServicesCallHistory = {
|
|
511
|
+
version: number
|
|
512
|
+
getMerklePath: ServiceCallHistory
|
|
513
|
+
getRawTx: ServiceCallHistory
|
|
514
|
+
postBeef: ServiceCallHistory
|
|
515
|
+
getUtxoStatus: ServiceCallHistory
|
|
516
|
+
getStatusForTxids: ServiceCallHistory
|
|
517
|
+
getScriptHashHistory: ServiceCallHistory
|
|
518
|
+
updateFiatExchangeRates: ServiceCallHistory
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Minimum data tracked for each service call.
|
|
523
|
+
*/
|
|
524
|
+
export interface ServiceCall {
|
|
525
|
+
/**
|
|
526
|
+
* string value must be Date's toISOString format.
|
|
527
|
+
*/
|
|
528
|
+
when: Date | string
|
|
529
|
+
msecs: number
|
|
530
|
+
/**
|
|
531
|
+
* true iff service provider successfully processed the request
|
|
532
|
+
* false iff service provider failed to process the request which includes thrown errors.
|
|
533
|
+
*/
|
|
534
|
+
success: boolean
|
|
535
|
+
/**
|
|
536
|
+
* Simple text summary of result. e.g. `not a valid utxo` or `valid utxo`
|
|
537
|
+
*/
|
|
538
|
+
result?: string
|
|
539
|
+
/**
|
|
540
|
+
* Error code and message iff success is false and a exception was thrown.
|
|
541
|
+
*/
|
|
542
|
+
error?: { message: string, code: string }
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Counts of service calls over a time interval.
|
|
547
|
+
*/
|
|
548
|
+
export interface ServiceCallHistoryCounts {
|
|
549
|
+
/**
|
|
550
|
+
* count of calls returning success true.
|
|
551
|
+
*/
|
|
552
|
+
success: number
|
|
553
|
+
/**
|
|
554
|
+
* count of calls returning success false.
|
|
555
|
+
*/
|
|
556
|
+
failure: number
|
|
557
|
+
/**
|
|
558
|
+
* of failures (success false), count of calls with valid error code and message.
|
|
559
|
+
*/
|
|
560
|
+
error: number
|
|
561
|
+
/**
|
|
562
|
+
* Counts are of calls over interval `since` to `until`.
|
|
563
|
+
* string value must be Date's toISOString format.
|
|
564
|
+
*/
|
|
565
|
+
since: Date | string
|
|
566
|
+
/**
|
|
567
|
+
* Counts are of calls over interval `since` to `until`.
|
|
568
|
+
* string value must be Date's toISOString format.
|
|
569
|
+
*/
|
|
570
|
+
until: Date | string
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* History of service calls for a single service, single provider.
|
|
575
|
+
*/
|
|
576
|
+
export interface ProviderCallHistory {
|
|
577
|
+
providerName: string
|
|
578
|
+
serviceName: string
|
|
579
|
+
/**
|
|
580
|
+
* Most recent service calls.
|
|
581
|
+
* Array length is limited by Services configuration.
|
|
582
|
+
*/
|
|
583
|
+
calls: ServiceCall[]
|
|
584
|
+
/**
|
|
585
|
+
* Counts since creation of Services instance.
|
|
586
|
+
*/
|
|
587
|
+
totalCounts: ServiceCallHistoryCounts
|
|
588
|
+
/**
|
|
589
|
+
* Entry [0] is always the current interval being extended by new calls.
|
|
590
|
+
* when `getServiceCallHistory` with `reset` true is called, a new interval with zero counts is added to the start of array.
|
|
591
|
+
* Array length is limited by Services configuration.
|
|
592
|
+
*/
|
|
593
|
+
resetCounts: ServiceCallHistoryCounts[]
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
/**
|
|
597
|
+
* History of service calls for a single service, all providers.
|
|
598
|
+
*/
|
|
599
|
+
export interface ServiceCallHistory {
|
|
600
|
+
serviceName: string
|
|
601
|
+
historyByProvider: Record<string, ProviderCallHistory>
|
|
602
|
+
}
|
|
@@ -189,6 +189,11 @@ export interface FindSincePagedArgs {
|
|
|
189
189
|
since?: Date
|
|
190
190
|
paged?: Paged
|
|
191
191
|
trx?: TrxToken
|
|
192
|
+
/**
|
|
193
|
+
* Support for orderDescending is implemented in StorageKnex for basic table find methods,
|
|
194
|
+
* excluding certificate_fields table, map tables, and settings (singleton row table).
|
|
195
|
+
*/
|
|
196
|
+
orderDescending?: boolean
|
|
192
197
|
}
|
|
193
198
|
|
|
194
199
|
export interface FindForUserSincePagedArgs extends FindSincePagedArgs {
|
|
@@ -1,10 +1,23 @@
|
|
|
1
|
+
import { WalletError } from "../sdk/WalletError";
|
|
2
|
+
import { ProviderCallHistory, ServiceCallHistory } from "../sdk/WalletServices.interfaces";
|
|
3
|
+
|
|
4
|
+
const MAX_RESET_COUNTS = 32
|
|
5
|
+
const MAX_CALL_HISTORY = 32
|
|
6
|
+
|
|
1
7
|
export class ServiceCollection<T> {
|
|
2
8
|
services: { name: string; service: T }[]
|
|
3
9
|
_index: number
|
|
4
10
|
|
|
5
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Start of currentCounts interval. Initially instance construction time.
|
|
13
|
+
*/
|
|
14
|
+
readonly since: Date
|
|
15
|
+
_historyByProvider: Record<string, ProviderCallHistory> = {}
|
|
16
|
+
|
|
17
|
+
constructor(public serviceName: string, services?: { name: string; service: T }[]) {
|
|
6
18
|
this.services = services || []
|
|
7
19
|
this._index = 0
|
|
20
|
+
this.since = new Date()
|
|
8
21
|
}
|
|
9
22
|
|
|
10
23
|
add(s: { name: string; service: T }): ServiceCollection<T> {
|
|
@@ -24,6 +37,23 @@ export class ServiceCollection<T> {
|
|
|
24
37
|
return this.services[this._index].service
|
|
25
38
|
}
|
|
26
39
|
|
|
40
|
+
get serviceToCall(): ServiceToCall<T> {
|
|
41
|
+
const i = this._index
|
|
42
|
+
const name = this.services[i].name
|
|
43
|
+
const service = this.services[i].service
|
|
44
|
+
const call = { name, when: new Date(), msecs: 0, success: false, result: undefined, error: undefined }
|
|
45
|
+
return { serviceName: this.serviceName, providerName: name, service, call }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
get allServicesToCall(): ServiceToCall<T>[] {
|
|
49
|
+
const all: ServiceToCall<T>[] = []
|
|
50
|
+
for (let i = 0; i < this.services.length; i++) {
|
|
51
|
+
all.push(this.serviceToCall)
|
|
52
|
+
this.next()
|
|
53
|
+
}
|
|
54
|
+
return all
|
|
55
|
+
}
|
|
56
|
+
|
|
27
57
|
get allServices() {
|
|
28
58
|
return this.services.map(x => x.service)
|
|
29
59
|
}
|
|
@@ -45,6 +75,157 @@ export class ServiceCollection<T> {
|
|
|
45
75
|
}
|
|
46
76
|
|
|
47
77
|
clone(): ServiceCollection<T> {
|
|
48
|
-
return new ServiceCollection([...this.services])
|
|
78
|
+
return new ServiceCollection(this.serviceName, [...this.services])
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
_addServiceCall(providerName: string, call: ServiceCall): ProviderCallHistory {
|
|
82
|
+
const now = new Date()
|
|
83
|
+
let h = this._historyByProvider[providerName]
|
|
84
|
+
if (!h) {
|
|
85
|
+
h = {
|
|
86
|
+
serviceName: this.serviceName,
|
|
87
|
+
providerName: providerName,
|
|
88
|
+
calls: [],
|
|
89
|
+
totalCounts: { success: 0, failure: 0, error: 0, since: this.since, until: now },
|
|
90
|
+
resetCounts: [{ success: 0, failure: 0, error: 0, since: this.since, until: now }]
|
|
91
|
+
}
|
|
92
|
+
this._historyByProvider[providerName] = h
|
|
93
|
+
}
|
|
94
|
+
h.calls.unshift(call)
|
|
95
|
+
h.calls = h.calls.slice(0,MAX_CALL_HISTORY)
|
|
96
|
+
h.totalCounts.until = now
|
|
97
|
+
h.resetCounts[0].until = now
|
|
98
|
+
return h
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
getDuration(since: Date | string): number {
|
|
102
|
+
const now = new Date()
|
|
103
|
+
if (typeof since === 'string') since = new Date(since)
|
|
104
|
+
return now.getTime() - since.getTime()
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
addServiceCallSuccess(stc: ServiceToCall<T>, result?: string): void {
|
|
108
|
+
const call = stc.call
|
|
109
|
+
call.success = true
|
|
110
|
+
call.result = result
|
|
111
|
+
call.error = undefined
|
|
112
|
+
call.msecs = this.getDuration(call.when)
|
|
113
|
+
const h = this._addServiceCall(stc.providerName, call)
|
|
114
|
+
h.totalCounts.success++
|
|
115
|
+
h.resetCounts[0].success++
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
addServiceCallFailure(stc: ServiceToCall<T>, result?: string): void {
|
|
119
|
+
const call = stc.call
|
|
120
|
+
call.success = false
|
|
121
|
+
call.result = result
|
|
122
|
+
call.error = undefined
|
|
123
|
+
call.msecs = this.getDuration(call.when)
|
|
124
|
+
const h = this._addServiceCall(this.name, call)
|
|
125
|
+
h.totalCounts.failure++
|
|
126
|
+
h.resetCounts[0].failure++
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
addServiceCallError(stc: ServiceToCall<T>, error: WalletError): void {
|
|
130
|
+
const call = stc.call
|
|
131
|
+
call.success = false
|
|
132
|
+
call.result = undefined
|
|
133
|
+
call.error = error
|
|
134
|
+
call.msecs = this.getDuration(call.when)
|
|
135
|
+
const h = this._addServiceCall(this.name, call)
|
|
136
|
+
h.totalCounts.failure++
|
|
137
|
+
h.totalCounts.error++
|
|
138
|
+
h.resetCounts[0].failure++
|
|
139
|
+
h.resetCounts[0].error++
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @returns A copy of current service call history
|
|
144
|
+
*/
|
|
145
|
+
getServiceCallHistory(reset?: boolean): ServiceCallHistory {
|
|
146
|
+
const now = new Date()
|
|
147
|
+
const history: ServiceCallHistory = { serviceName: this.serviceName, historyByProvider: {} }
|
|
148
|
+
for (const name of Object.keys(this._historyByProvider)) {
|
|
149
|
+
const h = this._historyByProvider[name]
|
|
150
|
+
const c: ProviderCallHistory = {
|
|
151
|
+
serviceName: h.serviceName,
|
|
152
|
+
providerName: h.providerName,
|
|
153
|
+
calls: h.calls.map(c => ({
|
|
154
|
+
when: dateToString(c.when),
|
|
155
|
+
msecs: c.msecs,
|
|
156
|
+
success: c.success,
|
|
157
|
+
result: c.result,
|
|
158
|
+
error: c.error ? { message: c.error.message, code: c.error.code } : undefined
|
|
159
|
+
})),
|
|
160
|
+
totalCounts: {
|
|
161
|
+
success: h.totalCounts.success,
|
|
162
|
+
failure: h.totalCounts.failure,
|
|
163
|
+
error: h.totalCounts.error,
|
|
164
|
+
since: dateToString(h.totalCounts.since),
|
|
165
|
+
until: dateToString(h.totalCounts.until)
|
|
166
|
+
},
|
|
167
|
+
resetCounts: []
|
|
168
|
+
}
|
|
169
|
+
for (let i = 0; i < h.resetCounts.length; i++) {
|
|
170
|
+
const r = h.resetCounts[i]
|
|
171
|
+
c.resetCounts.push({
|
|
172
|
+
success: r.success,
|
|
173
|
+
failure: r.failure,
|
|
174
|
+
error: r.error,
|
|
175
|
+
since: dateToString(r.since),
|
|
176
|
+
until: dateToString(r.until)
|
|
177
|
+
})
|
|
178
|
+
}
|
|
179
|
+
history.historyByProvider[name] = c
|
|
180
|
+
if (reset) {
|
|
181
|
+
// Make sure intervals are continuous.
|
|
182
|
+
h.resetCounts[0].until = now
|
|
183
|
+
// insert a new resetCounts interval
|
|
184
|
+
h.resetCounts.unshift({
|
|
185
|
+
success: 0,
|
|
186
|
+
failure: 0,
|
|
187
|
+
error: 0,
|
|
188
|
+
// start of new interval
|
|
189
|
+
since: now,
|
|
190
|
+
// end of new interval, gets bumped with each new call added
|
|
191
|
+
until: now
|
|
192
|
+
})
|
|
193
|
+
// limit history to most recent intervals
|
|
194
|
+
h.resetCounts = h.resetCounts.slice(0, MAX_CALL_HISTORY)
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return history
|
|
198
|
+
|
|
199
|
+
function dateToString(d: Date | string): string {
|
|
200
|
+
return typeof d === 'string' ? d : d.toISOString()
|
|
201
|
+
}
|
|
49
202
|
}
|
|
50
203
|
}
|
|
204
|
+
|
|
205
|
+
export interface ServiceCall {
|
|
206
|
+
/**
|
|
207
|
+
* string value must be Date's toISOString format.
|
|
208
|
+
*/
|
|
209
|
+
when: Date | string
|
|
210
|
+
msecs: number
|
|
211
|
+
/**
|
|
212
|
+
* true iff service provider successfully processed the request
|
|
213
|
+
* false iff service provider failed to process the request which includes thrown errors.
|
|
214
|
+
*/
|
|
215
|
+
success: boolean
|
|
216
|
+
/**
|
|
217
|
+
* Simple text summary of result. e.g. `not a valid utxo` or `valid utxo`
|
|
218
|
+
*/
|
|
219
|
+
result?: string
|
|
220
|
+
/**
|
|
221
|
+
* Error code and message iff success is false and a exception was thrown.
|
|
222
|
+
*/
|
|
223
|
+
error?: { message: string, code: string }
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export interface ServiceToCall<T> {
|
|
227
|
+
providerName: string
|
|
228
|
+
serviceName: string
|
|
229
|
+
service: T
|
|
230
|
+
call: ServiceCall
|
|
231
|
+
}
|