Skip to main content

Overview

The Devdraft C# SDK provides a complete client library for integrating payment processing, customer management, and webhook functionality into your .NET applications.

Async/Await

Full async/await support for modern .NET applications

Dependency Injection

Built-in support for Microsoft.Extensions.DependencyInjection

Type-Safe

Strong typing with generics and nullable reference types

Resilience

Polly integration for retry policies and circuit breakers

Installation

Using NuGet Package Manager

dotnet add package Devdraft
Or via Package Manager Console:
Install-Package Devdraft
Or add to your .csproj file:
<ItemGroup>
  <PackageReference Include="Devdraft" Version="1.0.0" />
</ItemGroup>

Requirements

  • .NET Standard 2.0 or higher
  • .NET Core 3.1+ / .NET 5+ / .NET 6+ recommended

Quick Start

using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Devdraft.Api;
using Devdraft.Client;
using Devdraft.Model;

namespace YourApp
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var host = CreateHostBuilder(args).Build();
            
            // Get API instance from DI container
            var transfersApi = host.Services.GetRequiredService<ITransfersApi>();
            
            // Create a transfer
            var transferDto = new CreateDirectWalletTransferDto(
                walletId: "your-wallet-id",
                network: "solana",
                stableCoinCurrency: "usdc",
                amount: 100.00m
            );
            
            var response = await transfersApi.TransferControllerCreateDirectWalletTransferAsync(transferDto);
            var transfer = response.Ok();
            
            Console.WriteLine($"Transfer created: {transfer.Id}");
        }
        
        static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureApi((context, services, options) =>
                {
                    // Configure API keys
                    var clientKey = new ApiKeyToken("x-client-key", 
                        Environment.GetEnvironmentVariable("DEVDRAFT_CLIENT_KEY"));
                    var clientSecret = new ApiKeyToken("x-client-secret", 
                        Environment.GetEnvironmentVariable("DEVDRAFT_CLIENT_SECRET"));
                    
                    options.AddTokens(clientKey, clientSecret);
                    
                    // Configure HTTP client with resilience policies
                    options.AddApiHttpClients(builder =>
                    {
                        builder
                            .AddRetryPolicy(3)
                            .AddTimeoutPolicy(TimeSpan.FromSeconds(30))
                            .AddCircuitBreakerPolicy(10, TimeSpan.FromSeconds(30));
                    });
                });
    }
}

API Interfaces

The SDK is organized into API interfaces, each handling a specific domain:
API InterfaceDescription
IAPIHealthApiService health checks and status monitoring
IAppBalancesApiQuery application balances across stablecoins
ICustomersApiCustomer management and KYC operations
IExchangeRatesApiReal-time currency exchange rates
IInvoicesApiInvoice creation and management
ILiquidationAddressesApiCryptocurrency liquidation addresses
IPaymentIntentsApiPayment intent creation for bank and stablecoin
IPaymentLinksApiGenerate and manage payment links
IProductsApiProduct catalog management
ITaxesApiTax configuration and management
ITestPaymentsApiTest payment processing in sandbox
ITransfersApiInitiate and manage fund transfers
IWalletsApiWallet management and balances
IWebhooksApiWebhook configuration and management

API Health

Monitor service health and availability.

Methods

HealthControllerCheckV0Async()

Authenticated health check endpoint requiring API credentials.
using Devdraft.Api;
using Microsoft.Extensions.DependencyInjection;

// Inject the API
var healthApi = host.Services.GetRequiredService<IAPIHealthApi>();

try
{
    var response = await healthApi.HealthControllerCheckV0Async();
    Console.WriteLine("Service is healthy and authenticated");
}
catch (ApiException ex)
{
    Console.WriteLine($"Health check failed: {ex.Message}");
}
Returns: Task<IHealthControllerCheckV0ApiResponse>

HealthControllerPublicHealthCheckV0Async()

Public health check endpoint (no authentication required).
var response = await healthApi.HealthControllerPublicHealthCheckV0Async();
var status = response.Ok();
Console.WriteLine($"Service status: {status.Status}");
Returns: Task<IHealthControllerPublicHealthCheckV0ApiResponse>

App Balances

Query your application’s stablecoin balances.

Methods

BalanceControllerGetAllBalancesAsync()

Get all stablecoin balances for your application.
using Devdraft.Api;
using Microsoft.Extensions.DependencyInjection;

var balancesApi = host.Services.GetRequiredService<IAppBalancesApi>();

try
{
    var response = await balancesApi.BalanceControllerGetAllBalancesAsync();
    var balances = response.Ok();
    
    Console.WriteLine($"USDC Balance: {balances.Usdc}");
    Console.WriteLine($"EURC Balance: {balances.Eurc}");
}
catch (ApiException ex)
{
    Console.WriteLine($"Error: {ex.Message}");
}
Returns: Task<IBalanceControllerGetAllBalancesApiResponse>

