This package aims to provide with an easy-to-use JS helping developers to communicate with the Minter blockchain through its API.
This package should be an aid to any developer working on JS applications with the Minter blockchain.
Please note that this SDK is under active development and is subject to change.
NOTE: since 0.34.0 SDK supports only v2 versions of node and gate APIs
It is complemented by the following packages:
- minterjs-wallet take care of BIP39 mnemonic phrase, private key, and address
- minterjs-util utility functions
Contents:
- Install
- Usage
- SDK API instance
- Tx params constructors
- Send
- Multisend
- Buy
- Sell
- Sell all
- Buy from pool
- Sell to pool
- Sell all to pool
- Create pool
- Add liquidity to pool
- Remove liquidity from pool
- Create coin
- Recreate coin
- Create token
- Recreate token
- Edit coin owner
- Mint token
- Burn token
- Declare candidacy
- Edit candidate
- Edit candidate public key
- Edit candidate commission
- Delegate
- Unbond
- Move stake
- Set candidate on
- Set candidate off
- Set halt block
- Vote for commission price
- Vote for network update
- Redeem check
- Create multisig
- Edit multisig
- Transaction
- Minter check
- Minter link
- Minter wallet
- License
npm install minter-js-sdk
import {Minter, prepareLink} from "minter-js-sdk";
const minter = new Minter({/* ...options, see Usage */});
const link = prepareLink(/* ... */)
or from browser
<script src="https://unpkg.com/minter-js-sdk"></script>
<script>
const minter = new minterSDK.Minter({/* ...options, see Usage */});
const link = minterSDK.prepareLink(/* ... */)
</script>
Post transaction full example
import {Minter, TX_TYPE} from "minter-js-sdk";
const minter = new Minter({apiType: 'node', baseURL: 'https://node-api.testnet.minter.network/v2/'});
const txParams = {
nonce: 1,
chainId: 1,
type: TX_TYPE.SEND,
data: {
to: 'Mx7633980c000139dd3bd24a3f54e06474fa941e16',
value: 10,
coin: 0, // coin id
},
gasCoin: 0, // coin id
gasPrice: 1,
payload: 'custom message',
};
minter.postTx(txParams, {seedPhrase: 'exercise fantasy smooth enough ...'})
.then((txHash) => {
// WARNING
// If you use minter-node api, successful response mean that Tx just get in mempool and it is not in blockchain yet.
// You have to wait it in the upcoming block.
// Also you can use gate api instead, it will return succes response only after Tx will be appeared in the blockchain
// WARNING #2
// If Tx was included in the block, it still may has failed status.
// Check tx.code to be `0`, to ensure it is successful
alert(`Tx created: ${txHash}`);
}).catch((error) => {
const errorMessage = error.response.data.error.message
alert(errorMessage);
});
Post transaction using SDK features
import {Minter, TX_TYPE} from "minter-js-sdk";
const minter = new Minter({apiType: 'node', baseURL: 'https://node-api.testnet.minter.network/v2/'});
const txParams = {
// no `nonce` specified, it will be fetched automatically
// no `gasPrice` specified, "1" will be used by default and in case of error request will be retried with autocorrected value
chainId: 1,
type: TX_TYPE.SEND,
data: {
to: 'Mx7633980c000139dd3bd24a3f54e06474fa941e16',
value: 10,
coin: 'BIP', // coin symbol
},
gasCoin: 'MYCOIN', // coin symbol
};
// coin symbols in txParams will be replaced automatically with coin ids
minter.postTx(newTxParams, {
// seedPhrase can be used to sign transaction instead of privateKey
seedPhrase: 'air model item valley auction bullet crisp always erosion paper orient fog',
})
.then((txHash) => {
// WARNINGs for minter-node api users
// #1
// Successful response mean that Tx just get in mempool and it is not in blockchain yet.
// You have to wait it in the upcoming block.
// #2
// If tx was included in the block, it still may has failed status.
// Check tx.code to be `0`, to ensure it is successful
// Gate api users not affected:
// Gate will return succes response only after tx will be appeared in the blockchain
// Also gate returns tx data in the response, so SDK will check tx.code automatically and reject promise for non-zero codes
alert(`Tx created: ${txHash}`);
}).catch((error) => {
const errorMessage = error.response.data.error.message
alert(errorMessage);
});
Create minter
SDK instance from Minter
constructor. It contains methods to communicate with API.
Minter
accept axios config as params and return axios instance
One extra field of options object is apiType
, which is one of 'gate'
or 'node'
. It is used to determine what type of API to use.
// specify gate url
const minterGate = new Minter({chainId: 2, apiType: 'gate', baseURL: 'https://gate-api.minter.network/api/v2/'});
// specify node url
const minterNode = new Minter({chainId: 2, apiType: 'node', baseURL: 'https://node-api.testnet.minter.network/v2/'});
Minter
constructor has the following options:
apiType
:'gate'
or'node'
baseURL
: API URLchainId
: default chain ID, used if no chainId specified in the tx params, 1 - mainnet, 2 - testnet
minter
SDK instance has the following methods:
- postTx
- postSignedTx
- getNonce
- ensureNonce
- getMinGasPrice
- getCoinInfo
- getCoinId
- replaceCoinSymbol
- replaceCoinSymbolByPath
- estimateCoinBuy
- estimateCoinSell
- estimateCoinSellAll
- estimateTxCommission
Post new transaction to the blockchain.
Accept tx params object and make asynchronous request to the blockchain API.
txParams.nonce
- optional, if no nonce given, it will be requested bygetNonce
automatically.txParams.gasPrice
- 1 by default, fee multiplier, should be equal or greater than current mempool's min gas price.gasRetryLimit
- count of repeating request, 2 by default. If first request fails because of low gas, it will be repeated with updatedgasPrice
mempoolRetryLimit
- count of repeating request, 0 by default. If first request fails because of error "Tx from address already exists in mempool", it will be repeated after 5 seconds (average time of the block) to try put it in the new block
Returns promise that resolves with:
- sent transaction data included in a block (from gate),
- or transaction hash included in mempool (from node).
Please note: always check that sent transaction has no errors (tx in a block should have code: 0
). Otherwise errored tx will not be applied
/**
* @typedef {Object} TxParams
* @property {number} [nonce] - can be omitted, will be received by `getNonce`
* @property {number} [chainId=1] - 1 = mainnet, 2 = testnet
* @property {number} [gasPrice=1] - can be updated automatically on retry, if gasRetryLimit > 1
* @property {string} [gasCoin='BIP']
* @property {string|TX_TYPE|Buffer} type
* @property {Object|Buffer|TxData} data
* @property {string} [payload]
* @property {number} [signatureType=1]
* @property {number} [signatureData] - can be signed automatically if `privateKey` or `seedPhrase` passed
*/
/**
* @param {TxParams} txParams
* @param {PostTxOptions} txOptions
* @param {number} [txOptions.gasRetryLimit=2] - number of retries, if request was failed because of low gas
* @param {number} [txOptions.nonceRetryLimit=0] - number of retries, if request was failed because of invalid nonce
* @param {number} [txOptions.mempoolRetryLimit=0] - number of retries, if request was failed with error "Tx from address already exists in mempool"
* @param {string|Buffer} [txOptions.seedPhrase] - alternative to txOptions.privateKey
* @param {string|Buffer} [txOptions.privateKey] - to sign tx or get nonce or to make proof for redeemCheck tx
* @param {string} [txOptions.address] - to get nonce (useful for multisignatures) or to make proof for redeemCheck tx
* @param {ByteArray} [txOptions.password] - to make proof for RedeemCheckTxData
* @param {AxiosRequestConfig} [axiosOptions]
* @return {Promise<NodeTransaction|{hash: string}>}
*/
minter.postTx(txParams, {seedPhrase: '...', gasRetryLimit: 2, mempoolRetryLimit: 0})
.then((tx) => {
console.log(tx.hash);
// 'Mt...'
// Check here that tx in block has no errors (code === 0)
});
Post new transaction to the blockchain.
Accept signed tx string or Buffer and make asynchronous request to the blockchain API.
Returns promise that resolves with:
- sent transaction data included in a block (from gate),
- or transaction hash included in mempool (from node).
/**
* @param {string|Buffer} signedTx
* @param {AxiosRequestConfig} [axiosOptions]
* @return {Promise<NodeTransaction|{hash: string}>}
*/
minter.postSignedTx('0xf8920102018a4d4e540000000000000001aae98a4d4e5400000000...')
.then((tx) => {
console.log(tx.hash);
// 'Mt...'
});
Get nonce for the new transaction from given address.
Accept address string and make asynchronous request to the blockchain API.
Returns promise that resolves with nonce for new tx (current address tx count + 1).
minter.getNonce('Mx...')
.then((nonce) => {
console.log(nonce);
// 123
});
Ensure nonce for the tx params. Address for which to get nonce should be provided, instead of address can be accepted seedPhrase
or privateKey
from which address will be derived.
/**
* @param {MinterApiInstance} apiInstance
* @param {TxParams} txParams
* @param {Object} txOptions
* @param {string} [txOptions.seedPhrase]
* @param {ByteArray} [txOptions.privateKey]
* @param {string} [txOptions.address]
* @param {AxiosRequestConfig} [axiosOptions]
* @return {Promise<number>}
*/
minter.ensureNonce(txParams, {seedPhrase: '...'})
.then((nonce) => {
console.log(nonce);
// 123
});
Get current minimal gas price.
minter.getMinGasPrice()
.then((gasPrice) => {
console.log(gasPrice);
// 1
});
Get coin info by coin ID or symbol.
/**
* @param {string|number} coin - coind ID or symbol
* @param {AxiosRequestConfig} [axiosOptions]
* @return {Promise<CoinInfo>}
*/
minter.getCoinInfo(coin)
.then((coinInfo) => {
console.log(coinInfo.id, coinInfo.symbol);
});
Get coin ID by coin symbol or array of symbols. Uses getCoinInfo()
under the hood.
/**
* @param {string|Array<string>} symbol - coin symbol or array of symbols
* @param {number} [chainId]
* @param {AxiosRequestConfig} [axiosOptions]
* @return {Promise<number|Array<number>>}
*/
minter.getCoinId('MNT')
.then((symbol) => {
console.log(symbol);
// 0
});
minter.getCoinId(['MNT', 'LASHIN'])
.then((symbols) => {
console.log(symbols);
// [0, 123]
});
Replace coin symbols with coin ids in txParams object.
/**
* @param {TxParams} txParams
* @param {AxiosRequestConfig} [axiosOptions]
* @return {Promise<TxParams>}
*/
const txParams = {
type: 1,
data: {
to: 'Mx7633980c000139dd3bd24a3f54e06474fa941e16',
value: 10,
coin: 'BIP',
},
gasCoin: 'MYCOIN',
};
minter.replaceCoinSymbol(txParams)
.then((newTxParams) => {
console.log(newTxParams);
// {
// type: 1,
// data: {
// to: 'Mx7633980c000139dd3bd24a3f54e06474fa941e16',
// value: 10,
// coin: 0,
// },
// gasCoin: 1234,
// }
});
Replace coin symbols with coin ids in arbitrary object by path list.
const params = {
foo: {
bar: {
coin: 'BIP',
},
},
gasCoin: 'MYCOIN',
};
/**
* @param {Object} params
* @param {Array<string>} pathList
* @param {number} [chainId]
* @param {AxiosRequestConfig} [axiosOptions]
* @return {Promise<TxParams>}
*/
minter.replaceCoinSymbolByPath(params, ['gasCoin', 'foo.bar.coin'])
.then((newParams) => {
console.log(newParams);
// {
// foo: {
// bar: {
// coin: 0,
// },
// },
// gasCoin: 1234,
// }
});
Estimate how much coins you will pay for buying some other coins.
/**
* @param {Object} params
* @param {string|number} params.coinToBuy - ID or symbol of the coin to buy
* @param {string|number} params.valueToBuy
* @param {string|number} params.coinToSell - ID or symbol of the coin to sell
* @param {ESTIMATE_SWAP_TYPE} [params.swapFrom] - estimate from pool, bancor or optimal
* @param {Array<number>} [params.route] - intermediate coins IDs for pool swaps
* @param {string|number} [params.gasCoin]
* @param {string|number} [params.coinCommission] - gasCoin alias
* @param {AxiosRequestConfig} [axiosOptions]
* @return {Promise<EstimateBuyResult>}
*/
/**
* @typedef {Object} EstimateBuyResult
* @property {number|string} will_pay - amount of coinToSell
* @property {number|string} commission - amount of coinToSell to pay fee
* @property {"pool"|"bancor"} swap_from
*/
minter.estimateCoinBuy({
coinToBuy: 'MYCOIN',
valueToBuy: 10,
coinToSell: 'BIP',
})
.then((result) => {
console.log(result.will_pay, result.commission, result.swap_from);
// 123, 0.1, 'pool'
});
Estimate how much coins you will get for selling some other coins.
/**
* @param {Object} params
* @param {string|number} params.coinToSell - ID or symbol of the coin to sell
* @param {string|number} params.valueToSell
* @param {string|number} params.coinToBuy - ID or symbol of the coin to buy
* @param {ESTIMATE_SWAP_TYPE} [params.swapFrom] - estimate pool swap
* @param {Array<string|number>} [params.route] - intermediate coins IDs for pool swaps
* @param {string|number} [params.gasCoin]
* @param {string|number} [params.coinCommission] - gasCoin alias
* @param {AxiosRequestConfig} [axiosOptions]
* @return {Promise<EstimateSellResult>}
*/
/**
* @typedef {Object} EstimateSellResult
* @property {number|string} will_get - amount of coinToBuy
* @property {number|string} commission - amount of coinToSell to pay fee
* @property {"pool"|"bancor"} swap_from
*/
minter.estimateCoinSell({
coinToSell: 'BIP',
valueToSell: 10,
coinToBuy: 'MYCOIN',
})
.then((result) => {
console.log(result.will_get, result.commission, result.swap_from);
// 123, 0.1, 'pool'
});
Estimate how much coins you will get for selling other coins by SellAll transaction.
/**
* @param {Object} params
* @param {string|number} params.coinToSell - ID or symbol of the coin to sell
* @param {string|number} params.valueToSell
* @param {string|number} params.coinToBuy - ID or symbol of the coin to buy
* @param {ESTIMATE_SWAP_TYPE} [params.swapFrom] - estimate pool swap
* @param {Array<string|number>} [params.route] - intermediate coins IDs for pool swaps
* @param {AxiosRequestConfig} [axiosOptions]
* @return {Promise<EstimateSellAllResult>}
*/
/**
* @typedef {Object} EstimateSellAllResult
* @property {number|string} will_get - amount of coinToBuy
* @property {"pool"|"bancor"} swap_from
*/
minter.estimateCoinSellAll({
coinToSell: 'BIP',
valueToSell: 10,
coinToBuy: 'MYCOIN',
})
.then((result) => {
console.log(result.will_get, result.swap_from);
// 123, 'pool'
});
Estimate transaction fee. This method can operate in two modes:
-
direct: true
make one direct request to theestimate_tx_commission/{tx}
API.
Pros: fewer requests, more accuracy. Cons: provide less data (onlycommission
field)
-
direct: false
makes several requests for blockchain data and calculates fee relying on this data. Pros: return more data (commission
,baseCoinCommission
,priceCoinCommission
,commissionPriceData
), some request can be cached so calculating fee when users types payload can be done dynamically without extra request for each payload character. Cons: make more request for single estimate, can be less accurate in some edge cases and when caching is used.
First argument txParams
can be a TxParams
object or raw signed tx hex string.
Second options argument accepts direct
field, true
by default .
Resolves with object containing commission.
See also Minter commissions docs
/**
* @param {TxParams|string} txParams
* @param {Object} [options]
* @param {boolean} [options.direct]
* @param {AxiosRequestConfig} [axiosOptions]
* @return {Promise<{commission: (number|string), baseCoinCommission: (number|string), priceCoinCommission: (number|string), commissionPriceData: CommissionPriceData}>|Promise<{commission: (number|string)}>}
*/
// direct with raw tx string
minter.estimateTxCommission('0xf8920101028a4d4e540000000000000001aae98a4d4e...')
.then((feeData) => {
console.log(feeData);
// { commission: 0.1 }
});
// direct with tx params
minter.estimateTxCommission({
type: TX_TYPE.SEND,
data: {to: 'Mx...', value: 10, coin: 'BIP'},
gasCoin: 'BIP',
})
.then((feeData) => {
console.log(feeData);
// { commission: 0.1 }
});
minter.estimateTxCommission(
{
type: TX_TYPE.SEND,
data: {to: 'Mx...', value: 10, coin: 'BIP'},
gasCoin: 'BIP',
}, {direct: false,}
)
.then((feeData) => {
console.log(feeData);
// { commission: 0.1, baseCoinCommission: 0.1, priceCoinCommission: 0.1, commissionPriceData: {coin: {id: 0, symbol: 'BIP'}, /*...*/} }
});
Tx params object to pass it to postTx
or prepareSignedTx
methods to post transaction to the blockchain.
nonce - unique number for each address, used to prevent transaction reply, starts from 1 chainId - id of the network (1 - mainnet, 2 - testnet) gasPrice - fee multiplier, should be equal or greater than current mempool min gas price. gasCoin - coin to pay fee type - type of transaction (see below) data - data of transaction (depends on transaction type) payload (arbitrary bytes) - arbitrary user-defined bytes serviceData - reserved field signatureType - 1 - single signed, 2 - multi signed signatureData - digital signature of transaction
/**
* @typedef {Object} TxParams
* @property {number} [nonce]
* @property {number} [chainId=1]
* @property {number} [gasPrice=1]
* @property {number|string} [gasCoin='0']
* @property {string|Buffer|TX_TYPE} type
* @property {Buffer|TxData|Object} data
* @property {string} [payload]
* @property {number} [signatureType]
* @property {ByteArray|{multisig: ByteArray, signatures: Array<ByteArray>}} [signatureData]
*/
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.SEND,
data: {
to: 'Mx376615B9A3187747dC7c32e51723515Ee62e37Dc',
value: 10,
coin: 0, // coin id
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.MULTISEND,
data: {
list: [
{
value: 10,
coin: 0, // coin id
to: 'Mx7633980c000139dd3bd24a3f54e06474fa941e16',
},
{
value: 2,
coin: 0, // coin id
to: 'Mxfe60014a6e9ac91618f5d1cab3fd58cded61ee99',
}
],
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = new {
type: TX_TYPE.BUY,
data: {
coinToSell: 0, // coin id
coinToBuy: 123, // coin id
valueToBuy: 10,
maximumValueToSell: 1234 // optional, by default 10^15
},
};
minter.postTx(txParams, {seedPhrase: '...'});
const txParams = {
type: TX_TYPE.SELL,
data: {
coinToSell: 0,
coinToBuy: 123,
valueToSell: 10,
minimumValueToBuy: 0, // optional, by default 0
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
// `gasCoin` will be set as `coinToSell` automatically
type: TX_TYPE.SELL_ALL,
data: {
coinToSell: 0, // coin id
coinToBuy: 123, // coin id
minimumValueToBuy: 0, // optional, by default 0
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = new {
type: TX_TYPE.BUY,
data: {
coins: [0, 123, 15], // route of coin IDs from spent to received
valueToBuy: 10,
maximumValueToSell: 1234 // optional, by default 10^15
},
};
minter.postTx(txParams, {seedPhrase: '...'});
const txParams = {
type: TX_TYPE.SELL_SWAP_POOL,
data: {
coins: [0, 123, 15], // route of coin IDs from spent to received
valueToSell: 10,
minimumValueToBuy: 0, // optional, by default 0
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
// `gasCoin` will be set as coin to spend (`coins[0]`) automatically
type: TX_TYPE.SELL_ALL_SWAP_POOL,
data: {
coins: [0, 123, 15], // route of coin IDs from spent to received
minimumValueToBuy: 0, // optional, by default 0
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = new {
type: TX_TYPE.CREATE_SWAP_POOL,
data: {
coin0: 12,
coin1: 34,
volume0: 123,
volume1: 456,
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = new {
type: TX_TYPE.ADD_LIQUIDITY,
data: {
coin0: 12,
coin1: 34,
volume0: 123,
maximumVolume1: 456,
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = new {
type: TX_TYPE.REMOVE_LIQUIDITY,
data: {
coin0: 12,
coin1: 34,
liquidity: 123,
minimumVolume0: 0,
minimumVolume1: 0,
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.CREATE_COIN,
data: {
name: 'My Coin',
symbol: 'MYCOIN',
initialAmount: 5,
constantReserveRatio: 10,
initialReserve: 20,
maxSupply: 10000, // optional, by default 10**15
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.RECREATE_COIN,
data: {
name: 'My Coin',
symbol: 'MYCOIN',
initialAmount: 5,
constantReserveRatio: 10,
initialReserve: 20,
maxSupply: 10000, // optional, by default 10**15
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.CREATE_TOKEN,
data: {
name: 'My Coin',
symbol: 'MYCOIN',
initialAmount: 5,
maxSupply: 10000, // optional, by default 10**15
mintable: true,
burnable: true,
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.RECREATE_TOKEN,
data: {
name: 'My Coin',
symbol: 'MYCOIN',
initialAmount: 5,
maxSupply: 10000, // optional, by default 10**15
mintable: true,
burnable: true,
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.EDIT_TICKER_OWNER,
data: {
symbol: 'MYCOIN',
newOwner: 'Mx7633980c000139dd3bd24a3f54e06474fa941e16',
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.MINT_TOKEN,
data: {
coin: 1, // coin id
value: 123,
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.BURN_TOKEN,
data: {
coin: 1, // coin id
value: 123,
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.DECLARE_CANDIDACY,
data: {
address: 'Mx7633980c000139dd3bd24a3f54e06474fa941e16',
publicKey: 'Mpf9e036839a29f7fba2d5394bd489eda927ccb95acc99e506e688e4888082b3a3',
commission: 10, // percentage
coin: 0, // coin id
stake: 100, // amount
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.EDIT_CANDIDATE,
data: {
publicKey: 'Mpf9e036839a29f7fba2d5394bd489eda927ccb95acc99e506e688e4888082b3a3',
rewardAddress: 'Mx7633980c000139dd3bd24a3f54e06474fa941e16',
ownerAddress: 'Mx7633980c000139dd3bd24a3f54e06474fa941e16',
controlAddress: 'Mx7633980c000139dd3bd24a3f54e06474fa941e16',
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.EDIT_CANDIDATE_PUBLIC_KEY,
data: {
publicKey: 'Mpf9e036839a29f7fba2d5394bd489eda927ccb95acc99e506e688e4888082b3a3',
newPublicKey: 'Mpf9e036839a29f7fba2d5394bd489eda927ccb95acc99e506e688e4888082b3a3',
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.EDIT_CANDIDATE_COMMISSION,
data: {
publicKey: 'Mpf9e036839a29f7fba2d5394bd489eda927ccb95acc99e506e688e4888082b3a3',
commission: 10, // percentage
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.DELEGATE,
data: {
publicKey: 'Mpf9e036839a29f7fba2d5394bd489eda927ccb95acc99e506e688e4888082b3a3',
coin: 0, // coin id
stake: 100,
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.UNBOND,
data: {
publicKey: 'Mpf9e036839a29f7fba2d5394bd489eda927ccb95acc99e506e688e4888082b3a3',
coin: 0, // coin id
stake: 100,
},
};
minter.postTx(txParams, {seedPhrase: '...'});
Disabled for now Tx docs
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.MOVE_STAKE,
data: {
from: 'Mpf9e036839a29f7fba2d5394bd489eda927ccb95acc99e506e688e4888082b3a3',
to: 'Mpf9e036839a29f7fba2d5394bd489eda927ccb95acc99e506e688e4888082b3a4',
coin: 0, // coin id
stake: 100,
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.SET_CANDIDATE_ON,
data: {
publicKey: 'Mpf9e036839a29f7fba2d5394bd489eda927ccb95acc99e506e688e4888082b3a3',
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.SET_CANDIDATE_OFF,
data: {
publicKey: 'Mpf9e036839a29f7fba2d5394bd489eda927ccb95acc99e506e688e4888082b3a3',
},
};
minter.postTx(txParams, {seedPhrase: '...'});
Tx docs Vote for halt block
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.SET_HALT_BLOCK,
data: {
publicKey: 'Mpf9e036839a29f7fba2d5394bd489eda927ccb95acc99e506e688e4888082b3a3',
height: 1234,
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.VOTE_COMMISSION,
data: {
publicKey: 'Mpf9e036839a29f7fba2d5394bd489eda927ccb95acc99e506e688e4888082b3a3',
height: 1234,
coin: 0, // coin id
payloadByte: '12',
send: '12',
buyBancor: '12',
sellBancor: '12',
sellAllBancor: '12',
buyPoolBase: '12',
sellPoolBase: '12',
sellAllPoolBase: '12',
buyPoolDelta: '12',
sellPoolDelta: '12',
sellAllPoolDelta: '12',
createTicker3: '12',
createTicker4: '12',
createTicker5: '12',
createTicker6: '12',
createTicker7to10: '12',
createCoin: '12',
createToken: '12',
recreateCoin: '12',
recreateToken: '12',
declareCandidacy: '12',
delegate: '12',
unbond: '12',
redeemCheck: '12',
setCandidateOn: '12',
setCandidateOff: '12',
createMultisig: '12',
multisendBase: '12',
multisendDelta: '12',
editCandidate: '12',
setHaltBlock: '12',
editTickerOwner: '12',
editMultisig: '12',
editCandidatePublicKey: '12',
addLiquidity: '12',
removeLiquidity: '12',
editCandidateCommission: '12',
burnToken: '12',
mintToken: '12',
voteCommission: '12',
voteUpdate: '12',
createSwapPool: '12',
},
};
minter.postTx(txParams, {seedPhrase: '...'});
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.VOTE_UPDATE,
data: {
version: 'v2.1',
publicKey: 'Mpf9e036839a29f7fba2d5394bd489eda927ccb95acc99e506e688e4888082b3a3',
height: 1234,
},
};
minter.postTx(txParams, {seedPhrase: '...'});
Disabled Tx docs
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.PRICE_VOTE,
data: {
price: 1234,
},
};
minter.postTx(txParams, {seedPhrase: '...'});
Checks docs
Tx docs
See also how to issue check
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.REDEEM_CHECK,
data: {
check: 'Mcf8ab3101830f423f8a4d4e5400000000000000888ac7230489e800008a4d4e5400000000000000b841f69950a210196529f47df938f7af84958cdb336daf304616c37ef8bebca324910910f046e2ff999a7f2ab564bd690c1102ab65a20e0f27b57a93854339b60837011ba00a07cbf311148a6b62c1d1b34a5e0c2b6931a0547ede8b9dfb37aedff4480622a023ac93f7173ca41499624f06dfdd58c4e65d1279ea526777c194ddb623d57027',
},
};
// password and seedPhrase will be used to generate check's proof
minter.postTx(txParams, {seedPhrase: '...', password: 'pass'});
// also combination of password and address can be used to generate proof
minter.postTx(txParams, {seedPhrase: '...', address: '...', password: 'pass'});
Addresses count must not be greater than 32.
Weights count must be equal to addresses count.
Weights must be between 0-1023.
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.CREATE_MULTISIG,
data: {
addresses: ['Mx7633980c000139dd3bd24a3f54e06474fa941e00', 'Mxfe60014a6e9ac91618f5d1cab3fd58cded61ee99'],
weights: [40, 80],
threshold: 100,
},
};
minter.postTx(txParams, {seedPhrase: '...'});
Tx docs Send it from the multisig address
import {TX_TYPE} from "minter-js-sdk";
const txParams = {
type: TX_TYPE.EDIT_MULTISIG,
data: {
addresses: ['Mx7633980c000139dd3bd24a3f54e06474fa941e00', 'Mxfe60014a6e9ac91618f5d1cab3fd58cded61ee99'],
weights: [40, 80],
threshold: 100,
},
};
minter.postTx(txParams, {seedPhrase: '...'});
Prepare Tx
object from txParams, used under the hood of PostTx, accepts arguments:
txParams
object,options.seedPhrase
- optional, can be passed to txData constructor for redeem check transaction and can be used to sign transaction with single signature.options.privateKey
- optional, can be used instead ofseedPhrase
directly
import {prepareTx} from 'minter-js-sdk';
const tx = prepareTx(txParams, {seedPhrase: '...'});
console.log('signed tx', tx.serialize().toString('hex'));
// get actual nonce first
minter.getNonce('Mx...')
.then((nonce) => {
const tx = prepareTx({...txParams, nonce}, {seedPhrase: '...'});
console.log('signed tx', tx.serialize().toString('hex'));
});
prepareSignedTx
is an alias for prepareTx
but with signatureType: 1
. So it doesn't support multisignatures.
import {prepareSignedTx, prepareTx} from 'minter-js-sdk';
let tx = prepareSignedTx(txParams, {seedPhrase: '...'});
// is the same as
tx = prepareTx({...txParams, signatureType: 1}, {seedPhrase: '...'})
Make signature buffer for Tx
with privateKey
. Useful to create signatures for transactions with multiple signatures.
import {makeSignature} from 'minter-js-sdk';
makeSignature(tx, privateKey);
Usually you should collect signatures from other multisig participants, which can make it with makeSignature
.
Then you should construct signatureData
for TxParams
object and pass such TxParams
to postTx
or prepareTx
import {Minter, TX_TYPE, prepareTx, makeSignature} from "minter-js-sdk";
const minter = new Minter({/* ... */});
const txParams = {
nonce: 1,
chainId: 1,
type: TX_TYPE.SEND,
data: {
to: 'Mx7633980c000139dd3bd24a3f54e06474fa941e16',
value: 10,
coin: 0, // coin id
},
gasCoin: 0, // coin id
gasPrice: 1,
payload: 'custom message',
signatureType: 2, // multiple signature type
};
const tx = prepareTx(txParams);
const signature1 = makeSignature(tx, privateKey1);
const signature2 = makeSignature(tx, privateKey2);
minter.postTx({
...txParams,
signatureData: {
multisig: multisigAddress,
signatures: [signature1, signature2],
},
})
Decode RLP serialized tx into params object
Params:
tx
- string, RLP decoded tx
options
- object with extra options
options.decodeCheck
- boolean, adds checkData
field next to check
field for redeemCheck tx data
import {decodeTx} from 'minter-js-sdk';
decodeTx('0xf87e818102018a42414e414e415445535402a3e28a42414e414e41544553548a067d59060c9f4d7282328a4d4e540000000000000080808001b845f8431ca01d568386460de1dd40a7c73084a84be68bbf4696aea0208530d3bae2ccf47e4ba059cb6cbfb12e56d7f5f4f8c367a76a867aff09afca15e8d61a7ef4cf7e0d26be');
// {
// nonce: '129',
// chainId: '2',
// gasPrice: '1',
// gasCoin: '0',
// type: '0x02',
// data: {
// coinToSell: '123',
// valueToSell: '30646.456735029139767858',
// coinToBuy: '0',
// minimumValueToBuy: '0',
// },
// payload: '',
// signatureType: '1',
// signatureData: '0xf8431ca01d568386460de1dd40a7c73084a84be68bbf4696aea0208530d3bae2ccf47e4ba059cb6cbfb12e56d7f5f4f8c367a76a867aff09afca15e8d61a7ef4cf7e0d26be',
// }
Minter Check is like an ordinary bank check. Each user of network can issue check with any amount of coins and pass it to another person. Receiver will be able to cash a check from arbitrary account.
Checks are issued offline and do not exist in blockchain before “cashing”.
Params:
seedPhrase
- seed phrase of the issuer to sign check. Type: stringprivateKey
- private key of the issuer to sign check. Type: string, Bufferpassword
- password to protect check. Type: stringnonce
- unique string to allow issue identical checks. Type: stringchainId
- network type to prevent using same check between networks. Type: number. Default:1
coin
- coin to transfer. Type: stringvalue
- amount to transfer. Type: numbergasCoin
- coin to pay fee, fee will be charged from issuer when RedeemCheck tx will be sent by check's recipient. Type: string. Default: network's base coin ('BIP'
or'MNT'
)dueBlock
- number of block, at this block check will be expired. Type: number. Default:999999999
// Since issuing checks is offline, you can use it standalone without instantiating SDK
import {issueCheck} from "minter-js-sdk";
const check = issueCheck({
seedPhrase: 'air model item valley ...',
password: 'pass',
nonce: '1',
chainId: 1,
coin: 0, // coin id
value: 10,
gasCoin: 0, // coin id
dueBlock: 999999,
});
console.log(check);
// => 'Mcf8ab3101830f423f8a4d4e5400000000000000888ac7230489e800008a4d4e5400000000000000b841f69950a210196529f47df938f7af84958cdb336daf304616c37ef8bebca324910910f046e2ff999a7f2ab564bd690c1102ab65a20e0f27b57a93854339b60837011ba00a07cbf311148a6b62c1d1b34a5e0c2b6931a0547ede8b9dfb37aedff4480622a023ac93f7173ca41499624f06dfdd58c4e65d1279ea526777c194ddb623d57027'
// This method also available on the SDK instance
const check = minter.issueCheck({...});
Decode raw check
import {decodeCheck} from "minter-js-sdk";
const check = decodeCheck('Mcf8ab3101830f423f8a4d4e5400000000000000888ac7230489e800008a4d4e5400000000000000b841f69950a210196529f47df938f7af84958cdb336daf304616c37ef8bebca324910910f046e2ff999a7f2ab564bd690c1102ab65a20e0f27b57a93854339b60837011ba00a07cbf311148a6b62c1d1b34a5e0c2b6931a0547ede8b9dfb37aedff4480622a023ac93f7173ca41499624f06dfdd58c4e65d1279ea526777c194ddb623d57027');
console.log(check);
// =>
// {
// nonce: '1',
// chainId: 1,
// coin: '0',
// value: '10',
// gasCoin: '0',
// dueBlock: 999999,
// }
// This method also available on the SDK instance
const check = minter.decodeCheck('...');
Minter Link Protocol describes how to represent transaction data into a simple link, which can be easily consumed by user as a link or as QR. Then link is being processed by bip.to web app or any associated mobile app. App retrieves data from the link, generate valid transaction using logged user's private key and send it.
So everything a user needs to do to send a transaction is to click on the link or scan QR code.
Create link from transaction params
Options:
txParams
- object with params of transactiontxParams.type
txParams.data
txParams.payload
- optionaltxParams.nonce
- optionaltxParams.gasPrice
- optionaltxParams.gasCoin
- optionallinkHost
- optional, custom hostname of the link, leave undefined to use default 'https://bip.to'
import {prepareLink, TX_TYPE} from 'minter-js-sdk';
const txParams = {
type: TX_TYPE.SEND,
data: {
to: 'Mx7633980c000139dd3bd24a3f54e06474fa941e16',
value: 10,
coin: 0, // coin id
},
gasCoin: 0, // coin id
payload: 'custom message',
};
prepareLink(txParams);
// => 'https://bip.to/tx/-EgBqumKTU5UAAAAAAAAAJR2M5gMAAE53TvSSj9U4GR0-pQeFoiKxyMEiegAAI5jdXN0b20gbWVzc2FnZYCAikFTRAAAAAAAAAA'
Decode link into transaction params
Params:
url
- string with link
options
- object with extra options
options.decodeCheck
- boolean, adds checkData
field next to check
field for redeemCheck tx data
options.privateKey
- links with password
and without proof
require privateKey to generate valid proof
options.seedPhrase
- alternative to options.privateKey
import {decodeLink} from 'minter-js-sdk';
decodeLink('https://bip.to/tx/-EgBqumKTU5UAAAAAAAAAJR2M5gMAAE53TvSSj9U4GR0-pQeFoiKxyMEiegAAI5jdXN0b20gbWVzc2FnZYCAikFTRAAAAAAAAAA');
// =>
// {
// gasCoin: 0,
// type: '0x01',
// data: {
// to: 'Mx7633980c000139dd3bd24a3f54e06474fa941e16',
// coin: '0',
// value: '10',
// },
// payload: 'custom message',
// }
const LINK_CHECK = 'https://bip.to/tx?d=f8f009b8e9f8e7b8a2f8a03101830f423f8a4d4e5400000000000000888ac7230489e80000b84149eba2361855724bbd3d20eb97a54ea15ad7dc28c1111b8dcf3bb15db26f874f095803cad9f8fc88b2b4eec9ba706325a7929be31b6ccfef01260791a844cb55011ba06c63ad17bfe07b82be8a0144fd4daf8b4144281fdf88f313205ceacf37fd877fa03c243ad79cab6205f4b753bd402c4cfa5d570888659090b2f923071ac52bdf75b8410497ea588f0fc2bd448de76d03a74cf371269e10ac1a02765fb5fa37c29f67e0348fb3faacd3370b8809401e7d562d8943f3642ce96667188d3c344e8e5bff6d0180808080';
decodeLink(LINK_CHECK, {decodeCheck: true})
// {
// type: '0x09',
// data: {
// proof: '0x0497ea588f0fc2bd448de76d03a74cf371269e10ac1a02765fb5fa37c29f67e0348fb3faacd3370b8809401e7d562d8943f3642ce96667188d3c344e8e5bff6d01',
// check: 'Mcf8a03101830f423f8a4d4e5400000000000000888ac7230489e80000b84149eba2361855724bbd3d20eb97a54ea15ad7dc28c1111b8dcf3bb15db26f874f095803cad9f8fc88b2b4eec9ba706325a7929be31b6ccfef01260791a844cb55011ba06c63ad17bfe07b82be8a0144fd4daf8b4144281fdf88f313205ceacf37fd877fa03c243ad79cab6205f4b753bd402c4cfa5d570888659090b2f923071ac52bdf75',
// checkData: {
// nonce: '1',
// chainId: '1',
// coin: '0',
// value: '10',
// dueBlock: '999999',
// },
// },
// payload: '',
// }
Get private key from seed phrase and address from private key
Use minterjs-wallet package
MIT License