Payment Processing

Last updated last month

Payment Processing

Zen Protocol is a multi-token blockchain, any contract can issue any number of tokens. Each token (called asset) is represented by the contract identifier and optional sub type (of 32 bytes).

Zen asset is an exception and represented by the one byte of value 0 (zero).

Each asset also have string representation, which is being used on UI and API. Zen token is represented by the string 00 (zero zero)

Unlike bitcoin, when sending a token we have to specify which token are we moving. Therefore the API always take an additional asset parameter on the wallet/send and wallet/execute API calls.

Hot wallet payment processing

Zen-Node expose an API for accepting payment.

For each payment generate a unique address and provide it to the end-user. Then periodically check the amount received for each address and save it. When the amount for address changed between calls you know the user made the payment. You can also specify the minimum confirmation.

All the tokens belong to the wallet and can be moved by the wallet/send API call.

You have first to create a wallet, either through the UI or through zen-cli. The private key is encrypted, however it is still on the hot zen-node machine, therefore the solution is a hot wallet one.

API Calls

  • POST wallet/send - Accept a list of asset,amount and destination address. Creating, sign and publish a transaction.

Get New Address
Generate a unique new address. Return both the address and the address index. Save the index as well in order to restore the wallet in the future.
200: OK
"address": "tzn1q7gye0nkgxuwal949y4ke94mwfwsf7eaafy7p5tkdcr6ujuyglqwsnjv2gt",
"index": 0

Received By Address
Return the amount received for each address and asset in the wallet. The amount can only grow, spending an input that belongs to one of the addresses does not decrease the amount received. Amount received is the amount the address received in it's entire lifetime.
200: OK
An array of addresses and the asset and amount in each address.
"address": "tzn1q7huplz5q5w7w9234a43hk4llyaegedq6dlfgm7mfp5w3em6s3uus4hwj7q",
"asset": "00",
"amount": 9497378334165913
"address": "tzn1q7huplz5q5w7w9234a43hk4llyaegedq6dlfgm7mfp5w3em6s3uus4hwj7q",
"asset": "000000006a26b38c2875d1379405bb7d140078ccffb560aff839a3d846850e99ab3d9de84265617200000000000000000000000000000000000000000000000000000000",
"amount": 199999994
"address": "tzn1qlvm8ey4m5mj6ak3an39qdfzf7yx4uz59flzlant6jp0gzld48egsj433m6",
"asset": "00",
"amount": 1855040761794

Account Discovery
Have a new node run an account discovery on a certain amount of addresses.
Path Parameters
Write the number of addresses you want the node to discover.
200: OK

Cold wallet payment processing

You can also use cold wallet for the payment processing.

You will have to use zen.js library for the process.

Generate an extended private key on a secure computer and import the extended public key.

import {Mnemonic, ExtendedKey} from '@zen/zenjs'
const mnemonic = Mnemonic.generateMnemonic(24); // Generate once
console.log('mnemonic phrase', mnemonic);
const publicKey = ExtendedKey.fromMnemonic(mnemonic).neutered();
console.log('Extended Public Key', publicKey.toString());

The on a hot machine generate a unique address by deriving the key with a unique index. Save the index to later sign the transaction on the secure computer.

import {ExtendedKey} from '@zen/zenjs'
import {post} from 'axios'
const publicKey = ExtendedKey.fromString(encodedString);
const address = publicKey.derive(uniqueIndex).toAddress();
// import the address to zen node
post('',address,{ headers: { 'Content-Type': 'application/json' }});

Share the address with the user and track the address for income payments the same as for the hot wallet, by calling wallet/receivedbyaddress

To make a payment you will to get the outputs from the zen-node and assemble the transaction on the secure computer. Retrieve the available outputs by calling wallet/addressoutputs for each address.

Example of assembling and publishing transaction:

import {TransactionBuilder,ExtendedKey} from '@zen/zenjs'
import {post} from 'axios'
const tb = new TransactionBuilder('main');
// Get the private key by matching the unique index for the input address
const privateKey = ExtendedKey.fromMnemonic(mnemonic).derive(inputAddressIndex).getPrivateKey();
// An example input, use one you retrieved by calling `wallet/addressoutputs`
tb.addInput('0000000000000000000000000000000000000000000000000000000000000000',0, privateKey);
// Address, amount and token (Zen)
tb.addOutput('tp1qfyplhxql09lvvg53dxg7t77tkkxhsp3l6q8xjjpj85hvqlw0ttqswjdapx', 100, '00');
const tx = tb.sign();
// You can take the hex to an hot computer
const hex = tx.toHex();
// Transaction is ready to be published
post('',hex,{ headers: { 'Content-Type': 'application/json' }});