@keetanetwork/anchor 0.0.38 → 0.0.40
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/client/index.d.ts +6 -0
- package/client/index.d.ts.map +1 -1
- package/client/index.js +7 -0
- package/client/index.js.map +1 -1
- package/lib/block-listener.d.ts +93 -0
- package/lib/block-listener.d.ts.map +1 -0
- package/lib/block-listener.js +259 -0
- package/lib/block-listener.js.map +1 -0
- package/lib/encrypted-container.d.ts +53 -3
- package/lib/encrypted-container.d.ts.map +1 -1
- package/lib/encrypted-container.js +549 -93
- package/lib/encrypted-container.js.map +1 -1
- package/lib/error.d.ts.map +1 -1
- package/lib/error.js +3 -1
- package/lib/error.js.map +1 -1
- package/lib/http-server/index.d.ts +14 -1
- package/lib/http-server/index.d.ts.map +1 -1
- package/lib/http-server/index.js +144 -12
- package/lib/http-server/index.js.map +1 -1
- package/lib/queue/drivers/queue_firestore.d.ts +29 -0
- package/lib/queue/drivers/queue_firestore.d.ts.map +1 -0
- package/lib/queue/drivers/queue_firestore.js +279 -0
- package/lib/queue/drivers/queue_firestore.js.map +1 -0
- package/lib/queue/index.d.ts +74 -3
- package/lib/queue/index.d.ts.map +1 -1
- package/lib/queue/index.js +161 -36
- package/lib/queue/index.js.map +1 -1
- package/lib/resolver.d.ts +61 -15
- package/lib/resolver.d.ts.map +1 -1
- package/lib/resolver.js +1132 -686
- package/lib/resolver.js.map +1 -1
- package/lib/utils/signing.d.ts +12 -3
- package/lib/utils/signing.d.ts.map +1 -1
- package/lib/utils/signing.js +7 -13
- package/lib/utils/signing.js.map +1 -1
- package/npm-shrinkwrap.json +6 -6
- package/package.json +2 -1
- package/services/asset-movement/client.d.ts +10 -3
- package/services/asset-movement/client.d.ts.map +1 -1
- package/services/asset-movement/client.js +36 -3
- package/services/asset-movement/client.js.map +1 -1
- package/services/asset-movement/common.d.ts +57 -22
- package/services/asset-movement/common.d.ts.map +1 -1
- package/services/asset-movement/common.js +370 -70
- package/services/asset-movement/common.js.map +1 -1
- package/services/fx/client.d.ts +15 -3
- package/services/fx/client.d.ts.map +1 -1
- package/services/fx/client.js +18 -0
- package/services/fx/client.js.map +1 -1
- package/services/fx/common.d.ts +1 -1
- package/services/fx/common.js.map +1 -1
- package/services/fx/server.d.ts +59 -9
- package/services/fx/server.d.ts.map +1 -1
- package/services/fx/server.js +337 -140
- package/services/fx/server.js.map +1 -1
- package/services/fx/util.d.ts +26 -8
- package/services/fx/util.d.ts.map +1 -1
- package/services/fx/util.js +92 -4
- package/services/fx/util.js.map +1 -1
- package/services/storage/client.d.ts +322 -0
- package/services/storage/client.d.ts.map +1 -0
- package/services/storage/client.js +1058 -0
- package/services/storage/client.js.map +1 -0
- package/services/storage/common.d.ts +653 -0
- package/services/storage/common.d.ts.map +1 -0
- package/services/storage/common.generated.d.ts +17 -0
- package/services/storage/common.generated.d.ts.map +1 -0
- package/services/storage/common.generated.js +863 -0
- package/services/storage/common.generated.js.map +1 -0
- package/services/storage/common.js +587 -0
- package/services/storage/common.js.map +1 -0
- package/services/storage/lib/validators.d.ts +64 -0
- package/services/storage/lib/validators.d.ts.map +1 -0
- package/services/storage/lib/validators.js +82 -0
- package/services/storage/lib/validators.js.map +1 -0
- package/services/storage/server.d.ts +127 -0
- package/services/storage/server.d.ts.map +1 -0
- package/services/storage/server.js +626 -0
- package/services/storage/server.js.map +1 -0
- package/services/storage/test-utils.d.ts +70 -0
- package/services/storage/test-utils.d.ts.map +1 -0
- package/services/storage/test-utils.js +347 -0
- package/services/storage/test-utils.js.map +1 -0
- package/services/storage/utils.d.ts +3 -0
- package/services/storage/utils.d.ts.map +1 -0
- package/services/storage/utils.js +10 -0
- package/services/storage/utils.js.map +1 -0
- package/services/username/client.d.ts +145 -0
- package/services/username/client.d.ts.map +1 -0
- package/services/username/client.js +681 -0
- package/services/username/client.js.map +1 -0
- package/services/username/common.d.ts +136 -0
- package/services/username/common.d.ts.map +1 -0
- package/services/username/common.generated.d.ts +13 -0
- package/services/username/common.generated.d.ts.map +1 -0
- package/services/username/common.generated.js +256 -0
- package/services/username/common.generated.js.map +1 -0
- package/services/username/common.js +226 -0
- package/services/username/common.js.map +1 -0
- package/services/username/server.d.ts +51 -0
- package/services/username/server.d.ts.map +1 -0
- package/services/username/server.js +264 -0
- package/services/username/server.js.map +1 -0
package/client/index.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ import * as lib from '../lib/index.js';
|
|
|
6
6
|
import * as KeetaNet from '@keetanetwork/keetanet-client';
|
|
7
7
|
import type { KeetaAssetMovementClientConfig } from '../services/asset-movement/client.ts';
|
|
8
8
|
import KeetaAssetMovementAnchorClient from '../services/asset-movement/client.js';
|
|
9
|
+
import type { KeetaUsernameAnchorClientConfig } from '../services/username/client.ts';
|
|
10
|
+
import KeetaUsernameAnchorClient from '../services/username/client.js';
|
|
9
11
|
export declare namespace KYC {
|
|
10
12
|
type ClientConfig = KeetaKYCAnchorClientConfig;
|
|
11
13
|
const Client: typeof KeetaKYCAnchorClient;
|
|
@@ -18,5 +20,9 @@ export declare namespace AssetMovement {
|
|
|
18
20
|
type ClientConfig = KeetaAssetMovementClientConfig;
|
|
19
21
|
const Client: typeof KeetaAssetMovementAnchorClient;
|
|
20
22
|
}
|
|
23
|
+
export declare namespace Username {
|
|
24
|
+
type ClientConfig = KeetaUsernameAnchorClientConfig;
|
|
25
|
+
const Client: typeof KeetaUsernameAnchorClient;
|
|
26
|
+
}
|
|
21
27
|
export { lib, KeetaNet };
|
|
22
28
|
//# sourceMappingURL=index.d.ts.map
|
package/client/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,0BAA0B,EAC1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EACX,yBAAyB,EACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,oBAAoB,MAAM,2BAA2B,CAAC;AAC7D,OAAO,mBAAmB,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,GAAG,MAAM,iBAAiB,CAAC;AACvC,OAAO,KAAK,QAAQ,MAAM,+BAA+B,CAAC;AAC1D,OAAO,KAAK,EACX,8BAA8B,EAC9B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,8BAA8B,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,0BAA0B,EAC1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EACX,yBAAyB,EACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,oBAAoB,MAAM,2BAA2B,CAAC;AAC7D,OAAO,mBAAmB,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,GAAG,MAAM,iBAAiB,CAAC;AACvC,OAAO,KAAK,QAAQ,MAAM,+BAA+B,CAAC;AAC1D,OAAO,KAAK,EACX,8BAA8B,EAC9B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,8BAA8B,MAAM,sCAAsC,CAAC;AAClF,OAAO,KAAK,EACX,+BAA+B,EAC/B,MAAM,gCAAgC,CAAC;AACxC,OAAO,yBAAyB,MAAM,gCAAgC,CAAC;AAIvE,yBAAiB,GAAG,CAAC;IACpB,KAAY,YAAY,GAAG,0BAA0B,CAAC;IAC/C,MAAM,MAAM,EAAE,OAAO,oBAA2C,CAAC;CACxE;AAGD,yBAAiB,EAAE,CAAC;IACnB,KAAY,YAAY,GAAG,yBAAyB,CAAC;IAC9C,MAAM,MAAM,EAAE,OAAO,mBAAyC,CAAC;CACtE;AAGD,yBAAiB,aAAa,CAAC;IAC9B,KAAY,YAAY,GAAG,8BAA8B,CAAC;IACnD,MAAM,MAAM,EAAE,OAAO,8BAA+D,CAAC;CAC5F;AAGD,yBAAiB,QAAQ,CAAC;IACzB,KAAY,YAAY,GAAG,+BAA+B,CAAC;IACpD,MAAM,MAAM,EAAE,OAAO,yBAAqD,CAAC;CAClF;AAED,OAAO,EACN,GAAG,EACH,QAAQ,EACR,CAAC"}
|
package/client/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import KeetaFXAnchorClient from '../services/fx/client.js';
|
|
|
3
3
|
import * as lib from '../lib/index.js';
|
|
4
4
|
import * as KeetaNet from '@keetanetwork/keetanet-client';
|
|
5
5
|
import KeetaAssetMovementAnchorClient from '../services/asset-movement/client.js';
|
|
6
|
+
import KeetaUsernameAnchorClient from '../services/username/client.js';
|
|
6
7
|
// TODO: Determine how we want to export the client
|
|
7
8
|
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
8
9
|
export var KYC;
|
|
@@ -21,5 +22,11 @@ export var AssetMovement;
|
|
|
21
22
|
(function (AssetMovement) {
|
|
22
23
|
AssetMovement.Client = KeetaAssetMovementAnchorClient;
|
|
23
24
|
})(AssetMovement || (AssetMovement = {}));
|
|
25
|
+
// TODO: Determine how we want to export the client
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
27
|
+
export var Username;
|
|
28
|
+
(function (Username) {
|
|
29
|
+
Username.Client = KeetaUsernameAnchorClient;
|
|
30
|
+
})(Username || (Username = {}));
|
|
24
31
|
export { lib, KeetaNet };
|
|
25
32
|
//# sourceMappingURL=index.js.map
|
package/client/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAMA,OAAO,oBAAoB,MAAM,2BAA2B,CAAC;AAC7D,OAAO,mBAAmB,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,GAAG,MAAM,iBAAiB,CAAC;AACvC,OAAO,KAAK,QAAQ,MAAM,+BAA+B,CAAC;AAI1D,OAAO,8BAA8B,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAMA,OAAO,oBAAoB,MAAM,2BAA2B,CAAC;AAC7D,OAAO,mBAAmB,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,GAAG,MAAM,iBAAiB,CAAC;AACvC,OAAO,KAAK,QAAQ,MAAM,+BAA+B,CAAC;AAI1D,OAAO,8BAA8B,MAAM,sCAAsC,CAAC;AAIlF,OAAO,yBAAyB,MAAM,gCAAgC,CAAC;AAEvE,mDAAmD;AACnD,2DAA2D;AAC3D,MAAM,KAAW,GAAG,CAGnB;AAHD,WAAiB,GAAG;IAEN,UAAM,GAAgC,oBAAoB,CAAC;AACzE,CAAC,EAHgB,GAAG,KAAH,GAAG,QAGnB;AACD,mDAAmD;AACnD,2DAA2D;AAC3D,MAAM,KAAW,EAAE,CAGlB;AAHD,WAAiB,EAAE;IAEL,SAAM,GAA+B,mBAAmB,CAAC;AACvE,CAAC,EAHgB,EAAE,KAAF,EAAE,QAGlB;AACD,mDAAmD;AACnD,2DAA2D;AAC3D,MAAM,KAAW,aAAa,CAG7B;AAHD,WAAiB,aAAa;IAEhB,oBAAM,GAA0C,8BAA8B,CAAC;AAC7F,CAAC,EAHgB,aAAa,KAAb,aAAa,QAG7B;AACD,mDAAmD;AACnD,2DAA2D;AAC3D,MAAM,KAAW,QAAQ,CAGxB;AAHD,WAAiB,QAAQ;IAEX,eAAM,GAAqC,yBAAyB,CAAC;AACnF,CAAC,EAHgB,QAAQ,KAAR,QAAQ,QAGxB;AAED,OAAO,EACN,GAAG,EACH,QAAQ,EACR,CAAC","sourcesContent":["import type {\n\tKeetaKYCAnchorClientConfig\n} from '../services/kyc/client.ts';\nimport type {\n\tKeetaFXAnchorClientConfig\n} from '../services/fx/client.ts';\nimport KeetaKYCAnchorClient from '../services/kyc/client.js';\nimport KeetaFXAnchorClient from '../services/fx/client.js';\nimport * as lib from '../lib/index.js';\nimport * as KeetaNet from '@keetanetwork/keetanet-client';\nimport type {\n\tKeetaAssetMovementClientConfig\n} from '../services/asset-movement/client.ts';\nimport KeetaAssetMovementAnchorClient from '../services/asset-movement/client.js';\nimport type {\n\tKeetaUsernameAnchorClientConfig\n} from '../services/username/client.ts';\nimport KeetaUsernameAnchorClient from '../services/username/client.js';\n\n// TODO: Determine how we want to export the client\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace KYC {\n\texport type ClientConfig = KeetaKYCAnchorClientConfig;\n\texport const Client: typeof KeetaKYCAnchorClient = KeetaKYCAnchorClient;\n}\n// TODO: Determine how we want to export the client\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace FX {\n\texport type ClientConfig = KeetaFXAnchorClientConfig;\n\texport const Client: typeof KeetaFXAnchorClient = KeetaFXAnchorClient;\n}\n// TODO: Determine how we want to export the client\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace AssetMovement {\n\texport type ClientConfig = KeetaAssetMovementClientConfig;\n\texport const Client: typeof KeetaAssetMovementAnchorClient = KeetaAssetMovementAnchorClient;\n}\n// TODO: Determine how we want to export the client\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace Username {\n\texport type ClientConfig = KeetaUsernameAnchorClientConfig;\n\texport const Client: typeof KeetaUsernameAnchorClient = KeetaUsernameAnchorClient;\n}\n\nexport {\n\tlib,\n\tKeetaNet\n};\n"]}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { Client } from "@keetanetwork/keetanet-client";
|
|
2
|
+
import type { Logger } from "./log/index.js";
|
|
3
|
+
import type { Block, BlockHash } from "@keetanetwork/keetanet-client/lib/block/index.js";
|
|
4
|
+
import type { BlockOperations } from "@keetanetwork/keetanet-client/lib/block/operations.js";
|
|
5
|
+
import { KeetaAnchorQueueRunner } from "./queue/index.js";
|
|
6
|
+
import type { KeetaAnchorQueueEntryExtra, KeetaAnchorQueueRequestID } from "./queue/index.js";
|
|
7
|
+
import type { JSONSerializable } from "./utils/json.js";
|
|
8
|
+
import type { KeetaAnchorQueueRunOptions } from "./queue/common.js";
|
|
9
|
+
interface BlockListenerConfig {
|
|
10
|
+
client: Client;
|
|
11
|
+
logger?: Logger;
|
|
12
|
+
}
|
|
13
|
+
interface BlockListenerContext {
|
|
14
|
+
block: Block;
|
|
15
|
+
}
|
|
16
|
+
interface NetworkListenerArguments {
|
|
17
|
+
'block': {
|
|
18
|
+
callback: (data: BlockListenerContext) => (Promise<{
|
|
19
|
+
requiresWork?: boolean;
|
|
20
|
+
}> | {
|
|
21
|
+
requiresWork?: boolean;
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
interface BlockListenerScanOptions {
|
|
26
|
+
searchTo?: {
|
|
27
|
+
extended: true;
|
|
28
|
+
} | number | undefined;
|
|
29
|
+
}
|
|
30
|
+
export declare class BlockListener {
|
|
31
|
+
#private;
|
|
32
|
+
constructor(config: BlockListenerConfig);
|
|
33
|
+
get logger(): Logger | undefined;
|
|
34
|
+
scan(options?: BlockListenerScanOptions): Promise<{
|
|
35
|
+
listenersHaveWork: boolean;
|
|
36
|
+
}>;
|
|
37
|
+
on<K extends keyof NetworkListenerArguments>(_ignore_type: K, args: NetworkListenerArguments[K]): {
|
|
38
|
+
remove: () => void;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
type BlockQueueRunnerRequest = {
|
|
42
|
+
blockHash: BlockHash;
|
|
43
|
+
};
|
|
44
|
+
type BlockQueueRunnerRequestSerialized = {
|
|
45
|
+
blockHash: string;
|
|
46
|
+
};
|
|
47
|
+
interface BaseBlockOperationQueueRunnerScanOptionsRequired {
|
|
48
|
+
scanWhenRunning: true;
|
|
49
|
+
extendedScanIntervalMs: number;
|
|
50
|
+
regularScanIntervalMs: number;
|
|
51
|
+
}
|
|
52
|
+
type BlockOperationQueueRunnerConfig<Request, Result, RequestSerialized extends JSONSerializable, ResultSerialized extends JSONSerializable | null> = ConstructorParameters<typeof KeetaAnchorQueueRunner<Request, Result, RequestSerialized, ResultSerialized>>[0] & {
|
|
53
|
+
listener: BlockListener | BlockListenerConfig;
|
|
54
|
+
scanOptions?: Partial<BaseBlockOperationQueueRunnerScanOptionsRequired> | {
|
|
55
|
+
scanWhenRunning: false;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
declare abstract class BaseBlockOperationQueueRunner<Request, Result = null, RequestSerialized extends JSONSerializable = JSONSerializable, ResultSerialized extends JSONSerializable = null> extends KeetaAnchorQueueRunner<Request, Result, RequestSerialized, ResultSerialized> {
|
|
59
|
+
#private;
|
|
60
|
+
constructor(config: BlockOperationQueueRunnerConfig<Request, Result, RequestSerialized, ResultSerialized>);
|
|
61
|
+
protected abstract onBlockSeen(block: Block): Promise<boolean>;
|
|
62
|
+
protected decodeResponse(response: ResultSerialized): Result | null;
|
|
63
|
+
protected encodeResponse(response: Result): ResultSerialized;
|
|
64
|
+
run(options?: KeetaAnchorQueueRunOptions): Promise<boolean>;
|
|
65
|
+
[Symbol.dispose](): void;
|
|
66
|
+
}
|
|
67
|
+
export declare abstract class BlockQueueRunner<UserResult = null, QueueResult extends JSONSerializable = null> extends BaseBlockOperationQueueRunner<BlockQueueRunnerRequest, UserResult, BlockQueueRunnerRequestSerialized, QueueResult> {
|
|
68
|
+
protected abstract filterBlock(block: Block): (boolean | Promise<boolean>);
|
|
69
|
+
protected decodeRequest(request: BlockQueueRunnerRequestSerialized): BlockQueueRunnerRequest;
|
|
70
|
+
protected encodeRequest(request: BlockQueueRunnerRequest): BlockQueueRunnerRequestSerialized;
|
|
71
|
+
protected onBlockSeen(block: Block): Promise<boolean>;
|
|
72
|
+
add(request: BlockQueueRunnerRequest, info?: KeetaAnchorQueueEntryExtra): Promise<KeetaAnchorQueueRequestID>;
|
|
73
|
+
}
|
|
74
|
+
type OperationQueueRunnerRequest = {
|
|
75
|
+
blockHash: BlockHash;
|
|
76
|
+
operationIndex: number;
|
|
77
|
+
};
|
|
78
|
+
type OperationQueueRunnerRequestSerialized = {
|
|
79
|
+
blockHash: string;
|
|
80
|
+
operationIndex: number;
|
|
81
|
+
};
|
|
82
|
+
export declare abstract class OperationQueueRunner<UserResult = null, QueueResult extends JSONSerializable = null> extends BaseBlockOperationQueueRunner<OperationQueueRunnerRequest, UserResult, OperationQueueRunnerRequestSerialized, QueueResult> {
|
|
83
|
+
protected abstract filterOperation(operation: BlockOperations, context: {
|
|
84
|
+
block: Block;
|
|
85
|
+
operationIndex: number;
|
|
86
|
+
}): (boolean | Promise<boolean>);
|
|
87
|
+
protected decodeRequest(request: OperationQueueRunnerRequestSerialized): OperationQueueRunnerRequest;
|
|
88
|
+
protected encodeRequest(request: OperationQueueRunnerRequest): OperationQueueRunnerRequestSerialized;
|
|
89
|
+
protected onBlockSeen(block: Block): Promise<boolean>;
|
|
90
|
+
add(request: OperationQueueRunnerRequest, info?: KeetaAnchorQueueEntryExtra): Promise<KeetaAnchorQueueRequestID>;
|
|
91
|
+
}
|
|
92
|
+
export {};
|
|
93
|
+
//# sourceMappingURL=block-listener.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block-listener.d.ts","sourceRoot":"","sources":["../../src/lib/block-listener.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { KeetaAnchorQueueRunner } from "./queue/index.js";
|
|
2
|
+
import { KeetaNet } from "../client/index.js";
|
|
3
|
+
import { ConvertStringToRequestID } from "./queue/internal.js";
|
|
4
|
+
export class BlockListener {
|
|
5
|
+
#config;
|
|
6
|
+
#blockListeners = [];
|
|
7
|
+
constructor(config) {
|
|
8
|
+
this.#config = config;
|
|
9
|
+
}
|
|
10
|
+
get #client() {
|
|
11
|
+
return (this.#config.client);
|
|
12
|
+
}
|
|
13
|
+
get logger() {
|
|
14
|
+
return (this.#config.logger);
|
|
15
|
+
}
|
|
16
|
+
async #runWithLog(label, func) {
|
|
17
|
+
try {
|
|
18
|
+
await func();
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
this.logger?.error(`BlockListener::${label}`, `Received Error running`, error);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async #processBlockListeners(block) {
|
|
25
|
+
let listenersHaveWork = false;
|
|
26
|
+
const promises = [];
|
|
27
|
+
for (const listener of this.#blockListeners) {
|
|
28
|
+
promises.push(this.#runWithLog('block callback', async function () {
|
|
29
|
+
const response = await listener.callback({ block });
|
|
30
|
+
if (response.requiresWork) {
|
|
31
|
+
listenersHaveWork = true;
|
|
32
|
+
}
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
await Promise.allSettled(promises);
|
|
36
|
+
return ({ listenersHaveWork });
|
|
37
|
+
}
|
|
38
|
+
async scan(options) {
|
|
39
|
+
let listenersHaveWork = false;
|
|
40
|
+
try {
|
|
41
|
+
let reachedEndOfTime = false;
|
|
42
|
+
let startBlocksHash;
|
|
43
|
+
let pageCount = 0;
|
|
44
|
+
/*
|
|
45
|
+
* Either perform an extended
|
|
46
|
+
* scan (30 days) or a short
|
|
47
|
+
* scan (4 hours) to find
|
|
48
|
+
* relevant operations
|
|
49
|
+
*/
|
|
50
|
+
const now = Date.now();
|
|
51
|
+
let oldestVoteStapleToCheck = now - (4 * 60 * 60 * 1000); // 4 hours ago
|
|
52
|
+
if (options?.searchTo) {
|
|
53
|
+
if (typeof options.searchTo === 'number') {
|
|
54
|
+
if (options.searchTo >= now || options.searchTo <= 0) {
|
|
55
|
+
throw (new Error('BlockListener::scan: When providing searchTo as a number, it must be a timestamp in the past'));
|
|
56
|
+
}
|
|
57
|
+
oldestVoteStapleToCheck = options.searchTo;
|
|
58
|
+
}
|
|
59
|
+
else if ('extended' in options.searchTo) {
|
|
60
|
+
oldestVoteStapleToCheck = now - (30 * 24 * 60 * 60 * 1000); // 30 days ago
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
throw (new Error('BlockListener::scan: Invalid searchTo option provided'));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
while (!reachedEndOfTime) {
|
|
67
|
+
pageCount++;
|
|
68
|
+
const historyOptions = { depth: 20, ...(startBlocksHash ? { startBlocksHash } : {}) };
|
|
69
|
+
this.logger?.debug('BlockListener::poll', `Fetching history page ${pageCount}`, { ...historyOptions });
|
|
70
|
+
const history = await this.#client.getHistory(null, historyOptions);
|
|
71
|
+
if (history.length === 0) {
|
|
72
|
+
this.logger?.debug('BlockListener::poll', `No more history found, ending discovery`);
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
const processBlocksPromises = [];
|
|
76
|
+
for (const { voteStaple } of history) {
|
|
77
|
+
if (voteStaple.timestamp().valueOf() < oldestVoteStapleToCheck) {
|
|
78
|
+
this.logger?.debug('BlockListener::poll', 'Reached vote staple older than scanning time, ending discovery for this run', { voteStapleTime: voteStaple.timestamp(), oldestVoteStapleToCheck: new Date(oldestVoteStapleToCheck) });
|
|
79
|
+
reachedEndOfTime = true;
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
for (const block of voteStaple.blocks) {
|
|
83
|
+
processBlocksPromises.push(this.#processBlockListeners(block));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const processBlockPromiseResults = await Promise.all(processBlocksPromises);
|
|
87
|
+
if (processBlockPromiseResults.some(result => result.listenersHaveWork)) {
|
|
88
|
+
listenersHaveWork = true;
|
|
89
|
+
}
|
|
90
|
+
// Set up for next page
|
|
91
|
+
const lastVoteStaple = history[history.length - 1]?.voteStaple;
|
|
92
|
+
if (lastVoteStaple) {
|
|
93
|
+
startBlocksHash = lastVoteStaple.blocksHash;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
this.logger?.error('BlockListener::poll', 'Error during discovery:', error);
|
|
102
|
+
}
|
|
103
|
+
return ({ listenersHaveWork });
|
|
104
|
+
}
|
|
105
|
+
on(_ignore_type, args) {
|
|
106
|
+
const id = String(Math.random());
|
|
107
|
+
this.#blockListeners.push({ ...args, id });
|
|
108
|
+
return ({
|
|
109
|
+
remove: () => {
|
|
110
|
+
const index = this.#blockListeners.findIndex(listener => listener.id === id);
|
|
111
|
+
if (index !== -1) {
|
|
112
|
+
this.#blockListeners.splice(index, 1);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
class BaseBlockOperationQueueRunner extends KeetaAnchorQueueRunner {
|
|
119
|
+
#listener;
|
|
120
|
+
#lastExtendedScanTime = null;
|
|
121
|
+
#lastScanTime = null;
|
|
122
|
+
#scanOptions;
|
|
123
|
+
#removeListenerCallback;
|
|
124
|
+
constructor(config) {
|
|
125
|
+
const { listener, ...restConfig } = config;
|
|
126
|
+
super(restConfig);
|
|
127
|
+
if (listener instanceof BlockListener) {
|
|
128
|
+
this.#listener = listener;
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
this.#listener = new BlockListener(listener);
|
|
132
|
+
}
|
|
133
|
+
const addedListener = this.#listener.on('block', {
|
|
134
|
+
callback: async ({ block }) => {
|
|
135
|
+
return ({ requiresWork: await this.onBlockSeen(block) });
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
this.#removeListenerCallback = addedListener.remove;
|
|
139
|
+
if (!config.scanOptions || config.scanOptions?.scanWhenRunning || config.scanOptions?.scanWhenRunning === undefined) {
|
|
140
|
+
this.#scanOptions = {
|
|
141
|
+
scanWhenRunning: true,
|
|
142
|
+
extendedScanIntervalMs: 60 * 60 * 1000, // 1 hour
|
|
143
|
+
regularScanIntervalMs: 5 * 60 * 1000, // 5 minutes
|
|
144
|
+
...config.scanOptions
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
this.#scanOptions = { scanWhenRunning: false };
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
decodeResponse(response) {
|
|
152
|
+
if (response === null) {
|
|
153
|
+
return (null);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
throw (new Error('BlockQueueRunner::decodeResponse: Not implemented when response is not null, you must override this method in your subclass'));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
encodeResponse(response) {
|
|
160
|
+
if (response === null) {
|
|
161
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
throw (new Error('BlockQueueRunner::encodeResponse: Not implemented when response is not null, you must override this method in your subclass'));
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async run(options) {
|
|
169
|
+
let scanYieldedWork = false;
|
|
170
|
+
if (this.#scanOptions.scanWhenRunning) {
|
|
171
|
+
const now = Date.now();
|
|
172
|
+
let extendedScanDue = false;
|
|
173
|
+
let dueForScan = false;
|
|
174
|
+
if (!this.#lastScanTime || (now - this.#lastScanTime > this.#scanOptions.regularScanIntervalMs)) {
|
|
175
|
+
dueForScan = true;
|
|
176
|
+
}
|
|
177
|
+
if (!this.#lastExtendedScanTime || (now - this.#lastExtendedScanTime > this.#scanOptions.extendedScanIntervalMs)) {
|
|
178
|
+
extendedScanDue = true;
|
|
179
|
+
}
|
|
180
|
+
if (extendedScanDue || dueForScan) {
|
|
181
|
+
let searchTo;
|
|
182
|
+
if (extendedScanDue) {
|
|
183
|
+
searchTo = { extended: true };
|
|
184
|
+
}
|
|
185
|
+
else if (this.#lastScanTime) {
|
|
186
|
+
searchTo = this.#lastScanTime;
|
|
187
|
+
}
|
|
188
|
+
const scanResult = await this.#listener.scan({ searchTo });
|
|
189
|
+
this.#lastScanTime = now;
|
|
190
|
+
if (extendedScanDue) {
|
|
191
|
+
this.#lastExtendedScanTime = now;
|
|
192
|
+
}
|
|
193
|
+
scanYieldedWork = scanResult.listenersHaveWork;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
const moreRunWork = await super.run(options);
|
|
197
|
+
return (moreRunWork || scanYieldedWork);
|
|
198
|
+
}
|
|
199
|
+
[Symbol.dispose]() {
|
|
200
|
+
this.#removeListenerCallback();
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
export class BlockQueueRunner extends BaseBlockOperationQueueRunner {
|
|
204
|
+
decodeRequest(request) {
|
|
205
|
+
return ({ blockHash: new KeetaNet.lib.Block.Hash(request.blockHash) });
|
|
206
|
+
}
|
|
207
|
+
encodeRequest(request) {
|
|
208
|
+
return ({ blockHash: request.blockHash.toString() });
|
|
209
|
+
}
|
|
210
|
+
async onBlockSeen(block) {
|
|
211
|
+
const shouldInclude = await this.filterBlock(block);
|
|
212
|
+
if (shouldInclude) {
|
|
213
|
+
await this.add({ blockHash: block.hash });
|
|
214
|
+
}
|
|
215
|
+
return (shouldInclude);
|
|
216
|
+
}
|
|
217
|
+
add(request, info) {
|
|
218
|
+
const requestIdString = ConvertStringToRequestID(request.blockHash.toString().toLowerCase());
|
|
219
|
+
if (info?.id && String(info.id) !== String(requestIdString)) {
|
|
220
|
+
throw (new Error(`OperationQueueRunner::add: When providing an "id" in info, it must match the blockHash of the request. Expected ${String(requestIdString)}, got ${String(info.id)}`));
|
|
221
|
+
}
|
|
222
|
+
return (super.add(request, { ...info, id: requestIdString }));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
export class OperationQueueRunner extends BaseBlockOperationQueueRunner {
|
|
226
|
+
decodeRequest(request) {
|
|
227
|
+
return ({ blockHash: new KeetaNet.lib.Block.Hash(request.blockHash), operationIndex: request.operationIndex });
|
|
228
|
+
}
|
|
229
|
+
encodeRequest(request) {
|
|
230
|
+
return ({ blockHash: request.blockHash.toString(), operationIndex: Number(request.operationIndex) });
|
|
231
|
+
}
|
|
232
|
+
async onBlockSeen(block) {
|
|
233
|
+
const addPromises = [];
|
|
234
|
+
let anyShouldInclude = false;
|
|
235
|
+
for (let operationIndex = 0; operationIndex < block.operations.length; operationIndex++) {
|
|
236
|
+
const operation = block.operations[operationIndex];
|
|
237
|
+
if (!operation) {
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
addPromises.push((async () => {
|
|
241
|
+
const shouldInclude = await this.filterOperation(operation, { block, operationIndex });
|
|
242
|
+
if (shouldInclude) {
|
|
243
|
+
anyShouldInclude = true;
|
|
244
|
+
await this.add({ blockHash: block.hash, operationIndex });
|
|
245
|
+
}
|
|
246
|
+
})());
|
|
247
|
+
}
|
|
248
|
+
await Promise.all(addPromises);
|
|
249
|
+
return (anyShouldInclude);
|
|
250
|
+
}
|
|
251
|
+
add(request, info) {
|
|
252
|
+
const requestIdString = ConvertStringToRequestID(`${request.blockHash.toString()}-${String(request.operationIndex)}`.toLowerCase());
|
|
253
|
+
if (info?.id && String(info.id) !== String(requestIdString)) {
|
|
254
|
+
throw (new Error(`OperationQueueRunner::add: When providing an "id" in info, it must match the blockHash and operationIndex of the request. Expected ${String(requestIdString)}, got ${String(info.id)}`));
|
|
255
|
+
}
|
|
256
|
+
return (super.add(request, { ...info, id: requestIdString }));
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=block-listener.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block-listener.js","sourceRoot":"","sources":["../../src/lib/block-listener.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Client } from \"@keetanetwork/keetanet-client\";\nimport type { Logger } from \"./log/index.js\";\nimport type { Block, BlockHash } from \"@keetanetwork/keetanet-client/lib/block/index.js\";\nimport type { BlockOperations } from \"@keetanetwork/keetanet-client/lib/block/operations.js\";\nimport type { VoteBlockHash } from \"@keetanetwork/keetanet-client/lib/vote.js\";\nimport { KeetaAnchorQueueRunner } from \"./queue/index.js\";\nimport type { KeetaAnchorQueueEntryExtra, KeetaAnchorQueueRequestID } from \"./queue/index.js\";\nimport type { JSONSerializable } from \"./utils/json.js\";\nimport { KeetaNet } from \"../client/index.js\";\nimport { ConvertStringToRequestID } from \"./queue/internal.js\";\nimport type { KeetaAnchorQueueRunOptions } from \"./queue/common.js\";\n\ninterface BlockListenerConfig {\n\tclient: Client;\n\n\tlogger?: Logger;\n}\n\ninterface BlockListenerContext {\n\tblock: Block;\n}\n\ninterface NetworkListenerArguments {\n\t'block': {\n\t\tcallback: (data: BlockListenerContext) => (Promise<{ requiresWork?: boolean; }> | { requiresWork?: boolean; });\n\t}\n}\n\ninterface BlockListenerScanOptions {\n\tsearchTo?: { extended: true; } | number | undefined;\n}\n\nexport class BlockListener {\n\t#config: BlockListenerConfig;\n\n\t#blockListeners: (NetworkListenerArguments['block'] & { id: string; })[] = [];\n\n\tconstructor(config: BlockListenerConfig) {\n\t\tthis.#config = config;\n\t}\n\n\tget #client(): Client {\n\t\treturn(this.#config.client);\n\t}\n\n\tget logger(): Logger | undefined {\n\t\treturn(this.#config.logger);\n\t}\n\n\tasync #runWithLog(label: string, func: () => Promise<void>) {\n\t\ttry {\n\t\t\tawait func();\n\t\t} catch (error) {\n\t\t\tthis.logger?.error(`BlockListener::${label}`, `Received Error running`, error);\n\t\t}\n\t}\n\n\tasync #processBlockListeners(block: Block) {\n\t\tlet listenersHaveWork = false;\n\n\t\tconst promises = [];\n\t\tfor (const listener of this.#blockListeners) {\n\t\t\tpromises.push(this.#runWithLog('block callback', async function() {\n\t\t\t\tconst response = await listener.callback({ block });\n\t\t\t\tif (response.requiresWork) {\n\t\t\t\t\tlistenersHaveWork = true;\n\t\t\t\t}\n\t\t\t}));\n\t\t}\n\n\t\tawait Promise.allSettled(promises);\n\n\t\treturn({ listenersHaveWork });\n\t}\n\n\tasync scan(options?: BlockListenerScanOptions): Promise<{ listenersHaveWork: boolean; }> {\n\t\tlet listenersHaveWork = false;\n\n\t\ttry {\n\t\t\tlet reachedEndOfTime = false;\n\t\t\tlet startBlocksHash: VoteBlockHash | undefined;\n\t\t\tlet pageCount = 0;\n\n\t\t\t/*\n\t\t\t * Either perform an extended\n\t\t\t * scan (30 days) or a short\n\t\t\t * scan (4 hours) to find\n\t\t\t * relevant operations\n\t\t\t */\n\t\t\tconst now = Date.now();\n\n\t\t\tlet oldestVoteStapleToCheck = now - (4 * 60 * 60 * 1000); // 4 hours ago\n\n\t\t\tif (options?.searchTo) {\n\t\t\t\tif (typeof options.searchTo === 'number') {\n\t\t\t\t\tif (options.searchTo >= now || options.searchTo <= 0) {\n\t\t\t\t\t\tthrow(new Error('BlockListener::scan: When providing searchTo as a number, it must be a timestamp in the past'));\n\t\t\t\t\t}\n\n\t\t\t\t\toldestVoteStapleToCheck = options.searchTo;\n\t\t\t\t} else if ('extended' in options.searchTo) {\n\t\t\t\t\toldestVoteStapleToCheck = now - (30 * 24 * 60 * 60 * 1000); // 30 days ago\n\t\t\t\t} else {\n\t\t\t\t\tthrow(new Error('BlockListener::scan: Invalid searchTo option provided'));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\twhile (!reachedEndOfTime) {\n\t\t\t\tpageCount++;\n\n\t\t\t\tconst historyOptions = { depth: 20, ...(startBlocksHash ? { startBlocksHash } : {}) };\n\n\t\t\t\tthis.logger?.debug('BlockListener::poll', `Fetching history page ${pageCount}`, { ...historyOptions });\n\n\t\t\t\tconst history = await this.#client.getHistory(null, historyOptions);\n\n\t\t\t\tif (history.length === 0) {\n\t\t\t\t\tthis.logger?.debug('BlockListener::poll', `No more history found, ending discovery`);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tconst processBlocksPromises = [];\n\t\t\t\tfor (const { voteStaple } of history) {\n\t\t\t\t\tif (voteStaple.timestamp().valueOf() < oldestVoteStapleToCheck) {\n\t\t\t\t\t\tthis.logger?.debug('BlockListener::poll', 'Reached vote staple older than scanning time, ending discovery for this run', { voteStapleTime: voteStaple.timestamp(), oldestVoteStapleToCheck: new Date(oldestVoteStapleToCheck) });\n\t\t\t\t\t\treachedEndOfTime = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (const block of voteStaple.blocks) {\n\t\t\t\t\t\tprocessBlocksPromises.push(this.#processBlockListeners(block));\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst processBlockPromiseResults = await Promise.all(processBlocksPromises);\n\n\t\t\t\tif (processBlockPromiseResults.some(result => result.listenersHaveWork)) {\n\t\t\t\t\tlistenersHaveWork = true;\n\t\t\t\t}\n\n\t\t\t\t// Set up for next page\n\t\t\t\tconst lastVoteStaple = history[history.length - 1]?.voteStaple;\n\t\t\t\tif (lastVoteStaple) {\n\t\t\t\t\tstartBlocksHash = lastVoteStaple.blocksHash;\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.logger?.error('BlockListener::poll', 'Error during discovery:', error);\n\t\t}\n\n\t\treturn({ listenersHaveWork });\n\t}\n\n\ton<K extends keyof NetworkListenerArguments>(_ignore_type: K, args: NetworkListenerArguments[K]): { remove: () => void; } {\n\t\tconst id = String(Math.random());\n\n\t\tthis.#blockListeners.push({ ...args, id });\n\n\t\treturn({\n\t\t\tremove: () => {\n\t\t\t\tconst index = this.#blockListeners.findIndex(listener => listener.id === id);\n\t\t\t\tif (index !== -1) {\n\t\t\t\t\tthis.#blockListeners.splice(index, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n\ntype BlockQueueRunnerRequest = { blockHash: BlockHash; };\ntype BlockQueueRunnerRequestSerialized = { blockHash: string; };\n\ninterface BaseBlockOperationQueueRunnerScanOptionsRequired {\n\tscanWhenRunning: true;\n\textendedScanIntervalMs: number;\n\tregularScanIntervalMs: number;\n}\n\ntype BlockOperationQueueRunnerConfig<Request, Result, RequestSerialized extends JSONSerializable, ResultSerialized extends JSONSerializable | null> =\n\tConstructorParameters<typeof KeetaAnchorQueueRunner<Request, Result, RequestSerialized, ResultSerialized>>[0] &\n\t{\n\t\tlistener: BlockListener | BlockListenerConfig;\n\n\t\tscanOptions?: Partial<BaseBlockOperationQueueRunnerScanOptionsRequired> | {\n\t\t\tscanWhenRunning: false;\n\t\t}\n\t};\n\nabstract class BaseBlockOperationQueueRunner<\n\tRequest,\n\tResult = null,\n\tRequestSerialized extends JSONSerializable = JSONSerializable,\n\tResultSerialized extends JSONSerializable = null\n> extends KeetaAnchorQueueRunner<Request, Result, RequestSerialized, ResultSerialized> {\n\t#listener: BlockListener;\n\n\t#lastExtendedScanTime: number | null = null;\n\t#lastScanTime: number | null = null;\n\n\t#scanOptions: BaseBlockOperationQueueRunnerScanOptionsRequired | { scanWhenRunning: false; };\n\n\t#removeListenerCallback: (() => void);\n\n\tconstructor(config: BlockOperationQueueRunnerConfig<Request, Result, RequestSerialized, ResultSerialized>) {\n\t\tconst { listener, ...restConfig } = config;\n\n\t\tsuper(restConfig);\n\n\t\tif (listener instanceof BlockListener) {\n\t\t\tthis.#listener = listener;\n\t\t} else {\n\t\t\tthis.#listener = new BlockListener(listener);\n\t\t}\n\n\t\tconst addedListener = this.#listener.on('block', {\n\t\t\tcallback: async ({ block }) => {\n\t\t\t\treturn({ requiresWork: await this.onBlockSeen(block) });\n\t\t\t}\n\t\t});\n\n\t\tthis.#removeListenerCallback = addedListener.remove;\n\n\t\tif (!config.scanOptions || config.scanOptions?.scanWhenRunning || config.scanOptions?.scanWhenRunning === undefined) {\n\t\t\tthis.#scanOptions = {\n\t\t\t\tscanWhenRunning: true,\n\t\t\t\textendedScanIntervalMs: 60 * 60 * 1000, // 1 hour\n\t\t\t\tregularScanIntervalMs: 5 * 60 * 1000, // 5 minutes\n\t\t\t\t...config.scanOptions\n\t\t\t};\n\t\t} else {\n\t\t\tthis.#scanOptions = { scanWhenRunning: false };\n\t\t}\n\n\t}\n\n\tprotected abstract onBlockSeen(block: Block): Promise<boolean>;\n\n\tprotected decodeResponse(response: ResultSerialized): Result | null {\n\t\tif (response === null) {\n\t\t\treturn(null);\n\t\t} else {\n\t\t\tthrow(new Error('BlockQueueRunner::decodeResponse: Not implemented when response is not null, you must override this method in your subclass'));\n\t\t}\n\t}\n\n\tprotected encodeResponse(response: Result): ResultSerialized {\n\t\tif (response === null) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\treturn(null as ResultSerialized);\n\t\t} else {\n\t\t\tthrow(new Error('BlockQueueRunner::encodeResponse: Not implemented when response is not null, you must override this method in your subclass'));\n\t\t}\n\t}\n\n\toverride async run(options?: KeetaAnchorQueueRunOptions): Promise<boolean> {\n\t\tlet scanYieldedWork = false;\n\t\tif (this.#scanOptions.scanWhenRunning) {\n\t\t\tconst now = Date.now();\n\n\t\t\tlet extendedScanDue = false;\n\t\t\tlet dueForScan = false;\n\t\t\tif (!this.#lastScanTime || (now - this.#lastScanTime > this.#scanOptions.regularScanIntervalMs)) {\n\t\t\t\tdueForScan = true;\n\t\t\t}\n\n\t\t\tif (!this.#lastExtendedScanTime || (now - this.#lastExtendedScanTime > this.#scanOptions.extendedScanIntervalMs)) {\n\t\t\t\textendedScanDue = true;\n\t\t\t}\n\n\n\t\t\tif (extendedScanDue || dueForScan) {\n\t\t\t\tlet searchTo: BlockListenerScanOptions['searchTo'];\n\t\t\t\tif (extendedScanDue) {\n\t\t\t\t\tsearchTo = { extended: true };\n\t\t\t\t} else if (this.#lastScanTime) {\n\t\t\t\t\tsearchTo = this.#lastScanTime;\n\t\t\t\t}\n\n\t\t\t\tconst scanResult = await this.#listener.scan({ searchTo });\n\n\t\t\t\tthis.#lastScanTime = now;\n\t\t\t\tif (extendedScanDue) {\n\t\t\t\t\tthis.#lastExtendedScanTime = now;\n\t\t\t\t}\n\n\t\t\t\tscanYieldedWork = scanResult.listenersHaveWork;\n\t\t\t}\n\t\t}\n\n\t\tconst moreRunWork = await super.run(options);\n\n\t\treturn(moreRunWork || scanYieldedWork);\n\t}\n\n\t[Symbol.dispose](): void {\n\t\tthis.#removeListenerCallback();\n\t}\n}\n\nexport abstract class BlockQueueRunner<UserResult = null, QueueResult extends JSONSerializable = null> extends BaseBlockOperationQueueRunner<BlockQueueRunnerRequest, UserResult, BlockQueueRunnerRequestSerialized, QueueResult> {\n\tprotected abstract filterBlock(block: Block): (boolean | Promise<boolean>);\n\n\tprotected decodeRequest(request: BlockQueueRunnerRequestSerialized): BlockQueueRunnerRequest {\n\t\treturn({ blockHash: new KeetaNet.lib.Block.Hash(request.blockHash) });\n\t}\n\n\tprotected encodeRequest(request: BlockQueueRunnerRequest): BlockQueueRunnerRequestSerialized {\n\t\treturn({ blockHash: request.blockHash.toString() });\n\t}\n\n\tprotected async onBlockSeen(block: Block): Promise<boolean> {\n\t\tconst shouldInclude = await this.filterBlock(block);\n\t\tif (shouldInclude) {\n\t\t\tawait this.add({ blockHash: block.hash });\n\t\t}\n\t\treturn(shouldInclude);\n\t}\n\n\toverride add(request: BlockQueueRunnerRequest, info?: KeetaAnchorQueueEntryExtra): Promise<KeetaAnchorQueueRequestID> {\n\t\tconst requestIdString = ConvertStringToRequestID(request.blockHash.toString().toLowerCase())\n\n\t\tif (info?.id && String(info.id) !== String(requestIdString)) {\n\t\t\tthrow(new Error(`OperationQueueRunner::add: When providing an \"id\" in info, it must match the blockHash of the request. Expected ${String(requestIdString)}, got ${String(info.id)}`));\n\t\t}\n\n\t\treturn(super.add(request, { ...info, id: requestIdString }));\n\t}\n}\n\ntype OperationQueueRunnerRequest = { blockHash: BlockHash; operationIndex: number; };\ntype OperationQueueRunnerRequestSerialized = { blockHash: string; operationIndex: number; };\n\nexport abstract class OperationQueueRunner<UserResult = null, QueueResult extends JSONSerializable = null> extends BaseBlockOperationQueueRunner<OperationQueueRunnerRequest, UserResult, OperationQueueRunnerRequestSerialized, QueueResult> {\n\tprotected abstract filterOperation(operation: BlockOperations, context: { block: Block; operationIndex: number; }): (boolean | Promise<boolean>);\n\n\tprotected decodeRequest(request: OperationQueueRunnerRequestSerialized): OperationQueueRunnerRequest {\n\t\treturn({ blockHash: new KeetaNet.lib.Block.Hash(request.blockHash), operationIndex: request.operationIndex });\n\t}\n\n\tprotected encodeRequest(request: OperationQueueRunnerRequest): OperationQueueRunnerRequestSerialized {\n\t\treturn({ blockHash: request.blockHash.toString(), operationIndex: Number(request.operationIndex) });\n\t}\n\n\tprotected async onBlockSeen(block: Block): Promise<boolean> {\n\t\tconst addPromises = [];\n\n\t\tlet anyShouldInclude = false;\n\t\tfor (let operationIndex = 0; operationIndex < block.operations.length; operationIndex++) {\n\t\t\tconst operation = block.operations[operationIndex];\n\n\t\t\tif (!operation) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\taddPromises.push((async () => {\n\t\t\t\tconst shouldInclude = await this.filterOperation(operation, { block, operationIndex });\n\t\t\t\tif (shouldInclude) {\n\t\t\t\t\tanyShouldInclude = true;\n\t\t\t\t\tawait this.add({ blockHash: block.hash, operationIndex });\n\t\t\t\t}\n\t\t\t})());\n\t\t}\n\n\t\tawait Promise.all(addPromises);\n\n\t\treturn(anyShouldInclude);\n\t}\n\n\toverride add(request: OperationQueueRunnerRequest, info?: KeetaAnchorQueueEntryExtra): Promise<KeetaAnchorQueueRequestID> {\n\t\tconst requestIdString = ConvertStringToRequestID(`${request.blockHash.toString()}-${String(request.operationIndex)}`.toLowerCase());\n\n\t\tif (info?.id && String(info.id) !== String(requestIdString)) {\n\t\t\tthrow(new Error(`OperationQueueRunner::add: When providing an \"id\" in info, it must match the blockHash and operationIndex of the request. Expected ${String(requestIdString)}, got ${String(info.id)}`));\n\t\t}\n\n\t\treturn(super.add(request, { ...info, id: requestIdString }))\n\t}\n}\n"]}
|
|
@@ -1,7 +1,42 @@
|
|
|
1
1
|
import { lib as KeetaNetLib } from '@keetanetwork/keetanet-client';
|
|
2
2
|
import { Buffer } from './utils/buffer.js';
|
|
3
|
+
import { KeetaAnchorError } from './error.js';
|
|
4
|
+
/**
|
|
5
|
+
* Error codes for EncryptedContainer operations
|
|
6
|
+
*/
|
|
7
|
+
export declare const EncryptedContainerErrorCodes: readonly ["MALFORMED_BASE_FORMAT", "MALFORMED_VERSION", "MALFORMED_DATA_STRUCTURE", "MALFORMED_KEY_INFO", "MALFORMED_SIGNER_INFO", "UNSUPPORTED_VERSION", "UNSUPPORTED_CIPHER_ALGORITHM", "UNSUPPORTED_DIGEST_ALGORITHM", "UNSUPPORTED_SIGNATURE_ALGORITHM", "UNSUPPORTED_KEY_TYPE", "NO_KEYS_PROVIDED", "NO_MATCHING_KEY", "DECRYPTION_FAILED", "DECOMPRESSION_FAILED", "SIGNER_REQUIRES_PRIVATE_KEY", "NOT_SIGNED", "SIGNATURE_VERIFICATION_FAILED", "NO_PLAINTEXT_AVAILABLE", "NO_ENCODED_DATA_AVAILABLE", "PLAINTEXT_DISABLED", "ENCRYPTION_REQUIRED", "INVALID_PRINCIPALS", "ACCESS_MANAGEMENT_NOT_ALLOWED", "INTERNAL_ERROR"];
|
|
8
|
+
/**
|
|
9
|
+
* Error code type
|
|
10
|
+
*/
|
|
11
|
+
export type EncryptedContainerErrorCode = typeof EncryptedContainerErrorCodes[number];
|
|
12
|
+
/**
|
|
13
|
+
* Error class for EncryptedContainer operations
|
|
14
|
+
*/
|
|
15
|
+
export declare class EncryptedContainerError extends KeetaAnchorError {
|
|
16
|
+
static readonly name: string;
|
|
17
|
+
private readonly encryptedContainerErrorObjectTypeID;
|
|
18
|
+
private static readonly encryptedContainerErrorObjectTypeID;
|
|
19
|
+
readonly code: EncryptedContainerErrorCode;
|
|
20
|
+
/**
|
|
21
|
+
* Check if a string is a valid EncryptedContainerErrorCode
|
|
22
|
+
*/
|
|
23
|
+
static isValidCode(code: string): code is EncryptedContainerErrorCode;
|
|
24
|
+
constructor(code: EncryptedContainerErrorCode, message: string);
|
|
25
|
+
static isInstance(input: unknown): input is EncryptedContainerError;
|
|
26
|
+
toJSON(): ReturnType<KeetaAnchorError['toJSON']> & {
|
|
27
|
+
code: EncryptedContainerErrorCode;
|
|
28
|
+
};
|
|
29
|
+
static fromJSON(input: unknown): Promise<EncryptedContainerError>;
|
|
30
|
+
}
|
|
3
31
|
declare const Account: typeof KeetaNetLib.Account;
|
|
4
32
|
type Account = InstanceType<typeof KeetaNetLib.Account>;
|
|
33
|
+
/**
|
|
34
|
+
* Options for creating an EncryptedContainer from plaintext
|
|
35
|
+
*/
|
|
36
|
+
export type FromPlaintextOptions = {
|
|
37
|
+
locked?: boolean;
|
|
38
|
+
signer?: Account;
|
|
39
|
+
};
|
|
5
40
|
type CipherOptions = {
|
|
6
41
|
/**
|
|
7
42
|
* The symmetric cipher key (if any)
|
|
@@ -35,7 +70,7 @@ export declare class EncryptedContainer {
|
|
|
35
70
|
* Encryption details
|
|
36
71
|
*/
|
|
37
72
|
protected _internalState: EncryptedContainerInfo | UnencryptedContainerInfo;
|
|
38
|
-
constructor(principals: Account[] | null);
|
|
73
|
+
constructor(principals: Account[] | null, signer?: Account);
|
|
39
74
|
get encrypted(): boolean;
|
|
40
75
|
/**
|
|
41
76
|
* Create an instance of the EncryptedContainer from an encrypted blob,
|
|
@@ -54,10 +89,10 @@ export declare class EncryptedContainer {
|
|
|
54
89
|
*
|
|
55
90
|
* @param data The plaintext data to encrypt or encode
|
|
56
91
|
* @param principals The list of principals who can access the data if it is null then the data is not encrypted
|
|
57
|
-
* @param
|
|
92
|
+
* @param options Options including locked (plaintext accessibility) and signer (for RFC 5652 signing). For backward compatibility, can also be a boolean for locked.
|
|
58
93
|
* @returns The EncryptedContainer instance with the plaintext data and principals set
|
|
59
94
|
*/
|
|
60
|
-
static fromPlaintext(data: string | ArrayBuffer | Buffer, principals: Account[] | null,
|
|
95
|
+
static fromPlaintext(data: string | ArrayBuffer | Buffer, principals: Account[] | null, options?: boolean | FromPlaintextOptions): EncryptedContainer;
|
|
61
96
|
/**
|
|
62
97
|
* Set the plaintext buffer to the specified value
|
|
63
98
|
*/
|
|
@@ -101,6 +136,21 @@ export declare class EncryptedContainer {
|
|
|
101
136
|
* this container
|
|
102
137
|
*/
|
|
103
138
|
get principals(): Account[];
|
|
139
|
+
/**
|
|
140
|
+
* Check if this container is signed
|
|
141
|
+
*/
|
|
142
|
+
get isSigned(): boolean;
|
|
143
|
+
/**
|
|
144
|
+
* Get the signing account of this container.
|
|
145
|
+
*/
|
|
146
|
+
getSigningAccount(): Account | undefined;
|
|
147
|
+
/**
|
|
148
|
+
* Verify the signature on this container.
|
|
149
|
+
* This requires decrypting the container first to access the compressed plaintext.
|
|
150
|
+
*
|
|
151
|
+
* @returns true if signature is valid, false if invalid, or throws if not signed or plaintext unavailable
|
|
152
|
+
*/
|
|
153
|
+
verifySignature(): Promise<boolean>;
|
|
104
154
|
}
|
|
105
155
|
export default EncryptedContainer;
|
|
106
156
|
//# sourceMappingURL=encrypted-container.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encrypted-container.d.ts","sourceRoot":"","sources":["../../src/lib/encrypted-container.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,IAAI,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAKnE,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"encrypted-container.d.ts","sourceRoot":"","sources":["../../src/lib/encrypted-container.ts"],"names":[],"mappings":"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"}
|