Delete obsolete code
Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
This commit is contained in:
parent
c5771f3168
commit
9b990a8038
|
@ -1,525 +0,0 @@
|
||||||
var jsSuggestionContainerStyle = {
|
|
||||||
backgroundColor: "white"
|
|
||||||
};
|
|
||||||
|
|
||||||
var jsSubContainerStyle = {
|
|
||||||
paddingTop: 9,
|
|
||||||
borderBottomWidth: 1,
|
|
||||||
borderBottomColor: "#0000001f"
|
|
||||||
};
|
|
||||||
|
|
||||||
function jsSuggestionSubContainerStyle(isLast) {
|
|
||||||
var borderBottomWidth = (isLast ? 0 : 1);
|
|
||||||
|
|
||||||
return {
|
|
||||||
paddingTop: 14,
|
|
||||||
paddingBottom: 14,
|
|
||||||
paddingRight: 14,
|
|
||||||
marginLeft: 14,
|
|
||||||
borderBottomWidth: borderBottomWidth,
|
|
||||||
borderBottomColor: "#e8ebec"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var jsValueStyle = {
|
|
||||||
fontSize: 15,
|
|
||||||
fontFamily: "font",
|
|
||||||
color: "#000000de"
|
|
||||||
};
|
|
||||||
|
|
||||||
var jsBoldValueStyle = {
|
|
||||||
fontSize: 15,
|
|
||||||
fontFamily: "font",
|
|
||||||
color: "#000000de",
|
|
||||||
fontWeight: "bold"
|
|
||||||
};
|
|
||||||
|
|
||||||
var jsDescriptionStyle = {
|
|
||||||
marginTop: 2,
|
|
||||||
fontSize: 14,
|
|
||||||
fontFamily: "font",
|
|
||||||
color: "#838c93de"
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!String.prototype.startsWith) {
|
|
||||||
String.prototype.startsWith = function (searchString, position) {
|
|
||||||
position = position || 0;
|
|
||||||
return this.substr(position, searchString.length) === searchString;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function matchSubString(array, string) {
|
|
||||||
var matched = [];
|
|
||||||
for (var i = 0; i < array.length; i++) {
|
|
||||||
var item = array[i];
|
|
||||||
if (item.toLowerCase().startsWith(string.toLowerCase())) {
|
|
||||||
matched.push(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matched;
|
|
||||||
}
|
|
||||||
|
|
||||||
function cleanCode(code) {
|
|
||||||
// remove comments
|
|
||||||
var commentsRegex = /\/\*.+?\*\/|\/\/.*/g;
|
|
||||||
code = code.replace(commentsRegex, "");
|
|
||||||
// replace string literals
|
|
||||||
var literalsRegex = /\"(?:\\\\\"|[^\"])*?\"/g;
|
|
||||||
code = code.replace(literalsRegex, '""');
|
|
||||||
var literalsRegex = /\'(?:\\\\\'|[^\'])*?\'/g;
|
|
||||||
code = code.replace(literalsRegex, '""');
|
|
||||||
|
|
||||||
return code
|
|
||||||
}
|
|
||||||
|
|
||||||
function createObjectSuggestion(name, docInfo, code, parameterNumber) {
|
|
||||||
var title = name;
|
|
||||||
if (docInfo.args) {
|
|
||||||
title += "(";
|
|
||||||
for (var i = 0; i < docInfo.args.length; i++) {
|
|
||||||
var argument = docInfo.args[i];
|
|
||||||
var argumentText = (i > 0 ? ", " : "") + (parameterNumber === i ? "*" + argument.name + "*" : argument.name);
|
|
||||||
if (argument.optional) {
|
|
||||||
argumentText = "[" + argumentText + "]";
|
|
||||||
}
|
|
||||||
title += argumentText;
|
|
||||||
}
|
|
||||||
title += ")";
|
|
||||||
}
|
|
||||||
if (!docInfo.desc) {
|
|
||||||
name += ".";
|
|
||||||
} else if (docInfo.args) {
|
|
||||||
name += "(";
|
|
||||||
if (docInfo.args.length == 0) {
|
|
||||||
name += ")";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var suggestion = {
|
|
||||||
title: title,
|
|
||||||
desc: docInfo.desc
|
|
||||||
};
|
|
||||||
|
|
||||||
if (code != null) {
|
|
||||||
suggestion.pressValue = code + name;
|
|
||||||
}
|
|
||||||
return suggestion;
|
|
||||||
}
|
|
||||||
|
|
||||||
var lastMessage = null;
|
|
||||||
|
|
||||||
function getLastForm(code) {
|
|
||||||
var codeLength = code.length;
|
|
||||||
var form = '';
|
|
||||||
var level = 0;
|
|
||||||
var index = codeLength - 1;
|
|
||||||
while (index >= 0) {
|
|
||||||
var char = code[index];
|
|
||||||
if (level == 0 && index != 0 && (char == '(' || char == ',')) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (char == ')') {
|
|
||||||
level--;
|
|
||||||
}
|
|
||||||
if (char == '(') {
|
|
||||||
level++;
|
|
||||||
}
|
|
||||||
form = char + form;
|
|
||||||
index--;
|
|
||||||
}
|
|
||||||
return form;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLastLevel(code) {
|
|
||||||
var codeLength = code.length;
|
|
||||||
var form = '';
|
|
||||||
var index = codeLength - 1;
|
|
||||||
var nested = false;
|
|
||||||
var level = 0;
|
|
||||||
while (index >= 0) {
|
|
||||||
var char = code[index];
|
|
||||||
if (char == ')') {
|
|
||||||
level--;
|
|
||||||
// A single unbalanced ')' shouldn't set nested to true.
|
|
||||||
if (level > 0) {
|
|
||||||
nested = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (char == '(') {
|
|
||||||
level++;
|
|
||||||
if (level == 0) {
|
|
||||||
nested = false;
|
|
||||||
}
|
|
||||||
if (level <= 0) {
|
|
||||||
form = "argument" + form;
|
|
||||||
index--;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((level == 1 && char == ',') || level == 2) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!nested || level > 0) {
|
|
||||||
form = char + form;
|
|
||||||
}
|
|
||||||
index--;
|
|
||||||
}
|
|
||||||
if (form.indexOf("(") < 0 && form != ",") {
|
|
||||||
var parts = form.split(',');
|
|
||||||
form = parts[parts.length - 1];
|
|
||||||
}
|
|
||||||
return form;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPartialSuggestions(doc, fullCode, code) {
|
|
||||||
var suggestions = [];
|
|
||||||
var functionParts = code.split("(");
|
|
||||||
var objectParts = code.split(/[^a-zA-Z_0-9\$\-\u00C0-\u1FFF\u2C00-\uD7FF\w]+/);
|
|
||||||
|
|
||||||
var index = 0;
|
|
||||||
var suggestedFunction = '';
|
|
||||||
while (index < objectParts.length) {
|
|
||||||
var part = objectParts[index];
|
|
||||||
if (part != "desc" && part != "args" && doc[part] != null) {
|
|
||||||
doc = doc[part];
|
|
||||||
suggestedFunction += part + '.';
|
|
||||||
index++;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
suggestedFunction = suggestedFunction.substring(0, suggestedFunction.length - 1)
|
|
||||||
if (functionParts.length == 1) {
|
|
||||||
// object suggestions
|
|
||||||
if (index > objectParts.length - 1) {
|
|
||||||
var suggestion = objectParts[objectParts.length - 1];
|
|
||||||
suggestions.push(createObjectSuggestion(suggestion, doc, fullCode.substring(0, fullCode.length - suggestion.length)));
|
|
||||||
} else if (index === objectParts.length - 1) {
|
|
||||||
var lastPart = objectParts[index];
|
|
||||||
var keys = Object.keys(doc);
|
|
||||||
var matches = matchSubString(keys, lastPart);
|
|
||||||
|
|
||||||
for (var i = 0; i < matches.length; i++) {
|
|
||||||
var suggestion = matches[i];
|
|
||||||
if (suggestion == "desc" || suggestion == "args") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var docInfo = doc[suggestion];
|
|
||||||
if (docInfo != null) {
|
|
||||||
suggestions.push(createObjectSuggestion(suggestion, docInfo, fullCode.substring(0, fullCode.length - lastPart.length)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (functionParts.length == 2) {
|
|
||||||
// parameter suggestions
|
|
||||||
var parameters = functionParts[1].split(",");
|
|
||||||
if (doc.args && parameters.length <= doc.args.length && parameters[parameters.length - 1].indexOf(")") < 0) {
|
|
||||||
var paramInfo = doc.args[parameters.length - 1];
|
|
||||||
var docInfo = doc;
|
|
||||||
docInfo.desc = paramInfo.name + ": " + paramInfo.desc;
|
|
||||||
suggestions.push(createObjectSuggestion(suggestedFunction, docInfo, null, parameters.length - 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//console.debug(suggestions);
|
|
||||||
return suggestions;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getJsSuggestions(code, context) {
|
|
||||||
var suggestions = [];
|
|
||||||
var doc = DOC_MAP;
|
|
||||||
// TODO: what's /c / doing there ???
|
|
||||||
//console.debug(code);
|
|
||||||
var previousMessage = localStorage.getItem("previousMessage");
|
|
||||||
if (!code || code == "" || code == "c ") {
|
|
||||||
code = "";
|
|
||||||
//console.debug("Last message: " + context.data);
|
|
||||||
if (previousMessage != null) {
|
|
||||||
suggestions.push({
|
|
||||||
title: 'Last command used:',
|
|
||||||
desc: previousMessage,
|
|
||||||
pressValue: previousMessage
|
|
||||||
});
|
|
||||||
}
|
|
||||||
var keys = Object.keys(doc);
|
|
||||||
for (var i = 0; i < keys.length; i++) {
|
|
||||||
var suggestion = keys[i];
|
|
||||||
var docInfo = doc[suggestion];
|
|
||||||
if (docInfo != null) {
|
|
||||||
suggestions.push(createObjectSuggestion(suggestion, docInfo, ""));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// TODO: what's /c / doing there ???
|
|
||||||
if (code.startsWith("c ")) {
|
|
||||||
code = code.substring(2);
|
|
||||||
}
|
|
||||||
if (previousMessage != null &&
|
|
||||||
(typeof previousMessage === 'string' || previousMessage instanceof String) &&
|
|
||||||
previousMessage.startsWith(code)) {
|
|
||||||
suggestions.unshift({
|
|
||||||
title: 'Last command used:',
|
|
||||||
desc: previousMessage,
|
|
||||||
pressValue: previousMessage
|
|
||||||
});
|
|
||||||
}
|
|
||||||
var originalCode = code;
|
|
||||||
code = cleanCode(code);
|
|
||||||
var levelCode = getLastLevel(code);
|
|
||||||
var code = getLastForm(levelCode);
|
|
||||||
if (levelCode != code) {
|
|
||||||
suggestions = getPartialSuggestions(doc, originalCode, levelCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
//console.debug("Final code: " + code);
|
|
||||||
//console.debug("Level code: " + levelCode);
|
|
||||||
suggestions = suggestions.concat(getPartialSuggestions(doc, originalCode, code));
|
|
||||||
}
|
|
||||||
return suggestions;
|
|
||||||
}
|
|
||||||
|
|
||||||
function createMarkupText(text) {
|
|
||||||
var parts = [];
|
|
||||||
var index = 0;
|
|
||||||
var currentText = '';
|
|
||||||
var isBold = false;
|
|
||||||
while (index < text.length) {
|
|
||||||
var char = text[index];
|
|
||||||
if (char == '*') {
|
|
||||||
if (currentText != '') {
|
|
||||||
parts.push(
|
|
||||||
status.components.text(
|
|
||||||
{style: isBold ? jsBoldValueStyle : jsValueStyle},
|
|
||||||
currentText
|
|
||||||
)
|
|
||||||
);
|
|
||||||
currentText = '';
|
|
||||||
}
|
|
||||||
isBold = !isBold;
|
|
||||||
} else {
|
|
||||||
currentText += char;
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
if (currentText != '') {
|
|
||||||
parts.push(
|
|
||||||
status.components.text(
|
|
||||||
{style: isBold ? jsBoldValueStyle : jsValueStyle},
|
|
||||||
currentText
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
//console.debug(parts);
|
|
||||||
return parts;
|
|
||||||
}
|
|
||||||
|
|
||||||
function jsSuggestions(params, context) {
|
|
||||||
var suggestions = getJsSuggestions(params.code, context);
|
|
||||||
var sugestionsMarkup = [];
|
|
||||||
|
|
||||||
for (var i = 0; i < suggestions.length; i++) {
|
|
||||||
var suggestion = suggestions[i];
|
|
||||||
|
|
||||||
if (suggestion.title.indexOf('*') >= 0) {
|
|
||||||
suggestion.title = createMarkupText(suggestion.title);
|
|
||||||
}
|
|
||||||
var suggestionMarkup = status.components.view(jsSuggestionContainerStyle,
|
|
||||||
[status.components.view(jsSuggestionSubContainerStyle(i == suggestions.length - 1),
|
|
||||||
[
|
|
||||||
status.components.text({style: jsValueStyle},
|
|
||||||
suggestion.title),
|
|
||||||
status.components.text({style: jsDescriptionStyle},
|
|
||||||
suggestion.desc)
|
|
||||||
])]);
|
|
||||||
if (suggestion.pressValue) {
|
|
||||||
suggestionMarkup = status.components.touchable({
|
|
||||||
onPress: status.components.dispatch([status.events.SET_VALUE, suggestion.pressValue])
|
|
||||||
},
|
|
||||||
suggestionMarkup
|
|
||||||
);
|
|
||||||
}
|
|
||||||
sugestionsMarkup.push(suggestionMarkup);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sugestionsMarkup.length > 0) {
|
|
||||||
return {markup: status.components.view({}, sugestionsMarkup)};
|
|
||||||
} else {
|
|
||||||
return {markup: null};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function jsHandler(params, context) {
|
|
||||||
var result = {
|
|
||||||
err: null,
|
|
||||||
data: null,
|
|
||||||
messages: []
|
|
||||||
};
|
|
||||||
messages = [];
|
|
||||||
try {
|
|
||||||
result["text-message"] = String(JSON.stringify(eval(params.code)));
|
|
||||||
localStorage.setItem("previousMessage", params.code);
|
|
||||||
} catch (e) {
|
|
||||||
result.err = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.messages = messages;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
var suggestionsContainerStyle = {
|
|
||||||
keyboardShouldPersistTaps: "always",
|
|
||||||
backgroundColor: "white",
|
|
||||||
flexGrow: 1,
|
|
||||||
bounces: false
|
|
||||||
}
|
|
||||||
|
|
||||||
var suggestionContainerStyle = {
|
|
||||||
backgroundColor: "white"
|
|
||||||
};
|
|
||||||
|
|
||||||
function suggestionSubContainerStyle(isTwoLineEntry, isLast) {
|
|
||||||
var height = (isTwoLineEntry ? 64 : 48);
|
|
||||||
var borderBottomWidth = (isLast ? 0 : 1);
|
|
||||||
|
|
||||||
return {
|
|
||||||
paddingTop: 14,
|
|
||||||
paddingBottom: 14,
|
|
||||||
paddingRight: 14,
|
|
||||||
marginLeft: 14,
|
|
||||||
height: height,
|
|
||||||
borderBottomWidth: borderBottomWidth,
|
|
||||||
borderBottomColor: "#e8ebec"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var valueStyle = {
|
|
||||||
fontSize: 15,
|
|
||||||
fontFamily: "font",
|
|
||||||
color: "#000000de"
|
|
||||||
};
|
|
||||||
|
|
||||||
var descriptionStyle = {
|
|
||||||
marginTop: 2,
|
|
||||||
fontSize: 13,
|
|
||||||
fontFamily: "font",
|
|
||||||
color: "#838c93de"
|
|
||||||
};
|
|
||||||
|
|
||||||
function startsWith(str1, str2) {
|
|
||||||
// String.startsWith(...) doesn't work in otto
|
|
||||||
return str1.lastIndexOf(str2, 0) == 0 && str1 != str2;
|
|
||||||
}
|
|
||||||
|
|
||||||
var ropstenNetworkId = 3;
|
|
||||||
var rinkebyNetworkId = 4;
|
|
||||||
|
|
||||||
var ropstenFaucets = [
|
|
||||||
{
|
|
||||||
name: "Status Testnet Faucet",
|
|
||||||
url: "http://51.15.45.169:3001",
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
var rinkebyFaucets = [
|
|
||||||
{
|
|
||||||
name: "Status Rinkeby Faucet",
|
|
||||||
url: "http://51.15.60.23:3001",
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
function getFaucets(networkId) {
|
|
||||||
if (networkId == ropstenNetworkId) {
|
|
||||||
return ropstenFaucets;
|
|
||||||
} else if (networkId == rinkebyNetworkId) {
|
|
||||||
return rinkebyFaucets;
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var faucets = getFaucets(status.ethereumNetworkId);
|
|
||||||
|
|
||||||
function faucetSuggestions(params) {
|
|
||||||
var subContainerStyle = suggestionSubContainerStyle(true, false);
|
|
||||||
|
|
||||||
var suggestions = faucets.map(function (entry, index) {
|
|
||||||
return status.components.touchable(
|
|
||||||
{onPress: status.components.dispatch([status.events.SET_COMMAND_ARGUMENT, [0, entry.url, true]])},
|
|
||||||
status.components.view(
|
|
||||||
suggestionContainerStyle,
|
|
||||||
[status.components.view(
|
|
||||||
(index == faucets.length - 1 ? suggestionSubContainerStyle(true, true) : subContainerStyle),
|
|
||||||
[
|
|
||||||
status.components.text(
|
|
||||||
{style: valueStyle},
|
|
||||||
entry.name
|
|
||||||
),
|
|
||||||
status.components.text(
|
|
||||||
{style: descriptionStyle},
|
|
||||||
entry.url
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return {markup: status.components.view({}, suggestions)};
|
|
||||||
}
|
|
||||||
|
|
||||||
var faucetCommandConfig ={
|
|
||||||
name: "faucet",
|
|
||||||
title: I18n.t('faucet_title'),
|
|
||||||
description: I18n.t('faucet_description'),
|
|
||||||
color: "#7099e6",
|
|
||||||
scope: ["personal-chats", "registered", "dapps"],
|
|
||||||
params: [{
|
|
||||||
name: "url",
|
|
||||||
type: status.types.TEXT,
|
|
||||||
suggestions: faucetSuggestions,
|
|
||||||
placeholder: I18n.t('faucet_placeholder')
|
|
||||||
}],
|
|
||||||
preview: function (params) {
|
|
||||||
return {
|
|
||||||
markup: status.components.text(
|
|
||||||
{},
|
|
||||||
params.url
|
|
||||||
)
|
|
||||||
};
|
|
||||||
},
|
|
||||||
shortPreview: function (params) {
|
|
||||||
return {
|
|
||||||
markup: status.components.chatPreviewText(
|
|
||||||
{},
|
|
||||||
I18n.t('faucet_title') + ": " + params.url
|
|
||||||
)
|
|
||||||
};
|
|
||||||
},
|
|
||||||
validator: function (params, context) {
|
|
||||||
var f = faucets.map(function (entry) {
|
|
||||||
return entry.url;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (f.indexOf(params.url) == -1) {
|
|
||||||
var error = status.components.validationMessage(
|
|
||||||
I18n.t('faucet_incorrect_title'),
|
|
||||||
I18n.t('faucet_incorrect_description')
|
|
||||||
);
|
|
||||||
|
|
||||||
return {markup: error};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
if (faucets.length > 0) {
|
|
||||||
status.command(faucetCommandConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
status.addListener("on-message-input-change", function (params, context) {
|
|
||||||
return jsSuggestions({code: params.message}, context);
|
|
||||||
});
|
|
||||||
|
|
||||||
status.addListener("on-message-send", function (params, context) {
|
|
||||||
return jsHandler({code: params.message}, context);
|
|
||||||
});
|
|
|
@ -1,42 +0,0 @@
|
||||||
// Run this in a node REPL
|
|
||||||
// .load test.js
|
|
||||||
|
|
||||||
// Load dependencies
|
|
||||||
.load web3_metadata.js
|
|
||||||
.load bot.js
|
|
||||||
|
|
||||||
// A map from current input text to suggestion titles
|
|
||||||
var suggestionTests = {
|
|
||||||
",": [],
|
|
||||||
")": [],
|
|
||||||
"(": [],
|
|
||||||
"a)": [],
|
|
||||||
// Expected?
|
|
||||||
// "a,": [],
|
|
||||||
// "a(": [],
|
|
||||||
"c": ["console"],
|
|
||||||
"console.": ["log(text)"]
|
|
||||||
};
|
|
||||||
|
|
||||||
// Mock localStorage, necessary for suggestions functions in bot.js
|
|
||||||
var STORE = {};
|
|
||||||
var localStorage = function() {};
|
|
||||||
localStorage.getItem = function(k) { return STORE[k]; };
|
|
||||||
localStorage.setItem = function(k, v) { STORE[k] = v; };
|
|
||||||
|
|
||||||
var checkSuggestion = function(input) {
|
|
||||||
var suggestions = getJsSuggestions(input, {});
|
|
||||||
var titles = suggestions.map(function(suggestion) {
|
|
||||||
return suggestion.title;
|
|
||||||
});
|
|
||||||
var expectedTitles = suggestionTests[input];
|
|
||||||
var iseq = JSON.stringify(titles) == JSON.stringify(expectedTitles);
|
|
||||||
console.log("CHECK", input, " ", iseq);
|
|
||||||
if (!iseq) {
|
|
||||||
console.log("EXPECTED", expectedTitles);
|
|
||||||
console.log("ACTUAL", titles);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Run tests
|
|
||||||
Object.keys(suggestionTests).forEach(checkSuggestion);
|
|
|
@ -1,417 +0,0 @@
|
||||||
I18n.translations = {
|
|
||||||
en: {
|
|
||||||
password_description: 'Password',
|
|
||||||
password_placeholder: 'Type your password',
|
|
||||||
password_placeholder2: 'Confirm',
|
|
||||||
password_error: 'Password should be not less then 6 symbols.',
|
|
||||||
password_error1: 'Password confirmation doesn\'t match password.',
|
|
||||||
password_validation_title: 'Password',
|
|
||||||
|
|
||||||
faucet_incorrect_title: 'Incorrect faucet',
|
|
||||||
faucet_incorrect_description: 'Please, select a one from the list',
|
|
||||||
|
|
||||||
debug_mode_title: 'Debug mode',
|
|
||||||
debug_mode_description: 'Starts/stops a debug mode',
|
|
||||||
|
|
||||||
faucet_title: 'Faucet',
|
|
||||||
faucet_description: 'Get some ETH',
|
|
||||||
faucet_placeholder: 'Faucet URL'
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
,
|
|
||||||
ru: {
|
|
||||||
password_description: 'Пароль',
|
|
||||||
password_placeholder: 'Введите свой пароль',
|
|
||||||
password_placeholder2: 'Повторно введите пароль для подтверждения',
|
|
||||||
password_error: 'Пароль должен содержать не менее 6 символов',
|
|
||||||
password_error1: 'Подтверждение пароля не совпадает с паролем',
|
|
||||||
password_validation_title: 'Пароль'
|
|
||||||
|
|
||||||
},
|
|
||||||
af: {
|
|
||||||
password_description: 'Wagwoord',
|
|
||||||
password_placeholder: 'Tik jou wagwoord in',
|
|
||||||
password_placeholder2: 'Tik asseblief weer jou wagwoord in om te bevestig',
|
|
||||||
password_error: 'Wagwoord mag nie minder as 6 simbole wees nie.',
|
|
||||||
password_error1: 'Wagwoordbevestiging is nie dieselfde as wagwoord nie.',
|
|
||||||
password_validation_title: 'Wagwoord'
|
|
||||||
|
|
||||||
},
|
|
||||||
ar: {
|
|
||||||
password_description: 'كلمة المرور',
|
|
||||||
password_placeholder: 'اكتب كلمة المرور الخاصة بك',
|
|
||||||
password_placeholder2: 'الرجاء إعادة إدخال كلمة المرور للتأكيد',
|
|
||||||
password_error: 'ينبغي أن لا تقل كلمة المرور عن 6 رموز.',
|
|
||||||
password_error1: 'لا يتوافق تأكيد كلمة المرور مع كلمة المرور.',
|
|
||||||
password_validation_title: 'كلمة المرور'
|
|
||||||
|
|
||||||
},
|
|
||||||
'zh-hant': {
|
|
||||||
password_description: '密碼',
|
|
||||||
password_placeholder: '鍵入你的密碼',
|
|
||||||
password_placeholder2: '重新鍵入你的密碼',
|
|
||||||
password_error: '密碼不得短於6個字符。',
|
|
||||||
password_error1: '確認密碼與鍵入的密碼不一致。',
|
|
||||||
password_validation_title: '密碼',
|
|
||||||
|
|
||||||
faucet_incorrect_title: '不正確的水龍頭',
|
|
||||||
faucet_incorrect_description: '請從列表中選擇一個',
|
|
||||||
|
|
||||||
debug_mode_title: '調試模式',
|
|
||||||
debug_mode_description: '開始/停止調試模式',
|
|
||||||
|
|
||||||
faucet_title: '水龍頭',
|
|
||||||
faucet_description: '獲取一些以太幣',
|
|
||||||
faucet_placeholder: '水龍頭網址'
|
|
||||||
|
|
||||||
},
|
|
||||||
'zh-hant-tw': {
|
|
||||||
password_description: '密碼',
|
|
||||||
password_placeholder: '輸入密碼',
|
|
||||||
password_placeholder2: '請重新輸入密碼以確認',
|
|
||||||
password_error: '密碼應不少於6個字符。',
|
|
||||||
password_error1: '密碼確認資訊與密碼不匹配。',
|
|
||||||
password_validation_title: '密碼',
|
|
||||||
|
|
||||||
faucet_incorrect_title: '不正確的水龍頭',
|
|
||||||
faucet_incorrect_description: '請從列表中選擇一個',
|
|
||||||
|
|
||||||
debug_mode_title: '除錯模式',
|
|
||||||
debug_mode_description: '開始/停止除錯模式',
|
|
||||||
|
|
||||||
faucet_title: '水龍頭',
|
|
||||||
faucet_description: '獲取一些以太幣',
|
|
||||||
faucet_placeholder: '水龍頭網址'
|
|
||||||
|
|
||||||
},
|
|
||||||
'zh-hant-sg': {
|
|
||||||
password_description: '密碼',
|
|
||||||
password_placeholder: '輸入密碼',
|
|
||||||
password_placeholder2: '請重新輸入密碼以確認',
|
|
||||||
password_error: '密碼應不少於6個字符。',
|
|
||||||
password_error1: '密碼確認資訊與密碼不匹配。',
|
|
||||||
password_validation_title: '密碼',
|
|
||||||
|
|
||||||
faucet_incorrect_title: '不正確的水龍頭',
|
|
||||||
faucet_incorrect_description: '請從列表中選擇一個',
|
|
||||||
|
|
||||||
debug_mode_title: '除錯模式',
|
|
||||||
debug_mode_description: '開始/停止除錯模式',
|
|
||||||
|
|
||||||
faucet_title: '水龍頭',
|
|
||||||
faucet_description: '獲取一些以太幣',
|
|
||||||
faucet_placeholder: '水龍頭網址'
|
|
||||||
|
|
||||||
},
|
|
||||||
'zh-hant-hk': {
|
|
||||||
password_description: '密碼',
|
|
||||||
password_placeholder: '輸入密碼',
|
|
||||||
password_placeholder2: '請重新輸入密碼以確認',
|
|
||||||
password_error: '密碼應不少於6個字符。',
|
|
||||||
password_error1: '密碼確認信息與密碼不匹配。',
|
|
||||||
password_validation_title: '密碼',
|
|
||||||
|
|
||||||
faucet_incorrect_title: '不正確的水龍頭',
|
|
||||||
faucet_incorrect_description: '請從列表中選擇一個',
|
|
||||||
|
|
||||||
debug_mode_title: '調試模式',
|
|
||||||
debug_mode_description: '開始/停止調試模式',
|
|
||||||
|
|
||||||
faucet_title: '水龍頭',
|
|
||||||
faucet_description: '獲取一些以太幣',
|
|
||||||
faucet_placeholder: '水龍頭網址'
|
|
||||||
|
|
||||||
},
|
|
||||||
'zh-hans': {
|
|
||||||
password_description: '密码',
|
|
||||||
password_placeholder: '输入密码',
|
|
||||||
password_placeholder2: '请重新输入密码以确认',
|
|
||||||
password_error: '密码应不少于6个字符。',
|
|
||||||
password_error1: '密码确认信息与密码不匹配。',
|
|
||||||
password_validation_title: '密码',
|
|
||||||
|
|
||||||
faucet_incorrect_title: '不正确的水龙头',
|
|
||||||
faucet_incorrect_description: '请从列表中选择一个',
|
|
||||||
|
|
||||||
debug_mode_title: '调试模式',
|
|
||||||
debug_mode_description: '开始/停止调试模式',
|
|
||||||
|
|
||||||
faucet_title: '水龙头',
|
|
||||||
faucet_description: '获取一些以太币',
|
|
||||||
faucet_placeholder: '水龙头网址'
|
|
||||||
|
|
||||||
},
|
|
||||||
'zh-yue': {
|
|
||||||
password_description: '密碼',
|
|
||||||
password_placeholder: '輸入密碼',
|
|
||||||
password_placeholder2: '請重新輸入密碼確認',
|
|
||||||
password_error: '密碼不能短於6個字符.',
|
|
||||||
password_error1: '確認密碼與輸入密碼不符.',
|
|
||||||
password_validation_title: '密碼',
|
|
||||||
|
|
||||||
faucet_incorrect_title: '不正確的水龍頭',
|
|
||||||
faucet_incorrect_description: '請從列表中選擇一個',
|
|
||||||
|
|
||||||
debug_mode_title: '調試模式',
|
|
||||||
debug_mode_description: '開始/停止調試模式',
|
|
||||||
|
|
||||||
faucet_title: '水龍頭',
|
|
||||||
faucet_description: '獲取一些以太幣',
|
|
||||||
faucet_placeholder: '水龍頭網址'
|
|
||||||
|
|
||||||
},
|
|
||||||
'zh-wuu': {
|
|
||||||
password_description: '密码',
|
|
||||||
password_placeholder: '输入密码',
|
|
||||||
password_placeholder2: '请重新输入密码确认',
|
|
||||||
password_error: '密码应不小于6个字符。',
|
|
||||||
password_error1: '密码确认不匹配。',
|
|
||||||
password_validation_title: '密码',
|
|
||||||
|
|
||||||
faucet_incorrect_title: '不正確的水龍頭',
|
|
||||||
faucet_incorrect_description: '請從列表中選擇一個',
|
|
||||||
|
|
||||||
debug_mode_title: '調試模式',
|
|
||||||
debug_mode_description: '開始/停止調試模式',
|
|
||||||
|
|
||||||
faucet_title: '水龍頭',
|
|
||||||
faucet_description: '獲取一些以太幣',
|
|
||||||
faucet_placeholder: '水龍頭網址'
|
|
||||||
|
|
||||||
},
|
|
||||||
nl: {
|
|
||||||
password_description: 'Wachtwoord',
|
|
||||||
password_placeholder: 'Typ je wachtwoord',
|
|
||||||
password_placeholder2: 'Voer je wachtwoord opnieuw in om te bevestigen',
|
|
||||||
password_error: 'Wachtwoord moet minstens 6 tekens hebben.',
|
|
||||||
password_error1: 'Wachtwoordbevestiging komt niet overeen met wachtwoord.',
|
|
||||||
password_validation_title: 'Wachtwoord'
|
|
||||||
|
|
||||||
},
|
|
||||||
fr: {
|
|
||||||
password_description: 'Mot de passe',
|
|
||||||
password_placeholder: 'Tapez votre mot de passe',
|
|
||||||
password_placeholder2: 'Veuillez retapez votre mot de passe pour le confirmer',
|
|
||||||
password_error: 'Le mot de passe doit contenir 6 symboles au minimum.',
|
|
||||||
password_error1: 'Le mot de passe de confirmation ne correspond pas au mot de passe.',
|
|
||||||
password_validation_title: 'Mot de passe'
|
|
||||||
|
|
||||||
},
|
|
||||||
de: {
|
|
||||||
password_description: 'Passwort',
|
|
||||||
password_placeholder: 'Geben Sie Ihr Passwort ein',
|
|
||||||
password_placeholder2: 'Bitte geben Sie das Passwort zur Bestätigung erneut ein',
|
|
||||||
password_error: 'Das Passwort sollte nicht weniger als 6 Stellen beinhalten',
|
|
||||||
password_error1: 'Die Passwortbestätigung stimmt nicht mit dem Passwort überein',
|
|
||||||
password_validation_title: 'Passwort',
|
|
||||||
|
|
||||||
},
|
|
||||||
hi: {
|
|
||||||
password_description: 'पासवर्ड',
|
|
||||||
password_placeholder: 'अपना पासवर्ड टाइप करें',
|
|
||||||
password_placeholder2: 'पुष्टि करने के लिए फिर से पासवर्ड दर्ज करें',
|
|
||||||
password_error: 'पासवर्ड 6 प्रतीकों से कम का नहीं होना चाहिए।',
|
|
||||||
password_error1: 'पासवर्ड पुष्टि पासवर्ड मेल नहीं खाता है।',
|
|
||||||
password_validation_title: 'पासवर्ड'
|
|
||||||
|
|
||||||
},
|
|
||||||
hu: {
|
|
||||||
password_description: 'Jelszó',
|
|
||||||
password_placeholder: 'Add meg a jelszavad',
|
|
||||||
password_placeholder2: 'A megerősítéshez kérjük, add meg újra a jelszavad',
|
|
||||||
password_error: 'A jelszó nem lehet hosszabb 6 szimbólumnál.',
|
|
||||||
password_error1: 'A megerősített jelszó nem egyezik a jelszóval.',
|
|
||||||
password_validation_title: 'Jelszó'
|
|
||||||
|
|
||||||
},
|
|
||||||
it: {
|
|
||||||
password_description: 'Password',
|
|
||||||
password_placeholder: 'Digita la tua password',
|
|
||||||
password_placeholder2: 'Reinserisci la password per confermare',
|
|
||||||
password_error: 'La password deve contenere almeno 6 caratteri.',
|
|
||||||
password_error1: 'Conferma password\ la password non corrisponde.',
|
|
||||||
password_validation_title: 'Password'
|
|
||||||
|
|
||||||
},
|
|
||||||
ja: {
|
|
||||||
password_description: 'パスワード',
|
|
||||||
password_placeholder: 'パスワードを入力してください',
|
|
||||||
password_placeholder2: '確認のためにパスワードを再入力してください',
|
|
||||||
password_error: 'パスワードは6文字以上にしてください。',
|
|
||||||
password_error1: 'パスワードが一致しません。',
|
|
||||||
password_validation_title: 'パスワード',
|
|
||||||
|
|
||||||
faucet_incorrect_title: 'フォーセットが違います',
|
|
||||||
faucet_incorrect_description: '一覧の中から一つだけ選択してください',
|
|
||||||
|
|
||||||
debug_mode_title: 'デバッグモード',
|
|
||||||
debug_mode_description: 'デバッグモードを開始/停止します',
|
|
||||||
|
|
||||||
faucet_title: 'フォーセット',
|
|
||||||
faucet_description: 'ETHを取得する',
|
|
||||||
faucet_placeholder: 'フォーセットURL'
|
|
||||||
},
|
|
||||||
ko: {
|
|
||||||
password_description: '비밀번호',
|
|
||||||
password_placeholder: '비밀번호를 입력하세요',
|
|
||||||
password_placeholder2: '확인을 위해 비밀번호를 다시 입력해 주세요',
|
|
||||||
password_error: '비밀번호는 6자 이상이어야 합니다.',
|
|
||||||
password_error1: '확인용 비밀번호가 원래 비밀번호와 일치하지 않습니다.',
|
|
||||||
password_validation_title: '비밀번호'
|
|
||||||
|
|
||||||
},
|
|
||||||
pl: {
|
|
||||||
password_description: 'Hasło',
|
|
||||||
password_placeholder: 'Wpisz swoje hasło',
|
|
||||||
password_placeholder2: 'Wprowadź ponownie hasło, aby potwierdzić',
|
|
||||||
password_error: 'Hasło powinno zawierać co najmniej 6 symboli.',
|
|
||||||
password_error1: 'Wprowadzone i potwierdzone hasła nie są takie same.',
|
|
||||||
password_validation_title: 'Hasło'
|
|
||||||
|
|
||||||
},
|
|
||||||
'pt-br': {
|
|
||||||
password_description: 'Senha',
|
|
||||||
password_placeholder: 'Digite sua senha',
|
|
||||||
password_placeholder2: 'Por favor, digite a senha novamente para confirmar',
|
|
||||||
password_error: 'A senha deve ter no mínimo 6 símbolos.',
|
|
||||||
password_error1: 'A confirmação da senha é diferente da senha.',
|
|
||||||
password_validation_title: 'Senha'
|
|
||||||
|
|
||||||
},
|
|
||||||
'pt-pt': {
|
|
||||||
password_description: 'Palavra-passe',
|
|
||||||
password_placeholder: 'Digite a sua palavra-passe',
|
|
||||||
password_placeholder2: 'Por favor, volte a digitar a palavra-passe para confirmar',
|
|
||||||
password_error: 'A palavra-passe não deve ter menos de 6 símbolos.',
|
|
||||||
password_error1: 'A confirmação da palavra-passe não coincide com a palavra-passe.',
|
|
||||||
password_validation_title: 'Palavra-passe'
|
|
||||||
|
|
||||||
},
|
|
||||||
ro: {
|
|
||||||
password_description: 'Parolă',
|
|
||||||
password_placeholder: 'Tastează parola',
|
|
||||||
password_placeholder2: 'Te rugăm să re-introduci parola pentru a confirma',
|
|
||||||
password_error: 'Parola trebuie să aibă cel puțin 6 simboluri.',
|
|
||||||
password_error1: 'Parola confirmată nu este aceeași cu parola introdusă.',
|
|
||||||
password_validation_title: 'Parolă'
|
|
||||||
|
|
||||||
},
|
|
||||||
sl: {
|
|
||||||
password_description: 'Geslo',
|
|
||||||
password_placeholder: 'Vnesi svoje geslo',
|
|
||||||
password_placeholder2: 'Prosimo, ponovno vnesi geslo za potrditev',
|
|
||||||
password_error: 'Geslo mora vsebovati vsaj 6 simbolov.',
|
|
||||||
password_error1: 'Potrditev gesla se ne ujema z geslom.',
|
|
||||||
password_validation_title: 'Geslo'
|
|
||||||
|
|
||||||
},
|
|
||||||
es: {
|
|
||||||
password_description: 'Contraseña',
|
|
||||||
password_placeholder: 'Escribe tu contraseña',
|
|
||||||
password_placeholder2: 'Por favor, vuelve a escribir la contraseña para confirmar',
|
|
||||||
password_error: 'La contraseña no debe ser inferior a 6 símbolos.',
|
|
||||||
password_error1: 'La confirmación de contraseña no coincide con la contraseña.',
|
|
||||||
password_validation_title: 'Contraseña'
|
|
||||||
|
|
||||||
},
|
|
||||||
'es-ar': {
|
|
||||||
password_description: 'Contraseña',
|
|
||||||
password_placeholder: 'Ingresa tu contraseña',
|
|
||||||
password_placeholder2: 'Ingresa tu contraseña para confirmar',
|
|
||||||
password_error: 'Las contraseñas deben contener no menos de 6 símbolos.',
|
|
||||||
password_error1: 'La confirmación de la contraseña no coincide con la contraseña.',
|
|
||||||
password_validation_title: 'Contraseña'
|
|
||||||
|
|
||||||
},
|
|
||||||
sw: {
|
|
||||||
password_description: 'Nenosiri',
|
|
||||||
password_placeholder: 'Andika nenosiri lako',
|
|
||||||
password_placeholder2: 'Tafadhali ingiza tena nenosiri kuthibitisha',
|
|
||||||
password_error: 'Nenosiri lisiwe chini ya alama 6.',
|
|
||||||
password_error1: 'Uthibitisho wa nenosiri haulingani na nenosiri.',
|
|
||||||
password_validation_title: 'Nenosiri'
|
|
||||||
|
|
||||||
},
|
|
||||||
sv: {
|
|
||||||
password_description: 'Lösenord',
|
|
||||||
password_placeholder: 'Skriv ditt lösenord',
|
|
||||||
password_placeholder2: 'Var god ange ditt lösenord igen för att bekräfta',
|
|
||||||
password_error: 'Lösenordet bör inte vara mindre än 6 symboler.',
|
|
||||||
password_error1: 'Lösenordsbekräftelsen matcharinte lösenordet.',
|
|
||||||
password_validation_title: 'Lösenord'
|
|
||||||
|
|
||||||
},
|
|
||||||
'fr-ch': {
|
|
||||||
password_description: 'Mot de passe',
|
|
||||||
password_placeholder: 'Tapez votre mot de passe',
|
|
||||||
password_placeholder2: 'Veuillez saisir à nouveau le mot de passe pour confirmer',
|
|
||||||
password_error: 'Le mot de passe doit avoir au moins 6 caractères.',
|
|
||||||
password_error1: 'La confirmation du mot de passe ne correspond pas au premier mot de passe.',
|
|
||||||
password_validation_title: 'Mot de passe'
|
|
||||||
|
|
||||||
},
|
|
||||||
'de-ch': {
|
|
||||||
password_description: 'Passwort',
|
|
||||||
password_placeholder: 'Gib dein Passwort ein',
|
|
||||||
password_placeholder2: 'Bitte gib das Passwort zur Bestätigung erneut ein',
|
|
||||||
password_error: 'Passwort sollte nicht kleiner als 6 Symbole sein.',
|
|
||||||
password_error1: 'Passwort Bestätigung stimmt mit Passwort nicht überein.',
|
|
||||||
password_validation_title: 'Passwort'
|
|
||||||
|
|
||||||
},
|
|
||||||
'it-ch': {
|
|
||||||
password_description: 'Password',
|
|
||||||
password_placeholder: 'Digita la tua password',
|
|
||||||
password_placeholder2: 'Inserisci nuovamente la password per confermare',
|
|
||||||
password_error: 'La password non può contenere meno di 6 caratteri.',
|
|
||||||
password_error1: 'La password di conferma non corrisponde alla password.',
|
|
||||||
password_validation_title: 'Password'
|
|
||||||
|
|
||||||
},
|
|
||||||
th: {
|
|
||||||
password_description: 'รหัสผ่าน',
|
|
||||||
password_placeholder: 'พิมพ์รหัสผ่านของคุณ',
|
|
||||||
password_placeholder2: 'โปรดกรอกรหัสผ่านอีกครั้งเพื่อยืนยัน',
|
|
||||||
password_error: 'รหัสผ่านควรมีสัญลักษณ์ไม่น้อยกว่า 6 ตัว',
|
|
||||||
password_error1: 'การยืนยันรหัสผ่านไม่ตรงกับรหัสผ่าน',
|
|
||||||
password_validation_title: 'รหัสผ่าน'
|
|
||||||
|
|
||||||
},
|
|
||||||
tr: {
|
|
||||||
password_description: 'Şifre',
|
|
||||||
password_placeholder: 'Şifrenizi girin',
|
|
||||||
password_placeholder2: 'Onaylamak için lütfen parolanızı yeniden girin',
|
|
||||||
password_error: 'Şifre 6 simgeden daha kısa olmamalıdır.',
|
|
||||||
password_error1: 'Şifre onayı, şifre ile eşleşmiyor.',
|
|
||||||
password_validation_title: 'Şifre'
|
|
||||||
|
|
||||||
},
|
|
||||||
uk: {
|
|
||||||
password_description: 'Пароль',
|
|
||||||
password_placeholder: 'Введіть свій пароль',
|
|
||||||
password_placeholder2: 'Будь ласка, введіть пароль ще раз для підтвердження',
|
|
||||||
password_error: 'Пароль повинен бути не менше 6 символів.',
|
|
||||||
password_error1: 'Підтвердження паролю не співпадає з паролем.',
|
|
||||||
password_validation_title: 'Пароль'
|
|
||||||
|
|
||||||
},
|
|
||||||
ur: {
|
|
||||||
password_description: 'پاسورڈ',
|
|
||||||
password_placeholder: 'اپنا پاسورڈ لکھیں',
|
|
||||||
password_placeholder2: 'برائے مہربانی تصدیق کے لیے اپنا پاسورڈ دوبارہ لکھیں',
|
|
||||||
password_error: 'پاسورڈ 6 اعداد سے چھوٹا نہیں ہونا چاہیے۔',
|
|
||||||
password_error1: 'تصدیقی پاسورڈ پاسورڈ سے مماثل نہیں',
|
|
||||||
password_validation_title: 'پاسورڈ'
|
|
||||||
|
|
||||||
},
|
|
||||||
vi: {
|
|
||||||
password_description: 'Mật khẩu',
|
|
||||||
password_placeholder: 'Gõ mật khẩu của bạn',
|
|
||||||
password_placeholder2: 'Vui lòng nhập lại mật khẩu để xác nhận',
|
|
||||||
password_error: 'Mật khẩu không được ít hơn 6 ký tự.',
|
|
||||||
password_error1: 'Xác nhận mật khẩu không khớp với mật khẩu.',
|
|
||||||
password_validation_title: 'Mật khẩu'
|
|
||||||
|
|
||||||
} */
|
|
||||||
};
|
|
|
@ -1,587 +0,0 @@
|
||||||
var WEB3_UNIT = [
|
|
||||||
'kwei/ada',
|
|
||||||
'mwei/babbage',
|
|
||||||
'gwei/shannon',
|
|
||||||
'szabo',
|
|
||||||
'finney',
|
|
||||||
'ether',
|
|
||||||
'kether/grand/einstein',
|
|
||||||
'mether',
|
|
||||||
'gether',
|
|
||||||
'tether'
|
|
||||||
];
|
|
||||||
|
|
||||||
// because web3 doesn't provide params or docs
|
|
||||||
var DOC_MAP = {
|
|
||||||
console: {
|
|
||||||
log : {
|
|
||||||
desc: 'Outputs a message to chat context.',
|
|
||||||
args: [{
|
|
||||||
name: 'text',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'message to output to chat context'
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
web3: {
|
|
||||||
// setProvider : ['provider'], // TODO
|
|
||||||
version: {
|
|
||||||
api: {
|
|
||||||
desc: 'The ethereum js api version.'
|
|
||||||
},
|
|
||||||
node: {
|
|
||||||
desc: 'The client/node version.'
|
|
||||||
},
|
|
||||||
network: {
|
|
||||||
desc: 'The network protocol version.'
|
|
||||||
},
|
|
||||||
ethereum: {
|
|
||||||
desc: 'The ethereum protocol version.'
|
|
||||||
},
|
|
||||||
whisper: {
|
|
||||||
desc: 'The whisper protocol version.'
|
|
||||||
},
|
|
||||||
},
|
|
||||||
isConnected: {
|
|
||||||
desc: 'Check if a connection to a node exists.',
|
|
||||||
args: []
|
|
||||||
},
|
|
||||||
currentProvider: {
|
|
||||||
desc: 'Will contain the current provider, if one is set. This can be used to check if mist etc. set already a provider.'
|
|
||||||
},
|
|
||||||
reset: {
|
|
||||||
desc: 'Should be called to reset state of web3. Resets everything except manager. Uninstalls all filters. Stops polling.',
|
|
||||||
args: [{
|
|
||||||
name: 'keepIsSyncing',
|
|
||||||
type: 'Boolean',
|
|
||||||
desc: 'If true it will uninstall all filters, but will keep the web3.eth.isSyncing() polls'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
sha3: {
|
|
||||||
desc: 'Returns the Keccak-256 SHA3 of the given data.',
|
|
||||||
args: [{
|
|
||||||
name: 'string',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The string to hash using the Keccak-256 SHA3 algorithm'
|
|
||||||
}, {
|
|
||||||
name: 'options',
|
|
||||||
type: 'Object',
|
|
||||||
optional: true,
|
|
||||||
desc: 'Set encoding to hex if the string to hash is encoded in hex. A leading 0x will be automatically ignored.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
toHex: {
|
|
||||||
desc: 'Converts any value into HEX',
|
|
||||||
args: [{
|
|
||||||
name: 'mixed',
|
|
||||||
type: 'String|Number|Object|Array|BigNumber',
|
|
||||||
desc: 'The value to parse to HEX. If its an object or array it will be JSON.stringify first. If its a BigNumber it will make it the HEX value of a number.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
toAscii: {
|
|
||||||
desc: 'Converts a HEX string into a ASCII string.',
|
|
||||||
args: [{
|
|
||||||
name: 'hexString',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'A HEX string to be converted to ascii.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
fromAscii: {
|
|
||||||
desc: 'Converts any ASCII string to a HEX string.',
|
|
||||||
args: [{
|
|
||||||
name: 'string',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'An ASCII string to be converted to HEX.'
|
|
||||||
}, {
|
|
||||||
name: 'padding',
|
|
||||||
type: 'Number',
|
|
||||||
desc: 'The number of bytes the returned HEX string should have. '
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
toDecimal: {
|
|
||||||
desc: 'Converts a HEX string to its number representation.',
|
|
||||||
args: [{
|
|
||||||
name: 'hexString',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'An HEX string to be converted to a number.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
fromDecimal: {
|
|
||||||
desc: 'Converts a number or number string to its HEX representation.',
|
|
||||||
args: [{
|
|
||||||
name: 'number',
|
|
||||||
type: 'Number',
|
|
||||||
desc: 'A number to be converted to a HEX string.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
fromWei: {
|
|
||||||
desc: 'Converts a number of wei into an ethereum unit',
|
|
||||||
args: [{
|
|
||||||
name: 'number',
|
|
||||||
type: 'Number|String|BigNumber',
|
|
||||||
desc: 'A number or BigNumber instance.'
|
|
||||||
}, {
|
|
||||||
name: 'unit',
|
|
||||||
type: 'string',
|
|
||||||
desc: 'One of the ether units'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
toWei: {
|
|
||||||
desc: 'Converts an ethereum unit into wei',
|
|
||||||
args: [{
|
|
||||||
name: 'number',
|
|
||||||
type: 'Number|String|BigNumber',
|
|
||||||
desc: 'A number or BigNumber instance.'
|
|
||||||
}, {
|
|
||||||
name: 'unit',
|
|
||||||
type: 'string',
|
|
||||||
desc: 'One of the ether units'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
toBigNumber: {
|
|
||||||
desc: 'Converts a given number into a BigNumber instance',
|
|
||||||
args: [{
|
|
||||||
name: 'numberOrHexString',
|
|
||||||
type: 'Number|String',
|
|
||||||
desc: 'A number, number string or HEX string of a number.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
net: {
|
|
||||||
listening: {
|
|
||||||
desc: 'Is node actively listening for network connections?'
|
|
||||||
},
|
|
||||||
peerCount: {
|
|
||||||
desc: 'Returns the number of connected peers'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
isAddress: {
|
|
||||||
desc: '',
|
|
||||||
args: [{
|
|
||||||
name: '',
|
|
||||||
type: 'string',
|
|
||||||
desc: 'hex string'
|
|
||||||
}], // TODO not in docs
|
|
||||||
},
|
|
||||||
eth: {
|
|
||||||
defaultAccount: {
|
|
||||||
desc: 'The currently set default address'
|
|
||||||
},
|
|
||||||
defaultBlock: {
|
|
||||||
desc: 'The default block number to use when querying a state.'
|
|
||||||
},
|
|
||||||
syncing: {
|
|
||||||
desc: 'Returns the either a sync object, when the node is syncing or false.'
|
|
||||||
},
|
|
||||||
isSyncing: {
|
|
||||||
desc: 'This convenience function calls the callback everytime a sync starts, updates and stops.',
|
|
||||||
args: [{
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
desc: 'The callback will be fired with true when the syncing starts and with false when it stopped. While syncing it will return the syncing object: {startingBlock, currentBlock, highestBlock}'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
coinbase: {
|
|
||||||
desc: 'Returns the coinbase address were the mining rewards go to.'
|
|
||||||
},
|
|
||||||
mining: {
|
|
||||||
desc: 'Says whether the node is mining or not.'
|
|
||||||
},
|
|
||||||
hashrate: {
|
|
||||||
desc: 'Returns the number of hashes per second that the node is mining with.'
|
|
||||||
},
|
|
||||||
gasPrice: {
|
|
||||||
desc: 'Returns the current gas price. The gas price is determined by the x latest blocks median gas price'
|
|
||||||
},
|
|
||||||
accounts: {
|
|
||||||
desc: 'Returns a list of accounts the node controls'
|
|
||||||
},
|
|
||||||
blockNumber: {
|
|
||||||
desc: 'Returns the current block number'
|
|
||||||
},
|
|
||||||
getBalance: {
|
|
||||||
desc: 'Get the balance of an address at a given block.',
|
|
||||||
args: [{
|
|
||||||
name: 'addressHexString',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The address to get the balance of'
|
|
||||||
}, {
|
|
||||||
name: 'defaultBlock',
|
|
||||||
type: 'Number|String',
|
|
||||||
optional: true,
|
|
||||||
desc: 'If you pass this parameter it will not use the default block set with web3.eth.defaultBlock.'
|
|
||||||
}, {
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'If you pass a callback the HTTP request is made asynchronous.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
getStorageAt: {
|
|
||||||
desc: 'Get the storage at a specific position of an address.',
|
|
||||||
args: [{
|
|
||||||
name: 'addressHexString',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The address to get the storage from.'
|
|
||||||
}, {
|
|
||||||
name: 'position',
|
|
||||||
type: 'Number',
|
|
||||||
desc: 'The index position of the storage.'
|
|
||||||
}, {
|
|
||||||
name: 'defaultBlock',
|
|
||||||
type: 'Number|String',
|
|
||||||
optional: true,
|
|
||||||
desc: 'If you pass this parameter it will not use the default block set with web3.eth.defaultBlock.'
|
|
||||||
}, {
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'If you pass a callback the HTTP request is made asynchronous.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
getCode: {
|
|
||||||
desc: 'Get the code at a specific address.',
|
|
||||||
args: [{
|
|
||||||
name: 'addressHexString',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The address to get the code from.'
|
|
||||||
}, {
|
|
||||||
name: 'defaultBlock',
|
|
||||||
type: 'Number|String',
|
|
||||||
optional: true,
|
|
||||||
desc: 'If you pass this parameter it will not use the default block set with web3.eth.defaultBlock.'
|
|
||||||
}, {
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'If you pass a callback the HTTP request is made asynchronous.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
getBlock: {
|
|
||||||
desc: 'Returns a block matching the block number or block hash.',
|
|
||||||
args: [{
|
|
||||||
name: 'blockHashOrBlockNumber',
|
|
||||||
type: 'String|Number',
|
|
||||||
desc: 'The block number or hash. Or the string "earliest", "latest" or "pending"'
|
|
||||||
}, {
|
|
||||||
name: 'returnTransactionObjects',
|
|
||||||
type: 'Boolean',
|
|
||||||
optional: true,
|
|
||||||
desc: '(default false) If true, the returned block will contain all transactions as objects, if false it will only contains the transaction hashes.'
|
|
||||||
}, {
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'If you pass a callback the HTTP request is made asynchronous.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
getBlockTransactionCount: {
|
|
||||||
desc: 'Returns the number of transaction in a given block.',
|
|
||||||
args: [{
|
|
||||||
name: 'hashStringOrBlockNumber',
|
|
||||||
type: 'String|Number',
|
|
||||||
desc: 'The block number or hash. Or the string "earliest", "latest" or "pending"'
|
|
||||||
}, {
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'If you pass a callback the HTTP request is made asynchronous.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
getUncle: {
|
|
||||||
desc: 'Returns a blocks uncle by a given uncle index position',
|
|
||||||
args: [{
|
|
||||||
name: 'blockHashStringOrNumber',
|
|
||||||
type: 'String|Number',
|
|
||||||
desc: 'The block number or hash. Or the string "earliest", "latest" or "pending"'
|
|
||||||
}, {
|
|
||||||
name: 'uncleNumber',
|
|
||||||
type: 'Number',
|
|
||||||
desc: 'The index position of the uncle.'
|
|
||||||
}, {
|
|
||||||
name: 'returnTransactionObjects',
|
|
||||||
type: 'Boolean',
|
|
||||||
desc: '(default false) If true, the returned block will contain all transactions as objects, if false it will only contains the transaction hashes.'
|
|
||||||
}, {
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'If you pass a callback the HTTP request is made asynchronous.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
getBlockUncleCount: {
|
|
||||||
desc: '', // TODO missing from docs
|
|
||||||
},
|
|
||||||
getTransaction: {
|
|
||||||
desc: 'Returns a transaction matching the given transaction hash.',
|
|
||||||
args: [{
|
|
||||||
name: 'transactionHash',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The transaction hash.'
|
|
||||||
}, {
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'If you pass a callback the HTTP request is made asynchronous.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
getTransactionFromBlock: {
|
|
||||||
desc: 'Returns a transaction based on a block hash or number and the transactions index position.',
|
|
||||||
args: [{
|
|
||||||
name: 'hashStringOrBlockNumber',
|
|
||||||
type: 'String|Number',
|
|
||||||
desc: 'The block number or hash. Or the string "earliest", "latest" or "pending"'
|
|
||||||
}, {
|
|
||||||
name: 'indexNumber',
|
|
||||||
type: 'Number',
|
|
||||||
desc: 'The transactions index position.'
|
|
||||||
}, {
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'If you pass a callback the HTTP request is made asynchronous.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
getTransactionReceipt: {
|
|
||||||
desc: 'Returns the receipt of a transaction by transaction hash.',
|
|
||||||
args: [{
|
|
||||||
name: 'hashString',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The transaction hash.'
|
|
||||||
}, {
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'If you pass a callback the HTTP request is made asynchronous.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
getTransactionCount: {
|
|
||||||
desc: 'Get the numbers of transactions sent from this address.',
|
|
||||||
args: [{
|
|
||||||
name: 'addressHexString',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The address to get the numbers of transactions from.'
|
|
||||||
}, {
|
|
||||||
name: 'defaultBlock',
|
|
||||||
type: 'String|Number',
|
|
||||||
desc: 'If you pass this parameter it will not use the default block set with web3.eth.defaultBlock.'
|
|
||||||
}, {
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'If you pass a callback the HTTP request is made asynchronous.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
sendTransaction: {
|
|
||||||
desc: 'Sends a transaction to the network.',
|
|
||||||
args: [{
|
|
||||||
name: 'transactionObject',
|
|
||||||
type: 'Object',
|
|
||||||
desc: 'The transaction object to send: {from[, to][, value][, gas][, gasPrice][, data][, nonce]}'
|
|
||||||
}, {
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'If you pass a callback the HTTP request is made asynchronous.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
sendRawTransaction: {
|
|
||||||
desc: 'Sends an already signed transaction.',
|
|
||||||
args: [{
|
|
||||||
name: 'signedTransactionData',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'Signed transaction data in HEX format'
|
|
||||||
}, {
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'If you pass a callback the HTTP request is made asynchronous.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
sign: {
|
|
||||||
desc: 'Signs data from a specific account. This account needs to be unlocked.',
|
|
||||||
args: [{
|
|
||||||
name: 'address',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'Address to sign with.'
|
|
||||||
}, {
|
|
||||||
name: 'dataToSign',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'Data to sign.'
|
|
||||||
}, {
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'If you pass a callback the HTTP request is made asynchronous.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
call: {
|
|
||||||
desc: 'Executes a message call transaction, which is directly executed in the VM of the node, but never mined into the blockchain.',
|
|
||||||
args: [{
|
|
||||||
name: 'callObject',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'Address to sign with.'
|
|
||||||
}, {
|
|
||||||
name: 'defaultBlock',
|
|
||||||
type: 'String',
|
|
||||||
optional: true,
|
|
||||||
desc: 'Data to sign.'
|
|
||||||
}, {
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'If you pass a callback the HTTP request is made asynchronous.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
estimateGas: {
|
|
||||||
desc: 'Executes a message call or transaction, which is directly executed in the VM of the node, but never mined into the blockchain and returns the amount of the gas used.',
|
|
||||||
args: [{
|
|
||||||
name: 'callObject',
|
|
||||||
type: 'Object',
|
|
||||||
desc: 'The transaction object to send: {[from][, to][, value][, gas][, gasPrice][, data][, nonce]}'
|
|
||||||
}, {
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'If you pass a callback the HTTP request is made asynchronous.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
// TODO: add description
|
|
||||||
desc: '',
|
|
||||||
args: [{
|
|
||||||
name: 'options',
|
|
||||||
type: 'String|Object',
|
|
||||||
desc: 'The string "latest" or "pending" to watch for changes in the latest block or pending transactions respectively. Or a filter options object as follows: {fromBlock: Number|String, toBlock: Number|String, address: String, topics: StringArray}'
|
|
||||||
}, {
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'Watch callback'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
// TODO filters
|
|
||||||
// watch : ['callback'],
|
|
||||||
// stopWatching : ['callback'],
|
|
||||||
contract: {
|
|
||||||
desc: 'Creates a contract object for a solidity contract, which can be used to initiate contracts on an address.',
|
|
||||||
args: [{
|
|
||||||
name: 'abiArray',
|
|
||||||
type: 'Array',
|
|
||||||
desc: 'ABI array with descriptions of functions and events of the contract.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
getCompilers: {
|
|
||||||
desc: 'Gets a list of available compilers.',
|
|
||||||
args: [{
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'If you pass a callback the HTTP request is made asynchronous.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
compile: { // TODO we should auto hide these depending on output from getCompilers
|
|
||||||
lll: {
|
|
||||||
desc: 'Compiles LLL source code.',
|
|
||||||
args: [{
|
|
||||||
name: 'sourceString',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The LLL source code.'
|
|
||||||
}, {
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'Watch callback'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
solidity: {
|
|
||||||
desc: 'Compiles solidity source code',
|
|
||||||
args: [{
|
|
||||||
name: 'sourceString',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The solidity source code.'
|
|
||||||
}, {
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'Watch callback'
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
serpent: {
|
|
||||||
desc: 'Compiles serpent source code',
|
|
||||||
args: [{
|
|
||||||
name: 'sourceString',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The serpent source code.'
|
|
||||||
}, {
|
|
||||||
name: 'callback',
|
|
||||||
type: 'Function',
|
|
||||||
optional: true,
|
|
||||||
desc: 'Watch callback'
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
namereg: {
|
|
||||||
desc: 'Returns GlobalRegistrar object.'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
db: {
|
|
||||||
putString: {
|
|
||||||
desc: 'Store a string in the local leveldb database.',
|
|
||||||
args: [{
|
|
||||||
name: 'db',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The database to store to.'
|
|
||||||
}, {
|
|
||||||
name: 'key',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The name of the store.'
|
|
||||||
}, {
|
|
||||||
name: 'value',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The string value to store.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
getString: {
|
|
||||||
desc: 'Retrieve a string from the local leveldb database. (db, key)',
|
|
||||||
args: [{
|
|
||||||
name: 'db',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The database string name to retrieve from.'
|
|
||||||
}, {
|
|
||||||
name: 'key',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The name of the store.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
putHex: {
|
|
||||||
desc: 'Store binary data in the local leveldb database. (db, key, value)',
|
|
||||||
args: [{
|
|
||||||
name: 'db',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The database to store to.'
|
|
||||||
}, {
|
|
||||||
name: 'key',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The name of the store.'
|
|
||||||
}, {
|
|
||||||
name: 'value',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The HEX string to store.'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
getHex: {
|
|
||||||
desc: 'Retrieve binary data from the local leveldb database. (db, key)',
|
|
||||||
args: [{
|
|
||||||
name: 'db',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The database string name to retrieve from.'
|
|
||||||
}, {
|
|
||||||
name: 'key',
|
|
||||||
type: 'String',
|
|
||||||
desc: 'The name of the store.'
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,146 +0,0 @@
|
||||||
function round(n) {
|
|
||||||
return Math.round(n * 100) / 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
function doubledValueLabel(params) {
|
|
||||||
var value = round(params.value);
|
|
||||||
return "sliderValue = " + value +
|
|
||||||
"; (2 * sliderValue) = " + (2 * value);
|
|
||||||
}
|
|
||||||
|
|
||||||
status.defineSubscription(
|
|
||||||
// the name of subscription and the name of the value in bot-db
|
|
||||||
// associated with this subscription
|
|
||||||
"doubledValue",
|
|
||||||
// the map of values on which subscription depends: keys are arbitrary names
|
|
||||||
// and values are db paths to another value
|
|
||||||
{value: ["sliderValue"]},
|
|
||||||
// the function which will be called as reaction on changes of values above,
|
|
||||||
// should be pure. Returned result will be associated with subscription in bot-db
|
|
||||||
doubledValueLabel
|
|
||||||
);
|
|
||||||
|
|
||||||
status.defineSubscription(
|
|
||||||
"roundedValue",
|
|
||||||
{value: ["sliderValue"]},
|
|
||||||
function (params) {
|
|
||||||
return round(params.value);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
function demoSuggestions(params, context) {
|
|
||||||
var balance = parseFloat(web3.fromWei(web3.eth.getBalance(context.from), "ether"));
|
|
||||||
var defaultSliderValue = balance / 2;
|
|
||||||
|
|
||||||
var view = ["view", {},
|
|
||||||
["text", {}, "Balance " + balance + " ETH"],
|
|
||||||
["text", {}, ["subscribe", ["doubledValue"]]],
|
|
||||||
["slider", {
|
|
||||||
maximumValue: ["subscribe", ["balance"]],
|
|
||||||
value: defaultSliderValue,
|
|
||||||
minimumValue: 0,
|
|
||||||
onSlidingComplete: ["dispatch", ["set", "sliderValue"]],
|
|
||||||
step: 0.05
|
|
||||||
}],
|
|
||||||
['touchable',
|
|
||||||
{onPress: ['dispatch', ["set-value-from-db", "roundedValue"]]},
|
|
||||||
["view", {}, ["text", {}, "Set value"]]
|
|
||||||
],
|
|
||||||
["text", {style: {color: "red"}}, ["subscribe", ["validationText"]]]
|
|
||||||
];
|
|
||||||
|
|
||||||
status.setDefaultDb({
|
|
||||||
sliderValue: defaultSliderValue,
|
|
||||||
doubledValue: doubledValueLabel({value: defaultSliderValue})
|
|
||||||
});
|
|
||||||
|
|
||||||
var validationText = "";
|
|
||||||
|
|
||||||
if (typeof params !== 'undefined') {
|
|
||||||
if (isNaN(params.message)) {
|
|
||||||
validationText = "That's not a float number!";
|
|
||||||
} else if (parseFloat(params.message) > balance) {
|
|
||||||
validationText =
|
|
||||||
"Input value is too big!" +
|
|
||||||
" You have only " + balance + " ETH on your balance!";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
status.updateDb({
|
|
||||||
balance: balance,
|
|
||||||
validationText: validationText
|
|
||||||
});
|
|
||||||
|
|
||||||
return {markup: view};
|
|
||||||
}
|
|
||||||
|
|
||||||
status.addListener("on-message-input-change", demoSuggestions);
|
|
||||||
status.addListener("on-message-send", function (params, context) {
|
|
||||||
var cnt = localStorage.getItem("cnt");
|
|
||||||
if (!cnt) {
|
|
||||||
cnt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
cnt++;
|
|
||||||
|
|
||||||
localStorage.setItem("cnt", cnt);
|
|
||||||
if (isNaN(params.message)) {
|
|
||||||
return {"text-message": "Seems that you don't want to send money :(. cnt = " + cnt};
|
|
||||||
}
|
|
||||||
|
|
||||||
var balance = web3.eth.getBalance(context.from);
|
|
||||||
var value = parseFloat(params.message);
|
|
||||||
var weiValue = web3.toWei(value, "ether");
|
|
||||||
if (bn(weiValue).greaterThan(bn(balance))) {
|
|
||||||
return {"text-message": "No way man, you don't have enough money! :)"};
|
|
||||||
}
|
|
||||||
web3.eth.sendTransaction({
|
|
||||||
from: context.from,
|
|
||||||
to: context.from,
|
|
||||||
value: weiValue
|
|
||||||
}, function (error, hash) {
|
|
||||||
if (error) {
|
|
||||||
status.sendMessage("Something went wrong, try again :(");
|
|
||||||
status.showSuggestions(demoSuggestions(params, context).markup);
|
|
||||||
} else {
|
|
||||||
status.sendMessage("You are the hero, you sent " + value + " ETH to yourself!")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
status.command({
|
|
||||||
name: "init-request",
|
|
||||||
description: "send-request",
|
|
||||||
color: "#a187d5",
|
|
||||||
sequentialParams: true,
|
|
||||||
params: [{
|
|
||||||
name: "address",
|
|
||||||
type: status.types.TEXT,
|
|
||||||
placeholder: "address"
|
|
||||||
}],
|
|
||||||
handler: function (params) {
|
|
||||||
return {
|
|
||||||
"text-message": {
|
|
||||||
type: "request",
|
|
||||||
content: {
|
|
||||||
command: "response",
|
|
||||||
params: {first: "123"},
|
|
||||||
text: "That's request's content! It works!"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
status.response({
|
|
||||||
name: "response",
|
|
||||||
color: "#a187d5",
|
|
||||||
sequentialParams: true,
|
|
||||||
params: [{
|
|
||||||
name: "first",
|
|
||||||
type: status.types.TEXT,
|
|
||||||
placeholder: "first"
|
|
||||||
}],
|
|
||||||
handler: function (params) {
|
|
||||||
return {"text-message": "ok"};
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,305 +0,0 @@
|
||||||
|
|
||||||
// Send command/response
|
|
||||||
|
|
||||||
var assetSendParam = {
|
|
||||||
name: "asset",
|
|
||||||
type: status.types.TEXT,
|
|
||||||
suggestions: function (params) {
|
|
||||||
return {
|
|
||||||
markup: status.components.chooseAsset("asset", 0)
|
|
||||||
};
|
|
||||||
},
|
|
||||||
placeholder: I18n.t('currency_placeholder')
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
var recipientSendParam = {
|
|
||||||
name: "recipient",
|
|
||||||
type: status.types.TEXT,
|
|
||||||
suggestions: function (params) {
|
|
||||||
return {
|
|
||||||
title: I18n.t('send_title'),
|
|
||||||
markup: status.components.chooseContact(I18n.t('send_choose_recipient'), "recipient", 0)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function amountSendParam() {
|
|
||||||
return {
|
|
||||||
name: "amount",
|
|
||||||
type: status.types.NUMBER,
|
|
||||||
placeholder: I18n.t('amount_placeholder')
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var paramsPersonalSend = [assetSendParam, amountSendParam()];
|
|
||||||
var paramsGroupSend = [recipientSendParam, amountSendParam()];
|
|
||||||
|
|
||||||
function validateSend(validateRecipient, params, context) {
|
|
||||||
|
|
||||||
var allowedAssets = context["allowed-assets"];
|
|
||||||
var asset = params["asset"];
|
|
||||||
|
|
||||||
if(!allowedAssets.hasOwnProperty(asset)){
|
|
||||||
return {
|
|
||||||
markup: status.components.validationMessage(
|
|
||||||
"Invalid asset",
|
|
||||||
"Unknown token - " + asset
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!params["amount"]) {
|
|
||||||
return {
|
|
||||||
markup: status.components.validationMessage(
|
|
||||||
I18n.t('validation_title'),
|
|
||||||
I18n.t('validation_amount_specified')
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var amount = params["amount"].replace(",", ".");
|
|
||||||
var amountSplitted = amount.split(".");
|
|
||||||
var decimals = allowedAssets[asset];
|
|
||||||
if (amountSplitted.length === 2 && amountSplitted[1].length > decimals) {
|
|
||||||
return {
|
|
||||||
markup: status.components.validationMessage(
|
|
||||||
I18n.t('validation_title'),
|
|
||||||
I18n.t('validation_amount_is_too_small') + decimals
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNaN(parseFloat(params.amount.replace(",", ".")))) {
|
|
||||||
return {
|
|
||||||
markup: status.components.validationMessage(
|
|
||||||
I18n.t('validation_title'),
|
|
||||||
I18n.t('validation_invalid_number')
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
var val = web3.toWei(amount, "ether");
|
|
||||||
if (val < 0) {
|
|
||||||
throw new Error();
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
return {
|
|
||||||
markup: status.components.validationMessage(
|
|
||||||
I18n.t('validation_title'),
|
|
||||||
I18n.t('validation_invalid_number')
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleSend(params, context) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var personalSend = {
|
|
||||||
name: "send",
|
|
||||||
scope: ["global", "personal-chats", "registered", "humans"],
|
|
||||||
icon: "money_white",
|
|
||||||
color: "#5fc48d",
|
|
||||||
title: I18n.t('send_title'),
|
|
||||||
description: I18n.t('send_description'),
|
|
||||||
params: paramsPersonalSend,
|
|
||||||
validator: validateSend.bind(this, false),
|
|
||||||
handler: handleSend.bind(this),
|
|
||||||
asyncHandler: false
|
|
||||||
};
|
|
||||||
|
|
||||||
var groupSend = {
|
|
||||||
name: "send",
|
|
||||||
scope: ["global", "group-chats", "registered", "humans"],
|
|
||||||
icon: "money_white",
|
|
||||||
color: "#5fc48d",
|
|
||||||
title: I18n.t('send_title'),
|
|
||||||
description: I18n.t('send_description'),
|
|
||||||
params: paramsGroupSend,
|
|
||||||
validator: validateSend.bind(this, true),
|
|
||||||
handler: handleSend.bind(this),
|
|
||||||
asyncHandler: false
|
|
||||||
};
|
|
||||||
|
|
||||||
status.command(personalSend);
|
|
||||||
status.response(personalSend);
|
|
||||||
|
|
||||||
status.command(groupSend);
|
|
||||||
status.response(groupSend);
|
|
||||||
|
|
||||||
// Request command
|
|
||||||
|
|
||||||
var assetRequestParam = {
|
|
||||||
name: "asset",
|
|
||||||
type: status.types.TEXT,
|
|
||||||
suggestions: function (params) {
|
|
||||||
return {
|
|
||||||
markup: status.components.chooseAsset("asset", 0)
|
|
||||||
};
|
|
||||||
},
|
|
||||||
placeholder: I18n.t('currency_placeholder')
|
|
||||||
};
|
|
||||||
|
|
||||||
var recipientRequestParam = {
|
|
||||||
name: "recipient",
|
|
||||||
type: status.types.TEXT,
|
|
||||||
suggestions: function (params) {
|
|
||||||
return {
|
|
||||||
title: I18n.t('request_title'),
|
|
||||||
markup: status.components.chooseContact(I18n.t('send_choose_recipient'), "recipient", 0)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var amountRequestParam = {
|
|
||||||
name: "amount",
|
|
||||||
type: status.types.NUMBER,
|
|
||||||
placeholder: I18n.t('amount_placeholder')
|
|
||||||
};
|
|
||||||
|
|
||||||
var paramsPersonalRequest = [assetRequestParam, amountRequestParam];
|
|
||||||
var paramsGroupRequest = [recipientRequestParam, amountRequestParam];
|
|
||||||
|
|
||||||
function handlePersonalRequest(params, context) {
|
|
||||||
var val = params["amount"].replace(",", ".");
|
|
||||||
var network = context["network"];
|
|
||||||
var asset = params["asset"];
|
|
||||||
|
|
||||||
return {
|
|
||||||
event: "request",
|
|
||||||
request: {
|
|
||||||
command: "send",
|
|
||||||
params: {
|
|
||||||
network: network,
|
|
||||||
amount: val,
|
|
||||||
asset: asset
|
|
||||||
},
|
|
||||||
prefill: [asset, val]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleGroupRequest(params, context) {
|
|
||||||
var val = params["amount"].replace(",", ".");
|
|
||||||
var network = context["network"];
|
|
||||||
|
|
||||||
return {
|
|
||||||
event: "request",
|
|
||||||
request: {
|
|
||||||
command: "send",
|
|
||||||
params: {
|
|
||||||
recipient: context["current-account"]["name"],
|
|
||||||
network: network,
|
|
||||||
amount: val
|
|
||||||
},
|
|
||||||
prefill: [context["current-account"]["name"], val],
|
|
||||||
prefillBotDb: {
|
|
||||||
public: {
|
|
||||||
recipient: context["current-account"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateRequest(validateRecipient, params, context) {
|
|
||||||
if (!params["bot-db"]) {
|
|
||||||
params["bot-db"] = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (validateRecipient) {
|
|
||||||
if (!params["bot-db"]["public"] || !params["bot-db"]["public"]["recipient"] || !params["bot-db"]["public"]["recipient"]["address"]) {
|
|
||||||
return {
|
|
||||||
markup: status.components.validationMessage(
|
|
||||||
"Wrong address",
|
|
||||||
"Recipient address must be specified"
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var allowedAssets = context["allowed-assets"];
|
|
||||||
var asset = params["asset"];
|
|
||||||
|
|
||||||
if(!allowedAssets.hasOwnProperty(asset)){
|
|
||||||
return {
|
|
||||||
markup: status.components.validationMessage(
|
|
||||||
"Invalid asset",
|
|
||||||
"Unknown token - " + asset
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!params["amount"]) {
|
|
||||||
return {
|
|
||||||
markup: status.components.validationMessage(
|
|
||||||
I18n.t('validation_title'),
|
|
||||||
I18n.t('validation_amount_specified')
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var amount = params.amount.replace(",", ".");
|
|
||||||
var amountSplitted = amount.split(".");
|
|
||||||
var decimals = allowedAssets[asset];
|
|
||||||
if (amountSplitted.length === 2 && amountSplitted[1].length > decimals) {
|
|
||||||
return {
|
|
||||||
markup: status.components.validationMessage(
|
|
||||||
I18n.t('validation_title'),
|
|
||||||
I18n.t('validation_amount_is_too_small') + decimals
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNaN(parseFloat(params.amount.replace(",", ".")))) {
|
|
||||||
return {
|
|
||||||
markup: status.components.validationMessage(
|
|
||||||
I18n.t('validation_title'),
|
|
||||||
I18n.t('validation_invalid_number')
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
var val = web3.toWei(amount, "ether");
|
|
||||||
if (val < 0) {
|
|
||||||
throw new Error();
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
return {
|
|
||||||
markup: status.components.validationMessage(
|
|
||||||
I18n.t('validation_title'),
|
|
||||||
I18n.t('validation_invalid_number')
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
status.command({
|
|
||||||
name: "request",
|
|
||||||
scope: ["global", "personal-chats", "registered", "humans"],
|
|
||||||
icon: "money_white",
|
|
||||||
color: "#5fc48d",
|
|
||||||
title: I18n.t('request_title'),
|
|
||||||
description: I18n.t('request_description'),
|
|
||||||
params: paramsPersonalRequest,
|
|
||||||
handler: handlePersonalRequest,
|
|
||||||
validator: validateRequest.bind(null, false)
|
|
||||||
});
|
|
||||||
|
|
||||||
status.command({
|
|
||||||
name: "request",
|
|
||||||
scope: ["global", "group-chats", "registered", "humans"],
|
|
||||||
icon: "money_white",
|
|
||||||
color: "#5fc48d",
|
|
||||||
title: I18n.t('request_title'),
|
|
||||||
description: I18n.t('request_description'),
|
|
||||||
params: paramsGroupRequest,
|
|
||||||
handler: handleGroupRequest,
|
|
||||||
validator: validateRequest.bind(null, true)
|
|
||||||
});
|
|
|
@ -1,490 +0,0 @@
|
||||||
I18n.translations = {
|
|
||||||
en: {
|
|
||||||
send_title: 'Send transaction',
|
|
||||||
send_description: 'Send a payment',
|
|
||||||
send_choose_recipient: 'Choose recipient',
|
|
||||||
send_specify_amount: 'Specify amount',
|
|
||||||
send_sending_to: 'to ',
|
|
||||||
|
|
||||||
currency_placeholder: 'Currency',
|
|
||||||
amount_placeholder: 'Amount',
|
|
||||||
|
|
||||||
eth: 'ETH',
|
|
||||||
|
|
||||||
request_title: 'Request ETH',
|
|
||||||
request_description: 'Request a payment',
|
|
||||||
request_requesting: 'Requesting ',
|
|
||||||
request_requesting_from: 'from ',
|
|
||||||
|
|
||||||
validation_internal_title: 'Internal error',
|
|
||||||
validation_balance: 'Could not fetch current balance',
|
|
||||||
validation_title: 'Amount',
|
|
||||||
validation_tx_title: 'Transaction',
|
|
||||||
validation_tx_failed: 'Transaction failed',
|
|
||||||
validation_amount_specified: 'Amount must be specified',
|
|
||||||
validation_invalid_number: 'Amount is not valid number',
|
|
||||||
validation_amount_is_too_small: 'Max number of decimals is ',
|
|
||||||
validation_insufficient_amount: 'Insufficient funds for gas * price + value (balance '
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
,
|
|
||||||
ru: {
|
|
||||||
send_title: 'Отправить транзакцию',
|
|
||||||
send_description: 'Отправить платеж',
|
|
||||||
|
|
||||||
request_title: 'Запросить ETH',
|
|
||||||
request_description: 'Запросить платеж',
|
|
||||||
request_requesting: 'Запрос ',
|
|
||||||
|
|
||||||
validation_title: 'Сумма',
|
|
||||||
validation_amount_specified: 'Необходимо указать сумму',
|
|
||||||
validation_invalid_number: 'Сумма не является действительным числом',
|
|
||||||
validation_amount_is_too_small: 'Сумма излишне точная. Минимальная единица, которую можно отправить — 1 Wei (1x10^-18 ETH)',
|
|
||||||
validation_insufficient_amount: 'Недостаточно ETH на балансе ('
|
|
||||||
},
|
|
||||||
af: {
|
|
||||||
send_title: 'Stuur ETH',
|
|
||||||
send_description: 'Stuur \'n betaling',
|
|
||||||
|
|
||||||
request_title: 'Versoek ETH',
|
|
||||||
request_description: 'Versoek \'n betaling',
|
|
||||||
request_requesting: 'Besig met versoek ',
|
|
||||||
|
|
||||||
validation_title: 'Bedrag',
|
|
||||||
validation_amount_specified: 'Bedrag moet gespesifiseer word',
|
|
||||||
validation_invalid_number: 'Bedrag is nie \'n geldige syfer nie',
|
|
||||||
validation_insufficient_amount: 'Nie genoeg ETH in rekening nie ('
|
|
||||||
},
|
|
||||||
ar: {
|
|
||||||
send_title: 'إرسال ETH',
|
|
||||||
send_description: 'إرسال مدفوعات',
|
|
||||||
|
|
||||||
request_title: 'طلب ETH',
|
|
||||||
request_description: 'طلب مدفوعات',
|
|
||||||
request_requesting: 'مُطَالَبَة ',
|
|
||||||
|
|
||||||
validation_title: 'المبلغ',
|
|
||||||
validation_amount_specified: 'يجب تحديد المبلغ',
|
|
||||||
validation_invalid_number: 'المبلغ المحدد غير صحيح',
|
|
||||||
validation_insufficient_amount: 'لا يوجد ETH كافي بالحساب ('
|
|
||||||
},
|
|
||||||
'zh-hant': {
|
|
||||||
send_title: '發送 ETH',
|
|
||||||
send_description: '付款',
|
|
||||||
|
|
||||||
request_title: '請求 ETH',
|
|
||||||
request_description: '要求付款',
|
|
||||||
request_requesting: '正在請求 ',
|
|
||||||
|
|
||||||
validation_title: '金額',
|
|
||||||
validation_amount_specified: '必須指定金額',
|
|
||||||
validation_invalid_number: '金額不是有效數字',
|
|
||||||
validation_insufficient_amount: 'ETH 餘額不足 ('
|
|
||||||
},
|
|
||||||
'zh-hant-tw': {
|
|
||||||
send_title: '傳送 ETH',
|
|
||||||
send_description: '付款',
|
|
||||||
|
|
||||||
request_title: '請求 ETH',
|
|
||||||
request_description: '要求付款',
|
|
||||||
request_requesting: '正在請求 ',
|
|
||||||
|
|
||||||
validation_title: '金額',
|
|
||||||
validation_amount_specified: '必須指定金額',
|
|
||||||
validation_invalid_number: '金額不是有效數字',
|
|
||||||
validation_insufficient_amount: 'ETH 餘額不足 ('
|
|
||||||
},
|
|
||||||
'zh-hant-sg': {
|
|
||||||
send_title: '傳送 ETH',
|
|
||||||
send_description: '付款',
|
|
||||||
|
|
||||||
request_title: '請求 ETH',
|
|
||||||
request_description: '要求付款',
|
|
||||||
request_requesting: '正在請求 ',
|
|
||||||
|
|
||||||
validation_title: '金額',
|
|
||||||
validation_amount_specified: '必須指定金額',
|
|
||||||
validation_invalid_number: '金額不是有效數字',
|
|
||||||
validation_insufficient_amount: 'ETH 餘額不足 ('
|
|
||||||
},
|
|
||||||
'zh-hant-hk': {
|
|
||||||
send_title: '發送 ETH',
|
|
||||||
send_description: '付款',
|
|
||||||
|
|
||||||
request_title: '請求 ETH',
|
|
||||||
request_description: '要求付款',
|
|
||||||
request_requesting: '正在請求 ',
|
|
||||||
|
|
||||||
validation_title: '金額',
|
|
||||||
validation_amount_specified: '必須指定金額',
|
|
||||||
validation_invalid_number: '金額不是有效數字',
|
|
||||||
validation_insufficient_amount: 'ETH 餘額不足 ('
|
|
||||||
},
|
|
||||||
'zh-hans': {
|
|
||||||
send_title: '发送 ETH',
|
|
||||||
send_description: '付款',
|
|
||||||
|
|
||||||
request_title: '请求 ETH',
|
|
||||||
request_description: '要求付款',
|
|
||||||
request_requesting: '正在请求 ',
|
|
||||||
|
|
||||||
validation_title: '金额',
|
|
||||||
validation_amount_specified: '必须指定金额',
|
|
||||||
validation_invalid_number: '金额不是有效数字',
|
|
||||||
validation_insufficient_amount: 'ETH 余额不足 ('
|
|
||||||
},
|
|
||||||
'zh-yue': {
|
|
||||||
send_title: '發送 ETH',
|
|
||||||
send_description: '發送付款',
|
|
||||||
|
|
||||||
request_title: '請求 ETH',
|
|
||||||
request_description: '請求付款',
|
|
||||||
request_requesting: '請求中 ',
|
|
||||||
|
|
||||||
validation_title: '金額',
|
|
||||||
validation_amount_specified: '必須指定金額',
|
|
||||||
validation_invalid_number: '指定金額並非有效數字',
|
|
||||||
validation_insufficient_amount: '沒有足夠 ETH 餘額 ('
|
|
||||||
},
|
|
||||||
'zh-wuu': {
|
|
||||||
send_title: '发送 ETH',
|
|
||||||
send_description: '发送付款',
|
|
||||||
|
|
||||||
request_title: '请求 ETH',
|
|
||||||
request_description: '请求付款',
|
|
||||||
request_requesting: '请求中 ',
|
|
||||||
|
|
||||||
validation_title: '金额',
|
|
||||||
validation_amount_specified: '金额必须明确',
|
|
||||||
validation_invalid_number: '金额不是一个有效数字',
|
|
||||||
validation_insufficient_amount: 'ETH 余额不足 ('
|
|
||||||
},
|
|
||||||
nl: {
|
|
||||||
send_title: 'Stuur ETH',
|
|
||||||
send_description: 'Stuur een betaling',
|
|
||||||
|
|
||||||
request_title: 'Vraag ETH aan',
|
|
||||||
request_description: 'Vraag om een betaling',
|
|
||||||
request_requesting: 'Wordt aangevraagd ',
|
|
||||||
|
|
||||||
validation_title: 'Bedrag',
|
|
||||||
validation_amount_specified: 'Bedrag moet worden opgegeven',
|
|
||||||
validation_invalid_number: 'Bedrag is geen geldig nummer',
|
|
||||||
validation_insufficient_amount: 'Niet genoeg ETH op saldo ('
|
|
||||||
},
|
|
||||||
fr: {
|
|
||||||
send_title: 'Envoyer l\'ETH',
|
|
||||||
send_description: 'Envoyer un paiement',
|
|
||||||
|
|
||||||
request_title: 'Demander l\'ETH',
|
|
||||||
request_description: 'Demander un paiement',
|
|
||||||
request_requesting: 'Demande en cours: ',
|
|
||||||
|
|
||||||
validation_title: 'Montant',
|
|
||||||
validation_amount_specified: 'Le montant doit être spécifié',
|
|
||||||
validation_invalid_number: 'Le montant n\'est pas un nombre valide',
|
|
||||||
validation_insufficient_amount: 'Pas assez d\'ETH sur le solde ('
|
|
||||||
},
|
|
||||||
de: {
|
|
||||||
send_title: 'ETH abschicken',
|
|
||||||
send_description: 'Zahlung senden',
|
|
||||||
|
|
||||||
request_title: 'ETH anfragen',
|
|
||||||
request_description: 'Zahlung anfragen',
|
|
||||||
request_requesting: 'Anfrage: ',
|
|
||||||
|
|
||||||
validation_title: 'Betrag',
|
|
||||||
validation_amount_specified: 'Betrag muss angegeben werden',
|
|
||||||
validation_invalid_number: 'Betrag ist keine gültige Zahl',
|
|
||||||
validation_insufficient_amount: 'Nicht genügend ETH auf dem Konto ('
|
|
||||||
},
|
|
||||||
hi: {
|
|
||||||
send_title: 'ETH भेजें',
|
|
||||||
send_description: 'भुगतान भेजें',
|
|
||||||
|
|
||||||
request_title: 'ETH का अनुरोध करें',
|
|
||||||
request_description: 'भुगतान का अनुरोध करें',
|
|
||||||
request_requesting: 'अनुरोध किया जा रहा है ',
|
|
||||||
|
|
||||||
validation_title: 'राशि',
|
|
||||||
validation_amount_specified: 'राशि निर्दिष्ट की जानी चाहिए',
|
|
||||||
validation_invalid_number: 'राशि वैध संख्या नहीं है',
|
|
||||||
validation_insufficient_amount: 'बैलेंस पर पर्याप्त ETH नहीं है ('
|
|
||||||
},
|
|
||||||
hu: {
|
|
||||||
send_title: 'ETH küldése',
|
|
||||||
send_description: 'Kifizetés küldése',
|
|
||||||
|
|
||||||
request_title: 'ETH igénylése',
|
|
||||||
request_description: 'Fizetés igénylése',
|
|
||||||
request_requesting: 'Igénylés ',
|
|
||||||
|
|
||||||
validation_title: 'Összeg',
|
|
||||||
validation_amount_specified: 'Az összeget meg kell határozni',
|
|
||||||
validation_invalid_number: 'Az összeg nem egy elfogadott szám',
|
|
||||||
validation_insufficient_amount: 'Nincs elég ETH a számlán ('
|
|
||||||
},
|
|
||||||
it: {
|
|
||||||
send_title: 'Invia ETH',
|
|
||||||
send_description: 'Invia un pagamento',
|
|
||||||
|
|
||||||
request_title: 'Richiedi ETH',
|
|
||||||
request_description: 'Richiedi un pagamento',
|
|
||||||
request_requesting: 'Richiesta in corso: ',
|
|
||||||
|
|
||||||
validation_title: 'Ammontare',
|
|
||||||
validation_amount_specified: 'L\'ammontare deve essere specificato',
|
|
||||||
validation_invalid_number: 'L\'ammontare non è un numero valido',
|
|
||||||
validation_insufficient_amount: 'ETH insufficiente sul bilancio ('
|
|
||||||
},
|
|
||||||
ja: {
|
|
||||||
send_title: 'ETHを送信',
|
|
||||||
send_description: '支払いを送信',
|
|
||||||
|
|
||||||
request_title: 'ETHをリクエスト',
|
|
||||||
request_description: '支払いをリクエスト',
|
|
||||||
request_requesting: 'リクエスト中 ',
|
|
||||||
|
|
||||||
validation_title: '金額',
|
|
||||||
validation_amount_specified: '金額を特定する必要があります',
|
|
||||||
validation_invalid_number: '金額は有効な数字ではありません',
|
|
||||||
validation_insufficient_amount: '残高に十分なETHがありません('
|
|
||||||
},
|
|
||||||
ko: {
|
|
||||||
send_title: 'ETH 보내기',
|
|
||||||
send_description: '지불금 보내기',
|
|
||||||
|
|
||||||
request_title: 'ETH 요청',
|
|
||||||
request_description: '지불금 요청',
|
|
||||||
request_requesting: '요청 중 ',
|
|
||||||
|
|
||||||
validation_title: '금액',
|
|
||||||
validation_amount_specified: '금액을 지정해야 합니다',
|
|
||||||
validation_invalid_number: '금액이 유효한 숫자가 아닙니다',
|
|
||||||
validation_insufficient_amount: 'ETH 잔고가 부족합니다 ('
|
|
||||||
},
|
|
||||||
pl: {
|
|
||||||
send_title: 'Wyślij ETH',
|
|
||||||
send_description: 'Wyślij płatność',
|
|
||||||
|
|
||||||
request_title: 'Poproś o ETH',
|
|
||||||
request_description: 'Poproś o płatność',
|
|
||||||
request_requesting: 'Przesyłanie prośby ',
|
|
||||||
|
|
||||||
validation_title: 'Kwota',
|
|
||||||
validation_amount_specified: 'Należy określić kwotę',
|
|
||||||
validation_invalid_number: 'Kwota nie jest prawidłową liczbą',
|
|
||||||
validation_insufficient_amount: 'Brak wystarczającej liczby ETH na koncie ('
|
|
||||||
},
|
|
||||||
'pt-br': {
|
|
||||||
send_title: 'Enviar ETH',
|
|
||||||
send_description: 'Enviar um pagamento',
|
|
||||||
|
|
||||||
request_title: 'Solicitar ETH',
|
|
||||||
request_description: 'Solicitar um pagamento',
|
|
||||||
request_requesting: 'Solicitando ',
|
|
||||||
|
|
||||||
validation_title: 'Quantia',
|
|
||||||
validation_amount_specified: 'É necessário especificar a quantia',
|
|
||||||
validation_invalid_number: 'A quantia não é um número válido',
|
|
||||||
validation_insufficient_amount: 'ETH insuficiente no saldo ('
|
|
||||||
},
|
|
||||||
'pt-pt': {
|
|
||||||
send_title: 'Enviar ETH',
|
|
||||||
send_description: 'Enviar um pagamento',
|
|
||||||
|
|
||||||
request_title: 'Solicitar ETH',
|
|
||||||
request_description: 'Solicitar um pagamento',
|
|
||||||
request_requesting: 'A solicitar ',
|
|
||||||
|
|
||||||
validation_title: 'Montante',
|
|
||||||
validation_amount_specified: 'O montante deve ser especificado',
|
|
||||||
validation_invalid_number: 'O montante não é um número válido',
|
|
||||||
validation_insufficient_amount: 'Não há ETH suficiente no saldo ('
|
|
||||||
},
|
|
||||||
ro: {
|
|
||||||
send_title: 'Trimite ETH',
|
|
||||||
send_description: 'Trimite o plată',
|
|
||||||
|
|
||||||
request_title: 'Solicită ETH',
|
|
||||||
request_description: 'Solicită o plată',
|
|
||||||
request_requesting: 'Se solicită ',
|
|
||||||
|
|
||||||
validation_title: 'Sumă',
|
|
||||||
validation_amount_specified: 'Trebuie menționată o sumă',
|
|
||||||
validation_invalid_number: 'Suma nu are forma unui număr valid',
|
|
||||||
validation_insufficient_amount: 'Sold ETH insuficient ('
|
|
||||||
},
|
|
||||||
sl: {
|
|
||||||
send_title: 'Pošlji ETH',
|
|
||||||
send_description: 'Pošlji plačilo',
|
|
||||||
|
|
||||||
request_title: 'Zahtevaj ETH',
|
|
||||||
request_description: 'Zahtevaj plačilo',
|
|
||||||
request_requesting: 'Zahtevam ',
|
|
||||||
|
|
||||||
validation_title: 'Vsota',
|
|
||||||
validation_amount_specified: 'Vsota mora biti izrecno navedena',
|
|
||||||
validation_invalid_number: 'Vsota ni veljavna številka',
|
|
||||||
validation_insufficient_amount: 'Stanje ETH na računu je prenizko ('
|
|
||||||
},
|
|
||||||
es: {
|
|
||||||
send_title: 'Enviar ETH ',
|
|
||||||
send_description: 'Enviar un pago',
|
|
||||||
|
|
||||||
request_title: 'Solicitar ETH',
|
|
||||||
request_description: 'Solicitar un pago',
|
|
||||||
request_requesting: 'Solicitando ',
|
|
||||||
|
|
||||||
validation_title: 'Cantidad',
|
|
||||||
validation_amount_specified: 'Hay que especificar la cantidad',
|
|
||||||
validation_invalid_number: 'La cantidad no es un número válido',
|
|
||||||
validation_insufficient_amount: 'No hay suficiente ETH en conjunto ('
|
|
||||||
},
|
|
||||||
'es-ar': {
|
|
||||||
send_title: 'Enviar ETH',
|
|
||||||
send_description: 'Enviar un pago',
|
|
||||||
|
|
||||||
request_title: 'Solicitar ETH',
|
|
||||||
request_description: 'Solicitar un pago',
|
|
||||||
request_requesting: 'Solicitando ',
|
|
||||||
|
|
||||||
validation_title: 'Monto',
|
|
||||||
validation_amount_specified: 'Debes especificar el monto',
|
|
||||||
validation_invalid_number: 'El monto no es un número válido',
|
|
||||||
validation_insufficient_amount: 'No tienes suficiente ETH en tu saldo ('
|
|
||||||
},
|
|
||||||
sw: {
|
|
||||||
send_title: 'Tuma ETH',
|
|
||||||
send_description: 'Tuma malipo',
|
|
||||||
|
|
||||||
request_title: 'Omba ETH',
|
|
||||||
request_description: 'Omba malipo',
|
|
||||||
request_requesting: 'Kuomba ',
|
|
||||||
|
|
||||||
validation_title: 'Kiasi',
|
|
||||||
validation_amount_specified: 'Kiasi lazima kifafanuliwe',
|
|
||||||
validation_invalid_number: 'Kiasi si nambari halali',
|
|
||||||
validation_insufficient_amount: 'ETH haitoshi kwenye salio ('
|
|
||||||
},
|
|
||||||
sv: {
|
|
||||||
send_title: 'Skicka ETH',
|
|
||||||
send_description: 'Skicka en betalning',
|
|
||||||
|
|
||||||
request_title: 'Begär ETH',
|
|
||||||
request_description: 'Begär en betalning',
|
|
||||||
request_requesting: 'Begär ',
|
|
||||||
|
|
||||||
validation_title: 'Belopp',
|
|
||||||
validation_amount_specified: 'Beloppet måste anges',
|
|
||||||
validation_invalid_number: 'Beloppet är inte ett giltigt nummer',
|
|
||||||
validation_insufficient_amount: 'Inte tillräcklig ETH på balansen ('
|
|
||||||
},
|
|
||||||
'fr-ch': {
|
|
||||||
send_title: 'Envoyer des ETH',
|
|
||||||
send_description: 'Envoyer un paiement',
|
|
||||||
|
|
||||||
request_title: 'Demander des ETH',
|
|
||||||
request_description: 'Demander un paiement',
|
|
||||||
request_requesting: 'Demande ',
|
|
||||||
|
|
||||||
validation_title: 'Montant',
|
|
||||||
validation_amount_specified: 'Le montant doit être spécifié',
|
|
||||||
validation_invalid_number: 'Le montant n\'est pas un nombre valable',
|
|
||||||
validation_insufficient_amount: 'Pas assez d\'ETH sur le solde ('
|
|
||||||
},
|
|
||||||
'de-ch': {
|
|
||||||
send_title: 'Sende ETH',
|
|
||||||
send_description: 'Sende eine Zahlung',
|
|
||||||
|
|
||||||
request_title: 'Fordere ETH an',
|
|
||||||
request_description: 'Eine Zahlung anfordern',
|
|
||||||
request_requesting: 'Anfordern ',
|
|
||||||
|
|
||||||
validation_title: 'Betrag',
|
|
||||||
validation_amount_specified: 'Der Betrag muss angegeben werden',
|
|
||||||
validation_invalid_number: 'Der Betrag ist nicht gültig',
|
|
||||||
validation_insufficient_amount: 'Nicht genug ETH vorhanden ('
|
|
||||||
},
|
|
||||||
'it-ch': {
|
|
||||||
send_title: 'Invia ETH',
|
|
||||||
send_description: 'Invia un pagamento',
|
|
||||||
|
|
||||||
request_title: 'Richiedi ETH',
|
|
||||||
request_description: 'Richiedi un pagamento',
|
|
||||||
request_requesting: 'Richiesta in corso: ',
|
|
||||||
|
|
||||||
validation_title: 'Importo',
|
|
||||||
validation_amount_specified: 'Specificare l\'importo',
|
|
||||||
validation_invalid_number: 'Importo inserito non valido',
|
|
||||||
validation_insufficient_amount: 'Saldo ETH non sufficiente ('
|
|
||||||
},
|
|
||||||
th: {
|
|
||||||
send_title: 'ส่ง ETH',
|
|
||||||
send_description: 'ส่งการชำระเงิน',
|
|
||||||
|
|
||||||
request_title: 'ร้องขอ ETH',
|
|
||||||
request_description: 'ร้องขอการชำระเงิน',
|
|
||||||
request_requesting: 'กำลังร้องขอ ',
|
|
||||||
|
|
||||||
validation_title: 'จำนวน',
|
|
||||||
validation_amount_specified: 'จำเป็นต้องระบุจำนวน',
|
|
||||||
validation_invalid_number: 'จำนวนไม่ใช่หมายเลขที่ถูกต้อง',
|
|
||||||
validation_insufficient_amount: 'มี ETH ไม่เพียงพอในยอดคงเหลือ ('
|
|
||||||
},
|
|
||||||
tr: {
|
|
||||||
send_title: 'ETH gönder',
|
|
||||||
send_description: 'Bir ödeme gönder',
|
|
||||||
|
|
||||||
request_title: 'ETH iste',
|
|
||||||
request_description: 'Bir ödeme iste',
|
|
||||||
request_requesting: 'İsteniyor ',
|
|
||||||
|
|
||||||
validation_title: 'Miktar',
|
|
||||||
validation_amount_specified: 'Miktar belirtilmelidir',
|
|
||||||
validation_invalid_number: 'Miktar geçerli bir sayı değil',
|
|
||||||
validation_insufficient_amount: 'Yeterli ETH bakiyesi yok ('
|
|
||||||
},
|
|
||||||
uk: {
|
|
||||||
send_title: 'Надіслати ETH',
|
|
||||||
send_description: 'Надіслати платіж',
|
|
||||||
|
|
||||||
request_title: 'Запит ETH',
|
|
||||||
request_description: 'Запит платежу',
|
|
||||||
request_requesting: 'Запит ',
|
|
||||||
|
|
||||||
validation_title: 'Сума',
|
|
||||||
validation_amount_specified: 'Сума повинна бути вказана',
|
|
||||||
validation_invalid_number: 'Сума не дійсне число',
|
|
||||||
validation_insufficient_amount: 'Не вистачає ETH на балансі ('
|
|
||||||
},
|
|
||||||
ur: {
|
|
||||||
send_title: 'ETH بھیجیں',
|
|
||||||
send_description: 'ادائیگی کریں',
|
|
||||||
|
|
||||||
request_title: 'ETH کی درخواست دیں',
|
|
||||||
request_description: 'ادائیگی کی درخواست دیں',
|
|
||||||
request_requesting: 'درخواست کی جارہی ہے ',
|
|
||||||
|
|
||||||
validation_title: 'رقم',
|
|
||||||
validation_amount_specified: 'رقم درج کی جانی چاہیے۔ ',
|
|
||||||
validation_invalid_number: 'رقیم درست ہندسے نہیں ہیں',
|
|
||||||
validation_insufficient_amount: 'ETH میں کافی بیلنس نہیں ہے ('
|
|
||||||
},
|
|
||||||
vi: {
|
|
||||||
send_title: 'Gửi ETH',
|
|
||||||
send_description: 'Gửi một khoản thanh toán',
|
|
||||||
|
|
||||||
request_title: 'Yêu cầu ETH',
|
|
||||||
request_description: 'Yêu cầu một khoản thanh toán',
|
|
||||||
request_requesting: 'Đang yêu cầu ',
|
|
||||||
|
|
||||||
validation_title: 'Số tiền',
|
|
||||||
validation_amount_specified: 'Số tiền phải được xác định',
|
|
||||||
validation_invalid_number: 'Số tiền không phải là một số hợp lệ',
|
|
||||||
validation_insufficient_amount: 'Không đủ ETH trong số dư ('
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
};
|
|
|
@ -1,389 +0,0 @@
|
||||||
var _status_catalog = {
|
|
||||||
commands: {},
|
|
||||||
responses: {},
|
|
||||||
functions: {},
|
|
||||||
subscriptions: {}
|
|
||||||
},
|
|
||||||
status = {};
|
|
||||||
|
|
||||||
// This is default 'common sense' scope for commands/response which don't
|
|
||||||
// define any.
|
|
||||||
// We want the command/response to apply for 1-1 chats with registered user,
|
|
||||||
// as most of the bot developers will expect the sole registered user (for
|
|
||||||
// things like sending, etc.) and it will be non global, available only
|
|
||||||
// for that particular bot (that's what "dapps" in scope)
|
|
||||||
var defaultScope = ["personal-chats", "registered", "dapps"];
|
|
||||||
|
|
||||||
function scopeToBitMask(scope) {
|
|
||||||
// this function transforms scopes array to a single integer by generating a bit mask
|
|
||||||
return ((scope.indexOf("global") > -1) ? 1 : 0) |
|
|
||||||
((scope.indexOf("personal-chats") > -1) ? 2 : 0) |
|
|
||||||
((scope.indexOf("group-chats") > -1) ? 4 : 0) |
|
|
||||||
((scope.indexOf("anonymous") > -1) ? 8 : 0) |
|
|
||||||
((scope.indexOf("registered") > -1) ? 16 : 0) |
|
|
||||||
((scope.indexOf("dapps") > -1) ? 32 : 0) |
|
|
||||||
((scope.indexOf("humans") > -1) ? 64 : 0) |
|
|
||||||
((scope.indexOf("public-chats") > -1) ? 128 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
function Command() {
|
|
||||||
}
|
|
||||||
function Response() {
|
|
||||||
}
|
|
||||||
|
|
||||||
Command.prototype.addToCatalog = function () {
|
|
||||||
_status_catalog.commands[[this.name, this["scope-bitmask"]]] = this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Command.prototype.param = function (parameter) {
|
|
||||||
this.params.push(parameter);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Command.prototype.create = function (com) {
|
|
||||||
this.name = com.name;
|
|
||||||
this.title = com.title;
|
|
||||||
this.description = com.description;
|
|
||||||
this.handler = com.handler;
|
|
||||||
this["has-handler"] = com.handler !== null;
|
|
||||||
this["async-handler"] = (com.handler != null) && com.asyncHandler;
|
|
||||||
this.validator = com.validator;
|
|
||||||
this.color = com.color;
|
|
||||||
this.icon = com.icon;
|
|
||||||
this.params = com.params || [];
|
|
||||||
this.preview = com.preview;
|
|
||||||
this["short-preview"] = com.shortPreview;
|
|
||||||
this.fullscreen = com.fullscreen;
|
|
||||||
this.actions = com.actions;
|
|
||||||
this.request = com.request;
|
|
||||||
this["execute-immediately?"] = com.executeImmediately;
|
|
||||||
this["sequential-params"] = com.sequentialParams;
|
|
||||||
this["hide-send-button"] = com.hideSendButton;
|
|
||||||
|
|
||||||
// scopes
|
|
||||||
this.scope = com.scope || defaultScope;
|
|
||||||
this["scope-bitmask"] = scopeToBitMask(this["scope"]);
|
|
||||||
|
|
||||||
this.addToCatalog();
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
Response.prototype = Object.create(Command.prototype);
|
|
||||||
Response.prototype.addToCatalog = function () {
|
|
||||||
_status_catalog.responses[[this.name, this["scope-bitmask"]]] = this;
|
|
||||||
};
|
|
||||||
Response.prototype.onReceiveResponse = function (handler) {
|
|
||||||
this.onReceive = handler;
|
|
||||||
};
|
|
||||||
|
|
||||||
var context = {};
|
|
||||||
|
|
||||||
|
|
||||||
function addContext(key, value) {
|
|
||||||
context[status.message_id][key] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getContext(key) {
|
|
||||||
return context[status.message_id][key];
|
|
||||||
}
|
|
||||||
|
|
||||||
function call(pathStr, paramsStr) {
|
|
||||||
var params = JSON.parse(paramsStr),
|
|
||||||
path = JSON.parse(pathStr),
|
|
||||||
fn, callResult, message_id;
|
|
||||||
|
|
||||||
if (typeof params.context !== "undefined" &&
|
|
||||||
typeof params.context["message-id"] !== "undefined") {
|
|
||||||
message_id = params.context["message-id"];
|
|
||||||
} else {
|
|
||||||
message_id = null;
|
|
||||||
}
|
|
||||||
context[message_id] = {};
|
|
||||||
status.message_id = message_id;
|
|
||||||
|
|
||||||
fn = path.reduce(function (catalog, name) {
|
|
||||||
if (catalog && catalog[name]) {
|
|
||||||
return catalog[name];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_status_catalog
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!fn) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
context.messages = [];
|
|
||||||
|
|
||||||
callResult = fn(params.parameters, params.context);
|
|
||||||
result = {
|
|
||||||
returned: callResult,
|
|
||||||
context: context[message_id],
|
|
||||||
messages: context.messages
|
|
||||||
};
|
|
||||||
|
|
||||||
return JSON.stringify(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
function view(options, elements) {
|
|
||||||
return ['view', options].concat(elements);
|
|
||||||
}
|
|
||||||
|
|
||||||
function text(options, s) {
|
|
||||||
s = Array.isArray(s) ? s : [s];
|
|
||||||
return ['text', options].concat(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
function chatPreviewText(options, s) {
|
|
||||||
return ['chat-preview-text', options, s];
|
|
||||||
}
|
|
||||||
|
|
||||||
function textInput(options) {
|
|
||||||
return ['text-input', options];
|
|
||||||
}
|
|
||||||
|
|
||||||
function image(options) {
|
|
||||||
return ['image', options];
|
|
||||||
}
|
|
||||||
|
|
||||||
function qrCode(options) {
|
|
||||||
return ['qr-code', options];
|
|
||||||
}
|
|
||||||
|
|
||||||
function linking(options) {
|
|
||||||
return ['linking', options];
|
|
||||||
}
|
|
||||||
|
|
||||||
function slider(options) {
|
|
||||||
return ['slider', options];
|
|
||||||
}
|
|
||||||
|
|
||||||
function image(options) {
|
|
||||||
return ['image', options];
|
|
||||||
}
|
|
||||||
|
|
||||||
function touchable(options, element) {
|
|
||||||
return ['touchable', options, element];
|
|
||||||
}
|
|
||||||
|
|
||||||
function activityIndicator(options) {
|
|
||||||
return ['activity-indicator', options];
|
|
||||||
}
|
|
||||||
|
|
||||||
function scrollView(options, elements) {
|
|
||||||
return ['scroll-view', options].concat(elements);
|
|
||||||
}
|
|
||||||
|
|
||||||
function subscribe(path) {
|
|
||||||
return ['subscribe', path];
|
|
||||||
}
|
|
||||||
|
|
||||||
function dispatch(path) {
|
|
||||||
return ['dispatch', path];
|
|
||||||
}
|
|
||||||
|
|
||||||
function webView(url) {
|
|
||||||
return ['web-view', {
|
|
||||||
source: {
|
|
||||||
uri: url
|
|
||||||
},
|
|
||||||
javaScriptEnabled: true
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
function bridgedWebView(url) {
|
|
||||||
return ['bridged-web-view', {
|
|
||||||
url: url
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
function validationMessage(titleText, descriptionText) {
|
|
||||||
return ['validation-message', {
|
|
||||||
title: titleText,
|
|
||||||
description: descriptionText
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
function chooseContact(titleText, botDbKey, argumentIndex) {
|
|
||||||
return ['choose-contact', {
|
|
||||||
title: titleText,
|
|
||||||
"bot-db-key": botDbKey,
|
|
||||||
index: argumentIndex
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
function chooseAsset(botDbKey, argumentIndex) {
|
|
||||||
return ['choose-asset', {
|
|
||||||
"bot-db-key": botDbKey,
|
|
||||||
index: argumentIndex
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function separator() {
|
|
||||||
return ['separator'];
|
|
||||||
}
|
|
||||||
|
|
||||||
var status = {
|
|
||||||
command: function (h) {
|
|
||||||
var command = new Command();
|
|
||||||
return command.create(h);
|
|
||||||
},
|
|
||||||
response: function (h) {
|
|
||||||
var response = new Response();
|
|
||||||
return response.create(h);
|
|
||||||
},
|
|
||||||
addListener: function (name, fn) {
|
|
||||||
_status_catalog.functions[name] = fn;
|
|
||||||
},
|
|
||||||
localizeNumber: function (num, del, sep) {
|
|
||||||
return I18n.toNumber(
|
|
||||||
num.replace(",", "."),
|
|
||||||
{
|
|
||||||
precision: 10,
|
|
||||||
strip_insignificant_zeros: true,
|
|
||||||
delimiter: del,
|
|
||||||
separator: sep
|
|
||||||
});
|
|
||||||
},
|
|
||||||
types: {
|
|
||||||
TEXT: 'text',
|
|
||||||
NUMBER: 'number',
|
|
||||||
PASSWORD: 'password'
|
|
||||||
},
|
|
||||||
events: {
|
|
||||||
SET_VALUE: 'set-value',
|
|
||||||
SET_COMMAND_ARGUMENT: 'set-command-argument',
|
|
||||||
UPDATE_DB: 'set',
|
|
||||||
SET_COMMAND_ARGUMENT_FROM_DB: 'set-command-argument-from-db',
|
|
||||||
SET_VALUE_FROM_DB: 'set-value-from-db',
|
|
||||||
FOCUS_INPUT: 'focus-input'
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
WEB_VIEW_BACK: 'web-view-back',
|
|
||||||
WEB_VIEW_FORWARD: 'web-view-forward',
|
|
||||||
FULLSCREEN: 'fullscreen',
|
|
||||||
CUSTOM: 'custom',
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
view: view,
|
|
||||||
text: text,
|
|
||||||
chatPreviewText: chatPreviewText,
|
|
||||||
textInput: textInput,
|
|
||||||
slider: slider,
|
|
||||||
image: image,
|
|
||||||
qrCode: qrCode,
|
|
||||||
linking: linking,
|
|
||||||
slider: slider,
|
|
||||||
touchable: touchable,
|
|
||||||
activityIndicator: activityIndicator,
|
|
||||||
scrollView: scrollView,
|
|
||||||
webView: webView,
|
|
||||||
validationMessage: validationMessage,
|
|
||||||
bridgedWebView: bridgedWebView,
|
|
||||||
chooseAsset: chooseAsset,
|
|
||||||
chooseContact: chooseContact,
|
|
||||||
subscribe: subscribe,
|
|
||||||
dispatch: dispatch,
|
|
||||||
separator: separator
|
|
||||||
},
|
|
||||||
showSuggestions: function (view) {
|
|
||||||
status.sendSignal("show-suggestions", view);
|
|
||||||
},
|
|
||||||
setDefaultDb: function (db) {
|
|
||||||
addContext("default-db", db);
|
|
||||||
},
|
|
||||||
updateDb: function (db) {
|
|
||||||
addContext("update-db", db)
|
|
||||||
},
|
|
||||||
sendMessage: function (message) {
|
|
||||||
if(typeof message !== "string") {
|
|
||||||
message = JSON.stringify(message);
|
|
||||||
}
|
|
||||||
status.sendSignal("send-message", message);
|
|
||||||
},
|
|
||||||
addLogMessage: function (type, message) {
|
|
||||||
var message = {
|
|
||||||
type: type,
|
|
||||||
message: JSON.stringify(message)
|
|
||||||
};
|
|
||||||
var logMessages = getContext("log-messages");
|
|
||||||
if (!logMessages) {
|
|
||||||
logMessages = [];
|
|
||||||
}
|
|
||||||
logMessages.push(message);
|
|
||||||
addContext("log-messages", logMessages);
|
|
||||||
},
|
|
||||||
defineSubscription: function (name, subscriptions, handler) {
|
|
||||||
_status_catalog.subscriptions[name] = {
|
|
||||||
subscriptions: subscriptions,
|
|
||||||
handler: handler
|
|
||||||
};
|
|
||||||
},
|
|
||||||
sendSignal: function (eventName, data) {
|
|
||||||
var event = {
|
|
||||||
event: eventName,
|
|
||||||
data: data
|
|
||||||
};
|
|
||||||
|
|
||||||
statusSignals.sendSignal(JSON.stringify(event));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function calculateSubscription(parameters, context) {
|
|
||||||
var subscriptionConfig = _status_catalog.subscriptions[parameters.name];
|
|
||||||
if (!subscriptionConfig) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return subscriptionConfig.handler(parameters.subscriptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
status.addListener("subscription", calculateSubscription);
|
|
||||||
|
|
||||||
console = (function (old) {
|
|
||||||
return {
|
|
||||||
log: function (text) {
|
|
||||||
old.log(text);
|
|
||||||
status.addLogMessage('log', text);
|
|
||||||
},
|
|
||||||
debug: function (text) {
|
|
||||||
old.debug(text);
|
|
||||||
status.addLogMessage('debug', text);
|
|
||||||
},
|
|
||||||
info: function (text) {
|
|
||||||
old.info(text);
|
|
||||||
status.addLogMessage('info', text);
|
|
||||||
},
|
|
||||||
warn: function (text) {
|
|
||||||
old.warn(text);
|
|
||||||
status.addLogMessage('warn', text);
|
|
||||||
},
|
|
||||||
error: function (text) {
|
|
||||||
old.error(text);
|
|
||||||
status.addLogMessage('error', text);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}(console));
|
|
||||||
|
|
||||||
var localStorage = {};
|
|
||||||
|
|
||||||
localStorage.setItem = function(key, value) {
|
|
||||||
if(value === null) {
|
|
||||||
delete localStorageData[key];
|
|
||||||
} else {
|
|
||||||
localStorageData[key] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
status.sendSignal("local-storage", JSON.stringify(localStorageData));
|
|
||||||
};
|
|
||||||
|
|
||||||
localStorage.getItem = function (key) {
|
|
||||||
if (typeof localStorageData[key] === "undefined") {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return localStorageData[key];
|
|
||||||
};
|
|
|
@ -1,8 +1,8 @@
|
||||||
(ns status-im.core
|
(ns status-im.core
|
||||||
(:require [status-im.utils.error-handler :as error-handler]
|
(:require [re-frame.core :as re-frame]
|
||||||
|
[status-im.utils.error-handler :as error-handler]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im.native-module.core :as status]
|
|
||||||
status-im.transport.impl.receive
|
status-im.transport.impl.receive
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[status-im.utils.config :as config]
|
[status-im.utils.config :as config]
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
(defn init [app-root]
|
(defn init [app-root]
|
||||||
(log/set-level! config/log-level)
|
(log/set-level! config/log-level)
|
||||||
(error-handler/register-exception-handler!)
|
(error-handler/register-exception-handler!)
|
||||||
(status/init-jail)
|
(re-frame/dispatch [:initialize-keychain])
|
||||||
(when config/testfairy-enabled?
|
(when config/testfairy-enabled?
|
||||||
(.begin js-dependencies/testfairy config/testfairy-token))
|
(.begin js-dependencies/testfairy config/testfairy-token))
|
||||||
(.registerComponent react/app-registry "StatusIm" #(reagent/reactify-component app-root)))
|
(.registerComponent react/app-registry "StatusIm" #(reagent/reactify-component app-root)))
|
||||||
|
|
|
@ -19,9 +19,6 @@
|
||||||
(log/debug :callback name args)
|
(log/debug :callback name args)
|
||||||
(apply callback args)))
|
(apply callback args)))
|
||||||
|
|
||||||
(defn init-jail []
|
|
||||||
(module-interface/-init-jail rns-module))
|
|
||||||
|
|
||||||
(defn move-to-internal-storage [callback]
|
(defn move-to-internal-storage [callback]
|
||||||
(module-interface/-move-to-internal-storage rns-module callback))
|
(module-interface/-move-to-internal-storage rns-module callback))
|
||||||
|
|
||||||
|
@ -49,15 +46,6 @@
|
||||||
(defn discard-sign-request [id]
|
(defn discard-sign-request [id]
|
||||||
(module-interface/-discard-sign-request rns-module id))
|
(module-interface/-discard-sign-request rns-module id))
|
||||||
|
|
||||||
(defn parse-jail [chat-id file callback]
|
|
||||||
(module-interface/-parse-jail rns-module chat-id file callback))
|
|
||||||
|
|
||||||
(defn call-jail [params]
|
|
||||||
(module-interface/-call-jail rns-module params))
|
|
||||||
|
|
||||||
(defn call-function! [params]
|
|
||||||
(module-interface/-call-function! rns-module params))
|
|
||||||
|
|
||||||
(defn set-soft-input-mode [mode]
|
(defn set-soft-input-mode [mode]
|
||||||
(module-interface/-set-soft-input-mode rns-module mode))
|
(module-interface/-set-soft-input-mode rns-module mode))
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
[re-frame.core :refer [dispatch] :as re-frame]
|
[re-frame.core :refer [dispatch] :as re-frame]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[cljs.core.async :as async :refer [<!]]
|
[cljs.core.async :as async :refer [<!]]
|
||||||
[status-im.utils.js-resources :as js-res]
|
|
||||||
[status-im.utils.platform :as p]
|
[status-im.utils.platform :as p]
|
||||||
[status-im.utils.types :as types]
|
[status-im.utils.types :as types]
|
||||||
[status-im.utils.transducers :as transducers]
|
[status-im.utils.transducers :as transducers]
|
||||||
|
@ -51,18 +50,6 @@
|
||||||
(when (exists? (.-NativeModules rn-dependencies/react-native))
|
(when (exists? (.-NativeModules rn-dependencies/react-native))
|
||||||
(.-Status (.-NativeModules rn-dependencies/react-native))))
|
(.-Status (.-NativeModules rn-dependencies/react-native))))
|
||||||
|
|
||||||
(defn init-jail []
|
|
||||||
(when status
|
|
||||||
(call-module
|
|
||||||
(fn []
|
|
||||||
(let [init-js (string/join [js-res/status-js
|
|
||||||
"I18n.locale = '"
|
|
||||||
rn-dependencies/i18n.locale
|
|
||||||
"'; "
|
|
||||||
js-res/web3])]
|
|
||||||
(.initJail status init-js #(do (re-frame/dispatch [:initialize-keychain])
|
|
||||||
(log/debug "JavaScriptCore jail initialized"))))))))
|
|
||||||
|
|
||||||
(defonce listener-initialized (atom false))
|
(defonce listener-initialized (atom false))
|
||||||
|
|
||||||
(when-not @listener-initialized
|
(when-not @listener-initialized
|
||||||
|
@ -138,86 +125,6 @@
|
||||||
(defn- append-catalog-init [js]
|
(defn- append-catalog-init [js]
|
||||||
(str js "\n" "var catalog = JSON.stringify(_status_catalog); catalog;"))
|
(str js "\n" "var catalog = JSON.stringify(_status_catalog); catalog;"))
|
||||||
|
|
||||||
(defn parse-jail [bot-id file callback]
|
|
||||||
(when status
|
|
||||||
(call-module #(.parseJail status
|
|
||||||
bot-id
|
|
||||||
(append-catalog-init file)
|
|
||||||
callback))))
|
|
||||||
|
|
||||||
(defn execute-call [{:keys [jail-id path params callback]}]
|
|
||||||
(when status
|
|
||||||
(call-module
|
|
||||||
#(do
|
|
||||||
(log/debug :call-jail :jail-id jail-id)
|
|
||||||
(log/debug :call-jail :path path)
|
|
||||||
;; this debug message can contain sensitive info
|
|
||||||
#_(log/debug :call-jail :params params)
|
|
||||||
(let [params' (update params :context assoc
|
|
||||||
:debug js/goog.DEBUG
|
|
||||||
:locale rn-dependencies/i18n.locale)
|
|
||||||
cb (fn [jail-result]
|
|
||||||
(let [result (-> jail-result
|
|
||||||
types/json->clj
|
|
||||||
(assoc :bot-id jail-id)
|
|
||||||
(update :result types/json->clj))]
|
|
||||||
(callback result)))]
|
|
||||||
(.callJail status jail-id (types/clj->json path) (types/clj->json params') cb))))))
|
|
||||||
|
|
||||||
;; We want the mainting (time) windowed queue of all calls to the jail
|
|
||||||
;; in order to de-duplicate certain type of calls made in rapid succession
|
|
||||||
;; where it's beneficial to only execute the last call of that type.
|
|
||||||
;;
|
|
||||||
;; The reason why is to improve performance and user feedback, for example
|
|
||||||
;; when making command argument suggestion lookups, everytime the command
|
|
||||||
;; input changes (so the user types/deletes a character), we need to fetch
|
|
||||||
;; new suggestions.
|
|
||||||
;; However the process of asynchronously fetching and displaying them
|
|
||||||
;; is unfortunately not instant, so without de-duplication, given that user
|
|
||||||
;; typed N characters in rapid succession, N percievable suggestion updates
|
|
||||||
;; will be performed after user already stopped typing, which gives
|
|
||||||
;; impression of slow, unresponsive UI.
|
|
||||||
;;
|
|
||||||
;; With de-duplication in some timeframe (set to 400ms currently), only
|
|
||||||
;; the last suggestion call for given jail-id jail-path combination is
|
|
||||||
;; made, and the UI feedback is much better + we save some unnecessary
|
|
||||||
;; calls to jail.
|
|
||||||
|
|
||||||
(def ^:private queue-flush-time 400)
|
|
||||||
|
|
||||||
(def ^:private call-queue (async/chan))
|
|
||||||
(def ^:private deduplicated-calls (async/chan))
|
|
||||||
|
|
||||||
(async-util/chunked-pipe! call-queue deduplicated-calls queue-flush-time)
|
|
||||||
|
|
||||||
(defn compare-calls
|
|
||||||
"Used as comparator deciding which calls should be de-duplicated.
|
|
||||||
Whenever we fetch suggestions, we only want to issue the last call
|
|
||||||
done in the `queue-flush-time` window, for all other calls, we have
|
|
||||||
de-duplicate based on call identity"
|
|
||||||
[{:keys [jail-id path] :as call}]
|
|
||||||
(if (= :suggestions (last path))
|
|
||||||
[jail-id path]
|
|
||||||
call))
|
|
||||||
|
|
||||||
(go-loop []
|
|
||||||
(doseq [call (sequence (transducers/last-distinct-by compare-calls) (<! deduplicated-calls))]
|
|
||||||
(execute-call call))
|
|
||||||
(recur))
|
|
||||||
|
|
||||||
(defn call-jail [call]
|
|
||||||
(async/put! call-queue call))
|
|
||||||
|
|
||||||
(defn call-function!
|
|
||||||
[{:keys [chat-id function callback] :as opts}]
|
|
||||||
(let [path [:functions function]
|
|
||||||
params (select-keys opts [:parameters :context])]
|
|
||||||
(call-jail
|
|
||||||
{:jail-id chat-id
|
|
||||||
:path path
|
|
||||||
:params params
|
|
||||||
:callback callback})))
|
|
||||||
|
|
||||||
(defn set-soft-input-mode [mode]
|
(defn set-soft-input-mode [mode]
|
||||||
(when status
|
(when status
|
||||||
(call-module #(.setSoftInputMode status mode))))
|
(call-module #(.setSoftInputMode status mode))))
|
||||||
|
@ -254,8 +161,7 @@
|
||||||
(defrecord ReactNativeStatus []
|
(defrecord ReactNativeStatus []
|
||||||
module/IReactNativeStatus
|
module/IReactNativeStatus
|
||||||
;; status-go calls
|
;; status-go calls
|
||||||
(-init-jail [this]
|
(-init-jail [this])
|
||||||
(init-jail))
|
|
||||||
(-start-node [this config]
|
(-start-node [this config]
|
||||||
(start-node config))
|
(start-node config))
|
||||||
(-stop-node [this]
|
(-stop-node [this]
|
||||||
|
@ -272,12 +178,9 @@
|
||||||
(approve-sign-request-with-args id password gas gas-price callback))
|
(approve-sign-request-with-args id password gas gas-price callback))
|
||||||
(-discard-sign-request [this id]
|
(-discard-sign-request [this id]
|
||||||
(discard-sign-request id))
|
(discard-sign-request id))
|
||||||
(-parse-jail [this chat-id file callback]
|
(-parse-jail [this chat-id file callback])
|
||||||
(parse-jail chat-id file callback))
|
(-call-jail [this params])
|
||||||
(-call-jail [this params]
|
(-call-function! [this params])
|
||||||
(call-jail params))
|
|
||||||
(-call-function! [this params]
|
|
||||||
(call-function! params))
|
|
||||||
(-call-web3 [this payload callback]
|
(-call-web3 [this payload callback]
|
||||||
(call-web3 payload callback))
|
(call-web3 payload callback))
|
||||||
(-call-web3-private [this payload callback]
|
(-call-web3-private [this payload callback]
|
||||||
|
|
|
@ -32,11 +32,6 @@
|
||||||
(fn [error sync]
|
(fn [error sync]
|
||||||
(re-frame/dispatch [:update-sync-state error sync]))))))
|
(re-frame/dispatch [:update-sync-state error sync]))))))
|
||||||
|
|
||||||
(re-frame/reg-fx
|
|
||||||
::status-init-jail
|
|
||||||
(fn []
|
|
||||||
(status/init-jail)))
|
|
||||||
|
|
||||||
(defn- assert-correct-network
|
(defn- assert-correct-network
|
||||||
[{:keys [db]}]
|
[{:keys [db]}]
|
||||||
;; Assure that node was started correctly
|
;; Assure that node was started correctly
|
||||||
|
|
|
@ -58,20 +58,6 @@
|
||||||
[status-im.utils.utils :as utils]
|
[status-im.utils.utils :as utils]
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
;;;; Helper fns
|
|
||||||
|
|
||||||
(defn- call-jail-function
|
|
||||||
[{:keys [chat-id function callback-event-creator] :as opts}]
|
|
||||||
(let [path [:functions function]
|
|
||||||
params (select-keys opts [:parameters :context])]
|
|
||||||
(status/call-jail
|
|
||||||
{:jail-id chat-id
|
|
||||||
:path path
|
|
||||||
:params params
|
|
||||||
:callback (fn [jail-response]
|
|
||||||
(when-let [event (callback-event-creator jail-response)]
|
|
||||||
(re-frame/dispatch event)))})))
|
|
||||||
|
|
||||||
;;;; COFX
|
;;;; COFX
|
||||||
|
|
||||||
(re-frame/reg-cofx
|
(re-frame/reg-cofx
|
||||||
|
|
|
@ -10,24 +10,6 @@
|
||||||
|
|
||||||
(def default-contacts (json->clj (slurp "resources/default_contacts.json")))
|
(def default-contacts (json->clj (slurp "resources/default_contacts.json")))
|
||||||
|
|
||||||
(def transactor-js (slurp-bot :transactor))
|
|
||||||
|
|
||||||
(def console-js (slurp-bot :console "web3_metadata.js"))
|
|
||||||
|
|
||||||
(def demo-bot-js (slurp-bot :demo_bot))
|
|
||||||
|
|
||||||
(def resources
|
|
||||||
{:transactor-bot transactor-js
|
|
||||||
:console-bot console-js
|
|
||||||
:demo-bot demo-bot-js})
|
|
||||||
|
|
||||||
(defn get-resource [url]
|
|
||||||
(let [resource-name (keyword (subs url (count local-protocol)))]
|
|
||||||
(resources resource-name)))
|
|
||||||
|
|
||||||
(def status-js (str (slurp "resources/js/status.js")
|
|
||||||
(slurp "resources/js/i18n.js")))
|
|
||||||
|
|
||||||
(def webview-js (slurp "resources/js/webview.js"))
|
(def webview-js (slurp "resources/js/webview.js"))
|
||||||
(def web3 (str "; if (typeof Web3 == 'undefined') {"
|
(def web3 (str "; if (typeof Web3 == 'undefined') {"
|
||||||
(slurp "node_modules/web3/dist/web3.min.js")
|
(slurp "node_modules/web3/dist/web3.min.js")
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
(ns status-im.test.utils.transducers
|
(ns status-im.test.utils.transducers
|
||||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||||
[status-im.utils.transducers :as transducers]
|
[status-im.utils.transducers :as transducers]))
|
||||||
[status-im.native-module.impl.module :as native-module]))
|
|
||||||
|
|
||||||
(def ^:private preview-call-1
|
(def ^:private preview-call-1
|
||||||
{:jail-id 1
|
{:jail-id 1
|
||||||
|
@ -39,7 +38,11 @@
|
||||||
(deftest last-distinct-by-test
|
(deftest last-distinct-by-test
|
||||||
(testing "Elements are removed from input according to provided `compare-fn`,
|
(testing "Elements are removed from input according to provided `compare-fn`,
|
||||||
when duplicate elements are removed, the last one stays"
|
when duplicate elements are removed, the last one stays"
|
||||||
(is (= (sequence (transducers/last-distinct-by native-module/compare-calls) jail-calls)
|
(is (= (sequence (transducers/last-distinct-by (fn [{:keys [jail-id path] :as call}]
|
||||||
|
(if (= :suggestions (last path))
|
||||||
|
[jail-id path]
|
||||||
|
call)))
|
||||||
|
jail-calls)
|
||||||
'({:jail-id 1
|
'({:jail-id 1
|
||||||
:path [:suggestions]
|
:path [:suggestions]
|
||||||
:params {:arg 2}}
|
:params {:arg 2}}
|
||||||
|
|
Loading…
Reference in New Issue