# Use cases

{% hint style="info" %}
More cases can be found here: [https://github.com/YARlabs/YAR-v2-contracts/](https://github.com/YARlabs/YAR-v2-contracts/tree/main)
{% endhint %}

The YAR protocol allows sending arbitrary transactions to any address, whether it's a smart contract or an EOA wallet.

### Sending Transactions to an EOA Wallet

Such transactions usually only make sense when transferring the native token of the network, the amount of which is specified in the `value` parameter.

For example, a standard transaction within one network:

```typescript
sender.sendTransaction({
  from: sender.address, // sender
  to: recipient.address, // recipient
  value: 1e18, // amount of funds sent
})
```

To deliver a similar transaction to another network, it looks like this:

```typescript
yarRequest.send({
  initialChainId,
  sender: sender.address, // sender
  payer: sender.address, // sender
  targetChainId,
  target: recipient.address, // recipient
  value: 1e18, // amount of funds sent
  data: '0x',
  _nonce: 0,
})
```

After executing this transaction, the Relayers network will transfer 1e18 of the target network's native tokens to the recipient's address.

### Sending Transactions to a Smart Contract

Sending transactions to an arbitrary smart contract makes sense when the called method does not depend on the `msg.sender` address. For example, the address is passed in the arguments, or it involves meta-transactions or account abstraction.

For example, a standard transaction within one network:

```typescript
sender.sendTransaction({
    from: sender.address, // sender
    to: smartContract.address, // called smart contract
    value: 0, // amount of funds sent
    data: '0x11111...' // encoded transaction
})
```

To deliver a similar transaction to another network, it looks like this:

```typescript
yarRequest.send({
    initialChainId,
    sender: sender.address, // sender
    payer: sender.address, // sender
    targetChainId,
    target: smartContract.address, // called smart contract
    value: 0, // amount of funds sent
    data: '0x11111...', // encoded transaction
    _nonce: 0
})
```

By executing this transaction, the `YarResponse` smart contract will parse the bytes from `data` and call the specified function at the `target` address. You can also pass the `value` parameter with this transaction if needed.

Here's the English translation of the provided Russian text, formatted for a programming context:

***

### Cross-Chain API

The main potential of the Yar protocol lies in enabling communication between smart contracts of the same application located on different networks.\
Create an empty smart contract:

```solidity
contract Example {

}
```

Register the addresses of \[YarRequest] and \[YarResponse] in the smart contract:

```solidity
contract Example {
    address public yarRequest;
    address public yarResponse;

    constructor(
        address initialYarRequest,
        address initialYarResponse
    ) {
        yarRequest = initialYarRequest;
        yarResponse = initialYarResponse;
    }
}
```

To send a cross-chain transaction from a smart contract, the \[YarRequest] will require the data model \[YarLib.YarTX].

```solidity
library YarLib {
    struct YarTX {
        uint256 initialChainId; // Identifier of the current network
        address sender; // Your smart contract [Example]
        address payer; // User who calls Example and pays the fee in Yar
        uint256 targetChainId; // Identifier of the network where the transaction will be delivered
        address target; // Address in the [TARGET] network where the transaction will be called
        uint256 value; // Amount of the native token of the [TARGET] network to be sent with the transaction
        bytes data; // Encoded transaction data (bytes4 for the function signature + function arguments)
        uint256 _nonce; // This parameter will be redefined in YarRequest; set it to 0
    }
}
```

Import `YarLib` into your smart contract:

```solidity
import { YarLib } from "./YarLib.sol";

contract Example {
    ...
}
```

Develop a receiver function that will accept a string of data. Two checks are required to identify the senders:

1. Check that `msg.sender` equals the `yarResponse` address.
2. Check that `yarTX.sender` equals the address of your smart contract from the initial network.

```solidity
contract Example {
    string public lastMessage;

    function exampleReceiveMessage(string calldata message) external {
        require(msg.sender == yarResponse, "only yarResponse!");
        YarLib.YarTX memory yarTx = YarResponse(yarResponse).trustedYarTx();
        // Check against address(this)
        // - This will work if both smart contracts have the same address
        // If your smart contracts have different addresses, you will need to register them separately
        require(yarTx.sender == address(this), "only app!");
        lastMessage = message;
    }
}
```

Example of registering the addresses of your applications from external networks:

```solidity
contract Example {

    mapping(uint256 chainId => address peer) public peers;

    function setPeer(uint256 newChainId, address newPeer) external {
        require(msg.sender == owner, "only owner!");
        peers[newChainId] = newPeer;
    }

    function getPeer(uint256 _chainId) public view returns (address) {
        address peer = peers[_chainId];
        return peer == address(0) ? address(this) : peer;
    }

    function exampleReceiveMessage(string calldata message) external {
        require(msg.sender == yarResponse, "only yarResponse!");
        YarLib.YarTX memory yarTx = YarResponse(yarResponse).trustedYarTx();
        require(yarTx.sender == getPeer(yarTx.initialChainId), "only app!");
        ...
    }
}
```

Now, to make this function callable from another network, implement a message-sending function.

```solidity
contract Example {
    function exampleSendMessage(
        string calldata message,
        uint256 targetChainId
    ) external returns(YarLib.YarTX) {
        ...
    }
}
```

Where `message` is the message to be sent\
`targetChainId` is the network where the message will be delivered\
`returns(YarLib.YarTX)` is used in simulation for gas estimation.

Encode the call to the \[exampleReceiveMessage] function:

```solidity
bytes memory encodedTX = abi.encodeWithSelector(
    Example.exampleReceiveMessage.selector,
    message
);
```

Then create `YarTX`:

```solidity
YarLib.YarTX memory yarTx = YarLib.YarTX(
    block.chainid,
    address(this), // if your applications have identical addresses
    msg.sender,
    targetChainId,
    targetAddress,
    0,
    encodedTX,
    0
);
```

or

```solidity
YarLib.YarTX memory yarTx = YarLib.YarTX(
    block.chainid,
    getPeer(targetChainId), // to get the address of your application in the target network
    msg.sender,
    targetChainId,
    targetAddress,
    0,
    encodedTX,
    0
);
```

Next, send this model to `YarRequest`:

```solidity
contract Example {
    function exampleSendMessage(
        string calldata message,
        uint256 targetChainId
    ) external returns(YarLib.YarTX) {
        bytes memory encodedTX = abi.encodeWithSelector(
            Example.exampleReceiveMessage.selector,
            message
        );

        YarLib.YarTX memory yarTx = YarLib.YarTX(
            block.chainid,
            address(this), // if your applications have identical addresses
            msg.sender,
            targetChainId,
            targetAddress,
            0,
            encodedTX,
            0
        );

        // Send the transaction
        // Returning the model can be useful for transaction simulation and fee estimation
        return YarRequest(yarRequest).send(yarTX);
    }
}
```

Now, for the user to send a transaction from one of your smart contracts to another in an external network, they must have a balance in YarHub.

The balance can be topped up through `YarRequest`:

```solidity
yarRequest.connect(user).deposit(nativeTokenAmount);
```

Next, grant permission to your application to spend funds:

```solidity
yarRequest.connect(user).approve(yourAppFromInitialChainAddress, yarAmount);
```

Then, call your application:

```solidity
example.connect(user).exampleSendMessage('Hello!', targetChainId);
```

The rest will be handled by the YAR network.

First, the deposit will be credited in YarHub:

```solidity
yarHub.connect(relayers).deposit(user.address, yarTokenAmount);
```

Next, permission will be recorded for the transfer to the application:

```solidity
yarHub.connect(relayers).approve(user.address, initialChainId, yourAppFromInitialChainAddress, yarTokenAmount);
```

Then, the user's transaction will be added to the queue:

```solidity
yarHub.connect(relayers).createTransaction(yarTX, initialNativeTxHash);
```

After that, the transaction will be processed, temporarily locking sufficient funds on the user's deposit to complete the transaction:

```solidity
yarHub.connect(relayers).executeTransaction(yarTX, feeTokensToLock);
```

Finally, the YAR network will deliver the transaction to the target network:

```solidity
yarResponse.connect(relayers).deliver(yarTX);
```

In the target network, the `YarResponse` smart contract will execute the transaction:

```solidity
yarTx.target.call{ value: yarTx.value }(yarTx.data);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.yarchain.org/dev-docs/use-cases.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
