Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ABW-1770] Profile Snapshot change of PersonData to be mainnet ready. NOT CAP21 implementation change. #585

Merged
merged 129 commits into from
Jul 6, 2023

Conversation

CyonAlexRDX
Copy link
Contributor

@CyonAlexRDX CyonAlexRDX commented Jun 17, 2023

ABW-1770

CAUTION

This PR is complete in the sense of Profile Snapshot change ONLY, apart from that it is INCOMPLETE, in regards to:

  • Create Persona Feature
  • Display Persona Feature
  • Edit Persona Feature
  • AuthorizedDapp Feature (persona section)
  • WHOLE OF CAP21 - interaction with Dapp.

The above listed features (except Creation and Display Persona) are broken and out of scope of this PR.

My suggestion is once approved, we do NOT merge it into main, but we plan for someone in iOS team to ASAP migrate all the reducers and disable Dapp interaction related to Persona in a new branch and once that is done a new PR into this source branch/PR gets created. And then we merge that into main. With the updated UI for complex persona data kinds like postal address. And then after that work we will ASAP try to finish CAP21 updates and CE to migrate to new format.

SNAPSHOT CHANGE

Persona changes its data/fields from:

var fields: IdentifiedArrayOf<Field>

To:

var personaData: PersonaData

Where PersonaData is this struct:

public struct PersonaData: Sendable, Hashable, Codable {
	public typealias IdentifiedName = IdentifiedEntry<Name>
	public typealias IdentifiedDateOfBirth = IdentifiedEntry<DateOfBirth>
	public typealias IdentifiedCompanyName = IdentifiedEntry<CompanyName>

	public typealias IdentifiedEmailAddresses = CollectionOfIdentifiedEntries<EmailAddress>
	public typealias IdentifiedPostalAddresses = CollectionOfIdentifiedEntries<PostalAddress>
	public typealias IdentifiedPhoneNumbers = CollectionOfIdentifiedEntries<PhoneNumber>
	public typealias IdentifiedCreditCards = CollectionOfIdentifiedEntries<CreditCard>

	public var name: IdentifiedName?
	public var dateOfBirth: IdentifiedDateOfBirth?
	public var companyName: IdentifiedCompanyName?
	public var emailAddresses: IdentifiedEmailAddresses
	public var postalAddresses: IdentifiedPostalAddresses
	public var phoneNumbers: IdentifiedPhoneNumbers
	public var creditCards: IdentifiedCreditCards
}

Where IdentifiedEntry is this:

extension PersonaData {
	public struct IdentifiedEntry<Value: BasePersonaDataEntryProtocol> {
		public let id: PersonaDataEntryID
		public var value: Value
        }
}

Entry
Can be used for homogenous arrays. which is not used by profile or CAP21 (Dapp) but might be useful for tests and debug views.

extension PersonaData {
	public enum Entry: Sendable, Hashable, Codable, BasePersonaDataEntryProtocol {
		case name(Name)
		case dateOfBirth(DateOfBirth)
		case emailAddress(EmailAddress)
		case postalAddress(PostalAddress)
		case phoneNumber(PhoneNumber)
		case creditCard(CreditCard)
		case companyName(CompanyName)
	}
}

PostalAddress is complicated... it is this:

struct PostalAddress {
	public let fields: IdentifiedArrayOf<PersonaData.PostalAddress.Field>
}

Where PostalAddress.Field is this:

extension PostalAddress {
    public enum Field: Sendable, Hashable, Codable, Identifiable {
		public typealias ID = Discriminator
		public var id: ID {
			discriminator
		}

		case country(Country)
		case streetLine0(String)
		case streetLine1(String = "")

		case postalCodeString(String)

		/// Sweden
		case postalCodeNumber(Int)

		/// "Postcode" e.g.: `India`
		case postcodeNumber(Int)

		/// "Postcode" .e.g. UK
		case postcodeString(String)

		/// US
		case zipNumber(Int)

		case city(String)
		case state(String)

