I am trying call transferWithAuthorization on the USDC contract (which implements EIP-3009). To do this I need to sign the transaction data and then execute the transaction, however I am getting the error: Fail with error 'FiatTokenV2: invalid signature'
Example transaction error:
https://goerli.etherscan.io/tx/0x3d2cee8414682bcf55bc8adf86c2deaf14eb77448824c417629cca0d3f9bea94
Any ideas why?
const { ethers } = require('ethers');
const abi = require('./abi');
async function main() {
/* Generate Signature */
const sendingWallet = ethers.Wallet.createRandom();
const sendingAddress = await sendingWallet.getAddress();
const types = {
TransferWithAuthorization: [
{ name: 'from', type: 'address' },
{ name: 'to', type: 'address' },
{ name: 'value', type: 'uint256' },
{ name: 'validAfter', type: 'uint256' },
{ name: 'validBefore', type: 'uint256' },
{ name: 'nonce', type: 'bytes32' },
],
};
const domain = {
name: 'testapp',
version: '1',
chainId: '5',
verifyingContract: '0x07865c6E87B9F70255377e024ace6630C1Eaa37F', // USDC Contract
};
const message = {
from: sendingAddress,
to: '0x1bC152F3E47CC7baDF5629bc77CBEf9DaE813843', // Receiver wallet
value: 100000,
validAfter: 0,
validBefore: Math.floor(Date.now() / 1000) + 3600, // Valid for an hour
nonce: ethers.utils.hexValue(ethers.utils.randomBytes(32)), // 32 byte hex string
};
const signature = await sendingWallet._signTypedData(domain, types, message);
console.log(signature);
const { v, r, s } = ethers.utils.splitSignature(signature);
console.log(v, r, s);
/* Execute transaction */
// Throw away wallet :)
const wallet = ethers.Wallet.fromMnemonic(
'youth tool amount venue exact birth opinion derive lend charge roof food',
);
const connection = new ethers.providers.InfuraProvider(
'goerli', // or 'ropsten', 'rinkeby', 'kovan', 'goerli'
'x', // Infura API Key
);
const signer = wallet.connect(connection);
const contract = new ethers.Contract(
'0x07865c6E87B9F70255377e024ace6630C1Eaa37F',
abi,
signer,
);
const res = await contract.transferWithAuthorization(
message.from,
message.to,
message.value,
message.validAfter,
message.validBefore,
message.nonce,
v,
r,
s,
{
gasLimit: 1000000,
},
);
console.log(res);
const receipt = await res.wait();
console.log(receipt);
}
main();
Related
so I'm trying to make this idea I have come into fruition and I'm having a hard time figuring out where to start. The idea is a Nike Order Check command via discord bot, the user would use '/status' and input their email and order number and the bot would use Axios to get the guest order link 'https://www.nike.com/orders/details/', enter the two inputs the user inputted, click the submit button, then return values. New to using the Axios packages as a whole, so I'm lost on where to start. Does anyone have any ideas? The code below is what I have for before entering the inputs and after the data is captured
const { Discord, CommandInteraction, MessageEmbed } = require('discord.js');
const axios = require('axios');
const requests = require('request')
const wait = require('node:timers/promises').setTimeout;
module.exports = {
name: 'status',
description: 'Check Status Of Nike Order',
permission: 'USE_APPLICATION_COMMANDS',
options: [
{
name: 'email',
description: 'Input Account Email.',
required: true,
type: 'STRING'
},
{
name: 'ordernumber',
description: 'Input Order Number',
required: true,
type: 'STRING'
},
],
/**
*
* #param {CommandInteraction} interaction
*/
async execute(interaction) {
const { options } = interaction;
let email = options.getString("email");
let orderNumber = options.getString("ordernumber");
const baseURL = 'https://www.nike.com/orders/details/';
axios.get(`${baseURL}.json`).then((response) => {
let orderEmbed = new MessageEmbed()
.setTitle('Order Checked 🧪')
.setURL(``)
.addFields(
{ name: '**Account:**', value: `${email}` },
{ name: '**Status:**', value: `` },
{ name: '**Product Name:**', value: ``, inline: true },
{ name: '**Order Date:**', value: ``, inline: true },
{ name: '**Order Number:**', value: `${orderNumber}`, inline: true },
{ name: '**Size:**', value: `` },
)
.setTimestamp()
wait(2000);
interaction.reply({ embeds: [ orderEmbed ]})
})
}
}```
Since there was no answer to how to use axios for this project, I decided to use Puppeteer to integrate into Discord. The following code below is how I got that done.
const { Discord, CommandInteraction, MessageEmbed } = require('discord.js');
const puppeteer = require('puppeteer-extra');
const fs = require('fs');
const ChromeLauncher = require('chrome-launcher');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
const Ua = require('puppeteer-extra-plugin-anonymize-ua');
const prompt = require("prompt-sync")({ sigint: true });
const util = require('util');
const UserAgent = require('user-agents');
const request = require('request')
const wait = require('node:timers/promises').setTimeout;
puppeteer.use(StealthPlugin());
puppeteer.use(Ua());
//------------------ Proxy Integration ------------------//
var proxyData = "proxies.json";
function getProxies() {
if (fs.existsSync(proxyData)) {
return JSON.parse(fs.readFileSync(proxyData));
}
var proxies = {
proxies: prompt("Input Proxy List Separated By Commas: ")?.split(/,\s*/) ?? [],
proxyUsername: prompt("Input Proxy Username: "),
proxyPassword: prompt("Input Proxy Password: ")
};
fs.writeFileSync(proxyData, JSON.stringify(proxies));
return proxies [Math.floor(Math.random() * proxies.length)];
}
let { proxies, proxyUsername, proxyPassword } = getProxies();
let proxyList = (`${proxies[Math.floor(Math.random() * proxies.length)]}`);
console.log(proxyList)
module.exports = {
name: 'status',
description: 'Check Status Of Nike Order',
permission: 'USE_APPLICATION_COMMANDS',
options: [
{
name: 'email',
description: 'Input Account Email.',
required: true,
type: 'STRING'
},
{
name: 'ordernumber',
description: 'Input Order Number',
required: true,
type: 'STRING'
},
],
/**
*
* #param {CommandInteraction} interaction
*/
async execute(interaction) {
const { options } = interaction;
let email = options.getString("email");
let orderNumber = options.getString("ordernumber");
await interaction.deferReply();
await wait(1000);
try {
const browser = await puppeteer.launch({
headless: false,
executablePath: `C:/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe`,
userDataDir: `%LOCALAPPDATA%/BraveSoftware/Brave-Browser/User Data/Default`,
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-web-security',
'--disable-features=IsolateOrigins,site-per-process',
`--enable-auto-reload=true`,
`--proxy-server=http://${proxyList}`
],
})
const page = await browser.newPage()
await page.authenticate({username:proxyUsername, password:proxyPassword});
await page.goto("https://www.nike.com/orders/details/")
await page.evaluate(async() => {
await new Promise(function(resolve) {
setTimeout(resolve, 1000)
});
});
await page.waitForSelector('#orderNumber');
await page.click("#orderNumber", { delay: 250 });
await page.keyboard.type(`${orderNumber}`, { delay: 250 })
await page.waitForSelector('#email');
await page.click('#email', { delay: 500 })
await page.keyboard.type(`${email}`, { delay: 250 })
await page.keyboard.press("Enter", { delay: 250 });
await page.waitForSelector(`p[data-testid="Order Purchase Type"]`)
let purchaseInfo = await page.evaluate(() => {
let purchaseTag = document.querySelectorAll(`p[data-testid="Order Purchase Type"]`);
let purchase = [];
purchaseTag.forEach((tag) => {
purchase.push(tag.innerText)
})
return purchase;
});
await page.waitForSelector(`h3[data-testid="Product Title"]`);
let productInfo = await page.evaluate(() => {
let productTag = document.querySelectorAll(`h3[data-testid="Product Title"]`);
let product = [];
productTag.forEach((tag) => {
product.push(tag.innerText)
})
return product;
});
await page.waitForSelector(`p[data-testid="Product Size"]`);
let productSize = await page.evaluate(() => {
let sizeTag = document.querySelectorAll(`p[data-testid="Product Size"]`);
let size = [];
sizeTag.forEach((tag) => {
size.push(tag.innerHTML)
})
return size;
});
await page.waitForSelector(`div[class="shipment-status-messaging mb3-sm u-full-width"]`);
let deliveryInfo = await page.evaluate(() => {
let deliveryTag = document.querySelectorAll(`div[class="shipment-status-messaging mb3-sm u-full-width"]`);
let delivery = [];
deliveryTag.forEach((tag) => {
delivery.push(tag.innerText)
})
return delivery;
});
await page.waitForSelector(`p[data-testid="Product Style Color"]`);
let skuInfo = await page.evaluate(() => {
let skuTag = document.querySelectorAll(`p[data-testid="Product Style Color"]`);
let sku = [];
skuTag.forEach((tag) => {
sku.push(tag.innerText)
})
return sku.toString();
});
browser.close()
let imgSKU = skuInfo.replace("-", "_")
let updatedSKU = imgSKU.replace("Style ", "")
console.log(updatedSKU)
let orderEmbed = new MessageEmbed()
.setTitle('Order Checked 🧪')
.setColor('#2B2F51')
.addFields(
{ name: '**Account:**', value: `${email}` },
{ name: '**Status:**', value: `${deliveryInfo}` },
{ name: '**Product Name:**', value: `${productInfo}`, inline: true },
{ name: '**Order Date:**', value: `${purchaseInfo}`, inline: true },
{ name: '**Order Number:**', value: `${orderNumber}`, inline: true },
{ name: '**Size:**', value: `${productSize}` },
)
.setTimestamp()
.setThumbnail(`https://images.nike.com/is/image/DotCom/${updatedSKU}?/$OMEGA_PRODUCT$.png`)
wait(2000);
interaction.editReply({ embeds: [ orderEmbed ]})
} catch (error) {
const errorEmbed = new MessageEmbed()
errorEmbed.setTitle('❌ Error Encountered ❌')
errorEmbed.setDescription('No variants/product found')
errorEmbed.setTimestamp()
interaction.editReply({ embeds: [ errorEmbed ]})
}
}
}
I'm new to mongooseDB and i'm trying to insert data from this API to the database, it creates the Collection but not the documents, any idea what could i be doing wrong?
import fetch from 'node-fetch';
import mongoose, { mongo } from 'mongoose';
mongoose.connect("mongodb://localhost/highscore");
const postSchema = new mongoose.Schema({
position: {
type: Number,
required: true
},
id: {
type: Number,
required: true
},
score: {
type: Number,
required: true
},
});
const Post = mongoose.model('Players', postSchema);
async function getPlayers() {
const getPlayers = await fetch("http://localhost:3008/api/highscore/players");
const response = await getPlayers.json();
for (let i = 0; i < response.lenght; i++) {
const post = new Post({
position: response[i]['position'],
id: response[i]['id'],
score: response[i]['score'],
});
post.save()
}
}
getPlayers();```
MongoDB provides Api to insert many documents at the same time, example below.
// check if your mongoDb is connected
mongoose.connect(URI).then(err => {
if(err) console.error({err});
else console.info("Database Connected");
});
async function getPlayers() {
const getPlayers = await fetch("http://localhost:3008/api/highscore/players");
try{
const response = await getPlayers.json();
// And then check if you are getting players
console.log({response});
const posts = response.map((player) => ({
position: player['position'],
id: player['id'],
score: player['score'],
}))
// it's not required to await it, just to be sure it did insert
await Post.insertMany(posts);
}catch(error){
console.log({error})
}
}
This line:
for (let i = 0; i < response.lenght; i++) {
response.length
now your array is empty so the save never happens
EDIT
Are you sure about the imports?
Following code works:
//const fetch = require('fetch');
const mongoose = require('mongoose');
mongoose.connect("mongodb://localhost/highscore");
const postSchema = new mongoose.Schema({
position: {
type: Number,
required: true
},
id: {
type: Number,
required: true
},
score: {
type: Number,
required: true
},
});
const Post = mongoose.model('Players', postSchema);
async function getPlayers() {
/*
const getPlayers = await fetch("http://localhost:3008/api/highscore/players");
const response = await getPlayers.json();
for (let i = 0; i < response.lenght; i++) {
*/
const post = new Post({
position: '12',
id: '15',
score: '300',
});
post.save()
} //} getPlayers();
Solution:
import fetch from 'node-fetch';
import mongoose, { mongo } from 'mongoose';
mongoose.connect("mongodb://127.0.0.1:27017/highscore");
const postSchema = new mongoose.Schema({
position: {
type: Number,
required: true
},
id: {
type: Number,
required: true
},
score: {
type: Number,
required: true
},
});
const Post = mongoose.model('Players', postSchema);
async function getPosts() {
const getPlayers = await fetch("http://localhost:3008/api/highscore/players");
const response = await getPlayers.json();
for( let i = 0;i < response.players.length; i++){
const post = new Post({
position: response.players[i]['position'],
id: response.players[i]['id'],
score: response.players[i]['score'],
});
post.save();
}
}
getPosts();
By default mongodb runs on localhost: 27017
Check your mongodb connection url
mongoose.connect('mongodb://localhost:27017/highscore')
I am trying to fill my mongodb document with data from unsplash and randomuser api.
const userdata = await axios.get("https://randomuser.me/api/?results=51");
const imagedat = await axios.get(
"https://api.unsplash.com/photos/random/?count=51&client_id=GWDzPpjHk743C2QnVBRxu8PtmOI3npF5sePZZ7o0pg4"
);
I call both apis for 51 results but after 22 results the code under catch gets displayed and only 22 documents get created
how to store all 51 results
const seeddata = async () => {
const userdata = await axios.get("https://randomuser.me/api/?results=51");
const imagedat = await axios.get(
"https://api.unsplash.com/photos/random/?count=51&client_id=GWDzPpjHk743C2QnVBRxu8PtmOI3npF5sePZZ7o0pg4"
);
try {
await MemoModel.deleteMany({});
const userarr = await userdata.data;
const imagedata = await imagedat.data;
for (let i = 0; i < 50; i++) {
const data = new MemoModel({
name: {
firstname: `${userarr.results[i].name.first}`,
lastname: `${userarr.results[i].name.last}`,
username: `${userarr.results[i].login.username}`,
},
about: {
user: `${userarr.results[i].gender} aged ${userarr.results[i].dob.age}. Rotting here for ${userarr.results[i].registered.age} `,
},
location: {
country: `${
countryarr[Math.floor(Math.random() * countryarr.length)]
}`,
state: `${userarr.results[i].location.state}`,
city: `${userarr.results[i].location.city}`,
address: `${userarr.results[i].location.street.name} ,${userarr.results[i].location.street.number}`,
zipcode: `${userarr.results[i].location.postcode}`,
},
email: {
user: `${userarr.results[i].email}`,
},
image: {
dp: `${userarr.results[i].picture.large}`,
coverimage: "https://source.unsplash.com/random/?mountains",
},
posts: {
postno: i,
posttitle: `${imagedata[i].description}`,
postcontent: `${imagedata[i].urls.regular}`,
postlikesno: imagedata[i].likes,
postcommentno: imagedata[i].width,
},
});
await data.save();
}
} catch {
console.log("catastrophic Failure");
}
};
seeddata().then(() => {
mongoose.connection.close();
});
Can you add (err) after your catch and console it instead of "catastrophic error"? It will give us the whole error that break your code:
catch(err) {
console.error(err)
}
I am trying to implement hyperledger sawtooth transaction through javascript SDK following this https://sawtooth.hyperledger.org/docs/core/releases/1.0/_autogen/sdk_submit_tutorial_js.html#encoding-your-payload.
/*
*Create the transaction header
*/
const createTransactionHeader = function createTransactionHeader(payloadBytes) {
return protobuf.TransactionHeader.encode({
familyName: 'intkey',
familyVersion: '1.0',
inputs: [],
outputs: [],
signerPublicKey: '02cb65a26f7af4286d5f8118400262f7790e20018f2d01e1a9ffc25de1aafabdda',
batcherPublicKey: '02cb65a26f7af4286d5f8118400262f7790e20018f2d01e1a9ffc25de1aafabdda',
dependencies: [],
payloadSha512: createHash('sha512').update(payloadBytes).digest('hex')
}).finish();
}
/*
* Create the transactions
*/
const createTransaction = function createTransaction(transactionHeaderBytes, payloadBytes) {
const signature = signer.sign(transactionHeaderBytes)
return transaction = protobuf.Transaction.create({
header: transactionHeaderBytes,
headerSignature: Buffer.from(signature, 'utf8').toString('hex'),
payload: payloadBytes
});
}
While submitting the transaction I am getting the following error from REST API
{
"error": {
"code": 30,
"message": "The submitted BatchList was rejected by the validator. It was poorly formed, or has an invalid signature.",
"title": "Submitted Batches Invalid"
}
}
Found the following issue similar to my problem
Sawtooth Invalid Batch or Signature
But its implemented in java the solution not work for my case
This should work, try this:
const cbor = require('cbor');
const {createContext, CryptoFactory} = require('sawtooth-sdk/signing');
const {createHash} = require('crypto');
const {protobuf} = require('sawtooth-sdk');
const request = require('request');
const crypto = require('crypto');
const context = createContext('secp256k1');
const privateKey = context.newRandomPrivateKey();
const signer = CryptoFactory(context).newSigner(privateKey);
// Here's how you can generate the input output address
const FAMILY_NAMESPACE = crypto.createHash('sha512').update('intkey').digest('hex').toLowerCase().substr(0, 6);
const address = FAMILY_NAMESPACE + crypto.createHash('sha512').update('foo').digest('hex').toLowerCase().substr(0, 64);
const payload = {
Verb: 'set',
Name: 'foo',
Value: 42
};
const payloadBytes = cbor.encode(payload);
const transactionHeaderBytes = protobuf.TransactionHeader.encode({
familyName: 'intkey',
familyVersion: '1.0',
inputs: [address],
outputs: [address],
signerPublicKey: signer.getPublicKey().asHex(),
batcherPublicKey: signer.getPublicKey().asHex(),
dependencies: [],
payloadSha512: createHash('sha512').update(payloadBytes).digest('hex')
}).finish();
const transactionHeaderSignature = signer.sign(transactionHeaderBytes);
const transaction = protobuf.Transaction.create({
header: transactionHeaderBytes,
headerSignature: transactionHeaderSignature,
payload: payloadBytes
});
const transactions = [transaction]
const batchHeaderBytes = protobuf.BatchHeader.encode({
signerPublicKey: signer.getPublicKey().asHex(),
transactionIds: transactions.map((txn) => txn.headerSignature),
}).finish();
const batchHeaderSignature = signer.sign(batchHeaderBytes)
const batch = protobuf.Batch.create({
header: batchHeaderBytes,
headerSignature: batchHeaderSignature,
transactions: transactions
};
const batchListBytes = protobuf.BatchList.encode({
batches: [batch]
}).finish();
request.post({
url: 'http://rest.api.domain/batches',
body: batchListBytes,
headers: {'Content-Type': 'application/octet-stream'}
}, (err, response) => {
if(err) {
return console.log(err);
}
console.log(response.body);
});
I try to run the code without success.
Only the first call works in start of node.
Here is my current code:
const Product = require('../models/Product');
const Price = require('../models/Price');
const cron = require('node-cron');
const amazon = require('amazon-product-api');
const util = require('util');
const _ = require('underscore')
/**
* Cron job
* Tracking price
*/
exports.track = () => {
cron.schedule('* * * * *', () => {
const client = amazon.createClient({
awsId: process.env.AWS_ID,
awsSecret: process.env.AWS_SECRET,
assocId: process.env.AWS_TAG
});
Promise.all([Product.getAsin()])
.then(([asin]) => {
let listId = _.pluck(asin, '_id');
let listAsin = _.pluck(asin, 'asin');
if (asin.length === 0) {
return
}
client.itemLookup({
idType: 'ASIN',
itemId: listAsin,
domain: 'webservices.amazon.fr',
responseGroup: 'ItemAttributes,OfferFull,SalesRank'
}).then((results) => {
for(i=0; i<listId.length; i++){
results[i].id = listId[i];
}
for(res of results) {
Price.addPrice({
asin: res.ASIN[0],
product: res.id,
salePrice: res.Offers[0].Offer[0].OfferListing[0].Price[0].Amount[0],
})
}
console.log(listId);
Product.makeUpdate(listId);
}).catch(function(err) {
console.log(err);
console.log(util.inspect(err, true, null));
});
})
.catch((err) => {
console.log(err);
})
})
}
Requests to MongoDB are asynchronous.
Product
const mongoose = require('mongoose');
mongoose.Promise = Promise;
const _ = require('underscore');
const moment = require('moment');
const productSchema = new mongoose.Schema({
name: String,
domain: String,
originUrl: { type: String, unique: true },
check: { type: Number, default: 0 },
ean: String,
asin: String
}, { timestamps: true });
Object.assign(productSchema.statics, {
getAsin() {
return this.find(
{ updatedAt: { $lt: oneMin },
asin: { $ne: null }
}
).limit(10)
.select({ asin: 1 })
.exec()//.then((tuples) => _.pluck(tuples, 'asin'))
},
makeUpdate(id) {
console.log('list des ID updated => ' + id);
return this.update({ _id: { $in: id } }, { $inc : { "check": 1 } } , {multi: true}).exec();
}
});
const Product = mongoose.model('Product', productSchema);
module.exports = Product;
const oneMin = moment().subtract(1, 'minutes').format();
Also, since I'm absolutely new to JavaScript and Node.js in general, any best practices or general tips will be greatly appreciated! :)