BalanceControllerGetUSDCBalanceAsync()

Get USDC balance only.
var response = await balancesApi.BalanceControllerGetUSDCBalanceAsync();
var usdcBalance = response.Ok();
Console.WriteLine($"USDC: {usdcBalance.Amount}");
Returns: Task<IBalanceControllerGetUSDCBalanceApiResponse>

BalanceControllerGetEURCBalanceAsync()

Get EURC balance only.
var response = await balancesApi.BalanceControllerGetEURCBalanceAsync();
var eurcBalance = response.Ok();
Console.WriteLine($"EURC: {eurcBalance.Amount}");
Returns: Task<IBalanceControllerGetEURCBalanceApiResponse>

Customers

Manage customer records and KYC information.

Methods

CustomerControllerCreateAsync(createCustomerDto)

Create a new customer.
using Devdraft.Api;
using Devdraft.Model;
using Microsoft.Extensions.DependencyInjection;

var customersApi = host.Services.GetRequiredService<ICustomersApi>();

try
{
    var customerDto = new CreateCustomerDto(
        firstName: "John",
        lastName: "Doe",
        email: "john.doe@example.com",
        type: CustomerType.INDIVIDUAL,
        country: "US"
    );
    
    var response = await customersApi.CustomerControllerCreateAsync(customerDto);
    var customer = response.Ok();
    
    Console.WriteLine($"Customer created: {customer.Id}");
}
catch (ApiException ex)
{
    Console.WriteLine($"Error: {ex.Message}");
}
Parameters:
  • createCustomerDto: CreateCustomerDto - Customer details
Returns: Task<ICustomerControllerCreateApiResponse>

CustomerControllerFindAllAsync(page, limit, status)

Get all customers with optional filters.
var response = await customersApi.CustomerControllerFindAllAsync(
    page: 1,
    limit: 20,
    status: "ACTIVE"
);
var customers = response.Ok();

foreach (var customer in customers)
{
    Console.WriteLine($"{customer.FirstName} {customer.LastName} - {customer.Email}");
}
Parameters:
  • page: int? - Page number (optional, default: 1)
  • limit: int? - Items per page (optional, default: 20)
  • status: string? - Filter by status (optional)
Returns: Task<ICustomerControllerFindAllApiResponse>

CustomerControllerFindOneAsync(id)

Get a customer by ID.
var response = await customersApi.CustomerControllerFindOneAsync("customer-id-here");
var customer = response.Ok();
Console.WriteLine($"Customer: {customer.FirstName} {customer.LastName}");
Parameters:
  • id: string - Customer ID
Returns: Task<ICustomerControllerFindOneApiResponse>

CustomerControllerUpdateAsync(id, updateCustomerDto)

Update a customer’s information.
var updateDto = new UpdateCustomerDto
{
    Phone = "+1234567890",
    Address = "123 Main St"
};

var response = await customersApi.CustomerControllerUpdateAsync("customer-id-here", updateDto);
var updated = response.Ok();
Console.WriteLine($"Customer updated: {updated.Id}");
Parameters:
  • id: string - Customer ID
  • updateCustomerDto: UpdateCustomerDto - Fields to update
Returns: Task<ICustomerControllerUpdateApiResponse>

Exchange Rates

Get real-time currency exchange rates.

Methods

ExchangeRateControllerGetExchangeRateAsync(from, to)

Get exchange rate between any two supported currencies.
using Devdraft.Api;
using Microsoft.Extensions.DependencyInjection;

var ratesApi = host.Services.GetRequiredService<IExchangeRatesApi>();

try
{
    var response = await ratesApi.ExchangeRateControllerGetExchangeRateAsync(
        varFrom: "USD",
        to: "EUR"
    );
    var rate = response.Ok();
    
    Console.WriteLine($"1 USD = {rate.Rate} EUR");
    Console.WriteLine($"Rate expires at: {rate.ExpiresAt}");
}
catch (ApiException ex)
{
    Console.WriteLine($"Error: {ex.Message}");
}
Parameters:
  • varFrom: string? - Source currency code
  • to: string? - Target currency code
Returns: Task<IExchangeRateControllerGetExchangeRateApiResponse>

ExchangeRateControllerGetUSDToEURRateAsync()

Get USD to EUR exchange rate.
var response = await ratesApi.ExchangeRateControllerGetUSDToEURRateAsync();
var usdToEur = response.Ok();
Console.WriteLine($"USD to EUR: {usdToEur.Rate}");
Returns: Task<IExchangeRateControllerGetUSDToEURRateApiResponse>

ExchangeRateControllerGetEURToUSDRateAsync()

