@solana/web3.js 2.0.0-experimental.d6c5c0e → 2.0.0-experimental.da22638

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.
Files changed (33) hide show
  1. package/README.md +14 -13
  2. package/dist/index.browser.cjs +297 -9
  3. package/dist/index.browser.cjs.map +1 -1
  4. package/dist/index.browser.js +277 -11
  5. package/dist/index.browser.js.map +1 -1
  6. package/dist/index.development.js +2567 -195
  7. package/dist/index.development.js.map +1 -1
  8. package/dist/index.native.js +264 -11
  9. package/dist/index.native.js.map +1 -1
  10. package/dist/index.node.cjs +288 -9
  11. package/dist/index.node.cjs.map +1 -1
  12. package/dist/index.node.js +266 -11
  13. package/dist/index.node.js.map +1 -1
  14. package/dist/index.production.min.js +38 -4
  15. package/dist/types/cached-abortable-iterable.d.ts +11 -0
  16. package/dist/types/cached-abortable-iterable.d.ts.map +1 -0
  17. package/dist/types/index.d.ts +4 -0
  18. package/dist/types/index.d.ts.map +1 -1
  19. package/dist/types/rpc-default-config.d.ts.map +1 -1
  20. package/dist/types/rpc-request-coalescer.d.ts +5 -0
  21. package/dist/types/rpc-request-coalescer.d.ts.map +1 -0
  22. package/dist/types/rpc-request-deduplication.d.ts +3 -0
  23. package/dist/types/rpc-request-deduplication.d.ts.map +1 -0
  24. package/dist/types/rpc-transport.d.ts.map +1 -1
  25. package/dist/types/rpc-websocket-autopinger.d.ts +8 -0
  26. package/dist/types/rpc-websocket-autopinger.d.ts.map +1 -0
  27. package/dist/types/rpc-websocket-connection-sharding.d.ts +13 -0
  28. package/dist/types/rpc-websocket-connection-sharding.d.ts.map +1 -0
  29. package/dist/types/rpc-websocket-transport.d.ts +13 -0
  30. package/dist/types/rpc-websocket-transport.d.ts.map +1 -0
  31. package/dist/types/rpc.d.ts +4 -3
  32. package/dist/types/rpc.d.ts.map +1 -1
  33. package/package.json +23 -21
package/README.md CHANGED
@@ -62,8 +62,9 @@ const devnetRpc = createSolanaRpc({ transport: devnetTransport });
62
62
  Now, you can use it to call methods on your RPC server. For instance, here is how you would fetch an account's balance.
63
63
 
64
64
  ```ts
65
- const balanceInLamports = await devnetRpc.getBalance('11111111111111111111111111111111' as Base58EncodedAddress);
66
- console.log('Balance of account 11111111111111111111111111111111 in Lamports', balanceInLamports);
65
+ const systemProgramAddress = '11111111111111111111111111111111' as Base58EncodedAddress;
66
+ const balanceInLamports = await devnetRpc.getBalance(systemProgramAddress).send();
67
+ console.log('Balance of System Program account in Lamports', balanceInLamports);
67
68
  ```
68
69
 
69
70
  ### Transactions
@@ -83,16 +84,16 @@ import { assertIsBase58EncodedAddress } from '@solana/web3.js`;
83
84
 
84
85
  // Imagine a function that fetches an account's balance when a user submits a form.
85
86
  function handleSubmit() {
86
- // We know only that what the user typed conforms to the `string` type.
87
- const address: string = accountAddressInput.value;
88
- try {
89
- // If this type assertion function doesn't throw, then
90
- // Typescript will upcast `address` to `Base58EncodedAddress`.
91
- assertIsBase58EncodedAddress(address);
92
- // At this point, `address` is a `Base58EncodedAddress` that can be used with the RPC.
93
- const balanceInLamports = await rpc.getBalance(address);
94
- } catch (e) {
95
- // `address` turned out not to be a base58-encoded address
96
- }
87
+ // We know only that what the user typed conforms to the `string` type.
88
+ const address: string = accountAddressInput.value;
89
+ try {
90
+ // If this type assertion function doesn't throw, then
91
+ // Typescript will upcast `address` to `Base58EncodedAddress`.
92
+ assertIsBase58EncodedAddress(address);
93
+ // At this point, `address` is a `Base58EncodedAddress` that can be used with the RPC.
94
+ const balanceInLamports = await rpc.getBalance(address).send();
95
+ } catch (e) {
96
+ // `address` turned out not to be a base58-encoded address
97
+ }
97
98
  }
