infura-provider.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. "use strict";
  2. import { Network, Networkish } from "@ethersproject/networks";
  3. import { defineReadOnly } from "@ethersproject/properties";
  4. import { ConnectionInfo } from "@ethersproject/web";
  5. import { WebSocketProvider } from "./websocket-provider";
  6. import { CommunityResourcable, showThrottleMessage } from "./formatter";
  7. import { Logger } from "@ethersproject/logger";
  8. import { version } from "./_version";
  9. const logger = new Logger(version);
  10. import { UrlJsonRpcProvider } from "./url-json-rpc-provider";
  11. const defaultProjectId = "84842078b09946638c03157f83405213"
  12. export class InfuraWebSocketProvider extends WebSocketProvider implements CommunityResourcable {
  13. readonly apiKey: string;
  14. readonly projectId: string;
  15. readonly projectSecret: string;
  16. constructor(network?: Networkish, apiKey?: any) {
  17. const provider = new InfuraProvider(network, apiKey);
  18. const connection = provider.connection;
  19. if (connection.password) {
  20. logger.throwError("INFURA WebSocket project secrets unsupported", Logger.errors.UNSUPPORTED_OPERATION, {
  21. operation: "InfuraProvider.getWebSocketProvider()"
  22. });
  23. }
  24. const url = connection.url.replace(/^http/i, "ws").replace("/v3/", "/ws/v3/");
  25. super(url, network);
  26. defineReadOnly(this, "apiKey", provider.projectId);
  27. defineReadOnly(this, "projectId", provider.projectId);
  28. defineReadOnly(this, "projectSecret", provider.projectSecret);
  29. }
  30. isCommunityResource(): boolean {
  31. return (this.projectId === defaultProjectId);
  32. }
  33. }
  34. export class InfuraProvider extends UrlJsonRpcProvider {
  35. readonly projectId: string;
  36. readonly projectSecret: string;
  37. static getWebSocketProvider(network?: Networkish, apiKey?: any): InfuraWebSocketProvider {
  38. return new InfuraWebSocketProvider(network, apiKey);
  39. }
  40. static getApiKey(apiKey: any): any {
  41. const apiKeyObj: { apiKey: string, projectId: string, projectSecret: string } = {
  42. apiKey: defaultProjectId,
  43. projectId: defaultProjectId,
  44. projectSecret: null
  45. };
  46. if (apiKey == null) { return apiKeyObj; }
  47. if (typeof(apiKey) === "string") {
  48. apiKeyObj.projectId = apiKey;
  49. } else if (apiKey.projectSecret != null) {
  50. logger.assertArgument((typeof(apiKey.projectId) === "string"),
  51. "projectSecret requires a projectId", "projectId", apiKey.projectId);
  52. logger.assertArgument((typeof(apiKey.projectSecret) === "string"),
  53. "invalid projectSecret", "projectSecret", "[REDACTED]");
  54. apiKeyObj.projectId = apiKey.projectId;
  55. apiKeyObj.projectSecret = apiKey.projectSecret;
  56. } else if (apiKey.projectId) {
  57. apiKeyObj.projectId = apiKey.projectId;
  58. }
  59. apiKeyObj.apiKey = apiKeyObj.projectId;
  60. return apiKeyObj;
  61. }
  62. static getUrl(network: Network, apiKey: any): ConnectionInfo {
  63. let host: string = null;
  64. switch(network ? network.name: "unknown") {
  65. case "homestead":
  66. host = "mainnet.infura.io";
  67. break;
  68. case "ropsten":
  69. host = "ropsten.infura.io";
  70. break;
  71. case "rinkeby":
  72. host = "rinkeby.infura.io";
  73. break;
  74. case "kovan":
  75. host = "kovan.infura.io";
  76. break;
  77. case "goerli":
  78. host = "goerli.infura.io";
  79. break;
  80. case "matic":
  81. host = "polygon-mainnet.infura.io";
  82. break;
  83. case "maticmum":
  84. host = "polygon-mumbai.infura.io";
  85. break;
  86. case "optimism":
  87. host = "optimism-mainnet.infura.io";
  88. break;
  89. case "optimism-kovan":
  90. host = "optimism-kovan.infura.io";
  91. break;
  92. case "arbitrum":
  93. host = "arbitrum-mainnet.infura.io";
  94. break;
  95. case "arbitrum-rinkeby":
  96. host = "arbitrum-rinkeby.infura.io";
  97. break;
  98. default:
  99. logger.throwError("unsupported network", Logger.errors.INVALID_ARGUMENT, {
  100. argument: "network",
  101. value: network
  102. });
  103. }
  104. const connection: ConnectionInfo = {
  105. allowGzip: true,
  106. url: ("https:/" + "/" + host + "/v3/" + apiKey.projectId),
  107. throttleCallback: (attempt: number, url: string) => {
  108. if (apiKey.projectId === defaultProjectId) {
  109. showThrottleMessage();
  110. }
  111. return Promise.resolve(true);
  112. }
  113. };
  114. if (apiKey.projectSecret != null) {
  115. connection.user = "";
  116. connection.password = apiKey.projectSecret
  117. }
  118. return connection;
  119. }
  120. isCommunityResource(): boolean {
  121. return (this.projectId === defaultProjectId);
  122. }
  123. }