Skip to content

Instantly share code, notes, and snippets.

@andrewmunro
Created October 20, 2017 15:34
Show Gist options
  • Save andrewmunro/d9d4ef6ffdf6b643aeaedec1d1e41742 to your computer and use it in GitHub Desktop.
Save andrewmunro/d9d4ef6ffdf6b643aeaedec1d1e41742 to your computer and use it in GitHub Desktop.
Iota messages
const IOTA = require('iota.lib.js');
const curl = require('curl.lib.js');
const seed = 'SEEDHERE';
const tag = 'IOTATESTMESSAGE99999999999'
let iota = new IOTA({
'host': 'http://iota.bitfinex.com',
'port': 80
});
// Do proof-of-work locally using curl.lib.js
curl.init();
// Copy pasta from https://github.com/iotaledger/wallet/blob/master/ui/js/iota.lightwallet.js
iota.api.attachToTangle = function(trunkTransaction, branchTransaction, minWeightMagnitude, trytes, callback) {
const ccurlHashing = function(trunkTransaction, branchTransaction, minWeightMagnitude, trytes, callback) {
const iotaObj = iota;
// inputValidator: Check if correct hash
if (!iotaObj.valid.isHash(trunkTransaction)) {
return callback(new Error("Invalid trunkTransaction"));
}
// inputValidator: Check if correct hash
if (!iotaObj.valid.isHash(branchTransaction)) {
return callback(new Error("Invalid branchTransaction"));
}
// inputValidator: Check if int
if (!iotaObj.valid.isValue(minWeightMagnitude)) {
return callback(new Error("Invalid minWeightMagnitude"));
}
let finalBundleTrytes = [];
let previousTxHash;
let i = 0;
function loopTrytes() {
getBundleTrytes(trytes[i], function(error) {
if (error) {
return callback(error);
} else {
i++;
if (i < trytes.length) {
loopTrytes();
} else {
// reverse the order so that it's ascending from currentIndex
return callback(null, finalBundleTrytes.reverse());
}
}
});
}
function getBundleTrytes(thisTrytes, callback) {
// PROCESS LOGIC:
// Start with last index transaction
// Assign it the trunk / branch which the user has supplied
// IF there is a bundle, chain the bundle transactions via
// trunkTransaction together
let txObject = iotaObj.utils.transactionObject(thisTrytes);
txObject.tag = txObject.obsoleteTag;
txObject.attachmentTimestamp = Date.now();
txObject.attachmentTimestampLowerBound = 0;
txObject.attachmentTimestampUpperBound = (Math.pow(3,27) - 1) / 2;
// If this is the first transaction, to be processed
// Make sure that it's the last in the bundle and then
// assign it the supplied trunk and branch transactions
if (!previousTxHash) {
// Check if last transaction in the bundle
if (txObject.lastIndex !== txObject.currentIndex) {
return callback(new Error("Wrong bundle order. The bundle should be ordered in descending order from currentIndex"));
}
txObject.trunkTransaction = trunkTransaction;
txObject.branchTransaction = branchTransaction;
} else {
// Chain the bundle together via the trunkTransaction (previous tx in the bundle)
// Assign the supplied trunkTransaciton as branchTransaction
txObject.trunkTransaction = previousTxHash;
txObject.branchTransaction = trunkTransaction;
}
let newTrytes = iotaObj.utils.transactionTrytes(txObject);
curl.pow({trytes: newTrytes, minWeight: minWeightMagnitude}).then(function(nonce) {
var returnedTrytes = newTrytes.substr(0, 2673-81).concat(nonce);
var newTxObject= iotaObj.utils.transactionObject(returnedTrytes);
// Assign the previousTxHash to this tx
var txHash = newTxObject.hash;
previousTxHash = txHash;
finalBundleTrytes.push(returnedTrytes);
callback(null);
}).catch(callback);
}
loopTrytes()
}
ccurlHashing(trunkTransaction, branchTransaction, minWeightMagnitude, trytes, function(error, success) {
if (error) {
console.log(error);
} else {
console.log(success);
}
if (callback) {
return callback(error, success);
} else {
return success;
}
})
}
const sortToBundles = (transactions) => {
bundles = {}
for( var i = 0 ; i < transactions.length ; i++) {
var transaction = transactions[i]
var bundleHash = transaction.bundle
if(!bundles[bundleHash]) {
bundles[bundleHash] = []
}
bundles[bundleHash][transaction.currentIndex] = transaction
}
return bundles
};
const getBundleMessage = (bundle) => {
var messageTrytes = ''
bundle.forEach((transaction, idx) => {
messageTrytes += transaction.signatureMessageFragment;
});
// kluge to make sure it's an even # of chars for fromTrytes
if (messageTrytes.length % 2 > 0) {
messageTrytes += '9'
}
var decodedStr = iota.utils.fromTrytes(messageTrytes);
var jsonStr = decodedStr.substr(0, decodedStr.lastIndexOf('}') + 1)
try {
return JSON.parse(jsonStr);
} catch(error) {
return {error: error.toString()}
}
};
const getMessages = (addresses, callback) => {
iota.api.findTransactions({ tags: [tag], addresses: addresses}, (error, result) => {
if (error) {
return callback(error);
} else if (result.length == 0) {
// handle empty results
return callback("no results in findTransactions callback for tag "+ IOTALKMESSAGE_TAG);
} else {
iota.api.getTrytes(result, (error, trytes) => {
if (error) {
return callback(error);
} else {
var transactions = trytes.map((transactionTrytes) => {
return iota.utils.transactionObject(transactionTrytes);
});
var bundles = sortToBundles(transactions)
var messages = []
Object.keys(bundles).forEach((bundleHash) => {
var message = getBundleMessage(bundles[bundleHash])
message.timestamp = bundles[bundleHash][0].timestamp
message.address = bundles[bundleHash][0].address
messages.push(message);
});
callback(null, messages);
}
});
}
});
}
iota.api.getNewAddress(seed, { 'checksum': true, total: 1 }, function (error, addresses) {
if (error) {
console.log(error);
} else {
let [address] = addresses;
console.log('Found address:', address);
getMessages([address], (e, messages) => {
if (e) throw e;
console.log(messages);
let message = iota.utils.toTrytes(JSON.stringify({"data": "some message data"}));
console.log('Message to send:', message)
let transfers = [{
'address': address,
'value': 0,
'message': message,
'tag': tag
}];
console.log('Sending message...')
iota.api.sendTransfer(seed, 4, 14, transfers, function(e, bundle) {
if (e) throw e;
console.log("Successfully sent your transfer: ", bundle);
getMessages([address], (e, messages) => {
if (e) throw e;
console.log(messages);
});
});
});
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment