> For the complete documentation index, see [llms.txt](https://docs.aboutcircles.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.aboutcircles.com/circles-sdk/pathfinder.md).

# Pathfinder

Circles pathfinder calculates “how much and through which tokens can flow from A to B” based on trust and balances (wrapped and unwrapped). You can use it to:

* Preview a route and achievable amount.
* Feed `TransferBuilder` or custom `operateFlowMatrix` calls.

### Entry points

* High-level SDK: `sdk.rpc.pathfinder.findPath / findMaxFlow` (`sdk.rpc` is a public property — no cast needed)
* Standalone: `const rpc = new CirclesRpc(config.circlesRpcUrl);`

#### Methods

* `findPath(params: FindPathParams): Promise<PathfindingResult>`
* `findMaxFlow(params: Omit<FindPathParams, 'targetFlow'>): Promise<bigint>`

### Parameters (FindPathParams)

* `from` (Address, required): Source avatar.
* `to` (Address, required): Destination avatar.
* `targetFlow` (bigint, required for `findPath`): Desired amount.
* `useWrappedBalances` (boolean, optional): Allow ERC20 wrappers in the route. **Set true if you hold wrapped CRC.**
* `fromTokens` / `toTokens` (Address\[], optional): Only allow these token owners from sender/recipient sides.
* `excludeFromTokens` / `excludeToTokens` (Address\[], optional): Ban specific token owners.
* `simulatedBalances` (array, optional): Inject hypothetical balances `{ holder, token, amount, isWrapped, isStatic }`.
* `simulatedTrusts` (array, optional): Inject hypothetical trust edges `{ truster, trustee }`.
* `simulatedConsentedAvatars` (Address\[], optional): Treat these addresses as having granted ERC‑1155 operator approval. Affects which intermediate hops count as valid.
* `maxTransfers` (number, optional): Hop cap; lower = faster, but may reduce flow.
* `debugShowIntermediateSteps` (boolean, optional): Populate `PathfindingResult.debug` with the pipeline transformation stages.

### `findPath` (targeted route)

Computes a path for a requested amount; returns what is actually achievable plus hop-by-hop legs.

```ts
import { CirclesRpc } from '@aboutcircles/sdk-rpc';

const rpc = new CirclesRpc('https://rpc.aboutcircles.com/');

const path = await rpc.pathfinder.findPath({
  from: '0xSender',
  to: '0xRecipient',
  targetFlow: BigInt('10000000000000000000'), // 10 CRC
  useWrappedBalances: true,
  fromTokens: ['0xPreferredToken'],  // optional pin
  excludeToTokens: ['0xAvoidToken'], // optional ban
  maxTransfers: 4
});

console.log(path.maxFlow);    // bigint achievable
console.log(path.transfers);  // [{ from, to, tokenOwner, value }]
```

`PathfindingResult`:

* `maxFlow` – achievable flow for this request.
* `transfers` – ordered legs; `tokenOwner` is the ERC1155 owner or wrapper used in that hop.
* `debug` – present only when `debugShowIntermediateSteps: true` was passed.

#### Debugging a route

Setting `debugShowIntermediateSteps: true` returns each stage of the transformation pipeline, which is useful when a route looks wrong and you need to see where it changed:

```ts
const path = await rpc.pathfinder.findPath({
  from, to, targetFlow,
  debugShowIntermediateSteps: true
});

path.debug?.rawPaths;       // raw solver output, incl. token-pool intermediary nodes
path.debug?.collapsed;      // token pools collapsed to direct avatar → avatar flows
path.debug?.routerInserted; // group mints routed (avatar → router → group)
path.debug?.sorted;         // final on-chain execution order (collateral before mints)
```

Each stage is a `TransferStep[]`. Leave the flag off in production — it makes the response considerably larger.

If `maxFlow < targetFlow`, decide to scale down or show an error.

### `findMaxFlow` (ceiling)

Returns the absolute maximum possible flow between two avatars with the same options.

```ts
const max = await rpc.pathfinder.findMaxFlow({
  from: '0xSender',
  to: '0xRecipient',
  useWrappedBalances: true,
  simulatedBalances: [
    { holder: '0xSender', token: '0xToken', amount: 5n * 10n ** 18n, isWrapped: false, isStatic: false }
  ],
});
```

Use for sliders, validation, or deciding if you must unwrap/wrap first.

### Advanced usage

* **Wrapped tokens:** `useWrappedBalances: true` enables consuming inflationary/demurraged ERC20 wrappers the sender holds.
* **Token pinning/bans:** Use `fromTokens`/`toTokens` to force specific personal or group tokens; use the `exclude*` variants to forbid costly or undesired wrappers.
* **Simulations:** `simulatedBalances` let you preview flows after an expected mint/wrap without waiting for indexer updates.
* **Hop limit:** `maxTransfers` curbs route length; helpful for UX responsiveness but may lower `maxFlow`.

### From path to execution

* Easiest: call `TransferBuilder.constructAdvancedTransfer(from, to, amount, options)`—it runs `findPath`, adds unwrap/rewrap, approvals, and returns an ordered tx array.
* Manual: convert `PathfindingResult` to `operateFlowMatrix`:

```ts
import { createFlowMatrix } from '@aboutcircles/sdk-pathfinder';
import { Core } from '@aboutcircles/sdk-core';

const core = new Core();
const rpc = new CirclesRpc(core.config.circlesRpcUrl);

const path = await rpc.pathfinder.findPath({ from, to, targetFlow, useWrappedBalances: true });
const flow = createFlowMatrix(from, to, path.maxFlow, path.transfers);

const tx = core.hubV2.operateFlowMatrix(
  flow.flowVertices,
  flow.flowEdges,
  flow.streams,
  flow.packedCoordinates
);
// send tx via your runner
```

### Pathfinder helper functions (when you build flows yourself)

* `createFlowMatrix(from, to, maxFlow, transfers)` – turns a `PathfindingResult` into `flowVertices`, `flowEdges`, `streams`, `packedCoordinates` for `hubV2.operateFlowMatrix`.
* `packCoordinates(flowVertices)` / `transformToFlowVertices(transfers)` – lower-level helpers used by `createFlowMatrix` for packing vertex coordinates.
* `getTokenInfoMapFromPath(from, rpcUrl, path)` – fetches token metadata for all tokens/wrappers in a path; feed into other helpers.
* `getWrappedTokensFromPath(path, tokenInfoMap)` – list wrapped tokens present in the path.
* `getExpectedUnwrappedTokenTotals(path, tokenInfoMap)` – estimate ERC1155 amounts recovered after unwrapping wrappers used in the path.
* `replaceWrappedTokensWithAvatars(path, tokenInfoMap)` – rewrite path legs to underlying avatar addresses (for ERC1155 semantics).
* `replaceWrappedTokens(path, unwrappedMap)` – replace wrapped token addresses using a precomputed mapping.
* `shrinkPathValues(path, sink, retainBps)` – scale down flows proportionally (e.g., execute only 70% of a path).
* `assertNoNettedFlowMismatch(path)` – throw if transfers do not net to zero (consistency check).
* `computeNettedFlow(path)` – derive net inflow/outflow per address for diagnostics.

### Error handling & tips

* `maxFlow === 0`: check mutual trust or unwrap static/demurraged balances back to ERC1155.
* Paths needing wrapped balances will fail unless `useWrappedBalances` is true.


---

# 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.aboutcircles.com/circles-sdk/pathfinder.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.