98
99
  ```
@@ -1,10 +1,20 @@
1
1
  'use strict';
2
2
 
3
+ var addresses = require('@solana/addresses');
4
+ var instructions = require('@solana/instructions');
3
5
  var keys = require('@solana/keys');
6
+ var transactions = require('@solana/transactions');
4
7
  var rpcCore = require('@solana/rpc-core');
5
8
  var rpcTransport = require('@solana/rpc-transport');
9
+ var functional = require('@solana/functional');
10
+ var fastStableStringify = require('fast-stable-stringify');
6
11
 
7
- // src/index.ts
12
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
+
14
+ var fastStableStringify__default = /*#__PURE__*/_interopDefault(fastStableStringify);
15
+
16
+ // ../build-scripts/env-shim.ts
17
+ var __DEV__ = /* @__PURE__ */ (() => process["env"].NODE_ENV === "development")();
8
18
 
9
19
  // src/rpc-integer-overflow-error.ts
10
20
  var SolanaJsonRpcIntegerOverflowError = class extends Error {
@@ -41,12 +51,83 @@ var DEFAULT_RPC_CONFIG = {
41
51
  throw new SolanaJsonRpcIntegerOverflowError(methodName, keyPath, value);
42
52
  }
43
53
  };
54
+
55
+ // src/rpc.ts
44
56
  function createSolanaRpc(config) {
45
57
  return rpcTransport.createJsonRpc({
46
58
  ...config,
47
59
  api: rpcCore.createSolanaRpcApi(DEFAULT_RPC_CONFIG)
48
60
  });
49
61
  }
62
+ function createSolanaRpcSubscriptions(config) {
63
+ return rpcTransport.createJsonSubscriptionRpc({
64
+ ...config,
65
+ api: rpcCore.createSolanaRpcSubscriptionsApi(DEFAULT_RPC_CONFIG)
66
+ });
67
+ }
68
+
69
+ // src/rpc-request-coalescer.ts
70
+ function getRpcTransportWithRequestCoalescing(transport, getDeduplicationKey) {
71
+ let coalescedRequestsByDeduplicationKey;
72
+ return async function makeCoalescedHttpRequest(config) {
73
+ const { payload, signal } = config;
74
+ const deduplicationKey = getDeduplicationKey(payload);
75
+ if (deduplicationKey === void 0) {
76
+ return await transport(config);
77
+ }
78
+ if (!coalescedRequestsByDeduplicationKey) {
79
+ Promise.resolve().then(() => {
80
+ coalescedRequestsByDeduplicationKey = void 0;
81
+ });
82
+ coalescedRequestsByDeduplicationKey = {};
83
+ }
84
+ if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {
85
+ const abortController = new AbortController();
86
+ coalescedRequestsByDeduplicationKey[deduplicationKey] = {
87
+ abortController,
88
+ numConsumers: 0,
89
+ responsePromise: transport({
90
+ ...config,
91
+ signal: abortController.signal
92
+ })
93
+ };
94
+ }
95
+ const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];
96
+ coalescedRequest.numConsumers++;
97
+ if (signal) {
98
+ const responsePromise = coalescedRequest.responsePromise;
99
+ return await new Promise((resolve, reject) => {
100
+ const handleAbort = (e) => {
101
+ signal.removeEventListener("abort", handleAbort);
102
+ coalescedRequest.numConsumers -= 1;
103
+ if (coalescedRequest.numConsumers === 0) {
104
+ const abortController = coalescedRequest.abortController;
105
+ abortController.abort();
106
+ }
107
+ const abortError = new DOMException(e.target.reason, "AbortError");
108
+ reject(abortError);
109
+ };
110
+ signal.addEventListener("abort", handleAbort);
111
+ responsePromise.then(resolve).finally(() => {
112
+ signal.removeEventListener("abort", handleAbort);
113
+ });
114
+ });
115
+ } else {
116
+ return await coalescedRequest.responsePromise;
117
+ }
118
+ };
119
+ }
120
+ function isJsonRpcPayload(payload) {
121
+ if (payload == null || typeof payload !== "object" || Array.isArray(payload)) {
122
+ return false;
123
+ }
124
+ return "jsonrpc" in payload && payload.jsonrpc === "2.0" && "method" in payload && typeof payload.method === "string" && "params" in payload;
125
+ }
126
+ function getSolanaRpcPayloadDeduplicationKey(payload) {
127
+ return isJsonRpcPayload(payload) ? fastStableStringify__default.default([payload.method, payload.params]) : void 0;
128
+ }
129
+
130
+ // src/rpc-transport.ts
50
131
  function normalizeHeaders(headers) {
51
132
  const out = {};
52
133
  for (const headerName in headers) {
@@ -55,25 +136,232 @@ function normalizeHeaders(headers) {
55
136
  return out;
56
137
  }
57
138
  function createDefaultRpcTransport(config) {
58
- return rpcTransport.createHttpTransport({
59
- ...config,
60
- headers: {
61
- ...config.headers ? normalizeHeaders(config.headers) : void 0,
62
- ...{
63
- // Keep these headers lowercase so they will override any user-supplied headers above.
64
- "solana-client": `js/${"2.0.0-development"}` ?? "UNKNOWN"
139
+ return functional.pipe(
140
+ rpcTransport.createHttpTransport({
141
+ ...config,
142
+ headers: {
143
+ ...config.headers ? normalizeHeaders(config.headers) : void 0,
144
+ ...{
145
+ // Keep these headers lowercase so they will override any user-supplied headers above.
146
+ "solana-client": `js/${"2.0.0-development"}` ?? "UNKNOWN"
147
+ }
148
+ }
149
+ }),
150
+ (transport) => getRpcTransportWithRequestCoalescing(transport, getSolanaRpcPayloadDeduplicationKey)
151
+ );
152
+ }
153
+
154
+ // src/rpc-websocket-autopinger.ts
155
+ var PING_PAYLOAD = {
156
+ jsonrpc: "2.0",
157
+ method: "ping"
158
+ };
159
+ function getWebSocketTransportWithAutoping({ intervalMs, transport }) {
160
+ const pingableConnections = /* @__PURE__ */ new Map();
161
+ return async (...args) => {
162
+ const connection = await transport(...args);
163
+ let intervalId;
164
+ function sendPing() {
165
+ connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(PING_PAYLOAD);
166
+ }
167
+ function restartPingTimer() {
168
+ clearInterval(intervalId);
169
+ intervalId = setInterval(sendPing, intervalMs);
170
+ }
171
+ if (pingableConnections.has(connection) === false) {
172
+ pingableConnections.set(connection, {
173
+ [Symbol.asyncIterator]: connection[Symbol.asyncIterator].bind(connection),
174
+ send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: (...args2) => {
175
+ restartPingTimer();
176
+ return connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(...args2);
177
+ }
178
+ });
179
+ (async () => {
180
+ try {
181
+ for await (const _ of connection) {
182
+ restartPingTimer();
183
+ }
184
+ } catch {
185
+ } finally {
186
+ pingableConnections.delete(connection);
187
+ clearInterval(intervalId);
188
+ if (handleOffline) {
189
+ globalThis.window.removeEventListener("offline", handleOffline);
190
+ }
191
+ if (handleOnline) {
192
+ globalThis.window.removeEventListener("online", handleOnline);
193
+ }
194
+ }
195
+ })();
196
+ if (globalThis.navigator.onLine) {
197
+ restartPingTimer();
65
198
  }
199
+ let handleOffline;
200
+ let handleOnline;
201
+ {
202
+ handleOffline = () => {
203
+ clearInterval(intervalId);
204
+ };
205
+ handleOnline = () => {
206
+ sendPing();
207
+ restartPingTimer();
208
+ };
209
+ globalThis.window.addEventListener("offline", handleOffline);
210
+ globalThis.window.addEventListener("online", handleOnline);
211
+ }
212
+ }
213
+ return pingableConnections.get(connection);
214
+ };
215
+ }
216
+
217
+ // src/cached-abortable-iterable.ts
218
+ function registerIterableCleanup(iterable, cleanupFn) {
219
+ (async () => {
220
+ try {
221
+ for await (const _ of iterable)
222
+ ;
223
+ } catch {
224
+ } finally {
225
+ cleanupFn();
226
+ }
227
+ })();
228
+ }
229
+ function getCachedAbortableIterableFactory({
230
+ getAbortSignalFromInputArgs,
231
+ getCacheEntryMissingError,
232
+ getCacheKeyFromInputArgs,
233
+ onCacheHit,
234
+ onCreateIterable
235
+ }) {
236
+ const cache = /* @__PURE__ */ new Map();
237
+ function getCacheEntryOrThrow(cacheKey) {
238
+ const currentCacheEntry = cache.get(cacheKey);
239
+ if (!currentCacheEntry) {
240
+ throw getCacheEntryMissingError(cacheKey);
66
241
  }
242
+ return currentCacheEntry;
243
+ }
244
+ return async (...args) => {
245
+ const cacheKey = getCacheKeyFromInputArgs(...args);
246
+ const signal = getAbortSignalFromInputArgs(...args);
247
+ if (cacheKey === void 0) {
248
+ return await onCreateIterable(signal, ...args);
249
+ }
250
+ const cleanup = () => {
251
+ cache.delete(cacheKey);
252
+ signal.removeEventListener("abort", handleAbort);
253
+ };
254
+ const handleAbort = () => {
255
+ const cacheEntry = getCacheEntryOrThrow(cacheKey);
256
+ if (cacheEntry.purgeScheduled !== true) {
257
+ cacheEntry.purgeScheduled = true;
258
+ globalThis.queueMicrotask(() => {
259
+ cacheEntry.purgeScheduled = false;
260
+ if (cacheEntry.referenceCount === 0) {
261
+ cacheEntry.abortController.abort();
262
+ cleanup();
263
+ }
264
+ });
265
+ }
266
+ cacheEntry.referenceCount--;
267
+ };
268
+ signal.addEventListener("abort", handleAbort);
269
+ try {
270
+ const cacheEntry = cache.get(cacheKey);
271
+ if (!cacheEntry) {
272
+ const singletonAbortController = new AbortController();
273
+ const newIterablePromise = onCreateIterable(singletonAbortController.signal, ...args);
274
+ const newCacheEntry = {
275
+ abortController: singletonAbortController,
276
+ iterable: newIterablePromise,
277
+ purgeScheduled: false,
278
+ referenceCount: 1
279
+ };
280
+ cache.set(cacheKey, newCacheEntry);
281
+ const newIterable = await newIterablePromise;
282
+ registerIterableCleanup(newIterable, cleanup);
283
+ newCacheEntry.iterable = newIterable;
284
+ return newIterable;
285
+ } else {
286
+ cacheEntry.referenceCount++;
287
+ const iterableOrIterablePromise = cacheEntry.iterable;
288
+ const cachedIterable = "then" in iterableOrIterablePromise ? await iterableOrIterablePromise : iterableOrIterablePromise;
289
+ await onCacheHit(cachedIterable, ...args);
290
+ return cachedIterable;
291
+ }
292
+ } catch (e) {
293
+ cleanup();
294
+ throw e;
295
+ }
296
+ };
297
+ }
298
+
299
+ // src/rpc-websocket-connection-sharding.ts
300
+ var NULL_SHARD_CACHE_KEY = Symbol(
301
+ __DEV__ ? "Cache key to use when there is no connection sharding strategy" : void 0
302
+ );
303
+ function getWebSocketTransportWithConnectionSharding({ getShard, transport }) {
304
+ return getCachedAbortableIterableFactory({
305
+ getAbortSignalFromInputArgs: ({ signal }) => signal,
306
+ getCacheEntryMissingError(shardKey) {
307
+ return new Error(`Found no cache entry for connection with shard key \`${shardKey?.toString()}\``);
308
+ },
309
+ getCacheKeyFromInputArgs: ({ payload }) => getShard ? getShard(payload) : NULL_SHARD_CACHE_KEY,
310
+ onCacheHit: (connection, { payload }) => connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(payload),
311
+ onCreateIterable: (abortSignal, config) => transport({
312
+ ...config,
313
+ signal: abortSignal
314
+ })
67
315
  });
