feat(@desktop/communtiies): Set signer flow

Setting signer logic and computing fees.
AC messages for different transfer ownership states.
Declining ownership logic.
Added `CommunityTokensStore.qml` stub.
Removed deprecated property.

Issue #11964
This commit is contained in:
Noelia 2023-10-23 13:36:33 +02:00 committed by Michał Iskierko
parent e8c0275137
commit 88c09b3941
51 changed files with 730 additions and 104 deletions

View File

@ -225,7 +225,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.transactionService, result.tokenService, result.settingsService, result.walletAccountService, result.activityCenterService, result.communityService)
result.providerService = provider_service.newService(statusFoundation.events, statusFoundation.threadpool, result.ensService)
result.networkConnectionService = network_connection_service.newService(statusFoundation.events, result.walletAccountService, result.networkService, result.nodeService)
result.sharedUrlsService = shared_urls_service.newService(statusFoundation.events, statusFoundation.threadpool)

View File

@ -910,4 +910,4 @@ method onCommunityMemberRevealedAccountsLoaded*(self: Module, communityId, membe
if revealedAccount.isAirdropAddress:
airdropAddress = revealedAccount.address
self.view.setMyRevealedAddressesForCurrentCommunity($(%*addresses), airdropAddress)
self.view.setMyRevealedAddressesForCurrentCommunity($(%*addresses), airdropAddress)

View File

@ -56,6 +56,9 @@ proc init*(self: Controller) =
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)
@ -80,6 +83,18 @@ proc init*(self: Controller) =
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.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.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.events.on(SIGNAL_COMMUNITY_LOST_OWNERSHIP) do(e: Args):
let args = CommunityIdArgs(e)
self.communityTokensModule.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)
proc deployContract*(self: Controller, communityId: string, addressFrom: string, password: string, deploymentParams: DeploymentParameters, tokenMetadata: CommunityTokensMetadataDto, tokenImageCropInfoJson: string, chainId: int) =
self.communityTokensService.deployContract(communityId, addressFrom, password, deploymentParams, tokenMetadata, tokenImageCropInfoJson, chainId)
@ -106,6 +121,9 @@ proc selfDestructCollectibles*(self: Controller, communityId: string, password:
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)
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER, data)
@ -116,6 +134,9 @@ proc getCommunityTokens*(self: Controller, communityId: string): seq[CommunityTo
proc computeDeployFee*(self: Controller, chainId: int, accountAddress: string, tokenType: TokenType, requestId: string) =
self.communityTokensService.computeDeployFee(chainId, accountAddress, tokenType, requestId)
proc computeSetSignerFee*(self: Controller, chainId: int, contractAddress: string, addressFrom: string, requestId: string) =
self.communityTokensService.computeSetSignerFee(chainId, contractAddress, addressFrom, requestId)
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)
@ -138,4 +159,10 @@ proc getTokenMasterToken*(self: Controller, communityId: string): CommunityToken
return self.communityTokensService.getTokenMasterToken(communityId)
proc getCommunityById*(self: Controller, communityId: string): CommunityDto =
return self.communityService.getCommunityById(communityId)
return self.communityService.getCommunityById(communityId)
proc declineOwnership*(self: Controller, communityId: string) =
self.communityTokensService.declineOwnership(communityId)
proc asyncGetOwnerTokenOwnerAddress*(self: Controller, chainId: int, contractAddress: string) =
self.communityTokensService.asyncGetOwnerTokenOwnerAddress(chainId, contractAddress)

View File

