Separate makefiles
@ -24,10 +24,11 @@ def app_binary_configs():
|
|||||||
config = {
|
config = {
|
||||||
"ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES": "YES",
|
"ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES": "YES",
|
||||||
"DEVELOPMENT_LANGUAGE": DEVELOPMENT_LANGUAGE,
|
"DEVELOPMENT_LANGUAGE": DEVELOPMENT_LANGUAGE,
|
||||||
|
"EXECUTABLE_NAME": "Wallet",
|
||||||
"PRODUCT_BUNDLE_IDENTIFIER": bundle_identifier(suffix=""),
|
"PRODUCT_BUNDLE_IDENTIFIER": bundle_identifier(suffix=""),
|
||||||
"CODE_SIGN_ENTITLEMENTS": get_codesign_entitlements("app"),
|
"CODE_SIGN_ENTITLEMENTS": get_codesign_entitlements("app"),
|
||||||
"DEVELOPMENT_TEAM": get_development_team(),
|
"DEVELOPMENT_TEAM": get_development_team(),
|
||||||
"ASSETCATALOG_COMPILER_APPICON_NAME": "AppIconLLC",
|
"ASSETCATALOG_COMPILER_APPICON_NAME": "AppIconWallet",
|
||||||
"BUILD_NUMBER": get_build_number(),
|
"BUILD_NUMBER": get_build_number(),
|
||||||
"PRODUCT_BUNDLE_SHORT_VERSION": get_short_version(),
|
"PRODUCT_BUNDLE_SHORT_VERSION": get_short_version(),
|
||||||
"APP_NAME": "TON Wallet",
|
"APP_NAME": "TON Wallet",
|
||||||
@ -45,14 +46,14 @@ def app_binary_configs():
|
|||||||
def app_info_plist_substitutions():
|
def app_info_plist_substitutions():
|
||||||
substitutions = {
|
substitutions = {
|
||||||
"DEVELOPMENT_LANGUAGE": DEVELOPMENT_LANGUAGE,
|
"DEVELOPMENT_LANGUAGE": DEVELOPMENT_LANGUAGE,
|
||||||
"EXECUTABLE_NAME": "TON Wallet",
|
"EXECUTABLE_NAME": "Wallet",
|
||||||
"PRODUCT_BUNDLE_IDENTIFIER": bundle_identifier(suffix=""),
|
"PRODUCT_BUNDLE_IDENTIFIER": bundle_identifier(suffix=""),
|
||||||
"PRODUCT_NAME": "TON Wallet",
|
"PRODUCT_NAME": "TON Wallet",
|
||||||
"APP_NAME": "TON Wallet",
|
"APP_NAME": "TON Wallet",
|
||||||
"CURRENT_PROJECT_VERSION": "1",
|
"CURRENT_PROJECT_VERSION": "1",
|
||||||
"BUILD_NUMBER": get_build_number(),
|
"BUILD_NUMBER": get_build_number(),
|
||||||
"PRODUCT_BUNDLE_SHORT_VERSION": get_short_version(),
|
"PRODUCT_BUNDLE_SHORT_VERSION": get_short_version(),
|
||||||
"ASSETCATALOG_COMPILER_APPICON_NAME": "AppIconLLC",
|
"ASSETCATALOG_COMPILER_APPICON_NAME": "AppIconWallet",
|
||||||
"TARGETED_DEVICE_FAMILY": "1,2",
|
"TARGETED_DEVICE_FAMILY": "1,2",
|
||||||
}
|
}
|
||||||
return substitutions
|
return substitutions
|
||||||
|
75
Makefile
@ -1,17 +1,6 @@
|
|||||||
.PHONY : check_env build build_arm64 build_debug_arm64 package package_arm64 app app_arm64 app_debug_arm64 build_buckdebug build_verbose kill_xcode clean project project_buckdebug temp
|
.PHONY : check_env build build_arm64 build_debug_arm64 package package_arm64 app app_arm64 app_debug_arm64 build_buckdebug build_verbose kill_xcode clean project project_buckdebug temp
|
||||||
|
|
||||||
|
include Utils.makefile
|
||||||
BUCK_DEBUG_OPTIONS=\
|
|
||||||
--config custom.other_cflags="-O0 -D DEBUG" \
|
|
||||||
--config custom.other_cxxflags="-O0 -D DEBUG" \
|
|
||||||
--config custom.optimization="-Onone" \
|
|
||||||
--config custom.config_swift_compiler_flags="-DDEBUG"
|
|
||||||
|
|
||||||
BUCK_RELEASE_OPTIONS=\
|
|
||||||
--config custom.other_cflags="-Os" \
|
|
||||||
--config custom.other_cxxflags="-Os" \
|
|
||||||
--config custom.optimization="-O" \
|
|
||||||
--config custom.config_swift_compiler_flags="-whole-module-optimization"
|
|
||||||
|
|
||||||
BUCK_OPTIONS=\
|
BUCK_OPTIONS=\
|
||||||
--config custom.appVersion="5.12" \
|
--config custom.appVersion="5.12" \
|
||||||
@ -50,43 +39,6 @@ BUCK_OPTIONS=\
|
|||||||
--config custom.developmentProvisioningProfileWatchExtension="${DEVELOPMENT_PROVISIONING_PROFILE_WATCH_EXTENSION}" \
|
--config custom.developmentProvisioningProfileWatchExtension="${DEVELOPMENT_PROVISIONING_PROFILE_WATCH_EXTENSION}" \
|
||||||
--config custom.distributionProvisioningProfileWatchExtension="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_EXTENSION}"
|
--config custom.distributionProvisioningProfileWatchExtension="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_EXTENSION}"
|
||||||
|
|
||||||
WALLET_BUCK_OPTIONS=\
|
|
||||||
--config custom.appVersion="1.0" \
|
|
||||||
--config custom.developmentCodeSignIdentity="${DEVELOPMENT_CODE_SIGN_IDENTITY}" \
|
|
||||||
--config custom.distributionCodeSignIdentity="${DISTRIBUTION_CODE_SIGN_IDENTITY}" \
|
|
||||||
--config custom.developmentTeam="${DEVELOPMENT_TEAM}" \
|
|
||||||
--config custom.baseApplicationBundleId="${WALLET_BUNDLE_ID}" \
|
|
||||||
--config custom.buildNumber="${BUILD_NUMBER}" \
|
|
||||||
--config custom.entitlementsApp="${WALLET_ENTITLEMENTS_APP}" \
|
|
||||||
--config custom.developmentProvisioningProfileApp="${WALLET_DEVELOPMENT_PROVISIONING_PROFILE_APP}" \
|
|
||||||
--config custom.distributionProvisioningProfileApp="${WALLET_DISTRIBUTION_PROVISIONING_PROFILE_APP}" \
|
|
||||||
--config custom.apiId="${API_ID}" \
|
|
||||||
--config custom.apiHash="${API_HASH}" \
|
|
||||||
--config custom.hockeyAppId="${HOCKEYAPP_ID}" \
|
|
||||||
--config custom.isInternalBuild="${IS_INTERNAL_BUILD}" \
|
|
||||||
--config custom.isAppStoreBuild="${IS_APPSTORE_BUILD}" \
|
|
||||||
--config custom.appStoreId="${APPSTORE_ID}" \
|
|
||||||
--config custom.appSpecificUrlScheme="${APP_SPECIFIC_URL_SCHEME}"
|
|
||||||
|
|
||||||
BUCK_THREADS_OPTIONS=--config build.threads=$(shell sysctl -n hw.logicalcpu)
|
|
||||||
|
|
||||||
BUCK_CACHE_OPTIONS=
|
|
||||||
|
|
||||||
ifneq ($(BUCK_HTTP_CACHE),)
|
|
||||||
ifeq ($(BUCK_CACHE_MODE),)
|
|
||||||
BUCK_CACHE_MODE=readwrite
|
|
||||||
endif
|
|
||||||
BUCK_CACHE_OPTIONS=\
|
|
||||||
--config cache.mode=http \
|
|
||||||
--config cache.http_url="$(BUCK_HTTP_CACHE)" \
|
|
||||||
--config cache.http_mode="$(BUCK_CACHE_MODE)"
|
|
||||||
endif
|
|
||||||
|
|
||||||
check_env:
|
|
||||||
ifndef BUCK
|
|
||||||
$(error BUCK is not set)
|
|
||||||
endif
|
|
||||||
sh check_env.sh
|
|
||||||
|
|
||||||
build_arm64: check_env
|
build_arm64: check_env
|
||||||
$(BUCK) build \
|
$(BUCK) build \
|
||||||
@ -148,10 +100,6 @@ build_wallet_debug_arm64: check_env
|
|||||||
//submodules/MtProtoKit:MtProtoKit#shared,iphoneos-arm64 \
|
//submodules/MtProtoKit:MtProtoKit#shared,iphoneos-arm64 \
|
||||||
//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit#dwarf-and-dsym,shared,iphoneos-arm64 \
|
//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit#dwarf-and-dsym,shared,iphoneos-arm64 \
|
||||||
//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit#shared,iphoneos-arm64 \
|
//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit#shared,iphoneos-arm64 \
|
||||||
//submodules/Postbox:Postbox#dwarf-and-dsym,shared,iphoneos-arm64 \
|
|
||||||
//submodules/Postbox:Postbox#shared,iphoneos-arm64 \
|
|
||||||
//submodules/TelegramCore:TelegramCore#dwarf-and-dsym,shared,iphoneos-arm64 \
|
|
||||||
//submodules/TelegramCore:TelegramCore#shared,iphoneos-arm64 \
|
|
||||||
//submodules/AsyncDisplayKit:AsyncDisplayKit#dwarf-and-dsym,shared,iphoneos-arm64 \
|
//submodules/AsyncDisplayKit:AsyncDisplayKit#dwarf-and-dsym,shared,iphoneos-arm64 \
|
||||||
//submodules/AsyncDisplayKit:AsyncDisplayKit#shared,iphoneos-arm64 \
|
//submodules/AsyncDisplayKit:AsyncDisplayKit#shared,iphoneos-arm64 \
|
||||||
//submodules/Display:Display#dwarf-and-dsym,shared,iphoneos-arm64 \
|
//submodules/Display:Display#dwarf-and-dsym,shared,iphoneos-arm64 \
|
||||||
@ -228,7 +176,7 @@ package_arm64:
|
|||||||
PACKAGE_PROVISIONING_PROFILE_WATCH_APP="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_APP}" \
|
PACKAGE_PROVISIONING_PROFILE_WATCH_APP="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_APP}" \
|
||||||
PACKAGE_PROVISIONING_PROFILE_WATCH_EXTENSION="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_EXTENSION}" \
|
PACKAGE_PROVISIONING_PROFILE_WATCH_EXTENSION="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_EXTENSION}" \
|
||||||
PACKAGE_BUNDLE_ID="${BUNDLE_ID}" \
|
PACKAGE_BUNDLE_ID="${BUNDLE_ID}" \
|
||||||
sh package_app.sh iphoneos-arm64 $(BUCK) $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS}
|
sh package_app.sh iphoneos-arm64 $(BUCK) "telegram" $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS}
|
||||||
|
|
||||||
package_armv7:
|
package_armv7:
|
||||||
PACKAGE_DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \
|
PACKAGE_DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \
|
||||||
@ -248,7 +196,7 @@ package_armv7:
|
|||||||
PACKAGE_PROVISIONING_PROFILE_WATCH_APP="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_APP}" \
|
PACKAGE_PROVISIONING_PROFILE_WATCH_APP="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_APP}" \
|
||||||
PACKAGE_PROVISIONING_PROFILE_WATCH_EXTENSION="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_EXTENSION}" \
|
PACKAGE_PROVISIONING_PROFILE_WATCH_EXTENSION="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_EXTENSION}" \
|
||||||
PACKAGE_BUNDLE_ID="${BUNDLE_ID}" \
|
PACKAGE_BUNDLE_ID="${BUNDLE_ID}" \
|
||||||
sh package_app.sh iphoneos-armv7 $(BUCK) $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS}
|
sh package_app.sh iphoneos-armv7 $(BUCK) "telegram" $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS}
|
||||||
|
|
||||||
package_debug_arm64:
|
package_debug_arm64:
|
||||||
PACKAGE_DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \
|
PACKAGE_DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \
|
||||||
@ -270,7 +218,7 @@ package_debug_arm64:
|
|||||||
PACKAGE_BUNDLE_ID="${BUNDLE_ID}" \
|
PACKAGE_BUNDLE_ID="${BUNDLE_ID}" \
|
||||||
ENABLE_GET_TASK_ALLOW=0 \
|
ENABLE_GET_TASK_ALLOW=0 \
|
||||||
CODESIGNING_PROFILES_VARIANT="development" \
|
CODESIGNING_PROFILES_VARIANT="development" \
|
||||||
sh package_app.sh iphoneos-arm64 $(BUCK) $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS}
|
sh package_app.sh iphoneos-arm64 $(BUCK) "telegram" $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS}
|
||||||
|
|
||||||
package_debug_armv7:
|
package_debug_armv7:
|
||||||
PACKAGE_DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \
|
PACKAGE_DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \
|
||||||
@ -292,7 +240,7 @@ package_debug_armv7:
|
|||||||
PACKAGE_BUNDLE_ID="${BUNDLE_ID}" \
|
PACKAGE_BUNDLE_ID="${BUNDLE_ID}" \
|
||||||
ENABLE_GET_TASK_ALLOW=0 \
|
ENABLE_GET_TASK_ALLOW=0 \
|
||||||
CODESIGNING_PROFILES_VARIANT="development" \
|
CODESIGNING_PROFILES_VARIANT="development" \
|
||||||
sh package_app.sh iphoneos-armv7 $(BUCK) $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS}
|
sh package_app.sh iphoneos-armv7 $(BUCK) "telegram" $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS}
|
||||||
|
|
||||||
package:
|
package:
|
||||||
PACKAGE_DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \
|
PACKAGE_DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \
|
||||||
@ -312,7 +260,7 @@ package:
|
|||||||
PACKAGE_PROVISIONING_PROFILE_WATCH_APP="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_APP}" \
|
PACKAGE_PROVISIONING_PROFILE_WATCH_APP="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_APP}" \
|
||||||
PACKAGE_PROVISIONING_PROFILE_WATCH_EXTENSION="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_EXTENSION}" \
|
PACKAGE_PROVISIONING_PROFILE_WATCH_EXTENSION="${DISTRIBUTION_PROVISIONING_PROFILE_WATCH_EXTENSION}" \
|
||||||
PACKAGE_BUNDLE_ID="${BUNDLE_ID}" \
|
PACKAGE_BUNDLE_ID="${BUNDLE_ID}" \
|
||||||
sh package_app.sh iphoneos-arm64,iphoneos-armv7 $(BUCK) $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS}
|
sh package_app.sh iphoneos-arm64,iphoneos-armv7 $(BUCK) "telegram" $(BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS}
|
||||||
|
|
||||||
app: build package
|
app: build package
|
||||||
|
|
||||||
@ -400,9 +348,6 @@ build_ton: check_env
|
|||||||
//submodules/ton:ton#iphoneos-arm64 \
|
//submodules/ton:ton#iphoneos-arm64 \
|
||||||
--verbose 7 ${BUCK_OPTIONS} ${BUCK_THREADS_OPTIONS} ${BUCK_DEBUG_OPTIONS}
|
--verbose 7 ${BUCK_OPTIONS} ${BUCK_THREADS_OPTIONS} ${BUCK_DEBUG_OPTIONS}
|
||||||
|
|
||||||
kill_xcode:
|
|
||||||
killall Xcode || true
|
|
||||||
|
|
||||||
clean: kill_xcode
|
clean: kill_xcode
|
||||||
sh clean.sh
|
sh clean.sh
|
||||||
|
|
||||||
@ -410,14 +355,6 @@ project: check_env kill_xcode
|
|||||||
$(BUCK) project //:workspace --config custom.mode=project ${BUCK_OPTIONS} ${BUCK_DEBUG_OPTIONS}
|
$(BUCK) project //:workspace --config custom.mode=project ${BUCK_OPTIONS} ${BUCK_DEBUG_OPTIONS}
|
||||||
open Telegram_Buck.xcworkspace
|
open Telegram_Buck.xcworkspace
|
||||||
|
|
||||||
wallet_deps: check_env
|
|
||||||
$(BUCK) query "deps(//Wallet:AppPackage)" \
|
|
||||||
${WALLET_BUCK_OPTIONS} ${BUCK_DEBUG_OPTIONS}
|
|
||||||
|
|
||||||
wallet_project: check_env kill_xcode
|
|
||||||
$(BUCK) project //Wallet:workspace --config custom.mode=project ${WALLET_BUCK_OPTIONS} ${BUCK_DEBUG_OPTIONS}
|
|
||||||
open Wallet/WalletWorkspace.xcworkspace
|
|
||||||
|
|
||||||
project_opt: check_env kill_xcode
|
project_opt: check_env kill_xcode
|
||||||
$(BUCK) project //:workspace --config custom.mode=project ${BUCK_OPTIONS} ${BUCK_RELEASE_OPTIONS}
|
$(BUCK) project //:workspace --config custom.mode=project ${BUCK_OPTIONS} ${BUCK_RELEASE_OPTIONS}
|
||||||
open Telegram_Buck.xcworkspace
|
open Telegram_Buck.xcworkspace
|
||||||
|
@ -4756,7 +4756,7 @@ Any member of this group will be able to see messages in the channel.";
|
|||||||
|
|
||||||
"ChatSearch.ResultsTooltip" = "Tap to view as a list.";
|
"ChatSearch.ResultsTooltip" = "Tap to view as a list.";
|
||||||
|
|
||||||
"Wallet.Updated.JustNow" = "just now";
|
"Wallet.Updated.JustNow" = "updated just now";
|
||||||
"Wallet.Updated.MinutesAgo_0" = "%@ minutes ago"; //three to ten
|
"Wallet.Updated.MinutesAgo_0" = "%@ minutes ago"; //three to ten
|
||||||
"Wallet.Updated.MinutesAgo_1" = "1 minute ago"; //one
|
"Wallet.Updated.MinutesAgo_1" = "1 minute ago"; //one
|
||||||
"Wallet.Updated.MinutesAgo_2" = "2 minutes ago"; //two
|
"Wallet.Updated.MinutesAgo_2" = "2 minutes ago"; //two
|
||||||
@ -4778,6 +4778,7 @@ Any member of this group will be able to see messages in the channel.";
|
|||||||
"Wallet.Info.Address" = "Your wallet address";
|
"Wallet.Info.Address" = "Your wallet address";
|
||||||
"Wallet.Info.YourBalance" = "your balance";
|
"Wallet.Info.YourBalance" = "your balance";
|
||||||
"Wallet.Info.Receive" = "Receive";
|
"Wallet.Info.Receive" = "Receive";
|
||||||
|
"Wallet.Info.ReceiveGrams" = "Receive Grams";
|
||||||
"Wallet.Info.Send" = "Send";
|
"Wallet.Info.Send" = "Send";
|
||||||
"Wallet.Info.RefreshErrorTitle" = "No network";
|
"Wallet.Info.RefreshErrorTitle" = "No network";
|
||||||
"Wallet.Info.RefreshErrorText" = "Couldn't refresh balance. Please make sure your internet connection is working and try again.";
|
"Wallet.Info.RefreshErrorText" = "Couldn't refresh balance. Please make sure your internet connection is working and try again.";
|
||||||
|
40
Utils.makefile
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
export BUCK_DEBUG_OPTIONS=\
|
||||||
|
--config custom.other_cflags="-O0 -D DEBUG" \
|
||||||
|
--config custom.other_cxxflags="-O0 -D DEBUG" \
|
||||||
|
--config custom.optimization="-Onone" \
|
||||||
|
--config custom.config_swift_compiler_flags="-DDEBUG"
|
||||||
|
|
||||||
|
export BUCK_RELEASE_OPTIONS=\
|
||||||
|
--config custom.other_cflags="-Os" \
|
||||||
|
--config custom.other_cxxflags="-Os" \
|
||||||
|
--config custom.optimization="-O" \
|
||||||
|
--config custom.config_swift_compiler_flags="-whole-module-optimization"
|
||||||
|
|
||||||
|
export BUCK_THREADS_OPTIONS=--config build.threads=$(shell sysctl -n hw.logicalcpu)
|
||||||
|
|
||||||
|
ifneq ($(BUCK_HTTP_CACHE),)
|
||||||
|
ifeq ($(BUCK_CACHE_MODE),)
|
||||||
|
BUCK_CACHE_MODE=readwrite
|
||||||
|
endif
|
||||||
|
export BUCK_CACHE_OPTIONS=\
|
||||||
|
--config cache.mode=http \
|
||||||
|
--config cache.http_url="$(BUCK_HTTP_CACHE)" \
|
||||||
|
--config cache.http_mode="$(BUCK_CACHE_MODE)"
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(BUCK_DIR_CACHE),)
|
||||||
|
export BUCK_CACHE_OPTIONS=\
|
||||||
|
--config cache.mode=dir \
|
||||||
|
--config cache.dir="$(BUCK_DIR_CACHE)" \
|
||||||
|
--config cache.dir_mode="readwrite"
|
||||||
|
endif
|
||||||
|
|
||||||
|
check_env:
|
||||||
|
ifndef BUCK
|
||||||
|
$(error BUCK is not set)
|
||||||
|
endif
|
||||||
|
sh check_env.sh
|
||||||
|
|
||||||
|
kill_xcode:
|
||||||
|
killall Xcode || true
|
52
Wallet.makefile
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
include Utils.makefile
|
||||||
|
|
||||||
|
WALLET_BUCK_OPTIONS=\
|
||||||
|
--config custom.appVersion="1.0" \
|
||||||
|
--config custom.developmentCodeSignIdentity="${DEVELOPMENT_CODE_SIGN_IDENTITY}" \
|
||||||
|
--config custom.distributionCodeSignIdentity="${DISTRIBUTION_CODE_SIGN_IDENTITY}" \
|
||||||
|
--config custom.developmentTeam="${DEVELOPMENT_TEAM}" \
|
||||||
|
--config custom.baseApplicationBundleId="${WALLET_BUNDLE_ID}" \
|
||||||
|
--config custom.buildNumber="${BUILD_NUMBER}" \
|
||||||
|
--config custom.entitlementsApp="${WALLET_ENTITLEMENTS_APP}" \
|
||||||
|
--config custom.developmentProvisioningProfileApp="${WALLET_DEVELOPMENT_PROVISIONING_PROFILE_APP}" \
|
||||||
|
--config custom.distributionProvisioningProfileApp="${WALLET_DISTRIBUTION_PROVISIONING_PROFILE_APP}" \
|
||||||
|
--config custom.apiId="${API_ID}" \
|
||||||
|
--config custom.apiHash="${API_HASH}" \
|
||||||
|
--config custom.hockeyAppId="${HOCKEYAPP_ID}" \
|
||||||
|
--config custom.isInternalBuild="${IS_INTERNAL_BUILD}" \
|
||||||
|
--config custom.isAppStoreBuild="${IS_APPSTORE_BUILD}" \
|
||||||
|
--config custom.appStoreId="${APPSTORE_ID}" \
|
||||||
|
--config custom.appSpecificUrlScheme="${APP_SPECIFIC_URL_SCHEME}"
|
||||||
|
|
||||||
|
wallet_deps: check_env
|
||||||
|
$(BUCK) query "deps(//Wallet:AppPackage)" --output-attribute buck.type \
|
||||||
|
${WALLET_BUCK_OPTIONS} ${BUCK_RELEASE_OPTIONS}
|
||||||
|
|
||||||
|
wallet_project: check_env kill_xcode
|
||||||
|
$(BUCK) project //Wallet:workspace --config custom.mode=project ${WALLET_BUCK_OPTIONS} ${BUCK_DEBUG_OPTIONS}
|
||||||
|
open Wallet/WalletWorkspace.xcworkspace
|
||||||
|
|
||||||
|
build_wallet: check_env
|
||||||
|
$(BUCK) build \
|
||||||
|
//Wallet:AppPackage#iphoneos-arm64,iphoneos-armv7 \
|
||||||
|
//Wallet:Wallet#dwarf-and-dsym,iphoneos-arm64,iphoneos-armv7 \
|
||||||
|
//submodules/MtProtoKit:MtProtoKit#dwarf-and-dsym,shared,iphoneos-arm64,iphoneos-armv7 \
|
||||||
|
//submodules/MtProtoKit:MtProtoKit#shared,iphoneos-arm64,iphoneos-armv7 \
|
||||||
|
//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit#dwarf-and-dsym,shared,iphoneos-arm64,iphoneos-armv7 \
|
||||||
|
//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit#shared,iphoneos-arm64,iphoneos-armv7 \
|
||||||
|
//submodules/AsyncDisplayKit:AsyncDisplayKit#dwarf-and-dsym,shared,iphoneos-arm64,iphoneos-armv7 \
|
||||||
|
//submodules/AsyncDisplayKit:AsyncDisplayKit#shared,iphoneos-arm64,iphoneos-armv7 \
|
||||||
|
//submodules/Display:Display#dwarf-and-dsym,shared,iphoneos-arm64,iphoneos-armv7 \
|
||||||
|
//submodules/Display:Display#shared,iphoneos-arm64,iphoneos-armv7 \
|
||||||
|
${WALLET_BUCK_OPTIONS} ${BUCK_RELEASE_OPTIONS} ${BUCK_THREADS_OPTIONS} ${BUCK_CACHE_OPTIONS}
|
||||||
|
|
||||||
|
wallet_package:
|
||||||
|
PACKAGE_DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" \
|
||||||
|
PACKAGE_CODE_SIGN_IDENTITY="${DISTRIBUTION_CODE_SIGN_IDENTITY}" \
|
||||||
|
PACKAGE_PROVISIONING_PROFILE_APP="${WALLET_DISTRIBUTION_PROVISIONING_PROFILE_APP}" \
|
||||||
|
PACKAGE_ENTITLEMENTS_APP="Wallet/${WALLET_ENTITLEMENTS_APP}" \
|
||||||
|
PACKAGE_BUNDLE_ID="${WALLET_BUNDLE_ID}" \
|
||||||
|
sh package_app.sh iphoneos-arm64,iphoneos-armv7 $(BUCK) "wallet" $(WALLET_BUCK_OPTIONS) ${BUCK_RELEASE_OPTIONS}
|
||||||
|
|
||||||
|
wallet_app: build_wallet wallet_package
|
||||||
|
|
@ -52,7 +52,7 @@ apple_asset_catalog(
|
|||||||
dirs = [
|
dirs = [
|
||||||
"Icons.xcassets",
|
"Icons.xcassets",
|
||||||
],
|
],
|
||||||
app_icon = "AppIconLLC",
|
app_icon = "AppIconWallet",
|
||||||
visibility = ["PUBLIC"],
|
visibility = ["PUBLIC"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
BIN
Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueIcon@2x.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
Wallet/Icons.xcassets/AppIconWallet.appiconset/BlueIcon@3x.png
Normal file
After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 665 B After Width: | Height: | Size: 665 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 159 KiB After Width: | Height: | Size: 159 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
@ -68,6 +68,10 @@
|
|||||||
</dict>
|
</dict>
|
||||||
<key>NSFaceIDUsageDescription</key>
|
<key>NSFaceIDUsageDescription</key>
|
||||||
<string>For better security, please allow TON Wallet to use your Face ID to authenticate payments.</string>
|
<string>For better security, please allow TON Wallet to use your Face ID to authenticate payments.</string>
|
||||||
|
<key>NSCameraUsageDescription</key>
|
||||||
|
<string>Please allow TON Wallet access to your camera for scanning QR codes.</string>
|
||||||
|
<key>NSPhotoLibraryUsageDescription</key>
|
||||||
|
<string>Please allow TON Wallet access to your Photo Stream in case you need to scan a QR code from a picture.</string>
|
||||||
<key>UIDeviceFamily</key>
|
<key>UIDeviceFamily</key>
|
||||||
<array>
|
<array>
|
||||||
<integer>1</integer>
|
<integer>1</integer>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Localized versions of Info.plist keys */
|
/* Localized versions of Info.plist keys */
|
||||||
|
|
||||||
"NSCameraUsageDescription" = "We need this so that you can take and share photos and videos.";
|
"NSCameraUsageDescription" = "Please allow TON Wallet access to your camera for scanning QR codes.";
|
||||||
"NSPhotoLibraryUsageDescription" = "We need this so that you can share photos and videos from your photo library.";
|
"NSPhotoLibraryUsageDescription" = "Please allow TON Wallet access to your Photo Stream in case you need to scan a QR code from a picture.";
|
||||||
"NSFaceIDUsageDescription" = "For better security, please allow TON Wallet to use your Face ID to authenticate payments.";
|
"NSFaceIDUsageDescription" = "For better security, please allow TON Wallet to use your Face ID to authenticate payments.";
|
||||||
|
@ -4,6 +4,8 @@ import SwiftSignalKit
|
|||||||
import BuildConfig
|
import BuildConfig
|
||||||
import WalletUI
|
import WalletUI
|
||||||
import WalletCore
|
import WalletCore
|
||||||
|
import AVFoundation
|
||||||
|
import MtProtoKit
|
||||||
|
|
||||||
private func encodeText(_ string: String, _ key: Int) -> String {
|
private func encodeText(_ string: String, _ key: Int) -> String {
|
||||||
var result = ""
|
var result = ""
|
||||||
@ -120,27 +122,173 @@ private class ApplicationStatusBarHost: StatusBarHost {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final class FileBackedStorageImpl {
|
||||||
|
private let queue: Queue
|
||||||
|
private let path: String
|
||||||
|
private var data: Data?
|
||||||
|
private var subscribers = Bag<(Data?) -> Void>()
|
||||||
|
|
||||||
|
init(queue: Queue, path: String) {
|
||||||
|
self.queue = queue
|
||||||
|
self.path = path
|
||||||
|
}
|
||||||
|
|
||||||
|
func get() -> Data? {
|
||||||
|
if let data = self.data {
|
||||||
|
return data
|
||||||
|
} else {
|
||||||
|
self.data = try? Data(contentsOf: URL(fileURLWithPath: self.path))
|
||||||
|
return self.data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func set(data: Data) {
|
||||||
|
self.data = data
|
||||||
|
do {
|
||||||
|
try data.write(to: URL(fileURLWithPath: self.path), options: .atomic)
|
||||||
|
} catch let error {
|
||||||
|
print("Error writng data: \(error)")
|
||||||
|
}
|
||||||
|
for f in self.subscribers.copyItems() {
|
||||||
|
f(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func watch(_ f: @escaping (Data?) -> Void) -> Disposable {
|
||||||
|
f(self.get())
|
||||||
|
let index = self.subscribers.add(f)
|
||||||
|
let queue = self.queue
|
||||||
|
return ActionDisposable { [weak self] in
|
||||||
|
queue.async {
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
strongSelf.subscribers.remove(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class FileBackedStorage {
|
||||||
|
private let queue = Queue()
|
||||||
|
private let impl: QueueLocalObject<FileBackedStorageImpl>
|
||||||
|
|
||||||
|
init(path: String) {
|
||||||
|
let queue = self.queue
|
||||||
|
self.impl = QueueLocalObject(queue: queue, generate: {
|
||||||
|
return FileBackedStorageImpl(queue: queue, path: path)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func get() -> Signal<Data?, NoError> {
|
||||||
|
return Signal { subscriber in
|
||||||
|
self.impl.with { impl in
|
||||||
|
subscriber.putNext(impl.get())
|
||||||
|
subscriber.putCompletion()
|
||||||
|
}
|
||||||
|
return EmptyDisposable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func set(data: Data) -> Signal<Never, NoError> {
|
||||||
|
return Signal { subscriber in
|
||||||
|
self.impl.with { impl in
|
||||||
|
impl.set(data: data)
|
||||||
|
subscriber.putCompletion()
|
||||||
|
}
|
||||||
|
return EmptyDisposable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func update<T>(_ f: @escaping (Data?) -> (Data, T)) -> Signal<T, NoError> {
|
||||||
|
return Signal { subscriber in
|
||||||
|
self.impl.with { impl in
|
||||||
|
let (data, result) = f(impl.get())
|
||||||
|
impl.set(data: data)
|
||||||
|
subscriber.putNext(result)
|
||||||
|
subscriber.putCompletion()
|
||||||
|
}
|
||||||
|
return EmptyDisposable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func watch() -> Signal<Data?, NoError> {
|
||||||
|
return Signal { subscriber in
|
||||||
|
let disposable = MetaDisposable()
|
||||||
|
self.impl.with { impl in
|
||||||
|
disposable.set(impl.watch({ data in
|
||||||
|
subscriber.putNext(data)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
return disposable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private let records = Atomic<[WalletStateRecord]>(value: [])
|
private let records = Atomic<[WalletStateRecord]>(value: [])
|
||||||
|
|
||||||
private final class WalletStorageInterfaceImpl: WalletStorageInterface {
|
private final class WalletStorageInterfaceImpl: WalletStorageInterface {
|
||||||
|
private let storage: FileBackedStorage
|
||||||
|
|
||||||
|
init(path: String) {
|
||||||
|
self.storage = FileBackedStorage(path: path)
|
||||||
|
}
|
||||||
|
|
||||||
func watchWalletRecords() -> Signal<[WalletStateRecord], NoError> {
|
func watchWalletRecords() -> Signal<[WalletStateRecord], NoError> {
|
||||||
return .single(records.with { $0 })
|
return self.storage.watch()
|
||||||
|
|> map { data -> [WalletStateRecord] in
|
||||||
|
guard let data = data else {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
return try JSONDecoder().decode(Array<WalletStateRecord>.self, from: data)
|
||||||
|
} catch let error {
|
||||||
|
print("Error deserializing data: \(error)")
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getWalletRecords() -> Signal<[WalletStateRecord], NoError> {
|
func getWalletRecords() -> Signal<[WalletStateRecord], NoError> {
|
||||||
return .single(records.with { $0 })
|
return self.storage.get()
|
||||||
|
|> map { data -> [WalletStateRecord] in
|
||||||
|
guard let data = data else {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
return try JSONDecoder().decode(Array<WalletStateRecord>.self, from: data)
|
||||||
|
} catch let error {
|
||||||
|
print("Error deserializing data: \(error)")
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateWalletRecords(_ f: @escaping ([WalletStateRecord]) -> [WalletStateRecord]) -> Signal<[WalletStateRecord], NoError> {
|
func updateWalletRecords(_ f: @escaping ([WalletStateRecord]) -> [WalletStateRecord]) -> Signal<[WalletStateRecord], NoError> {
|
||||||
return .single(records.modify(f))
|
return self.storage.update { data -> (Data, [WalletStateRecord]) in
|
||||||
|
let records: [WalletStateRecord] = data.flatMap {
|
||||||
|
try? JSONDecoder().decode(Array<WalletStateRecord>.self, from: $0)
|
||||||
|
} ?? []
|
||||||
|
let updatedRecords = f(records)
|
||||||
|
do {
|
||||||
|
let updatedData = try JSONEncoder().encode(updatedRecords)
|
||||||
|
return (updatedData, updatedRecords)
|
||||||
|
} catch let error {
|
||||||
|
print("Error serializing data: \(error)")
|
||||||
|
return (Data(), updatedRecords)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class WalletContextImpl: WalletContext {
|
private final class WalletContextImpl: NSObject, WalletContext, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
|
||||||
let storage: WalletStorageInterface
|
let storage: WalletStorageInterface
|
||||||
let tonInstance: TonInstance
|
let tonInstance: TonInstance
|
||||||
let keychain: TonKeychain
|
let keychain: TonKeychain
|
||||||
let presentationData: WalletPresentationData
|
let presentationData: WalletPresentationData
|
||||||
|
let window: Window1
|
||||||
|
|
||||||
|
private var currentImagePickerCompletion: ((UIImage) -> Void)?
|
||||||
|
|
||||||
var inForeground: Signal<Bool, NoError> {
|
var inForeground: Signal<Bool, NoError> {
|
||||||
return .single(true)
|
return .single(true)
|
||||||
@ -151,7 +299,7 @@ private final class WalletContextImpl: WalletContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func presentNativeController(_ controller: UIViewController) {
|
func presentNativeController(_ controller: UIViewController) {
|
||||||
|
self.window.presentNative(controller)
|
||||||
}
|
}
|
||||||
|
|
||||||
func idleTimerExtension() -> Disposable {
|
func idleTimerExtension() -> Disposable {
|
||||||
@ -159,32 +307,75 @@ private final class WalletContextImpl: WalletContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func openUrl(_ url: String) {
|
func openUrl(_ url: String) {
|
||||||
|
if let parsedUrl = URL(string: url) {
|
||||||
|
UIApplication.shared.openURL(parsedUrl)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func shareUrl(_ url: String) {
|
func shareUrl(_ url: String) {
|
||||||
|
if let parsedUrl = URL(string: url) {
|
||||||
|
self.presentNativeController(UIActivityViewController(activityItems: [parsedUrl], applicationActivities: nil))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func openPlatformSettings() {
|
func openPlatformSettings() {
|
||||||
|
if let url = URL(string: UIApplication.openSettingsURLString) {
|
||||||
|
UIApplication.shared.openURL(url)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func authorizeAccessToCamera(completion: @escaping () -> Void) {
|
func authorizeAccessToCamera(completion: @escaping () -> Void) {
|
||||||
|
AVCaptureDevice.requestAccess(for: AVMediaType.video) { response in
|
||||||
|
Queue.mainQueue().async {
|
||||||
|
if response {
|
||||||
completion()
|
completion()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func pickImage(completion: @escaping (UIImage) -> Void) {
|
func pickImage(completion: @escaping (UIImage) -> Void) {
|
||||||
|
self.currentImagePickerCompletion = completion
|
||||||
|
|
||||||
|
let pickerController = UIImagePickerController()
|
||||||
|
pickerController.delegate = self
|
||||||
|
pickerController.allowsEditing = false
|
||||||
|
pickerController.mediaTypes = ["public.image"]
|
||||||
|
pickerController.sourceType = .photoLibrary
|
||||||
|
self.presentNativeController(pickerController)
|
||||||
}
|
}
|
||||||
|
|
||||||
init(basePath: String, config: String, blockchainName: String, navigationBarTheme: NavigationBarTheme) {
|
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
|
||||||
self.storage = WalletStorageInterfaceImpl()
|
let currentImagePickerCompletion = self.currentImagePickerCompletion
|
||||||
|
self.currentImagePickerCompletion = nil
|
||||||
|
if let image = info[.editedImage] as? UIImage {
|
||||||
|
currentImagePickerCompletion?(image)
|
||||||
|
} else if let image = info[.originalImage] as? UIImage {
|
||||||
|
currentImagePickerCompletion?(image)
|
||||||
|
}
|
||||||
|
picker.presentingViewController?.dismiss(animated: true, completion: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
|
||||||
|
self.currentImagePickerCompletion = nil
|
||||||
|
picker.presentingViewController?.dismiss(animated: true, completion: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
init(basePath: String, config: String, blockchainName: String, navigationBarTheme: NavigationBarTheme, window: Window1) {
|
||||||
|
let _ = try? FileManager.default.createDirectory(at: URL(fileURLWithPath: basePath + "/keys"), withIntermediateDirectories: true, attributes: nil)
|
||||||
|
|
||||||
|
self.storage = WalletStorageInterfaceImpl(path: basePath + "/data")
|
||||||
|
self.window = window
|
||||||
self.tonInstance = TonInstance(
|
self.tonInstance = TonInstance(
|
||||||
basePath: basePath,
|
basePath: basePath + "/keys",
|
||||||
config: config,
|
config: config,
|
||||||
blockchainName: blockchainName,
|
blockchainName: blockchainName,
|
||||||
proxy: nil
|
proxy: nil /*TonProxyImpl()*/
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let baseAppBundleId = Bundle.main.bundleIdentifier!
|
||||||
|
|
||||||
|
#if targetEnvironment(simulator)
|
||||||
self.keychain = TonKeychain(encryptionPublicKey: {
|
self.keychain = TonKeychain(encryptionPublicKey: {
|
||||||
return .single(Data())
|
return .single(Data())
|
||||||
}, encrypt: { data in
|
}, encrypt: { data in
|
||||||
@ -192,6 +383,47 @@ private final class WalletContextImpl: WalletContext {
|
|||||||
}, decrypt: { data in
|
}, decrypt: { data in
|
||||||
return .single(data.data)
|
return .single(data.data)
|
||||||
})
|
})
|
||||||
|
#else
|
||||||
|
self.keychain = TonKeychain(encryptionPublicKey: {
|
||||||
|
return Signal { subscriber in
|
||||||
|
BuildConfig.getHardwareEncryptionAvailable(withBaseAppBundleId: baseAppBundleId, completion: { value in
|
||||||
|
subscriber.putNext(value)
|
||||||
|
subscriber.putCompletion()
|
||||||
|
})
|
||||||
|
return EmptyDisposable
|
||||||
|
}
|
||||||
|
}, encrypt: { data in
|
||||||
|
return Signal { subscriber in
|
||||||
|
BuildConfig.encryptApplicationSecret(data, baseAppBundleId: baseAppBundleId, completion: { result, publicKey in
|
||||||
|
if let result = result, let publicKey = publicKey {
|
||||||
|
subscriber.putNext(TonKeychainEncryptedData(publicKey: publicKey, data: result))
|
||||||
|
subscriber.putCompletion()
|
||||||
|
} else {
|
||||||
|
subscriber.putError(.generic)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return EmptyDisposable
|
||||||
|
}
|
||||||
|
}, decrypt: { encryptedData in
|
||||||
|
return Signal { subscriber in
|
||||||
|
BuildConfig.decryptApplicationSecret(encryptedData.data, publicKey: encryptedData.publicKey, baseAppBundleId: baseAppBundleId, completion: { result, cancelled in
|
||||||
|
if let result = result {
|
||||||
|
subscriber.putNext(result)
|
||||||
|
} else {
|
||||||
|
let error: TonKeychainDecryptDataError
|
||||||
|
if cancelled {
|
||||||
|
error = .cancelled
|
||||||
|
} else {
|
||||||
|
error = .generic
|
||||||
|
}
|
||||||
|
subscriber.putError(error)
|
||||||
|
}
|
||||||
|
subscriber.putCompletion()
|
||||||
|
})
|
||||||
|
return EmptyDisposable
|
||||||
|
}
|
||||||
|
})
|
||||||
|
#endif
|
||||||
let accentColor = UIColor(rgb: 0x007ee5)
|
let accentColor = UIColor(rgb: 0x007ee5)
|
||||||
self.presentationData = WalletPresentationData(
|
self.presentationData = WalletPresentationData(
|
||||||
theme: WalletTheme(
|
theme: WalletTheme(
|
||||||
@ -271,6 +503,8 @@ private final class WalletContextImpl: WalletContext {
|
|||||||
groupingSeparator: " "
|
groupingSeparator: " "
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
super.init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,18 +518,20 @@ final class AppDelegate: NSObject, UIApplicationDelegate {
|
|||||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
|
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
|
||||||
let statusBarHost = ApplicationStatusBarHost()
|
let statusBarHost = ApplicationStatusBarHost()
|
||||||
let (window, hostView) = nativeWindowHostView()
|
let (window, hostView) = nativeWindowHostView()
|
||||||
self.mainWindow = Window1(hostView: hostView, statusBarHost: statusBarHost)
|
let mainWindow = Window1(hostView: hostView, statusBarHost: statusBarHost)
|
||||||
|
self.mainWindow = mainWindow
|
||||||
hostView.containerView.backgroundColor = UIColor.white
|
hostView.containerView.backgroundColor = UIColor.white
|
||||||
self.window = window
|
self.window = window
|
||||||
|
|
||||||
|
let accentColor = UIColor(rgb: 0x007ee5)
|
||||||
let navigationBarTheme = NavigationBarTheme(
|
let navigationBarTheme = NavigationBarTheme(
|
||||||
buttonColor: .blue,
|
buttonColor: accentColor,
|
||||||
disabledButtonColor: .gray,
|
disabledButtonColor: UIColor(rgb: 0xd0d0d0),
|
||||||
primaryTextColor: .black,
|
primaryTextColor: .black,
|
||||||
backgroundColor: .lightGray,
|
backgroundColor: UIColor(rgb: 0xf7f7f7),
|
||||||
separatorColor: .black,
|
separatorColor: UIColor(rgb: 0xb1b1b1),
|
||||||
badgeBackgroundColor: .red,
|
badgeBackgroundColor: UIColor(rgb: 0xff3b30),
|
||||||
badgeStrokeColor: .red,
|
badgeStrokeColor: UIColor(rgb: 0xff3b30),
|
||||||
badgeTextColor: .white
|
badgeTextColor: .white
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -309,6 +545,7 @@ final class AppDelegate: NSObject, UIApplicationDelegate {
|
|||||||
)
|
)
|
||||||
|
|
||||||
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
|
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
|
||||||
|
print("Starting with \(documentsPath)")
|
||||||
|
|
||||||
let config =
|
let config =
|
||||||
"""
|
"""
|
||||||
@ -336,16 +573,230 @@ final class AppDelegate: NSObject, UIApplicationDelegate {
|
|||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
let walletContext = WalletContextImpl(basePath: documentsPath, config: config, blockchainName: "testnet", navigationBarTheme: navigationBarTheme)
|
let walletContext = WalletContextImpl(basePath: documentsPath, config: config, blockchainName: "testnet", navigationBarTheme: navigationBarTheme, window: mainWindow)
|
||||||
self.walletContext = walletContext
|
self.walletContext = walletContext
|
||||||
|
|
||||||
|
let _ = (combineLatest(queue: .mainQueue(),
|
||||||
|
walletContext.storage.getWalletRecords(),
|
||||||
|
walletContext.keychain.encryptionPublicKey()
|
||||||
|
)
|
||||||
|
|> deliverOnMainQueue).start(next: { records, publicKey in
|
||||||
|
if let record = records.first {
|
||||||
|
if let publicKey = publicKey {
|
||||||
|
print("publicKey = \(publicKey.base64EncodedString())")
|
||||||
|
if record.info.encryptedSecret.publicKey == publicKey {
|
||||||
|
if record.exportCompleted {
|
||||||
|
let _ = (walletAddress(publicKey: record.info.publicKey, tonInstance: walletContext.tonInstance)
|
||||||
|
|> deliverOnMainQueue).start(next: { address in
|
||||||
|
let infoScreen = WalletInfoScreen(context: walletContext, walletInfo: record.info, address: address, enableDebugActions: false)
|
||||||
|
|
||||||
|
navigationController.setViewControllers([infoScreen], animated: false)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
let createdScreen = WalletSplashScreen(context: walletContext, mode: .created(record.info, nil), walletCreatedPreloadState: nil)
|
||||||
|
|
||||||
|
navigationController.setViewControllers([createdScreen], animated: false)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let splashScreen = WalletSplashScreen(context: walletContext, mode: .secureStorageReset(.changed), walletCreatedPreloadState: nil)
|
||||||
|
|
||||||
|
navigationController.setViewControllers([splashScreen], animated: false)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let splashScreen = WalletSplashScreen(context: walletContext, mode: WalletSplashMode.secureStorageReset(.notAvailable), walletCreatedPreloadState: nil)
|
||||||
|
|
||||||
|
navigationController.setViewControllers([splashScreen], animated: false)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if publicKey != nil {
|
||||||
let splashScreen = WalletSplashScreen(context: walletContext, mode: .intro, walletCreatedPreloadState: nil)
|
let splashScreen = WalletSplashScreen(context: walletContext, mode: .intro, walletCreatedPreloadState: nil)
|
||||||
|
|
||||||
navigationController.setViewControllers([splashScreen], animated: false)
|
navigationController.setViewControllers([splashScreen], animated: false)
|
||||||
self.mainWindow?.viewController = navigationController
|
} else {
|
||||||
|
let splashScreen = WalletSplashScreen(context: walletContext, mode: .secureStorageNotAvailable, walletCreatedPreloadState: nil)
|
||||||
|
|
||||||
|
navigationController.setViewControllers([splashScreen], animated: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
mainWindow.viewController = navigationController
|
||||||
|
|
||||||
self.window?.makeKeyAndVisible()
|
self.window?.makeKeyAndVisible()
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final class Serialization: NSObject, MTSerialization {
|
||||||
|
func currentLayer() -> UInt {
|
||||||
|
return 106
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseMessage(_ data: Data!) -> Any! {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func exportAuthorization(_ datacenterId: Int32, data: AutoreleasingUnsafeMutablePointer<NSData?>!) -> MTExportAuthorizationResponseParser! {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func importAuthorization(_ authId: Int32, bytes: Data!) -> Data! {
|
||||||
|
return Data()
|
||||||
|
}
|
||||||
|
|
||||||
|
func requestDatacenterAddress(with data: AutoreleasingUnsafeMutablePointer<NSData?>!) -> MTRequestDatacenterAddressListParser! {
|
||||||
|
return { _ in
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func requestNoop(_ data: AutoreleasingUnsafeMutablePointer<NSData?>!) -> MTRequestNoopParser! {
|
||||||
|
return { _ in
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class Keychain: NSObject, MTKeychain {
|
||||||
|
let get: (String) -> Data?
|
||||||
|
let set: (String, Data) -> Void
|
||||||
|
let remove: (String) -> Void
|
||||||
|
|
||||||
|
init(get: @escaping (String) -> Data?, set: @escaping (String, Data) -> Void, remove: @escaping (String) -> Void) {
|
||||||
|
self.get = get
|
||||||
|
self.set = set
|
||||||
|
self.remove = remove
|
||||||
|
}
|
||||||
|
|
||||||
|
func setObject(_ object: Any!, forKey aKey: String!, group: String!) {
|
||||||
|
if let object = object {
|
||||||
|
let data = NSKeyedArchiver.archivedData(withRootObject: object)
|
||||||
|
self.set(group + ":" + aKey, data)
|
||||||
|
} else {
|
||||||
|
self.remove(group + ":" + aKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func object(forKey aKey: String!, group: String!) -> Any! {
|
||||||
|
if let data = self.get(group + ":" + aKey) {
|
||||||
|
return NSKeyedUnarchiver.unarchiveObject(with: data as Data)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeObject(forKey aKey: String!, group: String!) {
|
||||||
|
self.remove(group + ":" + aKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func dropGroup(_ group: String!) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class TonProxyImpl: TonNetworkProxy {
|
||||||
|
private let context: MTContext
|
||||||
|
private let mtProto: MTProto
|
||||||
|
private let requestService: MTRequestMessageService
|
||||||
|
|
||||||
|
init() {
|
||||||
|
let serialization = Serialization()
|
||||||
|
|
||||||
|
var apiEnvironment = MTApiEnvironment()
|
||||||
|
|
||||||
|
apiEnvironment.apiId = 8
|
||||||
|
apiEnvironment.langPack = "ios"
|
||||||
|
apiEnvironment.layer = serialization.currentLayer() as NSNumber
|
||||||
|
apiEnvironment.disableUpdates = true
|
||||||
|
apiEnvironment = apiEnvironment.withUpdatedLangPackCode("en")
|
||||||
|
|
||||||
|
self.context = MTContext(serialization: serialization, apiEnvironment: apiEnvironment, isTestingEnvironment: false, useTempAuthKeys: false)
|
||||||
|
|
||||||
|
let seedAddressList: [Int: [String]]
|
||||||
|
|
||||||
|
seedAddressList = [
|
||||||
|
1: ["149.154.175.50", "2001:b28:f23d:f001::a"],
|
||||||
|
2: ["149.154.167.50", "2001:67c:4e8:f002::a"],
|
||||||
|
3: ["149.154.175.100", "2001:b28:f23d:f003::a"],
|
||||||
|
4: ["149.154.167.91", "2001:67c:4e8:f004::a"],
|
||||||
|
5: ["149.154.171.5", "2001:b28:f23f:f005::a"]
|
||||||
|
]
|
||||||
|
|
||||||
|
for (id, ips) in seedAddressList {
|
||||||
|
self.context.setSeedAddressSetForDatacenterWithId(id, seedAddressSet: MTDatacenterAddressSet(addressList: ips.map { MTDatacenterAddress(ip: $0, port: 443, preferForMedia: false, restrictToTcp: false, cdn: false, preferForProxy: false, secret: nil)! }))
|
||||||
|
}
|
||||||
|
|
||||||
|
let keychainDict = Atomic<[String: Data]>(value: [:])
|
||||||
|
self.context.keychain = Keychain(get: { key in
|
||||||
|
return keychainDict.with { dict -> Data? in
|
||||||
|
return dict[key]
|
||||||
|
}
|
||||||
|
}, set: { key, value in
|
||||||
|
let _ = keychainDict.modify { dict in
|
||||||
|
var dict = dict
|
||||||
|
dict[key] = value
|
||||||
|
return dict
|
||||||
|
}
|
||||||
|
}, remove: { key in
|
||||||
|
let _ = keychainDict.modify { dict in
|
||||||
|
var dict = dict
|
||||||
|
dict.removeValue(forKey: key)
|
||||||
|
return dict
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let mtProto = MTProto(context: self.context, datacenterId: 2, usageCalculationInfo: nil)!
|
||||||
|
mtProto.useTempAuthKeys = self.context.useTempAuthKeys
|
||||||
|
mtProto.checkForProxyConnectionIssues = false
|
||||||
|
|
||||||
|
self.mtProto = mtProto
|
||||||
|
|
||||||
|
self.requestService = MTRequestMessageService(context: context)!
|
||||||
|
mtProto.add(self.requestService)
|
||||||
|
|
||||||
|
self.mtProto.resume()
|
||||||
|
}
|
||||||
|
|
||||||
|
func request(data: Data, timeout: Double, completion: @escaping (TonNetworkProxyResult) -> Void) -> Disposable {
|
||||||
|
let request = MTRequest()
|
||||||
|
let outputStream = MTOutputStream()
|
||||||
|
|
||||||
|
//wallet.sendLiteRequest#e2c9d33e body:bytes = wallet.LiteResponse;
|
||||||
|
outputStream.write(Int32(bitPattern: 0xe2c9d33e as UInt32))
|
||||||
|
outputStream.writeBytes(data)
|
||||||
|
|
||||||
|
request.setPayload(outputStream.currentBytes(), metadata: "wallet.sendLiteRequest", shortMetadata: "wallet.sendLiteRequest", responseParser: { response in
|
||||||
|
guard let response = response else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
let inputStream = MTInputStream(data: response)!
|
||||||
|
//wallet.liteResponse#764386d7 response:bytes = wallet.LiteResponse;
|
||||||
|
let signature = inputStream.readInt32()
|
||||||
|
if (signature != 0x764386d7 as Int32) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return inputStream.readBytes()
|
||||||
|
})
|
||||||
|
|
||||||
|
request.dependsOnPasswordEntry = false
|
||||||
|
request.shouldContinueExecutionWithErrorContext = { _ in
|
||||||
|
return true
|
||||||
|
};
|
||||||
|
|
||||||
|
request.completed = { response, _, error in
|
||||||
|
if let response = response as? Data {
|
||||||
|
completion(.reponse(response))
|
||||||
|
} else {
|
||||||
|
completion(.error(error?.errorDescription ?? "UNKNOWN ERROR"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let requestId = request.internalId
|
||||||
|
|
||||||
|
self.requestService.add(request)
|
||||||
|
|
||||||
|
return ActionDisposable { [weak self] in
|
||||||
|
self?.requestService.removeRequest(byInternalId: requestId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
"Wallet.Updated.JustNow" = "just now";
|
"Wallet.Updated.JustNow" = "updated just now";
|
||||||
"Wallet.Updated.MinutesAgo_0" = "%@ minutes ago"; //three to ten
|
"Wallet.Updated.MinutesAgo_0" = "%@ minutes ago"; //three to ten
|
||||||
"Wallet.Updated.MinutesAgo_1" = "1 minute ago"; //one
|
"Wallet.Updated.MinutesAgo_1" = "1 minute ago"; //one
|
||||||
"Wallet.Updated.MinutesAgo_2" = "2 minutes ago"; //two
|
"Wallet.Updated.MinutesAgo_2" = "2 minutes ago"; //two
|
||||||
@ -19,6 +19,7 @@
|
|||||||
"Wallet.Info.Address" = "Your wallet address";
|
"Wallet.Info.Address" = "Your wallet address";
|
||||||
"Wallet.Info.YourBalance" = "your balance";
|
"Wallet.Info.YourBalance" = "your balance";
|
||||||
"Wallet.Info.Receive" = "Receive";
|
"Wallet.Info.Receive" = "Receive";
|
||||||
|
"Wallet.Info.ReceiveGrams" = "Receive Grams";
|
||||||
"Wallet.Info.Send" = "Send";
|
"Wallet.Info.Send" = "Send";
|
||||||
"Wallet.Info.RefreshErrorTitle" = "No network";
|
"Wallet.Info.RefreshErrorTitle" = "No network";
|
||||||
"Wallet.Info.RefreshErrorText" = "Couldn't refresh balance. Please make sure your internet connection is working and try again.";
|
"Wallet.Info.RefreshErrorText" = "Couldn't refresh balance. Please make sure your internet connection is working and try again.";
|
||||||
|
66
extract_wallet_source.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
def get_file_list(dir):
|
||||||
|
result_files = []
|
||||||
|
result_dirs = []
|
||||||
|
for root, dirs, files in os.walk(dir, topdown=False):
|
||||||
|
for name in files:
|
||||||
|
result_files.append(os.path.relpath(os.path.join(root, name), dir))
|
||||||
|
for name in dirs:
|
||||||
|
result_dirs.append(os.path.relpath(os.path.join(root, name), dir))
|
||||||
|
return set(result_dirs), set(result_files)
|
||||||
|
|
||||||
|
def clean_files(base_dir, dirs, files):
|
||||||
|
for file in files:
|
||||||
|
if file == '.DS_Store':
|
||||||
|
os.remove(base_dir + '/' + file)
|
||||||
|
for dir in dirs:
|
||||||
|
if re.match('.*\\.xcodeproj', dir) or re.match('.*\\.xcworkspace', dir):
|
||||||
|
shutil.rmtree(base_dir + '/' + dir, ignore_errors=True)
|
||||||
|
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print('Usage: extract_wallet_source.py destination')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
destination = sys.argv[1]
|
||||||
|
|
||||||
|
deps_data = os.popen('make -f Wallet.makefile --silent wallet_deps').read()
|
||||||
|
|
||||||
|
deps = json.loads(deps_data)
|
||||||
|
|
||||||
|
paths = []
|
||||||
|
for dep in deps:
|
||||||
|
dep_type = deps[dep]['buck.type']
|
||||||
|
if dep_type == 'genrule':
|
||||||
|
continue
|
||||||
|
match = re.search('//(.+?):', dep)
|
||||||
|
if match:
|
||||||
|
dep_path = match.group(1)
|
||||||
|
if dep_path not in paths:
|
||||||
|
paths.append(dep_path)
|
||||||
|
|
||||||
|
for dep_path in paths:
|
||||||
|
shutil.copytree(dep_path, destination + '/' + dep_path)
|
||||||
|
|
||||||
|
result_dirs, result_files = get_file_list(destination)
|
||||||
|
clean_files(destination, result_dirs, result_files)
|
||||||
|
|
||||||
|
with open(destination + '/BUCK', 'w+b') as file:
|
||||||
|
pass
|
||||||
|
|
||||||
|
shutil.copytree('Config', destination + '/' + 'Config')
|
||||||
|
|
||||||
|
copy_files = [
|
||||||
|
'.buckconfig',
|
||||||
|
'Utils.makefile',
|
||||||
|
'Wallet.makefile',
|
||||||
|
'check_env.sh',
|
||||||
|
'package_app.sh',
|
||||||
|
]
|
||||||
|
|
||||||
|
for file in copy_files:
|
||||||
|
shutil.copy(file, destination + '/' + file)
|
@ -3,13 +3,24 @@
|
|||||||
#set -x
|
#set -x
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then
|
||||||
|
echo "Usage: sh package_app.sh path/to/buck platform-flavors type"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
PLATFORM_FLAVORS="$1"
|
PLATFORM_FLAVORS="$1"
|
||||||
BUCK="$2"
|
BUCK="$2"
|
||||||
|
APP_TYPE="$3"
|
||||||
|
shift
|
||||||
shift
|
shift
|
||||||
shift
|
shift
|
||||||
|
|
||||||
BUILD_PATH="build"
|
BUILD_PATH="build"
|
||||||
|
if [ "$APP_TYPE" == "wallet" ]; then
|
||||||
|
APP_NAME="TONWallet"
|
||||||
|
else
|
||||||
APP_NAME="Telegram"
|
APP_NAME="Telegram"
|
||||||
|
fi
|
||||||
|
|
||||||
IPA_PATH="$BUILD_PATH/$APP_NAME.ipa"
|
IPA_PATH="$BUILD_PATH/$APP_NAME.ipa"
|
||||||
DSYMS_FOLDER_NAME="DSYMs"
|
DSYMS_FOLDER_NAME="DSYMs"
|
||||||
@ -41,7 +52,11 @@ rm -rf "$TEMP_PATH"
|
|||||||
mkdir -p "$TEMP_PATH"
|
mkdir -p "$TEMP_PATH"
|
||||||
mkdir -p "$TEMP_ENTITLEMENTS_PATH"
|
mkdir -p "$TEMP_ENTITLEMENTS_PATH"
|
||||||
|
|
||||||
|
if [ "$APP_TYPE" == "wallet" ]; then
|
||||||
|
cp "buck-out/gen/Wallet/AppPackage#$PLATFORM_FLAVORS.ipa" "$IPA_PATH.original"
|
||||||
|
else
|
||||||
cp "buck-out/gen/AppPackage#$PLATFORM_FLAVORS.ipa" "$IPA_PATH.original"
|
cp "buck-out/gen/AppPackage#$PLATFORM_FLAVORS.ipa" "$IPA_PATH.original"
|
||||||
|
fi
|
||||||
rm -rf "$IPA_PATH.original.unpacked"
|
rm -rf "$IPA_PATH.original.unpacked"
|
||||||
rm -f "$BUILD_PATH/${APP_NAME}_signed.ipa"
|
rm -f "$BUILD_PATH/${APP_NAME}_signed.ipa"
|
||||||
mkdir -p "$IPA_PATH.original.unpacked"
|
mkdir -p "$IPA_PATH.original.unpacked"
|
||||||
@ -51,18 +66,18 @@ unzip "$IPA_PATH.original" -d "$IPA_PATH.original.unpacked/" 1>/dev/null
|
|||||||
rm "$IPA_PATH.original"
|
rm "$IPA_PATH.original"
|
||||||
|
|
||||||
UNPACKED_PATH="$IPA_PATH.original.unpacked"
|
UNPACKED_PATH="$IPA_PATH.original.unpacked"
|
||||||
|
if [ "$APP_TYPE" == "wallet" ]; then
|
||||||
|
APP_PATH="$UNPACKED_PATH/Payload/Wallet.app"
|
||||||
|
else
|
||||||
APP_PATH="$UNPACKED_PATH/Payload/Telegram.app"
|
APP_PATH="$UNPACKED_PATH/Payload/Telegram.app"
|
||||||
|
fi
|
||||||
|
|
||||||
FRAMEWORKS_DIR="$APP_PATH/Frameworks"
|
FRAMEWORKS_DIR="$APP_PATH/Frameworks"
|
||||||
|
|
||||||
rm -rf "$IPA_PATH.original.unpacked/SwiftSupport/iphoneos/"*
|
rm -rf "$IPA_PATH.original.unpacked/SwiftSupport/iphoneos/"*
|
||||||
rm -rf "$IPA_PATH.original.unpacked/Symbols/"*
|
rm -rf "$IPA_PATH.original.unpacked/Symbols/"*
|
||||||
rm -rf "$FRAMEWORKS_DIR/"*
|
rm -rf "$FRAMEWORKS_DIR/"*
|
||||||
|
|
||||||
if [ -z "$1" ] || [ -z "$2" ]; then
|
|
||||||
echo "Usage: sh package_app.sh path/to/buck platform-flavors"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$PACKAGE_METHOD" ]; then
|
if [ -z "$PACKAGE_METHOD" ]; then
|
||||||
echo "PACKAGE_METHOD is not set"
|
echo "PACKAGE_METHOD is not set"
|
||||||
exit 1
|
exit 1
|
||||||
@ -111,14 +126,15 @@ if [ ! -d "$PROFILES_PATH" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#security delete-keychain "$KEYCHAIN_PATH" || true
|
|
||||||
rm -f "$KEYCHAIN_PATH"
|
rm -f "$KEYCHAIN_PATH"
|
||||||
#security create-keychain -p "password" "$KEYCHAIN_PATH"
|
|
||||||
#security unlock-keychain -p "password" "$KEYCHAIN_PATH"
|
|
||||||
#KEYCHAIN_FLAG="--keychain '$KEYCHAIN_PATH'"
|
|
||||||
|
|
||||||
|
if [ "$APP_TYPE" == "wallet" ]; then
|
||||||
|
APP_ITEMS_WITH_PROVISIONING_PROFILE="APP"
|
||||||
|
APP_ITEMS_WITH_ENTITLEMENTS="APP"
|
||||||
|
else
|
||||||
APP_ITEMS_WITH_PROVISIONING_PROFILE="APP EXTENSION_Share EXTENSION_Widget EXTENSION_NotificationService EXTENSION_NotificationContent EXTENSION_Intents WATCH_APP WATCH_EXTENSION"
|
APP_ITEMS_WITH_PROVISIONING_PROFILE="APP EXTENSION_Share EXTENSION_Widget EXTENSION_NotificationService EXTENSION_NotificationContent EXTENSION_Intents WATCH_APP WATCH_EXTENSION"
|
||||||
APP_ITEMS_WITH_ENTITLEMENTS="APP EXTENSION_Share EXTENSION_Widget EXTENSION_NotificationService EXTENSION_NotificationContent EXTENSION_Intents"
|
APP_ITEMS_WITH_ENTITLEMENTS="APP EXTENSION_Share EXTENSION_Widget EXTENSION_NotificationService EXTENSION_NotificationContent EXTENSION_Intents"
|
||||||
|
fi
|
||||||
|
|
||||||
COMMON_IDENTITY_HASH=""
|
COMMON_IDENTITY_HASH=""
|
||||||
|
|
||||||
@ -255,8 +271,14 @@ COPY_PLIST_KEYS=(\
|
|||||||
)
|
)
|
||||||
APP_PLIST="$APP_PATH/Info.plist"
|
APP_PLIST="$APP_PATH/Info.plist"
|
||||||
|
|
||||||
|
if [ "$APP_TYPE" == "wallet" ]; then
|
||||||
|
APP_BINARY_TARGET="//Wallet:Wallet"
|
||||||
|
else
|
||||||
|
APP_BINARY_TARGET="//:Telegram"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Repacking frameworks..."
|
echo "Repacking frameworks..."
|
||||||
for DEPENDENCY in $(${BUCK} query "kind('apple_library', deps('//:Telegram#$PLATFORM_FLAVORS', 1))" "$@"); do
|
for DEPENDENCY in $(${BUCK} query "kind('apple_library', deps('${APP_BINARY_TARGET}#$PLATFORM_FLAVORS', 1))" "$@"); do
|
||||||
DEPENDENCY_PATH=$(echo "$DEPENDENCY" | sed -e "s#^//##" | sed -e "s#:#/#")
|
DEPENDENCY_PATH=$(echo "$DEPENDENCY" | sed -e "s#^//##" | sed -e "s#:#/#")
|
||||||
DEPENDENCY_NAME=$(echo "$DEPENDENCY" | sed -e "s/#.*//" | sed -e "s/^.*\://")
|
DEPENDENCY_NAME=$(echo "$DEPENDENCY" | sed -e "s/#.*//" | sed -e "s/^.*\://")
|
||||||
DYLIB_PATH="buck-out/gen/$DEPENDENCY_PATH/lib$DEPENDENCY_NAME.dylib"
|
DYLIB_PATH="buck-out/gen/$DEPENDENCY_PATH/lib$DEPENDENCY_NAME.dylib"
|
||||||
@ -283,23 +305,40 @@ for DEPENDENCY in $(${BUCK} query "kind('apple_library', deps('//:Telegram#$PLAT
|
|||||||
cp -r "$DSYM_PATH" "$DSYMS_DIR/"
|
cp -r "$DSYM_PATH" "$DSYMS_DIR/"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if [ "$APP_TYPE" == "wallet" ]; then
|
||||||
|
APP_BINARY_DSYM_PATH="buck-out/gen/Wallet/Wallet#dwarf-and-dsym,$PLATFORM_FLAVORS,no-include-frameworks/Wallet.app.dSYM"
|
||||||
|
else
|
||||||
APP_BINARY_DSYM_PATH="buck-out/gen/Telegram#dwarf-and-dsym,$PLATFORM_FLAVORS,no-include-frameworks/Telegram.app.dSYM"
|
APP_BINARY_DSYM_PATH="buck-out/gen/Telegram#dwarf-and-dsym,$PLATFORM_FLAVORS,no-include-frameworks/Telegram.app.dSYM"
|
||||||
|
fi
|
||||||
cp -r "$APP_BINARY_DSYM_PATH" "$DSYMS_DIR/"
|
cp -r "$APP_BINARY_DSYM_PATH" "$DSYMS_DIR/"
|
||||||
|
|
||||||
|
if [ "$APP_TYPE" == "wallet" ]; then
|
||||||
|
EXTENSIONS=""
|
||||||
|
else
|
||||||
EXTENSIONS="Share Widget Intents NotificationContent NotificationService"
|
EXTENSIONS="Share Widget Intents NotificationContent NotificationService"
|
||||||
|
fi
|
||||||
|
|
||||||
for EXTENSION in $EXTENSIONS; do
|
for EXTENSION in $EXTENSIONS; do
|
||||||
EXTENSION_DSYM_PATH="buck-out/gen/${EXTENSION}Extension#dwarf-and-dsym,$PLATFORM_FLAVORS,no-include-frameworks/${EXTENSION}Extension.appex.dSYM"
|
EXTENSION_DSYM_PATH="buck-out/gen/${EXTENSION}Extension#dwarf-and-dsym,$PLATFORM_FLAVORS,no-include-frameworks/${EXTENSION}Extension.appex.dSYM"
|
||||||
cp -r "$EXTENSION_DSYM_PATH" "$DSYMS_DIR/"
|
cp -r "$EXTENSION_DSYM_PATH" "$DSYMS_DIR/"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if [ "$APP_TYPE" != "wallet" ]; then
|
||||||
WATCH_EXTENSION_DSYM_PATH="buck-out/gen/WatchAppExtension#dwarf-and-dsym,no-include-frameworks,watchos-arm64_32,watchos-armv7k/WatchAppExtension.appex.dSYM"
|
WATCH_EXTENSION_DSYM_PATH="buck-out/gen/WatchAppExtension#dwarf-and-dsym,no-include-frameworks,watchos-arm64_32,watchos-armv7k/WatchAppExtension.appex.dSYM"
|
||||||
cp -r "$WATCH_EXTENSION_DSYM_PATH" "$DSYMS_DIR/"
|
cp -r "$WATCH_EXTENSION_DSYM_PATH" "$DSYMS_DIR/"
|
||||||
|
fi
|
||||||
|
|
||||||
TEMP_DYLIB_DIR="$TEMP_PATH/SwiftSupport"
|
TEMP_DYLIB_DIR="$TEMP_PATH/SwiftSupport"
|
||||||
rm -rf "$TEMP_DYLIB_DIR"
|
rm -rf "$TEMP_DYLIB_DIR"
|
||||||
mkdir -p "$TEMP_DYLIB_DIR"
|
mkdir -p "$TEMP_DYLIB_DIR"
|
||||||
mkdir -p "$TEMP_DYLIB_DIR/out"
|
mkdir -p "$TEMP_DYLIB_DIR/out"
|
||||||
|
|
||||||
|
if [ "$APP_TYPE" == "wallet" ]; then
|
||||||
|
EXECUTABLE_NAME="Wallet"
|
||||||
|
else
|
||||||
|
EXECUTABLE_NAME="Telegram"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Copying swift support files..."
|
echo "Copying swift support files..."
|
||||||
xcrun swift-stdlib-tool \
|
xcrun swift-stdlib-tool \
|
||||||
--copy \
|
--copy \
|
||||||
@ -307,7 +346,7 @@ xcrun swift-stdlib-tool \
|
|||||||
--platform iphoneos \
|
--platform iphoneos \
|
||||||
--toolchain "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain" \
|
--toolchain "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain" \
|
||||||
--source-libraries "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos" \
|
--source-libraries "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos" \
|
||||||
--scan-executable "$APP_PATH/Telegram" \
|
--scan-executable "$APP_PATH/$EXECUTABLE_NAME" \
|
||||||
--scan-folder "$APP_PATH/Frameworks" \
|
--scan-folder "$APP_PATH/Frameworks" \
|
||||||
--scan-folder "$APP_PATH/PlugIns" \
|
--scan-folder "$APP_PATH/PlugIns" \
|
||||||
--destination "$TEMP_DYLIB_DIR"
|
--destination "$TEMP_DYLIB_DIR"
|
||||||
@ -348,7 +387,12 @@ done
|
|||||||
|
|
||||||
echo "Signing..."
|
echo "Signing..."
|
||||||
|
|
||||||
|
if [ "$APP_TYPE" == "wallet" ]; then
|
||||||
|
PLUGINS=""
|
||||||
|
else
|
||||||
PLUGINS="Share Widget Intents NotificationService NotificationContent"
|
PLUGINS="Share Widget Intents NotificationService NotificationContent"
|
||||||
|
fi
|
||||||
|
|
||||||
for PLUGIN in $PLUGINS; do
|
for PLUGIN in $PLUGINS; do
|
||||||
PLUGIN_PATH="$APP_PATH/PlugIns/${PLUGIN}Extension.appex"
|
PLUGIN_PATH="$APP_PATH/PlugIns/${PLUGIN}Extension.appex"
|
||||||
if [ ! -d "$PLUGIN_PATH" ]; then
|
if [ ! -d "$PLUGIN_PATH" ]; then
|
||||||
@ -377,6 +421,7 @@ for PLUGIN in $PLUGINS; do
|
|||||||
/usr/bin/codesign ${VERBOSE} -f -s "$COMMON_IDENTITY_HASH" --entitlements "${!ENTITLEMENTS_PATH_VAR}" "$PLUGIN_PATH"
|
/usr/bin/codesign ${VERBOSE} -f -s "$COMMON_IDENTITY_HASH" --entitlements "${!ENTITLEMENTS_PATH_VAR}" "$PLUGIN_PATH"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if [ "$APP_TYPE" != "wallet" ]; then
|
||||||
WATCH_APP_PATH="$APP_PATH/Watch/WatchApp.app"
|
WATCH_APP_PATH="$APP_PATH/Watch/WatchApp.app"
|
||||||
WATCH_EXTENSION_PATH="$WATCH_APP_PATH/PlugIns/WatchAppExtension.appex"
|
WATCH_EXTENSION_PATH="$WATCH_APP_PATH/PlugIns/WatchAppExtension.appex"
|
||||||
|
|
||||||
@ -423,6 +468,7 @@ fi
|
|||||||
|
|
||||||
cp "${!WATCH_APP_PROFILE_PATH_VAR}" "$WATCH_APP_PATH/embedded.mobileprovision"
|
cp "${!WATCH_APP_PROFILE_PATH_VAR}" "$WATCH_APP_PATH/embedded.mobileprovision"
|
||||||
/usr/bin/codesign ${VERBOSE} -f -s "$COMMON_IDENTITY_HASH" --entitlements "${!WATCH_APP_ENTITLEMENTS_PATH_VAR}" "$WATCH_APP_PATH" 2>/dev/null
|
/usr/bin/codesign ${VERBOSE} -f -s "$COMMON_IDENTITY_HASH" --entitlements "${!WATCH_APP_ENTITLEMENTS_PATH_VAR}" "$WATCH_APP_PATH" 2>/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
APP_PROFILE_PATH_VAR="PROFILE_PATH_APP"
|
APP_PROFILE_PATH_VAR="PROFILE_PATH_APP"
|
||||||
if [ -z "${!APP_PROFILE_PATH_VAR}" ]; then
|
if [ -z "${!APP_PROFILE_PATH_VAR}" ]; then
|
||||||
|
@ -389,6 +389,10 @@ public func nativeWindowHostView() -> (UIWindow & WindowHost, WindowHostView) {
|
|||||||
hostView?.presentNative?(controller)
|
hostView?.presentNative?(controller)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hostView.nativeController = { [weak rootViewController] in
|
||||||
|
return rootViewController
|
||||||
|
}
|
||||||
|
|
||||||
window.hitTestImpl = { [weak hostView] point, event in
|
window.hitTestImpl = { [weak hostView] point, event in
|
||||||
return hostView?.hitTest?(point, event)
|
return hostView?.hitTest?(point, event)
|
||||||
}
|
}
|
||||||
|
@ -211,6 +211,7 @@ public final class WindowHostView {
|
|||||||
var present: ((ContainableController, PresentationSurfaceLevel, Bool, @escaping () -> Void) -> Void)?
|
var present: ((ContainableController, PresentationSurfaceLevel, Bool, @escaping () -> Void) -> Void)?
|
||||||
var presentInGlobalOverlay: ((_ controller: ContainableController) -> Void)?
|
var presentInGlobalOverlay: ((_ controller: ContainableController) -> Void)?
|
||||||
var presentNative: ((UIViewController) -> Void)?
|
var presentNative: ((UIViewController) -> Void)?
|
||||||
|
var nativeController: (() -> UIViewController?)?
|
||||||
var updateSize: ((CGSize, Double) -> Void)?
|
var updateSize: ((CGSize, Double) -> Void)?
|
||||||
var layoutSubviews: (() -> Void)?
|
var layoutSubviews: (() -> Void)?
|
||||||
var updateToInterfaceOrientation: ((UIInterfaceOrientation) -> Void)?
|
var updateToInterfaceOrientation: ((UIInterfaceOrientation) -> Void)?
|
||||||
@ -1109,7 +1110,9 @@ public class Window1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func presentNative(_ controller: UIViewController) {
|
public func presentNative(_ controller: UIViewController) {
|
||||||
|
if let nativeController = self.hostView.nativeController?() {
|
||||||
|
nativeController.present(controller, animated: true, completion: nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func panGestureBegan(location: CGPoint) {
|
private func panGestureBegan(location: CGPoint) {
|
||||||
|
@ -477,7 +477,7 @@ public struct CombinedWalletState: Codable, Equatable {
|
|||||||
public var pendingTransactions: [PendingWalletTransaction]
|
public var pendingTransactions: [PendingWalletTransaction]
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct WalletStateRecord: Equatable {
|
public struct WalletStateRecord: Codable, Equatable {
|
||||||
public let info: WalletInfo
|
public let info: WalletInfo
|
||||||
public var exportCompleted: Bool
|
public var exportCompleted: Bool
|
||||||
public var state: CombinedWalletState?
|
public var state: CombinedWalletState?
|
||||||
|
@ -11,7 +11,7 @@ apple_resource(
|
|||||||
apple_asset_catalog(
|
apple_asset_catalog(
|
||||||
name = 'WalletUIAssets',
|
name = 'WalletUIAssets',
|
||||||
dirs = [
|
dirs = [
|
||||||
"Images.xcassets",
|
"WalletImages.xcassets",
|
||||||
],
|
],
|
||||||
visibility = ["PUBLIC"],
|
visibility = ["PUBLIC"],
|
||||||
)
|
)
|
||||||
|
@ -201,6 +201,7 @@ private final class WalletInfoHeaderNode: ASDisplayNode {
|
|||||||
private let refreshNode: WalletRefreshNode
|
private let refreshNode: WalletRefreshNode
|
||||||
private let balanceSubtitleNode: ImmediateTextNode
|
private let balanceSubtitleNode: ImmediateTextNode
|
||||||
private let receiveButtonNode: SolidRoundedButtonNode
|
private let receiveButtonNode: SolidRoundedButtonNode
|
||||||
|
private let receiveGramsButtonNode: SolidRoundedButtonNode
|
||||||
private let sendButtonNode: SolidRoundedButtonNode
|
private let sendButtonNode: SolidRoundedButtonNode
|
||||||
private let headerBackgroundNode: ASDisplayNode
|
private let headerBackgroundNode: ASDisplayNode
|
||||||
private let headerCornerNode: ASImageNode
|
private let headerCornerNode: ASImageNode
|
||||||
@ -229,6 +230,7 @@ private final class WalletInfoHeaderNode: ASDisplayNode {
|
|||||||
})?.stretchableImage(withLeftCapWidth: 10, topCapHeight: 1)
|
})?.stretchableImage(withLeftCapWidth: 10, topCapHeight: 1)
|
||||||
|
|
||||||
self.receiveButtonNode = SolidRoundedButtonNode(title: presentationData.strings.Wallet_Info_Receive, icon: UIImage(bundleImageName: "Wallet/ReceiveButtonIcon"), theme: SolidRoundedButtonTheme(backgroundColor: .white, foregroundColor: .black), height: 50.0, cornerRadius: 10.0, gloss: false)
|
self.receiveButtonNode = SolidRoundedButtonNode(title: presentationData.strings.Wallet_Info_Receive, icon: UIImage(bundleImageName: "Wallet/ReceiveButtonIcon"), theme: SolidRoundedButtonTheme(backgroundColor: .white, foregroundColor: .black), height: 50.0, cornerRadius: 10.0, gloss: false)
|
||||||
|
self.receiveGramsButtonNode = SolidRoundedButtonNode(title: presentationData.strings.Wallet_Info_ReceiveGrams, icon: UIImage(bundleImageName: "Wallet/ReceiveButtonIcon"), theme: SolidRoundedButtonTheme(backgroundColor: .white, foregroundColor: .black), height: 50.0, cornerRadius: 10.0, gloss: false)
|
||||||
self.sendButtonNode = SolidRoundedButtonNode(title: presentationData.strings.Wallet_Info_Send, icon: UIImage(bundleImageName: "Wallet/SendButtonIcon"), theme: SolidRoundedButtonTheme(backgroundColor: .white, foregroundColor: .black), height: 50.0, cornerRadius: 10.0, gloss: false)
|
self.sendButtonNode = SolidRoundedButtonNode(title: presentationData.strings.Wallet_Info_Send, icon: UIImage(bundleImageName: "Wallet/SendButtonIcon"), theme: SolidRoundedButtonTheme(backgroundColor: .white, foregroundColor: .black), height: 50.0, cornerRadius: 10.0, gloss: false)
|
||||||
|
|
||||||
self.refreshNode = WalletRefreshNode(strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat)
|
self.refreshNode = WalletRefreshNode(strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat)
|
||||||
@ -239,6 +241,7 @@ private final class WalletInfoHeaderNode: ASDisplayNode {
|
|||||||
self.addSubnode(self.headerCornerNode)
|
self.addSubnode(self.headerCornerNode)
|
||||||
if hasActions {
|
if hasActions {
|
||||||
self.addSubnode(self.receiveButtonNode)
|
self.addSubnode(self.receiveButtonNode)
|
||||||
|
self.addSubnode(self.receiveGramsButtonNode)
|
||||||
self.addSubnode(self.sendButtonNode)
|
self.addSubnode(self.sendButtonNode)
|
||||||
}
|
}
|
||||||
self.addSubnode(self.balanceNode)
|
self.addSubnode(self.balanceNode)
|
||||||
@ -248,6 +251,9 @@ private final class WalletInfoHeaderNode: ASDisplayNode {
|
|||||||
self.receiveButtonNode.pressed = {
|
self.receiveButtonNode.pressed = {
|
||||||
receiveAction()
|
receiveAction()
|
||||||
}
|
}
|
||||||
|
self.receiveGramsButtonNode.pressed = {
|
||||||
|
receiveAction()
|
||||||
|
}
|
||||||
self.sendButtonNode.pressed = {
|
self.sendButtonNode.pressed = {
|
||||||
sendAction()
|
sendAction()
|
||||||
}
|
}
|
||||||
@ -332,18 +338,18 @@ private final class WalletInfoHeaderNode: ASDisplayNode {
|
|||||||
let sendButtonFrame = CGRect(origin: CGPoint(x: leftButtonFrame.maxX + sideInset, y: leftButtonFrame.minY), size: CGSize(width: size.width - leftButtonFrame.maxX - sideInset * 2.0, height: buttonHeight))
|
let sendButtonFrame = CGRect(origin: CGPoint(x: leftButtonFrame.maxX + sideInset, y: leftButtonFrame.minY), size: CGSize(width: size.width - leftButtonFrame.maxX - sideInset * 2.0, height: buttonHeight))
|
||||||
let fullButtonFrame = CGRect(origin: CGPoint(x: sideInset, y: buttonOffset - sideInset - buttonHeight), size: CGSize(width: size.width - sideInset * 2.0, height: buttonHeight))
|
let fullButtonFrame = CGRect(origin: CGPoint(x: sideInset, y: buttonOffset - sideInset - buttonHeight), size: CGSize(width: size.width - sideInset * 2.0, height: buttonHeight))
|
||||||
|
|
||||||
var receiveButtonFrame: CGRect
|
|
||||||
if let balance = self.balance, balance > 0 {
|
if let balance = self.balance, balance > 0 {
|
||||||
receiveButtonFrame = leftButtonFrame
|
self.receiveGramsButtonNode.isHidden = true
|
||||||
self.receiveButtonNode.isHidden = false
|
self.receiveButtonNode.isHidden = false
|
||||||
self.sendButtonNode.isHidden = false
|
self.sendButtonNode.isHidden = false
|
||||||
} else {
|
} else {
|
||||||
receiveButtonFrame = fullButtonFrame
|
|
||||||
if self.balance == nil {
|
if self.balance == nil {
|
||||||
|
self.receiveGramsButtonNode.isHidden = true
|
||||||
self.receiveButtonNode.isHidden = true
|
self.receiveButtonNode.isHidden = true
|
||||||
self.sendButtonNode.isHidden = true
|
self.sendButtonNode.isHidden = true
|
||||||
} else {
|
} else {
|
||||||
self.receiveButtonNode.isHidden = false
|
self.receiveGramsButtonNode.isHidden = false
|
||||||
|
self.receiveButtonNode.isHidden = true
|
||||||
self.sendButtonNode.isHidden = true
|
self.sendButtonNode.isHidden = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -357,9 +363,12 @@ private final class WalletInfoHeaderNode: ASDisplayNode {
|
|||||||
self.refreshNode.isHidden = false
|
self.refreshNode.isHidden = false
|
||||||
}
|
}
|
||||||
|
|
||||||
transition.updateFrame(node: self.receiveButtonNode, frame: receiveButtonFrame)
|
transition.updateFrame(node: self.receiveGramsButtonNode, frame: fullButtonFrame)
|
||||||
|
transition.updateAlpha(node: self.receiveGramsButtonNode, alpha: buttonAlpha)
|
||||||
|
transition.updateFrame(node: self.receiveButtonNode, frame: leftButtonFrame)
|
||||||
transition.updateAlpha(node: self.receiveButtonNode, alpha: buttonAlpha)
|
transition.updateAlpha(node: self.receiveButtonNode, alpha: buttonAlpha)
|
||||||
self.receiveButtonNode.updateLayout(width: receiveButtonFrame.width, transition: transition)
|
self.receiveGramsButtonNode.updateLayout(width: fullButtonFrame.width, transition: transition)
|
||||||
|
self.receiveButtonNode.updateLayout(width: leftButtonFrame.width, transition: transition)
|
||||||
transition.updateFrame(node: self.sendButtonNode, frame: sendButtonFrame)
|
transition.updateFrame(node: self.sendButtonNode, frame: sendButtonFrame)
|
||||||
transition.updateAlpha(node: self.sendButtonNode, alpha: buttonAlpha)
|
transition.updateAlpha(node: self.sendButtonNode, alpha: buttonAlpha)
|
||||||
self.sendButtonNode.updateLayout(width: sendButtonFrame.width, transition: transition)
|
self.sendButtonNode.updateLayout(width: sendButtonFrame.width, transition: transition)
|
||||||
@ -372,12 +381,16 @@ private final class WalletInfoHeaderNode: ASDisplayNode {
|
|||||||
if let result = self.receiveButtonNode.hitTest(self.view.convert(point, to: self.receiveButtonNode.view), with: event) {
|
if let result = self.receiveButtonNode.hitTest(self.view.convert(point, to: self.receiveButtonNode.view), with: event) {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
if let result = self.receiveGramsButtonNode.hitTest(self.view.convert(point, to: self.receiveGramsButtonNode.view), with: event) {
|
||||||
|
return result
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func becameReady(animated: Bool) {
|
func becameReady(animated: Bool) {
|
||||||
if animated {
|
if animated {
|
||||||
self.sendButtonNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
self.sendButtonNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||||
|
self.receiveGramsButtonNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||||
self.receiveButtonNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
self.receiveButtonNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||||
self.balanceNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
self.balanceNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||||
self.balanceSubtitleNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
self.balanceSubtitleNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||||
|
@ -242,7 +242,7 @@ func cornersImage(_ theme: WalletTheme, top: Bool, bottom: Bool) -> UIImage? {
|
|||||||
|
|
||||||
func itemListClearInputIcon(_ theme: WalletTheme) -> UIImage? {
|
func itemListClearInputIcon(_ theme: WalletTheme) -> UIImage? {
|
||||||
return theme.image(WalletThemeResourceKey.itemListClearInputIcon.rawValue, { theme in
|
return theme.image(WalletThemeResourceKey.itemListClearInputIcon.rawValue, { theme in
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: "Components/Search Bar/Clear"), color: theme.list.inputClearButtonColor)
|
return generateTintedImage(image: UIImage(bundleImageName: "Wallet/ClearInput"), color: theme.list.inputClearButtonColor)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ public final class WalletSplashScreen: ViewController {
|
|||||||
self.walletCreatedPreloadState = nil
|
self.walletCreatedPreloadState = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
super.init(navigationBarPresentationData: NavigationBarPresentationData(theme: navigationBarTheme, strings: NavigationBarStrings(back: self.presentationData.strings.Wallet_Navigation_Back, close: self.presentationData.strings.Wallet_Navigation_Close)))
|
super.init(navigationBarPresentationData: NavigationBarPresentationData(theme: navigationBarTheme, strings: NavigationBarStrings(back: self.presentationData.strings.Wallet_Intro_NotNow, close: self.presentationData.strings.Wallet_Navigation_Close)))
|
||||||
|
|
||||||
self.statusBar.statusBarStyle = self.presentationData.theme.statusBarStyle
|
self.statusBar.statusBarStyle = self.presentationData.theme.statusBarStyle
|
||||||
self.navigationPresentation = .modalInLargeLayout
|
self.navigationPresentation = .modalInLargeLayout
|
||||||
@ -79,9 +79,7 @@ public final class WalletSplashScreen: ViewController {
|
|||||||
self.navigationBar?.intrinsicCanTransitionInline = false
|
self.navigationBar?.intrinsicCanTransitionInline = false
|
||||||
|
|
||||||
switch self.mode {
|
switch self.mode {
|
||||||
case .intro:
|
case let .intro: self.navigationItem.setRightBarButton(UIBarButtonItem(title: self.presentationData.strings.Wallet_Intro_ImportExisting, style: .plain, target: self, action: #selector(self.importPressed)), animated: false)
|
||||||
self.navigationItem.setLeftBarButton(UIBarButtonItem(title: self.presentationData.strings.Wallet_Intro_NotNow, style: .plain, target: self, action: #selector(self.backPressed)), animated: false)
|
|
||||||
self.navigationItem.setRightBarButton(UIBarButtonItem(title: self.presentationData.strings.Wallet_Intro_ImportExisting, style: .plain, target: self, action: #selector(self.importPressed)), animated: false)
|
|
||||||
case let .sending(walletInfo, address, amount, textMessage, randomId, serverSalt):
|
case let .sending(walletInfo, address, amount, textMessage, randomId, serverSalt):
|
||||||
self.navigationItem.setLeftBarButton(UIBarButtonItem(customDisplayNode: ASDisplayNode())!, animated: false)
|
self.navigationItem.setLeftBarButton(UIBarButtonItem(customDisplayNode: ASDisplayNode())!, animated: false)
|
||||||
let _ = (self.context.keychain.decrypt(walletInfo.encryptedSecret)
|
let _ = (self.context.keychain.decrypt(walletInfo.encryptedSecret)
|
||||||
|
@ -414,12 +414,13 @@ public final class WalletStrings: Equatable {
|
|||||||
public var Wallet_Info_RefreshErrorText: String { return self._s[188]! }
|
public var Wallet_Info_RefreshErrorText: String { return self._s[188]! }
|
||||||
public var Wallet_SecureStorageReset_Title: String { return self._s[189]! }
|
public var Wallet_SecureStorageReset_Title: String { return self._s[189]! }
|
||||||
public var Wallet_Receive_CommentHeader: String { return self._s[190]! }
|
public var Wallet_Receive_CommentHeader: String { return self._s[190]! }
|
||||||
public func Wallet_Updated_MinutesAgo(_ value: Int32) -> String {
|
public var Wallet_Info_ReceiveGrams: String { return self._s[191]! }
|
||||||
|
public func Wallet_Updated_HoursAgo(_ value: Int32) -> String {
|
||||||
let form = getPluralizationForm(self.lc, value)
|
let form = getPluralizationForm(self.lc, value)
|
||||||
let stringValue = walletStringsFormattedNumber(value, self.groupingSeparator)
|
let stringValue = walletStringsFormattedNumber(value, self.groupingSeparator)
|
||||||
return String(format: self._ps[0 * 6 + Int(form.rawValue)]!, stringValue)
|
return String(format: self._ps[0 * 6 + Int(form.rawValue)]!, stringValue)
|
||||||
}
|
}
|
||||||
public func Wallet_Updated_HoursAgo(_ value: Int32) -> String {
|
public func Wallet_Updated_MinutesAgo(_ value: Int32) -> String {
|
||||||
let form = getPluralizationForm(self.lc, value)
|
let form = getPluralizationForm(self.lc, value)
|
||||||
let stringValue = walletStringsFormattedNumber(value, self.groupingSeparator)
|
let stringValue = walletStringsFormattedNumber(value, self.groupingSeparator)
|
||||||
return String(format: self._ps[1 * 6 + Int(form.rawValue)]!, stringValue)
|
return String(format: self._ps[1 * 6 + Int(form.rawValue)]!, stringValue)
|
||||||
|
@ -2248,7 +2248,7 @@ public final class WalletWordCheckScreen: ViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func generateClearIcon(color: UIColor) -> UIImage? {
|
private func generateClearIcon(color: UIColor) -> UIImage? {
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: "Components/Search Bar/Clear"), color: color)
|
return generateTintedImage(image: UIImage(bundleImageName: "Wallet/ClearInput"), color: color)
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class WordCheckInputNode: ASDisplayNode, UITextFieldDelegate {
|
private final class WordCheckInputNode: ASDisplayNode, UITextFieldDelegate {
|
||||||
|
@ -77,9 +77,9 @@ public final class WalletWordDisplayScreen: ViewController {
|
|||||||
let deltaTime = Date().timeIntervalSince1970 - strongSelf.startTime
|
let deltaTime = Date().timeIntervalSince1970 - strongSelf.startTime
|
||||||
let minimalTimeout: Double
|
let minimalTimeout: Double
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
minimalTimeout = 60.0
|
minimalTimeout = 5.0
|
||||||
#else
|
#else
|
||||||
minimalTimeout = 60.0
|
minimalTimeout = 30.0
|
||||||
#endif
|
#endif
|
||||||
if deltaTime < minimalTimeout {
|
if deltaTime < minimalTimeout {
|
||||||
strongSelf.present(standardTextAlertController(theme: strongSelf.presentationData.theme.alert, title: strongSelf.presentationData.strings.Wallet_Words_NotDoneTitle, text: strongSelf.presentationData.strings.Wallet_Words_NotDoneText, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Wallet_Words_NotDoneOk, action: {
|
strongSelf.present(standardTextAlertController(theme: strongSelf.presentationData.theme.alert, title: strongSelf.presentationData.strings.Wallet_Words_NotDoneTitle, text: strongSelf.presentationData.strings.Wallet_Words_NotDoneText, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Wallet_Words_NotDoneOk, action: {
|
||||||
|
BIN
submodules/WalletUI/WalletImages.xcassets/Wallet/ClearInput.imageset/Clear.pdf
vendored
Normal file
12
submodules/WalletUI/WalletImages.xcassets/Wallet/ClearInput.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "Clear.pdf"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
12
submodules/WalletUI/WalletImages.xcassets/Wallet/NavigationShareIcon.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "ic_share.pdf"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
BIN
submodules/WalletUI/WalletImages.xcassets/Wallet/NavigationShareIcon.imageset/ic_share.pdf
vendored
Normal file
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |