peering.ts 5.08 KB
Newer Older
John Doe's avatar
John Doe committed
1 2 3
// @ts-ignore
import * as types from './types';
import { TransactionBuilder } from "./transactionBuilder";
John Doe's avatar
🟣  
John Doe committed
4 5
// import { createLibp2p } from 'libp2p'
// import * as filters from '@libp2p/websockets/filters'
John Doe's avatar
John Doe committed
6 7
import { finalizeEvent, verifyEvent, setNostrWasm, VerifiedEvent, Event } from 'nostr-tools/wasm'
import { SimplePool } from 'nostr-tools/pool'
John Doe's avatar
🟣  
John Doe committed
8 9 10 11 12 13
// import { gossipsub } from '@chainsafe/libp2p-gossipsub'
// import { noise } from '@chainsafe/libp2p-noise'
// import { yamux } from '@chainsafe/libp2p-yamux'
// import { mplex } from '@libp2p/mplex'
// import { identify } from "@libp2p/identify"
// import { dcutr } from "@libp2p/dcutr"
John Doe's avatar
John Doe committed
14 15
import { getPublicKey } from 'nostr-tools/pure';
import { initNostrWasm } from 'nostr-wasm'
John Doe's avatar
🟣  
John Doe committed
16
// import { multiaddr } from '@multiformats/multiaddr'
John Doe's avatar
John Doe committed
17 18
import { useWebSocketImplementation } from 'nostr-tools/pool'
import WebSocket from 'ws'
John Doe's avatar
🟣  
John Doe committed
19
import { Block } from 'ethers';
John Doe's avatar
John Doe committed
20 21 22 23 24 25

if (typeof global === "object") useWebSocketImplementation(WebSocket);


export class Peering extends TransactionBuilder {

John Doe's avatar
🟣  
John Doe committed
26 27
    // p2p: any | undefined; 
    pool: SimplePool = new SimplePool();
John Doe's avatar
John Doe committed
28 29 30
    relays: string[];
    seeds: string[];
    rebroadcast: any | undefined;
John Doe's avatar
🟣  
John Doe committed
31
    // callback: Function;
John Doe's avatar
John Doe committed
32 33 34

    constructor(_config: types.GlobalConfig) {
        super(_config);
John Doe's avatar
🟣  
John Doe committed
35
        // if (!this.config.gossip) throw new Error("Gossip config not found");
John Doe's avatar
John Doe committed
36 37 38
        this.pool = new SimplePool();
        this.relays = this.config.gossip!.relays;
        this.seeds = this.config.gossip!.seeds;
John Doe's avatar
🟣  
John Doe committed
39
        // this.callback = () => true;
John Doe's avatar
John Doe committed
40 41
    }

John Doe's avatar
🟣  
John Doe committed
42
    postEvent = async (_sk: Uint8Array, _timestamp: number, ips: string) => Promise.any(this.pool.publish(this.relays, finalizeEvent({
John Doe's avatar
John Doe committed
43 44 45
        kind: 1,
        created_at: _timestamp,
        tags: [],
John Doe's avatar
🟣  
John Doe committed
46
        content: ips
John Doe's avatar
John Doe committed
47 48
    }, _sk)))

John Doe's avatar
🟣  
John Doe committed
49 50 51 52 53 54 55 56 57 58 59 60
    // postTransaction = async (_tx: types.Transaction) => {
    //     const hexString = (await this.contracts.state.getAddress()).slice(2).padStart(64, '0');
    //     const matches = hexString.match(/.{1,2}/g);
    //     const skUint8Array = matches ? new Uint8Array(matches.map(byte => parseInt(byte, 16))) : new Uint8Array();
    //     const _pk: string = getPublicKey(skUint8Array);

