I'm using #solana/web3.js and have this code:
const web3 = require("#solana/web3.js");
const clusterApi = process.env.SOLANA_CLUSTER;
module.exports = {
getConfirmedSignaturesForAddress: async address => {
try {
const connection = new web3.Connection(web3.clusterApiUrl(clusterApi), "confirmed");
const result = await connection.getSignaturesForAddress(address, {
limit: 25
});
return {
tx: result,
status: true
};
} catch (e) {
return {
status: false,
error: e.message
};
}
}
}
And every time I call this function I get this error:
{ status: false, error: 'address.toBase58 is not a function' }
I was trying to send it already converted to Base58, but it just doesn't work. What's wrong?
This is how I solved this problem. Generally speaking, you need to convert it not just by converting to pure Base58, but like this:
const web3 = require("#solana/web3.js");
const bip39 = require("bip39");
const getKeyFromMemonic = async mnemonic => {
return new Promise((resolve, reject) => {
bip39
.mnemonicToSeed(mnemonic)
.then(buffer => {
const a = new Uint8Array(buffer.toJSON().data.slice(0, 32));
const key = web3.Keypair.fromSeed(a);
resolve(key);
})
.catch(err => reject(err));
});
};
getSignaturesForAddress: async address => {
try {
const key = await getKeyFromMemonic(address);
const connection = new web3.Connection(web3.clusterApiUrl(clusterApi), "confirmed");
const result = await connection.getSignaturesForAddress(key.publicKey);
return {
tx: result,
status: true
};
} catch (e) {
return {
status: false,
error: e.message
};
}
}
Related
I'm using Node JS, here's the code
import fetch from 'node-fetch';
import { JSDOM } from 'jsdom';
import {Appartment} from "./models/Appartment.mjs"
let applist = []
let multipleDivs = []
async function kijAppartments() {
try {
const kijCall = await fetch(`https://www.kijiji.ca/b-ville-de-montreal/appartement-4-1-2/k0l1700281?rb=true&dc=true`);
if(!kijCall.ok) {
throw new Error (
`HTTP error: ${kijCall.status}`
)
}
const response = await kijCall.text()
const dom = new JSDOM(response)
multipleDivs = dom.window.document.querySelectorAll(".info-container")
// console.log(multipleDivs)
return multipleDivs
}
catch(error) {
console.log("Error Made")
console.log(error)
}
}
async function arrayOfApps() {
await kijAppartments()
.then(data => {
data.forEach(div => {
const newApp = new Appartment
newApp.price = div.childNodes[1].innerText
newApp.title = div.childNodes[3].innerText
newApp.description = div.childNodes[7].innerText
console.log(newApp)
})
})
}
await arrayOfApps()
If you go on this link and try the following const aList = document.querySelectorAll(".info-container"), you get access to all of the nodes, innerHTML and innerText all work and give you access to the actual value but for some reason, when I try to run this code in the terminal, the value of all my objects is undefined.
You should use textContent instead of innerText.
Here's my solution:
const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));
const jsdom = require('jsdom');
const { JSDOM } = jsdom;
class Appartment {
price
title
description
location
}
let multipleDivs = []
const appartments = []
function trim(text){
return text.replace(/(\r\n|\n|\r)/gm, "").trim()
}
async function fetchKijijiAppartments() {
const url = `https://www.kijiji.ca/b-ville-de-montreal/appartement-4-1-2/k0l1700281?rb=true&dc=true`
try {
const kijijiRes = await fetch(url);
if (!kijijiRes.ok) {
throw new Error(
`HTTP error: ${kijijiRes.status}`
)
}
const response = await kijijiRes.text()
// console.log("DB: ", response)
const dom = new JSDOM(response)
multipleDivs = dom.window.document.querySelectorAll(".info-container")
//console.log("DB: " multipleDivs)
return multipleDivs
} catch (error) {
console.log("Error Made")
console.log(error)
}
}
async function scrapeAppartments() {
await fetchKijijiAppartments()
.then(data => {
data.forEach(div => {
const appartement = new Appartment
appartement.price = trim(div.querySelector(".price").textContent)
appartement.title = trim(div.querySelector(".title").textContent)
appartement.description = trim(div.querySelector(".description").textContent)
console.log("DB: ", appartement)
appartments.push(appartement)
})
})
}
scrapeAppartments()
i am initializing a node js app with crucial data for the app to work from a database in index.js.
index.ts
import {getInitialData} from 'initData.ts';
export let APP_DATA: AppData;
export const initializeAppData = async () => {
try {
APP_DATA = (await getInitialData()) as AppData;
if (process.env.NODE_ENV !== 'test') {
initializeMongoose();
startServer();
}
} catch (error) {
console.log(error);
}
};
initData.ts
let dbName: string = 'initialData';
if (process.env.NODE_ENV === 'test') {
dbName = 'testDb';
}
const uri = `${process.env.MONGODB_URI}/?maxPoolSize=20&w=majority`;
export async function getInitialData() {
const client = new MongoClient(uri);
try {
await client.connect();
const database = client.db(dbName);
const configCursor = database
.collection('config')
.find({}, { projection: { _id: 0 } });
const config = await configCursor.toArray();
const aaoCursor = database
.collection('aao')
.find({}, { projection: { _id: 0 } });
const aao = await aaoCursor.toArray();
return { config, aao };
} catch {
(err: Error) => console.log(err);
} finally {
await client.close();
}
}
I'm using this array in another file and import it there.
missionCreateHandler
import { APP_DATA } from '../index';
export const addMissionResources = (
alarmKeyword: AlarmKeyword,
newMission: MissionDocument
) => {
const alarmKeywordObject = APP_DATA?.aao.find(
(el) => Object.keys(el)[0] === alarmKeyword
);
const resourceCommand = Object.values(alarmKeywordObject!);
resourceCommand.forEach((el) => {
Object.entries(el).forEach(([key, value]) => {
for (let ii = 1; ii <= value; ii++) {
newMission.resources?.push({
initialType: key,
status: 'unarranged',
});
}
});
});
};
I'm setting up a mongodb-memory-server in globalSetup.ts for Jest and copy the relevant data to the database from json-files.
globalSetup.ts
export = async function globalSetup() {
const instance = await MongoMemoryServer.create({
instance: { dbName: 'testDb' },
});
const uri = instance.getUri();
(global as any).__MONGOINSTANCE = instance;
process.env.MONGODB_URI = uri.slice(0, uri.lastIndexOf('/'));
process.env.JWT_SECRET = 'testSECRET';
const client = new MongoClient(
`${process.env.MONGODB_URI}/?maxPoolSize=20&w=majority`
);
try {
await client.connect();
const database = client.db('testDb');
database.createCollection('aao');
//#ts-ignore
await database.collection('aao').insertMany(aao['default']);
} catch (error) {
console.log(error);
} finally {
await client.close();
}
};
missionCreateHandler.test.ts
test('it adds the correct mission resources to the array', async () => {
const newMission = await Mission.create({
address: {
street: 'test',
houseNr: 23,
},
alarmKeyword: 'R1',
});
const expected = {
initialType: 'rtw',
status: 'unarranged',
};
addMissionResources('R1', newMission);
expect(newMission.resources[0].initialType).toEqual(expected.initialType);
expect(newMission.resources[0].status).toEqual(expected.status);
});
When runing the test, i get an 'TypeError: Cannot convert undefined or null to object at Function.values ()'. So it seems that the APP_DATA object is not set. I checked that the mongodb-memory-server is set up correctly and feed with the needed data.
When i hardcode the content of APP_DATA in index.ts, the test runs without problems.
So my questions are: How is the best practice to set up initial data in a node js app and where to store it (global object, simple variable and import it in the files where needed)? How can the test successfully run, or is my code just untestable?
Thank you!
I keep running into an issue where one of my curried functions is not a function when mocked out according to jest. I made a set of util httpRequest functions in a file called httpRequest.js that looks like this:
const httpRequest = (method) => {
return (headers) => {
return (data) => {
return async (url) => {
try {
const result = await axios({ method, url, data, headers });
const { data: axiosResult } = result;
return axiosResult;
} catch (err) {
console.log(`${method}Data: `, err);
throw err;
}
};
};
};
};
const getData = httpRequest('get')()();
const postData = httpRequest('post')();
const putData = httpRequest('put')();
const patchData = httpRequest('patch')();
const deleteData = httpRequest('delete')()();
const preBuiltGetRequest = httpRequest('get');
const preBuiltPostRequest = httpRequest('post');
const preBuiltPutRequest = httpRequest('put');
const preBuiltPatchRequest = httpRequest('patch');
const preBuiltDeleteRequest = httpRequest('delete');
module.exports = {
httpRequest,
getData,
postData,
putData,
patchData,
deleteData,
preBuiltGetRequest,
preBuiltPostRequest,
preBuiltPutRequest,
preBuiltPatchRequest,
preBuiltDeleteRequest,
};
When I mock out this file in a test and then use a function such as preBuiltGetRequest I get an error on jest saying TypeError: preBuiltGetRequest(...) is not a function. Here is an example of implementation of this.
Here is the function in my codebase I am testing:
queryUser: async (accessToken, email) => {
const query = `
{
getUsersByCriteria(criteria: Email, values: "${email}") {
id
groups {
id
name
entitlements {
id
code
}
members {
total
}
}
}
}
`;
const newUrl = new URL(`${BaseUrl}/v3/graphql`);
newUrl.searchParams.append('query', papiQuery);
console.log('From the Api ', preBuiltGetRequest);
const getAuthenticatedData = preBuiltGetRequest({
Authorization: `Bearer ${accessToken}`,
})();
const response = await getAuthenticatedData(newUrl.toString());
const graphQlResult = response.data?.getUsersByCriteria;
if (!graphQlResult || graphQlResult.length === 0) {
throw new Error(`Could not find user with email=${email}`);
}
return graphQlResult[0];
},
When I then run the test code mocking out preBuiltGetRequest using this code:
jest.mock('/opt/httpRequest');
const { preBuiltGetRequest } = require('/opt/httpRequest');
I receive this error:
The preBuiltGetRequest function has a signature that can be typed as
declare const prebuiltGetRequest: (header: object) => (data: object) => (url: String) => Promise<never>;
You need to mock it accordingly,
jest.mock('/opt/httpRequest');
const { preBuiltGetRequest } = require('/opt/httpRequest');
const mockSig = jest.fn().mockReturnValue(
jest.fn().mockResolvedValueOnce(error)
)
preBuiltGetRequest.mockReturnValue(mockSig)
I'm having a problem reading this piece of code in a project that we are developing with colleagues. I'll be greateful if you can help me and tell me what that piece of code mean. I get that in that piece, I`m having the technologies.csv file and we need to parse it, and if there is an error we must throw an exception to this error. And at the end of the code there are some cards but i don't know what is the idea of this cards. And at the final we have to export the module with the data, and i think the data is from the const with the programing languages.If someone can explain it with details it would be more than perfect. Thanks in advance! :)
const fs = require('fs');
const parse = require('csv-parse');
const path = require('path');
const constants = {
testData: {
csvColumns: [
'ruby',
'python',
'vuejs',
'angular',
'react',
'nodejs',
],
},
};
const configFileLocation = (name) => {
return
{
filename: path.join(__dirname, `${name}technologies.csv`)
}
}
const getData = (name) =>
new Promise((resolve, reject) => {
const fileLocation = configFileLocation(name).filename;
const csvParser = parse({
delimiter: ',',
});
if (!fs.existsSync(fileLocation)) {
reject(new Error(`File ${fileLocation} is missing.`));
}
const csvFileStream = fs.createReadStream(fileLocation);
csvFileStream.on('ready', () => {
csvFileStream.pipe(csvParser);
});
csvFileStream.on('error', (error) => {
reject(
new Error({
error,
message: 'csvParseCards#csvFileStream on error',
})
);
});
csvParser.on('error', (error) => {
reject(
new Error({
error,
message: 'csvParseCards#csvParser on error',
})
);
});
const cards = [];
csvParser.on('readable', () => {
let record = '';
while ((record = csvParser.read())) {
const card = {};
const columns = constants.testData.csvColumns;
if (record.length !== columns.length) {
console.warn('Column mismatch', record);
}
record.map((value, index) => {
card[columns[index]] = value;
});
cards.push(card);
}
});
csvParser.on('end', () => {
cards.shift();
resolve(cards);
});
});
module.exports = getData;
I have a lambda function in AWS. I use it to retrieve information from a REST API. When I test it runs returns a 200 status code, but an "ERROR TypeError: Cannot read property 'Message' of undefined
at smsResponder (/var/task/smsResponder.js:33:35)" also shows. I have googled, and tried to use .responseText.
My code is below. Should I be using return or something of the sort?
'use strict'
const AWS = require('aws-sdk')
AWS.config.update({ region: process.env.AWS_REGION || 'us-east-1' })
const { getStock } = require('./getStock')
const KEYWORD = 'stock'
const validateStock = function (elementValue){
let stockTest = AAPL
return stockTest.test(elementValue)
}
const sendSMS = async function (params) {
const pinpoint = new AWS.Pinpoint()
console.log('sendSMS called: ', params)
return new Promise((resolve, reject) => {
pinpoint.sendMessages(params, function(err, data) {
if(err) {
console.error(err)
reject(err)
} else {
console.log("Message sent. Data: ", data)
resolve(data)
}
})
})
}
const smsResponder = async (event) => {
const msg = JSON.parse(event.Sns.Message)
const msgWords = msg.messageBody.split(" ")
// Check the first word of the text message is the keyword
if (msgWords[0].toLowerCase() !== KEYWORD) return console.log('No keyword found - exiting')
// Validate stock name and get price
let message =''
const stockCode = msgWords[1]
if (validateStock(stockCode)) {
message = await getStock(stockCode)
} else {
message = 'Invalid stock symbol - text me in the format "stock stocksymbol".'
}
// Send the SMS response
const params = {
ApplicationId: process.env.ApplicationId,
MessageRequest: {
Addresses: {
[msg.originationNumber]: {
ChannelType: 'SMS'
}
},
MessageConfiguration: {
SMSMessage: {
Body: message,
MessageType: 'PROMOTIONAL',
OriginationNumber: msg.destinationNumber
}
}
}
}
return console.log(await sendSMS(params))
}
module.exports = { smsResponder }
The SNS-Event is differently structured, it should be event.Records[0].Sns.Message .
Here are the docs:
https://docs.aws.amazon.com/lambda/latest/dg/with-sns.html