Keypairs และ Wallets
วิธีสร้าง Keypair ใหม่
actions ต่างๆ บน Solana libraries ต้องการ Keypair หรือ Wallet ถ้าเราเชื่อมกับ wallet อยู่แล้ว เราก็ไม่ต้องห่วงอะไร หรือถ้าเราต้องการ keypair เราก็แค่ต้องสร้างมันขึ้นมา
import { Keypair } from "@solana/web3.js";
(async () => {
let keypair = Keypair.generate();
})();
let keypair = Keypair.generate();
from solana.keypair import Keypair
keypair = Keypair()
keypair = Keypair()
use solana_sdk::signature::{Keypair};
fn main() {
let wallet = Keypair::new();
}
let wallet = Keypair::new();
$ solana-keygen new
# pubkey: 9ZNTfG4NyQgxy2SWjSiQoUyBPEvXT2xo7fKc5hPYYJ7b
solana-keygen new
วิธี restore a Keypair from a secret
ถ้าเรามี secret อยู่แล้วเราก็จะสามารถสร้าง Keypair จาก secret นั้นเพื่อทดสอบ dApp ของเราได้เลย
- สร้างจาก Bytes
import { Keypair } from "@solana/web3.js";
(async () => {
const keypair = Keypair.fromSecretKey(
Uint8Array.from([
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56,
222, 53, 138, 189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246,
15, 185, 186, 82, 177, 240, 148, 69, 241, 227, 167, 80, 141, 89, 240, 121,
121, 35, 172, 247, 68, 251, 226, 218, 48, 63, 176, 109, 168, 89, 238, 135,
])
);
})();
const keypair = Keypair.fromSecretKey(
Uint8Array.from([
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56,
222, 53, 138, 189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246,
15, 185, 186, 82, 177, 240, 148, 69, 241, 227, 167, 80, 141, 89, 240, 121,
121, 35, 172, 247, 68, 251, 226, 218, 48, 63, 176, 109, 168, 89, 238, 135,
])
);
from solana.keypair import Keypair
secret_key= [
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138,
189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240,
148, 69, 241, 227, 167, 80, 141, 89, 240, 121, 121, 35, 172, 247, 68, 251, 226, 218, 48,
63, 176, 109, 168, 89, 238, 135,
]
keypair = Keypair.from_secret_key(bytes(secret_key))
print("Created Keypair with Public Key: {}".format(keypair.public_key))
secret_key= [
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138,
189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240,
148, 69, 241, 227, 167, 80, 141, 89, 240, 121, 121, 35, 172, 247, 68, 251, 226, 218, 48,
63, 176, 109, 168, 89, 238, 135,
]
keypair = Keypair.from_secret_key(bytes(secret_key))
use solana_sdk::signature::{Keypair, Signer};
fn main() {
let secret_key: [u8; 64] = [
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138,
189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240,
148, 69, 241, 227, 167, 80, 141, 89, 240, 121, 121, 35, 172, 247, 68, 251, 226, 218, 48,
63, 176, 109, 168, 89, 238, 135,
];
if let Ok(wallet) = Keypair::from_bytes(&secret_key) {
let pubkey = Signer::pubkey(&wallet);
println!("Created keypair: {}", pubkey)
}
}
let secret_key: [u8; 64] = [
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138,
189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240,
148, 69, 241, 227, 167, 80, 141, 89, 240, 121, 121, 35, 172, 247, 68, 251, 226, 218, 48,
63, 176, 109, 168, 89, 238, 135,
];
let wallet = Keypair::from_bytes(&secret_key)?;
# input your secret into the Keypath listed under solana config get
# input your secret into the Keypath listed under solana config get
- สร้างจาก Base58 String
import { Keypair } from "@solana/web3.js";
import * as bs58 from "bs58";
(async () => {
const keypair = Keypair.fromSecretKey(
bs58.decode(
"5MaiiCavjCmn9Hs1o3eznqDEhRwxo7pXiAYez7keQUviUkauRiTMD8DrESdrNjN8zd9mTmVhRvBJeg5vhyvgrAhG"
)
);
})();
const keypair = Keypair.fromSecretKey(
bs58.decode(
"5MaiiCavjCmn9Hs1o3eznqDEhRwxo7pXiAYez7keQUviUkauRiTMD8DrESdrNjN8zd9mTmVhRvBJeg5vhyvgrAhG"
)
);
import base58
from solana.keypair import Keypair
b58_string = "5MaiiCavjCmn9Hs1o3eznqDEhRwxo7pXiAYez7keQUviUkauRiTMD8DrESdrNjN8zd9mTmVhRvBJeg5vhyvgrAhG"
keypair = Keypair.from_secret_key(base58.b58decode(b58_string)
print("Created Keypair with Public Key: {}".format(keypair.public_key))
b58_string = "5MaiiCavjCmn9Hs1o3eznqDEhRwxo7pXiAYez7keQUviUkauRiTMD8DrESdrNjN8zd9mTmVhRvBJeg5vhyvgrAhG"
keypair = Keypair.from_secret_key(base58.b58decode(b58_string))
use solana_sdk::signature::{Keypair, Signer};
fn main() {
let wallet = Keypair::from_base58_string(
"5MaiiCavjCmn9Hs1o3eznqDEhRwxo7pXiAYez7keQUviUkauRiTMD8DrESdrNjN8zd9mTmVhRvBJeg5vhyvgrAhG",
);
let pubkey = Signer::pubkey(&wallet);
println!("Created keypair: {}", pubkey)
}
let wallet = Keypair::from_base58_string(
"5MaiiCavjCmn9Hs1o3eznqDEhRwxo7pXiAYez7keQUviUkauRiTMD8DrESdrNjN8zd9mTmVhRvBJeg5vhyvgrAhG",
);
วิธี verify a Keypair
ถ้าเราได้ keypair มา เราสามารถตรวจสอบมันได้ว่า secret นั้นตรงกับ public key หรือเปล่า
import { Keypair, PublicKey } from "@solana/web3.js";
(async () => {
const publicKey = new PublicKey(
"24PNhTaNtomHhoy3fTRaMhAFCRj4uHqhZEEoWrKDbR5p"
);
const keypair = Keypair.fromSecretKey(
Uint8Array.from([
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56,
222, 53, 138, 189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246,
15, 185, 186, 82, 177, 240, 148, 69, 241, 227, 167, 80, 141, 89, 240, 121,
121, 35, 172, 247, 68, 251, 226, 218, 48, 63, 176, 109, 168, 89, 238, 135,
])
);
console.log(keypair.publicKey.toBase58() === publicKey.toBase58());
// true
})();
const publicKey = new PublicKey("24PNhTaNtomHhoy3fTRaMhAFCRj4uHqhZEEoWrKDbR5p");
const keypair = Keypair.fromSecretKey(
Uint8Array.from([
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56,
222, 53, 138, 189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246,
15, 185, 186, 82, 177, 240, 148, 69, 241, 227, 167, 80, 141, 89, 240, 121,
121, 35, 172, 247, 68, 251, 226, 218, 48, 63, 176, 109, 168, 89, 238, 135,
])
);
console.log(keypair.publicKey.toBase58() === publicKey.toBase58());
// true
from solana.keypair import Keypair
from solana.publickey import PublicKey
public_key = PublicKey("24PNhTaNtomHhoy3fTRaMhAFCRj4uHqhZEEoWrKDbR5p")
keys = [
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138,
189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240,
148, 69, 241, 227, 167, 80, 141, 89, 240, 121, 121, 35, 172, 247, 68, 251, 226, 218, 48,
63, 176, 109, 168, 89, 238, 135,
]
keypair = Keypair.from_secret_key(bytes(keys))
print(keypair.public_key.to_base58() == public_key.to_base58())
# True
public_key = PublicKey("24PNhTaNtomHhoy3fTRaMhAFCRj4uHqhZEEoWrKDbR5p")
keys = [
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138,
189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240,
148, 69, 241, 227, 167, 80, 141, 89, 240, 121, 121, 35, 172, 247, 68, 251, 226, 218, 48,
63, 176, 109, 168, 89, 238, 135,
]
keypair = Keypair.from_secret_key(bytes(keys))
print(keypair.public_key.to_base58() == public_key.to_base58())
# True
solana-keygen verify <PUBKEY> prompt://
solana-keygen verify <PUBKEY> prompt://
วิธี check if a public key has an associated private key
ในบางกรณีเฉพาะ (เช่น a Program Derived Address), public keys อาจจะไม่มี private key เราสามารถตรวจสอบโดยดูว่า public key อยู่บน ed25519 curve หรือไม่ เพราะ public keys ที่อยู่บน curve สามารถควบคุมได้จากผู้ใช้งานที่ถือ wallet นั้นอยู่
import { PublicKey } from "@solana/web3.js";
(async function () {
// Note that Keypair.generate() will always give a public key that is valid for users
const key = new PublicKey("5oNDL3swdJJF1g9DzJiZ4ynHXgszjAEpUkxVYejchzrY"); // Valid public key
console.log(PublicKey.isOnCurve(key.toBytes())); // Lies on the ed25519 curve and is suitable for users
const offCurveAddress = new PublicKey(
"4BJXYkfvg37zEmBbsacZjeQDpTNx91KppxFJxRqrz48e"
); // Valid public key
console.log(PublicKey.isOnCurve(offCurveAddress.toBytes())); // Not on the ed25519 curve, therefore not suitable for users
const errorPubkey = new PublicKey("testPubkey"); // Is not a valid public key
})();
const key = new PublicKey("5oNDL3swdJJF1g9DzJiZ4ynHXgszjAEpUkxVYejchzrY");
console.log(PublicKey.isOnCurve(key.toBytes()));
from solana.keypair import Keypair
from solana.publickey import PublicKey
from solana.utils.ed25519_base import is_on_curve
# Note that Keypair() will always give a public key that is valid for users
key = PublicKey('5oNDL3swdJJF1g9DzJiZ4ynHXgszjAEpUkxVYejchzrY') # Valid public key
print(is_on_curve(key)) # Lies on the ed25519 curve and is suitable for users
off_curve_address = PublicKey('4BJXYkfvg37zEmBbsacZjeQDpTNx91KppxFJxRqrz48e') # Valid public key
print(PublicKey._is_on_curve(off_curve_address)) # Not on the ed25519 curve, therefore not suitable for users
error_pubkey = PublicKey("testPubkey"); # Is not a valid public key
key = PublicKey('5oNDL3swdJJF1g9DzJiZ4ynHXgszjAEpUkxVYejchzrY')
print(is_on_curve(key))
use solana_sdk::pubkey::{Pubkey};
use std::str::FromStr;
fn main() {
// Note that Keypair::new() will always give a public key that is valid for users
let pubkey = Pubkey::from_str("5oNDL3swdJJF1g9DzJiZ4ynHXgszjAEpUkxVYejchzrY").unwrap(); // Valid public key
println!("{:?}", pubkey.is_on_curve()); // Lies on the ed25519 curve and is suitable for users
let off_curve_address = Pubkey::from_str("4BJXYkfvg37zEmBbsacZjeQDpTNx91KppxFJxRqrz48e").unwrap(); // Valid public key
println!("{:?}", off_curve_address.is_on_curve()); // Not on the ed25519 curve, therefore not suitable for users
let error_pubkey = Pubkey::from_str("testPubkey").unwrap(); // Is not a valid public key
}
let pubkey = Pubkey::from_str("5oNDL3swdJJF1g9DzJiZ4ynHXgszjAEpUkxVYejchzrY").unwrap();
println!("{:?}", pubkey.is_on_curve())
วิธี generate a mnemonic phrase
ถ้าเราสร้าง wallet เราต้องสร้าง mnemonic phrase เพื่อให้ user สามารถเก็บสำรองไว้
import * as bip39 from "bip39";
const mnemonic = bip39.generateMnemonic();
const mnemonic = bip39.generateMnemonic();
from mnemonic import Mnemonic
mnemo = Mnemonic("english")
words = mnemo.generate(strength=256)
mnemo = Mnemonic("english")
words = mnemo.generate(strength=256)
solana-keygen new
solana-keygen new
วิธีกู้ Keypair จาก mnemonic phrase
หลายๆ wallet extensions ใช้ mnemonics เพื่อใช้แทน secret keys เราสามารถเปลี่ยน mnemonic ไปเป็น Keypairs เพื่อทดสอบที่ local ได้
- BIP39 - สร้าง wallet 1 ตัว
import { Keypair } from "@solana/web3.js";
import * as bip39 from "bip39";
(async () => {
const mnemonic =
"pill tomorrow foster begin walnut borrow virtual kick shift mutual shoe scatter";
const seed = bip39.mnemonicToSeedSync(mnemonic, ""); // (mnemonic, password)
const keypair = Keypair.fromSeed(seed.slice(0, 32));
console.log(`${keypair.publicKey.toBase58()}`); // 5ZWj7a1f8tWkjBESHKgrLmXshuXxqeY9SYcfbshpAqPG
})();
const mnemonic =
"pill tomorrow foster begin walnut borrow virtual kick shift mutual shoe scatter";
const seed = bip39.mnemonicToSeedSync(mnemonic, ""); // (mnemonic, password)
const keypair = Keypair.fromSeed(seed.slice(0, 32));
from solana.keypair import Keypair
from mnemonic import Mnemonic
mnemo = Mnemonic("english")
seed = mnemo.to_seed("pill tomorrow foster begin walnut borrow virtual kick shift mutual shoe scatter")
keypair = Keypair.from_secret_key(seed)
print("Created Keypair with Public Key: {}".format(keypair.public_key)
mnemo = Mnemonic("english")
seed = mnemo.to_seed("pill tomorrow foster begin walnut borrow virtual kick shift mutual shoe scatter")
keypair = Keypair.from_secret_key(seed)
solana-keygen recover
solana-keygen recover
- BIP44 (สร้างหลาย wallets หรือที่เรียกว่า HD wallets)
เราสามารถสร้างหลาย wallets จาก seed เดียวหรือที่เราเรียกว่า 'Hierarchical Deterministic wallets' หรือ HD wallets:
import { Keypair } from "@solana/web3.js";
import { HDKey } from "micro-ed25519-hdkey";
import * as bip39 from "bip39";
(async () => {
const mnemonic =
"neither lonely flavor argue grass remind eye tag avocado spot unusual intact";
const seed = bip39.mnemonicToSeedSync(mnemonic, ""); // (mnemonic, password)
const hd = HDKey.fromMasterSeed(seed.toString("hex"));
for (let i = 0; i < 10; i++) {
const path = `m/44'/501'/${i}'/0'`;
const keypair = Keypair.fromSeed(hd.derive(path).privateKey);
console.log(`${path} => ${keypair.publicKey.toBase58()}`);
}
})();
const mnemonic =
"neither lonely flavor argue grass remind eye tag avocado spot unusual intact";
const seed = bip39.mnemonicToSeedSync(mnemonic, ""); // (mnemonic, password)
for (let i = 0; i < 10; i++) {
const path = `m/44'/501'/${i}'/0'`;
const keypair = Keypair.fromSeed(derivePath(path, seed.toString("hex")).key);
console.log(`${path} => ${keypair.publicKey.toBase58()}`);
}
solana-keygen recover 'prompt:?key=0/0'
solana-keygen recover 'prompt:?key=0/0'
วิธี generate a vanity address
Vanity public keys หรือ custom addresses คือ keys ที่เริ่มด้วยตัวอักษรที่เฉพาะเจาะจง เช่น เราอาจจะต้องการ publickey ที่ขึ้นต้้นด้วย "elv1s" หรือ "cook" ซึ่งมันจะทำให้จำไดง่ายขึ้นว่าเป็นของใคร ทำให้ key สามารถแยกแยะกันได้ง่ายขึ้น
Note: ยิ่งระบุ characters ใน vanity address มากเท่าไหร่ ก็จะยิ่งใช้เวลาในการค้นหา address นานขึ้น
WARNING
คุณควรใช้ CLI ในการสร้าง ทั้งตัวอย่าง Python และ TypeScript เป็นเพียงแค่การทำให้เห็นภาพมากขึ้นเท่านั้น และมันจะทำงานช้ากว่าบน CLI อีกด้วย
import { Keypair } from "@solana/web3.js";
(async () => {
let keypair = Keypair.generate();
while (!keypair.publicKey.toBase58().startsWith("elv1s")) {
keypair = Keypair.generate();
}
})();
let keypair = Keypair.generate();
while (!keypair.publicKey.toBase58().startsWith("elv1s")) {
keypair = Keypair.generate();
}
from solana.keypair import Keypair
keypair = Keypair()
while(str(keypair.public_key)[:5]!="elv1s") :
keypair = Keypair()
print("Created Keypair with Public Key: {}".format(keypair.public_key))
keypair = Keypair()
while(str(keypair.public_key)[:5]!="elv1s") :
keypair = Keypair()
solana-keygen grind --starts-with e1v1s:1
solana-keygen grind --starts-with e1v1s:1
วิธี sign และ verify messages with wallets
function หลักของ keypair คือ sign message และยังเอาไว้ตรวจสอบ signature ได้ด้วย ซึ่งการตรวจสอบ signature จะทำให้ผู้รับมั่นใจได้ว่าข้อมูลถูก sign ด้วยเจ้าของ private key นั้นจริงๆ
เพื่อที่จะทำตัวอย่างกันเราจะ import TweetNaCl crypto library มาใช้
import { Keypair } from "@solana/web3.js";
import nacl from "tweetnacl";
import { decodeUTF8 } from "tweetnacl-util";
(async () => {
const keypair = Keypair.fromSecretKey(
Uint8Array.from([
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56,
222, 53, 138, 189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246,
15, 185, 186, 82, 177, 240, 148, 69, 241, 227, 167, 80, 141, 89, 240, 121,
121, 35, 172, 247, 68, 251, 226, 218, 48, 63, 176, 109, 168, 89, 238, 135,
])
);
const message = "The quick brown fox jumps over the lazy dog";
const messageBytes = decodeUTF8(message);
const signature = nacl.sign.detached(messageBytes, keypair.secretKey);
const result = nacl.sign.detached.verify(
messageBytes,
signature,
keypair.publicKey.toBytes()
);
console.log(result);
})();
const message = "The quick brown fox jumps over the lazy dog";
const messageBytes = decodeUTF8(message);
const signature = nacl.sign.detached(messageBytes, keypair.secretKey);
const result = nacl.sign.detached.verify(
messageBytes,
signature,
keypair.publicKey.toBytes()
);
console.log(result);
from nacl.signing import VerifyKey
from solana.keypair import Keypair
secret_key = [
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138, 189, 224, 216, 117,
173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240, 148, 69, 241, 227, 167, 80, 141, 89, 240,
121, 121, 35, 172, 247, 68, 251, 226, 218, 48, 63, 176, 109, 168, 89, 238, 135,
]
keypair = Keypair.from_secret_key(bytes(secret_key))
pubkey_bytes = bytes(keypair.public_key)
message = "The quick brown fox jumps over the lazy dog"
message_bytes = bytes(message,'utf8')
signed_message = keypair.sign(message_bytes)
verify_sign = VerifyKey(
pubkey_bytes
).verify(
smessage=message_bytes,
signature=signed_message.signature
)
#Returns original message if the signature has not been tampered with
print(verify_sign)
message = "The quick brown fox jumps over the lazy dog"
message_bytes = bytes(message,'utf8')
signed_message = keypair.sign(message_bytes)
verify_sign = VerifyKey(
pubkey_bytes
).verify(
smessage=message_bytes,
signature=signed_message.signature
)
วิธีเชื่อมต่อกับ wallet
Solana's wallet-adapter libraries จะช่วยทำให้เราจัดการเชื่อมต่อ wallet ที่ฝั่ง client ได้อย่างง่ายดาย
React
Run คำสั่งข้างล่างเพื่อติดตั้ง dependencies ที่ต้องใช้:
yarn add @solana/wallet-adapter-react @solana/wallet-adapter-react-ui @solana/wallet-adapter-base @solana/wallet-adapter-wallets
React wallet-adapter libraries จะทำให้เราคงสถานะการเชื่อมต่อ wallet ผ่าน hooks และ Context providers ที่ชื่อว่า useWallet
, WalletProvider
, useConnection
, และ ConnectionProvider
React App ต้องครอบไว้ด้วย WalletProvider
และ ConnectionProvider
นอกจากนี้เรายังสามารถบอกให้ users เชื่อมต่อโดยใช้ useWalletModal
เพื่อสลับการมองเห็น connection modal และครอบ app ไว้ด้วย WalletModalProvider
จาก @solana/wallet-adapter-react-ui
ได้ด้วย. ตัว connection modal จะควบคุมการทำงาน connection ให้เรา ทำให้เราสามารถ listen ไว้ได้ว่า wallet เชื่อมต่อแล้ว. เราจะรู้ว่า wallet เชื่อมต่อแล้วเมื่อการตอบกลับของ useWallet
มีค่า wallet
อยู่ (ไม่ null). และตรงข้ามกันถ้า wallet ค่าเป็น null แสดงว่าเรายังไม่ได้เชื่อมต่อ (disconnected).
import React, { useMemo, FC, PropsWithChildren } from "react";
import {
ConnectionProvider,
WalletProvider,
} from "@solana/wallet-adapter-react";
import { WalletModalProvider } from "@solana/wallet-adapter-react-ui";
import { WalletAdapterNetwork } from "@solana/wallet-adapter-base";
import {
LedgerWalletAdapter,
PhantomWalletAdapter,
SlopeWalletAdapter,
TorusWalletAdapter,
} from "@solana/wallet-adapter-wallets";
import { clusterApiUrl } from "@solana/web3.js";
import { useWallet } from "@solana/wallet-adapter-react";
import { useWalletModal } from "@solana/wallet-adapter-react-ui";
import { MouseEventHandler } from "react";
export const Web3Provider: FC<PropsWithChildren<{}>> = ({ children }) => {
// Can be set to 'devnet', 'testnet', or 'mainnet-beta'
const endpoint = useMemo(
() => clusterApiUrl(WalletAdapterNetwork.Devnet),
[]
);
// @solana/wallet-adapter-wallets includes all the adapters but supports tree shaking --
// Only the wallets you configure here will be compiled into your application
const wallets = useMemo(
() => [
new PhantomWalletAdapter(),
new SlopeWalletAdapter(),
new TorusWalletAdapter(),
new LedgerWalletAdapter(),
],
[]
);
return (
<ConnectionProvider endpoint={endpoint}>
<WalletModalProvider>
<WalletProvider wallets={wallets}>{children}</WalletProvider>
</WalletModalProvider>
</ConnectionProvider>
);
};
/**
* Make sure to wrap the App with
* ConnectionProvider, WalletProvider, and WalletModalProvider.
*
* If you have a lot of Providers already, you can combine them
* into a single wrapper (i.e. Web3Provider) instead.
*/
export const App = () => {
return (
<Web3Provider>
<AppChild />
</Web3Provider>
);
};
const AppChild = () => {
const { wallet } = useWallet();
const { setVisible } = useWalletModal();
// Display the connection modal
const onRequestConnectWallet = () => {
setVisible(true);
};
// Prompt user to connect wallet
if (!wallet) {
return <button onClick={onRequestConnectWallet}>Connect Wallet</button>;
}
return (
<main>
<p>Wallet successfully connected!</p>
<p>{wallet.publicKey.toString()}</p>
</main>
);
};
const { wallet } = useWallet();
const { setVisible } = useWalletModal();
const onRequestConnectWallet = () => {
setVisible(true);
};
// Prompt the user to connect their wallet
if (!wallet) {
return <button onClick={onRequestConnectWallet}>Connect Wallet</button>;
}
// Displays the connected wallet address
return (
<main>
<p>Wallet successfully connected!</p>
<p>{wallet.publicKey.toBase58()}</p>
</main>
);
Vue
Run คำสั่งข้างล่างเพื่อติดตั้ง dependencies ที่ต้องใช้:
npm install solana-wallets-vue @solana/wallet-adapter-wallets
Solana Wallets Vue plugin จะทำให้เราสามาร initialise wallet store และ สร้าง global $wallet
ที่สามารถเข้าถึงได้จากทุกๆ component. ทุก properties และ methods ที่เราสามารถ อ่านค่าได้จาก useWallet()
จะมีแสดงไว้ ที่นี่. เราจะ import และ render WalletMultiButton component เพื่อให้ผู้ใช้สามารถเลือกและเชื่อมต่อ wallet ได้
<script setup>
import { WalletMultiButton } from "solana-wallets-vue";
import {
LedgerWalletAdapter,
PhantomWalletAdapter,
SlopeWalletAdapter,
TorusWalletAdapter,
} from "@solana/wallet-adapter-wallets";
import { initWallet, useWallet } from "solana-wallets-vue";
const wallets = {
wallets: [
new PhantomWalletAdapter(),
new SlopeWalletAdapter(),
new TorusWalletAdapter(),
new LedgerWalletAdapter(),
],
};
initWallet(wallets);
const { connected, wallet } = useWallet();
</script>
<template>
<div>
<p v-if="connected">
Wallet with public key {{ wallet.publicKey }} successfully connected!
</p>
<div v-else>
<wallet-multi-button></wallet-multi-button>
</div>
</div>
</template>
<script setup>
import { WalletMultiButton } from "solana-wallets-vue";
</script>
<template>
<wallet-multi-button></wallet-multi-button>
</template>
Svelte
Run คำสั่งข้างล่างเพื่อติดตั้ง dependencies ที่ต้องใช้:
npm install @svelte-on-solana/wallet-adapter-core @svelte-on-solana/wallet-adapter-ui @solana/wallet-adapter-base @solana/wallet-adapter-wallets @solana/web3.js
Svelte Wallet Adapter package จะทำให้เราสามารถเพิ่ม Svelte Store ($walletStore
) ที่เข้าถึงได้ทั้ง JS, TS และ/หรือ Svelte files ใน project ที่สร้างด้วย Svelte Template หรือ SvelteKit. โดยใช้ repo ที่นี่ เราสามารถที่จะใช้ adapter สำหรับ SSR หรือ SPA. ส่วน UI package จะมี <WalletMultiButton />
component เพื่อให้ผู้ใช้สามารถเลือกและเชื่อมต่อ wallet ได้
<script>
import { walletStore } from "@svelte-on-solana/wallet-adapter-core";
import {
WalletProvider,
WalletMultiButton,
ConnectionProvider,
} from "@svelte-on-solana/wallet-adapter-ui";
import { clusterApiUrl } from "@solana/web3.js";
import {
PhantomWalletAdapter,
SolflareWalletAdapter,
TorusWalletAdapter,
LedgerWalletAdapter,
} from "@solana/wallet-adapter-wallets";
const localStorageKey = "walletAdapter";
const network = clusterApiUrl("devnet"); // localhost or mainnet
let wallets = [
new PhantomWalletAdapter(),
new SolflareWalletAdapter(),
new TorusWalletAdapter(),
new LedgerWalletAdapter(),
];
</script>
<WalletProvider {localStorageKey} {wallets} autoConnect />
<ConnectionProvider {network} />
{#if $walletStore?.connected} Wallet with public key {$walletStore.publicKey}
successfully connected! {:else}
<WalletMultiButton />
{/if}
<script>
import { walletStore } from "@svelte-on-solana/wallet-adapter-core";
import { WalletMultiButton } from "@svelte-on-solana/wallet-adapter-ui";
</script>
{#if $walletStore?.connected} Wallet with public key {$walletStore.publicKey}
successfully connected! {:else}
<WalletMultiButton />
{/if}