AccountAdapter.test.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import { describe, it, expect, jest } from '@jest/globals'
  2. import {
  3. PacificaAccountAdapter,
  4. LeveragePayload,
  5. SubaccountPayload,
  6. } from '../../../src/exchanges/pacifica/AccountAdapter'
  7. describe('PacificaAccountAdapter', () => {
  8. const baseEndpoints = {
  9. accountInfo: '/api/v1/account/info',
  10. balances: '/api/v1/account/balance',
  11. positions: '/api/v1/account/positions',
  12. leverage: '/api/v1/account/leverage',
  13. subaccountCreate: '/api/v1/account/subaccount/create',
  14. } as const
  15. const createClientMock = () => {
  16. type SignResult = { timestamp: number; expiryWindow: number; signature: string }
  17. const signOperation =
  18. jest.fn<(type: string, data: Record<string, any>, expiryWindow?: number) => Promise<SignResult>>()
  19. const post = jest.fn<(path: string, body: any) => Promise<any>>()
  20. const get = jest.fn<(path: string, query?: Record<string, any>) => Promise<any>>()
  21. const requireAccount = jest.fn((acct?: string) => acct ?? 'mock-account')
  22. const client = {
  23. endpoints: baseEndpoints,
  24. signOperation,
  25. post,
  26. get,
  27. requireAccount,
  28. } as any
  29. return { client, signOperation, post, get, requireAccount }
  30. }
  31. it('updateLeverage signs payload and posts request body according to docs', async () => {
  32. const { client, signOperation, post } = createClientMock()
  33. signOperation.mockResolvedValue({ timestamp: 1716200000000, expiryWindow: 30000, signature: 'signed-value' })
  34. post.mockResolvedValue({ success: true })
  35. const adapter = new PacificaAccountAdapter(client)
  36. const payload: LeveragePayload = {
  37. account: '42trU9A5',
  38. symbol: 'BTC',
  39. leverage: 10,
  40. agentWallet: '69trU9A5',
  41. expiryWindow: 45000,
  42. }
  43. const result = await adapter.updateLeverage(payload)
  44. expect(signOperation).toHaveBeenCalledWith(
  45. 'update_leverage',
  46. {
  47. account: payload.account,
  48. symbol: payload.symbol,
  49. leverage: payload.leverage,
  50. agent_wallet: payload.agentWallet,
  51. },
  52. payload.expiryWindow,
  53. )
  54. expect(post).toHaveBeenCalledWith(
  55. baseEndpoints.leverage,
  56. {
  57. account: payload.account,
  58. symbol: payload.symbol,
  59. leverage: payload.leverage,
  60. agent_wallet: payload.agentWallet,
  61. timestamp: 1716200000000,
  62. expiry_window: 30000,
  63. signature: 'signed-value',
  64. },
  65. { skipHeaderSig: true },
  66. )
  67. expect(result).toEqual({ success: true })
  68. })
  69. it('createSubaccount signs with both main and sub accounts', async () => {
  70. const { client, signOperation, post } = createClientMock()
  71. signOperation
  72. .mockResolvedValueOnce({ timestamp: 1000, expiryWindow: 30000, signature: 'main-sign' })
  73. .mockResolvedValueOnce({ timestamp: 2000, expiryWindow: 30000, signature: 'sub-sign' })
  74. post.mockResolvedValue({ success: true })
  75. const adapter = new PacificaAccountAdapter(client)
  76. const payload: SubaccountPayload = {
  77. mainAccount: 'main-account',
  78. subAccount: 'child-account',
  79. expiryWindow: 60000,
  80. }
  81. const result = await adapter.createSubaccount(payload)
  82. expect(signOperation).toHaveBeenNthCalledWith(
  83. 1,
  84. 'subaccount_initiate',
  85. {
  86. account: payload.mainAccount,
  87. },
  88. payload.expiryWindow,
  89. )
  90. expect(signOperation).toHaveBeenNthCalledWith(
  91. 2,
  92. 'subaccount_confirm',
  93. {
  94. signature: 'main-sign',
  95. },
  96. payload.expiryWindow,
  97. )
  98. expect(post).toHaveBeenCalledWith(
  99. baseEndpoints.subaccountCreate,
  100. expect.objectContaining({
  101. main_account: payload.mainAccount,
  102. subaccount: payload.subAccount,
  103. expiry_window: 30000,
  104. main_signature: 'sub-sign',
  105. sub_signature: 'main-sign',
  106. }),
  107. { skipHeaderSig: true },
  108. )
  109. expect(result).toEqual({ success: true })
  110. })
  111. })