# Wallets

This page is for wallet developers integrating Branta into a send flow. Embedding Branta lets your users see counterparty name and logo before broadcast — turning an opaque address or invoice into a recognizable payee.

### Why integrate Branta

* Users see *who* they are paying before broadcast (counterparty name and logo), not just an opaque address or invoice.
* Eliminates phishing, supply-chain, address-swap, and man-in-the-middle attacks at point of transaction.
* Works across Bitcoin onchain, Lightning (bolt11, bolt12, lnurl, ln address), and Ark.
* Privacy-preserving — `strict` mode never sends plain-text onchain addresses to Branta.
* Free, no permission needed, and one network call per paste or scan.

### How Branta works for wallets

Your wallet hands user-pasted text or raw QR text to the Branta SDK. The SDK calls Branta in `strict` privacy mode: onchain destinations only resolve when the QR carries `branta_id` and `branta_secret` (ZK-encoded), while Lightning destinations (bolt11, bolt12, lnurl, ln address) resolve as plain text. On a hit, render the returned counterparty info (name, logo, `verifyUrl`) before the user confirms send. On a miss or error, show nothing — a missing record just means the destination was never posted to Branta.

See [SDK](/tech-and-setup/sdk.md), [Environments](/tech-and-setup/environments.md), and [Authentication](/tech-and-setup/authentication.md) for deeper reference.

### Integrate

{% tabs %}
{% tab title="JavaScript" %}
SDK: [branta-js](https://github.com/BrantaOps/branta-js)

Wallets should use `strict` privacy mode. Two flows are supported:

* **Copy/paste**: call `getPayments` with the pasted text. Plain-text on-chain addresses will not return results in strict mode — they must be ZK-encoded. Lightning destinations (bolt11, bolt12, ln\_url, ln\_address) work as plain text.
* **QR scan**: call `getPaymentsByQrCode` with the raw QR text. This handles both on-chain (when the QR includes `branta_id` / `branta_secret`) and lightning destinations.

Always catch errors and show nothing on not-found — a missing record just means the address was not posted to Branta.

```ts
import { BrantaServerBaseUrl } from "@branta-ops/branta";
import { BrantaService } from "@branta-ops/branta/v2";

const service = new BrantaService({
  baseUrl: BrantaServerBaseUrl.Production,
  privacy: 'strict',
});

async function lookup(input: string, isQrCode: boolean) {
  try {
    const result = isQrCode
      ? await service.getPaymentsByQrCode(input)
      : await service.getPayments(input);

    if (result.payments.length === 0) {
      // Not found — show nothing. The address may simply not exist in Branta.
      return;
    }

    // Render result.payments and result.verifyUrl
  } catch {
    // Swallow errors — never surface a "not found" or lookup failure to the user.
  }
}
```

{% endtab %}

{% tab title=".NET" %}
SDK: [branta-dotnet](https://github.com/BrantaOps/branta-dotnet)

Wallets should use `Strict` privacy mode. Two flows are supported:

* **Copy/paste**: call `GetPaymentsAsync` with the pasted text. Plain-text on-chain addresses will not return results in strict mode — they must be ZK-encoded. Lightning destinations (bolt11, bolt12, ln\_url, ln\_address) work as plain text.
* **QR scan**: call `GetPaymentsByQrCodeAsync` with the raw QR text. This handles both on-chain (when the QR includes `branta_id` / `branta_secret`) and lightning destinations.

Always catch errors and show nothing on not-found — a missing record just means the address was not posted to Branta.

```cs
using Branta.V2.Extensions;
using Branta.V2.Interfaces;

services.ConfigureBrantaServices(new BrantaClientOptions() {
    BaseUrl = BrantaServerBaseUrl.Production,
    Privacy = PrivacyMode.Strict
});
```

```cs
public class Example(IBrantaService brantaService)
{
    public async Task LookupAsync(string input, bool isQrCode)
    {
        try
        {
            var result = isQrCode
                ? await brantaService.GetPaymentsByQrCodeAsync(input)
                : await brantaService.GetPaymentsAsync(input);

            if (result.Payments.Count == 0)
            {
                // Not found — show nothing. The address may simply not exist in Branta.
                return;
            }

            // Render result.Payments and result.VerifyUrl
        }
        catch
        {
            // Swallow errors — never surface a "not found" or lookup failure to the user.
        }
    }
}
```

{% endtab %}
{% endtabs %}

### Test your integration

Scan the [example QR codes](/wallets/example-qr-codes.md) with your wallet to confirm each scenario renders the right thing before broadcast:

* **On-chain** and **Lightning** — counterparty name and logo render.
* **ZK On-chain** and **ZK Lightning** — encrypted destinations resolve via `branta_id` / `branta_secret`.
* **Not found** — your wallet shows nothing (a miss is not an error).

Each variant is published for both [Production](/wallets/example-qr-codes/production.md) and [Staging](/wallets/example-qr-codes/staging.md) — match the environment your SDK is pointed at.

### Wallets using Branta

See the live list at [branta.pro/network](https://branta.pro/network?tab=wallet).

To be listed, open a PR on [branta-network](https://github.com/brantaOps/branta-network).


---

# Agent Instructions: 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:

```
GET https://developer.branta.pro/wallets.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
