mirror of
https://github.com/status-im/status-desktop.git
synced 2025-02-21 19:18:53 +00:00
feat(@desktop/wallet): integrate new onramp status-go api
This commit is contained in:
parent
b8ffa65113
commit
2688d48d65
@ -12,6 +12,7 @@ import app_service/service/message/service as message_service
|
||||
import app_service/service/token/service as token_service
|
||||
import app_service/service/collectible/service as collectible_service
|
||||
import app_service/service/currency/service as currency_service
|
||||
import app_service/service/ramp/service as ramp_service
|
||||
import app_service/service/transaction/service as transaction_service
|
||||
import app_service/service/wallet_account/service as wallet_account_service
|
||||
import app_service/service/privacy/service as privacy_service
|
||||
@ -77,6 +78,7 @@ type
|
||||
tokenService: token_service.Service
|
||||
collectibleService: collectible_service.Service
|
||||
currencyService: currency_service.Service
|
||||
rampService: ramp_service.Service
|
||||
transactionService: transaction_service.Service
|
||||
walletAccountService: wallet_account_service.Service
|
||||
providerService: provider_service.Service
|
||||
@ -199,6 +201,7 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
||||
)
|
||||
result.communityService = community_service.newService(statusFoundation.events,
|
||||
statusFoundation.threadpool, result.chatService, result.activityCenterService, result.messageService)
|
||||
result.rampService = ramp_service.newService(statusFoundation.events, statusFoundation.threadpool)
|
||||
result.transactionService = transaction_service.newService(statusFoundation.events, statusFoundation.threadpool, result.networkService, result.settingsService, result.tokenService)
|
||||
result.profileService = profile_service.newService(statusFoundation.events, statusFoundation.threadpool, result.settingsService)
|
||||
result.stickersService = stickers_service.newService(
|
||||
@ -257,6 +260,7 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
||||
result.tokenService,
|
||||
result.collectibleService,
|
||||
result.currencyService,
|
||||
result.rampService,
|
||||
result.transactionService,
|
||||
result.walletAccountService,
|
||||
result.profileService,
|
||||
@ -317,6 +321,7 @@ proc delete*(self: AppController) =
|
||||
self.currencyService.delete
|
||||
self.collectibleService.delete
|
||||
self.tokenService.delete
|
||||
self.rampService.delete
|
||||
self.transactionService.delete
|
||||
self.walletAccountService.delete
|
||||
self.aboutService.delete
|
||||
@ -422,6 +427,7 @@ proc load(self: AppController) =
|
||||
self.messageService.init()
|
||||
self.communityService.init()
|
||||
self.providerService.init()
|
||||
self.rampService.init()
|
||||
self.transactionService.init()
|
||||
self.stickersService.init()
|
||||
self.activityCenterService.init()
|
||||
|
@ -38,6 +38,7 @@ import ../../../app_service/service/message/service as message_service
|
||||
import ../../../app_service/service/token/service as token_service
|
||||
import ../../../app_service/service/collectible/service as collectible_service
|
||||
import ../../../app_service/service/currency/service as currency_service
|
||||
import ../../../app_service/service/ramp/service as ramp_service
|
||||
import ../../../app_service/service/transaction/service as transaction_service
|
||||
import ../../../app_service/service/wallet_account/service as wallet_account_service
|
||||
import ../../../app_service/service/provider/service as provider_service
|
||||
@ -140,6 +141,7 @@ proc newModule*[T](
|
||||
tokenService: token_service.Service,
|
||||
collectibleService: collectible_service.Service,
|
||||
currencyService: currency_service.Service,
|
||||
rampService: ramp_service.Service,
|
||||
transactionService: transaction_service.Service,
|
||||
walletAccountService: wallet_account_service.Service,
|
||||
profileService: profile_service.Service,
|
||||
@ -208,7 +210,7 @@ proc newModule*[T](
|
||||
result.chatSectionModules = initOrderedTable[string, chat_section_module.AccessInterface]()
|
||||
result.walletSectionModule = wallet_section_module.newModule(
|
||||
result, events, tokenService, collectibleService, currencyService,
|
||||
transactionService, walletAccountService,
|
||||
rampService, transactionService, walletAccountService,
|
||||
settingsService, savedAddressService, networkService, accountsService,
|
||||
keycardService, nodeService, networkConnectionService, devicesService,
|
||||
communityTokensService, threadpool
|
||||
|
@ -1,31 +1,39 @@
|
||||
import io_interface
|
||||
|
||||
import ../../../../../app_service/service/transaction/service as transaction_service
|
||||
import app_service/service/ramp/service as ramp_service
|
||||
import app_service/service/ramp/dto
|
||||
import ../../../../core/eventemitter
|
||||
|
||||
type
|
||||
Controller* = ref object of RootObj
|
||||
delegate: io_interface.AccessInterface
|
||||
transactionService: transaction_service.Service
|
||||
rampService: ramp_service.Service
|
||||
events: EventEmitter
|
||||
|
||||
proc newController*(
|
||||
delegate: io_interface.AccessInterface,
|
||||
events: EventEmitter,
|
||||
transactionService: transaction_service.Service
|
||||
rampService: ramp_service.Service
|
||||
): Controller =
|
||||
result = Controller()
|
||||
result.delegate = delegate
|
||||
result.events = events
|
||||
result.transactionService = transactionService
|
||||
result.rampService = rampService
|
||||
|
||||
proc delete*(self: Controller) =
|
||||
discard
|
||||
|
||||
proc init*(self: Controller) =
|
||||
self.events.on(SIGNAL_CRYPTO_SERVICES_READY) do(e:Args):
|
||||
let args = CryptoServicesArgs(e)
|
||||
self.delegate.updateCryptoServices(args.data)
|
||||
self.events.on(SIGNAL_CRYPTO_RAMP_PROVIDERS_READY) do(e:Args):
|
||||
let args = CryptoRampProvidersArgs(e)
|
||||
self.delegate.updateRampProviders(args.data)
|
||||
|
||||
proc fetchCryptoServices*(self: Controller) =
|
||||
self.transactionService.fetchCryptoServices()
|
||||
self.events.on(SIGNAL_CRYPTO_RAMP_URL_READY) do(e:Args):
|
||||
let args = CryptoRampUrlArgs(e)
|
||||
self.delegate.onRampProviderUrlReady(args.uuid, args.url)
|
||||
|
||||
proc fetchCryptoRampProviders*(self: Controller) =
|
||||
self.rampService.fetchCryptoRampProviders()
|
||||
|
||||
proc fetchCryptoRampUrl*(self: Controller, uuid: string, providerID: string, parameters: CryptoRampParametersDto) =
|
||||
self.rampService.fetchCryptoRampUrl(uuid, providerID, parameters)
|
||||
|
@ -1,4 +1,4 @@
|
||||
import ../../../../../app_service/service/transaction/cryptoRampDto
|
||||
import app_service/service/ramp/dto
|
||||
|
||||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
@ -13,7 +13,16 @@ method load*(self: AccessInterface) {.base.} =
|
||||
method isLoaded*(self: AccessInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method updateCryptoServices*(self: AccessInterface, cryptoServices: seq[CryptoRampDto]) {.base.} =
|
||||
method fetchProviders*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method fetchProviderUrl*(self: AccessInterface, uuid: string, providerID: string, parameters: CryptoRampParametersDto) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method updateRampProviders*(self: AccessInterface, cryptoServices: seq[CryptoRampDto]) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onRampProviderUrlReady*(self: AccessInterface, uuid: string, url: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
# View Delegate Interface
|
||||
|
@ -1,35 +1,60 @@
|
||||
import stew/shims/strformat
|
||||
|
||||
import app/modules/shared_models/contract_model as contract_model
|
||||
import app/modules/shared_models/contract_item as contract_item
|
||||
|
||||
type Item* = object
|
||||
id: string
|
||||
name: string
|
||||
description: string
|
||||
fees: string
|
||||
logoUrl: string
|
||||
siteUrl: string
|
||||
logoUrl: string
|
||||
hostname: string
|
||||
recurrentSiteUrl: string
|
||||
supportsSinglePurchase: bool
|
||||
supportsRecurrentPurchase: bool
|
||||
supportedAssets: contract_model.Model
|
||||
urlsNeedParameters: bool
|
||||
|
||||
proc initItem*(name, description, fees, logoUrl, siteUrl,
|
||||
hostname, recurrentSiteUrl,: string): Item =
|
||||
proc initItem*(
|
||||
id: string,
|
||||
name: string,
|
||||
description: string,
|
||||
fees: string,
|
||||
logoUrl: string,
|
||||
hostname: string,
|
||||
supportsSinglePurchase: bool,
|
||||
supportsRecurrentPurchase: bool,
|
||||
supportedAssets: seq[contract_item.Item],
|
||||
urlsNeedParameters: bool): Item =
|
||||
result.id = id
|
||||
result.name = name
|
||||
result.description = description
|
||||
result.fees = fees
|
||||
result.logoUrl = logoUrl
|
||||
result.siteUrl = siteUrl
|
||||
result.hostname = hostname
|
||||
result.recurrentSiteUrl = recurrentSiteUrl
|
||||
result.supportsSinglePurchase = supportsSinglePurchase
|
||||
result.supportsRecurrentPurchase = supportsRecurrentPurchase
|
||||
result.supportedAssets = contract_model.newModel()
|
||||
result.supportedAssets.setItems(supportedAssets)
|
||||
result.urlsNeedParameters = urlsNeedParameters
|
||||
|
||||
proc `$`*(self: Item): string =
|
||||
result = "Item("
|
||||
result &= fmt"id:{self.id}, "
|
||||
result &= fmt"name:{self.name}, "
|
||||
result &= fmt"description:{self.description}, "
|
||||
result &= fmt"fees:{self.fees}, "
|
||||
result &= fmt"logoUrl:{self.logoUrl}, "
|
||||
result &= fmt"siteUrl:{self.siteUrl}"
|
||||
result &= fmt"hostname:{self.hostname}"
|
||||
result &= fmt"recurrentSiteUrl:{self.recurrentSiteUrl}"
|
||||
result &= fmt"hostname:{self.hostname}, "
|
||||
result &= fmt"supportsSinglePurchase:{self.supportsSinglePurchase}, "
|
||||
result &= fmt"supportsRecurrentPurchase:{self.supportsRecurrentPurchase}, "
|
||||
result &= fmt"supportedAssets:{self.supportedAssets}, "
|
||||
result &= fmt"urlsNeedParameters:{self.urlsNeedParameters}, "
|
||||
result &= ")"
|
||||
|
||||
method getId*(self: Item): string {.base.} =
|
||||
return self.id
|
||||
|
||||
method getName*(self: Item): string {.base.} =
|
||||
return self.name
|
||||
|
||||
@ -42,11 +67,17 @@ method getFees*(self: Item): string {.base.} =
|
||||
method getLogoUrl*(self: Item): string {.base.} =
|
||||
return self.logoUrl
|
||||
|
||||
method getSiteUrl*(self: Item): string {.base.} =
|
||||
return self.siteUrl
|
||||
|
||||
method getHostname*(self: Item): string {.base.} =
|
||||
return self.hostname
|
||||
|
||||
method getRecurrentSiteUrl*(self: Item): string {.base.} =
|
||||
return self.recurrentSiteUrl
|
||||
method getSupportsSinglePurchase*(self: Item): bool {.base.} =
|
||||
return self.supportsSinglePurchase
|
||||
|
||||
method getSupportsRecurrentPurchase*(self: Item): bool {.base.} =
|
||||
return self.supportsRecurrentPurchase
|
||||
|
||||
method getSupportedAssets*(self: Item): contract_model.Model {.base.} =
|
||||
return self.supportedAssets
|
||||
|
||||
method getUrlsNeedParameters*(self: Item): bool {.base.} =
|
||||
return self.urlsNeedParameters
|
@ -4,13 +4,16 @@ import item
|
||||
|
||||
type
|
||||
ModelRole {.pure.} = enum
|
||||
Name = UserRole + 1
|
||||
Id = UserRole + 1
|
||||
Name
|
||||
Description
|
||||
Fees
|
||||
LogoUrl
|
||||
SiteUrl
|
||||
Hostname
|
||||
RecurrentSiteUrl
|
||||
SupportsSinglePurchase
|
||||
SupportsRecurrentPurchase
|
||||
SupportedAssets
|
||||
UrlsNeedParameters
|
||||
|
||||
QtObject:
|
||||
type
|
||||
@ -32,13 +35,16 @@ QtObject:
|
||||
|
||||
method roleNames(self: Model): Table[int, string] =
|
||||
{
|
||||
ModelRole.Id.int:"id",
|
||||
ModelRole.Name.int:"name",
|
||||
ModelRole.Description.int:"description",
|
||||
ModelRole.Fees.int:"fees",
|
||||
ModelRole.LogoUrl.int:"logoUrl",
|
||||
ModelRole.SiteUrl.int:"siteUrl",
|
||||
ModelRole.Hostname.int:"hostname",
|
||||
ModelRole.RecurrentSiteUrl.int:"recurrentSiteUrl"
|
||||
ModelRole.SupportsSinglePurchase.int:"supportsSinglePurchase",
|
||||
ModelRole.SupportsRecurrentPurchase.int:"supportsRecurrentPurchase",
|
||||
ModelRole.SupportedAssets.int:"supportedAssets",
|
||||
ModelRole.UrlsNeedParameters.int:"urlsNeedParameters"
|
||||
}.toTable
|
||||
|
||||
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||
@ -52,6 +58,8 @@ QtObject:
|
||||
let enumRole = role.ModelRole
|
||||
|
||||
case enumRole:
|
||||
of ModelRole.Id:
|
||||
result = newQVariant(item.getId)
|
||||
of ModelRole.Name:
|
||||
result = newQVariant(item.getName)
|
||||
of ModelRole.Description:
|
||||
@ -60,12 +68,16 @@ QtObject:
|
||||
result = newQVariant(item.getFees)
|
||||
of ModelRole.LogoUrl:
|
||||
result = newQVariant(item.getLogoUrl)
|
||||
of ModelRole.SiteUrl:
|
||||
result = newQVariant(item.getSiteUrl)
|
||||
of ModelRole.Hostname:
|
||||
result = newQVariant(item.getHostname)
|
||||
of ModelRole.RecurrentSiteUrl:
|
||||
result = newQVariant(item.getRecurrentSiteUrl)
|
||||
of ModelRole.SupportsSinglePurchase:
|
||||
result = newQVariant(item.getSupportsSinglePurchase)
|
||||
of ModelRole.SupportsRecurrentPurchase:
|
||||
result = newQVariant(item.getSupportsRecurrentPurchase)
|
||||
of ModelRole.SupportedAssets:
|
||||
result = newQVariant(item.getSupportedAssets)
|
||||
of ModelRole.UrlsNeedParameters:
|
||||
result = newQVariant(item.getUrlsNeedParameters)
|
||||
|
||||
proc setItems*(self: Model, items: seq[Item]) =
|
||||
self.beginResetModel()
|
||||
|
@ -1,11 +1,11 @@
|
||||
import NimQml, sequtils
|
||||
import NimQml, sequtils, sugar
|
||||
|
||||
import ./io_interface, ./view, ./item, ./controller
|
||||
import ./io_interface, ./view, ./controller, ./utils
|
||||
import ../io_interface as delegate_interface
|
||||
import ../../../../global/global_singleton
|
||||
import ../../../../core/eventemitter
|
||||
import ../../../../../app_service/service/transaction/service as transaction_service
|
||||
import ../../../../../app_service/service/transaction/cryptoRampDto
|
||||
import app_service/service/ramp/service as ramp_service
|
||||
import app_service/service/ramp/dto
|
||||
|
||||
export io_interface
|
||||
|
||||
@ -21,14 +21,14 @@ type
|
||||
proc newModule*(
|
||||
delegate: delegate_interface.AccessInterface,
|
||||
events: EventEmitter,
|
||||
transactionService: transaction_service.Service,
|
||||
rampService: ramp_service.Service,
|
||||
): Module =
|
||||
result = Module()
|
||||
result.delegate = delegate
|
||||
result.events = events
|
||||
result.view = newView(result)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.controller = controller.newController(result, events, transactionService)
|
||||
result.controller = controller.newController(result, events, rampService)
|
||||
result.moduleLoaded = false
|
||||
|
||||
method delete*(self: Module) =
|
||||
@ -36,21 +36,23 @@ method delete*(self: Module) =
|
||||
self.view.delete
|
||||
self.controller.delete
|
||||
|
||||
method updateCryptoServices*(self: Module, cryptoServices: seq[CryptoRampDto]) =
|
||||
let items = cryptoServices.map(proc (w: CryptoRampDto): item.Item = result = initItem(
|
||||
w.name,
|
||||
w.description,
|
||||
w.fees,
|
||||
w.logoUrl,
|
||||
w.siteUrl,
|
||||
w.hostname,
|
||||
w.recurrentSiteUrl,
|
||||
))
|
||||
method fetchProviders*(self: Module) =
|
||||
self.controller.fetchCryptoRampProviders()
|
||||
self.view.setIsFetching(true)
|
||||
|
||||
method fetchProviderUrl*(self: Module, uuid: string, providerID: string, parameters: CryptoRampParametersDto) =
|
||||
self.controller.fetchCryptoRampUrl(uuid, providerID, parameters)
|
||||
|
||||
method updateRampProviders*(self: Module, cryptoServices: seq[CryptoRampDto]) =
|
||||
let items = cryptoServices.map(i => i.dtoToItem())
|
||||
self.view.setItems(items)
|
||||
self.view.setIsFetching(false)
|
||||
|
||||
method onRampProviderUrlReady*(self: Module, uuid: string, url: string) =
|
||||
self.view.onProviderUrlReady(uuid, url)
|
||||
|
||||
method load*(self: Module) =
|
||||
singletonInstance.engine.setRootContextProperty("walletSectionBuySellCrypto", self.viewVariant)
|
||||
self.controller.fetchCryptoServices()
|
||||
self.controller.init()
|
||||
self.view.load()
|
||||
|
||||
|
@ -0,0 +1,21 @@
|
||||
import sugar, sequtils
|
||||
|
||||
import ./item
|
||||
import app_service/service/ramp/dto
|
||||
import app/modules/shared_models/contract_item as contract_item
|
||||
|
||||
proc dtoToItem*(dto: CryptoRampDto): item.Item =
|
||||
let supportedAssets = dto.supportedTokens.map(t => contract_item.initItem(t.chainID, t.address))
|
||||
|
||||
return initItem(
|
||||
dto.id,
|
||||
dto.name,
|
||||
dto.description,
|
||||
dto.fees,
|
||||
dto.logoUrl,
|
||||
dto.hostname,
|
||||
dto.supportsSinglePurchase,
|
||||
dto.supportsRecurrentPurchase,
|
||||
supportedAssets,
|
||||
dto.urlsNeedParameters
|
||||
)
|
@ -1,15 +1,19 @@
|
||||
import NimQml
|
||||
import options
|
||||
|
||||
import ./model
|
||||
import ./item
|
||||
import ./io_interface
|
||||
|
||||
import app_service/service/ramp/dto
|
||||
|
||||
QtObject:
|
||||
type
|
||||
View* = ref object of QObject
|
||||
delegate: io_interface.AccessInterface
|
||||
model: Model
|
||||
modelVariant: QVariant
|
||||
isFetching: bool
|
||||
|
||||
proc delete*(self: View) =
|
||||
self.model.delete
|
||||
@ -22,6 +26,7 @@ QtObject:
|
||||
result.delegate = delegate
|
||||
result.model = newModel()
|
||||
result.modelVariant = newQVariant(result.model)
|
||||
result.isFetching = false
|
||||
|
||||
proc load*(self: View) =
|
||||
self.delegate.viewDidLoad()
|
||||
@ -35,6 +40,49 @@ QtObject:
|
||||
read = getModel
|
||||
notify = modelChanged
|
||||
|
||||
proc isFetchingChanged*(self: View) {.signal.}
|
||||
|
||||
proc getIsFetching*(self: View): bool {.slot.} =
|
||||
return self.isFetching
|
||||
|
||||
QtProperty[bool] isFetching:
|
||||
read = getIsFetching
|
||||
notify = isFetchingChanged
|
||||
|
||||
proc setIsFetching*(self: View, value: bool) =
|
||||
if self.isFetching == value:
|
||||
return
|
||||
self.isFetching = value
|
||||
self.isFetchingChanged()
|
||||
|
||||
proc setItems*(self: View, items: seq[Item]) =
|
||||
self.model.setItems(items)
|
||||
self.modelChanged()
|
||||
|
||||
proc fetchProviders*(self: View) {.slot.} =
|
||||
self.delegate.fetchProviders()
|
||||
|
||||
proc fetchProviderUrl*(self: View,
|
||||
uuid: string,
|
||||
providerID: string,
|
||||
isRecurrent: bool,
|
||||
destinationAccountAddress: string,
|
||||
chainID: int,
|
||||
symbol: string) {.slot.} =
|
||||
let parameters = CryptoRampParametersDto(
|
||||
isRecurrent: isRecurrent,
|
||||
)
|
||||
|
||||
if destinationAccountAddress.len > 0:
|
||||
parameters.destinationAddress = some(destinationAccountAddress)
|
||||
if chainID > 0:
|
||||
parameters.chainID = some(chainID)
|
||||
if symbol.len > 0:
|
||||
parameters.symbol = some(symbol)
|
||||
|
||||
self.delegate.fetchProviderUrl(uuid, providerID, parameters)
|
||||
|
||||
proc providerUrlReady*(self: View, uuid: string, url: string) {.signal.}
|
||||
|
||||
proc onProviderUrlReady*(self: View, uuid: string, url: string) =
|
||||
self.providerUrlReady(uuid, url)
|
||||
|
@ -29,6 +29,7 @@ import app_service/service/keycard/service as keycard_service
|
||||
import app_service/service/token/service as token_service
|
||||
import app_service/service/collectible/service as collectible_service
|
||||
import app_service/service/currency/service as currency_service
|
||||
import app_service/service/ramp/service as ramp_service
|
||||
import app_service/service/transaction/service as transaction_service
|
||||
import app_service/service/wallet_account/service as wallet_account_service
|
||||
import app_service/service/settings/service as settings_service
|
||||
@ -75,6 +76,7 @@ type
|
||||
overviewModule: overview_module.AccessInterface
|
||||
networksModule: networks_module.AccessInterface
|
||||
networksService: network_service.Service
|
||||
rampService: ramp_service.Service
|
||||
transactionService: transaction_service.Service
|
||||
keycardService: keycard_service.Service
|
||||
accountsService: accounts_service.Service
|
||||
@ -107,6 +109,7 @@ proc newModule*(
|
||||
tokenService: token_service.Service,
|
||||
collectibleService: collectible_service.Service,
|
||||
currencyService: currency_service.Service,
|
||||
rampService: ramp_service.Service,
|
||||
transactionService: transaction_service.Service,
|
||||
walletAccountService: wallet_account_service.Service,
|
||||
settingsService: settings_service.Service,
|
||||
@ -141,7 +144,7 @@ proc newModule*(
|
||||
result.sendModule = send_module.newModule(result, events, walletAccountService, networkService, currencyService,
|
||||
transactionService, keycardService)
|
||||
result.savedAddressesModule = saved_addresses_module.newModule(result, events, savedAddressService)
|
||||
result.buySellCryptoModule = buy_sell_crypto_module.newModule(result, events, transactionService)
|
||||
result.buySellCryptoModule = buy_sell_crypto_module.newModule(result, events, rampService)
|
||||
result.overviewModule = overview_module.newModule(result, events, walletAccountService, currencyService)
|
||||
result.networksModule = networks_module.newModule(result, events, networkService, walletAccountService, settingsService)
|
||||
result.networksService = networkService
|
||||
|
28
src/app/modules/shared_models/contract_item.nim
Normal file
28
src/app/modules/shared_models/contract_item.nim
Normal file
@ -0,0 +1,28 @@
|
||||
import stew/shims/strformat
|
||||
|
||||
type Item* = ref object
|
||||
key: string
|
||||
chainId: int
|
||||
address: string
|
||||
|
||||
proc initItem*(chainID: int, address: string): Item =
|
||||
result = Item()
|
||||
result.key = $chainID & address
|
||||
result.chainID = chainID
|
||||
result.address = address
|
||||
|
||||
proc `$`*(self: Item): string =
|
||||
result = fmt"""ContractItem(
|
||||
key: {self.key},
|
||||
chainId: {$self.chainId},
|
||||
address: {self.address},
|
||||
]"""
|
||||
|
||||
proc key*(self: Item): string {.inline.} =
|
||||
self.key
|
||||
|
||||
proc chainId*(self: Item): int {.inline.} =
|
||||
self.chainId
|
||||
|
||||
proc address*(self: Item): string {.inline.} =
|
||||
self.address
|
59
src/app/modules/shared_models/contract_model.nim
Normal file
59
src/app/modules/shared_models/contract_model.nim
Normal file
@ -0,0 +1,59 @@
|
||||
import NimQml, Tables, strutils, stew/shims/strformat
|
||||
|
||||
import ./contract_item
|
||||
|
||||
type
|
||||
ModelRole {.pure.} = enum
|
||||
Key = UserRole + 1
|
||||
ChainId
|
||||
Address
|
||||
|
||||
QtObject:
|
||||
type Model* = ref object of QAbstractListModel
|
||||
items: seq[Item]
|
||||
|
||||
proc setup(self: Model) =
|
||||
self.QAbstractListModel.setup
|
||||
|
||||
proc delete(self: Model) =
|
||||
self.items = @[]
|
||||
self.QAbstractListModel.delete
|
||||
|
||||
proc newModel*(): Model =
|
||||
new(result, delete)
|
||||
result.setup
|
||||
result.items = @[]
|
||||
|
||||
proc `$`*(self: Model): string =
|
||||
for i in 0 ..< self.items.len:
|
||||
result &= fmt"""[{i}]:({$self.items[i]})"""
|
||||
|
||||
method rowCount(self: Model, index: QModelIndex = nil): int =
|
||||
return self.items.len
|
||||
|
||||
method roleNames(self: Model): Table[int, string] =
|
||||
{
|
||||
ModelRole.Key.int:"key",
|
||||
ModelRole.ChainId.int:"chainId",
|
||||
ModelRole.Address.int:"address",
|
||||
}.toTable
|
||||
|
||||
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||
if not index.isValid:
|
||||
return
|
||||
if index.row < 0 or index.row >= self.rowCount():
|
||||
return
|
||||
let item = self.items[index.row]
|
||||
let enumRole = role.ModelRole
|
||||
case enumRole:
|
||||
of ModelRole.Key:
|
||||
result = newQVariant(item.key())
|
||||
of ModelRole.ChainId:
|
||||
result = newQVariant(item.chainId())
|
||||
of ModelRole.Address:
|
||||
result = newQVariant(item.address())
|
||||
|
||||
proc setItems*(self: Model, items: seq[Item]) =
|
||||
self.beginResetModel()
|
||||
self.items = items
|
||||
self.endResetModel()
|
47
src/app_service/service/ramp/async_tasks.nim
Normal file
47
src/app_service/service/ramp/async_tasks.nim
Normal file
@ -0,0 +1,47 @@
|
||||
import json
|
||||
import backend/ramp as ramp_backend
|
||||
|
||||
|
||||
proc getCryptoServicesTask*(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[QObjectTaskArg](argEncoded)
|
||||
|
||||
try:
|
||||
let response = ramp_backend.fetchCryptoRampProviders()
|
||||
|
||||
if not response.error.isNil:
|
||||
raise newException(ValueError, "Error fetching crypto services" & response.error.message)
|
||||
|
||||
arg.finish(%* {
|
||||
"result": response.result,
|
||||
})
|
||||
except Exception as e:
|
||||
error "Error fetching crypto services", message = e.msg
|
||||
arg.finish(%* {
|
||||
"result": @[],
|
||||
})
|
||||
|
||||
type
|
||||
GetCryptoRampUrlTaskArg* = ref object of QObjectTaskArg
|
||||
uuid: string
|
||||
providerID: string
|
||||
parameters: JsonNode
|
||||
|
||||
proc getCryptoRampUrlTask*(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[GetCryptoRampUrlTaskArg](argEncoded)
|
||||
|
||||
var data = %* {
|
||||
"uuid": arg.uuid
|
||||
}
|
||||
|
||||
try:
|
||||
let parameters = fromJson(arg.parameters, CryptoRampParametersDto)
|
||||
let response = ramp_backend.fetchCryptoRampUrl(arg.providerID, parameters)
|
||||
|
||||
if not response.error.isNil:
|
||||
raise newException(ValueError, "Error fetching crypto ramp url" & response.error.message)
|
||||
data["url"] = response.result
|
||||
arg.finish(data)
|
||||
|
||||
except Exception as e:
|
||||
error "Error fetching crypto ramp url", message = e.msg
|
||||
arg.finish(data)
|
79
src/app_service/service/ramp/dto.nim
Normal file
79
src/app_service/service/ramp/dto.nim
Normal file
@ -0,0 +1,79 @@
|
||||
|
||||
import json, json_serialization, stew/shims/strformat
|
||||
import options
|
||||
|
||||
include app_service/common/json_utils
|
||||
import app_service/service/token/dto
|
||||
|
||||
type
|
||||
CryptoRampDto* = ref object of RootObj
|
||||
id*: string
|
||||
name*: string
|
||||
description*: string
|
||||
fees*: string
|
||||
logoUrl*: string
|
||||
hostname*: string
|
||||
supportsSinglePurchase*: bool
|
||||
supportsRecurrentPurchase*: bool
|
||||
supportedChainIds*: seq[int]
|
||||
supportedTokens*: seq[TokenDto]
|
||||
urlsNeedParameters*: bool
|
||||
|
||||
type
|
||||
CryptoRampParametersDto* = ref object of RootObj
|
||||
isRecurrent*: bool
|
||||
destinationAddress*: Option[string]
|
||||
chainID*: Option[int]
|
||||
symbol*: Option[string]
|
||||
|
||||
proc `$`*(self: CryptoRampDto): string =
|
||||
result = "CryptoRampDto("
|
||||
result &= fmt"id:{self.id}, "
|
||||
result &= fmt"name:{self.name}, "
|
||||
result &= fmt"description:{self.description}, "
|
||||
result &= fmt"fees:{self.fees}, "
|
||||
result &= fmt"logoUrl:{self.logoUrl}, "
|
||||
result &= fmt"hostname:{self.hostname}, "
|
||||
result &= fmt"supportsSinglePurchase:{self.supportsSinglePurchase}, "
|
||||
result &= fmt"supportsRecurrentPurchase:{self.supportsRecurrentPurchase}, "
|
||||
result &= fmt"supportedChainIds:{self.supportedChainIds}, "
|
||||
result &= fmt"supportedTokens:{self.supportedTokens}, "
|
||||
result &= fmt"urlsNeedParameters:{self.urlsNeedParameters}"
|
||||
result &= ")"
|
||||
|
||||
proc toCryptoRampDto*(jsonObj: JsonNode): CryptoRampDto =
|
||||
result = CryptoRampDto()
|
||||
discard jsonObj.getProp("id", result.id)
|
||||
discard jsonObj.getProp("name", result.name)
|
||||
discard jsonObj.getProp("description", result.description)
|
||||
discard jsonObj.getProp("fees", result.fees)
|
||||
discard jsonObj.getProp("logoUrl", result.logoUrl)
|
||||
discard jsonObj.getProp("hostname", result.hostname)
|
||||
discard jsonObj.getProp("supportsSinglePurchase", result.supportsSinglePurchase)
|
||||
discard jsonObj.getProp("supportsRecurrentPurchase", result.supportsRecurrentPurchase)
|
||||
for chainID in jsonObj["supportedChainIds"].getElems():
|
||||
result.supportedChainIds.add(chainID.getInt())
|
||||
for token in jsonObj["supportedTokens"].getElems():
|
||||
let tokenDto = Json.decode($token, TokenDto, allowUnknownFields = true)
|
||||
result.supportedTokens.add(tokenDto)
|
||||
discard jsonObj.getProp("urlsNeedParameters", result.urlsNeedParameters)
|
||||
|
||||
proc `%`*(self: CryptoRampParametersDto): JsonNode =
|
||||
result = newJObject()
|
||||
result["isRecurrent"] = %(self.isRecurrent)
|
||||
if self.destinationAddress.isSome:
|
||||
result["destAddress"] = %(self.destinationAddress.get)
|
||||
if self.chainID.isSome:
|
||||
result["chainID"] = %(self.chainID.get)
|
||||
if self.symbol.isSome:
|
||||
result["symbol"] = %(self.symbol.get)
|
||||
|
||||
proc fromJson*(self: JsonNode, T: typedesc[CryptoRampParametersDto]): CryptoRampParametersDto {.inline.} =
|
||||
result = CryptoRampParametersDto()
|
||||
discard self.getProp("isRecurrent", result.isRecurrent)
|
||||
if self.contains("destAddress"):
|
||||
result.destinationAddress = some(self["destAddress"].getStr())
|
||||
if self.contains("chainID"):
|
||||
result.chainID = some(self["chainID"].getInt())
|
||||
if self.contains("symbol"):
|
||||
result.symbol = some(self["symbol"].getStr())
|
78
src/app_service/service/ramp/service.nim
Normal file
78
src/app_service/service/ramp/service.nim
Normal file
@ -0,0 +1,78 @@
|
||||
import NimQml, sequtils, sugar, chronicles, json
|
||||
|
||||
import app/core/[main]
|
||||
import app/core/signals/types
|
||||
import app/core/tasks/[qt, threadpool]
|
||||
|
||||
import ./dto
|
||||
export dto
|
||||
|
||||
const SIGNAL_CRYPTO_RAMP_PROVIDERS_READY* = "cryptoRampProvidersReady"
|
||||
const SIGNAL_CRYPTO_RAMP_URL_READY* = "cryptoRampUrlReady"
|
||||
|
||||
type
|
||||
CryptoRampProvidersArgs* = ref object of Args
|
||||
data*: seq[CryptoRampDto]
|
||||
|
||||
type
|
||||
CryptoRampUrlArgs* = ref object of Args
|
||||
uuid*: string
|
||||
url*: string
|
||||
|
||||
logScope:
|
||||
topics = "ramp-service"
|
||||
|
||||
include async_tasks
|
||||
include app_service/common/json_utils
|
||||
|
||||
QtObject:
|
||||
type Service* = ref object of QObject
|
||||
events: EventEmitter
|
||||
threadpool: ThreadPool
|
||||
|
||||
proc delete*(self: Service) =
|
||||
self.QObject.delete
|
||||
|
||||
proc newService*(
|
||||
events: EventEmitter,
|
||||
threadpool: ThreadPool,
|
||||
): Service =
|
||||
new(result, delete)
|
||||
result.QObject.setup
|
||||
result.events = events
|
||||
result.threadpool = threadpool
|
||||
|
||||
proc init*(self: Service) =
|
||||
discard
|
||||
|
||||
proc onFetchCryptoRampProviders*(self: Service, response: string) {.slot.} =
|
||||
let cryptoServices = parseJson(response){"result"}.getElems().map(x => x.toCryptoRampDto())
|
||||
self.events.emit(SIGNAL_CRYPTO_RAMP_PROVIDERS_READY, CryptoRampProvidersArgs(data: cryptoServices))
|
||||
|
||||
proc fetchCryptoRampProviders*(self: Service) =
|
||||
let arg = QObjectTaskArg(
|
||||
tptr: getCryptoServicesTask,
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "onFetchCryptoRampProviders",
|
||||
)
|
||||
self.threadpool.start(arg)
|
||||
|
||||
proc onFetchCryptoRampURL*(self: Service, response: string) {.slot.} =
|
||||
let responseJson = parseJson(response)
|
||||
let uuid = responseJson{"uuid"}.getStr()
|
||||
let url = responseJson{"url"}.getStr()
|
||||
self.events.emit(SIGNAL_CRYPTO_RAMP_URL_READY, CryptoRampUrlArgs(
|
||||
uuid: uuid,
|
||||
url: url,
|
||||
))
|
||||
|
||||
proc fetchCryptoRampUrl*(self: Service, uuid: string, providerID: string, parameters: CryptoRampParametersDto) =
|
||||
let arg = GetCryptoRampUrlTaskArg(
|
||||
tptr: getCryptoRampURLTask,
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "onFetchCryptoRampURL",
|
||||
uuid: uuid,
|
||||
providerID: providerID,
|
||||
parameters: %parameters,
|
||||
)
|
||||
self.threadpool.start(arg)
|
@ -46,6 +46,9 @@ proc `$`*(self: TokenDto): string =
|
||||
image: {self.image}
|
||||
]"""
|
||||
|
||||
proc key*(self: TokenDto): string =
|
||||
result = self.address
|
||||
|
||||
type TokenSourceDto* = ref object of RootObj
|
||||
name* {.serializedFieldName("name").}: string
|
||||
tokens* {.serializedFieldName("tokens").}: seq[TokenDto]
|
||||
|
@ -11,7 +11,7 @@ import app/core/tasks/[qt, threadpool]
|
||||
import app/core/signals/types
|
||||
import app_service/common/cache
|
||||
import app_service/common/wallet_constants
|
||||
import ./dto, ./service_items
|
||||
import ./dto, ./service_items, ./utils
|
||||
|
||||
export dto, service_items
|
||||
|
||||
@ -228,7 +228,7 @@ QtObject:
|
||||
let tokenType = TokenType.ERC20
|
||||
|
||||
var updated = false
|
||||
let unique_key = $token.chainID & token.address
|
||||
let unique_key = token.flatModelKey()
|
||||
if not any(self.flatTokenList, proc (x: TokenItem): bool = x.key == unique_key):
|
||||
self.flatTokenList.add(TokenItem(
|
||||
key: unique_key,
|
||||
@ -244,7 +244,7 @@ QtObject:
|
||||
self.flatTokenList.sort(cmpTokenItem)
|
||||
updated = true
|
||||
|
||||
let token_by_symbol_key = token.address
|
||||
let token_by_symbol_key = token.bySymbolModelKey()
|
||||
if not any(self.tokenBySymbolList, proc (x: TokenBySymbolItem): bool = x.key == token_by_symbol_key):
|
||||
self.tokenBySymbolList.add(TokenBySymbolItem(
|
||||
key: token_by_symbol_key,
|
||||
@ -298,7 +298,7 @@ QtObject:
|
||||
# Remove tokens that are not on list of supported status networks
|
||||
if supportedNetworkChains.contains(token.chainID):
|
||||
# logic for building flat tokens list
|
||||
let unique_key = $token.chainID & token.address
|
||||
let unique_key = token.flatModelKey()
|
||||
if flatTokensList.hasKey(unique_key):
|
||||
flatTokensList[unique_key].sources.add(s.name)
|
||||
else:
|
||||
@ -321,8 +321,7 @@ QtObject:
|
||||
# In case this is a community token the only param reliably unique is its address
|
||||
# as there is always a rare case that a user can create two or more community token
|
||||
# with same symbol and cannot be avoided
|
||||
let token_by_symbol_key = if token.communityData.id.isEmptyOrWhitespace: token.symbol
|
||||
else: token.address
|
||||
let token_by_symbol_key = token.bySymbolModelKey()
|
||||
if tokenBySymbolList.hasKey(token_by_symbol_key):
|
||||
if not tokenBySymbolList[token_by_symbol_key].sources.contains(s.name):
|
||||
tokenBySymbolList[token_by_symbol_key].sources.add(s.name)
|
||||
|
12
src/app_service/service/token/utils.nim
Normal file
12
src/app_service/service/token/utils.nim
Normal file
@ -0,0 +1,12 @@
|
||||
import strutils
|
||||
|
||||
import ./dto
|
||||
|
||||
proc flatModelKey*(self: TokenDto): string =
|
||||
result = $self.chainID & self.address
|
||||
|
||||
proc bySymbolModelKey*(self: TokenDto): string =
|
||||
if self.communityData.id.isEmptyOrWhitespace:
|
||||
result = self.symbol
|
||||
else:
|
||||
result = self.address
|
@ -67,28 +67,6 @@ proc watchTransactionTask*(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
"isSuccessfull": false
|
||||
}
|
||||
|
||||
type
|
||||
GetCryptoServicesTaskArg* = ref object of QObjectTaskArg
|
||||
discard
|
||||
|
||||
proc getCryptoServicesTask*(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[GetCryptoServicesTaskArg](argEncoded)
|
||||
|
||||
try:
|
||||
let response = transactions.fetchCryptoServices()
|
||||
|
||||
if not response.error.isNil:
|
||||
raise newException(ValueError, "Error fetching crypto services" & response.error.message)
|
||||
|
||||
arg.finish(%* {
|
||||
"result": response.result,
|
||||
})
|
||||
except Exception as e:
|
||||
error "Error fetching crypto services", message = e.msg
|
||||
arg.finish(%* {
|
||||
"result": @[],
|
||||
})
|
||||
|
||||
type
|
||||
FetchDecodedTxDataTaskArg* = ref object of QObjectTaskArg
|
||||
txHash: string
|
||||
|
@ -1,53 +0,0 @@
|
||||
import json, stew/shims/strformat
|
||||
|
||||
include ../../common/json_utils
|
||||
|
||||
type
|
||||
CryptoRampDto* = ref object of RootObj
|
||||
name*: string
|
||||
description*: string
|
||||
fees*: string
|
||||
logoUrl*: string
|
||||
siteUrl*: string
|
||||
hostname*: string
|
||||
recurrentSiteUrl*: string
|
||||
|
||||
proc newDto*(
|
||||
name: string,
|
||||
description: string,
|
||||
fees: string,
|
||||
logoUrl: string,
|
||||
siteUrl: string,
|
||||
hostname: string,
|
||||
recurrentSiteUrl: string
|
||||
): CryptoRampDto =
|
||||
return CryptoRampDto(
|
||||
name: name,
|
||||
description: description,
|
||||
fees: fees,
|
||||
logoUrl: logoUrl,
|
||||
siteUrl: siteUrl,
|
||||
hostname: hostname,
|
||||
recurrentSiteUrl: recurrentSiteUrl
|
||||
)
|
||||
|
||||
proc `$`*(self: CryptoRampDto): string =
|
||||
result = "CryptoRampDto("
|
||||
result &= fmt"name:{self.name}, "
|
||||
result &= fmt"description:{self.description}, "
|
||||
result &= fmt"fees:{self.fees}, "
|
||||
result &= fmt"logoUrl:{self.logoUrl}, "
|
||||
result &= fmt"siteUrl:{self.siteUrl}, "
|
||||
result &= fmt"hostname:{self.hostname}"
|
||||
result &= fmt"recurrentSiteUrl:{self.recurrentSiteUrl}"
|
||||
result &= ")"
|
||||
|
||||
proc toCryptoRampDto*(jsonObj: JsonNode): CryptoRampDto =
|
||||
result = CryptoRampDto()
|
||||
discard jsonObj.getProp("name", result.name)
|
||||
discard jsonObj.getProp("description", result.description)
|
||||
discard jsonObj.getProp("fees", result.fees)
|
||||
discard jsonObj.getProp("logoUrl", result.logoUrl)
|
||||
discard jsonObj.getProp("siteUrl", result.siteUrl)
|
||||
discard jsonObj.getProp("hostname", result.hostname)
|
||||
discard jsonObj.getProp("recurrentSiteUrl", result.recurrentSiteUrl)
|
@ -24,7 +24,6 @@ import app_service/service/eth/dto/[coder, method_dto]
|
||||
import ./dto as transaction_dto
|
||||
import ./dtoV2
|
||||
import ./dto_conversion
|
||||
import ./cryptoRampDto
|
||||
import app_service/service/eth/utils as eth_utils
|
||||
|
||||
|
||||
@ -42,7 +41,6 @@ const SIGNAL_TRANSACTION_SENT* = "transactionSent"
|
||||
const SIGNAL_SUGGESTED_ROUTES_READY* = "suggestedRoutesReady"
|
||||
const SIGNAL_HISTORY_NON_ARCHIVAL_NODE* = "historyNonArchivalNode"
|
||||
const SIGNAL_HISTORY_ERROR* = "historyError"
|
||||
const SIGNAL_CRYPTO_SERVICES_READY* = "cryptoServicesReady"
|
||||
const SIGNAL_TRANSACTION_DECODED* = "transactionDecoded"
|
||||
const SIGNAL_OWNER_TOKEN_SENT* = "ownerTokenSent"
|
||||
const SIGNAL_TRANSACTION_SENDING_COMPLETE* = "transactionSendingComplete"
|
||||
@ -137,9 +135,6 @@ type
|
||||
errCode*: string
|
||||
errDescription*: string
|
||||
|
||||
type
|
||||
CryptoServicesArgs* = ref object of Args
|
||||
data*: seq[CryptoRampDto]
|
||||
type
|
||||
TransactionDecodedArgs* = ref object of Args
|
||||
dataDecoded*: string
|
||||
@ -697,18 +692,6 @@ QtObject:
|
||||
except CatchableError as e:
|
||||
error "suggestedRoutes", exception=e.msg
|
||||
|
||||
proc onFetchCryptoServices*(self: Service, response: string) {.slot.} =
|
||||
let cryptoServices = parseJson(response){"result"}.getElems().map(x => x.toCryptoRampDto())
|
||||
self.events.emit(SIGNAL_CRYPTO_SERVICES_READY, CryptoServicesArgs(data: cryptoServices))
|
||||
|
||||
proc fetchCryptoServices*(self: Service) =
|
||||
let arg = GetCryptoServicesTaskArg(
|
||||
tptr: getCryptoServicesTask,
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "onFetchCryptoServices",
|
||||
)
|
||||
self.threadpool.start(arg)
|
||||
|
||||
proc getEstimatedTime*(self: Service, chainId: int, maxFeePerGas: string): EstimatedTime =
|
||||
try:
|
||||
let response = backend.getTransactionEstimatedTime(chainId, maxFeePerGas).result.getInt
|
||||
|
14
src/backend/ramp.nim
Normal file
14
src/backend/ramp.nim
Normal file
@ -0,0 +1,14 @@
|
||||
import json
|
||||
|
||||
import ./core as core
|
||||
import ./response_type
|
||||
export response_type
|
||||
|
||||
import ../app_service/service/ramp/dto
|
||||
|
||||
proc fetchCryptoRampProviders*(): RpcResponse[JsonNode] =
|
||||
result = core.callPrivateRPC("wallet_getCryptoOnRamps", %* [])
|
||||
|
||||
proc fetchCryptoRampUrl*(providerID: string, parameters: CryptoRampParametersDto): RpcResponse[JsonNode] =
|
||||
let payload = %* [providerID, parameters]
|
||||
result = core.callPrivateRPC("wallet_getCryptoOnRampURL", payload)
|
@ -82,9 +82,6 @@ proc getTransfersByAddress*(chainId: int, address: string, toBlock: Uint256, lim
|
||||
proc getTransactionReceipt*(chainId: int, transactionHash: string): RpcResponse[JsonNode] =
|
||||
core.callPrivateRPCWithChainId("eth_getTransactionReceipt", chainId, %* [transactionHash])
|
||||
|
||||
proc fetchCryptoServices*(): RpcResponse[JsonNode] =
|
||||
result = core.callPrivateRPC("wallet_getCryptoOnRamps", %* [])
|
||||
|
||||
proc createMultiTransaction*(multiTransactionCommand: MultiTransactionCommandDto, data: seq[TransactionBridgeDto], password: string): RpcResponse[JsonNode] =
|
||||
let payload = %* [multiTransactionCommand, data, password]
|
||||
result = core.callPrivateRPC("wallet_createMultiTransaction", payload)
|
||||
|
2
vendor/status-go
vendored
2
vendor/status-go
vendored
@ -1 +1 @@
|
||||
Subproject commit 48ebe24f8e986c174e8e933404b81a7d6a3beb3e
|
||||
Subproject commit b9d083c6d51befb85978ee3b4927c90bcf092625
|
Loading…
x
Reference in New Issue
Block a user