Esempio n. 1
0
def do_createmarket():
    global mymarket
    
    if entity != 'mod':
        print "Enter a Market Offer:"
        infostr = multiline()
        MM_util.importMarket(infostr)
        
        print "Congratulations, you may now Register with a new Metamarket!"
        print "Market ID:", mktmsg.hash
        
    else:
        if not mymarket:
            marketname = raw_input("Enter a name for this MARKET: ")
            print "Enter a description:"
            desc = multiline()
            reg_fee = str( truncate( decput("Enter a registration fee: ") ) )
            burn_mult = str( decput("Enter a Burn Multiplier: ") )
            
            msgstr = createmarketmsgstr(btcaddr, myid.hash, marketname, desc, reg_fee, burn_mult)
            mymarket = MM_loads(btcaddr, msgstr)
            MM_writefile(msgstr)
            appendindex('market', mymarket.hash)
            print "Congratulations, you are the proud new Owner of a new Metamarket!"
            print "Market ID:", mymarket.hash
        else:
            raise Exception("You are already running a Market!")
Esempio n. 2
0
 def register(self, idstr):
     if self.yorn("We were not able to find your ID on file. "+\
             "Is this a new identity you would like to create?"):
         MM_util.MM_writefile(idstr)
         MM_util.appendindex('ident', self.myid.hash)
         return True
     else:
         return False
Esempio n. 3
0
    def loadListIfModified(self, index):
        MM_util.loadindex(index)
        mtime = os.path.getmtime("%s.dat" % index)
        lastTime = self.listLastLoaded[index]

        if mtime > lastTime:
            self.listLastLoaded[index] = time.time()
            list = MM_util.loadlist(index)

            if index == "ident":
                MM_util.idList = list
            return list
Esempio n. 4
0
    def on_marketImportButton_clicked(self):
        result = self.showImportMarketDlg()
        if not result:
            return

        try:
            MM_util.importMarket(result)
        except json.scanner.JSONDecodeError:
            self.info("Input was not a JSON encoded string")

        self.info(
            "Congratulations, you may now Register with a new Metamarket!")
        self.updateUi()
Esempio n. 5
0
    def on_identBurnButton_clicked(self, amount=None):
        mod = MM_util.searchlistbyhash(self.listDict["ident"],
                                       self.currentMarket.obj['modid'])

        amount = self.value_input("How much BTC would you like to BURN?")
        if not amount or not self.yorn("Are you sure?"):
            return

        msgstr = MM_util.createburn( self.myid.hash, self.btcaddr, \
                            amount, self.getFee(), self.conf_wait, self.conf_end )

        hash = MM_util.MM_writefile(msgstr)
        MM_util.appendindex('burn', hash)

        self.do_sendmsgviabm(mod.obj['bmaddr'], msgstr)
        self.info("Proof of BURN sent!")
Esempio n. 6
0
    def on_identRegButton_clicked(self):
        if not self.yorn("Are you sure you would like to register your identity at %s?" \
                            % self.currentMarket.obj['markename']):
            return

        identlist = self.listDict['ident']
        mod = MM_util.searchlistbyhash(identlist,
                                       self.currentMarket.obj['modid'])
        amount = self.currentMarket.obj['fee']

        msgstr = MM_util.createreg( \
                    self.myid.hash, self.btcaddr, amount, mod, self.getFee() )
        hash = MM_util.MM_writefile(msgstr)
        MM_util.appendindex('reg', hash)

        self.do_sendmsgviabm(mod.obj['bmaddr'], msgstr)
        self.info("Registered!")
