Client for LTO Network. Integration for both public blockchain and private event-chain.
npm install @ltonetwork/lto --save
The chain_id is 'L' for the mainnet and 'T' testnet.
import {LTO} from '@ltonetwork/lto';
const lto = new LTO('T');
const account = lto.account();
const seed = 'satisfy sustain shiver skill betray mother appear pupil coconut weasel firm top puzzle monkey seek';
const account = lto.account({seed: seed});
Your seed can be encrypted:
const seed = 'satisfy sustain shiver skill betray mother appear pupil coconut weasel firm top puzzle monkey seek';
const account = lto.account({seed: seed});
const password = 'verysecretpassword';
const encrypted = account.encrypt(password);
console.log(encrypted); //U2FsdGVkX18tLqNbaYdDu5V27VYD4iSylvKnBjMmvQoFFJO1KbsoKKW1eK/y6kqahvv4eak8Uf8tO1w2I9hbcWFUJDysZh1UyaZt6TmXwYfUZq163e9qRhPn4xC8VkxFCymdzYNBAZgyw8ziRhSujujiDZFT3PTmhhkBwIT7FMs=
To create an account from an encrypted seed add seedPassword
when creating the account from seed.
const encryptedSeed = 'U2FsdGVkX18tLqNbaYdDu5V27VYD4iSylvKnBjMmvQoFFJO1KbsoKKW1eK/y6kqahvv4eak8Uf8tO1w2I9hbcWFUJDysZh1UyaZt6TmXwYfUZq163e9qRhPn4xC8VkxFCymdzYNBAZgyw8ziRhSujujiDZFT3PTmhhkBwIT7FMs=';
const password = 'verysecretpassword';
const account = lto.account({seed: encryptedSeed, seedPassword: password});
import {LTO, Binary} from '@ltonetwork/lto';
lto = new LTO();
const account = lto.account({seed: seed});
lto.transfer(account, recipient, 100 * 10^8);
lto.massTransfer(account, [{recipient: recipient1, amount: 100 * 10^8}, {recipient: recipient2, amount: 50 * 10^8}]);
lto.anchor(account, new Binary('some value').hash(), new Binary('other value').hash());
lto.issueAssociation(account, recipient, 10);
lto.revokeAssociation(account, recipient, 10);
lto.lease(account, recipient, 10000 * 10^8);
lto.cancelLease(account, leaseId);
lto.sponsor(account, otherAccount);
lto.cancelSponsorship(account, otherAccount);
lto.getBalance(account);
lto.setData(account, {foo: 'bar'});
lto.getData(account);
Amounts are in LTO * 10^8
. Eg: 12.46 LTO is 1246000000
.
The LTO
class provides a simple way for doing transactions. Some features like multisig and sponsored transactions
aren't available with these methods. To use them you'll need to create a transaction object, sign and broadcast it.
import {Transfer} from '@ltonetwork/lto';
const transaction = new Transfer(recipient, amount);
The Transaction needs then to be signed. In order to sign a transaction an account is needed.
account.sign(transaction);
For last the transaction needs to be broadcasted to the node. In order to do so we need to connect to the node using the PublicNode class.
const broadcastedTx = await lto.node.broadcast(transaction);
Transaction classes have convenience methods, providing a fluent interface
import {Transfer} from '@ltonetwork/lto';
const transaction = await new Transfer(recipient, amount)
.signWith(account)
.broadcastTo(lto.node);
import {Transfer} from '@ltonetwork/lto';
const transaction = new Transfer(recipient, amount, attachment)
import {MassTransfer} from '@ltonetwork/lto';
const transaction = new MassTransfer([{recipient: recipient1, amount: amount1}, {recipient: recipient2, amount: amount2}], attachment)
import {Anchor} from '@ltonetwork/lto';
const transaction = new Anchor(hash);
import {Lease} from '@ltonetwork/lto';
const transaction = new Lease(recipient, amount);
import {CancelLease} from '@ltonetwork/lto';
const transaction = new CancelLease(leaseId);
Create a SetScript
transaction using the compile
method of the public node.
const transaction = lto.node.compile(script);
Clear a script by using null
as compiled script.
import {SetScript} from '@ltonetwork/lto';
const transaction = new SetScript(null);
import {SetScript} from '@ltonetwork/lto';
const transaction = new Sponsorship(recipient);
import {CancelSponsorship} from '@ltonetwork/lto';
const transaction = new CancelSponsorship(recipient);
import {Association} from '@ltonetwork/lto';
transaction = new Association(recipient, association_type, hash);
import {RevokeAssociation} from '@ltonetwork/lto';
transaction = new RevokeAssociation(recipient, association_type, hash);
By default the following public nodes are used
- Mainnet - https://nodes.lto.network
- Testnet - https://testnet.lto.network
To use your own public node, set the node address of the LTO
object.
lto.nodeAddress = "http://localhost:6869";
The lto.node
object will automatically be replaced when the node address is changed.
const chain = account.createEventChain(); // Creates an empty event chain with a valid id and last hash
import {Event, EventChain} from '@ltonetwork/lto';
const body = {
"$schema": "http://specs.livecontracts.io/01-draft/12-comment/schema.json#",
"identity": {
"$schema": "http://specs.livecontracts.io/01-draft/02-identity/schema.json#",
"id": "1bb5a451-d496-42b9-97c3-e57404d2984f"
},
"content_media_type": "text/plain",
"content": "Hello world!"
};
const chain = new EventChain(account);
const genesisEvent = new Event(body).signWith(account);
chain.addEvent(genesisEvent);
HTTP requests can be signed with an LTO account using http-signatures standard.
import {Request, HTTPSignature} from '@ltonetwork/lto';
const headers = {
date: (new Date("April 1, 2018 12:00:00")).toISOString()
};
const request = new Request('http://example.com', 'get', headers);
const httpSign = new HTTPSignature(request, ['(request-target)', 'date']);
const signatureHeader = httpSign.signWith(account); // keyId="FkU1XyfrCftc4pQKXCrrDyRLSnifX1SMvmx1CYiiyB3Y",algorithm="ed25519-sha256",headers="(request-target) date",signature="tMAxot4iWb8gB4FQ2zqIMfH2Fd8kA9DwSoW3UZPj9f8QlpLX5VvWf314vFnM8MsDo5kqtGzk7XOOy0TL4zVWAg=="
The signatureHeader
should added as 'Signature' HTTP Header to an API request.
On the server the request should be validated. This should typically be done through middleware.
import {Request, HTTPSignature} from '@ltonetwork/lto';
app.use((req, res, next) => {
const request = new Request(req.path, req.method, req.headers);
const httpSign = new HTTPSignature(request, ['(request-target)', 'date']).verify();
try {
httpSign.verify();
} catch (error) {
res.send(error);
}
next();
});
Any account on LTO network, for which the public key is known, can be resolved as DID (decentralized identifier). To explicitly create a DID use the identity builder.
import {IdentityBuilder} from '@ltonetwork/lto';
const account = lto.account();
new IdentityBuilder(account).transactions.map(tx => lto.broadcast(tx));
By default the account's public key is the only verification method of the DID. Other verification methods can be added through associations with other accounts.
import {IdentityBuilder, VerificationRelationship as VR} from '@ltonetwork/lto';
const account = lto.account();
const key1 = lto.account({publicKey: "8cMyCW5Esx98zBqQCy9N36UaGZuNcuJhVe17DuG42dHS"});
const key2 = lto.account({publicKey: "9ubzzV9tRYTcQee68v1mUPJW7PHdB74LZEgG1MgZUExf"});
new IdentityBuilder(account)
.addVerificationMethod(key1)
.addVerificationMethod(key2, VR.authentication | VR.capabilityInvocation)
.transactions.map(tx => lto.broadcast(tx));
Use Promise.all()
if you wait to await for the transactions to be broadcasted.