Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Integrate docs with docusaurus #45

Merged
merged 19 commits into from
Oct 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,8 @@ out/
# Dotenv file
.env

# node modules
node_modules/*

# generated docs
/docs/docs/api/*
17 changes: 17 additions & 0 deletions docs/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@ const config = {
locales: ["en"],
},

plugins: [
[
'docusaurus-plugin-typedoc',
{
entryPoints: ['../sdk/src/*'],
out: 'api/ts-sdk',
tsconfig: 'tsconfig.json',
},
],

],
presets: [
[
"classic",
Expand Down Expand Up @@ -82,6 +93,12 @@ const config = {
position: "left",
label: "Build",
},
{
type: "docSidebar",
sidebarId: "apiSidebar",
position: "left",
label: "API",
},
{
href: GITHUB_LINK,
label: "GitHub",
Expand Down
11 changes: 7 additions & 4 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
"typecheck": "tsc"
},
"dependencies": {
"@docusaurus/core": "2.4.1",
"@docusaurus/preset-classic": "2.4.1",
"@docusaurus/theme-live-codeblock": "^2.4.1",
"@docusaurus/theme-mermaid": "^2.4.1",
"@docusaurus/core": "^2.4.3",
"@docusaurus/preset-classic": "^2.4.3",
"@docusaurus/theme-live-codeblock": "^2.4.3",
"@docusaurus/theme-mermaid": "^2.4.3",
"@easyops-cn/docusaurus-search-local": "^0.36.0",
"@mdx-js/react": "^1.6.22",
"clsx": "^1.2.1",
Expand All @@ -29,6 +29,9 @@
"devDependencies": {
"@docusaurus/module-type-aliases": "^2.4.1",
"@tsconfig/docusaurus": "^2.0.0",
"docusaurus-plugin-typedoc": "^0.20.2",
"typedoc": "^0.25.2",
"typedoc-plugin-markdown": "^3.16.0",
"typescript": "^5.1.6"
},
"browserslist": {
Expand Down
42 changes: 41 additions & 1 deletion docs/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,48 @@ const sidebars = {
// By default, Docusaurus generates a sidebar from the docs folder structure
rootSidebar: [{type: 'autogenerated', dirName: '.'}],
learnSidebar: [{type: 'autogenerated', dirName: 'learn'}],
// guideSidebar: [{type: 'autogenerated', dirName: 'guide'}],
buildSidebar: [{type: 'autogenerated', dirName: 'build'}],
apiSidebar: [
{
type: 'category',
label: 'TypeScript API',
collapsed: false,
items: [
"api/ts-sdk/modules",
{
type: 'category',
label: 'Modules',
items: [
{
type: 'autogenerated',
dirName: 'api/ts-sdk/modules'
}
]
},
{
type: 'category',
label: 'Interfaces',
items: [
{
type: 'autogenerated',
dirName: 'api/ts-sdk/interfaces'
}
]
},
{
type: 'category',
label: 'Classes',
items: [
{
type: 'autogenerated',
dirName: 'api/ts-sdk/classes'
}
]
}
],
}
],
// guideSidebar: [{type: 'autogenerated', dirName: 'guide'}],
// runSidebar: [{type: 'autogenerated', dirName: 'run'}],

// But you can create a sidebar manually
Expand Down
4 changes: 3 additions & 1 deletion docs/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
"extends": "@tsconfig/docusaurus/tsconfig.json",
"compilerOptions": {
"baseUrl": "."
}
},
"include": ["../sdk/src/*"], // Adjust the path as needed
"exclude": ["../sdk/src/index.ts"]
}
153 changes: 143 additions & 10 deletions sdk/src/electrs.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
/**
* Base path for the mainnet Esplora API.
* @default "https://btc-mainnet.interlay.io"
*/
export const MAINNET_ESPLORA_BASE_PATH = "https://btc-mainnet.interlay.io";
nud3l marked this conversation as resolved.
Show resolved Hide resolved
/**
* Base path for the testnet Esplora API.
* @default "https://btc-testnet.interlay.io"
*/
export const TESTNET_ESPLORA_BASE_PATH = "https://btc-testnet.interlay.io";
export const REGTEST_ESPLORA_BASE_PATH = "http://localhost:3002";
/**
* Base path for the regtest Esplora API.
* @default "http://localhost:3003"
*/
export const REGTEST_ESPLORA_BASE_PATH = "http://localhost:3003";

