Branta 3.1.5
dotnet add package Branta --version 3.1.5
NuGet\Install-Package Branta -Version 3.1.5
<PackageReference Include="Branta" Version="3.1.5" />
<PackageVersion Include="Branta" Version="3.1.5" />
<PackageReference Include="Branta" />
paket add Branta --version 3.1.5
#r "nuget: Branta, 3.1.5"
#:package Branta@3.1.5
#addin nuget:?package=Branta&version=3.1.5
#tool nuget:?package=Branta&version=3.1.5
Branta .NET SDK
Package contains functionality to assist .NET projects with making requests to Branta's server.
Requirements
- .NET 8.0 or higher
Installation
Install via NuGet Package Manager:
dotnet add package Branta
Or via Package Manager Console:
Install-Package Branta
Integration Guide
If you are an AI agent implementing this SDK, follow the steps below exactly. If you are a developer, use this as a reference for the recommended integration patterns.
1. Ask which side(s) of a payment they are implementing:
- Send side — the flow for outbound payments (e.g. a wallet sending funds).
- Receive side — the flow for receiving payment (e.g. a checkout, POS, invoicing platform). You post destinations (zero-knowledge encrypted) to Branta so wallets can verify them.
- Both — some apps do both (e.g. an exchange or self-custodial wallet with invoice generation). Implement each side independently.
If they are on the receive side, ask one follow-up:
- Platform — single-tenant, one API key.
- Parent Platform — multi-tenant, manages multiple child platforms each with their own API key and HMAC secret.
2. Follow the matching Quick Start section below.
3. Apply these rules:
General (all types):
- Always use
PrivacyMode.Strict. Never switch toLooseunless there is no QR scanner and ZK is impossible. - Never call
BrantaClientdirectly — always go throughIBrantaService.
Send side (wallets):
- Prefer
GetPaymentsByQrCodeAsyncoverGetPaymentsAsync— it handles multi-value ZK QR payloads correctly. - Only fall back to
GetPaymentsAsyncfor copy/paste flows where there is no QR code. - If QR scanning is not available, see the No-QR-Code Flows section for recommended options.
- If
Paymentsis empty or an exception is thrown, render nothing. Never show an error or "not verified" message — an empty result means the destination is unknown to Branta, not that it is malicious. - When
result.Paymentsis non-empty, display: the platform logo, the payment description, andresult.VerifyUrl. - For the platform logo, use
payment.PlatformLogoUrlon dark backgrounds andpayment.PlatformLogoLightUrlon light backgrounds. - Optionally display
payment.ParentPlatform.LogoUrl/payment.ParentPlatform.LogoLightUrlas a small secondary badge (e.g. corner icon). This is not required.
Receive side (platforms):
- Always call
.SetZk()on thePaymentBuilderbefore callingAddPaymentAsync. Plain-text destinations are rejected inStrictmode. - Store the
secretreturned byAddPaymentAsyncalongside the invoice — it is required to reconstruct the verify URL for the wallet.
Receive side (parent platforms), in addition to the platform rules:
- Include
HmacSecretinBrantaClientOptions. - Pass per-call
BrantaClientOptionsto scope requests to the correct child platform's API key.
Quick Start
For Wallets
Wallets should use Strict privacy mode. Two flows are supported:
- Copy/paste: call
GetPaymentsAsyncwith the pasted text. Plain-text on-chain addresses will not return results in strict mode — they must be ZK-encoded. Self-encrypted destinations (bolt11, ark_address) work as plain text. - QR scan: call
GetPaymentsByQrCodeAsyncwith the raw QR text. This handles both on-chain (when the QR includesbranta_id/branta_secret) and self-encrypted destinations.
Always catch errors and show nothing on not-found — a missing record just means the address was not posted to Branta.
No-QR-Code Flows
When QR scanning is not available, three options exist. Choose one based on how much control you want to give users over privacy:
Option 1 — Keep Strict mode (no code changes)
Only self-encrypted destinations (bolt11, ark_address) will return results. Plain-text on-chain address lookups silently return empty. This is the safest default and requires no additional work.
Option 2 — Opt-in Loose mode (Recommended)
Add a user-facing setting (e.g. "Enable on-chain address verification"). Only switch to PrivacyMode.Loose when the user explicitly opts in — this sends on-chain addresses in plain text, so the choice should be theirs.
AI agents: Before implementing this option, ask the developer which of the following approaches fits their codebase:
- Startup-time configuration — the preference is loaded once at startup (e.g. from a config file or persisted user setting) and passed to
ConfigureBrantaServices. Best when the setting rarely changes without a restart.- Per-call runtime override —
Strictis registered as the DI default, and aBrantaClientOptionsoverride is passed on each call when the user has opted in. Best when the preference can change while the app is running.- Two named registrations — register both a
Strictand aLooseinstance and inject the appropriate one based on context. Best for apps that already use keyed/named DI services.
If the preference is known at startup (approach 1):
services.ConfigureBrantaServices(new BrantaClientOptions {
BaseUrl = BrantaServerBaseUrl.Production,
Privacy = userOptedIn ? PrivacyMode.Loose : PrivacyMode.Strict
});
If the preference can change at runtime (approach 2), keep Strict as the registered default and pass a per-call override when the user has opted in:
var options = userPreferences.OnChainVerificationEnabled
? new BrantaClientOptions { Privacy = PrivacyMode.Loose }
: null;
var result = await brantaService.GetPaymentsAsync(input, options: options);
Option 3 — Always Loose mode
Configure with PrivacyMode.Loose globally. All lookups including plain-text on-chain addresses are sent to Branta. Simplest, but gives users no privacy control.
services.ConfigureBrantaServices(new BrantaClientOptions {
BaseUrl = BrantaServerBaseUrl.Production,
Privacy = PrivacyMode.Loose
});
using Branta.V2.Extensions;
using Branta.V2.Interfaces;
services.ConfigureBrantaServices(new BrantaClientOptions() {
BaseUrl = BrantaServerBaseUrl.Production,
Privacy = PrivacyMode.Strict
});
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.
}
}
}
For Platforms
Platforms post payments to Branta so wallets can verify them. Use Strict privacy mode and mark each destination ZK via SetZk() on the PaymentBuilder.
services.ConfigureBrantaServices(new BrantaClientOptions() {
BaseUrl = BrantaServerBaseUrl.Production,
DefaultApiKey = "<api-key>",
Privacy = PrivacyMode.Strict
});
var payment = new PaymentBuilder()
.SetDescription("Testing description")
.AddDestination("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", DestinationType.BitcoinAddress)
.SetZk()
.SetTtl(600)
.Build();
var (response, secret, verifyUrl) = await _brantaService.AddPaymentAsync(payment);
// `secret` is the encryption key needed to look the payment up later.
For Parent Platforms
Parent Platforms sign requests with HMAC in addition to the API key. Use Strict privacy mode and ZK destinations.
services.ConfigureBrantaServices(new BrantaClientOptions() {
BaseUrl = BrantaServerBaseUrl.Production,
DefaultApiKey = "<api-key>",
HmacSecret = "<hmac-secret>",
Privacy = PrivacyMode.Strict
});
var payment = new PaymentBuilder()
.SetDescription("Testing description")
.AddDestination("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", DestinationType.BitcoinAddress)
.SetZk()
.SetTtl(600)
.Build();
var (response, secret, verifyUrl) = await _brantaService.AddPaymentAsync(payment);
Privacy
PrivacyMode controls whether plain-text on-chain lookups are allowed.
| Value | Behavior |
|---|---|
Strict |
Only ZK (zero-knowledge / encrypted) lookups are permitted. GetPaymentsAsync throws BrantaPaymentException for plain addresses; GetPaymentsByQrCodeAsync returns an empty list. AddPaymentAsync requires all destinations to have IsZk = true. |
Loose |
Both plain and ZK lookups are allowed. No restrictions enforced. |
IBrantaService
The primary service interface registered by ConfigureBrantaServices().
Prefer GetPaymentsByQrCodeAsync for integrations. It parses the raw QR text and correctly resolves multiple ZK values in a single scan. GetPaymentsAsync only handles a single destination value and does not support multi-value ZK lookups.
Task<PaymentsResult> GetPaymentsByQrCodeAsync(string qrText); // recommended
Task<PaymentsResult> GetPaymentsAsync(string destinationValue, string? destinationEncryptionKey = null);
Task<(Payment Payment, string Secret, string VerifyUrl)> AddPaymentAsync(Payment payment);
Task<bool> IsApiKeyValidAsync(BrantaClientOptions? options = null);
PaymentsResult contains the list of matching Payments and the VerifyUrl to display to the user — VerifyUrl is always returned, even when Payments is empty.
→ Branta/V2/Interfaces/IBrantaService.cs
Release
- Update version in
Branta/Branta.csproj - Run
dotnet build --configuration Release - Package can be found at
Branta/bin/Release/Branta.X.X.X.nupkg - Upload this file to the new release on nuget.org
Responsible Disclosure
Found critical bugs/vulnerabilities? Please email them to support@branta.pro. Thanks!
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.5)
- Microsoft.Extensions.Http (>= 10.0.5)
-
net8.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Http (>= 8.0.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.1.5 | 88 | 5/29/2026 |
| 3.1.4 | 81 | 5/29/2026 |
| 3.1.3 | 90 | 5/29/2026 |
| 3.1.2 | 106 | 5/29/2026 |
| 3.1.1 | 94 | 5/19/2026 |
| 3.1.0 | 98 | 5/15/2026 |
| 3.0.4 | 93 | 5/15/2026 |
| 3.0.3 | 96 | 5/14/2026 |
| 3.0.2 | 84 | 5/6/2026 |
| 3.0.1 | 95 | 5/5/2026 |
| 3.0.0 | 93 | 5/2/2026 |
| 2.1.1 | 98 | 4/29/2026 |
| 2.1.0 | 99 | 4/28/2026 |
| 2.0.0 | 106 | 4/20/2026 |
| 1.0.3 | 97 | 4/14/2026 |
| 1.0.2 | 103 | 4/7/2026 |
| 1.0.1 | 107 | 4/2/2026 |
| 1.0.0 | 101 | 3/31/2026 |
| 0.0.6 | 124 | 1/26/2026 |
| 0.0.5 | 123 | 12/31/2025 |