github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/stellar/transform_cli.go (about)

     1  package stellar
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/keybase/client/go/libkb"
     7  	"github.com/keybase/client/go/protocol/keybase1"
     8  	"github.com/keybase/client/go/protocol/stellar1"
     9  	"github.com/keybase/client/go/stellar/relays"
    10  )
    11  
    12  func localizePayment(mctx libkb.MetaContext, p stellar1.PaymentSummary) (res stellar1.PaymentCLILocal, err error) {
    13  	typ, err := p.Typ()
    14  	if err != nil {
    15  		return res, fmt.Errorf("malformed payment summary: %v", err)
    16  	}
    17  	username := func(uid keybase1.UID) (username *string, err error) {
    18  		uname, err := mctx.G().GetUPAKLoader().LookupUsername(mctx.Ctx(), uid)
    19  		if err != nil {
    20  			return nil, err
    21  		}
    22  		tmp := uname.String()
    23  		return &tmp, nil
    24  	}
    25  	switch typ {
    26  	case stellar1.PaymentSummaryType_STELLAR:
    27  		p := p.Stellar()
    28  		return stellar1.PaymentCLILocal{
    29  			TxID:            p.TxID,
    30  			Time:            p.Ctime,
    31  			Status:          "Completed",
    32  			Amount:          p.Amount,
    33  			Asset:           p.Asset,
    34  			FromStellar:     p.From,
    35  			ToStellar:       &p.To,
    36  			Unread:          p.Unread,
    37  			IsAdvanced:      p.IsAdvanced,
    38  			SummaryAdvanced: p.SummaryAdvanced,
    39  			Operations:      p.Operations,
    40  		}, nil
    41  	case stellar1.PaymentSummaryType_DIRECT:
    42  		p := p.Direct()
    43  		res = stellar1.PaymentCLILocal{
    44  			TxID:               p.TxID,
    45  			Time:               p.Ctime,
    46  			Amount:             p.Amount,
    47  			Asset:              p.Asset,
    48  			DisplayAmount:      p.DisplayAmount,
    49  			DisplayCurrency:    p.DisplayCurrency,
    50  			FromStellar:        p.FromStellar,
    51  			ToStellar:          &p.ToStellar,
    52  			SourceAsset:        p.SourceAsset,
    53  			SourceAmountMax:    p.SourceAmountMax,
    54  			SourceAmountActual: p.SourceAmountActual,
    55  		}
    56  		res.Status, res.StatusDetail = p.TxStatus.Details(p.TxErrMsg)
    57  		res.FromUsername, err = username(p.From.Uid)
    58  		if err != nil {
    59  			return res, err
    60  		}
    61  		if p.To != nil {
    62  			res.ToUsername, err = username(p.To.Uid)
    63  			if err != nil {
    64  				return res, err
    65  			}
    66  		}
    67  		if len(p.NoteB64) > 0 {
    68  			note, err := NoteDecryptB64(mctx, p.NoteB64)
    69  			if err != nil {
    70  				res.NoteErr = fmt.Sprintf("failed to decrypt payment note: %v", err)
    71  			} else {
    72  				if note.StellarID != p.TxID {
    73  					res.NoteErr = "discarded note for wrong transaction ID"
    74  				} else {
    75  					res.Note = note.Note
    76  				}
    77  			}
    78  			if len(res.NoteErr) > 0 {
    79  				mctx.Warning(res.NoteErr)
    80  			}
    81  		}
    82  		return res, nil
    83  	case stellar1.PaymentSummaryType_RELAY:
    84  		p := p.Relay()
    85  		res = stellar1.PaymentCLILocal{
    86  			TxID:            p.TxID,
    87  			Time:            p.Ctime,
    88  			Amount:          p.Amount,
    89  			Asset:           stellar1.AssetNative(),
    90  			DisplayAmount:   p.DisplayAmount,
    91  			DisplayCurrency: p.DisplayCurrency,
    92  			FromStellar:     p.FromStellar,
    93  		}
    94  		if p.TxStatus != stellar1.TransactionStatus_SUCCESS {
    95  			// If the funding tx is not complete
    96  			res.Status, res.StatusDetail = p.TxStatus.Details(p.TxErrMsg)
    97  		} else {
    98  			res.Status = "Claimable"
    99  			res.StatusDetail = "Waiting for the recipient to open the app to claim, or the sender to cancel."
   100  		}
   101  		res.FromUsername, err = username(p.From.Uid)
   102  		if err != nil {
   103  			return res, err
   104  		}
   105  		if p.To != nil {
   106  			res.ToUsername, err = username(p.To.Uid)
   107  			if err != nil {
   108  				return res, err
   109  			}
   110  		}
   111  		if p.ToAssertion != "" {
   112  			res.ToAssertion = &p.ToAssertion
   113  		}
   114  		// Override status with claim status
   115  		if p.Claim != nil {
   116  			if p.Claim.TxStatus == stellar1.TransactionStatus_SUCCESS {
   117  				// If the claim succeeded, the relay payment is done.
   118  				switch p.Claim.Dir {
   119  				case stellar1.RelayDirection_CLAIM:
   120  					res.Status = "Completed"
   121  				case stellar1.RelayDirection_YANK:
   122  					res.Status = "Canceled"
   123  				}
   124  				res.ToStellar = &p.Claim.ToStellar
   125  				res.ToUsername, err = username(p.Claim.To.Uid)
   126  				if err != nil {
   127  					return res, err
   128  				}
   129  			} else {
   130  				claimantUsername, err := username(p.Claim.To.Uid)
   131  				if err != nil {
   132  					return res, err
   133  				}
   134  				res.Status, res.StatusDetail = p.Claim.TxStatus.Details(p.Claim.TxErrMsg)
   135  				res.Status = fmt.Sprintf("Funded. Claim by %v is: %v", *claimantUsername, res.Status)
   136  			}
   137  		}
   138  		relaySecrets, err := relays.DecryptB64(mctx, p.TeamID, p.BoxB64)
   139  		if err == nil {
   140  			res.Note = relaySecrets.Note
   141  		} else {
   142  			res.NoteErr = fmt.Sprintf("error decrypting note box: %v", err)
   143  		}
   144  		return res, nil
   145  	default:
   146  		return res, fmt.Errorf("unrecognized payment summary type: %v", typ)
   147  	}
   148  }