Easily integrate an exchange backend to Kadena's blockchain ecosystem
-
next
- Update all code to use
@kadena/client
,@kadena/utils
and other packages
- Update all code to use
-
1.0.0 - Tagged May 26, 2025
- First tag (based on the work of April 26, 2022)
- First implementation of the repo to work with Kadena for exchanges
- Exchange uses a single-sig k-account based on a public-key (see (https://medium.com/kadena-io/introducing-kadena-account-protocols-kip-0012-303462b77af1) )
- It has enough funds to process the withdraws
tokenAddress
for kda token iscoin
- this can be replaced with the address of any other
fungible
token deployed on Kadena for examplefree.anedak
- this can be replaced with the address of any other
It is highly reccomended that any exchange run their own node. Instructions for doing so can be found here: (https://github.com/kadena-io/chainweb-node#configuring-running-and-monitoring-the-health-of-a-chainweb-node)
-
install
nodejs
-
follow the example to run
processWithdraw()
frommain.js
-
toggle testnet/mainnet and general network settings go to
var/network-config.js
/util
dirblockchain-write.js
are function calls that write new data to the blockchain using the/send
endpoint of achainweb-node
blockchain-read.js
are function calls that read data from the blockchain using the/local
endpoint of achainweb-node
- you can use
getAcctDetails()
to fetch the balance for any account, including your own
- you can use
/var
dirnetwork-config.js
has all the relevant network settings to talk to thechainweb-node
endpoints. Covers basic blockchain setup, such as specified metadata and target network- toggle here for app to talk to mainnet
keys.js
contains a public and private key with few TESTNET funds- toggle here for own keypair
- PLEASE KEEP SAFE
main.js
has a sample withdraw function implementation. If the sending account does not have enough funds on the target chain,balanceFunds()
from/util/blockchain-write.js
will be called to fund own account on the given chain.- Cross-chain transfers are always performed on own account to ensure user will always receive funds without having to pay for gas on the target chain
- This assumes you have enough money to cover the withdraw spread out on other chains
In chainweb each of the 20 chains function as independent blockchains with their
own state (though the chains run an identical protocol and behave the same way).
This allows for the possiblity of having multiple accounts with the same name
accross the 20 different chains. These multiple accounts of the same name may
each be potenitally controlled by a different set of keys. To make things
simpler, Kadena has introduced KIP-12
(https://medium.com/kadena-io/introducing-kadena-account-protocols-kip-0012-303462b77af1)
to allow a user to reserve an account-name controlled by a single public key
across all 20 chains. The account name must be of the form: "k:". As
an example, suppose the public key is:
70c67dabe9a54d1970461de00009f074e2ea22589dab553d159b6e1e93ae7e27
. Then the
account name should be named
k:70c67dabe9a54d1970461de00009f074e2ea22589dab553d159b6e1e93ae7e27
. No one
will be able to create an account named
k:70c67dabe9a54d1970461de00009f074e2ea22589dab553d159b6e1e93ae7e27
on any of
the chains without access to the private key corresponding to the public key:
70c67dabe9a54d1970461de00009f074e2ea22589dab553d159b6e1e93ae7e27
The above shows a legacy
account that DOES NOT use the k-standard. You can see that the account exists on
certain chains, but has not yet been created on others. In chainweb there is no
restriction preventing an account name that matches a public key, from being
owned and controlled by a different key. In the picture, this is the case of
chain 4 account, which is controlled by another party's (possibly a malicious
one) public key. This is exactly the scenario that the k-style accounts prevent.
var Pact = require('pact-lang-api');
//Pregenerate accounts that can be used later
//Save the generated keypairs somewhere
const keyPairs = [];
// Each of these accounts can be used with the correspondingly indexed keypair
const kAccounts = [];
//change from 100 to any number of keys you would like to create
for (let i = 0; i < 100; i++) {
const kp = Pact.crypto.genKeyPair();
kAccounts.push('k:' + kp.publicKey);
keyPairs.push(kp);
}
var { processWithdraw } = require('./main.js');
// Same example keys and account from var/keys.js
const EXCHANGE_PRIVKEY =
'd817273c1d2ef7e2ababf8cfe0579bc1ffd2c36845684a3ae4b3275e215b2080';
const EXCHANGE_PUBKEY =
'70c67dabe9a54d1970461de00009f074e2ea22589dab553d159b6e1e93ae7e27';
// Exchange account; MUST BE FUNDED on at least one of the chains
const EXCHANGE_KACCOUNT = 'k:' + EXCHANGE_PUBKEY;
// We only deposit to k-accounts
const customerAddress =
'k:9be19442151c880492ec0fddc5bdbe9eccd243b8d723f4673b317f10b2e5d515';
// Withdrawal for 10 KDA to account: 'k:9be19442151c880492ec0fddc5bdbe9eccd243b8d723f4673b317f10b2e5d515
// on chain 13 . Assumes a sufficient balance on EXCHANGE_ACCOUNT
processWithdraw(
'coin',
EXCHANGE_KACCOUNT,
EXCHANGE_PRIVKEY,
customerAddress,
10,
'13'
).then((res) => console.log(res));