Hi NEMbers,
Apologies for the delays on getting this out - we have had some heavy deadlines to reach with the other parts of our platform, however I wanted to fulfill our obligations to point the community towards the iOS SDK we created for LocationCore. This is based on NEM 1 and would thus need to be updated for Catapult in the future.
The SDK requires some kind of gateway to talk to the node network, in our case we used AWS Lambda due to its fault tolerant and scalable nature - as this is a mobile SDK this Lambda provides your single point of reference for your mobile apps considering the transient & decentralised nature of the node network. This is where you would transmit signed transactions to the node network and in a nutshell it needs to sign and execute a transaction.
The code below is just an example of how to sign and transmit a transaction, in reality you would have to handle connection pooling and failovers for unresponsive nodes.
var common = nem.model.objects.create("common")("", "yourprivatekeyheresecurely");
// Create variable to store our mosaic definitions, needed to calculate fees properly (already contains xem definition)
var mosaicDefinitionMetaDataPair = nem.model.objects.get("mosaicDefinitionMetaDataPair");
// Create an un-prepared mosaic transfer transaction object (use same object as transfer tansaction)
var transferTransaction = nem.model.objects.create("transferTransaction")(parsed.address, 1, "Message: " + transaction_message); //hard code 1 as the amount to act as a multiplier
/**
* ATTACHING MOSAIC
* No need to get mosaic definition because it is already known in the mosaicdefinitionMetaDatapair
*/
// Create a mosaic attachment object
var mosaicAttachment = nem.model.objects.create("mosaicAttachment")("locationcore", "lcc", parseFloat(parsed.amount) * 100);
// Push attachment into transaction mosaics
transferTransaction.mosaics.push(mosaicAttachment);
// Need mosaic definition of locationcore:lcc to calculate adequate fees, so we get it from network.
// Otherwise you can simply take the mosaic definition from api manually (http://bob.nem.ninja/docs/#retrieving-mosaic-definitions)
// and put it into mosaicDefinitionMetaDataPair model (objects.js) next to nem:xem (be careful to respect object structure)
nem.com.requests.namespace.mosaicDefinitions(endpoint, mosaicAttachment.mosaicId.namespaceId).then(function(result) {
// Look for the mosaic definition(s) we want in the request response (Could use ["eur", "usd"] to return eur and usd mosaicDefinitionMetaDataPairs)
var neededDefinition = nem.utils.helpers.searchMosaicDefinitionArray(result.data, ["lcc"]);
// Get full name of mosaic to use as object key
var fullMosaicName = nem.utils.format.mosaicIdToName(mosaicAttachment.mosaicId);
// Check if the mosaic was found
if (undefined === neededDefinition[fullMosaicName]) return console.error("Mosaic not found !");
mosaicDefinitionMetaDataPair[fullMosaicName] = {};
mosaicDefinitionMetaDataPair[fullMosaicName].mosaicDefinition = neededDefinition[fullMosaicName];
// Get current supply
nem.com.requests.mosaic.supply(endpoint, nem.utils.format.mosaicIdToName(mosaicAttachment.mosaicId)).then(function(res) {
mosaicDefinitionMetaDataPair[nem.utils.format.mosaicIdToName(mosaicAttachment.mosaicId)].supply = res.supply;
// Get current supply for mosaic
nem.com.requests.mosaic.supply(endpoint, fullMosaicName).then(function(res) {
mosaicDefinitionMetaDataPair[fullMosaicName].supply = res.supply;
// Prepare the transfer transaction object
var transactionEntity = nem.model.transactions.prepare("mosaicTransferTransaction")(common, transferTransaction, mosaicDefinitionMetaDataPair, nem.model.network.data.testnet.id);
//create a keypair
var kp = nem.crypto.keyPair.create(common.privateKey);
// serialise transaction object
var serialized = nem.utils.serialization.serializeTransaction(transactionEntity);
// sign serialised transaction
var signature = kp.sign(serialized);
// build result object
var signedtx = {
"data": nem.utils.convert.ua2hex(serialized),
"signature": signature.toString()
};
var finalArray = {};
nem.com.requests.transaction.announce(endpoint, JSON.stringify(signedtx)).then(function(res) {
finalArray.transaction = res;
nem.com.requests.account.data(endpoint, parsed.address).then(function(res1) {
finalArray.account = res1;
nem.com.requests.account.mosaics.owned(endpoint, parsed.address).then(function(res2) {
finalArray.mosaics = res2;
response = { "statusCode": 200, "body": JSON.stringify((finalArray))};
//transaction sent
callback(null, response);
})
})
})
})
})
})
I feel at the very least this will allow any other Swift developers to use this as a reference for how some of the crypto stuff is implemented (We based this implementation off Kailin’s .NET / C# code), however I would say that the most useful feature of this is that this code allows you to generate a wallet file (.wlt) that is compatible with Nano Wallet meaning it can be implemented into existing iOS wallets to provide some level of portability.
I hope this helps someone out who can contribute a larger Swift library to NEM.