sol2uml 2.4.2 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,11 @@
1
- import { Storage } from './converterClasses2Storage';
2
- export declare const convertStorages2Dot: (storages: Storage[], options: {
1
+ import { StorageSection } from './converterClasses2Storage';
2
+ export declare const convertStorages2Dot: (storageSections: readonly StorageSection[], options: {
3
3
  data: boolean;
4
+ backColor: string;
5
+ shapeColor: string;
6
+ fillColor: string;
7
+ textColor: string;
4
8
  }) => string;
5
- export declare function convertStorage2Dot(storage: Storage, dotString: string, options: {
9
+ export declare function convertStorage2Dot(storageSection: StorageSection, dotString: string, options: {
6
10
  data: boolean;
7
11
  }): string;
@@ -2,23 +2,25 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.convertStorage2Dot = exports.convertStorages2Dot = void 0;
4
4
  const converterClasses2Storage_1 = require("./converterClasses2Storage");
5
+ const umlClass_1 = require("./umlClass");
5
6
  const debug = require('debug')('sol2uml');
6
- const convertStorages2Dot = (storages, options) => {
7
+ const convertStorages2Dot = (storageSections, options) => {
7
8
  let dotString = `
8
9
  digraph StorageDiagram {
9
10
  rankdir=LR
10
- color=black
11
11
  arrowhead=open
12
- node [shape=record, style=filled, fillcolor=gray95 fontname="Courier New"]`;
12
+ bgcolor="${options.backColor}"
13
+ edge [color="${options.shapeColor}"]
14
+ node [shape=record, style=filled, color="${options.shapeColor}", fillcolor="${options.fillColor}", fontcolor="${options.textColor}", fontname="Courier New"]`;
13
15
  // process contract and the struct storages
14
- storages.forEach((storage) => {
16
+ storageSections.forEach((storage) => {
15
17
  dotString = convertStorage2Dot(storage, dotString, options);
16
18
  });
17
19
  // link contract and structs to structs
18
- storages.forEach((slot) => {
20
+ storageSections.forEach((slot) => {
19
21
  slot.variables.forEach((storage) => {
20
- if (storage.referenceStorageId) {
21
- dotString += `\n ${slot.id}:${storage.id} -> ${storage.referenceStorageId}`;
22
+ if (storage.referenceSectionId) {
23
+ dotString += `\n ${slot.id}:${storage.id} -> ${storage.referenceSectionId}`;
22
24
  }
23
25
  });
24
26
  });
@@ -28,34 +30,50 @@ node [shape=record, style=filled, fillcolor=gray95 fontname="Courier New"]`;
28
30
  return dotString;
29
31
  };
30
32
  exports.convertStorages2Dot = convertStorages2Dot;
31
- function convertStorage2Dot(storage, dotString, options) {
33
+ function convertStorage2Dot(storageSection, dotString, options) {
32
34
  // write storage header with name and optional address
33
- dotString += `\n${storage.id} [label="${storage.name} \\<\\<${storage.type}\\>\\>\\n${storage.address || storage.slotKey || ''}`;
35
+ dotString += `\n${storageSection.id} [label="${storageSection.name} \\<\\<${storageSection.type}\\>\\>\\n${storageSection.address || storageSection.offset || ''}`;
34
36
  dotString += ' | {';
35
- const startingVariables = storage.variables.filter((s) => s.byteOffset === 0);
37
+ const startingVariables = storageSection.variables.filter((s) => s.byteOffset === 0);
38
+ // for each slot displayed, does is have any variables with parsed data?
39
+ const displayData = startingVariables.map((startVar) => storageSection.variables.some((variable) => variable.fromSlot === startVar.fromSlot && variable.parsedValue));
40
+ const linePad = '\\n\\ ';
36
41
  // write slot numbers
37
- dotString += '{ slot';
42
+ const dataLine = options.data ? linePad : '';
43
+ dotString +=
44
+ storageSection.offset || storageSection.mapping
45
+ ? `{ offset${dataLine}`
46
+ : `{ slot${dataLine}`;
38
47
  startingVariables.forEach((variable, i) => {
48
+ const dataLine = options.data && displayData[i] ? linePad : '';
39
49
  if (variable.fromSlot === variable.toSlot) {
40
- dotString += `| ${variable.fromSlot} `;
50
+ dotString += ` | ${variable.fromSlot}${dataLine}`;
41
51
  }
42
52
  else {
43
- dotString += `| ${variable.fromSlot}-${variable.toSlot} `;
53
+ dotString += ` | ${variable.fromSlot}-${variable.toSlot}${dataLine}`;
44
54
  }
45
55
  });
46
56
  // write slot values if available
47
57
  if (options.data) {
48
- dotString += '} | {value';
58
+ dotString += `} | {value${dataLine}`;
49
59
  startingVariables.forEach((variable, i) => {
50
- dotString += ` | ${variable.value || ''}`;
60
+ if (displayData[i]) {
61
+ dotString += ` | ${variable.slotValue || ''}${linePad}`;
62
+ }
63
+ else {
64
+ dotString += ` | `;
65
+ }
51
66
  });
52
67
  }
53
- const contractVariablePrefix = storage.type === converterClasses2Storage_1.StorageType.Contract ? '\\<inherited contract\\>.' : '';
54
- dotString += `} | { type: ${contractVariablePrefix}variable (bytes)`;
68
+ const contractVariablePrefix = storageSection.type === converterClasses2Storage_1.StorageSectionType.Contract
69
+ ? '\\<inherited contract\\>.'
70
+ : '';
71
+ const dataLine2 = options.data ? `\\ndecoded data` : '';
72
+ dotString += `} | { type: ${contractVariablePrefix}variable (bytes)${dataLine2}`;
55
73
  // For each slot
56
74
  startingVariables.forEach((variable) => {
57
75
  // Get all the storage variables in this slot
58
- const slotVariables = storage.variables.filter((s) => s.fromSlot === variable.fromSlot);
76
+ const slotVariables = storageSection.variables.filter((s) => s.fromSlot === variable.fromSlot);
59
77
  const usedBytes = slotVariables.reduce((acc, s) => acc + s.byteSize, 0);
60
78
  if (usedBytes < 32) {
61
79
  // Create an unallocated variable for display purposes
@@ -66,20 +84,22 @@ function convertStorage2Dot(storage, dotString, options) {
66
84
  byteSize: 32 - usedBytes,
67
85
  byteOffset: usedBytes,
68
86
  type: 'unallocated',
87
+ attributeType: umlClass_1.AttributeType.UserDefined,
69
88
  dynamic: false,
70
- noValue: true,
89
+ displayValue: false,
90
+ getValue: false,
71
91
  contractName: variable.contractName,
72
- variable: '',
92
+ name: '',
73
93
  });
74
94
  }
75
95
  const slotVariablesReversed = slotVariables.reverse();
76
96
  // For each variable in the slot
77
97
  slotVariablesReversed.forEach((variable, i) => {
78
98
  if (i === 0) {
79
- dotString += ` | { ${dotVariable(variable, storage.name)} `;
99
+ dotString += ` | { ${dotVariable(variable, storageSection.name)} `;
80
100
  }
81
101
  else {
82
- dotString += ` | ${dotVariable(variable, storage.name)} `;
102
+ dotString += ` | ${dotVariable(variable, storageSection.name)} `;
83
103
  }
84
104
  });
85
105
  dotString += '}';
@@ -89,12 +109,17 @@ function convertStorage2Dot(storage, dotString, options) {
89
109
  return dotString;
90
110
  }
91
111
  exports.convertStorage2Dot = convertStorage2Dot;
92
- const dotVariable = (storage, contractName) => {
93
- const port = storage.referenceStorageId !== undefined ? `<${storage.id}>` : '';
94
- const contractNamePrefix = storage.contractName !== contractName ? `${storage.contractName}.` : '';
95
- const variable = storage.variable
96
- ? `: ${contractNamePrefix}${storage.variable}`
112
+ const dotVariable = (variable, contractName) => {
113
+ const port = variable.referenceSectionId !== undefined ? `<${variable.id}>` : '';
114
+ const contractNamePrefix = variable.contractName !== contractName
115
+ ? `${variable.contractName}.`
116
+ : '';
117
+ const variableValue = variable.parsedValue
118
+ ? `\\n\\ ${variable.parsedValue}`
119
+ : '';
120
+ const variableName = variable.name
121
+ ? `: ${contractNamePrefix}${variable.name}`
97
122
  : '';
98
- return `${port} ${storage.type}${variable} (${storage.byteSize})`;
123
+ return `${port} ${variable.type}${variableName} (${variable.byteSize})${variableValue}`;
99
124
  };
100
125
  //# sourceMappingURL=converterStorage2Dot.js.map
@@ -7,7 +7,7 @@ import { ClassOptions } from './converterClass2Dot';
7
7
  * @param options sol2uml class options
8
8
  * @return umlClasses filtered list of UML classes of type `UMLClass`
9
9
  */
10
- export declare const filterHiddenClasses: (umlClasses: UmlClass[], options: ClassOptions) => UmlClass[];
10
+ export declare const filterHiddenClasses: (umlClasses: readonly UmlClass[], options: ClassOptions) => UmlClass[];
11
11
  /**
12
12
  * Finds all the UML classes that have an association with a list of base contract names.
13
13
  * The associated classes can be contracts, abstract contracts, interfaces, libraries, enums, structs or constants.
@@ -16,7 +16,7 @@ export declare const filterHiddenClasses: (umlClasses: UmlClass[], options: Clas
16
16
  * @param depth limit the number of associations from the base contract.
17
17
  * @return filteredUmlClasses list of UML classes of type `UMLClass`
18
18
  */
19
- export declare const classesConnectedToBaseContracts: (umlClasses: UmlClass[], baseContractNames: string[], depth?: number) => UmlClass[];
19
+ export declare const classesConnectedToBaseContracts: (umlClasses: readonly UmlClass[], baseContractNames: readonly string[], depth?: number) => UmlClass[];
20
20
  /**
21
21
  * Finds all the UML classes that have an association with a base contract name.
22
22
  * The associated classes can be contracts, abstract contracts, interfaces, libraries, enums, structs or constants.
@@ -26,7 +26,7 @@ export declare const classesConnectedToBaseContracts: (umlClasses: UmlClass[], b
26
26
  * @param depth limit the number of associations from the base contract.
27
27
  * @return filteredUmlClasses list of UML classes of type `UMLClass`
28
28
  */
29
- export declare const classesConnectedToBaseContract: (umlClasses: UmlClass[], baseContractName: string, weightedDirectedGraph: WeightedDiGraph, depth?: number) => {
29
+ export declare const classesConnectedToBaseContract: (umlClasses: readonly UmlClass[], baseContractName: string, weightedDirectedGraph: WeightedDiGraph, depth?: number) => {
30
30
  [contractName: string]: UmlClass;
31
31
  };
32
- export declare const topologicalSortClasses: (umlClasses: UmlClass[]) => UmlClass[];
32
+ export declare const topologicalSortClasses: (umlClasses: readonly UmlClass[]) => UmlClass[];
@@ -4,6 +4,7 @@ exports.topologicalSortClasses = exports.classesConnectedToBaseContract = export
4
4
  const js_graph_algorithms_1 = require("js-graph-algorithms");
5
5
  const umlClass_1 = require("./umlClass");
6
6
  const associations_1 = require("./associations");
7
+ const debug = require('debug')('sol2uml');
7
8
  /**
8
9
  * Filter out any UML Class types that are to be hidden.
9
10
  * @param umlClasses array of UML classes of type `UMLClass`
@@ -85,7 +86,7 @@ function loadWeightedDirectedGraph(umlClasses) {
85
86
  continue;
86
87
  }
87
88
  const isTarget = umlClasses.find((u) => u.id === targetUmlClass.id);
88
- console.log(`isTarget ${isTarget} Adding edge from ${sourceUmlClass.name} with id ${sourceUmlClass.id} to ${targetUmlClass.name} with id ${targetUmlClass.id} and type ${targetUmlClass.stereotype}`);
89
+ debug(`isTarget ${isTarget} Adding edge from ${sourceUmlClass.name} with id ${sourceUmlClass.id} to ${targetUmlClass.name} with id ${targetUmlClass.id} and type ${targetUmlClass.stereotype}`);
89
90
  weightedDirectedGraph.addEdge(new js_graph_algorithms_1.Edge(sourceUmlClass.id, targetUmlClass.id, 1));
90
91
  }
91
92
  }
@@ -1,7 +1,11 @@
1
1
  import { ASTNode } from '@solidity-parser/parser/dist/src/ast-types';
2
2
  import { UmlClass } from './umlClass';
3
+ export interface Remapping {
4
+ from: RegExp;
5
+ to: string;
6
+ }
3
7
  export declare const networks: readonly ["mainnet", "ropsten", "kovan", "rinkeby", "goerli", "sepolia", "polygon", "testnet.polygon", "arbitrum", "testnet.arbitrum", "avalanche", "testnet.avalanche", "bsc", "testnet.bsc", "crono", "fantom", "testnet.fantom", "moonbeam", "optimistic", "kovan-optimistic", "gnosisscan"];
4
- export type Network = typeof networks[number];
8
+ export type Network = (typeof networks)[number];
5
9
  export declare class EtherscanParser {
6
10
  protected apikey: string;
7
11
  network: Network;
@@ -37,11 +41,25 @@ export declare class EtherscanParser {
37
41
  * @param contractAddress Ethereum contract address with a 0x prefix
38
42
  */
39
43
  getSourceCode(contractAddress: string): Promise<{
40
- files: {
44
+ files: readonly {
41
45
  code: string;
42
46
  filename: string;
43
47
  }[];
44
48
  contractName: string;
45
49
  compilerVersion: string;
50
+ remappings: Remapping[];
46
51
  }>;
47
52
  }
53
+ /**
54
+ * Parses Ethersan's remappings config in its API response
55
+ * @param rawMappings
56
+ */
57
+ export declare const parseRemappings: (rawMappings: string[]) => Remapping[];
58
+ /**
59
+ * Parses a single mapping. For example
60
+ * "@openzeppelin/=lib/openzeppelin-contracts/"
61
+ * This is from Uniswap's UniversalRouter in the Settings section after the source files
62
+ * https://etherscan.io/address/0xEf1c6E67703c7BD7107eed8303Fbe6EC2554BF6B#code
63
+ * @param mapping
64
+ */
65
+ export declare const parseRemapping: (mapping: string) => Remapping;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.EtherscanParser = exports.networks = void 0;
6
+ exports.parseRemapping = exports.parseRemappings = exports.EtherscanParser = exports.networks = void 0;
7
7
  const axios_1 = __importDefault(require("axios"));
8
8
  const parser_1 = require("@solidity-parser/parser");
9
9
  const converterAST2Classes_1 = require("./converterAST2Classes");
@@ -110,12 +110,12 @@ class EtherscanParser {
110
110
  * @return Promise with an array of UmlClass objects
111
111
  */
112
112
  async getUmlClasses(contractAddress) {
113
- const { files, contractName } = await this.getSourceCode(contractAddress);
113
+ const { files, contractName, remappings } = await this.getSourceCode(contractAddress);
114
114
  let umlClasses = [];
115
115
  for (const file of files) {
116
116
  debug(`Parsing source file ${file.filename}`);
117
117
  const node = await this.parseSourceCode(file.code);
118
- const umlClass = (0, converterAST2Classes_1.convertAST2UmlClasses)(node, file.filename);
118
+ const umlClass = (0, converterAST2Classes_1.convertAST2UmlClasses)(node, file.filename, remappings);
119
119
  umlClasses = umlClasses.concat(umlClass);
120
120
  }
121
121
  return {
@@ -130,12 +130,12 @@ class EtherscanParser {
130
130
  * @return Promise string of Solidity code
131
131
  */
132
132
  async getSolidityCode(contractAddress) {
133
- const { files, contractName, compilerVersion } = await this.getSourceCode(contractAddress);
133
+ const { files, contractName, compilerVersion, remappings } = await this.getSourceCode(contractAddress);
134
134
  // Parse the UmlClasses from the Solidity code in each file
135
135
  let umlClasses = [];
136
136
  for (const file of files) {
137
137
  const node = await this.parseSourceCode(file.code);
138
- const umlClass = (0, converterAST2Classes_1.convertAST2UmlClasses)(node, file.filename);
138
+ const umlClass = (0, converterAST2Classes_1.convertAST2UmlClasses)(node, file.filename, remappings);
139
139
  umlClasses = umlClasses.concat(umlClass);
140
140
  }
141
141
  // Sort the classes so dependent code is first
@@ -209,6 +209,7 @@ class EtherscanParser {
209
209
  if (!Array.isArray(response?.data?.result)) {
210
210
  throw new Error(`Failed to ${description}. No result array in HTTP data: ${JSON.stringify(response?.data)}`);
211
211
  }
212
+ let remappings;
212
213
  const results = response.data.result.map((result) => {
213
214
  if (!result.SourceCode) {
214
215
  throw new Error(`Failed to ${description}. Most likely the contract has not been verified on Etherscan.`);
@@ -223,6 +224,8 @@ class EtherscanParser {
223
224
  parableResultString = result.SourceCode.slice(1, -1);
224
225
  }
225
226
  const sourceCodeObject = JSON.parse(parableResultString);
227
+ // Get any remapping of filenames from the settings
228
+ remappings = (0, exports.parseRemappings)(sourceCodeObject.settings?.remappings);
226
229
  // The getsource response from Etherscan is inconsistent so we need to handle both shapes
227
230
  const sourceFiles = sourceCodeObject.sources
228
231
  ? Object.entries(sourceCodeObject.sources)
@@ -239,6 +242,8 @@ class EtherscanParser {
239
242
  // if multiple Solidity source files with no Etherscan bug in the SourceCode field
240
243
  if (result?.SourceCode?.sources) {
241
244
  const sourceFiles = Object.values(result.SourceCode.sources);
245
+ // Get any remapping of filenames from the settings
246
+ remappings = (0, exports.parseRemappings)(result.SourceCode.settings?.remappings);
242
247
  return sourceFiles.map(([filename, code]) => ({
243
248
  code: code.content,
244
249
  filename,
@@ -254,6 +259,7 @@ class EtherscanParser {
254
259
  files: results.flat(1),
255
260
  contractName: response.data.result[0].ContractName,
256
261
  compilerVersion: response.data.result[0].CompilerVersion,
262
+ remappings,
257
263
  };
258
264
  }
259
265
  catch (err) {
@@ -268,4 +274,31 @@ class EtherscanParser {
268
274
  }
269
275
  }
270
276
  exports.EtherscanParser = EtherscanParser;
277
+ /**
278
+ * Parses Ethersan's remappings config in its API response
279
+ * @param rawMappings
280
+ */
281
+ const parseRemappings = (rawMappings) => {
282
+ if (!rawMappings)
283
+ return [];
284
+ return rawMappings.map((mapping) => (0, exports.parseRemapping)(mapping));
285
+ };
286
+ exports.parseRemappings = parseRemappings;
287
+ /**
288
+ * Parses a single mapping. For example
289
+ * "@openzeppelin/=lib/openzeppelin-contracts/"
290
+ * This is from Uniswap's UniversalRouter in the Settings section after the source files
291
+ * https://etherscan.io/address/0xEf1c6E67703c7BD7107eed8303Fbe6EC2554BF6B#code
292
+ * @param mapping
293
+ */
294
+ const parseRemapping = (mapping) => {
295
+ const equalIndex = mapping.indexOf('=');
296
+ const from = mapping.slice(0, equalIndex);
297
+ const to = mapping.slice(equalIndex + 1);
298
+ return {
299
+ from: new RegExp('^' + from),
300
+ to,
301
+ };
302
+ };
303
+ exports.parseRemapping = parseRemapping;
271
304
  //# sourceMappingURL=parserEtherscan.js.map
@@ -1,6 +1,6 @@
1
1
  import { ASTNode } from '@solidity-parser/parser/dist/src/ast-types';
2
2
  import { UmlClass } from './umlClass';
3
- export declare const parseUmlClassesFromFiles: (filesOrFolders: string[], ignoreFilesOrFolders: string[], subfolders?: number) => Promise<UmlClass[]>;
4
- export declare function getSolidityFilesFromFolderOrFiles(folderOrFilePaths: string[], ignoreFilesOrFolders: string[], subfolders?: number): Promise<string[]>;
5
- export declare function getSolidityFilesFromFolderOrFile(folderOrFilePath: string, ignoreFilesOrFolders?: string[], depthLimit?: number): Promise<string[]>;
3
+ export declare const parseUmlClassesFromFiles: (filesOrFolders: readonly string[], ignoreFilesOrFolders: readonly string[], subfolders?: number) => Promise<UmlClass[]>;
4
+ export declare function getSolidityFilesFromFolderOrFiles(folderOrFilePaths: readonly string[], ignoreFilesOrFolders: readonly string[], subfolders?: number): Promise<string[]>;
5
+ export declare function getSolidityFilesFromFolderOrFile(folderOrFilePath: string, ignoreFilesOrFolders?: readonly string[], depthLimit?: number): Promise<string[]>;
6
6
  export declare function parseSolidityFile(fileName: string): ASTNode;
@@ -16,7 +16,7 @@ const parseUmlClassesFromFiles = async (filesOrFolders, ignoreFilesOrFolders, su
16
16
  for (const file of files) {
17
17
  const node = await parseSolidityFile(file);
18
18
  const relativePath = (0, path_1.relative)(process.cwd(), file);
19
- const umlClass = (0, converterAST2Classes_1.convertAST2UmlClasses)(node, relativePath, true);
19
+ const umlClass = (0, converterAST2Classes_1.convertAST2UmlClasses)(node, relativePath, [], true);
20
20
  umlClasses = umlClasses.concat(umlClass);
21
21
  }
22
22
  return umlClasses;
@@ -82,7 +82,7 @@ function getSolidityFilesFromFolderOrFile(folderOrFilePath, ignoreFilesOrFolders
82
82
  else {
83
83
  error = new Error(`Failed to get Solidity files under folder or file ${folderOrFilePath}`, { cause: err });
84
84
  }
85
- console.error(error.stack);
85
+ console.error(error);
86
86
  reject(error);
87
87
  }
88
88
  });
@@ -1,3 +1,49 @@
1
1
  import { BigNumberish } from '@ethersproject/bignumber';
2
- export declare const getStorageValue: (url: string, contractAddress: string, slot: BigNumberish, blockTag?: BigNumberish | 'latest') => Promise<string>;
3
- export declare const getStorageValues: (url: string, contractAddress: string, slots: BigNumberish[], blockTag?: BigNumberish | 'latest') => Promise<string[]>;
2
+ import { StorageSection, Variable } from './converterClasses2Storage';
3
+ /**
4
+ * Adds the slot values to the variables in the storage section.
5
+ * This can be rerun for a section as it will only get if the slot value
6
+ * does not exist.
7
+ * @param url of Ethereum JSON-RPC API provider. eg Infura or Alchemy
8
+ * @param contractAddress Contract address to get the storage slot values from.
9
+ * If contract is proxied, use proxy and not the implementation contract.
10
+ * @param storageSection is mutated with the slot values added to the variables
11
+ * @param arrayItems the number of items to display at the start and end of an array
12
+ * @param blockTag block number or `latest`
13
+ */
14
+ export declare const addSlotValues: (url: string, contractAddress: string, storageSection: StorageSection, arrayItems: number, blockTag: BigNumberish) => Promise<void>;
15
+ export declare const parseValue: (variable: Variable) => string;
16
+ /**
17
+ * Get storage slot values from JSON-RPC API provider.
18
+ * @param url of Ethereum JSON-RPC API provider. eg Infura or Alchemy
19
+ * @param contractAddress Contract address to get the storage slot values from.
20
+ * If proxied, use proxy and not the implementation contract.
21
+ * @param slotKeys array of 32 byte slot keys as BigNumbers.
22
+ * @param blockTag block number or `latest`
23
+ * @return slotValues array of 32 byte slot values as hexadecimal strings
24
+ */
25
+ export declare const getSlotValues: (url: string, contractAddress: string, slotKeys: readonly BigNumberish[], blockTag?: BigNumberish | 'latest') => Promise<string[]>;
26
+ /**
27
+ * Get storage slot values from JSON-RPC API provider.
28
+ * @param url of Ethereum JSON-RPC API provider. eg Infura or Alchemy
29
+ * @param contractAddress Contract address to get the storage slot values from.
30
+ * If proxied, use proxy and not the implementation contract.
31
+ * @param slotKey 32 byte slot key as a BigNumber.
32
+ * @param blockTag block number or `latest`
33
+ * @return slotValue 32 byte slot value as hexadecimal string
34
+ */
35
+ export declare const getSlotValue: (url: string, contractAddress: string, slotKey: BigNumberish, blockTag: BigNumberish | 'latest') => Promise<string>;
36
+ /**
37
+ * Calculates the number of string characters or bytes of a string or bytes type.
38
+ * See the following for how string and bytes are stored in storage slots
39
+ * https://docs.soliditylang.org/en/v0.8.17/internals/layout_in_storage.html#bytes-and-string
40
+ * @param variable the variable with the slotValue that is being sized
41
+ * @return bytes the number of bytes of the dynamic slot. If static, zero is return.
42
+ */
43
+ export declare const dynamicSlotSize: (variable: {
44
+ name?: string;
45
+ type?: string;
46
+ slotValue?: string;
47
+ }) => number;
48
+ export declare const convert2String: (bytes: string) => string;
49
+ export declare const escapeString: (text: string) => string;