How to transfer custom token by '#solana/web3.js' - solana

I want to send my deployed token other than sol using solana web3.js, but I don't know how. I've been looking for the official documentation for a long time, but I can't find it. Could you please let me know if you have any information on this? Thanks

The problem with the existing answers is they only show you how to first create a new custom token then perform a transfer from one wallet to another. Here I will show how to do this with an existing custom token.
import { Token, TOKEN_PROGRAM_ID } from "#solana/spl-token";
import { web3, Wallet } from "#project-serum/anchor";
async function transfer(tokenMintAddress: string, wallet: Wallet, to: string, connection: web3.Connection, amount: number) {
const mintPublicKey = new web3.PublicKey(tokenMintAddress);
const mintToken = new Token(
connection,
mintPublicKey,
TOKEN_PROGRAM_ID,
wallet.payer // the wallet owner will pay to transfer and to create recipients associated token account if it does not yet exist.
);
const fromTokenAccount = await mintToken.getOrCreateAssociatedAccountInfo(
wallet.publicKey
);
const destPublicKey = new web3.PublicKey(to);
// Get the derived address of the destination wallet which will hold the custom token
const associatedDestinationTokenAddr = await Token.getAssociatedTokenAddress(
mintToken.associatedProgramId,
mintToken.programId,
mintPublicKey,
destPublicKey
);
const receiverAccount = await connection.getAccountInfo(associatedDestinationTokenAddr);
const instructions: web3.TransactionInstruction[] = [];
if (receiverAccount === null) {
instructions.push(
Token.createAssociatedTokenAccountInstruction(
mintToken.associatedProgramId,
mintToken.programId,
mintPublicKey,
associatedDestinationTokenAddr,
destPublicKey,
wallet.publicKey
)
)
}
instructions.push(
Token.createTransferInstruction(
TOKEN_PROGRAM_ID,
fromTokenAccount.address,
associatedDestinationTokenAddr,
wallet.publicKey,
[],
amount
)
);
const transaction = new web3.Transaction().add(...instructions);
transaction.feePayer = wallet.publicKey;
transaction.recentBlockhash = (await connection.getRecentBlockhash()).blockhash;
const transactionSignature = await connection.sendRawTransaction(
transaction.serialize(),
{ skipPreflight: true }
);
await connection.confirmTransaction(transactionSignature);
}
notice how we add an instruction for creating the recipient's custom token account if they don't have one.

You need to make sure to install the npm bindings for the token program as you can see from imports below
import * as web3 from "#solana/web3.js";
import * as splToken from "#solana/spl-token";
// Address: 9vpsmXhZYMpvhCKiVoX5U8b1iKpfwJaFpPEEXF7hRm9N
const DEMO_WALLET_SECRET_KEY = new Uint8Array([
37, 21, 197, 185, 105, 201, 212, 148, 164, 108, 251, 159, 174, 252, 43, 246,
225, 156, 38, 203, 99, 42, 244, 73, 252, 143, 34, 239, 15, 222, 217, 91, 132,
167, 105, 60, 17, 211, 120, 243, 197, 99, 113, 34, 76, 127, 190, 18, 91, 246,
121, 93, 189, 55, 165, 129, 196, 104, 25, 157, 209, 168, 165, 149,
]);
(async () => {
// Connect to cluster
var connection = new web3.Connection(web3.clusterApiUrl("devnet"));
// Construct wallet keypairs
var fromWallet = web3.Keypair.fromSecretKey(DEMO_WALLET_SECRET_KEY);
var toWallet = web3.Keypair.generate();
// Construct my token class
var myMint = new web3.PublicKey("My Mint Public Address");
var myToken = new splToken.Token(
connection,
myMint,
splToken.TOKEN_PROGRAM_ID,
fromWallet
);
// Create associated token accounts for my token if they don't exist yet
var fromTokenAccount = await myToken.getOrCreateAssociatedAccountInfo(
fromWallet.publicKey
)
var toTokenAccount = await myToken.getOrCreateAssociatedAccountInfo(
toWallet.publicKey
)
// Add token transfer instructions to transaction
var transaction = new web3.Transaction()
.add(
splToken.Token.createTransferInstruction(
splToken.TOKEN_PROGRAM_ID,
fromTokenAccount.address,
toTokenAccount.address,
fromWallet.publicKey,
[],
0
)
);
// Sign transaction, broadcast, and confirm
var signature = await web3.sendAndConfirmTransaction(
connection,
transaction,
[fromWallet]
);
console.log("SIGNATURE", signature);
console.log("SUCCESS");
})();

