@ethersproject/abi#Result TypeScript Examples

The following examples show how to use @ethersproject/abi#Result. 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: abi.ts    From ethcall with MIT License 6 votes vote down vote up
static decode(
    name: string,
    jsonOutputs: JsonFragmentType[],
    data: string,
  ): Result {
    const outputs = backfillParamNames(jsonOutputs);
    const abi = [
      {
        type: 'function',
        name,
        outputs,
      },
    ];
    const coder = new Coder(abi);

    const functionOutput = coder.decodeFunctionOutput(name, data);
    return outputs.map((output) => functionOutput.values[output.name || '']);
  }
Example #2
Source File: call.ts    From ethcall with MIT License 6 votes vote down vote up
async function callDeployless(
  provider: BaseProvider,
  callRequests: CallRequest[],
  block?: BlockTag,
): Promise<Result> {
  const inputAbi: JsonFragment[] = deploylessMulticallAbi;
  const constructor = inputAbi.find((f) => f.type === 'constructor');
  const inputs = constructor?.inputs || [];
  const args = Abi.encodeConstructor(inputs, [callRequests]);
  const data = hexConcat([deploylessMulticallBytecode, args]);
  const callData = await provider.call(
    {
      data,
    },
    block,
  );
  const outputAbi: JsonFragment[] = multicallAbi;
  const outputFunc = outputAbi.find(
    (f) => f.type === 'function' && f.name === 'aggregate',
  );
  const name = outputFunc?.name || '';
  const outputs = outputFunc?.outputs || [];
  const response = Abi.decode(name, outputs, callData);
  return response;
}
Example #3
Source File: call.ts    From ethcall with MIT License 6 votes vote down vote up
async function callDeployless2(
  provider: BaseProvider,
  callRequests: CallRequest[],
  block?: BlockTag,
): Promise<Result> {
  const inputAbi: JsonFragment[] = deploylessMulticall2Abi;
  const constructor = inputAbi.find((f) => f.type === 'constructor');
  const inputs = constructor?.inputs || [];
  const args = Abi.encodeConstructor(inputs, [false, callRequests]);
  const data = hexConcat([deploylessMulticall2Bytecode, args]);
  const callData = await provider.call(
    {
      data,
    },
    block,
  );
  const outputAbi: JsonFragment[] = multicall2Abi;
  const outputFunc = outputAbi.find(
    (f) => f.type === 'function' && f.name === 'tryAggregate',
  );
  const name = outputFunc?.name || '';
  const outputs = outputFunc?.outputs || [];
  // Note "[0]": low-level calls don't automatically unwrap tuple output
  const response = Abi.decode(name, outputs, callData)[0];
  return response as CallResult[];
}
Example #4
Source File: call.ts    From ethcall with MIT License 6 votes vote down vote up
async function callDeployless3(
  provider: BaseProvider,
  callRequests: CallRequest[],
  block?: BlockTag,
): Promise<Result> {
  const inputAbi: JsonFragment[] = deploylessMulticall3Abi;
  const constructor = inputAbi.find((f) => f.type === 'constructor');
  const inputs = constructor?.inputs || [];
  const args = Abi.encodeConstructor(inputs, [callRequests]);
  const data = hexConcat([deploylessMulticall3Bytecode, args]);
  const callData = await provider.call(
    {
      data,
    },
    block,
  );
  const outputAbi: JsonFragment[] = multicall3Abi;
  const outputFunc = outputAbi.find(
    (f) => f.type === 'function' && f.name === 'aggregate3',
  );
  const name = outputFunc?.name || '';
  const outputs = outputFunc?.outputs || [];
  // Note "[0]": low-level calls don't automatically unwrap tuple output
  const response = Abi.decode(name, outputs, callData)[0];
  return response as CallResult[];
}
Example #5
Source File: web3utils.ts    From lyra-protocol with ISC License 6 votes vote down vote up
export function getEventArgs(receipt: ContractReceipt, eventName: string): Result {
  const value = receipt.events!.find(e => e.event === eventName);
  if (value == undefined || value.args == undefined) {
    throw new Error(`Could not find event ${eventName}`);
  }
  return value.args;
}
Example #6
Source File: index.ts    From snapshot-plugins with MIT License 4 votes vote down vote up
async loadClaimBondData(
    web3: any,
    network: string,
    questionId: string,
    oracleAddress: string
  ) {
    const contract = new Contract(oracleAddress, ORACLE_ABI, web3);
    const provider: StaticJsonRpcProvider = getProvider(network);
    const account = (await web3.listAccounts())[0];

    const [
      [userBalance],
      [bestAnswer],
      [historyHash],
      [isFinalized]
    ] = await multicall(network, provider, ORACLE_ABI, [
      [oracleAddress, 'balanceOf', [account]],
      [oracleAddress, 'getBestAnswer', [questionId]],
      [oracleAddress, 'getHistoryHash', [questionId]],
      [oracleAddress, 'isFinalized', [questionId]]
    ]);

    let tokenSymbol = 'ETH';
    let tokenDecimals = 18;

    try {
      const token = await call(provider, ORACLE_ABI, [
        oracleAddress,
        'token',
        []
      ]);
      const [[symbol], [decimals]] = await multicall(
        network,
        provider,
        ERC20_ABI,
        [
          [token, 'symbol', []],
          [token, 'decimals', []]
        ]
      );

      tokenSymbol = symbol;
      tokenDecimals = decimals;
    } catch (e) {}

    const answersFilter = contract.filters.LogNewAnswer(null, questionId);
    const events = await contract.queryFilter(
      answersFilter,
      START_BLOCKS[network]
    );

    const users: Result[] = [];
    const historyHashes: Result[] = [];
    const bonds: Result[] = [];
    const answers: Result[] = [];

    // We need to send the information from last to first
    events.reverse().forEach(({ args }) => {
      users.push(args?.user.toLowerCase());
      historyHashes.push(args?.history_hash);
      bonds.push(args?.bond);
      answers.push(args?.answer);
    });

    const alreadyClaimed = BigNumber.from(historyHash).eq(0);
    const address = account.toLowerCase();

    // Check if current user has submitted an answer
    const currentUserAnswers = users.map((user, i) => {
      if (user === address) return answers[i];
    });

    // If the user has answers, check if one of them is the winner
    const votedForCorrectQuestion =
      currentUserAnswers.some((answer) => {
        if (answer) {
          return BigNumber.from(answer).eq(bestAnswer);
        }
      }) && isFinalized;

    // If user has balance in the contract, he should be able to withdraw
    const hasBalance = !userBalance.eq(0) && isFinalized;

    // Remove the first history and add an empty one
    // More info: https://github.com/realitio/realitio-contracts/blob/master/truffle/contracts/Realitio.sol#L502
    historyHashes.shift();
    const firstHash = '0x0000000000000000000000000000000000000000000000000000000000000000' as unknown;
    historyHashes.push(firstHash as Result);

    return {
      tokenSymbol,
      tokenDecimals,
      canClaim: (!alreadyClaimed && votedForCorrectQuestion) || hasBalance,
      data: {
        length: [bonds.length.toString()],
        historyHashes,
        users,
        bonds,
        answers
      }
    };
  }
Example #7
Source File: contract.ts    From solana-solidity.js with Apache License 2.0 4 votes vote down vote up
/** @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 };
    }