@com-chain/jsc3l 2.0.1-rc.1 → 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.
- package/build/bcRead.d.ts +8 -9
- package/build/bcRead.js +93 -35
- package/build/bcRead.js.map +1 -1
- package/build/bcTransaction.d.ts +2 -1
- package/build/bcTransaction.js +55 -76
- package/build/bcTransaction.js.map +1 -1
- package/build/config/transactions.d.ts +44 -0
- package/build/config/transactions.js +29 -0
- package/build/config/transactions.js.map +1 -0
- package/build/connection.js +14 -8
- package/build/connection.js.map +1 -1
- package/build/customization.js +11 -2
- package/build/customization.js.map +1 -1
- package/build/ethereum/ethFuncs.js +1 -1
- package/build/ethereum/ethFuncs.js.map +1 -1
- package/build/ethereum/etherUnits.js +5 -5
- package/build/ethereum/etherUnits.js.map +1 -1
- package/build/ethereum/uiFuncs.d.ts +1 -3
- package/build/ethereum/uiFuncs.js +13 -23
- package/build/ethereum/uiFuncs.js.map +1 -1
- package/build/index.d.ts +6 -5
- package/build/index.js +28 -17
- package/build/index.js.map +1 -1
- package/build/qr.d.ts +31 -6
- package/build/qr.js +32 -12
- package/build/qr.js.map +1 -1
- package/build/rest/ajaxReq.d.ts +2 -10
- package/build/rest/ajaxReq.js +10 -32
- package/build/rest/ajaxReq.js.map +1 -1
- package/build/type.d.ts +4 -4
- package/build/wallet.d.ts +7 -9
- package/build/wallet.js +31 -39
- package/build/wallet.js.map +1 -1
- package/package.json +1 -1
- package/src/bcRead.ts +108 -49
- package/src/bcTransaction.ts +58 -77
- package/src/config/transactions.ts +30 -0
- package/src/connection.ts +15 -7
- package/src/customization.ts +17 -2
- package/src/ethereum/ethFuncs.ts +1 -1
- package/src/ethereum/etherUnits.ts +5 -5
- package/src/ethereum/uiFuncs.ts +16 -25
- package/src/index.ts +43 -23
- package/src/qr.ts +86 -12
- package/src/rest/ajaxReq.ts +10 -39
- package/src/wallet.ts +40 -50
package/src/ethereum/ethFuncs.ts
CHANGED
|
@@ -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(
|
|
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(
|
|
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(
|
|
58
|
-
.div(
|
|
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(
|
|
64
|
+
.times(getValueOfUnit(unit))
|
|
65
65
|
.toString(10)
|
|
66
66
|
}
|
package/src/ethereum/uiFuncs.ts
CHANGED
|
@@ -24,32 +24,23 @@ function isTxDataValid (txData) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export function generateTx (txData, data) {
|
|
27
|
-
|
|
28
|
-
isTxDataValid(txData)
|
|
27
|
+
isTxDataValid(txData)
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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 (
|
|
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 (
|
|
178
|
-
|
|
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
|
|
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,15 +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
230
|
const wallet = this.getWallet(
|
|
216
|
-
|
|
231
|
+
endpointUrl, currencyName, customization.getUnlockUrl()
|
|
232
|
+
)
|
|
217
233
|
return {
|
|
218
234
|
// unlockWallet: (jsonData, password) => wallet.getWalletFromPrivKeyFile(jsonData, password),
|
|
219
235
|
jsc3l: this,
|
|
@@ -221,20 +237,19 @@ abstract class AbstractJsc3l {
|
|
|
221
237
|
ajaxReq: this.getAjaxReq(endpointUrl),
|
|
222
238
|
wallet: wallet,
|
|
223
239
|
bcRead: this.getBcRead(endpointUrl, contracts),
|
|
224
|
-
bcTransaction: this.getBcTransaction(
|
|
240
|
+
bcTransaction: this.getBcTransaction(
|
|
241
|
+
endpointUrl, contracts, transactionDefs
|
|
242
|
+
),
|
|
225
243
|
}
|
|
226
244
|
}
|
|
227
245
|
}
|
|
228
246
|
|
|
229
247
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
248
|
Object.assign(AbstractJsc3l.prototype, {
|
|
235
249
|
memo,
|
|
236
250
|
ethFuncs,
|
|
237
|
-
createIcon
|
|
251
|
+
createIcon,
|
|
252
|
+
qr,
|
|
238
253
|
})
|
|
239
254
|
|
|
240
255
|
|
|
@@ -290,13 +305,13 @@ abstract class IntegratedJsc3lAbstract extends AbstractJsc3l {
|
|
|
290
305
|
*/
|
|
291
306
|
get wallet (): MessagingWalletAbstract["constructor"] {
|
|
292
307
|
if (!this.ajaxReq) {
|
|
293
|
-
throw Error('a connect() is required before accessing wallet')
|
|
308
|
+
throw new Error('a connect() is required before accessing wallet')
|
|
294
309
|
}
|
|
295
310
|
let localCfg: any
|
|
296
311
|
try {
|
|
297
312
|
localCfg = this.customization
|
|
298
313
|
} catch (e) {
|
|
299
|
-
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')
|
|
300
315
|
}
|
|
301
316
|
return this.getWallet(
|
|
302
317
|
this.ajaxReq.endpoint.baseUrl,
|
|
@@ -319,13 +334,13 @@ abstract class IntegratedJsc3lAbstract extends AbstractJsc3l {
|
|
|
319
334
|
*/
|
|
320
335
|
get bcRead (): BcReadAbstract {
|
|
321
336
|
if (!this.ajaxReq) {
|
|
322
|
-
throw Error('an init() is required before accessing bcRead')
|
|
337
|
+
throw new Error('an init() is required before accessing bcRead')
|
|
323
338
|
}
|
|
324
339
|
let localCfg: any
|
|
325
340
|
try {
|
|
326
341
|
localCfg = this.customization
|
|
327
342
|
} catch (e) {
|
|
328
|
-
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')
|
|
329
344
|
}
|
|
330
345
|
return this.getBcRead(
|
|
331
346
|
this.ajaxReq.endpoint.baseUrl,
|
|
@@ -348,17 +363,22 @@ abstract class IntegratedJsc3lAbstract extends AbstractJsc3l {
|
|
|
348
363
|
*/
|
|
349
364
|
get bcTransaction (): BcTransactionAbstract {
|
|
350
365
|
if (!this.ajaxReq) {
|
|
351
|
-
throw Error('an init() is required before accessing bcTransaction')
|
|
366
|
+
throw new Error('an init() is required before accessing bcTransaction')
|
|
352
367
|
}
|
|
353
368
|
let localCfg: any
|
|
354
369
|
try {
|
|
355
370
|
localCfg = this.customization
|
|
356
371
|
} catch (e) {
|
|
357
|
-
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')
|
|
358
373
|
}
|
|
359
374
|
return this.getBcTransaction(
|
|
360
375
|
this.ajaxReq.endpoint.baseUrl,
|
|
361
|
-
[
|
|
376
|
+
[
|
|
377
|
+
localCfg.getContract1(),
|
|
378
|
+
localCfg.getContract2(),
|
|
379
|
+
localCfg.getContract3(),
|
|
380
|
+
],
|
|
381
|
+
this.defaultTransactionDefs
|
|
362
382
|
)
|
|
363
383
|
}
|
|
364
384
|
|
package/src/qr.ts
CHANGED
|
@@ -1,20 +1,43 @@
|
|
|
1
1
|
import ethUtil from 'ethereumjs-util'
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
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) {
|
|
29
|
-
|
|
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
|
|
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
|
}
|
package/src/rest/ajaxReq.ts
CHANGED
|
@@ -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
|
-
|
|
39
|
-
|
|
40
|
-
resolve(data
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
|
|
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
|
-
|
|
96
|
-
|
|
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
|
-
|
|
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.
|
|
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 (
|
|
124
|
-
return this.ajaxReq.
|
|
125
|
-
|
|
126
|
-
|
|
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
|
|
157
|
+
// QR Code helpers
|
|
153
158
|
//
|
|
154
159
|
|
|
155
|
-
public
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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
|
-
|