Wap 1.1.0
dotnet add package Wap --version 1.1.0
NuGet\Install-Package Wap -Version 1.1.0
<PackageReference Include="Wap" Version="1.1.0" />
<PackageVersion Include="Wap" Version="1.1.0" />
<PackageReference Include="Wap" />
paket add Wap --version 1.1.0
#r "nuget: Wap, 1.1.0"
#:package Wap@1.1.0
#addin nuget:?package=Wap&version=1.1.0
#tool nuget:?package=Wap&version=1.1.0
<p align="center"> <img src="core/public/logo.svg" alt="Wap" width="200" /> </p>
<h1 align="center">Wap</h1>
<p align="center">WhatsApp Web API client library for .NET.</p>
Connects directly to WhatsApp Web via WebSocket, implementing the full protocol stack: Noise handshake, Signal Protocol (Double Ratchet + Sender Key), binary XML encoding, and end-to-end encrypted messaging.
Disclaimer: This project is not affiliated with WhatsApp or Meta. Using this library may violate WhatsApp's Terms of Service. Use at your own risk.
Features
- Full Noise_XX handshake with certificate validation
- Signal Protocol (X3DH, Double Ratchet, Sender Key for groups)
- QR Code and Pairing Code authentication
- Send/receive text, image, video, audio, document, sticker, contact, location, reaction
- End-to-end encrypted media upload/download
- Group management (create, invite, promote, demote, settings)
- Chat operations (typing, presence, archive, pin, mute, block)
- Newsletters and Communities
- Business profile and catalog
- App State Sync (contacts, chat actions, push names)
- History sync
- Auto-reconnect with exponential backoff
- Link preview generation
- Pre-key rotation
- Identity change detection
- File-based session persistence
Requirements
- .NET 8.0+
- NuGet packages:
Google.Protobuf,Grpc.Tools,Sodium.Core,QRCoder
Installation
git clone https://github.com/seu-usuario/wap.git
cd wap
dotnet restore
dotnet build
Quick Start
using Wap;
using Wap.Types;
var client = await WapClient.CreateAsync(authFolder: "./auth_session");
client.OnConnectionUpdate(update =>
{
Console.WriteLine($"Connection: {update.Connection}");
});
client.OnMessage(msg =>
{
Console.WriteLine($"{msg.Sender}: {msg.TextContent}");
});
await client.ConnectAsync();
var jid = Jid.Parse("5511999999999@s.whatsapp.net");
await client.SendTextAsync(jid, "Hello from Wap!");
Sending Messages
// Text
await client.SendTextAsync(jid, "Hello!");
// Reaction
await client.SendReactionAsync(jid, messageId, "\ud83d\udc4d");
// Location
await client.SendLocationAsync(jid, -23.55, -46.63, "São Paulo");
// Contact
await client.SendContactAsync(jid, "John", "BEGIN:VCARD\nVERSION:3.0\nFN:John\nEND:VCARD");
Sending Media
// Image
var imgBytes = await File.ReadAllBytesAsync("photo.jpg");
await client.SendImageAsync(jid, imgBytes, "check this out");
// Video
var vidBytes = await File.ReadAllBytesAsync("clip.mp4");
await client.SendVideoAsync(jid, vidBytes);
// Audio (voice note)
var audioBytes = await File.ReadAllBytesAsync("voice.ogg");
await client.SendAudioAsync(jid, audioBytes, ptt: true);
// Document
var docBytes = await File.ReadAllBytesAsync("report.pdf");
await client.SendDocumentAsync(jid, docBytes, "report.pdf");
// Sticker
var stickerBytes = await File.ReadAllBytesAsync("sticker.webp");
await client.SendStickerAsync(jid, stickerBytes);
Downloading Media
client.OnMessage(async msg =>
{
if (msg.Message.ImageMessage != null)
{
var bytes = await client.DownloadImageAsync(msg.Message.ImageMessage);
await File.WriteAllBytesAsync("received.jpg", bytes);
}
});
Groups
// Create
var group = await client.Groups.CreateGroupAsync("My Group", [jid1, jid2]);
// Metadata
var meta = await client.Groups.GetGroupMetadataAsync(groupJid);
// Participants
await client.Groups.AddParticipantsAsync(groupJid, [newMember]);
await client.Groups.PromoteParticipantsAsync(groupJid, [admin]);
await client.Groups.RemoveParticipantsAsync(groupJid, [member]);
// Settings
await client.Groups.UpdateGroupSubjectAsync(groupJid, "New Name");
await client.Groups.UpdateGroupDescriptionAsync(groupJid, "New description");
await client.Groups.UpdateGroupSettingsAsync(groupJid, GroupSetting.Announcement, true);
// Invite
var code = await client.Groups.GetInviteCodeAsync(groupJid);
await client.Groups.JoinGroupViaInviteAsync(code);
Chat Operations
await client.Chats.SendTyping(jid);
await client.Chats.SendRecordingPresence(jid);
await client.Chats.ArchiveChat(jid);
await client.Chats.PinChat(jid);
await client.Chats.MuteChat(jid);
await client.Chats.BlockUserAsync(jid);
await client.Chats.UpdateProfileStatusAsync("Busy");
await client.Chats.UpdateProfileNameAsync("My Name");
var blocked = await client.Chats.GetBlockListAsync();
var status = await client.Chats.GetStatusAsync(jid);
Newsletters & Communities
// Newsletters
var newsletter = await client.Channels.CreateNewsletterAsync("My Channel", "Description");
var subscribed = await client.Channels.GetSubscribedNewslettersAsync();
var results = await client.Channels.SearchNewslettersAsync("tech");
await client.Channels.SubscribeNewsletterAsync(newsletterJid);
// Communities
var community = await client.Channels.CreateCommunityAsync("My Community");
var groups = await client.Channels.GetCommunityGroupsAsync(communityJid);
await client.Channels.LinkGroupToCommunityAsync(communityJid, groupJid);
Events
client.OnConnectionUpdate(update => { });
client.OnMessage(msg => { });
client.OnReceipt(node => { });
client.OnDecryptionError((msgId, ex) => { });
client.OnHistorySync(data => { });
client.OnIdentityChanged(evt => { });
Project Structure
core/
├── Auth/ QR Code and Pairing Code authentication
├── Crypto/ Curve25519, AES, HMAC, HKDF, Noise Protocol
├── Proto/ Protobuf definitions (handshake, messages, device identity)
├── Signal/ Signal Protocol (Double Ratchet, X3DH, Sender Key, PreKey management)
├── Socket/ WebSocket, message layers, media, groups, chats, channels, business
├── Store/ File-based credential and key persistence
├── Sync/ App State Sync (LTHash, mutations, patches)
├── Types/ Core types (JID, events, config, binary nodes)
├── WABinary/ WhatsApp binary XML encoder/decoder
└── WapClient.cs Main entry point
How It Works
- Opens a WebSocket to WhatsApp Web
- Performs Noise_XX handshake (Curve25519 ECDH + AES-256-GCM)
- Authenticates via QR Code or Pairing Code
- All frames encrypted with AES-256-GCM over Noise transport
- Messages encoded in WhatsApp's proprietary binary XML format
- Payloads serialized as Protocol Buffers
- End-to-end encryption via Signal Protocol (per-device Double Ratchet for 1:1, Sender Key for groups)
Contributing
Pull requests are welcome. For major changes, open an issue first.
License
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Google.Protobuf (>= 3.28.3)
- QRCoder (>= 1.6.0)
- Sodium.Core (>= 1.4.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.