bitpay-sdk
Version:
Complete version of the NodeJS library for the new cryptographically secure BitPay API
328 lines • 10.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
const BitPaySDK = require("../index");
const readline = require("readline");
const keyUtils = new BitPaySDK.KeyUtils();
let configFilePath = process.cwd();
let keyPair;
let ecKey;
let environment;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
let storeFile = true;
let apiUrl;
let merchantToken;
let merchantPairCode;
let payoutToken;
let payoutPairCode;
let keyPath = '';
let keyPlain = '';
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const main = function () {
selectEnv();
};
const selectEnv = async () => {
try {
console.log('Select target environment:');
rl.question('Press T for testing or P for production: \n', async (answer) => {
switch (answer.toLowerCase()) {
case 't':
environment = 'Test';
await setEnv(environment);
selectCreateKey();
break;
case 'p':
environment = 'Prod';
await setEnv(environment);
selectCreateKey();
break;
default:
selectEnv();
}
});
}
catch (e) {
console.log(e);
}
};
const setEnv = async (env) => {
if (env == 'Test') {
apiUrl = 'https://test.bitpay.com';
return;
}
apiUrl = 'https://bitpay.com';
};
const selectCreateKey = async () => {
try {
rl.question('Press (E) for existing or (N) for new private key: ', async (answer) => {
switch (answer.toLowerCase()) {
case 'n':
await createNewKey();
break;
default:
await loadKey(answer);
break;
}
});
}
catch (e) {
console.log(e);
}
};
const createNewKey = async () => {
try {
console.log('Generating private key... \n');
keyPair = keyUtils.generate_keypair();
ecKey = keyUtils.load_keypair(keyPair);
await sleep(2000);
console.log('Generated Private Key: ' + ecKey.getPrivate('hex'));
console.log('With Public Key: ' + ecKey.getPublic('hex') + '\n');
await prepareDirectory();
}
catch (e) {
console.log(e);
}
};
const loadKey = async (privateKey) => {
try {
if (fs.existsSync(privateKey)) {
console.log('Loading private key... \n');
await sleep(2000);
ecKey = keyUtils.load_keypair(fs.readFileSync(privateKey).toString().trim());
console.log('Loaded Private Key: ' + ecKey.getPrivate('hex'));
console.log('With Public Key: ' + keyUtils.getPublicKeyFromPrivateKey(ecKey));
console.log('From: ' + privateKey);
console.log('\n');
selectTokens();
}
else {
ecKey = keyUtils.load_keypair(privateKey);
console.log('Loading private key... \n');
await sleep(2000);
console.log('Loaded Private Key: ' + ecKey.getPrivate('hex'));
console.log('With Public Key: ' + keyUtils.getPublicKeyFromPrivateKey(ecKey));
console.log('From: ' + privateKey);
console.log('\n');
selectTokens();
}
}
catch (e) {
console.log(e);
}
};
const formatDirecotryPath = (dir) => {
if (dir === '' || dir === '.' || dir === '/' || !dir) {
return process.cwd();
}
if (dir && dir.charAt(0) !== '/') {
return process.cwd() + `/${dir}`;
}
else {
return process.cwd() + dir;
}
};
const prepareDirectory = async () => {
rl.question('Enter the directory for your new private key: ', async (dir) => {
configFilePath = formatDirecotryPath(dir);
try {
if (!fs.existsSync(configFilePath)) {
console.error(`Directory ${configFilePath} does not exist.`);
console.log(`Do you want to create ${configFilePath} ?`);
rl.question(`Press (Y) to create or (N) to cancel process: `, async (answer) => {
switch (answer.toLowerCase()) {
case 'n':
rl.close();
break;
default:
fs.mkdirSync(configFilePath);
await storeKey();
}
});
}
else {
await storeKey();
}
}
catch (e) {
console.log(e);
}
});
};
const storeKey = async () => {
console.log('Select the way you want to store your private key:');
rl.question('Press F for storing in a text file or T for plain text in your config file: ', async (answer) => {
switch (answer.toLowerCase()) {
case 'f':
storeFile = true;
if (configFilePath.charAt(configFilePath.length - 1) !== '/') {
keyPath = configFilePath + '/private_key' + '_' + environment.toLowerCase() + '.key';
}
else {
keyPath = configFilePath + 'private_key' + '_' + environment.toLowerCase() + '.key';
}
console.log('Saving private key... \n');
sleep(500);
fs.writeFile(keyPath, ecKey.getPrivate('hex'), { mode: 0o755 }, function (err) {
if (err)
throw err;
console.log('Private key saved in file: ' + keyPath + '\n');
});
await sleep(1000);
selectTokens();
break;
case 't':
storeFile = false;
keyPlain = ecKey.getPrivate('hex');
console.log('Saving private key... \n');
await sleep(1000);
selectTokens();
break;
default:
prepareDirectory();
}
});
};
const selectTokens = async () => {
try {
console.log('Select the tokens that you would like to request:');
rl.question('Press M for merchant, P for payout, or B for both: \n', async (answer) => {
switch (answer.toLowerCase()) {
case 'm':
case 'p':
case 'b':
console.log('Requesting tokens... \n');
await sleep(500);
await requestTokens(answer);
break;
default:
selectTokens();
}
});
}
catch (e) {
console.log(e);
}
};
const requestTokens = async (option) => {
async function requestMerchantToken(options) {
console.log('Requesting Merchant token... \n');
options.body['facade'] = 'merchant';
let result = await fetch(apiUrl + '/tokens', {
method: options.method,
headers: options.headers,
body: JSON.stringify(options.body)
})
.then((response) => {
return response.json();
})
.catch((e) => {
console.log(e.message);
});
result = result.data[0];
merchantToken = result.token;
merchantPairCode = result.pairingCode;
await sleep(2000);
}
async function requestPayoutToken(options) {
console.log('Requesting Payout token... \n');
options.body['facade'] = 'payout';
let result = await fetch(options.url, {
method: options.method,
headers: options.headers,
body: JSON.stringify(options.body)
})
.then((response) => {
return response.json();
})
.catch((e) => {
console.log(e.message);
});
result = result.data[0];
payoutToken = result.token;
payoutPairCode = result.pairingCode;
await sleep(2000);
}
try {
let reqMerchant = false;
let reqPayout = false;
switch (option.toLowerCase()) {
case 'm':
reqMerchant = true;
reqPayout = false;
break;
case 'p':
reqMerchant = false;
reqPayout = true;
break;
case 'b':
reqMerchant = true;
reqPayout = true;
break;
}
const headers = {
'x-accept-version': '2.0.0',
'Content-type': 'application/json'
};
const options = {
url: apiUrl + '/tokens',
method: 'POST',
body: { id: keyUtils.get_sin_from_key(ecKey) },
headers: headers
};
if (reqMerchant) {
await requestMerchantToken(options);
}
if (reqPayout) {
await requestPayoutToken(options);
}
await updateConfigFile();
}
catch (e) {
console.log(e);
}
};
const updateConfigFile = async () => {
const configurationObject = {
BitPayConfiguration: {
Environment: environment,
EnvConfig: {
[environment]: {
PrivateKeyPath: keyPath,
PrivateKey: keyPlain,
ApiTokens: {
merchant: merchantToken,
payout: payoutToken
}
}
}
}
};
fs.writeFile(configFilePath + '/BitPay.config.json', JSON.stringify(configurationObject, null, 4), function (err) {
if (err)
throw err;
console.log('Generated configuration file');
console.log('And saved in file: ' + configFilePath + '/BitPay.config.json' + '\n');
});
await sleep(5000);
console.log('Configuration generated successfully! \n');
console.log('To complete your setup, Go to ' +
apiUrl +
'/dashboard/merchant/api-tokens and pair this client with your merchant account using the pairing codes:');
if (merchantToken) {
console.log(merchantPairCode + ' for the Merchant facade.');
}
if (payoutToken) {
console.log(payoutPairCode + ' for the Payout facade ONLY if you have requested access for this role.');
}
process.exit();
};
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
main();
//# sourceMappingURL=BitPaySetup.js.map