> ## Documentation Index
> Fetch the complete documentation index at: https://lemoncash.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Call Smart Contract

> Interact with smart contracts on the blockchain.

## Usage

### Simple transaction

```typescript theme={null}
await callSmartContract({
  contracts: [
    {
      contractAddress: "0x1234567890123456789012345678901234567890",
      functionName: "transfer",
      functionParams: ["0x0987654321098765432109876543210987654321", "1000000"],
      value: "0",
      chainId: ChainId.POLYGON,
    },
  ],
});
```

### Batch transaction

```typescript theme={null}
await callSmartContract({
  contracts: [
    {
      contractAddress: "0x1234567890123456789012345678901234567890",
      functionName: "transfer",
      functionParams: ["0x0987654321098765432109876543210987654321", "1000000"],
      value: "0",
      chainId: ChainId.POLYGON,
    },
    {
      contractAddress: "0x1234567890123456789012345678901234567890",
      functionName: "deposit",
      functionParams: ["0x0987654321098765432109876543210987654321", "1000000"],
      value: "0",
      chainId: ChainId.POLYGON,
    },
  ],
});
```

### Values for title and description

```typescript theme={null}
await callSmartContract({
  contracts: [
    {
      contractAddress: "0x1234567890123456789012345678901234567890",
      functionName: "transfer",
      functionParams: ["0x0987654321098765432109876543210987654321", "1000000"],
      value: "0",
      chainId: ChainId.POLYGON
    },
  ]
  titleValues: {
    amount: "100",
    token: "USDC",
  },
  descriptionValues: {
    recipient: "0x0987654321098765432109876543210987654321",
    network: "Polygon",
  },
});
```

## Parameters

```typescript theme={null}
type CallSmartContractInput = {
  contracts: ContractParams[];
  titleValues?: Record<string, string>;
  descriptionValues?: Record<string, string>;
}

type ContractParams = {
  contractAddress: '0x${string}';
  functionName: string;
  functionParams: unknown[];
  value: string;
  contractStandard?: ContractStandard;
  chainId: ChainId;
  permits?: Permit[];
}
```

<ParamField body="contractAddress" type="0x${string}" required>
  The address of the smart contract to interact with.
</ParamField>

<ParamField body="functionName" type="string" required>
  The name of the smart contract function to call.
</ParamField>

<ParamField body="functionParams" type="string | number[]" required>
  The parameters to pass to the smart contract function. Should be an empty
  array if no parameters are needed.
</ParamField>

<ParamField body="value" type="string" required>
  The amount of native currency (ETH, POL, etc.) to send with the transaction.
  Specify '0' if no native token is transferred.
</ParamField>

<ParamField body="contractStandard" type="ContractStandard">
  The contract standard if any (e.g., 'ERC20').
</ParamField>

<ParamField body="chainId" type="ChainId" required>
  The chain id to use for the smart contract call.
</ParamField>

<ParamField body="permits" type="Permit[]">
  Optional array of Permit2 permits for token approvals. Each permit must
  include: - `owner`: The address of the user wallet that owns the tokens. -
  `token`: The address of the ERC20 token to be approved. - `spender`: The
  address of the contract authorized to spend the tokens (must match the
  `contractAddress`). - `amount`: The maximum amount that can be spent, in the
  token's smallest unit (e.g., wei). - `deadline`: UNIX timestamp (in seconds)
  after which the permit expires. - `nonce`: Unique nonce (number) to prevent
  replay attacks.
</ParamField>

<ParamField body="titleValues" type="Record<string, string>">
  Optional values to interpolate into the method title. Use `{{key}}` placeholders in the method title, and provide the corresponding values here.

  **Note**: Any unreplaced placeholders (those without a corresponding value) will be automatically removed from the final text.

  Example: If the title is "Swap `{{amount}}` `{{token}}`", pass `{ amount: "100", token: "USDC" }` to display "Swap 100 USDC". If you only pass `{ amount: "100" }`, it will display "Swap 100" (the `{{token}}` placeholder is removed).
</ParamField>

<ParamField body="descriptionValues" type="Record<string, string>">
  Optional values to interpolate into the method description. Use `{{key}}` placeholders in the method description configuration, and provide the corresponding values here.

  **Note**: Any unreplaced placeholders (those without a corresponding value) will be automatically removed from the final text.

  Example: If the description is "Exchange `{{fromToken}}` for `{{toToken}}`", pass `{ fromToken: "USDC", toToken: "ETH" }` to display "Exchange USDC for ETH".
