mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-27 15:45:48 +00:00
Cleanup RippleAPI
This commit is contained in:
@@ -10,5 +10,6 @@ module.exports = {
|
||||
xrpToDrops: utils.xrpToDrops,
|
||||
toRippledAmount: utils.toRippledAmount,
|
||||
wrapCatch: utils.wrapCatch,
|
||||
composeAsync: utils.composeAsync
|
||||
composeAsync: utils.composeAsync,
|
||||
convertExceptions: utils.convertExceptions
|
||||
};
|
||||
|
||||
@@ -3,17 +3,17 @@ const _ = require('lodash');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const validator = require('is-my-json-valid');
|
||||
const ripple = require('./utils').core;
|
||||
const utils = require('./utils');
|
||||
const ValidationError = require('./errors').ValidationError;
|
||||
|
||||
let SCHEMAS = {};
|
||||
|
||||
function isValidAddress(address) {
|
||||
return ripple.UInt160.is_valid(address);
|
||||
return utils.core.UInt160.is_valid(address);
|
||||
}
|
||||
|
||||
function isValidLedgerHash(ledgerHash) {
|
||||
return ripple.UInt256.is_valid(ledgerHash);
|
||||
return utils.core.UInt256.is_valid(ledgerHash);
|
||||
}
|
||||
|
||||
function loadSchema(filepath) {
|
||||
|
||||
7
src/api/common/schemas/hash128.json
Normal file
7
src/api/common/schemas/hash128.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "hash256",
|
||||
"description": "The hex representation of a 128-bit hash",
|
||||
"type": "string",
|
||||
"pattern": "^[A-F0-9]{32}$"
|
||||
}
|
||||
@@ -3,5 +3,5 @@
|
||||
"title": "hash256",
|
||||
"description": "The hex representation of a 256-bit hash",
|
||||
"type": "string",
|
||||
"pattern": "^[A-Fa-f0-9]{64}$"
|
||||
"pattern": "^[A-F0-9]{64}$"
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"properties": {
|
||||
"source": {"$ref": "adjustment"},
|
||||
"destination": {"$ref": "adjustment"},
|
||||
"paths": {"type": "string"},
|
||||
"slippage": {
|
||||
"description": "An optional cushion for the source_amount to increase the likelihood that the payment will succeed. The source_account will never be charged more than source_amount.value + source_slippage",
|
||||
"$ref": "value"
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"noFreeze": {"type": "boolean"},
|
||||
"globalFreeze": {"type": "boolean"},
|
||||
"defaultRipple": {"type": "boolean"},
|
||||
"emailHash": {"type": "string"},
|
||||
"emailHash": {"$ref": "hash128"},
|
||||
"walletLocator": {"$ref": "hash256"},
|
||||
"walletSize": {"type": "integer"},
|
||||
"messageKey": {"type": "string"},
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "uint32",
|
||||
"description": "A string representation of an unsigned 32-bit integer (0-4294967295)",
|
||||
"type": "string",
|
||||
"pattern": "^(429496729[0-5]|42949672[0-8][0-9]|4294967[01][0-9]{2}|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|429[0-3][0-9]{6}|42[0-8][0-9]{7}|4[01][0-9]{8}|[1-3][0-9]{9}|[1-9][0-9]{8}|[1-9][0-9]{7}|[1-9][0-9]{6}|[1-9][0-9]{5}|[1-9][0-9]{4}|[1-9][0-9]{3}|[1-9][0-9]{2}|[1-9][0-9]|[0-9])$"
|
||||
"description": "A 32-bit unsigned integer",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
const BigNumber = require('bignumber.js');
|
||||
const core = require('../../core');
|
||||
const errors = require('./errors');
|
||||
|
||||
function dropsToXrp(drops) {
|
||||
return (new BigNumber(drops)).dividedBy(1000000.0).toString();
|
||||
@@ -49,11 +50,22 @@ function composeAsync(wrapper, callback) {
|
||||
};
|
||||
}
|
||||
|
||||
function convertExceptions(f) {
|
||||
return function() {
|
||||
try {
|
||||
return f.apply(this, arguments);
|
||||
} catch (error) {
|
||||
throw new errors.ApiError(error.message);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
core,
|
||||
dropsToXrp,
|
||||
xrpToDrops,
|
||||
toRippledAmount,
|
||||
wrapCatch,
|
||||
composeAsync
|
||||
composeAsync,
|
||||
convertExceptions
|
||||
};
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const utils = require('./utils');
|
||||
const ValidationError = require('./errors').ValidationError;
|
||||
const schemaValidate = require('./schema-validator');
|
||||
const ripple = require('./utils').core;
|
||||
|
||||
function error(text) {
|
||||
return new ValidationError(text);
|
||||
@@ -16,7 +16,7 @@ function validateAddressAndSecret(obj) {
|
||||
throw error('Parameter missing: secret');
|
||||
}
|
||||
try {
|
||||
if (!ripple.Seed.from_json(secret).get_key(address)) {
|
||||
if (!utils.core.Seed.from_json(secret).get_key(address)) {
|
||||
throw error('secret does not match address');
|
||||
}
|
||||
} catch (exception) {
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
|
||||
function generateWallet() {
|
||||
const wallet = common.core.Wallet.generate();
|
||||
if (!wallet) {
|
||||
throw new common.errors.ApiError('Could not generate wallet');
|
||||
}
|
||||
return wallet;
|
||||
}
|
||||
|
||||
module.exports = generateWallet;
|
||||
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const ripple = require('./common').core;
|
||||
const core = require('./common').core;
|
||||
const server = require('./server/server');
|
||||
const connect = server.connect;
|
||||
const disconnect = server.disconnect;
|
||||
@@ -23,12 +23,13 @@ const prepareOrderCancellation = require('./transaction/ordercancellation');
|
||||
const prepareSettings = require('./transaction/settings');
|
||||
const sign = require('./transaction/sign');
|
||||
const submit = require('./transaction/submit');
|
||||
const generateWallet = require('./generate/wallet');
|
||||
const errors = require('./common').errors;
|
||||
const convertExceptions = require('./common').convertExceptions;
|
||||
const generateWallet = convertExceptions(core.Wallet.generate);
|
||||
|
||||
function RippleAPI(options) {
|
||||
const _options = _.assign({}, options, {automatic_resubmission: false});
|
||||
this.remote = new ripple.Remote(_options);
|
||||
this.remote = new core.Remote(_options);
|
||||
}
|
||||
|
||||
RippleAPI.prototype = {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/* @flow */
|
||||
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const utils = require('./utils');
|
||||
@@ -20,23 +19,19 @@ function getAccountLines(remote, address, ledgerVersion, options, marker, limit,
|
||||
peer: options.counterparty
|
||||
};
|
||||
|
||||
const currency = options.currency ? options.currency.toUpperCase() : null;
|
||||
remote.requestAccountLines(requestOptions, (error, data) => {
|
||||
return error ? callback(error) :
|
||||
callback(null, {
|
||||
marker: data.marker,
|
||||
results: data.lines.map(parseAccountTrustline)
|
||||
.filter(_.partial(currencyFilter, currency))
|
||||
.filter(_.partial(currencyFilter, options.currency || null))
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getTrustlines(
|
||||
account: string,
|
||||
options: {currency: string, counterparty: string,
|
||||
limit: number, ledgerVersion: number},
|
||||
callback: () => void
|
||||
): void {
|
||||
function getTrustlines(account: string, options: {currency: string,
|
||||
counterparty: string, limit: number, ledgerVersion: number},
|
||||
callback: () => void): void {
|
||||
validate.address(account);
|
||||
validate.getTrustlinesOptions(options);
|
||||
|
||||
|
||||
@@ -1,20 +1,7 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const utils = require('./utils');
|
||||
const ripple = utils.common.core;
|
||||
const validate = utils.common.validate;
|
||||
const xrpToDrops = utils.common.xrpToDrops;
|
||||
|
||||
function renameCounterpartyToIssuer(amount) {
|
||||
if (amount === undefined || amount.counterparty === undefined) {
|
||||
return amount;
|
||||
}
|
||||
const issuer = amount.counterparty === undefined ?
|
||||
amount.issuer : amount.counterparty;
|
||||
const withIssuer = _.assign({}, amount, {issuer: issuer});
|
||||
return _.omit(withIssuer, 'counterparty');
|
||||
}
|
||||
|
||||
const OfferCreateFlags = {
|
||||
passive: {set: 'Passive'},
|
||||
@@ -22,19 +9,14 @@ const OfferCreateFlags = {
|
||||
fillOrKill: {set: 'FillOrKill'}
|
||||
};
|
||||
|
||||
function toRippledAmount(amount) {
|
||||
return amount.currency === 'XRP' ?
|
||||
xrpToDrops(amount.value) : renameCounterpartyToIssuer(amount);
|
||||
}
|
||||
|
||||
function createOrderTransaction(account, order) {
|
||||
validate.address(account);
|
||||
validate.order(order);
|
||||
|
||||
const transaction = new ripple.Transaction();
|
||||
const takerPays = toRippledAmount(order.direction === 'buy' ?
|
||||
const transaction = new utils.common.core.Transaction();
|
||||
const takerPays = utils.common.toRippledAmount(order.direction === 'buy' ?
|
||||
order.quantity : order.totalPrice);
|
||||
const takerGets = toRippledAmount(order.direction === 'buy' ?
|
||||
const takerGets = utils.common.toRippledAmount(order.direction === 'buy' ?
|
||||
order.totalPrice : order.quantity);
|
||||
|
||||
transaction.offerCreate(account, takerPays, takerGets);
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
'use strict';
|
||||
const utils = require('./utils');
|
||||
const validate = utils.common.validate;
|
||||
const ripple = utils.common.core;
|
||||
|
||||
function createOrderCancellationTransaction(account, sequence) {
|
||||
validate.address(account);
|
||||
validate.sequence(sequence);
|
||||
|
||||
const transaction = new ripple.Transaction();
|
||||
const transaction = new utils.common.core.Transaction();
|
||||
transaction.offerCancel(account, sequence);
|
||||
return transaction;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/* @flow */
|
||||
/* eslint-disable valid-jsdoc */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const BigNumber = require('bignumber.js');
|
||||
const utils = require('./utils');
|
||||
const ripple = utils.common.core;
|
||||
const validate = utils.common.validate;
|
||||
const toRippledAmount = utils.common.toRippledAmount;
|
||||
|
||||
@@ -37,80 +36,48 @@ function applyAnyCounterpartyEncoding(payment) {
|
||||
}
|
||||
}
|
||||
|
||||
function uppercaseCurrencyCodes(payment) {
|
||||
if (payment.source.amount) {
|
||||
payment.source.amount.currency =
|
||||
payment.source.amount.currency.toUpperCase();
|
||||
}
|
||||
if (payment.destination.amount) {
|
||||
payment.destination.amount.currency =
|
||||
payment.destination.amount.currency.toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
function createPaymentTransaction(account, payment) {
|
||||
applyAnyCounterpartyEncoding(payment);
|
||||
uppercaseCurrencyCodes(payment);
|
||||
validate.address(account);
|
||||
validate.payment(payment);
|
||||
|
||||
const transaction = new ripple.Transaction();
|
||||
const transactionData = {
|
||||
const transaction = new utils.common.core.Transaction();
|
||||
transaction.payment({
|
||||
from: payment.source.address,
|
||||
to: payment.destination.address,
|
||||
amount: toRippledAmount(payment.destination.amount)
|
||||
};
|
||||
});
|
||||
|
||||
if (payment.invoiceID) {
|
||||
transaction.invoiceID(payment.invoiceID);
|
||||
}
|
||||
transaction.payment(transactionData);
|
||||
|
||||
if (payment.source.tag) {
|
||||
transaction.sourceTag(parseInt(payment.source.tag, 10));
|
||||
transaction.sourceTag(payment.source.tag);
|
||||
}
|
||||
if (payment.destination.tag) {
|
||||
transaction.destinationTag(parseInt(payment.destination.tag, 10));
|
||||
transaction.destinationTag(payment.destination.tag);
|
||||
}
|
||||
if (payment.paths) {
|
||||
transaction.paths(JSON.parse(payment.paths));
|
||||
}
|
||||
if (payment.memos) {
|
||||
_.forEach(payment.memos, memo =>
|
||||
transaction.addMemo(memo.type, memo.format, memo.data)
|
||||
);
|
||||
}
|
||||
if (payment.allowPartialPayment) {
|
||||
transaction.setFlags(['PartialPayment']);
|
||||
}
|
||||
if (payment.noDirectRipple) {
|
||||
transaction.setFlags(['NoRippleDirect']);
|
||||
}
|
||||
|
||||
if (isSendMaxAllowed(payment)) {
|
||||
const maxValue = new BigNumber(payment.source.amount.value)
|
||||
.plus(payment.source.slippage || 0).toString();
|
||||
|
||||
if (payment.source.amount.currency === 'XRP') {
|
||||
transaction.sendMax(utils.common.xrpToDrops(maxValue));
|
||||
} else {
|
||||
transaction.sendMax({
|
||||
value: maxValue,
|
||||
currency: payment.source.amount.currency,
|
||||
issuer: payment.source.amount.counterparty
|
||||
});
|
||||
}
|
||||
const maxAmount = _.assign({}, payment.source.amount, {value: maxValue});
|
||||
transaction.sendMax(toRippledAmount(maxAmount));
|
||||
}
|
||||
|
||||
if (typeof payment.paths === 'string') {
|
||||
transaction.paths(JSON.parse(payment.paths));
|
||||
} else if (typeof payment.paths === 'object') {
|
||||
transaction.paths(payment.paths);
|
||||
}
|
||||
|
||||
if (payment.memos && Array.isArray(payment.memos)) {
|
||||
for (let m = 0; m < payment.memos.length; m++) {
|
||||
const memo = payment.memos[m];
|
||||
transaction.addMemo(memo.type, memo.format, memo.data);
|
||||
}
|
||||
}
|
||||
|
||||
const flags = [];
|
||||
if (payment.allowPartialPayment) {
|
||||
flags.push('PartialPayment');
|
||||
}
|
||||
if (payment.noDirectRipple) {
|
||||
flags.push('NoRippleDirect');
|
||||
}
|
||||
if (flags.length > 0) {
|
||||
transaction.setFlags(flags);
|
||||
}
|
||||
return transaction;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,9 @@
|
||||
const _ = require('lodash');
|
||||
const assert = require('assert');
|
||||
const utils = require('./utils');
|
||||
const ripple = utils.common.core;
|
||||
const validate = utils.common.validate;
|
||||
const AccountFlagIndices = utils.common.constants.AccountFlagIndices;
|
||||
const AccountFields = utils.common.constants.AccountFields;
|
||||
const ValidationError = utils.common.errors.ValidationError;
|
||||
|
||||
// Emptry string passed to setting will clear it
|
||||
const CLEAR_SETTING = '';
|
||||
@@ -33,7 +31,7 @@ function setTransactionFields(transaction, input) {
|
||||
const field = fieldSchema[fieldName];
|
||||
let value = input[field.name];
|
||||
|
||||
if (typeof value === 'undefined') {
|
||||
if (value === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -42,24 +40,9 @@ function setTransactionFields(transaction, input) {
|
||||
value = field.defaults;
|
||||
}
|
||||
|
||||
if (field.encoding === 'hex') {
|
||||
// If the field is supposed to be hex, why don't we do a
|
||||
// toString('hex') on it?
|
||||
if (field.length) {
|
||||
// Field is fixed length, why are we checking here though?
|
||||
// We could move this to validateInputs
|
||||
if (value.length > field.length) {
|
||||
throw new ValidationError('Parameter length exceeded: ' + fieldName);
|
||||
} else if (value.length < field.length) {
|
||||
value = _.padLeft(value, field.length);
|
||||
}
|
||||
} else {
|
||||
// Field is variable length. Expecting an ascii string as input.
|
||||
// This is currently only used for Domain field
|
||||
value = new Buffer(value, 'ascii').toString('hex');
|
||||
}
|
||||
|
||||
value = value.toUpperCase();
|
||||
if (field.encoding === 'hex' && !field.length) {
|
||||
// This is currently only used for Domain field
|
||||
value = new Buffer(value, 'ascii').toString('hex').toUpperCase();
|
||||
}
|
||||
|
||||
transaction.tx_json[fieldName] = value;
|
||||
@@ -80,18 +63,14 @@ function setTransactionFields(transaction, input) {
|
||||
*/
|
||||
|
||||
function convertTransferRate(transferRate) {
|
||||
if (_.isNumber(transferRate)) {
|
||||
return transferRate * Math.pow(10, 9);
|
||||
}
|
||||
|
||||
return transferRate;
|
||||
return _.isNumber(transferRate) ? transferRate * 1e9 : transferRate;
|
||||
}
|
||||
|
||||
function createSettingsTransaction(account, settings) {
|
||||
validate.address(account);
|
||||
validate.settings(settings);
|
||||
|
||||
const transaction = new ripple.Transaction();
|
||||
const transaction = new utils.common.core.Transaction();
|
||||
if (settings.regularKey) {
|
||||
return transaction.setRegularKey({
|
||||
account: account,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const utils = require('./utils');
|
||||
const ripple = utils.common.core;
|
||||
const core = utils.common.core;
|
||||
const validate = utils.common.validate;
|
||||
|
||||
/**
|
||||
@@ -19,7 +19,7 @@ const HASH_TX_SIGN = 0x53545800; // 'STX'
|
||||
const HASH_TX_SIGN_TESTNET = 0x73747800; // 'stx'
|
||||
|
||||
function getKeyPair(address, secret) {
|
||||
return ripple.Seed.from_json(secret).get_key(address);
|
||||
return core.Seed.from_json(secret).get_key(address);
|
||||
}
|
||||
|
||||
function getPublicKeyHex(keypair) {
|
||||
@@ -27,7 +27,7 @@ function getPublicKeyHex(keypair) {
|
||||
}
|
||||
|
||||
function serialize(txJSON) {
|
||||
return ripple.SerializedObject.from_json(txJSON);
|
||||
return core.SerializedObject.from_json(txJSON);
|
||||
}
|
||||
|
||||
function hashSerialization(serialized, prefix) {
|
||||
@@ -44,13 +44,12 @@ function signingHash(txJSON, isTestNet=false) {
|
||||
|
||||
function computeSignature(txJSON, keypair) {
|
||||
const signature = keypair.sign(signingHash(txJSON));
|
||||
return ripple.sjcl.codec.hex.fromBits(signature).toUpperCase();
|
||||
return core.sjcl.codec.hex.fromBits(signature).toUpperCase();
|
||||
}
|
||||
|
||||
/*:: type TxJSON = {Account: string; SigningPubKey: string,
|
||||
TxnSignature: string};
|
||||
type Signed = {signedTransaction: string; id: string}; */
|
||||
function sign(txJSON: TxJSON, secret: string): Signed {
|
||||
function sign(txJSON: {Account: string; SigningPubKey: string,
|
||||
TxnSignature: string}, secret: string):
|
||||
{signedTransaction: string; id: string} {
|
||||
validate.txJSON(txJSON);
|
||||
validate.addressAndSecret({address: txJSON.Account, secret: secret});
|
||||
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const utils = require('./utils');
|
||||
const ripple = utils.common.core;
|
||||
const validate = utils.common.validate;
|
||||
|
||||
/*:: type Callback = (err: any, data: any) => void */
|
||||
function submit(tx_blob: string, callback: Callback): void {
|
||||
function submit(tx_blob: string,
|
||||
callback: (err: any, data: any) => void): void {
|
||||
validate.blob(tx_blob);
|
||||
const request = new ripple.Request(this.remote, 'submit');
|
||||
const request = new utils.common.core.Request(this.remote, 'submit');
|
||||
request.message.tx_blob = tx_blob;
|
||||
request.request(null, callback);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const utils = require('./utils');
|
||||
const ripple = utils.common.core;
|
||||
const validate = utils.common.validate;
|
||||
|
||||
const TrustSetFlags = {
|
||||
@@ -20,7 +19,7 @@ function createTrustlineTransaction(account, trustline) {
|
||||
value: trustline.limit
|
||||
};
|
||||
|
||||
const transaction = new ripple.Transaction();
|
||||
const transaction = new utils.common.core.Transaction();
|
||||
transaction.trustSet(account, limit,
|
||||
trustline.qualityIn, trustline.qualityOut);
|
||||
utils.setTransactionBitFlags(transaction, trustline, TrustSetFlags);
|
||||
|
||||
Reference in New Issue
Block a user