@com-chain/jsc3l 2.0.1-rc.0 → 2.0.1-rc.10

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 (46) hide show
  1. package/build/bcRead.d.ts +8 -9
  2. package/build/bcRead.js +93 -35
  3. package/build/bcRead.js.map +1 -1
  4. package/build/bcTransaction.d.ts +2 -1
  5. package/build/bcTransaction.js +55 -76
  6. package/build/bcTransaction.js.map +1 -1
  7. package/build/config/transactions.d.ts +44 -0
  8. package/build/config/transactions.js +29 -0
  9. package/build/config/transactions.js.map +1 -0
  10. package/build/connection.js +14 -8
  11. package/build/connection.js.map +1 -1
  12. package/build/customization.js +11 -2
  13. package/build/customization.js.map +1 -1
  14. package/build/ethereum/ethFuncs.js +1 -1
  15. package/build/ethereum/ethFuncs.js.map +1 -1
  16. package/build/ethereum/etherUnits.js +5 -5
  17. package/build/ethereum/etherUnits.js.map +1 -1
  18. package/build/ethereum/uiFuncs.d.ts +1 -3
  19. package/build/ethereum/uiFuncs.js +13 -23
  20. package/build/ethereum/uiFuncs.js.map +1 -1
  21. package/build/index.d.ts +10 -6
  22. package/build/index.js +35 -21
  23. package/build/index.js.map +1 -1
  24. package/build/qr.d.ts +31 -6
  25. package/build/qr.js +32 -12
  26. package/build/qr.js.map +1 -1
  27. package/build/rest/ajaxReq.d.ts +2 -10
  28. package/build/rest/ajaxReq.js +10 -32
  29. package/build/rest/ajaxReq.js.map +1 -1
  30. package/build/type.d.ts +4 -4
  31. package/build/wallet.d.ts +7 -9
  32. package/build/wallet.js +31 -39
  33. package/build/wallet.js.map +1 -1
  34. package/package.json +3 -1
  35. package/src/bcRead.ts +108 -49
  36. package/src/bcTransaction.ts +58 -77
  37. package/src/config/transactions.ts +30 -0
  38. package/src/connection.ts +15 -7
  39. package/src/customization.ts +17 -2
  40. package/src/ethereum/ethFuncs.ts +1 -1
  41. package/src/ethereum/etherUnits.ts +5 -5
  42. package/src/ethereum/uiFuncs.ts +16 -25
  43. package/src/index.ts +50 -28
  44. package/src/qr.ts +86 -12
  45. package/src/rest/ajaxReq.ts +10 -39
  46. package/src/wallet.ts +40 -50
@@ -131,14 +131,25 @@ export default abstract class CustomizationAbstract {
131
131
  if (!currencyName) {
132
132
  currencyName = this.cfg.server.name
133
133
  }
134
+ if (!this.cfg.custoRepo) {
135
+ throw Error(
136
+ 'Requested getCurrencyAssetBaseUrl while configuration is not available (yet?)'
137
+ )
138
+ }
134
139
  return `${this.cfg.custoRepo}${currencyName}`
135
140
  }
136
141
 
137
142
  public getCssUrl (currencyName?: string) {
138
143
  try {
139
- // XXXvlab: I guess that we don't need to keep 'etherwallet' css names
140
- return `${this.getCurrencyAssetBaseUrl(currencyName)}/css/etherwallet-master.min.css`
144
+ // XXXvlab: I guess that we don't need to keep 'etherwallet' css
145
+ // names
146
+ return this.getCurrencyAssetBaseUrl(currencyName) +
147
+ '/css/etherwallet-master.min.css'
141
148
  } catch (e) {
149
+ console.log(
150
+ '`customization.getCssUrl(..)` called before configuration was ' +
151
+ "ready. Returning `localDefaultConf`'s value."
152
+ )
142
153
  return this.localDefaultConf.server.url_Css
143
154
  }
144
155
  }
@@ -149,6 +160,10 @@ export default abstract class CustomizationAbstract {
149
160
  // be agnostic ?
150
161
  return `${this.getCurrencyAssetBaseUrl(currencyName)}/images/lem.png`
151
162
  } catch (e) {
163
+ console.log(
164
+ '`customization.getCurrencyLogoUrl(..)` called before configuration ' +
165
+ 'was ready. Returning empty string.'
166
+ )
152
167
  return ''
153
168
  }
