@cowprotocol/cow-sdk 6.2.0 → 6.3.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/dist/bridging/BridgingSdk/BridgingSdk.d.ts +3 -3
- package/dist/bridging/BridgingSdk/mock/bridgeRequestMocks.d.ts +2 -1
- package/dist/bridging/const.d.ts +1 -0
- package/dist/bridging/providers/across/AcrossBridgeProvider.d.ts +2 -2
- package/dist/bridging/providers/bungee/BungeeBridgeProvider.d.ts +3 -2
- package/dist/bridging/providers/bungee/types.d.ts +3 -2
- package/dist/bridging/providers/mock/MockBridgeProvider.d.ts +2 -2
- package/dist/bridging/providers/utils/getGasLimitEstimationForHook.d.ts +1 -1
- package/dist/bridging/types.d.ts +10 -2
- package/dist/chains/types.d.ts +4 -0
- package/dist/chains/utils.d.ts +1 -0
- package/dist/index-df7f4c3d.js +29 -0
- package/dist/index-df7f4c3d.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/index.modern.mjs +1 -1
- package/dist/index.module.js +4 -4
- package/dist/index.module.js.map +1 -1
- package/dist/package.json +2 -1
- package/dist/src/bridging/PROVIDER_README.md +56 -80
- package/dist/test/getWallet.d.ts +5 -0
- package/dist/{utils-0027f121.js → utils-d4263c91.js} +1 -1
- package/dist/{utils-0027f121.js.map → utils-d4263c91.js.map} +1 -1
- package/dist/{utils-23bf76fc.js → utils-f739380a.js} +1 -1
- package/dist/{utils-23bf76fc.js.map → utils-f739380a.js.map} +1 -1
- package/dist/{utils-fc43cd05.js → utils-f80c8347.js} +2 -2
- package/dist/{utils-fc43cd05.js.map → utils-f80c8347.js.map} +1 -1
- package/package.json +2 -1
- package/dist/index-7b4950ee.js +0 -29
- package/dist/index-7b4950ee.js.map +0 -1
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cowprotocol/cow-sdk",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.3.0",
|
|
4
4
|
"license": "(MIT OR Apache-2.0)",
|
|
5
5
|
"files": [
|
|
6
6
|
"/dist"
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"test": "jest",
|
|
25
25
|
"test:coverage": "jest --coverage --json --outputFile=jest.results.json && cat ./coverage/lcov.info | coveralls",
|
|
26
26
|
"test:coverage:html": "jest --silent=false --coverage --coverageReporters html",
|
|
27
|
+
"test:bungeeGnosisBridge": "yarn test --testPathPattern=BungeeGnosisBridge",
|
|
27
28
|
"codegen": "npm run swagger:codegen && npm run typechain:codegen",
|
|
28
29
|
"prepare": "npm run build",
|
|
29
30
|
"prepublishOnly": "npm test && npm run lint",
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
This guide explains how to develop a new bridge provider for the `CoW Protocol` `BridgingSDK`.
|
|
4
4
|
Bridge providers integrate third-party bridging protocols into the `CoW ecosystem`, enabling cross-chain token swaps.
|
|
5
5
|
|
|
6
|
-
>You can see existing providers code in [`src/bridging/providers`](./providers) directory.
|
|
6
|
+
> You can see existing providers code in [`src/bridging/providers`](./providers) directory.
|
|
7
7
|
|
|
8
8
|
## Table of Contents
|
|
9
9
|
|
|
@@ -92,37 +92,31 @@ interface BridgeProvider<Q extends BridgeQuoteResult> {
|
|
|
92
92
|
|
|
93
93
|
### Required Methods
|
|
94
94
|
|
|
95
|
-
| Method
|
|
96
|
-
|
|
97
|
-
| `getNetworks()`
|
|
98
|
-
| `getBuyTokens()`
|
|
99
|
-
| `getIntermediateTokens()`
|
|
100
|
-
| `getQuote()`
|
|
101
|
-
| `getUnsignedBridgeCall()`
|
|
102
|
-
| `getGasLimitEstimationForHook()` | Estimate gas for hook execution
|
|
103
|
-
| `getSignedHook()`
|
|
104
|
-
| `getStatus()`
|
|
105
|
-
| `getBridgingParams()`
|
|
106
|
-
| `getExplorerUrl()`
|
|
107
|
-
| `decodeBridgeHook()`
|
|
108
|
-
| `getCancelBridgingTx()`
|
|
109
|
-
| `getRefundBridgingTx()`
|
|
110
|
-
|
|
111
|
-
|
|
95
|
+
| Method | Purpose | Required |
|
|
96
|
+
| -------------------------------- | ------------------------------------- | ---------- |
|
|
97
|
+
| `getNetworks()` | Get supported destination chains | ✅ |
|
|
98
|
+
| `getBuyTokens()` | Get supported tokens for a chain | ✅ |
|
|
99
|
+
| `getIntermediateTokens()` | Get bridgeable tokens on source chain | ✅ |
|
|
100
|
+
| `getQuote()` | Generate bridge quote | ✅ |
|
|
101
|
+
| `getUnsignedBridgeCall()` | Create unsigned bridge transaction | ✅ |
|
|
102
|
+
| `getGasLimitEstimationForHook()` | Estimate gas for hook execution | ✅ |
|
|
103
|
+
| `getSignedHook()` | Generate pre-authorized hook | ✅ |
|
|
104
|
+
| `getStatus()` | Check bridge transaction status | ✅ |
|
|
105
|
+
| `getBridgingParams()` | Extract bridge params from settlement | ✅ |
|
|
106
|
+
| `getExplorerUrl()` | Get bridge explorer URL | ✅ |
|
|
107
|
+
| `decodeBridgeHook()` | Decode hook data | Optional\* |
|
|
108
|
+
| `getCancelBridgingTx()` | Create cancel transaction | Optional\* |
|
|
109
|
+
| `getRefundBridgingTx()` | Create refund transaction | Optional\* |
|
|
110
|
+
|
|
111
|
+
\*Can throw "Not implemented" error if unsupported
|
|
112
112
|
|
|
113
113
|
## Implementation Guide
|
|
114
114
|
|
|
115
115
|
### Step 1: Basic Provider Class
|
|
116
116
|
|
|
117
117
|
```typescript
|
|
118
|
-
import {
|
|
119
|
-
|
|
120
|
-
BridgeProviderInfo,
|
|
121
|
-
BridgeQuoteResult
|
|
122
|
-
} from '../../types'
|
|
123
|
-
import {
|
|
124
|
-
SupportedChainId, mainnet, polygon, arbitrumOne, optimism, ChainInfo
|
|
125
|
-
} from '../../../chains'
|
|
118
|
+
import { BridgeProvider, BridgeProviderInfo, BridgeQuoteResult } from '../../types'
|
|
119
|
+
import { SupportedChainId, mainnet, polygon, arbitrumOne, optimism, ChainInfo } from '../../../chains'
|
|
126
120
|
import { CowShedSdk } from '../../../cow-shed'
|
|
127
121
|
import { JsonRpcProvider } from '@ethersproject/providers'
|
|
128
122
|
import { HOOK_DAPP_BRIDGE_PROVIDER_PREFIX } from '../../const'
|
|
@@ -134,7 +128,7 @@ export const YOUR_BRIDGE_SUPPORTED_NETWORKS = [
|
|
|
134
128
|
mainnet,
|
|
135
129
|
polygon,
|
|
136
130
|
arbitrumOne,
|
|
137
|
-
optimism
|
|
131
|
+
optimism,
|
|
138
132
|
// Add your supported chains
|
|
139
133
|
// If there are no needed chains, add them to `src/chains`
|
|
140
134
|
]
|
|
@@ -187,7 +181,7 @@ export class YourBridgeProvider implements BridgeProvider<YourBridgeQuoteResult>
|
|
|
187
181
|
sellTokenAddress: params.sellTokenAddress,
|
|
188
182
|
})
|
|
189
183
|
|
|
190
|
-
return tokens.map(token => ({
|
|
184
|
+
return tokens.map((token) => ({
|
|
191
185
|
chainId: token.chainId,
|
|
192
186
|
address: token.address,
|
|
193
187
|
name: token.name,
|
|
@@ -204,14 +198,11 @@ export class YourBridgeProvider implements BridgeProvider<YourBridgeQuoteResult>
|
|
|
204
198
|
async getIntermediateTokens(request: QuoteBridgeRequest): Promise<TokenInfo[]> {
|
|
205
199
|
// Validate order kind
|
|
206
200
|
if (request.kind !== OrderKind.SELL) {
|
|
207
|
-
throw new BridgeProviderQuoteError(
|
|
208
|
-
BridgeQuoteErrors.ONLY_SELL_ORDER_SUPPORTED,
|
|
209
|
-
{kind: request.kind}
|
|
210
|
-
)
|
|
201
|
+
throw new BridgeProviderQuoteError(BridgeQuoteErrors.ONLY_SELL_ORDER_SUPPORTED, { kind: request.kind })
|
|
211
202
|
}
|
|
212
203
|
|
|
213
204
|
// Get tokens on source chain that can bridge to target token
|
|
214
|
-
const {sellTokenChainId, buyTokenChainId, buyTokenAddress} = request
|
|
205
|
+
const { sellTokenChainId, buyTokenChainId, buyTokenAddress } = request
|
|
215
206
|
|
|
216
207
|
const intermediateTokens = await this.api.getIntermediateTokens({
|
|
217
208
|
fromChainId: sellTokenChainId,
|
|
@@ -238,15 +229,12 @@ export class YourBridgeProvider implements BridgeProvider<YourBridgeQuoteResult>
|
|
|
238
229
|
amount,
|
|
239
230
|
receiver,
|
|
240
231
|
account,
|
|
241
|
-
owner
|
|
232
|
+
owner,
|
|
242
233
|
} = request
|
|
243
234
|
|
|
244
235
|
// Get CoW Shed account for the owner
|
|
245
236
|
const ownerAddress = owner ?? account
|
|
246
|
-
const cowShedAccount = this.cowShedSdk.getCowShedAccount(
|
|
247
|
-
sellTokenChainId,
|
|
248
|
-
ownerAddress
|
|
249
|
-
)
|
|
237
|
+
const cowShedAccount = this.cowShedSdk.getCowShedAccount(sellTokenChainId, ownerAddress)
|
|
250
238
|
|
|
251
239
|
// Request quote from external bridge
|
|
252
240
|
const externalQuote = await this.api.getQuote({
|
|
@@ -266,23 +254,14 @@ export class YourBridgeProvider implements BridgeProvider<YourBridgeQuoteResult>
|
|
|
266
254
|
return this.convertToBridgeQuote(externalQuote, request)
|
|
267
255
|
}
|
|
268
256
|
|
|
269
|
-
private async validateQuote(
|
|
270
|
-
externalQuote: YourBridgeQuote,
|
|
271
|
-
request: QuoteBridgeRequest
|
|
272
|
-
): Promise<void> {
|
|
257
|
+
private async validateQuote(externalQuote: YourBridgeQuote, request: QuoteBridgeRequest): Promise<void> {
|
|
273
258
|
// Add validation logic
|
|
274
259
|
if (!externalQuote.isValid) {
|
|
275
|
-
throw new BridgeProviderQuoteError(
|
|
276
|
-
BridgeQuoteErrors.NO_ROUTES_FOUND,
|
|
277
|
-
{quote: externalQuote}
|
|
278
|
-
)
|
|
260
|
+
throw new BridgeProviderQuoteError(BridgeQuoteErrors.NO_ROUTES_FOUND, { quote: externalQuote })
|
|
279
261
|
}
|
|
280
262
|
}
|
|
281
263
|
|
|
282
|
-
private convertToBridgeQuote(
|
|
283
|
-
externalQuote: YourBridgeQuote,
|
|
284
|
-
request: QuoteBridgeRequest
|
|
285
|
-
): YourBridgeQuoteResult {
|
|
264
|
+
private convertToBridgeQuote(externalQuote: YourBridgeQuote, request: QuoteBridgeRequest): YourBridgeQuoteResult {
|
|
286
265
|
return {
|
|
287
266
|
isSell: true,
|
|
288
267
|
amountsAndCosts: {
|
|
@@ -328,6 +307,7 @@ export class YourBridgeProvider implements BridgeProvider<YourBridgeQuoteResult>
|
|
|
328
307
|
|
|
329
308
|
> It very depends on your smart-contract implementation.
|
|
330
309
|
> Basically, the smart-contract should:
|
|
310
|
+
>
|
|
331
311
|
> 1. Approve sell token spending from `CoW Shed proxy`
|
|
332
312
|
> 2. Transfer funds from `CoW Shed proxy` to your deposit smart-contract
|
|
333
313
|
>
|
|
@@ -335,10 +315,7 @@ export class YourBridgeProvider implements BridgeProvider<YourBridgeQuoteResult>
|
|
|
335
315
|
|
|
336
316
|
```typescript
|
|
337
317
|
export class YourBridgeProvider implements BridgeProvider<YourBridgeQuoteResult> {
|
|
338
|
-
async getUnsignedBridgeCall(
|
|
339
|
-
request: QuoteBridgeRequest,
|
|
340
|
-
quote: YourBridgeQuoteResult
|
|
341
|
-
): Promise<EvmCall> {
|
|
318
|
+
async getUnsignedBridgeCall(request: QuoteBridgeRequest, quote: YourBridgeQuoteResult): Promise<EvmCall> {
|
|
342
319
|
// Create the bridge transaction that will be executed by CoW Shed
|
|
343
320
|
return createYourBridgeCall({
|
|
344
321
|
request,
|
|
@@ -356,7 +333,10 @@ import { EvmCall } from '../../../common'
|
|
|
356
333
|
import { YourBridgeQuoteResult } from '../types'
|
|
357
334
|
import { YOUR_BRIDGE_CONTRACTS, YOUR_BRIDGE_ABI } from '../const'
|
|
358
335
|
|
|
359
|
-
export async function createYourBridgeCall({
|
|
336
|
+
export async function createYourBridgeCall({
|
|
337
|
+
request,
|
|
338
|
+
quote,
|
|
339
|
+
}: {
|
|
360
340
|
request: QuoteBridgeRequest
|
|
361
341
|
quote: YourBridgeQuoteResult
|
|
362
342
|
}): Promise<EvmCall> {
|
|
@@ -401,13 +381,14 @@ import { getGasLimitEstimationForHook } from '../utils/getGasLimitEstimationForH
|
|
|
401
381
|
|
|
402
382
|
export class YourBridgeProvider implements BridgeProvider<YourBridgeQuoteResult> {
|
|
403
383
|
async getGasLimitEstimationForHook(
|
|
404
|
-
request: Omit<QuoteBridgeRequest, 'amount'>
|
|
384
|
+
request: Omit<QuoteBridgeRequest, 'amount'> & { extraGas?: number },
|
|
405
385
|
): Promise<number> {
|
|
406
386
|
// Use utility function or implement custom gas estimation
|
|
407
387
|
return getGasLimitEstimationForHook(
|
|
408
388
|
this.cowShedSdk,
|
|
409
389
|
request as QuoteBridgeRequest, // cast needed due to omit
|
|
410
|
-
this.getRpcProvider(request.sellTokenChainId)
|
|
390
|
+
this.getRpcProvider(request.sellTokenChainId),
|
|
391
|
+
request.extraGas, // to add extra gas to the hook.
|
|
411
392
|
)
|
|
412
393
|
}
|
|
413
394
|
|
|
@@ -421,13 +402,15 @@ export class YourBridgeProvider implements BridgeProvider<YourBridgeQuoteResult>
|
|
|
421
402
|
): Promise<BridgeHook> {
|
|
422
403
|
// Sign the multicall using CoW Shed SDK
|
|
423
404
|
const { signedMulticall, cowShedAccount, gasLimit } = await this.cowShedSdk.signCalls({
|
|
424
|
-
calls: [
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
405
|
+
calls: [
|
|
406
|
+
{
|
|
407
|
+
target: unsignedCall.to,
|
|
408
|
+
value: unsignedCall.value,
|
|
409
|
+
callData: unsignedCall.data,
|
|
410
|
+
allowFailure: false,
|
|
411
|
+
isDelegateCall: true,
|
|
412
|
+
},
|
|
413
|
+
],
|
|
431
414
|
chainId,
|
|
432
415
|
signer,
|
|
433
416
|
gasLimit: BigInt(hookGasLimit),
|
|
@@ -435,7 +418,7 @@ export class YourBridgeProvider implements BridgeProvider<YourBridgeQuoteResult>
|
|
|
435
418
|
nonce: bridgeHookNonce,
|
|
436
419
|
})
|
|
437
420
|
|
|
438
|
-
const {to, data} = signedMulticall
|
|
421
|
+
const { to, data } = signedMulticall
|
|
439
422
|
return {
|
|
440
423
|
postHook: {
|
|
441
424
|
target: to,
|
|
@@ -647,9 +630,7 @@ describe('YourBridgeProvider', () => {
|
|
|
647
630
|
// ... rest of request
|
|
648
631
|
}
|
|
649
632
|
|
|
650
|
-
await expect(provider.getQuote(request))
|
|
651
|
-
.rejects
|
|
652
|
-
.toThrow('Only sell orders are supported')
|
|
633
|
+
await expect(provider.getQuote(request)).rejects.toThrow('Only sell orders are supported')
|
|
653
634
|
})
|
|
654
635
|
})
|
|
655
636
|
|
|
@@ -663,23 +644,17 @@ describe('YourBridgeProvider', () => {
|
|
|
663
644
|
|
|
664
645
|
```typescript
|
|
665
646
|
// Use specific error types
|
|
666
|
-
throw new BridgeProviderQuoteError(
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
requestedAmount: '2000'
|
|
671
|
-
}
|
|
672
|
-
)
|
|
647
|
+
throw new BridgeProviderQuoteError(BridgeQuoteErrors.INSUFFICIENT_LIQUIDITY, {
|
|
648
|
+
availableLiquidity: '1000',
|
|
649
|
+
requestedAmount: '2000',
|
|
650
|
+
})
|
|
673
651
|
|
|
674
652
|
// Handle API failures gracefully
|
|
675
653
|
try {
|
|
676
654
|
return await this.api.getQuote(params)
|
|
677
655
|
} catch (error) {
|
|
678
656
|
if (error.status === 404) {
|
|
679
|
-
throw new BridgeProviderQuoteError(
|
|
680
|
-
BridgeQuoteErrors.NO_ROUTES_FOUND,
|
|
681
|
-
{ params }
|
|
682
|
-
)
|
|
657
|
+
throw new BridgeProviderQuoteError(BridgeQuoteErrors.NO_ROUTES_FOUND, { params })
|
|
683
658
|
}
|
|
684
659
|
throw error
|
|
685
660
|
}
|
|
@@ -768,6 +743,7 @@ const bridgingSdk = new BridgingSdk({
|
|
|
768
743
|
### Common Issues
|
|
769
744
|
|
|
770
745
|
1. **Gas Estimation Failures**
|
|
746
|
+
|
|
771
747
|
```typescript
|
|
772
748
|
import { getGasLimitEstimationForHook } from '../utils/getGasLimitEstimationForHook'
|
|
773
749
|
|
|
@@ -783,6 +759,7 @@ const bridgingSdk = new BridgingSdk({
|
|
|
783
759
|
```
|
|
784
760
|
|
|
785
761
|
2. **API Rate Limiting**
|
|
762
|
+
|
|
786
763
|
```typescript
|
|
787
764
|
// Implement retry logic with exponential backoff
|
|
788
765
|
private async withRetry<T>(operation: () => Promise<T>, maxRetries = 3): Promise<T> {
|
|
@@ -816,4 +793,3 @@ const bridgingSdk = new BridgingSdk({
|
|
|
816
793
|
- Test with small amounts first
|
|
817
794
|
- Validate against existing providers like `MockBridgeProvider`
|
|
818
795
|
- Monitor transaction status on both chains
|
|
819
|
-
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
import { SupportedChainId } from 'src/chains';
|
|
3
|
+
export declare function getRpcProvider(chainId: SupportedChainId): Promise<ethers.providers.JsonRpcProvider>;
|
|
4
|
+
export declare function getWallet(chainId: SupportedChainId): Promise<ethers.Wallet | null>;
|
|
5
|
+
export declare function getPk(): string | undefined;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
var e=require("@cowprotocol/contracts"),r=require("./index.js");require("cross-fetch/polyfill"),require("limiter"),require("exponential-backoff"),require("ethers"),require("@ethersproject/abstract-signer"),require("@cowprotocol/app-data"),require("ethers/lib/utils"),require("deepmerge"),require("@weiroll/weiroll.js"),require("graphql-request"),require("@openzeppelin/merkle-tree");const t=function(n,i,o,l="v4"){try{let f;function m(e){if(f)return e;const r=v?.data;return{signature:r?.toString()||"",signingScheme:p}}const p="eth_sign"===l?r.EcdsaSigningScheme.ETHSIGN:r.EcdsaSigningScheme.EIP712;let S,v=null;try{switch(l){case"default":case"v3":S=new e.TypedDataVersionedSigner(o);break;case"int_v4":S=new e.IntChainIdTypedDataV4Signer(o);break;default:S=o}}catch(P){throw console.error("Wallet not supported:",P),new r.CowError("Wallet not supported")}const w=function(e,r){try{var t=Promise.resolve(i({...n,signer:S,signingScheme:p})).then(function(e){v=e})}catch(e){return r(e)}return t&&t.then?t.then(void 0,r):t}(0,function(e){if(void 0===(r=e).code&&void 0===r.message)throw console.error(e),e;var r;const m=[a,h].some(r=>[e.message,e.toString()].some(e=>r.test(e)));if(e.code!==c&&!m){if(g.test(e.message)){const e=t(n,i,o,"int_v4");return f=1,e}if(e.code===s){const e=t(n,i,o,"eth_sign");return f=1,e}if(d.test(e.message)){const e=t(n,i,o,"v3");return f=1,e}if(u.test(e.message)){const e=t(n,i,o,"eth_sign");return f=1,e}throw console.error(e),e}switch(l){case"v4":const r=t(n,i,o,"default");return f=1,r;case"default":const s=t(n,i,o,"v3");return f=1,s;case"v3":const c=t(n,i,o,"eth_sign");return f=1,c;default:throw e}});return Promise.resolve(w&&w.then?w.then(m):m(w))}catch(q){return Promise.reject(q)}},n=function(r){try{const{chainId:t,signer:n,signingScheme:i,orderUids:o}=r,s=m(t);return Promise.resolve(e.signOrderCancellations(s,o,n,l[i]))}catch(e){return Promise.reject(e)}},i=function(r){try{const{chainId:t,signer:n,signingScheme:i,orderUid:o}=r,s=m(t);return Promise.resolve(e.signOrderCancellation(s,o,n,l[i]))}catch(e){return Promise.reject(e)}},o=function(r){try{const{chainId:t,signer:n,order:i,signingScheme:o}=r,s=m(t);return Promise.resolve(e.signOrder(s,i,n,l[o]))}catch(e){return Promise.reject(e)}},s=-32603,c=-32601,a=/Method not found/i,d=/eth_signTypedData_v4 does not exist/i,u=/eth_signTypedData_v3 does not exist/i,h=/RPC request failed/i,g=/provided chainid .* must match the active chainid/i,l={[r.EcdsaSigningScheme.EIP712]:e.SigningScheme.EIP712,[r.EcdsaSigningScheme.ETHSIGN]:e.SigningScheme.ETHSIGN};function m(t){const n=r.COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS[t];if(!n)throw new r.CowError("Unsupported network. Settlement contract is not deployed");return e.domain(t,n)}exports.generateOrderId=function(r,t,n){try{return Promise.resolve(m(r)).then(function(r){const i=e.hashOrder(r,t);return{orderId:e.packOrderUidParams({...n,orderDigest:i,validTo:t.validTo}),orderDigest:i}})}catch(e){return Promise.reject(e)}},exports.getDomain=m,exports.signOrder=function(e,r,n){return t({order:e,chainId:r},o,n)},exports.signOrderCancellation=function(e,r,n){return t({orderUid:e,chainId:r},i,n)},exports.signOrderCancellations=function(e,r,i){return t({orderUids:e,chainId:r},n,i)};
|
|
2
|
-
//# sourceMappingURL=utils-
|
|
2
|
+
//# sourceMappingURL=utils-d4263c91.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils-0027f121.js","sources":["../src/order-signing/utils.ts"],"sourcesContent":["import type {\n Order as OrderFromContract,\n Signature,\n TypedDataDomain,\n EcdsaSigningScheme as EcdsaSigningSchemeContract,\n Order,\n OrderUidParams,\n} from '@cowprotocol/contracts'\nimport {\n domain as domainGp,\n EcdsaSignature,\n IntChainIdTypedDataV4Signer,\n SigningScheme,\n hashOrder,\n packOrderUidParams,\n signOrder as signOrderGp,\n signOrderCancellation as signOrderCancellationGp,\n signOrderCancellations as signOrderCancellationsGp,\n TypedDataVersionedSigner,\n} from '@cowprotocol/contracts'\nimport type { Signer } from '@ethersproject/abstract-signer'\nimport type { SigningResult, SignOrderParams, SignOrderCancellationParams, UnsignedOrder } from './types'\n\nimport { COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS } from '../common/consts/contracts'\nimport { CowError } from '../common'\nimport type { SupportedChainId } from '../chains'\nimport { EcdsaSigningScheme } from '../order-book'\nimport { SignOrderCancellationsParams } from './types'\n\n// For error codes, see:\n// - https://eth.wiki/json-rpc/json-rpc-error-codes-improvement-proposal\n// - https://www.jsonrpc.org/specification#error_object\nconst METAMASK_SIGNATURE_ERROR_CODE = -32603\nconst METHOD_NOT_FOUND_ERROR_CODE = -32601\n// Added the following because of 1Inch wallet who doesn't send the error code\n// So we will check the actual error text\nconst METHOD_NOT_FOUND_ERROR_MSG_REGEX = /Method not found/i\nconst V4_ERROR_MSG_REGEX = /eth_signTypedData_v4 does not exist/i\nconst V3_ERROR_MSG_REGEX = /eth_signTypedData_v3 does not exist/i\nconst RPC_REQUEST_FAILED_REGEX = /RPC request failed/i\nconst METAMASK_STRING_CHAINID_REGEX = /provided chainid .* must match the active chainid/i\n\nconst mapSigningSchema: Record<EcdsaSigningScheme, EcdsaSigningSchemeContract> = {\n [EcdsaSigningScheme.EIP712]: SigningScheme.EIP712,\n [EcdsaSigningScheme.ETHSIGN]: SigningScheme.ETHSIGN,\n}\n\ninterface ProviderRpcError extends Error {\n message: string\n code: number\n data?: unknown\n}\n\ntype PayloadParams =\n | Pick<SignOrderParams, 'order' & 'chainId'>\n | Pick<SignOrderCancellationParams, 'chainId' & 'orderId'>\n | Pick<SignOrderCancellationsParams, 'chainId' & 'orderUids'>\n\nfunction isProviderRpcError(error: unknown): error is ProviderRpcError {\n return (error as ProviderRpcError).code !== undefined || (error as ProviderRpcError).message !== undefined\n}\n\nasync function _signOrder(params: SignOrderParams): Promise<Signature> {\n const { chainId, signer, order, signingScheme } = params\n\n const domain = getDomain(chainId)\n\n return signOrderGp(domain, order as unknown as OrderFromContract, signer, mapSigningSchema[signingScheme])\n}\n\nasync function _signOrderCancellation(params: SignOrderCancellationParams): Promise<Signature> {\n const { chainId, signer, signingScheme, orderUid } = params\n\n const domain = getDomain(chainId)\n\n return signOrderCancellationGp(domain, orderUid, signer, mapSigningSchema[signingScheme])\n}\n\nasync function _signOrderCancellations(params: SignOrderCancellationsParams): Promise<Signature> {\n const { chainId, signer, signingScheme, orderUids } = params\n\n const domain = getDomain(chainId)\n\n return signOrderCancellationsGp(domain, orderUids, signer, mapSigningSchema[signingScheme])\n}\n\nasync function _signPayload(\n payload: PayloadParams,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n signFn: (params: any) => Promise<Signature>,\n signer: Signer,\n signingMethod: 'default' | 'v4' | 'int_v4' | 'v3' | 'eth_sign' = 'v4',\n): Promise<SigningResult> {\n const signingScheme: EcdsaSigningScheme =\n signingMethod === 'eth_sign' ? EcdsaSigningScheme.ETHSIGN : EcdsaSigningScheme.EIP712\n let signature: Signature | null = null\n\n let _signer\n try {\n switch (signingMethod) {\n case 'default':\n case 'v3':\n _signer = new TypedDataVersionedSigner(signer)\n break\n case 'int_v4':\n _signer = new IntChainIdTypedDataV4Signer(signer)\n break\n default:\n _signer = signer\n }\n } catch (e) {\n console.error('Wallet not supported:', e)\n throw new CowError('Wallet not supported')\n }\n\n try {\n signature = (await signFn({ ...payload, signer: _signer, signingScheme })) as EcdsaSignature // Only ECDSA signing supported for now\n } catch (e: unknown) {\n if (!isProviderRpcError(e)) {\n // Some other error signing. Let it bubble up.\n console.error(e)\n throw e\n }\n\n const regexErrorCheck = [METHOD_NOT_FOUND_ERROR_MSG_REGEX, RPC_REQUEST_FAILED_REGEX].some((regex) =>\n // for example 1Inch error doesn't have e.message so we will check the output of toString()\n [(e as Error).message, (e as Error).toString()].some((msg) => regex.test(msg)),\n )\n\n if (e.code === METHOD_NOT_FOUND_ERROR_CODE || regexErrorCheck) {\n // Maybe the wallet returns the proper error code? We can only hope 🤞\n // OR it failed with a generic message, there's no error code set, and we also hope it'll work\n // with other methods...\n switch (signingMethod) {\n case 'v4':\n return _signPayload(payload, signFn, signer, 'default')\n case 'default':\n return _signPayload(payload, signFn, signer, 'v3')\n case 'v3':\n return _signPayload(payload, signFn, signer, 'eth_sign')\n default:\n throw e\n }\n } else if (METAMASK_STRING_CHAINID_REGEX.test(e.message)) {\n // Metamask now enforces chainId to be an integer\n return _signPayload(payload, signFn, signer, 'int_v4')\n } else if (e.code === METAMASK_SIGNATURE_ERROR_CODE) {\n // We tried to sign order the nice way.\n // That works fine for regular MM addresses. Does not work for Hardware wallets, though.\n // See https://github.com/MetaMask/metamask-extension/issues/10240#issuecomment-810552020\n // So, when that specific error occurs, we know this is a problem with MM + HW.\n // Then, we fallback to ETHSIGN.\n return _signPayload(payload, signFn, signer, 'eth_sign')\n } else if (V4_ERROR_MSG_REGEX.test(e.message)) {\n // Failed with `v4`, and the wallet does not set the proper error code\n return _signPayload(payload, signFn, signer, 'v3')\n } else if (V3_ERROR_MSG_REGEX.test(e.message)) {\n // Failed with `v3`, and the wallet does not set the proper error code\n return _signPayload(payload, signFn, signer, 'eth_sign')\n } else {\n // Some other error signing. Let it bubble up.\n console.error(e)\n throw e\n }\n }\n\n const data: unknown = signature?.data\n\n return { signature: data?.toString() || '', signingScheme }\n}\n\n/**\n * Returns the signature for the specified order with the signing scheme encoded\n * into the signature.\n * @param {UnsignedOrder} order The order to sign.\n * @param {SupportedChainId} chainId The chain Id\n * @param {Signer} signer The owner for the order used to sign.\n * @return {*} Encoded signature including signing scheme for the order.\n */\nexport async function signOrder(\n order: UnsignedOrder,\n chainId: SupportedChainId,\n signer: Signer,\n): Promise<SigningResult> {\n return _signPayload({ order, chainId }, _signOrder, signer)\n}\n\n/**\n * Returns the signature for the Order Cancellation with the signing scheme encoded\n * into the signature.\n * @param {string} orderUid The unique identifier of the order being cancelled.\n * @param {SupportedChainId} chainId The chain Id\n * @param {Signer} signer The owner for the order used to sign.\n * @return {*} Encoded signature including signing scheme for the order.\n */\nexport async function signOrderCancellation(\n orderUid: string,\n chainId: SupportedChainId,\n signer: Signer,\n): Promise<SigningResult> {\n return _signPayload({ orderUid, chainId }, _signOrderCancellation, signer)\n}\n\n/**\n * Returns the signature for the Order Cancellations with the signing scheme encoded\n * into the signature.\n *\n * @param {string[]} orderUids The unique identifiers of the orders being cancelled.\n * @param {SupportedChainId} chainId The CoW Protocol protocol `chainId` context that's being used.\n * @param {Signer} signer The owner that had placed the orders used to sign.\n * @returns {*} Encoded signature including signing scheme for the order.\n */\nexport async function signOrderCancellations(\n orderUids: string[],\n chainId: SupportedChainId,\n signer: Signer,\n): Promise<SigningResult> {\n return _signPayload({ orderUids, chainId }, _signOrderCancellations, signer)\n}\n\n/**\n * Returns the TypedDataDomain used for signing for the specified chainId.\n * @param {SupportedChainId} chainId The chain Id\n * @return {*} The TypedDataDomain for the specified chainId.\n * @throws {CowError} If the chainId is not supported.\n */\nexport function getDomain(chainId: SupportedChainId): TypedDataDomain {\n // Get settlement contract address\n const settlementContract = COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS[chainId]\n\n if (!settlementContract) {\n throw new CowError('Unsupported network. Settlement contract is not deployed')\n }\n\n return domainGp(chainId, settlementContract)\n}\n\n/**\n * Generate a deterministic order ID for the specified order.\n * @param {SupportedChainId} chainId The chain Id\n * @param {Order} order order to sign\n * @param {Pick<OrderUidParams, 'owner'>} params order unique identifier parameters.\n */\nexport async function generateOrderId(\n chainId: SupportedChainId,\n order: Order,\n params: Pick<OrderUidParams, 'owner'>,\n): Promise<{ orderId: string; orderDigest: string }> {\n const domain = await getDomain(chainId)\n const orderDigest = hashOrder(domain, order)\n // Generate the orderId from owner, orderDigest, and max validTo\n const orderId = packOrderUidParams({\n ...params,\n orderDigest,\n // Different validTo when signing because EthFlow contract expects it to be max for all orders\n validTo: order.validTo,\n })\n\n return { orderId, orderDigest }\n}\n"],"names":["_signPayload","payload","signFn","signer","signingMethod","_exit","_temp2","_result","data","signature","toString","signingScheme","EcdsaSigningScheme","ETHSIGN","EIP712","_signer","TypedDataVersionedSigner","IntChainIdTypedDataV4Signer","e","console","error","CowError","_temp","Promise","resolve","then","_signFn","_catch","undefined","code","message","regexErrorCheck","METHOD_NOT_FOUND_ERROR_MSG_REGEX","RPC_REQUEST_FAILED_REGEX","some","regex","msg","test","METHOD_NOT_FOUND_ERROR_CODE","METAMASK_STRING_CHAINID_REGEX","_signPayload5","METAMASK_SIGNATURE_ERROR_CODE","_signPayload6","V4_ERROR_MSG_REGEX","_signPayload7","V3_ERROR_MSG_REGEX","_signPayload8","_signPayload2","_signPayload3","_signPayload4","reject","_signOrderCancellations","params","chainId","orderUids","domain","getDomain","signOrderCancellationsGp","signOrderCancellations","mapSigningSchema","_signOrderCancellation","orderUid","signOrderCancellationGp","_signOrder","order","signOrderGp","SigningScheme","settlementContract","COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS","domainGp","generateOrderId","orderDigest","hashOrder","orderId","packOrderUidParams","validTo"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils-d4263c91.js","sources":["../src/order-signing/utils.ts"],"sourcesContent":["import type {\n Order as OrderFromContract,\n Signature,\n TypedDataDomain,\n EcdsaSigningScheme as EcdsaSigningSchemeContract,\n Order,\n OrderUidParams,\n} from '@cowprotocol/contracts'\nimport {\n domain as domainGp,\n EcdsaSignature,\n IntChainIdTypedDataV4Signer,\n SigningScheme,\n hashOrder,\n packOrderUidParams,\n signOrder as signOrderGp,\n signOrderCancellation as signOrderCancellationGp,\n signOrderCancellations as signOrderCancellationsGp,\n TypedDataVersionedSigner,\n} from '@cowprotocol/contracts'\nimport type { Signer } from '@ethersproject/abstract-signer'\nimport type { SigningResult, SignOrderParams, SignOrderCancellationParams, UnsignedOrder } from './types'\n\nimport { COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS } from '../common/consts/contracts'\nimport { CowError } from '../common'\nimport type { SupportedChainId } from '../chains'\nimport { EcdsaSigningScheme } from '../order-book'\nimport { SignOrderCancellationsParams } from './types'\n\n// For error codes, see:\n// - https://eth.wiki/json-rpc/json-rpc-error-codes-improvement-proposal\n// - https://www.jsonrpc.org/specification#error_object\nconst METAMASK_SIGNATURE_ERROR_CODE = -32603\nconst METHOD_NOT_FOUND_ERROR_CODE = -32601\n// Added the following because of 1Inch wallet who doesn't send the error code\n// So we will check the actual error text\nconst METHOD_NOT_FOUND_ERROR_MSG_REGEX = /Method not found/i\nconst V4_ERROR_MSG_REGEX = /eth_signTypedData_v4 does not exist/i\nconst V3_ERROR_MSG_REGEX = /eth_signTypedData_v3 does not exist/i\nconst RPC_REQUEST_FAILED_REGEX = /RPC request failed/i\nconst METAMASK_STRING_CHAINID_REGEX = /provided chainid .* must match the active chainid/i\n\nconst mapSigningSchema: Record<EcdsaSigningScheme, EcdsaSigningSchemeContract> = {\n [EcdsaSigningScheme.EIP712]: SigningScheme.EIP712,\n [EcdsaSigningScheme.ETHSIGN]: SigningScheme.ETHSIGN,\n}\n\ninterface ProviderRpcError extends Error {\n message: string\n code: number\n data?: unknown\n}\n\ntype PayloadParams =\n | Pick<SignOrderParams, 'order' & 'chainId'>\n | Pick<SignOrderCancellationParams, 'chainId' & 'orderId'>\n | Pick<SignOrderCancellationsParams, 'chainId' & 'orderUids'>\n\nfunction isProviderRpcError(error: unknown): error is ProviderRpcError {\n return (error as ProviderRpcError).code !== undefined || (error as ProviderRpcError).message !== undefined\n}\n\nasync function _signOrder(params: SignOrderParams): Promise<Signature> {\n const { chainId, signer, order, signingScheme } = params\n\n const domain = getDomain(chainId)\n\n return signOrderGp(domain, order as unknown as OrderFromContract, signer, mapSigningSchema[signingScheme])\n}\n\nasync function _signOrderCancellation(params: SignOrderCancellationParams): Promise<Signature> {\n const { chainId, signer, signingScheme, orderUid } = params\n\n const domain = getDomain(chainId)\n\n return signOrderCancellationGp(domain, orderUid, signer, mapSigningSchema[signingScheme])\n}\n\nasync function _signOrderCancellations(params: SignOrderCancellationsParams): Promise<Signature> {\n const { chainId, signer, signingScheme, orderUids } = params\n\n const domain = getDomain(chainId)\n\n return signOrderCancellationsGp(domain, orderUids, signer, mapSigningSchema[signingScheme])\n}\n\nasync function _signPayload(\n payload: PayloadParams,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n signFn: (params: any) => Promise<Signature>,\n signer: Signer,\n signingMethod: 'default' | 'v4' | 'int_v4' | 'v3' | 'eth_sign' = 'v4',\n): Promise<SigningResult> {\n const signingScheme: EcdsaSigningScheme =\n signingMethod === 'eth_sign' ? EcdsaSigningScheme.ETHSIGN : EcdsaSigningScheme.EIP712\n let signature: Signature | null = null\n\n let _signer\n try {\n switch (signingMethod) {\n case 'default':\n case 'v3':\n _signer = new TypedDataVersionedSigner(signer)\n break\n case 'int_v4':\n _signer = new IntChainIdTypedDataV4Signer(signer)\n break\n default:\n _signer = signer\n }\n } catch (e) {\n console.error('Wallet not supported:', e)\n throw new CowError('Wallet not supported')\n }\n\n try {\n signature = (await signFn({ ...payload, signer: _signer, signingScheme })) as EcdsaSignature // Only ECDSA signing supported for now\n } catch (e: unknown) {\n if (!isProviderRpcError(e)) {\n // Some other error signing. Let it bubble up.\n console.error(e)\n throw e\n }\n\n const regexErrorCheck = [METHOD_NOT_FOUND_ERROR_MSG_REGEX, RPC_REQUEST_FAILED_REGEX].some((regex) =>\n // for example 1Inch error doesn't have e.message so we will check the output of toString()\n [(e as Error).message, (e as Error).toString()].some((msg) => regex.test(msg)),\n )\n\n if (e.code === METHOD_NOT_FOUND_ERROR_CODE || regexErrorCheck) {\n // Maybe the wallet returns the proper error code? We can only hope 🤞\n // OR it failed with a generic message, there's no error code set, and we also hope it'll work\n // with other methods...\n switch (signingMethod) {\n case 'v4':\n return _signPayload(payload, signFn, signer, 'default')\n case 'default':\n return _signPayload(payload, signFn, signer, 'v3')\n case 'v3':\n return _signPayload(payload, signFn, signer, 'eth_sign')\n default:\n throw e\n }\n } else if (METAMASK_STRING_CHAINID_REGEX.test(e.message)) {\n // Metamask now enforces chainId to be an integer\n return _signPayload(payload, signFn, signer, 'int_v4')\n } else if (e.code === METAMASK_SIGNATURE_ERROR_CODE) {\n // We tried to sign order the nice way.\n // That works fine for regular MM addresses. Does not work for Hardware wallets, though.\n // See https://github.com/MetaMask/metamask-extension/issues/10240#issuecomment-810552020\n // So, when that specific error occurs, we know this is a problem with MM + HW.\n // Then, we fallback to ETHSIGN.\n return _signPayload(payload, signFn, signer, 'eth_sign')\n } else if (V4_ERROR_MSG_REGEX.test(e.message)) {\n // Failed with `v4`, and the wallet does not set the proper error code\n return _signPayload(payload, signFn, signer, 'v3')\n } else if (V3_ERROR_MSG_REGEX.test(e.message)) {\n // Failed with `v3`, and the wallet does not set the proper error code\n return _signPayload(payload, signFn, signer, 'eth_sign')\n } else {\n // Some other error signing. Let it bubble up.\n console.error(e)\n throw e\n }\n }\n\n const data: unknown = signature?.data\n\n return { signature: data?.toString() || '', signingScheme }\n}\n\n/**\n * Returns the signature for the specified order with the signing scheme encoded\n * into the signature.\n * @param {UnsignedOrder} order The order to sign.\n * @param {SupportedChainId} chainId The chain Id\n * @param {Signer} signer The owner for the order used to sign.\n * @return {*} Encoded signature including signing scheme for the order.\n */\nexport async function signOrder(\n order: UnsignedOrder,\n chainId: SupportedChainId,\n signer: Signer,\n): Promise<SigningResult> {\n return _signPayload({ order, chainId }, _signOrder, signer)\n}\n\n/**\n * Returns the signature for the Order Cancellation with the signing scheme encoded\n * into the signature.\n * @param {string} orderUid The unique identifier of the order being cancelled.\n * @param {SupportedChainId} chainId The chain Id\n * @param {Signer} signer The owner for the order used to sign.\n * @return {*} Encoded signature including signing scheme for the order.\n */\nexport async function signOrderCancellation(\n orderUid: string,\n chainId: SupportedChainId,\n signer: Signer,\n): Promise<SigningResult> {\n return _signPayload({ orderUid, chainId }, _signOrderCancellation, signer)\n}\n\n/**\n * Returns the signature for the Order Cancellations with the signing scheme encoded\n * into the signature.\n *\n * @param {string[]} orderUids The unique identifiers of the orders being cancelled.\n * @param {SupportedChainId} chainId The CoW Protocol protocol `chainId` context that's being used.\n * @param {Signer} signer The owner that had placed the orders used to sign.\n * @returns {*} Encoded signature including signing scheme for the order.\n */\nexport async function signOrderCancellations(\n orderUids: string[],\n chainId: SupportedChainId,\n signer: Signer,\n): Promise<SigningResult> {\n return _signPayload({ orderUids, chainId }, _signOrderCancellations, signer)\n}\n\n/**\n * Returns the TypedDataDomain used for signing for the specified chainId.\n * @param {SupportedChainId} chainId The chain Id\n * @return {*} The TypedDataDomain for the specified chainId.\n * @throws {CowError} If the chainId is not supported.\n */\nexport function getDomain(chainId: SupportedChainId): TypedDataDomain {\n // Get settlement contract address\n const settlementContract = COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS[chainId]\n\n if (!settlementContract) {\n throw new CowError('Unsupported network. Settlement contract is not deployed')\n }\n\n return domainGp(chainId, settlementContract)\n}\n\n/**\n * Generate a deterministic order ID for the specified order.\n * @param {SupportedChainId} chainId The chain Id\n * @param {Order} order order to sign\n * @param {Pick<OrderUidParams, 'owner'>} params order unique identifier parameters.\n */\nexport async function generateOrderId(\n chainId: SupportedChainId,\n order: Order,\n params: Pick<OrderUidParams, 'owner'>,\n): Promise<{ orderId: string; orderDigest: string }> {\n const domain = await getDomain(chainId)\n const orderDigest = hashOrder(domain, order)\n // Generate the orderId from owner, orderDigest, and max validTo\n const orderId = packOrderUidParams({\n ...params,\n orderDigest,\n // Different validTo when signing because EthFlow contract expects it to be max for all orders\n validTo: order.validTo,\n })\n\n return { orderId, orderDigest }\n}\n"],"names":["_signPayload","payload","signFn","signer","signingMethod","_exit","_temp2","_result","data","signature","toString","signingScheme","EcdsaSigningScheme","ETHSIGN","EIP712","_signer","TypedDataVersionedSigner","IntChainIdTypedDataV4Signer","e","console","error","CowError","_temp","Promise","resolve","then","_signFn","_catch","undefined","code","message","regexErrorCheck","METHOD_NOT_FOUND_ERROR_MSG_REGEX","RPC_REQUEST_FAILED_REGEX","some","regex","msg","test","METHOD_NOT_FOUND_ERROR_CODE","METAMASK_STRING_CHAINID_REGEX","_signPayload5","METAMASK_SIGNATURE_ERROR_CODE","_signPayload6","V4_ERROR_MSG_REGEX","_signPayload7","V3_ERROR_MSG_REGEX","_signPayload8","_signPayload2","_signPayload3","_signPayload4","reject","_signOrderCancellations","params","chainId","orderUids","domain","getDomain","signOrderCancellationsGp","signOrderCancellations","mapSigningSchema","_signOrderCancellation","orderUid","signOrderCancellationGp","_signOrder","order","signOrderGp","SigningScheme","settlementContract","COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS","domainGp","generateOrderId","orderDigest","hashOrder","orderId","packOrderUidParams","validTo"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import{hashOrder as e,packOrderUidParams as t,IntChainIdTypedDataV4Signer as r,TypedDataVersionedSigner as n,signOrderCancellations as o,signOrderCancellation as i,signOrder as s,SigningScheme as c,domain as a}from"@cowprotocol/contracts";import{EcdsaSigningScheme as d,CowError as u,COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS as l}from"./index.module.js";import"cross-fetch/polyfill";import"limiter";import"exponential-backoff";import"ethers";import"@ethersproject/abstract-signer";import"@cowprotocol/app-data";import"ethers/lib/utils";import"deepmerge";import"@weiroll/weiroll.js";import"graphql-request";import"@openzeppelin/merkle-tree";const h=function(r,n,o){try{return Promise.resolve(k(r)).then(function(r){const i=e(r,n);return{orderId:t({...o,orderDigest:i,validTo:n.validTo}),orderDigest:i}})}catch(e){return Promise.reject(e)}},m=function(e,t,r){return f({orderUids:e,chainId:t},v,r)},g=function(e,t,r){return f({orderUid:e,chainId:t},w,r)},p=function(e,t,r){return f({order:e,chainId:t},P,r)},f=function(e,t,o,i="v4"){try{let c;function s(e){if(c)return e;const t=h?.data;return{signature:t?.toString()||"",signingScheme:a}}const a="eth_sign"===i?d.ETHSIGN:d.EIP712;let l,h=null;try{switch(i){case"default":case"v3":l=new n(o);break;case"int_v4":l=new r(o);break;default:l=o}}catch(g){throw console.error("Wallet not supported:",g),new u("Wallet not supported")}const m=function(r,n){try{var o=Promise.resolve(t({...e,signer:l,signingScheme:a})).then(function(e){h=e})}catch(e){return n(e)}return o&&o.then?o.then(void 0,n):o}(0,function(r){if(void 0===(n=r).code&&void 0===n.message)throw console.error(r),r;var n;const s=[S,T].some(e=>[r.message,r.toString()].some(t=>e.test(t)));if(r.code!==y&&!s){if(E.test(r.message)){const r=f(e,t,o,"int_v4");return c=1,r}if(r.code===I){const r=f(e,t,o,"eth_sign");return c=1,r}if(_.test(r.message)){const r=f(e,t,o,"v3");return c=1,r}if(j.test(r.message)){const r=f(e,t,o,"eth_sign");return c=1,r}throw console.error(r),r}switch(i){case"v4":const n=f(e,t,o,"default");return c=1,n;case"default":const i=f(e,t,o,"v3");return c=1,i;case"v3":const s=f(e,t,o,"eth_sign");return c=1,s;default:throw r}});return Promise.resolve(m&&m.then?m.then(s):s(m))}catch(p){return Promise.reject(p)}},v=function(e){try{const{chainId:t,signer:r,signingScheme:n,orderUids:i}=e,s=k(t);return Promise.resolve(o(s,i,r,b[n]))}catch(e){return Promise.reject(e)}},w=function(e){try{const{chainId:t,signer:r,signingScheme:n,orderUid:o}=e,s=k(t);return Promise.resolve(i(s,o,r,b[n]))}catch(e){return Promise.reject(e)}},P=function(e){try{const{chainId:t,signer:r,order:n,signingScheme:o}=e,i=k(t);return Promise.resolve(s(i,n,r,b[o]))}catch(e){return Promise.reject(e)}},I=-32603,y=-32601,S=/Method not found/i,_=/eth_signTypedData_v4 does not exist/i,j=/eth_signTypedData_v3 does not exist/i,T=/RPC request failed/i,E=/provided chainid .* must match the active chainid/i,b={[d.EIP712]:c.EIP712,[d.ETHSIGN]:c.ETHSIGN};function k(e){const t=l[e];if(!t)throw new u("Unsupported network. Settlement contract is not deployed");return a(e,t)}export{h as generateOrderId,k as getDomain,p as signOrder,g as signOrderCancellation,m as signOrderCancellations};
|
|
2
|
-
//# sourceMappingURL=utils-
|
|
2
|
+
//# sourceMappingURL=utils-f739380a.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils-23bf76fc.js","sources":["../src/order-signing/utils.ts"],"sourcesContent":["import type {\n Order as OrderFromContract,\n Signature,\n TypedDataDomain,\n EcdsaSigningScheme as EcdsaSigningSchemeContract,\n Order,\n OrderUidParams,\n} from '@cowprotocol/contracts'\nimport {\n domain as domainGp,\n EcdsaSignature,\n IntChainIdTypedDataV4Signer,\n SigningScheme,\n hashOrder,\n packOrderUidParams,\n signOrder as signOrderGp,\n signOrderCancellation as signOrderCancellationGp,\n signOrderCancellations as signOrderCancellationsGp,\n TypedDataVersionedSigner,\n} from '@cowprotocol/contracts'\nimport type { Signer } from '@ethersproject/abstract-signer'\nimport type { SigningResult, SignOrderParams, SignOrderCancellationParams, UnsignedOrder } from './types'\n\nimport { COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS } from '../common/consts/contracts'\nimport { CowError } from '../common'\nimport type { SupportedChainId } from '../chains'\nimport { EcdsaSigningScheme } from '../order-book'\nimport { SignOrderCancellationsParams } from './types'\n\n// For error codes, see:\n// - https://eth.wiki/json-rpc/json-rpc-error-codes-improvement-proposal\n// - https://www.jsonrpc.org/specification#error_object\nconst METAMASK_SIGNATURE_ERROR_CODE = -32603\nconst METHOD_NOT_FOUND_ERROR_CODE = -32601\n// Added the following because of 1Inch wallet who doesn't send the error code\n// So we will check the actual error text\nconst METHOD_NOT_FOUND_ERROR_MSG_REGEX = /Method not found/i\nconst V4_ERROR_MSG_REGEX = /eth_signTypedData_v4 does not exist/i\nconst V3_ERROR_MSG_REGEX = /eth_signTypedData_v3 does not exist/i\nconst RPC_REQUEST_FAILED_REGEX = /RPC request failed/i\nconst METAMASK_STRING_CHAINID_REGEX = /provided chainid .* must match the active chainid/i\n\nconst mapSigningSchema: Record<EcdsaSigningScheme, EcdsaSigningSchemeContract> = {\n [EcdsaSigningScheme.EIP712]: SigningScheme.EIP712,\n [EcdsaSigningScheme.ETHSIGN]: SigningScheme.ETHSIGN,\n}\n\ninterface ProviderRpcError extends Error {\n message: string\n code: number\n data?: unknown\n}\n\ntype PayloadParams =\n | Pick<SignOrderParams, 'order' & 'chainId'>\n | Pick<SignOrderCancellationParams, 'chainId' & 'orderId'>\n | Pick<SignOrderCancellationsParams, 'chainId' & 'orderUids'>\n\nfunction isProviderRpcError(error: unknown): error is ProviderRpcError {\n return (error as ProviderRpcError).code !== undefined || (error as ProviderRpcError).message !== undefined\n}\n\nasync function _signOrder(params: SignOrderParams): Promise<Signature> {\n const { chainId, signer, order, signingScheme } = params\n\n const domain = getDomain(chainId)\n\n return signOrderGp(domain, order as unknown as OrderFromContract, signer, mapSigningSchema[signingScheme])\n}\n\nasync function _signOrderCancellation(params: SignOrderCancellationParams): Promise<Signature> {\n const { chainId, signer, signingScheme, orderUid } = params\n\n const domain = getDomain(chainId)\n\n return signOrderCancellationGp(domain, orderUid, signer, mapSigningSchema[signingScheme])\n}\n\nasync function _signOrderCancellations(params: SignOrderCancellationsParams): Promise<Signature> {\n const { chainId, signer, signingScheme, orderUids } = params\n\n const domain = getDomain(chainId)\n\n return signOrderCancellationsGp(domain, orderUids, signer, mapSigningSchema[signingScheme])\n}\n\nasync function _signPayload(\n payload: PayloadParams,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n signFn: (params: any) => Promise<Signature>,\n signer: Signer,\n signingMethod: 'default' | 'v4' | 'int_v4' | 'v3' | 'eth_sign' = 'v4',\n): Promise<SigningResult> {\n const signingScheme: EcdsaSigningScheme =\n signingMethod === 'eth_sign' ? EcdsaSigningScheme.ETHSIGN : EcdsaSigningScheme.EIP712\n let signature: Signature | null = null\n\n let _signer\n try {\n switch (signingMethod) {\n case 'default':\n case 'v3':\n _signer = new TypedDataVersionedSigner(signer)\n break\n case 'int_v4':\n _signer = new IntChainIdTypedDataV4Signer(signer)\n break\n default:\n _signer = signer\n }\n } catch (e) {\n console.error('Wallet not supported:', e)\n throw new CowError('Wallet not supported')\n }\n\n try {\n signature = (await signFn({ ...payload, signer: _signer, signingScheme })) as EcdsaSignature // Only ECDSA signing supported for now\n } catch (e: unknown) {\n if (!isProviderRpcError(e)) {\n // Some other error signing. Let it bubble up.\n console.error(e)\n throw e\n }\n\n const regexErrorCheck = [METHOD_NOT_FOUND_ERROR_MSG_REGEX, RPC_REQUEST_FAILED_REGEX].some((regex) =>\n // for example 1Inch error doesn't have e.message so we will check the output of toString()\n [(e as Error).message, (e as Error).toString()].some((msg) => regex.test(msg)),\n )\n\n if (e.code === METHOD_NOT_FOUND_ERROR_CODE || regexErrorCheck) {\n // Maybe the wallet returns the proper error code? We can only hope 🤞\n // OR it failed with a generic message, there's no error code set, and we also hope it'll work\n // with other methods...\n switch (signingMethod) {\n case 'v4':\n return _signPayload(payload, signFn, signer, 'default')\n case 'default':\n return _signPayload(payload, signFn, signer, 'v3')\n case 'v3':\n return _signPayload(payload, signFn, signer, 'eth_sign')\n default:\n throw e\n }\n } else if (METAMASK_STRING_CHAINID_REGEX.test(e.message)) {\n // Metamask now enforces chainId to be an integer\n return _signPayload(payload, signFn, signer, 'int_v4')\n } else if (e.code === METAMASK_SIGNATURE_ERROR_CODE) {\n // We tried to sign order the nice way.\n // That works fine for regular MM addresses. Does not work for Hardware wallets, though.\n // See https://github.com/MetaMask/metamask-extension/issues/10240#issuecomment-810552020\n // So, when that specific error occurs, we know this is a problem with MM + HW.\n // Then, we fallback to ETHSIGN.\n return _signPayload(payload, signFn, signer, 'eth_sign')\n } else if (V4_ERROR_MSG_REGEX.test(e.message)) {\n // Failed with `v4`, and the wallet does not set the proper error code\n return _signPayload(payload, signFn, signer, 'v3')\n } else if (V3_ERROR_MSG_REGEX.test(e.message)) {\n // Failed with `v3`, and the wallet does not set the proper error code\n return _signPayload(payload, signFn, signer, 'eth_sign')\n } else {\n // Some other error signing. Let it bubble up.\n console.error(e)\n throw e\n }\n }\n\n const data: unknown = signature?.data\n\n return { signature: data?.toString() || '', signingScheme }\n}\n\n/**\n * Returns the signature for the specified order with the signing scheme encoded\n * into the signature.\n * @param {UnsignedOrder} order The order to sign.\n * @param {SupportedChainId} chainId The chain Id\n * @param {Signer} signer The owner for the order used to sign.\n * @return {*} Encoded signature including signing scheme for the order.\n */\nexport async function signOrder(\n order: UnsignedOrder,\n chainId: SupportedChainId,\n signer: Signer,\n): Promise<SigningResult> {\n return _signPayload({ order, chainId }, _signOrder, signer)\n}\n\n/**\n * Returns the signature for the Order Cancellation with the signing scheme encoded\n * into the signature.\n * @param {string} orderUid The unique identifier of the order being cancelled.\n * @param {SupportedChainId} chainId The chain Id\n * @param {Signer} signer The owner for the order used to sign.\n * @return {*} Encoded signature including signing scheme for the order.\n */\nexport async function signOrderCancellation(\n orderUid: string,\n chainId: SupportedChainId,\n signer: Signer,\n): Promise<SigningResult> {\n return _signPayload({ orderUid, chainId }, _signOrderCancellation, signer)\n}\n\n/**\n * Returns the signature for the Order Cancellations with the signing scheme encoded\n * into the signature.\n *\n * @param {string[]} orderUids The unique identifiers of the orders being cancelled.\n * @param {SupportedChainId} chainId The CoW Protocol protocol `chainId` context that's being used.\n * @param {Signer} signer The owner that had placed the orders used to sign.\n * @returns {*} Encoded signature including signing scheme for the order.\n */\nexport async function signOrderCancellations(\n orderUids: string[],\n chainId: SupportedChainId,\n signer: Signer,\n): Promise<SigningResult> {\n return _signPayload({ orderUids, chainId }, _signOrderCancellations, signer)\n}\n\n/**\n * Returns the TypedDataDomain used for signing for the specified chainId.\n * @param {SupportedChainId} chainId The chain Id\n * @return {*} The TypedDataDomain for the specified chainId.\n * @throws {CowError} If the chainId is not supported.\n */\nexport function getDomain(chainId: SupportedChainId): TypedDataDomain {\n // Get settlement contract address\n const settlementContract = COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS[chainId]\n\n if (!settlementContract) {\n throw new CowError('Unsupported network. Settlement contract is not deployed')\n }\n\n return domainGp(chainId, settlementContract)\n}\n\n/**\n * Generate a deterministic order ID for the specified order.\n * @param {SupportedChainId} chainId The chain Id\n * @param {Order} order order to sign\n * @param {Pick<OrderUidParams, 'owner'>} params order unique identifier parameters.\n */\nexport async function generateOrderId(\n chainId: SupportedChainId,\n order: Order,\n params: Pick<OrderUidParams, 'owner'>,\n): Promise<{ orderId: string; orderDigest: string }> {\n const domain = await getDomain(chainId)\n const orderDigest = hashOrder(domain, order)\n // Generate the orderId from owner, orderDigest, and max validTo\n const orderId = packOrderUidParams({\n ...params,\n orderDigest,\n // Different validTo when signing because EthFlow contract expects it to be max for all orders\n validTo: order.validTo,\n })\n\n return { orderId, orderDigest }\n}\n"],"names":["generateOrderId","chainId","order","params","Promise","resolve","getDomain","then","domain","orderDigest","hashOrder","orderId","packOrderUidParams","validTo","e","reject","signOrderCancellations","orderUids","signer","_signPayload","_signOrderCancellations","signOrderCancellation","orderUid","_signOrderCancellation","signOrder","_signOrder","payload","signFn","signingMethod","_exit","_temp2","_result","data","signature","toString","signingScheme","EcdsaSigningScheme","ETHSIGN","EIP712","_signer","TypedDataVersionedSigner","IntChainIdTypedDataV4Signer","console","error","CowError","_temp","_signFn","_catch","undefined","code","message","regexErrorCheck","METHOD_NOT_FOUND_ERROR_MSG_REGEX","RPC_REQUEST_FAILED_REGEX","some","regex","msg","test","METHOD_NOT_FOUND_ERROR_CODE","METAMASK_STRING_CHAINID_REGEX","_signPayload5","METAMASK_SIGNATURE_ERROR_CODE","_signPayload6","V4_ERROR_MSG_REGEX","_signPayload7","V3_ERROR_MSG_REGEX","_signPayload8","_signPayload2","_signPayload3","_signPayload4","signOrderCancellationsGp","mapSigningSchema","signOrderCancellationGp","signOrderGp","SigningScheme","settlementContract","COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS","domainGp"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils-f739380a.js","sources":["../src/order-signing/utils.ts"],"sourcesContent":["import type {\n Order as OrderFromContract,\n Signature,\n TypedDataDomain,\n EcdsaSigningScheme as EcdsaSigningSchemeContract,\n Order,\n OrderUidParams,\n} from '@cowprotocol/contracts'\nimport {\n domain as domainGp,\n EcdsaSignature,\n IntChainIdTypedDataV4Signer,\n SigningScheme,\n hashOrder,\n packOrderUidParams,\n signOrder as signOrderGp,\n signOrderCancellation as signOrderCancellationGp,\n signOrderCancellations as signOrderCancellationsGp,\n TypedDataVersionedSigner,\n} from '@cowprotocol/contracts'\nimport type { Signer } from '@ethersproject/abstract-signer'\nimport type { SigningResult, SignOrderParams, SignOrderCancellationParams, UnsignedOrder } from './types'\n\nimport { COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS } from '../common/consts/contracts'\nimport { CowError } from '../common'\nimport type { SupportedChainId } from '../chains'\nimport { EcdsaSigningScheme } from '../order-book'\nimport { SignOrderCancellationsParams } from './types'\n\n// For error codes, see:\n// - https://eth.wiki/json-rpc/json-rpc-error-codes-improvement-proposal\n// - https://www.jsonrpc.org/specification#error_object\nconst METAMASK_SIGNATURE_ERROR_CODE = -32603\nconst METHOD_NOT_FOUND_ERROR_CODE = -32601\n// Added the following because of 1Inch wallet who doesn't send the error code\n// So we will check the actual error text\nconst METHOD_NOT_FOUND_ERROR_MSG_REGEX = /Method not found/i\nconst V4_ERROR_MSG_REGEX = /eth_signTypedData_v4 does not exist/i\nconst V3_ERROR_MSG_REGEX = /eth_signTypedData_v3 does not exist/i\nconst RPC_REQUEST_FAILED_REGEX = /RPC request failed/i\nconst METAMASK_STRING_CHAINID_REGEX = /provided chainid .* must match the active chainid/i\n\nconst mapSigningSchema: Record<EcdsaSigningScheme, EcdsaSigningSchemeContract> = {\n [EcdsaSigningScheme.EIP712]: SigningScheme.EIP712,\n [EcdsaSigningScheme.ETHSIGN]: SigningScheme.ETHSIGN,\n}\n\ninterface ProviderRpcError extends Error {\n message: string\n code: number\n data?: unknown\n}\n\ntype PayloadParams =\n | Pick<SignOrderParams, 'order' & 'chainId'>\n | Pick<SignOrderCancellationParams, 'chainId' & 'orderId'>\n | Pick<SignOrderCancellationsParams, 'chainId' & 'orderUids'>\n\nfunction isProviderRpcError(error: unknown): error is ProviderRpcError {\n return (error as ProviderRpcError).code !== undefined || (error as ProviderRpcError).message !== undefined\n}\n\nasync function _signOrder(params: SignOrderParams): Promise<Signature> {\n const { chainId, signer, order, signingScheme } = params\n\n const domain = getDomain(chainId)\n\n return signOrderGp(domain, order as unknown as OrderFromContract, signer, mapSigningSchema[signingScheme])\n}\n\nasync function _signOrderCancellation(params: SignOrderCancellationParams): Promise<Signature> {\n const { chainId, signer, signingScheme, orderUid } = params\n\n const domain = getDomain(chainId)\n\n return signOrderCancellationGp(domain, orderUid, signer, mapSigningSchema[signingScheme])\n}\n\nasync function _signOrderCancellations(params: SignOrderCancellationsParams): Promise<Signature> {\n const { chainId, signer, signingScheme, orderUids } = params\n\n const domain = getDomain(chainId)\n\n return signOrderCancellationsGp(domain, orderUids, signer, mapSigningSchema[signingScheme])\n}\n\nasync function _signPayload(\n payload: PayloadParams,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n signFn: (params: any) => Promise<Signature>,\n signer: Signer,\n signingMethod: 'default' | 'v4' | 'int_v4' | 'v3' | 'eth_sign' = 'v4',\n): Promise<SigningResult> {\n const signingScheme: EcdsaSigningScheme =\n signingMethod === 'eth_sign' ? EcdsaSigningScheme.ETHSIGN : EcdsaSigningScheme.EIP712\n let signature: Signature | null = null\n\n let _signer\n try {\n switch (signingMethod) {\n case 'default':\n case 'v3':\n _signer = new TypedDataVersionedSigner(signer)\n break\n case 'int_v4':\n _signer = new IntChainIdTypedDataV4Signer(signer)\n break\n default:\n _signer = signer\n }\n } catch (e) {\n console.error('Wallet not supported:', e)\n throw new CowError('Wallet not supported')\n }\n\n try {\n signature = (await signFn({ ...payload, signer: _signer, signingScheme })) as EcdsaSignature // Only ECDSA signing supported for now\n } catch (e: unknown) {\n if (!isProviderRpcError(e)) {\n // Some other error signing. Let it bubble up.\n console.error(e)\n throw e\n }\n\n const regexErrorCheck = [METHOD_NOT_FOUND_ERROR_MSG_REGEX, RPC_REQUEST_FAILED_REGEX].some((regex) =>\n // for example 1Inch error doesn't have e.message so we will check the output of toString()\n [(e as Error).message, (e as Error).toString()].some((msg) => regex.test(msg)),\n )\n\n if (e.code === METHOD_NOT_FOUND_ERROR_CODE || regexErrorCheck) {\n // Maybe the wallet returns the proper error code? We can only hope 🤞\n // OR it failed with a generic message, there's no error code set, and we also hope it'll work\n // with other methods...\n switch (signingMethod) {\n case 'v4':\n return _signPayload(payload, signFn, signer, 'default')\n case 'default':\n return _signPayload(payload, signFn, signer, 'v3')\n case 'v3':\n return _signPayload(payload, signFn, signer, 'eth_sign')\n default:\n throw e\n }\n } else if (METAMASK_STRING_CHAINID_REGEX.test(e.message)) {\n // Metamask now enforces chainId to be an integer\n return _signPayload(payload, signFn, signer, 'int_v4')\n } else if (e.code === METAMASK_SIGNATURE_ERROR_CODE) {\n // We tried to sign order the nice way.\n // That works fine for regular MM addresses. Does not work for Hardware wallets, though.\n // See https://github.com/MetaMask/metamask-extension/issues/10240#issuecomment-810552020\n // So, when that specific error occurs, we know this is a problem with MM + HW.\n // Then, we fallback to ETHSIGN.\n return _signPayload(payload, signFn, signer, 'eth_sign')\n } else if (V4_ERROR_MSG_REGEX.test(e.message)) {\n // Failed with `v4`, and the wallet does not set the proper error code\n return _signPayload(payload, signFn, signer, 'v3')\n } else if (V3_ERROR_MSG_REGEX.test(e.message)) {\n // Failed with `v3`, and the wallet does not set the proper error code\n return _signPayload(payload, signFn, signer, 'eth_sign')\n } else {\n // Some other error signing. Let it bubble up.\n console.error(e)\n throw e\n }\n }\n\n const data: unknown = signature?.data\n\n return { signature: data?.toString() || '', signingScheme }\n}\n\n/**\n * Returns the signature for the specified order with the signing scheme encoded\n * into the signature.\n * @param {UnsignedOrder} order The order to sign.\n * @param {SupportedChainId} chainId The chain Id\n * @param {Signer} signer The owner for the order used to sign.\n * @return {*} Encoded signature including signing scheme for the order.\n */\nexport async function signOrder(\n order: UnsignedOrder,\n chainId: SupportedChainId,\n signer: Signer,\n): Promise<SigningResult> {\n return _signPayload({ order, chainId }, _signOrder, signer)\n}\n\n/**\n * Returns the signature for the Order Cancellation with the signing scheme encoded\n * into the signature.\n * @param {string} orderUid The unique identifier of the order being cancelled.\n * @param {SupportedChainId} chainId The chain Id\n * @param {Signer} signer The owner for the order used to sign.\n * @return {*} Encoded signature including signing scheme for the order.\n */\nexport async function signOrderCancellation(\n orderUid: string,\n chainId: SupportedChainId,\n signer: Signer,\n): Promise<SigningResult> {\n return _signPayload({ orderUid, chainId }, _signOrderCancellation, signer)\n}\n\n/**\n * Returns the signature for the Order Cancellations with the signing scheme encoded\n * into the signature.\n *\n * @param {string[]} orderUids The unique identifiers of the orders being cancelled.\n * @param {SupportedChainId} chainId The CoW Protocol protocol `chainId` context that's being used.\n * @param {Signer} signer The owner that had placed the orders used to sign.\n * @returns {*} Encoded signature including signing scheme for the order.\n */\nexport async function signOrderCancellations(\n orderUids: string[],\n chainId: SupportedChainId,\n signer: Signer,\n): Promise<SigningResult> {\n return _signPayload({ orderUids, chainId }, _signOrderCancellations, signer)\n}\n\n/**\n * Returns the TypedDataDomain used for signing for the specified chainId.\n * @param {SupportedChainId} chainId The chain Id\n * @return {*} The TypedDataDomain for the specified chainId.\n * @throws {CowError} If the chainId is not supported.\n */\nexport function getDomain(chainId: SupportedChainId): TypedDataDomain {\n // Get settlement contract address\n const settlementContract = COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS[chainId]\n\n if (!settlementContract) {\n throw new CowError('Unsupported network. Settlement contract is not deployed')\n }\n\n return domainGp(chainId, settlementContract)\n}\n\n/**\n * Generate a deterministic order ID for the specified order.\n * @param {SupportedChainId} chainId The chain Id\n * @param {Order} order order to sign\n * @param {Pick<OrderUidParams, 'owner'>} params order unique identifier parameters.\n */\nexport async function generateOrderId(\n chainId: SupportedChainId,\n order: Order,\n params: Pick<OrderUidParams, 'owner'>,\n): Promise<{ orderId: string; orderDigest: string }> {\n const domain = await getDomain(chainId)\n const orderDigest = hashOrder(domain, order)\n // Generate the orderId from owner, orderDigest, and max validTo\n const orderId = packOrderUidParams({\n ...params,\n orderDigest,\n // Different validTo when signing because EthFlow contract expects it to be max for all orders\n validTo: order.validTo,\n })\n\n return { orderId, orderDigest }\n}\n"],"names":["generateOrderId","chainId","order","params","Promise","resolve","getDomain","then","domain","orderDigest","hashOrder","orderId","packOrderUidParams","validTo","e","reject","signOrderCancellations","orderUids","signer","_signPayload","_signOrderCancellations","signOrderCancellation","orderUid","_signOrderCancellation","signOrder","_signOrder","payload","signFn","signingMethod","_exit","_temp2","_result","data","signature","toString","signingScheme","EcdsaSigningScheme","ETHSIGN","EIP712","_signer","TypedDataVersionedSigner","IntChainIdTypedDataV4Signer","console","error","CowError","_temp","_signFn","_catch","undefined","code","message","regexErrorCheck","METHOD_NOT_FOUND_ERROR_MSG_REGEX","RPC_REQUEST_FAILED_REGEX","some","regex","msg","test","METHOD_NOT_FOUND_ERROR_CODE","METAMASK_STRING_CHAINID_REGEX","_signPayload5","METAMASK_SIGNATURE_ERROR_CODE","_signPayload6","V4_ERROR_MSG_REGEX","_signPayload7","V3_ERROR_MSG_REGEX","_signPayload8","_signPayload2","_signPayload3","_signPayload4","signOrderCancellationsGp","mapSigningSchema","signOrderCancellationGp","signOrderGp","SigningScheme","settlementContract","COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS","domainGp"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{C as e,_ as t,a as r,E as n}from"./index-
|
|
2
|
-
//# sourceMappingURL=utils-
|
|
1
|
+
import{C as e,_ as t,a as r,E as n}from"./index-df7f4c3d.js";import{domain as i,hashOrder as o,packOrderUidParams as s,IntChainIdTypedDataV4Signer as a,TypedDataVersionedSigner as c,signOrder as d,signOrderCancellation as l,signOrderCancellations as u,SigningScheme as g}from"@cowprotocol/contracts";import"cross-fetch/polyfill";import"limiter";import"exponential-backoff";import"ethers";import"@ethersproject/abstract-signer";import"@cowprotocol/app-data";import"ethers/lib/utils";import"deepmerge";import"@weiroll/weiroll.js";import"graphql-request";import"@openzeppelin/merkle-tree";const h=-32603,p=-32601,m=/Method not found/i,f=/eth_signTypedData_v4 does not exist/i,v=/eth_signTypedData_v3 does not exist/i,w=/RPC request failed/i,y=/provided chainid .* must match the active chainid/i,I={[n.EIP712]:g.EIP712,[n.ETHSIGN]:g.ETHSIGN};async function S(e){const{chainId:t,signer:r,order:n,signingScheme:i}=e,o=U(t);return d(o,n,r,I[i])}async function _(e){const{chainId:t,signer:r,signingScheme:n,orderUid:i}=e,o=U(t);return l(o,i,r,I[n])}async function E(e){const{chainId:t,signer:r,signingScheme:n,orderUids:i}=e,o=U(t);return u(o,i,r,I[n])}async function T(r,i,o,s="v4"){var d;const l="eth_sign"===s?n.ETHSIGN:n.EIP712;let u,g=null;try{switch(s){case"default":case"v3":u=new c(o);break;case"int_v4":u=new a(o);break;default:u=o}}catch(t){throw console.error("Wallet not supported:",t),new e("Wallet not supported")}try{g=await i(t({},r,{signer:u,signingScheme:l}))}catch(e){if(void 0===(I=e).code&&void 0===I.message)throw console.error(e),e;const t=[m,w].some(t=>[e.message,e.toString()].some(e=>t.test(e)));if(e.code!==p&&!t){if(y.test(e.message))return T(r,i,o,"int_v4");if(e.code===h)return T(r,i,o,"eth_sign");if(f.test(e.message))return T(r,i,o,"v3");if(v.test(e.message))return T(r,i,o,"eth_sign");throw console.error(e),e}switch(s){case"v4":return T(r,i,o,"default");case"default":return T(r,i,o,"v3");case"v3":return T(r,i,o,"eth_sign");default:throw e}}var I;const S=null==(d=g)?void 0:d.data;return{signature:(null==S?void 0:S.toString())||"",signingScheme:l}}async function b(e,t,r){return T({order:e,chainId:t},S,r)}async function k(e,t,r){return T({orderUid:e,chainId:t},_,r)}async function x(e,t,r){return T({orderUids:e,chainId:t},E,r)}function U(t){const n=r[t];if(!n)throw new e("Unsupported network. Settlement contract is not deployed");return i(t,n)}async function C(e,r,n){const i=await U(e),a=o(i,r);return{orderId:s(t({},n,{orderDigest:a,validTo:r.validTo})),orderDigest:a}}export{C as generateOrderId,U as getDomain,b as signOrder,k as signOrderCancellation,x as signOrderCancellations};
|
|
2
|
+
//# sourceMappingURL=utils-f80c8347.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils-fc43cd05.js","sources":["../src/order-signing/utils.ts"],"sourcesContent":["import type {\n Order as OrderFromContract,\n Signature,\n TypedDataDomain,\n EcdsaSigningScheme as EcdsaSigningSchemeContract,\n Order,\n OrderUidParams,\n} from '@cowprotocol/contracts'\nimport {\n domain as domainGp,\n EcdsaSignature,\n IntChainIdTypedDataV4Signer,\n SigningScheme,\n hashOrder,\n packOrderUidParams,\n signOrder as signOrderGp,\n signOrderCancellation as signOrderCancellationGp,\n signOrderCancellations as signOrderCancellationsGp,\n TypedDataVersionedSigner,\n} from '@cowprotocol/contracts'\nimport type { Signer } from '@ethersproject/abstract-signer'\nimport type { SigningResult, SignOrderParams, SignOrderCancellationParams, UnsignedOrder } from './types'\n\nimport { COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS } from '../common/consts/contracts'\nimport { CowError } from '../common'\nimport type { SupportedChainId } from '../chains'\nimport { EcdsaSigningScheme } from '../order-book'\nimport { SignOrderCancellationsParams } from './types'\n\n// For error codes, see:\n// - https://eth.wiki/json-rpc/json-rpc-error-codes-improvement-proposal\n// - https://www.jsonrpc.org/specification#error_object\nconst METAMASK_SIGNATURE_ERROR_CODE = -32603\nconst METHOD_NOT_FOUND_ERROR_CODE = -32601\n// Added the following because of 1Inch wallet who doesn't send the error code\n// So we will check the actual error text\nconst METHOD_NOT_FOUND_ERROR_MSG_REGEX = /Method not found/i\nconst V4_ERROR_MSG_REGEX = /eth_signTypedData_v4 does not exist/i\nconst V3_ERROR_MSG_REGEX = /eth_signTypedData_v3 does not exist/i\nconst RPC_REQUEST_FAILED_REGEX = /RPC request failed/i\nconst METAMASK_STRING_CHAINID_REGEX = /provided chainid .* must match the active chainid/i\n\nconst mapSigningSchema: Record<EcdsaSigningScheme, EcdsaSigningSchemeContract> = {\n [EcdsaSigningScheme.EIP712]: SigningScheme.EIP712,\n [EcdsaSigningScheme.ETHSIGN]: SigningScheme.ETHSIGN,\n}\n\ninterface ProviderRpcError extends Error {\n message: string\n code: number\n data?: unknown\n}\n\ntype PayloadParams =\n | Pick<SignOrderParams, 'order' & 'chainId'>\n | Pick<SignOrderCancellationParams, 'chainId' & 'orderId'>\n | Pick<SignOrderCancellationsParams, 'chainId' & 'orderUids'>\n\nfunction isProviderRpcError(error: unknown): error is ProviderRpcError {\n return (error as ProviderRpcError).code !== undefined || (error as ProviderRpcError).message !== undefined\n}\n\nasync function _signOrder(params: SignOrderParams): Promise<Signature> {\n const { chainId, signer, order, signingScheme } = params\n\n const domain = getDomain(chainId)\n\n return signOrderGp(domain, order as unknown as OrderFromContract, signer, mapSigningSchema[signingScheme])\n}\n\nasync function _signOrderCancellation(params: SignOrderCancellationParams): Promise<Signature> {\n const { chainId, signer, signingScheme, orderUid } = params\n\n const domain = getDomain(chainId)\n\n return signOrderCancellationGp(domain, orderUid, signer, mapSigningSchema[signingScheme])\n}\n\nasync function _signOrderCancellations(params: SignOrderCancellationsParams): Promise<Signature> {\n const { chainId, signer, signingScheme, orderUids } = params\n\n const domain = getDomain(chainId)\n\n return signOrderCancellationsGp(domain, orderUids, signer, mapSigningSchema[signingScheme])\n}\n\nasync function _signPayload(\n payload: PayloadParams,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n signFn: (params: any) => Promise<Signature>,\n signer: Signer,\n signingMethod: 'default' | 'v4' | 'int_v4' | 'v3' | 'eth_sign' = 'v4',\n): Promise<SigningResult> {\n const signingScheme: EcdsaSigningScheme =\n signingMethod === 'eth_sign' ? EcdsaSigningScheme.ETHSIGN : EcdsaSigningScheme.EIP712\n let signature: Signature | null = null\n\n let _signer\n try {\n switch (signingMethod) {\n case 'default':\n case 'v3':\n _signer = new TypedDataVersionedSigner(signer)\n break\n case 'int_v4':\n _signer = new IntChainIdTypedDataV4Signer(signer)\n break\n default:\n _signer = signer\n }\n } catch (e) {\n console.error('Wallet not supported:', e)\n throw new CowError('Wallet not supported')\n }\n\n try {\n signature = (await signFn({ ...payload, signer: _signer, signingScheme })) as EcdsaSignature // Only ECDSA signing supported for now\n } catch (e: unknown) {\n if (!isProviderRpcError(e)) {\n // Some other error signing. Let it bubble up.\n console.error(e)\n throw e\n }\n\n const regexErrorCheck = [METHOD_NOT_FOUND_ERROR_MSG_REGEX, RPC_REQUEST_FAILED_REGEX].some((regex) =>\n // for example 1Inch error doesn't have e.message so we will check the output of toString()\n [(e as Error).message, (e as Error).toString()].some((msg) => regex.test(msg)),\n )\n\n if (e.code === METHOD_NOT_FOUND_ERROR_CODE || regexErrorCheck) {\n // Maybe the wallet returns the proper error code? We can only hope 🤞\n // OR it failed with a generic message, there's no error code set, and we also hope it'll work\n // with other methods...\n switch (signingMethod) {\n case 'v4':\n return _signPayload(payload, signFn, signer, 'default')\n case 'default':\n return _signPayload(payload, signFn, signer, 'v3')\n case 'v3':\n return _signPayload(payload, signFn, signer, 'eth_sign')\n default:\n throw e\n }\n } else if (METAMASK_STRING_CHAINID_REGEX.test(e.message)) {\n // Metamask now enforces chainId to be an integer\n return _signPayload(payload, signFn, signer, 'int_v4')\n } else if (e.code === METAMASK_SIGNATURE_ERROR_CODE) {\n // We tried to sign order the nice way.\n // That works fine for regular MM addresses. Does not work for Hardware wallets, though.\n // See https://github.com/MetaMask/metamask-extension/issues/10240#issuecomment-810552020\n // So, when that specific error occurs, we know this is a problem with MM + HW.\n // Then, we fallback to ETHSIGN.\n return _signPayload(payload, signFn, signer, 'eth_sign')\n } else if (V4_ERROR_MSG_REGEX.test(e.message)) {\n // Failed with `v4`, and the wallet does not set the proper error code\n return _signPayload(payload, signFn, signer, 'v3')\n } else if (V3_ERROR_MSG_REGEX.test(e.message)) {\n // Failed with `v3`, and the wallet does not set the proper error code\n return _signPayload(payload, signFn, signer, 'eth_sign')\n } else {\n // Some other error signing. Let it bubble up.\n console.error(e)\n throw e\n }\n }\n\n const data: unknown = signature?.data\n\n return { signature: data?.toString() || '', signingScheme }\n}\n\n/**\n * Returns the signature for the specified order with the signing scheme encoded\n * into the signature.\n * @param {UnsignedOrder} order The order to sign.\n * @param {SupportedChainId} chainId The chain Id\n * @param {Signer} signer The owner for the order used to sign.\n * @return {*} Encoded signature including signing scheme for the order.\n */\nexport async function signOrder(\n order: UnsignedOrder,\n chainId: SupportedChainId,\n signer: Signer,\n): Promise<SigningResult> {\n return _signPayload({ order, chainId }, _signOrder, signer)\n}\n\n/**\n * Returns the signature for the Order Cancellation with the signing scheme encoded\n * into the signature.\n * @param {string} orderUid The unique identifier of the order being cancelled.\n * @param {SupportedChainId} chainId The chain Id\n * @param {Signer} signer The owner for the order used to sign.\n * @return {*} Encoded signature including signing scheme for the order.\n */\nexport async function signOrderCancellation(\n orderUid: string,\n chainId: SupportedChainId,\n signer: Signer,\n): Promise<SigningResult> {\n return _signPayload({ orderUid, chainId }, _signOrderCancellation, signer)\n}\n\n/**\n * Returns the signature for the Order Cancellations with the signing scheme encoded\n * into the signature.\n *\n * @param {string[]} orderUids The unique identifiers of the orders being cancelled.\n * @param {SupportedChainId} chainId The CoW Protocol protocol `chainId` context that's being used.\n * @param {Signer} signer The owner that had placed the orders used to sign.\n * @returns {*} Encoded signature including signing scheme for the order.\n */\nexport async function signOrderCancellations(\n orderUids: string[],\n chainId: SupportedChainId,\n signer: Signer,\n): Promise<SigningResult> {\n return _signPayload({ orderUids, chainId }, _signOrderCancellations, signer)\n}\n\n/**\n * Returns the TypedDataDomain used for signing for the specified chainId.\n * @param {SupportedChainId} chainId The chain Id\n * @return {*} The TypedDataDomain for the specified chainId.\n * @throws {CowError} If the chainId is not supported.\n */\nexport function getDomain(chainId: SupportedChainId): TypedDataDomain {\n // Get settlement contract address\n const settlementContract = COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS[chainId]\n\n if (!settlementContract) {\n throw new CowError('Unsupported network. Settlement contract is not deployed')\n }\n\n return domainGp(chainId, settlementContract)\n}\n\n/**\n * Generate a deterministic order ID for the specified order.\n * @param {SupportedChainId} chainId The chain Id\n * @param {Order} order order to sign\n * @param {Pick<OrderUidParams, 'owner'>} params order unique identifier parameters.\n */\nexport async function generateOrderId(\n chainId: SupportedChainId,\n order: Order,\n params: Pick<OrderUidParams, 'owner'>,\n): Promise<{ orderId: string; orderDigest: string }> {\n const domain = await getDomain(chainId)\n const orderDigest = hashOrder(domain, order)\n // Generate the orderId from owner, orderDigest, and max validTo\n const orderId = packOrderUidParams({\n ...params,\n orderDigest,\n // Different validTo when signing because EthFlow contract expects it to be max for all orders\n validTo: order.validTo,\n })\n\n return { orderId, orderDigest }\n}\n"],"names":["METAMASK_SIGNATURE_ERROR_CODE","METHOD_NOT_FOUND_ERROR_CODE","METHOD_NOT_FOUND_ERROR_MSG_REGEX","V4_ERROR_MSG_REGEX","V3_ERROR_MSG_REGEX","RPC_REQUEST_FAILED_REGEX","METAMASK_STRING_CHAINID_REGEX","mapSigningSchema","EcdsaSigningScheme","EIP712","SigningScheme","ETHSIGN","async","_signOrder","params","chainId","signer","order","signingScheme","domain","getDomain","signOrderGp","_signOrderCancellation","orderUid","signOrderCancellationGp","_signOrderCancellations","orderUids","signOrderCancellationsGp","_signPayload","payload","signFn","signingMethod","_signature","_signer","signature","TypedDataVersionedSigner","IntChainIdTypedDataV4Signer","e","console","error","CowError","_extends","undefined","code","message","regexErrorCheck","some","regex","toString","msg","test","data","signOrder","signOrderCancellation","signOrderCancellations","settlementContract","COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS","domainGp","generateOrderId","orderDigest","hashOrder","orderId","packOrderUidParams","validTo"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils-f80c8347.js","sources":["../src/order-signing/utils.ts"],"sourcesContent":["import type {\n Order as OrderFromContract,\n Signature,\n TypedDataDomain,\n EcdsaSigningScheme as EcdsaSigningSchemeContract,\n Order,\n OrderUidParams,\n} from '@cowprotocol/contracts'\nimport {\n domain as domainGp,\n EcdsaSignature,\n IntChainIdTypedDataV4Signer,\n SigningScheme,\n hashOrder,\n packOrderUidParams,\n signOrder as signOrderGp,\n signOrderCancellation as signOrderCancellationGp,\n signOrderCancellations as signOrderCancellationsGp,\n TypedDataVersionedSigner,\n} from '@cowprotocol/contracts'\nimport type { Signer } from '@ethersproject/abstract-signer'\nimport type { SigningResult, SignOrderParams, SignOrderCancellationParams, UnsignedOrder } from './types'\n\nimport { COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS } from '../common/consts/contracts'\nimport { CowError } from '../common'\nimport type { SupportedChainId } from '../chains'\nimport { EcdsaSigningScheme } from '../order-book'\nimport { SignOrderCancellationsParams } from './types'\n\n// For error codes, see:\n// - https://eth.wiki/json-rpc/json-rpc-error-codes-improvement-proposal\n// - https://www.jsonrpc.org/specification#error_object\nconst METAMASK_SIGNATURE_ERROR_CODE = -32603\nconst METHOD_NOT_FOUND_ERROR_CODE = -32601\n// Added the following because of 1Inch wallet who doesn't send the error code\n// So we will check the actual error text\nconst METHOD_NOT_FOUND_ERROR_MSG_REGEX = /Method not found/i\nconst V4_ERROR_MSG_REGEX = /eth_signTypedData_v4 does not exist/i\nconst V3_ERROR_MSG_REGEX = /eth_signTypedData_v3 does not exist/i\nconst RPC_REQUEST_FAILED_REGEX = /RPC request failed/i\nconst METAMASK_STRING_CHAINID_REGEX = /provided chainid .* must match the active chainid/i\n\nconst mapSigningSchema: Record<EcdsaSigningScheme, EcdsaSigningSchemeContract> = {\n [EcdsaSigningScheme.EIP712]: SigningScheme.EIP712,\n [EcdsaSigningScheme.ETHSIGN]: SigningScheme.ETHSIGN,\n}\n\ninterface ProviderRpcError extends Error {\n message: string\n code: number\n data?: unknown\n}\n\ntype PayloadParams =\n | Pick<SignOrderParams, 'order' & 'chainId'>\n | Pick<SignOrderCancellationParams, 'chainId' & 'orderId'>\n | Pick<SignOrderCancellationsParams, 'chainId' & 'orderUids'>\n\nfunction isProviderRpcError(error: unknown): error is ProviderRpcError {\n return (error as ProviderRpcError).code !== undefined || (error as ProviderRpcError).message !== undefined\n}\n\nasync function _signOrder(params: SignOrderParams): Promise<Signature> {\n const { chainId, signer, order, signingScheme } = params\n\n const domain = getDomain(chainId)\n\n return signOrderGp(domain, order as unknown as OrderFromContract, signer, mapSigningSchema[signingScheme])\n}\n\nasync function _signOrderCancellation(params: SignOrderCancellationParams): Promise<Signature> {\n const { chainId, signer, signingScheme, orderUid } = params\n\n const domain = getDomain(chainId)\n\n return signOrderCancellationGp(domain, orderUid, signer, mapSigningSchema[signingScheme])\n}\n\nasync function _signOrderCancellations(params: SignOrderCancellationsParams): Promise<Signature> {\n const { chainId, signer, signingScheme, orderUids } = params\n\n const domain = getDomain(chainId)\n\n return signOrderCancellationsGp(domain, orderUids, signer, mapSigningSchema[signingScheme])\n}\n\nasync function _signPayload(\n payload: PayloadParams,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n signFn: (params: any) => Promise<Signature>,\n signer: Signer,\n signingMethod: 'default' | 'v4' | 'int_v4' | 'v3' | 'eth_sign' = 'v4',\n): Promise<SigningResult> {\n const signingScheme: EcdsaSigningScheme =\n signingMethod === 'eth_sign' ? EcdsaSigningScheme.ETHSIGN : EcdsaSigningScheme.EIP712\n let signature: Signature | null = null\n\n let _signer\n try {\n switch (signingMethod) {\n case 'default':\n case 'v3':\n _signer = new TypedDataVersionedSigner(signer)\n break\n case 'int_v4':\n _signer = new IntChainIdTypedDataV4Signer(signer)\n break\n default:\n _signer = signer\n }\n } catch (e) {\n console.error('Wallet not supported:', e)\n throw new CowError('Wallet not supported')\n }\n\n try {\n signature = (await signFn({ ...payload, signer: _signer, signingScheme })) as EcdsaSignature // Only ECDSA signing supported for now\n } catch (e: unknown) {\n if (!isProviderRpcError(e)) {\n // Some other error signing. Let it bubble up.\n console.error(e)\n throw e\n }\n\n const regexErrorCheck = [METHOD_NOT_FOUND_ERROR_MSG_REGEX, RPC_REQUEST_FAILED_REGEX].some((regex) =>\n // for example 1Inch error doesn't have e.message so we will check the output of toString()\n [(e as Error).message, (e as Error).toString()].some((msg) => regex.test(msg)),\n )\n\n if (e.code === METHOD_NOT_FOUND_ERROR_CODE || regexErrorCheck) {\n // Maybe the wallet returns the proper error code? We can only hope 🤞\n // OR it failed with a generic message, there's no error code set, and we also hope it'll work\n // with other methods...\n switch (signingMethod) {\n case 'v4':\n return _signPayload(payload, signFn, signer, 'default')\n case 'default':\n return _signPayload(payload, signFn, signer, 'v3')\n case 'v3':\n return _signPayload(payload, signFn, signer, 'eth_sign')\n default:\n throw e\n }\n } else if (METAMASK_STRING_CHAINID_REGEX.test(e.message)) {\n // Metamask now enforces chainId to be an integer\n return _signPayload(payload, signFn, signer, 'int_v4')\n } else if (e.code === METAMASK_SIGNATURE_ERROR_CODE) {\n // We tried to sign order the nice way.\n // That works fine for regular MM addresses. Does not work for Hardware wallets, though.\n // See https://github.com/MetaMask/metamask-extension/issues/10240#issuecomment-810552020\n // So, when that specific error occurs, we know this is a problem with MM + HW.\n // Then, we fallback to ETHSIGN.\n return _signPayload(payload, signFn, signer, 'eth_sign')\n } else if (V4_ERROR_MSG_REGEX.test(e.message)) {\n // Failed with `v4`, and the wallet does not set the proper error code\n return _signPayload(payload, signFn, signer, 'v3')\n } else if (V3_ERROR_MSG_REGEX.test(e.message)) {\n // Failed with `v3`, and the wallet does not set the proper error code\n return _signPayload(payload, signFn, signer, 'eth_sign')\n } else {\n // Some other error signing. Let it bubble up.\n console.error(e)\n throw e\n }\n }\n\n const data: unknown = signature?.data\n\n return { signature: data?.toString() || '', signingScheme }\n}\n\n/**\n * Returns the signature for the specified order with the signing scheme encoded\n * into the signature.\n * @param {UnsignedOrder} order The order to sign.\n * @param {SupportedChainId} chainId The chain Id\n * @param {Signer} signer The owner for the order used to sign.\n * @return {*} Encoded signature including signing scheme for the order.\n */\nexport async function signOrder(\n order: UnsignedOrder,\n chainId: SupportedChainId,\n signer: Signer,\n): Promise<SigningResult> {\n return _signPayload({ order, chainId }, _signOrder, signer)\n}\n\n/**\n * Returns the signature for the Order Cancellation with the signing scheme encoded\n * into the signature.\n * @param {string} orderUid The unique identifier of the order being cancelled.\n * @param {SupportedChainId} chainId The chain Id\n * @param {Signer} signer The owner for the order used to sign.\n * @return {*} Encoded signature including signing scheme for the order.\n */\nexport async function signOrderCancellation(\n orderUid: string,\n chainId: SupportedChainId,\n signer: Signer,\n): Promise<SigningResult> {\n return _signPayload({ orderUid, chainId }, _signOrderCancellation, signer)\n}\n\n/**\n * Returns the signature for the Order Cancellations with the signing scheme encoded\n * into the signature.\n *\n * @param {string[]} orderUids The unique identifiers of the orders being cancelled.\n * @param {SupportedChainId} chainId The CoW Protocol protocol `chainId` context that's being used.\n * @param {Signer} signer The owner that had placed the orders used to sign.\n * @returns {*} Encoded signature including signing scheme for the order.\n */\nexport async function signOrderCancellations(\n orderUids: string[],\n chainId: SupportedChainId,\n signer: Signer,\n): Promise<SigningResult> {\n return _signPayload({ orderUids, chainId }, _signOrderCancellations, signer)\n}\n\n/**\n * Returns the TypedDataDomain used for signing for the specified chainId.\n * @param {SupportedChainId} chainId The chain Id\n * @return {*} The TypedDataDomain for the specified chainId.\n * @throws {CowError} If the chainId is not supported.\n */\nexport function getDomain(chainId: SupportedChainId): TypedDataDomain {\n // Get settlement contract address\n const settlementContract = COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS[chainId]\n\n if (!settlementContract) {\n throw new CowError('Unsupported network. Settlement contract is not deployed')\n }\n\n return domainGp(chainId, settlementContract)\n}\n\n/**\n * Generate a deterministic order ID for the specified order.\n * @param {SupportedChainId} chainId The chain Id\n * @param {Order} order order to sign\n * @param {Pick<OrderUidParams, 'owner'>} params order unique identifier parameters.\n */\nexport async function generateOrderId(\n chainId: SupportedChainId,\n order: Order,\n params: Pick<OrderUidParams, 'owner'>,\n): Promise<{ orderId: string; orderDigest: string }> {\n const domain = await getDomain(chainId)\n const orderDigest = hashOrder(domain, order)\n // Generate the orderId from owner, orderDigest, and max validTo\n const orderId = packOrderUidParams({\n ...params,\n orderDigest,\n // Different validTo when signing because EthFlow contract expects it to be max for all orders\n validTo: order.validTo,\n })\n\n return { orderId, orderDigest }\n}\n"],"names":["METAMASK_SIGNATURE_ERROR_CODE","METHOD_NOT_FOUND_ERROR_CODE","METHOD_NOT_FOUND_ERROR_MSG_REGEX","V4_ERROR_MSG_REGEX","V3_ERROR_MSG_REGEX","RPC_REQUEST_FAILED_REGEX","METAMASK_STRING_CHAINID_REGEX","mapSigningSchema","EcdsaSigningScheme","EIP712","SigningScheme","ETHSIGN","async","_signOrder","params","chainId","signer","order","signingScheme","domain","getDomain","signOrderGp","_signOrderCancellation","orderUid","signOrderCancellationGp","_signOrderCancellations","orderUids","signOrderCancellationsGp","_signPayload","payload","signFn","signingMethod","_signature","_signer","signature","TypedDataVersionedSigner","IntChainIdTypedDataV4Signer","e","console","error","CowError","_extends","undefined","code","message","regexErrorCheck","some","regex","toString","msg","test","data","signOrder","signOrderCancellation","signOrderCancellations","settlementContract","COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS","domainGp","generateOrderId","orderDigest","hashOrder","orderId","packOrderUidParams","validTo"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cowprotocol/cow-sdk",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.3.0",
|
|
4
4
|
"license": "(MIT OR Apache-2.0)",
|
|
5
5
|
"files": [
|
|
6
6
|
"/dist"
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"test": "jest",
|
|
25
25
|
"test:coverage": "jest --coverage --json --outputFile=jest.results.json && cat ./coverage/lcov.info | coveralls",
|
|
26
26
|
"test:coverage:html": "jest --silent=false --coverage --coverageReporters html",
|
|
27
|
+
"test:bungeeGnosisBridge": "yarn test --testPathPattern=BungeeGnosisBridge",
|
|
27
28
|
"codegen": "npm run swagger:codegen && npm run typechain:codegen",
|
|
28
29
|
"prepare": "npm run build",
|
|
29
30
|
"prepublishOnly": "npm test && npm run lint",
|