    //     if (this.p2p.services.pubsub.getSubscribers(_pk).length > 0) {
    //         await this.p2p.services.pubsub.publish(_pk, new TextEncoder().encode(JSON.stringify(_tx)))
    //     } else {
    //         setTimeout(async () => await this.postTransaction(_tx), 10_000);
    //     }
    // };
John Doe's avatar
John Doe committed
61 62
    initializePeering = async (callback?: Function): Promise<void> => {
        await this.initializeTransactionBuilder();
John Doe's avatar
🟣  
John Doe committed
63
        const hexString = "6835ccbeddc1c1c91fed2116099592a309f98d0df34d8dc72e770df83cc3b065".padStart(64, '0');
John Doe's avatar
John Doe committed
64
        const matches = hexString.match(/.{1,2}/g);
John Doe's avatar
🟣  
John Doe committed
65
        const skUint8Array = matches ? new Uint8Array(matches.map(byte => parseInt(byte, 16))) : new Uint8Array()
John Doe's avatar
John Doe committed
66 67 68 69
        let _pk = getPublicKey(skUint8Array);
        await this.fetchRelays();
        await initNostrWasm().then(setNostrWasm);
        const latestBlock = await this.config.provider.getBlock("latest");
John Doe's avatar
🟣  
John Doe committed
70 71 72 73 74 75 76
        let ip: string
        if (this.config.ip == "") {
            let ips: string[] = []
            let ipServices = ["https://api.ipify.org", "https://icanhazip.com", "https://ifconfig.me/ip", "https://checkip.amazonaws.com/"]
            for (let i = 0; i < ipServices.length; i++) {
                let res = await fetch(ipServices[i])
                ips.push((await res.text()).trim())
John Doe's avatar
John Doe committed
77
            }
John Doe's avatar
🟣  
John Doe committed
78 79 80 81 82 83 84 85
            let last = ips[0]
            for (let i = 0; i < ips.length; i++) {
                if (last === ips[i]) {
                    last = ips[i]
                } else {
                    console.log("Please set your public ip in the config file")
                    return
                }
John Doe's avatar
John Doe committed
86
            }
John Doe's avatar
🟣  
John Doe committed
87 88 89
            ip = last
        }else {
            ip = this.config.ip as string
John Doe's avatar
John Doe committed
90 91
        }
        if (typeof global === 'object') {
John Doe's avatar
🟣  
John Doe committed
92 93 94
            this.rebroadcast = setInterval(async () => {
                await this.postEvent(skUint8Array, latestBlock!.timestamp, ip)
            }, 60 * 60 * 1000);
John Doe's avatar
John Doe committed
95

John Doe's avatar
🟣  
John Doe committed
96
            await this.postEvent(skUint8Array, latestBlock!.timestamp, ip);
John Doe's avatar
John Doe committed
97 98 99 100
        }

    }

John Doe's avatar
🟣  
John Doe committed
101 102 103 104 105 106 107 108 109
    queryEvents = async (latestBlock: number) => {
        const hexString = "6835ccbeddc1c1c91fed2116099592a309f98d0df34d8dc72e770df83cc3b065".padStart(64, '0');
        const matches = hexString.match(/.{1,2}/g);
        const skUint8Array = matches ? new Uint8Array(matches.map(byte => parseInt(byte, 16))) : new Uint8Array()
        let _pk = getPublicKey(skUint8Array);
        let event = await this.pool.querySync(this.relays, {
            kinds: [1],
            authors: [_pk],
            since: latestBlock - (typeof global === 'object' ? 0 : 86400)
John Doe's avatar
John Doe committed
110

John Doe's avatar
🟣  
John Doe committed
111 112
        })
    }
John Doe's avatar
John Doe committed
113 114 115 116 117 118 119 120 121 122 123 124
    fetchRelays = async (refresh: boolean = false): Promise<string[]> => {
        if (this.seeds.length == 0 || refresh) return this.relays;
        for (const seed of this.seeds) {
            const relaysFromSeed: string[] = (await (await fetch(seed)).json()) as string[];
            this.relays = this.relays.concat(relaysFromSeed);
        }
        return this.relays;
    }
}

/* eslint-disable no-console */