Meriadec Pillet
6 years ago
committed by
GitHub
8 changed files with 991 additions and 763 deletions
@ -1,32 +1,62 @@ |
|||||
const { NODE_ENV } = process.env |
const { NODE_ENV, CLI } = process.env |
||||
|
|
||||
const __TEST__ = NODE_ENV === 'test' |
const __TEST__ = NODE_ENV === 'test' |
||||
|
const __CLI__ = !!CLI |
||||
|
|
||||
module.exports = () => ({ |
module.exports = (api) => { |
||||
presets: [ |
|
||||
[ |
if (api) { |
||||
require('@babel/preset-env'), |
api.cache(true); |
||||
{ |
} |
||||
loose: true, |
|
||||
modules: __TEST__ ? 'commonjs' : false, |
return { |
||||
targets: { |
presets: [ |
||||
electron: '1.8', |
[ |
||||
node: 'current', |
require('@babel/preset-env'), |
||||
|
{ |
||||
|
loose: true, |
||||
|
modules: __TEST__ || __CLI__ ? 'commonjs' : false, |
||||
|
targets: { |
||||
|
electron: '1.8', |
||||
|
node: 'current', |
||||
|
}, |
||||
}, |
}, |
||||
}, |
], |
||||
|
require('@babel/preset-flow'), |
||||
|
require('@babel/preset-react'), |
||||
], |
], |
||||
require('@babel/preset-flow'), |
plugins: [ |
||||
require('@babel/preset-react'), |
[require('babel-plugin-module-resolver'), { root: ['src'] }], |
||||
require('@babel/preset-stage-0'), |
[ |
||||
], |
require('babel-plugin-styled-components'), |
||||
plugins: [ |
{ |
||||
[require('babel-plugin-module-resolver'), { root: ['src'] }], |
displayName: true, |
||||
[ |
ssr: __TEST__, |
||||
require('babel-plugin-styled-components'), |
}, |
||||
{ |
], |
||||
displayName: true, |
// Stage 0
|
||||
ssr: __TEST__, |
"@babel/plugin-proposal-function-bind", |
||||
}, |
|
||||
|
// Stage 1
|
||||
|
"@babel/plugin-proposal-export-default-from", |
||||
|
"@babel/plugin-proposal-logical-assignment-operators", |
||||
|
["@babel/plugin-proposal-optional-chaining", { "loose": false }], |
||||
|
["@babel/plugin-proposal-pipeline-operator", { "proposal": "minimal" }], |
||||
|
["@babel/plugin-proposal-nullish-coalescing-operator", { "loose": false }], |
||||
|
"@babel/plugin-proposal-do-expressions", |
||||
|
|
||||
|
// Stage 2
|
||||
|
["@babel/plugin-proposal-decorators", { "legacy": true }], |
||||
|
"@babel/plugin-proposal-function-sent", |
||||
|
"@babel/plugin-proposal-export-namespace-from", |
||||
|
"@babel/plugin-proposal-numeric-separator", |
||||
|
"@babel/plugin-proposal-throw-expressions", |
||||
|
|
||||
|
// Stage 3
|
||||
|
"@babel/plugin-syntax-dynamic-import", |
||||
|
"@babel/plugin-syntax-import-meta", |
||||
|
["@babel/plugin-proposal-class-properties", { "loose": false }], |
||||
|
"@babel/plugin-proposal-json-strings" |
||||
], |
], |
||||
], |
} |
||||
}) |
} |
||||
|
@ -0,0 +1,9 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
# TODO: os specific |
||||
|
export LEDGER_DATA_DIR="$HOME/.config/Electron" |
||||
|
export LEDGER_LOGS_DIRECTORY="$LEDGER_DATA_DIR/logs" |
||||
|
export LEDGER_LIVE_SQLITE_PATH="$LEDGER_DATA_DIR/sqlite" |
||||
|
export CLI=1 |
||||
|
|
||||
|
node -r @babel/register scripts/cli/txBetweenAccounts.js |
@ -0,0 +1,21 @@ |
|||||
|
import CommNodeHid from '@ledgerhq/hw-transport-node-hid' |
||||
|
|
||||
|
export default function getDevice() { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
const sub = CommNodeHid.listen({ |
||||
|
error: err => { |
||||
|
sub.unsubscribe() |
||||
|
reject(err) |
||||
|
}, |
||||
|
next: async e => { |
||||
|
if (!e.device) { |
||||
|
return |
||||
|
} |
||||
|
if (e.type === 'add') { |
||||
|
sub.unsubscribe() |
||||
|
resolve(e.device) |
||||
|
} |
||||
|
}, |
||||
|
}) |
||||
|
}) |
||||
|
} |
@ -0,0 +1,106 @@ |
|||||
|
/* eslint-disable no-console */ |
||||
|
|
||||
|
import chalk from 'chalk' |
||||
|
import path from 'path' |
||||
|
import fs from 'fs' |
||||
|
import inquirer from 'inquirer' |
||||
|
import { createAccountModel } from '@ledgerhq/live-common/lib/models/account' |
||||
|
import { formatCurrencyUnit } from '@ledgerhq/live-common/lib/helpers/currencies' |
||||
|
|
||||
|
import 'globals' |
||||
|
import withLibcore from 'helpers/withLibcore' |
||||
|
import { doSignAndBroadcast } from 'commands/libcoreSignAndBroadcast' |
||||
|
|
||||
|
import getDevice from './getDevice' |
||||
|
|
||||
|
const accountModel = createAccountModel() |
||||
|
|
||||
|
async function main() { |
||||
|
try { |
||||
|
// GET ACCOUNTS
|
||||
|
const app = await parseAppFile() |
||||
|
const accounts = app.accounts.map(accountModel.decode) |
||||
|
|
||||
|
// GET SENDER ACCOUNT
|
||||
|
const senderAccount = await chooseAccount(accounts, 'Choose sender account') |
||||
|
|
||||
|
// GET RECIPIENT ACCOUNT
|
||||
|
const recipientAccount = await chooseAccount(accounts, 'Choose recipient account') |
||||
|
|
||||
|
// GET AMOUNT & FEE
|
||||
|
const { amount, feePerByte } = await inquirer.prompt([ |
||||
|
{ |
||||
|
type: 'input', |
||||
|
name: 'amount', |
||||
|
message: 'Amount', |
||||
|
default: 0, |
||||
|
}, |
||||
|
{ |
||||
|
type: 'input', |
||||
|
name: 'feePerByte', |
||||
|
message: 'Fee per byte', |
||||
|
default: 0, |
||||
|
}, |
||||
|
]) |
||||
|
|
||||
|
// GET DEVICE
|
||||
|
console.log(chalk.blue(`Waiting for device...`)) |
||||
|
const device = await getDevice() |
||||
|
console.log(chalk.blue(`Using device with path [${device.path}]`)) |
||||
|
|
||||
|
await withLibcore(async core => |
||||
|
doSignAndBroadcast({ |
||||
|
accountId: senderAccount.id, |
||||
|
currencyId: senderAccount.currency.id, |
||||
|
xpub: senderAccount.xpub, |
||||
|
freshAddress: senderAccount.freshAddress, |
||||
|
freshAddressPath: senderAccount.freshAddressPath, |
||||
|
index: senderAccount.index, |
||||
|
transaction: { |
||||
|
amount, |
||||
|
feePerByte, |
||||
|
recipient: recipientAccount.freshAddress, |
||||
|
}, |
||||
|
deviceId: device.path, |
||||
|
core, |
||||
|
isCancelled: () => false, |
||||
|
onSigned: () => { |
||||
|
console.log(`>> signed`) |
||||
|
}, |
||||
|
onOperationBroadcasted: operation => { |
||||
|
console.log(`>> broadcasted`, operation) |
||||
|
}, |
||||
|
}), |
||||
|
) |
||||
|
} catch (err) { |
||||
|
console.log(`[ERROR]`, err) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async function parseAppFile() { |
||||
|
const appFilePath = path.resolve(process.env.LEDGER_DATA_DIR, 'app.json') |
||||
|
const appFileContent = fs.readFileSync(appFilePath, 'utf-8') |
||||
|
const parsedApp = JSON.parse(appFileContent) |
||||
|
return parsedApp.data |
||||
|
} |
||||
|
|
||||
|
async function chooseAccount(accounts, msg) { |
||||
|
const { account } = await inquirer.prompt([ |
||||
|
{ |
||||
|
type: 'list', |
||||
|
choices: accounts.map(account => ({ |
||||
|
name: `${account.name} | ${chalk.green( |
||||
|
formatCurrencyUnit(account.unit, account.balance, { |
||||
|
showCode: true, |
||||
|
}), |
||||
|
)}`,
|
||||
|
value: account, |
||||
|
})), |
||||
|
name: 'account', |
||||
|
message: msg, |
||||
|
}, |
||||
|
]) |
||||
|
return account |
||||
|
} |
||||
|
|
||||
|
main() |
File diff suppressed because it is too large
Loading…
Reference in new issue