Skip to content

Commit

Permalink
feat(agent): allow fetching block by height or hash
Browse files Browse the repository at this point in the history
  • Loading branch information
egasimus committed May 3, 2024
1 parent 4505039 commit aa289c9
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 38 deletions.
41 changes: 29 additions & 12 deletions packages/agent/chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ with a local blockchain node instead, see `@fadroma/devnet`.
<!-- @hackbg/docs: begin -->

# abstract class *Endpoint*
Base class representing a remote API endpoint.
Represents a remote API endpoint.

You shouldn't need to instantiate this class directly.
Instead, see `Connection` and its subclasses.
Instead, see [`Connection`](#abstract-class-connection) and its subclasses.

<table><tbody>
<tr><td valign="top">
Expand Down Expand Up @@ -43,9 +43,8 @@ The same chain may be accessible via different endpoints, so
this property contains the URL to which requests are sent.</td></tr></tbody></table>

# abstract class *Backend*
Base class representing any connection backend, such as:
Provides control over the service backing an [`Endpoint`](#abstract-class-endpoint), such as:

* Remote RPC endpoint.
* Local devnet RPC endpoint.
* Stub/mock implementation of chain.

Expand Down Expand Up @@ -77,10 +76,10 @@ backend.getIdentity(name: string)
</pre>

# abstract class *Connection*
Base class representing a connection to a blockchain via a given endpoint.

Use one of its subclasses in `@fadroma/scrt`, `@fadroma/cw`, `@fadroma/namada`
to connect to the corresponding chain. Or, extend this class to implement
Represents a connection to a blockchain via a given endpoint.
* Use one of its subclasses in `@fadroma/scrt`, `@fadroma/cw`, `@fadroma/namada`
to connect to the corresponding chain.
* Or, extend this class to implement
support for new kinds of blockchains.

<table><tbody>
Expand Down Expand Up @@ -172,7 +171,17 @@ Fetch balance of 1 or many addresses in 1 or many native tokens.
Get info about a specific block.
If no height is passed, gets info about the latest block.
<pre>
<strong>const</strong> result: <em><a href="#">Block</a></em> = <strong>await</strong> connection.fetchBlock(height: number)
<strong>const</strong> result: <em><a href="#">Block</a></em> = <strong>await</strong> connection.fetchBlock()
</pre>
<pre>
<strong>const</strong> result: <em><a href="#">Block</a></em> = <strong>await</strong> connection.fetchBlock({
height,
})
</pre>
<pre>
<strong>const</strong> result: <em><a href="#">Block</a></em> = <strong>await</strong> connection.fetchBlock({
hash,
})
</pre>

## method [*connection.fetchCodeInfo*](https://github.com/hackbg/fadroma/tree/v2/packages/agent/chain.ts)
Expand Down Expand Up @@ -359,8 +368,16 @@ The building block of a blockchain.
Each block contains collection of transactions that are
appended to the blockchain at a given point in time.

You shouldn't have to instantiate this directly;
instead, it's returned from `connection.getBlock()`
```
// Fetching the latest block:
const block = await connection.fetchBlock()
// Fetching a specific block by height:
const block = await connection.fetchBlock({ height: 1234 })
// Fetching a specific block by hash:
const block = await connection.fetchBlock({ hash: "..." })
```

<table><tbody>
<tr><td valign="top">
Expand All @@ -384,7 +401,7 @@ instead, it's returned from `connection.getBlock()`
</pre>

# class *Contract*
Base class representing a particular instance of a smart contract.
Represents a particular instance of a smart contract.

Subclass this to add custom query and transaction methods corresponding
to the contract's API.
Expand Down
56 changes: 41 additions & 15 deletions packages/agent/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ export type Message = string|Record<string, unknown>
/** A transaction hash, uniquely identifying an executed transaction on a chain. */
export type TxHash = string

/** Base class representing a remote API endpoint.
/** Represents a remote API endpoint.
*
* You shouldn't need to instantiate this class directly.
* Instead, see `Connection` and its subclasses. */
* Instead, see [`Connection`](#abstract-class-connection) and its subclasses. */
export abstract class Endpoint extends Logged {
/** Chain ID. This is a string that uniquely identifies a chain.
* A project's mainnet and testnet have different chain IDs. */
Expand Down Expand Up @@ -86,9 +86,8 @@ export abstract class Endpoint extends Logged {
}
}

/** Base class representing any connection backend, such as:
/** Provides control over the service backing an [`Endpoint`](#abstract-class-endpoint), such as:
*
* * Remote RPC endpoint.
* * Local devnet RPC endpoint.
* * Stub/mock implementation of chain.
*
Expand All @@ -111,10 +110,10 @@ export abstract class Backend extends Logged {
abstract getIdentity (name: string): Promise<{ address?: Address, mnemonic?: string }>
}

/** Base class representing a connection to a blockchain via a given endpoint.
*
* Use one of its subclasses in `@fadroma/scrt`, `@fadroma/cw`, `@fadroma/namada`
* to connect to the corresponding chain. Or, extend this class to implement
/** Represents a connection to a blockchain via a given endpoint.
* * Use one of its subclasses in `@fadroma/scrt`, `@fadroma/cw`, `@fadroma/namada`
* to connect to the corresponding chain.
* * Or, extend this class to implement
* support for new kinds of blockchains. */
export abstract class Connection extends Endpoint {
/** Native token of chain. */
Expand Down Expand Up @@ -212,11 +211,29 @@ export abstract class Connection extends Endpoint {

/** Get info about a specific block.
* If no height is passed, gets info about the latest block. */
fetchBlock (height?: number): Promise<Block> {
this.log.debug(height ? `Querying block ${height}` : `Querying latest block`)
return this.fetchBlockInfoImpl(height) as Promise<Block>
fetchBlock (): Promise<Block>
fetchBlock ({ height }: { height: number }): Promise<Block>
fetchBlock ({ hash }: { hash: string }): Promise<Block>
fetchBlock (...args: unknown[]): Promise<Block> {
if (args[0]) {
if (typeof args[0] === 'object') {
if ('height' in args[0]) {
this.log.debug(`Querying block by height ${args[0].height}`)
return this.fetchBlockImpl({ height: args[0].height as number })
} else if ('hash' in args[0]) {
this.log.debug(`Querying block by hash ${args[0].hash}`)
return this.fetchBlockImpl({ hash: args[0].hash as string })
}
} else {
throw new Error('Invalid arguments, pass {height:number} or {hash:string}')
}
} else {
this.log.debug(`Querying latest block`)
return this.fetchBlockImpl()
}
}
protected abstract fetchBlockInfoImpl (height?: number): Promise<Block>
protected abstract fetchBlockImpl (options?: { height: number }|{ hash: string }):
Promise<Block>

/////////////////////////////////////////////////////////////////////////////////////////////////

Expand Down Expand Up @@ -665,8 +682,17 @@ export abstract class Agent extends Logged {
* Each block contains collection of transactions that are
* appended to the blockchain at a given point in time.
*
* You shouldn't have to instantiate this directly;
* instead, it's returned from `connection.getBlock()` */
* ```
* // Fetching the latest block:
* const block = await connection.fetchBlock()
*
* // Fetching a specific block by height:
* const block = await connection.fetchBlock({ height: 1234 })
*
* // Fetching a specific block by hash:
* const block = await connection.fetchBlock({ hash: "..." })
* ```
* */
export abstract class Block {
/** Connection to the chain to which this block belongs. */
chain?: Connection
Expand All @@ -689,7 +715,7 @@ export abstract class Block {
}
}

/** Base class representing a particular instance of a smart contract.
/** Represents a particular instance of a smart contract.
*
* Subclass this to add custom query and transaction methods corresponding
* to the contract's API. */
Expand Down
35 changes: 26 additions & 9 deletions packages/agent/stub.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,16 @@ The building block of a blockchain.
Each block contains collection of transactions that are
appended to the blockchain at a given point in time.

You shouldn't have to instantiate this directly;
instead, it's returned from `connection.getBlock()`
```
// Fetching the latest block:
const block = await connection.fetchBlock()
// Fetching a specific block by height:
const block = await connection.fetchBlock({ height: 1234 })
// Fetching a specific block by hash:
const block = await connection.fetchBlock({ hash: "..." })
```

<pre>
<strong>const</strong> stubBlock = new StubBlock(properties: Partial&lt;Block&gt;)
Expand Down Expand Up @@ -45,10 +53,10 @@ instead, it's returned from `connection.getBlock()`
</pre>

# class *StubConnection*
Base class representing a connection to a blockchain via a given endpoint.

Use one of its subclasses in `@fadroma/scrt`, `@fadroma/cw`, `@fadroma/namada`
to connect to the corresponding chain. Or, extend this class to implement
Represents a connection to a blockchain via a given endpoint.
* Use one of its subclasses in `@fadroma/scrt`, `@fadroma/cw`, `@fadroma/namada`
to connect to the corresponding chain.
* Or, extend this class to implement
support for new kinds of blockchains.

<pre>
Expand Down Expand Up @@ -157,7 +165,17 @@ Fetch balance of 1 or many addresses in 1 or many native tokens.
Get info about a specific block.
If no height is passed, gets info about the latest block.
<pre>
<strong>const</strong> result: <em><a href="#">Block</a></em> = <strong>await</strong> stubConnection.fetchBlock(height: number)
<strong>const</strong> result: <em><a href="#">Block</a></em> = <strong>await</strong> stubConnection.fetchBlock()
</pre>
<pre>
<strong>const</strong> result: <em><a href="#">Block</a></em> = <strong>await</strong> stubConnection.fetchBlock({
height,
})
</pre>
<pre>
<strong>const</strong> result: <em><a href="#">Block</a></em> = <strong>await</strong> stubConnection.fetchBlock({
hash,
})
</pre>

## method [*stubConnection.fetchCodeInfo*](https://github.com/hackbg/fadroma/tree/v2/packages/agent/chain.ts)
Expand Down Expand Up @@ -343,9 +361,8 @@ stubAgent.upload(
</pre>

# class *StubBackend*
Base class representing any connection backend, such as:
Provides control over the service backing an [`Endpoint`](#abstract-class-endpoint), such as:

* Remote RPC endpoint.
* Local devnet RPC endpoint.
* Stub/mock implementation of chain.

Expand Down
4 changes: 2 additions & 2 deletions packages/agent/stub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ export class StubConnection extends Connection {
return new StubBatch({ connection: this }) as unknown as Batch<this, StubAgent>
}
protected fetchHeightImpl () {
return this.fetchBlockInfoImpl().then(({height})=>height)
return this.fetchBlockImpl().then(({height})=>height)
}
protected fetchBlockInfoImpl () {
protected fetchBlockImpl () {
return Promise.resolve(new StubBlock({ height: + new Date() }))
}
protected fetchCodesImpl () {
Expand Down

0 comments on commit aa289c9

Please sign in to comment.