mirror of
https://github.com/transatoshi-mw/grin-web-wallet.git
synced 2025-10-07 00:02:47 +00:00
contents of zip
This commit is contained in:
593
scripts/json_rpc.js
Executable file
593
scripts/json_rpc.js
Executable file
@@ -0,0 +1,593 @@
|
||||
// Use strict
|
||||
"use strict";
|
||||
|
||||
|
||||
// Classes
|
||||
|
||||
// JSON-RPC class
|
||||
class JsonRpc {
|
||||
|
||||
// Public
|
||||
|
||||
// Send request
|
||||
static sendRequest(urlOrUrls, method, parameters = [], headers = {}, numberOfAttempts = JsonRpc.DEFAULT_NUMBER_OF_ATTEMPTS, cancelOccurred = Common.NO_CANCEL_OCCURRED) {
|
||||
|
||||
// Return promise
|
||||
return new Promise(function(resolve, reject) {
|
||||
|
||||
// Set current attempt
|
||||
var currentAttempt = new Promise(function(resolve, reject) {
|
||||
|
||||
// Resolve invalid response
|
||||
resolve(JsonRpc.INVALID_RESPONSE);
|
||||
});
|
||||
|
||||
// Initiaize attempts
|
||||
var attempts = [currentAttempt];
|
||||
|
||||
// Go through all attempts or URLs
|
||||
for(let i = 0; i < Math.max(numberOfAttempts, (Array.isArray(urlOrUrls) === true) ? urlOrUrls["length"] : [urlOrUrls]["length"]); ++i) {
|
||||
|
||||
// Set attempt that runs after the current attempt
|
||||
currentAttempt = currentAttempt.then(function(response) {
|
||||
|
||||
// Return promise
|
||||
return new Promise(function(resolve, reject) {
|
||||
|
||||
// Check if response isn't invalid
|
||||
if(response !== JsonRpc.INVALID_RESPONSE) {
|
||||
|
||||
// Resolve response
|
||||
resolve(response);
|
||||
}
|
||||
|
||||
// Otherwise
|
||||
else {
|
||||
|
||||
// Get current URL
|
||||
var currentUrl = (Array.isArray(urlOrUrls) === true) ? urlOrUrls[i % urlOrUrls["length"]] : urlOrUrls;
|
||||
|
||||
// Return sending data
|
||||
return JsonRpc.sendData(currentUrl, method, parameters, headers, JsonRpc.DEFAULT_ID, cancelOccurred).then(function(currentResponse) {
|
||||
|
||||
// Resolve current response
|
||||
resolve(currentResponse);
|
||||
|
||||
// Catch errors
|
||||
}).catch(function(error) {
|
||||
|
||||
// Check if at the last attempt, the error's response had an ok, bad request, unauthorized, forbidden, not found, unsupported media type, or payload too large status, or the response is a JSON-RPC error
|
||||
if(i === Math.max(numberOfAttempts, (Array.isArray(urlOrUrls) === true) ? urlOrUrls["length"] : [urlOrUrls]["length"]) - 1 || error === Common.HTTP_OK_STATUS || error === Common.HTTP_BAD_REQUEST_STATUS || error === Common.HTTP_UNAUTHORIZED_STATUS || error === Common.HTTP_FORBIDDEN_STATUS || error === Common.HTTP_NOT_FOUND_STATUS || error === Common.HTTP_UNSUPPORTED_MEDIA_TYPE_STATUS || error === Common.HTTP_PAYLOAD_TOO_LARGE_STATUS || Object.isObject(error) === true) {
|
||||
|
||||
// Reject error
|
||||
reject(error);
|
||||
}
|
||||
|
||||
// Otherwise
|
||||
else {
|
||||
|
||||
// Resolve invalid response
|
||||
resolve(JsonRpc.INVALID_RESPONSE);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Catch errors
|
||||
}).catch(function(error) {
|
||||
|
||||
// Return promise
|
||||
return new Promise(function(resolve, reject) {
|
||||
|
||||
// Reject error
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
|
||||
// Append current attempt to list
|
||||
attempts.push(currentAttempt);
|
||||
}
|
||||
|
||||
// Return trying all attempts
|
||||
return Promise.all(attempts).then(function(responses) {
|
||||
|
||||
// Resolve response
|
||||
resolve(responses[responses["length"] - 1]);
|
||||
|
||||
// Catch errors
|
||||
}).catch(function(error) {
|
||||
|
||||
// Reject error
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Send notification
|
||||
static sendNotification(urlOrUrls, method, parameters = [], headers = {}, numberOfAttempts = JsonRpc.DEFAULT_NUMBER_OF_ATTEMPTS, cancelOccurred = Common.NO_CANCEL_OCCURRED) {
|
||||
|
||||
// Return promise
|
||||
return new Promise(function(resolve, reject) {
|
||||
|
||||
// Set current attempt
|
||||
var currentAttempt = new Promise(function(resolve, reject) {
|
||||
|
||||
// Resolve invalid response
|
||||
resolve(JsonRpc.INVALID_RESPONSE);
|
||||
});
|
||||
|
||||
// Initiaize attempts
|
||||
var attempts = [currentAttempt];
|
||||
|
||||
// Go through all attempts or URLs
|
||||
for(let i = 0; i < Math.max(numberOfAttempts, (Array.isArray(urlOrUrls) === true) ? urlOrUrls["length"] : [urlOrUrls]["length"]); ++i) {
|
||||
|
||||
// Set attempt that runs after the current attempt
|
||||
currentAttempt = currentAttempt.then(function(response) {
|
||||
|
||||
// Return promise
|
||||
return new Promise(function(resolve, reject) {
|
||||
|
||||
// Check if response isn't invalid
|
||||
if(response !== JsonRpc.INVALID_RESPONSE) {
|
||||
|
||||
// Resolve response
|
||||
resolve(response);
|
||||
}
|
||||
|
||||
// Otherwise
|
||||
else {
|
||||
|
||||
// Get current URL
|
||||
var currentUrl = (Array.isArray(urlOrUrls) === true) ? urlOrUrls[i % urlOrUrls["length"]] : urlOrUrls;
|
||||
|
||||
// Return sending data
|
||||
return JsonRpc.sendData(currentUrl, method, parameters, headers, JsonRpc.NO_ID, cancelOccurred).then(function(currentResponse) {
|
||||
|
||||
// Resolve current response
|
||||
resolve(currentResponse);
|
||||
|
||||
// Catch errors
|
||||
}).catch(function(error) {
|
||||
|
||||
// Check if at the last attempt, the error's response had an ok, bad request, unauthorized, forbidden, not found, unsupported media type, or payload too large status, or the response is a JSON-RPC error
|
||||
if(i === Math.max(numberOfAttempts, (Array.isArray(urlOrUrls) === true) ? urlOrUrls["length"] : [urlOrUrls]["length"]) - 1 || error === Common.HTTP_OK_STATUS || error === Common.HTTP_BAD_REQUEST_STATUS || error === Common.HTTP_UNAUTHORIZED_STATUS || error === Common.HTTP_FORBIDDEN_STATUS || error === Common.HTTP_NOT_FOUND_STATUS || error === Common.HTTP_UNSUPPORTED_MEDIA_TYPE_STATUS || error === Common.HTTP_PAYLOAD_TOO_LARGE_STATUS || Object.isObject(error) === true) {
|
||||
|
||||
// Reject error
|
||||
reject(error);
|
||||
}
|
||||
|
||||
// Otherwise
|
||||
else {
|
||||
|
||||
// Resolve invalid response
|
||||
resolve(JsonRpc.INVALID_RESPONSE);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Catch errors
|
||||
}).catch(function(error) {
|
||||
|
||||
// Return promise
|
||||
return new Promise(function(resolve, reject) {
|
||||
|
||||
// Reject error
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
|
||||
// Append current attempt to list
|
||||
attempts.push(currentAttempt);
|
||||
}
|
||||
|
||||
// Return trying all attempts
|
||||
return Promise.all(attempts).then(function(responses) {
|
||||
|
||||
// Resolve response
|
||||
resolve(responses[responses["length"] - 1]);
|
||||
|
||||
// Catch errors
|
||||
}).catch(function(error) {
|
||||
|
||||
// Reject error
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Create response
|
||||
static createResponse(response, requestOrNotification, isError = false) {
|
||||
|
||||
// Check if a request is provided
|
||||
if(Object.isObject(requestOrNotification) === true && "id" in requestOrNotification === true) {
|
||||
|
||||
// Check if not error
|
||||
if(isError === false) {
|
||||
|
||||
// Return response
|
||||
return {
|
||||
|
||||
// Version
|
||||
"jsonrpc": JsonRpc.VERSION,
|
||||
|
||||
// ID
|
||||
"id": requestOrNotification["id"],
|
||||
|
||||
// Result
|
||||
"result": response
|
||||
};
|
||||
}
|
||||
|
||||
// Otherwise
|
||||
else {
|
||||
|
||||
// Return response
|
||||
return {
|
||||
|
||||
// Version
|
||||
"jsonrpc": JsonRpc.VERSION,
|
||||
|
||||
// ID
|
||||
"id": requestOrNotification["id"],
|
||||
|
||||
// Error
|
||||
"error": response
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise
|
||||
else {
|
||||
|
||||
// Return no response
|
||||
return JsonRpc.NO_RESPONSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Create error response
|
||||
static createErrorResponse(error, requestOrNotification, message = JsonRpc.DEFAULT_MESSAGE) {
|
||||
|
||||
// Check if message is default message
|
||||
if(message === JsonRpc.DEFAULT_MESSAGE) {
|
||||
|
||||
// Check error
|
||||
switch(error) {
|
||||
|
||||
// Invalid request error
|
||||
case JsonRpc.INVALID_REQUEST_ERROR:
|
||||
|
||||
// Set message
|
||||
message = Language.getDefaultTranslation('Invalid request');
|
||||
|
||||
// Break
|
||||
break;
|
||||
|
||||
// Method not found error
|
||||
case JsonRpc.METHOD_NOT_FOUND_ERROR:
|
||||
|
||||
// Set message
|
||||
message = Language.getDefaultTranslation('Method not found');
|
||||
|
||||
// Break
|
||||
break;
|
||||
|
||||
// Invalid parameters error
|
||||
case JsonRpc.INVALID_PARAMETERS_ERROR:
|
||||
|
||||
// Set message
|
||||
message = Language.getDefaultTranslation('Invalid parameters');
|
||||
|
||||
// Break
|
||||
break;
|
||||
|
||||
// Internal error error
|
||||
case JsonRpc.INTERNAL_ERROR_ERROR:
|
||||
|
||||
// Set message
|
||||
message = Language.getDefaultTranslation('Internal error');
|
||||
|
||||
// Break
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Return create response
|
||||
return JsonRpc.createResponse({
|
||||
|
||||
// Code
|
||||
"code": error,
|
||||
|
||||
// Message
|
||||
"message": message
|
||||
|
||||
}, requestOrNotification, true);
|
||||
}
|
||||
|
||||
// Is request
|
||||
static isRequest(data) {
|
||||
|
||||
// Return if data is a request
|
||||
return Object.isObject(data) === true && "jsonrpc" in data === true && data["jsonrpc"] === JsonRpc.VERSION && "id" in data === true && data["id"] instanceof BigNumber === true && data["id"].isInteger() === true && data["id"].isPositive() === true && "method" in data === true && "params" in data === true;
|
||||
}
|
||||
|
||||
// Is notification
|
||||
static isNotification(data) {
|
||||
|
||||
// Return if data is a notification
|
||||
return Object.isObject(data) === true && "jsonrpc" in data === true && data["jsonrpc"] === JsonRpc.VERSION && "id" in data === false && "method" in data === true && "params" in data === true;
|
||||
}
|
||||
|
||||
// Is error response
|
||||
static isErrorResponse(response) {
|
||||
|
||||
// Return if response is an error
|
||||
return Object.isObject(response) === true && "jsonrpc" in response === true && response["jsonrpc"] === JsonRpc.VERSION && "id" in response === true && response["id"] instanceof BigNumber === true && response["id"].isInteger() === true && response["id"].isPositive() === true && "error" in response === true && Object.isObject(response["error"]) === true && "code" in response["error"] === true;
|
||||
}
|
||||
|
||||
// No response
|
||||
static get NO_RESPONSE() {
|
||||
|
||||
// Return no response
|
||||
return null;
|
||||
}
|
||||
|
||||
// Invalid request error
|
||||
static get INVALID_REQUEST_ERROR() {
|
||||
|
||||
// Return invalid request error
|
||||
return -32600;
|
||||
}
|
||||
|
||||
// Method not found error
|
||||
static get METHOD_NOT_FOUND_ERROR() {
|
||||
|
||||
// Return method not found error
|
||||
return -32601;
|
||||
}
|
||||
|
||||
// Invalid parameters error
|
||||
static get INVALID_PARAMETERS_ERROR() {
|
||||
|
||||
// Return invalid parameters error
|
||||
return -32602;
|
||||
}
|
||||
|
||||
// Internal error error
|
||||
static get INTERNAL_ERROR_ERROR() {
|
||||
|
||||
// Return internal error error
|
||||
return -32603;
|
||||
}
|
||||
|
||||
// Default message
|
||||
static get DEFAULT_MESSAGE() {
|
||||
|
||||
// Return default message
|
||||
return null;
|
||||
}
|
||||
|
||||
// Private
|
||||
|
||||
// Send data
|
||||
static sendData(url, method, parameters, headers, id, cancelOccurred = Common.NO_CANCEL_OCCURRED) {
|
||||
|
||||
// Return promise
|
||||
return new Promise(function(resolve, reject) {
|
||||
|
||||
// Check if cancel didn't occur
|
||||
if(cancelOccurred === Common.NO_CANCEL_OCCURRED || cancelOccurred() === false) {
|
||||
|
||||
// Set data
|
||||
var data = {
|
||||
|
||||
// Version
|
||||
"jsonrpc": JsonRpc.VERSION,
|
||||
|
||||
// Method
|
||||
"method": method,
|
||||
|
||||
// Parameters
|
||||
"params": parameters
|
||||
};
|
||||
|
||||
// Check if an ID is provided
|
||||
if(id !== JsonRpc.NO_ID)
|
||||
|
||||
// Set data's ID
|
||||
data["id"] = id;
|
||||
|
||||
// Get AJAX request
|
||||
var ajaxRequest = $.ajax(url, {
|
||||
|
||||
// Data
|
||||
"data": JSONBigNumber.stringify(data),
|
||||
|
||||
// Content type
|
||||
"contentType": "application/json",
|
||||
|
||||
// Data type
|
||||
"dataType": "text",
|
||||
|
||||
// Type
|
||||
"type": "POST",
|
||||
|
||||
// Headers
|
||||
"headers": headers
|
||||
});
|
||||
|
||||
// Initialize cancel allowed
|
||||
var cancelAllowed = true;
|
||||
|
||||
// Abort if canceled
|
||||
var abortIfCanceled = function() {
|
||||
|
||||
// Check if cancel is allowed
|
||||
if(cancelAllowed === true) {
|
||||
|
||||
// Check if cancel occurred
|
||||
if(cancelOccurred !== Common.NO_CANCEL_OCCURRED && cancelOccurred() === true) {
|
||||
|
||||
// Abort AJAX request
|
||||
ajaxRequest.abort();
|
||||
}
|
||||
|
||||
// Otherwise
|
||||
else {
|
||||
|
||||
// Set timeout
|
||||
setTimeout(function() {
|
||||
|
||||
// Abort if canceled
|
||||
abortIfCanceled();
|
||||
|
||||
}, JsonRpc.AJAX_REQUEST_CANCELED_CHECK_INTERVAL_MILLISECONDS);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Abort if canceled
|
||||
abortIfCanceled();
|
||||
|
||||
// Return sending AJAX request
|
||||
return ajaxRequest.then(function(response, status, request) {
|
||||
|
||||
// Clear cancel allowed
|
||||
cancelAllowed = false;
|
||||
|
||||
// Check if a response was expected
|
||||
if(id !== JsonRpc.NO_ID) {
|
||||
|
||||
// Try
|
||||
try {
|
||||
|
||||
// Parse response as JSON
|
||||
response = JSONBigNumber.parse(response);
|
||||
}
|
||||
|
||||
// Catch errors
|
||||
catch(error) {
|
||||
|
||||
// Reject request's status
|
||||
reject(request["status"]);
|
||||
|
||||
// Return
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if response is invalid
|
||||
if(Object.isObject(response) === false)
|
||||
|
||||
// Reject request's status
|
||||
reject(request["status"]);
|
||||
|
||||
// Otherwise check if response contains an invalid version
|
||||
else if("jsonrpc" in response === false || response["jsonrpc"] !== JsonRpc.VERSION)
|
||||
|
||||
// Reject request's status
|
||||
reject(request["status"]);
|
||||
|
||||
// Otherwise check if response contains an invalid ID
|
||||
else if("id" in response === false || response["id"] instanceof BigNumber === false || response["id"].isInteger() === false || response["id"].isPositive() === false)
|
||||
|
||||
// Reject request's status
|
||||
reject(request["status"]);
|
||||
|
||||
// Otherwise check if response contains an invalid result
|
||||
else if("error" in response === true || "result" in response === false)
|
||||
|
||||
// Reject response's error or request's status
|
||||
reject(("error" in response === true) ? response["error"] : request["status"]);
|
||||
|
||||
// Otherwise
|
||||
else
|
||||
|
||||
// Resolve response's result
|
||||
resolve(response["result"]);
|
||||
}
|
||||
|
||||
// Otherwise
|
||||
else {
|
||||
|
||||
// Check if a response exists
|
||||
if(response["length"] !== 0)
|
||||
|
||||
// Reject request's status
|
||||
reject(request["status"]);
|
||||
|
||||
// Otherwise
|
||||
else
|
||||
|
||||
// Resolve
|
||||
resolve();
|
||||
}
|
||||
|
||||
// Catch errors
|
||||
}).catch(function(request) {
|
||||
|
||||
// Clear cancel allowed
|
||||
cancelAllowed = false;
|
||||
|
||||
// Reject request's status
|
||||
reject(request["status"]);
|
||||
});
|
||||
}
|
||||
|
||||
// Otherwise
|
||||
else {
|
||||
|
||||
// Reject HTTP no response status
|
||||
reject(Common.HTTP_NO_RESPONSE_STATUS);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Version
|
||||
static get VERSION() {
|
||||
|
||||
// Return version
|
||||
return "2.0";
|
||||
}
|
||||
|
||||
// Default ID
|
||||
static get DEFAULT_ID() {
|
||||
|
||||
// Return default ID
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Default number of attempts
|
||||
static get DEFAULT_NUMBER_OF_ATTEMPTS() {
|
||||
|
||||
// Return default number of attempts
|
||||
return 5;
|
||||
}
|
||||
|
||||
// Invalid response
|
||||
static get INVALID_RESPONSE() {
|
||||
|
||||
// Return invalid response
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// No ID
|
||||
static get NO_ID() {
|
||||
|
||||
// Return no ID
|
||||
return null;
|
||||
}
|
||||
|
||||
// AJAX request canceled check interval milliseconds
|
||||
static get AJAX_REQUEST_CANCELED_CHECK_INTERVAL_MILLISECONDS() {
|
||||
|
||||
// Return AJAX request canceled check interval milliseconds
|
||||
return 50;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Main function
|
||||
|
||||
// Set global object's JSON-RPC
|
||||
globalThis["JsonRpc"] = JsonRpc;
|
Reference in New Issue
Block a user