1 |
|
2 |
|
3 | jasmine.getEnv().defaultTimeoutInterval = 50000
|
4 |
|
5 | var openpublish = require('../src/index')
|
6 | var blockcast = require('blockcast')
|
7 | var bitcoin = require('bitcoinjs-lib')
|
8 | var File = require('file-api').File
|
9 | var fs = require('fs')
|
10 | var shasum = require('shasum')
|
11 |
|
12 | var txHexToJSON = require('bitcoin-tx-hex-to-json')
|
13 |
|
14 | var env = require('node-env-file')
|
15 | env('./.env', { raise: false })
|
16 |
|
17 | var BLOCKCYPHER_TOKEN = process.env.BLOCKCYPHER_TOKEN
|
18 |
|
19 | var commonBlockchain = require('blockcypher-unofficial')({
|
20 | key: BLOCKCYPHER_TOKEN,
|
21 | network: 'testnet'
|
22 | })
|
23 |
|
24 | var testCommonWallet = require('test-common-wallet')
|
25 |
|
26 | var aliceWallet = testCommonWallet({
|
27 | seed: 'test',
|
28 | network: 'testnet',
|
29 | commonBlockchain: commonBlockchain
|
30 | })
|
31 |
|
32 | var bobWallet = testCommonWallet({
|
33 | seed: 'test1',
|
34 | network: 'testnet',
|
35 | commonBlockchain: commonBlockchain
|
36 | })
|
37 |
|
38 | var inMemoryCommonBlockchain = require('mem-common-blockchain')()
|
39 |
|
40 | var inMemoryAliceWallet = testCommonWallet({
|
41 | seed: 'test',
|
42 | network: 'testnet',
|
43 | commonBlockchain: inMemoryCommonBlockchain
|
44 | })
|
45 |
|
46 | var createRandomString = function (length) {
|
47 | var characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'
|
48 | var output = ''
|
49 | for (var i = 0; i < length; i++) {
|
50 | var r = Math.floor(Math.random() * characters.length)
|
51 | output += characters.substring(r, r + 1)
|
52 | }
|
53 | return output
|
54 | }
|
55 |
|
56 | var createRandomFile = function (options, callback) {
|
57 | var fileName = options.fileName
|
58 | var string = options.string
|
59 | var path = './test/' + fileName
|
60 | fs.writeFile(path, string, function (err) {
|
61 | if (err) { }
|
62 | callback(path)
|
63 | })
|
64 | }
|
65 |
|
66 | var sha1 = 'dc724af18fbdd4e59189f5fe768a5f8311527050'
|
67 |
|
68 | describe('open-publish', function () {
|
69 | var fileBuffer = new Buffer('testing')
|
70 | var fileName = 'test.txt'
|
71 | var fileType = 'text/plain'
|
72 | var fileTitle = 'A text file for testing'
|
73 | var fileKeywords = 'test, text, txt'
|
74 | var fileBtih = '335400c43179bb1ad0085289e4e60c0574e6252e'
|
75 | var fileSha1 = 'dc724af18fbdd4e59189f5fe768a5f8311527050'
|
76 | var fileIpfs = 'QmcJf1w9bVpquGdzCp86pX4K21Zcn7bJBUtrBP1cr2NFuR'
|
77 |
|
78 | it('should get the number of transaction payloads', function (done) {
|
79 | var file = new File({
|
80 | name: fileName,
|
81 | type: fileType,
|
82 | buffer: fileBuffer
|
83 | })
|
84 | openpublish.getPayloadsLength({
|
85 | file: file,
|
86 | title: fileTitle,
|
87 | keywords: fileKeywords,
|
88 | commonWallet: aliceWallet,
|
89 | commonBlockchain: commonBlockchain
|
90 | }, function (err, payloadsLength) {
|
91 | if (err) { }
|
92 | expect(payloadsLength).toBe(3)
|
93 | done()
|
94 | })
|
95 | })
|
96 |
|
97 | it('Alice should publish a small text file', function (done) {
|
98 | var file = new File({
|
99 | name: fileName,
|
100 | type: fileType,
|
101 | buffer: fileBuffer
|
102 | })
|
103 | openpublish.register({
|
104 | file: file,
|
105 | title: fileTitle,
|
106 | keywords: fileKeywords,
|
107 | commonWallet: aliceWallet,
|
108 | commonBlockchain: commonBlockchain
|
109 | }, function (err, receipt) {
|
110 | if (err) { }
|
111 | console.log(receipt)
|
112 | var data = receipt.data
|
113 | expect(data.op).toBe('r')
|
114 | expect(data.btih).toBe(fileBtih)
|
115 | expect(data.sha1).toBe(fileSha1)
|
116 | expect(data.ipfs).toBe(fileIpfs)
|
117 | expect(data.name).toBe(fileName)
|
118 | expect(data.size).toBe(fileBuffer.length)
|
119 | expect(data.type).toBe(fileType)
|
120 | expect(data.title).toBe(fileTitle)
|
121 | expect(data.uri).not.toBeDefined()
|
122 | expect(data.keywords).toBe(fileKeywords)
|
123 | var blockcastTx = receipt.blockcastTx
|
124 | expect(blockcastTx.txid).toBeDefined()
|
125 | expect(blockcastTx.transactionTotal).toBe(3)
|
126 | done()
|
127 | })
|
128 | })
|
129 |
|
130 | it('Alice should register then transfer some ownership to Bob', function (done) {
|
131 | var randomBufferSize = 48
|
132 | var randomFileName = 'randomFile.txt'
|
133 | var randomString = createRandomString(randomBufferSize)
|
134 | var assetValue = 50000000
|
135 | var bitcoinValue = 12345
|
136 | var bobWalletSignPrimaryTxHex = function (txHex, callback) {
|
137 | var tx = txHexToJSON(txHex)
|
138 | expect(tx.vin.length).toBe(2)
|
139 | expect(tx.vout.length).toBe(4)
|
140 | expect(tx.vout[0].value).toBe(bitcoinValue)
|
141 | expect(tx.vout[2].value).toBe(0)
|
142 | expect(tx.vout[0].scriptPubKey.type).toBe('pubkeyhash')
|
143 | expect(tx.vout[1].scriptPubKey.type).toBe('pubkeyhash')
|
144 | expect(tx.vout[2].scriptPubKey.type).toBe('nulldata')
|
145 | expect(tx.vout[3].scriptPubKey.type).toBe('pubkeyhash')
|
146 | bobWallet.signRawTransaction({txHex: txHex, input: 0}, callback)
|
147 | }
|
148 | createRandomFile({string: randomString, fileName: randomFileName}, function (path) {
|
149 | var randomFile = new File(path)
|
150 | randomFile.size = randomBufferSize
|
151 | var ttl = 365
|
152 | openpublish.register({
|
153 | file: randomFile,
|
154 | commonWallet: aliceWallet,
|
155 | commonBlockchain: commonBlockchain
|
156 | }, function (err, receipt) {
|
157 | if (err) { }
|
158 | console.log(receipt)
|
159 | var registerData = receipt.data
|
160 | var sha1 = registerData.sha1
|
161 | openpublish.transfer({
|
162 | assetValue: assetValue,
|
163 | bitcoinValue: bitcoinValue,
|
164 | ttl: ttl,
|
165 | sha1: sha1,
|
166 | assetWallet: aliceWallet,
|
167 | bitcoinWallet: bobWallet,
|
168 | bitcoinWalletSignPrimaryTxHex: bobWalletSignPrimaryTxHex,
|
169 | commonBlockchain: commonBlockchain
|
170 | }, function (err, receipt) {
|
171 | if (err) { }
|
172 | console.log(receipt)
|
173 | var transferData = receipt.data
|
174 | expect(transferData.op).toBe('t')
|
175 | expect(transferData.sha1).toBe(sha1)
|
176 | expect(transferData.value).toBe(assetValue)
|
177 | expect(transferData.ttl).toBe(ttl)
|
178 | expect(receipt.blockcastTx.txid).toBeDefined()
|
179 | done()
|
180 | })
|
181 | })
|
182 | })
|
183 | })
|
184 |
|
185 | it("Bob should propose a bid on one of Alice's assets", function (done) {
|
186 | var assetValue = 50000000
|
187 | var bitcoinValue = 12345
|
188 | var ttl = 365
|
189 | openpublish.createBid({
|
190 | assetValue: assetValue,
|
191 | bitcoinValue: bitcoinValue,
|
192 | ttl: ttl,
|
193 | sha1: sha1,
|
194 | assetAddress: aliceWallet.address,
|
195 | bitcoinWallet: bobWallet,
|
196 | commonBlockchain: commonBlockchain
|
197 | }, function (err, proposedBid) {
|
198 | if (err) { }
|
199 | expect(proposedBid.assetValue).toBe(assetValue)
|
200 | done()
|
201 | })
|
202 | })
|
203 |
|
204 | it("Bob should propose a bid on one of Alice's assets and she should accept, and then Bob should sign and post", function (done) {
|
205 | var assetValue = 50000000
|
206 | var bitcoinValue = 12345
|
207 | var ttl = 365
|
208 | openpublish.createBid({
|
209 | assetValue: assetValue,
|
210 | bitcoinValue: bitcoinValue,
|
211 | ttl: ttl,
|
212 | sha1: sha1,
|
213 | assetAddress: aliceWallet.address,
|
214 | bitcoinWallet: bobWallet,
|
215 | commonBlockchain: commonBlockchain
|
216 | }, function (err, proposedBid) {
|
217 | if (err) { }
|
218 |
|
219 | proposedBid.assetWallet = aliceWallet
|
220 | proposedBid.commonBlockchain = commonBlockchain
|
221 | openpublish.acceptBid(proposedBid, function (err, acceptedBid) {
|
222 |
|
223 | acceptedBid.bitcoinWallet = bobWallet
|
224 | acceptedBid.commonBlockchain = commonBlockchain
|
225 | openpublish.transferAcceptedBid(acceptedBid, function (err, receipt) {
|
226 | console.log(err, receipt)
|
227 | expect(receipt.transfer.assetValue).toBe(assetValue)
|
228 | expect(receipt.transfer.assetAddress).toBe(aliceWallet.address)
|
229 | expect(receipt.transfer.bitcoinValue).toBe(bitcoinValue)
|
230 | expect(receipt.transfer.bitcoinAddress).toBe(bobWallet.address)
|
231 | done()
|
232 | })
|
233 | })
|
234 | })
|
235 | })
|
236 |
|
237 | it('should find an open publish register transaction', function (done) {
|
238 | openpublish.scanSingle({
|
239 | txid: '1a1a36bed1de5a46ae1c85c2a4efe53201b7cd650911576aba331279275b0e25',
|
240 | commonBlockchain: commonBlockchain
|
241 | }, function (err, data) {
|
242 | if (err) { }
|
243 | expect(data.op).toBe('r')
|
244 | expect(data.addr).toBe('msLoJikUfxbc2U5UhRSjc2svusBSqMdqxZ')
|
245 | expect(data.btih).toBe(fileBtih)
|
246 | expect(data.sha1).toBe(fileSha1)
|
247 | expect(data.name).toBe(fileName)
|
248 | expect(data.size).toBe(fileBuffer.length)
|
249 | expect(data.type).toBe(fileType)
|
250 | expect(data.title).toBe(fileTitle)
|
251 | expect(data.uri).not.toBeDefined()
|
252 | expect(data.keywords).toBe(fileKeywords)
|
253 | done()
|
254 | })
|
255 | })
|
256 |
|
257 | it('should process an open publish register transaction', function (done) {
|
258 | blockcast.scanSingle({
|
259 | txid: '1a1a36bed1de5a46ae1c85c2a4efe53201b7cd650911576aba331279275b0e25',
|
260 | commonBlockchain: commonBlockchain
|
261 | }, function (err, rawData, addresses, primaryTx) {
|
262 | if (err) { }
|
263 | var data = openpublish.processRegistration(JSON.parse(rawData), primaryTx)
|
264 | expect(data.op).toBe('r')
|
265 | expect(data.addr).toBe('msLoJikUfxbc2U5UhRSjc2svusBSqMdqxZ')
|
266 | expect(data.btih).toBe(fileBtih)
|
267 | expect(data.sha1).toBe(fileSha1)
|
268 | expect(data.name).toBe(fileName)
|
269 | expect(data.size).toBe(fileBuffer.length)
|
270 | expect(data.type).toBe(fileType)
|
271 | expect(data.title).toBe(fileTitle)
|
272 | expect(data.uri).not.toBeDefined()
|
273 | expect(data.keywords).toBe(fileKeywords)
|
274 | done()
|
275 | })
|
276 | })
|
277 |
|
278 | it('should find an open publish transfer transaction', function (done) {
|
279 | var txid = '8f495d095ab55839675af686b98dc5b437ad3d8789546c9c5521feabbe104d70'
|
280 | openpublish.scanSingle({
|
281 | txid: txid,
|
282 | commonBlockchain: commonBlockchain
|
283 | }, function (err, data) {
|
284 | if (err) { }
|
285 | expect(data.assetValue).toBe(50000000)
|
286 | expect(data.assetAddress).toBe('msLoJikUfxbc2U5UhRSjc2svusBSqMdqxZ')
|
287 | expect(data.bitcoinValue).toBe(12345)
|
288 | expect(data.bitcoinAddress).toBe('mwaj74EideMcpe4cjieuPFpqacmpjtKSk1')
|
289 | expect(data.sha1).toBe('78d4fdf50ab5c2528b9a1b69baac7fe9819f0670')
|
290 | expect(data.ttl).toBe(365)
|
291 | done()
|
292 | })
|
293 | })
|
294 |
|
295 | it('should process an open publish transfer transaction', function (done) {
|
296 | var txid = '8f495d095ab55839675af686b98dc5b437ad3d8789546c9c5521feabbe104d70'
|
297 | blockcast.scanSingle({
|
298 | txid: txid,
|
299 | commonBlockchain: commonBlockchain
|
300 | }, function (err, rawData, addresses, primaryTx) {
|
301 | if (err) { }
|
302 | var data = openpublish.processTransfer(JSON.parse(rawData), primaryTx)
|
303 | expect(data.assetValue).toBe(50000000)
|
304 | expect(data.assetAddress).toBe('msLoJikUfxbc2U5UhRSjc2svusBSqMdqxZ')
|
305 | expect(data.bitcoinValue).toBe(12345)
|
306 | expect(data.bitcoinAddress).toBe('mwaj74EideMcpe4cjieuPFpqacmpjtKSk1')
|
307 | expect(data.sha1).toBe('78d4fdf50ab5c2528b9a1b69baac7fe9819f0670')
|
308 | expect(data.ttl).toBe(365)
|
309 | done()
|
310 | })
|
311 | })
|
312 |
|
313 | it('should publish and then find an open publish transaction (inMemoryCommonBlockchain)', function (done) {
|
314 | var file = new File({
|
315 | name: fileName,
|
316 | type: fileType,
|
317 | buffer: fileBuffer
|
318 | })
|
319 | openpublish.register({
|
320 | file: file,
|
321 | title: fileTitle,
|
322 | keywords: fileKeywords,
|
323 | name: fileName,
|
324 | sha1: fileSha1,
|
325 | btih: fileBtih,
|
326 | size: fileBuffer.legnth,
|
327 | type: fileType,
|
328 | commonWallet: inMemoryAliceWallet,
|
329 | commonBlockchain: inMemoryCommonBlockchain
|
330 | }, function (err, receipt) {
|
331 | if (err) { }
|
332 | var blockcastTx = receipt.blockcastTx
|
333 | var txid = blockcastTx.txid
|
334 | openpublish.scanSingle({
|
335 | txid: txid,
|
336 | commonBlockchain: inMemoryCommonBlockchain
|
337 | }, function (err, data) {
|
338 | if (err) { }
|
339 | expect(data.op).toBe('r')
|
340 | expect(data.addr).toBe('msLoJikUfxbc2U5UhRSjc2svusBSqMdqxZ')
|
341 | expect(data.btih).toBe(fileBtih)
|
342 | expect(data.sha1).toBe(fileSha1)
|
343 | expect(data.name).toBe(fileName)
|
344 | expect(data.size).toBe(fileBuffer.length)
|
345 | expect(data.type).toBe(fileType)
|
346 | expect(data.title).toBe(fileTitle)
|
347 | expect(data.uri).not.toBeDefined()
|
348 | expect(data.keywords).toBe(fileKeywords)
|
349 | done()
|
350 | })
|
351 | })
|
352 | })
|
353 |
|
354 | it('Alice should tip an openpublish document', function (done) {
|
355 | var amount = 20000
|
356 | var destination = 'mqMsBiNtGJdwdhKr12TqyRNE7RTvEeAkaR'
|
357 | openpublish.tip({
|
358 | destination: destination,
|
359 | sha1: sha1,
|
360 | amount: amount,
|
361 | commonWallet: aliceWallet,
|
362 | commonBlockchain: commonBlockchain
|
363 | }, function (err, tipTx) {
|
364 | if (err) { }
|
365 | console.log(tipTx)
|
366 | expect(tipTx.tipDestinationAddress).toBe(destination)
|
367 | expect(tipTx.openpublishSha1).toBe(sha1)
|
368 | expect(tipTx.tipAmount).toBe(amount)
|
369 | expect(tipTx.txid).toBeDefined()
|
370 | expect(tipTx.propagateResponse).toBe('success')
|
371 | done()
|
372 | })
|
373 | })
|
374 |
|
375 | it('Bob should tip an openpublish document', function (done) {
|
376 | var amount = 20000
|
377 | var destination = 'mqMsBiNtGJdwdhKr12TqyRNE7RTvEeAkaR'
|
378 | openpublish.tip({
|
379 | destination: destination,
|
380 | sha1: sha1,
|
381 | amount: amount,
|
382 | commonWallet: bobWallet,
|
383 | commonBlockchain: commonBlockchain
|
384 | }, function (err, tipTx) {
|
385 | if (err) { }
|
386 | console.log(tipTx)
|
387 | expect(tipTx.tipDestinationAddress).toBe(destination)
|
388 | expect(tipTx.openpublishSha1).toBe(sha1)
|
389 | expect(tipTx.tipAmount).toBe(amount)
|
390 | expect(tipTx.txid).toBeDefined()
|
391 | expect(tipTx.propagateResponse).toBe('success')
|
392 | done()
|
393 | })
|
394 | })
|
395 |
|
396 | it('should scan an opentip', function (done) {
|
397 | var txid = 'b32192c9d2d75a8a28dd4034ea61eacb0dfe4f226acb502cfe108df20fbddebc'
|
398 | openpublish.scanSingle({
|
399 | txid: txid,
|
400 | commonBlockchain: commonBlockchain
|
401 | }, function (err, tip) {
|
402 | if (err) { }
|
403 | expect(tip.openpublishSha1).toBe(sha1)
|
404 | expect(tip.tipAmount).toBe(20000)
|
405 | expect(tip.tipDestinationAddresses[0]).toBe('mqMsBiNtGJdwdhKr12TqyRNE7RTvEeAkaR')
|
406 | done()
|
407 | })
|
408 | })
|
409 |
|
410 | it('should preorder and register a name (inMemoryCommonBlockchain)', function (done) {
|
411 | var name = 'test'
|
412 | openpublish.preorderName({
|
413 | name: name,
|
414 | commonWallet: inMemoryAliceWallet,
|
415 | commonBlockchain: inMemoryCommonBlockchain
|
416 | }, function (err, preordeReceipt) {
|
417 | if (err) { }
|
418 | openpublish.registerName({
|
419 | name: name,
|
420 | commonWallet: inMemoryAliceWallet,
|
421 | commonBlockchain: inMemoryCommonBlockchain
|
422 | }, function (err, registerReceipt) {
|
423 | if (err) { }
|
424 | var data = registerReceipt.data
|
425 | var doc = data.doc
|
426 | var sha1 = shasum(JSON.stringify(data.doc))
|
427 | var verify = bitcoin.Message.verify(inMemoryAliceWallet.address, doc.signedName, doc.name, bitcoin.networks.testnet)
|
428 | expect(verify).toBe(true)
|
429 | expect(sha1).toBe(data.sha1)
|
430 | expect(name).toBe(doc.name)
|
431 | expect(sha1).toBe(preordeReceipt.data.sha1)
|
432 | expect(name).toBe(preordeReceipt.name)
|
433 | done()
|
434 | })
|
435 | })
|
436 | })
|
437 | })
|