154
169
  }
@@ -36,7 +36,7 @@ function padLeftEven (hex) {
36
36
  }
37
37
 
38
38
  export function addTinyMoreToGas (hex) {
39
- hex = this.sanitizeHex(hex)
39
+ hex = sanitizeHex(hex)
40
40
  return new BigNumber(hex).plus(etherUnits.getValueOfUnit('gwei'))
41
41
  .toDigits(2).toString(16)
42
42
  }
@@ -41,26 +41,26 @@ export function getValueOfUnit (unit) {
41
41
  export function fiatToWei (number, pricePerEther) {
42
42
  return new BigNumber(String(number))
43
43
  .div(pricePerEther)
44
- .times(this.getValueOfUnit('ether'))
44
+ .times(getValueOfUnit('ether'))
45
45
  .round(0)
46
46
  .toString(10)
47
47
  }
48
48
 
49
49
  export function toFiat (number, unit, multi) {
50
- return new BigNumber(this.toEther(number, unit))
50
+ return new BigNumber(toEther(number, unit))
51
51
  .times(multi)
52
52
  .round(5)
53
53
  .toString(10)
54
54
  }
55
55
 
56
56
  export function toEther (number, unit) {
57
- return new BigNumber(this.toWei(number, unit))
58
- .div(this.getValueOfUnit('ether'))
57
+ return new BigNumber(toWei(number, unit))
58
+ .div(getValueOfUnit('ether'))
59
59
  .toString(10)
60
60
  }
61
61
 
62
62
  export function toWei (number, unit) {
63
63
  return new BigNumber(String(number))
64
- .times(this.getValueOfUnit(unit))
64
+ .times(getValueOfUnit(unit))
65
65
  .toString(10)
66
66
  }
@@ -24,32 +24,23 @@ function isTxDataValid (txData) {
24
24
  }
25
25
 
26
26
  export function generateTx (txData, data) {
27
- try {
28
- isTxDataValid(txData)
27
+ isTxDataValid(txData)
29
28
 
30
- const rawTx: {[k: string]: any} = {
31
- nonce: ethFuncs.sanitizeHex(data.nonce),
32
- gasPrice: ethFuncs.sanitizeHex(
33
- ethFuncs.addTinyMoreToGas(data.gasprice)),
34
- gasLimit: ethFuncs.sanitizeHex(
35
- ethFuncs.decimalToHex(txData.gasLimit)),
36
- to: ethFuncs.sanitizeHex(txData.to),
37
- value: ethFuncs.sanitizeHex(
38
- ethFuncs.decimalToHex(etherUnits.toWei(txData.value, txData.unit))),
39
- data: ethFuncs.sanitizeHex(txData.data)
40
- }
41
- const eTx = new Tx(rawTx)
42
-
43
- eTx.sign(Buffer.from(txData.key, 'hex'))
44
- rawTx.rawTx = JSON.stringify(rawTx)
45
- rawTx.signedTx = '0x' + eTx.serialize().toString('hex')
46
- rawTx.isError = false
47
- return rawTx
48
- } catch (e) {
49
- return {
50
- isError: true,
51
- error: e
52
- }
29
+ const rawTx: {[k: string]: any} = {
30
+ nonce: ethFuncs.sanitizeHex(data.nonce),
31
+ gasPrice: ethFuncs.sanitizeHex(
32
+ ethFuncs.addTinyMoreToGas(data.gasprice)),
33
+ gasLimit: ethFuncs.sanitizeHex(
34
+ ethFuncs.decimalToHex(txData.gasLimit)),
35
+ to: ethFuncs.sanitizeHex(txData.to),
36
+ value: ethFuncs.sanitizeHex(
37
+ ethFuncs.decimalToHex(etherUnits.toWei(txData.value, txData.unit))),
38
+ data: ethFuncs.sanitizeHex(txData.data)
53
39
  }
40
+ const eTx = new Tx(rawTx)
41
+
42
+ eTx.sign(Buffer.from(txData.key, 'hex'))
43
+ rawTx.rawTx = JSON.stringify(rawTx)
44
+ return '0x' + eTx.serialize().toString('hex')
54
45
  }
55
46
 
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as ethFuncs from './ethereum/ethFuncs' // Utilities to pass on
2
2
  import * as memo from './memo'
3
+ import * as qr from './qr'
3
4
 
4
5
  // Only required for blockie helper
5
6
  import blockies from './blockies'
@@ -17,8 +18,8 @@ import ConnectionMgrAbstract from './connection'
17
18
  import CustomizationAbstract from './customization'
18
19
  import MessagingWalletAbstract from './wallet'
19
20
  import BcReadAbstract from './bcRead'
20
- import BcTransactionAbstract from './bcTransaction'
21
-
21
+ import { BcTransactionAbstract, transactionFactory } from './bcTransaction'
22
+ import localTransactionDefs from './config/transactions'
22
23
 
23
24
 
24
25
  function createIcon (address: string | Wallet) {
@@ -39,6 +40,7 @@ abstract class AbstractJsc3l {
39
40
  protected abstract persistentStore: t.IPersistentStore
40
41
 
41
42
  localDefaultConf: {}
43
+ defaultTransactionDefs: []
42
44
 
43
45
  endpoint: string
44
46
 
@@ -47,8 +49,9 @@ abstract class AbstractJsc3l {
47
49
  _http: null | HttpAbstract
48
50
 
49
51
 
50
- constructor (localDefaultConf?) {
52
+ constructor (localDefaultConf?, defaultTransactionDefs?) {
51
53
  this.localDefaultConf = localDefaultConf || {}
54
+ this.defaultTransactionDefs = defaultTransactionDefs || localTransactionDefs
52
55
  }
53
56
 
54
57
  /**
@@ -163,23 +166,30 @@ abstract class AbstractJsc3l {
163
166
  }
164
167
 
165
168
 
166
- getBcTransaction (endpointUrl, contracts): BcTransactionAbstract {
169
+ getBcTransaction (
170
+ endpointUrl, contracts, transactionDefs
171
+ ): BcTransactionAbstract {
167
172
  const self = this
168
173
  class BcTransaction extends BcTransactionAbstract {
169
174
  ajaxReq = self.getAjaxReq(endpointUrl)
170
175
  contracts = contracts
171
176
  }
177
+ transactionFactory(transactionDefs, BcTransaction)
172
178
  return new BcTransaction()
173
179
  }
174
180
 
175
181
 
176
182
  _currencyMgrPromises = {}
177
- async getCurrencyMgr (currencyName: string, endpointUrl?: string, repoUrl?: string) {
178
- const key = Array.from(arguments).join('\0')
183
+ async getCurrencyMgr (
184
+ currencyName: string, endpointUrl?: string, repoUrl?: string,
185
+ transactionDefs?: any[],
186
+ ) {
187
+
188
+ const key = JSON.stringify(Array.from(arguments))
179
189
 
180
190
  if (!this._currencyMgrPromises[key]) {
181
191
  this._currencyMgrPromises[key] =
182
- this._getCurrencyMgr(currencyName, endpointUrl, repoUrl)
192
+ this._getCurrencyMgr(currencyName, endpointUrl, repoUrl, transactionDefs)
183
193
  }
184
194
 
185
195
  return await this._currencyMgrPromises[key]
@@ -188,7 +198,9 @@ abstract class AbstractJsc3l {
188
198
 
189
199
  async _getCurrencyMgr (currencyName: string,
190
200
  endpointUrl?: string,
191
- repoUrl?: string): Promise<any> {
201
+ repoUrl?: string,
202
+ transactionDefs?: any[],
203
+ ): Promise<any> {
192
204
  if (!repoUrl) {
193
205
  if (this.connection.repo) {
194
206
  repoUrl = this.connection.repo
@@ -205,16 +217,19 @@ abstract class AbstractJsc3l {
205
217
  }
206
218
  }
207
219
 
220
+ transactionDefs = transactionDefs || localTransactionDefs
221
+
208
222
  const config = await this.getConfig(repoUrl, currencyName)
209
223
  const customization = this.getCustomization(config)
210
224
  const contracts = [
211
225
  customization.getContract1(),
212
- customization.getContract2()
226
+ customization.getContract2(),
227
+ customization.getContract3()
213
228
  ]
214
229
 
215
- const self = this
216
230
  const wallet = this.getWallet(
217
- endpointUrl, currencyName, customization.getUnlockUrl())
231
+ endpointUrl, currencyName, customization.getUnlockUrl()
232
+ )
218
233
  return {
219
234
  // unlockWallet: (jsonData, password) => wallet.getWalletFromPrivKeyFile(jsonData, password),
220
235
  jsc3l: this,
@@ -222,20 +237,19 @@ abstract class AbstractJsc3l {
222
237
  ajaxReq: this.getAjaxReq(endpointUrl),
223
238
  wallet: wallet,
224
239
  bcRead: this.getBcRead(endpointUrl, contracts),
225
- bcTransaction: this.getBcTransaction(endpointUrl, contracts),
240
+ bcTransaction: this.getBcTransaction(
241
+ endpointUrl, contracts, transactionDefs
242
+ ),
226
243
  }
227
244
  }
228
245
  }
229
246
 
230
247
 
231
-
232
-
233
-
234
-
235
248
  Object.assign(AbstractJsc3l.prototype, {
236
249
  memo,
237
250
  ethFuncs,
238
- createIcon
251
+ createIcon,
252
+ qr,
239
253
  })
240
254
 
241
255
 
@@ -257,7 +271,10 @@ abstract class IntegratedJsc3lAbstract extends AbstractJsc3l {
257
271
 
258
272
  /**
259
273
  * `customization` depends on a local configuration being available
260
- * through a previous call to `this.connection.getConfJSON(..)`
274
+ * through a previous call to
275
+ * `this.connection.getConfJSON(..)`. Although as it has some
276
+ * fallback available, we need to be able to support being called
277
+ * even if no local conf is loaded yet.
261
278
  *
262
279
  * XXXvlab: We could cache the result with result of
263
280
  * `connection.getLocalConf()` being the key.
@@ -265,11 +282,11 @@ abstract class IntegratedJsc3lAbstract extends AbstractJsc3l {
265
282
  get customization (): CustomizationAbstract {
266
283
  // XXXvlab: Probably don't need a module for that, as the configuration
267
284
  // is always re-queried and quite small, we could cache-it in memory.
268
- const localCfg = this.connection.getLocalConfJSON()
285
+ let localCfg = this.connection.getLocalConfJSON()
269
286
  if (!localCfg) {
270
- throw new Error('No configuration is available locally.')
287
+ console.log('No local configuration available yet.')
288
+ localCfg = {}
271
289
  }
272
-
273
290
  return this.getCustomization(localCfg)
274
291
  }
275
292
 
@@ -288,13 +305,13 @@ abstract class IntegratedJsc3lAbstract extends AbstractJsc3l {
288
305
  */
289
306
  get wallet (): MessagingWalletAbstract["constructor"] {
290
307
  if (!this.ajaxReq) {
291
- throw Error('a connect() is required before accessing wallet')
308
+ throw new Error('a connect() is required before accessing wallet')
292
309
  }
293
310
  let localCfg: any
294
311
  try {
295
312
  localCfg = this.customization
296
313
  } catch (e) {
297
- throw Error('A local conf needs to be available before accessing wallet')
314
+ throw new Error('A local conf needs to be available before accessing wallet')
298
315
  }
299
316
  return this.getWallet(
300
317
  this.ajaxReq.endpoint.baseUrl,
@@ -317,13 +334,13 @@ abstract class IntegratedJsc3lAbstract extends AbstractJsc3l {
317
334
  */
318
335
  get bcRead (): BcReadAbstract {
319
336
  if (!this.ajaxReq) {
320
- throw Error('an init() is required before accessing bcRead')
337
+ throw new Error('an init() is required before accessing bcRead')
321
338
  }
322
339
  let localCfg: any
323
340
  try {
324
341
  localCfg = this.customization
325
342
  } catch (e) {
326
- throw Error('A local conf needs to be available before accessing wallet')
343
+ throw new Error('A local conf needs to be available before accessing wallet')
327
344
  }
328
345
  return this.getBcRead(
329
346
  this.ajaxReq.endpoint.baseUrl,
@@ -346,17 +363,22 @@ abstract class IntegratedJsc3lAbstract extends AbstractJsc3l {
346
363
  */
347
364
  get bcTransaction (): BcTransactionAbstract {
348
365
  if (!this.ajaxReq) {
349
- throw Error('an init() is required before accessing bcTransaction')
366
+ throw new Error('an init() is required before accessing bcTransaction')
350
367
  }
351
368
  let localCfg: any
352
369
  try {
353
370
  localCfg = this.customization
354
371
  } catch (e) {
355
- throw Error('A local conf needs to be available before accessing wallet')
372
+ throw new Error('A local conf needs to be available before accessing wallet')
356
373
  }
357
374
  return this.getBcTransaction(
358
375
  this.ajaxReq.endpoint.baseUrl,
359
- [localCfg.getContract1(), localCfg.getContract2()]
376
+ [
377
+ localCfg.getContract1(),
378
+ localCfg.getContract2(),
379
+ localCfg.getContract3(),
380
+ ],
381
+ this.defaultTransactionDefs
360
382
  )
361
383
  }
362
384
 
package/src/qr.ts CHANGED
@@ -1,20 +1,43 @@
1
1
  import ethUtil from 'ethereumjs-util'
2
2
 
3
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)
4
+
5
+ type Signature = {
6
+ v: string,
7
+ r: string,
8
+ s: string,
9
+ }
10
+
11
+ type QRDataRaw = {
12
+ address: string,
13
+ destinary: string,
14
+ begin: string,
15
+ end: string,
16
+ viewbalance: boolean,
17
+ viewoldtran: boolean,
18
+ message_key?: string,
19
+ }
20
+
21
+ type QRData = {
22
+ address: string,
23
+ destinary: string,
24
+ begin: Date,
25
+ end: Date,
26
+ viewbalance: boolean,
27
+ viewoldtran: boolean,
28
+ message_key?: string,
12
29
  }
13
30
 
14
- export function checkSignedQR (data, signature, intendedRecipientAddress) {
31
+
32
+ export type SignedQR = {data: QRDataRaw, signature: Signature}
33
+
34
+
35
+ export function checkSignedQR (qrContent: SignedQR, intendedRecipientAddress) {
36
+
15
37
  let hash: string
16
38
  let publicSignKey: string
17
39
  let receiverAddress: string
40
+ const { data, signature } = qrContent
18
41
  try {
19
42
  hash = ethUtil.sha3(JSON.stringify(data))
20
43
  publicSignKey = ethUtil.ecrecover(
@@ -22,13 +45,64 @@ export function checkSignedQR (data, signature, intendedRecipientAddress) {
22
45
  receiverAddress = ethUtil.bufferToHex(
23
46
  ethUtil.publicToAddress(publicSignKey))
24
47
  } catch (e) {
48
+ // XXXVlab: should probably use exceptions
25
49
  return 'InvalidFormat'
26
50
  }
27
51
 
28
- if (receiverAddress !== data.address) { return 'InvalidSignature' }
29
- if (data.destinary !== intendedRecipientAddress) { return 'NotForYou' }
52
+ if (receiverAddress !== data.address) {
53
+ return 'InvalidSignature'
54
+ }
55
+ if (data.destinary !== intendedRecipientAddress) {
56
+ return 'NotForYou'
57
+ }
30
58
  if ((new Date(data.end)).getTime() < (new Date()).getTime()) {
31
59
  return 'Expired'
32
60
  }
33
- return { signature, data }
61
+ return true
62
+ }
63
+
64
+
65
+ export function makeSignedQRFragments (
66
+ qrContent: SignedQR,
67
+ fragmentCount: number
68
+ ) {
69
+
70
+ const signatureId = qrContent.signature.s.substring(4, 8)
71
+
72
+ const qrString = JSON.stringify(qrContent)
73
+ const fragmentSize = Math.ceil(qrString.length / fragmentCount)
74
+ const fragments = {
75
+ full: qrString,
76
+ }
77
+
78
+ for (let i = 0; i < fragmentCount; i++) {
79
+ fragments[i] = `FRAG_CR${signatureId}${i}${qrString.substring(
80
+ fragmentSize * i,
81
+ Math.min(fragmentSize * (i + 1), qrString.length)
82
+ )}`
83
+ }
84
+
85
+ return fragments
86
+ }
87
+
88
+
89
+ export function makeSignedQRContent (obj: QRData, privKey: string): SignedQR {
90
+ const { begin, end } = obj
91
+ const formatDate = (date: Date) =>
92
+ `${date.getFullYear()}/${(date.getMonth()+1)}/${date.getDate()}`
93
+ const data = Object.assign(obj, {
94
+ begin: formatDate(begin),
95
+ end: formatDate(end),
96
+ })
97
+
98
+ const hash = ethUtil.sha3(JSON.stringify(data))
99
+ const { v, r, s } = ethUtil.ecsign(hash, privKey)
100
+ const signature = {
101
+ v,
102
+ r: '0x' + r.toString('hex'),
103
+ s: '0x' + s.toString('hex'),
104
+ }
105
+
106
+ return { data, signature }
107
+
34
108
  }
@@ -3,7 +3,6 @@ class URL {
3
3
  static SERVER = 'api.php';
4
4
  static ENROLL = 'enroll.php';
5
5
  static TRANLIST = 'trnslist.php';
6
- static TRANCHECK = 'api.php';
7
6
  static EXPORTTRAN = 'export.php';
8
7
  static GETCODE = 'getuid.php';
9
8
  static GETADDRESS = 'getadd.php';
@@ -35,14 +34,12 @@ export default abstract class AjaxReqAbstract {
35
34
  queuePost () {
36
35
  const { data, resolve, reject } = this.pendingPosts[0]
37
36
 
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
- }
37
+ this.endpoint.post(URL.SERVER, data).then(data => {
38
+ if (data.error) {
39
+ resolve(data)
40
+ }
41
+ resolve(data.data)
42
+ })
46
43
  this.pendingPosts.splice(0, 1)
47
44
  if (this.pendingPosts.length > 0) { this.queuePost() }
48
45
  }
@@ -50,18 +47,7 @@ export default abstract class AjaxReqAbstract {
50
47
 
51
48
  getBalance (addr) { return this.post({ balance: addr }) }
52
49
  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 }) }
50
+ sendTx (rawTx, more) { return this.post({ rawtx: rawTx, ...(more ?? {}) }) }
65
51
  getEthCall (txobj) { return this.post({ ethCall: txobj }) }
66
52
 
67
53
  getEthCallAt (txobj, blockNb) {
@@ -77,14 +63,6 @@ export default abstract class AjaxReqAbstract {
77
63
  return this.endpoint.post(URL.ENROLL, { data: JSON.stringify(data) })
78
64
  }
79
65
 
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
66
  async getTransList (id, count, offset) {
89
67
  // for some strange reasons, the answer is stringified 2 times,
90
68
  // so we need to unpack each entry a second time.
@@ -92,16 +70,9 @@ export default abstract class AjaxReqAbstract {
92
70
  return data.map((dataJSON) => JSON.parse(dataJSON))
93
71
  }
94
72
 
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 })
73
+ async getExportTransList (id, start, end) {
74
+ const data = await this.endpoint.get(URL.EXPORTTRAN, { addr: id, start, end })
75
+ return data.map((dataJSON) => JSON.parse(dataJSON))
105
76
  }
106
77
 
107
78
  getCodesFromAddresses (addresses, currency, caller, signature) {
package/src/wallet.ts CHANGED
@@ -1,6 +1,7 @@
1
- import ethUtil from 'ethereumjs-util'
2
-
3
1
  import AjaxReq from './rest/ajaxReq'
2
+ import {
3
+ checkSignedQR, SignedQR, makeSignedQRContent, makeSignedQRFragments
4
+ } from './qr'
4
5
  import { shortenAddress, cipherMsg, decipherMsg } from './ethereum/cipher'
5
6
  import Wallet from './ethereum/myetherwallet'
6
7
 
@@ -15,7 +16,8 @@ export default abstract class MessagingWalletAbstract extends Wallet {
15
16
 
16
17
  public static async createWallet (this: { new(): MessagingWalletAbstract }) {
17
18
  const wallet = new this()
18
- return wallet.ensureWalletMessageKey()
19
+ await wallet.ensureWalletMessageKey()
20
+ return wallet
19
21
  }
20
22
 
21
23
  private publishMessageKey () {
@@ -49,7 +51,7 @@ export default abstract class MessagingWalletAbstract extends Wallet {
49
51
  const remoteKey = await this.ajaxReq.getMessageKey(
50
52
  this.getAddressString(), true)
51
53
  const walletMessageKey = this?.message_key
52
- if (remoteKey.public_message_key !== undefined) {
54
+ if (typeof remoteKey.public_message_key !== 'undefined') {
53
55
  this.message_key = {
54
56
  pub: remoteKey.public_message_key,
55
57
  priv: remoteKey.private_message_key,
@@ -94,7 +96,7 @@ export default abstract class MessagingWalletAbstract extends Wallet {
94
96
  const newKey = Wallet.generate(false)
95
97
  const mPub = newKey.getPublicKeyString()
96
98
  const mPriv = newKey.getPrivateKeyString()
97
- return { pub: mPub, priv: cipherMsg(this.getPublicKey(), mPriv) }
99
+ return { pub: mPub, priv: cipherMsg(this.getPublicKeyString(), mPriv) }
98
100
  }
99
101
 
100
102
  public messageKeysFromCrypted (cipheredKey) {
@@ -120,10 +122,14 @@ export default abstract class MessagingWalletAbstract extends Wallet {
120
122
  })
121
123
  }
122
124
 
123
- public enrollAddress (codeId, token) {
124
- return this.ajaxReq.enrollAddress(
125
- codeId, this.getAddressString(),
126
- this.currencyName, token)
125
+ public enrollAddress (id, token) {
126
+ return this.ajaxReq.enrollPost({
127
+ id,
128
+ token,
129
+ currency: this.currencyName,
130
+ // XXXvlab: Yes, typo is intentional here (in PHP API):
131
+ adresse: this.getAddressString(),
132
+ })
127
133
  }
128
134
 
129
135
  public requestUnlock () {
@@ -147,54 +153,38 @@ export default abstract class MessagingWalletAbstract extends Wallet {
147
153
  }
148
154
  }
149
155
 
150
-
151
156
  //
152
- // QR Codes requires EthUtils
157
+ // QR Code helpers
153
158
  //
154
159
 
155
- public makeSignedQRWithPubKey (objContent, pubKey) {
156
- objContent.message_key = cipherMsg(
157
- pubKey, this.messageKeysFromWallet()
158
- )
159
- objContent.address = this.getAddressString()
160
- return this.makeSignedQR(objContent)
160
+ public makeSignedQRContent (obj, pubKey: string | null) {
161
+ return makeSignedQRContent({
162
+ server: this.currencyName,
163
+ address: this.getAddressString(),
164
+ ...obj,
165
+ ...pubKey && {
166
+ message_key: cipherMsg(pubKey, this.messageKeysFromWallet())
167
+ },
168
+ }, this.privKey)
161
169
  }
162
170
 
163
- public makeSignedQR (obj) {
164
-
165
- // Values expected:
166
- const {
167
- server, destinary, begin, end,
168
- viewbalance, viewoldtran, pub_key
169
- } = obj
170
- const formatDate = (date) =>
171
- `${begin.getFullYear()}/${begin.getMonth()}/${begin.getDate()}`
172
- const objContent = Object.assign(obj, {
173
- address: this.getAddressString(),
174
- begin: formatDate(begin),
175
- end: formatDate(end)
176
- })
171
+ public makeSignedQRFragments (
172
+ obj, fragmentCount: number, pubKey: string | null
173
+ ) {
174
+ return makeSignedQRFragments(
175
+ this.makeSignedQRContent(obj, pubKey),
176
+ fragmentCount,
177
+ )
178
+ }
177
179
 
178
- const hash = ethUtil.sha3(JSON.stringify(objContent))
179
- const signature = ethUtil.ecsign(hash, this.privKey)
180
- return {
181
- signature,
182
- qrContent: JSON.stringify({
183
- data: objContent,
184
- signature: {
185
- v: signature.v,
186
- r: '0x' + signature.r.toString('hex'),
187
- s: '0x' + signature.s.toString('hex')
188
- }
189
- })
180
+ public checkSignedQRFromString (qrString: string) {
181
+ let qrContent: SignedQR
182
+ try {
183
+ qrContent = JSON.parse(qrString)
184
+ } catch (e) {
185
+ return 'InvalidFormat'
190
186
  }
187
+ return checkSignedQR(qrContent, this.getAddressString())
191
188
  }
192
189
 
193
190
  }
194
-
195
- // // TODO: What to do with this validateEnrollment
196
- // public static validateEnrollment (codeId, signature) {
197
- // return this.ajaxReq.validateEnrollmentLetter(
198
- // codeId, this.currencyName, signature)
199
- // }
200
-