Skip to content

Commit f4df7ab

Browse files
authored
Merge pull request #186 from EdgeApp/paul/addKado
Add Kado
2 parents 7ffaaf2 + c17c803 commit f4df7ab

File tree

4 files changed

+180
-0
lines changed

4 files changed

+180
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- added: Add Lifi reporting
66
- added: Paybis support
7+
- added: Kado reporting
78
- changed: Paginate caching engine to prevent timeouts
89
- changed: Create caching engine 'initialized' document entry for each app:partner pair
910
- fixed: Properly handle null values in 'number' typed fields

src/demo/partners.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ export default {
7373
type: 'fiat',
7474
color: '#6381F5'
7575
},
76+
kado: {
77+
type: 'fiat',
78+
color: '#9AB4F9'
79+
},
7680
letsexchange: {
7781
type: 'swap',
7882
color: '#1A1438'

src/partners/kado.ts

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
import {
2+
asArray,
3+
asBoolean,
4+
asDate,
5+
asMaybe,
6+
asNumber,
7+
asObject,
8+
asOptional,
9+
asString,
10+
asValue
11+
} from 'cleaners'
12+
13+
import {
14+
asStandardPluginParams,
15+
PartnerPlugin,
16+
PluginParams,
17+
PluginResult,
18+
StandardTx,
19+
Status
20+
} from '../types'
21+
import { datelog, retryFetch, smartIsoDateFromTimestamp, snooze } from '../util'
22+
23+
// Define cleaner for individual transactions in onRamps and offRamps
24+
const asTxType = asValue('buy', 'sell')
25+
26+
const asTransaction = asObject({
27+
_id: asString,
28+
walletAddress: asString,
29+
createdAt: asDate,
30+
type: asTxType,
31+
walletType: asString,
32+
cryptoCurrency: asString,
33+
network: asString
34+
})
35+
36+
const asOnRampTx = asObject({
37+
...asTransaction.shape,
38+
receiveUnitCount: asNumber,
39+
paidAmountUsd: asNumber,
40+
paymentMethod: asString
41+
})
42+
43+
const asOffRampTx = asObject({
44+
...asTransaction.shape,
45+
depositUnitCount: asNumber,
46+
receiveUsd: asNumber
47+
// disburseMethod: asString
48+
})
49+
50+
// Define cleaner for the main data structure
51+
const asResponse = asObject({
52+
success: asBoolean,
53+
// message: asString,
54+
data: asObject({
55+
onRamps: asArray(asOnRampTx),
56+
offRamps: asArray(asOffRampTx)
57+
})
58+
})
59+
60+
const MAX_RETRIES = 5
61+
62+
export async function queryKado(
63+
pluginParams: PluginParams
64+
): Promise<PluginResult> {
65+
const { settings, apiKeys } = asStandardPluginParams(pluginParams)
66+
const { apiKey } = apiKeys
67+
let { latestIsoDate } = settings
68+
69+
// API doesn't currently support paging by date but leave this in here
70+
// for when it does
71+
if (latestIsoDate === '2018-01-01T00:00:00.000Z') {
72+
latestIsoDate = new Date('2024-01-01T00:00:00.000Z').toISOString()
73+
}
74+
75+
const ssFormatTxs: StandardTx[] = []
76+
let retry = 0
77+
78+
const url = `https://api.kado.money/v2/organizations/${apiKey}/orders`
79+
try {
80+
const response = await retryFetch(url)
81+
if (!response.ok) {
82+
const text = await response.text()
83+
throw new Error(text)
84+
}
85+
const jsonObj = await response.json()
86+
const transferResults = asResponse(jsonObj)
87+
const { onRamps, offRamps } = transferResults.data
88+
for (const tx of onRamps) {
89+
const {
90+
_id,
91+
createdAt,
92+
cryptoCurrency,
93+
paidAmountUsd,
94+
receiveUnitCount,
95+
walletAddress
96+
} = tx
97+
const { isoDate, timestamp } = smartIsoDateFromTimestamp(
98+
createdAt.toISOString()
99+
)
100+
const ssTx: StandardTx = {
101+
status: 'complete',
102+
orderId: _id,
103+
depositTxid: undefined,
104+
depositAddress: undefined,
105+
depositCurrency: 'USD',
106+
depositAmount: paidAmountUsd,
107+
payoutTxid: undefined,
108+
payoutAddress: walletAddress,
109+
payoutCurrency: cryptoCurrency,
110+
payoutAmount: receiveUnitCount,
111+
timestamp,
112+
isoDate,
113+
usdValue: paidAmountUsd,
114+
rawTx: tx
115+
}
116+
ssFormatTxs.push(ssTx)
117+
}
118+
for (const tx of offRamps) {
119+
const {
120+
_id,
121+
createdAt,
122+
cryptoCurrency,
123+
depositUnitCount,
124+
receiveUsd
125+
} = tx
126+
const { isoDate, timestamp } = smartIsoDateFromTimestamp(
127+
createdAt.toISOString()
128+
)
129+
const ssTx: StandardTx = {
130+
status: 'complete',
131+
orderId: _id,
132+
depositTxid: undefined,
133+
depositAddress: undefined,
134+
depositCurrency: cryptoCurrency,
135+
depositAmount: depositUnitCount,
136+
payoutTxid: undefined,
137+
payoutAddress: undefined,
138+
payoutCurrency: 'USD',
139+
payoutAmount: receiveUsd,
140+
timestamp,
141+
isoDate,
142+
usdValue: receiveUsd,
143+
rawTx: tx
144+
}
145+
ssFormatTxs.push(ssTx)
146+
}
147+
datelog(`Kado latestIsoDate:${latestIsoDate}`)
148+
retry = 0
149+
} catch (e) {
150+
datelog(e)
151+
// Retry a few times with time delay to prevent throttling
152+
retry++
153+
if (retry <= MAX_RETRIES) {
154+
datelog(`Snoozing ${60 * retry}s`)
155+
await snooze(61000 * retry)
156+
} else {
157+
// We can safely save our progress since we go from oldest to newest.
158+
// break
159+
}
160+
}
161+
162+
const out = {
163+
settings: {},
164+
transactions: ssFormatTxs
165+
}
166+
return out
167+
}
168+
169+
export const kado: PartnerPlugin = {
170+
queryFunc: queryKado,
171+
pluginName: 'Kado',
172+
pluginId: 'kado'
173+
}

src/queryEngine.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { gebo } from './partners/gebo'
1717
import { godex } from './partners/godex'
1818
import { ioniaGiftCards } from './partners/ioniagiftcard'
1919
import { ioniaVisaRewards } from './partners/ioniavisarewards'
20+
import { kado } from './partners/kado'
2021
import { letsexchange } from './partners/letsexchange'
2122
import { libertyx } from './partners/libertyx'
2223
import { lifi } from './partners/lifi'
@@ -52,6 +53,7 @@ const plugins = [
5253
godex,
5354
ioniaVisaRewards,
5455
ioniaGiftCards,
56+
kado,
5557
letsexchange,
5658
libertyx,
5759
lifi,

0 commit comments

Comments
 (0)