A Dart library that supports the Topl blockchain.

Topl logo Code of Conduct License Github build status bip-topl code coverage @topl_protocol on Twitter
stackoverflow
Discord

BramblDart

A dart library that connects via JSON-RPC to interact with the Topl blockchain. It connects to a Bifrost node to send transactions, interact with addresses and much more!

Features

  • Connect to an Topl node with the rpc-api, call common methods
  • Send signed Topl transactions
  • Generate private keys, setup new Topl addresses

Usage

Credentials and Wallets

In order to send transactions on the Topl network, some credentials are required. The library supports raw private keys and v1 encrypted key-files. In addition, it also supports the generation of keys via a HD wallet.


import 'package:brambldart/brambldart.dart';

// You can create credentials from private keys
Credentials credentials = ToplSigningKey.fromString("base58EncodedPrivateKeyHere");

// Or generate a new key randomly
var networkId = 0x40;
var propositionType = PropositionType.ed25519();
Credentials random = ToplSigningKey.createRandom(networkId, propositionType);

// In either way, the library can derive the public key and the address
// from a private key:

var address = await credentials.extractAddress();
print(address.toBase58());

Another way to obtain Credentials which the library uses to sign transactions is the usage of an encrypted keyfile. Wallets store a private key securely and require a password to unlock. The library has experimental support for version 1 keyfiles which are generated by this client and support Extended ED25519 Signing Keys:

import 'dart:io';
import 'package:brambldart/brambldart.dart';

String content = new File("wallet.json").readAsStringSync();
KeyStore keystore = KeyStore.fromV1Json(content, "testPassword");

Credentials unlocked = ToplSigningKey.fromString(keystore.privateKey);
// You can now use these credentials to sign transactions

You can also create Keystore files with this library. To do so, you first need the private key you want to encrypt and a desired password. Then, create your wallet with

Keystore keystore = KeyStore.createNew(credentials, 'password', random);
print(keystore.toJson());

You can also write keystore.toJson() to file which you can later open with BramblSC and potentially other Topl API libraries in the future.

Custom credentials

If you want to integrate brambldart with other wallet providers, you can implement Credentials and override the appropriate methods.

Connecting to an RPC server

The library won't send signed transactions to forgers itself. Instead, it relies on an RPC client to do that. You can use a public RPC API like baas, or, if you just want to test things out, use a private testnet with bifrost. All of these options will give you an RPC endpoint to which the library can connect.

import 'package:dio/dio.dart'; //You can also import the browser version
import 'package:brambldart/brambldart.dart';

var networkId = 0x40;
var propositionType = PropositionType.ed25519();
var privateKey = 'base58EncodedPrivateKey';

var apiUrl = "http://localhost:9085"; //Replace with your API
var httpClient = Dio(BaseOptions(
                    baseUrl: basePathOverride ?? basePath,
                    contentType: 'application/json',
                    connectTimeout: 5000,
                    receiveTimeout: 3000)
var bramblClient = BramblClient(httpClient: httpClient, basePathOverride: apiUrl);
var credentials = bramblClient.credentialsFromPrivateKey(privateKey, networkId, propositionType);

// You can now call rpc methods. This one will query the amount of Topl tokens you own
Balance balance = bramblClient.getBalance(credentials.address);
print(balance.toString());

Sending transactions

Of course, this library supports creating, signing and sending Topl transactions:

import 'package:brambldart/brambldart.dart';

/// [...], you need to specify the url and your client, see example above
var bramblClient = BramblClient(basePathOverride: apiUrl, httpClient: httpClient);

var credentials = bramblClient.credentialsFromPrivateKey("0x...");

const value = 1;

final assetCode =
    AssetCode.initialize(1, senderAddress, 'testy', 'valhalla');

final securityRoot = SecurityRoot.fromBase58(
    Base58Data.validated('11111111111111111111111111111111'));

final assetValue = AssetValue(
    value.toString(), assetCode, securityRoot, 'metadata', 'Asset');

final recipient = AssetRecipient(senderAddress, assetValue);

final data = Latin1Data.validated('data');

final assetTransaction = AssetTransaction(
    recipients: [recipient],
    sender: [senderAddress],
    changeAddress: senderAddress,
    consolidationAddress: senderAddress,
    propositionType: PropositionType.ed25519().propositionName,
    minting: true,
    assetCode: assetCode,
    data: data);

final rawTransaction =
          await client.sendRawAssetTransfer(assetTransaction: assetTransaction);

expect(rawTransaction['rawTx'], isA<TransactionReceipt>());

print(rawTransaction);

final txId = await client.sendTransaction(
    [first],
    rawTransaction['rawTx'] as TransactionReceipt,
    rawTransaction['messageToSign'] as Uint8List);

Missing data, like the fee, the sender or a change/consolidation address will be inferred by the BramblClient when not explicitly specified. If you only need the signed transaction but don't intend to send it, you can use client.signTransaction.

Feature requests and bugs

Please file feature requests and bugs at the issue tracker. If you want to contribute to this library, please submit a Pull Request.

Libraries

brambldart
client
Exports Brambl streaming operations needed to poll for transaction updates and changes to block state
credentials
Library to create and unlock Topl Wallets and operate with private keys.
crypto
Exports low-level cryptographic operations needed to sign Topl transactions
model
utils