Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make decodeFunctionCall and decodeFunctionReturn available at web3-eth-abi #7345

Merged
merged 9 commits into from
Oct 22, 2024
58 changes: 55 additions & 3 deletions packages/web3-eth-abi/src/api/functions_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
*
* @module ABI
*/
import { AbiError } from 'web3-errors';
import { AbiError, Web3ContractError } from 'web3-errors';
import { sha3Raw } from 'web3-utils';
import { AbiFunctionFragment } from 'web3-types';
import { AbiConstructorFragment, AbiFunctionFragment, DecodedParams, HexString } from 'web3-types';
import { isAbiFunctionFragment, jsonInterfaceMethodToString } from '../utils.js';
import { encodeParameters } from './parameters_api.js';
import { decodeParameters, encodeParameters } from './parameters_api.js';

/**
* Encodes the function name to its ABI representation, which are the first 4 bytes of the sha3 of the function name including types.
Expand Down Expand Up @@ -143,3 +143,55 @@
params ?? [],
).replace('0x', '')}`;
};

export const decodeMethodParams = (
functionsAbis: AbiFunctionFragment | AbiConstructorFragment,
data: HexString,
methodSignatureProvided = true,
): DecodedParams & { __method__: string } => {

Check warning on line 151 in packages/web3-eth-abi/src/api/functions_api.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth-abi/src/api/functions_api.ts#L150-L151

Added lines #L150 - L151 were not covered by tests
const value =
methodSignatureProvided && data && data.length >= 10 && data.startsWith('0x')
? data.slice(10)
: data;
if (!functionsAbis.inputs) {
if (value !== '') {
throw new Web3ContractError('No inputs found in the ABI');
} else {
return {

Check warning on line 160 in packages/web3-eth-abi/src/api/functions_api.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth-abi/src/api/functions_api.ts#L153-L160

Added lines #L153 - L160 were not covered by tests
__length__: 0,
__method__: jsonInterfaceMethodToString(functionsAbis),
};
}
}
const result = decodeParameters([...functionsAbis.inputs], value);
return {

Check warning on line 167 in packages/web3-eth-abi/src/api/functions_api.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth-abi/src/api/functions_api.ts#L166-L167

Added lines #L166 - L167 were not covered by tests
...result,
__method__: jsonInterfaceMethodToString(functionsAbis),
};
};

export const decodeMethodReturn = (abi: AbiFunctionFragment, returnValues?: HexString) => {
// If it was constructor then we need to return contract address
if (abi.type === 'constructor') {
return returnValues;

Check warning on line 176 in packages/web3-eth-abi/src/api/functions_api.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth-abi/src/api/functions_api.ts#L175-L176

Added lines #L175 - L176 were not covered by tests
}

if (!returnValues) {

Check warning on line 179 in packages/web3-eth-abi/src/api/functions_api.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth-abi/src/api/functions_api.ts#L179

Added line #L179 was not covered by tests
// Using "null" value intentionally to match legacy behavior
// eslint-disable-next-line no-null/no-null
return null;

Check warning on line 182 in packages/web3-eth-abi/src/api/functions_api.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth-abi/src/api/functions_api.ts#L182

Added line #L182 was not covered by tests
Muhammad-Altabba marked this conversation as resolved.
Show resolved Hide resolved
}

const value = returnValues.length >= 2 ? returnValues.slice(2) : returnValues;
if (!abi.outputs) {

Check warning on line 186 in packages/web3-eth-abi/src/api/functions_api.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth-abi/src/api/functions_api.ts#L185-L186

Added lines #L185 - L186 were not covered by tests
// eslint-disable-next-line no-null/no-null
return null;

Check warning on line 188 in packages/web3-eth-abi/src/api/functions_api.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth-abi/src/api/functions_api.ts#L188

Added line #L188 was not covered by tests
}
const result = decodeParameters([...abi.outputs], value);

Check warning on line 190 in packages/web3-eth-abi/src/api/functions_api.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth-abi/src/api/functions_api.ts#L190

Added line #L190 was not covered by tests

if (result.__length__ === 1) {
return result[0];

Check warning on line 193 in packages/web3-eth-abi/src/api/functions_api.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth-abi/src/api/functions_api.ts#L192-L193

Added lines #L192 - L193 were not covered by tests
}

return result;

Check warning on line 196 in packages/web3-eth-abi/src/api/functions_api.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth-abi/src/api/functions_api.ts#L196

Added line #L196 was not covered by tests
};
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ along with web3.js. If not, see <http://www.gnu.org/licenses/>.

import { Web3ContractError } from 'web3-errors';
import { sendTransaction, SendTransactionEvents, SendTransactionOptions } from 'web3-eth';
import { decodeMethodParams } from 'web3-eth-abi';
import {
AbiConstructorFragment,
AbiFunctionFragment,
Expand All @@ -34,7 +35,7 @@ import {
import { format } from 'web3-utils';
import { isNullish } from 'web3-validator';
import { Web3PromiEvent } from 'web3-core';
import { decodeMethodParams, encodeMethodABI } from './encoding.js';
import { encodeMethodABI } from './encoding.js';
import { NonPayableTxOptions, PayableTxOptions } from './types.js';
import { getSendTxParams } from './utils.js';
// eslint-disable-next-line import/no-cycle
Expand Down
11 changes: 4 additions & 7 deletions packages/web3-eth-contract/src/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ import {
TransactionMiddleware,
} from 'web3-eth';
import {
decodeMethodReturn,
decodeMethodParams,
encodeEventSignature,
encodeFunctionSignature,
decodeContractErrorData,
Expand Down Expand Up @@ -99,12 +101,7 @@ import {
ValidationSchemaInput,
Web3ValidatorError,
} from 'web3-validator';
import {
decodeMethodReturn,
decodeMethodParams,
encodeEventABI,
encodeMethodABI,
} from './encoding.js';
import { encodeEventABI, encodeMethodABI } from './encoding.js';
import { ContractLogsSubscription } from './contract_log_subscription.js';
import {
ContractEventOptions,
Expand Down Expand Up @@ -1026,7 +1023,7 @@ export class Contract<Abi extends ContractAbi>
`The ABI for the provided method signature ${methodSignature} was not found.`,
);
}
return { ...decodeMethodParams(abi, data), __method__: jsonInterfaceMethodToString(abi) };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the property __method__ is now returned by decodeMethodParams.

return decodeMethodParams(abi, data);
}

private _parseAndSetJsonInterface(
Expand Down
48 changes: 6 additions & 42 deletions packages/web3-eth-contract/src/encoding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ import {
} from 'web3-types';

import {
decodeParameters,
decodeMethodParams as decodeMethodParamsFromEthAbi,
decodeMethodReturn as decodeMethodReturnFromEthAbi,
encodeEventSignature,
encodeFunctionSignature,
encodeParameter,
Expand Down Expand Up @@ -153,44 +154,7 @@ export const encodeMethodABI = (
return `${encodeFunctionSignature(abi)}${params}`;
};

export const decodeMethodParams = (
abi: AbiFunctionFragment | AbiConstructorFragment,
data: HexString,
methodSignatureProvided = true,
) => {
const value =
methodSignatureProvided && data && data.length >= 10 && data.startsWith('0x')
? data.slice(10)
: data;
if (!abi.inputs) {
throw new Web3ContractError('No inputs found in the ABI');
}
const result = decodeParameters([...abi.inputs], value);
return result;
};

export const decodeMethodReturn = (abi: AbiFunctionFragment, returnValues?: HexString) => {
// If it was constructor then we need to return contract address
if (abi.type === 'constructor') {
return returnValues;
}

if (!returnValues) {
// Using "null" value intentionally to match legacy behavior
// eslint-disable-next-line no-null/no-null
return null;
}

const value = returnValues.length >= 2 ? returnValues.slice(2) : returnValues;
if (!abi.outputs) {
// eslint-disable-next-line no-null/no-null
return null;
}
const result = decodeParameters([...abi.outputs], value);

if (result.__length__ === 1) {
return result[0];
}

return result;
};
/** @deprecated import from ''web3-eth-abi' instead. */
export const decodeMethodParams = decodeMethodParamsFromEthAbi;
/** @deprecated import from ''web3-eth-abi' instead. */
export const decodeMethodReturn = decodeMethodReturnFromEthAbi;
Loading