> ## Documentation Index
> Fetch the complete documentation index at: https://docs.soran.domains/llms.txt
> Use this file to discover all available pages before exploring further.

# Supported addresses and memos

> Classic G accounts, optional memos, muxed M destinations and contract C addresses, with examples.

Soran's deployed payment interface returns a **destination address and an optional memo together**. It supports classic Stellar `G...` accounts, muxed `M...` destinations and Soroban `C...` contract addresses. The Resolver stores muxed destinations as an explicit base G account and unsigned 64-bit ID; the SDK and HTTP result encode that pair as the complete M address.

These are payment-destination capabilities, not a promise that every wallet can sign for every account type. This page describes the deployed Resolver payment ABI 2, Lookup ABI 2, Lookup SDK 0.6.0 and Holder SDK 0.4.0 in [release status](/reference/release-status).

<Note>
  The SDK examples below use published Lookup **0.6.0** and Holder **0.4.0**. These versions preserve M destinations; older SDKs cannot. The same on-chain instructions are available through the [contract methods](/api/onchain-resolution), [HTTP payment endpoint](/api/resolution) and app.
</Note>

## Support at a glance

| Destination                     | Current Soran support | Payment handling                                                                     |
| ------------------------------- | --------------------- | ------------------------------------------------------------------------------------ |
| Classic `G...`, without a memo  | Yes                   | Return `memo: { type: "none" }`; a classic payment can use the G address             |
| Classic `G...` with an ID memo  | Yes                   | For a classic payment, include the exact unsigned 64-bit ID as a transaction memo    |
| Classic `G...` with a text memo | Yes                   | For a classic payment, include the exact 1–28 UTF-8 bytes as a transaction memo      |
| Classic `G...` with a hash memo | Yes                   | For a classic payment, include the exact 32 bytes as a transaction hash memo         |
| Soroban contract `C...`         | Yes, with `none` only | Use the supported Soroban asset/token transfer flow, not a classic Payment operation |
| Muxed `M...`                    | Yes, with `none` only | Use the full M address as a supported payment destination; preserve its embedded ID  |

No memo is required for an ordinary memo-free record. A recipient account's own memo-required policy still applies. Other memo variants, including return-hash, and arbitrary contract routing arguments are outside this Soran ABI.

