@0x/0x-parser
Advanced tools
Comparing version 0.4.0 to 0.5.0
import { SupportedChainId } from "./types"; | ||
export declare const EVENT_SIGNATURES: { | ||
LimitOrderFilled: string; | ||
LiquidityProviderSwap: string; | ||
OtcOrderFilled: string; | ||
MetaTransactionExecuted: string; | ||
Transfer: string; | ||
TransformedERC20: string; | ||
readonly LimitOrderFilled: "0xab614d2b738543c0ea21f56347cf696a3a0c42a7cbec3212a5ca22a4dcff2124"; | ||
readonly LiquidityProviderSwap: "0x40a6ba9513d09e3488135e0e0d10e2d4382b792720155b144cbea89ac9db6d34"; | ||
readonly OtcOrderFilled: "0xac75f773e3a92f1a02b12134d65e1f47f8a14eabe4eaf1e24624918e6a8b269f"; | ||
readonly MetaTransactionExecuted: "0x7f4fe3ff8ae440e1570c558da08440b26f89fb1c1f2910cd91ca6452955f121a"; | ||
readonly Transfer: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"; | ||
readonly TransformedERC20: "0x0f6672f78a59ba8e5e5b5d38df3ebc67f3c792e2c9259b8d97d7f00dd78ba1b3"; | ||
}; | ||
export declare const ERC20_FUNCTION_HASHES: { | ||
symbol: string; | ||
decimals: string; | ||
readonly symbol: "0x95d89b41"; | ||
readonly decimals: "0x313ce567"; | ||
}; | ||
export declare const EXCHANGE_PROXY_ABI_URL = "https://raw.githubusercontent.com/0xProject/protocol/development/packages/contract-artifacts/artifacts/IZeroEx.json"; | ||
export declare const MULTICALL3 = "0xcA11bde05977b3631167028862bE2a173976CA11"; | ||
export declare const PERMIT_AND_CALL_BY_CHAIN_ID: { | ||
readonly 1: "0x1291C02D288de3De7dC25353459489073D11E1Ae"; | ||
readonly 137: "0x2ddd30fe5c12fc4cd497526f14bf3d1fcd3d5db4"; | ||
readonly 8453: "0x3CA53031Ad0B86a304845e83644983Be3340895f"; | ||
}; | ||
export declare const EXCHANGE_PROXY_BY_CHAIN_ID: { | ||
readonly 1: "0xdef1c0ded9bec7f1a1670819833240f027b25eff"; | ||
readonly 5: "0xf91bb752490473b8342a3e964e855b9f9a2a668e"; | ||
readonly 10: "0xdef1abe32c034e558cdd535791643c58a13acc10"; | ||
readonly 56: "0xdef1c0ded9bec7f1a1670819833240f027b25eff"; | ||
readonly 137: "0xdef1c0ded9bec7f1a1670819833240f027b25eff"; | ||
readonly 250: "0xdef189deaef76e379df891899eb5a00a94cbc250"; | ||
readonly 8453: "0xdef1c0ded9bec7f1a1670819833240f027b25eff"; | ||
readonly 42161: "0xdef1c0ded9bec7f1a1670819833240f027b25eff"; | ||
readonly 42220: "0xdef1c0ded9bec7f1a1670819833240f027b25eff"; | ||
readonly 43114: "0xdef1c0ded9bec7f1a1670819833240f027b25eff"; | ||
}; | ||
export declare const CONTRACTS: { | ||
weth: string; | ||
permitAndCall: string; | ||
exchangeProxyByChainId: { | ||
1: string; | ||
5: string; | ||
10: string; | ||
56: string; | ||
137: string; | ||
250: string; | ||
8453: string; | ||
42161: string; | ||
42220: string; | ||
43114: string; | ||
}; | ||
readonly weth: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"; | ||
}; | ||
export declare const NATIVE_ASSET = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; | ||
export declare const NATIVE_SYMBOL_BY_CHAIN_ID: Record<SupportedChainId, string>; |
import type { Contract, BaseContractMethod, TransactionReceipt, TransactionDescription } from "ethers"; | ||
export type PermitAndCallChainIds = 1 | 137 | 8453; | ||
export type SupportedChainId = 1 | 5 | 10 | 56 | 137 | 250 | 8453 | 42220 | 43114 | 42161; | ||
@@ -3,0 +4,0 @@ export interface CallResult { |
@@ -1,4 +0,5 @@ | ||
import type { ProcessedLog, SupportedChainId, EnrichedTxReceipt, EnrichedTxReceiptArgs, TryBlockAndAggregate } from "../types"; | ||
import type { ProcessedLog, SupportedChainId, PermitAndCallChainIds, EnrichedTxReceipt, EnrichedTxReceiptArgs, TryBlockAndAggregate } from "../types"; | ||
export declare function convertHexToAddress(hexString: string): string; | ||
export declare function isChainIdSupported(chainId: number): chainId is SupportedChainId; | ||
export declare function isPermitAndCallChainId(chainId: number): chainId is PermitAndCallChainIds; | ||
export declare function parseHexDataToString(hexData: string): string; | ||
@@ -5,0 +6,0 @@ export declare function formatUnits(data: string, decimals: number): string; |
{ | ||
"name": "@0x/0x-parser", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"description": "🧾 Designed for 0x integrators: This library parses 0x transactions on EVM blockchains into a format that is both user-friendly and easy to understand.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
# 0x-parser | ||
[![npm version](https://img.shields.io/npm/v/@0x/0x-parser.svg?style=flat-square&logo=npm)](https://www.npmjs.com/package/@0x/0x-parser) | ||
@@ -9,4 +8,12 @@ [![codecov](https://codecov.io/gh/0xproject/0x-parser/branch/main/graph/badge.svg?token=OnNsoc2OrF)](https://codecov.io/gh/0xproject/0x-parser) | ||
This library is specifically designed for [0x integrators](https://0x.org/docs/introduction/introduction-to-0x), and it simplifies the complex task of parsing [0x transactions](https://etherscan.io/address/0xdef1c0ded9bec7f1a1670819833240f027b25eff) into a format that is both user-friendly and easy to understand. One of the challenges in these trades is that they can experience [slippage](https://0x.org/post/what-is-slippage) through [Automated Market Makers]([AMMs](https://0x.org/post/what-is-an-automated-market-maker-amm)) (AMMs), making the final swap amounts difficult to predict prior to executing the trade. However, this library overcomes that challenge by accepting a transaction hash as input and parsing the receipt and event logs to accurately identify the final swap amounts. Try the demo [here](https://0x-parser-demo.vercel.app). | ||
## Blockchain Support | ||
| <img alt="arbitrum" src="https://raw.githubusercontent.com/rainbow-me/assets/master/blockchains/arbitrum/info/logo.png" width="23"/> | <img alt="avalanche" src="https://raw.githubusercontent.com/rainbow-me/assets/master/blockchains/avalanchec/info/logo.png" width="20"/> | <img alt="base" src="https://raw.githubusercontent.com/rainbow-me/assets/master/blockchains/base/info/logo.png" width="20"/> | <img alt="bnb chain" src="https://raw.githubusercontent.com/rainbow-me/assets/master/blockchains/binance/info/logo.png" width="21"/> | <img alt="celo" src="https://raw.githubusercontent.com/rainbow-me/assets/master/blockchains/celo/info/logo.png" width="20"/> | <img alt="ethereum" src="https://raw.githubusercontent.com/rainbow-me/assets/master/blockchains/ethereum/info/logo.png" width="21"/> | <img alt="fantom" src="https://raw.githubusercontent.com/rainbow-me/assets/master/blockchains/fantom/info/logo.png" width="22"/> | <img alt="optimism" src="https://raw.githubusercontent.com/rainbow-me/assets/master/blockchains/optimism/info/logo.png" width="22"/> | <img alt="polygon" src="https://raw.githubusercontent.com/rainbow-me/assets/master/blockchains/polygon/info/logo.png" width="22"/> | | ||
| :----------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------: | | ||
| Arbitrum | Avalanche | Base | BNB Chain | Celo | Ethereum | Fantom | Optimism | Polygon | | ||
## Overview | ||
This library is specifically designed for [0x integrators](https://0x.org/docs/introduction/introduction-to-0x), and it simplifies the complex task of parsing [0x transactions](https://etherscan.io/address/0xdef1c0ded9bec7f1a1670819833240f027b25eff) into a format that is both user-friendly and easy to understand. One of the challenges in these trades is that they can experience [slippage](https://0x.org/post/what-is-slippage) through [Automated Market Makers](<[AMMs](https://0x.org/post/what-is-an-automated-market-maker-amm)>) (AMMs), making the final swap amounts difficult to predict prior to executing the trade. However, this library overcomes that challenge by accepting a transaction hash as input and parsing the receipt and event logs to accurately identify the final swap amounts. Try the demo [here](https://0x-parser-demo.vercel.app). | ||
<p align="center"> | ||
@@ -25,3 +32,3 @@ <img style="" src="https://raw.githubusercontent.com/hzhu/yo/main/react-demo.png" alt="React demo app for 0x-parser" width="650"/> | ||
```typescript | ||
import { parseSwap } from '@0x/0x-parser'; | ||
import { parseSwap } from "@0x/0x-parser"; | ||
@@ -28,0 +35,0 @@ async function main() { |
@@ -16,3 +16,3 @@ import { SupportedChainId } from "./types"; | ||
"0x0f6672f78a59ba8e5e5b5d38df3ebc67f3c792e2c9259b8d97d7f00dd78ba1b3", | ||
}; | ||
} as const; | ||
@@ -22,3 +22,3 @@ export const ERC20_FUNCTION_HASHES = { | ||
decimals: "0x313ce567", | ||
}; | ||
} as const; | ||
@@ -32,18 +32,24 @@ export const EXCHANGE_PROXY_ABI_URL = | ||
export const PERMIT_AND_CALL_BY_CHAIN_ID = { | ||
1: "0x1291C02D288de3De7dC25353459489073D11E1Ae", | ||
137: "0x2ddd30fe5c12fc4cd497526f14bf3d1fcd3d5db4", | ||
8453: "0x3CA53031Ad0B86a304845e83644983Be3340895f" | ||
} as const | ||
export const EXCHANGE_PROXY_BY_CHAIN_ID = { | ||
1: CONONICAL_EXCHANGE_PROXY, | ||
5: "0xf91bb752490473b8342a3e964e855b9f9a2a668e", | ||
10: "0xdef1abe32c034e558cdd535791643c58a13acc10", | ||
56: CONONICAL_EXCHANGE_PROXY, | ||
137: CONONICAL_EXCHANGE_PROXY, | ||
250: "0xdef189deaef76e379df891899eb5a00a94cbc250", | ||
8453: CONONICAL_EXCHANGE_PROXY, | ||
42161: CONONICAL_EXCHANGE_PROXY, | ||
42220: CONONICAL_EXCHANGE_PROXY, | ||
43114: CONONICAL_EXCHANGE_PROXY, | ||
} as const | ||
export const CONTRACTS = { | ||
weth: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", | ||
permitAndCall: "0x1291C02D288de3De7dC25353459489073D11E1Ae", | ||
exchangeProxyByChainId: { | ||
1: CONONICAL_EXCHANGE_PROXY, | ||
5: "0xf91bb752490473b8342a3e964e855b9f9a2a668e", | ||
10: "0xdef1abe32c034e558cdd535791643c58a13acc10", | ||
56: CONONICAL_EXCHANGE_PROXY, | ||
137: CONONICAL_EXCHANGE_PROXY, | ||
250: "0xdef189deaef76e379df891899eb5a00a94cbc250", | ||
8453: CONONICAL_EXCHANGE_PROXY, | ||
42161: CONONICAL_EXCHANGE_PROXY, | ||
42220: CONONICAL_EXCHANGE_PROXY, | ||
43114: CONONICAL_EXCHANGE_PROXY, | ||
}, | ||
}; | ||
} as const; | ||
@@ -63,2 +69,2 @@ export const NATIVE_ASSET = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; | ||
43114: "AVAX", // Avalanche | ||
}; | ||
} as const; |
import { Contract, JsonRpcProvider } from "ethers"; | ||
import { abi as permitAndCallAbi } from "./abi/PermitAndCall.json"; | ||
import multicall3Abi from "./abi/Multicall3.json"; | ||
import { CONTRACTS, EXCHANGE_PROXY_ABI_URL, MULTICALL3 } from "./constants"; | ||
import { | ||
MULTICALL3, | ||
EXCHANGE_PROXY_ABI_URL, | ||
EXCHANGE_PROXY_BY_CHAIN_ID, | ||
PERMIT_AND_CALL_BY_CHAIN_ID, | ||
} from "./constants"; | ||
import { | ||
fillLimitOrder, | ||
@@ -27,3 +32,7 @@ fillOtcOrder, | ||
} from "./parsers"; | ||
import { enrichTxReceipt, isChainIdSupported } from "./utils"; | ||
import { | ||
enrichTxReceipt, | ||
isChainIdSupported, | ||
isPermitAndCallChainId, | ||
} from "./utils"; | ||
import { TransactionStatus } from "./types"; | ||
@@ -66,21 +75,21 @@ import type { | ||
const { exchangeProxyByChainId } = CONTRACTS; | ||
const exchangeProxyContract = new Contract( | ||
exchangeProxyByChainId[chainId], | ||
EXCHANGE_PROXY_BY_CHAIN_ID[chainId], | ||
exchangeProxyAbi | ||
); | ||
const permitAndCallContract = new Contract( | ||
CONTRACTS.permitAndCall, | ||
permitAndCallAbi | ||
); | ||
const permitAndCallAddress = isPermitAndCallChainId(chainId) | ||
? PERMIT_AND_CALL_BY_CHAIN_ID[chainId] | ||
: undefined; | ||
const permitAndCallContract = permitAndCallAddress | ||
? new Contract(permitAndCallAddress, permitAndCallAbi) | ||
: undefined; | ||
const transactionDescription = | ||
transactionReceipt.to === CONTRACTS.permitAndCall | ||
? permitAndCallContract.interface.parseTransaction(tx) | ||
transactionReceipt.to === permitAndCallAddress | ||
? permitAndCallContract?.interface.parseTransaction(tx) | ||
: exchangeProxyContract.interface.parseTransaction(tx); | ||
if (transactionDescription === null) { | ||
return null; | ||
} | ||
if (!transactionDescription) return null; | ||
@@ -87,0 +96,0 @@ const multicall = new Contract(MULTICALL3, multicall3Abi, provider); |
@@ -8,2 +8,3 @@ import { formatUnits } from "ethers"; | ||
NATIVE_SYMBOL_BY_CHAIN_ID, | ||
EXCHANGE_PROXY_BY_CHAIN_ID, | ||
} from "../constants"; | ||
@@ -357,3 +358,3 @@ import type { | ||
const { logs } = txReceipt; | ||
const exchangeProxy = CONTRACTS.exchangeProxyByChainId[56].toLowerCase(); | ||
const exchangeProxy = EXCHANGE_PROXY_BY_CHAIN_ID[56].toLowerCase(); | ||
let inputLog = logs.find((log) => log.from === from); | ||
@@ -360,0 +361,0 @@ let outputLog = logs.find((log) => log.from !== from); |
import { Contract } from "ethers"; | ||
import { it, expect, describe } from "vitest"; | ||
import { parseSwap } from "../index"; | ||
import { CONTRACTS } from "../constants"; | ||
import { EXCHANGE_PROXY_BY_CHAIN_ID } from "../constants"; | ||
import { transformERC20 } from "../parsers"; | ||
@@ -19,3 +19,3 @@ import EXCHANGE_PROXY_ABI from "../abi/IZeroEx.json"; | ||
const contract = new Contract( | ||
CONTRACTS.exchangeProxyByChainId[1], | ||
EXCHANGE_PROXY_BY_CHAIN_ID[1], | ||
EXCHANGE_PROXY_ABI.compilerOutput.abi | ||
@@ -22,0 +22,0 @@ ); |
@@ -10,2 +10,4 @@ import { narrow } from "abitype"; | ||
export type PermitAndCallChainIds = 1 | 137 | 8453; | ||
export type SupportedChainId = 1 | 5 | 10 | 56 | 137 | 250 | 8453 | 42220 | 43114 | 42161; | ||
@@ -12,0 +14,0 @@ |
@@ -1,5 +0,2 @@ | ||
import { | ||
EVENT_SIGNATURES, | ||
ERC20_FUNCTION_HASHES, | ||
} from "../constants"; | ||
import { EVENT_SIGNATURES, ERC20_FUNCTION_HASHES } from "../constants"; | ||
@@ -9,2 +6,3 @@ import type { | ||
SupportedChainId, | ||
PermitAndCallChainIds, | ||
EnrichedTxReceipt, | ||
@@ -26,6 +24,12 @@ EnrichedTxReceiptArgs, | ||
export function isPermitAndCallChainId( | ||
chainId: number | ||
): chainId is PermitAndCallChainIds { | ||
return [1, 137, 8453].includes(chainId); | ||
} | ||
export function parseHexDataToString(hexData: string) { | ||
const dataLength = parseInt(hexData.slice(66, 130), 16); | ||
const data = hexData.slice(130, 130 + dataLength * 2); | ||
const bytes: Uint8Array = new Uint8Array( | ||
const bytes = new Uint8Array( | ||
data.match(/.{1,2}/g)?.map((byte: string) => parseInt(byte, 16)) ?? [] | ||
@@ -32,0 +36,0 @@ ); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
1185623
13726
65