Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,4 @@ isolate-*-v8.log
processed.txt

.env
package-lock.json
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ You can remotely control your wallet via chat interface from devices listed in `
* `pay <amount in bytes>` to request withdrawal from the headless wallet to your `payout_address`, or `pay <amount> <asset>` to withdraw another asset.
* `mci`: to get the last stable MCI on the headless wallet;
* `space`: to get the file sizes of data folder;
* `ip`: to get the IP address of the wallet;
* `ip-proxy`: to get the IP address of the wallet through socks proxy;

![Chat with headless wallet](chat-with-headless.png)

Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@
"secp256k1": "secp256k1/js"
},
"dependencies": {
"ocore": "git+https://github.com/byteball/ocore.git",
"bitcore-lib": "^0.13.14",
"bitcore-mnemonic": "~1.0.0",
"json-rpc2": "^1.0.2"
"json-rpc2": "^1.0.2",
"ocore": "git+https://github.com/byteball/ocore.git",
"request": "^2.88.0",
"socks": "1.1.10"
}
}
44 changes: 44 additions & 0 deletions start.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ var storage = require('ocore/storage.js');
var Mnemonic = require('bitcore-mnemonic');
var Bitcore = require('bitcore-lib');
var readline = require('readline');
var request = require('request');
var socks = process.browser ? null : require('socks'+'');

var KEYS_FILENAME = appDataDir + '/' + (conf.KEYS_FILENAME || 'keys.json');
var wallet_id;
Expand Down Expand Up @@ -659,6 +661,18 @@ function handleText(from_address, text, onUnknown){
});
break;

case 'ip':
getMyIPAddress(false, function(data) {
device.sendMessageToDevice(from_address, 'text', data);
});
break;

case 'ip-proxy':
getMyIPAddress(true, function(data) {
device.sendMessageToDevice(from_address, 'text', data);
});
break;

default:
if (onUnknown){
onUnknown(from_address, text);
Expand Down Expand Up @@ -700,6 +714,36 @@ function getFileSizes(rootDir, cb) {
});
}

function getMyIPAddress(testProxy, cb){
var options = {'url': 'https://api.ipify.org/?format=json', 'json': true, 'agent': null, 'timeout': 3000};
if (testProxy === true){
if (socks && conf.socksHost && conf.socksPort){
options.agent = new socks.Agent({
proxy: {
ipaddress: conf.socksHost,
port: conf.socksPort,
type: 5,
authentication: {
username: "dummy",
password: "dummy"
}
}
}, true);
}
else {
return cb('Error, socks configuration missing.');
}
}
request(options, function(err, res, body){
if (!err && res.statusCode == 200){
return cb(body.ip);
} else {
return cb('Error requesting IP address.');
}
});
}


function analyzePayParams(amountText, assetText, cb){
// expected:
// amountText = amount; only digits
Expand Down