@across-protocol/sdk 4.1.14 → 4.1.16
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/cjs/providers/index.d.ts +1 -0
- package/dist/cjs/providers/index.js +1 -0
- package/dist/cjs/providers/index.js.map +1 -1
- package/dist/cjs/providers/retryProvider.d.ts +6 -1
- package/dist/cjs/providers/retryProvider.js +27 -11
- package/dist/cjs/providers/retryProvider.js.map +1 -1
- package/dist/cjs/providers/solana/baseRpcFactories.d.ts +11 -0
- package/dist/cjs/providers/solana/baseRpcFactories.js +30 -0
- package/dist/cjs/providers/solana/baseRpcFactories.js.map +1 -0
- package/dist/cjs/providers/solana/defaultRpcFactory.d.ts +6 -0
- package/dist/cjs/providers/solana/defaultRpcFactory.js +22 -0
- package/dist/cjs/providers/solana/defaultRpcFactory.js.map +1 -0
- package/dist/cjs/providers/solana/index.d.ts +4 -0
- package/dist/cjs/providers/solana/index.js +8 -0
- package/dist/cjs/providers/solana/index.js.map +1 -0
- package/dist/cjs/providers/solana/rateLimitedRpcFactory.d.ts +16 -0
- package/dist/cjs/providers/solana/rateLimitedRpcFactory.js +105 -0
- package/dist/cjs/providers/solana/rateLimitedRpcFactory.js.map +1 -0
- package/dist/cjs/providers/solana/utils.d.ts +6 -0
- package/dist/cjs/providers/solana/utils.js +3 -0
- package/dist/cjs/providers/solana/utils.js.map +1 -0
- package/dist/esm/providers/index.d.ts +1 -0
- package/dist/esm/providers/index.js +1 -0
- package/dist/esm/providers/index.js.map +1 -1
- package/dist/esm/providers/retryProvider.d.ts +17 -1
- package/dist/esm/providers/retryProvider.js +42 -17
- package/dist/esm/providers/retryProvider.js.map +1 -1
- package/dist/esm/providers/solana/baseRpcFactories.d.ts +11 -0
- package/dist/esm/providers/solana/baseRpcFactories.js +31 -0
- package/dist/esm/providers/solana/baseRpcFactories.js.map +1 -0
- package/dist/esm/providers/solana/defaultRpcFactory.d.ts +6 -0
- package/dist/esm/providers/solana/defaultRpcFactory.js +20 -0
- package/dist/esm/providers/solana/defaultRpcFactory.js.map +1 -0
- package/dist/esm/providers/solana/index.d.ts +4 -0
- package/dist/esm/providers/solana/index.js +5 -0
- package/dist/esm/providers/solana/index.js.map +1 -0
- package/dist/esm/providers/solana/rateLimitedRpcFactory.d.ts +16 -0
- package/dist/esm/providers/solana/rateLimitedRpcFactory.js +116 -0
- package/dist/esm/providers/solana/rateLimitedRpcFactory.js.map +1 -0
- package/dist/esm/providers/solana/utils.d.ts +9 -0
- package/dist/esm/providers/solana/utils.js +2 -0
- package/dist/esm/providers/solana/utils.js.map +1 -0
- package/dist/types/providers/index.d.ts +1 -0
- package/dist/types/providers/index.d.ts.map +1 -1
- package/dist/types/providers/retryProvider.d.ts +17 -1
- package/dist/types/providers/retryProvider.d.ts.map +1 -1
- package/dist/types/providers/solana/baseRpcFactories.d.ts +12 -0
- package/dist/types/providers/solana/baseRpcFactories.d.ts.map +1 -0
- package/dist/types/providers/solana/defaultRpcFactory.d.ts +7 -0
- package/dist/types/providers/solana/defaultRpcFactory.d.ts.map +1 -0
- package/dist/types/providers/solana/index.d.ts +5 -0
- package/dist/types/providers/solana/index.d.ts.map +1 -0
- package/dist/types/providers/solana/rateLimitedRpcFactory.d.ts +17 -0
- package/dist/types/providers/solana/rateLimitedRpcFactory.d.ts.map +1 -0
- package/dist/types/providers/solana/utils.d.ts +10 -0
- package/dist/types/providers/solana/utils.d.ts.map +1 -0
- package/package.json +3 -1
- package/src/providers/index.ts +1 -0
- package/src/providers/retryProvider.ts +44 -17
- package/src/providers/solana/baseRpcFactories.ts +25 -0
- package/src/providers/solana/defaultRpcFactory.ts +13 -0
- package/src/providers/solana/index.ts +4 -0
- package/src/providers/solana/rateLimitedRpcFactory.ts +101 -0
- package/src/providers/solana/utils.ts +14 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { RpcResponse, RpcTransport } from "@solana/web3.js";
|
|
2
|
+
import { QueueObject, queue } from "async";
|
|
3
|
+
import winston, { Logger } from "winston";
|
|
4
|
+
import { SolanaClusterRpcFactory } from "./baseRpcFactories";
|
|
5
|
+
import { SolanaDefaultRpcFactory } from "./defaultRpcFactory";
|
|
6
|
+
import { SolanaRateLimitTask } from "./utils";
|
|
7
|
+
import { getOriginFromURL } from "../../utils";
|
|
8
|
+
|
|
9
|
+
// This factory is a very small addition to the SolanaDefaultRpcFactory that ensures that no more than maxConcurrency
|
|
10
|
+
// requests are ever in flight. It uses the async/queue library to manage this.
|
|
11
|
+
export class RateLimitedSolanaRpcFactory extends SolanaClusterRpcFactory {
|
|
12
|
+
// The queue object that manages the tasks.
|
|
13
|
+
private queue: QueueObject<SolanaRateLimitTask>;
|
|
14
|
+
|
|
15
|
+
// Holds the underlying transport that the rate limiter wraps.
|
|
16
|
+
private readonly defaultTransport: RpcTransport;
|
|
17
|
+
|
|
18
|
+
// Takes the same arguments as the SolanaDefaultRpcFactory, but it has an additional parameters to control
|
|
19
|
+
// concurrency and logging at the beginning of the list.
|
|
20
|
+
constructor(
|
|
21
|
+
maxConcurrency: number,
|
|
22
|
+
readonly pctRpcCallsLogged: number,
|
|
23
|
+
readonly logger: Logger = winston.createLogger({
|
|
24
|
+
transports: [new winston.transports.Console()],
|
|
25
|
+
}),
|
|
26
|
+
...defaultConstructorParams: ConstructorParameters<typeof SolanaDefaultRpcFactory>
|
|
27
|
+
) {
|
|
28
|
+
super(...defaultConstructorParams);
|
|
29
|
+
this.defaultTransport = new SolanaDefaultRpcFactory(...defaultConstructorParams).createTransport();
|
|
30
|
+
|
|
31
|
+
// This sets up the queue. Each task is executed by forwarding the RPC request to the underlying base transport.
|
|
32
|
+
// This queue sends out requests concurrently, but stops once the concurrency limit is reached. The maxConcurrency
|
|
33
|
+
// is configured here.
|
|
34
|
+
this.queue = queue(async ({ rpcArgs, resolve, reject }: SolanaRateLimitTask, callback: () => void) => {
|
|
35
|
+
await this.wrapSendWithLog(...rpcArgs)
|
|
36
|
+
.then(resolve)
|
|
37
|
+
.catch(reject);
|
|
38
|
+
// we need this for the queue to know that the task is done
|
|
39
|
+
// @see: https://caolan.github.io/async/v3/global.html
|
|
40
|
+
callback();
|
|
41
|
+
}, maxConcurrency);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private async wrapSendWithLog(...rpcArgs: Parameters<RpcTransport>) {
|
|
45
|
+
if (this.pctRpcCallsLogged <= 0 || Math.random() > this.pctRpcCallsLogged / 100) {
|
|
46
|
+
// Non sample path: no logging or timing, just issue the request.
|
|
47
|
+
return await this.defaultTransport(...rpcArgs);
|
|
48
|
+
} else {
|
|
49
|
+
const payload = rpcArgs[0].payload as { method: string; params?: unknown[] };
|
|
50
|
+
const loggerArgs = {
|
|
51
|
+
at: "SolanaProviderUtils",
|
|
52
|
+
message: "Solana provider response sample",
|
|
53
|
+
provider: getOriginFromURL(this.clusterUrl),
|
|
54
|
+
method: payload.method,
|
|
55
|
+
params: payload.params,
|
|
56
|
+
chainId: this.chainId,
|
|
57
|
+
datadog: true,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// In this path we log an rpc response sample.
|
|
61
|
+
// Note: use performance.now() to ensure a purely monotonic clock.
|
|
62
|
+
const startTime = performance.now();
|
|
63
|
+
try {
|
|
64
|
+
const result = await this.defaultTransport(...rpcArgs);
|
|
65
|
+
const elapsedTimeS = (performance.now() - startTime) / 1000;
|
|
66
|
+
this.logger.debug({
|
|
67
|
+
...loggerArgs,
|
|
68
|
+
success: true,
|
|
69
|
+
timeElapsed: elapsedTimeS,
|
|
70
|
+
});
|
|
71
|
+
return result;
|
|
72
|
+
} catch (error) {
|
|
73
|
+
// Log errors as well.
|
|
74
|
+
// For now, to keep logs light, don't log the error itself, just propagate and let it be handled higher up.
|
|
75
|
+
const elapsedTimeS = (performance.now() - startTime) / 1000;
|
|
76
|
+
this.logger.debug({
|
|
77
|
+
...loggerArgs,
|
|
78
|
+
success: false,
|
|
79
|
+
timeElapsed: elapsedTimeS,
|
|
80
|
+
});
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
public createTransport() {
|
|
87
|
+
return <TResponse>(...args: Parameters<RpcTransport>): Promise<RpcResponse<TResponse>> => {
|
|
88
|
+
// This simply creates a promise and adds the arguments and resolve and reject handlers to the task.
|
|
89
|
+
return new Promise<RpcResponse<TResponse>>((resolve, reject) => {
|
|
90
|
+
const task: SolanaRateLimitTask = {
|
|
91
|
+
rpcArgs: args,
|
|
92
|
+
resolve: resolve as (value: unknown) => void,
|
|
93
|
+
reject,
|
|
94
|
+
};
|
|
95
|
+
// We didn't previously wait for this push so we can emulate
|
|
96
|
+
// the same behavior with the `void` keyword.
|
|
97
|
+
void this.queue.push(task);
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { RpcTransport } from "@solana/rpc-spec";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This is the type we pass to define a Solana RPC request "task".
|
|
5
|
+
*/
|
|
6
|
+
export interface SolanaRateLimitTask {
|
|
7
|
+
// These are the arguments to be passed to base transport when making the RPC request.
|
|
8
|
+
rpcArgs: Parameters<RpcTransport>;
|
|
9
|
+
|
|
10
|
+
// These are the promise callbacks that will cause the initial RPC call made by the user to either return a result
|
|
11
|
+
// or fail.
|
|
12
|
+
resolve: (result: unknown) => void;
|
|
13
|
+
reject: (err: unknown) => void;
|
|
14
|
+
}
|