Uniswap V3 AlphaRouter - "Failed to get subgraph pools from any providers" - node.js

I am trying to swap WETH against MyToken from a previously created Uniswap V3 pool on Arbitrum Rinkeby. When calling AlphaRouter.route, however, I get the following error message
Failed to get subgraph pools from any providers
What is still missing to swap?
What do I need to create?
My target is to swap WETH for a given output of MyToken.
I am trying to simply get a swap on Uniswap V3 with my pool done. Any ideas?
const Web3 = require('web3');
const {
ethers
} = require("ethers");
const HDWalletProvider = require('#truffle/hdwallet-provider');
const {
Token,
CurrencyAmount,
TradeType,
Percent
} = require("#uniswap/sdk-core");
const {
AlphaRouter
} = require('#uniswap/smart-order-router');
const ABI_UNISWAP_POOL_V3 = require("#uniswap/v3-core/artifacts/contracts/interfaces/IUniswapV3Pool.sol/IUniswapV3Pool.json");
const fs = require('fs');
const JSBI = require('JSBI');
const API_ALCHEMY_ARBITRUM_RINKEBY = 'https://arb-rinkeby.g.alchemy.com/v2/<API KEY>';
const POOL_ADDRESS_MYTOKEN_WETH = '0xc69e7AE1073DD8184FcF6dBfc27ba97d1524716A';
const mnemonic = fs.readFileSync("./.mnemonics").toString().trim();
const hdprovider = new HDWalletProvider(mnemonic, API_ALCHEMY_ARBITRUM_RINKEBY);
const provider = new ethers.providers.Web3Provider(hdprovider);
const owner = hdprovider.addresses[0];
var web3 = new Web3(hdprovider);
const Contract = web3.eth.Contract;
const router = new AlphaRouter({
chainId: 421611,
provider: provider
});
async function main() {
const MyPool = new Contract(ABI_UNISWAP_POOL_V3.abi, POOL_ADDRESS_MYTOKEN_WETH);
const [factory, token0, token1, fee, tickSpacing, liquidity, maxLiquidityPerTick] =
await Promise.all([MyPool.methods.factory().call(),
MyPool.methods.token0().call(),
MyPool.methods.token1().call(),
MyPool.methods.fee().call(),
MyPool.methods.tickSpacing().call(),
MyPool.methods.liquidity().call(),
MyPool.methods.maxLiquidityPerTick().call()
]);
const tokenA = new Token(3, token0, 2, "MTK", "MyToken");
const tokenB = new Token(3, token1, 18, "WETH", "Wrapped Ether");
var amountOut = 2000;
amountOut = CurrencyAmount.fromRawAmount(tokenA, JSBI.BigInt(amountOut.toString()));
const slippageTolerance = new Percent(5, 100);
const deadline = Date.now() + 15000;
const route = await router.route(
amountOut,
tokenB,
TradeType.EXACT_OUTPUT, {
recipient: owner,
slippageTolerance: slippageTolerance,
deadline: deadline
}
);
hdprovider.engine.stop();
}
main();

I see two things are not right in this code:
First is the amountOut that you are passing to router.route should be converted to wei
const amountOutInWei=ethers.utils.parseUnits(amountOut.toString(),decimals)
// amountOutInWei should be converted to currentAmount
const currencyAmount= CurrencyAmount.fromRawAmount(tokenA,JSBI.BigInt(amountOutInWei))
currencyAmount should be passed to the router.route(currencyAmount,..)
Second issue deadline must be in seconds.
const deadline=Math.floor(Date.now() / 1000)+10*60 // addded 10 minutes

Related

Opensea listing through Opensea-js is not working

