@ -37,6 +37,22 @@ const nettype_utils = require("../cryptonote_utils/nettype");
const MyMoneroCoreBridgeEssentialsClass = require ( './MyMoneroCoreBridgeEssentialsClass' )
const MyMoneroBridge _utils = require ( './MyMoneroBridge_utils' )
//
function bridge _sanitized _ _spendable _out ( raw _ _out )
{
const sanitary _ _output =
{
amount : raw _ _out . amount . toString ( ) ,
public _key : raw _ _out . public _key ,
global _index : "" + raw _ _out . global _index ,
index : "" + raw _ _out . index ,
tx _pub _key : raw _ _out . tx _pub _key
} ;
if ( raw _ _out . rct && typeof raw _ _out . rct !== 'undefined' ) {
sanitary _ _output . rct = raw _ _out . rct ;
}
return sanitary _ _output ;
}
//
class MyMoneroCoreBridgeClass extends MyMoneroCoreBridgeEssentialsClass
{
constructor ( this _Module )
@ -437,6 +453,115 @@ class MyMoneroCoreBridgeClass extends MyMoneroCoreBridgeEssentialsClass
}
return ret . retVal ;
}
send _step2 _ _try _create _transaction ( // send only IPC-safe vals - no JSBigInts
from _address _string ,
sec _keys ,
to _address _string ,
using _outs ,
mix _outs ,
fake _outputs _count ,
final _total _wo _fee ,
change _amount ,
fee _amount ,
payment _id ,
priority ,
fee _per _b , // not kib - if fee_per_kb, /= 1024
fee _mask ,
unlock _time ,
nettype ,
optl _ _fork _version
) {
unlock _time = unlock _time || 0 ;
mix _outs = mix _outs || [ ] ;
// NOTE: we also do this check in the C++... may as well remove it from here
if ( mix _outs . length !== using _outs . length && fake _outputs _count !== 0 ) {
return {
err _msg : "Wrong number of mix outs provided (" +
using _outs . length + " using_outs, " +
mix _outs . length + " mix outs)"
} ;
}
for ( var i = 0 ; i < mix _outs . length ; i ++ ) {
if ( ( mix _outs [ i ] . outputs || [ ] ) . length < fake _outputs _count ) {
return { err _msg : "Not enough outputs to mix with" } ;
}
}
//
// Now we need to convert all non-JSON-serializable objects such as JSBigInts to strings etc - not that there should be any!
// - and all numbers to strings - especially those which may be uint64_t on the receiving side
var sanitary _ _using _outs = [ ] ;
for ( let i in using _outs ) {
const sanitary _ _output = bridge _sanitized _ _spendable _out ( using _outs [ i ] )
sanitary _ _using _outs . push ( sanitary _ _output ) ;
}
var sanitary _ _mix _outs = [ ] ;
for ( let i in mix _outs ) {
const sanitary _ _mix _outs _and _amount =
{
amount : mix _outs [ i ] . amount . toString ( ) , // it should be a string, but in case it's not
outputs : [ ]
} ;
if ( mix _outs [ i ] . outputs && typeof mix _outs [ i ] . outputs !== 'undefined' ) {
for ( let j in mix _outs [ i ] . outputs ) {
const sanitary _ _mix _out =
{
global _index : "" + mix _outs [ i ] . outputs [ j ] . global _index , // number to string
public _key : mix _outs [ i ] . outputs [ j ] . public _key
} ;
if ( mix _outs [ i ] . outputs [ j ] . rct && typeof mix _outs [ i ] . outputs [ j ] . rct !== 'undefined' ) {
sanitary _ _mix _out . rct = mix _outs [ i ] . outputs [ j ] . rct ;
}
sanitary _ _mix _outs _and _amount . outputs . push ( sanitary _ _mix _out ) ;
}
}
sanitary _ _mix _outs . push ( sanitary _ _mix _outs _and _amount ) ;
}
const args =
{
from _address _string : from _address _string ,
sec _viewKey _string : sec _keys . view ,
sec _spendKey _string : sec _keys . spend ,
to _address _string : to _address _string ,
final _total _wo _fee : final _total _wo _fee . toString ( ) ,
change _amount : change _amount . toString ( ) ,
fee _amount : fee _amount . toString ( ) ,
priority : "" + priority ,
fee _per _b : fee _per _b . toString ( ) ,
fee _mask : fee _mask . toString ( ) ,
using _outs : sanitary _ _using _outs ,
mix _outs : sanitary _ _mix _outs ,
unlock _time : "" + unlock _time , // bridge is expecting a string
nettype _string : nettype _utils . nettype _to _API _string ( nettype ) ,
} ;
if ( typeof payment _id !== "undefined" && payment _id ) {
args . payment _id _string = payment _id ;
}
if ( typeof optl _ _fork _version !== "undefined" && optl _ _fork _version && optl _ _fork _version != "" ) {
args . fork _version = optl _ _fork _version . toString ( ) ;
}
const args _str = JSON . stringify ( args ) ;
const ret _string = this . Module . send _step2 _ _try _create _transaction ( args _str ) ;
const ret = JSON . parse ( ret _string ) ;
//
if ( typeof ret . err _msg !== 'undefined' && ret . err _msg ) {
return { err _msg : ret . err _msg , tx _must _be _reconstructed : false } ;
}
if ( ret . tx _must _be _reconstructed == "true" || ret . tx _must _be _reconstructed == true ) {
if ( typeof ret . fee _actually _needed == 'undefined' || ! ret . fee _actually _needed ) {
throw "tx_must_be_reconstructed; expected non-nil fee_actually_needed"
}
return {
tx _must _be _reconstructed : ret . tx _must _be _reconstructed , // if true, re-do procedure from step1 except for requesting UnspentOuts (that can be done oncet)
fee _actually _needed : ret . fee _actually _needed // can be passed back to step1
}
}
return { // calling these out to set an interface
tx _must _be _reconstructed : false , // in case caller is not checking for nil
signed _serialized _tx : ret . serialized _signed _tx , // this name change should be fixed to serialized_signed_tx
tx _hash : ret . tx _hash ,
tx _key : ret . tx _key
} ;
}
}
//
module . exports = MyMoneroCoreBridgeClass ;