/**
* @ignore
*/
export interface MerkleProof {
blockHeight: number
merkle: string,
Expand All @@ -10,35 +25,129 @@ export interface MerkleProof {

export interface ElectrsClient {
/**
* @param height The height of the Bitcoin block
* @returns The block hash of the Bitcoin block
* Get the block hash of the Bitcoin block at a specific height.
*
* This function retrieves the block hash for the Bitcoin block at the given height.
*
* @param {number} height - The height of the Bitcoin block.
* @returns {Promise<string>} A promise that resolves to the block hash of the Bitcoin block.
*
* @example
* ```typescript
* const BITCOIN_NETWORK = "regtest";
* const electrsClient = new DefaultElectrsClient(BITCOIN_NETWORK);
* const blockHeight = 123456;
* electrsClient.getBlockHash(blockHeight)
* .then((blockHash) => {
* console.log(`Block hash at height ${blockHeight}: ${blockHash}`);
* })
* .catch((error) => {
* console.error(`Error: ${error}`);
* });
* ```
*/
getBlockHash(height: number): Promise<string>;

/**
* @param height The hash of the Bitcoin block
* @returns The raw block header, represented as a hex string
* Get the raw block header, represented as a hex string, for a Bitcoin block with a given hash.
*
* @param {string} hash - The hash of the Bitcoin block.
* @returns {Promise<string>} A promise that resolves to the raw block header as a hex string.
*
* @example
* ```typescript
* const BITCOIN_NETWORK = "regtest";
* const electrsClient = new DefaultElectrsClient(BITCOIN_NETWORK);
* const blockHash = 'your_block_hash_here';
* electrsClient.getBlockHeader(blockHash)
* .then((blockHeader) => {
* console.log(`Raw block header for block with hash ${blockHash}: ${blockHeader}`);
* })
* .catch((error) => {
* console.error(`Error: ${error}`);
* });
* ```
*/
getBlockHeader(hash: string): Promise<string>;

/**
* @param txId The ID of a Bitcoin transaction
* @returns The transaction data, represented as a hex string
* Get the transaction data, represented as a hex string, for a Bitcoin transaction with a given ID (txId).
*
* @param {string} txId - The ID of a Bitcoin transaction.
* @returns {Promise<string>} A promise that resolves to the transaction data as a hex string.
*
* @example
* ```typescript
* const BITCOIN_NETWORK = "regtest";
* const electrsClient = new DefaultElectrsClient(BITCOIN_NETWORK);
* const transactionId = 'your_transaction_id_here';
* electrsClient.getTransactionHex(transactionId)
* .then((transactionHex) => {
* console.log(`Transaction hex for transaction with ID ${transactionId}: ${transactionHex}`);
* })
* .catch((error) => {
* console.error(`Error: ${error}`);
* });
* ```
*/
getTransactionHex(txId: string): Promise<string>;

/**
* @param txId The ID of a Bitcoin transaction
* @returns The encoded merkle inclusion proof for the transaction
* Get the encoded merkle inclusion proof for a Bitcoin transaction with a given ID (txId).
*
* @param {string} txId - The ID of a Bitcoin transaction.
* @returns {Promise<MerkleProof>} A promise that resolves to the encoded merkle inclusion proof.
*
* @example
* ```typescript
* const BITCOIN_NETWORK = "regtest";
* const electrsClient = new DefaultElectrsClient(BITCOIN_NETWORK);
* const transactionId = 'your_transaction_id_here';
* electrsClient.getMerkleProof(transactionId)
* .then((merkleProof) => {
* console.log(`Merkle inclusion proof for transaction with ID ${transactionId}: ${merkleProof}`);
* })
* .catch((error) => {
* console.error(`Error: ${error}`);
* });
* ```
*/
getMerkleProof(txId: string): Promise<MerkleProof>;
}
}


/**
* @ignore
*/
function encodeElectrsMerkleProof(merkle: string[]): string {
// convert to little-endian
return merkle.map(item => Buffer.from(item, "hex").reverse().toString("hex")).join('');
}


/**
* The `DefaultElectrsClient` class provides a client for interacting with an Esplora API
* for Bitcoin network data retrieval.
*/
export class DefaultElectrsClient implements ElectrsClient {
private basePath: string;

/**
* Create an instance of the `DefaultElectrsClient` with the specified network or URL.
* If the `networkOrUrl` parameter is omitted, it defaults to "mainnet."
*
* @param networkOrUrl The Bitcoin network (e.g., "mainnet," "testnet," "regtest")
*
* @returns An instance of the `DefaultElectrsClient` configured for the specified network or URL.
*
* @example
* const BITCOIN_NETWORK = "regtest";
* const electrsClient = new DefaultElectrsClient(BITCOIN_NETWORK);
*
* @example
* // Create a client for the mainnet using the default URL.
* const electrsClientMainnet = new DefaultElectrsClient();
*/
constructor(networkOrUrl: string = "mainnet") {
switch (networkOrUrl) {
case "mainnet":
Expand All @@ -55,18 +164,34 @@ export class DefaultElectrsClient implements ElectrsClient {
}
}


/**
* @ignore
*/
async getBlockHash(height: number): Promise<string> {
return this.getText(`${this.basePath}/block-height/${height}`);
}


/**
* @ignore
*/
async getBlockHeader(hash: string): Promise<string> {
return this.getText(`${this.basePath}/block/${hash}/header`);
}


/**
* @ignore
*/
async getTransactionHex(txId: string): Promise<string> {
return this.getText(`${this.basePath}/tx/${txId}/hex`);
}


/**
* @ignore
*/
async getMerkleProof(txId: string): Promise<MerkleProof> {
const response = await this.getJson<{
"block_height": number,
Expand All @@ -80,6 +205,10 @@ export class DefaultElectrsClient implements ElectrsClient {
};
}


/**
* @ignore
*/
async getJson<T>(url: string): Promise<T> {
const response = await fetch(url);
if (!response.ok) {
Expand All @@ -88,6 +217,10 @@ export class DefaultElectrsClient implements ElectrsClient {
return await response.json() as Promise<T>;
}


/**
* @ignore
*/
async getText(url: string): Promise<string> {
const response = await fetch(url);
if (!response.ok) {
Expand Down
Loading