@com-chain/jsc3l 2.0.1-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +45 -0
  3. package/build/bcRead.d.ts +15 -0
  4. package/build/bcRead.js +123 -0
  5. package/build/bcRead.js.map +1 -0
  6. package/build/bcTransaction.d.ts +10 -0
  7. package/build/bcTransaction.js +135 -0
  8. package/build/bcTransaction.js.map +1 -0
  9. package/build/blockies.d.ts +1 -0
  10. package/build/blockies.js +91 -0
  11. package/build/blockies.js.map +1 -0
  12. package/build/config.d.ts +6 -0
  13. package/build/config.js +25 -0
  14. package/build/config.js.map +1 -0
  15. package/build/connection.d.ts +58 -0
  16. package/build/connection.js +204 -0
  17. package/build/connection.js.map +1 -0
  18. package/build/customization.d.ts +37 -0
  19. package/build/customization.js +129 -0
  20. package/build/customization.js.map +1 -0
  21. package/build/ethereum/cipher.d.ts +3 -0
  22. package/build/ethereum/cipher.js +94 -0
  23. package/build/ethereum/cipher.js.map +1 -0
  24. package/build/ethereum/ethFuncs.d.ts +12 -0
  25. package/build/ethereum/ethFuncs.js +70 -0
  26. package/build/ethereum/ethFuncs.js.map +1 -0
  27. package/build/ethereum/etherUnits.d.ts +5 -0
  28. package/build/ethereum/etherUnits.js +60 -0
  29. package/build/ethereum/etherUnits.js.map +1 -0
  30. package/build/ethereum/myetherwallet.d.ts +47 -0
  31. package/build/ethereum/myetherwallet.js +294 -0
  32. package/build/ethereum/myetherwallet.js.map +1 -0
  33. package/build/ethereum/uiFuncs.d.ts +3 -0
  34. package/build/ethereum/uiFuncs.js +51 -0
  35. package/build/ethereum/uiFuncs.js.map +1 -0
  36. package/build/index.d.ts +111 -0
  37. package/build/index.js +310 -0
  38. package/build/index.js.map +1 -0
  39. package/build/memo.d.ts +6 -0
  40. package/build/memo.js +24 -0
  41. package/build/memo.js.map +1 -0
  42. package/build/qr.d.ts +8 -0
  43. package/build/qr.js +35 -0
  44. package/build/qr.js.map +1 -0
  45. package/build/rest/ajaxReq.d.ts +31 -0
  46. package/build/rest/ajaxReq.js +127 -0
  47. package/build/rest/ajaxReq.js.map +1 -0
  48. package/build/rest/endpoint.d.ts +18 -0
  49. package/build/rest/endpoint.js +26 -0
  50. package/build/rest/endpoint.js.map +1 -0
  51. package/build/rest/http.d.ts +10 -0
  52. package/build/rest/http.js +60 -0
  53. package/build/rest/http.js.map +1 -0
  54. package/build/rest/serializer.d.ts +1 -0
  55. package/build/rest/serializer.js +94 -0
  56. package/build/rest/serializer.js.map +1 -0
  57. package/build/type.d.ts +24 -0
  58. package/build/type.js +9 -0
  59. package/build/type.js.map +1 -0
  60. package/build/wallet.d.ts +35 -0
  61. package/build/wallet.js +162 -0
  62. package/build/wallet.js.map +1 -0
  63. package/package.json +41 -0
  64. package/src/bcRead.ts +184 -0
  65. package/src/bcTransaction.ts +157 -0
  66. package/src/blockies.ts +113 -0
  67. package/src/config.ts +33 -0
  68. package/src/connection.ts +243 -0
  69. package/src/customization.ts +156 -0
  70. package/src/ethereum/cipher.ts +118 -0
  71. package/src/ethereum/ethFuncs.ts +73 -0
  72. package/src/ethereum/etherUnits.ts +66 -0
  73. package/src/ethereum/myetherwallet.ts +354 -0
  74. package/src/ethereum/uiFuncs.ts +55 -0
  75. package/src/index.ts +366 -0
  76. package/src/memo.ts +37 -0
  77. package/src/qr.ts +34 -0
  78. package/src/rest/ajaxReq.ts +160 -0
  79. package/src/rest/endpoint.ts +31 -0
  80. package/src/rest/http.ts +69 -0
  81. package/src/rest/serializer.ts +99 -0
  82. package/src/type.ts +37 -0
  83. package/src/wallet.ts +200 -0
  84. package/tsconfig.json +31 -0
