indivisible_asset.js
function parsePrivatePaymentChain(conn, arrPrivateElements, callbacks){
	var bAllStable = true;
	var issuePrivateElement = arrPrivateElements[arrPrivateElements.length-1];
	if (!issuePrivateElement.payload || !issuePrivateElement.payload.inputs || !issuePrivateElement.payload.inputs[0])
		return callbacks.ifError("invalid issue private element");
	var asset = issuePrivateElement.payload.asset;
	if (!asset)
		return callbacks.ifError("no asset in issue private element");
	var denomination = issuePrivateElement.payload.denomination;
	if (!denomination)
		return callbacks.ifError("no denomination in issue private element");
	async.forEachOfSeries(
		arrPrivateElements,
		function(objPrivateElement, i, cb){
			if (!objPrivateElement.payload || !objPrivateElement.payload.inputs || !objPrivateElement.payload.inputs[0])
				return cb("invalid payload");
			if (!objPrivateElement.output)
				return cb("no output in private element");
			if (objPrivateElement.payload.asset !== asset)
				return cb("private element has a different asset");
			if (objPrivateElement.payload.denomination !== denomination)
				return cb("private element has a different denomination");
			var prevElement = null; 
			if (i+1 < arrPrivateElements.length){ // excluding issue transaction
				var prevElement = arrPrivateElements[i+1];
				if (prevElement.unit !== objPrivateElement.payload.inputs[0].unit)
					return cb("not referencing previous element unit");
				if (prevElement.message_index !== objPrivateElement.payload.inputs[0].message_index)
					return cb("not referencing previous element message index");
				if (prevElement.output_index !== objPrivateElement.payload.inputs[0].output_index)
					return cb("not referencing previous element output index");
			}
			validatePrivatePayment(conn, objPrivateElement, prevElement, {
				ifError: cb,
				ifOk: function(bStable, input_address){
					objPrivateElement.bStable = bStable;
					objPrivateElement.input_address = input_address;
					if (!bStable)
						bAllStable = false;
					cb();
				}
			});
		},
		function(err){
			if (err)
				return callbacks.ifError(err);
			callbacks.ifOk(bAllStable);
		}
	);
}
function parsePrivatePaymentChain(conn, arrPrivateElements, callbacks){
	var bAllStable = true;
	var issuePrivateElement = arrPrivateElements[arrPrivateElements.length-1];
	if (!issuePrivateElement.payload || !issuePrivateElement.payload.inputs || !issuePrivateElement.payload.inputs[0])
		return callbacks.ifError("invalid issue private element");
	var asset = issuePrivateElement.payload.asset;
	if (!asset)
		return callbacks.ifError("no asset in issue private element");
	var denomination = issuePrivateElement.payload.denomination;
	if (!denomination)
		return callbacks.ifError("no denomination in issue private element");
	async.forEachOfSeries(
		arrPrivateElements,
		function(objPrivateElement, i, cb){
			if (!objPrivateElement.payload || !objPrivateElement.payload.inputs || !objPrivateElement.payload.inputs[0])
				return cb("invalid payload");
			if (!objPrivateElement.output)
				return cb("no output in private element");
			if (objPrivateElement.payload.asset !== asset)
				return cb("private element has a different asset");
			if (objPrivateElement.payload.denomination !== denomination)
				return cb("private element has a different denomination");
			var prevElement = null; 
			if (i+1 < arrPrivateElements.length){ // excluding issue transaction
				var prevElement = arrPrivateElements[i+1];
				if (prevElement.unit !== objPrivateElement.payload.inputs[0].unit)
					return cb("not referencing previous element unit");
				if (prevElement.message_index !== objPrivateElement.payload.inputs[0].message_index)
					return cb("not referencing previous element message index");
				if (prevElement.output_index !== objPrivateElement.payload.inputs[0].output_index)
					return cb("not referencing previous element output index");
			}
			validatePrivatePayment(conn, objPrivateElement, prevElement, {
				ifError: cb,
				ifOk: function(bStable, input_address){
					objPrivateElement.bStable = bStable;
					objPrivateElement.input_address = input_address;
					if (!bStable)
						bAllStable = false;
					cb();
				}
			});
		},
		function(err){
			if (err)
				return callbacks.ifError(err);
			callbacks.ifOk(bAllStable);
		}
	);
}
function parsePrivatePaymentChain ( conn , arrPrivateElements , callbacks ) { var bAllStable = true ; var issuePrivateElement = arrPrivateElements [ arrPrivateElements . length - 1 ] ; if ( ! issuePrivateElement . payload || ! issuePrivateElement . payload . inputs || ! issuePrivateElement . payload . inputs [ 0 ] ) return callbacks . ifError ( "invalid issue private element" ) ; var asset = issuePrivateElement . payload . asset ; if ( ! asset ) return callbacks . ifError ( "no asset in issue private element" ) ; var denomination = issuePrivateElement . payload . denomination ; if ( ! denomination ) return callbacks . ifError ( "no denomination in issue private element" ) ; async . forEachOfSeries ( arrPrivateElements , function ( objPrivateElement , i , cb ) { if ( ! objPrivateElement . payload || ! objPrivateElement . payload . inputs || ! objPrivateElement . payload . inputs [ 0 ] ) return cb ( "invalid payload" ) ; if ( ! objPrivateElement . output ) return cb ( "no output in private element" ) ; if ( objPrivateElement . payload . asset !== asset ) return cb ( "private element has a different asset" ) ; if ( objPrivateElement . payload . denomination !== denomination ) return cb ( "private element has a different denomination" ) ; var prevElement = null ; if ( i + 1 < arrPrivateElements . length ) { // excluding issue transaction var prevElement = arrPrivateElements [ i + 1 ] ; if ( prevElement . unit !== objPrivateElement . payload . inputs [ 0 ] . unit ) return cb ( "not referencing previous element unit" ) ; if ( prevElement . message_index !== objPrivateElement . payload . inputs [ 0 ] . message_index ) return cb ( "not referencing previous element message index" ) ; if ( prevElement . output_index !== objPrivateElement . payload . inputs [ 0 ] . output_index ) return cb ( "not referencing previous element output index" ) ; } validatePrivatePayment ( conn , objPrivateElement , prevElement , { ifError : cb , ifOk : function ( bStable , input_address ) { objPrivateElement . bStable = bStable ; objPrivateElement . input_address = input_address ; if ( ! bStable ) bAllStable = false ; cb ( ) ; } } ) ; } , function ( err ) { if ( err ) return callbacks . ifError ( err ) ; callbacks . ifOk ( bAllStable ) ; } ) ; }
arrPrivateElements is ordered in reverse chronological order
arrPrivateElements is ordered in reverse chronological order