		/// Australia
		case suburb(String)

		/// Brazil
		case neighbourhood(String)

		/// Canada
		case province(String)

		/// Egypt
		case governorate(String)

		/// Hong Kong
		case districtString(String)

		/// Macao
		case districtNumber(Int)

		/// Hong Kong, Somalia
		case region(String)

		/// United Arab Emirates
		case area(String)

		/// China
		case prefectureLevelCity(String)

		/// Russia
		case subjectOfTheFederation(String)

		/// Japan
		case prefecture(String)
		/// Japan
		case county(String)
		/// Japan
		case furtherDivisionsLine0(String)

		/// Japan
		case furtherDivisionsLine1(String)

		/// Taiwan
		case township(String)

		/// Colombia
		case department(String)

		/// Jordan
		case postalDistrict(String)
	}
}

CAP21 ROUGH SKETCH

I've sketched out the most natural CAP21 change for DappInteraction, but it might need some more work. It needs to be documented, communicated. Then this CAP21 changes MUST be implemented by Connector Extension and tested.

But roughly the PersonaDataRequestItem looks like this:

extension P2P.Dapp.Request {
	public struct PersonaDataRequestItem: Sendable, Hashable, Decodable {
		public let isRequestingName: Bool?
		public let isRequestingDateOfBirth: Bool?
		public let isRequestingCompanyName: Bool?
		public let postalAddressesRequested: RequestedNumber?
		public let emailAddressesRequested: RequestedNumber?
		public let phoneNumbersAddressesRequested: RequestedNumber?
		public let creditCardsRequested: RequestedNumber?
        }
}

where RequestedNumber is:

public struct RequestedNumber: Sendable, Hashable, Codable {
	public enum Quantifier: String, Sendable, Hashable, Codable {
		case exactly
		case atLeast
	}

	public let quantifier: Quantifier
	public let quantity: Int
    }
}

Which where RequestedNumber is what is being used for AccountsRequestItem` in CAP21.

And the Response is going to be something like:

extension P2P.Dapp.Response.WalletInteractionSuccessResponse {
	public struct PersonaDataRequestResponseItem: Sendable, Hashable, Encodable {
		public let name: PersonaData.Name?
		public let dateOfBirth: PersonaData.DateOfBirth?
		public let companyName: PersonaData.CompanyName?
		public let emailAddresses: OrderedSet<PersonaData.EmailAddress>?
		public let postalAddresses: OrderedSet<PersonaData.PostalAddress>?
		public let phoneNumbers: OrderedSet<PersonaData.PhoneNumber>?
		public let creditCards: OrderedSet<PersonaData.CreditCard>?

	}
}

We do NOT share any IDs with the Dapp. We only share the values. The ID is only used exactly like Profile uses FactorSourceID, to only save FactorSource in one place in Profile. To avoid duplication of data.

Demo

This is PLACEHOLDER design, but hey it works...

Simulator.Screen.Recording.-.iPhone.14.Pro.-.2023-06-21.at.08.33.44.mp4

@CyonAlexRDX CyonAlexRDX added DO NOT MERGE Merging is blocked or prohibited due to missing specs or other higher priority PRs and removed DO NOT MERGE Merging is blocked or prohibited due to missing specs or other higher priority PRs labels Jun 27, 2023
@maciek-rdx maciek-rdx changed the title [ABW-1170] Profile Snapshot change of PersonData to be mainnet ready. NOT CAP21 implementation change. [ABW-1770] Profile Snapshot change of PersonData to be mainnet ready. NOT CAP21 implementation change. Jul 5, 2023
@CyonAlexRDX CyonAlexRDX removed the DO NOT MERGE Merging is blocked or prohibited due to missing specs or other higher priority PRs label Jul 5, 2023
@maciek-rdx maciek-rdx merged commit 63dbda6 into main Jul 6, 2023
2 checks passed
@maciek-rdx maciek-rdx deleted the ABW-1770_persona_field_complex_data branch July 6, 2023 11:22
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants