# P2P Connection Guide

This guide explains how to establish peer-to-peer connections using the Wish SDK.

## Overview

Unlike client-server applications, P2P networking requires:
1. At least two running instances
2. Identity creation on each instance
3. Peer discovery (via directory service or local network)
4. Friend request exchange
5. Connection establishment

Only after these steps can peers exchange messages.

## Basic Setup

### Start Wish Core

Each peer needs its own wish-core instance on a different port:

```js
const { WishCoreRunner, App } = require('@wishcore/wish-sdk');

// Peer 1
await WishCoreRunner.start({ appPort: 9094 });
const app1 = new App({ name: 'Alice', corePort: 9094, protocols: ['chat'] });

// Peer 2 (in separate process)
await WishCoreRunner.start({ appPort: 9095 });
const app2 = new App({ name: 'Bob', corePort: 9095, protocols: ['chat'] });
```

### Create Identities

Each peer needs a cryptographic identity:

```js
// On Alice's app
const aliceIdentity = await app1.request('identity.create', ['Alice']);

// On Bob's app
const bobIdentity = await app2.request('identity.create', ['Bob']);
```

## Peer Discovery

### Option 1: Directory Service (WLD)

Peers can discover each other via a centralized directory service:

```js
// Bob publishes to directory
await app2.request('wld.publish', [bobIdentity.uid, { alias: 'Bob' }]);

// Alice discovers Bob
const peers = await app1.request('wld.list', []);
const bob = peers.find(p => p.alias === 'Bob');
```

### Option 2: Local Discovery

Peers on the same network can discover each other automatically via UDP broadcast. This is enabled by default in wish-core.

## Friend Request Flow

After discovering a peer, you must establish a friend connection:

### 1. Send Friend Request

```js
// Alice sends request to Bob
await app1.request('wld.friendRequest', [
  aliceIdentity.uid,  // Local identity
  bob.ruid,           // Remote identity
  bob.rhid            // Remote host ID
]);
```

### 2. List Incoming Requests

```js
// Bob checks for friend requests
const requests = await app2.request('identity.friendRequestList', [bobIdentity.uid]);
const aliceRequest = requests.find(r => r.alias === 'Alice');
```

### 3. Accept Friend Request

```js
// Bob accepts Alice's request
await app2.request('identity.friendRequestAccept', [
  aliceRequest.luid,  // Bob's local identity
  aliceRequest.ruid   // Alice's remote identity
]);
```

## Connection Events

Once the friend request is accepted, peers will connect and trigger events:

```js
// Listen for peer coming online
app1.on('online', async (peer) => {
  const identity = await app1.request('identity.get', [peer.ruid]);
  console.log(`${identity.alias} is online!`);

  // Now you can send messages
  await app1.request('services.send', [peer, Buffer.from('Hello!')]);
});

// Listen for messages
app1.on('frame', async (peer, data) => {
  const identity = await app1.request('identity.get', [peer.ruid]);
  console.log(`${identity.alias}: ${data.toString()}`);
});
```

## Protocol Filtering

The `protocols` parameter filters which peers you connect to:

```js
const app = new App({
  protocols: ['chat']  // Only connects to peers with 'chat' protocol
});
```

Peers with different protocols won't trigger `online` events, even if they're friends.

## Complete Example

See [examples/chat.js](examples/chat.js) for a fully working interactive chat application.

**To test the chat:**

```bash
# Terminal 1 - Alice
node examples/chat.js Alice 9094

# Terminal 2 - Bob
node examples/chat.js Bob 9095
```

Note: The chat example assumes peers have already been set up (identities created, friend requests exchanged). For testing with fresh instances, you'll need to perform the discovery and friend request steps first.

## Common Issues

**Peers not discovering each other:**
- Ensure both instances are running
- Check firewall settings for UDP broadcast (local discovery)
- Verify directory service connectivity (if using WLD)

**Friend request not received:**
- Check the friend request was sent to correct ruid/rhid
- Verify both peers have created identities
- List friend requests to confirm it arrived

**Peer not coming online:**
- Ensure friend request was accepted on both sides
- Check that protocols match between peers
- Verify wish-core instances can reach each other on the network

## API Reference

### Identity Management
- `identity.create(alias)` - Create new identity
- `identity.list()` - List local identities
- `identity.get(uid)` - Get identity details
- `identity.friendRequestAccept(luid, ruid)` - Accept friend request
- `identity.friendRequestList(uid)` - List pending requests

### Directory Service (WLD)
- `wld.publish(uid, data)` - Publish to directory
- `wld.list()` - List peers in directory
- `wld.friendRequest(luid, ruid, rhid)` - Send friend request

### Messaging
- `services.send(peer, buffer)` - Send data to peer

### Events
- `ready` - Connected to wish-core
- `online(peer)` - Peer came online (after friend request accepted)
- `offline(peer)` - Peer went offline
- `frame(peer, data)` - Received data from peer
