bitcoin-atm
bitcoin atm for pyc inc.
git clone https://9o.is/git/bitcoin-atm.git
commit 5c87c6ebdad01b88d6b1e7db5b7de8b56042387a parent 8e1794308bcbacbde20bfd5ab9817556ce7746ef Author: Jul <jul@9o.is> Date: Mon, 4 Aug 2014 10:30:16 -0400 fixed qrcode.js error. now trying to handle transaction state management Diffstat:
| M | sbt.sh | | | 2 | +- |
| M | src/main/scala/inc/pyc/chimera/bitcoin/PriceTicker.scala | | | 8 | +++++++- |
| M | src/main/scala/inc/pyc/chimera/lycia/Lycia.scala | | | 4 | ++++ |
| M | src/main/scala/inc/pyc/chimera/snippet/PriceTickerComet.scala | | | 33 | +++++++++++++++++++++------------ |
| A | src/main/scala/inc/pyc/chimera/snippet/Transaction.scala | | | 55 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | src/main/scala/inc/pyc/chimera/snippet/UtilSnips.scala | | | 2 | +- |
| M | src/main/webapp/app/App.js | | | 24 | ++++++++++++++---------- |
| M | src/main/webapp/index.html | | | 6 | ++++-- |
| M | src/main/webapp/vendor/jsqrcode/qrcode.js | | | 4 | +++- |
9 files changed, 110 insertions(+), 28 deletions(-)
diff --git a/sbt.sh b/sbt.sh @@ -1,2 +1,2 @@ #!/bin/bash -java -Dfile.encoding=UTF8 -Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=384M -jar `dirname $0`/project/sbt-launch.jar "$@" +java -Dfile.encoding=UTF8 -Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=384M -javaagent:`dirname $0`/lib/aspectjweaver-1.8.1.jar -jar `dirname $0`/project/sbt-launch.jar "$@" diff --git a/src/main/scala/inc/pyc/chimera/bitcoin/PriceTicker.scala b/src/main/scala/inc/pyc/chimera/bitcoin/PriceTicker.scala @@ -6,14 +6,18 @@ import service._ import snippet.EventUpdate import akka.actor._ import akka.event._ +import akka.util.Timeout +import akka.pattern.{ask, pipe} import scala.concurrent._ import duration._ -import ExecutionContext.Implicits._ +import BitcoinServices.system.dispatcher object PriceTicker { import BitcoinServices._ import commands._ + + implicit val timeout: Timeout = Timeout(5 seconds) def !(any: Any): Unit = actor ! any @@ -58,6 +62,8 @@ object PriceTicker { */ case object Tick } + + def price(): Future[Double] = ((actor ? GetPrice).mapTo[Price]).map(_.price.toDouble) } /** diff --git a/src/main/scala/inc/pyc/chimera/lycia/Lycia.scala b/src/main/scala/inc/pyc/chimera/lycia/Lycia.scala @@ -27,6 +27,10 @@ object Lycia { "" } + def buyLimit: Double = { + 500 + } + def servicePriceTicker: BitcoinService.Value = { // TODO get service configured BitcoinService.BitStamp diff --git a/src/main/scala/inc/pyc/chimera/snippet/PriceTickerComet.scala b/src/main/scala/inc/pyc/chimera/snippet/PriceTickerComet.scala @@ -2,6 +2,7 @@ package inc.pyc.chimera package snippet import bitcoin._ +import lycia._ import PriceTicker.commands._ import BitcoinServices.system.dispatcher import Wallet.commands._ @@ -10,7 +11,9 @@ import xml._ import net.liftweb._ import http._ import json.JsonAST._ +import json.JsonDSL._ import akka.actor.ActorSystem +import net.liftweb.common.Logger //import kamon.trace.TraceRecorder /** @@ -35,7 +38,7 @@ class PriceTickerComet extends EventRegister { } } -class BitcoinAddressScanner extends RoundTripSnippet { +class BitcoinAddressScanner extends RoundTripSnippet with Logger { def roundTrips: List[RoundTripInfo] = List("submitAddress" -> submitAddress _) @@ -43,17 +46,23 @@ class BitcoinAddressScanner extends RoundTripSnippet { for (JString(address) <- json) yield for { validation <- Wallet.validateAddress(address) - } yield { + } yield { + + // TODO check website database if address exists + // TODO check if address is owned by a user - // TODO check website database if address exists - // TODO check if address is owned by a user - // TODO set LocalTransaction - - if (validation.isvalid) Message("success") - else Message("failure") - } - - - case class BtcAddressMsg() extends MsgData + CurrentTransaction.set(Some(Transaction( + address = "blahh", + limit = Lycia.buyLimit, + price = 500.23, + currentPage = "Insert Bills" + ))) + info("Tran: "+CurrentTransaction) + + + + if(validation.isvalid) Message("success", transaction = CurrentTransaction) + else Message("failure") + } } \ No newline at end of file diff --git a/src/main/scala/inc/pyc/chimera/snippet/Transaction.scala b/src/main/scala/inc/pyc/chimera/snippet/Transaction.scala @@ -0,0 +1,54 @@ +package inc.pyc.chimera +package snippet + +import org.joda.time.DateTime +import net.liftweb.json.JsonAST.JArray +import net.liftweb.http.RequestVar + + +object CurrentTransaction extends RequestVar[Option[Transaction]](None) + + +/** + * Information about the user. + * + * @param fname First Name + * @param lname Last Name + * @param email Email Address + * @param limit Buy Limit + */ +case class UserInfo( + fname: String, + lname: String, + email: String, + limit: Double) + + +/** + * The information of the current customer transaction. + * + * @param address Bitcoin address to send bitcoin + * @param price Accepted static buy price + * @param limit Buy limit (in USD) + * @param newAddress Whether we ever scanned the address before + * @param user Information about the user if they're registered + * @param billsInserted The USD bills the user has inserted into the bill acceptor + * @param sent Whether the bitcoin were sent or not + * @param startTime Time this transaction started + * @param stopTime Time this transaction stopped + * @param currentPage The wizard page the user is currently seeing. + */ +case class Transaction( + address: String, + price: Double, + limit: Double, + newAddress: Boolean = true, + user: Option[UserInfo] = None, + billsInserted: JArray = JArray(Nil), + sent: Boolean = false, + startTime: DateTime = DateTime.now, + stopTime: Option[DateTime] = None, + currentPage: String +) { + +} +\ No newline at end of file diff --git a/src/main/scala/inc/pyc/chimera/snippet/UtilSnips.scala b/src/main/scala/inc/pyc/chimera/snippet/UtilSnips.scala @@ -26,7 +26,7 @@ trait ImplicitSnip { /* * This is used to send messages to client. */ -case class Message(msg_type: String, msg: Option[String] = None) +case class Message(msg_type: String, msg: Option[String] = None, transaction: Option[Transaction] = None) object Message { def fail = Message("failure") } \ No newline at end of file diff --git a/src/main/webapp/app/App.js b/src/main/webapp/app/App.js @@ -36,7 +36,7 @@ app.controller('PriceTickerCtrl', ['$scope', '$rootScope', function($scope, $roo app.controller('MainCtrl', ['$scope', '$rootScope', function($scope, $rootScope) { - $rootScope.user = {}; + $rootScope.transaction = {}; }]); @@ -54,26 +54,30 @@ app.controller('WalletScannerCtrl', ['$scope', '$rootScope', '$controller', '$ti scanned = false; }, 1000); }; - - $scope.qr_valid = true; + + var showQrError = function() { + $scope.qr_error = true; + $timeout(function() { + $scope.qr_error = false; + }, 6000); + }; $scope.onSuccess = function(data) { if (data !== 'error decoding QR Code' && !scanned) { setScanned(); scan_sound.play(); - var success = function() { - $scope.qr_valid = true; - $rootScope.user.bitcoin_address = data; + var success = function(data) { + window.console.log("Data: "+data.data); + $rootScope.transaction = data.data; WizardHandler.wizard().next(); }; - var failme = function(info) { - window.console.log("Data Failure: "+info); - $scope.qr_valid = false; + var failure = function() { + showQrError(); }; - $scope.submit('BitcoinAddressScanner', 'submitAddress', success, failme, data); + $scope.submit('BitcoinAddressScanner', 'submitAddress', success, failure, data); } }; diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html @@ -13,7 +13,7 @@ <div id="wallet-scanner" data-lift="BitcoinAddressScanner" ng-controller="WalletScannerCtrl"> <qr-scanner ng-success="onSuccess(data)" width="400" height="300"></qr> - <div ng-hide="qr_valid" class="padding-top-20 text-center text-danger"> + <div ng-show="qr_error" class="padding-top-20 text-center text-danger"> Invalid Bitcoin Address </div> </div> @@ -21,7 +21,9 @@ <wz-step title="Insert Bills"> <h1>More Steps</h1> <p>Even more steps!!</p> - <div>{{ user.bitcoin_address }}</div> + <div>{{ transaction.address }}</div> + <div>{{ transaction.price }}</div> + <div>{{ transaction.limit }}</div> <input type="submit" wz-next value="Finish now" class="btn btn-primary" /> </wz-step> </wizard> diff --git a/src/main/webapp/vendor/jsqrcode/qrcode.js b/src/main/webapp/vendor/jsqrcode/qrcode.js @@ -311,9 +311,10 @@ function URShift( number, bits) return (number >> bits) + (2 << ~bits); } - +/* Array.prototype.remove = function(from, to) { var rest = this.slice((to || from) + 1 || this.length); this.length = from < 0 ? this.length + from : from; return this.push.apply(this, rest); }; +*/ +\ No newline at end of file