Kin SDK Docs

Kin SDK Docs

  • Developers
  • Build

›Node.js

Overview

  • Getting Started
  • Kin Architecture Overview
  • How It Works
  • App Registration
  • Migration to New SDKs
  • Solana
  • Terms & Concepts

Agora

  • Agora API Reference
  • Agora Webhook Reference

Android

  • Android SDK

iOS

  • iOS SDK

Go

  • Go SDK

Python

  • Python SDK
  • Python API reference

Node.js

  • Node.js SDK

Deprecated

    Android

    • Hello World Android
    • Kin SDK for Android
    • Android API reference
    • Backup/Restore Module for Android
    • Discovery Module for Android
    • Send Kin Module for Android

    iOS

    • Hello World iOS
    • Kin SDK for iOS
    • iOS API reference
    • Backup/Restore Module for iOS
    • Appreciation Module 'Options Menu' for iOS

    Unity

    • Hello World Unity
    • Kin SDK for Unity

    Python

    • Hello World Python
    • Kin SDK for Python
    • Kin Python Bootstrap
    • Python API reference

    Node.js

    • Hello World Node.js
    • Kin SDK for Node.js
Edit

Kin SDK for Node.js

Kin SDK for Node is meant to be used as a back-end service. It can perform actions for your client apps (iOS, Android, etc.) and also operate as a server for you to build services on top of the Kin blockchain. For example, the SDK can communicate with the Kin Blockchain on behalf of the client to create accounts and to whitelist transactions. It can also monitor blockchain transactions so that you can implement broader services. It is up to you how to integrate the SDK in your overall architecture and how to manage your server.

Requirements

Make sure you have Node v8 or higher.

Installation

npm install @kinecosystem/kin-sdk-node

Track the development of this SDK on GitHub.

Usage with TypeScript

Kin SDK for Node is written in TypeScript, thus typings are available out of the box and will be maintained.
Kin SDK for Node can be used from Vanilla JS as well.

Using Promises

Every method that performs network requests returns a chainable promise instead of a callback.

Overview

In this introduction, we describe a few basic operations on the Kin Blockchain and some features that are exclusive to Kin SDK for Node:

  • Accessing the Kin blockchain
  • Managing Kin accounts
  • Executing transactions against Kin accounts
  • Listening for Kin Payments (Node SDK can monitor all accounts)
  • Channels (unique to the back-end SDKs)

Accessing the Kin Blockchain

The SDK has two main components, KinClient and KinAccount.
KinClient - used to query the blockchain and perform actions that do not require authentication (e.g., get an account balance)
KinAccount - used to perform authenticated actions on the blockchain (e.g., Send payment)

To initialize the Kin Client, you need to specify an environment (the Test and Production environments are pre-configured).

const KinClient = require('@kinecosystem/kin-sdk-node').KinClient;
const Environment = require('@kinecosystem/kin-sdk-node').Environment;

const client = new KinClient(Environment.Testnet);

Alternatively, you can configure a custom environment with your own parameters:

const Environment = require('@kinecosystem/kin-sdk-node').Environment;

 const environement = new Environment({
        name: 'my custom environment',
        url: 'network url',
        passphrase: 'network passphrase',
        friendbotUrl: 'friendbot url' //Optional param for testnet only
    });

Once you have a KinClient, you can use it to get a KinAccount object and its associated keypair. Kin SDK for Node generates a keypair based on a secret seed. Each seed uniquely determines a keypair - if you save a secret seed, you can recreate the associated keypair.

The KinAccount object can be initialized in two ways:

  • With a single seed:
const account = client.createKinAccount({
            seed: 'seed'
        });
  • With channels
const account = client.createKinAccount({
            seed: 'seed',
            channelSecretKeys: ['channel_seed1', 'channel_seed2', ...]
        });

A unique appID can be provided to be added to all your transactions:

const account = client.createKinAccount({
            seed: 'seed',
            appId: 'unique_app_id',
            channelSecretKeys: ['channel_seed1', 'channel_seed2', ...]
        });

