feat(@desktop/communities): Deploy Owner and Master tokens flow.

Issue #11250
This commit is contained in:
Michal Iskierko 2023-07-11 15:23:00 +02:00 committed by Michał Iskierko
parent 7a1500a365
commit 603d4dd4d8
19 changed files with 521 additions and 100 deletions

View File

@ -76,7 +76,7 @@ proc newModule*(
tokensService, tokensService,
chatService, chatService,
) )
result.communityTokensModule = community_tokens_module.newCommunityTokensModule(result, events, communityTokensService, transactionService, networksService) result.communityTokensModule = community_tokens_module.newCommunityTokensModule(result, events, communityTokensService, transactionService, networksService, communityService)
result.moduleLoaded = false result.moduleLoaded = false
result.curatedCommunitiesLoaded = false result.curatedCommunitiesLoaded = false

View File

@ -4,6 +4,7 @@ import ./io_interface as community_tokens_module_interface
import ../../../../../app_service/service/community_tokens/service as community_tokens_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/transaction/service as transaction_service
import ../../../../../app_service/service/network/service as networks_service import ../../../../../app_service/service/network/service as networks_service
import ../../../../../app_service/service/community/service as community_service
import ../../../../../app_service/service/community/dto/community import ../../../../../app_service/service/community/dto/community
import ../../../../core/signals/types import ../../../../core/signals/types
import ../../../../core/eventemitter import ../../../../core/eventemitter
@ -19,13 +20,15 @@ type
communityTokensService: community_tokens_service.Service communityTokensService: community_tokens_service.Service
transactionService: transaction_service.Service transactionService: transaction_service.Service
networksService: networks_service.Service networksService: networks_service.Service
communityService: community_service.Service
proc newCommunityTokensController*( proc newCommunityTokensController*(
communityTokensModule: community_tokens_module_interface.AccessInterface, communityTokensModule: community_tokens_module_interface.AccessInterface,
events: EventEmitter, events: EventEmitter,
communityTokensService: community_tokens_service.Service, communityTokensService: community_tokens_service.Service,
transactionService: transaction_service.Service, transactionService: transaction_service.Service,
networksService: networks_service.Service networksService: networks_service.Service,
communityService: community_service.Service
): Controller = ): Controller =
result = Controller() result = Controller()
result.communityTokensModule = communityTokensModule result.communityTokensModule = communityTokensModule
@ -33,6 +36,7 @@ proc newCommunityTokensController*(
result.communityTokensService = communityTokensService result.communityTokensService = communityTokensService
result.transactionService = transactionService result.transactionService = transactionService
result.networksService = networksService result.networksService = networksService
result.communityService = communityService
proc delete*(self: Controller) = proc delete*(self: Controller) =
discard discard
@ -59,8 +63,14 @@ proc init*(self: Controller) =
let args = CommunityTokenDeploymentArgs(e) let args = CommunityTokenDeploymentArgs(e)
self.communityTokensModule.onCommunityTokenDeployStateChanged(args.communityToken.communityId, args.communityToken.chainId, args.transactionHash, args.communityToken.deployState) 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): self.events.on(SIGNAL_COMMUNITY_TOKEN_DEPLOY_STATUS) do(e: Args):
let args = CommunityTokenDeployedStatusArgs(e) let args = OwnerTokenDeployedStatusArgs(e)
self.communityTokensModule.onCommunityTokenDeployStateChanged(args.communityId, args.chainId, args.transactionHash, args.deployState) 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): self.events.on(SIGNAL_REMOTE_DESTRUCT_STATUS) do(e: Args):
let args = RemoteDestructArgs(e) let args = RemoteDestructArgs(e)
self.communityTokensModule.onRemoteDestructStateChanged(args.communityToken.communityId, args.communityToken.name, args.communityToken.chainId, args.transactionHash, args.status) self.communityTokensModule.onRemoteDestructStateChanged(args.communityToken.communityId, args.communityToken.name, args.communityToken.chainId, args.transactionHash, args.status)
@ -74,6 +84,13 @@ proc init*(self: Controller) =
proc deployContract*(self: Controller, communityId: string, addressFrom: string, password: string, deploymentParams: DeploymentParameters, tokenMetadata: CommunityTokensMetadataDto, tokenImageCropInfoJson: string, chainId: int) = 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) self.communityTokensService.deployContract(communityId, addressFrom, password, deploymentParams, tokenMetadata, tokenImageCropInfoJson, chainId)
proc deployOwnerContracts*(self: Controller, communityId: string, addressFrom: string, password: string,
ownerDeploymentParams: DeploymentParameters, ownerTokenMetadata: CommunityTokensMetadataDto,
masterDeploymentParams: DeploymentParameters, masterTokenMetadata: CommunityTokensMetadataDto,
tokenImageCropInfoJson: string, chainId: int) =
self.communityTokensService.deployOwnerContracts(communityId, addressFrom, password, ownerDeploymentParams, ownerTokenMetadata,
masterDeploymentParams, masterTokenMetadata, tokenImageCropInfoJson, chainId)
proc removeCommunityToken*(self: Controller, communityId: string, chainId: int, address: string) = proc removeCommunityToken*(self: Controller, communityId: string, chainId: int, address: string) =
self.communityTokensService.removeCommunityToken(communityId, chainId, address) self.communityTokensService.removeCommunityToken(communityId, chainId, address)
@ -99,6 +116,9 @@ proc getCommunityTokens*(self: Controller, communityId: string): seq[CommunityTo
proc computeDeployFee*(self: Controller, chainId: int, accountAddress: string, tokenType: TokenType) = proc computeDeployFee*(self: Controller, chainId: int, accountAddress: string, tokenType: TokenType) =
self.communityTokensService.computeDeployFee(chainId, accountAddress, tokenType) self.communityTokensService.computeDeployFee(chainId, accountAddress, tokenType)
proc computeDeployOwnerContractsFee*(self: Controller, chainId: int, accountAddress: string) =
self.communityTokensService.computeDeployOwnerContractsFee(chainId, accountAddress)
proc computeSelfDestructFee*(self: Controller, walletAndAmountList: seq[WalletAndAmount], contractUniqueKey: string) = proc computeSelfDestructFee*(self: Controller, walletAndAmountList: seq[WalletAndAmount], contractUniqueKey: string) =
self.communityTokensService.computeSelfDestructFee(walletAndAmountList, contractUniqueKey) self.communityTokensService.computeSelfDestructFee(walletAndAmountList, contractUniqueKey)
@ -110,3 +130,12 @@ proc computeBurnFee*(self: Controller, contractUniqueKey: string, amount: Uint25
proc getNetwork*(self:Controller, chainId: int): NetworkDto = proc getNetwork*(self:Controller, chainId: int): NetworkDto =
self.networksService.getNetwork(chainId) self.networksService.getNetwork(chainId)
proc getOwnerToken*(self: Controller, communityId: string): CommunityTokenDto =
return self.communityTokensService.getOwnerToken(communityId)
proc getMasterToken*(self: Controller, communityId: string): CommunityTokenDto =
return self.communityTokensService.getMasterToken(communityId)
proc getCommunityById*(self: Controller, communityId: string): CommunityDto =
return self.communityService.getCommunityById(communityId)

View File

@ -32,13 +32,17 @@ method deployAssets*(self: AccessInterface, communityId: string, address: string
chainId: int, imageCropInfoJson: string) {.base.} = chainId: int, imageCropInfoJson: string) {.base.} =
raise newException(ValueError, "No implementation available") 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) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method resetTempValues*(self: AccessInterface) {.base.} = method resetTempValues*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method computeDeployFee*(self: AccessInterface, chainId: int, accountAddress: string, tokenType: TokenType) {.base.} = method computeDeployFee*(self: AccessInterface, chainId: int, accountAddress: string, tokenType: TokenType, isOwnerDeployment: bool) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method computeSelfDestructFee*(self: AccessInterface, collectiblesToBurnJsonString: string, contractUniqueKey: string) {.base.} = method computeSelfDestructFee*(self: AccessInterface, collectiblesToBurnJsonString: string, contractUniqueKey: string) {.base.} =
@ -62,6 +66,12 @@ method onBurnFeeComputed*(self: AccessInterface, ethCurrency: CurrencyAmount, fi
method onCommunityTokenDeployStateChanged*(self: AccessInterface, communityId: string, chainId: int, transactionHash: string, deployState: DeployState) {.base.} = method onCommunityTokenDeployStateChanged*(self: AccessInterface, communityId: string, chainId: int, transactionHash: string, deployState: DeployState) {.base.} =
raise newException(ValueError, "No implementation available") 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 onRemoteDestructStateChanged*(self: AccessInterface, communityId: string, tokenName: string, chainId: int, transactionHash: string, status: ContractTransactionStatus) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")

View File

@ -26,10 +26,12 @@ type
ChainIcon ChainIcon
TokenOwnersModel TokenOwnersModel
AccountName AccountName
AccountAddress
RemainingSupply RemainingSupply
Decimals Decimals
BurnState BurnState
RemotelyDestructState RemotelyDestructState
PrivilegesLevel
QtObject: QtObject:
type TokenModel* = ref object of QAbstractListModel type TokenModel* = ref object of QAbstractListModel
@ -55,6 +57,15 @@ QtObject:
self.dataChanged(index, index, @[ModelRole.DeployState.int]) self.dataChanged(index, index, @[ModelRole.DeployState.int])
return return
proc updateAddress*(self: TokenModel, chainId: int, oldContractAddress: string, newContractAddress: string) =
for i in 0 ..< self.items.len:
if((self.items[i].tokenDto.address == oldContractAddress) and (self.items[i].tokenDto.chainId == chainId)):
self.items[i].tokenDto.address = newContractAddress
let index = self.createIndex(i, 0, nil)
defer: index.delete
self.dataChanged(index, index, @[ModelRole.TokenAddress.int])
return
proc updateBurnState*(self: TokenModel, chainId: int, contractAddress: string, burnState: ContractTransactionStatus) = proc updateBurnState*(self: TokenModel, chainId: int, contractAddress: string, burnState: ContractTransactionStatus) =
for i in 0 ..< self.items.len: for i in 0 ..< self.items.len:
if((self.items[i].tokenDto.address == contractAddress) and (self.items[i].tokenDto.chainId == chainId)): if((self.items[i].tokenDto.address == contractAddress) and (self.items[i].tokenDto.chainId == chainId)):
@ -166,10 +177,12 @@ QtObject:
ModelRole.ChainIcon.int:"chainIcon", ModelRole.ChainIcon.int:"chainIcon",
ModelRole.TokenOwnersModel.int:"tokenOwnersModel", ModelRole.TokenOwnersModel.int:"tokenOwnersModel",
ModelRole.AccountName.int:"accountName", ModelRole.AccountName.int:"accountName",
ModelRole.AccountAddress.int:"accountAddress",
ModelRole.RemainingSupply.int:"remainingSupply", ModelRole.RemainingSupply.int:"remainingSupply",
ModelRole.Decimals.int:"decimals", ModelRole.Decimals.int:"decimals",
ModelRole.BurnState.int:"burnState", ModelRole.BurnState.int:"burnState",
ModelRole.RemotelyDestructState.int:"remotelyDestructState", ModelRole.RemotelyDestructState.int:"remotelyDestructState",
ModelRole.PrivilegesLevel.int:"privilegesLevel"
}.toTable }.toTable
method data(self: TokenModel, index: QModelIndex, role: int): QVariant = method data(self: TokenModel, index: QModelIndex, role: int): QVariant =
@ -215,6 +228,8 @@ QtObject:
result = newQVariant(item.tokenOwnersModel) result = newQVariant(item.tokenOwnersModel)
of ModelRole.AccountName: of ModelRole.AccountName:
result = newQVariant(item.accountName) result = newQVariant(item.accountName)
of ModelRole.AccountAddress:
result = newQVariant(item.tokenDto.deployer)
of ModelRole.RemainingSupply: of ModelRole.RemainingSupply:
result = newQVariant(supplyByType(item.remainingSupply, item.tokenDto.tokenType)) result = newQVariant(supplyByType(item.remainingSupply, item.tokenDto.tokenType))
of ModelRole.Decimals: of ModelRole.Decimals:
@ -224,6 +239,8 @@ QtObject:
of ModelRole.RemotelyDestructState: of ModelRole.RemotelyDestructState:
let destructStatus = if len(item.remoteDestructedAddresses) > 0: ContractTransactionStatus.InProgress.int else: ContractTransactionStatus.Completed.int let destructStatus = if len(item.remoteDestructedAddresses) > 0: ContractTransactionStatus.InProgress.int else: ContractTransactionStatus.Completed.int
result = newQVariant(destructStatus) result = newQVariant(destructStatus)
of ModelRole.PrivilegesLevel:
result = newQVariant(item.tokenDto.privilegesLevel.int)
proc `$`*(self: TokenModel): string = proc `$`*(self: TokenModel): string =
for i in 0 ..< self.items.len: for i in 0 ..< self.items.len:

View File

@ -3,6 +3,7 @@ import NimQml, json, stint, strutils, chronicles
import ../../../../../app_service/service/community_tokens/service as community_tokens_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/transaction/service as transaction_service
import ../../../../../app_service/service/network/service as networks_service import ../../../../../app_service/service/network/service as networks_service
import ../../../../../app_service/service/community/service as community_service
import ../../../../../app_service/service/community/dto/community import ../../../../../app_service/service/community/dto/community
import ../../../../../app_service/service/accounts/utils as utl import ../../../../../app_service/service/accounts/utils as utl
import ../../../../../app_service/common/conversion import ../../../../../app_service/common/conversion
@ -22,6 +23,7 @@ type
Airdrop = 2 Airdrop = 2
SelfDestruct = 3 SelfDestruct = 3
Burn = 4 Burn = 4
DeployOwnerToken = 5
type type
Module* = ref object of io_interface.AccessInterface Module* = ref object of io_interface.AccessInterface
@ -42,18 +44,23 @@ type
tempContractAction: ContractAction tempContractAction: ContractAction
tempContractUniqueKey: string tempContractUniqueKey: string
tempAmount: Uint256 tempAmount: Uint256
tempOwnerDeploymentParams: DeploymentParameters
tempMasterDeploymentParams: DeploymentParameters
tempOwnerTokenMetadata: CommunityTokensMetadataDto
tempMasterTokenMetadata: CommunityTokensMetadataDto
proc newCommunityTokensModule*( proc newCommunityTokensModule*(
parent: parent_interface.AccessInterface, parent: parent_interface.AccessInterface,
events: EventEmitter, events: EventEmitter,
communityTokensService: community_tokens_service.Service, communityTokensService: community_tokens_service.Service,
transactionService: transaction_service.Service, transactionService: transaction_service.Service,
networksService: networks_service.Service): Module = networksService: networks_service.Service,
communityService: community_service.Service): Module =
result = Module() result = Module()
result.parent = parent result.parent = parent
result.view = newView(result) result.view = newView(result)
result.viewVariant = newQVariant(result.view) result.viewVariant = newQVariant(result.view)
result.controller = controller.newCommunityTokensController(result, events, communityTokensService, transactionService, networksService) result.controller = controller.newCommunityTokensController(result, events, communityTokensService, transactionService, networksService, communityService)
method delete*(self: Module) = method delete*(self: Module) =
self.view.delete self.view.delete
@ -151,6 +158,13 @@ method burnTokens*(self: Module, communityId: string, contractUniqueKey: string,
method deployCollectibles*(self: Module, communityId: string, fromAddress: string, name: string, symbol: string, description: string, method deployCollectibles*(self: Module, communityId: string, fromAddress: string, name: string, symbol: string, description: string,
supply: float64, infiniteSupply: bool, transferable: bool, selfDestruct: bool, chainId: int, imageCropInfoJson: string) = supply: float64, infiniteSupply: bool, transferable: bool, selfDestruct: bool, chainId: int, imageCropInfoJson: string) =
let ownerToken = self.controller.getOwnerToken(communityId)
let masterToken = self.controller.getMasterToken(communityId)
if not (ownerToken.address != "" and ownerToken.deployState == DeployState.Deployed and masterToken.address != "" and masterToken.deployState == DeployState.Deployed):
error "Owner token and master token not deployed"
return
self.tempAddressFrom = fromAddress self.tempAddressFrom = fromAddress
self.tempCommunityId = communityId self.tempCommunityId = communityId
self.tempChainId = chainId self.tempChainId = chainId
@ -161,12 +175,31 @@ method deployCollectibles*(self: Module, communityId: string, fromAddress: strin
self.tempDeploymentParams.transferable = transferable self.tempDeploymentParams.transferable = transferable
self.tempDeploymentParams.remoteSelfDestruct = selfDestruct self.tempDeploymentParams.remoteSelfDestruct = selfDestruct
self.tempDeploymentParams.tokenUri = utl.changeCommunityKeyCompression(communityId) & "/" self.tempDeploymentParams.tokenUri = utl.changeCommunityKeyCompression(communityId) & "/"
self.tempDeploymentParams.ownerTokenAddress = ownerToken.address
self.tempDeploymentParams.masterTokenAddress = masterToken.address
self.tempTokenMetadata.tokenType = TokenType.ERC721 self.tempTokenMetadata.tokenType = TokenType.ERC721
self.tempTokenMetadata.description = description self.tempTokenMetadata.description = description
self.tempTokenImageCropInfoJson = imageCropInfoJson self.tempTokenImageCropInfoJson = imageCropInfoJson
self.tempContractAction = ContractAction.Deploy self.tempContractAction = ContractAction.Deploy
self.authenticate() self.authenticate()
method deployOwnerToken*(self: Module, communityId: string, fromAddress: string, ownerName: string, ownerSymbol: string, ownerDescription: string,
masterName: string, masterSymbol: string, masterDescription: string, chainId: int, imageCropInfoJson: string) =
self.tempAddressFrom = fromAddress
self.tempCommunityId = communityId
self.tempChainId = chainId
let communityDto = self.controller.getCommunityById(communityId)
let commName = communityDto.name
self.tempOwnerDeploymentParams = DeploymentParameters(name: "Owner-" & commName, symbol: "OWN" & commName[0 .. 2].toUpper, supply: stint.u256("1"), infiniteSupply: false, transferable: true, remoteSelfDestruct: false, tokenUri: utl.changeCommunityKeyCompression(communityId) & "/")
self.tempMasterDeploymentParams = DeploymentParameters(name: "TMaster-" & commName, symbol: "TM" & commName[0 .. 2].toUpper, infiniteSupply: true, transferable: false, remoteSelfDestruct: true, tokenUri: utl.changeCommunityKeyCompression(communityId) & "/")
self.tempOwnerTokenMetadata.description = ownerDescription
self.tempOwnerTokenMetadata.tokenType = TokenType.ERC721
self.tempMasterTokenMetadata.description = masterDescription
self.tempMasterTokenMetadata.tokenType = TokenType.ERC721
self.tempTokenImageCropInfoJson = imageCropInfoJson
self.tempContractAction = ContractAction.DeployOwnerToken
self.authenticate()
method deployAssets*(self: Module, communityId: string, fromAddress: string, name: string, symbol: string, description: string, supply: float64, infiniteSupply: bool, decimals: int, method deployAssets*(self: Module, communityId: string, fromAddress: string, name: string, symbol: string, description: string, supply: float64, infiniteSupply: bool, decimals: int,
chainId: int, imageCropInfoJson: string) = chainId: int, imageCropInfoJson: string) =
self.tempAddressFrom = fromAddress self.tempAddressFrom = fromAddress
@ -201,6 +234,11 @@ method onUserAuthenticated*(self: Module, password: string) =
self.controller.selfDestructCollectibles(self.tempCommunityId, password, self.tempWalletAndAmountList, self.tempContractUniqueKey) self.controller.selfDestructCollectibles(self.tempCommunityId, password, self.tempWalletAndAmountList, self.tempContractUniqueKey)
elif self.tempContractAction == ContractAction.Burn: elif self.tempContractAction == ContractAction.Burn:
self.controller.burnTokens(self.tempCommunityId, password, self.tempContractUniqueKey, self.tempAmount) self.controller.burnTokens(self.tempCommunityId, password, self.tempContractUniqueKey, self.tempAmount)
elif self.tempContractAction == ContractAction.DeployOwnerToken:
self.controller.deployOwnerContracts(self.tempCommunityId, self.tempAddressFrom, password,
self.tempOwnerDeploymentParams, self.tempOwnerTokenMetadata,
self.tempMasterDeploymentParams, self.tempMasterTokenMetadata,
self.tempTokenImageCropInfoJson, self.tempChainId)
method onDeployFeeComputed*(self: Module, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: ComputeFeeErrorCode) = method onDeployFeeComputed*(self: Module, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: ComputeFeeErrorCode) =
self.view.updateDeployFee(ethCurrency, fiatCurrency, errorCode.int) self.view.updateDeployFee(ethCurrency, fiatCurrency, errorCode.int)
@ -214,8 +252,11 @@ method onAirdropFeesComputed*(self: Module, args: AirdropFeesArgs) =
method onBurnFeeComputed*(self: Module, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: ComputeFeeErrorCode) = method onBurnFeeComputed*(self: Module, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: ComputeFeeErrorCode) =
self.view.updateBurnFee(ethCurrency, fiatCurrency, errorCode.int) self.view.updateBurnFee(ethCurrency, fiatCurrency, errorCode.int)
method computeDeployFee*(self: Module, chainId: int, accountAddress: string, tokenType: TokenType) = method computeDeployFee*(self: Module, chainId: int, accountAddress: string, tokenType: TokenType, isOwnerDeployment: bool) =
self.controller.computeDeployFee(chainId, accountAddress, tokenType) if isOwnerDeployment:
self.controller.computeDeployOwnerContractsFee(chainId, accountAddress)
else:
self.controller.computeDeployFee(chainId, accountAddress, tokenType)
method computeSelfDestructFee*(self: Module, collectiblesToBurnJsonString: string, contractUniqueKey: string) = method computeSelfDestructFee*(self: Module, collectiblesToBurnJsonString: string, contractUniqueKey: string) =
let walletAndAmountList = self.getWalletAndAmountListFromJson(collectiblesToBurnJsonString) let walletAndAmountList = self.getWalletAndAmountListFromJson(collectiblesToBurnJsonString)
@ -237,6 +278,14 @@ method onCommunityTokenDeployStateChanged*(self: Module, communityId: string, ch
let url = self.createUrl(chainId, transactionHash) let url = self.createUrl(chainId, transactionHash)
self.view.emitDeploymentStateChanged(communityId, deployState.int, url) 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) = method onRemoteDestructStateChanged*(self: Module, communityId: string, tokenName: string, chainId: int, transactionHash: string, status: ContractTransactionStatus) =
let url = self.createUrl(chainId, transactionHash) let url = self.createUrl(chainId, transactionHash)
self.view.emitRemoteDestructStateChanged(communityId, tokenName, status.int, url) self.view.emitRemoteDestructStateChanged(communityId, tokenName, status.int, url)

View File

@ -27,6 +27,9 @@ QtObject:
proc deployAssets*(self: View, communityId: string, fromAddress: string, name: string, symbol: string, description: string, supply: float, infiniteSupply: bool, decimals: int, chainId: int, imageCropInfoJson: string) {.slot.} = proc deployAssets*(self: View, communityId: string, fromAddress: string, name: string, symbol: string, description: string, supply: float, infiniteSupply: bool, decimals: int, chainId: int, imageCropInfoJson: string) {.slot.} =
self.communityTokensModule.deployAssets(communityId, fromAddress, name, symbol, description, supply, infiniteSupply, decimals, chainId, imageCropInfoJson) self.communityTokensModule.deployAssets(communityId, fromAddress, name, symbol, description, supply, infiniteSupply, decimals, 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 removeCommunityToken*(self: View, communityId: string, chainId: int, address: string) {.slot.} = proc removeCommunityToken*(self: View, communityId: string, chainId: int, address: string) {.slot.} =
self.communityTokensModule.removeCommunityToken(communityId, chainId, address) self.communityTokensModule.removeCommunityToken(communityId, chainId, address)
@ -47,8 +50,8 @@ QtObject:
proc airdropFeesUpdated*(self: View, json: string) {.signal.} proc airdropFeesUpdated*(self: View, json: string) {.signal.}
proc burnFeeUpdated*(self: View, ethCurrency: QVariant, fiatCurrency: QVariant, errorCode: int) {.signal.} proc burnFeeUpdated*(self: View, ethCurrency: QVariant, fiatCurrency: QVariant, errorCode: int) {.signal.}
proc computeDeployFee*(self: View, chainId: int, accountAddress: string, tokenType: int) {.slot.} = proc computeDeployFee*(self: View, chainId: int, accountAddress: string, tokenType: int, isOwnerDeployment: bool) {.slot.} =
self.communityTokensModule.computeDeployFee(chainId, accountAddress, intToEnum(tokenType, TokenType.Unknown)) self.communityTokensModule.computeDeployFee(chainId, accountAddress, intToEnum(tokenType, TokenType.Unknown), isOwnerDeployment)
proc computeSelfDestructFee*(self: View, collectiblesToBurnJsonString: string, contractUniqueKey: string) {.slot.} = proc computeSelfDestructFee*(self: View, collectiblesToBurnJsonString: string, contractUniqueKey: string) {.slot.} =
self.communityTokensModule.computeSelfDestructFee(collectiblesToBurnJsonString, contractUniqueKey) self.communityTokensModule.computeSelfDestructFee(collectiblesToBurnJsonString, contractUniqueKey)
@ -83,3 +86,11 @@ QtObject:
proc airdropStateChanged*(self: View, communityId: string, tokenName: string, chainName: string, status: int, url: string) {.signal.} 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) = proc emitAirdropStateChanged*(self: View, communityId: string, tokenName: string, chainName: string, status: int, url: string) =
self.airdropStateChanged(communityId, tokenName, chainName, status, url) 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)

View File

@ -342,10 +342,18 @@ proc init*(self: Controller) =
let args = CommunityTokenDeploymentArgs(e) let args = CommunityTokenDeploymentArgs(e)
self.delegate.onCommunityTokenDeploymentStarted(args.communityToken) self.delegate.onCommunityTokenDeploymentStarted(args.communityToken)
self.events.on(SIGNAL_OWNER_TOKEN_DEPLOYMENT_STARTED) do(e: Args):
let args = OwnerTokenDeploymentArgs(e)
self.delegate.onOwnerTokensDeploymentStarted(args.ownerToken, args.masterToken)
self.events.on(SIGNAL_COMMUNITY_TOKEN_DEPLOY_STATUS) do(e: Args): self.events.on(SIGNAL_COMMUNITY_TOKEN_DEPLOY_STATUS) do(e: Args):
let args = CommunityTokenDeployedStatusArgs(e) let args = CommunityTokenDeployedStatusArgs(e)
self.delegate.onCommunityTokenDeployStateChanged(args.communityId, args.chainId, args.contractAddress, args.deployState) self.delegate.onCommunityTokenDeployStateChanged(args.communityId, args.chainId, args.contractAddress, args.deployState)
self.events.on(SIGNAL_OWNER_TOKEN_DEPLOY_STATUS) do(e: Args):
let args = OwnerTokenDeployedStatusArgs(e)
self.delegate.onOwnerTokenDeployStateChanged(args.communityId, args.chainId, args.ownerContractAddress, args.masterContractAddress, args.deployState)
self.events.on(SIGNAL_COMMUNITY_TOKEN_REMOVED) do(e: Args): self.events.on(SIGNAL_COMMUNITY_TOKEN_REMOVED) do(e: Args):
let args = CommunityTokenRemovedArgs(e) let args = CommunityTokenRemovedArgs(e)
self.delegate.onCommunityTokenRemoved(args.communityId, args.chainId, args.contractAddress) self.delegate.onCommunityTokenRemoved(args.communityId, args.chainId, args.contractAddress)
@ -499,8 +507,8 @@ proc getCommunityTokens*(self: Controller, communityId: string): seq[CommunityTo
proc getCommunityTokenOwners*(self: Controller, communityId: string, chainId: int, contractAddress: string): seq[CollectibleOwner] = proc getCommunityTokenOwners*(self: Controller, communityId: string, chainId: int, contractAddress: string): seq[CollectibleOwner] =
return self.communityTokensService.getCommunityTokenOwners(communityId, chainId, contractAddress) return self.communityTokensService.getCommunityTokenOwners(communityId, chainId, contractAddress)
proc getCommunityTokenOwnerName*(self: Controller, chainId: int, contractAddress: string): string = proc getCommunityTokenOwnerName*(self: Controller, contractOwnerAddress: string): string =
return self.communityTokensService.contractOwnerName(chainId, contractAddress) return self.communityTokensService.contractOwnerName(contractOwnerAddress)
proc getCommunityTokenBurnState*(self: Controller, chainId: int, contractAddress: string): ContractTransactionStatus = proc getCommunityTokenBurnState*(self: Controller, chainId: int, contractAddress: string): ContractTransactionStatus =
return self.communityTokensService.getCommunityTokenBurnState(chainId, contractAddress) return self.communityTokensService.getCommunityTokenBurnState(chainId, contractAddress)

View File

@ -291,12 +291,18 @@ method onSharedKeycarModuleKeycardSyncPurposeTerminated*(self: AccessInterface,
method onCommunityTokenDeploymentStarted*(self: AccessInterface, communityToken: CommunityTokenDto) {.base.} = method onCommunityTokenDeploymentStarted*(self: AccessInterface, communityToken: CommunityTokenDto) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method onOwnerTokensDeploymentStarted*(self: AccessInterface, ownerToken: CommunityTokenDto, masterToken: CommunityTokenDto) {.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityTokenOwnersFetched*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, owners: seq[CollectibleOwner]) {.base.} = method onCommunityTokenOwnersFetched*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, owners: seq[CollectibleOwner]) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method onCommunityTokenDeployStateChanged*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, deployState: DeployState) {.base.} = method onCommunityTokenDeployStateChanged*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, deployState: DeployState) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method onOwnerTokenDeployStateChanged*(self: AccessInterface, communityId: string, chainId: int, ownerContractAddress: string, masterContractAddress: string, deployState: DeployState) {.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityTokenSupplyChanged*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, supply: Uint256, remainingSupply: Uint256, destructedAmount: Uint256) {.base.} = method onCommunityTokenSupplyChanged*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, supply: Uint256, remainingSupply: Uint256, destructedAmount: Uint256) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")

