Beacon is the implementation of the wallet interaction standard tzip-10 which describes the connnection of a dApp with a wallet.
- .NET Standard 2.1
Beacon .NET SDK is available on NuGet:
dotnet add package Beacon.Sdk
For a complete example, refer
to Dapp sample
or to Wallet sample
.
Here is step by step guide how to create and use WalletBeaconClient
:
Use BeaconClientFactory
to create an instance of WalletBeaconClient
const string path = "wallet-beacon-sample.db";
var factory = new WalletBeaconClientFactory();
var options = new BeaconOptions
{
AppName = "Wallet sample",
AppUrl = "https://awesome-wallet.io",
IconUrl = "https://services.tzkt.io/v1/avatars/KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5",
KnownRelayServers = Constants.KnownRelayServers,
// for some operating systems compability reasons we should use Mode=Exclusive for LiteDB.
DatabaseConnectionString = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? $"Filename={path}; Connection=Shared;"
: $"Filename={path}; Mode=Exclusive;"
};
// creating test logger, you can provide your own app-context logger here.
Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.WriteTo.Console()
.CreateLogger();
ILoggerProvider loggerProvider = new SerilogLoggerProvider(Logger);
IWalletBeaconClient beaconWalletClient = BeaconClientFactory.Create<IWalletBeaconClient>(options, loggerProvider);
To listen for the incoming Beacon messages you need to subscribe to OnBeaconMessageReceived;
beaconWalletClient.OnBeaconMessageReceived += async (object? sender, BeaconMessageEventArgs args) =>
{
BaseBeaconMessage message = args.Request;
if (message == null) return;
case BeaconMessageType.permission_request:
{
if (message is not PermissionRequest permissionRequest)
return;
// here we give all permissions that dApp request, you can modify permissionRequest.Scopes
var response = new PermissionResponse(
id: permissionRequest.Id,
senderId: beaconWalletClient.SenderId,
appMetadata: beaconWalletClient.Metadata,
network: permissionRequest.Network,
scopes: permissionRequest.Scopes,
publicKey: "your tezos wallet address public key",
version: permissionRequest.Version);
await beaconWalletClient.SendResponseAsync(receiverId: permissionRequest.SenderId, response);
break;
}
case BeaconMessageType.sign_payload_request:
{
if (message is not SignPayloadRequest signRequest)
return;
// do some stuff here and send response.
break;
}
case BeaconMessageType.operation_request:
{
if (message is not OperationRequest operationRequest)
return;
// do some stuff here and send response.
break;
}
default:
{
var error = new BeaconAbortedError(
id: KeyPairService.CreateGuid(),
senderId: beaconWalletClient.SenderId);
await beaconWalletClient.SendResponseAsync(receiverId: message.SenderId, error);
break;
}
};
You can also subscribe to
beaconWalletClient.OnConnectedClientsListChanged += (object sender, ConnectedClientsListChangedEventArgs e) => {}
This event is triggered at the moments of issuing permissions or disconnecting peers, it's good to change your connected apps list here.
I recommend that you don't use anonymous functions to subscribe to events if you have to unsubscribe from the event at some later point in your code.
await beaconWalletClient.InitAsync()
beaconWalletClient.Connect();
string pairingQrCode = "paste-qrcode-here";
var pairingRequest = beaconWalletClient.GetPairingRequest(pairingQrCode);
await beaconWalletClient.AddPeerAsync(pairingRequest);
beaconWalletClient.Disconnect();
Follow these steps to reproduce the typical wallet workflow:
- Clone this repo and restore nuget packages
- Open Beacon playground, scroll to Setup and press " Run Code"
- Choose "Pair wallet on another device" and click on the QR code to copy
- Start
Beacon.Sdk.Sample.Wallet
sample project (make wallet-sample
) - Paste copied QR code to console
- In the browser you should see "Got permissions" message, sample project response with all requested permissions to dApp
- Scroll down to "Operation Request" item and do the "Run Code" thing again
- You should see the successful operation message
Take a look at the Wallet sample
project.
Here is step by step guide how to create and use DappBeaconClient
:
Use BeaconClientFactory
to create an instance of DappBeaconClient
IDappBeaconClient beaconDappClient = BeaconClientFactory.Create<IDappBeaconClient>(options, loggerProvider);
Options are same as during WalletBeaconClient
creation
To listen for the incoming responses from wallet you need to subscribe to OnBeaconMessageReceived
beaconDappClient.OnBeaconMessageReceived += async (object? sender, BeaconMessageEventArgs args) =>
{
if (args.PairingDone)
{
var network = new Network
{
Type = NetworkType.mainnet,
Name = "mainnet",
RpcUrl = "https://rpc.tzkt.io/mainnet"
};
var permissionScopes = new List<PermissionScope>
{
PermissionScope.operation_request,
PermissionScope.sign
};
// after pairing complete we request permissions from wallet
await BeaconDappClient.RequestPermissions(permissionScopes, network);
return;
}
var message = args.Request;
if (message == null) return;
// almost like as in WalletClient, but we receiving Reponses here and sending Requests
switch (message.Type)
{
case BeaconMessageType.permission_response:
{
if (message is not PermissionResponse)
return;
// do some stuff here and send response.
break;
}
case BeaconMessageType.operation_response:
// ...
case BeaconMessageType.sign_payload_response:
// ...
}
};
OnConnectedClientsListChanged
also available as in DappBeaconClient
. They both inherited from BaseBeaconClient
class
await beaconDappClient.InitAsync()
beaconDappClient.Connect();
var pairingRequestQrData = beaconDappClient.GetPairingRequestInfo();
Copy pairingRequestQrData
and paste it to Beacon wallet
var activeAccountPermissions = beaconDappClient.GetActiveAccount();
beaconDappClient.RequestPermissions(permissionScopes, network);
beaconDappClient.RequestSign(PayloadToSign, SignPayloadType.raw);
beaconDappClient.RequestOperation(operationDetails);
beaconDappClient.Disconnect();
Follow these steps to reproduce a typical dapp workflow:
- Clone this repo and restore nuget packages
- Start
Beacon.Sdk.Sample.Dapp
project (make dapp-sample
) - Go to https://debug.walletbeacon.io/ and create account (or connect your wallet)
- Copy pairing data string from console, paste it to the site, and press "Connect"
- You should see that Beacon wallet received permissions from
Beacon.Sdk.Sample.Dapp
("Messages" section) - You can print
sign
command in console to sendsign request
to the wallet - You can print
operation
command in console to sendoperation request
to the wallet
Take a look at the Dapp sample
project.