# Connector Routing

[[Source]](https://github.com/ripple/simpleXRPL/blob/main/docs/connector-routing.md)

How simpleXRPL dispatches each XRPL transactor per connector. Derived directly
from each custodian's native-operation set and the transactors the verticals
build, so it always matches the code.

## Transactor → connector path

The pipeline routes by transactor type: **Local** signs everything in-process;
a custodian uses its **native** operation when the transactor is in its
capability set, otherwise the **raw** sign-only fallback, otherwise the write
is rejected.

| Transactor | Local | Ripple Custody | Palisade |
|  --- | --- | --- | --- |
| `AccountSet` | signs locally | **native** | **native** |
| `Clawback` | signs locally | **native** | raw fallback¹ |
| `CredentialAccept` | signs locally | raw fallback¹ | raw fallback¹ |
| `CredentialCreate` | signs locally | raw fallback¹ | raw fallback¹ |
| `CredentialDelete` | signs locally | raw fallback¹ | raw fallback¹ |
| `DepositPreauth` | signs locally | **native** | raw fallback¹ |
| `EscrowFinish` | signs locally | **native** | raw fallback¹ |
| `MPTokenAuthorize` | signs locally | **native** | raw fallback¹ |
| `MPTokenIssuanceCreate` | signs locally | **native** | raw fallback¹ |
| `MPTokenIssuanceDestroy` | signs locally | **native** | raw fallback¹ |
| `MPTokenIssuanceSet` | signs locally | **native** | raw fallback¹ |
| `OfferCancel` | signs locally | raw fallback¹ | **native** |
| `OfferCreate` | signs locally | **native** | **native** |
| `Payment` | signs locally | **native** | **native** |
| `PermissionedDomainDelete` | signs locally | raw fallback¹ | raw fallback¹ |
| `PermissionedDomainSet` | signs locally | raw fallback¹ | raw fallback¹ |
| `SetRegularKey` | signs locally | raw fallback¹ | raw fallback¹ |
| `TrustSet` | signs locally | **native** | **native** |


¹ **raw fallback** applies only when raw signing is enabled on that custodian
(`allowRawSigning`). With raw signing disabled, a non-native transactor is
rejected with `SignerCapabilityError` — use a Local account or a custodian
that natively supports it. The raw path signs the encoded transaction and
submits it through the shared XRPL connection.

## Vertical → transactors

Which XRPL transactors each vertical builds. Cross-reference with the table
above to see how a given method routes on each connector.

| Vertical | Transactors emitted |
|  --- | --- |
| `account` | `AccountSet`, `DepositPreauth`, `Payment`, `SetRegularKey` |
| `credential` | `CredentialAccept`, `CredentialCreate`, `CredentialDelete` |
| `domain` | `PermissionedDomainDelete`, `PermissionedDomainSet` |
| `iou` | `AccountSet`, `Clawback`, `OfferCancel`, `OfferCreate`, `Payment`, `TrustSet` |
| `token` | `Clawback`, `MPTokenAuthorize`, `MPTokenIssuanceCreate`, `MPTokenIssuanceDestroy`, `MPTokenIssuanceSet`, `Payment` |
| `xrp` | `OfferCancel`, `OfferCreate`, `Payment` |


## Operation → native support

Each simpleXRPL write operation, the XRPL transactor(s) it emits, and whether
that operation is **native** on each custodian (all its transactors are in the
custodian's native-ops set) or falls back to **raw** signing. Local signs every
operation in-process. Read operations emit no transactor and are omitted.

| Operation | Transactor(s) | Ripple Custody | Palisade |
|  --- | --- | --- | --- |
| `XRP.transfer()` | `Payment` | **native** | **native** |
| `XRP.buyOffer()` | `OfferCreate` | **native** | **native** |
| `XRP.sellOffer()` | `OfferCreate` | **native** | **native** |
| `XRP.cancelOffer()` | `OfferCancel` | raw fallback¹ | **native** |
| `IOU.issue()` | `TrustSet`, `AccountSet`, `Payment` | **native** | **native** |
| `IOU.authorize()` | `TrustSet` | **native** | **native** |
| `IOU.lock()` | `TrustSet` | **native** | **native** |
| `IOU.unlock()` | `TrustSet` | **native** | **native** |
| `IOU.clawback()` | `Clawback` | **native** | raw fallback¹ |
| `IOU.transfer()` | `Payment` | **native** | **native** |
| `IOU.buyOffer()` | `OfferCreate` | **native** | **native** |
| `IOU.sellOffer()` | `OfferCreate` | **native** | **native** |
| `IOU.cancelOffer()` | `OfferCancel` | raw fallback¹ | **native** |
| `Token.issue()` | `MPTokenIssuanceCreate` | **native** | raw fallback¹ |
| `Token.authorize()` | `MPTokenAuthorize` | **native** | raw fallback¹ |
| `Token.unauthorize()` | `MPTokenAuthorize` | **native** | raw fallback¹ |
| `Token.grantHolder()` | `MPTokenAuthorize` | **native** | raw fallback¹ |
| `Token.revokeHolder()` | `MPTokenAuthorize` | **native** | raw fallback¹ |
| `Token.lock()` | `MPTokenIssuanceSet` | **native** | raw fallback¹ |
| `Token.unlock()` | `MPTokenIssuanceSet` | **native** | raw fallback¹ |
| `Token.destroy()` | `MPTokenIssuanceDestroy` | **native** | raw fallback¹ |
| `Token.transfer()` | `Payment` | **native** | raw fallback¹ |
| `Token.clawback()` | `Clawback` | **native** | raw fallback¹ |
| `Domain.create()` | `PermissionedDomainSet` | raw fallback¹ | raw fallback¹ |
| `Domain.setCredentials()` | `PermissionedDomainSet` | raw fallback¹ | raw fallback¹ |
| `Domain.delete()` | `PermissionedDomainDelete` | raw fallback¹ | raw fallback¹ |
| `Credential.issue()` | `CredentialCreate` | raw fallback¹ | raw fallback¹ |
| `Credential.accept()` | `CredentialAccept` | raw fallback¹ | raw fallback¹ |
| `Credential.delete()` | `CredentialDelete` | raw fallback¹ | raw fallback¹ |
| `Account.fund()` | `Payment`, `AccountSet` | **native** | **native** |
| `Account.activate()` | `Payment`, `AccountSet` | **native** | **native** |
| `Account.set()` | `AccountSet` | **native** | **native** |
| `Account.setRegularKey()` | `SetRegularKey` | raw fallback¹ | raw fallback¹ |
| `Account.depositPreauth()` | `DepositPreauth` | **native** | raw fallback¹ |


¹ **raw fallback** applies only when raw signing is enabled on that custodian
(`allowRawSigning`); otherwise the operation is rejected with
`SignerCapabilityError`. A multi-transactor operation (e.g. `IOU.issue`) is
native only when every step is native. **Palisade has no native MPT support**,
so the MPT-carrying operations `Token.transfer` and `Token.clawback` fall back
to raw there even though `Payment` and `Clawback` are otherwise native; Ripple
Custody handles MPT natively. The DEX offer operations
(`buyOffer` / `sellOffer` / `cancelOffer` on `iou` and `xrp`) never carry an
MPT — MPTs aren't DEX-tradeable — so they route purely on their `OfferCreate` /
`OfferCancel` legs: `buyOffer` / `sellOffer` are native on both custodians,
while `cancelOffer` is native on Palisade but falls back to raw on Ripple
Custody, which doesn't natively model `OfferCancel`.

*Native-ops sets: `NATIVE_XRPL_TRANSACTORS` (Ripple Custody),
`PALISADE_NATIVE_TRANSACTORS` (Palisade). Local signs all transactors.*