Esempio n. 7
0
    def login(self, retries=0):
        credentials = self.showLoginDlg()
        if not credentials:
            return

        self.username, self.passphrase = credentials

        hash = hashlib.sha256(self.passphrase).hexdigest()
        pkbytes = scrypt.hash(hash, self.username, N=2**18, buflen=32)
        self.pkstr = pycoin.serialize.b2h(pkbytes)
        se = long(self.pkstr, 16)
        pk = pycoin.key.Key(secret_exponent=se, netcode=self.netcode)

        self.wif = pk.wif()
        self.btcaddr = pk.address()
        try:
            self.bmaddr = MM_util.bm.getDeterministicAddress(
                base64.b64encode(self.pkstr), 4, 1)

            wp = self.input(
                "Please enter your Bitcoin Core wallet encryption passphrase:",
                password=True)
            if not wp:
                return
            MM_util.unlockwallet(wp)

            addrismine = MM_util.btcd.validateaddress(self.btcaddr)['ismine']
        except bitcoinrpc.authproxy.JSONRPCException as jre:
            if jre.error['code'] == -14:
                self.info(
                    "The passphrase was not correct. Please try logging in again."
                )
                return
        except socket.error:
            self.sockErr()
        except httplib.BadStatusLine:
            MM_util.reconnect_btcd(retries)
            return self.login(retries + 1)

        if MM_util.bm.createDeterministicAddresses(base64.b64encode(self.pkstr)) == [] \
            or not addrismine:
            if not self.importkeys():
                return

        myidstr = MM_util.createidentmsgstr(self.btcaddr, self.bmaddr,
                                            self.username)
        self.myid = MM_util.MM_loads(self.btcaddr, myidstr)

        identlist = self.listDict['ident'] = MM_util.loadlist('ident')
        if not MM_util.searchlistbyhash(identlist, self.myid.hash):
            if not self.register(myidstr):
                return

        self.info("You are now logged in as: %s" % self.username)
        self.loggedIn = True
        self.updateUi()
Esempio n. 8
0
    def showOfferByHash(self, offerhash):
        offerlist = self.listDict["offer"]
        identlist = self.listDict["ident"]
        taglist = self.listDict["tags"]
        offer = MM_util.searchlistbyhash(offerlist, offerhash)
        vendor = MM_util.searchlistbyhash(identlist, offer.obj['vendorid'])

        offername = offer.obj['name']
        ratio = offer.obj['ratio']
        locktime = time.asctime(time.localtime(offer.obj['locktime']))
        minrep = offer.obj['minrep']
        desc = offer.obj['description']
        tags = []
        for tag in offer.obj['tags']:
            tags.append(MM_util.searchlistbyhash(taglist, tag))

        self.showViewOfferDlg(offername, vendor, ratio, locktime, minrep, desc,
                              tags)
Esempio n. 9
0
    def on_identViewButton_clicked(self):
        selection = self.identTableWidget.selectedItems()
        if not selection:
            return

        identlist = self.listDict["ident"]
        identhash = str(selection[2].text())
        ident = MM_util.searchlistbyhash(identlist, identhash)

        self.showViewIdentDlg(ident.obj['name'], identhash,
                              ident.obj['btcaddr'], ident.obj['bmaddr'])
Esempio n. 10
0
    def on_marketViewButton_clicked(self):
        selection = self.marketTableWidget.selectedItems()
        if not selection:
            return

        mktHash = str(selection[2].text())
        market = MM_util.searchlistbyhash(self.listDict["market"], mktHash)

        mktName = market.obj['marketname']
        regfee = market.obj['fee']
        burnmult = market.obj['multiplier']
        downvotemult = 0
        desc = market.obj['description']

        modident = MM_util.searchlistbyhash(self.listDict["ident"],
                                            market.obj['modid'])
        info = {"market": market, "modid": modident}
        mktjson = json.dumps(info, indent=4, sort_keys=True)

        self.showViewMarketDlg(mktName, regfee, burnmult, downvotemult, desc,
                               mktjson)
