-
Notifications
You must be signed in to change notification settings - Fork 104
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add functionality to send notifications from ender
This reverts commit d34c181.
- Loading branch information
1 parent
f1c5a31
commit aaa9309
Showing
6 changed files
with
246 additions
and
1 deletion.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
155 changes: 155 additions & 0 deletions
155
indexer/services/ender/__tests__/helpers/notification-functions.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
import { | ||
sendOrderFilledNotification, | ||
sendOrderTriggeredNotification, | ||
} from '../../src/helpers/notifications/notifications-functions'; | ||
import { | ||
dbHelpers, | ||
OrderFromDatabase, | ||
PerpetualMarketFromDatabase, | ||
PerpetualMarketStatus, | ||
PerpetualMarketType, | ||
SubaccountTable, | ||
testMocks, | ||
} from '@dydxprotocol-indexer/postgres'; | ||
|
||
import { | ||
createNotification, | ||
sendFirebaseMessage, | ||
NotificationType, | ||
} from '@dydxprotocol-indexer/notifications'; | ||
import { | ||
defaultSubaccountId, | ||
defaultMarket, | ||
defaultToken, | ||
} from '@dydxprotocol-indexer/postgres/build/__tests__/helpers/constants'; | ||
|
||
// Mock only the sendFirebaseMessage function | ||
jest.mock('@dydxprotocol-indexer/notifications', () => { | ||
const actualModule = jest.requireActual('@dydxprotocol-indexer/notifications'); | ||
return { | ||
...actualModule, // keep all other exports intact | ||
sendFirebaseMessage: jest.fn(), | ||
createNotification: jest.fn(), | ||
}; | ||
}); | ||
|
||
const mockMarket: PerpetualMarketFromDatabase = { | ||
id: '1', | ||
clobPairId: '1', | ||
ticker: 'BTC-USD', | ||
marketId: 1, | ||
status: PerpetualMarketStatus.ACTIVE, | ||
priceChange24H: '0', | ||
volume24H: '0', | ||
trades24H: 0, | ||
nextFundingRate: '0', | ||
openInterest: '0', | ||
quantumConversionExponent: 1, | ||
atomicResolution: 1, | ||
subticksPerTick: 1, | ||
stepBaseQuantums: 1, | ||
liquidityTierId: 1, | ||
marketType: PerpetualMarketType.ISOLATED, | ||
baseOpenInterest: '0', | ||
}; | ||
|
||
describe('notification functions', () => { | ||
beforeEach(async () => { | ||
await testMocks.seedData(); | ||
}); | ||
|
||
afterEach(async () => { | ||
await dbHelpers.clearData(); | ||
}); | ||
describe('sendOrderFilledNotification', () => { | ||
it('should create and send an order filled notification', async () => { | ||
const mockOrder: OrderFromDatabase = { | ||
id: '1', | ||
subaccountId: defaultSubaccountId, | ||
clientId: '1', | ||
clobPairId: String(defaultMarket.id), | ||
side: 'BUY', | ||
size: '10', | ||
totalFilled: '0', | ||
price: '100.50', | ||
type: 'LIMIT', | ||
status: 'OPEN', | ||
timeInForce: 'GTT', | ||
reduceOnly: false, | ||
orderFlags: '0', | ||
goodTilBlock: '1000000', | ||
createdAtHeight: '900000', | ||
clientMetadata: '0', | ||
triggerPrice: undefined, | ||
updatedAt: new Date().toISOString(), | ||
updatedAtHeight: '900001', | ||
} as OrderFromDatabase; | ||
|
||
await sendOrderFilledNotification(mockOrder, mockMarket); | ||
|
||
// Assert that createNotification was called with correct arguments | ||
expect(createNotification).toHaveBeenCalledWith( | ||
NotificationType.ORDER_FILLED, | ||
{ | ||
AMOUNT: '10', | ||
MARKET: 'BTC-USD', | ||
AVERAGE_PRICE: '100.50', | ||
}, | ||
); | ||
|
||
expect(sendFirebaseMessage).toHaveBeenCalledWith( | ||
[ | ||
expect.objectContaining({ | ||
token: defaultToken.token, | ||
language: defaultToken.language, | ||
}), | ||
], | ||
undefined, | ||
); | ||
}); | ||
|
||
describe('sendOrderTriggeredNotification', () => { | ||
it('should create and send an order triggered notification', async () => { | ||
const subaccount = await SubaccountTable.findById(defaultSubaccountId); | ||
const mockOrder: OrderFromDatabase = { | ||
id: '1', | ||
subaccountId: subaccount!.id, | ||
clientId: '1', | ||
clobPairId: '1', | ||
side: 'BUY', | ||
size: '10', | ||
price: '100.50', | ||
type: 'LIMIT', | ||
status: 'OPEN', | ||
timeInForce: 'GTT', | ||
reduceOnly: false, | ||
orderFlags: '0', | ||
goodTilBlock: '1000000', | ||
createdAtHeight: '900000', | ||
clientMetadata: '0', | ||
triggerPrice: '99.00', | ||
updatedAt: new Date().toISOString(), | ||
updatedAtHeight: '900001', | ||
} as OrderFromDatabase; | ||
|
||
await sendOrderTriggeredNotification(mockOrder, mockMarket, subaccount!); | ||
|
||
expect(createNotification).toHaveBeenCalledWith( | ||
NotificationType.ORDER_TRIGGERED, | ||
{ | ||
MARKET: 'BTC-USD', | ||
PRICE: '100.50', | ||
AMOUNT: '10', | ||
}, | ||
); | ||
|
||
expect(sendFirebaseMessage).toHaveBeenCalledWith([expect.objectContaining( | ||
{ | ||
token: defaultToken.token, | ||
language: defaultToken.language, | ||
}, | ||
)], undefined); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
76 changes: 76 additions & 0 deletions
76
indexer/services/ender/src/helpers/notifications/notifications-functions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import { logger } from '@dydxprotocol-indexer/base'; | ||
import { | ||
createNotification, | ||
NotificationDynamicFieldKey, | ||
NotificationType, | ||
sendFirebaseMessage, | ||
} from '@dydxprotocol-indexer/notifications'; | ||
import { | ||
OrderFromDatabase, | ||
PerpetualMarketFromDatabase, | ||
SubaccountFromDatabase, | ||
SubaccountTable, | ||
TokenTable, | ||
} from '@dydxprotocol-indexer/postgres'; | ||
|
||
export async function sendOrderFilledNotification( | ||
order: OrderFromDatabase, | ||
market: PerpetualMarketFromDatabase, | ||
) { | ||
try { | ||
const subaccount = await SubaccountTable.findById(order.subaccountId); | ||
if (!subaccount) { | ||
throw new Error(`Subaccount not found for id ${order.subaccountId}`); | ||
} | ||
|
||
const tokens = (await TokenTable.findAll({ address: subaccount.address }, [])); | ||
if (tokens.length === 0) { | ||
throw new Error(`No token found for address ${subaccount.address}`); | ||
} | ||
|
||
const notification = createNotification( | ||
NotificationType.ORDER_FILLED, | ||
{ | ||
[NotificationDynamicFieldKey.AMOUNT]: order.size.toString(), | ||
[NotificationDynamicFieldKey.MARKET]: market.ticker, | ||
[NotificationDynamicFieldKey.AVERAGE_PRICE]: order.price, | ||
}, | ||
); | ||
|
||
await sendFirebaseMessage(tokens, notification); | ||
} catch (error) { | ||
logger.error({ | ||
at: 'ender#notification-functions', | ||
message: 'Error sending order filled notification', | ||
error, | ||
}); | ||
} | ||
} | ||
|
||
export async function sendOrderTriggeredNotification( | ||
order: OrderFromDatabase, | ||
market: PerpetualMarketFromDatabase, | ||
subaccount: SubaccountFromDatabase, | ||
) { | ||
try { | ||
const tokens = (await TokenTable.findAll({ address: subaccount.address }, [])); | ||
if (tokens.length === 0) { | ||
throw new Error(`No tokens found for address ${subaccount.address}`); | ||
} | ||
const notification = createNotification( | ||
NotificationType.ORDER_TRIGGERED, | ||
{ | ||
[NotificationDynamicFieldKey.MARKET]: market.ticker, | ||
[NotificationDynamicFieldKey.PRICE]: order.price, | ||
[NotificationDynamicFieldKey.AMOUNT]: order.size.toString(), | ||
}, | ||
); | ||
await sendFirebaseMessage(tokens, notification); | ||
} catch (error) { | ||
logger.error({ | ||
at: 'ender#notification-functions', | ||
message: 'Error sending order triggered notification', | ||
error, | ||
}); | ||
} | ||
} |