See more about channels in the "Channels" section

See AppID at Terms & Concepts to learn more about what an appID is and how to get it.

Managing Kin Accounts

Most methods provided by the KinClient to query the blockchain about a specific account can also be used from the KinAccount object to query the blockchain about itself.

Creating and Retrieving a Kin Account

Before you can send or receive Kin, you have to create an account on the blockchain. Do the following:

  1. Create a builder for the transaction:

account.buildCreateAccount({
        address: 'address',
        startingBalance: 10,
        fee: 100,
        memoText: 'my first account' //a text memo can also be added; memos cannot exceed 21 characters
    })
  1. Submit the transaction to the blockchain:
        .then(createAccountBuilder => {
            return account.submitTransaction(createAccountBuilder)
        }).then(transactionId => {
                });
  1. Save the transaction ID for future reference.

Account Address

Each account on the Kin blockchain has a public address. The address is identical to the public portion of the keypair created during account creation.

const accountAddress = account.publicAddress;

Checking Whether an Account Exists on the Blockchain

This is the only action you can perform without an account.

client.isAccountExisting('address')
        .then(exist => {
            if (exist){
                //do something
            }
        });

Account Balance and Data

Now that you have an account, you can check its balance.

client.getAccountBalance('address')
        .then(balance => {
                    });

You may want to use the output of this function in your application's code. You can get addtional information on the account with getAccountData.

client.getAccountData('address')
        .then(accountData => console.log(accountData))

The output will look similar to this:

{
    id: 'GDAVCZIOYRGV74ROE344CMRLPZYSZVRHNTRFGOUSAQBILJ7M5ES25KOZ',
    accountId: 'GDAVCZIOYRGV74ROE344CMRLPZYSZVRHNTRFGOUSAQBILJ7M5ES25KOZ',
    sequenceNumber: 9357771665313568,
    pagingToken: '',
    subentryCount: 1,
    thresholds: {highThreshold: 0, medThreshold: 0, lowThreshold: 0},
    signers:
           [{
               publicKey: 'GDAVCZIOYRGV74ROE344CMRLPZYSZVRHNTRFGOUSAQBILJ7M5ES25KOZ',
               weight: 1
           }],
    data: {},
    balances:
           [{
               assetType: 'native',
               balance: 2.96005,
               assetCode: undefined,
               assetIssuer: undefined,
               limit: undefined
           }],
    flags: {authRequired: false, authRevocable: false}
}

Keypairs

Several functions that involve seeds and keypairs are available.

Creating a New Random Keypair
const KeyPair = require('@kinecosystem/kin-sdk-node').KeyPair;

const newKeyPair = KeyPair.generate();
Creating a Keypair from an Existing Seed
const keyPair = KeyPair.fromSeed('seed');
Getting the Public Address from a Seed
const publicAddress = KeyPair.fromSeed('seed');
Generating a Deterministic Keypair

Given the same seed and salt (addtional passphrase), the same seed will always be generated.

const hdKeyPair = KeyPair.generateHDSeed('seed', 'salt');

Transactions

Transactions are performed on the Kin blockchain in a two-step process:

  1. Building the transaction, including calculation of the transaction hash. The hash is used as a transaction ID and is necessary for querying the status of the transaction.
  2. Sending the transaction to servers for execution on the blockchain.

Transferring Kin to Another Account

To transfer Kin to another account, you need the account's public address. The snippet Transfer Kin will transfer 20 Kin to the recipient account "GDIRGGTBE3H4CUIHNIFZGUECGFQ5MBGIZTPWGUHPIEVOOHFHSCAGMEHO".

Option 1: Send the transaction without using channels

   //Build the transaction locally
   account.buildSendKin({
        address: destination,
        amount: 20,
        fee: 100,
        memoText: 'tx memo'
    }).then(builder => {
        //Use the builder to submit the transaction to the blockchain
        builder => account.submitTransaction(builder)
    });

Option 2: Use channels to enable parallel processing of multiple transactions

