def status(multi, identity, jobid): """ Show user info and active jobs. """ (log, user, key, urls) = init(multi, identity) Order.update_orders(rein, Document, get_user_documents) documents = get_user_documents(rein) if jobid is None: click.echo("User: %s" % user.name) click.echo("Master bitcoin address: %s" % user.maddr) click.echo("Delegate bitcoin address: %s" % user.daddr) click.echo("Delegate public key: %s" % key) click.echo("Willing to mediate: %s" % user.will_mediate) if user.will_mediate: click.echo("Mediator fee: %s %%" % user.mediator_fee) click.echo("Total document count: %s" % len(documents)) click.echo("Registered servers: ") for url in urls: click.echo(" " + url) click.echo("Testnet: %s" % PersistConfig.get_testnet(rein)) click.echo('') click.echo('ID Job ID Status') click.echo('-----------------------------------------------------') orders = Order.get_user_orders(rein, Document) for order in orders: past_tense = order.get_past_tense(order.get_state(rein, Document)) click.echo("%s %s %s" % (order.id, order.job_id, past_tense)) else: order = Order.get_by_job_id(rein, jobid) documents = order.get_documents(rein, Document) for document in documents: click.echo("\n" + document.contents)
def status(multi, identity, jobid): """ Show user info and active jobs. """ (log, user, key, urls) = init(multi, identity) Order.update_orders(rein, Document, Document.get_user_documents) documents = Document.get_user_documents(rein) if jobid is None: click.echo("User: %s" % user.name) click.echo("Master bitcoin address: %s" % user.maddr) click.echo("Delegate bitcoin address: %s" % user.daddr) click.echo("Delegate public key: %s" % key) click.echo("Willing to mediate: %s" % user.will_mediate) if user.will_mediate: click.echo("Mediator fee: %s %%" % user.mediator_fee) click.echo("Total document count: %s" % len(documents)) click.echo("Registered servers: ") for url in urls: click.echo(" " + url) click.echo("Testnet: %s" % PersistConfig.get_testnet(rein)) click.echo('') click.echo('ID Job ID Status') click.echo('-----------------------------------------------------') orders = Order.get_user_orders(rein, Document) for order in orders: past_tense = order.get_past_tense(order.get_state(rein, Document)) click.echo("%s %s %s" % (order.id, order.job_id, past_tense)) else: remote_documents = [] for url in urls: log.info("Querying %s for job id %s..." % (url, jobid)) sel_url = "{0}query?owner={1}&query=by_job_id&job_ids={2}&testnet={3}" try: answer = requests.get( url=sel_url.format(url, user.maddr, jobid, rein.testnet)) except: click.echo('Error connecting to server.') log.error('server connect error ' + url) continue data = answer.json() remote_documents += filter_and_parse_valid_sigs( rein, data['by_job_id']) unique_documents = unique(remote_documents) for doc in remote_documents: click.echo(doc) if len(remote_documents) == 0: order = Order.get_by_job_id(rein, jobid) if order: documents = order.get_documents(rein, Document) for document in documents: click.echo("\n" + document.contents) else: click.echo("Job id not found")
def status(multi, identity, jobid): """ Show user info and active jobs. """ (log, user, key, urls) = init(multi, identity) Order.update_orders(rein, Document, Document.get_user_documents) documents = Document.get_user_documents(rein) if jobid is None: click.echo("User: %s" % user.name) click.echo("Master bitcoin address: %s" % user.maddr) click.echo("Delegate bitcoin address: %s" % user.daddr) click.echo("Delegate public key: %s" % key) click.echo("Willing to mediate: %s" % user.will_mediate) if user.will_mediate: click.echo("Mediator fee: %s %%" % user.mediator_fee) click.echo("Total document count: %s" % len(documents)) click.echo("Registered servers: ") for url in urls: click.echo(" " + url) click.echo("Testnet: %s" % PersistConfig.get_testnet(rein)) click.echo('') click.echo('ID Job ID Status') click.echo('-----------------------------------------------------') orders = Order.get_user_orders(rein, Document) for order in orders: past_tense = order.get_past_tense(order.get_state(rein, Document)) click.echo("%s %s %s" % (order.id, order.job_id, past_tense)) else: remote_documents = [] for url in urls: log.info("Querying %s for job id %s..." % (url, jobid)) sel_url = "{0}query?owner={1}&query=by_job_id&job_ids={2}&testnet={3}" try: answer = requests.get(url=sel_url.format(url, user.maddr, jobid, rein.testnet)) except: click.echo('Error connecting to server.') log.error('server connect error ' + url) continue data = answer.json() remote_documents += filter_and_parse_valid_sigs(rein, data['by_job_id']) unique_documents = unique(remote_documents) for doc in remote_documents: click.echo(doc) if len(remote_documents) == 0: order = Order.get_by_job_id(rein, jobid) if order: documents = order.get_documents(rein, Document) for document in documents: click.echo("\n" + document.contents) else: click.echo("Job id not found")
def accept(multi, identity, defaults, dry_run): """ Accept a delivery. Review and accept deliveries for your jobs. Once a delivery is accpted, mediators are advised not to sign any tranasctions refunding the job creator. """ (log, user, key, urls) = init(multi, identity) form = {} if defaults: form = parse_document(open(defaults).read()) if 'Title' in form and form['Title'] != 'Rein Accept Delivery': return click.echo("Input file type: " + form['Title']) store = False if dry_run else True Order.update_orders(rein, Document, Document.get_user_documents) documents = [] orders = Order.get_user_orders(rein, Document) for order in orders: state = order.get_state(rein, Document) if state in ['offer', 'delivery']: # get parsed offer for this order and put it in an array documents += order.get_documents(rein, Document, state) contents = [] for document in documents: contents.append(document.contents) valid_results = filter_and_parse_valid_sigs(rein, contents) our_orders = [] for res in valid_results: if res['Job creator public key'] == key: order = Order.get_by_job_id(rein, res['Job ID']) res['state'] = order.get_state(rein, Document) our_orders.append(res) if len(our_orders) == 0: click.echo('None found') return if 'Job ID' in form.keys(): doc = select_by_form(our_orders, 'Job ID', form) else: doc = accept_prompt(rein, our_orders, "Deliverables") if not doc: return log.info('got delivery for accept') fields = [ {'label': 'Job name', 'value_from': doc}, {'label': 'Job ID', 'value_from': doc}, {'label': 'Signed primary payment', 'not_null': form}, {'label': 'Signed mediator payment', 'not_null': form}, {'label': 'Primary escrow redeem script', 'value_from': doc}, {'label': 'Mediator escrow redeem script', 'value_from': doc}, ] document = assemble_document('Accept Delivery', fields) click.echo('\n'+document+'\n') if click.confirm("Are you sure?"): res = sign_and_store_document(rein, 'accept', document, user.daddr, user.dkey, store) if res and store: click.echo("Accepted delivery. Run 'rein sync' to push to available servers.") log.info('accept signed') if res else log.error('accept failed') else: click.echo("Accept aborted.")
def offer(multi, identity, defaults, dry_run): """ Award a job. A job creator would use this command to award the job to a specific bid. Once signed and pushed, escrow addresses should be funded and work can begin. """ (log, user, key, urls) = init(multi, identity) form = {} if defaults: form = parse_document(open(defaults).read()) if 'Title' in form and form['Title'] != 'Rein Offer': return click.echo("Input file type: " + form['Title']) store = False if dry_run else True bids = [] for url in urls: log.info("Querying %s for bids on your jobs..." % url) sel_url = "{0}query?owner={1}&delegate={2}&query=bids&testnet={3}" try: answer = requests.get(url=sel_url.format(url, user.maddr, user.daddr, rein.testnet)) except: click.echo('Error connecting to server.') log.error('server connect error ' + url) continue data = answer.json() bids += filter_and_parse_valid_sigs(rein, data['bids']) unique_bids = unique(bids, 'Description') bids = [] for bid in unique_bids: order = Order.get_by_job_id(rein, bid['Job ID']) if not order: order = Order(bid['Job ID'], testnet=rein.testnet) rein.session.add(order) rein.session.commit() state = order.get_state(rein, Document) if state in ['bid', 'job_posting']: bids.append(bid) if len(bids) == 0: click.echo('None found') return if 'Worker public key' in form.keys(): bid = select_by_form([bid], 'Worker public key', form) else: bid = bid_prompt(rein, bids) if not bid: return log.info('got bid to offer') fields = [ {'label': 'Job name', 'value_from': bid}, {'label': 'Worker', 'value_from': bid}, {'label': 'Description', 'value_from': bid}, {'label': 'Bid amount (BTC)', 'value_from': bid}, {'label': 'Primary escrow address', 'value_from': bid}, {'label': 'Mediator escrow address', 'value_from': bid}, {'label': 'Job ID', 'value_from': bid}, {'label': 'Job creator', 'value_from': bid}, {'label': 'Job creator public key', 'value_from': bid}, {'label': 'Mediator public key', 'value_from': bid}, {'label': 'Worker public key', 'value_from': bid}, {'label': 'Primary escrow redeem script', 'value_from': bid}, {'label': 'Mediator escrow redeem script', 'value_from': bid}, ] document = assemble_document('Offer', fields) if not click.confirm('Are you sure you want to award this bid?'): return res = sign_and_store_document(rein, 'offer', document, user.daddr, user.dkey, store) if res and store: click.echo("Two funding addresses and corresponding redeem scripts have been created for\n" "this job. When it is time to distribute payment, you would use the redeem\n" "script and a tool like Rein's modified version of Coinb.in to build and sign\n" "payment transactions. As long as there is no dispute, the job creator would\n" "sign a transaction paying the worker all funds held by the primary escrow\n" "address and the mediator all funds held by the mediator escrow address.\n") click.echo("Offer created. Run 'rein sync' to push to available servers.") log.info('offer signed') if res else log.error('offer failed')
def bid(multi, identity, defaults, dry_run): """ Bid on a job. Choose from available jobs posted to your registered servers your client knows about, and create a bid. Your bid should include the amount of Bitcoin you need to complete the job and when you expect to have it complete. """ (log, user, key, urls) = init(multi, identity) form = {} if defaults: form = parse_document(open(defaults).read()) if 'Title' in form and form['Title'] != 'Rein Bid': return click.echo("Input file type: " + form['Title']) store = False if dry_run else True jobs = [] for url in urls: log.info("Querying %s for jobs..." % url) sel_url = "{0}query?owner={1}&query=jobs&testnet={2}" try: answer = requests.get(url=sel_url.format(url, user.maddr, rein.testnet)) except: click.echo('Error connecting to server.') log.error('server connect error ' + url) continue data = answer.json() jobs += filter_and_parse_valid_sigs(rein, data['jobs']) unique_jobs = unique(jobs, 'Job ID') jobs = [] for job in unique_jobs: order = Order.get_by_job_id(rein, job['Job ID']) if not order: order = Order(job['Job ID'], testnet=rein.testnet) rein.session.add(order) rein.session.commit() state = order.get_state(rein, Document) if state in ['job_posting', 'bid']: jobs.append(job) if len(jobs) == 0: click.echo('None found') return if 'Job ID' in form.keys(): job = select_by_form(jobs, 'Job ID', form) else: job = job_prompt(rein, jobs) if not job: return log.info('got job for bid') primary_redeem_script, primary_addr = build_2_of_3([job['Job creator public key'], job['Mediator public key'], key]) mediator_redeem_script, mediator_escrow_addr = build_mandatory_multisig(job['Mediator public key'], [job['Job creator public key'],key]) fields = [ {'label': 'Job name', 'value_from': job}, {'label': 'Worker', 'value': user.name}, {'label': 'Worker contact', 'value': user.contact}, {'label': 'Description', 'not_null': form}, {'label': 'Bid amount (BTC)', 'not_null': form}, {'label': 'Primary escrow address', 'value': primary_addr}, {'label': 'Mediator escrow address', 'value': mediator_escrow_addr}, {'label': 'Job ID', 'value_from': job}, {'label': 'Job creator', 'value_from': job}, {'label': 'Job creator public key', 'value_from': job}, {'label': 'Mediator public key', 'value_from': job}, {'label': 'Worker public key', 'value': key}, {'label': 'Primary escrow redeem script', 'value': primary_redeem_script}, {'label': 'Mediator escrow redeem script', 'value': mediator_redeem_script}, ] document = assemble_document('Bid', fields) res = sign_and_store_document(rein, 'bid', document, user.daddr, user.dkey, store) if res and store: click.echo("Bid created. Run 'rein sync' to push to available servers.") log.info('bid signed') if res else log.error('bid failed')
def offer(multi, identity, defaults, dry_run): """ Award a job. A job creator would use this command to award the job to a specific bid. Once signed and pushed, escrow addresses should be funded and work can begin. """ (log, user, key, urls) = init(multi, identity) form = {} if defaults: form = parse_document(open(defaults).read()) if 'Title' in form and form['Title'] != 'Rein Offer': return click.echo("Input file type: " + form['Title']) store = False if dry_run else True bids = [] for url in urls: log.info("Querying %s for bids on your jobs..." % url) sel_url = "{0}query?owner={1}&delegate={2}&query=bids&testnet={3}" try: answer = requests.get( url=sel_url.format(url, user.maddr, user.daddr, rein.testnet)) except: click.echo('Error connecting to server.') log.error('server connect error ' + url) continue data = answer.json() bids += filter_and_parse_valid_sigs(rein, data['bids']) unique_bids = unique(bids, 'Description') bids = [] for bid in unique_bids: order = Order.get_by_job_id(rein, bid['Job ID']) if not order: order = Order(bid['Job ID'], testnet=rein.testnet) rein.session.add(order) rein.session.commit() state = order.get_state(rein, Document) if state in ['bid', 'job_posting']: bids.append(bid) if len(data['bids']) == 0: click.echo('None found') if 'Worker public key' in form.keys(): bid = select_by_form([bid], 'Worker public key', form) else: bid = bid_prompt(rein, bids) if not bid: click.echo('None chosen') return log.info('got bid to offer') fields = [ { 'label': 'Job name', 'value_from': bid }, { 'label': 'Worker', 'value_from': bid }, { 'label': 'Description', 'value_from': bid }, { 'label': 'Bid amount (BTC)', 'value_from': bid }, { 'label': 'Primary escrow address', 'value_from': bid }, { 'label': 'Mediator escrow address', 'value_from': bid }, { 'label': 'Job ID', 'value_from': bid }, { 'label': 'Job creator', 'value_from': bid }, { 'label': 'Job creator public key', 'value_from': bid }, { 'label': 'Mediator public key', 'value_from': bid }, { 'label': 'Worker public key', 'value_from': bid }, { 'label': 'Primary escrow redeem script', 'value_from': bid }, { 'label': 'Mediator escrow redeem script', 'value_from': bid }, ] document = assemble_document('Offer', fields) if not click.confirm('Are you sure you want to award this bid?'): return res = sign_and_store_document(rein, 'offer', document, user.daddr, user.dkey, store) if res and store: click.echo( "Offer created. Run 'rein sync' to push to available servers.") log.info('offer signed') if res else log.error('offer failed')
def bid(multi, identity, defaults, dry_run): """ Bid on a job. Choose from available jobs posted to your registered servers your client knows about, and create a bid. Your bid should include the amount of Bitcoin you need to complete the job and when you expect to have it complete. """ (log, user, key, urls) = init(multi, identity) form = {} if defaults: form = parse_document(open(defaults).read()) if 'Title' in form and form['Title'] != 'Rein Bid': return click.echo("Input file type: " + form['Title']) store = False if dry_run else True jobs = [] for url in urls: log.info("Querying %s for jobs..." % url) sel_url = "{0}query?owner={1}&query=jobs&testnet={2}" try: answer = requests.get( url=sel_url.format(url, user.maddr, rein.testnet)) except: click.echo('Error connecting to server.') log.error('server connect error ' + url) continue data = answer.json() jobs += filter_and_parse_valid_sigs(rein, data['jobs']) unique_jobs = unique(jobs, 'Job ID') jobs = [] for job in unique_jobs: order = Order.get_by_job_id(rein, job['Job ID']) if not order: order = Order(job['Job ID'], testnet=rein.testnet) rein.session.add(order) rein.session.commit() state = order.get_state(rein, Document) if state in ['job_posting', 'bid']: jobs.append(job) if len(jobs) == 0: click.echo('None found') return if 'Job ID' in form.keys(): job = select_by_form(jobs, 'Job ID', form) else: job = job_prompt(rein, jobs) if not job: return log.info('got job for bid') primary_redeem_script, primary_addr = build_2_of_3( [job['Job creator public key'], job['Mediator public key'], key]) mediator_redeem_script, mediator_escrow_addr = build_mandatory_multisig( job['Mediator public key'], [job['Job creator public key'], key]) fields = [ { 'label': 'Job name', 'value_from': job }, { 'label': 'Worker', 'value': user.name }, { 'label': 'Description', 'not_null': form }, { 'label': 'Bid amount (BTC)', 'not_null': form }, { 'label': 'Primary escrow address', 'value': primary_addr }, { 'label': 'Mediator escrow address', 'value': mediator_escrow_addr }, { 'label': 'Job ID', 'value_from': job }, { 'label': 'Job creator', 'value_from': job }, { 'label': 'Job creator public key', 'value_from': job }, { 'label': 'Mediator public key', 'value_from': job }, { 'label': 'Worker public key', 'value': key }, { 'label': 'Primary escrow redeem script', 'value': primary_redeem_script }, { 'label': 'Mediator escrow redeem script', 'value': mediator_redeem_script }, ] document = assemble_document('Bid', fields) res = sign_and_store_document(rein, 'bid', document, user.daddr, user.dkey, store) if res and store: click.echo( "Bid created. Run 'rein sync' to push to available servers.") log.info('bid signed') if res else log.error('bid failed')
def accept(multi, identity, defaults, dry_run): """ Accept a delivery. Review and accept deliveries for your jobs. Once a delivery is accpted, mediators are advised not to sign any tranasctions refunding the job creator. """ (log, user, key, urls) = init(multi, identity) form = {} if defaults: form = parse_document(open(defaults).read()) if 'Title' in form and form['Title'] != 'Rein Accept Delivery': return click.echo("Input file type: " + form['Title']) store = False if dry_run else True Order.update_orders(rein, Document, Document.get_user_documents) documents = [] orders = Order.get_user_orders(rein, Document) for order in orders: state = order.get_state(rein, Document) if state in ['offer', 'delivery']: # get parsed offer for this order and put it in an array documents += order.get_documents(rein, Document, state) contents = [] for document in documents: contents.append(document.contents) valid_results = filter_and_parse_valid_sigs(rein, contents) our_orders = [] for res in valid_results: if res['Job creator public key'] == key: order = Order.get_by_job_id(rein, res['Job ID']) res['state'] = order.get_state(rein, Document) our_orders.append(res) if len(our_orders) == 0: click.echo('None found') return if 'Job ID' in form.keys(): doc = select_by_form(our_orders, 'Job ID', form) else: doc = accept_prompt(rein, our_orders, "Deliverables") if not doc: return log.info('got delivery for accept') fields = [ { 'label': 'Job name', 'value_from': doc }, { 'label': 'Job ID', 'value_from': doc }, { 'label': 'Signed primary payment', 'not_null': form }, { 'label': 'Signed mediator payment', 'not_null': form }, { 'label': 'Primary escrow redeem script', 'value_from': doc }, { 'label': 'Mediator escrow redeem script', 'value_from': doc }, ] document = assemble_document('Accept Delivery', fields) click.echo('\n' + document + '\n') if click.confirm("Are you sure?"): res = sign_and_store_document(rein, 'accept', document, user.daddr, user.dkey, store) if res and store: click.echo( "Accepted delivery. Run 'rein sync' to push to available servers." ) log.info('accept signed') if res else log.error('accept failed') else: click.echo("Accept aborted.")