Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
a51a3cd
first try for json format for docs
Mar 21, 2017
4301f30
fix return value of parse_sigs
Mar 21, 2017
6891e0c
deal with ratings in json
Mar 22, 2017
99c62a5
fix bugs with handling json
Mar 22, 2017
4245422
use json for enrollment documents
Mar 25, 2017
bc80c7c
handle case of no job id in document
Mar 25, 2017
5db8ae8
fix willing to mediate value
Mar 25, 2017
90e33eb
put testnet support for multisig address generation
Mar 25, 2017
545377a
undo last change
Mar 25, 2017
05d18eb
enable backwards compatibility for ratings doc format
Mar 27, 2017
41e436a
first try for unique address generation
Mar 29, 2017
5cd52f1
touch up some things
Mar 29, 2017
2e9358d
fix small bugs
Apr 1, 2017
9402af5
fix more bugs
Apr 2, 2017
66b7777
fix the offer handler
Apr 2, 2017
e6be284
save privkeys for escrow and wallet
Apr 4, 2017
a3634e4
fix reference to Wallet in pubkeys.py
Apr 4, 2017
b43008a
fix wallet class
Apr 5, 2017
6796444
create pubkeys and wallet tables
Apr 5, 2017
db8b5f8
prepare wallet feature
Apr 8, 2017
c285a62
keep track of job id in wallet
Apr 8, 2017
103d0c3
prepare for withdrawl transaction
Apr 8, 2017
19fd0fa
finish up wallet feature
Apr 9, 2017
671ded0
fix payments for disputes
Apr 9, 2017
850fc7f
enable fresh addresses/pubkeys in cli mode
Apr 9, 2017
435cf68
fix typos
Apr 9, 2017
a34768d
fix bugs
Apr 9, 2017
3907f40
Search box and set up for api call
chbeltz Mar 15, 2017
bd371d5
Get user data from server
chbeltz Mar 16, 2017
5eb2062
Display search results
chbeltz Mar 17, 2017
62139e8
Table sorting
chbeltz Mar 18, 2017
4095a0c
Use local database for ratings data instead of server
chbeltz Mar 18, 2017
74e5522
Search by hitting enter
chbeltz Mar 18, 2017
d87d8ea
Fixed simple rating data collection
chbeltz Mar 19, 2017
8d07e7b
Pull trust score data from server
chbeltz Mar 19, 2017
b47fa60
Round ratings and trust scores
chbeltz Mar 19, 2017
ac44a3a
Merge remote-tracking branch 'upstream/master'
chbeltz Mar 22, 2017
d9b07d9
Fix issue with outdated enrollments still in the database
chbeltz Mar 22, 2017
09c7c2e
merge with master
Apr 10, 2017
4fa0a4a
revert
Apr 10, 2017
63a0d14
fix port and webbrowser display
Apr 10, 2017
4110c1c
enable multi user wallet and pubkeys
Apr 11, 2017
ab710fd
fix multi user wallet feature
Apr 11, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
287 changes: 209 additions & 78 deletions rein/cli.py

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions rein/html/js/wallet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
function postError(data) {
if (data != 'true') {
alert('Error withdrawing.')
} else {
alert('Withdrawl succeeded. Please allow some time for it to confirm.')
}
}

function withdraw_from_job(job_id) {
var amount = $('#withdraw_amount_'+job_id).val();
var destaddr = $('#withdraw_address_'+job_id).val();
$.ajax({
method: "POST",
url: "/withdraw",
contentType: "application/json",
data: JSON.stringify({
'job': job_id,
'amount': amount,
'addr': destaddr
}),
success: function(data) {
postError(data);
}
})
}
18 changes: 12 additions & 6 deletions rein/html/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,18 @@
<span class="hidden-xs">Rate</span>
</a></li>
</li>
<li>
<li><a href="/settings">
<i class="fa fa-cog"></i>
<span class="hidden-xs">Settings</span>
</a></li>
</li>
<li>
<li><a href="/settings">
<i class="fa fa-cog"></i>
<span class="hidden-xs">Settings</span>
</a></li>
</li>
<li>
<li><a href="/wallet">
<i class="fa fa-btc"></i>
<span class="hidden-xs">Wallet</span>
</a></li>
</li>
</ul>
</div>
<!--Start Content-->
Expand Down
55 changes: 55 additions & 0 deletions rein/html/wallet.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{% extends "layout.html" %}
{% from "_form_helpers.html" import render_error %}
{% block body %}

