ecash-agora
Version:
Library for interacting with the eCash Agora protocol
239 lines • 8.9 kB
TypeScript
import { ChronikClient, Token, WsEndpoint } from 'chronik-client';
import { Op, OutPoint, Script, Tx, TxBuilderInput, TxInput } from 'ecash-lib';
import { AgoraOneshot } from './oneshot.js';
import { AgoraPartial, AgoraPartialParams } from './partial.js';
/** Offer variant, determines the Script used to enforce the offer */
export type AgoraOfferVariant = {
type: 'ONESHOT';
params: AgoraOneshot;
} | {
type: 'PARTIAL';
params: AgoraPartial;
};
/** Status of the offer, i.e. if it open/taken/canceled */
export type AgoraOfferStatus = 'OPEN' | 'TAKEN' | 'CANCELED';
/** If an offer is TAKEN */
export interface TakenInfo {
/** satoshis paid in taking an offer */
sats: bigint;
/**
* amount of token purchased in atoms aka base tokens
*/
atoms: bigint;
/** taker outputScript as a hex string*/
takerScriptHex: string;
}
/**
* Individual token offer on the Agora, i.e. one UTXO offering tokens.
*
* It can be used to accept or cancel the offer.
*/
export declare class AgoraOffer {
variant: AgoraOfferVariant;
outpoint: OutPoint;
txBuilderInput: TxInput;
token: Token;
status: AgoraOfferStatus;
takenInfo?: TakenInfo;
constructor(params: {
variant: AgoraOfferVariant;
outpoint: OutPoint;
txBuilderInput: TxInput;
token: Token;
status: AgoraOfferStatus;
takenInfo?: TakenInfo;
});
/**
* Build a tx accepting this offer.
*
* Agora offers are UTXOs on the blockchain that can be accepted by anyone
* sending sufficient satoshis to a required output.
*
* `fuelInputs` has to provide enough sats for this offer to cover ask + tx fee.
* */
acceptTx(params: {
/**
* Arbitrary secret key to sign the accept tx with. Recommended to set
* this to a random key. Must be paired with covenantSk.
**/
covenantSk: Uint8Array;
/**
* Arbitrary public key to sign the accept tx with, must be paired with
* covenantSk.
**/
covenantPk: Uint8Array;
/**
* Inputs fueling this tx to cover tx fee and asked sats for the
* enforced outputs. Must have signatory and input.signData set
* correctly. If it is set incorrectly, may fail silently and build an
* invalid tx, failing at broadcast.
*
* The free sats of these inputs must be at least askedSats + acceptFeeSats.
**/
fuelInputs: TxBuilderInput[];
/** Script to send the tokens and the leftover sats (if any) to. */
recipientScript: Script;
/** For partial offers: Number of accepted atoms (base tokens) */
acceptedAtoms?: bigint;
/** Dust amount to use for the token output. */
dustSats?: bigint;
/** Fee per kB to use when building the tx. */
feePerKb?: bigint;
/** Allow accepting an offer such that the remaining quantity is unacceptable */
allowUnspendable?: boolean;
}): Tx;
/**
* How many extra satoshis are required to fuel this offer so it can be
* broadcast on the network, excluding the asked sats.
* This should be displayed to the user as network fee.
* The total required input amount is askedSats + acceptFeeSats.
**/
acceptFeeSats(params: {
/** Script to send the tokens and the leftover sats (if any) to. */
recipientScript: Script;
/** Extra inputs */
extraInputs?: TxBuilderInput[];
/** Fee per kB to use when building the tx. */
feePerKb?: bigint;
acceptedAtoms?: bigint;
}): bigint;
private _acceptTxBuilder;
/**
* Build a tx canceling the offer.
*
* An offer can only be cancelled using the secret key that created it.
*
* `fuelInputs` must cover the tx fee, you can calculate it with cancelFeeSats.
**/
cancelTx(params: {
/**
* Cancel secret key of the offer, must be paired with the cancelPk of
* the offer.
**/
cancelSk: Uint8Array;
/**
* Inputs fueling this tx with sats. Must have signatory and
* input.signData set correctly. If it is set incorrectly, may fail
* silently and build an invalid tx, failing at broadcast.
*
* The free sats of these inputs must be at least cancelFeeSats.
**/
fuelInputs: TxBuilderInput[];
/** Script to send canceled tokens and the leftover sats (if any) to. */
recipientScript: Script;
/** Dust amount to use for the token output. */
dustSats?: bigint;
/** Fee per kB to use when building the tx. */
feePerKb?: bigint;
}): Tx;
/**
* How many extra satoshis are required to fuel cancelling this offer,
* so the cancel tx can be broadcast on the network, excluding the asked
* sats and a dust amount to receive the tokens.
*
* extraInputs can be used to add an ad input so we have the correct
* estimate in case of a cancel + reoffer.
*
* This should be displayed to the user as cancellation network fee.
* The total required sats input amount is returned by this function.
**/
cancelFeeSats(params: {
/** Script to send the tokens and the leftover sats (if any) to. */
recipientScript: Script;
/** Extra inputs */
extraInputs?: TxBuilderInput[];
/** Fee per kB to use when building the tx. */
feePerKb?: bigint;
}): bigint;
private _cancelTxBuilder;
/**
* How many satoshis are asked to accept this offer, excluding tx fees.
* This is what should be displayed to the user as the price.
**/
askedSats(acceptedAtoms?: bigint): bigint;
}
/** Which txs to query (confirmed, unconfirmed, reverse history) */
export type TxHistoryTable = 'CONFIRMED' | 'UNCONFIRMED' | 'HISTORY';
export type AgoraQueryParamVariants = {
type: 'TOKEN_ID';
tokenId: string;
} | {
type: 'GROUP_TOKEN_ID';
groupTokenId: string;
} | {
type: 'PUBKEY';
pubkeyHex: string;
};
/** Params which Agora txs to query */
export type AgoraHistoryParams = AgoraQueryParamVariants & {
table: TxHistoryTable;
page?: number;
pageSize?: number;
};
/** Queried offers from the history */
export interface AgoraHistoryResult {
offers: AgoraOffer[];
numTxs: number;
numPages: number;
}
/**
* Enables access to Agora, via Chronik instances that have the "agora" plugin
* loaded.
*
* See agora.py.
**/
export declare class Agora {
private chronik;
private plugin;
private dustSats;
/**
* Create an Agora instance. The provided Chronik instance must have the
* "agora" plugin loaded.
**/
constructor(chronik: ChronikClient, dustSats?: bigint);
/**
* Query all the token IDs, fungible and non-fungible ones, that have active
* Agora offers.
**/
allOfferedTokenIds(): Promise<string[]>;
/** Query all fungible token IDs that have active Agora offers. */
offeredFungibleTokenIds(): Promise<string[]>;
/**
* Query all token IDs of groups of non-fungible tokens that have active
* Agora offers.
**/
offeredGroupTokenIds(): Promise<string[]>;
/** Query all active offers by token ID. */
activeOffersByTokenId(tokenId: string): Promise<AgoraOffer[]>;
/** Query all active offers by group token ID. */
activeOffersByGroupTokenId(groupTokenId: string): Promise<AgoraOffer[]>;
/** Query all active offers with the given cancel pubkey. */
activeOffersByPubKey(pubkeyHex: string): Promise<AgoraOffer[]>;
/**
* Query historic offers (paginated)
*
* These are basically the "candlesticks" of a specific token (and also the
* cancelled offers, but those would have to be ignored).
* Offers can also be queried by pubkey, giving a history of user's offers.
**/
historicOffers(params: AgoraHistoryParams): Promise<AgoraHistoryResult>;
/** Subscribe to updates from the websocket for some params */
subscribeWs(ws: WsEndpoint, params: AgoraQueryParamVariants): void;
/** Unsubscribe from updates from the websocket for some params */
unsubscribeWs(ws: WsEndpoint, params: AgoraQueryParamVariants): void;
/**
* Build a safe AgoraPartial for the given parameters.
*
* This looks at the blockchain to avoid creating an identical offer, by
* tweaking the enforcedLockTime.
*/
selectParams(params: Omit<AgoraPartialParams, 'enforcedLockTime'> | AgoraPartial): Promise<AgoraPartial>;
private _groupHex;
private _allTokenIdsByPrefix;
private _activeOffersByGroup;
private _parseOfferUtxo;
private _parseOneshotOfferUtxo;
private _parsePartialOfferUtxo;
}
export declare function scriptOps(script: Script): Op[];
//# sourceMappingURL=agora.d.ts.map