@ethersproject/abi#FunctionFragment TypeScript Examples
The following examples show how to use
@ethersproject/abi#FunctionFragment.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: hooks.ts From interface-v2 with GNU General Public License v3.0 | 6 votes |
function toCallState(
callResult: CallResult | undefined,
contractInterface: Interface | undefined,
fragment: FunctionFragment | undefined,
latestBlockNumber: number | undefined,
): CallState {
if (!callResult) return INVALID_CALL_STATE;
const { valid, data, blockNumber } = callResult;
if (!valid) return INVALID_CALL_STATE;
if (valid && !blockNumber) return LOADING_CALL_STATE;
if (!contractInterface || !fragment || !latestBlockNumber)
return LOADING_CALL_STATE;
const success = data && data.length > 2;
const syncing = (blockNumber ?? 0) < latestBlockNumber;
let result: Result | undefined = undefined;
if (success && data) {
try {
result = contractInterface.decodeFunctionResult(fragment, data);
} catch (error) {
console.debug('Result data parsing failed', fragment, data);
return {
valid: true,
loading: false,
error: true,
syncing,
result,
};
}
}
return {
valid: true,
loading: false,
syncing,
result: result,
error: !success,
};
}
Example #2
Source File: utils.ts From hardhat-deploy with MIT License | 6 votes |
export function mergeABIs(
abis: any[][],
options: {check: boolean; skipSupportsInterface: boolean}
): any[] {
if (abis.length === 0) {
return [];
}
const result: any[] = JSON.parse(JSON.stringify(abis[0]));
for (let i = 1; i < abis.length; i++) {
const abi = abis[i];
for (const fragment of abi) {
const newEthersFragment = Fragment.from(fragment);
// TODO constructor special handling ?
const foundSameSig = result.find((v) => {
const existingEthersFragment = Fragment.from(v);
if (v.type !== fragment.type) {
return false;
}
if (!existingEthersFragment) {
return v.name === fragment.name; // TODO fallback and receive hanlding
}
if (
existingEthersFragment.type === 'constructor' ||
newEthersFragment.type === 'constructor'
) {
return existingEthersFragment.name === newEthersFragment.name;
}
if (newEthersFragment.type === 'function') {
return (
Interface.getSighash(existingEthersFragment as FunctionFragment) ===
Interface.getSighash(newEthersFragment as FunctionFragment)
);
} else if (newEthersFragment.type === 'event') {
return existingEthersFragment.format() === newEthersFragment.format();
} else {
return v.name === fragment.name; // TODO fallback and receive hanlding
}
});
if (foundSameSig) {
if (
options.check &&
!(
options.skipSupportsInterface &&
fragment.name === 'supportsInterface'
)
) {
if (fragment.type === 'function') {
throw new Error(
`function "${fragment.name}" will shadow "${foundSameSig.name}". Please update code to avoid conflict.`
);
}
}
} else {
result.push(fragment);
}
}
}
return result;
}
Example #3
Source File: hooks.ts From vvs-ui with GNU General Public License v3.0 | 6 votes |
function toCallState(
callResult: CallResult | undefined,
contractInterface: Interface | undefined,
fragment: FunctionFragment | undefined,
latestBlockNumber: number | undefined,
): CallState {
if (!callResult) return INVALID_CALL_STATE
const { valid, data, blockNumber } = callResult
if (!valid) return INVALID_CALL_STATE
if (valid && !blockNumber) return LOADING_CALL_STATE
if (!contractInterface || !fragment || !latestBlockNumber) return LOADING_CALL_STATE
const success = data && data.length > 2
const syncing = (blockNumber ?? 0) < latestBlockNumber
let result: Result | undefined
if (success && data) {
try {
result = contractInterface.decodeFunctionResult(fragment, data)
} catch (error) {
console.debug('Result data parsing failed', fragment, data)
return {
valid: true,
loading: false,
error: true,
syncing,
result,
}
}
}
return {
valid: true,
loading: false,
syncing,
result,
error: !success,
}
}
Example #4
Source File: hooks.ts From luaswap-interface with GNU General Public License v3.0 | 6 votes |
function toCallState(
callResult: CallResult | undefined,
contractInterface: Interface | undefined,
fragment: FunctionFragment | undefined,
latestBlockNumber: number | undefined
): CallState {
if (!callResult) return INVALID_CALL_STATE
const { valid, data, blockNumber } = callResult
if (!valid) return INVALID_CALL_STATE
if (valid && !blockNumber) return LOADING_CALL_STATE
if (!contractInterface || !fragment || !latestBlockNumber) return LOADING_CALL_STATE
const success = data && data.length > 2
const syncing = (blockNumber ?? 0) < latestBlockNumber
let result: Result | undefined = undefined
if (success && data) {
try {
result = contractInterface.decodeFunctionResult(fragment, data)
} catch (error) {
console.debug('Result data parsing failed', fragment, data)
return {
valid: true,
loading: false,
error: true,
syncing,
result
}
}
}
return {
valid: true,
loading: false,
syncing,
result: result,
error: !success
}
}
Example #5
Source File: contract.ts From solana-solidity.js with Apache License 2.0 | 6 votes |
/** @internal */
protected buildCall(fragment: FunctionFragment, returnResult: boolean): ContractFunction {
return (...args: any[]) => {
const options = args[args.length - 1];
if (args.length > fragment.inputs.length && typeof options === 'object') {
return this.call(fragment, returnResult, args.slice(0, fragment.inputs.length), options);
} else {
return this.call(fragment, returnResult, args);
}
};
}
Example #6
Source File: transactions.ts From snapshot-plugins with MIT License | 6 votes |
export async function decodeContractTransaction(
network: string,
transaction: ModuleTransaction,
multiSendAddress: string
): Promise<ContractInteractionModuleTransaction> {
const decode = (abi: string | FunctionFragment[]) => {
const contractInterface = new InterfaceDecoder(abi);
const method = contractInterface.getMethodFragment(transaction.data);
contractInterface.decodeFunction(transaction.data, method); // Validate data can be decode by method.
return contractInteractionToModuleTransaction(
{
data: transaction.data,
nonce: 0,
to: transaction.to,
value: transaction.value,
method
},
multiSendAddress
);
};
const contractAbi = await getContractABI(network, transaction.to);
if (contractAbi) return decode(contractAbi);
const methodSignature = getMethodSignature(transaction.data);
if (methodSignature) {
const textSignatures = await fetchTextSignatures(methodSignature);
for (const signature of textSignatures) {
try {
return decode([FunctionFragment.fromString(signature)]);
} catch (e) {
console.warn('invalid abi for transaction');
}
}
}
throw new Error(`we were not able to decode this transaction`);
}
Example #7
Source File: decoder.ts From snapshot-plugins with MIT License | 6 votes |
public decodeFunction(
data: string,
fragmentOrName?: string | Fragment | JsonFragment
) {
const fragment = this.getMethodFragment(data, fragmentOrName);
if (!FunctionFragment.isFunctionFragment(fragment)) {
throw new Error(
`could not resolved to a function fragment fragmentOrName: ${fragmentOrName}`
);
}
const functionFragment = FunctionFragment.fromObject(fragment);
const decodedValues = this.decodeFunctionData(functionFragment.name, data);
return functionFragment.inputs.reduce((acc, parameter, index) => {
const value = decodedValues[index];
const formattedValue = this.formatParameter(parameter, value);
acc.push(formattedValue);
if (parameter.name) {
acc[parameter.name] = formattedValue;
}
return acc;
}, [] as string[]);
}
Example #8
Source File: abi.ts From snapshot-plugins with MIT License | 6 votes |
export function getContractTransactionData(
abi: string,
method: FunctionFragment,
values: string[]
) {
const contractInterface = new Interface(abi);
const parameterValues = method.inputs.map(extractMethodArgs(values));
return contractInterface.encodeFunctionData(method, parameterValues);
}
Example #9
Source File: abi.ts From snapshot-plugins with MIT License | 6 votes |
export function getABIWriteFunctions(abi: Fragment[]) {
const abiInterface = new Interface(abi);
return (
abiInterface.fragments
// Return only contract's functions
.filter(FunctionFragment.isFunctionFragment)
.map(FunctionFragment.fromObject)
// Return only write functions
.filter(isWriteFunction)
// Sort by name
.sort((a, b) => (a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1))
);
}
Example #10
Source File: hooks.ts From goose-frontend-amm with GNU General Public License v3.0 | 6 votes |
function toCallState(
callResult: CallResult | undefined,
contractInterface: Interface | undefined,
fragment: FunctionFragment | undefined,
latestBlockNumber: number | undefined
): CallState {
if (!callResult) return INVALID_CALL_STATE
const { valid, data, blockNumber } = callResult
if (!valid) return INVALID_CALL_STATE
if (valid && !blockNumber) return LOADING_CALL_STATE
if (!contractInterface || !fragment || !latestBlockNumber) return LOADING_CALL_STATE
const success = data && data.length > 2
const syncing = (blockNumber ?? 0) < latestBlockNumber
let result: Result | undefined
if (success && data) {
try {
result = contractInterface.decodeFunctionResult(fragment, data)
} catch (error) {
console.error('Result data parsing failed', fragment, data)
return {
valid: true,
loading: false,
error: true,
syncing,
result,
}
}
}
return {
valid: true,
loading: false,
syncing,
result,
error: !success,
}
}
Example #11
Source File: hooks.ts From glide-frontend with GNU General Public License v3.0 | 6 votes |
function toCallState(
callResult: CallResult | undefined,
contractInterface: Interface | undefined,
fragment: FunctionFragment | undefined,
latestBlockNumber: number | undefined,
): CallState {
if (!callResult) return INVALID_CALL_STATE
const { valid, data, blockNumber } = callResult
if (!valid) return INVALID_CALL_STATE
if (valid && !blockNumber) return LOADING_CALL_STATE
if (!contractInterface || !fragment || !latestBlockNumber) return LOADING_CALL_STATE
const success = data && data.length > 2
const syncing = (blockNumber ?? 0) < latestBlockNumber
let result: Result | undefined
if (success && data) {
try {
result = contractInterface.decodeFunctionResult(fragment, data)
} catch (error) {
console.debug('Result data parsing failed', fragment, data)
return {
valid: true,
loading: false,
error: true,
syncing,
result,
}
}
}
return {
valid: true,
loading: false,
syncing,
result,
error: !success,
}
}
Example #12
Source File: hooks.ts From limit-orders-lib with GNU General Public License v3.0 | 6 votes |
function toCallState(
callResult: CallResult | undefined,
contractInterface: Interface | undefined,
fragment: FunctionFragment | undefined,
latestBlockNumber: number | undefined
): CallState {
if (!callResult) return INVALID_CALL_STATE;
const { valid, data, blockNumber } = callResult;
if (!valid) return INVALID_CALL_STATE;
if (valid && !blockNumber) return LOADING_CALL_STATE;
if (!contractInterface || !fragment || !latestBlockNumber)
return LOADING_CALL_STATE;
const success = data && data.length > 2;
const syncing = (blockNumber ?? 0) < latestBlockNumber;
let result: Result | undefined = undefined;
if (success && data) {
try {
result = contractInterface.decodeFunctionResult(fragment, data);
} catch (error) {
console.debug("Result data parsing failed", fragment, data);
return {
valid: true,
loading: false,
error: true,
syncing,
result,
};
}
}
return {
valid: true,
loading: false,
syncing,
result: result,
error: !success,
};
}
Example #13
Source File: hooks.ts From cheeseswap-interface with GNU General Public License v3.0 | 6 votes |
function toCallState(
callResult: CallResult | undefined,
contractInterface: Interface | undefined,
fragment: FunctionFragment | undefined,
latestBlockNumber: number | undefined
): CallState {
if (!callResult) return INVALID_CALL_STATE
const { valid, data, blockNumber } = callResult
if (!valid) return INVALID_CALL_STATE
if (valid && !blockNumber) return LOADING_CALL_STATE
if (!contractInterface || !fragment || !latestBlockNumber) return LOADING_CALL_STATE
const success = data && data.length > 2
const syncing = (blockNumber ?? 0) < latestBlockNumber
let result: Result | undefined = undefined
if (success && data) {
try {
result = contractInterface.decodeFunctionResult(fragment, data)
} catch (error) {
console.debug('Result data parsing failed', fragment, data)
return {
valid: true,
loading: false,
error: true,
syncing,
result
}
}
}
return {
valid: true,
loading: false,
syncing,
result: result,
error: !success
}
}
Example #14
Source File: contract.ts From ethers-multicall with MIT License | 6 votes |
constructor(address: string, abi: JsonFragment[] | string[] | Fragment[]) {
this._address = address;
this._abi = toFragment(abi);
this._functions = this._abi.filter(x => x.type === 'function').map(x => FunctionFragment.from(x));
const callFunctions = this._functions.filter(x => x.stateMutability === 'pure' || x.stateMutability === 'view');
for (const callFunction of callFunctions) {
const { name } = callFunction;
const getCall = makeCallFunction(this, name);
if (!this[name]) {
defineReadOnly(this, name, getCall);
}
}
}
Example #15
Source File: hooks.ts From sybil-interface with GNU General Public License v3.0 | 6 votes |
function toCallState(
callResult: CallResult | undefined,
contractInterface: Interface | undefined,
fragment: FunctionFragment | undefined,
latestBlockNumber: number | undefined
): CallState {
if (!callResult) return INVALID_CALL_STATE
const { valid, data, blockNumber } = callResult
if (!valid) return INVALID_CALL_STATE
if (valid && !blockNumber) return LOADING_CALL_STATE
if (!contractInterface || !fragment || !latestBlockNumber) return LOADING_CALL_STATE
const success = data && data.length > 2
const syncing = (blockNumber ?? 0) < latestBlockNumber
let result: Result | undefined = undefined
if (success && data) {
try {
result = contractInterface.decodeFunctionResult(fragment, data)
} catch (error) {
console.debug('Result data parsing failed', fragment, data)
return {
valid: true,
loading: false,
error: true,
syncing,
result,
}
}
}
return {
valid: true,
loading: false,
syncing,
result: result,
error: !success,
}
}
Example #16
Source File: AbiParser.ts From useDApp with MIT License | 6 votes |
function makeCallParser(coder: Interface, fragment: FunctionFragment): CallParser {
return {
name: fragment.name,
parseCallData(data: string) {
try {
const decoded = coder.decodeFunctionData(fragment, data)
return fragment.inputs.map((input, i) => parseDecoded(input, decoded[i], i))
} catch {
return parseUnknownCallData(data)
}
},
parseCallResult(data: string) {
try {
if (fragment.outputs) {
const decoded = coder.decodeFunctionResult(fragment, data)
const items = fragment.outputs.map((input, i) => parseDecoded(input, decoded[i], i))
if (items.length === 1) {
return items[0]
} else {
return { type: 'tuple', name: '#0', value: items }
}
} else {
return parseUnknownCallResult(data)
}
} catch {
return parseUnknownCallResult(data)
}
},
}
}
Example #17
Source File: hooks.ts From cuiswap with GNU General Public License v3.0 | 6 votes |
function toCallState(
callResult: CallResult | undefined,
contractInterface: Interface | undefined,
fragment: FunctionFragment | undefined,
latestBlockNumber: number | undefined
): CallState {
if (!callResult) return INVALID_CALL_STATE
const { valid, data, blockNumber } = callResult
if (!valid) return INVALID_CALL_STATE
if (valid && !blockNumber) return LOADING_CALL_STATE
if (!contractInterface || !fragment || !latestBlockNumber) return LOADING_CALL_STATE
const success = data && data.length > 2
const syncing = (blockNumber ?? 0) < latestBlockNumber
let result: Result | undefined = undefined
if (success && data) {
try {
result = contractInterface.decodeFunctionResult(fragment, data)
} catch (error) {
console.debug('Result data parsing failed', fragment, data)
return {
valid: true,
loading: false,
error: true,
syncing,
result
}
}
}
return {
valid: true,
loading: false,
syncing,
result: result,
error: !success
}
}
Example #18
Source File: abi.ts From snapshot-plugins with MIT License | 5 votes |
export function parseMethodToABI(method: FunctionFragment) {
return [method.format(FormatTypes.full)];
}
Example #19
Source File: abi.ts From snapshot-plugins with MIT License | 5 votes |
export function isWriteFunction(method: FunctionFragment) {
if (!method.stateMutability) return true;
return !['view', 'pure'].includes(method.stateMutability);
}
Example #20
Source File: contract.ts From ethers-multicall with MIT License | 5 votes |
private _functions: FunctionFragment[];
Example #21
Source File: contract.ts From solana-solidity.js with Apache License 2.0 | 4 votes |
/** @internal */
protected async call<T extends boolean>(
fragment: FunctionFragment,
returnResult: T,
args: readonly any[],
options?: ContractCallOptions
): Promise<T extends true ? any : ContractFunctionResult> {
const payer = options?.payer || this.payer;
if (!payer) throw new MissingPayerAccountError();
const {
accounts = [],
writableAccounts = [],
programDerivedAddresses = [],
signers = [],
sender = payer.publicKey,
value = 0,
simulate = false,
ed25519sigs = [],
confirmOptions = {
commitment: 'confirmed',
skipPreflight: false,
preflightCommitment: 'processed',
},
} = options ?? {};
const seeds = programDerivedAddresses.map(({ seed }) => seed);
const input = this.interface.encodeFunctionData(fragment, args);
const data = Buffer.concat([
// storage account where state for this contract will be stored
this.storage.toBuffer(),
// msg.sender for this transaction
sender.toBuffer(),
// lamports to send to payable constructor
encodeU64(BigInt(value)),
// hash of contract name, 0 for function calls
Buffer.from('00000000', 'hex'),
// PDA seeds
encodeSeeds(seeds),
// eth abi encoded constructor arguments
Buffer.from(input.replace('0x', ''), 'hex'),
]);
const keys = [
...programDerivedAddresses.map(({ address }) => ({
pubkey: address,
isSigner: false,
isWritable: true,
})),
{
pubkey: this.storage,
isSigner: false,
isWritable: true,
},
{
pubkey: SYSVAR_CLOCK_PUBKEY,
isSigner: false,
isWritable: false,
},
{
pubkey: PublicKey.default,
isSigner: false,
isWritable: false,
},
...accounts.map((pubkey) => ({
pubkey,
isSigner: false,
isWritable: false,
})),
...writableAccounts.map((pubkey) => ({
pubkey,
isSigner: false,
isWritable: true,
})),
...signers.map((signer) => ({
pubkey: signer.publicKey,
isSigner: true,
isWritable: true,
})),
];
const transaction = new Transaction();
if (ed25519sigs.length > 0) {
keys.push({ pubkey: SYSVAR_INSTRUCTIONS_PUBKEY, isSigner: false, isWritable: false });
ed25519sigs.forEach(({ publicKey, message, signature }, index) => {
transaction.add(Ed25519Program.createInstructionWithPublicKey({
instructionIndex: index,
publicKey: publicKey.toBuffer(),
message,
signature,
}));
});
}
transaction.add(
new TransactionInstruction({
keys,
programId: this.program,
data,
})
);
// If the function is read-only, simulate the transaction to get the result
const { logs, encoded, computeUnitsUsed } =
simulate || fragment.stateMutability === 'view' || fragment.stateMutability === 'pure'
? await simulateTransactionWithLogs(this.connection, transaction, [payer, ...signers])
: await sendAndConfirmTransactionWithLogs(
this.connection,
transaction,
[payer, ...signers],
confirmOptions
);
const events = this.parseLogsEvents(logs);
const length = fragment.outputs?.length;
let result: Result | null = null;
if (length) {
if (!encoded) throw new MissingReturnDataError();
if (length == 1) {
[result] = this.interface.decodeFunctionResult(fragment, encoded);
} else {
result = this.interface.decodeFunctionResult(fragment, encoded);
}
}
if (returnResult === true)
return result as any;
return { result, logs, events, computeUnitsUsed };
}