<script src="/js/wallet.js"></script>

<br>
<div class="well">
<h2>Wallet</h2>
<br />
Overall Balance: {{balance}}
<br />
{% if txs %}
{% for txj in txs %}
<br /><br />
<h3>Unspent Payments for Job <a href="/job/{{txj.ref}}">{{txj.ref}}</a></h3>
{% if txj.txs %}
<table class="table m-table table-bordered table-hover table-heading">
<thead>
<th class="col-md-5">txid</th>
<th>value</th>
</thead>
<tbody>
{% for tx in txj.txs %}
<tr>
<td class="col-md-5"><a href="{{explorer}}/tx/{{tx.txid}}">{{tx.txid}}</a></td>
<td>{{tx.value}}</td>
</tr>
{% endfor %}
</tbody>
</table>
<form onsubmit="withdraw_from_job('{{txj.ref}}'); return false;" class="form-inline">
<h4>&emsp;Withdraw from this job's payments</h4>
<div class="form-group">
&emsp;<label for="withdraw_amount" class="control-label">Amount (BTC):</label>
<input type="text" name="withdraw_amount" id="withdraw_amount_{{txj.ref}}" pattern="[0-9.]{1,10}" value="" style="width:100px;">
</div>
<div class="form-group">
&emsp;<label for="withdraw_address" class="control-label">Address:</label>
<input type="text" name="withdraw_address" id="withdraw_address_{{txj.ref}}" value="{{withdraw_amount}}" style="width:300px;">
</div>
<div class="form-group">
&emsp;<input type="submit" value="Withdraw"/>
</div>
</form>
{% else %}
None found.
{% endif %}
{% endfor %}
{% else %}
<p>No transactions.</p>
{% endif %}
</div>

{% endblock %}
36 changes: 36 additions & 0 deletions rein/lib/crypto/bip32.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import hmac
import os
import rein.lib.config as config
from rein.lib.wallet import Wallet
from rein.lib.persistconfig import PersistConfig

# TODO Make Python index this file automatically
script_dir = os.path.dirname(__file__)
Expand Down Expand Up @@ -86,3 +88,37 @@ def get_delegate_extended_key(mxprv):
delegate_key = get_delegate_key(mxprv)
return delegate_key.ExtendedKey()

def generate_new_payment_address(dxprv,i):
parent_key = get_child_key(dxprv, 0+BIP32_HARDEN)
subparent_key = get_child_key(parent_key,i)
target_key = get_child_key(subparent_key,0)
return (target_key.Address(),target_key.WalletImportFormat())

def generate_new_escrow_pubkey(dxprv,i):
parent_key = get_child_key(dxprv, 1+BIP32_HARDEN)
subparent_key = get_child_key(parent_key,i)
target_key = get_child_key(subparent_key,0)
return (hexlify(target_key.PublicKey()),target_key.WalletImportFormat())

def from_xprv(xkey):
return BIP32Key.fromExtendedKey(xkey)

def get_new_change_address(dxprv,ref):
wallet_entries = rein.session.query(Wallet).filter(Wallet.ref == ref).all()
j = len(wallet_entries)
print("j = "+str(j))
if j > 0:
parent_key = get_child_key(dxprv,0+BIP32_HARDEN)
next_addr_index = int(PersistConfig.get(rein, 'next_addr_index'))
for i in range(next_addr_index):
subparent_key = get_child_key(parent_key,i)
target_key_address = get_child_key(subparent_key,0).Address()
for we in wallet_entries:
wallet_address = we.address
if wallet_address == target_key_address:
change_key = get_child_key(subparent_key,j)
change_key_address = change_key.Address()
change_key_privkey = change_key.WalletImportFormat()
Wallet.set(rein,change_key_address,change_key_privkey,ref=ref)
return change_key_address
return None
18 changes: 13 additions & 5 deletions rein/lib/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from .order import Order
from .io import safe_get
from .util import document_to_dict
import json

