# Payout from Your Own Address

Let a user turn crypto into money on a bank account from a wallet Aurea has never held a key for — MetaMask, Phantom, a hardware wallet.

## Overview

The path is the one in [Wallet Pay-Out](https://docs.aureahub.com/docs/guide-wallet-payout.md), with one difference that changes what you must build: **Aurea has no key**. It cannot sign, cannot prompt, cannot retry on the user's behalf. What it can do is prove once that the user controls the address, and then hand back a deposit request precise enough that the user's own wallet can honour it without anyone retyping a number.

So there are two phases. **Once**: the user signs a message and the address becomes theirs, in that environment, until they revoke it. **Each payout**: quote, bind, and then a deposit that must come from that address before a deadline.

## Before You Start

- Your tenant banks with the bank ramp, has **payouts** switched on in that environment, and has the **standalone** mode — [Tenant Settings](https://docs.aureahub.com/docs/bank-settings.md). Without the mode, asking for a proof and paying from a proven address both answer `403` `NOAH_MODE_OFF` with `details.mode` `standalone`.
- The user's KYC is approved in that environment.
- A proof belongs to **one environment**: an address proven in the sandbox is not proven in production.

## Step 1: Prove the Address

[Ask for a Challenge](https://docs.aureahub.com/docs/bank-address-challenge.md) gives a message; the user signs it with the address's own key; [Verify an Address](https://docs.aureahub.com/docs/bank-address-verify.md) checks the signature and keeps the address. [List Addresses](https://docs.aureahub.com/docs/bank-addresses-list.md) shows what a user has proven, and [Revoke an Address](https://docs.aureahub.com/docs/bank-address-revoke.md) takes one back.

This is the same proof the [standalone pay-in](https://docs.aureahub.com/docs/guide-standalone-payin.md) uses: an address proven once serves both directions.

## Step 2: Quote and Pay

The quote is the same as in [Wallet Pay-Out](https://docs.aureahub.com/docs/guide-wallet-payout.md): countries, channel, the channel's form, then [Create a Quote](https://docs.aureahub.com/docs/payout-quote.md) and its form steps until it is `ready`.

What changes is one field of [Pay Out a Quote from Your Wallet](https://docs.aureahub.com/docs/payout-wallet-pay.md): instead of `source.walletId` you send `source.address` — the proven address. Exactly one of the two; both, or neither, answers `400`. An EVM address is matched in any letter case.

An address that was never proven, or was revoked, answers `400` `NOAH_SOURCE_NOT_ALLOWED`. The proof is checked in the environment of the call.

## Step 3: The Deposit Request

The answer carries everything the user's wallet needs, and this is where standalone earns its keep:

- `deposit.address` and `deposit.amountUnits` — where, and **exactly** how much, in the token's smallest unit.
- `deposit.expiresAt` — **the deposit's own deadline**: 30 minutes after the quote's, which is when the rule stops holding the address. A deposit that arrives later is matched by nothing. Show it as a deadline, not as a detail.
- `deposit.uri` — the transfer written in the standard the chain family has, so the user opens it in their wallet instead of copying three values by hand: **EIP-681** on EVM (`ethereum:<token>@<chainId>/transfer?address=<deposit>&uint256=<amountUnits>`) and **Solana Pay** on Solana (`solana:<deposit>?spl-token=<mint>&amount=<amount>`). A QR code of that string is the shortest path from your screen to their wallet.
- `deposit.tokenAddress`, `decimals` and `chainId` when you build the transfer yourself.

The request carries **no reference and no memo**: The bank ramp attributes the deposit by the address it came from. A deposit sent from another address of the same user is not this payout's deposit.

`deposit.uri` is `null` when the request cannot be written exactly — no deposit address yet, or the registry no longer holds the token's details. The rest of the answer still says where and how much, so fall back to showing those rather than blocking the user.

## Step 4: While It Waits

While a payout waits for its deposit, that address is **held**: no other payout may use it for the same currency on the same network, anywhere in Aurea, and the API says so with `409` `NOAH_PAYOUT_SOURCE_BUSY`.

The address also cannot be **revoked** while it is holding a payout: [Revoke an Address](https://docs.aureahub.com/docs/bank-address-revoke.md) answers `409` `NOAH_ADDRESS_IN_USE`. That is deliberate — revoking would leave a deposit on its way to a payout the user no longer owns. Wait for the payout to finish, or let its deadline pass, and then revoke.

## Step 5: Follow It

As in the Aurea-wallets mode: [Get a Wallet Payout](https://docs.aureahub.com/docs/payout-wallet-get.md), and your own record posted to your server by [Bank Ramp Events](https://docs.aureahub.com/docs/guide-events.md). `expired` means no deposit came in time — the user's crypto never left their wallet, and nothing is owed.

## When It Does Not Work

| Answer | What happened | What to do |
| --- | --- | --- |
| `403` `NOAH_MODE_OFF`, `mode` `standalone` | Your tenant does not have the standalone mode in that environment | Ask the Aurea operator to switch it on |
| `400` `NOAH_SOURCE_NOT_ALLOWED` | That address is not proven in this environment, or was revoked | Prove it again (step 1). A proof is per environment |
| `404` `NOAH_RESOURCE_NOT_FOUND` on the channel reads | the bank ramp has nobody by that id yet: it creates the customer when the user *begins* the hosted onboarding, not when the session is made | Have the user start onboarding. [Sync KYC Status](https://docs.aureahub.com/docs/payin-sync-status.md) answering `synced: false` is the same fact seen from the other side |
| `409` `NOAH_PAYOUT_SOURCE_BUSY` | The address already has a payout waiting for that currency on that network | Wait, or use another proven address. Another network or currency does not collide |
| `409` `NOAH_ADDRESS_IN_USE` on revoke | A payout is waiting for a deposit from that address | Let the payout finish or expire, then revoke |
| The deposit was sent late | It arrived after `deposit.expiresAt`, so no rule matched it | Nothing can attach it to that payout afterwards. This is why the deadline is shown, not hidden |
| The deposit came from another address | the bank ramp attributes by address, and it was not the source named | The payout keeps waiting. Ask the user to send from the proven address |

---

Web version: https://docs.aureahub.com/#guide-standalone-payout
