diff --git a/docker/nginx/counterwallet.conf.template b/docker/nginx/counterwallet.conf.template index 908923db9..ccd4bda72 100644 --- a/docker/nginx/counterwallet.conf.template +++ b/docker/nginx/counterwallet.conf.template @@ -10,6 +10,10 @@ upstream counterblock_t_api_server { server ${COUNTERBLOCK_HOST_TESTNET}:${COUNTERBLOCK_PORT_TESTNET}; keepalive 30; } +upstream counterblock_r_api_server { + server ${COUNTERBLOCK_HOST_REGTEST}:${COUNTERBLOCK_PORT_REGTEST}; + keepalive 30; +} #Content Security Policy (CSP) header add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://ssl.google-analytics.com https://query.yahooapis.com; img-src 'self' data: https://ssl.google-analytics.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://themes.googleusercontent.com https://fonts.gstatic.com; frame-src 'none'; object-src 'self'; connect-src 'self' wss://$host wss://*.counterwallet.io https://*.counterwallet.io https://api.rollbar.com https://bitcoinfees.earn.com https://apiv2.bitcoinaverage.com https://min-api.cryptocompare.com; report-uri /_report_csp/;"; @@ -81,6 +85,11 @@ server { expires 1h; alias /counterblock_data/asset_img.testnet/; } + location /_r_asset_img/ { + access_log off; + expires 1h; + alias /counterblock_data/asset_img.regtest/; + } location /src { #For dev/testing (uses unminified resources) open_file_cache off; @@ -165,7 +174,40 @@ server { include /etc/nginx/sites-enabled/counterblock_socketio.inc; proxy_pass http://${COUNTERBLOCK_HOST_TESTNET}:${COUNTERBLOCK_PORT_TESTNET_CHAT}/socket.io; } - + + ##### + # REGTEST + # PROXY TO COUNTERBLOCK API REQUESTS (WSGI) - try to hit the cache in redis first + location ^~ /_r_api + { + #reject everything except GET, POST and OPTIONS + limit_except GET POST OPTIONS { + deny all; + } + + include /etc/nginx/sites-enabled/counterblock_api_cache.inc; + set $redis_db "2"; + + # Send to app server if Redis could not answer the request + error_page 404 405 550 = @r_wsgi_api; + } + # PROXY TO COUNTERBLOCK API BACKEND (WSGI) + location @r_wsgi_api { + include /etc/nginx/sites-enabled/counterblock_api.inc; + rewrite ^/_r_api/?$ /api/? break; + proxy_pass http://counterblock_r_api_server; + } + # PROXY TO COUNTERBLOCK FEED BACKEND (socket.io) + location ^~ /_r_feed { + include /etc/nginx/sites-enabled/counterblock_socketio.inc; + proxy_pass http://${COUNTERBLOCK_HOST_REGTEST}:${COUNTERBLOCK_PORT_REGTEST_FEED}/socket.io; + } + # PROXY TO COUNTERBLOCK CHAT BACKEND (socket.io) + location ^~ /_r_chat { + include /etc/nginx/sites-enabled/counterblock_socketio.inc; + proxy_pass http://${COUNTERBLOCK_HOST_REGTEST}:${COUNTERBLOCK_PORT_REGTEST_CHAT}/socket.io; + } + ##### # CSP REPORTING (mainnet and testnet) location ^~ /_report_csp/ { diff --git a/docker/start.sh b/docker/start.sh index 8ac7f9b95..b823c2db3 100644 --- a/docker/start.sh +++ b/docker/start.sh @@ -24,14 +24,18 @@ export REDIS_PORT=${REDIS_PORT:=6379} export REDIS_DB=${REDIS_DB:=0} export COUNTERBLOCK_HOST_MAINNET=${COUNTERBLOCK_HOST_MAINNET:="counterblock"} export COUNTERBLOCK_HOST_TESTNET=${COUNTERBLOCK_HOST_TESTNET:="counterblock-testnet"} +export COUNTERBLOCK_HOST_REGTEST=${COUNTERBLOCK_HOST_REGTEST:="counterblock-regtest"} export COUNTERBLOCK_PORT_MAINNET=${COUNTERBLOCK_PORT_MAINNET:=4100} export COUNTERBLOCK_PORT_TESTNET=${COUNTERBLOCK_PORT_TESTNET:=14100} +export COUNTERBLOCK_PORT_REGTEST=${COUNTERBLOCK_PORT_REGTEST:=24100} export COUNTERBLOCK_PORT_MAINNET_FEED=${COUNTERBLOCK_PORT_MAINNET_FEED:=4101} export COUNTERBLOCK_PORT_TESTNET_FEED=${COUNTERBLOCK_PORT_TESTNET_FEED:=14101} +export COUNTERBLOCK_PORT_REGTEST_FEED=${COUNTERBLOCK_PORT_REGTEST_FEED:=24101} export COUNTERBLOCK_PORT_MAINNET_CHAT=${COUNTERBLOCK_PORT_MAINNET_CHAT:=4102} export COUNTERBLOCK_PORT_TESTNET_CHAT=${COUNTERBLOCK_PORT_TESTNET_CHAT:=14102} +export COUNTERBLOCK_PORT_REGTEST_CHAT=${COUNTERBLOCK_PORT_REGTEST_CHAT:=24102} -VARS='$REDIS_HOST:$REDIS_PORT:$REDIS_DB:$COUNTERBLOCK_HOST_MAINNET:$COUNTERBLOCK_HOST_TESTNET:$COUNTERBLOCK_PORT_MAINNET:$COUNTERBLOCK_PORT_TESTNET:$COUNTERBLOCK_PORT_MAINNET_FEED:$COUNTERBLOCK_PORT_TESTNET_FEED:$COUNTERBLOCK_PORT_MAINNET_CHAT:$COUNTERBLOCK_PORT_TESTNET_CHAT' +VARS='$REDIS_HOST:$REDIS_PORT:$REDIS_DB:$COUNTERBLOCK_HOST_MAINNET:$COUNTERBLOCK_HOST_TESTNET:$COUNTERBLOCK_HOST_REGTEST:$COUNTERBLOCK_PORT_MAINNET:$COUNTERBLOCK_PORT_TESTNET:$COUNTERBLOCK_PORT_REGTEST:$COUNTERBLOCK_PORT_MAINNET_FEED:$COUNTERBLOCK_PORT_TESTNET_FEED:$COUNTERBLOCK_PORT_REGTEST_FEED:$COUNTERBLOCK_PORT_MAINNET_CHAT:$COUNTERBLOCK_PORT_TESTNET_CHAT:$COUNTERBLOCK_PORT_REGTEST_CHAT' envsubst "$VARS" < /counterwallet/docker/nginx/counterwallet.conf.template > /etc/nginx/sites-enabled/counterwallet.conf # Launch utilizing the SIGTERM/SIGINT propagation pattern from diff --git a/src/css/misc.css b/src/css/misc.css index c029b5e20..7ae2e9161 100644 --- a/src/css/misc.css +++ b/src/css/misc.css @@ -74,7 +74,7 @@ span.modeIndicator { } -#noticeTestnet { +#noticeTestnet, #noticeRegtest { font-size: 26px; font-weight: bolder; color: red; @@ -91,7 +91,7 @@ span.modeIndicator { } @media only screen and (max-width : 860px) { - #noticeTestnet { + #noticeTestnet, #noticeRegtest { font-size:13px; min-width: 116px; margin-left: -58px; @@ -99,7 +99,7 @@ span.modeIndicator { } @media only screen and (max-width : 500px) { - #noticeTestnet { + #noticeTestnet, #noticeRegtest { display:none; } } diff --git a/src/index.html b/src/index.html index 1deccf108..b99433b23 100644 --- a/src/index.html +++ b/src/index.html @@ -101,7 +101,7 @@
- REGTEST +
';
+ var prefix = USE_TESTNET ? '_t' : (USE_REGTEST ? '_r' : '');
+ dispAsset = '
';
//dispAsset += website ? ('' + asset + '') : asset;
dispAsset += asset; //keep it simple for now for avoid XSS
}
diff --git a/src/js/components/logon.js b/src/js/components/logon.js
index a8a3ecdb0..b6725816c 100644
--- a/src/js/components/logon.js
+++ b/src/js/components/logon.js
@@ -69,6 +69,7 @@ function LogonViewModel() {
self.cryptedPassphrase = ko.observable(CRYPTED_PASSPHRASE);
self.USE_TESTNET = USE_TESTNET;
+ self.USE_REGTEST = USE_REGTEST;
self.IS_DEV = IS_DEV;
self.sanitizedEnteredPassphrase = ko.computed(function() { //cleans whitespace and gunk off the passphrase
@@ -132,8 +133,7 @@ function LogonViewModel() {
multiAPI("is_ready", {}, function(data, endpoint) {
assert(data['caught_up'], "Invalid is_ready result"); //otherwise we should have gotten a 525 error
assert(USE_TESTNET == data['testnet'], "USE_TESTNET is " + USE_TESTNET + " from URL-based detection, but the server API disagrees!");
-
- $.jqlog.log("Backend is ready. Testnet status: " + USE_TESTNET + ". Last message feed index: " + data['last_message_index'] + ". CW last message seq: " + data['cw_last_message_seq']);
+ $.jqlog.log("Backend is ready. Testnet status: " + USE_TESTNET + ". Regtest status: " + USE_REGTEST + "Last message feed index: " + data['last_message_index'] + ". CW last message seq: " + data['cw_last_message_seq']);
assert(data['last_message_index'] > 0);
//User is logging in...
@@ -141,7 +141,8 @@ function LogonViewModel() {
self.setExtraInfoOpacity(0);
//generate the wallet ID from a double SHA256 hash of the passphrase and the network (if testnet)
- var hashBase = CryptoJS.SHA256(self.sanitizedEnteredPassphrase() + (USE_TESTNET ? '_testnet' : ''));
+ var network = USE_TESTNET ? '_testnet' : (USE_REGTEST ? '_regtest' : '');
+ var hashBase = CryptoJS.SHA256(self.sanitizedEnteredPassphrase() + network);
var hash = CryptoJS.SHA256(hashBase).toString(CryptoJS.enc.Base64);
//var hashBase = self.sanitizedEnteredPassphrase() + (USE_TESTNET ? '_testnet' : '');
@@ -170,7 +171,7 @@ function LogonViewModel() {
//Grab preferences
multiAPINewest("get_preferences", {
'wallet_id': WALLET.identifier(),
- 'network': (USE_TESTNET || USE_REGTEST) ? 'testnet' : 'mainnet',
+ 'network': USE_TESTNET ? 'testnet' : (USE_REGTEST ? 'regtest' : 'mainnet'),
'for_login': true
}, 'last_updated', self.onReceivedPreferences);
@@ -218,7 +219,7 @@ function LogonViewModel() {
} else { //could not find user stored preferences
//No server had the preferences
$.jqlog.log("Stored preferences NOT found on server(s). Creating new...");
- trackEvent("Login", "NewWallet", USE_TESTNET ? "Testnet" : "Mainnet");
+ trackEvent("Login", "NewWallet", USE_TESTNET ? "Testnet" : (USE_REGTEST ? "Regtest" : "Mainnet"));
WALLET.isNew(true);
//no stored preferences on any server(s) in the federation, go with the local storage preferences or default...
if (localPref && localPref['preferences']) {
@@ -439,7 +440,7 @@ function LogonViewModel() {
//record some metrics...
trackEvent("Login", "Wallet", "Size", PREFERENCES['num_addresses_used'] + PREFERENCES['num_segwit_addresses_used']);
- trackEvent("Login", "Network", USE_TESTNET ? "Testnet" : "Mainnet");
+ trackEvent("Login", "Network", USE_TESTNET ? "Testnet" : (USE_REGTEST ? "Regtest" : "Mainnet"));
trackEvent("Login", "Country", USER_COUNTRY || 'UNKNOWN');
trackEvent("Login", "Language", PREFERENCES['selected_lang']);
trackEvent("Login", "Theme", PREFERENCES['selected_theme']);
diff --git a/src/js/components/misc.js b/src/js/components/misc.js
index b5797b246..472e4ec1a 100644
--- a/src/js/components/misc.js
+++ b/src/js/components/misc.js
@@ -73,6 +73,7 @@ function CreateSupportCaseViewModel() {
'currentBlockID': WALLET.networkBlockHeight(),
'currentMsgID': MESSAGE_FEED.lastMessageIndexReceived(),
'useTestnet': USE_TESTNET,
+ 'useRegtest': USE_REGTEST,
'devMode': IS_DEV,
'walletID': WALLET.identifier(),
'originURL': window.location.origin,
diff --git a/src/js/components/wallet.js b/src/js/components/wallet.js
index 258aba85b..9caa11399 100644
--- a/src/js/components/wallet.js
+++ b/src/js/components/wallet.js
@@ -803,7 +803,7 @@ function WalletViewModel() {
var verifyDestAddr = data['destination'] || data['transfer_destination'] || data['feed_address'] || data['destBtcPay'] || data['source'];
delete data['destBtcPay'];
if (action == "create_burn") {
- verifyDestAddr = TESTNET_UNSPENDABLE;
+ verifyDestAddr = USE_TESTNET ? TESTNET_UNSPENDABLE : REGTEST_UNSPENDABLE;
} else if (action === 'create_dividend' && data['dividend_asset'] == KEY_ASSET.BTC) {
verifyDestAddr = data['_btc_dividend_dests'];
delete data['_btc_dividend_dests'];
@@ -971,7 +971,7 @@ function WalletViewModel() {
var params = {
'wallet_id': WALLET.identifier(),
'preferences': PREFERENCES,
- 'network': USE_TESTNET ? 'testnet' : 'mainnet',
+ 'network': USE_TESTNET ? 'testnet' : (USE_REGTEST ? 'regtest' : 'mainnet'),
'referer': ORIG_REFERER
};
if (forLogin) {
diff --git a/src/js/counterwallet.js b/src/js/counterwallet.js
index 0d3624895..adfbd655e 100644
--- a/src/js/counterwallet.js
+++ b/src/js/counterwallet.js
@@ -5,7 +5,7 @@
//Set up logging (jqlog) and monkey patch jqlog with a debug function
$.jqlog.enabled(true);
$.jqlog.debug = function(object, options) {
- if (IS_DEV || USE_TESTNET) //may change to just IS_DEV in the future
+ if (IS_DEV || USE_TESTNET || USE_REGTEST) //may change to just IS_DEV in the future
$.jqlog.info(object, options);
}
@@ -19,7 +19,7 @@ if (!window.location.origin) {
//if in dev or testnet mode (both of which are specified based on a URL querystring being present), IF a query string is
// provided clear the query string so that our hash-based AJAX navigation works after logging in...
-if ((IS_DEV || USE_TESTNET) && location.search) {
+if ((IS_DEV || USE_TESTNET || USE_REGTEST) && location.search) {
//history.replaceState is NOT supported on IE 9...ehh
assert($.layout.className !== 'trident9',
"Use of 'dev' or 'testnet' flags NOT supported on IE 9, due to lack of history.replaceState() support.");
@@ -66,7 +66,7 @@ function produceCWServerList() {
if (USE_TESTNET) {
return element + '/_t_api';
} else if (USE_REGTEST) {
- return element + '/';
+ return element + '/_r_api';
} else {
return element + '/_api';
}
@@ -98,7 +98,7 @@ function initRollbar() {
accessToken: ROLLBAR_ACCESS_TOKEN,
captureUncaught: true,
payload: {
- environment: USE_TESTNET ? "testnet" : "mainnet"
+ environment: USE_TESTNET ? "testnet" : (USE_REGTEST ? "regtest" : "mainnet")
}
};
try {
diff --git a/src/js/pages.init.js b/src/js/pages.init.js
index d20ac888c..0137ff1b4 100644
--- a/src/js/pages.init.js
+++ b/src/js/pages.init.js
@@ -37,6 +37,7 @@ function initIndex() { //main page
//so that knockout is run on the DOM sections and global context is accessible...
ko.applyBindings({}, document.getElementById("noticeTestnet"));
+ ko.applyBindings({}, document.getElementById("noticeRegtest"));
ko.applyBindings({}, document.getElementById("noticeDevMode"));
ko.applyBindings({}, document.getElementById("donate"));
ko.applyBindings({}, document.getElementById("logo"));
diff --git a/src/js/util.js b/src/js/util.js
index be0e1ebda..e3509e1cf 100644
--- a/src/js/util.js
+++ b/src/js/util.js
@@ -15,14 +15,16 @@ function cleanHtmlPrice(price) {
function feedImageUrl(image_name) {
var url = cwBaseURLs()[0];
- url += USE_TESTNET ? '/_t_feed_img/' : '/_feed_img/';
+ var prefix = USE_TESTNET ? "_t" : ( USE_REGTEST ? "_r" : "");
+ url += '/' + prefix + '_feed_img/';
url += image_name + '.png';
return url;
}
function assetImageUrl(image_name) {
var url = cwBaseURLs()[0];
- url += USE_TESTNET ? '/_t_asset_img/' : '/_asset_img/';
+ var prefix = USE_TESTNET ? "_t" : ( USE_REGTEST ? "_r" : "");
+ url += '/' + prefix + '_asset_img/';
url += image_name + '.png';
return url;
}
diff --git a/src/js/util.knockout.js b/src/js/util.knockout.js
index f09f166c6..2ea3fd105 100644
--- a/src/js/util.knockout.js
+++ b/src/js/util.knockout.js
@@ -90,23 +90,23 @@ var initDateTimePicker = function(locale) {
};
-/*
+/*
* Shared knockout Validation custom rules
*/
function createSharedKnockoutValidators() {
-
+ var addressKeyIdx = USE_TESTNET ? 'must_be_valid_testnet_address' : (USE_REGTEST ? 'must_be_valid_regtest_address' : 'must_be_valid_bitcoin_address');
ko.validation.rules['isValidBitcoinAddress'] = {
validator: function(val, self) {
return CWBitcore.isValidAddress(val) || CWBitcore.isValidMultisigAddress(val);
},
- message: USE_TESTNET ? i18n.t('must_be_valid_testnet_address') : i18n.t('must_be_valid_bitcoin_address')
+ message: addressKeyIdx
};
ko.validation.rules['isValidMonosigAddress'] = {
validator: function(val, self) {
return CWBitcore.isValidAddress(val);
},
- message: USE_TESTNET ? i18n.t('must_be_valid_testnet_address') : i18n.t('must_be_valid_bitcoin_address')
+ message: addressKeyIdx
};
ko.validation.rules['isValidBitcoinAddressIfSpecified'] = {
@@ -118,7 +118,7 @@ function createSharedKnockoutValidators() {
return false;
}
},
- message: USE_TESTNET ? i18n.t('must_be_valid_testnet_address') : i18n.t('must_be_valid_bitcoin_address')
+ message: addressKeyIdx
};
ko.validation.rules['isValidMonosigAddressIfSpecified'] = {
@@ -130,7 +130,7 @@ function createSharedKnockoutValidators() {
return false;
}
},
- message: USE_TESTNET ? i18n.t('must_be_valid_testnet_address') : i18n.t('must_be_valid_bitcoin_address')
+ message: addressKeyIdx
};
ko.validation.rules['isValidQtyForDivisibility'] = {
diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json
index 2c4a4b207..80bf5dcd0 100644
--- a/src/locales/en/translation.json
+++ b/src/locales/en/translation.json
@@ -36,6 +36,7 @@
"log_into_your_wallet": "Log Into Your Wallet",
"dev_mode_enabled": "Dev Mode Enabled",
"testnet_in_use": "Testnet In Use",
+ "regtest_in_use": "Regtest In Use",
"open_wallet": "Open Wallet",
"login": "Login",
"login_problems": "Problems logging in?",
@@ -176,6 +177,7 @@
"cannot_send_server_unavailable": "Cannot send BTC right now, as we cannot currently get in touch with the server to get your balance. Please try again later.",
"bal": "bal",
"not_valid_testnet_pk": "Not a valid TESTNET private key",
+ "not_valid_regtest_pk": "Not a valid REGTEST private key",
"not_valid_pk": "Not a valid private key",
"not_able_to_sweep": "Counterwallet cannot sweep all of the tokens you selected. Please send %s BTC to address %s and try again. OR use the following fields to pay fees with another address",
"asset_sent_to": "Sent %s %s to %s",
diff --git a/src/pages/balances.html b/src/pages/balances.html
index 3206ab078..d8bad381e 100644
--- a/src/pages/balances.html
+++ b/src/pages/balances.html
@@ -134,7 +134,7 @@