> For the complete documentation index, see [llms.txt](https://docs.j.tools/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.j.tools/tools/wallets/multi-to-multi-relay.md).

# Multi to Multi Relay

[Multi to Multi Relay](https://j.tools/en/tools/multi-to-multi-relay) moves SOL or one SPL token across many paired wallets, where each source-to-destination pair travels through its own chain of freshly generated relay wallets instead of a direct send. You map source row one to destination row one, row two to row two, and so on. Every pair then hops its funds forward through a private chain of intermediate wallets you never reuse. It is the matrix version of [Relay Transfer](/tools/wallets/relay-transfer.md): instead of one route, you run many at once, and the tool tracks status, signature, and any error for every hop of every pair.

```mermaid
flowchart LR
  S1[Source 1]:::soft --> R
  S2[Source 2]:::soft --> R
  R{Relay chains}:::soft --> D[Destinations]:::brand
  D --> D1[Dest 1]:::soft
  D --> D2[Dest 2]:::soft
  classDef brand fill:#EF2A2A,stroke:#EF2A2A,color:#ffffff,font-weight:bold;
  classDef soft fill:#1f2937,stroke:#374151,color:#e5e7eb;
```

{% hint style="warning" %}
**About fees.** Every action has two costs: the Solana **network fee** paid to validators, and the **J Tools platform fee**. The platform fee always shows in the app before you confirm, and nothing is charged until you sign. Fees can change over time, so trust the in-app summary rather than a number you saw once.
{% endhint %}

The platform fee here is charged **per hop**, and every hop is its own transaction. Each pair runs as many hops as its relay depth plus one for the final delivery, so the total platform fee scales with both the number of pairs and the depth you pick. The in-app summary shows the full estimate, total pairs, total operations, network fee, and platform fee, before you run anything. See the [Fee schedule](/reference/fee-schedule.md) for the current rate.

## When to use this

* You have many source wallets that each need to reach a specific destination through controlled relay hops, not a shared sender or a single drop wallet.
* You want per-pair routing where each source-to-destination mapping gets its own chain of intermediate wallets.
* You are running a large multi-wallet distribution or airdrop and want pair-by-pair and hop-by-hop progress before and during the run.

If you want a single route through relay wallets, use [Relay Transfer](/tools/wallets/relay-transfer.md). For paired transfers without the relay hops, use [Many to Many](/tools/wallets/many-to-many.md). To fan one wallet out to many, use [Multi Sender](/tools/wallets/multi-sender.md). To sweep many wallets into one, use [Batch Collector](/tools/wallets/batch-collector.md).

## Before you start

* A source wallet private key for each source row. This tool reads raw keys directly. The connected wallet is optional and used only to attribute the commission, not to sign the hops.
* A list of destination addresses, exactly one per source row. The two counts must match or the run is blocked.
* For an SPL run, the token's mint address (pick it with the built-in token selector) and Fixed amounts. All and Percentage modes do not work for SPL. If you are unsure which token standard you are routing, the [SPL vs Token-2022](/concepts/spl-vs-token2022.md) note explains the difference.
* Enough SOL in each source. SOL runs need to cover every hop's forward amount, the per-hop platform fee, and network and priority fees. SPL runs need meaningfully more, because each relay wallet is first seeded with SOL for its fees and token-account rent.
* A working RPC connection. The tool routes through the browser gateway, so provider failover and the same-origin fallback apply.

{% hint style="danger" %}
**Keep the recovery file.** When the run starts, the private keys for every generated relay wallet, across every pair, are auto-downloaded as one `.xlsx`. If a hop fails, those funds sit in the last successful intermediate wallet, and that file is the only way to recover them. Treat it like cash. Store it offline and never paste a key back into chat or any web form.
{% endhint %}

## Step by step

{% stepper %}
{% step %}

### Pick the asset

Choose SOL, or switch to SPL and pick a token with the selector. The SPL list shows the connected wallet's tokens. The whole run moves one asset.
{% endstep %}

{% step %}

### Import the source wallets

Use the import modal to paste your source private keys. Each row's SOL balance, and the selected token balance for SPL, is hydrated in bulk and shown per row.
{% endstep %}

{% step %}

### Import the destinations

Paste destination addresses, one per line. The count must equal the number of sources. A mismatch warning blocks a clean run, so line both lists up in the same order.
{% endstep %}

{% step %}

### Set the amounts

Apply a bulk amount mode to every source at once, or tune each pair by hand. **All** sends the full source balance after route fees and the reserve, **Fixed** sends an exact amount, and **Percentage** sends a share of the balance. For SPL, only Fixed works.
{% endstep %}

{% step %}

### Set relay depth, timing, and priority

Choose the global relay depth with a preset or a custom value, and optionally override the depth for any single pair. Pick a fixed or random delay between hops, each from 0 to 120 seconds. Add a priority fee preset if you want to nudge transactions through during congestion.
{% endstep %}

{% step %}

### Review the summary

Check total pairs, total operations (the sum of depth plus one across every pair), the estimated network fee, the platform fee, and the total cost. Fix anything flagged before running.
{% endstep %}

{% step %}

### Execute and let it run

Click **Execute Multi Relay**. The recovery `.xlsx` of every generated relay key downloads automatically at the start. Each pair then reads its source balance, plans the hop amounts, generates a fresh chain of relay wallets, and hops the funds from source to relay to destination, charging the platform fee on each hop. SPL pairs first seed each relay wallet with SOL for fees and ATA rent.
{% endstep %}

{% step %}

### Watch the live table

The grouped table shows one row per pair, expandable to per-hop detail, with from, to, amount, status, signature, and any error. A failed hop stops only that pair; the others keep running. On completion a result modal shows successful and failed operation counts, the destination net amount, and the recovery download status.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Source rows are raw private keys, parsed server-side through the keypair flow, so your wallet extension is not prompted for each hop. This is why the tool's Phantom risk is rated low: the extension is not in the signing path.
{% endhint %}

[**Open Multi to Multi Relay in the app →**](https://j.tools/en/tools/multi-to-multi-relay)

## The options, explained

| Field                 | What it does                                                                                                                                                                      |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Token type            | SOL or SPL. SOL drains each hop forward; SPL seeds each relay wallet with SOL for fees, then forwards the token amount.                                                           |
| Token mint            | Required for SPL. The mint of the token to route, chosen with the token picker. Ignored for SOL.                                                                                  |
| Source rows           | One private key per source, up to 1000 rows. Each carries its own amount mode and value, and an optional per-pair relay depth.                                                    |
| Amount mode (per row) | **All** sends the full balance after route fees and the reserve. **Fixed** sends an exact amount above zero. **Percentage** sends a share from 0 to 100. SPL supports Fixed only. |
| Destination wallets   | One address per source row, paired by position. Counts must match, and each must be a valid Solana public key.                                                                    |
| Relay count (global)  | The default hop depth applied to every pair. Presets run up to 2500, the slider reaches 2500, and a custom value reaches 5000. Per pair, total hops = relay count + 1.            |
| Relay count (per row) | Optional override for a single pair's depth, from 1 to 5000. Falls back to the global value when unset.                                                                           |
| Delay mode            | Fixed waits a set number of seconds between hops; random samples a wait between a minimum and maximum. Each value is capped at 0 to 120 seconds.                                  |
| Priority fee          | A validator tip applied per transaction. Presets run from none up to express, with a custom option. Default is none.                                                              |

{% hint style="info" %}
Limits at a glance: up to 1000 pairs, relay depth from 1 to 5000 per pair, delays from 0 to 120 seconds, and a priority fee up to 2,000,000 micro-lamports. Large depth across many pairs produces very large total operation counts, and each hop is a separate signed transaction with its own network and platform fee.
{% endhint %}

## If something goes wrong

* **Source and destination counts do not match.** The run is blocked until both lists are the same length. Line them up in the same order, one destination per source.
* **A hop failed mid-run.** That pair stops at the first failure, and its funds rest in the last successful relay wallet. The other pairs keep going. Recover the stranded funds with the downloaded `.xlsx`. The tool does not auto-retry or auto-recover.
* **Not enough source SOL.** A SOL run checks that each source covers its forwards plus every hop's platform and network fees. SPL runs need more, because each relay wallet is seeded for fees and account rent; an underfunded SPL source throws an insufficient-balance error.
* **SPL with All or Percentage.** Those modes need a token balance, not a SOL balance, so SPL rejects them. Switch the SPL rows to Fixed amounts.

For the full list, see the [Error codes reference](/reference/error-codes.md).

## FAQ

<details>

<summary>How are sources matched to destinations?</summary>

By position. The first source routes to the first destination, the second to the second, and so on down the list. Keep both lists the same length and in the same order. A count mismatch blocks the run rather than guessing a pairing.

</details>

<details>

<summary>What happens if a hop in the middle of one pair fails?</summary>

Only that pair stops. Every hop after the failure in that pair is marked failed, and the funds stay in the last wallet that received them. The other pairs keep running. That wallet's key is in the `.xlsx` you downloaded at the start, so you can import it and move the funds yourself. Keep that file safe.

</details>

<details>

<summary>Why does an SPL run cost more SOL than a SOL run?</summary>

Each relay wallet has to pay its own transaction fees and hold rent for the token account it creates. The tool seeds every hop with the SOL it needs for that, so an SPL run requires more source SOL than moving plain SOL through the same number of hops.

</details>

<details>

<summary>How many pairs and hops can I use?</summary>

Up to 1000 pairs, with a relay depth from 1 to 5000 per pair. Every hop is a separate on-chain transaction with its own network and platform fee, plus any delay you set, so cost and runtime grow with both pair count and depth. The summary shows the full estimate before you run.

</details>

<details>

<summary>Does the connected wallet sign the hops?</summary>

No. Each source row is a raw private key, parsed server-side, and the hops sign with those keys and the generated relay keys. The connected wallet is optional and only attributes the [commission](/getting-started/glossary.md). This is a sign-by-key flow, not a Phantom adapter flow.

</details>

<details>

<summary>Does J Tools hold the relay wallets or their keys?</summary>

No. The relay wallets are generated in your session and their keys go straight into the recovery file you download. J Tools never stores them. If you lose that file, funds stranded in an intermediate wallet cannot be recovered.

</details>

## Related tools

{% content-ref url="/pages/nHTziE15NKeVLAQMnxv5" %}
[Relay Transfer](/tools/wallets/relay-transfer.md)
{% endcontent-ref %}

{% content-ref url="/pages/eyvl1w0Ri5KEBHvrUAxz" %}
[Many to Many](/tools/wallets/many-to-many.md)
{% endcontent-ref %}

{% content-ref url="/pages/ABVX2mBQDoCv7DEdVmKp" %}
[Multi Sender](/tools/wallets/multi-sender.md)
{% endcontent-ref %}

{% content-ref url="/pages/7CPBHR61Y6akMdkeSBGW" %}
[Batch Collector](/tools/wallets/batch-collector.md)
{% endcontent-ref %}

{% hint style="success" %}
**J Tools is non-custodial.** We never hold your private keys and never ask for them. Every transaction is built in your browser and signed by your own wallet. If any page ever asks you to paste a private key, stop, close it, and let us know.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.j.tools/tools/wallets/multi-to-multi-relay.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
