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

# Complex Cross Contract Call

> Batching, parallel actions, and callback handling.

export const Github = ({url, start, end, fname, withSourceLink = true}) => {
  const [code, setCode] = useState(null);
  function toRaw(ref) {
    const fullUrl = ref.slice(ref.indexOf('https'));
    const [url] = fullUrl.split('#');
    const [org, repo, , branch, ...pathSeg] = new URL(url).pathname.split('/').slice(1);
    return `https://raw.githubusercontent.com/${org}/${repo}/${branch}/${pathSeg.join('/')}`;
  }
  async function fetchCode(url, fromLine, toLine) {
    let res;
    if (typeof window !== 'undefined') {
      const validUntil = localStorage.getItem(`${url}-until`);
      if (validUntil && Number(validUntil) > Date.now()) {
        res = localStorage.getItem(url);
      }
    }
    if (!res) {
      try {
        res = await (await fetch(url)).text();
        if (typeof window !== 'undefined') {
          localStorage.setItem(url, res);
          localStorage.setItem(`${url}-until`, String(Date.now() + 60000));
        }
      } catch {
        return 'Error fetching code, please try reloading';
      }
    }
    let body = res.split('\n');
    const from = fromLine ? Number(fromLine) - 1 : 0;
    const to = toLine ? Number(toLine) : body.length;
    body = body.slice(from, to);
    const precedingSpace = body.reduce((prev, line) => {
      if (line.length === 0) return prev;
      const spaces = line.match(/^\s+/);
      if (spaces) return Math.min(prev, spaces[0].length);
      return 0;
    }, Infinity);
    return body.map(line => line.slice(precedingSpace === Infinity ? 0 : precedingSpace)).join('\n');
  }
  function buildSourceUrl(url, start, end) {
    const base = url.split('#')[0];
    if (start && end) return `${base}#L${start}-L${end}`;
    if (start) return `${base}#L${start}`;
    return base;
  }
  useEffect(() => {
    const rawUrl = toRaw(url);
    fetchCode(rawUrl, start, end).then(res => setCode(res));
  }, [url, start, end]);
  const sourceUrl = buildSourceUrl(url, start, end);
  const startLine = start ? Number(start) : 1;
  const fileName = fname ?? sourceUrl.split('/').pop();
  return <div className="rounded-[0.625rem] border border-[#d0d7de] dark:border-[#30363d] overflow-hidden my-5 text-[0.8125rem] font-mono shadow-sm dark:shadow-[0_4px_24px_rgba(0,0,0,0.18)]">

      {}
      <div className="flex items-center justify-between py-2 px-[0.875rem] bg-[#f6f8fa] dark:bg-[#161b22] border-b border-[#d0d7de] dark:border-[#30363d]">
        <div className="flex items-center gap-2 text-[#656d76] dark:text-[#8b949e]">
          <svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor">
            <path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z" />
          </svg>
          <span className="text-xs font-medium text-[#1f2328] dark:text-[#e6edf3]">
            {fileName}
          </span>
        </div>
        {start && end && <span className="text-[0.6875rem] text-[#656d76] dark:text-[#8b949e] bg-[#eaeef2] dark:bg-[#21262d] border border-[#d0d7de] dark:border-[#30363d] rounded-full py-0.5 px-2">
            Lines {start}–{end}
          </span>}
      </div>

      {}
      <div className="overflow-auto max-h-[480px] bg-white dark:bg-[#0d1117] [&_tr]:border-b-0 [&_td]:border-b-0">
        {code === null ? <div className="py-5 px-4 text-xs text-[#656d76] dark:text-[#6e7681]">
            Loading...
          </div> : <table className="w-full border-collapse leading-[1.6]">
            <tbody>
              {code.split('\n').map((line, i) => <tr key={i} className="align-top border-0">
                  <td style={{
    minWidth: '60px'
  }} className="select-none pl-2 pr-3 text-right text-[0.7rem] text-[#8c959f] dark:text-[#3d444d] w-[1%] whitespace-nowrap border-r border-0 border-r-[#d0d7de] dark:border-r-[#21262d]">
                    {startLine + i}
                  </td>
                  <td className="pl-4 pr-6 text-[0.8125rem] text-[#1f2328] dark:text-[#e6edf3] whitespace-pre">
                    {line || ' '}
                  </td>
                </tr>)}
            </tbody>
          </table>}
      </div>

      {}
      {withSourceLink && <div className="flex justify-end py-1.5 px-[0.875rem] bg-[#f6f8fa] dark:bg-[#161b22] border-t border-[#d0d7de] dark:border-[#21262d]">
          <a href={sourceUrl} target="_blank" rel="noreferrer noopener" className="text-[0.6875rem] font-medium text-[#656d76] dark:text-[#8b949e] no-underline flex items-center gap-[0.3rem] hover:text-[#1f2328] dark:hover:text-[#e6edf3] transition-colors">
            View on GitHub
            <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
              <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
              <polyline points="15 3 21 3 21 9" />
              <line x1="10" y1="14" x2="21" y2="3" />
            </svg>
          </a>
        </div>}
    </div>;
};

