Pares de Chaves e Carteiras
Como gerar um novo Par de Chaves (Keypair)
Muitas das diferentes ações que você pode executar com as diversas bibliotecas da Solana requerem um Par de Chaves ou Carteira. Se você estiver conectando-se a uma carteira, não precisa se preocupar. No entanto, se precisar de um par de chaves, precisará gerar um.
import { Keypair } from "@solana/web3.js";
(async () => {
let keypair = Keypair.generate();
})();
let keypair = Keypair.generate();
from solders.keypair import Keypair
keypair = Keypair()
keypair = Keypair()
// clang++ generate_keypair.cpp -o generate_keypair -std=c++17 -lssl -lcrypto -lsodium
#include "solana.hpp"
using namespace many::solana;
int main() {
auto key_pair = Keypair::generate();
auto public_key = key_pair.public_key;
std::cout << "public_key = " << public_key.to_base58() << std::endl;
return 0;
}
auto key_pair = Keypair::generate();
use solana_sdk::signature::{Keypair};
fn main() {
let wallet = Keypair::new();
}
let wallet = Keypair::new();
$ solana-keygen new
# pubkey: 9ZNTfG4NyQgxy2SWjSiQoUyBPEvXT2xo7fKc5hPYYJ7b
solana-keygen new
Como restaurar um Par de Chaves a partir de uma senha
Se você já tem sua senha, pode obter seu Par de Chaves a partir da senha para testar seu dApp.
- A partir de 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 solders.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_bytes(secret_key)
print("Created Keypair with Public Key: {}".format(keypair.pubkey()))
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_bytes(secret_key)
// clang++ keypair_from_seed.cpp -o keypair_from_seed -std=c++17 -lssl -lcrypto -lsodium
#include "solana.hpp"
using namespace many::solana;
int main() {
const uint8_t bytes[] = {
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 key_pair = Keypair::from_seed(bytes);
std::cout << "Created Keypair with Public Key: " << key_pair.public_key.to_base58() << std::endl;
}
const uint8_t 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 key_pair = Keypair::from_seed(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
- A partir de uma String Base58
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"
)
);
from solders.keypair import Keypair
b58_string = "5MaiiCavjCmn9Hs1o3eznqDEhRwxo7pXiAYez7keQUviUkauRiTMD8DrESdrNjN8zd9mTmVhRvBJeg5vhyvgrAhG"
keypair = Keypair.from_string(b58_string)
print("Created Keypair with Public Key: {}".format(keypair.pubkey()))
b58_string = "5MaiiCavjCmn9Hs1o3eznqDEhRwxo7pXiAYez7keQUviUkauRiTMD8DrESdrNjN8zd9mTmVhRvBJeg5vhyvgrAhG"
keypair = Keypair.from_string(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",
);
Como verificar um Par de Chaves
Se você receber um Par de Chaves, pode verificar se a senha corresponde à chave pública fornecida.
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 solders.keypair import Keypair
from solders.pubkey import Pubkey
public_key = Pubkey.from_string("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_bytes(keys)
print(keypair.pubkey() == public_key)
# True
public_key = Pubkey.from_string("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_bytes(keys)
print(keypair.pubkey() == public_key)
# True
// clang++ verify_keypair.cpp -o verify_keypair -std=c++17 -lssl -lcrypto -lsodium
#include "solana.hpp"
using namespace many::solana;
int main() {
PublicKey public_key = PublicKey("24PNhTaNtomHhoy3fTRaMhAFCRj4uHqhZEEoWrKDbR5p");
const uint8_t bytes[] = {
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 key_pair = Keypair::from_seed(bytes);
std::cout << (public_key.to_base58() == key_pair.public_key.to_base58()) << std::endl;
}
PublicKey public_key = PublicKey("24PNhTaNtomHhoy3fTRaMhAFCRj4uHqhZEEoWrKDbR5p");
const uint8_t bytes[] = {
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 key_pair = Keypair::from_seed(bytes);
std::cout << (public_key.to_base58() == key_pair.public_key.to_base58()) << std::endl;
// 1
solana-keygen verify <PUBKEY> prompt://
solana-keygen verify <PUBKEY> prompt://
Como verificar se uma chave pública tem uma chave privada associada
Em certos casos especiais (por exemplo, em um endereço derivado do programa), as chaves públicas podem não ter uma chave privada associada a elas. Você pode verificar isso conferindo se a chave pública está na curva ed25519. Somente chaves públicas que estão na curva podem ser controladas por usuários com carteiras.
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 solders.pubkey import Pubkey
# Note that Keypair() will always give a public key that is valid for users
key = Pubkey.from_string('5oNDL3swdJJF1g9DzJiZ4ynHXgszjAEpUkxVYejchzrY') # Valid public key
print(key.is_on_curve()) # Lies on the ed25519 curve and is suitable for users
off_curve_address = Pubkey.from_string('4BJXYkfvg37zEmBbsacZjeQDpTNx91KppxFJxRqrz48e') # Valid public key
print(off_curve_address.is_on_curve()) # Not on the ed25519 curve, therefore not suitable for users
error_pubkey = Pubkey.from_string("testPubkey"); # Is not a valid public key
key = Pubkey.from_string('5oNDL3swdJJF1g9DzJiZ4ynHXgszjAEpUkxVYejchzrY')
print(key.is_on_curve())
#include <iostream>
#include <solana_sdk.h>
int main()
{
auto public_key = PublicKey("5oNDL3swdJJF1g9DzJiZ4ynHXgszjAEpUkxVYejchzrY");
std::cout << public_key.is_on_curve() << std::endl;
return 0;
}
auto public_key = PublicKey("5oNDL3swdJJF1g9DzJiZ4ynHXgszjAEpUkxVYejchzrY");
std::cout << public_key.is_on_curve() << std::endl;
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())
Como gerar uma frase mnemônica
Se você estiver criando uma carteira, precisará gerar uma frase mnemônica para que o usuário possa salvá-la como backup.
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
Como restaurar um Par de Chaves a partir de uma frase mnemônica
Muitas extensões de carteira usam mnemônicos para representar suas chaves secretas. Você pode converter o mnemônico em Pares de Chaves para testes locais.
- BIP39 - criando uma única carteira
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 solders.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_bytes(seed)
print("Created Keypair with Public Key: {}".format(keypair.pubkey()))
mnemo = Mnemonic("english")
seed = mnemo.to_seed("pill tomorrow foster begin walnut borrow virtual kick shift mutual shoe scatter")
keypair = Keypair.from_bytes(seed)
solana-keygen recover
solana-keygen recover
- BIP44 (múltiplas carteiras, também conhecidas como carteiras HD)
Você pode criar várias carteiras a partir de uma única semente - também conhecidas como "carteiras determinísticas hierárquicas" ou carteiras HD:
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'
Como gerar um endereço personalizado
As chaves públicas personalizadas, ou endereços personalizados (vanity addresses), são chaves que começam com caracteres específicos. Por exemplo, uma pessoa pode querer uma chave pública que comece com "elv1s", ou talvez até "cook". Isso pode ajudar outras pessoas a lembrar a quem a chave pertence, tornando a chave mais facilmente identificável.
Observação: quanto mais caracteres tiver o endereço personalizado, mais tempo levará.
Aviso
Você deve usar apenas a CLI para essa tarefa. Os exemplos em Python e TypeScript são apenas para fins ilustrativos e são muito mais lentos do que a 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 solders.keypair import Keypair
keypair = Keypair()
while(str(keypair.pubkey())[:5]!="elv1s") :
keypair = Keypair()
print("Created Keypair with Public Key: {}".format(keypair.pubkey()))
keypair = Keypair()
while(str(keypair.pubkey())[:5]!="elv1s") :
keypair = Keypair()
// clang++ vanity_keypair.cpp -o vanity_keypair -std=c++17 -lssl -lcrypto -lsodium
#include "solana.hpp"
using namespace many::solana;
int main() {
auto key_pair = Keypair::generate();
while (key_pair.public_key.to_base58().substr(0, 5) != "elv1s") {
key_pair = Keypair::generate();
}
std::cout << "Created Keypair with Public Key: " << key_pair.public_key.to_base58() << std::endl;
}
auto key_pair = Keypair::generate();
while (key_pair.public_key.to_base58().substr(0, 5) != "elv1s") {
key_pair = Keypair::generate();
}
solana-keygen grind --starts-with e1v1s:1
solana-keygen grind --starts-with e1v1s:1
Como assinar e verificar mensagens com carteiras
A função principal de um par de chaves é assinar mensagens e permitir a verificação da assinatura. A verificação de uma assinatura permite que o destinatário tenha certeza de que os dados foram assinados pelo proprietário de uma chave privada específica.
Para fazer isso, importaremos a biblioteca criptográfica TweetNaCl.
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 solders.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_bytes(secret_key)
message = b"The quick brown fox jumps over the lazy dog"
signature = keypair.sign_message(message)
verify_sign = signature.verify(keypair.pubkey(), message)
print(verify_sign) # bool
message = b"The quick brown fox jumps over the lazy dog"
signature = keypair.sign_message(message)
verify_sign = signature.verify(keypair.pubkey(), message)
print(verify_sign) # bool
Como se conectar a uma carteira
As bibliotecas wallet-adapter da Solana facilitam a gestão de conexões de carteira no lado do cliente.
React
Execute o seguinte comando para instalar as dependências necessárias:
yarn add @solana/wallet-adapter-react @solana/wallet-adapter-react-ui @solana/wallet-adapter-base @solana/wallet-adapter-wallets
As bibliotecas wallet-adapter do React nos permitem persistir e acessar estados de conexão de carteira por meio de ganchos (hooks) e provedores de contexto, nomeadamente useWallet
, WalletProvider
, useConnection
e ConnectionProvider
. O aplicativo React deve ser envolvido com WalletProvider
e ConnectionProvider
.
Além disso, podemos solicitar que os usuários se conectem usando useWalletModal
para alternar a visibilidade do modal de conexão e envolvendo o aplicativo com WalletModalProvider
de @solana/wallet-adapter-react-ui
. O modal de conexão lidará com o fluxo de conexão para nós, então só precisamos ouvir quando uma carteira estiver conectada. Sabemos que uma carteira está conectada quando a resposta useWallet
tem uma propriedade wallet
não nula. Vice-versa, se essa propriedade for nula, sabemos que a carteira está desconectada.
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
Execute o seguinte comando para instalar as dependências necessárias:
npm install solana-wallets-vue @solana/wallet-adapter-wallets
O plugin de integração Solana Wallets - Vue nos permite inicializar uma loja de carteiras e criar uma nova propriedade global $wallet
que pode ser acessada dentro de qualquer componente. Todas as propriedades e métodos que podem ser obtidos a partir de useWallet()
são exibidos aqui. Também importamos e renderizamos o componente WalletMultiButton para permitir que os usuários selecionem uma carteira e se conectem a ela.
<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
Execute o seguinte comando para instalar as dependências necessárias:
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
O pacote Svelte Wallet Adapter permite adicionar uma Loja Svelte ($walletStore
) acessível em todos os arquivos JS, TS ou Svelte dentro de um projeto feito com Svelte Template ou SvelteKit. Usando a referência do repositório aqui, você pode usar o adaptador para SSR ou SPA. O pacote da interface do usuário contém um componente <WalletMultiButton />
para permitir que os usuários selecionem uma carteira para se conectar a ela.
<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}