//acquire a channel first
account.channelsPool.acquireChannel(channel =>
        //Build the transaction within the channel
        account.buildSendKin({
            address: destination,
            amount: 20,
            fee: 100,
            memoText: 'tx memo',
            channel: channel
        })
        //Use the builder to submit the transaction to the blockchain
            .then(builder => account.submitTransaction(builder))
    )
        // The Promise inside acquireChannel function can be chained directly from acquireChannel.
        .then(transactionId => console.log(transactionId));

Note: A channel is a resource that has to be released after use. You should use channels only within the above function. In that case, the SDK will release the channel back to the channels pool, so it will be available for later use.

Decode Transaction

When the client sends you a transaction for whitelisting, it will be XDR-encoded. You may want to decode the transaction and verify its details before whitelisting it. There are two methods of decoding an XDR-encoded transaction:

  • Decode only to "RawTransaction": This method returns a "RawTransaction" object. It contains the entire transaction data, including some fields that are of no use to the user.

    const transaction = Transaction.decodeRawTransaction({
      envelope: encodedTransaction,
      networkId: networkId
    });
    
  • Decode to "Transaction": This method returns a "Transaction" object. It contains only the data that the usere needs.

    const transaction = Transaction.decodeTransaction({
      envelope: encodedTransaction,
      networkId: networkId
    });
    

Getting the Minimum Acceptable Fee from the Blockchain

By default, your user will have to pay a fee to the blockchain to transfer Kin or perform any other blockchain transaction. The fee depends on how fast the transaction will be processed by the blockchain. To find out what the minimum acceptable fee is, use:

client.getMinimumFee()
        .then(minFee =>{
            //save minimum fee
        });

The returned fee amount is in Quarks (0.00001 Kin).

Some apps can be added to the Kin whitelist, which is a set of pre-approved apps whose users will not be charged any fee for performing transactions. If your app is on the whitelist, see section Transferring Kin to Another Account Using Whitelist Service.

Transferring Kin to Another Account Using Whitelist Service

