Esempio n. 1
0
        private DataNode ValidateRequest(string[] args)
        {
            if (args.Length >= 3)
            {
                string dapp  = args[args.Length - 2];
                string token = args[args.Length - 1];

                if (authTokens.ContainsKey(dapp))
                {
                    if (authTokens[dapp] == token)
                    {
                        return(null);
                    }
                }
            }

            return(APIUtils.FromAPIResult(new Error()
            {
                message = "Invalid or missing API token"
            }));
        }
Esempio n. 2
0
        public void Execute(string cmd, Action <int, DataNode, bool> callback)
        {
            var args = cmd.Split(',');

            DataNode root;

            int id = 0;

            if (int.TryParse(args[0], out id))
            {
            }

            if (args.Length != 2)
            {
                root = APIUtils.FromAPIResult(new Error()
                {
                    message = "Malformed request"
                });
                callback(id, root, false);
                return;
            }

            cmd  = args[1];
            args = cmd.Split('/');

            bool success = false;

            var requestType = args[0];

            if (requestType != "authorize")
            {
                var status = this.Status;
                if (status != WalletStatus.Ready)
                {
                    root = APIUtils.FromAPIResult(new Error()
                    {
                        message = $"Wallet is {status}"
                    });
                    callback(id, root, false);
                    return;
                }
            }

            if (_isPendingRequest)
            {
                root = APIUtils.FromAPIResult(new Error()
                {
                    message = $"A previouus request is still pending"
                });
                callback(id, root, false);
                return;
            }

            _isPendingRequest = true;

            switch (requestType)
            {
            case "authorize":
            {
                if (args.Length == 2)
                {
                    string token;
                    var    dapp = args[1];

                    if (authTokens.ContainsKey(dapp))
                    {
                        token   = authTokens[dapp];
                        success = true;
                        root    = APIUtils.FromAPIResult(new Authorization()
                            {
                                wallet = this.Name, dapp = dapp, token = token
                            });
                    }
                    else
                    {
                        this.Authorize(dapp, (authorized, error) =>
                            {
                                if (authorized)
                                {
                                    var bytes = new byte[32];
                                    rnd.NextBytes(bytes);
                                    token            = Base16.Encode(bytes);
                                    authTokens[dapp] = token;

                                    success = true;
                                    root    = APIUtils.FromAPIResult(new Authorization()
                                    {
                                        wallet = this.Name, dapp = dapp, token = token
                                    });
                                }
                                else
                                {
                                    root = APIUtils.FromAPIResult(new Error()
                                    {
                                        message = error
                                    });
                                }

                                callback(id, root, success);
                                _isPendingRequest = false;
                            });

                        return;
                    }
                }
                else
                {
                    root = APIUtils.FromAPIResult(new Error()
                        {
                            message = $"authorize: Invalid amount of arguments: {args.Length} instead of 2"
                        });
                }

                break;
            }

            case "getAccount":
            {
                root = ValidateRequest(args);
                if (root == null)
                {
                    var account = this.GetAccount();
                    root = APIUtils.FromAPIResult(account);

                    success = true;
                }

                break;
            }

            case "signTx":
            {
                root = ValidateRequest(args);
                if (root == null)
                {
                    if (args.Length == 7)
                    {
                        var    nexus   = args[1];
                        var    chain   = args[2];
                        var    script  = Base16.Decode(args[3]);
                        byte[] payload = args[4].Length > 0 ? Base16.Decode(args[4]) : null;

                        SignTransaction(nexus, chain, script, payload, id, (hash, txError) => {
                                if (hash != Hash.Null)
                                {
                                    success = true;
                                    root    = APIUtils.FromAPIResult(new Transaction()
                                    {
                                        hash = hash.ToString()
                                    });
                                }
                                else
                                {
                                    root = APIUtils.FromAPIResult(new Error()
                                    {
                                        message = txError
                                    });
                                }

                                callback(id, root, success);
                                _isPendingRequest = false;
                            });

                        return;
                    }
                    else
                    {
                        root = APIUtils.FromAPIResult(new Error()
                            {
                                message = $"signTx: Invalid amount of arguments: {args.Length} instead of 7"
                            });
                    }
                }
                break;
            }

            case "invokeScript":
            {
                root = ValidateRequest(args);
                if (root == null)
                {
                    if (args.Length == 4)
                    {
                        var script = Base16.Decode(args[1]);

                        InvokeScript(script, id, (invokeResult, invokeError) =>
                            {
                                if (invokeResult != null)
                                {
                                    success = true;
                                    root    = APIUtils.FromAPIResult(new Invocation()
                                    {
                                        result = Base16.Encode(invokeResult)
                                    });
                                }
                                else
                                {
                                    root = APIUtils.FromAPIResult(new Error()
                                    {
                                        message = invokeError
                                    });
                                }

                                callback(id, root, success);
                                _isPendingRequest = false;
                            });
                        return;
                    }
                    else
                    {
                        root = APIUtils.FromAPIResult(new Error()
                            {
                                message = $"invokeScript: Invalid amount of arguments: {args.Length} instead of 4"
                            });
                    }
                }
                break;
            }

            default:
                root = APIUtils.FromAPIResult(new Error()
                {
                    message = "Invalid request type"
                });
                break;
            }

            callback(id, root, success);
            _isPendingRequest = false;
        }
