updated cryptonote_utils and sendingFunds usage of create_transaction to move dsts to core cpp, passing change amount, etc

pull/41/head
Paul Shapiro 6 years ago
parent 360cfa8d9c
commit 1bdfe2cbdb

@ -406,36 +406,28 @@ var cnUtil = function(currencyConfig)
from_address_string,
sec_keys,
to_address_string,
serialized__dsts, // amounts are strings
outputs,
mix_outs,
fake_outputs_count,
serialize__sending_amount,
serialized__sending_amount,
serialized__change_amount,
serialized__fee_amount, // string amount
payment_id,
pid_encrypt,
realDestViewKey,
unlock_time,
rct,
nettype
) {
const dsts = serialized__dsts.map(function(i) {
i.amount = new JSBigInt(i.amount)
return i
})
return this.create_signed_transaction(
from_address_string,
sec_keys,
to_address_string,
dsts,
outputs,
mix_outs,
fake_outputs_count,
new JSBigInt(serialize__sending_amount),
new JSBigInt(serialized__sending_amount),
new JSBigInt(serialized__change_amount),
new JSBigInt(serialized__fee_amount), // only to be deserialized again is a bit silly but this at least exposes a JSBigInt API for others
payment_id,
pid_encrypt,
realDestViewKey,
unlock_time,
rct,
nettype
@ -446,24 +438,19 @@ var cnUtil = function(currencyConfig)
from_address_string,
sec_keys,
to_address_string,
dsts,
outputs,
mix_outs,
fake_outputs_count,
sending_amount,
change_amount,
fee_amount,
payment_id,
pid_encrypt,
realDestViewKey,
unlock_time,
rct,
nettype
) {
unlock_time = unlock_time || 0;
mix_outs = mix_outs || [];
if (dsts.length === 0) {
return { err_msg: "Destinations empty" };
}
if (rct != true) {
return { err_msg: "Expected rct=true" }
}
@ -474,24 +461,13 @@ var cnUtil = function(currencyConfig)
mix_outs.length +
" mix outs)" };
}
for (i = 0; i < mix_outs.length; i++) {
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
var sanitary__dsts = [];
for (let i in dsts) {
const sanitary__dst =
{
amount: dsts[i].amount.toString(),
addr: dsts[i].address // key changes
// no need to pass is_subaddress - core C++ gets it
};
sanitary__dsts.push(sanitary__dst);
}
var sanitary__outputs = [];
for (let i in outputs) {
const sanitary__output =
@ -535,9 +511,9 @@ var cnUtil = function(currencyConfig)
sec_viewKey_string: sec_keys.view,
sec_spendKey_string: sec_keys.spend,
to_address_string: to_address_string,
amount: sending_amount.toString(),
sending_amount: sending_amount.toString(),
change_amount: change_amount.toString(),
fee_amount: fee_amount.toString(),
dsts: sanitary__dsts,
outputs: sanitary__outputs,
mix_outs: sanitary__mix_outs,
nettype_string: nettype_utils.nettype_to_API_string(nettype)
@ -546,9 +522,10 @@ var cnUtil = function(currencyConfig)
args.payment_id_string = payment_id;
}
const args_str = JSON.stringify(args);
console.log("args_str" , JSON.stringify(args, null, ' '))
const ret_string = loaded_CNCrypto().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 };
}

