@solana/rpc-transport-http 2.0.0-experimental.fbbf6ba → 2.0.0-experimental.feaeef2

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 CHANGED
@@ -14,4 +14,231 @@
14
14
 
15
15
  # @solana/rpc-transport-http
16
16
 
17
- TODO
17
+ This package allows developers to create custom RPC transports. With this library, one can implement highly specialized functionality for leveraging multiple transports, attempting/handling retries, and more.
18
+
19
+ ## Functions
20
+
21
+ ### `createHttpTransport()`
22
+
23
+ Call this to create a function that conforms to the `RpcTransport` interface (see `@solana/rpc-spec`). You can use that function in your programs to make `POST` requests with headers suitable for sending JSON data to a server.
24
+
25
+ ```ts
26
+ import { createHttpTransport } from '@solana/rpc-transport-http';
27
+
28
+ const transport = createHttpTransport({ url: 'https://api.mainnet-beta.solana.com' });
29
+ const response = await transport({
30
+ payload: { id: 1, jsonrpc: '2.0', method: 'getSlot' },
31
+ });
32
+ ```
33
+
34
+ #### Config
35
+
36
+ ##### `dispatcher_NODE_ONLY`
37
+
38
+ In Node environments you can tune how requests are dispatched to the network. Use this config parameter to install a [`undici.Dispatcher`](https://undici.nodejs.org/#/docs/api/Agent) in your transport.
39
+
40
+ ```ts
41
+ import { createHttpTransport } from '@solana/rpc-transport-http';
42
+ import { Agent, BalancedPool } from 'undici';
43
+
44
+ // Create a dispatcher that, when called with a special URL, creates a round-robin pool of RPCs.
45
+ const dispatcher = new Agent({
46
+ factory(origin, opts) {
47
+ if (origin === 'https://mypool') {
48
+ const upstreams = [
49
+ 'https://api.mainnet-beta.solana.com',
50
+ 'https://mainnet.helius-rpc.com',
51
+ 'https://several-neat-iguana.quiknode.pro',
52
+ ];
53
+ return new BalancedPool(upstreams, {
54
+ ...opts,
55
+ bodyTimeout: 60e3,
56
+ headersTimeout: 5e3,
57
+ keepAliveTimeout: 19e3,
58
+ });
59
+ } else {
60
+ return new Pool(origin, opts);
61
+ }
62
+ },
63
+ });
64
+ const transport = createHttpTransport({
65
+ dispatcher_NODE_ONLY: dispatcher,
66
+ url: 'https://mypool',
67
+ });
68
+ let id = 0;
69
+ const balances = await Promise.allSettled(
70
+ accounts.map(account =>
71
+ transport({
72
+ payload: {
73
+ id: ++id,
74
+ jsonrpc: '2.0',
75
+ method: 'getBalance',
76
+ params: [account],
77
+ },
78
+ }),
79
+ ),
80
+ );
81
+ ```
82
+
83
+ ##### `headers`
84
+
85
+ An object of headers to set on the request. Avoid [forbidden headers](https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name). Additionally, the headers `Accept`, `Content-Length`, and `Content-Type` are disallowed.
86
+
87
+ ```ts
88
+ import { createHttpTransport } from '@solana/rpc-transport-http';
89
+
90
+ const transport = createHttpTransport({
91
+ headers: {
92
+ // Authorize with the RPC using a bearer token
93
+ Authorization: `Bearer ${process.env.RPC_AUTH_TOKEN}`,
94
+ },
95
+ url: 'https://several-neat-iguana.quiknode.pro',
96
+ });
97
+ ```
98
+
99
+ ##### `url`
100
+
101
+ A string representing the target endpoint. In Node, it must be an absolute URL using the `http` or `https` protocol.
102
+
103
+ ## Augmenting Transports
104
+
105
+ Using this core transport, you can implement specialized functionality for leveraging multiple transports, attempting/handling retries, and more.
106
+
107
+ ### Round Robin
108
+
109
+ Here’s an example of how someone might implement a “round robin” approach to distribute requests to multiple transports:
110
+
111
+ ```ts
112
+ import { RpcTransport } from '@solana/rpc-spec';
113
+ import { createHttpTransport } from '@solana/rpc-transport-http';
114
+
115
+ // Create a transport for each RPC server
116
+ const transports = [
117
+ createHttpTransport({ url: 'https://mainnet-beta.my-server-1.com' }),
118
+ createHttpTransport({ url: 'https://mainnet-beta.my-server-2.com' }),
119
+ createHttpTransport({ url: 'https://mainnet-beta.my-server-3.com' }),
120
+ ];
121
+
122
+ // Create a wrapper transport that distributes requests to them
123
+ let nextTransport = 0;
124
+ async function roundRobinTransport<TResponse>(...args: Parameters<RpcTransport>): Promise<TResponse> {
125
+ const transport = transports[nextTransport];
126
+ nextTransport = (nextTransport + 1) % transports.length;
127
+ return await transport(...args);
128
+ }
129
+ ```
130
+
131
+ ### Sharding
132
+
133
+ Another example of a possible customization for a transport is to shard requests deterministically among a set of servers. Here’s an example:
134
+
135
+ Perhaps your application needs to make a large number of requests, or needs to fan request for different methods out to different servers. Here’s an example of an implementation that does the latter:
136
+
137
+ ```ts
138
+ import { RpcTransport } from '@solana/rpc-spec';
139
+ import { createHttpTransport } from '@solana/rpc-transport-http';
140
+
141
+ // Create multiple transports
142
+ const transportA = createHttpTransport({ url: 'https://mainnet-beta.my-server-1.com' });
143
+ const transportB = createHttpTransport({ url: 'https://mainnet-beta.my-server-2.com' });
144
+ const transportC = createHttpTransport({ url: 'https://mainnet-beta.my-server-3.com' });
145
+ const transportD = createHttpTransport({ url: 'https://mainnet-beta.my-server-4.com' });
146
+
147
+ // Function to determine which shard to use based on the request method
148
+ function selectShard(method: string): RpcTransport {
149
+ switch (method) {
150
+ case 'getAccountInfo':
151
+ case 'getBalance':
152
+ return transportA;
153
+ case 'getTransaction':
154
+ case 'getRecentBlockhash':
155
+ return transportB;
156
+ case 'sendTransaction':
157
+ return transportC;
158
+ default:
159
+ return transportD;
160
+ }
161
+ }
162
+
163
+ async function shardingTransport<TResponse>(...args: Parameters<RpcTransport>): Promise<TResponse> {
164
+ const payload = args[0].payload as { method: string };
165
+ const selectedTransport = selectShard(payload.method);
166
+ return await selectedTransport(...args);
167
+ }
168
+ ```
169
+
170
+ ### Retry Logic
171
+
172
+ The transport library can also be used to implement custom retry logic on any request:
173
+
174
+ ```ts
175
+ import { RpcTransport } from '@solana/rpc-spec';
176
+ import { createHttpTransport } from '@solana/rpc-transport-http';
177
+
178
+ // Set the maximum number of attempts to retry a request
179
+ const MAX_ATTEMPTS = 4;
180
+
181
+ // Create the default transport
182
+ const defaultTransport = createHttpTransport({ url: 'https://mainnet-beta.my-server-1.com' });
183
+
184
+ // Sleep function to wait for a given number of milliseconds
185
+ function sleep(ms: number): Promise<void> {
186
+ return new Promise(resolve => setTimeout(resolve, ms));
187
+ }
188
+
189
+ // Calculate the delay for a given attempt
190
+ function calculateRetryDelay(attempt: number): number {
191
+ // Exponential backoff with a maximum of 1.5 seconds
192
+ return Math.min(100 * Math.pow(2, attempt), 1500);
193
+ }
194
+
195
+ // A retrying transport that will retry up to `MAX_ATTEMPTS` times before failing
196
+ async function retryingTransport<TResponse>(...args: Parameters<RpcTransport>): Promise<TResponse> {
197
+ let requestError;
198
+ for (let attempts = 0; attempts < MAX_ATTEMPTS; attempts++) {
199
+ try {
200
+ return await defaultTransport(...args);
201
+ } catch (err) {
202
+ requestError = err;
203
+ // Only sleep if we have more attempts remaining
204
+ if (attempts < MAX_ATTEMPTS - 1) {
205
+ const retryDelay = calculateRetryDelay(attempts);
206
+ await sleep(retryDelay);
207
+ }
208
+ }
209
+ }
210
+ throw requestError;
211
+ }
212
+ ```
213
+
214
+ ### Failover
215
+
216
+ Here’s an example of some failover logic integrated into a transport:
217
+
218
+ ```ts
219
+ import { RpcTransport } from '@solana/rpc-spec';
220
+ import { createHttpTransport } from '@solana/rpc-transport-http';
221
+
222
+ // Create a transport for each RPC server
223
+ const transports = [
224
+ createHttpTransport({ url: 'https://mainnet-beta.my-server-1.com' }),
225
+ createHttpTransport({ url: 'https://mainnet-beta.my-server-2.com' }),
226
+ createHttpTransport({ url: 'https://mainnet-beta.my-server-2.com' }),
227
+ ];
228
+
229
+ // A failover transport that will try each transport in order until one succeeds before failing
230
+ async function failoverTransport<TResponse>(...args: Parameters<RpcTransport>): Promise<TResponse> {
231
+ let requestError;
232
+
233
+ for (const transport of transports) {
234
+ try {
235
+ return await transport(...args);
236
+ } catch (err) {
237
+ requestError = err;
238
+ console.error(err);
239
+ }
240
+ }
241
+ throw requestError;
242
+ }
243
+
244
+ ```
@@ -1,25 +1,12 @@
1
1
  'use strict';
2
2
 
3
+ var errors = require('@solana/errors');
4
+
3
5
  // ../build-scripts/env-shim.ts
4
6
  var __DEV__ = /* @__PURE__ */ (() => process["env"].NODE_ENV === "development")();
5
7
 
6
8
  // ../fetch-impl/dist/index.browser.js
7
9
  var e = globalThis.fetch;
8
-
9
- // src/http-transport-errors.ts
10
- var SolanaHttpError = class extends Error {
11
- statusCode;
12
- constructor(details) {
13
- super(`HTTP error (${details.statusCode}): ${details.message}`);
14
- Error.captureStackTrace(this, this.constructor);
15
- this.statusCode = details.statusCode;
16
- }
17
- get name() {
18
- return "SolanaHttpError";
19
- }
20
- };
21
-
22
- // src/http-transport-headers.ts
23
10
  var DISALLOWED_HEADERS = {
24
11
  accept: true,
25
12
  "content-length": true,
@@ -40,9 +27,9 @@ var FORBIDDEN_HEADERS = {
40
27
  "keep-alive": true,
41
28
  origin: true,
42
29
  "permissions-policy": true,
43
- // No currently available Typescript technique allows you to match on a prefix.
44
- // 'proxy-':true,
45
- // 'sec-':true,
30
+ // Prefix matching is implemented in code, below.
31
+ // 'proxy-': true,
32
+ // 'sec-': true,
46
33
  referer: true,
47
34
  te: true,
48
35
  trailer: true,
@@ -56,9 +43,9 @@ function assertIsAllowedHttpRequestHeaders(headers) {
56
43
  return DISALLOWED_HEADERS[headerName.toLowerCase()] === true || FORBIDDEN_HEADERS[headerName.toLowerCase()] === true || lowercaseHeaderName.startsWith("proxy-") || lowercaseHeaderName.startsWith("sec-");
57
44
  });
58
45
  if (badHeaders.length > 0) {
59
- throw new Error(
60
- `${badHeaders.length > 1 ? "These headers are" : "This header is"} forbidden: \`${badHeaders.join("`, `")}\`. Learn more at https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name.`
61
- );
46
+ throw new errors.SolanaError(errors.SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, {
47
+ headers: badHeaders
48
+ });
62
49
  }
63
50
  }
64
51
  function normalizeHeaders(headers) {
@@ -70,10 +57,25 @@ function normalizeHeaders(headers) {
70
57
  }
71
58
 
72
59
  // src/http-transport.ts
73
- function createHttpTransport({ headers, url }) {
60
+ var didWarnDispatcherWasSuppliedInNonNodeEnvironment = false;
61
+ function warnDispatcherWasSuppliedInNonNodeEnvironment() {
62
+ if (didWarnDispatcherWasSuppliedInNonNodeEnvironment) {
63
+ return;
64
+ }
65
+ didWarnDispatcherWasSuppliedInNonNodeEnvironment = true;
66
+ console.warn(
67
+ "You have supplied a `Dispatcher` to `createHttpTransport()`. It has been ignored because Undici dispatchers only work in Node environments. To eliminate this warning, omit the `dispatcher_NODE_ONLY` property from your config when running in a non-Node environment."
68
+ );
69
+ }
70
+ function createHttpTransport(config) {
71
+ if (__DEV__ && true && "dispatcher_NODE_ONLY" in config) {
72
+ warnDispatcherWasSuppliedInNonNodeEnvironment();
73
+ }
74
+ const { headers, url } = config;
74
75
  if (__DEV__ && headers) {
75
76
  assertIsAllowedHttpRequestHeaders(headers);
76
77
  }
78
+ let dispatcherConfig;
77
79
  const customHeaders = headers && normalizeHeaders(headers);
78
80
  return async function makeHttpRequest({
79
81
  payload,
@@ -81,6 +83,7 @@ function createHttpTransport({ headers, url }) {
81
83
  }) {
82
84
  const body = JSON.stringify(payload);
83
85
  const requestInfo = {
86
+ ...dispatcherConfig,
84
87
  body,
85
88
  headers: {
86
89
  ...customHeaders,
@@ -94,7 +97,7 @@ function createHttpTransport({ headers, url }) {
94
97
  };
95
98
  const response = await e(url, requestInfo);
96
99
  if (!response.ok) {
97
- throw new SolanaHttpError({
100
+ throw new errors.SolanaError(errors.SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, {
98
101
  message: response.statusText,
99
102
  statusCode: response.status
100
103
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../build-scripts/env-shim.ts","../../fetch-impl/src/index.browser.ts","../src/http-transport-errors.ts","../src/http-transport-headers.ts","../src/http-transport.ts"],"names":["index_browser_default"],"mappings":";AACO,IAAM,UAA2B,uBAAO,QAAgB,KAAU,EAAE,aAAa,eAAe;;;ACDvG,IAAOA,IAAQ,WAAW;;;ACKnB,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAC9B;AAAA,EACT,YAAY,SAAiC;AACzC,UAAM,eAAe,QAAQ,UAAU,MAAM,QAAQ,OAAO,EAAE;AAC9D,UAAM,kBAAkB,MAAM,KAAK,WAAW;AAC9C,SAAK,aAAa,QAAQ;AAAA,EAC9B;AAAA,EACA,IAAI,OAAO;AACP,WAAO;AAAA,EACX;AACJ;;;AC2BA,IAAM,qBAA8C;AAAA,EAChD,QAAQ;AAAA,EACR,kBAAkB;AAAA,EAClB,gBAAgB;AACpB;AAEA,IAAM,oBAA6C;AAAA,EAC/C,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,kCAAkC;AAAA,EAClC,iCAAiC;AAAA,EACjC,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,sBAAsB;AAAA;AAAA;AAAA;AAAA,EAItB,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,SAAS;AAAA,EACT,KAAK;AACT;AAEO,SAAS,kCACZ,SAC4C;AAC5C,QAAM,aAAa,OAAO,KAAK,OAAO,EAAE,OAAO,gBAAc;AACzD,UAAM,sBAAsB,WAAW,YAAY;AACnD,WACI,mBAAmB,WAAW,YAAY,CAAC,MAAM,QACjD,kBAAkB,WAAW,YAAY,CAAC,MAAM,QAChD,oBAAoB,WAAW,QAAQ,KACvC,oBAAoB,WAAW,MAAM;AAAA,EAE7C,CAAC;AACD,MAAI,WAAW,SAAS,GAAG;AACvB,UAAM,IAAI;AAAA,MACN,GAAG,WAAW,SAAS,IAAI,sBAAsB,gBAAgB,iBACxD,WAAW,KAAK,MAAM,CAAC;AAAA,IAEpC;AAAA,EACJ;AACJ;AAMO,SAAS,iBACZ,SACiD;AACjD,QAAM,MAA8B,CAAC;AACrC,aAAW,cAAc,SAAS;AAC9B,QAAI,WAAW,YAAY,CAAC,IAAI,QAAQ,UAAU;AAAA,EACtD;AACA,SAAO;AACX;;;AC5FO,SAAS,oBAAoB,EAAE,SAAS,IAAI,GAAyB;AACxE,MAAI,WAAW,SAAS;AACpB,sCAAkC,OAAO;AAAA,EAC7C;AACA,QAAM,gBAAgB,WAAW,iBAAiB,OAAO;AACzD,SAAO,eAAe,gBAA2B;AAAA,IAC7C;AAAA,IACA;AAAA,EACJ,GAAoD;AAChD,UAAM,OAAO,KAAK,UAAU,OAAO;AACnC,UAAM,cAAc;AAAA,MAChB;AAAA,MACA,SAAS;AAAA,QACL,GAAG;AAAA;AAAA,QAEH,QAAQ;AAAA,QACR,kBAAkB,KAAK,OAAO,SAAS;AAAA,QACvC,gBAAgB;AAAA,MACpB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACJ;AACA,UAAM,WAAW,MAAM,EAAU,KAAK,WAAW;AACjD,QAAI,CAAC,SAAS,IAAI;AACd,YAAM,IAAI,gBAAgB;AAAA,QACtB,SAAS,SAAS;AAAA,QAClB,YAAY,SAAS;AAAA,MACzB,CAAC;AAAA,IACL;AACA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAChC;AACJ","sourcesContent":["// Clever obfuscation to prevent the build system from inlining the value of `NODE_ENV`\nexport const __DEV__ = /* @__PURE__ */ (() => (process as any)['en' + 'v'].NODE_ENV === 'development')();\n","export default globalThis.fetch;\n","type SolanaHttpErrorDetails = Readonly<{\n statusCode: number;\n message: string;\n}>;\n\nexport class SolanaHttpError extends Error {\n readonly statusCode: number;\n constructor(details: SolanaHttpErrorDetails) {\n super(`HTTP error (${details.statusCode}): ${details.message}`);\n Error.captureStackTrace(this, this.constructor);\n this.statusCode = details.statusCode;\n }\n get name() {\n return 'SolanaHttpError';\n }\n}\n","export type AllowedHttpRequestHeaders = Readonly<\n { [headerName: string]: string } & {\n // Someone can still sneak a forbidden header past Typescript if they do something like\n // fOo-BaR, but at that point they deserve the runtime failure.\n [K in DisallowedHeaders | ForbiddenHeaders as\n | K // `Foo-Bar`\n | Capitalize<Lowercase<K>> // `Foo-bar`\n | Lowercase<K> // `foo-bar`\n | Uncapitalize<K> // `foo-Bar`\n // `FOO-BAR`\n | Uppercase<K>]?: never;\n }\n>;\n// These are headers that we simply don't allow the developer to override because they're\n// fundamental to the operation of the JSON-RPC transport.\ntype DisallowedHeaders = 'Accept' | 'Content-Length' | 'Content-Type' | 'Solana-Client';\ntype ForbiddenHeaders =\n | 'Accept-Charset'\n | 'Accept-Encoding'\n | 'Access-Control-Request-Headers'\n | 'Access-Control-Request-Method'\n | 'Connection'\n | 'Content-Length'\n | 'Cookie'\n | 'Date'\n | 'DNT'\n | 'Expect'\n | 'Host'\n | 'Keep-Alive'\n | 'Origin'\n | 'Permissions-Policy'\n // No currently available Typescript technique allows you to match on a prefix.\n // | 'Proxy-'\n // | 'Sec-'\n | 'Referer'\n | 'TE'\n | 'Trailer'\n | 'Transfer-Encoding'\n | 'Upgrade'\n | 'Via';\n\n// These are headers which are fundamental to the JSON-RPC transport, and must not be modified.\nconst DISALLOWED_HEADERS: Record<string, boolean> = {\n accept: true,\n 'content-length': true,\n 'content-type': true,\n};\n// https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name\nconst FORBIDDEN_HEADERS: Record<string, boolean> = {\n 'accept-charset': true,\n 'accept-encoding': true,\n 'access-control-request-headers': true,\n 'access-control-request-method': true,\n connection: true,\n 'content-length': true,\n cookie: true,\n date: true,\n dnt: true,\n expect: true,\n host: true,\n 'keep-alive': true,\n origin: true,\n 'permissions-policy': true,\n // No currently available Typescript technique allows you to match on a prefix.\n // 'proxy-':true,\n // 'sec-':true,\n referer: true,\n te: true,\n trailer: true,\n 'transfer-encoding': true,\n upgrade: true,\n via: true,\n};\n\nexport function assertIsAllowedHttpRequestHeaders(\n headers: Record<string, string>,\n): asserts headers is AllowedHttpRequestHeaders {\n const badHeaders = Object.keys(headers).filter(headerName => {\n const lowercaseHeaderName = headerName.toLowerCase();\n return (\n DISALLOWED_HEADERS[headerName.toLowerCase()] === true ||\n FORBIDDEN_HEADERS[headerName.toLowerCase()] === true ||\n lowercaseHeaderName.startsWith('proxy-') ||\n lowercaseHeaderName.startsWith('sec-')\n );\n });\n if (badHeaders.length > 0) {\n throw new Error(\n `${badHeaders.length > 1 ? 'These headers are' : 'This header is'} forbidden: ` +\n `\\`${badHeaders.join('`, `')}\\`. Learn more at ` +\n 'https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name.',\n );\n }\n}\n\n/**\n * Lowercasing header names makes it easier to override user-supplied headers, such as those defined\n * in the `DisallowedHeaders` type.\n */\nexport function normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in keyof T & string as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in keyof T & string as Lowercase<K>]: T[K] };\n}\n","import fetchImpl from '@solana/fetch-impl';\nimport { RpcTransport } from '@solana/rpc-spec';\n\nimport { SolanaHttpError } from './http-transport-errors';\nimport {\n AllowedHttpRequestHeaders,\n assertIsAllowedHttpRequestHeaders,\n normalizeHeaders,\n} from './http-transport-headers';\n\ntype Config = Readonly<{\n headers?: AllowedHttpRequestHeaders;\n url: string;\n}>;\n\nexport function createHttpTransport({ headers, url }: Config): RpcTransport {\n if (__DEV__ && headers) {\n assertIsAllowedHttpRequestHeaders(headers);\n }\n const customHeaders = headers && normalizeHeaders(headers);\n return async function makeHttpRequest<TResponse>({\n payload,\n signal,\n }: Parameters<RpcTransport>[0]): Promise<TResponse> {\n const body = JSON.stringify(payload);\n const requestInfo = {\n body,\n headers: {\n ...customHeaders,\n // Keep these headers lowercase so they will override any user-supplied headers above.\n accept: 'application/json',\n 'content-length': body.length.toString(),\n 'content-type': 'application/json; charset=utf-8',\n },\n method: 'POST',\n signal,\n };\n const response = await fetchImpl(url, requestInfo);\n if (!response.ok) {\n throw new SolanaHttpError({\n message: response.statusText,\n statusCode: response.status,\n });\n }\n return (await response.json()) as TResponse;\n };\n}\n"]}
1
+ {"version":3,"sources":["../../build-scripts/env-shim.ts","../src/http-transport.ts","../../fetch-impl/src/index.browser.ts","../src/http-transport-headers.ts"],"names":["SolanaError","index_browser_default"],"mappings":";AACO,IAAM,UAA2B,uBAAO,QAAgB,KAAU,EAAE,aAAa,eAAe;;;ACDvG,SAAS,yCAAyC,eAAAA,oBAAmB;;;ACArE,IAAOC,IAAQ,WAAW;;;ACA1B,SAAS,oDAAoD,mBAAmB;AA2ChF,IAAM,qBAA8C;AAAA,EAChD,QAAQ;AAAA,EACR,kBAAkB;AAAA,EAClB,gBAAgB;AACpB;AAEA,IAAM,oBAA6C;AAAA,EAC/C,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,kCAAkC;AAAA,EAClC,iCAAiC;AAAA,EACjC,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,sBAAsB;AAAA;AAAA;AAAA;AAAA,EAItB,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,SAAS;AAAA,EACT,KAAK;AACT;AAEO,SAAS,kCACZ,SAC4C;AAC5C,QAAM,aAAa,OAAO,KAAK,OAAO,EAAE,OAAO,gBAAc;AACzD,UAAM,sBAAsB,WAAW,YAAY;AACnD,WACI,mBAAmB,WAAW,YAAY,CAAC,MAAM,QACjD,kBAAkB,WAAW,YAAY,CAAC,MAAM,QAChD,oBAAoB,WAAW,QAAQ,KACvC,oBAAoB,WAAW,MAAM;AAAA,EAE7C,CAAC;AACD,MAAI,WAAW,SAAS,GAAG;AACvB,UAAM,IAAI,YAAY,oDAAoD;AAAA,MACtE,SAAS;AAAA,IACb,CAAC;AAAA,EACL;AACJ;AAMO,SAAS,iBACZ,SACiD;AACjD,QAAM,MAA8B,CAAC;AACrC,aAAW,cAAc,SAAS;AAC9B,QAAI,WAAW,YAAY,CAAC,IAAI,QAAQ,UAAU;AAAA,EACtD;AACA,SAAO;AACX;;;AFzFA,IAAI,mDAAmD;AACvD,SAAS,gDAAgD;AACrD,MAAI,kDAAkD;AAClD;AAAA,EACJ;AACA,qDAAmD;AACnD,UAAQ;AAAA,IACJ;AAAA,EAIJ;AACJ;AAEO,SAAS,oBAAoB,QAA8B;AAC9D,MAAI,WAAW,QAAe,0BAA0B,QAAQ;AAC5D,kDAA8C;AAAA,EAClD;AACA,QAAM,EAAE,SAAS,IAAI,IAAI;AACzB,MAAI,WAAW,SAAS;AACpB,sCAAkC,OAAO;AAAA,EAC7C;AACA,MAAI;AACJ,MAAI,OAAgD;AAChD,uBAAmB,EAAE,YAAY,OAAO,qBAAqB;AAAA,EACjE;AACA,QAAM,gBAAgB,WAAW,iBAAiB,OAAO;AACzD,SAAO,eAAe,gBAA2B;AAAA,IAC7C;AAAA,IACA;AAAA,EACJ,GAAoD;AAChD,UAAM,OAAO,KAAK,UAAU,OAAO;AACnC,UAAM,cAAc;AAAA,MAChB,GAAG;AAAA,MACH;AAAA,MACA,SAAS;AAAA,QACL,GAAG;AAAA;AAAA,QAEH,QAAQ;AAAA,QACR,kBAAkB,KAAK,OAAO,SAAS;AAAA,QACvC,gBAAgB;AAAA,MACpB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACJ;AACA,UAAM,WAAW,MAAM,EAAU,KAAK,WAAW;AACjD,QAAI,CAAC,SAAS,IAAI;AACd,YAAM,IAAID,aAAY,yCAAyC;AAAA,QAC3D,SAAS,SAAS;AAAA,QAClB,YAAY,SAAS;AAAA,MACzB,CAAC;AAAA,IACL;AACA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAChC;AACJ","sourcesContent":["// Clever obfuscation to prevent the build system from inlining the value of `NODE_ENV`\nexport const __DEV__ = /* @__PURE__ */ (() => (process as any)['en' + 'v'].NODE_ENV === 'development')();\n","import { SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, SolanaError } from '@solana/errors';\nimport fetchImpl from '@solana/fetch-impl';\nimport { RpcTransport } from '@solana/rpc-spec';\nimport type Dispatcher from 'undici/types/dispatcher';\n\nimport {\n AllowedHttpRequestHeaders,\n assertIsAllowedHttpRequestHeaders,\n normalizeHeaders,\n} from './http-transport-headers';\n\ntype Config = Readonly<{\n dispatcher_NODE_ONLY?: Dispatcher;\n headers?: AllowedHttpRequestHeaders;\n url: string;\n}>;\n\nlet didWarnDispatcherWasSuppliedInNonNodeEnvironment = false;\nfunction warnDispatcherWasSuppliedInNonNodeEnvironment() {\n if (didWarnDispatcherWasSuppliedInNonNodeEnvironment) {\n return;\n }\n didWarnDispatcherWasSuppliedInNonNodeEnvironment = true;\n console.warn(\n 'You have supplied a `Dispatcher` to `createHttpTransport()`. It has been ignored ' +\n 'because Undici dispatchers only work in Node environments. To eliminate this ' +\n 'warning, omit the `dispatcher_NODE_ONLY` property from your config when running in ' +\n 'a non-Node environment.',\n );\n}\n\nexport function createHttpTransport(config: Config): RpcTransport {\n if (__DEV__ && !__NODEJS__ && 'dispatcher_NODE_ONLY' in config) {\n warnDispatcherWasSuppliedInNonNodeEnvironment();\n }\n const { headers, url } = config;\n if (__DEV__ && headers) {\n assertIsAllowedHttpRequestHeaders(headers);\n }\n let dispatcherConfig: { dispatcher: Dispatcher | undefined } | undefined;\n if (__NODEJS__ && 'dispatcher_NODE_ONLY' in config) {\n dispatcherConfig = { dispatcher: config.dispatcher_NODE_ONLY };\n }\n const customHeaders = headers && normalizeHeaders(headers);\n return async function makeHttpRequest<TResponse>({\n payload,\n signal,\n }: Parameters<RpcTransport>[0]): Promise<TResponse> {\n const body = JSON.stringify(payload);\n const requestInfo = {\n ...dispatcherConfig,\n body,\n headers: {\n ...customHeaders,\n // Keep these headers lowercase so they will override any user-supplied headers above.\n accept: 'application/json',\n 'content-length': body.length.toString(),\n 'content-type': 'application/json; charset=utf-8',\n },\n method: 'POST',\n signal,\n };\n const response = await fetchImpl(url, requestInfo);\n if (!response.ok) {\n throw new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, {\n message: response.statusText,\n statusCode: response.status,\n });\n }\n return (await response.json()) as TResponse;\n };\n}\n","export default globalThis.fetch;\n","import { SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, SolanaError } from '@solana/errors';\n\nexport type AllowedHttpRequestHeaders = Readonly<\n { [headerName: string]: string } & {\n // Someone can still sneak a forbidden header past Typescript if they do something like\n // fOo-BaR, but at that point they deserve the runtime failure.\n [K in DisallowedHeaders | ForbiddenHeaders as\n | K // `Foo-Bar`\n | Capitalize<Lowercase<K>> // `Foo-bar`\n | Lowercase<K> // `foo-bar`\n | Uncapitalize<K> // `foo-Bar`\n // `FOO-BAR`\n | Uppercase<K>]?: never;\n }\n>;\n// These are headers that we simply don't allow the developer to override because they're\n// fundamental to the operation of the JSON-RPC transport.\ntype DisallowedHeaders = 'Accept' | 'Content-Length' | 'Content-Type' | 'Solana-Client';\ntype ForbiddenHeaders =\n | 'Accept-Charset'\n | 'Accept-Encoding'\n | 'Access-Control-Request-Headers'\n | 'Access-Control-Request-Method'\n | 'Connection'\n | 'Content-Length'\n | 'Cookie'\n | 'Date'\n | 'DNT'\n | 'Expect'\n | 'Host'\n | 'Keep-Alive'\n | 'Origin'\n | 'Permissions-Policy'\n | `Proxy-${string}`\n | `Sec-${string}`\n | 'Referer'\n | 'TE'\n | 'Trailer'\n | 'Transfer-Encoding'\n | 'Upgrade'\n | 'Via';\n\n// These are headers which are fundamental to the JSON-RPC transport, and must not be modified.\nconst DISALLOWED_HEADERS: Record<string, boolean> = {\n accept: true,\n 'content-length': true,\n 'content-type': true,\n};\n// https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name\nconst FORBIDDEN_HEADERS: Record<string, boolean> = {\n 'accept-charset': true,\n 'accept-encoding': true,\n 'access-control-request-headers': true,\n 'access-control-request-method': true,\n connection: true,\n 'content-length': true,\n cookie: true,\n date: true,\n dnt: true,\n expect: true,\n host: true,\n 'keep-alive': true,\n origin: true,\n 'permissions-policy': true,\n // Prefix matching is implemented in code, below.\n // 'proxy-': true,\n // 'sec-': true,\n referer: true,\n te: true,\n trailer: true,\n 'transfer-encoding': true,\n upgrade: true,\n via: true,\n};\n\nexport function assertIsAllowedHttpRequestHeaders(\n headers: Record<string, string>,\n): asserts headers is AllowedHttpRequestHeaders {\n const badHeaders = Object.keys(headers).filter(headerName => {\n const lowercaseHeaderName = headerName.toLowerCase();\n return (\n DISALLOWED_HEADERS[headerName.toLowerCase()] === true ||\n FORBIDDEN_HEADERS[headerName.toLowerCase()] === true ||\n lowercaseHeaderName.startsWith('proxy-') ||\n lowercaseHeaderName.startsWith('sec-')\n );\n });\n if (badHeaders.length > 0) {\n throw new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, {\n headers: badHeaders,\n });\n }\n}\n\n/**\n * Lowercasing header names makes it easier to override user-supplied headers, such as those defined\n * in the `DisallowedHeaders` type.\n */\nexport function normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in keyof T & string as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in keyof T & string as Lowercase<K>]: T[K] };\n}\n"]}
@@ -1,23 +1,10 @@
1
+ import { SolanaError, SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN } from '@solana/errors';
2
+
1
3
  // ../build-scripts/env-shim.ts
2
4
  var __DEV__ = /* @__PURE__ */ (() => process["env"].NODE_ENV === "development")();
3
5
 
4
6
  // ../fetch-impl/dist/index.browser.js
5
7
  var e = globalThis.fetch;
6
-
7
- // src/http-transport-errors.ts
8
- var SolanaHttpError = class extends Error {
9
- statusCode;
10
- constructor(details) {
11
- super(`HTTP error (${details.statusCode}): ${details.message}`);
12
- Error.captureStackTrace(this, this.constructor);
13
- this.statusCode = details.statusCode;
14
- }
15
- get name() {
16
- return "SolanaHttpError";
17
- }
18
- };
19
-
20
- // src/http-transport-headers.ts
21
8
  var DISALLOWED_HEADERS = {
22
9
  accept: true,
23
10
  "content-length": true,
@@ -38,9 +25,9 @@ var FORBIDDEN_HEADERS = {
38
25
  "keep-alive": true,
39
26
  origin: true,
40
27
  "permissions-policy": true,
41
- // No currently available Typescript technique allows you to match on a prefix.
42
- // 'proxy-':true,
43
- // 'sec-':true,
28
+ // Prefix matching is implemented in code, below.
29
+ // 'proxy-': true,
30
+ // 'sec-': true,
44
31
  referer: true,
45
32
  te: true,
46
33
  trailer: true,
@@ -54,9 +41,9 @@ function assertIsAllowedHttpRequestHeaders(headers) {
54
41
  return DISALLOWED_HEADERS[headerName.toLowerCase()] === true || FORBIDDEN_HEADERS[headerName.toLowerCase()] === true || lowercaseHeaderName.startsWith("proxy-") || lowercaseHeaderName.startsWith("sec-");
55
42
  });
56
43
  if (badHeaders.length > 0) {
57
- throw new Error(
58
- `${badHeaders.length > 1 ? "These headers are" : "This header is"} forbidden: \`${badHeaders.join("`, `")}\`. Learn more at https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name.`
59
- );
44
+ throw new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, {
45
+ headers: badHeaders
46
+ });
60
47
  }
61
48
  }
62
49
  function normalizeHeaders(headers) {
@@ -68,10 +55,25 @@ function normalizeHeaders(headers) {
68
55
  }
69
56
 
70
57
  // src/http-transport.ts
71
- function createHttpTransport({ headers, url }) {
58
+ var didWarnDispatcherWasSuppliedInNonNodeEnvironment = false;
59
+ function warnDispatcherWasSuppliedInNonNodeEnvironment() {
60
+ if (didWarnDispatcherWasSuppliedInNonNodeEnvironment) {
61
+ return;
62
+ }
63
+ didWarnDispatcherWasSuppliedInNonNodeEnvironment = true;
64
+ console.warn(
65
+ "You have supplied a `Dispatcher` to `createHttpTransport()`. It has been ignored because Undici dispatchers only work in Node environments. To eliminate this warning, omit the `dispatcher_NODE_ONLY` property from your config when running in a non-Node environment."
66
+ );
67
+ }
68
+ function createHttpTransport(config) {
69
+ if (__DEV__ && true && "dispatcher_NODE_ONLY" in config) {
70
+ warnDispatcherWasSuppliedInNonNodeEnvironment();
71
+ }
72
+ const { headers, url } = config;
72
73
  if (__DEV__ && headers) {
73
74
  assertIsAllowedHttpRequestHeaders(headers);
74
75
  }
76
+ let dispatcherConfig;
75
77
  const customHeaders = headers && normalizeHeaders(headers);
76
78
  return async function makeHttpRequest({
77
79
  payload,
@@ -79,6 +81,7 @@ function createHttpTransport({ headers, url }) {
79
81
  }) {
80
82
  const body = JSON.stringify(payload);
81
83
  const requestInfo = {
84
+ ...dispatcherConfig,
82
85
  body,
83
86
  headers: {
84
87
  ...customHeaders,
@@ -92,7 +95,7 @@ function createHttpTransport({ headers, url }) {
92
95
  };
93
96
  const response = await e(url, requestInfo);
94
97
  if (!response.ok) {
95
- throw new SolanaHttpError({
98
+ throw new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, {
96
99
  message: response.statusText,
97
100
  statusCode: response.status
98
101
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../build-scripts/env-shim.ts","../../fetch-impl/src/index.browser.ts","../src/http-transport-errors.ts","../src/http-transport-headers.ts","../src/http-transport.ts"],"names":["index_browser_default"],"mappings":";AACO,IAAM,UAA2B,uBAAO,QAAgB,KAAU,EAAE,aAAa,eAAe;;;ACDvG,IAAOA,IAAQ,WAAW;;;ACKnB,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAC9B;AAAA,EACT,YAAY,SAAiC;AACzC,UAAM,eAAe,QAAQ,UAAU,MAAM,QAAQ,OAAO,EAAE;AAC9D,UAAM,kBAAkB,MAAM,KAAK,WAAW;AAC9C,SAAK,aAAa,QAAQ;AAAA,EAC9B;AAAA,EACA,IAAI,OAAO;AACP,WAAO;AAAA,EACX;AACJ;;;AC2BA,IAAM,qBAA8C;AAAA,EAChD,QAAQ;AAAA,EACR,kBAAkB;AAAA,EAClB,gBAAgB;AACpB;AAEA,IAAM,oBAA6C;AAAA,EAC/C,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,kCAAkC;AAAA,EAClC,iCAAiC;AAAA,EACjC,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,sBAAsB;AAAA;AAAA;AAAA;AAAA,EAItB,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,SAAS;AAAA,EACT,KAAK;AACT;AAEO,SAAS,kCACZ,SAC4C;AAC5C,QAAM,aAAa,OAAO,KAAK,OAAO,EAAE,OAAO,gBAAc;AACzD,UAAM,sBAAsB,WAAW,YAAY;AACnD,WACI,mBAAmB,WAAW,YAAY,CAAC,MAAM,QACjD,kBAAkB,WAAW,YAAY,CAAC,MAAM,QAChD,oBAAoB,WAAW,QAAQ,KACvC,oBAAoB,WAAW,MAAM;AAAA,EAE7C,CAAC;AACD,MAAI,WAAW,SAAS,GAAG;AACvB,UAAM,IAAI;AAAA,MACN,GAAG,WAAW,SAAS,IAAI,sBAAsB,gBAAgB,iBACxD,WAAW,KAAK,MAAM,CAAC;AAAA,IAEpC;AAAA,EACJ;AACJ;AAMO,SAAS,iBACZ,SACiD;AACjD,QAAM,MAA8B,CAAC;AACrC,aAAW,cAAc,SAAS;AAC9B,QAAI,WAAW,YAAY,CAAC,IAAI,QAAQ,UAAU;AAAA,EACtD;AACA,SAAO;AACX;;;AC5FO,SAAS,oBAAoB,EAAE,SAAS,IAAI,GAAyB;AACxE,MAAI,WAAW,SAAS;AACpB,sCAAkC,OAAO;AAAA,EAC7C;AACA,QAAM,gBAAgB,WAAW,iBAAiB,OAAO;AACzD,SAAO,eAAe,gBAA2B;AAAA,IAC7C;AAAA,IACA;AAAA,EACJ,GAAoD;AAChD,UAAM,OAAO,KAAK,UAAU,OAAO;AACnC,UAAM,cAAc;AAAA,MAChB;AAAA,MACA,SAAS;AAAA,QACL,GAAG;AAAA;AAAA,QAEH,QAAQ;AAAA,QACR,kBAAkB,KAAK,OAAO,SAAS;AAAA,QACvC,gBAAgB;AAAA,MACpB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACJ;AACA,UAAM,WAAW,MAAM,EAAU,KAAK,WAAW;AACjD,QAAI,CAAC,SAAS,IAAI;AACd,YAAM,IAAI,gBAAgB;AAAA,QACtB,SAAS,SAAS;AAAA,QAClB,YAAY,SAAS;AAAA,MACzB,CAAC;AAAA,IACL;AACA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAChC;AACJ","sourcesContent":["// Clever obfuscation to prevent the build system from inlining the value of `NODE_ENV`\nexport const __DEV__ = /* @__PURE__ */ (() => (process as any)['en' + 'v'].NODE_ENV === 'development')();\n","export default globalThis.fetch;\n","type SolanaHttpErrorDetails = Readonly<{\n statusCode: number;\n message: string;\n}>;\n\nexport class SolanaHttpError extends Error {\n readonly statusCode: number;\n constructor(details: SolanaHttpErrorDetails) {\n super(`HTTP error (${details.statusCode}): ${details.message}`);\n Error.captureStackTrace(this, this.constructor);\n this.statusCode = details.statusCode;\n }\n get name() {\n return 'SolanaHttpError';\n }\n}\n","export type AllowedHttpRequestHeaders = Readonly<\n { [headerName: string]: string } & {\n // Someone can still sneak a forbidden header past Typescript if they do something like\n // fOo-BaR, but at that point they deserve the runtime failure.\n [K in DisallowedHeaders | ForbiddenHeaders as\n | K // `Foo-Bar`\n | Capitalize<Lowercase<K>> // `Foo-bar`\n | Lowercase<K> // `foo-bar`\n | Uncapitalize<K> // `foo-Bar`\n // `FOO-BAR`\n | Uppercase<K>]?: never;\n }\n>;\n// These are headers that we simply don't allow the developer to override because they're\n// fundamental to the operation of the JSON-RPC transport.\ntype DisallowedHeaders = 'Accept' | 'Content-Length' | 'Content-Type' | 'Solana-Client';\ntype ForbiddenHeaders =\n | 'Accept-Charset'\n | 'Accept-Encoding'\n | 'Access-Control-Request-Headers'\n | 'Access-Control-Request-Method'\n | 'Connection'\n | 'Content-Length'\n | 'Cookie'\n | 'Date'\n | 'DNT'\n | 'Expect'\n | 'Host'\n | 'Keep-Alive'\n | 'Origin'\n | 'Permissions-Policy'\n // No currently available Typescript technique allows you to match on a prefix.\n // | 'Proxy-'\n // | 'Sec-'\n | 'Referer'\n | 'TE'\n | 'Trailer'\n | 'Transfer-Encoding'\n | 'Upgrade'\n | 'Via';\n\n// These are headers which are fundamental to the JSON-RPC transport, and must not be modified.\nconst DISALLOWED_HEADERS: Record<string, boolean> = {\n accept: true,\n 'content-length': true,\n 'content-type': true,\n};\n// https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name\nconst FORBIDDEN_HEADERS: Record<string, boolean> = {\n 'accept-charset': true,\n 'accept-encoding': true,\n 'access-control-request-headers': true,\n 'access-control-request-method': true,\n connection: true,\n 'content-length': true,\n cookie: true,\n date: true,\n dnt: true,\n expect: true,\n host: true,\n 'keep-alive': true,\n origin: true,\n 'permissions-policy': true,\n // No currently available Typescript technique allows you to match on a prefix.\n // 'proxy-':true,\n // 'sec-':true,\n referer: true,\n te: true,\n trailer: true,\n 'transfer-encoding': true,\n upgrade: true,\n via: true,\n};\n\nexport function assertIsAllowedHttpRequestHeaders(\n headers: Record<string, string>,\n): asserts headers is AllowedHttpRequestHeaders {\n const badHeaders = Object.keys(headers).filter(headerName => {\n const lowercaseHeaderName = headerName.toLowerCase();\n return (\n DISALLOWED_HEADERS[headerName.toLowerCase()] === true ||\n FORBIDDEN_HEADERS[headerName.toLowerCase()] === true ||\n lowercaseHeaderName.startsWith('proxy-') ||\n lowercaseHeaderName.startsWith('sec-')\n );\n });\n if (badHeaders.length > 0) {\n throw new Error(\n `${badHeaders.length > 1 ? 'These headers are' : 'This header is'} forbidden: ` +\n `\\`${badHeaders.join('`, `')}\\`. Learn more at ` +\n 'https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name.',\n );\n }\n}\n\n/**\n * Lowercasing header names makes it easier to override user-supplied headers, such as those defined\n * in the `DisallowedHeaders` type.\n */\nexport function normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in keyof T & string as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in keyof T & string as Lowercase<K>]: T[K] };\n}\n","import fetchImpl from '@solana/fetch-impl';\nimport { RpcTransport } from '@solana/rpc-spec';\n\nimport { SolanaHttpError } from './http-transport-errors';\nimport {\n AllowedHttpRequestHeaders,\n assertIsAllowedHttpRequestHeaders,\n normalizeHeaders,\n} from './http-transport-headers';\n\ntype Config = Readonly<{\n headers?: AllowedHttpRequestHeaders;\n url: string;\n}>;\n\nexport function createHttpTransport({ headers, url }: Config): RpcTransport {\n if (__DEV__ && headers) {\n assertIsAllowedHttpRequestHeaders(headers);\n }\n const customHeaders = headers && normalizeHeaders(headers);\n return async function makeHttpRequest<TResponse>({\n payload,\n signal,\n }: Parameters<RpcTransport>[0]): Promise<TResponse> {\n const body = JSON.stringify(payload);\n const requestInfo = {\n body,\n headers: {\n ...customHeaders,\n // Keep these headers lowercase so they will override any user-supplied headers above.\n accept: 'application/json',\n 'content-length': body.length.toString(),\n 'content-type': 'application/json; charset=utf-8',\n },\n method: 'POST',\n signal,\n };\n const response = await fetchImpl(url, requestInfo);\n if (!response.ok) {\n throw new SolanaHttpError({\n message: response.statusText,\n statusCode: response.status,\n });\n }\n return (await response.json()) as TResponse;\n };\n}\n"]}
1
+ {"version":3,"sources":["../../build-scripts/env-shim.ts","../src/http-transport.ts","../../fetch-impl/src/index.browser.ts","../src/http-transport-headers.ts"],"names":["SolanaError","index_browser_default"],"mappings":";AACO,IAAM,UAA2B,uBAAO,QAAgB,KAAU,EAAE,aAAa,eAAe;;;ACDvG,SAAS,yCAAyC,eAAAA,oBAAmB;;;ACArE,IAAOC,IAAQ,WAAW;;;ACA1B,SAAS,oDAAoD,mBAAmB;AA2ChF,IAAM,qBAA8C;AAAA,EAChD,QAAQ;AAAA,EACR,kBAAkB;AAAA,EAClB,gBAAgB;AACpB;AAEA,IAAM,oBAA6C;AAAA,EAC/C,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,kCAAkC;AAAA,EAClC,iCAAiC;AAAA,EACjC,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,sBAAsB;AAAA;AAAA;AAAA;AAAA,EAItB,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,SAAS;AAAA,EACT,KAAK;AACT;AAEO,SAAS,kCACZ,SAC4C;AAC5C,QAAM,aAAa,OAAO,KAAK,OAAO,EAAE,OAAO,gBAAc;AACzD,UAAM,sBAAsB,WAAW,YAAY;AACnD,WACI,mBAAmB,WAAW,YAAY,CAAC,MAAM,QACjD,kBAAkB,WAAW,YAAY,CAAC,MAAM,QAChD,oBAAoB,WAAW,QAAQ,KACvC,oBAAoB,WAAW,MAAM;AAAA,EAE7C,CAAC;AACD,MAAI,WAAW,SAAS,GAAG;AACvB,UAAM,IAAI,YAAY,oDAAoD;AAAA,MACtE,SAAS;AAAA,IACb,CAAC;AAAA,EACL;AACJ;AAMO,SAAS,iBACZ,SACiD;AACjD,QAAM,MAA8B,CAAC;AACrC,aAAW,cAAc,SAAS;AAC9B,QAAI,WAAW,YAAY,CAAC,IAAI,QAAQ,UAAU;AAAA,EACtD;AACA,SAAO;AACX;;;AFzFA,IAAI,mDAAmD;AACvD,SAAS,gDAAgD;AACrD,MAAI,kDAAkD;AAClD;AAAA,EACJ;AACA,qDAAmD;AACnD,UAAQ;AAAA,IACJ;AAAA,EAIJ;AACJ;AAEO,SAAS,oBAAoB,QAA8B;AAC9D,MAAI,WAAW,QAAe,0BAA0B,QAAQ;AAC5D,kDAA8C;AAAA,EAClD;AACA,QAAM,EAAE,SAAS,IAAI,IAAI;AACzB,MAAI,WAAW,SAAS;AACpB,sCAAkC,OAAO;AAAA,EAC7C;AACA,MAAI;AACJ,MAAI,OAAgD;AAChD,uBAAmB,EAAE,YAAY,OAAO,qBAAqB;AAAA,EACjE;AACA,QAAM,gBAAgB,WAAW,iBAAiB,OAAO;AACzD,SAAO,eAAe,gBAA2B;AAAA,IAC7C;AAAA,IACA;AAAA,EACJ,GAAoD;AAChD,UAAM,OAAO,KAAK,UAAU,OAAO;AACnC,UAAM,cAAc;AAAA,MAChB,GAAG;AAAA,MACH;AAAA,MACA,SAAS;AAAA,QACL,GAAG;AAAA;AAAA,QAEH,QAAQ;AAAA,QACR,kBAAkB,KAAK,OAAO,SAAS;AAAA,QACvC,gBAAgB;AAAA,MACpB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACJ;AACA,UAAM,WAAW,MAAM,EAAU,KAAK,WAAW;AACjD,QAAI,CAAC,SAAS,IAAI;AACd,YAAM,IAAID,aAAY,yCAAyC;AAAA,QAC3D,SAAS,SAAS;AAAA,QAClB,YAAY,SAAS;AAAA,MACzB,CAAC;AAAA,IACL;AACA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAChC;AACJ","sourcesContent":["// Clever obfuscation to prevent the build system from inlining the value of `NODE_ENV`\nexport const __DEV__ = /* @__PURE__ */ (() => (process as any)['en' + 'v'].NODE_ENV === 'development')();\n","import { SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, SolanaError } from '@solana/errors';\nimport fetchImpl from '@solana/fetch-impl';\nimport { RpcTransport } from '@solana/rpc-spec';\nimport type Dispatcher from 'undici/types/dispatcher';\n\nimport {\n AllowedHttpRequestHeaders,\n assertIsAllowedHttpRequestHeaders,\n normalizeHeaders,\n} from './http-transport-headers';\n\ntype Config = Readonly<{\n dispatcher_NODE_ONLY?: Dispatcher;\n headers?: AllowedHttpRequestHeaders;\n url: string;\n}>;\n\nlet didWarnDispatcherWasSuppliedInNonNodeEnvironment = false;\nfunction warnDispatcherWasSuppliedInNonNodeEnvironment() {\n if (didWarnDispatcherWasSuppliedInNonNodeEnvironment) {\n return;\n }\n didWarnDispatcherWasSuppliedInNonNodeEnvironment = true;\n console.warn(\n 'You have supplied a `Dispatcher` to `createHttpTransport()`. It has been ignored ' +\n 'because Undici dispatchers only work in Node environments. To eliminate this ' +\n 'warning, omit the `dispatcher_NODE_ONLY` property from your config when running in ' +\n 'a non-Node environment.',\n );\n}\n\nexport function createHttpTransport(config: Config): RpcTransport {\n if (__DEV__ && !__NODEJS__ && 'dispatcher_NODE_ONLY' in config) {\n warnDispatcherWasSuppliedInNonNodeEnvironment();\n }\n const { headers, url } = config;\n if (__DEV__ && headers) {\n assertIsAllowedHttpRequestHeaders(headers);\n }\n let dispatcherConfig: { dispatcher: Dispatcher | undefined } | undefined;\n if (__NODEJS__ && 'dispatcher_NODE_ONLY' in config) {\n dispatcherConfig = { dispatcher: config.dispatcher_NODE_ONLY };\n }\n const customHeaders = headers && normalizeHeaders(headers);\n return async function makeHttpRequest<TResponse>({\n payload,\n signal,\n }: Parameters<RpcTransport>[0]): Promise<TResponse> {\n const body = JSON.stringify(payload);\n const requestInfo = {\n ...dispatcherConfig,\n body,\n headers: {\n ...customHeaders,\n // Keep these headers lowercase so they will override any user-supplied headers above.\n accept: 'application/json',\n 'content-length': body.length.toString(),\n 'content-type': 'application/json; charset=utf-8',\n },\n method: 'POST',\n signal,\n };\n const response = await fetchImpl(url, requestInfo);\n if (!response.ok) {\n throw new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, {\n message: response.statusText,\n statusCode: response.status,\n });\n }\n return (await response.json()) as TResponse;\n };\n}\n","export default globalThis.fetch;\n","import { SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, SolanaError } from '@solana/errors';\n\nexport type AllowedHttpRequestHeaders = Readonly<\n { [headerName: string]: string } & {\n // Someone can still sneak a forbidden header past Typescript if they do something like\n // fOo-BaR, but at that point they deserve the runtime failure.\n [K in DisallowedHeaders | ForbiddenHeaders as\n | K // `Foo-Bar`\n | Capitalize<Lowercase<K>> // `Foo-bar`\n | Lowercase<K> // `foo-bar`\n | Uncapitalize<K> // `foo-Bar`\n // `FOO-BAR`\n | Uppercase<K>]?: never;\n }\n>;\n// These are headers that we simply don't allow the developer to override because they're\n// fundamental to the operation of the JSON-RPC transport.\ntype DisallowedHeaders = 'Accept' | 'Content-Length' | 'Content-Type' | 'Solana-Client';\ntype ForbiddenHeaders =\n | 'Accept-Charset'\n | 'Accept-Encoding'\n | 'Access-Control-Request-Headers'\n | 'Access-Control-Request-Method'\n | 'Connection'\n | 'Content-Length'\n | 'Cookie'\n | 'Date'\n | 'DNT'\n | 'Expect'\n | 'Host'\n | 'Keep-Alive'\n | 'Origin'\n | 'Permissions-Policy'\n | `Proxy-${string}`\n | `Sec-${string}`\n | 'Referer'\n | 'TE'\n | 'Trailer'\n | 'Transfer-Encoding'\n | 'Upgrade'\n | 'Via';\n\n// These are headers which are fundamental to the JSON-RPC transport, and must not be modified.\nconst DISALLOWED_HEADERS: Record<string, boolean> = {\n accept: true,\n 'content-length': true,\n 'content-type': true,\n};\n// https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name\nconst FORBIDDEN_HEADERS: Record<string, boolean> = {\n 'accept-charset': true,\n 'accept-encoding': true,\n 'access-control-request-headers': true,\n 'access-control-request-method': true,\n connection: true,\n 'content-length': true,\n cookie: true,\n date: true,\n dnt: true,\n expect: true,\n host: true,\n 'keep-alive': true,\n origin: true,\n 'permissions-policy': true,\n // Prefix matching is implemented in code, below.\n // 'proxy-': true,\n // 'sec-': true,\n referer: true,\n te: true,\n trailer: true,\n 'transfer-encoding': true,\n upgrade: true,\n via: true,\n};\n\nexport function assertIsAllowedHttpRequestHeaders(\n headers: Record<string, string>,\n): asserts headers is AllowedHttpRequestHeaders {\n const badHeaders = Object.keys(headers).filter(headerName => {\n const lowercaseHeaderName = headerName.toLowerCase();\n return (\n DISALLOWED_HEADERS[headerName.toLowerCase()] === true ||\n FORBIDDEN_HEADERS[headerName.toLowerCase()] === true ||\n lowercaseHeaderName.startsWith('proxy-') ||\n lowercaseHeaderName.startsWith('sec-')\n );\n });\n if (badHeaders.length > 0) {\n throw new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, {\n headers: badHeaders,\n });\n }\n}\n\n/**\n * Lowercasing header names makes it easier to override user-supplied headers, such as those defined\n * in the `DisallowedHeaders` type.\n */\nexport function normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in keyof T & string as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in keyof T & string as Lowercase<K>]: T[K] };\n}\n"]}
@@ -1,23 +1,10 @@
1
+ import { SolanaError, SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN } from '@solana/errors';
2
+
1
3
  // ../build-scripts/env-shim.ts
2
4
  var __DEV__ = /* @__PURE__ */ (() => process["env"].NODE_ENV === "development")();
3
5
 
4
6
  // ../fetch-impl/dist/index.browser.js
5
7
  var e = globalThis.fetch;
6
-
7
- // src/http-transport-errors.ts
8
- var SolanaHttpError = class extends Error {
9
- statusCode;
10
- constructor(details) {
11
- super(`HTTP error (${details.statusCode}): ${details.message}`);
12
- Error.captureStackTrace(this, this.constructor);
13
- this.statusCode = details.statusCode;
14
- }
15
- get name() {
16
- return "SolanaHttpError";
17
- }
18
- };
19
-
20
- // src/http-transport-headers.ts
21
8
  var DISALLOWED_HEADERS = {
22
9
  accept: true,
23
10
  "content-length": true,
@@ -38,9 +25,9 @@ var FORBIDDEN_HEADERS = {
38
25
  "keep-alive": true,
39
26
  origin: true,
40
27
  "permissions-policy": true,
41
- // No currently available Typescript technique allows you to match on a prefix.
42
- // 'proxy-':true,
43
- // 'sec-':true,
28
+ // Prefix matching is implemented in code, below.
29
+ // 'proxy-': true,
30
+ // 'sec-': true,
44
31
  referer: true,
45
32
  te: true,
46
33
  trailer: true,
@@ -54,9 +41,9 @@ function assertIsAllowedHttpRequestHeaders(headers) {
54
41
  return DISALLOWED_HEADERS[headerName.toLowerCase()] === true || FORBIDDEN_HEADERS[headerName.toLowerCase()] === true || lowercaseHeaderName.startsWith("proxy-") || lowercaseHeaderName.startsWith("sec-");
55
42
  });
56
43
  if (badHeaders.length > 0) {
57
- throw new Error(
58
- `${badHeaders.length > 1 ? "These headers are" : "This header is"} forbidden: \`${badHeaders.join("`, `")}\`. Learn more at https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name.`
59
- );
44
+ throw new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, {
45
+ headers: badHeaders
46
+ });
60
47
  }
61
48
  }
62
49
  function normalizeHeaders(headers) {
@@ -68,10 +55,25 @@ function normalizeHeaders(headers) {
68
55
  }
69
56
 
70
57
  // src/http-transport.ts
71
- function createHttpTransport({ headers, url }) {
58
+ var didWarnDispatcherWasSuppliedInNonNodeEnvironment = false;
59
+ function warnDispatcherWasSuppliedInNonNodeEnvironment() {
60
+ if (didWarnDispatcherWasSuppliedInNonNodeEnvironment) {
61
+ return;
62
+ }
63
+ didWarnDispatcherWasSuppliedInNonNodeEnvironment = true;
64
+ console.warn(
65
+ "You have supplied a `Dispatcher` to `createHttpTransport()`. It has been ignored because Undici dispatchers only work in Node environments. To eliminate this warning, omit the `dispatcher_NODE_ONLY` property from your config when running in a non-Node environment."
66
+ );
67
+ }
68
+ function createHttpTransport(config) {
69
+ if (__DEV__ && true && "dispatcher_NODE_ONLY" in config) {
70
+ warnDispatcherWasSuppliedInNonNodeEnvironment();
71
+ }
72
+ const { headers, url } = config;
72
73
  if (__DEV__ && headers) {
73
74
  assertIsAllowedHttpRequestHeaders(headers);
74
75
  }
76
+ let dispatcherConfig;
75
77
  const customHeaders = headers && normalizeHeaders(headers);
76
78
  return async function makeHttpRequest({
77
79
  payload,
@@ -79,6 +81,7 @@ function createHttpTransport({ headers, url }) {
79
81
  }) {
80
82
  const body = JSON.stringify(payload);
81
83
  const requestInfo = {
84
+ ...dispatcherConfig,
82
85
  body,
83
86
  headers: {
84
87
  ...customHeaders,
@@ -92,7 +95,7 @@ function createHttpTransport({ headers, url }) {
92
95
  };
93
96
  const response = await e(url, requestInfo);
94
97
  if (!response.ok) {
95
- throw new SolanaHttpError({
98
+ throw new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, {
96
99
  message: response.statusText,
97
100
  statusCode: response.status
98
101
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../build-scripts/env-shim.ts","../../fetch-impl/src/index.browser.ts","../src/http-transport-errors.ts","../src/http-transport-headers.ts","../src/http-transport.ts"],"names":["index_browser_default"],"mappings":";AACO,IAAM,UAA2B,uBAAO,QAAgB,KAAU,EAAE,aAAa,eAAe;;;ACDvG,IAAOA,IAAQ,WAAW;;;ACKnB,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAC9B;AAAA,EACT,YAAY,SAAiC;AACzC,UAAM,eAAe,QAAQ,UAAU,MAAM,QAAQ,OAAO,EAAE;AAC9D,UAAM,kBAAkB,MAAM,KAAK,WAAW;AAC9C,SAAK,aAAa,QAAQ;AAAA,EAC9B;AAAA,EACA,IAAI,OAAO;AACP,WAAO;AAAA,EACX;AACJ;;;AC2BA,IAAM,qBAA8C;AAAA,EAChD,QAAQ;AAAA,EACR,kBAAkB;AAAA,EAClB,gBAAgB;AACpB;AAEA,IAAM,oBAA6C;AAAA,EAC/C,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,kCAAkC;AAAA,EAClC,iCAAiC;AAAA,EACjC,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,sBAAsB;AAAA;AAAA;AAAA;AAAA,EAItB,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,SAAS;AAAA,EACT,KAAK;AACT;AAEO,SAAS,kCACZ,SAC4C;AAC5C,QAAM,aAAa,OAAO,KAAK,OAAO,EAAE,OAAO,gBAAc;AACzD,UAAM,sBAAsB,WAAW,YAAY;AACnD,WACI,mBAAmB,WAAW,YAAY,CAAC,MAAM,QACjD,kBAAkB,WAAW,YAAY,CAAC,MAAM,QAChD,oBAAoB,WAAW,QAAQ,KACvC,oBAAoB,WAAW,MAAM;AAAA,EAE7C,CAAC;AACD,MAAI,WAAW,SAAS,GAAG;AACvB,UAAM,IAAI;AAAA,MACN,GAAG,WAAW,SAAS,IAAI,sBAAsB,gBAAgB,iBACxD,WAAW,KAAK,MAAM,CAAC;AAAA,IAEpC;AAAA,EACJ;AACJ;AAMO,SAAS,iBACZ,SACiD;AACjD,QAAM,MAA8B,CAAC;AACrC,aAAW,cAAc,SAAS;AAC9B,QAAI,WAAW,YAAY,CAAC,IAAI,QAAQ,UAAU;AAAA,EACtD;AACA,SAAO;AACX;;;AC5FO,SAAS,oBAAoB,EAAE,SAAS,IAAI,GAAyB;AACxE,MAAI,WAAW,SAAS;AACpB,sCAAkC,OAAO;AAAA,EAC7C;AACA,QAAM,gBAAgB,WAAW,iBAAiB,OAAO;AACzD,SAAO,eAAe,gBAA2B;AAAA,IAC7C;AAAA,IACA;AAAA,EACJ,GAAoD;AAChD,UAAM,OAAO,KAAK,UAAU,OAAO;AACnC,UAAM,cAAc;AAAA,MAChB;AAAA,MACA,SAAS;AAAA,QACL,GAAG;AAAA;AAAA,QAEH,QAAQ;AAAA,QACR,kBAAkB,KAAK,OAAO,SAAS;AAAA,QACvC,gBAAgB;AAAA,MACpB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACJ;AACA,UAAM,WAAW,MAAM,EAAU,KAAK,WAAW;AACjD,QAAI,CAAC,SAAS,IAAI;AACd,YAAM,IAAI,gBAAgB;AAAA,QACtB,SAAS,SAAS;AAAA,QAClB,YAAY,SAAS;AAAA,MACzB,CAAC;AAAA,IACL;AACA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAChC;AACJ","sourcesContent":["// Clever obfuscation to prevent the build system from inlining the value of `NODE_ENV`\nexport const __DEV__ = /* @__PURE__ */ (() => (process as any)['en' + 'v'].NODE_ENV === 'development')();\n","export default globalThis.fetch;\n","type SolanaHttpErrorDetails = Readonly<{\n statusCode: number;\n message: string;\n}>;\n\nexport class SolanaHttpError extends Error {\n readonly statusCode: number;\n constructor(details: SolanaHttpErrorDetails) {\n super(`HTTP error (${details.statusCode}): ${details.message}`);\n Error.captureStackTrace(this, this.constructor);\n this.statusCode = details.statusCode;\n }\n get name() {\n return 'SolanaHttpError';\n }\n}\n","export type AllowedHttpRequestHeaders = Readonly<\n { [headerName: string]: string } & {\n // Someone can still sneak a forbidden header past Typescript if they do something like\n // fOo-BaR, but at that point they deserve the runtime failure.\n [K in DisallowedHeaders | ForbiddenHeaders as\n | K // `Foo-Bar`\n | Capitalize<Lowercase<K>> // `Foo-bar`\n | Lowercase<K> // `foo-bar`\n | Uncapitalize<K> // `foo-Bar`\n // `FOO-BAR`\n | Uppercase<K>]?: never;\n }\n>;\n// These are headers that we simply don't allow the developer to override because they're\n// fundamental to the operation of the JSON-RPC transport.\ntype DisallowedHeaders = 'Accept' | 'Content-Length' | 'Content-Type' | 'Solana-Client';\ntype ForbiddenHeaders =\n | 'Accept-Charset'\n | 'Accept-Encoding'\n | 'Access-Control-Request-Headers'\n | 'Access-Control-Request-Method'\n | 'Connection'\n | 'Content-Length'\n | 'Cookie'\n | 'Date'\n | 'DNT'\n | 'Expect'\n | 'Host'\n | 'Keep-Alive'\n | 'Origin'\n | 'Permissions-Policy'\n // No currently available Typescript technique allows you to match on a prefix.\n // | 'Proxy-'\n // | 'Sec-'\n | 'Referer'\n | 'TE'\n | 'Trailer'\n | 'Transfer-Encoding'\n | 'Upgrade'\n | 'Via';\n\n// These are headers which are fundamental to the JSON-RPC transport, and must not be modified.\nconst DISALLOWED_HEADERS: Record<string, boolean> = {\n accept: true,\n 'content-length': true,\n 'content-type': true,\n};\n// https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name\nconst FORBIDDEN_HEADERS: Record<string, boolean> = {\n 'accept-charset': true,\n 'accept-encoding': true,\n 'access-control-request-headers': true,\n 'access-control-request-method': true,\n connection: true,\n 'content-length': true,\n cookie: true,\n date: true,\n dnt: true,\n expect: true,\n host: true,\n 'keep-alive': true,\n origin: true,\n 'permissions-policy': true,\n // No currently available Typescript technique allows you to match on a prefix.\n // 'proxy-':true,\n // 'sec-':true,\n referer: true,\n te: true,\n trailer: true,\n 'transfer-encoding': true,\n upgrade: true,\n via: true,\n};\n\nexport function assertIsAllowedHttpRequestHeaders(\n headers: Record<string, string>,\n): asserts headers is AllowedHttpRequestHeaders {\n const badHeaders = Object.keys(headers).filter(headerName => {\n const lowercaseHeaderName = headerName.toLowerCase();\n return (\n DISALLOWED_HEADERS[headerName.toLowerCase()] === true ||\n FORBIDDEN_HEADERS[headerName.toLowerCase()] === true ||\n lowercaseHeaderName.startsWith('proxy-') ||\n lowercaseHeaderName.startsWith('sec-')\n );\n });\n if (badHeaders.length > 0) {\n throw new Error(\n `${badHeaders.length > 1 ? 'These headers are' : 'This header is'} forbidden: ` +\n `\\`${badHeaders.join('`, `')}\\`. Learn more at ` +\n 'https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name.',\n );\n }\n}\n\n/**\n * Lowercasing header names makes it easier to override user-supplied headers, such as those defined\n * in the `DisallowedHeaders` type.\n */\nexport function normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in keyof T & string as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in keyof T & string as Lowercase<K>]: T[K] };\n}\n","import fetchImpl from '@solana/fetch-impl';\nimport { RpcTransport } from '@solana/rpc-spec';\n\nimport { SolanaHttpError } from './http-transport-errors';\nimport {\n AllowedHttpRequestHeaders,\n assertIsAllowedHttpRequestHeaders,\n normalizeHeaders,\n} from './http-transport-headers';\n\ntype Config = Readonly<{\n headers?: AllowedHttpRequestHeaders;\n url: string;\n}>;\n\nexport function createHttpTransport({ headers, url }: Config): RpcTransport {\n if (__DEV__ && headers) {\n assertIsAllowedHttpRequestHeaders(headers);\n }\n const customHeaders = headers && normalizeHeaders(headers);\n return async function makeHttpRequest<TResponse>({\n payload,\n signal,\n }: Parameters<RpcTransport>[0]): Promise<TResponse> {\n const body = JSON.stringify(payload);\n const requestInfo = {\n body,\n headers: {\n ...customHeaders,\n // Keep these headers lowercase so they will override any user-supplied headers above.\n accept: 'application/json',\n 'content-length': body.length.toString(),\n 'content-type': 'application/json; charset=utf-8',\n },\n method: 'POST',\n signal,\n };\n const response = await fetchImpl(url, requestInfo);\n if (!response.ok) {\n throw new SolanaHttpError({\n message: response.statusText,\n statusCode: response.status,\n });\n }\n return (await response.json()) as TResponse;\n };\n}\n"]}
1
+ {"version":3,"sources":["../../build-scripts/env-shim.ts","../src/http-transport.ts","../../fetch-impl/src/index.browser.ts","../src/http-transport-headers.ts"],"names":["SolanaError","index_browser_default"],"mappings":";AACO,IAAM,UAA2B,uBAAO,QAAgB,KAAU,EAAE,aAAa,eAAe;;;ACDvG,SAAS,yCAAyC,eAAAA,oBAAmB;;;ACArE,IAAOC,IAAQ,WAAW;;;ACA1B,SAAS,oDAAoD,mBAAmB;AA2ChF,IAAM,qBAA8C;AAAA,EAChD,QAAQ;AAAA,EACR,kBAAkB;AAAA,EAClB,gBAAgB;AACpB;AAEA,IAAM,oBAA6C;AAAA,EAC/C,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,kCAAkC;AAAA,EAClC,iCAAiC;AAAA,EACjC,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,sBAAsB;AAAA;AAAA;AAAA;AAAA,EAItB,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,SAAS;AAAA,EACT,KAAK;AACT;AAEO,SAAS,kCACZ,SAC4C;AAC5C,QAAM,aAAa,OAAO,KAAK,OAAO,EAAE,OAAO,gBAAc;AACzD,UAAM,sBAAsB,WAAW,YAAY;AACnD,WACI,mBAAmB,WAAW,YAAY,CAAC,MAAM,QACjD,kBAAkB,WAAW,YAAY,CAAC,MAAM,QAChD,oBAAoB,WAAW,QAAQ,KACvC,oBAAoB,WAAW,MAAM;AAAA,EAE7C,CAAC;AACD,MAAI,WAAW,SAAS,GAAG;AACvB,UAAM,IAAI,YAAY,oDAAoD;AAAA,MACtE,SAAS;AAAA,IACb,CAAC;AAAA,EACL;AACJ;AAMO,SAAS,iBACZ,SACiD;AACjD,QAAM,MAA8B,CAAC;AACrC,aAAW,cAAc,SAAS;AAC9B,QAAI,WAAW,YAAY,CAAC,IAAI,QAAQ,UAAU;AAAA,EACtD;AACA,SAAO;AACX;;;AFzFA,IAAI,mDAAmD;AACvD,SAAS,gDAAgD;AACrD,MAAI,kDAAkD;AAClD;AAAA,EACJ;AACA,qDAAmD;AACnD,UAAQ;AAAA,IACJ;AAAA,EAIJ;AACJ;AAEO,SAAS,oBAAoB,QAA8B;AAC9D,MAAI,WAAW,QAAe,0BAA0B,QAAQ;AAC5D,kDAA8C;AAAA,EAClD;AACA,QAAM,EAAE,SAAS,IAAI,IAAI;AACzB,MAAI,WAAW,SAAS;AACpB,sCAAkC,OAAO;AAAA,EAC7C;AACA,MAAI;AACJ,MAAI,OAAgD;AAChD,uBAAmB,EAAE,YAAY,OAAO,qBAAqB;AAAA,EACjE;AACA,QAAM,gBAAgB,WAAW,iBAAiB,OAAO;AACzD,SAAO,eAAe,gBAA2B;AAAA,IAC7C;AAAA,IACA;AAAA,EACJ,GAAoD;AAChD,UAAM,OAAO,KAAK,UAAU,OAAO;AACnC,UAAM,cAAc;AAAA,MAChB,GAAG;AAAA,MACH;AAAA,MACA,SAAS;AAAA,QACL,GAAG;AAAA;AAAA,QAEH,QAAQ;AAAA,QACR,kBAAkB,KAAK,OAAO,SAAS;AAAA,QACvC,gBAAgB;AAAA,MACpB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACJ;AACA,UAAM,WAAW,MAAM,EAAU,KAAK,WAAW;AACjD,QAAI,CAAC,SAAS,IAAI;AACd,YAAM,IAAID,aAAY,yCAAyC;AAAA,QAC3D,SAAS,SAAS;AAAA,QAClB,YAAY,SAAS;AAAA,MACzB,CAAC;AAAA,IACL;AACA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAChC;AACJ","sourcesContent":["// Clever obfuscation to prevent the build system from inlining the value of `NODE_ENV`\nexport const __DEV__ = /* @__PURE__ */ (() => (process as any)['en' + 'v'].NODE_ENV === 'development')();\n","import { SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, SolanaError } from '@solana/errors';\nimport fetchImpl from '@solana/fetch-impl';\nimport { RpcTransport } from '@solana/rpc-spec';\nimport type Dispatcher from 'undici/types/dispatcher';\n\nimport {\n AllowedHttpRequestHeaders,\n assertIsAllowedHttpRequestHeaders,\n normalizeHeaders,\n} from './http-transport-headers';\n\ntype Config = Readonly<{\n dispatcher_NODE_ONLY?: Dispatcher;\n headers?: AllowedHttpRequestHeaders;\n url: string;\n}>;\n\nlet didWarnDispatcherWasSuppliedInNonNodeEnvironment = false;\nfunction warnDispatcherWasSuppliedInNonNodeEnvironment() {\n if (didWarnDispatcherWasSuppliedInNonNodeEnvironment) {\n return;\n }\n didWarnDispatcherWasSuppliedInNonNodeEnvironment = true;\n console.warn(\n 'You have supplied a `Dispatcher` to `createHttpTransport()`. It has been ignored ' +\n 'because Undici dispatchers only work in Node environments. To eliminate this ' +\n 'warning, omit the `dispatcher_NODE_ONLY` property from your config when running in ' +\n 'a non-Node environment.',\n );\n}\n\nexport function createHttpTransport(config: Config): RpcTransport {\n if (__DEV__ && !__NODEJS__ && 'dispatcher_NODE_ONLY' in config) {\n warnDispatcherWasSuppliedInNonNodeEnvironment();\n }\n const { headers, url } = config;\n if (__DEV__ && headers) {\n assertIsAllowedHttpRequestHeaders(headers);\n }\n let dispatcherConfig: { dispatcher: Dispatcher | undefined } | undefined;\n if (__NODEJS__ && 'dispatcher_NODE_ONLY' in config) {\n dispatcherConfig = { dispatcher: config.dispatcher_NODE_ONLY };\n }\n const customHeaders = headers && normalizeHeaders(headers);\n return async function makeHttpRequest<TResponse>({\n payload,\n signal,\n }: Parameters<RpcTransport>[0]): Promise<TResponse> {\n const body = JSON.stringify(payload);\n const requestInfo = {\n ...dispatcherConfig,\n body,\n headers: {\n ...customHeaders,\n // Keep these headers lowercase so they will override any user-supplied headers above.\n accept: 'application/json',\n 'content-length': body.length.toString(),\n 'content-type': 'application/json; charset=utf-8',\n },\n method: 'POST',\n signal,\n };\n const response = await fetchImpl(url, requestInfo);\n if (!response.ok) {\n throw new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, {\n message: response.statusText,\n statusCode: response.status,\n });\n }\n return (await response.json()) as TResponse;\n };\n}\n","export default globalThis.fetch;\n","import { SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, SolanaError } from '@solana/errors';\n\nexport type AllowedHttpRequestHeaders = Readonly<\n { [headerName: string]: string } & {\n // Someone can still sneak a forbidden header past Typescript if they do something like\n // fOo-BaR, but at that point they deserve the runtime failure.\n [K in DisallowedHeaders | ForbiddenHeaders as\n | K // `Foo-Bar`\n | Capitalize<Lowercase<K>> // `Foo-bar`\n | Lowercase<K> // `foo-bar`\n | Uncapitalize<K> // `foo-Bar`\n // `FOO-BAR`\n | Uppercase<K>]?: never;\n }\n>;\n// These are headers that we simply don't allow the developer to override because they're\n// fundamental to the operation of the JSON-RPC transport.\ntype DisallowedHeaders = 'Accept' | 'Content-Length' | 'Content-Type' | 'Solana-Client';\ntype ForbiddenHeaders =\n | 'Accept-Charset'\n | 'Accept-Encoding'\n | 'Access-Control-Request-Headers'\n | 'Access-Control-Request-Method'\n | 'Connection'\n | 'Content-Length'\n | 'Cookie'\n | 'Date'\n | 'DNT'\n | 'Expect'\n | 'Host'\n | 'Keep-Alive'\n | 'Origin'\n | 'Permissions-Policy'\n | `Proxy-${string}`\n | `Sec-${string}`\n | 'Referer'\n | 'TE'\n | 'Trailer'\n | 'Transfer-Encoding'\n | 'Upgrade'\n | 'Via';\n\n// These are headers which are fundamental to the JSON-RPC transport, and must not be modified.\nconst DISALLOWED_HEADERS: Record<string, boolean> = {\n accept: true,\n 'content-length': true,\n 'content-type': true,\n};\n// https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name\nconst FORBIDDEN_HEADERS: Record<string, boolean> = {\n 'accept-charset': true,\n 'accept-encoding': true,\n 'access-control-request-headers': true,\n 'access-control-request-method': true,\n connection: true,\n 'content-length': true,\n cookie: true,\n date: true,\n dnt: true,\n expect: true,\n host: true,\n 'keep-alive': true,\n origin: true,\n 'permissions-policy': true,\n // Prefix matching is implemented in code, below.\n // 'proxy-': true,\n // 'sec-': true,\n referer: true,\n te: true,\n trailer: true,\n 'transfer-encoding': true,\n upgrade: true,\n via: true,\n};\n\nexport function assertIsAllowedHttpRequestHeaders(\n headers: Record<string, string>,\n): asserts headers is AllowedHttpRequestHeaders {\n const badHeaders = Object.keys(headers).filter(headerName => {\n const lowercaseHeaderName = headerName.toLowerCase();\n return (\n DISALLOWED_HEADERS[headerName.toLowerCase()] === true ||\n FORBIDDEN_HEADERS[headerName.toLowerCase()] === true ||\n lowercaseHeaderName.startsWith('proxy-') ||\n lowercaseHeaderName.startsWith('sec-')\n );\n });\n if (badHeaders.length > 0) {\n throw new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, {\n headers: badHeaders,\n });\n }\n}\n\n/**\n * Lowercasing header names makes it easier to override user-supplied headers, such as those defined\n * in the `DisallowedHeaders` type.\n */\nexport function normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in keyof T & string as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in keyof T & string as Lowercase<K>]: T[K] };\n}\n"]}
@@ -1,25 +1,10 @@
1
1
  'use strict';
2
2
 
3
+ var errors = require('@solana/errors');
4
+ var undici = require('undici');
5
+
3
6
  // ../build-scripts/env-shim.ts
4
7
  var __DEV__ = /* @__PURE__ */ (() => process["env"].NODE_ENV === "development")();
5
-
6
- // ../fetch-impl/dist/index.node.js
7
- var e = globalThis.fetch;
8
-
9
- // src/http-transport-errors.ts
10
- var SolanaHttpError = class extends Error {
11
- statusCode;
12
- constructor(details) {
13
- super(`HTTP error (${details.statusCode}): ${details.message}`);
14
- Error.captureStackTrace(this, this.constructor);
15
- this.statusCode = details.statusCode;
16
- }
17
- get name() {
18
- return "SolanaHttpError";
19
- }
20
- };
21
-
22
- // src/http-transport-headers.ts
23
8
  var DISALLOWED_HEADERS = {
24
9
  accept: true,
25
10
  "content-length": true,
@@ -40,9 +25,9 @@ var FORBIDDEN_HEADERS = {
40
25
  "keep-alive": true,
41
26
  origin: true,
42
27
  "permissions-policy": true,
43
- // No currently available Typescript technique allows you to match on a prefix.
44
- // 'proxy-':true,
45
- // 'sec-':true,
28
+ // Prefix matching is implemented in code, below.
29
+ // 'proxy-': true,
30
+ // 'sec-': true,
46
31
  referer: true,
47
32
  te: true,
48
33
  trailer: true,
@@ -56,9 +41,9 @@ function assertIsAllowedHttpRequestHeaders(headers) {
56
41
  return DISALLOWED_HEADERS[headerName.toLowerCase()] === true || FORBIDDEN_HEADERS[headerName.toLowerCase()] === true || lowercaseHeaderName.startsWith("proxy-") || lowercaseHeaderName.startsWith("sec-");
57
42
  });
58
43
  if (badHeaders.length > 0) {
59
- throw new Error(
60
- `${badHeaders.length > 1 ? "These headers are" : "This header is"} forbidden: \`${badHeaders.join("`, `")}\`. Learn more at https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name.`
61
- );
44
+ throw new errors.SolanaError(errors.SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, {
45
+ headers: badHeaders
46
+ });
62
47
  }
63
48
  }
64
49
  function normalizeHeaders(headers) {
@@ -70,10 +55,18 @@ function normalizeHeaders(headers) {
70
55
  }
71
56
 
72
57
  // src/http-transport.ts
73
- function createHttpTransport({ headers, url }) {
58
+ function createHttpTransport(config) {
59
+ if (__DEV__ && false) {
60
+ warnDispatcherWasSuppliedInNonNodeEnvironment();
61
+ }
62
+ const { headers, url } = config;
74
63
  if (__DEV__ && headers) {
75
64
  assertIsAllowedHttpRequestHeaders(headers);
76
65
  }
66
+ let dispatcherConfig;
67
+ if ("dispatcher_NODE_ONLY" in config) {
68
+ dispatcherConfig = { dispatcher: config.dispatcher_NODE_ONLY };
69
+ }
77
70
  const customHeaders = headers && normalizeHeaders(headers);
78
71
  return async function makeHttpRequest({
79
72
  payload,
@@ -81,6 +74,7 @@ function createHttpTransport({ headers, url }) {
81
74
  }) {
82
75
  const body = JSON.stringify(payload);
83
76
  const requestInfo = {
77
+ ...dispatcherConfig,
84
78
  body,
85
79
  headers: {
86
80
  ...customHeaders,
@@ -92,9 +86,9 @@ function createHttpTransport({ headers, url }) {
92
86
  method: "POST",
93
87
  signal
94
88
  };
95
- const response = await e(url, requestInfo);
89
+ const response = await undici.fetch(url, requestInfo);
96
90
  if (!response.ok) {
97
- throw new SolanaHttpError({
91
+ throw new errors.SolanaError(errors.SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, {
98
92
  message: response.statusText,
99
93
  statusCode: response.status
100
94
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../build-scripts/env-shim.ts","../../fetch-impl/src/index.node.ts","../src/http-transport-errors.ts","../src/http-transport-headers.ts","../src/http-transport.ts"],"names":["index_node_default"],"mappings":";AACO,IAAM,UAA2B,uBAAO,QAAgB,KAAU,EAAE,aAAa,eAAe;;;ACAvG,IAAOA,IAAQ,WAAW;;;ACInB,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAC9B;AAAA,EACT,YAAY,SAAiC;AACzC,UAAM,eAAe,QAAQ,UAAU,MAAM,QAAQ,OAAO,EAAE;AAC9D,UAAM,kBAAkB,MAAM,KAAK,WAAW;AAC9C,SAAK,aAAa,QAAQ;AAAA,EAC9B;AAAA,EACA,IAAI,OAAO;AACP,WAAO;AAAA,EACX;AACJ;;;AC2BA,IAAM,qBAA8C;AAAA,EAChD,QAAQ;AAAA,EACR,kBAAkB;AAAA,EAClB,gBAAgB;AACpB;AAEA,IAAM,oBAA6C;AAAA,EAC/C,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,kCAAkC;AAAA,EAClC,iCAAiC;AAAA,EACjC,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,sBAAsB;AAAA;AAAA;AAAA;AAAA,EAItB,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,SAAS;AAAA,EACT,KAAK;AACT;AAEO,SAAS,kCACZ,SAC4C;AAC5C,QAAM,aAAa,OAAO,KAAK,OAAO,EAAE,OAAO,gBAAc;AACzD,UAAM,sBAAsB,WAAW,YAAY;AACnD,WACI,mBAAmB,WAAW,YAAY,CAAC,MAAM,QACjD,kBAAkB,WAAW,YAAY,CAAC,MAAM,QAChD,oBAAoB,WAAW,QAAQ,KACvC,oBAAoB,WAAW,MAAM;AAAA,EAE7C,CAAC;AACD,MAAI,WAAW,SAAS,GAAG;AACvB,UAAM,IAAI;AAAA,MACN,GAAG,WAAW,SAAS,IAAI,sBAAsB,gBAAgB,iBACxD,WAAW,KAAK,MAAM,CAAC;AAAA,IAEpC;AAAA,EACJ;AACJ;AAMO,SAAS,iBACZ,SACiD;AACjD,QAAM,MAA8B,CAAC;AACrC,aAAW,cAAc,SAAS;AAC9B,QAAI,WAAW,YAAY,CAAC,IAAI,QAAQ,UAAU;AAAA,EACtD;AACA,SAAO;AACX;;;AC5FO,SAAS,oBAAoB,EAAE,SAAS,IAAI,GAAyB;AACxE,MAAI,WAAW,SAAS;AACpB,sCAAkC,OAAO;AAAA,EAC7C;AACA,QAAM,gBAAgB,WAAW,iBAAiB,OAAO;AACzD,SAAO,eAAe,gBAA2B;AAAA,IAC7C;AAAA,IACA;AAAA,EACJ,GAAoD;AAChD,UAAM,OAAO,KAAK,UAAU,OAAO;AACnC,UAAM,cAAc;AAAA,MAChB;AAAA,MACA,SAAS;AAAA,QACL,GAAG;AAAA;AAAA,QAEH,QAAQ;AAAA,QACR,kBAAkB,KAAK,OAAO,SAAS;AAAA,QACvC,gBAAgB;AAAA,MACpB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACJ;AACA,UAAM,WAAW,MAAM,EAAU,KAAK,WAAW;AACjD,QAAI,CAAC,SAAS,IAAI;AACd,YAAM,IAAI,gBAAgB;AAAA,QACtB,SAAS,SAAS;AAAA,QAClB,YAAY,SAAS;AAAA,MACzB,CAAC;AAAA,IACL;AACA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAChC;AACJ","sourcesContent":["// Clever obfuscation to prevent the build system from inlining the value of `NODE_ENV`\nexport const __DEV__ = /* @__PURE__ */ (() => (process as any)['en' + 'v'].NODE_ENV === 'development')();\n","// TODO(https://github.com/solana-labs/solana-web3.js/issues/1787) Write HTTP/2 implementation.\nexport default globalThis.fetch; // The Fetch API is supported natively in Node 18+.\n","type SolanaHttpErrorDetails = Readonly<{\n statusCode: number;\n message: string;\n}>;\n\nexport class SolanaHttpError extends Error {\n readonly statusCode: number;\n constructor(details: SolanaHttpErrorDetails) {\n super(`HTTP error (${details.statusCode}): ${details.message}`);\n Error.captureStackTrace(this, this.constructor);\n this.statusCode = details.statusCode;\n }\n get name() {\n return 'SolanaHttpError';\n }\n}\n","export type AllowedHttpRequestHeaders = Readonly<\n { [headerName: string]: string } & {\n // Someone can still sneak a forbidden header past Typescript if they do something like\n // fOo-BaR, but at that point they deserve the runtime failure.\n [K in DisallowedHeaders | ForbiddenHeaders as\n | K // `Foo-Bar`\n | Capitalize<Lowercase<K>> // `Foo-bar`\n | Lowercase<K> // `foo-bar`\n | Uncapitalize<K> // `foo-Bar`\n // `FOO-BAR`\n | Uppercase<K>]?: never;\n }\n>;\n// These are headers that we simply don't allow the developer to override because they're\n// fundamental to the operation of the JSON-RPC transport.\ntype DisallowedHeaders = 'Accept' | 'Content-Length' | 'Content-Type' | 'Solana-Client';\ntype ForbiddenHeaders =\n | 'Accept-Charset'\n | 'Accept-Encoding'\n | 'Access-Control-Request-Headers'\n | 'Access-Control-Request-Method'\n | 'Connection'\n | 'Content-Length'\n | 'Cookie'\n | 'Date'\n | 'DNT'\n | 'Expect'\n | 'Host'\n | 'Keep-Alive'\n | 'Origin'\n | 'Permissions-Policy'\n // No currently available Typescript technique allows you to match on a prefix.\n // | 'Proxy-'\n // | 'Sec-'\n | 'Referer'\n | 'TE'\n | 'Trailer'\n | 'Transfer-Encoding'\n | 'Upgrade'\n | 'Via';\n\n// These are headers which are fundamental to the JSON-RPC transport, and must not be modified.\nconst DISALLOWED_HEADERS: Record<string, boolean> = {\n accept: true,\n 'content-length': true,\n 'content-type': true,\n};\n// https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name\nconst FORBIDDEN_HEADERS: Record<string, boolean> = {\n 'accept-charset': true,\n 'accept-encoding': true,\n 'access-control-request-headers': true,\n 'access-control-request-method': true,\n connection: true,\n 'content-length': true,\n cookie: true,\n date: true,\n dnt: true,\n expect: true,\n host: true,\n 'keep-alive': true,\n origin: true,\n 'permissions-policy': true,\n // No currently available Typescript technique allows you to match on a prefix.\n // 'proxy-':true,\n // 'sec-':true,\n referer: true,\n te: true,\n trailer: true,\n 'transfer-encoding': true,\n upgrade: true,\n via: true,\n};\n\nexport function assertIsAllowedHttpRequestHeaders(\n headers: Record<string, string>,\n): asserts headers is AllowedHttpRequestHeaders {\n const badHeaders = Object.keys(headers).filter(headerName => {\n const lowercaseHeaderName = headerName.toLowerCase();\n return (\n DISALLOWED_HEADERS[headerName.toLowerCase()] === true ||\n FORBIDDEN_HEADERS[headerName.toLowerCase()] === true ||\n lowercaseHeaderName.startsWith('proxy-') ||\n lowercaseHeaderName.startsWith('sec-')\n );\n });\n if (badHeaders.length > 0) {\n throw new Error(\n `${badHeaders.length > 1 ? 'These headers are' : 'This header is'} forbidden: ` +\n `\\`${badHeaders.join('`, `')}\\`. Learn more at ` +\n 'https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name.',\n );\n }\n}\n\n/**\n * Lowercasing header names makes it easier to override user-supplied headers, such as those defined\n * in the `DisallowedHeaders` type.\n */\nexport function normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in keyof T & string as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in keyof T & string as Lowercase<K>]: T[K] };\n}\n","import fetchImpl from '@solana/fetch-impl';\nimport { RpcTransport } from '@solana/rpc-spec';\n\nimport { SolanaHttpError } from './http-transport-errors';\nimport {\n AllowedHttpRequestHeaders,\n assertIsAllowedHttpRequestHeaders,\n normalizeHeaders,\n} from './http-transport-headers';\n\ntype Config = Readonly<{\n headers?: AllowedHttpRequestHeaders;\n url: string;\n}>;\n\nexport function createHttpTransport({ headers, url }: Config): RpcTransport {\n if (__DEV__ && headers) {\n assertIsAllowedHttpRequestHeaders(headers);\n }\n const customHeaders = headers && normalizeHeaders(headers);\n return async function makeHttpRequest<TResponse>({\n payload,\n signal,\n }: Parameters<RpcTransport>[0]): Promise<TResponse> {\n const body = JSON.stringify(payload);\n const requestInfo = {\n body,\n headers: {\n ...customHeaders,\n // Keep these headers lowercase so they will override any user-supplied headers above.\n accept: 'application/json',\n 'content-length': body.length.toString(),\n 'content-type': 'application/json; charset=utf-8',\n },\n method: 'POST',\n signal,\n };\n const response = await fetchImpl(url, requestInfo);\n if (!response.ok) {\n throw new SolanaHttpError({\n message: response.statusText,\n statusCode: response.status,\n });\n }\n return (await response.json()) as TResponse;\n };\n}\n"]}
1
+ {"version":3,"sources":["../../build-scripts/env-shim.ts","../src/http-transport.ts","../../fetch-impl/src/index.node.ts","../src/http-transport-headers.ts"],"names":["SolanaError","fetch"],"mappings":";AACO,IAAM,UAA2B,uBAAO,QAAgB,KAAU,EAAE,aAAa,eAAe;;;ACDvG,SAAS,yCAAyC,eAAAA,oBAAmB;;;ACArE,SAASC,aAAwB;;;ACAjC,SAAS,oDAAoD,mBAAmB;AA2ChF,IAAM,qBAA8C;AAAA,EAChD,QAAQ;AAAA,EACR,kBAAkB;AAAA,EAClB,gBAAgB;AACpB;AAEA,IAAM,oBAA6C;AAAA,EAC/C,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,kCAAkC;AAAA,EAClC,iCAAiC;AAAA,EACjC,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,sBAAsB;AAAA;AAAA;AAAA;AAAA,EAItB,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,SAAS;AAAA,EACT,KAAK;AACT;AAEO,SAAS,kCACZ,SAC4C;AAC5C,QAAM,aAAa,OAAO,KAAK,OAAO,EAAE,OAAO,gBAAc;AACzD,UAAM,sBAAsB,WAAW,YAAY;AACnD,WACI,mBAAmB,WAAW,YAAY,CAAC,MAAM,QACjD,kBAAkB,WAAW,YAAY,CAAC,MAAM,QAChD,oBAAoB,WAAW,QAAQ,KACvC,oBAAoB,WAAW,MAAM;AAAA,EAE7C,CAAC;AACD,MAAI,WAAW,SAAS,GAAG;AACvB,UAAM,IAAI,YAAY,oDAAoD;AAAA,MACtE,SAAS;AAAA,IACb,CAAC;AAAA,EACL;AACJ;AAMO,SAAS,iBACZ,SACiD;AACjD,QAAM,MAA8B,CAAC;AACrC,aAAW,cAAc,SAAS;AAC9B,QAAI,WAAW,YAAY,CAAC,IAAI,QAAQ,UAAU;AAAA,EACtD;AACA,SAAO;AACX;;;AF3EO,SAAS,oBAAoB,QAA8B;AAC9D,MAAI,WAAW,OAAiD;AAC5D,kDAA8C;AAAA,EAClD;AACA,QAAM,EAAE,SAAS,IAAI,IAAI;AACzB,MAAI,WAAW,SAAS;AACpB,sCAAkC,OAAO;AAAA,EAC7C;AACA,MAAI;AACJ,MAAkB,0BAA0B,QAAQ;AAChD,uBAAmB,EAAE,YAAY,OAAO,qBAAqB;AAAA,EACjE;AACA,QAAM,gBAAgB,WAAW,iBAAiB,OAAO;AACzD,SAAO,eAAe,gBAA2B;AAAA,IAC7C;AAAA,IACA;AAAA,EACJ,GAAoD;AAChD,UAAM,OAAO,KAAK,UAAU,OAAO;AACnC,UAAM,cAAc;AAAA,MAChB,GAAG;AAAA,MACH;AAAA,MACA,SAAS;AAAA,QACL,GAAG;AAAA;AAAA,QAEH,QAAQ;AAAA,QACR,kBAAkB,KAAK,OAAO,SAAS;AAAA,QACvC,gBAAgB;AAAA,MACpB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACJ;AACA,UAAM,WAAW,MAAM,MAAU,KAAK,WAAW;AACjD,QAAI,CAAC,SAAS,IAAI;AACd,YAAM,IAAID,aAAY,yCAAyC;AAAA,QAC3D,SAAS,SAAS;AAAA,QAClB,YAAY,SAAS;AAAA,MACzB,CAAC;AAAA,IACL;AACA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAChC;AACJ","sourcesContent":["// Clever obfuscation to prevent the build system from inlining the value of `NODE_ENV`\nexport const __DEV__ = /* @__PURE__ */ (() => (process as any)['en' + 'v'].NODE_ENV === 'development')();\n","import { SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, SolanaError } from '@solana/errors';\nimport fetchImpl from '@solana/fetch-impl';\nimport { RpcTransport } from '@solana/rpc-spec';\nimport type Dispatcher from 'undici/types/dispatcher';\n\nimport {\n AllowedHttpRequestHeaders,\n assertIsAllowedHttpRequestHeaders,\n normalizeHeaders,\n} from './http-transport-headers';\n\ntype Config = Readonly<{\n dispatcher_NODE_ONLY?: Dispatcher;\n headers?: AllowedHttpRequestHeaders;\n url: string;\n}>;\n\nlet didWarnDispatcherWasSuppliedInNonNodeEnvironment = false;\nfunction warnDispatcherWasSuppliedInNonNodeEnvironment() {\n if (didWarnDispatcherWasSuppliedInNonNodeEnvironment) {\n return;\n }\n didWarnDispatcherWasSuppliedInNonNodeEnvironment = true;\n console.warn(\n 'You have supplied a `Dispatcher` to `createHttpTransport()`. It has been ignored ' +\n 'because Undici dispatchers only work in Node environments. To eliminate this ' +\n 'warning, omit the `dispatcher_NODE_ONLY` property from your config when running in ' +\n 'a non-Node environment.',\n );\n}\n\nexport function createHttpTransport(config: Config): RpcTransport {\n if (__DEV__ && !__NODEJS__ && 'dispatcher_NODE_ONLY' in config) {\n warnDispatcherWasSuppliedInNonNodeEnvironment();\n }\n const { headers, url } = config;\n if (__DEV__ && headers) {\n assertIsAllowedHttpRequestHeaders(headers);\n }\n let dispatcherConfig: { dispatcher: Dispatcher | undefined } | undefined;\n if (__NODEJS__ && 'dispatcher_NODE_ONLY' in config) {\n dispatcherConfig = { dispatcher: config.dispatcher_NODE_ONLY };\n }\n const customHeaders = headers && normalizeHeaders(headers);\n return async function makeHttpRequest<TResponse>({\n payload,\n signal,\n }: Parameters<RpcTransport>[0]): Promise<TResponse> {\n const body = JSON.stringify(payload);\n const requestInfo = {\n ...dispatcherConfig,\n body,\n headers: {\n ...customHeaders,\n // Keep these headers lowercase so they will override any user-supplied headers above.\n accept: 'application/json',\n 'content-length': body.length.toString(),\n 'content-type': 'application/json; charset=utf-8',\n },\n method: 'POST',\n signal,\n };\n const response = await fetchImpl(url, requestInfo);\n if (!response.ok) {\n throw new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, {\n message: response.statusText,\n statusCode: response.status,\n });\n }\n return (await response.json()) as TResponse;\n };\n}\n","export { fetch as default } from 'undici';\n","import { SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, SolanaError } from '@solana/errors';\n\nexport type AllowedHttpRequestHeaders = Readonly<\n { [headerName: string]: string } & {\n // Someone can still sneak a forbidden header past Typescript if they do something like\n // fOo-BaR, but at that point they deserve the runtime failure.\n [K in DisallowedHeaders | ForbiddenHeaders as\n | K // `Foo-Bar`\n | Capitalize<Lowercase<K>> // `Foo-bar`\n | Lowercase<K> // `foo-bar`\n | Uncapitalize<K> // `foo-Bar`\n // `FOO-BAR`\n | Uppercase<K>]?: never;\n }\n>;\n// These are headers that we simply don't allow the developer to override because they're\n// fundamental to the operation of the JSON-RPC transport.\ntype DisallowedHeaders = 'Accept' | 'Content-Length' | 'Content-Type' | 'Solana-Client';\ntype ForbiddenHeaders =\n | 'Accept-Charset'\n | 'Accept-Encoding'\n | 'Access-Control-Request-Headers'\n | 'Access-Control-Request-Method'\n | 'Connection'\n | 'Content-Length'\n | 'Cookie'\n | 'Date'\n | 'DNT'\n | 'Expect'\n | 'Host'\n | 'Keep-Alive'\n | 'Origin'\n | 'Permissions-Policy'\n | `Proxy-${string}`\n | `Sec-${string}`\n | 'Referer'\n | 'TE'\n | 'Trailer'\n | 'Transfer-Encoding'\n | 'Upgrade'\n | 'Via';\n\n// These are headers which are fundamental to the JSON-RPC transport, and must not be modified.\nconst DISALLOWED_HEADERS: Record<string, boolean> = {\n accept: true,\n 'content-length': true,\n 'content-type': true,\n};\n// https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name\nconst FORBIDDEN_HEADERS: Record<string, boolean> = {\n 'accept-charset': true,\n 'accept-encoding': true,\n 'access-control-request-headers': true,\n 'access-control-request-method': true,\n connection: true,\n 'content-length': true,\n cookie: true,\n date: true,\n dnt: true,\n expect: true,\n host: true,\n 'keep-alive': true,\n origin: true,\n 'permissions-policy': true,\n // Prefix matching is implemented in code, below.\n // 'proxy-': true,\n // 'sec-': true,\n referer: true,\n te: true,\n trailer: true,\n 'transfer-encoding': true,\n upgrade: true,\n via: true,\n};\n\nexport function assertIsAllowedHttpRequestHeaders(\n headers: Record<string, string>,\n): asserts headers is AllowedHttpRequestHeaders {\n const badHeaders = Object.keys(headers).filter(headerName => {\n const lowercaseHeaderName = headerName.toLowerCase();\n return (\n DISALLOWED_HEADERS[headerName.toLowerCase()] === true ||\n FORBIDDEN_HEADERS[headerName.toLowerCase()] === true ||\n lowercaseHeaderName.startsWith('proxy-') ||\n lowercaseHeaderName.startsWith('sec-')\n );\n });\n if (badHeaders.length > 0) {\n throw new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, {\n headers: badHeaders,\n });\n }\n}\n\n/**\n * Lowercasing header names makes it easier to override user-supplied headers, such as those defined\n * in the `DisallowedHeaders` type.\n */\nexport function normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in keyof T & string as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in keyof T & string as Lowercase<K>]: T[K] };\n}\n"]}
@@ -1,23 +1,8 @@
1
+ import { SolanaError, SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN } from '@solana/errors';
2
+ import { fetch } from 'undici';
3
+
1
4
  // ../build-scripts/env-shim.ts
2
5
  var __DEV__ = /* @__PURE__ */ (() => process["env"].NODE_ENV === "development")();
3
-
4
- // ../fetch-impl/dist/index.node.js
5
- var e = globalThis.fetch;
6
-
7
- // src/http-transport-errors.ts
8
- var SolanaHttpError = class extends Error {
9
- statusCode;
10
- constructor(details) {
11
- super(`HTTP error (${details.statusCode}): ${details.message}`);
12
- Error.captureStackTrace(this, this.constructor);
13
- this.statusCode = details.statusCode;
14
- }
15
- get name() {
16
- return "SolanaHttpError";
17
- }
18
- };
19
-
20
- // src/http-transport-headers.ts
21
6
  var DISALLOWED_HEADERS = {
22
7
  accept: true,
23
8
  "content-length": true,
@@ -38,9 +23,9 @@ var FORBIDDEN_HEADERS = {
38
23
  "keep-alive": true,
39
24
  origin: true,
40
25
  "permissions-policy": true,
41
- // No currently available Typescript technique allows you to match on a prefix.
42
- // 'proxy-':true,
43
- // 'sec-':true,
26
+ // Prefix matching is implemented in code, below.
27
+ // 'proxy-': true,
28
+ // 'sec-': true,
44
29
  referer: true,
45
30
  te: true,
46
31
  trailer: true,
@@ -54,9 +39,9 @@ function assertIsAllowedHttpRequestHeaders(headers) {
54
39
  return DISALLOWED_HEADERS[headerName.toLowerCase()] === true || FORBIDDEN_HEADERS[headerName.toLowerCase()] === true || lowercaseHeaderName.startsWith("proxy-") || lowercaseHeaderName.startsWith("sec-");
55
40
  });
56
41
  if (badHeaders.length > 0) {
57
- throw new Error(
58
- `${badHeaders.length > 1 ? "These headers are" : "This header is"} forbidden: \`${badHeaders.join("`, `")}\`. Learn more at https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name.`
59
- );
42
+ throw new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, {
43
+ headers: badHeaders
44
+ });
60
45
  }
61
46
  }
62
47
  function normalizeHeaders(headers) {
@@ -68,10 +53,18 @@ function normalizeHeaders(headers) {
68
53
  }
69
54
 
70
55
  // src/http-transport.ts
71
- function createHttpTransport({ headers, url }) {
56
+ function createHttpTransport(config) {
57
+ if (__DEV__ && false) {
58
+ warnDispatcherWasSuppliedInNonNodeEnvironment();
59
+ }
60
+ const { headers, url } = config;
72
61
  if (__DEV__ && headers) {
73
62
  assertIsAllowedHttpRequestHeaders(headers);
74
63
  }
64
+ let dispatcherConfig;
65
+ if ("dispatcher_NODE_ONLY" in config) {
66
+ dispatcherConfig = { dispatcher: config.dispatcher_NODE_ONLY };
67
+ }
75
68
  const customHeaders = headers && normalizeHeaders(headers);
76
69
  return async function makeHttpRequest({
77
70
  payload,
@@ -79,6 +72,7 @@ function createHttpTransport({ headers, url }) {
79
72
  }) {
80
73
  const body = JSON.stringify(payload);
81
74
  const requestInfo = {
75
+ ...dispatcherConfig,
82
76
  body,
83
77
  headers: {
84
78
  ...customHeaders,
@@ -90,9 +84,9 @@ function createHttpTransport({ headers, url }) {
90
84
  method: "POST",
91
85
  signal
92
86
  };
93
- const response = await e(url, requestInfo);
87
+ const response = await fetch(url, requestInfo);
94
88
  if (!response.ok) {
95
- throw new SolanaHttpError({
89
+ throw new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, {
96
90
  message: response.statusText,
97
91
  statusCode: response.status
98
92
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../build-scripts/env-shim.ts","../../fetch-impl/src/index.node.ts","../src/http-transport-errors.ts","../src/http-transport-headers.ts","../src/http-transport.ts"],"names":["index_node_default"],"mappings":";AACO,IAAM,UAA2B,uBAAO,QAAgB,KAAU,EAAE,aAAa,eAAe;;;ACAvG,IAAOA,IAAQ,WAAW;;;ACInB,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAC9B;AAAA,EACT,YAAY,SAAiC;AACzC,UAAM,eAAe,QAAQ,UAAU,MAAM,QAAQ,OAAO,EAAE;AAC9D,UAAM,kBAAkB,MAAM,KAAK,WAAW;AAC9C,SAAK,aAAa,QAAQ;AAAA,EAC9B;AAAA,EACA,IAAI,OAAO;AACP,WAAO;AAAA,EACX;AACJ;;;AC2BA,IAAM,qBAA8C;AAAA,EAChD,QAAQ;AAAA,EACR,kBAAkB;AAAA,EAClB,gBAAgB;AACpB;AAEA,IAAM,oBAA6C;AAAA,EAC/C,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,kCAAkC;AAAA,EAClC,iCAAiC;AAAA,EACjC,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,sBAAsB;AAAA;AAAA;AAAA;AAAA,EAItB,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,SAAS;AAAA,EACT,KAAK;AACT;AAEO,SAAS,kCACZ,SAC4C;AAC5C,QAAM,aAAa,OAAO,KAAK,OAAO,EAAE,OAAO,gBAAc;AACzD,UAAM,sBAAsB,WAAW,YAAY;AACnD,WACI,mBAAmB,WAAW,YAAY,CAAC,MAAM,QACjD,kBAAkB,WAAW,YAAY,CAAC,MAAM,QAChD,oBAAoB,WAAW,QAAQ,KACvC,oBAAoB,WAAW,MAAM;AAAA,EAE7C,CAAC;AACD,MAAI,WAAW,SAAS,GAAG;AACvB,UAAM,IAAI;AAAA,MACN,GAAG,WAAW,SAAS,IAAI,sBAAsB,gBAAgB,iBACxD,WAAW,KAAK,MAAM,CAAC;AAAA,IAEpC;AAAA,EACJ;AACJ;AAMO,SAAS,iBACZ,SACiD;AACjD,QAAM,MAA8B,CAAC;AACrC,aAAW,cAAc,SAAS;AAC9B,QAAI,WAAW,YAAY,CAAC,IAAI,QAAQ,UAAU;AAAA,EACtD;AACA,SAAO;AACX;;;AC5FO,SAAS,oBAAoB,EAAE,SAAS,IAAI,GAAyB;AACxE,MAAI,WAAW,SAAS;AACpB,sCAAkC,OAAO;AAAA,EAC7C;AACA,QAAM,gBAAgB,WAAW,iBAAiB,OAAO;AACzD,SAAO,eAAe,gBAA2B;AAAA,IAC7C;AAAA,IACA;AAAA,EACJ,GAAoD;AAChD,UAAM,OAAO,KAAK,UAAU,OAAO;AACnC,UAAM,cAAc;AAAA,MAChB;AAAA,MACA,SAAS;AAAA,QACL,GAAG;AAAA;AAAA,QAEH,QAAQ;AAAA,QACR,kBAAkB,KAAK,OAAO,SAAS;AAAA,QACvC,gBAAgB;AAAA,MACpB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACJ;AACA,UAAM,WAAW,MAAM,EAAU,KAAK,WAAW;AACjD,QAAI,CAAC,SAAS,IAAI;AACd,YAAM,IAAI,gBAAgB;AAAA,QACtB,SAAS,SAAS;AAAA,QAClB,YAAY,SAAS;AAAA,MACzB,CAAC;AAAA,IACL;AACA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAChC;AACJ","sourcesContent":["// Clever obfuscation to prevent the build system from inlining the value of `NODE_ENV`\nexport const __DEV__ = /* @__PURE__ */ (() => (process as any)['en' + 'v'].NODE_ENV === 'development')();\n","// TODO(https://github.com/solana-labs/solana-web3.js/issues/1787) Write HTTP/2 implementation.\nexport default globalThis.fetch; // The Fetch API is supported natively in Node 18+.\n","type SolanaHttpErrorDetails = Readonly<{\n statusCode: number;\n message: string;\n}>;\n\nexport class SolanaHttpError extends Error {\n readonly statusCode: number;\n constructor(details: SolanaHttpErrorDetails) {\n super(`HTTP error (${details.statusCode}): ${details.message}`);\n Error.captureStackTrace(this, this.constructor);\n this.statusCode = details.statusCode;\n }\n get name() {\n return 'SolanaHttpError';\n }\n}\n","export type AllowedHttpRequestHeaders = Readonly<\n { [headerName: string]: string } & {\n // Someone can still sneak a forbidden header past Typescript if they do something like\n // fOo-BaR, but at that point they deserve the runtime failure.\n [K in DisallowedHeaders | ForbiddenHeaders as\n | K // `Foo-Bar`\n | Capitalize<Lowercase<K>> // `Foo-bar`\n | Lowercase<K> // `foo-bar`\n | Uncapitalize<K> // `foo-Bar`\n // `FOO-BAR`\n | Uppercase<K>]?: never;\n }\n>;\n// These are headers that we simply don't allow the developer to override because they're\n// fundamental to the operation of the JSON-RPC transport.\ntype DisallowedHeaders = 'Accept' | 'Content-Length' | 'Content-Type' | 'Solana-Client';\ntype ForbiddenHeaders =\n | 'Accept-Charset'\n | 'Accept-Encoding'\n | 'Access-Control-Request-Headers'\n | 'Access-Control-Request-Method'\n | 'Connection'\n | 'Content-Length'\n | 'Cookie'\n | 'Date'\n | 'DNT'\n | 'Expect'\n | 'Host'\n | 'Keep-Alive'\n | 'Origin'\n | 'Permissions-Policy'\n // No currently available Typescript technique allows you to match on a prefix.\n // | 'Proxy-'\n // | 'Sec-'\n | 'Referer'\n | 'TE'\n | 'Trailer'\n | 'Transfer-Encoding'\n | 'Upgrade'\n | 'Via';\n\n// These are headers which are fundamental to the JSON-RPC transport, and must not be modified.\nconst DISALLOWED_HEADERS: Record<string, boolean> = {\n accept: true,\n 'content-length': true,\n 'content-type': true,\n};\n// https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name\nconst FORBIDDEN_HEADERS: Record<string, boolean> = {\n 'accept-charset': true,\n 'accept-encoding': true,\n 'access-control-request-headers': true,\n 'access-control-request-method': true,\n connection: true,\n 'content-length': true,\n cookie: true,\n date: true,\n dnt: true,\n expect: true,\n host: true,\n 'keep-alive': true,\n origin: true,\n 'permissions-policy': true,\n // No currently available Typescript technique allows you to match on a prefix.\n // 'proxy-':true,\n // 'sec-':true,\n referer: true,\n te: true,\n trailer: true,\n 'transfer-encoding': true,\n upgrade: true,\n via: true,\n};\n\nexport function assertIsAllowedHttpRequestHeaders(\n headers: Record<string, string>,\n): asserts headers is AllowedHttpRequestHeaders {\n const badHeaders = Object.keys(headers).filter(headerName => {\n const lowercaseHeaderName = headerName.toLowerCase();\n return (\n DISALLOWED_HEADERS[headerName.toLowerCase()] === true ||\n FORBIDDEN_HEADERS[headerName.toLowerCase()] === true ||\n lowercaseHeaderName.startsWith('proxy-') ||\n lowercaseHeaderName.startsWith('sec-')\n );\n });\n if (badHeaders.length > 0) {\n throw new Error(\n `${badHeaders.length > 1 ? 'These headers are' : 'This header is'} forbidden: ` +\n `\\`${badHeaders.join('`, `')}\\`. Learn more at ` +\n 'https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name.',\n );\n }\n}\n\n/**\n * Lowercasing header names makes it easier to override user-supplied headers, such as those defined\n * in the `DisallowedHeaders` type.\n */\nexport function normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in keyof T & string as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in keyof T & string as Lowercase<K>]: T[K] };\n}\n","import fetchImpl from '@solana/fetch-impl';\nimport { RpcTransport } from '@solana/rpc-spec';\n\nimport { SolanaHttpError } from './http-transport-errors';\nimport {\n AllowedHttpRequestHeaders,\n assertIsAllowedHttpRequestHeaders,\n normalizeHeaders,\n} from './http-transport-headers';\n\ntype Config = Readonly<{\n headers?: AllowedHttpRequestHeaders;\n url: string;\n}>;\n\nexport function createHttpTransport({ headers, url }: Config): RpcTransport {\n if (__DEV__ && headers) {\n assertIsAllowedHttpRequestHeaders(headers);\n }\n const customHeaders = headers && normalizeHeaders(headers);\n return async function makeHttpRequest<TResponse>({\n payload,\n signal,\n }: Parameters<RpcTransport>[0]): Promise<TResponse> {\n const body = JSON.stringify(payload);\n const requestInfo = {\n body,\n headers: {\n ...customHeaders,\n // Keep these headers lowercase so they will override any user-supplied headers above.\n accept: 'application/json',\n 'content-length': body.length.toString(),\n 'content-type': 'application/json; charset=utf-8',\n },\n method: 'POST',\n signal,\n };\n const response = await fetchImpl(url, requestInfo);\n if (!response.ok) {\n throw new SolanaHttpError({\n message: response.statusText,\n statusCode: response.status,\n });\n }\n return (await response.json()) as TResponse;\n };\n}\n"]}
1
+ {"version":3,"sources":["../../build-scripts/env-shim.ts","../src/http-transport.ts","../../fetch-impl/src/index.node.ts","../src/http-transport-headers.ts"],"names":["SolanaError","fetch"],"mappings":";AACO,IAAM,UAA2B,uBAAO,QAAgB,KAAU,EAAE,aAAa,eAAe;;;ACDvG,SAAS,yCAAyC,eAAAA,oBAAmB;;;ACArE,SAASC,aAAwB;;;ACAjC,SAAS,oDAAoD,mBAAmB;AA2ChF,IAAM,qBAA8C;AAAA,EAChD,QAAQ;AAAA,EACR,kBAAkB;AAAA,EAClB,gBAAgB;AACpB;AAEA,IAAM,oBAA6C;AAAA,EAC/C,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,kCAAkC;AAAA,EAClC,iCAAiC;AAAA,EACjC,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,sBAAsB;AAAA;AAAA;AAAA;AAAA,EAItB,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,SAAS;AAAA,EACT,KAAK;AACT;AAEO,SAAS,kCACZ,SAC4C;AAC5C,QAAM,aAAa,OAAO,KAAK,OAAO,EAAE,OAAO,gBAAc;AACzD,UAAM,sBAAsB,WAAW,YAAY;AACnD,WACI,mBAAmB,WAAW,YAAY,CAAC,MAAM,QACjD,kBAAkB,WAAW,YAAY,CAAC,MAAM,QAChD,oBAAoB,WAAW,QAAQ,KACvC,oBAAoB,WAAW,MAAM;AAAA,EAE7C,CAAC;AACD,MAAI,WAAW,SAAS,GAAG;AACvB,UAAM,IAAI,YAAY,oDAAoD;AAAA,MACtE,SAAS;AAAA,IACb,CAAC;AAAA,EACL;AACJ;AAMO,SAAS,iBACZ,SACiD;AACjD,QAAM,MAA8B,CAAC;AACrC,aAAW,cAAc,SAAS;AAC9B,QAAI,WAAW,YAAY,CAAC,IAAI,QAAQ,UAAU;AAAA,EACtD;AACA,SAAO;AACX;;;AF3EO,SAAS,oBAAoB,QAA8B;AAC9D,MAAI,WAAW,OAAiD;AAC5D,kDAA8C;AAAA,EAClD;AACA,QAAM,EAAE,SAAS,IAAI,IAAI;AACzB,MAAI,WAAW,SAAS;AACpB,sCAAkC,OAAO;AAAA,EAC7C;AACA,MAAI;AACJ,MAAkB,0BAA0B,QAAQ;AAChD,uBAAmB,EAAE,YAAY,OAAO,qBAAqB;AAAA,EACjE;AACA,QAAM,gBAAgB,WAAW,iBAAiB,OAAO;AACzD,SAAO,eAAe,gBAA2B;AAAA,IAC7C;AAAA,IACA;AAAA,EACJ,GAAoD;AAChD,UAAM,OAAO,KAAK,UAAU,OAAO;AACnC,UAAM,cAAc;AAAA,MAChB,GAAG;AAAA,MACH;AAAA,MACA,SAAS;AAAA,QACL,GAAG;AAAA;AAAA,QAEH,QAAQ;AAAA,QACR,kBAAkB,KAAK,OAAO,SAAS;AAAA,QACvC,gBAAgB;AAAA,MACpB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACJ;AACA,UAAM,WAAW,MAAM,MAAU,KAAK,WAAW;AACjD,QAAI,CAAC,SAAS,IAAI;AACd,YAAM,IAAID,aAAY,yCAAyC;AAAA,QAC3D,SAAS,SAAS;AAAA,QAClB,YAAY,SAAS;AAAA,MACzB,CAAC;AAAA,IACL;AACA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAChC;AACJ","sourcesContent":["// Clever obfuscation to prevent the build system from inlining the value of `NODE_ENV`\nexport const __DEV__ = /* @__PURE__ */ (() => (process as any)['en' + 'v'].NODE_ENV === 'development')();\n","import { SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, SolanaError } from '@solana/errors';\nimport fetchImpl from '@solana/fetch-impl';\nimport { RpcTransport } from '@solana/rpc-spec';\nimport type Dispatcher from 'undici/types/dispatcher';\n\nimport {\n AllowedHttpRequestHeaders,\n assertIsAllowedHttpRequestHeaders,\n normalizeHeaders,\n} from './http-transport-headers';\n\ntype Config = Readonly<{\n dispatcher_NODE_ONLY?: Dispatcher;\n headers?: AllowedHttpRequestHeaders;\n url: string;\n}>;\n\nlet didWarnDispatcherWasSuppliedInNonNodeEnvironment = false;\nfunction warnDispatcherWasSuppliedInNonNodeEnvironment() {\n if (didWarnDispatcherWasSuppliedInNonNodeEnvironment) {\n return;\n }\n didWarnDispatcherWasSuppliedInNonNodeEnvironment = true;\n console.warn(\n 'You have supplied a `Dispatcher` to `createHttpTransport()`. It has been ignored ' +\n 'because Undici dispatchers only work in Node environments. To eliminate this ' +\n 'warning, omit the `dispatcher_NODE_ONLY` property from your config when running in ' +\n 'a non-Node environment.',\n );\n}\n\nexport function createHttpTransport(config: Config): RpcTransport {\n if (__DEV__ && !__NODEJS__ && 'dispatcher_NODE_ONLY' in config) {\n warnDispatcherWasSuppliedInNonNodeEnvironment();\n }\n const { headers, url } = config;\n if (__DEV__ && headers) {\n assertIsAllowedHttpRequestHeaders(headers);\n }\n let dispatcherConfig: { dispatcher: Dispatcher | undefined } | undefined;\n if (__NODEJS__ && 'dispatcher_NODE_ONLY' in config) {\n dispatcherConfig = { dispatcher: config.dispatcher_NODE_ONLY };\n }\n const customHeaders = headers && normalizeHeaders(headers);\n return async function makeHttpRequest<TResponse>({\n payload,\n signal,\n }: Parameters<RpcTransport>[0]): Promise<TResponse> {\n const body = JSON.stringify(payload);\n const requestInfo = {\n ...dispatcherConfig,\n body,\n headers: {\n ...customHeaders,\n // Keep these headers lowercase so they will override any user-supplied headers above.\n accept: 'application/json',\n 'content-length': body.length.toString(),\n 'content-type': 'application/json; charset=utf-8',\n },\n method: 'POST',\n signal,\n };\n const response = await fetchImpl(url, requestInfo);\n if (!response.ok) {\n throw new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, {\n message: response.statusText,\n statusCode: response.status,\n });\n }\n return (await response.json()) as TResponse;\n };\n}\n","export { fetch as default } from 'undici';\n","import { SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, SolanaError } from '@solana/errors';\n\nexport type AllowedHttpRequestHeaders = Readonly<\n { [headerName: string]: string } & {\n // Someone can still sneak a forbidden header past Typescript if they do something like\n // fOo-BaR, but at that point they deserve the runtime failure.\n [K in DisallowedHeaders | ForbiddenHeaders as\n | K // `Foo-Bar`\n | Capitalize<Lowercase<K>> // `Foo-bar`\n | Lowercase<K> // `foo-bar`\n | Uncapitalize<K> // `foo-Bar`\n // `FOO-BAR`\n | Uppercase<K>]?: never;\n }\n>;\n// These are headers that we simply don't allow the developer to override because they're\n// fundamental to the operation of the JSON-RPC transport.\ntype DisallowedHeaders = 'Accept' | 'Content-Length' | 'Content-Type' | 'Solana-Client';\ntype ForbiddenHeaders =\n | 'Accept-Charset'\n | 'Accept-Encoding'\n | 'Access-Control-Request-Headers'\n | 'Access-Control-Request-Method'\n | 'Connection'\n | 'Content-Length'\n | 'Cookie'\n | 'Date'\n | 'DNT'\n | 'Expect'\n | 'Host'\n | 'Keep-Alive'\n | 'Origin'\n | 'Permissions-Policy'\n | `Proxy-${string}`\n | `Sec-${string}`\n | 'Referer'\n | 'TE'\n | 'Trailer'\n | 'Transfer-Encoding'\n | 'Upgrade'\n | 'Via';\n\n// These are headers which are fundamental to the JSON-RPC transport, and must not be modified.\nconst DISALLOWED_HEADERS: Record<string, boolean> = {\n accept: true,\n 'content-length': true,\n 'content-type': true,\n};\n// https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name\nconst FORBIDDEN_HEADERS: Record<string, boolean> = {\n 'accept-charset': true,\n 'accept-encoding': true,\n 'access-control-request-headers': true,\n 'access-control-request-method': true,\n connection: true,\n 'content-length': true,\n cookie: true,\n date: true,\n dnt: true,\n expect: true,\n host: true,\n 'keep-alive': true,\n origin: true,\n 'permissions-policy': true,\n // Prefix matching is implemented in code, below.\n // 'proxy-': true,\n // 'sec-': true,\n referer: true,\n te: true,\n trailer: true,\n 'transfer-encoding': true,\n upgrade: true,\n via: true,\n};\n\nexport function assertIsAllowedHttpRequestHeaders(\n headers: Record<string, string>,\n): asserts headers is AllowedHttpRequestHeaders {\n const badHeaders = Object.keys(headers).filter(headerName => {\n const lowercaseHeaderName = headerName.toLowerCase();\n return (\n DISALLOWED_HEADERS[headerName.toLowerCase()] === true ||\n FORBIDDEN_HEADERS[headerName.toLowerCase()] === true ||\n lowercaseHeaderName.startsWith('proxy-') ||\n lowercaseHeaderName.startsWith('sec-')\n );\n });\n if (badHeaders.length > 0) {\n throw new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, {\n headers: badHeaders,\n });\n }\n}\n\n/**\n * Lowercasing header names makes it easier to override user-supplied headers, such as those defined\n * in the `DisallowedHeaders` type.\n */\nexport function normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in keyof T & string as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in keyof T & string as Lowercase<K>]: T[K] };\n}\n"]}
@@ -4,7 +4,7 @@ export type AllowedHttpRequestHeaders = Readonly<{
4
4
  [K in DisallowedHeaders | ForbiddenHeaders as K | Capitalize<Lowercase<K>> | Lowercase<K> | Uncapitalize<K> | Uppercase<K>]?: never;
5
5
  }>;
6
6
  type DisallowedHeaders = 'Accept' | 'Content-Length' | 'Content-Type' | 'Solana-Client';
7
- type ForbiddenHeaders = 'Accept-Charset' | 'Accept-Encoding' | 'Access-Control-Request-Headers' | 'Access-Control-Request-Method' | 'Connection' | 'Content-Length' | 'Cookie' | 'Date' | 'DNT' | 'Expect' | 'Host' | 'Keep-Alive' | 'Origin' | 'Permissions-Policy' | 'Referer' | 'TE' | 'Trailer' | 'Transfer-Encoding' | 'Upgrade' | 'Via';
7
+ type ForbiddenHeaders = 'Accept-Charset' | 'Accept-Encoding' | 'Access-Control-Request-Headers' | 'Access-Control-Request-Method' | 'Connection' | 'Content-Length' | 'Cookie' | 'Date' | 'DNT' | 'Expect' | 'Host' | 'Keep-Alive' | 'Origin' | 'Permissions-Policy' | `Proxy-${string}` | `Sec-${string}` | 'Referer' | 'TE' | 'Trailer' | 'Transfer-Encoding' | 'Upgrade' | 'Via';
8
8
  export declare function assertIsAllowedHttpRequestHeaders(headers: Record<string, string>): asserts headers is AllowedHttpRequestHeaders;
9
9
  /**
10
10
  * Lowercasing header names makes it easier to override user-supplied headers, such as those defined
@@ -1 +1 @@
1
- {"version":3,"file":"http-transport-headers.d.ts","sourceRoot":"","sources":["../../src/http-transport-headers.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAC5C;IAAE,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAAG;KAG9B,CAAC,IAAI,iBAAiB,GAAG,gBAAgB,IACpC,CAAC,GACD,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GACxB,SAAS,CAAC,CAAC,CAAC,GACZ,YAAY,CAAC,CAAC,CAAC,GAEf,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK;CAC9B,CACJ,CAAC;AAGF,KAAK,iBAAiB,GAAG,QAAQ,GAAG,gBAAgB,GAAG,cAAc,GAAG,eAAe,CAAC;AACxF,KAAK,gBAAgB,GACf,gBAAgB,GAChB,iBAAiB,GACjB,gCAAgC,GAChC,+BAA+B,GAC/B,YAAY,GACZ,gBAAgB,GAChB,QAAQ,GACR,MAAM,GACN,KAAK,GACL,QAAQ,GACR,MAAM,GACN,YAAY,GACZ,QAAQ,GACR,oBAAoB,GAIpB,SAAS,GACT,IAAI,GACJ,SAAS,GACT,mBAAmB,GACnB,SAAS,GACT,KAAK,CAAC;AAmCZ,wBAAgB,iCAAiC,CAC7C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,OAAO,CAAC,OAAO,IAAI,yBAAyB,CAiB9C;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7D,OAAO,EAAE,CAAC,GACX;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,IAAI,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,CAMnD"}
1
+ {"version":3,"file":"http-transport-headers.d.ts","sourceRoot":"","sources":["../../src/http-transport-headers.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAC5C;IAAE,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAAG;KAG9B,CAAC,IAAI,iBAAiB,GAAG,gBAAgB,IACpC,CAAC,GACD,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GACxB,SAAS,CAAC,CAAC,CAAC,GACZ,YAAY,CAAC,CAAC,CAAC,GAEf,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK;CAC9B,CACJ,CAAC;AAGF,KAAK,iBAAiB,GAAG,QAAQ,GAAG,gBAAgB,GAAG,cAAc,GAAG,eAAe,CAAC;AACxF,KAAK,gBAAgB,GACf,gBAAgB,GAChB,iBAAiB,GACjB,gCAAgC,GAChC,+BAA+B,GAC/B,YAAY,GACZ,gBAAgB,GAChB,QAAQ,GACR,MAAM,GACN,KAAK,GACL,QAAQ,GACR,MAAM,GACN,YAAY,GACZ,QAAQ,GACR,oBAAoB,GACpB,SAAS,MAAM,EAAE,GACjB,OAAO,MAAM,EAAE,GACf,SAAS,GACT,IAAI,GACJ,SAAS,GACT,mBAAmB,GACnB,SAAS,GACT,KAAK,CAAC;AAmCZ,wBAAgB,iCAAiC,CAC7C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,OAAO,CAAC,OAAO,IAAI,yBAAyB,CAe9C;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7D,OAAO,EAAE,CAAC,GACX;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,IAAI,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,CAMnD"}
@@ -1,9 +1,11 @@
1
1
  import { RpcTransport } from '@solana/rpc-spec';
2
+ import type Dispatcher from 'undici/types/dispatcher';
2
3
  import { AllowedHttpRequestHeaders } from './http-transport-headers.js';
3
4
  type Config = Readonly<{
5
+ dispatcher_NODE_ONLY?: Dispatcher;
4
6
  headers?: AllowedHttpRequestHeaders;
5
7
  url: string;
6
8
  }>;
7
- export declare function createHttpTransport({ headers, url }: Config): RpcTransport;
9
+ export declare function createHttpTransport(config: Config): RpcTransport;
8
10
  export {};
9
11
  //# sourceMappingURL=http-transport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"http-transport.d.ts","sourceRoot":"","sources":["../../src/http-transport.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,OAAO,EACH,yBAAyB,EAG5B,MAAM,0BAA0B,CAAC;AAElC,KAAK,MAAM,GAAG,QAAQ,CAAC;IACnB,OAAO,CAAC,EAAE,yBAAyB,CAAC;IACpC,GAAG,EAAE,MAAM,CAAC;CACf,CAAC,CAAC;AAEH,wBAAgB,mBAAmB,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,MAAM,GAAG,YAAY,CA+B1E"}
1
+ {"version":3,"file":"http-transport.d.ts","sourceRoot":"","sources":["../../src/http-transport.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,UAAU,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EACH,yBAAyB,EAG5B,MAAM,0BAA0B,CAAC;AAElC,KAAK,MAAM,GAAG,QAAQ,CAAC;IACnB,oBAAoB,CAAC,EAAE,UAAU,CAAC;IAClC,OAAO,CAAC,EAAE,yBAAyB,CAAC;IACpC,GAAG,EAAE,MAAM,CAAC;CACf,CAAC,CAAC;AAgBH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAwChE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solana/rpc-transport-http",
3
- "version": "2.0.0-experimental.fbbf6ba",
3
+ "version": "2.0.0-experimental.feaeef2",
4
4
  "description": "An RPC transport that uses HTTP requests",
5
5
  "exports": {
6
6
  "browser": {
@@ -46,7 +46,9 @@
46
46
  "maintained node versions"
47
47
  ],
48
48
  "dependencies": {
49
- "@solana/rpc-spec": "2.0.0-experimental.fbbf6ba"
49
+ "undici": "^6.6.2",
50
+ "@solana/errors": "2.0.0-experimental.feaeef2",
51
+ "@solana/rpc-spec": "2.0.0-experimental.feaeef2"
50
52
  },
51
53
  "bundlewatch": {
52
54
  "defaultCompression": "gzip",
@@ -1,11 +0,0 @@
1
- type SolanaHttpErrorDetails = Readonly<{
2
- statusCode: number;
3
- message: string;
4
- }>;
5
- export declare class SolanaHttpError extends Error {
6
- readonly statusCode: number;
7
- constructor(details: SolanaHttpErrorDetails);
8
- get name(): string;
9
- }
10
- export {};
11
- //# sourceMappingURL=http-transport-errors.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"http-transport-errors.d.ts","sourceRoot":"","sources":["../../src/http-transport-errors.ts"],"names":[],"mappings":"AAAA,KAAK,sBAAsB,GAAG,QAAQ,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC,CAAC;AAEH,qBAAa,eAAgB,SAAQ,KAAK;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAChB,OAAO,EAAE,sBAAsB;IAK3C,IAAI,IAAI,WAEP;CACJ"}