Contract-account senders need a compatible transfer flow that preserves the recipient's routing requirement. Soroban transfers cannot use the classic transaction memo field. A supported numeric-ID route may use muxed transfer support if the receiver supports it; text and hash memos must not be dropped or silently converted. Refuse a payment when the chosen flow cannot carry its required instruction. See [Stellar's contract-account payment guide](https://developers.stellar.org/docs/build/guides/transactions/send-and-receive-c-accounts).

## Example destinations

The examples below show complete, validly encoded values. They are illustrative: the account comes from Stellar's documentation, the contract address is synthetic, and these names are not promised to exist. Do not send funds to these examples.

### Classic account without a memo

An ordinary `alice.nova` payment could resolve to:

```json theme={null}
{
  "address": "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ",
  "memo": { "type": "none" }
}
```

No customer memo was published in this instruction. The holder does not have to add one to use Soran.

### Classic account with an ID memo

An exchange deposit name such as `customer420.nova` could resolve to:

```json theme={null}
{
  "address": "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ",
  "memo": { "type": "id", "value": "420" }
}
```

The wallet sends to that G account with **Memo ID 420**. The memo type matters: text `"420"` is a different instruction. IDs range from `0` to `18446744073709551615`; preserve them as decimal strings, with no leading zeroes except `"0"`.

The exchange supplies the actual account and customer memo. A Soran name removes the need to copy those fields separately; it does not remove the wallet's duty to put the memo in the payment.

### Classic account with a text memo

```json theme={null}
{
  "address": "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ",
  "memo": { "type": "text", "value": "customer-420" }
}
```

Preserve case, spaces and exact UTF-8 bytes. The limit is 28 **bytes**, not 28 characters. An empty text memo is invalid; use `none` to remove a memo explicitly.

### Classic account with a hash memo

```json theme={null}
{
  "address": "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ",
  "memo": {
    "type": "hash",
    "value": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
  }
}
```

This is a 32-byte memo encoded as 64 lowercase hexadecimal characters in the SDK and JSON. Convert those hex bytes to the transaction's hash-memo representation; do not send the 64-character string as a text memo or hash it again.

### Contract address

```json theme={null}
{
  "address": "CADQOBYHA4DQOBYHA4DQOBYHA4DQOBYHA4DQOBYHA4DQOBYHA4DQP5KR",
  "memo": { "type": "none" }
}
```

The Resolver can store a contract recipient. Receiving assets requires a supported Soroban transfer flow. Soran's result does not specify an asset, amount, contract method or additional routing arguments, and a valid address alone does not prove that a particular receiving flow is supported.

## Muxed accounts: what is and is not supported

A muxed `M...` address packages a base G account with a 64-bit identifier. For example:

```text theme={null}
M address: MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAABUTGI4
G account: GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ
Muxed ID:  420
```

Stellar supports muxed destinations on selected operations, including classic payments. The muxed ID belongs to the operation's destination; a classic memo belongs to the transaction. They are different representations, even when their numbers match. See [Stellar's muxed-account guide](https://developers.stellar.org/docs/build/guides/transactions/pooled-accounts-muxed-accounts-memos).

Soran accepts the full M address and keeps its ID distinct from a transaction memo. For example, `customer420.nova` can resolve to:

```json theme={null}
{
  "address": "MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAABUTGI4",
  "memo": { "type": "none" }
}
```

Here `none` means no separate transaction memo. The embedded muxed ID **420 is still required** and remains part of the M address. Send to that complete address using a compatible payment flow. Do not substitute the base G address or Memo ID 420.

M addresses with a separate ID, text or hash memo are rejected by this Soran interface. Invalid M encodings and out-of-range IDs are rejected. Muxed IDs range from `0` to `18446744073709551615`; preserve them as exact decimal strings or bigint values when inspecting them.

You can inspect an M address with Stellar SDK 17 without submitting a transaction:

```ts theme={null}
import { MuxedAccount } from "@stellar/stellar-sdk";

const muxed = MuxedAccount.fromAddress(
  "MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAABUTGI4",
  "0",
);
const baseAddress = muxed.baseAccount().accountId();
const muxedId = muxed.id(); // "420", kept as a decimal string
// Keep the full M address for payment; the base address is for account inspection.
```

Reverse and Primary names identify a G/C account, not a muxed customer or a memo customer. They do not strip a muxed ID to establish a base-account proof. Current account-input methods accept G or C addresses, not M addresses. Changing a payment destination to M can invalidate an earlier reverse/Primary forward proof; direct M payment support does not create a customer-specific account identity.

## Publish and read the whole instruction

With a configured [Holder SDK](/holder/managing-your-name), the name's holder can publish the recipient-approved destination:

```ts theme={null}
await me.setPayment("customer420.nova", {
  address: "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ",
  memo: { type: "id", value: "420" },
});
```

For a muxed destination, use the same Holder method with the full M address:

```ts theme={null}
await me.setPayment("customer420.nova", {
  address: "MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAABUTGI4",
  memo: { type: "none" },
});
```

The Holder SDK validates the M address and submits the base G account and exact ID to on-chain `set_muxed`. Address and routing information are stored atomically in the namespace's Resolver. Universal Lookup obtains the current instruction from that Resolver; no Soran database is the source of the memo or muxed ID.

Wallets call on-chain `resolve_destination`, SDK `resolvePayment`, or HTTP `/v1/payment/{namespace}/{label}`. The older on-chain `resolve_payment` and address-only contract methods, plus HTTP `/v1/resolve`, reject muxed records rather than return an incomplete G address. The updated SDK's `resolve`/`record`/`verify` conveniences can preserve the full M address, but `resolvePayment` remains the general payment API. Display and preserve the whole pair. A required separate memo makes address-only lookup fail. Read failures and unknown legacy memo capability must never become memo-free results.

A classic transaction has one memo, so payments requiring different memos need separate transactions. Recheck the full instruction before confirmation, honor recipient memo requirements, and use the correct payment flow for the address type. See [payment integration](/sdk/resolving-names) and the [contract ABI](/api/onchain-resolution).
