How can I get transactions from a wallet using alchemy websockets - javascript

I want to get all new transactions from a specified wallet and Im using this code. It just dont work when I use the function tx["transaction"]["from"] and I filter the wallet or ca I want on "WALLET".
Im using Alchemy methods with ws and I have read the documentation about how to use it, I should be missing something.
const { Alchemy, Network, AlchemySubscription } = require("alchemy-sdk")
const {ethers, FixedNumber} = require("ethers")
const delay = require('delay')
require("dotenv").config()
const ARBI_WS_KEY = process.env.ARBI_WS_KEY
const settings = {
apiKey: ARBI_WS_KEY, // Replace with your Alchemy API Key
network: Network.ARB_MAINNET, // Replace with your network
}
const alchemy = new Alchemy(settings)
// Subscription for Alchemy's minedTransactions API
const add = async () => {
alchemy.ws.on(
{
method: AlchemySubscription.MINED_TRANSACTIONS,
},
(tx) => {
let add0 = String(tx["transaction"]["from"])
if( add0 == "WALLET"){
console.log(tx["transaction"]["hash"])
}
}
)
}
Its weird because everything works when I filter tx["transaction"]["to"] and I specify a wallet or a contract to filter but when trying to filter "from" I dont get anything.

Related

ETH ENS Web3 - How to get Registrant

I've following code snippet to get the "Controller" (The owner of the domain) but I need to get the "Registrant" of provided ENS name
const Web3 = require("web3")
const web3 = new Web3("https://cloudflare-eth.com");
var ens = web3.eth.ens;
var names = ['jtimberlake.eth', 'usman.eth'];
(async () => {
for (let domainName of names) {
// console.log('checking: ' + domainName);
const addr = await getDomain(domainName);
console.log(addr);
}
})();
async function getDomain(word) {
try {
const addr = await ens.getAddress(`${word}`)
// console.log(addr);
return addr;
} catch (err) {
console.error(err);
return;
}
}
Can you please guide how I can get the "Registrant" of provided ENS name e.g. jtimberlake.eth
Web3 is a steaming pile. It doesn't do it with its methods. The registrant used to be called the deed owner, and the controller the owner. Now it is registrant and controller. That's why the method name makes no sense at all now in Web3.js - it never got updated, and never was useful for this in the first place.
The good news is there is a simple way. You can derive the token ID of the ENS domain from its name with the getRegistrant function below. https://docs.ens.domains/dapp-developer-guide/ens-as-nft
The name variable in the docs is superfluous and does nothing. You will need to instantiate ethersjs (npm install ethers) to get the ethers methods to work. You have to use this crazy number of functions because the token ID of an ENS domain/NFT is a uint256. JavaScript hates those natively.
The web3 method to find the controller also still works well if you ever need that. I suggest putting it in another function.
const getRegistrant = (domainName) => {
const BigNumber = ethers.BigNumber
const utils = ethers.utils
const labelHash = utils.keccak256(utils.toUtf8Bytes(domainName))
const derivedTokenId = BigNumber.from(labelHash).toString()
//You need to instantiate the ENSRegistrarContract with its ABI and address. e.g. const ENSRegistrarContract = new web3.eth.Contract(ABI, ADDRESS)
ENSRegistrarContract.methods.ownerOf(derivedTokenId).call()
.then(function(registrant) {
console.log(domainName + "is owned by: " + registrant)
return registrant
})
}
const getController = (domainName) => {
//getOwner fetches the controller of a domain confusingly.
web3.eth.ens.getOwner(domainName).then(function(controller) {
console.log(domainName + "is controlled by: " + controller)
return controller
})
}

AWS Lambda - Only getting answer after the second test trigger

I'm developing an AWS Lambda in TypeScript that uses Axios to get data from an API and that data will be filtered and be put into a dynamoDb.
The code looks as follows:
export {};
const axios = require("axios");
const AWS = require('aws-sdk');
exports.handler = async (event: any) => {
const shuttleDB = new AWS.DynamoDB.DocumentClient();
const startDate = "2021-08-16";
const endDate = "2021-08-16";
const startTime = "16:00:00";
const endTime = "17:00:00";
const response = await axios.post('URL', {
data:{
"von": startDate+"T"+startTime,
"bis": endDate+"T"+endTime
}}, {
headers: {
'x-rs-api-key': KEY
}
}
);
const params = response.data.data;
const putPromise = params.map(async(elem: object) => {
delete elem.feat1;
delete elem.feat2;
delete elem.feat3;
delete elem.feat4;
delete elem.feat5;
const paramsDynamoDB = {
TableName: String(process.env.TABLE_NAME),
Item: elem
}
shuttleDB.put(paramsDynamoDB).promise();
});
await Promise.all(putPromise);
};
This all works kind of fine. If the test button gets pushed the first time, everything seems fine and is working. E.g. I received all the console.logs during developing but the data is not put into the db.
With the second try it is the same output but the data is successfully put into the Db.
Any ideas regarding this issue? How can I solve this problem and have the data put into the Db after the first try?
Thanks in advance!
you need to return the promise from the db call -
return shuttleDB.put(paramsDynamoDB).promise();
also, Promise.all will complete early if any call fails (compared to Promise.allSettled), so it may be worth logging out any errors that may be happening too.
Better still, take a look at transactWrite - https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html#transactWrite-property to ensure all or nothing gets written