Esempio n. 11
0
    def importkeys(self, retries=0):
        if self.yorn("Bitcoin private key not found in wallet or "+\
                "Bitmessage identity does not exist. Import your "+\
                "BTC private key and create your BM ID?"):
            pass2 = self.input("Please re-enter your passphrase:",
                               password=True)
            if pass2 == self.passphrase:
                try:
                    MM_util.btcd.importprivkey(self.wif, self.username, False)
                except httplib.BadStatusLine:
                    MM_util.reconnect_btcd(retries)
                    return self.importkeys(retries + 1)

                self.info("REMEMBER TO SECURELY BACKUP YOUR wallet.dat file!")
                return True
            else:
                self.info("Passphrase did not match.")
                return False
        else:
            MM_util.bm.deleteAddress(self.bmaddr)
            return False
Esempio n. 12
0
    def setConfig(self, configTuple, retries=0):
        self.chain, self.channame, self.default_fee, self.minconf, \
            self.bmuser, self.bmpswd, self.bmhost, self.bmport, \
            self.btcuser, self.btcpswd, self.btchost, self.btcport = configTuple

        if self.chain == 'testnet':
            self.netcode = 'XTN'
            pob_address = "msj42CCGruhRsFrGATiUuh25dtxYtnpbTx"
        elif self.chain == 'mainnet':
            self.netcode = 'BTC'
            pob_address = "1METAMARKETxxxxxxxxxxxxxxxxx4TPjws"
        else:
            raise Exception("Config: chain must be either testnet or mainnet.")

        MM_util.connect_btcd(self.btcuser, self.btcpswd, self.btchost,
                             self.btcport)
        MM_util.connect_bm(self.bmuser, self.bmpswd, self.bmhost, self.bmport)
        MM_util.minconf = self.minconf
        MM_util.pob_address = pob_address

        try:
            self.chan_v3 = MM_util.bm.getDeterministicAddress(
                base64.b64encode(self.channame), 3, 1)
            self.chan_v4 = MM_util.bm.getDeterministicAddress(
                base64.b64encode(self.channame), 4, 1)
            self.feePerKB = MM_util.btcd.estimatefee(6)
        except socket.error:
            self.sockErr()
        except httplib.BadStatusLine:
            MM_util.reconnect_btcd(retries)
            return self.setConfig(configTuple, retries + 1)
Esempio n. 13
0
    def on_marketDeleteButton_clicked(self):
        selection = self.marketTableWidget.selectedItems()
        if not selection:
            return

        if not self.yorn("Are you sure?"):
            return

        mktHash = str(selection[2].text())
        market = self.searchlistbyhash(listDict["market"], mktHash)

        MM_util.MM_backupfile("market", market.hash)
        self.updateUi()
Esempio n. 14
0
    def importConfig(self):
        chain = self.config.get(self.section, 'chain')
        channame = self.config.get(self.section, 'channame')

        fee = MM_util.truncate(
            decimal.Decimal(self.config.get(self.section, 'fee')))
        minconf = self.config.getint(self.section, 'minconf')

        bmuser = self.config.get(self.section, 'bmuser')
        bmpswd = self.config.get(self.section, 'bmpswd')
        bmhost = self.config.get(self.section, 'bmhost')
        bmport = self.config.getint(self.section, 'bmport')

        btcuser = self.config.get(self.section, 'btcuser')
        btcpswd = self.config.get(self.section, 'btcpswd')
        btchost = self.config.get(self.section, 'btchost')
        btcport = self.config.getint(self.section, 'btcport')
        return ( chain, channame, fee, minconf, \
                bmuser, bmpswd, bmhost, bmport, \
                btcuser, btcpswd, btchost, btcport )
Esempio n. 15
0
    def on_offerOrderButton_clicked(self):
        selection = self.offerTableWidget.selectedItems()
        if not selection:
            return

        if not self.yorn("Are you sure?"):
            return

        offerlist = self.listDict["offer"]
        identlist = self.listDict["ident"]
        offer = MM_util.searchlistbyhash(offerlist, str(selection[4].text()))
        vendor = MM_util.searchlistbyhash(identlist, offer.obj['vendorid'])

        msgstr = MM_util.createorder( \
                    self.myid.hash, self.btcaddr, offer, self.pkstr, self.getFee() )
        hash = MM_util.MM_writefile(msgstr)
        MM_util.appendindex('order', hash)

        self.do_sendmsgviabm(vendor.obj['bmaddr'], msgstr)
        self.info("Order placed!")