Get EUR to USD exchange rate.
var response = await ratesApi.ExchangeRateControllerGetEURToUSDRateAsync();
var eurToUsd = response.Ok();
Console.WriteLine($"EUR to USD: {eurToUsd.Rate}");
Returns: Task<IExchangeRateControllerGetEURToUSDRateApiResponse>

Invoices

Create and manage invoices for your customers.

Methods

InvoiceControllerCreateAsync(createInvoiceDto)

Create a new invoice.
using Devdraft.Api;
using Devdraft.Model;
using Microsoft.Extensions.DependencyInjection;

var invoicesApi = host.Services.GetRequiredService<IInvoicesApi>();

try
{
    var invoiceDto = new CreateInvoiceDto(
        customerId: "customer-id",
        items: new List<InvoiceProductDto>
        {
            new InvoiceProductDto(
                description: "Premium Subscription",
                quantity: 1,
                price: 99.99m,
                currency: "USD"
            )
        },
        dueDate: DateTime.Parse("2024-12-31")
    );
    
    var response = await invoicesApi.InvoiceControllerCreateAsync(invoiceDto);
    var invoice = response.Ok();
    
    Console.WriteLine($"Invoice created: {invoice.Id}");
    Console.WriteLine($"Total: {invoice.Total}");
}
catch (ApiException ex)
{
    Console.WriteLine($"Error: {ex.Message}");
}
Parameters:
  • createInvoiceDto: CreateInvoiceDto - Invoice details
Returns: Task<IInvoiceControllerCreateApiResponse>

InvoiceControllerFindAllAsync(page, limit, status)

Get all invoices.
var response = await invoicesApi.InvoiceControllerFindAllAsync(
    page: 1,
    limit: 50,
    status: "UNPAID"
);
var invoices = response.Ok();

foreach (var invoice in invoices)
{
    Console.WriteLine($"Invoice {invoice.Id}: {invoice.Total}");
}
Parameters:
  • page: int? - Page number (optional)
  • limit: int? - Items per page (optional)
  • status: string? - Filter by status (optional)
Returns: Task<IInvoiceControllerFindAllApiResponse>

InvoiceControllerFindOneAsync(id)

Get an invoice by ID.
var response = await invoicesApi.InvoiceControllerFindOneAsync("invoice-id");
var invoice = response.Ok();
Console.WriteLine($"Invoice total: {invoice.Total}");
Parameters:
  • id: string - Invoice ID
Returns: Task<IInvoiceControllerFindOneApiResponse>

InvoiceControllerUpdateAsync(id, updateInvoiceDto)

Update an invoice.
var updateDto = new UpdateInvoiceDto
{
    Status = "PAID",
    PaidAt = DateTime.UtcNow
};

var response = await invoicesApi.InvoiceControllerUpdateAsync("invoice-id", updateDto);
var updated = response.Ok();
Console.WriteLine($"Invoice updated: {updated.Id}");
Parameters:
  • id: string - Invoice ID
  • updateInvoiceDto: UpdateInvoiceDto - Fields to update
Returns: Task<IInvoiceControllerUpdateApiResponse>

Liquidation Addresses

Manage cryptocurrency liquidation addresses for customers.

Methods

LiquidationAddressControllerCreateLiquidationAddressAsync(customerId, createLiquidationAddressDto)

Create a new liquidation address for a customer.
using Devdraft.Api;
using Devdraft.Model;
using Microsoft.Extensions.DependencyInjection;

var liquidationApi = host.Services.GetRequiredService<ILiquidationAddressesApi>();

try
{
    var addressDto = new CreateLiquidationAddressDto(
        network: "solana",
        currency: "usdc"
    );
    
    var response = await liquidationApi.LiquidationAddressControllerCreateLiquidationAddressAsync(
        customerId: "customer-id",
        createLiquidationAddressDto: addressDto
    );
    var address = response.Ok();
    
    Console.WriteLine($"Liquidation address: {address.Address}");
    Console.WriteLine($"Network: {address.Network}");
}
catch (ApiException ex)
{
    Console.WriteLine($"Error: {ex.Message}");
}
Parameters:
  • customerId: string - Customer ID
  • createLiquidationAddressDto: CreateLiquidationAddressDto - Address details
Returns: Task<ILiquidationAddressControllerCreateLiquidationAddressApiResponse>

LiquidationAddressControllerGetLiquidationAddressesAsync(customerId)

Get all liquidation addresses for a customer.
var response = await liquidationApi.LiquidationAddressControllerGetLiquidationAddressesAsync("customer-id");
var addresses = response.Ok();

foreach (var addr in addresses)
{
    Console.WriteLine($"{addr.Network}: {addr.Address}");
}
Parameters:
  • customerId: string - Customer ID
Returns: Task<ILiquidationAddressControllerGetLiquidationAddressesApiResponse>

LiquidationAddressControllerGetLiquidationAddressAsync(customerId, liquidationAddressId)

