diff --git a/src/app/boot/app_controller.nim b/src/app/boot/app_controller.nim
index 6c412e83559..dc0c954d89c 100644
--- a/src/app/boot/app_controller.nim
+++ b/src/app/boot/app_controller.nim
@@ -215,7 +215,8 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
result.communityService = community_service.newService(statusFoundation.events,
statusFoundation.threadpool, result.chatService, result.activityCenterService, result.messageService)
result.rampService = ramp_service.newService(statusFoundation.events, statusFoundation.threadpool)
- result.transactionService = transaction_service.newService(statusFoundation.events, statusFoundation.threadpool, result.networkService, result.settingsService, result.tokenService)
+ result.transactionService = transaction_service.newService(statusFoundation.events, statusFoundation.threadpool,
+ result.currencyService, result.networkService, result.settingsService, result.tokenService)
result.profileService = profile_service.newService(statusFoundation.events, statusFoundation.threadpool, result.settingsService)
result.stickersService = stickers_service.newService(
statusFoundation.events,
@@ -244,7 +245,7 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
result.settingsService, result.walletAccountService, result.transactionService,
result.networkService, result.tokenService)
result.tokensService = tokens_service.newService(statusFoundation.events, statusFoundation.threadpool,
- result.transactionService, result.tokenService, result.settingsService, result.walletAccountService,
+ result.networkService, result.transactionService, result.tokenService, result.settingsService, result.walletAccountService,
result.activityCenterService, result.communityService, result.currencyService)
result.providerService = provider_service.newService(statusFoundation.events, statusFoundation.threadpool, result.ensService)
result.networkConnectionService = network_connection_service.newService(statusFoundation.events,
diff --git a/src/app/core/signals/remote_signals/community.nim b/src/app/core/signals/remote_signals/community.nim
index 043756ac38c..233c283c69c 100644
--- a/src/app/core/signals/remote_signals/community.nim
+++ b/src/app/core/signals/remote_signals/community.nim
@@ -79,7 +79,7 @@ type DiscordChannelImportFinishedSignal* = ref object of Signal
channelId*: string
type CommunityTokenTransactionStatusChangedSignal* = ref object of Signal
- transactionType*: string
+ sendType*: int
success*: bool
hash*: string
communityToken*: CommunityTokenDto
@@ -276,7 +276,7 @@ proc downloadingHistoryArchivesFinishedFromEvent*(T: type HistoryArchivesSignal,
proc fromEvent*(T: type CommunityTokenTransactionStatusChangedSignal, event: JsonNode): CommunityTokenTransactionStatusChangedSignal =
result = CommunityTokenTransactionStatusChangedSignal()
result.signalType = SignalType.CommunityTokenTransactionStatusChanged
- result.transactionType = event["event"]{"transactionType"}.getStr()
+ result.sendType = event["event"]{"sendType"}.getInt()
result.success = event["event"]{"success"}.getBool()
result.hash = event["event"]{"hash"}.getStr()
if event["event"].hasKey("communityToken"):
diff --git a/src/app/global/utils.nim b/src/app/global/utils.nim
index 7a2dc79cb6b..b74323d234f 100644
--- a/src/app/global/utils.nim
+++ b/src/app/global/utils.nim
@@ -47,6 +47,9 @@ QtObject:
weiValue = fromHex(Stuint[256], weiValue).toString()
return conversion.wei2Eth(weiValue, decimals)
+ proc hexToDec*(self: Utils, hexValue: string): string {.slot.} =
+ return fromHex(Stuint[256], hexValue).toString()
+
proc hex2Ascii*(self: Utils, value: string): string {.slot.} =
result = string.fromBytes(hexToSeqByte(value))
diff --git a/src/app/modules/main/communities/module.nim b/src/app/modules/main/communities/module.nim
index 8dbe101446d..7bee6fcff85 100644
--- a/src/app/modules/main/communities/module.nim
+++ b/src/app/modules/main/communities/module.nim
@@ -128,7 +128,8 @@ proc newModule*(
walletAccountService,
keycardService,
)
- result.communityTokensModule = community_tokens_module.newCommunityTokensModule(result, events, communityTokensService, transactionService, networksService, communityService)
+ result.communityTokensModule = community_tokens_module.newCommunityTokensModule(result, events, walletAccountService,
+ communityTokensService, transactionService, networksService, communityService, keycardService)
result.moduleLoaded = false
result.events = events
result.curatedCommunitiesLoaded = false
@@ -955,7 +956,7 @@ proc applyPermissionResponse*(self: Module, communityId: string, permissions: Ta
if not aCriteriaChanged:
continue
-
+
let updatedTokenPermissionItem = initTokenPermissionItem(
tokenPermissionItem.id,
tokenPermissionItem.`type`,
diff --git a/src/app/modules/main/communities/tokens/controller.nim b/src/app/modules/main/communities/tokens/controller.nim
index 1d66af99e14..73c511dcc0f 100644
--- a/src/app/modules/main/communities/tokens/controller.nim
+++ b/src/app/modules/main/communities/tokens/controller.nim
@@ -1,43 +1,50 @@
-import stint
+import uuids, chronicles
import ./io_interface as community_tokens_module_interface
import app_service/service/community_tokens/service as community_tokens_service
+import app_service/service/wallet_account/service as wallet_account_service
import app_service/service/transaction/service as transaction_service
import app_service/service/network/service as networks_service
import app_service/service/community/service as community_service
+import app_service/service/keycard/service as keycard_service
import app_service/service/network/network_item
-import app_service/common/types
import app/core/signals/types
import app/core/eventemitter
-import ../../../shared_modules/keycard_popup/io_interface as keycard_shared_module
+import app/modules/shared_modules/keycard_popup/io_interface as keycard_shared_module
-
-const UNIQUE_DEPLOY_COLLECTIBLES_COMMUNITY_TOKENS_MODULE_IDENTIFIER* = "communityTokensModule-DeployCollectibles"
+const UNIQUE_COMMUNITY_TOKENS_MODULE_IDENTIFIER* = "communityTokensModuleIdentifier"
type
Controller* = ref object of RootObj
- communityTokensModule: community_tokens_module_interface.AccessInterface
+ delegate: community_tokens_module_interface.AccessInterface
events: EventEmitter
+ walletAccountService: wallet_account_service.Service
communityTokensService: community_tokens_service.Service
transactionService: transaction_service.Service
networksService: networks_service.Service
communityService: community_service.Service
+ keycardService: keycard_service.Service
+ connectionKeycardResponse: UUID
proc newCommunityTokensController*(
- communityTokensModule: community_tokens_module_interface.AccessInterface,
+ delegate: community_tokens_module_interface.AccessInterface,
events: EventEmitter,
+ walletAccountService: wallet_account_service.Service,
communityTokensService: community_tokens_service.Service,
transactionService: transaction_service.Service,
networksService: networks_service.Service,
- communityService: community_service.Service
+ communityService: community_service.Service,
+ keycardService: keycard_service.Service
): Controller =
result = Controller()
- result.communityTokensModule = communityTokensModule
+ result.delegate = delegate
result.events = events
+ result.walletAccountService = walletAccountService
result.communityTokensService = communityTokensService
result.transactionService = transactionService
result.networksService = networksService
result.communityService = communityService
+ result.keycardService = keycardService
proc delete*(self: Controller) =
discard
@@ -45,75 +52,59 @@ proc delete*(self: Controller) =
proc init*(self: Controller) =
self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED) do(e: Args):
let args = SharedKeycarModuleArgs(e)
- if args.uniqueIdentifier != UNIQUE_DEPLOY_COLLECTIBLES_COMMUNITY_TOKENS_MODULE_IDENTIFIER:
+ if args.uniqueIdentifier != UNIQUE_COMMUNITY_TOKENS_MODULE_IDENTIFIER:
return
- self.communityTokensModule.onUserAuthenticated(args.password)
- self.events.on(SIGNAL_COMPUTE_DEPLOY_FEE) do(e:Args):
- let args = ComputeFeeArgs(e)
- self.communityTokensModule.onDeployFeeComputed(args.ethCurrency, args.fiatCurrency, args.errorCode, args.requestId)
- self.events.on(SIGNAL_COMPUTE_SELF_DESTRUCT_FEE) do(e:Args):
- let args = ComputeFeeArgs(e)
- self.communityTokensModule.onSelfDestructFeeComputed(args.ethCurrency, args.fiatCurrency, args.errorCode, args.requestId)
- self.events.on(SIGNAL_COMPUTE_BURN_FEE) do(e:Args):
- let args = ComputeFeeArgs(e)
- self.communityTokensModule.onBurnFeeComputed(args.ethCurrency, args.fiatCurrency, args.errorCode, args.requestId)
- self.events.on(SIGNAL_COMPUTE_SET_SIGNER_FEE) do(e:Args):
- let args = ComputeFeeArgs(e)
- self.communityTokensModule.onSetSignerFeeComputed(args.ethCurrency, args.fiatCurrency, args.errorCode, args.requestId)
- self.events.on(SIGNAL_COMPUTE_AIRDROP_FEE) do(e:Args):
- let args = AirdropFeesArgs(e)
- self.communityTokensModule.onAirdropFeesComputed(args)
- self.events.on(SIGNAL_COMMUNITY_TOKEN_DEPLOYMENT_STARTED) do(e: Args):
- let args = CommunityTokenDeploymentArgs(e)
- self.communityTokensModule.onCommunityTokenDeployStateChanged(args.communityToken.communityId, args.communityToken.chainId, args.transactionHash, args.communityToken.deployState)
- self.events.on(SIGNAL_COMMUNITY_TOKEN_DEPLOY_STATUS) do(e: Args):
- let args = CommunityTokenDeployedStatusArgs(e)
- self.communityTokensModule.onCommunityTokenDeployStateChanged(args.communityId, args.chainId, args.transactionHash, args.deployState)
- self.events.on(SIGNAL_OWNER_TOKEN_DEPLOYMENT_STARTED) do(e: Args):
- let args = OwnerTokenDeploymentArgs(e)
- self.communityTokensModule.onOwnerTokenDeployStarted(args.ownerToken.communityId, args.ownerToken.chainId, args.transactionHash)
- self.events.on(SIGNAL_OWNER_TOKEN_DEPLOY_STATUS) do(e: Args):
- let args = OwnerTokenDeployedStatusArgs(e)
- self.communityTokensModule.onOwnerTokenDeployStateChanged(args.communityId, args.chainId, args.transactionHash, args.deployState)
- self.events.on(SIGNAL_REMOTE_DESTRUCT_STATUS) do(e: Args):
- let args = RemoteDestructArgs(e)
- self.communityTokensModule.onRemoteDestructStateChanged(args.communityToken.communityId, args.communityToken.name, args.communityToken.chainId, args.transactionHash, args.status)
- self.events.on(SIGNAL_BURN_STATUS) do(e: Args):
- let args = RemoteDestructArgs(e)
- self.communityTokensModule.onBurnStateChanged(args.communityToken.communityId, args.communityToken.name, args.communityToken.chainId, args.transactionHash, args.status)
- self.events.on(SIGNAL_AIRDROP_STATUS) do(e: Args):
- let args = AirdropArgs(e)
- self.communityTokensModule.onAirdropStateChanged(args.communityToken.communityId, args.communityToken.name, args.communityToken.chainId, args.transactionHash, args.status)
+ self.delegate.onUserAuthenticated(args.password, args.pin)
self.events.on(SIGNAL_OWNER_TOKEN_RECEIVED) do(e: Args):
let args = OwnerTokenReceivedArgs(e)
- self.communityTokensModule.onOwnerTokenReceived(args.communityId, args.communityName, args.chainId, args.contractAddress)
+ self.delegate.onOwnerTokenReceived(args.communityId, args.communityName, args.chainId, args.contractAddress)
self.events.on(SIGNAL_COMMUNITY_TOKEN_RECEIVED) do(e: Args):
let args = CommunityTokenReceivedArgs(e)
if args.isWatchOnlyAccount:
return
- self.communityTokensModule.onCommunityTokenReceived(args.name, args.symbol, args.image, args.communityId, args.communityName, $args.amount, args.chainId, args.txHash, args.isFirst, args.tokenType, args.accountName, args.accountAddress)
- self.events.on(SIGNAL_SET_SIGNER_STATUS) do(e: Args):
- let args = SetSignerArgs(e)
- self.communityTokensModule.onSetSignerStateChanged(args.communityId, args.chainId, args.transactionHash, args.status)
+ self.delegate.onCommunityTokenReceived(args.name, args.symbol, args.image, args.communityId, args.communityName, $args.amount, args.chainId, args.txHash, args.isFirst, args.tokenType, args.accountName, args.accountAddress)
self.events.on(SIGNAL_COMMUNITY_LOST_OWNERSHIP) do(e: Args):
let args = CommunityIdArgs(e)
- self.communityTokensModule.onLostOwnership(args.communityId)
+ self.delegate.onLostOwnership(args.communityId)
self.events.on(SIGNAL_OWNER_TOKEN_OWNER_ADDRESS) do(e: Args):
let args = OwnerTokenOwnerAddressArgs(e)
- self.communityTokensModule.onOwnerTokenOwnerAddress(args.chainId, args.contractAddress, args.address, args.addressName)
- self.events.on(SIGNAL_OWNER_TOKEN_SENT) do(e: Args):
- let args = OwnerTokenSentArgs(e)
- self.communityTokensModule.onSendOwnerTokenStateChanged(args.chainId, args.txHash, args.tokenName, args.status)
+ self.delegate.onOwnerTokenOwnerAddress(args.chainId, args.contractAddress, args.address, args.addressName)
self.events.on(SIGNAL_COMMUNITY_TOKENS_CHANGED) do(e:Args):
self.communityTokensService.getAllCommunityTokensAsync()
-
-proc deployContract*(self: Controller, communityId: string, addressFrom: string, password: string, deploymentParams: DeploymentParameters, chainId: int) =
- self.communityTokensService.deployContract(communityId, addressFrom, password, deploymentParams, chainId)
-
-proc deployOwnerContracts*(self: Controller, communityId: string, addressFrom: string, password: string,
- ownerDeploymentParams: DeploymentParameters, masterDeploymentParams: DeploymentParameters, chainId: int) =
- self.communityTokensService.deployOwnerContracts(communityId, addressFrom, password, ownerDeploymentParams,
- masterDeploymentParams, chainId)
+ self.events.on(SIGNAL_SUGGESTED_ROUTES_READY) do(e:Args):
+ let args = SuggestedRoutesArgs(e)
+ self.delegate.suggestedRoutesReady(args.uuid, args.sendType, args.totalCostEthCurrency, args.totalCostFiatCurrency,
+ args.costPerPath, args.errCode, args.errDescription)
+ self.events.on(SIGNAL_SIGN_ROUTER_TRANSACTIONS) do(e:Args):
+ let args = RouterTransactionsForSigningArgs(e)
+ self.delegate.prepareSignaturesForTransactions(args.data)
+ self.events.on(SIGNAL_TRANSACTION_SENT) do(e:Args):
+ let args = TransactionArgs(e)
+ var
+ txHash = ""
+ isApprovalTx = false
+ toAddress = ""
+ if not args.sentTransaction.isNil:
+ txHash = args.sentTransaction.hash
+ isApprovalTx = args.sentTransaction.approvalTx
+ toAddress = args.sentTransaction.toAddress
+ self.delegate.onTransactionSent(
+ args.sendDetails.uuid,
+ SendType(args.sendDetails.sendType),
+ args.sendDetails.fromChain,
+ isApprovalTx,
+ txHash,
+ toAddress,
+ if not args.sendDetails.errorResponse.isNil: args.sendDetails.errorResponse.details else: ""
+ )
+
+proc storeDeployedContract*(self: Controller, sendType: SendType, addressFrom: string, addressTo: string, chainId: int,
+ txHash: string, deploymentParams: DeploymentParameters) =
+ self.communityTokensService.storeDeployedContract(sendType, addressFrom, addressTo, chainId, txHash, deploymentParams)
+
+proc storeDeployedOwnerContract*(self: Controller, addressFrom: string, chainId: int, txHash: string,
+ ownerDeploymentParams: DeploymentParameters, masterDeploymentParams: DeploymentParameters) =
+ self.communityTokensService.storeDeployedOwnerContract(addressFrom, chainId, txHash, ownerDeploymentParams, masterDeploymentParams)
proc removeCommunityToken*(self: Controller, communityId: string, chainId: int, address: string) =
self.communityTokensService.removeCommunityToken(communityId, chainId, address)
@@ -121,45 +112,35 @@ proc removeCommunityToken*(self: Controller, communityId: string, chainId: int,
proc refreshCommunityToken*(self: Controller, chainId: int, address: string) =
self.communityTokensService.refreshCommunityToken(chainId, address)
-proc airdropTokens*(self: Controller, communityId: string, password: string, tokensAndAmounts: seq[CommunityTokenAndAmount], walletAddresses: seq[string], addressFrom: string) =
- self.communityTokensService.airdropTokens(communityId, password, tokensAndAmounts, walletAddresses, addressFrom)
-
-proc computeAirdropFee*(self: Controller, tokensAndAmounts: seq[CommunityTokenAndAmount], walletAddresses: seq[string], addressFrom: string, requestId: string) =
- self.communityTokensService.computeAirdropFee(tokensAndAmounts, walletAddresses, addressFrom, requestId)
+proc computeAirdropFee*(self: Controller, uuid: string, tokensAndAmounts: seq[CommunityTokenAndAmount], walletAddresses: seq[string], addressFrom: string) =
+ self.communityTokensService.computeAirdropFee(uuid, tokensAndAmounts, walletAddresses, addressFrom)
-proc selfDestructCollectibles*(self: Controller, communityId: string, password: string, walletAndAmounts: seq[WalletAndAmount], contractUniqueKey: string, addressFrom: string) =
- self.communityTokensService.selfDestructCollectibles(communityId, password, walletAndAmounts, contractUniqueKey, addressFrom)
-
-proc burnTokens*(self: Controller, communityId: string, password: string, contractUniqueKey: string, amount: Uint256, addressFrom: string) =
- self.communityTokensService.burnTokens(communityId, password, contractUniqueKey, amount, addressFrom)
-
-proc setSigner*(self: Controller, password: string, communityId: string, chainId: int, contractAddress: string, addressFrom: string) =
- self.communityTokensService.setSigner(password, communityId, chainId, contractAddress, addressFrom)
-
-proc authenticateUser*(self: Controller, keyUid = "") =
- let data = SharedKeycarModuleAuthenticationArgs(uniqueIdentifier: UNIQUE_DEPLOY_COLLECTIBLES_COMMUNITY_TOKENS_MODULE_IDENTIFIER, keyUid: keyUid)
+proc authenticate*(self: Controller, keyUid = "") =
+ let data = SharedKeycarModuleAuthenticationArgs(uniqueIdentifier: UNIQUE_COMMUNITY_TOKENS_MODULE_IDENTIFIER,
+ keyUid: keyUid)
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER, data)
proc getCommunityTokens*(self: Controller, communityId: string): seq[CommunityTokenDto] =
return self.communityTokensService.getCommunityTokens(communityId)
-proc computeDeployFee*(self: Controller, chainId: int, accountAddress: string, tokenType: TokenType, requestId: string) =
- self.communityTokensService.computeDeployFee(chainId, accountAddress, tokenType, requestId)
+proc computeDeployTokenFee*(self: Controller, uuid: string, chainId: int, accountAddress: string, communityId: string, deploymentParams: DeploymentParameters) =
+ self.communityTokensService.computeDeployTokenFee(uuid, chainId, accountAddress, communityId, deploymentParams)
-proc computeSetSignerFee*(self: Controller, chainId: int, contractAddress: string, addressFrom: string, requestId: string) =
- self.communityTokensService.computeSetSignerFee(chainId, contractAddress, addressFrom, requestId)
+proc computeSetSignerFee*(self: Controller, uuid: string, communityId: string, chainId: int, contractAddress: string, addressFrom: string) =
+ self.communityTokensService.computeSetSignerFee(uuid, communityId, chainId, contractAddress, addressFrom)
-proc computeDeployOwnerContractsFee*(self: Controller, chainId: int, accountAddress: string, communityId: string, ownerDeploymentParams: DeploymentParameters, masterDeploymentParams: DeploymentParameters, requestId: string) =
- self.communityTokensService.computeDeployOwnerContractsFee(chainId, accountAddress, communityId, ownerDeploymentParams, masterDeploymentParams, requestId)
+proc computeDeployOwnerContractsFee*(self: Controller, uuid: string, chainId: int, accountAddress: string, communityId: string,
+ownerDeploymentParams: DeploymentParameters, masterDeploymentParams: DeploymentParameters) =
+ self.communityTokensService.computeDeployOwnerContractsFee(uuid, chainId, accountAddress, communityId, ownerDeploymentParams, masterDeploymentParams)
-proc computeSelfDestructFee*(self: Controller, walletAndAmountList: seq[WalletAndAmount], contractUniqueKey: string, addressFrom: string, requestId: string) =
- self.communityTokensService.computeSelfDestructFee(walletAndAmountList, contractUniqueKey, addressFrom, requestId)
+proc computeSelfDestructFee*(self: Controller, uuid: string, walletAndAmountList: seq[WalletAndAmount], contractUniqueKey: string, addressFrom: string) =
+ self.communityTokensService.computeSelfDestructFee(uuid, walletAndAmountList, contractUniqueKey, addressFrom)
proc findContractByUniqueId*(self: Controller, contractUniqueKey: string): CommunityTokenDto =
return self.communityTokensService.findContractByUniqueId(contractUniqueKey)
-proc computeBurnFee*(self: Controller, contractUniqueKey: string, amount: Uint256, addressFrom: string, requestId: string) =
- self.communityTokensService.computeBurnFee(contractUniqueKey, amount, addressFrom, requestId)
+proc computeBurnFee*(self: Controller, uuid: string, contractUniqueKey: string, amount: string, addressFrom: string) =
+ self.communityTokensService.computeBurnFee(uuid, contractUniqueKey, amount, addressFrom)
proc getNetworkByChainId*(self:Controller, chainId: int): NetworkItem =
self.networksService.getNetworkByChainId(chainId)
@@ -178,3 +159,41 @@ proc declineOwnership*(self: Controller, communityId: string) =
proc asyncGetOwnerTokenOwnerAddress*(self: Controller, chainId: int, contractAddress: string) =
self.communityTokensService.asyncGetOwnerTokenOwnerAddress(chainId, contractAddress)
+
+proc stopSuggestedRoutesAsyncCalculation*(self: Controller) =
+ self.communityTokensService.stopSuggestedRoutesAsyncCalculation()
+
+proc getKeypairByAccountAddress*(self: Controller, address: string): KeypairDto =
+ return self.walletAccountService.getKeypairByAccountAddress(address)
+
+proc buildTransactionsFromRoute*(self: Controller, uuid: string): string =
+ return self.communityTokensService.buildTransactionsFromRoute(uuid)
+
+proc sendRouterTransactionsWithSignatures*(self: Controller, uuid: string, signatures: TransactionsSignatures): string =
+ return self.communityTokensService.sendRouterTransactionsWithSignatures(uuid, signatures)
+
+proc signMessage*(self: Controller, address: string, hashedPassword: string, hashedMessage: string): tuple[res: string, err: string] =
+ return self.communityTokensService.signMessage(address, hashedPassword, hashedMessage)
+
+proc disconnectKeycardReponseSignal(self: Controller) =
+ self.events.disconnect(self.connectionKeycardResponse)
+
+proc connectKeycardReponseSignal(self: Controller) =
+ self.connectionKeycardResponse = self.events.onWithUUID(SIGNAL_KEYCARD_RESPONSE) do(e: Args):
+ let args = KeycardLibArgs(e)
+ self.disconnectKeycardReponseSignal()
+ let currentFlow = self.keycardService.getCurrentFlow()
+ if currentFlow != KCSFlowType.Sign:
+ error "trying to use keycard in other than the signing a community related transaction flow"
+ #TODO: notifify about error
+ # self.delegate.transactionWasSent(uuid = "", chainId = 0, approvalTx = false, txHash = "", error = "trying to use keycard in the other than the signing a transaction flow")
+ return
+ self.delegate.onTransactionSigned(args.flowType, args.flowEvent)
+
+proc cancelCurrentFlow*(self: Controller) =
+ self.keycardService.cancelCurrentFlow()
+
+proc runSignFlow*(self: Controller, pin, bip44Path, txHash: string) =
+ self.cancelCurrentFlow()
+ self.connectKeycardReponseSignal()
+ self.keycardService.startSignFlow(bip44Path, txHash, pin)
\ No newline at end of file
diff --git a/src/app/modules/main/communities/tokens/io_interface.nim b/src/app/modules/main/communities/tokens/io_interface.nim
index 47926ca61a1..8d09c061d9a 100644
--- a/src/app/modules/main/communities/tokens/io_interface.nim
+++ b/src/app/modules/main/communities/tokens/io_interface.nim
@@ -1,7 +1,9 @@
-import ../../../../../app_service/service/community_tokens/service
-import ../../../../../app_service/service/community/dto/community
-import ../../../../../app_service/common/types
-import ../../../shared_models/currency_amount
+import app_service/service/transaction/dto
+import app_service/service/transaction/router_transactions_dto
+import app_service/service/community/dto/community
+import app_service/common/types
+import app/modules/shared_models/currency_amount
+from app_service/service/keycard/service import KeycardEvent
type
AccessInterface* {.pure inheritable.} = ref object of RootObj
@@ -12,110 +14,84 @@ method delete*(self: AccessInterface) {.base.} =
method load*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
-method airdropTokens*(self: AccessInterface, communityId: string, tokensJsonString: string, walletsJsonString: string, addressFrom: string) {.base.} =
+method computeAirdropFee*(self: AccessInterface, uuid: string, communityId: string, tokensJsonString: string,
+ walletsJsonString: string, addressFrom: string) {.base.} =
raise newException(ValueError, "No implementation available")
-method computeAirdropFee*(self: AccessInterface, communityId: string, tokensJsonString: string, walletsJsonString: string, addressFrom: string, requestId: string) {.base.} =
- raise newException(ValueError, "No implementation available")
-
-method selfDestructCollectibles*(self: AccessInterface, communityId: string, collectiblesToBurnJsonString: string, contractUniqueKey: string, addressFrom: string) {.base.} =
- raise newException(ValueError, "No implementation available")
+method computeDeployCollectiblesFee*(self: AccessInterface, uuid: string, communityId: string, fromAddress: string,
+ name: string, symbol: string, description: string, supply: string, infiniteSupply: bool, transferable: bool,
+ selfDestruct: bool, chainId: int, imageCropInfoJson: string) {.base.} =
+ raise newException(ValueError, "No implementation available")
-method burnTokens*(self: AccessInterface, communityId: string, contractUniqueKey: string, amount: string, addressFrom: string) {.base.} =
- raise newException(ValueError, "No implementation available")
+method computeDeployAssetsFee*(self: AccessInterface, uuid: string, communityId: string, address: string, name: string,
+ symbol: string, description: string, supply: string, infiniteSupply: bool, decimals: int, chainId: int,
+ imageCropInfoJson: string) {.base.} =
+ raise newException(ValueError, "No implementation available")
-method setSigner*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, addressFrom: string) {.base.} =
- raise newException(ValueError, "No implementation available")
+method computeDeployTokenOwnerFee*(self: AccessInterface, uuid: string, communityId: string, fromAddress: string,
+ ownerName: string, ownerSymbol: string, ownerDescription: string, masterName: string, masterSymbol: string,
+ masterDescription: string, chainId: int, imageCropInfoJson: string) {.base.} =
+ raise newException(ValueError, "No implementation available")
-method deployCollectibles*(self: AccessInterface, communityId: string, address: string, name: string, symbol: string, description: string, supply: string, infiniteSupply: bool, transferable: bool,
- selfDestruct: bool, chainId: int, imageCropInfoJson: string) {.base.} =
+method authenticateAndTransfer*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
-method deployAssets*(self: AccessInterface, communityId: string, address: string, name: string, symbol: string, description: string, supply: string, infiniteSupply: bool, decimals: int,
- chainId: int, imageCropInfoJson: string) {.base.} =
- raise newException(ValueError, "No implementation available")
-
-method deployOwnerToken*(self: AccessInterface, communityId: string, fromAddress: string, ownerName: string, ownerSymbol: string, ownerDescription: string,
- masterName: string, masterSymbol: string, masterDescription: string, chainId: int, imageCropInfoJson: string) {.base.} =
- raise newException(ValueError, "No implementation available")
-
-method onUserAuthenticated*(self: AccessInterface, password: string) {.base.} =
+method onUserAuthenticated*(self: AccessInterface, password: string, pin: string) {.base.} =
raise newException(ValueError, "No implementation available")
method resetTempValues*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
-method computeDeployFee*(self: AccessInterface, communityId: string, chainId: int, accountAddress: string, tokenType: TokenType, isOwnerDeployment: bool, requestId: string) {.base.} =
- raise newException(ValueError, "No implementation available")
-
-method computeSetSignerFee*(self: AccessInterface, chainId: int, contractAddress: string, addressFrom: string, requestId: string) {.base.} =
- raise newException(ValueError, "No implementation available")
-
-method computeSelfDestructFee*(self: AccessInterface, collectiblesToBurnJsonString: string, contractUniqueKey: string, addressFrom: string, requestId: string) {.base.} =
- raise newException(ValueError, "No implementation available")
-
-method computeBurnFee*(self: AccessInterface, contractUniqueKey: string, amount: string, addressFrom: string, requestId: string) {.base.} =
- raise newException(ValueError, "No implementation available")
-
-method onDeployFeeComputed*(self: AccessInterface, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: ComputeFeeErrorCode, responseId: string) {.base.} =
- raise newException(ValueError, "No implementation available")
-
-method onSelfDestructFeeComputed*(self: AccessInterface, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: ComputeFeeErrorCode, responseId: string) {.base.} =
- raise newException(ValueError, "No implementation available")
-
-method onAirdropFeesComputed*(self: AccessInterface, args: AirdropFeesArgs) {.base.} =
+method computeDeployFee*(self: AccessInterface, uuid: string, communityId: string, chainId: int, accountAddress: string,
+ tokenType: TokenType, isOwnerDeployment: bool) {.base.} =
raise newException(ValueError, "No implementation available")
-method onBurnFeeComputed*(self: AccessInterface, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: ComputeFeeErrorCode, responseId: string) {.base.} =
+method computeSetSignerFee*(self: AccessInterface, uuid: string, communityId: string, chainId: int, contractAddress: string, addressFrom: string) {.base.} =
raise newException(ValueError, "No implementation available")
-method onSetSignerFeeComputed*(self: AccessInterface, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: ComputeFeeErrorCode, responseId: string) {.base.} =
+method computeSelfDestructFee*(self: AccessInterface, uuid: string, collectiblesToBurnJsonString: string, contractUniqueKey: string, addressFrom: string) {.base.} =
raise newException(ValueError, "No implementation available")
-method onCommunityTokenDeployStateChanged*(self: AccessInterface, communityId: string, chainId: int, transactionHash: string, deployState: DeployState) {.base.} =
+method computeBurnFee*(self: AccessInterface, uuid: string, contractUniqueKey: string, amount: string, addressFrom: string) {.base.} =
raise newException(ValueError, "No implementation available")
-method onOwnerTokenDeployStateChanged*(self: AccessInterface, communityId: string, chainId: int, transactionHash: string, deployState: DeployState) {.base.} =
- raise newException(ValueError, "No implementation available")
-
-method onOwnerTokenDeployStarted*(self: AccessInterface, communityId: string, chainId: int, transactionHash: string) {.base.} =
- raise newException(ValueError, "No implementation available")
-
-method onRemoteDestructStateChanged*(self: AccessInterface, communityId: string, tokenName: string, chainId: int, transactionHash: string, status: ContractTransactionStatus) {.base.} =
+method removeCommunityToken*(self: AccessInterface, communityId: string, chainId: int, address: string) {.base.} =
raise newException(ValueError, "No implementation available")
-method onBurnStateChanged*(self: AccessInterface, communityId: string, tokenName: string, chainId: int, transactionHash: string, status: ContractTransactionStatus) {.base.} =
+method refreshCommunityToken*(self: AccessInterface, chainId: int, address: string) {.base.} =
raise newException(ValueError, "No implementation available")
-method onAirdropStateChanged*(self: AccessInterface, communityId: string, tokenName: string, chainId: int, transactionHash: string, status: ContractTransactionStatus) {.base.} =
+method onOwnerTokenReceived*(self: AccessInterface, communityId: string, communityName: string, chainId: int, contractAddress: string) {.base.} =
raise newException(ValueError, "No implementation available")
-method removeCommunityToken*(self: AccessInterface, communityId: string, chainId: int, address: string) {.base.} =
+method onCommunityTokenReceived*(self: AccessInterface, name: string, symbol: string, image: string, communityId: string, communityName: string, balance: string, chainId: int, txHash: string, isFirst: bool, tokenType: int, accountName: string, accountAddress: string) {.base.} =
raise newException(ValueError, "No implementation available")
-method refreshCommunityToken*(self: AccessInterface, chainId: int, address: string) {.base.} =
+method onLostOwnership*(self: AccessInterface, communityId: string) {.base.} =
raise newException(ValueError, "No implementation available")
-method onOwnerTokenReceived*(self: AccessInterface, communityId: string, communityName: string, chainId: int, contractAddress: string) {.base.} =
+method declineOwnership*(self: AccessInterface, communityId: string) {.base.} =
raise newException(ValueError, "No implementation available")
-method onCommunityTokenReceived*(self: AccessInterface, name: string, symbol: string, image: string, communityId: string, communityName: string, balance: string, chainId: int, txHash: string, isFirst: bool, tokenType: int, accountName: string, accountAddress: string) {.base.} =
+method onOwnerTokenOwnerAddress*(self: AccessInterface, chainId: int, contractAddress: string, address: string, addressName: string) {.base.} =
raise newException(ValueError, "No implementation available")
-method onSendOwnerTokenStateChanged*(self: AccessInterface, chainId: int, transactionHash: string, tokenName: string, status: ContractTransactionStatus) {.base.} =
+method asyncGetOwnerTokenDetails*(self: AccessInterface, communityId: string) {.base.} =
raise newException(ValueError, "No implementation available")
-method onSetSignerStateChanged*(self: AccessInterface, communityId: string, chainId: int, transactionHash: string, status: ContractTransactionStatus) {.base.} =
+method suggestedRoutesReady*(self: AccessInterface, uuid: string, sendType: SendType, ethCurrency: CurrencyAmount,
+ fiatCurrency: CurrencyAmount, costPerPath: seq[CostPerPath], errCode: string, errDescription: string) {.base.} =
raise newException(ValueError, "No implementation available")
-method onLostOwnership*(self: AccessInterface, communityId: string) {.base.} =
+method stopUpdatesForSuggestedRoute*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
-method declineOwnership*(self: AccessInterface, communityId: string) {.base.} =
+method prepareSignaturesForTransactions*(self:AccessInterface, txForSigning: RouterTransactionsForSigningDto) {.base.} =
raise newException(ValueError, "No implementation available")
-method onOwnerTokenOwnerAddress*(self: AccessInterface, chainId: int, contractAddress: string, address: string, addressName: string) {.base.} =
+method onTransactionSigned*(self: AccessInterface, keycardFlowType: string, keycardEvent: KeycardEvent) {.base.} =
raise newException(ValueError, "No implementation available")
-method asyncGetOwnerTokenDetails*(self: AccessInterface, communityId: string) {.base.} =
- raise newException(ValueError, "No implementation available")
+method onTransactionSent*(self: AccessInterface, uuid: string, sendType: SendType, chainId: int, approvalTx: bool,
+ txHash: string, toAddress: string, error: string) {.base.} =
+ raise newException(ValueError, "No implementation available")
\ No newline at end of file
diff --git a/src/app/modules/main/communities/tokens/module.nim b/src/app/modules/main/communities/tokens/module.nim
index aa23dc1cdf1..3c16441a288 100644
--- a/src/app/modules/main/communities/tokens/module.nim
+++ b/src/app/modules/main/communities/tokens/module.nim
@@ -1,14 +1,20 @@
-import NimQml, json, stint, strutils, chronicles, tables
-
-import ../../../../../app_service/service/community_tokens/service as community_tokens_service
-import ../../../../../app_service/service/transaction/service as transaction_service
-import ../../../../../app_service/service/network/service as networks_service
-import ../../../../../app_service/service/community/service as community_service
-import ../../../../../app_service/service/accounts/utils as utl
-import ../../../../../app_service/common/types
-import ../../../../core/eventemitter
-import ../../../../global/global_singleton
-import ../../../shared_models/currency_amount
+import NimQml
+import tables, json, sequtils, sugar, stint, strutils, chronicles
+
+import app_service/service/wallet_account/service as wallet_account_service
+import app_service/service/community_tokens/service as community_tokens_service
+import app_service/service/transaction/service as transaction_service
+import app_service/service/network/service as networks_service
+import app_service/service/community/service as community_service
+import app_service/service/accounts/utils as utl
+import app_service/service/keycard/service as keycard_service
+import app_service/service/keycard/constants as keycard_constants
+import app_service/common/types
+import app_service/common/utils
+import app_service/common/wallet_constants
+import app/core/eventemitter
+import app/global/global_singleton
+import app/modules/shared_models/currency_amount
import ../io_interface as parent_interface
import ./io_interface, ./view , ./controller
@@ -30,8 +36,12 @@ type
controller: Controller
view: View
viewVariant: QVariant
+ tempUuid: string
+ tempPin: string
+ tempPassword: string
tempTokenAndAmountList: seq[CommunityTokenAndAmount]
tempWalletAndAmountList: seq[WalletAndAmount]
+ tempAddressPath: string
tempAddressFrom: string
tempCommunityId: string
tempChainId: int
@@ -44,19 +54,28 @@ type
tempOwnerDeploymentParams: DeploymentParameters
tempMasterDeploymentParams: DeploymentParameters
tempOwnerTokenCommunity: CommunityDto
+ tempResolvedSignatures: TransactionsSignatures
+ tempTxHashBeingProcessed: string
proc newCommunityTokensModule*(
parent: parent_interface.AccessInterface,
events: EventEmitter,
+ walletAccountService: wallet_account_service.Service,
communityTokensService: community_tokens_service.Service,
transactionService: transaction_service.Service,
networksService: networks_service.Service,
- communityService: community_service.Service): Module =
+ communityService: community_service.Service,
+ keycardService: keycard_service.Service
+ ): Module =
result = Module()
result.parent = parent
result.view = newView(result)
result.viewVariant = newQVariant(result.view)
- result.controller = controller.newCommunityTokensController(result, events, communityTokensService, transactionService, networksService, communityService)
+ result.controller = controller.newCommunityTokensController(result, events, walletAccountService, communityTokensService,
+ transactionService, networksService, communityService, keycardService)
+
+## Forward declarations
+proc buildTransactionsFromRoute(self: Module)
method delete*(self: Module) =
self.view.delete
@@ -64,6 +83,10 @@ method delete*(self: Module) =
self.controller.delete
method resetTempValues(self:Module) =
+ self.tempUuid = ""
+ self.tempPin = ""
+ self.tempPassword = ""
+ self.tempAddressPath = ""
self.tempAddressFrom = ""
self.tempCommunityId = ""
self.tempDeploymentParams = DeploymentParameters()
@@ -76,18 +99,191 @@ method resetTempValues(self:Module) =
self.tempContractUniqueKey = ""
self.tempOwnerDeploymentParams = DeploymentParameters()
self.tempMasterDeploymentParams = DeploymentParameters()
+ self.tempOwnerTokenCommunity = CommunityDto()
+ self.tempResolvedSignatures.clear()
+ self.tempTxHashBeingProcessed = ""
method load*(self: Module) =
singletonInstance.engine.setRootContextProperty("communityTokensModule", self.viewVariant)
self.controller.init()
self.view.load()
-proc authenticate(self: Module) =
- if singletonInstance.userProfile.getIsKeycardUser():
- let keyUid = singletonInstance.userProfile.getKeyUid()
- self.controller.authenticateUser(keyUid)
+proc createOwnerAndMasterDeploymentParams(self: Module, communityId: string): (DeploymentParameters, DeploymentParameters) =
+ let communityDto = self.controller.getCommunityById(communityId)
+ let commName = communityDto.name
+ let commNameShort = try: commName[0 .. 2].toUpper except: commName.toUpper
+ return (
+ DeploymentParameters(
+ communityId: communityId,
+ name: "Owner-" & commName,
+ symbol: "OWN" & commNameShort,
+ supply: stint.u256("1"),
+ infiniteSupply: false,
+ transferable: true,
+ remoteSelfDestruct: false,
+ tokenUri: utl.changeCommunityKeyCompression(communityId) & "/"
+ ),
+ DeploymentParameters(
+ communityId: communityId,
+ name: "TMaster-" & commName,
+ symbol: "TM" & commNameShort,
+ infiniteSupply: true,
+ transferable: false,
+ remoteSelfDestruct: true,
+ tokenUri: utl.changeCommunityKeyCompression(communityId) & "/"
+ )
+ )
+
+method authenticateAndTransfer*(self: Module) =
+ self.tempResolvedSignatures.clear()
+
+ if self.tempUuid.len == 0:
+ error "No uuid to authenticate and transfer"
+ #TODO: notify about error
+ return
+
+ if self.tempAddressFrom.len == 0:
+ error "No address to send from"
+ #TODO: notify about error
+ return
+
+ let kp = self.controller.getKeypairByAccountAddress(self.tempAddressFrom)
+ if kp.migratedToKeycard():
+ let accounts = kp.accounts.filter(acc => cmpIgnoreCase(acc.address, self.tempAddressFrom) == 0)
+ if accounts.len != 1:
+ error "cannot resolve selected account to send from among known keypair accounts"
+ #TODO: notify about error
+ return
+ self.controller.authenticate(kp.keyUid)
else:
- self.controller.authenticateUser()
+ self.controller.authenticate()
+
+method onUserAuthenticated*(self: Module, password: string, pin: string) =
+ if password.len == 0:
+ error "No password provided from authentication"
+ #TODO: notify about error
+ self.resetTempValues()
+ else:
+ self.tempPin = pin
+ self.tempPassword = password
+ self.buildTransactionsFromRoute()
+
+proc buildTransactionsFromRoute(self: Module) =
+ let err = self.controller.buildTransactionsFromRoute(self.tempUuid)
+ if err.len > 0:
+ error "Error building transactions from route", err = err
+ #TODO: notify about error
+ self.resetTempValues()
+
+proc sendSignedTransactions*(self: Module) =
+ try:
+ # check if all transactions are signed
+ for _, (r, s, v) in self.tempResolvedSignatures.pairs:
+ if r.len == 0 or s.len == 0 or v.len == 0:
+ raise newException(CatchableError, "not all transactions are signed")
+
+ let err = self.controller.sendRouterTransactionsWithSignatures(self.tempUuid, self.tempResolvedSignatures)
+ if err.len > 0:
+ raise newException(CatchableError, "sending transaction failed: " & err)
+ except Exception as e:
+ error "sendSignedTransactions failed: ", msg=e.msg
+ #TODO: notify about error
+ self.resetTempValues()
+
+proc signOnKeycard(self: Module) =
+ self.tempTxHashBeingProcessed = ""
+ for h, (r, s, v) in self.tempResolvedSignatures.pairs:
+ if r.len != 0 and s.len != 0 and v.len != 0:
+ continue
+ self.tempTxHashBeingProcessed = h
+ var txForKcFlow = self.tempTxHashBeingProcessed
+ if txForKcFlow.startsWith("0x"):
+ txForKcFlow = txForKcFlow[2..^1]
+ self.controller.runSignFlow(self.tempPin, self.tempAddressPath, txForKcFlow)
+ break
+ if self.tempTxHashBeingProcessed.len == 0:
+ self.sendSignedTransactions()
+
+proc getRSVFromSignature(self: Module, signature: string): (string, string, string) =
+ let finalSignature = singletonInstance.utils.removeHexPrefix(signature)
+ if finalSignature.len != SIGNATURE_LEN:
+ return ("", "", "")
+ let r = finalSignature[0..63]
+ let s = finalSignature[64..127]
+ let v = finalSignature[128..129]
+ return (r, s, v)
+
+method prepareSignaturesForTransactions*(self:Module, txForSigning: RouterTransactionsForSigningDto) =
+ var res = ""
+ try:
+ if txForSigning.sendDetails.uuid != self.tempUuid:
+ raise newException(CatchableError, "preparing signatures for transactions are not matching the initial request")
+ if txForSigning.signingDetails.hashes.len == 0:
+ raise newException(CatchableError, "no transaction hashes to be signed")
+ if txForSigning.signingDetails.keyUid == "" or txForSigning.signingDetails.address == "" or txForSigning.signingDetails.addressPath == "":
+ raise newException(CatchableError, "preparing signatures for transactions failed")
+
+ if txForSigning.signingDetails.signOnKeycard:
+ self.tempAddressFrom = txForSigning.signingDetails.address
+ self.tempAddressPath = txForSigning.signingDetails.addressPath
+ for h in txForSigning.signingDetails.hashes:
+ self.tempResolvedSignatures[h] = ("", "", "")
+ self.signOnKeycard()
+ else:
+ var finalPassword = self.tempPassword
+ if not singletonInstance.userProfile.getIsKeycardUser():
+ finalPassword = hashPassword(self.tempPassword)
+ for h in txForSigning.signingDetails.hashes:
+ self.tempResolvedSignatures[h] = ("", "", "")
+ var
+ signature = ""
+ err: string
+ (signature, err) = self.controller.signMessage(txForSigning.signingDetails.address, finalPassword, h)
+ if err.len > 0:
+ raise newException(CatchableError, "signing transaction failed: " & err)
+ self.tempResolvedSignatures[h] = self.getRSVFromSignature(signature)
+ self.sendSignedTransactions()
+ except Exception as e:
+ error "signMessageWithCallback failed: ", msg=e.msg
+ #TODO: notify about error
+ self.resetTempValues()
+
+method onTransactionSigned*(self: Module, keycardFlowType: string, keycardEvent: KeycardEvent) =
+ if keycardFlowType != keycard_constants.ResponseTypeValueKeycardFlowResult:
+ let err = "unexpected error while keycard signing transaction"
+ error "error", err=err
+ # TODO: notify about error
+ self.resetTempValues()
+ return
+ self.tempResolvedSignatures[self.tempTxHashBeingProcessed] = (keycardEvent.txSignature.r, keycardEvent.txSignature.s, keycardEvent.txSignature.v)
+ self.signOnKeycard()
+
+method onTransactionSent*(self: Module, uuid: string, sendType: SendType, chainId: int, approvalTx: bool, txHash: string,
+ toAddress: string, error: string) =
+ if error.len > 0:
+ error "Error sending transaction", error = error
+ #TODO: notify about error
+ self.resetTempValues()
+ return
+ if self.tempContractAction == ContractAction.Deploy:
+ self.controller.storeDeployedContract(sendType, self.tempAddressFrom, toAddress, chainId, txHash, self.tempDeploymentParams)
+ return
+ if self.tempContractAction == ContractAction.Airdrop:
+ # no action required
+ return
+ if self.tempContractAction == ContractAction.SelfDestruct:
+ # no action required
+ return
+ if self.tempContractAction == ContractAction.Burn:
+ # no action required
+ return
+ if self.tempContractAction == ContractAction.DeployOwnerToken:
+ self.controller.storeDeployedOwnerContract(self.tempAddressFrom, chainId, txHash, self.tempOwnerDeploymentParams, self.tempMasterDeploymentParams)
+ return
+ if self.tempContractAction == ContractAction.SetSigner:
+ # no action required
+ return
+ error "Unknown contract action"
proc getTokenAndAmountList(self: Module, communityId: string, tokensJsonString: string): seq[CommunityTokenAndAmount] =
try:
@@ -117,21 +313,16 @@ proc getOwnerAndMasterTokensAddresses(self: Module, communityId: string, chainId
let masterTokenAddress = self.getTokenAddressFromPermissions(communityDto, chainId, TokenPermissionType.BecomeTokenMaster)
return (ownerTokenAddress, masterTokenAddress, ownerTokenAddress != "" and masterTokenAddress != "")
-method airdropTokens*(self: Module, communityId: string, tokensJsonString: string, walletsJsonString: string, addressFrom: string) =
- self.tempTokenAndAmountList = self.getTokenAndAmountList(communityId, tokensJsonString)
- if len(self.tempTokenAndAmountList) == 0:
- return
- self.tempWalletAddresses = walletsJsonString.parseJson.to(seq[string])
- self.tempCommunityId = communityId
- self.tempAddressFrom = addressFrom
- self.tempContractAction = ContractAction.Airdrop
- self.authenticate()
-
-method computeAirdropFee*(self: Module, communityId: string, tokensJsonString: string, walletsJsonString: string, addressFrom: string, requestId: string) =
+method computeAirdropFee*(self: Module, uuid: string, communityId: string, tokensJsonString: string, walletsJsonString: string,
+ addressFrom: string) =
let tokenAndAmountList = self.getTokenAndAmountList(communityId, tokensJsonString)
if len(tokenAndAmountList) == 0:
+ error "No tokens to airdrop"
return
- self.controller.computeAirdropFee(tokenAndAmountList, walletsJsonString.parseJson.to(seq[string]), addressFrom, requestId)
+ self.tempContractAction = ContractAction.Airdrop
+ self.tempUuid = uuid
+ self.tempAddressFrom = addressFrom
+ self.controller.computeAirdropFee(uuid, tokenAndAmountList, walletsJsonString.parseJson.to(seq[string]), addressFrom)
proc getWalletAndAmountListFromJson(self: Module, collectiblesToBurnJsonString: string): seq[WalletAndAmount] =
let collectiblesToBurnJson = collectiblesToBurnJsonString.parseJson
@@ -140,36 +331,16 @@ proc getWalletAndAmountListFromJson(self: Module, collectiblesToBurnJsonString:
let amount = collectibleToBurn["amount"].getInt
result.add(WalletAndAmount(walletAddress: walletAddress, amount: amount))
-method selfDestructCollectibles*(self: Module, communityId: string, collectiblesToBurnJsonString: string, contractUniqueKey: string, addressFrom: string) =
- self.tempWalletAndAmountList = self.getWalletAndAmountListFromJson(collectiblesToBurnJsonString)
- self.tempCommunityId = communityId
- self.tempContractUniqueKey = contractUniqueKey
- self.tempAddressFrom = addressFrom
- self.tempContractAction = ContractAction.SelfDestruct
- self.authenticate()
-
-method burnTokens*(self: Module, communityId: string, contractUniqueKey: string, amount: string, addressFrom: string) =
- self.tempCommunityId = communityId
- self.tempContractUniqueKey = contractUniqueKey
- self.tempAmount = amount.parse(Uint256)
- self.tempAddressFrom = addressFrom
- self.tempContractAction = ContractAction.Burn
- self.authenticate()
-
-method setSigner*(self: Module, communityId: string, chainId: int, contractAddress: string, addressFrom: string) =
- self.tempCommunityId = communityId
- self.tempChainId = chainId
- self.tempContractAddress = contractAddress
- self.tempAddressFrom = addressFrom
- self.tempContractAction = ContractAction.SetSigner
- self.authenticate()
-method deployCollectibles*(self: Module, communityId: string, fromAddress: string, name: string, symbol: string, description: string,
- supply: string, infiniteSupply: bool, transferable: bool, selfDestruct: bool, chainId: int, imageCropInfoJson: string) =
+method computeDeployCollectiblesFee*(self: Module, uuid: string, communityId: string, fromAddress: string, name: string,
+ symbol: string, description: string, supply: string, infiniteSupply: bool, transferable: bool, selfDestruct: bool,
+ chainId: int, imageCropInfoJson: string) =
+ # TODO: move this check to service and send route ready signal to update the UI and notifiy the user
let (ownerTokenAddress, masterTokenAddress, isDeployed) = self.getOwnerAndMasterTokensAddresses(communityId, chainId)
if not isDeployed:
error "Owner token and master token not deployed"
return
+ self.tempUuid = uuid
self.tempAddressFrom = fromAddress
self.tempCommunityId = communityId
self.tempChainId = chainId
@@ -191,26 +362,18 @@ method deployCollectibles*(self: Module, communityId: string, fromAddress: strin
self.tempDeploymentParams.communityId = communityId
self.tempContractAction = ContractAction.Deploy
- self.authenticate()
+ self.controller.computeDeployTokenFee(uuid, chainId, fromAddress, communityId, self.tempDeploymentParams)
-proc createOwnerAndMasterDeploymentParams(self: Module, communityId: string): (DeploymentParameters, DeploymentParameters) =
- let communityDto = self.controller.getCommunityById(communityId)
- let commName = communityDto.name
- let commNameShort = try: commName[0 .. 2].toUpper except: commName.toUpper
- return (DeploymentParameters(name: "Owner-" & commName, symbol: "OWN" & commNameShort, supply: stint.u256("1"),
- infiniteSupply: false, transferable: true, remoteSelfDestruct: false,
- tokenUri: utl.changeCommunityKeyCompression(communityId) & "/", communityId: communityId),
- DeploymentParameters(name: "TMaster-" & commName, symbol: "TM" & commNameShort, infiniteSupply: true,
- transferable: false, remoteSelfDestruct: true,
- tokenUri: utl.changeCommunityKeyCompression(communityId) & "/", communityId: communityId))
-
-method deployOwnerToken*(self: Module, communityId: string, fromAddress: string, ownerName: string, ownerSymbol: string, ownerDescription: string,
- masterName: string, masterSymbol: string, masterDescription: string, chainId: int, imageCropInfoJson: string) =
+method computeDeployTokenOwnerFee*(self: Module, uuid: string, communityId: string, fromAddress: string, ownerName: string,
+ ownerSymbol: string, ownerDescription: string, masterName: string, masterSymbol: string, masterDescription: string,
+ chainId: int, imageCropInfoJson: string) =
+ # TODO: move this check to service and send route ready signal to update the UI and notifiy the user
let (_, _, isDeployed) = self.getOwnerAndMasterTokensAddresses(communityId, chainId)
if isDeployed:
error "Owner token and master token are deployed or pending"
return
+ self.tempUuid = uuid
self.tempAddressFrom = fromAddress
self.tempCommunityId = communityId
self.tempChainId = chainId
@@ -224,14 +387,17 @@ method deployOwnerToken*(self: Module, communityId: string, fromAddress: string,
self.tempMasterDeploymentParams.tokenType = TokenType.ERC721
self.tempMasterDeploymentParams.base64image = base65Image
self.tempContractAction = ContractAction.DeployOwnerToken
- self.authenticate()
-method deployAssets*(self: Module, communityId: string, fromAddress: string, name: string, symbol: string, description: string, supply: string, infiniteSupply: bool, decimals: int,
- chainId: int, imageCropInfoJson: string) =
+ self.controller.computeDeployOwnerContractsFee(uuid, chainId, fromAddress, communityId, self.tempOwnerDeploymentParams, self.tempMasterDeploymentParams)
+
+method computeDeployAssetsFee*(self: Module, uuid: string, communityId: string, fromAddress: string, name: string, symbol: string, description: string,
+ supply: string, infiniteSupply: bool, decimals: int, chainId: int, imageCropInfoJson: string) =
+ # TODO: move this check to service and send route ready signal to update the UI and notifiy the user
let (ownerTokenAddress, masterTokenAddress, isDeployed) = self.getOwnerAndMasterTokensAddresses(communityId, chainId)
if not isDeployed:
error "Owner token and master token not deployed"
return
+ self.tempUuid = uuid
self.tempAddressFrom = fromAddress
self.tempCommunityId = communityId
self.tempChainId = chainId
@@ -252,7 +418,7 @@ method deployAssets*(self: Module, communityId: string, fromAddress: string, nam
self.tempDeploymentParams.communityId = communityId
self.tempContractAction = ContractAction.Deploy
- self.authenticate()
+ self.controller.computeDeployTokenFee(uuid, chainId, fromAddress, communityId, self.tempDeploymentParams)
method removeCommunityToken*(self: Module, communityId: string, chainId: int, address: string) =
self.controller.removeCommunityToken(communityId, chainId, address)
@@ -260,107 +426,39 @@ method removeCommunityToken*(self: Module, communityId: string, chainId: int, ad
method refreshCommunityToken*(self: Module, chainId: int, address: string) =
self.controller.refreshCommunityToken(chainId, address)
-method onUserAuthenticated*(self: Module, password: string) =
- defer: self.resetTempValues()
- if password.len == 0:
- discard
- #TODO signalize somehow
- else:
- if self.tempContractAction == ContractAction.Deploy:
- self.controller.deployContract(self.tempCommunityId, self.tempAddressFrom, password, self.tempDeploymentParams, self.tempChainId)
- elif self.tempContractAction == ContractAction.Airdrop:
- self.controller.airdropTokens(self.tempCommunityId, password, self.tempTokenAndAmountList, self.tempWalletAddresses, self.tempAddressFrom)
- elif self.tempContractAction == ContractAction.SelfDestruct:
- self.controller.selfDestructCollectibles(self.tempCommunityId, password, self.tempWalletAndAmountList, self.tempContractUniqueKey, self.tempAddressFrom)
- elif self.tempContractAction == ContractAction.Burn:
- self.controller.burnTokens(self.tempCommunityId, password, self.tempContractUniqueKey, self.tempAmount, self.tempAddressFrom)
- elif self.tempContractAction == ContractAction.DeployOwnerToken:
- self.controller.deployOwnerContracts(self.tempCommunityId, self.tempAddressFrom, password,
- self.tempOwnerDeploymentParams, self.tempMasterDeploymentParams, self.tempChainId)
- elif self.tempContractAction == ContractAction.SetSigner:
- self.controller.setSigner(password, self.tempCommunityId, self.tempChainId, self.tempContractAddress, self.tempAddressFrom)
-
-method onDeployFeeComputed*(self: Module, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: ComputeFeeErrorCode, responseId: string) =
- self.view.updateDeployFee(ethCurrency, fiatCurrency, errorCode.int, responseId)
-
-method onSelfDestructFeeComputed*(self: Module, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: ComputeFeeErrorCode, responseId: string) =
- self.view.updateSelfDestructFee(ethCurrency, fiatCurrency, errorCode.int, responseId)
-
-method onAirdropFeesComputed*(self: Module, args: AirdropFeesArgs) =
- self.view.updateAirdropFees(%args)
-
-method onBurnFeeComputed*(self: Module, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: ComputeFeeErrorCode, responseId: string) =
- self.view.updateBurnFee(ethCurrency, fiatCurrency, errorCode.int, responseId)
-
-method onSetSignerFeeComputed*(self: Module, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: ComputeFeeErrorCode, responseId: string) =
- self.view.updateSetSignerFee(ethCurrency, fiatCurrency, errorCode.int, responseId)
-
-method computeDeployFee*(self: Module, communityId: string, chainId: int, accountAddress: string, tokenType: TokenType, isOwnerDeployment: bool, requestId: string) =
- if isOwnerDeployment:
- let (ownerDeploymentParams, masterDeploymentParams) = self.createOwnerAndMasterDeploymentParams(communityId)
- self.controller.computeDeployOwnerContractsFee(chainId, accountAddress, communityId, ownerDeploymentParams, masterDeploymentParams, requestId)
- else:
- self.controller.computeDeployFee(chainId, accountAddress, tokenType, requestId)
-
-method computeSetSignerFee*(self: Module, chainId: int, contractAddress: string, addressFrom: string, requestId: string) =
- self.controller.computeSetSignerFee(chainId, contractAddress, addressFrom, requestId)
+method computeSetSignerFee*(self: Module, uuid: string, communityId: string, chainId: int, contractAddress: string, addressFrom: string) =
+ self.tempContractAction = ContractAction.SetSigner
+ self.tempUuid = uuid
+ self.tempAddressFrom = addressFrom
+ self.tempCommunityId = communityId
+ self.controller.computeSetSignerFee(uuid, communityId, chainId, contractAddress, addressFrom)
-method computeSelfDestructFee*(self: Module, collectiblesToBurnJsonString: string, contractUniqueKey: string, addressFrom: string, requestId: string) =
+method computeSelfDestructFee*(self: Module, uuid: string, collectiblesToBurnJsonString: string, contractUniqueKey: string, addressFrom: string) =
let walletAndAmountList = self.getWalletAndAmountListFromJson(collectiblesToBurnJsonString)
- self.controller.computeSelfDestructFee(walletAndAmountList, contractUniqueKey, addressFrom, requestId)
-
-method computeBurnFee*(self: Module, contractUniqueKey: string, amount: string, addressFrom: string, requestId: string) =
- self.controller.computeBurnFee(contractUniqueKey, amount.parse(Uint256), addressFrom, requestId)
+ if len(walletAndAmountList) == 0:
+ error "No collectibles/assets to burn"
+ return
+ self.tempContractAction = ContractAction.SelfDestruct
+ self.tempUuid = uuid
+ self.tempAddressFrom = addressFrom
+ self.controller.computeSelfDestructFee(uuid, walletAndAmountList, contractUniqueKey, addressFrom)
-proc createUrl(self: Module, chainId: int, transactionHash: string): string =
- let network = self.controller.getNetworkByChainId(chainId)
- result = if network != nil: network.blockExplorerURL & "/tx/" & transactionHash else: ""
+method computeBurnFee*(self: Module, uuid: string, contractUniqueKey: string, amount: string, addressFrom: string) =
+ self.tempContractAction = ContractAction.Burn
+ self.tempUuid = uuid
+ self.tempAddressFrom = addressFrom
+ self.controller.computeBurnFee(uuid, contractUniqueKey, amount, addressFrom)
proc getChainName(self: Module, chainId: int): string =
let network = self.controller.getNetworkByChainId(chainId)
result = if network != nil: network.chainName else: ""
-method onCommunityTokenDeployStateChanged*(self: Module, communityId: string, chainId: int, transactionHash: string, deployState: DeployState) =
- let url = self.createUrl(chainId, transactionHash)
- self.view.emitDeploymentStateChanged(communityId, deployState.int, url)
-
-method onOwnerTokenDeployStateChanged*(self: Module, communityId: string, chainId: int, transactionHash: string, deployState: DeployState) =
- let url = self.createUrl(chainId, transactionHash)
- self.view.emitOwnerTokenDeploymentStateChanged(communityId, deployState.int, url)
-
-method onOwnerTokenDeployStarted*(self: Module, communityId: string, chainId: int, transactionHash: string) =
- let url = self.createUrl(chainId, transactionHash)
- self.view.emitOwnerTokenDeploymentStarted(communityId, url)
-
-method onRemoteDestructStateChanged*(self: Module, communityId: string, tokenName: string, chainId: int, transactionHash: string, status: ContractTransactionStatus) =
- let url = self.createUrl(chainId, transactionHash)
- self.view.emitRemoteDestructStateChanged(communityId, tokenName, status.int, url)
-
-method onBurnStateChanged*(self: Module, communityId: string, tokenName: string, chainId: int, transactionHash: string, status: ContractTransactionStatus) =
- let url = self.createUrl(chainId, transactionHash)
- self.view.emitBurnStateChanged(communityId, tokenName, status.int, url)
-
-method onAirdropStateChanged*(self: Module, communityId: string, tokenName: string, chainId: int, transactionHash: string, status: ContractTransactionStatus) =
- let url = self.createUrl(chainId, transactionHash)
- let chainName = self.getChainName(chainId)
- self.view.emitAirdropStateChanged(communityId, tokenName, chainName, status.int, url)
-
method onOwnerTokenReceived*(self: Module, communityId: string, communityName: string, chainId: int, contractAddress: string) =
self.view.emitOwnerTokenReceived(communityId, communityName, chainId, contractAddress)
method onCommunityTokenReceived*(self: Module, name: string, symbol: string, image: string, communityId: string, communityName: string, balance: string, chainId: int, txHash: string, isFirst: bool, tokenType: int, accountName: string, accountAddress: string) =
self.view.emitCommunityTokenReceived(name, symbol, image, communityId, communityName, balance, chainId, txHash, isFirst, tokenType, accountName, accountAddress)
-method onSetSignerStateChanged*(self: Module, communityId: string, chainId: int, transactionHash: string, status: ContractTransactionStatus) =
- let communityDto = self.controller.getCommunityById(communityId)
- let communityName = communityDto.name
- let url = self.createUrl(chainId, transactionHash)
- self.view.emitSetSignerStateChanged(communityId, communityName, status.int, url)
-
-method onSendOwnerTokenStateChanged*(self: Module, chainId: int, transactionHash: string, tokenName: string, status: ContractTransactionStatus) =
- let url = self.createUrl(chainId, transactionHash)
- self.view.emitSendOwnerTokenStateChanged(tokenName, status.int, url)
-
method onLostOwnership*(self: Module, communityId: string) =
let communityDto = self.controller.getCommunityById(communityId)
let communityName = communityDto.name
@@ -393,3 +491,18 @@ method onOwnerTokenOwnerAddress*(self: Module, chainId: int, contractAddress: st
"contractAddress": contractAddress
}
self.view.setOwnerTokenDetails($jsonObj)
+
+method suggestedRoutesReady*(self: Module, uuid: string, sendType: SendType, ethCurrency: CurrencyAmount,
+ fiatCurrency: CurrencyAmount, costPerPath: seq[CostPerPath], errCode: string, errDescription: string) =
+ if sendType != SendType.CommunityBurn and
+ sendType != SendType.CommunityDeployAssets and
+ sendType != SendType.CommunityDeployCollectibles and
+ sendType != SendType.CommunityDeployOwnerToken and
+ sendType != SendType.CommunityMintTokens and
+ sendType != SendType.CommunityRemoteBurn and
+ sendType != SendType.CommunitySetSignerPubKey:
+ return
+ self.view.emitSuggestedRoutesReadySignal(uuid, ethCurrency, fiatCurrency, %costPerPath, errCode, errDescription)
+
+method stopUpdatesForSuggestedRoute*(self: Module) =
+ self.controller.stopSuggestedRoutesAsyncCalculation()
\ No newline at end of file
diff --git a/src/app/modules/main/communities/tokens/view.nim b/src/app/modules/main/communities/tokens/view.nim
index 9ffb55402eb..ab6145eb2d6 100644
--- a/src/app/modules/main/communities/tokens/view.nim
+++ b/src/app/modules/main/communities/tokens/view.nim
@@ -2,8 +2,6 @@ import NimQml, json, strutils, sequtils
import ./io_interface as community_tokens_module_interface
import app/modules/shared_models/currency_amount
-import app_service/common/conversion
-import app_service/common/types
QtObject:
type
@@ -22,14 +20,26 @@ QtObject:
result.QObject.setup
result.communityTokensModule = communityTokensModule
- proc deployCollectible*(self: View, communityId: string, fromAddress: string, name: string, symbol: string, description: string, supply: string, infiniteSupply: bool, transferable: bool, selfDestruct: bool, chainId: int, imageCropInfoJson: string) {.slot.} =
- self.communityTokensModule.deployCollectibles(communityId, fromAddress, name, symbol, description, supply, infiniteSupply, transferable, selfDestruct, chainId, imageCropInfoJson)
+ proc authenticateAndTransfer*(self: View) {.slot.} =
+ self.communityTokensModule.authenticateAndTransfer()
- proc deployAssets*(self: View, communityId: string, fromAddress: string, name: string, symbol: string, description: string, supply: string, infiniteSupply: bool, decimals: int, chainId: int, imageCropInfoJson: string) {.slot.} =
- self.communityTokensModule.deployAssets(communityId, fromAddress, name, symbol, description, supply, infiniteSupply, decimals, chainId, imageCropInfoJson)
+ proc computeDeployCollectiblesFee*(self: View, uuid: string, communityId: string, fromAddress: string, name: string,
+ symbol: string, description: string, supply: string, infiniteSupply: bool, transferable: bool, selfDestruct: bool,
+ chainId: int, imageCropInfoJson: string) {.slot.} =
+ self.communityTokensModule.computeDeployCollectiblesFee(uuid, communityId, fromAddress, name, symbol, description,
+ supply, infiniteSupply, transferable, selfDestruct, chainId, imageCropInfoJson)
- proc deployOwnerToken*(self:View, communityId: string, fromAddress: string, ownerName: string, ownerSymbol: string, ownerDescription: string, masterName: string, masterSymbol: string, masterDescription: string, chainId: int, imageCropInfoJson: string) {.slot.} =
- self.communityTokensModule.deployOwnerToken(communityId, fromAddress, ownerName, ownerSymbol, ownerDescription, masterName, masterSymbol, masterDescription, chainId, imageCropInfoJson)
+ proc computeDeployAssetsFee*(self: View, uuid: string, communityId: string, fromAddress: string, name: string,
+ symbol: string, description: string, supply: string, infiniteSupply: bool, decimals: int, chainId: int,
+ imageCropInfoJson: string) {.slot.} =
+ self.communityTokensModule.computeDeployAssetsFee(uuid, communityId, fromAddress, name, symbol, description, supply,
+ infiniteSupply, decimals, chainId, imageCropInfoJson)
+
+ proc computeDeployTokenOwnerFee*(self:View, uuid: string, communityId: string, fromAddress: string, ownerName: string,
+ ownerSymbol: string, ownerDescription: string, masterName: string, masterSymbol: string, masterDescription: string,
+ chainId: int, imageCropInfoJson: string) {.slot.} =
+ self.communityTokensModule.computeDeployTokenOwnerFee(uuid, communityId, fromAddress, ownerName, ownerSymbol,
+ ownerDescription, masterName, masterSymbol, masterDescription, chainId, imageCropInfoJson)
proc removeCommunityToken*(self: View, communityId: string, chainId: int, address: string) {.slot.} =
self.communityTokensModule.removeCommunityToken(communityId, chainId, address)
@@ -37,101 +47,35 @@ QtObject:
proc refreshCommunityToken*(self: View, chainId: int, address: string) {.slot.} =
self.communityTokensModule.refreshCommunityToken(chainId, address)
- proc airdropTokens*(self: View, communityId: string, tokensJsonString: string, walletsJsonString: string, addressFrom: string) {.slot.} =
- self.communityTokensModule.airdropTokens(communityId, tokensJsonString, walletsJsonString, addressFrom)
-
- proc computeAirdropFee*(self: View, communityId: string, tokensJsonString: string, walletsJsonString: string, addressFrom: string, requestId: string) {.slot.} =
- self.communityTokensModule.computeAirdropFee(communityId, tokensJsonString, walletsJsonString, addressFrom, requestId)
-
- proc selfDestructCollectibles*(self: View, communityId: string, collectiblesToBurnJsonString: string, contractUniqueKey: string, addressFrom: string) {.slot.} =
- self.communityTokensModule.selfDestructCollectibles(communityId, collectiblesToBurnJsonString, contractUniqueKey, addressFrom)
+ proc computeAirdropFee*(self: View, uuid: string, communityId: string, tokensJsonString: string,
+ walletsJsonString: string, addressFrom: string) {.slot.} =
+ self.communityTokensModule.computeAirdropFee(uuid, communityId, tokensJsonString, walletsJsonString, addressFrom)
- proc burnTokens*(self: View, communityId: string, contractUniqueKey: string, amount: string, addressFrom: string) {.slot.} =
- self.communityTokensModule.burnTokens(communityId, contractUniqueKey, amount, addressFrom)
-
- proc setSigner*(self: View, communityId: string, chainId: int, contractAddress: string, addressFrom: string) {.slot.} =
- self.communityTokensModule.setSigner(communityId, chainId, contractAddress, addressFrom)
-
- proc deployFeeUpdated*(self: View, ethCurrency: QVariant, fiatCurrency: QVariant, errorCode: int, responseId: string) {.signal.}
- proc selfDestructFeeUpdated*(self: View, ethCurrency: QVariant, fiatCurrency: QVariant, errorCode: int, responseId: string) {.signal.}
- proc airdropFeesUpdated*(self: View, json: string) {.signal.}
- proc burnFeeUpdated*(self: View, ethCurrency: QVariant, fiatCurrency: QVariant, errorCode: int, responseId: string) {.signal.}
- proc setSignerFeeUpdated*(self: View, ethCurrency: QVariant, fiatCurrency: QVariant, errorCode: int, responseId: string) {.signal.}
proc ownerTokenReceived*(self: View, communityId: string, communityName: string, chainId: int, contractAddress: string) {.signal.}
proc communityTokenReceived*(self: View, name: string, symbol: string, image: string, communityId: string, communityName: string, balance: string, chainId: int, txHash: string, isFirst: bool, tokenType: int, accountName: string, accountAddress: string) {.signal.}
- proc setSignerStateChanged*(self: View, communityId: string, communityName: string, status: int, url: string) {.signal.}
proc ownershipNodeLost*(self: View, communityId: string, communityName: string) {.signal.}
- proc sendOwnerTokenStateChanged*(self: View, tokenName: string, status: int, url: string) {.signal.}
-
- proc computeDeployFee*(self: View, communityId: string, chainId: int, accountAddress: string, tokenType: int, isOwnerDeployment: bool, requestId: string) {.slot.} =
- self.communityTokensModule.computeDeployFee(communityId, chainId, accountAddress, intToEnum(tokenType, TokenType.Unknown), isOwnerDeployment, requestId)
- proc computeSetSignerFee*(self: View, chainId: int, contractAddress: string, addressFrom: string, requestId: string) {.slot.} =
- self.communityTokensModule.computeSetSignerFee(chainId, contractAddress, addressFrom, requestId)
+ proc computeSetSignerFee*(self: View, uuid: string, communityId: string, chainId: int, contractAddress: string, addressFrom: string) {.slot.} =
+ self.communityTokensModule.computeSetSignerFee(uuid, communityId, chainId, contractAddress, addressFrom)
- proc computeSelfDestructFee*(self: View, collectiblesToBurnJsonString: string, contractUniqueKey: string, addressFrom: string, requestId: string) {.slot.} =
- self.communityTokensModule.computeSelfDestructFee(collectiblesToBurnJsonString, contractUniqueKey, addressFrom, requestId)
+ proc computeSelfDestructFee*(self: View, uuid: string, collectiblesToBurnJsonString: string, contractUniqueKey: string, addressFrom: string) {.slot.} =
+ self.communityTokensModule.computeSelfDestructFee(uuid, collectiblesToBurnJsonString, contractUniqueKey, addressFrom)
- proc computeBurnFee*(self: View, contractUniqueKey: string, amount: string, addressFrom: string, requestId: string) {.slot.} =
- self.communityTokensModule.computeBurnFee(contractUniqueKey, amount, addressFrom, requestId)
+ proc computeBurnFee*(self: View, uuid: string, contractUniqueKey: string, amount: string, addressFrom: string) {.slot.} =
+ self.communityTokensModule.computeBurnFee(uuid, contractUniqueKey, amount, addressFrom)
proc declineOwnership*(self: View, communityId: string) {.slot.} =
self.communityTokensModule.declineOwnership(communityId)
- proc updateDeployFee*(self: View, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: int, responseId: string) =
- self.deployFeeUpdated(newQVariant(ethCurrency), newQVariant(fiatCurrency), errorCode, responseId)
-
- proc updateBurnFee*(self: View, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: int, responseId: string) =
- self.burnFeeUpdated(newQVariant(ethCurrency), newQVariant(fiatCurrency), errorCode, responseId)
-
- proc updateSetSignerFee*(self: View, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: int, responseId: string) =
- self.setSignerFeeUpdated(newQVariant(ethCurrency), newQVariant(fiatCurrency), errorCode, responseId)
-
- proc updateSelfDestructFee*(self: View, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: int, responseId: string) =
- self.selfDestructFeeUpdated(newQVariant(ethCurrency), newQVariant(fiatCurrency), errorCode, responseId)
-
- proc updateAirdropFees*(self: View, args: JsonNode) =
- self.airdropFeesUpdated($args)
-
- proc deploymentStateChanged*(self: View, communityId: string, status: int, url: string) {.signal.}
- proc emitDeploymentStateChanged*(self: View, communityId: string, status: int, url: string) =
- self.deploymentStateChanged(communityId, status, url)
-
- proc remoteDestructStateChanged*(self: View, communityId: string, tokenName: string, status: int, url: string) {.signal.}
- proc emitRemoteDestructStateChanged*(self: View, communityId: string, tokenName: string, status: int, url: string) =
- self.remoteDestructStateChanged(communityId, tokenName, status, url)
-
- proc burnStateChanged*(self: View, communityId: string, tokenName: string, status: int, url: string) {.signal.}
- proc emitBurnStateChanged*(self: View, communityId: string, tokenName: string, status: int, url: string) =
- self.burnStateChanged(communityId, tokenName, status, url)
-
- proc airdropStateChanged*(self: View, communityId: string, tokenName: string, chainName: string, status: int, url: string) {.signal.}
- proc emitAirdropStateChanged*(self: View, communityId: string, tokenName: string, chainName: string, status: int, url: string) =
- self.airdropStateChanged(communityId, tokenName, chainName, status, url)
-
- proc ownerTokenDeploymentStarted*(self: View, communityId: string, url: string) {.signal.}
- proc emitOwnerTokenDeploymentStarted*(self: View, communityId: string, url: string) =
- self.ownerTokenDeploymentStarted(communityId, url)
-
- proc ownerTokenDeploymentStateChanged*(self: View, communityId: string, status: int, url: string) {.signal.}
- proc emitOwnerTokenDeploymentStateChanged*(self: View, communityId: string, status: int, url: string) =
- self.ownerTokenDeploymentStateChanged(communityId, status, url)
-
proc emitOwnerTokenReceived*(self: View, communityId: string, communityName: string, chainId: int, contractAddress: string) =
self.ownerTokenReceived(communityId, communityName, chainId, contractAddress)
proc emitCommunityTokenReceived*(self: View, name: string, symbol: string, image: string, communityId: string, communityName: string, balance: string, chainId: int, txHash: string, isFirst: bool, tokenType: int, accountName: string, accountAddress: string) =
self.communityTokenReceived(name, symbol, image, communityId, communityName, balance, chainId, txHash, isFirst, tokenType, accountName, accountAddress)
- proc emitSetSignerStateChanged*(self: View, communityId: string, communityName: string, status: int, url: string) =
- self.setSignerStateChanged(communityId, communityName, status, url)
-
proc emitOwnershipLost*(self: View, communityId: string, communityName: string) =
self.ownershipNodeLost(communityId, communityName)
- proc emitSendOwnerTokenStateChanged*(self: View, tokenName: string, status: int, url: string) =
- self.sendOwnerTokenStateChanged(tokenName, status, url)
-
proc asyncGetOwnerTokenDetails*(self: View, communityId: string) {.slot.} =
self.communityTokensModule.asyncGetOwnerTokenDetails(communityId)
@@ -145,3 +89,13 @@ QtObject:
QtProperty[string] ownerTokenDetails:
read = getOwnerTokenDetails
notify = ownerTokenDetailsChanged
+
+ proc suggestedRoutesReady(self: View, uuid: string, ethCurrency: QVariant, fiatCurrency: QVariant,
+ costPerPath: string, errCode: string, errDescription: string) {.signal.}
+ proc emitSuggestedRoutesReadySignal*(self: View, uuid: string, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount,
+ costPerPath: JsonNode, errCode: string, errDescription: string) =
+ self.suggestedRoutesReady(uuid, newQVariant(ethCurrency), newQVariant(fiatCurrency),
+ $costPerPath, errCode, errDescription)
+
+ proc stopUpdatesForSuggestedRoute*(self: View) {.slot.} =
+ self.communityTokensModule.stopUpdatesForSuggestedRoute()
\ No newline at end of file
diff --git a/src/app/modules/main/controller.nim b/src/app/modules/main/controller.nim
index 7c082fba44a..8b2ad5497ef 100644
--- a/src/app/modules/main/controller.nim
+++ b/src/app/modules/main/controller.nim
@@ -351,13 +351,13 @@ proc init*(self: Controller) =
self.events.on(SIGNAL_COMMUNITY_MY_REQUEST_ADDED) do(e: Args):
self.delegate.onMyRequestAdded();
- self.events.on(SIGNAL_COMMUNITY_TOKEN_DEPLOYMENT_STARTED) do(e: Args):
+ self.events.on(SIGNAL_COMMUNITY_TOKEN_DEPLOYMENT_STORED) do(e: Args):
let args = CommunityTokenDeploymentArgs(e)
- self.delegate.onCommunityTokenDeploymentStarted(args.communityToken)
+ self.delegate.onCommunityTokenDeploymentStored(args.communityToken, args.error)
- self.events.on(SIGNAL_OWNER_TOKEN_DEPLOYMENT_STARTED) do(e: Args):
+ self.events.on(SIGNAL_OWNER_TOKEN_DEPLOYMENT_STORED) do(e: Args):
let args = OwnerTokenDeploymentArgs(e)
- self.delegate.onOwnerTokensDeploymentStarted(args.ownerToken, args.masterToken)
+ self.delegate.onOwnerTokensDeploymentStored(args.ownerToken, args.masterToken, args.error)
self.events.on(SIGNAL_COMMUNITY_TOKEN_DEPLOY_STATUS) do(e: Args):
let args = CommunityTokenDeployedStatusArgs(e)
diff --git a/src/app/modules/main/io_interface.nim b/src/app/modules/main/io_interface.nim
index f8808ac8f9a..768308d6af6 100644
--- a/src/app/modules/main/io_interface.nim
+++ b/src/app/modules/main/io_interface.nim
@@ -346,10 +346,10 @@ method tryKeycardSync*(self: AccessInterface, keyUid: string, pin: string) {.bas
method onSharedKeycarModuleKeycardSyncPurposeTerminated*(self: AccessInterface, lastStepInTheCurrentFlow: bool) {.base.} =
raise newException(ValueError, "No implementation available")
-method onCommunityTokenDeploymentStarted*(self: AccessInterface, communityToken: CommunityTokenDto) {.base.} =
+method onCommunityTokenDeploymentStored*(self: AccessInterface, communityToken: CommunityTokenDto, error: string) {.base.} =
raise newException(ValueError, "No implementation available")
-method onOwnerTokensDeploymentStarted*(self: AccessInterface, ownerToken: CommunityTokenDto, masterToken: CommunityTokenDto) {.base.} =
+method onOwnerTokensDeploymentStored*(self: AccessInterface, ownerToken: CommunityTokenDto, masterToken: CommunityTokenDto, error: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityTokenOwnersFetched*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, owners: seq[CommunityCollectibleOwner]) {.base.} =
diff --git a/src/app/modules/main/module.nim b/src/app/modules/main/module.nim
index f217f2231bd..ed3f3e44c36 100644
--- a/src/app/modules/main/module.nim
+++ b/src/app/modules/main/module.nim
@@ -103,6 +103,7 @@ type
keychainService: keychain_service.Service
networkConnectionService: network_connection_service.Service
stickersService: stickers_service.Service
+ communityTokensService: community_tokens_service.Service
walletSectionModule: wallet_section_module.AccessInterface
profileSectionModule: profile_section_module.AccessInterface
stickersModule: stickers_module.AccessInterface
@@ -211,6 +212,7 @@ proc newModule*[T](
result.savedAddressService = savedAddressService
result.keychainService = keychainService
result.stickersService = stickersService
+ result.communityTokensService = communityTokensService
# Submodules
result.chatSectionModules = initOrderedTable[string, chat_section_module.AccessInterface]()
@@ -454,6 +456,28 @@ proc sendNotification[T](self: Module[T], status: string, sendDetails: SendDetai
error = ""
txHash = ""
isApprovalTx = false
+ #community specific details
+ # main community details
+ communityId = ""
+ communityName = ""
+ communityInvolvedTokens = 0
+ communityTotalAmount = ""
+ # community token 1 details
+ communityAmount1 = ""
+ communityAmountInfinite1 = false
+ communityAssetName1 = ""
+ communityAssetDecimals1 = 0
+ # community token 2 details
+ communityAmount2 = ""
+ communityAmountInfinite2 = false
+ communityAssetName2 = ""
+ communityAssetDecimals2 = 0
+ # other community details
+ communityInvolvedAddress = ""
+ communityNubmerOfInvolvedAddresses = 0
+ communityOwnerTokenName = ""
+ communityMasterTokenName = ""
+ communityDeployedTokenName = ""
if not sendDetails.errorResponse.isNil:
error = sendDetails.errorResponse.details
@@ -503,6 +527,64 @@ proc sendNotification[T](self: Module[T], status: string, sendDetails: SendDetai
if not accDto.isNil:
txToName = accDto.name
+ # check for community details
+ if not sendDetails.communityParams.isNil:
+ let getTokenContractAddressAtIndex = proc(transferDetails: seq[TansferDetails], index: int): string =
+ if transferDetails.len == 0 or index >= transferDetails.len:
+ return ""
+ return transferDetails[index].tokenContractAddress
+
+ let getCommunityAmount = proc(transferDetails: seq[TansferDetails]): string =
+ var total: UInt256 = stint.u256(0)
+ for td in transferDetails:
+ total += td.amount
+ return total.toString(10)
+
+ communityId = sendDetails.communityParams.communityId
+ let item = self.view.model().getItemById(communityId)
+ if item.id == "":
+ error = "cannot_resolve_community"
+ else:
+ communityName = item.name
+
+ communityInvolvedTokens = sendDetails.communityParams.transferDetails.len
+ communityTotalAmount = getCommunityAmount(sendDetails.communityParams.transferDetails)
+
+ for i in 0 ..< sendDetails.communityParams.transferDetails.len:
+ let tokenContractAddress = getTokenContractAddressAtIndex(sendDetails.communityParams.transferDetails, i)
+ if tokenContractAddress.len == 0:
+ error = "cannot_resolve_token_contract_address"
+ else:
+ let communityToken = self.communityTokensService.getCommunityTokenFromCache(fromChain, tokenContractAddress)
+ if communityToken.name.len == 0:
+ error = "cannot_resolve_community_token"
+ else:
+ if i == 0:
+ communityAssetName1 = communityToken.name
+ communityAssetDecimals1 = communityToken.decimals
+ communityAmount1 = sendDetails.communityParams.transferDetails[i].amount.toString(10)
+ elif i == 1:
+ communityAssetName2 = communityToken.name
+ communityAssetDecimals2 = communityToken.decimals
+ communityAmount2 = sendDetails.communityParams.transferDetails[i].amount.toString(10)
+
+ if txType == SendType.CommunityDeployOwnerToken:
+ communityOwnerTokenName = sendDetails.communityParams.ownerTokenParameters.name
+ communityMasterTokenName = sendDetails.communityParams.masterTokenParameters.name
+
+ if txType == SendType.CommunityDeployAssets or
+ txType == SendType.CommunityDeployCollectibles:
+ communityDeployedTokenName = sendDetails.communityParams.deploymentParameters.name
+ communityAmountInfinite1 = sendDetails.communityParams.deploymentParameters.infiniteSupply
+ if not communityAmountInfinite1:
+ communityAmount1 = sendDetails.communityParams.deploymentParameters.supply.toString(10)
+
+ if txType == SendType.CommunityRemoteBurn or
+ txType == SendType.CommunityBurn:
+ communityNubmerOfInvolvedAddresses = sendDetails.communityParams.walletAddresses.len
+ if communityNubmerOfInvolvedAddresses == 1: # set address only if all tokens are from the same address
+ communityInvolvedAddress = sendDetails.communityParams.walletAddresses[0]
+
self.view.showTransactionToast(
sendDetails.uuid,
sendDetails.sendType,
@@ -523,6 +605,23 @@ proc sendNotification[T](self: Module[T], status: string, sendDetails: SendDetai
sendDetails.username,
sendDetails.publicKey,
sendDetails.packId,
+ communityId,
+ communityName,
+ communityInvolvedTokens,
+ communityTotalAmount,
+ communityAmount1,
+ communityAmountInfinite1,
+ communityAssetName1,
+ communityAssetDecimals1,
+ communityAmount2,
+ communityAmountInfinite2,
+ communityAssetName2,
+ communityAssetDecimals2,
+ communityInvolvedAddress,
+ communityNubmerOfInvolvedAddresses,
+ communityOwnerTokenName,
+ communityMasterTokenName,
+ communityDeployedTokenName,
status,
error,
)
@@ -1348,16 +1447,26 @@ method resolvedENS*[T](self: Module[T], publicKey: string, address: string, uuid
else:
self.view.emitResolvedENSSignal(publicKey, address, uuid)
-method onCommunityTokenDeploymentStarted*[T](self: Module[T], communityToken: CommunityTokenDto) =
+method onCommunityTokenDeploymentStored*[T](self: Module[T], communityToken: CommunityTokenDto, error: string) =
+ if error != "":
+ error "Cannot update section model, due to error storing community token: ", error
+ return
let item = self.view.model().getItemById(communityToken.communityId)
- if item.id != "":
- item.appendCommunityToken(self.createTokenItem(communityToken))
+ if item.id == "":
+ error "Cannot update section model, due to missing community with id: ", communityId=communityToken.communityId
+ return
+ item.appendCommunityToken(self.createTokenItem(communityToken))
-method onOwnerTokensDeploymentStarted*[T](self: Module[T], ownerToken: CommunityTokenDto, masterToken: CommunityTokenDto) =
+method onOwnerTokensDeploymentStored*[T](self: Module[T], ownerToken: CommunityTokenDto, masterToken: CommunityTokenDto, error: string) =
+ if error != "":
+ error "Cannot update section model, due to error storing owner tokens: ", error
+ return
let item = self.view.model().getItemById(ownerToken.communityId)
- if item.id != "":
- item.appendCommunityToken(self.createTokenItem(ownerToken))
- item.appendCommunityToken(self.createTokenItem(masterToken))
+ if item.id == "":
+ error "Cannot update section model, due to missing community with id: ", communityId=ownerToken.communityId
+ return
+ item.appendCommunityToken(self.createTokenItem(ownerToken))
+ item.appendCommunityToken(self.createTokenItem(masterToken))
method onCommunityTokenRemoved*[T](self: Module[T], communityId: string, chainId: int, address: string) =
let item = self.view.model().getItemById(communityId)
diff --git a/src/app/modules/main/view.nim b/src/app/modules/main/view.nim
index f90bf1d1037..01410cca1e5 100644
--- a/src/app/modules/main/view.nim
+++ b/src/app/modules/main/view.nim
@@ -361,6 +361,23 @@ QtObject:
username: string,
publicKey: string,
packId: string,
+ communityId: string,
+ communityName: string,
+ communityInvolvedTokens: int,
+ communityTotalAmount: string,
+ communityAmount1: string,
+ communityAmountInfinite1: bool,
+ communityAssetName1: string,
+ communityAssetDecimals1: int,
+ communityAmount2: string,
+ communityAmountInfinite2: bool,
+ communityAssetName2: string,
+ communityAssetDecimals2: int,
+ communityInvolvedAddress: string,
+ communityNubmerOfInvolvedAddresses: int,
+ communityOwnerTokenName: string,
+ communityMasterTokenName: string,
+ communityDeployedTokenName: string,
status: string,
error: string) {.signal.}
diff --git a/src/app/modules/main/wallet_section/send/controller.nim b/src/app/modules/main/wallet_section/send/controller.nim
index 365e8fdb138..2087d624091 100644
--- a/src/app/modules/main/wallet_section/send/controller.nim
+++ b/src/app/modules/main/wallet_section/send/controller.nim
@@ -55,7 +55,7 @@ proc delete*(self: Controller) =
proc init*(self: Controller) =
self.events.on(SIGNAL_TRANSACTION_SENT) do(e:Args):
let args = TransactionArgs(e)
- var
+ var
txHash = ""
isApprovalTx = false
if not args.sentTransaction.isNil:
@@ -69,9 +69,6 @@ proc init*(self: Controller) =
if not args.sendDetails.errorResponse.isNil: args.sendDetails.errorResponse.details else: ""
)
- self.events.on(SIGNAL_OWNER_TOKEN_SENT) do(e:Args):
- let args = OwnerTokenSentArgs(e)
- self.delegate.transactionWasSent(args.uuid, args.chainId, approvalTx = false, args.txHash, error = "")
self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED) do(e: Args):
let args = SharedKeycarModuleArgs(e)
@@ -81,6 +78,14 @@ proc init*(self: Controller) =
self.events.on(SIGNAL_SUGGESTED_ROUTES_READY) do(e:Args):
let args = SuggestedRoutesArgs(e)
+ if args.sendType == SendType.CommunityBurn or
+ args.sendType == SendType.CommunityDeployAssets or
+ args.sendType == SendType.CommunityDeployCollectibles or
+ args.sendType == SendType.CommunityDeployOwnerToken or
+ args.sendType == SendType.CommunityMintTokens or
+ args.sendType == SendType.CommunityRemoteBurn or
+ args.sendType == SendType.CommunitySetSignerPubKey:
+ return
self.delegate.suggestedRoutesReady(args.uuid, args.suggestedRoutes, args.errCode, args.errDescription)
self.events.on(SIGNAL_SIGN_ROUTER_TRANSACTIONS) do(e:Args):
diff --git a/src/app/modules/main/wallet_section/send/io_interface.nim b/src/app/modules/main/wallet_section/send/io_interface.nim
index 4df1f267dd3..cf8b37f69a8 100644
--- a/src/app/modules/main/wallet_section/send/io_interface.nim
+++ b/src/app/modules/main/wallet_section/send/io_interface.nim
@@ -59,9 +59,6 @@ method viewDidLoad*(self: AccessInterface) {.base.} =
method authenticateUser*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
-method onUserAuthenticated*(self: AccessInterface, pin: string, password: string, keyUid: string) {.base.} =
- raise newException(ValueError, "No implementation available")
-
method setSelectedReceiveAccountIndex*(self: AccessInterface, index: int) {.base.} =
raise newException(ValueError, "No implementation available")
diff --git a/src/app/modules/main/wallet_section/send/view.nim b/src/app/modules/main/wallet_section/send/view.nim
index 36fab7fe294..c27741abc8a 100644
--- a/src/app/modules/main/wallet_section/send/view.nim
+++ b/src/app/modules/main/wallet_section/send/view.nim
@@ -6,7 +6,7 @@ import app_service/service/transaction/dto as transaction_dto
import app_service/common/utils as common_utils
import app_service/service/eth/utils as eth_utils
-from backend/eth import ExtraKeyPackId
+from backend/wallet import ExtraKeyPackId
QtObject:
type
diff --git a/src/app/modules/main/wallet_section/send_new/controller.nim b/src/app/modules/main/wallet_section/send_new/controller.nim
index 21b8bb7003a..1ca24d3fc43 100644
--- a/src/app/modules/main/wallet_section/send_new/controller.nim
+++ b/src/app/modules/main/wallet_section/send_new/controller.nim
@@ -63,9 +63,6 @@ proc init*(self: Controller) =
if not args.sendDetails.errorResponse.isNil: args.sendDetails.errorResponse.details else: ""
)
- self.events.on(SIGNAL_OWNER_TOKEN_SENT) do(e:Args):
- let args = OwnerTokenSentArgs(e)
- self.delegate.transactionWasSent(args.uuid, args.chainId, approvalTx = false, args.txHash, error = "")
self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED) do(e: Args):
let args = SharedKeycarModuleArgs(e)
diff --git a/src/app/modules/main/wallet_section/send_new/view.nim b/src/app/modules/main/wallet_section/send_new/view.nim
index 6f57a4ec725..d2bef8d5a7c 100644
--- a/src/app/modules/main/wallet_section/send_new/view.nim
+++ b/src/app/modules/main/wallet_section/send_new/view.nim
@@ -4,7 +4,7 @@ import ./io_interface, ./path_model, ./path_item
import app_service/common/utils as common_utils
import app_service/service/eth/utils as eth_utils
import app_service/service/transaction/dto as transaction_dto
-from backend/eth import ExtraKeyPackId
+from backend/wallet import ExtraKeyPackId
export path_model
diff --git a/src/app_service/service/community_tokens/async_tasks.nim b/src/app_service/service/community_tokens/async_tasks.nim
index b86cb2c61b2..7658ad8cd9f 100644
--- a/src/app_service/service/community_tokens/async_tasks.nim
+++ b/src/app_service/service/community_tokens/async_tasks.nim
@@ -1,21 +1,11 @@
import stint, Tables
-include ../../common/json_utils
-import ../../../backend/eth
-import ../../../backend/community_tokens
-import ../../../backend/collectibles
-include ../../../app/core/tasks/common
-import ../../../app/core/tasks/qt
-import ../transaction/dto
+
+import backend/collectibles
+import app/core/tasks/qt
import ../community/dto/community
-proc tableToJsonArray[A, B](t: var Table[A, B]): JsonNode =
- let data = newJArray()
- for k,v in t:
- data.elems.add(%*{
- "key": k,
- "value": v
- })
- return data
+include app/core/tasks/common
+include app_service/common/json_utils
proc balanceInfoToTable(jsonNode: JsonNode): Table[string, UInt256] =
for chainBalancesPair in jsonNode.pairs():
@@ -26,203 +16,6 @@ proc balanceInfoToTable(jsonNode: JsonNode): Table[string, UInt256] =
result[addressTokenBalancesPair.key.toUpper] = amount
break
-type
- AsyncDeployOwnerContractsFeesArg = ref object of QObjectTaskArg
- chainId: int
- addressFrom: string
- requestId: string
- ownerParams: JsonNode
- masterParams: JsonNode
- communityId: string
- signerPubKey: string
-
-proc asyncGetDeployOwnerContractsFeesTask(argEncoded: string) {.gcsafe, nimcall.} =
- let arg = decode[AsyncDeployOwnerContractsFeesArg](argEncoded)
- try:
- var gasTable: Table[ContractTuple, int] # gas per contract
- var feeTable: Table[int, SuggestedFeesDto] # fees for chain
-
- let estimations = community_tokens.deployOwnerTokenEstimate(arg.chainId, arg.addressFrom, arg.ownerParams, arg.masterParams, arg.communityId, arg.signerPubKey).result
- gasTable[(arg.chainId, "")] = estimations{"gasUnits"}.getInt
- feeTable[arg.chainId] = estimations{"suggestedFees"}.toSuggestedFeesDto()
-
- arg.finish(%* {
- "feeTable": tableToJsonArray(feeTable),
- "gasTable": tableToJsonArray(gasTable),
- "chainId": arg.chainId,
- "addressFrom": arg.addressFrom,
- "error": "",
- "requestId": arg.requestId,
- })
- except Exception as e:
- arg.finish(%* {
- "error": e.msg,
- "requestId": arg.requestId,
- })
-
-type
- AsyncGetDeployFeesArg = ref object of QObjectTaskArg
- chainId: int
- addressFrom: string
- tokenType: TokenType
- requestId: string
-
-proc asyncGetDeployFeesTask(argEncoded: string) {.gcsafe, nimcall.} =
- let arg = decode[AsyncGetDeployFeesArg](argEncoded)
- try:
- var gasTable: Table[ContractTuple, int] # gas per contract
- var feeTable: Table[int, SuggestedFeesDto] # fees for chain
-
- let estimations = if arg.tokenType == TokenType.ERC721: community_tokens.deployCollectiblesEstimate(arg.chainId, arg.addressFrom).result
- else: community_tokens.deployAssetsEstimate(arg.chainId, arg.addressFrom).result
- gasTable[(arg.chainId, "")] = estimations{"gasUnits"}.getInt
- feeTable[arg.chainId] = estimations{"suggestedFees"}.toSuggestedFeesDto()
-
- arg.finish(%* {
- "feeTable": tableToJsonArray(feeTable),
- "gasTable": tableToJsonArray(gasTable),
- "chainId": arg.chainId,
- "addressFrom": arg.addressFrom,
- "error": "",
- "requestId": arg.requestId,
- })
- except Exception as e:
- arg.finish(%* {
- "error": e.msg,
- "requestId": arg.requestId,
- })
-
-type
- AsyncSetSignerFeesArg = ref object of QObjectTaskArg
- chainId: int
- contractAddress: string
- addressFrom: string
- newSignerPubKey: string
- requestId: string
-
-proc asyncSetSignerFeesTask(argEncoded: string) {.gcsafe, nimcall.} =
- let arg = decode[AsyncSetSignerFeesArg](argEncoded)
- try:
- var gasTable: Table[ContractTuple, int] # gas per contract
- var feeTable: Table[int, SuggestedFeesDto] # fees for chain
-
- let estimations = community_tokens.estimateSetSignerPubKey(arg.chainId, arg.contractAddress, arg.addressFrom, arg.newSignerPubKey).result
- gasTable[(arg.chainId, arg.contractAddress)] = estimations{"gasUnits"}.getInt
- feeTable[arg.chainId] = estimations{"suggestedFees"}.toSuggestedFeesDto()
-
- arg.finish(%* {
- "feeTable": tableToJsonArray(feeTable),
- "gasTable": tableToJsonArray(gasTable),
- "chainId": arg.chainId,
- "addressFrom": arg.addressFrom,
- "error": "",
- "requestId": arg.requestId,
- })
- except Exception as e:
- arg.finish(%* {
- "error": e.msg,
- "requestId": arg.requestId,
- })
-
-type
- AsyncGetRemoteBurnFees = ref object of QObjectTaskArg
- chainId: int
- contractAddress: string
- tokenIds: seq[UInt256]
- addressFrom: string
- requestId: string
-
-proc asyncGetRemoteBurnFeesTask(argEncoded: string) {.gcsafe, nimcall.} =
- let arg = decode[AsyncGetRemoteBurnFees](argEncoded)
- try:
- var gasTable: Table[ContractTuple, int] # gas per contract
- var feeTable: Table[int, SuggestedFeesDto] # fees for chain
-
- let estimations = community_tokens.estimateRemoteBurn(arg.chainId, arg.contractAddress, arg.addressFrom, arg.tokenIds).result
- gasTable[(arg.chainId, arg.contractAddress)] = estimations{"gasUnits"}.getInt
- feeTable[arg.chainId] = estimations{"suggestedFees"}.toSuggestedFeesDto()
-
- arg.finish(%* {
- "feeTable": tableToJsonArray(feeTable),
- "gasTable": tableToJsonArray(gasTable),
- "chainId": arg.chainId,
- "addressFrom": arg.addressFrom,
- "error": "",
- "requestId": arg.requestId,
- })
- except Exception as e:
- arg.finish(%* {
- "error": e.msg,
- "requestId": arg.requestId,
- })
-
-type
- AsyncGetBurnFees = ref object of QObjectTaskArg
- chainId: int
- contractAddress: string
- amount: Uint256
- addressFrom: string
- requestId: string
-
-proc asyncGetBurnFeesTask(argEncoded: string) {.gcsafe, nimcall.} =
- let arg = decode[AsyncGetBurnFees](argEncoded)
- try:
- var gasTable: Table[ContractTuple, int] # gas per contract
- var feeTable: Table[int, SuggestedFeesDto] # fees for chain
-
- let estimations = community_tokens.estimateBurn(arg.chainId, arg.contractAddress, arg.addressFrom, arg.amount).result
- gasTable[(arg.chainId, arg.contractAddress)] = estimations{"gasUnits"}.getInt
- feeTable[arg.chainId] = estimations{"suggestedFees"}.toSuggestedFeesDto()
-
- arg.finish(%* {
- "feeTable": tableToJsonArray(feeTable),
- "gasTable": tableToJsonArray(gasTable),
- "chainId": arg.chainId,
- "addressFrom": arg.addressFrom,
- "error": "",
- "requestId": arg.requestId
- })
- except Exception as e:
- arg.finish(%* {
- "error": e.msg,
- "requestId": arg.requestId,
- })
-
-type
- AsyncGetMintFees = ref object of QObjectTaskArg
- collectiblesAndAmounts: seq[CommunityTokenAndAmount]
- walletAddresses: seq[string]
- addressFrom: string
- requestId: string
-
-proc asyncGetMintFeesTask(argEncoded: string) {.gcsafe, nimcall.} =
- let arg = decode[AsyncGetMintFees](argEncoded)
- try:
- var gasTable: Table[ContractTuple, int] # gas per contract
- var feeTable: Table[int, SuggestedFeesDto] # fees for chain
- for collectibleAndAmount in arg.collectiblesAndAmounts:
- # get fees if we do not have for this chain yet
- let chainId = collectibleAndAmount.communityToken.chainId
- # get gas for smart contract
- let estimations = community_tokens.estimateMintTokens(chainId,
- collectibleAndAmount.communityToken.address, arg.addressFrom,
- arg.walletAddresses, collectibleAndAmount.amount).result
- gasTable[(chainId, collectibleAndAmount.communityToken.address)] = estimations{"gasUnits"}.getInt
- feeTable[chainId] = estimations{"suggestedFees"}.toSuggestedFeesDto()
- arg.finish(%* {
- "feeTable": tableToJsonArray(feeTable),
- "gasTable": tableToJsonArray(gasTable),
- "addressFrom": arg.addressFrom,
- "error": "",
- "requestId": arg.requestId
- })
- except Exception as e:
- let output = %* {
- "error": e.msg,
- "requestId": arg.requestId
- }
- arg.finish(output)
-
type
FetchCollectibleOwnersArg = ref object of QObjectTaskArg
chainId*: int
diff --git a/src/app_service/service/community_tokens/dto/deployment_parameters.nim b/src/app_service/service/community_tokens/dto/deployment_parameters.nim
index b4e78c49820..e9b1ec5faaa 100644
--- a/src/app_service/service/community_tokens/dto/deployment_parameters.nim
+++ b/src/app_service/service/community_tokens/dto/deployment_parameters.nim
@@ -1,6 +1,9 @@
import json, stint
-import ../../../../backend/interpret/cropped_image
-import ../../../common/types
+import backend/interpret/cropped_image
+import app_service/common/types
+
+include app_service/common/json_utils
+from app_service/common/account_constants import ZERO_ADDRESS
type
DeploymentParameters* = object
@@ -30,11 +33,43 @@ proc `%`*(x: DeploymentParameters): JsonNode =
result["remoteSelfDestruct"] = %x.remoteSelfDestruct
result["tokenUri"] = %x.tokenUri
result["decimals"] = %x.decimals
- result["ownerTokenAddress"] = %x.ownerTokenAddress
- result["masterTokenAddress"] = %x.masterTokenAddress
+ var address = ZERO_ADDRESS
+ if x.ownerTokenAddress.len > 0:
+ address = x.ownerTokenAddress
+ result["ownerTokenAddress"] = %address
+ address = ZERO_ADDRESS
+ if x.masterTokenAddress.len > 0:
+ address = x.masterTokenAddress
+ result["masterTokenAddress"] = %address
result["description"] = %x.description
result["communityId"] = %x.communityId
if x.croppedImageJson != "":
result["croppedImage"] = %newCroppedImage(x.croppedImageJson)
result["base64image"] = %x.base64image
- result["tokenType"] = %x.tokenType
\ No newline at end of file
+ result["tokenType"] = %x.tokenType
+
+proc toDeploymentParameters*(jsonObj: JsonNode): DeploymentParameters =
+ result = DeploymentParameters()
+ discard jsonObj.getProp("name", result.name)
+ discard jsonObj.getProp("symbol", result.symbol)
+ discard jsonObj.getProp("infiniteSupply", result.infiniteSupply)
+ discard jsonObj.getProp("transferable", result.transferable)
+ discard jsonObj.getProp("remoteSelfDestruct", result.remoteSelfDestruct)
+ discard jsonObj.getProp("tokenUri", result.tokenUri)
+ discard jsonObj.getProp("decimals", result.decimals)
+ discard jsonObj.getProp("ownerTokenAddress", result.ownerTokenAddress)
+ discard jsonObj.getProp("masterTokenAddress", result.masterTokenAddress)
+ discard jsonObj.getProp("description", result.description)
+ discard jsonObj.getProp("communityId", result.communityId)
+ discard jsonObj.getProp("base64image", result.base64image)
+ var tmpObj: JsonNode
+ if jsonObj.getProp("supply", tmpObj):
+ result.supply = stint.fromHex(UInt256, tmpObj.getStr)
+ if jsonObj.getProp("croppedImage", tmpObj):
+ result.croppedImageJson = tmpObj.getStr
+ if jsonObj.getProp("tokenType", tmpObj):
+ let txType = tmpObj.getInt
+ if txType < ord(low(TokenType)) or txType >= ord(high(TokenType)):
+ result.tokenType = TokenType.Native
+ else:
+ result.tokenType = TokenType(txType)
\ No newline at end of file
diff --git a/src/app_service/service/community_tokens/service.nim b/src/app_service/service/community_tokens/service.nim
index 94d9311f46f..7511e2ac6fe 100644
--- a/src/app_service/service/community_tokens/service.nim
+++ b/src/app_service/service/community_tokens/service.nim
@@ -1,34 +1,37 @@
import NimQml, Tables, chronicles, json, stint, strutils, sugar, sequtils, stew/shims/strformat, times
-import ../../../app/global/global_singleton
-import ../../../app/core/eventemitter
-import ../../../app/core/tasks/[qt, threadpool]
-import ../../../app/core/signals/types
-
-import ../../../app/modules/shared_models/currency_amount
-
-import ../../../backend/collectibles as collectibles_backend
-import ../../../backend/communities as communities_backend
-import ../../../backend/community_tokens as tokens_backend
-import ../transaction/service as transaction_service
-import ../token/service as token_service
-import ../settings/service as settings_service
-import ../wallet_account/service as wallet_account_service
-import ../activity_center/service as ac_service
-import ../community/service as community_service
-import app_service/service/currency/service as currency_service
-import ../ens/utils as ens_utils
-import ../eth/dto/transaction
-from backend/collectibles_types import CollectibleOwner
-import ../../../backend/backend
-import ../../../backend/response_type
+import app/global/global_singleton
+import app/core/eventemitter
+import app/core/tasks/[qt, threadpool]
+import app/core/signals/types
-import ../../common/activity_center
-import ../../common/conversion
-import ../../common/account_constants
-import ../../common/utils as common_utils
-import ../community/dto/community
-import ../contacts/dto/contacts
+import app/modules/shared_models/currency_amount
+
+import backend/backend
+import backend/response_type
+import backend/wallet
+import backend/collectibles as collectibles_backend
+import backend/communities as communities_backend
+import backend/community_tokens as tokens_backend
+from backend/collectibles_types import CollectibleOwner
+
+import app_service/service/network/service as network_service
+import app_service/service/transaction/service as transaction_service
+import app_service/service/token/service as token_service
+import app_service/service/settings/service as settings_service
+import app_service/service/wallet_account/service as wallet_account_service
+import app_service/service/activity_center/service as ac_service
+import app_service/service/community/service as community_service
+import app_service/service/currency/service as currency_service
+import app_service/service/ens/utils as ens_utils
+import app_service/service/eth/utils as eth_utils
+import app_service/service/eth/dto/transaction
+import app_service/service/community/dto/community
+import app_service/service/contacts/dto/contacts
+import app_service/common/activity_center
+import app_service/common/types
+import app_service/common/account_constants
+import app_service/common/utils as common_utils
import ./community_collectible_owner
import ./dto/deployment_parameters
@@ -39,10 +42,10 @@ export community_token
export deployment_parameters
export community_token_owner
-const ethSymbol = "ETH"
-
include async_tasks
+const ethSymbol = "ETH"
+
logScope:
topics = "community-tokens-service"
@@ -63,20 +66,17 @@ type
transactionHash*: string
deployState*: DeployState
-type
- CommunityTokensArgs* = ref object of Args
- communityTokens*: seq[CommunityTokenDto]
-
type
CommunityTokenDeploymentArgs* = ref object of Args
communityToken*: CommunityTokenDto
transactionHash*: string
+ error*: string
type
OwnerTokenDeploymentArgs* = ref object of Args
ownerToken*: CommunityTokenDto
masterToken*: CommunityTokenDto
- transactionHash*: string
+ error*: string
type
CommunityTokenRemovedArgs* = ref object of Args
@@ -104,52 +104,6 @@ type
transactionHash*: string
status*: ContractTransactionStatus
-type
- ComputeFeeArgs* = ref object of Args
- ethCurrency*: CurrencyAmount
- fiatCurrency*: CurrencyAmount
- errorCode*: ComputeFeeErrorCode
- contractUniqueKey*: string # used for minting
- requestId*: string
-
-type
- SetSignerArgs* = ref object of Args
- transactionHash*: string
- status*: ContractTransactionStatus
- communityId*: string
- chainId*: int
-
-proc `%`*(self: ComputeFeeArgs): JsonNode =
- result = %* {
- "ethFee": if self.ethCurrency == nil: newCurrencyAmount().toJsonNode() else: self.ethCurrency.toJsonNode(),
- "fiatFee": if self.fiatCurrency == nil: newCurrencyAmount().toJsonNode() else: self.fiatCurrency.toJsonNode(),
- "errorCode": self.errorCode.int,
- "contractUniqueKey": self.contractUniqueKey,
- }
-
-proc computeFeeArgsToJsonArray(args: seq[ComputeFeeArgs]): JsonNode =
- let arr = newJArray()
- for arg in args:
- arr.elems.add(%arg)
- return arr
-
-type
- AirdropFeesArgs* = ref object of Args
- fees*: seq[ComputeFeeArgs]
- totalEthFee*: CurrencyAmount
- totalFiatFee*: CurrencyAmount
- errorCode*: ComputeFeeErrorCode
- requestId*: string
-
-proc `%`*(self: AirdropFeesArgs): JsonNode =
- result = %* {
- "fees": computeFeeArgsToJsonArray(self.fees),
- "totalEthFee": if self.totalEthFee == nil: newCurrencyAmount().toJsonNode() else: self.totalEthFee.toJsonNode(),
- "totalFiatFee": if self.totalFiatFee == nil: newCurrencyAmount().toJsonNode() else: self.totalFiatFee.toJsonNode(),
- "errorCode": self.errorCode.int,
- "requestId": self.requestId,
- }
-
type
CommunityTokenOwnersArgs* = ref object of Args
communityId*: string
@@ -253,12 +207,7 @@ proc toContractDetails*(jsonObj: JsonNode): ContractDetails =
# Signals which may be emitted by this service:
const SIGNAL_COMMUNITY_TOKEN_DEPLOY_STATUS* = "communityTokens-communityTokenDeployStatus"
-const SIGNAL_COMMUNITY_TOKEN_DEPLOYMENT_STARTED* = "communityTokens-communityTokenDeploymentStarted"
-const SIGNAL_COMPUTE_DEPLOY_FEE* = "communityTokens-computeDeployFee"
-const SIGNAL_COMPUTE_SET_SIGNER_FEE* = "communityTokens-computeSetSignerFee"
-const SIGNAL_COMPUTE_SELF_DESTRUCT_FEE* = "communityTokens-computeSelfDestructFee"
-const SIGNAL_COMPUTE_BURN_FEE* = "communityTokens-computeBurnFee"
-const SIGNAL_COMPUTE_AIRDROP_FEE* = "communityTokens-computeAirdropFee"
+const SIGNAL_COMMUNITY_TOKEN_DEPLOYMENT_STORED* = "communityTokens-communityTokenDeploymentStored"
const SIGNAL_COMMUNITY_TOKEN_OWNERS_FETCHED* = "communityTokens-communityTokenOwnersFetched"
const SIGNAL_COMMUNITY_TOKEN_OWNERS_LOADING_FAILED* = "communityTokens-communityTokenOwnersLoadingFailed"
const SIGNAL_REMOTE_DESTRUCT_STATUS* = "communityTokens-communityTokenRemoteDestructStatus"
@@ -268,10 +217,9 @@ const SIGNAL_AIRDROP_STATUS* = "communityTokens-airdropStatus"
const SIGNAL_REMOVE_COMMUNITY_TOKEN_FAILED* = "communityTokens-removeCommunityTokenFailed"
const SIGNAL_COMMUNITY_TOKEN_REMOVED* = "communityTokens-communityTokenRemoved"
const SIGNAL_OWNER_TOKEN_DEPLOY_STATUS* = "communityTokens-ownerTokenDeployStatus"
-const SIGNAL_OWNER_TOKEN_DEPLOYMENT_STARTED* = "communityTokens-ownerTokenDeploymentStarted"
+const SIGNAL_OWNER_TOKEN_DEPLOYMENT_STORED* = "communityTokens-ownerTokenDeploymentStored"
const SIGNAL_COMMUNITY_TOKENS_DETAILS_LOADED* = "communityTokens-communityTokenDetailsLoaded"
const SIGNAL_OWNER_TOKEN_RECEIVED* = "communityTokens-ownerTokenReceived"
-const SIGNAL_SET_SIGNER_STATUS* = "communityTokens-setSignerStatus"
const SIGNAL_FINALISE_OWNERSHIP_STATUS* = "communityTokens-finaliseOwnershipStatus"
const SIGNAL_OWNER_TOKEN_OWNER_ADDRESS* = "communityTokens-ownerTokenOwnerAddress"
const SIGNAL_COMMUNITY_TOKEN_RECEIVED* = "communityTokens-communityTokenReceived"
@@ -281,6 +229,7 @@ QtObject:
Service* = ref object of QObject
events: EventEmitter
threadpool: ThreadPool
+ networkService: network_service.Service
transactionService: transaction_service.Service
tokenService: token_service.Service
settingsService: settings_service.Service
@@ -314,7 +263,6 @@ QtObject:
proc restartTokenHoldersTimer(self: Service, chainId: int, contractAddress: string)
proc refreshTokenHolders(self: Service, token: CommunityTokenDto)
-
proc delete*(self: Service) =
delete(self.tokenHoldersTimer)
self.QObject.delete
@@ -322,6 +270,7 @@ QtObject:
proc newService*(
events: EventEmitter,
threadpool: ThreadPool,
+ networkService: network_service.Service,
transactionService: transaction_service.Service,
tokenService: token_service.Service,
settingsService: settings_service.Service,
@@ -334,6 +283,7 @@ QtObject:
result.QObject.setup
result.events = events
result.threadpool = threadpool
+ result.networkService = networkService
result.transactionService = transactionService
result.tokenService = tokenService
result.settingsService = settingsService
@@ -357,6 +307,11 @@ QtObject:
discard tokens_backend.removeCommunityToken(chainId, contractAddress)
self.communityTokensCache = self.communityTokensCache.filter(x => ((x.chainId != chainId) or (x.address != contractAddress)))
+ proc getCommunityTokenFromCache*(self: Service, chainId: int, address: string): CommunityTokenDto =
+ for token in self.communityTokensCache:
+ if token.chainId == chainId and cmpIgnoreCase(token.address, address) == 0:
+ return token
+
# end of cache functions
proc processReceivedCollectiblesWalletEvent(self: Service, jsonMessage: string, accounts: seq[string]) =
@@ -486,11 +441,6 @@ QtObject:
else:
error "Signer not set"
- let data = SetSignerArgs(status: if signalArgs.success: ContractTransactionStatus.Completed else: ContractTransactionStatus.Failed,
- chainId: chainId,
- transactionHash: signalArgs.hash,
- communityId: communityId)
- self.events.emit(SIGNAL_SET_SIGNER_STATUS, data)
# TODO move AC notifications to status-go
let response = if signalArgs.success: tokens_backend.registerReceivedOwnershipNotification(communityId) else: tokens_backend.registerSetSignerFailedNotification(communityId)
@@ -604,17 +554,17 @@ QtObject:
if receivedData.errorString != "":
error "Community token transaction has finished but the system error occured. Probably state of the token in database is broken.",
errorString=receivedData.errorString, transactionHash=receivedData.hash, transactionSuccess=receivedData.success
- if receivedData.transactionType == $PendingTransactionTypeDto.SetSignerPublicKey:
+ if receivedData.sendType == int(SendType.CommunitySetSignerPubKey):
self.processSetSignerTransactionEvent(receivedData)
- elif receivedData.transactionType == $PendingTransactionTypeDto.AirdropCommunityToken:
+ elif receivedData.sendType == int(SendType.CommunityMintTokens):
self.processAirdropTransactionEvent(receivedData)
- elif receivedData.transactionType == $PendingTransactionTypeDto.RemoteDestructCollectible:
+ elif receivedData.sendType == int(SendType.CommunityRemoteBurn):
self.processRemoteDestructEvent(receivedData)
- elif receivedData.transactionType == $PendingTransactionTypeDto.BurnCommunityToken:
+ elif receivedData.sendType == int(SendType.CommunityBurn):
self.processBurnEvent(receivedData)
- elif receivedData.transactionType == $PendingTransactionTypeDto.DeployCommunityToken:
+ elif receivedData.sendType == int(SendType.CommunityDeployAssets) or receivedData.sendType == int(SendType.CommunityDeployCollectibles):
self.processDeployCommunityToken(receivedData)
- elif receivedData.transactionType == $PendingTransactionTypeDto.DeployOwnerToken:
+ elif receivedData.sendType == int(SendType.CommunityDeployOwnerToken):
self.processDeployOwnerToken(receivedData)
proc buildTransactionDataDto(self: Service, addressFrom: string, chainId: int, contractAddress: string): TransactionDataDto =
@@ -631,68 +581,62 @@ QtObject:
proc temporaryOwnerContractAddress*(ownerContractTransactionHash: string): string =
return ownerContractTransactionHash & "-owner"
- proc deployOwnerContracts*(self: Service, communityId: string, addressFrom: string, password: string,
- ownerDeploymentParams: DeploymentParameters, masterDeploymentParams: DeploymentParameters, chainId: int) =
+ proc storeDeployedOwnerContract*(self: Service, addressFrom: string, chainId: int, txHash: string,
+ ownerDeploymentParams: DeploymentParameters, masterDeploymentParams: DeploymentParameters) =
+ var data = OwnerTokenDeploymentArgs(
+ ownerToken: CommunityTokenDto(
+ communityId: ownerDeploymentParams.communityId,
+ name: ownerDeploymentParams.name,
+ symbol: ownerDeploymentParams.symbol,
+ tokenType: ownerDeploymentParams.tokenType,
+ ),
+ masterToken: CommunityTokenDto(
+ communityId: masterDeploymentParams.communityId,
+ name: masterDeploymentParams.name,
+ symbol: masterDeploymentParams.symbol,
+ tokenType: masterDeploymentParams.tokenType,
+ ),
+ )
try:
- let txData = self.buildTransactionDataDto(addressFrom, chainId, "")
- if txData.source == parseAddress(ZERO_ADDRESS):
- return
- # set my pub key as signer
- let signerPubKey = singletonInstance.userProfile.getPubKey()
+ let response = tokens_backend.storeDeployedOwnerToken(addressFrom, chainId, txHash, %ownerDeploymentParams, %masterDeploymentParams)
+ if not response.error.isNil:
+ raise newException(CatchableError, response.error.message)
- # deploy contract
- let response = tokens_backend.deployOwnerToken(chainId, %ownerDeploymentParams, %masterDeploymentParams,
- signerPubKey, %txData, common_utils.hashPassword(password))
- let transactionHash = response.result["transactionHash"].getStr()
let deployedOwnerToken = toCommunityTokenDto(response.result["ownerToken"])
let deployedMasterToken = toCommunityTokenDto(response.result["masterToken"])
- debug "Deployment transaction hash ", transactionHash=transactionHash
-
self.communityTokensCache.add(deployedOwnerToken)
self.communityTokensCache.add(deployedMasterToken)
-
- let data = OwnerTokenDeploymentArgs(ownerToken: deployedOwnerToken, masterToken: deployedMasterToken, transactionHash: transactionHash)
- self.events.emit(SIGNAL_OWNER_TOKEN_DEPLOYMENT_STARTED, data)
-
- except RpcException:
- error "Error deploying owner contract", message = getCurrentExceptionMsg()
- let data = OwnerTokenDeployedStatusArgs(communityId: communityId,
- deployState: DeployState.Failed)
- self.events.emit(SIGNAL_OWNER_TOKEN_DEPLOY_STATUS, data)
-
- proc deployContract*(self: Service, communityId: string, addressFrom: string, password: string, deploymentParams: DeploymentParameters, chainId: int) =
+ data.ownerToken = deployedOwnerToken
+ data.masterToken = deployedMasterToken
+ except Exception as e:
+ data.error = e.msg
+ error "Error storing deployed owner contract", msg = e.msg
+ self.events.emit(SIGNAL_OWNER_TOKEN_DEPLOYMENT_STORED, data)
+
+ proc storeDeployedContract*(self: Service, sendType: SendType, addressFrom: string, addressTo: string, chainId: int,
+ txHash: string, deploymentParams: DeploymentParameters) =
+ var data = CommunityTokenDeploymentArgs(
+ transactionHash: txHash
+ )
try:
- let txData = self.buildTransactionDataDto(addressFrom, chainId, "")
- if txData.source == parseAddress(ZERO_ADDRESS):
- return
-
var response: RpcResponse[JsonNode]
- case deploymentParams.tokenType
- of TokenType.ERC721:
- response = tokens_backend.deployCollectibles(chainId, %deploymentParams, %txData, common_utils.hashPassword(password))
- of TokenType.ERC20:
- response = tokens_backend.deployAssets(chainId, %deploymentParams, %txData, common_utils.hashPassword(password))
+ case sendType
+ of SendType.CommunityDeployAssets:
+ response = tokens_backend.storeDeployedAssets(addressFrom, addressTo, chainId, txHash, %deploymentParams)
+ of SendType.CommunityDeployCollectibles:
+ response = tokens_backend.storeDeployedCollectibles(addressFrom, addressTo, chainId, txHash, %deploymentParams)
else:
- error "Contract deployment error - unknown token type", tokenType=deploymentParams.tokenType
- return
+ let err = "unexpected send type " & $sendType
+ raise newException(CatchableError, err)
- let contractAddress = response.result["contractAddress"].getStr()
- let transactionHash = response.result["transactionHash"].getStr()
let deployedCommunityToken = toCommunityTokenDto(response.result["communityToken"])
- debug "Deployed contract address ", contractAddress=contractAddress
- debug "Deployment transaction hash ", transactionHash=transactionHash
-
- # add to cache
self.communityTokensCache.add(deployedCommunityToken)
- let data = CommunityTokenDeploymentArgs(communityToken: deployedCommunityToken, transactionHash: transactionHash)
- self.events.emit(SIGNAL_COMMUNITY_TOKEN_DEPLOYMENT_STARTED, data)
-
- except RpcException:
- error "Error deploying contract", message = getCurrentExceptionMsg()
- let data = CommunityTokenDeployedStatusArgs(communityId: communityId,
- deployState: DeployState.Failed)
- self.events.emit(SIGNAL_COMMUNITY_TOKEN_DEPLOY_STATUS, data)
+ data.communityToken = deployedCommunityToken
+ except Exception as e:
+ data.error = e.msg
+ error "Error storing deployed contract", msg = e.msg
+ self.events.emit(SIGNAL_COMMUNITY_TOKEN_DEPLOYMENT_STORED, data)
proc getCommunityTokens*(self: Service, communityId: string): seq[CommunityTokenDto] =
return self.communityTokensCache.filter(x => (x.communityId == communityId))
@@ -833,40 +777,41 @@ QtObject:
except RpcException:
error "Error getting remote destructed amount", message = getCurrentExceptionMsg()
- proc airdropTokens*(self: Service, communityId: string, password: string, collectiblesAndAmounts: seq[CommunityTokenAndAmount], walletAddresses: seq[string], addressFrom: string) =
+ proc computeAirdropFee*(self: Service, uuid: string, collectiblesAndAmounts: seq[CommunityTokenAndAmount], walletAddresses: seq[string], addressFrom: string) =
+ let sendType = SendType.CommunityMintTokens
try:
+ if collectiblesAndAmounts.len == 0:
+ raise newException(CatchableError, "no collectibles to airdrop")
+ let chainId = collectiblesAndAmounts[0].communityToken.chainId
+ let communityId = collectiblesAndAmounts[0].communityToken.communityId
+ var transferDetails: seq[JsonNode]
for collectibleAndAmount in collectiblesAndAmounts:
- let txData = self.buildTransactionDataDto(addressFrom, collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address)
- if txData.source == parseAddress(ZERO_ADDRESS):
- return
- debug "Airdrop tokens ", chainId=collectibleAndAmount.communityToken.chainId, address=collectibleAndAmount.communityToken.address, amount=collectibleAndAmount.amount
- let response = tokens_backend.mintTokens(collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address, %txData, common_utils.hashPassword(password), walletAddresses, collectibleAndAmount.amount)
- let transactionHash = response.result.getStr()
- debug "Airdrop transaction hash ", transactionHash=transactionHash
-
- var data = AirdropArgs(communityToken: collectibleAndAmount.communityToken, transactionHash: transactionHash, status: ContractTransactionStatus.InProgress)
- self.events.emit(SIGNAL_AIRDROP_STATUS, data)
- except RpcException:
- error "Error airdropping tokens", message = getCurrentExceptionMsg()
-
- proc computeAirdropFee*(self: Service, collectiblesAndAmounts: seq[CommunityTokenAndAmount], walletAddresses: seq[string], addressFrom: string, requestId: string) =
- try:
- self.tempTokensAndAmounts = collectiblesAndAmounts
- let arg = AsyncGetMintFees(
- tptr: asyncGetMintFeesTask,
- vptr: cast[uint](self.vptr),
- slot: "onAirdropFees",
- collectiblesAndAmounts: collectiblesAndAmounts,
- walletAddresses: walletAddresses,
- addressFrom: addressFrom,
- requestId: requestId
+ let amountHex = "0x" & eth_utils.stripLeadingZeros(collectibleAndAmount.amount.toHex)
+ transferDetails.add(%* {
+ "tokenContractAddress": collectibleAndAmount.communityToken.address,
+ "amount": amountHex,
+ })
+ self.transactionService.suggestedCommunityRoutes(
+ uuid,
+ sendType,
+ chainId,
+ addressFrom,
+ communityId,
+ signerPubKey = "",
+ tokenIds = @[],
+ walletAddresses,
+ transferDetails
)
- self.threadpool.start(arg)
except Exception as e:
- error "Error loading airdrop fees", msg = e.msg
- var dataToEmit = AirdropFeesArgs()
- dataToEmit.errorCode = ComputeFeeErrorCode.Other
- self.events.emit(SIGNAL_COMPUTE_AIRDROP_FEE, dataToEmit)
+ error "Error loading deploy owner fees", msg = e.msg
+ self.transactionService.emitSuggestedRoutesReadySignal(
+ SuggestedRoutesArgs(
+ uuid: uuid,
+ sendType: sendType,
+ errCode: $InternalErrorCode,
+ errDescription: e.msg
+ )
+ )
proc getFiatValue(self: Service, cryptoBalance: float, cryptoSymbol: string): float =
if (cryptoSymbol == ""):
@@ -879,62 +824,102 @@ QtObject:
for token in allTokens:
if common_utils.contractUniqueKey(token.chainId, token.address) == contractUniqueKey:
return token
+ raise newException(CatchableError, "Contract not found")
- proc computeDeployFee*(self: Service, chainId: int, accountAddress: string, tokenType: TokenType, requestId: string) =
+ proc computeDeployTokenFee*(self: Service, uuid: string, chainId: int, accountFrom: string, communityId: string, deploymentParams: DeploymentParameters) =
+ var sendType = SendType.CommunityDeployAssets
+ if deploymentParams.tokenType == TokenType.ERC721:
+ sendType = SendType.CommunityDeployCollectibles
try:
- if tokenType != TokenType.ERC20 and tokenType != TokenType.ERC721:
- error "Error loading fees: unknown token type", tokenType = tokenType
- return
- let arg = AsyncGetDeployFeesArg(
- tptr: asyncGetDeployFeesTask,
- vptr: cast[uint](self.vptr),
- slot: "onDeployFees",
- chainId: chainId,
- addressFrom: accountAddress,
- tokenType: tokenType,
- requestId: requestId
+ self.transactionService.suggestedCommunityRoutes(
+ uuid,
+ sendType,
+ chainId,
+ accountFrom,
+ communityId,
+ signerPubKey = "",
+ tokenIds = @[],
+ walletAddresses = @[],
+ transferDetails = @[],
+ signature = "",
+ ownerTokenParameters = JsonNode(),
+ masterTokenParameters = JsonNode(),
+ %deploymentParams
)
- self.threadpool.start(arg)
except Exception as e:
- #TODO: handle error - emit error signal
- error "Error loading fees", msg = e.msg
+ error "Error loading deploy owner fees", msg = e.msg
+ self.transactionService.emitSuggestedRoutesReadySignal(
+ SuggestedRoutesArgs(
+ uuid: uuid,
+ sendType: sendType,
+ errCode: $InternalErrorCode,
+ errDescription: e.msg
+ )
+ )
- proc computeSetSignerFee*(self: Service, chainId: int, contractAddress: string, accountAddress: string, requestId: string) =
+ proc computeSetSignerFee*(self: Service, uuid: string, communityId: string, chainId: int, contractAddress: string, addressFrom: string) =
+ let sendType = SendType.CommunitySetSignerPubKey
try:
- let arg = AsyncSetSignerFeesArg(
- tptr: asyncSetSignerFeesTask,
- vptr: cast[uint](self.vptr),
- slot: "onSetSignerFees",
- chainId: chainId,
- contractAddress: contractAddress,
- addressFrom: accountAddress,
- requestId: requestId,
- newSignerPubKey: singletonInstance.userProfile.getPubKey()
+ var transferDetails: seq[JsonNode]
+ transferDetails.add(%* {
+ "tokenContractAddress": contractAddress,
+ })
+
+ self.transactionService.suggestedCommunityRoutes(
+ uuid,
+ sendType,
+ chainId,
+ addressFrom,
+ communityId,
+ signerPubKey = singletonInstance.userProfile.getPubKey(),
+ tokenIds = @[],
+ walletAddresses = @[],
+ transferDetails
)
- self.threadpool.start(arg)
except Exception as e:
- #TODO: handle error - emit error signal
- error "Error loading fees", msg = e.msg
-
+ error "Error loading burn fees", msg = e.msg
+ self.transactionService.emitSuggestedRoutesReadySignal(
+ SuggestedRoutesArgs(
+ uuid: uuid,
+ sendType: sendType,
+ errCode: $InternalErrorCode,
+ errDescription: e.msg
+ )
+ )
- proc computeDeployOwnerContractsFee*(self: Service, chainId: int, accountAddress: string, communityId: string, ownerDeploymentParams: DeploymentParameters, masterDeploymentParams: DeploymentParameters, requestId: string) =
+ proc computeDeployOwnerContractsFee*(self: Service, uuid: string, chainId: int, accountFrom: string, communityId: string,
+ ownerDeploymentParams: DeploymentParameters, masterDeploymentParams: DeploymentParameters) =
try:
- let arg = AsyncDeployOwnerContractsFeesArg(
- tptr: asyncGetDeployOwnerContractsFeesTask,
- vptr: cast[uint](self.vptr),
- slot: "onDeployOwnerContractsFees",
- chainId: chainId,
- addressFrom: accountAddress,
- requestId: requestId,
- signerPubKey: singletonInstance.userProfile.getPubKey(),
- communityId: communityId,
- ownerParams: %ownerDeploymentParams,
- masterParams: %masterDeploymentParams
+ var signatureResult: JsonNode
+ let err = tokens_backend.createCommunityTokenDeploymentSignature(signatureResult, chainId, accountFrom, communityId)
+ if err.len > 0:
+ raise newException(CatchableError, "createCommunityTokenDeploymentSignature failed " & err)
+ let signature = signatureResult.getStr
+
+ self.transactionService.suggestedCommunityRoutes(
+ uuid,
+ SendType.CommunityDeployOwnerToken,
+ chainId,
+ accountFrom,
+ communityId,
+ signerPubKey = singletonInstance.userProfile.getPubKey(),
+ tokenIds = @[],
+ walletAddresses = @[],
+ transferDetails = @[],
+ signature,
+ %ownerDeploymentParams,
+ %masterDeploymentParams
)
- self.threadpool.start(arg)
except Exception as e:
- #TODO: handle error - emit error signal
- error "Error loading fees", msg = e.msg
+ error "Error loading deploy owner fees", msg = e.msg
+ self.transactionService.emitSuggestedRoutesReadySignal(
+ SuggestedRoutesArgs(
+ uuid: uuid,
+ sendType: SendType.CommunityDeployOwnerToken,
+ errCode: $InternalErrorCode,
+ errDescription: e.msg
+ )
+ )
proc getOwnerBalances(self: Service, contractOwners: seq[CommunityCollectibleOwner], ownerAddress: string): seq[CollectibleBalance] =
for owner in contractOwners:
@@ -955,56 +940,56 @@ QtObject:
proc getTokensToBurn(self: Service, walletAndAmountList: seq[WalletAndAmount], contract: CommunityTokenDto): seq[Uint256] =
if contract.address == "":
- error "Can't find contract"
- return
+ raise newException(CatchableError, "contract address is empty")
let tokenOwners = self.getCommunityTokenOwners(contract.communityId, contract.chainId, contract.address)
let tokenIds = self.collectTokensToBurn(walletAndAmountList, tokenOwners)
if len(tokenIds) == 0:
- error "Can't find token ids to burn"
+ raise newException(CatchableError, "cannot resolve token ids to burn")
return tokenIds
- proc selfDestructCollectibles*(self: Service, communityId: string, password: string, walletAndAmounts: seq[WalletAndAmount], contractUniqueKey: string, addressFrom: string) =
- try:
- let contract = self.findContractByUniqueId(contractUniqueKey)
- let tokenIds = self.getTokensToBurn(walletAndAmounts, contract)
- if len(tokenIds) == 0:
- debug "No token ids to remote burn", walletAndAmounts=walletAndAmounts
- return
- var addresses: seq[string] = @[]
- for walletAndAmount in walletAndAmounts:
- addresses.add(walletAndAmount.walletAddress)
- let txData = self.buildTransactionDataDto(addressFrom, contract.chainId, contract.address)
- debug "Remote destruct collectibles ", chainId=contract.chainId, address=contract.address, tokens=tokenIds
- let response = tokens_backend.remoteBurn(contract.chainId, contract.address, %txData, common_utils.hashPassword(password),
- tokenIds, $(%addresses))
- let transactionHash = response.result.getStr()
- debug "Remote destruct transaction hash ", transactionHash=transactionHash
-
- var data = RemoteDestructArgs(communityToken: contract, transactionHash: transactionHash, status: ContractTransactionStatus.InProgress, remoteDestructAddresses: addresses)
- self.events.emit(SIGNAL_REMOTE_DESTRUCT_STATUS, data)
- except Exception as e:
- error "Remote self destruct error", msg = e.msg
+ proc computeSelfDestructFee*(self: Service, uuid: string, walletAndAmountList: seq[WalletAndAmount], contractUniqueKey: string, addressFrom: string) =
- proc computeSelfDestructFee*(self: Service, walletAndAmountList: seq[WalletAndAmount], contractUniqueKey: string, addressFrom: string, requestId: string) =
+ let sendType = SendType.CommunityRemoteBurn
try:
+ if walletAndAmountList.len == 0:
+ raise newException(CatchableError, "no amounts to burn for addresses")
let contract = self.findContractByUniqueId(contractUniqueKey)
let tokenIds = self.getTokensToBurn(walletAndAmountList, contract)
- if len(tokenIds) == 0:
- warn "token list is empty"
- return
- let arg = AsyncGetRemoteBurnFees(
- tptr: asyncGetRemoteBurnFeesTask,
- vptr: cast[uint](self.vptr),
- slot: "onSelfDestructFees",
- chainId: contract.chainId,
- contractAddress: contract.address,
- tokenIds: tokenIds,
- addressFrom: addressFrom,
- requestId: requestId
+ let tokensCount = len(tokenIds)
+ if tokensCount == 0:
+ raise newException(CatchableError, "token list is empty")
+
+ let
+ bigTokensCount = common_utils.stringToUint256($tokensCount)
+ hexTokensCount = "0x" & eth_utils.stripLeadingZeros(bigTokensCount.toHex)
+
+ var transferDetails: seq[JsonNode]
+ transferDetails.add(%* {
+ "tokenContractAddress": contract.address,
+ "amount": hexTokensCount,
+ })
+
+ self.transactionService.suggestedCommunityRoutes(
+ uuid,
+ sendType,
+ contract.chainId,
+ addressFrom,
+ contract.communityId,
+ signerPubKey = "",
+ tokenIds.map(x => "0x" & eth_utils.stripLeadingZeros(x.toHex)),
+ walletAddresses = walletAndAmountList.map(x => x.walletAddress),
+ transferDetails
)
- self.threadpool.start(arg)
except Exception as e:
- error "Error loading fees", msg = e.msg
+ error "Error loading self destruct fees", msg = e.msg
+ self.transactionService.emitSuggestedRoutesReadySignal(
+ SuggestedRoutesArgs(
+ uuid: uuid,
+ sendType: sendType,
+ errCode: $InternalErrorCode,
+ errDescription: e.msg
+ )
+ )
proc create0CurrencyAmounts(self: Service): (CurrencyAmount, CurrencyAmount) =
let ethCurrency = newCurrencyAmount(0.0, ethSymbol, 1, false)
@@ -1024,83 +1009,42 @@ QtObject:
errorCode = ComputeFeeErrorCode.Revert
return errorCode
- proc burnTokens*(self: Service, communityId: string, password: string, contractUniqueKey: string, amount: Uint256, addressFrom: string) =
- try:
- var contract = self.findContractByUniqueId(contractUniqueKey)
- let txData = self.buildTransactionDataDto(addressFrom, contract.chainId, contract.address)
- debug "Burn tokens ", chainId=contract.chainId, address=contract.address, amount=amount
- let response = tokens_backend.burn(contract.chainId, contract.address, %txData, common_utils.hashPassword(password), amount)
- let transactionHash = response.result.getStr()
- debug "Burn transaction hash ", transactionHash=transactionHash
-
- var data = RemoteDestructArgs(communityToken: contract, transactionHash: transactionHash, status: ContractTransactionStatus.InProgress)
- self.events.emit(SIGNAL_BURN_STATUS, data)
- except Exception as e:
- error "Burn error", msg = e.msg
-
- proc setSigner*(self: Service, password: string, communityId: string, chainId: int, contractAddress: string, addressFrom: string) =
- try:
- let txData = self.buildTransactionDataDto(addressFrom, chainId, contractAddress)
- debug "Set signer ", chainId=chainId, address=contractAddress
- let signerPubKey = singletonInstance.userProfile.getPubKey()
- let response = tokens_backend.setSignerPubKey(chainId, contractAddress, %txData, signerPubKey, common_utils.hashPassword(password))
- let transactionHash = response.result.getStr()
- debug "Set signer transaction hash ", transactionHash=transactionHash
-
- let data = SetSignerArgs(status: ContractTransactionStatus.InProgress,
- chainId: chainId,
- transactionHash: transactionHash,
- communityId: communityId)
-
- self.events.emit(SIGNAL_SET_SIGNER_STATUS, data)
-
- # observe transaction state
- let contractDetails = ContractDetails(chainId: chainId, contractAddress: contractAddress, communityId: communityId)
- self.transactionService.watchTransaction(
- transactionHash,
- addressFrom,
- contractAddress,
- $PendingTransactionTypeDto.SetSignerPublicKey,
- $(%contractDetails),
- chainId,
- )
- except Exception as e:
- error "Set signer error", msg = e.msg
-
- proc computeBurnFee*(self: Service, contractUniqueKey: string, amount: Uint256, addressFrom: string, requestId: string) =
+ proc computeBurnFee*(self: Service, uuid: string, contractUniqueKey: string, amount: string, addressFrom: string) =
+ let sendType = SendType.CommunityBurn
try:
let contract = self.findContractByUniqueId(contractUniqueKey)
- let arg = AsyncGetBurnFees(
- tptr: asyncGetBurnFeesTask,
- vptr: cast[uint](self.vptr),
- slot: "onBurnFees",
- chainId: contract.chainId,
- contractAddress: contract.address,
- amount: amount,
- addressFrom: addressFrom,
- requestId: requestId
- )
- self.threadpool.start(arg)
- except Exception as e:
- error "Error loading burn fees", msg = e.msg
- proc createComputeFeeArgsWithError(self:Service, errorMessage: string): ComputeFeeArgs =
- let errorCode = self.getErrorCodeFromMessage(errorMessage)
- let (ethCurrency, fiatCurrency) = self.create0CurrencyAmounts()
- return ComputeFeeArgs(ethCurrency: ethCurrency, fiatCurrency: fiatCurrency, errorCode: errorCode)
+ let
+ bigAmount = common_utils.stringToUint256(amount)
+ hexAmount = "0x" & eth_utils.stripLeadingZeros(bigAmount.toHex)
- # Returns eth value with l1 fee included
- proc computeEthValue(self:Service, gasUnits: int, suggestedFees: SuggestedFeesDto): float =
- try:
- let maxFees = suggestedFees.maxFeePerGasM
- let gasPrice = if suggestedFees.eip1559Enabled: maxFees else: suggestedFees.gasPrice
+ var transferDetails: seq[JsonNode]
+ transferDetails.add(%* {
+ "tokenContractAddress": contract.address,
+ "amount": hexAmount,
+ })
- let weiValue = gwei2Wei(gasPrice) * gasUnits.u256
- let l1FeeInWei = gwei2Wei(suggestedFees.l1GasFee)
- let ethValueStr = wei2Eth(weiValue + l1FeeInWei)
- return parseFloat(ethValueStr)
+ self.transactionService.suggestedCommunityRoutes(
+ uuid,
+ sendType,
+ contract.chainId,
+ addressFrom,
+ contract.communityId,
+ signerPubKey = "",
+ tokenIds = @[],
+ walletAddresses = @[],
+ transferDetails
+ )
except Exception as e:
- error "Error computing eth value", msg = e.msg
+ error "Error loading burn fees", msg = e.msg
+ self.transactionService.emitSuggestedRoutesReadySignal(
+ SuggestedRoutesArgs(
+ uuid: uuid,
+ sendType: sendType,
+ errCode: $InternalErrorCode,
+ errDescription: e.msg
+ )
+ )
proc getWalletBalanceForChain(self:Service, walletAddress: string, chainId: int): float =
var balance = 0.0
@@ -1114,18 +1058,6 @@ QtObject:
balance += self.currencyService.parseCurrencyValueByTokensKey(token.tokensKey, b)
return balance
- proc createComputeFeeArgsFromEthAndBalance(self: Service, ethValue: float, balance: float): ComputeFeeArgs =
- let fiatValue = self.getFiatValue(ethValue, ethSymbol)
- let (ethCurrency, fiatCurrency) = self.createCurrencyAmounts(ethValue, fiatValue)
- return ComputeFeeArgs(ethCurrency: ethCurrency, fiatCurrency: fiatCurrency,
- errorCode: (if ethValue > balance: ComputeFeeErrorCode.Balance else: ComputeFeeErrorCode.Success))
-
- proc createComputeFeeArgs(self: Service, gasUnits: int, suggestedFees: SuggestedFeesDto, chainId: int, walletAddress: string): ComputeFeeArgs =
- let ethValue = self.computeEthValue(gasUnits, suggestedFees)
- let balance = self.getWalletBalanceForChain(walletAddress, chainId)
- debug "computing fees", walletBalance=balance, ethValueWithL1Fee=ethValue, l1Fee=gwei2Eth(suggestedFees.l1GasFee)
- return self.createComputeFeeArgsFromEthAndBalance(ethValue, balance)
-
# convert json returned from async task into gas table
proc toGasTable(json: JsonNode): Table[ContractTuple, int] =
try:
@@ -1146,118 +1078,6 @@ QtObject:
except Exception:
error "Error converting to fee table", message = getCurrentExceptionMsg()
- proc parseFeeResponseAndEmitSignal(self:Service, response: string, signalName: string) =
- let responseJson = response.parseJson()
- try:
- let errorMessage = responseJson{"error"}.getStr
- if errorMessage != "":
- let data = self.createComputeFeeArgsWithError(errorMessage)
- data.requestId = responseJson{"requestId"}.getStr
- self.events.emit(signalName, data)
- return
- let gasTable = responseJson{"gasTable"}.toGasTable
- let feeTable = responseJson{"feeTable"}.toFeeTable
- let chainId = responseJson{"chainId"}.getInt
- let addressFrom = responseJson{"addressFrom"}.getStr
- self.tempGasTable = gasTable
- self.tempFeeTable = feeTable
- let gasUnits = toSeq(gasTable.values())[0]
- let suggestedFees = toSeq(feeTable.values())[0]
- let data = self.createComputeFeeArgs(gasUnits, suggestedFees, chainId, addressFrom)
- data.requestId = responseJson{"requestId"}.getStr
- self.events.emit(signalName, data)
- except Exception:
- error "Error creating fee args", message = getCurrentExceptionMsg()
- let data = self.createComputeFeeArgsWithError(getCurrentExceptionMsg())
- data.requestId = responseJson{"requestId"}.getStr
- self.events.emit(signalName, data)
-
- proc onDeployOwnerContractsFees*(self:Service, response: string) {.slot.} =
- self.parseFeeResponseAndEmitSignal(response, SIGNAL_COMPUTE_DEPLOY_FEE)
-
- proc onSelfDestructFees*(self:Service, response: string) {.slot.} =
- self.parseFeeResponseAndEmitSignal(response, SIGNAL_COMPUTE_SELF_DESTRUCT_FEE)
-
- proc onBurnFees*(self:Service, response: string) {.slot.} =
- self.parseFeeResponseAndEmitSignal(response, SIGNAL_COMPUTE_BURN_FEE)
-
- proc onDeployFees*(self:Service, response: string) {.slot.} =
- self.parseFeeResponseAndEmitSignal(response, SIGNAL_COMPUTE_DEPLOY_FEE)
-
- proc onSetSignerFees*(self: Service, response: string) {.slot.} =
- self.parseFeeResponseAndEmitSignal(response, SIGNAL_COMPUTE_SET_SIGNER_FEE)
-
- proc onAirdropFees*(self:Service, response: string) {.slot.} =
- var wholeEthCostForChainWallet: Table[ChainWalletTuple, float]
- var ethValuesForContracts: Table[ContractTuple, float]
- var allComputeFeeArgs: seq[ComputeFeeArgs]
- var dataToEmit = AirdropFeesArgs()
- dataToEmit.errorCode = ComputeFeeErrorCode.Success
- let responseJson = response.parseJson()
-
- try:
- let errorMessage = responseJson{"error"}.getStr
- let requestId = responseJson{"requestId"}.getStr
- if errorMessage != "":
- for collectibleAndAmount in self.tempTokensAndAmounts:
- let args = self.createComputeFeeArgsWithError(errorMessage)
- args.contractUniqueKey = common_utils.contractUniqueKey(collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address)
- dataToEmit.fees.add(args)
- let (ethTotal, fiatTotal) = self.create0CurrencyAmounts()
- dataToEmit.totalEthFee = ethTotal
- dataToEmit.totalFiatFee = fiatTotal
- dataToEmit.errorCode = self.getErrorCodeFromMessage(errorMessage)
- dataToEmit.requestId = requestId
- self.events.emit(SIGNAL_COMPUTE_AIRDROP_FEE, dataToEmit)
- return
-
- let gasTable = responseJson{"gasTable"}.toGasTable
- let feeTable = responseJson{"feeTable"}.toFeeTable
- let addressFrom = responseJson{"addressFrom"}.getStr
- self.tempGasTable = gasTable
- self.tempFeeTable = feeTable
-
- # compute eth cost for every contract
- # also sum all eth costs per (chain, wallet) - it will be needed to compare with (chain, wallet) balance
- for collectibleAndAmount in self.tempTokensAndAmounts:
- let gasUnits = self.tempGasTable[(collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address)]
- let suggestedFees = self.tempFeeTable[collectibleAndAmount.communityToken.chainId]
- let ethValue = self.computeEthValue(gasUnits, suggestedFees)
- wholeEthCostForChainWallet[(collectibleAndAmount.communityToken.chainId, addressFrom)] = wholeEthCostForChainWallet.getOrDefault((collectibleAndAmount.communityToken.chainId, addressFrom), 0.0) + ethValue
- ethValuesForContracts[(collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address)] = ethValue
-
- var totalEthVal = 0.0
- var totalFiatVal = 0.0
- # for every contract create cost Args
- for collectibleAndAmount in self.tempTokensAndAmounts:
- let contractTuple = (chainId: collectibleAndAmount.communityToken.chainId,
- address: collectibleAndAmount.communityToken.address)
- let ethValue = ethValuesForContracts[contractTuple]
- var balance = self.getWalletBalanceForChain(addressFrom, contractTuple.chainId)
- if balance < wholeEthCostForChainWallet[(contractTuple.chainId, addressFrom)]:
- # if wallet balance for this chain is less than the whole cost
- # then we can't afford it; setting balance to 0.0 will set balance error code in Args
- balance = 0.0
- dataToEmit.errorCode = ComputeFeeErrorCode.Balance # set total error code to balance error
- var args = self.createComputeFeeArgsFromEthAndBalance(ethValue, balance)
- totalEthVal = totalEthVal + ethValue
- totalFiatVal = totalFiatVal + args.fiatCurrency.getAmount()
- args.contractUniqueKey = common_utils.contractUniqueKey(collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address)
- allComputeFeeArgs.add(args)
-
- dataToEmit.fees = allComputeFeeArgs
- let (ethTotal, fiatTotal) = self.createCurrencyAmounts(totalEthVal, totalFiatVal)
- dataToEmit.totalEthFee = ethTotal
- dataToEmit.totalFiatFee = fiatTotal
- dataToEmit.requestId = requestId
- self.events.emit(SIGNAL_COMPUTE_AIRDROP_FEE, dataToEmit)
-
- except Exception as e:
- error "Error computing airdrop fees", msg = e.msg
- dataToEmit.errorCode = ComputeFeeErrorCode.Other
- dataToEmit.requestId = responseJson{"requestId"}.getStr
- self.events.emit(SIGNAL_COMPUTE_AIRDROP_FEE, dataToEmit)
-
proc isTokenDeployed(self: Service, token: CommunityTokenDto): bool =
return token.deployState == DeployState.Deployed
@@ -1440,4 +1260,16 @@ QtObject:
if (tokenTupleKey != holdersTokenTuple):
# different token is opened now
return
- self.restartTokenHoldersTimer(token.chainId, token.address)
\ No newline at end of file
+ self.restartTokenHoldersTimer(token.chainId, token.address)
+
+ proc stopSuggestedRoutesAsyncCalculation*(self: Service) =
+ self.transactionService.stopSuggestedRoutesAsyncCalculation()
+
+ proc buildTransactionsFromRoute*(self: Service, uuid: string): string =
+ return self.transactionService.buildTransactionsFromRoute(uuid, slippagePercentage = 0.0)
+
+ proc sendRouterTransactionsWithSignatures*(self: Service, uuid: string, signatures: TransactionsSignatures): string =
+ return self.transactionService.sendRouterTransactionsWithSignatures(uuid, signatures)
+
+ proc signMessage*(self: Service, address: string, hashedPassword: string, hashedMessage: string): tuple[res: string, err: string] =
+ return self.transactionService.signMessage(address, hashedPassword, hashedMessage)
\ No newline at end of file
diff --git a/src/app_service/service/network/service.nim b/src/app_service/service/network/service.nim
index 31104a9ad3e..23d37f57acd 100644
--- a/src/app_service/service/network/service.nim
+++ b/src/app_service/service/network/service.nim
@@ -77,6 +77,11 @@ proc getCurrentNetworksChainIds*(self: Service): seq[int] =
proc getEnabledChainIds*(self: Service): seq[int] =
return self.getCurrentNetworks().filter(n => n.isEnabled).map(n => n.chainId)
+proc getDisabledChainIdsForEnabledChainIds*(self: Service, enabledChainIds: seq[int]): seq[int] =
+ for network in self.getCurrentNetworks():
+ if not enabledChainIds.contains(network.chainId):
+ result.add(network.chainId)
+
proc upsertNetwork*(self: Service, network: NetworkItem): bool =
let response = backend.addEthereumChain(backend.Network(
chainId: network.chainId,
diff --git a/src/app_service/service/transaction/dto.nim b/src/app_service/service/transaction/dto.nim
index a62622e0186..6282c69d299 100644
--- a/src/app_service/service/transaction/dto.nim
+++ b/src/app_service/service/transaction/dto.nim
@@ -4,11 +4,13 @@ import Tables, sequtils
import
web3/ethtypes
-include ../../common/json_utils
-import ../network/dto, ../token/dto
-import ../../common/conversion as service_conversion
+import backend/transactions
+import app_service/common/conversion as service_conversion
+import app_service/service/network/dto
+import app_service/service/token/dto
+import app/modules/shared_models/currency_amount
-import ../../../backend/transactions
+include app_service/common/json_utils
type
SendType* {.pure.} = enum
@@ -21,6 +23,13 @@ type
ERC721Transfer
ERC1155Transfer
Swap
+ CommunityBurn
+ CommunityDeployAssets
+ CommunityDeployCollectibles
+ CommunityDeployOwnerToken
+ CommunityMintTokens
+ CommunityRemoteBurn
+ CommunitySetSignerPubKey
Approve
type
@@ -355,6 +364,19 @@ type
amountToReceive*: UInt256
toNetworks*: seq[SendToNetwork]
+type
+ CostPerPath* = object
+ contractUniqueKey*: string
+ costEthCurrency*: CurrencyAmount
+ costFiatCurrency*: CurrencyAmount
+
+proc `%`*(self: CostPerPath): JsonNode =
+ result = %* {
+ "ethFee": if self.costEthCurrency == nil: newCurrencyAmount().toJsonNode() else: self.costEthCurrency.toJsonNode(),
+ "fiatFee": if self.costFiatCurrency == nil: newCurrencyAmount().toJsonNode() else: self.costFiatCurrency.toJsonNode(),
+ "contractUniqueKey": self.contractUniqueKey,
+ }
+
proc getGasEthValue*(gweiValue: float, gasLimit: uint64): float =
let weiValue = service_conversion.gwei2Wei(gweiValue) * u256(gasLimit)
let ethValue = parseFloat(service_conversion.wei2Eth(weiValue))
diff --git a/src/app_service/service/transaction/dtoV2.nim b/src/app_service/service/transaction/dtoV2.nim
index 65cc6fa5be5..4273c567892 100644
--- a/src/app_service/service/transaction/dtoV2.nim
+++ b/src/app_service/service/transaction/dtoV2.nim
@@ -32,9 +32,11 @@ type
amountOut*: UInt256
suggestedLevelsForMaxFeesPerGas*: SuggestedLevelsForMaxFeesPerGasDto
+ maxFeesPerGas*: UInt256
suggestedMinPriorityFee*: UInt256
suggestedMaxPriorityFee*: UInt256
currentBaseFee*: UInt256
+ usedContractAddress*: string
txNonce*: UInt256
txMaxFeesPerGas*: UInt256
@@ -85,9 +87,11 @@ proc toTransactionPathDtoV2*(jsonObj: JsonNode): TransactionPathDtoV2 =
discard jsonObj.getProp("AmountInLocked", result.amountInLocked)
result.amountOut = stint.fromHex(UInt256, jsonObj{"AmountOut"}.getStr)
result.suggestedLevelsForMaxFeesPerGas = jsonObj["SuggestedLevelsForMaxFeesPerGas"].toSuggestedLevelsForMaxFeesPerGasDto()
+ result.maxFeesPerGas = stint.fromHex(UInt256, jsonObj{"MaxFeesPerGas"}.getStr)
result.suggestedMinPriorityFee = stint.fromHex(UInt256, jsonObj{"SuggestedMinPriorityFee"}.getStr)
result.suggestedMaxPriorityFee = stint.fromHex(UInt256, jsonObj{"SuggestedMaxPriorityFee"}.getStr)
result.currentBaseFee = stint.fromHex(UInt256, jsonObj{"CurrentBaseFee"}.getStr)
+ discard jsonObj.getProp("UsedContractAddress", result.usedContractAddress)
result.txNonce = stint.fromHex(UInt256, jsonObj{"TxNonce"}.getStr)
result.txMaxFeesPerGas = stint.fromHex(UInt256, jsonObj{"TxMaxFeesPerGas"}.getStr)
result.txBaseFee = stint.fromHex(UInt256, jsonObj{"TxBaseFee"}.getStr)
diff --git a/src/app_service/service/transaction/router_transactions_dto.nim b/src/app_service/service/transaction/router_transactions_dto.nim
index b324545619e..59bf80a7200 100644
--- a/src/app_service/service/transaction/router_transactions_dto.nim
+++ b/src/app_service/service/transaction/router_transactions_dto.nim
@@ -1,6 +1,7 @@
import json, stint
+import app_service/service/community_tokens/dto/deployment_parameters
-include ../../common/json_utils
+include app_service/common/json_utils
const
TxStatusSending* = "Sending"
@@ -12,6 +13,26 @@ type
ErrorResponse* = ref object
details*: string
code*: string
+
+type
+ TansferDetails* = ref object
+ tokenType*: int
+ privilegeLevel*: int
+ tokenContractAddress*: string
+ amount*: UInt256
+
+type
+ CommunityParamsDto* = ref object
+ communityID*: string
+ signerPubKey*: string
+ tokenIds*: seq[UInt256]
+ walletAddresses*: seq[string]
+ tokenDeploymentSignature*: string
+ ownerTokenParameters*: DeploymentParameters
+ masterTokenParameters*: DeploymentParameters
+ deploymentParameters*: DeploymentParameters
+ transferDetails*: seq[TansferDetails]
+
type
SendDetailsDto* = ref object
uuid*: string
@@ -29,6 +50,7 @@ type
username*: string
publicKey*: string
packId*: string
+ communityParams*: CommunityParamsDto
type
SigningDetails* = ref object
@@ -77,6 +99,37 @@ proc toErrorResponse*(jsonObj: JsonNode): ErrorResponse =
if jsonObj.contains("code"):
result.code = jsonObj["code"].getStr
+proc toTansferDetails*(jsonObj: JsonNode): TansferDetails =
+ result = TansferDetails()
+ discard jsonObj.getProp("tokenType", result.tokenType)
+ discard jsonObj.getProp("privilegeLevel", result.privilegeLevel)
+ discard jsonObj.getProp("tokenContractAddress", result.tokenContractAddress)
+ var tmpObj: JsonNode
+ if jsonObj.getProp("amount", tmpObj):
+ result.amount = stint.fromHex(UInt256, tmpObj.getStr)
+
+proc toCommunityParamsDto*(jsonObj: JsonNode): CommunityParamsDto =
+ result = CommunityParamsDto()
+ discard jsonObj.getProp("communityID", result.communityID)
+ discard jsonObj.getProp("signerPubKey", result.signerPubKey)
+ discard jsonObj.getProp("tokenDeploymentSignature", result.tokenDeploymentSignature)
+ var tmpObj: JsonNode
+ if jsonObj.getProp("tokenIds", tmpObj) and tmpObj.kind == JArray:
+ for id in tmpObj:
+ result.tokenIds.add(stint.fromHex(UInt256, id.getStr))
+ if jsonObj.getProp("walletAddresses", tmpObj) and tmpObj.kind == JArray:
+ for addr in tmpObj:
+ result.walletAddresses.add(addr.getStr)
+ if jsonObj.getProp("ownerTokenParameters", tmpObj):
+ result.ownerTokenParameters = toDeploymentParameters(tmpObj)
+ if jsonObj.getProp("masterTokenParameters", tmpObj):
+ result.masterTokenParameters = toDeploymentParameters(tmpObj)
+ if jsonObj.getProp("deploymentParameters", tmpObj):
+ result.deploymentParameters = toDeploymentParameters(tmpObj)
+ if jsonObj.getProp("transferDetails", tmpObj) and tmpObj.kind == JArray:
+ for tx in tmpObj:
+ result.transferDetails.add(toTansferDetails(tx))
+
proc toSendDetailsDto*(jsonObj: JsonNode): SendDetailsDto =
result = SendDetailsDto()
discard jsonObj.getProp("uuid", result.uuid)
@@ -100,6 +153,8 @@ proc toSendDetailsDto*(jsonObj: JsonNode): SendDetailsDto =
if jsonObj.getProp("packId", tmpObj):
let packId = stint.fromHex(UInt256, tmpObj.getStr)
result.packId = $packId
+ if jsonObj.getProp("communityParams", tmpObj):
+ result.communityParams = toCommunityParamsDto(tmpObj)
proc toSigningDetails*(jsonObj: JsonNode): SigningDetails =
result = SigningDetails()
diff --git a/src/app_service/service/transaction/service.nim b/src/app_service/service/transaction/service.nim
index ec169758ef4..9521e66975f 100644
--- a/src/app_service/service/transaction/service.nim
+++ b/src/app_service/service/transaction/service.nim
@@ -6,25 +6,27 @@ import backend/backend
import backend/eth
import backend/wallet
-import app_service/common/utils as common_utils
-import app_service/common/types as common_types
-
import app/core/[main]
import app/core/signals/types
import app/core/tasks/[qt, threadpool]
import app/global/global_singleton
import app/global/app_signals
+import app_service/common/wallet_constants as common_wallet_constants
+import app_service/common/utils as common_utils
+import app_service/common/types as common_types
+import app_service/service/currency/service as currency_service
import app_service/service/wallet_account/service as wallet_account_service
import app_service/service/network/service as network_service
import app_service/service/token/service as token_service
import app_service/service/settings/service as settings_service
+import app_service/service/eth/utils as eth_utils
import ./dto as transaction_dto
import ./dtoV2
import ./dto_conversion
import ./router_transactions_dto
-import app_service/service/eth/utils as eth_utils
+import app/modules/shared_models/currency_amount
export transaction_dto, router_transactions_dto
export transactions.TransactionsSignatures
@@ -43,10 +45,9 @@ const SIGNAL_SUGGESTED_ROUTES_READY* = "suggestedRoutesReady"
const SIGNAL_HISTORY_NON_ARCHIVAL_NODE* = "historyNonArchivalNode"
const SIGNAL_HISTORY_ERROR* = "historyError"
const SIGNAL_TRANSACTION_DECODED* = "transactionDecoded"
-const SIGNAL_OWNER_TOKEN_SENT* = "ownerTokenSent"
const SIGNAL_TRANSACTION_STATUS_CHANGED* = "transactionStatusChanged"
-const InternalErrorCode = -1
+const InternalErrorCode* = -1
type TokenTransferMetadata* = object
tokenName*: string
@@ -114,11 +115,16 @@ type
type
SuggestedRoutesArgs* = ref object of Args
uuid*: string
+ sendType*: SendType
suggestedRoutes*: SuggestedRoutesDto
# this should be the only one used when old send modal code is removed
routes*: seq[TransactionPathDtoV2]
errCode*: string
errDescription*: string
+ # Below fields used for community related tx
+ costPerPath*: seq[CostPerPath]
+ totalCostEthCurrency*: CurrencyAmount
+ totalCostFiatCurrency*: CurrencyAmount
type
TransactionDecodedArgs* = ref object of Args
@@ -139,10 +145,11 @@ QtObject:
type Service* = ref object of QObject
events: EventEmitter
threadpool: ThreadPool
+ currencyService: currency_service.Service
networkService: network_service.Service
settingsService: settings_service.Service
tokenService: token_service.Service
- uuidOfTheLastRequestForSuggestedRoutes: string
+ lastRequestForSuggestedRoutes: tuple[uuid: string, sendType: SendType]
## Forward declarations
proc suggestedRoutesReady(self: Service, uuid: string, route: seq[TransactionPathDtoV2], routeRaw: string, errCode: string, errDescription: string)
@@ -154,6 +161,7 @@ QtObject:
proc newService*(
events: EventEmitter,
threadpool: ThreadPool,
+ currencyService: currency_service.Service,
networkService: network_service.Service,
settingsService: settings_service.Service,
tokenService: token_service.Service,
@@ -162,6 +170,7 @@ QtObject:
result.QObject.setup
result.events = events
result.threadpool = threadpool
+ result.currencyService = currencyService
result.networkService = networkService
result.settingsService = settingsService
result.tokenService = tokenService
@@ -325,20 +334,11 @@ QtObject:
return
for tx in sentTransactions:
- if sendDetails.ownerTokenBeingSent:
- self.events.emit(SIGNAL_OWNER_TOKEN_SENT, OwnerTokenSentArgs(
- chainId: tx.fromChain,
- txHash: tx.hash,
- uuid: sendDetails.uuid,
- tokenName: tx.fromToken,
- status: ContractTransactionStatus.InProgress
- ))
- else:
- self.events.emit(SIGNAL_TRANSACTION_SENT, TransactionArgs(
- status: TxStatusSending, # here should be TxStatusPending state, but that's not what Figma wants
- sendDetails: sendDetails,
- sentTransaction: tx
- ))
+ self.events.emit(SIGNAL_TRANSACTION_SENT, TransactionArgs(
+ status: TxStatusSending, # here should be TxStatusPending state, but that's not what Figma wants
+ sendDetails: sendDetails,
+ sentTransaction: tx
+ ))
proc suggestedFees*(self: Service, chainId: int): SuggestedFeesDto =
try:
@@ -347,8 +347,35 @@ QtObject:
except Exception as e:
error "Error getting suggested fees", msg = e.msg
+ proc updateCommunityRoute(self: Service, data: var SuggestedRoutesArgs, route: seq[TransactionPathDtoV2]) =
+ let ethFormat = self.currencyService.getCurrencyFormat(common_wallet_constants.ETH_SYMBOL)
+ let currencyFormat = self.currencyService.getCurrencyFormat(self.settingsService.getCurrency())
+ let fiatPriceForSymbol = self.tokenService.getPriceBySymbol(ethFormat.symbol)
+ var totalFee: UInt256
+ for p in route:
+ let feeInEth = wei2Eth(p.txTotalFee)
+ let ethFeeAsFloat = parseFloat(feeInEth)
+ let fiatFeeAsFloat = ethFeeAsFloat * fiatPriceForSymbol
+ data.costPerPath.add(CostPerPath(
+ contractUniqueKey: common_utils.contractUniqueKey(p.fromChain.chainId, p.usedContractAddress),
+ costEthCurrency: newCurrencyAmount(ethFeeAsFloat, ethFormat.symbol, int(ethFormat.displayDecimals), ethFormat.stripTrailingZeroes),
+ costFiatCurrency: newCurrencyAmount(fiatFeeAsFloat, currencyFormat.symbol, int(currencyFormat.displayDecimals), currencyFormat.stripTrailingZeroes)
+ ))
+ totalFee += p.txTotalFee
+ let totalFeeInEth = wei2Eth(totalFee)
+ let totalEthFeeAsFloat = parseFloat(totalFeeInEth)
+ data.totalCostEthCurrency = newCurrencyAmount(totalEthFeeAsFloat, ethFormat.symbol, int(ethFormat.displayDecimals), ethFormat.stripTrailingZeroes)
+ let totalFiatFeeAsFloat = totalEthFeeAsFloat * fiatPriceForSymbol
+ data.totalCostFiatCurrency = newCurrencyAmount(totalFiatFeeAsFloat, currencyFormat.symbol, int(currencyFormat.displayDecimals), currencyFormat.stripTrailingZeroes)
+
+ proc emitSuggestedRoutesReadySignal*(self: Service, data: SuggestedRoutesArgs) =
+ if self.lastRequestForSuggestedRoutes.uuid != data.uuid:
+ error "cannot emit suggested routes ready signal, uuid mismatch"
+ return
+ self.events.emit(SIGNAL_SUGGESTED_ROUTES_READY, data)
+
proc suggestedRoutesReady(self: Service, uuid: string, route: seq[TransactionPathDtoV2], routeRaw: string, errCode: string, errDescription: string) =
- if self.uuidOfTheLastRequestForSuggestedRoutes != uuid:
+ if self.lastRequestForSuggestedRoutes.uuid != uuid:
return
# TODO: refactor sending modal part of the app, but for now since we're integrating the router v2 just map params to the old dto
@@ -361,13 +388,25 @@ QtObject:
amountToReceive: getTotalAmountToReceive(oldRoute),
toNetworks: getToNetworksList(oldRoute),
)
- self.events.emit(SIGNAL_SUGGESTED_ROUTES_READY, SuggestedRoutesArgs(
+ var data = SuggestedRoutesArgs(
uuid: uuid,
+ sendType: self.lastRequestForSuggestedRoutes.sendType,
suggestedRoutes: suggestedDto,
routes: route,
errCode: errCode,
errDescription: errDescription
- ))
+ )
+
+ if self.lastRequestForSuggestedRoutes.sendType == SendType.CommunityBurn or
+ self.lastRequestForSuggestedRoutes.sendType == SendType.CommunityDeployAssets or
+ self.lastRequestForSuggestedRoutes.sendType == SendType.CommunityDeployCollectibles or
+ self.lastRequestForSuggestedRoutes.sendType == SendType.CommunityDeployOwnerToken or
+ self.lastRequestForSuggestedRoutes.sendType == SendType.CommunityMintTokens or
+ self.lastRequestForSuggestedRoutes.sendType == SendType.CommunityRemoteBurn or
+ self.lastRequestForSuggestedRoutes.sendType == SendType.CommunitySetSignerPubKey:
+ self.updateCommunityRoute(data, route)
+
+ self.emitSuggestedRoutesReadySignal(data)
proc suggestedRoutes*(self: Service,
uuid: string,
@@ -384,7 +423,7 @@ QtObject:
lockedInAmounts: Table[string, string] = initTable[string, string](),
extraParamsTable: Table[string, string] = initTable[string, string]()) =
- self.uuidOfTheLastRequestForSuggestedRoutes = uuid
+ self.lastRequestForSuggestedRoutes = (uuid, sendType)
let
bigAmountIn = common_utils.stringToUint256(amountIn)
@@ -393,15 +432,49 @@ QtObject:
amountOutHex = "0x" & eth_utils.stripLeadingZeros(bigAmountOut.toHex)
try:
- let res = eth.suggestedRoutesAsync(uuid, ord(sendType), accountFrom, accountTo, amountInHex, amountOutHex, token,
+ let err = wallet.suggestedRoutesAsync(uuid, ord(sendType), accountFrom, accountTo, amountInHex, amountOutHex, token,
tokenIsOwnerToken, toToken, disabledFromChainIDs, disabledToChainIDs, lockedInAmounts, extraParamsTable)
+ if err.len > 0:
+ raise newException(CatchableError, "err fetching the best route: " & err)
except CatchableError as e:
error "suggestedRoutes", exception=e.msg
self.suggestedRoutesReady(uuid, @[], "", $InternalErrorCode, e.msg)
+ proc suggestedCommunityRoutes*(self: Service, uuid: string, sendType: SendType, chainId: int, accountFrom: string,
+ communityId: string, signerPubKey: string = "", tokenIds: seq[string] = @[], walletAddresses: seq[string] = @[],
+ transferDetails: seq[JsonNode] = @[], signature: string = "", ownerTokenParameters: JsonNode = JsonNode(),
+ masterTokenParameters: JsonNode = JsonNode(), deploymentParameters: JsonNode = JsonNode()) =
+ self.lastRequestForSuggestedRoutes = (uuid, sendType)
+ try:
+ let
+ disabledFromChainIDs = self.networkService.getDisabledChainIdsForEnabledChainIds(@[chainId])
+ disabledToChainIDs = disabledFromChainIDs
+
+ let err = wallet.suggestedRoutesAsyncForCommunities(
+ uuid,
+ ord(sendType),
+ accountFrom,
+ disabledFromChainIDs,
+ disabledToChainIDs,
+ communityId,
+ signerPubKey,
+ tokenIds,
+ walletAddresses,
+ tokenDeploymentSignature = signature,
+ ownerTokenParameters,
+ masterTokenParameters,
+ deploymentParameters,
+ transferDetails
+ )
+ if err.len > 0:
+ raise newException(CatchableError, "err fetching the best route for deploying owner: " & err)
+ except Exception as e:
+ error "Error loading fees", msg = e.msg
+ self.suggestedRoutesReady(uuid, @[], "", $InternalErrorCode, e.msg)
+
proc stopSuggestedRoutesAsyncCalculation*(self: Service) =
try:
- discard eth.stopSuggestedRoutesAsyncCalculation()
+ discard wallet.stopSuggestedRoutesAsyncCalculation()
except CatchableError as e:
error "stopSuggestedRoutesAsyncCalculation", exception=e.msg
diff --git a/src/backend/community_tokens.nim b/src/backend/community_tokens.nim
index 0134d08a04c..5d26dd4978c 100644
--- a/src/backend/community_tokens.nim
+++ b/src/backend/community_tokens.nim
@@ -1,6 +1,4 @@
import json, stint
-import std/sequtils
-import std/sugar
import ./eth
import ./core, ./response_type
import ../app_service/service/community_tokens/dto/community_token
@@ -8,16 +6,20 @@ import interpret/cropped_image
from ./gen import rpc
+include common
+
# Mirrors the transfer event from status-go, services/wallet/transfer/commands.go
const eventCommunityTokenReceived*: string = "wallet-community-token-received"
-proc deployCollectibles*(chainId: int, deploymentParams: JsonNode, txData: JsonNode, hashedPassword: string): RpcResponse[JsonNode] =
- let payload = %* [chainId, deploymentParams, txData, hashedPassword]
- return core.callPrivateRPC("communitytokens_deployCollectibles", payload)
+proc storeDeployedCollectibles*(addressFrom: string, addressTo: string, chainId: int, txHash: string, deploymentParams: JsonNode):
+ RpcResponse[JsonNode] =
+ let payload = %* [addressFrom, addressTo, chainId, txHash, deploymentParams]
+ return core.callPrivateRPC("communitytokens_storeDeployedCollectibles", payload)
-proc deployAssets*(chainId: int, deploymentParams: JsonNode, txData: JsonNode, hashedPassword: string): RpcResponse[JsonNode] =
- let payload = %* [chainId, deploymentParams, txData, hashedPassword]
- return core.callPrivateRPC("communitytokens_deployAssets", payload)
+proc storeDeployedAssets*(addressFrom: string, addressTo: string, chainId: int, txHash: string, deploymentParams: JsonNode):
+ RpcResponse[JsonNode] =
+ let payload = %* [addressFrom, addressTo, chainId, txHash, deploymentParams]
+ return core.callPrivateRPC("communitytokens_storeDeployedAssets", payload)
proc removeCommunityToken*(chainId: int, address: string): RpcResponse[JsonNode] =
let payload = %* [chainId, address]
@@ -52,73 +54,26 @@ proc updateCommunityTokenSupply*(chainId: int, contractAddress: string, supply:
let payload = %* [chainId, contractAddress, supply.toString(10)]
return core.callPrivateRPC("wakuext_updateCommunityTokenSupply", payload)
-proc mintTokens*(chainId: int, contractAddress: string, txData: JsonNode, hashedPasword: string, walletAddresses: seq[string], amount: Uint256): RpcResponse[JsonNode] =
- let payload = %* [chainId, contractAddress, txData, hashedPasword, walletAddresses, amount.toString(10)]
- return core.callPrivateRPC("communitytokens_mintTokens", payload)
-
-proc estimateMintTokens*(chainId: int, contractAddress: string, fromAddress: string, walletAddresses: seq[string], amount: Uint256): RpcResponse[JsonNode] =
- let payload = %* [chainId, contractAddress, fromAddress, walletAddresses, amount.toString(10)]
- return core.callPrivateRPC("communitytokens_estimateMintTokens", payload)
-
-proc remoteBurn*(chainId: int, contractAddress: string, txData: JsonNode, hashedPassword: string, tokenIds: seq[UInt256], additionalData: string): RpcResponse[JsonNode] =
- let payload = %* [chainId, contractAddress, txData, hashedPassword, tokenIds.map(x => x.toString(10)), additionalData]
- return core.callPrivateRPC("communitytokens_remoteBurn", payload)
-
-proc estimateRemoteBurn*(chainId: int, contractAddress: string, fromAddress: string, tokenIds: seq[UInt256]): RpcResponse[JsonNode] =
- let payload = %* [chainId, contractAddress, fromAddress, tokenIds.map(x => x.toString(10))]
- return core.callPrivateRPC("communitytokens_estimateRemoteBurn", payload)
-
-proc burn*(chainId: int, contractAddress: string, txData: JsonNode, hashedPassword: string, amount: Uint256): RpcResponse[JsonNode] =
- let payload = %* [chainId, contractAddress, txData, hashedPassword, amount.toString(10)]
- return core.callPrivateRPC("communitytokens_burn", payload)
-
-proc estimateBurn*(chainId: int, contractAddress: string, fromAddress: string, amount: Uint256): RpcResponse[JsonNode] =
- let payload = %* [chainId, contractAddress, fromAddress, amount.toString(10)]
- return core.callPrivateRPC("communitytokens_estimateBurn", payload)
-
-proc estimateSetSignerPubKey*(chainId: int, contractAddress: string, fromAddress: string, newSignerPubkey: string): RpcResponse[JsonNode] =
- let payload = %* [chainId, contractAddress, fromAddress, newSignerPubkey]
- return core.callPrivateRPC("communitytokens_estimateSetSignerPubKey", payload)
-
proc remainingSupply*(chainId: int, contractAddress: string): RpcResponse[JsonNode] =
let payload = %* [chainId, contractAddress]
return core.callPrivateRPC("communitytokens_remainingSupply", payload)
-proc deployCollectiblesEstimate*(chainId: int, addressFrom: string): RpcResponse[JsonNode] =
- let payload = %*[chainId, addressFrom]
- return core.callPrivateRPC("communitytokens_deployCollectiblesEstimate", payload)
-
-proc deployAssetsEstimate*(chainId: int, addressFrom: string): RpcResponse[JsonNode] =
- let payload = %*[chainId, addressFrom]
- return core.callPrivateRPC("communitytokens_deployAssetsEstimate", payload)
-
proc remoteDestructedAmount*(chainId: int, contractAddress: string): RpcResponse[JsonNode] =
let payload = %*[chainId, contractAddress]
return core.callPrivateRPC("communitytokens_remoteDestructedAmount", payload)
-proc deployOwnerTokenEstimate*(chainId: int, addressFrom: string, ownerParams: JsonNode, masterParams: JsonNode, communityId: string, signerPubKey: string): RpcResponse[JsonNode] =
- let payload = %*[chainId, addressFrom, ownerParams, masterParams, communityId, signerPubKey]
- return core.callPrivateRPC("communitytokens_deployOwnerTokenEstimate", payload)
-
-proc deployOwnerToken*(chainId: int, ownerParams: JsonNode, masterParams: JsonNode, signerPubKey: string, txData: JsonNode, hashedPassword: string): RpcResponse[JsonNode] =
- let payload = %*[chainId, ownerParams, masterParams, signerPubKey, txData, hashedPassword]
- return core.callPrivateRPC("communitytokens_deployOwnerToken", payload)
-
-proc getMasterTokenContractAddressFromHash*(chainId: int, transactionHash: string): RpcResponse[JsonNode] =
- let payload = %*[chainId, transactionHash]
- return core.callPrivateRPC("communitytokens_getMasterTokenContractAddressFromHash", payload)
-
-proc getOwnerTokenContractAddressFromHash*(chainId: int, transactionHash: string): RpcResponse[JsonNode] =
- let payload = %*[chainId, transactionHash]
- return core.callPrivateRPC("communitytokens_getOwnerTokenContractAddressFromHash", payload)
-
-proc createCommunityTokenDeploymentSignature*(chainId: int, addressFrom: string, signerAddress: string): RpcResponse[JsonNode] =
- let payload = %*[chainId, addressFrom, signerAddress]
- return core.callPrivateRPC("wakuext_createCommunityTokenDeploymentSignature", payload)
-
-proc setSignerPubKey*(chainId: int, contractAddress: string, txData: JsonNode, newSignerPubKey: string, hashedPassword: string): RpcResponse[JsonNode] =
- let payload = %* [chainId, contractAddress, txData, hashedPassword, newSignerPubKey]
- return core.callPrivateRPC("communitytokens_setSignerPubKey", payload)
+proc storeDeployedOwnerToken*(addressFrom: string, chainId: int, txHash: string, ownerParams: JsonNode, masterParams: JsonNode):
+ RpcResponse[JsonNode] =
+ let payload = %* [addressFrom, chainId, txHash, ownerParams, masterParams]
+ return core.callPrivateRPC("communitytokens_storeDeployedOwnerToken", payload)
+
+proc createCommunityTokenDeploymentSignature*(resultOut: var JsonNode, chainId: int, addressFrom: string, signerAddress: string): string =
+ try:
+ let payload = %*[chainId, addressFrom, signerAddress]
+ let response = core.callPrivateRPC("wakuext_createCommunityTokenDeploymentSignature", payload)
+ return prepareResponse(resultOut, response)
+ except Exception as e:
+ return e.msg
proc registerOwnerTokenReceivedNotification*(communityId: string): RpcResponse[JsonNode] =
let payload = %*[communityId]
diff --git a/src/backend/eth.nim b/src/backend/eth.nim
index 4f39084665a..c4a46cc15d8 100644
--- a/src/backend/eth.nim
+++ b/src/backend/eth.nim
@@ -1,21 +1,9 @@
-import json, tables
+import json
import ./core, ./response_type
from ./gen import rpc
export response_type
-const
- GasFeeLow* = 0
- GasFeeMedium* = 1
- GasFeeHigh* = 2
-
-const
- ExtraKeyUsername* = "username"
- ExtraKeyPublicKey* = "publicKey"
- ExtraKeyPackId* = "packID"
-
- ExtraKeys = @[ExtraKeyUsername, ExtraKeyPublicKey, ExtraKeyPackId]
-
proc getAccounts*(): RpcResponse[JsonNode] =
return core.callPrivateRPC("eth_accounts")
@@ -38,57 +26,5 @@ proc suggestedFees*(chainId: int): RpcResponse[JsonNode] =
let payload = %* [chainId]
return core.callPrivateRPC("wallet_getSuggestedFees", payload)
-proc prepareDataForSuggestedRoutes(uuid: string, sendType: int, accountFrom: string, accountTo: string, amountIn: string, amountOut: string,
- token: string, tokenIsOwnerToken: bool, toToken: string, disabledFromChainIDs, disabledToChainIDs: seq[int], lockedInAmounts: Table[string, string],
- extraParamsTable: Table[string, string]): JsonNode =
-
- let data = %* {
- "uuid": uuid,
- "sendType": sendType,
- "addrFrom": accountFrom,
- "addrTo": accountTo,
- "amountIn": amountIn,
- "amountOut": amountOut,
- "tokenID": token,
- "tokenIDIsOwnerToken": tokenIsOwnerToken,
- "toTokenID": toToken,
- "disabledFromChainIDs": disabledFromChainIDs,
- "disabledToChainIDs": disabledToChainIDs,
- "gasFeeMode": GasFeeMedium,
- "fromLockedAmount": lockedInAmounts
- }
-
- # `extraParamsTable` is used for send types like EnsRegister, EnsRelease, EnsSetPubKey, StickersBuy
- # keys that can be used in `extraParamsTable` are:
- # "username", "publicKey", "packID"
- for key, value in extraParamsTable:
- if key in ExtraKeys:
- data[key] = %* value
- else:
- return nil
-
- return %* [data]
-
-proc suggestedRoutes*(sendType: int, accountFrom: string, accountTo: string, amountIn: string, amountOut: string, token: string,
- tokenIsOwnerToken: bool, toToken: string, disabledFromChainIDs, disabledToChainIDs: seq[int], lockedInAmounts: Table[string, string],
- extraParamsTable: Table[string, string]): RpcResponse[JsonNode] {.raises: [RpcException].} =
- let payload = prepareDataForSuggestedRoutes(uuid = "", sendType, accountFrom, accountTo, amountIn, amountOut, token, tokenIsOwnerToken, toToken,
- disabledFromChainIDs, disabledToChainIDs, lockedInAmounts, extraParamsTable)
- if payload.isNil:
- raise newException(RpcException, "Invalid key in extraParamsTable")
- return core.callPrivateRPC("wallet_getSuggestedRoutes", payload)
-
-proc suggestedRoutesAsync*(uuid: string, sendType: int, accountFrom: string, accountTo: string, amountIn: string, amountOut: string, token: string,
- tokenIsOwnerToken: bool, toToken: string, disabledFromChainIDs, disabledToChainIDs: seq[int], lockedInAmounts: Table[string, string],
- extraParamsTable: Table[string, string]): RpcResponse[JsonNode] {.raises: [RpcException].} =
- let payload = prepareDataForSuggestedRoutes(uuid, sendType, accountFrom, accountTo, amountIn, amountOut, token, tokenIsOwnerToken, toToken,
- disabledFromChainIDs, disabledToChainIDs, lockedInAmounts, extraParamsTable)
- if payload.isNil:
- raise newException(RpcException, "Invalid key in extraParamsTable")
- return core.callPrivateRPC("wallet_getSuggestedRoutesAsync", payload)
-
-proc stopSuggestedRoutesAsyncCalculation*() : RpcResponse[JsonNode] =
- return core.callPrivateRPC("wallet_stopSuggestedRoutesAsyncCalculation")
-
rpc(getEstimatedLatestBlockNumber, "wallet"):
chainId: int
diff --git a/src/backend/wallet.nim b/src/backend/wallet.nim
index ed59a7a04d0..126615ad13c 100644
--- a/src/backend/wallet.nim
+++ b/src/backend/wallet.nim
@@ -1,11 +1,26 @@
-import json, json_serialization, logging
+import json, tables, json_serialization, logging
import core, response_type
from ./gen import rpc
import status_go
+from app_service/common/account_constants import ZERO_ADDRESS
include common
+export response_type
+
+const
+ GasFeeLow* = 0
+ GasFeeMedium* = 1
+ GasFeeHigh* = 2
+
+const
+ ExtraKeyUsername* = "username"
+ ExtraKeyPublicKey* = "publicKey"
+ ExtraKeyPackId* = "packID"
+
+ ExtraKeys = @[ExtraKeyUsername, ExtraKeyPublicKey, ExtraKeyPackId]
+
rpc(signMessage, "wallet"):
message: string
address: string
@@ -102,4 +117,90 @@ proc hashTypedDataV4*(resultOut: var JsonNode, data: string): string =
return prepareResponse(resultOut, response)
except Exception as e:
warn e.msg
- return e.msg
\ No newline at end of file
+ return e.msg
+
+proc prepareDataForSuggestedRoutes(
+ uuid: string,
+ sendType: int,
+ accountFrom: string,
+ accountTo: string,
+ amountIn: string,
+ amountOut: string,
+ token: string,
+ tokenIsOwnerToken: bool,
+ toToken: string,
+ disabledFromChainIDs,
+ disabledToChainIDs: seq[int],
+ lockedInAmounts: Table[string, string],
+ extraParamsTable: Table[string, string],
+ communityRouteInputParameters: JsonNode = JsonNode(),
+ ): JsonNode =
+
+ let data = %* {
+ "uuid": uuid,
+ "sendType": sendType,
+ "addrFrom": accountFrom,
+ "addrTo": accountTo,
+ "amountIn": amountIn,
+ "amountOut": amountOut,
+ "tokenID": token,
+ "tokenIDIsOwnerToken": tokenIsOwnerToken,
+ "toTokenID": toToken,
+ "disabledFromChainIDs": disabledFromChainIDs,
+ "disabledToChainIDs": disabledToChainIDs,
+ "gasFeeMode": GasFeeMedium,
+ "fromLockedAmount": lockedInAmounts,
+ "communityRouteInputParams": communityRouteInputParameters,
+ }
+
+ # `extraParamsTable` is used for send types like EnsRegister, EnsRelease, EnsSetPubKey, StickersBuy
+ # keys that can be used in `extraParamsTable` are:
+ # "username", "publicKey", "packID"
+ for key, value in extraParamsTable:
+ if key in ExtraKeys:
+ data[key] = %* value
+ else:
+ return nil
+
+ return %* [data]
+
+proc suggestedRoutesAsync*(uuid: string, sendType: int, accountFrom: string, accountTo: string, amountIn: string, amountOut: string, token: string,
+ tokenIsOwnerToken: bool, toToken: string, disabledFromChainIDs, disabledToChainIDs: seq[int], lockedInAmounts: Table[string, string],
+ extraParamsTable: Table[string, string]): string {.raises: [RpcException].} =
+ let payload = prepareDataForSuggestedRoutes(uuid, sendType, accountFrom, accountTo, amountIn, amountOut, token, tokenIsOwnerToken, toToken,
+ disabledFromChainIDs, disabledToChainIDs, lockedInAmounts, extraParamsTable)
+ if payload.isNil:
+ raise newException(RpcException, "Invalid key in extraParamsTable")
+ let rpcResponse = core.callPrivateRPC("wallet_getSuggestedRoutesAsync", payload)
+ if isErrorResponse(rpcResponse):
+ return rpcResponse.error.message
+
+proc suggestedRoutesAsyncForCommunities*(uuid: string, sendType: int, accountFrom: string, disabledFromChainIDs,
+ disabledToChainIDs: seq[int], communityId: string, signerPubKey: string = "0x0", tokenIds: seq[string] = @[],
+ walletAddresses: seq[string] = @[], tokenDeploymentSignature: string = "", ownerTokenParameters: JsonNode = JsonNode(),
+ masterTokenParameters: JsonNode = JsonNode(), deploymentParameters: JsonNode = JsonNode(),
+ transferDetails: seq[JsonNode] = @[]): string {.raises: [RpcException].} =
+
+ let data = %* {
+ "communityID": communityId,
+ "signerPubKey": signerPubKey,
+ "tokenIds": tokenIds,
+ "walletAddresses": walletAddresses,
+ "tokenDeploymentSignature": tokenDeploymentSignature,
+ "ownerTokenParameters": ownerTokenParameters,
+ "masterTokenParameters": masterTokenParameters,
+ "deploymentParameters": deploymentParameters,
+ "transferDetails": transferDetails,
+ }
+
+ let payload = prepareDataForSuggestedRoutes(uuid, sendType, accountFrom, accountTo=ZERO_ADDRESS, amountIn="0x0", amountOut="0x0", token="ETH",
+ tokenIsOwnerToken=false, toToken="", disabledFromChainIDs, disabledToChainIDs, lockedInAmounts=initTable[string, string](),
+ extraParamsTable=initTable[string, string](), communityRouteInputParameters=data)
+ let rpcResponse = core.callPrivateRPC("wallet_getSuggestedRoutesAsync", payload)
+ if isErrorResponse(rpcResponse):
+ return rpcResponse.error.message
+
+proc stopSuggestedRoutesAsyncCalculation*(): string {.raises: [RpcException].} =
+ let rpcResponse = core.callPrivateRPC("wallet_stopSuggestedRoutesAsyncCalculation")
+ if isErrorResponse(rpcResponse):
+ return rpcResponse.error.message
\ No newline at end of file
diff --git a/ui/StatusQ/src/StatusQ/Core/Utils/SubscriptionBrokerCommunities.qml b/ui/StatusQ/src/StatusQ/Core/Utils/SubscriptionBrokerCommunities.qml
new file mode 100644
index 00000000000..0b9ee5c805b
--- /dev/null
+++ b/ui/StatusQ/src/StatusQ/Core/Utils/SubscriptionBrokerCommunities.qml
@@ -0,0 +1,200 @@
+import QtQuick 2.15
+
+//This is a helper component that is used to batch requests and send them periodically
+//It is used to reduce the number of requests sent to the server and notify different subscribers of the same request
+//It is used by the Subscription component
+QtObject {
+ id: root
+
+ signal request(string subscriptionId, string topic)
+
+ signal subscribed(string subscriptionId)
+ signal unsubscribed(string subscriptionId)
+
+ function response(subscriptionId, responseObj) {
+ let resolvedTopic = ""
+ Object.keys(d.topics).forEach(function (topic) {
+ d.topics[topic].subscriptions.forEach(function(subscrId) {
+ if(subscriptionId === subscrId) {
+ resolvedTopic = topic
+ return
+ }
+ })
+ })
+ d.onResponse(resolvedTopic, responseObj)
+ }
+ function subscribe(subscription) {
+ d.subscribe(subscription)
+ }
+ function unsubscribe(subscription) {
+ d.unsubscribe(subscription)
+ }
+
+ property bool active: true
+
+ readonly property QtObject d: QtObject {
+ //Mapping subscriptionId to subscription object
+ //subscriptionId is a string and represents the id of the subscription
+ //E.g. "subscriptionId": {subscription: subscriptionObject, topic: "topic"}
+ //The purpose of this mapping is to keep track of the subscriptions and their topics
+ readonly property var managedSubscriptions: ({})
+
+ //Mapping topic to subscriptionIds and request data
+ //topic is a string and represents the topic of the subscription
+ //E.g. "topic": {nextRequestTimestamp: 0, requestInterval: 1000, subscriptions: ["subscriptionId1", "subscriptionId2"], response: null}
+ readonly property var topics: ({})
+ property int topicsCount: 0 //helper property to track change events
+
+
+
+
+
+
+
+ function subscribe(subscription) {
+ if(!(subscription instanceof Subscription))
+ return
+ if(d.managedSubscriptions.hasOwnProperty(subscription.subscriptionId))
+ return
+
+ registerToManagedSubscriptions(subscription)
+ connectToSubscriptionEvents(subscription)
+ if(subscription.isReady && subscription.topic)
+ registerToTopic(subscription.topic, subscription.subscriptionId)
+ root.subscribed(subscription.subscriptionId)
+ }
+
+ function unsubscribe(subscriptionId) {
+ if(!subscriptionId || !d.managedSubscriptions.hasOwnProperty(subscriptionId))
+ return
+
+ releaseManagedSubscription(subscriptionId)
+ root.unsubscribed(subscriptionId)
+ }
+
+ function registerToManagedSubscriptions(subscriptionObject) {
+ d.managedSubscriptions[subscriptionObject.subscriptionId] = {
+ subscription: subscriptionObject,
+ topic: subscriptionObject.topic,
+ }
+ }
+
+ function releaseManagedSubscription(subscriptionId) {
+ if(!subscriptionId || !d.managedSubscriptions.hasOwnProperty(subscriptionId)) return
+
+ const subscriptionInfo = d.managedSubscriptions[subscriptionId]
+
+ unregisterFromTopic(subscriptionInfo.topic, subscriptionId)
+ delete d.managedSubscriptions[subscriptionId]
+ }
+
+ function connectToSubscriptionEvents(subscription) {
+ const subscriptionId = subscription.subscriptionId
+ const topic = subscription.topic
+
+ const onTopicChangeHandler = () => {
+ if(!subscription.isReady || !d.managedSubscriptions.hasOwnProperty(subscriptionId)) return
+
+ const newTopic = subscription.topic
+ const oldTopic = d.managedSubscriptions[subscriptionId].topic
+
+ if(newTopic === oldTopic) return
+
+ d.unregisterFromTopic(oldTopic, subscriptionId)
+ d.registerToTopic(newTopic, subscriptionId)
+ d.managedSubscriptions[subscriptionId].topic = newTopic
+ }
+
+ const onReadyChangeHandler = () => {
+ if(!d.managedSubscriptions.hasOwnProperty(subscriptionId)) return
+
+ if(subscription.isReady) {
+ d.registerToTopic(subscription.topic, subscription.subscriptionId)
+ } else {
+ const subscriptionTopic = d.managedSubscriptions[subscriptionId].topic
+ d.unregisterFromTopic(subscriptionTopic, subscriptionId)
+ }
+ }
+
+ const onUnsubscribedHandler = (subscriptionId) => {
+ if(subscriptionId !== subscription.subscriptionId)
+ return
+
+ subscription.Component.onDestruction.disconnect(onDestructionHandler)
+ subscription.isReadyChanged.disconnect(onReadyChangeHandler)
+ subscription.topicChanged.disconnect(onTopicChangeHandler)
+ }
+
+ const onDestructionHandler = () => {
+ if(!d.managedSubscriptions.hasOwnProperty(subscriptionId))
+ return
+
+ root.unsubscribed.disconnect(onUnsubscribedHandler) //object is destroyed, no need to listen to the signal anymore
+ unsubscribe(subscriptionId)
+ }
+
+ subscription.Component.onDestruction.connect(onDestructionHandler)
+ subscription.isReadyChanged.connect(onReadyChangeHandler)
+ subscription.topicChanged.connect(onTopicChangeHandler)
+ root.unsubscribed.connect(onUnsubscribedHandler)
+ }
+
+ function registerToTopic(topic, subscriptionId) {
+ if(!d.topics.hasOwnProperty(topic)) {
+ d.topics[topic] = {
+ subscriptions: [],
+ response: null,
+ requestPending: false
+ }
+ d.topicsCount++
+ }
+
+ const index = d.topics[topic].subscriptions.indexOf(subscriptionId)
+ if(index !== -1) {
+ console.assert("Duplicate subscription: " + subscriptionId + " " + topic)
+ return
+ }
+
+ const subscriptionsCount = d.topics[topic].subscriptions.push(subscriptionId)
+ if(subscriptionsCount === 1 && root.active) {
+ d.request(subscriptionId, topic)
+ }
+ d.managedSubscriptions[subscriptionId].subscription.response = d.topics[topic].response
+ }
+
+ function unregisterFromTopic(topic, subscriptionId) {
+ if(!d.topics.hasOwnProperty(topic)) return
+
+ const index = d.topics[topic].subscriptions.indexOf(subscriptionId)
+ if(index === -1) return
+
+ d.topics[topic].subscriptions.splice(index, 1)
+ if(d.topics[topic].subscriptions.length === 0) {
+ delete d.topics[topic]
+ d.topicsCount--
+ }
+ }
+
+
+
+
+
+ function request(subscriptionId, topic) {
+ if(!d.topics.hasOwnProperty(topic)) return
+
+ d.topics[topic].requestPending = true
+
+ root.request(subscriptionId, topic)
+ }
+
+ function onResponse(topic, responseObj) {
+ if(!d.topics.hasOwnProperty(topic)) return
+
+ d.topics[topic].response = responseObj
+ d.topics[topic].subscriptions.forEach(function(subscriptionId) {
+ d.managedSubscriptions[subscriptionId].subscription.response = responseObj
+ })
+ d.topics[topic].requestPending = false
+ }
+ }
+}
diff --git a/ui/StatusQ/src/StatusQ/Core/Utils/qmldir b/ui/StatusQ/src/StatusQ/Core/Utils/qmldir
index f98c58d52d1..f096f22653a 100644
--- a/ui/StatusQ/src/StatusQ/Core/Utils/qmldir
+++ b/ui/StatusQ/src/StatusQ/Core/Utils/qmldir
@@ -16,6 +16,7 @@ StackViewStates 0.1 StackViewStates.qml
StatesStack 0.1 StatesStack.qml
Subscription 0.1 Subscription.qml
SubscriptionBroker 0.1 SubscriptionBroker.qml
+SubscriptionBrokerCommunities 0.1 SubscriptionBrokerCommunities.qml
XSS 1.0 xss.js
singleton AmountsArithmetic 0.1 AmountsArithmetic.qml
singleton Emoji 0.1 Emoji.qml
diff --git a/ui/StatusQ/src/statusq.qrc b/ui/StatusQ/src/statusq.qrc
index 1379cbb10e8..56505ef5376 100644
--- a/ui/StatusQ/src/statusq.qrc
+++ b/ui/StatusQ/src/statusq.qrc
@@ -211,6 +211,7 @@
StatusQ/Core/Utils/StringUtils.qml
StatusQ/Core/Utils/Subscription.qml
StatusQ/Core/Utils/SubscriptionBroker.qml
+ StatusQ/Core/Utils/SubscriptionBrokerCommunities.qml
StatusQ/Core/Utils/Utils.qml
StatusQ/Core/Utils/big.min.mjs
StatusQ/Core/Utils/emojiList.js
diff --git a/ui/app/AppLayouts/Communities/helpers/AirdropFeesSubscriber.qml b/ui/app/AppLayouts/Communities/helpers/AirdropFeesSubscriber.qml
index 3f2d0cc5558..bf8c789edb8 100644
--- a/ui/app/AppLayouts/Communities/helpers/AirdropFeesSubscriber.qml
+++ b/ui/app/AppLayouts/Communities/helpers/AirdropFeesSubscriber.qml
@@ -36,34 +36,33 @@ QtObject {
property var airdropFeesResponse: null
readonly property string feesError: {
- if (!airdropFeesResponse) return ""
-
- if (airdropFeesResponse.errorCode === Constants.ComputeFeeErrorCode.Success) return ""
-
- if (airdropFeesResponse.errorCode === Constants.ComputeFeeErrorCode.Balance)
- return qsTr("Your account does not have enough ETH to pay the gas fee for this airdrop. Try adding some ETH to your account.")
-
- if (airdropFeesResponse.errorCode === Constants.ComputeFeeErrorCode.Infura)
- return qsTr("Infura error")
-
- if (airdropFeesResponse.errorCode === Constants.ComputeFeeErrorCode.Revert)
- return qsTr("Estimation reverted. Make sure you selected the Wallet account that owns the TokenMaster or Owner Token.")
+ if (!root.airdropFeesResponse)
+ return ""
- return qsTr("Unknown error")
+ return root.airdropFeesResponse.error
}
readonly property string totalFee: {
- if (!airdropFeesResponse || !Object.values(airdropFeesResponse.totalEthFee).length || !Object.values(airdropFeesResponse.totalFiatFee).length) return ""
+ if (!root.airdropFeesResponse) {
+ return ""
+ }
+
+ if (!!root.airdropFeesResponse.error) {
+ return "-"
+ }
- if (airdropFeesResponse.errorCode !== Constants.ComputeFeeErrorCode.Success && airdropFeesResponse.errorCode !== Constants.ComputeFeeErrorCode.Balance)
+ if (!root.airdropFeesResponse || !Object.values(root.airdropFeesResponse.ethCurrency).length || !Object.values(root.airdropFeesResponse.fiatCurrency).length) {
return ""
+ }
- return `${LocaleUtils.currencyAmountToLocaleString(airdropFeesResponse.totalEthFee)} (${LocaleUtils.currencyAmountToLocaleString(airdropFeesResponse.totalFiatFee)})`
+ return LocaleUtils.currencyAmountToLocaleString(root.airdropFeesResponse.ethCurrency)
+ + " (" + LocaleUtils.currencyAmountToLocaleString(root.airdropFeesResponse.fiatCurrency) + ")"
}
readonly property var feesPerContract: {
- if (!airdropFeesResponse || !Object.values(airdropFeesResponse.fees).length || totalFee == "") return []
+ if (!root.airdropFeesResponse || !Object.values(root.airdropFeesResponse.fees).length || totalFee == "")
+ return []
- return airdropFeesResponse.fees.map(fee => {
+ return root.airdropFeesResponse.fees.map(fee => {
return {
contractUniqueKey: fee.contractUniqueKey,
feeText: `${LocaleUtils.currencyAmountToLocaleString(fee.ethFee)} (${LocaleUtils.currencyAmountToLocaleString(fee.fiatFee)})`
diff --git a/ui/app/AppLayouts/Communities/helpers/DeployFeesSubscriber.qml b/ui/app/AppLayouts/Communities/helpers/DeployFeesSubscriber.qml
index 7bef0014359..1e0f12040c8 100644
--- a/ui/app/AppLayouts/Communities/helpers/DeployFeesSubscriber.qml
+++ b/ui/app/AppLayouts/Communities/helpers/DeployFeesSubscriber.qml
@@ -14,4 +14,8 @@ SingleFeeSubscriber {
required property bool isOwnerDeployment
required property string accountAddress
required property bool enabled
+
+ property var ownerToken
+ property var masterToken
+ property var token
}
diff --git a/ui/app/AppLayouts/Communities/helpers/SetSignerFeesSubscriber.qml b/ui/app/AppLayouts/Communities/helpers/SetSignerFeesSubscriber.qml
index 52c8b9e6750..f995b94aafa 100644
--- a/ui/app/AppLayouts/Communities/helpers/SetSignerFeesSubscriber.qml
+++ b/ui/app/AppLayouts/Communities/helpers/SetSignerFeesSubscriber.qml
@@ -8,6 +8,7 @@ import QtQuick 2.15
SingleFeeSubscriber {
id: root
+ required property string communityId
required property int chainId
required property string contractAddress
required property string accountAddress
diff --git a/ui/app/AppLayouts/Communities/helpers/SingleFeeSubscriber.qml b/ui/app/AppLayouts/Communities/helpers/SingleFeeSubscriber.qml
index 9bde66a1f09..8a4b095954f 100644
--- a/ui/app/AppLayouts/Communities/helpers/SingleFeeSubscriber.qml
+++ b/ui/app/AppLayouts/Communities/helpers/SingleFeeSubscriber.qml
@@ -17,24 +17,26 @@ import utils 1.0
// Internal properties based on response
readonly property string feeText: {
- if (!feesResponse || !Object.values(feesResponse.ethCurrency).length || !Object.values(feesResponse.fiatCurrency).length) return ""
-
- if (feesResponse.errorCode !== Constants.ComputeFeeErrorCode.Success && feesResponse.errorCode !== Constants.ComputeFeeErrorCode.Balance)
+ if (!root.feesResponse) {
return ""
+ }
- return LocaleUtils.currencyAmountToLocaleString(feesResponse.ethCurrency)
- + " (" + LocaleUtils.currencyAmountToLocaleString(feesResponse.fiatCurrency) + ")"
- }
- readonly property string feeErrorText: {
- if (!feesResponse) return ""
- if (feesResponse.errorCode === Constants.ComputeFeeErrorCode.Success) return ""
- if (feesResponse.errorCode === Constants.ComputeFeeErrorCode.Balance)
- return qsTr("Not enough funds to make transaction")
+ if (!!root.feesResponse.error) {
+ return "-"
+ }
+
+ if (!root.feesResponse || !Object.values(root.feesResponse.ethCurrency).length || !Object.values(root.feesResponse.fiatCurrency).length) {
+ return ""
+ }
- if (feesResponse.errorCode === Constants.ComputeFeeErrorCode.Infura)
- return qsTr("Infura error")
+ return LocaleUtils.currencyAmountToLocaleString(root.feesResponse.ethCurrency)
+ + " (" + LocaleUtils.currencyAmountToLocaleString(root.feesResponse.fiatCurrency) + ")"
+ }
+ readonly property string feeErrorText: {
+ if (!root.feesResponse)
+ return ""
- return qsTr("Unknown error")
+ return root.feesResponse.error
}
}
diff --git a/ui/app/AppLayouts/Communities/helpers/TransactionFeesBroker.qml b/ui/app/AppLayouts/Communities/helpers/TransactionFeesBroker.qml
index a71a871ffcc..51724a5e904 100644
--- a/ui/app/AppLayouts/Communities/helpers/TransactionFeesBroker.qml
+++ b/ui/app/AppLayouts/Communities/helpers/TransactionFeesBroker.qml
@@ -3,6 +3,9 @@ import QtQuick 2.15
import shared.stores 1.0
import StatusQ.Core.Utils 0.1
+import AppLayouts.Wallet 1.0
+
+import utils 1.0
QtObject {
id: root
@@ -51,7 +54,10 @@ QtObject {
chainId: subscriber.chainId,
accountAddress: subscriber.accountAddress,
tokenType: subscriber.tokenType,
- isOwnerDeployment: subscriber.isOwnerDeployment
+ isOwnerDeployment: subscriber.isOwnerDeployment,
+ ownerToken: subscriber.ownerToken,
+ masterToken: subscriber.masterToken,
+ token: subscriber.token
})
isReady: !!subscriber.chainId &&
@@ -101,13 +107,15 @@ QtObject {
component SetSignerFeeSubscription: Subscription {
required property SetSignerFeesSubscriber subscriber
readonly property var requestArgs: ({
+ communityId: subscriber.communityId,
type: TransactionFeesBroker.FeeType.SetSigner,
chainId: subscriber.chainId,
contractAddress: subscriber.contractAddress,
accountAddress: subscriber.accountAddress
})
- isReady: !!subscriber.chainId &&
- !!subscriber.contractAddress &&
+ isReady: !!subscriber.communityId &&
+ !!subscriber.chainId &&
+ !!subscriber.contractAddress &&
!!subscriber.accountAddress &&
subscriber.enabled
@@ -121,83 +129,141 @@ QtObject {
readonly property Component burnFeeSubscriptionComponent: BurnTokenFeeSubscription {}
readonly property Component setSignerFeeSubscriptionComponent: SetSignerFeeSubscription {}
- readonly property SubscriptionBroker feesBroker: SubscriptionBroker {
+ readonly property SubscriptionBrokerCommunities feesBroker: SubscriptionBrokerCommunities {
id: feesBroker
- onRequest: internal.computeFee(topic)
+ onRequest: internal.computeFee(subscriptionId, topic)
}
property Connections communityTokensStoreConnections: Connections {
- target: communityTokensStore
-
- function onDeployFeeUpdated(ethCurrency, fiatCurrency, errorCode, responseId) {
- d.feesBroker.response(responseId, { ethCurrency: ethCurrency, fiatCurrency: fiatCurrency, errorCode: errorCode })
+ target: root.communityTokensStore.communityTokensModuleInst
+
+ function onSuggestedRoutesReady(uuid, ethCurrency, fiatCurrency, costPerPath, errCode, errDescription) {
+ let err = ""
+ if(!!errCode || !!errDescription) {
+ err = "%1 - %2".arg(errCode).arg(WalletUtils.getRouterErrorDetailsOnCode(errCode, errDescription))
+ }
+
+ let jsonFees = [{
+ ethFee: {},
+ fiatFee: {},
+ contractUniqueKey: ""
+ }]
+
+ if (!err && !!costPerPath) {
+ try {
+ jsonFees = JSON.parse(costPerPath)
+ }
+ catch (e) {
+ console.info("parsing fees issue: ", e.message)
+ }
+ }
+
+ d.feesBroker.response(uuid, { ethCurrency: ethCurrency, fiatCurrency: fiatCurrency, fees: jsonFees, error: err })
}
- function onAirdropFeeUpdated(response) {
- d.feesBroker.response(response.requestId, response)
- }
- function onSelfDestructFeeUpdated(ethCurrency, fiatCurrency, errorCode, responseId) {
- d.feesBroker.response(responseId, { ethCurrency: ethCurrency, fiatCurrency: fiatCurrency, errorCode: errorCode })
- }
- function onBurnFeeUpdated(ethCurrency, fiatCurrency, errorCode, responseId) {
- d.feesBroker.response(responseId, { ethCurrency: ethCurrency, fiatCurrency: fiatCurrency, errorCode: errorCode })
- }
- function onSetSignerFeeUpdated(ethCurrency, fiatCurrency, errorCode, responseId) {
- d.feesBroker.response(responseId, { ethCurrency: ethCurrency, fiatCurrency: fiatCurrency, errorCode: errorCode })
- }
}
- function computeFee(topic) {
+ function computeFee(subscriptionId, topic) {
const args = JSON.parse(topic)
switch (args.type) {
case TransactionFeesBroker.FeeType.Airdrop:
- computeAirdropFee(args, topic)
+ computeAirdropFee(subscriptionId, args)
break
case TransactionFeesBroker.FeeType.Deploy:
- computeDeployFee(args, topic)
+ computeDeployFee(subscriptionId, args)
break
case TransactionFeesBroker.FeeType.SelfDestruct:
- computeSelfDestructFee(args, topic)
+ computeSelfDestructFee(subscriptionId, args)
break
case TransactionFeesBroker.FeeType.Burn:
- computeBurnFee(args, topic)
+ computeBurnFee(subscriptionId, args)
break
case TransactionFeesBroker.FeeType.SetSigner:
- computeSetSignerFee(args, topic)
+ computeSetSignerFee(subscriptionId, args)
break
default:
console.error("Unknown fee type: " + args.type)
}
}
- function computeAirdropFee(args, topic) {
+ function computeAirdropFee(subscriptionId, args) {
communityTokensStore.computeAirdropFee(
+ subscriptionId,
args.communityId,
args.contractKeysAndAmounts,
args.addressesToAirdrop,
- args.feeAccountAddress,
- topic)
+ args.feeAccountAddress)
}
- function computeDeployFee(args, topic) {
- communityTokensStore.computeDeployFee(args.communityId, args.chainId, args.accountAddress, args.tokenType, args.isOwnerDeployment, topic)
+ function computeDeployFee(subscriptionId, args) {
+ if (args.isOwnerDeployment) {
+ communityTokensStore.computeDeployTokenOwnerFee(
+ subscriptionId,
+ args.communityId,
+ args.ownerToken.chainId,
+ args.ownerToken.accountAddress,
+ args.ownerToken.name,
+ args.ownerToken.symbol,
+ args.ownerToken.description,
+ args.ownerToken.artworkSource,
+ args.ownerToken.artworkCropRect,
+ args.masterToken.name,
+ args.masterToken.symbol,
+ args.masterToken.description)
+ return
+ }
+
+ if (args.tokenType === Constants.TokenType.ERC721) {
+ communityTokensStore.computeDeployCollectiblesFee(
+ subscriptionId,
+ args.communityId,
+ args.token.key,
+ args.token.chainId,
+ args.token.accountAddress,
+ args.token.name,
+ args.token.symbol,
+ args.token.description,
+ args.token.supply,
+ args.token.infiniteSupply,
+ args.token.transferable,
+ args.token.remotelyDestruct,
+ args.token.artworkSource,
+ args.token.artworkCropRect)
+ return
+
+ }
+
+ communityTokensStore.computeDeployAssetsFee(
+ subscriptionId,
+ args.communityId,
+ args.token.key,
+ args.token.chainId,
+ args.token.accountAddress,
+ args.token.name,
+ args.token.symbol,
+ args.token.description,
+ args.token.supply,
+ args.token.infiniteSupply,
+ args.token.decimals,
+ args.token.artworkSource,
+ args.token.artworkCropRect)
}
- function computeSelfDestructFee(args, topic) {
- communityTokensStore.computeSelfDestructFee(args.walletsAndAmounts, args.tokenKey, args.accountAddress, topic)
+ function computeSelfDestructFee(subscriptionId, args) {
+ communityTokensStore.computeSelfDestructFee(subscriptionId, args.walletsAndAmounts, args.tokenKey, args.accountAddress)
}
- function computeBurnFee(args, topic) {
+ function computeBurnFee(subscriptionId, args) {
console.assert(typeof args.amount === "string")
- communityTokensStore.computeBurnFee(args.tokenKey, args.amount, args.accountAddress, topic)
+ communityTokensStore.computeBurnFee(subscriptionId, args.tokenKey, args.amount, args.accountAddress)
}
- function computeSetSignerFee(args, topic) {
- communityTokensStore.computeSetSignerFee(args.chainId, args.contractAddress, args.accountAddress, topic)
+ function computeSetSignerFee(subscriptionId, args) {
+ communityTokensStore.computeSetSignerFee(subscriptionId, args.communityId, args.chainId, args.contractAddress, args.accountAddress)
}
}
diff --git a/ui/app/AppLayouts/Communities/panels/AirdropsSettingsPanel.qml b/ui/app/AppLayouts/Communities/panels/AirdropsSettingsPanel.qml
index bf7c55a85a9..7707c5d96db 100644
--- a/ui/app/AppLayouts/Communities/panels/AirdropsSettingsPanel.qml
+++ b/ui/app/AppLayouts/Communities/panels/AirdropsSettingsPanel.qml
@@ -44,6 +44,7 @@ StackView {
signal navigateToMintTokenSettings(bool isAssetType)
signal registerAirdropFeeSubscriber(var feeSubscriber)
signal enableNetwork(int chainId)
+ signal stopUpdatingFees()
function navigateBack() {
pop(StackView.Immediate)
@@ -139,6 +140,14 @@ StackView {
d.addAddresses.connect(view.addAddresses)
}
+ onCalculateFees: {
+ root.registerAirdropFeeSubscriber(feesSubscriber)
+ }
+
+ onStopUpdatingFees: {
+ root.stopUpdatingFees()
+ }
+
AirdropFeesSubscriber {
id: feesSubscriber
enabled: view.visible && view.showingFees
@@ -146,7 +155,6 @@ StackView {
contractKeysAndAmounts: view.selectedContractKeysAndAmounts
addressesToAirdrop: view.selectedAddressesToAirdrop
feeAccountAddress: view.selectedFeeAccount
- Component.onCompleted: root.registerAirdropFeeSubscriber(feesSubscriber)
}
}
}
diff --git a/ui/app/AppLayouts/Communities/panels/MintTokensSettingsPanel.qml b/ui/app/AppLayouts/Communities/panels/MintTokensSettingsPanel.qml
index a7a70d12a4d..68fd0081673 100644
--- a/ui/app/AppLayouts/Communities/panels/MintTokensSettingsPanel.qml
+++ b/ui/app/AppLayouts/Communities/panels/MintTokensSettingsPanel.qml
@@ -82,6 +82,7 @@ StackView {
signal registerDeployFeesSubscriber(var feeSubscriber)
signal registerSelfDestructFeesSubscriber(var feeSubscriber)
signal registerBurnTokenFeesSubscriber(var feeSubscriber)
+ signal stopUpdatingFees()
signal startTokenHoldersManagement(int chainId, string address)
signal stopTokenHoldersManagement()
@@ -269,6 +270,10 @@ StackView {
isOwnerDeployment: editOwnerTokenView.ownerToken.isPrivilegedToken
accountAddress: editOwnerTokenView.ownerToken.accountAddress
enabled: editOwnerTokenView.visible || signMintPopup.visible
+
+ ownerToken: editOwnerTokenView.ownerToken
+ masterToken: editOwnerTokenView.tMasterToken
+
Component.onCompleted: root.registerDeployFeesSubscriber(feeSubscriber)
}
@@ -407,6 +412,14 @@ StackView {
StackView.Immediate)
}
+ onCalculateFees: {
+ root.registerDeployFeesSubscriber(deployFeeSubscriber)
+ }
+
+ onStopUpdatingFees: {
+ root.stopUpdatingFees()
+ }
+
DeployFeesSubscriber {
id: deployFeeSubscriber
communityId: root.communityId
@@ -415,7 +428,8 @@ StackView {
isOwnerDeployment: editView.token.isPrivilegedToken
accountAddress: editView.token.accountAddress
enabled: editView.visible
- Component.onCompleted: root.registerDeployFeesSubscriber(deployFeeSubscriber)
+
+ token: editView.token
}
}
}
@@ -464,7 +478,14 @@ StackView {
isOwnerDeployment: preview.token.isPrivilegedToken
accountAddress: preview.token.accountAddress
enabled: preview.visible || signMintPopup.visible
- Component.onCompleted: root.registerDeployFeesSubscriber(feeSubscriber)
+
+ token: preview.token
+
+ Component.onCompleted: {
+ Qt.callLater(function () {
+ root.registerDeployFeesSubscriber(feeSubscriber)
+ })
+ }
}
SignTransactionsPopup {
@@ -660,8 +681,6 @@ StackView {
accountAddress: tokenMasterActionPopup.selectedAccount
tokenKey: view.token.key
enabled: tokenMasterActionPopup.opened
- Component.onCompleted: root.registerSelfDestructFeesSubscriber(
- selfDestructFeesSubscriber)
}
SignTransactionsPopup {
@@ -819,6 +838,18 @@ StackView {
alertPopup.open()
}
+ onCalculateFees: {
+ root.registerSelfDestructFeesSubscriber(remotelyDestructFeeSubscriber)
+ }
+
+ onStopUpdatingFees: {
+ root.stopUpdatingFees()
+ }
+
+ onClosed: {
+ root.stopUpdatingFees()
+ }
+
SelfDestructFeesSubscriber {
id: remotelyDestructFeeSubscriber
@@ -826,7 +857,6 @@ StackView {
accountAddress: remotelyDestructPopup.selectedAccount
tokenKey: view.token.key
enabled: remotelyDestructPopup.tokenCount > 0 && accountAddress !== "" && (remotelyDestructPopup.opened || signTransactionPopup.opened)
- Component.onCompleted: root.registerSelfDestructFeesSubscriber(remotelyDestructFeeSubscriber)
}
}
@@ -863,6 +893,18 @@ StackView {
signTransactionPopup.open()
}
+ onCalculateFees: {
+ root.registerBurnTokenFeesSubscriber(burnTokensFeeSubscriber)
+ }
+
+ onStopUpdatingFees: {
+ root.stopUpdatingFees()
+ }
+
+ onClosed: {
+ root.stopUpdatingFees()
+ }
+
BurnTokenFeesSubscriber {
id: burnTokensFeeSubscriber
@@ -873,7 +915,6 @@ StackView {
tokenKey: tokenViewPage.token.key
accountAddress: burnTokensPopup.selectedAccountAddress
enabled: burnTokensPopup.visible || signTransactionPopup.visible
- Component.onCompleted: root.registerBurnTokenFeesSubscriber(burnTokensFeeSubscriber)
}
}
diff --git a/ui/app/AppLayouts/Communities/popups/BurnTokensPopup.qml b/ui/app/AppLayouts/Communities/popups/BurnTokensPopup.qml
index 20528dea441..3cdde29f584 100644
--- a/ui/app/AppLayouts/Communities/popups/BurnTokensPopup.qml
+++ b/ui/app/AppLayouts/Communities/popups/BurnTokensPopup.qml
@@ -43,6 +43,8 @@ StatusDialog {
signal burnClicked(string burnAmount, string accountAddress)
signal cancelClicked
signal enableNetwork
+ signal calculateFees()
+ signal stopUpdatingFees()
QtObject {
id: d
@@ -105,6 +107,7 @@ StatusDialog {
}
Item {
+ enabled: !showFees.checked
Layout.bottomMargin: 12
Layout.leftMargin: -Theme.halfPadding
Layout.fillWidth: true
@@ -169,8 +172,23 @@ StatusDialog {
Layout.fillWidth: true
}
+ StatusSwitch {
+ id: showFees
+ enabled: d.isFormValid
+ text: qsTr("Show fees (will be enabled once the form is filled)")
+
+ onCheckedChanged: {
+ if(checked) {
+ root.calculateFees()
+ return
+ }
+ root.stopUpdatingFees()
+ }
+ }
+
FeesBox {
id: feesBox
+ visible: showFees.checked
Layout.fillWidth: true
placeholderText: qsTr("Choose number of tokens to burn to see gas fees")
@@ -235,13 +253,14 @@ StatusDialog {
normalColor: "transparent"
onClicked: {
+ root.stopUpdatingFees()
root.cancelClicked()
close()
}
}
StatusButton {
- enabled: d.isFormValid && !d.isFeeError && !root.isFeeLoading
+ enabled: showFees.checked && !d.isFeeError && !root.isFeeLoading
&& root.feeText !== ""
text: qsTr("Burn tokens")
type: StatusBaseButton.Type.Danger
diff --git a/ui/app/AppLayouts/Communities/popups/FinaliseOwnershipPopup.qml b/ui/app/AppLayouts/Communities/popups/FinaliseOwnershipPopup.qml
index c7d3146aec1..39f67000db7 100644
--- a/ui/app/AppLayouts/Communities/popups/FinaliseOwnershipPopup.qml
+++ b/ui/app/AppLayouts/Communities/popups/FinaliseOwnershipPopup.qml
@@ -35,10 +35,14 @@ StatusDialog {
// Account expected roles: address, name, color, emoji, walletType
property var accounts
+ readonly property alias selectedAccountAddress: d.accountAddress
+
signal finaliseOwnershipClicked
signal rejectClicked
signal visitCommunityClicked
signal openControlNodeDocClicked(string link)
+ signal calculateFees()
+ signal stopUpdatingFees()
QtObject {
id: d
@@ -47,6 +51,7 @@ StatusDialog {
readonly property int init: 0
readonly property int finalise: 1
+ property bool feesActive: false
property bool ackCheck: false
// Fees related props:
@@ -107,7 +112,7 @@ StatusDialog {
PropertyChanges {
target: acceptBtn
text: qsTr("Make this device the control node and update smart contract")
- enabled: d.ackCheck && !root.isFeeLoading && root.feeErrorText === ""
+ enabled: d.feesActive && !root.isFeeLoading && root.feeErrorText === ""
onClicked: root.finaliseOwnershipClicked()
}
@@ -142,6 +147,7 @@ StatusDialog {
text: qsTr("I don't want to be the owner")
onClicked: {
+ root.stopUpdatingFees()
root.rejectClicked()
close()
}
@@ -292,8 +298,24 @@ StatusDialog {
text: qsTr("This transaction updates the %1 Community smart contract, making you the %1 Community owner.").arg(root.communityName)
}
+ StatusSwitch {
+ id: showFees
+ enabled: d.ackCheck
+ text: qsTr("Show fees (will be enabled once acknowledge confirmed)")
+
+ onCheckedChanged: {
+ d.feesActive = checked
+ if(checked) {
+ root.calculateFees()
+ return
+ }
+ root.stopUpdatingFees()
+ }
+ }
+
FeesBox {
id: feesBox
+ visible: showFees.checked
Layout.fillWidth: true
implicitWidth: 0
@@ -324,6 +346,7 @@ StatusDialog {
}
StatusCheckBox {
+ enabled: !showFees.checked
Layout.topMargin: -Theme.halfPadding
Layout.fillWidth: true
diff --git a/ui/app/AppLayouts/Communities/popups/RemotelyDestructPopup.qml b/ui/app/AppLayouts/Communities/popups/RemotelyDestructPopup.qml
index 6e902bb6418..2d51a831b92 100644
--- a/ui/app/AppLayouts/Communities/popups/RemotelyDestructPopup.qml
+++ b/ui/app/AppLayouts/Communities/popups/RemotelyDestructPopup.qml
@@ -40,6 +40,8 @@ StatusDialog {
signal remotelyDestructClicked(var walletsAndAmounts, string accountAddress)
signal enableNetwork
+ signal calculateFees()
+ signal stopUpdatingFees()
QtObject {
id: d
@@ -101,9 +103,25 @@ StatusDialog {
onSelfDestructRemoved: d.clearTokensToDestruct(walletAddress)
}
+ StatusSwitch {
+ id: showFees
+ enabled: d.tokenCount > 0
+ text: qsTr("Show fees (will be enabled once the form is filled)")
+
+ onCheckedChanged: {
+ if(checked) {
+ root.calculateFees()
+ return
+ }
+ root.stopUpdatingFees()
+ }
+ }
+
FeesBox {
id: feesBox
+ visible: showFees.checked
+
Layout.fillWidth: true
Layout.bottomMargin: networkWarningPanel.visible ? 0 : 16
Layout.leftMargin: 16
@@ -152,12 +170,13 @@ StatusDialog {
StatusFlatButton {
text: qsTr("Cancel")
onClicked: {
+ root.stopUpdatingFees()
root.close()
}
}
StatusButton {
- enabled: d.tokenCount > 0
text: qsTr("Remotely destruct %n token(s)", "", d.tokenCount)
+ enabled: showFees.checked
type: StatusBaseButton.Type.Danger
onClicked: {
diff --git a/ui/app/AppLayouts/Communities/views/CommunitySettingsView.qml b/ui/app/AppLayouts/Communities/views/CommunitySettingsView.qml
index 751d09af20d..c4464fae93d 100644
--- a/ui/app/AppLayouts/Communities/views/CommunitySettingsView.qml
+++ b/ui/app/AppLayouts/Communities/views/CommunitySettingsView.qml
@@ -92,7 +92,10 @@ StatusSectionLayout {
d.goTo(section, subSection)
}
- onBackButtonClicked: stackLayout.children[d.currentIndex].item.navigateBack()
+ onBackButtonClicked: {
+ root.rootStore.communityTokensStore.stopUpdatesForSuggestedRoute()
+ stackLayout.children[d.currentIndex].item.navigateBack()
+ }
leftPanel: Item {
anchors.fill: parent
@@ -179,6 +182,7 @@ StatusSectionLayout {
currentIndex: d.currentIndex
onCurrentIndexChanged: {
+ root.rootStore.communityTokensStore.stopUpdatesForSuggestedRoute()
children[currentIndex].active = true
}
@@ -368,6 +372,7 @@ StatusSectionLayout {
readonly property bool sectionEnabled: true
sourceComponent: MintTokensSettingsPanel {
+ id: mintTokensSettingsPanel
enabledChainIds: root.enabledChainIds
readonly property CommunityTokensStore communityTokensStore:
@@ -397,49 +402,75 @@ StatusSectionLayout {
accounts: root.walletAccountsModel
referenceAssetsBySymbolModel: root.tokensStore.assetsBySymbolModel
- onRegisterDeployFeesSubscriber: d.feesBroker.registerDeployFeesSubscriber(feeSubscriber)
+ onStopUpdatingFees: {
+ communityTokensStore.stopUpdatesForSuggestedRoute()
+ }
- onRegisterSelfDestructFeesSubscriber: d.feesBroker.registerSelfDestructFeesSubscriber(feeSubscriber)
+ onRegisterDeployFeesSubscriber: {
+ d.feesBroker.registerDeployFeesSubscriber(feeSubscriber)
+ }
+
+ onRegisterSelfDestructFeesSubscriber: {
+ d.feesBroker.registerSelfDestructFeesSubscriber(feeSubscriber)
+ }
- onRegisterBurnTokenFeesSubscriber: d.feesBroker.registerBurnFeesSubscriber(feeSubscriber)
+ onRegisterBurnTokenFeesSubscriber: {
+ d.feesBroker.registerBurnFeesSubscriber(feeSubscriber)
+ }
- onStartTokenHoldersManagement: communityTokensStore.startTokenHoldersManagement(root.community.id, chainId, address)
+ onStartTokenHoldersManagement: {
+ communityTokensStore.startTokenHoldersManagement(root.community.id, chainId, address)
+ }
- onStopTokenHoldersManagement: communityTokensStore.stopTokenHoldersManagement()
+ onStopTokenHoldersManagement: {
+ communityTokensStore.stopTokenHoldersManagement()
+ }
onEnableNetwork: root.enableNetwork(chainId)
- onMintCollectible:
- communityTokensStore.deployCollectible(
- root.community.id, collectibleItem)
+ onMintCollectible: {
+ communityTokensStore.authenticateAndTransfer()
+ }
- onMintAsset:
- communityTokensStore.deployAsset(root.community.id, assetItem)
+ onMintAsset: {
- onMintOwnerToken:
- communityTokensStore.deployOwnerToken(
- root.community.id, ownerToken, tMasterToken)
+ communityTokensStore.authenticateAndTransfer()
+ }
- onRemotelyDestructCollectibles:
- communityTokensStore.remoteSelfDestructCollectibles(
- root.community.id, walletsAndAmounts, tokenKey, accountAddress)
+ onMintOwnerToken: {
+ communityTokensStore.authenticateAndTransfer()
+ }
+
+ onRemotelyDestructCollectibles: {
+ communityTokensStore.authenticateAndTransfer()
+ }
+
+ onRemotelyDestructAndBan: {
- onRemotelyDestructAndBan:
communityTokensStore.remotelyDestructAndBan(
root.community.id, contactId, tokenKey, accountAddress)
+ }
+
+ onRemotelyDestructAndKick: {
- onRemotelyDestructAndKick:
communityTokensStore.remotelyDestructAndKick(
root.community.id, contactId, tokenKey, accountAddress)
+ }
+
+ onBurnToken: {
+
+ communityTokensStore.authenticateAndTransfer()
+ }
- onBurnToken:
- communityTokensStore.burnToken(root.community.id, tokenKey, amount, accountAddress)
+ onDeleteToken: {
- onDeleteToken:
communityTokensStore.deleteToken(root.community.id, tokenKey)
+ }
+
+ onRefreshToken: {
- onRefreshToken:
communityTokensStore.refreshToken(tokenKey)
+ }
onAirdropToken: {
root.goTo(Constants.CommunitySettingsSections.Airdrops)
@@ -451,8 +482,13 @@ StatusSectionLayout {
airdropPanelLoader.item.addAddresses(addresses)
}
- onKickUserRequested: root.rootStore.removeUserFromCommunity(contactId)
- onBanUserRequested: root.rootStore.banUserFromCommunity(contactId)
+ onKickUserRequested: {
+ root.rootStore.removeUserFromCommunity(contactId)
+ }
+
+ onBanUserRequested: {
+ root.rootStore.banUserFromCommunity(contactId)
+ }
}
}
@@ -545,35 +581,31 @@ StatusSectionLayout {
]
}
- Connections {
- target: root.rootStore.communityTokensStore
- function onAirdropStateChanged(communityId, tokenName, chainName, status, url) {
- if (root.community.id !== communityId) {
- return
- }
- if (status == Constants.ContractTransactionStatus.InProgress) {
- airdropsSettingsPanel.navigateBack()
- }
- }
- }
membersModel: root.joinedMembers
enabledChainIds: root.enabledChainIds
onEnableNetwork: root.enableNetwork(chainId)
accountsModel: root.walletAccountsModel
- onAirdropClicked: communityTokensStore.airdrop(
- root.community.id, airdropTokens, addresses,
- feeAccountAddress)
+ onAirdropClicked: {
+ communityTokensStore.authenticateAndTransfer()
+ }
onNavigateToMintTokenSettings: {
root.goTo(Constants.CommunitySettingsSections.MintTokens)
mintPanelLoader.item.openNewTokenForm(isAssetType)
}
- onRegisterAirdropFeeSubscriber: d.feesBroker.registerAirdropFeesSubscriber(feeSubscriber)
+ onStopUpdatingFees: {
+ communityTokensStore.stopUpdatesForSuggestedRoute()
+ }
+
+ onRegisterAirdropFeeSubscriber: {
+ d.feesBroker.registerAirdropFeesSubscriber(feeSubscriber)
+ }
+
}
}
}
@@ -706,159 +738,6 @@ StatusSectionLayout {
}
- Connections {
- target: rootStore.communityTokensStore
-
- function onRemoteDestructStateChanged(communityId, tokenName, status, url) {
- if (root.community.id !== communityId)
- return
-
- let title = ""
- let loading = false
- let type = Constants.ephemeralNotificationType.normal
-
- switch (status) {
- case Constants.ContractTransactionStatus.InProgress:
- title = qsTr("Remotely destroying tokens...")
- loading = true
- break
- case Constants.ContractTransactionStatus.Completed:
- title = qsTr("%1 tokens destroyed").arg(tokenName)
- type = Constants.ephemeralNotificationType.success
- break
- case Constants.ContractTransactionStatus.Failed:
- title = qsTr("%1 tokens destruction failed").arg(tokenName)
- break
- default:
- console.warn("Unknown destruction state: "+status)
- return
- }
-
- Global.displayToastMessage(title, qsTr("View on etherscan"), "",
- loading, type, url)
- }
-
- function onAirdropStateChanged(communityId, tokenName, chainName,
- status, url) {
- if (root.community.id !== communityId)
- return
-
- let title = ""
- let loading = false
- let type = Constants.ephemeralNotificationType.normal
-
- switch (status) {
- case Constants.ContractTransactionStatus.InProgress:
- title = qsTr("Airdrop on %1 in progress...").arg(chainName)
- loading = true
- break
- case Constants.ContractTransactionStatus.Completed:
- title = qsTr("Airdrop on %1 in complete").arg(chainName)
- type = Constants.ephemeralNotificationType.success
- break
- case Constants.ContractTransactionStatus.Failed:
- title = qsTr("Airdrop on %1 failed").arg(chainName)
- break
- default:
- console.warn("Unknown airdrop state: "+status)
- return
- }
-
- Global.displayToastMessage(title, qsTr("View on etherscan"), "",
- loading, type, url)
- }
-
- function onBurnStateChanged(communityId, tokenName, status, url) {
- if (root.community.id !== communityId)
- return
-
- let title = ""
- let loading = false
- let type = Constants.ephemeralNotificationType.normal
-
- switch (status) {
- case Constants.ContractTransactionStatus.InProgress:
- title = qsTr("%1 being burned...").arg(tokenName)
- loading = true
- break
- case Constants.ContractTransactionStatus.Completed:
- title = qsTr("%1 burning is complete").arg(tokenName)
- type = Constants.ephemeralNotificationType.success
- break
- case Constants.ContractTransactionStatus.Failed:
- title = qsTr("%1 burning is failed").arg(tokenName)
- break
- default:
- console.warn("Unknown burning state: "+status)
- return
- }
-
- Global.displayToastMessage(title, qsTr("View on etherscan"), "",
- loading, type, url)
- }
-
- function onDeploymentStateChanged(communityId, status, url) {
- if (root.community.id !== communityId)
- return
-
- let title = ""
- let loading = false
- let type = Constants.ephemeralNotificationType.normal
-
- switch (status) {
- case Constants.ContractTransactionStatus.InProgress:
- title = qsTr("Token is being minted...")
- loading = true
- break
- case Constants.ContractTransactionStatus.Completed:
- title = qsTr("Token minting finished")
- type = Constants.ephemeralNotificationType.success
- break
- case Constants.ContractTransactionStatus.Failed:
- title = qsTr("Token minting failed")
- break
- default:
- console.warn("Unknown deploy state: "+status)
- return
- }
-
- Global.displayToastMessage(title, url === "" ? qsTr("Something went wrong") : qsTr("View on etherscan"), "",
- loading, type, url)
- }
-
- function onOwnerTokenDeploymentStateChanged(communityId, status, url) {
- if (root.community.id !== communityId)
- return
-
- if (status === Constants.ContractTransactionStatus.Completed)
- {
- let title1 = qsTr("%1 Owner and TokenMaster tokens minting complete").arg(community.name)
- let title2 = qsTr("%1 Owner token airdropped to you").arg(community.name)
- let title3 = qsTr("%1 Owner and TokenMaster permissions created").arg(community.name)
- let type = Constants.ephemeralNotificationType.normal
-
- Global.displayToastMessage(title1, url, "", true, type, url)
- Global.displayToastMessage(title2, url, "", true, type, url)
- Global.displayToastMessage(title3, url, "", true, type, url)
- } else if (status === Constants.ContractTransactionStatus.Failed) {
- let title = qsTr("%1 Owner and TokenMaster tokens minting failed").arg(community.name)
- let type = Constants.ephemeralNotificationType.normal
- Global.displayToastMessage(title, url, "", true, type, url)
- }
- }
-
- function onOwnerTokenDeploymentStarted(communityId, url) {
- if (root.community.id !== communityId)
- return
-
- let title1 = qsTr("%1 Owner and TokenMaster tokens are being minted...").arg(community.name)
- let title2 = qsTr("Airdropping %1 Owner token to you...").arg(community.name)
- let type = Constants.ephemeralNotificationType.normal
-
- Global.displayToastMessage(title1, url, "", true, type, url)
- Global.displayToastMessage(title2, url, "", true, type, url)
- }
- }
Connections {
target: root.chatCommunitySectionModule
diff --git a/ui/app/AppLayouts/Communities/views/EditAirdropView.qml b/ui/app/AppLayouts/Communities/views/EditAirdropView.qml
index 678c7d48a46..1475f1841bb 100644
--- a/ui/app/AppLayouts/Communities/views/EditAirdropView.qml
+++ b/ui/app/AppLayouts/Communities/views/EditAirdropView.qml
@@ -60,12 +60,16 @@ StatusScrollView {
// Bool property indicating whether the fees are shown
readonly property bool showingFees: d.showFees
+ signal calculateFees()
+ signal stopUpdatingFees()
+
onFeesPerSelectedContractChanged: {
feesModel.clear()
let feeSource = feesPerSelectedContract
- if(!feeSource || feeSource.length === 0) // if no fees are available, show the placeholder text based on selection
+ if(!feeSource || feeSource.length === 0) { // if no fees are available, show the placeholder text based on selection
feeSource = ModelUtils.modelToArray(root.selectedHoldingsModel, ["contractUniqueKey"])
+ }
feeSource.forEach(entry => {
feesModel.append({
@@ -254,6 +258,7 @@ StatusScrollView {
AirdropTokensSelector {
id: tokensSelector
+ enabled: !showFees.checked
property int editedIndex: -1
@@ -406,6 +411,7 @@ StatusScrollView {
AirdropRecipientsSelector {
id: airdropRecipientsSelector
+ enabled: !showFees.checked
addressesModel: addresses
@@ -557,8 +563,25 @@ StatusScrollView {
SequenceColumnLayout.Separator {}
+ StatusSwitch {
+ id: showFees
+ enabled: root.isFullyFilled
+ text: qsTr("Show fees (will be enabled once the form is filled)")
+
+ onCheckedChanged: {
+ if(checked) {
+ root.calculateFees()
+ return
+ }
+ root.stopUpdatingFees()
+ }
+ }
+
+ SequenceColumnLayout.Separator {}
+
FeesBox {
id: feesBox
+ visible: showFees.checked
Layout.fillWidth: true
model: feesModel
diff --git a/ui/app/AppLayouts/Communities/views/EditCommunityTokenView.qml b/ui/app/AppLayouts/Communities/views/EditCommunityTokenView.qml
index a77398a7a75..4b62fdd50ea 100644
--- a/ui/app/AppLayouts/Communities/views/EditCommunityTokenView.qml
+++ b/ui/app/AppLayouts/Communities/views/EditCommunityTokenView.qml
@@ -53,17 +53,21 @@ StatusScrollView {
signal chooseArtWork
signal previewClicked
+ signal calculateFees()
+ signal stopUpdatingFees()
QtObject {
id: d
- readonly property bool isFullyFilled: dropAreaItem.artworkSource.toString().length > 0
+ readonly property bool formFilled: dropAreaItem.artworkSource.toString().length > 0
&& nameInput.valid
&& descriptionInput.valid
&& symbolInput.valid
&& (unlimitedSupplyChecker.checked || (!unlimitedSupplyChecker.checked && parseInt(supplyInput.text) > 0))
&& (!root.isAssetView || (root.isAssetView && assetDecimalsInput.valid))
- && deployFeeSubscriber.feeText !== "" && deployFeeSubscriber.feeErrorText === ""
+ readonly property bool isFullyFilled: d.formFilled
+ && deployFeeSubscriber.feeText !== ""
+ && deployFeeSubscriber.feeErrorText === ""
readonly property int imageSelectorRectWidth: root.isAssetView ? 128 : 290
@@ -110,6 +114,7 @@ StatusScrollView {
DropAndEditImagePanel {
id: dropAreaItem
+ enabled: !showFees.checked
Layout.fillWidth: true
Layout.preferredHeight: d.imageSelectorRectWidth
dataImage: root.token.artworkSource
@@ -129,6 +134,7 @@ StatusScrollView {
CustomStatusInput {
id: nameInput
+ enabled: !showFees.checked
label: qsTr("Name")
text: root.token.name
charLimit: 15
@@ -157,6 +163,7 @@ StatusScrollView {
CustomStatusInput {
id: descriptionInput
+ enabled: !showFees.checked
label: qsTr("Description")
text: root.token.description
charLimit: 280
@@ -177,6 +184,7 @@ StatusScrollView {
CustomStatusInput {
id: symbolInput
+ enabled: !showFees.checked
label: qsTr("Symbol")
text: root.token.symbol
charLimit: 6
@@ -258,6 +266,7 @@ StatusScrollView {
NetworkWarningPanel {
visible: !!root.networkThatIsNotActive
+ enabled: !showFees.checked
Layout.fillWidth: true
Layout.topMargin: Theme.padding
@@ -268,6 +277,7 @@ StatusScrollView {
CustomSwitchRowComponent {
id: unlimitedSupplyChecker
+ enabled: !showFees.checked
label: qsTr("Unlimited supply")
description: qsTr("Enable to allow the minting of additional tokens in the future. Disable to specify a finite supply")
checked: root.token.infiniteSupply
@@ -310,6 +320,7 @@ StatusScrollView {
id: transferableChecker
visible: !root.isAssetView
+ enabled: !showFees.checked
label: checked ? qsTr("Not transferable (Soulbound)") : qsTr("Transferable")
description: qsTr("If enabled, the token is locked to the first address it is sent to and can never be transferred to another address. Useful for tokens that represent Admin permissions")
checked: !root.token.transferable
@@ -321,6 +332,7 @@ StatusScrollView {
id: remotelyDestructChecker
visible: !root.isAssetView
+ enabled: !showFees.checked
label: qsTr("Remotely destructible")
description: qsTr("Enable to allow you to destroy tokens remotely. Useful for revoking permissions from individuals")
checked: !!root.token ? root.token.remotelyDestruct : true
@@ -347,9 +359,26 @@ StatusScrollView {
onTextChanged: root.token.decimals = parseInt(text)
}
+ CustomSwitchRowComponent {
+ id: showFees
+ enabled: d.formFilled
+ label: qsTr("Show fees")
+ description: qsTr("Fees will be enabled once the form is filled")
+
+ onCheckedChanged: {
+ if(checked) {
+ root.calculateFees()
+ return
+ }
+ root.stopUpdatingFees()
+ }
+ }
+
FeesBox {
id: feesBox
+ visible: showFees.checked
+
Layout.fillWidth: true
Layout.topMargin: Theme.padding
diff --git a/ui/app/AppLayouts/Communities/views/MintedTokensView.qml b/ui/app/AppLayouts/Communities/views/MintedTokensView.qml
index 2ad0537a451..3c76036d89b 100644
--- a/ui/app/AppLayouts/Communities/views/MintedTokensView.qml
+++ b/ui/app/AppLayouts/Communities/views/MintedTokensView.qml
@@ -193,9 +193,11 @@ StatusScrollView {
color: Theme.palette.baseColor1
}
]
- onClicked: root.itemClicked(model.contractUniqueKey,
+ onClicked: {
+ root.itemClicked(model.contractUniqueKey,
model.chainId, model.chainName,
model.accountName, model.address)
+ }
}
}
@@ -256,9 +258,11 @@ StatusScrollView {
privilegesLevel: model.privilegesLevel
ornamentColor: model.color
communityId: ""
- onClicked: root.itemClicked(model.contractUniqueKey,
+ onClicked: {
+ root.itemClicked(model.contractUniqueKey,
model.chainId, model.chainName,
model.accountName, model.address)
+ }
}
}
diff --git a/ui/app/AppLayouts/Wallet/services/dapps/internal/TransactionFeesBroker.qml b/ui/app/AppLayouts/Wallet/services/dapps/internal/TransactionFeesBroker.qml
index 459d278d7db..0ba33255686 100644
--- a/ui/app/AppLayouts/Wallet/services/dapps/internal/TransactionFeesBroker.qml
+++ b/ui/app/AppLayouts/Wallet/services/dapps/internal/TransactionFeesBroker.qml
@@ -112,7 +112,6 @@ SQUtils.QObject {
return
subscriber.setEstimatedTime(response.estimatedTime)
}
- notificationInterval: root.interval
}
}
@@ -132,7 +131,6 @@ SQUtils.QObject {
return
subscriber.setGas(response.gasEstimate)
}
- notificationInterval: root.interval
}
}
diff --git a/ui/app/mainui/AppMain.qml b/ui/app/mainui/AppMain.qml
index df1013b2e65..6957e9867ac 100644
--- a/ui/app/mainui/AppMain.qml
+++ b/ui/app/mainui/AppMain.qml
@@ -80,7 +80,9 @@ Item {
property ChatStores.CreateChatPropertiesStore createChatPropertiesStore: ChatStores.CreateChatPropertiesStore {}
property ActivityCenterStore activityCenterStore: ActivityCenterStore {}
property SharedStores.NetworkConnectionStore networkConnectionStore: SharedStores.NetworkConnectionStore {}
- property SharedStores.CommunityTokensStore communityTokensStore: SharedStores.CommunityTokensStore {}
+ property SharedStores.CommunityTokensStore communityTokensStore: SharedStores.CommunityTokensStore {
+ currencyStore: appMain.currencyStore
+ }
property CommunitiesStore communitiesStore: CommunitiesStore {}
readonly property WalletStores.TokensStore tokensStore: WalletStores.RootStore.tokensStore
readonly property WalletStores.WalletAssetsStore walletAssetsStore: WalletStores.RootStore.walletAssetsStore
@@ -279,6 +281,23 @@ Item {
username: string,
publicKey: string,
packId: string,
+ communityId: string,
+ communityName: string,
+ communityInvolvedTokens: int,
+ communityTotalAmount: string,
+ communityAmount1: string,
+ communityAmountInfinite1: bool,
+ communityAssetName1: string,
+ communityAssetDecimals1: int,
+ communityAmount2: string,
+ communityAmountInfinite2: bool,
+ communityAssetName2: string,
+ communityAssetDecimals2: int,
+ communityInvolvedAddress: string,
+ communityNubmerOfInvolvedAddresses: int,
+ communityOwnerTokenName: string,
+ communityMasterTokenName: string,
+ communityDeployedTokenName: string,
status: string,
error: string) {
@@ -302,6 +321,9 @@ Item {
let ensName = d.ensName(username)
let stickersPackName = qsTr("unknown")
+ let sentCommunityAmount1 = ""
+ let sentCommunityAmount2 = ""
+
if (!!txHash) {
toastLink = "%1/%2".arg(appMain.rootStore.getEtherscanTxLink(fromChainId)).arg(txHash)
}
@@ -344,6 +366,16 @@ Item {
}
}
+ if (!!communityAmount1) {
+ let bigIntCommunityAmount1 = SQUtils.AmountsArithmetic.fromString(communityAmount1)
+ sentCommunityAmount1 = SQUtils.AmountsArithmetic.toNumber(bigIntCommunityAmount1, communityAssetDecimals1)
+ }
+
+ if (!!communityAmount2) {
+ let bigIntCommunityAmount2 = SQUtils.AmountsArithmetic.fromString(communityAmount2)
+ sentCommunityAmount2 = SQUtils.AmountsArithmetic.toNumber(bigIntCommunityAmount2, communityAssetDecimals2)
+ }
+
switch(status) {
case Constants.txStatus.sending: {
toastTitle = qsTr("Sending %1 from %2 to %3")
@@ -392,6 +424,60 @@ Item {
}
break
}
+ case Constants.SendType.CommunityDeployAssets: {
+ if (communityAmountInfinite1) {
+ toastTitle = qsTr("Minting infinite %1 tokens for %2 using %3").arg(communityDeployedTokenName).arg(communityName).arg(sender)
+ } else {
+ toastTitle = qsTr("Minting %1 %2 tokens for %3 using %4").arg(sentCommunityAmount1).arg(communityDeployedTokenName).arg(communityName).arg(sender)
+ }
+ break
+ }
+ case Constants.SendType.CommunityDeployCollectibles: {
+ if (communityAmountInfinite1) {
+ toastTitle = qsTr("Minting infinite %1 tokens for %2 using %3").arg(communityDeployedTokenName).arg(communityName).arg(sender)
+ } else {
+ toastTitle = qsTr("Minting %1 %2 tokens for %3 using %4").arg(sentCommunityAmount1).arg(communityDeployedTokenName).arg(communityName).arg(sender)
+ }
+ break
+ }
+ case Constants.SendType.CommunityDeployOwnerToken: {
+ toastTitle = qsTr("Minting %1 and %2 tokens for %3 using %4").arg(communityOwnerTokenName).arg(communityMasterTokenName).arg(communityName).arg(sender)
+ break
+ }
+ case Constants.SendType.CommunityMintTokens: {
+ if (!sentCommunityAmount2) {
+ if (communityNubmerOfInvolvedAddresses === 1 && !!communityInvolvedAddress) {
+ toastTitle = qsTr("Airdropping %1x %2 to %3 using %4").arg(sentCommunityAmount1).arg(communityAssetName1).arg(communityInvolvedAddress).arg(sender)
+ } else {
+ toastTitle = qsTr("Airdropping %1x %2 to %3 addresses using %4").arg(sentCommunityAmount1).arg(communityAssetName1).arg(communityNubmerOfInvolvedAddresses).arg(sender)
+ }
+ } else if(communityInvolvedTokens === 2) {
+ if (communityNubmerOfInvolvedAddresses === 1 && !!communityInvolvedAddress) {
+ toastTitle = qsTr("Airdropping %1x %2 and %3x %4 to %5 using %6").arg(sentCommunityAmount1).arg(communityAssetName1).arg(sentCommunityAmount2).arg(communityAssetName2).arg(communityInvolvedAddress).arg(sender)
+ } else {
+ toastTitle = qsTr("Airdropping %1x %2 and %3x %4 to %5 addresses using %6").arg(sentCommunityAmount1).arg(communityAssetName1).arg(sentCommunityAmount2).arg(communityAssetName2).arg(communityNubmerOfInvolvedAddresses).arg(sender)
+ }
+ } else {
+ toastTitle = qsTr("Airdropping %1 tokens to %2 using %3").arg(communityInvolvedTokens).arg(communityInvolvedAddress).arg(sender)
+ }
+ break
+ }
+ case Constants.SendType.CommunityRemoteBurn: {
+ if (communityNubmerOfInvolvedAddresses === 1 && !!communityInvolvedAddress) {
+ toastTitle = qsTr("Destroying %1x %2 at %3 using %4").arg(sentCommunityAmount1).arg(communityAssetName1).arg(communityInvolvedAddress).arg(sender)
+ } else {
+ toastTitle = qsTr("Destroying %1x %2 at %3 addresses using %4").arg(sentCommunityAmount1).arg(communityAssetName1).arg(communityNubmerOfInvolvedAddresses).arg(sender)
+ }
+ break
+ }
+ case Constants.SendType.CommunityBurn: {
+ toastTitle = qsTr("Burning %1x %2 for %3 using %4").arg(sentCommunityAmount1).arg(communityAssetName1).arg(communityName).arg(sender)
+ break
+ }
+ case Constants.SendType.CommunitySetSignerPubKey: {
+ toastTitle = qsTr("Finalizing ownership for %1 using %2").arg(communityName).arg(sender)
+ break
+ }
case Constants.SendType.Approve: {
console.warn("tx type approve not yet identified as a stand alone path")
break
@@ -456,6 +542,60 @@ Item {
}
break
}
+ case Constants.SendType.CommunityDeployAssets: {
+ if (communityAmountInfinite1){
+ toastTitle = qsTr("Minted infinite %1 tokens for %2 using %3").arg(communityDeployedTokenName).arg(communityName).arg(sender)
+ } else {
+ toastTitle = qsTr("Minted %1 %2 tokens for %3 using %4").arg(sentCommunityAmount1).arg(communityDeployedTokenName).arg(communityName).arg(sender)
+ }
+ break
+ }
+ case Constants.SendType.CommunityDeployCollectibles: {
+ if (communityAmountInfinite1){
+ toastTitle = qsTr("Minted infinite %1 tokens for %2 using %3").arg(communityDeployedTokenName).arg(communityName).arg(sender)
+ } else {
+ toastTitle = qsTr("Minted %1 %2 tokens for %3 using %4").arg(sentCommunityAmount1).arg(communityDeployedTokenName).arg(communityName).arg(sender)
+ }
+ break
+ }
+ case Constants.SendType.CommunityDeployOwnerToken: {
+ toastTitle = qsTr("Minted %1 and %2 tokens for %3 using %4").arg(communityOwnerTokenName).arg(communityMasterTokenName).arg(communityName).arg(sender)
+ break
+ }
+ case Constants.SendType.CommunityMintTokens: {
+ if (!sentCommunityAmount2) {
+ if (communityNubmerOfInvolvedAddresses === 1 && !!communityInvolvedAddress) {
+ toastTitle = qsTr("Airdropped %1x %2 to %3 using %4").arg(sentCommunityAmount1).arg(communityAssetName1).arg(communityInvolvedAddress).arg(sender)
+ } else {
+ toastTitle = qsTr("Airdropped %1x %2 to %3 addresses using %4").arg(sentCommunityAmount1).arg(communityAssetName1).arg(communityNubmerOfInvolvedAddresses).arg(sender)
+ }
+ } else if(communityInvolvedTokens === 2) {
+ if (communityNubmerOfInvolvedAddresses === 1 && !!communityInvolvedAddress) {
+ toastTitle = qsTr("Airdropped %1x %2 and %3x %4 to %5 using %6").arg(sentCommunityAmount1).arg(communityAssetName1).arg(sentCommunityAmount2).arg(communityAssetName2).arg(communityInvolvedAddress).arg(sender)
+ } else {
+ toastTitle = qsTr("Airdropped %1x %2 and %3x %4 to %5 addresses using %6").arg(sentCommunityAmount1).arg(communityAssetName1).arg(sentCommunityAmount2).arg(communityAssetName2).arg(communityNubmerOfInvolvedAddresses).arg(sender)
+ }
+ } else {
+ toastTitle = qsTr("Airdropped %1 tokens to %2 using %3").arg(communityInvolvedTokens).arg(communityInvolvedAddress).arg(sender)
+ }
+ break
+ }
+ case Constants.SendType.CommunityRemoteBurn: {
+ if (communityNubmerOfInvolvedAddresses === 1 && !!communityInvolvedAddress) {
+ toastTitle = qsTr("Destroyed %1x %2 at %3 using %4").arg(sentCommunityAmount1).arg(communityAssetName1).arg(communityInvolvedAddress).arg(sender)
+ } else {
+ toastTitle = qsTr("Destroyed %1x %2 at %3 addresses using %4").arg(sentCommunityAmount1).arg(communityAssetName1).arg(communityNubmerOfInvolvedAddresses).arg(sender)
+ }
+ break
+ }
+ case Constants.SendType.CommunityBurn: {
+ toastTitle = qsTr("Burned %1x %2 for %3 using %4").arg(sentCommunityAmount1).arg(communityAssetName1).arg(communityName).arg(sender)
+ break
+ }
+ case Constants.SendType.CommunitySetSignerPubKey: {
+ toastTitle = qsTr("Finalized ownership for %1 using %2").arg(communityName).arg(sender)
+ break
+ }
case Constants.SendType.Approve: {
console.warn("tx type approve not yet identified as a stand alone path")
break
@@ -514,6 +654,60 @@ Item {
}
break
}
+ case Constants.SendType.CommunityDeployAssets: {
+ if (communityAmountInfinite1){
+ toastTitle = qsTr("Mint failed: infinite %1 tokens for %2 using %3").arg(communityDeployedTokenName).arg(communityName).arg(sender)
+ } else {
+ toastTitle = qsTr("Mint failed: %1 %2 tokens for %3 using %4").arg(sentCommunityAmount1).arg(communityDeployedTokenName).arg(communityName).arg(sender)
+ }
+ break
+ }
+ case Constants.SendType.CommunityDeployCollectibles: {
+ if (communityAmountInfinite1){
+ toastTitle = qsTr("Mint failed: infinite %1 tokens for %2 using %3").arg(communityDeployedTokenName).arg(communityName).arg(sender)
+ } else {
+ toastTitle = qsTr("Mint failed: %1 %2 tokens for %3 using %4").arg(sentCommunityAmount1).arg(communityDeployedTokenName).arg(communityName).arg(sender)
+ }
+ break
+ }
+ case Constants.SendType.CommunityDeployOwnerToken: {
+ toastTitle = qsTr("Mint failed: %1 and %2 tokens for %3 using %4").arg(communityOwnerTokenName).arg(communityMasterTokenName).arg(communityName).arg(sender)
+ break
+ }
+ case Constants.SendType.CommunityMintTokens: {
+ if (!sentCommunityAmount2) {
+ if (communityNubmerOfInvolvedAddresses === 1 && !!communityInvolvedAddress) {
+ toastTitle = qsTr("Airdrop failed: %1x %2 to %3 using %4").arg(sentCommunityAmount1).arg(communityAssetName1).arg(communityInvolvedAddress).arg(sender)
+ } else {
+ toastTitle = qsTr("Airdrop failed: %1x %2 to %3 addresses using %4").arg(sentCommunityAmount1).arg(communityAssetName1).arg(communityNubmerOfInvolvedAddresses).arg(sender)
+ }
+ } else if(communityInvolvedTokens === 2) {
+ if (communityNubmerOfInvolvedAddresses === 1 && !!communityInvolvedAddress) {
+ toastTitle = qsTr("Airdrop failed: %1x %2 and %3x %4 to %5 using %6").arg(sentCommunityAmount1).arg(communityAssetName1).arg(sentCommunityAmount2).arg(communityAssetName2).arg(communityInvolvedAddress).arg(sender)
+ } else {
+ toastTitle = qsTr("Airdrop failed: %1x %2 and %3x %4 to %5 addresses using %6").arg(sentCommunityAmount1).arg(communityAssetName1).arg(sentCommunityAmount2).arg(communityAssetName2).arg(communityNubmerOfInvolvedAddresses).arg(sender)
+ }
+ } else {
+ toastTitle = qsTr("Airdrop failed: %1 tokens to %2 using %3").arg(communityInvolvedTokens).arg(communityInvolvedAddress).arg(sender)
+ }
+ break
+ }
+ case Constants.SendType.CommunityRemoteBurn: {
+ if (communityNubmerOfInvolvedAddresses === 1 && !!communityInvolvedAddress) {
+ toastTitle = qsTr("Destruction failed: %1x %2 at %3 using %4").arg(sentCommunityAmount1).arg(communityAssetName1).arg(communityInvolvedAddress).arg(sender)
+ } else {
+ toastTitle = qsTr("Destruction failed: %1x %2 at %3 addresses using %4").arg(sentCommunityAmount1).arg(communityAssetName1).arg(communityNubmerOfInvolvedAddresses).arg(sender)
+ }
+ break
+ }
+ case Constants.SendType.CommunityBurn: {
+ toastTitle = qsTr("Burn failed: %1x %2 for %3 using %4").arg(sentCommunityAmount1).arg(communityAssetName1).arg(communityName).arg(sender)
+ break
+ }
+ case Constants.SendType.CommunitySetSignerPubKey: {
+ toastTitle = qsTr("Finalize ownership failed: %1 using %2").arg(communityName).arg(sender)
+ break
+ }
case Constants.SendType.Approve: {
console.warn("tx type approve not yet identified as a stand alone path")
break
@@ -525,8 +719,16 @@ Item {
break
}
default:
- console.warn("not supported status")
- return
+ if (!error) {
+ console.warn("not supported status")
+ return
+ } else {
+ const err1 = "cannot_resolve_community" // move to Constants
+ if (error === err1) {
+ Global.displayToastMessage(qsTr("Unknown error resolving community"), "", "", false, Constants.ephemeralNotificationType.normal, "")
+ return
+ }
+ }
}
Global.displayToastMessage(toastTitle, toastSubtitle, toastIcon, toastLoading, toastType, toastLink)
diff --git a/ui/app/mainui/Popups.qml b/ui/app/mainui/Popups.qml
index 54d247176be..a099c1c8f5d 100644
--- a/ui/app/mainui/Popups.qml
+++ b/ui/app/mainui/Popups.qml
@@ -1101,6 +1101,11 @@ QtObject {
readonly property var ownerTokenDetails: root.communityTokensStore.ownerTokenDetails
readonly property var communityData : root.communitiesStore.getCommunityDetailsAsJson(communityId)
+ readonly property TransactionFeesBroker feesBroker: TransactionFeesBroker {
+ communityTokensStore: root.communityTokensStore
+ active: finalisePopup.contentItem.Window.window.active
+ }
+
Component.onCompleted: root.communityTokensStore.asyncGetOwnerTokenDetails(communityId)
communityName: communityData.name
@@ -1124,19 +1129,25 @@ QtObject {
onVisitCommunityClicked: communitiesStore.navigateToCommunity(finalisePopup.communityId)
onOpenControlNodeDocClicked: Global.openLink(link)
- SetSignerFeesSubscriber {
- id: feeSubscriber
+ onCalculateFees: {
+ feesBroker.registerSetSignerFeesSubscriber(feeSubscriber)
+ }
- readonly property TransactionFeesBroker feesBroker: TransactionFeesBroker {
- communityTokensStore: root.communityTokensStore
- active: finalisePopup.contentItem.Window.window.active
- }
+ onStopUpdatingFees: {
+ communityTokensStore.stopUpdatesForSuggestedRoute()
+ }
+
+ onClosed: {
+ communityTokensStore.stopUpdatesForSuggestedRoute()
+ }
+ SetSignerFeesSubscriber {
+ id: feeSubscriber
+ communityId: finalisePopup.communityId
chainId: finalisePopup.ownerTokenDetails.chainId
contractAddress: finalisePopup.ownerTokenDetails.contractAddress
- accountAddress: finalisePopup.ownerTokenDetails.accountAddress
+ accountAddress: finalisePopup.selectedAccountAddress
enabled: finalisePopup.visible || signPopup.visible
- Component.onCompleted: feesBroker.registerSetSignerFeesSubscriber(feeSubscriber)
}
SignTransactionsPopup {
@@ -1155,7 +1166,7 @@ QtObject {
onSignTransactionClicked: {
finalisePopup.close()
- root.communityTokensStore.updateSmartContract(finalisePopup.communityId, finalisePopup.ownerTokenDetails.chainId, finalisePopup.ownerTokenDetails.contractAddress, finalisePopup.ownerTokenDetails.accountAddress)
+ root.communityTokensStore.authenticateAndTransfer()
}
}
diff --git a/ui/app/mainui/ToastsManager.qml b/ui/app/mainui/ToastsManager.qml
index 1badca23254..2b495b93313 100644
--- a/ui/app/mainui/ToastsManager.qml
+++ b/ui/app/mainui/ToastsManager.qml
@@ -61,38 +61,6 @@ QtObject {
communityId)
}
- function onSetSignerStateChanged(communityId, communityName, status, url) {
- if (status === Constants.ContractTransactionStatus.Completed) {
- Global.displayToastMessage(qsTr("%1 smart contract amended").arg(communityName),
- root.viewOptimismExplorerText,
- root.checkmarkCircleAssetName,
- false,
- Constants.ephemeralNotificationType.success,
- url)
- Global.displayToastWithActionMessage(qsTr("Your device is now the control node for %1. You now have full Community admin rights.").arg(communityName),
- qsTr("%1 Community admin").arg(communityName),
- root.checkmarkCircleAssetName,
- "",
- false,
- Constants.ephemeralNotificationType.success,
- ToastsManager.ActionType.NavigateToCommunityAdmin,
- communityId)
- } else if (status === Constants.ContractTransactionStatus.Failed) {
- Global.displayToastMessage(qsTr("%1 smart contract update failed").arg(communityName),
- root.viewOptimismExplorerText,
- root.warningAssetName,
- false,
- Constants.ephemeralNotificationType.danger,
- url)
- } else if (status === Constants.ContractTransactionStatus.InProgress) {
- Global.displayToastMessage(qsTr("Updating %1 smart contract").arg(communityName),
- root.viewOptimismExplorerText,
- "",
- true,
- Constants.ephemeralNotificationType.normal,
- url)
- }
- }
function onCommunityOwnershipDeclined(communityName) {
Global.displayToastWithActionMessage(qsTr("You declined ownership of %1.").arg(communityName),
@@ -105,22 +73,6 @@ QtObject {
"")
}
- // Ownership Sender:
- function onSendOwnerTokenStateChanged(tokenName, status, url) {
- if (status === Constants.ContractTransactionStatus.InProgress) {
- Global.displayToastMessage(qsTr("Sending %1 token").arg(tokenName),
- root.viewOptimismExplorerText,
- "",
- true,
- Constants.ephemeralNotificationType.normal, url)
- } else if (status === Constants.ContractTransactionStatus.Completed) {
- Global.displayToastMessage(qsTr("%1 token sent").arg(tokenName),
- root.viewOptimismExplorerText,
- root.checkmarkCircleAssetName,
- false,
- Constants.ephemeralNotificationType.success, url)
- }
- }
function onOwnershipLost(communityId, communityName) {
Global.displayToastMessage(qsTr("Your device is no longer the control node for %1.
diff --git a/ui/imports/shared/stores/CommunityTokensStore.qml b/ui/imports/shared/stores/CommunityTokensStore.qml
index eac1a210e22..2573639d28e 100644
--- a/ui/imports/shared/stores/CommunityTokensStore.qml
+++ b/ui/imports/shared/stores/CommunityTokensStore.qml
@@ -6,6 +6,8 @@ import utils 1.0
QtObject {
id: root
+ property CurrenciesStore currencyStore
+
property var communityTokensModuleInst: communityTokensModule ?? null
property var mainModuleInst: mainModule ?? null
@@ -21,22 +23,8 @@ QtObject {
JSON.parse(communityTokensModuleInst.ownerTokenDetails)
}
- signal deployFeeUpdated(var ethCurrency, var fiatCurrency, int error, string responseId)
- signal selfDestructFeeUpdated(var ethCurrency, var fiatCurrency, int error, string responseId)
- signal airdropFeeUpdated(var airdropFees)
- signal burnFeeUpdated(var ethCurrency, var fiatCurrency, int error, string responseId)
- signal setSignerFeeUpdated(var ethCurrency, var fiatCurrency, int error, string responseId)
-
- signal deploymentStateChanged(string communityId, int status, string url)
- signal ownerTokenDeploymentStateChanged(string communityId, int status, string url)
- signal remoteDestructStateChanged(string communityId, string tokenName, int status, string url)
- signal burnStateChanged(string communityId, string tokenName, int status, string url)
- signal airdropStateChanged(string communityId, string tokenName, string chainName, int status, string url)
- signal ownerTokenDeploymentStarted(string communityId, string url)
- signal setSignerStateChanged(string communityId, string communityName, int status, string url)
signal ownershipLost(string communityId, string communityName)
signal communityOwnershipDeclined(string communityName)
- signal sendOwnerTokenStateChanged(string tokenName, int status, string url)
signal ownerTokenReceived(string communityId, string communityName)
signal communityTokenReceived(string name, string symbol, string image,
string communityId, string communityName,
@@ -45,47 +33,63 @@ QtObject {
int tokenType, string walletAccountName,
string walletAddress)
- // Minting tokens:
- function deployCollectible(communityId, collectibleItem) {
- if (collectibleItem.key !== "")
- deleteToken(communityId, collectibleItem.key)
+ function authenticateAndTransfer() {
+ communityTokensModuleInst.authenticateAndTransfer()
+ }
+
+ function computeDeployCollectiblesFee(subscriptionId, communityId, cKey, cChainId, cAccountAddress, cName, cSymbol,
+ cDescription, cSupply, cInfiniteSupply, cTransferable, cRemotelyDestruct, cArtworkSource, cArtworkCropRect) {
+ if (cKey !== "")
+ deleteToken(communityId, cKey)
- const jsonArtworkFile = Utils.getImageAndCropInfoJson(collectibleItem.artworkSource, collectibleItem.artworkCropRect)
- communityTokensModuleInst.deployCollectible(communityId, collectibleItem.accountAddress, collectibleItem.name,
- collectibleItem.symbol, collectibleItem.description, collectibleItem.supply,
- collectibleItem.infiniteSupply, collectibleItem.transferable, collectibleItem.remotelyDestruct,
- collectibleItem.chainId, jsonArtworkFile)
+ const jsonArtworkFile = Utils.getImageAndCropInfoJson(cArtworkSource, cArtworkCropRect)
+ communityTokensModuleInst.computeDeployCollectiblesFee(subscriptionId, communityId, cAccountAddress, cName,
+ cSymbol, cDescription, cSupply, cInfiniteSupply,
+ cTransferable, cRemotelyDestruct, cChainId, jsonArtworkFile)
}
- function deployAsset(communityId, assetItem) {
- if (assetItem.key !== "")
- deleteToken(communityId, assetItem.key)
+ function computeDeployAssetsFee(subscriptionId, communityId, aKey, aChainId, aAccountAddress, aName, aSymbol,
+ aDescription, aSupply, aInfiniteSupply, aDecimals, aArtworkSource, aArtworkCropRect) {
+ if (aKey !== "")
+ deleteToken(communityId, aKey)
- const jsonArtworkFile = Utils.getImageAndCropInfoJson(assetItem.artworkSource, assetItem.artworkCropRect)
- communityTokensModuleInst.deployAssets(communityId, assetItem.accountAddress, assetItem.name,
- assetItem.symbol, assetItem.description, assetItem.supply,
- assetItem.infiniteSupply, assetItem.decimals, assetItem.chainId, jsonArtworkFile)
+ const jsonArtworkFile = Utils.getImageAndCropInfoJson(aArtworkSource, aArtworkCropRect)
+ communityTokensModuleInst.computeDeployAssetsFee(subscriptionId, communityId, aAccountAddress, aName,
+ aSymbol, aDescription, aSupply,
+ aInfiniteSupply, aDecimals, aChainId, jsonArtworkFile)
}
- function deployOwnerToken(communityId, ownerToken, tMasterToken) {
- function deployOwnerTokenWithArtwork (communityId, artworkSource, ownerToken, tMasterToken) {
- const jsonArtworkFile = Utils.getImageAndCropInfoJson(artworkSource, ownerToken.artworkCropRect)
- communityTokensModuleInst.deployOwnerToken(communityId, ownerToken.accountAddress, ownerToken.name, ownerToken.symbol, ownerToken.description,
- tMasterToken.name, tMasterToken.symbol, tMasterToken.description, ownerToken.chainId, jsonArtworkFile)
+ function computeDeployTokenOwnerFee(subscriptionId, communityId,
+ otChainId, otAccountAddress, otName, otSymbol, otDescription, otArtworkSource, otArtworkCropRect,
+ tmtName, tmtSymbol, tmtDescription) {
+
+ function deployOwnerTokenWithArtwork (subscriptionId, communityId, artworkSource,
+ otChainId, otAccountAddress, otName, otSymbol, otDescription, otArtworkCropRect,
+ tmtName, tmtSymbol, tmtDescription) {
+ const jsonArtworkFile = Utils.getImageAndCropInfoJson(artworkSource, otArtworkCropRect)
+ communityTokensModuleInst.computeDeployTokenOwnerFee(subscriptionId, communityId, otAccountAddress, otName, otSymbol, otDescription,
+ tmtName, tmtSymbol, tmtDescription, otChainId, jsonArtworkFile)
}
- if (String(ownerToken.artworkSource).startsWith("https://localhost:")) {
- const ownerTokenCopy = Object.assign({}, ownerToken)
- const tMasterTokenCopy = Object.assign({}, tMasterToken)
- Utils.fetchImageBase64(ownerToken.artworkSource, (dataUrl) => {
- deployOwnerTokenWithArtwork(communityId, dataUrl, ownerTokenCopy, tMasterTokenCopy)
+ if (String(otArtworkSource).startsWith("https://localhost:")) {
+ Utils.fetchImageBase64(otArtworkSource, (dataUrl) => {
+ deployOwnerTokenWithArtwork(subscriptionId, communityId, dataUrl,
+ otChainId, otAccountAddress, otName, otSymbol, otDescription, otArtworkCropRect,
+ tmtName, tmtSymbol, tmtDescription)
})
} else {
- deployOwnerTokenWithArtwork(communityId, ownerToken.artworkSource, ownerToken, tMasterToken);
+ deployOwnerTokenWithArtwork(subscriptionId, communityId, otArtworkSource,
+ otChainId, otAccountAddress, otName, otSymbol, otDescription, otArtworkCropRect,
+ tmtName, tmtSymbol, tmtDescription)
}
}
+ function computeAirdropFee(subscriptionId, communityId, contractKeysAndAmounts, addresses, feeAccountAddress) {
+ communityTokensModuleInst.computeAirdropFee(subscriptionId, communityId, JSON.stringify(contractKeysAndAmounts),
+ JSON.stringify(addresses), feeAccountAddress)
+ }
+
function deleteToken(communityId, contractUniqueKey) {
let parts = contractUniqueKey.split("_");
communityTokensModuleInst.removeCommunityToken(communityId, parts[0], parts[1])
@@ -96,9 +100,6 @@ QtObject {
communityTokensModuleInst.refreshCommunityToken(parts[0], parts[1])
}
- function updateSmartContract(communityId, chainId, contractAddress, accountAddress) {
- communityTokensModuleInst.setSigner(communityId, chainId, contractAddress, accountAddress)
- }
function ownershipDeclined(communityId, communityName) {
communityTokensModuleInst.declineOwnership(communityId)
@@ -108,50 +109,6 @@ QtObject {
readonly property Connections connections: Connections {
target: communityTokensModuleInst
- function onDeployFeeUpdated(ethCurrency, fiatCurrency, errorCode, responseId) {
- root.deployFeeUpdated(ethCurrency, fiatCurrency, errorCode, responseId)
- }
-
- function onSelfDestructFeeUpdated(ethCurrency, fiatCurrency, errorCode, responseId) {
- root.selfDestructFeeUpdated(ethCurrency, fiatCurrency, errorCode, responseId)
- }
-
- function onAirdropFeesUpdated(jsonFees) {
- root.airdropFeeUpdated(JSON.parse(jsonFees))
- }
-
- function onBurnFeeUpdated(ethCurrency, fiatCurrency, errorCode, responseId) {
- root.burnFeeUpdated(ethCurrency, fiatCurrency, errorCode, responseId)
- }
-
- function onSetSignerFeeUpdated(ethCurrency, fiatCurrency, errorCode, responseId) {
- root.setSignerFeeUpdated(ethCurrency, fiatCurrency, errorCode, responseId)
- }
-
- function onDeploymentStateChanged(communityId, status, url) {
- root.deploymentStateChanged(communityId, status, url)
- }
-
- function onOwnerTokenDeploymentStateChanged(communityId, status, url) {
- root.ownerTokenDeploymentStateChanged(communityId, status, url)
- }
-
- function onOwnerTokenDeploymentStarted(communityId, url) {
- root.ownerTokenDeploymentStarted(communityId, url)
- }
-
- function onRemoteDestructStateChanged(communityId, tokenName, status, url) {
- root.remoteDestructStateChanged(communityId, tokenName, status, url)
- }
-
- function onAirdropStateChanged(communityId, tokenName, chainName, status, url) {
- root.airdropStateChanged(communityId, tokenName, chainName, status, url)
- }
-
- function onBurnStateChanged(communityId, tokenName, status, url) {
- root.burnStateChanged(communityId, tokenName, status, url)
- }
-
function onOwnerTokenReceived(communityId, communityName, chainId, communityAddress) {
root.ownerTokenReceived(communityId, communityName)
}
@@ -160,37 +117,23 @@ QtObject {
root.communityTokenReceived(name, symbol, image, communityId, communityName, balance, chainId, txHash, isFirst, tokenType, walletAccountName, walletAccountName, walletAddress)
}
- function onSetSignerStateChanged(communityId, communityName, status, url) {
- root.setSignerStateChanged(communityId, communityName, status, url)
- }
-
function onOwnershipNodeLost(communityId, communityName) {
root.ownershipLost(communityId, communityName)
}
+ }
- function onSendOwnerTokenStateChanged(tokenName, status, url) {
- root.sendOwnerTokenStateChanged(tokenName, status, url)
- }
+ function stopUpdatesForSuggestedRoute() {
+ communityTokensModuleInst.stopUpdatesForSuggestedRoute()
}
// Burn:
- function computeBurnFee(tokenKey, amount, accountAddress, requestId) {
+ function computeBurnFee(subscriptionId, tokenKey, amount, accountAddress) {
console.assert(typeof amount === "string")
- communityTokensModuleInst.computeBurnFee(tokenKey, amount, accountAddress, requestId)
- }
-
- function computeAirdropFee(communityId, contractKeysAndAmounts, addresses, feeAccountAddress, requestId) {
- communityTokensModuleInst.computeAirdropFee(
- communityId, JSON.stringify(contractKeysAndAmounts),
- JSON.stringify(addresses), feeAccountAddress, requestId)
+ communityTokensModuleInst.computeBurnFee(subscriptionId, tokenKey, amount, accountAddress)
}
- function computeDeployFee(communityId, chainId, accountAddress, tokenType, isOwnerDeployment, requestId) {
- communityTokensModuleInst.computeDeployFee(communityId, chainId, accountAddress, tokenType, isOwnerDeployment, requestId)
- }
-
- function computeSetSignerFee(chainId, contractAddress, accountAddress, requestId) {
- communityTokensModuleInst.computeSetSignerFee(chainId, contractAddress, accountAddress, requestId)
+ function computeSetSignerFee(subscriptionId, communityId, chainId, contractAddress, accountAddress) {
+ communityTokensModuleInst.computeSetSignerFee(subscriptionId, communityId, chainId, contractAddress, accountAddress)
}
/**
@@ -202,13 +145,10 @@ QtObject {
* }
* ]
*/
- function computeSelfDestructFee(walletsAndAmounts, tokenKey, accountAddress, requestId) {
- communityTokensModuleInst.computeSelfDestructFee(JSON.stringify(walletsAndAmounts), tokenKey, accountAddress, requestId)
+ function computeSelfDestructFee(subscriptionId, walletsAndAmounts, tokenKey, accountAddress) {
+ communityTokensModuleInst.computeSelfDestructFee(subscriptionId, JSON.stringify(walletsAndAmounts), tokenKey, accountAddress)
}
- function remoteSelfDestructCollectibles(communityId, walletsAndAmounts, tokenKey, accountAddress) {
- communityTokensModuleInst.selfDestructCollectibles(communityId, JSON.stringify(walletsAndAmounts), tokenKey, accountAddress)
- }
function remotelyDestructAndBan(communityId, contactId, tokenKey, accountAddress, deleteMessages) {
console.warn("remotelyDestructAndBan, not implemented yet!")
@@ -218,15 +158,7 @@ QtObject {
console.warn("remotelyDestructAndKick, not implemented yet!")
}
- function burnToken(communityId, tokenKey, burnAmount, accountAddress) {
- console.assert(typeof burnAmount === "string")
- communityTokensModuleInst.burnTokens(communityId, tokenKey, burnAmount, accountAddress)
- }
- // Airdrop tokens:
- function airdrop(communityId, airdropTokens, addresses, feeAccountAddress) {
- communityTokensModuleInst.airdropTokens(communityId, JSON.stringify(airdropTokens), JSON.stringify(addresses), feeAccountAddress)
- }
function asyncGetOwnerTokenDetails(communityId) {
communityTokensModuleInst.asyncGetOwnerTokenDetails(communityId)
diff --git a/ui/imports/shared/stores/CurrenciesStore.qml b/ui/imports/shared/stores/CurrenciesStore.qml
index 2e4f37efa56..101d932cc43 100644
--- a/ui/imports/shared/stores/CurrenciesStore.qml
+++ b/ui/imports/shared/stores/CurrenciesStore.qml
@@ -76,4 +76,29 @@ QtObject {
function getCurrentCurrencyAmount(amount) {
return getCurrencyAmount(amount, currentCurrency)
}
+
+ function hexToDec(hex) {
+ return globalUtils.hexToDec(hex)
+ }
+
+ function hexToEth(value) {
+ return hexToEthDenomination(value, "eth")
+ }
+
+ function hexToEthDenomination(value, ethUnit) {
+ let BigOps = SQUtils.AmountsArithmetic
+ if (ethUnit !== "qwei" && ethUnit !== "eth") {
+ console.warn("unsuported conversion")
+ return BigOps.fromNumber(0)
+ }
+ let unitMapping = {
+ "gwei": 9,
+ "eth": 18
+ }
+ let decValue = hexToDec(value)
+ if (!!decValue) {
+ return BigOps.div(BigOps.fromNumber(decValue), BigOps.fromNumber(1, unitMapping[ethUnit]))
+ }
+ return BigOps.fromNumber(0)
+ }
}
diff --git a/ui/imports/utils/Constants.qml b/ui/imports/utils/Constants.qml
index 826225c609b..c2839ecdbb9 100644
--- a/ui/imports/utils/Constants.qml
+++ b/ui/imports/utils/Constants.qml
@@ -1014,6 +1014,13 @@ QtObject {
ERC721Transfer,
ERC1155Transfer,
Swap,
+ CommunityBurn,
+ CommunityDeployAssets,
+ CommunityDeployCollectibles,
+ CommunityDeployOwnerToken,
+ CommunityMintTokens,
+ CommunityRemoteBurn,
+ CommunitySetSignerPubKey,
Approve,
Unknown
}
diff --git a/vendor/status-go b/vendor/status-go
index e4d5622a345..90a72ac4faf 160000
--- a/vendor/status-go
+++ b/vendor/status-go
@@ -1 +1 @@
-Subproject commit e4d5622a345535ddb207163eab2d2d95a37b48a8
+Subproject commit 90a72ac4fafcadef28b592ccdc6a9a9511503062