public IEnumerator Process(Block block, BlockType blockType, Action <string> callback) { yield return(rpc.Process(block, NanoUtils.GetBlockTypeStr(blockType), (response) => { callback(JsonUtility.FromJson <ProcessResponse>(response).hash); })); }
/** * Creates a NanoAmount from a given {@code raw} value. * * @param rawValue the raw value */ public NanoAmount(string rawValue) { if (NanoUtils.ValidateRaw(rawValue)) { this.rawValue = BigInteger.Parse(rawValue); } }
public IEnumerator WorkGenerate(string address, string previous, Action <string> callback) { var hashForWork = previous == null?NanoUtils.AddressToPublicKeyHexString(address) : previous; yield return(rpc.WorkGenerate(hashForWork, (response) => { callback(JsonUtility.FromJson <WorkGenerateResponse>(response).work); })); }
public IEnumerator Send(string toAddress, NanoAmount amount, string privateKey, string work, Action <bool, string> callback) { // First we get the frontier NanoAmount currentBalance = null; string previous = null; string rep = defaultRep; string fromAddress = NanoUtils.PrivateKeyToAddress(privateKey); yield return(AccountInfo(fromAddress, (accountInfo) => { currentBalance = new NanoAmount(accountInfo.balance); previous = accountInfo.frontier; rep = accountInfo.representative; })); if (previous != null) { if (String.IsNullOrEmpty(work)) { // Generate the work yield return(WorkGenerate(fromAddress, previous, (workResponse) => { work = workResponse; })); } if (!String.IsNullOrEmpty(work)) { // Create the block to send var newBalance = currentBalance - amount; var block = CreateBlock(fromAddress, NanoUtils.HexStringToByteArray(privateKey), newBalance, NanoUtils.AddressToPublicKeyHexString(toAddress), previous, rep, work); yield return(Process(block, BlockType.send, (hash) => { if (hash != null) { callback(false, hash); } else { callback(true, ""); } Debug.Log(hash); })); } else { callback(true, ""); Debug.Log("Invalid work"); } } else { callback(true, ""); Debug.Log("No account exists to send from"); } }
public IEnumerator Receive(string address, PendingBlock pendingBlock, string privateKey, string work, Action <bool, string> callback) { // First we get the frontier NanoAmount currentBalance = null; string previous = null; var rep = defaultRep; yield return(AccountInfo(address, (accountInfo) => { currentBalance = new NanoAmount(accountInfo.balance); previous = accountInfo.frontier; if (previous != null) { rep = accountInfo.representative; } })); if (String.IsNullOrEmpty(work)) { // Generate the work yield return(WorkGenerate(address, previous, (workResponse) => { work = workResponse; })); } if (!String.IsNullOrEmpty(work)) { // Create the block to receive var newBalance = currentBalance + pendingBlock.amount; var block = CreateBlock(address, NanoUtils.HexStringToByteArray(privateKey), newBalance, pendingBlock.source, previous, rep, work); yield return(Process(block, previous == null ? BlockType.open : BlockType.receive, (hash) => { if (hash != null) { callback(false, hash); } else { callback(true, ""); } Debug.Log(hash); })); } else { callback(true, ""); } }
public Block CreateBlock(string address, byte[] privateKey, NanoAmount balance, string link, string previous, string rep, string work) { Block block = new Block(); block.account = address; block.balance = balance.ToString(); block.link = link; block.previous = previous == null ? "0000000000000000000000000000000000000000000000000000000000000000" : previous; block.representative = rep; // Sign the block var hash = NanoUtils.HashStateBlock(address, block.previous, balance.ToString(), rep, link); var signature = NanoUtils.SignHash(hash, privateKey); block.signature = signature; block.work = work; return(block); }
public async void UnregisterAccount(string address) { int count; var publicKey = NanoUtils.AddressToPublicKeyHexString(address); if (registeredAccounts.TryGetValue(publicKey, out count)) { registeredAccounts[publicKey]--; } else { registeredAccounts.Remove(publicKey); if (websocket == null || websocket.State != WebSocketState.Open) { return; } AccountRegisterRequest request = new AccountRegisterRequest(); request.account = address; request.action = "unregister_account"; await websocket.SendText(JsonUtility.ToJson(request)); } }
public async void RegisterAccount(String address) { int count; var publicKey = NanoUtils.AddressToPublicKeyHexString(address); if (registeredAccounts.TryGetValue(publicKey, out count)) { registeredAccounts[publicKey]++; } else { registeredAccounts[publicKey] = 1; if (websocket == null || websocket.State != WebSocketState.Open) { // Don't send if we're not connected. return; } AccountRegisterRequest request = new AccountRegisterRequest(); request.account = address; request.action = "register_account"; await websocket.SendText(JsonUtility.ToJson(request)); } }
// Start is called before the first frame update async void Start() { websocket = new WebSocket(url); websocket.OnOpen += async() => { Debug.Log("Connection open!"); if (isListeningAll) { ListenAll(); } foreach (var registeredAccount in registeredAccounts) { AccountRegisterRequest request = new AccountRegisterRequest { account = NanoUtils.PublicKeyToAddress(registeredAccount.Key), action = "register_account" }; await websocket.SendText(JsonUtility.ToJson(request)); } foreach (var del in openDelegates) { del(false, isReconnection); } }; websocket.OnError += (e) => { foreach (var del in openDelegates) { del(true, isReconnection); } Debug.Log("Error! " + e); }; websocket.OnClose += (e) => { Debug.Log("Connection closed!"); }; websocket.OnMessage += (bytes) => { var json = System.Text.Encoding.UTF8.GetString(bytes); // Confirmation var websocketConfirmationResponseData = JsonUtility.FromJson <WebsocketConfirmationResponseData>(json); if (websocketConfirmationResponseData.is_filtered) { foreach (var del in filteredConfirmationDelegates) { del(websocketConfirmationResponseData); } } else { foreach (var del in confirmationDelegates) { del(websocketConfirmationResponseData); } } Debug.Log("Received OnMessage! (" + bytes.Length + " bytes) " + json); }; await websocket.Connect(); }
/** * Returns the value of this amount in the standard base unit ({@link NanoUnit#BASE_UNIT}). * * @return the value, in the base unit */ public string getAsNano() { return(NanoUtils.RawToNano(ToString())); }
// Only call this once... public void SetupFilteredConfirmationMessageWebsocketListener() { if (websocket != null) { AddFilteredConfirmationListener((websocketConfirmationResponseData) => { // Need to determine if it's: // 1 - Send to an account we are watching (we need to check pending, and fire off a loop to get these blocks (highest amount // first), if above a certain amount) // 2 - Send from an account we are watching (our balance goes down, check account_info) // 3 - Receive (pocket) an account we are watching (no need to check pending, but need to check balance. But this could be an old // block, so need to check account_info balance) // We could be monitoring multiple accounts which may be interacting with each other so need to check all if (websocketConfirmationResponseData.message.block.subtype.Equals(NanoUtils.GetBlockTypeStr(BlockType.send))) { var linkAsAccount = websocketConfirmationResponseData.message.block.link_as_account; if (watchers.ContainsKey(linkAsAccount)) { // Invoke callbacks foreach (var val in watchers[linkAsAccount]) { val.Value(new WatcherInfo(new NanoAmount(websocketConfirmationResponseData.message.amount), ConfType.SendTo, websocketConfirmationResponseData.message.hash)); } } var address = websocketConfirmationResponseData.message.block.account; if (watchers.ContainsKey(address)) { // Invoke callbacks foreach (var val in watchers[address]) { val.Value(new WatcherInfo(new NanoAmount(websocketConfirmationResponseData.message.amount), ConfType.SendFrom, websocketConfirmationResponseData.message.hash)); } } // Check for payment if (listeningPayment.callback != null) { if (listeningPayment.address.Equals(linkAsAccount) && listeningPayment.amount.Equals(new NanoAmount(websocketConfirmationResponseData.message.amount)) || (!listeningPayment.exactAmount && listeningPayment.amount > new NanoAmount(websocketConfirmationResponseData.message.amount))) { Unwatch(listeningPayment.address, listeningPayment.watcherId); listeningPayment.callback(false); listeningPayment.callback = null; } } // Check for payout if (listeningPayout.callback != null) { if (listeningPayout.address.Equals(address) && websocketConfirmationResponseData.message.block.balance.Equals("0")) { Unwatch(listeningPayout.address, listeningPayout.watcherId); listeningPayout.callback(false); listeningPayout.callback = null; } } } else if ((websocketConfirmationResponseData.message.block.subtype.Equals(NanoUtils.GetBlockTypeStr(BlockType.receive))) || (websocketConfirmationResponseData.message.block.subtype.Equals(NanoUtils.GetBlockTypeStr(BlockType.open)))) { var account = websocketConfirmationResponseData.message.account; if (watchers.ContainsKey(account)) { // Invoke callbacks foreach (var val in watchers[account]) { val.Value(new WatcherInfo(new NanoAmount(websocketConfirmationResponseData.message.amount), ConfType.Receive, websocketConfirmationResponseData.message.hash)); } } } if (blockListener.ContainsKey(websocketConfirmationResponseData.message.hash)) { blockListener[websocketConfirmationResponseData.message.hash](false, websocketConfirmationResponseData.message.hash); blockListener.Remove(websocketConfirmationResponseData.message.hash); } }); } else { Debug.Log("Websocket must be initialised before calling SetupConfirmationListener"); } }