@ -554,95 +554,18 @@ function SendFunds(
__trampolineFor_err_withStr(errStr);
return;
}
// Now we can put together the list of fund transfers we need to perform
const fundTransferDescriptions = []; // to build…
// I. the actual transaction the user is asking to do
fundTransferDescriptions.push({
address: moneroReady_targetDescription_address,
amount: totalAmountWithoutFee_JSBigInt,
});
// II. the fee that the hosting provider charges
// NOTE: The fee has been removed for RCT until a later date
// fundTransferDescriptions.push({
// address: hostedMoneroAPIClient.HostingServiceFeeDepositAddress(),
// amount: hostingService_chargeAmount
// })
// III. some amount of the total outputs will likely need to be returned to the user as "change":
//
// Must calculate change..
var changeAmount = JSBigInt("0"); // to initialize
if (usingOutsAmount_comparedTo_totalAmount > 0) {
if (sweeping) {
throw "Unexpected usingOutsAmount_comparedTo_totalAmount > 0 && sweeping";
}
var changeAmount = usingOutsAmount.subtract(
changeAmount = usingOutsAmount.subtract(
totalAmountIncludingFees,
);
console.log("changeAmount", changeAmount);
if (isRingCT) {
// for RCT we don't presently care about dustiness so add entire change amount
console.log(
"Sending change of " +
monero_amount_format_utils.formatMoneySymbol(changeAmount) +
" to " +
wallet__public_address,
);
fundTransferDescriptions.push({
address: wallet__public_address,
amount: changeAmount,
});
} else {
// pre-ringct
// do not give ourselves change < dust threshold
var changeAmountDivRem = changeAmount.divRem(
monero_config.dustThreshold,
);
console.log("💬 changeAmountDivRem", changeAmountDivRem);
if (changeAmountDivRem[1].toString() !== "0") {
// miners will add dusty change to fee
console.log(
"💬 Miners will add change of " +
monero_amount_format_utils.formatMoneyFullSymbol(
changeAmountDivRem[1],
) +
" to transaction fee (below dust threshold)",
);
}
if (changeAmountDivRem[0].toString() !== "0") {
// send non-dusty change to our address
var usableChange = changeAmountDivRem[0].multiply(
monero_config.dustThreshold,
);
console.log(
"💬 Sending change of " +
monero_amount_format_utils.formatMoneySymbol(usableChange) +
" to " +
wallet__public_address,
);
fundTransferDescriptions.push({
address: wallet__public_address,
amount: usableChange,
});
}
}
} else if (usingOutsAmount_comparedTo_totalAmount == 0) {
// this should always fire when sweeping
if (isRingCT) {
// then create random destination to keep 2 outputs always in case of 0 change
const fakeAddress = monero_utils.new_fake_address_for_rct_tx(
nettype,
);
console.log(
"Sending 0 XMR to a fake address to keep tx uniform (no change exists): " +
fakeAddress,
);
fundTransferDescriptions.push({
address: fakeAddress,
amount: 0,
});
}
}
console.log(
"fundTransferDescriptions so far",
fundTransferDescriptions,
);
console.log("Calculated changeAmount:", changeAmount);
if (mixin < 0 || isNaN(mixin)) {
__trampolineFor_err_withStr("Invalid mixin");
return;
@ -679,43 +602,22 @@ function SendFunds(
}
var create_transaction__retVals;
try {
console.log("Destinations: ");
printDsts(fundTransferDescriptions); // TODO: port this out
//
var realDestViewKey; // need to get viewkey for encrypting here, because of splitting and sorting
if (final__pid_encrypt) {
realDestViewKey = monero_utils.decode_address(
moneroReady_targetDescription_address,
nettype,
).view;
console.log("got realDestViewKey", realDestViewKey);
}
console.log("fundTransferDescriptions", fundTransferDescriptions)
var IPCsafe_splitDestinations = decompose_tx_destinations( // TODO: port this out
fundTransferDescriptions,
isRingCT,
true // serialize (convert JSBigInts to strings for IPC)
);
printDsts(IPCsafe_splitDestinations);
//
console.log('try send ', totalAmountWithoutFee_JSBigInt)
create_transaction__retVals = monero_utils.create_signed_transaction__IPCsafe(
wallet__public_address,
wallet__private_keys,
target_address,
IPCsafe_splitDestinations,
usingOuts,
mix_outs,
mixin,
totalAmountWithoutFee_JSBigInt.toString(), // even though it's in dsts, sending it directly as core C++ takes it
changeAmount.toString(),
attemptAt_network_minimumFee.toString(), // must serialize for IPC
final__payment_id,
final__pid_encrypt,
realDestViewKey,
0,
isRingCT,
nettype,
);
console.log("got back", create_transaction__retVals)
} catch (e) {
var errStr;
if (e) {

Loading…
Cancel
Save