</ParamField>

## Returns

<CodeGroup>
  ```typescript CallSmartContractResponse theme={null}
  type CallSmartContractResponse = {
    result: TransactionResult.SUCCESS | TransactionResult.PENDING;
    data: {
      txHash: string;
    };
  } | {
    result: TransactionResult.FAILED;
    error: MiniAppError;
  } | {
    result: TransactionResult.CANCELLED;
  }
  ```

  ```typescript SUCCESS icon="check" theme={null}
  {
    result: 'SUCCESS',
    data: {
      txHash: '0x1234567890123456789012345678901234567890'
    }
  }
  ```

  ```typescript FAILED icon="ban" theme={null}
  {
    result: 'FAILED',
    error: {
      message: 'Insufficient balance',
      code: 'INSUFFICIENT_BALANCE'
    }
  }
  ```

  ```typescript CANCELLED icon="user-minus" theme={null}
  {
    result: 'CANCELLED',
  }
  ```

  ```typescript PENDING icon="clock" theme={null}
  {
    result: 'PENDING',
    data: {
      txHash: '0x1234567890123456789012345678901234567890'
    }
  }
  ```
</CodeGroup>

<ResponseField name="result" type="TransactionResult">
  The result of the smart contract call attempt. - `SUCCESS`: The smart contract
  call was successful. - `FAILED`: The smart contract call failed. -
  `CANCELLED`: The smart contract call was cancelled by the user. -
  `PENDING`: The smart contract call is pending confirmation.
</ResponseField>

<ResponseField name="data" type="object">
  Contains the transaction hash of the smart contract call transaction. Only
  present when the result is `SUCCESS` or `PENDING`. - `txHash`: The transaction hash.
</ResponseField>

<ResponseField name="error" type="MiniAppError">
  Contains the error information when the smart contract call fails. Only
  present when the result is `FAILED`. - `message`: The error message. - `code`:
  The error code.
</ResponseField>

## Demo

<div className="w-screen px-0 relative left-1/2 right-1/2 -mx-[50vw]">
  <video autoPlay muted loop playsInline className="w-full aspect-video rounded-xl" src="https://mintcdn.com/lemoncash/V3w-aDpCopaji2Ja/assets/videos/demo-call-smart-contract.mov?fit=max&auto=format&n=V3w-aDpCopaji2Ja&q=85&s=1ca28b76a99b0da3c0494b1c0d3e9c70" data-path="assets/videos/demo-call-smart-contract.mov" />
</div>

### Example using Permit2

Instead of requiring a user to submit a separate `approve` transaction before a contract can interact with their tokens, you can provide a signed permit. The service will automatically handle the one-time approval to the Permit2 contract if it hasn't been done already.

```typescript theme={null}
await callSmartContract({
  contracts: [
    {
      contractAddress: "0xDeFiProtocolContract...",
      functionName: "depositWithPermit",
      args: ["1000000000000000000", "PERMIT_PLACEHOLDER_0"],
      value: "0",
      permits: [
        {
          owner: wallet,
          token: "0xTokenAddress...",
          spender: "0xDeFiProtocolContract...",
          amount: "1000000000000000000",
          deadline: "1735689600",
          nonce: "0",
        },
      ],
      chainId: ChainId.POLYGON,
    },
  ],
});
```

### Permit Type

```typescript theme={null}
type Permit = {
  owner: Address; // User's wallet address
  token: Address; // ERC20 token address
  spender: Address; // Contract that will spend the tokens
  amount: string; // Amount in smallest unit (wei)
  deadline: string; // Unix timestamp in seconds
  nonce: string; // Unique number
};
```

## Using Permits

The SDK automatically handles all Permit2 complexity for you. You simply provide the permit data, and the SDK will:

1. Generate the EIP-712 signature
2. Handle the one-time ERC-20 approval to Permit2 if needed
3. Execute the transaction with the permit signature

Related resources:

* [Dragonfly's Permit2 Pattern Guide](https://github.com/dragonfly-xyz/useful-solidity-patterns/tree/main/patterns/permit2)
* [Uniswap Permit2 Documentation](https://docs.uniswap.org/contracts/permit2/overview)

## Related Functions

<CardGroup cols={2}>
  <Card title="Authenticate" icon="wallet" href="/functions/authenticate">
    Get user's wallet using SIWE.
  </Card>

  <Card title="Deposit" icon="arrow-down-right" href="/functions/deposit">
    Deposit funds to your Mini App Wallet.
  </Card>
</CardGroup>
