Skip to content

Commit

Permalink
improved bitcoin url handling
Browse files Browse the repository at this point in the history
  • Loading branch information
Aaron Voisine committed Sep 13, 2013
1 parent 7bb9d45 commit 4451e88
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 34 deletions.
4 changes: 3 additions & 1 deletion ZincWallet.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3916,7 +3916,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "ZBAR=ZBar/iphone/include/ZBarSDK/ZBarSDK.h\n\ncd $SRCROOT\n\n[ -f $SRCROOT/$ZBAR ] || git submodule init\n[ -f $SRCROOT/$ZBAR ] || git submodule update";
shellScript = "cd $SRCROOT\n\ngit submodule init\ngit submodule update";
};
75D8F3B0173ABE3D0080D95E /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
Expand Down Expand Up @@ -4924,6 +4924,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
Expand Down Expand Up @@ -4953,6 +4954,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
Expand Down
17 changes: 11 additions & 6 deletions ZincWallet/ZNAppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,19 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
if (! url.host && url.resourceSpecifier) {
url = [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@", url.scheme, url.resourceSpecifier]];
NSURL *u = url;

if (! u.host && u.resourceSpecifier) {
u = [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@", u.scheme, u.resourceSpecifier]];
}

if (! [url.scheme isEqual:@"bitcoin"] || ! [url.host isValidBitcoinAddress]) return NO;

[[NSNotificationCenter defaultCenter] postNotificationName:bitcoinURLNotification object:nil
userInfo:@{@"url":url}];
if (! [u.scheme isEqual:@"bitcoin"]) {
[[[UIAlertView alloc] initWithTitle:@"Not a bitcoin URL" message:url.absoluteString delegate:nil
cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
return NO;
}

[[NSNotificationCenter defaultCenter] postNotificationName:bitcoinURLNotification object:nil userInfo:@{@"url":u}];

return YES;
}
Expand Down
53 changes: 32 additions & 21 deletions ZincWallet/ZNPayViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -108,18 +108,25 @@ - (void)viewDidLoad
usingBlock:^(NSNotification *note) {
ZNPaymentRequest *req = [ZNPaymentRequest requestWithURL:note.userInfo[@"url"]];

if (req.isValid &&
[self.requests indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
return [[req data] isEqualToData:[obj data]] ? (*stop = YES) : NO;
}] == NSNotFound) {
[self.requests insertObject:req atIndex:0];
[self.requestIDs insertObject:URL_ID atIndex:0];
[self layoutButtonsAnimated:YES];
[self.scrollView setContentOffset:CGPointZero animated:YES];

[self.navigationController popToRootViewControllerAnimated:NO];
if (w.masterPublicKey) [self.navigationController dismissViewControllerAnimated:NO completion:nil];
if (! req.label.length) req.label = req.paymentAddress;

if (req.amount > 0 && [req.label rangeOfString:[w stringForAmount:req.amount]].location == NSNotFound) {
req.label = [NSString stringWithFormat:@"%@ - %@", req.label,
[[ZNWallet sharedInstance] stringForAmount:req.amount]];
}

if ([self.requestIDs indexOfObject:URL_ID] != NSNotFound) {
[self.requests removeObjectAtIndex:[self.requestIDs indexOfObject:URL_ID]];
[self.requestIDs removeObjectAtIndex:[self.requestIDs indexOfObject:URL_ID]];
}

[self.requests insertObject:req atIndex:0];
[self.requestIDs insertObject:URL_ID atIndex:0];
[self layoutButtonsAnimated:YES];
[self.scrollView setContentOffset:CGPointZero animated:YES];

[self.navigationController popToRootViewControllerAnimated:NO];
if (w.masterPublicKey) [self.navigationController dismissViewControllerAnimated:NO completion:nil];
}];

self.activeObserver =
Expand Down Expand Up @@ -300,18 +307,17 @@ - (ZNReceiveViewController *)receiveController

- (void)layoutButtonsAnimated:(BOOL)animated
{
ZNWallet *w = [ZNWallet sharedInstance];
ZNPaymentRequest *req = [ZNPaymentRequest requestWithString:[[UIPasteboard generalPasteboard] string]];

if (! req.paymentAddress) req.label = CLIPBOARD_LABEL;

if (! req.label.length) {
if (req.amount > 0) {
req.label = [NSString stringWithFormat:@"%@ - %@", req.paymentAddress,
[[ZNWallet sharedInstance] stringForAmount:req.amount]];
}
else req.label = req.paymentAddress;
if (! req.isValid) {
req.paymentAddress = nil;
req.label = CLIPBOARD_LABEL;
}

else if (req.amount > 0 && [req.label rangeOfString:[w stringForAmount:req.amount]].location == NSNotFound) {
req.label = [NSString stringWithFormat:@"%@ - %@", req.label, [w stringForAmount:req.amount]];
}

if ([self.requestIDs indexOfObject:CLIPBOARD_ID] == NSNotFound) {
[self.requests addObject:req];
[self.requestIDs addObject:CLIPBOARD_ID];
Expand Down Expand Up @@ -398,8 +404,13 @@ - (void)confirmRequest:(ZNPaymentRequest *)request
if ([request.label isEqual:CLIPBOARD_LABEL]) {
[[[UIAlertView alloc] initWithTitle:nil message:@"The clipboard doesn't contain a valid bitcoin address."
delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
self.selectedIndex = NSNotFound;
}
else {
[[[UIAlertView alloc] initWithTitle:@"Not a valid bitcoin address." message:request.paymentAddress
delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
}

self.selectedIndex = NSNotFound;
return;
}

Expand Down
8 changes: 2 additions & 6 deletions ZincWallet/ZNPaymentRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ - (void)setData:(NSData *)data

self.paymentAddress = url.host;

//TODO: correctly handle unkown but required url arguments (by reporting the request invalid)
[[url.query componentsSeparatedByString:@"&"] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSArray *pair = [obj componentsSeparatedByString:@"="];
if (pair.count != 2) return;
Expand All @@ -99,11 +100,6 @@ - (void)setData:(NSData *)data
}];
}

- (void)setPaymentAddress:(NSString *)paymentAddress
{
_paymentAddress = [paymentAddress isValidBitcoinAddress] ? paymentAddress : nil;
}

- (NSData *)data
{
if (! self.paymentAddress) return nil;
Expand Down Expand Up @@ -135,7 +131,7 @@ - (NSData *)data

- (BOOL)isValid
{
if (! self.paymentAddress) return NO;
if (! [self.paymentAddress isValidBitcoinAddress]) return NO;

// TODO: validate bitcoin payment request X.509 certificate, hopefully offline

Expand Down
8 changes: 8 additions & 0 deletions ZincWalletTests/ZincWalletTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@ - (void)testKeyWithPrivateKey
@"[ZNKey privateKey]");
}

#pragma mark - testPaymentRequest

//TODO: test valid request with no arguments
//TODO: test valid request with known arguments
//TODO: test valid request with unkown arguments
//TODO: test invalid bitcoin address
//TODO: test invalid request with unkown required arguments

#pragma mark - testTransaction

- (void)testTransactionHeightUntilFree
Expand Down

0 comments on commit 4451e88

Please sign in to comment.