Get a specific liquidation address.
var response = await liquidationApi.LiquidationAddressControllerGetLiquidationAddressAsync(
    customerId: "customer-id",
    liquidationAddressId: "address-id"
);
var address = response.Ok();
Console.WriteLine($"Address: {address.Address}");
Parameters:
  • customerId: string - Customer ID
  • liquidationAddressId: string - Address ID
Returns: Task<ILiquidationAddressControllerGetLiquidationAddressApiResponse>

Payment Intents

Create payment intents for bank and stablecoin payments.

Methods

PaymentIntentControllerCreateBankPaymentIntentAsync(createBankPaymentIntentDto)

Create a bank payment intent.
using Devdraft.Api;
using Devdraft.Model;
using Microsoft.Extensions.DependencyInjection;

var intentApi = host.Services.GetRequiredService<IPaymentIntentsApi>();

try
{
    var intentDto = new CreateBankPaymentIntentDto(
        customerId: "customer-id",
        amount: 1000.00m,
        currency: "USD",
        paymentRail: "wire"
    );
    
    var response = await intentApi.PaymentIntentControllerCreateBankPaymentIntentAsync(intentDto);
    var intent = response.Ok();
    
    Console.WriteLine($"Payment intent: {intent.Id}");
    Console.WriteLine($"Status: {intent.Status}");
}
catch (ApiException ex)
{
    Console.WriteLine($"Error: {ex.Message}");
}
Parameters:
  • createBankPaymentIntentDto: CreateBankPaymentIntentDto - Intent details
Returns: Task<IPaymentIntentControllerCreateBankPaymentIntentApiResponse>

PaymentIntentControllerCreateStablePaymentIntentAsync(createStablePaymentIntentDto)

Create a stablecoin payment intent.
var stableIntentDto = new CreateStablePaymentIntentDto(
    customerId: "customer-id",
    amount: 500.00m,
    currency: "usdc",
    network: "solana"
);

var response = await intentApi.PaymentIntentControllerCreateStablePaymentIntentAsync(stableIntentDto);
var stableIntent = response.Ok();
Console.WriteLine($"Stable intent: {stableIntent.Id}");
Parameters:
  • createStablePaymentIntentDto: CreateStablePaymentIntentDto - Intent details
Returns: Task<IPaymentIntentControllerCreateStablePaymentIntentApiResponse>
Generate and manage payment links for easy customer payments.

Methods

PaymentLinksControllerCreateAsync(createPaymentLinkDto)

Create a new payment link.
using Devdraft.Api;
using Devdraft.Model;
using Microsoft.Extensions.DependencyInjection;

var linksApi = host.Services.GetRequiredService<IPaymentLinksApi>();

try
{
    var linkDto = new CreatePaymentLinkDto(
        name: "Product Purchase",
        amount: 99.99m,
        currency: "USD",
        products: new List<PaymentLinkProductDto>
        {
            new PaymentLinkProductDto(
                name: "Premium Plan",
                quantity: 1,
                price: 99.99m
            )
        }
    );
    
    var response = await linksApi.PaymentLinksControllerCreateAsync(linkDto);
    var link = response.Ok();
    
    Console.WriteLine($"Payment link: {link.Url}");
    Console.WriteLine($"Share this link with customers: {link.ShortUrl}");
}
catch (ApiException ex)
{
    Console.WriteLine($"Error: {ex.Message}");
}
Parameters:
  • createPaymentLinkDto: CreatePaymentLinkDto - Link details
Returns: Task<IPaymentLinksControllerCreateApiResponse>

PaymentLinksControllerFindAllAsync(page, limit, active)

Get all payment links.
var response = await linksApi.PaymentLinksControllerFindAllAsync(
    page: 1,
    limit: 20,
    active: true
);
var links = response.Ok();

foreach (var link in links)
{
    Console.WriteLine($"{link.Name}: {link.Url}");
}
Parameters:
  • page: int? - Page number (optional)
  • limit: int? - Items per page (optional)
  • active: bool? - Filter by active status (optional)
Returns: Task<IPaymentLinksControllerFindAllApiResponse>

PaymentLinksControllerFindOneAsync(id)

Get a payment link by ID.
var response = await linksApi.PaymentLinksControllerFindOneAsync("link-id");
var link = response.Ok();
Console.WriteLine($"Link: {link.Url}");
Parameters:
  • id: string - Payment link ID
Returns: Task<IPaymentLinksControllerFindOneApiResponse>

PaymentLinksControllerUpdateAsync(id, updatePaymentLinkDto)

Update a payment link.
var updateDto = new UpdatePaymentLinkDto
{
    Active = false,
    ExpiresAt = DateTime.Parse("2024-12-31T23:59:59Z")
};