Esempio n. 16
0
    def on_orderCancelButton_clicked(self):
        selection = self.orderTableWidget.selectedItems()
        if not selection:
            return

        index = self.indexFromOrderStatus()
        prevmsg = MM_util.searchlistbyhash(self.listDict[index],
                                           str(selection[4].text()))

        conf = None
        order = None
        if index == 'order':
            order = prevmsg
            for ver in self.listDict['conf']:
                if ver.obj['orderhash'] == order.hash:
                    conf = ver
        elif index == 'conf':
            conf = prevmsg
            order = MM_util.searchlistbyhash(self.listDict['order'],
                                             conf.obj['orderhash'])

        if conf:
            for ver in self.listDict['pay']:
                if ver.obj['confhash'] == conf.hash:
                    self.info("We cannot cancel this Order, " + \
                                "as a Payment has already been sent.")
                    return

        if not self.yorn("Are you sure?"):
            return

        msgstr = MM_util.createcancel(self.myid.hash, self.btcaddr, \
                                    "buyer", self.listDict['conf'], order)

        hash = MM_util.MM_writefile(msgstr)
        MM_util.appendindex('cancel', hash)

        self.do_sendmsgviabm(vendor.obj['bmaddr'], msgstr)
        self.info("Order cancellation message sent to Vendor!")
Esempio n. 17
0
 def do_offerfromordermsg(self, obj):
     return MM_util.offerfromordermsg(obj, self.listDict["offer"],
                                      self.listDict["order"],
                                      self.listDict["conf"],
                                      self.listDict["pay"],
                                      self.listDict["rec"])
Esempio n. 18
0
def savemsg(btc, name, msgstr):
    ver = MM_util.MM_loads(btc, msgstr)
    MM_util.MM_writefile(msgstr)
    MM_util.appendindex(name, ver.hash)
    return ver
Esempio n. 19
0
    return ver


mod_pkstr = pkstr("MM mod", """sr#hrAoe0S4]GCb8~J3>9"Hl$""")
vendor_pkstr = pkstr("MM vendor", """[OQ2zu%A|TFef5`!h|]BL""")
buyer_pkstr = pkstr("MM buyer", """W3}xa`XrHkoyZ9vHZ/'U{""")

mod_btc = btcaddr(mod_pkstr)
mod_bm = bmaddr(mod_pkstr)
vendor_btc = btcaddr(vendor_pkstr)
vendor_bm = bmaddr(vendor_pkstr)
buyer_btc = btcaddr(buyer_pkstr)
buyer_bm = bmaddr(buyer_pkstr)

# IDENT
msgstr = MM_util.createidentmsgstr(mod_btc, mod_bm, "MM mod")
mod = savemsg(mod_btc, 'ident', msgstr)
print mod

msgstr = MM_util.createidentmsgstr(vendor_btc, vendor_bm, "MM vendor")
vendor = savemsg(vendor_btc, 'ident', msgstr)
print vendor

msgstr = MM_util.createidentmsgstr(buyer_btc, buyer_bm, "MM buyer")
buyer = savemsg(buyer_btc, 'ident', msgstr)
print buyer

# TAG
msgstr = MM_util.createtagmsgstr( vendor_btc, vendor.hash, "Anything", \
                "The most useless tag of all! Can be ascribed to anything." )
tag = savemsg(vendor_btc, 'tags', msgstr)
Esempio n. 20
0
 def value_input(self, prompt):
     double, ok = QInputDialog.getDouble( \
             self, "Input Amount", prompt, decimals=8, min=0.00000001)
     if ok:
         return MM_util.truncate(decimal.Decimal(double))
Esempio n. 21
0
 def do_processinbox(self):
     return MM_util.processinbox(self.bmaddr,
                                 self.processMsg,
                                 processMkt=True)