I have created a nft and is listed in OpenSea. Now I am trying to create sell order of my item through opensea-js sdk. Unfortunately it is not working. Do not know where I am making a mistake. Also I am not sure on base derivation path. Below is my code to create sell order. Pls help me resolving this.
const opensea = require("opensea-js");
const OpenSeaPort = opensea.OpenSeaPort;
const Network = opensea.Network;
const MnemonicWalletSubprovider = require("#0x/subproviders")
.MnemonicWalletSubprovider;
const RPCSubprovider = require("web3-provider-engine/subproviders/rpc");
const Web3ProviderEngine = require("web3-provider-engine");
const MNEMONIC = "accuse never ....";
const NFT_CONTRACT_ADDRESS = "0x6C317E7dE3e8823BBc308a2912Ba6F24587fc167";
const OWNER_ADDRESS = "0x589a1532AAaE84e38345b58C11CF4697Ea89A866";
API_KEY = "";
const infuraRpcSubprovider = new RPCSubprovider({
rpcUrl: "https://rinkeby.infura.io/v3/c0e4482bdf9e4f539692666cd56ef6e4"
});
const BASE_DERIVATION_PATH = `44'/60'/0'/0`;
const mnemonicWalletSubprovider = new MnemonicWalletSubprovider({
mnemonic: MNEMONIC,
baseDerivationPath: BASE_DERIVATION_PATH,
chainId: 4
});
const providerEngine = new Web3ProviderEngine();
providerEngine.addProvider(mnemonicWalletSubprovider);
providerEngine.addProvider(infuraRpcSubprovider);
providerEngine.start();
const seaport = new OpenSeaPort(
providerEngine,
{
networkName: Network.Rinkeby,
apiKey: API_KEY,
},
(arg) => console.log(arg)
);
async function main() {
console.log("Auctioning an item for a fixed price...");
const fixedPriceSellOrder = await seaport.createSellOrder({
asset: {
tokenId: "3",
tokenAddress: NFT_CONTRACT_ADDRESS,
},
startAmount: 0.0001,
expirationTime: 0,
accountAddress: OWNER_ADDRESS,
}) ;
console.log("fixedPriceSellOrder") ;
}
main();
This has been resolved. I have changed the HDProvider to #truffle/hdwallet-provider. Now I could see the listing in opensea after createSellOrder through opensea-js.
This link helped me to get this resolved

I’m trying to execute swap on Pancakeswap with node script but I get error

I am new at ethereum development and I am working on a simple script to execute swaps using Pancakeswap.
The code:
const ethers = require('ethers');
const {ChainId, Token, TokenAmount, Fetcher, Pair, Route, Trade, TradeType, Percent} =
require('#pancakeswap-libs/sdk');
const Web3 = require('web3');
const {JsonRpcProvider} = require("#ethersproject/providers");
require("dotenv").config();
const provider = new JsonRpcProvider('https://bsc-dataseed1.binance.org/');
const web3 = new Web3('wss://apis.ankr.com/wss/c40792ffe3514537be9fb4109b32d257/946dd909d324e5a6caa2b72ba75c5799/binance/full/main');
const { address: admin } = web3.eth.accounts.wallet.add(process.env.PRIVATE_KEY);
console.log(`Modulos cargados`);
// Command Line Input
const InputTokenAddr = web3.utils.toChecksumAddress(process.argv[2]);
// var BUSD = '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56';
const OutputTokenAddr = web3.utils.toChecksumAddress(process.argv[3]);
// var WBNB = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c';
const InputTokenAmount = process.argv[4]
const Slipage = process.argv[5];
const PANCAKE_ROUTER = process.argv[6];
// const PANCAKE_ROUTER_V2 = '0x10ed43c718714eb63d5aa57b78b54704e256024e';
// const PANCAKE_ROUTER_V1 = '0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F';
// 1/1000 = 0.001
const ONE_ETH_IN_WEI = web3.utils.toBN(web3.utils.toWei('1'));//BN->(BIG NUMBER) || toWei -> Converts any ether value value into wei.
const tradeAmount = ONE_ETH_IN_WEI.div(web3.utils.toBN('1000'));//tradeAmount = ONE_ETH_IN_WEI/1000
console.log(`tradeAmount ` + tradeAmount );
const init = async () => {
const [INPUT_TOKEN, OUTPUT_TOKEN] = await Promise.all(
[InputTokenAddr, OutputTokenAddr].map(tokenAddress => (
new Token(
ChainId.MAINNET,
tokenAddress,
18
)
)));
console.log(` <<<<<------- pair-------->>>>>`);
const pair = await Fetcher.fetchPairData(INPUT_TOKEN, OUTPUT_TOKEN, provider);
//console.log(JSON.stringify(pair));
console.log(` <<<<<------- route-------->>>>>`);
const route = await new Route([pair], INPUT_TOKEN);
//console.log(JSON.stringify(route));
console.log(` <<<<<------- Trade-------->>>>>`);
const trade = await new Trade(route, new TokenAmount(INPUT_TOKEN, tradeAmount), TradeType.EXACT_INPUT);
//console.log(JSON.stringify(trade));
//https://uniswap.org/docs/v2/javascript-SDK/trading/
const slippageTolerance = new Percent(Slipage, '100'); //
console.log("slippageTolerance: " + JSON.stringify(slippageTolerance));
// create transaction parameters
const amountOutMin = trade.minimumAmountOut(slippageTolerance).raw;
const path = [INPUT_TOKEN.address, OUTPUT_TOKEN.address];
const to = admin;
const deadline = Math.floor(Date.now() / 1000) + 60 * 20;
// Create signer
const wallet = new ethers.Wallet(
Buffer.from(
process.env.PRIVATE_KEY,
"hex"
)
);
const signer = wallet.connect(provider);
// Create Pancakeswap ethers Contract
const pancakeswap = new ethers.Contract(
PANCAKE_ROUTER,
['function swapExactTokensForTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)'],
signer
);
//Allow input token
if(true)
{
console.log(`Allow Pancakeswap <<<<<------- START-------->>>>>`);
let abi = ["function approve(address _spender, uint256 _value) public returns (bool success)"];
let contract = new ethers.Contract(INPUT_TOKEN.address, abi, signer);
let aproveResponse = await contract.approve(PANCAKE_ROUTER, ethers.utils.parseUnits('1000.0', 18), {gasLimit: 100000, gasPrice: 5e9});
console.log(JSON.stringify(aproveResponse));
console.log(`Allow Pancakeswap <<<<<------- END-------->>>>>`);
}
if(true)
{
console.log(`Ejecutando transaccion`);
var amountInParam = ethers.utils.parseUnits(InputTokenAmount, 18);
var amountOutMinParam = ethers.utils.parseUnits(web3.utils.fromWei(amountOutMin.toString()), 18);
console.log("amountInParam: " + amountInParam);
console.log("amountOutMinParam: " + amountOutMinParam);
console.log("amountOutMin: " + amountOutMin);
const tx = await pancakeswap.swapExactTokensForTokens(
amountInParam,
amountOutMinParam,
path,
to,
deadline,
{ gasLimit: ethers.utils.hexlify(300000), gasPrice: ethers.utils.parseUnits("9", "gwei") }
);
console.log(`Tx-hash: ${tx.hash}`)
const receipt = await tx.wait();
console.log(`Tx was mined in block: ${receipt.blockNumber}`);
}
}
init();
Normally I set BUSD as input token
And I use pancakeswap v1 or v2 router as router.
When output token is WBNB or BCH, it seems working well on both v1 and v2 router.
But when I set other token as an output token, I get error.
Plz help me.

