feat(@desktop/communities): Compute minting fees and displaying minting toast messages
Issue #10536
This commit is contained in:
parent
523ddd0572
commit
db55d10b37
|
@ -48,6 +48,9 @@ proc init*(self: Controller) =
|
|||
self.events.on(SIGNAL_COMPUTE_SELF_DESTRUCT_FEE) do(e:Args):
|
||||
let args = ComputeFeeArgs(e)
|
||||
self.communityTokensModule.onSelfDestructFeeComputed(args.ethCurrency, args.fiatCurrency, args.errorCode)
|
||||
self.events.on(SIGNAL_COMPUTE_AIRDROP_FEE) do(e:Args):
|
||||
let args = AirdropFeesArgs(e)
|
||||
self.communityTokensModule.onAirdropFeesComputed(args)
|
||||
self.events.on(SIGNAL_COMMUNITY_TOKEN_DEPLOYED) do(e: Args):
|
||||
let args = CommunityTokenDeployedArgs(e)
|
||||
self.communityTokensModule.onCommunityTokenDeployStateChanged(args.communityToken.communityId, args.communityToken.chainId, args.transactionHash, args.communityToken.deployState)
|
||||
|
@ -57,6 +60,9 @@ proc init*(self: Controller) =
|
|||
self.events.on(SIGNAL_REMOTE_DESTRUCT_STATUS) do(e: Args):
|
||||
let args = RemoteDestructArgs(e)
|
||||
self.communityTokensModule.onRemoteDestructStateChanged(args.communityToken.communityId, args.communityToken.name, args.communityToken.chainId, args.transactionHash, args.status)
|
||||
self.events.on(SIGNAL_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)
|
||||
|
||||
proc deployCollectibles*(self: Controller, communityId: string, addressFrom: string, password: string, deploymentParams: DeploymentParameters, tokenMetadata: CommunityTokensMetadataDto, chainId: int) =
|
||||
self.communityTokensService.deployCollectibles(communityId, addressFrom, password, deploymentParams, tokenMetadata, chainId)
|
||||
|
@ -64,6 +70,9 @@ proc deployCollectibles*(self: Controller, communityId: string, addressFrom: str
|
|||
proc airdropCollectibles*(self: Controller, communityId: string, password: string, collectiblesAndAmounts: seq[CommunityTokenAndAmount], walletAddresses: seq[string]) =
|
||||
self.communityTokensService.airdropCollectibles(communityId, password, collectiblesAndAmounts, walletAddresses)
|
||||
|
||||
proc computeAirdropCollectiblesFee*(self: Controller, collectiblesAndAmounts: seq[CommunityTokenAndAmount], walletAddresses: seq[string]) =
|
||||
self.communityTokensService.computeAirdropCollectiblesFee(collectiblesAndAmounts, walletAddresses)
|
||||
|
||||
proc selfDestructCollectibles*(self: Controller, communityId: string, password: string, walletAndAmounts: seq[WalletAndAmount], contractUniqueKey: string) =
|
||||
self.communityTokensService.selfDestructCollectibles(communityId, password, walletAndAmounts, contractUniqueKey)
|
||||
|
||||
|
@ -80,8 +89,8 @@ proc computeDeployFee*(self: Controller, chainId: int, accountAddress: string) =
|
|||
proc computeSelfDestructFee*(self: Controller, walletAndAmountList: seq[WalletAndAmount], contractUniqueKey: string) =
|
||||
self.communityTokensService.computeSelfDestructFee(walletAndAmountList, contractUniqueKey)
|
||||
|
||||
proc getCommunityTokenBySymbol*(self: Controller, communityId: string, symbol: string): CommunityTokenDto =
|
||||
return self.communityTokensService.getCommunityTokenBySymbol(communityId, symbol)
|
||||
proc findContractByUniqueId*(self: Controller, contractUniqueKey: string): CommunityTokenDto =
|
||||
return self.communityTokensService.findContractByUniqueId(contractUniqueKey)
|
||||
|
||||
proc getNetwork*(self:Controller, chainId: int): NetworkDto =
|
||||
self.networksService.getNetwork(chainId)
|
|
@ -13,6 +13,9 @@ method load*(self: AccessInterface) {.base.} =
|
|||
method airdropCollectibles*(self: AccessInterface, communityId: string, collectiblesJsonString: string, walletsJsonString: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method computeAirdropCollectiblesFee*(self: AccessInterface, communityId: string, collectiblesJsonString: string, walletsJsonString: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method selfDestructCollectibles*(self: AccessInterface, communityId: string, collectiblesToBurnJsonString: string, contractUniqueKey: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
@ -38,8 +41,14 @@ method onDeployFeeComputed*(self: AccessInterface, ethCurrency: CurrencyAmount,
|
|||
method onSelfDestructFeeComputed*(self: AccessInterface, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: ComputeFeeErrorCode) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onAirdropFeesComputed*(self: AccessInterface, args: AirdropFeesArgs) {.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")
|
||||
|
||||
method onRemoteDestructStateChanged*(self: AccessInterface, communityId: string, tokenName: string, chainId: int, transactionHash: string, status: ContractTransactionStatus) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onAirdropStateChanged*(self: AccessInterface, communityId: string, tokenName: string, chainId: int, transactionHash: string, status: ContractTransactionStatus) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -80,23 +80,33 @@ proc authenticate(self: Module) =
|
|||
else:
|
||||
self.controller.authenticateUser()
|
||||
|
||||
method airdropCollectibles*(self: Module, communityId: string, collectiblesJsonString: string, walletsJsonString: string) =
|
||||
proc getTokenAndAmountList(self: Module, communityId: string, collectiblesJsonString: string): seq[CommunityTokenAndAmount] =
|
||||
try:
|
||||
let collectiblesJson = collectiblesJsonString.parseJson
|
||||
self.tempTokenAndAmountList = @[]
|
||||
for collectible in collectiblesJson:
|
||||
let symbol = collectible["key"].getStr
|
||||
let contractUniqueKey = collectible["contractUniqueKey"].getStr
|
||||
let amount = collectible["amount"].getInt
|
||||
let tokenDto = self.controller.getCommunityTokenBySymbol(communityId, symbol)
|
||||
let tokenDto = self.controller.findContractByUniqueId(contractUniqueKey)
|
||||
if tokenDto.tokenType == TokenType.Unknown:
|
||||
error "Can't find token for community", communityId=communityId, symbol=symbol
|
||||
return
|
||||
self.tempTokenAndAmountList.add(CommunityTokenAndAmount(communityToken: tokenDto, amount: amount))
|
||||
error "Can't find token for community", contractUniqueKey=contractUniqueKey
|
||||
return @[]
|
||||
result.add(CommunityTokenAndAmount(communityToken: tokenDto, amount: amount))
|
||||
except Exception as e:
|
||||
error "Error getTokenAndAmountList", msg = e.msg
|
||||
|
||||
method airdropCollectibles*(self: Module, communityId: string, collectiblesJsonString: string, walletsJsonString: string) =
|
||||
self.tempTokenAndAmountList = self.getTokenAndAmountList(communityId, collectiblesJsonString)
|
||||
if len(self.tempTokenAndAmountList) == 0:
|
||||
return
|
||||
self.tempWalletAddresses = walletsJsonString.parseJson.to(seq[string])
|
||||
self.tempCommunityId = communityId
|
||||
self.tempContractAction = ContractAction.Airdrop
|
||||
self.authenticate()
|
||||
|
||||
method computeAirdropCollectiblesFee*(self: Module, communityId: string, collectiblesJsonString: string, walletsJsonString: string) =
|
||||
let tokenAndAmountList = self.getTokenAndAmountList(communityId, collectiblesJsonString)
|
||||
self.controller.computeAirdropCollectiblesFee(tokenAndAmountList, walletsJsonString.parseJson.to(seq[string]))
|
||||
|
||||
proc getWalletAndAmountListFromJson(self: Module, collectiblesToBurnJsonString: string): seq[WalletAndAmount] =
|
||||
let collectiblesToBurnJson = collectiblesToBurnJsonString.parseJson
|
||||
for collectibleToBurn in collectiblesToBurnJson:
|
||||
|
@ -147,6 +157,9 @@ method onDeployFeeComputed*(self: Module, ethCurrency: CurrencyAmount, fiatCurre
|
|||
method onSelfDestructFeeComputed*(self: Module, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: ComputeFeeErrorCode) =
|
||||
self.view.updateSelfDestructFee(ethCurrency, fiatCurrency, errorCode.int)
|
||||
|
||||
method onAirdropFeesComputed*(self: Module, args: AirdropFeesArgs) =
|
||||
self.view.updateAirdropFees(%args)
|
||||
|
||||
method computeDeployFee*(self: Module, chainId: int, accountAddress: string) =
|
||||
self.controller.computeDeployFee(chainId, accountAddress)
|
||||
|
||||
|
@ -163,3 +176,8 @@ method onRemoteDestructStateChanged*(self: Module, communityId: string, tokenNam
|
|||
let network = self.controller.getNetwork(chainId)
|
||||
let url = if network != nil: network.blockExplorerURL & "/tx/" & transactionHash else: ""
|
||||
self.view.emitRemoteDestructStateChanged(communityId, tokenName, status.int, url)
|
||||
|
||||
method onAirdropStateChanged*(self: Module, communityId: string, tokenName: string, chainId: int, transactionHash: string, status: ContractTransactionStatus) =
|
||||
let network = self.controller.getNetwork(chainId)
|
||||
let url = if network != nil: network.blockExplorerURL & "/tx/" & transactionHash else: ""
|
||||
self.view.emitAirdropStateChanged(communityId, tokenName, status.int, url)
|
|
@ -25,11 +25,15 @@ QtObject:
|
|||
proc airdropCollectibles*(self: View, communityId: string, collectiblesJsonString: string, walletsJsonString: string) {.slot.} =
|
||||
self.communityTokensModule.airdropCollectibles(communityId, collectiblesJsonString, walletsJsonString)
|
||||
|
||||
proc computeAirdropCollectiblesFee*(self: View, communityId: string, collectiblesJsonString: string, walletsJsonString: string) {.slot.} =
|
||||
self.communityTokensModule.computeAirdropCollectiblesFee(communityId, collectiblesJsonString, walletsJsonString)
|
||||
|
||||
proc selfDestructCollectibles*(self: View, communityId: string, collectiblesToBurnJsonString: string, contractUniqueKey: string) {.slot.} =
|
||||
self.communityTokensModule.selfDestructCollectibles(communityId, collectiblesToBurnJsonString, contractUniqueKey)
|
||||
|
||||
proc deployFeeUpdated*(self: View, ethCurrency: QVariant, fiatCurrency: QVariant, errorCode: int) {.signal.}
|
||||
proc selfDestructFeeUpdated*(self: View, ethCurrency: QVariant, fiatCurrency: QVariant, errorCode: int) {.signal.}
|
||||
proc airdropFeesUpdated*(self: View, json: string) {.signal.}
|
||||
|
||||
proc computeDeployFee*(self: View, chainId: int, accountAddress: string) {.slot.} =
|
||||
self.communityTokensModule.computeDeployFee(chainId, accountAddress)
|
||||
|
@ -43,6 +47,9 @@ QtObject:
|
|||
proc updateSelfDestructFee*(self: View, ethCurrency: CurrencyAmount, fiatCurrency: CurrencyAmount, errorCode: int) =
|
||||
self.selfDestructFeeUpdated(newQVariant(ethCurrency), newQVariant(fiatCurrency), errorCode)
|
||||
|
||||
proc updateAirdropFees*(self: View, args: JsonNode) =
|
||||
self.airdropFeesUpdated($args)
|
||||
|
||||
proc deploymentStateChanged*(self: View, communityId: string, status: int, url: string) {.signal.}
|
||||
proc emitDeploymentStateChanged*(self: View, communityId: string, status: int, url: string) =
|
||||
self.deploymentStateChanged(communityId, status, url)
|
||||
|
@ -50,3 +57,7 @@ QtObject:
|
|||
proc remoteDestructStateChanged*(self: View, communityId: string, tokenName: string, status: int, url: string) {.signal.}
|
||||
proc emitRemoteDestructStateChanged*(self: View, communityId: string, tokenName: string, status: int, url: string) =
|
||||
self.remoteDestructStateChanged(communityId, tokenName, status, url)
|
||||
|
||||
proc airdropStateChanged*(self: View, communityId: string, tokenName: string, status: int, url: string) {.signal.}
|
||||
proc emitAirdropStateChanged*(self: View, communityId: string, tokenName: string, status: int, url: string) =
|
||||
self.airdropStateChanged(communityId, tokenName, status, url)
|
|
@ -1,4 +1,4 @@
|
|||
import stint
|
||||
import stint, Tables
|
||||
include ../../common/json_utils
|
||||
import ../../../backend/eth
|
||||
import ../../../backend/community_tokens
|
||||
|
@ -7,16 +7,31 @@ import ../../../app/core/tasks/common
|
|||
import ../../../app/core/tasks/qt
|
||||
import ../transaction/dto
|
||||
|
||||
proc tableToJsonArray[A, B](t: var Table[A, B]): JsonNode =
|
||||
let data = newJArray()
|
||||
for k,v in t:
|
||||
data.elems.add(%*{
|
||||
"key": k,
|
||||
"value": v
|
||||
})
|
||||
return data
|
||||
|
||||
type
|
||||
AsyncGetSuggestedFees = ref object of QObjectTaskArg
|
||||
AsyncGetDeployFeesArg = ref object of QObjectTaskArg
|
||||
chainId: int
|
||||
|
||||
const asyncGetSuggestedFeesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[AsyncGetSuggestedFees](argEncoded)
|
||||
const asyncGetDeployFeesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[AsyncGetDeployFeesArg](argEncoded)
|
||||
try:
|
||||
var gasTable: Table[ContractTuple, int] # gas per contract
|
||||
var feeTable: Table[int, SuggestedFeesDto] # fees for chain
|
||||
let response = eth.suggestedFees(arg.chainId).result
|
||||
feeTable[arg.chainId] = response.toSuggestedFeesDto()
|
||||
let deployGas = community_tokens.deployCollectiblesEstimate().result.getInt
|
||||
gasTable[(arg.chainId, "")] = deployGas
|
||||
arg.finish(%* {
|
||||
"fees": response.toSuggestedFeesDto(),
|
||||
"feeTable": tableToJsonArray(feeTable),
|
||||
"gasTable": tableToJsonArray(gasTable),
|
||||
"error": "",
|
||||
})
|
||||
except Exception as e:
|
||||
|
@ -33,17 +48,53 @@ type
|
|||
const asyncGetBurnFeesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[AsyncGetBurnFees](argEncoded)
|
||||
try:
|
||||
let feesResponse = eth.suggestedFees(arg.chainId).result
|
||||
var gasTable: Table[ContractTuple, int] # gas per contract
|
||||
var feeTable: Table[int, SuggestedFeesDto] # fees for chain
|
||||
let fee = eth.suggestedFees(arg.chainId).result.toSuggestedFeesDto()
|
||||
let burnGas = community_tokens.estimateRemoteBurn(arg.chainId, arg.contractAddress, arg.tokenIds).result.getInt
|
||||
feeTable[arg.chainId] = fee
|
||||
gasTable[(arg.chainId, arg.contractAddress)] = burnGas
|
||||
arg.finish(%* {
|
||||
"fees": feesResponse.toSuggestedFeesDto(),
|
||||
"burnGas": burnGas,
|
||||
"feeTable": tableToJsonArray(feeTable),
|
||||
"gasTable": tableToJsonArray(gasTable),
|
||||
"error": "" })
|
||||
except Exception as e:
|
||||
arg.finish(%* {
|
||||
"error": e.msg,
|
||||
})
|
||||
|
||||
type
|
||||
AsyncGetMintFees = ref object of QObjectTaskArg
|
||||
collectiblesAndAmounts: seq[CommunityTokenAndAmount]
|
||||
walletAddresses: seq[string]
|
||||
|
||||
const asyncGetMintFeesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[AsyncGetMintFees](argEncoded)
|
||||
try:
|
||||
var gasTable: Table[ContractTuple, int] # gas per contract
|
||||
var feeTable: Table[int, SuggestedFeesDto] # fees for chain
|
||||
for collectibleAndAmount in arg.collectiblesAndAmounts:
|
||||
# get fees if we do not have for this chain yet
|
||||
let chainId = collectibleAndAmount.communityToken.chainId
|
||||
if not feeTable.hasKey(chainId):
|
||||
let feesResponse = eth.suggestedFees(chainId).result
|
||||
feeTable[chainId] = feesResponse.toSuggestedFeesDto()
|
||||
|
||||
# get gas for smart contract
|
||||
let gas = community_tokens.estimateMintTo(chainId,
|
||||
collectibleAndAmount.communityToken.address,
|
||||
arg.walletAddresses, collectibleAndAmount.amount).result.getInt
|
||||
gasTable[(chainId, collectibleAndAmount.communityToken.address)] = gas
|
||||
arg.finish(%* {
|
||||
"feeTable": tableToJsonArray(feeTable),
|
||||
"gasTable": tableToJsonArray(gasTable),
|
||||
"error": "" })
|
||||
except Exception as e:
|
||||
let output = %* {
|
||||
"error": e.msg
|
||||
}
|
||||
arg.finish(output)
|
||||
|
||||
type
|
||||
FetchCollectibleOwnersArg = ref object of QObjectTaskArg
|
||||
chainId*: int
|
||||
|
|
|
@ -23,22 +23,41 @@ import ./dto/deployment_parameters
|
|||
import ./dto/community_token
|
||||
import ./dto/community_token_owner
|
||||
|
||||
import airdrop_details
|
||||
|
||||
include async_tasks
|
||||
|
||||
export community_token
|
||||
export deployment_parameters
|
||||
export community_token_owner
|
||||
|
||||
logScope:
|
||||
topics = "community-tokens-service"
|
||||
const ethSymbol = "ETH"
|
||||
|
||||
type
|
||||
CommunityTokenAndAmount* = object
|
||||
communityToken*: CommunityTokenDto
|
||||
amount*: int
|
||||
|
||||
type
|
||||
ContractTuple* = tuple
|
||||
chainId: int
|
||||
address: string
|
||||
|
||||
proc `%`*(self: ContractTuple): JsonNode =
|
||||
result = %* {
|
||||
"address": self.address,
|
||||
"chainId": self.chainId
|
||||
}
|
||||
|
||||
proc toContractTuple*(json: JsonNode): ContractTuple =
|
||||
return (json["chainId"].getInt, json["address"].getStr)
|
||||
|
||||
type
|
||||
ChainWalletTuple* = tuple
|
||||
chainId: int
|
||||
address: string
|
||||
|
||||
include async_tasks
|
||||
|
||||
logScope:
|
||||
topics = "community-tokens-service"
|
||||
|
||||
type
|
||||
WalletAndAmount* = object
|
||||
walletAddress*: string
|
||||
|
@ -69,6 +88,12 @@ type
|
|||
transactionHash*: string
|
||||
status*: ContractTransactionStatus
|
||||
|
||||
type
|
||||
AirdropArgs* = ref object of Args
|
||||
communityToken*: CommunityTokenDto
|
||||
transactionHash*: string
|
||||
status*: ContractTransactionStatus
|
||||
|
||||
type
|
||||
ComputeFeeErrorCode* {.pure.} = enum
|
||||
Success,
|
||||
|
@ -81,11 +106,36 @@ type
|
|||
ethCurrency*: CurrencyAmount
|
||||
fiatCurrency*: CurrencyAmount
|
||||
errorCode*: ComputeFeeErrorCode
|
||||
contractUniqueKey*: string # used for minting
|
||||
|
||||
proc `%`*(self: ComputeFeeArgs): JsonNode =
|
||||
result = %* {
|
||||
"ethFee": self.ethCurrency.toJsonNode(),
|
||||
"fiatFee": self.fiatCurrency.toJsonNode(),
|
||||
"errorCode": self.errorCode.int,
|
||||
"contractUniqueKey": self.contractUniqueKey,
|
||||
}
|
||||
|
||||
proc computeFeeArgsToJsonArray(args: seq[ComputeFeeArgs]): JsonNode =
|
||||
let arr = newJArray()
|
||||
for arg in args:
|
||||
arr.elems.add(%arg)
|
||||
return arr
|
||||
|
||||
type
|
||||
ContractTuple = tuple
|
||||
address: string
|
||||
chainId: int
|
||||
AirdropFeesArgs* = ref object of Args
|
||||
fees*: seq[ComputeFeeArgs]
|
||||
totalEthFee*: CurrencyAmount
|
||||
totalFiatFee*: CurrencyAmount
|
||||
errorCode*: ComputeFeeErrorCode
|
||||
|
||||
proc `%`*(self: AirdropFeesArgs): JsonNode =
|
||||
result = %* {
|
||||
"fees": computeFeeArgsToJsonArray(self.fees),
|
||||
"totalEthFee": self.totalEthFee.toJsonNode(),
|
||||
"totalFiatFee": self.totalFiatFee.toJsonNode(),
|
||||
"errorCode": self.errorCode.int
|
||||
}
|
||||
|
||||
type
|
||||
CommunityTokenOwnersArgs* = ref object of Args
|
||||
|
@ -99,8 +149,10 @@ const SIGNAL_COMMUNITY_TOKEN_DEPLOY_STATUS* = "communityTokenDeployStatus"
|
|||
const SIGNAL_COMMUNITY_TOKEN_DEPLOYED* = "communityTokenDeployed"
|
||||
const SIGNAL_COMPUTE_DEPLOY_FEE* = "computeDeployFee"
|
||||
const SIGNAL_COMPUTE_SELF_DESTRUCT_FEE* = "computeSelfDestructFee"
|
||||
const SIGNAL_COMPUTE_AIRDROP_FEE* = "computeAirdropFee"
|
||||
const SIGNAL_COMMUNITY_TOKEN_OWNERS_FETCHED* = "communityTokenOwnersFetched"
|
||||
const SIGNAL_REMOTE_DESTRUCT_STATUS* = "communityTokenRemoteDestructStatus"
|
||||
const SIGNAL_AIRDROP_STATUS* = "airdropStatus"
|
||||
|
||||
QtObject:
|
||||
type
|
||||
|
@ -117,8 +169,10 @@ QtObject:
|
|||
tokenOwners1SecTimer: QTimer # used to update 1 sec after changes in owners
|
||||
tempTokenOwnersToFetch: CommunityTokenDto # used by 1sec timer
|
||||
tokenOwnersCache: Table[ContractTuple, seq[CollectibleOwner]]
|
||||
tempSuggestedFees: SuggestedFeesDto
|
||||
tempGasUnits: int
|
||||
|
||||
tempFeeTable: Table[int, SuggestedFeesDto] # fees per chain, 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]
|
||||
|
||||
# Forward declaration
|
||||
proc fetchAllTokenOwners*(self: Service)
|
||||
|
@ -173,11 +227,15 @@ QtObject:
|
|||
|
||||
self.events.on(PendingTransactionTypeDto.CollectibleAirdrop.event) do(e: Args):
|
||||
let receivedData = TransactionMinedArgs(e)
|
||||
let airdropDetails = toAirdropDetails(parseJson(receivedData.data))
|
||||
if not receivedData.success:
|
||||
error "Collectible airdrop failed", contractAddress=airdropDetails.contractAddress
|
||||
return
|
||||
#TODO signalize about airdrops - add when extending airdrops
|
||||
let tokenDto = toCommunityTokenDto(parseJson(receivedData.data))
|
||||
let transactionStatus = if receivedData.success: ContractTransactionStatus.Completed else: ContractTransactionStatus.Failed
|
||||
let data = AirdropArgs(communityToken: tokenDto, transactionHash: receivedData.transactionHash, status: transactionStatus)
|
||||
self.events.emit(SIGNAL_AIRDROP_STATUS, data)
|
||||
|
||||
# update owners list if burn was successfull
|
||||
if receivedData.success:
|
||||
self.tempTokenOwnersToFetch = tokenDto
|
||||
self.tokenOwners1SecTimer.start()
|
||||
self.events.on(PendingTransactionTypeDto.CollectibleRemoteSelfDestruct.event) do(e: Args):
|
||||
let receivedData = TransactionMinedArgs(e)
|
||||
let tokenDto = toCommunityTokenDto(parseJson(receivedData.data))
|
||||
|
@ -190,26 +248,23 @@ QtObject:
|
|||
self.tempTokenOwnersToFetch = tokenDto
|
||||
self.tokenOwners1SecTimer.start()
|
||||
|
||||
proc deployCollectiblesEstimate*(self: Service): int =
|
||||
try:
|
||||
let response = tokens_backend.deployCollectiblesEstimate()
|
||||
return response.result.getInt()
|
||||
except RpcException:
|
||||
error "Error getting deploy estimate", message = getCurrentExceptionMsg()
|
||||
|
||||
proc deployCollectibles*(self: Service, communityId: string, addressFrom: string, password: string, deploymentParams: DeploymentParameters, tokenMetadata: CommunityTokensMetadataDto, chainId: int) =
|
||||
try:
|
||||
let suggestedFees = self.transactionService.suggestedFees(chainId)
|
||||
let contractGasUnits = self.deployCollectiblesEstimate()
|
||||
proc buildTransactionDataDto(self: Service, addressFrom: string, chainId: int, contractAddress: string): TransactionDataDto =
|
||||
let gasUnits = self.tempGasTable.getOrDefault((chainId, contractAddress), 0)
|
||||
let suggestedFees = self.tempFeeTable[chainId]
|
||||
if suggestedFees == nil:
|
||||
error "Error deploying collectibles", message = "Can't get suggested fees"
|
||||
error "Can't find suggested fees for chainId", chainId=chainId
|
||||
return
|
||||
|
||||
let txData = ens_utils.buildTransaction(parseAddress(addressFrom), 0.u256, $contractGasUnits,
|
||||
return ens_utils.buildTransaction(parseAddress(addressFrom), 0.u256, $gasUnits,
|
||||
if suggestedFees.eip1559Enabled: "" else: $suggestedFees.gasPrice, suggestedFees.eip1559Enabled,
|
||||
if suggestedFees.eip1559Enabled: $suggestedFees.maxPriorityFeePerGas else: "",
|
||||
if suggestedFees.eip1559Enabled: $suggestedFees.maxFeePerGasM else: "")
|
||||
|
||||
proc deployCollectibles*(self: Service, communityId: string, addressFrom: string, password: string, deploymentParams: DeploymentParameters, tokenMetadata: CommunityTokensMetadataDto, chainId: int) =
|
||||
try:
|
||||
let txData = self.buildTransactionDataDto(addressFrom, chainId, "")
|
||||
if txData.source == parseAddress(ZERO_ADDRESS):
|
||||
return
|
||||
|
||||
let response = tokens_backend.deployCollectibles(chainId, %deploymentParams, %txData, password)
|
||||
let contractAddress = response.result["contractAddress"].getStr()
|
||||
let transactionHash = response.result["transactionHash"].getStr()
|
||||
|
@ -289,16 +344,16 @@ QtObject:
|
|||
try:
|
||||
for collectibleAndAmount in collectiblesAndAmounts:
|
||||
let addressFrom = self.contractOwner(collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address)
|
||||
let txData = TransactionDataDto(source: parseAddress(addressFrom)) #TODO estimate fee in UI
|
||||
let txData = self.buildTransactionDataDto(addressFrom, collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address)
|
||||
if txData.source == parseAddress(ZERO_ADDRESS):
|
||||
return
|
||||
debug "Airdrop collectibles ", chainId=collectibleAndAmount.communityToken.chainId, address=collectibleAndAmount.communityToken.address, amount=collectibleAndAmount.amount
|
||||
let response = tokens_backend.mintTo(collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address, %txData, password, walletAddresses, collectibleAndAmount.amount)
|
||||
let transactionHash = response.result.getStr()
|
||||
debug "Airdrop transaction hash ", transactionHash=transactionHash
|
||||
|
||||
let airdropDetails = AirdropDetails(
|
||||
chainId: collectibleAndAmount.communityToken.chainId,
|
||||
contractAddress: collectibleAndAmount.communityToken.address,
|
||||
walletAddresses: walletAddresses,
|
||||
amount: collectibleAndAmount.amount)
|
||||
var data = AirdropArgs(communityToken: collectibleAndAmount.communityToken, transactionHash: transactionHash, status: ContractTransactionStatus.InProgress)
|
||||
self.events.emit(SIGNAL_AIRDROP_STATUS, data)
|
||||
|
||||
# observe transaction state
|
||||
self.transactionService.watchTransaction(
|
||||
|
@ -306,12 +361,26 @@ QtObject:
|
|||
addressFrom,
|
||||
collectibleAndAmount.communityToken.address,
|
||||
$PendingTransactionTypeDto.CollectibleAirdrop,
|
||||
$airdropDetails.toJsonNode(),
|
||||
$collectibleAndAmount.communityToken.toJsonNode(),
|
||||
collectibleAndAmount.communityToken.chainId,
|
||||
)
|
||||
except RpcException:
|
||||
error "Error airdropping collectibles", message = getCurrentExceptionMsg()
|
||||
|
||||
proc computeAirdropCollectiblesFee*(self: Service, collectiblesAndAmounts: seq[CommunityTokenAndAmount], walletAddresses: seq[string]) =
|
||||
try:
|
||||
self.tempTokensAndAmounts = collectiblesAndAmounts
|
||||
let arg = AsyncGetMintFees(
|
||||
tptr: cast[ByteAddress](asyncGetMintFeesTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "onAirdropFees",
|
||||
collectiblesAndAmounts: collectiblesAndAmounts,
|
||||
walletAddresses: walletAddresses
|
||||
)
|
||||
self.threadpool.start(arg)
|
||||
except Exception as e:
|
||||
error "Error loading airdrop fees", msg = e.msg
|
||||
|
||||
proc getFiatValue*(self: Service, cryptoBalance: float, cryptoSymbol: string): float =
|
||||
if (cryptoSymbol == ""):
|
||||
return 0.0
|
||||
|
@ -323,8 +392,8 @@ QtObject:
|
|||
try:
|
||||
self.tempAccountAddress = accountAddress
|
||||
self.tempChainId = chainId
|
||||
let arg = AsyncGetSuggestedFees(
|
||||
tptr: cast[ByteAddress](asyncGetSuggestedFeesTask),
|
||||
let arg = AsyncGetDeployFeesArg(
|
||||
tptr: cast[ByteAddress](asyncGetDeployFeesTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "onDeployFees",
|
||||
chainId: chainId,
|
||||
|
@ -333,7 +402,7 @@ QtObject:
|
|||
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()
|
||||
for token in allTokens:
|
||||
if common_utils.contractUniqueKey(token.chainId, token.address) == contractUniqueKey:
|
||||
|
@ -366,13 +435,6 @@ QtObject:
|
|||
error "Can't find token ids to burn"
|
||||
return tokenIds
|
||||
|
||||
# TODO use temp fees for deployment also
|
||||
proc buildTransactionFromTempFees(self: Service, addressFrom: string): TransactionDataDto =
|
||||
return ens_utils.buildTransaction(parseAddress(addressFrom), 0.u256, $self.tempGasUnits,
|
||||
if self.tempSuggestedFees.eip1559Enabled: "" else: $self.tempSuggestedFees.gasPrice, self.tempSuggestedFees.eip1559Enabled,
|
||||
if self.tempSuggestedFees.eip1559Enabled: $self.tempSuggestedFees.maxPriorityFeePerGas else: "",
|
||||
if self.tempSuggestedFees.eip1559Enabled: $self.tempSuggestedFees.maxFeePerGasM else: "")
|
||||
|
||||
proc selfDestructCollectibles*(self: Service, communityId: string, password: string, walletAndAmounts: seq[WalletAndAmount], contractUniqueKey: string) =
|
||||
try:
|
||||
let contract = self.findContractByUniqueId(contractUniqueKey)
|
||||
|
@ -380,7 +442,7 @@ QtObject:
|
|||
if len(tokenIds) == 0:
|
||||
return
|
||||
let addressFrom = self.contractOwner(contract.chainId, contract.address)
|
||||
let txData = self.buildTransactionFromTempFees(addressFrom)
|
||||
let txData = self.buildTransactionDataDto(addressFrom, contract.chainId, contract.address)
|
||||
debug "Remote destruct collectibles ", chainId=contract.chainId, address=contract.address, tokens=tokenIds
|
||||
let response = tokens_backend.remoteBurn(contract.chainId, contract.address, %txData, password, tokenIds)
|
||||
let transactionHash = response.result.getStr()
|
||||
|
@ -422,28 +484,39 @@ QtObject:
|
|||
except Exception as e:
|
||||
error "Error loading fees", msg = e.msg
|
||||
|
||||
proc createComputeFeeArgs(self:Service, jsonNode: JsonNode, gasUnits: int, chainId: int, walletAddress: string): ComputeFeeArgs =
|
||||
const ethSymbol = "ETH"
|
||||
if jsonNode{"error"}.kind != JNull and jsonNode{"error"}.getStr != "":
|
||||
let errorMessage = jsonNode["error"].getStr
|
||||
proc create0CurrencyAmounts(self: Service): (CurrencyAmount, CurrencyAmount) =
|
||||
let ethCurrency = newCurrencyAmount(0.0, ethSymbol, 1, false)
|
||||
let fiatCurrency = newCurrencyAmount(0.0, self.settingsService.getCurrency(), 1, false)
|
||||
return (ethCurrency, fiatCurrency)
|
||||
|
||||
proc createCurrencyAmounts(self: Service, ethValue: float64, fiatValue: float64): (CurrencyAmount, CurrencyAmount) =
|
||||
let ethCurrency = newCurrencyAmount(ethValue, ethSymbol, 4, false)
|
||||
let fiatCurrency = newCurrencyAmount(fiatValue, self.settingsService.getCurrency(), 2, false)
|
||||
return (ethCurrency, fiatCurrency)
|
||||
|
||||
proc getErrorCodeFromMessage(self: Service, errorMessage: string): ComputeFeeErrorCode =
|
||||
var errorCode = ComputeFeeErrorCode.Other
|
||||
if errorMessage.contains("403 Forbidden") or errorMessage.contains("exceed"):
|
||||
errorCode = ComputeFeeErrorCode.Infura
|
||||
let ethCurrency = newCurrencyAmount(0.0, ethSymbol, 1, false)
|
||||
let fiatCurrency = newCurrencyAmount(0.0, self.settingsService.getCurrency(), 1, false)
|
||||
return errorCode
|
||||
|
||||
proc createComputeFeeArgsWithError(self:Service, errorMessage: string): ComputeFeeArgs =
|
||||
let errorCode = self.getErrorCodeFromMessage(errorMessage)
|
||||
let (ethCurrency, fiatCurrency) = self.create0CurrencyAmounts()
|
||||
return ComputeFeeArgs(ethCurrency: ethCurrency, fiatCurrency: fiatCurrency, errorCode: errorCode)
|
||||
let suggestedFees = decodeSuggestedFeesDto(jsonNode["fees"])
|
||||
# save suggested fees and use during operation, we always compute fees before operation
|
||||
self.tempSuggestedFees = suggestedFees
|
||||
self.tempGasUnits = gasUnits
|
||||
|
||||
proc computeEthValue(self:Service, gasUnits: int, suggestedFees: SuggestedFeesDto): float =
|
||||
try:
|
||||
let maxFees = suggestedFees.maxFeePerGasM
|
||||
let gasPrice = if suggestedFees.eip1559Enabled: maxFees else: suggestedFees.gasPrice
|
||||
|
||||
let weiValue = gwei2Wei(gasPrice) * gasUnits.u256
|
||||
let ethValueStr = wei2Eth(weiValue)
|
||||
let ethValue = parseFloat(ethValueStr)
|
||||
let fiatValue = self.getFiatValue(ethValue, ethSymbol)
|
||||
return parseFloat(ethValueStr)
|
||||
except Exception as e:
|
||||
error "Error computing eth value", msg = e.msg
|
||||
|
||||
proc getWalletBalanceForChain(self:Service, walletAddress: string, chainId: int): float =
|
||||
let wallet = self.walletAccountService.getAccountByAddress(walletAddress.toLower())
|
||||
var balance = 0.0
|
||||
let tokens = wallet.tokens
|
||||
|
@ -451,23 +524,131 @@ QtObject:
|
|||
if token.symbol == ethSymbol:
|
||||
balance = token.balancesPerChain[chainId].balance
|
||||
break
|
||||
return balance
|
||||
|
||||
let ethCurrency = newCurrencyAmount(ethValue, ethSymbol, 4, false)
|
||||
let fiatCurrency = newCurrencyAmount(fiatValue, self.settingsService.getCurrency(), 2, false)
|
||||
|
||||
proc createComputeFeeArgsFromEthAndBalance(self: Service, ethValue: float, balance: float): ComputeFeeArgs =
|
||||
let fiatValue = self.getFiatValue(ethValue, ethSymbol)
|
||||
let (ethCurrency, fiatCurrency) = self.createCurrencyAmounts(ethValue, fiatValue)
|
||||
return ComputeFeeArgs(ethCurrency: ethCurrency, fiatCurrency: fiatCurrency,
|
||||
errorCode: (if ethValue > balance: ComputeFeeErrorCode.Balance else: ComputeFeeErrorCode.Success))
|
||||
|
||||
proc onSelfDestructFees*(self:Service, response: string) {.slot.} =
|
||||
proc createComputeFeeArgs(self: Service, gasUnits: int, suggestedFees: SuggestedFeesDto, chainId: int, walletAddress: string): ComputeFeeArgs =
|
||||
let ethValue = self.computeEthValue(gasUnits, suggestedFees)
|
||||
let balance = self.getWalletBalanceForChain(walletAddress, chainId)
|
||||
return self.createComputeFeeArgsFromEthAndBalance(ethValue, balance)
|
||||
|
||||
# convert json returned from async task into gas table
|
||||
proc toGasTable(json: JsonNode): Table[ContractTuple, int] =
|
||||
try:
|
||||
if json.kind != JArray:
|
||||
return
|
||||
for i in json:
|
||||
result[i["key"].toContractTuple] = i["value"].getInt
|
||||
except Exception:
|
||||
error "Error converting to gas table", message = getCurrentExceptionMsg()
|
||||
|
||||
# convert json returned from async task into fee table
|
||||
proc toFeeTable(json: JsonNode): Table[int, SuggestedFeesDto] =
|
||||
try:
|
||||
if json.kind != JArray:
|
||||
return
|
||||
for i in json:
|
||||
result[i["key"].getInt] = decodeSuggestedFeesDto(i["value"])
|
||||
except Exception:
|
||||
error "Error converting to fee table", message = getCurrentExceptionMsg()
|
||||
|
||||
proc parseFeeResponseAndEmitSignal(self:Service, response: string, signalName: string) =
|
||||
try:
|
||||
let responseJson = response.parseJson()
|
||||
let burnGas = if responseJson{"burnGas"}.kind != JNull: responseJson{"burnGas"}.getInt else: 0
|
||||
let data = self.createComputeFeeArgs(responseJson, burnGas, self.tempChainId, self.tempAccountAddress)
|
||||
self.events.emit(SIGNAL_COMPUTE_SELF_DESTRUCT_FEE, data)
|
||||
let errorMessage = responseJson{"error"}.getStr
|
||||
if errorMessage != "":
|
||||
let data = self.createComputeFeeArgsWithError(errorMessage)
|
||||
self.events.emit(signalName, data)
|
||||
return
|
||||
let gasTable = responseJson{"gasTable"}.toGasTable
|
||||
let feeTable = responseJson{"feeTable"}.toFeeTable
|
||||
self.tempGasTable = gasTable
|
||||
self.tempFeeTable = feeTable
|
||||
let gasUnits = toSeq(gasTable.values())[0]
|
||||
let suggestedFees = toSeq(feeTable.values())[0]
|
||||
let data = self.createComputeFeeArgs(gasUnits, suggestedFees, self.tempChainId, self.tempAccountAddress)
|
||||
self.events.emit(signalName, data)
|
||||
except Exception:
|
||||
error "Error creating self destruct fee args", message = getCurrentExceptionMsg()
|
||||
let data = self.createComputeFeeArgsWithError(getCurrentExceptionMsg())
|
||||
self.events.emit(signalName, data)
|
||||
|
||||
proc onSelfDestructFees*(self:Service, response: string) {.slot.} =
|
||||
self.parseFeeResponseAndEmitSignal(response, SIGNAL_COMPUTE_SELF_DESTRUCT_FEE)
|
||||
|
||||
proc onDeployFees*(self:Service, response: string) {.slot.} =
|
||||
self.parseFeeResponseAndEmitSignal(response, SIGNAL_COMPUTE_DEPLOY_FEE)
|
||||
|
||||
proc onAirdropFees*(self:Service, response: string) {.slot.} =
|
||||
var wholeEthCostForChainWallet: Table[ChainWalletTuple, float]
|
||||
var ethValuesForContracts: Table[ContractTuple, float]
|
||||
var allComputeFeeArgs: seq[ComputeFeeArgs]
|
||||
var dataToEmit = AirdropFeesArgs()
|
||||
dataToEmit.errorCode = ComputeFeeErrorCode.Success
|
||||
|
||||
try:
|
||||
let responseJson = response.parseJson()
|
||||
let data = self.createComputeFeeArgs(responseJson, self.deployCollectiblesEstimate(), self.tempChainId, self.tempAccountAddress)
|
||||
self.events.emit(SIGNAL_COMPUTE_DEPLOY_FEE, data)
|
||||
let errorMessage = responseJson{"error"}.getStr
|
||||
if errorMessage != "":
|
||||
for collectibleAndAmount in self.tempTokensAndAmounts:
|
||||
let args = self.createComputeFeeArgsWithError(errorMessage)
|
||||
args.contractUniqueKey = common_utils.contractUniqueKey(collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address)
|
||||
dataToEmit.fees.add(args)
|
||||
let (ethTotal, fiatTotal) = self.create0CurrencyAmounts()
|
||||
dataToEmit.totalEthFee = ethTotal
|
||||
dataToEmit.totalFiatFee = fiatTotal
|
||||
dataToEmit.errorCode = self.getErrorCodeFromMessage(errorMessage)
|
||||
self.events.emit(SIGNAL_COMPUTE_AIRDROP_FEE, dataToEmit)
|
||||
return
|
||||
|
||||
let gasTable = responseJson{"gasTable"}.toGasTable
|
||||
let feeTable = responseJson{"feeTable"}.toFeeTable
|
||||
self.tempGasTable = gasTable
|
||||
self.tempFeeTable = feeTable
|
||||
|
||||
# compute eth cost for every contract
|
||||
# also sum all eth costs per (chain, wallet) - it will be needed to compare with (chain, wallet) balance
|
||||
for collectibleAndAmount in self.tempTokensAndAmounts:
|
||||
let gasUnits = self.tempGasTable[(collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address)]
|
||||
let suggestedFees = self.tempFeeTable[collectibleAndAmount.communityToken.chainId]
|
||||
let ethValue = self.computeEthValue(gasUnits, suggestedFees)
|
||||
let walletAddress = self.contractOwner(collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address)
|
||||
wholeEthCostForChainWallet[(collectibleAndAmount.communityToken.chainId, walletAddress)] = wholeEthCostForChainWallet.getOrDefault((collectibleAndAmount.communityToken.chainId, walletAddress), 0.0) + ethValue
|
||||
ethValuesForContracts[(collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address)] = ethValue
|
||||
|
||||
var totalEthVal = 0.0
|
||||
var totalFiatVal = 0.0
|
||||
# for every contract create cost Args
|
||||
for collectibleAndAmount in self.tempTokensAndAmounts:
|
||||
let contractTuple = (chainId: collectibleAndAmount.communityToken.chainId,
|
||||
address: collectibleAndAmount.communityToken.address)
|
||||
let ethValue = ethValuesForContracts[contractTuple]
|
||||
let walletAddress = self.contractOwner(contractTuple.chainId, contractTuple.address)
|
||||
var balance = self.getWalletBalanceForChain(walletAddress, contractTuple.chainId)
|
||||
if balance < wholeEthCostForChainWallet[(contractTuple.chainId, walletAddress)]:
|
||||
# if wallet balance for this chain is less than the whole cost
|
||||
# then we can't afford it; setting balance to 0.0 will set balance error code in Args
|
||||
balance = 0.0
|
||||
dataToEmit.errorCode = ComputeFeeErrorCode.Balance # set total error code to balance error
|
||||
var args = self.createComputeFeeArgsFromEthAndBalance(ethValue, balance)
|
||||
totalEthVal = totalEthVal + ethValue
|
||||
totalFiatVal = totalFiatVal + args.fiatCurrency.getAmountFloat()
|
||||
args.contractUniqueKey = common_utils.contractUniqueKey(collectibleAndAmount.communityToken.chainId, collectibleAndAmount.communityToken.address)
|
||||
allComputeFeeArgs.add(args)
|
||||
|
||||
dataToEmit.fees = allComputeFeeArgs
|
||||
let (ethTotal, fiatTotal) = self.createCurrencyAmounts(totalEthVal, totalFiatVal)
|
||||
dataToEmit.totalEthFee = ethTotal
|
||||
dataToEmit.totalFiatFee = fiatTotal
|
||||
self.events.emit(SIGNAL_COMPUTE_AIRDROP_FEE, dataToEmit)
|
||||
|
||||
except Exception as e:
|
||||
error "Error computing airdrop fees", msg = e.msg
|
||||
|
||||
proc fetchCommunityOwners*(self: Service, communityId: string, chainId: int, contractAddress: string) =
|
||||
let arg = FetchCollectibleOwnersArg(
|
||||
|
@ -482,7 +663,7 @@ QtObject:
|
|||
|
||||
# get owners from cache
|
||||
proc getCommunityTokenOwners*(self: Service, communityId: string, chainId: int, contractAddress: string): seq[CollectibleOwner] =
|
||||
return self.tokenOwnersCache.getOrDefault((address: contractAddress, chainId: chainId))
|
||||
return self.tokenOwnersCache.getOrDefault((chainId: chainId, address: contractAddress))
|
||||
|
||||
proc onCommunityTokenOwnersFetched*(self:Service, response: string) {.slot.} =
|
||||
let responseJson = response.parseJson()
|
||||
|
@ -496,7 +677,7 @@ QtObject:
|
|||
let resultJson = responseJson["result"]
|
||||
var owners = collectibles_dto.toCollectibleOwnershipDto(resultJson).owners
|
||||
owners = owners.filter(x => x.address != ZERO_ADDRESS)
|
||||
self.tokenOwnersCache[(contractAddress, chainId)] = owners
|
||||
self.tokenOwnersCache[(chainId, contractAddress)] = owners
|
||||
let data = CommunityTokenOwnersArgs(chainId: chainId, contractAddress: contractAddress, communityId: communityId, owners: owners)
|
||||
self.events.emit(SIGNAL_COMMUNITY_TOKEN_OWNERS_FETCHED, data)
|
||||
|
||||
|
|
|
@ -30,6 +30,10 @@ proc mintTo*(chainId: int, contractAddress: string, txData: JsonNode, password:
|
|||
let payload = %* [chainId, contractAddress, txData, utils.hashPassword(password), walletAddresses, amount]
|
||||
return core.callPrivateRPC("collectibles_mintTo", payload)
|
||||
|
||||
proc estimateMintTo*(chainId: int, contractAddress: string, walletAddresses: seq[string], amount: int): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [chainId, contractAddress, walletAddresses, amount]
|
||||
return core.callPrivateRPC("collectibles_estimateMintTo", payload)
|
||||
|
||||
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))]
|
||||
return core.callPrivateRPC("collectibles_remoteBurn", payload)
|
||||
|
|
|
@ -79,7 +79,8 @@ StatusScrollView {
|
|||
networkText: modelItem.chainName,
|
||||
networkImage: Style.svg(modelItem.chainIcon),
|
||||
supply: modelItem.supply,
|
||||
infiniteSupply: modelItem.infiniteSupply
|
||||
infiniteSupply: modelItem.infiniteSupply,
|
||||
contractUniqueKey: modelItem.contractUniqueKey,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -402,7 +403,7 @@ StatusScrollView {
|
|||
onClicked: {
|
||||
const airdropTokens = ModelUtils.modelToArray(
|
||||
root.selectedHoldingsModel,
|
||||
["key", "amount"])
|
||||
["contractUniqueKey", "amount"])
|
||||
|
||||
const addresses_ = ModelUtils.modelToArray(
|
||||
addresses, ["address"]).map(e => e.address)
|
||||
|
|
|
@ -58,6 +58,10 @@ QtObject {
|
|||
function onSelfDestructFeeUpdated(ethCurrency, fiatCurrency, errorCode) {
|
||||
root.selfDestructFeeUpdated(ethCurrency, fiatCurrency, errorCode)
|
||||
}
|
||||
function onAirdropFeesUpdated(jsonFees) {
|
||||
console.log("Fees:", jsonFees)
|
||||
}
|
||||
|
||||
function onDeploymentStateChanged(communityId, status, url) {
|
||||
root.deploymentStateChanged(communityId, status, url)
|
||||
}
|
||||
|
@ -94,4 +98,8 @@ QtObject {
|
|||
function airdrop(communityId, airdropTokens, addresses) {
|
||||
communityTokensModuleInst.airdropCollectibles(communityId, JSON.stringify(airdropTokens), JSON.stringify(addresses))
|
||||
}
|
||||
|
||||
function computeAirdropFee(communityId, airdropTokens, addresses) {
|
||||
communityTokensModuleInst.computeAirdropCollectiblesFee(communityId, JSON.stringify(airdropTokens), JSON.stringify(addresses))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue