[Refactoring] Extract AlphaWalletTokenScript pod

pull/6884/head
Hwee-Boon Yar 1 year ago
parent 50893a74c2
commit 0445e0e178
  1. 8
      AlphaWallet.xcodeproj/project.pbxproj
  2. 2
      AlphaWallet/ActiveWalletCoordinator.swift
  3. 6
      AlphaWallet/Activities/ViewModels/ActivityViewModel.swift
  4. 4
      AlphaWallet/Activities/ViewModels/DefaultActivityCellViewModel.swift
  5. 1
      AlphaWallet/AlphaWalletHelp/Views/ContactUsBannerView.swift
  6. 1
      AlphaWallet/Browser/Views/DappBrowserNavigationBar.swift
  7. 34
      AlphaWallet/Common/Services/Application.swift
  8. 1
      AlphaWallet/Common/Services/FirebaseReportService.swift
  9. 1
      AlphaWallet/Common/Views/ViewModels/TokenCardRowViewModel.swift
  10. 2
      AlphaWallet/Market/ImportMagicLinkController.swift
  11. 3
      AlphaWallet/Market/ViewModels/ImportMagicTokenCardRowViewModel.swift
  12. 5
      AlphaWallet/Redeem/ViewModels/RedeemTokenCardQuantitySelectionViewModel.swift
  13. 1
      AlphaWallet/Sell/ViewControllers/SetSellTokensCardExpiryDateViewController.swift
  14. 1
      AlphaWallet/Settings/ViewModels/EnabledServersViewModel.swift
  15. 1
      AlphaWallet/Settings/ViewModels/SettingsViewModel.swift
  16. 5
      AlphaWallet/Swap/Swap/ViewModels/SwapQuoteDetailsViewModel.swift
  17. 2
      AlphaWallet/TokenScript/Coordinators/AssetDefinitionStoreCoordinator.swift
  18. 1
      AlphaWallet/Tokens/Collectibles/ViewModels/NFTCollectionInfoPageViewModel.swift
  19. 1
      AlphaWallet/Tokens/Collectibles/Views/NonFungibleRowView.swift
  20. 1
      AlphaWallet/Tokens/NftAssetDisplayHelper.swift
  21. 1
      AlphaWallet/Tokens/NftCollectionDisplayHelper.swift
  22. 3
      AlphaWallet/Tokens/TokenScriptOverrides+Extensions.swift
  23. 1
      AlphaWallet/Tokens/ViewControllers/NewTokenViewController.swift
  24. 8
      AlphaWallet/Tokens/ViewControllers/TokenInstanceActionViewController.swift
  25. 1
      AlphaWallet/Tokens/ViewControllers/VerifiableStatusViewController.swift
  26. 1
      AlphaWallet/Tokens/ViewModels/TokenCardWebViewModel.swift
  27. 7
      AlphaWallet/Tokens/Views/TokenInstanceWebView.swift
  28. 1
      AlphaWallet/Transfer/Collectibles/ViewModels/SendSemiFungibleTokenViewModel.swift
  29. 21
      AlphaWallet/Transfer/Coordinators/TokenScriptCoordinator.swift
  30. 15
      AlphaWallet/Types/ImportedTypes.swift
  31. 34
      AlphaWalletABI.podspec
  32. 6
      AlphaWalletAddress.podspec
  33. 1
      AlphaWalletAttestation.podspec
  34. 5
      AlphaWalletCore.podspec
  35. 25
      AlphaWalletFoundation.podspec
  36. 1
      AlphaWalletGoBack.podspec
  37. 2
      AlphaWalletHardwareWallet.podspec
  38. 2
      AlphaWalletLogger.podspec
  39. 2
      AlphaWalletNotifications.podspec
  40. 1
      AlphaWalletOpenSea.podspec
  41. 1
      AlphaWalletShareExtensionCore.podspec
  42. 15
      AlphaWalletTests/Coordinators/ActiveWalletViewTests.swift
  43. 1
      AlphaWalletTests/Core/Types/FunctionCallArgumentTests.swift
  44. 21
      AlphaWalletTests/Factories/FakeSessionsProvider.swift
  45. 1
      AlphaWalletTests/Settings/ConfigTests.swift
  46. 3
      AlphaWalletTests/TokenScriptClient/AssetDefinitionDiskBackingStoreWithOverridesTests.swift
  47. 7
      AlphaWalletTests/TokenScriptClient/AssetDefinitionStoreTests.swift
  48. 3
      AlphaWalletTests/TokenScriptClient/TokenScriptFilterParserTests.swift
  49. 12
      AlphaWalletTests/TokenScriptClient/TokenScriptSignatureVerifierTest.swift
  50. 12
      AlphaWalletTests/TokenScriptClient/XMLHandlerTest.swift
  51. 6
      AlphaWalletTests/Transfer/Types/UnconfirmedTransactionTests.swift
  52. 3
      AlphaWalletTests/ViewControllers/PaymentCoordinatorTests.swift
  53. 39
      AlphaWalletTokenScript.podspec
  54. 1
      AlphaWalletTrackAPICalls.podspec
  55. 2
      AlphaWalletTrustWalletCoreExtensions.podspec
  56. 3
      AlphaWalletWeb3.podspec
  57. 2
      Podfile
  58. 57
      Podfile.lock
  59. 1
      modules/AlphaWalletABI/AlphaWalletABI/ABI/ABI.swift
  60. 3
      modules/AlphaWalletABI/AlphaWalletABI/ABI/ERC1155.swift
  61. 3
      modules/AlphaWalletABI/AlphaWalletABI/ABI/ERC20.swift
  62. 3
      modules/AlphaWalletABI/AlphaWalletABI/ABI/ERC721.swift
  63. 3
      modules/AlphaWalletABI/AlphaWalletABI/ABIEncoder.swift
  64. 13
      modules/AlphaWalletABI/AlphaWalletABI/AlphaWalletABI.h
  65. 0
      modules/AlphaWalletABI/AlphaWalletABI/Types/ABIError.swift
  66. 0
      modules/AlphaWalletABI/AlphaWalletABI/Types/ABIType.swift
  67. 3
      modules/AlphaWalletABI/AlphaWalletABI/Types/ABIValue.swift
  68. 17
      modules/AlphaWalletABI/AlphaWalletABI/Types/DecodedFunctionCall+Decode.swift
  69. 1
      modules/AlphaWalletABI/AlphaWalletABI/Types/DecodedFunctionCall.swift
  70. 0
      modules/AlphaWalletABI/AlphaWalletABI/Types/Function.swift
  71. 21
      modules/AlphaWalletABI/LICENSE
  72. 19
      modules/AlphaWalletAddress/AlphaWalletAddress/Extensions/Data+Extensions.swift
  73. 15
      modules/AlphaWalletAddress/AlphaWalletAddress/Extensions/EthereumAddress_fromWeb3SwiftPod.swift
  74. 88
      modules/AlphaWalletAddress/AlphaWalletAddress/Extensions/String+Extensions.swift
  75. 36
      modules/AlphaWalletAddress/AlphaWalletAddress/ThirdPartyAddress+Extension.swift
  76. 0
      modules/AlphaWalletCore/AlphaWalletCore/CryptoAddressValidator.swift
  77. 11
      modules/AlphaWalletCore/AlphaWalletCore/Extensions/Array+Extensions.swift
  78. 12
      modules/AlphaWalletCore/AlphaWalletCore/Extensions/Collection+Extensions.swift
  79. 59
      modules/AlphaWalletCore/AlphaWalletCore/Extensions/Data+Extensions.swift
  80. 20
      modules/AlphaWalletCore/AlphaWalletCore/Extensions/Date+Extensions.swift
  81. 4
      modules/AlphaWalletCore/AlphaWalletCore/Extensions/Dictionary+Extensions.swift
  82. 54
      modules/AlphaWalletCore/AlphaWalletCore/Extensions/Publisher+Extensions.swift
  83. 25
      modules/AlphaWalletCore/AlphaWalletCore/Extensions/Publisher+Utils.swift.swift
  84. 109
      modules/AlphaWalletCore/AlphaWalletCore/Extensions/String+Extensions.swift
  85. 22
      modules/AlphaWalletCore/AlphaWalletCore/Extensions/StringProtocol+Extensions.swift
  86. 0
      modules/AlphaWalletCore/AlphaWalletCore/Extensions/URL+Extensions.swift
  87. 14
      modules/AlphaWalletCore/AlphaWalletCore/Extensions/UserDefaults+Extensions.swift
  88. 19
      modules/AlphaWalletCore/AlphaWalletCore/Networking/NetworkService.swift
  89. 0
      modules/AlphaWalletCore/AlphaWalletCore/Networking/ReachabilityManager.swift
  90. 0
      modules/AlphaWalletCore/AlphaWalletCore/Types/AtomicArray.swift
  91. 0
      modules/AlphaWalletCore/AlphaWalletCore/Types/AtomicDictionary.swift
  92. 0
      modules/AlphaWalletCore/AlphaWalletCore/Types/CastError.swift
  93. 15
      modules/AlphaWalletCore/AlphaWalletCore/Types/CustomRPC.swift
  94. 6
      modules/AlphaWalletCore/AlphaWalletCore/Types/DecodeError.swift
  95. 0
      modules/AlphaWalletCore/AlphaWalletCore/Types/Loadable.swift
  96. 185
      modules/AlphaWalletCore/AlphaWalletCore/Types/RPCServer.swift
  97. 11
      modules/AlphaWalletCore/AlphaWalletCore/Types/ServerDictionary.swift
  98. 2
      modules/AlphaWalletCore/AlphaWalletCore/Types/Subscribable.swift
  99. 0
      modules/AlphaWalletCore/AlphaWalletCore/Types/WebImageURL.swift
  100. 0
      modules/AlphaWalletCore/AlphaWalletCore/Utils/attempt.swift
  101. Some files were not shown because too many files have changed in this diff Show More

