// Copyright (c) 2014-2019, MyMonero.com
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
"use strict" ;
//
const JSBigInt = require ( "../cryptonote_utils/biginteger" ) . BigInteger ;
const monero _amount _format _utils = require ( "../monero_utils/monero_amount_format_utils" ) ;
const monero _keyImage _cache _utils = require ( "../monero_utils/monero_keyImage_cache_utils" ) ;
//
function Parsed _AddressInfo _ _sync (
keyImage _cache ,
data ,
address ,
view _key _ _private ,
spend _key _ _public ,
spend _key _ _private ,
coreBridge _instance ,
) {
// -> returnValuesByKey
const total _received = new JSBigInt ( data . total _received || 0 ) ;
const locked _balance = new JSBigInt ( data . locked _funds || 0 ) ;
var total _sent = new JSBigInt ( data . total _sent || 0 ) ; // will be modified in place
//
const account _scanned _tx _height = data . scanned _height || 0 ;
const account _scanned _block _height = data . scanned _block _height || 0 ;
const account _scan _start _height = data . start _height || 0 ;
const transaction _height = data . transaction _height || 0 ;
const blockchain _height = data . blockchain _height || 0 ;
const spent _outputs = data . spent _outputs || [ ] ;
//
for ( let spent _output of spent _outputs ) {
var key _image = monero _keyImage _cache _utils . Lazy _KeyImage (
keyImage _cache ,
spent _output . tx _pub _key ,
spent _output . out _index ,
address ,
view _key _ _private ,
spend _key _ _public ,
spend _key _ _private ,
coreBridge _instance ,
) ;
if ( spent _output . key _image !== key _image ) {
// console.log('💬 Output used as mixin (' + spent_output.key_image + '/' + key_image + ')')
total _sent = new JSBigInt ( total _sent ) . subtract ( spent _output . amount ) ;
}
}
//
const ratesBySymbol = data . rates || { } ; // jic it's not there
//
const returnValuesByKey = {
total _received _String : total _received
? total _received . toString ( )
: null ,
locked _balance _String : locked _balance
? locked _balance . toString ( )
: null ,
total _sent _String : total _sent ? total _sent . toString ( ) : null ,
// ^serialized JSBigInt
spent _outputs : spent _outputs ,
account _scanned _tx _height : account _scanned _tx _height ,
account _scanned _block _height : account _scanned _block _height ,
account _scan _start _height : account _scan _start _height ,
transaction _height : transaction _height ,
blockchain _height : blockchain _height ,
//
ratesBySymbol : ratesBySymbol ,
} ;
return returnValuesByKey ;
}
function Parsed _AddressInfo _ _sync _ _keyImageManaged (
data ,
address ,
view _key _ _private ,
spend _key _ _public ,
spend _key _ _private ,
coreBridge _instance ,
) {
// -> returnValuesByKey
const keyImageCache = monero _keyImage _cache _utils . Lazy _KeyImageCacheForWalletWith (
address ,
) ;
return Parsed _AddressInfo _ _sync (
keyImageCache ,
data ,
address ,
view _key _ _private ,
spend _key _ _public ,
spend _key _ _private ,
coreBridge _instance ,
) ;
}
function Parsed _AddressInfo (
keyImage _cache ,
data ,
address ,
view _key _ _private ,
spend _key _ _public ,
spend _key _ _private ,
coreBridge _instance ,
fn , // (err?, returnValuesByKey) -> Void
) {
const returnValuesByKey = Parsed _AddressInfo _ _sync (
keyImage _cache ,
data ,
address ,
view _key _ _private ,
spend _key _ _public ,
spend _key _ _private ,
coreBridge _instance ,
) ;
fn ( null , returnValuesByKey ) ;
}
function Parsed _AddressInfo _ _keyImageManaged (
data ,
address ,
view _key _ _private ,
spend _key _ _public ,
spend _key _ _private ,
coreBridge _instance ,
fn ,
) {
// -> returnValuesByKey
Parsed _AddressInfo (
monero _keyImage _cache _utils . Lazy _KeyImageCacheForWalletWith ( address ) ,
data ,
address ,
view _key _ _private ,
spend _key _ _public ,
spend _key _ _private ,
coreBridge _instance ,
fn ,
) ;
}
exports . Parsed _AddressInfo = Parsed _AddressInfo ;
exports . Parsed _AddressInfo _ _keyImageManaged = Parsed _AddressInfo _ _keyImageManaged ; // in case you can't send a mutable key image cache dictionary
exports . Parsed _AddressInfo _ _sync _ _keyImageManaged = Parsed _AddressInfo _ _sync _ _keyImageManaged ; // in case you can't send a mutable key image cache dictionary
exports . Parsed _AddressInfo _ _sync = Parsed _AddressInfo _ _sync ;
//
function Parsed _AddressTransactions (
keyImage _cache ,
data ,
address ,
view _key _ _private ,
spend _key _ _public ,
spend _key _ _private ,
coreBridge _instance ,
fn , // (err?, returnValuesByKey) -> Void
) {
const returnValuesByKey = Parsed _AddressTransactions _ _sync (
keyImage _cache ,
data ,
address ,
view _key _ _private ,
spend _key _ _public ,
spend _key _ _private ,
coreBridge _instance ,
) ;
fn ( null , returnValuesByKey ) ;
}
function Parsed _AddressTransactions _ _sync (
keyImage _cache ,
data ,
address ,
view _key _ _private ,
spend _key _ _public ,
spend _key _ _private ,
coreBridge _instance ,
) {
const account _scanned _height = data . scanned _height || 0 ;
const account _scanned _block _height = data . scanned _block _height || 0 ;
const account _scan _start _height = data . start _height || 0 ;
const transaction _height = data . transaction _height || 0 ;
const blockchain _height = data . blockchain _height || 0 ;
//
const transactions = data . transactions || [ ] ;
//
// TODO: rewrite this with more clarity if possible
for ( let i = 0 ; i < transactions . length ; ++ i ) {
if ( ( transactions [ i ] . spent _outputs || [ ] ) . length > 0 ) {
for ( var j = 0 ; j < transactions [ i ] . spent _outputs . length ; ++ j ) {
var key _image = monero _keyImage _cache _utils . Lazy _KeyImage (
keyImage _cache ,
transactions [ i ] . spent _outputs [ j ] . tx _pub _key ,
transactions [ i ] . spent _outputs [ j ] . out _index ,
address ,
view _key _ _private ,
spend _key _ _public ,
spend _key _ _private ,
coreBridge _instance ,
) ;
if ( transactions [ i ] . spent _outputs [ j ] . key _image !== key _image ) {
// console.log('Output used as mixin, ignoring (' + transactions[i].spent_outputs[j].key_image + '/' + key_image + ')')
transactions [ i ] . total _sent = new JSBigInt (
transactions [ i ] . total _sent ,
)
. subtract ( transactions [ i ] . spent _outputs [ j ] . amount )
. toString ( ) ;
transactions [ i ] . spent _outputs . splice ( j , 1 ) ;
j -- ;
}
}
}
if (
new JSBigInt ( transactions [ i ] . total _received || 0 )
. add ( transactions [ i ] . total _sent || 0 )
. compare ( 0 ) <= 0
) {
transactions . splice ( i , 1 ) ;
i -- ;
continue ;
}
transactions [ i ] . amount = new JSBigInt (
transactions [ i ] . total _received || 0 ,
)
. subtract ( transactions [ i ] . total _sent || 0 )
. toString ( ) ;
transactions [ i ] . approx _float _amount = parseFloat (
monero _amount _format _utils . formatMoney ( transactions [ i ] . amount ) ,
) ;
transactions [ i ] . timestamp = transactions [ i ] . timestamp ;
const record _ _payment _id = transactions [ i ] . payment _id ;
if ( typeof record _ _payment _id !== "undefined" && record _ _payment _id ) {
if ( record _ _payment _id . length == 16 ) {
// short (encrypted) pid
if ( transactions [ i ] . approx _float _amount < 0 ) {
// outgoing
delete transactions [ i ] [ "payment_id" ] ; // need to filter these out .. because the server can't filter out short (encrypted) pids on outgoing txs
}
}
}
}
transactions . sort ( function ( a , b ) {
if ( a . mempool == true ) {
if ( b . mempool != true ) {
return - 1 ; // a first
}
// both mempool - fall back to .id compare
} else if ( b . mempool == true ) {
return 1 ; // b first
}
return b . id - a . id ;
} ) ;
// prepare transactions to be serialized
for ( let transaction of transactions ) {
transaction . amount = transaction . amount . toString ( ) ; // JSBigInt -> String
if (
typeof transaction . total _sent !== "undefined" &&
transaction . total _sent !== null
) {
transaction . total _sent = transaction . total _sent . toString ( ) ;
}
}
// on the other side, we convert transactions timestamp to Date obj
const returnValuesByKey = {
account _scanned _height : account _scanned _height ,
account _scanned _block _height : account _scanned _block _height ,
account _scan _start _height : account _scan _start _height ,
transaction _height : transaction _height ,
blockchain _height : blockchain _height ,
serialized _transactions : transactions ,
} ;
return returnValuesByKey ;
}
function Parsed _AddressTransactions _ _sync _ _keyImageManaged (
data ,
address ,
view _key _ _private ,
spend _key _ _public ,
spend _key _ _private ,
coreBridge _instance ,
) {
const keyImageCache = monero _keyImage _cache _utils . Lazy _KeyImageCacheForWalletWith (
address ,
) ;
return Parsed _AddressTransactions _ _sync (
keyImageCache ,
data ,
address ,
view _key _ _private ,
spend _key _ _public ,
spend _key _ _private ,
coreBridge _instance ,
) ;
}
function Parsed _AddressTransactions _ _keyImageManaged (
data ,
address ,
view _key _ _private ,
spend _key _ _public ,
spend _key _ _private ,
coreBridge _instance ,
fn ,
) {
Parsed _AddressTransactions (
monero _keyImage _cache _utils . Lazy _KeyImageCacheForWalletWith ( address ) ,
data ,
address ,
view _key _ _private ,
spend _key _ _public ,
spend _key _ _private ,
coreBridge _instance ,
fn ,
) ;
}
exports . Parsed _AddressTransactions = Parsed _AddressTransactions ;
exports . Parsed _AddressTransactions _ _keyImageManaged = Parsed _AddressTransactions _ _keyImageManaged ;
exports . Parsed _AddressTransactions _ _sync = Parsed _AddressTransactions _ _sync ;
exports . Parsed _AddressTransactions _ _sync _ _keyImageManaged = Parsed _AddressTransactions _ _sync _ _keyImageManaged ;