68
316
  }
69
317
 
318
+ // src/rpc-websocket-transport.ts
319
+ function createDefaultRpcSubscriptionsTransport(config) {
320
+ const { getShard, intervalMs, ...rest } = config;
321
+ return functional.pipe(
322
+ rpcTransport.createWebSocketTransport({
323
+ ...rest,
324
+ sendBufferHighWatermark: config.sendBufferHighWatermark ?? // Let 128KB of data into the WebSocket buffer before buffering it in the app.
325
+ 131072
326
+ }),
327
+ (transport) => getWebSocketTransportWithAutoping({
328
+ intervalMs: intervalMs ?? 5e3,
329
+ transport
330
+ }),
331
+ (transport) => getWebSocketTransportWithConnectionSharding({
332
+ getShard,
333
+ transport
334
+ })
335
+ );
336
+ }
337
+
338
+ exports.createDefaultRpcSubscriptionsTransport = createDefaultRpcSubscriptionsTransport;
70
339
  exports.createDefaultRpcTransport = createDefaultRpcTransport;
71
340
  exports.createSolanaRpc = createSolanaRpc;
341
+ exports.createSolanaRpcSubscriptions = createSolanaRpcSubscriptions;
342
+ Object.keys(addresses).forEach(function (k) {
343
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
344
+ enumerable: true,
345
+ get: function () { return addresses[k]; }
346
+ });
347
+ });
348
+ Object.keys(instructions).forEach(function (k) {
349
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
350
+ enumerable: true,
351
+ get: function () { return instructions[k]; }
352
+ });
353
+ });
72
354
  Object.keys(keys).forEach(function (k) {
73
- if (k !== 'default' && !exports.hasOwnProperty(k)) Object.defineProperty(exports, k, {
355
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
74
356
  enumerable: true,
75
357
  get: function () { return keys[k]; }
76
358
  });
77
359
  });
360
+ Object.keys(transactions).forEach(function (k) {
361
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
362
+ enumerable: true,
363
+ get: function () { return transactions[k]; }
364
+ });
365
+ });
78
366
  //# sourceMappingURL=out.js.map
79
367
  //# sourceMappingURL=index.browser.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/rpc.ts","../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../src/rpc-transport.ts"],"names":[],"mappings":";AAAA,cAAc;;;ACAd,SAA2B,0BAA0B;;;ACA9C,IAAM,oCAAN,cAAgD,MAAM;AAAA,EAIzD,YAAY,YAAoB,SAA8B,OAAe;AACzE,UAAM,eAAe,OAAO,QAAQ,CAAC,MAAM,WAAW,QAAQ,CAAC,IAAI,SAAS,QAAQ,CAAC,GAAG,EAAE,KAAK;AAC/F,QAAI,UAAU;AACd,UAAM,YAAY,cAAc;AAChC,UAAM,gBAAgB,cAAc;AACpC,QAAI,aAAa,KAAK,iBAAiB,IAAI;AACvC,gBAAU,cAAc;AAAA,IAC5B,WAAW,aAAa,KAAK,iBAAiB,IAAI;AAC9C,gBAAU,cAAc;AAAA,IAC5B,WAAW,aAAa,KAAK,iBAAiB,IAAI;AAC9C,gBAAU,cAAc;AAAA,IAC5B,OAAO;AACH,gBAAU,cAAc;AAAA,IAC5B;AACA,UAAM,OACF,QAAQ,SAAS,IACX,QACK,MAAM,CAAC,EACP,IAAI,cAAa,OAAO,aAAa,WAAW,IAAI,cAAc,QAAS,EAC3E,KAAK,GAAG,IACb;AACV;AAAA,MACI,OAAO,6BAA6B,0BAC7B,OAAO,cAAc,WAAW,YAAY;AAAA,IAGvD;AACA,SAAK,UAAU;AACf,SAAK,aAAa;AAClB,SAAK,QAAQ;AAAA,EACjB;AAAA,EACA,IAAI,OAAO;AACP,WAAO;AAAA,EACX;AACJ;;;ACnCO,IAAM,qBAAwE;AAAA,EACjF,kBAAkB,YAAY,SAAS,OAAO;AAC1C,UAAM,IAAI,kCAAkC,YAAY,SAAS,KAAK;AAAA,EAC1E;AACJ;;;AFJA,SAAS,qBAAqB;AAGvB,SAAS,gBAAgB,QAAiF;AAC7G,SAAO,cAAgC;AAAA,IACnC,GAAG;AAAA,IACH,KAAK,mBAAmB,kBAAkB;AAAA,EAC9C,CAAC;AACL;;;AGXA,SAAS,2BAA2B;AAMpC,SAAS,iBACL,SACiD;AACjD,QAAM,MAA8B,CAAC;AACrC,aAAW,cAAc,SAAS;AAC9B,QAAI,WAAW,YAAY,CAAC,IAAI,QAAQ,UAAU;AAAA,EACtD;AACA,SAAO;AACX;AAEO,SAAS,0BAA0B,QAAkE;AACxG,SAAO,oBAAoB;AAAA,IACvB,GAAG;AAAA,IACH,SAAS;AAAA,MACL,GAAI,OAAO,UAAU,iBAAiB,OAAO,OAAO,IAAI;AAAA,MACxD,GAAI;AAAA;AAAA,QAEA,iBAAiB,MAAM,yBAAiB;AAAA,MAC5C;AAAA,IACJ;AAAA,EACJ,CAAC;AACL","sourcesContent":["export * from '@solana/keys';\nexport * from './rpc';\nexport * from './rpc-transport';\n","import { SolanaRpcMethods, createSolanaRpcApi } from '@solana/rpc-core';\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\n\nimport { createJsonRpc } from '@solana/rpc-transport';\nimport type { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';\n\nexport function createSolanaRpc(config: Omit<Parameters<typeof createJsonRpc>[0], 'api'>): Rpc<SolanaRpcMethods> {\n return createJsonRpc<SolanaRpcMethods>({\n ...config,\n api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n });\n}\n","export class SolanaJsonRpcIntegerOverflowError extends Error {\n readonly methodName: string;\n readonly keyPath: (number | string)[];\n readonly value: bigint;\n constructor(methodName: string, keyPath: (number | string)[], value: bigint) {\n const argPosition = (typeof keyPath[0] === 'number' ? keyPath[0] : parseInt(keyPath[0], 10)) + 1;\n let ordinal = '';\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n ordinal = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n ordinal = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n ordinal = argPosition + 'rd';\n } else {\n ordinal = argPosition + 'th';\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : null;\n super(\n `The ${ordinal} argument to the \\`${methodName}\\` RPC method` +\n `${path ? ` at path \\`${path}\\`` : ''} was \\`${value}\\`. This number is ` +\n 'unsafe for use with the Solana JSON-RPC because it exceeds ' +\n '`Number.MAX_SAFE_INTEGER`.'\n );\n this.keyPath = keyPath;\n this.methodName = methodName;\n this.value = value;\n }\n get name() {\n return 'SolanaJsonRpcIntegerOverflowError';\n }\n}\n","import { createSolanaRpcApi } from '@solana/rpc-core';\nimport { SolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\nexport const DEFAULT_RPC_CONFIG: Partial<Parameters<typeof createSolanaRpcApi>[0]> = {\n onIntegerOverflow(methodName, keyPath, value) {\n throw new SolanaJsonRpcIntegerOverflowError(methodName, keyPath, value);\n },\n};\n","import { createHttpTransport } from '@solana/rpc-transport';\nimport { IRpcTransport } from '@solana/rpc-transport/dist/types/transports/transport-types';\n\n/**\n * Lowercasing header names makes it easier to override user-supplied headers.\n */\nfunction 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\nexport function createDefaultRpcTransport(config: Parameters<typeof createHttpTransport>[0]): IRpcTransport {\n return createHttpTransport({\n ...config,\n headers: {\n ...(config.headers ? normalizeHeaders(config.headers) : undefined),\n ...({\n // Keep these headers lowercase so they will override any user-supplied headers above.\n 'solana-client': `js/${__VERSION__}` ?? 'UNKNOWN',\n } as { [overrideHeader: string]: string }),\n },\n });\n}\n"]}