@ -415,6 +415,7 @@
5E7C7F61D540CAFC68D6843D /* WebImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C77A8E9F8DF94ED53D452 /* WebImageView.swift */; };
5E7C7F67945615E242B61CC3 /* BoxView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7C5454600A70DCFD7C0E /* BoxView.swift */; };
5E7C7F69EBFEEBFBDB381F6E /* AttestationViewCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7B55ABB480A38611D682 /* AttestationViewCellViewModel.swift */; };
5E7C7F776D272AC23213B3BA /* ImportedTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7864DB8E82BACE2F5F1F /* ImportedTypes.swift */; };
5E7C7F808D0B0B19ECEA6623 /* ETH.tsml in Resources */ = {isa = PBXBuildFile; fileRef = 5E7C768D3C3F400E0B88B575 /* ETH.tsml */; };
5E7C7F8271F730462D4E3D93 /* FakeBlockiesGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C737AF4E3BED49DD63CF4 /* FakeBlockiesGenerator.swift */; };
5E7C7F906FE07C75F357569B /* DAI.tsml in Resources */ = {isa = PBXBuildFile; fileRef = 5E7C75D9C3EA9FF978ECF8E5 /* DAI.tsml */; };
@ -1222,6 +1223,7 @@
5E7C783E3ADA4CF9554A0E7D /* NonFungibleTokenViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NonFungibleTokenViewCell.swift; sourceTree = "<group>"; };
5E7C78402B975F69A72E8C04 /* TokensViewControllerTableViewHeader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokensViewControllerTableViewHeader.swift; sourceTree = "<group>"; };
5E7C78454B11E39CF8B5E695 /* EnterPasswordCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnterPasswordCoordinator.swift; sourceTree = "<group>"; };
5E7C7864DB8E82BACE2F5F1F /* ImportedTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ImportedTypes.swift; path = Types/ImportedTypes.swift; sourceTree = "<group>"; };
5E7C786E7AACC1ECD44F2EAA /* DecodedFunctionCall+DecodeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DecodedFunctionCall+DecodeTests.swift"; sourceTree = "<group>"; };
5E7C78795F6336DDBE2EB4C5 /* ERC20-TokenScript.tsml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.tsml; path = "ERC20-TokenScript.tsml"; sourceTree = "<group>"; };
5E7C788ADDEA0609433B1FDF /* VerifySeedPhraseViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerifySeedPhraseViewController.swift; sourceTree = "<group>"; };
@ -2047,6 +2049,7 @@
5E7C74F0A1BB877A6FE35F37 /* BuyCrypto */,
5E7C704885516A808B3B8866 /* ErrorLocalizations.swift */,
5E7C7D784300C463FF3C7514 /* HardwareWallet */,
5E7C7864DB8E82BACE2F5F1F /* ImportedTypes.swift */,
);
path = AlphaWallet;
sourceTree = "<group>";
@ -4966,6 +4969,7 @@
"${PODS_ROOT}/Target Support Files/Pods-AlphaWallet/Pods-AlphaWallet-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/APIKit/APIKit.framework",
"${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework",
"${BUILT_PRODUCTS_DIR}/AlphaWalletABI/AlphaWalletABI.framework",
"${BUILT_PRODUCTS_DIR}/AlphaWalletAddress/AlphaWalletAddress.framework",
"${BUILT_PRODUCTS_DIR}/AlphaWalletAttestation/AlphaWalletAttestation.framework",
"${BUILT_PRODUCTS_DIR}/AlphaWalletCore/AlphaWalletCore.framework",
@ -4977,6 +4981,7 @@
"${BUILT_PRODUCTS_DIR}/AlphaWalletNotifications/AlphaWalletNotifications.framework",
"${BUILT_PRODUCTS_DIR}/AlphaWalletOpenSea/AlphaWalletOpenSea.framework",
"${BUILT_PRODUCTS_DIR}/AlphaWalletShareExtensionCore/AlphaWalletShareExtensionCore.framework",
"${BUILT_PRODUCTS_DIR}/AlphaWalletTokenScript/AlphaWalletTokenScript.framework",
"${BUILT_PRODUCTS_DIR}/AlphaWalletTrackAPICalls/AlphaWalletTrackAPICalls.framework",
"${BUILT_PRODUCTS_DIR}/AlphaWalletTrustWalletCoreExtensions/AlphaWalletTrustWalletCoreExtensions.framework",
"${BUILT_PRODUCTS_DIR}/AlphaWalletWeb3/AlphaWalletWeb3.framework",
@ -5033,6 +5038,7 @@
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/APIKit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AlphaWalletABI.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AlphaWalletAddress.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AlphaWalletAttestation.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AlphaWalletCore.framework",
@ -5044,6 +5050,7 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AlphaWalletNotifications.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AlphaWalletOpenSea.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AlphaWalletShareExtensionCore.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AlphaWalletTokenScript.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AlphaWalletTrackAPICalls.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AlphaWalletTrustWalletCoreExtensions.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AlphaWalletWeb3.framework",
@ -5884,6 +5891,7 @@
5E7C7DFB3A663A3581A8C3CB /* AcceptProposalCoordinator.swift in Sources */,
5E7C74D586547B32EF5CD91C /* AcceptProposalViewController.swift in Sources */,
5E7C7270C6A83CC1ADC106DC /* AcceptAuthRequestViewController.swift in Sources */,
5E7C7F776D272AC23213B3BA /* ImportedTypes.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

@ -1,9 +1,9 @@
import UIKit
import PromiseKit
import Combine
import AlphaWalletCore
import AlphaWalletFoundation
import AlphaWalletLogger
import AlphaWalletCore
import AlphaWalletNotifications
// swiftlint:disable file_length

@ -1,10 +1,10 @@
// Copyright © 2020 Stormbird PTE. LTD.
import Combine
import Foundation
import BigInt
import AlphaWalletFoundation
import UIKit
import Combine
import AlphaWalletFoundation
import BigInt
struct ActivityViewModel {
let activity: Activity

@ -1,9 +1,9 @@
// Copyright © 2020 Stormbird PTE. LTD.
import UIKit
import BigInt
import AlphaWalletFoundation
import Combine
import AlphaWalletFoundation
import BigInt
struct DefaultActivityCellViewModel {
private var server: RPCServer {

@ -3,6 +3,7 @@
import UIKit
import MessageUI
import AlphaWalletFoundation
import enum AlphaWalletTokenScript.TokenScript
protocol ContactUsBannerViewDelegate: AnyObject {
func present(_ viewController: UIViewController, for view: ContactUsBannerView)

@ -1,6 +1,7 @@
// Copyright © 2018 Stormbird PTE. LTD.
import UIKit
import AlphaWalletCore
import AlphaWalletFoundation
protocol DappBrowserNavigationBarDelegate: AnyObject {

@ -13,6 +13,7 @@ import AlphaWalletFoundation
import AlphaWalletLogger
import AlphaWalletTrackAPICalls
import AlphaWalletNotifications
import AlphaWalletTokenScript
extension TokenScript {
static let baseTokenScriptFiles: [TokenType: String] = [
@ -48,6 +49,8 @@ class Application: WalletDependenciesProvidable {
let legacyFileBasedKeystore: LegacyFileBasedKeystore
let lock: Lock
let keystore: Keystore
//This exist because feature flags are set at the app level (as of 20230709: AlpahWalletFoundation), but we read a few of those flags within AlphaWalletTokenScript
let tokenScriptFeatures: TokenScriptFeatures
let assetDefinitionStore: AssetDefinitionStore
let appTracker: AppTracker
let universalLinkService: UniversalLinkService
@ -119,7 +122,7 @@ class Application: WalletDependenciesProvidable {
self.caip10AccountProvidable = AnyCAIP10AccountProvidable(keystore: keystore, serversProvidable: serversProvider)
self.currencyService = CurrencyService(storage: config)
self.walletBalanceService = MultiWalletBalanceService(currencyService: currencyService)
self.networkService = BaseNetworkService(analytics: analytics)
self.networkService = BaseNetworkService()
let navigationHandler = ApplicationNavigationHandler(subject: navigationSubject)
self.universalLinkService = BaseUniversalLinkService(
analytics: analytics,
@ -130,16 +133,13 @@ class Application: WalletDependenciesProvidable {
self.tokenGroupIdentifier = TokenGroupIdentifier.identifier(tokenJsonUrl: R.file.tokensJson()!)!
self.systemSettingsRequestableDelegate = SystemSettingsRequestableDelegate()
self.blockchainsProvider = BlockchainsProvider(
self.blockchainsProvider = BlockchainsProviderImplementation(
serversProvider: serversProvider,
blockchainFactory: BaseBlockchainFactory(
config: config,
analytics: analytics))
self.assetDefinitionStore = AssetDefinitionStore(
baseTokenScriptFiles: TokenScript.baseTokenScriptFiles,
networkService: networkService,
blockchainsProvider: blockchainsProvider)
blockchainFactory: BaseBlockchainFactory(analytics: analytics))
let tokenScriptFeatures = TokenScriptFeatures()
Self.copyFeatures(Features.default, toTokenScriptFeatures: tokenScriptFeatures)
self.tokenScriptFeatures = tokenScriptFeatures
self.assetDefinitionStore = AssetDefinitionStore(baseTokenScriptFiles: TokenScript.baseTokenScriptFiles, networkService: networkService, blockchainsProvider: blockchainsProvider, features: tokenScriptFeatures)
self.coinTickersFetcher = CoinTickersFetcherImpl(
transporter: BaseApiTransporter(),
@ -214,6 +214,8 @@ class Application: WalletDependenciesProvidable {
donationUserActivityHandler
])
Features.delegate = self
bindWalletAddressesStore()
handleTokenScriptOverrideImport()
}
@ -503,6 +505,12 @@ class Application: WalletDependenciesProvidable {
guard let wallet = dependencies.values.keys.first(where: { $0.address == walletAddress }) else { return nil }
return dependencies[wallet]
}
private static func copyFeatures(_ features: Features, toTokenScriptFeatures tokenScriptFeatures: TokenScriptFeatures) {
tokenScriptFeatures.isActivityEnabled = features.isAvailable(.isActivityEnabled)
tokenScriptFeatures.isTokenScriptSignatureStatusEnabled = features.isAvailable(.isTokenScriptSignatureStatusEnabled)
tokenScriptFeatures.shouldLoadTokenScriptWithFailedSignatures = features.isAvailable(.shouldLoadTokenScriptWithFailedSignatures )
}
}
// swiftlint:enable type_body_length
@ -528,6 +536,12 @@ extension Application: WalletApiCoordinatorDelegate {
extension Application: ShortcutNavigatable { }
extension Application: FeaturesDelegate {
func featuresModified(_ features: Features) {
Self.copyFeatures(features, toTokenScriptFeatures: tokenScriptFeatures)
}
}
extension AtomicDictionary: WalletDependenciesProvidable where Key == Wallet, Value == WalletDependencies {
public func walletDependencies(walletAddress: AlphaWallet.Address) -> WalletDependencies? {
guard let wallet = values.keys.first(where: { $0.address == walletAddress }) else { return nil }

@ -6,6 +6,7 @@
//
import FirebaseCore
import FirebaseCrashlytics
import func AlphaWalletCore.isRunningTests
import AlphaWalletFoundation
import AlphaWalletLogger

@ -2,6 +2,7 @@
import Foundation
import AlphaWalletFoundation
import AlphaWalletTokenScript
import Combine
struct TokenCardRowViewModel: TokenCardRowViewModelProtocol {

@ -346,7 +346,7 @@ final class ImportMagicLinkController {
name: name,
symbol: symbol,
fromTokenIdOrEvent: .tokenId(tokenId: tokenId), index: UInt16(i),
inWallet: wallet,
inWallet: wallet.address,
server: server,
tokenType: tokenType,
assetDefinitionStore: assetDefinitionStore)

@ -1,9 +1,10 @@
// Copyright © 2018 Stormbird PTE. LTD.
import Foundation
import AlphaWalletFoundation
import Combine
import AlphaWalletCore
import AlphaWalletFoundation
import AlphaWalletTokenScript
struct ImportMagicTokenCardRowViewModel: TokenCardRowViewModelProtocol {
private let viewModel: ImportMagicTokenViewModel

@ -9,6 +9,7 @@
import Foundation
import UIKit
import AlphaWalletFoundation
import AlphaWalletTokenScript
struct RedeemTokenCardQuantitySelectionViewModel {
let token: Token
@ -34,7 +35,7 @@ struct RedeemTokenCardQuantitySelectionViewModel {
extension XMLHandler {
func getLabel() -> String {
let name = getLabel(fallback: R.string.localizable.tokenTitlecase())
if name == Constants.katNameFallback {
if name == AlphaWalletTokenScript.Constants.katNameFallback {
return R.string.localizable.katTitlecase()
} else {
return name
@ -43,7 +44,7 @@ extension XMLHandler {
func getNameInPluralForm() -> String {
let name = getNameInPluralForm(fallback: R.string.localizable.tokensTitlecase())
if name == Constants.katNameFallback {
if name == AlphaWalletTokenScript.Constants.katNameFallback {
return R.string.localizable.katTitlecase()
} else {
return name

@ -1,6 +1,7 @@
// Copyright © 2018 Stormbird PTE. LTD.
import UIKit
import AlphaWalletCore
import AlphaWalletFoundation
protocol SetSellTokensCardExpiryDateViewControllerDelegate: AnyObject, CanOpenURL {

@ -1,6 +1,7 @@
// Copyright © 2018 Stormbird PTE. LTD.
import Foundation
import AlphaWalletCore
import AlphaWalletFoundation
import Combine

@ -5,6 +5,7 @@ import UIKit
import Combine
import AlphaWalletFoundation
import AlphaWalletNotifications
import AlphaWalletTokenScript
struct SettingsViewModelInput {
let willAppear: AnyPublisher<Void, Never>

@ -5,10 +5,11 @@
// Created by Vladyslav Shepitko on 28.03.2022.
//
import UIKit
import Combine
import BigInt
import UIKit
import AlphaWalletFoundation
import enum AlphaWalletTokenScript.TokenLevelTokenScriptDisplayStatus
import BigInt
struct SwapQuoteDetailsViewModelInput {

@ -12,7 +12,7 @@ class AssetDefinitionStoreCoordinator: Coordinator {
private let tokenScriptOverridesFileManager: TokenScriptOverridesFileManager
private let navigationController: UINavigationController
private lazy var rootViewController: AssetDefinitionsOverridesViewController = {
let viewModel = AssetDefinitionsOverridesViewModel(tokenScriptOverridesFileManager: tokenScriptOverridesFileManager, fileExtension: AssetDefinitionDiskBackingStore.fileExtension)
let viewModel = AssetDefinitionsOverridesViewModel(tokenScriptOverridesFileManager: tokenScriptOverridesFileManager, fileExtension: XMLHandler.fileExtension)
let viewController = AssetDefinitionsOverridesViewController(viewModel: viewModel)
viewController.delegate = self
viewController.hidesBottomBarWhenPushed = true

@ -10,6 +10,7 @@ import BigInt
import Combine
import AlphaWalletFoundation
import AlphaWalletCore
import struct AlphaWalletTokenScript.Constants
struct NFTCollectionInfoPageViewModelInput {
let selection: AnyPublisher<IndexPath, Never>

@ -7,6 +7,7 @@
import UIKit
import AlphaWalletFoundation
import struct AlphaWalletTokenScript.TokenId
class NonFungibleRowView: TokenCardViewRepresentable {
private let titleLabel = UILabel()

@ -8,6 +8,7 @@
import Foundation
import AlphaWalletOpenSea
import AlphaWalletFoundation
import AlphaWalletTokenScript
import Combine
final class NftAssetDisplayHelper {

@ -8,6 +8,7 @@
import Foundation
import AlphaWalletOpenSea
import AlphaWalletFoundation
import AlphaWalletTokenScript
final class NftCollectionDisplayHelper {
private (set) var tokenId: TokenId

@ -2,13 +2,14 @@
import Foundation
import AlphaWalletFoundation
import AlphaWalletTokenScript
extension TokenScriptOverrides {
//TODO: Not good to require to use safeTitleInPluralForm. Easy to access wrong var
///Use this instead of shortTitleInPluralForm directly
var safeShortTitleInPluralForm: String? {
let s = shortTitleInPluralForm
if s == Constants.katNameFallback {
if s == AlphaWalletTokenScript.Constants.katNameFallback {
return R.string.localizable.katTitlecase()
} else {
return s

@ -2,6 +2,7 @@
import Foundation
import UIKit
import struct AlphaWalletCore.CryptoAddressValidator
import AlphaWalletFoundation
protocol NewTokenViewControllerDelegate: AnyObject {

@ -2,11 +2,11 @@
import Foundation
import UIKit
import BigInt
import PromiseKit
import Combine
import AlphaWalletFoundation
import AlphaWalletCore
import Combine
import BigInt
import PromiseKit
protocol TokenInstanceActionViewControllerDelegate: AnyObject, CanOpenURL, RequestSignMessageDelegate {
func didPressViewRedemptionInfo(in viewController: TokenInstanceActionViewController)
@ -140,7 +140,7 @@ class TokenInstanceActionViewController: UIViewController, TokenVerifiableStatus
.resolve(withTokenIdOrEvent: tokenHolder.tokens[0].tokenIdOrEvent,
userEntryValues: .init(),
server: server,
account: session.account,
account: session.account.address,
additionalValues: existingAttributeValues,
localRefs: tokenScriptRendererView.localRefs,
attributes: action.attributes)

@ -3,6 +3,7 @@
import UIKit
import PromiseKit
import AlphaWalletFoundation
import enum AlphaWalletTokenScript.TokenLevelTokenScriptDisplayStatus
@objc protocol VerifiableStatusViewController: CanOpenURL2 {
func showContractWebPage()

@ -7,6 +7,7 @@
import UIKit
import AlphaWalletFoundation
import AlphaWalletTokenScript
struct TokenCardWebViewModel {
let tokenHolder: TokenHolder

@ -2,12 +2,13 @@
import Foundation
import UIKit
import BigInt
import PromiseKit
import WebKit
import Combine
import AlphaWalletFoundation
import AlphaWalletCore
import AlphaWalletTokenScript
import BigInt
import PromiseKit
protocol RequestSignMessageDelegate: AnyObject {
func requestSignMessage(message: SignMessageType,
@ -209,7 +210,7 @@ class TokenInstanceWebView: UIView, TokenScriptLocalRefsSource {
.resolve(withTokenIdOrEvent: .tokenId(tokenId: tokenHolder.tokenIds[0]),
userEntryValues: .init(),
server: server,
account: wallet,
account: wallet.address,
additionalValues: .init(),
localRefs: localRefs,
attributes: attributes)

@ -7,6 +7,7 @@
import UIKit
import AlphaWalletFoundation
import enum AlphaWalletTokenScript.OpenURLError
import Combine
final class SendSemiFungibleTokenViewModel {

@ -6,10 +6,11 @@
//
import UIKit
import BigInt
import Combine
import AlphaWalletFoundation
import AlphaWalletCore
import AlphaWalletFoundation
import AlphaWalletTokenScript
import BigInt
protocol TokenScriptCoordinatorDelegate: CanOpenURL, SendTransactionDelegate, BuyCryptoDelegate {
func didFinish(_ result: ConfirmResult, in coordinator: TokenScriptCoordinator)
@ -224,22 +225,14 @@ extension TokenScriptCoordinator: TransactionInProgressCoordinatorDelegate {
extension TokenScriptCoordinator: ConfirmTokenScriptActionTransactionDelegate {
func confirmTransactionSelected(in navigationController: UINavigationController, token: Token, contract: AlphaWallet.Address, tokenId: TokenId, values: [AttributeId: AssetInternalValue], localRefs: [AttributeId: AssetInternalValue], server: RPCServer, session: WalletSession, keystore: Keystore, transactionFunction: FunctionOrigin) {
do {
let data = try transactionFunction.makeUnConfirmedTransaction(
withTokenObject: token,
tokenId: tokenId,
attributeAndValues: values,
localRefs: localRefs,
server: server,
session: session)
let tokenScriptUnconfirmedTransaction: TokenScriptUnconfirmedTransaction = try transactionFunction.makeUnConfirmedTransaction(tokenServer: token.server, tokenId: tokenId, attributeAndValues: values, localRefs: localRefs, server: server, wallet: session.account.address)
let unconfirmedTransaction: UnconfirmedTransaction = UnconfirmedTransaction(transactionType: TransactionType.prebuilt(tokenScriptUnconfirmedTransaction.server), value: tokenScriptUnconfirmedTransaction.value, recipient: tokenScriptUnconfirmedTransaction.recipient, contract: tokenScriptUnconfirmedTransaction.contract, data: tokenScriptUnconfirmedTransaction.data)
let coordinator = TransactionConfirmationCoordinator(
presentingViewController: navigationController,
session: session,
transaction: data.0,
configuration: .tokenScriptTransaction(
confirmType: .signThenSend,
contract: contract,
functionCallMetaData: data.1),
transaction: unconfirmedTransaction,
configuration: .tokenScriptTransaction(confirmType: .signThenSend, contract: contract, functionCallMetaData: tokenScriptUnconfirmedTransaction.decodedFunctionCall),
analytics: analytics,
domainResolutionService: domainResolutionService,
keystore: keystore,

@ -0,0 +1,15 @@
// Copyright © 2023 Stormbird PTE. LTD.
import AlphaWalletCore
typealias ReachabilityManager = AlphaWalletCore.ReachabilityManager
typealias Loadable = AlphaWalletCore.Loadable
typealias ReachabilityManagerProtocol = AlphaWalletCore.ReachabilityManagerProtocol
import AlphaWalletTokenScript
typealias AssetAttributeValues = AlphaWalletTokenScript.AssetAttributeValues
typealias AssetAttribute = AlphaWalletTokenScript.AssetAttribute
typealias AssetInternalValue = AlphaWalletTokenScript.AssetInternalValue
typealias AttributeId = AlphaWalletTokenScript.AttributeId
typealias GeneralisedTime = AlphaWalletTokenScript.GeneralisedTime
typealias TokenScript = AlphaWalletTokenScript.TokenScript
typealias XMLHandler = AlphaWalletTokenScript.XMLHandler

@ -0,0 +1,34 @@
#
# Be sure to run `pod lib lint AlphaWalletABI.podspec' to ensure this is a
# valid spec before submitting.
#
# Any lines starting with a # are optional, but their use is encouraged
# To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html
#
Pod::Spec.new do |s|
s.name = 'AlphaWalletABI'
s.version = '1.0.0'
s.summary = 'AlphaWallet ABI library'
s.description = <<-DESC
Lightweight library representing the AlphaWallet ABI functionality
DESC
s.homepage = "https://github.com/AlphaWallet/alpha-wallet-ios/tree/master/modules/AlphaWalletABI"
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { "Hwee-Boon Yar" => "hboon@motionobj.com" }
s.social_media_url = "https://twitter.com/hboon"
s.ios.deployment_target = '13.0'
s.swift_version = '5.0'
s.platform = :ios, "13.0"
s.source = { :git => 'git@github.com:AlphaWallet/alpha-wallet-ios.git', :tag => "#{s.version}" }
s.source_files = 'modules/AlphaWalletABI/AlphaWalletABI/**/*.{h,m,swift}'
s.pod_target_xcconfig = { 'SWIFT_OPTIMIZATION_LEVEL' => '-Owholemodule' }
s.frameworks = 'Foundation'
s.dependency 'AlphaWalletAddress'
s.dependency 'AlphaWalletWeb3'
s.dependency 'EthereumABI'
s.dependency 'TrustKeystore'
end

