Skip to content

Commit

Permalink
Use ProviderSupportStore for bityProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
samholmes committed Nov 5, 2024
1 parent d84e90b commit f843675
Showing 1 changed file with 86 additions and 83 deletions.
169 changes: 86 additions & 83 deletions src/plugins/gui/providers/bityProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ import {
FiatProviderFactory,
FiatProviderFactoryParams,
FiatProviderGetQuoteParams,
FiatProviderGetTokenId,
FiatProviderQuote
} from '../fiatProviderTypes'
import { addTokenToArray } from '../util/providerUtils'
import { ProviderSupportStore } from './ProviderSupportStore'

const providerId = 'bity'
const storeId = 'com.bity'
Expand All @@ -32,11 +31,6 @@ const supportEmail = '[email protected]'
const supportedPaymentType: FiatPaymentType = 'sepa'
const partnerFee = 0.005

const allowedCurrencyCodes: Record<FiatDirection, FiatProviderAssetMap> = {
buy: { providerId, fiat: {}, crypto: {} },
sell: { providerId, fiat: {}, crypto: {} }
}

const noKycCurrencyCodes: Record<FiatDirection, FiatProviderAssetMap> = {
buy: {
providerId,
Expand All @@ -58,38 +52,38 @@ const noKycCurrencyCodes: Record<FiatDirection, FiatProviderAssetMap> = {
}
}

const allowedCountryCodes: { readonly [code: string]: boolean } = {
AT: true,
BE: true,
BG: true,
CH: true,
CZ: true,
DK: true,
EE: true,
FI: true,
FR: true,
DE: true,
GR: true,
HU: true,
IE: true, // Ireland
IT: true,
LV: true,
LT: true,
LU: true,
NL: true,
PL: true,
PT: true,
RO: true,
SK: true,
SI: true,
ES: true,
SE: true,
HR: true,
LI: true,
NO: true,
SM: true,
GB: true
}
const supportedRegionCodes = [
'AT',
'BE',
'BG',
'CH',
'CZ',
'DK',
'EE',
'FI',
'FR',
'DE',
'GR',
'HU',
'IE', // Ireland
'IT',
'LV',
'LT',
'LU',
'NL',
'PL',
'PT',
'RO',
'SK',
'SI',
'ES',
'SE',
'HR',
'LI',
'NO',
'SM',
'GB'
]

const CURRENCY_PLUGINID_MAP: StringMap = {
BTC: 'bitcoin',
Expand Down Expand Up @@ -370,18 +364,30 @@ export const bityProvider: FiatProviderFactory = {
const { apiKeys, getTokenId } = params
const clientId = asBityApiKeys(apiKeys).clientId

const supportedAssets = new ProviderSupportStore(providerId)

supportedRegionCodes.forEach(region => {
supportedAssets.add.direction('*').region(region)
})

const out: FiatProvider = {
providerId,
partnerIcon,
pluginDisplayName,
getSupportedAssets: async ({ direction, paymentTypes }): Promise<FiatProviderAssetMap> => {
getSupportedAssets: async ({ direction, paymentTypes, regionCode }): Promise<FiatProviderAssetMap> => {
if (!supportedAssets.is.direction('*').region(regionCode.countryCode).supported)
throw new FiatProviderError({ providerId, errorType: 'regionRestricted' })
// Return nothing if 'sepa' is not included in the props
if (!paymentTypes.includes(supportedPaymentType)) throw new FiatProviderError({ providerId, errorType: 'paymentUnsupported' })

const response = await fetch(`https://exchange.api.bity.com/v2/currencies`).catch(e => undefined)
if (response == null || !response.ok) {
console.error(`Bity getSupportedAssets response error: ${await response?.text()}`)
return allowedCurrencyCodes[direction]
return supportedAssets.getFiatProviderAssetMap({
direction,
region: `*`,
payment: supportedPaymentType
})
}

const result = await response.json()
Expand All @@ -390,32 +396,45 @@ export const bityProvider: FiatProviderFactory = {
bityCurrencies = asBityCurrencyResponse(result).currencies
} catch (error: any) {
console.error(error)
return allowedCurrencyCodes[direction]
return supportedAssets.getFiatProviderAssetMap({
direction,
region: `*`,
payment: supportedPaymentType
})
}

for (const currency of bityCurrencies) {
let isAddCurrencySuccess = false
if (currency.tags.length === 1 && currency.tags[0] === 'fiat') {
allowedCurrencyCodes[direction].fiat['iso:' + currency.code.toUpperCase()] = currency
isAddCurrencySuccess = true
const fiatCurrencyCode = 'iso:' + currency.code.toUpperCase()
supportedAssets.add.direction(direction).region('*').fiat(fiatCurrencyCode).payment(supportedPaymentType)
supportedAssets.addFiatInfo(fiatCurrencyCode, currency)
} else if (currency.tags.includes('crypto')) {
// Bity reports cryptos with a set of multiple tags such that there is
// overlap, such as USDC being 'crypto', 'ethereum', 'erc20'.
if (currency.tags.includes('erc20') && currency.tags.includes('ethereum')) {
// ETH tokens
addToAllowedCurrencies(direction, getTokenId, 'ethereum', currency, currency.code)
isAddCurrencySuccess = true
} else if (Object.keys(CURRENCY_PLUGINID_MAP).includes(currency.code)) {
// Mainnet currencies
addToAllowedCurrencies(direction, getTokenId, CURRENCY_PLUGINID_MAP[currency.code], currency, currency.code)
isAddCurrencySuccess = true
const pluginId = currency.tags.includes('erc20') && currency.tags.includes('ethereum') ? 'ethereum' : CURRENCY_PLUGINID_MAP[currency.code]
if (pluginId == null) continue

const tokenId = getTokenId(pluginId, currency.code)
if (tokenId === undefined) continue

// If token is not in the no-KYC list do not add it
const list = noKycCurrencyCodes[direction].crypto[pluginId]
if (list == null || !list.some(t => t.tokenId === tokenId)) {
continue
}
}

// Unhandled combination not caught by cleaner. Skip to be safe.
if (!isAddCurrencySuccess) console.log('Unhandled Bity supported currency: ', currency)
const crypto = `${pluginId}:${tokenId}`
supportedAssets.add.direction('*').region('*').fiat('*').payment(supportedPaymentType).crypto(crypto)
supportedAssets.addCryptoInfo(crypto, currency)
} else {
// Unhandled combination not caught by cleaner. Skip to be safe.
console.log('Unhandled Bity supported currency: ', currency)
}
}

return allowedCurrencyCodes[direction]
const assetMap = supportedAssets.getFiatProviderAssetMap({ direction, region: '*', payment: supportedPaymentType })

return assetMap
},
getQuote: async (params: FiatProviderGetQuoteParams): Promise<FiatProviderQuote> => {
const {
Expand All @@ -430,12 +449,17 @@ export const bityProvider: FiatProviderFactory = {
displayCurrencyCode
} = params
const isBuy = direction === 'buy'
if (!allowedCountryCodes[regionCode.countryCode]) throw new FiatProviderError({ providerId, errorType: 'regionRestricted', displayCurrencyCode })
if (!paymentTypes.includes(supportedPaymentType)) throw new FiatProviderError({ providerId, errorType: 'paymentUnsupported' })

const bityCurrency = allowedCurrencyCodes[direction].crypto[pluginId].find(t => t.tokenId === tokenId)
const cryptoCurrencyObj = asBityCurrency(bityCurrency?.otherInfo)
const fiatCurrencyObj = asBityCurrency(allowedCurrencyCodes[direction].fiat[fiatCurrencyCode])
if (!supportedAssets.is.direction(direction).region(regionCode.countryCode).supported)
throw new FiatProviderError({ providerId, errorType: 'regionRestricted', displayCurrencyCode })
if (!supportedAssets.is.direction(direction).region(regionCode.countryCode).fiat('*').payment(supportedPaymentType).supported)
throw new FiatProviderError({ providerId, errorType: 'regionRestricted', displayCurrencyCode })

const cryptoOtherInfo = supportedAssets.getCryptoInfo(`${pluginId}:${tokenId}`)
const cryptoCurrencyObj = asBityCurrency(cryptoOtherInfo)

const fiatOtherInfo = supportedAssets.getFiatInfo(fiatCurrencyCode)
const fiatCurrencyObj = asBityCurrency(fiatOtherInfo)

if (cryptoCurrencyObj == null || fiatCurrencyObj == null) throw new Error('Bity: Could not query supported currencies')
const cryptoCode = cryptoCurrencyObj.code
Expand Down Expand Up @@ -639,27 +663,6 @@ export const bityProvider: FiatProviderFactory = {
}
}

const addToAllowedCurrencies = (
direction: FiatDirection,
getTokenId: FiatProviderGetTokenId,
pluginId: string,
currency: BityCurrency,
currencyCode: string
) => {
if (allowedCurrencyCodes[direction].crypto[pluginId] == null) allowedCurrencyCodes[direction].crypto[pluginId] = []
const tokenId = getTokenId(pluginId, currencyCode)
if (tokenId === undefined) return

const tokens = allowedCurrencyCodes[direction].crypto[pluginId]

// If token is not in the no-KYC list do not add it
const list = noKycCurrencyCodes[direction].crypto[pluginId]
if (list == null || !list.some(t => t.tokenId === tokenId)) {
return
}
addTokenToArray({ tokenId, otherInfo: currency }, tokens)
}

/**
* Transition to the send scene pre-populted with the payment address from the
* previously opened/approved sell order
Expand Down

0 comments on commit f843675

Please sign in to comment.