Esempio n. 22
0
    def processMsg(self, msg):
        ver = MM_util.readmsg(msg)  # Verifies sig/hash

        if ver.msgname == MM_util.IDENT:
            MM_util.processident(msg, ver)
        elif ver.msgname == MM_util.TAG:
            MM_util.processtag(msg, ver)
        elif ver.msgname == MM_util.OFFER:
            MM_util.processoffer(msg, ver)
        elif ver.msgname == MM_util.CONF:
            MM_util.processconf(msg, ver)
        elif ver.msgname == MM_util.REC:
            MM_util.processrec(msg, ver)
        elif ver.msgname == MM_util.FEEDBACK:
            MM_util.processfeedback(msg, ver)
        elif ver.msgname == MM_util.CAST:
            MM_util.processcast(msg, ver)
        else:
            raise Exception("Someone sent us the wrong type of Msg.")

        return ver
Esempio n. 23
0
    def updateUi(self):
        #UPDATE MAINWINDOW UI WITH DATA FROM ALL DATA STRUCTURES
        if not self.loggedIn:
            return

        self.tabWidget.setEnabled(True)
        self.inbox = json.loads(
            MM_util.bm.getAllInboxMessages())['inboxMessages']

        chanMsgs = []
        for msg in self.inbox:
            subject = base64.b64decode(msg['subject'])
            if subject not in ('Msg', 'MultiMsg') and \
                    msg['toAddress'] in ( self.chan_v3, self.chan_v4 ):
                chanMsgs.append(msg)

        self.do_processinbox()
        self.loadLists()

        # Update 'Channel' Tab:
        self.chanGroupBox.setTitle("Channel: %s" % self.channame)
        # Join Chan if not already?
        numChanMsgs = len(chanMsgs)
        self.chanTableWidget.setRowCount(numChanMsgs)

        for i in range(numChanMsgs):
            subject = base64.b64decode(chanMsgs[i]['subject'])
            msgid = chanMsgs[i]['msgid']
            self.chanTableWidget.setItem(i, 0, QTableWidgetItem(subject))
            self.chanTableWidget.setItem(i, 1, QTableWidgetItem(msgid))

        # Update 'Markets' Tab:
        marketlist = self.listDict['market']
        numMarkets = len(marketlist)
        self.marketTableWidget.setRowCount(numMarkets)

        for i in range(numMarkets):
            self.marketTableWidget.setItem(
                i, 0, QTableWidgetItem(marketlist[i].obj['marketname']))
            self.marketTableWidget.setItem(
                i, 1, QTableWidgetItem(marketlist[i].obj['description']))
            self.marketTableWidget.setItem(
                i, 2, QTableWidgetItem(marketlist[i].hash))

        # Update 'Offers' Tab:
        if self.currentTag:
            self.offerGroupBox.setTitle( \
                    "Available Offers: Filtered for '%s'" % self.currentTag.obj['tagname'])
        else:
            self.offerGroupBox.setTitle("Available Offers:")
        self.populateMktBox(self.offerMktComboBox, self.searchText)

        if self.offerMktComboBox.count() <= 0:
            self.currentMarket = None

        if self.currentMarket:
            offerlist = self.listDict['offer']
            currentOffers = []

            for offer in offerlist:
                if offer.obj['markethash'] == self.currentMarket.hash:
                    if not self.currentTag or self.currentTag.hash in offer.obj[
                            'tags']:
                        currentOffers.append(offer)

            numOffers = len(currentOffers)
            self.offerTableWidget.setRowCount(numOffers)

            for i in range(numOffers):
                self.offerTableWidget.setItem(
                    i, 0, QTableWidgetItem(currentOffers[i].obj['name']))
                self.offerTableWidget.setItem(
                    i, 1, QTableWidgetItem(currentOffers[i].obj['locale']))
                self.offerTableWidget.setItem(
                    i, 2, QTableWidgetItem(currentOffers[i].obj['amount']))
                self.offerTableWidget.setItem(
                    i, 3, QTableWidgetItem(currentOffers[i].obj['price']))
                self.offerTableWidget.setItem(
                    i, 4, QTableWidgetItem(currentOffers[i].hash))
        else:
            self.offerTableWidget.clearContents()
            self.offerTableWidget.setRowCount(0)

        # Update 'Orders' Tab:
        index = self.indexFromOrderStatus()
        msgList = self.listDict[index]
        numMsgs = len(msgList)
        self.orderTableWidget.setRowCount(numMsgs)

        isCancelable = index in ('order', 'conf')
        self.orderCancelButton.setEnabled(isCancelable)

        for i in range(numMsgs):
            obj = msgList[i]
            msgstr = open(os.path.join('msg', obj.hash + '.dat'), 'r').read()
            offer = self.do_offerfromordermsg(obj)

            self.orderTableWidget.setItem(i, 0,
                                          QTableWidgetItem(offer.obj["name"]))
            self.orderTableWidget.setItem(
                i, 1, QTableWidgetItem(offer.obj["locale"]))
            self.orderTableWidget.setItem(
                i, 2, QTableWidgetItem(offer.obj["amount"]))
            self.orderTableWidget.setItem(i, 3,
                                          QTableWidgetItem(offer.obj["price"]))
            self.orderTableWidget.setItem(i, 4, QTableWidgetItem(obj.hash))
            self.orderTableWidget.setItem(i, 5, QTableWidgetItem(offer.hash))

        # Update 'Identities' Tab:
        self.setWindowTitle("METAbuyer-Qt [%s]" % self.username)
        self.identMyidLabel.setText("ID Hash: %s" % self.myid.hash)
        self.identBtcaddrLabel.setText("BTC Address: %s" % self.btcaddr)
        self.identBmaddrLabel.setText("BM Address: %s" % self.bmaddr)

        self.populateMktBox(self.identMktComboBox, self.searchText)

        if self.currentMarket:
            reglist = self.listDict['reg']
            registered = False
            for reg in reglist:
                if reg.obj['modid'] == self.currentMarket.obj['modid'] and \
                        reg.obj['userid'] == self.myid.hash:
                    registered = True
                    break
            self.identRegButton.setEnabled(not registered)
            self.identBurnButton.setEnabled(True)

            identlist = self.listDict['ident']
            numIdents = len(identlist)
            self.identTableWidget.setRowCount(numIdents)

            for i in range(numIdents):
                id = identlist[i]
                rep = MM_util.getrep(id.hash, decimal.Decimal(self.currentMarket.obj['multiplier']), \
                                        self.listDict['feedback'], self.listDict['burn'])

                self.identTableWidget.setItem(i, 0,
                                              QTableWidgetItem(id.obj['name']))
                self.identTableWidget.setItem(i, 1,
                                              QTableWidgetItem("%d" % rep))
                self.identTableWidget.setItem(i, 2, QTableWidgetItem(id.hash))
        else:
            self.identTableWidget.clearContents()
            self.identTableWidget.setRowCount(0)
            self.identRegButton.setEnabled(False)
            self.identBurnButton.setEnabled(False)
