1- import { div } from 'biggystring'
21import {
32 asArray ,
43 asBoolean ,
54 asNumber ,
65 asObject ,
76 asOptional ,
87 asString ,
9- asUnknown
8+ asUnknown ,
9+ asValue
1010} from 'cleaners'
1111import fetch from 'node-fetch'
1212
13- import { PartnerPlugin , PluginParams , PluginResult , StandardTx } from '../types'
14- import { safeParseFloat } from '../util'
13+ import {
14+ PartnerPlugin ,
15+ PluginParams ,
16+ PluginResult ,
17+ StandardTx ,
18+ Status
19+ } from '../types'
20+ import { smartIsoDateFromTimestamp } from '../util'
21+ import { EdgeTokenId } from '../util/asEdgeTokenId'
22+ import { EVM_CHAIN_IDS } from '../util/chainIds'
23+
24+ const asBitrefillStatus = asValue (
25+ 'unpaid' ,
26+ 'delivered' ,
27+ 'sealed' ,
28+ 'created' ,
29+ 'permanent_failure' ,
30+ 'refunded'
31+ )
1532
1633const asBitrefillTx = asObject ( {
34+ status : asBitrefillStatus ,
1735 paymentReceived : asBoolean ,
1836 expired : asBoolean ,
1937 sent : asBoolean ,
2038 invoiceTime : asNumber ,
21- satoshiPrice : asOptional ( asNumber ) ,
39+ btcPrice : asString ,
40+ altcoinPrice : asOptional ( asString ) ,
2241 value : asString ,
2342 currency : asString ,
2443 country : asString ,
2544 coinCurrency : asString ,
26- receivedPaymentAltcoin : asOptional ( asNumber ) ,
45+ paymentMethod : asString ,
46+ // receivedPaymentAltcoin: asOptional(asNumber),
2747 orderId : asString ,
2848 usdPrice : asNumber
2949} )
3050
31- // Partial type for Bitrefill txs for pre-processing
32- const asPreBitrefillTx = asObject ( {
33- expired : asBoolean ,
34- paymentReceived : asBoolean ,
35- sent : asBoolean ,
36- status : asString
37- } )
51+ type BitrefillTx = ReturnType < typeof asBitrefillTx >
52+ type BitrefillStatus = ReturnType < typeof asBitrefillStatus >
53+ const statusMap : { [ key in BitrefillStatus ] : Status } = {
54+ unpaid : 'pending' ,
55+ created : 'pending' ,
56+ delivered : 'complete' ,
57+ refunded : 'refunded' ,
58+ permanent_failure : 'failed' ,
59+ sealed : 'complete'
60+ }
3861
3962const asBitrefillResult = asObject ( {
4063 nextUrl : asOptional ( asString ) ,
4164 orders : asArray ( asUnknown )
4265} )
4366
44- const multipliers : { [ key : string ] : string } = {
45- BTC : '100000000' ,
46- ETH : '1000000' ,
47- LTC : '100000000' ,
48- DASH : '100000000' ,
49- DOGE : '100000000'
67+ const countryCodeMap : { [ key : string ] : string | null } = {
68+ argentina : 'AR' ,
69+ australia : 'AU' ,
70+ austria : 'AT' ,
71+ bangladesh : 'BD' ,
72+ belgium : 'BE' ,
73+ bolivia : 'BO' ,
74+ brazil : 'BR' ,
75+ canada : 'CA' ,
76+ chile : 'CL' ,
77+ china : 'CN' ,
78+ colombia : 'CO' ,
79+ 'costa-rica' : 'CR' ,
80+ 'czech-republic' : 'CZ' ,
81+ denmark : 'DK' ,
82+ 'dominican-republic' : 'DO' ,
83+ ecuador : 'EC' ,
84+ egypt : 'EG' ,
85+ 'el-salvador' : 'SV' ,
86+ finland : 'FI' ,
87+ france : 'FR' ,
88+ germany : 'DE' ,
89+ ghana : 'GH' ,
90+ greece : 'GR' ,
91+ guatemala : 'GT' ,
92+ honduras : 'HN' ,
93+ 'hong-kong' : 'HK' ,
94+ hungary : 'HU' ,
95+ india : 'IN' ,
96+ indonesia : 'ID' ,
97+ ireland : 'IE' ,
98+ israel : 'IL' ,
99+ italy : 'IT' ,
100+ japan : 'JP' ,
101+ kenya : 'KE' ,
102+ malaysia : 'MY' ,
103+ mexico : 'MX' ,
104+ morocco : 'MA' ,
105+ netherlands : 'NL' ,
106+ 'new-zealand' : 'NZ' ,
107+ nicaragua : 'NI' ,
108+ nigeria : 'NG' ,
109+ norway : 'NO' ,
110+ pakistan : 'PK' ,
111+ panama : 'PA' ,
112+ paraguay : 'PY' ,
113+ peru : 'PE' ,
114+ philippines : 'PH' ,
115+ poland : 'PL' ,
116+ portugal : 'PT' ,
117+ romania : 'RO' ,
118+ russia : 'RU' ,
119+ 'saudi-arabia' : 'SA' ,
120+ singapore : 'SG' ,
121+ 'south-africa' : 'ZA' ,
122+ 'south-korea' : 'KR' ,
123+ spain : 'ES' ,
124+ sweden : 'SE' ,
125+ switzerland : 'CH' ,
126+ taiwan : 'TW' ,
127+ thailand : 'TH' ,
128+ turkey : 'TR' ,
129+ ukraine : 'UA' ,
130+ 'united-arab-emirates' : 'AE' ,
131+ 'united-kingdom' : 'GB' ,
132+ uruguay : 'UY' ,
133+ usa : 'US' ,
134+ venezuela : 'VE' ,
135+ vietnam : 'VN' ,
136+ eu : 'EU' ,
137+ international : null
138+ }
139+
140+ const paymentMethodMap : {
141+ [ key : string ] : {
142+ pluginId : string
143+ tokenId : EdgeTokenId
144+ currencyCode : string
145+ }
146+ } = {
147+ bitcoin : { pluginId : 'bitcoin' , tokenId : null , currencyCode : 'BTC' } ,
148+ dash : { pluginId : 'dash' , tokenId : null , currencyCode : 'DASH' } ,
149+ ethereum : { pluginId : 'ethereum' , tokenId : null , currencyCode : 'ETH' } ,
150+ litecoin : { pluginId : 'litecoin' , tokenId : null , currencyCode : 'LTC' } ,
151+ dogecoin : { pluginId : 'dogecoin' , tokenId : null , currencyCode : 'DOGE' } ,
152+ usdc_erc20 : {
153+ pluginId : 'ethereum' ,
154+ tokenId : 'a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' ,
155+ currencyCode : 'USDC'
156+ } ,
157+ usdc_polygon : {
158+ pluginId : 'polygon' ,
159+ tokenId : '3c499c542cef5e3811e1192ce70d8cc03d5c3359' ,
160+ currencyCode : 'USDC'
161+ } ,
162+ usdt_erc20 : {
163+ pluginId : 'ethereum' ,
164+ tokenId : 'dac17f958d2ee523a2206206994597c13d831ec7' ,
165+ currencyCode : 'USDT'
166+ } ,
167+ usdt_trc20 : {
168+ pluginId : 'tron' ,
169+ tokenId : 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t' ,
170+ currencyCode : 'USDT'
171+ }
50172}
51173
52174export async function queryBitrefill (
@@ -74,7 +196,7 @@ export async function queryBitrefill(
74196 }
75197 const standardTxs : StandardTx [ ] = [ ]
76198
77- let url = `https://api.bitrefill.com/v1/orders/`
199+ let url = `https://api.bitrefill.com/v1/orders/?limit=150 `
78200 let count = 0
79201 while ( true ) {
80202 let jsonObj : ReturnType < typeof asBitrefillResult >
@@ -83,22 +205,16 @@ export async function queryBitrefill(
83205 method : 'GET' ,
84206 headers
85207 } )
86- jsonObj = asBitrefillResult ( await result . json ( ) )
208+ const json = await result . json ( )
209+ jsonObj = asBitrefillResult ( json )
87210 } catch ( e ) {
88211 log . error ( String ( e ) )
89212 break
90213 }
91214 const txs = jsonObj . orders
92215 for ( const rawTx of txs ) {
93- // Pre-process the tx to see if it's meets criteria for inclusion:
94- const preTx = asPreBitrefillTx ( rawTx )
95- if ( preTx . status === 'unpaid' ) {
96- continue
97- }
98- if ( preTx . paymentReceived && ! preTx . expired && preTx . sent ) {
99- const standardTx = processBitrefillTx ( rawTx )
100- standardTxs . push ( standardTx )
101- }
216+ const standardTx = processBitrefillTx ( rawTx , pluginParams )
217+ standardTxs . push ( standardTx )
102218 }
103219
104220 if ( count > MAX_ITERATIONS ) {
@@ -127,34 +243,62 @@ export const bitrefill: PartnerPlugin = {
127243 pluginId : 'bitrefill'
128244}
129245
130- export function processBitrefillTx ( rawTx : unknown ) : StandardTx {
131- const tx = asBitrefillTx ( rawTx )
132- const timestamp = tx . invoiceTime / 1000
246+ export function processBitrefillTx (
247+ rawTx : unknown ,
248+ pluginParams : PluginParams
249+ ) : StandardTx {
250+ const { log } = pluginParams
251+ let tx : BitrefillTx
252+ try {
253+ tx = asBitrefillTx ( rawTx )
254+ } catch ( e ) {
255+ throw new Error ( `${ String ( e ) } : ${ JSON . stringify ( rawTx ) } ` )
256+ }
257+ const { isoDate } = smartIsoDateFromTimestamp ( tx . invoiceTime )
258+ const countryCode = countryCodeMap [ tx . country ]
133259
134- const inputCurrency : string = tx . coinCurrency . toUpperCase ( )
135- if ( typeof multipliers [ inputCurrency ] !== 'string' ) {
136- throw new Error ( inputCurrency + ' has no multipliers' )
260+ if ( tx . altcoinPrice != null ) {
261+ log (
262+ `${ tx . orderId } : ${ isoDate } ${ countryCode } ${ tx . status } ${ tx . paymentMethod } alt:${ tx . altcoinPrice } `
263+ )
264+ } else {
265+ log (
266+ `${ tx . orderId } : ${ isoDate } ${ countryCode } ${ tx . status } ${ tx . paymentMethod } btc:${ tx . btcPrice } `
267+ )
137268 }
138- let depositAmountStr = tx . satoshiPrice ?. toString ( )
139- if ( typeof inputCurrency === 'string' && inputCurrency !== 'BTC' ) {
140- depositAmountStr = tx . receivedPaymentAltcoin ?. toString ( )
269+ const edgeAsset = paymentMethodMap [ tx . paymentMethod ]
270+
271+ if ( edgeAsset == null ) {
272+ throw new Error ( `${ tx . orderId } : ${ tx . paymentMethod } has no payment method` )
273+ }
274+ if ( countryCode === undefined ) {
275+ throw new Error ( `${ tx . orderId } : ${ tx . country } has no country code` )
276+ }
277+ const evmChainId = EVM_CHAIN_IDS [ edgeAsset . pluginId ]
278+
279+ const timestamp = tx . invoiceTime / 1000
280+
281+ const { paymentMethod } = tx
282+ let depositAmountStr : string | undefined
283+ if ( paymentMethod === 'bitcoin' ) {
284+ depositAmountStr = tx . btcPrice
285+ } else if ( tx . altcoinPrice != null ) {
286+ depositAmountStr = tx . altcoinPrice
141287 }
142288 if ( depositAmountStr == null ) {
143289 throw new Error ( `Missing depositAmount for tx: ${ tx . orderId } ` )
144290 }
145- const depositAmount = safeParseFloat (
146- div ( depositAmountStr , multipliers [ inputCurrency ] , 8 )
147- )
291+ const depositAmount = Number ( depositAmountStr )
148292 const standardTx : StandardTx = {
149- status : 'complete' ,
293+ status : statusMap [ tx . status ] ,
150294 orderId : tx . orderId ,
151- countryCode : tx . country . toUpperCase ( ) ,
295+ countryCode,
152296 depositTxid : undefined ,
153297 depositAddress : undefined ,
154- depositCurrency : inputCurrency ,
155- depositChainPluginId : undefined ,
156- depositEvmChainId : undefined ,
157- depositTokenId : undefined ,
298+ depositCurrency : edgeAsset . currencyCode ,
299+ depositChainPluginId : edgeAsset . pluginId ,
300+ depositEvmChainId : evmChainId ,
301+ depositTokenId : edgeAsset . tokenId ,
158302 depositAmount,
159303 direction : 'sell' ,
160304 exchangeType : 'fiat' ,
@@ -167,7 +311,7 @@ export function processBitrefillTx(rawTx: unknown): StandardTx {
167311 payoutTokenId : undefined ,
168312 payoutAmount : parseInt ( tx . value ) ,
169313 timestamp,
170- isoDate : new Date ( tx . invoiceTime ) . toISOString ( ) ,
314+ isoDate,
171315 usdValue : tx . usdPrice ,
172316 rawTx
173317 }
0 commit comments