def confirm_order(self, request): try: def respond(success): if success: request.write(json.dumps({"success": True})) request.finish() else: request.write(json.dumps({"success": False, "reason": "Failed to send order confirmation"})) request.finish() file_path = DATA_FOLDER + "store/listings/in progress/" + request.args["id"][0] + ".json" with open(file_path, 'r') as filename: order = json.load(filename, object_pairs_hook=OrderedDict) c = Contract(self.db, contract=order, testnet=self.protocol.testnet) c.add_order_confirmation(self.protocol.blockchain, request.args["payout_address"][0], comments=request.args["comments"][0] if "comments" in request.args else None, shipper=request.args["shipper"][0] if "shipper" in request.args else None, tracking_number=request.args["tracking_number"][0] if "tracking_number" in request.args else None, est_delivery=request.args["est_delivery"][0] if "est_delivery" in request.args else None, url=request.args["url"][0] if "url" in request.args else None, password=request.args["password"][0] if "password" in request.args else None) guid = c.contract["buyer_order"]["order"]["id"]["guid"] self.mserver.confirm_order(guid, c).addCallback(respond) return server.NOT_DONE_YET except Exception, e: request.write(json.dumps({"success": False, "reason": e.message}, indent=4)) request.finish() return server.NOT_DONE_YET
def check_for_payment(self, request): if not self.protocol.blockchain.connected: request.write( json.dumps( { "success": False, "reason": "libbitcoin server offline" }, indent=4)) request.finish() return server.NOT_DONE_YET try: file_path = DATA_FOLDER + "purchases/unfunded/" + request.args[ "order_id"][0] + ".json" with open(file_path, 'r') as filename: order = json.load(filename, object_pairs_hook=OrderedDict) c = Contract(self.db, contract=order, testnet=self.protocol.testnet) c.blockchain = self.protocol.blockchain c.notification_listener = self.mserver.protocol.get_notification_listener( ) c.is_purchase = True addr = c.contract["buyer_order"]["order"]["payment"]["address"] def history_fetched(ec, history): if not ec: # pylint: disable=W0612 # pylint: disable=W0640 for objid, txhash, index, height, value in history: def cb_txpool(ec, result): if ec: self.protocol.blockchain.fetch_transaction( txhash, cb_chain) else: c.on_tx_received(None, None, None, None, result) def cb_chain(ec, result): if not ec: c.on_tx_received(None, None, None, None, result) self.protocol.blockchain.fetch_txpool_transaction( txhash, cb_txpool) self.protocol.blockchain.fetch_history2(addr, history_fetched) request.write(json.dumps({"success": True}, indent=4)) request.finish() return server.NOT_DONE_YET except Exception, e: request.write( json.dumps({ "success": False, "reason": e.message }, indent=4)) request.finish() return server.NOT_DONE_YET
def rpc_order(self, sender, pubkey, encrypted): try: box = Box(PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey)) order = box.decrypt(encrypted) c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict), testnet=self.multiplexer.testnet) if c.verify(sender.signed_pubkey[64:]): self.router.addContact(sender) self.log.info("received an order from %s, waiting for payment..." % sender) payment_address = c.contract["buyer_order"]["order"]["payment"]["address"] chaincode = c.contract["buyer_order"]["order"]["payment"]["chaincode"] masterkey_b = c.contract["buyer_order"]["order"]["id"]["pubkeys"]["bitcoin"] buyer_key = derive_childkey(masterkey_b, chaincode) amount = c.contract["buyer_order"]["order"]["payment"]["amount"] listing_hash = c.contract["buyer_order"]["order"]["ref_hash"] signature = self.signing_key.sign( str(payment_address) + str(amount) + str(listing_hash) + str(buyer_key))[:64] c.await_funding(self.multiplexer.ws, self.multiplexer.blockchain, signature, False) return [signature] else: self.log.warning("received invalid order from %s" % sender) return ["False"] except Exception: self.log.error("unable to decrypt order from %s" % sender) return ["False"]
def set_contract(self, request): print request c = Contract() c.create( str(request.args["expiration_date"][0]), request.args["metadata_category"][0], request.args["title"][0], request.args["description"][0], request.args["currency_code"][0], request.args["price"][0], request.args["process_time"][0], True if "nsfw" in request.args else False, request.args["shipping_origin"][0], request.args["ships_to"], est_delivery_domestic=request.args["est_delivery_domestic"][0], est_delivery_international=request. args["est_delivery_international"][0], shipping_currency_code=request.args["shipping_currency_code"][0], shipping_domestic=request.args["shipping_domestic"][0], shipping_international=request.args["shipping_international"][0], keywords=request.args["keywords"] if "keywords" in request.args else None, category=request.args["category"][0] if request.args["category"][0] is not "" else None, condition=request.args["condition"][0] if request.args["condition"][0] is not "" else None, sku=request.args["sku"][0] if request.args["sku"][0] is not "" else None, images=request.args["images"], free_shipping=True if "free_shipping" in request.args else False) for keyword in request.args["keywords"]: self.kserver.set(keyword.lower(), c.get_contract_id(), self.kserver.node.getProto().SerializeToString())
def parse_messages(messages): if messages is not None: for message in messages: try: value = objects.Value() value.ParseFromString(message) try: box = Box(PrivateKey(self.signing_key.encode()), PublicKey(value.valueKey)) ciphertext = value.serializedData plaintext = box.decrypt(ciphertext) p = objects.Plaintext_Message() p.ParseFromString(plaintext) signature = p.signature p.ClearField("signature") verify_key = nacl.signing.VerifyKey(p.signed_pubkey[64:]) verify_key.verify(p.SerializeToString(), signature) h = nacl.hash.sha512(p.signed_pubkey) pow_hash = h[64:128] if int(pow_hash[:6], 16) >= 50 or hexlify(p.sender_guid) != h[:40]: raise Exception('Invalid guid') if p.type == objects.Plaintext_Message.Type.Value("ORDER_CONFIRMATION"): c = Contract(self.db, hash_value=unhexlify(p.subject)) c.accept_order_confirmation(self.protocol.multiplexer.ws, confirmation_json=p.message) else: listener.notify(p.sender_guid, p.encryption_pubkey, p.subject, objects.Plaintext_Message.Type.Name(p.type), p.message) except Exception: pass signature = self.signing_key.sign(value.valueKey)[:64] self.kserver.delete(self.kserver.node.id, value.valueKey, signature) except Exception: pass
def rpc_order(self, sender, pubkey, encrypted): try: box = Box(self.signing_key.to_curve25519_private_key(), PublicKey(pubkey)) order = box.decrypt(encrypted) c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict), testnet=self.multiplexer.testnet) v = c.verify(sender.pubkey) if v is True: self.router.addContact(sender) self.log.info("received an order from %s, waiting for payment..." % sender) payment_address = c.contract["buyer_order"]["order"]["payment"]["address"] chaincode = c.contract["buyer_order"]["order"]["payment"]["chaincode"] masterkey_b = c.contract["buyer_order"]["order"]["id"]["pubkeys"]["bitcoin"] buyer_key = derive_childkey(masterkey_b, chaincode) amount = c.contract["buyer_order"]["order"]["payment"]["amount"] listing_hash = c.contract["vendor_offer"]["listing"]["contract_id"] signature = self.signing_key.sign( str(payment_address) + str(amount) + str(listing_hash) + str(buyer_key))[:64] c.await_funding(self.get_notification_listener(), self.multiplexer.blockchain, signature, False) return [signature] else: self.log.warning("received invalid order from %s reason %s" % (sender, v)) return ["False"] except Exception, e: self.log.error("Exception (%s) occurred processing order from %s" % (e.message, sender)) return ["False"]
def set_contract(self, request): print request c = Contract() c.create( str(request.args["expiration_date"][0]), request.args["metadata_category"][0], request.args["title"][0], request.args["description"][0], request.args["currency_code"][0], request.args["price"][0], request.args["process_time"][0], True if "nsfw" in request.args else False, request.args["shipping_origin"][0], request.args["ships_to"], est_delivery_domestic=request.args["est_delivery_domestic"][0], est_delivery_international=request.args["est_delivery_international"][0], shipping_currency_code=request.args["shipping_currency_code"][0], shipping_domestic=request.args["shipping_domestic"][0], shipping_international=request.args["shipping_international"][0], keywords=request.args["keywords"] if "keywords" in request.args else None, category=request.args["category"][0] if request.args["category"][0] is not "" else None, condition=request.args["condition"][0] if request.args["condition"][0] is not "" else None, sku=request.args["sku"][0] if request.args["sku"][0] is not "" else None, images=request.args["images"], free_shipping=True if "free_shipping" in request.args else False) for keyword in request.args["keywords"]: self.kserver.set(keyword.lower(), c.get_contract_id(), self.kserver.node.getProto().SerializeToString())
def complete_order(self, request): def respond(success): if success: request.write(json.dumps({"success": True})) request.finish() else: request.write( json.dumps({ "success": False, "reason": "Failed to send receipt to vendor" })) request.finish() file_path = DATA_FOLDER + "purchases/in progress/" + request.args[ "id"][0] + ".json" with open(file_path, 'r') as filename: order = json.load(filename, object_pairs_hook=OrderedDict) c = Contract(self.db, contract=order, testnet=self.protocol.testnet) c.add_receipt(True, self.protocol.blockchain, feedback=request.args["feedback"][0] if "feedback" in request.args else None, quality=request.args["quality"][0] if "quality" in request.args else None, description=request.args["description"][0] if "description" in request.args else None, delivery_time=request.args["delivery_time"][0] if "delivery_time" in request.args else None, customer_service=request.args["customer_service"][0] if "customer_service" in request.args else None, review=request.args["review"][0] if "review" in request.args else "") guid = c.contract["vendor_offer"]["listing"]["id"]["guid"] self.mserver.complete_order(guid, c).addCallback(respond) return server.NOT_DONE_YET
def rpc_order(self, sender, pubkey, encrypted): try: box = Box(PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey)) order = box.decrypt(encrypted) c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict), testnet=self.multiplexer.testnet) if c.verify(sender.signed_pubkey[64:]): self.router.addContact(sender) self.log.info("received an order from %s, waiting for payment..." % sender) payment_address = c.contract["buyer_order"]["order"]["payment"]["address"] chaincode = c.contract["buyer_order"]["order"]["payment"]["chaincode"] masterkey_b = c.contract["buyer_order"]["order"]["id"]["pubkeys"]["bitcoin"] buyer_key = derive_childkey(masterkey_b, chaincode) amount = c.contract["buyer_order"]["order"]["payment"]["amount"] listing_hash = c.contract["buyer_order"]["order"]["ref_hash"] signature = self.signing_key.sign( str(payment_address) + str(amount) + str(listing_hash) + str(buyer_key))[:64] c.await_funding(self.get_notification_listener(), self.multiplexer.blockchain, signature, False) return [signature] else: self.log.warning("received invalid order from %s" % sender) return ["False"] except Exception: self.log.error("unable to decrypt order from %s" % sender) return ["False"]
def confirm_order(self, request): try: def respond(success): if success: request.write(json.dumps({"success": True})) request.finish() else: request.write(json.dumps({"success": False, "reason": "Failed to send order confirmation"})) request.finish() file_path = DATA_FOLDER + "store/contracts/in progress/" + request.args["id"][0] + ".json" with open(file_path, 'r') as filename: order = json.load(filename, object_pairs_hook=OrderedDict) c = Contract(self.db, contract=order, testnet=self.protocol.testnet) c.add_order_confirmation(self.protocol.blockchain, request.args["payout_address"][0], comments=request.args["comments"][0] if "comments" in request.args else None, shipper=request.args["shipper"][0] if "shipper" in request.args else None, tracking_number=request.args["tracking_number"][0] if "tracking_number" in request.args else None, est_delivery=request.args["est_delivery"][0] if "est_delivery" in request.args else None, url=request.args["url"][0] if "url" in request.args else None, password=request.args["password"][0] if "password" in request.args else None) guid = c.contract["buyer_order"]["order"]["id"]["guid"] self.mserver.confirm_order(guid, c).addCallback(respond) return server.NOT_DONE_YET except Exception, e: request.write(json.dumps({"success": False, "reason": e.message}, indent=4)) request.finish() return server.NOT_DONE_YET
def rpc_complete_order(self, sender, pubkey, encrypted): try: box = Box( PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey)) order = box.decrypt(encrypted) c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict), testnet=self.multiplexer.testnet) def handle_result(contract_id): if contract_id: self.router.addContact(sender) self.log.info("Received receipt for order %s" % contract_id) return ["True"] else: self.log.error("Received invalid receipt from %s" % sender) return ["False"] d = c.accept_receipt(self.multiplexer.ws, self.multiplexer.blockchain) d.addCallback(handle_result) except Exception: self.log.error("Unable to decrypt order receipt from %s" % sender) return ["False"]
def rpc_order_confirmation(self, sender, pubkey, encrypted): try: box = Box( PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey)) order = box.decrypt(encrypted) c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict), testnet=self.multiplexer.testnet) contract_id = c.accept_order_confirmation( self.get_notification_listener()) if contract_id: self.router.addContact(sender) self.log.info("received confirmation for order %s" % contract_id) return ["True"] else: self.log.warning( "received invalid order confirmation from %s" % sender) return ["False"] except Exception: self.log.error("unable to decrypt order confirmation from %s" % sender) return ["False"]
def rpc_order(self, sender, pubkey, encrypted): try: box = Box( PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey)) order = box.decrypt(encrypted) c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict), testnet=self.multiplexer.testnet) if c.verify(sender.signed_pubkey[64:]): self.router.addContact(sender) self.log.info("Received an order from %s" % sender) payment_address = c.contract["buyer_order"]["order"][ "payment"]["address"] signature = self.signing_key.sign(str(payment_address))[:64] c.await_funding(self.multiplexer.ws, self.multiplexer.blockchain, signature, False) return [signature] else: self.log.error("Received invalid order from %s" % sender) return ["False"] except Exception: self.log.error("Unable to decrypt order from %s" % sender) return ["False"]
def complete_order(self, request): def respond(success): if success: request.write(json.dumps({"success": True})) request.finish() else: request.write(json.dumps({"success": False, "reason": "Failed to send receipt to vendor"})) request.finish() file_path = DATA_FOLDER + "purchases/in progress/" + request.args["id"][0] + ".json" with open(file_path, 'r') as filename: order = json.load(filename, object_pairs_hook=OrderedDict) c = Contract(self.db, contract=order, testnet=self.protocol.testnet) c.add_receipt(True, self.protocol.blockchain, feedback=request.args["feedback"][0] if "feedback" in request.args else None, quality=request.args["quality"][0] if "quality" in request.args else None, description=request.args["description"][0] if "description" in request.args else None, delivery_time=request.args["delivery_time"][0] if "delivery_time" in request.args else None, customer_service=request.args["customer_service"][0] if "customer_service" in request.args else None, review=request.args["review"][0] if "review" in request.args else "") guid = c.contract["vendor_offer"]["listing"]["id"]["guid"] self.mserver.complete_order(guid, c).addCallback(respond) return server.NOT_DONE_YET
def delete_contract(self, request): if "id" in request.args: c = Contract(hash_value=unhexlify(request.args["id"][0])) for keyword in c.contract["vendor_offer"]["listing"]["item"]["keywords"]: self.kserver.delete(keyword.lower(), c.get_contract_id(), KeyChain().signing_key.sign(c.get_contract_id())[:64]) c.delete()
def purchase_contract(self, request): try: def handle_response(resp, contract): if resp: contract.await_funding( self.mserver.protocol.get_notification_listener(), self.protocol.blockchain, resp ) request.write( json.dumps( { "success": True, "payment_address": payment[0], "amount": payment[1], "order_id": c.get_contract_id().encode("hex"), }, indent=4, ) ) request.finish() else: request.write(json.dumps({"success": False, "reason": "seller rejected contract"}, indent=4)) request.finish() options = None if "options" in request.args: options = {} for option in request.args["options"]: options[option] = request.args[option][0] c = Contract(self.db, hash_value=unhexlify(request.args["id"][0]), testnet=self.protocol.testnet) payment = c.add_purchase_info( int(request.args["quantity"][0]), request.args["ship_to"][0] if "ship_to" in request.args else None, request.args["address"][0] if "address" in request.args else None, request.args["city"][0] if "city" in request.args else None, request.args["state"][0] if "state" in request.args else None, request.args["postal_code"][0] if "postal_code" in request.args else None, request.args["country"][0] if "country" in request.args else None, request.args["moderator"][0] if "moderator" in request.args else None, options, ) def get_node(node): if node is not None: self.mserver.purchase(node, c).addCallback(handle_response, c) else: request.write(json.dumps({"success": False, "reason": "unable to reach vendor"}, indent=4)) request.finish() seller_guid = unhexlify(c.contract["vendor_offer"]["listing"]["id"]["guid"]) self.kserver.resolve(seller_guid).addCallback(get_node) return server.NOT_DONE_YET except Exception, e: request.write(json.dumps({"success": False, "reason": e.message}, indent=4)) request.finish() return server.NOT_DONE_YET
def set_contract(self, request): try: if "options" in request.args: options = {} for option in request.args["options"]: options[option] = request.args[option] c = Contract(self.db) c.create( str(request.args["expiration_date"][0]), request.args["metadata_category"][0], request.args["title"][0], request.args["description"][0], request.args["currency_code"][0], request.args["price"][0], request.args["process_time"][0], str_to_bool(request.args["nsfw"][0]), shipping_origin=request.args["shipping_origin"][0] if "shipping_origin" in request.args else None, shipping_regions=request.args["ships_to"] if "ships_to" in request.args else None, est_delivery_domestic=request.args["est_delivery_domestic"][0] if "est_delivery_domestic" in request.args else None, est_delivery_international=request.args["est_delivery_international"][0] if "est_delivery_international" in request.args else None, terms_conditions=request.args["terms_conditions"][0] if request.args["terms_conditions"][0] is not "" else None, returns=request.args["returns"][0] if request.args["returns"][0] is not "" else None, shipping_currency_code=request.args["shipping_currency_code"][0], shipping_domestic=request.args["shipping_domestic"][0], shipping_international=request.args["shipping_international"][0], keywords=request.args["keywords"] if "keywords" in request.args else None, category=request.args["category"][0] if request.args["category"][0] is not "" else None, condition=request.args["condition"][0] if request.args["condition"][0] is not "" else None, sku=request.args["sku"][0] if request.args["sku"][0] is not "" else None, images=request.args["images"], free_shipping=str_to_bool(request.args["free_shipping"][0]), options=options if "options" in request.args else None, moderators=request.args["moderators"] if "moderators" in request.args else None, ) for keyword in request.args["keywords"]: self.kserver.set( digest(keyword.lower()), c.get_contract_id(), self.kserver.node.getProto().SerializeToString() ) request.write(json.dumps({"success": True, "id": c.get_contract_id().encode("hex")})) request.finish() return server.NOT_DONE_YET except Exception, e: request.write(json.dumps({"success": False, "reason": e.message}, indent=4)) request.finish() return server.NOT_DONE_YET
def rpc_complete_order(self, sender, pubkey, encrypted): try: box = Box(PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey)) order = box.decrypt(encrypted) c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict), testnet=self.multiplexer.testnet) contract_id = c.accept_receipt(self.get_notification_listener(), self.multiplexer.blockchain) self.router.addContact(sender) self.log.info("received receipt for order %s" % contract_id) return ["True"] except Exception: self.log.error("unable to parse receipt from %s" % sender) return ["False"]
def rpc_refund(self, sender, pubkey, encrypted): try: box = Box(self.signing_key.to_curve25519_private_key(), PublicKey(pubkey)) refund = box.decrypt(encrypted) refund_json = json.loads(refund, object_pairs_hook=OrderedDict) c = Contract(self.db, hash_value=unhexlify(refund_json["refund"]["order_id"]), testnet=self.multiplexer.testnet) c.process_refund(refund_json, self.multiplexer.blockchain, self.get_notification_listener()) self.router.addContact(sender) self.log.info("order %s refunded by vendor" % refund_json["refund"]["order_id"]) return ["True"] except Exception, e: self.log.error("unable to parse refund message from %s" % sender) return [e.message]
def delete_contract(self, request): try: if "id" in request.args: file_path = self.db.HashMap().get_file( unhexlify(request.args["id"][0])) with open(file_path, 'r') as filename: contract = json.load(filename, object_pairs_hook=OrderedDict) c = Contract(self.db, contract=contract) if "keywords" in c.contract["vendor_offer"]["listing"]["item"]: for keyword in c.contract["vendor_offer"]["listing"][ "item"]["keywords"]: self.kserver.delete( keyword.lower(), c.get_contract_id(), self.keychain.signing_key.sign( c.get_contract_id())[:64]) if "delete_images" in request.args: c.delete(delete_images=True) else: c.delete() request.write(json.dumps({"success": True})) request.finish() return server.NOT_DONE_YET except Exception, e: request.write( json.dumps({ "success": False, "reason": e.message }, indent=4)) request.finish() return server.NOT_DONE_YET
def rpc_order_confirmation(self, sender, pubkey, encrypted): try: box = Box(PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey)) order = box.decrypt(encrypted) c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict), testnet=self.multiplexer.testnet) contract_id = c.accept_order_confirmation(self.multiplexer.ws) if contract_id: self.router.addContact(sender) self.log.info("received confirmation for order %s" % contract_id) return ["True"] else: self.log.warning("received invalid order confirmation from %s" % sender) return ["False"] except Exception: self.log.error("unable to decrypt order confirmation from %s" % sender) return ["False"]
def rpc_order_confirmation(self, sender, pubkey, encrypted): try: box = Box(self.signing_key.to_curve25519_private_key(), PublicKey(pubkey)) order = box.decrypt(encrypted) c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict), testnet=self.multiplexer.testnet) valid = c.accept_order_confirmation(self.get_notification_listener()) if valid is True: self.router.addContact(sender) self.log.info("received confirmation for order %s" % c.get_order_id()) return ["True"] else: self.log.warning("received invalid order confirmation from %s" % sender) return [valid] except Exception, e: self.log.error("unable to decrypt order confirmation from %s" % sender) return [str(e.message)]
def set_contract(self, request): try: if "options" in request.args: options = {} for option in request.args["options"]: options[option] = request.args[option] c = Contract(self.db) c.create( str(request.args["expiration_date"][0]), request.args["metadata_category"][0], request.args["title"][0], request.args["description"][0], request.args["currency_code"][0], request.args["price"][0], request.args["process_time"][0], True if "nsfw" in request.args else False, shipping_origin=request.args["shipping_origin"][0] if "shipping_origin" in request.args else None, shipping_regions=request.args["ships_to"] if "ships_to" in request.args else None, est_delivery_domestic=request.args["est_delivery_domestic"][0] if "est_delivery_domestic" in request.args else None, est_delivery_international=request.args["est_delivery_international"][0] if "est_delivery_international" in request.args else None, terms_conditions=request.args["terms_conditions"][0] if request.args["terms_conditions"][0] is not "" else None, returns=request.args["returns"][0] if request.args["returns"][0] is not "" else None, shipping_currency_code=request.args["shipping_currency_code"][0], shipping_domestic=request.args["shipping_domestic"][0], shipping_international=request.args["shipping_international"][0], keywords=request.args["keywords"] if "keywords" in request.args else None, category=request.args["category"][0] if request.args["category"][0] is not "" else None, condition=request.args["condition"][0] if request.args["condition"][0] is not "" else None, sku=request.args["sku"][0] if request.args["sku"][0] is not "" else None, images=request.args["images"], free_shipping=True if "free_shipping" in request.args else False, options=options if "options" in request.args else None, moderators=request.args["moderators"] if "moderators" in request.args else None) for keyword in request.args["keywords"]: self.kserver.set(digest(keyword.lower()), c.get_contract_id(), self.kserver.node.getProto().SerializeToString()) request.write(json.dumps({"success": True})) request.finish() return server.NOT_DONE_YET except Exception, e: request.write(json.dumps({"success": False, "reason": e.message}, indent=4)) request.finish() return server.NOT_DONE_YET
def delete_contract(self, request): try: if "id" in request.args: file_path = self.db.HashMap().get_file(request.args["id"][0]) with open(file_path, "r") as filename: contract = json.load(filename, object_pairs_hook=OrderedDict) c = Contract(self.db, contract=contract) if "keywords" in c.contract["vendor_offer"]["listing"]["item"]: for keyword in c.contract["vendor_offer"]["listing"]["item"]["keywords"]: self.kserver.delete( keyword.lower(), c.get_contract_id(), self.keychain.signing_key.sign(c.get_contract_id())[:64], ) if "delete_images" in request.args: c.delete(delete_images=True) else: c.delete() request.write(json.dumps({"success": True})) request.finish() return server.NOT_DONE_YET except Exception, e: request.write(json.dumps({"success": False, "reason": e.message}, indent=4)) request.finish() return server.NOT_DONE_YET
def rpc_order(self, sender, pubkey, encrypted): try: box = Box(PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey)) order = box.decrypt(encrypted) c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict), testnet=self.multiplexer.testnet) if c.verify(sender.signed_pubkey[64:]): self.router.addContact(sender) self.log.info("Received an order from %s" % sender) payment_address = c.contract["buyer_order"]["order"]["payment"]["address"] signature = self.signing_key.sign(str(payment_address))[:64] c.await_funding(self.multiplexer.ws, self.multiplexer.blockchain, signature, False) return [signature] else: self.log.error("Received invalid order from %s" % sender) return ["False"] except Exception: self.log.error("Unable to decrypt order from %s" % sender) return ["False"]
def rpc_complete_order(self, sender, pubkey, encrypted): try: box = Box(self.signing_key.to_curve25519_private_key(), PublicKey(pubkey)) order = box.decrypt(encrypted) json.loads(order, object_pairs_hook=OrderedDict) temp = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict), testnet=self.multiplexer.testnet) c = Contract(self.db, hash_value=unhexlify(temp.get_order_id()), testnet=self.multiplexer.testnet) contract_id = c.accept_receipt(self.get_notification_listener(), self.multiplexer.blockchain, receipt_json=json.dumps(temp.contract["buyer_receipt"], indent=4)) self.router.addContact(sender) self.log.info("received receipt for order %s" % contract_id) return ["True"] except Exception, e: self.log.error("unable to parse receipt from %s" % sender) return [e.message]
def check_for_payment(self, request): if not self.protocol.blockchain.connected: request.write(json.dumps({"success": False, "reason": "libbitcoin server offline"}, indent=4)) request.finish() return server.NOT_DONE_YET try: file_path = DATA_FOLDER + "purchases/unfunded/" + request.args["order_id"][0] + ".json" with open(file_path, 'r') as filename: order = json.load(filename, object_pairs_hook=OrderedDict) c = Contract(self.db, contract=order, testnet=self.protocol.testnet) self.protocol.blockchain.refresh_connection() c.blockchain = self.protocol.blockchain c.notification_listener = self.mserver.protocol.get_notification_listener() c.is_purchase = True addr = c.contract["buyer_order"]["order"]["payment"]["address"] def history_fetched(ec, history): if not ec: # pylint: disable=W0612 # pylint: disable=W0640 for objid, txhash, index, height, value in history: def cb_txpool(ec, result): if ec: self.protocol.blockchain.fetch_transaction(txhash, cb_chain) else: c.on_tx_received(None, None, None, None, result) def cb_chain(ec, result): if not ec: c.on_tx_received(None, None, None, None, result) self.protocol.blockchain.fetch_txpool_transaction(txhash, cb_txpool) self.protocol.blockchain.fetch_history2(addr, history_fetched) request.write(json.dumps({"success": True}, indent=4)) request.finish() return server.NOT_DONE_YET except Exception, e: request.write(json.dumps({"success": False, "reason": e.message}, indent=4)) request.finish() return server.NOT_DONE_YET
def rpc_complete_order(self, sender, pubkey, encrypted): try: box = Box(PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey)) order = box.decrypt(encrypted) c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict), testnet=self.multiplexer.testnet) def handle_result(contract_id): if contract_id: self.router.addContact(sender) self.log.info("Received receipt for order %s" % contract_id) return ["True"] else: self.log.error("Received invalid receipt from %s" % sender) return ["False"] d = c.accept_receipt(self.multiplexer.ws, self.multiplexer.blockchain) d.addCallback(handle_result) except Exception: self.log.error("Unable to decrypt order receipt from %s" % sender) return ["False"]
def rpc_complete_order(self, sender, pubkey, encrypted): try: box = Box(self.signing_key.to_curve25519_private_key(), PublicKey(pubkey)) order = box.decrypt(encrypted) c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict), testnet=self.multiplexer.testnet) contract_id = c.accept_receipt(self.get_notification_listener(), self.multiplexer.blockchain) self.router.addContact(sender) self.log.info("received receipt for order %s" % contract_id) return ["True"] except Exception: import traceback traceback.print_exc() self.log.error("unable to parse receipt from %s" % sender) return ["False"]
def setcontract(): parser = argparse.ArgumentParser( description="Sets a new contract in the database and filesystem.", usage='''usage: networkcli.py setcontract [-f FILEPATH]''') parser.add_argument('-f', '--filepath', help="a path to a completed json contract") args = parser.parse_args(sys.argv[2:]) with open(args.filepath) as data_file: contract = json.load(data_file, object_pairs_hook=OrderedDict) Contract(contract).save()
def rpc_order(self, sender, pubkey, encrypted): try: box = Box(self.signing_key.to_curve25519_private_key(), PublicKey(pubkey)) order = box.decrypt(encrypted) c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict), testnet=self.multiplexer.testnet) v = c.verify(sender.pubkey) if v is True: self.router.addContact(sender) self.log.info( "received an order from %s, waiting for payment..." % sender) payment_address = c.contract["buyer_order"]["order"][ "payment"]["address"] chaincode = c.contract["buyer_order"]["order"]["payment"][ "chaincode"] masterkey_b = c.contract["buyer_order"]["order"]["id"][ "pubkeys"]["bitcoin"] buyer_key = derive_childkey(masterkey_b, chaincode) amount = c.contract["buyer_order"]["order"]["payment"][ "amount"] listing_hash = c.contract["vendor_offer"]["listing"][ "contract_id"] signature = self.signing_key.sign( str(payment_address) + str(amount) + str(listing_hash) + str(buyer_key))[:64] c.await_funding(self.get_notification_listener(), self.multiplexer.blockchain, signature, False) return [signature] else: self.log.warning("received invalid order from %s reason %s" % (sender, v)) return ["False"] except Exception, e: self.log.error("Exception (%s) occurred processing order from %s" % (e.message, sender)) return ["False"]
def rpc_complete_order(self, sender, pubkey, encrypted): try: box = Box(self.signing_key.to_curve25519_private_key(), PublicKey(pubkey)) order = box.decrypt(encrypted) json.loads(order, object_pairs_hook=OrderedDict) temp = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict), testnet=self.multiplexer.testnet) c = Contract(self.db, hash_value=unhexlify(temp.get_order_id()), testnet=self.multiplexer.testnet) contract_id = c.accept_receipt(self.get_notification_listener(), self.multiplexer.blockchain, receipt_json=json.dumps( temp.contract["buyer_receipt"], indent=4)) self.router.addContact(sender) self.log.info("received receipt for order %s" % contract_id) return ["True"] except Exception, e: self.log.error("unable to parse receipt from %s" % sender) return [e.message]
def parse_messages(messages): if messages is not None: self.log.info("retrieved %s message(s) from the dht" % len(messages)) for message in messages: try: value = objects.Value() value.ParseFromString(message) try: box = Box(PrivateKey(self.signing_key.encode()), PublicKey(value.valueKey)) ciphertext = value.serializedData plaintext = box.decrypt(ciphertext).decode("zlib") p = objects.Plaintext_Message() p.ParseFromString(plaintext) signature = p.signature p.ClearField("signature") verify_key = nacl.signing.VerifyKey( p.signed_pubkey[64:]) verify_key.verify(p.SerializeToString(), signature) h = nacl.hash.sha512(p.signed_pubkey) pow_hash = h[64:128] if int(pow_hash[:6], 16) >= 50 or p.sender_guid.encode( "hex") != h[:40]: raise Exception('Invalid guid') if p.type == objects.Plaintext_Message.Type.Value( "ORDER_CONFIRMATION"): c = Contract(self.db, hash_value=p.subject) c.accept_order_confirmation( self.protocol.get_notification_listener(), confirmation_json=p.message) elif p.type == objects.Plaintext_Message.Type.Value( "RECEIPT"): c = Contract(self.db, hash_value=p.subject) c.accept_receipt( self.protocol.get_notification_listener(), self.protocol.multiplexer.blockchain, receipt_json=p.message) else: listener.notify(p, signature) except Exception: pass signature = self.signing_key.sign(value.valueKey)[:64] self.kserver.delete(self.kserver.node.id, value.valueKey, signature) except Exception: pass
def parse_messages(messages): if messages is not None: self.log.info("retrieved %s message(s) from the dht" % len(messages)) for message in messages: try: value = objects.Value() value.ParseFromString(message) try: box = Box(self.signing_key.to_curve25519_private_key(), PublicKey(value.valueKey)) ciphertext = value.serializedData plaintext = box.decrypt(ciphertext).decode("zlib") p = objects.PlaintextMessage() p.ParseFromString(plaintext) signature = p.signature p.ClearField("signature") verify_key = nacl.signing.VerifyKey(p.pubkey) verify_key.verify(p.SerializeToString(), signature) h = nacl.hash.sha512(p.pubkey) pow_hash = h[40:] if int(pow_hash[:6], 16) >= 50 or p.sender_guid.encode("hex") != h[:40]: raise Exception("Invalid guid") if p.type == objects.PlaintextMessage.Type.Value("ORDER_CONFIRMATION"): c = Contract( self.db, hash_value=unhexlify(p.subject), testnet=self.protocol.multiplexer.testnet ) c.accept_order_confirmation( self.protocol.get_notification_listener(), confirmation_json=p.message ) elif p.type == objects.PlaintextMessage.Type.Value("RECEIPT"): c = Contract( self.db, hash_value=unhexlify(p.subject), testnet=self.protocol.multiplexer.testnet ) c.accept_receipt( self.protocol.get_notification_listener(), self.protocol.multiplexer.blockchain, receipt_json=p.message, ) elif p.type == objects.PlaintextMessage.Type.Value("DISPUTE_OPEN"): process_dispute( json.loads(p.message, object_pairs_hook=OrderedDict), self.db, self.protocol.get_message_listener(), self.protocol.get_notification_listener(), self.protocol.multiplexer.testnet, ) else: listener.notify(p, signature) except Exception: pass signature = self.signing_key.sign(value.valueKey)[:64] self.kserver.delete(self.kserver.node.id, value.valueKey, signature) except Exception: pass
def purchase_contract(self, request): try: def handle_response(resp, contract): if resp: contract.await_funding(self.protocol.ws, self.protocol.blockchain, resp) request.write(json.dumps({"success": True, "payment_address": payment[0], "amount": payment[1], "order_id": c.get_contract_id().encode("hex")}, indent=4)) request.finish() else: request.write(json.dumps({"success": False, "reason": "seller rejected contract"}, indent=4)) request.finish() options = None if "options" in request.args: options = {} for option in request.args["options"]: options[option] = request.args[option][0] c = Contract(self.db, hash_value=unhexlify(request.args["id"][0]), testnet=self.protocol.testnet) payment = c.\ add_purchase_info(int(request.args["quantity"][0]), request.args["ship_to"][0] if "ship_to" in request.args else None, request.args["address"][0] if "address" in request.args else None, request.args["city"][0] if "city" in request.args else None, request.args["state"][0] if "state" in request.args else None, request.args["postal_code"][0] if "postal_code" in request.args else None, request.args["country"][0] if "country" in request.args else None, request.args["moderator"][0] if "moderator" in request.args else None, options) def get_node(node): if node is not None: self.mserver.purchase(node, c).addCallback(handle_response, c) else: request.write(json.dumps({"success": False, "reason": "unable to reach vendor"}, indent=4)) request.finish() seller_guid = unhexlify(c.contract["vendor_offer"]["listing"]["id"]["guid"]) self.kserver.resolve(seller_guid).addCallback(get_node) return server.NOT_DONE_YET except Exception, e: request.write(json.dumps({"success": False, "reason": e.message}, indent=4)) request.finish() return server.NOT_DONE_YET
def delete_contract(self, request): try: if "id" in request.args: c = Contract(self.db, hash_value=unhexlify(request.args["id"][0])) for keyword in c.contract["vendor_offer"]["listing"]["item"]["keywords"]: self.kserver.delete(keyword.lower(), c.get_contract_id(), self.keychain.signing_key.sign(c.get_contract_id())[:64]) c.delete() request.write(json.dumps({"success": True})) request.finish() return server.NOT_DONE_YET except Exception, e: request.write(json.dumps({"success": False, "reason": e.message}, indent=4)) request.finish() return server.NOT_DONE_YET
def process_dispute(contract, db, message_listener, notification_listener, testnet): """ This function processes a dispute message received from another node. It checks the contract to see if this a dispute for a purchase we made, a dispute for one of our sales, or a new case if we are the moderator. If it's a purchase or sale it will update the order status to disputed and push a notification to the listener. If it's a new case it will validate the contract, create a new case in the db, and push a notification to the listener. Args: contract: a json contract of the current order state. Should have a "dispute" object attached with dispute info. db: a `Database` object. message_listener: a `MessageListenerImpl` object. notification_listener: a `NotificationListenerImpl` object. testnet: `bool` of whether we're on testnet or not. """ tmp_contract = deepcopy(contract) if "vendor_order_confirmation" in tmp_contract: del tmp_contract["vendor_order_confirmation"] if "buyer_receipt" in tmp_contract: del tmp_contract["buyer_receipt"] del tmp_contract["dispute"] order_id = digest(json.dumps(tmp_contract, indent=4)).encode("hex") own_guid = KeyChain(db).guid.encode("hex") if contract["dispute"]["info"]["guid"] == contract["vendor_offer"]["listing"]["id"]["guid"]: guid = unhexlify(contract["vendor_offer"]["listing"]["id"]["guid"]) public_key = unhexlify(contract["vendor_offer"]["listing"]["id"]["pubkeys"]["guid"]) if "blockchain_id" in contract["vendor_offer"]["listing"]["id"]: handle = contract["vendor_offer"]["listing"]["id"]["blockchain_id"] else: handle = "" proof_sig = None elif contract["dispute"]["info"]["guid"] == contract["buyer_order"]["order"]["id"]["guid"]: guid = unhexlify(contract["buyer_order"]["order"]["id"]["guid"]) public_key = unhexlify(contract["buyer_order"]["order"]["id"]["pubkeys"]["guid"]) if "blockchain_id" in contract["buyer_order"]["order"]["id"]: handle = contract["buyer_order"]["order"]["id"]["blockchain_id"] else: handle = "" proof_sig = contract["dispute"]["info"]["proof_sig"] else: raise Exception("Dispute guid not in contract") verify_key = nacl.signing.VerifyKey(public_key) verify_key.verify(json.dumps(contract["dispute"]["info"], indent=4), base64.b64decode(contract["dispute"]["signature"])) p = PlaintextMessage() p.sender_guid = guid p.handle = handle p.pubkey = public_key p.subject = str(order_id) p.type = PlaintextMessage.Type.Value("DISPUTE_OPEN") p.message = str(contract["dispute"]["info"]["claim"]) p.timestamp = int(time.time()) p.avatar_hash = unhexlify(str(contract["dispute"]["info"]["avatar_hash"])) if db.purchases.get_purchase(order_id) is not None: db.purchases.update_status(order_id, 4) elif db.sales.get_sale(order_id) is not None: db.sales.update_status(order_id, 4) elif "moderators" in contract["vendor_offer"]["listing"]: # TODO: make sure a case isn't already open in the db is_selected = False for moderator in contract["vendor_offer"]["listing"]["moderators"]: if moderator["guid"] == own_guid and contract["buyer_order"]["order"]["moderator"] == own_guid: is_selected = True if not is_selected: raise Exception("Not a moderator for this contract") else: if "blockchain_id" in contract["vendor_offer"]["listing"]["id"] and \ contract["vendor_offer"]["listing"]["id"]["blockchain_id"] != "": vendor = contract["vendor_offer"]["listing"]["id"]["blockchain_id"] else: vendor = contract["vendor_offer"]["listing"]["id"]["guid"] if "blockchain_id" in contract["buyer_order"]["order"]["id"] and \ contract["buyer_order"]["order"]["id"]["blockchain_id"] != "": buyer = contract["buyer_order"]["order"]["id"]["blockchain_id"] else: buyer = contract["buyer_order"]["order"]["id"]["guid"] c = Contract(db, contract=contract, testnet=testnet) validation_failures = c.validate_for_moderation(proof_sig) db.cases.new_case(order_id, contract["vendor_offer"]["listing"]["item"]["title"], time.time(), contract["buyer_order"]["order"]["date"], float(contract["buyer_order"]["order"]["payment"]["amount"]), contract["vendor_offer"]["listing"]["item"]["image_hashes"][0], buyer, vendor, json.dumps(validation_failures), contract["dispute"]["info"]["claim"]) with open(os.path.join(DATA_FOLDER, "cases", order_id + ".json"), 'wb') as outfile: outfile.write(json.dumps(contract, indent=4)) else: raise Exception("Order ID for dispute not found") message_listener.notify(p, "") title = contract["vendor_offer"]["listing"]["item"]["title"] notification_listener.notify(guid, handle, "dispute_open", order_id, title, unhexlify(contract["vendor_offer"]["listing"]["item"]["image_hashes"][0])) # Send SMTP notification notification = SMTPNotification(db) guid = guid.encode("hex") notification.send("[OpenBazaar] Dispute Opened", "A dispute has been opened.\n\n" "Order: %s\n" "Opened By: %s\n" "Title: %s" % (order_id, guid, title))