@antseed/node 0.2.91 → 0.2.93
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/dist/buyer-request-handler.d.ts +9 -0
- package/dist/buyer-request-handler.d.ts.map +1 -1
- package/dist/buyer-request-handler.js +48 -7
- package/dist/buyer-request-handler.js.map +1 -1
- package/dist/discovery/announcer.d.ts +4 -1
- package/dist/discovery/announcer.d.ts.map +1 -1
- package/dist/discovery/announcer.js +53 -0
- package/dist/discovery/announcer.js.map +1 -1
- package/dist/discovery/domain-verification.d.ts +33 -0
- package/dist/discovery/domain-verification.d.ts.map +1 -0
- package/dist/discovery/domain-verification.js +114 -0
- package/dist/discovery/domain-verification.js.map +1 -0
- package/dist/discovery/github-verification.d.ts +30 -0
- package/dist/discovery/github-verification.d.ts.map +1 -0
- package/dist/discovery/github-verification.js +75 -0
- package/dist/discovery/github-verification.js.map +1 -0
- package/dist/discovery/index.d.ts +3 -1
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/index.js +3 -1
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/metadata-codec.d.ts +9 -0
- package/dist/discovery/metadata-codec.d.ts.map +1 -1
- package/dist/discovery/metadata-codec.js +175 -0
- package/dist/discovery/metadata-codec.js.map +1 -1
- package/dist/discovery/metadata-validator.d.ts +8 -1
- package/dist/discovery/metadata-validator.d.ts.map +1 -1
- package/dist/discovery/metadata-validator.js +219 -4
- package/dist/discovery/metadata-validator.js.map +1 -1
- package/dist/discovery/peer-metadata.d.ts +35 -1
- package/dist/discovery/peer-metadata.d.ts.map +1 -1
- package/dist/discovery/peer-metadata.js +1 -1
- package/dist/discovery/peer-metadata.js.map +1 -1
- package/dist/discovery/verification-utils.d.ts +11 -0
- package/dist/discovery/verification-utils.d.ts.map +1 -0
- package/dist/discovery/verification-utils.js +77 -0
- package/dist/discovery/verification-utils.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +22 -0
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +71 -1
- package/dist/node.js.map +1 -1
- package/dist/p2p/connection-manager.d.ts +3 -0
- package/dist/p2p/connection-manager.d.ts.map +1 -1
- package/dist/p2p/connection-manager.js +30 -4
- package/dist/p2p/connection-manager.js.map +1 -1
- package/dist/p2p/message-protocol.d.ts.map +1 -1
- package/dist/p2p/message-protocol.js +2 -10
- package/dist/p2p/message-protocol.js.map +1 -1
- package/dist/p2p/payment-codec.d.ts.map +1 -1
- package/dist/p2p/payment-codec.js +22 -33
- package/dist/p2p/payment-codec.js.map +1 -1
- package/dist/payments/buyer-payment-negotiator.d.ts.map +1 -1
- package/dist/payments/buyer-payment-negotiator.js +3 -8
- package/dist/payments/buyer-payment-negotiator.js.map +1 -1
- package/dist/seller-request-handler.d.ts +6 -2
- package/dist/seller-request-handler.d.ts.map +1 -1
- package/dist/seller-request-handler.js +72 -24
- package/dist/seller-request-handler.js.map +1 -1
- package/dist/storage/migrations/verification/001_create_tables.d.ts +3 -0
- package/dist/storage/migrations/verification/001_create_tables.d.ts.map +1 -0
- package/dist/storage/migrations/verification/001_create_tables.js +31 -0
- package/dist/storage/migrations/verification/001_create_tables.js.map +1 -0
- package/dist/storage/migrations/verification/index.d.ts +3 -0
- package/dist/storage/migrations/verification/index.d.ts.map +1 -0
- package/dist/storage/migrations/verification/index.js +3 -0
- package/dist/storage/migrations/verification/index.js.map +1 -0
- package/dist/types/peer.d.ts +2 -0
- package/dist/types/peer.d.ts.map +1 -1
- package/dist/types/protocol.d.ts +21 -0
- package/dist/types/protocol.d.ts.map +1 -1
- package/dist/types/protocol.js +3 -0
- package/dist/types/protocol.js.map +1 -1
- package/dist/utils/json-codec.d.ts +10 -0
- package/dist/utils/json-codec.d.ts.map +1 -0
- package/dist/utils/json-codec.js +52 -0
- package/dist/utils/json-codec.js.map +1 -0
- package/dist/verification/codec.d.ts +4 -0
- package/dist/verification/codec.d.ts.map +1 -0
- package/dist/verification/codec.js +38 -0
- package/dist/verification/codec.js.map +1 -0
- package/dist/verification/index.d.ts +6 -0
- package/dist/verification/index.d.ts.map +1 -0
- package/dist/verification/index.js +6 -0
- package/dist/verification/index.js.map +1 -0
- package/dist/verification/response-auth.d.ts +31 -0
- package/dist/verification/response-auth.d.ts.map +1 -0
- package/dist/verification/response-auth.js +111 -0
- package/dist/verification/response-auth.js.map +1 -0
- package/dist/verification/samples.d.ts +29 -0
- package/dist/verification/samples.d.ts.map +1 -0
- package/dist/verification/samples.js +96 -0
- package/dist/verification/samples.js.map +1 -0
- package/dist/verification/storage.d.ts +20 -0
- package/dist/verification/storage.d.ts.map +1 -0
- package/dist/verification/storage.js +108 -0
- package/dist/verification/storage.js.map +1 -0
- package/dist/verification/verification-mux.d.ts +20 -0
- package/dist/verification/verification-mux.d.ts.map +1 -0
- package/dist/verification/verification-mux.js +100 -0
- package/dist/verification/verification-mux.js.map +1 -0
- package/package.json +5 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { parseJsonObject, requireFiniteNumberField, requireStringField, } from '../utils/json-codec.js';
|
|
2
|
+
const encoder = new TextEncoder();
|
|
3
|
+
const MAX_PAYLOAD_SIZE = 64 * 1024;
|
|
4
|
+
function parseVerificationJson(data) {
|
|
5
|
+
return parseJsonObject(data, {
|
|
6
|
+
maxBytes: MAX_PAYLOAD_SIZE,
|
|
7
|
+
payloadName: 'Verification payload',
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
export function encodeResponseAuth(payload) {
|
|
11
|
+
return encoder.encode(JSON.stringify(payload));
|
|
12
|
+
}
|
|
13
|
+
export function decodeResponseAuth(data) {
|
|
14
|
+
const obj = parseVerificationJson(data);
|
|
15
|
+
const version = obj.version;
|
|
16
|
+
if (version !== 1) {
|
|
17
|
+
throw new Error(`Unsupported response auth version: ${String(version)}`);
|
|
18
|
+
}
|
|
19
|
+
const result = {
|
|
20
|
+
version,
|
|
21
|
+
requestId: requireStringField(obj, 'requestId'),
|
|
22
|
+
buyerPeerId: requireStringField(obj, 'buyerPeerId'),
|
|
23
|
+
sellerPeerId: requireStringField(obj, 'sellerPeerId'),
|
|
24
|
+
advertisedService: requireStringField(obj, 'advertisedService'),
|
|
25
|
+
provider: requireStringField(obj, 'provider'),
|
|
26
|
+
statusCode: requireFiniteNumberField(obj, 'statusCode'),
|
|
27
|
+
requestHash: requireStringField(obj, 'requestHash'),
|
|
28
|
+
responseHash: requireStringField(obj, 'responseHash'),
|
|
29
|
+
responseStartedAt: requireFiniteNumberField(obj, 'responseStartedAt'),
|
|
30
|
+
responseCompletedAt: requireFiniteNumberField(obj, 'responseCompletedAt'),
|
|
31
|
+
signature: requireStringField(obj, 'signature'),
|
|
32
|
+
};
|
|
33
|
+
if (typeof obj.channelId === 'string' && obj.channelId.length > 0) {
|
|
34
|
+
result.channelId = obj.channelId;
|
|
35
|
+
}
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=codec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codec.js","sourceRoot":"","sources":["../../src/verification/codec.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;AAElC,MAAM,gBAAgB,GAAG,EAAE,GAAG,IAAI,CAAC;AAEnC,SAAS,qBAAqB,CAAC,IAAgB;IAC7C,OAAO,eAAe,CAAC,IAAI,EAAE;QAC3B,QAAQ,EAAE,gBAAgB;QAC1B,WAAW,EAAE,sBAAsB;KACpC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAA4B;IAC7D,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAgB;IACjD,MAAM,GAAG,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;IAC5B,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,sCAAsC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,MAAM,GAAwB;QAClC,OAAO;QACP,SAAS,EAAE,kBAAkB,CAAC,GAAG,EAAE,WAAW,CAAC;QAC/C,WAAW,EAAE,kBAAkB,CAAC,GAAG,EAAE,aAAa,CAAC;QACnD,YAAY,EAAE,kBAAkB,CAAC,GAAG,EAAE,cAAc,CAAC;QACrD,iBAAiB,EAAE,kBAAkB,CAAC,GAAG,EAAE,mBAAmB,CAAC;QAC/D,QAAQ,EAAE,kBAAkB,CAAC,GAAG,EAAE,UAAU,CAAC;QAC7C,UAAU,EAAE,wBAAwB,CAAC,GAAG,EAAE,YAAY,CAAC;QACvD,WAAW,EAAE,kBAAkB,CAAC,GAAG,EAAE,aAAa,CAAC;QACnD,YAAY,EAAE,kBAAkB,CAAC,GAAG,EAAE,cAAc,CAAC;QACrD,iBAAiB,EAAE,wBAAwB,CAAC,GAAG,EAAE,mBAAmB,CAAC;QACrE,mBAAmB,EAAE,wBAAwB,CAAC,GAAG,EAAE,qBAAqB,CAAC;QACzE,SAAS,EAAE,kBAAkB,CAAC,GAAG,EAAE,WAAW,CAAC;KAChD,CAAC;IACF,IAAI,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,IAAI,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClE,MAAM,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;IACnC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { decodeResponseAuth, encodeResponseAuth } from './codec.js';
|
|
2
|
+
export { VerificationMux } from './verification-mux.js';
|
|
3
|
+
export { createResponseAuthPayload, hashRequest, hashResponse, verifyResponseAuth, type ResponseAuthInput, type ResponseAuthVerificationExpected, type ResponseAuthVerificationResult, } from './response-auth.js';
|
|
4
|
+
export { VerificationSampler, type ResponseAuthSampleInput, type StoredVerificationSample, type VerificationSampleConfig, } from './samples.js';
|
|
5
|
+
export { VerificationStorage, type StoredResponseAuth } from './storage.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/verification/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EACL,yBAAyB,EACzB,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,KAAK,iBAAiB,EACtB,KAAK,gCAAgC,EACrC,KAAK,8BAA8B,GACpC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,mBAAmB,EACnB,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,GAC9B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { decodeResponseAuth, encodeResponseAuth } from './codec.js';
|
|
2
|
+
export { VerificationMux } from './verification-mux.js';
|
|
3
|
+
export { createResponseAuthPayload, hashRequest, hashResponse, verifyResponseAuth, } from './response-auth.js';
|
|
4
|
+
export { VerificationSampler, } from './samples.js';
|
|
5
|
+
export { VerificationStorage } from './storage.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/verification/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EACL,yBAAyB,EACzB,WAAW,EACX,YAAY,EACZ,kBAAkB,GAInB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,mBAAmB,GAIpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,mBAAmB,EAA2B,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Wallet } from 'ethers';
|
|
2
|
+
import type { ResponseAuthPayload } from '../types/protocol.js';
|
|
3
|
+
import type { SerializedHttpRequest, SerializedHttpResponse } from '../types/http.js';
|
|
4
|
+
export interface ResponseAuthInput {
|
|
5
|
+
request: SerializedHttpRequest;
|
|
6
|
+
response: SerializedHttpResponse;
|
|
7
|
+
buyerPeerId: string;
|
|
8
|
+
sellerPeerId: string;
|
|
9
|
+
advertisedService: string;
|
|
10
|
+
provider: string;
|
|
11
|
+
responseStartedAt: number;
|
|
12
|
+
responseCompletedAt: number;
|
|
13
|
+
channelId?: string | null;
|
|
14
|
+
}
|
|
15
|
+
export interface ResponseAuthVerificationExpected {
|
|
16
|
+
request: SerializedHttpRequest;
|
|
17
|
+
response: SerializedHttpResponse;
|
|
18
|
+
buyerPeerId: string;
|
|
19
|
+
sellerPeerId: string;
|
|
20
|
+
advertisedService: string;
|
|
21
|
+
channelId?: string | null;
|
|
22
|
+
}
|
|
23
|
+
export interface ResponseAuthVerificationResult {
|
|
24
|
+
valid: boolean;
|
|
25
|
+
reason?: string;
|
|
26
|
+
}
|
|
27
|
+
export declare function createResponseAuthPayload(input: ResponseAuthInput, signer: Wallet): ResponseAuthPayload;
|
|
28
|
+
export declare function verifyResponseAuth(payload: ResponseAuthPayload, expected: ResponseAuthVerificationExpected): ResponseAuthVerificationResult;
|
|
29
|
+
export declare function hashRequest(request: SerializedHttpRequest): string;
|
|
30
|
+
export declare function hashResponse(response: SerializedHttpResponse): string;
|
|
31
|
+
//# sourceMappingURL=response-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-auth.d.ts","sourceRoot":"","sources":["../../src/verification/response-auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,KAAK,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAOtF,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,qBAAqB,CAAC;IAC/B,QAAQ,EAAE,sBAAsB,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,gCAAgC;IAC/C,OAAO,EAAE,qBAAqB,CAAC;IAC/B,QAAQ,EAAE,sBAAsB,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,8BAA8B;IAC7C,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAiBvG;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,mBAAmB,EAC5B,QAAQ,EAAE,gCAAgC,GACzC,8BAA8B,CA+ChC;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,CAElE;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,sBAAsB,GAAG,MAAM,CAErE"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { keccak256 } from 'ethers';
|
|
2
|
+
import { ANTSEED_STREAMING_RESPONSE_HEADER } from '../types/http.js';
|
|
3
|
+
import { bytesToHex, hexToBytes, signData, verifySignature } from '../p2p/identity.js';
|
|
4
|
+
import { encodeHttpRequest, encodeHttpResponse } from '../proxy/request-codec.js';
|
|
5
|
+
const RESPONSE_AUTH_DOMAIN = 'antseed-response-auth-v1';
|
|
6
|
+
export function createResponseAuthPayload(input, signer) {
|
|
7
|
+
const payload = {
|
|
8
|
+
version: 1,
|
|
9
|
+
requestId: input.request.requestId,
|
|
10
|
+
...(input.channelId ? { channelId: input.channelId } : {}),
|
|
11
|
+
buyerPeerId: normalizePeerId(input.buyerPeerId),
|
|
12
|
+
sellerPeerId: normalizePeerId(input.sellerPeerId),
|
|
13
|
+
advertisedService: input.advertisedService,
|
|
14
|
+
provider: input.provider,
|
|
15
|
+
statusCode: input.response.statusCode,
|
|
16
|
+
requestHash: hashRequest(input.request),
|
|
17
|
+
responseHash: hashResponse(input.response),
|
|
18
|
+
responseStartedAt: input.responseStartedAt,
|
|
19
|
+
responseCompletedAt: input.responseCompletedAt,
|
|
20
|
+
};
|
|
21
|
+
const signature = bytesToHex(signData(signer, buildResponseAuthSigningBytes(payload)));
|
|
22
|
+
return { ...payload, signature };
|
|
23
|
+
}
|
|
24
|
+
export function verifyResponseAuth(payload, expected) {
|
|
25
|
+
const expectedRequestHash = hashRequest(expected.request);
|
|
26
|
+
if (payload.requestHash !== expectedRequestHash) {
|
|
27
|
+
return { valid: false, reason: 'request_hash_mismatch' };
|
|
28
|
+
}
|
|
29
|
+
const expectedResponseHash = hashResponse(expected.response);
|
|
30
|
+
if (payload.responseHash !== expectedResponseHash) {
|
|
31
|
+
return { valid: false, reason: 'response_hash_mismatch' };
|
|
32
|
+
}
|
|
33
|
+
if (payload.requestId !== expected.request.requestId) {
|
|
34
|
+
return { valid: false, reason: 'request_id_mismatch' };
|
|
35
|
+
}
|
|
36
|
+
if (payload.statusCode !== expected.response.statusCode) {
|
|
37
|
+
return { valid: false, reason: 'status_code_mismatch' };
|
|
38
|
+
}
|
|
39
|
+
if (normalizePeerId(payload.buyerPeerId) !== normalizePeerId(expected.buyerPeerId)) {
|
|
40
|
+
return { valid: false, reason: 'buyer_peer_mismatch' };
|
|
41
|
+
}
|
|
42
|
+
if (normalizePeerId(payload.sellerPeerId) !== normalizePeerId(expected.sellerPeerId)) {
|
|
43
|
+
return { valid: false, reason: 'seller_peer_mismatch' };
|
|
44
|
+
}
|
|
45
|
+
if (payload.advertisedService !== expected.advertisedService) {
|
|
46
|
+
return { valid: false, reason: 'advertised_service_mismatch' };
|
|
47
|
+
}
|
|
48
|
+
if (expected.channelId && payload.channelId !== expected.channelId) {
|
|
49
|
+
return { valid: false, reason: 'channel_id_mismatch' };
|
|
50
|
+
}
|
|
51
|
+
const { signature: _signature, ...unsigned } = payload;
|
|
52
|
+
let validSignature = false;
|
|
53
|
+
try {
|
|
54
|
+
const signature = hexToBytes(payload.signature);
|
|
55
|
+
validSignature = verifySignature(normalizePeerId(expected.sellerPeerId), signature, buildResponseAuthSigningBytes(unsigned));
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
validSignature = false;
|
|
59
|
+
}
|
|
60
|
+
if (!validSignature) {
|
|
61
|
+
return { valid: false, reason: 'invalid_signature' };
|
|
62
|
+
}
|
|
63
|
+
return { valid: true };
|
|
64
|
+
}
|
|
65
|
+
export function hashRequest(request) {
|
|
66
|
+
return keccak256(encodeHttpRequest(request));
|
|
67
|
+
}
|
|
68
|
+
export function hashResponse(response) {
|
|
69
|
+
return keccak256(encodeHttpResponse(stripStreamingHeader(response)));
|
|
70
|
+
}
|
|
71
|
+
function buildResponseAuthSigningBytes(payload) {
|
|
72
|
+
const encoder = new TextEncoder();
|
|
73
|
+
const fields = [
|
|
74
|
+
RESPONSE_AUTH_DOMAIN,
|
|
75
|
+
String(payload.version),
|
|
76
|
+
payload.requestId,
|
|
77
|
+
payload.channelId ?? '',
|
|
78
|
+
normalizePeerId(payload.buyerPeerId),
|
|
79
|
+
normalizePeerId(payload.sellerPeerId),
|
|
80
|
+
payload.advertisedService,
|
|
81
|
+
payload.provider,
|
|
82
|
+
String(payload.statusCode),
|
|
83
|
+
payload.requestHash,
|
|
84
|
+
payload.responseHash,
|
|
85
|
+
String(payload.responseStartedAt),
|
|
86
|
+
String(payload.responseCompletedAt),
|
|
87
|
+
].map((field) => encoder.encode(field));
|
|
88
|
+
const totalLength = fields.reduce((sum, field) => sum + 4 + field.length, 0);
|
|
89
|
+
const out = new Uint8Array(totalLength);
|
|
90
|
+
const view = new DataView(out.buffer);
|
|
91
|
+
let offset = 0;
|
|
92
|
+
for (const field of fields) {
|
|
93
|
+
view.setUint32(offset, field.length);
|
|
94
|
+
offset += 4;
|
|
95
|
+
out.set(field, offset);
|
|
96
|
+
offset += field.length;
|
|
97
|
+
}
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
100
|
+
function stripStreamingHeader(response) {
|
|
101
|
+
if (response.headers[ANTSEED_STREAMING_RESPONSE_HEADER] !== '1') {
|
|
102
|
+
return response;
|
|
103
|
+
}
|
|
104
|
+
const headers = { ...response.headers };
|
|
105
|
+
delete headers[ANTSEED_STREAMING_RESPONSE_HEADER];
|
|
106
|
+
return { ...response, headers };
|
|
107
|
+
}
|
|
108
|
+
function normalizePeerId(peerId) {
|
|
109
|
+
return peerId.startsWith('0x') ? peerId.slice(2).toLowerCase() : peerId.toLowerCase();
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=response-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-auth.js","sourceRoot":"","sources":["../../src/verification/response-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { SerializedHttpRequest, SerializedHttpResponse } from '../types/http.js';
|
|
2
|
+
import type { ResponseAuthPayload } from '../types/protocol.js';
|
|
3
|
+
export interface VerificationSampleConfig {
|
|
4
|
+
sampleRate?: number;
|
|
5
|
+
maxSampleBytes?: number;
|
|
6
|
+
random?: () => number;
|
|
7
|
+
}
|
|
8
|
+
export interface ResponseAuthSampleInput {
|
|
9
|
+
request: SerializedHttpRequest;
|
|
10
|
+
response: SerializedHttpResponse;
|
|
11
|
+
responseAuth: ResponseAuthPayload;
|
|
12
|
+
verified: boolean;
|
|
13
|
+
verificationError: string | null;
|
|
14
|
+
}
|
|
15
|
+
export interface StoredVerificationSample {
|
|
16
|
+
sampleId: string;
|
|
17
|
+
directory: string;
|
|
18
|
+
savedAt: number;
|
|
19
|
+
}
|
|
20
|
+
export declare class VerificationSampler {
|
|
21
|
+
private readonly _samplesDir;
|
|
22
|
+
private readonly _sampleRate;
|
|
23
|
+
private readonly _maxSampleBytes;
|
|
24
|
+
private readonly _random;
|
|
25
|
+
constructor(samplesDir: string, config?: VerificationSampleConfig);
|
|
26
|
+
shouldSample(): boolean;
|
|
27
|
+
maybeStoreResponseAuthSample(input: ResponseAuthSampleInput): Promise<StoredVerificationSample | null>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=samples.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"samples.d.ts","sourceRoot":"","sources":["../../src/verification/samples.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AACtF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAOhE,MAAM,WAAW,wBAAwB;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,qBAAqB,CAAC;IAC/B,QAAQ,EAAE,sBAAsB,CAAC;IACjC,YAAY,EAAE,mBAAmB,CAAC;IAClC,QAAQ,EAAE,OAAO,CAAC;IAClB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;gBAE3B,UAAU,EAAE,MAAM,EAAE,MAAM,GAAE,wBAA6B;IAOrE,YAAY,IAAI,OAAO;IAMjB,4BAA4B,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC;CAmD7G"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { randomBytes, randomInt } from 'node:crypto';
|
|
2
|
+
import { mkdir, rename, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { encodeHttpRequest, encodeHttpResponse } from '../proxy/request-codec.js';
|
|
5
|
+
const SAMPLE_RANDOM_SCALE = 1_000_000;
|
|
6
|
+
const DEFAULT_SAMPLE_RATE = 0.01;
|
|
7
|
+
const DEFAULT_MAX_SAMPLE_BYTES = 16 * 1024 * 1024;
|
|
8
|
+
export class VerificationSampler {
|
|
9
|
+
_samplesDir;
|
|
10
|
+
_sampleRate;
|
|
11
|
+
_maxSampleBytes;
|
|
12
|
+
_random;
|
|
13
|
+
constructor(samplesDir, config = {}) {
|
|
14
|
+
this._samplesDir = samplesDir;
|
|
15
|
+
this._sampleRate = normalizeSampleRate(config.sampleRate ?? DEFAULT_SAMPLE_RATE);
|
|
16
|
+
this._maxSampleBytes = Math.max(1, config.maxSampleBytes ?? DEFAULT_MAX_SAMPLE_BYTES);
|
|
17
|
+
this._random = config.random ?? cryptoRandomFloat;
|
|
18
|
+
}
|
|
19
|
+
shouldSample() {
|
|
20
|
+
if (this._sampleRate <= 0)
|
|
21
|
+
return false;
|
|
22
|
+
if (this._sampleRate >= 1)
|
|
23
|
+
return true;
|
|
24
|
+
return this._random() < this._sampleRate;
|
|
25
|
+
}
|
|
26
|
+
async maybeStoreResponseAuthSample(input) {
|
|
27
|
+
if (!input.verified)
|
|
28
|
+
return null;
|
|
29
|
+
if (!this.shouldSample())
|
|
30
|
+
return null;
|
|
31
|
+
const requestBytes = encodeHttpRequest(input.request);
|
|
32
|
+
const responseBytes = encodeHttpResponse(input.response);
|
|
33
|
+
const combinedBytes = requestBytes.byteLength + responseBytes.byteLength;
|
|
34
|
+
if (combinedBytes > this._maxSampleBytes) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
const savedAt = Date.now();
|
|
38
|
+
const sampleId = sampleIdFor(input.responseAuth);
|
|
39
|
+
const directory = join(this._samplesDir, input.responseAuth.sellerPeerId, sampleId);
|
|
40
|
+
await mkdir(directory, { recursive: true });
|
|
41
|
+
const manifest = {
|
|
42
|
+
version: 1,
|
|
43
|
+
savedAt,
|
|
44
|
+
requestId: input.responseAuth.requestId,
|
|
45
|
+
buyerPeerId: input.responseAuth.buyerPeerId,
|
|
46
|
+
sellerPeerId: input.responseAuth.sellerPeerId,
|
|
47
|
+
advertisedService: input.responseAuth.advertisedService,
|
|
48
|
+
provider: input.responseAuth.provider,
|
|
49
|
+
statusCode: input.responseAuth.statusCode,
|
|
50
|
+
requestHash: input.responseAuth.requestHash,
|
|
51
|
+
responseHash: input.responseAuth.responseHash,
|
|
52
|
+
responseStartedAt: input.responseAuth.responseStartedAt,
|
|
53
|
+
responseCompletedAt: input.responseAuth.responseCompletedAt,
|
|
54
|
+
verified: input.verified,
|
|
55
|
+
verificationError: input.verificationError,
|
|
56
|
+
responseAuth: input.responseAuth,
|
|
57
|
+
files: {
|
|
58
|
+
request: 'request.bin',
|
|
59
|
+
response: 'response.bin',
|
|
60
|
+
encoding: 'antseed-http-codec-v1',
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
await writeFileAtomic(join(directory, 'request.bin'), requestBytes);
|
|
64
|
+
await writeFileAtomic(join(directory, 'response.bin'), responseBytes);
|
|
65
|
+
// The manifest is the completion marker. Readers should ignore sample
|
|
66
|
+
// directories without manifest.json because the process may have stopped
|
|
67
|
+
// between evidence writes.
|
|
68
|
+
await writeFileAtomic(join(directory, 'manifest.json'), new TextEncoder().encode(JSON.stringify(manifest, null, 2)));
|
|
69
|
+
return { sampleId, directory, savedAt };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function sampleIdFor(payload) {
|
|
73
|
+
return `${sanitizePathSegment(payload.requestId)}-${payload.requestHash.slice(2, 18)}`;
|
|
74
|
+
}
|
|
75
|
+
function sanitizePathSegment(value) {
|
|
76
|
+
const sanitized = value.replace(/[^a-zA-Z0-9._-]/g, '_').slice(0, 96);
|
|
77
|
+
return sanitized.length > 0 ? sanitized : 'sample';
|
|
78
|
+
}
|
|
79
|
+
function normalizeSampleRate(value) {
|
|
80
|
+
if (!Number.isFinite(value))
|
|
81
|
+
return DEFAULT_SAMPLE_RATE;
|
|
82
|
+
if (value <= 0)
|
|
83
|
+
return 0;
|
|
84
|
+
if (value >= 1)
|
|
85
|
+
return 1;
|
|
86
|
+
return value;
|
|
87
|
+
}
|
|
88
|
+
function cryptoRandomFloat() {
|
|
89
|
+
return randomInt(0, SAMPLE_RANDOM_SCALE) / SAMPLE_RANDOM_SCALE;
|
|
90
|
+
}
|
|
91
|
+
async function writeFileAtomic(path, data) {
|
|
92
|
+
const tmp = `${path}.${process.pid}.${randomBytes(4).toString('hex')}.tmp`;
|
|
93
|
+
await writeFile(tmp, data);
|
|
94
|
+
await rename(tmp, path);
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=samples.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"samples.js","sourceRoot":"","sources":["../../src/verification/samples.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAElF,MAAM,mBAAmB,GAAG,SAAS,CAAC;AACtC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AACjC,MAAM,wBAAwB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAsBlD,MAAM,OAAO,mBAAmB;IACb,WAAW,CAAS;IACpB,WAAW,CAAS;IACpB,eAAe,CAAS;IACxB,OAAO,CAAe;IAEvC,YAAY,UAAkB,EAAE,SAAmC,EAAE;QACnE,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;QAC9B,IAAI,CAAC,WAAW,GAAG,mBAAmB,CAAC,MAAM,CAAC,UAAU,IAAI,mBAAmB,CAAC,CAAC;QACjF,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,cAAc,IAAI,wBAAwB,CAAC,CAAC;QACtF,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,IAAI,iBAAiB,CAAC;IACpD,CAAC;IAED,YAAY;QACV,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACxC,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACvC,OAAO,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,4BAA4B,CAAC,KAA8B;QAC/D,IAAI,CAAC,KAAK,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QACjC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;YAAE,OAAO,IAAI,CAAC;QAEtC,MAAM,YAAY,GAAG,iBAAiB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACtD,MAAM,aAAa,GAAG,kBAAkB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACzD,MAAM,aAAa,GAAG,YAAY,CAAC,UAAU,GAAG,aAAa,CAAC,UAAU,CAAC;QACzE,IAAI,aAAa,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;YACzC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACjD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QACpF,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE5C,MAAM,QAAQ,GAA+B;YAC3C,OAAO,EAAE,CAAC;YACV,OAAO;YACP,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC,SAAS;YACvC,WAAW,EAAE,KAAK,CAAC,YAAY,CAAC,WAAW;YAC3C,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC,YAAY;YAC7C,iBAAiB,EAAE,KAAK,CAAC,YAAY,CAAC,iBAAiB;YACvD,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,QAAQ;YACrC,UAAU,EAAE,KAAK,CAAC,YAAY,CAAC,UAAU;YACzC,WAAW,EAAE,KAAK,CAAC,YAAY,CAAC,WAAW;YAC3C,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC,YAAY;YAC7C,iBAAiB,EAAE,KAAK,CAAC,YAAY,CAAC,iBAAiB;YACvD,mBAAmB,EAAE,KAAK,CAAC,YAAY,CAAC,mBAAmB;YAC3D,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;YAC1C,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,KAAK,EAAE;gBACL,OAAO,EAAE,aAAa;gBACtB,QAAQ,EAAE,cAAc;gBACxB,QAAQ,EAAE,uBAAuB;aAClC;SACF,CAAC;QAEF,MAAM,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,EAAE,YAAY,CAAC,CAAC;QACpE,MAAM,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,EAAE,aAAa,CAAC,CAAC;QACtE,sEAAsE;QACtE,yEAAyE;QACzE,2BAA2B;QAC3B,MAAM,eAAe,CACnB,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,EAChC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAC5D,CAAC;QAEF,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;IAC1C,CAAC;CACF;AAyBD,SAAS,WAAW,CAAC,OAA4B;IAC/C,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AACzF,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa;IACxC,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACtE,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;AACrD,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa;IACxC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,mBAAmB,CAAC;IACxD,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACzB,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACzB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,iBAAiB;IACxB,OAAO,SAAS,CAAC,CAAC,EAAE,mBAAmB,CAAC,GAAG,mBAAmB,CAAC;AACjE,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,IAAY,EAAE,IAAgB;IAC3D,MAAM,GAAG,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3E,MAAM,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC3B,MAAM,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ResponseAuthPayload } from '../types/protocol.js';
|
|
2
|
+
export interface StoredResponseAuth extends ResponseAuthPayload {
|
|
3
|
+
receivedAt: number;
|
|
4
|
+
verified: boolean;
|
|
5
|
+
verificationError: string | null;
|
|
6
|
+
}
|
|
7
|
+
export declare class VerificationStorage {
|
|
8
|
+
private readonly _db;
|
|
9
|
+
private readonly _insertResponseAuth;
|
|
10
|
+
private readonly _getResponseAuth;
|
|
11
|
+
private readonly _listResponseAuthsBySeller;
|
|
12
|
+
constructor(dbPath: string);
|
|
13
|
+
private _prepareStatements;
|
|
14
|
+
private _prepareInsertResponseAuthStatement;
|
|
15
|
+
insertResponseAuth(record: StoredResponseAuth): void;
|
|
16
|
+
getResponseAuth(requestId: string): StoredResponseAuth | null;
|
|
17
|
+
listResponseAuthsBySeller(sellerPeerId: string, limit?: number): StoredResponseAuth[];
|
|
18
|
+
close(): void;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/verification/storage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAIhE,MAAM,WAAW,kBAAmB,SAAQ,mBAAmB;IAC7D,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoB;IACxC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IACtD,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAqB;gBAEpD,MAAM,EAAE,MAAM;IAW1B,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,mCAAmC;IAgC3C,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAqBpD,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI;IAK7D,yBAAyB,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,kBAAkB,EAAE;IAKlF,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import { runMigrations } from '../storage/migrate.js';
|
|
3
|
+
import { verificationMigrations } from '../storage/migrations/verification/index.js';
|
|
4
|
+
export class VerificationStorage {
|
|
5
|
+
_db;
|
|
6
|
+
_insertResponseAuth;
|
|
7
|
+
_getResponseAuth;
|
|
8
|
+
_listResponseAuthsBySeller;
|
|
9
|
+
constructor(dbPath) {
|
|
10
|
+
this._db = new Database(dbPath);
|
|
11
|
+
this._db.pragma('journal_mode = WAL');
|
|
12
|
+
runMigrations(this._db, verificationMigrations);
|
|
13
|
+
const statements = this._prepareStatements();
|
|
14
|
+
this._insertResponseAuth = statements.insertResponseAuth;
|
|
15
|
+
this._getResponseAuth = statements.getResponseAuth;
|
|
16
|
+
this._listResponseAuthsBySeller = statements.listResponseAuthsBySeller;
|
|
17
|
+
}
|
|
18
|
+
_prepareStatements() {
|
|
19
|
+
return {
|
|
20
|
+
insertResponseAuth: this._prepareInsertResponseAuthStatement(),
|
|
21
|
+
getResponseAuth: this._db.prepare('SELECT * FROM response_auths WHERE request_id = ?'),
|
|
22
|
+
listResponseAuthsBySeller: this._db.prepare('SELECT * FROM response_auths WHERE seller_peer_id = ? ORDER BY received_at DESC LIMIT ?'),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
_prepareInsertResponseAuthStatement() {
|
|
26
|
+
return this._db.prepare(`
|
|
27
|
+
INSERT INTO response_auths (
|
|
28
|
+
request_id, version, channel_id, buyer_peer_id, seller_peer_id,
|
|
29
|
+
advertised_service, provider, status_code, request_hash, response_hash,
|
|
30
|
+
response_started_at, response_completed_at, signature,
|
|
31
|
+
received_at, verified, verification_error
|
|
32
|
+
) VALUES (
|
|
33
|
+
@requestId, @version, @channelId, @buyerPeerId, @sellerPeerId,
|
|
34
|
+
@advertisedService, @provider, @statusCode, @requestHash, @responseHash,
|
|
35
|
+
@responseStartedAt, @responseCompletedAt, @signature,
|
|
36
|
+
@receivedAt, @verified, @verificationError
|
|
37
|
+
)
|
|
38
|
+
ON CONFLICT(request_id) DO UPDATE SET
|
|
39
|
+
version = excluded.version,
|
|
40
|
+
channel_id = excluded.channel_id,
|
|
41
|
+
buyer_peer_id = excluded.buyer_peer_id,
|
|
42
|
+
seller_peer_id = excluded.seller_peer_id,
|
|
43
|
+
advertised_service = excluded.advertised_service,
|
|
44
|
+
provider = excluded.provider,
|
|
45
|
+
status_code = excluded.status_code,
|
|
46
|
+
request_hash = excluded.request_hash,
|
|
47
|
+
response_hash = excluded.response_hash,
|
|
48
|
+
response_started_at = excluded.response_started_at,
|
|
49
|
+
response_completed_at = excluded.response_completed_at,
|
|
50
|
+
signature = excluded.signature,
|
|
51
|
+
received_at = excluded.received_at,
|
|
52
|
+
verified = excluded.verified,
|
|
53
|
+
verification_error = excluded.verification_error
|
|
54
|
+
`);
|
|
55
|
+
}
|
|
56
|
+
insertResponseAuth(record) {
|
|
57
|
+
this._insertResponseAuth.run({
|
|
58
|
+
requestId: record.requestId,
|
|
59
|
+
version: record.version,
|
|
60
|
+
channelId: record.channelId ?? null,
|
|
61
|
+
buyerPeerId: record.buyerPeerId,
|
|
62
|
+
sellerPeerId: record.sellerPeerId,
|
|
63
|
+
advertisedService: record.advertisedService,
|
|
64
|
+
provider: record.provider,
|
|
65
|
+
statusCode: record.statusCode,
|
|
66
|
+
requestHash: record.requestHash,
|
|
67
|
+
responseHash: record.responseHash,
|
|
68
|
+
responseStartedAt: record.responseStartedAt,
|
|
69
|
+
responseCompletedAt: record.responseCompletedAt,
|
|
70
|
+
signature: record.signature,
|
|
71
|
+
receivedAt: record.receivedAt,
|
|
72
|
+
verified: record.verified ? 1 : 0,
|
|
73
|
+
verificationError: record.verificationError,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
getResponseAuth(requestId) {
|
|
77
|
+
const row = this._getResponseAuth.get(requestId);
|
|
78
|
+
return row ? rowToResponseAuth(row) : null;
|
|
79
|
+
}
|
|
80
|
+
listResponseAuthsBySeller(sellerPeerId, limit = 100) {
|
|
81
|
+
const rows = this._listResponseAuthsBySeller.all(sellerPeerId, Math.max(1, limit));
|
|
82
|
+
return rows.map(rowToResponseAuth);
|
|
83
|
+
}
|
|
84
|
+
close() {
|
|
85
|
+
this._db.close();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function rowToResponseAuth(row) {
|
|
89
|
+
return {
|
|
90
|
+
version: row.version,
|
|
91
|
+
requestId: row.request_id,
|
|
92
|
+
...(row.channel_id ? { channelId: row.channel_id } : {}),
|
|
93
|
+
buyerPeerId: row.buyer_peer_id,
|
|
94
|
+
sellerPeerId: row.seller_peer_id,
|
|
95
|
+
advertisedService: row.advertised_service,
|
|
96
|
+
provider: row.provider,
|
|
97
|
+
statusCode: row.status_code,
|
|
98
|
+
requestHash: row.request_hash,
|
|
99
|
+
responseHash: row.response_hash,
|
|
100
|
+
responseStartedAt: row.response_started_at,
|
|
101
|
+
responseCompletedAt: row.response_completed_at,
|
|
102
|
+
signature: row.signature,
|
|
103
|
+
receivedAt: row.received_at,
|
|
104
|
+
verified: row.verified === 1,
|
|
105
|
+
verificationError: row.verification_error,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/verification/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type FramedMessage, type ResponseAuthPayload } from '../types/protocol.js';
|
|
2
|
+
import type { PeerConnection } from '../p2p/connection-manager.js';
|
|
3
|
+
export type VerificationMessageHandler<T> = (payload: T) => void | Promise<void>;
|
|
4
|
+
export declare class VerificationMux {
|
|
5
|
+
private readonly _connection;
|
|
6
|
+
private _messageIdCounter;
|
|
7
|
+
private _onResponseAuth?;
|
|
8
|
+
private readonly _pendingResponseAuths;
|
|
9
|
+
private readonly _bufferedResponseAuths;
|
|
10
|
+
constructor(connection: PeerConnection);
|
|
11
|
+
onResponseAuth(handler: VerificationMessageHandler<ResponseAuthPayload>): void;
|
|
12
|
+
sendResponseAuth(payload: ResponseAuthPayload): void;
|
|
13
|
+
waitForResponseAuth(requestId: string, timeoutMs?: number): Promise<ResponseAuthPayload>;
|
|
14
|
+
close(): void;
|
|
15
|
+
handleFrame(frame: FramedMessage): Promise<boolean>;
|
|
16
|
+
static isVerificationMessage(type: number): boolean;
|
|
17
|
+
private _bufferResponseAuth;
|
|
18
|
+
private _send;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=verification-mux.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification-mux.d.ts","sourceRoot":"","sources":["../../src/verification/verification-mux.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AACjG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAYnE,MAAM,MAAM,0BAA0B,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEjF,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiB;IAC7C,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,eAAe,CAAC,CAAkD;IAC1E,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAA0C;IAChF,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAA0C;gBAErE,UAAU,EAAE,cAAc;IAItC,cAAc,CAAC,OAAO,EAAE,0BAA0B,CAAC,mBAAmB,CAAC,GAAG,IAAI;IAI9E,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI;IAIpD,mBAAmB,CACjB,SAAS,EAAE,MAAM,EACjB,SAAS,SAAmC,GAC3C,OAAO,CAAC,mBAAmB,CAAC;IAyB/B,KAAK,IAAI,IAAI;IASP,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;IAwBzD,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAInD,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,KAAK;CASd"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { MessageType } from '../types/protocol.js';
|
|
2
|
+
import { encodeFrame } from '../p2p/message-protocol.js';
|
|
3
|
+
import { debugLog } from '../utils/debug.js';
|
|
4
|
+
import { decodeResponseAuth, encodeResponseAuth } from './codec.js';
|
|
5
|
+
const MESSAGE_TYPE_NAME = {
|
|
6
|
+
[MessageType.VerificationResponseAuth]: 'VerificationResponseAuth',
|
|
7
|
+
};
|
|
8
|
+
const MAX_BUFFERED_AUTHS = 256;
|
|
9
|
+
const DEFAULT_RESPONSE_AUTH_TIMEOUT_MS = 30_000;
|
|
10
|
+
export class VerificationMux {
|
|
11
|
+
_connection;
|
|
12
|
+
_messageIdCounter = 0;
|
|
13
|
+
_onResponseAuth;
|
|
14
|
+
_pendingResponseAuths = new Map();
|
|
15
|
+
_bufferedResponseAuths = new Map();
|
|
16
|
+
constructor(connection) {
|
|
17
|
+
this._connection = connection;
|
|
18
|
+
}
|
|
19
|
+
onResponseAuth(handler) {
|
|
20
|
+
this._onResponseAuth = handler;
|
|
21
|
+
}
|
|
22
|
+
sendResponseAuth(payload) {
|
|
23
|
+
this._send(MessageType.VerificationResponseAuth, encodeResponseAuth(payload));
|
|
24
|
+
}
|
|
25
|
+
waitForResponseAuth(requestId, timeoutMs = DEFAULT_RESPONSE_AUTH_TIMEOUT_MS) {
|
|
26
|
+
const buffered = this._bufferedResponseAuths.get(requestId);
|
|
27
|
+
if (buffered) {
|
|
28
|
+
this._bufferedResponseAuths.delete(requestId);
|
|
29
|
+
return Promise.resolve(buffered);
|
|
30
|
+
}
|
|
31
|
+
const existing = this._pendingResponseAuths.get(requestId);
|
|
32
|
+
if (existing)
|
|
33
|
+
return existing.promise;
|
|
34
|
+
let resolve;
|
|
35
|
+
let reject;
|
|
36
|
+
const timer = setTimeout(() => {
|
|
37
|
+
this._pendingResponseAuths.delete(requestId);
|
|
38
|
+
reject(new Error(`ResponseAuth timed out for request ${requestId}`));
|
|
39
|
+
}, Math.max(1, timeoutMs));
|
|
40
|
+
const promise = new Promise((res, rej) => {
|
|
41
|
+
resolve = res;
|
|
42
|
+
reject = rej;
|
|
43
|
+
});
|
|
44
|
+
this._pendingResponseAuths.set(requestId, { promise, resolve, reject, timer });
|
|
45
|
+
return promise;
|
|
46
|
+
}
|
|
47
|
+
close() {
|
|
48
|
+
for (const pending of this._pendingResponseAuths.values()) {
|
|
49
|
+
clearTimeout(pending.timer);
|
|
50
|
+
pending.reject(new Error('VerificationMux closed'));
|
|
51
|
+
}
|
|
52
|
+
this._pendingResponseAuths.clear();
|
|
53
|
+
this._bufferedResponseAuths.clear();
|
|
54
|
+
}
|
|
55
|
+
async handleFrame(frame) {
|
|
56
|
+
const name = MESSAGE_TYPE_NAME[frame.type];
|
|
57
|
+
if (!name)
|
|
58
|
+
return false;
|
|
59
|
+
debugLog(`[VerificationMux] ← recv ${name} (${frame.payload.length}b)`);
|
|
60
|
+
switch (frame.type) {
|
|
61
|
+
case MessageType.VerificationResponseAuth: {
|
|
62
|
+
const payload = decodeResponseAuth(frame.payload);
|
|
63
|
+
const pending = this._pendingResponseAuths.get(payload.requestId);
|
|
64
|
+
if (pending) {
|
|
65
|
+
clearTimeout(pending.timer);
|
|
66
|
+
this._pendingResponseAuths.delete(payload.requestId);
|
|
67
|
+
pending.resolve(payload);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
this._bufferResponseAuth(payload);
|
|
71
|
+
}
|
|
72
|
+
await this._onResponseAuth?.(payload);
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
default:
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
static isVerificationMessage(type) {
|
|
80
|
+
return type >= 0x80 && type <= 0x8f;
|
|
81
|
+
}
|
|
82
|
+
_bufferResponseAuth(payload) {
|
|
83
|
+
if (this._bufferedResponseAuths.size >= MAX_BUFFERED_AUTHS) {
|
|
84
|
+
const oldest = this._bufferedResponseAuths.keys().next().value;
|
|
85
|
+
if (oldest)
|
|
86
|
+
this._bufferedResponseAuths.delete(oldest);
|
|
87
|
+
}
|
|
88
|
+
this._bufferedResponseAuths.set(payload.requestId, payload);
|
|
89
|
+
}
|
|
90
|
+
_send(type, payload) {
|
|
91
|
+
debugLog(`[VerificationMux] → send ${MESSAGE_TYPE_NAME[type] ?? `0x${type.toString(16)}`} (${payload.length}b)`);
|
|
92
|
+
const frame = encodeFrame({
|
|
93
|
+
type,
|
|
94
|
+
messageId: this._messageIdCounter++ & 0xffffffff,
|
|
95
|
+
payload,
|
|
96
|
+
});
|
|
97
|
+
this._connection.send(frame);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=verification-mux.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification-mux.js","sourceRoot":"","sources":["../../src/verification/verification-mux.ts"],"names":[],"mappings":"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"}
|