/* * @project: TERA * @version: Development (beta) * @license: MIT (not for evil) * @copyright: Yuriy Ivanov (Vtools) 2017-2019 [progr76@gmail.com] * Web: https://terafoundation.org * Twitter: https://twitter.com/terafoundation * Telegram: https://t.me/terafoundation */ var PayList = []; var AttachItem; var MapAccounts = {}; var LoadMapAfter = {}; var MapCheckTransaction = {}; var CanSendTransaction = 1; var CurrentTR = {}; var MaxBlockNum = 0; var DelList = {}; var WasAccountsDataStr; function SetAccountsData(Data, AccountsDataStr) { if (!Data || !Data.result) return; if ($("idBtRun")) $("idBtRun").style.display = (Data.arr.length ? '' : 'none'); if (AccountsDataStr === WasAccountsDataStr) return; WasAccountsDataStr = AccountsDataStr; var arr = Data.arr; var Select = $("idAccount"); if (arr.length !== Select.options.length) { var options = Select.options; options.length = arr.length; } MaxBlockNum = GetCurrentBlockNumByTime(); SetGridData(arr, "grid_accounts", "idMyTotalSum"); for (var i = 0; arr && i < arr.length; i++) { var Item = arr[i]; Item.MyAccount = true; var Num = ParseNum(Item.Num); if (!MapAccounts[Num]) MapAccounts[Num] = {}; CopyObjKeys(MapAccounts[Num], Item); var option = Select.options[i]; var StrText = GetAccountText(Item, Num, 1); if (option.text !== StrText) CheckNameAccTo(); option.value = Num; option.text = StrText; } var CurentValue = LoadMapAfter["idAccount"]; if (CurentValue) { Select.value = CurentValue; delete LoadMapAfter["idAccount"]; } SetCurCurencyName(); }; function CurTransactionToForm(bForce) { var Item = $("idTransaction"); if (Item && (Item.className === "" || bForce)) Item.value = GetJSONFromTransaction(CurrentTR); }; function CheckNameAccTo() { MaxBlockNum = GetCurrentBlockNumByTime(); var ToID = ParseNum($("idTo").value); if (!MapAccounts[ToID] || (MapAccounts[ToID].MustUpdate && MapAccounts[ToID].MustUpdate >= MaxBlockNum)) { GetData("GetAccountList", { StartNum: ToID }, function(Data) { if (Data && Data.result === 1 && Data.arr.length) { var Item = Data.arr[0]; Item.UpdateData = Date.now(); MapAccounts[Item.Num] = Item; SetNameAccTo(); } }); } SetNameAccTo(); }; function SetNameAccTo() { var Str = ""; var ToID = ParseNum($("idTo").value); var Item = MapAccounts[ToID]; var element = $("idNameTo"); var StrTo = GetAccountText(Item, ToID, 1); if (!element) { element = $("idNameTo2"); } else { StrTo = "To: " + StrTo; } if (element.innerText !== StrTo) { element.innerText = StrTo; if (Item && Item.MyAccount) element.className = "smallbold"; else element.className = ""; } }; function GetAccountText(Item, Num, bGetSum) { if (Item) { var text = Item.Name; if (!text || text.length === 0) text = Num; else text = "" + Num + ". " + text; if (bGetSum) { var StrSum = SUM_TO_STRING(Item.Value, Item.Currency); text += " (" + StrSum + ")"; } return text; } else { return Num; } }; function OnEditIdTo() { CheckNameAccTo(); OnEditTransactionFields(); }; function OnEditTransactionFields() { if (IsVisibleBlock("edit_transaction")) CreateTransaction(); SetCurCurencyName(); SaveValues(); }; function SetCurCurencyName() { var idCoin = $("idCoinName"); if (!idCoin) return; var Num = ParseNum($("idAccount").value); var Item = MapAccounts[Num]; if (Item) { idCoin.innerText = CurrencyName(Item.Currency); } }; function CreateTransaction(F, CheckErr, Run) { CheckNameAccTo(); CheckSending(); var FromID = ParseNum($("idAccount").value); if (CheckErr && FromID === 0) { SetError("Select valid 'From account'"); return; } var StrTo = $("idTo").value.trim(); var bFindAcc = 0; var ToPubKey = ""; var ToID = ParseNum(StrTo); if (StrTo !== "" + ToID) { if (StrTo.length === 66 && (StrTo.substr(0, 2) === "02" || StrTo.substr(0, 2) === "03") && IsHexStr(StrTo)) { ToID = 0; ToPubKey = StrTo; if (ToPubKey === PubKeyStr) bFindAcc = 1; } else { if (CheckErr) SetError("Valid 'Pay to' - required!"); return; } } if (CheckErr && ToID <= 0 && ToPubKey === "" && !AttachItem) { SetError("Valid 'Pay to' - required!"); return; } var Description = $("idDescription").value.substr(0, 200); var StrSum = $("idSumSend").value; var indDot = StrSum.indexOf("."); if (indDot >= 0) { var StrTER = StrSum.substr(0, indDot); var StrCENT = StrSum.substr(indDot + 1); } else { var StrTER = StrSum; var StrCENT = "0"; } StrCENT = StrCENT + "000000000"; var Coin = { SumCOIN: ParseNum(StrTER), SumCENT: ParseNum(StrCENT.substr(0, 9)) }; var OperationID = 0; var Item = MapAccounts[FromID]; if (Item) { OperationID = Item.Value.OperationID; } var AttachBody = []; if (AttachItem) { AttachBody = AttachItem.Data.Body; if (!AttachBody) AttachBody = []; } var ToPubKeyArr = []; if (ToPubKey) ToPubKeyArr = GetArrFromHex(ToPubKey); var TR = { Type: 111, Version: 3, Reserve: 0, FromID: FromID, OperationID: OperationID, To: [{ PubKey: ToPubKeyArr, ID: ToID, SumCOIN: Coin.SumCOIN, SumCENT: Coin.SumCENT }], Description: Description, Body: AttachBody, Sign: CurrentTR.Sign, }; Object.defineProperties(TR, { bFindAcc: { configurable: true, writable: true, enumerable: false, value: bFindAcc } }); Object.defineProperties(TR, { Run: { configurable: true, writable: true, enumerable: false, value: Run } }); if (JSON.stringify(TR) === JSON.stringify(CurrentTR)) { if (F) F(CurrentTR); return; } CurrentTR = TR; GetSignTransaction(TR, "", function(TR) { CurTransactionToForm(true); if (F) F(TR); }); }; function SignJSON(F) { if ($("idSignJSON").disabled) return; var TR = GetTransactionFromJSON(); if (!TR) return; CurrentTR = TR; GetSignTransaction(TR, "", function(TR) { CurTransactionToForm(true); if (F) F(); }); }; function CheckSending(bToStatus) { MaxBlockNum = GetCurrentBlockNumByTime(); var CanSend = IsPrivateMode(); var StrButton = "Send"; var StrButtonSign = "Sign JSON"; if (!CanSend) { StrButton = " "; StrButtonSign = " "; } if (CanSend) { var FromID = ParseNum($("idAccount").value); var Item = MapAccounts[FromID]; if (Item && Item.NextSendTime && Item.NextSendTime > MaxBlockNum) { if (bToStatus) SetStatus("Transaction was sending. Wait... (" + Item.LastTransactionText + ")"); CanSend = false; StrButton = "Wait..."; } } $("idSendButton").disabled = (!CanSend); $("idSendButton").value = StrButton; $("idSignJSON").disabled = (!CanSend); $("idSignJSON").value = StrButtonSign; return CanSend; }; function AddWhiteList() { var ToID = ParseNum($("idTo").value); if (ToID && $("idWhiteOnSend").checked) Storage.setItem("White:" + ToID, 1); }; function SendMoneyBefore() { if ($("idSendButton").disabled) return; var ToID = ParseNum($("idTo").value); var Item = MapAccounts[ToID]; if (Storage.getItem("White:" + ToID) || !$("idSumSend").value || Item && Item.MyAccount) { SendMoney(); } else { var CoinAmount = COIN_FROM_FLOAT($("idSumSend").value); var StrTo = " to " + GetAccountText(Item, ToID); $("idWhiteOnSend").checked = 0; $("idOnSendText").innerHTML = "" + STRING_FROM_COIN(CoinAmount) + " " + $("idCoinName").innerText + StrTo; if ($("idSumSend").value >= 100000) { $("idOnSendText").innerHTML += "
WARNING: You are about to send a very large amount!
"; } SetVisibleBlock("idBlockOnSend", 1); SetImg(this, 'idBlockOnSend'); } }; function SendMoney2() { AddWhiteList(); SendMoney(); }; function SendMoney() { if (!CanSendTransaction) { SetError("Can't Send transaction"); return; } CheckSending(true); if ($("idSendButton").disabled) return; SetVisibleBlock("idBlockOnSend", 0); CreateTransaction(SendMoneyTR, true, ClearAttach); }; function GetJSONFromTransaction(TR) { var TR2 = JSON.parse(JSON.stringify(TR)); for (var i = 0; i < TR2.To.length; i++) { var Item = TR2.To[i]; Item.PubKey = GetHexFromArr(Item.PubKey); } TR2.Body = GetHexFromArr(TR2.Body); TR2.Sign = GetHexFromArr(TR2.Sign); var Str = JSON.stringify(TR2, "", 4); return Str; }; function GetTransactionFromJSON() { var Str = $("idTransaction").value; try { var TR = JSON.parse(Str); } catch (e) { SetError(e); return undefined; } for (var i = 0; i < TR.To.length; i++) { var Item = TR.To[i]; Item.PubKey = GetArrFromHex(Item.PubKey); if (Item.SumTER && Item.SumCOIN === undefined) { Item.SumCOIN = Item.SumTER; delete Item.SumTER; } } TR.Body = GetArrFromHex(TR.Body); TR.Sign = GetArrFromHex(TR.Sign); return TR; }; function SendMoneyJSON() { if (!CanSendTransaction) { SetError("Can't Send transaction"); return; } var TR = GetTransactionFromJSON(); if (!TR) return; SendMoneyTR(TR); }; function SignAndSendFromJSON() { SignJSON(SendMoneyJSON); }; function GetTransactionText(TR, key) { var Str; if (TR) { if (TR.Type === TYPE_TRANSACTION_CREATE) { Str = "New account " + TR.Name.substr(0, 20); } else if (TR.Type === 111) { var MapItem = {}; var ValueTotal = { SumCOIN: 0, SumCENT: 0 }; Str = "" + TR.FromID + "/" + TR.OperationID + " to "; for (var i = 0; i < TR.To.length; i++) { var Item = TR.To[i]; if (Item.ID === TR.FromID || MapItem[Item.ID]) continue; MapItem[Item.ID] = 1; ADD(ValueTotal, Item); if (i === 0) Str += "["; if (Str.length < 16) { if (i > 0) Str += ","; if (Item.ID || (Item.PubKey && Item.PubKey.length !== 66)) Str += Item.ID; else Str += GetHexFromArr(Item.PubKey).substr(0, 8); } else if (Str.substr(Str.length - 1) !== ".") Str += "..."; } Str += "] " + SUM_TO_STRING(ValueTotal); Str += " " + (TR.Description.substr(0, 20)).replace(/\n/g, ""); } } else { if (key) Str = key; else Str = ""; } return Str; }; function SendMoneyTR(TR) { var Body = GetArrFromTR(TR); WriteArr(Body, TR.Sign, 64); Body.length += 12; SendTransaction(Body, TR, undefined, function(Err, TR, Body) { if (Err) return; var Item = MapAccounts[TR.FromID]; if (Item) { var key = GetHexFromArr(sha3(Body)); var BlockNum = GetCurrentBlockNumByTime(); Item.LastTransactionText = GetTransactionText(TR); Item.NextSendTime = BlockNum + 10; MapCheckTransaction[key] = Item; CheckSending(); } }); }; function ClearTransaction() { PayList = []; ClearAttach(); CheckSendList(1); var arr = ["idAccount", "idTo", "idSumSend", "idDescription"]; for (var i = 0; i < arr.length; i++) { $(arr[i]).value = ""; } SaveValues(); CreateTransaction(); }; function StartEditTransactionJSON() { var Item = $("idTransaction"); Item.className = "smallbold"; }; function EditJSONTransaction() { var name = "edit_transaction"; var Item = $("idTransaction"); if (IsVisibleBlock(name)) { SetVisibleBlock(name, false); Item.className = ""; } else { CreateTransaction(); SetVisibleBlock(name, true); Item.className = ""; } }; var glNumPayCount = 0; function GetInvoiceHTML(item, onclick, classstr) { if (!item.num) { glNumPayCount++; item.num = glNumPayCount; } var idname = "idSendInvoice" + item.num; var value = ""; if (item.Data.Amount) value += "" + item.Data.Amount + " Tera"; else value += "No pay"; value += " " + item.num + ". " + item.Data.name; return ""; }; function AddSendList(item) { PayList.push({ Data: item }); }; function CheckSendList(bRedraw) { TitleWarning = PayList.length; if (AttachItem) TitleWarning++; var Str = Storage.getItem("InvoiceList"); if (!Str && !bRedraw) return; if (!bRedraw) { SelectTab("TabSend"); } if (Str) { var arr = JSON.parse(Str); for (var i = 0; i < arr.length; i++) { AddSendList(arr[i]); } Storage.setItem("InvoiceList", ""); } var idList = $("idSendList"); if (PayList.length) { idList.innerHTML = "
Select the item you want to sign (pay) and send to blockchain:
"; for (var i = 0; i < PayList.length; i++) { var item = PayList[i]; idList.innerHTML += GetInvoiceHTML(item, "UseInvoice(" + i + ")", "btinvoice"); } if (AttachItem === undefined) UseInvoice(0); } else { idList.innerHTML = ""; } }; setInterval(CheckSendList, 200); function UseInvoice(Num) { var item = PayList[Num]; if (item.Data.From) $("idAccount").value = item.Data.From; $("idTo").value = item.Data.To; $("idSumSend").value = item.Data.Amount; $("idDescription").value = item.Data.Description; PayList.splice(Num, 1); AttachItem = item; $("idAttach").innerHTML = GetInvoiceHTML(AttachItem, "OpenAttach()", "btinvoice btinvoice_use"); CheckSendList(1); }; function ClearAttach() { AttachItem = undefined; if ($("idAttach")) $("idAttach").innerHTML = ""; }; function OpenAttach() { if (AttachItem) { var Data2 = JSON.parse(JSON.stringify(AttachItem.Data)); if (Data2.Body) Data2.Body = GetHexFromArr(Data2.Body); delete Data2.TransferSecret; alert("DATA:\n" + JSON.stringify(Data2, "", 4)); } }; var CURRENCY, PUBKEY, NAME, SMART; function SendTrCreateAccWait(Currency, PubKey, Name, Smart) { CURRENCY = Currency; PUBKEY = PubKey; NAME = Name; SMART = Smart; setTimeout(function() { SendTrCreateAcc(CURRENCY, PUBKEY, NAME, 0, SMART, 0, 0); }, 50); }; function SendTrCreateAcc(Currency, PubKey, Description, Adviser, Smart, bFindAcc, bAddToPay) { var TR = GetTrCreateAcc(Currency, PubKey, Description, Adviser, Smart); var Body = GetBodyCreateAcc(TR); TR.bFindAcc = 1; if (bAddToPay) { var Item = { name: Description, To: 0, Amount: CONFIG_DATA.PRICE_DAO.NewAccount, Description: "Create acc: " + Description, Body: Body, }; AddToInvoiceList(Item); } else { SendTransaction(Body, TR); } $("idAccountName").value = ""; CancelCreateAccount(); }; function ChangeSmart(NumAccount, WasSmart) { if (!IsPrivateMode()) { SetError("Pls, open wallet"); return 0; } var Result = prompt("Enter smart number:", WasSmart); if (Result !== null && Result != WasSmart) { var Smart = parseInt(Result); if (Smart) { GetData("GetDappList", { StartNum: Smart, CountNum: 1 }, function(Data) { if (Data && Data.result && Data.arr.length === 1) { SetSmartToAccount(NumAccount, Smart); } else { SetError("Error smart number"); } }); } else { SetSmartToAccount(NumAccount, Smart); } } }; function SetSmartToAccount(NumAccount, Smart) { var OperationID = 0; var Item = MapAccounts[NumAccount]; if (Item) { OperationID = Item.Value.OperationID; } OperationID++; var TR = { Type: 140, Account: NumAccount, Smart: Smart, FromNum: NumAccount, Reserve: [], OperationID: OperationID, Sign: "", }; var Body = []; WriteByte(Body, TR.Type); WriteUint(Body, TR.Account); WriteUint32(Body, TR.Smart); WriteArr(Body, TR.Reserve, 10); WriteUint(Body, TR.FromNum); WriteUint(Body, TR.OperationID); SendTrArrayWithSign(Body, TR.Account, TR); }; function CheckLengthAccDesription(name, Length) { var Str = $(name).value.substr(0, Length + 1); var arr = toUTF8Array(Str); var Len = Length - arr.length; if (Len < 0) SetError("Bad length"); else SetStatus("Lost: " + Len + " bytes"); };