@psf/bch-js 5.3.2 → 6.1.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.
- package/.on-save.json +8 -0
- package/LICENSE.md +1 -2
- package/package.json +8 -10
- package/src/bch-js.js +0 -2
- package/src/psf-slp-indexer.js +9 -9
- package/src/slp/utils.js +0 -1241
- package/src/utxo.js +0 -270
- package/test/integration/chains/bchn/utxo-integration.js +9 -124
- package/test/integration/slp.js +0 -470
- package/test/unit/slp-utils.js +0 -724
- package/test/unit/utxo-unit.js +0 -131
- package/src/ipfs.js +0 -454
- package/test/integration/chains/abc/slp.js +0 -226
- package/test/integration/chains/bchn-no-wl-slpdb/rawtransaction.js +0 -71
- package/test/integration/chains/bchn-no-wl-slpdb/slp.js +0 -273
- package/test/integration/chains/bchn-no-wl-slpdb/utxo-integration.js +0 -105
- package/test/unit/ipfs.js +0 -443
package/test/unit/slp-utils.js
CHANGED
|
@@ -45,216 +45,6 @@ describe('#SLP Utils', () => {
|
|
|
45
45
|
sandbox.restore()
|
|
46
46
|
})
|
|
47
47
|
|
|
48
|
-
describe('#list', () => {
|
|
49
|
-
it('should list single SLP token by id', async () => {
|
|
50
|
-
sandbox
|
|
51
|
-
.stub(uut.Utils.axios, 'get')
|
|
52
|
-
.resolves({ data: mockData.mockToken })
|
|
53
|
-
|
|
54
|
-
const tokenId =
|
|
55
|
-
'4276533bb702e7f8c9afd8aa61ebf016e95011dc3d54e55faa847ac1dd461e84'
|
|
56
|
-
|
|
57
|
-
const list = await uut.Utils.list(tokenId)
|
|
58
|
-
// console.log(`list: ${JSON.stringify(list, null, 2)}`)
|
|
59
|
-
|
|
60
|
-
assert.equal(list.id, tokenId)
|
|
61
|
-
assert.property(list, 'decimals')
|
|
62
|
-
assert.property(list, 'symbol')
|
|
63
|
-
assert.property(list, 'documentUri')
|
|
64
|
-
assert.property(list, 'name')
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
it('should list multiple SLP tokens by array of ids', async () => {
|
|
68
|
-
// Mock the call to the REST API
|
|
69
|
-
sandbox
|
|
70
|
-
.stub(uut.Utils.axios, 'post')
|
|
71
|
-
.resolves({ data: mockData.mockList })
|
|
72
|
-
|
|
73
|
-
const tokenIds = [
|
|
74
|
-
'4276533bb702e7f8c9afd8aa61ebf016e95011dc3d54e55faa847ac1dd461e84',
|
|
75
|
-
'8fc284dcbc922f7bb7e2a443dc3af792f52923bba403fcf67ca028c88e89da0e'
|
|
76
|
-
]
|
|
77
|
-
|
|
78
|
-
const list = await uut.Utils.list(tokenIds)
|
|
79
|
-
// console.log(`list: ${JSON.stringify(list, null, 2)}`)
|
|
80
|
-
|
|
81
|
-
assert.isArray(list)
|
|
82
|
-
assert.property(list[0], 'symbol')
|
|
83
|
-
assert.property(list[1], 'symbol')
|
|
84
|
-
})
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
describe('#balancesForAddress', () => {
|
|
88
|
-
it('should throw an error if input is not a string or array of strings', async () => {
|
|
89
|
-
try {
|
|
90
|
-
const address = 1234
|
|
91
|
-
|
|
92
|
-
await uut.Utils.balancesForAddress(address)
|
|
93
|
-
|
|
94
|
-
assert.equal(true, false, 'Uh oh. Code path should not end here.')
|
|
95
|
-
} catch (err) {
|
|
96
|
-
// console.log(`Error: `, err)
|
|
97
|
-
assert.include(
|
|
98
|
-
err.message,
|
|
99
|
-
'Input address must be a string or array of strings'
|
|
100
|
-
)
|
|
101
|
-
}
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
it('should fetch all balances for address: simpleledger:qzv3zz2trz0xgp6a96lu4m6vp2nkwag0kvyucjzqt9', async () => {
|
|
105
|
-
// Mock the call to the REST API
|
|
106
|
-
if (process.env.TEST === 'unit') {
|
|
107
|
-
sandbox
|
|
108
|
-
.stub(uut.Utils.axios, 'get')
|
|
109
|
-
.resolves({ data: mockData.balancesForAddress })
|
|
110
|
-
}
|
|
111
|
-
// sandbox
|
|
112
|
-
// .stub(uut.Utils, "balancesForAddress")
|
|
113
|
-
// .resolves(mockData.balancesForAddress)
|
|
114
|
-
|
|
115
|
-
const balances = await uut.Utils.balancesForAddress(
|
|
116
|
-
'simpleledger:qzv3zz2trz0xgp6a96lu4m6vp2nkwag0kvyucjzqt9'
|
|
117
|
-
)
|
|
118
|
-
// console.log(`balances: ${JSON.stringify(balances, null, 2)}`)
|
|
119
|
-
|
|
120
|
-
assert.isArray(balances)
|
|
121
|
-
assert.hasAllKeys(balances[0], [
|
|
122
|
-
'tokenId',
|
|
123
|
-
'balanceString',
|
|
124
|
-
'balance',
|
|
125
|
-
'decimalCount',
|
|
126
|
-
'slpAddress'
|
|
127
|
-
])
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
it('should fetch balances for multiple addresses.', async () => {
|
|
131
|
-
const addresses = [
|
|
132
|
-
'simpleledger:qzv3zz2trz0xgp6a96lu4m6vp2nkwag0kvyucjzqt9',
|
|
133
|
-
'simpleledger:qqss4zp80hn6szsa4jg2s9fupe7g5tcg5ucdyl3r57'
|
|
134
|
-
]
|
|
135
|
-
|
|
136
|
-
// Mock the call to the REST API
|
|
137
|
-
if (process.env.TEST === 'unit') {
|
|
138
|
-
sandbox
|
|
139
|
-
.stub(uut.Utils.axios, 'post')
|
|
140
|
-
.resolves({ data: mockData.balancesForAddresses })
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const balances = await uut.Utils.balancesForAddress(addresses)
|
|
144
|
-
// console.log(`balances: ${JSON.stringify(balances, null, 2)}`)
|
|
145
|
-
|
|
146
|
-
assert.isArray(balances)
|
|
147
|
-
assert.isArray(balances[0])
|
|
148
|
-
assert.hasAllKeys(balances[0][0], [
|
|
149
|
-
'tokenId',
|
|
150
|
-
'balanceString',
|
|
151
|
-
'balance',
|
|
152
|
-
'decimalCount',
|
|
153
|
-
'slpAddress'
|
|
154
|
-
])
|
|
155
|
-
})
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
describe('#validateTxid', () => {
|
|
159
|
-
it('should validate slp txid', async () => {
|
|
160
|
-
// Mock the call to the REST API
|
|
161
|
-
sandbox
|
|
162
|
-
.stub(uut.Utils.axios, 'post')
|
|
163
|
-
.resolves({ data: mockData.mockIsValidTxid })
|
|
164
|
-
|
|
165
|
-
const isValid = await uut.Utils.validateTxid(
|
|
166
|
-
'df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb'
|
|
167
|
-
)
|
|
168
|
-
assert.deepEqual(isValid, [
|
|
169
|
-
{
|
|
170
|
-
txid:
|
|
171
|
-
'df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb',
|
|
172
|
-
valid: true
|
|
173
|
-
}
|
|
174
|
-
])
|
|
175
|
-
})
|
|
176
|
-
})
|
|
177
|
-
|
|
178
|
-
describe('#balancesForToken', () => {
|
|
179
|
-
it('should retrieve token balances for a given tokenId', async () => {
|
|
180
|
-
// Mock the call to the REST API
|
|
181
|
-
sandbox
|
|
182
|
-
.stub(uut.Utils.axios, 'get')
|
|
183
|
-
.resolves({ data: mockData.mockBalancesForToken })
|
|
184
|
-
|
|
185
|
-
const balances = await uut.Utils.balancesForToken(
|
|
186
|
-
'df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb'
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
assert.hasAnyKeys(balances[0], ['tokenBalance', 'slpAddress'])
|
|
190
|
-
})
|
|
191
|
-
})
|
|
192
|
-
|
|
193
|
-
describe('#tokenStats', () => {
|
|
194
|
-
it('should retrieve stats for a given tokenId', async () => {
|
|
195
|
-
// Mock the call to the REST API
|
|
196
|
-
sandbox
|
|
197
|
-
.stub(uut.Utils.axios, 'get')
|
|
198
|
-
.resolves({ data: mockData.mockTokenStats })
|
|
199
|
-
|
|
200
|
-
const tokenStats = await uut.Utils.tokenStats(
|
|
201
|
-
'df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb'
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
assert.hasAnyKeys(tokenStats, [
|
|
205
|
-
'circulatingSupply',
|
|
206
|
-
'decimals',
|
|
207
|
-
'documentUri',
|
|
208
|
-
'name',
|
|
209
|
-
'satoshisLockedUp',
|
|
210
|
-
'symbol',
|
|
211
|
-
'tokenId',
|
|
212
|
-
'totalBurned',
|
|
213
|
-
'totalMinted',
|
|
214
|
-
'txnsSinceGenesis',
|
|
215
|
-
'validAddresses',
|
|
216
|
-
'validUtxos'
|
|
217
|
-
])
|
|
218
|
-
})
|
|
219
|
-
})
|
|
220
|
-
|
|
221
|
-
describe('#transactions', () => {
|
|
222
|
-
it('should retrieve transactions for a given tokenId and address', async () => {
|
|
223
|
-
// Mock the call to the REST API
|
|
224
|
-
sandbox
|
|
225
|
-
.stub(uut.Utils.axios, 'get')
|
|
226
|
-
.resolves({ data: mockData.mockTransactions })
|
|
227
|
-
|
|
228
|
-
const transactions = await uut.Utils.transactions(
|
|
229
|
-
'495322b37d6b2eae81f045eda612b95870a0c2b6069c58f70cf8ef4e6a9fd43a',
|
|
230
|
-
'simpleledger:qrhvcy5xlegs858fjqf8ssl6a4f7wpstaqnt0wauwu'
|
|
231
|
-
)
|
|
232
|
-
|
|
233
|
-
assert.hasAnyKeys(transactions[0], ['txid', 'tokenDetails'])
|
|
234
|
-
})
|
|
235
|
-
})
|
|
236
|
-
|
|
237
|
-
describe('#burnTotal', () => {
|
|
238
|
-
it('should retrieve input, output and burn totals', async () => {
|
|
239
|
-
// Mock the call to the REST API
|
|
240
|
-
sandbox
|
|
241
|
-
.stub(uut.Utils.axios, 'get')
|
|
242
|
-
.resolves({ data: mockData.mockBurnTotal })
|
|
243
|
-
|
|
244
|
-
const burnTotal = await uut.Utils.burnTotal(
|
|
245
|
-
'c7078a6c7400518a513a0bde1f4158cf740d08d3b5bfb19aa7b6657e2f4160de'
|
|
246
|
-
)
|
|
247
|
-
// console.log(`burnTotal: ${JSON.stringify(burnTotal, null, 2)}`)
|
|
248
|
-
|
|
249
|
-
assert.hasAnyKeys(burnTotal, [
|
|
250
|
-
'transactionId',
|
|
251
|
-
'inputTotal',
|
|
252
|
-
'outputTotal',
|
|
253
|
-
'burnTotal'
|
|
254
|
-
])
|
|
255
|
-
})
|
|
256
|
-
})
|
|
257
|
-
|
|
258
48
|
describe('#decodeOpReturn', () => {
|
|
259
49
|
it('should throw an error for a non-string input', async () => {
|
|
260
50
|
try {
|
|
@@ -1910,518 +1700,4 @@ describe('#SLP Utils', () => {
|
|
|
1910
1700
|
assert.equal(data[0].isValid, false)
|
|
1911
1701
|
})
|
|
1912
1702
|
})
|
|
1913
|
-
|
|
1914
|
-
describe('#tokenUtxoDetailsWL', () => {
|
|
1915
|
-
it('should return details for a simple SEND SLP token utxo', async () => {
|
|
1916
|
-
// Mock the call to REST API
|
|
1917
|
-
// Stub the calls to decodeOpReturn.
|
|
1918
|
-
sandbox
|
|
1919
|
-
.stub(uut.Utils, 'decodeOpReturn')
|
|
1920
|
-
.onCall(0)
|
|
1921
|
-
.resolves({
|
|
1922
|
-
tokenType: 1,
|
|
1923
|
-
txType: 'SEND',
|
|
1924
|
-
tokenId:
|
|
1925
|
-
'497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7',
|
|
1926
|
-
amounts: ['200000000', '99887500000000']
|
|
1927
|
-
})
|
|
1928
|
-
.onCall(1)
|
|
1929
|
-
.resolves({
|
|
1930
|
-
tokenType: 1,
|
|
1931
|
-
txType: 'GENESIS',
|
|
1932
|
-
ticker: 'TOK-CH',
|
|
1933
|
-
name: 'TokyoCash',
|
|
1934
|
-
tokenId:
|
|
1935
|
-
'497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7',
|
|
1936
|
-
documentUri: '',
|
|
1937
|
-
documentHash: '',
|
|
1938
|
-
decimals: 8,
|
|
1939
|
-
mintBatonVout: 0,
|
|
1940
|
-
qty: '2100000000000000'
|
|
1941
|
-
})
|
|
1942
|
-
|
|
1943
|
-
// Stub the call to validateTxid
|
|
1944
|
-
sandbox.stub(uut.Utils, 'validateTxid3').resolves([
|
|
1945
|
-
{
|
|
1946
|
-
txid:
|
|
1947
|
-
'fde117b1f176b231e2fa9a6cb022e0f7c31c288221df6bcb05f8b7d040ca87cb',
|
|
1948
|
-
valid: true
|
|
1949
|
-
}
|
|
1950
|
-
])
|
|
1951
|
-
|
|
1952
|
-
const utxos = [
|
|
1953
|
-
{
|
|
1954
|
-
txid:
|
|
1955
|
-
'fde117b1f176b231e2fa9a6cb022e0f7c31c288221df6bcb05f8b7d040ca87cb',
|
|
1956
|
-
vout: 1,
|
|
1957
|
-
amount: 0.00000546,
|
|
1958
|
-
satoshis: 546,
|
|
1959
|
-
height: 596089,
|
|
1960
|
-
confirmations: 748
|
|
1961
|
-
}
|
|
1962
|
-
]
|
|
1963
|
-
|
|
1964
|
-
const data = await uut.Utils.tokenUtxoDetailsWL(utxos)
|
|
1965
|
-
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
|
|
1966
|
-
|
|
1967
|
-
assert.property(data[0], 'txid')
|
|
1968
|
-
assert.property(data[0], 'vout')
|
|
1969
|
-
assert.property(data[0], 'height')
|
|
1970
|
-
assert.property(data[0], 'utxoType')
|
|
1971
|
-
assert.property(data[0], 'tokenId')
|
|
1972
|
-
assert.property(data[0], 'tokenTicker')
|
|
1973
|
-
assert.property(data[0], 'tokenName')
|
|
1974
|
-
assert.property(data[0], 'tokenDocumentUrl')
|
|
1975
|
-
assert.property(data[0], 'tokenDocumentHash')
|
|
1976
|
-
assert.property(data[0], 'decimals')
|
|
1977
|
-
assert.property(data[0], 'tokenQty')
|
|
1978
|
-
assert.property(data[0], 'isValid')
|
|
1979
|
-
assert.equal(data[0].isValid, true)
|
|
1980
|
-
})
|
|
1981
|
-
})
|
|
1982
|
-
|
|
1983
|
-
describe('#txDetails', () => {
|
|
1984
|
-
it('should throw an error if txid is not included', async () => {
|
|
1985
|
-
try {
|
|
1986
|
-
await uut.Utils.txDetails()
|
|
1987
|
-
} catch (err) {
|
|
1988
|
-
assert.include(
|
|
1989
|
-
err.message,
|
|
1990
|
-
'txid string must be included',
|
|
1991
|
-
'Expected error message.'
|
|
1992
|
-
)
|
|
1993
|
-
}
|
|
1994
|
-
})
|
|
1995
|
-
|
|
1996
|
-
it('should throw error for non-existent txid', async () => {
|
|
1997
|
-
try {
|
|
1998
|
-
// Mock the call to the REST API
|
|
1999
|
-
if (process.env.TEST === 'unit') {
|
|
2000
|
-
sandbox
|
|
2001
|
-
.stub(uut.Utils.axios, 'get')
|
|
2002
|
-
// .resolves({ data: mockData.nonSLPTxDetailsWithoutOpReturn })
|
|
2003
|
-
.throws({ error: 'TXID not found' })
|
|
2004
|
-
}
|
|
2005
|
-
|
|
2006
|
-
const txid =
|
|
2007
|
-
'd284e71227ec89f714b964d8eda595be6392bebd2fac46082bc5a9ce6fb7b33e'
|
|
2008
|
-
|
|
2009
|
-
await uut.Utils.txDetails(txid)
|
|
2010
|
-
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
|
2011
|
-
|
|
2012
|
-
assert.fail('Unexpected result')
|
|
2013
|
-
} catch (err) {
|
|
2014
|
-
// console.log(`err: `, err)
|
|
2015
|
-
assert.include(err.error, 'TXID not found', 'Expected error message.')
|
|
2016
|
-
}
|
|
2017
|
-
})
|
|
2018
|
-
|
|
2019
|
-
it('should return details for an SLP txid', async () => {
|
|
2020
|
-
// Mock the call to the REST API
|
|
2021
|
-
if (process.env.TEST === 'unit') {
|
|
2022
|
-
sandbox
|
|
2023
|
-
.stub(uut.Utils.axios, 'get')
|
|
2024
|
-
.resolves({ data: mockData.mockTxDetails })
|
|
2025
|
-
}
|
|
2026
|
-
|
|
2027
|
-
const txid =
|
|
2028
|
-
'9dbaaafc48c49a21beabada8de632009288a2cd52eecefd0c00edcffca9955d0'
|
|
2029
|
-
|
|
2030
|
-
const result = await uut.Utils.txDetails(txid)
|
|
2031
|
-
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
|
2032
|
-
|
|
2033
|
-
assert.hasAnyKeys(result, [
|
|
2034
|
-
'txid',
|
|
2035
|
-
'version',
|
|
2036
|
-
'locktime',
|
|
2037
|
-
'vin',
|
|
2038
|
-
'vout',
|
|
2039
|
-
'blockhash',
|
|
2040
|
-
'blockheight',
|
|
2041
|
-
'confirmations',
|
|
2042
|
-
'time',
|
|
2043
|
-
'blocktime',
|
|
2044
|
-
'valueOut',
|
|
2045
|
-
'size',
|
|
2046
|
-
'valueIn',
|
|
2047
|
-
'fees',
|
|
2048
|
-
'tokenInfo',
|
|
2049
|
-
'tokenIsValid'
|
|
2050
|
-
])
|
|
2051
|
-
})
|
|
2052
|
-
})
|
|
2053
|
-
|
|
2054
|
-
describe('#hydrateUtxos', () => {
|
|
2055
|
-
it('should throw an error if input is not an array', async () => {
|
|
2056
|
-
try {
|
|
2057
|
-
const utxos = 1234
|
|
2058
|
-
|
|
2059
|
-
await uut.Utils.hydrateUtxos(utxos)
|
|
2060
|
-
|
|
2061
|
-
assert.equal(true, false, 'Uh oh. Code path should not end here.')
|
|
2062
|
-
} catch (err) {
|
|
2063
|
-
// console.log(`Error: `, err)
|
|
2064
|
-
assert.include(err.message, 'Input must be an array.')
|
|
2065
|
-
}
|
|
2066
|
-
})
|
|
2067
|
-
})
|
|
2068
|
-
|
|
2069
|
-
describe('#hydrateUtxosWL', () => {
|
|
2070
|
-
it('should throw an error if input is not an array', async () => {
|
|
2071
|
-
try {
|
|
2072
|
-
const utxos = 1234
|
|
2073
|
-
|
|
2074
|
-
await uut.Utils.hydrateUtxosWL(utxos)
|
|
2075
|
-
|
|
2076
|
-
assert.equal(true, false, 'Uh oh. Code path should not end here.')
|
|
2077
|
-
} catch (err) {
|
|
2078
|
-
// console.log(`Error: `, err)
|
|
2079
|
-
assert.include(err.message, 'Input must be an array.')
|
|
2080
|
-
}
|
|
2081
|
-
})
|
|
2082
|
-
})
|
|
2083
|
-
|
|
2084
|
-
describe('#validateTxid2', () => {
|
|
2085
|
-
it('should throw an error if the input is an array', async () => {
|
|
2086
|
-
try {
|
|
2087
|
-
const txid = [
|
|
2088
|
-
'f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a'
|
|
2089
|
-
]
|
|
2090
|
-
|
|
2091
|
-
await uut.Utils.validateTxid2(txid)
|
|
2092
|
-
|
|
2093
|
-
assert.equal(true, false, 'Unexpected result')
|
|
2094
|
-
} catch (err) {
|
|
2095
|
-
// console.log("err: ", err)
|
|
2096
|
-
assert.include(err.message, 'txid must be 64 character string')
|
|
2097
|
-
}
|
|
2098
|
-
})
|
|
2099
|
-
|
|
2100
|
-
it('should throw an error for a malformed txid', async () => {
|
|
2101
|
-
try {
|
|
2102
|
-
const txid =
|
|
2103
|
-
'f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783'
|
|
2104
|
-
|
|
2105
|
-
await uut.Utils.validateTxid2(txid)
|
|
2106
|
-
|
|
2107
|
-
assert.equal(true, false, 'Unexpected result')
|
|
2108
|
-
} catch (err) {
|
|
2109
|
-
// console.log("err: ", err)
|
|
2110
|
-
assert.include(err.message, 'txid must be 64 character string')
|
|
2111
|
-
}
|
|
2112
|
-
})
|
|
2113
|
-
|
|
2114
|
-
it('should invalidate a known invalid TXID', async () => {
|
|
2115
|
-
const txid =
|
|
2116
|
-
'f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a'
|
|
2117
|
-
|
|
2118
|
-
// Mock live network calls.
|
|
2119
|
-
sandbox.stub(uut.Utils.axios, 'get').resolves({
|
|
2120
|
-
data: {
|
|
2121
|
-
txid: txid,
|
|
2122
|
-
isValid: false,
|
|
2123
|
-
msg: ''
|
|
2124
|
-
}
|
|
2125
|
-
})
|
|
2126
|
-
|
|
2127
|
-
const result = await uut.Utils.validateTxid2(txid)
|
|
2128
|
-
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
|
2129
|
-
|
|
2130
|
-
assert.property(result, 'txid')
|
|
2131
|
-
assert.equal(result.txid, txid)
|
|
2132
|
-
|
|
2133
|
-
assert.property(result, 'isValid')
|
|
2134
|
-
assert.equal(result.isValid, false)
|
|
2135
|
-
})
|
|
2136
|
-
|
|
2137
|
-
it('should validate a known valid TXID', async () => {
|
|
2138
|
-
const txid =
|
|
2139
|
-
'3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488'
|
|
2140
|
-
|
|
2141
|
-
// Mock live network calls.
|
|
2142
|
-
sandbox.stub(uut.Utils.axios, 'get').resolves({
|
|
2143
|
-
data: {
|
|
2144
|
-
txid: txid,
|
|
2145
|
-
isValid: true,
|
|
2146
|
-
msg: ''
|
|
2147
|
-
}
|
|
2148
|
-
})
|
|
2149
|
-
|
|
2150
|
-
const result = await uut.Utils.validateTxid2(txid)
|
|
2151
|
-
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
|
2152
|
-
|
|
2153
|
-
assert.property(result, 'txid')
|
|
2154
|
-
assert.equal(result.txid, txid)
|
|
2155
|
-
|
|
2156
|
-
assert.property(result, 'isValid')
|
|
2157
|
-
assert.equal(result.isValid, true)
|
|
2158
|
-
})
|
|
2159
|
-
|
|
2160
|
-
// slp-validate can take a long time. bch-api cuts it off if it fails to
|
|
2161
|
-
// return is less than 10 seconds. This test case handle this situation.
|
|
2162
|
-
it('should handle timeout errors', async () => {
|
|
2163
|
-
try {
|
|
2164
|
-
const txid =
|
|
2165
|
-
'eacb1085dfa296fef6d4ae2c0f4529a1bef096dd2325bdcc6dcb5241b3bdb579'
|
|
2166
|
-
|
|
2167
|
-
// Mock live network calls.
|
|
2168
|
-
sandbox.stub(uut.Utils.axios, 'get').rejects({
|
|
2169
|
-
error:
|
|
2170
|
-
'Network error: Could not communicate with full node or other external service.'
|
|
2171
|
-
})
|
|
2172
|
-
|
|
2173
|
-
await uut.Utils.validateTxid2(txid)
|
|
2174
|
-
|
|
2175
|
-
assert.equal(true, false, 'Unexpected result')
|
|
2176
|
-
} catch (err) {
|
|
2177
|
-
// console.log("err: ", err)
|
|
2178
|
-
assert.include(err.message, 'slp-validate timed out')
|
|
2179
|
-
}
|
|
2180
|
-
})
|
|
2181
|
-
})
|
|
2182
|
-
|
|
2183
|
-
describe('#validateTxid', () => {
|
|
2184
|
-
it('should invalidate a known invalid TXID', async () => {
|
|
2185
|
-
const txid =
|
|
2186
|
-
'f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a'
|
|
2187
|
-
|
|
2188
|
-
// Mock live network calls.
|
|
2189
|
-
sandbox.stub(uut.Utils.axios, 'post').resolves({
|
|
2190
|
-
data: mockData.mockValidateTxid3Invalid
|
|
2191
|
-
})
|
|
2192
|
-
|
|
2193
|
-
const result = await uut.Utils.validateTxid(txid)
|
|
2194
|
-
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
|
2195
|
-
|
|
2196
|
-
assert.isArray(result)
|
|
2197
|
-
|
|
2198
|
-
assert.property(result[0], 'txid')
|
|
2199
|
-
assert.equal(result[0].txid, txid)
|
|
2200
|
-
|
|
2201
|
-
assert.property(result[0], 'valid')
|
|
2202
|
-
assert.equal(result[0].valid, null)
|
|
2203
|
-
})
|
|
2204
|
-
/*
|
|
2205
|
-
it("should handle a mix of valid, invalid, and non-SLP txs", async () => {
|
|
2206
|
-
const txids = [
|
|
2207
|
-
// Malformed SLP tx
|
|
2208
|
-
"f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a",
|
|
2209
|
-
// Normal TX (non-SLP)
|
|
2210
|
-
"01cdaec2f8b311fc2d6ecc930247bd45fa696dc204ab684596e281fe1b06c1f0",
|
|
2211
|
-
// Valid PSF SLP tx
|
|
2212
|
-
"daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd",
|
|
2213
|
-
// Valid SLP token not in whitelist
|
|
2214
|
-
"3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488"
|
|
2215
|
-
]
|
|
2216
|
-
|
|
2217
|
-
const result = await uut.Utils.validateTxid(txids)
|
|
2218
|
-
console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
|
2219
|
-
})
|
|
2220
|
-
*/
|
|
2221
|
-
})
|
|
2222
|
-
|
|
2223
|
-
describe('#waterfallValidateTxid', () => {
|
|
2224
|
-
// This test ensures that the whitelist SLPDB is called before the
|
|
2225
|
-
// general purpose SLPDB.
|
|
2226
|
-
it('should call validateTxid3() first', async () => {
|
|
2227
|
-
const txid = 'fakeTxid'
|
|
2228
|
-
|
|
2229
|
-
const retVal = [{ txid, valid: true }]
|
|
2230
|
-
|
|
2231
|
-
// Use stubs to force the desired code path.
|
|
2232
|
-
sandbox.stub(uut.Utils, 'validateTxid3').resolves(retVal)
|
|
2233
|
-
sandbox
|
|
2234
|
-
.stub(uut.Utils, 'validateTxid')
|
|
2235
|
-
.rejects(new Error('Unexpected code path'))
|
|
2236
|
-
sandbox
|
|
2237
|
-
.stub(uut.Utils, 'validateTxid2')
|
|
2238
|
-
.rejects(new Error('Unexpected code path'))
|
|
2239
|
-
|
|
2240
|
-
const result = await uut.Utils.waterfallValidateTxid(txid)
|
|
2241
|
-
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
|
2242
|
-
|
|
2243
|
-
assert.equal(result, true)
|
|
2244
|
-
})
|
|
2245
|
-
|
|
2246
|
-
// This test ensures that the general purpose SLPDB is called after the
|
|
2247
|
-
// whitelist SLPDB, but before slp-api.
|
|
2248
|
-
it('should call validateTxid() second', async () => {
|
|
2249
|
-
const txid = 'fakeTxid'
|
|
2250
|
-
|
|
2251
|
-
const retVal1 = [{ txid, valid: null }]
|
|
2252
|
-
const retVal2 = [{ txid, valid: true }]
|
|
2253
|
-
|
|
2254
|
-
// Use stubs to force the desired code path.
|
|
2255
|
-
sandbox.stub(uut.Utils, 'validateTxid3').resolves(retVal1)
|
|
2256
|
-
sandbox.stub(uut.Utils, 'validateTxid').resolves(retVal2)
|
|
2257
|
-
sandbox
|
|
2258
|
-
.stub(uut.Utils, 'validateTxid2')
|
|
2259
|
-
.rejects(new Error('Unexpected code path'))
|
|
2260
|
-
|
|
2261
|
-
const result = await uut.Utils.waterfallValidateTxid(txid)
|
|
2262
|
-
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
|
2263
|
-
|
|
2264
|
-
assert.equal(result, true)
|
|
2265
|
-
})
|
|
2266
|
-
|
|
2267
|
-
// This test ensures that slp-api is called if both SLPDBs return null.
|
|
2268
|
-
it('should call slp-api last', async () => {
|
|
2269
|
-
const txid = 'fakeTxid'
|
|
2270
|
-
|
|
2271
|
-
const retVal1 = [{ txid, valid: null }]
|
|
2272
|
-
|
|
2273
|
-
// Use stubs to force the desired code path.
|
|
2274
|
-
sandbox.stub(uut.Utils, 'validateTxid3').resolves(retVal1)
|
|
2275
|
-
sandbox.stub(uut.Utils, 'validateTxid').resolves(retVal1)
|
|
2276
|
-
sandbox.stub(uut.Utils, 'validateTxid2').resolves({ isValid: true })
|
|
2277
|
-
|
|
2278
|
-
const result = await uut.Utils.waterfallValidateTxid(txid)
|
|
2279
|
-
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
|
2280
|
-
|
|
2281
|
-
assert.equal(result, true)
|
|
2282
|
-
})
|
|
2283
|
-
|
|
2284
|
-
// CT 08-09-21 Changed behavior. validateTxid3() is now wrapped in a
|
|
2285
|
-
// try/catch statement that exits quietly if there is an error.
|
|
2286
|
-
// it('catches and throws an error', async () => {
|
|
2287
|
-
// try {
|
|
2288
|
-
// const txid = 'fakeTxid'
|
|
2289
|
-
//
|
|
2290
|
-
// // Force an error
|
|
2291
|
-
// sandbox
|
|
2292
|
-
// .stub(uut.Utils, 'validateTxid3')
|
|
2293
|
-
// .rejects(new Error('fake error'))
|
|
2294
|
-
//
|
|
2295
|
-
// await await uut.Utils.waterfallValidateTxid(txid)
|
|
2296
|
-
//
|
|
2297
|
-
// assert.fail('Unexpected result')
|
|
2298
|
-
// } catch (err) {
|
|
2299
|
-
// // console.log(`err.message: ${err.message}`)
|
|
2300
|
-
// assert.include(err.message, 'fake error')
|
|
2301
|
-
// }
|
|
2302
|
-
// })
|
|
2303
|
-
})
|
|
2304
|
-
|
|
2305
|
-
describe('#getWhitelist', () => {
|
|
2306
|
-
it('should return the list', async () => {
|
|
2307
|
-
sandbox
|
|
2308
|
-
.stub(uut.Utils.axios, 'get')
|
|
2309
|
-
.resolves({ data: mockData.mockWhitelist })
|
|
2310
|
-
|
|
2311
|
-
const result = await uut.Utils.getWhitelist()
|
|
2312
|
-
|
|
2313
|
-
assert.isArray(result)
|
|
2314
|
-
assert.property(result[0], 'name')
|
|
2315
|
-
assert.property(result[1], 'tokenId')
|
|
2316
|
-
})
|
|
2317
|
-
|
|
2318
|
-
it('catches and throws an error', async () => {
|
|
2319
|
-
try {
|
|
2320
|
-
sandbox.stub(uut.Utils.axios, 'get').rejects({
|
|
2321
|
-
error:
|
|
2322
|
-
'Network error: Could not communicate with full node or other external service.'
|
|
2323
|
-
})
|
|
2324
|
-
|
|
2325
|
-
await uut.Utils.getWhitelist()
|
|
2326
|
-
|
|
2327
|
-
assert.fail('Unexpected result')
|
|
2328
|
-
} catch (err) {
|
|
2329
|
-
console.log('err: ', err)
|
|
2330
|
-
assert.include(err.error, 'Network error')
|
|
2331
|
-
}
|
|
2332
|
-
})
|
|
2333
|
-
})
|
|
2334
|
-
|
|
2335
|
-
describe('#validateTxid3', () => {
|
|
2336
|
-
it('should invalidate a known invalid TXID', async () => {
|
|
2337
|
-
const txid =
|
|
2338
|
-
'f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a'
|
|
2339
|
-
|
|
2340
|
-
// Mock live network calls.
|
|
2341
|
-
sandbox.stub(uut.Utils.axios, 'post').resolves({
|
|
2342
|
-
data: mockData.mockValidateTxid3Invalid
|
|
2343
|
-
})
|
|
2344
|
-
|
|
2345
|
-
const result = await uut.Utils.validateTxid3(txid)
|
|
2346
|
-
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
|
2347
|
-
|
|
2348
|
-
assert.isArray(result)
|
|
2349
|
-
|
|
2350
|
-
assert.property(result[0], 'txid')
|
|
2351
|
-
assert.equal(result[0].txid, txid)
|
|
2352
|
-
|
|
2353
|
-
assert.property(result[0], 'valid')
|
|
2354
|
-
assert.equal(result[0].valid, null)
|
|
2355
|
-
})
|
|
2356
|
-
|
|
2357
|
-
it('should handle an array with a single element', async () => {
|
|
2358
|
-
sandbox
|
|
2359
|
-
.stub(uut.Utils.axios, 'post')
|
|
2360
|
-
.resolves({ data: mockData.mockValidateTxid3Valid })
|
|
2361
|
-
|
|
2362
|
-
const txid = [
|
|
2363
|
-
'daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd'
|
|
2364
|
-
]
|
|
2365
|
-
|
|
2366
|
-
const result = await uut.Utils.validateTxid3(txid)
|
|
2367
|
-
|
|
2368
|
-
assert.isArray(result)
|
|
2369
|
-
|
|
2370
|
-
assert.property(result[0], 'txid')
|
|
2371
|
-
assert.equal(result[0].txid, txid)
|
|
2372
|
-
|
|
2373
|
-
assert.property(result[0], 'valid')
|
|
2374
|
-
assert.equal(result[0].valid, true)
|
|
2375
|
-
})
|
|
2376
|
-
|
|
2377
|
-
it('should handle an single string input', async () => {
|
|
2378
|
-
sandbox
|
|
2379
|
-
.stub(uut.Utils.axios, 'post')
|
|
2380
|
-
.resolves({ data: mockData.mockValidateTxid3Valid })
|
|
2381
|
-
|
|
2382
|
-
const txid =
|
|
2383
|
-
'daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd'
|
|
2384
|
-
|
|
2385
|
-
const result = await uut.Utils.validateTxid3(txid)
|
|
2386
|
-
|
|
2387
|
-
assert.isArray(result)
|
|
2388
|
-
|
|
2389
|
-
assert.property(result[0], 'txid')
|
|
2390
|
-
assert.equal(result[0].txid, txid)
|
|
2391
|
-
|
|
2392
|
-
assert.property(result[0], 'valid')
|
|
2393
|
-
assert.equal(result[0].valid, true)
|
|
2394
|
-
})
|
|
2395
|
-
|
|
2396
|
-
it('catches and throws an error', async () => {
|
|
2397
|
-
try {
|
|
2398
|
-
sandbox.stub(uut.Utils.axios, 'post').rejects({
|
|
2399
|
-
error:
|
|
2400
|
-
'Network error: Could not communicate with full node or other external service.'
|
|
2401
|
-
})
|
|
2402
|
-
|
|
2403
|
-
await uut.Utils.validateTxid3()
|
|
2404
|
-
|
|
2405
|
-
assert.equal(true, false, 'Unexpected result')
|
|
2406
|
-
} catch (err) {
|
|
2407
|
-
// console.log("err: ", err)
|
|
2408
|
-
assert.include(err.error, 'Network error')
|
|
2409
|
-
}
|
|
2410
|
-
})
|
|
2411
|
-
})
|
|
2412
|
-
|
|
2413
|
-
describe('#getStatus', () => {
|
|
2414
|
-
it('should return the current block height of the SLPDB indexer', async () => {
|
|
2415
|
-
sandbox
|
|
2416
|
-
.stub(uut.Utils.axios, 'get')
|
|
2417
|
-
.resolves({ data: mockData.slpdbStatus })
|
|
2418
|
-
|
|
2419
|
-
const result = await uut.Utils.getStatus()
|
|
2420
|
-
|
|
2421
|
-
// console.log(`result: `, result)
|
|
2422
|
-
|
|
2423
|
-
assert.property(result, 'bchBlockHeight')
|
|
2424
|
-
assert.property(result, 'slpProcessedBlockHeight')
|
|
2425
|
-
})
|
|
2426
|
-
})
|
|
2427
1703
|
})
|