Esempio n. 3
0
        public void Execute(string cmd, Action <int, DataNode, bool> callback)
        {
            var args = cmd.Split(',');

            DataNode root;

            int id = 0;

            if (int.TryParse(args[0], out id))
            {
            }

            if (args.Length != 2)
            {
                root = APIUtils.FromAPIResult(new Error()
                {
                    message = "Malformed request"
                });
                callback(id, root, false);
                return;
            }

            cmd  = args[1];
            args = cmd.Split('/');

            bool success = false;

            var requestType = args[0];

            if (requestType != "authorize")
            {
                var status = this.Status;
                if (status != WalletStatus.Ready)
                {
                    root = APIUtils.FromAPIResult(new Error()
                    {
                        message = $"Wallet is {status}"
                    });
                    callback(id, root, false);
                    return;
                }
            }

            switch (requestType)
            {
            case "authorize":
            {
                if (args.Length == 2)
                {
                    string token;
                    var    dapp = args[1];

                    if (authTokens.ContainsKey(dapp))
                    {
                        token = authTokens[dapp];
                    }
                    else
                    {
                        var bytes = new byte[32];
                        rnd.NextBytes(bytes);
                        token            = Base16.Encode(bytes);
                        authTokens[dapp] = token;
                    }

                    success = true;
                    root    = APIUtils.FromAPIResult(new Authorization()
                        {
                            wallet = this.Name, dapp = dapp, token = token
                        });
                }
                else
                {
                    root = APIUtils.FromAPIResult(new Error()
                        {
                            message = "Invalid amount of arguments"
                        });
                }

                break;
            }

            case "getAccount":
            {
                root = ValidateRequest(args);
                if (root == null)
                {
                    var account = this.GetAccount();
                    root = APIUtils.FromAPIResult(account);

                    success = true;
                }

                break;
            }

            case "signTx":
            {
                root = ValidateRequest(args);
                if (root == null)
                {
                    if (args.Length == 3)
                    {
                        var script = args[1];

                        SignTransaction(script, id, callback);
                        return;
                    }
                    else
                    {
                        root = APIUtils.FromAPIResult(new Error()
                            {
                                message = "Invalid amount of arguments"
                            });
                    }
                }
                break;
            }

            case "invokeScript":
            {
                root = ValidateRequest(args);
                if (root == null)
                {
                    if (args.Length == 3)
                    {
                        var script = args[1];

                        InvokeScript(script, id, callback);
                        return;
                    }
                    else
                    {
                        root = APIUtils.FromAPIResult(new Error()
                            {
                                message = "Invalid amount of arguments"
                            });
                    }
                }
                break;
            }

            default:
                root = APIUtils.FromAPIResult(new Error()
                {
                    message = "Invalid request type"
                });
                break;
            }

            callback(id, root, success);
        }