View File

@ -245,7 +245,7 @@ method delete*[T](self: Module[T]) =
proc createTokenItem[T](self: Module[T], tokenDto: CommunityTokenDto) : TokenItem = proc createTokenItem[T](self: Module[T], tokenDto: CommunityTokenDto) : TokenItem =
let network = self.controller.getNetwork(tokenDto.chainId) let network = self.controller.getNetwork(tokenDto.chainId)
let tokenOwners = self.controller.getCommunityTokenOwners(tokenDto.communityId, tokenDto.chainId, tokenDto.address) let tokenOwners = self.controller.getCommunityTokenOwners(tokenDto.communityId, tokenDto.chainId, tokenDto.address)
let ownerAddressName = self.controller.getCommunityTokenOwnerName(tokenDto.chainId, tokenDto.address) let ownerAddressName = if len(tokenDto.deployer) > 0: self.controller.getCommunityTokenOwnerName(tokenDto.deployer) else: ""
let remainingSupply = if tokenDto.infiniteSupply: stint.parse("0", Uint256) else: self.controller.getRemainingSupply(tokenDto.chainId, tokenDto.address) let remainingSupply = if tokenDto.infiniteSupply: stint.parse("0", Uint256) else: self.controller.getRemainingSupply(tokenDto.chainId, tokenDto.address)
let burnState = self.controller.getCommunityTokenBurnState(tokenDto.chainId, tokenDto.address) let burnState = self.controller.getCommunityTokenBurnState(tokenDto.chainId, tokenDto.address)
let remoteDestructedAddresses = self.controller.getRemoteDestructedAddresses(tokenDto.chainId, tokenDto.address) let remoteDestructedAddresses = self.controller.getRemoteDestructedAddresses(tokenDto.chainId, tokenDto.address)
@ -1049,6 +1049,12 @@ method onCommunityTokenDeploymentStarted*[T](self: Module[T], communityToken: Co
if item.id != "": if item.id != "":
item.appendCommunityToken(self.createTokenItem(communityToken)) item.appendCommunityToken(self.createTokenItem(communityToken))
method onOwnerTokensDeploymentStarted*[T](self: Module[T], ownerToken: CommunityTokenDto, masterToken: CommunityTokenDto) =
let item = self.view.model().getItemById(ownerToken.communityId)
if item.id != "":
item.appendCommunityToken(self.createTokenItem(ownerToken))
item.appendCommunityToken(self.createTokenItem(masterToken))
method onCommunityTokenRemoved*[T](self: Module[T], communityId: string, chainId: int, address: string) = method onCommunityTokenRemoved*[T](self: Module[T], communityId: string, chainId: int, address: string) =
let item = self.view.model().getItemById(communityId) let item = self.view.model().getItemById(communityId)
if item.id != "": if item.id != "":
@ -1064,6 +1070,15 @@ method onCommunityTokenDeployStateChanged*[T](self: Module[T], communityId: stri
if item.id != "": if item.id != "":
item.updateCommunityTokenDeployState(chainId, contractAddress, deployState) item.updateCommunityTokenDeployState(chainId, contractAddress, deployState)
method onOwnerTokenDeployStateChanged*[T](self: Module[T], communityId: string, chainId: int, ownerContractAddress: string, masterContractAddress: string, deployState: DeployState) =
let item = self.view.model().getItemById(communityId)
if item.id != "":
# update temporary master contract address first
item.updateCommunityTokenAddress(chainId, temporaryMasterContractAddress(ownerContractAddress), masterContractAddress)
# then update states
item.updateCommunityTokenDeployState(chainId, ownerContractAddress, deployState)
item.updateCommunityTokenDeployState(chainId, masterContractAddress, deployState)
method onCommunityTokenSupplyChanged*[T](self: Module[T], communityId: string, chainId: int, contractAddress: string, supply: Uint256, remainingSupply: Uint256, destructedAmount: Uint256) = method onCommunityTokenSupplyChanged*[T](self: Module[T], communityId: string, chainId: int, contractAddress: string, supply: Uint256, remainingSupply: Uint256, destructedAmount: Uint256) =
let item = self.view.model().getItemById(communityId) let item = self.view.model().getItemById(communityId)
if item.id != "": if item.id != "":

View File

@ -338,6 +338,9 @@ proc removeCommunityToken*(self: SectionItem, chainId: int, contractAddress: str
proc updateCommunityTokenDeployState*(self: SectionItem, chainId: int, contractAddress: string, deployState: DeployState) {.inline.} = proc updateCommunityTokenDeployState*(self: SectionItem, chainId: int, contractAddress: string, deployState: DeployState) {.inline.} =
self.communityTokensModel.updateDeployState(chainId, contractAddress, deployState) self.communityTokensModel.updateDeployState(chainId, contractAddress, deployState)
proc updateCommunityTokenAddress*(self: SectionItem, chainId: int, oldContractAddress: string, newContractAddress: string) {.inline.} =
self.communityTokensModel.updateAddress(chainId, oldContractAddress, newContractAddress)
proc updateCommunityTokenSupply*(self: SectionItem, chainId: int, contractAddress: string, supply: Uint256, destructedAmount: Uint256) {.inline.} = proc updateCommunityTokenSupply*(self: SectionItem, chainId: int, contractAddress: string, supply: Uint256, destructedAmount: Uint256) {.inline.} =
self.communityTokensModel.updateSupply(chainId, contractAddress, supply, destructedAmount) self.communityTokensModel.updateSupply(chainId, contractAddress, supply, destructedAmount)

View File

@ -17,6 +17,29 @@ proc tableToJsonArray[A, B](t: var Table[A, B]): JsonNode =
}) })
return data return data
type
AsyncDeployOwnerContractsFeesArg = ref object of QObjectTaskArg
chainId: int
const asyncGetDeployOwnerContractsFeesTask: Task = proc(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 response = eth.suggestedFees(arg.chainId).result
feeTable[arg.chainId] = response.toSuggestedFeesDto()
let deployGas = community_tokens.deployOwnerTokenEstimate().result.getInt
gasTable[(arg.chainId, "")] = deployGas
arg.finish(%* {
"feeTable": tableToJsonArray(feeTable),
"gasTable": tableToJsonArray(gasTable),
"error": "",
})
except Exception as e:
arg.finish(%* {
"error": e.msg,
})
type type
AsyncGetDeployFeesArg = ref object of QObjectTaskArg AsyncGetDeployFeesArg = ref object of QObjectTaskArg
chainId: int chainId: int
@ -47,6 +70,7 @@ type
chainId: int chainId: int
contractAddress: string contractAddress: string
tokenIds: seq[UInt256] tokenIds: seq[UInt256]
addressFrom: string
const asyncGetRemoteBurnFeesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} = const asyncGetRemoteBurnFeesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncGetRemoteBurnFees](argEncoded) let arg = decode[AsyncGetRemoteBurnFees](argEncoded)
@ -54,7 +78,7 @@ const asyncGetRemoteBurnFeesTask: Task = proc(argEncoded: string) {.gcsafe, nimc
var gasTable: Table[ContractTuple, int] # gas per contract var gasTable: Table[ContractTuple, int] # gas per contract
var feeTable: Table[int, SuggestedFeesDto] # fees for chain var feeTable: Table[int, SuggestedFeesDto] # fees for chain
let fee = eth.suggestedFees(arg.chainId).result.toSuggestedFeesDto() let fee = eth.suggestedFees(arg.chainId).result.toSuggestedFeesDto()
let burnGas = community_tokens.estimateRemoteBurn(arg.chainId, arg.contractAddress, arg.tokenIds).result.getInt let burnGas = community_tokens.estimateRemoteBurn(arg.chainId, arg.contractAddress, arg.addressFrom, arg.tokenIds).result.getInt
feeTable[arg.chainId] = fee feeTable[arg.chainId] = fee
gasTable[(arg.chainId, arg.contractAddress)] = burnGas gasTable[(arg.chainId, arg.contractAddress)] = burnGas
arg.finish(%* { arg.finish(%* {
@ -71,6 +95,7 @@ type
chainId: int chainId: int
contractAddress: string contractAddress: string
amount: Uint256 amount: Uint256
addressFrom: string
const asyncGetBurnFeesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} = const asyncGetBurnFeesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncGetBurnFees](argEncoded) let arg = decode[AsyncGetBurnFees](argEncoded)
@ -78,7 +103,7 @@ const asyncGetBurnFeesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.}
var gasTable: Table[ContractTuple, int] # gas per contract var gasTable: Table[ContractTuple, int] # gas per contract
var feeTable: Table[int, SuggestedFeesDto] # fees for chain var feeTable: Table[int, SuggestedFeesDto] # fees for chain
let fee = eth.suggestedFees(arg.chainId).result.toSuggestedFeesDto() let fee = eth.suggestedFees(arg.chainId).result.toSuggestedFeesDto()
let burnGas = community_tokens.estimateBurn(arg.chainId, arg.contractAddress, arg.amount).result.getInt let burnGas = community_tokens.estimateBurn(arg.chainId, arg.contractAddress, arg.addressFrom, arg.amount).result.getInt
feeTable[arg.chainId] = fee feeTable[arg.chainId] = fee
gasTable[(arg.chainId, arg.contractAddress)] = burnGas gasTable[(arg.chainId, arg.contractAddress)] = burnGas
arg.finish(%* { arg.finish(%* {
@ -109,7 +134,7 @@ const asyncGetMintFeesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.}
# get gas for smart contract # get gas for smart contract
let gas = community_tokens.estimateMintTokens(chainId, let gas = community_tokens.estimateMintTokens(chainId,
collectibleAndAmount.communityToken.address, collectibleAndAmount.communityToken.address, collectibleAndAmount.communityToken.deployer,
arg.walletAddresses, collectibleAndAmount.amount).result.getInt arg.walletAddresses, collectibleAndAmount.amount).result.getInt
gasTable[(chainId, collectibleAndAmount.communityToken.address)] = gas gasTable[(chainId, collectibleAndAmount.communityToken.address)] = gas
arg.finish(%* { arg.finish(%* {
@ -152,4 +177,4 @@ const fetchCollectibleOwnersTaskArg: Task = proc(argEncoded: string) {.gcsafe, n
"result": "", "result": "",
"error": e.msg "error": e.msg
} }
arg.finish(output) arg.finish(output)

View File

@ -10,6 +10,13 @@ type
InProgress, InProgress,
Deployed Deployed
# determines what is the type of the token: owner, master or normal community contract
type
PrivilegesLevel* {.pure.} = enum
Owner,
Master,
Community
type type
CommunityTokenDto* = object CommunityTokenDto* = object
tokenType*: TokenType tokenType*: TokenType
@ -27,6 +34,8 @@ type
deployState*: DeployState deployState*: DeployState
image*: string image*: string
decimals*: int decimals*: int
deployer*: string
privilegesLevel*: PrivilegesLevel
proc toJsonNode*(self: CommunityTokenDto): JsonNode = proc toJsonNode*(self: CommunityTokenDto): JsonNode =
result = %* { result = %* {
@ -44,7 +53,9 @@ proc toJsonNode*(self: CommunityTokenDto): JsonNode =
"chainId": self.chainId, "chainId": self.chainId,
"deployState": self.deployState.int, "deployState": self.deployState.int,
"image": self.image, "image": self.image,
"decimals": self.decimals "decimals": self.decimals,
"deployer": self.deployer,
"privilegesLevel": self.privilegesLevel.int,
} }
proc toCommunityTokenDto*(jsonObj: JsonNode): CommunityTokenDto = proc toCommunityTokenDto*(jsonObj: JsonNode): CommunityTokenDto =
@ -70,6 +81,10 @@ proc toCommunityTokenDto*(jsonObj: JsonNode): CommunityTokenDto =
result.deployState = intToEnum(deployStateInt, DeployState.Failed) result.deployState = intToEnum(deployStateInt, DeployState.Failed)
discard jsonObj.getProp("image", result.image) discard jsonObj.getProp("image", result.image)
discard jsonObj.getProp("decimals", result.decimals) discard jsonObj.getProp("decimals", result.decimals)
discard jsonObj.getProp("deployer", result.deployer)
var privilegesLevelInt: int
discard jsonObj.getProp("privilegesLevel", privilegesLevelInt)
result.privilegesLevel = intToEnum(privilegesLevelInt, PrivilegesLevel.Community)
proc parseCommunityTokens*(response: RpcResponse[JsonNode]): seq[CommunityTokenDto] = proc parseCommunityTokens*(response: RpcResponse[JsonNode]): seq[CommunityTokenDto] =
result = map(response.result.getElems(), result = map(response.result.getElems(),

View File

@ -10,6 +10,8 @@ type
remoteSelfDestruct*: bool remoteSelfDestruct*: bool
tokenUri*: string tokenUri*: string
decimals*: int decimals*: int
ownerTokenAddress*: string
masterTokenAddress*: string
proc `%`*(x: DeploymentParameters): JsonNode = proc `%`*(x: DeploymentParameters): JsonNode =
result = newJobject() result = newJobject()
@ -21,5 +23,5 @@ proc `%`*(x: DeploymentParameters): JsonNode =
result["remoteSelfDestruct"] = %x.remoteSelfDestruct result["remoteSelfDestruct"] = %x.remoteSelfDestruct
result["tokenUri"] = %x.tokenUri result["tokenUri"] = %x.tokenUri
result["decimals"] = %x.decimals result["decimals"] = %x.decimals
result["ownerTokenAddress"] = %x.ownerTokenAddress
result["masterTokenAddress"] = %x.masterTokenAddress

View File

@ -72,11 +72,26 @@ type
transactionHash*: string transactionHash*: string
deployState*: DeployState deployState*: DeployState
type
OwnerTokenDeployedStatusArgs* = ref object of Args
communityId*: string
chainId*: int
ownerContractAddress*: string
masterContractAddress*: string
transactionHash*: string
deployState*: DeployState
type type
CommunityTokenDeploymentArgs* = ref object of Args CommunityTokenDeploymentArgs* = ref object of Args
communityToken*: CommunityTokenDto communityToken*: CommunityTokenDto
transactionHash*: string transactionHash*: string
type
OwnerTokenDeploymentArgs* = ref object of Args
ownerToken*: CommunityTokenDto
masterToken*: CommunityTokenDto
transactionHash*: string
type type
CommunityTokenRemovedArgs* = ref object of Args CommunityTokenRemovedArgs* = ref object of Args
communityId*: string communityId*: string
@ -109,6 +124,28 @@ proc `%`*(self: RemoteDestroyTransactionDetails): JsonNode =
"addresses": self.addresses "addresses": self.addresses
} }
type
OwnerTokenDeploymentTransactionDetails* = object
ownerToken*: ContractTuple
masterToken*: ContractTuple
communityId*: string
proc `%`*(self: OwnerTokenDeploymentTransactionDetails): JsonNode =
result = %* {
"ownerToken": %self.ownerToken,
"masterToken": %self.masterToken,
"communityId": self.communityId
}
proc toOwnerTokenDeploymentTransactionDetails*(jsonObj: JsonNode): OwnerTokenDeploymentTransactionDetails =
result = OwnerTokenDeploymentTransactionDetails()
try:
result.ownerToken = (jsonObj["ownerToken"]["chainId"].getInt, jsonObj["ownerToken"]["address"].getStr)
result.masterToken = (jsonObj["masterToken"]["chainId"].getInt, jsonObj["masterToken"]["address"].getStr)
result.communityId = jsonObj["communityId"].getStr
except Exception as e:
error "Error parsing OwnerTokenDeploymentTransactionDetails json", msg=e.msg
proc toRemoteDestroyTransactionDetails*(json: JsonNode): RemoteDestroyTransactionDetails = proc toRemoteDestroyTransactionDetails*(json: JsonNode): RemoteDestroyTransactionDetails =
return RemoteDestroyTransactionDetails(chainId: json["chainId"].getInt, contractAddress: json["contractAddress"].getStr, addresses: to(json["addresses"], seq[string])) return RemoteDestroyTransactionDetails(chainId: json["chainId"].getInt, contractAddress: json["contractAddress"].getStr, addresses: to(json["addresses"], seq[string]))
@ -175,7 +212,10 @@ const SIGNAL_BURN_STATUS* = "communityTokenBurnStatus"
const SIGNAL_AIRDROP_STATUS* = "airdropStatus" const SIGNAL_AIRDROP_STATUS* = "airdropStatus"
const SIGNAL_REMOVE_COMMUNITY_TOKEN_FAILED* = "removeCommunityTokenFailed" const SIGNAL_REMOVE_COMMUNITY_TOKEN_FAILED* = "removeCommunityTokenFailed"
const SIGNAL_COMMUNITY_TOKEN_REMOVED* = "communityTokenRemoved" const SIGNAL_COMMUNITY_TOKEN_REMOVED* = "communityTokenRemoved"
const SIGNAL_OWNER_TOKEN_DEPLOY_STATUS* = "ownerTokenDeployStatus"
const SIGNAL_OWNER_TOKEN_DEPLOYMENT_STARTED* = "ownerTokenDeploymentStarted"
const SIGNAL_DEPLOY_OWNER_TOKEN* = "deployOwnerToken"
QtObject: QtObject:
type type
@ -197,6 +237,12 @@ QtObject:
tempGasTable: Table[ContractTuple, int] # gas per contract, filled during gas computation, used during operation (deployment, mint, burn) tempGasTable: Table[ContractTuple, int] # gas per contract, filled during gas computation, used during operation (deployment, mint, burn)
tempTokensAndAmounts: seq[CommunityTokenAndAmount] tempTokensAndAmounts: seq[CommunityTokenAndAmount]
tempDeploymentChainId: int
tempDeploymentCommunityId: string
tempDeploymentParams: DeploymentParameters
tempDeploymentCroppedImageJson: string
tempDeploymentAddressFrom: string
# Forward declaration # Forward declaration
proc fetchAllTokenOwners*(self: Service) proc fetchAllTokenOwners*(self: Service)
proc getCommunityTokenOwners*(self: Service, communityId: string, chainId: int, contractAddress: string): seq[CollectibleOwner] proc getCommunityTokenOwners*(self: Service, communityId: string, chainId: int, contractAddress: string): seq[CollectibleOwner]
@ -258,6 +304,50 @@ QtObject:
except Exception as e: except Exception as e:
error "Error processing Collectible deployment pending transaction event", msg=e.msg, receivedData error "Error processing Collectible deployment pending transaction event", msg=e.msg, receivedData
self.events.on(PendingTransactionTypeDto.DeployOwnerToken.event) do(e: Args):
var receivedData = TransactionMinedArgs(e)
try:
let deployState = if receivedData.success: DeployState.Deployed else: DeployState.Failed
let ownerTransactionDetails = toOwnerTokenDeploymentTransactionDetails(parseJson(receivedData.data))
if not receivedData.success:
error "Owner contracts not deployed", chainId=ownerTransactionDetails.ownerToken.chainId, address=ownerTransactionDetails.ownerToken.address
var masterContractAddress = ownerTransactionDetails.masterToken.address
try:
# get master token address from transaction logs
if receivedData.success:
let response = tokens_backend.getMasterTokenContractAddressFromHash(ownerTransactionDetails.masterToken.chainId, receivedData.transactionHash)
masterContractAddress = response.result.getStr()
if masterContractAddress == "":
raise newException(RpcException, "master contract address is empty")
# update master token address
discard updateCommunityTokenAddress(ownerTransactionDetails.masterToken.chainId, ownerTransactionDetails.masterToken.address, masterContractAddress)
#update db state for owner and master token
discard updateCommunityTokenState(ownerTransactionDetails.ownerToken.chainId, ownerTransactionDetails.ownerToken.address, deployState)
discard updateCommunityTokenState(ownerTransactionDetails.masterToken.chainId, masterContractAddress, deployState)
# now add owner token to community and publish update
var response = tokens_backend.addCommunityToken(ownerTransactionDetails.communityId, ownerTransactionDetails.ownerToken.chainId, ownerTransactionDetails.ownerToken.address)
if response.error != nil:
let error = Json.decode($response.error, RpcError)
raise newException(RpcException, "error adding owner token: " & error.message)
# now add master token to community and publish update
response = tokens_backend.addCommunityToken(ownerTransactionDetails.communityId, ownerTransactionDetails.masterToken.chainId, masterContractAddress)
if response.error != nil:
let error = Json.decode($response.error, RpcError)
raise newException(RpcException, "error adding master token: " & error.message)
except RpcException:
error "Error updating owner contracts state", message = getCurrentExceptionMsg()
let data = OwnerTokenDeployedStatusArgs(communityId: ownerTransactionDetails.communityId, chainId: ownerTransactionDetails.ownerToken.chainId,
ownerContractAddress: ownerTransactionDetails.ownerToken.address,
masterContractAddress: masterContractAddress,
deployState: deployState,
transactionHash: receivedData.transactionHash)
self.events.emit(SIGNAL_OWNER_TOKEN_DEPLOY_STATUS, data)
except Exception as e:
error "Error processing Collectible deployment pending transaction event", msg=e.msg, receivedData
self.events.on(PendingTransactionTypeDto.AirdropCommunityToken.event) do(e: Args): self.events.on(PendingTransactionTypeDto.AirdropCommunityToken.event) do(e: Args):
let receivedData = TransactionMinedArgs(e) let receivedData = TransactionMinedArgs(e)
@ -316,6 +406,98 @@ QtObject:
if suggestedFees.eip1559Enabled: $suggestedFees.maxPriorityFeePerGas else: "", if suggestedFees.eip1559Enabled: $suggestedFees.maxPriorityFeePerGas else: "",
if suggestedFees.eip1559Enabled: $suggestedFees.maxFeePerGasM else: "") if suggestedFees.eip1559Enabled: $suggestedFees.maxFeePerGasM else: "")
proc createCommunityToken(self: Service, deploymentParams: DeploymentParameters, tokenMetadata: CommunityTokensMetadataDto,
chainId: int, contractAddress: string, communityId: string, addressFrom: string, privilegesLevel: PrivilegesLevel): CommunityTokenDto =
result.tokenType = tokenMetadata.tokenType
result.communityId = communityId
result.address = contractAddress
result.name = deploymentParams.name
result.symbol = deploymentParams.symbol
result.description = tokenMetadata.description
result.supply = stint.parse($deploymentParams.supply, Uint256)
result.infiniteSupply = deploymentParams.infiniteSupply
result.transferable = deploymentParams.transferable
result.remoteSelfDestruct = deploymentParams.remoteSelfDestruct
result.tokenUri = deploymentParams.tokenUri
result.chainId = chainId
result.deployState = DeployState.InProgress
result.decimals = deploymentParams.decimals
result.deployer = addressFrom
result.privilegesLevel = privilegesLevel
proc saveTokenToDbAndWatchTransaction*(self:Service, communityToken: CommunityTokenDto, croppedImageJson: string,
transactionHash: string, addressFrom: string, watchTransaction: bool) =
var croppedImage = croppedImageJson.parseJson
croppedImage{"imagePath"} = newJString(singletonInstance.utils.formatImagePath(croppedImage["imagePath"].getStr))
# save token to db
let communityTokenJson = tokens_backend.saveCommunityToken(communityToken, $croppedImage)
let addedCommunityToken = communityTokenJson.result.toCommunityTokenDto()
let data = CommunityTokenDeploymentArgs(communityToken: addedCommunityToken, transactionHash: transactionHash)
self.events.emit(SIGNAL_COMMUNITY_TOKEN_DEPLOYMENT_STARTED, data)
if watchTransaction:
# observe transaction state
self.transactionService.watchTransaction(
transactionHash,
addressFrom,
addedCommunityToken.address,
$PendingTransactionTypeDto.DeployCommunityToken,
$addedCommunityToken.toJsonNode(),
addedCommunityToken.chainId,
)
proc temporaryMasterContractAddress*(ownerContractAddress: string): string =
return ownerContractAddress & "-master"
proc deployOwnerContracts*(self: Service, communityId: string, addressFrom: string, password: string,
ownerDeploymentParams: DeploymentParameters, ownerTokenMetadata: CommunityTokensMetadataDto,
masterDeploymentParams: DeploymentParameters, masterTokenMetadata: CommunityTokensMetadataDto,
croppedImageJson: string, chainId: int) =
try:
let txData = self.buildTransactionDataDto(addressFrom, chainId, "")
if txData.source == parseAddress(ZERO_ADDRESS):
return
let response = tokens_backend.deployOwnerToken(chainId, %ownerDeploymentParams, %masterDeploymentParams, %txData, password)
let ownerContractAddress = response.result["contractAddress"].getStr()
let transactionHash = response.result["transactionHash"].getStr()
debug "Deployed owner contract address ", ownerContractAddress=ownerContractAddress
debug "Deployment transaction hash ", transactionHash=transactionHash
var ownerToken = self.createCommunityToken(ownerDeploymentParams, ownerTokenMetadata, chainId, ownerContractAddress, communityId, addressFrom, PrivilegesLevel.Owner)
var masterToken = self.createCommunityToken(masterDeploymentParams, masterTokenMetadata, chainId, temporaryMasterContractAddress(ownerContractAddress), communityId, addressFrom, PrivilegesLevel.Master)
var croppedImage = croppedImageJson.parseJson
ownerToken.image = croppedImage{"imagePath"}.getStr
masterToken.image = croppedImage{"imagePath"}.getStr
let ownerTokenJson = tokens_backend.saveCommunityToken(ownerToken, "")
let addedOwnerToken = ownerTokenJson.result.toCommunityTokenDto()
let masterTokenJson = tokens_backend.saveCommunityToken(masterToken, "")
let addedMasterToken = masterTokenJson.result.toCommunityTokenDto()
let data = OwnerTokenDeploymentArgs(ownerToken: addedOwnerToken, masterToken: addedMasterToken, transactionHash: transactionHash)
self.events.emit(SIGNAL_OWNER_TOKEN_DEPLOYMENT_STARTED, data)
let transactionDetails = OwnerTokenDeploymentTransactionDetails(ownerToken: (chainId, addedOwnerToken.address),
masterToken: (chainId, addedMasterToken.address), communityId: addedOwnerToken.communityId)
self.transactionService.watchTransaction(
transactionHash,
addressFrom,
addedOwnerToken.address,
$PendingTransactionTypeDto.DeployOwnerToken,
$(%transactionDetails),
chainId,
)
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, tokenMetadata: CommunityTokensMetadataDto, croppedImageJson: string, chainId: int) = proc deployContract*(self: Service, communityId: string, addressFrom: string, password: string, deploymentParams: DeploymentParameters, tokenMetadata: CommunityTokensMetadataDto, croppedImageJson: string, chainId: int) =
try: try:
let txData = self.buildTransactionDataDto(addressFrom, chainId, "") let txData = self.buildTransactionDataDto(addressFrom, chainId, "")
@ -337,42 +519,11 @@ QtObject:
debug "Deployed contract address ", contractAddress=contractAddress debug "Deployed contract address ", contractAddress=contractAddress
debug "Deployment transaction hash ", transactionHash=transactionHash debug "Deployment transaction hash ", transactionHash=transactionHash
var communityToken: CommunityTokenDto var communityToken = self.createCommunityToken(deploymentParams, tokenMetadata, chainId, contractAddress, communityId, addressFrom, PrivilegesLevel.Community)
communityToken.tokenType = tokenMetadata.tokenType
communityToken.communityId = communityId
communityToken.address = contractAddress
communityToken.name = deploymentParams.name
communityToken.symbol = deploymentParams.symbol
communityToken.description = tokenMetadata.description
communityToken.supply = stint.parse($deploymentParams.supply, Uint256)
communityToken.infiniteSupply = deploymentParams.infiniteSupply
communityToken.transferable = deploymentParams.transferable
communityToken.remoteSelfDestruct = deploymentParams.remoteSelfDestruct
communityToken.tokenUri = deploymentParams.tokenUri
communityToken.chainId = chainId
communityToken.deployState = DeployState.InProgress
communityToken.decimals = deploymentParams.decimals
var croppedImage = croppedImageJson.parseJson self.saveTokenToDbAndWatchTransaction(communityToken, croppedImageJson, transactionHash, addressFrom, true)
croppedImage{"imagePath"} = newJString(singletonInstance.utils.formatImagePath(croppedImage["imagePath"].getStr))
# save token to db except RpcException:
let communityTokenJson = tokens_backend.saveCommunityToken(communityToken, $croppedImage)
communityToken = communityTokenJson.result.toCommunityTokenDto()
let data = CommunityTokenDeploymentArgs(communityToken: communityToken, transactionHash: transactionHash)
self.events.emit(SIGNAL_COMMUNITY_TOKEN_DEPLOYMENT_STARTED, data)
# observe transaction state
self.transactionService.watchTransaction(
transactionHash,
addressFrom,
contractAddress,
$PendingTransactionTypeDto.DeployCommunityToken,
$communityToken.toJsonNode(),
chainId,
)
except RpcException as e:
error "Error deploying contract", message = getCurrentExceptionMsg() error "Error deploying contract", message = getCurrentExceptionMsg()
let data = CommunityTokenDeployedStatusArgs(communityId: communityId, let data = CommunityTokenDeployedStatusArgs(communityId: communityId,
deployState: DeployState.Failed) deployState: DeployState.Failed)
@ -437,17 +588,9 @@ QtObject:
except Exception: except Exception:
error "Error getting contract owner", message = getCurrentExceptionMsg() error "Error getting contract owner", message = getCurrentExceptionMsg()
proc contractOwner*(self: Service, chainId: int, contractAddress: string): string = proc contractOwnerName*(self: Service, contractOwnerAddress: string): string =
try: try:
let response = tokens_backend.contractOwner(chainId, contractAddress) return self.walletAccountService.getAccountByAddress(contractOwnerAddress).name
return response.result.getStr()
except RpcException:
error "Error getting contract owner", message = getCurrentExceptionMsg()
proc contractOwnerName*(self: Service, chainId: int, contractAddress: string): string =
try:
let response = tokens_backend.contractOwner(chainId, contractAddress)
return self.walletAccountService.getAccountByAddress(response.result.getStr().toLower()).name
except RpcException: except RpcException:
error "Error getting contract owner name", message = getCurrentExceptionMsg() error "Error getting contract owner name", message = getCurrentExceptionMsg()
@ -457,6 +600,8 @@ QtObject:
return stint.parse(response.result.getStr(), Uint256) return stint.parse(response.result.getStr(), Uint256)
except RpcException: except RpcException:
error "Error getting remaining supply", message = getCurrentExceptionMsg() error "Error getting remaining supply", message = getCurrentExceptionMsg()
# if there is an exception probably community token is not minted yet
return self.getCommunityToken(chainId, contractAddress).supply
proc getRemoteDestructedAmount*(self: Service, chainId: int, contractAddress: string): Uint256 = proc getRemoteDestructedAmount*(self: Service, chainId: int, contractAddress: string): Uint256 =
try: try:
@ -471,7 +616,7 @@ QtObject:
proc airdropTokens*(self: Service, communityId: string, password: string, collectiblesAndAmounts: seq[CommunityTokenAndAmount], walletAddresses: seq[string]) = proc airdropTokens*(self: Service, communityId: string, password: string, collectiblesAndAmounts: seq[CommunityTokenAndAmount], walletAddresses: seq[string]) =
try: try:
for collectibleAndAmount in collectiblesAndAmounts: for collectibleAndAmount in collectiblesAndAmounts:
let addressFrom = self.contractOwner(collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address) let addressFrom = collectibleAndAmount.communityToken.deployer
let txData = self.buildTransactionDataDto(addressFrom, collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address) let txData = self.buildTransactionDataDto(addressFrom, collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address)
if txData.source == parseAddress(ZERO_ADDRESS): if txData.source == parseAddress(ZERO_ADDRESS):
return return
@ -534,6 +679,20 @@ QtObject:
except Exception as e: except Exception as e:
error "Error loading fees", msg = e.msg error "Error loading fees", msg = e.msg
proc computeDeployOwnerContractsFee*(self: Service, chainId: int, accountAddress: string) =
try:
self.tempAccountAddress = accountAddress
self.tempChainId = chainId
let arg = AsyncDeployOwnerContractsFeesArg(
tptr: cast[ByteAddress](asyncGetDeployOwnerContractsFeesTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onDeployOwnerContractsFees",
chainId: chainId,
)
self.threadpool.start(arg)
except Exception as e:
error "Error loading fees", msg = e.msg
proc findContractByUniqueId*(self: Service, contractUniqueKey: string): CommunityTokenDto = proc findContractByUniqueId*(self: Service, contractUniqueKey: string): CommunityTokenDto =
let allTokens = self.getAllCommunityTokens() let allTokens = self.getAllCommunityTokens()
for token in allTokens: for token in allTokens:
@ -573,7 +732,7 @@ QtObject:
let tokenIds = self.getTokensToBurn(walletAndAmounts, contract) let tokenIds = self.getTokensToBurn(walletAndAmounts, contract)
if len(tokenIds) == 0: if len(tokenIds) == 0:
return return
let addressFrom = self.contractOwner(contract.chainId, contract.address) let addressFrom = contract.deployer
let txData = self.buildTransactionDataDto(addressFrom, contract.chainId, contract.address) let txData = self.buildTransactionDataDto(addressFrom, contract.chainId, contract.address)
debug "Remote destruct collectibles ", chainId=contract.chainId, address=contract.address, tokens=tokenIds debug "Remote destruct collectibles ", chainId=contract.chainId, address=contract.address, tokens=tokenIds
let response = tokens_backend.remoteBurn(contract.chainId, contract.address, %txData, password, tokenIds) let response = tokens_backend.remoteBurn(contract.chainId, contract.address, %txData, password, tokenIds)
@ -602,7 +761,7 @@ QtObject:
proc computeSelfDestructFee*(self: Service, walletAndAmountList: seq[WalletAndAmount], contractUniqueKey: string) = proc computeSelfDestructFee*(self: Service, walletAndAmountList: seq[WalletAndAmount], contractUniqueKey: string) =
try: try:
let contract = self.findContractByUniqueId(contractUniqueKey) let contract = self.findContractByUniqueId(contractUniqueKey)
self.tempAccountAddress = self.contractOwner(contract.chainId, contract.address) self.tempAccountAddress = contract.deployer
self.tempChainId = contract.chainId self.tempChainId = contract.chainId
let tokenIds = self.getTokensToBurn(walletAndAmountList, contract) let tokenIds = self.getTokensToBurn(walletAndAmountList, contract)
if len(tokenIds) == 0: if len(tokenIds) == 0:
@ -614,7 +773,8 @@ QtObject:
slot: "onSelfDestructFees", slot: "onSelfDestructFees",
chainId: contract.chainId, chainId: contract.chainId,
contractAddress: contract.address, contractAddress: contract.address,
tokenIds: tokenIds tokenIds: tokenIds,
addressFrom: contract.deployer
) )
self.threadpool.start(arg) self.threadpool.start(arg)
except Exception as e: except Exception as e:
@ -639,7 +799,7 @@ QtObject:
proc burnTokens*(self: Service, communityId: string, password: string, contractUniqueKey: string, amount: Uint256) = proc burnTokens*(self: Service, communityId: string, password: string, contractUniqueKey: string, amount: Uint256) =
try: try:
var contract = self.findContractByUniqueId(contractUniqueKey) var contract = self.findContractByUniqueId(contractUniqueKey)
let addressFrom = self.contractOwner(contract.chainId, contract.address) let addressFrom = contract.deployer
let txData = self.buildTransactionDataDto(addressFrom, contract.chainId, contract.address) let txData = self.buildTransactionDataDto(addressFrom, contract.chainId, contract.address)
debug "Burn tokens ", chainId=contract.chainId, address=contract.address, amount=amount debug "Burn tokens ", chainId=contract.chainId, address=contract.address, amount=amount
let response = tokens_backend.burn(contract.chainId, contract.address, %txData, password, amount) let response = tokens_backend.burn(contract.chainId, contract.address, %txData, password, amount)
@ -665,7 +825,7 @@ QtObject:
proc computeBurnFee*(self: Service, contractUniqueKey: string, amount: Uint256) = proc computeBurnFee*(self: Service, contractUniqueKey: string, amount: Uint256) =
try: try:
let contract = self.findContractByUniqueId(contractUniqueKey) let contract = self.findContractByUniqueId(contractUniqueKey)
self.tempAccountAddress = self.contractOwner(contract.chainId, contract.address) self.tempAccountAddress = contract.deployer
self.tempChainId = contract.chainId self.tempChainId = contract.chainId
let arg = AsyncGetBurnFees( let arg = AsyncGetBurnFees(
tptr: cast[ByteAddress](asyncGetBurnFeesTask), tptr: cast[ByteAddress](asyncGetBurnFeesTask),
@ -673,7 +833,8 @@ QtObject:
slot: "onBurnFees", slot: "onBurnFees",
chainId: contract.chainId, chainId: contract.chainId,
contractAddress: contract.address, contractAddress: contract.address,
amount: amount amount: amount,
addressFrom: contract.deployer
) )
self.threadpool.start(arg) self.threadpool.start(arg)
except Exception as e: except Exception as e:
@ -754,6 +915,9 @@ QtObject:
let data = self.createComputeFeeArgsWithError(getCurrentExceptionMsg()) let data = self.createComputeFeeArgsWithError(getCurrentExceptionMsg())
self.events.emit(signalName, data) 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.} = proc onSelfDestructFees*(self:Service, response: string) {.slot.} =
self.parseFeeResponseAndEmitSignal(response, SIGNAL_COMPUTE_SELF_DESTRUCT_FEE) self.parseFeeResponseAndEmitSignal(response, SIGNAL_COMPUTE_SELF_DESTRUCT_FEE)
@ -796,7 +960,7 @@ QtObject:
let gasUnits = self.tempGasTable[(collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address)] let gasUnits = self.tempGasTable[(collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address)]
let suggestedFees = self.tempFeeTable[collectibleAndAmount.communityToken.chainId] let suggestedFees = self.tempFeeTable[collectibleAndAmount.communityToken.chainId]
let ethValue = self.computeEthValue(gasUnits, suggestedFees) let ethValue = self.computeEthValue(gasUnits, suggestedFees)
let walletAddress = self.contractOwner(collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address) let walletAddress = collectibleAndAmount.communityToken.deployer
wholeEthCostForChainWallet[(collectibleAndAmount.communityToken.chainId, walletAddress)] = wholeEthCostForChainWallet.getOrDefault((collectibleAndAmount.communityToken.chainId, walletAddress), 0.0) + ethValue wholeEthCostForChainWallet[(collectibleAndAmount.communityToken.chainId, walletAddress)] = wholeEthCostForChainWallet.getOrDefault((collectibleAndAmount.communityToken.chainId, walletAddress), 0.0) + ethValue
ethValuesForContracts[(collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address)] = ethValue ethValuesForContracts[(collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address)] = ethValue
@ -807,7 +971,7 @@ QtObject:
let contractTuple = (chainId: collectibleAndAmount.communityToken.chainId, let contractTuple = (chainId: collectibleAndAmount.communityToken.chainId,
address: collectibleAndAmount.communityToken.address) address: collectibleAndAmount.communityToken.address)
let ethValue = ethValuesForContracts[contractTuple] let ethValue = ethValuesForContracts[contractTuple]
let walletAddress = self.contractOwner(contractTuple.chainId, contractTuple.address) let walletAddress = collectibleAndAmount.communityToken.deployer
var balance = self.getWalletBalanceForChain(walletAddress, contractTuple.chainId) var balance = self.getWalletBalanceForChain(walletAddress, contractTuple.chainId)
if balance < wholeEthCostForChainWallet[(contractTuple.chainId, walletAddress)]: if balance < wholeEthCostForChainWallet[(contractTuple.chainId, walletAddress)]:
# if wallet balance for this chain is less than the whole cost # if wallet balance for this chain is less than the whole cost
@ -877,3 +1041,15 @@ QtObject:
let allTokens = self.getAllCommunityTokens() let allTokens = self.getAllCommunityTokens()
for token in allTokens: for token in allTokens:
self.fetchCommunityOwners(token) self.fetchCommunityOwners(token)
proc getOwnerToken*(self: Service, communityId: string): CommunityTokenDto =
let communityTokens = self.getCommunityTokens(communityId)
for token in communityTokens:
if token.privilegesLevel == PrivilegesLevel.Owner:
return token
proc getMasterToken*(self: Service, communityId: string): CommunityTokenDto =
let communityTokens = self.getCommunityTokens(communityId)
for token in communityTokens:
if token.privilegesLevel == PrivilegesLevel.Master:
return token

View File

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

View File

@ -28,7 +28,7 @@ proc getAllCommunityTokens*(): RpcResponse[JsonNode] {.raises: [Exception].} =
return core.callPrivateRPC("wakuext_getAllCommunityTokens", payload) return core.callPrivateRPC("wakuext_getAllCommunityTokens", payload)
proc saveCommunityToken*(token: CommunityTokenDto, croppedImageJson: string): RpcResponse[JsonNode] {.raises: [Exception].} = proc saveCommunityToken*(token: CommunityTokenDto, croppedImageJson: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let croppedImage = newCroppedImage(croppedImageJson) let croppedImage = if len(croppedImageJson) > 0: newCroppedImage(croppedImageJson) else: nil
let payload = %* [token.toJsonNode(), croppedImage] let payload = %* [token.toJsonNode(), croppedImage]
return core.callPrivateRPC("wakuext_saveCommunityToken", payload) return core.callPrivateRPC("wakuext_saveCommunityToken", payload)
@ -40,6 +40,10 @@ proc updateCommunityTokenState*(chainId: int, contractAddress: string, deploySta
let payload = %* [chainId, contractAddress, deployState.int] let payload = %* [chainId, contractAddress, deployState.int]
return core.callPrivateRPC("wakuext_updateCommunityTokenState", payload) return core.callPrivateRPC("wakuext_updateCommunityTokenState", payload)
proc updateCommunityTokenAddress*(chainId: int, oldContractAddress: string, newContractAddress: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chainId, oldContractAddress, newContractAddress]
return core.callPrivateRPC("wakuext_updateCommunityTokenAddress", payload)
proc updateCommunityTokenSupply*(chainId: int, contractAddress: string, supply: Uint256): RpcResponse[JsonNode] {.raises: [Exception].} = proc updateCommunityTokenSupply*(chainId: int, contractAddress: string, supply: Uint256): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chainId, contractAddress, supply.toString(10)] let payload = %* [chainId, contractAddress, supply.toString(10)]
return core.callPrivateRPC("wakuext_updateCommunityTokenSupply", payload) return core.callPrivateRPC("wakuext_updateCommunityTokenSupply", payload)
@ -48,30 +52,26 @@ proc mintTokens*(chainId: int, contractAddress: string, txData: JsonNode, passwo
let payload = %* [chainId, contractAddress, txData, utils.hashPassword(password), walletAddresses, amount.toString(10)] let payload = %* [chainId, contractAddress, txData, utils.hashPassword(password), walletAddresses, amount.toString(10)]
return core.callPrivateRPC("collectibles_mintTokens", payload) return core.callPrivateRPC("collectibles_mintTokens", payload)
proc estimateMintTokens*(chainId: int, contractAddress: string, walletAddresses: seq[string], amount: Uint256): RpcResponse[JsonNode] {.raises: [Exception].} = proc estimateMintTokens*(chainId: int, contractAddress: string, fromAddress: string, walletAddresses: seq[string], amount: Uint256): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chainId, contractAddress, walletAddresses, amount.toString(10)] let payload = %* [chainId, contractAddress, fromAddress, walletAddresses, amount.toString(10)]
return core.callPrivateRPC("collectibles_estimateMintTokens", payload) return core.callPrivateRPC("collectibles_estimateMintTokens", payload)
proc remoteBurn*(chainId: int, contractAddress: string, txData: JsonNode, password: string, tokenIds: seq[UInt256]): RpcResponse[JsonNode] {.raises: [Exception].} = proc remoteBurn*(chainId: int, contractAddress: string, txData: JsonNode, password: string, tokenIds: seq[UInt256]): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chainId, contractAddress, txData, utils.hashPassword(password), tokenIds.map(x => x.toString(10))] let payload = %* [chainId, contractAddress, txData, utils.hashPassword(password), tokenIds.map(x => x.toString(10))]
return core.callPrivateRPC("collectibles_remoteBurn", payload) return core.callPrivateRPC("collectibles_remoteBurn", payload)
proc estimateRemoteBurn*(chainId: int, contractAddress: string, tokenIds: seq[UInt256]): RpcResponse[JsonNode] {.raises: [Exception].} = proc estimateRemoteBurn*(chainId: int, contractAddress: string, fromAddress: string, tokenIds: seq[UInt256]): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chainId, contractAddress, tokenIds.map(x => x.toString(10))] let payload = %* [chainId, contractAddress, fromAddress, tokenIds.map(x => x.toString(10))]
return core.callPrivateRPC("collectibles_estimateRemoteBurn", payload) return core.callPrivateRPC("collectibles_estimateRemoteBurn", payload)
proc burn*(chainId: int, contractAddress: string, txData: JsonNode, password: string, amount: Uint256): RpcResponse[JsonNode] {.raises: [Exception].} = proc burn*(chainId: int, contractAddress: string, txData: JsonNode, password: string, amount: Uint256): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chainId, contractAddress, txData, utils.hashPassword(password), amount.toString(10)] let payload = %* [chainId, contractAddress, txData, utils.hashPassword(password), amount.toString(10)]
return core.callPrivateRPC("collectibles_burn", payload) return core.callPrivateRPC("collectibles_burn", payload)
proc estimateBurn*(chainId: int, contractAddress: string, amount: Uint256): RpcResponse[JsonNode] {.raises: [Exception].} = proc estimateBurn*(chainId: int, contractAddress: string, fromAddress: string, amount: Uint256): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chainId, contractAddress, amount.toString(10)] let payload = %* [chainId, contractAddress, fromAddress, amount.toString(10)]
return core.callPrivateRPC("collectibles_estimateBurn", payload) return core.callPrivateRPC("collectibles_estimateBurn", payload)
proc contractOwner*(chainId: int, contractAddress: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chainId, contractAddress]
return core.callPrivateRPC("collectibles_contractOwner", payload)
proc remainingSupply*(chainId: int, contractAddress: string): RpcResponse[JsonNode] {.raises: [Exception].} = proc remainingSupply*(chainId: int, contractAddress: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chainId, contractAddress] let payload = %* [chainId, contractAddress]
return core.callPrivateRPC("collectibles_remainingSupply", payload) return core.callPrivateRPC("collectibles_remainingSupply", payload)
@ -86,4 +86,16 @@ proc deployAssetsEstimate*(): RpcResponse[JsonNode] {.raises: [Exception].} =
proc remoteDestructedAmount*(chainId: int, contractAddress: string): RpcResponse[JsonNode] {.raises: [Exception].} = proc remoteDestructedAmount*(chainId: int, contractAddress: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %*[chainId, contractAddress] let payload = %*[chainId, contractAddress]
return core.callPrivateRPC("collectibles_remoteDestructedAmount", payload) return core.callPrivateRPC("collectibles_remoteDestructedAmount", payload)
proc deployOwnerTokenEstimate*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %*[]
return core.callPrivateRPC("collectibles_deployOwnerTokenEstimate", payload)
proc deployOwnerToken*(chainId: int, ownerParams: JsonNode, masterParams: JsonNode, txData: JsonNode, password: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %*[chainId, ownerParams, masterParams, txData, utils.hashPassword(password)]
return core.callPrivateRPC("collectibles_deployOwnerToken", payload)
proc getMasterTokenContractAddressFromHash*(chainId: int, transactionHash: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %*[chainId, transactionHash]
return core.callPrivateRPC("collectibles_getMasterTokenContractAddressFromHash", payload)

View File

@ -793,8 +793,7 @@ StackView {
token.type: model.tokenType token.type: model.tokenType
token.burnState: model.burnState token.burnState: model.burnState
token.remotelyDestructState: model.remotelyDestructState token.remotelyDestructState: model.remotelyDestructState
// TODO: Backend token.accountAddress: model.accountAddress
//token.accountAddress: model.accountAddress
} }
onCountChanged: { onCountChanged: {

View File

@ -360,7 +360,7 @@ StatusSectionLayout {
isFeeLoading = true isFeeLoading = true
communityTokensStore.computeDeployFee( communityTokensStore.computeDeployFee(
chainId, accountAddress, tokenType) chainId, accountAddress, tokenType, !(mintPanel.isOwnerTokenDeployed && mintPanel.isTMasterTokenDeployed))
} }
onBurnFeesRequested: { onBurnFeesRequested: {
@ -613,22 +613,24 @@ StatusSectionLayout {
StatusQUtils.ModelUtils.contains(model, "name", PermissionsHelpers.tMasterTokenNameTag + root.communityName) StatusQUtils.ModelUtils.contains(model, "name", PermissionsHelpers.tMasterTokenNameTag + root.communityName)
} }
function reviewTokenDeployState(tagType, isOwner, deployState) { function reviewTokenDeployState(isOwner, deployState) {
const index = StatusQUtils.ModelUtils.indexOf(model, "name", tagType + root.communityName) const privileges = isOwner ? Constants.TokenPrivilegesLevel.Owner : Constants.TokenPrivilegesLevel.TMaster
const index = StatusQUtils.ModelUtils.indexOf(model, "privilegesLevel", privileges)
if(index === -1) if(index === -1)
return false return false
const token = StatusQUtils.ModelUtils.get(model, index) const token = StatusQUtils.ModelUtils.get(model, index)
// Some assertions: // Some assertions:
if(!token.isPrivilegedToken) if(isOwner && token.privilegesLevel !== Constants.TokenPrivilegesLevel.Owner)
return false
if(!isOwner && token.privilegesLevel !== Constants.TokenPrivilegesLevel.TMaster)
return false return false
if(token.isOwner !== isOwner) if(token.isOwner !== isOwner)
return false return false
// Deploy state check: // Deploy state check:
return token.deployState !== deployState return token.deployState === deployState
} }
model: root.community.communityTokens model: root.community.communityTokens
@ -822,6 +824,39 @@ StatusSectionLayout {
Global.displayToastMessage(title, url === "" ? qsTr("Something went wrong") : qsTr("View on etherscan"), "", Global.displayToastMessage(title, url === "" ? qsTr("Something went wrong") : qsTr("View on etherscan"), "",
loading, type, url) 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 { Connections {

View File

@ -18,9 +18,11 @@ QtObject {
signal burnFeeUpdated(var ethCurrency, var fiatCurrency, int error) signal burnFeeUpdated(var ethCurrency, var fiatCurrency, int error)
signal deploymentStateChanged(string communityId, int status, string url) 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 remoteDestructStateChanged(string communityId, string tokenName, int status, string url)
signal burnStateChanged(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 airdropStateChanged(string communityId, string tokenName, string chainName, int status, string url)
signal ownerTokenDeploymentStarted(string communityId, string url)
// Minting tokens: // Minting tokens:
function deployCollectible(communityId, collectibleItem) function deployCollectible(communityId, collectibleItem)
@ -48,11 +50,9 @@ QtObject {
function deployOwnerToken(communityId, ownerToken, tMasterToken) function deployOwnerToken(communityId, ownerToken, tMasterToken)
{ {
// NOTE for backend team: `ownerToken` and `tMasterToken` can be used to do an assertion before the deployment process starts, since const jsonArtworkFile = Utils.getImageAndCropInfoJson(ownerToken.artworkSource, ownerToken.artworkCropRect)
// the objects have been created to display the token details to the user and must be the same than backend builds. communityTokensModuleInst.deployOwnerToken(communityId, ownerToken.accountAddress, ownerToken.name, ownerToken.symbol, ownerToken.description,
// TODO: Backend will need to check if the ownerToken or tMasterToken have a valid tokenKey, so it means a deployment retry, tMasterToken.name, tMasterToken.symbol, tMasterToken.description, ownerToken.chainId, jsonArtworkFile)
// otherwise, it is a new deployment.
console.log("TODO: Backend Owner and Token Master token deployment!")
} }
function deleteToken(communityId, contractUniqueKey) { function deleteToken(communityId, contractUniqueKey) {
@ -79,6 +79,14 @@ QtObject {
root.deploymentStateChanged(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) { function onRemoteDestructStateChanged(communityId, tokenName, status, url) {
root.remoteDestructStateChanged(communityId, tokenName, status, url) root.remoteDestructStateChanged(communityId, tokenName, status, url)
} }
@ -96,8 +104,8 @@ QtObject {
} }
} }
function computeDeployFee(chainId, accountAddress, tokenType) { function computeDeployFee(chainId, accountAddress, tokenType, isOwnerDeployment) {
communityTokensModuleInst.computeDeployFee(chainId, accountAddress, tokenType) communityTokensModuleInst.computeDeployFee(chainId, accountAddress, tokenType, isOwnerDeployment)
} }
function computeSelfDestructFee(selfDestructTokensList, tokenKey, accountAddress) { function computeSelfDestructFee(selfDestructTokensList, tokenKey, accountAddress) {