<!-- tempo-docs-context -->
> Source: [/docs/accounts/apps](https://tempo.xyz/developers/docs/accounts/apps.md)
> Section: [Accounts](https://tempo.xyz/developers/docs/accounts.md). Create accounts, set up signing methods, policies, access keys, key rotation, and fees, and follow guides for users, automations, agents, and teams.
> [Documentation index](https://tempo.xyz/developers/llms.txt) · [Docs skill](https://tempo.xyz/developers/SKILL.md)

> Tempo MCP: Use `search`, `find_pages`, `read_page`, and `code` at `https://mcp.tempo.xyz` for Tempo and related documentation.
> If an indexed page is missing or reflects an older site, read this site’s [documentation index](https://tempo.xyz/developers/llms.txt) and Markdown pages directly.

# Apps

Gives each user an account they control, with your wallet provider signing alongside them.

## Overview

A consumer app holds each user's Tempo account through a wallet provider, such as Privy, Turnkey, or Dynamic. Examples include wallets, remittance apps, and savings apps.

Each user keeps the same address when they recover the account or leave your app. Users who connect a [wallet they already have](https://tempo.xyz/developers/docs/accounts/wallets) hold their own key instead.

:::warning
**Multiple signers arrive with the [T14 network upgrade](https://tempo.xyz/developers/docs/protocol/upgrades/t14).** Until T14 activates, an account with several signers and a threshold runs only on the [Tempo Accounts devnet](https://tempo.xyz/developers/docs/accounts/create#connect-to-the-devnet), not on mainnet or testnet, and may still change.
:::

<span id="plan-recovery-that-doesnt-depend-on-the-provider" />

<span id="give-each-user-a-self-custodial-wallet" />

## Recommended App Setup

Provider wallets with one key each work on mainnet and testnet today ([what your provider sets up today](https://tempo.xyz/developers/docs/accounts/apps#what-your-provider-sets-up-today)).

Give each account three signers at weight 1, with any two approving ([signing thresholds](https://tempo.xyz/developers/docs/accounts/policies/signing-thresholds)):

* **User Passkey:** The user's [passkey](https://tempo.xyz/developers/docs/accounts/authentication/passkeys) on their phone.
* **Provider Key:** A key your provider manages. It signs only for a user your app has signed in.
* **Backup Key:** A key the user keeps, such as a second passkey on another device or a hardware key.

Day to day, the passkey and the provider sign each payment together. No payment goes through without the user. If the user loses their phone, the provider and the backup replace the passkey.

The passkey and backup work without your app or the provider, even when either is down or breached. Together they pay, recover the account, or remove the provider's key.

<span id="custody-test" />

<span id="your-app-holds-the-key-through-a-provider" />

<span id="what-your-provider-sets-up-today" />

## Existing Provider Wallets

Each user gets one secp256k1 key. The provider holds it and unlocks it when the user logs in. That key makes the user's wallet a [single-key account](https://tempo.xyz/developers/docs/accounts/how-it-works#address), which works unchanged on Tempo mainnet and testnet.

The key controls the whole balance. Anyone the provider lets request a signature moves it. That includes the user after they log in, and your backend under the provider's policies. Because the key is secp256k1, the account's own key can't be a passkey or device key.

<span id="keep-your-existing-provider-wallets" />

## Migration From Provider Wallets

If your users already have wallets with Privy or another provider, you don't create new accounts. Each wallet's secp256k1 key gives it the same address on Tempo as on other EVM chains. Balances on other chains don't carry over. Sending and receiving stablecoins works unchanged.

Fee tokens, batched calls, and access keys need the provider's Tempo integration, which sends [Tempo Transactions](https://tempo.xyz/developers/docs/guide/tempo-transaction). Privy's Tempo-specific React hook supports `sponsor: true`. Its [Tempo transaction guide](https://docs.privy.io/wallets/using-wallets/tempo/send-a-transaction) lists the SDK and project requirements. To operate your own sponsorship service, use a [fee payer](https://tempo.xyz/developers/docs/accounts/fees/fee-sponsorship).

<span id="which-tempo-features-does-my-setup-support" />

<span id="what-tempo-adds" />

<span id="what-your-provider-supports-on-tempo" />

<span id="what-the-providers-policy-engine-can-enforce" />

<span id="who-can-move-the-funds" />

<span id="what-we-recommend" />

<span id="route-raw-signing-through-one-backend" />

## Provider Support on Tempo

Any provider that signs Ethereum transactions can hold and send stablecoins on Tempo ([EVM compatibility](https://tempo.xyz/developers/docs/quickstart/evm-compatibility)). Tempo Transaction features need more. They include paying fees in any stablecoin, batching payments, sponsoring fees, and authorizing [access keys](https://tempo.xyz/developers/docs/accounts/access-keys).

For those, the provider sends Tempo Transactions itself. Or it signs a transaction's raw hash, and your app sends the transaction to a Tempo RPC. Privy, Turnkey, and Dynamic do both.

| Provider | Sends Tempo Transactions | Signs raw hashes |
| --- | --- | --- |
| [Privy](https://docs.privy.io/wallets/using-wallets/tempo/send-a-transaction) | Yes, with calls, fee token, nonces, and sponsorship | `secp256k1_sign`, or `raw_sign` on server wallets |
| [Turnkey](https://docs.turnkey.com/features/networks/overview) | Yes, through `sign_transaction`, which its policies can inspect | `sign_raw_payload` with no hash function |
| [Dynamic](https://www.dynamic.xyz/docs) | Yes, through its Tempo SDK extension | `signRawMessage` |

The provider's policy engine can't read a raw hash. It can't tell a payment or a key authorization from any other request. Route raw signing through one backend service that builds and checks each transaction. It checks any access key's limits, scopes, and expiry before it calls the provider.

To keep key authorization inside the policy engine instead, use the provider's transaction API. Send a Tempo Transaction that calls `authorizeKey` on the [Account Keychain](https://tempo.xyz/developers/docs/protocol/transactions/AccountKeychain).

<span id="how-do-i-give-a-service-limited-spending-power" />

<span id="wrap-the-providers-signing-as-an-account" />

<span id="authorize-from-the-browser" />

<span id="let-your-backend-or-an-agent-spend-from-a-users-wallet" />

<span id="give-your-backend-or-an-agent-an-access-key" />

<span id="guides-for-consumer-apps" />

## Related

[Set Up a Self-Custodial Wallet With a Provider](https://tempo.xyz/developers/docs/accounts/apps/self-custodial-wallets): Use for giving each user a passkey, a provider key, and a backup key.

[Recover a User's Account](https://tempo.xyz/developers/docs/accounts/apps/recover-an-account): Use for replacing a lost passkey or backup at the same address.

[Pay From a User's Embedded Wallet](https://tempo.xyz/developers/docs/accounts/automations/pay-from-an-embedded-wallet): Use for letting your backend or an agent pay within limits the wallet signs once.

[Signing Thresholds](https://tempo.xyz/developers/docs/accounts/policies/signing-thresholds): Covers signer weights and how many approvals an account needs.
