@ar.io/wayfinder-core 0.0.5-alpha.3 → 0.0.5-alpha.4
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/README.md +13 -0
- package/dist/telemetry.d.ts +33 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +115 -0
- package/dist/types.d.ts +19 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/verification/data-root-verifier.d.ts +1 -1
- package/dist/verification/data-root-verifier.d.ts.map +1 -1
- package/dist/verification/hash-verifier.d.ts +1 -1
- package/dist/verification/hash-verifier.d.ts.map +1 -1
- package/dist/verification/signature-verifier.d.ts +3 -2
- package/dist/verification/signature-verifier.d.ts.map +1 -1
- package/dist/verification/signature-verifier.js +2 -0
- package/dist/wayfinder.d.ts +14 -4
- package/dist/wayfinder.d.ts.map +1 -1
- package/dist/wayfinder.js +138 -61
- package/package.json +18 -3
package/README.md
CHANGED
|
@@ -91,9 +91,22 @@ const wayfinder = new Wayfinder({
|
|
|
91
91
|
},
|
|
92
92
|
},
|
|
93
93
|
},
|
|
94
|
+
// telemetry configuration
|
|
95
|
+
telemetrySettings: {
|
|
96
|
+
enabled: true,
|
|
97
|
+
// sample 50% of requests
|
|
98
|
+
sampleRate: 0.5,
|
|
99
|
+
// honeycomb API key and dataset if you want to collect traces
|
|
100
|
+
apiKey: '<YOUR_API_KEY>',
|
|
101
|
+
dataset: 'wayfinder',
|
|
102
|
+
},
|
|
94
103
|
});
|
|
95
104
|
```
|
|
96
105
|
|
|
106
|
+
### Telemetry
|
|
107
|
+
|
|
108
|
+
Wayfinder can optionally emit OpenTelemetry spans for every request. **By default, telemetry is disabled**. You can control this behavior with the `telemetrySettings` option.
|
|
109
|
+
|
|
97
110
|
## ar:// Protocol
|
|
98
111
|
|
|
99
112
|
Wayfinder supports several ar:// URL formats:
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WayFinder
|
|
3
|
+
* Copyright (C) 2022-2025 Permanent Data Solutions, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { Span, type Tracer } from '@opentelemetry/api';
|
|
18
|
+
import type { GatewaysProvider, TelemetryConfig, WayfinderOptions } from './types.js';
|
|
19
|
+
import { WayfinderEmitter } from './wayfinder.js';
|
|
20
|
+
export declare const initTelemetry: (config?: TelemetryConfig) => Tracer | undefined;
|
|
21
|
+
export declare const startRequestSpans: ({ originalUrl, emitter, tracer, verificationSettings, routingSettings, gatewaysProvider, }?: {
|
|
22
|
+
originalUrl?: string;
|
|
23
|
+
emitter?: WayfinderEmitter;
|
|
24
|
+
tracer?: Tracer;
|
|
25
|
+
verificationSettings?: WayfinderOptions["verificationSettings"];
|
|
26
|
+
routingSettings?: WayfinderOptions["routingSettings"];
|
|
27
|
+
gatewaysProvider?: GatewaysProvider;
|
|
28
|
+
}) => {
|
|
29
|
+
parentSpan: Span | undefined;
|
|
30
|
+
routingSpan: Span | undefined;
|
|
31
|
+
verificationSpan: Span | undefined;
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=telemetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAGL,IAAI,EACJ,KAAK,MAAM,EAIZ,MAAM,oBAAoB,CAAC;AAc5B,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,eAAO,MAAM,aAAa,GACxB,SAAQ,eAIP,KACA,MAAM,GAAG,SAmCX,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,6FAO/B;IACD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oBAAoB,CAAC,EAAE,gBAAgB,CAAC,sBAAsB,CAAC,CAAC;IAChE,eAAe,CAAC,EAAE,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;IACtD,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CAChC;;;;CA+DL,CAAC"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WayFinder
|
|
3
|
+
* Copyright (C) 2022-2025 Permanent Data Solutions, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { DiagConsoleLogger, DiagLogLevel, context, diag, trace, } from '@opentelemetry/api';
|
|
18
|
+
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
|
|
19
|
+
import { resourceFromAttributes } from '@opentelemetry/resources';
|
|
20
|
+
import { BatchSpanProcessor, TraceIdRatioBasedSampler, } from '@opentelemetry/sdk-trace-base';
|
|
21
|
+
import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
|
|
22
|
+
import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
|
|
23
|
+
import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, } from '@opentelemetry/semantic-conventions';
|
|
24
|
+
export const initTelemetry = (config = {
|
|
25
|
+
enabled: false,
|
|
26
|
+
sampleRate: 0,
|
|
27
|
+
serviceName: 'wayfinder-core',
|
|
28
|
+
}) => {
|
|
29
|
+
if (config.enabled === false)
|
|
30
|
+
return undefined;
|
|
31
|
+
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.ERROR);
|
|
32
|
+
const exporter = new OTLPTraceExporter({
|
|
33
|
+
url: config.exporterUrl ?? 'https://api.honeycomb.io',
|
|
34
|
+
headers: {
|
|
35
|
+
'x-honeycomb-team': config.apiKey ?? '',
|
|
36
|
+
'x-honeycomb-dataset': 'wayfinder-dev',
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
const isBrowser = typeof window !== 'undefined';
|
|
40
|
+
const spanProcessor = new BatchSpanProcessor(exporter);
|
|
41
|
+
const sampler = new TraceIdRatioBasedSampler(config.sampleRate ?? 1);
|
|
42
|
+
const resource = resourceFromAttributes({
|
|
43
|
+
[ATTR_SERVICE_NAME]: 'wayfinder-core',
|
|
44
|
+
[ATTR_SERVICE_VERSION]: 'v0.0.5-alpha.5', // hard coded for now as importing JSON breaks wayfinder-react
|
|
45
|
+
});
|
|
46
|
+
const provider = isBrowser
|
|
47
|
+
? new WebTracerProvider({
|
|
48
|
+
sampler,
|
|
49
|
+
resource,
|
|
50
|
+
spanProcessors: [spanProcessor],
|
|
51
|
+
})
|
|
52
|
+
: new NodeTracerProvider({
|
|
53
|
+
sampler,
|
|
54
|
+
resource,
|
|
55
|
+
spanProcessors: [spanProcessor],
|
|
56
|
+
});
|
|
57
|
+
provider.register();
|
|
58
|
+
return trace.getTracer('wayfinder-core');
|
|
59
|
+
};
|
|
60
|
+
export const startRequestSpans = ({ originalUrl, emitter, tracer, verificationSettings, routingSettings, gatewaysProvider, } = {}) => {
|
|
61
|
+
const activeContext = context.active();
|
|
62
|
+
const parentSpan = tracer?.startSpan('wayfinder.request', {
|
|
63
|
+
attributes: {
|
|
64
|
+
originalUrl: originalUrl ?? 'undefined',
|
|
65
|
+
'verification.enabled': verificationSettings?.enabled ?? false,
|
|
66
|
+
'verification.strategy': verificationSettings?.strategy?.constructor.name ?? 'undefined',
|
|
67
|
+
'verification.strict': verificationSettings?.strict ?? false,
|
|
68
|
+
'verification.trustedGateways': verificationSettings?.strategy?.trustedGateways
|
|
69
|
+
?.map((gateway) => gateway.toString())
|
|
70
|
+
.join(','),
|
|
71
|
+
'routing.strategy': routingSettings?.strategy?.constructor.name ?? 'undefined',
|
|
72
|
+
gatewaysProvider: gatewaysProvider?.constructor.name,
|
|
73
|
+
},
|
|
74
|
+
}, activeContext);
|
|
75
|
+
const parentContext = parentSpan
|
|
76
|
+
? trace.setSpan(context.active(), parentSpan)
|
|
77
|
+
: context.active();
|
|
78
|
+
let routingSpan;
|
|
79
|
+
let verificationSpan;
|
|
80
|
+
// add listeners on the emitter to the span
|
|
81
|
+
emitter?.on('routing-started', () => {
|
|
82
|
+
if (parentSpan && !routingSpan) {
|
|
83
|
+
context.with(parentContext, () => {
|
|
84
|
+
routingSpan = tracer?.startSpan('wayfinder.routing');
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
emitter?.on('routing-skipped', () => {
|
|
89
|
+
parentSpan?.setAttribute('routing.skipped', true);
|
|
90
|
+
routingSpan?.end();
|
|
91
|
+
parentSpan?.end();
|
|
92
|
+
});
|
|
93
|
+
emitter?.on('routing-succeeded', () => {
|
|
94
|
+
parentSpan?.setAttribute('routing.succeeded', true);
|
|
95
|
+
routingSpan?.end();
|
|
96
|
+
});
|
|
97
|
+
emitter?.on('verification-progress', () => {
|
|
98
|
+
if (parentSpan && !verificationSpan) {
|
|
99
|
+
context.with(parentContext, () => {
|
|
100
|
+
verificationSpan = tracer?.startSpan('wayfinder.verification');
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
emitter?.on('verification-succeeded', () => {
|
|
105
|
+
parentSpan?.setAttribute('verification.succeeded', true);
|
|
106
|
+
verificationSpan?.end();
|
|
107
|
+
parentSpan?.end();
|
|
108
|
+
});
|
|
109
|
+
emitter?.on('verification-failed', () => {
|
|
110
|
+
parentSpan?.setAttribute('verification.failed', true);
|
|
111
|
+
verificationSpan?.end();
|
|
112
|
+
parentSpan?.end();
|
|
113
|
+
});
|
|
114
|
+
return { parentSpan, routingSpan, verificationSpan };
|
|
115
|
+
};
|
package/dist/types.d.ts
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* See the License for the specific language governing permissions and
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
|
+
import type { WayfinderEmitter } from './wayfinder.js';
|
|
17
18
|
/**
|
|
18
19
|
* This is an extension of the fetch function that allows for overriding the verification and routing settings for a single request.
|
|
19
20
|
*/
|
|
@@ -70,6 +71,7 @@ export interface WayfinderVerificationEventArgs {
|
|
|
70
71
|
export interface WayfinderEventArgs {
|
|
71
72
|
verification?: WayfinderVerificationEventArgs;
|
|
72
73
|
routing?: WayfinderRoutingEventArgs;
|
|
74
|
+
parentEmitter?: WayfinderEmitter;
|
|
73
75
|
}
|
|
74
76
|
/**
|
|
75
77
|
* Configuration options for the Wayfinder
|
|
@@ -122,6 +124,22 @@ export interface WayfinderOptions {
|
|
|
122
124
|
*/
|
|
123
125
|
strategy?: RoutingStrategy;
|
|
124
126
|
};
|
|
127
|
+
/**
|
|
128
|
+
* Telemetry configuration used to initialize OpenTelemetry tracing
|
|
129
|
+
*/
|
|
130
|
+
telemetrySettings?: TelemetryConfig;
|
|
131
|
+
}
|
|
132
|
+
export interface TelemetryConfig {
|
|
133
|
+
/** Enable or disable telemetry collection */
|
|
134
|
+
enabled: boolean;
|
|
135
|
+
/** Sampling ratio between 0 and 1 */
|
|
136
|
+
sampleRate: number;
|
|
137
|
+
/** Honeycomb API key */
|
|
138
|
+
apiKey?: string;
|
|
139
|
+
/** Optional custom OTLP exporter URL */
|
|
140
|
+
exporterUrl?: string;
|
|
141
|
+
/** Service name used for traces */
|
|
142
|
+
serviceName: string;
|
|
125
143
|
}
|
|
126
144
|
export type DataStream = ReadableStream<Uint8Array> | AsyncIterable<Uint8Array>;
|
|
127
145
|
export interface GatewaysProvider {
|
|
@@ -138,6 +156,7 @@ export interface RoutingStrategy {
|
|
|
138
156
|
}): Promise<URL>;
|
|
139
157
|
}
|
|
140
158
|
export interface VerificationStrategy {
|
|
159
|
+
trustedGateways: URL[];
|
|
141
160
|
verifyData(params: {
|
|
142
161
|
data: DataStream;
|
|
143
162
|
txId: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ export declare const convertDataStreamToDataRoot: ({ stream, }: {
|
|
|
3
3
|
stream: DataStream;
|
|
4
4
|
}) => Promise<string>;
|
|
5
5
|
export declare class DataRootVerificationStrategy implements VerificationStrategy {
|
|
6
|
-
|
|
6
|
+
readonly trustedGateways: URL[];
|
|
7
7
|
private readonly maxConcurrency;
|
|
8
8
|
private readonly logger;
|
|
9
9
|
private readonly classifier;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-root-verifier.d.ts","sourceRoot":"","sources":["../../src/verification/data-root-verifier.ts"],"names":[],"mappings":"AA4BA,OAAO,EACL,cAAc,EACd,UAAU,EACV,MAAM,EACN,oBAAoB,EACrB,MAAM,aAAa,CAAC;AAOrB,eAAO,MAAM,2BAA2B,GAAU,aAE/C;IACD,MAAM,EAAE,UAAU,CAAC;CACpB,KAAG,OAAO,CAAC,MAAM,CAwDjB,CAAC;AAGF,qBAAa,4BAA6B,YAAW,oBAAoB;IACvE,
|
|
1
|
+
{"version":3,"file":"data-root-verifier.d.ts","sourceRoot":"","sources":["../../src/verification/data-root-verifier.ts"],"names":[],"mappings":"AA4BA,OAAO,EACL,cAAc,EACd,UAAU,EACV,MAAM,EACN,oBAAoB,EACrB,MAAM,aAAa,CAAC;AAOrB,eAAO,MAAM,2BAA2B,GAAU,aAE/C;IACD,MAAM,EAAE,UAAU,CAAC;CACpB,KAAG,OAAO,CAAC,MAAM,CAwDjB,CAAC;AAGF,qBAAa,4BAA6B,YAAW,oBAAoB;IACvE,SAAgB,eAAe,EAAE,GAAG,EAAE,CAAC;IACvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiB;gBAChC,EACV,eAAe,EACf,cAAkB,EAClB,MAAsB,EACtB,UAA0C,GAC3C,EAAE;QACD,eAAe,EAAE,GAAG,EAAE,CAAC;QACvB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,cAAc,CAAC;KAC7B;IAOD;;;;OAIG;IACG,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAuCxD,UAAU,CAAC,EACf,IAAI,EACJ,IAAI,GACL,EAAE;QACD,IAAI,EAAE,UAAU,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KACd,GAAG,OAAO,CAAC,IAAI,CAAC;CA0BlB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DataStream, Logger, VerificationStrategy } from '../types.js';
|
|
2
2
|
export declare class HashVerificationStrategy implements VerificationStrategy {
|
|
3
|
-
|
|
3
|
+
readonly trustedGateways: URL[];
|
|
4
4
|
private readonly maxConcurrency;
|
|
5
5
|
private readonly logger;
|
|
6
6
|
constructor({ trustedGateways, maxConcurrency, logger, }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash-verifier.d.ts","sourceRoot":"","sources":["../../src/verification/hash-verifier.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAK5E,qBAAa,wBAAyB,YAAW,oBAAoB;IACnE,
|
|
1
|
+
{"version":3,"file":"hash-verifier.d.ts","sourceRoot":"","sources":["../../src/verification/hash-verifier.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAK5E,qBAAa,wBAAyB,YAAW,oBAAoB;IACnE,SAAgB,eAAe,EAAE,GAAG,EAAE,CAAC;IACvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBACpB,EACV,eAAe,EACf,cAAkB,EAClB,MAAsB,GACvB,EAAE;QACD,eAAe,EAAE,GAAG,EAAE,CAAC;QACvB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB;IAMD;;;;OAIG;IACG,SAAS,CAAC,EACd,IAAI,GACL,EAAE;QACD,IAAI,EAAE,MAAM,CAAC;KACd,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,QAAQ,CAAA;KAAE,CAAC;IAqE5C,UAAU,CAAC,EACf,IAAI,EACJ,IAAI,GACL,EAAE;QACD,IAAI,EAAE,UAAU,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KACd,GAAG,OAAO,CAAC,IAAI,CAAC;CAgBlB"}
|
|
@@ -4,7 +4,7 @@ import type { DataClassifier, DataStream, Logger, VerificationStrategy } from '.
|
|
|
4
4
|
* using trusted gateways to provide the metadata needed for verification.
|
|
5
5
|
*/
|
|
6
6
|
export declare class Ans104SignatureVerificationStrategy implements VerificationStrategy {
|
|
7
|
-
|
|
7
|
+
readonly trustedGateways: URL[];
|
|
8
8
|
private readonly maxConcurrency;
|
|
9
9
|
private readonly logger;
|
|
10
10
|
constructor({ trustedGateways, maxConcurrency, logger, }: {
|
|
@@ -58,7 +58,7 @@ export declare class Ans104SignatureVerificationStrategy implements Verification
|
|
|
58
58
|
* from a trusted gateway's /tx/<tx-id>/signature endpoint.
|
|
59
59
|
*/
|
|
60
60
|
export declare class TransactionSignatureVerificationStrategy implements VerificationStrategy {
|
|
61
|
-
|
|
61
|
+
readonly trustedGateways: URL[];
|
|
62
62
|
private readonly logger;
|
|
63
63
|
constructor({ trustedGateways, logger, }: {
|
|
64
64
|
trustedGateways: URL[];
|
|
@@ -102,6 +102,7 @@ export declare class SignatureVerificationStrategy {
|
|
|
102
102
|
private readonly ans104;
|
|
103
103
|
private readonly transaction;
|
|
104
104
|
private readonly classifier;
|
|
105
|
+
readonly trustedGateways: URL[];
|
|
105
106
|
constructor({ trustedGateways, maxConcurrency, logger, classifier, }: {
|
|
106
107
|
trustedGateways: URL[];
|
|
107
108
|
maxConcurrency?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signature-verifier.d.ts","sourceRoot":"","sources":["../../src/verification/signature-verifier.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EACV,cAAc,EACd,UAAU,EACV,MAAM,EACN,oBAAoB,EACrB,MAAM,aAAa,CAAC;AASrB;;;GAGG;AACH,qBAAa,mCACX,YAAW,oBAAoB;IAE/B,
|
|
1
|
+
{"version":3,"file":"signature-verifier.d.ts","sourceRoot":"","sources":["../../src/verification/signature-verifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -334,7 +334,9 @@ export class SignatureVerificationStrategy {
|
|
|
334
334
|
ans104;
|
|
335
335
|
transaction;
|
|
336
336
|
classifier;
|
|
337
|
+
trustedGateways;
|
|
337
338
|
constructor({ trustedGateways, maxConcurrency = 1, logger = defaultLogger, classifier = new GqlClassifier({ logger }), }) {
|
|
339
|
+
this.trustedGateways = trustedGateways;
|
|
338
340
|
this.ans104 = new Ans104SignatureVerificationStrategy({
|
|
339
341
|
trustedGateways,
|
|
340
342
|
maxConcurrency,
|
package/dist/wayfinder.d.ts
CHANGED
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
import { EventEmitter } from 'eventemitter3';
|
|
18
|
-
import
|
|
18
|
+
import { type Tracer } from '@opentelemetry/api';
|
|
19
|
+
import type { GatewaysProvider, Logger, TelemetryConfig, VerificationStrategy, WayfinderEvent, WayfinderEventArgs, WayfinderFetch, WayfinderOptions } from './types.js';
|
|
19
20
|
export declare const arnsRegex: RegExp;
|
|
20
21
|
export declare const txIdRegex: RegExp;
|
|
21
22
|
/**
|
|
@@ -30,7 +31,7 @@ export declare const resolveWayfinderUrl: ({ originalUrl, selectedGateway, logge
|
|
|
30
31
|
logger?: Logger;
|
|
31
32
|
}) => URL;
|
|
32
33
|
export declare class WayfinderEmitter extends EventEmitter<WayfinderEvent> {
|
|
33
|
-
constructor({ verification, routing }?: WayfinderEventArgs);
|
|
34
|
+
constructor({ verification, routing, parentEmitter, }?: WayfinderEventArgs);
|
|
34
35
|
}
|
|
35
36
|
export declare function tapAndVerifyReadableStream({ originalStream, contentLength, verifyData, txId, emitter, strict, }: {
|
|
36
37
|
originalStream: ReadableStream;
|
|
@@ -51,12 +52,13 @@ export declare function tapAndVerifyReadableStream({ originalStream, contentLeng
|
|
|
51
52
|
* @param resolveUrl - the function to construct the redirect url for ar:// requests
|
|
52
53
|
* @returns a wrapped fetch function that supports ar:// protocol and always returns Response
|
|
53
54
|
*/
|
|
54
|
-
export declare const wayfinderFetch: ({ logger, gatewaysProvider, verificationSettings, routingSettings, emitter, }: {
|
|
55
|
+
export declare const wayfinderFetch: ({ logger, gatewaysProvider, verificationSettings, routingSettings, emitter, tracer, }: {
|
|
55
56
|
logger?: Logger;
|
|
56
57
|
gatewaysProvider: GatewaysProvider;
|
|
57
58
|
verificationSettings: NonNullable<WayfinderOptions["verificationSettings"]>;
|
|
58
59
|
routingSettings: NonNullable<WayfinderOptions["routingSettings"]>;
|
|
59
60
|
emitter?: WayfinderEmitter;
|
|
61
|
+
tracer?: Tracer;
|
|
60
62
|
}) => (input: URL | RequestInfo, init?: RequestInit & {
|
|
61
63
|
verificationSettings?: NonNullable<WayfinderOptions["verificationSettings"]>;
|
|
62
64
|
routingSettings?: NonNullable<WayfinderOptions["routingSettings"]>;
|
|
@@ -87,6 +89,14 @@ export declare class Wayfinder {
|
|
|
87
89
|
* The verification settings to use when verifying data.
|
|
88
90
|
*/
|
|
89
91
|
readonly verificationSettings: WayfinderOptions['verificationSettings'];
|
|
92
|
+
/**
|
|
93
|
+
* Telemetry configuration used for OpenTelemetry tracing
|
|
94
|
+
*/
|
|
95
|
+
readonly telemetrySettings: TelemetryConfig;
|
|
96
|
+
/**
|
|
97
|
+
* OpenTelemetry tracer instance
|
|
98
|
+
*/
|
|
99
|
+
protected tracer?: Tracer;
|
|
90
100
|
/**
|
|
91
101
|
* A helper function that resolves the redirect url for ar:// requests to a target gateway.
|
|
92
102
|
*
|
|
@@ -204,6 +214,6 @@ export declare class Wayfinder {
|
|
|
204
214
|
* @param options - Wayfinder configuration options
|
|
205
215
|
*/
|
|
206
216
|
constructor({ logger, gatewaysProvider, // forcing it to be required to avoid making ar-io-sdk a dependency
|
|
207
|
-
verificationSettings, routingSettings, }: WayfinderOptions);
|
|
217
|
+
verificationSettings, routingSettings, telemetrySettings, }: WayfinderOptions);
|
|
208
218
|
}
|
|
209
219
|
//# sourceMappingURL=wayfinder.d.ts.map
|
package/dist/wayfinder.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wayfinder.d.ts","sourceRoot":"","sources":["../src/wayfinder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"wayfinder.d.ts","sourceRoot":"","sources":["../src/wayfinder.ts"],"names":[],"mappings":"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"}
|
package/dist/wayfinder.js
CHANGED
|
@@ -16,7 +16,9 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { EventEmitter } from 'eventemitter3';
|
|
18
18
|
import { defaultLogger } from './logger.js';
|
|
19
|
+
import { context, trace } from '@opentelemetry/api';
|
|
19
20
|
import { FastestPingRoutingStrategy } from './routing/ping.js';
|
|
21
|
+
import { initTelemetry, startRequestSpans } from './telemetry.js';
|
|
20
22
|
import { sandboxFromId } from './utils/base64.js';
|
|
21
23
|
import { HashVerificationStrategy } from './verification/hash-verifier.js';
|
|
22
24
|
// known regexes for wayfinder urls
|
|
@@ -68,7 +70,7 @@ export const resolveWayfinderUrl = ({ originalUrl, selectedGateway, logger, }) =
|
|
|
68
70
|
return new URL(originalUrl);
|
|
69
71
|
};
|
|
70
72
|
export class WayfinderEmitter extends EventEmitter {
|
|
71
|
-
constructor({ verification, routing } = {}) {
|
|
73
|
+
constructor({ verification, routing, parentEmitter, } = {}) {
|
|
72
74
|
super();
|
|
73
75
|
if (verification) {
|
|
74
76
|
if (verification.onVerificationSucceeded) {
|
|
@@ -92,6 +94,29 @@ export class WayfinderEmitter extends EventEmitter {
|
|
|
92
94
|
this.on('routing-succeeded', routing.onRoutingSucceeded);
|
|
93
95
|
}
|
|
94
96
|
}
|
|
97
|
+
if (parentEmitter) {
|
|
98
|
+
this.on('routing-started', (event) => {
|
|
99
|
+
parentEmitter.emit('routing-started', event);
|
|
100
|
+
});
|
|
101
|
+
this.on('routing-skipped', (event) => {
|
|
102
|
+
parentEmitter.emit('routing-skipped', event);
|
|
103
|
+
});
|
|
104
|
+
this.on('routing-succeeded', (event) => {
|
|
105
|
+
parentEmitter.emit('routing-succeeded', event);
|
|
106
|
+
});
|
|
107
|
+
this.on('verification-succeeded', (event) => {
|
|
108
|
+
parentEmitter.emit('verification-succeeded', event);
|
|
109
|
+
});
|
|
110
|
+
this.on('verification-failed', (event) => {
|
|
111
|
+
parentEmitter.emit('verification-failed', event);
|
|
112
|
+
});
|
|
113
|
+
this.on('verification-progress', (event) => {
|
|
114
|
+
parentEmitter.emit('verification-progress', event);
|
|
115
|
+
});
|
|
116
|
+
this.on('verification-skipped', (event) => {
|
|
117
|
+
parentEmitter.emit('verification-skipped', event);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
95
120
|
}
|
|
96
121
|
}
|
|
97
122
|
export function tapAndVerifyReadableStream({ originalStream, contentLength, verifyData, txId, emitter, strict = false, }) {
|
|
@@ -182,26 +207,25 @@ export function tapAndVerifyReadableStream({ originalStream, contentLength, veri
|
|
|
182
207
|
* @param resolveUrl - the function to construct the redirect url for ar:// requests
|
|
183
208
|
* @returns a wrapped fetch function that supports ar:// protocol and always returns Response
|
|
184
209
|
*/
|
|
185
|
-
export const wayfinderFetch = ({ logger = defaultLogger, gatewaysProvider, verificationSettings, routingSettings, emitter, }) => {
|
|
210
|
+
export const wayfinderFetch = ({ logger = defaultLogger, gatewaysProvider, verificationSettings, routingSettings, emitter, tracer, }) => {
|
|
186
211
|
return async (input, init) => {
|
|
187
212
|
const {
|
|
188
213
|
// allows for overriding the verification and routing settings for a single request
|
|
189
214
|
verificationSettings: requestVerificationSettings, routingSettings: requestRoutingSettings, ...restInit } = init ?? {};
|
|
215
|
+
const url = input instanceof URL ? input.toString() : input.toString();
|
|
190
216
|
const requestEmitter = new WayfinderEmitter({
|
|
191
217
|
verification: requestVerificationSettings?.events,
|
|
192
218
|
routing: requestRoutingSettings?.events,
|
|
219
|
+
parentEmitter: emitter,
|
|
220
|
+
});
|
|
221
|
+
const { parentSpan } = startRequestSpans({
|
|
222
|
+
originalUrl: url,
|
|
223
|
+
verificationSettings: requestVerificationSettings ?? verificationSettings,
|
|
224
|
+
routingSettings: requestRoutingSettings ?? routingSettings,
|
|
225
|
+
gatewaysProvider,
|
|
226
|
+
emitter: requestEmitter,
|
|
227
|
+
tracer,
|
|
193
228
|
});
|
|
194
|
-
if (emitter) {
|
|
195
|
-
requestEmitter.on('routing-started', (event) => {
|
|
196
|
-
emitter.emit('routing-started', event);
|
|
197
|
-
});
|
|
198
|
-
requestEmitter.on('routing-skipped', (event) => emitter.emit('routing-skipped', event));
|
|
199
|
-
requestEmitter.on('routing-succeeded', (event) => emitter.emit('routing-succeeded', event));
|
|
200
|
-
requestEmitter.on('verification-succeeded', (event) => emitter.emit('verification-succeeded', event));
|
|
201
|
-
requestEmitter.on('verification-failed', (event) => emitter.emit('verification-failed', event));
|
|
202
|
-
requestEmitter.on('verification-progress', (event) => emitter.emit('verification-progress', event));
|
|
203
|
-
}
|
|
204
|
-
const url = input instanceof URL ? input.toString() : input.toString();
|
|
205
229
|
if (!url.toString().startsWith('ar://')) {
|
|
206
230
|
logger?.debug('URL is not a wayfinder url, skipping routing', {
|
|
207
231
|
input,
|
|
@@ -246,6 +270,9 @@ export const wayfinderFetch = ({ logger = defaultLogger, gatewaysProvider, verif
|
|
|
246
270
|
originalUrl: url,
|
|
247
271
|
redirectUrl: redirectUrl.toString(),
|
|
248
272
|
});
|
|
273
|
+
const requestSpan = parentSpan
|
|
274
|
+
? tracer?.startSpan('wayfinder.fetch', undefined, trace.setSpan(context.active(), parentSpan))
|
|
275
|
+
: undefined;
|
|
249
276
|
// make the request to the target gateway using the redirect url
|
|
250
277
|
const response = await fetch(redirectUrl.toString(), {
|
|
251
278
|
// enforce CORS given we're likely going to a different origin, but always allow the client to override
|
|
@@ -253,58 +280,87 @@ export const wayfinderFetch = ({ logger = defaultLogger, gatewaysProvider, verif
|
|
|
253
280
|
mode: 'cors',
|
|
254
281
|
...restInit,
|
|
255
282
|
});
|
|
283
|
+
// add response attributes to the span
|
|
284
|
+
requestSpan?.setAttribute('response.status', response.status);
|
|
285
|
+
requestSpan?.setAttribute('response.statusText', response.statusText);
|
|
286
|
+
response.headers.forEach((value, key) => {
|
|
287
|
+
requestSpan?.setAttribute(`response.headers.${key}`, value);
|
|
288
|
+
});
|
|
256
289
|
logger?.debug(`Successfully routed request to gateway`, {
|
|
257
290
|
redirectUrl: redirectUrl.toString(),
|
|
258
291
|
originalUrl: url,
|
|
259
292
|
});
|
|
260
293
|
// only verify data if the redirect url is different from the original url
|
|
261
|
-
if (redirectUrl.toString()
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
294
|
+
if (redirectUrl.toString() === url) {
|
|
295
|
+
logger?.debug('Redirect URL is the same as the original URL, skipping verification', {
|
|
296
|
+
redirectUrl: redirectUrl.toString(),
|
|
297
|
+
originalUrl: url,
|
|
298
|
+
});
|
|
299
|
+
requestEmitter.emit('verification-skipped', {
|
|
300
|
+
originalUrl: url,
|
|
301
|
+
});
|
|
302
|
+
requestSpan?.end();
|
|
303
|
+
return response;
|
|
304
|
+
}
|
|
305
|
+
// if verification is disabled, return the response
|
|
306
|
+
if (!(verificationSettings.enabled &&
|
|
307
|
+
verificationSettings.strategy?.verifyData)) {
|
|
308
|
+
logger?.debug('Verification is disabled or no verification strategy is provided, skipping verification', {
|
|
309
|
+
redirectUrl: redirectUrl.toString(),
|
|
310
|
+
originalUrl: url,
|
|
311
|
+
});
|
|
312
|
+
requestEmitter.emit('verification-skipped', {
|
|
313
|
+
originalUrl: url,
|
|
314
|
+
});
|
|
315
|
+
requestSpan?.end();
|
|
316
|
+
return response;
|
|
317
|
+
}
|
|
318
|
+
// Verify the response
|
|
319
|
+
// TODO: add more verification and response attributes to the span
|
|
320
|
+
const headers = response.headers;
|
|
321
|
+
// transaction id is either in the response headers or the path of the request as the first parameter
|
|
322
|
+
const txId = headers.get('x-arns-resolved-id') ??
|
|
323
|
+
redirectUrl.pathname.split('/')[1];
|
|
324
|
+
const contentLength = +(headers.get('content-length') ?? 0);
|
|
325
|
+
requestSpan?.setAttribute('txId', txId);
|
|
326
|
+
requestSpan?.setAttribute('contentLength', contentLength);
|
|
327
|
+
requestSpan?.end();
|
|
328
|
+
if (!txIdRegex.test(txId)) {
|
|
329
|
+
// no transaction id found, skip verification
|
|
330
|
+
logger?.debug('No transaction id found, skipping verification', {
|
|
331
|
+
redirectUrl: redirectUrl.toString(),
|
|
332
|
+
originalUrl: url,
|
|
333
|
+
});
|
|
334
|
+
requestEmitter.emit('verification-skipped', {
|
|
335
|
+
originalUrl: url,
|
|
336
|
+
});
|
|
337
|
+
return response;
|
|
338
|
+
}
|
|
339
|
+
// Check if the response has a body
|
|
340
|
+
if (response.body) {
|
|
341
|
+
const newClientStream = tapAndVerifyReadableStream({
|
|
342
|
+
originalStream: response.body,
|
|
343
|
+
contentLength,
|
|
344
|
+
verifyData: verificationSettings.strategy?.verifyData.bind(verificationSettings.strategy),
|
|
345
|
+
txId,
|
|
346
|
+
emitter: requestEmitter,
|
|
347
|
+
strict: verificationSettings.strict,
|
|
348
|
+
});
|
|
349
|
+
return new Response(newClientStream, {
|
|
350
|
+
status: response.status,
|
|
351
|
+
statusText: response.statusText,
|
|
352
|
+
headers: response.headers,
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
// No response body to verify, skip verification
|
|
357
|
+
logger?.debug('No response body to verify', {
|
|
358
|
+
redirectUrl: redirectUrl.toString(),
|
|
359
|
+
originalUrl: url,
|
|
360
|
+
txId,
|
|
361
|
+
});
|
|
362
|
+
return response;
|
|
306
363
|
}
|
|
307
|
-
return response;
|
|
308
364
|
}
|
|
309
365
|
catch (error) {
|
|
310
366
|
logger?.debug('Failed to route request', {
|
|
@@ -353,6 +409,14 @@ export class Wayfinder {
|
|
|
353
409
|
* The verification settings to use when verifying data.
|
|
354
410
|
*/
|
|
355
411
|
verificationSettings;
|
|
412
|
+
/**
|
|
413
|
+
* Telemetry configuration used for OpenTelemetry tracing
|
|
414
|
+
*/
|
|
415
|
+
telemetrySettings;
|
|
416
|
+
/**
|
|
417
|
+
* OpenTelemetry tracer instance
|
|
418
|
+
*/
|
|
419
|
+
tracer;
|
|
356
420
|
/**
|
|
357
421
|
* A helper function that resolves the redirect url for ar:// requests to a target gateway.
|
|
358
422
|
*
|
|
@@ -467,7 +531,7 @@ export class Wayfinder {
|
|
|
467
531
|
* @param options - Wayfinder configuration options
|
|
468
532
|
*/
|
|
469
533
|
constructor({ logger = defaultLogger, gatewaysProvider, // forcing it to be required to avoid making ar-io-sdk a dependency
|
|
470
|
-
verificationSettings, routingSettings, }) {
|
|
534
|
+
verificationSettings, routingSettings, telemetrySettings, }) {
|
|
471
535
|
this.logger = logger;
|
|
472
536
|
this.gatewaysProvider = gatewaysProvider;
|
|
473
537
|
// default verification settings
|
|
@@ -495,12 +559,21 @@ export class Wayfinder {
|
|
|
495
559
|
verification: this.verificationSettings?.events,
|
|
496
560
|
routing: this.routingSettings?.events,
|
|
497
561
|
});
|
|
562
|
+
this.telemetrySettings = {
|
|
563
|
+
enabled: telemetrySettings?.enabled ?? false,
|
|
564
|
+
sampleRate: telemetrySettings?.sampleRate ?? 0.1, // 10% sample rate by default
|
|
565
|
+
apiKey: telemetrySettings?.apiKey ?? 'c8gU8dHlu6V7e5k2Gn9LaG', // intentionally left here - if it gets abused we'll disable it
|
|
566
|
+
exporterUrl: telemetrySettings?.exporterUrl ?? 'https://api.honeycomb.io/v1/traces', // TODO: replace with proxy url and remove api key
|
|
567
|
+
serviceName: telemetrySettings?.serviceName ?? 'wayfinder-core',
|
|
568
|
+
};
|
|
569
|
+
this.tracer = initTelemetry(this.telemetrySettings);
|
|
498
570
|
this.request = wayfinderFetch({
|
|
499
571
|
logger: this.logger,
|
|
500
572
|
emitter: this.emitter,
|
|
501
573
|
gatewaysProvider: this.gatewaysProvider,
|
|
502
574
|
routingSettings: this.routingSettings,
|
|
503
575
|
verificationSettings: this.verificationSettings,
|
|
576
|
+
tracer: this.tracer,
|
|
504
577
|
});
|
|
505
578
|
this.resolveUrl = async ({ originalUrl, logger = this.logger }) => {
|
|
506
579
|
const selectedGateway = await this.routingSettings.strategy.selectGateway({
|
|
@@ -512,6 +585,10 @@ export class Wayfinder {
|
|
|
512
585
|
logger,
|
|
513
586
|
});
|
|
514
587
|
};
|
|
515
|
-
this.logger.debug(
|
|
588
|
+
this.logger.debug('Wayfinder initialized', {
|
|
589
|
+
verificationSettings: this.verificationSettings,
|
|
590
|
+
routingSettings: this.routingSettings,
|
|
591
|
+
telemetrySettings: this.telemetrySettings,
|
|
592
|
+
});
|
|
516
593
|
}
|
|
517
594
|
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ar.io/wayfinder-core",
|
|
3
|
-
"version": "0.0.5-alpha.
|
|
3
|
+
"version": "0.0.5-alpha.4",
|
|
4
4
|
"description": "WayFinder core library for intelligently routing to optimal AR.IO gateways",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"license": "Apache-2.0",
|
|
10
|
-
"keywords": [
|
|
10
|
+
"keywords": [
|
|
11
|
+
"ar-io",
|
|
12
|
+
"arweave",
|
|
13
|
+
"wayfinder",
|
|
14
|
+
"ar://"
|
|
15
|
+
],
|
|
11
16
|
"author": {
|
|
12
17
|
"name": "Permanent Data Solutions Inc",
|
|
13
18
|
"email": "info@ar.io",
|
|
@@ -16,7 +21,12 @@
|
|
|
16
21
|
"publishConfig": {
|
|
17
22
|
"access": "public"
|
|
18
23
|
},
|
|
19
|
-
"files": [
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"package.json",
|
|
27
|
+
"README.md",
|
|
28
|
+
"LICENSE"
|
|
29
|
+
],
|
|
20
30
|
"exports": {
|
|
21
31
|
".": {
|
|
22
32
|
"types": "./dist/index.d.ts",
|
|
@@ -39,6 +49,11 @@
|
|
|
39
49
|
},
|
|
40
50
|
"dependencies": {
|
|
41
51
|
"@dha-team/arbundles": "^1.0.3",
|
|
52
|
+
"@opentelemetry/api": "^1.9.0",
|
|
53
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.202.0",
|
|
54
|
+
"@opentelemetry/sdk-trace-base": "^2.0.1",
|
|
55
|
+
"@opentelemetry/sdk-trace-node": "^2.0.1",
|
|
56
|
+
"@opentelemetry/sdk-trace-web": "^2.0.1",
|
|
42
57
|
"arweave": "^1.14.0",
|
|
43
58
|
"eventemitter3": "^5.0.1",
|
|
44
59
|
"plimit-lit": "^3.0.1",
|