UNPKG

7.64 kBJavaScriptView Raw
1var blockcast = require('blockcast')
2var createTorrent = require('create-torrent')
3var FileReader = typeof (window) !== 'undefined' ? window.FileReader : require('filereader')
4var parseTorrent = require('parse-torrent')
5var multihash = require('multihashes')
6var bs58 = require('bs58')
7var crypto = require('crypto')
8var opentip = require('./opentip')
9
10var register = function (options, callback) {
11 getData(options, function (err, data) {
12 if (err) { } // TODO
13 var dataJSON = JSON.stringify(data)
14 blockcast.post({
15 data: dataJSON,
16 fee: options.fee,
17 commonWallet: options.commonWallet,
18 commonBlockchain: options.commonBlockchain,
19 propagationStatus: options.propagationStatus,
20 buildStatus: options.buildStatus
21 }, function (err, blockcastTx) {
22 if (err) { } // TODO
23 var receipt = {
24 data: data,
25 blockcastTx: blockcastTx
26 }
27 callback(false, receipt)
28 })
29 })
30}
31
32var transfer = function (options, callback) {
33 var assetValue = options.assetValue
34 var bitcoinValue = options.bitcoinValue
35 var sha1 = options.sha1
36 var ttl = options.ttl
37 var data = {
38 op: 't',
39 sha1: sha1,
40 value: assetValue,
41 ttl: ttl
42 }
43 var dataJSON = JSON.stringify(data)
44 var assetWallet = options.assetWallet
45 var bitcoinWallet = options.bitcoinWallet
46 var bitcoinWalletSignPrimaryTxHex = options.bitcoinWalletSignPrimaryTxHex || function (txHex, callback) { bitcoinWallet.signRawTransaction({txHex: txHex, input: 0}, callback) }
47 bitcoinWallet.createTransaction({
48 destinationAddress: assetWallet.address,
49 value: bitcoinValue,
50 skipSign: true
51 }, function (err, primaryTxHex) {
52 if (err) { } // TODO
53 blockcast.post({
54 primaryTxHex: primaryTxHex,
55 signPrimaryTxHex: bitcoinWalletSignPrimaryTxHex,
56 data: dataJSON,
57 fee: options.fee,
58 commonWallet: assetWallet,
59 commonBlockchain: options.commonBlockchain,
60 propagationStatus: options.propagationStatus,
61 buildStatus: options.buildStatus
62 }, function (err, blockcastTx) {
63 if (err) { } // TODO
64 var receipt = {
65 data: data,
66 blockcastTx: blockcastTx
67 }
68 callback(false, receipt)
69 })
70 })
71}
72
73var getPayloadsLength = function (options, callback) {
74 getData(options, function (err, data) {
75 if (err) { } // TODO
76 var dataJSON = JSON.stringify(data)
77 blockcast.payloadsLength({data: dataJSON}, function (err, payloadsLength) {
78 callback(err, payloadsLength)
79 })
80 })
81}
82
83var getData = function (options, callback) {
84 var file = options.file
85 var keywords = options.keywords
86 var title = options.title
87 var uri = options.uri
88 var sha1 = options.sha1
89 var reader = new FileReader()
90 reader.addEventListener('load', function (e) {
91 var arr = new Uint8Array(e.target.result)
92 var buffer = new Buffer(arr)
93 buffer.name = file.name
94 if (!sha1) {
95 if (typeof (window) === 'undefined') {
96 sha1 = crypto.createHash('sha1').update(buffer).digest('hex')
97 } else {
98 sha1 = crypto.createHash('sha1').update(arr).digest('hex')
99 }
100 }
101 var sha256Buffer
102 if (typeof (window) === 'undefined') {
103 sha256Buffer = crypto.createHash('sha256').update(buffer).digest('buffer')
104 } else {
105 sha256Buffer = new Buffer(crypto.createHash('sha256').update(arr).digest('hex'), 'hex')
106 }
107 var sha256MultihashBuffer = multihash.encode(sha256Buffer, 'sha2-256')
108 var ipfs = bs58.encode(sha256MultihashBuffer)
109 createTorrent(buffer, function onTorrent (err, torrentBuffer) {
110 var torrent = parseTorrent(torrentBuffer)
111 var btih = torrent.infoHash
112 var data = {
113 op: 'r',
114 btih: btih,
115 sha1: sha1,
116 ipfs: ipfs
117 }
118 if (file.name) {
119 data.name = file.name
120 }
121 if (file.size) {
122 data.size = file.size
123 }
124 if (file.type) {
125 data.type = file.type
126 }
127 if (title) {
128 data.title = title
129 }
130 if (uri) {
131 data.uri = uri
132 }
133 if (keywords) {
134 data.keywords = keywords
135 }
136 callback(err, data)
137 })
138 })
139 reader.readAsArrayBuffer(file)
140}
141
142var processRegistration = function (obj, tx) {
143 if (!obj || !tx || !obj.op || !obj.op === 'r') {
144 return false
145 }
146 var address = tx.vin[0].addresses[0]
147 obj.addr = address
148 return obj
149}
150
151var processTransfer = function (obj, tx) {
152 if (!obj || !tx || !obj.op || !obj.op === 't') {
153 return false
154 }
155 var bitcoinOutput
156 var assetOutput
157 tx.vout.forEach(function (output) {
158 // nulldata must be output index 0 or 2
159 if (output.scriptPubKey.type === 'nulldata' && (output.index === 0 || output.index === 2)) {
160 assetOutput = output
161 }
162 })
163 // the bitcoinOutput is dependent on the location of the assetOutput
164 if (assetOutput.index === 2) {
165 bitcoinOutput = tx.vout[0]
166 } else {
167 bitcoinOutput = tx.vout[2]
168 }
169 if (!bitcoinOutput || !assetOutput) {
170 return obj // return false ?
171 }
172 obj.assetValue = obj.value
173 delete (obj.value)
174 obj.assetAddress = bitcoinOutput.scriptPubKey.addresses[0] // the bitcoin is sent to the owner who is exchanging assets
175 obj.bitcoinValue = bitcoinOutput.value
176 // the bitcoinAddress that is receiving the asset from the assetAddress must but the other input address
177 tx.vin.forEach(function (input) {
178 var address = input.addresses[0]
179 if (address !== obj.assetAddress) {
180 obj.bitcoinAddress = address
181 }
182 })
183 return obj
184}
185
186var scanSingle = function (options, callback) {
187 var opentipScan = function (blockcastErr) {
188 opentip.scanSingle(options, function (err, tip) {
189 if (err) { } // TODO
190 if (tip) {
191 callback(false, tip)
192 } else {
193 callback(blockcastErr, false)
194 }
195 })
196 }
197
198 blockcast.scanSingle(options, function (err, rawData, addresses, primaryTx) {
199 if (err || !rawData) {
200 return opentipScan(err)
201 }
202 try {
203 var data = JSON.parse(rawData)
204 if (data.op) {
205 var openpublishOperation
206 if (data.op === 'r') {
207 openpublishOperation = processRegistration(data, primaryTx)
208 } else if (data.op === 't') {
209 openpublishOperation = processTransfer(data, primaryTx)
210 }
211 callback(false, openpublishOperation)
212 } else {
213 return opentipScan(false)
214 }
215 } catch (e) {
216 return opentipScan(e)
217 }
218 })
219}
220
221var tip = function (options, callback) {
222 var commonBlockchain = options.commonBlockchain
223 if (options.sha1) {
224 options.openpublishSha1 = options.sha1
225 }
226 if (options.amount) {
227 options.tipAmount = options.amount
228 }
229 if (options.destination) {
230 options.tipDestinationAddress = options.destination
231 }
232 opentip.create(options, function (err, signedTxHex, txid) {
233 if (err) {
234 callback(err, null)
235 } else {
236 var propagateResponse = function (err, res) {
237 var tipTx = {
238 openpublishSha1: options.openpublishSha1,
239 tipDestinationAddress: options.tipDestinationAddress,
240 tipAmount: options.tipAmount,
241 txid: txid
242 }
243 if (err) {
244 tipTx.propagateResponse = 'failure'
245 } else {
246 tipTx.propagateResponse = 'success'
247 }
248 callback(err, tipTx)
249 }
250 commonBlockchain.Transactions.Propagate(signedTxHex, propagateResponse)
251 }
252 })
253}
254
255var OpenPublish = {
256 register: register,
257 transfer: transfer,
258 tip: tip,
259 scanSingle: scanSingle,
260 getData: getData,
261 getPayloadsLength: getPayloadsLength,
262 processRegistration: processRegistration,
263 processTransfer: processTransfer
264}
265
266module.exports = OpenPublish