diff --git a/src/api/orders/order-api.spec.ts b/src/api/orders/order-api.spec.ts index 6ca7795..3c16563 100644 --- a/src/api/orders/order-api.spec.ts +++ b/src/api/orders/order-api.spec.ts @@ -102,7 +102,7 @@ describe(__filename, () => { expect(response).toEqual(expected) expect(httpProvider.get).toHaveBeenLastCalledWith( - `${url}/orders/v1.0/1/order/active/?page=1&limit=2` + `${url}/orders/v2.0/1/order/active/?page=1&limit=2` ) }) @@ -175,7 +175,7 @@ describe(__filename, () => { expect(response).toEqual(expected) expect(httpProvider.get).toHaveBeenLastCalledWith( - `${url}/orders/v1.0/1/order/active/?` + `${url}/orders/v2.0/1/order/active/?` ) }) }) @@ -225,7 +225,7 @@ describe(__filename, () => { expect(response).toEqual(expected) expect(httpProvider.get).toHaveBeenLastCalledWith( - `${url}/orders/v1.0/1/order/status/${orderHash}` + `${url}/orders/v2.0/1/order/status/${orderHash}` ) }) @@ -377,7 +377,7 @@ describe(__filename, () => { expect(response).toEqual(expected) expect(httpProvider.get).toHaveBeenLastCalledWith( - `${url}/orders/v1.0/1/order/maker/${address}/?limit=1&page=1` + `${url}/orders/v2.0/1/order/maker/${address}/?limit=1&page=1` ) }) @@ -433,7 +433,7 @@ describe(__filename, () => { expect(response).toEqual(expected) expect(httpProvider.get).toHaveBeenLastCalledWith( - `${url}/orders/v1.0/1/order/maker/${address}/?` + `${url}/orders/v2.0/1/order/maker/${address}/?` ) }) diff --git a/src/api/orders/orders.api.ts b/src/api/orders/orders.api.ts index 8e4181c..ea4284a 100644 --- a/src/api/orders/orders.api.ts +++ b/src/api/orders/orders.api.ts @@ -13,6 +13,8 @@ import {AxiosProviderConnector, HttpProviderConnector} from '../../connector' import {concatQueryParams} from '../params' export class OrdersApi { + private static Version = 'v2.0' + constructor( private readonly config: OrdersApiConfig, private readonly httpClient: HttpProviderConnector @@ -37,7 +39,7 @@ export class OrdersApi { } const queryParams = concatQueryParams(params.build()) - const url = `${this.config.url}/v1.0/${this.config.network}/order/active/${queryParams}` + const url = `${this.config.url}/${OrdersApi.Version}/${this.config.network}/order/active/${queryParams}` return this.httpClient.get(url) } @@ -51,7 +53,7 @@ export class OrdersApi { throw new Error(err) } - const url = `${this.config.url}/v1.0/${this.config.network}/order/status/${params.orderHash}` + const url = `${this.config.url}/${OrdersApi.Version}/${this.config.network}/order/status/${params.orderHash}` return this.httpClient.get(url) } @@ -66,7 +68,7 @@ export class OrdersApi { } const queryParams = concatQueryParams(params.buildQueryParams()) - const url = `${this.config.url}/v1.0/${this.config.network}/order/maker/${params.address}/${queryParams}` + const url = `${this.config.url}/${OrdersApi.Version}/${this.config.network}/order/maker/${params.address}/${queryParams}` return this.httpClient.get(url) } diff --git a/src/api/quoter/quote/quote.ts b/src/api/quoter/quote/quote.ts index f60cc7a..9c82540 100644 --- a/src/api/quoter/quote/quote.ts +++ b/src/api/quoter/quote/quote.ts @@ -1,4 +1,5 @@ -import {Address} from '@1inch/limit-order-sdk' +import {Address, randBigInt} from '@1inch/limit-order-sdk' +import {UINT_40_MAX} from '@1inch/byte-utils' import {FusionOrderParams} from './order-params' import {FusionOrderParamsData} from './types' import {Cost, PresetEnum, QuoterResponse} from '../types' @@ -76,6 +77,16 @@ export class Quote { params.delayAuctionStartTimeBy ) + const allowPartialFills = + paramsData?.allowPartialFills ?? preset.allowPartialFills + const allowMultipleFills = + paramsData?.allowMultipleFills ?? preset.allowMultipleFills + const isNonceRequired = !allowPartialFills || !allowMultipleFills + + const nonce = isNonceRequired + ? params.nonce ?? randBigInt(UINT_40_MAX) + : params.nonce + return FusionOrder.new( this.settlementAddress, { @@ -103,15 +114,13 @@ export class Quote { ) }, { - nonce: params.nonce, + nonce, unwrapWETH: this.params.toTokenAddress.isNative(), permit: params.permit ? this.params.fromTokenAddress + params.permit.substring(2) : undefined, - allowPartialFills: - paramsData?.allowPartialFills ?? preset.allowPartialFills, - allowMultipleFills: - paramsData?.allowMultipleFills ?? preset.allowMultipleFills, + allowPartialFills, + allowMultipleFills, orderExpirationDelay: paramsData?.orderExpirationDelay } ) diff --git a/src/api/quoter/quoter.api.spec.ts b/src/api/quoter/quoter.api.spec.ts index b09770c..7e2bb8d 100644 --- a/src/api/quoter/quoter.api.spec.ts +++ b/src/api/quoter/quoter.api.spec.ts @@ -135,7 +135,7 @@ describe('Quoter API', () => { expect(res).toStrictEqual(QuoterResponseMock) expect(httpProvider.get).toHaveBeenCalledWith( - 'https://test.com/quoter/v1.0/1/quote/receive/?fromTokenAddress=0x6b175474e89094c44da98b954eedeac495271d0f&toTokenAddress=0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2&amount=1000000000000000000000&walletAddress=0x00000000219ab540356cbb839cbe05303d7705fa&source=sdk' + 'https://test.com/quoter/v2.0/1/quote/receive/?fromTokenAddress=0x6b175474e89094c44da98b954eedeac495271d0f&toTokenAddress=0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2&amount=1000000000000000000000&walletAddress=0x00000000219ab540356cbb839cbe05303d7705fa&source=sdk' ) }) @@ -161,7 +161,7 @@ describe('Quoter API', () => { const res = await quoter.getQuote(params) expect(res).toStrictEqual(QuoterResponseMock) expect(httpProvider.get).toHaveBeenCalledWith( - 'https://test.com/quoter/v1.0/1/quote/receive/?fromTokenAddress=0x6b175474e89094c44da98b954eedeac495271d0f&toTokenAddress=0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2&amount=1000000000000000000000&walletAddress=0x00000000219ab540356cbb839cbe05303d7705fa&fee=1&source=0x6b175474e89094c44da98b954eedeac495271d0f' + 'https://test.com/quoter/v2.0/1/quote/receive/?fromTokenAddress=0x6b175474e89094c44da98b954eedeac495271d0f&toTokenAddress=0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2&amount=1000000000000000000000&walletAddress=0x00000000219ab540356cbb839cbe05303d7705fa&fee=1&source=0x6b175474e89094c44da98b954eedeac495271d0f' ) }) @@ -199,7 +199,7 @@ describe('Quoter API', () => { const res = await quoter.getQuoteWithCustomPreset(params, body) expect(res).toStrictEqual(QuoterResponseMock) expect(httpProvider.post).toHaveBeenCalledWith( - 'https://test.com/quoter/v1.0/1/quote/receive/?fromTokenAddress=0x6b175474e89094c44da98b954eedeac495271d0f&toTokenAddress=0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2&amount=1000000000000000000000&walletAddress=0x00000000219ab540356cbb839cbe05303d7705fa&fee=1&source=0x6b175474e89094c44da98b954eedeac495271d0f', + 'https://test.com/quoter/v2.0/1/quote/receive/?fromTokenAddress=0x6b175474e89094c44da98b954eedeac495271d0f&toTokenAddress=0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2&amount=1000000000000000000000&walletAddress=0x00000000219ab540356cbb839cbe05303d7705fa&fee=1&source=0x6b175474e89094c44da98b954eedeac495271d0f', body.build() ) }) diff --git a/src/api/quoter/quoter.api.ts b/src/api/quoter/quoter.api.ts index 17e2521..6dfd09e 100644 --- a/src/api/quoter/quoter.api.ts +++ b/src/api/quoter/quoter.api.ts @@ -6,6 +6,8 @@ import {concatQueryParams} from '../params' import {AxiosProviderConnector, HttpProviderConnector} from '../../connector' export class QuoterApi { + private static Version = 'v2.0' + constructor( private readonly config: QuoterApiConfig, private readonly httpClient: HttpProviderConnector @@ -22,7 +24,7 @@ export class QuoterApi { async getQuote(params: QuoterRequest): Promise { const queryParams = concatQueryParams(params.build()) - const url = `${this.config.url}/v1.0/${this.config.network}/quote/receive/${queryParams}` + const url = `${this.config.url}/${QuoterApi.Version}/${this.config.network}/quote/receive/${queryParams}` const res = await this.httpClient.get(url) @@ -41,7 +43,7 @@ export class QuoterApi { const queryParams = concatQueryParams(params.build()) const bodyParams = body.build() - const url = `${this.config.url}/v1.0/${this.config.network}/quote/receive/${queryParams}` + const url = `${this.config.url}/${QuoterApi.Version}/${this.config.network}/quote/receive/${queryParams}` const res = await this.httpClient.post(url, bodyParams) diff --git a/src/api/relayer/relayer.api.spec.ts b/src/api/relayer/relayer.api.spec.ts index e0e36f5..93bf407 100644 --- a/src/api/relayer/relayer.api.spec.ts +++ b/src/api/relayer/relayer.api.spec.ts @@ -34,7 +34,8 @@ describe('Relayer API', () => { makerTraits: '0' }, signature: '0x123signature-here789', - quoteId: '9a43c86d-f3d7-45b9-8cb6-803d2bdfa08b' + quoteId: '9a43c86d-f3d7-45b9-8cb6-803d2bdfa08b', + extension: '0x' } const params = RelayerRequest.new(orderData) @@ -42,7 +43,7 @@ describe('Relayer API', () => { await quoter.submit(params) expect(httpProvider.post).toHaveBeenCalledWith( - 'https://test.com/relayer/v1.0/1/order/submit', + 'https://test.com/relayer/v2.0/1/order/submit', orderData ) }) @@ -68,7 +69,8 @@ describe('Relayer API', () => { makerTraits: '0' }, signature: '0x123signature-here789', - quoteId: '9a43c86d-f3d7-45b9-8cb6-803d2bdfa08b' + quoteId: '9a43c86d-f3d7-45b9-8cb6-803d2bdfa08b', + extension: '0x' } const orderData2: RelayerRequestParams = { @@ -83,7 +85,8 @@ describe('Relayer API', () => { makerTraits: '0' }, signature: '0x123signature-2-here789', - quoteId: '1a36c861-ffd7-45b9-1cb6-403d3bdfa084' + quoteId: '1a36c861-ffd7-45b9-1cb6-403d3bdfa084', + extension: '0x' } const params = [ @@ -94,7 +97,7 @@ describe('Relayer API', () => { await quoter.submitBatch(params) expect(httpProvider.post).toHaveBeenCalledWith( - 'https://test.com/relayer/v1.0/1/order/submit/many', + 'https://test.com/relayer/v2.0/1/order/submit/many', params ) }) diff --git a/src/api/relayer/relayer.api.ts b/src/api/relayer/relayer.api.ts index c43b029..0ea3824 100644 --- a/src/api/relayer/relayer.api.ts +++ b/src/api/relayer/relayer.api.ts @@ -3,6 +3,8 @@ import {RelayerApiConfig} from './types' import {AxiosProviderConnector, HttpProviderConnector} from '../../connector' export class RelayerApi { + private static Version = 'v2.0' + constructor( private readonly config: RelayerApiConfig, private readonly httpClient: HttpProviderConnector @@ -18,13 +20,13 @@ export class RelayerApi { } submit(params: RelayerRequest): Promise { - const url = `${this.config.url}/v1.0/${this.config.network}/order/submit` + const url = `${this.config.url}/${RelayerApi.Version}/${this.config.network}/order/submit` return this.httpClient.post(url, params) } submitBatch(params: RelayerRequest[]): Promise { - const url = `${this.config.url}/v1.0/${this.config.network}/order/submit/many` + const url = `${this.config.url}/${RelayerApi.Version}/${this.config.network}/order/submit/many` return this.httpClient.post(url, params) } diff --git a/src/api/relayer/relayer.request.ts b/src/api/relayer/relayer.request.ts index 2b5d6e2..b2d02a6 100644 --- a/src/api/relayer/relayer.request.ts +++ b/src/api/relayer/relayer.request.ts @@ -8,10 +8,13 @@ export class RelayerRequest { public readonly quoteId: string + public readonly extension: string + constructor(params: RelayerRequestParams) { this.order = params.order this.signature = params.signature this.quoteId = params.quoteId + this.extension = params.extension } static new(params: RelayerRequestParams): RelayerRequest { @@ -22,7 +25,8 @@ export class RelayerRequest { return { order: this.order, signature: this.signature, - quoteId: this.quoteId + quoteId: this.quoteId, + extension: this.extension } } } diff --git a/src/api/relayer/types.ts b/src/api/relayer/types.ts index c577559..bc91522 100644 --- a/src/api/relayer/types.ts +++ b/src/api/relayer/types.ts @@ -5,6 +5,7 @@ export type RelayerRequestParams = { order: LimitOrderV4Struct signature: string quoteId: string + extension: string } export type RelayerApiConfig = { diff --git a/src/fusion-order/fusion-order.ts b/src/fusion-order/fusion-order.ts index 543d119..1cfff5b 100644 --- a/src/fusion-order/fusion-order.ts +++ b/src/fusion-order/fusion-order.ts @@ -47,7 +47,7 @@ export class FusionOrder { extra: { unwrapWETH?: boolean /** - * Required if `allowPartialFills` is false + * Required if `allowPartialFills` or `allowMultipleFills` is false */ nonce?: bigint /** @@ -230,7 +230,8 @@ export class FusionOrder { extra?: { unwrapWETH?: boolean /** - * Required if `allowPartialFills` is false + * Required if `allowPartialFills` or `allowMultipleFills` is false + * Max size is 40bit */ nonce?: bigint permit?: string diff --git a/src/sdk/sdk.ts b/src/sdk/sdk.ts index e63db46..55b11a2 100644 --- a/src/sdk/sdk.ts +++ b/src/sdk/sdk.ts @@ -142,7 +142,8 @@ export class FusionSDK { const relayerRequest = RelayerRequest.new({ order: orderStruct, signature, - quoteId + quoteId, + extension: order.extension.encode() }) await this.api.submitOrder(relayerRequest) @@ -151,7 +152,8 @@ export class FusionSDK { order: orderStruct, signature, quoteId, - orderHash: order.getOrderHash(this.config.network) + orderHash: order.getOrderHash(this.config.network), + extension: relayerRequest.extension } } diff --git a/src/sdk/types.ts b/src/sdk/types.ts index 90da265..36d84aa 100644 --- a/src/sdk/types.ts +++ b/src/sdk/types.ts @@ -63,6 +63,7 @@ export type OrderInfo = { signature: string quoteId: string orderHash: string + extension: string } export type PreparedOrder = { diff --git a/src/ws-api/README.md b/src/ws-api/README.md index b504979..bec5376 100644 --- a/src/ws-api/README.md +++ b/src/ws-api/README.md @@ -43,7 +43,7 @@ class MyFancyProvider implements WsProviderConnector { // ... user implementation } -const url = 'wss://api.1inch.dev/fusion/ws/v1.0/1' +const url = 'wss://api.1inch.dev/fusion/ws/v2.0/1' const provider = new MyFancyProvider({url}) const wsSdk = new WebSocketApi(provider) diff --git a/src/ws-api/ws-api.ts b/src/ws-api/ws-api.ts index f2feceb..5ea3641 100644 --- a/src/ws-api/ws-api.ts +++ b/src/ws-api/ws-api.ts @@ -11,6 +11,8 @@ import { } from '../connector/ws' export class WebSocketApi { + private static Version = 'v2.0' + public readonly rpc: RpcWebsocketApi public readonly order: ActiveOrdersWebSocketApi @@ -22,7 +24,7 @@ export class WebSocketApi { ) { if (instanceOfWsApiConfigWithNetwork(configOrProvider)) { const url = castUrl(configOrProvider.url) - const urlWithNetwork = `${url}/v1.0/${configOrProvider.network}` + const urlWithNetwork = `${url}/${WebSocketApi.Version}/${configOrProvider.network}` const configWithUrl = {...configOrProvider, url: urlWithNetwork} const provider = new WebsocketClient(configWithUrl) diff --git a/src/ws-api/ws.spec.ts b/src/ws-api/ws.spec.ts index ed6126e..a2015f8 100644 --- a/src/ws-api/ws.spec.ts +++ b/src/ws-api/ws.spec.ts @@ -91,7 +91,7 @@ describe(__filename, () => { const port = 8080 const url = `ws://localhost:${port}/ws` - const wss = new WebSocketServer({port, path: '/ws/v1.0/1'}) + const wss = new WebSocketServer({port, path: '/ws/v2.0/1'}) wss.on('connection', (ws) => { for (const m of [message]) { @@ -136,7 +136,7 @@ describe(__filename, () => { const port = 8080 const url = `ws://localhost:${port}/ws` - const wss = new WebSocketServer({port, path: '/ws/v1.0/1'}) + const wss = new WebSocketServer({port, path: '/ws/v2.0/1'}) wss.on('connection', (ws) => { for (const m of [message]) { @@ -166,7 +166,7 @@ describe(__filename, () => { const port = 8080 const url = `ws://localhost:${port}/ws` - const wss = new WebSocketServer({port, path: '/ws/v1.0/1'}) + const wss = new WebSocketServer({port, path: '/ws/v2.0/1'}) wss.on('connection', (ws) => { for (const m of [message]) { @@ -175,7 +175,7 @@ describe(__filename, () => { }) const castedUrl = castUrl(url) - const urlWithNetwork = `${castedUrl}/v1.0/1` + const urlWithNetwork = `${castedUrl}/v2.0/1` const provider = new WebsocketClient({url: urlWithNetwork}) const wsSdk = new WebSocketApi(provider) @@ -199,7 +199,7 @@ describe(__filename, () => { const port = 8080 const url = `ws://localhost:${port}/ws` - const wss = new WebSocketServer({port, path: '/ws/v1.0/1'}) + const wss = new WebSocketServer({port, path: '/ws/v2.0/1'}) wss.on('connection', (ws) => { for (const m of [message]) { @@ -208,7 +208,7 @@ describe(__filename, () => { }) const castedUrl = castUrl(url) - const urlWithNetwork = `${castedUrl}/v1.0/1` + const urlWithNetwork = `${castedUrl}/v2.0/1` const provider = new WebsocketClient({ url: urlWithNetwork, authKey: '' @@ -828,7 +828,7 @@ function createWebsocketRpcServerMock(cb: (ws: WebSocket, data: any) => void): { } { const port = 8080 const returnUrl = `ws://localhost:${port}/ws` - const wss = new WebSocketServer({port, path: '/ws/v1.0/1'}) + const wss = new WebSocketServer({port, path: '/ws/v2.0/1'}) wss.on('connection', (ws) => { ws.on('message', (data) => cb(ws, data)) @@ -844,7 +844,7 @@ function createWebsocketServerMock(messages: any[]): { const port = 8080 const returnUrl = `ws://localhost:${port}/ws` - const wss = new WebSocketServer({port, path: '/ws/v1.0/1'}) + const wss = new WebSocketServer({port, path: '/ws/v2.0/1'}) wss.on('connection', (ws) => { for (const message of messages) {