Small update on #Ozymandias answer, there seems to be few changes in the spl-token library.
Firstly Token dosen't exist anymore. And few functions such as Token.getAssociatedTokenAddress also seem to be removed. Here is the updated code:
import * as splToken from "#solana/spl-token";
import { web3, Wallet } from "#project-serum/anchor";
async function transfer(tokenMintAddress: string, wallet: Wallet, to: string, connection: web3.Connection, amount: number) {
const mintPublicKey = new web3.PublicKey(tokenMintAddress);
const {TOKEN_PROGRAM_ID} = splToken
const fromTokenAccount = await splToken.getOrCreateAssociatedTokenAccount(
connection,
wallet.payer,
mintPublicKey,
wallet.publicKey
);
const destPublicKey = new web3.PublicKey(to);
// Get the derived address of the destination wallet which will hold the custom token
const associatedDestinationTokenAddr = await splToken.getOrCreateAssociatedTokenAccount(
connection,
wallet.payer,
mintPublicKey,
destPublicKey
);
const receiverAccount = await connection.getAccountInfo(associatedDestinationTokenAddr.address);
const instructions: web3.TransactionInstruction[] = [];
instructions.push(
splToken.createTransferInstruction(
fromTokenAccount.address,
associatedDestinationTokenAddr.address,
wallet.publicKey,
amount,
[],
TOKEN_PROGRAM_ID
)
);
const transaction = new web3.Transaction().add(...instructions);
transaction.feePayer = wallet.publicKey;
transaction.recentBlockhash = (await connection.getRecentBlockhash()).blockhash;
const transactionSignature = await connection.sendRawTransaction(
transaction.serialize(),
{ skipPreflight: true }
);
await connection.confirmTransaction(transactionSignature);
}

Related

Retrying failed custom token transaction with '#solana/web3.js'

I want to send my deployed token other than sol using solana web3.js. My code works most of the time but sometimes the transaction fails.
I put a while loop so that when the transaction fails the client retries it with the sendRawTransaction function. The problem is that when it fails the first time it always fails after it.
const provider = await this.getProvider();
const publicKey = new web3.PublicKey(this.wallet);
const toPublicKey = new web3.PublicKey(
"the public key to send"
);
const mint = new web3.PublicKey(
"my token adress"
);
const connection = await new Connection(clusterApiUrl("mainnet-beta"));
const { signTransaction } = useWallet();
const fromTokenAccount = await this.getOrCreateAssociatedTokenAccount(
connection,
publicKey,
mint,
publicKey,
signTransaction
)
});
const toTokenAccount = await this.getOrCreateAssociatedTokenAccount(
connection,
publicKey,
mint,
toPublicKey,
signTransaction
);
const transferInstruction = await this.createTransferInstruction(
fromTokenAccount.address, // source
toTokenAccount.address, // dest
publicKey,
amount,
[],
TOKEN_PROGRAM_ID
);
const transaction = new Transaction().add(transferInstruction);
var blockHash = await connection.getLatestBlockhash('finalized');
transaction.feePayer = await publicKey;
console.log(blockHash.blockhash)
transaction.recentBlockhash = blockHash.blockhash;
// const provider = await this.getProvider();
const signed = await provider.signTransaction(transaction);
window.createEvent('openPopup', {
text: 'Your transaction is being validated by the Solana blockchain.',
loading: 30,
show: true
})
var nbRetry = 0;
while(true){
const signature = await connection.sendRawTransaction(signed.serialize())
this.post(`verifyTransaction`, {
signature,
})
.then(() => {
window.location.assign('/transaction_success')
})
.catch(async (error) => {
if (error.response.status === 403) {
if (nbRetry > 5){
window.createEvent('openPopup', {
show: true,
image: 'error.png',
text: 'The transaction failed.',
reload: true
})} else nbRetry++;
}}
})

How to make GraphQL resolver for list of objects returned by API using Apollo?