package/src/index.ts ADDED
@@ -0,0 +1,366 @@
1
+ import * as ethFuncs from './ethereum/ethFuncs' // Utilities to pass on
2
+ import * as memo from './memo'
3
+
4
+ // Only required for blockie helper
5
+ import blockies from './blockies'
6
+ import Wallet from './ethereum/myetherwallet'
7
+
8
+ import * as t from './type'
9
+
10
+
11
+ // Abstracts
12
+
13
+ import HttpAbstract from './rest/http'
14
+ import EndpointAbstract from './rest/endpoint'
15
+ import AjaxReqAbstract from './rest/ajaxReq'
16
+ import ConnectionMgrAbstract from './connection'
17
+ import CustomizationAbstract from './customization'
18
+ import MessagingWalletAbstract from './wallet'
19
+ import BcReadAbstract from './bcRead'
20
+ import BcTransactionAbstract from './bcTransaction'
21
+
22
+
23
+
24
+ function createIcon (address: string | Wallet) {
25
+ if (address instanceof Wallet) {
26
+ address = address.getAddressString()
27
+ }
28
+ return blockies({
29
+ seed: address.toLowerCase(),
30
+ size: 8,
31
+ scale: 16
32
+ }).toDataURL()
33
+ }
34
+
35
+
36
+ abstract class AbstractJsc3l {
37
+
38
+ protected abstract httpRequest: t.HttpRequest
39
+ protected abstract persistentStore: t.IPersistentStore
40
+
41
+ localDefaultConf: {}
42
+
43
+ endpoint: string
44
+
45
+ _Endpoint: new (baseUrl: any) => EndpointAbstract
46
+ _connection: null | ConnectionMgrAbstract
47
+ _http: null | HttpAbstract
48
+
49
+
50
+ constructor (localDefaultConf?) {
51
+ this.localDefaultConf = localDefaultConf || {}
52
+ }
53
+
54
+ /**
55
+ * `connection` facility needs to be lazy loaded as `this` and
56
+ * abstract `httpRequest` is not available in constructor.
57
+ */
58
+ get connection () {
59
+ if (!this._connection) {
60
+ const self = this
61
+ class ConnectionMgr extends ConnectionMgrAbstract {
62
+ http = self.http
63
+ persistentStore = self.persistentStore
64
+ }
65
+ this._connection = new ConnectionMgr()
66
+ }
67
+ return this._connection
68
+ }
69
+
70
+ /**
71
+ * `Endpoint` class is a facility that needs to be lazy loaded as
72
+ * `this` and abstract `httpRequest` is not available in
73
+ * constructor.
74
+ */
75
+ get Endpoint () {
76
+ if (!this._Endpoint) {
77
+ const self = this
78
+ class Endpoint extends EndpointAbstract {
79
+ httpRequest = self.httpRequest
80
+ }
81
+ this._Endpoint = Endpoint
82
+ }
83
+ return this._Endpoint
84
+ }
85
+
86
+ /**
87
+ * 'http' facility needs to be lazy loaded as 'this' and abstract
88
+ * httpRequest is not available in constructor.
89
+ */
90
+ get http () {
91
+ if (!this._http) {
92
+ const self = this
93
+ // ConnectionMgr
94
+
95
+ class Http extends HttpAbstract {
96
+ httpRequest = self.httpRequest
97
+ }
98
+ this._http = new Http()
99
+ }
100
+ return this._http
101
+ }
102
+
103
+
104
+
105
+ getAjaxReq (endpointUrl: string): AjaxReqAbstract {
106
+ const self = this
107
+ class AjaxReq extends AjaxReqAbstract {
108
+ endpoint = new self.Endpoint(endpointUrl)
109
+ }
110
+ return new AjaxReq()
111
+ }
112
+
113
+ /**
114
+ * `getConfJson` check persistent storage for configuration for
115
+ * given currency, otherwise will use the given repo to fetch
116
+ * it (and save it in persistent storage).
117
+ */
118
+ async getConfig (repo: string, currencyName: string) {
119
+ const cfgJson = this.connection.getLocalConfJSON()
120
+ if (cfgJson && cfgJson.server.name === currencyName) {
121
+ return cfgJson
122
+ }
123
+ return await this.connection.getConfJSON(currencyName, repo)
124
+ }
125
+
126
+
127
+ /**
128
+ * `getConfJson` check persistent storage for configuration for
129
+ * given currency, otherwise will use the given repo to fetch
130
+ * it (and save it in persistent storage).
131
+ */
132
+ getCustomization (config: any): CustomizationAbstract {
133
+ class Customization extends CustomizationAbstract {
134
+ cfg = config
135
+ }
136
+ return new Customization(this.localDefaultConf)
137
+ }
138
+
139
+
140
+ getWallet (
141
+ endpointUrl: string,
142
+ currencyName: string,
143
+ unlockUrl: string): new () => MessagingWalletAbstract {
144
+
145
+ const self = this
146
+ class MessagingWallet extends MessagingWalletAbstract {
147
+ ajaxReq = self.getAjaxReq(endpointUrl)
148
+ currencyName = currencyName
149
+ unlockUrl = unlockUrl
150
+ }
151
+ // XXXvlab: should we instanciate this ?
152
+ return MessagingWallet
153
+ }
154
+
155
+
156
+ getBcRead (endpointUrl, contracts): BcReadAbstract {
157
+ const self = this
158
+ class BcRead extends BcReadAbstract {
159
+ ajaxReq = self.getAjaxReq(endpointUrl)
160
+ contracts = contracts
161
+ }
162
+ return new BcRead()
163
+ }
164
+
165
+
166
+ getBcTransaction (endpointUrl, contracts): BcTransactionAbstract {
167
+ const self = this
168
+ class BcTransaction extends BcTransactionAbstract {
169
+ ajaxReq = self.getAjaxReq(endpointUrl)
170
+ contracts = contracts
171
+ }
172
+ return new BcTransaction()
173
+ }
174
+
175
+
176
+ _currencyMgrPromises = {}
177
+ async getCurrencyMgr (currencyName: string, endpointUrl?: string, repoUrl?: string) {
178
+ const key = Array.from(arguments).join('\0')
179
+
180
+ if (!this._currencyMgrPromises[key]) {
181
+ this._currencyMgrPromises[key] =
182
+ this._getCurrencyMgr(currencyName, endpointUrl, repoUrl)
183
+ }
184
+
185
+ return await this._currencyMgrPromises[key]
186
+ }
187
+
188
+
189
+ async _getCurrencyMgr (currencyName: string,
190
+ endpointUrl?: string,
191
+ repoUrl?: string): Promise<any> {
192
+ if (!repoUrl) {
193
+ if (this.connection.repo) {
194
+ repoUrl = this.connection.repo
195
+ } else {
196
+ repoUrl = await this.connection.lookupAvailableComChainRepo()
197
+ }
198
+ }
199
+
200
+ if (!endpointUrl) {
201
+ if (this.connection.endpoint) {
202
+ endpointUrl = this.connection.endpoint
203
+ } else {
204
+ endpointUrl = (await this.connection.acquireEndPoint(repoUrl)).endpoint
205
+ }
206
+ }
207
+
208
+ const config = await this.getConfig(repoUrl, currencyName)
209
+ const customization = this.getCustomization(config)
210
+ const contracts = [
211
+ customization.getContract1(),
212
+ customization.getContract2()
213
+ ]
214
+
215
+ const self = this
216
+ const wallet = this.getWallet(
217
+ endpointUrl, currencyName, customization.getUnlockUrl())
218
+ return {
219
+ // unlockWallet: (jsonData, password) => wallet.getWalletFromPrivKeyFile(jsonData, password),
220
+ jsc3l: this,
221
+ customization,
222
+ ajaxReq: this.getAjaxReq(endpointUrl),
223
+ wallet: wallet,
224
+ bcRead: this.getBcRead(endpointUrl, contracts),
225
+ bcTransaction: this.getBcTransaction(endpointUrl, contracts),
226
+ }
227
+ }
228
+ }
229
+
230
+
231
+
232
+
233
+
234
+
235
+ Object.assign(AbstractJsc3l.prototype, {
236
+ memo,
237
+ ethFuncs,
238
+ createIcon
239
+ })
240
+
241
+
242
+ abstract class IntegratedJsc3lAbstract extends AbstractJsc3l {
243
+
244
+ /**
245
+ * `ajaxReq` depends on a loaded endpoint in
246
+ * `this.connection.endpoint` obtained through
247
+ * `this.endpoint.acquireEndPoint(..)`. XXXvlab: We could cache the
248
+ * result with endpoint being a key.
249
+ */
250
+ get ajaxReq (): AjaxReqAbstract {
251
+ if (!this.connection.endpoint) {
252
+ throw new Error('An endpoint need to have been acquired.')
253
+ }
254
+ return this.getAjaxReq(this.connection.endpoint)
255
+ }
256
+
257
+
258
+ /**
259
+ * `customization` depends on a local configuration being available
260
+ * through a previous call to `this.connection.getConfJSON(..)`
261
+ *
262
+ * XXXvlab: We could cache the result with result of
263
+ * `connection.getLocalConf()` being the key.
264
+ */
265
+ get customization (): CustomizationAbstract {
266
+ // XXXvlab: Probably don't need a module for that, as the configuration
267
+ // is always re-queried and quite small, we could cache-it in memory.
268
+ const localCfg = this.connection.getLocalConfJSON()
269
+ if (!localCfg) {
270
+ throw new Error('No configuration is available locally.')
271
+ }
272
+
273
+ return this.getCustomization(localCfg)
274
+ }
275
+
276
+
277
+ /**
278
+ * `wallet` depends on both:
279
+ * - a local configuration (only for the `currencyName`) being
280
+ * available through a previous call to
281
+ * `this.connection.getConfJSON(..)`
282
+ * - a loaded endpoint in `this.connection.endpoint` obtained
283
+ * through `this.endpoint.acquireEndPoint(..)`.
284
+ *
285
+ * XXXvlab: We could cache the result with result of
286
+ * `connection.getLocalConf()` and `this.connection.endpoint` being
287
+ * the keys.
288
+ */
289
+ get wallet (): MessagingWalletAbstract["constructor"] {
290
+ if (!this.ajaxReq) {
291
+ throw Error('a connect() is required before accessing wallet')
292
+ }
293
+ let localCfg: any
294
+ try {
295
+ localCfg = this.customization
296
+ } catch (e) {
297
+ throw Error('A local conf needs to be available before accessing wallet')
298
+ }
299
+ return this.getWallet(
300
+ this.ajaxReq.endpoint.baseUrl,
301
+ localCfg.getCurrencyName(),
302
+ this.customization.getUnlockUrl())
303
+ }
304
+
305
+
306
+ /**
307
+ * `bcRead` access depends on both:
308
+ * - a local configuration (only for contracts information) being
309
+ * available through a previous call to
310
+ * `this.connection.getConfJSON(..)`
311
+ * - a loaded endpoint in `this.connection.endpoint` obtained through
312
+ * `this.endpoint.acquireEndPoint(..)`.
313
+ *
314
+ * XXXvlab: We could cache the result with result of
315
+ * `connection.getLocalConf()` and `this.connection.endpoint` being
316
+ * the keys.
317
+ */
318
+ get bcRead (): BcReadAbstract {
319
+ if (!this.ajaxReq) {
320
+ throw Error('an init() is required before accessing bcRead')
321
+ }
322
+ let localCfg: any
323
+ try {
324
+ localCfg = this.customization
325
+ } catch (e) {
326
+ throw Error('A local conf needs to be available before accessing wallet')
327
+ }
328
+ return this.getBcRead(
329
+ this.ajaxReq.endpoint.baseUrl,
330
+ [localCfg.getContract1(), localCfg.getContract2()]
331
+ )
332
+ }
333
+
334
+
335
+ /**
336
+ * `bcTransaction` access depends on both:
337
+ * - a local configuration (only for contracts information) being
338
+ * available through a previous call to
339
+ * `this.connection.getConfJSON(..)`
340
+ * - a loaded endpoint in `this.connection.endpoint` obtained through
341
+ * `this.endpoint.acquireEndPoint(..)`.
342
+ *
343
+ * XXXvlab: We could cache the result with result of
344
+ * `connection.getLocalConf()` and `this.connection.endpoint` being
345
+ * the keys.
346
+ */
347
+ get bcTransaction (): BcTransactionAbstract {
348
+ if (!this.ajaxReq) {
349
+ throw Error('an init() is required before accessing bcTransaction')
350
+ }
351
+ let localCfg: any
352
+ try {
353
+ localCfg = this.customization
354
+ } catch (e) {
355
+ throw Error('A local conf needs to be available before accessing wallet')
356
+ }
357
+ return this.getBcTransaction(
358
+ this.ajaxReq.endpoint.baseUrl,
359
+ [localCfg.getContract1(), localCfg.getContract2()]
360
+ )
361
+ }
362
+
363
+ }
364
+
365
+
366
+ export default IntegratedJsc3lAbstract
package/src/memo.ts ADDED
@@ -0,0 +1,37 @@
1
+ import { cipherMsg, decipherMsg } from './ethereum/cipher'
2
+
3
+
4
+ // Used in the test
5
+ export function getMyTransactionMemo (msgWallet, transaction) {
6
+ const key = msgWallet.messageKeysFromWallet()
7
+ const watchedAddress = msgWallet.getAddressString().toLowerCase()
8
+ const { addr_to, message_to, addr_from, message_from } = transaction
9
+
10
+ return getTransactionMemo(transaction, watchedAddress, key)
11
+ }
12
+
13
+
14
+ export function getTransactionMemo (transaction, forAddress, messageKey) {
15
+ const { addr_to, message_to, addr_from, message_from } = transaction
16
+
17
+ if (addr_to.toLowerCase() === forAddress && message_to) {
18
+ return decipherMsg(messageKey, message_to)
19
+ }
20
+
21
+ if (addr_from.toLowerCase() === forAddress && message_from) {
22
+ return decipherMsg(messageKey, message_from)
23
+ }
24
+
25
+ return ''
26
+ }
27
+
28
+
29
+ export function getTxMemoCipheredData (fromMsgKey, toMsgKey, msgFrom, msgTo) {
30
+ return {
31
+ ...(fromMsgKey && msgFrom) &&
32
+ { memo_from: cipherMsg(fromMsgKey, msgFrom) },
33
+ ...(toMsgKey && msgTo) &&
34
+ { memo_to: cipherMsg(toMsgKey, msgTo) },
35
+ }
36
+ }
37
+
package/src/qr.ts ADDED
@@ -0,0 +1,34 @@
1
+ import ethUtil from 'ethereumjs-util'
2
+
3
+
4
+ export function checkSignedQRFromString (qrString, intendedRecipientAddress) {
5
+ let data:string, signature: string
6
+ try {
7
+ ({ data, signature } = JSON.parse(qrString))
8
+ } catch (e) {
9
+ return 'InvalidFormat'
10
+ }
11
+ return checkSignedQR(data, signature, intendedRecipientAddress)
12
+ }
13
+
14
+ export function checkSignedQR (data, signature, intendedRecipientAddress) {
15
+ let hash: string
16
+ let publicSignKey: string
17
+ let receiverAddress: string
18
+ try {
19
+ hash = ethUtil.sha3(JSON.stringify(data))
20
+ publicSignKey = ethUtil.ecrecover(
21
+ hash, signature.v, signature.r, signature.s)
22
+ receiverAddress = ethUtil.bufferToHex(
23
+ ethUtil.publicToAddress(publicSignKey))
24
+ } catch (e) {
25
+ return 'InvalidFormat'
26
+ }
27
+
28
+ if (receiverAddress !== data.address) { return 'InvalidSignature' }
29
+ if (data.destinary !== intendedRecipientAddress) { return 'NotForYou' }
30
+ if ((new Date(data.end)).getTime() < (new Date()).getTime()) {
31
+ return 'Expired'
32
+ }
33
+ return { signature, data }
34
+ }
@@ -0,0 +1,160 @@
1
+
2
+ class URL {
3
+ static SERVER = 'api.php';
4
+ static ENROLL = 'enroll.php';
5
+ static TRANLIST = 'trnslist.php';
6
+ static TRANCHECK = 'api.php';
7
+ static EXPORTTRAN = 'export.php';
8
+ static GETCODE = 'getuid.php';
9
+ static GETADDRESS = 'getadd.php';
10
+ static KEYSTORE = 'keys.php';
11
+ static requestMessages = 'requestMessages.php';
12
+ }
13
+
14
+
15
+ export default abstract class AjaxReqAbstract {
16
+
17
+ // XXXvlab: need to be public only to allow integrated mode (used in
18
+ // ``jsc3l.wallet``)
19
+ public abstract endpoint: any
20
+
21
+ pendingPosts = []
22
+
23
+ //
24
+ // URL.SERVER POST requests (that are using queuing mecanism)
25
+ //
26
+
27
+ post (data) {
28
+ const self = this
29
+ return new Promise(function (resolve, reject) {
30
+ self.pendingPosts.push({ data, resolve, reject })
31
+ if (self.pendingPosts.length === 1) self.queuePost()
32
+ })
33
+ }
34
+
35
+ queuePost () {
36
+ const { data, resolve, reject } = this.pendingPosts[0]
37
+
38
+ try {
39
+ this.endpoint.post(URL.SERVER, data).then(data => {
40
+ resolve(data.data)
41
+ })
42
+ } catch (err) {
43
+ console.log(err)
44
+ reject(err)
45
+ }
46
+ this.pendingPosts.splice(0, 1)
47
+ if (this.pendingPosts.length > 0) { this.queuePost() }
48
+ }
49
+
50
+
51
+ getBalance (addr) { return this.post({ balance: addr }) }
52
+ getTransactionData (addr) { return this.post({ txdata: addr }) }
53
+ async sendTx (rawTx, additionalData) {
54
+ const data: {[k: string]: any} =
55
+ await this.post(Object.assign({}, { rawtx: rawTx }, additionalData ?? {}))
56
+
57
+ return {
58
+ isError: !!data.error,
59
+ error: data.error ? data.data : data.msg
60
+ }
61
+ }
62
+
63
+
64
+ getEstimatedGas (txobj) { return this.post({ estimatedGas: txobj }) }
65
+ getEthCall (txobj) { return this.post({ ethCall: txobj }) }
66
+
67
+ getEthCallAt (txobj, blockNb) {
68
+ return this.post({ ethCallAt: txobj, blockNb })
69
+ }
70
+
71
+
72
+ //
73
+ // Other calls
74
+ //
75
+
76
+ enrollPost (data) {
77
+ return this.endpoint.post(URL.ENROLL, { data: JSON.stringify(data) })
78
+ }
79
+
80
+ validateEnrollmentLetter (id, currency, signature) {
81
+ return this.enrollPost({ id, currency, signature })
82
+ }
83
+
84
+ enrollAddress (id, address, currency, token) {
85
+ return this.enrollPost({ id, addresse: address, token, currency })
86
+ }
87
+
88
+ async getTransList (id, count, offset) {
89
+ // for some strange reasons, the answer is stringified 2 times,
90
+ // so we need to unpack each entry a second time.
91
+ const data = await this.endpoint.get(URL.TRANLIST, { addr: id, count, offset })
92
+ return data.map((dataJSON) => JSON.parse(dataJSON))
93
+ }
94
+
95
+ getTransCheck (hash) {
96
+ return this.endpoint.get(URL.TRANCHECK, { hash })
97
+ }
98
+
99
+ getExportTransList (id, start, end) {
100
+ return this.endpoint.get(URL.EXPORTTRAN, { addr: id, start, end })
101
+ }
102
+
103
+ getExportTransListWithId (id, start, end) {
104
+ return this.endpoint.get(URL.EXPORTTRAN, { addr: id, start, end })
105
+ }
106
+
107
+ getCodesFromAddresses (addresses, currency, caller, signature) {
108
+ return this.endpoint.post(URL.GETCODE, {
109
+ server: currency,
110
+ caller,
111
+ signature,
112
+ addresses
113
+ })
114
+ }
115
+
116
+ getAddressesFromCode (code, currency, caller, signature) {
117
+ return this.endpoint.post(URL.GETADDRESS, {
118
+ server: currency,
119
+ caller,
120
+ signature,
121
+ code
122
+ })
123
+ }
124
+
125
+ getMessageKey (addr, withPrivate) {
126
+ const data: {[k: string]: any} = { addr }
127
+ if (withPrivate) data.private = '1'
128
+ return this.endpoint.get(URL.KEYSTORE, data)
129
+ }
130
+
131
+ publishMessageKey (data, sign) {
132
+ return this.endpoint.post(URL.KEYSTORE, { data, sign })
133
+ }
134
+
135
+ requestUnlock (address, url) {
136
+ return this.endpoint.post(url, { address })
137
+ }
138
+
139
+ getReqMessages (addFrom, addTo) {
140
+ return this.endpoint.get(
141
+ URL.requestMessages,
142
+ { add_req: addFrom, add_cli: addTo })
143
+ }
144
+
145
+ publishReqMessages (data, sign) {
146
+ return this.endpoint.post(URL.requestMessages, { data, sign })
147
+ }
148
+
149
+ currBlock () { return this.endpoint.get(URL.SERVER) }
150
+
151
+ async getBlock (hash) {
152
+ let res = await this.endpoint.get(URL.SERVER, { hash })
153
+ if (res && typeof res !== 'object') {
154
+ res = JSON.parse(res).transaction
155
+ }
156
+ return res
157
+ }
158
+
159
+ }
160
+
@@ -0,0 +1,31 @@
1
+ import HttpAbstract from './http'
2
+ import postSerializer from './serializer'
3
+
4
+ /**
5
+ * Serialize data, adds default config and transfer to code http module
6
+ *
7
+ */
8
+ abstract class PostSerializedHttpAbstract extends HttpAbstract {
9
+ post (...[url, data, opts]: any[]) {
10
+ return super.post(url, postSerializer(data), opts)
11
+ }
12
+ }
13
+
14
+ /**
15
+ * Prepend endpoint address to url, and support passing data to
16
+ * querystring when method is GET.
17
+ */
18
+ export default abstract class EndpointAbstract extends PostSerializedHttpAbstract {
19
+
20
+ baseUrl: string
21
+
22
+ constructor (baseUrl) {
23
+ super()
24
+ this.baseUrl = baseUrl
25
+ }
26
+
27
+ request (method, url, ...args: any[]) {
28
+ url = url.includes('://') ? url : this.baseUrl + url
29
+ return super.request(method, url, ...args)
30
+ }
31
+ }
@@ -0,0 +1,69 @@
1
+ import * as t from '../type'
2
+
3
+
4
+ function getHostOrUrlParts (HostOrUrl: string): t.UrlParts {
5
+ let protocol: string, host: string, port: number, path: string
6
+ if (HostOrUrl.includes('://')) {
7
+ ;[protocol, HostOrUrl] = HostOrUrl.split('://')
8
+ } else {
9
+ protocol = 'https'
10
+ HostOrUrl = HostOrUrl.replace(/\/$/, '')
11
+ }
12
+ if (HostOrUrl.includes('/')) {
13
+ const splits = HostOrUrl.split('/')
14
+ ;[host, path] = [splits[0], '/' + splits.slice(1).join('/')]
15
+ } else {
16
+ // assume host only
17
+ path = ''
18
+ host = HostOrUrl
19
+ }
20
+ if (host.includes(':')) {
21
+ const splits = host.split(':')
22
+ if (splits.length > 2) {
23
+ throw new Error(`Too many ':' to get host and port: ${host}`)
24
+ }
25
+ ;[host, port] = [splits[0], parseInt(splits[1])]
26
+ } else {
27
+ if (protocol === 'http') {
28
+ port = 80
29
+ } else if (protocol === 'https') {
30
+ port = 443
31
+ } else {
32
+ throw new Error(
33
+ `Could not infer port from unknown protocol ${protocol}`
34
+ )
35
+ }
36
+ }
37
+ return {
38
+ protocol,
39
+ host,
40
+ port,
41
+ path,
42
+ }
43
+ }
44
+
45
+
46
+ /**
47
+ * Support passing data to querystring when method is GET.
48
+ */
49
+ export default abstract class HttpAbstract {
50
+
51
+ protected abstract httpRequest: t.HttpRequest
52
+
53
+ async request (...[method, url, data, opts]: any[]) {
54
+ if (method === 'GET' && data && Object.keys(data).length > 0) {
55
+ url += '?' + (new URLSearchParams(data)).toString()
56
+ }
57
+
58
+ var coreOpts = {
59
+ method,
60
+ data: method === 'GET' ? null : data,
61
+ ...opts,
62
+ ...getHostOrUrlParts(url)
63
+ }
64
+ return await <any> this.httpRequest(coreOpts)
65
+ }
66
+
67
+ get (...args: any[]) { return this.request('GET', ...args) }
68
+ post (...args: any[]) { return this.request('POST', ...args) }
69
+ }