Esempio n. 24
0
 def do_sendmsgviabm(self, to_addr, msgstr, prompt=False, subject='Msg'):
     if not prompt or self.yorn(
             "Are you sure you want to send this Message?"):
         MM_util.sendmsgviabm(to_addr, self.bmaddr, msgstr, subject)
Esempio n. 25
0
    MM_util.appendindex(name, ver.hash)
    return ver

mod_pkstr = pkstr("MM mod", """sr#hrAoe0S4]GCb8~J3>9"Hl$""")
vendor_pkstr = pkstr("MM vendor", """[OQ2zu%A|TFef5`!h|]BL""")
buyer_pkstr = pkstr("MM buyer", """W3}xa`XrHkoyZ9vHZ/'U{""")

mod_btc = btcaddr(mod_pkstr)
mod_bm = bmaddr(mod_pkstr)
vendor_btc = btcaddr(vendor_pkstr)
vendor_bm = bmaddr(vendor_pkstr)
buyer_btc = btcaddr(buyer_pkstr)
buyer_bm = bmaddr(buyer_pkstr)

# IDENT
msgstr = MM_util.createidentmsgstr( mod_btc, mod_bm, "MM mod" )
mod = savemsg(mod_btc, 'ident', msgstr)
print mod

msgstr = MM_util.createidentmsgstr( vendor_btc, vendor_bm, "MM vendor" )
vendor = savemsg(vendor_btc, 'ident', msgstr)
print vendor