@ -24,6 +24,9 @@ method selfDestructCollectibles*(self: AccessInterface, communityId: string, col
method burnTokens*(self: AccessInterface, communityId: string, contractUniqueKey: string, amount: string, addressFrom: 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 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.} =
raise newException(ValueError, "No implementation available")
@ -45,6 +48,9 @@ method resetTempValues*(self: AccessInterface) {.base.} =
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")
@ -63,6 +69,9 @@ method onAirdropFeesComputed*(self: AccessInterface, args: AirdropFeesArgs) {.ba
method onBurnFeeComputed*(self: AccessInterface, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: ComputeFeeErrorCode, responseId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onSetSignerFeeComputed*(self: AccessInterface, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: ComputeFeeErrorCode, responseId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityTokenDeployStateChanged*(self: AccessInterface, communityId: string, chainId: int, transactionHash: string, deployState: DeployState) {.base.} =
raise newException(ValueError, "No implementation available")
@ -83,3 +92,21 @@ method onAirdropStateChanged*(self: AccessInterface, communityId: string, tokenN
method removeCommunityToken*(self: AccessInterface, communityId: string, chainId: int, address: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onOwnerTokenReceived*(self: AccessInterface, communityId: string, communityName: string, chainId: int, contractAddress: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onSetSignerStateChanged*(self: AccessInterface, communityId: string, chainId: int, transactionHash: string, status: ContractTransactionStatus) {.base.} =
raise newException(ValueError, "No implementation available")
method onLostOwnership*(self: AccessInterface, communityId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method declineOwnership*(self: AccessInterface, communityId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onOwnerTokenOwnerAddress*(self: AccessInterface, chainId: int, contractAddress: string, address: string, addressName: string) {.base.} =
raise newException(ValueError, "No implementation available")
method asyncGetOwnerTokenDetails*(self: AccessInterface, communityId: string) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -129,6 +129,12 @@ QtObject:
self.endResetModel()
self.countChanged()
proc getOwnerToken*(self: TokenModel): TokenItem =
for i in 0 ..< self.items.len:
if(self.items[i].tokenDto.privilegesLevel == PrivilegesLevel.Owner):
return self.items[i]
proc appendItem*(self: TokenModel, item: TokenItem) =
let parentModelIndex = newQModelIndex()
defer: parentModelIndex.delete

View File

@ -8,6 +8,7 @@ import ../../../../../app_service/service/community/dto/community
import ../../../../../app_service/service/accounts/utils as utl
import ../../../../../app_service/common/conversion
import ../../../../../app_service/common/types
import ../../../../../app_service/common/utils as common_utils
import ../../../../core/eventemitter
import ../../../../global/global_singleton
import ../../../shared_models/currency_amount
@ -24,6 +25,7 @@ type
SelfDestruct = 3
Burn = 4
DeployOwnerToken = 5
SetSigner = 6
type
Module* = ref object of io_interface.AccessInterface
@ -48,6 +50,7 @@ type
tempMasterDeploymentParams: DeploymentParameters
tempOwnerTokenMetadata: CommunityTokensMetadataDto
tempMasterTokenMetadata: CommunityTokensMetadataDto
tempOwnerTokenCommunity: CommunityDto
proc newCommunityTokensModule*(
parent: parent_interface.AccessInterface,
@ -160,6 +163,14 @@ method burnTokens*(self: Module, communityId: string, contractUniqueKey: string,
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) =
let (ownerTokenAddress, masterTokenAddress, isDeployed) = self.getOwnerAndMasterTokensAddresses(communityId, chainId)
@ -255,6 +266,8 @@ method onUserAuthenticated*(self: Module, password: string) =
self.tempOwnerDeploymentParams, self.tempOwnerTokenMetadata,
self.tempMasterDeploymentParams, self.tempMasterTokenMetadata,
self.tempTokenImageCropInfoJson, 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)
@ -268,6 +281,9 @@ method onAirdropFeesComputed*(self: Module, args: AirdropFeesArgs) =
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)
@ -275,6 +291,9 @@ method computeDeployFee*(self: Module, communityId: string, chainId: int, accoun
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 computeSelfDestructFee*(self: Module, collectiblesToBurnJsonString: string, contractUniqueKey: string, addressFrom: string, requestId: string) =
let walletAndAmountList = self.getWalletAndAmountListFromJson(collectiblesToBurnJsonString)
self.controller.computeSelfDestructFee(walletAndAmountList, contractUniqueKey, addressFrom, requestId)
@ -314,3 +333,45 @@ method onAirdropStateChanged*(self: Module, communityId: string, tokenName: stri
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 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 onLostOwnership*(self: Module, communityId: string) =
let communityDto = self.controller.getCommunityById(communityId)
let communityName = communityDto.name
self.view.emitOwnershipLost(communityId, communityName)
method declineOwnership*(self: Module, communityId: string) =
self.controller.declineOwnership(communityId)
method asyncGetOwnerTokenDetails*(self: Module, communityId: string) =
self.tempOwnerTokenCommunity = self.controller.getCommunityById(communityId)
if self.tempOwnerTokenCommunity.id == "":
error "No community with id", communityId
return
let (chainId, contractAddress) = self.tempOwnerTokenCommunity.getOwnerTokenAddressFromPermissions()
self.controller.asyncGetOwnerTokenOwnerAddress(chainId, contractAddress)
method onOwnerTokenOwnerAddress*(self: Module, chainId: int, contractAddress: string, address: string, addressName: string) =
let chainName = self.getChainName(chainId)
var symbol = ""
for tokenMetadata in self.tempOwnerTokenCommunity.communityTokensMetadata:
if tokenMetadata.addresses[chainId] == contractAddress:
symbol = tokenMetadata.symbol
break
let jsonObj = %* {
"symbol": symbol,
"chainName": chainName,
"accountName": addressName,
"accountAddress": address,
"chainId": chainId,
"contractAddress": contractAddress
}
self.view.setOwnerTokenDetails($jsonObj)

View File

@ -9,6 +9,7 @@ QtObject:
type
View* = ref object of QObject
communityTokensModule: community_tokens_module_interface.AccessInterface
ownerTokenDetails: string
proc load*(self: View) =
discard
@ -45,26 +46,42 @@ QtObject:
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 setSignerStateChanged*(self: View, communityId: string, communityName: string, status: int, url: string) {.signal.}
proc ownershipNodeLost*(self: View, communityId: string, communityName: 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 computeSelfDestructFee*(self: View, collectiblesToBurnJsonString: string, contractUniqueKey: string, addressFrom: string, requestId: string) {.slot.} =
self.communityTokensModule.computeSelfDestructFee(collectiblesToBurnJsonString, contractUniqueKey, addressFrom, requestId)
proc computeBurnFee*(self: View, contractUniqueKey: string, amount: string, addressFrom: string, requestId: string) {.slot.} =
self.communityTokensModule.computeBurnFee(contractUniqueKey, amount, addressFrom, requestId)
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)
@ -93,4 +110,27 @@ QtObject:
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)
self.ownerTokenDeploymentStateChanged(communityId, status, url)
proc emitOwnerTokenReceived*(self: View, communityId: string, communityName: string, chainId: int, contractAddress: string) =
self.ownerTokenReceived(communityId, communityName, chainId, contractAddress)
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 asyncGetOwnerTokenDetails*(self: View, communityId: string) {.slot.} =
self.communityTokensModule.asyncGetOwnerTokenDetails(communityId)
proc ownerTokenDetailsChanged*(self: View) {.signal.}
proc getOwnerTokenDetails*(self: View): string {.slot.} =
return self.ownerTokenDetails
proc setOwnerTokenDetails*(self: View, ownerTokenDetails: string) =
self.ownerTokenDetails = ownerTokenDetails
self.ownerTokenDetailsChanged()
QtProperty[string] ownerTokenDetails:
read = getOwnerTokenDetails
notify = ownerTokenDetailsChanged

View File

@ -786,4 +786,5 @@ QtObject:
proc sharedAddressesForAllNonKeycardKeypairsSigned(self: View) {.signal.}
proc sendSharedAddressesForAllNonKeycardKeypairsSignedSignal*(self: View) =
self.sharedAddressesForAllNonKeycardKeypairsSigned()
self.sharedAddressesForAllNonKeycardKeypairsSigned()

View File

@ -194,6 +194,7 @@ proc init*(self: Controller) =
self.communityTokensService,
setActive = args.fromUserAction
)
self.delegate.onFinaliseOwnershipStatusChanged(args.isPendingOwnershipRequest, args.community.id)
self.events.on(TOGGLE_SECTION) do(e:Args):
let args = ToggleSectionArgs(e)
@ -342,6 +343,10 @@ proc init*(self: Controller) =
self.getRemoteDestructedAmount(communityToken.chainId, communityToken.address))
self.delegate.onBurnStateChanged(communityToken.communityId, communityToken.chainId, communityToken.address, args.status)
self.events.on(SIGNAL_FINALISE_OWNERSHIP_STATUS) do(e: Args):
let args = FinaliseOwnershipStatusArgs(e)
self.delegate.onFinaliseOwnershipStatusChanged(args.isPending, args.communityId)
self.events.on(SIGNAL_REMOTE_DESTRUCT_STATUS) do(e: Args):
let args = RemoteDestructArgs(e)
let communityToken = args.communityToken

View File

@ -153,7 +153,7 @@ method communityJoined*(self: AccessInterface, community: CommunityDto, events:
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service,
setActive: bool = false,) {.base.} =
setActive: bool = false) {.base.} =
raise newException(ValueError, "No implementation available")
method communityEdited*(self: AccessInterface, community: CommunityDto) {.base.} =
@ -231,6 +231,9 @@ method getAppSearchModule*(self: AccessInterface): QVariant {.base.} =
method getContactDetailsAsJson*(self: AccessInterface, publicKey: string, getVerificationRequest: bool, getOnlineStatus: bool): string {.base.} =
raise newException(ValueError, "No implementation available")
method getOwnerTokenAsJson*(self: AccessInterface, communityId: string): string {.base.} =
raise newException(ValueError, "No implementation available")
method isEnsVerified*(self: AccessInterface, publicKey: string): bool {.base.} =
raise newException(ValueError, "No implementation available")
@ -318,12 +321,15 @@ method onOwnerTokenDeployStateChanged*(self: AccessInterface, communityId: strin
method onCommunityTokenSupplyChanged*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, supply: Uint256, remainingSupply: Uint256, destructedAmount: Uint256) {.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityTokenRemoved*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string) =
method onCommunityTokenRemoved*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onBurnStateChanged*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, burnState: ContractTransactionStatus) {.base.} =
raise newException(ValueError, "No implementation available")
method onFinaliseOwnershipStatusChanged*(self: AccessInterface, isPending: bool, communityId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onRemoteDestructed*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, addresses: seq[string]) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -24,6 +24,7 @@ import activity_center/module as activity_center_module
import communities/module as communities_module
import node_section/module as node_section_module
import communities/tokens/models/token_item
import communities/tokens/models/token_model
import network_connection/module as network_connection_module
import shared_urls/module as shared_urls_module
@ -66,6 +67,7 @@ import ../../../app_service/service/network_connection/service as network_connec
import ../../../app_service/service/visual_identity/service as procs_from_visual_identity_service
import ../../../app_service/common/types
import ../../../app_service/common/social_links
import ../../../app_service/common/utils as common_utils
import ../../core/notifications/details
import ../../core/eventemitter
@ -956,7 +958,7 @@ method communityJoined*[T](
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service,
setActive: bool = false,
setActive: bool = false
) =
if self.channelGroupModules.contains(community.id):
# The community is already spectated
@ -1079,6 +1081,22 @@ method getContactDetailsAsJson*[T](self: Module[T], publicKey: string, getVerifi
}
return $jsonObj
# used in FinaliseOwnershipPopup in UI
method getOwnerTokenAsJson*[T](self: Module[T], communityId: string): string =
let item = self.view.model().getItemById(communityId)
if item.id == "":
return
let tokensModel = item.communityTokens()
let ownerToken = tokensModel.getOwnerToken()
let jsonObj = %* {
"symbol": ownerToken.tokenDto.symbol,
"chainName": ownerToken.chainName,
"accountName": ownerToken.accountName,
"accountAddress": ownerToken.tokenDto.deployer,
"contractUniqueKey": common_utils.contractUniqueKey(ownerToken.tokenDto.chainId, ownerToken.tokenDto.address)
}
return $jsonObj
method isEnsVerified*[T](self: Module[T], publicKey: string): bool =
return self.controller.getContact(publicKey).ensVerified
@ -1129,6 +1147,9 @@ method onCommunityTokenDeployStateChanged*[T](self: Module[T], communityId: stri
if item.id != "":
item.updateCommunityTokenDeployState(chainId, contractAddress, deployState)
method onFinaliseOwnershipStatusChanged*[T](self: Module[T], isPending: bool, communityId: string) =
self.view.model().updateIsPendingOwnershipRequest(communityId, isPending)
method onOwnerTokenDeployStateChanged*[T](self: Module[T], communityId: string, chainId: int, ownerContractAddress: string, masterContractAddress: string, deployState: DeployState, transactionHash: string) =
let item = self.view.model().getItemById(communityId)
if item.id != "":

View File

@ -211,6 +211,9 @@ QtObject:
proc getContactDetailsAsJson(self: View, publicKey: string, getVerificationRequest: bool, getOnlineStatus: bool): string {.slot.} =
return self.delegate.getContactDetailsAsJson(publicKey, getVerificationRequest, getOnlineStatus)
proc getOwnerTokenAsJson(self: View, communityId: string): string {.slot.} =
return self.delegate.getOwnerTokenAsJson(communityId)
proc isEnsVerified(self:View, publicKey: string): bool {.slot.} =
return self.delegate.isEnsVerified(publicKey)

View File

@ -1,9 +1,11 @@
import NimQml, Tables, strutils, strformat, sequtils, stint
import NimQml, Tables, strutils, strformat, sequtils, stint, json
import logging
import ./collectibles_item, ./collectible_trait_model
import web3/ethtypes as eth
import backend/activity as backend_activity
import backend/community_tokens_types
import ../../../app_service/common/utils as common_utils
type
CollectibleRole* {.pure.} = enum
@ -379,4 +381,5 @@ QtObject:
# Fallback, create uid from data, because it still might not be fetched
if chainId > 0 and len(tokenAddress) > 0 and len(tokenId) > 0:
return $chainId & "+" & tokenAddress & "+" & tokenId
return ""
return ""

View File

@ -60,6 +60,7 @@ type
pubsubTopic: string
pubsubTopicKey: string
shardIndex: int
isPendingOwnershipRequest: bool
proc initItem*(
id: string,
@ -100,6 +101,7 @@ proc initItem*(
pubsubTopic = "",
pubsubTopicKey = "",
shardIndex = -1,
isPendingOwnershipRequest: bool = false
): SectionItem =
result.id = id
result.sectionType = sectionType
@ -145,6 +147,7 @@ proc initItem*(
result.pubsubTopic = pubsubTopic
result.pubsubTopicKey = pubsubTopicKey
result.shardIndex = shardIndex
result.isPendingOwnershipRequest = isPendingOwnershipRequest
proc isEmpty*(self: SectionItem): bool =
return self.id.len == 0
@ -185,6 +188,7 @@ proc `$`*(self: SectionItem): string =
declinedMemberRequests:{self.declinedMemberRequestsModel},
encrypted:{self.encrypted},
communityTokensModel:{self.communityTokensModel},
isPendingOwnershipRequest:{self.isPendingOwnershipRequest}
]"""
proc id*(self: SectionItem): string {.inline.} =
@ -325,6 +329,12 @@ proc pendingMemberRequests*(self: SectionItem): member_model.Model {.inline.} =
proc declinedMemberRequests*(self: SectionItem): member_model.Model {.inline.} =
self.declinedMemberRequestsModel
proc isPendingOwnershipRequest*(self: SectionItem): bool {.inline.} =
self.isPendingOwnershipRequest
proc setIsPendingOwnershipRequest*(self: var SectionItem, isPending: bool) {.inline.} =
self.isPendingOwnershipRequest = isPending
proc pendingRequestsToJoin*(self: SectionItem): PendingRequestModel {.inline.} =
self.pendingRequestsToJoinModel

View File

@ -46,6 +46,7 @@ type
PubsubTopic
PubsubTopicKey
ShardIndex
IsPendingOwnershipRequest
QtObject:
type
@ -122,6 +123,7 @@ QtObject:
ModelRole.PubsubTopic.int:"pubsubTopic",
ModelRole.PubsubTopicKey.int:"pubsubTopicKey",
ModelRole.ShardIndex.int:"shardIndex",
ModelRole.IsPendingOwnershipRequest.int:"isPendingOwnershipRequest",
}.toTable
method data(self: SectionModel, index: QModelIndex, role: int): QVariant =
@ -213,6 +215,8 @@ QtObject:
result = newQVariant(item.pubsubTopicKey)
of ModelRole.ShardIndex:
result = newQVariant(item.shardIndex)
of ModelRole.IsPendingOwnershipRequest:
result = newQVariant(item.isPendingOwnershipRequest)
proc itemExists*(self: SectionModel, id: string): bool =
for it in self.items:
@ -371,6 +375,15 @@ QtObject:
if item.sectionType == SectionType.Chat or item.sectionType == SectionType.Community:
result += item.notificationsCount
proc updateIsPendingOwnershipRequest*(self: SectionModel, id: string, isPending: bool) =
for i in 0 ..< self.items.len:
if(self.items[i].id == id):
let index = self.createIndex(i, 0, nil)
defer: index.delete
self.items[i].setIsPendingOwnershipRequest(isPending)
self.dataChanged(index, index, @[ModelRole.IsPendingOwnershipRequest.int])
return
proc updateNotifications*(self: SectionModel, id: string, hasNotification: bool, notificationsCount: int) =
for i in 0 ..< self.items.len:
if(self.items[i].id == id):

View File

@ -21,6 +21,11 @@ type ActivityCenterNotificationType* {.pure.}= enum
ContactVerification = 10
ContactRemoved = 11
NewKeypairAddedToPairedDevice = 12
OwnerTokenReceived = 13
OwnershipReceived = 14
OwnershipLost = 15
SetSignerFailed = 16
SetSignerDeclined = 17
type ActivityCenterGroup* {.pure.}= enum
All = 0,
@ -152,7 +157,12 @@ proc activityCenterNotificationTypesByGroup*(group: ActivityCenterGroup) : seq[i
ActivityCenterNotificationType.CommunityKicked.int,
ActivityCenterNotificationType.ContactVerification.int,
ActivityCenterNotificationType.ContactRemoved.int,
ActivityCenterNotificationType.NewKeypairAddedToPairedDevice.int
ActivityCenterNotificationType.NewKeypairAddedToPairedDevice.int,
ActivityCenterNotificationType.OwnerTokenReceived.int,
ActivityCenterNotificationType.OwnershipReceived.int,
ActivityCenterNotificationType.SetSignerFailed.int,
ActivityCenterNotificationType.SetSignerDeclined.int,
ActivityCenterNotificationType.OwnershipLost.int
]
of ActivityCenterGroup.Mentions:
return @[ActivityCenterNotificationType.Mention.int]

View File

@ -306,3 +306,20 @@ QtObject:
except Exception as e:
error "Error marking as dismissed", msg = e.msg
result = e.msg
proc deleteActivityCenterNotifications*(self: Service, notificationIds: seq[string]): string =
try:
discard backend.deleteActivityCenterNotifications(notificationIds)
self.events.emit(SIGNAL_ACTIVITY_CENTER_NOTIFICATIONS_REMOVED, RemoveActivityCenterNotificationsArgs(
notificationIds: notificationIds
))
self.events.emit(SIGNAL_ACTIVITY_CENTER_NOTIFICATIONS_COUNT_MAY_HAVE_CHANGED, Args())
except Exception as e:
error "Error deleting notifications", msg = e.msg
result = e.msg
proc getNotificationForTypeAndCommunityId*(self: Service, notificationType: ActivityCenterNotificationType, communityId: string): ActivityCenterNotificationDto =
let acNotifications = self.getActivityCenterNotifications()
for acNotification in acNotifications:
if acNotification.notificationType == notificationType and acNotification.communityId == communityId:
return acNotification

View File

@ -635,3 +635,15 @@ proc isAdmin*(self: CommunityDto): bool =
proc isPrivilegedUser*(self: CommunityDto): bool =
return self.isControlNode or self.isOwner or self.isTokenMaster or self.isAdmin
proc getOwnerTokenAddressFromPermissions*(self: CommunityDto): (int, string) =
for _, tokenPermission in self.tokenPermissions.pairs:
if tokenPermission.`type` == TokenPermissionType.BecomeTokenOwner:
if len(tokenPermission.tokenCriteria) == 0:
return (0, "")
let addresses = tokenPermission.tokenCriteria[0].contractAddresses
# should be one address
for ch, add in addresses.pairs:
return (ch, add)
return (0, "")

View File

@ -15,6 +15,7 @@ import ../../../app/core/eventemitter
import ../../../app/core/[main]
import ../../../app/core/tasks/[qt, threadpool]
import ../../../backend/communities as status_go
import ../../../backend/community_tokens as tokens_backend
import ../../../app_service/common/types
import ../../../app_service/common/utils
@ -32,6 +33,7 @@ type
communityId*: string # should be set when community is nil (i.e. error occured)
error*: string
fromUserAction*: bool
isPendingOwnershipRequest*: bool
CommunitiesArgs* = ref object of Args
communities*: seq[CommunityDto]
@ -241,6 +243,7 @@ const SIGNAL_CHECK_PERMISSIONS_TO_JOIN_RESPONSE* = "checkPermissionsToJoinRespon
const SIGNAL_CHECK_PERMISSIONS_TO_JOIN_FAILED* = "checkPermissionsToJoinFailed"
const SIGNAL_COMMUNITY_METRICS_UPDATED* = "communityMetricsUpdated"
const SIGNAL_COMMUNITY_LOST_OWNERSHIP* = "communityLostOwnership"
const SIGNAL_COMMUNITY_SHARD_SET* = "communityShardSet"
const SIGNAL_COMMUNITY_SHARD_SET_FAILED* = "communityShardSetFailed"
@ -550,6 +553,12 @@ QtObject:
let prev_community = self.communities[community.id]
# ownership lost
if prev_community.isOwner and not community.isOwner:
self.events.emit(SIGNAL_COMMUNITY_LOST_OWNERSHIP, CommunityIdArgs(communityId: community.id))
let response = tokens_backend.registerLostOwnershipNotification(community.id)
self.activityCenterService.parseActivityCenterResponse(response)
# If there's settings without `id` it means the original
# signal didn't include actual communitySettings, hence we
# assign the settings we already have, otherwise we risk our
@ -958,8 +967,10 @@ QtObject:
self.communities[communityId] = updatedCommunity
self.chatService.loadChannelGroupById(communityId)
let ownerTokenNotification = self.activityCenterService.getNotificationForTypeAndCommunityId(notification.ActivityCenterNotificationType.OwnerTokenReceived, communityId)
self.events.emit(SIGNAL_COMMUNITIES_UPDATE, CommunitiesArgs(communities: @[updatedCommunity]))
self.events.emit(SIGNAL_COMMUNITY_SPECTATED, CommunityArgs(community: updatedCommunity, fromUserAction: true))
self.events.emit(SIGNAL_COMMUNITY_SPECTATED, CommunityArgs(community: updatedCommunity, fromUserAction: true, isPendingOwnershipRequest: (ownerTokenNotification != nil)))
for k, chat in updatedCommunity.chats:
let fullChatId = communityId & chat.id

View File

@ -3,7 +3,7 @@ include ../../common/json_utils
import ../../../backend/eth
import ../../../backend/community_tokens
import ../../../backend/collectibles
import ../../../app/core/tasks/common
include ../../../app/core/tasks/common
import ../../../app/core/tasks/qt
import ../transaction/dto
import ../community/dto/community
@ -87,6 +87,37 @@ const asyncGetDeployFeesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.
"requestId": arg.requestId,
})
type
AsyncSetSignerFeesArg = ref object of QObjectTaskArg
chainId: int
contractAddress: string
addressFrom: string
newSignerPubKey: string
requestId: string
const asyncSetSignerFeesTask: Task = proc(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 response = eth.suggestedFees(arg.chainId).result
feeTable[arg.chainId] = response.toSuggestedFeesDto()
let gasUsed = community_tokens.estimateSetSignerPubKey(arg.chainId, arg.contractAddress, arg.addressFrom, arg.newSignerPubKey).result.getInt
gasTable[(arg.chainId, "")] = gasUsed
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
@ -349,3 +380,27 @@ const getAllCommunityTokensTaskArg: Task = proc(argEncoded: string) {.gcsafe, ni
"error": e.msg
}
arg.finish(output)
type
GetOwnerTokenOwnerAddressArgs = ref object of QObjectTaskArg
chainId*: int
contractAddress*: string
const getOwnerTokenOwnerAddressTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[GetOwnerTokenOwnerAddressArgs](argEncoded)
try:
let response = tokens_backend.getOwnerTokenOwnerAddress(arg.chainId, arg.contractAddress)
let output = %* {
"chainId": arg.chainId,
"contractAddress": arg.contractAddress,
"address": response.result.getStr(),
"error": ""
}
arg.finish(output)
except Exception as e:
let output = %* {
"chainId": arg.chainId,
"contractAddress": arg.contractAddress,
"error": e.msg
}
arg.finish(output)

View File

@ -1,22 +1,18 @@
import json, sequtils, stint, strutils, chronicles
import ../../../../backend/response_type
import ../../../../backend/community_tokens_types
include ../../../common/json_utils
import ../../../common/conversion
import ../../community/dto/community
export community_tokens_types
type
DeployState* {.pure.} = enum
Failed,
InProgress,
Deployed
# determines what is the type of the token: owner, master or normal community contract
type
PrivilegesLevel* {.pure.} = enum
Owner,
TokenMaster,
Community
type
CommunityTokenDto* = object
tokenType*: TokenType

View File

@ -2,14 +2,19 @@ import NimQml, Tables, chronicles, json, stint, strutils, sugar, sequtils
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 ../ens/utils as ens_utils
import ../eth/dto/transaction
from backend/collectibles_types import CollectibleOwner
@ -77,6 +82,13 @@ type
contractAddress*: string
chainId*: int
type
OwnerTokenOwnerAddressArgs* = ref object of Args
chainId*: int
contractAddress*: string
address*: string
addressName*: string
type
RemoteDestructArgs* = ref object of Args
communityToken*: CommunityTokenDto
@ -90,7 +102,6 @@ type
transactionHash*: string
status*: ContractTransactionStatus
type
ComputeFeeArgs* = ref object of Args
ethCurrency*: CurrencyAmount
@ -99,6 +110,13 @@ type
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": self.ethCurrency.toJsonNode(),
@ -143,25 +161,58 @@ type
communityTokens*: seq[CommunityTokenDto]
communityTokenJsonItems*: JsonNode
# Signals which may be emitted by this service:
const SIGNAL_COMMUNITY_TOKEN_DEPLOY_STATUS* = "communityTokenDeployStatus"
const SIGNAL_COMMUNITY_TOKEN_DEPLOYMENT_STARTED* = "communityTokenDeploymentStarted"
const SIGNAL_COMPUTE_DEPLOY_FEE* = "computeDeployFee"
const SIGNAL_COMPUTE_SELF_DESTRUCT_FEE* = "computeSelfDestructFee"
const SIGNAL_COMPUTE_BURN_FEE* = "computeBurnFee"
const SIGNAL_COMPUTE_AIRDROP_FEE* = "computeAirdropFee"
const SIGNAL_COMMUNITY_TOKEN_OWNERS_FETCHED* = "communityTokenOwnersFetched"
const SIGNAL_REMOTE_DESTRUCT_STATUS* = "communityTokenRemoteDestructStatus"
const SIGNAL_BURN_STATUS* = "communityTokenBurnStatus"
const SIGNAL_AIRDROP_STATUS* = "airdropStatus"
const SIGNAL_REMOVE_COMMUNITY_TOKEN_FAILED* = "removeCommunityTokenFailed"
const SIGNAL_COMMUNITY_TOKEN_REMOVED* = "communityTokenRemoved"
const SIGNAL_OWNER_TOKEN_DEPLOY_STATUS* = "ownerTokenDeployStatus"
const SIGNAL_OWNER_TOKEN_DEPLOYMENT_STARTED* = "ownerTokenDeploymentStarted"
const SIGNAL_COMMUNITY_TOKENS_DETAILS_LOADED* = "communityTokenDetailsLoaded"
const SIGNAL_ALL_COMMUNITY_TOKENS_LOADED* = "allCommunityTokensLoaded"
type
OwnerTokenReceivedArgs* = ref object of Args
communityId*: string
communityName*: string
chainId*: int
contractAddress*: string
const SIGNAL_DEPLOY_OWNER_TOKEN* = "deployOwnerToken"
type
FinaliseOwnershipStatusArgs* = ref object of Args
isPending*: bool
communityId*: string
type ContractDetails* = object
chainId*: int
contractAddress*: string
communityId*: string
proc `%`*(self: ContractDetails): JsonNode =
result = %* {
"chainId": self.chainId,
"contractAddress": self.contractAddress,
"communityId": self.communityId,
}
proc toContractDetails*(jsonObj: JsonNode): ContractDetails =
result = ContractDetails()
discard jsonObj.getProp("chainId", result.chainId)
discard jsonObj.getProp("contractAddress", result.contractAddress)
discard jsonObj.getProp("communityId", result.communityId)
# 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_OWNERS_FETCHED* = "communityTokens-communityTokenOwnersFetched"
const SIGNAL_REMOTE_DESTRUCT_STATUS* = "communityTokens-communityTokenRemoteDestructStatus"
const SIGNAL_BURN_STATUS* = "communityTokens-communityTokenBurnStatus"
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_COMMUNITY_TOKENS_DETAILS_LOADED* = "communityTokens-communityTokenDetailsLoaded"
const SIGNAL_ALL_COMMUNITY_TOKENS_LOADED* = "communityTokens-allCommunityTokensLoaded"
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"
QtObject:
type
@ -172,6 +223,8 @@ QtObject:
tokenService: token_service.Service
settingsService: settings_service.Service
walletAccountService: wallet_account_service.Service
acService: ac_service.Service
communityService: community_service.Service
tokenOwnersTimer: QTimer
tokenOwners1SecTimer: QTimer # used to update 1 sec after changes in owners
@ -186,6 +239,7 @@ QtObject:
proc fetchAllTokenOwners*(self: Service)
proc getCommunityTokenOwners*(self: Service, communityId: string, chainId: int, contractAddress: string): seq[CommunityCollectibleOwner]
proc getCommunityToken*(self: Service, chainId: int, address: string): CommunityTokenDto
proc findContractByUniqueId*(self: Service, contractUniqueKey: string): CommunityTokenDto
proc delete*(self: Service) =
delete(self.tokenOwnersTimer)
@ -198,7 +252,9 @@ QtObject:
transactionService: transaction_service.Service,
tokenService: token_service.Service,
settingsService: settings_service.Service,
walletAccountService: wallet_account_service.Service
walletAccountService: wallet_account_service.Service,
acService: ac_service.Service,
communityService: community_service.Service
): Service =
result = Service()
result.QObject.setup
@ -208,6 +264,8 @@ QtObject:
result.tokenService = tokenService
result.settingsService = settingsService
result.walletAccountService = walletAccountService
result.acService = acService
result.communityService = communityService
result.tokenOwnersTimer = newQTimer()
result.tokenOwnersTimer.setInterval(10*60*1000)
signalConnect(result.tokenOwnersTimer, "timeout()", result, "onRefreshTransferableTokenOwners()", 2)
@ -216,10 +274,70 @@ QtObject:
result.tokenOwners1SecTimer.setSingleShot(true)
signalConnect(result.tokenOwners1SecTimer, "timeout()", result, "onFetchTempTokenOwners()", 2)
proc processReceivedCollectiblesWalletEvent(self: Service, jsonMessage: string) =
try:
let dataMessageJson = parseJson(jsonMessage)
let tokenDataPayload = fromJson(dataMessageJson, CommunityCollectiblesReceivedPayload)
for coll in tokenDataPayload.collectibles:
let privilegesLevel = coll.communityHeader.privilegesLevel
let communityId = coll.communityHeader.communityId
let community = self.communityService.getCommunityById(communityId)
if privilegesLevel == PrivilegesLevel.Owner and not community.isOwner():
let communityName = coll.communityHeader.communityName
let chainId = coll.id.contractID.chainID
let contractAddress = coll.id.contractID.address
debug "received owner token", contractAddress=contractAddress, chainId=chainId
let tokenReceivedArgs = OwnerTokenReceivedArgs(communityId: communityId, communityName: communityName, chainId: chainId, contractAddress: contractAddress)
self.events.emit(SIGNAL_OWNER_TOKEN_RECEIVED, tokenReceivedArgs)
let finaliseStatusArgs = FinaliseOwnershipStatusArgs(isPending: true, communityId: communityId)
self.events.emit(SIGNAL_FINALISE_OWNERSHIP_STATUS, finaliseStatusArgs)
let response = tokens_backend.registerOwnerTokenReceivedNotification(communityId)
self.acService.parseActivityCenterResponse(response)
except Exception as e:
error "Error registering owner token received notification", msg=e.msg
proc processSetSignerTransactionEvent(self: Service, transactionArgs: TransactionMinedArgs) =
try:
if not transactionArgs.success:
error "Signer not set"
let contractDetails = transactionArgs.data.parseJson().toContractDetails()
if transactionArgs.success:
# promoteSelfToControlNode will be moved to status-go in next phase
discard tokens_backend.promoteSelfToControlNode(contractDetails.communityId)
let finaliseStatusArgs = FinaliseOwnershipStatusArgs(isPending: false, communityId: contractDetails.communityId)
self.events.emit(SIGNAL_FINALISE_OWNERSHIP_STATUS, finaliseStatusArgs)
let data = SetSignerArgs(status: if transactionArgs.success: ContractTransactionStatus.Completed else: ContractTransactionStatus.Failed,
chainId: transactionArgs.chainId,
transactionHash: transactionArgs.transactionHash,
communityId: contractDetails.communityId)
self.events.emit(SIGNAL_SET_SIGNER_STATUS, data)
let response = if transactionArgs.success: tokens_backend.registerReceivedOwnershipNotification(contractDetails.communityId) else: tokens_backend.registerSetSignerFailedNotification(contractDetails.communityId)
self.acService.parseActivityCenterResponse(response)
let notificationToSetRead = self.acService.getNotificationForTypeAndCommunityId(notification.ActivityCenterNotificationType.OwnerTokenReceived, contractDetails.communityId)
if notificationToSetRead != nil:
let markAsReadProps = MarkAsReadNotificationProperties(
notificationIds: @[notificationToSetRead.id],
communityId: contractDetails.communityId,
notificationTypes: @[notification.ActivityCenterNotificationType.OwnerTokenReceived]
)
discard self.acService.markActivityCenterNotificationRead(notificationToSetRead.id, markAsReadProps)
except Exception as e:
error "Error processing set signer transaction", msg=e.msg
proc init*(self: Service) =
self.fetchAllTokenOwners()
self.tokenOwnersTimer.start()
self.events.on(SignalType.Wallet.event) do(e:Args):
var data = WalletSignal(e)
if data.eventType == collectibles_backend.eventCommunityCollectiblesReceived:
self.processReceivedCollectiblesWalletEvent(data.message)
self.events.on(PendingTransactionTypeDto.SetSigner.event) do(e: Args):
let receivedData = TransactionMinedArgs(e)
self.processSetSignerTransactionEvent(receivedData)
self.events.on(PendingTransactionTypeDto.DeployCommunityToken.event) do(e: Args):
var receivedData = TransactionMinedArgs(e)
try:
@ -425,7 +543,7 @@ QtObject:
debug "Deployment transaction hash ", transactionHash=transactionHash
var ownerToken = self.createCommunityToken(ownerDeploymentParams, ownerTokenMetadata, chainId, temporaryOwnerContractAddress(transactionHash), communityId, addressFrom, PrivilegesLevel.Owner)
var masterToken = self.createCommunityToken(masterDeploymentParams, masterTokenMetadata, chainId, temporaryMasterContractAddress(transactionHash), communityId, addressFrom, PrivilegesLevel.TokenMaster)
var masterToken = self.createCommunityToken(masterDeploymentParams, masterTokenMetadata, chainId, temporaryMasterContractAddress(transactionHash), communityId, addressFrom, PrivilegesLevel.Master)
var croppedImage = croppedImageJson.parseJson
ownerToken.image = croppedImage{"imagePath"}.getStr
@ -673,6 +791,12 @@ QtObject:
let price = self.tokenService.getTokenPrice(cryptoSymbol, currentCurrency)
return cryptoBalance * price
proc findContractByUniqueId*(self: Service, contractUniqueKey: string): CommunityTokenDto =
let allTokens = self.getAllCommunityTokens()
for token in allTokens:
if common_utils.contractUniqueKey(token.chainId, token.address) == contractUniqueKey:
return token
proc computeDeployFee*(self: Service, chainId: int, accountAddress: string, tokenType: TokenType, requestId: string) =
try:
if tokenType != TokenType.ERC20 and tokenType != TokenType.ERC721:
@ -692,6 +816,24 @@ QtObject:
#TODO: handle error - emit error signal
error "Error loading fees", msg = e.msg
proc computeSetSignerFee*(self: Service, chainId: int, contractAddress: string, accountAddress: string, requestId: string) =
try:
let arg = AsyncSetSignerFeesArg(
tptr: cast[ByteAddress](asyncSetSignerFeesTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onSetSignerFees",
chainId: chainId,
contractAddress: contractAddress,
addressFrom: accountAddress,
requestId: requestId,
newSignerPubKey: singletonInstance.userProfile.getPubKey()
)
self.threadpool.start(arg)
except Exception as e:
#TODO: handle error - emit error signal
error "Error loading fees", msg = e.msg
proc computeDeployOwnerContractsFee*(self: Service, chainId: int, accountAddress: string, communityId: string, ownerDeploymentParams: DeploymentParameters, masterDeploymentParams: DeploymentParameters, requestId: string) =
try:
let arg = AsyncDeployOwnerContractsFeesArg(
@ -711,12 +853,6 @@ QtObject:
#TODO: handle error - emit error signal
error "Error loading fees", msg = e.msg
proc findContractByUniqueId*(self: Service, contractUniqueKey: string): CommunityTokenDto =
let allTokens = self.getAllCommunityTokens()
for token in allTokens:
if common_utils.contractUniqueKey(token.chainId, token.address) == contractUniqueKey:
return token
proc getOwnerBalances(self: Service, contractOwners: seq[CommunityCollectibleOwner], ownerAddress: string): seq[CollectibleBalance] =
for owner in contractOwners:
if owner.collectibleOwner.address == ownerAddress:
@ -837,6 +973,35 @@ QtObject:
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.SetSigner,
$(%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) =
try:
let contract = self.findContractByUniqueId(contractUniqueKey)
@ -946,6 +1111,9 @@ QtObject:
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]
@ -1101,5 +1269,47 @@ QtObject:
proc getTokenMasterToken*(self: Service, communityId: string): CommunityTokenDto =
let communityTokens = self.getCommunityTokens(communityId)
for token in communityTokens:
if token.privilegesLevel == PrivilegesLevel.TokenMaster:
return token
if token.privilegesLevel == PrivilegesLevel.Master:
return token
proc declineOwnership*(self: Service, communityId: string) =
let notification = self.acService.getNotificationForTypeAndCommunityId(notification.ActivityCenterNotificationType.OwnerTokenReceived, communityId)
if notification != nil:
discard self.acService.deleteActivityCenterNotifications(@[notification.id])
try:
let response = tokens_backend.registerSetSignerDeclinedNotification(communityId)
self.acService.parseActivityCenterResponse(response)
except Exception as e:
error "Error registering decline set signer notification", msg=e.msg
let finaliseStatusArgs = FinaliseOwnershipStatusArgs(isPending: false, communityId: communityId)
self.events.emit(SIGNAL_FINALISE_OWNERSHIP_STATUS, finaliseStatusArgs)
proc asyncGetOwnerTokenOwnerAddress*(self: Service, chainId: int, contractAddress: string) =
let arg = GetOwnerTokenOwnerAddressArgs(
tptr: cast[ByteAddress](getOwnerTokenOwnerAddressTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onGetOwnerTokenOwner",
chainId: chainId,
contractAddress: contractAddress
)
self.threadpool.start(arg)
proc onGetOwnerTokenOwner*(self:Service, response: string) {.slot.} =
var ownerTokenArgs = OwnerTokenOwnerAddressArgs()
try:
let responseJson = response.parseJson()
ownerTokenArgs.chainId = responseJson{"chainId"}.getInt
ownerTokenArgs.contractAddress = responseJson{"contractAddress"}.getStr
let errorMsg = responseJson["error"].getStr
if errorMsg != "":
error "can't get owner token owner address", errorMsg
else:
ownerTokenArgs.address = responseJson{"address"}.getStr
let acc = self.walletAccountService.getAccountByAddress(ownerTokenArgs.address)
if acc == nil:
error "getAccountByAddress result is nil"
else:
ownerTokenArgs.addressName = acc.name
except Exception:
error "can't get owner token owner address", message = getCurrentExceptionMsg()
self.events.emit(SIGNAL_OWNER_TOKEN_OWNER_ADDRESS, ownerTokenArgs)

View File

@ -31,6 +31,7 @@ type
RemoteDestructCollectible = "RemoteDestructCollectible"
BurnCommunityToken = "BurnCommunityToken"
DeployOwnerToken = "DeployOwnerToken"
SetSigner = "SetSigner"
proc event*(self:PendingTransactionTypeDto):string =
result = "transaction:" & $self

View File

@ -170,6 +170,9 @@ rpc(acceptActivityCenterNotifications, "wakuext"):
rpc(dismissActivityCenterNotifications, "wakuext"):
ids: seq[string]
rpc(deleteActivityCenterNotifications, "wakuext"):
ids: seq[string]
rpc(hasUnseenActivityCenterNotifications, "wakuext"):
discard

View File

@ -72,6 +72,10 @@ proc estimateBurn*(chainId: int, contractAddress: string, fromAddress: string, a
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] {.raises: [Exception].} =
let payload = %* [chainId, contractAddress, fromAddress, newSignerPubkey]
return core.callPrivateRPC("communitytokens_estimateSetSignerPubKey", payload)
proc remainingSupply*(chainId: int, contractAddress: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chainId, contractAddress]
return core.callPrivateRPC("communitytokens_remainingSupply", payload)
@ -106,4 +110,36 @@ proc getOwnerTokenContractAddressFromHash*(chainId: int, transactionHash: string
proc createCommunityTokenDeploymentSignature*(chainId: int, addressFrom: string, signerAddress: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %*[chainId, addressFrom, signerAddress]
return core.callPrivateRPC("wakuext_createCommunityTokenDeploymentSignature", payload)
return core.callPrivateRPC("wakuext_createCommunityTokenDeploymentSignature", payload)
proc setSignerPubKey*(chainId: int, contractAddress: string, txData: JsonNode, newSignerPubKey: string, hashedPassword: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chainId, contractAddress, txData, hashedPassword, newSignerPubKey]
return core.callPrivateRPC("communitytokens_setSignerPubKey", payload)
proc registerOwnerTokenReceivedNotification*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %*[communityId]
return core.callPrivateRPC("wakuext_registerOwnerTokenReceivedNotification", payload)
proc registerReceivedOwnershipNotification*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %*[communityId]
return core.callPrivateRPC("wakuext_registerReceivedOwnershipNotification", payload)
proc registerSetSignerFailedNotification*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %*[communityId]
return core.callPrivateRPC("wakuext_registerSetSignerFailedNotification", payload)
proc registerSetSignerDeclinedNotification*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %*[communityId]
return core.callPrivateRPC("wakuext_registerSetSignerDeclinedNotification", payload)
proc registerLostOwnershipNotification*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %*[communityId]
return core.callPrivateRPC("wakuext_registerLostOwnershipNotification", payload)
proc promoteSelfToControlNode*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %*[communityId]
return core.callPrivateRPC("wakuext_promoteSelfToControlNode", payload)
proc getOwnerTokenOwnerAddress*(chainId: int, contractAddress: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %*[chainId, contractAddress]
return core.callPrivateRPC("communitytokens_ownerTokenOwnerAddress", payload)

View File

@ -11,6 +11,7 @@ import Models 1.0
import utils 1.0
import mainui 1.0
import shared.stores 1.0
SplitView {
id: root
@ -19,6 +20,7 @@ SplitView {
Popups {
popupParent: root
rootStore: QtObject {}
communityTokensStore: CommunityTokensStore {}
}
SplitView {

View File

@ -9,6 +9,7 @@ import utils 1.0
import Storybook 1.0
import Models 1.0
import shared.stores 1.0
SplitView {
id: root
@ -20,6 +21,7 @@ SplitView {
Popups {
popupParent: root
rootStore: QtObject {}
communityTokensStore: CommunityTokensStore {}
}
ListModel {

View File

@ -3,6 +3,7 @@ import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import mainui 1.0
import shared.stores 1.0
import AppLayouts.Communities.panels 1.0
import Storybook 1.0
@ -14,6 +15,7 @@ SplitView {
Popups {
popupParent: root
rootStore: QtObject {}
communityTokensStore: CommunityTokensStore {}
}
EditSettingsPanel {

View File

@ -26,7 +26,6 @@ SplitView {
shardIndex: communityEditor.shardIndex
isPendingOwnershipRequest: pendingOwnershipSwitch.checked
finaliseOwnershipTransferPopup: undefined
}
Pane {

View File

@ -4,6 +4,7 @@ import QtQuick.Layouts 1.14
import utils 1.0
import shared.views 1.0
import shared.stores 1.0
import mainui 1.0
import StatusQ 0.1
@ -106,6 +107,7 @@ SplitView {
}
}
}
communityTokensStore: CommunityTokensStore {}
}
SplitView {

View File

@ -6,6 +6,7 @@ import StatusQ.Core.Utils 0.1 as CoreUtils
import mainui 1.0
import AppLayouts.Profile.panels 1.0
import shared.stores 1.0
import utils 1.0
@ -22,6 +23,7 @@ SplitView {
Popups {
popupParent: root
rootStore: QtObject {}
communityTokensStore: CommunityTokensStore {}
}
readonly property string currentWallet: "0xcdc2ea3b6ba8fed3a3402f8db8b2fab53e7b7420"

View File

@ -6,6 +6,7 @@ import StatusQ.Core.Utils 0.1 as CoreUtils
import mainui 1.0
import AppLayouts.Profile.panels 1.0
import shared.stores 1.0
import utils 1.0
@ -22,6 +23,7 @@ SplitView {
Popups {
popupParent: root
rootStore: QtObject {}
communityTokensStore: CommunityTokensStore {}
}
ListModel {

View File

@ -6,6 +6,7 @@ import StatusQ.Core.Utils 0.1 as CoreUtils
import mainui 1.0
import AppLayouts.Profile.panels 1.0
import shared.stores 1.0
import utils 1.0
@ -22,6 +23,7 @@ SplitView {
Popups {
popupParent: root
rootStore: QtObject {}
communityTokensStore: CommunityTokensStore {}
}
ListModel {

View File

@ -6,6 +6,7 @@ import StatusQ.Core.Utils 0.1 as CoreUtils
import mainui 1.0
import AppLayouts.Profile.panels 1.0
import shared.stores 1.0
import utils 1.0
@ -22,6 +23,7 @@ SplitView {
Popups {
popupParent: root
rootStore: QtObject {}
communityTokensStore: CommunityTokensStore {}
}
ListModel {

View File

@ -6,6 +6,7 @@ import StatusQ.Core.Utils 0.1 as CoreUtils
import mainui 1.0
import AppLayouts.Profile.panels 1.0
import shared.stores 1.0
import utils 1.0
@ -21,6 +22,7 @@ SplitView {
Popups {
popupParent: root
rootStore: QtObject {}
communityTokensStore: CommunityTokensStore {}
}
ListModel {

View File

@ -6,6 +6,7 @@ import Storybook 1.0
import mainui 1.0
import shared.views 1.0
import shared.stores 1.0
SplitView {
id: root
@ -16,6 +17,7 @@ SplitView {
Popups {
popupParent: root
rootStore: QtObject {}
communityTokensStore: CommunityTokensStore {}
}
Item {

View File

@ -7,6 +7,7 @@ import Storybook 1.0
import mainui 1.0
import utils 1.0
import AppLayouts.Profile.views 1.0
import shared.stores 1.0
SplitView {
id: root
@ -17,6 +18,7 @@ SplitView {
Popups {
popupParent: root
rootStore: QtObject {}
communityTokensStore: CommunityTokensStore {}
}
SyncingView {

View File

@ -0,0 +1,4 @@
import QtQuick 2.15
QtObject {
}

View File

@ -1,3 +1,4 @@
CommunityTokensStore 1.0 CommunityTokensStore.qml
CurrenciesStore 1.0 CurrenciesStore.qml
NetworkConnectionStore 1.0 NetworkConnectionStore.qml
singleton RootStore 1.0 RootStore.qml

View File

@ -43,7 +43,6 @@ StackLayout {
signal openAppSearch()
// Community transfer ownership related props/signals:
// TODO: Backend integrations:
property bool isPendingOwnershipRequest: sectionItemModel.isPendingOwnershipRequest
onCurrentIndexChanged: {

View File

@ -8,7 +8,8 @@ import QtQuick 2.15
SingleFeeSubscriber {
id: root
required property string tokenKey
required property int chainId
required property string contractAddress
required property string accountAddress
required property bool enabled
}

View File

@ -102,10 +102,12 @@ QtObject {
required property SetSignerFeesSubscriber subscriber
readonly property var requestArgs: ({
type: TransactionFeesBroker.FeeType.SetSigner,
tokenKey: subscriber.tokenKey,
chainId: subscriber.chainId,
contractAddress: subscriber.contractAddress,
accountAddress: subscriber.accountAddress
})
isReady: !!subscriber.tokenKey &&
isReady: !!subscriber.chainId &&
!!subscriber.contractAddress &&
!!subscriber.accountAddress &&
subscriber.enabled
@ -142,6 +144,10 @@ QtObject {
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) {
@ -190,7 +196,7 @@ QtObject {
}
function computeSetSignerFee(args, topic) {
communityTokensStore.computeSetSignerFee(args.tokenKey, args.accountAddress, topic)
communityTokensStore.computeSetSignerFee(args.chainId, args.contractAddress, args.accountAddress, topic)
}
}

View File

@ -14,6 +14,7 @@ StatusDialog {
// Community related props:
required property string communityName
required property string communityId
signal cancelClicked
signal declineClicked

View File

@ -107,10 +107,7 @@ StatusDialog {
text: qsTr("Make this device the control node and update smart contract")
enabled: d.ackCheck && !root.isFeeLoading && root.feeErrorText === ""
onClicked: {
root.finaliseOwnershipClicked()
close()
}
onClicked: root.finaliseOwnershipClicked()
}
PropertyChanges { target: rejectBtn; visible: false }
PropertyChanges {

View File

@ -823,6 +823,14 @@ StatusSectionLayout {
Constants.ephemeralNotificationType.normal, url)
}
}
function onOwnershipLost(communityId, communityName) {
if (root.community.id !== communityId)
return
let type = Constants.ephemeralNotificationType.normal
Global.displayToastMessage(qsTr("Your device is no longer the control node for Doodles.
Your ownership and admin rights for %1 have been transferred to the new owner.").arg(communityName), "", "", false, type, "")
}
}
Connections {

View File

@ -20,4 +20,4 @@ QtObject {
function getDetailedCollectible(chainId, contractAddress, tokenId) {
walletSection.collectibleDetailsController.getDetailedCollectible(chainId, contractAddress, tokenId)
}
}
}

View File

@ -298,8 +298,8 @@ QtObject {
openPopup(finaliseOwnershipPopup, { communityId: communityId })
}
function openDeclineOwnershipPopup(communityName) {
openPopup(declineOwnershipPopup, { communityName: communityName })
function openDeclineOwnershipPopup(communityId, communityName) {
openPopup(declineOwnershipPopup, { communityName: communityName, communityId: communityId })
}
readonly property list<Component> _components: [
@ -829,18 +829,17 @@ QtObject {
id: finalisePopup
property string communityId
readonly property var ownerToken: {
let jsonObj = root.rootStore.mainModuleInst.getOwnerTokenAsJson(finalisePopup.communityId)
return JSON.parse(jsonObj)
}
readonly property var ownerTokenDetails: root.communityTokensStore.ownerTokenDetails
readonly property var communityData : root.communitiesStore.getCommunityDetailsAsJson(communityId)
Component.onCompleted: root.communityTokensStore.asyncGetOwnerTokenDetails(communityId)
communityName: communityData.name
communityLogo: communityData.image
communityColor: communityData.color
tokenSymbol: ownerToken.symbol
tokenChainName: ownerToken.chainName
tokenSymbol: ownerTokenDetails.symbol
tokenChainName: ownerTokenDetails.chainName
feeText: feeSubscriber.feeText
feeErrorText: feeSubscriber.feeErrorText
@ -850,9 +849,10 @@ QtObject {
destroyOnClose: true
onRejectClicked: Global.openDeclineOwnershipPopup(communityData.name)
onRejectClicked: Global.openDeclineOwnershipPopup(finalisePopup.communityId, communityData.name)
onFinaliseOwnershipClicked: signPopup.open()
onVisitCommunityClicked: rootStore.setActiveCommunity(communityData.id)
onVisitCommunityClicked: communitiesStore.navigateToCommunity(finalisePopup.communityId)
onOpenControlNodeDocClicked: Global.openLink(link)
SetSignerFeesSubscriber {
@ -862,8 +862,9 @@ QtObject {
communityTokensStore: root.communityTokensStore
}
tokenKey: finalisePopup.ownerToken.contractUniqueKey
accountAddress: finalisePopup.ownerToken.accountAddress
chainId: finalisePopup.ownerTokenDetails.chainId
contractAddress: finalisePopup.ownerTokenDetails.contractAddress
accountAddress: finalisePopup.ownerTokenDetails.accountAddress
enabled: finalisePopup.visible || signPopup.visible
Component.onCompleted: feesBroker.registerSetSignerFeesSubscriber(feeSubscriber)
}
@ -874,7 +875,7 @@ QtObject {
title: qsTr("Sign transaction - update %1 smart contract").arg(finalisePopup.communityName)
totalFeeText: finalisePopup.isFeeLoading ? "" : finalisePopup.feeText
errorText: finalisePopup.feeErrorText
accountName: finalisePopup.ownerToken.accountName
accountName: finalisePopup.ownerTokenDetails.accountName
model: QtObject {
readonly property string title: finalisePopup.feeLabel
@ -883,8 +884,8 @@ QtObject {
}
onSignTransactionClicked: {
root.communityTokensStore.updateSmartContract(finalisePopup.communityId, finalisePopup.ownerToken.contractUniqueKey)
close()
finalisePopup.close()
root.communityTokensStore.updateSmartContract(finalisePopup.communityId, finalisePopup.ownerTokenDetails.chainId, finalisePopup.ownerTokenDetails.contractAddress, finalisePopup.ownerTokenDetails.accountAddress)
}
}
@ -892,7 +893,7 @@ QtObject {
target: root
onOwnershipDeclined: {
finalisePopup.close()
root.communityTokensStore.ownershipDeclined()
root.communityTokensStore.ownershipDeclined(communityId)
}
}
}
@ -903,7 +904,10 @@ QtObject {
FinaliseOwnershipDeclinePopup {
destroyOnClose: true
onDeclineClicked: root.ownershipDeclined()
onDeclineClicked: {
close()
root.ownershipDeclined()
}
}
}
// End of components related to transfer community ownership flow.

View File

@ -117,10 +117,10 @@ Popup {
case ActivityCenterStore.ActivityCenterNotificationType.NewKeypairAddedToPairedDevice:
return newKeypairFromPairedDeviceComponent
case ActivityCenterStore.ActivityCenterNotificationType.OwnerTokenReceived:
case ActivityCenterStore.ActivityCenterNotificationType.OwnershipDeclined:
case ActivityCenterStore.ActivityCenterNotificationType.OwnershipSucceeded:
case ActivityCenterStore.ActivityCenterNotificationType.OwnershipReceived:
case ActivityCenterStore.ActivityCenterNotificationType.OwnershipLost:
case ActivityCenterStore.ActivityCenterNotificationType.OwnershipFailed:
case ActivityCenterStore.ActivityCenterNotificationType.NoLongerControlNode:
case ActivityCenterStore.ActivityCenterNotificationType.OwnershipDeclined:
return ownerTokenReceivedNotificationComponent
default:
return null

View File

@ -32,10 +32,10 @@ QtObject {
ContactRemoved = 11,
NewKeypairAddedToPairedDevice = 12,
OwnerTokenReceived = 13,
OwnershipDeclined = 14,
OwnershipSucceeded = 15,
OwnershipReceived = 14,
OwnershipLost = 15,
OwnershipFailed = 16,
NoLongerControlNode = 17
OwnershipDeclined = 17
}
enum ActivityCenterReadType {

View File

@ -12,6 +12,11 @@ QtObject {
property var enabledNetworks: networksModule.enabled
property var allNetworks: networksModule.all
// set by asyncGetOwnerTokenDetails
readonly property var ownerTokenDetails: {
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)
@ -25,6 +30,7 @@ QtObject {
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)
// Minting tokens:
function deployCollectible(communityId, collectibleItem)
@ -62,13 +68,12 @@ QtObject {
communityTokensModuleInst.removeCommunityToken(communityId, parts[0], parts[1])
}
function updateSmartContract(tokenKey, accountAddress) {
console.warn("TODO: Backend to update smart contract and finalise community transfer ownership! The token owner is: " + collectibleItem.symbol)
//communityTokensModuleInst.setSigner(tokenKey, accountAddress)
function updateSmartContract(communityId, chainId, contractAddress, accountAddress) {
communityTokensModuleInst.setSigner(communityId, chainId, contractAddress, accountAddress)
}
function ownershipDeclined() {
console.warn("TODO: Backend update notification center and display a toast: Ownership Declined!")
function ownershipDeclined(communityId) {
communityTokensModuleInst.declineOwnership(communityId)
}
readonly property Connections connections: Connections {
@ -91,8 +96,7 @@ QtObject {
}
function onSetSignerFeeUpdated(ethCurrency, fiatCurrency, errorCode, responseId) {
console.warn("TODO: Backend")
//root.setSignerFeeUpdated(ethCurrency, fiatCurrency, errorCode, responseId)
root.setSignerFeeUpdated(ethCurrency, fiatCurrency, errorCode, responseId)
}
function onDeploymentStateChanged(communityId, status, url) {
@ -120,18 +124,21 @@ QtObject {
}
function onOwnerTokenReceived(communityId, communityName, chainId, communityAddress) {
console.warn("TODO: Backend")
// Global.displayToastMessage(qsTr("You received the Owner token for %1. To finalize ownership, make your device the control node.").arg(communityName),
// qsTr("Finalise ownership"),
// "",
// false,
// Constants.ephemeralNotificationType.normal,
// "")
// TODO clicking url should execute finalise flow
Global.displayToastMessage(qsTr("You received the Owner token for %1. To finalize ownership, make your device the control node.").arg(communityName),
qsTr("Finalise ownership"),
"",
false,
Constants.ephemeralNotificationType.normal,
"")
}
function onSetSignerStateChanged(communityId, communityName, status, url) {
console.warn("TODO: Backend")
//root.setSignerStateChanged(communityId, communityName, status, url)
root.setSignerStateChanged(communityId, communityName, status, url)
}
function onOwnershipLost(communityId, communityName) {
root.ownershipLost(communityId, communityName)
}
}
@ -151,9 +158,8 @@ QtObject {
communityTokensModuleInst.computeDeployFee(communityId, chainId, accountAddress, tokenType, isOwnerDeployment, requestId)
}
function computeSetSignerFee(tokenKey, accountAddress, requestId) {
console.warn("TODO: Backend!")
//communityTokensModuleInst.computeSetSignerFee(tokenKey, accountAddress, requestId)
function computeSetSignerFee(chainId, contractAddress, accountAddress, requestId) {
communityTokensModuleInst.computeSetSignerFee(chainId, contractAddress, accountAddress, requestId)
}
/**
@ -190,4 +196,8 @@ QtObject {
function airdrop(communityId, airdropTokens, addresses, feeAccountAddress) {
communityTokensModuleInst.airdropTokens(communityId, JSON.stringify(airdropTokens), JSON.stringify(addresses), feeAccountAddress)
}
function asyncGetOwnerTokenDetails(communityId) {
communityTokensModuleInst.asyncGetOwnerTokenDetails(communityId)
}
}

View File

@ -53,7 +53,7 @@ QtObject {
var accounts,
var sendModalPopup)
signal openFinaliseOwnershipPopup(string communityId)
signal openDeclineOwnershipPopup(string communityName)
signal openDeclineOwnershipPopup(string communityId, string communityName)
signal openLink(string link)
signal openLinkWithConfirmation(string link, string domain)