TonProof 0.1.0

dotnet add package TonProof --version 0.1.0                
NuGet\Install-Package TonProof -Version 0.1.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="TonProof" Version="0.1.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add TonProof --version 0.1.0                
#r "nuget: TonProof, 0.1.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install TonProof as a Cake Addin
#addin nuget:?package=TonProof&version=0.1.0

// Install TonProof as a Cake Tool
#tool nuget:?package=TonProof&version=0.1.0                

TonProof.NET for TON Connect

This repository provides the TonProofService for verifying proof requests and handling authentication processes in a TON Connect-based application. It is specifically designed for ASP.NET Core applications and makes use of the tonClient from the TonLib.Net repository.

Overview

ITonProofService is essential for integrating TON Connect authentication into your ASP.NET Core application. It validates proof requests by checking the integrity and authenticity of the provided data, including public keys, addresses, domain restrictions, and proof expiration.

Usage

Configuration

⚠ Be sure to configure the tonClient from the TonLib.NET repository!

Set up the TonProofOptions with appropriate values for your TON Connect application.

Example configuration:

builder.Services.Configure<TonProofOptions>(o =>
{
  o.ValidAuthTime = 30 * 60; // 30 minutes
  o.AllowedDomains = new[] { "example.com" };
  // o.KnownWallets.Add(WalletContractV5.CodeBase64, WalletContractV5.Create); // Add other known wallet contracts
});

builder.Services.AddHttpClient<IPublicKeyProvider, TonApiPublicKeyProvider>(
  client =>
  {
    client.BaseAddress = new Uri(tonApiOptions.BaseAddress);
    if (!string.IsNullOrEmpty(tonApiOptions.Token))
    {
      client.DefaultRequestHeaders.Add("Authorization", $"Bearer {tonApiOptions.Token}");
    }
  }).AddStandardResilienceHandler();

builder.Services.AddSingleton<ITonClient, TonClient>();
builder.Services.AddSingleton<ITonProofService, TonProofService>();

If the public key cannot be extracted from the InitState of the known wallets, the service will call the GetPublicKeyAsync method from the IPublicKeyProvider.

The library offers the IPublicKeyProvider interface with two implementations:

  • TonLibPublicKeyProvider calls get_public_key method on the smart contract via Lite server.
  • TonApiPublicKeyProvider calls the HTTP method from TonApi.

If these providers don't fit your requirements, you can create your own by implementing the IPublicKeyProvider interface.

For more information, please refer to the complete example TonProof.Demo/Program.cs

Using the service for authentication

To fully implement authentication using ITonProofService, you'll need two endpoints: one to generate a payload for the client and another to verify the proof and generate a JWT token (e.g.).

1. Generating a payload.
The client first requests a payload, which will be used in the proof verification step. In this example, the payload is a token that can include any necessary information for the verification process.

Example: <details> <summary>Request</summary> <pre> url -X 'POST'
'https://host/Auth/GeneratePayload'
-H 'accept: application/json'
-d '' </pre> </details>

[AllowAnonymous]
public ActionResult<GeneratePayloadResponse> GeneratePayload()
{
  var payload = this.CreatePayloadToken();

  var response = new GeneratePayloadResponse()
  {
      Payload = payload
  };
  return this.Ok(response);
}

<details> <summary>Response</summary> <pre> { "payload": "string" } </pre> </details>

2. Verifying the proof and generating a token.
After the client receives the payload, they will submit it along with the evidence for verification. The server will then verify the proof and generate a JWT token if the evidence for verification is valid.

Example: <details> <summary>Request</summary> <pre> curl -X 'POST'
'https://host/Auth/CheckProof'
-H 'accept: application/json'
-H 'Content-Type: application/json'
-d '{ "address": "0:13f04fa2a978c...", "network": "-3", "public_key": "c5134fcb...", "proof": { "timestamp": 1721812530, "domain": { "LengthBytes": 20, "value": "winogarcia.github.io" }, "signature": "YlhjR9vEhyGyYbr...", "payload": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9", "state_init": "te6cc..." } }' </pre> </details>

[AllowAnonymous]
public async Task<ActionResult<CheckProofResponse>> CheckProof(CheckProofRequest request, CancellationToken cancellationToken)
{
  var verifyResult = await this.TonProofService.VerifyAsync(request, cancellationToken);
  if (verifyResult != VerifyResult.Valid)
  {
    return this.BadRequest($"Invalid proof: {Enum.GetName(verifyResult)}");
  }

  var payload = request.Proof.Payload;
  if (!this.ValidateToken(payload))
  {
    return this.BadRequest("Invalid payload");
  }

  var token = this.CreateToken(payload, request.Address);

  return this.Ok(new CheckProofResponse()
  {
    Token = token
  });
}

<details> <summary>Response</summary> <pre> { "token": "string" } </pre> </details>

For more information, please refer to the complete example AuthController.cs

Example of an authorized request to get a balance

In this example, we will show how to make an authorized request to retrieve the balance using a JWT token. The JWT token, created in the earlier steps, is employed to authorize the request. The ASP.NET Core middleware verifies the validity of the JWT token, ensuring that only authenticated users can access the endpoint.

<details> <summary>Request</summary> <pre> curl -X 'POST'
'https://host/Account/GetBalance'
-H 'accept: application/json'
-H 'Authorization: Bearer XXXXXXX'
-d '' </pre> </details>

[Authorize]
public async Task<ActionResult<BalanceResponse>> GetBalance(CancellationToken cancellationToken)
{
  await this.tonClient.InitIfNeededAsync(cancellationToken);

  var address = this.GetUserAddress();
  var ast = await this.tonClient.GetAccountState(address);

  var response = new BalanceResponse
  {
    Amount = ast.Balance.ToString()
  };
  return this.Ok(response);
}

<details> <summary>Response</summary> <pre> { "amount": "777777" } </pre> </details>

For more information, please refer to the complete example AccountController.cs

More information is available in the demo project TonProof.Demo

3rd-party libraries and dependencies

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
0.1.0 329 8/7/2024