Skip to content
This repository has been archived by the owner on Feb 8, 2024. It is now read-only.

Commit

Permalink
Age of client-side-validation has begun
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-orlovsky committed Mar 8, 2021
1 parent d1a90f0 commit 1b8dd49
Show file tree
Hide file tree
Showing 31 changed files with 145 additions and 16 deletions.
Binary file added Docs/Assets/accept01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/accept02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/internals01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/internals02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/internals03.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/internals04.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/internals05.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/internals06.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/internals07.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/invoice01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/invoice02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/invoice03.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/ipad01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/ipad02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/ipad03.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/ipad04.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/ipad05.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/ipad06.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/payment01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/payment02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/Assets/payment03.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<VariablesViewState
version = "1.0">
<ContextStates>
<ContextState
contextName = "PaymentView.pay():PaymentView.swift">
</ContextState>
<ContextState
contextName = "TransactionView.operations.getter:TransactionView.swift">
</ContextState>
<ContextState
contextName = "PaymentView.hasAmount.getter:PaymentView.swift">
</ContextState>
<ContextState
contextName = "Import.importData():Import.swift">
</ContextState>
<ContextState
contextName = "CitadelVault.pay(from:invoice:fee:giveaway:):CAPI.swift">
</ContextState>
<ContextState
contextName = "TransferDirection.init(from:):Wallet.swift">
</ContextState>
</ContextStates>
</VariablesViewState>
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
BreakpointExtensionID = "Xcode.Breakpoint.SwiftErrorBreakpoint">
<BreakpointContent
uuid = "16C5B9A5-CC52-424F-908B-3CEFA70F37C9"
shouldBeEnabled = "Yes"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No">
</BreakpointContent>
Expand All @@ -17,7 +17,7 @@
BreakpointExtensionID = "Xcode.Breakpoint.ExceptionBreakpoint">
<BreakpointContent
uuid = "B80B1286-9CCB-419B-820D-7075AC0646A8"
shouldBeEnabled = "Yes"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
breakpointStackSelectionBehavior = "1"
Expand All @@ -29,7 +29,7 @@
BreakpointExtensionID = "Xcode.Breakpoint.RuntimeIssueBreakpoint">
<BreakpointContent
uuid = "7F6C4764-45A3-43AE-AECE-D70810FBF0E0"
shouldBeEnabled = "Yes"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
breakpointStackSelectionBehavior = "1"
Expand Down
61 changes: 61 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# MyCitadel Wallet