hdwallet provider create wallet for user

I have created a smart contract that facilitates a token sale. I want a user to be able to press a button that automatically generates an ERC20 wallet that tokens can be sent to.
I am using the truffle HDWallet Provider and Infura. I don't want the user to have to use MetaMask or anything else. I will sign the transactions on the backend using the private key of the user's generated wallet.
How would I go about implementing this so a new wallet is created for every new user that wants to perform a transaction?
This is the code that allowed me to create a wallet on a button press. I now need to find a way to store the credentials of these wallets so I can sign transactions and transfer tokens to them.
var bip39 = require('bip39');
const EthereumUtil = require('ethereumjs-util');
const hdkey = require('hdkey');
const mnemonic = bip39.generateMnemonic(); //generates string
const seed = bip39.mnemonicToSeed(mnemonic); //creates seed buffer
const root = hdkey.fromMasterSeed(seed);
const masterPrivateKey = root.privateKey.toString('hex');
const addrNode = root.derive("m/44'/60'/0'/0/0");
const pubKey = EthereumUtil.privateToPublic(addrNode._privateKey);
const addr = EthereumUtil.publicToAddress(pubKey).toString('hex');
const address = EthereumUtil.toChecksumAddress(addr);
Its pretty simple, just create a HDWalletProvider and the provider.addresses has all the accounts you can use:
Here is the code:
const createWallet = function(_providerUrl) {
const mnemonicPhrase = bip39.generateMnemonic()
let provider = new HDWalletProvider({
mnemonic: {
phrase: mnemonicPhrase
},
providerOrUrl: "http://localhost:8545"
});
return provider.addresses
}
Addresses has the accounts
The solution has already been commented above, but I have a better suggestion for you. I think it's better to generate only one mnemonic in your backend and you create infinite accounts from that mnemonic. From each account you extract the private key and store it, store the address of the account and the index of the account.
Management code:
const HDWalletProvider = require("#truffle/hdwallet-provider");
const Web3 = require("web3");
const mnemonicPhrase = "mnemonicPhrase here";
const urlRPC = "https://bsc-dataseed.binance.org";
//Creating another instance to query balances
const Web3Instance = require('web3');
const web3instance = new Web3Instance(new Web3Instance.providers.HttpProvider(urlRPC));
//HD Wallet Provider loads by default only 10 accounts
//We change the limit to as many accounts as we want
//You cannot run the loop below for i greater than 10, because for
const limit = 50;
async function getAccount() {
provider = new HDWalletProvider({
mnemonic: mnemonicPhrase,
numberOfAddresses: limit,
providerOrUrl: urlRPC,
addressIndex: 0,
});
//HDWalletProvider is compatible with Web3
//Use it at Web3 constructor, just like any other Web3 Provider
const web3 = new Web3(provider);
//I realized that iterating a loop to limit always gives an error when it reaches limit
//This happens in this HD Wallet Provider package
//limit - 1 seems to work best
for (let i = 0; i < limit - 1; i ++) {
var get = await web3.eth.getAccounts()
var address = get[i];
var balanceETH = await web3instance.eth.getBalance(address)
//Checking the adress
console.log(address);
console.log(balanceETH);
}
}
getAccount();
Here is more information:
https://ethereum.stackexchange.com/questions/52370/web3-create-account-from-mnemonic-passphrase/144340#144340

Using google apis in firebase funcion

