From 4d5550e98baedda48998609a67bfad1560ae0a37 Mon Sep 17 00:00:00 2001 From: Vladimir Date: Fri, 12 Apr 2024 16:46:32 +0300 Subject: [PATCH] fix(api): response types (#87) --- package.json | 4 +- pnpm-lock.yaml | 101 ++++++++++------------ src/api/orders/types.ts | 2 + src/fusion-order/fusion-extension.spec.ts | 54 ++++++++++++ src/fusion-order/fusion-extension.ts | 57 ++++++++++-- 5 files changed, 156 insertions(+), 62 deletions(-) create mode 100644 src/fusion-order/fusion-extension.spec.ts diff --git a/package.json b/package.json index d0d408d..bd967b8 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,8 @@ "changelog:generate": "changelog generate -a" }, "dependencies": { - "@1inch/byte-utils": "2.2.0", - "@1inch/limit-order-sdk": "^4.8.2", + "@1inch/byte-utils": "2.2.1", + "@1inch/limit-order-sdk": "^4.8.3", "@metamask/eth-sig-util": "^5.1.0", "bn.js": "^5.2.1", "ethers": "6.11.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dad0652..049e02f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: '6.0' +lockfileVersion: '6.1' settings: autoInstallPeers: true @@ -6,11 +6,11 @@ settings: dependencies: '@1inch/byte-utils': - specifier: 2.2.0 - version: 2.2.0 + specifier: 2.2.1 + version: 2.2.1 '@1inch/limit-order-sdk': - specifier: ^4.8.2 - version: 4.8.2(assert@2.1.0)(axios@1.6.8) + specifier: ^4.8.3 + version: 4.8.3(assert@2.1.0)(axios@1.6.8) '@metamask/eth-sig-util': specifier: ^5.1.0 version: 5.1.0 @@ -105,20 +105,15 @@ devDependencies: version: 2.6.1 ts-node: specifier: ^10.9.2 - version: 10.9.2(@swc/core@1.3.66)(@types/node@20.12.4)(typescript@4.9.4) + version: 10.9.2(@swc/core@1.3.66)(@types/node@20.12.7)(typescript@4.9.4) typescript: specifier: 4.9.4 version: 4.9.4 packages: - /@1inch/byte-utils@2.0.0: - resolution: {integrity: sha512-CcEsI6At09oqWDFrZNUTokbiOVUG0HNkkAPIhHo6rMPG+1m4Zls+kSWtotFUpy7tp0PUby/PmrOkqZgk/hFq1A==} - engines: {node: '>=18.16.0'} - dev: false - - /@1inch/byte-utils@2.2.0: - resolution: {integrity: sha512-oy9GTjIRtAXB0PGvIEONu4z7fjmiGDLcn2Oq7RehWGpd4qwU2osE4x5KQL8lTTyCaGlKXXQH2WaG1c7ezpT3YQ==} + /@1inch/byte-utils@2.2.1: + resolution: {integrity: sha512-ESIUUGcRu8cL+rFEJedSLOMMXUmLC3A0zyHcWH1fxLAzUsY+bdjqUX/jWQIbOqg+k1XKyXBu6vkREDna3JCp6w==} engines: {node: '>=18.16.0'} dev: false @@ -155,8 +150,8 @@ packages: typescript: 4.9.4 dev: true - /@1inch/limit-order-sdk@4.8.2(assert@2.1.0)(axios@1.6.8): - resolution: {integrity: sha512-rWszXyULUrenm5apgRSMPsCn3iW6GHaw5z72Gydy2VPIBMmET0Ow+MmBBvBSMthOf45H1bHHFiNU91nuLHtnYA==} + /@1inch/limit-order-sdk@4.8.3(assert@2.1.0)(axios@1.6.8): + resolution: {integrity: sha512-xsqbPkiPGt/xKu+m5rTiuS8xVzE2p4TDzjNy+Ns8z2LaWhDjJd8D07c+2xSXEFaRbjEwEfV9VfRqPiIRdewBFg==} engines: {node: '>=18.16.0'} peerDependencies: assert: ^2.0.0 @@ -167,7 +162,7 @@ packages: axios: optional: true dependencies: - '@1inch/byte-utils': 2.0.0 + '@1inch/byte-utils': 2.2.1 '@metamask/eth-sig-util': 5.1.0 assert: 2.1.0 axios: 1.6.8 @@ -619,7 +614,7 @@ packages: engines: {node: '>= 10.14.2'} dependencies: '@jest/types': 26.6.2 - '@types/node': 20.12.4 + '@types/node': 20.12.7 chalk: 4.1.2 jest-message-util: 26.6.2 jest-util: 26.6.2 @@ -635,7 +630,7 @@ packages: '@jest/test-result': 26.6.2 '@jest/transform': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 20.12.4 + '@types/node': 20.12.7 ansi-escapes: 4.3.2 chalk: 4.1.2 exit: 0.1.2 @@ -679,7 +674,7 @@ packages: dependencies: '@jest/fake-timers': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 20.12.4 + '@types/node': 20.12.7 jest-mock: 26.6.2 dev: true @@ -689,7 +684,7 @@ packages: dependencies: '@jest/types': 26.6.2 '@sinonjs/fake-timers': 6.0.1 - '@types/node': 20.12.4 + '@types/node': 20.12.7 jest-message-util: 26.6.2 jest-mock: 26.6.2 jest-util: 26.6.2 @@ -803,7 +798,7 @@ packages: dependencies: '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.12.4 + '@types/node': 20.12.7 '@types/yargs': 15.0.19 chalk: 4.1.2 dev: true @@ -814,7 +809,7 @@ packages: dependencies: '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.12.4 + '@types/node': 20.12.7 '@types/yargs': 16.0.9 chalk: 4.1.2 dev: true @@ -1130,12 +1125,12 @@ packages: /@types/eslint-scope@3.7.7: resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} dependencies: - '@types/eslint': 8.56.7 + '@types/eslint': 8.56.9 '@types/estree': 1.0.5 dev: true - /@types/eslint@8.56.7: - resolution: {integrity: sha512-SjDvI/x3zsZnOkYZ3lCt9lOZWZLB2jIlNKz+LBgCtDurK0JZcwucxYHn1w2BJkD34dgX9Tjnak0txtq4WTggEA==} + /@types/eslint@8.56.9: + resolution: {integrity: sha512-W4W3KcqzjJ0sHg2vAq9vfml6OhsJ53TcUjUqfzzZf/EChUtwspszj/S0pzMxnfRcO55/iGq47dscXw71Fxc4Zg==} dependencies: '@types/estree': 1.0.5 '@types/json-schema': 7.0.15 @@ -1148,7 +1143,7 @@ packages: /@types/graceful-fs@4.1.9: resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} dependencies: - '@types/node': 20.12.4 + '@types/node': 20.12.7 dev: true /@types/istanbul-lib-coverage@2.0.6: @@ -1186,8 +1181,8 @@ packages: resolution: {integrity: sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==} dev: false - /@types/node@20.12.4: - resolution: {integrity: sha512-E+Fa9z3wSQpzgYQdYmme5X3OTuejnnTx88A6p6vkkJosR3KBz+HpE3kqNm98VE6cfLFcISx7zW7MsJkH6KwbTw==} + /@types/node@20.12.7: + resolution: {integrity: sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==} dependencies: undici-types: 5.26.5 dev: true @@ -1203,7 +1198,7 @@ packages: /@types/prompts@2.4.9: resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==} dependencies: - '@types/node': 20.12.4 + '@types/node': 20.12.7 kleur: 3.0.3 dev: true @@ -1218,7 +1213,7 @@ packages: /@types/ws@8.5.10: resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} dependencies: - '@types/node': 20.12.4 + '@types/node': 20.12.7 dev: true /@types/yargs-parser@21.0.3: @@ -1911,8 +1906,8 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001605 - electron-to-chromium: 1.4.726 + caniuse-lite: 1.0.30001609 + electron-to-chromium: 1.4.735 node-releases: 2.0.14 update-browserslist-db: 1.0.13(browserslist@4.23.0) dev: true @@ -1932,8 +1927,8 @@ packages: engines: {node: '>=6'} dev: true - /builtins@5.0.1: - resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} + /builtins@5.1.0: + resolution: {integrity: sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==} dependencies: semver: 7.6.0 dev: true @@ -1978,8 +1973,8 @@ packages: engines: {node: '>=10'} dev: true - /caniuse-lite@1.0.30001605: - resolution: {integrity: sha512-nXwGlFWo34uliI9z3n6Qc0wZaf7zaZWA1CPZ169La5mV3I/gem7bst0vr5XQH5TJXZIMfDeZyOrZnSlVzKxxHQ==} + /caniuse-lite@1.0.30001609: + resolution: {integrity: sha512-JFPQs34lHKx1B5t1EpQpWH4c+29zIyn/haGsbpfq3suuV9v56enjFt23zqijxGTMwy1p/4H2tjnQMY+p1WoAyA==} dev: true /capture-exit@2.0.0: @@ -2329,8 +2324,8 @@ packages: webidl-conversions: 5.0.0 dev: true - /electron-to-chromium@1.4.726: - resolution: {integrity: sha512-xtjfBXn53RORwkbyKvDfTajtnTp0OJoPOIBzXvkNbb7+YYvCHJflba3L7Txyx/6Fov3ov2bGPr/n5MTixmPhdQ==} + /electron-to-chromium@1.4.735: + resolution: {integrity: sha512-pkYpvwg8VyOTQAeBqZ7jsmpCjko1Qc6We1ZtZCjRyYbT5v4AIUKDy5cQTRotQlSSZmMr8jqpEt6JtOj5k7lR7A==} dev: true /emittery@0.7.2: @@ -2639,7 +2634,7 @@ packages: eslint: '>=7.0.0' dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.41.0) - builtins: 5.0.1 + builtins: 5.1.0 eslint: 8.41.0 eslint-plugin-es-x: 7.6.0(eslint@8.41.0) get-tsconfig: 4.7.3 @@ -3864,7 +3859,7 @@ packages: jest-validate: 26.6.2 micromatch: 4.0.5 pretty-format: 26.6.2 - ts-node: 10.9.2(@swc/core@1.3.66)(@types/node@20.12.4)(typescript@4.9.4) + ts-node: 10.9.2(@swc/core@1.3.66)(@types/node@20.12.7)(typescript@4.9.4) transitivePeerDependencies: - bufferutil - canvas @@ -3907,7 +3902,7 @@ packages: '@jest/environment': 26.6.2 '@jest/fake-timers': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 20.12.4 + '@types/node': 20.12.7 jest-mock: 26.6.2 jest-util: 26.6.2 jsdom: 16.7.0 @@ -3925,7 +3920,7 @@ packages: '@jest/environment': 26.6.2 '@jest/fake-timers': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 20.12.4 + '@types/node': 20.12.7 jest-mock: 26.6.2 jest-util: 26.6.2 dev: true @@ -3941,7 +3936,7 @@ packages: dependencies: '@jest/types': 26.6.2 '@types/graceful-fs': 4.1.9 - '@types/node': 20.12.4 + '@types/node': 20.12.7 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -3967,7 +3962,7 @@ packages: '@jest/source-map': 26.6.2 '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 20.12.4 + '@types/node': 20.12.7 chalk: 4.1.2 co: 4.6.0 expect: 26.6.2 @@ -4026,7 +4021,7 @@ packages: engines: {node: '>= 10.14.2'} dependencies: '@jest/types': 26.6.2 - '@types/node': 20.12.4 + '@types/node': 20.12.7 dev: true /jest-pnp-resolver@1.2.3(jest-resolve@26.6.2): @@ -4079,7 +4074,7 @@ packages: '@jest/environment': 26.6.2 '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 20.12.4 + '@types/node': 20.12.7 chalk: 4.1.2 emittery: 0.7.2 exit: 0.1.2 @@ -4147,7 +4142,7 @@ packages: resolution: {integrity: sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==} engines: {node: '>= 10.14.2'} dependencies: - '@types/node': 20.12.4 + '@types/node': 20.12.7 graceful-fs: 4.2.11 dev: true @@ -4180,7 +4175,7 @@ packages: engines: {node: '>= 10.14.2'} dependencies: '@jest/types': 26.6.2 - '@types/node': 20.12.4 + '@types/node': 20.12.7 chalk: 4.1.2 graceful-fs: 4.2.11 is-ci: 2.0.0 @@ -4205,7 +4200,7 @@ packages: dependencies: '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 20.12.4 + '@types/node': 20.12.7 ansi-escapes: 4.3.2 chalk: 4.1.2 jest-util: 26.6.2 @@ -4216,7 +4211,7 @@ packages: resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 20.12.4 + '@types/node': 20.12.7 merge-stream: 2.0.0 supports-color: 7.2.0 dev: true @@ -4225,7 +4220,7 @@ packages: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 20.12.4 + '@types/node': 20.12.7 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true @@ -5632,7 +5627,7 @@ packages: lodash: 4.17.21 dev: true - /ts-node@10.9.2(@swc/core@1.3.66)(@types/node@20.12.4)(typescript@4.9.4): + /ts-node@10.9.2(@swc/core@1.3.66)(@types/node@20.12.7)(typescript@4.9.4): resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true peerDependencies: @@ -5652,7 +5647,7 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.12.4 + '@types/node': 20.12.7 acorn: 8.11.3 acorn-walk: 8.3.2 arg: 4.1.3 diff --git a/src/api/orders/types.ts b/src/api/orders/types.ts index d579ab8..7643cc7 100644 --- a/src/api/orders/types.ts +++ b/src/api/orders/types.ts @@ -21,6 +21,7 @@ export type ActiveOrder = { auctionEndDate: string remainingMakerAmount: string order: LimitOrderV4Struct + extension: string } export type ActiveOrdersResponse = PaginationOutput @@ -50,6 +51,7 @@ export type Fill = { export type OrderStatusResponse = { status: OrderStatus order: LimitOrderV4Struct + extension: string points: AuctionPoint[] | null fills: Fill[] auctionStartDate: number diff --git a/src/fusion-order/fusion-extension.spec.ts b/src/fusion-order/fusion-extension.spec.ts new file mode 100644 index 0000000..0c7528b --- /dev/null +++ b/src/fusion-order/fusion-extension.spec.ts @@ -0,0 +1,54 @@ +import {Address} from '@1inch/limit-order-sdk' +import {FusionOrder} from './fusion-order' +import {AuctionDetails} from './auction-details' +import {FusionExtension} from './fusion-extension' + +describe('FusionExtension', () => { + it('should decode', () => { + const extensionContract = new Address( + '0x8273f37417da37c4a6c3995e82cf442f87a25d9c' + ) + + const order = FusionOrder.new( + extensionContract, + { + makerAsset: new Address( + '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' + ), + takerAsset: new Address( + '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' + ), + makingAmount: 1000000000000000000n, + takingAmount: 1420000000n, + maker: new Address( + '0x00000000219ab540356cbb839cbe05303d7705fa' + ), + salt: 10n + }, + { + auction: new AuctionDetails({ + duration: 180n, + startTime: 1673548149n, + initialRateBump: 50000, + points: [ + { + coefficient: 20000, + delay: 12 + } + ] + }), + whitelist: [ + { + address: new Address( + '0x00000000219ab540356cbb839cbe05303d7705fa' + ), + allowFrom: 0n + } + ], + resolvingStartTime: 1673548139n + } + ) + const fusionExtension = FusionExtension.decode(order.extension.encode()) + expect(fusionExtension).toStrictEqual(order.fusionExtension) + }) +}) diff --git a/src/fusion-order/fusion-extension.ts b/src/fusion-order/fusion-extension.ts index d60b1a7..c01429c 100644 --- a/src/fusion-order/fusion-extension.ts +++ b/src/fusion-order/fusion-extension.ts @@ -4,27 +4,70 @@ import { ExtensionBuilder, Interaction } from '@1inch/limit-order-sdk' +import assert from 'assert' + import {AuctionDetails} from './auction-details' import {SettlementPostInteractionData} from './settlement-post-interaction-data' -export class FusionExtension extends ExtensionBuilder { +export class FusionExtension { + private readonly builder = new ExtensionBuilder() + constructor( public readonly address: Address, public readonly auctionDetails: AuctionDetails, public readonly postInteractionData: SettlementPostInteractionData ) { - super() - } - - public build(): Extension { const detailsBytes = this.auctionDetails.encode() - this.withMakingAmountData(this.address, detailsBytes) + this.builder + .withMakingAmountData(this.address, detailsBytes) .withTakingAmountData(this.address, detailsBytes) .withPostInteraction( new Interaction(this.address, this.postInteractionData.encode()) ) + } + + /** + * Create `FusionExtension` from bytes + * + * @param bytes 0x prefixed bytes + */ + public static decode(bytes: string): FusionExtension { + const extension = Extension.decode(bytes) + + const settlementContract = Address.fromFirstBytes( + extension.makingAmountData + ) + + assert( + Address.fromFirstBytes(extension.takingAmountData).equal( + settlementContract + ) && + Address.fromFirstBytes(extension.postInteraction).equal( + settlementContract + ), + 'Invalid extension, all calls should be to the same address' + ) - return super.build() + const auctionDetails = AuctionDetails.fromExtension(extension) + + const postInteractionData = + SettlementPostInteractionData.fromExtension(extension) + + return new FusionExtension( + settlementContract, + auctionDetails, + postInteractionData + ) + } + + withMakerPermit(tokenFrom: Address, permitData: string): this { + this.builder.withMakerPermit(tokenFrom, permitData) + + return this + } + + public build(): Extension { + return this.builder.build() } }