import # global deps atomics, sequtils, strutils, tables import # project deps chronicles, web3/[ethtypes, conversions], stint import # local deps eth/contracts as status_contracts, libstatus/stickers as status_stickers, transactions, libstatus/wallet, ../eventemitter import ./types/[sticker, transaction, rpc_response] from utils as libstatus_utils import eth2Wei, gwei2Wei, toUInt64, parseAddress logScope: topics = "stickers-model" type StickersModel* = ref object events*: EventEmitter recentStickers*: seq[Sticker] availableStickerPacks*: Table[int, StickerPack] installedStickerPacks*: Table[int, StickerPack] purchasedStickerPacks*: seq[int] StickerArgs* = ref object of Args sticker*: Sticker save*: bool # forward declaration proc addStickerToRecent*(self: StickersModel, sticker: Sticker, save: bool = false) proc newStickersModel*(events: EventEmitter): StickersModel = result = StickersModel() result.events = events result.recentStickers = @[] result.availableStickerPacks = initTable[int, StickerPack]() result.installedStickerPacks = initTable[int, StickerPack]() result.purchasedStickerPacks = @[] proc init*(self: StickersModel) = self.events.on("stickerSent") do(e: Args): var evArgs = StickerArgs(e) self.addStickerToRecent(evArgs.sticker, evArgs.save) proc buildTransaction(packId: Uint256, address: Address, price: Uint256, approveAndCall: var ApproveAndCall[100], sntContract: var Erc20Contract, gas = "", gasPrice = "", isEIP1559Enabled = false, maxPriorityFeePerGas = "", maxFeePerGas = ""): TransactionData = sntContract = status_contracts.getSntContract() let stickerMktContract = status_contracts.getContract("sticker-market") buyToken = BuyToken(packId: packId, address: address, price: price) buyTxAbiEncoded = stickerMktContract.methods["buyToken"].encodeAbi(buyToken) approveAndCall = ApproveAndCall[100](to: stickerMktContract.address, value: price, data: DynamicBytes[100].fromHex(buyTxAbiEncoded)) transactions.buildTokenTransaction(address, sntContract.address, gas, gasPrice, isEIP1559Enabled, maxPriorityFeePerGas, maxFeePerGas) proc estimateGas*(packId: int, address: string, price: string, success: var bool): int = var approveAndCall: ApproveAndCall[100] sntContract = status_contracts.getSntContract() tx = buildTransaction( packId.u256, parseAddress(address), eth2Wei(parseFloat(price), sntContract.decimals), approveAndCall, sntContract ) let response = sntContract.methods["approveAndCall"].estimateGas(tx, approveAndCall, success) if success: result = fromHex[int](response) proc buyPack*(self: StickersModel, packId: int, address, price, gas, gasPrice: string, isEIP1559Enabled: bool, maxPriorityFeePerGas: string, maxFeePerGas: string, password: string, success: var bool): string = var sntContract: Erc20Contract approveAndCall: ApproveAndCall[100] tx = buildTransaction( packId.u256, parseAddress(address), eth2Wei(parseFloat(price), 18), # SNT approveAndCall, sntContract, gas, gasPrice, isEIP1559Enabled, maxPriorityFeePerGas, maxFeePerGas ) result = sntContract.methods["approveAndCall"].send(tx, approveAndCall, password, success) if success: trackPendingTransaction(result, address, $sntContract.address, PendingTransactionType.BuyStickerPack, $packId) proc getStickerMarketAddress*(self: StickersModel): Address = result = status_contracts.getContract("sticker-market").address proc getPurchasedStickerPacks*(self: StickersModel, address: Address): seq[int] = try: let balance = status_stickers.getBalance(address) tokenIds = toSeq[0.. 24: self.recentStickers = self.recentStickers[0..23] # take top 24 most recent if save: status_stickers.saveRecentStickers(self.recentStickers) proc decodeContentHash*(value: string): string = result = status_stickers.decodeContentHash(value) proc getPackIdFromTokenId*(tokenId: Stuint[256]): int = result = status_stickers.getPackIdFromTokenId(tokenId)