@ -25,8 +25,8 @@ Pod::Spec.new do |s|
s.frameworks = 'Foundation'
s.dependency 'TrustKeystore'
s.dependency 'AlphaWalletWeb3'
s.dependency 'EthereumAddress'
#Should not include any more of our own pods as dependency unless that pod is never going to have a dependency on this pod
s.dependency 'AlphaWalletCore'
s.dependency 'EthereumAddress'
s.dependency 'TrustKeystore'
end

@ -26,6 +26,7 @@ s.public_header_files = "AlphaWalletAttestation/**/*.{h}"
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
s.dependency 'AlphaWalletFoundation'
s.dependency 'AlphaWalletTokenScript'
s.dependency 'AlphaWalletWeb3'
s.dependency 'BigInt'
s.dependency 'GzipSwift'

@ -23,8 +23,13 @@ Pod::Spec.new do |s|
s.source_files = 'modules/AlphaWalletCore/AlphaWalletCore/**/*.{h,m,swift}'
s.pod_target_xcconfig = { 'SWIFT_OPTIMIZATION_LEVEL' => '-Owholemodule' }
s.frameworks = 'Combine'
s.frameworks = 'Foundation'
#Should not include any of our own pods as dependency unless that pod is never going to have a dependency on this pod
s.dependency 'Alamofire', '5.6.4'
s.dependency 'APIKit', '5.1.0'
s.dependency 'BigInt'
s.dependency 'CombineExt', '1.8.0'
s.dependency 'PromiseKit'
end

