Global Rank · of 601 Skills
wallet-encrypt-decrypt AI Agent Skill
View Source: b-open-io/bsv-skills
SafeInstallation
npx skills add b-open-io/bsv-skills --skill wallet-encrypt-decrypt 22
Installs
BSV Message Encryption
Encrypt and decrypt messages between parties using @bsv/sdk.
Recommended: Use EncryptedMessage from @bsv/sdk
The @bsv/sdk provides EncryptedMessage for secure message encryption. This is the preferred approach - avoid rolling custom encryption implementations.
import { PrivateKey, EncryptedMessage, Utils } from '@bsv/sdk'
const sender = PrivateKey.fromRandom()
const recipient = PrivateKey.fromRandom()
// Encrypt: sender uses their private key + recipient's public key
const message = Utils.toArray('Secret message', 'utf8')
const encrypted = EncryptedMessage.encrypt(message, sender, recipient.toPublicKey())
// Decrypt: recipient uses their private key
const decrypted = EncryptedMessage.decrypt(encrypted, recipient)
const plaintext = Utils.toUTF8(decrypted)Two Encryption Patterns
Pattern 1: Static-Static ECDH (Both Parties Have Keys)
Use when both parties have established keypairs (e.g., BAP identities, paymail addresses).
import { PrivateKey, EncryptedMessage, Utils } from '@bsv/sdk'
// Alice and Bob both have persistent keys
const alice = PrivateKey.fromWif('L1...')
const bob = PrivateKey.fromWif('K1...')
// Alice encrypts to Bob
const ciphertext = EncryptedMessage.encrypt(
Utils.toArray('Hello Bob', 'utf8'),
alice,
bob.toPublicKey()
)
// Bob decrypts from Alice
const plaintext = EncryptedMessage.decrypt(ciphertext, bob)Use cases:
- Peer-to-peer encrypted messaging
- Encrypted backups to your own key
- Communication between known identities
Pattern 2: ECIES-Style (Ephemeral Sender Key)
Use when sender doesn't have a persistent identity (e.g., browser-to-server).
import { PrivateKey, EncryptedMessage, Utils } from '@bsv/sdk'
// Server has persistent key, client generates ephemeral
const serverKey = PrivateKey.fromWif('L1...')
const ephemeralClient = PrivateKey.fromRandom()
// Client encrypts (ephemeral → server)
const encrypted = EncryptedMessage.encrypt(
Utils.toArray('sensitive data', 'utf8'),
ephemeralClient,
serverKey.toPublicKey()
)
// Include ephemeral public key so server can decrypt
const payload = {
ephemeralPub: ephemeralClient.toPublicKey().toString(),
ciphertext: Utils.toHex(encrypted)
}
// Server decrypts using ephemeral pubkey
const clientPub = PublicKey.fromString(payload.ephemeralPub)
// Note: EncryptedMessage.decrypt needs the sender info embedded in ciphertextUse cases:
- Browser-to-server encryption
- One-way secure channels
- Forward secrecy (fresh key per message)
How ECDH Key Agreement Works
Both parties derive the same shared secret:
Alice: alicePrivKey × bobPubKey = sharedPoint
Bob: bobPrivKey × alicePubKey = sharedPointThe shared point is then used to derive a symmetric key for AES-256-GCM encryption.
API Reference
EncryptedMessage.encrypt()
static encrypt(
message: number[], // Plaintext as byte array
sender: PrivateKey, // Sender's private key
recipient: PublicKey // Recipient's public key
): number[] // Encrypted bytesEncryptedMessage.decrypt()
static decrypt(
ciphertext: number[], // Encrypted bytes from encrypt()
recipient: PrivateKey // Recipient's private key
): number[] // Decrypted plaintext bytesUtility Functions
// String to bytes
Utils.toArray('hello', 'utf8') // number[]
// Bytes to string
Utils.toUTF8([104, 101, 108, 108, 111]) // 'hello'
// Bytes to hex
Utils.toHex([1, 2, 3]) // '010203'
// Hex to bytes
Utils.toArray('010203', 'hex') // [1, 2, 3]Security Properties
- Authenticated encryption: AES-256-GCM provides confidentiality + integrity
- Key agreement: ECDH ensures only intended recipient can decrypt
- No key transmission: Private keys never leave their owner
Common Mistakes
Don't roll your own crypto
❌ Wrong: Implementing ECDH + AES manually
// Don't do this - use EncryptedMessage instead
const sharedSecret = myPrivKey.deriveSharedSecret(theirPubKey)
const aesKey = sha256(sharedSecret)
// ... manual AES encryption✅ Correct: Use the SDK's built-in class
const encrypted = EncryptedMessage.encrypt(message, sender, recipient)Don't confuse encryption with authentication
- Encryption (this skill): Hides message content
- Authentication (
bitcoin-auth): Proves sender identity
For authenticated + encrypted communication, use both:
// Encrypt the payload
const encrypted = EncryptedMessage.encrypt(payload, sender, recipient)
// Sign the request (proves sender identity)
const authToken = getAuthToken({ privateKeyWif, requestPath, body })Installs
Security Audit
View Source
b-open-io/bsv-skills
More from this source
Power your AI Agents with
the best open-source models.
Drop-in OpenAI-compatible API. No data leaves Europe.
Explore Inference APIGLM
GLM 5
$1.00 / $3.20
per M tokens
Kimi
Kimi K2.5
$0.60 / $2.80
per M tokens
MiniMax
MiniMax M2.5
$0.30 / $1.20
per M tokens
Qwen
Qwen3.5 122B
$0.40 / $3.00
per M tokens
How to use this skill
Install wallet-encrypt-decrypt by running npx skills add b-open-io/bsv-skills --skill wallet-encrypt-decrypt in your project directory. Run the install command above in your project directory. The skill file will be downloaded from GitHub and placed in your project.
No configuration needed. Your AI agent (Claude Code, Cursor, Windsurf, etc.) automatically detects installed skills and uses them as context when generating code.
The skill enhances your agent's understanding of wallet-encrypt-decrypt, helping it follow established patterns, avoid common mistakes, and produce production-ready output.
What you get
Skills are plain-text instruction files — not executable code. They encode expert knowledge about frameworks, languages, or tools that your AI agent reads to improve its output. This means zero runtime overhead, no dependency conflicts, and full transparency: you can read and review every instruction before installing.
Compatibility
This skill works with any AI coding agent that supports the skills.sh format, including Claude Code (Anthropic), Cursor, Windsurf, Cline, Aider, and other tools that read project-level context files. Skills are framework-agnostic at the transport level — the content inside determines which language or framework it applies to.
Chat with 100+ AI Models in one App.
Use Claude, ChatGPT, Gemini alongside with EU-Hosted Models like Deepseek, GLM-5, Kimi K2.5 and many more.