Skip to content

Commit

Permalink
✨ Enable address[] decoding (#278)
Browse files Browse the repository at this point in the history
* Fix package-lock allowed versions

* Add address[] support

* prettier sort imports
  • Loading branch information
dawsbot authored Apr 7, 2024
1 parent 59c540f commit 0067af4
Show file tree
Hide file tree
Showing 16 changed files with 87 additions and 124 deletions.
2 changes: 1 addition & 1 deletion docusaurus/src/components/Contributions/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Link from '@docusaurus/Link';
import clsx from 'clsx';
import React from 'react';
import Link from '@docusaurus/Link';

interface ContributeItem {
title: string;
Expand Down
2 changes: 1 addition & 1 deletion docusaurus/src/components/HomepageFeatures/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Link from '@docusaurus/Link';
import CodeBlock from '@theme/CodeBlock';
import clsx from 'clsx';
import React from 'react';
import Link from '@docusaurus/Link';
import HomepageContributions from '../Contributions';

interface FeatureItem {
Expand Down
6 changes: 3 additions & 3 deletions docusaurus/src/pages/getting_started.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from 'react';
import Link from '@docusaurus/Link';
import CodeBlock from '@theme/CodeBlock';
import Layout from '@theme/Layout';
import clsx from 'clsx';
import CodeBlock from '@theme/CodeBlock';
import Link from '@docusaurus/Link';
import React from 'react';

function GettingStarted() {
return (
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,10 @@
"prettier": {
"trailingComma": "all",
"tabWidth": 2,
"singleQuote": true
"singleQuote": true,
"plugins": [
"prettier-plugin-organize-imports"
]
},
"keywords": [
"ethereum",
Expand Down
2 changes: 1 addition & 1 deletion scripts/markdown-magic/generate-readme.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { functionsMarkdown, providerMarkdown } from './parse-typedoc';
import path from 'path';
import { functionsMarkdown, providerMarkdown } from './parse-typedoc';

import markdownMagic from 'markdown-magic';
import { fileURLToPath } from 'url';
Expand Down
2 changes: 1 addition & 1 deletion scripts/markdown-magic/parse-typedoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* Parse a typedoc output file and generate the markdown code
* This markdown generated is injected into the root readme via markdown-magic
*/
import stats from './typedoc.out.json';
import z from 'zod';
import stats from './typedoc.out.json';

const functions = z
.array(z.number())
Expand Down
75 changes: 0 additions & 75 deletions src/classes/test/Contract/crv-abi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,81 +5,6 @@ export const abi: JSONABI =
// http://api.etherscan.io/api?module=contract&action=getabi&address=0x575CCD8e2D300e2377B43478339E364000318E2c&format=raw

[
{
name: 'Fund',
inputs: [
{
type: 'address',
name: 'recipient',
indexed: true,
},
{
type: 'uint256',
name: 'amount',
indexed: false,
},
],
anonymous: false,
type: 'event',
},
{
name: 'Claim',
inputs: [
{
type: 'address',
name: 'recipient',
indexed: true,
},
{
type: 'uint256',
name: 'claimed',
indexed: false,
},
],
anonymous: false,
type: 'event',
},
{
name: 'ToggleDisable',
inputs: [
{
type: 'address',
name: 'recipient',
indexed: false,
},
{
type: 'bool',
name: 'disabled',
indexed: false,
},
],
anonymous: false,
type: 'event',
},
{
name: 'CommitOwnership',
inputs: [
{
type: 'address',
name: 'admin',
indexed: false,
},
],
anonymous: false,
type: 'event',
},
{
name: 'ApplyOwnership',
inputs: [
{
type: 'address',
name: 'admin',
indexed: false,
},
],
anonymous: false,
type: 'event',
},
{
outputs: [],
inputs: [
Expand Down
1 change: 0 additions & 1 deletion src/classes/test/Contract/crv.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { rpcUrls } from '../../../providers/test/rpc-urls';
import { Contract as EssentialEthContract } from '../../Contract';
import { abi } from './crv-abi';

// The JSONABI
const JSONABI = abi;

const rpcURL = rpcUrls.mainnet;
Expand Down
3 changes: 1 addition & 2 deletions src/classes/test/Contract/ens.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Contract as EssentialEthContract } from '../../Contract';
import { rpcUrls } from './../../../providers/test/rpc-urls';
import { ensABI } from './ens-abi';

// The JSONABI
const JSONABI = ensABI;

const rpcURL = rpcUrls.mainnet;
Expand All @@ -27,6 +26,6 @@ const labelHash =
describe('eNS Base Registrar Expiration', () => {
it('should detect expiration properly', async () => {
const expiration = await essentialEthContract.nameExpires(labelHash);
expect(expiration.toNumber()).toBe(1853233633);
expect(expiration.toNumber()).toBeGreaterThan(2010913632);
});
});
1 change: 0 additions & 1 deletion src/classes/test/Contract/fei.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { Contract as EssentialEthContract } from '../../Contract';
import { rpcUrls } from './../../../providers/test/rpc-urls';
import { feiABI } from './fei-abi';

// The JSONABI
const JSONABI = feiABI;

const rpcURL = rpcUrls.mainnet;
Expand Down
10 changes: 10 additions & 0 deletions src/classes/test/Contract/jokerrace-abi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { JSONABI } from '../../../types/Contract.types';

export const abi: JSONABI = [
{
name: 'getAllAddressesThatHaveVoted',
outputs: [{ type: 'address[]', name: '' }],
inputs: [],
type: 'function',
},
];
19 changes: 19 additions & 0 deletions src/classes/test/Contract/jokerrace.integration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { z } from 'zod';
import { isAddress } from '../../../utils/is-address';
import { decodeRPCResponse } from '../../utils/encode-decode-transaction';
import { abi } from './jokerrace-abi';

describe('jokerrace contract', () => {
it('should decode "address[]"', async () => {
const nodeResponse =
'0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001300000000000000000000000067243d6c3c3bdc2f59d2f74ba1949a02973a529d0000000000000000000000000b06ca5dcc8a10be0951d4e140d4312702b8d0ec0000000000000000000000003fad8bcd2aea732d02a203c156b19205253f2a0600000000000000000000000073186b2a81952c2340c4eb2e74e89869e1183df000000000000000000000000087ece9936ad2254d03af83958fe3b202dc79793f00000000000000000000000068f272fcaae074cb33e68d88a32c325ed0df8379000000000000000000000000c9d20533c5b8a79526377e5d05dc79b87b28e92f000000000000000000000000e04885c3f1419c6e8495c33bdcf5f8387cd888460000000000000000000000000c887420937d8f9305ff872eaa5aaf5e379a811a0000000000000000000000007234c36a71ec237c2ae7698e8916e0735001e9af0000000000000000000000001c9f765c579f94f6502acd9fc356171d85a1f8d0000000000000000000000000ca85c622d4c61047f96e352cb919695486a193e6000000000000000000000000c11c6f47fe090a706ba82964b8a98f1682b244ff000000000000000000000000020f64f264ab7e90ef24a108c379a796a82175df000000000000000000000000eb2ee1250dc8c954da4eff4df0e4467a1ca6af6c0000000000000000000000003b60e31cfc48a9074cd5bebb26c9eaa77650a43f00000000000000000000000068d36dcbdd7bbf206e27134f28103abe7cf972df0000000000000000000000001a9cee6e1d21c3c09fb83a980ea54299f01920cd0000000000000000000000001d3bf13f8f7a83390d03db5e23a950778e1d1309';
const addresses = z
.array(z.string())
.parse(decodeRPCResponse(abi[0], nodeResponse));
expect(addresses.length).toBeGreaterThan(18);
expect(addresses).toContain('0x0b06ca5DcC8A10Be0951d4E140D4312702B8D0EC');
addresses.map((address) => {
expect(isAddress(address)).toBe(true);
});
});
});
1 change: 0 additions & 1 deletion src/classes/test/Contract/uni.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Contract as EssentialEthContract } from '../../Contract';
import { rpcUrls } from './../../../providers/test/rpc-urls';
import { uniswapABI } from './uniswap-abi';

// The JSONABI
const JSONABI = uniswapABI;

const rpcURL = rpcUrls.mainnet;
Expand Down
17 changes: 14 additions & 3 deletions src/classes/utils/encode-decode-transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ function expandType(type: ContractTypes) {
// https://docs.soliditylang.org/en/v0.8.7/types.html#integers
if (type === 'uint[]') {
return 'uint256[]';
} else if (type === 'int[]') {
}
if (type === 'int[]') {
return 'int256[]';
}
return type;
Expand Down Expand Up @@ -171,8 +172,17 @@ export function decodeRPCResponse(
return hexToUtf8(hexToDecode);
}
// chunk response every 64 characters
const encodedOutputs = slicedResponse.match(/.{1,64}/g);
const outputs = (encodedOutputs || []).map((output: string, i: number) => {
const encodedOutputs = slicedResponse.match(/.{1,64}/g) || [];
if (
jsonABIArgument?.outputs?.length === 1 &&
jsonABIArgument.outputs[0].type === 'address[]'
) {
const unformattedAddresses = encodedOutputs.slice(2);
return unformattedAddresses.map((unformattedAddress) => {
return toChecksumAddress(`0x${unformattedAddress.slice(24)}`);
});
}
const outputs = encodedOutputs.map((output: string, i: number) => {
const outputType = (rawOutputs || [])[i].type;
switch (outputType) {
case 'bool':
Expand All @@ -187,6 +197,7 @@ export function decodeRPCResponse(
return `0x${output}`;
case 'uint8':
return Number(hexToDecimal(`0x${output}`));

default:
throw new Error(
`essential-eth does not yet support "${outputType}" outputs. Make a PR today!"`,
Expand Down
63 changes: 31 additions & 32 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
export { Contract, BaseContract } from './classes/Contract';
export { BaseContract, Contract } from './classes/Contract';
export { AlchemyProvider } from './providers/AlchemyProvider';
export {
FallthroughProvider,
ConstructorOptions,
FallthroughProvider,
} from './providers/FallthroughProvider';
export { jsonRpcProvider, JsonRpcProvider } from './providers/JsonRpcProvider';
export { tinyBig, TinyBig } from './shared/tiny-big/tiny-big';
export { BlockResponse, RPCBlock, BlockTag } from './types/Block.types';
export { BlockResponse, BlockTag, RPCBlock } from './types/Block.types';
export {
ContractTypes,
JSONABI,
Expand All @@ -15,50 +15,49 @@ export {
export { Filter, FilterByBlockHash } from './types/Filter.types';
export { Network } from './types/Network.types';
export {
TransactionResponse,
BlockTransactionResponse,
Log,
RPCLog,
RPCTransaction,
RPCTransactionReceipt,
TransactionRequest,
RPCTransactionRequest,
TransactionReceipt,
RPCLog,
Log,
BlockTransactionResponse,
TransactionRequest,
TransactionResponse,
} from './types/Transaction.types';
export { computeAddress } from './utils/compute-address';
export { computePublicKey } from './utils/compute-public-key';
export { etherToGwei } from './utils/ether-to-gwei';
export { etherToWei } from './utils/ether-to-wei';
export { gweiToEther } from './utils/gwei-to-ether';
export { hashMessage } from './utils/hash-message';
export { isAddress } from './utils/is-address';
export { splitSignature } from './utils/split-signature';
export { toChecksumAddress } from './utils/to-checksum-address';
export { toUtf8Bytes } from './utils/to-utf8-bytes';
export { weiToEther } from './utils/wei-to-ether';

export {
arrayify,
Bytes,
BytesLike,
BytesLikeWithNumber,
concat,
DataOptions,
Hexable,
SignatureLike,
Signature,
isBytesLike,
isBytes,
arrayify,
concat,
stripZeros,
zeroPad,
isHexString,
hexlify,
hexConcat,
hexDataLength,
hexDataSlice,
hexConcat,
hexValue,
hexlify,
hexStripZeros,
hexValue,
hexZeroPad,
isBytes,
isBytesLike,
isHexString,
Signature,
SignatureLike,
stripZeros,
zeroPad,
} from './utils/bytes';
export { computeAddress } from './utils/compute-address';
export { computePublicKey } from './utils/compute-public-key';
export { etherToGwei } from './utils/ether-to-gwei';
export { etherToWei } from './utils/ether-to-wei';
export { gweiToEther } from './utils/gwei-to-ether';
export { hashMessage } from './utils/hash-message';
export { isAddress } from './utils/is-address';
export { keccak256 } from './utils/keccak256';
export { pack, solidityKeccak256 } from './utils/solidity-keccak256';
export { splitSignature } from './utils/split-signature';
export { toChecksumAddress } from './utils/to-checksum-address';
export { toUtf8Bytes } from './utils/to-utf8-bytes';
export { weiToEther } from './utils/wei-to-ether';

0 comments on commit 0067af4

Please sign in to comment.