@ -22,30 +22,31 @@ Pod::Spec.new do |spec|
spec.resource_bundles = {'AlphaWalletFoundation' => ['modules/AlphaWalletFoundation/AlphaWalletFoundation/**/*.{graphql,json}'] }
spec.pod_target_xcconfig = { 'SWIFT_OPTIMIZATION_LEVEL' => '-Owholemodule' }
spec.dependency 'AlphaWalletWeb3'
spec.dependency 'AlphaWalletWeb3Provider'
spec.dependency 'AlphaWalletLogger'
spec.dependency 'AlphaWalletABI'
spec.dependency 'AlphaWalletAddress'
spec.dependency 'AlphaWalletCore'
spec.dependency 'AlphaWalletGoBack'
spec.dependency 'AlphaWalletENS'
spec.dependency 'AlphaWalletHardwareWallet'
spec.dependency 'AlphaWalletOpenSea'
spec.dependency 'AlphaWalletShareExtensionCore'
spec.dependency 'AlphaWalletTokenScript'
spec.dependency 'AlphaWalletTrustWalletCoreExtensions'
spec.dependency 'BigInt', '~> 3.1'
spec.dependency 'JSONRPCKit', '~> 2.0.0'
spec.dependency 'APIKit', '5.1.0'
spec.dependency 'RealmSwift', '10.36.0'
spec.dependency 'CryptoSwift', '~> 1.4'
spec.dependency 'AlphaWalletWeb3Provider'
spec.dependency 'TrezorCrypto'
spec.dependency 'TrustKeystore'
spec.dependency 'SwiftyJSON', '5.0.0'
spec.dependency 'AlphaWalletWeb3'
spec.dependency 'PromiseKit/CorePromise'
spec.dependency 'Kanna'
spec.dependency 'EthereumABI'
spec.dependency 'BlockiesSwift'
spec.dependency 'PaperTrailLumberjack/Swift'
spec.dependency 'AlphaWalletLogger'
spec.dependency 'AlphaWalletAddress'
spec.dependency 'AlphaWalletCore'
spec.dependency 'AlphaWalletGoBack'
spec.dependency 'AlphaWalletENS'
spec.dependency 'AlphaWalletHardwareWallet'
spec.dependency 'AlphaWalletOpenSea'
spec.dependency 'AlphaWalletShareExtensionCore'
spec.dependency 'AlphaWalletTrustWalletCoreExtensions'
spec.dependency 'Apollo', '0.53.0'
spec.dependency 'CombineExt', '1.8.0'
spec.dependency 'SwiftProtobuf', '~> 1.18.0'

@ -24,4 +24,5 @@ Pod::Spec.new do |s|
s.pod_target_xcconfig = { 'SWIFT_OPTIMIZATION_LEVEL' => '-Owholemodule' }
s.frameworks = 'UIKit'
#Should not include any of our own pods as dependency unless that pod is never going to have a dependency on this pod
end

@ -26,8 +26,8 @@ Pod::Spec.new do |s|
s.frameworks = 'Foundation'
s.dependency 'AlphaWalletAddress'
s.dependency 'AlphaWalletWeb3'
s.dependency 'AlphaWalletTrustWalletCoreExtensions'
s.dependency 'AlphaWalletWeb3'
s.dependency 'TrustKeystore'
end

@ -23,5 +23,7 @@ Pod::Spec.new do |s|
s.pod_target_xcconfig = { 'SWIFT_OPTIMIZATION_LEVEL' => '-Owholemodule' }
s.frameworks = 'Foundation'
#Should not include any of our own pods as dependency unless that pod is never going to have a dependency on this pod
s.dependency 'CocoaLumberjack', '3.7.0'
end

@ -25,10 +25,10 @@ Pod::Spec.new do |s|
s.frameworks = 'Foundation'
s.dependency 'AlphaWalletCore'
s.dependency 'AlphaWalletFoundation'
s.dependency 'FirebaseCrashlytics'
s.dependency 'Firebase/Messaging'
s.dependency 'AlphaWalletCore'
s.dependency 'SwiftyJSON'
end

@ -24,6 +24,7 @@ Pod::Spec.new do |spec|
spec.dependency 'AlphaWalletAddress'
spec.dependency 'AlphaWalletCore'
spec.dependency 'BigInt'
spec.dependency 'PromiseKit'
spec.dependency 'SwiftyJSON', '5.0.0'
end

@ -22,4 +22,5 @@ Pod::Spec.new do |spec|
spec.resource_bundles = {'AlphaWalletShareExtensionCore' => ['modules/AlphaWalletShareExtensionCore/AlphaWalletShareExtensionCore/**/*.{graphql,json}'] }
spec.pod_target_xcconfig = { 'SWIFT_OPTIMIZATION_LEVEL' => '-Owholemodule' }
#Should not include any of our own pods as dependency unless that pod is never going to have a dependency on this pod
end