1
+ {"version":3,"sources":["../../build-scripts/env-shim.ts","../src/index.ts","../src/rpc.ts","../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../src/rpc-transport.ts","../src/rpc-request-coalescer.ts","../src/rpc-request-deduplication.ts","../src/rpc-websocket-transport.ts","../src/rpc-websocket-autopinger.ts","../src/cached-abortable-iterable.ts","../src/rpc-websocket-connection-sharding.ts"],"names":["pipe","args"],"mappings":"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","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 * from '@solana/addresses';\nexport * from '@solana/instructions';\nexport * from '@solana/keys';\nexport * from '@solana/transactions';\nexport * from './rpc';\nexport * from './rpc-transport';\nexport * from './rpc-websocket-transport';\n","import {\n createSolanaRpcApi,\n createSolanaRpcSubscriptionsApi,\n SolanaRpcMethods,\n SolanaRpcSubscriptions,\n} from '@solana/rpc-core';\nimport { createJsonRpc, createJsonSubscriptionRpc } from '@solana/rpc-transport';\nimport type { Rpc, RpcSubscriptions } from '@solana/rpc-transport/dist/types/json-rpc-types';\n\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\n\nexport function createSolanaRpc(config: Omit<Parameters<typeof createJsonRpc>[0], 'api'>): Rpc<SolanaRpcMethods> {\n return createJsonRpc({\n ...config,\n api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n });\n}\n\nexport function createSolanaRpcSubscriptions(\n config: Omit<Parameters<typeof createJsonSubscriptionRpc>[0], 'api'>\n): RpcSubscriptions<SolanaRpcSubscriptions> {\n return createJsonSubscriptionRpc({\n ...config,\n api: createSolanaRpcSubscriptionsApi(DEFAULT_RPC_CONFIG),\n });\n}\n","export class SolanaJsonRpcIntegerOverflowError extends Error {\n readonly methodName: string;\n readonly keyPath: (number | string)[];\n readonly value: bigint;\n constructor(methodName: string, keyPath: (number | string)[], value: bigint) {\n const argPosition = (typeof keyPath[0] === 'number' ? keyPath[0] : parseInt(keyPath[0], 10)) + 1;\n let ordinal = '';\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n ordinal = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n ordinal = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n ordinal = argPosition + 'rd';\n } else {\n ordinal = argPosition + 'th';\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : null;\n super(\n `The ${ordinal} argument to the \\`${methodName}\\` RPC method` +\n `${path ? ` at path \\`${path}\\`` : ''} was \\`${value}\\`. This number is ` +\n 'unsafe for use with the Solana JSON-RPC because it exceeds ' +\n '`Number.MAX_SAFE_INTEGER`.'\n );\n this.keyPath = keyPath;\n this.methodName = methodName;\n this.value = value;\n }\n get name() {\n return 'SolanaJsonRpcIntegerOverflowError';\n }\n}\n","import { createSolanaRpcApi } from '@solana/rpc-core';\n\nimport { SolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\nexport const DEFAULT_RPC_CONFIG: Partial<Parameters<typeof createSolanaRpcApi>[0]> = {\n onIntegerOverflow(methodName, keyPath, value) {\n throw new SolanaJsonRpcIntegerOverflowError(methodName, keyPath, value);\n },\n};\n","import { pipe } from '@solana/functional';\nimport { createHttpTransport } from '@solana/rpc-transport';\nimport { IRpcTransport } from '@solana/rpc-transport/dist/types/transports/transport-types';\n\nimport { getRpcTransportWithRequestCoalescing } from './rpc-request-coalescer';\nimport { getSolanaRpcPayloadDeduplicationKey } from './rpc-request-deduplication';\n\n/**\n * Lowercasing header names makes it easier to override user-supplied headers.\n */\nfunction 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\nexport function createDefaultRpcTransport(config: Parameters<typeof createHttpTransport>[0]): IRpcTransport {\n return pipe(\n createHttpTransport({\n ...config,\n headers: {\n ...(config.headers ? normalizeHeaders(config.headers) : undefined),\n ...({\n // Keep these headers lowercase so they will override any user-supplied headers above.\n 'solana-client': `js/${__VERSION__}` ?? 'UNKNOWN',\n } as { [overrideHeader: string]: string }),\n },\n }),\n transport => getRpcTransportWithRequestCoalescing(transport, getSolanaRpcPayloadDeduplicationKey)\n );\n}\n","import { IRpcTransport } from '@solana/rpc-transport/dist/types/transports/transport-types';\n\ntype CoalescedRequest = {\n readonly abortController: AbortController;\n numConsumers: number;\n readonly responsePromise: Promise<unknown>;\n};\n\ntype GetDeduplicationKeyFn = (payload: unknown) => string | undefined;\n\nexport function getRpcTransportWithRequestCoalescing(\n transport: IRpcTransport,\n getDeduplicationKey: GetDeduplicationKeyFn\n): IRpcTransport {\n let coalescedRequestsByDeduplicationKey: Record<string, CoalescedRequest> | undefined;\n return async function makeCoalescedHttpRequest<TResponse>(\n config: Parameters<IRpcTransport>[0]\n ): Promise<TResponse> {\n const { payload, signal } = config;\n const deduplicationKey = getDeduplicationKey(payload);\n if (deduplicationKey === undefined) {\n return await transport(config);\n }\n if (!coalescedRequestsByDeduplicationKey) {\n Promise.resolve().then(() => {\n coalescedRequestsByDeduplicationKey = undefined;\n });\n coalescedRequestsByDeduplicationKey = {};\n }\n if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {\n const abortController = new AbortController();\n coalescedRequestsByDeduplicationKey[deduplicationKey] = {\n abortController,\n numConsumers: 0,\n responsePromise: transport<TResponse>({\n ...config,\n signal: abortController.signal,\n }),\n };\n }\n const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];\n coalescedRequest.numConsumers++;\n if (signal) {\n const responsePromise = coalescedRequest.responsePromise as Promise<TResponse>;\n return await new Promise<TResponse>((resolve, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n signal.removeEventListener('abort', handleAbort);\n coalescedRequest.numConsumers -= 1;\n if (coalescedRequest.numConsumers === 0) {\n const abortController = coalescedRequest.abortController;\n abortController.abort();\n }\n const abortError = new DOMException((e.target as AbortSignal).reason, 'AbortError');\n reject(abortError);\n };\n signal.addEventListener('abort', handleAbort);\n responsePromise.then(resolve).finally(() => {\n signal.removeEventListener('abort', handleAbort);\n });\n });\n } else {\n return (await coalescedRequest.responsePromise) as TResponse;\n }\n };\n}\n","// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport fastStableStringify from 'fast-stable-stringify';\n\nfunction isJsonRpcPayload(payload: unknown): payload is Readonly<{ method: string; params: unknown }> {\n if (payload == null || typeof payload !== 'object' || Array.isArray(payload)) {\n return false;\n }\n return (\n 'jsonrpc' in payload &&\n payload.jsonrpc === '2.0' &&\n 'method' in payload &&\n typeof payload.method === 'string' &&\n 'params' in payload\n );\n}\n\nexport function getSolanaRpcPayloadDeduplicationKey(payload: unknown): string | undefined {\n return isJsonRpcPayload(payload) ? fastStableStringify([payload.method, payload.params]) : undefined;\n}\n\nexport function getSolanaRpcSubscriptionPayloadDeduplicationKey(payload: unknown): string | undefined {\n return isJsonRpcPayload(payload) && payload.method.endsWith('Subscribe')\n ? fastStableStringify([payload.method, payload.params])\n : undefined;\n}\n","import { pipe } from '@solana/functional';\nimport { createWebSocketTransport } from '@solana/rpc-transport';\nimport { IRpcWebSocketTransport } from '@solana/rpc-transport/dist/types/transports/transport-types';\n\nimport { getWebSocketTransportWithAutoping } from './rpc-websocket-autopinger';\nimport { getWebSocketTransportWithConnectionSharding } from './rpc-websocket-connection-sharding';\n\nexport function createDefaultRpcSubscriptionsTransport(\n config: Omit<Parameters<typeof createWebSocketTransport>[0], 'sendBufferHighWatermark'> & {\n /**\n * You might like to open more subscriptions per connection than your RPC provider allows\n * for. Using the initial payload as input, return a shard key from this method to assign\n * subscriptions to separate connections. One socket will be opened per shard key.\n */\n getShard?: (payload: unknown) => string;\n intervalMs?: number;\n sendBufferHighWatermark?: number;\n }\n): IRpcWebSocketTransport {\n const { getShard, intervalMs, ...rest } = config;\n return pipe(\n createWebSocketTransport({\n ...rest,\n sendBufferHighWatermark:\n config.sendBufferHighWatermark ??\n // Let 128KB of data into the WebSocket buffer before buffering it in the app.\n 131_072,\n }),\n transport =>\n getWebSocketTransportWithAutoping({\n intervalMs: intervalMs ?? 5_000,\n transport,\n }),\n transport =>\n getWebSocketTransportWithConnectionSharding({\n getShard,\n transport,\n })\n );\n}\n","import { IRpcWebSocketTransport } from '@solana/rpc-transport/dist/types/transports/transport-types';\n\ntype Config = Readonly<{\n intervalMs: number;\n transport: IRpcWebSocketTransport;\n}>;\n\nconst PING_PAYLOAD = {\n jsonrpc: '2.0',\n method: 'ping',\n} as const;\n\nexport function getWebSocketTransportWithAutoping({ intervalMs, transport }: Config): IRpcWebSocketTransport {\n const pingableConnections = new Map<\n Awaited<ReturnType<IRpcWebSocketTransport>>,\n Awaited<ReturnType<IRpcWebSocketTransport>>\n >();\n return async (...args) => {\n const connection = await transport(...args);\n let intervalId: string | number | NodeJS.Timeout | undefined;\n function sendPing() {\n connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(PING_PAYLOAD);\n }\n function restartPingTimer() {\n clearInterval(intervalId);\n intervalId = setInterval(sendPing, intervalMs);\n }\n if (pingableConnections.has(connection) === false) {\n pingableConnections.set(connection, {\n [Symbol.asyncIterator]: connection[Symbol.asyncIterator].bind(connection),\n send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: (\n ...args: Parameters<typeof connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>\n ) => {\n restartPingTimer();\n return connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(...args);\n },\n });\n (async () => {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for await (const _ of connection) {\n restartPingTimer();\n }\n } catch {\n /* empty */\n } finally {\n pingableConnections.delete(connection);\n clearInterval(intervalId);\n if (handleOffline) {\n globalThis.window.removeEventListener('offline', handleOffline);\n }\n if (handleOnline) {\n globalThis.window.removeEventListener('online', handleOnline);\n }\n }\n })();\n if (!__BROWSER__ || globalThis.navigator.onLine) {\n restartPingTimer();\n }\n let handleOffline;\n let handleOnline;\n if (__BROWSER__) {\n handleOffline = () => {\n clearInterval(intervalId);\n };\n handleOnline = () => {\n sendPing();\n restartPingTimer();\n };\n globalThis.window.addEventListener('offline', handleOffline);\n globalThis.window.addEventListener('online', handleOnline);\n }\n }\n return pingableConnections.get(connection)!;\n };\n}\n","type CacheEntry<TIterable extends AsyncIterable<unknown>> = {\n abortController: AbortController;\n iterable: Promise<TIterable> | TIterable;\n purgeScheduled: boolean;\n referenceCount: number;\n};\ntype CacheKey = string | symbol;\ntype Config<TInput extends unknown[], TIterable extends AsyncIterable<unknown>> = Readonly<{\n getAbortSignalFromInputArgs: (...args: TInput) => AbortSignal;\n getCacheEntryMissingError: (cacheKey: CacheKey) => Error;\n getCacheKeyFromInputArgs: (...args: TInput) =>\n | CacheKey\n // `undefined` implies 'do not cache'\n | undefined;\n onCacheHit: (iterable: TIterable, ...args: TInput) => Promise<void>;\n onCreateIterable: (abortSignal: AbortSignal, ...args: TInput) => Promise<TIterable>;\n}>;\n\nfunction registerIterableCleanup(iterable: AsyncIterable<unknown>, cleanupFn: CallableFunction) {\n (async () => {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for await (const _ of iterable);\n } catch {\n /* empty */\n } finally {\n // Run the cleanup function.\n cleanupFn();\n }\n })();\n}\n\nexport function getCachedAbortableIterableFactory<TInput extends unknown[], TIterable extends AsyncIterable<unknown>>({\n getAbortSignalFromInputArgs,\n getCacheEntryMissingError,\n getCacheKeyFromInputArgs,\n onCacheHit,\n onCreateIterable,\n}: Config<TInput, TIterable>): (...args: TInput) => Promise<TIterable> {\n const cache = new Map<CacheKey, CacheEntry<TIterable>>();\n function getCacheEntryOrThrow(cacheKey: CacheKey) {\n const currentCacheEntry = cache.get(cacheKey);\n if (!currentCacheEntry) {\n throw getCacheEntryMissingError(cacheKey);\n }\n return currentCacheEntry;\n }\n return async (...args: TInput) => {\n const cacheKey = getCacheKeyFromInputArgs(...args);\n const signal = getAbortSignalFromInputArgs(...args);\n if (cacheKey === undefined) {\n return await onCreateIterable(signal, ...args);\n }\n const cleanup = () => {\n cache.delete(cacheKey);\n signal.removeEventListener('abort', handleAbort);\n };\n const handleAbort = () => {\n const cacheEntry = getCacheEntryOrThrow(cacheKey);\n if (cacheEntry.purgeScheduled !== true) {\n cacheEntry.purgeScheduled = true;\n globalThis.queueMicrotask(() => {\n cacheEntry.purgeScheduled = false;\n if (cacheEntry.referenceCount === 0) {\n cacheEntry.abortController.abort();\n cleanup();\n }\n });\n }\n cacheEntry.referenceCount--;\n };\n signal.addEventListener('abort', handleAbort);\n try {\n const cacheEntry = cache.get(cacheKey);\n if (!cacheEntry) {\n const singletonAbortController = new AbortController();\n const newIterablePromise = onCreateIterable(singletonAbortController.signal, ...args);\n const newCacheEntry: CacheEntry<TIterable> = {\n abortController: singletonAbortController,\n iterable: newIterablePromise,\n purgeScheduled: false,\n referenceCount: 1,\n };\n cache.set(cacheKey, newCacheEntry);\n const newIterable = await newIterablePromise;\n registerIterableCleanup(newIterable, cleanup);\n newCacheEntry.iterable = newIterable;\n return newIterable;\n } else {\n cacheEntry.referenceCount++;\n const iterableOrIterablePromise = cacheEntry.iterable;\n const cachedIterable =\n 'then' in iterableOrIterablePromise ? await iterableOrIterablePromise : iterableOrIterablePromise;\n await onCacheHit(cachedIterable, ...args);\n return cachedIterable;\n }\n } catch (e) {\n cleanup();\n throw e;\n }\n };\n}\n","import { IRpcWebSocketTransport } from '@solana/rpc-transport/dist/types/transports/transport-types';\n\nimport { getCachedAbortableIterableFactory } from './cached-abortable-iterable';\n\ntype Config = Readonly<{\n /**\n * You might like to open more subscriptions per connection than your RPC provider allows for.\n * Using the initial payload as input, return a shard key from this method to assign\n * subscriptions to separate connections. One socket will be opened per shard key.\n */\n getShard?: (payload: unknown) => string | symbol;\n transport: IRpcWebSocketTransport;\n}>;\n\nconst NULL_SHARD_CACHE_KEY = Symbol(\n __DEV__ ? 'Cache key to use when there is no connection sharding strategy' : undefined\n);\n\nexport function getWebSocketTransportWithConnectionSharding({ getShard, transport }: Config): IRpcWebSocketTransport {\n return getCachedAbortableIterableFactory({\n getAbortSignalFromInputArgs: ({ signal }) => signal,\n getCacheEntryMissingError(shardKey) {\n // TODO: Coded error.\n return new Error(`Found no cache entry for connection with shard key \\`${shardKey?.toString()}\\``);\n },\n getCacheKeyFromInputArgs: ({ payload }) => (getShard ? getShard(payload) : NULL_SHARD_CACHE_KEY),\n onCacheHit: (connection, { payload }) => connection.send_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(payload),\n onCreateIterable: (abortSignal, config) =>\n transport({\n ...config,\n signal: abortSignal,\n }),\n });\n}\n"]}