From 2c6d90acd237167f6732d2f8d85e07c11d4d48a4 Mon Sep 17 00:00:00 2001 From: Johann BICH <2253470+kalote@users.noreply.github.com> Date: Tue, 31 Oct 2023 10:09:26 +0100 Subject: [PATCH 1/4] add new gas parameter + remove unused gasPrice --- src/constants/constants.ts | 14 ++------------ src/index.ts | 23 +++++++++++++++------- src/lib/provider-wrapper-utils.ts | 7 +++++-- src/provider/providerWrapper.ts | 32 +++++++++++++++++++++++++------ src/types/Config.ts | 1 + src/types/Method.ts | 2 -- 6 files changed, 50 insertions(+), 29 deletions(-) diff --git a/src/constants/constants.ts b/src/constants/constants.ts index 4915183d..21eb28f5 100644 --- a/src/constants/constants.ts +++ b/src/constants/constants.ts @@ -58,47 +58,35 @@ export const METHODS: Record = { [Method.GET_DATA_LEGACY]: { // Legacy version of ERC725Y - before v0.3.0 sig: '0x54f6127f', - gas: numberToHex(2000000), - gasPrice: numberToHex(100000000), value: numberToHex(0), returnEncoding: Encoding.BYTES, }, [Method.GET_DATA]: { // https://github.com/ERC725Alliance/ERC725/blob/v4.0.0/docs/ERC-725.md#erc725y sig: '0x4e3e6e9c', - gas: numberToHex(2000000), - gasPrice: numberToHex(100000000), value: numberToHex(0), returnEncoding: Encoding.BYTES_ARRAY, }, [Method.GET_DATA_BATCH]: { // https://github.com/ERC725Alliance/ERC725/blob/v5.1.0/docs/ERC-725.md#erc725y sig: '0xdedff9c6', - gas: numberToHex(2000000), - gasPrice: numberToHex(100000000), value: numberToHex(0), returnEncoding: Encoding.BYTES_ARRAY, }, [Method.OWNER]: { sig: '0x8da5cb5b', - gas: numberToHex(2000000), - gasPrice: numberToHex(100000000), value: numberToHex(0), returnEncoding: Encoding.ADDRESS, }, [Method.SUPPORTS_INTERFACE]: { // https://eips.ethereum.org/EIPS/eip-165 sig: '0x01ffc9a7', - gas: numberToHex(2000000), - gasPrice: numberToHex(100000000), value: numberToHex(0), returnEncoding: Encoding.BOOL, }, [Method.IS_VALID_SIGNATURE]: { // https://eips.ethereum.org/EIPS/eip-1271 sig: '0x1626ba7e', - gas: numberToHex(2000000), - gasPrice: numberToHex(100000000), value: numberToHex(0), returnEncoding: Encoding.BYTES4, }, @@ -183,3 +171,5 @@ export const LSP6_ALL_PERMISSIONS = '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'; export const COMPACT_BYTES_ARRAY_STRING = '[CompactBytesArray]'; + +export const DEFAULT_GAS_VALUE = 2000000; diff --git a/src/index.ts b/src/index.ts index 6a07e404..ec12ebbe 100644 --- a/src/index.ts +++ b/src/index.ts @@ -37,6 +37,7 @@ import { isValidSignature } from './lib/isValidSignature'; import { LSP6_ALL_PERMISSIONS, LSP6_DEFAULT_PERMISSIONS, + DEFAULT_GAS_VALUE, } from './constants/constants'; import { encodeKeyName, isDynamicKeyName } from './lib/encodeKeyName'; @@ -105,15 +106,20 @@ export class ERC725 { const defaultConfig = { ipfsGateway: 'https://cloudflare-ipfs.com/ipfs/', + gas: DEFAULT_GAS_VALUE, }; this.options = { schemas: this.validateSchemas(schemas), address, - provider: ERC725.initializeProvider(provider), + provider: ERC725.initializeProvider( + provider, + config?.gas ? config?.gas : defaultConfig.gas, + ), ipfsGateway: config?.ipfsGateway ? convertIPFSGatewayUrl(config?.ipfsGateway) : defaultConfig.ipfsGateway, + gas: config?.gas ? config?.gas : defaultConfig.gas, }; } @@ -151,20 +157,20 @@ export class ERC725 { }); } - private static initializeProvider(providerOrRpcUrl) { + private static initializeProvider(providerOrRpcUrl, gasInfo) { // do not fail on no-provider if (!providerOrRpcUrl) return undefined; // if provider is a string, assume it's a rpcUrl if (typeof providerOrRpcUrl === 'string') { - return new ProviderWrapper(new HttpProvider(providerOrRpcUrl)); + return new ProviderWrapper(new HttpProvider(providerOrRpcUrl), gasInfo); } if ( typeof providerOrRpcUrl.request === 'function' || typeof providerOrRpcUrl.send === 'function' ) - return new ProviderWrapper(providerOrRpcUrl); + return new ProviderWrapper(providerOrRpcUrl, gasInfo); throw new Error(`Incorrect or unsupported provider ${providerOrRpcUrl}`); } @@ -593,12 +599,12 @@ export class ERC725 { * supports a certain interface. * * @param {string} interfaceIdOrName Interface ID or supported interface name. - * @param options Object of address and RPC URL. + * @param options Object of address, RPC URL and optional gas. * @returns {Promise} if interface is supported. */ static async supportsInterface( interfaceIdOrName: string, - options: { address: string; rpcUrl: string }, + options: { address: string; rpcUrl: string; gas?: number }, ): Promise { if (!isAddress(options.address)) { throw new Error('Invalid address'); @@ -609,7 +615,10 @@ export class ERC725 { return supportsInterface(interfaceIdOrName, { address: options.address, - provider: this.initializeProvider(options.rpcUrl), + provider: this.initializeProvider( + options.rpcUrl, + options?.gas ? options?.gas : DEFAULT_GAS_VALUE, + ), }); } diff --git a/src/lib/provider-wrapper-utils.ts b/src/lib/provider-wrapper-utils.ts index 5f2adf67..0a0d52a0 100644 --- a/src/lib/provider-wrapper-utils.ts +++ b/src/lib/provider-wrapper-utils.ts @@ -13,6 +13,7 @@ */ import * as abi from 'web3-eth-abi'; +import { numberToHex } from 'web3-utils'; import { JsonRpc, @@ -49,6 +50,7 @@ export function decodeResult(method: Method, hexString: string) { const constructJSONRPCParams = ( address: string, method: Method, + gasInfo: number, methodParam?: string, ): JsonRpcEthereumProviderParamsWithLatest => { const data = methodParam @@ -59,7 +61,7 @@ const constructJSONRPCParams = ( { to: address, value: METHODS[method].value, - gas: METHODS[method].gas, + gas: numberToHex(gasInfo), data, }, 'latest', @@ -69,13 +71,14 @@ const constructJSONRPCParams = ( export function constructJSONRPC( address: string, method: Method, + gasInfo: number, methodParam?: string, ): JsonRpc { idCount += 1; return { jsonrpc: '2.0', method: 'eth_call', - params: constructJSONRPCParams(address, method, methodParam), + params: constructJSONRPCParams(address, method, gasInfo, methodParam), id: idCount, }; } diff --git a/src/provider/providerWrapper.ts b/src/provider/providerWrapper.ts index 3f7026db..a3f235d1 100644 --- a/src/provider/providerWrapper.ts +++ b/src/provider/providerWrapper.ts @@ -40,18 +40,20 @@ interface GetDataReturn { export class ProviderWrapper { type: ProviderTypes; provider: any; - constructor(provider: any) { + gas: number; + constructor(provider: any, gasInfo: number) { if (typeof provider.request === 'function') { this.type = ProviderTypes.ETHEREUM; } else { this.type = ProviderTypes.WEB3; } this.provider = provider; + this.gas = gasInfo; } async getOwner(address: string) { const result = await this.callContract( - constructJSONRPC(address, Method.OWNER), + constructJSONRPC(address, Method.OWNER, this.gas), ); if (result.error) { throw result.error; @@ -115,6 +117,7 @@ export class ProviderWrapper { constructJSONRPC( address, Method.SUPPORTS_INTERFACE, + this.gas, `${interfaceId}${'00000000000000000000000000000000000000000000000000000000'}`, ), ); @@ -152,7 +155,12 @@ export class ProviderWrapper { ); const result = await this.callContract( - constructJSONRPC(address, Method.IS_VALID_SIGNATURE, encodedParams), + constructJSONRPC( + address, + Method.IS_VALID_SIGNATURE, + this.gas, + encodedParams, + ), ); if (result.error) { @@ -172,7 +180,12 @@ export class ProviderWrapper { ); const results = await this.callContract([ - constructJSONRPC(address, Method.IS_VALID_SIGNATURE, encodedParams), + constructJSONRPC( + address, + Method.IS_VALID_SIGNATURE, + this.gas, + encodedParams, + ), ]); if (results.error) { throw results.error; @@ -232,6 +245,7 @@ export class ProviderWrapper { constructJSONRPC( address, method, + this.gas, abiCoder.encodeParameter('bytes32[]', keyHashes), ), ); @@ -248,6 +262,7 @@ export class ProviderWrapper { constructJSONRPC( address, method, + this.gas, abiCoder.encodeParameter('bytes32[]', keyHashes), ), ]; @@ -270,7 +285,7 @@ export class ProviderWrapper { // But this is already legacy and it won't be used anymore.. const encodedResultsPromises = keyHashes.map((keyHash) => this.callContract( - constructJSONRPC(address, Method.GET_DATA_LEGACY, keyHash), + constructJSONRPC(address, Method.GET_DATA_LEGACY, this.gas, keyHash), ), ); @@ -287,7 +302,12 @@ export class ProviderWrapper { // But this is already legacy and it won't be used anymore.. for (let index = 0; index < keyHashes.length; index++) { payload.push( - constructJSONRPC(address, Method.GET_DATA_LEGACY, keyHashes[index]), + constructJSONRPC( + address, + Method.GET_DATA_LEGACY, + this.gas, + keyHashes[index], + ), ); } diff --git a/src/types/Config.ts b/src/types/Config.ts index 24e4ab33..fa40adbb 100644 --- a/src/types/Config.ts +++ b/src/types/Config.ts @@ -11,6 +11,7 @@ export interface ERC725Config { * Another example: `https://cloudflare-ipfs.com/ipfs/` */ ipfsGateway: string; + gas: number; } export interface ERC725Options { diff --git a/src/types/Method.ts b/src/types/Method.ts index e28b49ab..1c794a67 100644 --- a/src/types/Method.ts +++ b/src/types/Method.ts @@ -19,8 +19,6 @@ export enum Encoding { export interface MethodData { sig: string; - gas: string; - gasPrice: string; value: string; returnEncoding: Encoding; } From 14e600c74c2d8a3551b0e984a807a65ce5157c36 Mon Sep 17 00:00:00 2001 From: Johann BICH <2253470+kalote@users.noreply.github.com> Date: Tue, 31 Oct 2023 10:27:54 +0100 Subject: [PATCH 2/4] fixing test + no magic number --- src/constants/constants.ts | 2 +- src/provider/providerWrapper.test.ts | 7 ++++--- src/types/Config.ts | 3 ++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/constants/constants.ts b/src/constants/constants.ts index 21eb28f5..c9948fc9 100644 --- a/src/constants/constants.ts +++ b/src/constants/constants.ts @@ -172,4 +172,4 @@ export const LSP6_ALL_PERMISSIONS = export const COMPACT_BYTES_ARRAY_STRING = '[CompactBytesArray]'; -export const DEFAULT_GAS_VALUE = 2000000; +export const DEFAULT_GAS_VALUE = 2_000_000; diff --git a/src/provider/providerWrapper.test.ts b/src/provider/providerWrapper.test.ts index 91748eb3..75e8ed94 100644 --- a/src/provider/providerWrapper.test.ts +++ b/src/provider/providerWrapper.test.ts @@ -3,6 +3,7 @@ import assert from 'assert'; import { ProviderWrapper } from './providerWrapper'; const erc725AccountAddress = '0x214be121bB52e6909c5158579b3458f8760f1b2f'; +const defaultGas = 2_000_000; describe('ProviderWrapper', () => { describe('#getOwner', () => { @@ -15,7 +16,7 @@ describe('ProviderWrapper', () => { }); }, }; - const ethSource = new ProviderWrapper(mockProvider); + const ethSource = new ProviderWrapper(mockProvider, defaultGas); const owner = await ethSource.getOwner(erc725AccountAddress); assert.deepStrictEqual( @@ -30,7 +31,7 @@ describe('ProviderWrapper', () => { cb(new Error('some error')); }, }; - const ethSource = new ProviderWrapper(mockProvider); + const ethSource = new ProviderWrapper(mockProvider, defaultGas); try { await ethSource.getOwner(erc725AccountAddress); @@ -47,7 +48,7 @@ describe('ProviderWrapper', () => { }); }, }; - const ethSource = new ProviderWrapper(mockProvider); + const ethSource = new ProviderWrapper(mockProvider, defaultGas); try { await ethSource.getOwner(erc725AccountAddress); diff --git a/src/types/Config.ts b/src/types/Config.ts index fa40adbb..15707591 100644 --- a/src/types/Config.ts +++ b/src/types/Config.ts @@ -5,13 +5,14 @@ export interface ERC725Config { * ```js title=Example * const config = { * ipfsGateway: 'https://ipfs.lukso.network/ipfs/' + * gas: 20_000_000 // Optional, default 2_000_000 * }; * ``` * Make sure to use the following format: `/ipfs/`.
* Another example: `https://cloudflare-ipfs.com/ipfs/` */ ipfsGateway: string; - gas: number; + gas?: number; } export interface ERC725Options { From 0d0f725cfafea1650f82cf353a0f307123a77548 Mon Sep 17 00:00:00 2001 From: Johann BICH <2253470+kalote@users.noreply.github.com> Date: Tue, 31 Oct 2023 10:37:29 +0100 Subject: [PATCH 3/4] update docs --- docs/classes/ERC725.md | 2 ++ docs/getting-started.md | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/classes/ERC725.md b/docs/classes/ERC725.md index c6a41019..48985771 100644 --- a/docs/classes/ERC725.md +++ b/docs/classes/ERC725.md @@ -1446,6 +1446,7 @@ On non instantiated class, you should provide an `options` object. | :-------- | :----- | :------------------------------------------------------------------- | | `address` | string | Address of the smart contract to check against a certain interface. | | `rpcUrl` | string | RPC URL to connect to the network the smart contract is deployed to. | +| `gas` | number | Optional: gas parameter to use. Default: 2_000_000. | #### Returns @@ -1473,6 +1474,7 @@ myErc725.supportsInterface('LSP0ERC725Account'); ERC725.supportsInterface('LSP0ERC725Account', { address: '0x0Dc07C77985fE31996Ed612F568eb441afe5768D', rpcUrl: 'https://rpc.testnet.lukso.network', + gas: 20_000_000, }); // true ``` diff --git a/docs/getting-started.md b/docs/getting-started.md index cbe47702..71b05e92 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -61,6 +61,7 @@ const address = '0x0Dc07C77985fE31996Ed612F568eb441afe5768D'; const RPC_URL = 'https://rpc.testnet.lukso.network'; const config = { ipfsGateway: 'https://YOUR-IPFS-GATEWAY/ipfs/', + gas: 20_000_000, // optional, default is 2_000_000 }; const erc725 = new ERC725(schemas, address, RPC_URL, config); @@ -110,7 +111,7 @@ await erc725.fetchData('LSP3Profile'); // downloads and verifies the linked JSON ``` :::tip Try it out -You can run the code snippit within your browser using the corresponding [StackBlitz example](https://stackblitz.com/edit/erc725js-instantiation?devtoolsheight=66&file=index.js). +You can run the code snippet within your browser using the corresponding [StackBlitz example](https://stackblitz.com/edit/erc725js-instantiation?devtoolsheight=66&file=index.js). :::note Whenever you can you should import `ERC725` via the named export. However currently we are also providing a default export. @@ -127,6 +128,7 @@ After the instance has been created, it is still possible to change settings thr myERC725.options.schema = '' // change schema myERC725.options.address '
' // change address myERC725.options.ipfsGateway = '' // used for fetchData(), default: 'https://cloudflare-ipfs.com/ipfs/' +myERC725.options.gas = 20_000_000 // change gas setting // NOTE: ERC725.provider can not be changed ``` From ca39593f061fbc532823c6fa01393fe22046f08f Mon Sep 17 00:00:00 2001 From: Johann BICH <2253470+kalote@users.noreply.github.com> Date: Thu, 2 Nov 2023 13:07:26 +0100 Subject: [PATCH 4/4] change default gas value to 1_000_000 & update interface --- docs/classes/ERC725.md | 2 +- docs/getting-started.md | 2 +- src/constants/constants.ts | 2 +- src/index.ts | 2 +- src/provider/providerWrapper.test.ts | 2 +- src/types/Config.ts | 6 ++++-- 6 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/classes/ERC725.md b/docs/classes/ERC725.md index 48985771..bf276aca 100644 --- a/docs/classes/ERC725.md +++ b/docs/classes/ERC725.md @@ -1446,7 +1446,7 @@ On non instantiated class, you should provide an `options` object. | :-------- | :----- | :------------------------------------------------------------------- | | `address` | string | Address of the smart contract to check against a certain interface. | | `rpcUrl` | string | RPC URL to connect to the network the smart contract is deployed to. | -| `gas` | number | Optional: gas parameter to use. Default: 2_000_000. | +| `gas` | number | Optional: gas parameter to use. Default: 1_000_000. | #### Returns diff --git a/docs/getting-started.md b/docs/getting-started.md index 71b05e92..e2e0a4ed 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -61,7 +61,7 @@ const address = '0x0Dc07C77985fE31996Ed612F568eb441afe5768D'; const RPC_URL = 'https://rpc.testnet.lukso.network'; const config = { ipfsGateway: 'https://YOUR-IPFS-GATEWAY/ipfs/', - gas: 20_000_000, // optional, default is 2_000_000 + gas: 20_000_000, // optional, default is 1_000_000 }; const erc725 = new ERC725(schemas, address, RPC_URL, config); diff --git a/src/constants/constants.ts b/src/constants/constants.ts index c9948fc9..5a9ce435 100644 --- a/src/constants/constants.ts +++ b/src/constants/constants.ts @@ -172,4 +172,4 @@ export const LSP6_ALL_PERMISSIONS = export const COMPACT_BYTES_ARRAY_STRING = '[CompactBytesArray]'; -export const DEFAULT_GAS_VALUE = 2_000_000; +export const DEFAULT_GAS_VALUE = 1_000_000; diff --git a/src/index.ts b/src/index.ts index ec12ebbe..4d37d9be 100644 --- a/src/index.ts +++ b/src/index.ts @@ -81,7 +81,7 @@ export { encodeData } from './lib/utils'; * */ export class ERC725 { - options: ERC725Options & ERC725Config; + options: ERC725Options; /** * Creates an instance of ERC725. diff --git a/src/provider/providerWrapper.test.ts b/src/provider/providerWrapper.test.ts index 75e8ed94..fa655712 100644 --- a/src/provider/providerWrapper.test.ts +++ b/src/provider/providerWrapper.test.ts @@ -3,7 +3,7 @@ import assert from 'assert'; import { ProviderWrapper } from './providerWrapper'; const erc725AccountAddress = '0x214be121bB52e6909c5158579b3458f8760f1b2f'; -const defaultGas = 2_000_000; +const defaultGas = 1_000_000; describe('ProviderWrapper', () => { describe('#getOwner', () => { diff --git a/src/types/Config.ts b/src/types/Config.ts index 15707591..dd592c49 100644 --- a/src/types/Config.ts +++ b/src/types/Config.ts @@ -5,13 +5,13 @@ export interface ERC725Config { * ```js title=Example * const config = { * ipfsGateway: 'https://ipfs.lukso.network/ipfs/' - * gas: 20_000_000 // Optional, default 2_000_000 + * gas: 20_000_000 // Optional, default 0 * }; * ``` * Make sure to use the following format: `/ipfs/`.
* Another example: `https://cloudflare-ipfs.com/ipfs/` */ - ipfsGateway: string; + ipfsGateway?: string; gas?: number; } @@ -19,4 +19,6 @@ export interface ERC725Options { schemas: ERC725JSONSchema[]; address?: string; provider?; + ipfsGateway: string; + gas: number; }