Skip to content
This repository was archived by the owner on Feb 3, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,22 @@ Opting Out

If you'd like to opt out of receiving a payment, simply include the string "FREEBIE" somewhere in your commit message, and you will not receive BTC for that commit.

Payment processing
------------------

By default, you need a coinbase account for recieving payment. However, if you add a `Send-bitcoin-reward: `-line to your commit, you recieve payment to that address instead.
You may consider adding a git hook that appends this line for you:

$ git config --global user.reward-btc "your-btc-address"
$ cat > .git/hooks/commit-msg << "EOF"
#!/bin/sh
VAR=$(git config -z user.reward-btc)
if [ -n "$VAR" ]; then
awk "/Signed-off-by:.*/ && c == 0 {c = 1; print \"Send-bitcoin-reward: $VAR\"}; {print} END{if(c == 0) {print \"Send-bitcoin-reward: $VAR\"}}" $1 > "$1".tmp
mv "$1".tmp $1
fi
EOF
$ chmod +x .git/hooks/commit-msg

Building
-------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public BigDecimal getExchangeRate() throws IOException {
}
}

public void sendPayment(Author author, BigDecimal amount, String url)
public void sendPayment(Author author, String overwritingBtcAddress, BigDecimal amount, String url)
throws TransferFailedException
{
try {
Expand All @@ -95,7 +95,12 @@ public void sendPayment(Author author, BigDecimal amount, String url)

String note = "Commit payment:\n__" + author.getUsername() + "__ " + url;

BitcoinTransaction transaction = new BitcoinTransaction(author.getEmail(),
String recipient = author.getEmail();
if (overwritingBtcAddress != null && overwritingBtcAddress != "") {
recipient = overwritingBtcAddress;
}

BitcoinTransaction transaction = new BitcoinTransaction(recipient,
amount.toPlainString(),
note);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Handles incoming API calls from GitHub. These are currently only
Expand Down Expand Up @@ -125,12 +127,19 @@ public void handleCommits(@Auth Authentication auth,
private void sendPaymentsFor(Repository repository, List<Commit> commits,
BigDecimal balance, BigDecimal exchangeRate)
{
Pattern addressPattern = Pattern.compile("^Send-Bitcoin-reward: (.*)$", Pattern.MULTILINE);

for (Commit commit : commits) {
try {
BigDecimal payout = balance.multiply(payoutRate);

if (isViablePaymentAmount(payout)) {
coinbaseClient.sendPayment(commit.getAuthor(), payout, commit.getUrl());
String authorBtcAddress = getHeaderBtcAddress(commit.getMessage(), addressPattern);
if (authorBtcAddress != null) {
logger.info("Retrieved btc address from commit message: " + authorBtcAddress + ".");
}
coinbaseClient.sendPayment(commit.getAuthor(), authorBtcAddress, payout,
commit.getUrl());
}

balance = balance.subtract(payout);
Expand Down Expand Up @@ -181,6 +190,15 @@ private boolean isViableMessage(String message, String defaultMode) {
(message.contains("MONEYMONEY") && defaultMode.equals("FREEBIE"));
}

private String getHeaderBtcAddress(String message, Pattern pattern) {
Matcher addressMatcher = pattern.matcher(message);
String btcAddress = null;
while (addressMatcher.find()) {
btcAddress = addressMatcher.group(1);
}
return btcAddress;
}

private boolean isViablePaymentAmount(BigDecimal payment) {
return payment.compareTo(new BigDecimal(0)) == 1;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,24 @@ public void testOptOutCommit() throws Exception, TransferFailedException {
.post(ClientResponse.class, post);

verify(coinbaseClient, never()).sendPayment(any(Author.class),
anyString(),
any(BigDecimal.class),
anyString());
}

@Test
public void testCommitSendToLine() throws Exception, TransferFailedException {
String payloadValue = payload("/payloads/commit_send_to_line.json");
MultivaluedMapImpl post = new MultivaluedMapImpl();
post.add("payload", payloadValue);
ClientResponse response = client().resource("/v1/github/commits/")
.header("X-Forwarded-For", "192.30.252.1")
.header("Authorization", authString)
.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
.post(ClientResponse.class, post);

verify(coinbaseClient).sendPayment(any(Author.class),
eq("1PRmBDjTcgjR13FPMQ3m4fLhTxo3s4tCkg"),
any(BigDecimal.class),
anyString());
}
Expand All @@ -178,6 +196,7 @@ public void testValidCommit() throws Exception, TransferFailedException {
.post(ClientResponse.class, post);

verify(coinbaseClient).sendPayment(any(Author.class),
anyString(),
eq(BALANCE.multiply(new BigDecimal(0.02))),
anyString());
}
Expand All @@ -194,6 +213,7 @@ public void testNonMaster() throws Exception, TransferFailedException {
.post(ClientResponse.class, post);

verify(coinbaseClient, never()).sendPayment(any(Author.class),
anyString(),
eq(BALANCE.multiply(new BigDecimal(0.02))),
anyString());
}
Expand All @@ -209,9 +229,9 @@ public void testValidMultipleCommitsMultipleAuthors() throws Exception, Transfer
.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
.post(ClientResponse.class, post);

verify(coinbaseClient, times(1)).sendPayment(any(Author.class), eq(BALANCE.multiply(new BigDecimal(0.02))),
verify(coinbaseClient, times(1)).sendPayment(any(Author.class), anyString(), eq(BALANCE.multiply(new BigDecimal(0.02))),
anyString());
verify(coinbaseClient, times(1)).sendPayment(any(Author.class), eq(BALANCE.subtract(BALANCE.multiply(new BigDecimal(0.02)))
verify(coinbaseClient, times(1)).sendPayment(any(Author.class), anyString(), eq(BALANCE.subtract(BALANCE.multiply(new BigDecimal(0.02)))
.multiply(new BigDecimal(0.02))), anyString());
}

Expand All @@ -227,6 +247,7 @@ public void testOptInCommit() throws Exception, TransferFailedException {
.post(ClientResponse.class, post);

verify(coinbaseClient).sendPayment(any(Author.class),
anyString(),
eq(BALANCE.multiply(new BigDecimal(0.02))),
anyString());
}
Expand All @@ -243,6 +264,7 @@ public void testNoOptInCommit() throws Exception, TransferFailedException {
.post(ClientResponse.class, post);

verify(coinbaseClient, never()).sendPayment(any(Author.class),
anyString(),
any(BigDecimal.class),
anyString());
}
Expand Down
79 changes: 79 additions & 0 deletions src/test/resources/payloads/commit_send_to_line.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{
"after": "bcf09f8b4a32921114587e4814a3f0849aa9900f",
"before": "1b141aa068165dd1ed376f483cd5fdc2c64f32b1",
"commits": [
{
"added": [],
"author": {
"email": "moxie@thoughtcrime.org",
"name": "Moxie Marlinspike",
"username": "moxie0"
},
"committer": {
"email": "moxie@thoughtcrime.org",
"name": "Moxie Marlinspike",
"username": "moxie0"
},
"distinct": true,
"id": "ba1b681c71db4fcd461954b1bf344bc6e29411e5",
"message": "Update path\n\nsome-description\nSend-Bitcoin-reward: 1PRmBDjTcgjR13FPMQ3m4fLhTxo3s4tCkg",
"modified": [
"README.md"
],
"removed": [],
"timestamp": "2013-12-14T11:42:28-08:00",
"url": "https://github.com/moxie0/tempt/commit/ba1b681c71db4fcd461954b1bf344bc6e29411e5"
}],
"compare": "https://github.com/moxie0/tempt/compare/1b141aa06816...bcf09f8b4a32",
"created": false,
"deleted": false,
"forced": false,
"head_commit": {
"added": [],
"author": {
"email": "moxie@thoughtcrime.org",
"name": "Moxie Marlinspike",
"username": "moxie0"
},
"committer": {
"email": "moxie@thoughtcrime.org",
"name": "Moxie Marlinspike",
"username": "moxie0"
},
"distinct": true,
"id": "bcf09f8b4a32921114587e4814a3f0849aa9900f",
"message": "Merge branch 'master' of github.com:moxie0/tempt",
"modified": [],
"removed": [],
"timestamp": "2013-12-14T11:42:44-08:00",
"url": "https://github.com/moxie0/tempt/commit/bcf09f8b4a32921114587e4814a3f0849aa9900f"
},
"pusher": {
"email": "moxie@thoughtcrime.org",
"name": "moxie0"
},
"ref": "refs/heads/master",
"repository": {
"created_at": 1386866024,
"description": "test",
"fork": false,
"forks": 1,
"has_downloads": true,
"has_issues": true,
"has_wiki": true,
"id": 15141344,
"master_branch": "master",
"name": "tempt",
"open_issues": 0,
"owner": {
"email": "moxie@thoughtcrime.org",
"name": "moxie0"
},
"private": false,
"pushed_at": 1387050173,
"size": 216,
"stargazers": 1,
"url": "https://github.com/moxie0/test",
"watchers": 1
}
}