The Kin blockchain also allows for transactions to be performed with no fee. Apps and services have to be approved first (for details, see Whitelisted Account. After your service has been added to the whitelist, you will be able to whitelist transactions for your clients. To have their transactions whitelisted, your clients will send HTTP requests containing their transactions to your Node server. You will then whitelist the transactions and return them to the clients to send to the blockchain.

const whitelistedTransaction = account.whitelistTransaction({ envelope: clientTransaction, networkId: network_id});

Note that if you are whitelisted, any payment sent from a server developed with the Node SDK is already considered whitelisted, so the server transactions will not need the above step.

Getting Transaction Data

To review a transaction, use getTransactionData with the transaction's ID:

client.getTransactionData('transactionId')
        .then(transactionData => {
            
        });

The returned object will be one of the following:

  • PaymentTransaction - in case of a simple payment transaction between two accounts.
interface PaymentTransaction {
    type: 'PaymentTransaction';
    fee: number;
    hash: string;
    sequence: number;
    source: string;
    signatures: xdr.DecoratedSignature[],
    amount: number;
    destination: string;
    memo?: string;
    timestamp: string;
}
  • CreateAccountTransaction - in case of a simple Create Account transaction.
interface CreateAccountTransaction {
    type: 'CreateAccountTransaction';
    fee: number;
    hash: string;
    sequence: number;
    source: string;
    signatures: xdr.DecoratedSignature[],
    destination: string;
    startingBalance: number;
    memo?: string;
    timestamp: string;
}
  • RawTransaction - when the transaction includes more than a single operation or more advanced operation types.
interface RawTransaction {
    type: 'RawTransaction';
    fee: number;
    hash: string;
    sequence: number;
    source: string;
    signatures: xdr.DecoratedSignature[],
    memo?: Memo;
    operations: Operation[];
    timestamp: string;
}

Friendbot

If a friendbot endpoint is provided when creating the environment (it is provided with the Environment.Testnet), you will be able to use the friendbot method to call a service that will create an account for you, or fund an existing account with Kin.

client.friendbot({
        address: 'address',
        amount: 100
    })
        .then(transactionId => {
            //in case of success, the transaction id of the funding/creating transaction will be returned.  
        });

Listening for Kin Payments

These methods can be used to listening for Kin payment that an account or multiple accounts are sending or receiving.

While SDKs designed for client apps such as iOS and Android can listen for an accounts associated with their local users, the Node SDK can monitor other users' accounts. This feature is currently unique to the backend SDKs.

It is possible to monitor multiple accounts using createPaymentListener. This function will continuously get data about all accounts on the blockchain, and you can specify which accounts you want to monitor.

const paymentListener = client.createPaymentListener({
        onPayment: payment => {
            console.log(payment);
        },
        addresses: ['address1', 'address2']
    });

You can freely add accounts to this monitor or remove them:

paymentListener.addAddress('address3');
paymentListener.removeAddress('address1');

Stopping a Monitor

When you are done monitoring, stop the monitor to terminate the connection to the blockchain.

paymentListener.close();

Channels

The Kin Blockchain is based on the the Stellar blockchain. One of the most sensitive points in Stellar is transaction sequence. For a transaction to be submitted successfully, its sequence number should be correct. However, if you have several SDK instances, each working with the same wallet account or channel accounts, sequence collisions will occur.

We highly recommend to keep only one KinAccount instance in your application and to have unique channel accounts. Depending on the nature of your application, here are our recommendations:

  1. Have a simple (command line) script that sends transactions on demand or only once in a while. In this case, the SDK can be instantiated with only the wallet key, and channel accounts are not necessary.

  2. Have a single application server that handles a stream of concurrent transactions. In this case, you need to make sure that only a single instance of a KinAccount is initialized with multiple channel accounts.

  3. Have a number of load-balanced application servers. Each application server should have the setup outlined above and its own channel accounts. This way, you ensure that there are no collisions in your transaction sequences.

Creating Channels

The Kin SDK allows you to create HD (highly deterministic) channels based on your seed and a passphrase to be used as a salt. As long as you use the same seed and passphrase, you will always get the same list of seeds.

Channels.createChannels will create those channels on the Kin blockchain using the base seed account.

const Channels = require('@kinecosystem/kin-sdk-node').Channels;

const channels = Channels.createChannels({
        environment: Environment.Testnet,
        baseSeed : 'base seed',
        salt: 'seed',
        channelsCount : 'channels count',
        startingBalance: 'starting balance for each channel'
    });

channels will be a list of KeyPair objects representing the seeds the SDK created for you. They can be used when initializing the KinAccount object.

If you just want to get the list of the channels generated from your seed + passphrase combination without actually creating them, use this function to get a list of KeyPair objects.

const channels = Channels.generateSeeds({
        baseSeed: 'base seed',
        salt: 'seed',
        channelsCount : 'channels count'
    });

Error Handling

The Kin SDK for Node can produce several types of errors, such as IO (network) errors, invalid input errors, and transaction errors. Each Error object contains a type field that can be used for identifying the error.

Examples of Kin SDK primary errors:

switch (err.type) {
  case 'NetworkError':
    // Network availability error. 
    break;
  case 'HorizonError':
    // The blockchain returns an error.
    err.errorCode; //The returned error code from Horizon server.
    break;
  case 'AccountNotFoundError':
    // Some operation performed an account that wasn't created on the Kin blockchain.
    break;
  default:
    // Handle any other types of unexpected errors
    break;
}

For the full error list, see error declaration at index.ts

Last updated on 2019-9-9
← Hello World Node.js
  • Requirements
  • Installation
    • Usage with TypeScript
    • Using Promises
  • Overview
    • Accessing the Kin Blockchain
    • Managing Kin Accounts
    • Transactions
    • Friendbot
  • Listening for Kin Payments
    • Stopping a Monitor
  • Channels
    • Creating Channels
  • Error Handling
Kin SDK Docs

Docs

IntroductionAndroidiOSGoPythonNode.js

Resources

GithubGuidelines
LinkedInRedditMedium
Privacy policyTerms and conditions
© 2021 Kin Foundation