Skip to content

ArcLib: Typescript SDK for Arcade

earonesty edited this page May 9, 2023 · 1 revision

ArcLib, for now, is an unpublished module. Working with it involves

  • include as a submodule
  • require/import from the arclib subfolder

Proposed SDK for Nostr:

Identity

Todo: seamlessly switching between multiple active identities for the purposes of posting

from 'arclib' import {ArcadeIdentity}

ident = new ArcadeIdentity({nsec string, bitcoinAddress string, lnUrl string})

Relay Pool API

Maintains a pool of active connections, allows the user to send messages

from 'arclib' import {NostrRelayPool}

pool = new NostrRelayPool(ident)
pool.setRelays({in: [list of urls], out: [list of urls]})
pool.addRequiredNips([list of nips that are checked and used to filter out relays that don't comply])
pool.startConnect()
pool.getStatus(): 
   returns a list of {
	status: "connected|connecting|unsupported|timed-out",
        sent: num
        received: num
   }
pool.send(message)


// called for every event received
pool.eventCallback(callbackForEvents)

Channel API

from arclib import {N28Channel}

channel = new N28Channel(relayPoolInstance)
channel.setStore(sqliteStore) // sync with storage object
channel.create(name, about, picture) // create a channel, throw an error if it exists

// called only for unique deduplicated KIND 42 events received
channel.eventCallback(func)
channel.setMeta({name, about picture})
channel.getMeta()
channel.send({content, replyTo})
channel.muteUser({content, pubkey})
channel.join(name, {tag filter for events})  // join a channel *by name*, this will REQ events matching the channel

Trade API

type TradeCommand = {
  action: 'BUY' | 'SELL' | 'buy' | 'sell';
  minAmount?: number;
  maxAmount: number;
  currency: string;
  price: number;
  paymentTags: string;
  escrowAgentIds?: Array<string>;
  expirationDays?: number;
  additionalData?: Record<string, number | string>;
};
from arclib import {OrderBook}

// "joins" a passed-in channel, sets filter tags, loads from storage, and receives events, building up the book
// throws an error if the channel has already been "joined"
book = new OrderBook(channelInstance)

tradeEventId = book.postTrade(TradeCommand)
book.listTrades({showExpired: false})  // list of active trades the book knows about
      [{sender,  tradeEventId, trade: TradeCommand}...]
book.cancelTrade(tradeEventId)

// sends a DM to the trader with your selected payment method, price, selected escrowAgent, amount and digital payment information
offerId = book.startOffer(tradeEventId, content: string, terms: OfferTerms) 

// prior offers are implicitly "deleted" when a new offer is sent on the same trade for the same id
// we don't want to use replaceable events here we want it to show up as a "chat"
// we can just sent a DELETE for the old ones, and hope for the best

book.listOffers()  // list of private structured trading offers received
      [{sender, tradeEventId, offerEventId, content: string, terms: OfferTerms }, ... ]

// trader does this when he gets and offer he likes
// should throw an exception if the offerId is NOT a recent/active offer or if the offerId has been deleted
// this sends a copy of the order details to the escrow agent
book.acceptOffer(offerId) // "ok i accept, let's start wiring money"

// hodlInvoice used for lighting payments, multisig used for bitcoin payments
// this gets info about the offer and the counterparty
// QR codes and info for lightning payments
// QR codes and info for lighting escrow (hodlInvoice)
// bitcoin payment address with an appropriate p2SH escrow associated with it
// todo: this function is complex, and can return a rich object that has a lot of information, wire transfer info, etc.
book.generatePaymentDetails(offerId)

book.withdrawOffer(offerId) // "changed my mind"

// both parties should do this.   

// when sending bitcoin using the ArcTrade UX we can auto-finalize
// when sending lightning using the ArcTrade lightning node, we can auto-finalize
// if the party has a linked bank account, and we see the wire with a tradeId, we can auto-finalize

book.finalizeOffer(offerId, content) // "ok i sent the money from my end"

// if an agent is associated with the offer, the agent is CC'ed on finalize calls
book.escrowAccepted(offerId, content) // "ok i got the money, i'm releasing the bitcoin from the 2 of 2"
book.escrowRejected(offerId, content) // "money never arrived, i'm cancelling the trade, and releasing bitcoin back to the sender"


Clone this wiki locally