Rinkeby Uniswap swapExactETHForTokens - Fail with error 'UniswapV2Router: EXPIRED'

Ideally, I need example of correct transaction format in web3 or ethers,
Where it can swap WETH for ERC20 or ERC20 for WETH using UniswapV2Router on Rinkeby,
I think, I'm having wrong transaction format, maybe it's because of gasPrice or gasLimit, but I don't understand where it happens, So I tried with the increased gasPrice(100 Gwei) and gasLimit(8,000,000) but it's still failing, I also decreased the "amountOutMin" to 1,
Transaction deadline is 20 minutes but it's failiing in a few seconds
Swap 1 Ether for UNI (WETH and ETH balances are more than 5 on sender's address)
transaction deadline: 20 minute
UNI address: 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984
UniswapV2Router: 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
Another small question, when you swap ETH for ERC20 does it takes WETH or ETH from senders balance?
const swap = async () => {
try{
const chainId = ChainId.RINKEBY
const tokenAddress = "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"
const uni = await Fetcher.fetchTokenData(chainId, tokenAddress)
const weth = WETH[chainId]
const pair = await Fetcher.fetchPairData(uni, weth)
const route = new Route([pair], weth)
const trade = new Trade(route, new TokenAmount(weth, '100000000000000000'), TradeType.EXACT_INPUT)
console.log('1 WETH for', route.midPrice.toSignificant(6), ' UNI')
console.log('1 UNI for', route.midPrice.invert().toSignificant(6), ' WETH')
console.log('Trade price 1 WETH for ', trade.executionPrice.toSignificant(6), ' UNI')
const accounts = await web3.eth.getAccounts()
const account = accounts[0]
const slippageTolerance = new Percent('20', '100')
const path = [weth.address, uni.address ]
const to = account
// function toHex(currencyAmount) {
// return `0x${currencyAmount.raw.toString(16)}`
// }
// const amountOutMin = toHex(trade.minimumAmountOut(slippageTolerance))
// const value = toHex(trade.inputAmount)
const uniswap = await new web3.eth.Contract(abi, "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D")
const now = moment().unix()
const DEADLINE = now + 60 *20
console.log('Sending...')
let txn = await uniswap.methods.swapExactETHForTokens( 1, path, to, DEADLINE ).send( {
from: account,
gasLimit: 8000000,
gasPrice: web3.utils.toWei('100', 'Gwei'),
value: web3.utils.toWei('1', 'Ether')
})
console.log(`Txn: https://rinkeby.etherscan.io/tx/${txn.transactionHash}`)
}catch(e){
console.log(e)
}
}
module.exports = swap
Transaction results on rinkeby etherscan:
Console:
"Error: Transaction has been reverted by the EVM "
Here is an example of swapping ETH to UNI. I am using ethJS.
const WETH_ADDRESS = "0xc778417e063141139fce010982780140aa0cd5ab";
const UNI_ADDRESS = "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984";
const path = [WETH_ADDRESS, UNI_ADDRESS];
const ethAmount = ethers.utils.parseEther("0.1");
const nowInSeconds = Math.floor(Date.now() / 1000)
const expiryDate = nowInSeconds + 900;
const txn = await uniswapV2Contract.swapExactETHForTokens(
0,
path,
user.address,
expiryDate,
{
gasLimit: 1000000,
gasPrice: ethers.utils.parseUnits("10", "gwei"),
value: ethAmount
}
)
const res = await txn.wait();
When you call the method swapExactETHForTokens, it would be taking ETH and not WETH. If you would like to swap with WETH, you should call swapExactTokensForTokens.

Uniswap - TypeError: Cannot read property 'sortsBefore' of undefined

We're building an ERC20 token and we're planning to deploy it on Uniswap.
Currently, we want to get the conversion rate on Uniswap but we're getting this error.
TypeError: Cannot read property 'sortsBefore' of undefined
Here's the code:
require('rootpath')();
const {ChainId, Token, WETH, Fetcher, Route, Pair} = require('#uniswap/sdk');
const {Config} = require('config');
const Web3 = require('web3');
module.exports = class UniswapManager {
// Docs: https://uniswap.org/docs/v2/javascript-SDK/pricing/
static async getPrice() {
const network = ChainId.RINKEBY;
const HelloWorldContract = Web3.utils.toChecksumAddress(Config.Contract.token());
const HWD = new Token(network, HelloWorldContract, 18);
const pair = new Pair(HWD, WETH[network]); > Error here
const route = new Route([pair], WETH[network]);
// Logging only
return 'HWD/ETH: ' + route.midPrice.toSignificant(6) + '\n' +
'ETH/HWD: ' + route.midPrice.invert().toSignificant(6);
}
}
UNI to ETH is working perfectly but not our ERC20 token.
const UniswapContract= Web3.utils.toChecksumAddress('0x5592ec0cfb4dbc12d3ab100b257153436a1f0fea'); // Rinkeby
const Uniswap = new Token(network, UniswapContract, 18);
const pair = await Fetcher.fetchPairData(Uniswap, WETH[network])
const route = new Route([pair], WETH[network]);
Try defining your token like
const WETH = new Token(
router.chainId,
'0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
18,
'WETH',
'Wrapped Ether'
);
chainID, address, decimals, symbol, name
it's because you're not defining the pair correctly

Sending a transaction results in "invalid sender"

I'm attempting to call a function on my smart contract (Ropsten) using web3 via an Infura node. I've created a test account in Metmask and have exported the account address and private key. The details look correct, however I am getting the error {"code":-32000,"message":"invalid sender"}. I'm guessing this is a problem with the signing of the transaction?
Here's my code
const Web3 = require('web3');
const Tx = require('ethereumjs-tx').Transaction;
const fs = require('fs');
const pk = Buffer.from('PRIVATE KEY FROM METAMASK', 'hex')
const sourceAccount = 'ACCOUNT ADDRESS FROM METAMASK'
const web3 = new Web3(new Web3.providers.HttpProvider("https://ropsten.infura.io/v3/API_KEY"));
const consumerAddress = '0xc36577aa0171f649be6bd7205148ed83c07198ee';
web3.eth.defaultAccount = sourceAccount;
//Get Consumer contract instance
const consumerAbi = JSON.parse(fs.readFileSync('rental-contract-abi.json', 'utf8'));
let consumerContract = new web3.eth.Contract(consumerAbi, consumerAddress);
const myData = consumerContract.methods.checkDate("e716efba3b404da98e28faaa2939c0fd","2019-06-04","AU-NSW").encodeABI();
web3.eth.getTransactionCount(sourceAccount, (err, txCount) => {
// Build the transaction
const txObject = {
nonce: web3.utils.toHex(txCount),
to: consumerAddress,
from: sourceAccount,
chainId: 3,
value: web3.utils.toHex(web3.utils.toWei('0', 'ether')),
gasLimit: web3.utils.toHex(2100000),
gasPrice: web3.utils.toHex(web3.utils.toWei('6', 'gwei')),
data: myData
}
// Sign the transaction
const tx = new Tx(txObject);
tx.sign(pk);
const feeCost = tx.getUpfrontCost()
console.log('Total Amount of ETH needed:' + web3.utils.fromWei(feeCost.toString(), 'ether'))
console.log('---Serialized TX----')
console.log(tx.serialize().toString('hex'))
console.log('--------------------')
const serializedTx = tx.serialize();
const raw = '0x' + serializedTx.toString('hex');
// Broadcast the transaction
const transaction = web3.eth.sendSignedTransaction(raw, (err, tx) => {
console.log(tx);
console.log(err);
});
});
You need to add network information while signing the transaction. Refer to latest web3 docs. Change signing transaction code to :
const tx = new Tx(txObject,{'chain':'ropsten'});

Resources