This example presents 3 instances of complex cross-contract calls on the NEAR blockchain, showcasing how to batch multiple function calls to a same contract, call multiple contracts in parallel, and handle responses in the callback. It includes both the smart contract and the frontend components.

<Info>
  **Simple Cross-Contract Calls**

  Check the tutorial on how to use [simple cross-contract calls](/smart-contracts/tutorials/cross-contracts/xcc)
</Info>

***

## Obtaining the Cross Contract Call Example

You have two options to start the Donation Example:

1. You can use the app through `Github Codespaces`, which will open a web-based interactive environment.
2. Clone the repository locally and use it from your computer.

| Codespaces                                                                                                                                      | Clone locally                                              |
| ----------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
| [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/near-examples/cross-contract-calls?quickstart=1) | 🌐 `https://github.com/near-examples/cross-contract-calls` |

***

## Structure of the Example

The smart contract is available in two flavors: Rust and JavaScript

<Tabs>
  <Tab title="🌐 JavaScript">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    ┌── sandbox-ts # sandbox testing
    │    ├── external-contracts
    │    │    ├── counter.wasm
    │    │    ├── guest-book.wasm
    │    │    └── hello-near.wasm
    │    └── main.ava.ts
    ├── src # contract's code
    │    ├── internal
    │    │    ├── batch_actions.ts
    │    │    ├── constants.ts
    │    │    ├── multiple_contracts.ts
    │    │    ├── similar_contracts.ts
    │    │    └── utils.ts
    │    └── contract.ts
    ├── package.json
    ├── README.md
    └── tsconfig.json
    ```
  </Tab>

  <Tab title="🦀 Rust">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    ┌── tests # sandbox testing
    │    ├── external-contracts
    │    │    ├── counter.wasm
    │    │    ├── guest-book.wasm
    │    │    └── hello-near.wasm
    │    └── main.ava.ts
    ├── src # contract's code
    │    ├── batch_actions.rs
    │    ├── lib.rs
    │    ├── multiple_contracts.rs
    │    └── similar_contracts.rs
    ├── Cargo.toml # package manager
    ├── README.md
    └── rust-toolchain.toml
    ```
  </Tab>
</Tabs>

***

## Smart Contract

### Batch Actions

You can aggregate multiple actions directed towards one same contract into a batched transaction.
Methods called this way are executed sequentially, with the added benefit that, if one fails then
they **all get reverted**.

<CodeGroup>
  <Github fname="contract.ts" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-ts/src/contract.ts" start="38" end="41" />

  <Github fname="batch_actions.ts" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-ts/src/internal/batch_actions.ts" start="5" end="17" />

  <Github fname="batch_actions.rs" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-rs/src/batch_actions.rs" start="8" end="20" />
</CodeGroup>

#### Getting the Last Response

In this case, the callback has access to the value returned by the **last
action** from the chain.

<CodeGroup>
  <Github fname="contract.ts" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-ts/src/contract.ts" start="43" end="46" />

  <Github fname="batch_actions.ts" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-ts/src/internal/batch_actions.ts" start="19" end="29" />

  <Github fname="utils.ts" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-ts/src/internal/utils.ts" start="3" end="20" />

  <Github fname="batch_actions.rs" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-rs/src/batch_actions.rs" start="22" end="35" />
</CodeGroup>

***

### Calling Multiple Contracts

A contract can call multiple other contracts. This creates multiple transactions that execute
all in parallel. If one of them fails the rest **ARE NOT REVERTED**.

<CodeGroup>
  <Github fname="contract.ts" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-ts/src/contract.ts" start="48" end="51" />

  <Github fname="multiple_contracts.ts" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-ts/src/internal/multiple_contracts.ts" start="6" end="21" />

  <Github fname="multiple_contracts.rs" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-rs/src/multiple_contracts.rs" start="16" end="55" />
</CodeGroup>

#### Getting All Responses

In this case, the callback has access to an **array of responses**, which have either the
value returned by each call, or an error message.

<CodeGroup>
  <Github fname="contract.ts" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-ts/src/contract.ts" start="53" end="58" />

  <Github fname="multiple_contracts.ts" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-ts/src/internal/multiple_contracts.ts" start="24" end="41" />

  <Github fname="utils.ts" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-ts/src/internal/utils.ts" start="3" end="20" />

  <Github fname="multiple_contracts.rs" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-rs/src/multiple_contracts.rs" start="58" end="92" />
</CodeGroup>

***

### Multiple Calls - Same Result Type

