Skip to content

Commit

Permalink
Merge pull request #106 from getlipa/feature/phone-number-registration
Browse files Browse the repository at this point in the history
Implement phone number interface
  • Loading branch information
danielgranhao authored May 21, 2024
2 parents adf19cb + 3006e2b commit 4543426
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ important analytics data about payments to the backend. This data is pseudonymiz

## Pigeon
Pigeons excel in orientation and have a remarkable ability to navigate addresses.
The library allows to register Lightning addresses and processing incoming payments sent to a Lightning address.
The library allows to register Lightning addresses and phone numbers as well as processing incoming payments sent to an address or number.
32 changes: 23 additions & 9 deletions graphql/schemas/operations.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ mutation AcceptTermsAndConditions($serviceProvider: String!, $version: Int!) {
}

query GetTermsAndConditionsStatus($serviceProvider: ServiceProviderEnum!) {
get_terms_conditions_status(args: {service_provider: $serviceProvider}) {
serviceProvider
acceptedTerms
acceptDate
version
}
get_terms_conditions_status(args: {service_provider: $serviceProvider}) {
serviceProvider
acceptedTerms
acceptDate
version
}
}

# Employee
Expand Down Expand Up @@ -130,7 +130,7 @@ query ListUncompletedTopups {

query MigrationBalance($nodePubKey: String) {
migration_balance(nodePubKey: $nodePubKey) {
balanceAmountSat
balanceAmountSat
}
}

Expand Down Expand Up @@ -160,11 +160,25 @@ mutation ReportPaymentTelemetry($telemetryId: String!, $events: PaymentTelemetry

mutation AssignLightningAddress {
assign_lightning_address {
address
assignedAt
address
assignedAt
}
}

mutation SubmitLnurlPayInvoice($id: String!, $invoice: String!) {
submit_lnurl_pay_invoice(id: $id, invoice: $invoice)
}

mutation RequestPhoneNumberVerification($number: String!) {
request_phone_number_verification(number: $number)
}

mutation VerifyPhoneNumber($number: String!, $otp: String!) {
verify_phone_number(number: $number, otp: $otp)
}

query VerifiedPhoneNumber {
verified_phone_number {
phoneNumber
}
}
20 changes: 20 additions & 0 deletions graphql/schemas/schema_wallet_read.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,16 @@ type mutation_root {
recover_backup(schemaName: String!): RecoverBackupResponse
refresh_session(refreshToken: String!): TokenContainer
refresh_session_v2(refreshToken: String!): SessionPermit
"""
Allows registering even if a previous registration is verified or pending verification.
"""
request_phone_number_verification(number: String!): Void

"""
If a distinct phone number was previously registered, expire it in case this
new one gets verified.
"""
verify_phone_number(number: String!, otp: String!): Void
register_notification_token(language: String!, notificationToken: String!): Token
register_topup(email: String, orderId: String!): RegisterTopupResponse
report_payment_telemetry(events: PaymentTelemetryEventsInput, telemetryId: String!): ReportPaymentTelemetryResponse
Expand Down Expand Up @@ -816,6 +826,12 @@ type query_root {
"""fetch data from the table: "country" using primary key columns"""
country_by_pk(countryCode: String!): country

"""
Returns the PhoneNumberResponse corresponding to the VERIFIED registration.
If there's no VERIFIED registration, it returns null.
"""
verified_phone_number: PhoneNumberResponse

"""
fetch data from the table: "currency"
"""
Expand Down Expand Up @@ -940,6 +956,10 @@ type query_root {
wallet_acl_by_pk(id: uuid!): wallet_acl
}

type PhoneNumberResponse {
phoneNumber: String!
}

enum service_enum {
LIPA_WALLET
POCKET_EXCHANGE
Expand Down
24 changes: 24 additions & 0 deletions graphql/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,27 @@ pub struct AssignLightningAddress;
response_derives = "Debug"
)]
pub struct SubmitLnurlPayInvoice;

#[derive(GraphQLQuery)]
#[graphql(
schema_path = "schemas/schema_wallet_read.graphql",
query_path = "schemas/operations.graphql",
response_derives = "Debug"
)]
pub struct RequestPhoneNumberVerification;

#[derive(GraphQLQuery)]
#[graphql(
schema_path = "schemas/schema_wallet_read.graphql",
query_path = "schemas/operations.graphql",
response_derives = "Debug"
)]
pub struct VerifyPhoneNumber;

#[derive(GraphQLQuery)]
#[graphql(
schema_path = "schemas/schema_wallet_read.graphql",
query_path = "schemas/operations.graphql",
response_derives = "Debug"
)]
pub struct VerifiedPhoneNumber;
50 changes: 50 additions & 0 deletions pigeon/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
use graphql::perro::OptionToError;
use graphql::schema::VerifiedPhoneNumber;
use graphql::schema::{
assign_lightning_address, submit_lnurl_pay_invoice, AssignLightningAddress,
SubmitLnurlPayInvoice,
};
use graphql::schema::{
request_phone_number_verification, verified_phone_number, verify_phone_number,
RequestPhoneNumberVerification, VerifyPhoneNumber,
};
use graphql::{build_async_client, post};
use honeybadger::asynchronous::Auth;

Expand Down Expand Up @@ -38,3 +43,48 @@ pub async fn submit_lnurl_pay_invoice(
.await?;
Ok(())
}

pub async fn request_phone_number_verification(
backend_url: &str,
auth: &Auth,
number: String,
) -> graphql::Result<()> {
let token = auth.query_token().await?;
let client = build_async_client(Some(&token))?;
let _data = post::<RequestPhoneNumberVerification>(
&client,
backend_url,
request_phone_number_verification::Variables { number },
)
.await?;
Ok(())
}

pub async fn verify_phone_number(
backend_url: &str,
auth: &Auth,
number: String,
otp: String,
) -> graphql::Result<()> {
let token = auth.query_token().await?;
let client = build_async_client(Some(&token))?;
let _data = post::<VerifyPhoneNumber>(
&client,
backend_url,
verify_phone_number::Variables { number, otp },
)
.await?;
Ok(())
}

pub async fn query_verified_phone_number(
backend_url: &str,
auth: &Auth,
) -> graphql::Result<Option<String>> {
let token = auth.query_token().await?;
let client = build_async_client(Some(&token))?;
let data =
post::<VerifiedPhoneNumber>(&client, backend_url, verified_phone_number::Variables {})
.await?;
Ok(data.verified_phone_number.map(|n| n.phone_number))
}
15 changes: 14 additions & 1 deletion pigeon/tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use bitcoin::Network;
use honeybadger::asynchronous::Auth;
use honeybadger::secrets::{derive_keys, generate_keypair, generate_mnemonic};
use honeybadger::AuthLevel;
use pigeon::assign_lightning_address;
use pigeon::{assign_lightning_address, submit_lnurl_pay_invoice};
use simplelog::TestLogger;
use std::env;
use std::sync::Once;
Expand Down Expand Up @@ -33,6 +33,19 @@ async fn test_assigning_lightning_address() {
assert_ne!(address, address_for_another_user);
}

#[tokio::test]
async fn test_submit_lnurl_pay_invoice() {
let (backend_url, auth) = build_client();
submit_lnurl_pay_invoice(
&backend_url,
&auth,
"5fab1a65-3486-4dfd-bba8-dad2c1a1b98e".to_string(),
"invoice".to_string(),
)
.await
.unwrap();
}

fn build_client() -> (String, Auth) {
println!("Generating keys ...");
let mnemonic = generate_mnemonic();
Expand Down

0 comments on commit 4543426

Please sign in to comment.