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

fix(coinbase): transfer to wallet fix #677

Merged
merged 2 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ extension CBAccount {

// MARK: Transfer
extension CBAccount {
public func send(amount: UInt64, verificationCode: String?) async throws -> CoinbaseTransaction {
public func send(amount: UInt64, verificationCode: String?, idem: UUID?) async throws -> CoinbaseTransaction {
// NOTE: Maybe better to get the address once and use it during the tx flow
guard let dashWalletAddress = DWEnvironment.sharedInstance().currentAccount.receiveAddress else {
fatalError("No wallet")
Expand All @@ -121,26 +121,26 @@ extension CBAccount {

// NOTE: Make sure we format the amount back into coinbase format (en_US)
let coinbaseAmount = amount.formattedDashAmountWithoutCurrencySymbol.coinbaseAmount()

let currentIdem = idem ?? UUID()

do {
try await authInterop.refreshTokenIfNeeded()

let dto = CoinbaseTransactionsRequest(type: .send,
to: dashWalletAddress,
amount: coinbaseAmount,
currency: kDashCurrency,
idem: UUID())
idem: currentIdem)

let result: BaseDataResponse<CoinbaseTransaction> = try await httpClient
.request(.sendCoinsToWallet(accountId: accountId, verificationCode: verificationCode, dto: dto))
let _ = try? await refreshAccount() // Ignore if fails

return result.data
} catch HTTPClientError.statusCode(let r) where r.statusCode == 402 {
DSLogger.log("Tranfer from coinbase: transferToWallet - failure - statusCode - 402")
} catch HTTPClientError.statusCode(let r) where r.statusCode == 400 {
DSLogger.log("Tranfer from coinbase: transferToWallet - failure - statusCode - 400")
if let err = r.error?.errors.first {
if err.id == .twoFactorRequired {
throw Coinbase.Error.transactionFailed(.twoFactorRequired)
throw Coinbase.Error.transactionFailed(.twoFactorRequired(idem: currentIdem))
} else {
throw Coinbase.Error.transactionFailed(.unknown(err))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ class AccountService {
return try await account.retrieveAddress()
}

public func send(from accountName: String, amount: UInt64, verificationCode: String?) async throws -> CoinbaseTransaction {
public func send(from accountName: String, amount: UInt64, verificationCode: String?, idem: UUID?) async throws -> CoinbaseTransaction {
let account = try await account(by: accountName)

let tx = try await account.send(amount: amount, verificationCode: verificationCode)
let tx = try await account.send(amount: amount, verificationCode: verificationCode, idem: idem)
return tx
}

Expand Down
2 changes: 1 addition & 1 deletion DashWallet/Sources/Models/Coinbase/Coinbase+Error.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ extension Coinbase {

case invalidAmount
case failedToObtainNewAddress
case twoFactorRequired
case twoFactorRequired(idem: UUID)
case invalidVerificationCode
case notEnoughFunds
case enteredAmountTooLow(minimumAmount: String)
Expand Down
7 changes: 4 additions & 3 deletions DashWallet/Sources/Models/Coinbase/Coinbase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,11 @@ extension Coinbase {
}
}

public func transferFromCoinbaseToDashWallet(verificationCode: String?,
amount: UInt64) async throws -> CoinbaseTransaction {
public func transferFromCoinbaseToDashWallet(amount: UInt64,
verificationCode: String?,
idem: UUID?) async throws -> CoinbaseTransaction {
do {
let tx = try await accountService.send(from: kDashAccount, amount: amount, verificationCode: verificationCode)
let tx = try await accountService.send(from: kDashAccount, amount: amount, verificationCode: verificationCode, idem: idem)

if let address = tx.to?.address {
Taxes.shared.mark(address: address, with: .transferIn)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,18 @@ extension BaseViewController {
protocol CoinbaseCodeConfirmationPreviewing: ActivityIndicatorPreviewing {
var codeConfirmationController: TwoFactorAuthViewController? { set get }
var isCancelingToFail: Bool { get }
func codeConfirmationControllerDidContinue(with code: String)
func codeConfirmationControllerDidContinue(with code: String, for idem: UUID)
func codeConfirmationControllerDidCancel()
}

extension CoinbaseCodeConfirmationPreviewing where Self: BaseViewController {
var isCancelingToFail: Bool { false }

func showCodeConfirmationController() {
let vc = TwoFactorAuthViewController.controller()
func showCodeConfirmationController(idem: UUID) {
let vc = TwoFactorAuthViewController.controller(idem: idem)
vc.isCancelingToFail = isCancelingToFail
vc.verifyHandler = { [weak self] code in
self?.codeConfirmationControllerDidContinue(with: code)
vc.verifyHandler = { [weak self] (code: String, idem: UUID) in
self?.codeConfirmationControllerDidContinue(with: code, for: idem)
}
vc.cancelHandler = { [weak self] in
self?.codeConfirmationControllerDidCancel()
Expand All @@ -95,8 +95,8 @@ extension CoinbaseTransactionHandling where Self: BaseViewController {
func transferFromCoinbaseToWalletDidFail(with error: Error) {
if case Coinbase.Error.transactionFailed(let r) = error {
switch r {
case .twoFactorRequired:
showCodeConfirmationController()
case .twoFactorRequired(let idem):
showCodeConfirmationController(idem: idem)
case .invalidVerificationCode:
showInvalidCodeState()
case .invalidAmount, .enteredAmountTooLow, .limitExceded, .notEnoughFunds:
Expand Down
10 changes: 5 additions & 5 deletions DashWallet/Sources/UI/Coinbase/Base/ViewModel+Coinbase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ protocol CoinbaseTransactionSendable {
var transactionDelegate: CoinbaseTransactionDelegate? { set get }

func transferFromCoinbase()
func continueTransferFromCoinbase(with verificationCode: String)
func continueTransferFromCoinbase(with verificationCode: String, idem: UUID)
}

extension CoinbaseTransactionSendable {
Expand All @@ -49,17 +49,17 @@ extension CoinbaseTransactionSendable {
}
}

func continueTransferFromCoinbase(with verificationCode: String) {
func continueTransferFromCoinbase(with verificationCode: String, idem: UUID) {
let amount = amountToTransfer

Task {
try await transferFromCoinbase(amount: amount, with: verificationCode)
try await transferFromCoinbase(amount: amount, with: verificationCode, for: idem)
}
}

func transferFromCoinbase(amount: UInt64, with verificationCode: String?) async throws {
func transferFromCoinbase(amount: UInt64, with verificationCode: String?, for idem: UUID? = nil) async throws {
do {
_ = try await Coinbase.shared.transferFromCoinbaseToDashWallet(verificationCode: verificationCode, amount: amount)
_ = try await Coinbase.shared.transferFromCoinbaseToDashWallet(amount: amount, verificationCode: verificationCode, idem: idem)
await MainActor.run {
self.transactionDelegate?.transferFromCoinbaseToWalletDidSucceed()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,8 @@ extension OrderPreviewViewController: CoinbaseCodeConfirmationPreviewing, Coinba
actionButton?.hideActivityIndicator()
}

func codeConfirmationControllerDidContinue(with code: String) {
model.continueTransferFromCoinbase(with: code)
func codeConfirmationControllerDidContinue(with code: String, for idem: UUID) {
model.continueTransferFromCoinbase(with: code, idem: idem)
}

func codeConfirmationControllerDidCancel() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ extension TransferAmountViewController: PaymentControllerPresentationContextProv
// MARK: CoinbaseCodeConfirmationPreviewing, CoinbaseTransactionHandling

extension TransferAmountViewController: CoinbaseCodeConfirmationPreviewing, CoinbaseTransactionHandling {
func codeConfirmationControllerDidContinue(with code: String) {
transferModel.continueTransferFromCoinbase(with: code)
func codeConfirmationControllerDidContinue(with code: String, for idem: UUID) {
transferModel.continueTransferFromCoinbase(with: code, idem: idem)
}

func codeConfirmationControllerDidCancel() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ final class TwoFactorAuthViewController: ActionButtonViewController {
@IBOutlet var twoFactorAuthField: UITextField!
@IBOutlet var hintLabel: UILabel!

public var verifyHandler: ((String) -> Void)?
private var idem: UUID!
public var verifyHandler: ((String, UUID) -> Void)?
public var cancelHandler: (() -> Void)?

public var isCancelingToFail = false
Expand Down Expand Up @@ -94,7 +95,7 @@ final class TwoFactorAuthViewController: ActionButtonViewController {

override func actionButtonAction(sender: UIView) {
showActivityIndicator()
verifyHandler?(twoFactorAuthField.text!)
verifyHandler?(twoFactorAuthField.text!, idem)
}

func styleTitle() {
Expand Down Expand Up @@ -225,8 +226,10 @@ final class TwoFactorAuthViewController: ActionButtonViewController {
}

@objc
class func controller() -> TwoFactorAuthViewController {
vc(TwoFactorAuthViewController.self, from: sb("Coinbase"))
class func controller(idem: UUID) -> TwoFactorAuthViewController {
let vc = vc(TwoFactorAuthViewController.self, from: sb("Coinbase"))
vc.idem = idem
return vc
}
}

Expand Down
Loading