This is the Lamden javascript implementation used in the Lamden Wallet Chrome Extention (Github).
This package should work in Node.js and Broswer implementations.
npm install lamden-js
npm run tests
import Lamden from 'lamden-js'
or
const Lamden = require('lamden-js')
Creates a new wallet object.
- verifying key (vk): public key
- secret key (sk): private key
let lamdenWallet = Lamden.wallet.new_wallet()
console.log(lamdenWallet)
>> {
vk: "ea2cee33f9478d767d67afe345592ef36446ee04f8d588fa76942e6569a53298",
sk: "69a8db3fb7196debc2711fad1fa1935918d09f5d8900d84c3288ea5237611c03"
}
- BIP39 = 24 word mnemonic
- BIP32 = derivation path
let lamdenWallet = Lamden.wallet.new_wallet_bip39()
console.log(lamdenWallet)
>> {
sk: 'a6b72cb3d1160c26f9f39a8f1d4a3c7c0da2ac59d193b66ac5f919ec77f28915',
vk: '53d016586ce35c5f6ea581cadf4693dd2850621dfad6a2261e8dd311c83e11d5',
derivationIndex: 0,
seed: '3626c59ee5bce833a8bf5024645eb10415b39c6f9fd0ff0fb1b00b8ca9fd6ff4b8a0ed7077296cdaff1b955f03318f244dfd3fead404d93f11a3f301c0e3e1c6',
mnemonic: 'evidence rifle behave normal duty mean junk chicken salute relief raw chunk region ocean guard swarm taste toy loop ozone spell crumble apart echo'
}
- BIP39 = 24 word mnemonic
- BIP32 = derivation path
const seed = '3626c59ee5bce833a8bf5024645eb10415b39c6f9fd0ff0fb1b00b8ca9fd6ff4b8a0ed7077296cdaff1b955f03318f244dfd3fead404d93f11a3f301c0e3e1c6'
const derivationIndex = 0;
let lamdenWallet = Lamden.wallet.new_wallet_bip39(seed, derivationIndex)
console.log(lamdenWallet)
>> {
sk: 'a6b72cb3d1160c26f9f39a8f1d4a3c7c0da2ac59d193b66ac5f919ec77f28915',
vk: '53d016586ce35c5f6ea581cadf4693dd2850621dfad6a2261e8dd311c83e11d5',
derivationIndex: 0,
seed: null,
mnemonic: null
}
Takes the sk as an argument and returns the vk
let sk = "69a8db3fb7196debc2711fad1fa1935918d09f5d8900d84c3288ea5237611c03"
let vk = wallet.get_vk(sk)
console.log(vk)
>> 'ea2cee33f9478d767d67afe345592ef36446ee04f8d588fa76942e6569a53298'
Signs a string payload
const stringBuffer = Buffer.from('message')
let messageBytes = new Uint8Array(stringBuffer);
let sk = "69a8db3fb7196debc2711fad1fa1935918d09f5d8900d84c3288ea5237611c03"
let signedMessage = wallet.sign(sk, messageBytes)
console.log(signedMessage)
>> '982c204fe88e620f3319558aa6b11f9d8be75b99b3199f434f5edf2834a9c52059ba4ea3d623ac1d550170e532e919c364aad1333f757f8f22e0355cb1dd8c09'
verify a payload
let validSignature = wallet.verify(vk, messageBytes, signedMessage)
console.log(validSignature)
>> true
Public Testnet masternode is http://167.172.126.5:18080
Use Lamden.TransactionBuilder(networkInfo, txInfo) to create a new Lamden transaction.
create an object that describes the masternode/network that you are going to send the transcation to.
let networkInfo = {
// Optional: Name of network
name: 'Lamden Public Testnet',
// Required: type of network 'mockchain', 'testnet', 'mainnet'
type: 'testnet',
// Required: must begin with http or https
hosts: ['https://testnet-master-1.lamden.io:443']
}
create an object that describes the transaction you are going to send
//Sender and Receiver public keys
let senderVk = "ea2cee33f9478d767d67afe345592ef36446ee04f8d588fa76942e6569a53298"
let receiverVk = "bb0fab41b9118f0afdabf3721fa9a6caae3c93845ed409d3118841065ad1a197"
// Kwargs are the arugments you will send the contract method.
// For example the "currency" contract's "transfer" method needs two arguments to create a transfter; the person reciving the TAU and the amount to transfer. So we create a kwargs object like so.
let kwargs: {
to: receiverVk,
amount: 1000
}
let txInfo = {
senderVk,
contractName: "currency",
methodName: "transfer",
kwargs,
stampLimit: 50000, //Max stamps to be used. Could use less, won't use more.
}
let tx = new Lamden.TransactionBuilder(networkInfo, txInfo)
let senderSk = "69a8db3fb7196debc2711fad1fa1935918d09f5d8900d84c3288ea5237611c03"
tx.send(senderSk, (res, err) => {
if (err) throw new Error(err)
console.log(res.hash)
tx.checkForTransactionResult()
.then(res => console.log(res))
})
//or
tx.events.on('response', (response) => {
if (tx.resultInfo.type === 'error') return
console.log(response)
})
tx.send(senderSk).then(() => tx.checkForTransactionResult())
Returns the NEW changed state in the currency contract for whatever variables the transfer method effected.
In this case, the new balances for both keys is returned
{
state_changes: {
"currency:balances:ea2cee33f9478d767d67afe345592ef36446ee04f8d588fa76942e6569a53298": "4895.0" // -1005 (amount + stamps)
"currency:balances:bb0fab41b9118f0afdabf3721fa9a6caae3c93845ed409d3118841065ad1a197": "1000.0" // +1000
}
status_code: 0
stamps_used: 13924
}
Note: Nonce and processor will be retrieved from the masternode automatcially when send() is called.
getNonce() can be used to set the nonce and processor before hand.
let tx = new Lamden.TransactionBuilder(networkInfo, TxInfo)
tx.getNonce((res, err) => {
if (err) {
console.log("Nonce Not Set")
return
}
console.log(res)
})
>> {
"nonce": 37,
"processor": "0000000000000000000000000000000000000000000000000000000000000000",
"sender": "ea2cee33f9478d767d67afe345592ef36446ee04f8d588fa76942e6569a53298"
}
Create a network instance will allow you to call the masternode API. This class takes a "networkInfo" object as described above.
let testnet = new Network({
name: 'Lamden Public Testnet',
type: 'testnet',
hosts: ['https://testnet-master-1.lamden.io:443']
})
testnet.events.on('online', (online) => {
console.log(online)
>> true or false
})
testnet.ping()
All API methods return a value, Promise or callback if provided
method | masternode endpoint | Description |
---|---|---|
getContractInfo(contractName) | /contracts/contractName | Returns the contract code of contractName example |
getVariable(contractName, variableName, parms) | /contracts/contractName/variableName?key=parm | Retrieve the current state of a contract variable example |
getContractMethods(contractName) | /contracts/contractName/methods | Returns all methods belonging to contractName example |
pingServer() | /ping | Checks if network is online example |
getCurrencyBalance(vk) | /contracts/currency/balances | A wrapper method for getVariable() which always returns the result of the currency contract's balances?key=vk example |
contractExists(contractName) | /contracts/contractName | a wrapper method for getContractInfo() which returns if a contract exists on the blockchain |
sendTransaction(txData, callback) | / | submits a contract to the network a txHash will be returned. Use checkTransaction() to get tx result |
getNonce(senderVk, callback) | /nonce/senderVk | Get the current nonce and processor for a public key (vk) |
checkTransaction(txHash, callback) | /tx?hash=txHash | Get the result of a transaction |
let keystore = new Lamden.Keystore()
let keystore = new Lamden.Keystore({key: {sk: "a67a2dc10b67e7ef6ef049cc2e748bbf669be990827236472108a752f2d7cb8d"}})
let keystore = new Lamden.Keystore({
key: {
sk: "a67a2dc10b67e7ef6ef049cc2e748bbf669be990827236472108a752f2d7cb8d",
nickname: "main account"
}
})
let keystore = new Lamden.Keystore({keyList: [
{sk: "a67a2dc10b67e7ef6ef049cc2e748bbf669be990827236472108a752f2d7cb8d"},
{sk: "3b7f44da84053441372454e8d58d3bf0cbcd12b21e136e4336a8f536704f1e1e"}
]})
let keystore = new Lamden.Keystore({keystoreData: {
data: '{"ct":"nqBdCILO/cRj2pwGU9PLxvIwxWuWQFd9tQuZkoANnyiig55YTIzCPhRSKgFv7xmmuU823aP2jznNkrVWy2k15l+W3gfENe9dXF300HRcTGEFFvdOE52wxsQG4KRNC+UYOB/3VgjCJczb+HCJ39EWzSm+4qQXQI/5/K0ZzG5R+VGRZbI4b6LkfUgpDsOhXdb0BPVrFy45o/c2RjEZ1ocBgTVw63E+9SUYoxNQDHuviMU=","iv":"add60fe81ae267a01f22f18d78fade60","s":"52571fdd0c5d481c"}',
w: 'U2FsdGVkX19dmxAHJ6wQ7DuwkPNawIAD1rmNRrJdMF8='
}})
Keystores expose the keys as wallet objects.
Wallet objects have the following properties:
- a sign method to sign messsages
- a verify method to verify signatures
- a vk property
// Make a new transaction
let tx = new Lamden.TransactionBuilder(networkInfo, TxInfo)
// Sign the transaction with the first wallet in the keystore
tx.sign(null, keystore.wallets[0])
// Send transaction
tx.send()
// Get a wallet from the keystore
let wallet = keystore.getWallet(vk)
// Make a new transaction
let tx = new Lamden.TransactionBuilder(networkInfo, TxInfo)
// Sign the transaction with the wallet
tx.sign(null, wallet[0])
// Send transaction
tx.send()
// Create a keystore with a list of keys
let keystore = new Lamden.Keystore({keyList: [
{sk: "a67a2dc10b67e7ef6ef049cc2e748bbf669be990827236472108a752f2d7cb8d"},
{sk: "3b7f44da84053441372454e8d58d3bf0cbcd12b21e136e4336a8f536704f1e1e"}
]})
// Create a password
let password = "CoolPassword9000"
// Create a keystore file
let keyStoreFile = keystore.createKeystore(password)
let keyStoreFile = {
data: '{"ct":"s6M4AvQvklttEyGq5ebPj/PzAmjNtV6wlS9X8L0RCoZiaqyOz0Y80eZbdf1WRv7gm4Y9aN4vPEoU4oNVVbXoT7QYhuaxMZ+XUyPihcOOnxxmMMGckWD9QOROSgLovvm5yZxp6C2G47dWp7QLkJvubuPgZ+Ws0uexLnkvxXnCikwdZ20yUAFwGN+u3RhQvmgFagCLeuViFXSOtfkDRXmzX4k/7P6cWet8j5rn5gCBbOYHq8rFOxc34ihdhE/8N+x+3MyxGYk2QmwyfzTE9jDEXZwWRlz4GtMXi29ZccRi0z2XEeB7yBl1LTLvngpQM2QnCcX0AQNjHqlPb30bZtQD5shwzgNiRKRon41tKBAH7uvTjw6N39DVIABUkQCusQ1dWWkuvkt79kPjKI/oRF3RH101kXbejFLfDy0eXNUcV3U=","iv":"14e2a23a66fae00bb201f013e9ae1699","s":"5f4b1877b9d4235e"}',
w: 'U2FsdGVkX19RU+1vmxcY5wDfbkn1Gq8zOsh9Y4ylvSs='
}
// Create a keystore instance from the keystore file
let keystore = new Lamden.Keystore({keystoreData: keyStoreFile})
// Decrypt keystore with password
keystore.decryptKeystore('Testing010203')
// Make a new transaction
let tx = new Lamden.TransactionBuilder(networkInfo, TxInfo)
// Sign the transaction with the first wallet in the keystore
tx.sign(null, keystore.wallets[0])
// Send transaction
tx.send()