Skip to content

Commit

Permalink
Merge pull request #185 from EdgeApp/paul/addLifi
Browse files Browse the repository at this point in the history
Paul/add lifi
  • Loading branch information
paullinator authored Apr 2, 2024
2 parents 2e687c4 + de9a98c commit 9f2bd69
Show file tree
Hide file tree
Showing 11 changed files with 216 additions and 16 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

- added: Add Lifi reporting
- changed: Paginate caching engine to prevent timeouts
- changed: Create caching engine 'initialized' document entry for each app:partner pair

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"@types/node": "^14.0.22",
"api-changelly": "git://github.com/changelly/api-changelly.git#8e350f3",
"axios": "^0.21.2",
"biggystring": "^3.0.2",
"biggystring": "^4.1.3",
"body-parser": "^1.19.0",
"cleaner-config": "^0.1.10",
"cleaners": "^0.3.13",
Expand Down
4 changes: 4 additions & 0 deletions src/demo/partners.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ export default {
type: 'fiat',
color: '#2551E8'
},
lifi: {
type: 'swap',
color: '#EBB8FA'
},
moonpay: {
type: 'fiat',
color: '#7214F5'
Expand Down
3 changes: 2 additions & 1 deletion src/partners/banxa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import crypto from 'crypto'
import { Response } from 'node-fetch'

import {
EDGE_APP_START_DATE,
PartnerPlugin,
PluginParams,
PluginResult,
Expand All @@ -22,7 +23,7 @@ import { datelog, retryFetch, smartIsoDateFromTimestamp, snooze } from '../util'

export const asBanxaParams = asObject({
settings: asObject({
latestIsoDate: asOptional(asString, '2018-01-01T00:00:00.000Z')
latestIsoDate: asOptional(asString, EDGE_APP_START_DATE)
}),
apiKeys: asObject({
apiKey: asString,
Expand Down
10 changes: 5 additions & 5 deletions src/partners/bitrefill.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { bns } from 'biggystring'
import { div } from 'biggystring'
import {
asArray,
asBoolean,
Expand Down Expand Up @@ -36,7 +36,7 @@ const asBitrefillResult = asObject({
orders: asArray(asUnknown)
})

const div: { [key: string]: string } = {
const multipliers: { [key: string]: string } = {
BTC: '100000000',
ETH: '1000000',
LTC: '100000000',
Expand Down Expand Up @@ -93,8 +93,8 @@ export async function queryBitrefill(

let inputAmountStr = tx.satoshiPrice?.toString()
const inputCurrency: string = tx.coinCurrency.toUpperCase()
if (typeof div[inputCurrency] !== 'string') {
datelog(inputCurrency + ' has no div')
if (typeof multipliers[inputCurrency] !== 'string') {
datelog(inputCurrency + ' has no multipliers')
break
}
if (typeof inputCurrency === 'string' && inputCurrency !== 'BTC') {
Expand All @@ -104,7 +104,7 @@ export async function queryBitrefill(
break
}
const inputAmountNum = parseFloat(
bns.div(inputAmountStr, div[inputCurrency], 8)
div(inputAmountStr, multipliers[inputCurrency], 8)
)
const ssTx: StandardTx = {
status: 'complete',
Expand Down
3 changes: 2 additions & 1 deletion src/partners/letsexchange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from 'cleaners'

import {
EDGE_APP_START_DATE,
PartnerPlugin,
PluginParams,
PluginResult,
Expand All @@ -19,7 +20,7 @@ import { datelog, retryFetch, smartIsoDateFromTimestamp } from '../util'

export const asLetsExchangePluginParams = asObject({
settings: asObject({
latestIsoDate: asOptional(asString, '2018-01-01T00:00:00.000Z')
latestIsoDate: asOptional(asString, EDGE_APP_START_DATE)
}),
apiKeys: asObject({
affiliateId: asOptional(asString),
Expand Down
188 changes: 188 additions & 0 deletions src/partners/lifi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
import {
asArray,
asMaybe,
asNumber,
asObject,
asOptional,
asString,
asValue
} from 'cleaners'

import {
asStandardPluginParams,
EDGE_APP_START_DATE,
PartnerPlugin,
PluginParams,
PluginResult,
StandardTx,
Status
} from '../types'
import { datelog, retryFetch, smartIsoDateFromTimestamp, snooze } from '../util'

const PLUGIN_START_DATE = '2023-01-01T00:00:00.000Z'
const asStatuses = asMaybe(asValue('DONE'), 'other')
const asToken = asObject({
// address: asString,
// chainId: asNumber,
symbol: asString,
decimals: asNumber
// name: asString,
// coinKey: asString,
// logoURI: asString,
// priceUSD: asString
})

const asTransaction = asObject({
txHash: asString,
// txLink: asString,
amount: asString,
token: asToken,
// chainId: asNumber,
// gasPrice: asString,
// gasUsed: asString,
// gasToken: asToken,
// gasAmount: asString,
// gasAmountUSD: asString,
amountUSD: asOptional(asString),
// value: asString,
timestamp: asOptional(asNumber)
})

const asTransfer = asObject({
// transactionId: asString,
sending: asTransaction,
receiving: asTransaction,
// lifiExplorerLink: asString,
// fromAddress: asString,
toAddress: asString,
// tool: asString,
status: asString
// substatus: asString,
// substatusMessage: asString,
// metadata: asObject({
// integrator: asString
// })
})

// Define the cleaner for the whole JSON
const asTransfersResult = asObject({
transfers: asArray(asTransfer)
})

type PartnerStatuses = ReturnType<typeof asStatuses>

const MAX_RETRIES = 5
const QUERY_LOOKBACK = 1000 * 60 * 60 * 24 * 30 // 30 days
const QUERY_TIME_BLOCK_MS = QUERY_LOOKBACK

const statusMap: { [key in PartnerStatuses]: Status } = {
DONE: 'complete',
other: 'other'
}

export async function queryLifi(
pluginParams: PluginParams
): Promise<PluginResult> {
const { settings, apiKeys } = asStandardPluginParams(pluginParams)
const { apiKey } = apiKeys
let { latestIsoDate } = settings

if (latestIsoDate === EDGE_APP_START_DATE) {
latestIsoDate = new Date(PLUGIN_START_DATE).toISOString()
}

let lastCheckedTimestamp = new Date(latestIsoDate).getTime() - QUERY_LOOKBACK
if (lastCheckedTimestamp < 0) lastCheckedTimestamp = 0

const ssFormatTxs: StandardTx[] = []
let retry = 0
let startTime = lastCheckedTimestamp

while (true) {
const endTime = startTime + QUERY_TIME_BLOCK_MS
const now = Date.now()

const startTimeS = startTime / 1000
const endTimeS = endTime / 1000

const url = `https://li.quest/v1/analytics/transfers?integrator=${apiKey}&fromTimestamp=${startTimeS}&toTimestamp=${endTimeS}`
try {
const response = await retryFetch(url)
if (!response.ok) {
const text = await response.text()
throw new Error(text)
}
const jsonObj = await response.json()
const transferResults = asTransfersResult(jsonObj)
for (const tx of transferResults.transfers) {
const txTimestamp = tx.receiving.timestamp ?? tx.sending.timestamp ?? 0
if (txTimestamp === 0) {
throw new Error('No timestamp')
}
const { isoDate, timestamp } = smartIsoDateFromTimestamp(txTimestamp)

const depositAmount =
Number(tx.sending.amount) / 10 ** tx.sending.token.decimals

const payoutAmount =
Number(tx.receiving.amount) / 10 ** tx.receiving.token.decimals

const ssTx: StandardTx = {
status: statusMap[tx.status],
orderId: tx.sending.txHash,
depositTxid: tx.sending.txHash,
depositAddress: undefined,
depositCurrency: tx.sending.token.symbol,
depositAmount,
payoutTxid: undefined,
payoutAddress: tx.toAddress,
payoutCurrency: tx.receiving.token.symbol,
payoutAmount,
timestamp,
isoDate,
usdValue: Number(
tx.receiving.amountUSD ?? tx.sending.amountUSD ?? '-1'
),
rawTx: tx
}
ssFormatTxs.push(ssTx)
if (ssTx.isoDate > latestIsoDate) {
latestIsoDate = ssTx.isoDate
}
}
const endDate = new Date(endTime)
startTime = endTime
datelog(
`Lifi endDate:${endDate.toISOString()} latestIsoDate:${latestIsoDate}`
)
if (endTime > now) {
break
}
retry = 0
} catch (e) {
datelog(e)
// Retry a few times with time delay to prevent throttling
retry++
if (retry <= MAX_RETRIES) {
datelog(`Snoozing ${60 * retry}s`)
await snooze(60000 * retry)
} else {
// We can safely save our progress since we go from oldest to newest.
break
}
}
await snooze(3000)
}

const out = {
settings: { latestIsoDate },
transactions: ssFormatTxs
}
return out
}

export const lifi: PartnerPlugin = {
queryFunc: queryLifi,
pluginName: 'Li.Fi',
pluginId: 'lifi'
}
6 changes: 3 additions & 3 deletions src/partners/totle.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { bns } from 'biggystring'
import { div } from 'biggystring'
import { asArray, asNumber, asObject, asString, asUnknown } from 'cleaners'
import fetch from 'node-fetch'
import Web3 from 'web3'
Expand Down Expand Up @@ -394,7 +394,7 @@ export async function queryTotle(
depositAddress: receipt.from,
depositCurrency: sourceToken.symbol,
depositAmount: parseFloat(
bns.div(
div(
sourceAmount.toString(),
(10 ** sourceToken.decimals).toString(),
10,
Expand All @@ -405,7 +405,7 @@ export async function queryTotle(
payoutAddress: receipt.to,
payoutCurrency: destinationToken.symbol,
payoutAmount: parseFloat(
bns.div(
div(
destinationAmount.toString(),
(10 ** destinationToken.decimals).toString(),
10,
Expand Down
2 changes: 2 additions & 0 deletions src/queryEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { ioniaGiftCards } from './partners/ioniagiftcard'
import { ioniaVisaRewards } from './partners/ioniavisarewards'
import { letsexchange } from './partners/letsexchange'
import { libertyx } from './partners/libertyx'
import { lifi } from './partners/lifi'
import { moonpay } from './partners/moonpay'
import { paytrie } from './partners/paytrie'
import { safello } from './partners/safello'
Expand Down Expand Up @@ -52,6 +53,7 @@ const plugins = [
ioniaGiftCards,
letsexchange,
libertyx,
lifi,
moonpay,
paytrie,
safello,
Expand Down
5 changes: 4 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import {
asValue
} from 'cleaners'

/** Earliest date that transactions may show in Edge */
export const EDGE_APP_START_DATE = '2018-01-01T00:00:00.000Z'

export const asPluginParams = asObject({
settings: asMap((raw: any): any => raw),
apiKeys: asMap((raw: any): any => raw)
Expand Down Expand Up @@ -71,7 +74,7 @@ export const asDbCurrencyCodeMappings = asObject({

export const asStandardPluginParams = asObject({
settings: asObject({
latestIsoDate: asOptional(asString, '2018-01-01T00:00:00.000Z')
latestIsoDate: asOptional(asString, EDGE_APP_START_DATE)
}),
apiKeys: asObject({
apiKey: asOptional(asString)
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1553,10 +1553,10 @@ better-assert@~1.0.0:
dependencies:
callsite "1.0.0"

biggystring@^3.0.2:
version "3.0.2"
resolved "https://registry.npmjs.org/biggystring/-/biggystring-3.0.2.tgz"
integrity sha512-Sl1Ek3XwFliCf08nIaypxQtW+XwocfF33h5WC2baU5xVBf/LBctiK28cB3hmhWOBeArtZp0FbNk4hgDFCP3Fag==
biggystring@^4.1.3:
version "4.1.3"
resolved "https://registry.yarnpkg.com/biggystring/-/biggystring-4.1.3.tgz#9a7d6e79e82781ecd1504aac30a1a815f073adcc"
integrity sha512-u2Uq8rFRHyo8AJgNdOMjwUk6CxOd174LBA63BeHU+SuUOIzFsDu8gIL176128Y6nRrAgEc9U4BYbPDD7zJ+O0g==
dependencies:
bn.js "^4.11.7"

Expand Down

0 comments on commit 9f2bd69

Please sign in to comment.