var response = await linksApi.PaymentLinksControllerUpdateAsync("link-id", updateDto);
var updated = response.Ok();
Console.WriteLine($"Link updated: {updated.Id}");
Parameters:
  • id: string - Payment link ID
  • updatePaymentLinkDto: UpdatePaymentLinkDto - Fields to update
Returns: Task<IPaymentLinksControllerUpdateApiResponse>

Transfers

Initiate and manage fund transfers between different payment rails.

Methods

TransferControllerCreateDirectBankTransferAsync(createDirectBankTransferDto)

Create a direct bank transfer.
using Devdraft.Api;
using Devdraft.Model;
using Microsoft.Extensions.DependencyInjection;

var transfersApi = host.Services.GetRequiredService<ITransfersApi>();

try
{
    var transferDto = new CreateDirectBankTransferDto(
        walletId: "wallet-id",
        paymentRail: "wire",
        sourceCurrency: "usd",
        destinationCurrency: "usdc",
        amount: 1000.00m
    );
    
    var response = await transfersApi.TransferControllerCreateDirectBankTransferAsync(transferDto);
    var transfer = response.Ok();
    
    Console.WriteLine($"Transfer created: {transfer.Id}");
    Console.WriteLine($"Bank instructions: {transfer.SourceDepositInstructions}");
}
catch (ApiException ex)
{
    Console.WriteLine($"Error: {ex.Message}");
}
Parameters:
  • createDirectBankTransferDto: CreateDirectBankTransferDto - Transfer details
Returns: Task<ITransferControllerCreateDirectBankTransferApiResponse> See also: Direct Bank Transfer Guide

TransferControllerCreateDirectWalletTransferAsync(createDirectWalletTransferDto)

Create a direct wallet transfer.
var transferDto = new CreateDirectWalletTransferDto(
    walletId: "wallet-id",
    network: "solana",
    stableCoinCurrency: "usdc",
    amount: 500.00m
);

var response = await transfersApi.TransferControllerCreateDirectWalletTransferAsync(transferDto);
var transfer = response.Ok();

Console.WriteLine($"Transfer created: {transfer.Id}");
Console.WriteLine($"Deposit address: {transfer.SourceDepositInstructions.ToAddress}");
Parameters:
  • createDirectWalletTransferDto: CreateDirectWalletTransferDto - Transfer details
Returns: Task<ITransferControllerCreateDirectWalletTransferApiResponse> See also: Direct Wallet Transfer Guide

TransferControllerCreateExternalBankTransferAsync(createExternalBankTransferDto)

Create an external bank transfer (from your wallet to external bank).
var transferDto = new CreateExternalBankTransferDto(
    sourceWalletId: "wallet-id",
    destinationBankAccountId: "bank-account-id",
    amount: 1000.00m,
    currency: "USD"
);

var response = await transfersApi.TransferControllerCreateExternalBankTransferAsync(transferDto);
var transfer = response.Ok();
Console.WriteLine($"External bank transfer: {transfer.Id}");
Parameters:
  • createExternalBankTransferDto: CreateExternalBankTransferDto - Transfer details
Returns: Task<ITransferControllerCreateExternalBankTransferApiResponse>

TransferControllerCreateExternalStablecoinTransferAsync(createExternalStablecoinTransferDto)

Create an external stablecoin transfer (from your wallet to external wallet).
var transferDto = new CreateExternalStablecoinTransferDto(
    sourceWalletId: "wallet-id",
    destinationAddress: "0x742d35Cc6Ff82a8C2D8D1Da9da17c7eDfD5bE0a3",
    network: "ethereum",
    currency: "usdc",
    amount: 250.00m
);

var response = await transfersApi.TransferControllerCreateExternalStablecoinTransferAsync(transferDto);
var transfer = response.Ok();
Console.WriteLine($"External stablecoin transfer: {transfer.Id}");
Parameters:
  • createExternalStablecoinTransferDto: CreateExternalStablecoinTransferDto - Transfer details
Returns: Task<ITransferControllerCreateExternalStablecoinTransferApiResponse>

TransferControllerCreateStablecoinConversionAsync(createStablecoinConversionDto)

Convert between different stablecoins or networks.
var conversionDto = new CreateStablecoinConversionDto(
    sourceWalletId: "wallet-id",
    destinationWalletId: "wallet-id",
    sourceNetwork: "ethereum",
    destinationNetwork: "solana",
    sourceCurrency: "usdc",
    destinationCurrency: "usdc",
    amount: 1000.00m
);

var response = await transfersApi.TransferControllerCreateStablecoinConversionAsync(conversionDto);
var conversion = response.Ok();

Console.WriteLine($"Conversion ID: {conversion.Id}");
Console.WriteLine($"Exchange rate: {conversion.ExchangeRate.Rate}");
Console.WriteLine($"Estimated completion: {conversion.EstimatedCompletion}");
Parameters:
  • createStablecoinConversionDto: CreateStablecoinConversionDto - Conversion details
