Before we get started we need to make sure that all of the required dependencies are installed. These dependencies are the Crypto SDK and Client SDK. You can head on over to their documentations to read more about them but for now we are only concerned with installing them to get up and running.
yarn add @smartholdem/crypto
yarn add @smartholdem/client
pnpm add @smartholdem/crypto
pnpm add @smartholdem/client
npm install @smartholdem/crypto
npm install @smartholdem/client
Now that we’re setup and ready to go we’ll look into some examples for the most common tasks you’ll encounter when wanting to interact with the SmartHoldem Blockchain.
The process of getting your transaction verified and persisted on the SmartHoldem Blockchain involves a few steps with which our SDKs will help you but lets break them down to get a better idea of what is happening.
A common issue when trying to get your transaction onto the blockchain is that you’ll receive an error to the effect of Transaction Version 2 is not supported which indicates that your Crypto SDK configuration might be wrong.
The solution to this is to make sure that your Crypto SDK instance is properly configured. This includes both the network preset and the height it’s configured to assume the network has passed, if any of those don’t match up you’ll encounter the aforementioned issue with the version of your transactions.
Managers.configManager.setFromPreset("mainnet");
Managers.configManager.setHeight(1500000);
const { Transactions, Managers, Utils } = require("@smartholdem/crypto");
const { Connection } = require("@smartholdem/client");
// Configure our API client
const client = new Connection("https://node0.smartholdem.io/api");
Managers.configManager.setFromPreset("mainnet");
Managers.configManager.setHeight(1500000);
(async () => {
// Step 1: Retrieve the incremental nonce of the sender wallet
const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");
const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);
// Step 2: Create the transaction
const transaction = Transactions.BuilderFactory.transfer()
.version(2)
.nonce(senderNonce.toFixed())
.recipientId("Address of Recipient")
.amount(1 * 1e8)
.vendorField("Hello World")
.sign("this is a top secret passphrase");
// Step 4: Broadcast the transaction
const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });
// Step 5: Log the response
console.log(JSON.stringify(broadcastResponse.body.data, null, 4))
})();
The vendorField is optional and limited to a length of 255 characters. It can be a good idea to add a vendor field to your transactions if you want to be able to easily track them in the future.
const { Transactions, Managers, Utils } = require("@smartholdem/crypto");
const { Connection } = require("@smartholdem/client");
// Configure our API client
const client = new Connection("https://node0.smartholdem.io/api");
Managers.configManager.setFromPreset("mainnet");
Managers.configManager.setHeight(1500000);
(async () => {
// Step 1: Retrieve the incremental nonce of the sender wallet
const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");
const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);
// Step 2: Create the transaction
const transaction = Transactions.BuilderFactory.secondSignature()
.version(2)
.nonce(senderNonce.toFixed())
.signatureAsset("this is a top secret second passphrase")
.sign("this is a top secret passphrase");
// Step 4: Broadcast the transaction
const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });
// Step 5: Log the response
console.log(JSON.stringify(broadcastResponse.body.data, null, 4))
})();
const { Transactions, Managers, Utils } = require("@smartholdem/crypto");
const { Connection } = require("@smartholdem/client");
// Configure our API client
const client = new Connection("https://node0.smartholdem.io/api");
Managers.configManager.setFromPreset("mainnet");
Managers.configManager.setHeight(1500000);
(async () => {
// Step 1: Retrieve the incremental nonce of the sender wallet
const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");
const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);
// Step 2: Create the transaction
const transaction = Transactions.BuilderFactory.delegateRegistration()
.version(2)
.nonce(senderNonce.toFixed())
.usernameAsset("johndoe")
.sign("this is a top secret passphrase");
// Step 4: Broadcast the transaction
const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });
// Step 5: Log the response
console.log(JSON.stringify(broadcastResponse.body.data,
const { Transactions, Managers, Utils } = require("@smartholdem/crypto");
const { Connection } = require("@smartholdem/client");
// Configure our API client
const client = new Connection("https://node0.smartholdem.io/api");
Managers.configManager.setFromPreset("mainnet");
Managers.configManager.setHeight(1500000);
(async () => {
// Step 1: Retrieve the incremental nonce of the sender wallet
const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");
const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);
// Step 2: Create the transaction
const transaction = Transactions.BuilderFactory.vote()
.version(2)
.nonce(senderNonce.toFixed())
.votesAsset(["+public_key_of_a_delegate_wallet"])
.sign("this is a top secret passphrase");
// Step 4: Broadcast the transaction
const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });
// Step 5: Log the response
console.log(JSON.stringify(broadcastResponse.body.data, null, 4))
})();
Note the plus prefix for the public key that is passed to the votesAsset function. This prefix denotes that this is a transaction to remove a vote from the given delegate.
const { Transactions, Managers, Utils } = require("@smartholdem/crypto");
const { Connection } = require("@smartholdem/client");
// Configure our API client
const client = new Connection("https://node0.smartholdem.io/api");
Managers.configManager.setFromPreset("mainnet");
Managers.configManager.setHeight(1500000);
(async () => {
// Step 1: Retrieve the incremental nonce of the sender wallet
const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");
const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);
// Step 2: Create the transaction
const transaction = Transactions.BuilderFactory.vote()
.version(2)
.nonce(senderNonce.toFixed())
.votesAsset(["-public_key_of_a_delegate_wallet"])
.sign("this is a top secret passphrase");
// Step 4: Broadcast the transaction
const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });
// Step 5: Log the response
console.log(JSON.stringify(broadcastResponse.body.data, null, 4))
})();
Note the minus prefix for the public key that is passed to the votesAsset function. This prefix denotes that this is a transaction to add a vote to the given delegate.
const { Transactions, Managers, Utils } = require("@smartholdem/crypto");
const { Connection } = require("@smartholdem/client");
// Configure our API client
const client = new Connection("https://node0.smartholdem.io/api");
Managers.configManager.setFromPreset("mainnet");
Managers.configManager.setHeight(1500000);
(async () => {
// Step 1: Retrieve the incremental nonce of the sender wallet
const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");
const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);
// Step 2: Create the transaction
const transaction = Transactions.BuilderFactory.multiSignature()
.version(2)
.nonce(senderNonce.toFixed())
.multiSignatureAsset({
publicKeys: [
"035231cc2fccf7fba239b8abb2611def73f0c0a01598164909181eebd544ce114d",
"036560f20d578da7b8433248d0c82e68121163958d533dc74b0e7d8dbabc0606a0",
"02800fe25c005535be15f1a092aba211b69095f0a782224d71a541c14f3a186ef1",
],
min: 2,
})
.senderPublicKey("035231cc2fccf7fba239b8abb2611def73f0c0a01598164909181eebd544ce114d")
.multiSign("this is a top secret passphrase 1", 0)
.multiSign("this is a top secret passphrase 2", 1)
.multiSign("this is a top secret passphrase 3", 2)
.sign("this is a top secret passphrase");
// Step 4: Broadcast the transaction
const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });
// Step 5: Log the response
console.log(JSON.stringify(broadcastResponse.body.data, null, 4))
})();
const { Transactions, Managers, Utils } = require("@smartholdem/crypto");
const { Connection } = require("@smartholdem/client");
// Configure our API client
const client = new Connection("https://node0.smartholdem.io/api");
Managers.configManager.setFromPreset("mainnet");
Managers.configManager.setHeight(1500000);
(async () => {
// Step 1: Retrieve the incremental nonce of the sender wallet
const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");
const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);
// Step 2: Create the transaction
const transaction = Transactions.BuilderFactory.ipfs()
.version(2)
.nonce(senderNonce.toFixed())
.ipfsAsset("QmVUvLMxTEaVBpiQBiBBdnv7ZTwt7pv8BxNhpPCMixuRBT")
.sign("this is a top secret passphrase");
// Step 4: Broadcast the transaction
const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });
// Step 5: Log the response
console.log(JSON.stringify(broadcastResponse.body.data, null, 4))
})();
const { Transactions, Managers, Utils } = require("@smartholdem/crypto");
const { Connection } = require("@smartholdem/client");
// Configure our API client
const client = new Connection("https://node0.smartholdem.io/api");
Managers.configManager.setFromPreset("mainnet");
Managers.configManager.setHeight(1500000);
(async () => {
// Step 1: Retrieve the incremental nonce of the sender wallet
const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");
const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);
// Step 2: Create the transaction
const transaction = Transactions.BuilderFactory.multiPayment()
.version(2)
.nonce(senderNonce.toFixed())
.addPayment("Address of Recipient Wallet 1", 1 * 1e8)
.addPayment("Address of Recipient Wallet 2", 1 * 1e8)
.addPayment("Address of Recipient Wallet 3", 1 * 1e8)
.sign("this is a top secret passphrase");
// Step 4: Broadcast the transaction
const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });
// Step 5: Log the response
console.log(JSON.stringify(broadcastResponse.body.data, null, 4))
})();
const { Transactions, Managers, Utils } = require("@smartholdem/crypto");
const { Connection } = require("@smartholdem/client");
// Configure our API client
const client = new Connection("https://node0.smartholdem.io/api");
Managers.configManager.setFromPreset("mainnet");
Managers.configManager.setHeight(1500000);
(async () => {
// Step 1: Retrieve the incremental nonce of the sender wallet
const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");
const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);
// Step 2: Create the transaction
const transaction = Transactions.BuilderFactory.delegateResignation()
.version(2)
.nonce(senderNonce.toFixed())
.sign("this is a top secret passphrase");
// Step 4: Broadcast the transaction
const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });
// Step 5: Log the response
console.log(JSON.stringify(broadcastResponse.body.data, null, 4))
})();
A delegate resignation has to be sent from the delegate wallet itself to verify its identity.
const { Transactions, Managers, Utils } = require("@smartholdem/crypto");
const { Connection } = require("@smartholdem/client");
const client = new Connection("https://node0.smartholdem.io/api");
Managers.configManager.setFromPreset("mainnet");
Managers.configManager.setHeight(1500000);
(async () => {
// Step 1: Retrieve the incremental nonce of the sender wallet
const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");
const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);
// Step 2: Create the transaction
const transaction = Transactions.BuilderFactory.htlcLock()
.version(2)
.nonce(senderNonce.toFixed())
.htlcLockAsset({
secretHash: "035231cc2fccf7fba239b8abb2611def73f0c0a01598164909181eebd544ce114d",
expiration: {
type: 1,
value: Math.floor(Date.now() / 1000),
},
})
.amount(1 * 1e8)
.sign("this is a top secret passphrase");
// Step 4: Broadcast the transaction
const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });
// Step 5: Log the response
console.log(JSON.stringify(broadcastResponse.body.data, null, 4))
})();
const { Transactions, Managers, Utils } = require("@smartholdem/crypto");
const { Connection } = require("@smartholdem/client");
// Configure our API client
const client = new Connection("https://node0.smartholdem.io/api");
Managers.configManager.setFromPreset("mainnet");
Managers.configManager.setHeight(1500000);
(async () => {
// Step 1: Retrieve the incremental nonce of the sender wallet
const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");
const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);
// Step 2: Create the transaction
const transaction = Transactions.BuilderFactory.htlcClaim()
.version(2)
.nonce(senderNonce.toFixed())
.htlcClaimAsset({
lockTransactionId: "5631f0807ac68ba3607d52a587a1c3ecc9ad31386effe564e6f4e31b1c0bfa6d",
unlockSecret: "fe0817c3e33a46a0ceaa24e1de82395eb344731c0a7f375f0844dfc86df76880",
})
.sign("this is a top secret passphrase");
// Step 4: Broadcast the transaction
const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });
// Step 5: Log the response
console.log(JSON.stringify(broadcastResponse.body.data, null, 4))
})();
The unlockSecret has to be a SHA256 hash of the plain text secret that you shared with the person that is allowed to claim the transaction.
const { Transactions, Managers, Utils } = require("@smartholdem/crypto");
const { Connection } = require("@smartholdem/client");
// Configure our API client
const client = new Connection("https://node0.smartholdem.io/api");
Managers.configManager.setFromPreset("mainnet");
Managers.configManager.setHeight(1500000);
(async () => {
// Step 1: Retrieve the incremental nonce of the sender wallet
const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");
const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);
// Step 2: Create the transaction
const transaction = Transactions.BuilderFactory.htlcRefund()
.version(2)
.nonce(senderNonce.toFixed())
.htlcRefundAsset({
lockTransactionId: "5631f0807ac68ba3607d52a587a1c3ecc9ad31386effe564e6f4e31b1c0bfa6d",
})
.sign("this is a top secret passphrase");
// Step 4: Broadcast the transaction
const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });
// Step 5: Log the response
console.log(JSON.stringify(broadcastResponse.body.data, null, 4))
})();
const {Identities} = require("@smartholdem/crypto");
const bip39 = require("bip39");
(async () => {
const mnemonicSecret = bip39.generateMnemonic();
const addressSTH = Identities.Address.fromPassphrase(mnemonicSecret, 63);
console.log('Public Address:', addressSTH);
console.log('BIP39 secret:',mnemonicSecret);
})();
Result example:
Public Address: Sg6epK4DXVKVZ2t57kndUZjtjkS2eCYUZ1
BIP39 secret: salmon any bracket quit toast add arrow rabbit hidden motor ancient always