Skip to content

Commit e725c8e

Browse files
authored
Merge pull request #199 from EdgeApp/paul/moonpaySell
Paul/moonpay sell
2 parents 3cb0dbd + 5f83924 commit e725c8e

4 files changed

Lines changed: 181 additions & 61 deletions

File tree

src/partners/moonpay.ts

Lines changed: 172 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,21 @@
1-
import { asArray, asNumber, asObject, asString, asUnknown } from 'cleaners'
1+
import {
2+
asArray,
3+
asDate,
4+
asNumber,
5+
asObject,
6+
asString,
7+
asUnknown
8+
} from 'cleaners'
29
import fetch from 'node-fetch'
310

4-
import { PartnerPlugin, PluginParams, PluginResult, StandardTx } from '../types'
11+
import {
12+
asStandardPluginParams,
13+
EDGE_APP_START_DATE,
14+
PartnerPlugin,
15+
PluginParams,
16+
PluginResult,
17+
StandardTx
18+
} from '../types'
519
import { datelog } from '../util'
620

721
const asMoonpayCurrency = asObject({
@@ -16,23 +30,35 @@ const asMoonpayTx = asObject({
1630
baseCurrencyAmount: asNumber,
1731
walletAddress: asString,
1832
quoteCurrencyAmount: asNumber,
19-
createdAt: asString,
33+
createdAt: asDate,
2034
id: asString,
2135
baseCurrencyId: asString,
22-
currencyId: asString,
2336
currency: asMoonpayCurrency,
2437
baseCurrency: asMoonpayCurrency
2538
})
2639

40+
const asMoonpaySellTx = asObject({
41+
baseCurrencyAmount: asNumber,
42+
quoteCurrencyAmount: asNumber,
43+
createdAt: asDate,
44+
id: asString,
45+
baseCurrencyId: asString,
46+
depositHash: asString,
47+
quoteCurrency: asMoonpayCurrency,
48+
baseCurrency: asMoonpayCurrency
49+
})
50+
2751
type MoonpayTx = ReturnType<typeof asMoonpayTx>
52+
type MoonpaySellTx = ReturnType<typeof asMoonpaySellTx>
2853

2954
const asMoonpayRawTx = asObject({
3055
status: asString
3156
})
3257

3358
const asMoonpayResult = asArray(asUnknown)
3459

35-
const QUERY_LOOKBACK = 1000 * 60 * 60 * 24 * 5
60+
const PARTNER_START_DATE = '2024-06-17T00:00:00.000Z'
61+
const QUERY_LOOKBACK = 1000 * 60 * 60 * 24 * 7
3662
const PER_REQUEST_LIMIT = 50
3763

3864
export async function queryMoonpay(
@@ -41,80 +67,167 @@ export async function queryMoonpay(
4167
const ssFormatTxs: StandardTx[] = []
4268

4369
let headers
44-
let latestTimestamp = 0
45-
if (typeof pluginParams.settings.latestTimestamp === 'number') {
46-
latestTimestamp = pluginParams.settings.latestTimestamp
70+
const { apiKeys, settings } = asStandardPluginParams(pluginParams)
71+
let { latestIsoDate } = settings
72+
if (latestIsoDate === EDGE_APP_START_DATE) {
73+
latestIsoDate = PARTNER_START_DATE
4774
}
75+
const { apiKey } = pluginParams.apiKeys
4876

49-
const apiKey = pluginParams.apiKeys.apiKey
5077
if (typeof apiKey === 'string') {
5178
headers = {
5279
Authorization: `Api-Key ${apiKey}`
5380
}
5481
} else {
5582
return {
56-
settings: { latestTimestamp: latestTimestamp },
83+
settings: { latestIsoDate },
5784
transactions: []
5885
}
5986
}
6087

61-
if (latestTimestamp > QUERY_LOOKBACK) {
62-
latestTimestamp -= QUERY_LOOKBACK
63-
}
64-
let done = false
65-
let offset = 0
66-
let newestTimestamp = latestTimestamp
67-
while (!done) {
68-
const url = `https://api.moonpay.io/v1/transactions?limit=${PER_REQUEST_LIMIT}&offset=${offset}`
69-
const result = await fetch(url, {
70-
method: 'GET',
71-
headers
72-
})
73-
const txs = asMoonpayResult(await result.json())
74-
// cryptoTransactionId is a duplicate among other transactions sometimes
75-
// in bulk update it throws an error for document update conflict because of this.
76-
77-
for (const rawtx of txs) {
78-
if (asMoonpayRawTx(rawtx).status === 'completed') {
79-
let tx: MoonpayTx
80-
try {
81-
tx = asMoonpayTx(rawtx)
82-
} catch (e) {
83-
datelog(e)
84-
datelog(rawtx)
85-
throw e
88+
// Make endDate a week after the query date
89+
let queryIsoDate = new Date(
90+
new Date(latestIsoDate).getTime() - QUERY_LOOKBACK
91+
).toISOString()
92+
93+
const isoNow = new Date().toISOString()
94+
95+
try {
96+
do {
97+
console.log(`Querying Moonpay from ${queryIsoDate} to ${latestIsoDate}`)
98+
let offset = 0
99+
100+
while (true) {
101+
const url = `https://api.moonpay.io/v3/sell_transactions?limit=${PER_REQUEST_LIMIT}&offset=${offset}&startDate=${queryIsoDate}&endDate=${latestIsoDate}`
102+
const result = await fetch(url, {
103+
method: 'GET',
104+
headers
105+
})
106+
const txs = asMoonpayResult(await result.json())
107+
108+
for (const rawtx of txs) {
109+
if (asMoonpayRawTx(rawtx).status === 'completed') {
110+
let tx: MoonpaySellTx
111+
try {
112+
tx = asMoonpaySellTx(rawtx)
113+
} catch (e) {
114+
datelog(e)
115+
datelog(rawtx)
116+
throw e
117+
}
118+
119+
const isoDate = tx.createdAt.toISOString()
120+
const timestamp = tx.createdAt.getTime()
121+
const ssTx: StandardTx = {
122+
status: 'complete',
123+
orderId: tx.id,
124+
depositTxid: tx.depositHash,
125+
depositAddress: undefined,
126+
depositCurrency: tx.baseCurrency.code.toUpperCase(),
127+
depositAmount: tx.baseCurrencyAmount,
128+
payoutTxid: undefined,
129+
payoutAddress: undefined,
130+
payoutCurrency: tx.quoteCurrency.code.toUpperCase(),
131+
payoutAmount: tx.quoteCurrencyAmount,
132+
timestamp: timestamp / 1000,
133+
isoDate,
134+
usdValue: -1,
135+
rawTx: rawtx
136+
}
137+
ssFormatTxs.push(ssTx)
138+
}
139+
}
140+
141+
if (txs.length > 0) {
142+
console.log(
143+
`Moonpay sell txs ${txs.length}: ${JSON.stringify(
144+
txs.slice(-1)
145+
).slice(0, 100)}`
146+
)
86147
}
87148

88-
const date = new Date(tx.createdAt)
89-
const timestamp = date.getTime()
90-
const ssTx: StandardTx = {
91-
status: 'complete',
92-
orderId: tx.id,
93-
depositTxid: undefined,
94-
depositAddress: undefined,
95-
depositCurrency: tx.baseCurrency.code.toUpperCase(),
96-
depositAmount: tx.baseCurrencyAmount,
97-
payoutTxid: tx.cryptoTransactionId,
98-
payoutAddress: tx.walletAddress,
99-
payoutCurrency: tx.currency.code.toUpperCase(),
100-
payoutAmount: tx.quoteCurrencyAmount,
101-
timestamp: timestamp / 1000,
102-
isoDate: tx.createdAt,
103-
usdValue: -1,
104-
rawTx: rawtx
149+
if (txs.length < PER_REQUEST_LIMIT) {
150+
break
105151
}
106-
ssFormatTxs.push(ssTx)
107-
done = latestTimestamp > timestamp || txs.length < PER_REQUEST_LIMIT
108-
newestTimestamp =
109-
newestTimestamp > timestamp ? newestTimestamp : timestamp
152+
153+
offset += PER_REQUEST_LIMIT
110154
}
111-
}
112155

113-
offset += PER_REQUEST_LIMIT
156+
offset = 0
157+
while (true) {
158+
const url = `https://api.moonpay.io/v1/transactions?limit=${PER_REQUEST_LIMIT}&offset=${offset}&startDate=${queryIsoDate}&endDate=${latestIsoDate}`
159+
const result = await fetch(url, {
160+
method: 'GET',
161+
headers
162+
})
163+
const txs = asMoonpayResult(await result.json())
164+
// cryptoTransactionId is a duplicate among other transactions sometimes
165+
// in bulk update it throws an error for document update conflict because of this.
166+
167+
for (const rawtx of txs) {
168+
if (asMoonpayRawTx(rawtx).status === 'completed') {
169+
let tx: MoonpayTx
170+
try {
171+
tx = asMoonpayTx(rawtx)
172+
} catch (e) {
173+
datelog(e)
174+
datelog(rawtx)
175+
throw e
176+
}
177+
178+
const isoDate = tx.createdAt.toISOString()
179+
const timestamp = tx.createdAt.getTime()
180+
const ssTx: StandardTx = {
181+
status: 'complete',
182+
orderId: tx.id,
183+
depositTxid: undefined,
184+
depositAddress: undefined,
185+
depositCurrency: tx.baseCurrency.code.toUpperCase(),
186+
depositAmount: tx.baseCurrencyAmount,
187+
payoutTxid: tx.cryptoTransactionId,
188+
payoutAddress: tx.walletAddress,
189+
payoutCurrency: tx.currency.code.toUpperCase(),
190+
payoutAmount: tx.quoteCurrencyAmount,
191+
timestamp: timestamp / 1000,
192+
isoDate,
193+
usdValue: -1,
194+
rawTx: rawtx
195+
}
196+
ssFormatTxs.push(ssTx)
197+
}
198+
}
199+
if (txs.length > 0) {
200+
console.log(
201+
`Moonpay buy txs ${txs.length}: ${JSON.stringify(
202+
txs.slice(-1)
203+
).slice(0, 100)}`
204+
)
205+
}
206+
207+
if (txs.length < PER_REQUEST_LIMIT) {
208+
break
209+
}
210+
211+
offset += PER_REQUEST_LIMIT
212+
}
213+
queryIsoDate = latestIsoDate
214+
latestIsoDate = new Date(
215+
new Date(latestIsoDate).getTime() + QUERY_LOOKBACK
216+
).toISOString()
217+
} while (isoNow > latestIsoDate)
218+
latestIsoDate = isoNow
219+
} catch (e) {
220+
datelog(e)
221+
console.log(`Moonpay error: ${e}`)
222+
console.log(`Saving progress up until ${queryIsoDate}`)
223+
224+
// Set the latestIsoDate to the queryIsoDate so that the next query will
225+
// query the same time range again since we had a failure in that time range
226+
latestIsoDate = queryIsoDate
114227
}
115228

116229
const out: PluginResult = {
117-
settings: { latestTimestamp: newestTimestamp },
230+
settings: { latestIsoDate },
118231
transactions: ssFormatTxs
119232
}
120233
return out

src/partners/thorchain.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,5 +304,5 @@ export const thorchain = makeThorchainPlugin({
304304
export const maya = makeThorchainPlugin({
305305
pluginName: 'Maya',
306306
pluginId: 'maya',
307-
midgardUrl: 'midgard.mayachain.info'
307+
midgardUrl: 'midgard-maya.liquify.com'
308308
})

src/queryEngine.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,10 @@ export async function queryEngine(): Promise<void> {
120120
string => string !== partnerId
121121
)
122122
if (remainingPartners.length > 0) {
123-
datelog('REMAINING PLUGINS:', remainingPartners.join(', '))
123+
datelog(
124+
`REMAINING PLUGINS for ${app.appId}:`,
125+
remainingPartners.join(', ')
126+
)
124127
}
125128
})
126129
)

src/util.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { config } from './config'
55
export const SIX_DAYS = 6
66

77
const CURRENCY_CONVERSION = {
8+
AAVEBSC: 'AAVE',
89
AWCBEP20: 'AWC',
910
AWCBSC: 'AWC',
1011
DAIMATIC: 'DAI',
@@ -15,11 +16,14 @@ const CURRENCY_CONVERSION = {
1516
WBTCMATIC: 'WBTC',
1617
USDCERC20: 'USDC',
1718
USDCSOLO: 'USDC',
19+
USDCBSC: 'USDC',
20+
USDCBASE: 'USDC',
1821
USDT20: 'USDT',
1922
USDTERC20: 'USDT',
2023
USDTPOLYGON: 'USDT',
2124
USDCARB: 'USDC',
2225
USDCPOLYGON: 'USDC',
26+
USDCSOL: 'USDC',
2327
USDCTRC20: 'USDC',
2428
USDDTRC20: 'USDD',
2529
USDTARB: 'USDT',

0 commit comments

Comments
 (0)