Returns: Task<ITransferControllerCreateStablecoinConversionApiResponse> See also: Stablecoin Conversion Guide

Wallets

Manage wallets and query balances.

Methods

WalletControllerGetWalletsAsync()

Get all wallets for your application.
using Devdraft.Api;
using Microsoft.Extensions.DependencyInjection;

var walletsApi = host.Services.GetRequiredService<IWalletsApi>();

try
{
    var response = await walletsApi.WalletControllerGetWalletsAsync();
    Console.WriteLine("Wallets retrieved successfully");
}
catch (ApiException ex)
{
    Console.WriteLine($"Error: {ex.Message}");
}
Returns: Task<IWalletControllerGetWalletsApiResponse>
The response contains wallet IDs that you can use for transfers and other operations. In a future SDK version, this will return typed wallet objects.

Webhooks

Configure webhooks to receive real-time event notifications.

Methods

WebhookControllerCreateAsync(createWebhookDto)

Create a new webhook.
using Devdraft.Api;
using Devdraft.Model;
using Microsoft.Extensions.DependencyInjection;

var webhooksApi = host.Services.GetRequiredService<IWebhooksApi>();

try
{
    var webhookDto = new CreateWebhookDto(
        url: "https://your-app.com/webhooks/devdraft",
        name: "Production Webhook",
        isActive: true,
        encrypted: false
    );
    
    var response = await webhooksApi.WebhookControllerCreateAsync(webhookDto);
    var webhook = response.Ok();
    
    Console.WriteLine($"Webhook ID: {webhook.Id}");
    Console.WriteLine($"Signing secret: {webhook.SigningSecret}");
}
catch (ApiException ex)
{
    Console.WriteLine($"Error: {ex.Message}");
}
Parameters:
  • createWebhookDto: CreateWebhookDto - Webhook configuration
Returns: Task<IWebhookControllerCreateApiResponse> See also: Webhooks Overview

WebhookControllerFindAllAsync(page, limit, active)

Get all webhooks.
var response = await webhooksApi.WebhookControllerFindAllAsync(
    page: 1,
    limit: 20,
    active: true
);
var webhooks = response.Ok();

foreach (var webhook in webhooks)
{
    Console.WriteLine($"{webhook.Name}: {webhook.Url}");
    Console.WriteLine($"Active: {webhook.IsActive}");
}
Parameters:
  • page: int? - Page number (optional)
  • limit: int? - Items per page (optional)
  • active: bool? - Filter by active status (optional)
Returns: Task<IWebhookControllerFindAllApiResponse>

WebhookControllerFindOneAsync(id)

Get a webhook by ID.
var response = await webhooksApi.WebhookControllerFindOneAsync("webhook-id");
var webhook = response.Ok();

Console.WriteLine($"Webhook: {webhook.Name}");
Console.WriteLine($"URL: {webhook.Url}");
Console.WriteLine($"Delivery stats: {webhook.DeliveryStats}");
Parameters:
  • id: string - Webhook ID
Returns: Task<IWebhookControllerFindOneApiResponse>

WebhookControllerUpdateAsync(id, updateWebhookDto)

Update a webhook.
var updateDto = new UpdateWebhookDto
{
    Url = "https://your-app.com/webhooks/new-endpoint",
    IsActive = true
};

var response = await webhooksApi.WebhookControllerUpdateAsync("webhook-id", updateDto);
var updated = response.Ok();
Console.WriteLine($"Webhook updated: {updated.Id}");
Parameters:
  • id: string - Webhook ID
  • updateWebhookDto: UpdateWebhookDto - Fields to update
Returns: Task<IWebhookControllerUpdateApiResponse>

WebhookControllerRemoveAsync(id)

Delete a webhook.
var response = await webhooksApi.WebhookControllerRemoveAsync("webhook-id");
Console.WriteLine("Webhook deleted");
Parameters:
  • id: string - Webhook ID
Returns: Task<IWebhookControllerRemoveApiResponse>

Error Handling

All SDK methods return API response objects. Handle errors appropriately:
using Devdraft.Client;

