Source

Web3Connection.js

  1. import Web3 from 'web3';
  2. import Account from './utils/Account';
  3. const ETH_URL_TESTNET = 'https://rinkeby.infura.io/v3/811fe4fa5c4b41cb9b92f9656aaeaa3b';
  4. // you can find this in "./truffle-config.js" file and should match ganache/ganache-cli local server settings too
  5. const ETH_URL_LOCAL_TEST = 'http://localhost:8545';
  6. const TEST_PRIVATE_KEY = '0x7f76de05082c4d578219ca35a905f8debe922f1f00b99315ebf0706afc97f132';
  7. // const LOCAL_TEST_PRIVATE_KEY = '4f4f26f4a82351b1f9a98623f901ad5fb2f3e38ac92ff39955ee8e124c718fa7';
  8. const networksEnum = Object.freeze({
  9. 1: 'Ethereum Main',
  10. 2: 'Morden',
  11. 3: 'Ropsten',
  12. 4: 'Rinkeby',
  13. 56: 'BSC Main',
  14. 97: 'BSC Test',
  15. 42: 'Kovan',
  16. });
  17. /**
  18. * @typedef {Object} Web3Connection~Optional
  19. * @property {string} web3Connection Web3 Connection String (Ex : https://data-seed-prebsc-1-s1.binance.org:8545)
  20. * @property {string} privateKey Private key (0x....) used for server side use
  21. */
  22. /**
  23. * @typedef {Object} Web3Connection~Options
  24. * @property {boolean} [test=false] Automated Tests
  25. * @property {boolean} [localtest=false] Ganache Local Blockchain
  26. * @property {web3Connection~Optional} [opt] Optional Chain Connection Object (Default ETH)
  27. * @property {provider~Optional} [opt] Directly supply any web3 provider, automatically calls start()
  28. */
  29. /**
  30. * Web3Connection Object
  31. * @class Web3Connection
  32. * @param {Web3Connection~Options} options
  33. */
  34. class Web3Connection {
  35. constructor({
  36. test = false, // Automated tests
  37. localtest = false, // ganache local blockchain
  38. opt = {
  39. privateKey: TEST_PRIVATE_KEY,
  40. provider: null,
  41. web3Connection: ETH_URL_TESTNET,
  42. },
  43. }) {
  44. this.test = test;
  45. this.localtest = localtest;
  46. this.opt = opt;
  47. // If a provider is supplied, we assume all connection logic is on its side.
  48. if (opt.provider) {
  49. this.start(opt.provider);
  50. }
  51. if (this.test) {
  52. this.start();
  53. this.login();
  54. if (!this.localtest) {
  55. this.account = new Account(
  56. this.web3,
  57. this.web3.eth.accounts.privateKeyToAccount(opt.privateKey),
  58. );
  59. }
  60. }
  61. }
  62. /** **** */
  63. /** * CORE */
  64. /** **** */
  65. /**
  66. * Connect to Web3 injected in the constructor
  67. * @function
  68. * @typedef {provider~Optional} [opt] Directly supply any web3 provider, to skip both start() and login()
  69. * @throws {Error} Please Use an Ethereum Enabled Browser like Metamask or Coinbase Wallet
  70. * @void
  71. */
  72. start(provider) {
  73. if (provider) {
  74. this.web3 = new Web3(provider);
  75. }
  76. else if (this.localtest) {
  77. this.web3 = new Web3(
  78. new Web3.providers.HttpProvider(ETH_URL_LOCAL_TEST),
  79. // NOTE: depending on your web3 version, you may need to set a number of confirmation blocks
  80. null,
  81. { transactionConfirmationBlocks: 1 },
  82. );
  83. }
  84. else if (this.opt.web3Connection.toLowerCase().includes('http')) {
  85. this.web3 = new Web3(new Web3.providers.HttpProvider(this.opt.web3Connection));
  86. }
  87. else {
  88. this.web3 = new Web3(new Web3.providers.WebsocketProvider(this.opt.web3Connection));
  89. }
  90. if (!this.localtest && this.test) {
  91. this.account = new Account(
  92. this.web3,
  93. this.web3.eth.accounts.privateKeyToAccount(this.opt.privateKey),
  94. );
  95. }
  96. if (typeof window !== 'undefined') {
  97. window.web3 = this.web3;
  98. }
  99. else if (!this.test) {
  100. throw new Error(
  101. 'Please Use an Ethereum Enabled Browser like Metamask or Coinbase Wallet',
  102. );
  103. }
  104. }
  105. /**
  106. * Login with Metamask/Web3 Wallet - substitutes start()
  107. * @function
  108. * @return {Promise<boolean>}
  109. */
  110. async login() {
  111. if (typeof window === 'undefined') {
  112. return false;
  113. }
  114. if (window.ethereum) {
  115. window.web3 = new Web3(window.ethereum);
  116. this.web3 = window.web3;
  117. await window.ethereum.enable();
  118. return true;
  119. }
  120. return false;
  121. }
  122. /** ***** */
  123. /** UTILS */
  124. /** ***** */
  125. /**
  126. * Get ETH Network
  127. * @function
  128. * @return {Promise<string>} Network Name (Ex : Kovan)
  129. */
  130. async getETHNetwork() {
  131. const netId = await this.web3.eth.net.getId();
  132. // eslint-disable-next-line no-prototype-builtins
  133. const networkName = networksEnum.hasOwnProperty(netId)
  134. ? networksEnum[netId]
  135. : await this.web3.currentProvider.host; // 'Unknown';
  136. return networkName;
  137. }
  138. /**
  139. * Get current/selected account in use if available,
  140. * or selected signer wallet/address otherwise.
  141. * @function
  142. * @return {Promise<string>} Account/Wallet in use
  143. */
  144. getCurrentAccount() {
  145. if (this.account) {
  146. return this.account;
  147. }
  148. // return selected wallet in use otherwise
  149. return this.getAddress();
  150. }
  151. /**
  152. * Get Address connected
  153. * @function
  154. * @return {Promise<string>} Address in Use
  155. */
  156. async getAddress() {
  157. if (this.account) {
  158. return this.account.getAddress();
  159. }
  160. const accounts = await this.web3.eth.getAccounts();
  161. return accounts[0];
  162. }
  163. /**
  164. * Get accounts connected via login()
  165. * @function
  166. * @return {Promise<Array<string>>} Addresses array available
  167. */
  168. async getAccounts() {
  169. return this.account
  170. ? [ this.account.getAddress() ]
  171. : this.web3.eth.getAccounts();
  172. }
  173. /**
  174. * Get ETH Balance of Address connected
  175. * @function
  176. * @return {Promise<string>} ETH Balance
  177. */
  178. async getETHBalance() {
  179. const address = await this.getAddress();
  180. const wei = await this.web3.eth.getBalance(address);
  181. return this.web3.utils.fromWei(wei, 'ether');
  182. }
  183. /**
  184. * Get Web3 to access functions as https://ethereum.stackexchange.com/questions/66454/how-to-get-events-emitted-by-a-transaction-with-web3-js
  185. * @function
  186. * @return {Web3} Web3
  187. */
  188. getWeb3() {
  189. return this.web3;
  190. }
  191. }
  192. export default Web3Connection;