# Submit a transaction to proxy

Fast network reaches consensus on a transaction in two stages:

1. A transaction is checked by individual validators and if it is valid, i.e., doesn't overspend, has the correct nonce, has a valid signature by the transaction sender, etc., the validator signs it. Once a quorum (2/3 of validators + 1) have provided their signature, the second stage can begin.
2. A certificate is constructed containing this quorum of validator signatures, and then this certificate is passed along to all the validators, who then check that there is indeed a quorum of validator signatures, and that these are correct, and only then update their local views of the account's state according to the transaction.

A proxy is used to handle this process for you, collapsing both steps into a single one. By providing the transaction with your sender signature on it, the proxy can then drive the whole process to completion.

This tutorial shows how to submit/confirm transactions using the [proxy RPC](/fast-archived/developers/fast-api/proxy-api.md).

## Fetch the next nonce

Fast doesn't enforce a total global order on transaction processing. However, it does require a per-account sequencing to protect against double-spending. To ensure the sequencing is respected, transactions initiated from the same account should carry an increasing nonce. For example, transaction *t*<sub>1</sub> carries nonce 1, transaction *t*<sub>2</sub> nonce 2, etc.

Through nonces, the validators can enforce a processing order on transactions originating from the same account. If the nonce is not the expected one, then the validators reject the transaction. Therefore, you must submit the transaction to Fast with the correct nonce to be accepted.

In simple applications, one can just keep track of this locally and increment it before building each transaction, but what if you lose track of this number? Or what if you have multiple users submitting transactions from the same account, e.g., using a multisig account or just a shared key?

In this case, you would simply query the proxy to find out what the next expected nonce is for your account.

When querying the proxy to get the next expected nonce of a given account, you need to use the [`proxy_getAccountInfo`](/fast-archived/developers/fast-api/proxy-api.md#proxy_getaccountinfo) endpoint.

Parameters `token_balances_filter` and `certificate_by_nonce` can be ignored, since the next nonce is always returned regardless of options.

```rust
  use std::time::{SystemTime, UNIX_EPOCH};
  use jsonrpsee::http_client::HttpClient;
  use fast_rust_examples::{fastset_types::*, client::ProxyRpcClient};

  let (sender_pub_key, sender_priv_key) = get_key_pair();
  let client = HttpClient::builder().build("https://proxy.fastset.xyz")?;
  let next_nonce = client.get_account_info(sender_pub_key, None, None, None).await?.next_nonce;
```

[<sup>source</sup>](https://github.com/Pi-Squared-Inc/fastset-rpc-docs/blob/457bbf314a5de50486483b04d4930f5d73c05a5f/rust-examples/examples/submit-a-transaction.rs#L5-L11)

## Submit a transaction

Sumitting a transaction is now straightforward. First, you construct the transaction with the fields you want, i.e., sender, recipient, and amount. For simplicity, we will use a native token transfer of 100 tokens as an example.

```rust
  let (recipient_pub_key, _recipient_priv_key) = get_key_pair();
  let txn_fee = 10_u64.pow(16);
  let amount = 100;
  client.faucet_drip(sender_pub_key, (txn_fee + amount).into(), None).await?;

  let claim = ClaimType::TokenTransfer(TokenTransfer {
    amount: amount.into(),
    user_data: UserData(None),
    token_id: TokenId::native(),
  });

  let tx = Transaction {
      sender: sender_pub_key,
      recipient: recipient_pub_key,
      nonce: next_nonce,
      claim,
      timestamp_nanos: SystemTime::now()
          .duration_since(UNIX_EPOCH)
          .expect("Current time is before the unix epoch")
          .as_nanos(),
      archival: false,
  };
```

[<sup>source</sup>](https://github.com/Pi-Squared-Inc/fastset-rpc-docs/blob/457bbf314a5de50486483b04d4930f5d73c05a5f/rust-examples/examples/submit-a-transaction.rs#L15-L36)

Then, you sign the transaction using your private key.

```rust
  let signature = SignatureOrMultiSig::Signature(Signature::new(&tx, &sender_priv_key));
```

[<sup>source</sup>](https://github.com/Pi-Squared-Inc/fastset-rpc-docs/blob/457bbf314a5de50486483b04d4930f5d73c05a5f/rust-examples/examples/submit-a-transaction.rs#L40-L40)

Then you submit both the transaction and the signature to the [`proxy_submitTransaction`](/fast-archived/developers/fast-api/proxy-api.md#set_proxy_submittransaction) endpoint. If everything goes well, this will submit and confirm the transaction `tx` on the Fast network.

```rust
  let res = client.submit_transaction(tx.clone(), signature).await?;
```

[<sup>source</sup>](https://github.com/Pi-Squared-Inc/fastset-rpc-docs/blob/457bbf314a5de50486483b04d4930f5d73c05a5f/rust-examples/examples/submit-a-transaction.rs#L44-L44)

{% hint style="warning" %}
Note a couple of complications that might occur.

If the network is out of sync in its view of your account, the proxy could fail because some of the validators need to be caught up on the transaction history for your account by submitting missing certificates.

However, if only some validators are behind, and behind by only one nonce, the proxy will be able to attempt to recover from this by itself, because it can query the pending transaction from the validators.
{% endhint %}

This is done with the [`proxy_submitTransaction`](/fast-archived/developers/fast-api/proxy-api.md#set_proxy_submittransaction) and [`proxy_submitVerifierSig`](/fast-archived/developers/fast-api/proxy-api.md#set_proxy_submitverifiersig) endpoints.

## Submit a transaction from a multisig account

To send transactions with the multisig account as the sender, use the same [`proxy_submitTransaction`](/fast-archived/developers/fast-api/proxy-api.md#set_proxy_submittransaction) endpoint as you would for single-signer accounts, but instead of the signature being `SignatureOrMultisig::Signature`, set it to `SignatureOrMultiSig::MultiSig` where the multisig contains enough signatures plus the same [`MultiSigConfig`](/fast-archived/developers/fast-api/data-types.md#multisigconfig) you created before. The sender field in the transactions must be set to the hash of the [`MultiSigConfig`](/fast-archived/developers/fast-api/data-types.md#multisigconfig) as described above.

Currently, for efficient validating of the multisigs, the list of signatures must be sorted by the address or public key of the signer.


---

# 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.fast.xyz/fast-archived/developers/tutorials/submit-a-transaction-to-proxy.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.
