/
utils.js
132 lines (111 loc) · 3.83 KB
/
utils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
'use strict'
const _ = require('lodash')
const WebFinger = require('webfinger.js')
const currencySymbolMap = require('currency-symbol-map').currencySymbolMap
const superagent = require('superagent-promise')(require('superagent'), Promise)
const Config = require('./config')
const Ledger = require('./ledger')
const NotFoundError = require('../errors/not-found-error')
// TODO implement caching
module.exports = class Utils {
static constitute () { return [ Config, Ledger ] }
constructor (config, ledger) {
this.ledger = ledger
this.ledgerUriPublic = config.data.getIn(['ledger', 'public_uri'])
this.ledgerPrefix = config.data.getIn(['ledger', 'prefix'])
this.localUri = config.data.getIn(['server', 'base_uri'])
this.localHost = config.data.getIn(['server', 'base_host'])
}
isWebfinger (destination) {
// TODO better email style checking
return destination.search('@') > -1
}
* _webfingerLookup (resource) {
const webfinger = new WebFinger({
webfist_fallback: false,
tls_only: true,
uri_fallback: false,
request_timeout: 3000
})
return (yield new Promise((resolve, reject) => {
webfinger.lookup(resource, (err, res) => err ? reject(err) : resolve(res.object))
}))
}
* getWebfingerAccount (address) {
try {
const response = yield this._webfingerLookup(address)
return {
ledgerUri: _.filter(response.links, {rel: 'https://interledger.org/rel/ledgerUri'})[0].href,
paymentUri: _.filter(response.links, {rel: 'https://interledger.org/rel/spsp/v2'})[0].href,
ilpAddress: _.filter(response.links, {rel: 'https://interledger.org/rel/ilpAddress'})[0].href
}
} catch (e) {
throw new NotFoundError('Unknown account')
}
}
/**
* options
* - destination - string (username or webfinger)
*/
* parseDestination (options) {
const self = this
const destination = options.destination
let ledgerUri
let paymentUri
let ilpAddress
let ledgerInfo = {}
let receiverInfo = {}
if (self.isWebfinger(destination)) {
// Webfinger lookup
const account = yield self.getWebfingerAccount(destination)
ledgerUri = account.ledgerUri
paymentUri = account.paymentUri
ilpAddress = account.ilpAddress
} else {
// Local account
ledgerUri = self.ledgerUriPublic
paymentUri = self.localUri + '/spsp/' + destination
ilpAddress = self.ledgerPrefix + destination
}
// Get SPSP receiver info
let spspResponse
try {
spspResponse = (yield superagent.get(paymentUri).end()).body
ledgerInfo = spspResponse.ledger_info
receiverInfo = spspResponse.receiver_info
} catch (e) {
throw new NotFoundError('Unknown spsp receiver')
}
return {
ledgerUri,
paymentUri,
ilpAddress,
identifier: self.isWebfinger(destination) ? destination : this.getWebfingerAddress(destination),
currencyCode: ledgerInfo.currency_code,
currencySymbol: currencySymbolMap[ledgerInfo.currency_code],
name: receiverInfo.name,
imageUrl: receiverInfo.image_url
}
}
getWebfingerAddress (username) {
return username + '@' + this.localHost
}
* hostLookup (host) {
let response
try {
response = yield this._webfingerLookup(host)
} catch (e) {
throw new NotFoundError('Host is unavailable')
}
if (!response) throw new NotFoundError('Host is unavailable')
if (!response.properties) throw new NotFoundError("Host doesn't have an ilp-kit or the version is not compatible")
try {
return {
publicKey: response.properties['https://interledger.org/rel/publicKey'],
peersRpcUri: _.filter(response.links, {rel: 'https://interledger.org/rel/peersRpcUri'})[0].href
}
} catch (e) {
throw new NotFoundError('Host webfinger parsing failed')
}
}
}