try
{
    var response = await transfersApi.TransferControllerCreateDirectWalletTransferAsync(transferDto);
    
    // Check if response is successful
    if (response.IsOk)
    {
        var transfer = response.Ok();
        Console.WriteLine($"Transfer created: {transfer.Id}");
    }
    else
    {
        // Handle specific status codes
        switch (response.StatusCode)
        {
            case 400:
                Console.WriteLine($"Invalid request: {response.ReasonPhrase}");
                break;
            case 401:
                Console.WriteLine("Authentication failed - check your API credentials");
                break;
            case 404:
                Console.WriteLine($"Resource not found: {response.ReasonPhrase}");
                break;
            case 422:
                Console.WriteLine($"Validation error: {response.ReasonPhrase}");
                break;
            case 429:
                Console.WriteLine("Rate limited - please retry later");
                break;
            default:
                Console.WriteLine($"API error ({response.StatusCode}): {response.ReasonPhrase}");
                break;
        }
    }
}
catch (ApiException ex)
{
    Console.WriteLine($"API Exception: {ex.Message}");
    Console.WriteLine($"Status Code: {ex.StatusCode}");
    Console.WriteLine($"Response: {ex.ResponseBody}");
}
catch (Exception ex)
{
    Console.WriteLine($"Unexpected error: {ex.Message}");
}

Best Practices

1

Use Dependency Injection

Leverage .NET’s built-in DI container for better testability and maintainability.
// In Startup.cs or Program.cs
public void ConfigureServices(IServiceCollection services)
{
    services.ConfigureApi((context, options) =>
    {
        var clientKey = new ApiKeyToken("x-client-key", 
            Configuration["Devdraft:ClientKey"]);
        var clientSecret = new ApiKeyToken("x-client-secret", 
            Configuration["Devdraft:ClientSecret"]);
        
        options.AddTokens(clientKey, clientSecret);
    });
}

// In your controller or service
public class PaymentService
{
    private readonly ITransfersApi _transfersApi;
    
    public PaymentService(ITransfersApi transfersApi)
    {
        _transfersApi = transfersApi;
    }
    
    public async Task<string> CreateTransferAsync(decimal amount)
    {
        var dto = new CreateDirectWalletTransferDto(
            walletId: "wallet-id",
            network: "solana",
            stableCoinCurrency: "usdc",
            amount: amount
        );
        
        var response = await _transfersApi.TransferControllerCreateDirectWalletTransferAsync(dto);
        var transfer = response.Ok();
        return transfer.Id;
    }
}
2

Configure Resilience Policies

Use Polly policies for retry, timeout, and circuit breaker patterns.
Host.CreateDefaultBuilder(args)
    .ConfigureApi((context, services, options) =>
    {
        options.AddApiHttpClients(builder =>
        {
            builder
                .AddRetryPolicy(3)  // Retry 3 times
                .AddTimeoutPolicy(TimeSpan.FromSeconds(30))  // 30 second timeout
                .AddCircuitBreakerPolicy(10, TimeSpan.FromSeconds(30));  // Break after 10 failures
        });
    });
3

Use Async/Await Properly

Always await async methods and don’t block on async code.
// Bad: Blocking on async code
var result = api.SomeMethodAsync().Result;  // DON'T DO THIS

// Good: Proper async/await
var response = await api.SomeMethodAsync();
var result = response.Ok();
4

Handle Nullable Types

Use nullable reference types and check for null values.
#nullable enable

public async Task ProcessCustomerAsync(string? customerId)
{
    if (string.IsNullOrEmpty(customerId))
    {
        throw new ArgumentException("Customer ID is required", nameof(customerId));
    }
    
    var response = await customersApi.CustomerControllerFindOneAsync(customerId);
    var customer = response.Ok();
    
    // Check for null before accessing properties
    if (customer?.Email != null)
    {
        Console.WriteLine($"Email: {customer.Email}");
    }
}
5

Use Configuration for Credentials

Store credentials in appsettings.json or environment variables.
// appsettings.json
{
  "Devdraft": {
    "ClientKey": "your-client-key",
    "ClientSecret": "your-client-secret",
    "ApiUrl": "https://api.devdraft.ai"
  }
}
// Configuration
services.ConfigureApi((context, options) =>
{
    var config = context.Configuration;
    var clientKey = new ApiKeyToken("x-client-key", 
        config["Devdraft:ClientKey"]);
    var clientSecret = new ApiKeyToken("x-client-secret", 
        config["Devdraft:ClientSecret"]);
    
    options.AddTokens(clientKey, clientSecret);
});
6

Implement Structured Logging

Use ILogger for structured logging.
public class PaymentService
{
    private readonly ITransfersApi _transfersApi;
    private readonly ILogger<PaymentService> _logger;
    
    public PaymentService(ITransfersApi transfersApi, ILogger<PaymentService> logger)
    {
        _transfersApi = transfersApi;
        _logger = logger;
    }
    
    public async Task<string> CreateTransferAsync(decimal amount)
    {
        _logger.LogInformation("Creating transfer for amount {Amount}", amount);
        
        try
        {
            var dto = new CreateDirectWalletTransferDto(
                walletId: "wallet-id",
                network: "solana",
                stableCoinCurrency: "usdc",
                amount: amount
            );
            
            var response = await _transfersApi.TransferControllerCreateDirectWalletTransferAsync(dto);
            var transfer = response.Ok();
            
            _logger.LogInformation("Transfer created successfully with ID {TransferId}", transfer.Id);
            return transfer.Id;
        }
        catch (ApiException ex)
        {
            _logger.LogError(ex, "Failed to create transfer. Status: {StatusCode}", ex.StatusCode);
            throw;
        }
    }
}

