From bb42490e6f3974e4264baf46ff0ffafaf2e6ca55 Mon Sep 17 00:00:00 2001 From: Themvp07 <44710716+Themvp07@users.noreply.github.com> Date: Sun, 11 Jun 2023 10:55:17 +0200 Subject: [PATCH 1/2] web3plugin --- .gitignore | 39 +++++++ README.md | 137 +++++++++++++++++++++--- TempAPI.sol | 106 ------------------ package.json | 29 +++++ src/index.ts | 2 + src/qrcode_plugin.ts | 183 ++++++++++++++++++++++++++++++++ src/types.ts | 28 +++++ test/config/jest.config.js | 40 +++++++ test/config/setup.js | 7 ++ test/tsconfig.json | 8 ++ test/unit/jest.config.js | 9 ++ test/unit/qrcode_plugin.test.ts | 105 ++++++++++++++++++ tsconfig.json | 25 +++++ 13 files changed, 597 insertions(+), 121 deletions(-) create mode 100644 .gitignore delete mode 100644 TempAPI.sol create mode 100644 package.json create mode 100644 src/index.ts create mode 100644 src/qrcode_plugin.ts create mode 100644 src/types.ts create mode 100644 test/config/jest.config.js create mode 100644 test/config/setup.js create mode 100644 test/tsconfig.json create mode 100644 test/unit/jest.config.js create mode 100644 test/unit/qrcode_plugin.test.ts create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e831804 --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +# General +.DS_Store +*.swp +*.orig + +# Logs +logs +*.log +npm-debug.log* + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# nyc test coverage +.nyc_output + +# Dependency directories +node_modules + +# Optional npm cache directory +.npm +.coverage +.tool-versions + +# IDE directories +.idea +tmp + +# Distribution directory +.vscode +lib/ +dist/ +tsconfig.tsbuildinfo + +# Unsupported lock files +package-lock.json + +tmp/ +.npmrc \ No newline at end of file diff --git a/README.md b/README.md index 1db8a13..3d409cc 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,122 @@ -# ChainTrust -There are 3 actors in this workflow. -Each of them there are controladed by value at variables. When client seller and deliver have value =1 an automated external method is activated. When deliver completed their process and his state change to 0 a flag is activated to indicate that the workflow has been completed. -There is a flag that change it´s value to 1 that can be used to generate a prof of delivery. - -Instructions: -network : sepolia - --Compile --Deploy SC --Send 0.3 link to contract address --Execute function to request temperature --Copy SC address. --Add SC address to At Address and press on “At Address” --Request Temperature +# Web3.js QR Code Plugin + +![ES Version](https://img.shields.io/badge/ES-2020-yellow) +![Node Version](https://img.shields.io/badge/node-18.x-green) + +This is a [web3.js](https://github.com/web3/web3.js) `4.x` plugin to generate payable QR Codes. + +## Prerequisites + +- :gear: [NodeJS](https://nodejs.org/) (LTS/Fermium) + +## Installation + +```bash +npm i @Themvp07/qr-web3 +``` +## Using this plugin + +### Installing Version `4.x` of `web3` + +When adding the `web3` package to your project, make sure to use version `4.x`. You can append `@4.0.2-dev.af57eae.0` tag to install the latest version of 4 that this plugin was tested with: + +- `npm i -S web3@4.0.2-dev.af57eae.0` +- `yarn add web3@4.0.2-dev.af57eae.0` + +> **_NOTE_** +> If 4.x was already released, you are good to just use `web3` without appending anything to it. + +To verify you have the correct `web3` version installed, after adding the package to your project (the above commands), look at the versions listed in your project's `package.json` under the `dependencies` section, it should contain version 4.x similar to: + +```json +"dependencies": { + "web3": "4.0.2-dev.af57eae.0" +} +``` +### Registering the Plugin with a web3.js Instance + +After importing `QRCodePlugin` from `@Themvp07/qr-web3` and `Web3` from `web3`, register an instance of `QRCodePlugin` with an instance of `Web3` like so: + +```typescript +import { QRCodePlugin } from '@Themvp07/qr-web3'; +import { Web3 } from 'web3'; + +const web3 = new Web3('YOUR_PROVIDER_URL'); +const qrCodePlugin = new QRCodePlugin(); + +web3.registerPlugin(qrCodePlugin); +``` + +More information about registering web3.js plugins can be found [here](https://docs.web3js.org/docs/guides/web3_plugin_guide/plugin_users#registering-the-plugin). + +### Plugin Methods + +#### Get QR Code to transfer ETH in Ethereum Mainnet + +#### `getQrEthereumMainnet` + +```typescript +async getQrEthereumMainnet( + ethMainnetParams: IETHMainnet + ): { + QRCode // In base64 format + } +``` + +#### Get QR Code to transfer ETH in Ethereum Testnet + +#### `getQrEthereumTestnet` + +```typescript +async getQrEthereumTestnet( + ethTestnetParams: IETHTestnet + ): { + QRCode // In base64 format + } +``` + +#### Get QR Code for transfer Custom ERC20 Token in Ethereum Mainnet + +#### `getQrEthereumMainnetCustomERC20` + +```typescript +async getQrEthereumMainnetCustomERC20( + ethMainnetCustomERC20Params: IETHMainnetCustomERC20 + ): { + QRCode // In base64 format + } +``` + +#### Get QR Code for transfer Custom ERC20 Token in Ethereum Mainnet + +#### `getQrEthereumTestnetCustomERC20` + +```typescript +async getQrEthereumTestnetCustomERC20( + ethTestnetCustomERC20Params: IETHTestnetCustomERC20 + ): { + QRCode // In base64 format + } +``` + +## Example +```typescript +import { QRCodePlugin } from '@Themvp07/qr-web3'; +import { Web3 } from 'web3'; + +const web3 = new Web3('YOUR_PROVIDER_URL'); +const qrCodePlugin = new QRCodePlugin(); + +web3.registerPlugin(qrCodePlugin); + +const qrData = { + to: '0x7772fb5804c9C60B76C56aBEEb79f2F6d54519C4', // SOME ADDRESS TO TRANSFER + value: '0.1' // SOME VALUE 0.1 ETH + }; + +const qr = await web3.qrcode.getQrEthereumMainnet(qrData); +console.log(qr); +``` +## Useful links + +[base64-to-image-converter](https://codebeautify.org/base64-to-image-converter) diff --git a/TempAPI.sol b/TempAPI.sol deleted file mode 100644 index bf8ddd0..0000000 --- a/TempAPI.sol +++ /dev/null @@ -1,106 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.7; - -import '@chainlink/contracts/src/v0.8/ChainlinkClient.sol'; -import '@chainlink/contracts/src/v0.8/ConfirmedOwner.sol'; -//import 'hardhat/console.sol'; - -/** - * Request testnet LINK and ETH here: https://faucets.chain.link/ - * Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/ - */ - -/** - * THIS IS AN EXAMPLE CONTRACT WHICH USES HARDCODED VALUES FOR CLARITY. - * THIS EXAMPLE USES UN-AUDITED CODE. - * DO NOT USE THIS CODE IN PRODUCTION. - */ - -contract APIConsumer is ChainlinkClient, ConfirmedOwner { - using Chainlink for Chainlink.Request; - - uint256 public temperature; - uint256 public client; - uint256 public seller; - uint256 public delivery; - uint256 public automate; - uint256 public fnft = 0; - bytes32 private jobId; - uint256 private fee; - - event RequestTemperature(bytes32 indexed requestId, uint256 temperature); - - /** - * @notice Initialize the link token and target oracle - - * Sapolia Testnet details: - */ - - constructor() ConfirmedOwner(msg.sender) { - setChainlinkToken(0x779877A7B0D9E8603169DdbD7836e478b4624789); - setChainlinkOracle(0x6090149792dAAeE9D1D568c9f9a6F6B46AA29eFD); - jobId = 'ca98366cc7314957b8c012c72f05aeeb'; - fee = (1 * LINK_DIVISIBILITY) / 10; // 0,1 * 10**18 (Varies by network and job) - - } - - /** - * Create a Chainlink request to retrieve API response, find the target - * data, then multiply by 1000000000000000000 (to remove decimal places from data). - */ - function requestTemperatureData() public returns (bytes32 requestId) { - Chainlink.Request memory req = buildChainlinkRequest(jobId, address(this), this.fulfill.selector); - - // Set the URL to perform the GET request on - - req.add('get', 'http://34.170.142.252:8000/readings'); - - req.add('path', 'temperature'); - - int256 timesAmount = 1**1; - req.addInt('times', timesAmount); - - // Sends the request - return sendChainlinkRequest(req, fee); - } - - /** - * Receive the response in the form of uint256 - */ - function fulfill(bytes32 _requestId, uint256 _temperature) public recordChainlinkFulfillment(_requestId) { - temperature = _temperature; - emit RequestTemperature(_requestId, _temperature); - - } - - function setClient(uint256 _newClient) public { - client = _newClient; - } - - function setSeller(uint256 _newSeller) public { - seller = _newSeller; - } - - function setDelivery(uint256 _newDellivery) public { - delivery = _newDellivery; - if (delivery == 1 && seller == 1) - { - requestTemperatureData(); - automate = 1; - } - if (delivery == 0 && seller == 0) - { - automate = 0; - fnft = 1; - } - } - - - /** - * Allow withdraw of Link tokens from the contract - */ - function withdrawLink() public onlyOwner { - LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress()); - require(link.transfer(msg.sender, link.balanceOf(address(this))), 'Unable to transfer'); - } -} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..6b3dbb0 --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "name": "qr-web3", + "version": "1.0.0", + "description": "A Web3.js 4.x Plugin for creating Payable QR Codes", + "main": "lib/index.js", + "scripts": { + "build": "tsc --build", + "test": "jest --config=./test/unit/jest.config.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "@types/jest": "^29.5.2", + "@types/node": "^20.3.0", + "@types/qrcode": "^1.5.0", + "jest": "^29.5.0", + "qrcode": "^1.5.3", + "typescript": "^5.1.3", + "web3": "^4.0.2-dev.af57eae.0" + }, + "peerDependencies": { + "web3": ">= 4.0.2-dev.af57eae.0 < 5" + }, + "dependencies": { + "jest-extended": "^4.0.0", + "ts-jest": "^29.1.0" + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..ac2cb41 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,2 @@ +export * from './types'; +export * from './qrcode_plugin'; \ No newline at end of file diff --git a/src/qrcode_plugin.ts b/src/qrcode_plugin.ts new file mode 100644 index 0000000..533f18e --- /dev/null +++ b/src/qrcode_plugin.ts @@ -0,0 +1,183 @@ +import { Web3, Web3PluginBase, validator } from 'web3'; +import { ChainId, IETHMainnet, IETHMainnetCustomERC20, IETHTestnet, IETHTestnetCustomERC20, } from './types'; +import QRCode from 'qrcode'; + +export class QRCodePlugin extends Web3PluginBase { + public pluginNamespace: string; + + public constructor(options?: { + pluginNamespace?: string; + }) { + super(); + this.pluginNamespace = options?.pluginNamespace ?? 'qrcode'; + } + + /** + * + * Generates a QR code according to EIP-681 ("URI Scheme to facilitate ERC20 token payments"). + * The QR code represents a URI for an Ethereum transaction on the mainnet. + * + * @returns A QR code as a string, which encodes a URI for an Ethereum transaction on the mainnet according to EIP-681. + */ + public async getQrEthereumMainnet(ethMainnetParams: IETHMainnet) { + try { + const { to, value } = ethMainnetParams; + + if (!validator.isAddress(to)) { + throw new Error( + `Provided 'to' address is not a valid Ethereum address: ${to}`, + ); + } + + if (typeof value !== 'string' || isNaN(Number(value)) || Number(value) < 0) { + throw new Error( + `Provided 'value' is not a valid amount of Ether: ${value}`, + ); + } + + let valueWei = Web3.utils.toWei(value, 'ether'); + const qrData = `ethereum:${to}@${ChainId.MAINNET}?value=${valueWei}`; + + const qr = await QRCode.toDataURL(qrData); + return qr; + + } catch (error) { + throw error; + } + } + + + /** + * + * Generates a QR code according to EIP-681 ("URI Scheme to facilitate ERC20 token payments"). + * The QR code represents a URI for an Ethereum transaction on the testnet. + * + * @returns A QR code as a string, which encodes a URI for an Ethereum transaction on the testnet according to EIP-681. + */ + public async getQrEthereumTestnet(ethTestnetParams: IETHTestnet) { + try { + const { to, value, chainId } = ethTestnetParams; + + if (!validator.isAddress(to)) { + throw new Error( + `Provided 'to' address is not a valid Ethereum address: ${to}`, + ); + } + + if (typeof value !== 'string' || isNaN(Number(value)) || Number(value) < 0) { + throw new Error( + `Provided 'value' is not a valid amount of Ether: ${value}`, + ); + } + + if (typeof chainId !== 'number' || chainId < 0) { + throw new Error( + `Provided 'chainId' is not a valid chainId: ${chainId}`, + ); + } + + let valueWei = Web3.utils.toWei(value, 'ether'); + const qrData = `ethereum:${to}@${chainId}?value=${valueWei}`; + + const qr = await QRCode.toDataURL(qrData); + return qr; + + } catch (error) { + throw error; + } + } + + /** + * + * Generates a QR code according to EIP-681 ("URI Scheme to facilitate ERC20 token payments"). + * The QR code represents a URI for an Ethereum transaction on the mainnet. + * + * @returns A QR code as a string, which encodes a URI for an Ethereum transaction on the mainnet for ERC20 according to EIP-681. + */ + public async getQrEthereumMainnetCustomERC20(ethMainnetCustomERC20Params: IETHMainnetCustomERC20) { + try { + const { erc20, to, value } = ethMainnetCustomERC20Params; + + if (!validator.isAddress(erc20)) { + throw new Error( + `Provided 'erc20' address is not a valid ERC20 Contract address: ${erc20}`, + ); + } + + if (!validator.isAddress(to)) { + throw new Error( + `Provided 'to' address is not a valid Ethereum address: ${to}`, + ); + } + + if (typeof value !== 'string' || isNaN(Number(value)) || Number(value) < 0) { + throw new Error( + `Provided 'value' is not a valid amount of Ether: ${value}`, + ); + } + + let valueWei = Web3.utils.toWei(value, 'ether'); + const qrData = `ethereum:${erc20}@${ChainId.MAINNET}/transfer?address=${to}&uint256=${valueWei}`; + + const qr = await QRCode.toDataURL(qrData); + return qr; + + } catch (error) { + throw error; + } + } + + /** + * + * Generates a QR code according to EIP-681 ("URI Scheme to facilitate ERC20 token payments"). + * The QR code represents a URI for an Ethereum transaction on the testnet. + * + * @returns A QR code as a string, which encodes a URI for an Ethereum transaction on the testnet for ERC20 according to EIP-681. + */ + public async getQrEthereumTestnetCustomERC20(ethTestnetCustomERC20Params: IETHTestnetCustomERC20) { + try { + const { erc20, to, value, chainId } = ethTestnetCustomERC20Params; + + if (!validator.isAddress(erc20)) { + throw new Error( + `Provided 'erc20' address is not a valid ERC20 Contract address: ${erc20}`, + ); + } + + if (!validator.isAddress(to)) { + throw new Error( + `Provided 'to' address is not a valid Ethereum address: ${to}`, + ); + } + + if (typeof value !== 'string' || isNaN(Number(value)) || Number(value) < 0) { + throw new Error( + `Provided 'value' is not a valid amount of Ether: ${value}`, + ); + } + + if (typeof chainId !== 'number' || chainId < 0) { + throw new Error( + `Provided 'chainId' is not a valid chainId: ${chainId}`, + ); + } + + let valueWei = Web3.utils.toWei(value, 'ether'); + const qrData = `ethereum:${erc20}@${chainId}/transfer?address=${to}&uint256=${valueWei}`; + + const qr = await QRCode.toDataURL(qrData); + return qr; + + } catch (error) { + throw error; + } + } + +} + +// Module Augmentation +declare module 'web3' { + interface Web3Context { + qrcode: QRCodePlugin; + } +} \ No newline at end of file diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..7590f36 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,28 @@ +export interface IETHMainnet { + to: string; + value: string; +} + +export interface IETHMainnetCustomERC20 { + erc20: string; + to: string; + value: string; +} + +export interface IETHTestnet { + to: string; + value: string; + chainId: number; +} + +export interface IETHTestnetCustomERC20 { + erc20: string; + to: string; + value: string; + chainId: number; +} + +export enum ChainId { + MAINNET=1, + SEPOLIA=11155111, +} \ No newline at end of file diff --git a/test/config/jest.config.js b/test/config/jest.config.js new file mode 100644 index 0000000..6797841 --- /dev/null +++ b/test/config/jest.config.js @@ -0,0 +1,40 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + rootDir: '../..', + testMatch: ['/test/**/?(*.)+(spec|test).+(ts|tsx|js)'], + testPathIgnorePatterns: ['/test/black_box'], + setupFilesAfterEnv: ['/test/config/setup.js'], + transform: { + '^.+\\.(ts|tsx)$': ['ts-jest', { + tsconfig: './test/tsconfig.json', + }] + }, + verbose: false, + collectCoverage: false, + coverageReporters: ['json'], + coverageDirectory: '.coverage', + /** + * restoreMocks [boolean] + * + * Default: false + * + * Automatically restore mock state between every test. + * Equivalent to calling jest.restoreAllMocks() between each test. + * This will lead to any mocks having their fake implementations removed + * and restores their initial implementation. + */ + restoreMocks: true, + + /** + * resetModules [boolean] + * + * Default: false + * + * By default, each test file gets its own independent module registry. + * Enabling resetModules goes a step further and resets the module registry before running each individual test. + * This is useful to isolate modules for every test so that local module state doesn't conflict between tests. + * This can be done programmatically using jest.resetModules(). + */ + resetModules: true, +}; \ No newline at end of file diff --git a/test/config/setup.js b/test/config/setup.js new file mode 100644 index 0000000..05022e0 --- /dev/null +++ b/test/config/setup.js @@ -0,0 +1,7 @@ +// Have to use `require` because of Jest issue https://jestjs.io/docs/ecmascript-modules +// eslint-disable-next-line @typescript-eslint/no-require-imports +require('jest-extended'); + +// @todo extend jest to have "toHaveBeenCalledOnceWith" matcher. + +process.env.NODE_ENV = 'test'; \ No newline at end of file diff --git a/test/tsconfig.json b/test/tsconfig.json new file mode 100644 index 0000000..4aa8215 --- /dev/null +++ b/test/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../tsconfig", + "compilerOptions": { + "declaration": false, + "declarationMap": false + }, + "include": ["./**/*", "../node_modules/jest-extended/types/**/*.ts"] +} \ No newline at end of file diff --git a/test/unit/jest.config.js b/test/unit/jest.config.js new file mode 100644 index 0000000..ceac341 --- /dev/null +++ b/test/unit/jest.config.js @@ -0,0 +1,9 @@ +const base = require('../config/jest.config'); + +module.exports = { + ...base, + testMatch: ['/test/unit/**/*.(spec|test).(js|ts)'], + + coverageDirectory: '.coverage/unit', + collectCoverageFrom: ['src/**'], +}; diff --git a/test/unit/qrcode_plugin.test.ts b/test/unit/qrcode_plugin.test.ts new file mode 100644 index 0000000..23afe52 --- /dev/null +++ b/test/unit/qrcode_plugin.test.ts @@ -0,0 +1,105 @@ +import { Web3, Web3Context, Web3Eth } from 'web3'; +import { QRCodePlugin } from '../../src/qrcode_plugin'; + +describe('QRCodePlugin Tests', () => { + it('should register QRCodePlugin plugin on Web3Context instance', () => { + const web3Context = new Web3Context('http://127.0.0.1:8545'); + web3Context.registerPlugin(new QRCodePlugin()); + expect(web3Context.qrcode).toBeDefined(); + }) + + it('should register QRCodePlugin plugin on Web3Eth instance', () => { + const web3Eth = new Web3Eth('http://127.0.0.1:8545'); + web3Eth.registerPlugin(new QRCodePlugin()); + expect(web3Eth.qrcode).toBeDefined(); + }); + + describe('QRCodePlugin method tests', () => { + const requestManagerSendSpy = jest.fn(); + + let web3Context: Web3; + + beforeAll(() => { + web3Context = new Web3('http://127.0.0.1:8545'); + web3Context.registerPlugin(new QRCodePlugin()); + web3Context.qrcode.requestManager.send = requestManagerSendSpy; + }); + + it('should call QRCodePlugin.getQrEthMainnet', async () => { + const qrData = { + to: '0x7772fb5804c9C60B76C56aBEEb79f2F6d54519C4', + value: '0.1' + }; + + const qr = await web3Context.qrcode.getQrEthereumMainnet(qrData); + expect(qr).toEqual(expect.stringMatching(/^data:image\/png;base64,/)); + }); + + it('should throw an error when calling QRCodePlugin.getQrEthMainnet with incorrect value parameter', async () => { + const qrData = { + to: '0x7772fb5804c9C60B76C56aBEEb79f2F6d54519C4', + value: 'some ether' + }; + + await expect(web3Context.qrcode.getQrEthereumMainnet(qrData)) + .rejects.toThrow('Provided \'value\' is not a valid amount of Ether: some ether'); + }); + + it('should throw an error when calling QRCodePlugin.getQrEthMainnet with incorrect address parameter', async () => { + const qrData = { + to: '0xADDRESS7772fb5804c9C60B76C56aBEEb79f2F6d54519C4', + value: '0.1' + }; + + await expect(web3Context.qrcode.getQrEthereumMainnet(qrData)) + .rejects.toThrow('Provided \'to\' address is not a valid Ethereum address'); + }); + + it('should call QRCodePlugin.getQrEthereumTestnet', async () => { + const qrData = { + to: '0x7772fb5804c9C60B76C56aBEEb79f2F6d54519C4', + value: '0.1', + chainId: 11155111, + }; + + const qr = await web3Context.qrcode.getQrEthereumTestnet(qrData); + expect(qr).toEqual(expect.stringMatching(/^data:image\/png;base64,/)); + }); + + it('should call QRCodePlugin.getQrEthereumMainnetCustomERC20', async () => { + const qrData = { + erc20: '0x514910771AF9Ca656af840dff83E8264EcF986CA', // Link Token + to: '0x7772fb5804c9C60B76C56aBEEb79f2F6d54519C4', + value: '0.1' + }; + + const qr = await web3Context.qrcode.getQrEthereumMainnetCustomERC20(qrData); + expect(qr).toEqual(expect.stringMatching(/^data:image\/png;base64,/)); + }); + + it('should throw an error when calling QRCodePlugin.getQrEthereumMainnetCustomERC20 with incorrect erc20 parameter', async () => { + const qrData = { + erc20: '0xCHAINLINK514910771AF9Ca656af840dff83E8264EcF986CA', // Link Token + to: '0x7772fb5804c9C60B76C56aBEEb79f2F6d54519C4', + value: '0.1' + }; + + await expect(web3Context.qrcode.getQrEthereumMainnetCustomERC20(qrData)) + .rejects.toThrow('Provided \'erc20\' address is not a valid ERC20 Contract address'); + }); + + it('should call QRCodePlugin.getQrEthereumTestnetCustomERC20', async () => { + const qrData = { + erc20: '0x779877A7B0D9E8603169DdbD7836e478b4624789', // Link Token + to: '0xA8D54c204127177d7b6C9156F7caD31894455607', // Simon's Custom Contract + value: '1', + chainId: 11155111, + }; + + const qr = await web3Context.qrcode.getQrEthereumTestnetCustomERC20(qrData); + console.log (qr); + expect(qr).toEqual(expect.stringMatching(/^data:image\/png;base64,/)); + }); + }); + +}); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..b98e479 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "baseUrl": "./", + "resolveJsonModule": true, + "forceConsistentCasingInFileNames": true, + "target": "es2020", + "module": "commonjs", + "declaration": true, + "moduleResolution": "node", + "newLine": "lf", + "noFallthroughCasesInSwitch": true, + "noImplicitReturns": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "pretty": true, + "removeComments": true, + "sourceMap": true, + "declarationMap": true, + "strict": true, + "strictNullChecks": true, + "outDir": "lib", + "esModuleInterop": true + }, + "include": ["src/**/*"] +} \ No newline at end of file From acdec65f040899f5569aea713fb7e93d18b83958 Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Sun, 11 Jun 2023 14:42:46 +0200 Subject: [PATCH 2/2] Update tsconfig.json Skipping the lib check till the following issues identified here are resolved: - https://github.com/web3/web3.js/issues/6162 - https://github.com/web3/web3.js/issues/6185 --- tsconfig.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index b98e479..9cbda25 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,7 +19,8 @@ "strict": true, "strictNullChecks": true, "outDir": "lib", - "esModuleInterop": true + "esModuleInterop": true, + "skipLibCheck": true }, "include": ["src/**/*"] -} \ No newline at end of file +}