I would like to use the google iot core api from a firebase function.
It all works, but it is very slow. I think is due to the authentication process that needs to be carried out one very call. Is there a way to speed this up?
Right now I have this:
function getClient(cb) {
const API_VERSION = 'v1';
const DISCOVERY_API = 'https://cloudiot.googleapis.com/$discovery/rest';
const jwtAccess = new google.auth.JWT();
jwtAccess.fromJSON(serviceAccount);
// Note that if you require additional scopes, they should be specified as a
// string, separated by spaces.
jwtAccess.scopes = 'https://www.googleapis.com/auth/cloud-platform';
// Set the default authentication to the above JWT access.
google.options({ auth: jwtAccess });
const discoveryUrl = `${DISCOVERY_API}?version=${API_VERSION}`;
google.discoverAPI(discoveryUrl, {}).then( end_point => {
cb(end_point);
});
}
And this allows me to do:
export function sendCommandToDevice(deviceId, subfolder, mqtt_data) {
const cloudRegion = 'europe-west1';
const projectId = 'my-project-id;
const registryId = 'my-registry-id';
getClient(client => {
const parentName = `projects/${projectId}/locations/${cloudRegion}`;
const registryName = `${parentName}/registries/${registryId}`;
const binaryData = Buffer.from(mqtt_data).toString('base64');
const request = {
name: `${registryName}/devices/${deviceId}`,
binaryData: binaryData,
subfolder: subfolder
};
client.projects.locations.registries.devices.sendCommandToDevice(request,
(err, data) => {
if (err) {
console.log('Could not update config:', deviceId);
}
});
});
}
The way that I've found to speed it up is to avoid doing the authentication. I've solved it doing this:
const google = new GoogleApis();
const API_VERSION = 'v1';
const DISCOVERY_API = 'https://cloudiot.googleapis.com/$discovery/rest';
const jwtAccess = new google.auth.JWT();
jwtAccess.fromJSON(serviceAccount);
// Note that if you require additional scopes, they should be specified as a
// string, separated by spaces.
jwtAccess.scopes = 'https://www.googleapis.com/auth/cloud-platform';
// Set the default authentication to the above JWT access.
google.options({ auth: jwtAccess });
const discoveryUrl = `${DISCOVERY_API}?version=${API_VERSION}`;
var googleClient;
google.discoverAPI(discoveryUrl, {}).then( client => {
//cb(end_point);
googleClient = client;
});
// Returns an authorized API client by discovering the Cloud IoT Core API with
// the provided API key.
function getClient(cb) {
cb(googleClient);
}
But when happens then when the client expires? Is there any good solution from using google apis from firebase functions?
The problem may be the discovery pieces. There's a direct IoT Core admin REST API, so you don't have to use discovery...I think. I haven't worked with the Firebase Functions, but they're roughly equivalent to the Google Cloud Functions which may end up working here also. The code we (in a live demo we did) ran to do what you're doing is here if you wanted to tinker around and see if you can get this running in a Firebase Function.

BCH transaction failed: Missing inputs 25

I am using Bitcoin Cash JS to create a transaction, and my code is as follows:
let BITBOXCli = require('bitbox-cli/lib/bitbox-cli').default;
const explorers = require('bitcore-explorers')
const insight = new explorers.Insight('https://test-bch-insight.bitpay.com')
let BITBOX = new BITBOXCli();
let txb = new BITBOX.TransactionBuilder('testnet');
var To = 'mkiuwbSQQVxMvvbBcYEKUdZgJfURhu3hrW'
var from = 'mvStb7hPtDCL8dmyifPGcYTuToVzf7ajTb';
var bch = require('bitcoincashjs')
var bchLib = require('#owstack/bch-lib')
const buf = new Buffer('b27ab45d3e3d157e8b95f800347974f9991cf13ceb814e1992f40c5e4e6d5253', 'hex')
const privateKey = new bch.PrivateKey(buf, bch.Networks.testnet)
const address = privateKey.toAddress('testnet')
insight.getUnspentUtxos(address.toString(), function (error, utxos) {
if (error) {
console.error(error)
return
}
console.log(utxos)
const utxo = {
txid: utxos[0].txid,
outputIndex: utxos[0].vout,
script: utxos[0].scriptPubKey,
satoshis: utxos[0].satoshis
}
const transaction = new bch.Transaction()
.from(utxo)
.to(To, 50000)
.sign(0, privateKey)
console.log(transaction.toString())
});
Now when I am running this code, I am able to get the raw transaction hash but I am not able to broadcast transaction and message is as follows:
Missing Inputs Error:-25
Any idea about this error?
Or is there any other way to create BCH transaction?
It looks like you're trying to create a simple transaction to send BCH from one address to another. There is now an example for this exact use case in the BITBOX SDK repository:
https://github.com/Bitcoin-com/bitbox-javascript-sdk/blob/master/examples/applications/wallet/send-bch/send-bch.js
There are also other examples there like creating a wallet checking a balance:
https://github.com/Bitcoin-com/bitbox-javascript-sdk/tree/master/examples/applications/wallet
There are even more examples in the Wormhole SDK. (Wormhole SDK is a superset of BITBOX, so it can do anything BITBOX can do):
https://github.com/Bitcoin-com/wormhole-sdk/tree/master/examples

Categories