Skip to content

Commit

Permalink
Implement fiat topup setup (#118)
Browse files Browse the repository at this point in the history
* Implement fiat topup setup

* Add referral code parameter

* Rename `FiatTopupInfo` to `FiatTopupSetupInfo`

* Add `source_iban` param to `complete_topup_setup`

* Update schema
  • Loading branch information
danielgranhao authored Dec 3, 2024
1 parent 8ad85fa commit c6d1c3f
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 93 deletions.
107 changes: 91 additions & 16 deletions crow/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
use graphql::perro::{ensure, permanent_failure};
use graphql::schema::list_uncompleted_topups::{topup_status_enum, ListUncompletedTopupsTopup};
use graphql::schema::{
hide_topup, list_uncompleted_topups, register_notification_token, register_topup, HideTopup,
ListUncompletedTopups, RegisterNotificationToken, RegisterTopup,
complete_topup_setup, hide_topup, list_uncompleted_topups, register_notification_token,
start_topup_setup, CompleteTopupSetup, HideTopup, ListUncompletedTopups,
RegisterNotificationToken, StartTopupSetup,
};
use graphql::{build_client, parse_from_rfc3339, post_blocking, ExchangeRate};
use honeybadger::Auth;
use std::sync::Arc;
use std::time::SystemTime;

use graphql::perro::runtime_error;
use graphql::schema::complete_topup_setup::CompleteTopupSetupCompleteTopupSetup;
pub use isocountry::CountryCode;
pub use isolanguage_1::LanguageCode;

Expand Down Expand Up @@ -63,6 +65,58 @@ pub struct TopupInfo {
pub error: Option<TopupError>,
}

pub struct FiatTopupSetupChallenge {
pub id: String,
pub challenge: String,
}

/// Information about a fiat top-up registration
#[derive(Debug, Clone, PartialEq)]
pub struct FiatTopupSetupInfo {
pub order_id: String,
/// The user should transfer fiat from this IBAN
pub debitor_iban: String,
/// This reference should be included in the fiat transfer reference
pub creditor_reference: String,
/// The user should transfer fiat to this IBAN
pub creditor_iban: String,
pub creditor_bank_name: String,
pub creditor_bank_street: String,
pub creditor_bank_postal_code: String,
pub creditor_bank_town: String,
pub creditor_bank_country: String,
pub creditor_bank_bic: String,
pub creditor_name: String,
pub creditor_street: String,
pub creditor_postal_code: String,
pub creditor_town: String,
pub creditor_country: String,
pub currency: String,
}

impl From<CompleteTopupSetupCompleteTopupSetup> for FiatTopupSetupInfo {
fn from(value: CompleteTopupSetupCompleteTopupSetup) -> Self {
Self {
order_id: value.id,
debitor_iban: value.debitor_iban,
creditor_reference: value.creditor_reference,
creditor_iban: value.creditor_iban,
creditor_bank_name: value.creditor_bank_name,
creditor_bank_street: value.creditor_bank_street,
creditor_bank_postal_code: value.creditor_bank_postal_code,
creditor_bank_town: value.creditor_bank_town,
creditor_bank_country: value.creditor_bank_country,
creditor_bank_bic: value.creditor_bank_bic,
creditor_name: value.creditor_name,
creditor_street: value.creditor_street,
creditor_postal_code: value.creditor_postal_code,
creditor_town: value.creditor_town,
creditor_country: value.creditor_country,
currency: value.currency,
}
}
}

pub struct OfferManager {
backend_url: String,
auth: Arc<Auth>,
Expand All @@ -73,28 +127,49 @@ impl OfferManager {
Self { backend_url, auth }
}

pub fn register_topup(
pub fn start_topup_setup(
&self,
order_id: String,
node_pubkey: String,
provider: String,
source_iban: String,
user_currency: String,
email: Option<String>,
referral_code: Option<String>,
) -> graphql::Result<()> {
let variables = register_topup::Variables {
order_id,
) -> graphql::Result<FiatTopupSetupChallenge> {
let variables = start_topup_setup::Variables {
email,
node_pubkey,
provider,
referral_code,
source_iban,
user_currency,
};
let access_token = self.auth.query_token()?;
let client = build_client(Some(&access_token))?;
let data = post_blocking::<RegisterTopup>(&client, &self.backend_url, variables)?;
ensure!(
matches!(
data.register_topup,
Some(register_topup::RegisterTopupRegisterTopup { .. })
),
permanent_failure("Backend rejected topup registration")
);
Ok(())
let data = post_blocking::<StartTopupSetup>(&client, &self.backend_url, variables)?;

Ok(FiatTopupSetupChallenge {
id: data.start_topup_setup.id,
challenge: data.start_topup_setup.challenge,
})
}

pub fn complete_topup_setup(
&self,
id: String,
signed_challenge: String,
source_iban: String,
) -> graphql::Result<FiatTopupSetupInfo> {
let variables = complete_topup_setup::Variables {
id,
signed_challenge,
source_iban,
};
let access_token = self.auth.query_token()?;
let client = build_client(Some(&access_token))?;
let data = post_blocking::<CompleteTopupSetup>(&client, &self.backend_url, variables)?;

Ok(data.complete_topup_setup.into())
}

pub fn register_notification_token(
Expand Down
28 changes: 28 additions & 0 deletions graphql/schemas/operations.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,31 @@ mutation DisableLightningAddresses($addresses: [String!]!) {
mutation EnableLightningAddresses($addresses: [String!]!) {
enable_lightning_addresses(addresses: $addresses)
}

mutation StartTopupSetup($email: String, $node_pubkey: String!, $provider: String!, $referralCode: String, $source_iban: String!, $user_currency: String!) {
start_topup_setup(email: $email, node_pubkey: $node_pubkey, provider: $provider, referralCode: $referralCode, source_iban: $source_iban, user_currency: $user_currency) {
id
challenge
}
}

mutation CompleteTopupSetup($id: String!, $signedChallenge: String!, $sourceIban: String!) {
complete_topup_setup(id: $id, signed_challenge: $signedChallenge, source_iban: $sourceIban) {
id
debitorIban
creditorReference
creditorIban
creditorBankName
creditorBankStreet
creditorBankPostalCode
creditorBankTown
creditorBankCountry
creditorBankBic
creditorName
creditorStreet
creditorPostalCode
creditorTown
creditorCountry
currency
}
}
113 changes: 36 additions & 77 deletions graphql/schemas/schema_wallet_read.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,25 @@ enum ChallengeSignatureType {
SECP256K1
}

type CompleteTopupSetupResponse {
creditorBankBic: String!
creditorBankCountry: String!
creditorBankName: String!
creditorBankPostalCode: String!
creditorBankStreet: String!
creditorBankTown: String!
creditorCountry: String!
creditorIban: String!
creditorName: String!
creditorPostalCode: String!
creditorReference: String!
creditorStreet: String!
creditorTown: String!
currency: String!
debitorIban: String!
id: String!
}

type CreateBackupResponse {
schemaName: String
schemaVersion: String
Expand Down Expand Up @@ -199,6 +218,11 @@ type SessionPermit {
walletPubKeyId: String
}

type StartTopupSetupResponse {
challenge: String!
id: String!
}

"""
Boolean expression to compare columns of type "String". All fields are combined with logical 'AND'.
"""
Expand Down Expand Up @@ -316,7 +340,7 @@ unique or primary key constraints on table "accepted_terms_conditions"
"""
enum accepted_terms_conditions_constraint {
"""
unique or primary key constraint on columns "id", "service"
unique or primary key constraint on columns "service", "id"
"""
accepted_terms_conditions_pkey
}
Expand Down Expand Up @@ -521,26 +545,6 @@ enum country_select_column {
name
}

"""
Streaming cursor of the table "country"
"""
input country_stream_cursor_input {
"""Stream column input with initial value"""
initial_value: country_stream_cursor_value_input!

"""cursor ordering"""
ordering: cursor_ordering
}

"""Initial value of the column from where the streaming should start"""
input country_stream_cursor_value_input {
callingCode: String
countryCode: String
currencyCode: bpchar
currencyName: String
name: String
}

"""
columns and relationships of "currency"
"""
Expand Down Expand Up @@ -697,6 +701,7 @@ type mutation_root {
accept_terms_conditions_v2(args: AcceptTermsConditionsV2Input): AcceptTermsConditionsV2Response
accept_wallet_acl_by_pk(pk_columns: AcceptWalletPkRequestInput!): WalletAcl
assign_lightning_address: LightningAddressResponse
complete_topup_setup(id: String!, signed_challenge: String!, source_iban: String!): CompleteTopupSetupResponse!
create_backup(encryptedBackup: String!, schemaName: String!, schemaVersion: String!): CreateBackupResponse
disable_lightning_addresses(addresses: [String!]!): Void
enable_lightning_addresses(addresses: [String!]!): Void
Expand Down Expand Up @@ -728,13 +733,14 @@ type mutation_root {
refresh_session(refreshToken: String!): TokenContainer
refresh_session_v2(refreshToken: String!): SessionPermit
register_notification_token(language: String!, notificationToken: String!): Token
register_topup(email: String, orderId: String!): RegisterTopupResponse
register_topup(email: String, orderId: String!, referralCode: String): RegisterTopupResponse
report_payment_telemetry(events: PaymentTelemetryEventsInput, telemetryId: String!): ReportPaymentTelemetryResponse
request_phone_number_verification(encryptedNumber: String!, number: String!): Void
start_prepared_session(challenge: String!, challengeSignature: String!, challengeSignatureType: ChallengeSignatureType, preparedPermissionToken: String!): TokenContainer
start_prepared_session_v2(challenge: String!, challengeSignature: String!, challengeSignatureType: ChallengeSignatureType, preparedPermissionToken: String!): SessionPermit
start_session(authPubKey: String!, challenge: String!, challengeSignature: String!, challengeSignatureType: ChallengeSignatureType, signedAuthPubKey: String!, walletPubKey: String!): TokenContainer
start_session_v2(authPubKey: String!, challenge: String!, challengeSignature: String!, challengeSignatureType: ChallengeSignatureType, signedAuthPubKey: String!, walletPubKey: String!): SessionPermit
start_topup_setup(email: String, node_pubkey: String!, provider: String!, referralCode: String, source_iban: String!, user_currency: String!): StartTopupSetupResponse!
submit_lnurl_pay_invoice(id: String!, invoice: String): Void
verify_phone_number(number: String!, otp: String!): Void
}
Expand Down Expand Up @@ -801,9 +807,7 @@ type query_root {
backup_service_version: String
consumer_service_version: String

"""
fetch data from the table: "country"
"""
"""Get information about all countries supported by lipa"""
country(
"""distinct select on columns"""
distinct_on: [country_select_column!]
Expand All @@ -821,12 +825,10 @@ type query_root {
where: country_bool_exp
): [country!]!

"""fetch data from the table: "country" using primary key columns"""
"""Get information about a specific country supported by lipa"""
country_by_pk(countryCode: String!): country

"""
fetch data from the table: "currency"
"""
"""Get exchange rates for all currencies supported by lipa"""
currency(
"""distinct select on columns"""
distinct_on: [currency_select_column!]
Expand All @@ -844,7 +846,7 @@ type query_root {
where: currency_bool_exp
): [currency!]!

"""fetch data from the table: "currency" using primary key columns"""
"""Get exchange rate for a specific currency supported by lipa"""
currency_by_pk(
"""ISO 4217"""
currencyCode: String!
Expand Down Expand Up @@ -878,9 +880,7 @@ type query_root {
prepare_wallet_session(challenge: String!, ownerPubKeyId: String!, signature: String!): String
sms_service_version: String

"""
fetch data from the table: "token"
"""
"""TEST COMMENT"""
token(
"""distinct select on columns"""
distinct_on: [token_select_column!]
Expand Down Expand Up @@ -1001,46 +1001,7 @@ type subscription_root {
where: accepted_terms_conditions_bool_exp
): [accepted_terms_conditions!]!

"""
fetch data from the table: "country"
"""
country(
"""distinct select on columns"""
distinct_on: [country_select_column!]

"""limit the number of rows returned"""
limit: Int

"""skip the first n rows. Use only with order_by"""
offset: Int

"""sort the rows by one or more columns"""
order_by: [country_order_by!]

"""filter the rows returned"""
where: country_bool_exp
): [country!]!

"""fetch data from the table: "country" using primary key columns"""
country_by_pk(countryCode: String!): country

"""
fetch data from the table in a streaming manner: "country"
"""
country_stream(
"""maximum number of rows returned in a single batch"""
batch_size: Int!

"""cursor to stream the results returned by the query"""
cursor: [country_stream_cursor_input]!

"""filter the rows returned"""
where: country_bool_exp
): [country!]!

"""
fetch data from the table: "currency"
"""
"""Get exchange rates for all currencies supported by lipa"""
currency(
"""distinct select on columns"""
distinct_on: [currency_select_column!]
Expand All @@ -1058,7 +1019,7 @@ type subscription_root {
where: currency_bool_exp
): [currency!]!

"""fetch data from the table: "currency" using primary key columns"""
"""Get exchange rate for a specific currency supported by lipa"""
currency_by_pk(
"""ISO 4217"""
currencyCode: String!
Expand Down Expand Up @@ -1112,9 +1073,7 @@ type subscription_root {
where: lightning_address_bool_exp
): [lightning_address!]!

"""
fetch data from the table: "token"
"""
"""TEST COMMENT"""
token(
"""distinct select on columns"""
distinct_on: [token_select_column!]
Expand Down
Loading

0 comments on commit c6d1c3f

Please sign in to comment.