NKN Client: Send and receive data for free between any NKN clients regardless their network condition without setting up a server or relying on any third party services. Data are end to end encrypted by default. Typically you might want to use multiclient instead of using client directly.
NKN MultiClient: Send and receive data using multiple NKN clients concurrently to improve reliability and latency. In addition, it supports session mode, a reliable streaming protocol similar to TCP based on ncp.
Advantages of using NKN client/multiclient for data transmission:
Network agnostic: Neither sender nor receiver needs to have public IP address or port forwarding. NKN clients only establish outbound (websocket) connections, so Internet access is all they need. This is ideal for client side peer to peer communication.
Top level security: All data are end to end authenticated and encrypted. No one else in the world except sender and receiver can see or modify the content of the data. The same public key is used for both routing and encryption, eliminating the possibility of man in the middle attack.
Decent performance: By aggregating multiple overlay paths concurrently, multiclient can get ~100ms end to end latency and 10+mbps end to end session throughput between international devices.
Everything is free, open source and decentralized. (If you are curious, node relay traffic for clients for free to earn mining rewards in NKN blockchain.)
npm install nkn-sdk
And then in your code:
const nkn = ;
or using ES6 import:
For browser, use
For environment where cryptographically secure random number generator is not natively implemented (e.g. React Native), see Random bytes generation.
NKN client provides the basic functions of sending and receiving data between NKN clients or topics regardless their network condition without setting up a server or relying on any third party services. Typically you might want to use multiclient instead of using client directly.
Create a client with a generated key pair:
let client = ;
Or with an identifier (used to distinguish different clients sharing the same key pair):
let client =identifier: 'any-string';
Get client secret seed and public key:
Create a client using an existing secret seed:
let client =seed: '2bc5501d131696429264eb7286c44a29dd44dd66834d9471bd8b0eb875a1edb0';
Secret key should be kept SECRET! Never put it in version control system like here.
By default the client will use bootstrap RPC server (for getting node address) provided by nkn.org. Any NKN full node can serve as a bootstrap RPC server. You can create a client using customized bootstrap RPC server:
let client =rpcServerAddr: '';
Get client NKN address, which is used to receive data from other clients:
Listen for connection established:
Send text message to other clients:
You can also send byte array directly:
The destination address can also be a name registered using wallet.
Publish text message to all subscribers of a topic (subscribe is done through wallet):
Receive data from other clients:
If a valid data (string or Uint8Array) is returned at the end of the handler, the data will be sent back to sender as reply:
Handler can also be an async function, and reply can be byte array as well:
Note that if multiple message handlers are added, the result returned by the first handler (in the order of being added) will be sent as reply.
send method will return a Promise that will be resolved when sender
receives a reply, or rejected if not receiving reply or acknowledgement within
timeout period. Similar to message, reply can be either string or byte array:
Client receiving data will automatically send an acknowledgement back to sender
if message handler returns
undefined so that sender will be able to
know if the packet has been delivered. On the sender's side, it's almost the
same as receiving a reply, except that the Promise is resolved with
If handler returns
false, no reply or ACK will be sent.
MultiClient creates multiple NKN client instances by adding identifier prefix
__2__., ...) to a NKN address and send/receive packets
concurrently. This will greatly increase reliability and reduce latency at the
cost of more bandwidth usage (proportional to the number of clients).
MultiClient basically has the same API as client, with a few additional initial configurations and session mode:
let multiclient =numSubClients: 4originalClient: false;
originalClient controls whether a client with original identifier
(without adding any additional identifier prefix) will be created, and
numSubClients controls how many sub-clients to create by adding prefix
__2__., etc. Using
originalClient: true and
numSubClients: 0 is equivalent to using a standard NKN Client without any
modification to the identifier. Note that if you use
originalClient: true and
numSubClients is greater than 0, your identifier should not starts with
X is any number, otherwise you may end up with identifier
Any additional options will be passed to NKN client.
MultiClient instance shares most of the public API as regular NKN client, see
client for usage and examples. If you need low-level property or API,
you can use
multiclient.defaultClient to get the default client and
multiclient.clients to get all clients.
In addition to the default packet mode, multiclient also supports session mode, a reliable streaming protocol similar to TCP based on ncp.
Listens for incoming sessions (without
listen() no sessions will be accepted):
Dial a session:
Accepts for incoming sessions:
Write to session:
Read from session:
session.read also accepts a
maxSize parameter, e.g.
maxSize > 0, at most
maxSize bytes will be returned. If
maxSize == 0 or
not set, the first batch of received data will be returned. If
maxSize < 0,
all received data will be concatenated and returned together.
Session can be converted to WebStream using
session.getWritableStream(closeSessionOnEnd = false). Note that WebStream is
not fully supported by all browser, so you might need to polyfill it globally or
NKN Wallet SDK.
Create a new wallet with a generated key pair:
let wallet = password: 'password' ;
Create wallet from a secret seed:
let wallet =seed: walletpassword: 'new-wallet-password';
Export wallet to JSON string:
let walletJson = wallet;
Load wallet from JSON and password:
let wallet = nknWallet;
By default the wallet will use RPC server provided by nkn.org. Any NKN full node can serve as a RPC server. You can create a wallet using customized RPC server:
let wallet =password: 'password'rpcServerAddr: '';
Verify whether an address is a valid NKN wallet address:
Verify password of the wallet:
Get balance of this wallet:
Transfer token to another wallet address:
Subscribe to a topic for this wallet for next 100 blocks (around 20 seconds per
block), client using the same key pair (seed) as this wallet and same identifier
as passed to
subscribe will be able to receive messages from this topic:
Random bytes generation
By default, this library uses the same random bytes generator as tweetnacl-js.
If a platform you are targeting doesn't implement secure random number
generator, but you somehow have a cryptographically-strong source of entropy
Math.random!), and you know what you are doing, you can plug it like
An example using node.js native crypto library:
crypto = ;nkn;
setPRNG completely replaces internal random byte generator
with the one provided.
Can I submit a bug, suggestion or feature request?
Yes. Please open an issue for that.
Can I contribute patches?
Yes, we appreciate your help! To make contributions, please fork the repo, push your changes to the forked repo with signed-off commits, and open a pull request here.
Please sign off your commit. This means adding a line "Signed-off-by: Name " at the end of each commit, indicating that you wrote the code and have the right to pass it on as an open source patch. This can be done automatically by adding -s when committing:
git commit -s