@ -1,15 +1,16 @@
// Copyright SIX DAY LLC. All rights reserved.
import XCTest
@testable import AlphaWallet
import AlphaWalletFoundation
import Combine
@testable import AlphaWallet
import AlphaWalletCore
import AlphaWalletFoundation
import AlphaWalletTokenScript
import Alamofire
final class FakeApiTransporter: ApiTransporter {
func responseTaskPublisher(_ request: AlphaWalletFoundation.URLRequestConvertible) -> AnyPublisher<HTTPURLResponse, AlphaWalletFoundation.SessionTaskError> {
func responseTaskPublisher(_ request: URLRequestConvertible) -> AnyPublisher<HTTPURLResponse, AlphaWalletFoundation.SessionTaskError> {
return .empty()
}
@ -23,7 +24,7 @@ final class FakeApiTransporter: ApiTransporter {
}
final class FakeNetworkService: NetworkService {
func dataTask(_ request: AlphaWalletFoundation.URLRequestConvertible) async throws -> URLRequest.Response {
func dataTask(_ request: URLRequestConvertible) async throws -> URLRequest.Response {
let url = URL(string: "https://github.com/AlphaWallet/alpha-wallet-ios")!
let response = HTTPURLResponse(url: url, statusCode: 500, httpVersion: nil, headerFields: nil)!
return (data: Data(), response: response)
@ -36,13 +37,13 @@ final class FakeNetworkService: NetworkService {
func upload(multipartFormData: @escaping (MultipartFormData) -> Void,
usingThreshold: UInt64,
with request: AlphaWalletFoundation.URLRequestConvertible,
with request: URLRequestConvertible,
callbackQueue: DispatchQueue) -> AnyPublisher<URLRequest.Response, SessionTaskError> {
return .empty()
}
func dataTaskPublisher(_ request: AlphaWalletFoundation.URLRequestConvertible, callbackQueue: DispatchQueue = .main) -> AnyPublisher<URLRequest.Response, SessionTaskError> {
func dataTaskPublisher(_ request: URLRequestConvertible, callbackQueue: DispatchQueue = .main) -> AnyPublisher<URLRequest.Response, SessionTaskError> {
return AnyPublisher<URLRequest.Response, AlphaWalletFoundation.SessionTaskError>.create { [callbackQueue, delay] seal in
self.calls += 1
@ -75,7 +76,7 @@ extension AnyCAIP10AccountProvidable {
extension AssetDefinitionStore {
static func make() -> AssetDefinitionStore {
return .init(networkService: FakeNetworkService(), blockchainsProvider: BlockchainsProvider.make(servers: [.main]))
return .init(networkService: FakeNetworkService(), blockchainsProvider: BlockchainsProviderImplementation.make(servers: [.main]), features: TokenScriptFeatures())
}
}

@ -9,6 +9,7 @@ import XCTest
@testable import AlphaWallet
import EthereumAddress
import BigInt
import AlphaWalletABI
import AlphaWalletFoundation
class FunctionCallArgumentTests: XCTestCase {

@ -6,26 +6,23 @@
//
import Foundation
import Combine
import XCTest
@testable import AlphaWallet
import AlphaWalletFoundation
import Combine
import AlphaWalletWeb3
extension BlockchainsProvider {
extension BlockchainsProviderImplementation {
static func make(servers: [RPCServer]) -> BlockchainsProvider {
let analytics = FakeAnalyticsService()
let config = Config.make(defaults: .standardOrForTests, enabledServers: servers)
let blockchainFactory = BaseBlockchainFactory(
config: config,
analytics: analytics)
let blockchainFactory = BaseBlockchainFactory(analytics: analytics)
let serversProvider = BaseServersProvider(config: config)
let blockchainsProvider = BlockchainsProvider(
serversProvider: serversProvider,
blockchainFactory: blockchainFactory)
let blockchainsProvider = BlockchainsProviderImplementation(serversProvider: serversProvider, blockchainFactory: blockchainFactory)
return blockchainsProvider
}
@ -36,7 +33,7 @@ extension FakeSessionsProvider {
let provider = FakeSessionsProvider(
config: .make(),
analytics: FakeAnalyticsService(),
blockchainsProvider: .make(servers: servers),
blockchainsProvider: BlockchainsProviderImplementation .make(servers: servers),
tokensDataStore: FakeTokensDataStore(servers: servers),
assetDefinitionStore: .make(),
reachability: FakeReachabilityManager(true),
@ -78,7 +75,7 @@ class FakeSessionsProvider: SessionsProvider {
self.init(
config: config,
analytics: FakeAnalyticsService(),
blockchainsProvider: BlockchainsProvider.make(servers: servers),
blockchainsProvider: BlockchainsProviderImplementation.make(servers: servers),
tokensDataStore: FakeTokensDataStore(servers: servers),
assetDefinitionStore: .make(),
reachability: FakeReachabilityManager(false),
@ -108,7 +105,9 @@ class FakeSessionsProvider: SessionsProvider {
public func start() {
blockchainsProvider
.blockchains
.map { [sessionsSubject] blockchains -> ServerDictionary<WalletSession>in
.map { [sessionsSubject] (blockchains: ServerDictionary<BlockchainCallable>) -> ServerDictionary<WalletSession>in
//TODO unfortunate casting needed due to how/when we extract AlphaWalletTokenScript
let blockchains = blockchains.mapValues { $0 as! BlockchainProvider }
var sessions: ServerDictionary<WalletSession> = .init()
for blockchain in blockchains.values {

@ -3,6 +3,7 @@
import XCTest
@testable import AlphaWallet
import Combine
import AlphaWalletCore
import AlphaWalletFoundation
extension WalletConnectCoordinator {

@ -3,7 +3,8 @@
import Foundation
import XCTest
@testable import AlphaWallet
import AlphaWalletFoundation
import AlphaWalletAddress
import AlphaWalletTokenScript
class AssetDefinitionDiskBackingStoreWithOverridesTests: XCTestCase {
func testBackingStoreWithOverrides() {

@ -4,6 +4,7 @@ import Foundation
import XCTest
@testable import AlphaWallet
import AlphaWalletFoundation
import AlphaWalletTokenScript
class AssetDefinitionStoreTests: XCTestCase {
func testConvertsModifiedDateToStringForHTTPHeaderIfModifiedSince() {
@ -12,7 +13,7 @@ class AssetDefinitionStoreTests: XCTestCase {
}
func testXMLAccess() {
let store = AssetDefinitionStore(backingStore: AssetDefinitionInMemoryBackingStore(), networkService: FakeNetworkService(), blockchainsProvider: BlockchainsProvider.make(servers: [.main]))
let store = AssetDefinitionStore(backingStore: AssetDefinitionInMemoryBackingStore(), networkService: FakeNetworkService(), blockchainsProvider: BlockchainsProviderImplementation.make(servers: [.main]), features: TokenScriptFeatures())
let address = AlphaWallet.Address.make()
XCTAssertNil(store[address])
store[address] = "xml1"
@ -21,7 +22,7 @@ class AssetDefinitionStoreTests: XCTestCase {
func testShouldNotCallCompletionBlockWithCacheCaseIfNotAlreadyCached() {
let contractAddress = AlphaWallet.Address.make()
let store = AssetDefinitionStore(backingStore: AssetDefinitionInMemoryBackingStore(), networkService: FakeNetworkService(), blockchainsProvider: BlockchainsProvider.make(servers: [.main]))
let store = AssetDefinitionStore(backingStore: AssetDefinitionInMemoryBackingStore(), networkService: FakeNetworkService(), blockchainsProvider: BlockchainsProviderImplementation.make(servers: [.main]), features: TokenScriptFeatures())
let expectation = XCTestExpectation(description: "cached case should not be called")
expectation.isInverted = true
store.fetchXML(forContract: contractAddress, server: nil, useCacheAndFetch: true) { [weak self] result in
@ -38,7 +39,7 @@ class AssetDefinitionStoreTests: XCTestCase {
func testShouldCallCompletionBlockWithCacheCaseIfAlreadyCached() {
let contractAddress = AlphaWallet.Address.ethereumAddress(eip55String: "0x0000000000000000000000000000000000000001")
let store = AssetDefinitionStore(backingStore: AssetDefinitionInMemoryBackingStore(), networkService: FakeNetworkService(), blockchainsProvider: BlockchainsProvider.make(servers: [.main]))
let store = AssetDefinitionStore(backingStore: AssetDefinitionInMemoryBackingStore(), networkService: FakeNetworkService(), blockchainsProvider: BlockchainsProviderImplementation.make(servers: [.main]), features: TokenScriptFeatures())
store[contractAddress] = "something"
let expectation = XCTestExpectation(description: "cached case should be called")
store.fetchXML(forContract: contractAddress, server: nil, useCacheAndFetch: true) { [weak self] result in

@ -3,7 +3,8 @@
import Foundation
import XCTest
@testable import AlphaWallet
import AlphaWalletFoundation
import AlphaWalletAddress
import AlphaWalletTokenScript
class TokenScriptFilterParserTests: XCTestCase {
func testTokenizing() {

File diff suppressed because one or more lines are too long

@ -9,14 +9,18 @@ import Foundation
import XCTest
@testable import AlphaWallet
import BigInt
import AlphaWalletAddress
import AlphaWalletCore
import AlphaWalletFoundation
import AlphaWalletTokenScript
// swiftlint:disable type_body_length
class XMLHandlerTest: XCTestCase {
let tokenHex = "0x00000000000000000000000000000000fefe5ae99a3000000000000000010001".substring(from: 2)
func testParser() {
let assetDefinitionStore = AssetDefinitionStore.make()
let token = XMLHandler(contract: Constants.nullAddress, tokenType: .erc20, assetDefinitionStore: assetDefinitionStore).getToken(
let token = XMLHandler(contract: AlphaWalletFoundation.Constants.nullAddress, tokenType: .erc20, assetDefinitionStore: assetDefinitionStore).getToken(
name: "",
symbol: "",
fromTokenIdOrEvent: .tokenId(tokenId: BigUInt(tokenHex, radix: 16)!),
@ -899,7 +903,7 @@ class XMLHandlerTest: XCTestCase {
</ts:token>
"""
let contractAddress = AlphaWallet.Address(string: "0xA66A3F08068174e8F005112A8b2c7A507a822335")!
let store = AssetDefinitionStore(backingStore: AssetDefinitionInMemoryBackingStore(), networkService: FakeNetworkService(), blockchainsProvider: BlockchainsProvider.make(servers: [.main]))
let store = AssetDefinitionStore(backingStore: AssetDefinitionInMemoryBackingStore(), networkService: FakeNetworkService(), blockchainsProvider: BlockchainsProviderImplementation.make(servers: [.main]), features: TokenScriptFeatures())
store[contractAddress] = xml
let xmlHandler = XMLHandler(contract: contractAddress, tokenType: .erc20, assetDefinitionStore: store)
@ -913,8 +917,8 @@ class XMLHandlerTest: XCTestCase {
// swiftlint:enable function_body_length
func testNoAssetDefinition() {
let store = AssetDefinitionStore(backingStore: AssetDefinitionInMemoryBackingStore(), networkService: FakeNetworkService(), blockchainsProvider: BlockchainsProvider.make(servers: [.main]))
let xmlHandler = XMLHandler(contract: Constants.nullAddress, tokenType: .erc875, assetDefinitionStore: store)
let store = AssetDefinitionStore(backingStore: AssetDefinitionInMemoryBackingStore(), networkService: FakeNetworkService(), blockchainsProvider: BlockchainsProviderImplementation.make(servers: [.main]), features: TokenScriptFeatures())
let xmlHandler = XMLHandler(contract: AlphaWalletFoundation.Constants.nullAddress, tokenType: .erc875, assetDefinitionStore: store)
let tokenId = BigUInt("0000000000000000000000000000000002000000000000000000000000000000", radix: 16)!
let server: RPCServer = .main
let token = xmlHandler.getToken(name: "Some name", symbol: "Some symbol", fromTokenIdOrEvent: .tokenId(tokenId: tokenId), index: 1, inWallet: .make(), server: server, tokenType: TokenType.erc721, assetDefinitionStore: store)

@ -88,3 +88,9 @@ class UnconfirmedTransactionTests: XCTestCase {
XCTAssertEqual((result.params?["to"] as? AlphaWalletWeb3.EthereumAddress)?.description, recipient.eip55String)
}
}
extension EthereumAddress: CustomStringConvertible {
public var description: String {
address
}
}

@ -4,6 +4,7 @@ import XCTest
@testable import AlphaWallet
import Combine
import AlphaWalletFoundation
import AlphaWalletWeb3
extension TokensFilter {
static func make() -> TokensFilter {
@ -34,7 +35,7 @@ extension WalletDataProcessingPipeline {
let sessionsProvider = FakeSessionsProvider(
config: .make(),
analytics: FakeAnalyticsService(),
blockchainsProvider: .make(servers: [server]),
blockchainsProvider: BlockchainsProviderImplementation .make(servers: [server]),
tokensDataStore: tokensDataStore,
assetDefinitionStore: .make(),
reachability: FakeReachabilityManager(true),

@ -0,0 +1,39 @@
#
# Be sure to run `pod lib lint AlphaWalletTokenScript.podspec' to ensure this is a
# valid spec before submitting.
#
# Any lines starting with a # are optional, but their use is encouraged
# To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html
#
Pod::Spec.new do |s|
s.name = 'AlphaWalletTokenScript'
s.version = '1.0.0'
s.summary = 'AlphaWallet TokenScript library'
s.description = <<-DESC
Lightweight library representing the AlphaWallet TokenScript functionality
DESC
s.homepage = "https://github.com/AlphaWallet/alpha-wallet-ios/tree/master/modules/AlphaWalletTokenScript"
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { "Hwee-Boon Yar" => "hboon@motionobj.com" }
s.social_media_url = "https://twitter.com/hboon"
s.ios.deployment_target = '13.0'
s.swift_version = '5.0'
s.platform = :ios, "13.0"
s.source = { :git => 'git@github.com:AlphaWallet/alpha-wallet-ios.git', :tag => "#{s.version}" }
s.source_files = 'modules/AlphaWalletTokenScript/AlphaWalletTokenScript/**/*.{h,m,swift}'
s.pod_target_xcconfig = { 'SWIFT_OPTIMIZATION_LEVEL' => '-Owholemodule' }
s.frameworks = 'Foundation'
s.dependency 'APIKit'
s.dependency 'BigInt'
s.dependency 'Kanna'
s.dependency 'PromiseKit/CorePromise'
s.dependency 'AlphaWalletAddress'
s.dependency 'AlphaWalletABI'
s.dependency 'AlphaWalletCore'
s.dependency 'AlphaWalletLogger'
s.dependency 'AlphaWalletOpenSea'
s.dependency 'AlphaWalletWeb3'
end

@ -23,4 +23,5 @@ Pod::Spec.new do |s|
s.pod_target_xcconfig = { 'SWIFT_OPTIMIZATION_LEVEL' => '-Owholemodule' }
s.frameworks = 'Foundation'
#Should not include any of our own pods as dependency unless that pod is never going to have a dependency on this pod
end

@ -25,6 +25,8 @@ Pod::Spec.new do |s|
s.frameworks = 'Foundation'
#Should not include any of our own pods as dependency unless that pod is never going to have a dependency on this pod
s.dependency 'AlphaWalletCore'
s.dependency 'BigInt'
s.dependency 'TrustWalletCore', '2.6.34'
end

@ -28,6 +28,9 @@ s.source_files = 'modules/AlphaWalletWeb3/AlphaWalletWeb3/**/*.{h,m,swift}'
s.public_header_files = "AlphaWalletWeb3/**/*.{h}"
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
s.dependency 'AlphaWalletAddress'
s.dependency 'AlphaWalletCore'
s.dependency 'APIKit'
s.dependency 'BigInt'
s.dependency 'CryptoSwift'
s.dependency 'secp256k1_ios', '~> 0.1.3'

@ -20,6 +20,7 @@ target 'AlphaWallet' do
pod 'Mixpanel-swift', '~> 3.1'
pod 'EthereumABI', :git => 'https://github.com/AlphaWallet/EthereumABI.git', :commit => '877b77e8e7cbc54ab0712d509b74fec21b79d1bb'
pod 'Charts'
pod 'AlphaWalletABI', :path => '.'
pod 'AlphaWalletAddress', :path => '.'
pod 'AlphaWalletAttestation', :path => '.'
pod 'AlphaWalletCore', :path => '.'
@ -34,6 +35,7 @@ target 'AlphaWallet' do
pod 'AlphaWalletShareExtensionCore', :path => '.'
pod 'AlphaWalletTrustWalletCoreExtensions', :path => '.'
pod 'AlphaWalletNotifications', :path => '.'
pod 'AlphaWalletTokenScript', :path => '.'
pod 'MailchimpSDK'
pod 'xcbeautify'
pod 'FloatingPanel'

@ -1,17 +1,25 @@
PODS:
- Alamofire (5.6.4)
- AlphaWalletABI (1.0.0):
- AlphaWalletAddress
- AlphaWalletWeb3
- EthereumABI
- TrustKeystore
- AlphaWalletAddress (1.0.2):
- AlphaWalletCore
- AlphaWalletWeb3
- EthereumAddress
- TrustKeystore
- AlphaWalletAttestation (0.0.1):
- AlphaWalletFoundation
- AlphaWalletTokenScript
- AlphaWalletWeb3
- BigInt
- GzipSwift
- AlphaWalletCore (1.0.2):
- Alamofire (= 5.6.4)
- APIKit (= 5.1.0)
- BigInt
- CombineExt (= 1.8.0)
- PromiseKit
- AlphaWalletENS (1.0.0):
- AlphaWalletAddress
@ -19,6 +27,7 @@ PODS:
- AlphaWalletWeb3
- PromiseKit
- AlphaWalletFoundation (1.0.0):
- AlphaWalletABI
- AlphaWalletAddress
- AlphaWalletCore
- AlphaWalletENS
@ -27,6 +36,7 @@ PODS:
- AlphaWalletLogger
- AlphaWalletOpenSea
- AlphaWalletShareExtensionCore
- AlphaWalletTokenScript
- AlphaWalletTrustWalletCoreExtensions
- AlphaWalletWeb3
- AlphaWalletWeb3Provider
@ -36,7 +46,6 @@ PODS:
- BlockiesSwift
- CombineExt (= 1.8.0)
- CryptoSwift (~> 1.4)
- EthereumABI
- JSONRPCKit (~> 2.0.0)
- Kanna
- PaperTrailLumberjack/Swift
@ -63,14 +72,30 @@ PODS:
- AlphaWalletOpenSea (1.0.0):
- AlphaWalletAddress
- AlphaWalletCore
- BigInt
- PromiseKit
- SwiftyJSON (= 5.0.0)
- AlphaWalletShareExtensionCore (1.0.0)
- AlphaWalletTokenScript (1.0.0):
- AlphaWalletABI
- AlphaWalletAddress
- AlphaWalletCore
- AlphaWalletLogger
- AlphaWalletOpenSea
- AlphaWalletWeb3
- APIKit
- BigInt
- Kanna
- PromiseKit/CorePromise
- AlphaWalletTrackAPICalls (1.0.0)
- AlphaWalletTrustWalletCoreExtensions (1.0.0):
- AlphaWalletCore
- BigInt
- TrustWalletCore (= 2.6.34)
- AlphaWalletWeb3 (0.0.1):
- AlphaWalletAddress
- AlphaWalletCore
- APIKit
- BigInt
- CryptoSwift
- PromiseKit (~> 6.3.0)
@ -232,6 +257,7 @@ PODS:
- xcbeautify (0.11.0)
DEPENDENCIES:
- AlphaWalletABI (from `.`)
- AlphaWalletAddress (from `.`)
- AlphaWalletAttestation (from `.`)
- AlphaWalletCore (from `.`)
@ -243,6 +269,7 @@ DEPENDENCIES:
- AlphaWalletNotifications (from `.`)
- AlphaWalletOpenSea (from `.`)
- AlphaWalletShareExtensionCore (from `.`)
- AlphaWalletTokenScript (from `.`)
- AlphaWalletTrackAPICalls (from `.`)
- AlphaWalletTrustWalletCoreExtensions (from `.`)
- AlphaWalletWeb3 (from `.`)
@ -326,6 +353,8 @@ SPEC REPOS:
- xcbeautify
EXTERNAL SOURCES:
AlphaWalletABI:
:path: "."
AlphaWalletAddress:
:path: "."
AlphaWalletAttestation:
@ -348,6 +377,8 @@ EXTERNAL SOURCES:
:path: "."
AlphaWalletShareExtensionCore:
:path: "."
AlphaWalletTokenScript:
:path: "."
AlphaWalletTrackAPICalls:
:path: "."
AlphaWalletTrustWalletCoreExtensions:
@ -407,20 +438,22 @@ CHECKOUT OPTIONS:
SPEC CHECKSUMS:
Alamofire: 4e95d97098eacb88856099c4fc79b526a299e48c
AlphaWalletAddress: e9f10243983ac7f51671671b7964eb49d14854ab
AlphaWalletAttestation: 64970455862b55785a04d7f3da556e781e1ae9a5
AlphaWalletCore: 6f67a6ce7b25614a4cad4ca7330afeaea1b9ad03
AlphaWalletABI: 3a44d65976f24264b93389a830f9333ee72fb274
AlphaWalletAddress: b1689336d5b2560d4f0993aa680e758c49068f87
AlphaWalletAttestation: 20806a9a5448a2c88927c0ff32726d68c5936032
AlphaWalletCore: 5b06f12b96578c533585bb1c06acf255a9f98bec
AlphaWalletENS: 8f611f655728c8f2a6b91fb8f1417144d33a4915
AlphaWalletFoundation: 7cf355ef9b4aff7acd54621290a533dd2659ed69
AlphaWalletFoundation: fecb0317a9f6b55dd736416660830a1145b9cd0c
AlphaWalletGoBack: 665101a1185145ef0a4a92943dcb11ae1fe697ca
AlphaWalletHardwareWallet: 01e02d59b25853134c823063e27a9e05fbfde0a7
AlphaWalletHardwareWallet: 7aafac3ef2246713a606bd69e3af75ff111e1afc
AlphaWalletLogger: 54208bad850ec92a32fa4f969d0026305b6ce028
AlphaWalletNotifications: bdf36020ac1ed564c06a01f60d10f42b402e96d7
AlphaWalletOpenSea: f2711af0cbce462bcd569cff276a9a17fe16e6b8
AlphaWalletNotifications: 6e6a5f1cf0fc598c1c917dfb527a608b049a0a96
AlphaWalletOpenSea: e6ee4efb03db0dfebc69dfe23db33fa33bba8918
AlphaWalletShareExtensionCore: e5fc88c6120d5b77b3ba44a37e7b58da5ccbb7b6
AlphaWalletTokenScript: b4e5d7acdc85ed6915d8bf07c82abf20836cee50
AlphaWalletTrackAPICalls: 0e18ad5b389b054ee30673e7f1caf095a17c1b33
AlphaWalletTrustWalletCoreExtensions: 290b1c05cada7715c29b52622688da01ab88ffa7
AlphaWalletWeb3: fe40c838f2f829a50d8a666090c9c6cd906b5431
AlphaWalletTrustWalletCoreExtensions: 976653ec0116dbcafa6ff1fc93ebdc3a469e5f57
AlphaWalletWeb3: e15e5841128a960f45c51cdb07843e4588447b2c
AlphaWalletWeb3Provider: 7ca1e1c1dc841dc1915f970daace48bf34931655
APIKit: 9e1a4069608bf0ae5238811e6cfc26928ad4d01e
Apollo: 204819ea82022fbc59ad05056820df867f19bd02
@ -478,6 +511,6 @@ SPEC CHECKSUMS:
WalletConnectSwift: 6309bf3011b0b30e3e9d1e7449535302a9240f71
xcbeautify: b2c6b50c9cab6414296898e94cd153e4ea879662
PODFILE CHECKSUM: 33a87f051e9a4960aea2e639beb2cb787b24b55b
PODFILE CHECKSUM: f29721774eddc40fefd076855cdca437f2155e8a
COCOAPODS: 1.11.3

@ -6,6 +6,7 @@
//
import Foundation
import AlphaWalletAddress
extension AlphaWallet {
public enum Ethereum {

@ -1,4 +1,7 @@
// Copyright © 2023 Stormbird PTE. LTD.
import Foundation
import AlphaWalletAddress
extension AlphaWallet.Ethereum.ABI {
public static let erc1155String: String = {

@ -1,4 +1,7 @@
// Copyright © 2021 Stormbird PTE. LTD.
import Foundation
import AlphaWalletAddress
extension AlphaWallet.Ethereum.ABI {
public static let erc20: Data = {

@ -1,4 +1,7 @@
// Copyright © 2021 Stormbird PTE. LTD.
import Foundation
import AlphaWalletAddress
// swiftlint:disable line_length
extension AlphaWallet.Ethereum.ABI {

@ -4,8 +4,9 @@
// terms governing use, modification, and redistribution, is contained in the
// file LICENSE at the root of the source code distribution tree.
import BigInt
import Foundation
import AlphaWalletAddress
import BigInt
import TrustKeystore
/// Encodes fields according to Ethereum's Application Binary Interface Specification

@ -0,0 +1,13 @@
// Copyright © 2023 Stormbird PTE. LTD.
#import <Foundation/Foundation.h>
//! Project version number for AlphaWalletABI.
FOUNDATION_EXPORT double AlphaWalletABIVersionNumber;
//! Project version string for AlphaWalletABI.
FOUNDATION_EXPORT const unsigned char AlphaWalletABIVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <AlphaWalletABI/PublicHeader.h>

@ -4,8 +4,9 @@
// terms governing use, modification, and redistribution, is contained in the
// file LICENSE at the root of the source code distribution tree.
import BigInt
import Foundation
import AlphaWalletAddress
import BigInt
import TrustKeystore
public indirect enum ABIValue: Equatable {

@ -5,6 +5,9 @@
// Created by Vladyslav Shepitko on 11.05.2021.
//
import AlphaWalletAddress
import AlphaWalletCore
import AlphaWalletWeb3
import BigInt
import EthereumABI
@ -123,3 +126,17 @@ private extension Collection where Element == FunctionCall.Argument {
}
}
}
private extension AlphaWallet.Address {
public init?(possibleAddress: Any?) {
if let address = possibleAddress as? AlphaWallet.Address {
self = address
} else if let address = possibleAddress as? EthereumAddress_fromEthereumAddressPod {
self = .ethereumAddress(eip55String: address.address)
} else if let address = possibleAddress as? AlphaWalletWeb3.EthereumAddress {
self = .ethereumAddress(eip55String: address.address)
} else {
return nil
}
}
}

@ -1,6 +1,7 @@
// Copyright © 2020 Stormbird PTE. LTD.
import Foundation
import AlphaWalletAddress
import BigInt
public struct FunctionCall {

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 AlphaWallet
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -1,26 +1,9 @@
// Copyright SIX DAY LLC. All rights reserved.
import Foundation
import AlphaWalletCore
extension Data {
internal struct HexEncodingOptions: OptionSet {
public let rawValue: Int
static let upperCase = HexEncodingOptions(rawValue: 1 << 0)
public init(rawValue: Int) {
self.rawValue = rawValue
}
}
internal func hex(options: HexEncodingOptions = []) -> String {
let format = options.contains(.upperCase) ? "%02hhX" : "%02hhx"
return map { String(format: format, $0) }.joined()
}
internal var hexEncoded: String {
return "0x" + self.hex()
}
init?(hexString: String) {
let string: String
if hexString.hasPrefix("0x") {

@ -1,15 +0,0 @@
//
// EthereumAddress_fromWeb3.swift
// AlphaWalletFoundation
//
// Created by Vladyslav Shepitko on 15.09.2022.
//
import AlphaWalletWeb3
public typealias EthereumAddress_fromWeb3 = AlphaWalletWeb3.EthereumAddress
extension EthereumAddress_fromWeb3: CustomStringConvertible {
public var description: String {
return address
}
}

@ -1,88 +0,0 @@
// Copyright SIX DAY LLC. All rights reserved.
import Foundation
extension String {
internal var hex: String {
guard let data = self.data(using: .utf8) else {
return String()
}
return data.map {
String(format: "%02x", $0)
}.joined()
}
internal var hexEncoded: String {
guard let data = self.data(using: .utf8) else {
return String()
}
return data.hexEncoded
}
internal var has0xPrefix: Bool {
return hasPrefix("0x")
}
internal var isPrivateKey: Bool {
let value = self.drop0x.components(separatedBy: " ").joined()
return value.count == 64
}
public var drop0x: String {
if count > 2 && substring(with: 0..<2) == "0x" {
return String(dropFirst(2))
}
return self
}
internal var add0x: String {
if hasPrefix("0x") {
return self
} else {
return "0x" + self
}
}
internal func index(from: Int) -> Index {
return index(startIndex, offsetBy: from)
}
internal func substring(from: Int) -> String {
let fromIndex = index(from: from)
return String(self[fromIndex...])
}
internal func substring(to: Int) -> String {
let toIndex = index(from: to)
return String(self[..<toIndex])
}
internal func substring(with r: Range<Int>) -> String {
let startIndex = index(from: r.lowerBound)
let endIndex = index(from: r.upperBound)
return String(self[startIndex..<endIndex])
}
}
extension StringProtocol {
internal func chunked(into size: Int) -> [SubSequence] {
var chunks: [SubSequence] = []
var i = startIndex
while let nextIndex = index(i, offsetBy: size, limitedBy: endIndex) {
chunks.append(self[i ..< nextIndex])
i = nextIndex
}
let finalChunk = self[i ..< endIndex]
if finalChunk.isEmpty == false {
chunks.append(finalChunk)
}
return chunks
}
}

@ -3,44 +3,12 @@
import Foundation
import TrustKeystore
extension AlphaWallet.Address {
//TODO multiple versions of init() that accept address types from other libraries goes here. Anymore?
public init(address: EthereumAddress_fromWeb3) {
self = .ethereumAddress(eip55String: address.address)
}
//TODO multiple versions of init() that accept address types from other libraries goes here. Anymore?
extension AlphaWallet.Address {
public init(address: TrustKeystore.Address) {
self = .ethereumAddress(eip55String: address.eip55String)
}
public init?(possibleAddress: Any?) {
if let address = possibleAddress as? AlphaWallet.Address {
self = address
} else if let address = possibleAddress as? EthereumAddress_fromEthereumAddressPod {
self = .ethereumAddress(eip55String: address.address)
} else if let address = possibleAddress as? EthereumAddress_fromWeb3 {
self = .ethereumAddress(eip55String: address.address)
} else {
return nil
}
}
public func sameContract(as contract: EthereumAddress_fromWeb3) -> Bool {
return eip55String == contract.address
}
}
extension EthereumAddress_fromWeb3 {
public init(address: AlphaWallet.Address) {
//EthereumAddress(Data) is much faster than EthereumAddress(String). This is significant because we can make a few hundred calls
// let data = Data.fromHex(address.eip55String)!
// self.init(data)!
//During testing we found that EthereumAddress(address.eip55String) is faster then self.init(data)!
//approx time is 0.000980973243713379 while with using self.init(data)! is 2.8967857360839844e-05 seconds.
self.init(address.eip55String)!
}
}
extension TrustKeystore.Address {

@ -0,0 +1,11 @@
// Copyright © 2023 Stormbird PTE. LTD.
import Combine
import Foundation
import BigInt
public func - <T: Equatable> (left: [T], right: [T]) -> [T] {
return left.filter { l in
!right.contains { $0 == l }
}
}

@ -0,0 +1,12 @@
// Copyright © 2023 Stormbird PTE. LTD.
extension Optional where Wrapped: Collection {
public var isEmpty: Bool {
switch self {
case .none:
return true
case .some(let value):
return value.isEmpty
}
}
}

@ -0,0 +1,59 @@
// Copyright © 2023 Stormbird PTE. LTD.
extension Data {
public init(json: Any, options: JSONSerialization.WritingOptions = []) throws {
guard JSONSerialization.isValidJSONObject(json) else {
throw DecodeError.initFailure
}
self = try JSONSerialization.data(withJSONObject: json, options: options)
}
//NOTE: as minimum chunck is as min time it will be executed, during testing we found that optimal chunck size is 100, but seems it could be optimized more, execution time (0.2 seconds), pretty good and doesn't block UI
public init(_hex value: String) {
let chunkSize: Int = 100
if value.count > chunkSize {
self = value.chunked(into: chunkSize).reduce(NSMutableData()) { result, chunk -> NSMutableData in
let part = Data.data(from: String(chunk))
result.append(part)
return result
} as Data
} else {
self = Data.data(from: value)
}
}
//NOTE: renamed to `_hex` because CryptoSwift has its own implementation of `.init(hex:)` that instantiates Data() object with additionaly byte at the end. That brokes `signing` in app. Not sure that this is good name.
private static func data(from hex: String) -> Data {
let len = hex.count / 2
var data = Data(capacity: len)
for i in 0..<len {
let from = hex.index(hex.startIndex, offsetBy: i*2)
let to = hex.index(hex.startIndex, offsetBy: i*2 + 2)
let bytes = hex[from ..< to]
if var num = UInt8(bytes, radix: 16) {
data.append(&num, count: 1)
}
}
return data
}
public struct HexEncodingOptions: OptionSet {
public static let upperCase = HexEncodingOptions(rawValue: 1 << 0)
public let rawValue: Int
public init(rawValue: Int) {
self.rawValue = rawValue
}
}
public func hex(options: HexEncodingOptions = []) -> String {
let format = options.contains(.upperCase) ? "%02hhX" : "%02hhx"
return map { String(format: format, $0) }.joined()
}
public var hexEncoded: String {
return "0x" + self.hex()
}
}

@ -1,12 +1,16 @@
//
// Date.swift
// Alpha-Wallet
//
// Created by Oguzhan Gungor on 2/24/18.
// Copyright © 2018 Alpha-Wallet. All rights reserved.
//
// Copyright © 2023 Stormbird PTE. LTD.
import Foundation
//TODO Some duplicate from AlphaWalletFoundation's Config
fileprivate struct Config {
fileprivate static func getLocale() -> String? {
let defaults = UserDefaults.standardOrForTests
return defaults.string(forKey: Keys.locale)
}
struct Keys {
static let locale = "locale"
}
}
public extension Date {
private static var formatsMap: AtomicDictionary<String, DateFormatter> = .init()

@ -1,6 +1,4 @@
// Copyright SIX DAY LLC. All rights reserved.
import Foundation
// Copyright © 2023 Stormbird PTE. LTD.
extension Dictionary where Key: ExpressibleByStringLiteral, Value: Any {
public var jsonString: String? {

@ -0,0 +1,54 @@
//
// Publisher+Extensions.swift
// AlphaWallet
//
// Created by Vladyslav Shepitko on 04.04.2022.
//
import Foundation
import Combine
import PromiseKit
public extension Publisher {
static func empty() -> AnyPublisher<Output, Failure> {
return Empty().eraseToAnyPublisher()
}
static func just(_ output: Output) -> AnyPublisher<Output, Failure> {
return Just(output)
.setFailureType(to: Failure.self)
.eraseToAnyPublisher()
}
static func fail(_ error: Failure) -> AnyPublisher<Output, Failure> {
return Fail(error: error).eraseToAnyPublisher()
}
public func sinkAsync(receiveCompletion: @escaping (Subscribers.Completion<Failure>) -> Void = { _ in }, receiveValue: @escaping (Output) -> Void = { _ in }) {
var cancellable: AnyCancellable?
cancellable = self
.handleEvents(receiveCancel: { cancellable = nil })
.sink { result in
receiveCompletion(result)
cancellable = nil
} receiveValue: { value in
receiveValue(value)
}
}
public func promise() -> Promise<Output> {
var cancellable: AnyCancellable?
return Promise<Output> { seal in
cancellable = self
.receive(on: RunLoop.main)
.sink { result in
if case .failure(let error) = result {
seal.reject(error)
}
cancellable = nil
} receiveValue: {
seal.fulfill($0)
}
}
}
}

@ -1,25 +0,0 @@
//
// Publisher+Utils.swift
// AlphaWallet
//
// Created by Vladyslav Shepitko on 04.04.2022.
//
import Foundation
import Combine
public extension Publisher {
static func empty() -> AnyPublisher<Output, Failure> {
return Empty().eraseToAnyPublisher()
}
static func just(_ output: Output) -> AnyPublisher<Output, Failure> {
return Just(output)
.setFailureType(to: Failure.self)
.eraseToAnyPublisher()
}
static func fail(_ error: Failure) -> AnyPublisher<Output, Failure> {
return Fail(error: error).eraseToAnyPublisher()
}
}

@ -0,0 +1,109 @@
// Copyright © 2023 Stormbird PTE. LTD.
extension Optional where Wrapped == String {
public var nilIfEmpty: String? {
guard let strongSelf = self else { return nil }
if strongSelf.isEmpty {
return nil
} else {
return strongSelf
}
}
}
extension String {
public var nilIfEmpty: String? {
if isEmpty {
return nil
} else {
return self
}
}
}
extension String {
public var hexToBytes: [UInt8] {
let hex: [Character]
if count % 2 == 0 {
hex = Array(self)
} else {
hex = Array(("0" + self))
}
return stride(from: 0, to: count, by: 2).compactMap {
UInt8(String(hex[$0..<$0.advanced(by: 2)]), radix: 16)
}
}
public func index(from: Int) -> Index {
return index(startIndex, offsetBy: from)
}
public func substring(from: Int) -> String {
let fromIndex = index(from: from)
return String(self[fromIndex...])
}
public func substring(to: Int) -> String {
let toIndex = index(from: to)
return String(self[..<toIndex])
}
public func substring(with r: Range<Int>) -> String {
let startIndex = index(from: r.lowerBound)
let endIndex = index(from: r.upperBound)
return String(self[startIndex..<endIndex])
}
public func nextLetterInAlphabet(for index: Int) -> String? {
guard let uniCode = UnicodeScalar(self) else {
return nil
}
switch uniCode {
case "A"..<"Z":
return String(UnicodeScalar(uniCode.value.advanced(by: index))!)
default:
return nil
}
}
public var trimmed: String {
return trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
}
public var hex: String {
guard let data = self.data(using: .utf8) else {
return String()
}
return data.map { String(format: "%02x", $0) }.joined() }
internal var hexEncoded: String {
guard let data = self.data(using: .utf8) else {
return String()
}
return data.hexEncoded
}
public var has0xPrefix: Bool {
return hasPrefix("0x")
}
public var isPrivateKey: Bool {
let value = self.drop0x.components(separatedBy: " ").joined()
return value.count == 64
}
public var drop0x: String {
if count > 2 && substring(with: 0..<2) == "0x" {
return String(dropFirst(2))
}
return self
}
public var add0x: String {
if hasPrefix("0x") {
return self
} else {
return "0x" + self
}
}
}

@ -0,0 +1,22 @@
// Copyright © 2023 Stormbird PTE. LTD.
extension StringProtocol {
public func chunked(into size: Int) -> [SubSequence] {
var chunks: [SubSequence] = []
var i = startIndex
while let nextIndex = index(i, offsetBy: size, limitedBy: endIndex) {
chunks.append(self[i ..< nextIndex])
i = nextIndex
}
let finalChunk = self[i ..< endIndex]
if finalChunk.isEmpty == false {
chunks.append(finalChunk)
}
return chunks
}
}

@ -0,0 +1,14 @@
// Copyright © 2023 Stormbird PTE. LTD.
extension UserDefaults {
//NOTE: its quite important to use single instance of user defaults, otherwise the data will be written in different suites
private static let testSuiteDefaults = UserDefaults(suiteName: NSUUID().uuidString)!
public static var standardOrForTests: UserDefaults {
if isRunningTests() {
return testSuiteDefaults
} else {
return .standard
}
}
}

@ -8,15 +8,18 @@
import Foundation
import Alamofire
import Combine
import AlphaWalletCore
public typealias URLRequestConvertible = Alamofire.URLRequestConvertible
public typealias URLEncoding = Alamofire.URLEncoding
public typealias JSONEncoding = Alamofire.JSONEncoding
public typealias Parameters = Alamofire.Parameters
import APIKit
public typealias SessionTaskError = APIKit.SessionTaskError
public typealias HTTPHeaders = Alamofire.HTTPHeaders
public typealias HTTPMethod = Alamofire.HTTPMethod
public typealias JSONEncoding = Alamofire.JSONEncoding
public typealias MultipartFormData = Alamofire.MultipartFormData
public typealias Parameters = Alamofire.Parameters
public typealias Session = Alamofire.Session
public typealias URLEncoding = Alamofire.URLEncoding
public typealias URLRequestConvertible = Alamofire.URLRequestConvertible
extension URLRequest {
public typealias Response = (data: Data, response: HTTPURLResponse)
@ -42,7 +45,7 @@ public protocol NetworkService {
func upload(multipartFormData: @escaping (MultipartFormData) -> Void, usingThreshold: UInt64, with request: URLRequestConvertible, callbackQueue: DispatchQueue) -> AnyPublisher<URLRequest.Response, SessionTaskError>
}
extension NetworkService {
public extension NetworkService {
func dataTaskPublisher(_ request: URLRequestConvertible) -> AnyPublisher<URLRequest.Response, SessionTaskError> {
dataTaskPublisher(request, callbackQueue: .main)
}
@ -61,12 +64,10 @@ extension NetworkService {
}
public class BaseNetworkService: NetworkService {
private let analytics: AnalyticsLogger
private let session: Session
public init(analytics: AnalyticsLogger, configuration: URLSessionConfiguration = .default) {
public init(configuration: URLSessionConfiguration = .default) {
self.session = Session(configuration: configuration)
self.analytics = analytics
}
public func upload(

@ -1,6 +1,4 @@
// Copyright SIX DAY LLC. All rights reserved.
import Foundation
// Copyright © 2023 Stormbird PTE. LTD.
public struct CustomRPC: Codable, Hashable {
public let chainID: Int
@ -12,6 +10,17 @@ public struct CustomRPC: Codable, Hashable {
public let etherscanCompatibleType: RPCServer.EtherscanCompatibleType
public let isTestnet: Bool
public init(chainID: Int, nativeCryptoTokenName: String?, chainName: String, symbol: String?, rpcEndpoint: String, explorerEndpoint: String?, etherscanCompatibleType: RPCServer.EtherscanCompatibleType, isTestnet: Bool) {
self.chainID = chainID
self.nativeCryptoTokenName = nativeCryptoTokenName
self.chainName = chainName
self.symbol = symbol
self.rpcEndpoint = rpcEndpoint
self.explorerEndpoint = explorerEndpoint
self.etherscanCompatibleType = etherscanCompatibleType
self.isTestnet = isTestnet
}
public static func custom(chainId: Int) -> CustomRPC {
return .init(chainID: chainId, nativeCryptoTokenName: nil, chainName: "", symbol: nil, rpcEndpoint: "", explorerEndpoint: "", etherscanCompatibleType: .unknown, isTestnet: false)
}

@ -0,0 +1,6 @@
// Copyright © 2023 Stormbird PTE. LTD.
public enum DecodeError: Error {
case typeMismatch
case initFailure
}

@ -0,0 +1,185 @@
// Copyright © 2023 Stormbird PTE. LTD.
import Foundation
public enum RPCServer: Hashable, CaseIterable {
public enum EtherscanCompatibleType: String, Codable {
case etherscan
case blockscout
case unknown
}
case main
case classic
//As of 20210601, `.callisto` doesn't eth_blockNumber because their endpoint requires including `"params": []` in the payload even if it's empty and we don't.
//As of 20210601, `.callisto` doesn't support eth_call according to https://testnet-explorer.callisto.network/eth-rpc-api-docs
case callisto
case xDai
case goerli
case binance_smart_chain
case binance_smart_chain_testnet
case heco
case heco_testnet
case fantom
case fantom_testnet
case avalanche
case avalanche_testnet
case polygon
case mumbai_testnet
case optimistic
case cronosMainnet
case cronosTestnet
case custom(CustomRPC)
case arbitrum
case palm
case palmTestnet
case klaytnCypress
case klaytnBaobabTestnet
case ioTeX
case ioTeXTestnet
case optimismGoerli
case arbitrumGoerli
case okx
case sepolia
public var chainID: Int {
switch self {
case .main: return 1
case .classic: return 61
case .callisto: return 104729
case .xDai: return 100
case .goerli: return 5
case .binance_smart_chain: return 56
case .binance_smart_chain_testnet: return 97
case .heco: return 128
case .heco_testnet: return 256
case .custom(let custom): return custom.chainID
case .fantom: return 250
case .fantom_testnet: return 0xfa2
case .avalanche: return 0xa86a
case .avalanche_testnet: return 0xa869
case .polygon: return 137
case .mumbai_testnet: return 80001
case .optimistic: return 10
case .cronosTestnet: return 338
case .cronosMainnet: return 25
case .arbitrum: return 42161
case .palm: return 11297108109
case .palmTestnet: return 11297108099
case .klaytnCypress: return 8217
case .klaytnBaobabTestnet: return 1001
case .ioTeX: return 4689
case .ioTeXTestnet: return 4690
case .optimismGoerli: return 420
case .arbitrumGoerli: return 421613
case .okx: return 66
case .sepolia: return 11155111
}
}
//We'll have to manually new cases here
//Cannot be `let` as the chains can change dynamically without the app being restarted (i.e. killed). The UI can be restarted though (when switching changes)
public static var allCases: [RPCServer] {
return [
.main,
.classic,
.xDai,
.goerli,
.binance_smart_chain_testnet,
.binance_smart_chain,
.heco,
//.heco_testnet, TODO: Enable if find another working rpc url
.fantom,
.fantom_testnet,
.avalanche,
.avalanche_testnet,
.polygon,
.callisto,
.mumbai_testnet,
.optimistic,
.cronosMainnet,
.cronosTestnet,
.arbitrum,
.klaytnCypress,
.klaytnBaobabTestnet,
.palm,
.palmTestnet,
//.ioTeX, //TODO: Disabled as non in Phase 1 anymore, need to take a look on transactions, native balances
//.ioTeXTestnet
.optimismGoerli,
.arbitrumGoerli,
.okx,
.sepolia,
]
}
public private(set) static var customServers: [Self] = customRpcs.map { RPCServer.custom($0) }
public static var customRpcs: [CustomRPC] = RPCServer.convertJsonToCustomRpcs(Config().customRpcServersJson) {
didSet {
if let data = try? JSONEncoder().encode(customRpcs), let json = String(data: data, encoding: .utf8) {
var c = Config()
c.customRpcServersJson = json
customServers = customRpcs.map { RPCServer.custom($0) }
} else {
//no-op
}
}
}
public static var availableServers: [RPCServer] {
allCases + Self.customServers
}
public init(chainID: Int) {
//TODO defaulting to .main is bad
self = Self.availableServers.first { $0.chainID == chainID } ?? .main
}
private static func convertJsonToCustomRpcs(_ json: String?) -> [CustomRPC] {
if let json = json {
let data = json.data(using: .utf8)
if let servers = try? JSONDecoder().decode([CustomRPC].self, from: data!) {
return servers
} else {
return .init()
}
} else {
return .init()
}
}
}
extension RPCServer: Codable {
private enum Keys: String, CodingKey {
case chainId
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: Keys.self)
let chainId = try container.decode(Int.self, forKey: .chainId)
self = .init(chainID: chainId)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: Keys.self)
try container.encode(chainID, forKey: .chainId)
}
}
fileprivate class Config {
struct Keys {
static let customRpcServers = "customRpcServers"
}
public var customRpcServersJson: String? {
get {
let defaults = UserDefaults.standardOrForTests
return defaults.string(forKey: Keys.customRpcServers)
}
set {
let defaults = UserDefaults.standardOrForTests
defaults.set(newValue, forKey: Keys.customRpcServers)
}
}
}

@ -5,7 +5,7 @@ import Foundation
//This class removes the need to force unwrap in the client code when we access the contents using the subscript operator
//TODO probably have a special init() that better ensures we create a store with values for every RPCServer key?
public struct ServerDictionary<T> {
private var backingStore = [RPCServer: T]()
private var backingStore: [RPCServer: T]
public subscript(server: RPCServer) -> T {
get {
@ -19,7 +19,14 @@ public struct ServerDictionary<T> {
public var keys: Set<RPCServer> {
Set(backingStore.keys)
}
public init() { }
public init() {
self.backingStore = .init()
}
public init(_ anotherDictionary: [RPCServer: T]) {
self.backingStore = anotherDictionary
}
public mutating func remove(at key: RPCServer) {
backingStore.removeValue(forKey: key)

@ -40,7 +40,7 @@ public struct Subscribable<T>: Equatable {
subject.send(.done(newValue))
}
func mapFirst<V>(_ closure: @escaping (T?) -> V?) -> Subscribable<V> {
public func mapFirst<V>(_ closure: @escaping (T?) -> V?) -> Subscribable<V> {
let new = Subscribable<V>()
var subject: CurrentValueSubject<Loadable<V?, Never>, Never>? = new.subject

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save