This example is a particular case of the previous one ([Calling Multiple Contracts](#calling-multiple-contracts)).
It simply showcases a different way to check the results by directly accessing the `promise_result` array.

In this case, we call multiple contracts that will return the same type:

<CodeGroup>
  <Github fname="contract.ts" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-ts/src/contract.ts" start="65" end="70" />

  <Github fname="similar_contracts.ts" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-ts/src/internal/similar_contracts.ts" start="6" end="35" />

  <Github fname="similar_contracts.rs" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-rs/src/similar_contracts.rs" start="8" end="31" />
</CodeGroup>

#### Getting All Responses

In this case, the callback again has access to an **array of responses**, which we can iterate checking the
results.

<CodeGroup>
  <Github fname="contract.ts" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-ts/src/contract.ts" start="62" end="65" />

  <Github fname="similar_contracts.ts" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-ts/src/internal/similar_contracts.ts" start="37" end="54" />

  <Github fname="utils.ts" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-ts/src/internal/utils.ts" start="3" end="20" />

  <Github fname="similar_contracts.rs" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-rs/src/similar_contracts.rs" start="32" end="57" />
</CodeGroup>

***

### Testing the Contract

The contract readily includes a set of unit and sandbox testing to validate its functionality. To execute the tests, run the following commands:

<Tabs>
  <Tab title="🌐 JavaScript">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    cd contract-advanced-ts
    yarn
    yarn test
    ```
  </Tab>

  <Tab title="🦀 Rust">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    cd contract-advanced-rs
    cargo test
    ```
  </Tab>
</Tabs>

<Tip>
  The `integration tests` use a sandbox to create NEAR users and simulate interactions with the contract.
</Tip>

### Deploying the Contract to the NEAR network

In order to deploy the contract you will need to create a NEAR account.

<Tabs>
  <Tab title="Short">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    # Create a new account pre-funded by a faucet
    near create-account <accountId> --useFaucet
    ```
  </Tab>

  <Tab title="Full">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    # Create a new account pre-funded by a faucet
    near account create-account sponsor-by-faucet-service <my-new-dev-account>.testnet autogenerate-new-keypair save-to-keychain network-config testnet create
    ```
  </Tab>
</Tabs>

Go into the directory containing the smart contract (`cd contract-advanced-ts` or `cd contract-advanced-rs`), build and deploy it:

<Tabs>
  <Tab title="🌐 JavaScript">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    npm run build
    near deploy <accountId> ./build/cross_contract.wasm --initFunction new --initArgs '{"hello_account":"hello.near-example.testnet","guestbook_account":"guestbook_account.near-example.testnet","counter_account":"counter_account.near-example.testnet"}'
    ```
  </Tab>

  <Tab title="🦀 Rust">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    cargo near deploy build-non-reproducible-wasm <accountId> with-init-call new json-args '{"hello_account":"hello.near-example.testnet","guestbook_account":"guestbook_account.near-example.testnet","counter_account":"counter_account.near-example.testnet"}' prepaid-gas '100.0 Tgas' attached-deposit '0 NEAR' network-config testnet sign-with-keychain send
    ```
  </Tab>
</Tabs>

### CLI: Interacting with the Contract

To interact with the contract through the console, you can use the following commands:

<Tabs>
  <Tab title="Short">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    # Execute contracts sequentially
    # Replace <accountId> with your account ID
    near call <accountId> batch_actions --useAccount <accountId> --gas 300000000000000   

    # Execute contracts in parallel
    # Replace <accountId> with your account ID
    near call <accountId>  multiple_contracts --useAccount <accountId> --gas 300000000000000   

    # Execute multiple instances of the same contract in parallel
    # Replace <accountId> with your account ID
    near call <accountId> similar_contracts --useAccount <accountId> --gas 300000000000000
    ```
  </Tab>

  <Tab title="Full">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    # Execute contracts sequentially
    # Replace <accountId> with your account ID
    near contract call-function as-transaction <accountId> batch_actions json-args '{}' prepaid-gas '300.0 Tgas' attached-deposit '0 NEAR' sign-as <accountId> network-config testnet sign-with-keychain send

    # Execute contracts in parallel
    # Replace <accountId> with your account ID
    near contract call-function as-transaction <accountId> multiple_contracts json-args '{}' prepaid-gas '300.0 Tgas' attached-deposit '0 NEAR' sign-as <accountId> network-config testnet sign-with-keychain send

    # Execute multiple instances of the same contract in parallel
    # Replace <accountId> with your account ID
    near contract call-function as-transaction <accountId> similar_contracts json-args '{}' prepaid-gas '300.0 Tgas' attached-deposit '0 NEAR' sign-as <accountId> network-config testnet sign-with-keychain send
    ```
  </Tab>
</Tabs>

<Info>
  If at some point you get an "Exceeded the prepaid gas" error, try to increase the gas amount used within the functions when calling other contracts
</Info>

<Note>
  **Versioning for this article**

  At the time of this writing, this example works with the following versions:

  * near-cli: `4.0.13`
  * node: `18.19.1`
  * rustc: `1.77.0`
</Note>
