Skip to content

Commit

Permalink
Feat/viem support (#174)
Browse files Browse the repository at this point in the history
* abstract away providers/findPrimaryType

* add TransactionParams.maxFeeGas params

* providers/viem

* export from providers/viem

* DEFAULT_VERSION better type

* add wagmi & viem deps

* SimpleSDK/viem for contractCaller

* examples/viem

* cleanup

* examples/wagmi

* tests/fix types

* examples/fix types

* tests/fix types

* viem/fix account usage

* examples/viem/fix account usage

* types/TxHash=Hex

* add hardhat

* legacy/fix types

* ignore cache files

* some tests

* tsconfig/allow BigInt short notation

* providers/viem/reuse account

* viem/fix tests

* tests/viem/remove extra

* tests/viem/Order signing

* rename stuff

* cleanup

* reenable tests

* tests/viem/const acc

* tests/viem/update snapshots

* reexport txParamsToViemTxParams

* tests/viem/update snapshots

* more comments

* cleanup

* remove extra deps

* moved bignumber.js to devDeps

* cleanup

* update tests jpeg

* update README

* update snapshots

* FetcherError/fix types

* viem test/market swap

* fix deps

* update deps

* update snapshots

* remove dummy test

* change default version

* Feat/deps update/tests migration (#180)

* update some deps

* replace ganache with hardhat

* remove ganache

* fix chainId in tests mismatch

* try with tevm

* tevm test

* add hardhat-switch-network plugin

* simplify hardhat helpers

* make tests work with hardhat

* fix method name

* disable web3 tests that break with hardhat

* fix NFT tests

* remove tevm

* hardhat config/explicit gasPrice

* NFT tests/adjust amounts

* cleanup

* remove temp tests

* update some deps

* NFT tests/workaround some errors

* update ethers dep

* update web3 dep(slightly)

* update deps

* override some deps

* Feat/web3 upgrade (#181)

* update some deps

* hadrhat config/smaller default baseFee

* NFT tests/workaround edge case

* update web3 dep

* update Web3 types

* update web3/constructContractCaller

* legacy/update types

* hardhat config/fixed accounts

* LOrder tests/reenable sign with web3

* NFT Order tests/reenable sign with web3

* getBalance tests workaround

* cleanup

* update some deps

* update snapshots

* update perrDeps

* update required Node v

* NFT tests/account for dust

* hadrhat config/lower initialBaseFeePerGas

* Feat/ether v6 support (#182)

* install ethersV6 as alias

* providers/ethersV6

* distinct ethersV5 exports

* legacy/support ethersV6

* simple SDK/support ethersV6

* simpleSDK.tests/add ethersV6

* partialSDK.tests/add ethersV6

* LOrders.tests/add ethersV6

* NFT_Orders.tests/add ethersV6

* update snapshots

* examples/ add ethersV6

* perrDeps/update ethers versions

* update snapshots

* cleanup

* move ethers types to provider/ethers

* move web3 types to provider/web3

* untie FetchError type from AxiosError

* ethers -> ethersV5, ethersV6 -> ethers to fix types when used as lib

* cleanup

* README/update version

* less dependency on ethers types

* update README

* rremove temp tests

* tests/ethersV6/fix derivation path arg position
  • Loading branch information
Velenir authored Nov 12, 2024
1 parent 5d392d7 commit 1240bd3
Show file tree
Hide file tree
Showing 45 changed files with 6,821 additions and 4,900 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ src/*.js

dist

*.log
*.log

/cache
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
Refer to the documentation of the ParaSwap API: https://developers.paraswap.network

## Features
**Versatility**: works with both [web3](https://www.npmjs.com/package/web3) and [ethers](https://www.npmjs.com/package/ethers) without direct dependency
**Versatility**: works with [web3](https://www.npmjs.com/package/web3), [ethers](https://www.npmjs.com/package/ethers) or [viem](https://viem.sh/) without direct dependency

**Canonical**: bring only the functions you actually need

**Lightweight**: 400B Gzipped for the minimal variant
**Lightweight**: 10KB Gzipped for the minimal variant

## Installing ParaSwap SDK

Expand All @@ -25,9 +25,11 @@ yarn add @paraswap/sdk

There are multiple ways to use ParaSwap SDK, ranging from a simple construct-and-use approach to a fully composable _bring what you need_ approach which allows for advanced tree-shaking and minimizes bundle size.

You can see some examples in [/src/examples](src/examples) directory.

### Simple SDK

Can be created by providing `chainId` and either `axios` or `window.fetch` (or alternative `fetch` implementation), and an optional `version` (`'5'` or `'6.1'`) parameter that corresponds to the API version SDK will be making requests to. The resulting SDK will be able to use all methods that query the API.
Can be created by providing `chainId` and either `axios` or `window.fetch` (or alternative `fetch` implementation), and an optional `version` (`'5'` or `'6.2'`) parameter that corresponds to the API version SDK will be making requests to. The resulting SDK will be able to use all methods that query the API.

```ts
import { constructSimpleSDK } from '@paraswap/sdk';
Expand Down Expand Up @@ -87,6 +89,12 @@ If optional `providerOptions` is provided as the second parameter, then the resu
account: senderAddress,
};

// or with viem (from wagmi or standalone)
const providerOptionsViem = {
viemClient, // made with createWalletClient()
account: senderAddress,
};

// or with web3.js
const providerOptionsWeb3 = {
web3, // new Web3(...) instance
Expand All @@ -112,7 +120,7 @@ const account = '__signer_address__';
const contractCaller = constructEthersContractCaller({
ethersProviderOrSigner: signer,
EthersContract: ethers.Contract,
}, account); // alternatively constructWeb3ContractCaller
}, account); // alternatively constructViemContractCaller or constructWeb3ContractCaller
const fetcher = constructAxiosFetcher(axios); // alternatively constructFetchFetcher

const paraswap = constructFullSDK({
Expand Down
Binary file modified docs/passed_tests.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as dotenv from 'dotenv';
import type { HardhatUserConfig } from 'hardhat/config';
import 'hardhat-switch-network';

dotenv.config();

const TEST_MNEMONIC =
'radar blur cabbage chef fix engine embark joy scheme fiction master release';

const config: HardhatUserConfig = {
solidity: '0.8.24',
networks: {
hardhat: {
forking: {
url: process.env.PROVIDER_URL!, // Replace with your actual Alchemy/Infura URL
// Optional forking configurations (e.g., block number):
// blockNumber: 12345678,
},
chainId: 1,
// have to config hardhat with fixed accounts unlocked, otherwise signTx and signTyped data fail when used in RPC calls to Node
// which breaks web3.js
// ethers signs data and txs locally off-chain as long as it has provate key
// web3 is a bit harder to init wallets for locally.
// impersonateAccounts doesn't work, even though it should logically fully unlock accounts,
// but only remore accounts are unlocked, fixed are not,
// so we always need to only use accounts generated from this mnemonic

// refs:
// https://github.com/NomicFoundation/hardhat/issues/3059
// https://github.com/NomicFoundation/hardhat/issues/1226
accounts: { mnemonic: TEST_MNEMONIC }, // and with fixed
// dynamically switch between networks configured here
// by calling `hre.switchNetwork(networkName)` thanks to hardhat-switch-network plugin
gasPrice: 8e9,
initialBaseFeePerGas: 1e8, // will break if used with a chain without eip1559
},
},
};

export default config;
44 changes: 26 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"testEnvironment": "node"
},
"engines": {
"node": ">=12"
"node": ">=18"
},
"size-limit": [
{
Expand All @@ -48,28 +48,34 @@
}
],
"devDependencies": {
"@size-limit/preset-small-lib": "^11.1.5",
"@tsconfig/recommended": "^1.0.7",
"axios": "^1.1.3",
"dotenv": "^16.0.0",
"@size-limit/preset-small-lib": "^11.1.6",
"@tsconfig/recommended": "^1.0.8",
"axios": "^1.7.7",
"bignumber.js": "^9.1.2",
"dotenv": "^16.4.5",
"dts-cli": "^2.0.5",
"ethers": "^5.6.5",
"ganache": "^7.9.2",
"ethers": "^6.13.4",
"ethersV5": "npm:ethers@5",
"hardhat": "^2.22.15",
"hardhat-switch-network": "^1.1.1",
"husky": "^9.1.6",
"isomorphic-unfetch": "^3.1.0",
"size-limit": "^11.1.5",
"tslib": "^2.7.0",
"typedoc": "^0.26.7",
"typedoc-plugin-markdown": "^4.2.7",
"isomorphic-unfetch": "^4.0.2",
"size-limit": "^11.1.6",
"tslib": "^2.8.1",
"typedoc": "^0.26.11",
"typedoc-plugin-markdown": "^4.2.10",
"typedoc-plugin-missing-exports": "^3.0.0",
"typedoc-plugin-replace-text": "^4.0.0",
"typescript": "^5.6.2",
"web3": "^1.7.3"
"typescript": "^5.6.3",
"viem": "^2.21.39",
"wagmi": "^2.12.25",
"web3": "^4.14.0"
},
"peerDependencies": {
"axios": ">=0.25.0 <2.0.0",
"ethers": "^5.5.0",
"web3": "^1.7.1"
"ethers": "^5.5.0 || ^6.0.0",
"viem": "^2.21.0",
"web3": "^4.14.0"
},
"peerDependenciesMeta": {
"axios": {
Expand All @@ -80,12 +86,14 @@
},
"web3": {
"optional": true
},
"viem": {
"optional": true
}
},
"dependencies": {
"@paraswap/core": "2.4.0",
"bignumber.js": "^9.0.2",
"ts-essentials": "^9.1.2"
"ts-essentials": "^10.0.3"
},
"author": "ParaSwap",
"description": "ParaSwap SDK",
Expand Down
2 changes: 1 addition & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ export {
} from '@paraswap/core';

export const API_URL = 'https://api.paraswap.io';
export const DEFAULT_VERSION: ParaSwapVersionUnion = '5';
export const DEFAULT_VERSION = '6.2' satisfies ParaSwapVersionUnion;
38 changes: 38 additions & 0 deletions src/examples/ethersV6.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import axios from 'axios';
import { ethers } from 'ethers';
import {
constructPartialSDK,
constructFullSDK,
constructGetAdapters,
constructEthersV6ContractCaller,
constructAxiosFetcher,
} from '..';

const fetcher = constructAxiosFetcher(axios);

const provider = ethers.getDefaultProvider(1);
const contractCaller = constructEthersV6ContractCaller({
ethersV6ProviderOrSigner: provider,
EthersV6Contract: ethers.Contract,
});

const paraswap = constructFullSDK({
chainId: 1,
fetcher,
contractCaller,
});

const res = paraswap.swap.getAdapters();

// type Promise<ContractTransaction>
const txResponse = paraswap.swap.approveToken('1', '0x...');
// type Promise<ContractTransaction[]>
const txResponses = paraswap.swap.approveTokenBulk('1', ['0x...']);

const partial = constructPartialSDK(
{ apiURL: '', chainId: 1, fetcher },
constructGetAdapters
);

const res1 = partial.getAdapters();
12 changes: 10 additions & 2 deletions src/examples/limitOrders_all.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import axios from 'axios';
import BigNumber from 'bignumber.js';
import { ethers } from 'ethers';
import { ethers } from 'ethersV5';
import { assert } from 'ts-essentials';
import {
// swap methods
Expand Down Expand Up @@ -108,7 +108,15 @@ async function run() {

const tx5Params = {
...LOPayloadTxParams,
gasPrice: '0x' + new BigNumber(LOPayloadTxParams.gasPrice).toString(16),
gasPrice:
LOPayloadTxParams.gasPrice &&
'0x' + new BigNumber(LOPayloadTxParams.gasPrice).toString(16),
maxFeePerGas:
LOPayloadTxParams.maxFeePerGas &&
'0x' + new BigNumber(LOPayloadTxParams.maxFeePerGas).toString(16),
maxPriorityFeePerGas:
LOPayloadTxParams.maxPriorityFeePerGas &&
'0x' + new BigNumber(LOPayloadTxParams.maxPriorityFeePerGas).toString(16),
gasLimit: '0x' + new BigNumber(payloadGas || 5000000).toString(16),
value: '0x' + new BigNumber(LOPayloadTxParams.value).toString(16),
};
Expand Down
12 changes: 10 additions & 2 deletions src/examples/limitOrders_partial.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import axios from 'axios';
import BigNumber from 'bignumber.js';
import { ethers } from 'ethers';
import { ethers } from 'ethersV5';
import { assert } from 'ts-essentials';
import {
// swap methods
Expand Down Expand Up @@ -145,7 +145,15 @@ async function run() {

const tx5Params = {
...LOPayloadTxParams,
gasPrice: '0x' + new BigNumber(LOPayloadTxParams.gasPrice).toString(16),
gasPrice:
LOPayloadTxParams.gasPrice &&
'0x' + new BigNumber(LOPayloadTxParams.gasPrice).toString(16),
maxFeePerGas:
LOPayloadTxParams.maxFeePerGas &&
'0x' + new BigNumber(LOPayloadTxParams.maxFeePerGas).toString(16),
maxPriorityFeePerGas:
LOPayloadTxParams.maxPriorityFeePerGas &&
'0x' + new BigNumber(LOPayloadTxParams.maxPriorityFeePerGas).toString(16),
gasLimit: '0x' + new BigNumber(payloadGas || 5000000).toString(16),
value: '0x' + new BigNumber(LOPayloadTxParams.value).toString(16),
};
Expand Down
2 changes: 1 addition & 1 deletion src/examples/limitOrders_postOrder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import axios from 'axios';
import { ethers } from 'ethers';
import { ethers } from 'ethersV5';

import {
// swap methods
Expand Down
2 changes: 1 addition & 1 deletion src/examples/partial.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import axios from 'axios';
import { ethers } from 'ethers';
import { ethers } from 'ethersV5';
import {
constructPartialSDK,
constructGetAdapters,
Expand Down
6 changes: 3 additions & 3 deletions src/examples/sdk.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import axios from 'axios';
import { ethers } from 'ethers';
import { ethers } from 'ethersV5';
import {
constructPartialSDK,
constructFullSDK,
constructGetAdapters,
constructEthersContractCaller,
constructEthersV5ContractCaller,
constructAxiosFetcher,
} from '..';

const fetcher = constructAxiosFetcher(axios);

const provider = ethers.getDefaultProvider(1);
const contractCaller = constructEthersContractCaller({
const contractCaller = constructEthersV5ContractCaller({
ethersProviderOrSigner: provider,
EthersContract: ethers.Contract,
});
Expand Down
2 changes: 1 addition & 1 deletion src/examples/simple.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import axios from 'axios';
import { ethers, Wallet } from 'ethers';
import { ethers, Wallet } from 'ethersV5';
import {
constructSimpleSDK,
ContractMethod,
Expand Down
Loading

0 comments on commit 1240bd3

Please sign in to comment.