Mobile & desktop wallet for Apple Darwin platforms (iOS, iPadOS, macOS) supporting:
- Bitcoin descriptor-based wallets with private keys stored in Apple hardware secure enclave
- [RGB](https://rgbfaq.com): bitcoin & lightning client-validated smart contracts
- Multisignature & miniscript-based spending policies (WIP)
- Taproot & Schnorr signatures (WIP)
- Lightning network, including RGB-over-lightning payments (WIP)

The wallet is using [MyCitadel Node](https://github.com/mycitadel/mycitadel-node) backend, either as an embedded
library & runtime, or as an externally hosted service (personal or enterprise server).

MyCitadel is a consumer-facing apps & products based on [LNP/BP Association](https://github.com/LNP-BP) open-source
libraries for:
- [client-side-validation](https://github.com/LNP-BP/rust-lnpbp), RGB(https://github.com/rgb-org),
- LNP ([lightning network protocol](https://github.com/LNP-BP/lnp-core) and [rust node](https://github.com/LNP-BP/lnp-node)),
- [descriptor wallets](https://github.com/LNP-BP/descriptor-wallet)
- [Internet2](https://github.com/internet2-org/rust-internet2) focusing on end-to-end-encrypted peer-to-peer
microservice architectures

It is also heavily uses [rust-bitcoin](https://github.com/rust-bitcoin/) community libraries:
- [rust-bitcoin](https://github.com/rust-bitcoin/rust-bitcoin)
- [rust-miniscript](https://github.com/rust-bitcoin/rust-miniscript)

## Screenshots

### General

![](Docs/Assets/ipad01.png)
![](Docs/Assets/ipad02.png)
![](Docs/Assets/ipad03.png)
![](Docs/Assets/ipad04.png)
![](Docs/Assets/ipad05.png)
![](Docs/Assets/ipad06.png)

### Invoicing

![](Docs/Assets/invoice01.png)
![](Docs/Assets/invoice02.png)
![](Docs/Assets/invoice03.png)

### Payments

![](Docs/Assets/payment01.png)
![](Docs/Assets/payment02.png)
![](Docs/Assets/payment03.png)

### Payment acceptance

![](Docs/Assets/accept01.png)
![](Docs/Assets/accept02.png)

### Tool for bitcoin hackers

![](Docs/Assets/internals01.png)
![](Docs/Assets/internals02.png)
![](Docs/Assets/internals03.png)
![](Docs/Assets/internals04.png)
![](Docs/Assets/internals05.png)
![](Docs/Assets/internals06.png)
![](Docs/Assets/internals07.png)
26 changes: 18 additions & 8 deletions Shared/Import/Import.swift
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,14 @@ struct Import: View {
case .unknown:
recognizedAs = "incorrect data"
recognitionErrors = [info.parseReport]
case .rgb20Asset(let asset):
recognitionDetails = [asset.id]
recognitionMessages = [
("Ticker", asset.ticker),
("Name", asset.name),
("Known supply", String(asset.knownIssued ?? 0))
]
canImport = category == .genesis || category == .all
case .address(let address):
if address.isBIP21 {
recognitionDetails = ["BIP21 bitcoin invoice"]
Expand All @@ -200,14 +208,6 @@ struct Import: View {
("Network", address.network.localizedName),
])
canImport = category == .invoice || category == .all
case .rgb20Asset(let asset):
recognitionDetails = [asset.id]
recognitionMessages = [
("Ticker", asset.ticker),
("Name", asset.name),
("Known supply", String(asset.knownIssued ?? 0))
]
canImport = category == .genesis || category == .all
case .lnbpInvoice(let invoice):
recognitionMessages = [
("Pay to", invoice.beneficiary),
Expand All @@ -221,6 +221,16 @@ struct Import: View {
recognitionMessages.append(("Description", message))
}
canImport = category == .invoice || category == .all
case .rgbConsignment(let info):
recognitionDetails = ["allows accepting RGB payments & state transfers"]
recognitionMessages = [
("Asset Id", info.asset.id),
("Asset name", info.asset.name),
("Known circulation", "\(info.asset.knownCirculating) \(info.asset.ticker)"),
("Schema Id", info.schemaId),
("Stats", "\(info.transactionsCount) txes, \(info.transitionsCount) transitions, \(info.extensionsCount) endpoints")
]
canImport = category == .consignment || category == .all
default: break
}

Expand Down
5 changes: 4 additions & 1 deletion Shared/Invoice/InvoiceCreate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,10 @@ final class InvoiceConfig: ObservableObject {
return try wallet.invoice(
usingFormat: wallet.hasUtxo ? .addressUtxo : .descriptor,
nominatedIn: asset,
amount: Double(amount) ?? 0
amount: Double(amount) ?? 0,
from: useMerchant ? merchant : nil,
purpose: usePurpose ? purpose : nil,
useLegacySegWit: legacyFormat
)
}
let address = try wallet.nextAddress(legacySegWit: legacyFormat).address
Expand Down
10 changes: 9 additions & 1 deletion Shared/Wallet/AddressView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ struct AddressView: View {
private let listStyle = GroupedListStyle()
#endif

private var toolbarPlacement: ToolbarItemPlacement {
#if os(iOS)
return .navigationBarTrailing
#else
return .primaryAction
#endif
}

var body: some View {
List {
Section {
Expand Down Expand Up @@ -145,7 +153,7 @@ struct AddressView: View {
.listStyle(listStyle)
.navigationTitle("Address details")
.toolbar {
ToolbarItemGroup(placement: .primaryAction) {
ToolbarItemGroup(placement: toolbarPlacement) {
Button(action: movePrev) {
Image(systemName: "chevron.backward")
}.disabled(prev == nil)
Expand Down
10 changes: 9 additions & 1 deletion Shared/Wallet/BalanceList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ struct BalanceList: View {

var wallet: WalletContract

private var toolbarPlacement: ToolbarItemPlacement {
#if os(iOS)
return .navigationBarTrailing
#else
return .primaryAction
#endif
}

var body: some View {
List {
ForEach(wallet.availableAssets, id: \.id) { asset in
Expand All @@ -30,7 +38,7 @@ struct BalanceList: View {
}
.navigationTitle(wallet.name)
.toolbar {
ToolbarItemGroup(placement: .primaryAction) {
ToolbarItemGroup(placement: toolbarPlacement) {
Button(action: { presentedSheet = .walletDetails(wallet) }) {
Image(systemName: "info.circle")
}
Expand Down
9 changes: 8 additions & 1 deletion Shared/Wallet/UtxoView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ struct UtxoView: View {
#else
private let listStyle = GroupedListStyle()
#endif
private var toolbarPlacement: ToolbarItemPlacement {
#if os(iOS)
return .navigationBarTrailing
#else
return .primaryAction
#endif
}

var body: some View {
List {
Expand Down Expand Up @@ -125,7 +132,7 @@ struct UtxoView: View {
.listStyle(listStyle)
.navigationTitle("UTXO details")
.toolbar {
ToolbarItemGroup(placement: .primaryAction) {
ToolbarItemGroup(placement: toolbarPlacement) {
Button(action: movePrev) {
Image(systemName: "chevron.backward")
}.disabled(prev == nil)
Expand Down
10 changes: 9 additions & 1 deletion Shared/Wallet/WalletView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ struct WalletView: View {
@State private var status: String? = nil
@State private var statusPresented: Bool = false

private var toolbarPlacement: ToolbarItemPlacement {
#if os(iOS)
return .navigationBarTrailing
#else
return .primaryAction
#endif
}

var body: some View {
List {
BalancePager(wallet: wallet, assetId: $assetId)
Expand All @@ -84,7 +92,7 @@ struct WalletView: View {
}
.navigationTitle(wallet.name)
.toolbar {
ToolbarItemGroup(placement: .primaryAction) {
ToolbarItemGroup(placement: toolbarPlacement) {
Button(action: { presentedSheet = .walletDetails(wallet) }) {
Image(systemName: "info.circle")
}
Expand Down

0 comments on commit 1b8dd49

Please sign in to comment.