eco-solver 0.0.1-security → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of eco-solver might be problematic. Click here for more details.
- package/.eslintignore +8 -0
- package/.eslintrc.js +24 -0
- package/.github/workflows/ci.yaml +38 -0
- package/.nvmrc +1 -0
- package/.prettierignore +3 -0
- package/.prettierrc +8 -0
- package/Dockerfile +11 -0
- package/LICENSE +21 -0
- package/README.md +29 -5
- package/config/default.ts +135 -0
- package/config/development.ts +95 -0
- package/config/preproduction.ts +17 -0
- package/config/production.ts +17 -0
- package/config/staging.ts +17 -0
- package/config/test.ts +7 -0
- package/index.js +43 -0
- package/jest.config.ts +14 -0
- package/nest-cli.json +8 -0
- package/package.json +115 -6
- package/src/api/api.module.ts +27 -0
- package/src/api/balance.controller.ts +41 -0
- package/src/api/quote.controller.ts +54 -0
- package/src/api/tests/balance.controller.spec.ts +113 -0
- package/src/api/tests/quote.controller.spec.ts +83 -0
- package/src/app.module.ts +74 -0
- package/src/balance/balance.module.ts +14 -0
- package/src/balance/balance.service.ts +230 -0
- package/src/balance/balance.ws.service.ts +104 -0
- package/src/balance/types.ts +16 -0
- package/src/bullmq/bullmq.helper.ts +41 -0
- package/src/bullmq/processors/eth-ws.processor.ts +47 -0
- package/src/bullmq/processors/inbox.processor.ts +55 -0
- package/src/bullmq/processors/interval.processor.ts +54 -0
- package/src/bullmq/processors/processor.module.ts +14 -0
- package/src/bullmq/processors/signer.processor.ts +41 -0
- package/src/bullmq/processors/solve-intent.processor.ts +73 -0
- package/src/bullmq/processors/tests/solve-intent.processor.spec.ts +3 -0
- package/src/bullmq/utils/queue.ts +22 -0
- package/src/chain-monitor/chain-monitor.module.ts +12 -0
- package/src/chain-monitor/chain-sync.service.ts +134 -0
- package/src/chain-monitor/tests/chain-sync.service.spec.ts +190 -0
- package/src/commander/.eslintrc.js +6 -0
- package/src/commander/balance/balance-command.module.ts +12 -0
- package/src/commander/balance/balance.command.ts +73 -0
- package/src/commander/command-main.ts +15 -0
- package/src/commander/commander-app.module.ts +31 -0
- package/src/commander/eco-config.command.ts +20 -0
- package/src/commander/safe/safe-command.module.ts +11 -0
- package/src/commander/safe/safe.command.ts +70 -0
- package/src/commander/transfer/client.command.ts +24 -0
- package/src/commander/transfer/transfer-command.module.ts +26 -0
- package/src/commander/transfer/transfer.command.ts +138 -0
- package/src/commander/utils.ts +8 -0
- package/src/common/chains/definitions/arbitrum.ts +12 -0
- package/src/common/chains/definitions/base.ts +21 -0
- package/src/common/chains/definitions/eco.ts +54 -0
- package/src/common/chains/definitions/ethereum.ts +22 -0
- package/src/common/chains/definitions/helix.ts +53 -0
- package/src/common/chains/definitions/mantle.ts +12 -0
- package/src/common/chains/definitions/optimism.ts +22 -0
- package/src/common/chains/definitions/polygon.ts +12 -0
- package/src/common/chains/supported.ts +26 -0
- package/src/common/chains/transport.ts +19 -0
- package/src/common/errors/eco-error.ts +155 -0
- package/src/common/events/constants.ts +3 -0
- package/src/common/events/viem.ts +22 -0
- package/src/common/logging/eco-log-message.ts +74 -0
- package/src/common/redis/constants.ts +55 -0
- package/src/common/redis/redis-connection-utils.ts +106 -0
- package/src/common/routes/constants.ts +3 -0
- package/src/common/utils/objects.ts +34 -0
- package/src/common/utils/strings.ts +49 -0
- package/src/common/utils/tests/objects.spec.ts +23 -0
- package/src/common/utils/tests/strings.spec.ts +22 -0
- package/src/common/viem/contracts.ts +25 -0
- package/src/common/viem/tests/utils.spec.ts +115 -0
- package/src/common/viem/utils.ts +78 -0
- package/src/contracts/ERC20.contract.ts +389 -0
- package/src/contracts/EntryPoint.V6.contract.ts +1309 -0
- package/src/contracts/KernelAccount.abi.ts +87 -0
- package/src/contracts/OwnableExecutor.abi.ts +128 -0
- package/src/contracts/SimpleAccount.contract.ts +524 -0
- package/src/contracts/inbox.ts +8 -0
- package/src/contracts/index.ts +9 -0
- package/src/contracts/intent-source.ts +55 -0
- package/src/contracts/interfaces/index.ts +1 -0
- package/src/contracts/interfaces/prover.interface.ts +22 -0
- package/src/contracts/prover.ts +9 -0
- package/src/contracts/tests/erc20.contract.spec.ts +59 -0
- package/src/contracts/utils.ts +31 -0
- package/src/decoder/decoder.interface.ts +3 -0
- package/src/decoder/tests/utils.spec.ts +36 -0
- package/src/decoder/utils.ts +24 -0
- package/src/decorators/cacheable.decorator.ts +48 -0
- package/src/eco-configs/aws-config.service.ts +75 -0
- package/src/eco-configs/eco-config.module.ts +44 -0
- package/src/eco-configs/eco-config.service.ts +220 -0
- package/src/eco-configs/eco-config.types.ts +278 -0
- package/src/eco-configs/interfaces/config-source.interface.ts +3 -0
- package/src/eco-configs/tests/aws-config.service.spec.ts +52 -0
- package/src/eco-configs/tests/eco-config.service.spec.ts +137 -0
- package/src/eco-configs/tests/utils.spec.ts +84 -0
- package/src/eco-configs/utils.ts +49 -0
- package/src/fee/fee.module.ts +10 -0
- package/src/fee/fee.service.ts +467 -0
- package/src/fee/tests/fee.service.spec.ts +909 -0
- package/src/fee/tests/utils.spec.ts +49 -0
- package/src/fee/types.ts +44 -0
- package/src/fee/utils.ts +23 -0
- package/src/flags/flags.module.ts +10 -0
- package/src/flags/flags.service.ts +112 -0
- package/src/flags/tests/flags.service.spec.ts +68 -0
- package/src/flags/utils.ts +22 -0
- package/src/health/constants.ts +1 -0
- package/src/health/health.controller.ts +23 -0
- package/src/health/health.module.ts +25 -0
- package/src/health/health.service.ts +40 -0
- package/src/health/indicators/balance.indicator.ts +196 -0
- package/src/health/indicators/eco-redis.indicator.ts +23 -0
- package/src/health/indicators/git-commit.indicator.ts +67 -0
- package/src/health/indicators/mongodb.indicator.ts +11 -0
- package/src/health/indicators/permission.indicator.ts +64 -0
- package/src/intent/create-intent.service.ts +129 -0
- package/src/intent/feasable-intent.service.ts +80 -0
- package/src/intent/fulfill-intent.service.ts +318 -0
- package/src/intent/intent.controller.ts +199 -0
- package/src/intent/intent.module.ts +49 -0
- package/src/intent/schemas/intent-call-data.schema.ts +16 -0
- package/src/intent/schemas/intent-data.schema.ts +114 -0
- package/src/intent/schemas/intent-source.schema.ts +33 -0
- package/src/intent/schemas/intent-token-amount.schema.ts +14 -0
- package/src/intent/schemas/reward-data.schema.ts +48 -0
- package/src/intent/schemas/route-data.schema.ts +52 -0
- package/src/intent/schemas/watch-event.schema.ts +32 -0
- package/src/intent/tests/create-intent.service.spec.ts +215 -0
- package/src/intent/tests/feasable-intent.service.spec.ts +155 -0
- package/src/intent/tests/fulfill-intent.service.spec.ts +564 -0
- package/src/intent/tests/utils-intent.service.spec.ts +308 -0
- package/src/intent/tests/utils.spec.ts +62 -0
- package/src/intent/tests/validate-intent.service.spec.ts +297 -0
- package/src/intent/tests/validation.service.spec.ts +337 -0
- package/src/intent/utils-intent.service.ts +168 -0
- package/src/intent/utils.ts +37 -0
- package/src/intent/validate-intent.service.ts +176 -0
- package/src/intent/validation.sevice.ts +223 -0
- package/src/interceptors/big-int.interceptor.ts +30 -0
- package/src/intervals/interval.module.ts +18 -0
- package/src/intervals/retry-infeasable-intents.service.ts +89 -0
- package/src/intervals/tests/retry-infeasable-intents.service.spec.ts +167 -0
- package/src/kms/errors.ts +0 -0
- package/src/kms/kms.module.ts +12 -0
- package/src/kms/kms.service.ts +65 -0
- package/src/kms/tests/kms.service.spec.ts +60 -0
- package/src/liquidity-manager/jobs/check-balances-cron.job.ts +229 -0
- package/src/liquidity-manager/jobs/liquidity-manager.job.ts +52 -0
- package/src/liquidity-manager/jobs/rebalance.job.ts +61 -0
- package/src/liquidity-manager/liquidity-manager.module.ts +29 -0
- package/src/liquidity-manager/processors/base.processor.ts +117 -0
- package/src/liquidity-manager/processors/eco-protocol-intents.processor.ts +34 -0
- package/src/liquidity-manager/processors/grouped-jobs.processor.ts +103 -0
- package/src/liquidity-manager/queues/liquidity-manager.queue.ts +48 -0
- package/src/liquidity-manager/schemas/rebalance-token.schema.ts +32 -0
- package/src/liquidity-manager/schemas/rebalance.schema.ts +32 -0
- package/src/liquidity-manager/services/liquidity-manager.service.ts +188 -0
- package/src/liquidity-manager/services/liquidity-provider.service.ts +25 -0
- package/src/liquidity-manager/services/liquidity-providers/LiFi/lifi-provider.service.spec.ts +125 -0
- package/src/liquidity-manager/services/liquidity-providers/LiFi/lifi-provider.service.ts +117 -0
- package/src/liquidity-manager/services/liquidity-providers/LiFi/utils/get-transaction-hashes.ts +16 -0
- package/src/liquidity-manager/tests/liquidity-manager.service.spec.ts +142 -0
- package/src/liquidity-manager/types/token-state.enum.ts +5 -0
- package/src/liquidity-manager/types/types.d.ts +52 -0
- package/src/liquidity-manager/utils/address.ts +5 -0
- package/src/liquidity-manager/utils/math.ts +9 -0
- package/src/liquidity-manager/utils/serialize.spec.ts +24 -0
- package/src/liquidity-manager/utils/serialize.ts +47 -0
- package/src/liquidity-manager/utils/token.ts +91 -0
- package/src/main.ts +63 -0
- package/src/nest-redlock/nest-redlock.config.ts +14 -0
- package/src/nest-redlock/nest-redlock.interface.ts +5 -0
- package/src/nest-redlock/nest-redlock.module.ts +64 -0
- package/src/nest-redlock/nest-redlock.service.ts +59 -0
- package/src/prover/proof.service.ts +184 -0
- package/src/prover/prover.module.ts +10 -0
- package/src/prover/tests/proof.service.spec.ts +154 -0
- package/src/quote/dto/quote.intent.data.dto.ts +35 -0
- package/src/quote/dto/quote.reward.data.dto.ts +67 -0
- package/src/quote/dto/quote.route.data.dto.ts +71 -0
- package/src/quote/dto/types.ts +18 -0
- package/src/quote/errors.ts +215 -0
- package/src/quote/quote.module.ts +17 -0
- package/src/quote/quote.service.ts +299 -0
- package/src/quote/schemas/quote-call.schema.ts +16 -0
- package/src/quote/schemas/quote-intent.schema.ts +27 -0
- package/src/quote/schemas/quote-reward.schema.ts +24 -0
- package/src/quote/schemas/quote-route.schema.ts +30 -0
- package/src/quote/schemas/quote-token.schema.ts +14 -0
- package/src/quote/tests/quote.service.spec.ts +444 -0
- package/src/sign/atomic-signer.service.ts +24 -0
- package/src/sign/atomic.nonce.service.ts +114 -0
- package/src/sign/kms-account/kmsToAccount.ts +73 -0
- package/src/sign/kms-account/signKms.ts +30 -0
- package/src/sign/kms-account/signKmsTransaction.ts +37 -0
- package/src/sign/kms-account/signKmsTypedData.ts +21 -0
- package/src/sign/nonce.service.ts +89 -0
- package/src/sign/schemas/nonce.schema.ts +36 -0
- package/src/sign/sign.controller.ts +52 -0
- package/src/sign/sign.helper.ts +23 -0
- package/src/sign/sign.module.ts +27 -0
- package/src/sign/signer-kms.service.ts +27 -0
- package/src/sign/signer.service.ts +26 -0
- package/src/solver/filters/tests/valid-smart-wallet.service.spec.ts +87 -0
- package/src/solver/filters/valid-smart-wallet.service.ts +58 -0
- package/src/solver/solver.module.ts +10 -0
- package/src/transaction/multichain-public-client.service.ts +15 -0
- package/src/transaction/smart-wallets/kernel/actions/encodeData.kernel.ts +57 -0
- package/src/transaction/smart-wallets/kernel/create-kernel-client-v2.account.ts +183 -0
- package/src/transaction/smart-wallets/kernel/create.kernel.account.ts +270 -0
- package/src/transaction/smart-wallets/kernel/index.ts +2 -0
- package/src/transaction/smart-wallets/kernel/kernel-account-client-v2.service.ts +90 -0
- package/src/transaction/smart-wallets/kernel/kernel-account-client.service.ts +107 -0
- package/src/transaction/smart-wallets/kernel/kernel-account.client.ts +105 -0
- package/src/transaction/smart-wallets/kernel/kernel-account.config.ts +34 -0
- package/src/transaction/smart-wallets/simple-account/create.simple.account.ts +19 -0
- package/src/transaction/smart-wallets/simple-account/index.ts +2 -0
- package/src/transaction/smart-wallets/simple-account/simple-account-client.service.ts +42 -0
- package/src/transaction/smart-wallets/simple-account/simple-account.client.ts +83 -0
- package/src/transaction/smart-wallets/simple-account/simple-account.config.ts +5 -0
- package/src/transaction/smart-wallets/smart-wallet.types.ts +38 -0
- package/src/transaction/smart-wallets/utils.ts +14 -0
- package/src/transaction/transaction.module.ts +25 -0
- package/src/transaction/viem_multichain_client.service.ts +100 -0
- package/src/transforms/viem-address.decorator.ts +14 -0
- package/src/utils/bigint.ts +44 -0
- package/src/utils/types.ts +18 -0
- package/src/watch/intent/tests/watch-create-intent.service.spec.ts +257 -0
- package/src/watch/intent/tests/watch-fulfillment.service.spec.ts +141 -0
- package/src/watch/intent/watch-create-intent.service.ts +106 -0
- package/src/watch/intent/watch-event.service.ts +133 -0
- package/src/watch/intent/watch-fulfillment.service.ts +115 -0
- package/src/watch/watch.module.ts +13 -0
- package/test/app.e2e-spec.ts +21 -0
- package/test/jest-e2e.json +9 -0
- package/tsconfig.build.json +4 -0
- package/tsconfig.json +29 -0
@@ -0,0 +1,215 @@
|
|
1
|
+
const mockDecodeCreateIntentLog = jest.fn()
|
2
|
+
import { createMock, DeepMocked } from '@golevelup/ts-jest'
|
3
|
+
import { EcoConfigService } from '../../eco-configs/eco-config.service'
|
4
|
+
import { Test, TestingModule } from '@nestjs/testing'
|
5
|
+
import { getModelToken } from '@nestjs/mongoose'
|
6
|
+
import { IntentSourceModel } from '../schemas/intent-source.schema'
|
7
|
+
import { Model } from 'mongoose'
|
8
|
+
import { BullModule, getQueueToken } from '@nestjs/bullmq'
|
9
|
+
import { QUEUES } from '../../common/redis/constants'
|
10
|
+
import { Queue } from 'bullmq'
|
11
|
+
import { CreateIntentService } from '../create-intent.service'
|
12
|
+
import { ValidSmartWalletService } from '../../solver/filters/valid-smart-wallet.service'
|
13
|
+
import { IntentDataModel } from '../schemas/intent-data.schema'
|
14
|
+
import { FlagService } from '../../flags/flags.service'
|
15
|
+
|
16
|
+
jest.mock('../../contracts', () => {
|
17
|
+
return {
|
18
|
+
...jest.requireActual('../../contracts'),
|
19
|
+
decodeCreateIntentLog: mockDecodeCreateIntentLog,
|
20
|
+
}
|
21
|
+
})
|
22
|
+
|
23
|
+
describe('CreateIntentService', () => {
|
24
|
+
let createIntentService: CreateIntentService
|
25
|
+
let validSmartWalletService: DeepMocked<ValidSmartWalletService>
|
26
|
+
let flagService: DeepMocked<FlagService>
|
27
|
+
let ecoConfigService: DeepMocked<EcoConfigService>
|
28
|
+
let intentSourceModel: DeepMocked<Model<IntentSourceModel>>
|
29
|
+
let queue: DeepMocked<Queue>
|
30
|
+
const mockLogDebug = jest.fn()
|
31
|
+
const mockLogLog = jest.fn()
|
32
|
+
|
33
|
+
beforeEach(async () => {
|
34
|
+
const chainMod: TestingModule = await Test.createTestingModule({
|
35
|
+
providers: [
|
36
|
+
CreateIntentService,
|
37
|
+
{ provide: ValidSmartWalletService, useValue: createMock<ValidSmartWalletService>() },
|
38
|
+
{ provide: FlagService, useValue: createMock<FlagService>() },
|
39
|
+
{ provide: EcoConfigService, useValue: createMock<EcoConfigService>() },
|
40
|
+
{
|
41
|
+
provide: getModelToken(IntentSourceModel.name),
|
42
|
+
useValue: createMock<Model<IntentSourceModel>>(),
|
43
|
+
},
|
44
|
+
],
|
45
|
+
imports: [
|
46
|
+
BullModule.registerQueue({
|
47
|
+
name: QUEUES.SOURCE_INTENT.queue,
|
48
|
+
}),
|
49
|
+
],
|
50
|
+
})
|
51
|
+
.overrideProvider(getQueueToken(QUEUES.SOURCE_INTENT.queue))
|
52
|
+
.useValue(createMock<Queue>())
|
53
|
+
.compile()
|
54
|
+
//turn off the services from logging durring testing
|
55
|
+
chainMod.useLogger(false)
|
56
|
+
|
57
|
+
createIntentService = chainMod.get(CreateIntentService)
|
58
|
+
validSmartWalletService = chainMod.get(ValidSmartWalletService)
|
59
|
+
flagService = chainMod.get(FlagService)
|
60
|
+
ecoConfigService = chainMod.get(EcoConfigService)
|
61
|
+
intentSourceModel = chainMod.get(getModelToken(IntentSourceModel.name))
|
62
|
+
queue = chainMod.get(getQueueToken(QUEUES.SOURCE_INTENT.queue))
|
63
|
+
|
64
|
+
createIntentService['logger'].debug = mockLogDebug
|
65
|
+
createIntentService['logger'].log = mockLogLog
|
66
|
+
})
|
67
|
+
|
68
|
+
afterEach(async () => {
|
69
|
+
// restore the spy created with spyOn
|
70
|
+
jest.restoreAllMocks()
|
71
|
+
mockLogDebug.mockClear()
|
72
|
+
mockLogLog.mockClear()
|
73
|
+
})
|
74
|
+
|
75
|
+
describe('on createIntent', () => {
|
76
|
+
const mockEvent = {
|
77
|
+
creator: '0xaaa',
|
78
|
+
data: '0xda',
|
79
|
+
transactionHash: '0x123',
|
80
|
+
topics: ['0x456'],
|
81
|
+
sourceChainID: 85432,
|
82
|
+
}
|
83
|
+
const mockIntent = {
|
84
|
+
reward: { creator: '0xaaa' },
|
85
|
+
hash: mockEvent.transactionHash,
|
86
|
+
logIndex: 1,
|
87
|
+
}
|
88
|
+
beforeEach(() => {
|
89
|
+
mockDecodeCreateIntentLog.mockReturnValue({ hash: mockEvent.transactionHash })
|
90
|
+
const mockIntentSourceEvent = jest.fn()
|
91
|
+
IntentDataModel.fromEvent = mockIntentSourceEvent
|
92
|
+
mockIntentSourceEvent.mockReturnValue(mockIntent)
|
93
|
+
})
|
94
|
+
|
95
|
+
it('should decode the event', async () => {
|
96
|
+
createIntentService.createIntent(mockEvent as any)
|
97
|
+
expect(mockLogDebug).toHaveBeenCalledWith({
|
98
|
+
msg: `createIntent ${mockEvent.transactionHash}`,
|
99
|
+
intentHash: mockEvent.transactionHash,
|
100
|
+
})
|
101
|
+
expect(mockDecodeCreateIntentLog).toHaveBeenCalledWith(mockEvent.data, mockEvent.topics)
|
102
|
+
})
|
103
|
+
|
104
|
+
it('should return if model has already been created in db', async () => {
|
105
|
+
const mockFindOne = jest.fn().mockReturnValue({ hash: mockEvent.transactionHash })
|
106
|
+
intentSourceModel.findOne = mockFindOne
|
107
|
+
await createIntentService.createIntent(mockEvent as any)
|
108
|
+
expect(mockFindOne).toHaveBeenCalledWith({ 'intent.hash': mockEvent.transactionHash })
|
109
|
+
expect(mockLogDebug).toHaveBeenNthCalledWith(2, {
|
110
|
+
msg: `Record for intent already exists ${mockEvent.transactionHash}`,
|
111
|
+
intentHash: mockIntent.hash,
|
112
|
+
intent: mockIntent,
|
113
|
+
})
|
114
|
+
expect(validSmartWalletService.validateSmartWallet).not.toHaveBeenCalled()
|
115
|
+
})
|
116
|
+
|
117
|
+
it('should check if the bendWalletOnly flag is up', async () => {
|
118
|
+
const mockFindOne = jest.fn().mockReturnValue(undefined)
|
119
|
+
intentSourceModel.findOne = mockFindOne
|
120
|
+
const mockFlag = jest.spyOn(flagService, 'getFlagValue').mockReturnValue(false)
|
121
|
+
const mockValidateSmartWallet = jest.fn().mockReturnValue(true)
|
122
|
+
validSmartWalletService.validateSmartWallet = mockValidateSmartWallet
|
123
|
+
await createIntentService.createIntent(mockEvent as any)
|
124
|
+
expect(mockFlag).toHaveBeenCalledTimes(1)
|
125
|
+
expect(mockValidateSmartWallet).toHaveBeenCalledTimes(0)
|
126
|
+
})
|
127
|
+
|
128
|
+
it('should validate the intent is from a bend wallet', async () => {
|
129
|
+
const mockFindOne = jest.fn().mockReturnValue(undefined)
|
130
|
+
intentSourceModel.findOne = mockFindOne
|
131
|
+
const mockValidateSmartWallet = jest.fn().mockReturnValue(true)
|
132
|
+
jest.spyOn(flagService, 'getFlagValue').mockReturnValue(true)
|
133
|
+
validSmartWalletService.validateSmartWallet = mockValidateSmartWallet
|
134
|
+
await createIntentService.createIntent(mockEvent as any)
|
135
|
+
expect(mockValidateSmartWallet).toHaveBeenCalledTimes(1)
|
136
|
+
expect(mockValidateSmartWallet).toHaveBeenCalledWith(
|
137
|
+
mockIntent.reward.creator,
|
138
|
+
mockEvent.sourceChainID,
|
139
|
+
)
|
140
|
+
})
|
141
|
+
|
142
|
+
it('should create an intent model in the database', async () => {
|
143
|
+
const mockFindOne = jest.fn().mockReturnValue(undefined)
|
144
|
+
intentSourceModel.findOne = mockFindOne
|
145
|
+
const mockValidateSmartWallet = jest.fn().mockReturnValue(true)
|
146
|
+
jest.spyOn(flagService, 'getFlagValue').mockReturnValue(true)
|
147
|
+
validSmartWalletService.validateSmartWallet = mockValidateSmartWallet
|
148
|
+
const mockCreate = jest.fn()
|
149
|
+
intentSourceModel.create = mockCreate
|
150
|
+
await createIntentService.createIntent(mockEvent as any)
|
151
|
+
expect(mockCreate).toHaveBeenCalledWith({
|
152
|
+
event: mockEvent,
|
153
|
+
intent: mockIntent,
|
154
|
+
receipt: null,
|
155
|
+
status: 'PENDING',
|
156
|
+
})
|
157
|
+
|
158
|
+
mockCreate.mockClear()
|
159
|
+
mockValidateSmartWallet.mockResolvedValueOnce(false)
|
160
|
+
await createIntentService.createIntent(mockEvent as any)
|
161
|
+
expect(mockCreate).toHaveBeenCalledWith({
|
162
|
+
event: mockEvent,
|
163
|
+
intent: mockIntent,
|
164
|
+
receipt: null,
|
165
|
+
status: 'NON-BEND-WALLET',
|
166
|
+
})
|
167
|
+
})
|
168
|
+
|
169
|
+
it('should not enqueue a job if the intent is not from a bend wallet', async () => {
|
170
|
+
const mockFindOne = jest.fn().mockReturnValue(undefined)
|
171
|
+
const mockQueueAdd = jest.fn()
|
172
|
+
intentSourceModel.findOne = mockFindOne
|
173
|
+
intentSourceModel.create = jest.fn().mockReturnValue({ intent: mockIntent })
|
174
|
+
queue.add = mockQueueAdd
|
175
|
+
jest.spyOn(flagService, 'getFlagValue').mockReturnValue(true)
|
176
|
+
validSmartWalletService.validateSmartWallet = jest.fn().mockReturnValue(false)
|
177
|
+
|
178
|
+
await createIntentService.createIntent(mockEvent as any)
|
179
|
+
expect(mockQueueAdd).not.toHaveBeenCalled()
|
180
|
+
expect(mockLogLog).toHaveBeenNthCalledWith(1, {
|
181
|
+
msg: `Recorded intent ${mockEvent.transactionHash}`,
|
182
|
+
intentHash: mockIntent.hash,
|
183
|
+
intent: mockIntent,
|
184
|
+
validWallet: false,
|
185
|
+
})
|
186
|
+
})
|
187
|
+
|
188
|
+
it('should enqueue a job if the intent is from a bend wallet', async () => {
|
189
|
+
const mockFindOne = jest.fn().mockReturnValue(undefined)
|
190
|
+
const mockQueueAdd = jest.fn()
|
191
|
+
intentSourceModel.findOne = mockFindOne
|
192
|
+
intentSourceModel.create = jest.fn().mockReturnValue({ intent: mockIntent })
|
193
|
+
queue.add = mockQueueAdd
|
194
|
+
jest.spyOn(flagService, 'getFlagValue').mockReturnValue(true)
|
195
|
+
validSmartWalletService.validateSmartWallet = jest.fn().mockReturnValue(true)
|
196
|
+
|
197
|
+
const jobId = `create-${mockIntent.hash}-${mockIntent.logIndex}`
|
198
|
+
await createIntentService.createIntent(mockEvent as any)
|
199
|
+
expect(mockQueueAdd).toHaveBeenCalledTimes(1)
|
200
|
+
expect(mockQueueAdd).toHaveBeenCalledWith(
|
201
|
+
QUEUES.SOURCE_INTENT.jobs.validate_intent,
|
202
|
+
mockIntent.hash,
|
203
|
+
{ jobId },
|
204
|
+
)
|
205
|
+
|
206
|
+
expect(mockLogLog).toHaveBeenNthCalledWith(1, {
|
207
|
+
msg: `Recorded intent ${mockEvent.transactionHash}`,
|
208
|
+
intentHash: mockIntent.hash,
|
209
|
+
intent: mockIntent,
|
210
|
+
validWallet: true,
|
211
|
+
jobId,
|
212
|
+
})
|
213
|
+
})
|
214
|
+
})
|
215
|
+
})
|
@@ -0,0 +1,155 @@
|
|
1
|
+
import { createMock, DeepMocked } from '@golevelup/ts-jest'
|
2
|
+
import { EcoConfigService } from '../../eco-configs/eco-config.service'
|
3
|
+
import { Test, TestingModule } from '@nestjs/testing'
|
4
|
+
import { getModelToken } from '@nestjs/mongoose'
|
5
|
+
import { IntentSourceModel } from '../schemas/intent-source.schema'
|
6
|
+
import { Model } from 'mongoose'
|
7
|
+
import { UtilsIntentService } from '../utils-intent.service'
|
8
|
+
import { BullModule, getQueueToken } from '@nestjs/bullmq'
|
9
|
+
import { QUEUES } from '../../common/redis/constants'
|
10
|
+
import { Queue } from 'bullmq'
|
11
|
+
import { FeasableIntentService } from '../feasable-intent.service'
|
12
|
+
import { Hex } from 'viem'
|
13
|
+
import { FeeService } from '@/fee/fee.service'
|
14
|
+
import { QuoteError } from '@/quote/errors'
|
15
|
+
|
16
|
+
describe('FeasableIntentService', () => {
|
17
|
+
let feasableIntentService: FeasableIntentService
|
18
|
+
let feeService: DeepMocked<FeeService>
|
19
|
+
let utilsIntentService: DeepMocked<UtilsIntentService>
|
20
|
+
let ecoConfigService: DeepMocked<EcoConfigService>
|
21
|
+
let queue: DeepMocked<Queue>
|
22
|
+
const mockLogDebug = jest.fn()
|
23
|
+
const mockLogLog = jest.fn()
|
24
|
+
const mockLogError = jest.fn()
|
25
|
+
const address1 = '0x1111111111111111111111111111111111111111'
|
26
|
+
const address2 = '0x2222222222222222222222222222222222222222'
|
27
|
+
beforeEach(async () => {
|
28
|
+
const chainMod: TestingModule = await Test.createTestingModule({
|
29
|
+
providers: [
|
30
|
+
FeasableIntentService,
|
31
|
+
{ provide: FeeService, useValue: createMock<FeeService>() },
|
32
|
+
{ provide: UtilsIntentService, useValue: createMock<UtilsIntentService>() },
|
33
|
+
{ provide: EcoConfigService, useValue: createMock<EcoConfigService>() },
|
34
|
+
{
|
35
|
+
provide: getModelToken(IntentSourceModel.name),
|
36
|
+
useValue: createMock<Model<IntentSourceModel>>(),
|
37
|
+
},
|
38
|
+
],
|
39
|
+
imports: [
|
40
|
+
BullModule.registerQueue({
|
41
|
+
name: QUEUES.SOURCE_INTENT.queue,
|
42
|
+
}),
|
43
|
+
],
|
44
|
+
})
|
45
|
+
.overrideProvider(getQueueToken(QUEUES.SOURCE_INTENT.queue))
|
46
|
+
.useValue(createMock<Queue>())
|
47
|
+
.compile()
|
48
|
+
|
49
|
+
feasableIntentService = chainMod.get(FeasableIntentService)
|
50
|
+
feeService = chainMod.get(FeeService)
|
51
|
+
utilsIntentService = chainMod.get(UtilsIntentService)
|
52
|
+
ecoConfigService = chainMod.get(EcoConfigService)
|
53
|
+
queue = chainMod.get(getQueueToken(QUEUES.SOURCE_INTENT.queue))
|
54
|
+
|
55
|
+
feasableIntentService['logger'].debug = mockLogDebug
|
56
|
+
feasableIntentService['logger'].log = mockLogLog
|
57
|
+
feasableIntentService['logger'].error = mockLogError
|
58
|
+
})
|
59
|
+
|
60
|
+
const mockData = { model: { intent: { logIndex: 1, hash: '0x123' as Hex } }, solver: {} }
|
61
|
+
const intentHash = mockData.model.intent.hash
|
62
|
+
const jobId = `feasable-${intentHash}-${mockData.model.intent.logIndex}`
|
63
|
+
afterEach(async () => {
|
64
|
+
// restore the spy created with spyOn
|
65
|
+
jest.restoreAllMocks()
|
66
|
+
mockLogDebug.mockClear()
|
67
|
+
mockLogLog.mockClear()
|
68
|
+
})
|
69
|
+
|
70
|
+
describe('onModuleInit', () => {
|
71
|
+
it('should set the intentJobConfig', async () => {
|
72
|
+
const mockConfig = { foo: 'bar' }
|
73
|
+
jest
|
74
|
+
.spyOn(ecoConfigService, 'getRedis')
|
75
|
+
.mockReturnValue({ jobs: { intentJobConfig: mockConfig } } as any)
|
76
|
+
await feasableIntentService.onModuleInit()
|
77
|
+
expect(feasableIntentService['intentJobConfig']).toEqual(mockConfig)
|
78
|
+
})
|
79
|
+
})
|
80
|
+
|
81
|
+
describe('on feasableIntent', () => {
|
82
|
+
it('should error out if processing intent data fails', async () => {
|
83
|
+
jest.spyOn(utilsIntentService, 'getIntentProcessData').mockResolvedValue(undefined)
|
84
|
+
await expect(feasableIntentService.feasableIntent(intentHash)).resolves.not.toThrow()
|
85
|
+
|
86
|
+
const error = new Error('noo')
|
87
|
+
jest
|
88
|
+
.spyOn(utilsIntentService, 'getIntentProcessData')
|
89
|
+
.mockResolvedValue({ err: error } as any)
|
90
|
+
await expect(feasableIntentService.feasableIntent(intentHash)).rejects.toThrow(error)
|
91
|
+
})
|
92
|
+
|
93
|
+
it('should fail if intent has more than 1 target call', async () => {
|
94
|
+
const mockModel = {
|
95
|
+
intent: {
|
96
|
+
route: {
|
97
|
+
calls: [
|
98
|
+
{ data: '0x', target: address1 },
|
99
|
+
{ data: '0x', target: address2 },
|
100
|
+
],
|
101
|
+
},
|
102
|
+
logIndex: 1,
|
103
|
+
},
|
104
|
+
}
|
105
|
+
const errData = { solver: mockData.solver, model: mockModel } as any
|
106
|
+
jest.spyOn(utilsIntentService, 'getIntentProcessData').mockResolvedValue(errData)
|
107
|
+
jest.spyOn(feeService, 'isRouteFeasible').mockResolvedValue({
|
108
|
+
error: QuoteError.MultiFulfillRoute(),
|
109
|
+
} as any)
|
110
|
+
await feasableIntentService.feasableIntent(intentHash)
|
111
|
+
expect(utilsIntentService.updateInfeasableIntentModel).toHaveBeenCalledWith(
|
112
|
+
errData.model,
|
113
|
+
QuoteError.MultiFulfillRoute(),
|
114
|
+
)
|
115
|
+
expect(mockLogDebug).toHaveBeenCalledTimes(2)
|
116
|
+
expect(mockLogDebug).toHaveBeenNthCalledWith(2, {
|
117
|
+
msg: `FeasableIntent intent ${intentHash}`,
|
118
|
+
feasable: false,
|
119
|
+
})
|
120
|
+
expect(queue.add).not.toHaveBeenCalled()
|
121
|
+
})
|
122
|
+
|
123
|
+
it('should update the db intent model if the intent is not feasable', async () => {
|
124
|
+
jest.spyOn(utilsIntentService, 'getIntentProcessData').mockResolvedValue(mockData as any)
|
125
|
+
jest
|
126
|
+
.spyOn(feeService, 'isRouteFeasible')
|
127
|
+
.mockResolvedValue({ error: QuoteError.MultiFulfillRoute() })
|
128
|
+
|
129
|
+
await feasableIntentService.feasableIntent(intentHash)
|
130
|
+
|
131
|
+
expect(utilsIntentService.updateInfeasableIntentModel).toHaveBeenCalledWith(
|
132
|
+
mockData.model,
|
133
|
+
QuoteError.MultiFulfillRoute(),
|
134
|
+
)
|
135
|
+
})
|
136
|
+
|
137
|
+
it('should add the intent when its feasable to the queue to be processed', async () => {
|
138
|
+
jest.spyOn(utilsIntentService, 'getIntentProcessData').mockResolvedValue(mockData as any)
|
139
|
+
jest.spyOn(feeService, 'isRouteFeasible').mockResolvedValue({ calls: [] } as any)
|
140
|
+
|
141
|
+
await feasableIntentService.feasableIntent(intentHash)
|
142
|
+
|
143
|
+
expect(mockLogDebug).toHaveBeenCalledTimes(2)
|
144
|
+
expect(mockLogDebug).toHaveBeenNthCalledWith(2, {
|
145
|
+
msg: `FeasableIntent intent ${intentHash}`,
|
146
|
+
feasable: true,
|
147
|
+
jobId,
|
148
|
+
})
|
149
|
+
expect(queue.add).toHaveBeenCalledWith(QUEUES.SOURCE_INTENT.jobs.fulfill_intent, intentHash, {
|
150
|
+
jobId,
|
151
|
+
...feasableIntentService['intentJobConfig'],
|
152
|
+
})
|
153
|
+
})
|
154
|
+
})
|
155
|
+
})
|