@cowprotocol/cow-sdk 0.0.8-RC.0 → 0.0.11

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.
Files changed (56) hide show
  1. package/README.md +102 -23
  2. package/dist/CowSdk.d.ts +2 -1
  3. package/dist/api/cow/index.d.ts +1 -1
  4. package/dist/api/cow/types.d.ts +34 -1
  5. package/dist/api/cow-subgraph/graphql.d.ts +2603 -0
  6. package/dist/api/cow-subgraph/index.d.ts +17 -0
  7. package/dist/api/cow-subgraph/queries.d.ts +3 -0
  8. package/dist/api/index.d.ts +1 -0
  9. package/dist/api/metadata/index.d.ts +3 -1
  10. package/dist/index.d.ts +3 -2
  11. package/dist/index.js +28 -1
  12. package/dist/index.js.map +1 -1
  13. package/dist/index.modern.js +28 -1
  14. package/dist/index.modern.js.map +1 -1
  15. package/dist/index.module.js +28 -1
  16. package/dist/index.module.js.map +1 -1
  17. package/dist/utils/context.d.ts +12 -3
  18. package/dist/utils/ipfs.d.ts +8 -0
  19. package/package.json +27 -6
  20. package/.babelrc +0 -4
  21. package/.eslintrc.json +0 -15
  22. package/.github/workflows/build.yml +0 -50
  23. package/.github/workflows/lint.yml +0 -19
  24. package/.github/workflows/publish.yml +0 -20
  25. package/.github/workflows/test.yml +0 -47
  26. package/.nvmrc +0 -1
  27. package/.prettierignore +0 -1
  28. package/.prettierrc +0 -5
  29. package/COPYRIGHT.md +0 -13
  30. package/LICENSE-APACHE +0 -201
  31. package/LICENSE-MIT +0 -21
  32. package/babel.config.js +0 -3
  33. package/docs/images/CoW.png +0 -0
  34. package/src/CowSdk.ts +0 -53
  35. package/src/api/cow/errors/OperatorError.ts +0 -142
  36. package/src/api/cow/errors/QuoteError.ts +0 -115
  37. package/src/api/cow/index.ts +0 -367
  38. package/src/api/cow/types.ts +0 -82
  39. package/src/api/index.ts +0 -2
  40. package/src/api/metadata/index.ts +0 -37
  41. package/src/api/metadata/types.ts +0 -17
  42. package/src/constants/chains.ts +0 -11
  43. package/src/constants/index.ts +0 -16
  44. package/src/constants/tokens.ts +0 -16
  45. package/src/index.ts +0 -4
  46. package/src/schemas/appData.schema.json +0 -70
  47. package/src/types/index.ts +0 -6
  48. package/src/utils/appData.spec.ts +0 -109
  49. package/src/utils/appData.ts +0 -58
  50. package/src/utils/common.ts +0 -35
  51. package/src/utils/context.ts +0 -89
  52. package/src/utils/price.ts +0 -44
  53. package/src/utils/sign.ts +0 -224
  54. package/src/utils/tokens.ts +0 -12
  55. package/src/workflows/publish.sh +0 -49
  56. package/tsconfig.json +0 -17
