From 4a4a166f207575354d760daea8549b35b459fdbb Mon Sep 17 00:00:00 2001 From: Adam A Date: Fri, 3 May 2024 21:34:01 +0300 Subject: [PATCH] feat(agent): allow fetching block by height or hash --- packages/agent/chain.md | 43 ++++++++++++++++++------------- packages/agent/chain.ts | 57 ++++++++++++++++++++++++++--------------- packages/agent/stub.md | 37 +++++++++++++++----------- packages/agent/stub.ts | 4 +-- 4 files changed, 85 insertions(+), 56 deletions(-) diff --git a/packages/agent/chain.md b/packages/agent/chain.md index 4ac9019e7c..3fa66da0bf 100644 --- a/packages/agent/chain.md +++ b/packages/agent/chain.md @@ -8,10 +8,10 @@ with a local blockchain node instead, see `@fadroma/devnet`. # 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.
@@ -43,9 +43,8 @@ The same chain may be accessible via different endpoints, so this property contains the URL to which requests are sent.
# 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. @@ -77,10 +76,10 @@ backend.getIdentity(name: string) # 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. @@ -169,10 +168,21 @@ Fetch balance of 1 or many addresses in 1 or many native tokens. ## method [*connection.fetchBlock*](https://github.com/hackbg/fadroma/tree/v2/packages/agent/chain.ts) -Get info about a specific block. -If no height is passed, gets info about the latest block. +Get info about the latest block. +
+const result: Block = await connection.fetchBlock()
+
+Get info about the block with a specific height. +
+const result: Block = await connection.fetchBlock({
+  height,
+})
+
+Get info about the block with a specific hash.
-const result: Block = await connection.fetchBlock(height: number)
+const result: Block = await connection.fetchBlock({
+  hash,
+})
 
## method [*connection.fetchCodeInfo*](https://github.com/hackbg/fadroma/tree/v2/packages/agent/chain.ts) @@ -354,13 +364,10 @@ agent.upload( # abstract class *Block* -The building block of a blockchain. - -Each block contains collection of transactions that are -appended to the blockchain at a given point in time. +The building block of a blockchain, as obtained by +[the `fetchBlock` method of `Connection`](#method-connectionfetchblock) -You shouldn't have to instantiate this directly; -instead, it's returned from `connection.getBlock()` +Contains zero or more transactions.
@@ -384,7 +391,7 @@ instead, it's returned from `connection.getBlock()` # 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. diff --git a/packages/agent/chain.ts b/packages/agent/chain.ts index 7e4eb07199..308387acce 100644 --- a/packages/agent/chain.ts +++ b/packages/agent/chain.ts @@ -40,10 +40,10 @@ export type Message = string|Record /** 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. */ @@ -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. * @@ -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. */ @@ -210,13 +209,32 @@ export abstract class Connection extends Endpoint { } protected abstract fetchHeightImpl (): Promise - /** Get info about a specific block. - * If no height is passed, gets info about the latest block. */ - fetchBlock (height?: number): Promise { - this.log.debug(height ? `Querying block ${height}` : `Querying latest block`) - return this.fetchBlockInfoImpl(height) as Promise + /** Get info about the latest block. */ + fetchBlock (): Promise + /** Get info about the block with a specific height. */ + fetchBlock ({ height }: { height: number }): Promise + /** Get info about the block with a specific hash. */ + fetchBlock ({ hash }: { hash: string }): Promise + fetchBlock (...args: unknown[]): Promise { + 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 + protected abstract fetchBlockImpl (options?: { height: number }|{ hash: string }): + Promise ///////////////////////////////////////////////////////////////////////////////////////////////// @@ -660,13 +678,10 @@ export abstract class Agent extends Logged { ): Promise } -/** The building block of a blockchain. - * - * Each block contains collection of transactions that are - * appended to the blockchain at a given point in time. +/** The building block of a blockchain, as obtained by + * [the `fetchBlock` method of `Connection`](#method-connectionfetchblock) * - * You shouldn't have to instantiate this directly; - * instead, it's returned from `connection.getBlock()` */ + * Contains zero or more transactions. */ export abstract class Block { /** Connection to the chain to which this block belongs. */ chain?: Connection @@ -689,7 +704,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. */ diff --git a/packages/agent/stub.md b/packages/agent/stub.md index 58766a55c1..6b02e669dc 100644 --- a/packages/agent/stub.md +++ b/packages/agent/stub.md @@ -1,13 +1,10 @@ # class *StubBlock* -The building block of a blockchain. +The building block of a blockchain, as obtained by +[the `fetchBlock` method of `Connection`](#method-connectionfetchblock) -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()` +Contains zero or more transactions.
 const stubBlock = new StubBlock(properties: Partial<Block>)
@@ -45,10 +42,10 @@ instead, it's returned from `connection.getBlock()`
 
# 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.
@@ -154,10 +151,21 @@ Fetch balance of 1 or many addresses in 1 or many native tokens.
 
## method [*stubConnection.fetchBlock*](https://github.com/hackbg/fadroma/tree/v2/packages/agent/chain.ts) -Get info about a specific block. -If no height is passed, gets info about the latest block. +Get info about the latest block. +
+const result: Block = await stubConnection.fetchBlock()
+
+Get info about the block with a specific height.
-const result: Block = await stubConnection.fetchBlock(height: number)
+const result: Block = await stubConnection.fetchBlock({
+  height,
+})
+
+Get info about the block with a specific hash. +
+const result: Block = await stubConnection.fetchBlock({
+  hash,
+})
 
## method [*stubConnection.fetchCodeInfo*](https://github.com/hackbg/fadroma/tree/v2/packages/agent/chain.ts) @@ -343,9 +351,8 @@ stubAgent.upload( # 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. diff --git a/packages/agent/stub.ts b/packages/agent/stub.ts index bbbf6ff61c..d025108db9 100644 --- a/packages/agent/stub.ts +++ b/packages/agent/stub.ts @@ -37,9 +37,9 @@ export class StubConnection extends Connection { return new StubBatch({ connection: this }) as unknown as Batch } 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 () {