Skip to content

Commit 2d28c45

Browse files
feat(sample): update sample apps for 2.0
1 parent 5c94352 commit 2d28c45

31 files changed

+1711
-27
lines changed

Sample/AtalaPrismWalletDemo/AtalaPrismWalletDemo.xcodeproj/project.pbxproj

Lines changed: 212 additions & 0 deletions
Large diffs are not rendered by default.

Sample/AtalaPrismWalletDemo/AtalaPrismWalletDemo/FuncionalitiesList.swift

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import SwiftUI
22

33
struct FuncionalitiesList: View {
44
let mainRouter = MainViewRouterImpl()
5+
@State var presentWallet2 = false
56
var body: some View {
6-
NavigationView {
7+
NavigationStack {
78
List {
89
NavigationLink("Seed Funcionalities", destination: SeedFuncionalitiesView(model: .init()))
910
NavigationLink("DID Funcionalities", destination: DIDFuncionalitiesView(model: .init()))
@@ -12,7 +13,21 @@ struct FuncionalitiesList: View {
1213
)
1314
NavigationLink("Setup Prism Agent", destination: SetupPrismAgentView(viewModel: SetupPrismAgentViewModelImpl())
1415
)
15-
NavigationLink("Wallet Demo", destination: MainView(viewModel: MainViewModelImpl(router: mainRouter), router: mainRouter))
16+
Button {
17+
self.presentWallet2 = true
18+
} label: {
19+
Text("Wallet Demo 2.0")
20+
}
21+
// Button {
22+
// self.presentWallet2 = true
23+
// } label: {
24+
// Text("Wallet Demo")
25+
// }
26+
// NavigationLink("Wallet Demo", destination: MainView(viewModel: MainViewModelImpl(router: mainRouter), router: mainRouter))
27+
}
28+
.buttonStyle(.plain)
29+
.fullScreenCover(isPresented: $presentWallet2) {
30+
Main2View(router: Main2RouterImpl())
1631
}
1732
}
1833
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import SwiftUI
2+
3+
protocol ConnectionsListViewModel: ObservableObject {
4+
var connections: [ConnectionsViewState.Connection] { get }
5+
var error: FancyToast? { get set }
6+
7+
func addConnection(invitation: String, alias: String)
8+
}
9+
10+
struct ConnectionsListView<ViewModel: ConnectionsListViewModel>: View {
11+
@StateObject var viewModel: ViewModel
12+
@State var showAddConnection = false
13+
@State var aliasInput = ""
14+
@State var newConnectionInput = ""
15+
16+
var body: some View {
17+
NavigationStack {
18+
VStack {
19+
if showAddConnection {
20+
VStack(spacing: 16) {
21+
TextField("Alias", text: $aliasInput)
22+
TextField("DID or OOB", text: $newConnectionInput)
23+
HStack(spacing: 8) {
24+
Button {
25+
viewModel.addConnection(invitation: newConnectionInput, alias: aliasInput)
26+
showAddConnection = false
27+
} label: {
28+
Text("Add")
29+
}
30+
Button {
31+
showAddConnection = false
32+
} label: {
33+
Text("Cancel")
34+
}
35+
}
36+
}
37+
}
38+
List {
39+
ForEach(viewModel.connections) { connection in
40+
VStack(spacing: 8) {
41+
if let alias = connection.alias {
42+
Text(alias)
43+
}
44+
HStack {
45+
Text("Host: ")
46+
Text(connection.hostDID)
47+
.lineLimit(1)
48+
.truncationMode(.middle)
49+
}
50+
51+
HStack {
52+
Text("Recipient: ")
53+
Text(connection.recipientDID)
54+
.lineLimit(1)
55+
.truncationMode(.middle)
56+
}
57+
}
58+
}
59+
}
60+
}
61+
.padding()
62+
.toolbar(content: {
63+
ToolbarItem(placement: .navigationBarTrailing) {
64+
Button(action: {
65+
showAddConnection = true
66+
}, label: {
67+
Image(systemName: "plus")
68+
})
69+
}
70+
})
71+
}
72+
}
73+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import Combine
2+
import Domain
3+
import Foundation
4+
import PrismAgent
5+
6+
final class ConnectionsListViewModelImpl: ConnectionsListViewModel {
7+
@Published var connections = [ConnectionsViewState.Connection]()
8+
@Published var error: FancyToast?
9+
10+
private let castor: Castor
11+
private let pluto: Pluto
12+
private let agent: PrismAgent
13+
14+
init(castor: Castor, pluto: Pluto, agent: PrismAgent) {
15+
self.castor = castor
16+
self.pluto = pluto
17+
self.agent = agent
18+
19+
bind()
20+
}
21+
22+
func bind() {
23+
agent
24+
.getAllDIDPairs()
25+
.map {
26+
$0.map {
27+
ConnectionsViewState.Connection(
28+
hostDID: $0.holder.string,
29+
recipientDID: $0.other.string,
30+
alias: $0.name
31+
)
32+
}
33+
}
34+
.replaceError(with: [])
35+
.assign(to: &$connections)
36+
}
37+
38+
func addConnection(invitation: String, alias: String) {
39+
let castor = self.castor
40+
let agent = self.agent
41+
Task { [weak self] in
42+
do {
43+
if let did = try? castor.parseDID(str: invitation) {
44+
let hostDID = try await agent.createNewPeerDID(
45+
alias: alias.isEmpty ? nil : alias,
46+
updateMediator: true
47+
)
48+
let connectionRequest = ConnectionRequest(
49+
from: hostDID,
50+
to: did,
51+
thid: nil,
52+
body: .init()
53+
)
54+
_ = try await agent.sendMessage(message: connectionRequest.makeMessage())
55+
} else if let url = URL(string: invitation) {
56+
let inv = try agent.parseOOBInvitation(url: url)
57+
try await agent.acceptDIDCommInvitation(invitation: inv)
58+
}
59+
} catch let error as LocalizedError {
60+
await MainActor.run { [weak self] in
61+
self?.error = FancyToast(
62+
type: .error,
63+
title: error.localizedDescription,
64+
message: error.errorDescription ?? ""
65+
)
66+
}
67+
} catch {
68+
await MainActor.run { [weak self] in
69+
self?.error = FancyToast(
70+
type: .error,
71+
title: error.localizedDescription,
72+
message: ""
73+
)
74+
}
75+
}
76+
}
77+
}
78+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
struct ConnectionsViewState {
2+
struct Connection: Identifiable {
3+
var id: String { hostDID + recipientDID }
4+
let hostDID: String
5+
let recipientDID: String
6+
let alias: String?
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import SwiftUI
2+
3+
struct CredentialListRouterImpl: CredentialListRouter {
4+
let container: DIContainer
5+
6+
func routeToCredentialDetail(id: String) -> some View {
7+
Text("")
8+
}
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import SwiftUI
2+
3+
protocol CredentialListViewModel: ObservableObject {
4+
var credentials: [CredentialListViewState.Credential] { get }
5+
}
6+
7+
protocol CredentialListRouter {
8+
associatedtype CredentialDetailV: View
9+
10+
func routeToCredentialDetail(id: String) -> CredentialDetailV
11+
}
12+
13+
struct CredentialListView<
14+
ViewModel: CredentialListViewModel,
15+
Router: CredentialListRouter
16+
>: View {
17+
@StateObject var viewModel: ViewModel
18+
let router: Router
19+
20+
var body: some View {
21+
NavigationStack {
22+
List(viewModel.credentials, id: \.id) { credential in
23+
NavigationLink(value: credential) {
24+
VStack(alignment: .leading) {
25+
Text(credential.credentialType)
26+
.font(.headline)
27+
Text(credential.issuer)
28+
.lineLimit(1)
29+
.truncationMode(.middle)
30+
.font(.subheadline)
31+
.foregroundColor(.secondary)
32+
Text(credential.issuanceDate)
33+
.font(.subheadline)
34+
.foregroundColor(.secondary)
35+
if !credential.type.isEmpty {
36+
Spacer()
37+
HStack {
38+
ForEach(credential.type, id: \.self) { type in
39+
Text(type)
40+
.font(.caption)
41+
.padding(.horizontal, 8)
42+
.padding(.vertical, 4)
43+
.background(Color.blue.opacity(0.2))
44+
.cornerRadius(4)
45+
}
46+
}
47+
}
48+
}
49+
}
50+
}
51+
.navigationDestination(for: CredentialListViewState.Credential.self) {
52+
router.routeToCredentialDetail(id: $0.id)
53+
}
54+
.navigationTitle("My Credentials")
55+
}
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import Combine
2+
import Domain
3+
import Foundation
4+
5+
final class CredentialListViewModelImpl: CredentialListViewModel {
6+
@Published var credentials = [CredentialListViewState.Credential]()
7+
8+
private let pluto: Pluto
9+
10+
init(pluto: Pluto) {
11+
self.pluto = pluto
12+
bind()
13+
}
14+
15+
private func bind() {
16+
self.pluto
17+
.getAllCredentials()
18+
.map {
19+
$0.map {
20+
CredentialListViewState.Credential(
21+
credentialType: getTypeString(type: $0.credentialType),
22+
id: $0.id,
23+
issuer: $0.issuer.string,
24+
issuanceDate: $0.issuanceDate.formatted(),
25+
context: Array($0.context),
26+
type: Array($0.type)
27+
)
28+
}
29+
}
30+
.replaceError(with: [])
31+
.assign(to: &$credentials)
32+
}
33+
}
34+
35+
private func getTypeString(type: CredentialType) -> String {
36+
switch type {
37+
case .jwt:
38+
return "jwt"
39+
case .w3c:
40+
return "w3c"
41+
default:
42+
return "unknown"
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
struct CredentialListViewState {
2+
struct Credential: Hashable {
3+
let credentialType: String
4+
let id: String
5+
let issuer: String
6+
let issuanceDate: String
7+
let context: [String]
8+
let type: [String]
9+
}
10+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import SwiftUI
2+
3+
protocol DIDDetailViewModel: ObservableObject {
4+
var state: DIDDetailViewState { get }
5+
}
6+
7+
struct DIDDetailView: View {
8+
var body: some View {
9+
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
10+
}
11+
}
12+
13+
struct DIDDetailView_Previews: PreviewProvider {
14+
static var previews: some View {
15+
DIDDetailView()
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import Combine
2+
import Domain
3+
import Foundation
4+
import PrismAgent
5+
6+
final class DIDDetailViewModelImpl: DIDDetailViewModel {
7+
@Published var state: DIDDetailViewState = .init(
8+
did: "",
9+
alias: nil,
10+
publicKeys: [],
11+
services: [:]
12+
)
13+
private let pluto: Pluto
14+
private let did: String
15+
16+
init(did: String, pluto: Pluto) {
17+
self.did = did
18+
self.pluto = pluto
19+
}
20+
21+
// func bind() {
22+
// let did = try! DID(string: did)
23+
// switch did.method {
24+
// case "prism":
25+
// pluto
26+
// .getPeerDIDInfo(did: <#T##DID#>)
27+
// }
28+
// }
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
struct DIDDetailViewState {
2+
let did: String
3+
let alias: String?
4+
let publicKeys: [String]
5+
let services: [String: String]
6+
}

0 commit comments

Comments
 (0)