Signal-iOS/SignalServiceKit/Payments/TSPaymentModels.m
2026-01-14 16:12:42 -06:00

399 lines
9.8 KiB
Objective-C

//
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
#import "TSPaymentModels.h"
#import <SignalServiceKit/SignalServiceKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN
NSString *NSStringFromTSPaymentCurrency(TSPaymentCurrency value)
{
switch (value) {
case TSPaymentCurrencyUnknown:
return @"Unknown";
case TSPaymentCurrencyMobileCoin:
return @"MobileCoin";
}
}
NSString *NSStringFromTSPaymentType(TSPaymentType value)
{
switch (value) {
case TSPaymentTypeIncomingPayment:
return @"IncomingPayment";
case TSPaymentTypeOutgoingPaymentNotFromLocalDevice:
return @"OutgoingPaymentNotFromLocalDevice";
case TSPaymentTypeOutgoingPayment:
return @"OutgoingPayment";
case TSPaymentTypeIncomingUnidentified:
return @"IncomingUnidentified";
case TSPaymentTypeOutgoingUnidentified:
return @"OutgoingUnidentified";
case TSPaymentTypeOutgoingTransfer:
return @"OutgoingTransfer";
case TSPaymentTypeOutgoingDefragmentation:
return @"OutgoingDefragmentation";
case TSPaymentTypeOutgoingDefragmentationNotFromLocalDevice:
return @"OutgoingDefragmentationNotFromLocalDevice";
case TSPaymentTypeIncomingRestored:
return @"IncomingRestoredPayment";
case TSPaymentTypeOutgoingRestored:
return @"OutgoingRestoredPayment";
default:
OWSCFailDebug(@"Unknown value: %d", (int)value);
return @"Unknown";
}
}
NSString *NSStringFromTSPaymentState(TSPaymentState value)
{
switch (value) {
case TSPaymentStateOutgoingUnsubmitted:
return @"OutgoingUnsubmitted";
case TSPaymentStateOutgoingUnverified:
return @"OutgoingUnverified";
case TSPaymentStateOutgoingVerified:
return @"OutgoingVerified";
case TSPaymentStateOutgoingSending:
return @"OutgoingSending";
case TSPaymentStateOutgoingSent:
return @"OutgoingSent";
case TSPaymentStateOutgoingComplete:
return @"OutgoingComplete";
case TSPaymentStateOutgoingFailed:
return @"OutgoingFailed";
case TSPaymentStateIncomingUnverified:
return @"IncomingUnverified";
case TSPaymentStateIncomingVerified:
return @"IncomingVerified";
case TSPaymentStateIncomingComplete:
return @"IncomingComplete";
case TSPaymentStateIncomingFailed:
return @"IncomingFailed";
default:
OWSCFailDebug(@"Unknown TSPaymentState.");
return @"Unknown";
}
}
NSString *NSStringFromTSPaymentFailure(TSPaymentFailure value)
{
switch (value) {
case TSPaymentFailureNone:
return @"None";
case TSPaymentFailureUnknown:
return @"Unknown";
case TSPaymentFailureInsufficientFunds:
return @"InsufficientFunds";
case TSPaymentFailureValidationFailed:
return @"ValidationFailed";
case TSPaymentFailureNotificationSendFailed:
return @"NotificationSendFailed";
case TSPaymentFailureInvalid:
return @"Invalid";
case TSPaymentFailureExpired:
return @"Expired";
default:
OWSCFailDebug(@"Unknown TSPaymentFailure.");
return @"Unknown";
}
}
#pragma mark -
@implementation TSPaymentAmount
- (instancetype)initWithCurrency:(TSPaymentCurrency)currency picoMob:(uint64_t)picoMob
{
self = [super init];
if (!self) {
return self;
}
_currency = currency;
_picoMob = picoMob;
OWSAssertDebug([self isValidAmountWithCanBeEmpty:YES]);
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:[self valueForKey:@"currency"] forKey:@"currency"];
[coder encodeObject:[self valueForKey:@"picoMob"] forKey:@"picoMob"];
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
self = [super init];
if (!self) {
return self;
}
self->_currency = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"currency"] unsignedIntegerValue];
self->_picoMob = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] forKey:@"picoMob"] unsignedLongLongValue];
return self;
}
- (NSUInteger)hash
{
NSUInteger result = 0;
result ^= self.currency;
result ^= self.picoMob;
return result;
}
- (BOOL)isEqual:(id)other
{
if (![other isMemberOfClass:self.class]) {
return NO;
}
TSPaymentAmount *typedOther = (TSPaymentAmount *)other;
if (self.currency != typedOther.currency) {
return NO;
}
if (self.picoMob != typedOther.picoMob) {
return NO;
}
return YES;
}
- (id)copyWithZone:(nullable NSZone *)zone
{
TSPaymentAmount *result = [[[self class] allocWithZone:zone] init];
result->_currency = self.currency;
result->_picoMob = self.picoMob;
return result;
}
@end
#pragma mark -
@implementation TSPaymentAddress
- (instancetype)initWithCurrency:(TSPaymentCurrency)currency
mobileCoinPublicAddressData:(NSData *)mobileCoinPublicAddressData
{
self = [super init];
if (!self) {
return self;
}
_currency = currency;
_mobileCoinPublicAddressData = mobileCoinPublicAddressData;
OWSAssertDebug(self.isValid);
return self;
}
- (NSUInteger)hash
{
NSUInteger result = 0;
result ^= self.currency;
result ^= self.mobileCoinPublicAddressData.hash;
return result;
}
- (BOOL)isEqual:(id)other
{
if (![other isMemberOfClass:self.class]) {
return NO;
}
TSPaymentAddress *typedOther = (TSPaymentAddress *)other;
if (self.currency != typedOther.currency) {
return NO;
}
if (![NSObject isObject:self.mobileCoinPublicAddressData equalToObject:typedOther.mobileCoinPublicAddressData]) {
return NO;
}
return YES;
}
@end
#pragma mark -
@implementation TSPaymentNotification
- (instancetype)initWithMemoMessage:(nullable NSString *)memoMessage mcReceiptData:(NSData *)mcReceiptData
{
self = [super init];
if (!self) {
return self;
}
_memoMessage = memoMessage;
_mcReceiptData = mcReceiptData;
OWSAssertDebug(self.isValid);
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
NSData *mcReceiptData = self.mcReceiptData;
if (mcReceiptData != nil) {
[coder encodeObject:mcReceiptData forKey:@"mcReceiptData"];
}
NSString *memoMessage = self.memoMessage;
if (memoMessage != nil) {
[coder encodeObject:memoMessage forKey:@"memoMessage"];
}
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
self = [super init];
if (!self) {
return self;
}
self->_mcReceiptData = [coder decodeObjectOfClass:[NSData class] forKey:@"mcReceiptData"];
self->_memoMessage = [coder decodeObjectOfClass:[NSString class] forKey:@"memoMessage"];
return self;
}
- (NSUInteger)hash
{
NSUInteger result = 0;
result ^= self.mcReceiptData.hash;
result ^= self.memoMessage.hash;
return result;
}
- (BOOL)isEqual:(id)other
{
if (![other isMemberOfClass:self.class]) {
return NO;
}
TSPaymentNotification *typedOther = (TSPaymentNotification *)other;
if (![NSObject isObject:self.mcReceiptData equalToObject:typedOther.mcReceiptData]) {
return NO;
}
if (![NSObject isObject:self.memoMessage equalToObject:typedOther.memoMessage]) {
return NO;
}
return YES;
}
- (id)copyWithZone:(nullable NSZone *)zone
{
TSPaymentNotification *result = [[[self class] allocWithZone:zone] init];
result->_mcReceiptData = self.mcReceiptData;
result->_memoMessage = self.memoMessage;
return result;
}
@end
#pragma mark -
@implementation TSArchivedPaymentInfo
- (instancetype)initWithAmount:(nullable NSString *)amount fee:(nullable NSString *)fee note:(nullable NSString *)note
{
self = [super init];
if (!self) {
return self;
}
_amount = amount;
_fee = fee;
_note = note;
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
NSString *amount = self.amount;
if (amount != nil) {
[coder encodeObject:amount forKey:@"amount"];
}
NSString *fee = self.fee;
if (fee != nil) {
[coder encodeObject:fee forKey:@"fee"];
}
NSString *note = self.note;
if (note != nil) {
[coder encodeObject:note forKey:@"note"];
}
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
self = [super init];
if (!self) {
return self;
}
self->_amount = [coder decodeObjectOfClass:[NSString class] forKey:@"amount"];
self->_fee = [coder decodeObjectOfClass:[NSString class] forKey:@"fee"];
self->_note = [coder decodeObjectOfClass:[NSString class] forKey:@"note"];
return self;
}
- (NSUInteger)hash
{
NSUInteger result = 0;
result ^= self.amount.hash;
result ^= self.fee.hash;
result ^= self.note.hash;
return result;
}
- (BOOL)isEqual:(id)other
{
if (![other isMemberOfClass:self.class]) {
return NO;
}
TSArchivedPaymentInfo *typedOther = (TSArchivedPaymentInfo *)other;
if (![NSObject isObject:self.amount equalToObject:typedOther.amount]) {
return NO;
}
if (![NSObject isObject:self.fee equalToObject:typedOther.fee]) {
return NO;
}
if (![NSObject isObject:self.note equalToObject:typedOther.note]) {
return NO;
}
return YES;
}
- (id)copyWithZone:(nullable NSZone *)zone
{
TSArchivedPaymentInfo *result = [[[self class] allocWithZone:zone] init];
result->_amount = self.amount;
result->_fee = self.fee;
result->_note = self.note;
return result;
}
@end
NS_ASSUME_NONNULL_END