I am new to GraphQL and want to run my first app. I have seen several examples but they have used several libraries and i just want simple example.
I have seen https://www.youtube.com/watch?v=hLcAlln-D_s
My Index.js code
const { ApolloServer, gql } = require("apollo-server");
const fetch = require("node-fetch");
const typeDefs = `
type Query {
getApplicant: [Applicant]
}
type Applicant {
FiscalYear:String
JobNumber: String
JobDescription: String
AppsReceived: Int
Female: Int
Male: Int
UnknownGender: Int
Black: Int
Hispanic: Int
Asian: Int
Caucasian: Int
AmericanIndian:Int
Filipino: Int
UnknownEthnicity: Int
} `;
const url = `http://localhost:52993/api/values`;
const resolvers = {
Query: {
getApplicant: async () => {
const response = await fetch(url).then(res => res.json());
console.log(response);
return response;
}
}
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
Data returned from API
[{ "FiscalYear": "2013-2014",
"JobNumber": "9206 OP 2014/04/18",
"JobDescription": "311 DIRECTOR 9206",
"AppsReceived": 54,
"Female": 20,
"Male": 31,
"UnknownGender": 3,
"Black": 25,
"Hispanic": 18,
"Asian": 1,
"Caucasian": 6,
"AmericanIndian": 0,
"Filipino": 0,
"UnknownEthnicity": 4
},
{
"FiscalYear": "2013-2014",
"JobNumber": "1223 P 2013/08/09",
"JobDescription": "ACCOUNTING CLERK 1223",
"AppsReceived": 648,
"Female": 488,
"Male": 152,
"UnknownGender": 8,
"Black": 151,
"Hispanic": 204,
"Asian": 123,
"Caucasian": 62,
"AmericanIndian": 3,
"Filipino": 79,
"UnknownEthnicity": 26
}]
when I query data it always displays null.What I am missing?
I have tried another API and it worked well with the same code, just changed the schema related things. Although my .net core Web API was returning same data as mentioned but to make my resolver work, I did 2 things
I returned the following from the API Get method:
var myJObject = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Applicant>>(json);
return Ok(myJObject);
In schema I modified "Applicant" properties to camel case. As I saw my API was returning camel case properties which are not getting mapped to my "Applicant" schema
I spent hours on that so I found it worth sharing.

How can i set color of the bullet depending on the data passed from the external array of values?

i have two types of data in one graph - the normal range (bars) and the value (line wiht bullets). if the value is more or less then the range - the color of bullet must be red, meaning that the value is not normal... How is it possible to pass there in the graph the precalculated color or calculate it by means of adapter function or any other working way?
image example
let data = [
{
code: "07090",
name: "Sodium",
result: 150,
unit: "mmol/L",
refMin: 137,
refMax: 149,
date: "2019-10-04"
},
{
code: "07090",
name: "Sodium",
result: 139,
unit: "mmol/L",
refMin: 135,
refMax: 147,
date: "2019-10-06"
},
{
code: "07090",
name: "Sodium",
result: 130,
unit: "mmol/L",
refMin: 135,
refMax: 147,
date: "2019-10-07"
},
{
code: "07090",
name: "Sodium",
result: 140,
unit: "mmol/L",
refMin: 135,
refMax: 147,
date: "2019-11-07"
},
{
code: "07090",
name: "Sodium",
result: 147,
unit: "mmol/L",
refMin: 135,
refMax: 147,
date: "2019-11-08"
},
{
code: "07090",
name: "Sodium",
result: 147,
unit: "mmol/L",
refMin: 134,
refMax: 146,
date: "2019-11-10"
},
{
code: "07090",
name: "Sodium",
result: 147,
unit: "mmol/L",
refMin: 134,
refMax: 146,
date: "2020-11-10"
},
{
code: "07090",
name: "Sodium",
result: 147,
unit: "mmol/L",
refMin: 134,
refMax: 146,
date: "2020-11-11"
}
];
let cols = [];
let lines = [];
let chartData = [];
for(let { result, refMin, refMax, date } of data) {
let markerColor = "#fff"; // !!!! the color is predefined here
if (result > refMax || result < refMin) {
markerColor = "#f00";
}
chartData.push({
date: new Date(date),
result: result,
colMin: refMin,
colMax: refMax,
markerColor
});
}
am4core.ready(function() {
// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end
// Create chart instance
var chart = am4core.create("chartContainer", am4charts.XYChart);
chart.responsive.enabled = true;
// Add data
chart.data = chartData;
// Create axes
var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
dateAxis.renderer.minGridDistance = 50;
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
var seriesCols = chart.series.push(new am4charts.ColumnSeries());
seriesCols.dataFields.dateX = "date";
seriesCols.dataFields.valueY = "colMax";
seriesCols.dataFields.openValueY = "colMin";
seriesCols.fill = am4core.color("#ccc");
seriesCols.strokeWidth = 0;
seriesCols.name = "Range";
seriesCols.tooltipText = "{colMin} - {colMax}";
seriesCols.tooltip.pointerOrientation = "horizontal";
seriesCols.tooltip.background.cornerRadius = 0;
seriesCols.tooltip.background.fillOpacity = 0.5;
seriesCols.tooltip.label.padding(10,10,7,10);
// Create series
var series = chart.series.push(new am4charts.LineSeries());
let circleBullet = series.bullets.push(new am4charts.CircleBullet());
circleBullet.circle.stroke = "#fff";
circleBullet.circle.fillOpacity = ".7";
circleBullet.circle.strokeWidth = 1;
series.dataFields.valueY = "result";
series.dataFields.dateX = "date";
series.dataFields.dummyData = "date";
series.strokeWidth = 2;
series.minBulletDistance = 30;
series.tooltipText = "{valueY}";
series.tooltip.pointerOrientation = "vertical";
series.tooltip.background.cornerRadius = 20;
series.tooltip.background.fillOpacity = 0.5;
series.tooltip.label.padding(12,12,12,12);
series.dummyData = { color: "markerColor" };
series.adapter.add("fill", function(fill, lalal) {
return fill;
});
// Add scrollbar
chart.scrollbarX = new am4charts.XYChartScrollbar();
chart.scrollbarX.series.push(series);
// Add cursor
chart.cursor = new am4charts.XYCursor();
chart.cursor.xAxis = dateAxis;
chart.cursor.snapToSeries = series;
});
SOLVED:
circleBullet.propertyFields.fill = "bulletColor";

How to connect to Azure Service Bus queue using AMQP over WebSocket on browser?

I have a Node app that can connect to Azure Service Bus queue using AMQP over WebSocket. The following are the libraries that I'm using:
node-amqp10 from noodlefrenzy
node-amqp10-transport-ws from noodelfrenzy
nodejs-websocket from sitegui
With the above libraries, I'm trying to make React app that will connect to Azure Service Bus queue using AMQP over WebSocket. I have made some changes to nodejs-websocket locally to replace the websocket. Below is the code that I'm using:
var url = 'wss://saskeyname:saskey#sbnamespace.servicebus.windows.net:443/$servicebus/websocket';
var socket = new WebSocket(url, 'AMQPWSB10');
socket.onmessage = function (event) {
console.log('onmessage:', event.data);
};
socket.onerror = function (event) {
console.error('onerror:', event);
};
socket.onclose = function (event) {
console.log('onclose:', event);
};
socket.onopen = function (event) {
console.log('onopen:', event) {
sasl.negotiate();
};
The web socket is closed as soon as the SASL negotiation starts.
I have the logs as below:
onopen: Event {isTrusted: true, type: "open", target: WebSocket, currentTarget: WebSocket, eventPhase: 2, …} Connection.js:66
write: Uint8Array(14) [130, 136, 117, 116, 125, 158, 52, 57, 44, 206, 118, 117, 125, 158] Connection.js:102
onclose: CloseEvent {isTrusted: true, wasClean: false, code: 1000, reason: "", type: "close", …}
Am I doing something wrong?

Laravel Excel chart

i'm trying to create a chart with the Laravel-excel package , but when the file is created and exported is without chart. I'm using laravel 5.1.
The excel.php file has the property 'includeCharts' => true
public function getChart(){
$excel= Excel::create('Users by Country-BetonLove', function($excel) {
$excel->setTitle('Users by Country');
$excel->setCompany('BetonLove');
$excel->sheet('First sheet', function($sheet) {
$sheet->fromArray(
array(
array('', 2010, 2011, 2012),
array('Q1', 12, 15, 21),
array('Q2', 56, 73, 86),
array('Q3', 52, 61, 69),
array('Q4', 30, 32, 0),
)
);
$dataSeriesLabels = array(
new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), // 2010
new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), // 2011
new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), // 2012
);
$xAxisTickValues = array(
new PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4), // Q1 to Q4
);
$dataSeriesValues = array(
new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', NULL, 4),
new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),
new PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$5', NULL, 4),
);
$series = new PHPExcel_Chart_DataSeries(
PHPExcel_Chart_DataSeries::TYPE_BARCHART, // plotType
PHPExcel_Chart_DataSeries::GROUPING_CLUSTERED, // plotGrouping
range(0, count($dataSeriesValues)-1), // plotOrder
$dataSeriesLabels, // plotLabel
$xAxisTickValues, // plotCategory
$dataSeriesValues // plotValues
);
$series->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_BAR);
$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series));
$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false);
$title = new PHPExcel_Chart_Title('Test Bar Chart');
$yAxisLabel = new PHPExcel_Chart_Title('Value ($k)');
// Create the chart
$chart = new PHPExcel_Chart(
'chart1', // name
$title, // title
$legend, // legend
$plotArea, // plotArea
true, // plotVisibleOnly
0, // displayBlanksAs
NULL, // xAxisLabel
$yAxisLabel // yAxisLabel
);
// Set the position where the chart should appear in the worksheet
$chart->setTopLeftPosition('A7');
$chart->setBottomRightPosition('H20');
// Add the chart to the worksheet
$sheet->addChart($chart);
});
});
$excel->export();
}
Excel charts are supported for '.xlsx'; $excel->export() default exports to '.xls'
So you should use $excel->export('xlsx');

Resources