provider-browser.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import { assertArgument } from "../utils/index.js";
  2. import { JsonRpcApiPollingProvider } from "./provider-jsonrpc.js";
  3. ;
  4. /**
  5. * A **BrowserProvider** is intended to wrap an injected provider which
  6. * adheres to the [[link-eip-1193]] standard, which most (if not all)
  7. * currently do.
  8. */
  9. export class BrowserProvider extends JsonRpcApiPollingProvider {
  10. #request;
  11. /**
  12. * Connect to the %%ethereum%% provider, optionally forcing the
  13. * %%network%%.
  14. */
  15. constructor(ethereum, network, _options) {
  16. // Copy the options
  17. const options = Object.assign({}, ((_options != null) ? _options : {}), { batchMaxCount: 1 });
  18. assertArgument(ethereum && ethereum.request, "invalid EIP-1193 provider", "ethereum", ethereum);
  19. super(network, options);
  20. this.#request = async (method, params) => {
  21. const payload = { method, params };
  22. this.emit("debug", { action: "sendEip1193Request", payload });
  23. try {
  24. const result = await ethereum.request(payload);
  25. this.emit("debug", { action: "receiveEip1193Result", result });
  26. return result;
  27. }
  28. catch (e) {
  29. const error = new Error(e.message);
  30. error.code = e.code;
  31. error.data = e.data;
  32. error.payload = payload;
  33. this.emit("debug", { action: "receiveEip1193Error", error });
  34. throw error;
  35. }
  36. };
  37. }
  38. async send(method, params) {
  39. await this._start();
  40. return await super.send(method, params);
  41. }
  42. async _send(payload) {
  43. assertArgument(!Array.isArray(payload), "EIP-1193 does not support batch request", "payload", payload);
  44. try {
  45. const result = await this.#request(payload.method, payload.params || []);
  46. return [{ id: payload.id, result }];
  47. }
  48. catch (e) {
  49. return [{
  50. id: payload.id,
  51. error: { code: e.code, data: e.data, message: e.message }
  52. }];
  53. }
  54. }
  55. getRpcError(payload, error) {
  56. error = JSON.parse(JSON.stringify(error));
  57. // EIP-1193 gives us some machine-readable error codes, so rewrite
  58. // them into
  59. switch (error.error.code || -1) {
  60. case 4001:
  61. error.error.message = `ethers-user-denied: ${error.error.message}`;
  62. break;
  63. case 4200:
  64. error.error.message = `ethers-unsupported: ${error.error.message}`;
  65. break;
  66. }
  67. return super.getRpcError(payload, error);
  68. }
  69. /**
  70. * Resolves to ``true`` if the provider manages the %%address%%.
  71. */
  72. async hasSigner(address) {
  73. if (address == null) {
  74. address = 0;
  75. }
  76. const accounts = await this.send("eth_accounts", []);
  77. if (typeof (address) === "number") {
  78. return (accounts.length > address);
  79. }
  80. address = address.toLowerCase();
  81. return accounts.filter((a) => (a.toLowerCase() === address)).length !== 0;
  82. }
  83. async getSigner(address) {
  84. if (address == null) {
  85. address = 0;
  86. }
  87. if (!(await this.hasSigner(address))) {
  88. try {
  89. //const resp =
  90. await this.#request("eth_requestAccounts", []);
  91. //console.log("RESP", resp);
  92. }
  93. catch (error) {
  94. const payload = error.payload;
  95. throw this.getRpcError(payload, { id: payload.id, error });
  96. }
  97. }
  98. return await super.getSigner(address);
  99. }
  100. }
  101. //# sourceMappingURL=provider-browser.js.map