Esempio n. 4
0
        public void Execute(string cmd, Action <int, DataNode, bool> callback)
        {
            var args = cmd.Split(',');

            DataNode answer;

            int id = 0;

            if (!int.TryParse(args[0], out id))
            {
                answer = APIUtils.FromAPIResult(new Error()
                {
                    message = "Invalid request id"
                });
                callback(id, answer, false);
                return;
            }

            if (args.Length != 2)
            {
                answer = APIUtils.FromAPIResult(new Error()
                {
                    message = "Malformed request"
                });
                callback(id, answer, false);
                return;
            }

            cmd  = args[1];
            args = cmd.Split('/');

            bool success = false;

            var requestType = args[0];

            if (requestType != "authorize")
            {
                var status = this.Status;
                if (status != WalletStatus.Ready)
                {
                    answer = APIUtils.FromAPIResult(new Error()
                    {
                        message = $"Wallet is {status}"
                    });
                    callback(id, answer, false);
                    return;
                }
            }

            if (_isPendingRequest)
            {
                answer = APIUtils.FromAPIResult(new Error()
                {
                    message = $"A previous request is still pending"
                });
                callback(id, answer, false);
                return;
            }

            _isPendingRequest = true;

            switch (requestType)
            {
            case "version":
            {
                answer = APIUtils.FromAPIResult(new Invocation()
                    {
                        result = LinkProtocol.ToString()
                    });
                success = true;
                break;
            }

            case "authorize":
            {
                if (args.Length == 2)
                {
                    string token;
                    var    dapp = args[1];

                    if (authTokens.ContainsKey(dapp))
                    {
                        token   = authTokens[dapp];
                        success = true;
                        answer  = APIUtils.FromAPIResult(new Authorization()
                            {
                                wallet = this.Name, nexus = this.Nexus, dapp = dapp, token = token
                            });
                    }
                    else
                    {
                        var bytes = new byte[32];
                        rnd.NextBytes(bytes);
                        token = Base16.Encode(bytes);

                        this.Authorize(dapp, token, (authorized, error) =>
                            {
                                if (authorized)
                                {
                                    authTokens[dapp] = token;

                                    success = true;
                                    answer  = APIUtils.FromAPIResult(new Authorization()
                                    {
                                        wallet = this.Name, nexus = this.Nexus, dapp = dapp, token = token
                                    });
                                }
                                else
                                {
                                    answer = APIUtils.FromAPIResult(new Error()
                                    {
                                        message = error
                                    });
                                }

                                callback(id, answer, success);
                                _isPendingRequest = false;
                            });

                        return;
                    }
                }
                else
                {
                    answer = APIUtils.FromAPIResult(new Error()
                        {
                            message = $"authorize: Invalid amount of arguments: {args.Length} instead of 2"
                        });
                }

                break;
            }

            case "getAccount":
            {
                answer = ValidateRequest(args);
                if (answer == null)
                {
                    var account = this.GetAccount();
                    answer = APIUtils.FromAPIResult(account);

                    success = true;
                }

                break;
            }

            case "signData":
            {
                answer = ValidateRequest(args);
                if (answer == null)
                {
                    if (args.Length == 5)
                    {
                        var data = Base16.Decode(args[1], false);
                        if (data == null)
                        {
                            answer = APIUtils.FromAPIResult(new Error()
                                {
                                    message = $"signTx: Invalid input received"
                                });
                        }
                        else
                        {
                            var signatureKind = (SignatureKind)Enum.Parse(typeof(SignatureKind), args[2], true);

                            SignData(data, signatureKind, id, (signature, random, txError) => {
                                    if (signature != null)
                                    {
                                        success = true;
                                        answer  = APIUtils.FromAPIResult(new Signature()
                                        {
                                            signature = signature, random = random
                                        });
                                    }
                                    else
                                    {
                                        answer = APIUtils.FromAPIResult(new Error()
                                        {
                                            message = txError
                                        });
                                    }

                                    callback(id, answer, success);
                                    _isPendingRequest = false;
                                });
                        }

                        return;
                    }
                    else
                    {
                        answer = APIUtils.FromAPIResult(new Error()
                            {
                                message = $"signTx: Invalid amount of arguments: {args.Length} instead of 5"
                            });
                    }
                }
                break;
            }

            case "signTx":
            {
                answer = ValidateRequest(args);
                if (answer == null)
                {
                    if (args.Length == 7)
                    {
                        var nexus = args[1];
                        if (nexus == this.Nexus)
                        {
                            args = args.Skip(1).ToArray();
                        }
                        else
                        {
                            answer = APIUtils.FromAPIResult(new Error()
                                {
                                    message = $"signTx: Invalid nexus: '{nexus}' expected '{this.Nexus}' instead"
                                });
                            break;
                        }
                    }

                    if (args.Length == 6)
                    {
                        var chain  = args[1];
                        var script = Base16.Decode(args[2], false);

                        if (script == null)
                        {
                            answer = APIUtils.FromAPIResult(new Error()
                                {
                                    message = $"signTx: Invalid script data"
                                });
                        }
                        else
                        {
                            byte[] payload = args[4].Length > 0 ? Base16.Decode(args[4], false) : null;

                            SignTransaction(chain, script, payload, id, (hash, txError) => {
                                    if (hash != Hash.Null)
                                    {
                                        success = true;
                                        answer  = APIUtils.FromAPIResult(new Transaction()
                                        {
                                            hash = hash.ToString()
                                        });
                                    }
                                    else
                                    {
                                        answer = APIUtils.FromAPIResult(new Error()
                                        {
                                            message = txError
                                        });
                                    }

                                    callback(id, answer, success);
                                    _isPendingRequest = false;
                                });
                        }

                        return;
                    }
                    else
                    {
                        answer = APIUtils.FromAPIResult(new Error()
                            {
                                message = $"signTx: Invalid amount of arguments: {args.Length} instead of 7"
                            });
                    }
                }
                break;
            }

            case "invokeScript":
            {
                answer = ValidateRequest(args);
                if (answer == null)
                {
                    if (args.Length == 4)
                    {
                        var script = Base16.Decode(args[1], false);

                        if (script == null)
                        {
                            answer = APIUtils.FromAPIResult(new Error()
                                {
                                    message = $"signTx: Invalid script data"
                                });
                        }
                        else
                        {
                            InvokeScript(script, id, (invokeResult, invokeError) =>
                                {
                                    if (invokeResult != null)
                                    {
                                        success = true;
                                        answer  = APIUtils.FromAPIResult(new Invocation()
                                        {
                                            result = Base16.Encode(invokeResult)
                                        });
                                    }
                                    else
                                    {
                                        answer = APIUtils.FromAPIResult(new Error()
                                        {
                                            message = invokeError
                                        });
                                    }

                                    callback(id, answer, success);
                                    _isPendingRequest = false;
                                });
                            return;
                        }
                    }
                    else
                    {
                        answer = APIUtils.FromAPIResult(new Error()
                            {
                                message = $"invokeScript: Invalid amount of arguments: {args.Length} instead of 4"
                            });
                    }
                }
                break;
            }

            case "writeArchive":
            {
                answer = ValidateRequest(args);
                if (answer == null)
                {
                    if (args.Length == 6)
                    {
                        var archiveHash = Hash.Parse(args[1]);
                        var blockIndex  = int.Parse(args[2]);
                        var bytes       = Base16.Decode(args[3], false);

                        if (bytes == null)
                        {
                            answer = APIUtils.FromAPIResult(new Error()
                                {
                                    message = $"invokeScript: Invalid archive data"
                                });
                        }
                        else
                        {
                            WriteArchive(archiveHash, blockIndex, bytes, (result, error) =>
                                {
                                    if (result)
                                    {
                                        success = true;
                                        answer  = APIUtils.FromAPIResult(new Transaction()
                                        {
                                            hash = archiveHash.ToString()
                                        });
                                    }
                                    else
                                    {
                                        answer = APIUtils.FromAPIResult(new Error()
                                        {
                                            message = error
                                        });
                                    }

                                    callback(id, answer, success);
                                    _isPendingRequest = false;
                                });
                        }

                        return;
                    }
                    else
                    {
                        answer = APIUtils.FromAPIResult(new Error()
                            {
                                message = $"invokeScript: Invalid amount of arguments: {args.Length} instead of 6"
                            });
                    }
                }
                break;
            }

            default:
                answer = APIUtils.FromAPIResult(new Error()
                {
                    message = "Invalid request type"
                });
                break;
            }

            callback(id, answer, success);
            _isPendingRequest = false;
        }
