Connect to a Solana custom program without a wallet / frontend - smartcontracts

I would like to be able to connect to my custom solana program without using any frontend object.
Currently, my provider method uses "window.solana" which I want to avoid.
The idea is to be able to sign transaction from a backend without having to retrieve object from a frontend. The transactions will be signed and paid directly by the program.
This how I am calling the my program now:
const network = clusterApiUrl("devnet");
const opts = {
preflightCommitment: "processed",
};
const { SystemProgram } = web3;
const getProvider = () => {
const connection = new Connection(network, opts.preflightCommitment);
const provider = new AnchorProvider(
connection,
window.solana,
opts.preflightCommitment
);
return provider;
};
const provider = getProvider();
const program = new Program(idl, programID, provider);

Anchor's Wallet class allows for exactly that form of implementation, as it is inherited from NodeWallet.
You need to instantiate an #solana/web3.js Keypair object, likely from your provided secret key, and then pass the keypair into the Anchor Wallet constructor. You can then pass the Wallet object into the AnchorProvider, no frontend adapters needed.
For your code, see below, where the Base58SecretKey comes from exporting private key of your desired signer on Phantom (or another wallet). You can also import the keypair using a uint8 array or Keypair.generate() for testing, if you prefer.
import * as anchor from "#project-serum/anchor";
const getProvider = () => {
const connection = new Connection(network, opts.preflightCommitment);
const keypair = new anchor.web3.Keypair.fromSecretKey(anchor.utils.bytes.bs58.decode("Base58SecretKey"))
const wallet = new Wallet(keypair);
const provider = new AnchorProvider(
connection,
wallet,
opts.preflightCommitment
);
return provider;
};

Related

Send erc20 Tokens using Alchemy