msgstr = MM_util.createidentmsgstr( buyer_btc, buyer_bm, "MM buyer" )
buyer = savemsg(buyer_btc, 'ident', msgstr)
print buyer

# TAG
msgstr = MM_util.createtagmsgstr( vendor_btc, vendor.hash, "Anything", \
                "The most useless tag of all! Can be ascribed to anything." )
tag = savemsg(vendor_btc, 'tags', msgstr)
Esempio n. 26
0
def savemsg( btc, name, msgstr ):
    ver = MM_util.MM_loads(btc, msgstr)
    MM_util.MM_writefile(msgstr)
    MM_util.appendindex(name, ver.hash)
    return ver
Esempio n. 27
0
    def on_orderProcessButton_clicked(self):
        selection = self.orderTableWidget.selectedItems()
        if not selection:
            return

        index = self.indexFromOrderStatus()
        prevmsg = MM_util.searchlistbyhash(self.listDict[index],
                                           str(selection[4].text()))
        offer = self.do_offerfromordermsg(prevmsg)
        vendor = MM_util.searchlistbyhash(self.listDict['ident'],
                                          prevmsg.obj['vendorid'])

        if index == 'conf':
            # Send pay based on this conf
            replyindex = 'pay'
            if not self.yorn("Are you sure?"):
                return

            for ver in self.listDict['pay']:
                if ver.obj['confhash'] == prevmsg.hash:
                    self.info("This Order is already Paid.")
                    return

            order = MM_util.searchlistbyhash(self.listDict['order'],
                                             prevmsg.obj['orderhash'])
            msgstr = MM_util.createpay(self.myid.hash, self.btcaddr, prevmsg,
                                       order, offer, self.getFee())

        elif index == 'rec':
            # Send final based on this rec
            replyindex = 'final'
            flag = self.yorn("Click Yes to Finalize this purchase, " + \
                                "or click No to collect the refund.")
            if not self.yorn("Are you sure?"):
                return

            for ver in self.listDict['final']:
                if ver.obj['rechash'] == prevmsg.hash:
                    self.info("This Order has already been Finalized.")
                    return

            price = decimal.Decimal(offer.obj['price'])
            msgstr = MM_util.createfinal(self.myid.hash, self.btcaddr, \
                                    flag, prevmsg, vendor, offer, price)

        elif index == 'final':
            # Send feedback based on this final
            replyindex = 'feedback'
            flag = self.yorn("Click Yes to give positive feedback on this purchase, " + \
                                "or click No to give negative feedback.")
            if not self.yorn("Are you sure?"):
                return

            for ver in self.listDict['feedback']:
                if ver.obj['finalhash'] == prevmsg.hash:
                    self.info("You've already given feedback on this Order.")
                    return

            message = self.input("Leave a message with your feedback.")
            order = None
            for ver in self.listDict['order']:
                if ver.obj['offerhash'] == offer.hash:
                    order = ver
                    break
            msgstr = MM_util.createfeedback(self.btcaddr, \
                                    "buyer", flag, message, prevmsg, offer, order)

        else:
            self.info("Buyers cannot process this type of message.")
            return

        hash = MM_util.MM_writefile(msgstr)
        MM_util.appendindex(replyindex, hash)

        self.do_sendmsgviabm(vendor.obj['bmaddr'], msgstr)
        self.info("Message sent to Vendor!")