@@ -1,82 +0,0 @@
1
- import { OrderKind } from '@gnosis.pm/gp-v2-contracts'
2
- import { SupportedChainId as ChainId } from '../../constants/chains'
3
- import { OrderCancellation, SigningSchemeValue } from '../../utils/sign'
4
-
5
- /**
6
- * Unique identifier for the order, calculated by keccak256(orderDigest, ownerAddress, validTo),
7
- * where orderDigest = keccak256(orderStruct). bytes32.
8
- */
9
- export type OrderID = string
10
- export type ApiOrderStatus = 'fulfilled' | 'expired' | 'cancelled' | 'presignaturePending' | 'open'
11
-
12
- export interface OrderMetaData {
13
- creationDate: string
14
- owner: string
15
- uid: OrderID
16
- availableBalance: string
17
- executedBuyAmount: string
18
- executedSellAmount: string
19
- executedSellAmountBeforeFees: string
20
- executedFeeAmount: string
21
- invalidated: false
22
- sellToken: string
23
- buyToken: string
24
- sellAmount: string
25
- buyAmount: string
26
- validTo: number
27
- appData: number
28
- feeAmount: string
29
- kind: OrderKind
30
- partiallyFillable: false
31
- signature: string
32
- signingScheme: SigningSchemeValue
33
- status: ApiOrderStatus
34
- receiver: string
35
- }
36
-
37
- export interface TradeMetaData {
38
- blockNumber: number
39
- logIndex: number
40
- orderUid: OrderID
41
- owner: string
42
- sellToken: string
43
- buyToken: string
44
- sellAmount: string
45
- buyAmount: string
46
- sellAmountBeforeFees: string
47
- txHash: string
48
- }
49
-
50
- export interface UnsupportedToken {
51
- [token: string]: {
52
- address: string
53
- dateAdded: number
54
- }
55
- }
56
-
57
- export type PaginationParams = {
58
- limit?: number
59
- offset?: number
60
- }
61
-
62
- export type OrderCancellationParams = {
63
- chainId: ChainId
64
- cancellation: OrderCancellation
65
- owner: string
66
- }
67
-
68
- export type GetOrdersParams = {
69
- owner: string
70
- } & PaginationParams
71
-
72
- export type GetTradesParams = {
73
- owner: string
74
- } & PaginationParams
75
-
76
- export type ProfileData = {
77
- totalTrades: number
78
- totalReferrals: number
79
- tradeVolumeUsd: number
80
- referralVolumeUsd: number
81
- lastUpdated: string
82
- }
package/src/api/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from './cow'
2
- export * from './metadata'
@@ -1,37 +0,0 @@
1
- import log from 'loglevel'
2
- import { Context } from '../../utils/context'
3
- import { getSerializedCID, loadIpfsFromCid } from '../../utils/appData'
4
- import { AppDataDoc } from './types'
5
- import { CowError } from '../../utils/common'
6
-
7
- export class MetadataApi {
8
- context: Context
9
-
10
- constructor(context: Context) {
11
- this.context = context
12
- }
13
-
14
- async decodeAppData(hash: string): Promise<void | AppDataDoc> {
15
- try {
16
- const cidV0 = await getSerializedCID(hash)
17
- if (!cidV0) throw new CowError('Error getting serialized CID')
18
- return await loadIpfsFromCid(cidV0)
19
- } catch (error) {
20
- log.error('Error decoding AppData:', error)
21
- throw new CowError('Error decoding AppData: ' + error)
22
- }
23
- }
24
-
25
- async cidToAppDataHex(ipfsHash: string): Promise<string | void> {
26
- const { CID } = await import('multiformats/cid')
27
-
28
- const { digest } = CID.parse(ipfsHash).multihash
29
- return `0x${Buffer.from(digest).toString('hex')}`
30
- }
31
-
32
- async appDataHexToCid(hash: string): Promise<string | void> {
33
- const cidV0 = await getSerializedCID(hash)
34
- if (!cidV0) throw new CowError('Error getting serialized CID')
35
- return cidV0
36
- }
37
- }
@@ -1,17 +0,0 @@
1
- interface Metadata {
2
- version: string
3
- }
4
-
5
- export interface ReferralMetadata extends Metadata {
6
- address: string
7
- }
8
-
9
- export type MetadataDoc = {
10
- referrer?: ReferralMetadata
11
- }
12
-
13
- export type AppDataDoc = {
14
- version: string
15
- appCode?: string
16
- metadata: MetadataDoc
17
- }
@@ -1,11 +0,0 @@
1
- export enum SupportedChainId {
2
- MAINNET = 1,
3
- RINKEBY = 4,
4
- GNOSIS_CHAIN = 100,
5
- }
6
-
7
- export const ALL_SUPPORTED_CHAIN_IDS: SupportedChainId[] = [
8
- SupportedChainId.MAINNET,
9
- SupportedChainId.RINKEBY,
10
- SupportedChainId.GNOSIS_CHAIN,
11
- ]
@@ -1,16 +0,0 @@
1
- import contractNetworks from '@gnosis.pm/gp-v2-contracts/networks.json'
2
- import { SupportedChainId as ChainId } from './chains'
3
-
4
- const { GPv2Settlement } = contractNetworks
5
-
6
- export const GP_SETTLEMENT_CONTRACT_ADDRESS: Partial<Record<number, string>> = {
7
- [ChainId.MAINNET]: GPv2Settlement[ChainId.MAINNET].address,
8
- [ChainId.RINKEBY]: GPv2Settlement[ChainId.RINKEBY].address,
9
- [ChainId.GNOSIS_CHAIN]: GPv2Settlement[ChainId.GNOSIS_CHAIN].address,
10
- }
11
-
12
- export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
13
-
14
- export const DEFAULT_APP_DATA_HASH = '0x0000000000000000000000000000000000000000000000000000000000000000'
15
-
16
- export const DEFAULT_IPFS_GATEWAY_URI = 'https://gnosis.mypinata.cloud/ipfs'
@@ -1,16 +0,0 @@
1
- import { SupportedChainId as ChainId } from './chains'
2
- import { Token } from '../types'
3
-
4
- export const XDAI_SYMBOL = 'XDAI'
5
-
6
- export const WRAPPED_NATIVE_TOKEN: Record<ChainId, Token> = {
7
- [ChainId.MAINNET]: new Token('WETH', '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'),
8
- [ChainId.RINKEBY]: new Token('WETH', '0xc778417E063141139Fce010982780140Aa0cD5Ab'),
9
- [ChainId.GNOSIS_CHAIN]: new Token('WXDAI', '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d'),
10
- }
11
-
12
- export const NATIVE: Record<ChainId, string> = {
13
- [ChainId.MAINNET]: 'ETH',
14
- [ChainId.RINKEBY]: 'ETH',
15
- [ChainId.GNOSIS_CHAIN]: XDAI_SYMBOL,
16
- }
package/src/index.ts DELETED
@@ -1,4 +0,0 @@
1
- export { CowError } from './utils/common'
2
- export { ALL_SUPPORTED_CHAIN_IDS } from './constants/chains'
3
- export * from './types'
4
- export { CowSdk } from './CowSdk'
@@ -1,70 +0,0 @@
1
- {
2
- "$id": "https://cowswap.exchange/appdata.schema.json",
3
- "$schema": "http://json-schema.org/draft-07/schema",
4
- "description": "Metadata JSON document for adding information to orders.",
5
- "required": ["version", "metadata"],
6
- "title": "AppData Root Schema",
7
- "type": "object",
8
- "properties": {
9
- "version": {
10
- "$id": "#/properties/version",
11
- "description": "Semantic versioning of document",
12
- "examples": ["1.0.0", "1.2.3"],
13
- "title": "Semantic Versioning",
14
- "type": "string"
15
- },
16
- "appCode": {
17
- "$id": "#/properties/appCode",
18
- "description": "The code identifying the CLI, UI, service generating the order.",
19
- "examples": ["CowSwap"],
20
- "title": "App Code",
21
- "type": "string"
22
- },
23
- "metadata": {
24
- "$id": "#/properties/metadata",
25
- "default": {},
26
- "description": "Each metadata will specify one aspect of the order.",
27
- "required": [],
28
- "title": "Metadata descriptors",
29
- "type": "object",
30
- "properties": {
31
- "referrer": {
32
- "$ref": "#/definitions/kindMetadata/referrer"
33
- }
34
- }
35
- }
36
- },
37
- "definitions": {
38
- "version": {
39
- "$id": "#/definitions/version",
40
- "description": "Semantic versioning of document",
41
- "examples": ["1.0.0", "1.2.3"],
42
- "title": "Semantic Versioning",
43
- "type": "string"
44
- },
45
- "ethereumAddress": {
46
- "$id": "#/definitions/ethereumAddress",
47
- "pattern": "^0x[a-fA-F0-9]{40}$",
48
- "title": "Ethereum compatible address",
49
- "examples": ["0xb6BAd41ae76A11D10f7b0E664C5007b908bC77C9"],
50
- "type": "string"
51
- },
52
- "kindMetadata": {
53
- "referrer": {
54
- "$id": "#/definitions/referrer",
55
- "required": ["version", "address"],
56
- "title": "Referrer",
57
- "type": "object",
58
- "properties": {
59
- "version": {
60
- "$ref": "#/definitions/version"
61
- },
62
- "address": {
63
- "$ref": "#/definitions/ethereumAddress",
64
- "title": "Referrer address"
65
- }
66
- }
67
- }
68
- }
69
- }
70
- }
@@ -1,6 +0,0 @@
1
- export * from '../api/cow/types'
2
- export * from '../api/metadata/types'
3
- export { OrderKind } from '@gnosis.pm/gp-v2-contracts'
4
- export class Token {
5
- constructor(public symbol: string, public address: string) {}
6
- }
@@ -1,109 +0,0 @@
1
- import { validateAppDataDocument, getSerializedCID, loadIpfsFromCid } from './appData'
2
-
3
- const VALID_RESULT = {
4
- result: true,
5
- }
6
-
7
- const INVALID_CID_LENGTH = 'Incorrect length'
8
-
9
- test('Valid minimal document', async () => {
10
- const validation = await validateAppDataDocument({
11
- version: '0.1.0',
12
- metadata: {},
13
- })
14
- expect(validation).toEqual(VALID_RESULT)
15
- })
16
-
17
- test('Valid minimal document + appCode', async () => {
18
- const validation = await validateAppDataDocument({
19
- version: '0.1.0',
20
- appCode: 'MyApp',
21
- metadata: {},
22
- })
23
- expect(validation).toEqual(VALID_RESULT)
24
- })
25
-
26
- test('Valid minimal document + appCode + referrer', async () => {
27
- const validation = await validateAppDataDocument({
28
- version: '0.1.0',
29
- appCode: 'MyApp',
30
- metadata: {
31
- referrer: {
32
- version: '0.1.0',
33
- address: '0xFEB4acf3df3cDEA7399794D0869ef76A6EfAff52',
34
- },
35
- },
36
- })
37
- expect(validation).toEqual(VALID_RESULT)
38
- })
39
-
40
- test('Invalid: Bad referrer', async () => {
41
- const validation = await validateAppDataDocument({
42
- version: '0.1.0',
43
- appCode: 'MyApp',
44
- metadata: {
45
- referrer: {
46
- version: '0.1.0',
47
- address: 'this is not an ethereum address',
48
- },
49
- },
50
- })
51
- expect(validation.result).toBeFalsy()
52
- })
53
-
54
- test('Invalid: No version', async () => {
55
- const validation = await validateAppDataDocument({
56
- appCode: 'MyApp',
57
- metadata: {},
58
- })
59
- expect(validation.result).toBeFalsy()
60
- })
61
-
62
- test('Invalid: No metadata', async () => {
63
- const validation = await validateAppDataDocument({
64
- version: '0.1.0',
65
- appCode: 'MyApp',
66
- })
67
- expect(validation.result).toBeFalsy()
68
- })
69
-
70
- test('Invalid: No metadata', async () => {
71
- const validation = await validateAppDataDocument({
72
- version: '0.1.0',
73
- appCode: 'MyApp',
74
- })
75
- expect(validation.result).toBeFalsy()
76
- })
77
-
78
- test('Invalid: No metadata', async () => {
79
- const validation = await validateAppDataDocument({
80
- version: '0.1.0',
81
- appCode: 'MyApp',
82
- })
83
- expect(validation.result).toBeFalsy()
84
- })
85
-
86
- test('Valid serialized appData CID', async () => {
87
- const hash = '0xa6c81f4ca727252a05b108f1742a07430f28d474d2a3492d8f325746824d22e5'
88
- const serializedCidV0 = 'QmZZhNnqMF1gRywNKnTPuZksX7rVjQgTT3TJAZ7R6VE3b2'
89
- const cidV0 = await getSerializedCID(hash)
90
-
91
- expect(cidV0).toEqual(serializedCidV0)
92
- })
93
-
94
- test('Invalid: serialized appData CID format ', async () => {
95
- const invalidHash = '0xa6c81f4ca727252a05b108f1742'
96
- try {
97
- await getSerializedCID(invalidHash)
98
- } catch (e: any) {
99
- expect(e.message).toEqual(INVALID_CID_LENGTH)
100
- }
101
- })
102
-
103
- test('Valid IPFS appData from CID', async () => {
104
- const validSerializedCidV0 = 'QmZZhNnqMF1gRywNKnTPuZksX7rVjQgTT3TJAZ7R6VE3b2'
105
- const appDataDocument = await loadIpfsFromCid(validSerializedCidV0)
106
- const validation = await validateAppDataDocument(appDataDocument)
107
-
108
- expect(validation).toEqual(VALID_RESULT)
109
- })
@@ -1,58 +0,0 @@
1
- import Ajv, { ErrorObject, ValidateFunction } from 'ajv'
2
- import { fromHexString } from './common'
3
- import { DEFAULT_IPFS_GATEWAY_URI } from '../constants'
4
- import { AppDataDoc } from '../types'
5
-
6
- let validate: ValidateFunction | undefined
7
- let ajv: Ajv
8
-
9
- interface ValidationResult {
10
- result: boolean
11
- errors?: ErrorObject[]
12
- }
13
-
14
- async function getValidator(): Promise<{ ajv: Ajv; validate: ValidateFunction }> {
15
- if (!ajv) {
16
- ajv = new Ajv()
17
- }
18
-
19
- if (!validate) {
20
- const appDataSchema = await import('../schemas/appData.schema.json')
21
- validate = ajv.compile(appDataSchema)
22
- }
23
-
24
- return { ajv, validate }
25
- }
26
-
27
- export async function getSerializedCID(hash: string): Promise<void | string> {
28
- const cidVersion = 0x1 //cidv1
29
- const codec = 0x70 //dag-pb
30
- const type = 0x12 //sha2-256
31
- const length = 32 //256 bits
32
- const _hash = hash.replace(/(^0x)/, '')
33
-
34
- const hexHash = fromHexString(_hash)
35
-
36
- if (!hexHash) return
37
-
38
- const uint8array = Uint8Array.from([cidVersion, codec, type, length, ...hexHash])
39
- const { CID } = await import('multiformats/cid')
40
- return CID.decode(uint8array).toV0().toString()
41
- }
42
-
43
- export async function loadIpfsFromCid(cid: string, ipfsUri = DEFAULT_IPFS_GATEWAY_URI): Promise<AppDataDoc> {
44
- const { default: fetch } = await import('cross-fetch')
45
- const response = await fetch(`${ipfsUri}/${cid}`)
46
-
47
- return await response.json()
48
- }
49
-
50
- export async function validateAppDataDocument(appDataDocument: unknown): Promise<ValidationResult> {
51
- const { ajv, validate } = await getValidator()
52
- const result = !!validate(appDataDocument)
53
-
54
- return {
55
- result,
56
- errors: ajv.errors ?? undefined,
57
- }
58
- }
@@ -1,35 +0,0 @@
1
- export class CowError extends Error {
2
- error_code?: string
3
-
4
- constructor(message: string, error_code?: string) {
5
- super(message)
6
- this.error_code = error_code
7
- }
8
- }
9
-
10
- export function objectToQueryString(o: any): string {
11
- if (!o) {
12
- return ''
13
- }
14
-
15
- const qs = new URLSearchParams()
16
-
17
- for (const key of Object.keys(o)) {
18
- const value = o[key]
19
- if (value) {
20
- qs.append(key, value)
21
- }
22
- }
23
-
24
- const qsResult = qs.toString()
25
-
26
- return qsResult ? `?${qsResult}` : ''
27
- }
28
-
29
- export const logPrefix = 'cow-sdk:'
30
-
31
- export function fromHexString(hexString: string) {
32
- const stringMatch = hexString.match(/.{1,2}/g)
33
- if (!stringMatch) return
34
- return new Uint8Array(stringMatch.map((byte) => parseInt(byte, 16)))
35
- }
@@ -1,89 +0,0 @@
1
- import { Signer } from 'ethers'
2
- import log from 'loglevel'
3
- import { CowError, logPrefix } from './common'
4
- import { SupportedChainId as ChainId } from '../constants/chains'
5
- import { DEFAULT_APP_DATA_HASH, DEFAULT_IPFS_GATEWAY_URI } from '../constants'
6
-
7
- export interface CowContext {
8
- appDataHash?: string
9
- isDevEnvironment?: boolean
10
- signer?: Signer
11
- ipfsUri?: string
12
- }
13
-
14
- export const DefaultCowContext = {
15
- appDataHash: DEFAULT_APP_DATA_HASH,
16
- isDevEnvironment: false,
17
- ipfsUri: DEFAULT_IPFS_GATEWAY_URI,
18
- }
19
-
20
- /**
21
- *
22
- *
23
- * @export
24
- * @class Context
25
- * @implements {Required<CowContext>}
26
- */
27
- export class Context implements Partial<CowContext> {
28
- #context: CowContext
29
- #chainId: ChainId
30
-
31
- constructor(chainId: ChainId, context: CowContext) {
32
- this.#chainId = this.updateChainId(chainId)
33
- this.#context = { ...DefaultCowContext, ...context }
34
- }
35
-
36
- updateChainId(chainId: ChainId) {
37
- if (!ChainId[chainId]) {
38
- throw new CowError(`Invalid chainId: ${chainId}`)
39
- }
40
-
41
- log.debug(logPrefix, `Updating chainId to: ${chainId}`)
42
-
43
- this.#chainId = chainId
44
- return chainId
45
- }
46
-
47
- get chainId(): Promise<ChainId> {
48
- const provider = this.#context.signer?.provider
49
- if (!provider) {
50
- return Promise.resolve(this.#chainId)
51
- }
52
-
53
- log.debug(logPrefix, 'Getting chainId from provider')
54
-
55
- const getAndReconciliateNetwork = async () => {
56
- const network = await provider.getNetwork()
57
- const chainId = network.chainId
58
-
59
- if (chainId !== this.#chainId) {
60
- log.debug(
61
- logPrefix,
62
- `ChainId mismatch: Provider's chainId: ${chainId} vs Context's chainId: ${
63
- this.#chainId
64
- }. Updating Context's chainId`
65
- )
66
- this.updateChainId(chainId)
67
- }
68
- return chainId
69
- }
70
-
71
- return getAndReconciliateNetwork()
72
- }
73
-
74
- get appDataHash(): string {
75
- return this.#context.appDataHash ?? DefaultCowContext.appDataHash
76
- }
77
-
78
- get isDevEnvironment(): boolean {
79
- return this.#context.isDevEnvironment ?? DefaultCowContext.isDevEnvironment
80
- }
81
-
82
- get signer(): Signer | undefined {
83
- return this.#context.signer
84
- }
85
-
86
- get ipfsUri(): string {
87
- return this.#context.ipfsUri ?? DefaultCowContext.ipfsUri
88
- }
89
- }
@@ -1,44 +0,0 @@
1
- import { GetQuoteResponse } from '@gnosis.pm/gp-v2-contracts'
2
- import { OrderMetaData } from '../api/cow/types'
3
-
4
- export interface QuoteParams {
5
- quoteParams: FeeQuoteParams
6
- fetchFee: boolean
7
- previousFee?: FeeInformation
8
- isPriceRefresh: boolean
9
- }
10
-
11
- export interface FeeInformation {
12
- expirationDate: string
13
- amount: string
14
- }
15
-
16
- export interface PriceInformation {
17
- token: string
18
- amount: string | null
19
- }
20
-
21
- // GetQuoteResponse from @gnosis.pm/gp-v2-contracts types Timestamp and BigNumberish
22
- // do not play well with our existing methods, using string instead
23
- export type SimpleGetQuoteResponse = Pick<GetQuoteResponse, 'from'> & {
24
- // We need to map BigNumberIsh and Timestamp to what we use: string
25
- quote: Omit<GetQuoteResponse['quote'], 'sellAmount' | 'buyAmount' | 'feeAmount' | 'validTo'> & {
26
- sellAmount: string
27
- buyAmount: string
28
- validTo: string
29
- feeAmount: string
30
- }
31
- expiration: string
32
- }
33
-
34
- export type FeeQuoteParams = Pick<OrderMetaData, 'sellToken' | 'buyToken' | 'kind'> & {
35
- amount: string
36
- userAddress?: string | null
37
- receiver?: string | null
38
- validTo: number
39
- }
40
-
41
- export type PriceQuoteParams = Omit<FeeQuoteParams, 'sellToken' | 'buyToken'> & {
42
- baseToken: string
43
- quoteToken: string
44
- }