I am using the Alchemy SDK to build an ethereum wallet app on react native. The docs (https://docs.alchemy.com/docs/how-to-send-transactions-on-ethereum) show me how to send Eth and I have already tested this and it works. However, I don't see anywhere in the docs on how to specify which token should be sent. I am wondering how I can set up my transaction object so that it will send the correct token. Our app handles Eth and all erc20 tokens currently so that the user can see their balances.
Here is the method for sending Eth using Alchemy's SDK
const { Alchemy, Network, Wallet, Utils } = require("alchemy-sdk");
const dotenv = require("dotenv");
dotenv.config();
const { API_KEY, PRIVATE_KEY } = process.env;
const settings = {
apiKey: API_KEY,
network: Network.ETH_GOERLI,
};
const alchemy = new Alchemy(settings);
let wallet = new Wallet(PRIVATE_KEY);
async function main() {
const nonce = await alchemy.core.getTransactionCount(
wallet.address,
"latest"
);
let transaction = {
to: "0xa238b6008Bc2FBd9E386A5d4784511980cE504Cd",
value: Utils.parseEther("0.001"),
gasLimit: "21000",
maxPriorityFeePerGas: Utils.parseUnits("5", "gwei"),
maxFeePerGas: Utils.parseUnits("20", "gwei"),
nonce: nonce,
type: 2,
chainId: 5,
};
let rawTransaction = await wallet.signTransaction(transaction);
let tx = await alchemy.core.sendTransaction(rawTransaction);
console.log("Sent transaction", tx);
}
main();
I also found this article in the docs which explains the transaction object (https://docs.alchemy.com/docs/understanding-the-transaction-object-on-ethereum) but I still do not see where I would specify the token that I am sending.
The Alchemy SDK does not contain any CORE methods that you can use to connect to an interface of a deployed ERC20 contract with a view to using it to send transactions. However, you can connect with a deployed instance of a contract using a library like web3js or EthersJS
To send tokens from an ERC20 contract, you need to use a library like Ethersjs to connect to an instance of the deployed contract. An Ethereum is also required to connect to a deployed instance of the contract. A Provider is an abstraction of a connection to the Ethereum network, providing a concise, consistent interface to standard Ethereum node functionality. With a Provider, you can connect to an instance of a deployed contract and carry out transactions, track events, etc.
To be able to send transactions with an ERC20 token using the Alchemy SDK, you need the following:
The deployed contract address.
The deployed contract ABI.
The Contract Provider.
EtherJS
To connect to the EthersJS provider, use your Alchemy API KEY.
The following code is an example code which you can reference:
const { Wallet, Utils } = require("alchemy-sdk");
const dotenv = require("dotenv");
dotenv.config();
const { ALCHEMY_KEY, PRIVATE_KEY } = process.env;
const ethers = require("ethers");
const ABI = require("./ABI.json");
let wallet = new Wallet(PRIVATE_KEY);
const CONTRACT_ADDRESS = "0x...";
const provider = new ethers.providers.AlchemyProvider(
`https://eth-goerli.g.alchemy.com/v2/${ALCHEMY_KEY}`
);
async function main() {
const contract = new ethers.Contract(CONTRACT_ADDRESS, ABI, provider);
const amount = Utils.parseEther("0.001");
await contract.transfer(wallet.address, "<receiver-wallet-address>", amount);
console.log("Sent ", amount);
}
main();

How do I know which network currently connected in MetaMask by WalletConnet react native?

I am developing react native mobile application where user can connect their crypto wallet(MetaMask, Rainbow, etc.) to mobile application. Everything is working well. I have used this (#walletconnect/react-native-dapp) react-native package to achieve this requirement.
After connected the external wallet (MetaMask), later I have to do some transaction by my app.
To do transaction I have to get know which network currently set in MetaMask wallet.
Is there any way to know the current connected network(chainId)to Metamask by this react-native package.
To do the transaction I am using this code.
try {
let dataa = await contract.methods
.transfer(toAddress, value.toString())
.encodeABI();
let txObj = {
// gas: Web3js.utils.toHex(100000),
data: Web3js.utils.toHex(dataa),
from: userWallet,
to: POZ_TOKEN, // Contractor token address
};
try {
const transactionHash = await connector
.sendTransaction(txObj)
.catch((_err: any) => {
Toast.show({
autoHide: true,
text1: t('topUpPoz.transactionFailed'),
type: 'error',
});
});
console.log('transactionHash is =', transactionHash);
Please suggest me anyone.
With #walletconnect/react-native-dapp we can fetch chain ID using connector, sample code is given below.
Note: checkNetworkIdHandler is a custom user defined function to check chainId connected is valid or not.
import {useWalletConnect} from '#walletconnect/react-native-dapp';
//creating a wallet connect connector
const connector = useWalletConnect();
const connectExternalWallet = React.useCallback(() => {
return connector.connect();
}, [connector]);
//below code snippet to be called on wallet connect button click
async function connectWallet(){
try {
let connection = await connectExternalWallet();
let networkStatus = checkNetworkIdHandler(connection.chainId);
}catch (exception) {
console.log("Exception occurred while connecting to metamask");
}
}

bigquery authenticating with service account from text\string and not file path

I am using
this nodejs bigquery client
I have the service account json in string\text, I want to avoid to write it to temporary file due to security reasons.
Is there an option to do new BigQuery() and provide the service account as string and not as filepath?
Couldn't find this option anythere, in all the examples need to provide the filepath or export the GOOGLE_APPLICATION_CREDENTIALS variable.
Thanks.
It is possible to use the values in your service account as string for authentication. You can use BigQueryOptions and pass a credentials object. Credentials object will need client_email and private_key which can be found in your service account json.
Using the sample code you linked in your question, BigQueryOptions can be implemented in this manner.
const creds = {
client_email: 'your_service_account#project-id.iam.gserviceaccount.com',
private_key: '-----BEGIN PRIVATE KEY-----\nxxxxxxxxxxxxxxxxxxx\n-----END PRIVATE KEY-----\n'
};
const bigquery = new BigQuery(credentials=creds);
The whole code will be:
const {BigQuery} = require('#google-cloud/bigquery');
const creds = {
client_email: 'your_service_account#project-id.iam.gserviceaccount.com',
private_key: '-----BEGIN PRIVATE KEY-----\nxxxxxxxxxxxxxxxxxxx\n-----END PRIVATE KEY-----\n'
};
const bigquery = new BigQuery(credentials=creds);
async function query() {
// Queries the U.S. given names dataset for the state of Texas.
const query = `SELECT name
FROM \`bigquery-public-data.usa_names.usa_1910_2013\`
WHERE state = 'TX'
LIMIT 100`;
// For all options, see https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/query
const options = {
query: query,
// Location must match that of the dataset(s) referenced in the query.
location: 'US',
};
// Run the query as a job
const [job] = await bigquery.createQueryJob(options);
console.log(`Job ${job.id} started.`);
// Wait for the query to finish
const [rows] = await job.getQueryResults();
// Print the results
console.log('Rows:');
rows.forEach(row => console.log(row));
}
query()
Snippet of the output:

TronWeb to send trc20 usdt

I want to use TronWeb to send trc20 token. Whether I need to use contract().at() to do this? It means I need to treat trc20 token just as smart contract?
first things first, to clarify every token on any network (not just tron) has its own smart contract that has been published to the network
here is the code to get your account balance and another to transfer USDT
don't forget to init the code with your private key and network endpoints
note that you need tron energy and bandwidth to perform a transaction
you can read about them using this link
const CONTRACT = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"
async function getBalance(account) {
const {
abi
} = await tronWeb.trx.getContract(CONTRACT);
const contract = tronWeb.contract(abi.entrys, CONTRACT);
const balance = await contract.methods.balanceOf(account).call();
console.log("balance:", balance.toString());
}
async function transferUSDT(destination, amount) {
const {
abi
} = await tronWeb.trx.getContract(CONTRACT);
const contract = tronWeb.contract(abi.entrys, CONTRACT);
const resp = await contract.methods.transfer(destination, amount).send();
console.log("transfer:", resp);
}
When you init the tronweb compnent with private key ,you could use the contract().at()
tronWeb = new TronWeb(
'https://api.nileex.io/',
'https://api.nileex.io/',
'https://event.nileex.io/',
'your privateKey'
);

MongoDB Connection created for every AWS serverless function call

I have set up Express js with Serverless and connecting to mongoDb atlas.
The Code works fine, but It creates a connection for each call. I tried the Caching method also, but no luck with it.
Here is my code below
// server.js
const sls = require('serverless-http')
const connectToDatabase = require('./lib/db');
const app = require('./lib/app')
connectToDatabase();
module.exports.run = sls(app)
//db.js
const mongoose = require('mongoose')
var Promise = require("bluebird");
// console.log("Connecting to " + process.env.DB);
const connection = {}
mongoose.Promise= Promise;
module.exports = async () => {
if (connection.isConnected) {
console.log('=> using existing database connection')
return
}
console.log('=> using new database connection')
const db = await mongoose.connect(process.env.DB,{useNewUrlParser:true})
connection.isConnected = db.connections[0].readyState
}
There are a few things to check:
How long does your Lambda function take to execute? Your function will only handle one request at a time. If you make a second request before your first request completes a new instance of your function will spin up.
Ensure that mongoose isn't closing the connection after your function completes.