Testing with xUnit

Example xUnit test for SDK integration:
using Xunit;
using Moq;
using Devdraft.Api;
using Devdraft.Model;
using Devdraft.Client;

public class WebhookServiceTests
{
    private readonly Mock<IWebhooksApi> _mockWebhooksApi;
    private readonly WebhookService _service;
    
    public WebhookServiceTests()
    {
        _mockWebhooksApi = new Mock<IWebhooksApi>();
        _service = new WebhookService(_mockWebhooksApi.Object);
    }
    
    [Fact]
    public async Task CreateWebhook_ReturnsWebhookId()
    {
        // Arrange
        var webhookDto = new CreateWebhookDto(
            url: "https://test.example.com/webhook",
            name: "Test Webhook",
            isActive: true,
            encrypted: false
        );
        
        var expectedWebhook = new WebhookResponseDto
        {
            Id = "webhook-123",
            Name = "Test Webhook",
            IsActive = true
        };
        
        var mockResponse = new Mock<IWebhookControllerCreateApiResponse>();
        mockResponse.Setup(r => r.Ok()).Returns(expectedWebhook);
        mockResponse.Setup(r => r.IsOk).Returns(true);
        
        _mockWebhooksApi
            .Setup(api => api.WebhookControllerCreateAsync(It.IsAny<CreateWebhookDto>(), default))
            .ReturnsAsync(mockResponse.Object);
        
        // Act
        var result = await _service.CreateWebhookAsync(webhookDto);
        
        // Assert
        Assert.Equal("webhook-123", result);
        _mockWebhooksApi.Verify(api => 
            api.WebhookControllerCreateAsync(It.IsAny<CreateWebhookDto>(), default), 
            Times.Once);
    }
    
    [Fact]
    public async Task CreateWebhook_ThrowsException_OnApiError()
    {
        // Arrange
        var webhookDto = new CreateWebhookDto(
            url: "invalid-url",
            name: "Invalid Webhook",
            isActive: true,
            encrypted: false
        );
        
        _mockWebhooksApi
            .Setup(api => api.WebhookControllerCreateAsync(It.IsAny<CreateWebhookDto>(), default))
            .ThrowsAsync(new ApiException(400, "Invalid URL"));
        
        // Act & Assert
        await Assert.ThrowsAsync<ApiException>(() => 
            _service.CreateWebhookAsync(webhookDto));
    }
}

ASP.NET Core Integration

Example ASP.NET Core controller using the SDK:
using Microsoft.AspNetCore.Mvc;
using Devdraft.Api;
using Devdraft.Model;
using Devdraft.Client;

namespace YourApp.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class TransfersController : ControllerBase
    {
        private readonly ITransfersApi _transfersApi;
        private readonly ILogger<TransfersController> _logger;
        
        public TransfersController(
            ITransfersApi transfersApi,
            ILogger<TransfersController> logger)
        {
            _transfersApi = transfersApi;
            _logger = logger;
        }
        
        [HttpPost]
        public async Task<IActionResult> CreateTransfer([FromBody] CreateTransferRequest request)
        {
            try
            {
                var transferDto = new CreateDirectWalletTransferDto(
                    walletId: request.WalletId,
                    network: request.Network,
                    stableCoinCurrency: request.Currency,
                    amount: request.Amount
                );
                
                var response = await _transfersApi.TransferControllerCreateDirectWalletTransferAsync(
                    transferDto,
                    HttpContext.RequestAborted
                );
                
                if (!response.IsOk)
                {
                    return StatusCode(
                        (int)response.StatusCode,
                        new { error = response.ReasonPhrase }
                    );
                }
                
                var transfer = response.Ok();
                
                return Ok(new
                {
                    transferId = transfer.Id,
                    depositAddress = transfer.SourceDepositInstructions?.ToAddress
                });
            }
            catch (ApiException ex)
            {
                _logger.LogError(ex, "API error creating transfer");
                return StatusCode((int)ex.StatusCode, new { error = ex.Message });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Unexpected error creating transfer");
                return StatusCode(500, new { error = "Internal server error" });
            }
        }
    }
    
    public class CreateTransferRequest
    {
        public string WalletId { get; set; } = string.Empty;
        public string Network { get; set; } = "solana";
        public string Currency { get; set; } = "usdc";
        public decimal Amount { get; set; }
    }
}

Next Steps

SDK Quickstart

Complete integration guide with examples

Transfers

Learn about initiating transfers

Webhooks

Set up webhook notifications

API Reference

Complete REST API documentation