UNPKG

2.74 kBPlain TextView Raw
1import BigNumber from 'bignumber.js'
2import { AccountInfo } from '../types/accounts'
3import { BackendInstance, BackendServices } from '../types/backend'
4
5import { create as createLogger } from '../common/log'
6const log = createLogger('one-to-one-backend')
7
8export interface OneToOneOptions {
9 spread: number,
10 ratesApiUrl: string,
11 getInfo: (accountId: string) => AccountInfo,
12 getAssetCode: (accountId: string) => string
13}
14
15/**
16 * Backend which charges no spread and trades everything one-to-one.
17 */
18export default class OneToOneBackend implements BackendInstance {
19 protected spread: number
20 protected getInfo: (accountId: string) => AccountInfo | undefined
21
22 /**
23 * Constructor.
24 *
25 * @param {Integer} opts.spread The spread we will use to mark up the FX rates
26 */
27 constructor (opts: OneToOneOptions, api: BackendServices) {
28 this.spread = opts.spread || 0
29 this.getInfo = api.getInfo
30 }
31
32 /**
33 * Nothing to do since this backend is totally static.
34 */
35 async connect () {
36 // Nothing to do
37 }
38
39 /**
40 * Get a rate for the given parameters.
41 *
42 * The one-to-one backend applies an exchange of 1, however, it will subtract
43 * the spread if a spread is set in the configuration.
44 *
45 * @param sourceAccount The account ID of the previous party
46 * @param destinationAccount The account ID of the next hop party
47 */
48 async getRate (sourceAccount: string, destinationAccount: string) {
49 const sourceInfo = this.getInfo(sourceAccount)
50 const destinationInfo = this.getInfo(destinationAccount)
51
52 if (!sourceInfo) {
53 log.error('unable to fetch account info for source account. accountId=%s', sourceAccount)
54 throw new Error('unable to fetch account info for source account. accountId=' + sourceAccount)
55 }
56 if (!destinationInfo) {
57 log.error('unable to fetch account info for destination account. accountId=%s', destinationAccount)
58 throw new Error('unable to fetch account info for destination account. accountId=' + destinationAccount)
59 }
60
61 const scaleDiff = destinationInfo.assetScale - sourceInfo.assetScale
62 // The spread is subtracted from the rate when going in either direction,
63 // so that the DestinationAmount always ends up being slightly less than
64 // the (equivalent) SourceAmount -- regardless of which of the 2 is fixed:
65 //
66 // SourceAmount * (1 - Spread) = DestinationAmount
67 //
68 const rate = new BigNumber(1).minus(this.spread).shiftedBy(scaleDiff).toPrecision(15)
69
70 return Number(rate)
71 }
72
73 /**
74 * This method is called to allow statistics to be collected by the backend.
75 *
76 * The one-to-one backend does not support this functionality.
77 */
78 submitPayment () {
79 return Promise.resolve()
80 }
81}