import { Artifact, Multipart } from "oip-index"
const CHOP_MAX_LEN = 900;
const FLODATA_MAX_LEN = 1040;
/** Easily broadcast OIP messages */
class OIP {
/**
* Create a new OIP Broadcaster
* @param {Wallet} wallet - The Wallet that should broadcast the messages
* @param {Address} address - The Address you wish to sign and broadcast with
*/
constructor(wallet, address){
this._wallet = wallet
this._address = address
}
async sendTransaction(data){
let send_to = {}
send_to[this._address.getPublicAddress()] = 0.0001
let txid
try {
txid = await this._wallet.sendPayment({
discover: false,
to: send_to,
from: this._address.getPublicAddress(),
floData: data
})
} catch (e) {
throw new Error("Unable to send floData Transaction! \n" + e)
}
return txid
}
async broadcastMessage(json_to_broadcast){
let broadcast_json = { oip042: json_to_broadcast }
let broadcast_string = JSON.stringify(broadcast_json)
if (broadcast_string.length <= FLODATA_MAX_LEN){
let txid
try {
txid = await this.sendTransaction(broadcast_string)
} catch (e) {
throw new Error("Unable to Broadcast Message! \n" + e)
}
return txid
} else {
let txids
try {
txids = await this.broadcastMultiparts(this.getMultiparts(broadcast_string))
} catch(e) {
throw new Error("Unable to Broadcast Message! \n" + e)
}
return txids
}
}
async broadcastMultiparts(multiparts){
let tmp_multiparts
let txids = []
for (var multipart of multiparts){
if (txids.length > 0){
multipart.setFirstPartTXID(txids[0])
multipart.sign(this._address)
}
try {
let txid = await this.sendTransaction(multipart.toString())
txids.push(txid)
} catch(e) {
throw new Error("Unable to Broadcast Multiparts! \n" + e)
}
}
return txids
}
/**
* Get the Multiparts for a specific message
* @param {String} message - The string you wish to create multiparts from
* @return {Array.<Multipart>} [description]
*/
getMultiparts(message){
// Check if we can just broadcast all the data in `floData`
if (message.length <= FLODATA_MAX_LEN)
throw new Error("Message can fit in only one Transaction, Multiparts are thus not allowed!")
let multiparts = [];
var tmpMessage = message.slice(0)
var chunks = [];
while (tmpMessage.length > CHOP_MAX_LEN) {
chunks[chunks.length] = tmpMessage.slice(0, CHOP_MAX_LEN);
tmpMessage = tmpMessage.slice(CHOP_MAX_LEN);
}
chunks[chunks.length] = tmpMessage;
for (var c in chunks){
var mp = new Multipart();
mp.setPartNumber(parseInt(c));
mp.setTotalParts(chunks.length - 1);
mp.setPublisherAddress(this._address.getPublicAddress());
mp.setChoppedStringData(chunks[c]);
mp.is_valid = mp.isValid().success;
// If we are the first multipart, then sign right now, for all others, sign after the first tx has broadcast.
if (c == 0){
mp.is_first_part = true;
mp.hasJSONPrefix = true;
mp.sign(this._address);
}
multiparts.push(mp);
}
return multiparts
}
async publish(item){
let pub_message = {}
// Get the sub-object key
let publish_type = "register"
if (item instanceof Artifact)
publish_type = "publish"
// Set it up to be blank
pub_message[publish_type] = {}
// Set the timestamp of the item
item.setTimestamp(Date.now())
let item_json = item.toJSON()
// Remove the version from the returned json, we don't want to publish it twice.
item_json = item_json.oip042
pub_message[publish_type] = item_json
// Create signature preimages
let signature_preimage
if (item instanceof Artifact)
signature_preimage = `${item.getLocation()}-${item.getMainAddress()}-${item.getTimestamp()}`
// if (item instanceof Publisher)
// signature_preimage = `${item.getAlias()}-${item.getMainAddress()}-${item.getTimestamp()}`
let signature
try {
signature = this._address.signMessage(signature_preimage)
} catch(e) {
throw new Error("Unable to create signature preimage! \n" + e)
}
pub_message[publish_type][item.getClassName().toLowerCase()].signature = signature
let txid
try {
txid = await this.broadcastMessage(pub_message)
} catch(e) {
throw new Error(`Unable to Publish ${item.getClassName()}! \n` + e)
}
return txid
}
edit(){
}
transfer(){
}
deactivate(){
}
}
module.exports = OIP