@cowprotocol/sdk-order-signing 0.1.0-monorepo.0
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.
- package/README.md +152 -0
- package/dist/index.d.mts +154 -0
- package/dist/index.d.ts +154 -0
- package/dist/index.js +253 -0
- package/dist/index.mjs +239 -0
- package/package.json +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img width="400" src="https://github.com/cowprotocol/cow-sdk/raw/main/docs/images/CoW.png" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# SDK Order Signing
|
|
6
|
+
|
|
7
|
+
This package provides EIP-712 order signing and cancellation utilities for the CoW Protocol. It handles all the cryptographic operations required to sign orders and cancellations according to CoW Protocol's specifications.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @cowprotocol/sdk-order-signing
|
|
13
|
+
or
|
|
14
|
+
pnpm add @cowprotocol/sdk-order-signing
|
|
15
|
+
or
|
|
16
|
+
yarn add @cowprotocol/sdk-order-signing
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
### Individual package usage
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { OrderSigningUtils, SupportedChainId, UnsignedOrder, SigningResult } from '@cowprotocol/sdk-order-signing'
|
|
25
|
+
import { EthersV6Adapter } from '@cowprotocol/sdk-ethers-v6-adapter'
|
|
26
|
+
import { JsonRpcProvider, Wallet } from 'ethers'
|
|
27
|
+
|
|
28
|
+
// Configure the adapter
|
|
29
|
+
const provider = new JsonRpcProvider('YOUR_RPC_URL')
|
|
30
|
+
const wallet = new Wallet('YOUR_PRIVATE_KEY', provider)
|
|
31
|
+
const adapter = new EthersV6Adapter({ provider, signer: wallet })
|
|
32
|
+
|
|
33
|
+
// Create order signing utils
|
|
34
|
+
const orderSigning = new OrderSigningUtils(adapter)
|
|
35
|
+
|
|
36
|
+
// Sign an order
|
|
37
|
+
const orderToSign: UnsignedOrder = {
|
|
38
|
+
sellToken: '0xA0b86a33E6417b528874E10EB3a95beb4F25A0E3',
|
|
39
|
+
buyToken: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
|
|
40
|
+
sellAmount: '1000000000000000000',
|
|
41
|
+
buyAmount: '1000000000000000000',
|
|
42
|
+
validTo: Math.floor(Date.now() / 1000) + 3600,
|
|
43
|
+
appData: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
44
|
+
feeAmount: '0',
|
|
45
|
+
kind: 'sell',
|
|
46
|
+
partiallyFillable: false,
|
|
47
|
+
sellTokenBalance: 'erc20',
|
|
48
|
+
buyTokenBalance: 'erc20',
|
|
49
|
+
receiver: '0x0000000000000000000000000000000000000000',
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const signingResult: SigningResult = await OrderSigningUtils.signOrder(
|
|
53
|
+
orderToSign,
|
|
54
|
+
SupportedChainId.MAINNET,
|
|
55
|
+
adapter.signer,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
// Sign order cancellation
|
|
59
|
+
const orderId = 'ORDER_UID_TO_CANCEL'
|
|
60
|
+
const cancellationResult = await OrderSigningUtils.signOrderCancellation(
|
|
61
|
+
orderId,
|
|
62
|
+
SupportedChainId.MAINNET,
|
|
63
|
+
adapter.signer,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
// Generate order ID
|
|
67
|
+
const { orderId: generatedId, orderDigest } = await OrderSigningUtils.generateOrderId(
|
|
68
|
+
SupportedChainId.MAINNET,
|
|
69
|
+
orderToSign as any,
|
|
70
|
+
{ owner: await adapter.signer.getAddress() },
|
|
71
|
+
)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Usage with Umbrella SDK
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { CowSdk, OrderSigningUtils, SupportedChainId, UnsignedOrder } from '@cowprotocol/cow-sdk'
|
|
78
|
+
import { EthersV6Adapter } from '@cowprotocol/sdk-ethers-v6-adapter'
|
|
79
|
+
import { JsonRpcProvider, Wallet } from 'ethers'
|
|
80
|
+
|
|
81
|
+
// Configure the adapter
|
|
82
|
+
const provider = new JsonRpcProvider('YOUR_RPC_URL')
|
|
83
|
+
const wallet = new Wallet('YOUR_PRIVATE_KEY', provider)
|
|
84
|
+
const adapter = new EthersV6Adapter({ provider, signer: wallet })
|
|
85
|
+
|
|
86
|
+
// Initialize the unified SDK
|
|
87
|
+
const sdk = new CowSdk({
|
|
88
|
+
chainId: SupportedChainId.MAINNET,
|
|
89
|
+
adapter,
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
// Sign order using the umbrella SDK
|
|
93
|
+
const signingResult = await sdk.orderSigning.signOrder(orderToSign, SupportedChainId.MAINNET, adapter.signer)
|
|
94
|
+
|
|
95
|
+
// Sign cancellation
|
|
96
|
+
const cancellationResult = await sdk.orderSigning.signOrderCancellation(
|
|
97
|
+
orderId,
|
|
98
|
+
SupportedChainId.MAINNET,
|
|
99
|
+
adapter.signer,
|
|
100
|
+
)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Signing Schemes
|
|
104
|
+
|
|
105
|
+
The SDK supports multiple signing schemes:
|
|
106
|
+
|
|
107
|
+
### EIP-712 (Default)
|
|
108
|
+
|
|
109
|
+
Standard wallet signature using EIP-712 typed data:
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
// Automatically uses EIP-712 for wallet signers
|
|
113
|
+
const result = await OrderSigningUtils.signOrder(order, chainId, signer)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Smart Contract Wallets (Pre-sign)
|
|
117
|
+
|
|
118
|
+
For smart contract wallets like Safe:
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import { SigningScheme } from '@cowprotocol/sdk-order-signing'
|
|
122
|
+
|
|
123
|
+
// For smart contract wallets, specify the signing scheme
|
|
124
|
+
// Then execute the pre-sign transaction on-chain
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### EIP-1271
|
|
128
|
+
|
|
129
|
+
For contracts that implement EIP-1271:
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
// Used for contracts that can validate signatures
|
|
133
|
+
// The SDK automatically detects and handles this
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Integration with Order Book
|
|
137
|
+
|
|
138
|
+
This package works seamlessly with the Order Book API:
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
// 1. Sign the order
|
|
142
|
+
const signingResult = await OrderSigningUtils.signOrder(order, chainId, signer)
|
|
143
|
+
|
|
144
|
+
// 2. Submit to order book
|
|
145
|
+
const orderId = await orderBookApi.sendOrder({ ...order, ...signingResult })
|
|
146
|
+
|
|
147
|
+
// 3. Cancel if needed
|
|
148
|
+
const cancellation = await OrderSigningUtils.signOrderCancellation(orderId, chainId, signer)
|
|
149
|
+
await orderBookApi.sendSignedOrderCancellations({ ...cancellation, orderUids: [orderId] })
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
> **Note:** This package handles the cryptographic aspects of CoW Protocol orders. It's typically used in conjunction with the Trading SDK or Order Book API for complete order management workflows.
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { SupportedChainId } from '@cowprotocol/sdk-config';
|
|
2
|
+
import { ContractsOrder, OrderUidParams } from '@cowprotocol/sdk-contracts-ts';
|
|
3
|
+
import { SignerLike, AbstractProviderAdapter, Signer, TypedDataDomain } from '@cowprotocol/sdk-common';
|
|
4
|
+
import { OrderParameters, EcdsaSigningScheme } from '@cowprotocol/sdk-order-book';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Unsigned order intent to be placed.
|
|
8
|
+
*/
|
|
9
|
+
type UnsignedOrder = Omit<OrderParameters, 'receiver'> & {
|
|
10
|
+
receiver: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Encoded signature including signing scheme for the order.
|
|
14
|
+
*/
|
|
15
|
+
type SigningResult = {
|
|
16
|
+
signature: string;
|
|
17
|
+
signingScheme: EcdsaSigningScheme;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Parameters for signing an order intent.
|
|
21
|
+
* @param chainId The CoW Protocol `chainId` context that's being used.
|
|
22
|
+
* @param signer The signer who is placing the order intent.
|
|
23
|
+
* @param order The unsigned order intent to be placed.
|
|
24
|
+
* @param signingScheme The signing scheme to use for the signature.
|
|
25
|
+
*/
|
|
26
|
+
interface SignOrderParams {
|
|
27
|
+
chainId: SupportedChainId;
|
|
28
|
+
signer: SignerLike;
|
|
29
|
+
order: UnsignedOrder;
|
|
30
|
+
signingScheme: EcdsaSigningScheme;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Parameters for signing an order cancellation.
|
|
34
|
+
* @param chainId The CoW Protocol `chainId` context that's being used.
|
|
35
|
+
* @param signer The signer who initially placed the order intent.
|
|
36
|
+
* @param orderUid The unique identifier of the order to cancel.
|
|
37
|
+
* @param signingScheme The signing scheme to use for the signature.
|
|
38
|
+
*/
|
|
39
|
+
interface SignOrderCancellationParams {
|
|
40
|
+
chainId: SupportedChainId;
|
|
41
|
+
signer: SignerLike;
|
|
42
|
+
orderUid: string;
|
|
43
|
+
signingScheme: EcdsaSigningScheme;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Parameters for signing multiple bulk order cancellations.
|
|
47
|
+
* @param chainId The CoW Protocol `chainId` context that's being used.
|
|
48
|
+
* @param signer The signer who initially placed the order intents.
|
|
49
|
+
* @param orderUids An array of `orderUid` to cancel.
|
|
50
|
+
* @param signingScheme The signing scheme to use for the signature.
|
|
51
|
+
*/
|
|
52
|
+
interface SignOrderCancellationsParams {
|
|
53
|
+
chainId: SupportedChainId;
|
|
54
|
+
signer: SignerLike;
|
|
55
|
+
orderUids: string[];
|
|
56
|
+
signingScheme: EcdsaSigningScheme;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Utility class for signing order intents and cancellations.
|
|
61
|
+
*
|
|
62
|
+
* @remarks This class only supports `eth_sign` and wallet-native EIP-712 signing. For use of
|
|
63
|
+
* `presign` and `eip1271` {@link https://docs.cow.fi/ | see the docs}.
|
|
64
|
+
* @example
|
|
65
|
+
*
|
|
66
|
+
* ```typescript
|
|
67
|
+
* import { OrderSigningUtils, SupportedChainId, UnsignedOrder } from '@cowprotocol/cow-sdk'
|
|
68
|
+
* import { Web3Provider } from '@ethersproject/providers'
|
|
69
|
+
*
|
|
70
|
+
* const account = 'YOUR_WALLET_ADDRESS'
|
|
71
|
+
* const chainId = 100 // Gnosis chain
|
|
72
|
+
* const provider = new Web3Provider(window.ethereum)
|
|
73
|
+
* const signer = provider.getSigner()
|
|
74
|
+
*
|
|
75
|
+
* async function main() {
|
|
76
|
+
* const orderToSign: UnsignedOrder = { ... }
|
|
77
|
+
* const orderSigningResult = await OrderSigningUtils.signOrder(orderToSign, chainId, signer)
|
|
78
|
+
*
|
|
79
|
+
* const orderId = await orderBookApi.sendOrder({ ...orderToSign, ...orderSigningResult })
|
|
80
|
+
*
|
|
81
|
+
* const order = await orderBookApi.getOrder(orderId)
|
|
82
|
+
*
|
|
83
|
+
* const trades = await orderBookApi.getTrades({ orderId })
|
|
84
|
+
*
|
|
85
|
+
* const orderCancellationSigningResult = await OrderSigningUtils.signOrderCancellations([orderId], chainId, signer)
|
|
86
|
+
*
|
|
87
|
+
* const cancellationResult = await orderBookApi.sendSignedOrderCancellations({...orderCancellationSigningResult, orderUids: [orderId] })
|
|
88
|
+
*
|
|
89
|
+
* console.log('Results: ', { orderId, order, trades, orderCancellationSigningResult, cancellationResult })
|
|
90
|
+
* }
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
declare class OrderSigningUtils {
|
|
94
|
+
constructor(adapter?: AbstractProviderAdapter);
|
|
95
|
+
/**
|
|
96
|
+
* Sign the order intent with the specified signer.
|
|
97
|
+
*
|
|
98
|
+
* @remarks If the API reports an error with the signature, it is likely to be due to an incorrectly
|
|
99
|
+
* specified `chainId`. Please ensure that the `chainId` is correct for the network you are
|
|
100
|
+
* using.
|
|
101
|
+
* @param {UnsignedOrder} order The unsigned order intent to be placed.
|
|
102
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainId` context that's being used.
|
|
103
|
+
* @param {Signer} signer The signer who is placing the order intent.
|
|
104
|
+
* @returns {Promise<SigningResult>} Encoded signature including signing scheme for the order.
|
|
105
|
+
*/
|
|
106
|
+
static signOrder(order: UnsignedOrder, chainId: SupportedChainId, signer: Signer): Promise<SigningResult>;
|
|
107
|
+
/**
|
|
108
|
+
* Sign a cancellation message of an order intent with the specified signer.
|
|
109
|
+
* @param {string} orderUid The unique identifier of the order to cancel.
|
|
110
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainid` context that's being used.
|
|
111
|
+
* @param {Signer} signer The signer who initially placed the order intent.
|
|
112
|
+
* @returns {Promise<SigningResult>} Encoded signature including signing scheme for the cancellation.
|
|
113
|
+
*/
|
|
114
|
+
static signOrderCancellation(orderUid: string, chainId: SupportedChainId, signer: Signer): Promise<SigningResult>;
|
|
115
|
+
/**
|
|
116
|
+
* Sign a cancellation message of multiple order intents with the specified signer.
|
|
117
|
+
* @param {string[]} orderUids An array of `orderUid` to cancel.
|
|
118
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainId` context that's being used.
|
|
119
|
+
* @param {Signer} signer The signer who initially placed the order intents.
|
|
120
|
+
* @returns {Promise<SigningResult>} Encoded signature including signing scheme for the cancellation.
|
|
121
|
+
*/
|
|
122
|
+
static signOrderCancellations(orderUids: string[], chainId: SupportedChainId, signer: Signer): Promise<SigningResult>;
|
|
123
|
+
/**
|
|
124
|
+
* Get the EIP-712 typed domain data being used for signing.
|
|
125
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainId` context that's being used.
|
|
126
|
+
* @return The EIP-712 typed domain data.
|
|
127
|
+
* @see https://eips.ethereum.org/EIPS/eip-712
|
|
128
|
+
*/
|
|
129
|
+
static getDomain(chainId: SupportedChainId): Promise<TypedDataDomain>;
|
|
130
|
+
/**
|
|
131
|
+
* Hashes the order intent and generate deterministic order ID.
|
|
132
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainId` context that's being used.
|
|
133
|
+
* @param {Order} order order to sign
|
|
134
|
+
* @param {Pick<OrderUidParams, 'owner'>} params order unique identifier parameters.
|
|
135
|
+
*/
|
|
136
|
+
static generateOrderId(chainId: SupportedChainId, order: ContractsOrder, params: Pick<OrderUidParams, 'owner'>): Promise<{
|
|
137
|
+
orderId: string;
|
|
138
|
+
orderDigest: string;
|
|
139
|
+
}>;
|
|
140
|
+
/**
|
|
141
|
+
* Get the domain separator hash for the EIP-712 typed domain data being used for signing.
|
|
142
|
+
* @param chainId {SupportedChainId} chainId The CoW Protocol protocol `chainId` context that's being used.
|
|
143
|
+
* @returns A string representation of the EIP-712 typed domain data hash.
|
|
144
|
+
*/
|
|
145
|
+
static getDomainSeparator(chainId: SupportedChainId): Promise<string>;
|
|
146
|
+
/**
|
|
147
|
+
* Get the EIP-712 types used for signing a GPv2Order.Data struct. This is useful for when
|
|
148
|
+
* signing orders using smart contracts, whereby this SDK cannot do the EIP-1271 signing for you.
|
|
149
|
+
* @returns The EIP-712 types used for signing.
|
|
150
|
+
*/
|
|
151
|
+
static getEIP712Types(): Record<string, unknown>;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export { OrderSigningUtils, type SignOrderCancellationParams, type SignOrderCancellationsParams, type SignOrderParams, type SigningResult, type UnsignedOrder };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { SupportedChainId } from '@cowprotocol/sdk-config';
|
|
2
|
+
import { ContractsOrder, OrderUidParams } from '@cowprotocol/sdk-contracts-ts';
|
|
3
|
+
import { SignerLike, AbstractProviderAdapter, Signer, TypedDataDomain } from '@cowprotocol/sdk-common';
|
|
4
|
+
import { OrderParameters, EcdsaSigningScheme } from '@cowprotocol/sdk-order-book';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Unsigned order intent to be placed.
|
|
8
|
+
*/
|
|
9
|
+
type UnsignedOrder = Omit<OrderParameters, 'receiver'> & {
|
|
10
|
+
receiver: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Encoded signature including signing scheme for the order.
|
|
14
|
+
*/
|
|
15
|
+
type SigningResult = {
|
|
16
|
+
signature: string;
|
|
17
|
+
signingScheme: EcdsaSigningScheme;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Parameters for signing an order intent.
|
|
21
|
+
* @param chainId The CoW Protocol `chainId` context that's being used.
|
|
22
|
+
* @param signer The signer who is placing the order intent.
|
|
23
|
+
* @param order The unsigned order intent to be placed.
|
|
24
|
+
* @param signingScheme The signing scheme to use for the signature.
|
|
25
|
+
*/
|
|
26
|
+
interface SignOrderParams {
|
|
27
|
+
chainId: SupportedChainId;
|
|
28
|
+
signer: SignerLike;
|
|
29
|
+
order: UnsignedOrder;
|
|
30
|
+
signingScheme: EcdsaSigningScheme;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Parameters for signing an order cancellation.
|
|
34
|
+
* @param chainId The CoW Protocol `chainId` context that's being used.
|
|
35
|
+
* @param signer The signer who initially placed the order intent.
|
|
36
|
+
* @param orderUid The unique identifier of the order to cancel.
|
|
37
|
+
* @param signingScheme The signing scheme to use for the signature.
|
|
38
|
+
*/
|
|
39
|
+
interface SignOrderCancellationParams {
|
|
40
|
+
chainId: SupportedChainId;
|
|
41
|
+
signer: SignerLike;
|
|
42
|
+
orderUid: string;
|
|
43
|
+
signingScheme: EcdsaSigningScheme;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Parameters for signing multiple bulk order cancellations.
|
|
47
|
+
* @param chainId The CoW Protocol `chainId` context that's being used.
|
|
48
|
+
* @param signer The signer who initially placed the order intents.
|
|
49
|
+
* @param orderUids An array of `orderUid` to cancel.
|
|
50
|
+
* @param signingScheme The signing scheme to use for the signature.
|
|
51
|
+
*/
|
|
52
|
+
interface SignOrderCancellationsParams {
|
|
53
|
+
chainId: SupportedChainId;
|
|
54
|
+
signer: SignerLike;
|
|
55
|
+
orderUids: string[];
|
|
56
|
+
signingScheme: EcdsaSigningScheme;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Utility class for signing order intents and cancellations.
|
|
61
|
+
*
|
|
62
|
+
* @remarks This class only supports `eth_sign` and wallet-native EIP-712 signing. For use of
|
|
63
|
+
* `presign` and `eip1271` {@link https://docs.cow.fi/ | see the docs}.
|
|
64
|
+
* @example
|
|
65
|
+
*
|
|
66
|
+
* ```typescript
|
|
67
|
+
* import { OrderSigningUtils, SupportedChainId, UnsignedOrder } from '@cowprotocol/cow-sdk'
|
|
68
|
+
* import { Web3Provider } from '@ethersproject/providers'
|
|
69
|
+
*
|
|
70
|
+
* const account = 'YOUR_WALLET_ADDRESS'
|
|
71
|
+
* const chainId = 100 // Gnosis chain
|
|
72
|
+
* const provider = new Web3Provider(window.ethereum)
|
|
73
|
+
* const signer = provider.getSigner()
|
|
74
|
+
*
|
|
75
|
+
* async function main() {
|
|
76
|
+
* const orderToSign: UnsignedOrder = { ... }
|
|
77
|
+
* const orderSigningResult = await OrderSigningUtils.signOrder(orderToSign, chainId, signer)
|
|
78
|
+
*
|
|
79
|
+
* const orderId = await orderBookApi.sendOrder({ ...orderToSign, ...orderSigningResult })
|
|
80
|
+
*
|
|
81
|
+
* const order = await orderBookApi.getOrder(orderId)
|
|
82
|
+
*
|
|
83
|
+
* const trades = await orderBookApi.getTrades({ orderId })
|
|
84
|
+
*
|
|
85
|
+
* const orderCancellationSigningResult = await OrderSigningUtils.signOrderCancellations([orderId], chainId, signer)
|
|
86
|
+
*
|
|
87
|
+
* const cancellationResult = await orderBookApi.sendSignedOrderCancellations({...orderCancellationSigningResult, orderUids: [orderId] })
|
|
88
|
+
*
|
|
89
|
+
* console.log('Results: ', { orderId, order, trades, orderCancellationSigningResult, cancellationResult })
|
|
90
|
+
* }
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
declare class OrderSigningUtils {
|
|
94
|
+
constructor(adapter?: AbstractProviderAdapter);
|
|
95
|
+
/**
|
|
96
|
+
* Sign the order intent with the specified signer.
|
|
97
|
+
*
|
|
98
|
+
* @remarks If the API reports an error with the signature, it is likely to be due to an incorrectly
|
|
99
|
+
* specified `chainId`. Please ensure that the `chainId` is correct for the network you are
|
|
100
|
+
* using.
|
|
101
|
+
* @param {UnsignedOrder} order The unsigned order intent to be placed.
|
|
102
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainId` context that's being used.
|
|
103
|
+
* @param {Signer} signer The signer who is placing the order intent.
|
|
104
|
+
* @returns {Promise<SigningResult>} Encoded signature including signing scheme for the order.
|
|
105
|
+
*/
|
|
106
|
+
static signOrder(order: UnsignedOrder, chainId: SupportedChainId, signer: Signer): Promise<SigningResult>;
|
|
107
|
+
/**
|
|
108
|
+
* Sign a cancellation message of an order intent with the specified signer.
|
|
109
|
+
* @param {string} orderUid The unique identifier of the order to cancel.
|
|
110
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainid` context that's being used.
|
|
111
|
+
* @param {Signer} signer The signer who initially placed the order intent.
|
|
112
|
+
* @returns {Promise<SigningResult>} Encoded signature including signing scheme for the cancellation.
|
|
113
|
+
*/
|
|
114
|
+
static signOrderCancellation(orderUid: string, chainId: SupportedChainId, signer: Signer): Promise<SigningResult>;
|
|
115
|
+
/**
|
|
116
|
+
* Sign a cancellation message of multiple order intents with the specified signer.
|
|
117
|
+
* @param {string[]} orderUids An array of `orderUid` to cancel.
|
|
118
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainId` context that's being used.
|
|
119
|
+
* @param {Signer} signer The signer who initially placed the order intents.
|
|
120
|
+
* @returns {Promise<SigningResult>} Encoded signature including signing scheme for the cancellation.
|
|
121
|
+
*/
|
|
122
|
+
static signOrderCancellations(orderUids: string[], chainId: SupportedChainId, signer: Signer): Promise<SigningResult>;
|
|
123
|
+
/**
|
|
124
|
+
* Get the EIP-712 typed domain data being used for signing.
|
|
125
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainId` context that's being used.
|
|
126
|
+
* @return The EIP-712 typed domain data.
|
|
127
|
+
* @see https://eips.ethereum.org/EIPS/eip-712
|
|
128
|
+
*/
|
|
129
|
+
static getDomain(chainId: SupportedChainId): Promise<TypedDataDomain>;
|
|
130
|
+
/**
|
|
131
|
+
* Hashes the order intent and generate deterministic order ID.
|
|
132
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainId` context that's being used.
|
|
133
|
+
* @param {Order} order order to sign
|
|
134
|
+
* @param {Pick<OrderUidParams, 'owner'>} params order unique identifier parameters.
|
|
135
|
+
*/
|
|
136
|
+
static generateOrderId(chainId: SupportedChainId, order: ContractsOrder, params: Pick<OrderUidParams, 'owner'>): Promise<{
|
|
137
|
+
orderId: string;
|
|
138
|
+
orderDigest: string;
|
|
139
|
+
}>;
|
|
140
|
+
/**
|
|
141
|
+
* Get the domain separator hash for the EIP-712 typed domain data being used for signing.
|
|
142
|
+
* @param chainId {SupportedChainId} chainId The CoW Protocol protocol `chainId` context that's being used.
|
|
143
|
+
* @returns A string representation of the EIP-712 typed domain data hash.
|
|
144
|
+
*/
|
|
145
|
+
static getDomainSeparator(chainId: SupportedChainId): Promise<string>;
|
|
146
|
+
/**
|
|
147
|
+
* Get the EIP-712 types used for signing a GPv2Order.Data struct. This is useful for when
|
|
148
|
+
* signing orders using smart contracts, whereby this SDK cannot do the EIP-1271 signing for you.
|
|
149
|
+
* @returns The EIP-712 types used for signing.
|
|
150
|
+
*/
|
|
151
|
+
static getEIP712Types(): Record<string, unknown>;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export { OrderSigningUtils, type SignOrderCancellationParams, type SignOrderCancellationsParams, type SignOrderParams, type SigningResult, type UnsignedOrder };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
OrderSigningUtils: () => OrderSigningUtils
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(src_exports);
|
|
26
|
+
|
|
27
|
+
// src/orderSigningUtils.ts
|
|
28
|
+
var import_sdk_common2 = require("@cowprotocol/sdk-common");
|
|
29
|
+
|
|
30
|
+
// src/utils.ts
|
|
31
|
+
var import_sdk_contracts_ts = require("@cowprotocol/sdk-contracts-ts");
|
|
32
|
+
var import_sdk_common = require("@cowprotocol/sdk-common");
|
|
33
|
+
var import_sdk_order_book = require("@cowprotocol/sdk-order-book");
|
|
34
|
+
var import_sdk_config = require("@cowprotocol/sdk-config");
|
|
35
|
+
var METAMASK_SIGNATURE_ERROR_CODE = -32603;
|
|
36
|
+
var METHOD_NOT_FOUND_ERROR_CODE = -32601;
|
|
37
|
+
var METHOD_NOT_FOUND_ERROR_MSG_REGEX = /Method not found/i;
|
|
38
|
+
var V4_ERROR_MSG_REGEX = /eth_signTypedData_v4 does not exist/i;
|
|
39
|
+
var V3_ERROR_MSG_REGEX = /eth_signTypedData_v3 does not exist/i;
|
|
40
|
+
var RPC_REQUEST_FAILED_REGEX = /RPC request failed/i;
|
|
41
|
+
var METAMASK_STRING_CHAINID_REGEX = /provided chainid .* must match the active chainid/i;
|
|
42
|
+
var mapSigningSchema = {
|
|
43
|
+
[import_sdk_order_book.EcdsaSigningScheme.EIP712]: import_sdk_contracts_ts.ContractsSigningScheme.EIP712,
|
|
44
|
+
[import_sdk_order_book.EcdsaSigningScheme.ETHSIGN]: import_sdk_contracts_ts.ContractsSigningScheme.ETHSIGN
|
|
45
|
+
};
|
|
46
|
+
function isProviderRpcError(error) {
|
|
47
|
+
return error.code !== void 0 || error.message !== void 0;
|
|
48
|
+
}
|
|
49
|
+
async function _signOrder(params) {
|
|
50
|
+
const { chainId, signer, order, signingScheme } = params;
|
|
51
|
+
const domain = getDomain(chainId);
|
|
52
|
+
return (0, import_sdk_contracts_ts.signOrder)(domain, order, mapSigningSchema[signingScheme], signer);
|
|
53
|
+
}
|
|
54
|
+
async function _signOrderCancellation(params) {
|
|
55
|
+
const { chainId, signer, signingScheme, orderUid } = params;
|
|
56
|
+
const domain = getDomain(chainId);
|
|
57
|
+
return (0, import_sdk_contracts_ts.signOrderCancellation)(domain, orderUid, mapSigningSchema[signingScheme], signer);
|
|
58
|
+
}
|
|
59
|
+
async function _signOrderCancellations(params) {
|
|
60
|
+
const { chainId, signer, signingScheme, orderUids } = params;
|
|
61
|
+
const domain = getDomain(chainId);
|
|
62
|
+
return (0, import_sdk_contracts_ts.signOrderCancellations)(domain, orderUids, mapSigningSchema[signingScheme], signer);
|
|
63
|
+
}
|
|
64
|
+
async function _signPayload(payload, signFn, signer, signingMethod = "v4") {
|
|
65
|
+
const signingScheme = signingMethod === "eth_sign" ? import_sdk_order_book.EcdsaSigningScheme.ETHSIGN : import_sdk_order_book.EcdsaSigningScheme.EIP712;
|
|
66
|
+
let signature = null;
|
|
67
|
+
let _signer;
|
|
68
|
+
try {
|
|
69
|
+
switch (signingMethod) {
|
|
70
|
+
case "default":
|
|
71
|
+
case "v3":
|
|
72
|
+
_signer = (0, import_sdk_contracts_ts.getTypedDataVersionedSigner)(signer, "v3");
|
|
73
|
+
break;
|
|
74
|
+
case "int_v4":
|
|
75
|
+
_signer = (0, import_sdk_contracts_ts.getIntChainIdTypedDataV4Signer)(signer);
|
|
76
|
+
break;
|
|
77
|
+
default:
|
|
78
|
+
_signer = signer;
|
|
79
|
+
}
|
|
80
|
+
} catch (e) {
|
|
81
|
+
console.error("Wallet not supported:", e);
|
|
82
|
+
throw new import_sdk_common.CowError("Wallet not supported");
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
signature = await signFn({ ...payload, signer: _signer, signingScheme });
|
|
86
|
+
} catch (e) {
|
|
87
|
+
if (!isProviderRpcError(e)) {
|
|
88
|
+
console.error(e);
|
|
89
|
+
throw e;
|
|
90
|
+
}
|
|
91
|
+
const regexErrorCheck = [METHOD_NOT_FOUND_ERROR_MSG_REGEX, RPC_REQUEST_FAILED_REGEX].some(
|
|
92
|
+
(regex) => (
|
|
93
|
+
// for example 1Inch error doesn't have e.message so we will check the output of toString()
|
|
94
|
+
[e.message, e.toString()].some((msg) => regex.test(msg))
|
|
95
|
+
)
|
|
96
|
+
);
|
|
97
|
+
if (e.code === METHOD_NOT_FOUND_ERROR_CODE || regexErrorCheck) {
|
|
98
|
+
switch (signingMethod) {
|
|
99
|
+
case "v4":
|
|
100
|
+
return _signPayload(payload, signFn, signer, "default");
|
|
101
|
+
case "default":
|
|
102
|
+
return _signPayload(payload, signFn, signer, "v3");
|
|
103
|
+
case "v3":
|
|
104
|
+
return _signPayload(payload, signFn, signer, "eth_sign");
|
|
105
|
+
default:
|
|
106
|
+
throw e;
|
|
107
|
+
}
|
|
108
|
+
} else if (METAMASK_STRING_CHAINID_REGEX.test(e.message)) {
|
|
109
|
+
return _signPayload(payload, signFn, signer, "int_v4");
|
|
110
|
+
} else if (e.code === METAMASK_SIGNATURE_ERROR_CODE) {
|
|
111
|
+
return _signPayload(payload, signFn, signer, "eth_sign");
|
|
112
|
+
} else if (V4_ERROR_MSG_REGEX.test(e.message)) {
|
|
113
|
+
return _signPayload(payload, signFn, signer, "v3");
|
|
114
|
+
} else if (V3_ERROR_MSG_REGEX.test(e.message)) {
|
|
115
|
+
return _signPayload(payload, signFn, signer, "eth_sign");
|
|
116
|
+
} else {
|
|
117
|
+
console.error(e);
|
|
118
|
+
throw e;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const data = signature?.data;
|
|
122
|
+
return { signature: data?.toString() || "", signingScheme };
|
|
123
|
+
}
|
|
124
|
+
async function signOrder(order, chainId, signer) {
|
|
125
|
+
return _signPayload({ order, chainId }, _signOrder, signer);
|
|
126
|
+
}
|
|
127
|
+
async function signOrderCancellation(orderUid, chainId, signer) {
|
|
128
|
+
return _signPayload({ orderUid, chainId }, _signOrderCancellation, signer);
|
|
129
|
+
}
|
|
130
|
+
async function signOrderCancellations(orderUids, chainId, signer) {
|
|
131
|
+
return _signPayload({ orderUids, chainId }, _signOrderCancellations, signer);
|
|
132
|
+
}
|
|
133
|
+
function getDomain(chainId) {
|
|
134
|
+
const settlementContract = import_sdk_config.COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS[chainId];
|
|
135
|
+
if (!settlementContract) {
|
|
136
|
+
throw new import_sdk_common.CowError("Unsupported network. Settlement contract is not deployed");
|
|
137
|
+
}
|
|
138
|
+
return import_sdk_contracts_ts.ContractsTs.domain(chainId, settlementContract);
|
|
139
|
+
}
|
|
140
|
+
async function generateOrderId(chainId, order, params) {
|
|
141
|
+
const domain = await getDomain(chainId);
|
|
142
|
+
const orderDigest = (0, import_sdk_contracts_ts.hashOrder)(domain, order);
|
|
143
|
+
const orderId = (0, import_sdk_contracts_ts.packOrderUidParams)({
|
|
144
|
+
...params,
|
|
145
|
+
orderDigest,
|
|
146
|
+
// Different validTo when signing because EthFlow contract expects it to be max for all orders
|
|
147
|
+
validTo: order.validTo
|
|
148
|
+
});
|
|
149
|
+
return { orderId, orderDigest };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// src/orderSigningUtils.ts
|
|
153
|
+
var OrderSigningUtils = class {
|
|
154
|
+
constructor(adapter) {
|
|
155
|
+
if (adapter) {
|
|
156
|
+
(0, import_sdk_common2.setGlobalAdapter)(adapter);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Sign the order intent with the specified signer.
|
|
161
|
+
*
|
|
162
|
+
* @remarks If the API reports an error with the signature, it is likely to be due to an incorrectly
|
|
163
|
+
* specified `chainId`. Please ensure that the `chainId` is correct for the network you are
|
|
164
|
+
* using.
|
|
165
|
+
* @param {UnsignedOrder} order The unsigned order intent to be placed.
|
|
166
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainId` context that's being used.
|
|
167
|
+
* @param {Signer} signer The signer who is placing the order intent.
|
|
168
|
+
* @returns {Promise<SigningResult>} Encoded signature including signing scheme for the order.
|
|
169
|
+
*/
|
|
170
|
+
static async signOrder(order, chainId, signer) {
|
|
171
|
+
return signOrder(order, chainId, signer);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Sign a cancellation message of an order intent with the specified signer.
|
|
175
|
+
* @param {string} orderUid The unique identifier of the order to cancel.
|
|
176
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainid` context that's being used.
|
|
177
|
+
* @param {Signer} signer The signer who initially placed the order intent.
|
|
178
|
+
* @returns {Promise<SigningResult>} Encoded signature including signing scheme for the cancellation.
|
|
179
|
+
*/
|
|
180
|
+
static async signOrderCancellation(orderUid, chainId, signer) {
|
|
181
|
+
return signOrderCancellation(orderUid, chainId, signer);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Sign a cancellation message of multiple order intents with the specified signer.
|
|
185
|
+
* @param {string[]} orderUids An array of `orderUid` to cancel.
|
|
186
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainId` context that's being used.
|
|
187
|
+
* @param {Signer} signer The signer who initially placed the order intents.
|
|
188
|
+
* @returns {Promise<SigningResult>} Encoded signature including signing scheme for the cancellation.
|
|
189
|
+
*/
|
|
190
|
+
static async signOrderCancellations(orderUids, chainId, signer) {
|
|
191
|
+
return signOrderCancellations(orderUids, chainId, signer);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Get the EIP-712 typed domain data being used for signing.
|
|
195
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainId` context that's being used.
|
|
196
|
+
* @return The EIP-712 typed domain data.
|
|
197
|
+
* @see https://eips.ethereum.org/EIPS/eip-712
|
|
198
|
+
*/
|
|
199
|
+
static async getDomain(chainId) {
|
|
200
|
+
return getDomain(chainId);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Hashes the order intent and generate deterministic order ID.
|
|
204
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainId` context that's being used.
|
|
205
|
+
* @param {Order} order order to sign
|
|
206
|
+
* @param {Pick<OrderUidParams, 'owner'>} params order unique identifier parameters.
|
|
207
|
+
*/
|
|
208
|
+
static async generateOrderId(chainId, order, params) {
|
|
209
|
+
return generateOrderId(chainId, order, params);
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Get the domain separator hash for the EIP-712 typed domain data being used for signing.
|
|
213
|
+
* @param chainId {SupportedChainId} chainId The CoW Protocol protocol `chainId` context that's being used.
|
|
214
|
+
* @returns A string representation of the EIP-712 typed domain data hash.
|
|
215
|
+
*/
|
|
216
|
+
static async getDomainSeparator(chainId) {
|
|
217
|
+
const adapter = (0, import_sdk_common2.getGlobalAdapter)();
|
|
218
|
+
const types = [
|
|
219
|
+
{ name: "name", type: "string" },
|
|
220
|
+
{ name: "version", type: "string" },
|
|
221
|
+
{ name: "chainId", type: "uint256" },
|
|
222
|
+
{ name: "verifyingContract", type: "address" }
|
|
223
|
+
];
|
|
224
|
+
return adapter.utils.hashDomain(getDomain(chainId), types);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Get the EIP-712 types used for signing a GPv2Order.Data struct. This is useful for when
|
|
228
|
+
* signing orders using smart contracts, whereby this SDK cannot do the EIP-1271 signing for you.
|
|
229
|
+
* @returns The EIP-712 types used for signing.
|
|
230
|
+
*/
|
|
231
|
+
static getEIP712Types() {
|
|
232
|
+
return {
|
|
233
|
+
Order: [
|
|
234
|
+
{ name: "sellToken", type: "address" },
|
|
235
|
+
{ name: "buyToken", type: "address" },
|
|
236
|
+
{ name: "receiver", type: "address" },
|
|
237
|
+
{ name: "sellAmount", type: "uint256" },
|
|
238
|
+
{ name: "buyAmount", type: "uint256" },
|
|
239
|
+
{ name: "validTo", type: "uint32" },
|
|
240
|
+
{ name: "appData", type: "bytes32" },
|
|
241
|
+
{ name: "feeAmount", type: "uint256" },
|
|
242
|
+
{ name: "kind", type: "string" },
|
|
243
|
+
{ name: "partiallyFillable", type: "bool" },
|
|
244
|
+
{ name: "sellTokenBalance", type: "string" },
|
|
245
|
+
{ name: "buyTokenBalance", type: "string" }
|
|
246
|
+
]
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
251
|
+
0 && (module.exports = {
|
|
252
|
+
OrderSigningUtils
|
|
253
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
// src/orderSigningUtils.ts
|
|
2
|
+
import {
|
|
3
|
+
getGlobalAdapter,
|
|
4
|
+
setGlobalAdapter
|
|
5
|
+
} from "@cowprotocol/sdk-common";
|
|
6
|
+
|
|
7
|
+
// src/utils.ts
|
|
8
|
+
import {
|
|
9
|
+
ContractsTs,
|
|
10
|
+
ContractsSigningScheme as SigningScheme,
|
|
11
|
+
getIntChainIdTypedDataV4Signer,
|
|
12
|
+
getTypedDataVersionedSigner,
|
|
13
|
+
hashOrder,
|
|
14
|
+
packOrderUidParams,
|
|
15
|
+
signOrder as signOrderGp,
|
|
16
|
+
signOrderCancellation as signOrderCancellationGp,
|
|
17
|
+
signOrderCancellations as signOrderCancellationsGp
|
|
18
|
+
} from "@cowprotocol/sdk-contracts-ts";
|
|
19
|
+
import { CowError } from "@cowprotocol/sdk-common";
|
|
20
|
+
import { EcdsaSigningScheme } from "@cowprotocol/sdk-order-book";
|
|
21
|
+
import { COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS } from "@cowprotocol/sdk-config";
|
|
22
|
+
var METAMASK_SIGNATURE_ERROR_CODE = -32603;
|
|
23
|
+
var METHOD_NOT_FOUND_ERROR_CODE = -32601;
|
|
24
|
+
var METHOD_NOT_FOUND_ERROR_MSG_REGEX = /Method not found/i;
|
|
25
|
+
var V4_ERROR_MSG_REGEX = /eth_signTypedData_v4 does not exist/i;
|
|
26
|
+
var V3_ERROR_MSG_REGEX = /eth_signTypedData_v3 does not exist/i;
|
|
27
|
+
var RPC_REQUEST_FAILED_REGEX = /RPC request failed/i;
|
|
28
|
+
var METAMASK_STRING_CHAINID_REGEX = /provided chainid .* must match the active chainid/i;
|
|
29
|
+
var mapSigningSchema = {
|
|
30
|
+
[EcdsaSigningScheme.EIP712]: SigningScheme.EIP712,
|
|
31
|
+
[EcdsaSigningScheme.ETHSIGN]: SigningScheme.ETHSIGN
|
|
32
|
+
};
|
|
33
|
+
function isProviderRpcError(error) {
|
|
34
|
+
return error.code !== void 0 || error.message !== void 0;
|
|
35
|
+
}
|
|
36
|
+
async function _signOrder(params) {
|
|
37
|
+
const { chainId, signer, order, signingScheme } = params;
|
|
38
|
+
const domain = getDomain(chainId);
|
|
39
|
+
return signOrderGp(domain, order, mapSigningSchema[signingScheme], signer);
|
|
40
|
+
}
|
|
41
|
+
async function _signOrderCancellation(params) {
|
|
42
|
+
const { chainId, signer, signingScheme, orderUid } = params;
|
|
43
|
+
const domain = getDomain(chainId);
|
|
44
|
+
return signOrderCancellationGp(domain, orderUid, mapSigningSchema[signingScheme], signer);
|
|
45
|
+
}
|
|
46
|
+
async function _signOrderCancellations(params) {
|
|
47
|
+
const { chainId, signer, signingScheme, orderUids } = params;
|
|
48
|
+
const domain = getDomain(chainId);
|
|
49
|
+
return signOrderCancellationsGp(domain, orderUids, mapSigningSchema[signingScheme], signer);
|
|
50
|
+
}
|
|
51
|
+
async function _signPayload(payload, signFn, signer, signingMethod = "v4") {
|
|
52
|
+
const signingScheme = signingMethod === "eth_sign" ? EcdsaSigningScheme.ETHSIGN : EcdsaSigningScheme.EIP712;
|
|
53
|
+
let signature = null;
|
|
54
|
+
let _signer;
|
|
55
|
+
try {
|
|
56
|
+
switch (signingMethod) {
|
|
57
|
+
case "default":
|
|
58
|
+
case "v3":
|
|
59
|
+
_signer = getTypedDataVersionedSigner(signer, "v3");
|
|
60
|
+
break;
|
|
61
|
+
case "int_v4":
|
|
62
|
+
_signer = getIntChainIdTypedDataV4Signer(signer);
|
|
63
|
+
break;
|
|
64
|
+
default:
|
|
65
|
+
_signer = signer;
|
|
66
|
+
}
|
|
67
|
+
} catch (e) {
|
|
68
|
+
console.error("Wallet not supported:", e);
|
|
69
|
+
throw new CowError("Wallet not supported");
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
signature = await signFn({ ...payload, signer: _signer, signingScheme });
|
|
73
|
+
} catch (e) {
|
|
74
|
+
if (!isProviderRpcError(e)) {
|
|
75
|
+
console.error(e);
|
|
76
|
+
throw e;
|
|
77
|
+
}
|
|
78
|
+
const regexErrorCheck = [METHOD_NOT_FOUND_ERROR_MSG_REGEX, RPC_REQUEST_FAILED_REGEX].some(
|
|
79
|
+
(regex) => (
|
|
80
|
+
// for example 1Inch error doesn't have e.message so we will check the output of toString()
|
|
81
|
+
[e.message, e.toString()].some((msg) => regex.test(msg))
|
|
82
|
+
)
|
|
83
|
+
);
|
|
84
|
+
if (e.code === METHOD_NOT_FOUND_ERROR_CODE || regexErrorCheck) {
|
|
85
|
+
switch (signingMethod) {
|
|
86
|
+
case "v4":
|
|
87
|
+
return _signPayload(payload, signFn, signer, "default");
|
|
88
|
+
case "default":
|
|
89
|
+
return _signPayload(payload, signFn, signer, "v3");
|
|
90
|
+
case "v3":
|
|
91
|
+
return _signPayload(payload, signFn, signer, "eth_sign");
|
|
92
|
+
default:
|
|
93
|
+
throw e;
|
|
94
|
+
}
|
|
95
|
+
} else if (METAMASK_STRING_CHAINID_REGEX.test(e.message)) {
|
|
96
|
+
return _signPayload(payload, signFn, signer, "int_v4");
|
|
97
|
+
} else if (e.code === METAMASK_SIGNATURE_ERROR_CODE) {
|
|
98
|
+
return _signPayload(payload, signFn, signer, "eth_sign");
|
|
99
|
+
} else if (V4_ERROR_MSG_REGEX.test(e.message)) {
|
|
100
|
+
return _signPayload(payload, signFn, signer, "v3");
|
|
101
|
+
} else if (V3_ERROR_MSG_REGEX.test(e.message)) {
|
|
102
|
+
return _signPayload(payload, signFn, signer, "eth_sign");
|
|
103
|
+
} else {
|
|
104
|
+
console.error(e);
|
|
105
|
+
throw e;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const data = signature?.data;
|
|
109
|
+
return { signature: data?.toString() || "", signingScheme };
|
|
110
|
+
}
|
|
111
|
+
async function signOrder(order, chainId, signer) {
|
|
112
|
+
return _signPayload({ order, chainId }, _signOrder, signer);
|
|
113
|
+
}
|
|
114
|
+
async function signOrderCancellation(orderUid, chainId, signer) {
|
|
115
|
+
return _signPayload({ orderUid, chainId }, _signOrderCancellation, signer);
|
|
116
|
+
}
|
|
117
|
+
async function signOrderCancellations(orderUids, chainId, signer) {
|
|
118
|
+
return _signPayload({ orderUids, chainId }, _signOrderCancellations, signer);
|
|
119
|
+
}
|
|
120
|
+
function getDomain(chainId) {
|
|
121
|
+
const settlementContract = COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS[chainId];
|
|
122
|
+
if (!settlementContract) {
|
|
123
|
+
throw new CowError("Unsupported network. Settlement contract is not deployed");
|
|
124
|
+
}
|
|
125
|
+
return ContractsTs.domain(chainId, settlementContract);
|
|
126
|
+
}
|
|
127
|
+
async function generateOrderId(chainId, order, params) {
|
|
128
|
+
const domain = await getDomain(chainId);
|
|
129
|
+
const orderDigest = hashOrder(domain, order);
|
|
130
|
+
const orderId = packOrderUidParams({
|
|
131
|
+
...params,
|
|
132
|
+
orderDigest,
|
|
133
|
+
// Different validTo when signing because EthFlow contract expects it to be max for all orders
|
|
134
|
+
validTo: order.validTo
|
|
135
|
+
});
|
|
136
|
+
return { orderId, orderDigest };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// src/orderSigningUtils.ts
|
|
140
|
+
var OrderSigningUtils = class {
|
|
141
|
+
constructor(adapter) {
|
|
142
|
+
if (adapter) {
|
|
143
|
+
setGlobalAdapter(adapter);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Sign the order intent with the specified signer.
|
|
148
|
+
*
|
|
149
|
+
* @remarks If the API reports an error with the signature, it is likely to be due to an incorrectly
|
|
150
|
+
* specified `chainId`. Please ensure that the `chainId` is correct for the network you are
|
|
151
|
+
* using.
|
|
152
|
+
* @param {UnsignedOrder} order The unsigned order intent to be placed.
|
|
153
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainId` context that's being used.
|
|
154
|
+
* @param {Signer} signer The signer who is placing the order intent.
|
|
155
|
+
* @returns {Promise<SigningResult>} Encoded signature including signing scheme for the order.
|
|
156
|
+
*/
|
|
157
|
+
static async signOrder(order, chainId, signer) {
|
|
158
|
+
return signOrder(order, chainId, signer);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Sign a cancellation message of an order intent with the specified signer.
|
|
162
|
+
* @param {string} orderUid The unique identifier of the order to cancel.
|
|
163
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainid` context that's being used.
|
|
164
|
+
* @param {Signer} signer The signer who initially placed the order intent.
|
|
165
|
+
* @returns {Promise<SigningResult>} Encoded signature including signing scheme for the cancellation.
|
|
166
|
+
*/
|
|
167
|
+
static async signOrderCancellation(orderUid, chainId, signer) {
|
|
168
|
+
return signOrderCancellation(orderUid, chainId, signer);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Sign a cancellation message of multiple order intents with the specified signer.
|
|
172
|
+
* @param {string[]} orderUids An array of `orderUid` to cancel.
|
|
173
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainId` context that's being used.
|
|
174
|
+
* @param {Signer} signer The signer who initially placed the order intents.
|
|
175
|
+
* @returns {Promise<SigningResult>} Encoded signature including signing scheme for the cancellation.
|
|
176
|
+
*/
|
|
177
|
+
static async signOrderCancellations(orderUids, chainId, signer) {
|
|
178
|
+
return signOrderCancellations(orderUids, chainId, signer);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Get the EIP-712 typed domain data being used for signing.
|
|
182
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainId` context that's being used.
|
|
183
|
+
* @return The EIP-712 typed domain data.
|
|
184
|
+
* @see https://eips.ethereum.org/EIPS/eip-712
|
|
185
|
+
*/
|
|
186
|
+
static async getDomain(chainId) {
|
|
187
|
+
return getDomain(chainId);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Hashes the order intent and generate deterministic order ID.
|
|
191
|
+
* @param {SupportedChainId} chainId The CoW Protocol `chainId` context that's being used.
|
|
192
|
+
* @param {Order} order order to sign
|
|
193
|
+
* @param {Pick<OrderUidParams, 'owner'>} params order unique identifier parameters.
|
|
194
|
+
*/
|
|
195
|
+
static async generateOrderId(chainId, order, params) {
|
|
196
|
+
return generateOrderId(chainId, order, params);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Get the domain separator hash for the EIP-712 typed domain data being used for signing.
|
|
200
|
+
* @param chainId {SupportedChainId} chainId The CoW Protocol protocol `chainId` context that's being used.
|
|
201
|
+
* @returns A string representation of the EIP-712 typed domain data hash.
|
|
202
|
+
*/
|
|
203
|
+
static async getDomainSeparator(chainId) {
|
|
204
|
+
const adapter = getGlobalAdapter();
|
|
205
|
+
const types = [
|
|
206
|
+
{ name: "name", type: "string" },
|
|
207
|
+
{ name: "version", type: "string" },
|
|
208
|
+
{ name: "chainId", type: "uint256" },
|
|
209
|
+
{ name: "verifyingContract", type: "address" }
|
|
210
|
+
];
|
|
211
|
+
return adapter.utils.hashDomain(getDomain(chainId), types);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Get the EIP-712 types used for signing a GPv2Order.Data struct. This is useful for when
|
|
215
|
+
* signing orders using smart contracts, whereby this SDK cannot do the EIP-1271 signing for you.
|
|
216
|
+
* @returns The EIP-712 types used for signing.
|
|
217
|
+
*/
|
|
218
|
+
static getEIP712Types() {
|
|
219
|
+
return {
|
|
220
|
+
Order: [
|
|
221
|
+
{ name: "sellToken", type: "address" },
|
|
222
|
+
{ name: "buyToken", type: "address" },
|
|
223
|
+
{ name: "receiver", type: "address" },
|
|
224
|
+
{ name: "sellAmount", type: "uint256" },
|
|
225
|
+
{ name: "buyAmount", type: "uint256" },
|
|
226
|
+
{ name: "validTo", type: "uint32" },
|
|
227
|
+
{ name: "appData", type: "bytes32" },
|
|
228
|
+
{ name: "feeAmount", type: "uint256" },
|
|
229
|
+
{ name: "kind", type: "string" },
|
|
230
|
+
{ name: "partiallyFillable", type: "bool" },
|
|
231
|
+
{ name: "sellTokenBalance", type: "string" },
|
|
232
|
+
{ name: "buyTokenBalance", type: "string" }
|
|
233
|
+
]
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
export {
|
|
238
|
+
OrderSigningUtils
|
|
239
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cowprotocol/sdk-order-signing",
|
|
3
|
+
"version": "0.1.0-monorepo.0",
|
|
4
|
+
"description": "TypeScript order signing for CoW Protocol SDK",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"sideEffects": false,
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/**"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsup src/index.ts --format esm,cjs --dts",
|
|
15
|
+
"dev": "tsup src/index.ts --format esm,cjs --watch --dts",
|
|
16
|
+
"lint": "eslint src/**/*.ts",
|
|
17
|
+
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
|
|
18
|
+
"test": "jest",
|
|
19
|
+
"test:watch": "jest --watch",
|
|
20
|
+
"test:coverage": "jest --coverage --json --outputFile=jest.results.json && cat ./coverage/lcov.info | coveralls",
|
|
21
|
+
"test:coverage:html": "jest --silent=false --coverage --coverageReporters html",
|
|
22
|
+
"typecheck": "tsc --noEmit"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@cowprotocol/sdk-common": "workspace:*",
|
|
26
|
+
"@cowprotocol/sdk-config": "workspace:*",
|
|
27
|
+
"@cowprotocol/sdk-contracts-ts": "workspace:*",
|
|
28
|
+
"@cowprotocol/sdk-order-book": "workspace:*"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@cowprotocol/sdk-ethers-v5-adapter": "workspace:*",
|
|
32
|
+
"@cowprotocol/sdk-ethers-v6-adapter": "workspace:*",
|
|
33
|
+
"@cow-sdk/typescript-config": "workspace:*",
|
|
34
|
+
"@cowprotocol/sdk-viem-adapter": "workspace:*",
|
|
35
|
+
"@types/jest": "^29.5.5",
|
|
36
|
+
"@types/node": "^20.17.31",
|
|
37
|
+
"ethers-v5": "npm:ethers@^5.7.2",
|
|
38
|
+
"ethers-v6": "npm:ethers@^6.13.7",
|
|
39
|
+
"jest": "^29.7.0",
|
|
40
|
+
"ts-jest": "^29.1.1",
|
|
41
|
+
"eslint": "^8.48.0",
|
|
42
|
+
"tsup": "^7.2.0",
|
|
43
|
+
"typescript": "^5.2.2",
|
|
44
|
+
"viem": "^2.28.4"
|
|
45
|
+
}
|
|
46
|
+
}
|