Base = declarative_base()

Expand Down Expand Up @@ -106,11 +107,18 @@ def get_documents_by_job_id(rein, url, job_id):

@staticmethod
def get_job_id(text):
m = re.search('Job ID: (.+)\n', text)
if m:
return m.group(1)
else:
return None
try:
json_object = json.loads(text)
if "Job ID" in json_object:
return json_object["Job ID"]
else:
return None
except ValueError, e:
m = re.search('Job ID: (.+)\n', text)
if m:
return m.group(1)
else:
return None

@staticmethod
def get_document_type(document):
Expand Down
19 changes: 10 additions & 9 deletions rein/lib/market.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from sqlalchemy import and_
import os
import click

import json

def assemble_document(title, fields):
"""
Expand Down Expand Up @@ -35,11 +35,12 @@ def assemble_document(title, fields):
else:
entry['value'] = click.prompt(prompt)
data.append(entry)
document = "Rein %s\n" % title
for entry in data:
document = document + entry['label'] + ": " + entry['value'] + "\n"
return document[:-1]

document = {}
document['Title'] = "Rein %s" % title
for entry in data:
document[entry['label']] = entry['value']
return json.dumps(document,sort_keys=True)

def sign_and_store_document(rein, doc_type, document, signature_address=None, signature_key=None, store=True, overwrite_hash=None):
"""
Expand Down Expand Up @@ -67,10 +68,10 @@ def sign_and_store_document(rein, doc_type, document, signature_address=None, si

if validated:
# insert signed document into documents table
b = "-----BEGIN BITCOIN SIGNED MESSAGE-----"
c = "-----BEGIN SIGNATURE-----"
d = "-----END BITCOIN SIGNED MESSAGE-----"
signed = "%s\n%s\n%s\n%s\n%s\n%s" % (b, document, c, signature_address, signature, d)
document_json = json.loads(document)
document_json["signature_address"] = signature_address
document_json["signature"] = signature
signed = json.dumps(document_json,sort_keys=True)
click.echo('\n' + signed + '\n')
# If document doesn't already exist, create
if store and not overwrite_hash:
Expand Down
6 changes: 6 additions & 0 deletions rein/lib/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,10 @@
from .hidden_content import Base
Base.metadata.create_all(engine)

from .pubkeys import Base
Base.metadata.create_all(engine)

from .wallet import Base
Base.metadata.create_all(engine)

log.info('database tables updated')
38 changes: 38 additions & 0 deletions rein/lib/pubkeys.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from sqlalchemy import Column, Integer, String, DateTime
from sqlalchemy.ext.declarative import declarative_base
import click

Base = declarative_base()

class Pubkeys(Base):
__tablename__ = 'pubkeys'

pubkey = Column(String(34), primary_key=True)
privkey = Column(String(52))
userid = Column(Integer)

def __init__(self, session, pubkey, privkey, userid=None):
self.pubkey = pubkey
self.privkey = privkey
self.userid = userid
session.add(self)
session.commit()

@classmethod
def get(self, rein, pubkey, default=False):
res = rein.session.query(Pubkeys).filter(Pubkeys.pubkey == pubkey).first()
if res:
return res.privkey
else:
return default

@classmethod
def set(self, rein, pubkey, privkey='', userid=None):
res = rein.session.query(Pubkeys).filter(Pubkeys.pubkey == pubkey).first()
if res:
res.privkey = privkey
if userid is not None:
res.userid = userid
rein.session.commit()
else:
p = Pubkeys(rein.session, pubkey, privkey=privkey, userid=userid)
44 changes: 28 additions & 16 deletions rein/lib/rating.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from .order import Order, STATE
from .document import Document
from .bitcoinaddress import generate_sin
from sqlalchemy import and_
from sqlalchemy import and_, or_
import json

def get_job_info(rein, order):
Expand Down Expand Up @@ -78,30 +78,44 @@ def get_user_jobs(rein, return_dict=False):
return json.dumps(job_list)

def rating_identifier(fields):
"""Generates a string that would be found in the contents of an existing rating document"""
identifier = ''
relevant_fields = ['User msin', 'Job id', 'Rater msin']
for field in fields:
if field['label'] in relevant_fields:
identifier += field['label'] + ": " + field['value'] + "\n"

return identifier
"""Generates a string that would be found in the contents of an existing rating document"""
identifier = ''
relevant_fields = ['User msin', 'Job id', 'Rater msin']
for field in fields:
if field['label'] in relevant_fields:
identifier += '"'+field['label']+'": "'+field['value']+'"%'
return identifier

def rating_identifier_old(fields):
identifier = ''
relevant_fields = ['User msin', 'Job id', 'Rater msin']
for field in fields:
if field['label'] in relevant_fields:
identifier += field['label'] + ": " + field['value'] + "\n"
return identifier

def add_rating(rein, user, testnet, rating, user_msin, job_id, rated_by_msin, comments):
"""Adds a rating to the database or updates it if an already existing
rating is adjusted"""
fields = [
{'label': 'Rating', 'value': rating},
{'label': 'User msin', 'value': user_msin},
{'label': 'Job id', 'value': job_id},
{'label': 'Rater msin', 'value': rated_by_msin},
{'label': 'Comments', 'value': comments},
{'label': 'User msin', 'value': user_msin},
{'label': 'Comments', 'value': comments}
]
fields_old = [
{'label': 'Rating', 'value': rating},
{'label': 'User msin', 'value': user_msin},
{'label': 'Job id', 'value': job_id},
{'label': 'Rater msin', 'value': rated_by_msin},
{'label': 'Comments', 'value': comments}
]

document_text = assemble_document('Rating', fields)
update_identifier = rating_identifier(fields)
look_for = '%\n{}%'.format(update_identifier)
update_rating = rein.session.query(Document).filter(and_(Document.testnet == testnet, Document.contents.like(look_for), Document.doc_type == 'rating')).first()
look_for = '%{}'.format(rating_identifier(fields))
look_for_old = '%{}'.format(rating_itentifier_old(fields_old))
update_rating = rein.session.query(Document).filter(and_(Document.testnet == testnet, or_(Document.contents.like(look_for),Document.contents.like(look_for_old)), Document.doc_type == 'rating')).first()

store = True
document = None
Expand Down Expand Up @@ -203,7 +217,6 @@ def calculate_trust_score(dest_msin=None, source_msin=None, rein=None, test=Fals

data = [rating['value'] for rating in raw_data]
ratings_by_source = filter_and_parse_valid_sigs(rein, data)

else:
ratings_by_source = [test_rating for test_rating in test_ratings if test_rating['Rater msin'] == 'SourceMsin']

Expand Down Expand Up @@ -234,7 +247,6 @@ def calculate_trust_score(dest_msin=None, source_msin=None, rein=None, test=Fals

data = [rating['value'] for rating in raw_data]
dest_ratings_by_vouched_user = filter_and_parse_valid_sigs(rein, data)

else:
dest_ratings_by_vouched_user = [test_rating for test_rating in test_ratings if test_rating['Rater msin'] == vouched_user_msin and test_rating['User msin'] == 'DestMsin']

Expand Down
2 changes: 1 addition & 1 deletion rein/lib/script.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,4 @@ def check_redeem_scripts(document):
ret['Mediator public key'], pubkeys):
click.echo("2-of-3 check failed")
return False
return True
return True
Loading