Esempio n. 5
0
        public void Execute(string cmd, Action <int, DataNode, bool> callback)
        {
            var args = cmd.Split(',');

            DataNode answer;

            int id = 0;

            if (!int.TryParse(args[0], out id))
            {
                answer = APIUtils.FromAPIResult(new Error()
                {
                    message = "Invalid request id"
                });
                callback(id, answer, false);
                return;
            }

            if (args.Length != 2)
            {
                answer = APIUtils.FromAPIResult(new Error()
                {
                    message = "Malformed request"
                });
                callback(id, answer, false);
                return;
            }

            cmd  = args[1];
            args = cmd.Split('/');

            bool success = false;

            var requestType = args[0];

            if (requestType != "authorize")
            {
                var status = this.Status;
                if (status != WalletStatus.Ready)
                {
                    answer = APIUtils.FromAPIResult(new Error()
                    {
                        message = $"Wallet is {status}"
                    });
                    callback(id, answer, false);
                    return;
                }
            }

            if (_isPendingRequest)
            {
                answer = APIUtils.FromAPIResult(new Error()
                {
                    message = $"A previous request is still pending"
                });
                callback(id, answer, false);
                return;
            }

            _isPendingRequest = true;

            Connection connection = null;

            if (requestType != "authorize")
            {
                connection = ValidateRequest(args);
                if (connection == null)
                {
                    answer = APIUtils.FromAPIResult(new Error()
                    {
                        message = "Invalid or missing API token"
                    });
                    callback(id, answer, false);
                    return;
                }

                // exclude dapp/token args
                args = args.Take(args.Length - 2).ToArray();
            }

            args = args.Skip(1).ToArray();

            switch (requestType)
            {
            case "authorize":
            {
                if (args.Length == 1 || args.Length == 2)
                {
                    string token;
                    var    dapp = args[0];

                    int version;

                    if (args.Length == 2)
                    {
                        var str = args[1];
                        if (!int.TryParse(str, out version))
                        {
                            answer = APIUtils.FromAPIResult(new Error()
                                {
                                    message = $"authorize: Invalid version: {str}"
                                });
                            callback(id, answer, false);
                            _isPendingRequest = false;
                            return;
                        }
                    }
                    else
                    {
                        version = 1;
                    }

                    if (_connections.ContainsKey(dapp))
                    {
                        connection = _connections[dapp];
                        success    = true;
                        answer     = APIUtils.FromAPIResult(new Authorization()
                            {
                                wallet = this.Name, nexus = this.Nexus, dapp = dapp, token = connection.Token, version = connection.Version
                            });
                    }
                    else
                    {
                        var bytes = new byte[32];
                        rnd.NextBytes(bytes);
                        token = Base16.Encode(bytes);

                        this.Authorize(dapp, token, version, (authorized, error) =>
                            {
                                if (authorized)
                                {
                                    _connections[dapp] = new Connection(token, version);

                                    success = true;
                                    answer  = APIUtils.FromAPIResult(new Authorization()
                                    {
                                        wallet = this.Name, nexus = this.Nexus, dapp = dapp, token = token
                                    });
                                }
                                else
                                {
                                    answer = APIUtils.FromAPIResult(new Error()
                                    {
                                        message = error
                                    });
                                }

                                callback(id, answer, success);
                                _isPendingRequest = false;
                            });

                        return;
                    }
                }
                else
                {
                    answer = APIUtils.FromAPIResult(new Error()
                        {
                            message = $"authorize: Invalid amount of arguments: {args.Length}"
                        });
                }

                break;
            }

            case "getAccount":
            {
                int expectedLength;

                switch (connection.Version)
                {
                case 1:
                    expectedLength = 0;
                    break;

                default:
                    expectedLength = 1;
                    break;
                }

                if (args.Length == expectedLength)
                {
                    string platform;

                    if (connection.Version >= 2)
                    {
                        platform = args[0].ToLower();
                    }
                    else
                    {
                        platform = "phantasma";
                    }

                    GetAccount(platform, (account, error) => {
                            if (error == null)
                            {
                                success = true;
                                answer  = APIUtils.FromAPIResult(account);
                            }
                            else
                            {
                                answer = APIUtils.FromAPIResult(new Error()
                                {
                                    message = error
                                });
                            }

                            callback(id, answer, success);
                            _isPendingRequest = false;
                        });

                    return;
                }
                else
                {
                    answer = APIUtils.FromAPIResult(new Error()
                        {
                            message = $"getAccount: Invalid amount of arguments: {args.Length}"
                        });
                }

                break;
            }

            case "signData":
            {
                int expectedLength;

                switch (connection.Version)
                {
                case 1:
                    expectedLength = 2;
                    break;

                default:
                    expectedLength = 3;
                    break;
                }

                if (args.Length == expectedLength)
                {
                    var data = Base16.Decode(args[0], false);
                    if (data == null)
                    {
                        answer = APIUtils.FromAPIResult(new Error()
                            {
                                message = $"signTx: Invalid input received"
                            });
                    }
                    else
                    {
                        SignatureKind signatureKind;

                        if (!Enum.TryParse <SignatureKind>(args[1], out signatureKind))
                        {
                            answer = APIUtils.FromAPIResult(new Error()
                                {
                                    message = $"signData: Invalid signature: " + args[1]
                                });
                            callback(id, answer, false);
                            _isPendingRequest = false;
                            return;
                        }

                        var platform = connection.Version >= 2 ? args[2].ToLower() : "phantasma";

                        SignData(platform, signatureKind, data, id, (signature, random, txError) => {
                                if (signature != null)
                                {
                                    success = true;
                                    answer  = APIUtils.FromAPIResult(new Signature()
                                    {
                                        signature = signature, random = random
                                    });
                                }
                                else
                                {
                                    answer = APIUtils.FromAPIResult(new Error()
                                    {
                                        message = txError
                                    });
                                }

                                callback(id, answer, success);
                                _isPendingRequest = false;
                            });
                    }

                    return;
                }
                else
                {
                    answer = APIUtils.FromAPIResult(new Error()
                        {
                            message = $"signTx: Invalid amount of arguments: {args.Length}"
                        });
                }
                break;
            }

            case "signTx":
            {
                int expectedLength;

                switch (connection.Version)
                {
                case 1:
                    expectedLength = 4;
                    break;

                default:
                    expectedLength = 5;
                    break;
                }

                if (args.Length == expectedLength)
                {
                    int index = 0;

                    if (connection.Version == 1)
                    {
                        var txNexus = args[index]; index++;
                        if (txNexus != this.Nexus)
                        {
                            answer = APIUtils.FromAPIResult(new Error()
                                {
                                    message = $"signTx: Expected nexus {this.Nexus}, instead got {txNexus}"
                                });
                            callback(id, answer, false);
                            _isPendingRequest = false;
                            return;
                        }
                    }

                    var chain  = args[index]; index++;
                    var script = Base16.Decode(args[index], false); index++;

                    if (script == null)
                    {
                        answer = APIUtils.FromAPIResult(new Error()
                            {
                                message = $"signTx: Invalid script data"
                            });
                    }
                    else
                    {
                        byte[] payload = args[index].Length > 0 ? Base16.Decode(args[index], false) : null;
                        index++;

                        string        platform;
                        SignatureKind signatureKind;

                        if (connection.Version >= 2)
                        {
                            if (!Enum.TryParse <SignatureKind>(args[index], out signatureKind))
                            {
                                answer = APIUtils.FromAPIResult(new Error()
                                    {
                                        message = $"signTx: Invalid signature: " + args[index]
                                    });
                                callback(id, answer, false);
                                _isPendingRequest = false;
                                return;
                            }
                            index++;

                            platform = args[index].ToLower();
                            index++;
                        }
                        else
                        {
                            platform      = "phantasma";
                            signatureKind = SignatureKind.Ed25519;
                        }

                        SignTransaction(platform, signatureKind, chain, script, payload, id, (hash, txError) => {
                                if (hash != Hash.Null)
                                {
                                    success = true;
                                    answer  = APIUtils.FromAPIResult(new Transaction()
                                    {
                                        hash = hash.ToString()
                                    });
                                }
                                else
                                {
                                    answer = APIUtils.FromAPIResult(new Error()
                                    {
                                        message = txError
                                    });
                                }

                                callback(id, answer, success);
                                _isPendingRequest = false;
                            });
                    }

                    return;
                }
                else
                {
                    answer = APIUtils.FromAPIResult(new Error()
                        {
                            message = $"signTx: Invalid amount of arguments: {args.Length}"
                        });
                }
                break;
            }

            case "invokeScript":
            {
                if (args.Length == 2)
                {
                    var chain  = args[0];
                    var script = Base16.Decode(args[1], false);

                    if (script == null)
                    {
                        answer = APIUtils.FromAPIResult(new Error()
                            {
                                message = $"signTx: Invalid script data"
                            });
                    }
                    else
                    {
                        InvokeScript(chain, script, id, (invokeResult, invokeError) =>
                            {
                                if (invokeResult != null)
                                {
                                    success = true;
                                    answer  = APIUtils.FromAPIResult(new Invocation()
                                    {
                                        result = Base16.Encode(invokeResult)
                                    });
                                }
                                else
                                {
                                    answer = APIUtils.FromAPIResult(new Error()
                                    {
                                        message = invokeError
                                    });
                                }

                                callback(id, answer, success);
                                _isPendingRequest = false;
                            });
                        return;
                    }
                }
                else
                {
                    answer = APIUtils.FromAPIResult(new Error()
                        {
                            message = $"invokeScript: Invalid amount of arguments: {args.Length}"
                        });
                }

                break;
            }

            case "writeArchive":
            {
                if (args.Length == 3)
                {
                    var archiveHash = Hash.Parse(args[0]);
                    var blockIndex  = int.Parse(args[1]);
                    var bytes       = Base16.Decode(args[2], false);

                    if (bytes == null)
                    {
                        answer = APIUtils.FromAPIResult(new Error()
                            {
                                message = $"invokeScript: Invalid archive data"
                            });
                    }
                    else
                    {
                        WriteArchive(archiveHash, blockIndex, bytes, (result, error) =>
                            {
                                if (result)
                                {
                                    success = true;
                                    answer  = APIUtils.FromAPIResult(new Transaction()
                                    {
                                        hash = archiveHash.ToString()
                                    });
                                }
                                else
                                {
                                    answer = APIUtils.FromAPIResult(new Error()
                                    {
                                        message = error
                                    });
                                }

                                callback(id, answer, success);
                                _isPendingRequest = false;
                            });
                    }

                    return;
                }
                else
                {
                    answer = APIUtils.FromAPIResult(new Error()
                        {
                            message = $"writeArchive: Invalid amount of arguments: {args.Length}"
                        });
                }

                break;
            }

            default:
                answer = APIUtils.FromAPIResult(new Error()
                {
                    message = "Invalid request type"
                });
                break;
            }

            callback(id, answer, success);
            _isPendingRequest = false;
        }