From f3839155e1bc073e76ac1d01febbb95ce09da3d1 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 27 Nov 2024 08:24:22 +0000 Subject: [PATCH 01/98] docs: account-module.md --- .../thor/accounts/account-module.md | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 docs/diagrams/architecture/thor/accounts/account-module.md diff --git a/docs/diagrams/architecture/thor/accounts/account-module.md b/docs/diagrams/architecture/thor/accounts/account-module.md new file mode 100644 index 000000000..4181fd7c5 --- /dev/null +++ b/docs/diagrams/architecture/thor/accounts/account-module.md @@ -0,0 +1,92 @@ +```mermaid +classDiagram + class AccountDetails { + VET balance + VTHO energy + boolean hasCode + } + class CallResult { + HexUInt data + Event[] events + VTHO gasUsed + boolean reverted + Transfer[] transfers + string vmError + } + class Clause { + HexUInt data + Address to + VET value + } + class InspectedClauses { + CallResult[] callResults + } + class ContractByteCode { + HexUInt code + } + class Event { + HexUInt data + Address event + HexUInt[] topics + } + class InspectClauses { + BlockRef blockRef + Address caller + Clause[] clauses + number expiration + VTHO gas + Address gasPayer + VTHO gasPrice + string provedWork + Revision revision + } + class HttpClient { + <> + } + class RetrieveContractByteCode { + Address address + Revision revision + } + class RetrieveAccountDetails { + Address address + Revision revision + } + class RetrieveStoragePositionValue { + Address address + BlockId key + Revision revision + } + class StoragePositionValue { + UInt8Array value + } + class ThorRequest { + <> + ThorResponse askTo(HttpClient httpClient) + } + class ThorResponse { + <> + } + class Transfer { + VET amount + Address recepient + Address sender + } + Clause *-- InspectClauses + HttpClient o-- ThorRequest + InspectClauses <|-- InspectedClauses + RetrieveContractByteCode <|-- ContractByteCode + RetrieveAccountDetails <|-- AccountDetails + RetrieveStoragePositionValue <|-- StoragePositionValue + ThorRequest <|.. InspectClauses + ThorRequest <|.. RetrieveContractByteCode + ThorRequest <|.. RetrieveAccountDetails + ThorRequest <|.. RetrieveStoragePositionValue + + AccountDetails ..|> ThorResponse + CallResult --* Event + CallResult --* Transfer + ContractByteCode ..|> ThorResponse + InspectedClauses ..|> ThorResponse + InspectedClauses --* CallResult + StoragePositionValue ..|> ThorResponse +``` From 41c5438d95eab544cc75c6116d0f80013a1cb66d Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 27 Nov 2024 14:06:19 +0000 Subject: [PATCH 02/98] docs: transaction-module.md --- .../thor/transactions/transactions-module.md | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 docs/diagrams/architecture/thor/transactions/transactions-module.md diff --git a/docs/diagrams/architecture/thor/transactions/transactions-module.md b/docs/diagrams/architecture/thor/transactions/transactions-module.md new file mode 100644 index 000000000..cc628faa4 --- /dev/null +++ b/docs/diagrams/architecture/thor/transactions/transactions-module.md @@ -0,0 +1,97 @@ +```mermaid +classDiagram + class HttpClient { + <> + } + class ThorRequest~Request~ { + <> + ThorResponse~Request~ askTo(HttpClient httpClient) + } + class ThorResponse~Response~ { + <> + ThorRequest~Request~ request + Response response + } + namespace Request { + class RetrieveTransactionByID { + HexUInt id + RetrieveTransactionByID_Query query + } + class RetrieveTransactionByID_Query { + BlockId head + boolean pending + boolean raw + } + class RetrieveTransactionReceipt { + HexUInt id + RetrieveTransactionReceipt_Query query + } + class RetrieveTransactionReceipt_Query { + BlockId head + } + class SendTransaction { + } + class SendTransaction_Body { + HexUInt raw + } + } + namespace Response { + class SendTransactionResponse { + HexUInt id + } + class GetTxResponse { + HexUInt id + Address origin + Address delegator + number size + number chainTag + string BlockRef + number expiration + Clause[] clauses + number gasPriceCoef + VTHO gaa + HexUInt dependsOn + HexUInt nonce + TxMeta meta + } + class GetTxReceiptResponse { + number gasUsed + Address gasPayer + VTHO paid + VTHO reward + boolean reverted + TransactionOutput[] outputs + ReceiptMeta meta + } + } + class Clause { + Address to + VET value + HexUInt data + } + class TxMeta { + BlockID blockID + number blockBumber + number BlockTimeestamp + } + + HttpClient o-- ThorRequest + + ThorRequest <|.. RetrieveTransactionByID + ThorRequest <|.. RetrieveTransactionReceipt + ThorRequest <|.. SendTransaction + + ThorRequest --* ThorResponse + + ThorResponse <|.. GetTxResponse + ThorResponse <|.. GetTxReceiptResponse + ThorResponse <|.. SendTransactionResponse + + RetrieveTransactionByID --* RetrieveTransactionByID_Query + RetrieveTransactionReceipt --* RetrieveTransactionReceipt_Query + SendTransaction --* SendTransaction_Body + + GetTxResponse --* Clause + GetTxResponse --* TxMeta + +``` From 5909d12e6201078dcbaa11206518605568c1332b Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 27 Nov 2024 16:10:42 +0000 Subject: [PATCH 03/98] docs: blocks-module.md --- .../architecture/thor/blocks/blocks-module.md | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 docs/diagrams/architecture/thor/blocks/blocks-module.md diff --git a/docs/diagrams/architecture/thor/blocks/blocks-module.md b/docs/diagrams/architecture/thor/blocks/blocks-module.md new file mode 100644 index 000000000..4c06f5415 --- /dev/null +++ b/docs/diagrams/architecture/thor/blocks/blocks-module.md @@ -0,0 +1,56 @@ +```mermaid +classDiagram + class HttpClient { + <> + } + class ThorRequest~Request~ { + <> + ThorResponse~Request~ askTo(HttpClient httpClient) + } + class ThorResponse~Response~ { + <> + ThorRequest~Request~ request + Response response + } + namespace Request { + class RetrieveBlock { + Revision revision + RetrieveBlock_Query + } + class RetrieveBlock_Query { + boolean expanded + } + } + namespace Response { + class RegularBlockResponse { + number integer + HexUInt id + number size + HexHUInt parentID + number timestamp + VTHO gasLimit + Address benificiary + VTHO gasUsed + number totalScore + HexUInt txsRoot + number txsFeatures + HexUInt stateRoot + HexUInt receiptRoot + boolean com + Address signer + boolean isTrunk + boolean isFinalized + HexUInt[] transactions + } + } + + HttpClient o-- ThorRequest + ThorRequest <|.. RetrieveBlock + ThorResponse <|.. RegularBlockResponse + + ThorRequest --* ThorResponse + + RetrieveBlock --* RetrieveBlock_Query + + RetrieveBlock <..> RegularBlockResponse +``` From 0315e9056cc0e7415303ab67e365dd7f69c0a844 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 27 Nov 2024 16:15:06 +0000 Subject: [PATCH 04/98] docs: blocks-module.md --- .../{architecture => v2/network}/thor/accounts/account-module.md | 0 .../{architecture => v2/network}/thor/blocks/blocks-module.md | 0 .../network}/thor/transactions/transactions-module.md | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename docs/diagrams/{architecture => v2/network}/thor/accounts/account-module.md (100%) rename docs/diagrams/{architecture => v2/network}/thor/blocks/blocks-module.md (100%) rename docs/diagrams/{architecture => v2/network}/thor/transactions/transactions-module.md (100%) diff --git a/docs/diagrams/architecture/thor/accounts/account-module.md b/docs/diagrams/v2/network/thor/accounts/account-module.md similarity index 100% rename from docs/diagrams/architecture/thor/accounts/account-module.md rename to docs/diagrams/v2/network/thor/accounts/account-module.md diff --git a/docs/diagrams/architecture/thor/blocks/blocks-module.md b/docs/diagrams/v2/network/thor/blocks/blocks-module.md similarity index 100% rename from docs/diagrams/architecture/thor/blocks/blocks-module.md rename to docs/diagrams/v2/network/thor/blocks/blocks-module.md diff --git a/docs/diagrams/architecture/thor/transactions/transactions-module.md b/docs/diagrams/v2/network/thor/transactions/transactions-module.md similarity index 100% rename from docs/diagrams/architecture/thor/transactions/transactions-module.md rename to docs/diagrams/v2/network/thor/transactions/transactions-module.md From 24ed557834817745156e4c7e2f55555fca5746d1 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 27 Nov 2024 19:09:51 +0000 Subject: [PATCH 05/98] docs: logs-module.md --- .../v2/network/thor/logs/logs-module.md | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 docs/diagrams/v2/network/thor/logs/logs-module.md diff --git a/docs/diagrams/v2/network/thor/logs/logs-module.md b/docs/diagrams/v2/network/thor/logs/logs-module.md new file mode 100644 index 000000000..6bc5b2627 --- /dev/null +++ b/docs/diagrams/v2/network/thor/logs/logs-module.md @@ -0,0 +1,88 @@ +```mermaid +classDiagram + class HttpClient { + <> + } + class ThorRequest~Request~ { + <> + ThorResponse~Request~ askTo(HttpClient httpClient) + } + class ThorResponse~Response~ { + <> + ThorRequest~Request~ request + Response response + } + namespace Request { + class QuerySmartContractEvents { + EventLogFilterRequest body + } + class QueryVETTransferEvents { + TransferLogFilterRequest body + } + } + namespace Response { + class EventLogsResponse { + Address address + HexUInt topics + HexUInt data + LogMeta meta + } + class TransferLogsResponse { + Address sender + Address recipient + VET amount + LogMeta meta + } + } + class EventLogFilterRequest { + FilterRange range + FilterOptions options + EventCriteria[] criteriaSet + Sort order + } + class FilterOptions { + UInt offset + UInt limit + } + class FilterRange { + Unit unit + UInt from + UInt to + } + class LogMeta { + BlockID blockID + UInt number + bigint timestamp + TXID txID + TXID txOrigin + UInt clauseIndex + } + class TransferCriteria { + Address txOrigin + Address sender + Address recipient + Sort order + } + class TransferLogFilterRequest { + FilterRange range + FilterOptions options + TransferCriteria[] criteriaSet + } + + HttpClient o-- ThorRequest + ThorRequest <|.. QuerySmartContractEvents + ThorRequest <|.. QueryVETTransferEvents + ThorResponse <|.. EventLogsResponse + ThorResponse <|.. TransferLogsResponse + + ThorRequest --* ThorResponse + EventLogFilterRequest --* FilterRange + EventLogFilterRequest --* FilterOptions + EventLogsResponse --* LogMeta + QuerySmartContractEvents --* EventLogFilterRequest + QueryVETTransferEvents --* TransferLogFilterRequest + TransferLogFilterRequest --* FilterOptions + TransferLogFilterRequest --* FilterRange + TransferLogFilterRequest --* TransferCriteria + TransferLogsResponse --* LogMeta +``` From e31b8bcfd997f66b6202a592e0bc237494c6c4a2 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 27 Nov 2024 19:13:20 +0000 Subject: [PATCH 06/98] docs: logs-module.md --- docs/diagrams/v2/network/thor/logs/logs-module.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/diagrams/v2/network/thor/logs/logs-module.md b/docs/diagrams/v2/network/thor/logs/logs-module.md index 6bc5b2627..a2d34f73e 100644 --- a/docs/diagrams/v2/network/thor/logs/logs-module.md +++ b/docs/diagrams/v2/network/thor/logs/logs-module.md @@ -70,6 +70,7 @@ classDiagram } HttpClient o-- ThorRequest + ThorRequest <|.. QuerySmartContractEvents ThorRequest <|.. QueryVETTransferEvents ThorResponse <|.. EventLogsResponse From bfbba276e7aabbb02291a3adcd408098fcc8c5b8 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 27 Nov 2024 19:29:16 +0000 Subject: [PATCH 07/98] docs: node-module.md --- .../v2/network/thor/node/node-module.md | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 docs/diagrams/v2/network/thor/node/node-module.md diff --git a/docs/diagrams/v2/network/thor/node/node-module.md b/docs/diagrams/v2/network/thor/node/node-module.md new file mode 100644 index 000000000..3257ad265 --- /dev/null +++ b/docs/diagrams/v2/network/thor/node/node-module.md @@ -0,0 +1,36 @@ +```mermaid +classDiagram + class HttpClient { + <> + } + class ThorRequest~Request~ { + <> + ThorResponse~Request~ askTo(HttpClient httpClient) + } + class ThorResponse~Response~ { + <> + ThorRequest~Request~ request + Response response + } + namespace Request { + class RetrieveConnectedPeers { + } + } + namespace Response { + class GetPeersResponse { + string name + BlockID bestBlockID + UInt totalScore + string netAddr + boolean inbound + UInt duration + } + } + + HttpClient o-- ThorRequest + + ThorRequest <|.. RetrieveConnectedPeers + ThorResponse <|.. GetPeersResponse + + ThorRequest --* ThorResponse +``` From aaf95ba2b9ddfa311c3ab9c4766b7a5e0827ca0b Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Thu, 28 Nov 2024 14:00:30 +0000 Subject: [PATCH 08/98] docs: node-module.md --- .../subscriptions/subscriptions-module.md | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 docs/diagrams/v2/network/thor/subscriptions/subscriptions-module.md diff --git a/docs/diagrams/v2/network/thor/subscriptions/subscriptions-module.md b/docs/diagrams/v2/network/thor/subscriptions/subscriptions-module.md new file mode 100644 index 000000000..747eb1a74 --- /dev/null +++ b/docs/diagrams/v2/network/thor/subscriptions/subscriptions-module.md @@ -0,0 +1,130 @@ +```mermaid +classDiagram + class HttpClient { + <> + } + class ThorRequest~Request~ { + <> + askTo(httpClient: HttpClient) ThorResponse~Request~ + } + class ThorResponse~Response~ { + <> + request: ThorRequest~Request~ + response: Response + } + namespace Request { + class SubscribeBeats { + query: SubscribeBeats_Query + } + class SubscribeBeats_Query { + pos: BlockID + } + class SubscribeBlocksCreation { + Blocks_Query query + } + class SubscribeBlocksCreation_Query { + TXID pos + } + class SubscribeContractEvents { + Events_Query query + } + class SubscribeContractEvents_Query { + addr: Address + pos: BlockID + t0: HexUInt + t1: HexUInt + t2: HexUInt + t3: HexUIn + } + class SubscribeBlockchainBeats { + } + class SubscribeTransactionsEvents { + body: SubscribeTransactionsEvents_Body + } + class SubscribeTransactionsEvents_Body { + id: TXID + } + class SubscribeVETTransfers { + quesry: SubscribeVETTransfer_Query + } + class SubscribeVETTransfer_Query { + pos: BlockID + recipient: Address + sender: Address + txOrigin: Address + } + } + namespace Response { + class SubscriptionBeat2Response { + gasLimit: VTHO + obsolete: boolean + number: UInt + id: BlockID + parentId: BlockID + timestamp: bigint + txsFeatures: UInt + bloom: BloomFilter + } + class SubscriptionBlockResponse { + number: UInt + id: TXID + size: UInt + parentID: BlockID + timestamp: bigint + gasLimit: VTHO + beneficiary: Address + gasUsed: VTHO + totalScore: UInt + txsRoot: HexUInt + txsFeature: UInt + stateRoot: HexUInt + receiptsRoot: HexUInt + com: boolean + signer: Address + } + class SubscriptionEventResponse { + address: Address + topics: HexUInt + data: HexUInt + obsolete: boolean + meta: LogMeta + } + class SubscriptionTransferResponse { + sender: Address + recipient: Address + amount: VET + obsolete: boolean + meta: LogMeta + } + } + class LogMeta { + blockID: blockID + blockNumber: UInt + blockTimestamp: bigint + txID: TXID + txOrigin: TXID + clauseIndex: UInt + } + + HttpClient o-- ThorRequest + ThorRequest <|.. SubscribeBeats + ThorRequest <|.. SubscribeBlocksCreation + ThorRequest <|.. SubscribeContractEvents + ThorRequest <|.. SubscribeBlockchainBeats + ThorRequest <|.. SubscribeTransactionsEvents + ThorRequest <|.. SubscribeVETTransfers + ThorResponse <|.. SubscriptionBlockResponse + ThorResponse <|.. SubscriptionEventResponse + ThorRequest --* ThorResponse + SubscribeBeats --* SubscribeBeats_Query + SubscribeBlocksCreation --* SubscribeBlocksCreation_Query + SubscribeContractEvents --* SubscribeContractEvents_Query + SubscribeTransactionsEvents --* SubscribeTransactionsEvents_Body + SubscriptionEventResponse --* LogMeta + SubscriptionTransferResponse --*LogMeta + SubscribeVETTransfers --* SubscribeVETTransfer_Query + SubscribeBeats <..> SubscriptionBeat2Response + SubscribeBlocksCreation <..> SubscriptionBlockResponse + SubscribeContractEvents <..> SubscriptionEventResponse + SubscribeVETTransfers <..> SubscriptionTransferResponse +``` From 36a0d1333e1b6a18c043a6e7e188cc2cf572f198 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Fri, 29 Nov 2024 14:56:48 +0000 Subject: [PATCH 09/98] docs: subscriptions-module.md --- .../subscriptions/subscriptions-module.md | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/docs/diagrams/v2/network/thor/subscriptions/subscriptions-module.md b/docs/diagrams/v2/network/thor/subscriptions/subscriptions-module.md index 747eb1a74..713b3ae35 100644 --- a/docs/diagrams/v2/network/thor/subscriptions/subscriptions-module.md +++ b/docs/diagrams/v2/network/thor/subscriptions/subscriptions-module.md @@ -14,19 +14,19 @@ classDiagram } namespace Request { class SubscribeBeats { - query: SubscribeBeats_Query + query: SubscribeBeats_Query } class SubscribeBeats_Query { pos: BlockID } class SubscribeBlocksCreation { - Blocks_Query query + query: SubscribeBlocksCreation_Query } class SubscribeBlocksCreation_Query { - TXID pos + pos: TXID } class SubscribeContractEvents { - Events_Query query + query: SubscribeContractEvents_Query } class SubscribeContractEvents_Query { addr: Address @@ -37,15 +37,16 @@ classDiagram t3: HexUIn } class SubscribeBlockchainBeats { + query: SubscribeBlockchainBeats_Query } - class SubscribeTransactionsEvents { - body: SubscribeTransactionsEvents_Body + class SubscribeBlockchainBeats_Query { + pos: BlockID } - class SubscribeTransactionsEvents_Body { - id: TXID + class SubscribeTransactionsEvents { + body: SubscribeTransactionsEvents_Body } class SubscribeVETTransfers { - quesry: SubscribeVETTransfer_Query + query: SubscribeVETTransfer_Query } class SubscribeVETTransfer_Query { pos: BlockID @@ -55,6 +56,15 @@ classDiagram } } namespace Response { + class SubscriptionBeatResponse { + obsolete: boolean + number: UInt + id: BlockID + parentID: BlockID + timestamp: bigint + txsFeature: UInt + bloom: BloomFilter + } class SubscriptionBeat2Response { gasLimit: VTHO obsolete: boolean @@ -113,17 +123,21 @@ classDiagram ThorRequest <|.. SubscribeBlockchainBeats ThorRequest <|.. SubscribeTransactionsEvents ThorRequest <|.. SubscribeVETTransfers + ThorResponse <|.. SubscriptionBeatResponse + ThorResponse <|.. SubscriptionBeat2Response ThorResponse <|.. SubscriptionBlockResponse ThorResponse <|.. SubscriptionEventResponse + ThorResponse <|.. SubscriptionTransferResponse ThorRequest --* ThorResponse SubscribeBeats --* SubscribeBeats_Query + SubscribeBlockchainBeats --* SubscribeBlockchainBeats_Query SubscribeBlocksCreation --* SubscribeBlocksCreation_Query SubscribeContractEvents --* SubscribeContractEvents_Query - SubscribeTransactionsEvents --* SubscribeTransactionsEvents_Body SubscriptionEventResponse --* LogMeta - SubscriptionTransferResponse --*LogMeta + SubscriptionTransferResponse --* LogMeta SubscribeVETTransfers --* SubscribeVETTransfer_Query SubscribeBeats <..> SubscriptionBeat2Response + SubscribeBlockchainBeats <..> SubscriptionBeatResponse SubscribeBlocksCreation <..> SubscriptionBlockResponse SubscribeContractEvents <..> SubscriptionEventResponse SubscribeVETTransfers <..> SubscriptionTransferResponse From 288e9053c229c33362bf7c496c3273b753483a6c Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Fri, 29 Nov 2024 16:14:28 +0000 Subject: [PATCH 10/98] docs: debug-module.md --- .../v2/network/thor/debug/debug-module.md | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 docs/diagrams/v2/network/thor/debug/debug-module.md diff --git a/docs/diagrams/v2/network/thor/debug/debug-module.md b/docs/diagrams/v2/network/thor/debug/debug-module.md new file mode 100644 index 000000000..4e9a1b9cb --- /dev/null +++ b/docs/diagrams/v2/network/thor/debug/debug-module.md @@ -0,0 +1,80 @@ +```mermaid +classDiagram + class HttpClient { + <> + } + class ThorRequest~Request~ { + askTo(httpClient: HttpClient): ThorResponse~Response~ + } + class ThorResponse~Response~ { + request: ThorRequest~Request~ + } + namespace Request { + class TraceTransactionClause { + body: TraceTransactionClause_Body + } + class TraceTransactionClause_Body { + name: TracerName + config: Object~Class~ + target: string + } + class TraceCall { + body: TraceCall_Body + } + class TraceCall_Body { + name: TracerName + config: Object~Class~ + value: VET + data: HexUInt + to: Address + gas: VTHO + gasPrice: VTHO + caller: Address + provedWork: string + gasPayer: Address + expiration UInt + blockRef: BlockRef + } + class RetrieveStorageRange { + body: RetrieveStorageRange_Body + } + class RetrieveStorageRange_Body { + address: Address + keyStart: HexUInt + maxResult: UInt + target: string + } + } + namespace Response { + class StorageRange { + nextKey: string + storage: HexUInt + } + } + class TracerName { + <> + structLogger: string + 4byte: string + call: string + noop: string + prestate: string + unigram: string + bigram: string + trigram: string + evmdis: string + opcount: string + null: string + } + HttpClient o-- ThorRequest + ThorRequest <|.. RetrieveStorageRange + ThorRequest <|.. TraceCall + ThorRequest <|.. TraceTransactionClause + ThorResponse <|.. StorageRange + RetrieveStorageRange --* RetrieveStorageRange_Body + ThorRequest --* ThorResponse + TraceCall --* TraceCall_Body + TraceCall_Body --* TracerName + TraceTransactionClause --* TraceTransactionClause_Body + TraceTransactionClause_Body --* TracerName + RetrieveStorageRange ..> StorageRange +``` From b25891bbf89b88e36f4f2d4f9ace75ee66b02eef Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Fri, 29 Nov 2024 17:49:45 +0000 Subject: [PATCH 11/98] feat: v2 network dev... --- packages/v2-network/README.md | 1 + packages/v2-network/eslint.config.mjs | 19 +++++++++ packages/v2-network/jest.browser-setup.js | 18 ++++++++ packages/v2-network/jest.config.browser.js | 10 +++++ packages/v2-network/jest.config.js | 23 ++++++++++ packages/v2-network/package.json | 49 ++++++++++++++++++++++ packages/v2-network/src/index.ts | 0 packages/v2-network/tsconfig.json | 12 ++++++ packages/v2-network/typedoc.json | 4 ++ 9 files changed, 136 insertions(+) create mode 100644 packages/v2-network/README.md create mode 100644 packages/v2-network/eslint.config.mjs create mode 100644 packages/v2-network/jest.browser-setup.js create mode 100644 packages/v2-network/jest.config.browser.js create mode 100644 packages/v2-network/jest.config.js create mode 100644 packages/v2-network/package.json create mode 100644 packages/v2-network/src/index.ts create mode 100644 packages/v2-network/tsconfig.json create mode 100644 packages/v2-network/typedoc.json diff --git a/packages/v2-network/README.md b/packages/v2-network/README.md new file mode 100644 index 000000000..a6db39615 --- /dev/null +++ b/packages/v2-network/README.md @@ -0,0 +1 @@ +# @vechain/sdk-v2-network diff --git a/packages/v2-network/eslint.config.mjs b/packages/v2-network/eslint.config.mjs new file mode 100644 index 000000000..ca549b46e --- /dev/null +++ b/packages/v2-network/eslint.config.mjs @@ -0,0 +1,19 @@ +import baseConfig from "../../eslint.config.mjs"; + +export default [ + ...baseConfig, + { + rules: { + "import/no-restricted-paths": ["error", { + zones: [{ + target: "./src", + + from: [ + "../errors" + ], + + message: "Please import using @vechain/sdk-", + }], + }], + }, + }]; diff --git a/packages/v2-network/jest.browser-setup.js b/packages/v2-network/jest.browser-setup.js new file mode 100644 index 000000000..f5a510b90 --- /dev/null +++ b/packages/v2-network/jest.browser-setup.js @@ -0,0 +1,18 @@ +require('whatwg-fetch'); + +const fetchMock = require('jest-fetch-mock'); + +// Don't auto-enable mocks +fetchMock.dontMock(); + +// Jest configuration for WebSocket mocking based on environment +if (typeof window === 'undefined') { + // Running in Node.js environment + jest.mock('ws', () => require('ws')); +} else { + // Running in browser environment + global.WebSocket = window.WebSocket; +} + +// Make fetch global +global.fetch = fetch; \ No newline at end of file diff --git a/packages/v2-network/jest.config.browser.js b/packages/v2-network/jest.config.browser.js new file mode 100644 index 000000000..349145031 --- /dev/null +++ b/packages/v2-network/jest.config.browser.js @@ -0,0 +1,10 @@ +/** @type {import('ts-jest').JestConfigWithTsJest} */ +module.exports = { + preset: 'ts-jest', + testEnvironment: '../../customEnv.js', + setupFiles: ['./jest.browser-setup.js'], + coverageReporters: ['html', 'lcov', 'json'], + runner: 'groups', + reporters: ['default', 'jest-junit'], + workerThreads: true +}; diff --git a/packages/v2-network/jest.config.js b/packages/v2-network/jest.config.js new file mode 100644 index 000000000..27eab725f --- /dev/null +++ b/packages/v2-network/jest.config.js @@ -0,0 +1,23 @@ +/** @type {import('ts-jest').JestConfigWithTsJest} */ +// Coverage threshold would apply to yarn test, not yarn test:unit +const isUnitTest = process.env.UNIT; + +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + coverageReporters: ['html', 'lcov', 'json'], + runner: 'groups', + reporters: ['default', 'jest-junit'], + workerThreads: true, + coverageThreshold: + isUnitTest !== 'true' + ? { + global: { + branches: 98, + functions: 99, + lines: 99, + statements: 99 + } + } + : undefined +}; diff --git a/packages/v2-network/package.json b/packages/v2-network/package.json new file mode 100644 index 000000000..6ff7d0b10 --- /dev/null +++ b/packages/v2-network/package.json @@ -0,0 +1,49 @@ +{ + "name": "@vechain/sdk-v2-network", + "version": "1.0.0-rc.4", + "description": "This module serves connects decentralized applications (dApps) the VeChainThor blockchain", + "author": "VeChain Foundation", + "license": "MIT", + "homepage": "https://github.com/vechain/vechain-sdk-js", + "repository": { + "type": "git", + "url": "github:vechain/vechain-sdk-js" + }, + "keywords": [ + "VeChain" + ], + "main": "dist/index.js", + "module": "dist/index.mjs", + "types": "dist/index.d.ts", + "files": [ + "dist", + "src", + "package.json", + "README.md", + "LICENSE" + ], + "scripts": { + "build": "rm -rf ./dist && tsup-node src/index.ts --format cjs,esm --dts", + "check:circular-dependencies": "npx madge --json --circular --extensions ts src | jq '. | length' | awk '{if($1 > 15) exit 1}'", + "lint": "eslint", + "format": "prettier --write src/**/*.ts tests/**/*.ts solo-seeding/**/*.ts", + "start-thor-solo": "echo 'Starting thor solo node ...' && docker compose -f ../../docker-compose.thor.yml up -d --wait && echo '\nThor solo node started ...'", + "stop-thor-solo": "echo 'Stopping thor solo node ...' && docker compose -f ../../docker-compose.thor.yml down && echo 'Thor solo node stopped ...'", + "test:unit": "rm -rf ./coverageUnit && UNIT=true jest --coverage --coverageDirectory=coverageUnit --group=unit", + "test:integration": "rm -rf ./coverageIntegration && jest --coverage --coverageDirectory=coverageIntegration --group=integration", + "test:integration:solo": "(yarn start-thor-solo && yarn test:integration && yarn stop-thor-solo) || yarn stop-thor-solo", + "test:browser": "rm -rf ./coverage && jest --coverage --coverageDirectory=coverage --group=integration --group=unit --config ./jest.config.browser.js", + "test": "rm -rf ./coverage && jest --coverage --coverageDirectory=coverage --group=integration --group=unit", + "test:solo": "(yarn start-thor-solo && yarn test && yarn stop-thor-solo) || yarn stop-thor-solo", + "test:browser:solo": "(yarn start-thor-solo && yarn test:browser && yarn stop-thor-solo) || yarn stop-thor-solo" + }, + "dependencies": { + "@vechain/sdk-core": "1.0.0-rc.4", + "ws": "^8.18.0" + }, + "devDependencies": { + "@types/ws": "^8.5.13", + "jest-fetch-mock": "^3.0.3", + "whatwg-fetch": "^3.6.20" + } +} diff --git a/packages/v2-network/src/index.ts b/packages/v2-network/src/index.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/v2-network/tsconfig.json b/packages/v2-network/tsconfig.json new file mode 100644 index 000000000..b523f6a50 --- /dev/null +++ b/packages/v2-network/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + }, + "include": [ + "./src/**/*.ts", + "./tests/**/*.ts" + ] +} \ No newline at end of file diff --git a/packages/v2-network/typedoc.json b/packages/v2-network/typedoc.json new file mode 100644 index 000000000..664b688e4 --- /dev/null +++ b/packages/v2-network/typedoc.json @@ -0,0 +1,4 @@ +{ + "extends": ["../../typedoc.base.json"], + "entryPoints": ["src/network.ts"] +} \ No newline at end of file From 4a1e77564079636a5d2dc58d4bf679f4445ebfa6 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Sat, 30 Nov 2024 15:44:22 +0000 Subject: [PATCH 12/98] feat: v2 http dev... --- .../v2-network/src/http/FetchHttpClient.ts | 41 +++++++++++++++++++ packages/v2-network/src/http/HttpClient.ts | 5 +++ packages/v2-network/src/http/HttpPath.ts | 3 ++ packages/v2-network/src/http/index.ts | 3 ++ packages/v2-network/src/index.ts | 1 + .../tests/FetchHttpClient.testnet.test.ts | 18 ++++++++ 6 files changed, 71 insertions(+) create mode 100644 packages/v2-network/src/http/FetchHttpClient.ts create mode 100644 packages/v2-network/src/http/HttpClient.ts create mode 100644 packages/v2-network/src/http/HttpPath.ts create mode 100644 packages/v2-network/src/http/index.ts create mode 100644 packages/v2-network/tests/FetchHttpClient.testnet.test.ts diff --git a/packages/v2-network/src/http/FetchHttpClient.ts b/packages/v2-network/src/http/FetchHttpClient.ts new file mode 100644 index 000000000..d395c615b --- /dev/null +++ b/packages/v2-network/src/http/FetchHttpClient.ts @@ -0,0 +1,41 @@ +import { type HttpClient } from './HttpClient'; +import { type HttpPath } from './HttpPath'; + +class FetchHttpClient implements HttpClient { + private static readonly SLASH = '/'; + + public readonly baseURL: string; + + private readonly onRequest: (request: Request) => Request; + + private readonly onResponse: (response: Response) => Response; + + constructor( + baseURL: string, + onRequest: (request: Request) => Request = (request) => request, + onResponse: (response: Response) => Response = (response) => response + ) { + this.baseURL = baseURL.endsWith(FetchHttpClient.SLASH) + ? baseURL.substring(0, baseURL.length - 1) + : baseURL; + this.onRequest = onRequest; + this.onResponse = onResponse; + } + + async get( + httpPath: HttpPath = { + path: '' + } + ): Promise { + const path = httpPath.path.startsWith(FetchHttpClient.SLASH) + ? httpPath.path.substring(1) + : httpPath.path; + const request = new Request( + `${this.baseURL}${FetchHttpClient.SLASH}${path}` + ); + const response = await fetch(this.onRequest(request)); + return this.onResponse(response); + } +} + +export { FetchHttpClient }; diff --git a/packages/v2-network/src/http/HttpClient.ts b/packages/v2-network/src/http/HttpClient.ts new file mode 100644 index 000000000..12e9fa353 --- /dev/null +++ b/packages/v2-network/src/http/HttpClient.ts @@ -0,0 +1,5 @@ +import { type HttpPath } from './HttpPath'; + +export interface HttpClient { + get: (httpPath: HttpPath) => Promise; +} diff --git a/packages/v2-network/src/http/HttpPath.ts b/packages/v2-network/src/http/HttpPath.ts new file mode 100644 index 000000000..487f63980 --- /dev/null +++ b/packages/v2-network/src/http/HttpPath.ts @@ -0,0 +1,3 @@ +export interface HttpPath { + get path(): string; +} diff --git a/packages/v2-network/src/http/index.ts b/packages/v2-network/src/http/index.ts new file mode 100644 index 000000000..985f399c0 --- /dev/null +++ b/packages/v2-network/src/http/index.ts @@ -0,0 +1,3 @@ +export * from './FetchHttpClient'; +export * from './HttpClient'; +export * from './HttpPath'; diff --git a/packages/v2-network/src/index.ts b/packages/v2-network/src/index.ts index e69de29bb..c202386ae 100644 --- a/packages/v2-network/src/index.ts +++ b/packages/v2-network/src/index.ts @@ -0,0 +1 @@ +export * from './http'; diff --git a/packages/v2-network/tests/FetchHttpClient.testnet.test.ts b/packages/v2-network/tests/FetchHttpClient.testnet.test.ts new file mode 100644 index 000000000..541ae9640 --- /dev/null +++ b/packages/v2-network/tests/FetchHttpClient.testnet.test.ts @@ -0,0 +1,18 @@ +import { describe, test } from '@jest/globals'; +import { FetchHttpClient } from '../src'; + +describe('FetchHttpClient testnet tests', () => { + test('ok', async () => { + await new FetchHttpClient( + 'https://testnet.vechain.org/', + (request: Request) => { + console.log(request); + return request; + }, + (response: Response) => { + console.log(response); + return response; + } + ).get(); + }); +}); From 5f8a6df8a6885f10e5fc7832ca3b6bd2268b5a39 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Sat, 30 Nov 2024 19:37:36 +0000 Subject: [PATCH 13/98] feat: v2 http dev... --- packages/v2-network/src/index.ts | 1 + packages/v2-network/src/thor/ThorNetworks.ts | 5 ++++ packages/v2-network/src/thor/ThorRequest.ts | 5 ++++ packages/v2-network/src/thor/ThorResponse.ts | 6 ++++ packages/v2-network/src/thor/index.ts | 1 + packages/v2-network/src/thor/node/Peer.ts | 3 ++ .../src/thor/node/RetrieveConnectedPeers.ts | 28 +++++++++++++++++ packages/v2-network/src/thor/node/index.ts | 2 ++ .../tests/FetchHttpClient.testnet.test.ts | 18 ----------- .../http/FetchHttpClient.testnet.test.ts | 30 +++++++++++++++++++ 10 files changed, 81 insertions(+), 18 deletions(-) create mode 100644 packages/v2-network/src/thor/ThorNetworks.ts create mode 100644 packages/v2-network/src/thor/ThorRequest.ts create mode 100644 packages/v2-network/src/thor/ThorResponse.ts create mode 100644 packages/v2-network/src/thor/index.ts create mode 100644 packages/v2-network/src/thor/node/Peer.ts create mode 100644 packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts create mode 100644 packages/v2-network/src/thor/node/index.ts delete mode 100644 packages/v2-network/tests/FetchHttpClient.testnet.test.ts create mode 100644 packages/v2-network/tests/http/FetchHttpClient.testnet.test.ts diff --git a/packages/v2-network/src/index.ts b/packages/v2-network/src/index.ts index c202386ae..9624102dd 100644 --- a/packages/v2-network/src/index.ts +++ b/packages/v2-network/src/index.ts @@ -1 +1,2 @@ export * from './http'; +export * from './thor'; diff --git a/packages/v2-network/src/thor/ThorNetworks.ts b/packages/v2-network/src/thor/ThorNetworks.ts new file mode 100644 index 000000000..59477a80d --- /dev/null +++ b/packages/v2-network/src/thor/ThorNetworks.ts @@ -0,0 +1,5 @@ +enum ThorNetworks { + TESTNET = 'https://testnet.vechain.org/' +} + +export { ThorNetworks }; diff --git a/packages/v2-network/src/thor/ThorRequest.ts b/packages/v2-network/src/thor/ThorRequest.ts new file mode 100644 index 000000000..6d7cefb66 --- /dev/null +++ b/packages/v2-network/src/thor/ThorRequest.ts @@ -0,0 +1,5 @@ +import { type HttpClient } from '../http'; + +export interface ThorRequest { + askTo: (httpClient: HttpClient) => Promise; +} diff --git a/packages/v2-network/src/thor/ThorResponse.ts b/packages/v2-network/src/thor/ThorResponse.ts new file mode 100644 index 000000000..e39ef9fb4 --- /dev/null +++ b/packages/v2-network/src/thor/ThorResponse.ts @@ -0,0 +1,6 @@ +import { type ThorRequest } from './ThorRequest'; + +export interface ThorResponse { + request: ThorRequest; + response: Response; +} diff --git a/packages/v2-network/src/thor/index.ts b/packages/v2-network/src/thor/index.ts new file mode 100644 index 000000000..d0dddb69c --- /dev/null +++ b/packages/v2-network/src/thor/index.ts @@ -0,0 +1 @@ +export * from './node'; diff --git a/packages/v2-network/src/thor/node/Peer.ts b/packages/v2-network/src/thor/node/Peer.ts new file mode 100644 index 000000000..11e2be003 --- /dev/null +++ b/packages/v2-network/src/thor/node/Peer.ts @@ -0,0 +1,3 @@ +export interface Peer { + name: string; +} diff --git a/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts b/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts new file mode 100644 index 000000000..eb72fad9b --- /dev/null +++ b/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts @@ -0,0 +1,28 @@ +import { type HttpClient, type HttpPath } from '../../http'; +import { type ThorRequest } from '../ThorRequest'; +import { type Peer } from './Peer'; + +class RetrieveConnectedPeers implements ThorRequest { + public static readonly PATH: HttpPath = { path: '/node/network/peers' }; + + async askTo(httpClient: HttpClient): Promise { + const response = await httpClient.get(RetrieveConnectedPeers.PATH); + const responseBody: ResponseElement[] = + (await response.json()) as ResponseElement[]; + return responseBody.map((peer) => { + return { name: peer.name }; + }); + } +} + +interface ResponseElement { + name: string; + bestBlockID: string; + totalScore: number; + peerID: string; + netAddr: string; + inbound: boolean; + duration: number; +} + +export { RetrieveConnectedPeers }; diff --git a/packages/v2-network/src/thor/node/index.ts b/packages/v2-network/src/thor/node/index.ts new file mode 100644 index 000000000..cd0500677 --- /dev/null +++ b/packages/v2-network/src/thor/node/index.ts @@ -0,0 +1,2 @@ +export * from './Peer'; +export * from './RetrieveConnectedPeers'; diff --git a/packages/v2-network/tests/FetchHttpClient.testnet.test.ts b/packages/v2-network/tests/FetchHttpClient.testnet.test.ts deleted file mode 100644 index 541ae9640..000000000 --- a/packages/v2-network/tests/FetchHttpClient.testnet.test.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { describe, test } from '@jest/globals'; -import { FetchHttpClient } from '../src'; - -describe('FetchHttpClient testnet tests', () => { - test('ok', async () => { - await new FetchHttpClient( - 'https://testnet.vechain.org/', - (request: Request) => { - console.log(request); - return request; - }, - (response: Response) => { - console.log(response); - return response; - } - ).get(); - }); -}); diff --git a/packages/v2-network/tests/http/FetchHttpClient.testnet.test.ts b/packages/v2-network/tests/http/FetchHttpClient.testnet.test.ts new file mode 100644 index 000000000..a3c1bdf62 --- /dev/null +++ b/packages/v2-network/tests/http/FetchHttpClient.testnet.test.ts @@ -0,0 +1,30 @@ +import { describe, test } from '@jest/globals'; +import { FetchHttpClient, RetrieveConnectedPeers } from '../../src'; +import { ThorNetworks } from '../../src/thor/ThorNetworks'; + +/** + * Test FetchHttpClient class. + * + * @group integration/network/http + */ +describe('FetchHttpClient testnet tests', () => { + test('ok <- get', async () => { + await new FetchHttpClient( + ThorNetworks.TESTNET, + (request: Request) => { + console.log(request); + return request; + }, + (response: Response) => { + console.log(response); + return response; + } + ).get(); + }); + + test('x', async () => { + await new RetrieveConnectedPeers().askTo( + new FetchHttpClient(ThorNetworks.TESTNET) + ); + }); +}); From 58606c77b6189a5dd29c10a3812a94d753f207aa Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Sat, 30 Nov 2024 19:49:32 +0000 Subject: [PATCH 14/98] feat: v2 http dev... --- packages/v2-network/src/thor/node/GetPeersResponse.ts | 3 +++ packages/v2-network/src/thor/node/index.ts | 1 + 2 files changed, 4 insertions(+) create mode 100644 packages/v2-network/src/thor/node/GetPeersResponse.ts diff --git a/packages/v2-network/src/thor/node/GetPeersResponse.ts b/packages/v2-network/src/thor/node/GetPeersResponse.ts new file mode 100644 index 000000000..1dacd9aad --- /dev/null +++ b/packages/v2-network/src/thor/node/GetPeersResponse.ts @@ -0,0 +1,3 @@ +import { type Peer } from './Peer'; + +export interface GetPeersResponse extends Array {} diff --git a/packages/v2-network/src/thor/node/index.ts b/packages/v2-network/src/thor/node/index.ts index cd0500677..47863df63 100644 --- a/packages/v2-network/src/thor/node/index.ts +++ b/packages/v2-network/src/thor/node/index.ts @@ -1,2 +1,3 @@ +export * from './GetPeersResponse'; export * from './Peer'; export * from './RetrieveConnectedPeers'; From 5cdd9a273efd6a37ac9423f7cdddbf458cd5d01e Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Sun, 1 Dec 2024 11:27:30 +0000 Subject: [PATCH 15/98] feat: v2 thor node dev... --- packages/core/src/vcdm/Int.ts | 18 +++++++++++++++ packages/core/src/vcdm/UInt.ts | 23 +++++++++++++++++++ packages/core/src/vcdm/index.ts | 2 ++ .../src/thor/node/GetPeersResponse.ts | 4 ++-- packages/v2-network/src/thor/node/Peer.ts | 3 --- .../v2-network/src/thor/node/PeerResponse.ts | 11 +++++++++ .../src/thor/node/RetrieveConnectedPeers.ts | 15 +++++++++--- packages/v2-network/src/thor/node/index.ts | 2 +- .../http/FetchHttpClient.testnet.test.ts | 3 ++- 9 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 packages/core/src/vcdm/Int.ts create mode 100644 packages/core/src/vcdm/UInt.ts delete mode 100644 packages/v2-network/src/thor/node/Peer.ts create mode 100644 packages/v2-network/src/thor/node/PeerResponse.ts diff --git a/packages/core/src/vcdm/Int.ts b/packages/core/src/vcdm/Int.ts new file mode 100644 index 000000000..4caf84c43 --- /dev/null +++ b/packages/core/src/vcdm/Int.ts @@ -0,0 +1,18 @@ +import { InvalidDataType } from '@vechain/sdk-errors'; + +class Int extends Number { + protected constructor(value: number) { + super(value); + } + + static of(exp: number): Int { + if (Number.isInteger(exp)) { + return new Int(exp); + } + throw new InvalidDataType('Int.of', 'not an integer expression', { + exp: `${exp}` + }); + } +} + +export { Int }; diff --git a/packages/core/src/vcdm/UInt.ts b/packages/core/src/vcdm/UInt.ts new file mode 100644 index 000000000..fdd9b10c1 --- /dev/null +++ b/packages/core/src/vcdm/UInt.ts @@ -0,0 +1,23 @@ +import { Int } from './Int'; +import { InvalidDataType } from '@vechain/sdk-errors'; + +class UInt extends Int { + protected constructor(value: number) { + super(value); + } + + static of(exp: number): UInt { + if (exp >= 0 && Number.isInteger(exp)) { + return new UInt(exp); + } + throw new InvalidDataType( + 'UInt.of', + 'not an unsigned integer expression', + { + exp: `${exp}` + } + ); + } +} + +export { UInt }; diff --git a/packages/core/src/vcdm/index.ts b/packages/core/src/vcdm/index.ts index 9c12b8af5..1905cba33 100644 --- a/packages/core/src/vcdm/index.ts +++ b/packages/core/src/vcdm/index.ts @@ -10,9 +10,11 @@ export * from './hash'; export * from './Hex'; export * from './HexInt'; export * from './HexUInt'; +export * from './Int'; export * from './Mnemonic'; export * from './Quantity'; export * from './Revision'; export * from './BlockId'; export * from './Txt'; +export * from './UInt'; export type * from './VeChainDataModel'; diff --git a/packages/v2-network/src/thor/node/GetPeersResponse.ts b/packages/v2-network/src/thor/node/GetPeersResponse.ts index 1dacd9aad..82b8d4703 100644 --- a/packages/v2-network/src/thor/node/GetPeersResponse.ts +++ b/packages/v2-network/src/thor/node/GetPeersResponse.ts @@ -1,3 +1,3 @@ -import { type Peer } from './Peer'; +import { type PeerResponse } from './PeerResponse'; -export interface GetPeersResponse extends Array {} +export interface GetPeersResponse extends Array {} diff --git a/packages/v2-network/src/thor/node/Peer.ts b/packages/v2-network/src/thor/node/Peer.ts deleted file mode 100644 index 11e2be003..000000000 --- a/packages/v2-network/src/thor/node/Peer.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface Peer { - name: string; -} diff --git a/packages/v2-network/src/thor/node/PeerResponse.ts b/packages/v2-network/src/thor/node/PeerResponse.ts new file mode 100644 index 000000000..fd0e154b0 --- /dev/null +++ b/packages/v2-network/src/thor/node/PeerResponse.ts @@ -0,0 +1,11 @@ +import { type BlockId, type UInt } from '@vechain/sdk-core'; + +export interface PeerResponse { + name: string; + bestBlockID: BlockId; + totalScore: UInt; + peerID: string; + netAddr: string; + inbound: boolean; + duration: UInt; +} diff --git a/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts b/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts index eb72fad9b..35a67ee66 100644 --- a/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts +++ b/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts @@ -1,16 +1,25 @@ import { type HttpClient, type HttpPath } from '../../http'; import { type ThorRequest } from '../ThorRequest'; -import { type Peer } from './Peer'; +import { type PeerResponse } from './PeerResponse'; +import { BlockId, UInt } from '@vechain/sdk-core'; class RetrieveConnectedPeers implements ThorRequest { public static readonly PATH: HttpPath = { path: '/node/network/peers' }; - async askTo(httpClient: HttpClient): Promise { + async askTo(httpClient: HttpClient): Promise { const response = await httpClient.get(RetrieveConnectedPeers.PATH); const responseBody: ResponseElement[] = (await response.json()) as ResponseElement[]; return responseBody.map((peer) => { - return { name: peer.name }; + return { + name: peer.name, + bestBlockID: BlockId.of(peer.bestBlockID), + totalScore: UInt.of(peer.totalScore), + peerID: peer.peerID, + netAddr: peer.netAddr, + inbound: peer.inbound, + duration: UInt.of(peer.duration) + } satisfies PeerResponse; }); } } diff --git a/packages/v2-network/src/thor/node/index.ts b/packages/v2-network/src/thor/node/index.ts index 47863df63..3011e7c47 100644 --- a/packages/v2-network/src/thor/node/index.ts +++ b/packages/v2-network/src/thor/node/index.ts @@ -1,3 +1,3 @@ export * from './GetPeersResponse'; -export * from './Peer'; +export * from './PeerResponse'; export * from './RetrieveConnectedPeers'; diff --git a/packages/v2-network/tests/http/FetchHttpClient.testnet.test.ts b/packages/v2-network/tests/http/FetchHttpClient.testnet.test.ts index a3c1bdf62..52355cac0 100644 --- a/packages/v2-network/tests/http/FetchHttpClient.testnet.test.ts +++ b/packages/v2-network/tests/http/FetchHttpClient.testnet.test.ts @@ -23,8 +23,9 @@ describe('FetchHttpClient testnet tests', () => { }); test('x', async () => { - await new RetrieveConnectedPeers().askTo( + const r = await new RetrieveConnectedPeers().askTo( new FetchHttpClient(ThorNetworks.TESTNET) ); + console.log(r); }); }); From af56fe6592767d249a63f453dfa2e30f21538ced Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Sun, 1 Dec 2024 11:36:58 +0000 Subject: [PATCH 16/98] feat: v2 thor node dev... --- .../src/thor/node/RetrieveConnectedPeers.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts b/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts index 35a67ee66..aa9f3af60 100644 --- a/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts +++ b/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts @@ -2,23 +2,24 @@ import { type HttpClient, type HttpPath } from '../../http'; import { type ThorRequest } from '../ThorRequest'; import { type PeerResponse } from './PeerResponse'; import { BlockId, UInt } from '@vechain/sdk-core'; +import { type GetPeersResponse } from './GetPeersResponse'; class RetrieveConnectedPeers implements ThorRequest { public static readonly PATH: HttpPath = { path: '/node/network/peers' }; - async askTo(httpClient: HttpClient): Promise { + async askTo(httpClient: HttpClient): Promise { const response = await httpClient.get(RetrieveConnectedPeers.PATH); const responseBody: ResponseElement[] = (await response.json()) as ResponseElement[]; - return responseBody.map((peer) => { + return responseBody.map((responseElement) => { return { - name: peer.name, - bestBlockID: BlockId.of(peer.bestBlockID), - totalScore: UInt.of(peer.totalScore), - peerID: peer.peerID, - netAddr: peer.netAddr, - inbound: peer.inbound, - duration: UInt.of(peer.duration) + name: responseElement.name, + bestBlockID: BlockId.of(responseElement.bestBlockID), + totalScore: UInt.of(responseElement.totalScore), + peerID: responseElement.peerID, + netAddr: responseElement.netAddr, + inbound: responseElement.inbound, + duration: UInt.of(responseElement.duration) } satisfies PeerResponse; }); } From 8f7d167761af74c1e20a4af02da383f8d8a38dad Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Mon, 2 Dec 2024 12:53:38 +0000 Subject: [PATCH 17/98] feat: v2 thor node dev... --- packages/v2-network/src/thor/ThorRequest.ts | 10 +++- packages/v2-network/src/thor/ThorResponse.ts | 9 ++-- packages/v2-network/src/thor/index.ts | 3 ++ .../v2-network/src/thor/node/PeerResponse.ts | 44 ++++++++++++++++-- .../src/thor/node/RetrieveConnectedPeers.ts | 46 ++++++++----------- .../http/FetchHttpClient.testnet.test.ts | 9 ++-- 6 files changed, 81 insertions(+), 40 deletions(-) diff --git a/packages/v2-network/src/thor/ThorRequest.ts b/packages/v2-network/src/thor/ThorRequest.ts index 6d7cefb66..76ad64746 100644 --- a/packages/v2-network/src/thor/ThorRequest.ts +++ b/packages/v2-network/src/thor/ThorRequest.ts @@ -1,5 +1,11 @@ import { type HttpClient } from '../http'; +import { type ThorResponse } from './ThorResponse'; -export interface ThorRequest { - askTo: (httpClient: HttpClient) => Promise; +export interface ThorRequest< + RequestClass extends ThorRequest, + ResponseClass +> { + askTo: ( + httpClient: HttpClient + ) => Promise>; } diff --git a/packages/v2-network/src/thor/ThorResponse.ts b/packages/v2-network/src/thor/ThorResponse.ts index e39ef9fb4..e925587c2 100644 --- a/packages/v2-network/src/thor/ThorResponse.ts +++ b/packages/v2-network/src/thor/ThorResponse.ts @@ -1,6 +1,9 @@ import { type ThorRequest } from './ThorRequest'; -export interface ThorResponse { - request: ThorRequest; - response: Response; +export interface ThorResponse< + RequestClass extends ThorRequest, + ResponseClass +> { + request: RequestClass; + response: ResponseClass; } diff --git a/packages/v2-network/src/thor/index.ts b/packages/v2-network/src/thor/index.ts index d0dddb69c..2b4edeabf 100644 --- a/packages/v2-network/src/thor/index.ts +++ b/packages/v2-network/src/thor/index.ts @@ -1 +1,4 @@ export * from './node'; +export * from './ThorNetworks'; +export * from './ThorRequest'; +export * from './ThorResponse'; diff --git a/packages/v2-network/src/thor/node/PeerResponse.ts b/packages/v2-network/src/thor/node/PeerResponse.ts index fd0e154b0..1923b2a6f 100644 --- a/packages/v2-network/src/thor/node/PeerResponse.ts +++ b/packages/v2-network/src/thor/node/PeerResponse.ts @@ -1,11 +1,45 @@ -import { type BlockId, type UInt } from '@vechain/sdk-core'; +import { BlockId, UInt } from '@vechain/sdk-core'; -export interface PeerResponse { +interface PeerResponseJSON { name: string; - bestBlockID: BlockId; - totalScore: UInt; + bestBlockID: string; + totalScore: number; peerID: string; netAddr: string; inbound: boolean; - duration: UInt; + duration: number; } + +class PeerResponse { + readonly name: string; + readonly bestBlockID: BlockId; + readonly totalScore: UInt; + readonly peerID: string; + readonly netAddr: string; + readonly inbound: boolean; + readonly duration: UInt; + + constructor(json: PeerResponseJSON) { + this.name = json.name; + this.bestBlockID = BlockId.of(json.bestBlockID); + this.totalScore = UInt.of(json.totalScore); + this.peerID = json.peerID; + this.netAddr = json.netAddr; + this.inbound = json.inbound; + this.duration = UInt.of(json.duration); + } + + toJSON(): PeerResponseJSON { + return { + name: this.name, + bestBlockID: this.bestBlockID.toString(), + totalScore: this.totalScore.valueOf(), + peerID: this.peerID, + netAddr: this.netAddr, + inbound: this.inbound, + duration: this.duration.valueOf() + }; + } +} + +export { PeerResponse, type PeerResponseJSON }; diff --git a/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts b/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts index aa9f3af60..116c88ce9 100644 --- a/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts +++ b/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts @@ -1,38 +1,30 @@ import { type HttpClient, type HttpPath } from '../../http'; import { type ThorRequest } from '../ThorRequest'; -import { type PeerResponse } from './PeerResponse'; -import { BlockId, UInt } from '@vechain/sdk-core'; +import { PeerResponse, type PeerResponseJSON } from './PeerResponse'; import { type GetPeersResponse } from './GetPeersResponse'; +import { type ThorResponse } from '../ThorResponse'; -class RetrieveConnectedPeers implements ThorRequest { +class RetrieveConnectedPeers + implements ThorRequest +{ public static readonly PATH: HttpPath = { path: '/node/network/peers' }; - async askTo(httpClient: HttpClient): Promise { + async askTo( + httpClient: HttpClient + ): Promise> { const response = await httpClient.get(RetrieveConnectedPeers.PATH); - const responseBody: ResponseElement[] = - (await response.json()) as ResponseElement[]; - return responseBody.map((responseElement) => { - return { - name: responseElement.name, - bestBlockID: BlockId.of(responseElement.bestBlockID), - totalScore: UInt.of(responseElement.totalScore), - peerID: responseElement.peerID, - netAddr: responseElement.netAddr, - inbound: responseElement.inbound, - duration: UInt.of(responseElement.duration) - } satisfies PeerResponse; - }); + const responseBody: PeerResponseJSON[] = + (await response.json()) as PeerResponseJSON[]; + const getPeersResponse: GetPeersResponse = responseBody.map( + (peerResponseJSON) => { + return new PeerResponse(peerResponseJSON); + } + ); + return { + request: this, + response: getPeersResponse + }; } } -interface ResponseElement { - name: string; - bestBlockID: string; - totalScore: number; - peerID: string; - netAddr: string; - inbound: boolean; - duration: number; -} - export { RetrieveConnectedPeers }; diff --git a/packages/v2-network/tests/http/FetchHttpClient.testnet.test.ts b/packages/v2-network/tests/http/FetchHttpClient.testnet.test.ts index 52355cac0..82455261c 100644 --- a/packages/v2-network/tests/http/FetchHttpClient.testnet.test.ts +++ b/packages/v2-network/tests/http/FetchHttpClient.testnet.test.ts @@ -1,6 +1,9 @@ import { describe, test } from '@jest/globals'; -import { FetchHttpClient, RetrieveConnectedPeers } from '../../src'; -import { ThorNetworks } from '../../src/thor/ThorNetworks'; +import { + FetchHttpClient, + RetrieveConnectedPeers, + ThorNetworks +} from '../../src'; /** * Test FetchHttpClient class. @@ -26,6 +29,6 @@ describe('FetchHttpClient testnet tests', () => { const r = await new RetrieveConnectedPeers().askTo( new FetchHttpClient(ThorNetworks.TESTNET) ); - console.log(r); + console.log(JSON.stringify(r, null, 2)); }); }); From 9b231f010783506f5de5ced0ad86703dd2c6a95b Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Mon, 2 Dec 2024 14:26:25 +0000 Subject: [PATCH 18/98] feat: v2 thor node dev... --- .../tests/http/FetchHttpClient.testnet.test.ts | 13 +------------ .../node/RetrieveConnectedPeers.testnet.test.ts | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 12 deletions(-) create mode 100644 packages/v2-network/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts diff --git a/packages/v2-network/tests/http/FetchHttpClient.testnet.test.ts b/packages/v2-network/tests/http/FetchHttpClient.testnet.test.ts index 82455261c..a979a34f6 100644 --- a/packages/v2-network/tests/http/FetchHttpClient.testnet.test.ts +++ b/packages/v2-network/tests/http/FetchHttpClient.testnet.test.ts @@ -1,9 +1,5 @@ import { describe, test } from '@jest/globals'; -import { - FetchHttpClient, - RetrieveConnectedPeers, - ThorNetworks -} from '../../src'; +import { FetchHttpClient, ThorNetworks } from '../../src'; /** * Test FetchHttpClient class. @@ -24,11 +20,4 @@ describe('FetchHttpClient testnet tests', () => { } ).get(); }); - - test('x', async () => { - const r = await new RetrieveConnectedPeers().askTo( - new FetchHttpClient(ThorNetworks.TESTNET) - ); - console.log(JSON.stringify(r, null, 2)); - }); }); diff --git a/packages/v2-network/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts b/packages/v2-network/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts new file mode 100644 index 000000000..522a6a1ea --- /dev/null +++ b/packages/v2-network/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts @@ -0,0 +1,15 @@ +import { describe, test } from '@jest/globals'; +import { + FetchHttpClient, + RetrieveConnectedPeers, + ThorNetworks +} from '../../../src'; + +describe('RetrieveConnectedPeers', () => { + test('GetPeersResponse <- askTo', async () => { + const r = await new RetrieveConnectedPeers().askTo( + new FetchHttpClient(ThorNetworks.TESTNET) + ); + console.log(JSON.stringify(r, null, 2)); + }); +}); From 73f1d5474dddc28755297ef1d250372817a44c2b Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Mon, 2 Dec 2024 16:57:19 +0000 Subject: [PATCH 19/98] feat: v2 thor account dev... --- packages/v2-network/src/thor/ThorNetworks.ts | 1 + .../src/thor/accounts/GetAccountResponse.ts | 29 +++++++++++ .../thor/accounts/RetrieveAccountDetails.ts | 51 +++++++++++++++++++ .../v2-network/src/thor/accounts/index.ts | 2 + packages/v2-network/src/thor/index.ts | 1 + .../src/thor/node/RetrieveConnectedPeers.ts | 4 +- .../RetrieveAccountDetails.testnet.test.ts | 16 ++++++ .../RetrieveConnectedPeers.testnet.test.ts | 4 +- 8 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 packages/v2-network/src/thor/accounts/GetAccountResponse.ts create mode 100644 packages/v2-network/src/thor/accounts/RetrieveAccountDetails.ts create mode 100644 packages/v2-network/src/thor/accounts/index.ts create mode 100644 packages/v2-network/tests/thor/accounts/RetrieveAccountDetails.testnet.test.ts diff --git a/packages/v2-network/src/thor/ThorNetworks.ts b/packages/v2-network/src/thor/ThorNetworks.ts index 59477a80d..9cece1c46 100644 --- a/packages/v2-network/src/thor/ThorNetworks.ts +++ b/packages/v2-network/src/thor/ThorNetworks.ts @@ -1,4 +1,5 @@ enum ThorNetworks { + MAINNET = 'https://mainnet.vechain.org/', TESTNET = 'https://testnet.vechain.org/' } diff --git a/packages/v2-network/src/thor/accounts/GetAccountResponse.ts b/packages/v2-network/src/thor/accounts/GetAccountResponse.ts new file mode 100644 index 000000000..fbf9a140a --- /dev/null +++ b/packages/v2-network/src/thor/accounts/GetAccountResponse.ts @@ -0,0 +1,29 @@ +import { Quantity, VET, VTHO } from '@vechain/sdk-core'; + +interface GetAccountResponseJSON { + balance: string; + energy: string; + hasCode: boolean; +} + +class GetAccountResponse { + balance: VET; + energy: VTHO; + hasCode: boolean; + + constructor(json: GetAccountResponseJSON) { + this.balance = VET.of(json.balance); + this.energy = VTHO.of(json.energy); + this.hasCode = json.hasCode; + } + + toJSON(): GetAccountResponseJSON { + return { + balance: Quantity.of(this.balance.wei).toString(), + energy: Quantity.of(this.energy.wei).toString(), + hasCode: this.hasCode + }; + } +} + +export { GetAccountResponse, type GetAccountResponseJSON }; diff --git a/packages/v2-network/src/thor/accounts/RetrieveAccountDetails.ts b/packages/v2-network/src/thor/accounts/RetrieveAccountDetails.ts new file mode 100644 index 000000000..e3cb1e52b --- /dev/null +++ b/packages/v2-network/src/thor/accounts/RetrieveAccountDetails.ts @@ -0,0 +1,51 @@ +import { type HttpClient, type HttpPath } from '../../http'; +import { type ThorRequest } from '../ThorRequest'; +import { type ThorResponse } from '../ThorResponse'; +import { + GetAccountResponse, + type GetAccountResponseJSON +} from './GetAccountResponse'; +import { type Address } from '@vechain/sdk-core'; + +class RetrieveAccountDetails + implements ThorRequest +{ + public readonly path: RetrieveAccountDetailsPath; + + constructor(path: RetrieveAccountDetailsPath) { + this.path = path; + } + + async askTo( + httpClient: HttpClient + ): Promise> { + const response = await httpClient.get(this.path); + const responseBody = (await response.json()) as GetAccountResponseJSON; + return { + request: this, + response: new GetAccountResponse(responseBody) + }; + } + + static of(address: Address): RetrieveAccountDetails { + return new RetrieveAccountDetails( + new RetrieveAccountDetailsPath(address) + ); + } +} + +class RetrieveAccountDetailsPath implements HttpPath { + static readonly PATH = '/accounts'; + + readonly address: Address; + + constructor(address: Address) { + this.address = address; + } + + get path(): string { + return `${RetrieveAccountDetailsPath.PATH}/${this.address.toString()}`; + } +} + +export { RetrieveAccountDetails, RetrieveAccountDetailsPath }; diff --git a/packages/v2-network/src/thor/accounts/index.ts b/packages/v2-network/src/thor/accounts/index.ts new file mode 100644 index 000000000..8211dfcd1 --- /dev/null +++ b/packages/v2-network/src/thor/accounts/index.ts @@ -0,0 +1,2 @@ +export * from './GetAccountResponse'; +export * from './RetrieveAccountDetails'; diff --git a/packages/v2-network/src/thor/index.ts b/packages/v2-network/src/thor/index.ts index 2b4edeabf..ac65b1b95 100644 --- a/packages/v2-network/src/thor/index.ts +++ b/packages/v2-network/src/thor/index.ts @@ -1,3 +1,4 @@ +export * from './accounts'; export * from './node'; export * from './ThorNetworks'; export * from './ThorRequest'; diff --git a/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts b/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts index 116c88ce9..ca5b6d01c 100644 --- a/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts +++ b/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts @@ -1,7 +1,7 @@ -import { type HttpClient, type HttpPath } from '../../http'; -import { type ThorRequest } from '../ThorRequest'; import { PeerResponse, type PeerResponseJSON } from './PeerResponse'; import { type GetPeersResponse } from './GetPeersResponse'; +import { type HttpClient, type HttpPath } from '../../http'; +import { type ThorRequest } from '../ThorRequest'; import { type ThorResponse } from '../ThorResponse'; class RetrieveConnectedPeers diff --git a/packages/v2-network/tests/thor/accounts/RetrieveAccountDetails.testnet.test.ts b/packages/v2-network/tests/thor/accounts/RetrieveAccountDetails.testnet.test.ts new file mode 100644 index 000000000..81827e944 --- /dev/null +++ b/packages/v2-network/tests/thor/accounts/RetrieveAccountDetails.testnet.test.ts @@ -0,0 +1,16 @@ +import { describe, test } from '@jest/globals'; +import { + FetchHttpClient, + RetrieveAccountDetails, + ThorNetworks +} from '../../../src'; +import { Address } from '@vechain/sdk-core'; + +describe('RetrieveAccountDetails testnet tests', () => { + test('ok <- askTo', async () => { + const r = await RetrieveAccountDetails.of( + Address.of('0x0000000000000000000000000000456E65726779') + ).askTo(new FetchHttpClient(ThorNetworks.TESTNET)); + console.log(JSON.stringify(r, null, 2)); + }); +}); diff --git a/packages/v2-network/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts b/packages/v2-network/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts index 522a6a1ea..539cdaa4a 100644 --- a/packages/v2-network/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts +++ b/packages/v2-network/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts @@ -5,8 +5,8 @@ import { ThorNetworks } from '../../../src'; -describe('RetrieveConnectedPeers', () => { - test('GetPeersResponse <- askTo', async () => { +describe('RetrieveConnectedPeers testnet tests', () => { + test('ok <- askTo', async () => { const r = await new RetrieveConnectedPeers().askTo( new FetchHttpClient(ThorNetworks.TESTNET) ); From d9eafd37b1ab947438f0e74d633e73747e809a14 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Mon, 2 Dec 2024 18:05:28 +0000 Subject: [PATCH 20/98] feat: v2 thor account dev... --- .../src/thor/blocks/RegularBlockResponse..ts | 64 +++++++++++++++++++ .../src/thor/blocks/RetrieveBlock.ts | 50 +++++++++++++++ packages/v2-network/src/thor/blocks/index.ts | 2 + packages/v2-network/src/thor/index.ts | 1 + .../thor/blocks/RetrieveBlock.testnet.test.ts | 12 ++++ 5 files changed, 129 insertions(+) create mode 100644 packages/v2-network/src/thor/blocks/RegularBlockResponse..ts create mode 100644 packages/v2-network/src/thor/blocks/RetrieveBlock.ts create mode 100644 packages/v2-network/src/thor/blocks/index.ts create mode 100644 packages/v2-network/tests/thor/blocks/RetrieveBlock.testnet.test.ts diff --git a/packages/v2-network/src/thor/blocks/RegularBlockResponse..ts b/packages/v2-network/src/thor/blocks/RegularBlockResponse..ts new file mode 100644 index 000000000..c4e72a9e7 --- /dev/null +++ b/packages/v2-network/src/thor/blocks/RegularBlockResponse..ts @@ -0,0 +1,64 @@ +interface RegularBlockResponseJSON { + number: number; + id: string; + size: number; + parentID: string; + timestamp: bigint; + gasLimit: number; + beneficiary: string; + gasUsed: number; + totalScore: number; + txsRoot: string; + txsFeatures: number; + stateRoot: string; + receiptsRoot: string; + com: boolean; + signer: string; + isTrunk: boolean; + isFinalized: boolean; + transactions: string[]; +} + +class RegularBlockResponse { + readonly number: number; + readonly id: string; + readonly size: number; + readonly parentID: string; + readonly timestamp: bigint; + readonly gasLimit: number; + readonly beneficiary: string; + readonly gasUsed: number; + readonly totalScore: number; + readonly txsRoot: string; + readonly txsFeatures: number; + readonly stateRoot: string; + readonly receiptsRoot: string; + readonly com: boolean; + readonly signer: string; + readonly isTrunk: boolean; + readonly isFinalized: boolean; + readonly transactions: string[]; + + constructor(json: RegularBlockResponseJSON) { + this.number = json.number; + this.id = json.id; + this.size = json.size; + this.parentID = json.parentID; + this.timestamp = json.timestamp; + this.gasLimit = json.gasLimit; + this.beneficiary = json.beneficiary; + this.gasUsed = json.gasUsed; + this.totalScore = json.totalScore; + this.txsRoot = json.txsRoot; + this.txsFeatures = json.txsFeatures; + this.stateRoot = json.stateRoot; + this.receiptsRoot = json.receiptsRoot; + this.com = json.com; + this.signer = json.signer; + this.isTrunk = json.isTrunk; + this.isFinalized = json.isFinalized; + this.transactions = json.transactions; + } +} + +export { RegularBlockResponse, type RegularBlockResponseJSON }; diff --git a/packages/v2-network/src/thor/blocks/RetrieveBlock.ts b/packages/v2-network/src/thor/blocks/RetrieveBlock.ts new file mode 100644 index 000000000..2b779d3f1 --- /dev/null +++ b/packages/v2-network/src/thor/blocks/RetrieveBlock.ts @@ -0,0 +1,50 @@ +import { type HttpClient, type HttpPath } from '../../http'; +import { type ThorRequest } from '../ThorRequest'; +import { type ThorResponse } from '../ThorResponse'; +import { + RegularBlockResponse, + type RegularBlockResponseJSON +} from './RegularBlockResponse.'; +import { type Revision } from '@vechain/sdk-core'; + +class RetrieveBlock + implements ThorRequest +{ + public readonly path: RetrieveBlockPath; + + constructor(path: RetrieveBlockPath) { + this.path = path; + } + + async askTo( + httpClient: HttpClient + ): Promise> { + const response = await httpClient.get(this.path); + const responseBody = + (await response.json()) as RegularBlockResponseJSON; + return { + request: this, + response: new RegularBlockResponse(responseBody) + }; + } + + static of(revision: Revision): RetrieveBlock { + return new RetrieveBlock(new RetrieveBlockPath(revision)); + } +} + +class RetrieveBlockPath implements HttpPath { + static readonly Path = '/blocks'; + + readonly revision: Revision; + + constructor(revision: Revision) { + this.revision = revision; + } + + get path(): string { + return `${RetrieveBlockPath.Path}/${this.revision}`; + } +} + +export { RetrieveBlock, RetrieveBlockPath }; diff --git a/packages/v2-network/src/thor/blocks/index.ts b/packages/v2-network/src/thor/blocks/index.ts new file mode 100644 index 000000000..99bfdd062 --- /dev/null +++ b/packages/v2-network/src/thor/blocks/index.ts @@ -0,0 +1,2 @@ +export * from './RetrieveBlock'; +export * from './RegularBlockResponse.'; diff --git a/packages/v2-network/src/thor/index.ts b/packages/v2-network/src/thor/index.ts index ac65b1b95..bc1c55361 100644 --- a/packages/v2-network/src/thor/index.ts +++ b/packages/v2-network/src/thor/index.ts @@ -1,5 +1,6 @@ export * from './accounts'; export * from './node'; +export * from './blocks'; export * from './ThorNetworks'; export * from './ThorRequest'; export * from './ThorResponse'; diff --git a/packages/v2-network/tests/thor/blocks/RetrieveBlock.testnet.test.ts b/packages/v2-network/tests/thor/blocks/RetrieveBlock.testnet.test.ts new file mode 100644 index 000000000..c9235db7b --- /dev/null +++ b/packages/v2-network/tests/thor/blocks/RetrieveBlock.testnet.test.ts @@ -0,0 +1,12 @@ +import { describe, test } from '@jest/globals'; +import { FetchHttpClient, RetrieveBlock, ThorNetworks } from '../../../src'; +import { Revision } from '@vechain/sdk-core'; + +describe('RetrieveBlock testnet tests', () => { + test('ok <- askTo', async () => { + const r = await RetrieveBlock.of(Revision.BEST).askTo( + new FetchHttpClient(ThorNetworks.TESTNET) + ); + console.log(JSON.stringify(r, null, 2)); + }); +}); From 96eb3b1d822e456ebfe2b19526768e14f3d87356 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 3 Dec 2024 11:22:11 +0000 Subject: [PATCH 21/98] feat: v2 thor account dev... --- docs/diagrams/v2/network/http/http.md | 15 +++++ .../src/thor/accounts/ContractBytecode.ts | 21 +++++++ .../thor/accounts/RetrieveAccountDetails.ts | 6 +- .../thor/accounts/RetrieveContractBytecode.ts | 49 +++++++++++++++++ .../accounts/RetrieveStoragePositionValue.ts | 55 +++++++++++++++++++ .../src/thor/accounts/StoragePositionValue.ts | 21 +++++++ .../v2-network/src/thor/accounts/index.ts | 4 ++ .../src/thor/blocks/RetrieveBlock.ts | 4 +- .../src/thor/node/RetrieveConnectedPeers.ts | 2 +- .../RetrieveAccountDetails.testnet.test.ts | 2 +- .../RetrieveContractBytecode.testnet.test.ts | 16 ++++++ ...trieveStoragePositionValue.testnet.test.ts | 19 +++++++ .../thor/blocks/RetrieveBlock.testnet.test.ts | 2 +- .../RetrieveConnectedPeers.testnet.test.ts | 2 +- 14 files changed, 207 insertions(+), 11 deletions(-) create mode 100644 docs/diagrams/v2/network/http/http.md create mode 100644 packages/v2-network/src/thor/accounts/ContractBytecode.ts create mode 100644 packages/v2-network/src/thor/accounts/RetrieveContractBytecode.ts create mode 100644 packages/v2-network/src/thor/accounts/RetrieveStoragePositionValue.ts create mode 100644 packages/v2-network/src/thor/accounts/StoragePositionValue.ts create mode 100644 packages/v2-network/tests/thor/accounts/RetrieveContractBytecode.testnet.test.ts create mode 100644 packages/v2-network/tests/thor/accounts/RetrieveStoragePositionValue.testnet.test.ts diff --git a/docs/diagrams/v2/network/http/http.md b/docs/diagrams/v2/network/http/http.md new file mode 100644 index 000000000..aab975465 --- /dev/null +++ b/docs/diagrams/v2/network/http/http.md @@ -0,0 +1,15 @@ +```mermaid +classDiagram + class FetchHttpClient { + baseURL: string + + } + class HttpClient { + get(httpPath: HttpPath): Promise~Response~ + } + class HttpPath { + <> + path: string + } + HttpPath o-- HttpClient +``` diff --git a/packages/v2-network/src/thor/accounts/ContractBytecode.ts b/packages/v2-network/src/thor/accounts/ContractBytecode.ts new file mode 100644 index 000000000..a6cac2c9b --- /dev/null +++ b/packages/v2-network/src/thor/accounts/ContractBytecode.ts @@ -0,0 +1,21 @@ +import { HexUInt } from '@vechain/sdk-core'; + +interface ContractBytecodeJSON { + code: string; +} + +class ContractBytecode { + readonly code: HexUInt; + + constructor(json: ContractBytecodeJSON) { + this.code = HexUInt.of(json.code); + } + + toJSON(): ContractBytecodeJSON { + return { + code: this.code.toString() + }; + } +} + +export { ContractBytecode, type ContractBytecodeJSON }; diff --git a/packages/v2-network/src/thor/accounts/RetrieveAccountDetails.ts b/packages/v2-network/src/thor/accounts/RetrieveAccountDetails.ts index e3cb1e52b..ad9d499f2 100644 --- a/packages/v2-network/src/thor/accounts/RetrieveAccountDetails.ts +++ b/packages/v2-network/src/thor/accounts/RetrieveAccountDetails.ts @@ -10,7 +10,7 @@ import { type Address } from '@vechain/sdk-core'; class RetrieveAccountDetails implements ThorRequest { - public readonly path: RetrieveAccountDetailsPath; + readonly path: RetrieveAccountDetailsPath; constructor(path: RetrieveAccountDetailsPath) { this.path = path; @@ -35,8 +35,6 @@ class RetrieveAccountDetails } class RetrieveAccountDetailsPath implements HttpPath { - static readonly PATH = '/accounts'; - readonly address: Address; constructor(address: Address) { @@ -44,7 +42,7 @@ class RetrieveAccountDetailsPath implements HttpPath { } get path(): string { - return `${RetrieveAccountDetailsPath.PATH}/${this.address.toString()}`; + return `/accounts/${this.address}`; } } diff --git a/packages/v2-network/src/thor/accounts/RetrieveContractBytecode.ts b/packages/v2-network/src/thor/accounts/RetrieveContractBytecode.ts new file mode 100644 index 000000000..49e20e9e8 --- /dev/null +++ b/packages/v2-network/src/thor/accounts/RetrieveContractBytecode.ts @@ -0,0 +1,49 @@ +import { + ContractBytecode, + type ContractBytecodeJSON +} from './ContractBytecode'; +import { type ThorRequest } from '../ThorRequest'; +import { type HttpClient, type HttpPath } from '../../http'; +import type { Address } from '@vechain/sdk-core'; +import { type ThorResponse } from '../ThorResponse'; + +class RetrieveContractBytecode + implements ThorRequest +{ + readonly path: RetrieveContractBytecodePath; + + constructor(path: RetrieveContractBytecodePath) { + this.path = path; + } + + async askTo( + httpClient: HttpClient + ): Promise> { + const response = await httpClient.get(this.path); + const responseBody = (await response.json()) as ContractBytecodeJSON; + return { + request: this, + response: new ContractBytecode(responseBody) + }; + } + + static of(address: Address): RetrieveContractBytecode { + return new RetrieveContractBytecode( + new RetrieveContractBytecodePath(address) + ); + } +} + +class RetrieveContractBytecodePath implements HttpPath { + readonly address: Address; + + constructor(address: Address) { + this.address = address; + } + + get path(): string { + return `/accounts/${this.address}/code`; + } +} + +export { RetrieveContractBytecode, RetrieveContractBytecodePath }; diff --git a/packages/v2-network/src/thor/accounts/RetrieveStoragePositionValue.ts b/packages/v2-network/src/thor/accounts/RetrieveStoragePositionValue.ts new file mode 100644 index 000000000..e1389f418 --- /dev/null +++ b/packages/v2-network/src/thor/accounts/RetrieveStoragePositionValue.ts @@ -0,0 +1,55 @@ +import { type HttpClient, type HttpPath } from '../../http'; +import { type Address, type BlockId } from '@vechain/sdk-core'; +import { type ThorRequest } from '../ThorRequest'; +import { + StoragePositionValue, + type StoragePositionValueJSON +} from './StoragePositionValue'; +import { type ThorResponse } from '../ThorResponse'; + +class RetrieveStoragePositionValue + implements ThorRequest +{ + readonly path: RetrieveStoragePositionValuePath; + + constructor(path: RetrieveStoragePositionValuePath) { + this.path = path; + } + + async askTo( + httpClient: HttpClient + ): Promise< + ThorResponse + > { + const response = await httpClient.get(this.path); + const responseBody = + (await response.json()) as StoragePositionValueJSON; + return { + request: this, + response: new StoragePositionValue(responseBody) + }; + } + + static of(address: Address, key: BlockId): RetrieveStoragePositionValue { + return new RetrieveStoragePositionValue( + new RetrieveStoragePositionValuePath(address, key) + ); + } +} + +class RetrieveStoragePositionValuePath implements HttpPath { + readonly address: Address; + + readonly key: BlockId; + + constructor(address: Address, key: BlockId) { + this.address = address; + this.key = key; + } + + get path(): string { + return `/accounts/${this.address}/storage/${this.key}`; + } +} + +export { RetrieveStoragePositionValue, RetrieveStoragePositionValuePath }; diff --git a/packages/v2-network/src/thor/accounts/StoragePositionValue.ts b/packages/v2-network/src/thor/accounts/StoragePositionValue.ts new file mode 100644 index 000000000..cadcba02a --- /dev/null +++ b/packages/v2-network/src/thor/accounts/StoragePositionValue.ts @@ -0,0 +1,21 @@ +import { HexUInt } from '@vechain/sdk-core'; + +interface StoragePositionValueJSON { + value: string; +} + +class StoragePositionValue { + readonly value: HexUInt; + + constructor(json: StoragePositionValueJSON) { + this.value = HexUInt.of(json.value); + } + + toJSON(): StoragePositionValueJSON { + return { + value: this.value.toString() + }; + } +} + +export { StoragePositionValue, type StoragePositionValueJSON }; diff --git a/packages/v2-network/src/thor/accounts/index.ts b/packages/v2-network/src/thor/accounts/index.ts index 8211dfcd1..47cb6480c 100644 --- a/packages/v2-network/src/thor/accounts/index.ts +++ b/packages/v2-network/src/thor/accounts/index.ts @@ -1,2 +1,6 @@ +export * from './ContractBytecode'; export * from './GetAccountResponse'; export * from './RetrieveAccountDetails'; +export * from './RetrieveContractBytecode'; +export * from './RetrieveStoragePositionValue'; +export * from './StoragePositionValue'; diff --git a/packages/v2-network/src/thor/blocks/RetrieveBlock.ts b/packages/v2-network/src/thor/blocks/RetrieveBlock.ts index 2b779d3f1..cf4813b79 100644 --- a/packages/v2-network/src/thor/blocks/RetrieveBlock.ts +++ b/packages/v2-network/src/thor/blocks/RetrieveBlock.ts @@ -34,8 +34,6 @@ class RetrieveBlock } class RetrieveBlockPath implements HttpPath { - static readonly Path = '/blocks'; - readonly revision: Revision; constructor(revision: Revision) { @@ -43,7 +41,7 @@ class RetrieveBlockPath implements HttpPath { } get path(): string { - return `${RetrieveBlockPath.Path}/${this.revision}`; + return `/blocks/${this.revision}`; } } diff --git a/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts b/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts index ca5b6d01c..1ed8435cc 100644 --- a/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts +++ b/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts @@ -7,7 +7,7 @@ import { type ThorResponse } from '../ThorResponse'; class RetrieveConnectedPeers implements ThorRequest { - public static readonly PATH: HttpPath = { path: '/node/network/peers' }; + private static readonly PATH: HttpPath = { path: '/node/network/peers' }; async askTo( httpClient: HttpClient diff --git a/packages/v2-network/tests/thor/accounts/RetrieveAccountDetails.testnet.test.ts b/packages/v2-network/tests/thor/accounts/RetrieveAccountDetails.testnet.test.ts index 81827e944..5ffe3d48b 100644 --- a/packages/v2-network/tests/thor/accounts/RetrieveAccountDetails.testnet.test.ts +++ b/packages/v2-network/tests/thor/accounts/RetrieveAccountDetails.testnet.test.ts @@ -7,7 +7,7 @@ import { import { Address } from '@vechain/sdk-core'; describe('RetrieveAccountDetails testnet tests', () => { - test('ok <- askTo', async () => { + test('ok <- askTo', async () => { const r = await RetrieveAccountDetails.of( Address.of('0x0000000000000000000000000000456E65726779') ).askTo(new FetchHttpClient(ThorNetworks.TESTNET)); diff --git a/packages/v2-network/tests/thor/accounts/RetrieveContractBytecode.testnet.test.ts b/packages/v2-network/tests/thor/accounts/RetrieveContractBytecode.testnet.test.ts new file mode 100644 index 000000000..014c643cb --- /dev/null +++ b/packages/v2-network/tests/thor/accounts/RetrieveContractBytecode.testnet.test.ts @@ -0,0 +1,16 @@ +import { describe, test } from '@jest/globals'; +import { Address } from '@vechain/sdk-core'; +import { + RetrieveContractBytecode, + FetchHttpClient, + ThorNetworks +} from '../../../src'; + +describe('RetrieveContractBytecode testnet tests', () => { + test('ok <- askTo', async () => { + const r = await RetrieveContractBytecode.of( + Address.of('0x0000000000000000000000000000456E65726779') + ).askTo(new FetchHttpClient(ThorNetworks.TESTNET)); + console.log(JSON.stringify(r, null, 2)); + }); +}); diff --git a/packages/v2-network/tests/thor/accounts/RetrieveStoragePositionValue.testnet.test.ts b/packages/v2-network/tests/thor/accounts/RetrieveStoragePositionValue.testnet.test.ts new file mode 100644 index 000000000..aa179bc5b --- /dev/null +++ b/packages/v2-network/tests/thor/accounts/RetrieveStoragePositionValue.testnet.test.ts @@ -0,0 +1,19 @@ +import { describe, test } from '@jest/globals'; +import { Address, BlockId } from '@vechain/sdk-core'; +import { + FetchHttpClient, + RetrieveStoragePositionValue, + ThorNetworks +} from '../../../src'; + +describe('RetrieveStoragePositionValue testnet tests', () => { + test('ok <- askTo', async () => { + const r = await RetrieveStoragePositionValue.of( + Address.of('0x93Ae8aab337E58A6978E166f8132F59652cA6C56'), + BlockId.of( + '0x0000000000000000000000000000000000000000000000000000000000000001' + ) + ).askTo(new FetchHttpClient(ThorNetworks.TESTNET)); + console.log(JSON.stringify(r, null, 2)); + }); +}); diff --git a/packages/v2-network/tests/thor/blocks/RetrieveBlock.testnet.test.ts b/packages/v2-network/tests/thor/blocks/RetrieveBlock.testnet.test.ts index c9235db7b..5988df353 100644 --- a/packages/v2-network/tests/thor/blocks/RetrieveBlock.testnet.test.ts +++ b/packages/v2-network/tests/thor/blocks/RetrieveBlock.testnet.test.ts @@ -3,7 +3,7 @@ import { FetchHttpClient, RetrieveBlock, ThorNetworks } from '../../../src'; import { Revision } from '@vechain/sdk-core'; describe('RetrieveBlock testnet tests', () => { - test('ok <- askTo', async () => { + test('ok <- askTo', async () => { const r = await RetrieveBlock.of(Revision.BEST).askTo( new FetchHttpClient(ThorNetworks.TESTNET) ); diff --git a/packages/v2-network/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts b/packages/v2-network/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts index 539cdaa4a..2c560ed47 100644 --- a/packages/v2-network/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts +++ b/packages/v2-network/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts @@ -6,7 +6,7 @@ import { } from '../../../src'; describe('RetrieveConnectedPeers testnet tests', () => { - test('ok <- askTo', async () => { + test('ok <- askTo', async () => { const r = await new RetrieveConnectedPeers().askTo( new FetchHttpClient(ThorNetworks.TESTNET) ); From cc9e7284ba3192a9e4ff028c998a8e40b2ea8086 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 3 Dec 2024 11:57:57 +0000 Subject: [PATCH 22/98] feat: v2 thor account dev... --- docs/diagrams/v2/network/http/http.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/docs/diagrams/v2/network/http/http.md b/docs/diagrams/v2/network/http/http.md index aab975465..8f85fb34e 100644 --- a/docs/diagrams/v2/network/http/http.md +++ b/docs/diagrams/v2/network/http/http.md @@ -2,14 +2,27 @@ classDiagram class FetchHttpClient { baseURL: string - + onRequest: OnRequest + onResponse: OnResponse } class HttpClient { - get(httpPath: HttpPath): Promise~Response~ + <> + get(httpPath: HttpPath) Promise~Response~ } class HttpPath { <> path: string } - HttpPath o-- HttpClient + class OnRequest { + <> + onRequest(request: Request) Request + } + class OnResponse{ + <> + onResponse(response: Response) Response + } + HttpPath <-- HttpClient + HttpClient <|.. FetchHttpClient + FetchHttpClient --* OnRequest + FetchHttpClient --* OnResponse ``` From f99f3f5c3b601efe9278ff0beb2b4a150ef1242e Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 3 Dec 2024 12:10:29 +0000 Subject: [PATCH 23/98] feat: v2 thor account dev... --- docs/diagrams/v2/network/thor/thor.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 docs/diagrams/v2/network/thor/thor.md diff --git a/docs/diagrams/v2/network/thor/thor.md b/docs/diagrams/v2/network/thor/thor.md new file mode 100644 index 000000000..a5dace1ca --- /dev/null +++ b/docs/diagrams/v2/network/thor/thor.md @@ -0,0 +1,18 @@ +```mermaid +classDiagram + class ThorNetworks { + <> + MAINNET: string + TESTNET: string + } + class ThorRequest~RequestClass~ { + <> + askTo(httpClient: HttpClient Promise~ThorResponse~ResponseClass~~; + } + class ThorResponse~ResponseClass~ { + <> + request: ThorRequest~RequestClass~ + response: ResponseClass + } + ThorRequest <-- ThorResponse +``` From 81610c6c4410d98a99168ed69a67ce5b032724ca Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 3 Dec 2024 16:40:56 +0000 Subject: [PATCH 24/98] feat: v2 thor account dev... --- docs/diagrams/v2/network/thor/node/node.md | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 docs/diagrams/v2/network/thor/node/node.md diff --git a/docs/diagrams/v2/network/thor/node/node.md b/docs/diagrams/v2/network/thor/node/node.md new file mode 100644 index 000000000..005fa23cf --- /dev/null +++ b/docs/diagrams/v2/network/thor/node/node.md @@ -0,0 +1,35 @@ +```mermaid +classDiagram + class Array~PeerResponse~ { + } + class GetPeersResponse{ + <> + } + class PeerResponse { + bestBlockID: BlockId + duration: UInt + inbound: boolean + name: string + netAddr: string + peerID: string + totalScore: UInt + + } + class RetrieveConnectedPeers { + + } + class ThorRequest~RetrieveConnectedPeers~ { + <> + askTo(httpClient: HttpClient Promise~ThorResponse~GetPeersResponse~~; + } + class ThorResponse~RetrieveConnectedPeers~ { + <> + request: ThorRequest~RequestClass~ + response: GetPeersResponse + } + Array~PeerResponse~ <|-- GetPeersResponse + PeerResponse o-- Array~PeerResponse~ + ThorRequest~RetrieveConnectedPeers~ <|.. RetrieveConnectedPeers + GetPeersResponse *-- ThorResponse~RetrieveConnectedPeers~ + ThorResponse~RetrieveConnectedPeers~ --* ThorRequest +``` From c0c2b73aa0bea2865a26e9c0532ea6fdc0c1dca1 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 3 Dec 2024 16:48:09 +0000 Subject: [PATCH 25/98] feat: v2 thor account dev... --- .../v2/network/thor/node/node-module.md | 36 ------------------- docs/diagrams/v2/network/thor/node/node.md | 30 +++++++++------- 2 files changed, 18 insertions(+), 48 deletions(-) delete mode 100644 docs/diagrams/v2/network/thor/node/node-module.md diff --git a/docs/diagrams/v2/network/thor/node/node-module.md b/docs/diagrams/v2/network/thor/node/node-module.md deleted file mode 100644 index 3257ad265..000000000 --- a/docs/diagrams/v2/network/thor/node/node-module.md +++ /dev/null @@ -1,36 +0,0 @@ -```mermaid -classDiagram - class HttpClient { - <> - } - class ThorRequest~Request~ { - <> - ThorResponse~Request~ askTo(HttpClient httpClient) - } - class ThorResponse~Response~ { - <> - ThorRequest~Request~ request - Response response - } - namespace Request { - class RetrieveConnectedPeers { - } - } - namespace Response { - class GetPeersResponse { - string name - BlockID bestBlockID - UInt totalScore - string netAddr - boolean inbound - UInt duration - } - } - - HttpClient o-- ThorRequest - - ThorRequest <|.. RetrieveConnectedPeers - ThorResponse <|.. GetPeersResponse - - ThorRequest --* ThorResponse -``` diff --git a/docs/diagrams/v2/network/thor/node/node.md b/docs/diagrams/v2/network/thor/node/node.md index 005fa23cf..fa62bc527 100644 --- a/docs/diagrams/v2/network/thor/node/node.md +++ b/docs/diagrams/v2/network/thor/node/node.md @@ -2,7 +2,7 @@ classDiagram class Array~PeerResponse~ { } - class GetPeersResponse{ + class GetPeersResponse { <> } class PeerResponse { @@ -13,23 +13,29 @@ classDiagram netAddr: string peerID: string totalScore: UInt - } class RetrieveConnectedPeers { - } - class ThorRequest~RetrieveConnectedPeers~ { - <> - askTo(httpClient: HttpClient Promise~ThorResponse~GetPeersResponse~~; + namespace http { + class HttpClient { + <> + } } - class ThorResponse~RetrieveConnectedPeers~ { - <> - request: ThorRequest~RequestClass~ - response: GetPeersResponse + namespace thor { + class ThorRequest~RetrieveConnectedPeers~ { + <> + askTo(httpClient: HttpClient Promise~ThorResponse~GetPeersResponse~~; + } + class ThorResponse~RetrieveConnectedPeers~ { + <> + request: ThorRequest~RequestClass~ + response: GetPeersResponse + } } Array~PeerResponse~ <|-- GetPeersResponse + GetPeersResponse *-- ThorResponse~RetrieveConnectedPeers~ + HttpClient <-- ThorRequest~RetrieveConnectedPeers~ PeerResponse o-- Array~PeerResponse~ ThorRequest~RetrieveConnectedPeers~ <|.. RetrieveConnectedPeers - GetPeersResponse *-- ThorResponse~RetrieveConnectedPeers~ - ThorResponse~RetrieveConnectedPeers~ --* ThorRequest + ThorResponse~RetrieveConnectedPeers~ --* ThorRequest~RetrieveConnectedPeers~ ``` From 6bcd7e3c82f8f9222cdc171a9b908a42b2687492 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Thu, 5 Dec 2024 17:43:29 +0000 Subject: [PATCH 26/98] feat: v2 thor transactions dev... --- packages/core/src/vcdm/BlockId.ts | 26 ++++++- packages/core/src/vcdm/Nonce.ts | 42 ++++++++++ packages/core/src/vcdm/index.ts | 1 + packages/{v2-network => net}/README.md | 0 .../{v2-network => net}/eslint.config.mjs | 0 .../{v2-network => net}/jest.browser-setup.js | 0 .../jest.config.browser.js | 0 packages/{v2-network => net}/jest.config.js | 0 packages/{v2-network => net}/package.json | 0 .../src/http/FetchHttpClient.ts | 0 .../src/http/HttpClient.ts | 0 .../{v2-network => net}/src/http/HttpPath.ts | 0 .../{v2-network => net}/src/http/index.ts | 0 packages/{v2-network => net}/src/index.ts | 0 .../src/thor/ThorNetworks.ts | 1 + .../src/thor/ThorRequest.ts | 0 .../src/thor/ThorResponse.ts | 0 .../src/thor/accounts/ContractBytecode.ts | 0 .../src/thor/accounts/GetAccountResponse.ts | 0 .../thor/accounts/RetrieveAccountDetails.ts | 0 .../thor/accounts/RetrieveContractBytecode.ts | 0 .../accounts/RetrieveStoragePositionValue.ts | 0 .../src/thor/accounts/StoragePositionValue.ts | 0 .../src/thor/accounts/index.ts | 0 .../src/thor/blocks/RegularBlockResponse..ts | 0 .../src/thor/blocks/RetrieveBlock.ts | 0 .../src/thor/blocks/index.ts | 0 packages/net/src/thor/explorer/index.ts | 32 ++++++++ .../{v2-network => net}/src/thor/index.ts | 1 + .../src/thor/node/GetPeersResponse.ts | 0 .../src/thor/node/PeerResponse.ts | 0 .../src/thor/node/RetrieveConnectedPeers.ts | 0 .../src/thor/node/index.ts | 0 packages/net/src/thor/transactions/Clause.ts | 29 +++++++ .../src/thor/transactions/GetTxResponse.ts | 77 +++++++++++++++++++ .../transactions/RetrieveTransactionByID.ts | 46 +++++++++++ packages/net/src/thor/transactions/TxMeta.ts | 29 +++++++ packages/net/src/thor/transactions/index.ts | 4 + .../http/FetchHttpClient.testnet.test.ts | 0 .../RetrieveAccountDetails.testnet.test.ts | 0 .../RetrieveContractBytecode.testnet.test.ts | 0 ...trieveStoragePositionValue.testnet.test.ts | 0 .../thor/blocks/RetrieveBlock.testnet.test.ts | 45 +++++++++++ .../RetrieveConnectedPeers.testnet.test.ts | 0 .../RetrieveTransactionByIID.testnet.test.ts | 18 +++++ packages/{v2-network => net}/tsconfig.json | 0 packages/{v2-network => net}/typedoc.json | 0 .../thor/blocks/RetrieveBlock.testnet.test.ts | 12 --- 48 files changed, 350 insertions(+), 13 deletions(-) create mode 100644 packages/core/src/vcdm/Nonce.ts rename packages/{v2-network => net}/README.md (100%) rename packages/{v2-network => net}/eslint.config.mjs (100%) rename packages/{v2-network => net}/jest.browser-setup.js (100%) rename packages/{v2-network => net}/jest.config.browser.js (100%) rename packages/{v2-network => net}/jest.config.js (100%) rename packages/{v2-network => net}/package.json (100%) rename packages/{v2-network => net}/src/http/FetchHttpClient.ts (100%) rename packages/{v2-network => net}/src/http/HttpClient.ts (100%) rename packages/{v2-network => net}/src/http/HttpPath.ts (100%) rename packages/{v2-network => net}/src/http/index.ts (100%) rename packages/{v2-network => net}/src/index.ts (100%) rename packages/{v2-network => net}/src/thor/ThorNetworks.ts (77%) rename packages/{v2-network => net}/src/thor/ThorRequest.ts (100%) rename packages/{v2-network => net}/src/thor/ThorResponse.ts (100%) rename packages/{v2-network => net}/src/thor/accounts/ContractBytecode.ts (100%) rename packages/{v2-network => net}/src/thor/accounts/GetAccountResponse.ts (100%) rename packages/{v2-network => net}/src/thor/accounts/RetrieveAccountDetails.ts (100%) rename packages/{v2-network => net}/src/thor/accounts/RetrieveContractBytecode.ts (100%) rename packages/{v2-network => net}/src/thor/accounts/RetrieveStoragePositionValue.ts (100%) rename packages/{v2-network => net}/src/thor/accounts/StoragePositionValue.ts (100%) rename packages/{v2-network => net}/src/thor/accounts/index.ts (100%) rename packages/{v2-network => net}/src/thor/blocks/RegularBlockResponse..ts (100%) rename packages/{v2-network => net}/src/thor/blocks/RetrieveBlock.ts (100%) rename packages/{v2-network => net}/src/thor/blocks/index.ts (100%) create mode 100644 packages/net/src/thor/explorer/index.ts rename packages/{v2-network => net}/src/thor/index.ts (84%) rename packages/{v2-network => net}/src/thor/node/GetPeersResponse.ts (100%) rename packages/{v2-network => net}/src/thor/node/PeerResponse.ts (100%) rename packages/{v2-network => net}/src/thor/node/RetrieveConnectedPeers.ts (100%) rename packages/{v2-network => net}/src/thor/node/index.ts (100%) create mode 100644 packages/net/src/thor/transactions/Clause.ts create mode 100644 packages/net/src/thor/transactions/GetTxResponse.ts create mode 100644 packages/net/src/thor/transactions/RetrieveTransactionByID.ts create mode 100644 packages/net/src/thor/transactions/TxMeta.ts create mode 100644 packages/net/src/thor/transactions/index.ts rename packages/{v2-network => net}/tests/http/FetchHttpClient.testnet.test.ts (100%) rename packages/{v2-network => net}/tests/thor/accounts/RetrieveAccountDetails.testnet.test.ts (100%) rename packages/{v2-network => net}/tests/thor/accounts/RetrieveContractBytecode.testnet.test.ts (100%) rename packages/{v2-network => net}/tests/thor/accounts/RetrieveStoragePositionValue.testnet.test.ts (100%) create mode 100644 packages/net/tests/thor/blocks/RetrieveBlock.testnet.test.ts rename packages/{v2-network => net}/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts (100%) create mode 100644 packages/net/tests/thor/transactions/RetrieveTransactionByIID.testnet.test.ts rename packages/{v2-network => net}/tsconfig.json (100%) rename packages/{v2-network => net}/typedoc.json (100%) delete mode 100644 packages/v2-network/tests/thor/blocks/RetrieveBlock.testnet.test.ts diff --git a/packages/core/src/vcdm/BlockId.ts b/packages/core/src/vcdm/BlockId.ts index e2bb39b41..d72d9aaaa 100644 --- a/packages/core/src/vcdm/BlockId.ts +++ b/packages/core/src/vcdm/BlockId.ts @@ -66,6 +66,7 @@ class BlockId extends HexUInt { * @throws {InvalidDataType} If the given expression is not a valid hexadecimal positive integer expression. */ public static of( + // eslint-disable-next-line sonarjs/use-type-alias exp: bigint | number | string | Uint8Array | HexUInt ): BlockId { try { @@ -107,4 +108,27 @@ class ThorId extends BlockId { } } -export { BlockId, ThorId }; +/** + * This class is an alias of {@link TxId} for back compatibility. + */ +class TxId extends BlockId { + /** + * Constructs an instance of the class with the specified transaction ID. + * + * @param {TxId} blockId - The unique identifier for the block. + */ + protected constructor(blockId: BlockId) { + super(blockId); + } + + /** + * See {@link BlockId.of}. + */ + public static of( + exp: bigint | number | string | Uint8Array | HexUInt + ): TxId { + return new TxId(BlockId.of(exp)); + } +} + +export { BlockId, ThorId, TxId }; diff --git a/packages/core/src/vcdm/Nonce.ts b/packages/core/src/vcdm/Nonce.ts new file mode 100644 index 000000000..b51068836 --- /dev/null +++ b/packages/core/src/vcdm/Nonce.ts @@ -0,0 +1,42 @@ +import { HexUInt } from './HexUInt'; +import { Hex } from './Hex'; +import { InvalidDataType } from '@vechain/sdk-errors'; + +class Nonce extends HexUInt { + private static readonly DIGITS = 8; + + protected constructor(huint: HexUInt) { + super(Hex.POSITIVE, huint.fit(Nonce.DIGITS).digits); + } + + public static isValid(exp: string): boolean { + return Hex.isValid(exp) && HexUInt.REGEX_HEXUINT_PREFIX.test(exp) + ? exp.length === Nonce.DIGITS + 2 + : exp.length === Nonce.DIGITS; + } + + public static isValid0x(exp: string): boolean { + return HexUInt.REGEX_HEXUINT_PREFIX.test(exp) && Nonce.isValid(exp); + } + + public static of( + // eslint-disable-next-line sonarjs/use-type-alias + exp: bigint | number | string | Uint8Array | HexUInt + ): Nonce { + try { + if (exp instanceof HexUInt) { + return new Nonce(exp); + } + return new Nonce(HexUInt.of(exp)); + } catch (e) { + throw new InvalidDataType( + 'Nonce.of', + 'not a Nonce expression', + { exp: `${exp}` }, // Needed to serialize bigint values. + e + ); + } + } +} + +export { Nonce }; diff --git a/packages/core/src/vcdm/index.ts b/packages/core/src/vcdm/index.ts index 1905cba33..29f3ed4fb 100644 --- a/packages/core/src/vcdm/index.ts +++ b/packages/core/src/vcdm/index.ts @@ -12,6 +12,7 @@ export * from './HexInt'; export * from './HexUInt'; export * from './Int'; export * from './Mnemonic'; +export * from './Nonce'; export * from './Quantity'; export * from './Revision'; export * from './BlockId'; diff --git a/packages/v2-network/README.md b/packages/net/README.md similarity index 100% rename from packages/v2-network/README.md rename to packages/net/README.md diff --git a/packages/v2-network/eslint.config.mjs b/packages/net/eslint.config.mjs similarity index 100% rename from packages/v2-network/eslint.config.mjs rename to packages/net/eslint.config.mjs diff --git a/packages/v2-network/jest.browser-setup.js b/packages/net/jest.browser-setup.js similarity index 100% rename from packages/v2-network/jest.browser-setup.js rename to packages/net/jest.browser-setup.js diff --git a/packages/v2-network/jest.config.browser.js b/packages/net/jest.config.browser.js similarity index 100% rename from packages/v2-network/jest.config.browser.js rename to packages/net/jest.config.browser.js diff --git a/packages/v2-network/jest.config.js b/packages/net/jest.config.js similarity index 100% rename from packages/v2-network/jest.config.js rename to packages/net/jest.config.js diff --git a/packages/v2-network/package.json b/packages/net/package.json similarity index 100% rename from packages/v2-network/package.json rename to packages/net/package.json diff --git a/packages/v2-network/src/http/FetchHttpClient.ts b/packages/net/src/http/FetchHttpClient.ts similarity index 100% rename from packages/v2-network/src/http/FetchHttpClient.ts rename to packages/net/src/http/FetchHttpClient.ts diff --git a/packages/v2-network/src/http/HttpClient.ts b/packages/net/src/http/HttpClient.ts similarity index 100% rename from packages/v2-network/src/http/HttpClient.ts rename to packages/net/src/http/HttpClient.ts diff --git a/packages/v2-network/src/http/HttpPath.ts b/packages/net/src/http/HttpPath.ts similarity index 100% rename from packages/v2-network/src/http/HttpPath.ts rename to packages/net/src/http/HttpPath.ts diff --git a/packages/v2-network/src/http/index.ts b/packages/net/src/http/index.ts similarity index 100% rename from packages/v2-network/src/http/index.ts rename to packages/net/src/http/index.ts diff --git a/packages/v2-network/src/index.ts b/packages/net/src/index.ts similarity index 100% rename from packages/v2-network/src/index.ts rename to packages/net/src/index.ts diff --git a/packages/v2-network/src/thor/ThorNetworks.ts b/packages/net/src/thor/ThorNetworks.ts similarity index 77% rename from packages/v2-network/src/thor/ThorNetworks.ts rename to packages/net/src/thor/ThorNetworks.ts index 9cece1c46..991dd1f80 100644 --- a/packages/v2-network/src/thor/ThorNetworks.ts +++ b/packages/net/src/thor/ThorNetworks.ts @@ -1,5 +1,6 @@ enum ThorNetworks { MAINNET = 'https://mainnet.vechain.org/', + SOLONET = 'https://localhost:8669/', TESTNET = 'https://testnet.vechain.org/' } diff --git a/packages/v2-network/src/thor/ThorRequest.ts b/packages/net/src/thor/ThorRequest.ts similarity index 100% rename from packages/v2-network/src/thor/ThorRequest.ts rename to packages/net/src/thor/ThorRequest.ts diff --git a/packages/v2-network/src/thor/ThorResponse.ts b/packages/net/src/thor/ThorResponse.ts similarity index 100% rename from packages/v2-network/src/thor/ThorResponse.ts rename to packages/net/src/thor/ThorResponse.ts diff --git a/packages/v2-network/src/thor/accounts/ContractBytecode.ts b/packages/net/src/thor/accounts/ContractBytecode.ts similarity index 100% rename from packages/v2-network/src/thor/accounts/ContractBytecode.ts rename to packages/net/src/thor/accounts/ContractBytecode.ts diff --git a/packages/v2-network/src/thor/accounts/GetAccountResponse.ts b/packages/net/src/thor/accounts/GetAccountResponse.ts similarity index 100% rename from packages/v2-network/src/thor/accounts/GetAccountResponse.ts rename to packages/net/src/thor/accounts/GetAccountResponse.ts diff --git a/packages/v2-network/src/thor/accounts/RetrieveAccountDetails.ts b/packages/net/src/thor/accounts/RetrieveAccountDetails.ts similarity index 100% rename from packages/v2-network/src/thor/accounts/RetrieveAccountDetails.ts rename to packages/net/src/thor/accounts/RetrieveAccountDetails.ts diff --git a/packages/v2-network/src/thor/accounts/RetrieveContractBytecode.ts b/packages/net/src/thor/accounts/RetrieveContractBytecode.ts similarity index 100% rename from packages/v2-network/src/thor/accounts/RetrieveContractBytecode.ts rename to packages/net/src/thor/accounts/RetrieveContractBytecode.ts diff --git a/packages/v2-network/src/thor/accounts/RetrieveStoragePositionValue.ts b/packages/net/src/thor/accounts/RetrieveStoragePositionValue.ts similarity index 100% rename from packages/v2-network/src/thor/accounts/RetrieveStoragePositionValue.ts rename to packages/net/src/thor/accounts/RetrieveStoragePositionValue.ts diff --git a/packages/v2-network/src/thor/accounts/StoragePositionValue.ts b/packages/net/src/thor/accounts/StoragePositionValue.ts similarity index 100% rename from packages/v2-network/src/thor/accounts/StoragePositionValue.ts rename to packages/net/src/thor/accounts/StoragePositionValue.ts diff --git a/packages/v2-network/src/thor/accounts/index.ts b/packages/net/src/thor/accounts/index.ts similarity index 100% rename from packages/v2-network/src/thor/accounts/index.ts rename to packages/net/src/thor/accounts/index.ts diff --git a/packages/v2-network/src/thor/blocks/RegularBlockResponse..ts b/packages/net/src/thor/blocks/RegularBlockResponse..ts similarity index 100% rename from packages/v2-network/src/thor/blocks/RegularBlockResponse..ts rename to packages/net/src/thor/blocks/RegularBlockResponse..ts diff --git a/packages/v2-network/src/thor/blocks/RetrieveBlock.ts b/packages/net/src/thor/blocks/RetrieveBlock.ts similarity index 100% rename from packages/v2-network/src/thor/blocks/RetrieveBlock.ts rename to packages/net/src/thor/blocks/RetrieveBlock.ts diff --git a/packages/v2-network/src/thor/blocks/index.ts b/packages/net/src/thor/blocks/index.ts similarity index 100% rename from packages/v2-network/src/thor/blocks/index.ts rename to packages/net/src/thor/blocks/index.ts diff --git a/packages/net/src/thor/explorer/index.ts b/packages/net/src/thor/explorer/index.ts new file mode 100644 index 000000000..65f9c29a1 --- /dev/null +++ b/packages/net/src/thor/explorer/index.ts @@ -0,0 +1,32 @@ +import { FetchHttpClient } from '../../http'; +import { ThorNetworks } from '../ThorNetworks'; +import { RetrieveBlock, RetrieveBlockPath } from '../blocks'; +import { Revision } from '@vechain/sdk-core'; + +async function getBestBlockNumber( + httpClient: FetchHttpClient +): Promise { + const r = await new RetrieveBlock( + new RetrieveBlockPath(Revision.BEST) + ).askTo(httpClient); + return r.response.number; +} + +async function explore(): Promise { + const httpClient = new FetchHttpClient(ThorNetworks.TESTNET); + const lastBlockNumber = await getBestBlockNumber(httpClient); + for (let blockNumber = lastBlockNumber; blockNumber >= 0; blockNumber--) { + const block = ( + await RetrieveBlock.of(Revision.of(blockNumber)).askTo(httpClient) + ).response; + console.log(block.number, lastBlockNumber); + block.transactions.forEach((tx) => { + console.log(tx); + }); + } +} + +console.log('explorer'); +void explore().then((r) => { + console.log(r); +}); diff --git a/packages/v2-network/src/thor/index.ts b/packages/net/src/thor/index.ts similarity index 84% rename from packages/v2-network/src/thor/index.ts rename to packages/net/src/thor/index.ts index bc1c55361..846caa20b 100644 --- a/packages/v2-network/src/thor/index.ts +++ b/packages/net/src/thor/index.ts @@ -4,3 +4,4 @@ export * from './blocks'; export * from './ThorNetworks'; export * from './ThorRequest'; export * from './ThorResponse'; +export * from './transactions'; diff --git a/packages/v2-network/src/thor/node/GetPeersResponse.ts b/packages/net/src/thor/node/GetPeersResponse.ts similarity index 100% rename from packages/v2-network/src/thor/node/GetPeersResponse.ts rename to packages/net/src/thor/node/GetPeersResponse.ts diff --git a/packages/v2-network/src/thor/node/PeerResponse.ts b/packages/net/src/thor/node/PeerResponse.ts similarity index 100% rename from packages/v2-network/src/thor/node/PeerResponse.ts rename to packages/net/src/thor/node/PeerResponse.ts diff --git a/packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts b/packages/net/src/thor/node/RetrieveConnectedPeers.ts similarity index 100% rename from packages/v2-network/src/thor/node/RetrieveConnectedPeers.ts rename to packages/net/src/thor/node/RetrieveConnectedPeers.ts diff --git a/packages/v2-network/src/thor/node/index.ts b/packages/net/src/thor/node/index.ts similarity index 100% rename from packages/v2-network/src/thor/node/index.ts rename to packages/net/src/thor/node/index.ts diff --git a/packages/net/src/thor/transactions/Clause.ts b/packages/net/src/thor/transactions/Clause.ts new file mode 100644 index 000000000..922adb697 --- /dev/null +++ b/packages/net/src/thor/transactions/Clause.ts @@ -0,0 +1,29 @@ +import { Address, HexUInt, VET } from '@vechain/sdk-core'; + +class Clause { + readonly to: Address | null; + readonly value: VET; + readonly data: HexUInt; + + constructor(json: ClauseJSON) { + this.to = json.to === null ? null : Address.of(json.to); + this.value = VET.of(json.value); + this.data = HexUInt.of(json.data); + } + + toJSON(): ClauseJSON { + return { + to: this.to === null ? null : this.to.toString(), + value: HexUInt.of(this.value.wei).toString(), + data: this.data.toString() + } satisfies ClauseJSON; + } +} + +interface ClauseJSON { + to: string | null; + value: string; + data: string; +} + +export { Clause, type ClauseJSON }; diff --git a/packages/net/src/thor/transactions/GetTxResponse.ts b/packages/net/src/thor/transactions/GetTxResponse.ts new file mode 100644 index 000000000..915d8f417 --- /dev/null +++ b/packages/net/src/thor/transactions/GetTxResponse.ts @@ -0,0 +1,77 @@ +import { Clause, type ClauseJSON } from './Clause'; +import { TxMeta, type TxMetaJSON } from './TxMeta'; +import { Address, BlockId, Nonce, TxId, UInt, VTHO } from '@vechain/sdk-core'; + +class GetTxResponse { + readonly id: TxId; + readonly origin: Address; + readonly delegator: Address | null; + readonly size: UInt; + readonly chainTag: UInt; + readonly blockRef: BlockId; + readonly expiration: UInt; + readonly clauses: Clause[]; + readonly gasPriceCoef: UInt; + readonly gas: VTHO; + readonly dependsOn: TxId | null; + readonly nonce: Nonce; + readonly meta: TxMeta; + + constructor(json: GetTxResponseJSON) { + this.id = TxId.of(json.id); + this.origin = Address.of(json.origin); + this.delegator = + json.delegator === null ? null : Address.of(json.delegator); + this.size = UInt.of(json.size); + this.chainTag = UInt.of(json.chainTag); + this.blockRef = BlockId.of(json.blockRef); + this.expiration = UInt.of(json.expiration); + this.clauses = json.clauses.map((clauseJSON: ClauseJSON) => { + return new Clause(clauseJSON); + }); + this.gasPriceCoef = UInt.of(json.gasPriceCoef); + this.gas = VTHO.of(json.gas); + this.dependsOn = + json.dependsOn === null ? null : TxId.of(json.dependsOn); + this.nonce = Nonce.of(json.nonce); + this.meta = new TxMeta(json.meta); + } + + toJSON(): GetTxResponseJSON { + return { + id: this.id.toString(), + origin: this.origin.toString(), + delegator: + this.delegator === null ? null : this.delegator.toString(), + size: this.size.valueOf(), + chainTag: this.chainTag.valueOf(), + blockRef: this.blockRef.toString(), + expiration: this.expiration.valueOf(), + clauses: this.clauses.map((clause) => clause.toJSON()), + gasPriceCoef: this.gasPriceCoef.valueOf(), + gas: Number(this.gas.wei), + dependsOn: + this.dependsOn === null ? null : this.dependsOn.toString(), + nonce: this.nonce.toString(), + meta: this.meta.toJSON() + } satisfies GetTxResponseJSON; + } +} + +interface GetTxResponseJSON { + id: string; + origin: string; + delegator: string | null; + size: number; + chainTag: number; + blockRef: string; + expiration: number; + clauses: ClauseJSON[]; + gasPriceCoef: number; + gas: number; + dependsOn: string | null; + nonce: string; + meta: TxMetaJSON; +} + +export { GetTxResponse, type GetTxResponseJSON }; diff --git a/packages/net/src/thor/transactions/RetrieveTransactionByID.ts b/packages/net/src/thor/transactions/RetrieveTransactionByID.ts new file mode 100644 index 000000000..940dcf9a7 --- /dev/null +++ b/packages/net/src/thor/transactions/RetrieveTransactionByID.ts @@ -0,0 +1,46 @@ +import { type TxId } from '@vechain/sdk-core'; +import { type HttpClient, type HttpPath } from '../../http'; +import { GetTxResponse, type GetTxResponseJSON } from './GetTxResponse'; +import { type ThorRequest } from '../ThorRequest'; +import { type ThorResponse } from '../ThorResponse'; + +class RetrieveTransactionByID + implements ThorRequest +{ + readonly path: RetrieveTransactionByIDPath; + + constructor(path: RetrieveTransactionByIDPath) { + this.path = path; + } + + async askTo( + httpClient: HttpClient + ): Promise> { + const response = await httpClient.get(this.path); + const responseBody = (await response.json()) as GetTxResponseJSON; + return { + request: this, + response: new GetTxResponse(responseBody) + }; + } + + static of(txId: TxId): RetrieveTransactionByID { + return new RetrieveTransactionByID( + new RetrieveTransactionByIDPath(txId) + ); + } +} + +class RetrieveTransactionByIDPath implements HttpPath { + readonly txId: TxId; + + constructor(txId: TxId) { + this.txId = txId; + } + + get path(): string { + return `/transactions/${this.txId}`; + } +} + +export { RetrieveTransactionByID, RetrieveTransactionByIDPath }; diff --git a/packages/net/src/thor/transactions/TxMeta.ts b/packages/net/src/thor/transactions/TxMeta.ts new file mode 100644 index 000000000..749acda41 --- /dev/null +++ b/packages/net/src/thor/transactions/TxMeta.ts @@ -0,0 +1,29 @@ +import { BlockId, UInt } from '@vechain/sdk-core'; + +class TxMeta { + readonly blockID: BlockId; + readonly blockNumber: UInt; + readonly blockTimestamp: bigint; + + constructor(json: TxMetaJSON) { + this.blockID = BlockId.of(json.blockID); + this.blockNumber = UInt.of(json.blockNumber); + this.blockTimestamp = json.blockTimestamp; + } + + toJSON(): TxMetaJSON { + return { + blockID: this.blockID.toString(), + blockNumber: this.blockNumber.valueOf(), + blockTimestamp: this.blockTimestamp + } satisfies TxMetaJSON; + } +} + +interface TxMetaJSON { + blockID: string; + blockNumber: number; + blockTimestamp: bigint; +} + +export { TxMeta, type TxMetaJSON }; diff --git a/packages/net/src/thor/transactions/index.ts b/packages/net/src/thor/transactions/index.ts new file mode 100644 index 000000000..f48ea4fb6 --- /dev/null +++ b/packages/net/src/thor/transactions/index.ts @@ -0,0 +1,4 @@ +export * from './Clause'; +export * from './GetTxResponse'; +export * from './RetrieveTransactionByID'; +export * from './TxMeta'; diff --git a/packages/v2-network/tests/http/FetchHttpClient.testnet.test.ts b/packages/net/tests/http/FetchHttpClient.testnet.test.ts similarity index 100% rename from packages/v2-network/tests/http/FetchHttpClient.testnet.test.ts rename to packages/net/tests/http/FetchHttpClient.testnet.test.ts diff --git a/packages/v2-network/tests/thor/accounts/RetrieveAccountDetails.testnet.test.ts b/packages/net/tests/thor/accounts/RetrieveAccountDetails.testnet.test.ts similarity index 100% rename from packages/v2-network/tests/thor/accounts/RetrieveAccountDetails.testnet.test.ts rename to packages/net/tests/thor/accounts/RetrieveAccountDetails.testnet.test.ts diff --git a/packages/v2-network/tests/thor/accounts/RetrieveContractBytecode.testnet.test.ts b/packages/net/tests/thor/accounts/RetrieveContractBytecode.testnet.test.ts similarity index 100% rename from packages/v2-network/tests/thor/accounts/RetrieveContractBytecode.testnet.test.ts rename to packages/net/tests/thor/accounts/RetrieveContractBytecode.testnet.test.ts diff --git a/packages/v2-network/tests/thor/accounts/RetrieveStoragePositionValue.testnet.test.ts b/packages/net/tests/thor/accounts/RetrieveStoragePositionValue.testnet.test.ts similarity index 100% rename from packages/v2-network/tests/thor/accounts/RetrieveStoragePositionValue.testnet.test.ts rename to packages/net/tests/thor/accounts/RetrieveStoragePositionValue.testnet.test.ts diff --git a/packages/net/tests/thor/blocks/RetrieveBlock.testnet.test.ts b/packages/net/tests/thor/blocks/RetrieveBlock.testnet.test.ts new file mode 100644 index 000000000..be9515881 --- /dev/null +++ b/packages/net/tests/thor/blocks/RetrieveBlock.testnet.test.ts @@ -0,0 +1,45 @@ +import { describe, test } from '@jest/globals'; +import { + FetchHttpClient, + RetrieveBlock, + RetrieveBlockPath, + ThorNetworks +} from '../../../src'; +import { Revision } from '@vechain/sdk-core'; + +describe('RetrieveBlock testnet tests', () => { + test('ok <- askTo', async () => { + const r = await RetrieveBlock.of(Revision.BEST).askTo( + new FetchHttpClient(ThorNetworks.TESTNET) + ); + console.log(JSON.stringify(r, null, 2)); + }); + + test('explore', async () => { + const httpClient = new FetchHttpClient(ThorNetworks.TESTNET); + const lastBlockNumber = await getBestBlockNumber(httpClient); + for ( + let blockNumber = 0; + blockNumber <= lastBlockNumber; + blockNumber++ + ) { + const block = ( + await RetrieveBlock.of(Revision.of(blockNumber)).askTo( + httpClient + ) + ).response; + block.transactions.forEach((tx) => { + console.log(`${block.number}/${tx}`); + }); + } + }); + + async function getBestBlockNumber( + httpClient: FetchHttpClient + ): Promise { + const r = await new RetrieveBlock( + new RetrieveBlockPath(Revision.BEST) + ).askTo(httpClient); + return r.response.number; + } +}); diff --git a/packages/v2-network/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts b/packages/net/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts similarity index 100% rename from packages/v2-network/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts rename to packages/net/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts diff --git a/packages/net/tests/thor/transactions/RetrieveTransactionByIID.testnet.test.ts b/packages/net/tests/thor/transactions/RetrieveTransactionByIID.testnet.test.ts new file mode 100644 index 000000000..c91386e2c --- /dev/null +++ b/packages/net/tests/thor/transactions/RetrieveTransactionByIID.testnet.test.ts @@ -0,0 +1,18 @@ +import { describe, test } from '@jest/globals'; +import { TxId } from '@vechain/sdk-core'; +import { + FetchHttpClient, + RetrieveTransactionByID, + ThorNetworks +} from '../../../src'; + +describe('RetrieveTransactionByID testnet tests', () => { + test('ok <- askTo', async () => { + const txId = TxId.of( + '0xb6b5b47a5eee8b14e5222ac1bb957c0bbdc3d489850b033e3e544d9ca0cef934' + ); + const httpClient = new FetchHttpClient(ThorNetworks.MAINNET); + const r = await RetrieveTransactionByID.of(txId).askTo(httpClient); + console.log(JSON.stringify(r, null, 2)); + }); +}); diff --git a/packages/v2-network/tsconfig.json b/packages/net/tsconfig.json similarity index 100% rename from packages/v2-network/tsconfig.json rename to packages/net/tsconfig.json diff --git a/packages/v2-network/typedoc.json b/packages/net/typedoc.json similarity index 100% rename from packages/v2-network/typedoc.json rename to packages/net/typedoc.json diff --git a/packages/v2-network/tests/thor/blocks/RetrieveBlock.testnet.test.ts b/packages/v2-network/tests/thor/blocks/RetrieveBlock.testnet.test.ts deleted file mode 100644 index 5988df353..000000000 --- a/packages/v2-network/tests/thor/blocks/RetrieveBlock.testnet.test.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { describe, test } from '@jest/globals'; -import { FetchHttpClient, RetrieveBlock, ThorNetworks } from '../../../src'; -import { Revision } from '@vechain/sdk-core'; - -describe('RetrieveBlock testnet tests', () => { - test('ok <- askTo', async () => { - const r = await RetrieveBlock.of(Revision.BEST).askTo( - new FetchHttpClient(ThorNetworks.TESTNET) - ); - console.log(JSON.stringify(r, null, 2)); - }); -}); From 236a78409f381607c2e17d7b7a9b11ef7cea34ac Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Fri, 6 Dec 2024 12:00:21 +0000 Subject: [PATCH 27/98] feat: v2 thor transactions dev... --- packages/net/src/http/FetchHttpClient.ts | 25 +++++-- packages/net/src/http/HttpClient.ts | 3 +- packages/net/src/http/HttpQuery.ts | 3 + packages/net/src/http/index.ts | 1 + .../thor/accounts/RetrieveAccountDetails.ts | 2 +- .../thor/accounts/RetrieveContractBytecode.ts | 2 +- .../accounts/RetrieveStoragePositionValue.ts | 2 +- packages/net/src/thor/blocks/RetrieveBlock.ts | 2 +- .../src/thor/node/RetrieveConnectedPeers.ts | 4 +- .../src/thor/transactions/GetRawTxResponse.ts | 26 +++++++ .../RetrieveRawTransactionByID.ts | 75 +++++++++++++++++++ .../transactions/RetrieveTransactionByID.ts | 52 +++++++++++-- packages/net/src/thor/transactions/index.ts | 2 + .../RetrieveAccountDetails.testnet.test.ts | 2 +- .../RetrieveContractBytecode.testnet.test.ts | 2 +- ...trieveStoragePositionValue.testnet.test.ts | 2 +- .../thor/blocks/RetrieveBlock.testnet.test.ts | 4 +- .../RetrieveConnectedPeers.testnet.test.ts | 2 +- ...etrieveRawTransactionByIID.testnet.test.ts | 18 +++++ .../RetrieveTransactionByIID.testnet.test.ts | 2 +- 20 files changed, 206 insertions(+), 25 deletions(-) create mode 100644 packages/net/src/http/HttpQuery.ts create mode 100644 packages/net/src/thor/transactions/GetRawTxResponse.ts create mode 100644 packages/net/src/thor/transactions/RetrieveRawTransactionByID.ts create mode 100644 packages/net/tests/thor/transactions/RetrieveRawTransactionByIID.testnet.test.ts diff --git a/packages/net/src/http/FetchHttpClient.ts b/packages/net/src/http/FetchHttpClient.ts index d395c615b..cbcf207c5 100644 --- a/packages/net/src/http/FetchHttpClient.ts +++ b/packages/net/src/http/FetchHttpClient.ts @@ -1,8 +1,10 @@ import { type HttpClient } from './HttpClient'; import { type HttpPath } from './HttpPath'; +import { type HttpQuery } from './HttpQuery'; class FetchHttpClient implements HttpClient { - private static readonly SLASH = '/'; + private static readonly PATH_SEPARATOR = '/'; + private static readonly QUERY_SEPARATOR = '?'; public readonly baseURL: string; @@ -12,26 +14,37 @@ class FetchHttpClient implements HttpClient { constructor( baseURL: string, - onRequest: (request: Request) => Request = (request) => request, - onResponse: (response: Response) => Response = (response) => response + onRequest: (request: Request) => Request, + onResponse: (response: Response) => Response ) { - this.baseURL = baseURL.endsWith(FetchHttpClient.SLASH) + this.baseURL = baseURL.endsWith(FetchHttpClient.PATH_SEPARATOR) ? baseURL.substring(0, baseURL.length - 1) : baseURL; this.onRequest = onRequest; this.onResponse = onResponse; } + static at( + baseURL: string, + onRequest: (request: Request) => Request = (request) => request, + onResponse: (response: Response) => Response = (response) => response + ): FetchHttpClient { + return new FetchHttpClient(baseURL, onRequest, onResponse); + } + async get( httpPath: HttpPath = { path: '' + }, + httpQuery: HttpQuery = { + query: '' } ): Promise { - const path = httpPath.path.startsWith(FetchHttpClient.SLASH) + const path = httpPath.path.startsWith(FetchHttpClient.PATH_SEPARATOR) ? httpPath.path.substring(1) : httpPath.path; const request = new Request( - `${this.baseURL}${FetchHttpClient.SLASH}${path}` + `${this.baseURL}${FetchHttpClient.PATH_SEPARATOR}${path}${httpQuery.query}` ); const response = await fetch(this.onRequest(request)); return this.onResponse(response); diff --git a/packages/net/src/http/HttpClient.ts b/packages/net/src/http/HttpClient.ts index 12e9fa353..21c27dccb 100644 --- a/packages/net/src/http/HttpClient.ts +++ b/packages/net/src/http/HttpClient.ts @@ -1,5 +1,6 @@ import { type HttpPath } from './HttpPath'; +import { type HttpQuery } from './HttpQuery'; export interface HttpClient { - get: (httpPath: HttpPath) => Promise; + get: (httpPath: HttpPath, httpQuery: HttpQuery) => Promise; } diff --git a/packages/net/src/http/HttpQuery.ts b/packages/net/src/http/HttpQuery.ts new file mode 100644 index 000000000..3e0a56bc9 --- /dev/null +++ b/packages/net/src/http/HttpQuery.ts @@ -0,0 +1,3 @@ +export interface HttpQuery { + get query(): string; +} diff --git a/packages/net/src/http/index.ts b/packages/net/src/http/index.ts index 985f399c0..fca06d72a 100644 --- a/packages/net/src/http/index.ts +++ b/packages/net/src/http/index.ts @@ -1,3 +1,4 @@ export * from './FetchHttpClient'; export * from './HttpClient'; export * from './HttpPath'; +export * from './HttpQuery'; diff --git a/packages/net/src/thor/accounts/RetrieveAccountDetails.ts b/packages/net/src/thor/accounts/RetrieveAccountDetails.ts index ad9d499f2..d6bc13dcf 100644 --- a/packages/net/src/thor/accounts/RetrieveAccountDetails.ts +++ b/packages/net/src/thor/accounts/RetrieveAccountDetails.ts @@ -19,7 +19,7 @@ class RetrieveAccountDetails async askTo( httpClient: HttpClient ): Promise> { - const response = await httpClient.get(this.path); + const response = await httpClient.get(this.path, { query: '' }); const responseBody = (await response.json()) as GetAccountResponseJSON; return { request: this, diff --git a/packages/net/src/thor/accounts/RetrieveContractBytecode.ts b/packages/net/src/thor/accounts/RetrieveContractBytecode.ts index 49e20e9e8..7bf4b293f 100644 --- a/packages/net/src/thor/accounts/RetrieveContractBytecode.ts +++ b/packages/net/src/thor/accounts/RetrieveContractBytecode.ts @@ -19,7 +19,7 @@ class RetrieveContractBytecode async askTo( httpClient: HttpClient ): Promise> { - const response = await httpClient.get(this.path); + const response = await httpClient.get(this.path, { query: '' }); const responseBody = (await response.json()) as ContractBytecodeJSON; return { request: this, diff --git a/packages/net/src/thor/accounts/RetrieveStoragePositionValue.ts b/packages/net/src/thor/accounts/RetrieveStoragePositionValue.ts index e1389f418..b97d27a35 100644 --- a/packages/net/src/thor/accounts/RetrieveStoragePositionValue.ts +++ b/packages/net/src/thor/accounts/RetrieveStoragePositionValue.ts @@ -21,7 +21,7 @@ class RetrieveStoragePositionValue ): Promise< ThorResponse > { - const response = await httpClient.get(this.path); + const response = await httpClient.get(this.path, { query: '' }); const responseBody = (await response.json()) as StoragePositionValueJSON; return { diff --git a/packages/net/src/thor/blocks/RetrieveBlock.ts b/packages/net/src/thor/blocks/RetrieveBlock.ts index cf4813b79..02a30cd2c 100644 --- a/packages/net/src/thor/blocks/RetrieveBlock.ts +++ b/packages/net/src/thor/blocks/RetrieveBlock.ts @@ -19,7 +19,7 @@ class RetrieveBlock async askTo( httpClient: HttpClient ): Promise> { - const response = await httpClient.get(this.path); + const response = await httpClient.get(this.path, { query: '' }); const responseBody = (await response.json()) as RegularBlockResponseJSON; return { diff --git a/packages/net/src/thor/node/RetrieveConnectedPeers.ts b/packages/net/src/thor/node/RetrieveConnectedPeers.ts index 1ed8435cc..af02f4661 100644 --- a/packages/net/src/thor/node/RetrieveConnectedPeers.ts +++ b/packages/net/src/thor/node/RetrieveConnectedPeers.ts @@ -12,7 +12,9 @@ class RetrieveConnectedPeers async askTo( httpClient: HttpClient ): Promise> { - const response = await httpClient.get(RetrieveConnectedPeers.PATH); + const response = await httpClient.get(RetrieveConnectedPeers.PATH, { + query: '' + }); const responseBody: PeerResponseJSON[] = (await response.json()) as PeerResponseJSON[]; const getPeersResponse: GetPeersResponse = responseBody.map( diff --git a/packages/net/src/thor/transactions/GetRawTxResponse.ts b/packages/net/src/thor/transactions/GetRawTxResponse.ts new file mode 100644 index 000000000..3546620c9 --- /dev/null +++ b/packages/net/src/thor/transactions/GetRawTxResponse.ts @@ -0,0 +1,26 @@ +import { HexUInt } from '@vechain/sdk-core'; +import { TxMeta, type TxMetaJSON } from './TxMeta'; + +class GetRawTxResponse { + readonly raw: HexUInt; + readonly meta: TxMeta; + + constructor(json: GetRawTxResponseJSON) { + this.raw = HexUInt.of(json.raw); + this.meta = new TxMeta(json.meta); + } + + toJSON(): GetRawTxResponseJSON { + return { + raw: this.raw.toString(), + meta: this.meta.toJSON() + } satisfies GetRawTxResponseJSON; + } +} + +interface GetRawTxResponseJSON { + raw: string; + meta: TxMetaJSON; +} + +export { GetRawTxResponse, type GetRawTxResponseJSON }; diff --git a/packages/net/src/thor/transactions/RetrieveRawTransactionByID.ts b/packages/net/src/thor/transactions/RetrieveRawTransactionByID.ts new file mode 100644 index 000000000..660c66c53 --- /dev/null +++ b/packages/net/src/thor/transactions/RetrieveRawTransactionByID.ts @@ -0,0 +1,75 @@ +import { + RetrieveTransactionByIDPath, + RetrieveTransactionByIDQuery +} from './RetrieveTransactionByID'; +import { + GetRawTxResponse, + type GetRawTxResponseJSON +} from './GetRawTxResponse'; +import { type BlockId, type TxId } from '@vechain/sdk-core'; +import { type HttpClient } from '../../http'; +import { type ThorRequest } from '../ThorRequest'; +import { type ThorResponse } from '../ThorResponse'; + +class RetrieveRawTransactionByID + implements ThorRequest +{ + readonly path: RetrieveRawTransactionByIDPath; + + readonly query: RetrieveRawTransactionByIDQuery; + + constructor( + path: RetrieveRawTransactionByIDPath, + query: RetrieveRawTransactionByIDQuery + ) { + this.path = path; + this.query = query; + } + + async askTo( + httpClient: HttpClient + ): Promise> { + const response = await httpClient.get(this.path, this.query); + const responseBody = (await response.json()) as GetRawTxResponseJSON; + return { + request: this, + response: new GetRawTxResponse(responseBody) + }; + } + + static of(txId: TxId): RetrieveRawTransactionByID { + return new RetrieveRawTransactionByID( + new RetrieveRawTransactionByIDPath(txId), + new RetrieveRawTransactionByIDQuery(null, false) + ); + } + + withHead(head: BlockId | null = null): RetrieveRawTransactionByID { + return new RetrieveRawTransactionByID( + this.path, + new RetrieveRawTransactionByIDQuery(head, this.query.pending) + ); + } + + withPending(pending: boolean = true): RetrieveRawTransactionByID { + return new RetrieveRawTransactionByID( + this.path, + new RetrieveRawTransactionByIDQuery(this.query.head, pending) + ); + } +} + +class RetrieveRawTransactionByIDPath extends RetrieveTransactionByIDPath {} + +class RetrieveRawTransactionByIDQuery extends RetrieveTransactionByIDQuery { + get query(): string { + const head = this.head === null ? '' : `${this.head}&`; + return `?${head}pending=${this.pending}&raw=true`; + } +} + +export { + RetrieveRawTransactionByID, + RetrieveRawTransactionByIDPath, + RetrieveRawTransactionByIDQuery +}; diff --git a/packages/net/src/thor/transactions/RetrieveTransactionByID.ts b/packages/net/src/thor/transactions/RetrieveTransactionByID.ts index 940dcf9a7..6d16f00be 100644 --- a/packages/net/src/thor/transactions/RetrieveTransactionByID.ts +++ b/packages/net/src/thor/transactions/RetrieveTransactionByID.ts @@ -1,5 +1,5 @@ -import { type TxId } from '@vechain/sdk-core'; -import { type HttpClient, type HttpPath } from '../../http'; +import { type BlockId, type TxId } from '@vechain/sdk-core'; +import { type HttpClient, type HttpPath, type HttpQuery } from '../../http'; import { GetTxResponse, type GetTxResponseJSON } from './GetTxResponse'; import { type ThorRequest } from '../ThorRequest'; import { type ThorResponse } from '../ThorResponse'; @@ -9,14 +9,20 @@ class RetrieveTransactionByID { readonly path: RetrieveTransactionByIDPath; - constructor(path: RetrieveTransactionByIDPath) { + readonly query: RetrieveTransactionByIDQuery; + + constructor( + path: RetrieveTransactionByIDPath, + query: RetrieveTransactionByIDQuery + ) { this.path = path; + this.query = query; } async askTo( httpClient: HttpClient ): Promise> { - const response = await httpClient.get(this.path); + const response = await httpClient.get(this.path, this.query); const responseBody = (await response.json()) as GetTxResponseJSON; return { request: this, @@ -26,7 +32,22 @@ class RetrieveTransactionByID static of(txId: TxId): RetrieveTransactionByID { return new RetrieveTransactionByID( - new RetrieveTransactionByIDPath(txId) + new RetrieveTransactionByIDPath(txId), + new RetrieveTransactionByIDQuery(null, false) + ); + } + + withHead(head: BlockId | null = null): RetrieveTransactionByID { + return new RetrieveTransactionByID( + this.path, + new RetrieveTransactionByIDQuery(head, this.query.pending) + ); + } + + withPending(pending: boolean = true): RetrieveTransactionByID { + return new RetrieveTransactionByID( + this.path, + new RetrieveTransactionByIDQuery(this.query.head, pending) ); } } @@ -43,4 +64,23 @@ class RetrieveTransactionByIDPath implements HttpPath { } } -export { RetrieveTransactionByID, RetrieveTransactionByIDPath }; +class RetrieveTransactionByIDQuery implements HttpQuery { + readonly head: BlockId | null; + readonly pending; + + constructor(head: BlockId | null, pending: boolean) { + this.head = head; + this.pending = pending; + } + + get query(): string { + const head = this.head === null ? '' : `${this.head}&`; + return `?${head}pending=${this.pending}&raw=false`; + } +} + +export { + RetrieveTransactionByID, + RetrieveTransactionByIDPath, + RetrieveTransactionByIDQuery +}; diff --git a/packages/net/src/thor/transactions/index.ts b/packages/net/src/thor/transactions/index.ts index f48ea4fb6..e5369bd27 100644 --- a/packages/net/src/thor/transactions/index.ts +++ b/packages/net/src/thor/transactions/index.ts @@ -1,4 +1,6 @@ export * from './Clause'; +export * from './GetRawTxResponse'; export * from './GetTxResponse'; export * from './RetrieveTransactionByID'; +export * from './RetrieveRawTransactionByID'; export * from './TxMeta'; diff --git a/packages/net/tests/thor/accounts/RetrieveAccountDetails.testnet.test.ts b/packages/net/tests/thor/accounts/RetrieveAccountDetails.testnet.test.ts index 5ffe3d48b..f5d663b4a 100644 --- a/packages/net/tests/thor/accounts/RetrieveAccountDetails.testnet.test.ts +++ b/packages/net/tests/thor/accounts/RetrieveAccountDetails.testnet.test.ts @@ -10,7 +10,7 @@ describe('RetrieveAccountDetails testnet tests', () => { test('ok <- askTo', async () => { const r = await RetrieveAccountDetails.of( Address.of('0x0000000000000000000000000000456E65726779') - ).askTo(new FetchHttpClient(ThorNetworks.TESTNET)); + ).askTo(FetchHttpClient.at(ThorNetworks.TESTNET)); console.log(JSON.stringify(r, null, 2)); }); }); diff --git a/packages/net/tests/thor/accounts/RetrieveContractBytecode.testnet.test.ts b/packages/net/tests/thor/accounts/RetrieveContractBytecode.testnet.test.ts index 014c643cb..dc3299953 100644 --- a/packages/net/tests/thor/accounts/RetrieveContractBytecode.testnet.test.ts +++ b/packages/net/tests/thor/accounts/RetrieveContractBytecode.testnet.test.ts @@ -10,7 +10,7 @@ describe('RetrieveContractBytecode testnet tests', () => { test('ok <- askTo', async () => { const r = await RetrieveContractBytecode.of( Address.of('0x0000000000000000000000000000456E65726779') - ).askTo(new FetchHttpClient(ThorNetworks.TESTNET)); + ).askTo(FetchHttpClient.at(ThorNetworks.TESTNET)); console.log(JSON.stringify(r, null, 2)); }); }); diff --git a/packages/net/tests/thor/accounts/RetrieveStoragePositionValue.testnet.test.ts b/packages/net/tests/thor/accounts/RetrieveStoragePositionValue.testnet.test.ts index aa179bc5b..73f135efe 100644 --- a/packages/net/tests/thor/accounts/RetrieveStoragePositionValue.testnet.test.ts +++ b/packages/net/tests/thor/accounts/RetrieveStoragePositionValue.testnet.test.ts @@ -13,7 +13,7 @@ describe('RetrieveStoragePositionValue testnet tests', () => { BlockId.of( '0x0000000000000000000000000000000000000000000000000000000000000001' ) - ).askTo(new FetchHttpClient(ThorNetworks.TESTNET)); + ).askTo(FetchHttpClient.at(ThorNetworks.TESTNET)); console.log(JSON.stringify(r, null, 2)); }); }); diff --git a/packages/net/tests/thor/blocks/RetrieveBlock.testnet.test.ts b/packages/net/tests/thor/blocks/RetrieveBlock.testnet.test.ts index be9515881..e26fdf730 100644 --- a/packages/net/tests/thor/blocks/RetrieveBlock.testnet.test.ts +++ b/packages/net/tests/thor/blocks/RetrieveBlock.testnet.test.ts @@ -10,13 +10,13 @@ import { Revision } from '@vechain/sdk-core'; describe('RetrieveBlock testnet tests', () => { test('ok <- askTo', async () => { const r = await RetrieveBlock.of(Revision.BEST).askTo( - new FetchHttpClient(ThorNetworks.TESTNET) + FetchHttpClient.at(ThorNetworks.TESTNET) ); console.log(JSON.stringify(r, null, 2)); }); test('explore', async () => { - const httpClient = new FetchHttpClient(ThorNetworks.TESTNET); + const httpClient = FetchHttpClient.at(ThorNetworks.TESTNET); const lastBlockNumber = await getBestBlockNumber(httpClient); for ( let blockNumber = 0; diff --git a/packages/net/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts b/packages/net/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts index 2c560ed47..96a771424 100644 --- a/packages/net/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts +++ b/packages/net/tests/thor/node/RetrieveConnectedPeers.testnet.test.ts @@ -8,7 +8,7 @@ import { describe('RetrieveConnectedPeers testnet tests', () => { test('ok <- askTo', async () => { const r = await new RetrieveConnectedPeers().askTo( - new FetchHttpClient(ThorNetworks.TESTNET) + FetchHttpClient.at(ThorNetworks.TESTNET) ); console.log(JSON.stringify(r, null, 2)); }); diff --git a/packages/net/tests/thor/transactions/RetrieveRawTransactionByIID.testnet.test.ts b/packages/net/tests/thor/transactions/RetrieveRawTransactionByIID.testnet.test.ts new file mode 100644 index 000000000..cd892efb8 --- /dev/null +++ b/packages/net/tests/thor/transactions/RetrieveRawTransactionByIID.testnet.test.ts @@ -0,0 +1,18 @@ +import { describe, test } from '@jest/globals'; +import { TxId } from '@vechain/sdk-core'; +import { + FetchHttpClient, + RetrieveRawTransactionByID, + ThorNetworks +} from '../../../src'; + +describe('RetrieveRawTransactionByID testnet tests', () => { + test('ok <- askTo', async () => { + const txId = TxId.of( + '0xb6b5b47a5eee8b14e5222ac1bb957c0bbdc3d489850b033e3e544d9ca0cef934' + ); + const httpClient = FetchHttpClient.at(ThorNetworks.MAINNET); + const r = await RetrieveRawTransactionByID.of(txId).askTo(httpClient); + console.log(JSON.stringify(r, null, 2)); + }); +}); diff --git a/packages/net/tests/thor/transactions/RetrieveTransactionByIID.testnet.test.ts b/packages/net/tests/thor/transactions/RetrieveTransactionByIID.testnet.test.ts index c91386e2c..6eb7a95ca 100644 --- a/packages/net/tests/thor/transactions/RetrieveTransactionByIID.testnet.test.ts +++ b/packages/net/tests/thor/transactions/RetrieveTransactionByIID.testnet.test.ts @@ -11,7 +11,7 @@ describe('RetrieveTransactionByID testnet tests', () => { const txId = TxId.of( '0xb6b5b47a5eee8b14e5222ac1bb957c0bbdc3d489850b033e3e544d9ca0cef934' ); - const httpClient = new FetchHttpClient(ThorNetworks.MAINNET); + const httpClient = FetchHttpClient.at(ThorNetworks.MAINNET); const r = await RetrieveTransactionByID.of(txId).askTo(httpClient); console.log(JSON.stringify(r, null, 2)); }); From b6e518f15b8ca5435528f0c7efff7710ac1cbe83 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Fri, 6 Dec 2024 18:03:00 +0000 Subject: [PATCH 28/98] feat: v2 thor transactions dev... --- packages/net/src/thor/transactions/Event.ts | 33 ++++++++ .../thor/transactions/GetTxReceiptResponse.ts | 24 ++++++ packages/net/src/thor/transactions/Receipt.ts | 42 ++++++++++ .../net/src/thor/transactions/ReceiptMeta.ts | 28 +++++++ .../src/thor/transactions/ReceiptOutput.ts | 37 +++++++++ .../RetrieveTransactionReceipt.ts | 83 +++++++++++++++++++ .../net/src/thor/transactions/Transfer.ts | 29 +++++++ packages/net/src/thor/transactions/index.ts | 9 +- 8 files changed, 284 insertions(+), 1 deletion(-) create mode 100644 packages/net/src/thor/transactions/Event.ts create mode 100644 packages/net/src/thor/transactions/GetTxReceiptResponse.ts create mode 100644 packages/net/src/thor/transactions/Receipt.ts create mode 100644 packages/net/src/thor/transactions/ReceiptMeta.ts create mode 100644 packages/net/src/thor/transactions/ReceiptOutput.ts create mode 100644 packages/net/src/thor/transactions/RetrieveTransactionReceipt.ts create mode 100644 packages/net/src/thor/transactions/Transfer.ts diff --git a/packages/net/src/thor/transactions/Event.ts b/packages/net/src/thor/transactions/Event.ts new file mode 100644 index 000000000..0336c0cf7 --- /dev/null +++ b/packages/net/src/thor/transactions/Event.ts @@ -0,0 +1,33 @@ +import { Address, HexUInt, ThorId } from '@vechain/sdk-core'; + +class Event { + readonly address: Address; + readonly topics: ThorId[]; + readonly data: HexUInt; + + constructor(json: EventJSON) { + this.address = Address.of(json.address); + this.topics = json.topics.map( + (topic: string): ThorId => ThorId.of(topic) + ); + this.data = HexUInt.of(json.data); + } + + toJSON(): EventJSON { + return { + address: this.address.toString(), + topics: this.topics.map((topic: ThorId): string => + topic.toString() + ), + data: this.data.toString() + } satisfies EventJSON; + } +} + +interface EventJSON { + address: string; + topics: string[]; + data: string; +} + +export { Event, type EventJSON }; diff --git a/packages/net/src/thor/transactions/GetTxReceiptResponse.ts b/packages/net/src/thor/transactions/GetTxReceiptResponse.ts new file mode 100644 index 000000000..6cd583f98 --- /dev/null +++ b/packages/net/src/thor/transactions/GetTxReceiptResponse.ts @@ -0,0 +1,24 @@ +import { Receipt, type ReceiptJSON } from './Receipt'; +import { ReceiptMeta, type ReceiptMetaJSON } from './ReceiptMeta'; + +class GetTxReceiptResponse extends Receipt { + readonly meta: ReceiptMeta; + + constructor(json: GetTxReceiptResponseJSON) { + super(json); + this.meta = new ReceiptMeta(json.meta); + } + + toJSON(): GetTxReceiptResponseJSON { + return { + ...super.toJSON(), + meta: this.meta.toJSON() + } satisfies GetTxReceiptResponseJSON; + } +} + +interface GetTxReceiptResponseJSON extends ReceiptJSON { + meta: ReceiptMetaJSON; +} + +export { GetTxReceiptResponse, type GetTxReceiptResponseJSON }; diff --git a/packages/net/src/thor/transactions/Receipt.ts b/packages/net/src/thor/transactions/Receipt.ts new file mode 100644 index 000000000..40ac4da90 --- /dev/null +++ b/packages/net/src/thor/transactions/Receipt.ts @@ -0,0 +1,42 @@ +import { ReceiptOutput, type ReceiptOutputJSON } from './ReceiptOutput'; +import { Address, Hex, HexUInt, Units, VTHO } from '@vechain/sdk-core'; + +class Receipt { + readonly gasUsed: VTHO; + readonly gasPayer: Address; + readonly paid: VTHO; + readonly reward: VTHO; + readonly reverted: boolean; + readonly outputs: ReceiptOutput[]; + + constructor(json: ReceiptJSON) { + this.gasUsed = VTHO.of(json.gasUsed); + this.gasPayer = Address.of(json.gasPayer); + this.paid = VTHO.of(Hex.of(json.paid).bi, Units.wei); + this.reward = VTHO.of(Hex.of(json.reward).bi, Units.wei); + this.reverted = json.reverted; + this.outputs = json.outputs.map((output) => new ReceiptOutput(output)); + } + + toJSON(): ReceiptJSON { + return { + gasUsed: Number(this.gasUsed.wei), + gasPayer: this.gasPayer.toString(), + paid: HexUInt.of(this.paid.wei).toString(), + reward: HexUInt.of(this.reward.wei).toString(), + reverted: this.reverted, + outputs: this.outputs.map((output) => output.toJSON()) + }; + } +} + +interface ReceiptJSON { + gasUsed: number; + gasPayer: string; + paid: string; + reward: string; + reverted: boolean; + outputs: ReceiptOutputJSON[]; +} + +export { Receipt, type ReceiptJSON }; diff --git a/packages/net/src/thor/transactions/ReceiptMeta.ts b/packages/net/src/thor/transactions/ReceiptMeta.ts new file mode 100644 index 000000000..fe45978e9 --- /dev/null +++ b/packages/net/src/thor/transactions/ReceiptMeta.ts @@ -0,0 +1,28 @@ +import { TxMeta, type TxMetaJSON } from './TxMeta'; +import { Address, TxId } from '@vechain/sdk-core'; + +class ReceiptMeta extends TxMeta { + txID: TxId; + txOrigin: Address; + + constructor(json: ReceiptMetaJSON) { + super(json); + this.txID = TxId.of(json.txID); + this.txOrigin = Address.of(json.txOrigin); + } + + toJSON(): ReceiptMetaJSON { + return { + ...super.toJSON(), + txID: this.txID.toString(), + txOrigin: this.txOrigin.toString() + } satisfies ReceiptMetaJSON; + } +} + +interface ReceiptMetaJSON extends TxMetaJSON { + txID: string; + txOrigin: string; +} + +export { ReceiptMeta, type ReceiptMetaJSON }; diff --git a/packages/net/src/thor/transactions/ReceiptOutput.ts b/packages/net/src/thor/transactions/ReceiptOutput.ts new file mode 100644 index 000000000..01dbde469 --- /dev/null +++ b/packages/net/src/thor/transactions/ReceiptOutput.ts @@ -0,0 +1,37 @@ +import { Event, type EventJSON } from './Event'; +import { Transfer, type TransferJSON } from './Transfer'; +import { Address } from '@vechain/sdk-core'; + +class ReceiptOutput { + readonly contractAddress: Address; + readonly events: Event[]; + readonly transfers: Transfer[]; + + constructor(json: ReceiptOutputJSON) { + this.contractAddress = Address.of(json.contractAddress); + this.events = json.events.map( + (eventJSON): Event => new Event(eventJSON) + ); + this.transfers = json.transfers.map( + (transferJSON): Transfer => new Transfer(transferJSON) + ); + } + + toJSON(): ReceiptOutputJSON { + return { + contractAddress: this.contractAddress.toString(), + events: this.events.map((event): EventJSON => event.toJSON()), + transfers: this.transfers.map( + (transfer): TransferJSON => transfer.toJSON() + ) + } satisfies ReceiptOutputJSON; + } +} + +interface ReceiptOutputJSON { + contractAddress: string; + events: EventJSON[]; + transfers: TransferJSON[]; +} + +export { ReceiptOutput, type ReceiptOutputJSON }; diff --git a/packages/net/src/thor/transactions/RetrieveTransactionReceipt.ts b/packages/net/src/thor/transactions/RetrieveTransactionReceipt.ts new file mode 100644 index 000000000..0b54dc561 --- /dev/null +++ b/packages/net/src/thor/transactions/RetrieveTransactionReceipt.ts @@ -0,0 +1,83 @@ +import { type BlockId, type TxId } from '@vechain/sdk-core'; +import { type HttpClient, type HttpPath, type HttpQuery } from '../../http'; +import { + GetTxReceiptResponse, + type GetTxReceiptResponseJSON +} from './GetTxReceiptResponse'; +import { type ThorRequest } from '../ThorRequest'; +import { type ThorResponse } from '../ThorResponse'; + +class RetrieveTransactionReceipt + implements ThorRequest +{ + readonly path: RetrieveTransactionReceiptPath; + + readonly query: RetrieveTransactionReceiptQuery; + + constructor( + path: RetrieveTransactionReceiptPath, + query: RetrieveTransactionReceiptQuery + ) { + this.path = path; + this.query = query; + } + + async askTo( + httpClient: HttpClient + ): Promise> { + const response = await httpClient.get(this.path, this.query); + const responseBody = + (await response.json()) as GetTxReceiptResponseJSON; + return { + request: this, + response: new GetTxReceiptResponse(responseBody) + } satisfies ThorResponse< + RetrieveTransactionReceipt, + GetTxReceiptResponse + >; + } + + static of(txId: TxId): RetrieveTransactionReceipt { + return new RetrieveTransactionReceipt( + new RetrieveTransactionReceiptPath(txId), + new RetrieveTransactionReceiptQuery(null) + ); + } + + withHead(head: BlockId | null = null): RetrieveTransactionReceipt { + return new RetrieveTransactionReceipt( + this.path, + new RetrieveTransactionReceiptQuery(head) + ); + } +} + +class RetrieveTransactionReceiptPath implements HttpPath { + readonly txId: TxId; + + constructor(txId: TxId) { + this.txId = txId; + } + + get path(): string { + return `/transactions/${this.txId}/receipt`; + } +} + +class RetrieveTransactionReceiptQuery implements HttpQuery { + readonly head: BlockId | null; + + constructor(head: BlockId | null) { + this.head = head; + } + + get query(): string { + return this.head === null ? '' : `${this.head}&`; + } +} + +export { + RetrieveTransactionReceipt, + RetrieveTransactionReceiptPath, + RetrieveTransactionReceiptQuery +}; diff --git a/packages/net/src/thor/transactions/Transfer.ts b/packages/net/src/thor/transactions/Transfer.ts new file mode 100644 index 000000000..ea63164d1 --- /dev/null +++ b/packages/net/src/thor/transactions/Transfer.ts @@ -0,0 +1,29 @@ +import { Address, VET } from '@vechain/sdk-core'; + +class Transfer { + readonly sender: Address; + readonly recipient: Address; + readonly amount: VET; + + constructor(json: TransferJSON) { + this.sender = Address.of(json.sender); + this.recipient = Address.of(json.recipient); + this.amount = VET.of(json.amount); + } + + toJSON(): TransferJSON { + return { + sender: this.sender.toString(), + recipient: this.recipient.toString(), + amount: this.amount.toString() + } satisfies TransferJSON; + } +} + +interface TransferJSON { + sender: string; + recipient: string; + amount: string; +} + +export { Transfer, type TransferJSON }; diff --git a/packages/net/src/thor/transactions/index.ts b/packages/net/src/thor/transactions/index.ts index e5369bd27..ea4b0b574 100644 --- a/packages/net/src/thor/transactions/index.ts +++ b/packages/net/src/thor/transactions/index.ts @@ -1,6 +1,13 @@ export * from './Clause'; +export * from './Event'; export * from './GetRawTxResponse'; export * from './GetTxResponse'; -export * from './RetrieveTransactionByID'; +export * from './GetTxReceiptResponse'; +export * from './Receipt'; +export * from './ReceiptMeta'; +export * from './ReceiptOutput'; export * from './RetrieveRawTransactionByID'; +export * from './RetrieveTransactionByID'; +export * from './RetrieveTransactionReceipt'; +export * from './Transfer'; export * from './TxMeta'; From c7022803187d3623ecfed3217a93968f16d36aab Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Sat, 7 Dec 2024 17:20:38 +0000 Subject: [PATCH 29/98] feat: v2 thor transactions dev... --- packages/net/src/http/FetchHttpClient.ts | 24 ++++++++++++- packages/net/src/http/HttpClient.ts | 6 ++++ .../src/thor/transactions/SendTransaction.ts | 35 +++++++++++++++++++ packages/net/src/thor/transactions/index.ts | 1 + .../http/FetchHttpClient.testnet.test.ts | 19 ++++++++++ ...RetrieveTransactionReceipt.testnet.test.ts | 18 ++++++++++ 6 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 packages/net/src/thor/transactions/SendTransaction.ts create mode 100644 packages/net/tests/thor/transactions/RetrieveTransactionReceipt.testnet.test.ts diff --git a/packages/net/src/http/FetchHttpClient.ts b/packages/net/src/http/FetchHttpClient.ts index cbcf207c5..e699e59ac 100644 --- a/packages/net/src/http/FetchHttpClient.ts +++ b/packages/net/src/http/FetchHttpClient.ts @@ -4,7 +4,6 @@ import { type HttpQuery } from './HttpQuery'; class FetchHttpClient implements HttpClient { private static readonly PATH_SEPARATOR = '/'; - private static readonly QUERY_SEPARATOR = '?'; public readonly baseURL: string; @@ -49,6 +48,29 @@ class FetchHttpClient implements HttpClient { const response = await fetch(this.onRequest(request)); return this.onResponse(response); } + + async post( + httpPath: HttpPath = { + path: '' + }, + httpQuery: HttpQuery = { + query: '' + }, + body?: unknown + ): Promise { + const path = httpPath.path.startsWith(FetchHttpClient.PATH_SEPARATOR) + ? httpPath.path.substring(1) + : httpPath.path; + const request = new Request( + `${this.baseURL}${FetchHttpClient.PATH_SEPARATOR}${path}${httpQuery.query}`, + { + body: JSON.stringify(body), + method: 'POST' + } + ); + const response = await fetch(this.onRequest(request)); + return this.onResponse(response); + } } export { FetchHttpClient }; diff --git a/packages/net/src/http/HttpClient.ts b/packages/net/src/http/HttpClient.ts index 21c27dccb..aea4e43e2 100644 --- a/packages/net/src/http/HttpClient.ts +++ b/packages/net/src/http/HttpClient.ts @@ -3,4 +3,10 @@ import { type HttpQuery } from './HttpQuery'; export interface HttpClient { get: (httpPath: HttpPath, httpQuery: HttpQuery) => Promise; + + post: ( + httpPath: HttpPath, + httpQuery: HttpQuery, + body?: unknown + ) => Promise; } diff --git a/packages/net/src/thor/transactions/SendTransaction.ts b/packages/net/src/thor/transactions/SendTransaction.ts new file mode 100644 index 000000000..7e3b8c413 --- /dev/null +++ b/packages/net/src/thor/transactions/SendTransaction.ts @@ -0,0 +1,35 @@ +import { TxId } from '@vechain/sdk-core'; +import { type HttpClient, type HttpPath } from '../../http'; +import { type ThorRequest } from '../ThorRequest'; +import { type ThorResponse } from '../ThorResponse'; + +class SendTransaction implements ThorRequest { + static readonly PATH: HttpPath = { path: '/transactions' }; + + readonly body: unknown; + + constructor(body: unknown) { + this.body = body; + } + + async askTo( + httpClient: HttpClient + ): Promise> { + const response = await httpClient.post( + SendTransaction.PATH, + { query: '' }, + this.body + ); + const responseBody = await response.text(); + return { + request: this, + response: TxId.of(responseBody) + } satisfies ThorResponse; + } + + static of(body: unknown): SendTransaction { + return new SendTransaction(body); + } +} + +export { SendTransaction }; diff --git a/packages/net/src/thor/transactions/index.ts b/packages/net/src/thor/transactions/index.ts index ea4b0b574..41cd0ca72 100644 --- a/packages/net/src/thor/transactions/index.ts +++ b/packages/net/src/thor/transactions/index.ts @@ -9,5 +9,6 @@ export * from './ReceiptOutput'; export * from './RetrieveRawTransactionByID'; export * from './RetrieveTransactionByID'; export * from './RetrieveTransactionReceipt'; +export * from './SendTransaction'; export * from './Transfer'; export * from './TxMeta'; diff --git a/packages/net/tests/http/FetchHttpClient.testnet.test.ts b/packages/net/tests/http/FetchHttpClient.testnet.test.ts index a979a34f6..b9c4d250b 100644 --- a/packages/net/tests/http/FetchHttpClient.testnet.test.ts +++ b/packages/net/tests/http/FetchHttpClient.testnet.test.ts @@ -20,4 +20,23 @@ describe('FetchHttpClient testnet tests', () => { } ).get(); }); + + test('ok <- post', async () => { + const expected = { + hello: 'world' + }; + const response = await new FetchHttpClient( + 'https://httpbin.org', + (request: Request) => { + console.log(request); + return request; + }, + (response: Response) => { + console.log(response); + return response; + } + ).post({ path: '/post' }, { query: '' }, expected); + const actual: unknown = await response.json(); + console.log(JSON.stringify(actual, null, 2)); + }); }); diff --git a/packages/net/tests/thor/transactions/RetrieveTransactionReceipt.testnet.test.ts b/packages/net/tests/thor/transactions/RetrieveTransactionReceipt.testnet.test.ts new file mode 100644 index 000000000..b9ceef825 --- /dev/null +++ b/packages/net/tests/thor/transactions/RetrieveTransactionReceipt.testnet.test.ts @@ -0,0 +1,18 @@ +import { describe, test } from '@jest/globals'; +import { TxId } from '@vechain/sdk-core'; +import { + FetchHttpClient, + RetrieveTransactionReceipt, + ThorNetworks +} from '../../../src'; + +describe('RetrieveTransactionReceipt testnet tests', () => { + test('ok <- askTo', async () => { + const txId = TxId.of( + '0xb6b5b47a5eee8b14e5222ac1bb957c0bbdc3d489850b033e3e544d9ca0cef934' + ); + const httpClient = FetchHttpClient.at(ThorNetworks.MAINNET); + const r = await RetrieveTransactionReceipt.of(txId).askTo(httpClient); + console.log(JSON.stringify(r, null, 2)); + }); +}); From f73ad0dbb85124fa89af3717aff9833bd2def633 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Sun, 8 Dec 2024 18:26:32 +0000 Subject: [PATCH 30/98] feat: v2 thor transactions dev... --- .../src/thor/transactions/SendTransaction.ts | 25 +++++++++----- .../transactions/SendTransaction.solo.test.ts | 34 +++++++++++++++++++ 2 files changed, 50 insertions(+), 9 deletions(-) create mode 100644 packages/net/tests/thor/transactions/SendTransaction.solo.test.ts diff --git a/packages/net/src/thor/transactions/SendTransaction.ts b/packages/net/src/thor/transactions/SendTransaction.ts index 7e3b8c413..9bd96462d 100644 --- a/packages/net/src/thor/transactions/SendTransaction.ts +++ b/packages/net/src/thor/transactions/SendTransaction.ts @@ -1,4 +1,4 @@ -import { TxId } from '@vechain/sdk-core'; +import { HexUInt, TxId } from '@vechain/sdk-core'; import { type HttpClient, type HttpPath } from '../../http'; import { type ThorRequest } from '../ThorRequest'; import { type ThorResponse } from '../ThorResponse'; @@ -6,10 +6,10 @@ import { type ThorResponse } from '../ThorResponse'; class SendTransaction implements ThorRequest { static readonly PATH: HttpPath = { path: '/transactions' }; - readonly body: unknown; + readonly encoded: Uint8Array; - constructor(body: unknown) { - this.body = body; + constructor(encoded: Uint8Array) { + this.encoded = encoded; } async askTo( @@ -18,18 +18,25 @@ class SendTransaction implements ThorRequest { const response = await httpClient.post( SendTransaction.PATH, { query: '' }, - this.body + { + raw: HexUInt.of(this.encoded).toString() + } ); - const responseBody = await response.text(); + const responseBody = + (await response.json()) as SendTransactionResponseJSON; return { request: this, - response: TxId.of(responseBody) + response: TxId.of(responseBody.id) } satisfies ThorResponse; } - static of(body: unknown): SendTransaction { - return new SendTransaction(body); + static of(encoded: Uint8Array): SendTransaction { + return new SendTransaction(encoded); } } +interface SendTransactionResponseJSON { + id: string; +} + export { SendTransaction }; diff --git a/packages/net/tests/thor/transactions/SendTransaction.solo.test.ts b/packages/net/tests/thor/transactions/SendTransaction.solo.test.ts new file mode 100644 index 000000000..da12b7efa --- /dev/null +++ b/packages/net/tests/thor/transactions/SendTransaction.solo.test.ts @@ -0,0 +1,34 @@ +import { describe, test } from '@jest/globals'; + +import { THOR_SOLO_URL, ThorClient } from '../../../../network/'; +import { + transfer1VTHOClause, + transferTransactionBody +} from '../../../../network/tests/thor-client/transactions/fixture'; +import { TEST_ACCOUNTS } from '../../../../network/tests/fixture'; +import { HexUInt, Transaction } from '@vechain/sdk-core'; +import { FetchHttpClient, SendTransaction } from '../../../src'; + +describe('SendTransaction solo tests', () => { + test('ok <- askTo', async () => { + const thorSoloClient = ThorClient.at(THOR_SOLO_URL); + const gasResult = await thorSoloClient.gas.estimateGas( + [transfer1VTHOClause], + TEST_ACCOUNTS.TRANSACTION.TRANSACTION_SENDER.address + ); + console.log(gasResult); + const tx = Transaction.of({ + ...transferTransactionBody, + gas: gasResult.totalGas, + nonce: 10000000 + }).sign( + HexUInt.of(TEST_ACCOUNTS.TRANSACTION.TRANSACTION_SENDER.privateKey) + .bytes + ).encoded; + console.log(tx); + const r = await SendTransaction.of(tx).askTo( + FetchHttpClient.at(THOR_SOLO_URL) + ); + console.log(r); + }); +}); From 3475fcbe11668ae9a81898f8bf857dcb4e7350b2 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Mon, 9 Dec 2024 11:15:35 +0000 Subject: [PATCH 31/98] feat: v2 thor transactions dev... --- packages/net/src/thor/ThorNetworks.ts | 2 +- packages/net/src/thor/explorer/index.ts | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/net/src/thor/ThorNetworks.ts b/packages/net/src/thor/ThorNetworks.ts index 991dd1f80..0d570c137 100644 --- a/packages/net/src/thor/ThorNetworks.ts +++ b/packages/net/src/thor/ThorNetworks.ts @@ -1,6 +1,6 @@ enum ThorNetworks { MAINNET = 'https://mainnet.vechain.org/', - SOLONET = 'https://localhost:8669/', + SOLONET = 'http://localhost:8669/', TESTNET = 'https://testnet.vechain.org/' } diff --git a/packages/net/src/thor/explorer/index.ts b/packages/net/src/thor/explorer/index.ts index 65f9c29a1..acd36dbab 100644 --- a/packages/net/src/thor/explorer/index.ts +++ b/packages/net/src/thor/explorer/index.ts @@ -1,7 +1,8 @@ import { FetchHttpClient } from '../../http'; import { ThorNetworks } from '../ThorNetworks'; import { RetrieveBlock, RetrieveBlockPath } from '../blocks'; -import { Revision } from '@vechain/sdk-core'; +import { Revision, TxId } from '@vechain/sdk-core'; +import { RetrieveTransactionByID } from '../transactions'; async function getBestBlockNumber( httpClient: FetchHttpClient @@ -13,16 +14,23 @@ async function getBestBlockNumber( } async function explore(): Promise { - const httpClient = new FetchHttpClient(ThorNetworks.TESTNET); + const httpClient = FetchHttpClient.at(ThorNetworks.SOLONET); const lastBlockNumber = await getBestBlockNumber(httpClient); for (let blockNumber = lastBlockNumber; blockNumber >= 0; blockNumber--) { const block = ( await RetrieveBlock.of(Revision.of(blockNumber)).askTo(httpClient) ).response; console.log(block.number, lastBlockNumber); - block.transactions.forEach((tx) => { - console.log(tx); - }); + for (const txid of block.transactions) { + console.log(txid); + const tx = ( + await RetrieveTransactionByID.of(TxId.of(txid)).askTo( + httpClient + ) + ).response; + + console.log(JSON.stringify(tx, null, 2)); + } } } From f1dffc42dfae2772eb927671b70ba9f000061d3b Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Mon, 9 Dec 2024 11:20:37 +0000 Subject: [PATCH 32/98] feat: v2 thor transactions dev... --- packages/net/src/thor/explorer/index.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/net/src/thor/explorer/index.ts b/packages/net/src/thor/explorer/index.ts index acd36dbab..a26da9ba7 100644 --- a/packages/net/src/thor/explorer/index.ts +++ b/packages/net/src/thor/explorer/index.ts @@ -20,21 +20,21 @@ async function explore(): Promise { const block = ( await RetrieveBlock.of(Revision.of(blockNumber)).askTo(httpClient) ).response; - console.log(block.number, lastBlockNumber); + console.log(`BLOCK ${block.number} of ${lastBlockNumber}`); for (const txid of block.transactions) { - console.log(txid); + console.log(`TXID ${txid}`); const tx = ( await RetrieveTransactionByID.of(TxId.of(txid)).askTo( httpClient ) ).response; - console.log(JSON.stringify(tx, null, 2)); + console.log(`TX: ${JSON.stringify(tx, null, 2)}`); } } } -console.log('explorer'); -void explore().then((r) => { - console.log(r); +console.log('Thor Scanner...'); +void explore().then((_r) => { + console.log('End of all jobs.'); }); From eab7a7fbfa72b36cc4c43dff3c4ed9405fdb13c1 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 10 Dec 2024 16:05:45 +0000 Subject: [PATCH 33/98] fix: 1560 Transaction.ts allows making of incomplete signed instances --- .../network/thor/transactions/transactions.md | 171 ++++++++++++++++++ .../transactions/RetrieveTransactionByID.ts | 2 +- 2 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 docs/diagrams/v2/network/thor/transactions/transactions.md diff --git a/docs/diagrams/v2/network/thor/transactions/transactions.md b/docs/diagrams/v2/network/thor/transactions/transactions.md new file mode 100644 index 000000000..1b43391ef --- /dev/null +++ b/docs/diagrams/v2/network/thor/transactions/transactions.md @@ -0,0 +1,171 @@ +```mermaid +classDiagram + class Clause { + to: Address + value: VET + data: HexUInt + constructor(json: EventJSON) + toJSON() EventJSON + } + class ClauseJSON { + <> + to: string + value: string + data string + } + class Event { + address: Address + topics: ThorId[] + data HexUInt + constructor(json: EventJSON) + toJSON() EventJSON + } + class EventJSON { + <> + address: string + topics: string[] + data: string + } + class GetRawTxResponse { + raw: HexUInt + meta: TxMeta + constructor(json: GetTawTxResponseJSON) + toJSON() GetTawTxResponseJSON + } + class GetTawTxResponseJSON { + <> + raw: string; + meta: TxMetaJSON + } + class GetTxReceiptResponse { + meta: ReceiptMeta + constructor(json: GetTxReceiptResponseJSON) + toJSON(): GetTxReceiptResponseJSON + } + class GetTxReceiptResponseJSON { + meta: ReceiptMetaJSON + } + class GetTxResponse { + id: TxId + origin: Address + delegator: Address|null + size: UInt + chainTag: UInt + blockRef: BlockId + expiration: UInt + clauses: Clause[] + gasPriceCoef: UInt + gas: VTHO + dependsOn: TxId|null + nonce: Nonce + meta: TxMeta + constructor(json: GetTxResponseJSON) + toJSON() GetTxResponseJSON + } + class GetTxResponseJSON { + <> + id: string + origin: string + delegator: string|null + size: number + chainTag: number + blockRef: string + expiration: number + clauses: ClauseJSON[] + gasPriceCoef: number + gas: number + dependsOn: string|null + nonce: string + meta: TxMetaJSON + } + class Receipt { + gasUsed: VTHO + gasPayer: Address + paid: VTHO + reward: VTHO + reverted: boolean + outputs: ReceiptOutput[] + constructor(json: ReceiptJSON) + toJSON() ReceiptJSON + } + class ReceiptJSON { + <> + gasUsed: number; + gasPayer: string; + paid: string; + reward: string; + reverted: boolean; + outputs: ReceiptOutputJSON[]; + } + class ReceiptMeta { + txID: TxId + txOrigin: Address + constructor(json: ReceiptMetaJSON) + toJSON() ReceiptMetaJSON + } + class ReceiptMetaJSON { + <> + txID: string + txOrigin: string + } + class ReceiptOutput { + contractAddress: Address + events: Event[] + transfers: Transfer[] + constructor(json: ReceiptOutputJSON) + toJSON(): ReceiptOutputJSON + } + class ReceiptOutputJSON { + <> + contractAddress: string + events: EventJSON[] + transfers: TransferJSON[] + } + class RetrieveRawTransactionByID { + path: RetrieveRawTransactionByIDPath; + query: RetrieveRawTransactionByIDQuery; + constructor(path: RetrieveRawTransactionByIDPath, query: RetrieveRawTransactionByIDQuery) + askTo(httpClient: HttpClient): Promise~ThorResponse~ RetrieveRawTransactionByID, GetRawTxResponse~~ + of(txId: TxId) RetrieveRawTransactionByID + withHead(head: BlockId|null) RetrieveRawTransactionByID + withPending(pending: boolean) RetrieveRawTransactionByID + } + class RetrieveRawTransactionByIDPath { + } + class RetrieveRawTransactionByIDQuery { + } + class RetrieveTransactionByID { + path: RetrieveTransactionByIDPath + query: RetrieveTransactionByIDQuery + constructor(path: RetrieveTransactionByIDPath, query: RetrieveTransactionByIDQuery) + askTo(httpClient: HttpClient) Promise~ThorResponse~ RetrieveTransactionByID, GetTxResponse~~ + of(txId: TxId) RetrieveTransactionByID + withHead(head: BlockId|null): RetrieveTransactionByID + withPending(pending: boolean): RetrieveTransactionByID + } + class RetrieveTransactionByIDPath { + txId: TxId + constructor(txId: TxId) + } + class RetrieveTransactionByIDQuery { + head: BlockId | null; + pending: boolean + constructor(head: BlockId|null, pending: boolean) RetrieveTransactionByIDQuery + } + class RetrieveTransactionReceipt { + path: RetrieveTransactionReceiptPath + query: RetrieveTransactionReceiptQuery + constructor(path: RetrieveTransactionReceiptPath, query: RetrieveTransactionReceiptQuery) + askTo(httpClient: HttpClient): Promise~ThorResponse~RetrieveTransactionReceipt, GetTxReceiptResponse~~ + of(txId: TxId): RetrieveTransactionReceipt + withHead(head: BlockId): RetrieveTransactionReceipt + } + class RetrieveTransactionReceiptPath { + txId: TxId + constructor(txId: TxId) + } + class RetrieveTransactionReceiptQuery { + head: BlockId|null; + constructor(head: BlockId|null) + } +``` diff --git a/packages/net/src/thor/transactions/RetrieveTransactionByID.ts b/packages/net/src/thor/transactions/RetrieveTransactionByID.ts index 6d16f00be..e952837d1 100644 --- a/packages/net/src/thor/transactions/RetrieveTransactionByID.ts +++ b/packages/net/src/thor/transactions/RetrieveTransactionByID.ts @@ -66,7 +66,7 @@ class RetrieveTransactionByIDPath implements HttpPath { class RetrieveTransactionByIDQuery implements HttpQuery { readonly head: BlockId | null; - readonly pending; + readonly pending: boolean; constructor(head: BlockId | null, pending: boolean) { this.head = head; From 6ced514efdcc5f146797588c9900fe2576c341fd Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 11 Dec 2024 11:39:57 +0000 Subject: [PATCH 34/98] feat: 1484 net in dev... --- .../network/thor/transactions/transactions.md | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/docs/diagrams/v2/network/thor/transactions/transactions.md b/docs/diagrams/v2/network/thor/transactions/transactions.md index 1b43391ef..923727187 100644 --- a/docs/diagrams/v2/network/thor/transactions/transactions.md +++ b/docs/diagrams/v2/network/thor/transactions/transactions.md @@ -156,7 +156,7 @@ classDiagram path: RetrieveTransactionReceiptPath query: RetrieveTransactionReceiptQuery constructor(path: RetrieveTransactionReceiptPath, query: RetrieveTransactionReceiptQuery) - askTo(httpClient: HttpClient): Promise~ThorResponse~RetrieveTransactionReceipt, GetTxReceiptResponse~~ + askTo(httpClient: HttpClient): Promise~ThorResponse~ RetrieveTransactionReceipt, GetTxReceiptResponse~~ of(txId: TxId): RetrieveTransactionReceipt withHead(head: BlockId): RetrieveTransactionReceipt } @@ -168,4 +168,40 @@ classDiagram head: BlockId|null; constructor(head: BlockId|null) } + class SendTransaction { + PATH: HttpPath + encoded: Uint8Array + askTo(httpClient: httpClient) + of(encoded: Uint8Array): SendTransaction + } + class SendTransactionResponseJSON { + id: string + <> + } + class Transfer { + sender: Address; + recipient: Address; + amount: VET; + constructor(json: TransferJSON) + toJSON(): TransferJSON + } + class TransferJSON { + <> + sender: string; + recipient: string; + amount: string; + } + class TxMeta { + blockID: BlockId; + blockNumber: UInt; + blockTimestamp: bigint; + constructor(json: TxMetaJSON) + toJSON(): TxMetaJSON + } + class TxMetaJSON { + <> + blockID: string; + blockNumber: number; + blockTimestamp: bigint; + } ``` From af7bb8ba22abbf0a95de68bf644efce843bef45c Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 11 Dec 2024 15:20:03 +0000 Subject: [PATCH 35/98] feat: 1484 net in dev... --- .../network/thor/transactions/transactions.md | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/docs/diagrams/v2/network/thor/transactions/transactions.md b/docs/diagrams/v2/network/thor/transactions/transactions.md index 923727187..8741ed6f4 100644 --- a/docs/diagrams/v2/network/thor/transactions/transactions.md +++ b/docs/diagrams/v2/network/thor/transactions/transactions.md @@ -203,5 +203,41 @@ classDiagram blockID: string; blockNumber: number; blockTimestamp: bigint; - } + } + class ThorRequest { + <> + askTo: (httpClient: HttpClient) + } + class HttpPath { + <> + } + class HttpQuery { + <> + } + RetrieveTransactionByIDPath ..|> HttpPath + RetrieveTransactionReceiptPath ..|> HttpPath + RetrieveTransactionByIDQuery ..|> HttpQuery + RetrieveTransactionReceiptQuery ..|> HttpQuery + ThorRequest <|.. RetrieveRawTransactionByID + ThorRequest <|.. RetrieveTransactionByID + ThorRequest <|.. RetrieveTransactionReceipt + ThorRequest <|.. SendTransaction + Receipt <|-- GetTxReceiptResponse + RetrieveTransactionByIDPath <|-- RetrieveRawTransactionByIDPath + RetrieveTransactionByIDQuery <|-- RetrieveRawTransactionByIDQuery + RetrieveRawTransactionByID --* RetrieveRawTransactionByIDPath + RetrieveRawTransactionByID --* RetrieveRawTransactionByIDQuery + RetrieveTransactionByID --* RetrieveTransactionByIDPath + RetrieveTransactionByID --* RetrieveRawTransactionByIDQuery + RetrieveTransactionReceipt --* RetrieveTransactionReceiptPath + RetrieveTransactionReceipt --* RetrieveTransactionReceiptQuery + GetRawTxResponse --* TxMeta + GetTxResponse --* Clause + GetTxResponse --* Nonce + GetTxResponse --* TxMeta + Receipt --* ReceiptOutput + ReceiptOutput --* Event + ReceiptOutput --* Transfer + Clause --> ClauseJSON + Event --> EventJSON ``` From 02a86e61996088515e6d1fb1d3d15c196f0e0da4 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Thu, 12 Dec 2024 12:00:23 +0100 Subject: [PATCH 36/98] feat: 1484 net in dev... --- .../network/thor/transactions/transactions.md | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/docs/diagrams/v2/network/thor/transactions/transactions.md b/docs/diagrams/v2/network/thor/transactions/transactions.md index 8741ed6f4..49759aeb9 100644 --- a/docs/diagrams/v2/network/thor/transactions/transactions.md +++ b/docs/diagrams/v2/network/thor/transactions/transactions.md @@ -32,7 +32,7 @@ classDiagram constructor(json: GetTawTxResponseJSON) toJSON() GetTawTxResponseJSON } - class GetTawTxResponseJSON { + class GetRawTxResponseJSON { <> raw: string; meta: TxMetaJSON @@ -174,10 +174,6 @@ classDiagram askTo(httpClient: httpClient) of(encoded: Uint8Array): SendTransaction } - class SendTransactionResponseJSON { - id: string - <> - } class Transfer { sender: Address; recipient: Address; @@ -214,8 +210,10 @@ classDiagram class HttpQuery { <> } + RetrieveRawTransactionByIDPath ..|> HttpPath RetrieveTransactionByIDPath ..|> HttpPath RetrieveTransactionReceiptPath ..|> HttpPath + RetrieveRawTransactionByIDQuery ..|> HttpQuery RetrieveTransactionByIDQuery ..|> HttpQuery RetrieveTransactionReceiptQuery ..|> HttpQuery ThorRequest <|.. RetrieveRawTransactionByID @@ -225,6 +223,7 @@ classDiagram Receipt <|-- GetTxReceiptResponse RetrieveTransactionByIDPath <|-- RetrieveRawTransactionByIDPath RetrieveTransactionByIDQuery <|-- RetrieveRawTransactionByIDQuery + TxMeta <-- ReceiptMeta RetrieveRawTransactionByID --* RetrieveRawTransactionByIDPath RetrieveRawTransactionByID --* RetrieveRawTransactionByIDQuery RetrieveTransactionByID --* RetrieveTransactionByIDPath @@ -232,12 +231,23 @@ classDiagram RetrieveTransactionReceipt --* RetrieveTransactionReceiptPath RetrieveTransactionReceipt --* RetrieveTransactionReceiptQuery GetRawTxResponse --* TxMeta + GetTxReceiptResponse --* ReceiptMeta GetTxResponse --* Clause - GetTxResponse --* Nonce GetTxResponse --* TxMeta Receipt --* ReceiptOutput ReceiptOutput --* Event ReceiptOutput --* Transfer - Clause --> ClauseJSON - Event --> EventJSON + ClauseJSON <-- Clause + EventJSON <-- Event + GetRawTxResponseJSON <-- GetRawTxResponse + GetTxReceiptResponseJSON <-- GetTxReceiptResponse + GetTxResponseJSON <-- GetTxResponse + ReceiptJSON <-- Receipt + ReceiptMetaJSON <-- ReceiptMeta + ReceiptOutputJSON <-- ReceiptOutput + TransferJSON <-- Transfer + TxMetaJSON <-- TxMeta + GetRawTxResponse <-- RetrieveRawTransactionByID + GetTxResponse <-- RetrieveTransactionByID + GetTxReceiptResponse <-- RetrieveTransactionReceipt ``` From ac090e7f8fdc18e2332eb0a2bf92b1fdb2b1402e Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Mon, 16 Dec 2024 19:45:42 +0000 Subject: [PATCH 37/98] feat: 1484 additional VCDM classes direct import: to fix... --- packages/net/src/thor/explorer/index.ts | 4 +- packages/net/src/thor/node/PeerResponse.ts | 4 +- .../src/thor/transactions/GetTxResponse.ts | 6 ++- .../net/src/thor/transactions/ReceiptMeta.ts | 4 +- .../RetrieveRawTransactionByID.ts | 4 +- .../transactions/RetrieveTransactionByID.ts | 4 +- .../RetrieveTransactionReceipt.ts | 4 +- .../src/thor/transactions/SendTransaction.ts | 4 +- packages/net/src/thor/transactions/TxMeta.ts | 4 +- yarn.lock | 46 +++++++++++++++++++ 10 files changed, 75 insertions(+), 9 deletions(-) diff --git a/packages/net/src/thor/explorer/index.ts b/packages/net/src/thor/explorer/index.ts index a26da9ba7..3c1a09d73 100644 --- a/packages/net/src/thor/explorer/index.ts +++ b/packages/net/src/thor/explorer/index.ts @@ -1,9 +1,11 @@ import { FetchHttpClient } from '../../http'; import { ThorNetworks } from '../ThorNetworks'; import { RetrieveBlock, RetrieveBlockPath } from '../blocks'; -import { Revision, TxId } from '@vechain/sdk-core'; +import { Revision } from '@vechain/sdk-core'; import { RetrieveTransactionByID } from '../transactions'; +import { TxId } from '../../../../core/src/vcdm/BlockId'; + async function getBestBlockNumber( httpClient: FetchHttpClient ): Promise { diff --git a/packages/net/src/thor/node/PeerResponse.ts b/packages/net/src/thor/node/PeerResponse.ts index 1923b2a6f..b66dab586 100644 --- a/packages/net/src/thor/node/PeerResponse.ts +++ b/packages/net/src/thor/node/PeerResponse.ts @@ -1,4 +1,6 @@ -import { BlockId, UInt } from '@vechain/sdk-core'; +import { BlockId } from '@vechain/sdk-core'; + +import { UInt } from '../../../../core/src/vcdm/UInt'; interface PeerResponseJSON { name: string; diff --git a/packages/net/src/thor/transactions/GetTxResponse.ts b/packages/net/src/thor/transactions/GetTxResponse.ts index 915d8f417..59e0ce5e2 100644 --- a/packages/net/src/thor/transactions/GetTxResponse.ts +++ b/packages/net/src/thor/transactions/GetTxResponse.ts @@ -1,6 +1,10 @@ import { Clause, type ClauseJSON } from './Clause'; import { TxMeta, type TxMetaJSON } from './TxMeta'; -import { Address, BlockId, Nonce, TxId, UInt, VTHO } from '@vechain/sdk-core'; +import { Address, BlockId, VTHO } from '@vechain/sdk-core'; + +import { Nonce } from '../../../../core/src/vcdm/Nonce'; +import { TxId } from '../../../../core/src/vcdm/BlockId'; +import { UInt } from '../../../../core/src/vcdm/UInt'; class GetTxResponse { readonly id: TxId; diff --git a/packages/net/src/thor/transactions/ReceiptMeta.ts b/packages/net/src/thor/transactions/ReceiptMeta.ts index fe45978e9..2d896a1b9 100644 --- a/packages/net/src/thor/transactions/ReceiptMeta.ts +++ b/packages/net/src/thor/transactions/ReceiptMeta.ts @@ -1,5 +1,7 @@ import { TxMeta, type TxMetaJSON } from './TxMeta'; -import { Address, TxId } from '@vechain/sdk-core'; +import { Address } from '@vechain/sdk-core'; + +import { TxId } from '../../../../core/src/vcdm/BlockId'; class ReceiptMeta extends TxMeta { txID: TxId; diff --git a/packages/net/src/thor/transactions/RetrieveRawTransactionByID.ts b/packages/net/src/thor/transactions/RetrieveRawTransactionByID.ts index 660c66c53..6cd6092cb 100644 --- a/packages/net/src/thor/transactions/RetrieveRawTransactionByID.ts +++ b/packages/net/src/thor/transactions/RetrieveRawTransactionByID.ts @@ -6,11 +6,13 @@ import { GetRawTxResponse, type GetRawTxResponseJSON } from './GetRawTxResponse'; -import { type BlockId, type TxId } from '@vechain/sdk-core'; +import { type BlockId } from '@vechain/sdk-core'; import { type HttpClient } from '../../http'; import { type ThorRequest } from '../ThorRequest'; import { type ThorResponse } from '../ThorResponse'; +import { type TxId } from '../../../../core/src/vcdm/BlockId'; + class RetrieveRawTransactionByID implements ThorRequest { diff --git a/packages/net/src/thor/transactions/RetrieveTransactionByID.ts b/packages/net/src/thor/transactions/RetrieveTransactionByID.ts index e952837d1..cc2625b1e 100644 --- a/packages/net/src/thor/transactions/RetrieveTransactionByID.ts +++ b/packages/net/src/thor/transactions/RetrieveTransactionByID.ts @@ -1,9 +1,11 @@ -import { type BlockId, type TxId } from '@vechain/sdk-core'; +import { type BlockId } from '@vechain/sdk-core'; import { type HttpClient, type HttpPath, type HttpQuery } from '../../http'; import { GetTxResponse, type GetTxResponseJSON } from './GetTxResponse'; import { type ThorRequest } from '../ThorRequest'; import { type ThorResponse } from '../ThorResponse'; +import { type TxId } from '../../../../core/src/vcdm/BlockId'; + class RetrieveTransactionByID implements ThorRequest { diff --git a/packages/net/src/thor/transactions/RetrieveTransactionReceipt.ts b/packages/net/src/thor/transactions/RetrieveTransactionReceipt.ts index 0b54dc561..60994af0a 100644 --- a/packages/net/src/thor/transactions/RetrieveTransactionReceipt.ts +++ b/packages/net/src/thor/transactions/RetrieveTransactionReceipt.ts @@ -1,4 +1,4 @@ -import { type BlockId, type TxId } from '@vechain/sdk-core'; +import { type BlockId } from '@vechain/sdk-core'; import { type HttpClient, type HttpPath, type HttpQuery } from '../../http'; import { GetTxReceiptResponse, @@ -7,6 +7,8 @@ import { import { type ThorRequest } from '../ThorRequest'; import { type ThorResponse } from '../ThorResponse'; +import { type TxId } from '../../../../core/src/vcdm/BlockId'; + class RetrieveTransactionReceipt implements ThorRequest { diff --git a/packages/net/src/thor/transactions/SendTransaction.ts b/packages/net/src/thor/transactions/SendTransaction.ts index 9bd96462d..72c01bea7 100644 --- a/packages/net/src/thor/transactions/SendTransaction.ts +++ b/packages/net/src/thor/transactions/SendTransaction.ts @@ -1,8 +1,10 @@ -import { HexUInt, TxId } from '@vechain/sdk-core'; +import { HexUInt } from '@vechain/sdk-core'; import { type HttpClient, type HttpPath } from '../../http'; import { type ThorRequest } from '../ThorRequest'; import { type ThorResponse } from '../ThorResponse'; +import { TxId } from '../../../../core/src/vcdm/BlockId'; + class SendTransaction implements ThorRequest { static readonly PATH: HttpPath = { path: '/transactions' }; diff --git a/packages/net/src/thor/transactions/TxMeta.ts b/packages/net/src/thor/transactions/TxMeta.ts index 749acda41..589a4ec75 100644 --- a/packages/net/src/thor/transactions/TxMeta.ts +++ b/packages/net/src/thor/transactions/TxMeta.ts @@ -1,4 +1,6 @@ -import { BlockId, UInt } from '@vechain/sdk-core'; +import { BlockId } from '@vechain/sdk-core'; + +import { UInt } from '../../../../core/src/vcdm/UInt'; class TxMeta { readonly blockID: BlockId; diff --git a/yarn.lock b/yarn.lock index 2efcd8452..9787765a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5467,6 +5467,37 @@ uuid "2.0.1" xmlhttprequest "1.8.0" +"@vechain/sdk-core@1.0.0-rc.4": + version "1.0.0-rc.4" + resolved "https://registry.yarnpkg.com/@vechain/sdk-core/-/sdk-core-1.0.0-rc.4.tgz#926c820d81d27830384860df69378648fa3a952e" + integrity sha512-/qKeMny9mhiGZfQesaepP/EOH/F2tXcTq1OiDHBQwJs6wGVd1lj6RoyoSS+WsRIMG7AbzHeD+iLyqNcYKxBvTQ== + dependencies: + "@ethereumjs/rlp" "^5.0.2" + "@noble/ciphers" "^1.1.1" + "@noble/curves" "^1.6.0" + "@noble/hashes" "^1.5.0" + "@scure/base" "^1.1.9" + "@scure/bip32" "^1.4.0" + "@scure/bip39" "^1.4.0" + "@vechain/sdk-errors" "1.0.0-rc.4" + "@vechain/sdk-logging" "1.0.0-rc.4" + abitype "^1.0.6" + ethers "6.13.4" + fast-json-stable-stringify "^2.1.0" + viem "^2.21.45" + +"@vechain/sdk-errors@1.0.0-rc.4": + version "1.0.0-rc.4" + resolved "https://registry.yarnpkg.com/@vechain/sdk-errors/-/sdk-errors-1.0.0-rc.4.tgz#24cc9e9636e8ce7c4b45bde5b5ee883eba460561" + integrity sha512-XLczRbf6aMIxPLWEFqHsNae2vJ42blX8dK+TsPsIYIFCAAK8LHEHrHV5LCocJQS+BP+MgKH8sX+2O7FQdjHKiw== + +"@vechain/sdk-logging@1.0.0-rc.4": + version "1.0.0-rc.4" + resolved "https://registry.yarnpkg.com/@vechain/sdk-logging/-/sdk-logging-1.0.0-rc.4.tgz#803e46bdcf20dfe222329a771ad832ba84b5e3d6" + integrity sha512-C1TF367Fl/CTElASX+zvzcZpB5msczpOy1DFOTwkhVFbar08TgtfvsVdE1M/rg8B8Af0zd5M8FST7TCeDpw3uA== + dependencies: + "@vechain/sdk-errors" "1.0.0-rc.4" + "@vechain/vebetterdao-contracts@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@vechain/vebetterdao-contracts/-/vebetterdao-contracts-4.0.0.tgz#a4ddd8de1b232002810bcee40b9617a5379d40d0" @@ -14543,6 +14574,21 @@ vfile@^6.0.0: "@types/unist" "^3.0.0" vfile-message "^4.0.0" +viem@^2.21.45: + version "2.21.55" + resolved "https://registry.yarnpkg.com/viem/-/viem-2.21.55.tgz#a57ad31fcf2a0f6c011b1909f02c94421ec4f781" + integrity sha512-PgXew7C11cAuEtOSgRyQx2kJxEOPUwIwZA9dMglRByqJuFVA7wSGZZOOo/93iylAA8E15bEdqy9xulU3oKZ70Q== + dependencies: + "@noble/curves" "1.7.0" + "@noble/hashes" "1.6.1" + "@scure/bip32" "1.6.0" + "@scure/bip39" "1.5.0" + abitype "1.0.7" + isows "1.0.6" + ox "0.1.2" + webauthn-p256 "0.0.10" + ws "8.18.0" + viem@^2.21.54: version "2.21.54" resolved "https://registry.yarnpkg.com/viem/-/viem-2.21.54.tgz#76d6f86ab8809078f1ac140ac1a2beadbc86b9f6" From b8536e98abe093eb76ec258b4a8031da4848f3bb Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Mon, 16 Dec 2024 19:46:52 +0000 Subject: [PATCH 38/98] feat: 1484 additional VCDM classes direct import: to fix... --- .../transactions/RetrieveRawTransactionByIID.testnet.test.ts | 2 +- .../thor/transactions/RetrieveTransactionByIID.testnet.test.ts | 2 +- .../transactions/RetrieveTransactionReceipt.testnet.test.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/net/tests/thor/transactions/RetrieveRawTransactionByIID.testnet.test.ts b/packages/net/tests/thor/transactions/RetrieveRawTransactionByIID.testnet.test.ts index cd892efb8..7d60e24f2 100644 --- a/packages/net/tests/thor/transactions/RetrieveRawTransactionByIID.testnet.test.ts +++ b/packages/net/tests/thor/transactions/RetrieveRawTransactionByIID.testnet.test.ts @@ -1,5 +1,5 @@ import { describe, test } from '@jest/globals'; -import { TxId } from '@vechain/sdk-core'; +import { TxId } from '../../../../core'; import { FetchHttpClient, RetrieveRawTransactionByID, diff --git a/packages/net/tests/thor/transactions/RetrieveTransactionByIID.testnet.test.ts b/packages/net/tests/thor/transactions/RetrieveTransactionByIID.testnet.test.ts index 6eb7a95ca..32f48194e 100644 --- a/packages/net/tests/thor/transactions/RetrieveTransactionByIID.testnet.test.ts +++ b/packages/net/tests/thor/transactions/RetrieveTransactionByIID.testnet.test.ts @@ -1,5 +1,5 @@ import { describe, test } from '@jest/globals'; -import { TxId } from '@vechain/sdk-core'; +import { TxId } from '../../../../core'; import { FetchHttpClient, RetrieveTransactionByID, diff --git a/packages/net/tests/thor/transactions/RetrieveTransactionReceipt.testnet.test.ts b/packages/net/tests/thor/transactions/RetrieveTransactionReceipt.testnet.test.ts index b9ceef825..ae543125c 100644 --- a/packages/net/tests/thor/transactions/RetrieveTransactionReceipt.testnet.test.ts +++ b/packages/net/tests/thor/transactions/RetrieveTransactionReceipt.testnet.test.ts @@ -1,5 +1,5 @@ import { describe, test } from '@jest/globals'; -import { TxId } from '@vechain/sdk-core'; +import { TxId } from '../../../../core'; import { FetchHttpClient, RetrieveTransactionReceipt, From 85e7ce4082f50ef012e3be1c06726f03bd818e39 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 17 Dec 2024 14:29:11 +0000 Subject: [PATCH 39/98] feat: 1484 additional VCDM classes direct import: to fix... --- docs/diagrams/v2/network/thor/logs/logs.md | 114 ++++++++++++++++++ .../src/thor/accounts/GetAccountResponse.ts | 12 +- packages/net/src/thor/logs/EventCriteria.ts | 41 +++++++ .../src/thor/logs/EventLogFilterRequest.ts | 56 +++++++++ .../net/src/thor/logs/EventLogsResponse.ts | 42 +++++++ packages/net/src/thor/logs/FilterOptions.ts | 25 ++++ packages/net/src/thor/logs/FilterRange.ts | 34 ++++++ packages/net/src/thor/logs/LogMeta.ts | 42 +++++++ .../src/thor/logs/QuerySmartContractEvents.ts | 0 packages/net/src/thor/logs/index.ts | 6 + 10 files changed, 366 insertions(+), 6 deletions(-) create mode 100644 docs/diagrams/v2/network/thor/logs/logs.md create mode 100644 packages/net/src/thor/logs/EventCriteria.ts create mode 100644 packages/net/src/thor/logs/EventLogFilterRequest.ts create mode 100644 packages/net/src/thor/logs/EventLogsResponse.ts create mode 100644 packages/net/src/thor/logs/FilterOptions.ts create mode 100644 packages/net/src/thor/logs/FilterRange.ts create mode 100644 packages/net/src/thor/logs/LogMeta.ts create mode 100644 packages/net/src/thor/logs/QuerySmartContractEvents.ts create mode 100644 packages/net/src/thor/logs/index.ts diff --git a/docs/diagrams/v2/network/thor/logs/logs.md b/docs/diagrams/v2/network/thor/logs/logs.md new file mode 100644 index 000000000..0b51b41bf --- /dev/null +++ b/docs/diagrams/v2/network/thor/logs/logs.md @@ -0,0 +1,114 @@ +```mermaid +classDiagram + class Array~EventLogsResponse~ { + } + class EventCriteria { + address: Address | null; + topic0: ThorId | null; + topic1: ThorId | null; + topic2: ThorId | null; + topic3: ThorId | null; + topic4: ThorId | null; + } + class EventCriteriaJSON { + <> + address: string | null; + topic0: string | null; + topic1: string | null; + topic2: string | null; + topic3: string | null; + topic4: string | null; + } + class EventLogFilterRequest { + range: FilterRange | null; + options: FilterOptions | null; + criteriaSet: EventCriteria[] | null; + order: EventLogFilterRequestOrder | null; + } + class EventLogFilterRequestJSON { + <> + range: FilterRangeJSON | null; + options: FilterOptionsJSON | null; + criteriaSet: EventCriteriaJSON[] | null; + order: string | null; + } + class EventLogFilterRequestOrder { + <> + asc$ + desc$ + } + class EventLogResponse { + readonly address: Address; + readonly topics: ThorId[]; + readonly data: HexUInt; + readonly meta: LogMeta; + } + class EventLogResponseJSON { + address: string; + topics: string[]; + data: string; + meta: LogMetaJSON; + } + class EventLogsResponse { + } + class FilterOptions { + limit: UInt | null; + offset: UInt | null; + } + class FilterOptionsJSON { + <> + limit: number | null; + offset: number | null; + } + class FilterRange { + from: UInt|null + to: UInt|null + unit: FilterRangeUnit|null + } + class FilterRangeJSON { + <> + from: number|null + to: number|null + unit: string|null + } + class FilterRangeUnit { + <> + block$ + time$ + } + class LogMeta { + blockID: BlockId; + blockNumber: UInt; + blockTimestamp: UInt; + txID: TxId; + txOrigin: Address; + clauseIndex: UInt; + } + class LogMetaJSON { + <> + blockID: string; + blockNumber: number; + blockTimestamp: number; + txID: string; + txOrigin: string; + clauseIndex: number; + } + Array~EventLogResponse~ <|-- EventLogsResponse + EventCriteriaJSON <-- EventCriteria + EventLogFilterRequestJSON <-- EventLogFilterRequest + EventLogResponse <-- Array~EventLogResponse~ + EventLogResponseJSON <-- EventLogResponse + FilterOptionsJSON <-- FilterOptions + FilterRangeJSON <-- FilterRange + LogMetaJSON <-- LogMeta + EventLogFilterRequest --* FilterRange + EventLogFilterRequest --* FilterOptions + EventLogFilterRequest --* EventCriteria + EventLogFilterRequest --* EventLogFilterRequestOrder + EventLogFilterRequestJSON --* FilterRangeJSON + EventLogFilterRequestJSON --* FilterOptionsJSON + EventLogFilterRequestJSON --* EventCriteriaJSON + EventLogResponse --* LogMeta + EventLogResponseJSON --* LogMetaJSON + FilterRange --* FilterRangeUnit +``` diff --git a/packages/net/src/thor/accounts/GetAccountResponse.ts b/packages/net/src/thor/accounts/GetAccountResponse.ts index fbf9a140a..c3cf03b7c 100644 --- a/packages/net/src/thor/accounts/GetAccountResponse.ts +++ b/packages/net/src/thor/accounts/GetAccountResponse.ts @@ -1,11 +1,5 @@ import { Quantity, VET, VTHO } from '@vechain/sdk-core'; -interface GetAccountResponseJSON { - balance: string; - energy: string; - hasCode: boolean; -} - class GetAccountResponse { balance: VET; energy: VTHO; @@ -26,4 +20,10 @@ class GetAccountResponse { } } +interface GetAccountResponseJSON { + balance: string; + energy: string; + hasCode: boolean; +} + export { GetAccountResponse, type GetAccountResponseJSON }; diff --git a/packages/net/src/thor/logs/EventCriteria.ts b/packages/net/src/thor/logs/EventCriteria.ts new file mode 100644 index 000000000..c4bc8f00c --- /dev/null +++ b/packages/net/src/thor/logs/EventCriteria.ts @@ -0,0 +1,41 @@ +import { Address, ThorId } from '@vechain/sdk-core'; + +class EventCriteria { + readonly address: Address | null; + readonly topic0: ThorId | null; + readonly topic1: ThorId | null; + readonly topic2: ThorId | null; + readonly topic3: ThorId | null; + readonly topic4: ThorId | null; + + constructor(json: EventCriteriaJSON) { + this.address = json.address === null ? null : Address.of(json.address); + this.topic0 = json.topic0 === null ? null : ThorId.of(json.topic0); + this.topic1 = json.topic1 === null ? null : ThorId.of(json.topic1); + this.topic2 = json.topic2 === null ? null : ThorId.of(json.topic2); + this.topic3 = json.topic3 === null ? null : ThorId.of(json.topic3); + this.topic4 = json.topic4 === null ? null : ThorId.of(json.topic4); + } + + toJSON(): EventCriteriaJSON { + return { + address: this.address === null ? null : this.address.toString(), + topic0: this.topic0 === null ? null : this.topic0.toString(), + topic1: this.topic1 === null ? null : this.topic1.toString(), + topic2: this.topic2 === null ? null : this.topic2.toString(), + topic3: this.topic3 === null ? null : this.topic3.toString(), + topic4: this.topic4 === null ? null : this.topic4.toString() + } satisfies EventCriteriaJSON; + } +} + +interface EventCriteriaJSON { + address: string | null; + topic0: string | null; + topic1: string | null; + topic2: string | null; + topic3: string | null; + topic4: string | null; +} + +export { EventCriteria, type EventCriteriaJSON }; diff --git a/packages/net/src/thor/logs/EventLogFilterRequest.ts b/packages/net/src/thor/logs/EventLogFilterRequest.ts new file mode 100644 index 000000000..1576a2a87 --- /dev/null +++ b/packages/net/src/thor/logs/EventLogFilterRequest.ts @@ -0,0 +1,56 @@ +import { FilterRange, type FilterRangeJSON } from './FilterRange'; +import { EventCriteria, type EventCriteriaJSON } from './EventCriteria'; +import { FilterOptions, type FilterOptionsJSON } from './FilterOptions'; + +class EventLogFilterRequest { + readonly range: FilterRange | null; + readonly options: FilterOptions | null; + readonly criteriaSet: EventCriteria[] | null; + readonly order: EventLogFilterRequestOrder | null; + + constructor(json: EventLogFilterRequestJSON) { + this.range = json.range === null ? null : new FilterRange(json.range); + this.options = + json.options === null ? null : new FilterOptions(json.options); + this.criteriaSet = + json.criteriaSet === null + ? null + : json.criteriaSet.map( + (criteriaJSON) => new EventCriteria(criteriaJSON) + ); + this.order = + json.order === null + ? null + : (json.order as EventLogFilterRequestOrder); + } + + toJSON(): EventLogFilterRequestJSON { + return { + range: this.range === null ? null : this.range.toJSON(), + options: this.options === null ? null : this.options.toJSON(), + criteriaSet: + this.criteriaSet === null + ? null + : this.criteriaSet.map((criteria) => criteria.toJSON()), + order: this.order === null ? null : this.order.toString() + } satisfies EventLogFilterRequestJSON; + } +} + +interface EventLogFilterRequestJSON { + range: FilterRangeJSON | null; + options: FilterOptionsJSON | null; + criteriaSet: EventCriteriaJSON[] | null; + order: string | null; +} + +enum EventLogFilterRequestOrder { + asc = 'asc', + desc = 'desc' +} + +export { + EventLogFilterRequest, + type EventLogFilterRequestJSON, + EventLogFilterRequestOrder +}; diff --git a/packages/net/src/thor/logs/EventLogsResponse.ts b/packages/net/src/thor/logs/EventLogsResponse.ts new file mode 100644 index 000000000..92eea968a --- /dev/null +++ b/packages/net/src/thor/logs/EventLogsResponse.ts @@ -0,0 +1,42 @@ +import { LogMeta, type LogMetaJSON } from './LogMeta'; +import { Address, HexUInt, ThorId } from '@vechain/sdk-core'; + +class EventLogResponse { + readonly address: Address; + readonly topics: ThorId[]; + readonly data: HexUInt; + readonly meta: LogMeta; + + constructor(json: EventLogResponseJSON) { + this.address = Address.of(json.address); + this.topics = json.topics.map( + (topic: string): ThorId => ThorId.of(topic) + ); + this.data = HexUInt.of(json.data); + this.meta = new LogMeta(json.meta); + } + + toJSON(): EventLogResponseJSON { + return { + address: this.address.toString(), + topics: this.topics.map((topic: ThorId): string => + topic.toString() + ), + data: this.data.toString(), + meta: this.meta.toJSON() + } satisfies EventLogResponseJSON; + } +} + +interface EventLogResponseJSON { + address: string; + topics: string[]; + data: string; + meta: LogMetaJSON; +} + +interface EventLogsResponseJSON extends Array {} + +class EventLogsResponse extends Array {} + +export { EventLogResponse, type EventLogsResponseJSON, EventLogsResponse }; diff --git a/packages/net/src/thor/logs/FilterOptions.ts b/packages/net/src/thor/logs/FilterOptions.ts new file mode 100644 index 000000000..9afdc3fbf --- /dev/null +++ b/packages/net/src/thor/logs/FilterOptions.ts @@ -0,0 +1,25 @@ +import { UInt } from '../../../../core/src'; + +class FilterOptions { + readonly limit: UInt | null; + readonly offset: UInt | null; + + constructor(json: FilterOptionsJSON) { + this.limit = json.limit === null ? null : UInt.of(json.limit); + this.offset = json.offset === null ? null : UInt.of(json.offset); + } + + toJSON(): FilterOptionsJSON { + return { + limit: this.limit === null ? null : this.limit.valueOf(), + offset: this.offset === null ? null : this.offset.valueOf() + } satisfies FilterOptionsJSON; + } +} + +interface FilterOptionsJSON { + limit: number | null; + offset: number | null; +} + +export { FilterOptions, type FilterOptionsJSON }; diff --git a/packages/net/src/thor/logs/FilterRange.ts b/packages/net/src/thor/logs/FilterRange.ts new file mode 100644 index 000000000..7f4d8a45a --- /dev/null +++ b/packages/net/src/thor/logs/FilterRange.ts @@ -0,0 +1,34 @@ +import { UInt } from '../../../../core/src'; + +class FilterRange { + readonly unit: FilterRangeUnits | null; + readonly from: UInt | null; + readonly to: UInt | null; + + constructor(json: FilterRangeJSON) { + this.unit = json.unit === null ? null : (json.unit as FilterRangeUnits); + this.from = json.from === null ? null : UInt.of(json.from); + this.to = json.to === null ? null : UInt.of(json.to); + } + + toJSON(): FilterRangeJSON { + return { + unit: this.unit === null ? null : this.unit.toString(), + from: this.from === null ? null : this.from.valueOf(), + to: this.to === null ? null : this.to.valueOf() + } satisfies FilterRangeJSON; + } +} + +interface FilterRangeJSON { + unit: string | null; + from: number | null; + to: number | null; +} + +enum FilterRangeUnits { + block = 'block', + time = 'time' +} + +export { FilterRange, type FilterRangeJSON, FilterRangeUnits }; diff --git a/packages/net/src/thor/logs/LogMeta.ts b/packages/net/src/thor/logs/LogMeta.ts new file mode 100644 index 000000000..7a2b3b61b --- /dev/null +++ b/packages/net/src/thor/logs/LogMeta.ts @@ -0,0 +1,42 @@ +import { Address, BlockId } from '@vechain/sdk-core'; +import { TxId, UInt } from '../../../../core/src/vcdm'; + +class LogMeta { + readonly blockID: BlockId; + readonly blockNumber: UInt; + readonly blockTimestamp: UInt; + readonly txID: TxId; + readonly txOrigin: Address; + readonly clauseIndex: UInt; + + constructor(json: LogMetaJSON) { + this.blockID = BlockId.of(json.blockID); + this.blockNumber = UInt.of(json.blockNumber); + this.blockTimestamp = UInt.of(json.blockTimestamp); + this.txID = TxId.of(json.txID); + this.txOrigin = Address.of(json.txOrigin); + this.clauseIndex = UInt.of(json.clauseIndex); + } + + toJSON(): LogMetaJSON { + return { + blockID: this.blockID.toString(), + blockNumber: this.blockNumber.valueOf(), + blockTimestamp: this.blockTimestamp.valueOf(), + txID: this.txID.toString(), + txOrigin: this.txOrigin.toString(), + clauseIndex: this.clauseIndex.valueOf() + } satisfies LogMetaJSON; + } +} + +interface LogMetaJSON { + blockID: string; + blockNumber: number; + blockTimestamp: number; + txID: string; + txOrigin: string; + clauseIndex: number; +} + +export { LogMeta, type LogMetaJSON }; diff --git a/packages/net/src/thor/logs/QuerySmartContractEvents.ts b/packages/net/src/thor/logs/QuerySmartContractEvents.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/net/src/thor/logs/index.ts b/packages/net/src/thor/logs/index.ts new file mode 100644 index 000000000..43d342a34 --- /dev/null +++ b/packages/net/src/thor/logs/index.ts @@ -0,0 +1,6 @@ +export * from './EventCriteria'; +export * from './EventLogFilterRequest'; +export * from './EventLogResponse'; +export * from './FilterOptions'; +export * from './FilterRange'; +export * from './LogMeta'; From 1abd01b36a23b8bb1e7efd30cbb126b6dd5b3a92 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 17 Dec 2024 20:03:06 +0000 Subject: [PATCH 40/98] feat: 1484 logs in dev... --- .../net/src/thor/logs/EventLogsResponse.ts | 11 +++-- .../src/thor/logs/QuerySmartContractEvents.ts | 49 +++++++++++++++++++ packages/net/src/thor/logs/index.ts | 3 +- .../QuerySmartContractEvents.testnet.test.ts | 38 ++++++++++++++ 4 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 packages/net/tests/thor/logs/QuerySmartContractEvents.testnet.test.ts diff --git a/packages/net/src/thor/logs/EventLogsResponse.ts b/packages/net/src/thor/logs/EventLogsResponse.ts index 92eea968a..73aad25ef 100644 --- a/packages/net/src/thor/logs/EventLogsResponse.ts +++ b/packages/net/src/thor/logs/EventLogsResponse.ts @@ -35,8 +35,13 @@ interface EventLogResponseJSON { meta: LogMetaJSON; } -interface EventLogsResponseJSON extends Array {} +interface EventLogsResponse extends Array {} -class EventLogsResponse extends Array {} +interface EventLogsResponseJSON extends Array {} -export { EventLogResponse, type EventLogsResponseJSON, EventLogsResponse }; +export { + EventLogResponse, + type EventLogResponseJSON, + type EventLogsResponseJSON, + type EventLogsResponse +}; diff --git a/packages/net/src/thor/logs/QuerySmartContractEvents.ts b/packages/net/src/thor/logs/QuerySmartContractEvents.ts index e69de29bb..567a857dd 100644 --- a/packages/net/src/thor/logs/QuerySmartContractEvents.ts +++ b/packages/net/src/thor/logs/QuerySmartContractEvents.ts @@ -0,0 +1,49 @@ +import { type ThorRequest } from '../ThorRequest'; +import type { HttpClient, HttpPath } from '../../http'; +import { + EventLogFilterRequest, + type EventLogFilterRequestJSON +} from './EventLogFilterRequest'; +import type { ThorResponse } from '../ThorResponse'; +import { + EventLogResponse, + type EventLogResponseJSON, + type EventLogsResponse, + type EventLogsResponseJSON +} from './EventLogsResponse'; + +class QuerySmartContractEvents + implements ThorRequest +{ + static readonly PATH: HttpPath = { path: '/logs/event' }; + + readonly request: EventLogFilterRequest; + + constructor(request: EventLogFilterRequest) { + this.request = request; + } + + async askTo( + httpClient: HttpClient + ): Promise> { + const response = await httpClient.post( + QuerySmartContractEvents.PATH, + { query: '' }, + this.request.toJSON() + ); + const responseBody = (await response.json()) as EventLogsResponseJSON; + return { + request: this, + response: responseBody.map( + (json: EventLogResponseJSON): EventLogResponse => + new EventLogResponse(json) + ) as EventLogsResponse + }; + } + + static of(request: EventLogFilterRequestJSON): QuerySmartContractEvents { + return new QuerySmartContractEvents(new EventLogFilterRequest(request)); + } +} + +export { QuerySmartContractEvents }; diff --git a/packages/net/src/thor/logs/index.ts b/packages/net/src/thor/logs/index.ts index 43d342a34..805bdca35 100644 --- a/packages/net/src/thor/logs/index.ts +++ b/packages/net/src/thor/logs/index.ts @@ -1,6 +1,7 @@ export * from './EventCriteria'; export * from './EventLogFilterRequest'; -export * from './EventLogResponse'; +export * from './EventLogsResponse'; export * from './FilterOptions'; export * from './FilterRange'; export * from './LogMeta'; +export * from './QuerySmartContractEvents'; diff --git a/packages/net/tests/thor/logs/QuerySmartContractEvents.testnet.test.ts b/packages/net/tests/thor/logs/QuerySmartContractEvents.testnet.test.ts new file mode 100644 index 000000000..aed7223d1 --- /dev/null +++ b/packages/net/tests/thor/logs/QuerySmartContractEvents.testnet.test.ts @@ -0,0 +1,38 @@ +import { describe, test } from '@jest/globals'; + +import { + type EventLogFilterRequestJSON, + QuerySmartContractEvents +} from '../../../src/thor/logs'; +import { FetchHttpClient, ThorNetworks } from '../../../src'; + +describe('QuerySmartContractEvents testnet tests', () => { + test('ok <- askTo', async () => { + const request = { + range: { + unit: 'block', + from: 17240365, + to: 17289864 + }, + options: { + offset: 0, + limit: 100 + }, + criteriaSet: [ + { + address: '0x0000000000000000000000000000456E65726779', + topic0: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', + topic1: '0x0000000000000000000000006d95e6dca01d109882fe1726a2fb9865fa41e7aa', + topic2: null, + topic3: null, + topic4: null + } + ], + order: 'asc' + } satisfies EventLogFilterRequestJSON; + const r = await QuerySmartContractEvents.of(request).askTo( + FetchHttpClient.at(ThorNetworks.TESTNET) + ); + console.log(JSON.stringify(r, null, 2)); + }); +}); From c94537f7c92c11cddadd5cc0705311bf16c5d502 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 18 Dec 2024 08:58:12 +0000 Subject: [PATCH 41/98] feat: 1484 logs in dev... --- docs/diagrams/v2/network/thor/logs/logs.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/diagrams/v2/network/thor/logs/logs.md b/docs/diagrams/v2/network/thor/logs/logs.md index 0b51b41bf..0a9bfcfac 100644 --- a/docs/diagrams/v2/network/thor/logs/logs.md +++ b/docs/diagrams/v2/network/thor/logs/logs.md @@ -93,11 +93,19 @@ classDiagram txOrigin: string; clauseIndex: number; } + class QuerySmartContractEvents { + PATH$: HttpPath + request: EventLogFilterRequest + constructor(request: EventLogFilterRequest) + askTo(httpClient: HttpClient): Promise~ThorResponse~EventLogsResponse~~ + of(request: EventLogFilterRequestJSON)$ + } Array~EventLogResponse~ <|-- EventLogsResponse EventCriteriaJSON <-- EventCriteria EventLogFilterRequestJSON <-- EventLogFilterRequest EventLogResponse <-- Array~EventLogResponse~ EventLogResponseJSON <-- EventLogResponse + EventLogsResponse <-- QuerySmartContractEvents FilterOptionsJSON <-- FilterOptions FilterRangeJSON <-- FilterRange LogMetaJSON <-- LogMeta @@ -111,4 +119,5 @@ classDiagram EventLogResponse --* LogMeta EventLogResponseJSON --* LogMetaJSON FilterRange --* FilterRangeUnit + QuerySmartContractEvents --* EventLogFilterRequest ``` From f1c65897b864b3eaa4a117e14deaebe74abecfd2 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 18 Dec 2024 11:34:18 +0000 Subject: [PATCH 42/98] feat: 1484 logs in dev... --- docs/diagrams/v2/network/thor/logs/logs.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/diagrams/v2/network/thor/logs/logs.md b/docs/diagrams/v2/network/thor/logs/logs.md index 0a9bfcfac..6a957c497 100644 --- a/docs/diagrams/v2/network/thor/logs/logs.md +++ b/docs/diagrams/v2/network/thor/logs/logs.md @@ -120,4 +120,5 @@ classDiagram EventLogResponseJSON --* LogMetaJSON FilterRange --* FilterRangeUnit QuerySmartContractEvents --* EventLogFilterRequest + ``` From 23e26d1ff0ead5b958ebf37279fcbf1d4516726e Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 18 Dec 2024 18:53:35 +0000 Subject: [PATCH 43/98] feat: 1484 log in dev... --- .../diagrams/v2/{network => net}/http/http.md | 0 .../thor/accounts/account-module.md | 0 .../thor/blocks/blocks-module.md | 0 .../thor/debug/debug-module.md | 0 .../v2/{network => net}/thor/node/node.md | 0 .../subscriptions/subscriptions-module.md | 0 .../diagrams/v2/{network => net}/thor/thor.md | 0 .../thor/transactions/transactions-module.md | 0 .../thor/transactions/transactions.md | 0 .../v2/network/thor/logs/logs-module.md | 89 ------------------- packages/net/src/thor/logs/EventCriteria.ts | 54 ++++++----- .../src/thor/logs/EventLogFilterRequest.ts | 54 +++++------ packages/net/src/thor/logs/FilterOptions.ts | 17 ++-- packages/net/src/thor/logs/FilterRange.ts | 28 +++--- packages/net/src/thor/logs/LogSort.ts | 6 ++ .../net/src/thor/logs/TransferCriteria.ts | 34 +++++++ .../src/thor/logs/TransferLogFilterRequest.ts | 48 ++++++++++ .../net/src/thor/logs/TransferLogsResponse.ts | 43 +++++++++ packages/net/src/thor/logs/index.ts | 3 + .../QuerySmartContractEvents.testnet.test.ts | 5 +- 20 files changed, 212 insertions(+), 169 deletions(-) rename docs/diagrams/v2/{network => net}/http/http.md (100%) rename docs/diagrams/v2/{network => net}/thor/accounts/account-module.md (100%) rename docs/diagrams/v2/{network => net}/thor/blocks/blocks-module.md (100%) rename docs/diagrams/v2/{network => net}/thor/debug/debug-module.md (100%) rename docs/diagrams/v2/{network => net}/thor/node/node.md (100%) rename docs/diagrams/v2/{network => net}/thor/subscriptions/subscriptions-module.md (100%) rename docs/diagrams/v2/{network => net}/thor/thor.md (100%) rename docs/diagrams/v2/{network => net}/thor/transactions/transactions-module.md (100%) rename docs/diagrams/v2/{network => net}/thor/transactions/transactions.md (100%) delete mode 100644 docs/diagrams/v2/network/thor/logs/logs-module.md create mode 100644 packages/net/src/thor/logs/LogSort.ts create mode 100644 packages/net/src/thor/logs/TransferCriteria.ts create mode 100644 packages/net/src/thor/logs/TransferLogFilterRequest.ts create mode 100644 packages/net/src/thor/logs/TransferLogsResponse.ts diff --git a/docs/diagrams/v2/network/http/http.md b/docs/diagrams/v2/net/http/http.md similarity index 100% rename from docs/diagrams/v2/network/http/http.md rename to docs/diagrams/v2/net/http/http.md diff --git a/docs/diagrams/v2/network/thor/accounts/account-module.md b/docs/diagrams/v2/net/thor/accounts/account-module.md similarity index 100% rename from docs/diagrams/v2/network/thor/accounts/account-module.md rename to docs/diagrams/v2/net/thor/accounts/account-module.md diff --git a/docs/diagrams/v2/network/thor/blocks/blocks-module.md b/docs/diagrams/v2/net/thor/blocks/blocks-module.md similarity index 100% rename from docs/diagrams/v2/network/thor/blocks/blocks-module.md rename to docs/diagrams/v2/net/thor/blocks/blocks-module.md diff --git a/docs/diagrams/v2/network/thor/debug/debug-module.md b/docs/diagrams/v2/net/thor/debug/debug-module.md similarity index 100% rename from docs/diagrams/v2/network/thor/debug/debug-module.md rename to docs/diagrams/v2/net/thor/debug/debug-module.md diff --git a/docs/diagrams/v2/network/thor/node/node.md b/docs/diagrams/v2/net/thor/node/node.md similarity index 100% rename from docs/diagrams/v2/network/thor/node/node.md rename to docs/diagrams/v2/net/thor/node/node.md diff --git a/docs/diagrams/v2/network/thor/subscriptions/subscriptions-module.md b/docs/diagrams/v2/net/thor/subscriptions/subscriptions-module.md similarity index 100% rename from docs/diagrams/v2/network/thor/subscriptions/subscriptions-module.md rename to docs/diagrams/v2/net/thor/subscriptions/subscriptions-module.md diff --git a/docs/diagrams/v2/network/thor/thor.md b/docs/diagrams/v2/net/thor/thor.md similarity index 100% rename from docs/diagrams/v2/network/thor/thor.md rename to docs/diagrams/v2/net/thor/thor.md diff --git a/docs/diagrams/v2/network/thor/transactions/transactions-module.md b/docs/diagrams/v2/net/thor/transactions/transactions-module.md similarity index 100% rename from docs/diagrams/v2/network/thor/transactions/transactions-module.md rename to docs/diagrams/v2/net/thor/transactions/transactions-module.md diff --git a/docs/diagrams/v2/network/thor/transactions/transactions.md b/docs/diagrams/v2/net/thor/transactions/transactions.md similarity index 100% rename from docs/diagrams/v2/network/thor/transactions/transactions.md rename to docs/diagrams/v2/net/thor/transactions/transactions.md diff --git a/docs/diagrams/v2/network/thor/logs/logs-module.md b/docs/diagrams/v2/network/thor/logs/logs-module.md deleted file mode 100644 index a2d34f73e..000000000 --- a/docs/diagrams/v2/network/thor/logs/logs-module.md +++ /dev/null @@ -1,89 +0,0 @@ -```mermaid -classDiagram - class HttpClient { - <> - } - class ThorRequest~Request~ { - <> - ThorResponse~Request~ askTo(HttpClient httpClient) - } - class ThorResponse~Response~ { - <> - ThorRequest~Request~ request - Response response - } - namespace Request { - class QuerySmartContractEvents { - EventLogFilterRequest body - } - class QueryVETTransferEvents { - TransferLogFilterRequest body - } - } - namespace Response { - class EventLogsResponse { - Address address - HexUInt topics - HexUInt data - LogMeta meta - } - class TransferLogsResponse { - Address sender - Address recipient - VET amount - LogMeta meta - } - } - class EventLogFilterRequest { - FilterRange range - FilterOptions options - EventCriteria[] criteriaSet - Sort order - } - class FilterOptions { - UInt offset - UInt limit - } - class FilterRange { - Unit unit - UInt from - UInt to - } - class LogMeta { - BlockID blockID - UInt number - bigint timestamp - TXID txID - TXID txOrigin - UInt clauseIndex - } - class TransferCriteria { - Address txOrigin - Address sender - Address recipient - Sort order - } - class TransferLogFilterRequest { - FilterRange range - FilterOptions options - TransferCriteria[] criteriaSet - } - - HttpClient o-- ThorRequest - - ThorRequest <|.. QuerySmartContractEvents - ThorRequest <|.. QueryVETTransferEvents - ThorResponse <|.. EventLogsResponse - ThorResponse <|.. TransferLogsResponse - - ThorRequest --* ThorResponse - EventLogFilterRequest --* FilterRange - EventLogFilterRequest --* FilterOptions - EventLogsResponse --* LogMeta - QuerySmartContractEvents --* EventLogFilterRequest - QueryVETTransferEvents --* TransferLogFilterRequest - TransferLogFilterRequest --* FilterOptions - TransferLogFilterRequest --* FilterRange - TransferLogFilterRequest --* TransferCriteria - TransferLogsResponse --* LogMeta -``` diff --git a/packages/net/src/thor/logs/EventCriteria.ts b/packages/net/src/thor/logs/EventCriteria.ts index c4bc8f00c..9831188de 100644 --- a/packages/net/src/thor/logs/EventCriteria.ts +++ b/packages/net/src/thor/logs/EventCriteria.ts @@ -1,41 +1,47 @@ import { Address, ThorId } from '@vechain/sdk-core'; class EventCriteria { - readonly address: Address | null; - readonly topic0: ThorId | null; - readonly topic1: ThorId | null; - readonly topic2: ThorId | null; - readonly topic3: ThorId | null; - readonly topic4: ThorId | null; + readonly address?: Address; + readonly topic0?: ThorId; + readonly topic1?: ThorId; + readonly topic2?: ThorId; + readonly topic3?: ThorId; + readonly topic4?: ThorId; constructor(json: EventCriteriaJSON) { - this.address = json.address === null ? null : Address.of(json.address); - this.topic0 = json.topic0 === null ? null : ThorId.of(json.topic0); - this.topic1 = json.topic1 === null ? null : ThorId.of(json.topic1); - this.topic2 = json.topic2 === null ? null : ThorId.of(json.topic2); - this.topic3 = json.topic3 === null ? null : ThorId.of(json.topic3); - this.topic4 = json.topic4 === null ? null : ThorId.of(json.topic4); + this.address = + json.address === undefined ? undefined : Address.of(json.address); + this.topic0 = + json.topic0 === undefined ? undefined : ThorId.of(json.topic0); + this.topic1 = + json.topic1 === undefined ? undefined : ThorId.of(json.topic1); + this.topic2 = + json.topic2 === undefined ? undefined : ThorId.of(json.topic2); + this.topic3 = + json.topic3 === undefined ? undefined : ThorId.of(json.topic3); + this.topic4 = + json.topic4 === undefined ? undefined : ThorId.of(json.topic4); } toJSON(): EventCriteriaJSON { return { - address: this.address === null ? null : this.address.toString(), - topic0: this.topic0 === null ? null : this.topic0.toString(), - topic1: this.topic1 === null ? null : this.topic1.toString(), - topic2: this.topic2 === null ? null : this.topic2.toString(), - topic3: this.topic3 === null ? null : this.topic3.toString(), - topic4: this.topic4 === null ? null : this.topic4.toString() + address: this.address?.toString(), + topic0: this.topic0?.toString(), + topic1: this.topic1?.toString(), + topic2: this.topic2?.toString(), + topic3: this.topic3?.toString(), + topic4: this.topic4?.toString() } satisfies EventCriteriaJSON; } } interface EventCriteriaJSON { - address: string | null; - topic0: string | null; - topic1: string | null; - topic2: string | null; - topic3: string | null; - topic4: string | null; + address?: string; + topic0?: string; + topic1?: string; + topic2?: string; + topic3?: string; + topic4?: string; } export { EventCriteria, type EventCriteriaJSON }; diff --git a/packages/net/src/thor/logs/EventLogFilterRequest.ts b/packages/net/src/thor/logs/EventLogFilterRequest.ts index 1576a2a87..197ee1ac8 100644 --- a/packages/net/src/thor/logs/EventLogFilterRequest.ts +++ b/packages/net/src/thor/logs/EventLogFilterRequest.ts @@ -1,56 +1,46 @@ import { FilterRange, type FilterRangeJSON } from './FilterRange'; import { EventCriteria, type EventCriteriaJSON } from './EventCriteria'; import { FilterOptions, type FilterOptionsJSON } from './FilterOptions'; +import { type LogSort } from './LogSort'; class EventLogFilterRequest { - readonly range: FilterRange | null; - readonly options: FilterOptions | null; - readonly criteriaSet: EventCriteria[] | null; - readonly order: EventLogFilterRequestOrder | null; + readonly range?: FilterRange; + readonly options?: FilterOptions; + readonly criteriaSet?: EventCriteria[]; + readonly order?: LogSort; constructor(json: EventLogFilterRequestJSON) { - this.range = json.range === null ? null : new FilterRange(json.range); + this.range = + json.range === undefined ? undefined : new FilterRange(json.range); this.options = - json.options === null ? null : new FilterOptions(json.options); + json.options === undefined + ? undefined + : new FilterOptions(json.options); this.criteriaSet = - json.criteriaSet === null - ? null + json.criteriaSet === undefined + ? undefined : json.criteriaSet.map( (criteriaJSON) => new EventCriteria(criteriaJSON) ); this.order = - json.order === null - ? null - : (json.order as EventLogFilterRequestOrder); + json.order === undefined ? undefined : (json.order as LogSort); } toJSON(): EventLogFilterRequestJSON { return { - range: this.range === null ? null : this.range.toJSON(), - options: this.options === null ? null : this.options.toJSON(), - criteriaSet: - this.criteriaSet === null - ? null - : this.criteriaSet.map((criteria) => criteria.toJSON()), - order: this.order === null ? null : this.order.toString() + range: this.range?.toJSON(), + options: this.options?.toJSON(), + criteriaSet: this.criteriaSet?.map((criteria) => criteria.toJSON()), + order: this.order?.toString() } satisfies EventLogFilterRequestJSON; } } interface EventLogFilterRequestJSON { - range: FilterRangeJSON | null; - options: FilterOptionsJSON | null; - criteriaSet: EventCriteriaJSON[] | null; - order: string | null; + range?: FilterRangeJSON; + options?: FilterOptionsJSON; + criteriaSet?: EventCriteriaJSON[]; + order?: string; } -enum EventLogFilterRequestOrder { - asc = 'asc', - desc = 'desc' -} - -export { - EventLogFilterRequest, - type EventLogFilterRequestJSON, - EventLogFilterRequestOrder -}; +export { EventLogFilterRequest, type EventLogFilterRequestJSON }; diff --git a/packages/net/src/thor/logs/FilterOptions.ts b/packages/net/src/thor/logs/FilterOptions.ts index 9afdc3fbf..54c212af6 100644 --- a/packages/net/src/thor/logs/FilterOptions.ts +++ b/packages/net/src/thor/logs/FilterOptions.ts @@ -1,25 +1,26 @@ import { UInt } from '../../../../core/src'; class FilterOptions { - readonly limit: UInt | null; - readonly offset: UInt | null; + readonly limit?: UInt; + readonly offset?: UInt; constructor(json: FilterOptionsJSON) { - this.limit = json.limit === null ? null : UInt.of(json.limit); - this.offset = json.offset === null ? null : UInt.of(json.offset); + this.limit = json.limit === undefined ? undefined : UInt.of(json.limit); + this.offset = + json.offset === undefined ? undefined : UInt.of(json.offset); } toJSON(): FilterOptionsJSON { return { - limit: this.limit === null ? null : this.limit.valueOf(), - offset: this.offset === null ? null : this.offset.valueOf() + limit: this.limit?.valueOf(), + offset: this.offset?.valueOf() } satisfies FilterOptionsJSON; } } interface FilterOptionsJSON { - limit: number | null; - offset: number | null; + limit?: number; + offset?: number; } export { FilterOptions, type FilterOptionsJSON }; diff --git a/packages/net/src/thor/logs/FilterRange.ts b/packages/net/src/thor/logs/FilterRange.ts index 7f4d8a45a..658df799e 100644 --- a/packages/net/src/thor/logs/FilterRange.ts +++ b/packages/net/src/thor/logs/FilterRange.ts @@ -1,29 +1,33 @@ import { UInt } from '../../../../core/src'; class FilterRange { - readonly unit: FilterRangeUnits | null; - readonly from: UInt | null; - readonly to: UInt | null; + readonly unit?: FilterRangeUnits; + readonly from?: UInt; + readonly to?: UInt; constructor(json: FilterRangeJSON) { - this.unit = json.unit === null ? null : (json.unit as FilterRangeUnits); - this.from = json.from === null ? null : UInt.of(json.from); - this.to = json.to === null ? null : UInt.of(json.to); + this.unit = + typeof json.unit === 'string' + ? (json.unit as FilterRangeUnits) + : undefined; + this.from = + typeof json.from === 'number' ? UInt.of(json.from) : undefined; + this.to = typeof json.to === 'number' ? UInt.of(json.to) : undefined; } toJSON(): FilterRangeJSON { return { - unit: this.unit === null ? null : this.unit.toString(), - from: this.from === null ? null : this.from.valueOf(), - to: this.to === null ? null : this.to.valueOf() + unit: this.unit?.toString(), + from: this.from?.valueOf(), + to: this.to?.valueOf() } satisfies FilterRangeJSON; } } interface FilterRangeJSON { - unit: string | null; - from: number | null; - to: number | null; + unit?: string; + from?: number; + to?: number; } enum FilterRangeUnits { diff --git a/packages/net/src/thor/logs/LogSort.ts b/packages/net/src/thor/logs/LogSort.ts new file mode 100644 index 000000000..d31aec9de --- /dev/null +++ b/packages/net/src/thor/logs/LogSort.ts @@ -0,0 +1,6 @@ +enum LogSort { + asc = 'asc', + desc = 'desc' +} + +export { LogSort }; diff --git a/packages/net/src/thor/logs/TransferCriteria.ts b/packages/net/src/thor/logs/TransferCriteria.ts new file mode 100644 index 000000000..bc7fc3d1c --- /dev/null +++ b/packages/net/src/thor/logs/TransferCriteria.ts @@ -0,0 +1,34 @@ +import { Address } from '@vechain/sdk-core'; + +class TransferCriteria { + txOrigin?: Address; + sender?: Address; + recipient?: Address; + + constructor(json: TransferCriteriaJSON) { + this.txOrigin = + json.txOrigin === undefined ? undefined : Address.of(json.txOrigin); + this.sender = + json.sender === undefined ? undefined : Address.of(json.sender); + this.recipient = + json.recipient === undefined + ? undefined + : Address.of(json.recipient); + } + + toJSON(): TransferCriteriaJSON { + return { + txOrigin: this.txOrigin?.toString(), + sender: this.sender?.toString(), + recipient: this.recipient?.toString() + } satisfies TransferCriteriaJSON; + } +} + +interface TransferCriteriaJSON { + txOrigin?: string; + sender?: string; + recipient?: string; +} + +export { TransferCriteria, type TransferCriteriaJSON }; diff --git a/packages/net/src/thor/logs/TransferLogFilterRequest.ts b/packages/net/src/thor/logs/TransferLogFilterRequest.ts new file mode 100644 index 000000000..69f2653f9 --- /dev/null +++ b/packages/net/src/thor/logs/TransferLogFilterRequest.ts @@ -0,0 +1,48 @@ +import { FilterRange, type FilterRangeJSON } from './FilterRange'; +import { FilterOptions, type FilterOptionsJSON } from './FilterOptions'; +import { type LogSort } from './LogSort'; +import { + TransferCriteria, + type TransferCriteriaJSON +} from './TransferCriteria'; + +class TransferLogFilterRequest { + readonly range?: FilterRange; + readonly options?: FilterOptions; + readonly criteriaSet?: TransferCriteria[]; + readonly order?: LogSort; + + constructor(json: TransferLogFilterRequestJSON) { + this.range = + json.range === undefined ? undefined : new FilterRange(json.range); + this.options = + json.options === undefined + ? undefined + : new FilterOptions(json.options); + this.criteriaSet = json.criteriaSet?.map( + (criteriaJSON) => new TransferCriteria(criteriaJSON) + ); + this.order = + json.order === undefined + ? undefined + : (json.order satisfies LogSort); + } + + toJSON(): TransferLogFilterRequestJSON { + return { + range: this.range?.toJSON(), + options: this.options?.toJSON(), + criteriaSet: this.criteriaSet?.map((criteria) => criteria.toJSON()), + order: this.order + } satisfies TransferLogFilterRequestJSON; + } +} + +interface TransferLogFilterRequestJSON { + range?: FilterRangeJSON; + options?: FilterOptionsJSON; + criteriaSet?: TransferCriteriaJSON[]; + order?: LogSort; +} + +export { TransferLogFilterRequest, type TransferLogFilterRequestJSON }; diff --git a/packages/net/src/thor/logs/TransferLogsResponse.ts b/packages/net/src/thor/logs/TransferLogsResponse.ts new file mode 100644 index 000000000..f8e74eb77 --- /dev/null +++ b/packages/net/src/thor/logs/TransferLogsResponse.ts @@ -0,0 +1,43 @@ +import { LogMeta, type LogMetaJSON } from './LogMeta'; +import { Address, HexUInt, Units, VET } from '@vechain/sdk-core'; + +class TransferLogResponse { + sender: Address; + recipient: Address; + amount: VET; + meta: LogMeta; + + constructor(json: TransferLogResponseJSON) { + this.sender = Address.of(json.sender); + this.recipient = Address.of(json.recipient); + this.amount = VET.of(HexUInt.of(json.amount).bi, Units.wei); + this.meta = new LogMeta(json.meta); + } + + toJSON(): TransferLogResponseJSON { + return { + sender: this.sender.toString(), + recipient: this.recipient.toString(), + amount: HexUInt.of(this.amount.wei).toString(), + meta: this.meta.toJSON() + } satisfies TransferLogResponseJSON; + } +} + +interface TransferLogResponseJSON { + sender: string; + recipient: string; + amount: string; + meta: LogMetaJSON; +} + +interface TransferLogsResponse extends Array {} + +interface TransferLogsResponseJSON extends Array {} + +export { + TransferLogResponse, + type TransferLogResponseJSON, + type TransferLogsResponse, + type TransferLogsResponseJSON +}; diff --git a/packages/net/src/thor/logs/index.ts b/packages/net/src/thor/logs/index.ts index 805bdca35..2a810e494 100644 --- a/packages/net/src/thor/logs/index.ts +++ b/packages/net/src/thor/logs/index.ts @@ -4,4 +4,7 @@ export * from './EventLogsResponse'; export * from './FilterOptions'; export * from './FilterRange'; export * from './LogMeta'; +export * from './LogSort'; export * from './QuerySmartContractEvents'; +export * from './TransferLogsResponse'; +export * from './TransferCriteria'; diff --git a/packages/net/tests/thor/logs/QuerySmartContractEvents.testnet.test.ts b/packages/net/tests/thor/logs/QuerySmartContractEvents.testnet.test.ts index aed7223d1..00bfa8cf9 100644 --- a/packages/net/tests/thor/logs/QuerySmartContractEvents.testnet.test.ts +++ b/packages/net/tests/thor/logs/QuerySmartContractEvents.testnet.test.ts @@ -22,10 +22,7 @@ describe('QuerySmartContractEvents testnet tests', () => { { address: '0x0000000000000000000000000000456E65726779', topic0: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', - topic1: '0x0000000000000000000000006d95e6dca01d109882fe1726a2fb9865fa41e7aa', - topic2: null, - topic3: null, - topic4: null + topic1: '0x0000000000000000000000006d95e6dca01d109882fe1726a2fb9865fa41e7aa' } ], order: 'asc' From c589254dc17f5592a7685260ca08fd96039759b4 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 18 Dec 2024 20:16:00 +0000 Subject: [PATCH 44/98] feat: 1484 log in dev... --- docs/diagrams/v2/net/thor/logs/logs.md | 165 ++++++++++++++++++ docs/diagrams/v2/network/thor/logs/logs.md | 124 ------------- .../src/thor/logs/QueryVETTransferEvents.ts | 52 ++++++ 3 files changed, 217 insertions(+), 124 deletions(-) create mode 100644 docs/diagrams/v2/net/thor/logs/logs.md delete mode 100644 docs/diagrams/v2/network/thor/logs/logs.md create mode 100644 packages/net/src/thor/logs/QueryVETTransferEvents.ts diff --git a/docs/diagrams/v2/net/thor/logs/logs.md b/docs/diagrams/v2/net/thor/logs/logs.md new file mode 100644 index 000000000..7581464aa --- /dev/null +++ b/docs/diagrams/v2/net/thor/logs/logs.md @@ -0,0 +1,165 @@ +```mermaid +classDiagram + class EventCriteria { + address?: Address + topic0?: ThorId + topic1?: ThorId + topic2?: ThorId + topic3?: ThorId + topic4?: ThorId + } + class EventCriteriaJSON { + <> + address?: string; + topic0?: string + topic1?: string + topic2?: string + topic3?: string + topic4?: string + } + class EventLogFilterRequest { + range?: FilterRange + options?: FilterOptions + criteriaSet?: EventCriteria[] + order?: EventLogFilterRequestOrder + } + class EventLogFilterRequestJSON { + <> + range?: FilterRangeJSON + options?: FilterOptionsJSON + criteriaSet?: EventCriteriaJSON[] + order?: string + } + class EventLogResponse { + readonly address: Address; + readonly topics: ThorId[]; + readonly data: HexUInt; + readonly meta: LogMeta; + } + class EventLogResponseJSON { + address: string; + topics: string[]; + data: string; + meta: LogMetaJSON; + } + class EventLogsResponse { + } + class FilterOptions { + limit?: UInt + offset?: UInt + } + class FilterOptionsJSON { + <> + limit?: number + offset?: number + } + class FilterRange { + from?: UInt + to?: UInt + unit?: FilterRangeUnit + } + class FilterRangeJSON { + <> + from?: number + to?: number + unit?: string + } + class FilterRangeUnit { + <> + block$ + time$ + } + class LogMeta { + blockID: BlockId; + blockNumber: UInt; + blockTimestamp: UInt; + txID: TxId; + txOrigin: Address; + clauseIndex: UInt; + } + class LogMetaJSON { + <> + blockID: string; + blockNumber: number; + blockTimestamp: number; + txID: string; + txOrigin: string; + clauseIndex: number; + } + class LogSort { + <> + asc$ + desc$ + } + class QuerySmartContractEvents { + PATH$: HttpPath + request: EventLogFilterRequest + constructor(request: EventLogFilterRequest) + askTo(httpClient: HttpClient): Promise~ThorResponse~EventLogsResponse~~ + of(request: EventLogFilterRequestJSON)$ + } + class TransferCriteria { + txOrigin?: Address; + sender?: Address; + recipient?: Address; + constructor(json: TransferCriteriaJSON) + toJSON(): TransferCriteriaJSON + } + class TransferCriteriaJSON { + txOrigin?: string; + sender?: string; + recipient?: string; + } + class TransferLogFilterRequest { + range?: FilterRange + options?: FilterOptions + criteriaSet?: TransferCriteria[] + order?: LogSort + constructor(json: TransferLogFilterRequestJSON) + toJSON(): TransferLogFilterRequestJSON + } + class TransferLogFilterRequestJSON { + <> + range?: FilterRangeJSON + options?: FilterOptionsJSON + criteriaSet?: TransferCriteriaJSON[] + order?: LogSort + } + class TransferLogResponse { + sender: Address + recipient: Address + amount: VET + meta: LogMeta + constructor(json: TransferLogResponseJSON) + toJSON(): TransferLogResponseJSON + } + class TransferLogsResponse { + } + EventCriteriaJSON <-- EventCriteria + EventLogFilterRequestJSON <-- EventLogFilterRequest + EventLogResponseJSON <-- EventLogResponse + EventLogsResponse <-- QuerySmartContractEvents + FilterOptionsJSON <-- FilterOptions + FilterRangeJSON <-- FilterRange + LogMetaJSON <-- LogMeta + TransferCriteriaJSON <-- TransferCriteria + TransferLogFilterRequestJSON <-- TransferLogFilterRequest + EventLogResponse "*" o-- EventLogsResponse + TransferLogResponse "*" o-- TransferLogsResponse + EventLogFilterRequest --* FilterRange + EventLogFilterRequest --* FilterOptions + EventLogFilterRequest --* EventCriteria + EventLogFilterRequest --* LogSort + EventLogFilterRequestJSON --* FilterRangeJSON + EventLogFilterRequestJSON --* FilterOptionsJSON + EventLogFilterRequestJSON --* EventCriteriaJSON + EventLogResponse --* LogMeta + EventLogResponseJSON --* LogMetaJSON + FilterRange --* FilterRangeUnit + QuerySmartContractEvents --* EventLogFilterRequest + TransferLogFilterRequest --* FilterRange + TransferLogFilterRequest --* FilterOptions + TransferLogFilterRequest --* "*" TransferCriteria + TransferLogFilterRequest --* LogSort + TransferLogResponse --* LogMeta +``` diff --git a/docs/diagrams/v2/network/thor/logs/logs.md b/docs/diagrams/v2/network/thor/logs/logs.md deleted file mode 100644 index 6a957c497..000000000 --- a/docs/diagrams/v2/network/thor/logs/logs.md +++ /dev/null @@ -1,124 +0,0 @@ -```mermaid -classDiagram - class Array~EventLogsResponse~ { - } - class EventCriteria { - address: Address | null; - topic0: ThorId | null; - topic1: ThorId | null; - topic2: ThorId | null; - topic3: ThorId | null; - topic4: ThorId | null; - } - class EventCriteriaJSON { - <> - address: string | null; - topic0: string | null; - topic1: string | null; - topic2: string | null; - topic3: string | null; - topic4: string | null; - } - class EventLogFilterRequest { - range: FilterRange | null; - options: FilterOptions | null; - criteriaSet: EventCriteria[] | null; - order: EventLogFilterRequestOrder | null; - } - class EventLogFilterRequestJSON { - <> - range: FilterRangeJSON | null; - options: FilterOptionsJSON | null; - criteriaSet: EventCriteriaJSON[] | null; - order: string | null; - } - class EventLogFilterRequestOrder { - <> - asc$ - desc$ - } - class EventLogResponse { - readonly address: Address; - readonly topics: ThorId[]; - readonly data: HexUInt; - readonly meta: LogMeta; - } - class EventLogResponseJSON { - address: string; - topics: string[]; - data: string; - meta: LogMetaJSON; - } - class EventLogsResponse { - } - class FilterOptions { - limit: UInt | null; - offset: UInt | null; - } - class FilterOptionsJSON { - <> - limit: number | null; - offset: number | null; - } - class FilterRange { - from: UInt|null - to: UInt|null - unit: FilterRangeUnit|null - } - class FilterRangeJSON { - <> - from: number|null - to: number|null - unit: string|null - } - class FilterRangeUnit { - <> - block$ - time$ - } - class LogMeta { - blockID: BlockId; - blockNumber: UInt; - blockTimestamp: UInt; - txID: TxId; - txOrigin: Address; - clauseIndex: UInt; - } - class LogMetaJSON { - <> - blockID: string; - blockNumber: number; - blockTimestamp: number; - txID: string; - txOrigin: string; - clauseIndex: number; - } - class QuerySmartContractEvents { - PATH$: HttpPath - request: EventLogFilterRequest - constructor(request: EventLogFilterRequest) - askTo(httpClient: HttpClient): Promise~ThorResponse~EventLogsResponse~~ - of(request: EventLogFilterRequestJSON)$ - } - Array~EventLogResponse~ <|-- EventLogsResponse - EventCriteriaJSON <-- EventCriteria - EventLogFilterRequestJSON <-- EventLogFilterRequest - EventLogResponse <-- Array~EventLogResponse~ - EventLogResponseJSON <-- EventLogResponse - EventLogsResponse <-- QuerySmartContractEvents - FilterOptionsJSON <-- FilterOptions - FilterRangeJSON <-- FilterRange - LogMetaJSON <-- LogMeta - EventLogFilterRequest --* FilterRange - EventLogFilterRequest --* FilterOptions - EventLogFilterRequest --* EventCriteria - EventLogFilterRequest --* EventLogFilterRequestOrder - EventLogFilterRequestJSON --* FilterRangeJSON - EventLogFilterRequestJSON --* FilterOptionsJSON - EventLogFilterRequestJSON --* EventCriteriaJSON - EventLogResponse --* LogMeta - EventLogResponseJSON --* LogMetaJSON - FilterRange --* FilterRangeUnit - QuerySmartContractEvents --* EventLogFilterRequest - -``` diff --git a/packages/net/src/thor/logs/QueryVETTransferEvents.ts b/packages/net/src/thor/logs/QueryVETTransferEvents.ts new file mode 100644 index 000000000..4296b3e59 --- /dev/null +++ b/packages/net/src/thor/logs/QueryVETTransferEvents.ts @@ -0,0 +1,52 @@ +import { + TransferLogResponse, + type TransferLogResponseJSON, + type TransferLogsResponse, + type TransferLogsResponseJSON +} from './TransferLogsResponse'; +import { type ThorRequest } from '../ThorRequest'; +import type { HttpClient, HttpPath } from '../../http'; +import { + TransferLogFilterRequest, + type TransferLogFilterRequestJSON +} from './TransferLogFilterRequest'; +import { type ThorResponse } from '../ThorResponse'; + +class QueryVETTransferEvents + implements ThorRequest +{ + static readonly PATH: HttpPath = { path: '/logs/transfer' }; + + readonly request: TransferLogFilterRequest; + + constructor(request: TransferLogFilterRequest) { + this.request = request; + } + + async askTo( + httpClient: HttpClient + ): Promise> { + const response = await httpClient.post( + QueryVETTransferEvents.PATH, + { query: '' }, + this.request.toJSON() + ); + const responseBody = + (await response.json()) as TransferLogsResponseJSON; + return { + request: this, + response: responseBody.map( + (json: TransferLogResponseJSON): TransferLogResponse => + new TransferLogResponse(json) + ) as TransferLogsResponse + }; + } + + static of(request: TransferLogFilterRequestJSON): QueryVETTransferEvents { + return new QueryVETTransferEvents( + new TransferLogFilterRequest(request) + ); + } +} + +export { QueryVETTransferEvents }; From febf36477120d135662529f41a8e0117382e7629 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 18 Dec 2024 20:30:23 +0000 Subject: [PATCH 45/98] feat: 1484 log in dev... --- .../src/thor/logs/TransferLogFilterRequest.ts | 6 ++-- .../QueryVETTransferEvents.testnet.test.ts | 32 +++++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 packages/net/tests/thor/logs/QueryVETTransferEvents.testnet.test.ts diff --git a/packages/net/src/thor/logs/TransferLogFilterRequest.ts b/packages/net/src/thor/logs/TransferLogFilterRequest.ts index 69f2653f9..8257c903f 100644 --- a/packages/net/src/thor/logs/TransferLogFilterRequest.ts +++ b/packages/net/src/thor/logs/TransferLogFilterRequest.ts @@ -23,9 +23,7 @@ class TransferLogFilterRequest { (criteriaJSON) => new TransferCriteria(criteriaJSON) ); this.order = - json.order === undefined - ? undefined - : (json.order satisfies LogSort); + json.order === undefined ? undefined : (json.order as LogSort); } toJSON(): TransferLogFilterRequestJSON { @@ -42,7 +40,7 @@ interface TransferLogFilterRequestJSON { range?: FilterRangeJSON; options?: FilterOptionsJSON; criteriaSet?: TransferCriteriaJSON[]; - order?: LogSort; + order?: string; } export { TransferLogFilterRequest, type TransferLogFilterRequestJSON }; diff --git a/packages/net/tests/thor/logs/QueryVETTransferEvents.testnet.test.ts b/packages/net/tests/thor/logs/QueryVETTransferEvents.testnet.test.ts new file mode 100644 index 000000000..2d82713df --- /dev/null +++ b/packages/net/tests/thor/logs/QueryVETTransferEvents.testnet.test.ts @@ -0,0 +1,32 @@ +import { describe, test } from '@jest/globals'; +import { type TransferLogFilterRequestJSON } from '../../../src/thor/logs/TransferLogFilterRequest'; +import { QueryVETTransferEvents } from '../../../src/thor/logs/QueryVETTransferEvents'; +import { FetchHttpClient, ThorNetworks } from '../../../src'; + +describe('QueryVETTransferEvents testnet tests', () => { + test('ok <- askTo', async () => { + const request = { + range: { + unit: 'block', + from: 17240365, + to: 17289864 + }, + options: { + offset: 0, + limit: 100 + }, + criteriaSet: [ + { + txOrigin: '0x6d95e6dca01d109882fe1726a2fb9865fa41e7aa', + sender: '0x6d95e6dca01d109882fe1726a2fb9865fa41e7aa', + recipient: '0x45429a2255e7248e57fce99e7239aed3f84b7a53' + } + ], + order: 'asc' + } satisfies TransferLogFilterRequestJSON; + const r = await QueryVETTransferEvents.of(request).askTo( + FetchHttpClient.at(ThorNetworks.TESTNET) + ); + console.log(JSON.stringify(r, null, 2)); + }); +}); From c1d22579a338177d3b58b2ebb280c898e50d49dc Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 18 Dec 2024 20:58:59 +0000 Subject: [PATCH 46/98] feat: 1484 log in dev... --- docs/diagrams/v2/net/thor/logs/logs.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/diagrams/v2/net/thor/logs/logs.md b/docs/diagrams/v2/net/thor/logs/logs.md index 7581464aa..f50677050 100644 --- a/docs/diagrams/v2/net/thor/logs/logs.md +++ b/docs/diagrams/v2/net/thor/logs/logs.md @@ -98,6 +98,13 @@ classDiagram askTo(httpClient: HttpClient): Promise~ThorResponse~EventLogsResponse~~ of(request: EventLogFilterRequestJSON)$ } + class QueryVETTransferEvents { + PATH$: HttpPath + request: TransferLogFilterRequest + constructor(request: TransferLogFilterRequest) + askTo(httpClient: HttpClient): Promise~ThorResponse~TransferLogsResponse~~ + of(request: TransferLogFilterRequestJSON): QueryVETTransferEvents + } class TransferCriteria { txOrigin?: Address; sender?: Address; @@ -133,6 +140,12 @@ classDiagram constructor(json: TransferLogResponseJSON) toJSON(): TransferLogResponseJSON } + class TransferLogResponseJSON { + sender: string; + recipient: string; + amount: string; + meta: LogMetaJSON; + } class TransferLogsResponse { } EventCriteriaJSON <-- EventCriteria @@ -144,6 +157,8 @@ classDiagram LogMetaJSON <-- LogMeta TransferCriteriaJSON <-- TransferCriteria TransferLogFilterRequestJSON <-- TransferLogFilterRequest + TransferLogResponseJSON <-- TransferLogResponse + TransferLogsResponse <-- QueryVETTransferEvents EventLogResponse "*" o-- EventLogsResponse TransferLogResponse "*" o-- TransferLogsResponse EventLogFilterRequest --* FilterRange @@ -157,9 +172,11 @@ classDiagram EventLogResponseJSON --* LogMetaJSON FilterRange --* FilterRangeUnit QuerySmartContractEvents --* EventLogFilterRequest + QueryVETTransferEvents --* TransferLogFilterRequest TransferLogFilterRequest --* FilterRange TransferLogFilterRequest --* FilterOptions TransferLogFilterRequest --* "*" TransferCriteria TransferLogFilterRequest --* LogSort TransferLogResponse --* LogMeta + TransferLogResponseJSON --* LogMetaJSON ``` From da976d254275430af71353ea5c4fdf99c1ed22f9 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 18 Dec 2024 21:20:29 +0000 Subject: [PATCH 47/98] feat: 1484 log in dev... --- docs/diagrams/v2/net/thor/logs/logs.md | 40 ++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/docs/diagrams/v2/net/thor/logs/logs.md b/docs/diagrams/v2/net/thor/logs/logs.md index f50677050..d2ea34e9a 100644 --- a/docs/diagrams/v2/net/thor/logs/logs.md +++ b/docs/diagrams/v2/net/thor/logs/logs.md @@ -7,6 +7,8 @@ classDiagram topic2?: ThorId topic3?: ThorId topic4?: ThorId + constructor(json: EventCriteriaJSON) + toJSON() EventCriteriaJSON } class EventCriteriaJSON { <> @@ -22,6 +24,8 @@ classDiagram options?: FilterOptions criteriaSet?: EventCriteria[] order?: EventLogFilterRequestOrder + constructor(json: EventLogFilterRequestJSON) + toJSON() EventLogFilterRequestJSON } class EventLogFilterRequestJSON { <> @@ -35,18 +39,24 @@ classDiagram readonly topics: ThorId[]; readonly data: HexUInt; readonly meta: LogMeta; + constructor(json: EventLogResponseJSON) + toJSON() EventLogResponseJSON } class EventLogResponseJSON { + <> address: string; topics: string[]; data: string; meta: LogMetaJSON; } class EventLogsResponse { + <> } class FilterOptions { limit?: UInt offset?: UInt + constructor(json: FilterOptionsJSON) + toJSON() FilterOptionsJSON } class FilterOptionsJSON { <> @@ -57,6 +67,8 @@ classDiagram from?: UInt to?: UInt unit?: FilterRangeUnit + constructor(json: FilterRangeJSON) + toJSON() FilterRangeJSON } class FilterRangeJSON { <> @@ -76,6 +88,8 @@ classDiagram txID: TxId; txOrigin: Address; clauseIndex: UInt; + constructor(json: LogMetaJSON) + toJSON() LogMetaJSON } class LogMetaJSON { <> @@ -96,23 +110,24 @@ classDiagram request: EventLogFilterRequest constructor(request: EventLogFilterRequest) askTo(httpClient: HttpClient): Promise~ThorResponse~EventLogsResponse~~ - of(request: EventLogFilterRequestJSON)$ + of(request: EventLogFilterRequestJSON)$ QuerySmartContractEvents } class QueryVETTransferEvents { PATH$: HttpPath request: TransferLogFilterRequest constructor(request: TransferLogFilterRequest) askTo(httpClient: HttpClient): Promise~ThorResponse~TransferLogsResponse~~ - of(request: TransferLogFilterRequestJSON): QueryVETTransferEvents + of(request: TransferLogFilterRequestJSON) QueryVETTransferEvents } class TransferCriteria { txOrigin?: Address; sender?: Address; recipient?: Address; constructor(json: TransferCriteriaJSON) - toJSON(): TransferCriteriaJSON + toJSON() TransferCriteriaJSON } class TransferCriteriaJSON { + <> txOrigin?: string; sender?: string; recipient?: string; @@ -123,7 +138,7 @@ classDiagram criteriaSet?: TransferCriteria[] order?: LogSort constructor(json: TransferLogFilterRequestJSON) - toJSON(): TransferLogFilterRequestJSON + toJSON() TransferLogFilterRequestJSON } class TransferLogFilterRequestJSON { <> @@ -138,15 +153,28 @@ classDiagram amount: VET meta: LogMeta constructor(json: TransferLogResponseJSON) - toJSON(): TransferLogResponseJSON + toJSON() TransferLogResponseJSON } class TransferLogResponseJSON { + <> sender: string; recipient: string; amount: string; meta: LogMetaJSON; } class TransferLogsResponse { + <> + } + namespace thor { + class ThorRequest { + <> + askTo: (httpClient: HttpClient) Promise~ThorResponse~ResponseClass~~ + } + class ThorResponse { + <> + request: ~RequestClass~; + response: ~ResponseClass~; + } } EventCriteriaJSON <-- EventCriteria EventLogFilterRequestJSON <-- EventLogFilterRequest @@ -159,6 +187,8 @@ classDiagram TransferLogFilterRequestJSON <-- TransferLogFilterRequest TransferLogResponseJSON <-- TransferLogResponse TransferLogsResponse <-- QueryVETTransferEvents + ThorRequest <|.. QuerySmartContractEvents + ThorRequest <|.. QueryVETTransferEvents EventLogResponse "*" o-- EventLogsResponse TransferLogResponse "*" o-- TransferLogsResponse EventLogFilterRequest --* FilterRange From c390fc78b1dec29cc66bf3ebc52739000108f6ed Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Thu, 19 Dec 2024 09:29:35 +0000 Subject: [PATCH 48/98] feat: 1484 log in dev... --- docs/diagrams/v2/net/thor/logs/logs.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/diagrams/v2/net/thor/logs/logs.md b/docs/diagrams/v2/net/thor/logs/logs.md index d2ea34e9a..ad74b17a1 100644 --- a/docs/diagrams/v2/net/thor/logs/logs.md +++ b/docs/diagrams/v2/net/thor/logs/logs.md @@ -187,6 +187,10 @@ classDiagram TransferLogFilterRequestJSON <-- TransferLogFilterRequest TransferLogResponseJSON <-- TransferLogResponse TransferLogsResponse <-- QueryVETTransferEvents + ThorResponse <-- EventLogsResponse + ThorResponse <-- TransferLogResponse + ThorResponse <-- QuerySmartContractEvents + ThorResponse <-- QueryVETTransferEvents ThorRequest <|.. QuerySmartContractEvents ThorRequest <|.. QueryVETTransferEvents EventLogResponse "*" o-- EventLogsResponse From 4b4c15f8224f196fb307113a8296399eccfcd946 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Thu, 19 Dec 2024 12:18:54 +0000 Subject: [PATCH 49/98] feat: 1484 debug in dev... --- docs/diagrams/v2/net/thor/debug/debug.md | 50 +++++++++++++++++++ .../src/thor/debug/RetrieveStorageRange.ts | 41 +++++++++++++++ packages/net/src/thor/debug/StorageRange.ts | 26 ++++++++++ .../net/src/thor/debug/StorageRangeOption.ts | 36 +++++++++++++ packages/net/src/thor/debug/index.ts | 3 ++ .../RetrieveStorageRange.mainnet.test.ts | 22 ++++++++ 6 files changed, 178 insertions(+) create mode 100644 docs/diagrams/v2/net/thor/debug/debug.md create mode 100644 packages/net/src/thor/debug/RetrieveStorageRange.ts create mode 100644 packages/net/src/thor/debug/StorageRange.ts create mode 100644 packages/net/src/thor/debug/StorageRangeOption.ts create mode 100644 packages/net/src/thor/debug/index.ts create mode 100644 packages/net/tests/thor/debug/RetrieveStorageRange.mainnet.test.ts diff --git a/docs/diagrams/v2/net/thor/debug/debug.md b/docs/diagrams/v2/net/thor/debug/debug.md new file mode 100644 index 000000000..972355d29 --- /dev/null +++ b/docs/diagrams/v2/net/thor/debug/debug.md @@ -0,0 +1,50 @@ +```mermaid +classDiagram + class RetrieveStorageRange { + PATH$: HttpPath + request: StorageRangeOption + } + class StorageRange { + nextKey?: ThorId + storage: unknown + constructor(json: StorageRangeJSON) + toJSON() StorageRangeJSON + } + class StorageRangeJSON { + <> + nextKey?: string + storage: string + } + class StorageRangeOptions { + address: Address + keyStart?: ThorId + maxResult?: UInt + target: string + constructor(json: StorageRangeOptionJSON) + toJSON() StorageRangeOptionJSON + } + class StorageRangeOptionJSON { + <> + address: string + keyStart?: string + maxResult?: number + target: string + } + namespace thor { + class ThorRequest { + <> + askTo: (httpClient: HttpClient) Promise~ThorResponse~ResponseClass~~ + } + class ThorResponse { + <> + request: ~RequestClass~; + response: ~ResponseClass~; + } + } + StorageRange <-- RetrieveStorageRange + StorageRangeJSON <-- StorageRange + StorageRangeOptionJSON <-- StorageRangeOptions + ThorResponse <-- RetrieveStorageRange + ThorRequest <|.. RetrieveStorageRange + RetrieveStorageRange --* StorageRangeOptions +``` diff --git a/packages/net/src/thor/debug/RetrieveStorageRange.ts b/packages/net/src/thor/debug/RetrieveStorageRange.ts new file mode 100644 index 000000000..f50827612 --- /dev/null +++ b/packages/net/src/thor/debug/RetrieveStorageRange.ts @@ -0,0 +1,41 @@ +import type { HttpClient, HttpPath } from '../../http'; +import { type ThorRequest } from '../ThorRequest'; +import { + StorageRangeOption, + type StorageRangeOptionJSON +} from './StorageRangeOption'; +import { type ThorResponse } from '../ThorResponse'; +import { type StorageRange } from './StorageRange'; + +class RetrieveStorageRange + implements ThorRequest +{ + static readonly PATH: HttpPath = { path: '/debug/storage-range' }; + + readonly request: StorageRangeOption; + + constructor(request: StorageRangeOption) { + this.request = request; + } + + async askTo( + httpClient: HttpClient + ): Promise> { + const response = await httpClient.post( + RetrieveStorageRange.PATH, + { query: '' }, + this.request.toJSON() + ); + const responseBody = (await response.json()) as StorageRange; + return { + request: this, + response: responseBody + }; + } + + static of(request: StorageRangeOptionJSON): RetrieveStorageRange { + return new RetrieveStorageRange(new StorageRangeOption(request)); + } +} + +export { RetrieveStorageRange }; diff --git a/packages/net/src/thor/debug/StorageRange.ts b/packages/net/src/thor/debug/StorageRange.ts new file mode 100644 index 000000000..81bd8d430 --- /dev/null +++ b/packages/net/src/thor/debug/StorageRange.ts @@ -0,0 +1,26 @@ +import { ThorId } from '@vechain/sdk-core'; + +class StorageRange { + readonly nextKey?: ThorId; + readonly storage: undefined; + + constructor(json: StorageRangeJSON) { + this.nextKey = + json.nextKey === undefined ? undefined : ThorId.of(json.nextKey); + this.storage = json.storage; + } + + toJSON(): StorageRangeJSON { + return { + nextKey: this.nextKey?.toString(), + storage: this.storage + } satisfies StorageRangeJSON; + } +} + +interface StorageRangeJSON { + nextKey?: string; + storage: undefined; +} + +export { StorageRange, type StorageRangeJSON }; diff --git a/packages/net/src/thor/debug/StorageRangeOption.ts b/packages/net/src/thor/debug/StorageRangeOption.ts new file mode 100644 index 000000000..6416242d2 --- /dev/null +++ b/packages/net/src/thor/debug/StorageRangeOption.ts @@ -0,0 +1,36 @@ +import { Address, ThorId } from '@vechain/sdk-core'; +import { UInt } from '../../../../core'; + +class StorageRangeOption { + readonly address: Address; + readonly keyStart?: ThorId; + readonly maxResult?: UInt; + readonly target: string; // Path class? + + constructor(json: StorageRangeOptionJSON) { + this.address = Address.of(json.address); + this.keyStart = + json.keyStart === undefined ? undefined : ThorId.of(json.keyStart); + this.maxResult = + json.maxResult === undefined ? undefined : UInt.of(json.maxResult); + this.target = json.target; + } + + toJSON(): StorageRangeOptionJSON { + return { + address: this.address.toString(), + keyStart: this.keyStart?.toString(), + maxResult: this.maxResult?.valueOf(), + target: this.target + } satisfies StorageRangeOptionJSON; + } +} + +interface StorageRangeOptionJSON { + address: string; + keyStart?: string; + maxResult?: number; + target: string; +} + +export { StorageRangeOption, type StorageRangeOptionJSON }; diff --git a/packages/net/src/thor/debug/index.ts b/packages/net/src/thor/debug/index.ts new file mode 100644 index 000000000..f0eec0578 --- /dev/null +++ b/packages/net/src/thor/debug/index.ts @@ -0,0 +1,3 @@ +export * from './RetrieveStorageRange'; +export * from './StorageRange'; +export * from './StorageRangeOption'; diff --git a/packages/net/tests/thor/debug/RetrieveStorageRange.mainnet.test.ts b/packages/net/tests/thor/debug/RetrieveStorageRange.mainnet.test.ts new file mode 100644 index 000000000..3055ca05a --- /dev/null +++ b/packages/net/tests/thor/debug/RetrieveStorageRange.mainnet.test.ts @@ -0,0 +1,22 @@ +import { describe, test } from '@jest/globals'; +import { + RetrieveStorageRange, + type StorageRangeOptionJSON +} from '../../../src/thor/debug'; +import { FetchHttpClient, ThorNetworks } from '../../../src'; + +describe('RetrieveStorageRange testnet tests', () => { + test('ok <- askTo', async () => { + const request = { + address: '0xd8ccdd85abdbf68dfec95f06c973e87b1b5a9997', + keyStart: + '0x0000000000000000000000000000000000000000000000000000000000000000', + maxResult: 10, + target: '0x010709463c1f0c9aa66a31182fb36d1977d99bfb6526bae0564a0eac4006c31a/0/0' + } satisfies StorageRangeOptionJSON; + const r = await RetrieveStorageRange.of(request).askTo( + FetchHttpClient.at(ThorNetworks.MAINNET) + ); + console.log(JSON.stringify(r, null, 2)); + }); +}); From 549acc0927c33949cf9bf046fa5f6cbca08e2ad3 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Thu, 19 Dec 2024 18:20:43 +0000 Subject: [PATCH 50/98] feat: 1484 debug in dev... --- packages/net/src/thor/debug/TracerName.ts | 110 ++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 packages/net/src/thor/debug/TracerName.ts diff --git a/packages/net/src/thor/debug/TracerName.ts b/packages/net/src/thor/debug/TracerName.ts new file mode 100644 index 000000000..dd2ca066c --- /dev/null +++ b/packages/net/src/thor/debug/TracerName.ts @@ -0,0 +1,110 @@ +interface TracerName { + name: string; + toString: () => string; +} + +class StructLogger implements TracerName { + name = 'structLogger'; + toString: () => string = () => this.name; +} + +class FourByte implements TracerName { + name = '4byte'; + toString: () => string = () => this.name; +} + +class Call implements TracerName { + name = 'call'; + toString: () => string = () => this.name; +} + +class Noop implements TracerName { + name = 'noop'; + toString: () => string = () => this.name; +} + +class Prestate implements TracerName { + name = 'prestate'; + toString: () => string = () => this.name; +} + +class Unigram implements TracerName { + name = 'unigram'; + toString: () => string = () => this.name; +} + +class Bigram implements TracerName { + name = 'bigram'; + toString: () => string = () => this.name; +} + +class Trigram implements TracerName { + name = 'trigram'; + toString: () => string = () => this.name; +} + +class EvmDis implements TracerName { + name = 'evmdis'; + toString: () => string = () => this.name; +} + +class OpCount implements TracerName { + name = 'opcount'; + toString: () => string = () => this.name; +} + +class Null implements TracerName { + name = 'null'; + toString: () => string = () => this.name; +} + +class Tracer implements TracerName { + private static readonly NAMES: Map = new Map< + string, + TracerName + >() + .set(StructLogger.name, new StructLogger()) + .set(FourByte.name, new FourByte()) + .set(Call.name, new Call()) + .set(Noop.name, new Noop()) + .set(Prestate.name, new Prestate()) + .set(Unigram.name, new Unigram()) + .set(Bigram.name, new Bigram()) + .set(Trigram.name, new Trigram()) + .set(EvmDis.name, new EvmDis()) + .set(OpCount.name, new OpCount()) + .set(Null.name, new Null()); + + name: string; + + protected constructor(name: string) { + this.name = name; + } + + toString: () => string = () => this.name; + + static of(name: string): Tracer { + const label = Tracer.NAMES.get(name); + if (label !== undefined) { + return new Tracer(label.name); + } else { + throw new Error(`Tracer ${name} not found.`); + } + } +} + +export { + type TracerName, + StructLogger, + FourByte, + Call, + Noop, + Prestate, + Unigram, + Bigram, + Trigram, + EvmDis, + OpCount, + Null, + Tracer +}; From 0423a91e3fe852c3b241cabe44a87f79c2f58925 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Thu, 19 Dec 2024 19:48:58 +0000 Subject: [PATCH 51/98] feat: 1484 debug in dev... --- .../thor/debug/PostDebugTracerCallRequest.ts | 85 ++++++++++++++ packages/net/src/thor/debug/TraceACall.ts | 40 +++++++ packages/net/src/thor/debug/TracerName.ts | 107 +++++++++--------- packages/net/src/thor/debug/index.ts | 3 + .../RetrieveStorageRange.mainnet.test.ts | 2 +- .../thor/debug/TraceACall.testnet.test.ts | 28 +++++ 6 files changed, 208 insertions(+), 57 deletions(-) create mode 100644 packages/net/src/thor/debug/PostDebugTracerCallRequest.ts create mode 100644 packages/net/src/thor/debug/TraceACall.ts create mode 100644 packages/net/tests/thor/debug/TraceACall.testnet.test.ts diff --git a/packages/net/src/thor/debug/PostDebugTracerCallRequest.ts b/packages/net/src/thor/debug/PostDebugTracerCallRequest.ts new file mode 100644 index 000000000..c531eaa71 --- /dev/null +++ b/packages/net/src/thor/debug/PostDebugTracerCallRequest.ts @@ -0,0 +1,85 @@ +import { Tracer, type TracerName } from './TracerName'; +import { + Address, + type BlockRef, + HexUInt, + Units, + VET, + VTHO +} from '@vechain/sdk-core'; +import { UInt } from '../../../../core'; + +class PostDebugTracerCallRequest { + readonly name?: TracerName; + readonly config?: unknown; + readonly value: VET; + readonly data: HexUInt; + readonly to?: Address; + readonly gas?: VTHO; + readonly gasPrice?: VTHO; + readonly caller?: Address; + readonly provedWork?: string; + readonly gasPayer?: Address; + readonly expiration?: UInt; + readonly blockRef?: BlockRef; + + constructor(json: PostDebugTracerCallRequestJSON) { + this.name = json.name === undefined ? undefined : Tracer.of(json.name); + this.config = json.config; + this.value = VET.of(json.value); + this.data = HexUInt.of(json.data); + this.to = json.to === undefined ? undefined : Address.of(json.to); + this.gas = + json.gas === undefined ? undefined : VTHO.of(json.gas, Units.wei); + this.gasPrice = + json.gasPrice === undefined + ? undefined + : VTHO.of(json.gasPrice, Units.wei); + this.caller = + json.caller === undefined ? undefined : Address.of(json.caller); + this.provedWork = json.provedWork; + this.gasPayer = + json.gasPayer === undefined ? undefined : Address.of(json.gasPayer); + this.expiration = + json.expiration === undefined + ? undefined + : UInt.of(json.expiration); + } + + toJSON(): PostDebugTracerCallRequestJSON { + return { + name: this.name?.toString(), + config: this.config, + value: HexUInt.of(this.value.wei).toString(), + data: this.data.toString(), + to: this.to?.toString(), + gas: this.gas === undefined ? undefined : Number(this.gas.wei), + gasPrice: + this.gasPrice === undefined + ? undefined + : this.gasPrice.wei?.toString(), + caller: this.caller?.toString(), + provedWork: this.provedWork, + gasPayer: this.gasPayer?.toString(), + expiration: this.expiration?.valueOf(), + blockRef: this.blockRef?.toString() + }; + } +} + +interface PostDebugTracerCallRequestJSON { + name?: string; + config?: unknown; + value: string; + data: string; + to?: string; + gas?: number; + gasPrice?: string; + caller?: string; + provedWork?: string; + gasPayer?: string; + expiration?: number; + blockRef?: string; +} + +export { PostDebugTracerCallRequest, type PostDebugTracerCallRequestJSON }; diff --git a/packages/net/src/thor/debug/TraceACall.ts b/packages/net/src/thor/debug/TraceACall.ts new file mode 100644 index 000000000..9a6c8c4f2 --- /dev/null +++ b/packages/net/src/thor/debug/TraceACall.ts @@ -0,0 +1,40 @@ +import { type ThorRequest } from '../ThorRequest'; +import { type HttpClient, type HttpPath } from '../../http'; +import { + PostDebugTracerCallRequest, + type PostDebugTracerCallRequestJSON +} from './PostDebugTracerCallRequest'; +import { type ThorResponse } from '../ThorResponse'; + +class TraceACall implements ThorRequest { + static readonly PATH: HttpPath = { path: '/debug/tracers/call' }; + + readonly request: PostDebugTracerCallRequest; + + constructor(request: PostDebugTracerCallRequest) { + this.request = request; + } + + async askTo( + httpClient: HttpClient + ): Promise> { + const R = this.request.toJSON(); + console.log(R); + const response = await httpClient.post( + TraceACall.PATH, + { query: '' }, + this.request.toJSON() + ); + const responseBody: unknown = await response.json(); + return { + request: this, + response: responseBody as undefined + }; + } + + static of(request: PostDebugTracerCallRequestJSON): TraceACall { + return new TraceACall(new PostDebugTracerCallRequest(request)); + } +} + +export { TraceACall }; diff --git a/packages/net/src/thor/debug/TracerName.ts b/packages/net/src/thor/debug/TracerName.ts index dd2ca066c..6bc808546 100644 --- a/packages/net/src/thor/debug/TracerName.ts +++ b/packages/net/src/thor/debug/TracerName.ts @@ -1,95 +1,90 @@ -interface TracerName { - name: string; - toString: () => string; +abstract class TracerName { + abstract toString: () => string; } class StructLogger implements TracerName { - name = 'structLogger'; - toString: () => string = () => this.name; + static readonly NAME = 'structLogger'; + toString: () => string = () => StructLogger.NAME; } class FourByte implements TracerName { - name = '4byte'; - toString: () => string = () => this.name; + static readonly NAME = '4byte'; + toString: () => string = () => FourByte.NAME; } class Call implements TracerName { - name = 'call'; - toString: () => string = () => this.name; + static readonly NAME = 'call'; + toString: () => string = () => Call.NAME; } class Noop implements TracerName { - name = 'noop'; - toString: () => string = () => this.name; + static readonly NAME = 'noop'; + toString: () => string = () => Noop.NAME; } class Prestate implements TracerName { - name = 'prestate'; - toString: () => string = () => this.name; + static readonly NAME = 'prestate'; + toString: () => string = () => Prestate.NAME; } class Unigram implements TracerName { - name = 'unigram'; - toString: () => string = () => this.name; + static readonly NAME = 'unigram'; + toString: () => string = () => Unigram.NAME; } class Bigram implements TracerName { - name = 'bigram'; - toString: () => string = () => this.name; + static readonly NAME = 'bigram'; + toString: () => string = () => Bigram.NAME; } class Trigram implements TracerName { - name = 'trigram'; - toString: () => string = () => this.name; + static readonly NAME = 'trigram'; + toString: () => string = () => Trigram.NAME; } class EvmDis implements TracerName { - name = 'evmdis'; - toString: () => string = () => this.name; + static readonly NAME = 'evmdis'; + toString: () => string = () => EvmDis.NAME; } class OpCount implements TracerName { - name = 'opcount'; - toString: () => string = () => this.name; + static readonly NAME = 'opcount'; + toString: () => string = () => OpCount.NAME; } class Null implements TracerName { - name = 'null'; - toString: () => string = () => this.name; + static readonly NAME = 'null'; + toString: () => string = () => Null.NAME; } -class Tracer implements TracerName { - private static readonly NAMES: Map = new Map< - string, - TracerName - >() - .set(StructLogger.name, new StructLogger()) - .set(FourByte.name, new FourByte()) - .set(Call.name, new Call()) - .set(Noop.name, new Noop()) - .set(Prestate.name, new Prestate()) - .set(Unigram.name, new Unigram()) - .set(Bigram.name, new Bigram()) - .set(Trigram.name, new Trigram()) - .set(EvmDis.name, new EvmDis()) - .set(OpCount.name, new OpCount()) - .set(Null.name, new Null()); - - name: string; - - protected constructor(name: string) { - this.name = name; - } - - toString: () => string = () => this.name; - - static of(name: string): Tracer { - const label = Tracer.NAMES.get(name); - if (label !== undefined) { - return new Tracer(label.name); - } else { - throw new Error(`Tracer ${name} not found.`); +// eslint-disable-next-line @typescript-eslint/no-extraneous-class +class Tracer { + static of(name: string): TracerName { + switch (name) { + case StructLogger.NAME: + return new StructLogger(); + case FourByte.NAME: + return new FourByte(); + case Call.NAME: + return new Call(); + case Noop.NAME: + return new Noop(); + case Prestate.NAME: + return new Prestate(); + case Unigram.NAME: + return new Unigram(); + case Bigram.NAME: + return new Bigram(); + case Trigram.NAME: + return new Trigram(); + case EvmDis.NAME: + return new EvmDis(); + case OpCount.NAME: + return new OpCount(); + case Null.NAME: + return new Null(); } + throw new Error(`TracerName ${name} not found`); } } diff --git a/packages/net/src/thor/debug/index.ts b/packages/net/src/thor/debug/index.ts index f0eec0578..4efca7a68 100644 --- a/packages/net/src/thor/debug/index.ts +++ b/packages/net/src/thor/debug/index.ts @@ -1,3 +1,6 @@ +export * from './PostDebugTracerCallRequest'; export * from './RetrieveStorageRange'; export * from './StorageRange'; export * from './StorageRangeOption'; +export * from './TraceACall'; +export * from './TracerName'; diff --git a/packages/net/tests/thor/debug/RetrieveStorageRange.mainnet.test.ts b/packages/net/tests/thor/debug/RetrieveStorageRange.mainnet.test.ts index 3055ca05a..daba15595 100644 --- a/packages/net/tests/thor/debug/RetrieveStorageRange.mainnet.test.ts +++ b/packages/net/tests/thor/debug/RetrieveStorageRange.mainnet.test.ts @@ -5,7 +5,7 @@ import { } from '../../../src/thor/debug'; import { FetchHttpClient, ThorNetworks } from '../../../src'; -describe('RetrieveStorageRange testnet tests', () => { +describe('RetrieveStorageRange mainnet tests', () => { test('ok <- askTo', async () => { const request = { address: '0xd8ccdd85abdbf68dfec95f06c973e87b1b5a9997', diff --git a/packages/net/tests/thor/debug/TraceACall.testnet.test.ts b/packages/net/tests/thor/debug/TraceACall.testnet.test.ts new file mode 100644 index 000000000..6e879e159 --- /dev/null +++ b/packages/net/tests/thor/debug/TraceACall.testnet.test.ts @@ -0,0 +1,28 @@ +import { describe, test } from '@jest/globals'; +import { + type PostDebugTracerCallRequestJSON, + TraceACall +} from '../../../src/thor/debug'; +import { FetchHttpClient, ThorNetworks } from '../../../src'; + +describe('RetrieveStorageRange testnet tests', () => { + test('ok <- askTo', async () => { + const request = { + value: '0x0', + to: '0x0000000000000000000000000000456E65726779', + data: '0xa9059cbb0000000000000000000000000f872421dc479f3c11edd89512731814d0598db50000000000', + gas: 50000, + gasPrice: '1000000000000000', + caller: '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed', + provedWork: '1000', + gasPayer: '0xd3ae78222beadb038203be21ed5ce7c9b1bff602', + expiration: 1000, + blockRef: '0x00000000851caf3c', + name: 'call' + } satisfies PostDebugTracerCallRequestJSON; + const r = await TraceACall.of(request).askTo( + FetchHttpClient.at(ThorNetworks.TESTNET) + ); + console.log(JSON.stringify(r, null, 2)); + }); +}); From dbc0862a85842f4c818ad72adecb7ac9b754728e Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Thu, 19 Dec 2024 22:24:37 +0000 Subject: [PATCH 52/98] feat: 1484 debug in dev... --- .../src/thor/debug/PostDebugTracerRequest.ts | 29 ++++++++++++++ .../debug/{TraceACall.ts => TraceCall.ts} | 14 +++---- .../src/thor/debug/TraceTransactionClause.ts | 40 +++++++++++++++++++ packages/net/src/thor/debug/index.ts | 4 +- ...tnet.test.ts => TraceCall.testnet.test.ts} | 6 +-- .../TraceTransactionClause.mainnet.test.ts | 20 ++++++++++ 6 files changed, 101 insertions(+), 12 deletions(-) create mode 100644 packages/net/src/thor/debug/PostDebugTracerRequest.ts rename packages/net/src/thor/debug/{TraceACall.ts => TraceCall.ts} (69%) create mode 100644 packages/net/src/thor/debug/TraceTransactionClause.ts rename packages/net/tests/thor/debug/{TraceACall.testnet.test.ts => TraceCall.testnet.test.ts} (88%) create mode 100644 packages/net/tests/thor/debug/TraceTransactionClause.mainnet.test.ts diff --git a/packages/net/src/thor/debug/PostDebugTracerRequest.ts b/packages/net/src/thor/debug/PostDebugTracerRequest.ts new file mode 100644 index 000000000..91bc81484 --- /dev/null +++ b/packages/net/src/thor/debug/PostDebugTracerRequest.ts @@ -0,0 +1,29 @@ +import { Tracer, type TracerName } from './TracerName'; + +class PostDebugTracerRequest { + readonly name?: TracerName; + readonly config?: unknown; + readonly target: string; + + constructor(json: PostDebugTracerRequestJSON) { + this.name = json.name === undefined ? undefined : Tracer.of(json.name); + this.config = json.config; + this.target = json.target; + } + + toJSON(): PostDebugTracerRequestJSON { + return { + name: this.name?.toString(), + config: this.config, + target: this.target + }; + } +} + +interface PostDebugTracerRequestJSON { + name?: string; + config?: unknown; + target: string; +} + +export { PostDebugTracerRequest, type PostDebugTracerRequestJSON }; diff --git a/packages/net/src/thor/debug/TraceACall.ts b/packages/net/src/thor/debug/TraceCall.ts similarity index 69% rename from packages/net/src/thor/debug/TraceACall.ts rename to packages/net/src/thor/debug/TraceCall.ts index 9a6c8c4f2..d74a28023 100644 --- a/packages/net/src/thor/debug/TraceACall.ts +++ b/packages/net/src/thor/debug/TraceCall.ts @@ -6,7 +6,7 @@ import { } from './PostDebugTracerCallRequest'; import { type ThorResponse } from '../ThorResponse'; -class TraceACall implements ThorRequest { +class TraceCall implements ThorRequest { static readonly PATH: HttpPath = { path: '/debug/tracers/call' }; readonly request: PostDebugTracerCallRequest; @@ -17,11 +17,9 @@ class TraceACall implements ThorRequest { async askTo( httpClient: HttpClient - ): Promise> { - const R = this.request.toJSON(); - console.log(R); + ): Promise> { const response = await httpClient.post( - TraceACall.PATH, + TraceCall.PATH, { query: '' }, this.request.toJSON() ); @@ -32,9 +30,9 @@ class TraceACall implements ThorRequest { }; } - static of(request: PostDebugTracerCallRequestJSON): TraceACall { - return new TraceACall(new PostDebugTracerCallRequest(request)); + static of(request: PostDebugTracerCallRequestJSON): TraceCall { + return new TraceCall(new PostDebugTracerCallRequest(request)); } } -export { TraceACall }; +export { TraceCall }; diff --git a/packages/net/src/thor/debug/TraceTransactionClause.ts b/packages/net/src/thor/debug/TraceTransactionClause.ts new file mode 100644 index 000000000..73e0d6835 --- /dev/null +++ b/packages/net/src/thor/debug/TraceTransactionClause.ts @@ -0,0 +1,40 @@ +import { type ThorRequest } from '../ThorRequest'; +import type { HttpClient, HttpPath } from '../../http'; +import { + PostDebugTracerRequest, + type PostDebugTracerRequestJSON +} from './PostDebugTracerRequest'; +import { type ThorResponse } from '../ThorResponse'; + +class TraceTransactionClause + implements ThorRequest +{ + static readonly PATH: HttpPath = { path: '/debug/tracers' }; + + readonly request: PostDebugTracerRequest; + + constructor(request: PostDebugTracerRequest) { + this.request = request; + } + + async askTo( + httpClient: HttpClient + ): Promise> { + const response = await httpClient.post( + TraceTransactionClause.PATH, + { query: '' }, + this.request.toJSON() + ); + const responseBody: unknown = await response.json(); + return { + request: this, + response: responseBody as undefined + }; + } + + static of(request: PostDebugTracerRequestJSON): TraceTransactionClause { + return new TraceTransactionClause(new PostDebugTracerRequest(request)); + } +} + +export { TraceTransactionClause }; diff --git a/packages/net/src/thor/debug/index.ts b/packages/net/src/thor/debug/index.ts index 4efca7a68..0a03ce0a4 100644 --- a/packages/net/src/thor/debug/index.ts +++ b/packages/net/src/thor/debug/index.ts @@ -1,6 +1,8 @@ export * from './PostDebugTracerCallRequest'; +export * from './PostDebugTracerRequest'; export * from './RetrieveStorageRange'; export * from './StorageRange'; export * from './StorageRangeOption'; -export * from './TraceACall'; +export * from './TraceCall'; export * from './TracerName'; +export * from './TraceTransactionClause'; diff --git a/packages/net/tests/thor/debug/TraceACall.testnet.test.ts b/packages/net/tests/thor/debug/TraceCall.testnet.test.ts similarity index 88% rename from packages/net/tests/thor/debug/TraceACall.testnet.test.ts rename to packages/net/tests/thor/debug/TraceCall.testnet.test.ts index 6e879e159..e06ad9722 100644 --- a/packages/net/tests/thor/debug/TraceACall.testnet.test.ts +++ b/packages/net/tests/thor/debug/TraceCall.testnet.test.ts @@ -1,11 +1,11 @@ import { describe, test } from '@jest/globals'; import { type PostDebugTracerCallRequestJSON, - TraceACall + TraceCall } from '../../../src/thor/debug'; import { FetchHttpClient, ThorNetworks } from '../../../src'; -describe('RetrieveStorageRange testnet tests', () => { +describe('TraceCall testnet tests', () => { test('ok <- askTo', async () => { const request = { value: '0x0', @@ -20,7 +20,7 @@ describe('RetrieveStorageRange testnet tests', () => { blockRef: '0x00000000851caf3c', name: 'call' } satisfies PostDebugTracerCallRequestJSON; - const r = await TraceACall.of(request).askTo( + const r = await TraceCall.of(request).askTo( FetchHttpClient.at(ThorNetworks.TESTNET) ); console.log(JSON.stringify(r, null, 2)); diff --git a/packages/net/tests/thor/debug/TraceTransactionClause.mainnet.test.ts b/packages/net/tests/thor/debug/TraceTransactionClause.mainnet.test.ts new file mode 100644 index 000000000..85daa5aa6 --- /dev/null +++ b/packages/net/tests/thor/debug/TraceTransactionClause.mainnet.test.ts @@ -0,0 +1,20 @@ +import { describe, test } from '@jest/globals'; +import { + type PostDebugTracerRequestJSON, + TraceTransactionClause +} from '../../../src/thor/debug'; +import { FetchHttpClient, ThorNetworks } from '../../../src'; + +describe('TraceTransactionClause mainnet tests', () => { + test('ok <- askTo', async () => { + const request = { + target: '0x010709463c1f0c9aa66a31182fb36d1977d99bfb6526bae0564a0eac4006c31a/0/0', + name: 'call', + config: {} + } satisfies PostDebugTracerRequestJSON; + const r = await TraceTransactionClause.of(request).askTo( + FetchHttpClient.at(ThorNetworks.MAINNET) + ); + console.log(JSON.stringify(r, null, 2)); + }); +}); From 8f9922f607a005b48e2dbdf7b810f3edabe0bf66 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Thu, 19 Dec 2024 22:24:37 +0000 Subject: [PATCH 53/98] feat: 1484 debug in dev... --- .../src/thor/debug/PostDebugTracerRequest.ts | 29 ++++++++++++++ .../debug/{TraceACall.ts => TraceCall.ts} | 14 +++---- .../src/thor/debug/TraceTransactionClause.ts | 40 +++++++++++++++++++ packages/net/src/thor/debug/index.ts | 4 +- ...tnet.test.ts => TraceCall.testnet.test.ts} | 6 +-- .../TraceTransactionClause.mainnet.test.ts | 20 ++++++++++ 6 files changed, 101 insertions(+), 12 deletions(-) create mode 100644 packages/net/src/thor/debug/PostDebugTracerRequest.ts rename packages/net/src/thor/debug/{TraceACall.ts => TraceCall.ts} (69%) create mode 100644 packages/net/src/thor/debug/TraceTransactionClause.ts rename packages/net/tests/thor/debug/{TraceACall.testnet.test.ts => TraceCall.testnet.test.ts} (88%) create mode 100644 packages/net/tests/thor/debug/TraceTransactionClause.mainnet.test.ts diff --git a/packages/net/src/thor/debug/PostDebugTracerRequest.ts b/packages/net/src/thor/debug/PostDebugTracerRequest.ts new file mode 100644 index 000000000..91bc81484 --- /dev/null +++ b/packages/net/src/thor/debug/PostDebugTracerRequest.ts @@ -0,0 +1,29 @@ +import { Tracer, type TracerName } from './TracerName'; + +class PostDebugTracerRequest { + readonly name?: TracerName; + readonly config?: unknown; + readonly target: string; + + constructor(json: PostDebugTracerRequestJSON) { + this.name = json.name === undefined ? undefined : Tracer.of(json.name); + this.config = json.config; + this.target = json.target; + } + + toJSON(): PostDebugTracerRequestJSON { + return { + name: this.name?.toString(), + config: this.config, + target: this.target + }; + } +} + +interface PostDebugTracerRequestJSON { + name?: string; + config?: unknown; + target: string; +} + +export { PostDebugTracerRequest, type PostDebugTracerRequestJSON }; diff --git a/packages/net/src/thor/debug/TraceACall.ts b/packages/net/src/thor/debug/TraceCall.ts similarity index 69% rename from packages/net/src/thor/debug/TraceACall.ts rename to packages/net/src/thor/debug/TraceCall.ts index 9a6c8c4f2..d74a28023 100644 --- a/packages/net/src/thor/debug/TraceACall.ts +++ b/packages/net/src/thor/debug/TraceCall.ts @@ -6,7 +6,7 @@ import { } from './PostDebugTracerCallRequest'; import { type ThorResponse } from '../ThorResponse'; -class TraceACall implements ThorRequest { +class TraceCall implements ThorRequest { static readonly PATH: HttpPath = { path: '/debug/tracers/call' }; readonly request: PostDebugTracerCallRequest; @@ -17,11 +17,9 @@ class TraceACall implements ThorRequest { async askTo( httpClient: HttpClient - ): Promise> { - const R = this.request.toJSON(); - console.log(R); + ): Promise> { const response = await httpClient.post( - TraceACall.PATH, + TraceCall.PATH, { query: '' }, this.request.toJSON() ); @@ -32,9 +30,9 @@ class TraceACall implements ThorRequest { }; } - static of(request: PostDebugTracerCallRequestJSON): TraceACall { - return new TraceACall(new PostDebugTracerCallRequest(request)); + static of(request: PostDebugTracerCallRequestJSON): TraceCall { + return new TraceCall(new PostDebugTracerCallRequest(request)); } } -export { TraceACall }; +export { TraceCall }; diff --git a/packages/net/src/thor/debug/TraceTransactionClause.ts b/packages/net/src/thor/debug/TraceTransactionClause.ts new file mode 100644 index 000000000..73e0d6835 --- /dev/null +++ b/packages/net/src/thor/debug/TraceTransactionClause.ts @@ -0,0 +1,40 @@ +import { type ThorRequest } from '../ThorRequest'; +import type { HttpClient, HttpPath } from '../../http'; +import { + PostDebugTracerRequest, + type PostDebugTracerRequestJSON +} from './PostDebugTracerRequest'; +import { type ThorResponse } from '../ThorResponse'; + +class TraceTransactionClause + implements ThorRequest +{ + static readonly PATH: HttpPath = { path: '/debug/tracers' }; + + readonly request: PostDebugTracerRequest; + + constructor(request: PostDebugTracerRequest) { + this.request = request; + } + + async askTo( + httpClient: HttpClient + ): Promise> { + const response = await httpClient.post( + TraceTransactionClause.PATH, + { query: '' }, + this.request.toJSON() + ); + const responseBody: unknown = await response.json(); + return { + request: this, + response: responseBody as undefined + }; + } + + static of(request: PostDebugTracerRequestJSON): TraceTransactionClause { + return new TraceTransactionClause(new PostDebugTracerRequest(request)); + } +} + +export { TraceTransactionClause }; diff --git a/packages/net/src/thor/debug/index.ts b/packages/net/src/thor/debug/index.ts index 4efca7a68..0a03ce0a4 100644 --- a/packages/net/src/thor/debug/index.ts +++ b/packages/net/src/thor/debug/index.ts @@ -1,6 +1,8 @@ export * from './PostDebugTracerCallRequest'; +export * from './PostDebugTracerRequest'; export * from './RetrieveStorageRange'; export * from './StorageRange'; export * from './StorageRangeOption'; -export * from './TraceACall'; +export * from './TraceCall'; export * from './TracerName'; +export * from './TraceTransactionClause'; diff --git a/packages/net/tests/thor/debug/TraceACall.testnet.test.ts b/packages/net/tests/thor/debug/TraceCall.testnet.test.ts similarity index 88% rename from packages/net/tests/thor/debug/TraceACall.testnet.test.ts rename to packages/net/tests/thor/debug/TraceCall.testnet.test.ts index 6e879e159..e06ad9722 100644 --- a/packages/net/tests/thor/debug/TraceACall.testnet.test.ts +++ b/packages/net/tests/thor/debug/TraceCall.testnet.test.ts @@ -1,11 +1,11 @@ import { describe, test } from '@jest/globals'; import { type PostDebugTracerCallRequestJSON, - TraceACall + TraceCall } from '../../../src/thor/debug'; import { FetchHttpClient, ThorNetworks } from '../../../src'; -describe('RetrieveStorageRange testnet tests', () => { +describe('TraceCall testnet tests', () => { test('ok <- askTo', async () => { const request = { value: '0x0', @@ -20,7 +20,7 @@ describe('RetrieveStorageRange testnet tests', () => { blockRef: '0x00000000851caf3c', name: 'call' } satisfies PostDebugTracerCallRequestJSON; - const r = await TraceACall.of(request).askTo( + const r = await TraceCall.of(request).askTo( FetchHttpClient.at(ThorNetworks.TESTNET) ); console.log(JSON.stringify(r, null, 2)); diff --git a/packages/net/tests/thor/debug/TraceTransactionClause.mainnet.test.ts b/packages/net/tests/thor/debug/TraceTransactionClause.mainnet.test.ts new file mode 100644 index 000000000..85daa5aa6 --- /dev/null +++ b/packages/net/tests/thor/debug/TraceTransactionClause.mainnet.test.ts @@ -0,0 +1,20 @@ +import { describe, test } from '@jest/globals'; +import { + type PostDebugTracerRequestJSON, + TraceTransactionClause +} from '../../../src/thor/debug'; +import { FetchHttpClient, ThorNetworks } from '../../../src'; + +describe('TraceTransactionClause mainnet tests', () => { + test('ok <- askTo', async () => { + const request = { + target: '0x010709463c1f0c9aa66a31182fb36d1977d99bfb6526bae0564a0eac4006c31a/0/0', + name: 'call', + config: {} + } satisfies PostDebugTracerRequestJSON; + const r = await TraceTransactionClause.of(request).askTo( + FetchHttpClient.at(ThorNetworks.MAINNET) + ); + console.log(JSON.stringify(r, null, 2)); + }); +}); From 12ecaa4d2870e2cfb78409d163fc5cb42876e9b1 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Sat, 21 Dec 2024 10:16:31 +0100 Subject: [PATCH 54/98] feat: 1484 account clauses in dev... --- docs/diagrams/v2/net/thor/debug/debug.md | 91 ++++++++++++++++++- .../src/thor/accounts/ExecuteCodesRequest.ts | 71 +++++++++++++++ .../src/thor/accounts/ExecuteCodesResponse.ts | 64 +++++++++++++ .../net/src/thor/accounts/InspectClauses.ts | 62 +++++++++++++ packages/net/src/thor/accounts/index.ts | 3 + .../thor/debug/PostDebugTracerCallRequest.ts | 2 +- .../net/src/thor/debug/StorageRangeOption.ts | 2 +- .../accounts/InspectClauses.testnet.test.ts | 42 +++++++++ 8 files changed, 332 insertions(+), 5 deletions(-) create mode 100644 packages/net/src/thor/accounts/ExecuteCodesRequest.ts create mode 100644 packages/net/src/thor/accounts/ExecuteCodesResponse.ts create mode 100644 packages/net/src/thor/accounts/InspectClauses.ts create mode 100644 packages/net/tests/thor/accounts/InspectClauses.testnet.test.ts diff --git a/docs/diagrams/v2/net/thor/debug/debug.md b/docs/diagrams/v2/net/thor/debug/debug.md index 972355d29..28bae1f4d 100644 --- a/docs/diagrams/v2/net/thor/debug/debug.md +++ b/docs/diagrams/v2/net/thor/debug/debug.md @@ -1,15 +1,62 @@ ```mermaid classDiagram + class PostDebugTracerCallRequest { + name?: TracerName + config?: unknown + value: VET + data: HexUInt + to?: Address + gas?: VTHO + gasPrice?: VTHO + caller?: Address + provedWork?: string + gasPayer?: Address + expiration?: UInt + blockRef?: BlockRef + constructor(json: PostDebugTracerCallRequestJSON) + toJSON() PostDebugTracerCallRequestJSON + } + class PostDebugTracerCallRequestJSON { + <> + name?: string + config?: unknown + value: string + data: string + to?: string + gas?: number + gasPrice?: string + caller?: string + provedWork?: string + gasPayer?: string + expiration?: number + blockRef?: string + } + class PostDebugTracerRequest { + name?: TracerName + config?: unknown + target: string + constructor(json PostDebugTracerRequestJSON) + toJSON() PostDebugTracerRequestJSON + } + class PostDebugTracerRequestJSON { + <> + name?: string + config?: unknown + target: string + } class RetrieveStorageRange { - PATH$: HttpPath + PATH: HttpPath$ request: StorageRangeOption + constructor(request: StorageRangeOption) + askTo(httpClient: HttpClient) Promise~ThorResponse~StorageRange~~ + of(request: StorageRangeOptionJSON) RetrieveStorageRange$ } class StorageRange { nextKey?: ThorId storage: unknown - constructor(json: StorageRangeJSON) + constructor(json StorageRangeJSON) toJSON() StorageRangeJSON - } + } class StorageRangeJSON { <> nextKey?: string @@ -30,6 +77,23 @@ classDiagram maxResult?: number target: string } + class TraceCall { + PATH: HttpPath$ + request: PostDebugTracerCallRequest + constructor(request: request: PostDebugTracerCallRequest) + askTo(httpClient: HttpClient) Promise~ThorResponse~undefined~~ + of(request: PostDebugTracerCallRequestJSON): TraceCall$ + } + class TraceTransactionClause { + PATH: HttpPath$ + request: PostDebugTracerRequest + constructor(request: PostDebugTracerRequest) + askTo(httpClient: HttpClient) Promise~ThorResponse~unknown~ + of(request: PostDebugTracerRequestJSON): TraceTransactionClause$ + } + class TracerName { + <> + } namespace thor { class ThorRequest { <> @@ -41,10 +105,31 @@ classDiagram response: ~ResponseClass~; } } + PostDebugTracerCallRequestJSON <-- PostDebugTracerCallRequest + PostDebugTracerRequestJSON <-- PostDebugTracerRequest StorageRange <-- RetrieveStorageRange StorageRangeJSON <-- StorageRange StorageRangeOptionJSON <-- StorageRangeOptions ThorResponse <-- RetrieveStorageRange + ThorResponse <-- TraceCall + ThorResponse <-- TraceTransactionClause ThorRequest <|.. RetrieveStorageRange + ThorRequest <|.. TraceCall + ThorRequest <|.. TraceTransactionClause + TracerName <|-- StructLogger + TracerName <|-- FourByte + TracerNname <|-- Call + TracerName <|-- Noop + TracerName <|-- Prestate + TracerName <|-- Unigram + TracerName <|-- Bigram + TracerName <|-- Trigram + TracerName <|-- EvmDis + TracerName <|-- OpCount + TracerName <|-- Null RetrieveStorageRange --* StorageRangeOptions + PostDebugTracerCallRequest --* TracerName + PostDebugTracerRequest --* TracerName + TraceCall --* PostDebugTracerCallRequest + TraceTransactionClause --* PostDebugTracerRequest ``` diff --git a/packages/net/src/thor/accounts/ExecuteCodesRequest.ts b/packages/net/src/thor/accounts/ExecuteCodesRequest.ts new file mode 100644 index 000000000..d9a66005e --- /dev/null +++ b/packages/net/src/thor/accounts/ExecuteCodesRequest.ts @@ -0,0 +1,71 @@ +import { Clause, type ClauseJSON } from '../transactions'; +import { UInt } from '../../../../core/src'; +import { Address, BlockRef, Units, VTHO } from '@vechain/sdk-core'; + +class ExecuteCodesRequest { + readonly provedWork?: string; + readonly gasPayer?: Address; + expiration?: UInt; + blockRef?: BlockRef; + clauses?: Clause[]; + gas?: VTHO; + gasPrice?: VTHO; + caller?: Address; + + constructor(json: ExecuteCodesRequestJSON) { + this.provedWork = json.provedWork; + this.gasPayer = + json.gasPayer === undefined ? undefined : Address.of(json.gasPayer); + this.expiration = + json.expiration === undefined + ? undefined + : UInt.of(json.expiration); + this.blockRef = + json.blockRef === undefined + ? undefined + : BlockRef.of(json.blockRef); + this.clauses = + json.clauses === undefined + ? undefined + : json.clauses.map( + (clauseJSON: ClauseJSON): Clause => new Clause(clauseJSON) + ); + this.gas = + json.gas === undefined ? undefined : VTHO.of(json.gas, Units.wei); + this.gasPrice = + json.gasPrice === undefined + ? undefined + : VTHO.of(json.gasPrice, Units.wei); + this.caller = + json.caller === undefined ? undefined : Address.of(json.caller); + } + + toJSON(): ExecuteCodesRequestJSON { + return { + provedWork: this.provedWork, + gasPayer: this.gasPayer?.toString(), + expiration: this.expiration?.valueOf(), + blockRef: this.blockRef?.toString(), + clauses: this.clauses?.map((clause: Clause) => clause.toJSON()), + gas: this.gas === undefined ? undefined : Number(this.gas.wei), + gasPrice: + this.gasPrice === undefined + ? undefined + : this.gasPrice.wei.toString(), + caller: this.caller?.toString() + } satisfies ExecuteCodesRequestJSON; + } +} + +class ExecuteCodesRequestJSON { + provedWork?: string; + gasPayer?: string; + expiration?: number; + blockRef?: string; + clauses?: ClauseJSON[]; + gas?: number; + gasPrice?: string; + caller?: string; +} + +export { ExecuteCodesRequest, type ExecuteCodesRequestJSON }; diff --git a/packages/net/src/thor/accounts/ExecuteCodesResponse.ts b/packages/net/src/thor/accounts/ExecuteCodesResponse.ts new file mode 100644 index 000000000..eb522fc5d --- /dev/null +++ b/packages/net/src/thor/accounts/ExecuteCodesResponse.ts @@ -0,0 +1,64 @@ +import { + Event, + type EventJSON, + Transfer, + type TransferJSON +} from '../transactions'; +import { HexUInt, VTHO } from '@vechain/sdk-core'; + +class ExecuteCodeResponse { + readonly data: HexUInt; + readonly events: Event[]; + readonly transfers: Transfer[]; + readonly gasUsed: VTHO; + readonly reverted: boolean; + readonly vmError: string; + + constructor(json: ExecuteCodeResponseJSON) { + this.data = HexUInt.of(json.data); + this.events = json.events.map( + (eventJSON: EventJSON): Event => new Event(eventJSON) + ); + this.transfers = json.transfers.map( + (transferJSON: TransferJSON): Transfer => new Transfer(transferJSON) + ); + this.gasUsed = VTHO.of(json.gasUsed); + this.reverted = json.reverted; + this.vmError = json.vmError; + } + + toJSON(): ExecuteCodeResponseJSON { + return { + data: this.data.toString(), + events: this.events.map( + (event: Event): EventJSON => event.toJSON() + ), + transfers: this.transfers.map( + (transfer: Transfer): TransferJSON => transfer.toJSON() + ), + gasUsed: Number(this.gasUsed.wei), + reverted: this.reverted, + vmError: this.vmError + } satisfies ExecuteCodeResponseJSON; + } +} + +class ExecuteCodesResponse extends Array {} + +interface ExecuteCodeResponseJSON { + data: string; + events: EventJSON[]; + transfers: TransferJSON[]; + gasUsed: number; + reverted: boolean; + vmError: string; +} + +interface ExecuteCodesResponseJSON extends Array {} + +export { + ExecuteCodeResponse, + ExecuteCodesResponse, + type ExecuteCodeResponseJSON, + type ExecuteCodesResponseJSON +}; diff --git a/packages/net/src/thor/accounts/InspectClauses.ts b/packages/net/src/thor/accounts/InspectClauses.ts new file mode 100644 index 000000000..9d26e2c66 --- /dev/null +++ b/packages/net/src/thor/accounts/InspectClauses.ts @@ -0,0 +1,62 @@ +import { + ExecuteCodeResponse, + type ExecuteCodeResponseJSON, + type ExecuteCodesResponse, + type ExecuteCodesResponseJSON +} from './ExecuteCodesResponse'; +import { type ThorRequest } from '../ThorRequest'; +import { type HttpClient, type HttpPath } from '../../http'; +import { type ThorResponse } from '../ThorResponse'; +import { + ExecuteCodesRequest, + type ExecuteCodesRequestJSON +} from './ExecuteCodesRequest'; + +class InspectClauses + implements ThorRequest +{ + static readonly PATH: HttpPath = { path: '/accounts/*' }; + + readonly request: ExecuteCodesRequest; + + constructor(request: ExecuteCodesRequest) { + this.request = request; + } + + async askTo( + httpClient: HttpClient + ): Promise> { + const response = await httpClient.post( + InspectClauses.PATH, + { query: '' }, + this.request.toJSON() + ); + const responseBody = + (await response.json()) as ExecuteCodesResponseJSON; + return { + request: this, + response: responseBody.map( + (json: ExecuteCodeResponseJSON): ExecuteCodeResponse => + new ExecuteCodeResponse(json) + ) + }; + } + + static of(request: ExecuteCodesRequestJSON): InspectClauses { + return new InspectClauses(new ExecuteCodesRequest(request)); + } +} + +// class InspectClauseQuery implements HttpQuery { +// readonly revision: Revision; +// +// constructor(revision: Revision) { +// this.revision = revision; +// } +// +// get query(): string { +// return `\`?${this.revision}`; +// } +// } + +export { InspectClauses }; diff --git a/packages/net/src/thor/accounts/index.ts b/packages/net/src/thor/accounts/index.ts index 47cb6480c..8aa27ad35 100644 --- a/packages/net/src/thor/accounts/index.ts +++ b/packages/net/src/thor/accounts/index.ts @@ -1,5 +1,8 @@ export * from './ContractBytecode'; +export * from './ExecuteCodesRequest'; +export * from './ExecuteCodesResponse'; export * from './GetAccountResponse'; +export * from './InspectClauses'; export * from './RetrieveAccountDetails'; export * from './RetrieveContractBytecode'; export * from './RetrieveStoragePositionValue'; diff --git a/packages/net/src/thor/debug/PostDebugTracerCallRequest.ts b/packages/net/src/thor/debug/PostDebugTracerCallRequest.ts index c531eaa71..70663df62 100644 --- a/packages/net/src/thor/debug/PostDebugTracerCallRequest.ts +++ b/packages/net/src/thor/debug/PostDebugTracerCallRequest.ts @@ -7,7 +7,7 @@ import { VET, VTHO } from '@vechain/sdk-core'; -import { UInt } from '../../../../core'; +import { UInt } from '../../../../core/src'; class PostDebugTracerCallRequest { readonly name?: TracerName; diff --git a/packages/net/src/thor/debug/StorageRangeOption.ts b/packages/net/src/thor/debug/StorageRangeOption.ts index 6416242d2..e521daedf 100644 --- a/packages/net/src/thor/debug/StorageRangeOption.ts +++ b/packages/net/src/thor/debug/StorageRangeOption.ts @@ -1,5 +1,5 @@ import { Address, ThorId } from '@vechain/sdk-core'; -import { UInt } from '../../../../core'; +import { UInt } from '../../../../core/src'; class StorageRangeOption { readonly address: Address; diff --git a/packages/net/tests/thor/accounts/InspectClauses.testnet.test.ts b/packages/net/tests/thor/accounts/InspectClauses.testnet.test.ts new file mode 100644 index 000000000..193f7481c --- /dev/null +++ b/packages/net/tests/thor/accounts/InspectClauses.testnet.test.ts @@ -0,0 +1,42 @@ +import { describe, test } from '@jest/globals'; +import { + type ExecuteCodesRequestJSON, + FetchHttpClient, + InspectClauses, + ThorNetworks +} from '../../../src'; + +describe('InspectClauses testnet tests', () => { + test('ok <- askTo', async () => { + const request = { + gas: 50000, + gasPrice: '1000000000000000', + caller: '0x6d95e6dca01d109882fe1726a2fb9865fa41e7aa', + provedWork: '1000', + gasPayer: '0xd3ae78222beadb038203be21ed5ce7c9b1bff602', + expiration: 1000, + blockRef: '0x00000000851caf3c', + clauses: [ + { + to: '0x0000000000000000000000000000456E65726779', + value: '0x0', + data: '0xa9059cbb0000000000000000000000000f872421dc479f3c11edd89512731814d0598db50000000000000000000000000000000000000000000000013f306a2409fc0000' + }, + { + to: '0xf077b491b355E64048cE21E3A6Fc4751eEeA77fa', + value: '0x6124fee993bc00000', + data: '0x' + }, + { + to: null, + value: '0x0', + data: '0x6080604052348015600f57600080fd5b50609f8061001e6000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680631820cabb146044575b600080fd5b348015604f57600080fd5b506056606c565b6040518082815260200191505060405180910390f35b62015180815600a165627a7a723058200ac7475da248e2fc26c057319e296e90c24d5f8b9bf956fb3b77545642cad3b10029' + } + ] + } satisfies ExecuteCodesRequestJSON; + const r = await InspectClauses.of(request).askTo( + FetchHttpClient.at(ThorNetworks.TESTNET) + ); + console.log(JSON.stringify(r, null, 2)); + }); +}); From 20fba38baebf63d5e045efe434a6d03667312033 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Sat, 21 Dec 2024 10:27:44 +0100 Subject: [PATCH 55/98] feat: 1484 account clauses prototype --- .../net/src/thor/accounts/InspectClauses.ts | 44 ++++++++++++------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/packages/net/src/thor/accounts/InspectClauses.ts b/packages/net/src/thor/accounts/InspectClauses.ts index 9d26e2c66..cd60e4aed 100644 --- a/packages/net/src/thor/accounts/InspectClauses.ts +++ b/packages/net/src/thor/accounts/InspectClauses.ts @@ -5,21 +5,25 @@ import { type ExecuteCodesResponseJSON } from './ExecuteCodesResponse'; import { type ThorRequest } from '../ThorRequest'; -import { type HttpClient, type HttpPath } from '../../http'; +import { type HttpClient, type HttpPath, type HttpQuery } from '../../http'; import { type ThorResponse } from '../ThorResponse'; import { ExecuteCodesRequest, type ExecuteCodesRequestJSON } from './ExecuteCodesRequest'; +import { Revision } from '@vechain/sdk-core'; class InspectClauses implements ThorRequest { static readonly PATH: HttpPath = { path: '/accounts/*' }; + readonly query: InspectClauseQuery; + readonly request: ExecuteCodesRequest; - constructor(request: ExecuteCodesRequest) { + constructor(query: InspectClauseQuery, request: ExecuteCodesRequest) { + this.query = query; this.request = request; } @@ -28,7 +32,7 @@ class InspectClauses ): Promise> { const response = await httpClient.post( InspectClauses.PATH, - { query: '' }, + this.query, this.request.toJSON() ); const responseBody = @@ -42,21 +46,31 @@ class InspectClauses }; } + withRevision(revision: Revision = Revision.BEST): InspectClauses { + return new InspectClauses( + new InspectClauseQuery(revision), + this.request + ); + } + static of(request: ExecuteCodesRequestJSON): InspectClauses { - return new InspectClauses(new ExecuteCodesRequest(request)); + return new InspectClauses( + new InspectClauseQuery(Revision.BEST), + new ExecuteCodesRequest(request) + ); } } -// class InspectClauseQuery implements HttpQuery { -// readonly revision: Revision; -// -// constructor(revision: Revision) { -// this.revision = revision; -// } -// -// get query(): string { -// return `\`?${this.revision}`; -// } -// } +class InspectClauseQuery implements HttpQuery { + readonly revision: Revision; + + constructor(revision: Revision) { + this.revision = revision; + } + + get query(): string { + return `?revision=${this.revision}`; + } +} export { InspectClauses }; From c5289797a5ad2f395bc5be954611cfa60a16adb3 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 24 Dec 2024 13:04:00 +0100 Subject: [PATCH 56/98] feat: 1484 ws in dev... --- packages/net/src/ws/BlocksSubscription.ts | 21 ++++++++++++ packages/net/src/ws/MozillaWebSocketClient.ts | 32 +++++++++++++++++++ packages/net/src/ws/WebSocketClient.ts | 24 ++++++++++++++ packages/net/src/ws/WebSocketListener.ts | 5 +++ packages/net/src/ws/index.ts | 3 ++ .../ws/MozillaWebSocketClient.solo.test.ts | 24 ++++++++++++++ packages/net/tests/ws/ws.testnet.test.ts | 19 +++++++++++ 7 files changed, 128 insertions(+) create mode 100644 packages/net/src/ws/BlocksSubscription.ts create mode 100644 packages/net/src/ws/MozillaWebSocketClient.ts create mode 100644 packages/net/src/ws/WebSocketClient.ts create mode 100644 packages/net/src/ws/WebSocketListener.ts create mode 100644 packages/net/src/ws/index.ts create mode 100644 packages/net/tests/ws/MozillaWebSocketClient.solo.test.ts create mode 100644 packages/net/tests/ws/ws.testnet.test.ts diff --git a/packages/net/src/ws/BlocksSubscription.ts b/packages/net/src/ws/BlocksSubscription.ts new file mode 100644 index 000000000..c465ce436 --- /dev/null +++ b/packages/net/src/ws/BlocksSubscription.ts @@ -0,0 +1,21 @@ +import { type HttpPath } from '../http'; + +class BlocksSubscription { + static readonly PATH: HttpPath = { path: '/subscriptions/block' }; + + readonly baseURL: string; + + constructor(baseURL: string) { + this.baseURL = baseURL; + } + + close(): this { + return this; + } + + open(): this { + return this; + } +} + +export { BlocksSubscription }; diff --git a/packages/net/src/ws/MozillaWebSocketClient.ts b/packages/net/src/ws/MozillaWebSocketClient.ts new file mode 100644 index 000000000..b13c2b98c --- /dev/null +++ b/packages/net/src/ws/MozillaWebSocketClient.ts @@ -0,0 +1,32 @@ +import { type WebSocketClient } from './WebSocketClient'; +import { type WebSocketListener } from './WebSocketListener'; + +class MozillaWebSocketClient implements WebSocketClient { + private ws?: WebSocket; + + private readonly messageListeners: Array> = []; + + addMessageListener(listener: WebSocketListener): this { + this.messageListeners.push(listener); + return this; + } + + close(): WebSocketClient { + this.ws?.close(); + this.ws = undefined; + return this; + } + + open(url: string): WebSocketClient { + this.close(); + this.ws = new WebSocket(url); + this.ws.onmessage = (event: MessageEvent) => { + this.messageListeners.forEach((listener) => { + listener.onMessage(event); + }); + }; + return this; + } +} + +export { MozillaWebSocketClient }; diff --git a/packages/net/src/ws/WebSocketClient.ts b/packages/net/src/ws/WebSocketClient.ts new file mode 100644 index 000000000..ad627aee7 --- /dev/null +++ b/packages/net/src/ws/WebSocketClient.ts @@ -0,0 +1,24 @@ +interface WebSocketClient { + open: (url: string) => WebSocketClient; + + close: () => WebSocketClient; +} + +export { type WebSocketClient }; + +/* + +WebSocketListener { + onMessage +} + + BlockSubscription{ + PATH + open() + addListener() + removeListener() + close() + } + + + */ diff --git a/packages/net/src/ws/WebSocketListener.ts b/packages/net/src/ws/WebSocketListener.ts new file mode 100644 index 000000000..a32dc6de1 --- /dev/null +++ b/packages/net/src/ws/WebSocketListener.ts @@ -0,0 +1,5 @@ +interface WebSocketListener { + onMessage: (event: MessageEvent) => void; +} + +export type { WebSocketListener }; diff --git a/packages/net/src/ws/index.ts b/packages/net/src/ws/index.ts new file mode 100644 index 000000000..2f3415242 --- /dev/null +++ b/packages/net/src/ws/index.ts @@ -0,0 +1,3 @@ +export * from './MozillaWebSocketClient'; +export * from './WebSocketClient'; +export * from './WebSocketListener'; diff --git a/packages/net/tests/ws/MozillaWebSocketClient.solo.test.ts b/packages/net/tests/ws/MozillaWebSocketClient.solo.test.ts new file mode 100644 index 000000000..1fe3a69ae --- /dev/null +++ b/packages/net/tests/ws/MozillaWebSocketClient.solo.test.ts @@ -0,0 +1,24 @@ +import { afterEach, beforeEach, describe } from '@jest/globals'; +import { MozillaWebSocketClient } from '../../src/ws/MozillaWebSocketClient'; +import { type WebSocketListener } from '../../src/ws'; + +describe('FetchHttpClient testnet tests', () => { + let wsc: MozillaWebSocketClient; + beforeEach(() => { + wsc = new MozillaWebSocketClient(); + }); + + test('should connect to WebSocket and receive data', (done) => { + wsc.open('ws://localhost:8669/subscriptions/beat2'); + wsc.addMessageListener({ + onMessage: (message) => { + console.log(message.data); + done(); + } + } satisfies WebSocketListener); + }, 30000); + + afterEach(() => { + wsc.close(); + }); +}); diff --git a/packages/net/tests/ws/ws.testnet.test.ts b/packages/net/tests/ws/ws.testnet.test.ts new file mode 100644 index 000000000..dfe6cdd81 --- /dev/null +++ b/packages/net/tests/ws/ws.testnet.test.ts @@ -0,0 +1,19 @@ +import { afterEach, beforeEach, describe } from '@jest/globals'; + +describe('FetchHttpClient testnet tests', () => { + let ws: WebSocket; + beforeEach(() => { + ws = new WebSocket('ws://localhost:8669/subscriptions/beat2'); + }); + + test('should connect to WebSocket and receive data', (done) => { + ws.onmessage = (event) => { + console.log(event); + done(); // Call 'done' when the test is complete. + }; + }, 30000); + + afterEach(() => { + ws.close(); + }); +}); From 13c98d853079562e50d8aa512556dc11e9780c8c Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 24 Dec 2024 19:45:21 +0100 Subject: [PATCH 57/98] feat: 1484 ws in dev... --- .../thor/subscriptions/BlocksSubscription.ts | 43 +++++++++++++++++++ packages/net/src/thor/subscriptions/index.ts | 1 + packages/net/src/ws/BlocksSubscription.ts | 21 --------- packages/net/src/ws/MozillaWebSocketClient.ts | 13 ++++-- packages/net/src/ws/WebSocketClient.ts | 28 +++++------- .../BlocksSubscription.solo.test.ts | 32 ++++++++++++++ .../ws/MozillaWebSocketClient.solo.test.ts | 11 ++--- packages/net/tests/ws/ws.testnet.test.ts | 19 -------- 8 files changed, 102 insertions(+), 66 deletions(-) create mode 100644 packages/net/src/thor/subscriptions/BlocksSubscription.ts create mode 100644 packages/net/src/thor/subscriptions/index.ts delete mode 100644 packages/net/src/ws/BlocksSubscription.ts create mode 100644 packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts delete mode 100644 packages/net/tests/ws/ws.testnet.test.ts diff --git a/packages/net/src/thor/subscriptions/BlocksSubscription.ts b/packages/net/src/thor/subscriptions/BlocksSubscription.ts new file mode 100644 index 000000000..c66dcc7d5 --- /dev/null +++ b/packages/net/src/thor/subscriptions/BlocksSubscription.ts @@ -0,0 +1,43 @@ +import { type HttpPath } from '../../http'; +import { type WebSocketClient, type WebSocketListener } from '../../ws'; + +class BlocksSubscription + implements WebSocketClient, WebSocketListener +{ + static readonly PATH: HttpPath = { path: '/subscriptions/block' }; + + private readonly messageListeners: Array> = []; + + private readonly wsc: WebSocketClient; + + constructor(wsc: WebSocketClient) { + this.wsc = wsc; + } + + addMessageListener(listener: WebSocketListener): this { + this.messageListeners.push(listener); + return this; + } + + get baseURL(): string { + return this.wsc.baseURL; + } + + close(): this { + this.wsc.close(); + return this; + } + + onMessage(event: MessageEvent): void { + this.messageListeners.forEach((listener) => { + listener.onMessage(event); + }); + } + + open(path: HttpPath = BlocksSubscription.PATH): this { + this.wsc.addMessageListener(this).open(path); + return this; + } +} + +export { BlocksSubscription }; diff --git a/packages/net/src/thor/subscriptions/index.ts b/packages/net/src/thor/subscriptions/index.ts new file mode 100644 index 000000000..ad0701c5d --- /dev/null +++ b/packages/net/src/thor/subscriptions/index.ts @@ -0,0 +1 @@ +export * from './BlocksSubscription'; diff --git a/packages/net/src/ws/BlocksSubscription.ts b/packages/net/src/ws/BlocksSubscription.ts deleted file mode 100644 index c465ce436..000000000 --- a/packages/net/src/ws/BlocksSubscription.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { type HttpPath } from '../http'; - -class BlocksSubscription { - static readonly PATH: HttpPath = { path: '/subscriptions/block' }; - - readonly baseURL: string; - - constructor(baseURL: string) { - this.baseURL = baseURL; - } - - close(): this { - return this; - } - - open(): this { - return this; - } -} - -export { BlocksSubscription }; diff --git a/packages/net/src/ws/MozillaWebSocketClient.ts b/packages/net/src/ws/MozillaWebSocketClient.ts index b13c2b98c..5b2fa74dd 100644 --- a/packages/net/src/ws/MozillaWebSocketClient.ts +++ b/packages/net/src/ws/MozillaWebSocketClient.ts @@ -1,25 +1,32 @@ import { type WebSocketClient } from './WebSocketClient'; import { type WebSocketListener } from './WebSocketListener'; +import { type HttpPath } from '../http'; class MozillaWebSocketClient implements WebSocketClient { + readonly baseURL: string; + private ws?: WebSocket; private readonly messageListeners: Array> = []; + constructor(baseURL: string) { + this.baseURL = baseURL; + } + addMessageListener(listener: WebSocketListener): this { this.messageListeners.push(listener); return this; } - close(): WebSocketClient { + close(): this { this.ws?.close(); this.ws = undefined; return this; } - open(url: string): WebSocketClient { + open(path: HttpPath): this { this.close(); - this.ws = new WebSocket(url); + this.ws = new WebSocket(this.baseURL + path.path); this.ws.onmessage = (event: MessageEvent) => { this.messageListeners.forEach((listener) => { listener.onMessage(event); diff --git a/packages/net/src/ws/WebSocketClient.ts b/packages/net/src/ws/WebSocketClient.ts index ad627aee7..492acff6e 100644 --- a/packages/net/src/ws/WebSocketClient.ts +++ b/packages/net/src/ws/WebSocketClient.ts @@ -1,24 +1,16 @@ -interface WebSocketClient { - open: (url: string) => WebSocketClient; +import type { WebSocketListener } from './WebSocketListener'; +import { type HttpPath } from '../http'; - close: () => WebSocketClient; -} +interface WebSocketClient { + addMessageListener: ( + listener: WebSocketListener + ) => WebSocketClient; -export { type WebSocketClient }; + get baseURL(): string; -/* + close: () => WebSocketClient; -WebSocketListener { - onMessage + open: (path: HttpPath) => WebSocketClient; } - BlockSubscription{ - PATH - open() - addListener() - removeListener() - close() - } - - - */ +export { type WebSocketClient }; diff --git a/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts b/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts new file mode 100644 index 000000000..08798673c --- /dev/null +++ b/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts @@ -0,0 +1,32 @@ +import { afterEach, beforeEach, describe } from '@jest/globals'; +import { + MozillaWebSocketClient, + type WebSocketListener +} from '../../../src/ws'; +import { BlocksSubscription } from '../../../src/thor/subscriptions'; + +describe('BlocksSubscription solo tests', () => { + let subscription: BlocksSubscription; + beforeEach(() => { + subscription = new BlocksSubscription( + new MozillaWebSocketClient('ws://localhost:8669') + ); + }); + + test('data <- open', (done) => { + subscription + .addMessageListener({ + onMessage: (message) => { + console.log(message.data); + done(); + } + } satisfies WebSocketListener) + .open({ + path: '/subscriptions/beat2' + }); + }, 30000); + + afterEach(() => { + subscription.close(); + }); +}); diff --git a/packages/net/tests/ws/MozillaWebSocketClient.solo.test.ts b/packages/net/tests/ws/MozillaWebSocketClient.solo.test.ts index 1fe3a69ae..47ceeb4d5 100644 --- a/packages/net/tests/ws/MozillaWebSocketClient.solo.test.ts +++ b/packages/net/tests/ws/MozillaWebSocketClient.solo.test.ts @@ -2,20 +2,21 @@ import { afterEach, beforeEach, describe } from '@jest/globals'; import { MozillaWebSocketClient } from '../../src/ws/MozillaWebSocketClient'; import { type WebSocketListener } from '../../src/ws'; -describe('FetchHttpClient testnet tests', () => { +describe('MozillaWebSocketClient solo tests', () => { let wsc: MozillaWebSocketClient; beforeEach(() => { - wsc = new MozillaWebSocketClient(); + wsc = new MozillaWebSocketClient('ws://localhost:8669'); }); - test('should connect to WebSocket and receive data', (done) => { - wsc.open('ws://localhost:8669/subscriptions/beat2'); + test('data <- open', (done) => { wsc.addMessageListener({ onMessage: (message) => { console.log(message.data); done(); } - } satisfies WebSocketListener); + } satisfies WebSocketListener).open({ + path: '/subscriptions/beat2' + }); }, 30000); afterEach(() => { diff --git a/packages/net/tests/ws/ws.testnet.test.ts b/packages/net/tests/ws/ws.testnet.test.ts deleted file mode 100644 index dfe6cdd81..000000000 --- a/packages/net/tests/ws/ws.testnet.test.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { afterEach, beforeEach, describe } from '@jest/globals'; - -describe('FetchHttpClient testnet tests', () => { - let ws: WebSocket; - beforeEach(() => { - ws = new WebSocket('ws://localhost:8669/subscriptions/beat2'); - }); - - test('should connect to WebSocket and receive data', (done) => { - ws.onmessage = (event) => { - console.log(event); - done(); // Call 'done' when the test is complete. - }; - }, 30000); - - afterEach(() => { - ws.close(); - }); -}); From b32cca18554402419919fb64808fecb1b97aa135 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 24 Dec 2024 20:26:21 +0100 Subject: [PATCH 58/98] feat: 1484 ws in dev... --- .../SubscriptionBlockResponse.ts | 90 +++++++++++++++++++ packages/net/src/thor/subscriptions/index.ts | 1 + .../BlocksSubscription.solo.test.ts | 4 +- 3 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 packages/net/src/thor/subscriptions/SubscriptionBlockResponse.ts diff --git a/packages/net/src/thor/subscriptions/SubscriptionBlockResponse.ts b/packages/net/src/thor/subscriptions/SubscriptionBlockResponse.ts new file mode 100644 index 000000000..a72bf3278 --- /dev/null +++ b/packages/net/src/thor/subscriptions/SubscriptionBlockResponse.ts @@ -0,0 +1,90 @@ +import { UInt, type TxId } from '../../../../core'; +import { Address, BlockId, ThorId, Units, VTHO } from '@vechain/sdk-core'; + +class SubscriptionBlockResponse { + readonly number: UInt; + readonly id: BlockId; + readonly size: UInt; + readonly parentID: BlockId; + readonly timestamp: UInt; + readonly gasLimit: VTHO; + readonly beneficiary: Address; + readonly gasUsed: VTHO; + readonly totalScore: UInt; + readonly txsRoot: ThorId; + readonly txsFeatures: UInt; + readonly stateRoot: ThorId; + readonly receiptsRoot: ThorId; + readonly com: boolean; + readonly signer: Address; + readonly obsolete: boolean; + readonly transactions: TxId[]; + + constructor(json: SubscriptionBlockResponseJSON) { + this.number = UInt.of(json.number); + this.id = BlockId.of(json.id); + this.size = UInt.of(json.size); + this.parentID = BlockId.of(json.parentID); + this.timestamp = UInt.of(json.timestamp); + this.gasLimit = VTHO.of(json.gasLimit, Units.wei); + this.beneficiary = Address.of(json.beneficiary); + this.gasUsed = VTHO.of(json.gasUsed, Units.wei); + this.totalScore = UInt.of(json.totalScore); + this.txsRoot = ThorId.of(json.txsRoot); + this.txsFeatures = UInt.of(json.txsFeatures); + this.stateRoot = ThorId.of(json.stateRoot); + this.receiptsRoot = ThorId.of(json.receiptsRoot); + this.com = json.com; + this.signer = Address.of(json.signer); + this.obsolete = json.obsolete; + this.transactions = json.transactions.map( + (txId: string): TxId => ThorId.of(txId) + ); + } + + toJSON(): SubscriptionBlockResponseJSON { + return { + number: this.number.valueOf(), + id: this.id.toString(), + size: this.size.valueOf(), + parentID: this.parentID.toString(), + timestamp: this.timestamp.valueOf(), + gasLimit: Number(this.gasLimit.wei), + beneficiary: this.beneficiary.toString(), + gasUsed: Number(this.gasUsed.wei), + totalScore: this.totalScore.valueOf(), + txsRoot: this.txsRoot.toString(), + txsFeatures: this.txsFeatures.valueOf(), + stateRoot: this.stateRoot.toString(), + receiptsRoot: this.receiptsRoot.toString(), + com: this.com, + signer: this.signer.toString(), + obsolete: this.obsolete, + transactions: this.transactions.map((txId: ThorId) => + txId.toString() + ) + } satisfies SubscriptionBlockResponseJSON; + } +} + +interface SubscriptionBlockResponseJSON { + number: number; + id: string; + size: number; + parentID: string; + timestamp: number; + gasLimit: number; + beneficiary: string; + gasUsed: number; + totalScore: number; + txsRoot: string; + txsFeatures: number; + stateRoot: string; + receiptsRoot: string; + com: boolean; + signer: string; + obsolete: boolean; + transactions: string[]; +} + +export { SubscriptionBlockResponse, type SubscriptionBlockResponseJSON }; diff --git a/packages/net/src/thor/subscriptions/index.ts b/packages/net/src/thor/subscriptions/index.ts index ad0701c5d..5f76cb49f 100644 --- a/packages/net/src/thor/subscriptions/index.ts +++ b/packages/net/src/thor/subscriptions/index.ts @@ -1 +1,2 @@ export * from './BlocksSubscription'; +export * from './SubscriptionBlockResponse'; diff --git a/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts b/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts index 08798673c..d3cb8b4b9 100644 --- a/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts +++ b/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts @@ -21,9 +21,7 @@ describe('BlocksSubscription solo tests', () => { done(); } } satisfies WebSocketListener) - .open({ - path: '/subscriptions/beat2' - }); + .open(); }, 30000); afterEach(() => { From a45098e99b2f08a564da567f94260498cb61f497 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 24 Dec 2024 22:46:46 +0100 Subject: [PATCH 59/98] feat: 1484 subscriptions in dev... --- .../thor/subscriptions/BlocksSubscription.ts | 21 ++++++++++++++++--- .../BlocksSubscription.solo.test.ts | 8 +++++-- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/packages/net/src/thor/subscriptions/BlocksSubscription.ts b/packages/net/src/thor/subscriptions/BlocksSubscription.ts index c66dcc7d5..0e75164fb 100644 --- a/packages/net/src/thor/subscriptions/BlocksSubscription.ts +++ b/packages/net/src/thor/subscriptions/BlocksSubscription.ts @@ -1,12 +1,18 @@ import { type HttpPath } from '../../http'; import { type WebSocketClient, type WebSocketListener } from '../../ws'; +import { + SubscriptionBlockResponse, + type SubscriptionBlockResponseJSON +} from './SubscriptionBlockResponse'; class BlocksSubscription implements WebSocketClient, WebSocketListener { static readonly PATH: HttpPath = { path: '/subscriptions/block' }; - private readonly messageListeners: Array> = []; + private readonly messageListeners: Array< + WebSocketListener + > = []; private readonly wsc: WebSocketClient; @@ -14,7 +20,9 @@ class BlocksSubscription this.wsc = wsc; } - addMessageListener(listener: WebSocketListener): this { + addMessageListener( + listener: WebSocketListener + ): this { this.messageListeners.push(listener); return this; } @@ -29,8 +37,15 @@ class BlocksSubscription } onMessage(event: MessageEvent): void { + const json = JSON.parse( + event.data as string + ) as SubscriptionBlockResponseJSON; + const message = new MessageEvent( + event.type, + { data: new SubscriptionBlockResponse(json) } + ); this.messageListeners.forEach((listener) => { - listener.onMessage(event); + listener.onMessage(message); }); } diff --git a/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts b/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts index d3cb8b4b9..d0046ee37 100644 --- a/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts +++ b/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts @@ -3,7 +3,10 @@ import { MozillaWebSocketClient, type WebSocketListener } from '../../../src/ws'; -import { BlocksSubscription } from '../../../src/thor/subscriptions'; +import { + BlocksSubscription, + type SubscriptionBlockResponseJSON +} from '../../../src/thor/subscriptions'; describe('BlocksSubscription solo tests', () => { let subscription: BlocksSubscription; @@ -17,7 +20,8 @@ describe('BlocksSubscription solo tests', () => { subscription .addMessageListener({ onMessage: (message) => { - console.log(message.data); + const data = message.data as SubscriptionBlockResponseJSON; + console.log(JSON.stringify(data, null, 2)); done(); } } satisfies WebSocketListener) From 7342e45808183249b8b507f666d1546b5d368c4a Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 24 Dec 2024 23:23:30 +0100 Subject: [PATCH 60/98] feat: 1484 subscriptions in dev... --- .../thor/subscriptions/BlocksSubscription.ts | 31 +++++++++++++++++-- .../BlocksSubscription.solo.test.ts | 2 +- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/packages/net/src/thor/subscriptions/BlocksSubscription.ts b/packages/net/src/thor/subscriptions/BlocksSubscription.ts index 0e75164fb..a5228dab7 100644 --- a/packages/net/src/thor/subscriptions/BlocksSubscription.ts +++ b/packages/net/src/thor/subscriptions/BlocksSubscription.ts @@ -1,9 +1,10 @@ -import { type HttpPath } from '../../http'; +import { type HttpPath, type HttpQuery } from '../../http'; import { type WebSocketClient, type WebSocketListener } from '../../ws'; import { SubscriptionBlockResponse, type SubscriptionBlockResponseJSON } from './SubscriptionBlockResponse'; +import { type BlockId } from '@vechain/sdk-core'; class BlocksSubscription implements WebSocketClient, WebSocketListener @@ -14,10 +15,13 @@ class BlocksSubscription WebSocketListener > = []; + private readonly query: BlockSubscriptionQuery; + private readonly wsc: WebSocketClient; - constructor(wsc: WebSocketClient) { + protected constructor(wsc: WebSocketClient, query: BlockSubscriptionQuery) { this.wsc = wsc; + this.query = query; } addMessageListener( @@ -27,6 +31,17 @@ class BlocksSubscription return this; } + static at(wsc: WebSocketClient): BlocksSubscription { + return new BlocksSubscription(wsc, new BlockSubscriptionQuery()); + } + + atPos(pos: BlockId): BlocksSubscription { + return new BlocksSubscription( + this.wsc, + new BlockSubscriptionQuery(pos) + ); + } + get baseURL(): string { return this.wsc.baseURL; } @@ -55,4 +70,16 @@ class BlocksSubscription } } +class BlockSubscriptionQuery implements HttpQuery { + readonly pos?: BlockId; + + constructor(pos?: BlockId) { + this.pos = pos; + } + + get query(): string { + return this.pos === undefined ? '' : `?pos=${this.pos}`; + } +} + export { BlocksSubscription }; diff --git a/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts b/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts index d0046ee37..fe5c9e4c9 100644 --- a/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts +++ b/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts @@ -11,7 +11,7 @@ import { describe('BlocksSubscription solo tests', () => { let subscription: BlocksSubscription; beforeEach(() => { - subscription = new BlocksSubscription( + subscription = BlocksSubscription.at( new MozillaWebSocketClient('ws://localhost:8669') ); }); From 88faf21dd760b8826c3612b1ca9a254f7ab0e8e1 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 24 Dec 2024 23:54:56 +0100 Subject: [PATCH 61/98] feat: 1484 subscriptions in dev... --- .../thor/subscriptions/BeatsSubscription.ts | 0 .../SubscriptionBeat2Response.ts | 40 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 packages/net/src/thor/subscriptions/BeatsSubscription.ts create mode 100644 packages/net/src/thor/subscriptions/SubscriptionBeat2Response.ts diff --git a/packages/net/src/thor/subscriptions/BeatsSubscription.ts b/packages/net/src/thor/subscriptions/BeatsSubscription.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/net/src/thor/subscriptions/SubscriptionBeat2Response.ts b/packages/net/src/thor/subscriptions/SubscriptionBeat2Response.ts new file mode 100644 index 000000000..8922feac2 --- /dev/null +++ b/packages/net/src/thor/subscriptions/SubscriptionBeat2Response.ts @@ -0,0 +1,40 @@ +import { BlockId, HexUInt, Units, VTHO } from '@vechain/sdk-core'; +import { UInt } from '../../../../core'; + +class SubscriptionBeat2Response { + gasLimit: VTHO; + obsolete: boolean; + number: UInt; + id: BlockId; + parentID: BlockId; + timestamp: UInt; + txsFeatures: UInt; + bloom: HexUInt; + k: UInt; + + constructor(json: SubscriptionBeat2ResponseJSON) { + this.gasLimit = VTHO.of(json.gasLimit, Units.wei); + this.obsolete = json.obsolete; + this.number = UInt.of(json.number); + this.id = BlockId.of(json.id); + this.parentID = BlockId.of(json.parentID); + this.timestamp = UInt.of(json.timestamp); + this.txsFeatures = UInt.of(json.txsFeatures); + this.bloom = HexUInt.of(json.bloom); + this.k = UInt.of(json.k); + } +} + +interface SubscriptionBeat2ResponseJSON { + gasLimit: number; + obsolete: boolean; + number: number; + id: string; + parentID: string; + timestamp: number; + txsFeatures: number; + bloom: string; + k: number; +} + +export { SubscriptionBeat2Response, type SubscriptionBeat2ResponseJSON }; From 4c82215abd97651001eb72783a93f3600853a0ef Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 25 Dec 2024 11:46:10 +0100 Subject: [PATCH 62/98] feat: 1484 subscriptions in dev... --- docs/diagrams/v2/net/http/http.md | 6 +- .../v2/net/thor/accounts/account-module.md | 8 +- docs/diagrams/v2/net/thor/debug/debug.md | 10 +-- docs/diagrams/v2/net/thor/logs/logs.md | 36 ++++----- docs/diagrams/v2/net/thor/node/node.md | 2 +- docs/diagrams/v2/net/thor/thor.md | 2 +- .../v2/net/thor/transactions/transactions.md | 26 +++---- .../thor/subscriptions/BeatsSubscription.ts | 76 +++++++++++++++++++ packages/net/src/thor/subscriptions/index.ts | 2 + 9 files changed, 124 insertions(+), 44 deletions(-) diff --git a/docs/diagrams/v2/net/http/http.md b/docs/diagrams/v2/net/http/http.md index 8f85fb34e..b19cb339b 100644 --- a/docs/diagrams/v2/net/http/http.md +++ b/docs/diagrams/v2/net/http/http.md @@ -4,10 +4,12 @@ classDiagram baseURL: string onRequest: OnRequest onResponse: OnResponse + at(baseURL: string, onRequest: OnRequest, onResponse: OnResponse) FetchHttpClient } class HttpClient { <> get(httpPath: HttpPath) Promise~Response~ + post(httpPath: HttpPath, body?: unknown) Promise~Response~ } class HttpPath { <> @@ -23,6 +25,6 @@ classDiagram } HttpPath <-- HttpClient HttpClient <|.. FetchHttpClient - FetchHttpClient --* OnRequest - FetchHttpClient --* OnResponse + FetchHttpClient *--> OnRequest + FetchHttpClient *--> OnResponse ``` diff --git a/docs/diagrams/v2/net/thor/accounts/account-module.md b/docs/diagrams/v2/net/thor/accounts/account-module.md index 4181fd7c5..8ede4a548 100644 --- a/docs/diagrams/v2/net/thor/accounts/account-module.md +++ b/docs/diagrams/v2/net/thor/accounts/account-module.md @@ -71,7 +71,7 @@ classDiagram Address recepient Address sender } - Clause *-- InspectClauses + Clause <--* InspectClauses HttpClient o-- ThorRequest InspectClauses <|-- InspectedClauses RetrieveContractByteCode <|-- ContractByteCode @@ -83,10 +83,10 @@ classDiagram ThorRequest <|.. RetrieveStoragePositionValue AccountDetails ..|> ThorResponse - CallResult --* Event - CallResult --* Transfer + CallResult *--> Event + CallResult *--> Transfer ContractByteCode ..|> ThorResponse InspectedClauses ..|> ThorResponse - InspectedClauses --* CallResult + InspectedClauses *--> CallResult StoragePositionValue ..|> ThorResponse ``` diff --git a/docs/diagrams/v2/net/thor/debug/debug.md b/docs/diagrams/v2/net/thor/debug/debug.md index 28bae1f4d..395975705 100644 --- a/docs/diagrams/v2/net/thor/debug/debug.md +++ b/docs/diagrams/v2/net/thor/debug/debug.md @@ -127,9 +127,9 @@ classDiagram TracerName <|-- EvmDis TracerName <|-- OpCount TracerName <|-- Null - RetrieveStorageRange --* StorageRangeOptions - PostDebugTracerCallRequest --* TracerName - PostDebugTracerRequest --* TracerName - TraceCall --* PostDebugTracerCallRequest - TraceTransactionClause --* PostDebugTracerRequest + RetrieveStorageRange *--> StorageRangeOptions + PostDebugTracerCallRequest *--> TracerName + PostDebugTracerRequest *--> TracerName + TraceCall *--> PostDebugTracerCallRequest + TraceTransactionClause *--> PostDebugTracerRequest ``` diff --git a/docs/diagrams/v2/net/thor/logs/logs.md b/docs/diagrams/v2/net/thor/logs/logs.md index ad74b17a1..fa7e61383 100644 --- a/docs/diagrams/v2/net/thor/logs/logs.md +++ b/docs/diagrams/v2/net/thor/logs/logs.md @@ -195,22 +195,22 @@ classDiagram ThorRequest <|.. QueryVETTransferEvents EventLogResponse "*" o-- EventLogsResponse TransferLogResponse "*" o-- TransferLogsResponse - EventLogFilterRequest --* FilterRange - EventLogFilterRequest --* FilterOptions - EventLogFilterRequest --* EventCriteria - EventLogFilterRequest --* LogSort - EventLogFilterRequestJSON --* FilterRangeJSON - EventLogFilterRequestJSON --* FilterOptionsJSON - EventLogFilterRequestJSON --* EventCriteriaJSON - EventLogResponse --* LogMeta - EventLogResponseJSON --* LogMetaJSON - FilterRange --* FilterRangeUnit - QuerySmartContractEvents --* EventLogFilterRequest - QueryVETTransferEvents --* TransferLogFilterRequest - TransferLogFilterRequest --* FilterRange - TransferLogFilterRequest --* FilterOptions - TransferLogFilterRequest --* "*" TransferCriteria - TransferLogFilterRequest --* LogSort - TransferLogResponse --* LogMeta - TransferLogResponseJSON --* LogMetaJSON + EventLogFilterRequest *--> FilterRange + EventLogFilterRequest *--> FilterOptions + EventLogFilterRequest *--> EventCriteria + EventLogFilterRequest *--> LogSort + EventLogFilterRequestJSON *--> FilterRangeJSON + EventLogFilterRequestJSON *--> FilterOptionsJSON + EventLogFilterRequestJSON *--> EventCriteriaJSON + EventLogResponse *--> LogMeta + EventLogResponseJSON *--> LogMetaJSON + FilterRange *--> FilterRangeUnit + QuerySmartContractEvents *--> EventLogFilterRequest + QueryVETTransferEvents *--> TransferLogFilterRequest + TransferLogFilterRequest *--> FilterRange + TransferLogFilterRequest *--> FilterOptions + TransferLogFilterRequest *--> "*" TransferCriteria + TransferLogFilterRequest *--> LogSort + TransferLogResponse *--> LogMeta + TransferLogResponseJSON *--> LogMetaJSON ``` diff --git a/docs/diagrams/v2/net/thor/node/node.md b/docs/diagrams/v2/net/thor/node/node.md index fa62bc527..a9bda2e43 100644 --- a/docs/diagrams/v2/net/thor/node/node.md +++ b/docs/diagrams/v2/net/thor/node/node.md @@ -37,5 +37,5 @@ classDiagram HttpClient <-- ThorRequest~RetrieveConnectedPeers~ PeerResponse o-- Array~PeerResponse~ ThorRequest~RetrieveConnectedPeers~ <|.. RetrieveConnectedPeers - ThorResponse~RetrieveConnectedPeers~ --* ThorRequest~RetrieveConnectedPeers~ + ThorResponse~RetrieveConnectedPeers~ *--> ThorRequest~RetrieveConnectedPeers~ ``` diff --git a/docs/diagrams/v2/net/thor/thor.md b/docs/diagrams/v2/net/thor/thor.md index a5dace1ca..fe72d1385 100644 --- a/docs/diagrams/v2/net/thor/thor.md +++ b/docs/diagrams/v2/net/thor/thor.md @@ -14,5 +14,5 @@ classDiagram request: ThorRequest~RequestClass~ response: ResponseClass } - ThorRequest <-- ThorResponse + ThorRequest <--* ThorResponse ``` diff --git a/docs/diagrams/v2/net/thor/transactions/transactions.md b/docs/diagrams/v2/net/thor/transactions/transactions.md index 49759aeb9..a41477ca7 100644 --- a/docs/diagrams/v2/net/thor/transactions/transactions.md +++ b/docs/diagrams/v2/net/thor/transactions/transactions.md @@ -224,19 +224,19 @@ classDiagram RetrieveTransactionByIDPath <|-- RetrieveRawTransactionByIDPath RetrieveTransactionByIDQuery <|-- RetrieveRawTransactionByIDQuery TxMeta <-- ReceiptMeta - RetrieveRawTransactionByID --* RetrieveRawTransactionByIDPath - RetrieveRawTransactionByID --* RetrieveRawTransactionByIDQuery - RetrieveTransactionByID --* RetrieveTransactionByIDPath - RetrieveTransactionByID --* RetrieveRawTransactionByIDQuery - RetrieveTransactionReceipt --* RetrieveTransactionReceiptPath - RetrieveTransactionReceipt --* RetrieveTransactionReceiptQuery - GetRawTxResponse --* TxMeta - GetTxReceiptResponse --* ReceiptMeta - GetTxResponse --* Clause - GetTxResponse --* TxMeta - Receipt --* ReceiptOutput - ReceiptOutput --* Event - ReceiptOutput --* Transfer + RetrieveRawTransactionByID *--> RetrieveRawTransactionByIDPath + RetrieveRawTransactionByID *--> RetrieveRawTransactionByIDQuery + RetrieveTransactionByID *--> RetrieveTransactionByIDPath + RetrieveTransactionByID *--> RetrieveRawTransactionByIDQuery + RetrieveTransactionReceipt *--> RetrieveTransactionReceiptPath + RetrieveTransactionReceipt *--> RetrieveTransactionReceiptQuery + GetRawTxResponse *--> TxMeta + GetTxReceiptResponse *--> ReceiptMeta + GetTxResponse *--> Clause + GetTxResponse *--> TxMeta + Receipt *--> ReceiptOutput + ReceiptOutput *--> Event + ReceiptOutput *--> Transfer ClauseJSON <-- Clause EventJSON <-- Event GetRawTxResponseJSON <-- GetRawTxResponse diff --git a/packages/net/src/thor/subscriptions/BeatsSubscription.ts b/packages/net/src/thor/subscriptions/BeatsSubscription.ts index e69de29bb..ee81b7da3 100644 --- a/packages/net/src/thor/subscriptions/BeatsSubscription.ts +++ b/packages/net/src/thor/subscriptions/BeatsSubscription.ts @@ -0,0 +1,76 @@ +import { type WebSocketClient, type WebSocketListener } from '../../ws'; +import type { HttpPath } from '../../http'; +import type { BlockId } from '@vechain/sdk-core'; +import { + SubscriptionBeat2Response, + type SubscriptionBeat2ResponseJSON +} from './SubscriptionBeat2Response'; + +class BeatsSubscription implements WebSocketClient, WebSocketListener { + static readonly PATH: HttpPath = { path: '/subscriptions/beat2' }; + + private readonly messageListeners: Array< + WebSocketListener + > = []; + + private readonly query: BeatsSubscriptionQuery; + + private readonly wsc: WebSocketClient; + + protected constructor(wsc: WebSocketClient, query: BeatsSubscriptionQuery) { + this.wsc = wsc; + this.query = query; + } + + addMessageListener( + listener: WebSocketListener + ): this { + this.messageListeners.push(listener); + return this; + } + + static at(wsc: WebSocketClient): BeatsSubscription { + return new BeatsSubscription(wsc, new BeatsSubscriptionQuery()); + } + + get baseURL(): string { + return this.wsc.baseURL; + } + + close(): this { + this.wsc.close(); + return this; + } + + onMessage(event: MessageEvent): void { + const json = JSON.parse( + event.data as string + ) as SubscriptionBeat2ResponseJSON; + const message = new MessageEvent( + event.type, + { data: new SubscriptionBeat2Response(json) } + ); + this.messageListeners.forEach((listener) => { + listener.onMessage(message); + }); + } + + open(path: HttpPath = BeatsSubscription.PATH): this { + this.wsc.addMessageListener(this).open(path); + return this; + } +} + +class BeatsSubscriptionQuery { + readonly pos?: BlockId; + + constructor(pos?: BlockId) { + this.pos = pos; + } + + get query(): string { + return this.pos === undefined ? '' : `?pos=${this.pos}`; + } +} + +export { BeatsSubscription }; diff --git a/packages/net/src/thor/subscriptions/index.ts b/packages/net/src/thor/subscriptions/index.ts index 5f76cb49f..886cec9c4 100644 --- a/packages/net/src/thor/subscriptions/index.ts +++ b/packages/net/src/thor/subscriptions/index.ts @@ -1,2 +1,4 @@ +export * from './BeatsSubscription'; export * from './BlocksSubscription'; +export * from './SubscriptionBeat2Response'; export * from './SubscriptionBlockResponse'; From 70739edc1e7632dec8d407dff8c4c0bdd3e35e5d Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 25 Dec 2024 12:00:00 +0100 Subject: [PATCH 63/98] feat: 1484 subscriptions in dev... --- .../BeatsSubscription.solo.test.ts | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts diff --git a/packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts b/packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts new file mode 100644 index 000000000..2091c01b7 --- /dev/null +++ b/packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts @@ -0,0 +1,34 @@ +import { afterEach, beforeEach, describe } from '@jest/globals'; +import { + MozillaWebSocketClient, + type WebSocketListener +} from '../../../src/ws'; +import { + BeatsSubscription, + type SubscriptionBeat2ResponseJSON +} from '../../../src/thor/subscriptions'; + +describe('BlocksSubscription solo tests', () => { + let subscription: BeatsSubscription; + beforeEach(() => { + subscription = BeatsSubscription.at( + new MozillaWebSocketClient('ws://localhost:8669') + ); + }); + + test('data <- open', (done) => { + subscription + .addMessageListener({ + onMessage: (message) => { + const data = message.data as SubscriptionBeat2ResponseJSON; + console.log(JSON.stringify(data, null, 2)); + done(); + } + } satisfies WebSocketListener) + .open(); + }, 30000); + + afterEach(() => { + subscription.close(); + }); +}); From b7b028273949775c69b4d565f62dd5eb4497e2fb Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 25 Dec 2024 19:12:39 +0100 Subject: [PATCH 64/98] feat: 1484 subscriptions in dev... --- .../thor/subscriptions/BeatsSubscription.ts | 19 +++++++++---------- .../thor/subscriptions/BlocksSubscription.ts | 6 ++++-- .../BeatsSubscription.solo.test.ts | 4 ++-- .../BlocksSubscription.solo.test.ts | 6 +++--- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/packages/net/src/thor/subscriptions/BeatsSubscription.ts b/packages/net/src/thor/subscriptions/BeatsSubscription.ts index ee81b7da3..8fdc627bf 100644 --- a/packages/net/src/thor/subscriptions/BeatsSubscription.ts +++ b/packages/net/src/thor/subscriptions/BeatsSubscription.ts @@ -1,16 +1,13 @@ import { type WebSocketClient, type WebSocketListener } from '../../ws'; import type { HttpPath } from '../../http'; import type { BlockId } from '@vechain/sdk-core'; -import { - SubscriptionBeat2Response, - type SubscriptionBeat2ResponseJSON -} from './SubscriptionBeat2Response'; +import { type SubscriptionBeat2ResponseJSON } from './SubscriptionBeat2Response'; class BeatsSubscription implements WebSocketClient, WebSocketListener { static readonly PATH: HttpPath = { path: '/subscriptions/beat2' }; private readonly messageListeners: Array< - WebSocketListener + WebSocketListener > = []; private readonly query: BeatsSubscriptionQuery; @@ -23,7 +20,7 @@ class BeatsSubscription implements WebSocketClient, WebSocketListener { } addMessageListener( - listener: WebSocketListener + listener: WebSocketListener ): this { this.messageListeners.push(listener); return this; @@ -46,17 +43,19 @@ class BeatsSubscription implements WebSocketClient, WebSocketListener { const json = JSON.parse( event.data as string ) as SubscriptionBeat2ResponseJSON; - const message = new MessageEvent( + const message = new MessageEvent( event.type, - { data: new SubscriptionBeat2Response(json) } + { data: json } ); this.messageListeners.forEach((listener) => { listener.onMessage(message); }); } - open(path: HttpPath = BeatsSubscription.PATH): this { - this.wsc.addMessageListener(this).open(path); + open(): this { + this.wsc + .addMessageListener(this) + .open({ path: BeatsSubscription.PATH.path + this.query.query }); return this; } } diff --git a/packages/net/src/thor/subscriptions/BlocksSubscription.ts b/packages/net/src/thor/subscriptions/BlocksSubscription.ts index a5228dab7..a170d7b52 100644 --- a/packages/net/src/thor/subscriptions/BlocksSubscription.ts +++ b/packages/net/src/thor/subscriptions/BlocksSubscription.ts @@ -64,8 +64,10 @@ class BlocksSubscription }); } - open(path: HttpPath = BlocksSubscription.PATH): this { - this.wsc.addMessageListener(this).open(path); + open(): this { + this.wsc + .addMessageListener(this) + .open({ path: BlocksSubscription.PATH.path + this.query.query }); return this; } } diff --git a/packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts b/packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts index 2091c01b7..55efa103f 100644 --- a/packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts +++ b/packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts @@ -20,11 +20,11 @@ describe('BlocksSubscription solo tests', () => { subscription .addMessageListener({ onMessage: (message) => { - const data = message.data as SubscriptionBeat2ResponseJSON; + const data = message.data; console.log(JSON.stringify(data, null, 2)); done(); } - } satisfies WebSocketListener) + } satisfies WebSocketListener) .open(); }, 30000); diff --git a/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts b/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts index fe5c9e4c9..d4a1ac459 100644 --- a/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts +++ b/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts @@ -5,7 +5,7 @@ import { } from '../../../src/ws'; import { BlocksSubscription, - type SubscriptionBlockResponseJSON + type SubscriptionBlockResponse } from '../../../src/thor/subscriptions'; describe('BlocksSubscription solo tests', () => { @@ -20,11 +20,11 @@ describe('BlocksSubscription solo tests', () => { subscription .addMessageListener({ onMessage: (message) => { - const data = message.data as SubscriptionBlockResponseJSON; + const data = message.data; console.log(JSON.stringify(data, null, 2)); done(); } - } satisfies WebSocketListener) + } satisfies WebSocketListener) .open(); }, 30000); From 0fec0f5b7e0deb65f79f2b7e5c02b8809c3938e0 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 25 Dec 2024 19:28:37 +0100 Subject: [PATCH 65/98] feat: 1484 subscriptions in dev... --- .../src/thor/subscriptions/BeatsSubscription.ts | 13 ++++++++----- .../subscriptions/SubscriptionBeat2Response.ts | 14 ++++++++++++++ .../subscriptions/BeatsSubscription.solo.test.ts | 4 ++-- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/packages/net/src/thor/subscriptions/BeatsSubscription.ts b/packages/net/src/thor/subscriptions/BeatsSubscription.ts index 8fdc627bf..8ce92534d 100644 --- a/packages/net/src/thor/subscriptions/BeatsSubscription.ts +++ b/packages/net/src/thor/subscriptions/BeatsSubscription.ts @@ -1,13 +1,16 @@ import { type WebSocketClient, type WebSocketListener } from '../../ws'; import type { HttpPath } from '../../http'; import type { BlockId } from '@vechain/sdk-core'; -import { type SubscriptionBeat2ResponseJSON } from './SubscriptionBeat2Response'; +import { + SubscriptionBeat2Response, + type SubscriptionBeat2ResponseJSON +} from './SubscriptionBeat2Response'; class BeatsSubscription implements WebSocketClient, WebSocketListener { static readonly PATH: HttpPath = { path: '/subscriptions/beat2' }; private readonly messageListeners: Array< - WebSocketListener + WebSocketListener > = []; private readonly query: BeatsSubscriptionQuery; @@ -20,7 +23,7 @@ class BeatsSubscription implements WebSocketClient, WebSocketListener { } addMessageListener( - listener: WebSocketListener + listener: WebSocketListener ): this { this.messageListeners.push(listener); return this; @@ -43,9 +46,9 @@ class BeatsSubscription implements WebSocketClient, WebSocketListener { const json = JSON.parse( event.data as string ) as SubscriptionBeat2ResponseJSON; - const message = new MessageEvent( + const message = new MessageEvent( event.type, - { data: json } + { data: new SubscriptionBeat2Response(json) } ); this.messageListeners.forEach((listener) => { listener.onMessage(message); diff --git a/packages/net/src/thor/subscriptions/SubscriptionBeat2Response.ts b/packages/net/src/thor/subscriptions/SubscriptionBeat2Response.ts index 8922feac2..4c8620368 100644 --- a/packages/net/src/thor/subscriptions/SubscriptionBeat2Response.ts +++ b/packages/net/src/thor/subscriptions/SubscriptionBeat2Response.ts @@ -23,6 +23,20 @@ class SubscriptionBeat2Response { this.bloom = HexUInt.of(json.bloom); this.k = UInt.of(json.k); } + + toJSON(): SubscriptionBeat2ResponseJSON { + return { + gasLimit: Number(this.gasLimit.wei), + obsolete: this.obsolete, + number: this.number.valueOf(), + id: this.id.toString(), + parentID: this.parentID.toString(), + timestamp: this.timestamp.valueOf(), + txsFeatures: this.txsFeatures.valueOf(), + bloom: this.bloom.toString(), + k: this.k.valueOf() + } satisfies SubscriptionBeat2ResponseJSON; + } } interface SubscriptionBeat2ResponseJSON { diff --git a/packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts b/packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts index 55efa103f..a4dd35713 100644 --- a/packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts +++ b/packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts @@ -5,7 +5,7 @@ import { } from '../../../src/ws'; import { BeatsSubscription, - type SubscriptionBeat2ResponseJSON + type SubscriptionBeat2Response } from '../../../src/thor/subscriptions'; describe('BlocksSubscription solo tests', () => { @@ -24,7 +24,7 @@ describe('BlocksSubscription solo tests', () => { console.log(JSON.stringify(data, null, 2)); done(); } - } satisfies WebSocketListener) + } satisfies WebSocketListener) .open(); }, 30000); From 07e252c8614a856c6fc65faeb03fb0bc91d84529 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 25 Dec 2024 20:03:37 +0100 Subject: [PATCH 66/98] feat: 1484 subscriptions in dev... --- .../NewTransactionSubscription.ts | 52 +++++++++++++++++++ .../SubscriptionBeat2Response.ts | 18 +++---- packages/net/src/thor/subscriptions/TXID.ts | 21 ++++++++ packages/net/src/thor/subscriptions/index.ts | 2 + .../NewTransactionSubscription.solo.test.ts | 34 ++++++++++++ 5 files changed, 118 insertions(+), 9 deletions(-) create mode 100644 packages/net/src/thor/subscriptions/NewTransactionSubscription.ts create mode 100644 packages/net/src/thor/subscriptions/TXID.ts create mode 100644 packages/net/tests/thor/subscriptions/NewTransactionSubscription.solo.test.ts diff --git a/packages/net/src/thor/subscriptions/NewTransactionSubscription.ts b/packages/net/src/thor/subscriptions/NewTransactionSubscription.ts new file mode 100644 index 000000000..5a962ef38 --- /dev/null +++ b/packages/net/src/thor/subscriptions/NewTransactionSubscription.ts @@ -0,0 +1,52 @@ +import { type WebSocketClient, type WebSocketListener } from '../../ws'; +import type { HttpPath } from '../../http'; +import { TXID, type TXIDJSON } from './TXID'; + +class NewTransactionSubscription + implements WebSocketClient, WebSocketListener +{ + static readonly PATH: HttpPath = { path: '/subscriptions/txpool' }; + + private readonly messageListeners: Array> = []; + + private readonly wsc: WebSocketClient; + + protected constructor(wsc: WebSocketClient) { + this.wsc = wsc; + } + + addMessageListener(listener: WebSocketListener): this { + this.messageListeners.push(listener); + return this; + } + + static at(wsc: WebSocketClient): NewTransactionSubscription { + return new NewTransactionSubscription(wsc); + } + + get baseURL(): string { + return this.wsc.baseURL; + } + + close(): this { + this.wsc.close(); + return this; + } + + onMessage(event: MessageEvent): void { + const json = JSON.parse(event.data as string) as TXIDJSON; + const message = new MessageEvent(event.type, { + data: new TXID(json) + }); + this.messageListeners.forEach((listener) => { + listener.onMessage(message); + }); + } + + open(): this { + this.wsc.addMessageListener(this).open(NewTransactionSubscription.PATH); + return this; + } +} + +export { NewTransactionSubscription }; diff --git a/packages/net/src/thor/subscriptions/SubscriptionBeat2Response.ts b/packages/net/src/thor/subscriptions/SubscriptionBeat2Response.ts index 4c8620368..417551247 100644 --- a/packages/net/src/thor/subscriptions/SubscriptionBeat2Response.ts +++ b/packages/net/src/thor/subscriptions/SubscriptionBeat2Response.ts @@ -2,15 +2,15 @@ import { BlockId, HexUInt, Units, VTHO } from '@vechain/sdk-core'; import { UInt } from '../../../../core'; class SubscriptionBeat2Response { - gasLimit: VTHO; - obsolete: boolean; - number: UInt; - id: BlockId; - parentID: BlockId; - timestamp: UInt; - txsFeatures: UInt; - bloom: HexUInt; - k: UInt; + readonly gasLimit: VTHO; + readonly obsolete: boolean; + readonly number: UInt; + readonly id: BlockId; + readonly parentID: BlockId; + readonly timestamp: UInt; + readonly txsFeatures: UInt; + readonly bloom: HexUInt; + readonly k: UInt; constructor(json: SubscriptionBeat2ResponseJSON) { this.gasLimit = VTHO.of(json.gasLimit, Units.wei); diff --git a/packages/net/src/thor/subscriptions/TXID.ts b/packages/net/src/thor/subscriptions/TXID.ts new file mode 100644 index 000000000..d30f999d8 --- /dev/null +++ b/packages/net/src/thor/subscriptions/TXID.ts @@ -0,0 +1,21 @@ +import { ThorId } from '@vechain/sdk-core'; + +class TXID { + readonly id: ThorId; + + constructor(json: TXIDJSON) { + this.id = ThorId.of(json.id); + } + + toJSON(): TXIDJSON { + return { + id: this.id.toString() + } satisfies TXIDJSON; + } +} + +interface TXIDJSON { + id: string; +} + +export { TXID, type TXIDJSON }; diff --git a/packages/net/src/thor/subscriptions/index.ts b/packages/net/src/thor/subscriptions/index.ts index 886cec9c4..904d5e13a 100644 --- a/packages/net/src/thor/subscriptions/index.ts +++ b/packages/net/src/thor/subscriptions/index.ts @@ -1,4 +1,6 @@ export * from './BeatsSubscription'; export * from './BlocksSubscription'; +export * from './NewTransactionSubscription'; export * from './SubscriptionBeat2Response'; export * from './SubscriptionBlockResponse'; +export * from './TXID'; diff --git a/packages/net/tests/thor/subscriptions/NewTransactionSubscription.solo.test.ts b/packages/net/tests/thor/subscriptions/NewTransactionSubscription.solo.test.ts new file mode 100644 index 000000000..289409fd9 --- /dev/null +++ b/packages/net/tests/thor/subscriptions/NewTransactionSubscription.solo.test.ts @@ -0,0 +1,34 @@ +import { afterEach, beforeEach, describe } from '@jest/globals'; +import { + MozillaWebSocketClient, + type WebSocketListener +} from '../../../src/ws'; +import { + NewTransactionSubscription, + type TXID +} from '../../../src/thor/subscriptions'; + +describe('NewTransactionSubscription solo tests', () => { + let subscription: NewTransactionSubscription; + beforeEach(() => { + subscription = NewTransactionSubscription.at( + new MozillaWebSocketClient('ws://localhost:8669') + ); + }); + + test('data <- open', (done) => { + subscription + .addMessageListener({ + onMessage: (message) => { + const data = message.data; + console.log(JSON.stringify(data, null, 2)); + done(); + } + } satisfies WebSocketListener) + .open(); + }, 30000); + + afterEach(() => { + subscription.close(); + }); +}); From 3d1715bf2989e5ef72db9a73a1caa2de0598ad1c Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 25 Dec 2024 22:14:56 +0100 Subject: [PATCH 67/98] feat: 1484 subscriptions in dev... --- .../SubscriptionTransferResponse.ts | 38 +++++++ .../subscriptions/TransfersSubscription.ts | 107 ++++++++++++++++++ packages/net/src/thor/subscriptions/index.ts | 2 + 3 files changed, 147 insertions(+) create mode 100644 packages/net/src/thor/subscriptions/SubscriptionTransferResponse.ts create mode 100644 packages/net/src/thor/subscriptions/TransfersSubscription.ts diff --git a/packages/net/src/thor/subscriptions/SubscriptionTransferResponse.ts b/packages/net/src/thor/subscriptions/SubscriptionTransferResponse.ts new file mode 100644 index 000000000..7d1922db6 --- /dev/null +++ b/packages/net/src/thor/subscriptions/SubscriptionTransferResponse.ts @@ -0,0 +1,38 @@ +import { LogMeta, type LogMetaJSON } from '../logs'; +import { Address, HexUInt, Units, VET } from '@vechain/sdk-core'; + +class SubscriptionTransferResponse { + readonly sender: Address; + readonly recipient: Address; + readonly amount: VET; + readonly obsolete: boolean; + readonly meta: LogMeta; + + constructor(json: SubscriptionTransferJSON) { + this.sender = Address.of(json.sender); + this.recipient = Address.of(json.recipient); + this.amount = VET.of(HexUInt.of(json.amount).bi, Units.wei); + this.obsolete = json.obsolete; + this.meta = new LogMeta(json.meta); + } + + toJSON(): SubscriptionTransferJSON { + return { + sender: this.sender.toString(), + recipient: this.recipient.toString(), + amount: HexUInt.of(this.amount.wei).toString(), + obsolete: this.obsolete, + meta: this.meta.toJSON() + } satisfies SubscriptionTransferJSON; + } +} + +interface SubscriptionTransferJSON { + sender: string; + recipient: string; + amount: string; + obsolete: boolean; + meta: LogMetaJSON; +} + +export { SubscriptionTransferResponse, type SubscriptionTransferJSON }; diff --git a/packages/net/src/thor/subscriptions/TransfersSubscription.ts b/packages/net/src/thor/subscriptions/TransfersSubscription.ts new file mode 100644 index 000000000..1d35de738 --- /dev/null +++ b/packages/net/src/thor/subscriptions/TransfersSubscription.ts @@ -0,0 +1,107 @@ +import { type HttpPath, type HttpQuery } from '../../http'; +import { type Address, type BlockId } from '@vechain/sdk-core'; +import { type WebSocketClient, type WebSocketListener } from '../../ws'; +import { type SubscriptionTransferResponse } from './SubscriptionTransferResponse'; + +class TransfersSubscription + implements WebSocketClient, WebSocketListener +{ + static readonly PATH: HttpPath = { path: '/subscriptions/transfer' }; + + private readonly messageListeners: Array< + WebSocketListener + > = []; + + private readonly query: TransfersSubscriptionQuery; + + private readonly wsc: WebSocketClient; + + protected constructor( + wsc: WebSocketClient, + query: TransfersSubscriptionQuery + ) { + this.wsc = wsc; + this.query = query; + } + + addMessageListener( + listener: WebSocketListener + ): this { + this.messageListeners.push(listener); + return this; + } + + static at(wsc: WebSocketClient): TransfersSubscription { + return new TransfersSubscription(wsc, new TransfersSubscriptionQuery()); + } + + get baseURL(): string { + return this.wsc.baseURL; + } + + close(): this { + this.wsc.close(); + return this; + } + + onMessage(event: MessageEvent): void { + const json = JSON.parse( + event.data as string + ) as SubscriptionTransferResponse; + const message = new MessageEvent( + event.type, + { data: json } + ); + this.messageListeners.forEach((listener) => { + listener.onMessage(message); + }); + } + + open(): this { + this.wsc + .addMessageListener(this) + .open({ path: TransfersSubscription.PATH.path + this.query.query }); + return this; + } +} + +class TransfersSubscriptionQuery implements HttpQuery { + readonly pos?: BlockId; + readonly recipient?: Address; + readonly sender?: Address; + readonly txOrigin?: Address; + + constructor( + pos?: BlockId, + recipient?: Address, + sender?: Address, + txOrigin?: Address + ) { + this.pos = pos; + this.recipient = recipient; + this.sender = sender; + this.txOrigin = txOrigin; + } + + get query(): string { + let query = ''; + if (this.pos !== undefined) { + query += `pos=${this.pos}`; + } + if (this.recipient !== undefined) { + if (query.length > 0) query += '&'; + query += `recipient=${this.recipient}`; + } + if (this.sender !== undefined) { + if (query.length > 0) query += '&'; + query += `sender=${this.sender}`; + } + if (this.txOrigin !== undefined) { + if (query.length > 0) query += '&'; + query += `txOrigin=${this.txOrigin}`; + } + return query.length > 0 ? `?${query}` : query; + } +} + +export { TransfersSubscription }; diff --git a/packages/net/src/thor/subscriptions/index.ts b/packages/net/src/thor/subscriptions/index.ts index 904d5e13a..122898fb6 100644 --- a/packages/net/src/thor/subscriptions/index.ts +++ b/packages/net/src/thor/subscriptions/index.ts @@ -3,4 +3,6 @@ export * from './BlocksSubscription'; export * from './NewTransactionSubscription'; export * from './SubscriptionBeat2Response'; export * from './SubscriptionBlockResponse'; +export * from './SubscriptionTransferResponse'; +export * from './TransfersSubscription'; export * from './TXID'; From b832d3dc6bf8689c5f9a2e5d46b3684fa3a434b3 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 25 Dec 2024 22:49:15 +0100 Subject: [PATCH 68/98] feat: 1484 subscriptions prototype --- .../thor/subscriptions/EventsSubscription.ts | 121 ++++++++++++++++++ .../SubscriptionEventResponse.ts | 42 ++++++ packages/net/src/thor/subscriptions/index.ts | 2 + 3 files changed, 165 insertions(+) create mode 100644 packages/net/src/thor/subscriptions/EventsSubscription.ts create mode 100644 packages/net/src/thor/subscriptions/SubscriptionEventResponse.ts diff --git a/packages/net/src/thor/subscriptions/EventsSubscription.ts b/packages/net/src/thor/subscriptions/EventsSubscription.ts new file mode 100644 index 000000000..770444ece --- /dev/null +++ b/packages/net/src/thor/subscriptions/EventsSubscription.ts @@ -0,0 +1,121 @@ +import { type WebSocketClient, type WebSocketListener } from '../../ws'; +import { type SubscriptionEventResponse } from './SubscriptionEventResponse'; +import { type HttpPath, type HttpQuery } from '../../http'; +import { type Address, type ThorId } from '@vechain/sdk-core'; + +class EventsSubscription + implements WebSocketClient, WebSocketListener +{ + static readonly PATH: HttpPath = { path: '/subscriptions/event' }; + + private readonly messageListeners: Array< + WebSocketListener + > = []; + + private readonly query: EventsSubscriptionQuery; + + private readonly wsc: WebSocketClient; + + protected constructor( + wsc: WebSocketClient, + query: EventsSubscriptionQuery + ) { + this.wsc = wsc; + this.query = query; + } + + addMessageListener( + listener: WebSocketListener + ): this { + this.messageListeners.push(listener); + return this; + } + + static at(wsc: WebSocketClient): EventsSubscription { + return new EventsSubscription(wsc, new EventsSubscriptionQuery()); + } + + get baseURL(): string { + return this.wsc.baseURL; + } + + close(): this { + this.wsc.close(); + return this; + } + + onMessage(event: MessageEvent): void { + const json = JSON.parse( + event.data as string + ) as SubscriptionEventResponse; + const message = new MessageEvent( + event.type, + { data: json } + ); + this.messageListeners.forEach((listener) => { + listener.onMessage(message); + }); + } + + open(): this { + this.wsc + .addMessageListener(this) + .open({ path: EventsSubscription.PATH.path + this.query.query }); + return this; + } +} + +class EventsSubscriptionQuery implements HttpQuery { + readonly addr?: Address; + readonly pos?: ThorId; + readonly t0?: ThorId; + readonly t1?: ThorId; + readonly t2?: ThorId; + readonly t3?: ThorId; + + constructor( + addr?: Address, + pos?: ThorId, + t0?: ThorId, + t1?: ThorId, + t2?: ThorId, + t3?: ThorId + ) { + this.addr = addr; + this.pos = pos; + this.t0 = t0; + this.t1 = t1; + this.t2 = t2; + this.t3 = t3; + } + + get query(): string { + let query = ''; + if (this.addr !== undefined) { + query += `addr=${this.addr}`; + } + if (this.pos !== undefined) { + if (query.length > 0) query += '&'; + query += `pos=${this.pos}`; + } + if (this.t0 !== undefined) { + if (query.length > 0) query += '&'; + query += `t0=${this.t0}`; + } + if (this.t1 !== undefined) { + if (query.length > 0) query += '&'; + query += `t1=${this.t1}`; + } + if (this.t2 !== undefined) { + if (query.length > 0) query += '&'; + query += `t2=${this.t2}`; + } + if (this.t3 !== undefined) { + if (query.length > 0) query += '&'; + query += `t3=${this.t3}`; + } + return query.length > 0 ? `?${query}` : query; + } +} + +export { EventsSubscription }; diff --git a/packages/net/src/thor/subscriptions/SubscriptionEventResponse.ts b/packages/net/src/thor/subscriptions/SubscriptionEventResponse.ts new file mode 100644 index 000000000..ccd0db17b --- /dev/null +++ b/packages/net/src/thor/subscriptions/SubscriptionEventResponse.ts @@ -0,0 +1,42 @@ +import { LogMeta, type LogMetaJSON } from '../logs'; +import { Address, HexUInt, ThorId } from '@vechain/sdk-core'; + +class SubscriptionEventResponse { + readonly address: Address; + readonly topics: ThorId[]; + readonly data: HexUInt; + readonly obsolete: boolean; + readonly meta: LogMeta; + + constructor(json: SubscriptionEventResponseJSON) { + this.address = Address.of(json.address); + this.topics = json.topics.map( + (topic: string): ThorId => ThorId.of(topic) + ); + this.data = HexUInt.of(json.data); + this.obsolete = json.obsolete; + this.meta = new LogMeta(json.meta); + } + + toJSON(): SubscriptionEventResponseJSON { + return { + address: this.address.toString(), + topics: this.topics.map((topic: ThorId): string => + topic.toString() + ), + data: this.data.toString(), + obsolete: this.obsolete, + meta: this.meta.toJSON() + }; + } +} + +interface SubscriptionEventResponseJSON { + address: string; + topics: string[]; + data: string; + obsolete: boolean; + meta: LogMetaJSON; +} + +export { SubscriptionEventResponse, type SubscriptionEventResponseJSON }; diff --git a/packages/net/src/thor/subscriptions/index.ts b/packages/net/src/thor/subscriptions/index.ts index 122898fb6..eef21e6d0 100644 --- a/packages/net/src/thor/subscriptions/index.ts +++ b/packages/net/src/thor/subscriptions/index.ts @@ -1,8 +1,10 @@ export * from './BeatsSubscription'; export * from './BlocksSubscription'; +export * from './EventsSubscription'; export * from './NewTransactionSubscription'; export * from './SubscriptionBeat2Response'; export * from './SubscriptionBlockResponse'; +export * from './SubscriptionEventResponse'; export * from './SubscriptionTransferResponse'; export * from './TransfersSubscription'; export * from './TXID'; From 769eb89952df3c8128da2642778e4686308c0f2b Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Thu, 26 Dec 2024 11:33:25 +0100 Subject: [PATCH 69/98] feat: 1484 subscriptions documenting... --- .../subscriptions/subscriptions-module.md | 144 ------------------ .../net/thor/subscriptions/subscriptions.md | 89 +++++++++++ docs/diagrams/v2/net/ws/ws.md | 19 +++ .../thor/subscriptions/BlocksSubscription.ts | 4 +- .../thor/subscriptions/EventsSubscription.ts | 47 ++++++ packages/net/src/ws/WebSocketClient.ts | 4 +- 6 files changed, 159 insertions(+), 148 deletions(-) delete mode 100644 docs/diagrams/v2/net/thor/subscriptions/subscriptions-module.md create mode 100644 docs/diagrams/v2/net/thor/subscriptions/subscriptions.md create mode 100644 docs/diagrams/v2/net/ws/ws.md diff --git a/docs/diagrams/v2/net/thor/subscriptions/subscriptions-module.md b/docs/diagrams/v2/net/thor/subscriptions/subscriptions-module.md deleted file mode 100644 index 713b3ae35..000000000 --- a/docs/diagrams/v2/net/thor/subscriptions/subscriptions-module.md +++ /dev/null @@ -1,144 +0,0 @@ -```mermaid -classDiagram - class HttpClient { - <> - } - class ThorRequest~Request~ { - <> - askTo(httpClient: HttpClient) ThorResponse~Request~ - } - class ThorResponse~Response~ { - <> - request: ThorRequest~Request~ - response: Response - } - namespace Request { - class SubscribeBeats { - query: SubscribeBeats_Query - } - class SubscribeBeats_Query { - pos: BlockID - } - class SubscribeBlocksCreation { - query: SubscribeBlocksCreation_Query - } - class SubscribeBlocksCreation_Query { - pos: TXID - } - class SubscribeContractEvents { - query: SubscribeContractEvents_Query - } - class SubscribeContractEvents_Query { - addr: Address - pos: BlockID - t0: HexUInt - t1: HexUInt - t2: HexUInt - t3: HexUIn - } - class SubscribeBlockchainBeats { - query: SubscribeBlockchainBeats_Query - } - class SubscribeBlockchainBeats_Query { - pos: BlockID - } - class SubscribeTransactionsEvents { - body: SubscribeTransactionsEvents_Body - } - class SubscribeVETTransfers { - query: SubscribeVETTransfer_Query - } - class SubscribeVETTransfer_Query { - pos: BlockID - recipient: Address - sender: Address - txOrigin: Address - } - } - namespace Response { - class SubscriptionBeatResponse { - obsolete: boolean - number: UInt - id: BlockID - parentID: BlockID - timestamp: bigint - txsFeature: UInt - bloom: BloomFilter - } - class SubscriptionBeat2Response { - gasLimit: VTHO - obsolete: boolean - number: UInt - id: BlockID - parentId: BlockID - timestamp: bigint - txsFeatures: UInt - bloom: BloomFilter - } - class SubscriptionBlockResponse { - number: UInt - id: TXID - size: UInt - parentID: BlockID - timestamp: bigint - gasLimit: VTHO - beneficiary: Address - gasUsed: VTHO - totalScore: UInt - txsRoot: HexUInt - txsFeature: UInt - stateRoot: HexUInt - receiptsRoot: HexUInt - com: boolean - signer: Address - } - class SubscriptionEventResponse { - address: Address - topics: HexUInt - data: HexUInt - obsolete: boolean - meta: LogMeta - } - class SubscriptionTransferResponse { - sender: Address - recipient: Address - amount: VET - obsolete: boolean - meta: LogMeta - } - } - class LogMeta { - blockID: blockID - blockNumber: UInt - blockTimestamp: bigint - txID: TXID - txOrigin: TXID - clauseIndex: UInt - } - - HttpClient o-- ThorRequest - ThorRequest <|.. SubscribeBeats - ThorRequest <|.. SubscribeBlocksCreation - ThorRequest <|.. SubscribeContractEvents - ThorRequest <|.. SubscribeBlockchainBeats - ThorRequest <|.. SubscribeTransactionsEvents - ThorRequest <|.. SubscribeVETTransfers - ThorResponse <|.. SubscriptionBeatResponse - ThorResponse <|.. SubscriptionBeat2Response - ThorResponse <|.. SubscriptionBlockResponse - ThorResponse <|.. SubscriptionEventResponse - ThorResponse <|.. SubscriptionTransferResponse - ThorRequest --* ThorResponse - SubscribeBeats --* SubscribeBeats_Query - SubscribeBlockchainBeats --* SubscribeBlockchainBeats_Query - SubscribeBlocksCreation --* SubscribeBlocksCreation_Query - SubscribeContractEvents --* SubscribeContractEvents_Query - SubscriptionEventResponse --* LogMeta - SubscriptionTransferResponse --* LogMeta - SubscribeVETTransfers --* SubscribeVETTransfer_Query - SubscribeBeats <..> SubscriptionBeat2Response - SubscribeBlockchainBeats <..> SubscriptionBeatResponse - SubscribeBlocksCreation <..> SubscriptionBlockResponse - SubscribeContractEvents <..> SubscriptionEventResponse - SubscribeVETTransfers <..> SubscriptionTransferResponse -``` diff --git a/docs/diagrams/v2/net/thor/subscriptions/subscriptions.md b/docs/diagrams/v2/net/thor/subscriptions/subscriptions.md new file mode 100644 index 000000000..1980f6902 --- /dev/null +++ b/docs/diagrams/v2/net/thor/subscriptions/subscriptions.md @@ -0,0 +1,89 @@ +```mermaid +classDiagram + namespace ws { + class WebSocketClient { + <> + baseURL: string + addMessageListener(listener: WebSocketListener) + close(): WebSocketClient + open(path: HttpPath): WebSocketClient + } + class WebSocketListener~EventType~ { + <> + onMessage(event: MessageEvent~EventType~) + } + } + class BeatsSubscription { + PATH: HttpPath$ + addMessageListener(listener: WebSocketListener~SubscriptionBeat2Response~) BeatsSubscription + at(wsc: WebSocketClient) BeatsSubscription$ + close() BeatsSubscription + open() BeatsSubscription + } + class BlocksSubscription { + PATH: HttpPath$ + addMessageListener(listener: WebSocketListener~SubscriptionBlockResponse~) BlocksSubscription + at(wsc: WebSocketClient) BlocksSubscription$ + atPos(pos?: BlockId) + close() BlocksSubscription + open() BlocksSubscription + } + class EventsSubscription { + PATH: HttpPath$ + addMessageListener(listener: WebSocketListener~SubscriptionEventResponse~) EventsSubscription + at(wsc: WebSocketClient) EventsSubscription$ + atPos(pos?: ThorId) EventsSubscription + close() EventsSubscription + open() EventsSubscription + withContractAddress(contractAddress?: Address) EventsSubscription + withFilters(t0?: ThorId?, t1?: ThorId, t2: ThorId, t3: ThorId) EventsSubscription + } + class NewTransactionSubscription { + PATH: HttpPath$ + addMessageListener(listener: WebSocketListener~TXID~) NewTransactionSubscription + at(wsc: WebSocketClient) NewTransactionSubscription$ + close() NewTransactionSubscription + open() NewTransactionSubscription + } + class TransfersSubscription { + PATH: HttpPath$ + addMessageListener(listener: WebSocketListener~SubscriptionTransferResponse~) TransfersSubscription + at(wsc: WebSocketClient) TransfersSubscription + close() TransfersSubscription + open() TransfersSubscription + } + class SubscriptionBeat2Response { + gasLimit: VTHO + obsolete: boolean + number: UInt + id: BlockId + parentID: BlockId + timestamp: UInt + txsFeatures: UInt + bloom: HexUInt + k: UInt + constructor(json: SubscriptionBeat2ResponseJSON): SubscriptionBeat2Response + toJSON() SubscriptionBeat2ResponseJSON + } + class SubscriptionEventResponse { + address: Address; + topics: ThorId[]; + data: HexUInt; + obsolete: boolean; + meta: LogMeta; + constructor(json: SubscriptionEventResponseJSON) SubscriptionEventResponse + toJSON() SubscriptionEventResponseJSON + } + WebSocketClient <|.. BeatsSubscription + WebSocketClient <|.. BlocksSubscription + WebSocketClient <|.. EventsSubscription + WebSocketClient <|.. NewTransactionSubscription + WebSocketClient <|.. TransfersSubscription + WebSocketListener <|.. BeatsSubscription + WebSocketListener <|.. BlocksSubscription + WebSocketListener <|.. EventsSubscription + WebSocketListener <|.. NewTransactionSubscription + WebSocketListener <|.. TransfersSubscription + BeatsSubscription --> "onMessage" SubscriptionBeat2Response + EventsSubscription --> "onMessage" SubscriptionEventResponse +``` diff --git a/docs/diagrams/v2/net/ws/ws.md b/docs/diagrams/v2/net/ws/ws.md new file mode 100644 index 000000000..e649aa23d --- /dev/null +++ b/docs/diagrams/v2/net/ws/ws.md @@ -0,0 +1,19 @@ +```mermaid +classDiagram + class MozillaWebSocketClient { + constructor(baseURL: string) + } + class WebSocketClient { + <> + baseURL: string + addMessageListener(listener: WebSocketListener) + close(): WebSocketClient + open(path: HttpPath): WebSocketClient + } + class WebSocketListener~EventType~ { + <> + onMessage(event: MessageEvent~EventType~) + } + WebSocketClient <|.. MozillaWebSocketClient + WebSocketListener <--o WebSocketClient +``` diff --git a/packages/net/src/thor/subscriptions/BlocksSubscription.ts b/packages/net/src/thor/subscriptions/BlocksSubscription.ts index a170d7b52..07e349fad 100644 --- a/packages/net/src/thor/subscriptions/BlocksSubscription.ts +++ b/packages/net/src/thor/subscriptions/BlocksSubscription.ts @@ -35,10 +35,10 @@ class BlocksSubscription return new BlocksSubscription(wsc, new BlockSubscriptionQuery()); } - atPos(pos: BlockId): BlocksSubscription { + atPos(pos?: BlockId): BlocksSubscription { return new BlocksSubscription( this.wsc, - new BlockSubscriptionQuery(pos) + new BlockSubscriptionQuery(pos ?? this.query.pos) ); } diff --git a/packages/net/src/thor/subscriptions/EventsSubscription.ts b/packages/net/src/thor/subscriptions/EventsSubscription.ts index 770444ece..ed83dafcf 100644 --- a/packages/net/src/thor/subscriptions/EventsSubscription.ts +++ b/packages/net/src/thor/subscriptions/EventsSubscription.ts @@ -35,6 +35,20 @@ class EventsSubscription return new EventsSubscription(wsc, new EventsSubscriptionQuery()); } + atPos(pos?: ThorId): EventsSubscription { + return new EventsSubscription( + this.wsc, + new EventsSubscriptionQuery( + this.query.addr, + pos ?? this.query.pos, + this.query.t0, + this.query.t1, + this.query.t2, + this.query.t3 + ) + ); + } + get baseURL(): string { return this.wsc.baseURL; } @@ -63,6 +77,39 @@ class EventsSubscription .open({ path: EventsSubscription.PATH.path + this.query.query }); return this; } + + withContractAddress(contractAddress?: Address): EventsSubscription { + return new EventsSubscription( + this.wsc, + new EventsSubscriptionQuery( + contractAddress ?? this.query.addr, + this.query.pos, + this.query.t0, + this.query.t1, + this.query.t2, + this.query.t3 + ) + ); + } + + withFilters( + t0?: ThorId, + t1?: ThorId, + t2?: ThorId, + t3?: ThorId + ): EventsSubscription { + return new EventsSubscription( + this.wsc, + new EventsSubscriptionQuery( + this.query.addr, + this.query.pos, + t0 ?? this.query.t0, + t1 ?? this.query.t1, + t2 ?? this.query.t2, + t3 ?? this.query.t3 + ) + ); + } } class EventsSubscriptionQuery implements HttpQuery { diff --git a/packages/net/src/ws/WebSocketClient.ts b/packages/net/src/ws/WebSocketClient.ts index 492acff6e..1780de575 100644 --- a/packages/net/src/ws/WebSocketClient.ts +++ b/packages/net/src/ws/WebSocketClient.ts @@ -2,12 +2,12 @@ import type { WebSocketListener } from './WebSocketListener'; import { type HttpPath } from '../http'; interface WebSocketClient { + get baseURL(): string; + addMessageListener: ( listener: WebSocketListener ) => WebSocketClient; - get baseURL(): string; - close: () => WebSocketClient; open: (path: HttpPath) => WebSocketClient; From 3c1292d978a195544f1a5351ab295dda6eb78d2f Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Thu, 26 Dec 2024 12:56:40 +0100 Subject: [PATCH 70/98] feat: 1484 subscriptions documenting... --- .../net/thor/subscriptions/subscriptions.md | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/docs/diagrams/v2/net/thor/subscriptions/subscriptions.md b/docs/diagrams/v2/net/thor/subscriptions/subscriptions.md index 1980f6902..381cef9f0 100644 --- a/docs/diagrams/v2/net/thor/subscriptions/subscriptions.md +++ b/docs/diagrams/v2/net/thor/subscriptions/subscriptions.md @@ -1,5 +1,25 @@ ```mermaid classDiagram + namespace log { + class LogMeta { + blockID: BlockId + blockNumber: UInt + blockTimestamp: UInt + txID: TxId + txOrigin: Address + clauseIndex: UInt + constructor(json: LogMetaJSON) LogMeta + toJSON() LogMetaJSON + } + class LogMetaJSON { + blockID: string + blockNumber: number + blockTimestamp: number + txID: string + txOrigin: string + clauseIndex: number + } + } namespace ws { class WebSocketClient { <> @@ -65,6 +85,57 @@ classDiagram constructor(json: SubscriptionBeat2ResponseJSON): SubscriptionBeat2Response toJSON() SubscriptionBeat2ResponseJSON } + class SubscriptionBeat2ResponseJSON { + <> + gasLimit: number + obsolete: boolean + number: number + id: string + parentID: string + timestamp: number + txsFeatures: number + bloom: string + k: number + } + class SubscriptionBlockResponse { + number: UInt + id: BlockId + size: UInt + parentID: BlockId + timestamp: UInt + gasLimit: VTHO + beneficiary: Address + gasUsed: VTHO + totalScore: UInt + txsRoot: ThorId + txsFeatures: UInt + stateRoot: ThorId + receiptsRoot: ThorId + com: boolean + signer: Address + obsolete: boolean + transactions: TxId[] + } + class SubscriptionBlockResponseJSON { + <> + number: number + id: string + size: number + parentID: string + timestamp: number + gasLimit: number + beneficiary: string + gasUsed: number + totalScore: number + txsRoot: string + txsFeatures: number + stateRoot: string + receiptsRoot: string + com: boolean + signer: string + obsolete: boolean + transactions: string[] + } class SubscriptionEventResponse { address: Address; topics: ThorId[]; @@ -74,6 +145,38 @@ classDiagram constructor(json: SubscriptionEventResponseJSON) SubscriptionEventResponse toJSON() SubscriptionEventResponseJSON } + class SubscriptionEventResponseJSON { + <> + address: string + topics: string[] + data: string + obsolete: boolean + meta: LogMetaJSON + } + class SubscriptionTransferResponse { + sender: Address + recipient: Address + amount: VET + obsolete: boolean + meta: LogMeta + } + class SubscriptionTransferResponseJSON { + <> + sender: string + recipient: string + amount: string + obsolete: boolean + meta: LogMetaJSON + } + class TXID { + id: ThorId + constructor(json: TXIDJSON): TXID + toJSON() TXIDJSON + } + class TXIDJSON { + <> + id: string + } WebSocketClient <|.. BeatsSubscription WebSocketClient <|.. BlocksSubscription WebSocketClient <|.. EventsSubscription @@ -85,5 +188,18 @@ classDiagram WebSocketListener <|.. NewTransactionSubscription WebSocketListener <|.. TransfersSubscription BeatsSubscription --> "onMessage" SubscriptionBeat2Response + BlocksSubscription --> "onMessage" SubscriptionBlockResponse EventsSubscription --> "onMessage" SubscriptionEventResponse + NewTransactionSubscription --> "onMessage" TXID + TransfersSubscription --> "onMessage" SubscriptionTransferResponse + SubscriptionEventResponse *--> LogMeta + SubscriptionEventResponseJSON *--> LogMetaJSON + SubscriptionTransferResponse *--> LogMeta + SubscriptionTransferResponseJSON *-- LogMetaJSON + LogMeta --> "new - toJSON" LogMetaJSON + SubscriptionBeat2Response --> "new - toJSON" SubscriptionBeat2ResponseJSON + SubscriptionBlockResponse --> "new - toJSON" SubscriptionBlockResponseJSON + SubscriptionEventResponse --> "new - toJSON" SubscriptionEventResponseJSON + SubscriptionTransferResponse --> "new - toJSON" SubscriptionTransferResponseJSON + TXID --> "new - toJSON" TXIDJSON ``` From 958a4118e533b5a35ff7fe97e311cffe2cd06de7 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Thu, 26 Dec 2024 12:59:24 +0100 Subject: [PATCH 71/98] feat: 1484 subscriptions documenting... --- docs/diagrams/v2/net/ws/ws.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/diagrams/v2/net/ws/ws.md b/docs/diagrams/v2/net/ws/ws.md index e649aa23d..364f7894f 100644 --- a/docs/diagrams/v2/net/ws/ws.md +++ b/docs/diagrams/v2/net/ws/ws.md @@ -1,12 +1,12 @@ ```mermaid classDiagram class MozillaWebSocketClient { - constructor(baseURL: string) + constructor(baseURL: string) MozillaWebSocketClient } class WebSocketClient { <> baseURL: string - addMessageListener(listener: WebSocketListener) + addMessageListener(listener: WebSocketListener~EventType~) close(): WebSocketClient open(path: HttpPath): WebSocketClient } From f1b124b648d1129cad86f56390b2b53ff5fa269a Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Thu, 26 Dec 2024 20:20:26 +0100 Subject: [PATCH 72/98] feat: 1484 subscriptions documenting... --- .../net/thor/subscriptions/subscriptions.md | 8 ++++ docs/diagrams/v2/net/ws/ws.md | 4 ++ .../thor/subscriptions/BeatsSubscription.ts | 37 +++++++++++++++---- .../thor/subscriptions/BlocksSubscription.ts | 37 +++++++++++++++---- .../thor/subscriptions/EventsSubscription.ts | 37 +++++++++++++++---- .../NewTransactionSubscription.ts | 33 ++++++++++++++--- .../subscriptions/TransfersSubscription.ts | 4 +- packages/net/src/ws/MozillaWebSocketClient.ts | 31 +++++++++++++--- packages/net/src/ws/WebSocketClient.ts | 6 +-- packages/net/src/ws/WebSocketListener.ts | 3 ++ .../BeatsSubscription.solo.test.ts | 2 +- .../BlocksSubscription.solo.test.ts | 2 +- .../NewTransactionSubscription.solo.test.ts | 2 +- .../ws/MozillaWebSocketClient.solo.test.ts | 2 +- 14 files changed, 168 insertions(+), 40 deletions(-) diff --git a/docs/diagrams/v2/net/thor/subscriptions/subscriptions.md b/docs/diagrams/v2/net/thor/subscriptions/subscriptions.md index 381cef9f0..e6f56cb2d 100644 --- a/docs/diagrams/v2/net/thor/subscriptions/subscriptions.md +++ b/docs/diagrams/v2/net/thor/subscriptions/subscriptions.md @@ -27,10 +27,14 @@ classDiagram addMessageListener(listener: WebSocketListener) close(): WebSocketClient open(path: HttpPath): WebSocketClient + removeListener(listener: WebSocketListener): WebSocketClient } class WebSocketListener~EventType~ { <> + onClose(event: Event) + onError(event: Event) onMessage(event: MessageEvent~EventType~) + onOpen(event: Event) } } class BeatsSubscription { @@ -39,6 +43,7 @@ classDiagram at(wsc: WebSocketClient) BeatsSubscription$ close() BeatsSubscription open() BeatsSubscription + removeListener(listener: WebSocketListener~SubscriptionBeat2Response~) BeatsSubscription } class BlocksSubscription { PATH: HttpPath$ @@ -47,6 +52,7 @@ classDiagram atPos(pos?: BlockId) close() BlocksSubscription open() BlocksSubscription + removeListener(listener: WebSocketListener~SubscriptionBlockResponse~) BlocksSubscription } class EventsSubscription { PATH: HttpPath$ @@ -55,6 +61,7 @@ classDiagram atPos(pos?: ThorId) EventsSubscription close() EventsSubscription open() EventsSubscription + removeListener(listener: WebSocketListener~SubscriptionEventResponse~) EventsSubscription withContractAddress(contractAddress?: Address) EventsSubscription withFilters(t0?: ThorId?, t1?: ThorId, t2: ThorId, t3: ThorId) EventsSubscription } @@ -71,6 +78,7 @@ classDiagram at(wsc: WebSocketClient) TransfersSubscription close() TransfersSubscription open() TransfersSubscription + removeListener(listener: WebSocketListener~SubscriptionTransferResponse~) TransfersSubscription } class SubscriptionBeat2Response { gasLimit: VTHO diff --git a/docs/diagrams/v2/net/ws/ws.md b/docs/diagrams/v2/net/ws/ws.md index 364f7894f..a23307e2d 100644 --- a/docs/diagrams/v2/net/ws/ws.md +++ b/docs/diagrams/v2/net/ws/ws.md @@ -9,10 +9,14 @@ classDiagram addMessageListener(listener: WebSocketListener~EventType~) close(): WebSocketClient open(path: HttpPath): WebSocketClient + removeListener(listener: WebSocketListener): WebSocketClient } class WebSocketListener~EventType~ { <> + onClose(event: Event) + onError(event: Event) onMessage(event: MessageEvent~EventType~) + onOpen(event: Event) } WebSocketClient <|.. MozillaWebSocketClient WebSocketListener <--o WebSocketClient diff --git a/packages/net/src/thor/subscriptions/BeatsSubscription.ts b/packages/net/src/thor/subscriptions/BeatsSubscription.ts index 8ce92534d..c9af00f69 100644 --- a/packages/net/src/thor/subscriptions/BeatsSubscription.ts +++ b/packages/net/src/thor/subscriptions/BeatsSubscription.ts @@ -9,7 +9,7 @@ import { class BeatsSubscription implements WebSocketClient, WebSocketListener { static readonly PATH: HttpPath = { path: '/subscriptions/beat2' }; - private readonly messageListeners: Array< + private readonly listeners: Array< WebSocketListener > = []; @@ -22,10 +22,8 @@ class BeatsSubscription implements WebSocketClient, WebSocketListener { this.query = query; } - addMessageListener( - listener: WebSocketListener - ): this { - this.messageListeners.push(listener); + addListener(listener: WebSocketListener): this { + this.listeners.push(listener); return this; } @@ -42,6 +40,18 @@ class BeatsSubscription implements WebSocketClient, WebSocketListener { return this; } + onClose(event: Event): void { + this.listeners.forEach((listener) => { + listener.onClose(event); + }); + } + + onError(event: Event): void { + this.listeners.forEach((listener) => { + listener.onError(event); + }); + } + onMessage(event: MessageEvent): void { const json = JSON.parse( event.data as string @@ -50,17 +60,30 @@ class BeatsSubscription implements WebSocketClient, WebSocketListener { event.type, { data: new SubscriptionBeat2Response(json) } ); - this.messageListeners.forEach((listener) => { + this.listeners.forEach((listener) => { listener.onMessage(message); }); } + onOpen(event: Event): void { + this.listeners.forEach((listener) => { + listener.onOpen(event); + }); + } + open(): this { this.wsc - .addMessageListener(this) + .addListener(this) .open({ path: BeatsSubscription.PATH.path + this.query.query }); return this; } + + removeListener( + listener: WebSocketListener + ): this { + this.listeners.splice(this.listeners.indexOf(listener), 1); + return this; + } } class BeatsSubscriptionQuery { diff --git a/packages/net/src/thor/subscriptions/BlocksSubscription.ts b/packages/net/src/thor/subscriptions/BlocksSubscription.ts index 07e349fad..5ee594aa6 100644 --- a/packages/net/src/thor/subscriptions/BlocksSubscription.ts +++ b/packages/net/src/thor/subscriptions/BlocksSubscription.ts @@ -11,7 +11,7 @@ class BlocksSubscription { static readonly PATH: HttpPath = { path: '/subscriptions/block' }; - private readonly messageListeners: Array< + private readonly listeners: Array< WebSocketListener > = []; @@ -24,10 +24,8 @@ class BlocksSubscription this.query = query; } - addMessageListener( - listener: WebSocketListener - ): this { - this.messageListeners.push(listener); + addListener(listener: WebSocketListener): this { + this.listeners.push(listener); return this; } @@ -51,6 +49,18 @@ class BlocksSubscription return this; } + onClose(event: Event): void { + this.listeners.forEach((listener) => { + listener.onClose(event); + }); + } + + onError(event: Event): void { + this.listeners.forEach((listener) => { + listener.onError(event); + }); + } + onMessage(event: MessageEvent): void { const json = JSON.parse( event.data as string @@ -59,17 +69,30 @@ class BlocksSubscription event.type, { data: new SubscriptionBlockResponse(json) } ); - this.messageListeners.forEach((listener) => { + this.listeners.forEach((listener) => { listener.onMessage(message); }); } + onOpen(event: Event): void { + this.listeners.forEach((listener) => { + listener.onOpen(event); + }); + } + open(): this { this.wsc - .addMessageListener(this) + .addListener(this) .open({ path: BlocksSubscription.PATH.path + this.query.query }); return this; } + + removeListener( + listener: WebSocketListener + ): this { + this.listeners.splice(this.listeners.indexOf(listener), 1); + return this; + } } class BlockSubscriptionQuery implements HttpQuery { diff --git a/packages/net/src/thor/subscriptions/EventsSubscription.ts b/packages/net/src/thor/subscriptions/EventsSubscription.ts index ed83dafcf..4e0ff9af9 100644 --- a/packages/net/src/thor/subscriptions/EventsSubscription.ts +++ b/packages/net/src/thor/subscriptions/EventsSubscription.ts @@ -8,7 +8,7 @@ class EventsSubscription { static readonly PATH: HttpPath = { path: '/subscriptions/event' }; - private readonly messageListeners: Array< + private readonly listeners: Array< WebSocketListener > = []; @@ -24,10 +24,8 @@ class EventsSubscription this.query = query; } - addMessageListener( - listener: WebSocketListener - ): this { - this.messageListeners.push(listener); + addListener(listener: WebSocketListener): this { + this.listeners.push(listener); return this; } @@ -58,6 +56,18 @@ class EventsSubscription return this; } + onClose(event: Event): void { + this.listeners.forEach((listener) => { + listener.onClose(event); + }); + } + + onError(event: Event): void { + this.listeners.forEach((listener) => { + listener.onError(event); + }); + } + onMessage(event: MessageEvent): void { const json = JSON.parse( event.data as string @@ -66,18 +76,31 @@ class EventsSubscription event.type, { data: json } ); - this.messageListeners.forEach((listener) => { + this.listeners.forEach((listener) => { listener.onMessage(message); }); } + onOpen(event: Event): void { + this.listeners.forEach((listener) => { + listener.onOpen(event); + }); + } + open(): this { this.wsc - .addMessageListener(this) + .addListener(this) .open({ path: EventsSubscription.PATH.path + this.query.query }); return this; } + removeListener( + listener: WebSocketListener + ): this { + this.listeners.splice(this.listeners.indexOf(listener), 1); + return this; + } + withContractAddress(contractAddress?: Address): EventsSubscription { return new EventsSubscription( this.wsc, diff --git a/packages/net/src/thor/subscriptions/NewTransactionSubscription.ts b/packages/net/src/thor/subscriptions/NewTransactionSubscription.ts index 5a962ef38..8ef59755c 100644 --- a/packages/net/src/thor/subscriptions/NewTransactionSubscription.ts +++ b/packages/net/src/thor/subscriptions/NewTransactionSubscription.ts @@ -7,7 +7,7 @@ class NewTransactionSubscription { static readonly PATH: HttpPath = { path: '/subscriptions/txpool' }; - private readonly messageListeners: Array> = []; + private readonly listeners: Array> = []; private readonly wsc: WebSocketClient; @@ -15,8 +15,8 @@ class NewTransactionSubscription this.wsc = wsc; } - addMessageListener(listener: WebSocketListener): this { - this.messageListeners.push(listener); + addListener(listener: WebSocketListener): this { + this.listeners.push(listener); return this; } @@ -33,18 +33,41 @@ class NewTransactionSubscription return this; } + onClose(event: Event): void { + this.listeners.forEach((listener) => { + listener.onClose(event); + }); + } + + onError(event: Event): void { + this.listeners.forEach((listener) => { + listener.onError(event); + }); + } + onMessage(event: MessageEvent): void { const json = JSON.parse(event.data as string) as TXIDJSON; const message = new MessageEvent(event.type, { data: new TXID(json) }); - this.messageListeners.forEach((listener) => { + this.listeners.forEach((listener) => { listener.onMessage(message); }); } + onOpen(event: Event): void { + this.listeners.forEach((listener) => { + listener.onOpen(event); + }); + } + open(): this { - this.wsc.addMessageListener(this).open(NewTransactionSubscription.PATH); + this.wsc.addListener(this).open(NewTransactionSubscription.PATH); + return this; + } + + removeListener(listener: WebSocketListener): this { + this.listeners.splice(this.listeners.indexOf(listener), 1); return this; } } diff --git a/packages/net/src/thor/subscriptions/TransfersSubscription.ts b/packages/net/src/thor/subscriptions/TransfersSubscription.ts index 1d35de738..2ae670e0d 100644 --- a/packages/net/src/thor/subscriptions/TransfersSubscription.ts +++ b/packages/net/src/thor/subscriptions/TransfersSubscription.ts @@ -24,7 +24,7 @@ class TransfersSubscription this.query = query; } - addMessageListener( + addListener( listener: WebSocketListener ): this { this.messageListeners.push(listener); @@ -59,7 +59,7 @@ class TransfersSubscription open(): this { this.wsc - .addMessageListener(this) + .addListener(this) .open({ path: TransfersSubscription.PATH.path + this.query.query }); return this; } diff --git a/packages/net/src/ws/MozillaWebSocketClient.ts b/packages/net/src/ws/MozillaWebSocketClient.ts index 5b2fa74dd..74e2929e1 100644 --- a/packages/net/src/ws/MozillaWebSocketClient.ts +++ b/packages/net/src/ws/MozillaWebSocketClient.ts @@ -7,14 +7,14 @@ class MozillaWebSocketClient implements WebSocketClient { private ws?: WebSocket; - private readonly messageListeners: Array> = []; + private readonly listeners: Array> = []; constructor(baseURL: string) { this.baseURL = baseURL; } - addMessageListener(listener: WebSocketListener): this { - this.messageListeners.push(listener); + addListener(listener: WebSocketListener): this { + this.listeners.push(listener); return this; } @@ -27,11 +27,32 @@ class MozillaWebSocketClient implements WebSocketClient { open(path: HttpPath): this { this.close(); this.ws = new WebSocket(this.baseURL + path.path); + this.ws.onopen = (event: Event) => { + this.listeners.forEach((listener) => { + listener.onOpen?.(event); + }); + }; + this.ws.onerror = (event: Event) => { + this.listeners.forEach((listener) => { + listener.onError?.(event); + }); + }; this.ws.onmessage = (event: MessageEvent) => { - this.messageListeners.forEach((listener) => { - listener.onMessage(event); + this.listeners.forEach((listener) => { + listener.onMessage?.(event); }); }; + this.ws.onclose = (event: CloseEvent) => { + this.listeners.forEach((listener) => { + listener.onClose?.(event); + }); + this.ws = undefined; + }; + return this; + } + + removeListener(listener: WebSocketListener): this { + this.listeners.splice(this.listeners.indexOf(listener), 1); return this; } } diff --git a/packages/net/src/ws/WebSocketClient.ts b/packages/net/src/ws/WebSocketClient.ts index 1780de575..5df08ae7e 100644 --- a/packages/net/src/ws/WebSocketClient.ts +++ b/packages/net/src/ws/WebSocketClient.ts @@ -4,13 +4,13 @@ import { type HttpPath } from '../http'; interface WebSocketClient { get baseURL(): string; - addMessageListener: ( - listener: WebSocketListener - ) => WebSocketClient; + addListener: (listener: WebSocketListener) => WebSocketClient; close: () => WebSocketClient; open: (path: HttpPath) => WebSocketClient; + + removeListener: (listener: WebSocketListener) => WebSocketClient; } export { type WebSocketClient }; diff --git a/packages/net/src/ws/WebSocketListener.ts b/packages/net/src/ws/WebSocketListener.ts index a32dc6de1..3ca023fda 100644 --- a/packages/net/src/ws/WebSocketListener.ts +++ b/packages/net/src/ws/WebSocketListener.ts @@ -1,5 +1,8 @@ interface WebSocketListener { + onClose: (event: Event) => void; + onError: (event: Event) => void; onMessage: (event: MessageEvent) => void; + onOpen: (event: Event) => void; } export type { WebSocketListener }; diff --git a/packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts b/packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts index a4dd35713..68790d5fc 100644 --- a/packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts +++ b/packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts @@ -18,7 +18,7 @@ describe('BlocksSubscription solo tests', () => { test('data <- open', (done) => { subscription - .addMessageListener({ + .addListener({ onMessage: (message) => { const data = message.data; console.log(JSON.stringify(data, null, 2)); diff --git a/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts b/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts index d4a1ac459..92ce0007c 100644 --- a/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts +++ b/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts @@ -18,7 +18,7 @@ describe('BlocksSubscription solo tests', () => { test('data <- open', (done) => { subscription - .addMessageListener({ + .addListener({ onMessage: (message) => { const data = message.data; console.log(JSON.stringify(data, null, 2)); diff --git a/packages/net/tests/thor/subscriptions/NewTransactionSubscription.solo.test.ts b/packages/net/tests/thor/subscriptions/NewTransactionSubscription.solo.test.ts index 289409fd9..aa3af3ab7 100644 --- a/packages/net/tests/thor/subscriptions/NewTransactionSubscription.solo.test.ts +++ b/packages/net/tests/thor/subscriptions/NewTransactionSubscription.solo.test.ts @@ -18,7 +18,7 @@ describe('NewTransactionSubscription solo tests', () => { test('data <- open', (done) => { subscription - .addMessageListener({ + .addListener({ onMessage: (message) => { const data = message.data; console.log(JSON.stringify(data, null, 2)); diff --git a/packages/net/tests/ws/MozillaWebSocketClient.solo.test.ts b/packages/net/tests/ws/MozillaWebSocketClient.solo.test.ts index 47ceeb4d5..820ba56b3 100644 --- a/packages/net/tests/ws/MozillaWebSocketClient.solo.test.ts +++ b/packages/net/tests/ws/MozillaWebSocketClient.solo.test.ts @@ -9,7 +9,7 @@ describe('MozillaWebSocketClient solo tests', () => { }); test('data <- open', (done) => { - wsc.addMessageListener({ + wsc.addListener({ onMessage: (message) => { console.log(message.data); done(); From 184f59066ea1aa4f5225038d1d3ae6297c329363 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Fri, 27 Dec 2024 13:12:15 +0100 Subject: [PATCH 73/98] feat: 1484 subscriptions documenting... --- docs/diagrams/v2/net/http/http.md | 2 +- .../diagrams/v2/net/thor/accounts/accounts.md | 123 ++++++++++++++++++ .../src/thor/accounts/ExecuteCodesRequest.ts | 12 +- .../src/thor/accounts/ExecuteCodesResponse.ts | 18 ++- .../net/src/thor/accounts/InspectClauses.ts | 9 +- 5 files changed, 149 insertions(+), 15 deletions(-) create mode 100644 docs/diagrams/v2/net/thor/accounts/accounts.md diff --git a/docs/diagrams/v2/net/http/http.md b/docs/diagrams/v2/net/http/http.md index b19cb339b..d58d9c3c6 100644 --- a/docs/diagrams/v2/net/http/http.md +++ b/docs/diagrams/v2/net/http/http.md @@ -23,7 +23,7 @@ classDiagram <> onResponse(response: Response) Response } - HttpPath <-- HttpClient + HttpPath <-- "get - post" HttpClient HttpClient <|.. FetchHttpClient FetchHttpClient *--> OnRequest FetchHttpClient *--> OnResponse diff --git a/docs/diagrams/v2/net/thor/accounts/accounts.md b/docs/diagrams/v2/net/thor/accounts/accounts.md new file mode 100644 index 000000000..f0c936133 --- /dev/null +++ b/docs/diagrams/v2/net/thor/accounts/accounts.md @@ -0,0 +1,123 @@ +```mermaid +classDiagram + namespace JS { + class Array~Type~ { + <> + } + } + namespace transactions { + class Clause { + to: Address | null + value: VET + data: HexUInt + constructor(json: ClauseJSON) + toJSON() ClauseJSON + } + class ClauseJSON { + to: string | null + value: string + data: string + } + class Event { + address: Address + topics: ThorId[] + data: HexUInt + constructor(json: EventJSON) Event + toJSON() EventJSON + } + class EventJSON { + <> + address: string + topics: string[] + data: string + } + class Transfer { + sender: Address + recipient: Address + amount: VET + constructor(json: TransferJSON) Transfer + toJSON() TransferJSON + } + class TransferJSON { + <> + sender: string + recipient: string + amount: string + } + } + class ExecuteCodesRequest { + provedWork?: string + gasPayer?: Address + expiration?: UInt + blockRef?: BlockRef + clauses?: Clause[] + gas?: VTHO + gasPrice?: VTHO + caller?: Address + constructor(json: ExecuteCodesRequestJSON) ExecuteCodesRequest + toJSON() ExecuteCodesRequestJSON + } + class ExecuteCodesRequestJSON { + <> + provedWork?: string + gasPayer?: string + expiration?: number + blockRef?: string + clauses?: ClauseJSON[] + gas?: number + gasPrice?: string + caller?: string + } + class ExecuteCodeResponse { + data: HexUInt + events: Event[] + transfers: Transfer[] + gasUsed: VTHO + reverted: boolean + vmError: string + constructor(json: ExecuteCodeResponseJSON) + toJSON() ExecuteCodeResponseJSON + } + class ExecuteCodeResponseJSON { + <> + data: string + events: EventJSON[] + transfers: TransferJSON[] + gasUsed: number + reverted: boolean + vmError: string + } + class ExecuteCodesResponse { + constructor(json: ExecuteCodesResponseJSON) ExecuteCodesResponse + toJSON() ExecuteCodesResponseJSON + } + class ExecuteCodesResponseJSON { + <> + } + class ContractBytecode { + code HexUInt + constructor(json ContractBytecodeJSON) ContractBytecode + toJSON() ContractBytecodeJSON + } + class ContractBytecodeJSON { + <> + code: string + } + Array <|.. ExecuteCodesResponse + Array <|-- ExecuteCodesResponseJSON + Clause --> "new - toJSON" ClauseJSON + ContractBytecode --> "new - toJSON" ContractBytecodeJSON + Event --> "new - toJSON" EventJSON + ExecuteCodesRequest --> "new - toJSON" ExecuteCodesRequestJSON + ExecuteCodeResponse --> "new - toJSON" ExecuteCodeResponseJSON + ExecuteCodesResponse --> "new - toJSON" ExecuteCodesResponseJSON + Transfer --> "new - toJSON" TransferJSON + ExecuteCodesRequest *--> Clause + ExecuteCodesRequestJSON *--> ClauseJSON + ExecuteCodeResponse *--> Event + ExecuteCodeResponse *--> Transfer + ExecuteCodeResponseJSON *--> EventJSON + ExecuteCodeResponseJSON *--> TransferJSON + ExecuteCodesResponse *--> "ExecuteCodeResponseJSON[]" ExecuteCodeResponse + ExecuteCodesResponseJSON *--> "ExecuteCodeResponseJSON[]" ExecuteCodeResponseJSON +``` diff --git a/packages/net/src/thor/accounts/ExecuteCodesRequest.ts b/packages/net/src/thor/accounts/ExecuteCodesRequest.ts index d9a66005e..0ea2860d3 100644 --- a/packages/net/src/thor/accounts/ExecuteCodesRequest.ts +++ b/packages/net/src/thor/accounts/ExecuteCodesRequest.ts @@ -5,12 +5,12 @@ import { Address, BlockRef, Units, VTHO } from '@vechain/sdk-core'; class ExecuteCodesRequest { readonly provedWork?: string; readonly gasPayer?: Address; - expiration?: UInt; - blockRef?: BlockRef; - clauses?: Clause[]; - gas?: VTHO; - gasPrice?: VTHO; - caller?: Address; + readonly expiration?: UInt; + readonly blockRef?: BlockRef; + readonly clauses?: Clause[]; + readonly gas?: VTHO; + readonly gasPrice?: VTHO; + readonly caller?: Address; constructor(json: ExecuteCodesRequestJSON) { this.provedWork = json.provedWork; diff --git a/packages/net/src/thor/accounts/ExecuteCodesResponse.ts b/packages/net/src/thor/accounts/ExecuteCodesResponse.ts index eb522fc5d..4aa25cedf 100644 --- a/packages/net/src/thor/accounts/ExecuteCodesResponse.ts +++ b/packages/net/src/thor/accounts/ExecuteCodesResponse.ts @@ -43,7 +43,23 @@ class ExecuteCodeResponse { } } -class ExecuteCodesResponse extends Array {} +class ExecuteCodesResponse extends Array { + constructor(json: ExecuteCodesResponseJSON) { + super( + ...json.map( + (json: ExecuteCodeResponseJSON): ExecuteCodeResponse => + new ExecuteCodeResponse(json) + ) + ); + } + + toJSON(): ExecuteCodesResponseJSON { + return this.map( + (response: ExecuteCodeResponse): ExecuteCodeResponseJSON => + response.toJSON() + ) as ExecuteCodesResponseJSON; + } +} interface ExecuteCodeResponseJSON { data: string; diff --git a/packages/net/src/thor/accounts/InspectClauses.ts b/packages/net/src/thor/accounts/InspectClauses.ts index cd60e4aed..f45acd3a7 100644 --- a/packages/net/src/thor/accounts/InspectClauses.ts +++ b/packages/net/src/thor/accounts/InspectClauses.ts @@ -1,7 +1,5 @@ import { - ExecuteCodeResponse, - type ExecuteCodeResponseJSON, - type ExecuteCodesResponse, + ExecuteCodesResponse, type ExecuteCodesResponseJSON } from './ExecuteCodesResponse'; import { type ThorRequest } from '../ThorRequest'; @@ -39,10 +37,7 @@ class InspectClauses (await response.json()) as ExecuteCodesResponseJSON; return { request: this, - response: responseBody.map( - (json: ExecuteCodeResponseJSON): ExecuteCodeResponse => - new ExecuteCodeResponse(json) - ) + response: new ExecuteCodesResponse(responseBody) }; } From 0cbaabf7c9e4ca911979410b2e3c5030f6736dd4 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Fri, 27 Dec 2024 15:03:14 +0100 Subject: [PATCH 74/98] feat: 1484 subscriptions documenting... --- .../diagrams/v2/net/thor/accounts/accounts.md | 25 ++++++++++++++----- .../src/thor/accounts/GetAccountResponse.ts | 6 ++--- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/docs/diagrams/v2/net/thor/accounts/accounts.md b/docs/diagrams/v2/net/thor/accounts/accounts.md index f0c936133..c1eac5c3b 100644 --- a/docs/diagrams/v2/net/thor/accounts/accounts.md +++ b/docs/diagrams/v2/net/thor/accounts/accounts.md @@ -45,6 +45,15 @@ classDiagram amount: string } } + class ContractBytecode { + code HexUInt + constructor(json ContractBytecodeJSON) ContractBytecode + toJSON() ContractBytecodeJSON + } + class ContractBytecodeJSON { + <> + code: string + } class ExecuteCodesRequest { provedWork?: string gasPayer?: Address @@ -94,14 +103,17 @@ classDiagram class ExecuteCodesResponseJSON { <> } - class ContractBytecode { - code HexUInt - constructor(json ContractBytecodeJSON) ContractBytecode - toJSON() ContractBytecodeJSON + class GetAccountResponse { + balance: VET + energy: VTHO + hasCode: boolean + constructor(json: GetAccountResponseJSON) GetAccountResponse } - class ContractBytecodeJSON { + class GetAccountResponseJSON { <> - code: string + balance: string + energy: string + hasCode: boolean } Array <|.. ExecuteCodesResponse Array <|-- ExecuteCodesResponseJSON @@ -111,6 +123,7 @@ classDiagram ExecuteCodesRequest --> "new - toJSON" ExecuteCodesRequestJSON ExecuteCodeResponse --> "new - toJSON" ExecuteCodeResponseJSON ExecuteCodesResponse --> "new - toJSON" ExecuteCodesResponseJSON + GetAccountResponse --> "new - toJSON" GetAccountResponseJSON Transfer --> "new - toJSON" TransferJSON ExecuteCodesRequest *--> Clause ExecuteCodesRequestJSON *--> ClauseJSON diff --git a/packages/net/src/thor/accounts/GetAccountResponse.ts b/packages/net/src/thor/accounts/GetAccountResponse.ts index c3cf03b7c..fd4fc2ee8 100644 --- a/packages/net/src/thor/accounts/GetAccountResponse.ts +++ b/packages/net/src/thor/accounts/GetAccountResponse.ts @@ -1,9 +1,9 @@ import { Quantity, VET, VTHO } from '@vechain/sdk-core'; class GetAccountResponse { - balance: VET; - energy: VTHO; - hasCode: boolean; + readonly balance: VET; + readonly energy: VTHO; + readonly hasCode: boolean; constructor(json: GetAccountResponseJSON) { this.balance = VET.of(json.balance); From ab7172692214dd2f0e77f3465946339b950623a9 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Sat, 28 Dec 2024 13:24:40 +0100 Subject: [PATCH 75/98] feat: 1484 account and subscriptions documented --- .../v2/net/thor/accounts/account-module.md | 92 ------------------ .../diagrams/v2/net/thor/accounts/accounts.md | 95 +++++++++++++++++-- .../src/thor/accounts/GetStorageResponse.ts | 21 ++++ .../net/src/thor/accounts/InspectClauses.ts | 16 ++-- .../accounts/RetrieveStoragePositionValue.ts | 17 ++-- .../src/thor/accounts/StoragePositionValue.ts | 21 ---- packages/net/src/thor/accounts/index.ts | 2 +- 7 files changed, 123 insertions(+), 141 deletions(-) delete mode 100644 docs/diagrams/v2/net/thor/accounts/account-module.md create mode 100644 packages/net/src/thor/accounts/GetStorageResponse.ts delete mode 100644 packages/net/src/thor/accounts/StoragePositionValue.ts diff --git a/docs/diagrams/v2/net/thor/accounts/account-module.md b/docs/diagrams/v2/net/thor/accounts/account-module.md deleted file mode 100644 index 8ede4a548..000000000 --- a/docs/diagrams/v2/net/thor/accounts/account-module.md +++ /dev/null @@ -1,92 +0,0 @@ -```mermaid -classDiagram - class AccountDetails { - VET balance - VTHO energy - boolean hasCode - } - class CallResult { - HexUInt data - Event[] events - VTHO gasUsed - boolean reverted - Transfer[] transfers - string vmError - } - class Clause { - HexUInt data - Address to - VET value - } - class InspectedClauses { - CallResult[] callResults - } - class ContractByteCode { - HexUInt code - } - class Event { - HexUInt data - Address event - HexUInt[] topics - } - class InspectClauses { - BlockRef blockRef - Address caller - Clause[] clauses - number expiration - VTHO gas - Address gasPayer - VTHO gasPrice - string provedWork - Revision revision - } - class HttpClient { - <> - } - class RetrieveContractByteCode { - Address address - Revision revision - } - class RetrieveAccountDetails { - Address address - Revision revision - } - class RetrieveStoragePositionValue { - Address address - BlockId key - Revision revision - } - class StoragePositionValue { - UInt8Array value - } - class ThorRequest { - <> - ThorResponse askTo(HttpClient httpClient) - } - class ThorResponse { - <> - } - class Transfer { - VET amount - Address recepient - Address sender - } - Clause <--* InspectClauses - HttpClient o-- ThorRequest - InspectClauses <|-- InspectedClauses - RetrieveContractByteCode <|-- ContractByteCode - RetrieveAccountDetails <|-- AccountDetails - RetrieveStoragePositionValue <|-- StoragePositionValue - ThorRequest <|.. InspectClauses - ThorRequest <|.. RetrieveContractByteCode - ThorRequest <|.. RetrieveAccountDetails - ThorRequest <|.. RetrieveStoragePositionValue - - AccountDetails ..|> ThorResponse - CallResult *--> Event - CallResult *--> Transfer - ContractByteCode ..|> ThorResponse - InspectedClauses ..|> ThorResponse - InspectedClauses *--> CallResult - StoragePositionValue ..|> ThorResponse -``` diff --git a/docs/diagrams/v2/net/thor/accounts/accounts.md b/docs/diagrams/v2/net/thor/accounts/accounts.md index c1eac5c3b..d3d95d8e7 100644 --- a/docs/diagrams/v2/net/thor/accounts/accounts.md +++ b/docs/diagrams/v2/net/thor/accounts/accounts.md @@ -1,10 +1,27 @@ ```mermaid classDiagram + namespace http { + class HttpPath { + <> + path: string + } + } namespace JS { class Array~Type~ { <> } } + namespace thor { + class ThorRequest~RequestClass~ { + <> + askTo(httpClient: HttpClient Promise~ThorResponse~ResponseClass~~; + } + class ThorResponse~ResponseClass~ { + <> + request: ThorRequest~RequestClass~ + response: ResponseClass + } + } namespace transactions { class Clause { to: Address | null @@ -115,22 +132,82 @@ classDiagram energy: string hasCode: boolean } - Array <|.. ExecuteCodesResponse - Array <|-- ExecuteCodesResponseJSON + class GetStorageResponse { + value: ThorId + constructor(json: GetStorageResponseJSON) GetStorageResponse + toJSON() GetStorageResponseJSON + } + class GetStorageResponseJSON { + <> + value: string + } + class InspectClauses { + PATH: HttpPath$ + askTo(httpClient: HttpClient) Promise~ThorResponse~ExecuteCodesResponse~~ + of(request: ExecuteCodesRequestJSON) InspectClauses$ + withRevision(revision: Revision) InspectClauses + } + class RetrieveAccountDetails { + path: RetrieveAccountDetailsPath + askTo(httpClient: HttpClient) Promise~ThorResponse~GetAccountResponse~~ + of(address: Address) RetrieveAccountDetails$ + } + class RetrieveAccountDetailsPath { + address: Address + } + class RetrieveContractBytecode { + path: RetrieveContractBytecodePath + askTo(httpClient: HttpClient) Promise~ThorResponse~ContractBytecode~~ + of(address: Address) RetrieveContractBytecode + } + class RetrieveContractBytecodePath { + address: Address + } + class RetrieveStoragePositionValue { + path: RetrieveStoragePositionValuePath + askTo(httpClient: HttpClient) Promise~ThorResponse~GetStorageResponse~~ + of(address: Address, key: BlockId) RetrieveStoragePositionValue$ + } + class RetrieveStoragePositionValuePath { + address: Address + key: BlockId + } Clause --> "new - toJSON" ClauseJSON ContractBytecode --> "new - toJSON" ContractBytecodeJSON Event --> "new - toJSON" EventJSON - ExecuteCodesRequest --> "new - toJSON" ExecuteCodesRequestJSON - ExecuteCodeResponse --> "new - toJSON" ExecuteCodeResponseJSON - ExecuteCodesResponse --> "new - toJSON" ExecuteCodesResponseJSON - GetAccountResponse --> "new - toJSON" GetAccountResponseJSON - Transfer --> "new - toJSON" TransferJSON - ExecuteCodesRequest *--> Clause - ExecuteCodesRequestJSON *--> ClauseJSON ExecuteCodeResponse *--> Event ExecuteCodeResponse *--> Transfer + ExecuteCodeResponse --> "new - toJSON" ExecuteCodeResponseJSON ExecuteCodeResponseJSON *--> EventJSON ExecuteCodeResponseJSON *--> TransferJSON + ExecuteCodeResponseJSON --|> Array + ExecuteCodesRequest *--> Clause + ExecuteCodesRequest --> "new - toJSON" ExecuteCodesRequestJSON + ExecuteCodesRequestJSON *--> ClauseJSON ExecuteCodesResponse *--> "ExecuteCodeResponseJSON[]" ExecuteCodeResponse + ExecuteCodesResponse --> "new - toJSON" ExecuteCodesResponseJSON + ExecuteCodesResponse ..|> Array ExecuteCodesResponseJSON *--> "ExecuteCodeResponseJSON[]" ExecuteCodeResponseJSON + GetAccountResponse --> "new - toJSON" GetAccountResponseJSON + GetStorageResponse --> "new - toJSON" GetStorageResponseJSON + InspectClauses --> "askTo" ExecuteCodesResponse + RetrieveAccountDetails *--> RetrieveAccountDetailsPath + RetrieveAccountDetails --> "askTo" GetAccountResponse + RetrieveAccountDetailsPath ..|> HttpPath + RetrieveContractBytecode *--> RetrieveContractBytecodePath + RetrieveContractBytecode --> "askTo" ContractBytecode + RetrieveContractBytecodePath ..|> HttpPath + RetrieveStoragePositionValue *--> RetrieveStoragePositionValuePath + RetrieveStoragePositionValue --> "askTo" GetStorageResponse + RetrieveStoragePositionValuePath ..|> HttpPath + ThorRequest <--* ThorResponse + ThorRequest <|.. InspectClauses + ThorRequest <|.. RetrieveAccountDetails + ThorRequest <|.. RetrieveContractBytecode + ThorRequest <|.. RetrieveStoragePositionValue + ThorResponse <-- "askTo" InspectClauses + ThorResponse <-- "askTo" RetrieveAccountDetails + ThorResponse <-- "askTo" RetrieveContractBytecode + ThorResponse <-- "askTo" RetrieveStoragePositionValue + Transfer --> "new - toJSON" TransferJSON ``` diff --git a/packages/net/src/thor/accounts/GetStorageResponse.ts b/packages/net/src/thor/accounts/GetStorageResponse.ts new file mode 100644 index 000000000..406ba6b2d --- /dev/null +++ b/packages/net/src/thor/accounts/GetStorageResponse.ts @@ -0,0 +1,21 @@ +import { ThorId } from '@vechain/sdk-core'; + +class GetStorageResponse { + readonly value: ThorId; + + constructor(json: GetStorageResponseJSON) { + this.value = ThorId.of(json.value); + } + + toJSON(): GetStorageResponseJSON { + return { + value: this.value.toString() + } satisfies GetStorageResponseJSON; + } +} + +interface GetStorageResponseJSON { + value: string; +} + +export { GetStorageResponse, type GetStorageResponseJSON }; diff --git a/packages/net/src/thor/accounts/InspectClauses.ts b/packages/net/src/thor/accounts/InspectClauses.ts index f45acd3a7..c976271d9 100644 --- a/packages/net/src/thor/accounts/InspectClauses.ts +++ b/packages/net/src/thor/accounts/InspectClauses.ts @@ -16,9 +16,9 @@ class InspectClauses { static readonly PATH: HttpPath = { path: '/accounts/*' }; - readonly query: InspectClauseQuery; + private readonly query: InspectClauseQuery; - readonly request: ExecuteCodesRequest; + private readonly request: ExecuteCodesRequest; constructor(query: InspectClauseQuery, request: ExecuteCodesRequest) { this.query = query; @@ -41,17 +41,17 @@ class InspectClauses }; } - withRevision(revision: Revision = Revision.BEST): InspectClauses { + static of(request: ExecuteCodesRequestJSON): InspectClauses { return new InspectClauses( - new InspectClauseQuery(revision), - this.request + new InspectClauseQuery(Revision.BEST), + new ExecuteCodesRequest(request) ); } - static of(request: ExecuteCodesRequestJSON): InspectClauses { + withRevision(revision: Revision = Revision.BEST): InspectClauses { return new InspectClauses( - new InspectClauseQuery(Revision.BEST), - new ExecuteCodesRequest(request) + new InspectClauseQuery(revision), + this.request ); } } diff --git a/packages/net/src/thor/accounts/RetrieveStoragePositionValue.ts b/packages/net/src/thor/accounts/RetrieveStoragePositionValue.ts index b97d27a35..19ed82d6a 100644 --- a/packages/net/src/thor/accounts/RetrieveStoragePositionValue.ts +++ b/packages/net/src/thor/accounts/RetrieveStoragePositionValue.ts @@ -2,13 +2,13 @@ import { type HttpClient, type HttpPath } from '../../http'; import { type Address, type BlockId } from '@vechain/sdk-core'; import { type ThorRequest } from '../ThorRequest'; import { - StoragePositionValue, - type StoragePositionValueJSON -} from './StoragePositionValue'; + GetStorageResponse, + type GetStorageResponseJSON +} from './GetStorageResponse'; import { type ThorResponse } from '../ThorResponse'; class RetrieveStoragePositionValue - implements ThorRequest + implements ThorRequest { readonly path: RetrieveStoragePositionValuePath; @@ -18,15 +18,12 @@ class RetrieveStoragePositionValue async askTo( httpClient: HttpClient - ): Promise< - ThorResponse - > { + ): Promise> { const response = await httpClient.get(this.path, { query: '' }); - const responseBody = - (await response.json()) as StoragePositionValueJSON; + const responseBody = (await response.json()) as GetStorageResponseJSON; return { request: this, - response: new StoragePositionValue(responseBody) + response: new GetStorageResponse(responseBody) }; } diff --git a/packages/net/src/thor/accounts/StoragePositionValue.ts b/packages/net/src/thor/accounts/StoragePositionValue.ts deleted file mode 100644 index cadcba02a..000000000 --- a/packages/net/src/thor/accounts/StoragePositionValue.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { HexUInt } from '@vechain/sdk-core'; - -interface StoragePositionValueJSON { - value: string; -} - -class StoragePositionValue { - readonly value: HexUInt; - - constructor(json: StoragePositionValueJSON) { - this.value = HexUInt.of(json.value); - } - - toJSON(): StoragePositionValueJSON { - return { - value: this.value.toString() - }; - } -} - -export { StoragePositionValue, type StoragePositionValueJSON }; diff --git a/packages/net/src/thor/accounts/index.ts b/packages/net/src/thor/accounts/index.ts index 8aa27ad35..bed432f86 100644 --- a/packages/net/src/thor/accounts/index.ts +++ b/packages/net/src/thor/accounts/index.ts @@ -6,4 +6,4 @@ export * from './InspectClauses'; export * from './RetrieveAccountDetails'; export * from './RetrieveContractBytecode'; export * from './RetrieveStoragePositionValue'; -export * from './StoragePositionValue'; +export * from './GetStorageResponse'; From e0c98c3a3b96e8536514b0a65aae85c1c9defe5a Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Sat, 28 Dec 2024 18:26:47 +0100 Subject: [PATCH 76/98] feat: 1484 blocks documented --- .../v2/net/thor/blocks/blocks-module.md | 56 --------- docs/diagrams/v2/net/thor/blocks/blocks.md | 77 ++++++++++++ .../src/thor/blocks/RegularBlockResponse..ts | 114 +++++++++++------- packages/net/src/thor/explorer/index.ts | 2 +- .../thor/blocks/RetrieveBlock.testnet.test.ts | 2 +- 5 files changed, 151 insertions(+), 100 deletions(-) delete mode 100644 docs/diagrams/v2/net/thor/blocks/blocks-module.md create mode 100644 docs/diagrams/v2/net/thor/blocks/blocks.md diff --git a/docs/diagrams/v2/net/thor/blocks/blocks-module.md b/docs/diagrams/v2/net/thor/blocks/blocks-module.md deleted file mode 100644 index 4c06f5415..000000000 --- a/docs/diagrams/v2/net/thor/blocks/blocks-module.md +++ /dev/null @@ -1,56 +0,0 @@ -```mermaid -classDiagram - class HttpClient { - <> - } - class ThorRequest~Request~ { - <> - ThorResponse~Request~ askTo(HttpClient httpClient) - } - class ThorResponse~Response~ { - <> - ThorRequest~Request~ request - Response response - } - namespace Request { - class RetrieveBlock { - Revision revision - RetrieveBlock_Query - } - class RetrieveBlock_Query { - boolean expanded - } - } - namespace Response { - class RegularBlockResponse { - number integer - HexUInt id - number size - HexHUInt parentID - number timestamp - VTHO gasLimit - Address benificiary - VTHO gasUsed - number totalScore - HexUInt txsRoot - number txsFeatures - HexUInt stateRoot - HexUInt receiptRoot - boolean com - Address signer - boolean isTrunk - boolean isFinalized - HexUInt[] transactions - } - } - - HttpClient o-- ThorRequest - ThorRequest <|.. RetrieveBlock - ThorResponse <|.. RegularBlockResponse - - ThorRequest --* ThorResponse - - RetrieveBlock --* RetrieveBlock_Query - - RetrieveBlock <..> RegularBlockResponse -``` diff --git a/docs/diagrams/v2/net/thor/blocks/blocks.md b/docs/diagrams/v2/net/thor/blocks/blocks.md new file mode 100644 index 000000000..f8c59bd16 --- /dev/null +++ b/docs/diagrams/v2/net/thor/blocks/blocks.md @@ -0,0 +1,77 @@ +```mermaid +classDiagram + namespace http { + class HttpPath { + <> + path: string + } + } + namespace thor { + class ThorRequest~RequestClass~ { + <> + askTo(httpClient: HttpClient Promise~ThorResponse~ResponseClass~~; + } + class ThorResponse~ResponseClass~ { + <> + request: ThorRequest~RequestClass~ + response: ResponseClass + } + } + class RegularBlockResponse { + number: UInt + id: ThorId + size: UInt + parentID: ThorId + timestamp: bigint + gasLimit: VTHO + beneficiary: Address + gasUsed: VTHO + totalScore: UInt + txsRoot: ThorId + txsFeatures: UInt + stateRoot: ThorId + receiptsRoot: ThorId + com: boolean + signer: Address + isTrunk: boolean + isFinalized: boolean + transactions: ThorId[] + constructor(json: RegularBlockResponseJSON) RegularBlockResponse + toJSON() RegularBlockResponseJSON + } + class RegularBlockResponseJSON { + <> + number: number + id: string + size: number + parentID: string + timestamp: bigint + gasLimit: number + beneficiary: string + gasUsed: number + totalScore: number + txsRoot: string + txsFeatures: number + stateRoot: string + receiptsRoot: string + com: boolean + signer: string + isTrunk: boolean + isFinalized: boolean + transactions: string[] + } + class RetrieveBlock { + path: RetrieveBlockPath + askTo(httpClient: HttpClient) Promise~ThorResponse~RegularBlockResponse~~ + of(revision: Revision) RetrieveBlock$ + } + class RetrieveBlockPath { + revision: Revision + } + HttpPath <|.. RetrieveBlockPath + RegularBlockResponse --> "new - toJSON" RegularBlockResponseJSON + ThorRequest <|.. RetrieveBlock + ThorResponse <-- "askTo" RetrieveBlock + RetrieveBlock --> "askTo" RegularBlockResponse + RetrieveBlock *--> RetrieveBlockPath +``` diff --git a/packages/net/src/thor/blocks/RegularBlockResponse..ts b/packages/net/src/thor/blocks/RegularBlockResponse..ts index c4e72a9e7..971fec0fc 100644 --- a/packages/net/src/thor/blocks/RegularBlockResponse..ts +++ b/packages/net/src/thor/blocks/RegularBlockResponse..ts @@ -1,3 +1,75 @@ +import { Address, ThorId, Units, VTHO } from '@vechain/sdk-core'; +import { UInt } from '../../../../core'; + +class RegularBlockResponse { + readonly number: UInt; + readonly id: ThorId; + readonly size: UInt; + readonly parentID: ThorId; + readonly timestamp: bigint; + readonly gasLimit: VTHO; + readonly beneficiary: Address; + readonly gasUsed: VTHO; + readonly totalScore: UInt; + readonly txsRoot: ThorId; + readonly txsFeatures: UInt; + readonly stateRoot: ThorId; + readonly receiptsRoot: ThorId; + readonly com: boolean; + readonly signer: Address; + readonly isTrunk: boolean; + readonly isFinalized: boolean; + readonly transactions: ThorId[]; + + constructor(json: RegularBlockResponseJSON) { + this.number = UInt.of(json.number); + this.id = ThorId.of(json.id); + this.size = UInt.of(json.size); + this.parentID = ThorId.of(json.parentID); + this.timestamp = json.timestamp; + this.gasLimit = VTHO.of(json.gasLimit, Units.wei); + this.beneficiary = Address.of(json.beneficiary); + this.gasUsed = VTHO.of(json.gasUsed, Units.wei); + this.totalScore = UInt.of(json.totalScore); + this.txsRoot = ThorId.of(json.txsRoot); + this.txsFeatures = UInt.of(json.txsFeatures); + this.stateRoot = ThorId.of(json.stateRoot); + this.receiptsRoot = Address.of(json.receiptsRoot); + this.com = json.com; + this.signer = Address.of(json.signer); + this.isTrunk = json.isTrunk; + this.isFinalized = json.isFinalized; + this.transactions = json.transactions.map( + (txId: string): ThorId => ThorId.of(txId) + ); + } + + toJSON(): RegularBlockResponseJSON { + return { + number: this.number.valueOf(), + id: this.id.toString(), + size: this.size.valueOf(), + parentID: this.parentID.toString(), + timestamp: this.timestamp, + gasLimit: Number(this.gasLimit.wei), + beneficiary: this.beneficiary.toString(), + gasUsed: Number(this.gasUsed.wei), + totalScore: this.totalScore.valueOf(), + txsRoot: this.txsRoot.toString(), + txsFeatures: this.txsFeatures.valueOf(), + stateRoot: this.stateRoot.toString(), + receiptsRoot: this.receiptsRoot.toString(), + com: this.com, + signer: this.signer.toString(), + isTrunk: this.isTrunk, + isFinalized: this.isFinalized, + transactions: this.transactions.map((txId: ThorId) => + txId.toString() + ) + } satisfies RegularBlockResponseJSON; + } +} + interface RegularBlockResponseJSON { number: number; id: string; @@ -19,46 +91,4 @@ interface RegularBlockResponseJSON { transactions: string[]; } -class RegularBlockResponse { - readonly number: number; - readonly id: string; - readonly size: number; - readonly parentID: string; - readonly timestamp: bigint; - readonly gasLimit: number; - readonly beneficiary: string; - readonly gasUsed: number; - readonly totalScore: number; - readonly txsRoot: string; - readonly txsFeatures: number; - readonly stateRoot: string; - readonly receiptsRoot: string; - readonly com: boolean; - readonly signer: string; - readonly isTrunk: boolean; - readonly isFinalized: boolean; - readonly transactions: string[]; - - constructor(json: RegularBlockResponseJSON) { - this.number = json.number; - this.id = json.id; - this.size = json.size; - this.parentID = json.parentID; - this.timestamp = json.timestamp; - this.gasLimit = json.gasLimit; - this.beneficiary = json.beneficiary; - this.gasUsed = json.gasUsed; - this.totalScore = json.totalScore; - this.txsRoot = json.txsRoot; - this.txsFeatures = json.txsFeatures; - this.stateRoot = json.stateRoot; - this.receiptsRoot = json.receiptsRoot; - this.com = json.com; - this.signer = json.signer; - this.isTrunk = json.isTrunk; - this.isFinalized = json.isFinalized; - this.transactions = json.transactions; - } -} - export { RegularBlockResponse, type RegularBlockResponseJSON }; diff --git a/packages/net/src/thor/explorer/index.ts b/packages/net/src/thor/explorer/index.ts index 3c1a09d73..5901382ba 100644 --- a/packages/net/src/thor/explorer/index.ts +++ b/packages/net/src/thor/explorer/index.ts @@ -12,7 +12,7 @@ async function getBestBlockNumber( const r = await new RetrieveBlock( new RetrieveBlockPath(Revision.BEST) ).askTo(httpClient); - return r.response.number; + return r.response.number.valueOf(); } async function explore(): Promise { diff --git a/packages/net/tests/thor/blocks/RetrieveBlock.testnet.test.ts b/packages/net/tests/thor/blocks/RetrieveBlock.testnet.test.ts index e26fdf730..4dfc3a4f0 100644 --- a/packages/net/tests/thor/blocks/RetrieveBlock.testnet.test.ts +++ b/packages/net/tests/thor/blocks/RetrieveBlock.testnet.test.ts @@ -40,6 +40,6 @@ describe('RetrieveBlock testnet tests', () => { const r = await new RetrieveBlock( new RetrieveBlockPath(Revision.BEST) ).askTo(httpClient); - return r.response.number; + return r.response.number.valueOf(); } }); From bbe0bcf9f826e032d6e5c9d3342ab013ed479793 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Sat, 28 Dec 2024 18:33:30 +0100 Subject: [PATCH 77/98] feat: 1484 blocks documented --- packages/net/src/thor/explorer/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/net/src/thor/explorer/index.ts b/packages/net/src/thor/explorer/index.ts index 5901382ba..21fb5819e 100644 --- a/packages/net/src/thor/explorer/index.ts +++ b/packages/net/src/thor/explorer/index.ts @@ -26,9 +26,9 @@ async function explore(): Promise { for (const txid of block.transactions) { console.log(`TXID ${txid}`); const tx = ( - await RetrieveTransactionByID.of(TxId.of(txid)).askTo( - httpClient - ) + await RetrieveTransactionByID.of( + TxId.of(txid.toString()) + ).askTo(httpClient) ).response; console.log(`TX: ${JSON.stringify(tx, null, 2)}`); From 2ce7e996dfe607f6a58eba197fcfcbfd351bec15 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Sat, 28 Dec 2024 18:42:50 +0100 Subject: [PATCH 78/98] feat: 1484 blocks documented --- docs/diagrams/v2/net/thor/blocks/blocks.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/diagrams/v2/net/thor/blocks/blocks.md b/docs/diagrams/v2/net/thor/blocks/blocks.md index f8c59bd16..5b757e0d3 100644 --- a/docs/diagrams/v2/net/thor/blocks/blocks.md +++ b/docs/diagrams/v2/net/thor/blocks/blocks.md @@ -68,10 +68,11 @@ classDiagram class RetrieveBlockPath { revision: Revision } - HttpPath <|.. RetrieveBlockPath + RetrieveBlockPath --|> HttpPath RegularBlockResponse --> "new - toJSON" RegularBlockResponseJSON ThorRequest <|.. RetrieveBlock ThorResponse <-- "askTo" RetrieveBlock RetrieveBlock --> "askTo" RegularBlockResponse RetrieveBlock *--> RetrieveBlockPath + ThorRequest <--* ThorResponse ``` From f8fd51b1a1479a969ed684cced8d6bc1e9a979ec Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Sat, 28 Dec 2024 18:57:11 +0100 Subject: [PATCH 79/98] feat: 1484 blocks documented --- docs/diagrams/v2/net/thor/accounts/accounts.md | 10 ++++++++++ docs/diagrams/v2/net/thor/blocks/blocks.md | 15 +++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/docs/diagrams/v2/net/thor/accounts/accounts.md b/docs/diagrams/v2/net/thor/accounts/accounts.md index d3d95d8e7..0f274fea3 100644 --- a/docs/diagrams/v2/net/thor/accounts/accounts.md +++ b/docs/diagrams/v2/net/thor/accounts/accounts.md @@ -1,6 +1,11 @@ ```mermaid classDiagram namespace http { + class HttpClient { + <> + get(httpPath: HttpPath) Promise~Response~ + post(httpPath: HttpPath, body?: unknown) Promise~Response~ + } class HttpPath { <> path: string @@ -190,15 +195,20 @@ classDiagram ExecuteCodesResponseJSON *--> "ExecuteCodeResponseJSON[]" ExecuteCodeResponseJSON GetAccountResponse --> "new - toJSON" GetAccountResponseJSON GetStorageResponse --> "new - toJSON" GetStorageResponseJSON + HttpPath <-- "get - post" HttpClient InspectClauses --> "askTo" ExecuteCodesResponse + InspectClauses --> "askTo" HttpClient RetrieveAccountDetails *--> RetrieveAccountDetailsPath RetrieveAccountDetails --> "askTo" GetAccountResponse + RetrieveAccountDetails --> "askTo" HttpClient RetrieveAccountDetailsPath ..|> HttpPath RetrieveContractBytecode *--> RetrieveContractBytecodePath RetrieveContractBytecode --> "askTo" ContractBytecode + RetrieveContractBytecode --> "askTo" HttpClient RetrieveContractBytecodePath ..|> HttpPath RetrieveStoragePositionValue *--> RetrieveStoragePositionValuePath RetrieveStoragePositionValue --> "askTo" GetStorageResponse + RetrieveStoragePositionValue --> "askTo" HttpClient RetrieveStoragePositionValuePath ..|> HttpPath ThorRequest <--* ThorResponse ThorRequest <|.. InspectClauses diff --git a/docs/diagrams/v2/net/thor/blocks/blocks.md b/docs/diagrams/v2/net/thor/blocks/blocks.md index 5b757e0d3..456304dcf 100644 --- a/docs/diagrams/v2/net/thor/blocks/blocks.md +++ b/docs/diagrams/v2/net/thor/blocks/blocks.md @@ -1,6 +1,11 @@ ```mermaid classDiagram namespace http { + class HttpClient { + <> + get(httpPath: HttpPath) Promise~Response~ + post(httpPath: HttpPath, body?: unknown) Promise~Response~ + } class HttpPath { <> path: string @@ -68,11 +73,13 @@ classDiagram class RetrieveBlockPath { revision: Revision } - RetrieveBlockPath --|> HttpPath + HttpPath <-- "get - post" HttpClient RegularBlockResponse --> "new - toJSON" RegularBlockResponseJSON - ThorRequest <|.. RetrieveBlock - ThorResponse <-- "askTo" RetrieveBlock - RetrieveBlock --> "askTo" RegularBlockResponse RetrieveBlock *--> RetrieveBlockPath + RetrieveBlock --> "askTo" HttpClient + RetrieveBlock --> "askTo" RegularBlockResponse + RetrieveBlockPath --|> HttpPath ThorRequest <--* ThorResponse + ThorRequest <|.. RetrieveBlock + ThorResponse <-- "askTo" RetrieveBlock ``` From d3b495da1bbffc3a7e7d257f8212151ba7de123c Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Sun, 29 Dec 2024 14:20:08 +0100 Subject: [PATCH 80/98] feat: 1484 debug documented --- docs/diagrams/v2/net/thor/debug/_debug.md | 135 ++++++++++++++++ docs/diagrams/v2/net/thor/debug/debug.md | 169 ++++++++++++++------ packages/net/src/thor/debug/StorageRange.ts | 4 +- packages/net/src/thor/debug/TracerName.ts | 22 +-- 4 files changed, 269 insertions(+), 61 deletions(-) create mode 100644 docs/diagrams/v2/net/thor/debug/_debug.md diff --git a/docs/diagrams/v2/net/thor/debug/_debug.md b/docs/diagrams/v2/net/thor/debug/_debug.md new file mode 100644 index 000000000..395975705 --- /dev/null +++ b/docs/diagrams/v2/net/thor/debug/_debug.md @@ -0,0 +1,135 @@ +```mermaid +classDiagram + class PostDebugTracerCallRequest { + name?: TracerName + config?: unknown + value: VET + data: HexUInt + to?: Address + gas?: VTHO + gasPrice?: VTHO + caller?: Address + provedWork?: string + gasPayer?: Address + expiration?: UInt + blockRef?: BlockRef + constructor(json: PostDebugTracerCallRequestJSON) + toJSON() PostDebugTracerCallRequestJSON + } + class PostDebugTracerCallRequestJSON { + <> + name?: string + config?: unknown + value: string + data: string + to?: string + gas?: number + gasPrice?: string + caller?: string + provedWork?: string + gasPayer?: string + expiration?: number + blockRef?: string + } + class PostDebugTracerRequest { + name?: TracerName + config?: unknown + target: string + constructor(json PostDebugTracerRequestJSON) + toJSON() PostDebugTracerRequestJSON + } + class PostDebugTracerRequestJSON { + <> + name?: string + config?: unknown + target: string + } + class RetrieveStorageRange { + PATH: HttpPath$ + request: StorageRangeOption + constructor(request: StorageRangeOption) + askTo(httpClient: HttpClient) Promise~ThorResponse~StorageRange~~ + of(request: StorageRangeOptionJSON) RetrieveStorageRange$ + } + class StorageRange { + nextKey?: ThorId + storage: unknown + constructor(json StorageRangeJSON) + toJSON() StorageRangeJSON + } + class StorageRangeJSON { + <> + nextKey?: string + storage: string + } + class StorageRangeOptions { + address: Address + keyStart?: ThorId + maxResult?: UInt + target: string + constructor(json: StorageRangeOptionJSON) + toJSON() StorageRangeOptionJSON + } + class StorageRangeOptionJSON { + <> + address: string + keyStart?: string + maxResult?: number + target: string + } + class TraceCall { + PATH: HttpPath$ + request: PostDebugTracerCallRequest + constructor(request: request: PostDebugTracerCallRequest) + askTo(httpClient: HttpClient) Promise~ThorResponse~undefined~~ + of(request: PostDebugTracerCallRequestJSON): TraceCall$ + } + class TraceTransactionClause { + PATH: HttpPath$ + request: PostDebugTracerRequest + constructor(request: PostDebugTracerRequest) + askTo(httpClient: HttpClient) Promise~ThorResponse~unknown~ + of(request: PostDebugTracerRequestJSON): TraceTransactionClause$ + } + class TracerName { + <> + } + namespace thor { + class ThorRequest { + <> + askTo: (httpClient: HttpClient) Promise~ThorResponse~ResponseClass~~ + } + class ThorResponse { + <> + request: ~RequestClass~; + response: ~ResponseClass~; + } + } + PostDebugTracerCallRequestJSON <-- PostDebugTracerCallRequest + PostDebugTracerRequestJSON <-- PostDebugTracerRequest + StorageRange <-- RetrieveStorageRange + StorageRangeJSON <-- StorageRange + StorageRangeOptionJSON <-- StorageRangeOptions + ThorResponse <-- RetrieveStorageRange + ThorResponse <-- TraceCall + ThorResponse <-- TraceTransactionClause + ThorRequest <|.. RetrieveStorageRange + ThorRequest <|.. TraceCall + ThorRequest <|.. TraceTransactionClause + TracerName <|-- StructLogger + TracerName <|-- FourByte + TracerNname <|-- Call + TracerName <|-- Noop + TracerName <|-- Prestate + TracerName <|-- Unigram + TracerName <|-- Bigram + TracerName <|-- Trigram + TracerName <|-- EvmDis + TracerName <|-- OpCount + TracerName <|-- Null + RetrieveStorageRange *--> StorageRangeOptions + PostDebugTracerCallRequest *--> TracerName + PostDebugTracerRequest *--> TracerName + TraceCall *--> PostDebugTracerCallRequest + TraceTransactionClause *--> PostDebugTracerRequest +``` diff --git a/docs/diagrams/v2/net/thor/debug/debug.md b/docs/diagrams/v2/net/thor/debug/debug.md index 395975705..5f2e1d658 100644 --- a/docs/diagrams/v2/net/thor/debug/debug.md +++ b/docs/diagrams/v2/net/thor/debug/debug.md @@ -1,5 +1,53 @@ ```mermaid classDiagram + namespace http { + class HttpClient { + <> + get(httpPath: HttpPath) Promise~Response~ + post(httpPath: HttpPath, body?: unknown) Promise~Response~ + } + class HttpPath { + <> + path: string + } + } + namespace JS { + class unknown { + <> + } + } + namespace thor { + class ThorRequest~RequestClass~ { + <> + askTo(httpClient: HttpClient Promise~ThorResponse~ResponseClass~~ + } + class ThorResponse~ResponseClass~ { + <> + request: ThorRequest~RequestClass~ + response: ResponseClass + } + } + class Bigram { + NAME: string$ + } + class Call { + NAME: string$ + } + class EvmDis { + NAME: string$ + } + class FourByte { + NAME: string$ + } + class Noop { + NAME: string$ + } + class Null { + NAME: string$ + } + class OpCount { + NAME: string$ + } class PostDebugTracerCallRequest { name?: TracerName config?: unknown @@ -13,7 +61,7 @@ classDiagram gasPayer?: Address expiration?: UInt blockRef?: BlockRef - constructor(json: PostDebugTracerCallRequestJSON) + constructor(json: PostDebugTracerCallRequestJSON) PostDebugTracerCallRequest toJSON() PostDebugTracerCallRequestJSON } class PostDebugTracerCallRequestJSON { @@ -35,7 +83,7 @@ classDiagram name?: TracerName config?: unknown target: string - constructor(json PostDebugTracerRequestJSON) + constructor(json: PostDebugTracerRequestJSON) PostDebugTracerRequest toJSON() PostDebugTracerRequestJSON } class PostDebugTracerRequestJSON { @@ -44,31 +92,31 @@ classDiagram config?: unknown target: string } + class Presate { + NAME: string$ + } class RetrieveStorageRange { PATH: HttpPath$ request: StorageRangeOption - constructor(request: StorageRangeOption) - askTo(httpClient: HttpClient) Promise~ThorResponse~StorageRange~~ + askTo(httpClient: HttpClient): Promise~ThorResponse~StorageRange~~ of(request: StorageRangeOptionJSON) RetrieveStorageRange$ } class StorageRange { nextKey?: ThorId storage: unknown - constructor(json StorageRangeJSON) + constructor(json: StorageRangeJSON) StorageRange toJSON() StorageRangeJSON - } + } class StorageRangeJSON { <> nextKey?: string - storage: string + storage: unknown } - class StorageRangeOptions { + class StorageRangeOption { address: Address keyStart?: ThorId maxResult?: UInt target: string - constructor(json: StorageRangeOptionJSON) - toJSON() StorageRangeOptionJSON } class StorageRangeOptionJSON { <> @@ -77,59 +125,84 @@ classDiagram maxResult?: number target: string } + class StructLogger { + NAME: string$ + } class TraceCall { PATH: HttpPath$ request: PostDebugTracerCallRequest - constructor(request: request: PostDebugTracerCallRequest) - askTo(httpClient: HttpClient) Promise~ThorResponse~undefined~~ - of(request: PostDebugTracerCallRequestJSON): TraceCall$ + askTo(httpClient: HttpClient): Promise~ThorResponse~unknown~~ + of(request: PostDebugTracerCallRequestJSON) TraceCall$ + } + class Tracer { + of(name: string): TracerName$ + } + class TracerName { + <> + toString: string } class TraceTransactionClause { PATH: HttpPath$ request: PostDebugTracerRequest - constructor(request: PostDebugTracerRequest) - askTo(httpClient: HttpClient) Promise~ThorResponse~unknown~ - of(request: PostDebugTracerRequestJSON): TraceTransactionClause$ + askTo(httpClient: HttpClient): Promise~ThorResponse~unknown~~ + of(request: PostDebugTracerRequestJSON) TraceTransactionClause$ } - class TracerName { - <> + class Trigram { + NAME: string$ } - namespace thor { - class ThorRequest { - <> - askTo: (httpClient: HttpClient) Promise~ThorResponse~ResponseClass~~ - } - class ThorResponse { - <> - request: ~RequestClass~; - response: ~ResponseClass~; - } + class Unigram { + NAME: string$ } - PostDebugTracerCallRequestJSON <-- PostDebugTracerCallRequest - PostDebugTracerRequestJSON <-- PostDebugTracerRequest - StorageRange <-- RetrieveStorageRange - StorageRangeJSON <-- StorageRange - StorageRangeOptionJSON <-- StorageRangeOptions - ThorResponse <-- RetrieveStorageRange - ThorResponse <-- TraceCall - ThorResponse <-- TraceTransactionClause + Bigram <-- "of" Tracer + Call <-- "of" Tracer + EvmDis <-- "of" Tracer + FourByte <-- "of" Tracer + HttpPath <-- "get - post" HttpClient + Noop <-- "of" Tracer + Null <-- "of" Tracer + OpCount <-- "of" Tracer + PostDebugTracerCallRequest *--> TracerName + PostDebugTracerCallRequest --> "new - toJSON" PostDebugTracerCallRequestJSON + PostDebugTracerRequest *--> TracerName + PostDebugTracerRequest --> "new - toJSON" PostDebugTracerRequestJSON + Presate <-- "of" Tracer + Prestate <-- "of" Tracer + RetrieveStorageRange *-- HttpPath + RetrieveStorageRange *-- StorageRangeOption + RetrieveStorageRange --> "askTo" HttpClient + RetrieveStorageRange --> "askTo" StorageRange + RetrieveStorageRange --> "of" StorageRangeOptionJSON + StorageRange --> "new - toJSON" StorageRangeJSON + StorageRangeOption --> "new - toJSON" StorageRangeOptionJSON + StructLogger <-- "of" Tracer + ThorRequest <--* ThorResponse ThorRequest <|.. RetrieveStorageRange ThorRequest <|.. TraceCall ThorRequest <|.. TraceTransactionClause - TracerName <|-- StructLogger + ThorResponse <-- "askTo" RetrieveStorageRange + ThorResponse <-- "askTo" TraceCall + TraceCall *--> HttpPath + TraceCall *--> PostDebugTracerCallRequest + TraceCall --> "askTo" HttpClient + TraceCall --> "askTo" unknown + TraceCall --> "of" PostDebugTracerCallRequestJSON + TraceTransactionClause *--> HttpPath + TraceTransactionClause *--> PostDebugTracerCallRequest + TraceTransactionClause --> "askTo" HttpClient + TraceTransactionClause --> "askTo" unknown + TraceTransactionClause --> "of" PostDebugTracerRequestJSON + TracerName <|-- Bigram + TracerName <|-- Call + TracerName <|-- EvmDis TracerName <|-- FourByte - TracerNname <|-- Call TracerName <|-- Noop + TracerName <|-- Null + TracerName <|-- OpCount + TracerName <|-- Presate TracerName <|-- Prestate - TracerName <|-- Unigram - TracerName <|-- Bigram + TracerName <|-- StructLogger TracerName <|-- Trigram - TracerName <|-- EvmDis - TracerName <|-- OpCount - TracerName <|-- Null - RetrieveStorageRange *--> StorageRangeOptions - PostDebugTracerCallRequest *--> TracerName - PostDebugTracerRequest *--> TracerName - TraceCall *--> PostDebugTracerCallRequest - TraceTransactionClause *--> PostDebugTracerRequest + TracerName <|-- Unigram + Trigram <-- "of" Tracer + Unigram <-- "of" Tracer ``` diff --git a/packages/net/src/thor/debug/StorageRange.ts b/packages/net/src/thor/debug/StorageRange.ts index 81bd8d430..363d6b799 100644 --- a/packages/net/src/thor/debug/StorageRange.ts +++ b/packages/net/src/thor/debug/StorageRange.ts @@ -2,7 +2,7 @@ import { ThorId } from '@vechain/sdk-core'; class StorageRange { readonly nextKey?: ThorId; - readonly storage: undefined; + readonly storage: unknown; constructor(json: StorageRangeJSON) { this.nextKey = @@ -20,7 +20,7 @@ class StorageRange { interface StorageRangeJSON { nextKey?: string; - storage: undefined; + storage: unknown; } export { StorageRange, type StorageRangeJSON }; diff --git a/packages/net/src/thor/debug/TracerName.ts b/packages/net/src/thor/debug/TracerName.ts index 6bc808546..2372d7ef7 100644 --- a/packages/net/src/thor/debug/TracerName.ts +++ b/packages/net/src/thor/debug/TracerName.ts @@ -2,57 +2,57 @@ abstract class TracerName { abstract toString: () => string; } -class StructLogger implements TracerName { +class StructLogger extends TracerName { static readonly NAME = 'structLogger'; toString: () => string = () => StructLogger.NAME; } -class FourByte implements TracerName { +class FourByte extends TracerName { static readonly NAME = '4byte'; toString: () => string = () => FourByte.NAME; } -class Call implements TracerName { +class Call extends TracerName { static readonly NAME = 'call'; toString: () => string = () => Call.NAME; } -class Noop implements TracerName { +class Noop extends TracerName { static readonly NAME = 'noop'; toString: () => string = () => Noop.NAME; } -class Prestate implements TracerName { +class Prestate extends TracerName { static readonly NAME = 'prestate'; toString: () => string = () => Prestate.NAME; } -class Unigram implements TracerName { +class Unigram extends TracerName { static readonly NAME = 'unigram'; toString: () => string = () => Unigram.NAME; } -class Bigram implements TracerName { +class Bigram extends TracerName { static readonly NAME = 'bigram'; toString: () => string = () => Bigram.NAME; } -class Trigram implements TracerName { +class Trigram extends TracerName { static readonly NAME = 'trigram'; toString: () => string = () => Trigram.NAME; } -class EvmDis implements TracerName { +class EvmDis extends TracerName { static readonly NAME = 'evmdis'; toString: () => string = () => EvmDis.NAME; } -class OpCount implements TracerName { +class OpCount extends TracerName { static readonly NAME = 'opcount'; toString: () => string = () => OpCount.NAME; } -class Null implements TracerName { +class Null extends TracerName { static readonly NAME = 'null'; toString: () => string = () => Null.NAME; } From c8a2992a715e01f9a2e23cdde0d9f41f269963a4 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Sun, 29 Dec 2024 14:20:55 +0100 Subject: [PATCH 81/98] feat: 1484 debug documented --- docs/diagrams/v2/net/thor/debug/_debug.md | 135 ------------------ .../v2/net/thor/debug/debug-module.md | 80 ----------- 2 files changed, 215 deletions(-) delete mode 100644 docs/diagrams/v2/net/thor/debug/_debug.md delete mode 100644 docs/diagrams/v2/net/thor/debug/debug-module.md diff --git a/docs/diagrams/v2/net/thor/debug/_debug.md b/docs/diagrams/v2/net/thor/debug/_debug.md deleted file mode 100644 index 395975705..000000000 --- a/docs/diagrams/v2/net/thor/debug/_debug.md +++ /dev/null @@ -1,135 +0,0 @@ -```mermaid -classDiagram - class PostDebugTracerCallRequest { - name?: TracerName - config?: unknown - value: VET - data: HexUInt - to?: Address - gas?: VTHO - gasPrice?: VTHO - caller?: Address - provedWork?: string - gasPayer?: Address - expiration?: UInt - blockRef?: BlockRef - constructor(json: PostDebugTracerCallRequestJSON) - toJSON() PostDebugTracerCallRequestJSON - } - class PostDebugTracerCallRequestJSON { - <> - name?: string - config?: unknown - value: string - data: string - to?: string - gas?: number - gasPrice?: string - caller?: string - provedWork?: string - gasPayer?: string - expiration?: number - blockRef?: string - } - class PostDebugTracerRequest { - name?: TracerName - config?: unknown - target: string - constructor(json PostDebugTracerRequestJSON) - toJSON() PostDebugTracerRequestJSON - } - class PostDebugTracerRequestJSON { - <> - name?: string - config?: unknown - target: string - } - class RetrieveStorageRange { - PATH: HttpPath$ - request: StorageRangeOption - constructor(request: StorageRangeOption) - askTo(httpClient: HttpClient) Promise~ThorResponse~StorageRange~~ - of(request: StorageRangeOptionJSON) RetrieveStorageRange$ - } - class StorageRange { - nextKey?: ThorId - storage: unknown - constructor(json StorageRangeJSON) - toJSON() StorageRangeJSON - } - class StorageRangeJSON { - <> - nextKey?: string - storage: string - } - class StorageRangeOptions { - address: Address - keyStart?: ThorId - maxResult?: UInt - target: string - constructor(json: StorageRangeOptionJSON) - toJSON() StorageRangeOptionJSON - } - class StorageRangeOptionJSON { - <> - address: string - keyStart?: string - maxResult?: number - target: string - } - class TraceCall { - PATH: HttpPath$ - request: PostDebugTracerCallRequest - constructor(request: request: PostDebugTracerCallRequest) - askTo(httpClient: HttpClient) Promise~ThorResponse~undefined~~ - of(request: PostDebugTracerCallRequestJSON): TraceCall$ - } - class TraceTransactionClause { - PATH: HttpPath$ - request: PostDebugTracerRequest - constructor(request: PostDebugTracerRequest) - askTo(httpClient: HttpClient) Promise~ThorResponse~unknown~ - of(request: PostDebugTracerRequestJSON): TraceTransactionClause$ - } - class TracerName { - <> - } - namespace thor { - class ThorRequest { - <> - askTo: (httpClient: HttpClient) Promise~ThorResponse~ResponseClass~~ - } - class ThorResponse { - <> - request: ~RequestClass~; - response: ~ResponseClass~; - } - } - PostDebugTracerCallRequestJSON <-- PostDebugTracerCallRequest - PostDebugTracerRequestJSON <-- PostDebugTracerRequest - StorageRange <-- RetrieveStorageRange - StorageRangeJSON <-- StorageRange - StorageRangeOptionJSON <-- StorageRangeOptions - ThorResponse <-- RetrieveStorageRange - ThorResponse <-- TraceCall - ThorResponse <-- TraceTransactionClause - ThorRequest <|.. RetrieveStorageRange - ThorRequest <|.. TraceCall - ThorRequest <|.. TraceTransactionClause - TracerName <|-- StructLogger - TracerName <|-- FourByte - TracerNname <|-- Call - TracerName <|-- Noop - TracerName <|-- Prestate - TracerName <|-- Unigram - TracerName <|-- Bigram - TracerName <|-- Trigram - TracerName <|-- EvmDis - TracerName <|-- OpCount - TracerName <|-- Null - RetrieveStorageRange *--> StorageRangeOptions - PostDebugTracerCallRequest *--> TracerName - PostDebugTracerRequest *--> TracerName - TraceCall *--> PostDebugTracerCallRequest - TraceTransactionClause *--> PostDebugTracerRequest -``` diff --git a/docs/diagrams/v2/net/thor/debug/debug-module.md b/docs/diagrams/v2/net/thor/debug/debug-module.md deleted file mode 100644 index 4e9a1b9cb..000000000 --- a/docs/diagrams/v2/net/thor/debug/debug-module.md +++ /dev/null @@ -1,80 +0,0 @@ -```mermaid -classDiagram - class HttpClient { - <> - } - class ThorRequest~Request~ { - askTo(httpClient: HttpClient): ThorResponse~Response~ - } - class ThorResponse~Response~ { - request: ThorRequest~Request~ - } - namespace Request { - class TraceTransactionClause { - body: TraceTransactionClause_Body - } - class TraceTransactionClause_Body { - name: TracerName - config: Object~Class~ - target: string - } - class TraceCall { - body: TraceCall_Body - } - class TraceCall_Body { - name: TracerName - config: Object~Class~ - value: VET - data: HexUInt - to: Address - gas: VTHO - gasPrice: VTHO - caller: Address - provedWork: string - gasPayer: Address - expiration UInt - blockRef: BlockRef - } - class RetrieveStorageRange { - body: RetrieveStorageRange_Body - } - class RetrieveStorageRange_Body { - address: Address - keyStart: HexUInt - maxResult: UInt - target: string - } - } - namespace Response { - class StorageRange { - nextKey: string - storage: HexUInt - } - } - class TracerName { - <> - structLogger: string - 4byte: string - call: string - noop: string - prestate: string - unigram: string - bigram: string - trigram: string - evmdis: string - opcount: string - null: string - } - HttpClient o-- ThorRequest - ThorRequest <|.. RetrieveStorageRange - ThorRequest <|.. TraceCall - ThorRequest <|.. TraceTransactionClause - ThorResponse <|.. StorageRange - RetrieveStorageRange --* RetrieveStorageRange_Body - ThorRequest --* ThorResponse - TraceCall --* TraceCall_Body - TraceCall_Body --* TracerName - TraceTransactionClause --* TraceTransactionClause_Body - TraceTransactionClause_Body --* TracerName - RetrieveStorageRange ..> StorageRange -``` From e1f4e0d91188e59dc189c2009f10483f926dd0f6 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Sun, 29 Dec 2024 14:27:12 +0100 Subject: [PATCH 82/98] feat: 1484 debug documented --- docs/diagrams/v2/net/thor/blocks/blocks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/diagrams/v2/net/thor/blocks/blocks.md b/docs/diagrams/v2/net/thor/blocks/blocks.md index 456304dcf..730937a5e 100644 --- a/docs/diagrams/v2/net/thor/blocks/blocks.md +++ b/docs/diagrams/v2/net/thor/blocks/blocks.md @@ -78,7 +78,7 @@ classDiagram RetrieveBlock *--> RetrieveBlockPath RetrieveBlock --> "askTo" HttpClient RetrieveBlock --> "askTo" RegularBlockResponse - RetrieveBlockPath --|> HttpPath + RetrieveBlockPath ..|> HttpPath ThorRequest <--* ThorResponse ThorRequest <|.. RetrieveBlock ThorResponse <-- "askTo" RetrieveBlock From 5264651643cb8c58300d41ea5226244e3c075fdc Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Mon, 30 Dec 2024 17:53:18 +0100 Subject: [PATCH 83/98] feat: 1484 logs documented --- .../diagrams/v2/net/thor/accounts/accounts.md | 24 +- docs/diagrams/v2/net/thor/blocks/blocks.md | 15 +- docs/diagrams/v2/net/thor/debug/debug.md | 23 +- docs/diagrams/v2/net/thor/logs/logs.md | 245 ++++++++++-------- .../src/thor/blocks/RegularBlockResponse..ts | 2 +- .../net/src/thor/logs/EventLogsResponse.ts | 13 +- .../src/thor/logs/QuerySmartContractEvents.ts | 9 +- .../net/src/thor/logs/TransferCriteria.ts | 6 +- .../net/src/thor/logs/TransferLogsResponse.ts | 8 +- yarn.lock | 61 ++++- 10 files changed, 238 insertions(+), 168 deletions(-) diff --git a/docs/diagrams/v2/net/thor/accounts/accounts.md b/docs/diagrams/v2/net/thor/accounts/accounts.md index 0f274fea3..b46a207ac 100644 --- a/docs/diagrams/v2/net/thor/accounts/accounts.md +++ b/docs/diagrams/v2/net/thor/accounts/accounts.md @@ -1,5 +1,10 @@ ```mermaid classDiagram + namespace JS { + class Array~Type~ { + <> + } + } namespace http { class HttpClient { <> @@ -11,11 +16,6 @@ classDiagram path: string } } - namespace JS { - class Array~Type~ { - <> - } - } namespace thor { class ThorRequest~RequestClass~ { <> @@ -191,25 +191,21 @@ classDiagram ExecuteCodesRequestJSON *--> ClauseJSON ExecuteCodesResponse *--> "ExecuteCodeResponseJSON[]" ExecuteCodeResponse ExecuteCodesResponse --> "new - toJSON" ExecuteCodesResponseJSON - ExecuteCodesResponse ..|> Array + ExecuteCodesResponse --|> Array ExecuteCodesResponseJSON *--> "ExecuteCodeResponseJSON[]" ExecuteCodeResponseJSON GetAccountResponse --> "new - toJSON" GetAccountResponseJSON GetStorageResponse --> "new - toJSON" GetStorageResponseJSON - HttpPath <-- "get - post" HttpClient + HttpClient --> "get - post" HttpPath + HttpPath <|.. RetrieveAccountDetailsPath + HttpPath <|.. RetrieveContractBytecodePath + HttpPath <|.. RetrieveStoragePositionValuePath InspectClauses --> "askTo" ExecuteCodesResponse - InspectClauses --> "askTo" HttpClient RetrieveAccountDetails *--> RetrieveAccountDetailsPath RetrieveAccountDetails --> "askTo" GetAccountResponse - RetrieveAccountDetails --> "askTo" HttpClient - RetrieveAccountDetailsPath ..|> HttpPath RetrieveContractBytecode *--> RetrieveContractBytecodePath RetrieveContractBytecode --> "askTo" ContractBytecode - RetrieveContractBytecode --> "askTo" HttpClient - RetrieveContractBytecodePath ..|> HttpPath RetrieveStoragePositionValue *--> RetrieveStoragePositionValuePath RetrieveStoragePositionValue --> "askTo" GetStorageResponse - RetrieveStoragePositionValue --> "askTo" HttpClient - RetrieveStoragePositionValuePath ..|> HttpPath ThorRequest <--* ThorResponse ThorRequest <|.. InspectClauses ThorRequest <|.. RetrieveAccountDetails diff --git a/docs/diagrams/v2/net/thor/blocks/blocks.md b/docs/diagrams/v2/net/thor/blocks/blocks.md index 730937a5e..1b7c16e9a 100644 --- a/docs/diagrams/v2/net/thor/blocks/blocks.md +++ b/docs/diagrams/v2/net/thor/blocks/blocks.md @@ -73,13 +73,12 @@ classDiagram class RetrieveBlockPath { revision: Revision } - HttpPath <-- "get - post" HttpClient - RegularBlockResponse --> "new - toJSON" RegularBlockResponseJSON - RetrieveBlock *--> RetrieveBlockPath - RetrieveBlock --> "askTo" HttpClient - RetrieveBlock --> "askTo" RegularBlockResponse - RetrieveBlockPath ..|> HttpPath - ThorRequest <--* ThorResponse - ThorRequest <|.. RetrieveBlock ThorResponse <-- "askTo" RetrieveBlock + ThorRequest <|.. RetrieveBlock + ThorRequest <--* ThorResponse + HttpPath <|.. RetrieveBlockPath + RetrieveBlock --> "askTo" RegularBlockResponse + RetrieveBlock *--> RetrieveBlockPath + RegularBlockResponse --> "new - toJSON" RegularBlockResponseJSON + HttpClient --> "get - post" HttpPath ``` diff --git a/docs/diagrams/v2/net/thor/debug/debug.md b/docs/diagrams/v2/net/thor/debug/debug.md index 5f2e1d658..f18a551b6 100644 --- a/docs/diagrams/v2/net/thor/debug/debug.md +++ b/docs/diagrams/v2/net/thor/debug/debug.md @@ -1,5 +1,10 @@ ```mermaid classDiagram + namespace JS { + class unknown { + <> + } + } namespace http { class HttpClient { <> @@ -11,11 +16,6 @@ classDiagram path: string } } - namespace JS { - class unknown { - <> - } - } namespace thor { class ThorRequest~RequestClass~ { <> @@ -157,7 +157,10 @@ classDiagram Call <-- "of" Tracer EvmDis <-- "of" Tracer FourByte <-- "of" Tracer - HttpPath <-- "get - post" HttpClient + HttpClient --> "get - post" HttpPath + HttpPath <--* RetrieveStorageRange + HttpPath <--* TraceCall + HttpPath <--* TraceTransactionClause Noop <-- "of" Tracer Null <-- "of" Tracer OpCount <-- "of" Tracer @@ -167,9 +170,7 @@ classDiagram PostDebugTracerRequest --> "new - toJSON" PostDebugTracerRequestJSON Presate <-- "of" Tracer Prestate <-- "of" Tracer - RetrieveStorageRange *-- HttpPath - RetrieveStorageRange *-- StorageRangeOption - RetrieveStorageRange --> "askTo" HttpClient + RetrieveStorageRange *--> StorageRangeOption RetrieveStorageRange --> "askTo" StorageRange RetrieveStorageRange --> "of" StorageRangeOptionJSON StorageRange --> "new - toJSON" StorageRangeJSON @@ -181,14 +182,10 @@ classDiagram ThorRequest <|.. TraceTransactionClause ThorResponse <-- "askTo" RetrieveStorageRange ThorResponse <-- "askTo" TraceCall - TraceCall *--> HttpPath TraceCall *--> PostDebugTracerCallRequest - TraceCall --> "askTo" HttpClient TraceCall --> "askTo" unknown TraceCall --> "of" PostDebugTracerCallRequestJSON - TraceTransactionClause *--> HttpPath TraceTransactionClause *--> PostDebugTracerCallRequest - TraceTransactionClause --> "askTo" HttpClient TraceTransactionClause --> "askTo" unknown TraceTransactionClause --> "of" PostDebugTracerRequestJSON TracerName <|-- Bigram diff --git a/docs/diagrams/v2/net/thor/logs/logs.md b/docs/diagrams/v2/net/thor/logs/logs.md index fa7e61383..c0adb8018 100644 --- a/docs/diagrams/v2/net/thor/logs/logs.md +++ b/docs/diagrams/v2/net/thor/logs/logs.md @@ -1,5 +1,32 @@ ```mermaid classDiagram + namespace JS { + class Array~Type~ { + <> + } + } + namespace http { + class HttpClient { + <> + get(httpPath: HttpPath) Promise~Response~ + post(httpPath: HttpPath, body?: unknown) Promise~Response~ + } + class HttpPath { + <> + path: string + } + } + namespace thor { + class ThorRequest~RequestClass~ { + <> + askTo(httpClient: HttpClient Promise~ThorResponse~ResponseClass~~ + } + class ThorResponse~ResponseClass~ { + <> + request: ThorRequest~RequestClass~ + response: ResponseClass + } + } class EventCriteria { address?: Address topic0?: ThorId @@ -7,12 +34,12 @@ classDiagram topic2?: ThorId topic3?: ThorId topic4?: ThorId - constructor(json: EventCriteriaJSON) + constructor(json: EventCriteriaJSON) EventCriteria toJSON() EventCriteriaJSON } class EventCriteriaJSON { <> - address?: string; + address?: string topic0?: string topic1?: string topic2?: string @@ -23,194 +50,182 @@ classDiagram range?: FilterRange options?: FilterOptions criteriaSet?: EventCriteria[] - order?: EventLogFilterRequestOrder - constructor(json: EventLogFilterRequestJSON) + order?: LogSort + constructor(json: EventLogFilterRequestJSON) EventLogFilterRequest toJSON() EventLogFilterRequestJSON } class EventLogFilterRequestJSON { - <> range?: FilterRangeJSON options?: FilterOptionsJSON criteriaSet?: EventCriteriaJSON[] order?: string } class EventLogResponse { - readonly address: Address; - readonly topics: ThorId[]; - readonly data: HexUInt; - readonly meta: LogMeta; - constructor(json: EventLogResponseJSON) + address: Address + topics: ThorId[] + data: HexUInt + meta: LogMeta + constructor(json: EventLogResponseJSON) EventLogResponse toJSON() EventLogResponseJSON } class EventLogResponseJSON { <> - address: string; - topics: string[]; - data: string; - meta: LogMetaJSON; + address: string + topics: string[] + data: string + meta: LogMetaJSON } class EventLogsResponse { + constructor(json: EventLogsResponseJSON) EventLogsResponse + toJSON() EventLogsResponseJSON + } + class EventLogsResponseJSON { <> } class FilterOptions { limit?: UInt offset?: UInt - constructor(json: FilterOptionsJSON) + constructor(json: FilterOptionsJSON) FilterOptions toJSON() FilterOptionsJSON } class FilterOptionsJSON { - <> limit?: number offset?: number } + class LogMeta { + blockID: BlockId + blockNumber: UInt + blockTimestamp: UInt + txID: TxId + txOrigin: Address + clauseIndex: UInt + constructor(json: LogMetaJSON) + toJSON() LogMetaJSON + } + class LogMetaJSON { + <> + blockID: string + blockNumber: number + blockTimestamp: number + txID: string + txOrigin: string + clauseIndex: number + } + class LogSort { + <> + asc: string + desc: string + } class FilterRange { + unit?: FilterRangeUnits from?: UInt to?: UInt - unit?: FilterRangeUnit - constructor(json: FilterRangeJSON) + constructor(json: FilterRangeJSON) FilterRange toJSON() FilterRangeJSON } class FilterRangeJSON { - <> + unit?: string from?: number to?: number - unit?: string - } - class FilterRangeUnit { - <> - block$ - time$ - } - class LogMeta { - blockID: BlockId; - blockNumber: UInt; - blockTimestamp: UInt; - txID: TxId; - txOrigin: Address; - clauseIndex: UInt; - constructor(json: LogMetaJSON) - toJSON() LogMetaJSON } - class LogMetaJSON { - <> - blockID: string; - blockNumber: number; - blockTimestamp: number; - txID: string; - txOrigin: string; - clauseIndex: number; - } - class LogSort { - <> - asc$ - desc$ + class FilterRangeUnits { + <> + block = 'block', + time = 'time' } class QuerySmartContractEvents { - PATH$: HttpPath + PATH: HttpPath$ request: EventLogFilterRequest - constructor(request: EventLogFilterRequest) - askTo(httpClient: HttpClient): Promise~ThorResponse~EventLogsResponse~~ - of(request: EventLogFilterRequestJSON)$ QuerySmartContractEvents + constructor(request: EventLogFilterRequest) QuerySmartContractEvents + askTo(httpClient: HttpClient) Promise~ThorResponse~EventLogsResponse~~ + static of(request: EventLogFilterRequestJSON) QuerySmartContractEvents$ } class QueryVETTransferEvents { - PATH$: HttpPath + PATH: HttpPath$ request: TransferLogFilterRequest - constructor(request: TransferLogFilterRequest) - askTo(httpClient: HttpClient): Promise~ThorResponse~TransferLogsResponse~~ - of(request: TransferLogFilterRequestJSON) QueryVETTransferEvents + constructor(request: TransferLogFilterRequest) QueryVETTransferEvents + askTo(httpClient: HttpClient) Promise~ThorResponse~TransferLogsResponse~~ + of(request: TransferLogFilterRequestJSON) QueryVETTransferEvents$ } class TransferCriteria { - txOrigin?: Address; - sender?: Address; - recipient?: Address; - constructor(json: TransferCriteriaJSON) + txOrigin?: Address + sender?: Address + recipient?: Address + constructor(json: TransferCriteriaJSON) TransferCriteria toJSON() TransferCriteriaJSON } class TransferCriteriaJSON { - <> - txOrigin?: string; - sender?: string; - recipient?: string; + txOrigin?: string + sender?: string + recipient?: string } class TransferLogFilterRequest { range?: FilterRange options?: FilterOptions criteriaSet?: TransferCriteria[] order?: LogSort - constructor(json: TransferLogFilterRequestJSON) + constructor(json: TransferLogFilterRequestJSON) TransferLogFilterRequest toJSON() TransferLogFilterRequestJSON } class TransferLogFilterRequestJSON { - <> range?: FilterRangeJSON options?: FilterOptionsJSON criteriaSet?: TransferCriteriaJSON[] - order?: LogSort + order?: string } class TransferLogResponse { sender: Address recipient: Address amount: VET meta: LogMeta - constructor(json: TransferLogResponseJSON) + constructor(json: TransferLogResponseJSON) TransferLogResponse toJSON() TransferLogResponseJSON } class TransferLogResponseJSON { - <> - sender: string; - recipient: string; - amount: string; - meta: LogMetaJSON; + sender: string + recipient: string + amount: string + meta: LogMetaJSON } - class TransferLogsResponse { - <> - } - namespace thor { - class ThorRequest { - <> - askTo: (httpClient: HttpClient) Promise~ThorResponse~ResponseClass~~ - } - class ThorResponse { - <> - request: ~RequestClass~; - response: ~ResponseClass~; - } - } - EventCriteriaJSON <-- EventCriteria - EventLogFilterRequestJSON <-- EventLogFilterRequest - EventLogResponseJSON <-- EventLogResponse - EventLogsResponse <-- QuerySmartContractEvents - FilterOptionsJSON <-- FilterOptions - FilterRangeJSON <-- FilterRange - LogMetaJSON <-- LogMeta - TransferCriteriaJSON <-- TransferCriteria - TransferLogFilterRequestJSON <-- TransferLogFilterRequest - TransferLogResponseJSON <-- TransferLogResponse - TransferLogsResponse <-- QueryVETTransferEvents - ThorResponse <-- EventLogsResponse - ThorResponse <-- TransferLogResponse - ThorResponse <-- QuerySmartContractEvents - ThorResponse <-- QueryVETTransferEvents - ThorRequest <|.. QuerySmartContractEvents - ThorRequest <|.. QueryVETTransferEvents - EventLogResponse "*" o-- EventLogsResponse - TransferLogResponse "*" o-- TransferLogsResponse - EventLogFilterRequest *--> FilterRange - EventLogFilterRequest *--> FilterOptions + EventCriteria --> "new - toJSON" EventCriteriaJSON EventLogFilterRequest *--> EventCriteria EventLogFilterRequest *--> LogSort - EventLogFilterRequestJSON *--> FilterRangeJSON - EventLogFilterRequestJSON *--> FilterOptionsJSON + EventLogFilterRequest --> "new - toJSON" EventLogFilterRequestJSON EventLogFilterRequestJSON *--> EventCriteriaJSON EventLogResponse *--> LogMeta + EventLogResponse --> "new - toJSON" EventLogResponseJSON EventLogResponseJSON *--> LogMetaJSON - FilterRange *--> FilterRangeUnit + EventLogsResponse *--> EventLogResponse + EventLogsResponse --|> Array + EventLogsResponseJSON *--> EventLogResponseJSON + EventLogsResponseJSON --|> Array + FilterOptions --> "new - toJSON" FilterOptionsJSON + FilterRange *--> FilterRangeUnits + FilterRange --> "new - toJSON" FilterRangeJSON + HttpClient --> "get - post" HttpPath + HttpPath <--* QuerySmartContractEvents + HttpPath <--* QueryVETTransferEvents + LogMeta --> "new - toJSON" LogMetaJSON QuerySmartContractEvents *--> EventLogFilterRequest - QueryVETTransferEvents *--> TransferLogFilterRequest - TransferLogFilterRequest *--> FilterRange + QuerySmartContractEvents --> "askTo" EventLogsResponse + QueryVETTransferEvents *--> TransferLogFilterRequest + QueryVETTransferEvents --> "askTo" TransferLogsResponse + ThorRequest <--* ThorResponse + ThorRequest <|.. QuerySmartContractEvents + ThorRequest <|.. QueryVETTransferEvents + ThorResponse <-- "askTo" QuerySmartContractEvents + ThorResponse <-- "askTo" QueryVETTransferEvents + TransferCriteria --> "new - toJSON" TransferCriteriaJSON TransferLogFilterRequest *--> FilterOptions - TransferLogFilterRequest *--> "*" TransferCriteria + TransferLogFilterRequest *--> FilterRange TransferLogFilterRequest *--> LogSort + TransferLogFilterRequest *--> TransferCriteria + TransferLogFilterRequest --> "new - toJSON" TransferLogFilterRequestJSON TransferLogResponse *--> LogMeta - TransferLogResponseJSON *--> LogMetaJSON + TransferLogResponse --> "new - toJSON" TransferLogResponseJSON + TransferLogsResponse *--> TransferLogResponse + TransferLogsResponse --> "new - toJSON" TransferLogsResponseJSON + TransferLogsResponse --|> Array + TransferLogsResponseJSON *--> TransferLogResponseJSON + TransferLogsResponseJSON --|> Array ``` diff --git a/packages/net/src/thor/blocks/RegularBlockResponse..ts b/packages/net/src/thor/blocks/RegularBlockResponse..ts index 971fec0fc..cfab6b47d 100644 --- a/packages/net/src/thor/blocks/RegularBlockResponse..ts +++ b/packages/net/src/thor/blocks/RegularBlockResponse..ts @@ -1,5 +1,5 @@ import { Address, ThorId, Units, VTHO } from '@vechain/sdk-core'; -import { UInt } from '../../../../core'; +import { UInt } from '../../../../core/src'; class RegularBlockResponse { readonly number: UInt; diff --git a/packages/net/src/thor/logs/EventLogsResponse.ts b/packages/net/src/thor/logs/EventLogsResponse.ts index 73aad25ef..1ce266b29 100644 --- a/packages/net/src/thor/logs/EventLogsResponse.ts +++ b/packages/net/src/thor/logs/EventLogsResponse.ts @@ -35,7 +35,16 @@ interface EventLogResponseJSON { meta: LogMetaJSON; } -interface EventLogsResponse extends Array {} +class EventLogsResponse extends Array { + constructor(json: EventLogsResponseJSON) { + super( + ...json.map( + (response: EventLogResponseJSON): EventLogResponse => + new EventLogResponse(response) + ) + ); + } +} interface EventLogsResponseJSON extends Array {} @@ -43,5 +52,5 @@ export { EventLogResponse, type EventLogResponseJSON, type EventLogsResponseJSON, - type EventLogsResponse + EventLogsResponse }; diff --git a/packages/net/src/thor/logs/QuerySmartContractEvents.ts b/packages/net/src/thor/logs/QuerySmartContractEvents.ts index 567a857dd..097298b51 100644 --- a/packages/net/src/thor/logs/QuerySmartContractEvents.ts +++ b/packages/net/src/thor/logs/QuerySmartContractEvents.ts @@ -6,9 +6,7 @@ import { } from './EventLogFilterRequest'; import type { ThorResponse } from '../ThorResponse'; import { - EventLogResponse, - type EventLogResponseJSON, - type EventLogsResponse, + EventLogsResponse, type EventLogsResponseJSON } from './EventLogsResponse'; @@ -34,10 +32,7 @@ class QuerySmartContractEvents const responseBody = (await response.json()) as EventLogsResponseJSON; return { request: this, - response: responseBody.map( - (json: EventLogResponseJSON): EventLogResponse => - new EventLogResponse(json) - ) as EventLogsResponse + response: new EventLogsResponse(responseBody) }; } diff --git a/packages/net/src/thor/logs/TransferCriteria.ts b/packages/net/src/thor/logs/TransferCriteria.ts index bc7fc3d1c..e7eadbb8c 100644 --- a/packages/net/src/thor/logs/TransferCriteria.ts +++ b/packages/net/src/thor/logs/TransferCriteria.ts @@ -1,9 +1,9 @@ import { Address } from '@vechain/sdk-core'; class TransferCriteria { - txOrigin?: Address; - sender?: Address; - recipient?: Address; + readonly txOrigin?: Address; + readonly sender?: Address; + readonly recipient?: Address; constructor(json: TransferCriteriaJSON) { this.txOrigin = diff --git a/packages/net/src/thor/logs/TransferLogsResponse.ts b/packages/net/src/thor/logs/TransferLogsResponse.ts index f8e74eb77..c0b597e8d 100644 --- a/packages/net/src/thor/logs/TransferLogsResponse.ts +++ b/packages/net/src/thor/logs/TransferLogsResponse.ts @@ -2,10 +2,10 @@ import { LogMeta, type LogMetaJSON } from './LogMeta'; import { Address, HexUInt, Units, VET } from '@vechain/sdk-core'; class TransferLogResponse { - sender: Address; - recipient: Address; - amount: VET; - meta: LogMeta; + readonly sender: Address; + readonly recipient: Address; + readonly amount: VET; + readonly meta: LogMeta; constructor(json: TransferLogResponseJSON) { this.sender = Address.of(json.sender); diff --git a/yarn.lock b/yarn.lock index e440de56e..c534c2e69 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3547,7 +3547,7 @@ dependencies: eslint-scope "5.1.1" -"@noble/ciphers@^1.1.3": +"@noble/ciphers@^1.1.1", "@noble/ciphers@^1.1.3": version "1.1.3" resolved "https://registry.yarnpkg.com/@noble/ciphers/-/ciphers-1.1.3.tgz#eb27085aa7ce94d8c6eaeb64299bab0589920ec1" integrity sha512-Ygv6WnWJHLLiW4fnNDC1z+i13bud+enXOFRBlpxI+NJliPWx5wdR+oWlTjLuBPTqjUjtHXtjkU6w3kuuH6upZA== @@ -5460,6 +5460,37 @@ uuid "2.0.1" xmlhttprequest "1.8.0" +"@vechain/sdk-core@1.0.0-rc.4": + version "1.0.0-rc.4" + resolved "https://registry.yarnpkg.com/@vechain/sdk-core/-/sdk-core-1.0.0-rc.4.tgz#926c820d81d27830384860df69378648fa3a952e" + integrity sha512-/qKeMny9mhiGZfQesaepP/EOH/F2tXcTq1OiDHBQwJs6wGVd1lj6RoyoSS+WsRIMG7AbzHeD+iLyqNcYKxBvTQ== + dependencies: + "@ethereumjs/rlp" "^5.0.2" + "@noble/ciphers" "^1.1.1" + "@noble/curves" "^1.6.0" + "@noble/hashes" "^1.5.0" + "@scure/base" "^1.1.9" + "@scure/bip32" "^1.4.0" + "@scure/bip39" "^1.4.0" + "@vechain/sdk-errors" "1.0.0-rc.4" + "@vechain/sdk-logging" "1.0.0-rc.4" + abitype "^1.0.6" + ethers "6.13.4" + fast-json-stable-stringify "^2.1.0" + viem "^2.21.45" + +"@vechain/sdk-errors@1.0.0-rc.4": + version "1.0.0-rc.4" + resolved "https://registry.yarnpkg.com/@vechain/sdk-errors/-/sdk-errors-1.0.0-rc.4.tgz#24cc9e9636e8ce7c4b45bde5b5ee883eba460561" + integrity sha512-XLczRbf6aMIxPLWEFqHsNae2vJ42blX8dK+TsPsIYIFCAAK8LHEHrHV5LCocJQS+BP+MgKH8sX+2O7FQdjHKiw== + +"@vechain/sdk-logging@1.0.0-rc.4": + version "1.0.0-rc.4" + resolved "https://registry.yarnpkg.com/@vechain/sdk-logging/-/sdk-logging-1.0.0-rc.4.tgz#803e46bdcf20dfe222329a771ad832ba84b5e3d6" + integrity sha512-C1TF367Fl/CTElASX+zvzcZpB5msczpOy1DFOTwkhVFbar08TgtfvsVdE1M/rg8B8Af0zd5M8FST7TCeDpw3uA== + dependencies: + "@vechain/sdk-errors" "1.0.0-rc.4" + "@vechain/vebetterdao-contracts@^4.1.0": version "4.1.0" resolved "https://registry.yarnpkg.com/@vechain/vebetterdao-contracts/-/vebetterdao-contracts-4.1.0.tgz#5a081bf9c548ea777fe16dcab40536d6d2cc1a62" @@ -11723,6 +11754,19 @@ ox@0.1.2: abitype "^1.0.6" eventemitter3 "5.0.1" +ox@0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/ox/-/ox-0.4.4.tgz#9d1757c026406e60097680d98ffedf9e3bc1fa0b" + integrity sha512-oJPEeCDs9iNiPs6J0rTx+Y0KGeCGyCAA3zo94yZhm8G5WpOxrwUtn2Ie/Y8IyARSqqY/j9JTKA3Fc1xs1DvFnw== + dependencies: + "@adraffy/ens-normalize" "^1.10.1" + "@noble/curves" "^1.6.0" + "@noble/hashes" "^1.5.0" + "@scure/bip32" "^1.5.0" + "@scure/bip39" "^1.4.0" + abitype "^1.0.6" + eventemitter3 "5.0.1" + p-filter@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-filter/-/p-filter-2.1.0.tgz#1b1472562ae7a0f742f0f3d3d3718ea66ff9c09c" @@ -14541,6 +14585,21 @@ vfile@^6.0.0: "@types/unist" "^3.0.0" vfile-message "^4.0.0" +viem@^2.21.45: + version "2.21.59" + resolved "https://registry.yarnpkg.com/viem/-/viem-2.21.59.tgz#6b737166dd98cab1293578195d713c2b28c1acc7" + integrity sha512-aHycB6LRxmUiKArOoQ1nYmhtVvZgU+ltAVvK7J1g+MuSbZZW5pXUtosRCBLlCO2gs05zYfrhVih+LmbRrdEXKg== + dependencies: + "@noble/curves" "1.7.0" + "@noble/hashes" "1.6.1" + "@scure/bip32" "1.6.0" + "@scure/bip39" "1.5.0" + abitype "1.0.7" + isows "1.0.6" + ox "0.4.4" + webauthn-p256 "0.0.10" + ws "8.18.0" + viem@^2.21.54: version "2.21.54" resolved "https://registry.yarnpkg.com/viem/-/viem-2.21.54.tgz#76d6f86ab8809078f1ac140ac1a2beadbc86b9f6" From fa93b405e44068163ef85b3f18dd4f8517632d78 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Mon, 30 Dec 2024 17:55:41 +0100 Subject: [PATCH 84/98] feat: 1484 logs documented --- docs/diagrams/v2/net/thor/logs/logs.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/diagrams/v2/net/thor/logs/logs.md b/docs/diagrams/v2/net/thor/logs/logs.md index c0adb8018..752be6233 100644 --- a/docs/diagrams/v2/net/thor/logs/logs.md +++ b/docs/diagrams/v2/net/thor/logs/logs.md @@ -77,7 +77,6 @@ classDiagram } class EventLogsResponse { constructor(json: EventLogsResponseJSON) EventLogsResponse - toJSON() EventLogsResponseJSON } class EventLogsResponseJSON { <> From 19bd10e8aadf4ae791b35c6373b42c6f1cdc239c Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Mon, 30 Dec 2024 19:08:07 +0100 Subject: [PATCH 85/98] feat: 1484 node documented --- docs/diagrams/v2/net/thor/node/_node.md | 41 ++++++++++ docs/diagrams/v2/net/thor/node/node.md | 78 +++++++++++++------ .../net/src/thor/node/GetPeersResponse.ts | 12 ++- .../node/{PeerResponse.ts => PeerStat.ts} | 28 +++---- .../src/thor/node/RetrieveConnectedPeers.ts | 17 ++-- packages/net/src/thor/node/index.ts | 2 +- 6 files changed, 126 insertions(+), 52 deletions(-) create mode 100644 docs/diagrams/v2/net/thor/node/_node.md rename packages/net/src/thor/node/{PeerResponse.ts => PeerStat.ts} (86%) diff --git a/docs/diagrams/v2/net/thor/node/_node.md b/docs/diagrams/v2/net/thor/node/_node.md new file mode 100644 index 000000000..a9bda2e43 --- /dev/null +++ b/docs/diagrams/v2/net/thor/node/_node.md @@ -0,0 +1,41 @@ +```mermaid +classDiagram + class Array~PeerResponse~ { + } + class GetPeersResponse { + <> + } + class PeerResponse { + bestBlockID: BlockId + duration: UInt + inbound: boolean + name: string + netAddr: string + peerID: string + totalScore: UInt + } + class RetrieveConnectedPeers { + } + namespace http { + class HttpClient { + <> + } + } + namespace thor { + class ThorRequest~RetrieveConnectedPeers~ { + <> + askTo(httpClient: HttpClient Promise~ThorResponse~GetPeersResponse~~; + } + class ThorResponse~RetrieveConnectedPeers~ { + <> + request: ThorRequest~RequestClass~ + response: GetPeersResponse + } + } + Array~PeerResponse~ <|-- GetPeersResponse + GetPeersResponse *-- ThorResponse~RetrieveConnectedPeers~ + HttpClient <-- ThorRequest~RetrieveConnectedPeers~ + PeerResponse o-- Array~PeerResponse~ + ThorRequest~RetrieveConnectedPeers~ <|.. RetrieveConnectedPeers + ThorResponse~RetrieveConnectedPeers~ *--> ThorRequest~RetrieveConnectedPeers~ +``` diff --git a/docs/diagrams/v2/net/thor/node/node.md b/docs/diagrams/v2/net/thor/node/node.md index a9bda2e43..85f93ee56 100644 --- a/docs/diagrams/v2/net/thor/node/node.md +++ b/docs/diagrams/v2/net/thor/node/node.md @@ -1,41 +1,69 @@ ```mermaid classDiagram - class Array~PeerResponse~ { - } - class GetPeersResponse { - <> - } - class PeerResponse { - bestBlockID: BlockId - duration: UInt - inbound: boolean - name: string - netAddr: string - peerID: string - totalScore: UInt - } - class RetrieveConnectedPeers { + namespace JS { + class Array~Type~ { + <> + } } namespace http { class HttpClient { <> + get(httpPath: HttpPath) Promise~Response~ + post(httpPath: HttpPath, body?: unknown) Promise~Response~ + } + class HttpPath { + <> + path: string } } namespace thor { - class ThorRequest~RetrieveConnectedPeers~ { + class ThorRequest~RequestClass~ { <> - askTo(httpClient: HttpClient Promise~ThorResponse~GetPeersResponse~~; + askTo(httpClient: HttpClient Promise~ThorResponse~ResponseClass~~ } - class ThorResponse~RetrieveConnectedPeers~ { + class ThorResponse~ResponseClass~ { <> request: ThorRequest~RequestClass~ - response: GetPeersResponse + response: ResponseClass } } - Array~PeerResponse~ <|-- GetPeersResponse - GetPeersResponse *-- ThorResponse~RetrieveConnectedPeers~ - HttpClient <-- ThorRequest~RetrieveConnectedPeers~ - PeerResponse o-- Array~PeerResponse~ - ThorRequest~RetrieveConnectedPeers~ <|.. RetrieveConnectedPeers - ThorResponse~RetrieveConnectedPeers~ *--> ThorRequest~RetrieveConnectedPeers~ + class GetPeersResponse { + constructor(json: GetPeersResponseJSON) GetPeersResponse + } + class GetPeersResponseJSON { + <> + } + class PeerStat { + name: string + bestBlockID: BlockId + totalScore: UInt + peerID: string + netAddr: string + inbound: boolean + duration: UInt + constructor(json: PeerStatJSON) PeerStat + toJSON() PeerStatJSON + } + class PeerStatJSON { + name: string + bestBlockID: string + totalScore: number + peerID: string + netAddr: string + inbound: boolean + duration: number + } + class RetrieveConnectedPeers { + PATH: HttpPath + askTo(httpClient: HttpClient) Promise~ThorResponse~GetPeersResponse~~ + } + GetPeersResponse *--> PeerStat + GetPeersResponse --> "new - toJSON" GetPeersResponseJSON + GetPeersResponse --|> Array + GetPeersResponseJSON *--> PeerStatJSON + HttpPath <--* RetrieveConnectedPeers + PeerStat --> "new - toJSON" PeerStatJSON + RetrieveConnectedPeers --> "askTo" GetPeersResponse + ThorRequest <-- "askTo" RetrieveConnectedPeers + ThorResponse <|.. RetrieveConnectedPeers ``` diff --git a/packages/net/src/thor/node/GetPeersResponse.ts b/packages/net/src/thor/node/GetPeersResponse.ts index 82b8d4703..90fd3b3f5 100644 --- a/packages/net/src/thor/node/GetPeersResponse.ts +++ b/packages/net/src/thor/node/GetPeersResponse.ts @@ -1,3 +1,11 @@ -import { type PeerResponse } from './PeerResponse'; +import { PeerStat, type PeerStatJSON } from './PeerStat'; -export interface GetPeersResponse extends Array {} +class GetPeersResponse extends Array { + constructor(json: GetPeersResponseJSON) { + super(...json.map((json: PeerStatJSON) => new PeerStat(json))); + } +} + +interface GetPeersResponseJSON extends Array {} + +export { GetPeersResponse, type GetPeersResponseJSON }; diff --git a/packages/net/src/thor/node/PeerResponse.ts b/packages/net/src/thor/node/PeerStat.ts similarity index 86% rename from packages/net/src/thor/node/PeerResponse.ts rename to packages/net/src/thor/node/PeerStat.ts index b66dab586..35e187716 100644 --- a/packages/net/src/thor/node/PeerResponse.ts +++ b/packages/net/src/thor/node/PeerStat.ts @@ -2,17 +2,7 @@ import { BlockId } from '@vechain/sdk-core'; import { UInt } from '../../../../core/src/vcdm/UInt'; -interface PeerResponseJSON { - name: string; - bestBlockID: string; - totalScore: number; - peerID: string; - netAddr: string; - inbound: boolean; - duration: number; -} - -class PeerResponse { +class PeerStat { readonly name: string; readonly bestBlockID: BlockId; readonly totalScore: UInt; @@ -21,7 +11,7 @@ class PeerResponse { readonly inbound: boolean; readonly duration: UInt; - constructor(json: PeerResponseJSON) { + constructor(json: PeerStatJSON) { this.name = json.name; this.bestBlockID = BlockId.of(json.bestBlockID); this.totalScore = UInt.of(json.totalScore); @@ -31,7 +21,7 @@ class PeerResponse { this.duration = UInt.of(json.duration); } - toJSON(): PeerResponseJSON { + toJSON(): PeerStatJSON { return { name: this.name, bestBlockID: this.bestBlockID.toString(), @@ -44,4 +34,14 @@ class PeerResponse { } } -export { PeerResponse, type PeerResponseJSON }; +interface PeerStatJSON { + name: string; + bestBlockID: string; + totalScore: number; + peerID: string; + netAddr: string; + inbound: boolean; + duration: number; +} + +export { PeerStat, type PeerStatJSON }; diff --git a/packages/net/src/thor/node/RetrieveConnectedPeers.ts b/packages/net/src/thor/node/RetrieveConnectedPeers.ts index af02f4661..5a07dde0e 100644 --- a/packages/net/src/thor/node/RetrieveConnectedPeers.ts +++ b/packages/net/src/thor/node/RetrieveConnectedPeers.ts @@ -1,5 +1,7 @@ -import { PeerResponse, type PeerResponseJSON } from './PeerResponse'; -import { type GetPeersResponse } from './GetPeersResponse'; +import { + GetPeersResponse, + type GetPeersResponseJSON +} from './GetPeersResponse'; import { type HttpClient, type HttpPath } from '../../http'; import { type ThorRequest } from '../ThorRequest'; import { type ThorResponse } from '../ThorResponse'; @@ -15,16 +17,11 @@ class RetrieveConnectedPeers const response = await httpClient.get(RetrieveConnectedPeers.PATH, { query: '' }); - const responseBody: PeerResponseJSON[] = - (await response.json()) as PeerResponseJSON[]; - const getPeersResponse: GetPeersResponse = responseBody.map( - (peerResponseJSON) => { - return new PeerResponse(peerResponseJSON); - } - ); + const responseBody: GetPeersResponseJSON = + (await response.json()) as GetPeersResponseJSON; return { request: this, - response: getPeersResponse + response: new GetPeersResponse(responseBody) }; } } diff --git a/packages/net/src/thor/node/index.ts b/packages/net/src/thor/node/index.ts index 3011e7c47..95e495133 100644 --- a/packages/net/src/thor/node/index.ts +++ b/packages/net/src/thor/node/index.ts @@ -1,3 +1,3 @@ export * from './GetPeersResponse'; -export * from './PeerResponse'; +export * from './PeerStat'; export * from './RetrieveConnectedPeers'; From 066f0c44d8a3c9e1797080e59249fe9bfde6d4f2 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Mon, 30 Dec 2024 19:08:52 +0100 Subject: [PATCH 86/98] feat: 1484 node documented --- docs/diagrams/v2/net/thor/node/_node.md | 41 ------------------------- 1 file changed, 41 deletions(-) delete mode 100644 docs/diagrams/v2/net/thor/node/_node.md diff --git a/docs/diagrams/v2/net/thor/node/_node.md b/docs/diagrams/v2/net/thor/node/_node.md deleted file mode 100644 index a9bda2e43..000000000 --- a/docs/diagrams/v2/net/thor/node/_node.md +++ /dev/null @@ -1,41 +0,0 @@ -```mermaid -classDiagram - class Array~PeerResponse~ { - } - class GetPeersResponse { - <> - } - class PeerResponse { - bestBlockID: BlockId - duration: UInt - inbound: boolean - name: string - netAddr: string - peerID: string - totalScore: UInt - } - class RetrieveConnectedPeers { - } - namespace http { - class HttpClient { - <> - } - } - namespace thor { - class ThorRequest~RetrieveConnectedPeers~ { - <> - askTo(httpClient: HttpClient Promise~ThorResponse~GetPeersResponse~~; - } - class ThorResponse~RetrieveConnectedPeers~ { - <> - request: ThorRequest~RequestClass~ - response: GetPeersResponse - } - } - Array~PeerResponse~ <|-- GetPeersResponse - GetPeersResponse *-- ThorResponse~RetrieveConnectedPeers~ - HttpClient <-- ThorRequest~RetrieveConnectedPeers~ - PeerResponse o-- Array~PeerResponse~ - ThorRequest~RetrieveConnectedPeers~ <|.. RetrieveConnectedPeers - ThorResponse~RetrieveConnectedPeers~ *--> ThorRequest~RetrieveConnectedPeers~ -``` From c7f4f97d493471733ff695cf292a7540fe703ccc Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Mon, 30 Dec 2024 19:12:02 +0100 Subject: [PATCH 87/98] feat: 1484 node documented --- docs/diagrams/v2/net/thor/node/node.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/diagrams/v2/net/thor/node/node.md b/docs/diagrams/v2/net/thor/node/node.md index 85f93ee56..88badb683 100644 --- a/docs/diagrams/v2/net/thor/node/node.md +++ b/docs/diagrams/v2/net/thor/node/node.md @@ -60,6 +60,7 @@ classDiagram GetPeersResponse *--> PeerStat GetPeersResponse --> "new - toJSON" GetPeersResponseJSON GetPeersResponse --|> Array + GetPeersResponseJSON --|> Array GetPeersResponseJSON *--> PeerStatJSON HttpPath <--* RetrieveConnectedPeers PeerStat --> "new - toJSON" PeerStatJSON From 37bfe66a6544b0d46ab741d36931019df43b4999 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Mon, 30 Dec 2024 19:13:09 +0100 Subject: [PATCH 88/98] feat: 1484 node documented --- docs/diagrams/v2/net/thor/node/node.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/diagrams/v2/net/thor/node/node.md b/docs/diagrams/v2/net/thor/node/node.md index 88badb683..a76f1e606 100644 --- a/docs/diagrams/v2/net/thor/node/node.md +++ b/docs/diagrams/v2/net/thor/node/node.md @@ -62,6 +62,7 @@ classDiagram GetPeersResponse --|> Array GetPeersResponseJSON --|> Array GetPeersResponseJSON *--> PeerStatJSON + HttpClient --> "get - post" HttpPath HttpPath <--* RetrieveConnectedPeers PeerStat --> "new - toJSON" PeerStatJSON RetrieveConnectedPeers --> "askTo" GetPeersResponse From f619998766f294e99cb4e5128ec41b0fc359446a Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Mon, 30 Dec 2024 19:16:21 +0100 Subject: [PATCH 89/98] feat: 1484 node documented --- docs/diagrams/v2/net/thor/node/node.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/diagrams/v2/net/thor/node/node.md b/docs/diagrams/v2/net/thor/node/node.md index a76f1e606..9e59c80be 100644 --- a/docs/diagrams/v2/net/thor/node/node.md +++ b/docs/diagrams/v2/net/thor/node/node.md @@ -54,7 +54,7 @@ classDiagram duration: number } class RetrieveConnectedPeers { - PATH: HttpPath + PATH: HttpPath$ askTo(httpClient: HttpClient) Promise~ThorResponse~GetPeersResponse~~ } GetPeersResponse *--> PeerStat From 320173d79ca05b21d4e036c3315cb44611bc952f Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 1 Jan 2025 10:57:49 +0100 Subject: [PATCH 90/98] feat: 1484 node documented --- .../diagrams/v2/net/thor/accounts/accounts.md | 1 - .../net/thor/subscriptions/subscriptions.md | 20 +- .../thor/transactions/transactions-module.md | 97 ------- .../v2/net/thor/transactions/transactions.md | 274 +++++++++--------- .../src/thor/accounts/ExecuteCodesResponse.ts | 7 - .../NewTransactionSubscription.ts | 2 +- .../subscriptions/TransfersSubscription.ts | 51 +++- packages/net/src/thor/subscriptions/index.ts | 1 - packages/net/src/thor/transactions/Clause.ts | 8 +- .../src/thor/transactions/GetTxResponse.ts | 20 +- .../net/src/thor/transactions/ReceiptMeta.ts | 4 +- .../RetrieveRawTransactionByID.ts | 4 +- .../transactions/RetrieveTransactionByID.ts | 10 +- .../RetrieveTransactionReceipt.ts | 8 +- .../src/thor/transactions/SendTransaction.ts | 18 +- .../{subscriptions => transactions}/TXID.ts | 0 packages/net/src/thor/transactions/index.ts | 1 + .../accounts/InspectClauses.testnet.test.ts | 1 - .../thor/blocks/RetrieveBlock.testnet.test.ts | 35 +-- .../BeatsSubscription.solo.test.ts | 9 + .../BlocksSubscription.solo.test.ts | 5 + .../NewTransactionSubscription.solo.test.ts | 11 +- 22 files changed, 248 insertions(+), 339 deletions(-) delete mode 100644 docs/diagrams/v2/net/thor/transactions/transactions-module.md rename packages/net/src/thor/{subscriptions => transactions}/TXID.ts (100%) diff --git a/docs/diagrams/v2/net/thor/accounts/accounts.md b/docs/diagrams/v2/net/thor/accounts/accounts.md index b46a207ac..bf9020525 100644 --- a/docs/diagrams/v2/net/thor/accounts/accounts.md +++ b/docs/diagrams/v2/net/thor/accounts/accounts.md @@ -120,7 +120,6 @@ classDiagram } class ExecuteCodesResponse { constructor(json: ExecuteCodesResponseJSON) ExecuteCodesResponse - toJSON() ExecuteCodesResponseJSON } class ExecuteCodesResponseJSON { <> diff --git a/docs/diagrams/v2/net/thor/subscriptions/subscriptions.md b/docs/diagrams/v2/net/thor/subscriptions/subscriptions.md index e6f56cb2d..f9484eac0 100644 --- a/docs/diagrams/v2/net/thor/subscriptions/subscriptions.md +++ b/docs/diagrams/v2/net/thor/subscriptions/subscriptions.md @@ -20,6 +20,17 @@ classDiagram clauseIndex: number } } + namespace trasactions { + class TXID { + id: ThorId + constructor(json: TXIDJSON): TXID + toJSON() TXIDJSON + } + class TXIDJSON { + <> + id: string + } + } namespace ws { class WebSocketClient { <> @@ -176,15 +187,6 @@ classDiagram obsolete: boolean meta: LogMetaJSON } - class TXID { - id: ThorId - constructor(json: TXIDJSON): TXID - toJSON() TXIDJSON - } - class TXIDJSON { - <> - id: string - } WebSocketClient <|.. BeatsSubscription WebSocketClient <|.. BlocksSubscription WebSocketClient <|.. EventsSubscription diff --git a/docs/diagrams/v2/net/thor/transactions/transactions-module.md b/docs/diagrams/v2/net/thor/transactions/transactions-module.md deleted file mode 100644 index cc628faa4..000000000 --- a/docs/diagrams/v2/net/thor/transactions/transactions-module.md +++ /dev/null @@ -1,97 +0,0 @@ -```mermaid -classDiagram - class HttpClient { - <> - } - class ThorRequest~Request~ { - <> - ThorResponse~Request~ askTo(HttpClient httpClient) - } - class ThorResponse~Response~ { - <> - ThorRequest~Request~ request - Response response - } - namespace Request { - class RetrieveTransactionByID { - HexUInt id - RetrieveTransactionByID_Query query - } - class RetrieveTransactionByID_Query { - BlockId head - boolean pending - boolean raw - } - class RetrieveTransactionReceipt { - HexUInt id - RetrieveTransactionReceipt_Query query - } - class RetrieveTransactionReceipt_Query { - BlockId head - } - class SendTransaction { - } - class SendTransaction_Body { - HexUInt raw - } - } - namespace Response { - class SendTransactionResponse { - HexUInt id - } - class GetTxResponse { - HexUInt id - Address origin - Address delegator - number size - number chainTag - string BlockRef - number expiration - Clause[] clauses - number gasPriceCoef - VTHO gaa - HexUInt dependsOn - HexUInt nonce - TxMeta meta - } - class GetTxReceiptResponse { - number gasUsed - Address gasPayer - VTHO paid - VTHO reward - boolean reverted - TransactionOutput[] outputs - ReceiptMeta meta - } - } - class Clause { - Address to - VET value - HexUInt data - } - class TxMeta { - BlockID blockID - number blockBumber - number BlockTimeestamp - } - - HttpClient o-- ThorRequest - - ThorRequest <|.. RetrieveTransactionByID - ThorRequest <|.. RetrieveTransactionReceipt - ThorRequest <|.. SendTransaction - - ThorRequest --* ThorResponse - - ThorResponse <|.. GetTxResponse - ThorResponse <|.. GetTxReceiptResponse - ThorResponse <|.. SendTransactionResponse - - RetrieveTransactionByID --* RetrieveTransactionByID_Query - RetrieveTransactionReceipt --* RetrieveTransactionReceipt_Query - SendTransaction --* SendTransaction_Body - - GetTxResponse --* Clause - GetTxResponse --* TxMeta - -``` diff --git a/docs/diagrams/v2/net/thor/transactions/transactions.md b/docs/diagrams/v2/net/thor/transactions/transactions.md index a41477ca7..78cba088f 100644 --- a/docs/diagrams/v2/net/thor/transactions/transactions.md +++ b/docs/diagrams/v2/net/thor/transactions/transactions.md @@ -1,27 +1,47 @@ ```mermaid classDiagram + namespace http { + class HttpClient { + <> + get(httpPath: HttpPath) Promise~Response~ + post(httpPath: HttpPath, body?: unknown) Promise~Response~ + } + class HttpPath { + <> + path: string + } + } + namespace thor { + class ThorRequest~RequestClass~ { + <> + askTo(httpClient: HttpClient Promise~ThorResponse~ResponseClass~~ + } + class ThorResponse~ResponseClass~ { + <> + request: ThorRequest~RequestClass~ + response: ResponseClass + } + } class Clause { - to: Address + to?: Address value: VET data: HexUInt - constructor(json: EventJSON) - toJSON() EventJSON + constructor(json: ClauseJSON) Clause + toJSON() ClauseJSON } class ClauseJSON { - <> - to: string + to?: string value: string - data string + data: string } class Event { address: Address topics: ThorId[] - data HexUInt - constructor(json: EventJSON) + data: HexUInt + constructor(json: EventJSON) Event toJSON() EventJSON } class EventJSON { - <> address: string topics: string[] data: string @@ -29,18 +49,17 @@ classDiagram class GetRawTxResponse { raw: HexUInt meta: TxMeta - constructor(json: GetTawTxResponseJSON) - toJSON() GetTawTxResponseJSON + constructor(json: GetRawTxResponseJSON) GetRawTxResponse + toJSON() GetRawTxResponseJSON } class GetRawTxResponseJSON { - <> - raw: string; + raw: string meta: TxMetaJSON } class GetTxReceiptResponse { meta: ReceiptMeta - constructor(json: GetTxReceiptResponseJSON) - toJSON(): GetTxReceiptResponseJSON + constructor(json: GetTxReceiptResponseJSON) GetTxReceiptResponse + toJSON() GetTxReceiptResponseJSON } class GetTxReceiptResponseJSON { meta: ReceiptMetaJSON @@ -48,7 +67,7 @@ classDiagram class GetTxResponse { id: TxId origin: Address - delegator: Address|null + delegator?: Address size: UInt chainTag: UInt blockRef: BlockId @@ -56,17 +75,16 @@ classDiagram clauses: Clause[] gasPriceCoef: UInt gas: VTHO - dependsOn: TxId|null + dependsOn?: TxId nonce: Nonce meta: TxMeta - constructor(json: GetTxResponseJSON) + constructor(json: GetTxResponseJSON) GetTxResponse toJSON() GetTxResponseJSON } class GetTxResponseJSON { - <> id: string origin: string - delegator: string|null + delegator?: string size: number chainTag: number blockRef: string @@ -74,10 +92,22 @@ classDiagram clauses: ClauseJSON[] gasPriceCoef: number gas: number - dependsOn: string|null + dependsOn?: string nonce: string meta: TxMetaJSON } + class TxMeta { + blockID: BlockId + blockNumber: UInt + blockTimestamp: bigint + constructor(json: TxMetaJSON) TxMeta + toJSON() TxMetaJSON + } + class TxMetaJSON { + blockID: string + blockNumber: number + blockTimestamp: bigint + } class Receipt { gasUsed: VTHO gasPayer: Address @@ -85,26 +115,24 @@ classDiagram reward: VTHO reverted: boolean outputs: ReceiptOutput[] - constructor(json: ReceiptJSON) + constructor(json: ReceiptJSON) Receipt toJSON() ReceiptJSON } class ReceiptJSON { - <> - gasUsed: number; - gasPayer: string; - paid: string; - reward: string; - reverted: boolean; - outputs: ReceiptOutputJSON[]; + gasUsed: number + gasPayer: string + paid: string + reward: string + reverted: boolean + outputs: ReceiptOutputJSON[] } class ReceiptMeta { txID: TxId txOrigin: Address - constructor(json: ReceiptMetaJSON) + constructor(json: ReceiptMetaJSON) ReceiptMeta toJSON() ReceiptMetaJSON } class ReceiptMetaJSON { - <> txID: string txOrigin: string } @@ -112,142 +140,130 @@ classDiagram contractAddress: Address events: Event[] transfers: Transfer[] - constructor(json: ReceiptOutputJSON) - toJSON(): ReceiptOutputJSON + constructor(json: ReceiptOutputJSON) ReceiptOutput + toJSON() ReceiptOutputJSON } class ReceiptOutputJSON { - <> contractAddress: string events: EventJSON[] transfers: TransferJSON[] } class RetrieveRawTransactionByID { - path: RetrieveRawTransactionByIDPath; - query: RetrieveRawTransactionByIDQuery; - constructor(path: RetrieveRawTransactionByIDPath, query: RetrieveRawTransactionByIDQuery) - askTo(httpClient: HttpClient): Promise~ThorResponse~ RetrieveRawTransactionByID, GetRawTxResponse~~ - of(txId: TxId) RetrieveRawTransactionByID - withHead(head: BlockId|null) RetrieveRawTransactionByID - withPending(pending: boolean) RetrieveRawTransactionByID - } - class RetrieveRawTransactionByIDPath { - } - class RetrieveRawTransactionByIDQuery { - } - class RetrieveTransactionByID { - path: RetrieveTransactionByIDPath - query: RetrieveTransactionByIDQuery - constructor(path: RetrieveTransactionByIDPath, query: RetrieveTransactionByIDQuery) - askTo(httpClient: HttpClient) Promise~ThorResponse~ RetrieveTransactionByID, GetTxResponse~~ - of(txId: TxId) RetrieveTransactionByID - withHead(head: BlockId|null): RetrieveTransactionByID - withPending(pending: boolean): RetrieveTransactionByID + path: RetrieveRawTransactionByIDPath + query: RetrieveRawTransactionByIDQuery + askTo(httpClient: HttpClient) Promise~ThorResponse~ + of(txId: TxId) RetrieveRawTransactionByID$ + withHead(head?: BlockId) RetrieveTransactionByID$ + withPending(pending: boolean) RetrieveTransactionByID$ } class RetrieveTransactionByIDPath { txId: TxId - constructor(txId: TxId) } class RetrieveTransactionByIDQuery { - head: BlockId | null; + head?: BlockId pending: boolean - constructor(head: BlockId|null, pending: boolean) RetrieveTransactionByIDQuery } class RetrieveTransactionReceipt { path: RetrieveTransactionReceiptPath query: RetrieveTransactionReceiptQuery - constructor(path: RetrieveTransactionReceiptPath, query: RetrieveTransactionReceiptQuery) - askTo(httpClient: HttpClient): Promise~ThorResponse~ RetrieveTransactionReceipt, GetTxReceiptResponse~~ - of(txId: TxId): RetrieveTransactionReceipt - withHead(head: BlockId): RetrieveTransactionReceipt + askTo(httpPath: HttpPath) Promise~ThorResponse~GetTxReceiptResponse~~ + of(txId: TxId) RetrieveTransactionReceipt$ + withHead(head?: BlockId) RetrieveTransactionReceipt } class RetrieveTransactionReceiptPath { txId: TxId - constructor(txId: TxId) } class RetrieveTransactionReceiptQuery { - head: BlockId|null; - constructor(head: BlockId|null) + head?: BlockId } class SendTransaction { - PATH: HttpPath + PATH: HttpPath$ encoded: Uint8Array - askTo(httpClient: httpClient) - of(encoded: Uint8Array): SendTransaction + askTo(httpPath: HttpPath) Promise~ThorResponse~TXID~~ + of(encoded: Uint8Array) SendTransaction$ } class Transfer { - sender: Address; - recipient: Address; - amount: VET; - constructor(json: TransferJSON) - toJSON(): TransferJSON + sender: Address + recipient: Address + amount: VET + constructor(json: TransferJSON) Transfer + toJSON() TransferJSON } class TransferJSON { - <> - sender: string; - recipient: string; - amount: string; - } - class TxMeta { - blockID: BlockId; - blockNumber: UInt; - blockTimestamp: bigint; - constructor(json: TxMetaJSON) - toJSON(): TxMetaJSON + sender: string + recipient: string + amount: string } - class TxMetaJSON { - <> - blockID: string; - blockNumber: number; - blockTimestamp: bigint; + class TXID { + id: ThorId + constructor(json: TXIDJSON): TXID + toJSON() TXIDJSON } - class ThorRequest { + class TXIDJSON { <> - askTo: (httpClient: HttpClient) + id: string } - class HttpPath { - <> + class TxMeta { + blockID: BlockId + blockNumber: UInt + blockTimestamp: bigint + constructor(json: TxMetaJSON) TxMeta + toJSON() TxMetaJSON } - class HttpQuery { - <> + class TxMetaJSON { + blockID: string + blockNumber: number + blockTimestamp: bigint } - RetrieveRawTransactionByIDPath ..|> HttpPath - RetrieveTransactionByIDPath ..|> HttpPath - RetrieveTransactionReceiptPath ..|> HttpPath - RetrieveRawTransactionByIDQuery ..|> HttpQuery - RetrieveTransactionByIDQuery ..|> HttpQuery - RetrieveTransactionReceiptQuery ..|> HttpQuery - ThorRequest <|.. RetrieveRawTransactionByID - ThorRequest <|.. RetrieveTransactionByID - ThorRequest <|.. RetrieveTransactionReceipt - ThorRequest <|.. SendTransaction + Clause --> "new - toJSON" ClauseJSON + Event --> "new - toJSON" EventJSON + GetRawTxResponse *--> TxMeta + GetRawTxResponse --> "new - toJSON" GetRawTxResponseJSON + GetRawTxResponse <-- "askTo" RetrieveRawTransactionByID + GetRawTxResponseJSON *--> TxMetaJSON + GetTxReceiptResponse *--> ReceiptMeta + GetTxReceiptResponse --> "new - toJSON" GetTxReceiptResponseJSON + GetTxReceiptResponseJSON *--> ReceiptMetaJSON + GetTxResponse *--> "*" Clause + GetTxResponse --> "new - toJSON" GetTxResponseJSON + GetTxResponseJSON *--> "*" ClauseJSON + HttpPath <--* SendTransaction + HttpPath <|.. RetrieveTransactionByIDPath + HttpPath <|.. RetrieveTransactionReceiptPath + HttpQuery <|.. RetrieveTransactionByIDQuery + HttpQuery <|.. RetrieveTransactionReceiptQuery + Receipt *--> "*" ReceiptOutput + Receipt --> "new - toJSON" ReceiptJSON Receipt <|-- GetTxReceiptResponse - RetrieveTransactionByIDPath <|-- RetrieveRawTransactionByIDPath - RetrieveTransactionByIDQuery <|-- RetrieveRawTransactionByIDQuery - TxMeta <-- ReceiptMeta + ReceiptJSON *--> "*" ReceiptOutputJSON + ReceiptJSON <|-- GetTxReceiptResponseJSON + ReceiptMeta --> "new - toJSON" ReceiptMetaJSON + ReceiptOutput *--> "*" Event + ReceiptOutput *--> "*" Transfer + ReceiptOutput --> "new - toJSON" ReceiptOutputJSON + ReceiptOutputJSON *--> "*" EventJSON + ReceiptOutputJSON *--> "*" TransferJSON RetrieveRawTransactionByID *--> RetrieveRawTransactionByIDPath RetrieveRawTransactionByID *--> RetrieveRawTransactionByIDQuery - RetrieveTransactionByID *--> RetrieveTransactionByIDPath - RetrieveTransactionByID *--> RetrieveRawTransactionByIDQuery + RetrieveRawTransactionByID --> "askTo" GetRawTxResponse + RetrieveTransactionByID --> "askTo" GetTxResponse + RetrieveTransactionByIDPath <|-- RetrieveRawTransactionByIDPath + RetrieveTransactionByIDQuery <|-- RetrieveRawTransactionByIDQuery RetrieveTransactionReceipt *--> RetrieveTransactionReceiptPath RetrieveTransactionReceipt *--> RetrieveTransactionReceiptQuery - GetRawTxResponse *--> TxMeta - GetTxReceiptResponse *--> ReceiptMeta - GetTxResponse *--> Clause - GetTxResponse *--> TxMeta - Receipt *--> ReceiptOutput - ReceiptOutput *--> Event - ReceiptOutput *--> Transfer - ClauseJSON <-- Clause - EventJSON <-- Event - GetRawTxResponseJSON <-- GetRawTxResponse - GetTxReceiptResponseJSON <-- GetTxReceiptResponse - GetTxResponseJSON <-- GetTxResponse - ReceiptJSON <-- Receipt - ReceiptMetaJSON <-- ReceiptMeta - ReceiptOutputJSON <-- ReceiptOutput - TransferJSON <-- Transfer - TxMetaJSON <-- TxMeta - GetRawTxResponse <-- RetrieveRawTransactionByID - GetTxResponse <-- RetrieveTransactionByID - GetTxReceiptResponse <-- RetrieveTransactionReceipt + RetrieveTransactionReceipt --> "askTo" GetTxReceiptResponse + SendTransaction --> "askTo" TXID + ThorRequest <|.. RetrieveRawTransactionByID + ThorRequest <|.. RetrieveTransactionByID + ThorRequest <|.. RetrieveTransactionReceipt + ThorRequest <|.. SendTransaction + ThorResponse <-- "askTo" RetrieveRawTransactionByID + ThorResponse <-- "askTo" RetrieveTransactionByID + ThorResponse <-- "askTo" RetrieveTransactionReceipt + ThorResponse <-- "askTo" SendTransaction + Transfer --> "new - toJSON" TransferJSON + TXID --> "new - toJSON" TXIDJSON + TxMeta --> "new - toJSON" TxMetaJSON + TxMeta <|-- ReceiptMeta + TxMetaJSON <|-- ReceiptMetaJSON ``` diff --git a/packages/net/src/thor/accounts/ExecuteCodesResponse.ts b/packages/net/src/thor/accounts/ExecuteCodesResponse.ts index 4aa25cedf..bdd547304 100644 --- a/packages/net/src/thor/accounts/ExecuteCodesResponse.ts +++ b/packages/net/src/thor/accounts/ExecuteCodesResponse.ts @@ -52,13 +52,6 @@ class ExecuteCodesResponse extends Array { ) ); } - - toJSON(): ExecuteCodesResponseJSON { - return this.map( - (response: ExecuteCodeResponse): ExecuteCodeResponseJSON => - response.toJSON() - ) as ExecuteCodesResponseJSON; - } } interface ExecuteCodeResponseJSON { diff --git a/packages/net/src/thor/subscriptions/NewTransactionSubscription.ts b/packages/net/src/thor/subscriptions/NewTransactionSubscription.ts index 8ef59755c..51a58f203 100644 --- a/packages/net/src/thor/subscriptions/NewTransactionSubscription.ts +++ b/packages/net/src/thor/subscriptions/NewTransactionSubscription.ts @@ -1,6 +1,6 @@ import { type WebSocketClient, type WebSocketListener } from '../../ws'; import type { HttpPath } from '../../http'; -import { TXID, type TXIDJSON } from './TXID'; +import { TXID, type TXIDJSON } from '../transactions/TXID'; class NewTransactionSubscription implements WebSocketClient, WebSocketListener diff --git a/packages/net/src/thor/subscriptions/TransfersSubscription.ts b/packages/net/src/thor/subscriptions/TransfersSubscription.ts index 2ae670e0d..0be102bb7 100644 --- a/packages/net/src/thor/subscriptions/TransfersSubscription.ts +++ b/packages/net/src/thor/subscriptions/TransfersSubscription.ts @@ -4,11 +4,11 @@ import { type WebSocketClient, type WebSocketListener } from '../../ws'; import { type SubscriptionTransferResponse } from './SubscriptionTransferResponse'; class TransfersSubscription - implements WebSocketClient, WebSocketListener + implements WebSocketClient, WebSocketListener { static readonly PATH: HttpPath = { path: '/subscriptions/transfer' }; - private readonly messageListeners: Array< + private readonly listeners: Array< WebSocketListener > = []; @@ -24,10 +24,25 @@ class TransfersSubscription this.query = query; } - addListener( - listener: WebSocketListener - ): this { - this.messageListeners.push(listener); + addListener(listener: WebSocketListener): WebSocketClient { + this.listeners.push(listener); + return this; + } + + close(): WebSocketClient { + this.wsc.close(); + return this; + } + + open(): WebSocketClient { + this.wsc.addListener(this).open({ + path: TransfersSubscription.PATH.path + this.query.query + }); + return this; + } + + removeListener(listener: WebSocketListener): WebSocketClient { + this.listeners.splice(this.listeners.indexOf(listener), 1); return this; } @@ -39,9 +54,16 @@ class TransfersSubscription return this.wsc.baseURL; } - close(): this { - this.wsc.close(); - return this; + onClose(event: Event): void { + this.listeners.forEach((listener) => { + listener.onClose(event); + }); + } + + onError(event: Event): void { + this.listeners.forEach((listener) => { + listener.onError(event); + }); } onMessage(event: MessageEvent): void { @@ -52,16 +74,15 @@ class TransfersSubscription event.type, { data: json } ); - this.messageListeners.forEach((listener) => { + this.listeners.forEach((listener) => { listener.onMessage(message); }); } - open(): this { - this.wsc - .addListener(this) - .open({ path: TransfersSubscription.PATH.path + this.query.query }); - return this; + onOpen(event: Event): void { + this.listeners.forEach((listener) => { + listener.onOpen(event); + }); } } diff --git a/packages/net/src/thor/subscriptions/index.ts b/packages/net/src/thor/subscriptions/index.ts index eef21e6d0..4f8935c99 100644 --- a/packages/net/src/thor/subscriptions/index.ts +++ b/packages/net/src/thor/subscriptions/index.ts @@ -7,4 +7,3 @@ export * from './SubscriptionBlockResponse'; export * from './SubscriptionEventResponse'; export * from './SubscriptionTransferResponse'; export * from './TransfersSubscription'; -export * from './TXID'; diff --git a/packages/net/src/thor/transactions/Clause.ts b/packages/net/src/thor/transactions/Clause.ts index 922adb697..e3f95c030 100644 --- a/packages/net/src/thor/transactions/Clause.ts +++ b/packages/net/src/thor/transactions/Clause.ts @@ -1,19 +1,19 @@ import { Address, HexUInt, VET } from '@vechain/sdk-core'; class Clause { - readonly to: Address | null; + readonly to?: Address; readonly value: VET; readonly data: HexUInt; constructor(json: ClauseJSON) { - this.to = json.to === null ? null : Address.of(json.to); + this.to = json.to !== undefined ? Address.of(json.to) : undefined; this.value = VET.of(json.value); this.data = HexUInt.of(json.data); } toJSON(): ClauseJSON { return { - to: this.to === null ? null : this.to.toString(), + to: this.to?.toString(), value: HexUInt.of(this.value.wei).toString(), data: this.data.toString() } satisfies ClauseJSON; @@ -21,7 +21,7 @@ class Clause { } interface ClauseJSON { - to: string | null; + to?: string; value: string; data: string; } diff --git a/packages/net/src/thor/transactions/GetTxResponse.ts b/packages/net/src/thor/transactions/GetTxResponse.ts index 59e0ce5e2..903548f0b 100644 --- a/packages/net/src/thor/transactions/GetTxResponse.ts +++ b/packages/net/src/thor/transactions/GetTxResponse.ts @@ -9,7 +9,7 @@ import { UInt } from '../../../../core/src/vcdm/UInt'; class GetTxResponse { readonly id: TxId; readonly origin: Address; - readonly delegator: Address | null; + readonly delegator?: Address; readonly size: UInt; readonly chainTag: UInt; readonly blockRef: BlockId; @@ -17,7 +17,7 @@ class GetTxResponse { readonly clauses: Clause[]; readonly gasPriceCoef: UInt; readonly gas: VTHO; - readonly dependsOn: TxId | null; + readonly dependsOn?: TxId; readonly nonce: Nonce; readonly meta: TxMeta; @@ -25,7 +25,9 @@ class GetTxResponse { this.id = TxId.of(json.id); this.origin = Address.of(json.origin); this.delegator = - json.delegator === null ? null : Address.of(json.delegator); + json.delegator !== undefined + ? Address.of(json.delegator) + : undefined; this.size = UInt.of(json.size); this.chainTag = UInt.of(json.chainTag); this.blockRef = BlockId.of(json.blockRef); @@ -36,7 +38,7 @@ class GetTxResponse { this.gasPriceCoef = UInt.of(json.gasPriceCoef); this.gas = VTHO.of(json.gas); this.dependsOn = - json.dependsOn === null ? null : TxId.of(json.dependsOn); + json.dependsOn !== undefined ? TxId.of(json.dependsOn) : undefined; this.nonce = Nonce.of(json.nonce); this.meta = new TxMeta(json.meta); } @@ -45,8 +47,7 @@ class GetTxResponse { return { id: this.id.toString(), origin: this.origin.toString(), - delegator: - this.delegator === null ? null : this.delegator.toString(), + delegator: this.delegator?.toString(), size: this.size.valueOf(), chainTag: this.chainTag.valueOf(), blockRef: this.blockRef.toString(), @@ -54,8 +55,7 @@ class GetTxResponse { clauses: this.clauses.map((clause) => clause.toJSON()), gasPriceCoef: this.gasPriceCoef.valueOf(), gas: Number(this.gas.wei), - dependsOn: - this.dependsOn === null ? null : this.dependsOn.toString(), + dependsOn: this.dependsOn?.toString(), nonce: this.nonce.toString(), meta: this.meta.toJSON() } satisfies GetTxResponseJSON; @@ -65,7 +65,7 @@ class GetTxResponse { interface GetTxResponseJSON { id: string; origin: string; - delegator: string | null; + delegator?: string; size: number; chainTag: number; blockRef: string; @@ -73,7 +73,7 @@ interface GetTxResponseJSON { clauses: ClauseJSON[]; gasPriceCoef: number; gas: number; - dependsOn: string | null; + dependsOn?: string; nonce: string; meta: TxMetaJSON; } diff --git a/packages/net/src/thor/transactions/ReceiptMeta.ts b/packages/net/src/thor/transactions/ReceiptMeta.ts index 2d896a1b9..47216cf0d 100644 --- a/packages/net/src/thor/transactions/ReceiptMeta.ts +++ b/packages/net/src/thor/transactions/ReceiptMeta.ts @@ -4,8 +4,8 @@ import { Address } from '@vechain/sdk-core'; import { TxId } from '../../../../core/src/vcdm/BlockId'; class ReceiptMeta extends TxMeta { - txID: TxId; - txOrigin: Address; + readonly txID: TxId; + readonly txOrigin: Address; constructor(json: ReceiptMetaJSON) { super(json); diff --git a/packages/net/src/thor/transactions/RetrieveRawTransactionByID.ts b/packages/net/src/thor/transactions/RetrieveRawTransactionByID.ts index 6cd6092cb..308098d0a 100644 --- a/packages/net/src/thor/transactions/RetrieveRawTransactionByID.ts +++ b/packages/net/src/thor/transactions/RetrieveRawTransactionByID.ts @@ -42,11 +42,11 @@ class RetrieveRawTransactionByID static of(txId: TxId): RetrieveRawTransactionByID { return new RetrieveRawTransactionByID( new RetrieveRawTransactionByIDPath(txId), - new RetrieveRawTransactionByIDQuery(null, false) + new RetrieveRawTransactionByIDQuery(undefined, false) ); } - withHead(head: BlockId | null = null): RetrieveRawTransactionByID { + withHead(head?: BlockId): RetrieveRawTransactionByID { return new RetrieveRawTransactionByID( this.path, new RetrieveRawTransactionByIDQuery(head, this.query.pending) diff --git a/packages/net/src/thor/transactions/RetrieveTransactionByID.ts b/packages/net/src/thor/transactions/RetrieveTransactionByID.ts index cc2625b1e..1ae1abc32 100644 --- a/packages/net/src/thor/transactions/RetrieveTransactionByID.ts +++ b/packages/net/src/thor/transactions/RetrieveTransactionByID.ts @@ -35,11 +35,11 @@ class RetrieveTransactionByID static of(txId: TxId): RetrieveTransactionByID { return new RetrieveTransactionByID( new RetrieveTransactionByIDPath(txId), - new RetrieveTransactionByIDQuery(null, false) + new RetrieveTransactionByIDQuery(undefined, false) ); } - withHead(head: BlockId | null = null): RetrieveTransactionByID { + withHead(head?: BlockId): RetrieveTransactionByID { return new RetrieveTransactionByID( this.path, new RetrieveTransactionByIDQuery(head, this.query.pending) @@ -67,16 +67,16 @@ class RetrieveTransactionByIDPath implements HttpPath { } class RetrieveTransactionByIDQuery implements HttpQuery { - readonly head: BlockId | null; + readonly head?: BlockId; readonly pending: boolean; - constructor(head: BlockId | null, pending: boolean) { + constructor(head: BlockId | undefined, pending: boolean) { this.head = head; this.pending = pending; } get query(): string { - const head = this.head === null ? '' : `${this.head}&`; + const head = this.head === undefined ? '' : `${this.head}&`; return `?${head}pending=${this.pending}&raw=false`; } } diff --git a/packages/net/src/thor/transactions/RetrieveTransactionReceipt.ts b/packages/net/src/thor/transactions/RetrieveTransactionReceipt.ts index 60994af0a..d1e9acad3 100644 --- a/packages/net/src/thor/transactions/RetrieveTransactionReceipt.ts +++ b/packages/net/src/thor/transactions/RetrieveTransactionReceipt.ts @@ -42,11 +42,11 @@ class RetrieveTransactionReceipt static of(txId: TxId): RetrieveTransactionReceipt { return new RetrieveTransactionReceipt( new RetrieveTransactionReceiptPath(txId), - new RetrieveTransactionReceiptQuery(null) + new RetrieveTransactionReceiptQuery(undefined) ); } - withHead(head: BlockId | null = null): RetrieveTransactionReceipt { + withHead(head?: BlockId): RetrieveTransactionReceipt { return new RetrieveTransactionReceipt( this.path, new RetrieveTransactionReceiptQuery(head) @@ -67,9 +67,9 @@ class RetrieveTransactionReceiptPath implements HttpPath { } class RetrieveTransactionReceiptQuery implements HttpQuery { - readonly head: BlockId | null; + readonly head?: BlockId; - constructor(head: BlockId | null) { + constructor(head: BlockId | undefined) { this.head = head; } diff --git a/packages/net/src/thor/transactions/SendTransaction.ts b/packages/net/src/thor/transactions/SendTransaction.ts index 72c01bea7..4f4aa6fc3 100644 --- a/packages/net/src/thor/transactions/SendTransaction.ts +++ b/packages/net/src/thor/transactions/SendTransaction.ts @@ -2,10 +2,9 @@ import { HexUInt } from '@vechain/sdk-core'; import { type HttpClient, type HttpPath } from '../../http'; import { type ThorRequest } from '../ThorRequest'; import { type ThorResponse } from '../ThorResponse'; +import { TXID, type TXIDJSON } from './TXID'; -import { TxId } from '../../../../core/src/vcdm/BlockId'; - -class SendTransaction implements ThorRequest { +class SendTransaction implements ThorRequest { static readonly PATH: HttpPath = { path: '/transactions' }; readonly encoded: Uint8Array; @@ -16,7 +15,7 @@ class SendTransaction implements ThorRequest { async askTo( httpClient: HttpClient - ): Promise> { + ): Promise> { const response = await httpClient.post( SendTransaction.PATH, { query: '' }, @@ -24,12 +23,11 @@ class SendTransaction implements ThorRequest { raw: HexUInt.of(this.encoded).toString() } ); - const responseBody = - (await response.json()) as SendTransactionResponseJSON; + const json = (await response.json()) as TXIDJSON; return { request: this, - response: TxId.of(responseBody.id) - } satisfies ThorResponse; + response: new TXID(json) + } satisfies ThorResponse; } static of(encoded: Uint8Array): SendTransaction { @@ -37,8 +35,4 @@ class SendTransaction implements ThorRequest { } } -interface SendTransactionResponseJSON { - id: string; -} - export { SendTransaction }; diff --git a/packages/net/src/thor/subscriptions/TXID.ts b/packages/net/src/thor/transactions/TXID.ts similarity index 100% rename from packages/net/src/thor/subscriptions/TXID.ts rename to packages/net/src/thor/transactions/TXID.ts diff --git a/packages/net/src/thor/transactions/index.ts b/packages/net/src/thor/transactions/index.ts index 41cd0ca72..65504bc01 100644 --- a/packages/net/src/thor/transactions/index.ts +++ b/packages/net/src/thor/transactions/index.ts @@ -10,5 +10,6 @@ export * from './RetrieveRawTransactionByID'; export * from './RetrieveTransactionByID'; export * from './RetrieveTransactionReceipt'; export * from './SendTransaction'; +export * from './TXID'; export * from './Transfer'; export * from './TxMeta'; diff --git a/packages/net/tests/thor/accounts/InspectClauses.testnet.test.ts b/packages/net/tests/thor/accounts/InspectClauses.testnet.test.ts index 193f7481c..bb0593b2a 100644 --- a/packages/net/tests/thor/accounts/InspectClauses.testnet.test.ts +++ b/packages/net/tests/thor/accounts/InspectClauses.testnet.test.ts @@ -28,7 +28,6 @@ describe('InspectClauses testnet tests', () => { data: '0x' }, { - to: null, value: '0x0', data: '0x6080604052348015600f57600080fd5b50609f8061001e6000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680631820cabb146044575b600080fd5b348015604f57600080fd5b506056606c565b6040518082815260200191505060405180910390f35b62015180815600a165627a7a723058200ac7475da248e2fc26c057319e296e90c24d5f8b9bf956fb3b77545642cad3b10029' } diff --git a/packages/net/tests/thor/blocks/RetrieveBlock.testnet.test.ts b/packages/net/tests/thor/blocks/RetrieveBlock.testnet.test.ts index 4dfc3a4f0..320cccc7d 100644 --- a/packages/net/tests/thor/blocks/RetrieveBlock.testnet.test.ts +++ b/packages/net/tests/thor/blocks/RetrieveBlock.testnet.test.ts @@ -1,10 +1,5 @@ import { describe, test } from '@jest/globals'; -import { - FetchHttpClient, - RetrieveBlock, - RetrieveBlockPath, - ThorNetworks -} from '../../../src'; +import { FetchHttpClient, RetrieveBlock, ThorNetworks } from '../../../src'; import { Revision } from '@vechain/sdk-core'; describe('RetrieveBlock testnet tests', () => { @@ -14,32 +9,4 @@ describe('RetrieveBlock testnet tests', () => { ); console.log(JSON.stringify(r, null, 2)); }); - - test('explore', async () => { - const httpClient = FetchHttpClient.at(ThorNetworks.TESTNET); - const lastBlockNumber = await getBestBlockNumber(httpClient); - for ( - let blockNumber = 0; - blockNumber <= lastBlockNumber; - blockNumber++ - ) { - const block = ( - await RetrieveBlock.of(Revision.of(blockNumber)).askTo( - httpClient - ) - ).response; - block.transactions.forEach((tx) => { - console.log(`${block.number}/${tx}`); - }); - } - }); - - async function getBestBlockNumber( - httpClient: FetchHttpClient - ): Promise { - const r = await new RetrieveBlock( - new RetrieveBlockPath(Revision.BEST) - ).askTo(httpClient); - return r.response.number.valueOf(); - } }); diff --git a/packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts b/packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts index 68790d5fc..28572b9ad 100644 --- a/packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts +++ b/packages/net/tests/thor/subscriptions/BeatsSubscription.solo.test.ts @@ -23,6 +23,15 @@ describe('BlocksSubscription solo tests', () => { const data = message.data; console.log(JSON.stringify(data, null, 2)); done(); + }, + onOpen: () => { + console.log('WebSocket connection opened'); + }, + onClose: () => { + console.log(`WebSocket connection closed`); + }, + onError: (error) => { + console.error('WebSocket encountered an error:', error); } } satisfies WebSocketListener) .open(); diff --git a/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts b/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts index 92ce0007c..da30ba968 100644 --- a/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts +++ b/packages/net/tests/thor/subscriptions/BlocksSubscription.solo.test.ts @@ -23,6 +23,11 @@ describe('BlocksSubscription solo tests', () => { const data = message.data; console.log(JSON.stringify(data, null, 2)); done(); + }, + onOpen: () => {}, + onClose: () => {}, + onError: (error) => { + console.error('WebSocket error:', error); } } satisfies WebSocketListener) .open(); diff --git a/packages/net/tests/thor/subscriptions/NewTransactionSubscription.solo.test.ts b/packages/net/tests/thor/subscriptions/NewTransactionSubscription.solo.test.ts index aa3af3ab7..d70ef1978 100644 --- a/packages/net/tests/thor/subscriptions/NewTransactionSubscription.solo.test.ts +++ b/packages/net/tests/thor/subscriptions/NewTransactionSubscription.solo.test.ts @@ -3,10 +3,8 @@ import { MozillaWebSocketClient, type WebSocketListener } from '../../../src/ws'; -import { - NewTransactionSubscription, - type TXID -} from '../../../src/thor/subscriptions'; +import { NewTransactionSubscription } from '../../../src/thor/subscriptions'; +import { type TXID } from '../../../src'; describe('NewTransactionSubscription solo tests', () => { let subscription: NewTransactionSubscription; @@ -23,7 +21,10 @@ describe('NewTransactionSubscription solo tests', () => { const data = message.data; console.log(JSON.stringify(data, null, 2)); done(); - } + }, + onClose: () => {}, + onError: () => {}, + onOpen: () => {} } satisfies WebSocketListener) .open(); }, 30000); From 4e22ce0049fd4d7cc298bd06414e80be51ffe7d6 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 1 Jan 2025 12:37:48 +0100 Subject: [PATCH 91/98] feat: 1484 node documented --- .../v2/net/thor/transactions/transactions.md | 4 +-- packages/net/src/thor/transactions/Clause.ts | 12 ++++++--- .../src/thor/transactions/GetTxResponse.ts | 26 +++++++++++-------- .../RetrieveTransactionReceipt.ts | 2 +- 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/docs/diagrams/v2/net/thor/transactions/transactions.md b/docs/diagrams/v2/net/thor/transactions/transactions.md index 78cba088f..8d9a1c6a0 100644 --- a/docs/diagrams/v2/net/thor/transactions/transactions.md +++ b/docs/diagrams/v2/net/thor/transactions/transactions.md @@ -67,7 +67,7 @@ classDiagram class GetTxResponse { id: TxId origin: Address - delegator?: Address + delegator: Address | null size: UInt chainTag: UInt blockRef: BlockId @@ -84,7 +84,7 @@ classDiagram class GetTxResponseJSON { id: string origin: string - delegator?: string + delegator: string | null size: number chainTag: number blockRef: string diff --git a/packages/net/src/thor/transactions/Clause.ts b/packages/net/src/thor/transactions/Clause.ts index e3f95c030..936115770 100644 --- a/packages/net/src/thor/transactions/Clause.ts +++ b/packages/net/src/thor/transactions/Clause.ts @@ -6,14 +6,20 @@ class Clause { readonly data: HexUInt; constructor(json: ClauseJSON) { - this.to = json.to !== undefined ? Address.of(json.to) : undefined; + this.to = + json.to !== undefined && json.to != null + ? Address.of(json.to) + : undefined; this.value = VET.of(json.value); this.data = HexUInt.of(json.data); } toJSON(): ClauseJSON { return { - to: this.to?.toString(), + to: + this.to !== undefined && this.to !== null + ? this.to.toString() + : undefined, value: HexUInt.of(this.value.wei).toString(), data: this.data.toString() } satisfies ClauseJSON; @@ -21,7 +27,7 @@ class Clause { } interface ClauseJSON { - to?: string; + to?: string | null; value: string; data: string; } diff --git a/packages/net/src/thor/transactions/GetTxResponse.ts b/packages/net/src/thor/transactions/GetTxResponse.ts index 903548f0b..2c3eba646 100644 --- a/packages/net/src/thor/transactions/GetTxResponse.ts +++ b/packages/net/src/thor/transactions/GetTxResponse.ts @@ -9,7 +9,7 @@ import { UInt } from '../../../../core/src/vcdm/UInt'; class GetTxResponse { readonly id: TxId; readonly origin: Address; - readonly delegator?: Address; + readonly delegator: Address | null; readonly size: UInt; readonly chainTag: UInt; readonly blockRef: BlockId; @@ -17,7 +17,7 @@ class GetTxResponse { readonly clauses: Clause[]; readonly gasPriceCoef: UInt; readonly gas: VTHO; - readonly dependsOn?: TxId; + readonly dependsOn?: TxId | null; readonly nonce: Nonce; readonly meta: TxMeta; @@ -25,9 +25,7 @@ class GetTxResponse { this.id = TxId.of(json.id); this.origin = Address.of(json.origin); this.delegator = - json.delegator !== undefined - ? Address.of(json.delegator) - : undefined; + json.delegator !== null ? Address.of(json.delegator) : null; this.size = UInt.of(json.size); this.chainTag = UInt.of(json.chainTag); this.blockRef = BlockId.of(json.blockRef); @@ -38,7 +36,9 @@ class GetTxResponse { this.gasPriceCoef = UInt.of(json.gasPriceCoef); this.gas = VTHO.of(json.gas); this.dependsOn = - json.dependsOn !== undefined ? TxId.of(json.dependsOn) : undefined; + json.dependsOn !== undefined && json.dependsOn !== null + ? TxId.of(json.dependsOn) + : undefined; this.nonce = Nonce.of(json.nonce); this.meta = new TxMeta(json.meta); } @@ -47,15 +47,19 @@ class GetTxResponse { return { id: this.id.toString(), origin: this.origin.toString(), - delegator: this.delegator?.toString(), + delegator: + this.delegator != null ? this.delegator.toString() : null, size: this.size.valueOf(), chainTag: this.chainTag.valueOf(), blockRef: this.blockRef.toString(), expiration: this.expiration.valueOf(), - clauses: this.clauses.map((clause) => clause.toJSON()), + clauses: this.clauses?.map((clause) => clause.toJSON()), gasPriceCoef: this.gasPriceCoef.valueOf(), gas: Number(this.gas.wei), - dependsOn: this.dependsOn?.toString(), + dependsOn: + this.dependsOn !== undefined && this.dependsOn !== null + ? this.dependsOn.toString() + : undefined, nonce: this.nonce.toString(), meta: this.meta.toJSON() } satisfies GetTxResponseJSON; @@ -65,7 +69,7 @@ class GetTxResponse { interface GetTxResponseJSON { id: string; origin: string; - delegator?: string; + delegator: string | null; // The end point at https://mainnet.vechain.org/doc/stoplight-ui/#/schemas/GetTxResponse specifically returns `null`. size: number; chainTag: number; blockRef: string; @@ -73,7 +77,7 @@ interface GetTxResponseJSON { clauses: ClauseJSON[]; gasPriceCoef: number; gas: number; - dependsOn?: string; + dependsOn?: string | null; nonce: string; meta: TxMetaJSON; } diff --git a/packages/net/src/thor/transactions/RetrieveTransactionReceipt.ts b/packages/net/src/thor/transactions/RetrieveTransactionReceipt.ts index d1e9acad3..a89792b66 100644 --- a/packages/net/src/thor/transactions/RetrieveTransactionReceipt.ts +++ b/packages/net/src/thor/transactions/RetrieveTransactionReceipt.ts @@ -74,7 +74,7 @@ class RetrieveTransactionReceiptQuery implements HttpQuery { } get query(): string { - return this.head === null ? '' : `${this.head}&`; + return this.head === undefined ? '' : `${this.head}&`; } } From 7f8d35f829001fc7d45bc57c8605506127eb4e12 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 1 Jan 2025 13:01:27 +0100 Subject: [PATCH 92/98] feat: 1484 node documented --- docs/diagrams/v2/net/http/http.md | 13 +++++++++---- .../v2/net/thor/transactions/transactions.md | 16 ++++++++++++++-- .../thor/subscriptions/TransfersSubscription.ts | 8 ++++---- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/docs/diagrams/v2/net/http/http.md b/docs/diagrams/v2/net/http/http.md index d58d9c3c6..0178766de 100644 --- a/docs/diagrams/v2/net/http/http.md +++ b/docs/diagrams/v2/net/http/http.md @@ -8,13 +8,17 @@ classDiagram } class HttpClient { <> - get(httpPath: HttpPath) Promise~Response~ - post(httpPath: HttpPath, body?: unknown) Promise~Response~ + get(httpPath: HttpPath, httpQuery: HttpQuery) Promise~Response~ + post(httpPath: HttpPath, httpQuery: HttpQuery, body?: unknown) Promise~Response~ } class HttpPath { <> path: string } + class HttpQuery { + <> + query(): string; + } class OnRequest { <> onRequest(request: Request) Request @@ -23,8 +27,9 @@ classDiagram <> onResponse(response: Response) Response } - HttpPath <-- "get - post" HttpClient - HttpClient <|.. FetchHttpClient FetchHttpClient *--> OnRequest FetchHttpClient *--> OnResponse + HttpClient <|.. FetchHttpClient + HttpPath <-- "get - post" HttpClient + HttpQuery <-- "get - post" HttpClient ``` diff --git a/docs/diagrams/v2/net/thor/transactions/transactions.md b/docs/diagrams/v2/net/thor/transactions/transactions.md index 8d9a1c6a0..ae2d308f9 100644 --- a/docs/diagrams/v2/net/thor/transactions/transactions.md +++ b/docs/diagrams/v2/net/thor/transactions/transactions.md @@ -10,11 +10,18 @@ classDiagram <> path: string } + class HttpQuery { + <> + query(): string; + } } namespace thor { class ThorRequest~RequestClass~ { <> askTo(httpClient: HttpClient Promise~ThorResponse~ResponseClass~~ + of(txId: TxId) RetrieveTransactionByID$ + withHead(head?: BlockId) RetrieveTransactionByID + withPending(pending: boolean) RetrieveTransactionByID } class ThorResponse~ResponseClass~ { <> @@ -23,14 +30,14 @@ classDiagram } } class Clause { - to?: Address + to?: Address | null value: VET data: HexUInt constructor(json: ClauseJSON) Clause toJSON() ClauseJSON } class ClauseJSON { - to?: string + to?: string | null value: string data: string } @@ -156,6 +163,11 @@ classDiagram withHead(head?: BlockId) RetrieveTransactionByID$ withPending(pending: boolean) RetrieveTransactionByID$ } + class RetrieveTransactionByID { + path: RetrieveTransactionByIDPath + query: RetrieveTransactionByIDQuery + askTo(httpClient: HttpClient) Promise~ThorRespons~GetTxResponse~~ + } class RetrieveTransactionByIDPath { txId: TxId } diff --git a/packages/net/src/thor/subscriptions/TransfersSubscription.ts b/packages/net/src/thor/subscriptions/TransfersSubscription.ts index 0be102bb7..8e4d6c009 100644 --- a/packages/net/src/thor/subscriptions/TransfersSubscription.ts +++ b/packages/net/src/thor/subscriptions/TransfersSubscription.ts @@ -24,24 +24,24 @@ class TransfersSubscription this.query = query; } - addListener(listener: WebSocketListener): WebSocketClient { + addListener(listener: WebSocketListener): this { this.listeners.push(listener); return this; } - close(): WebSocketClient { + close(): this { this.wsc.close(); return this; } - open(): WebSocketClient { + open(): this { this.wsc.addListener(this).open({ path: TransfersSubscription.PATH.path + this.query.query }); return this; } - removeListener(listener: WebSocketListener): WebSocketClient { + removeListener(listener: WebSocketListener): this { this.listeners.splice(this.listeners.indexOf(listener), 1); return this; } From 602153e8525293c2ff0ddfab127ec5a593700785 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 7 Jan 2025 11:41:25 +0000 Subject: [PATCH 93/98] feat: 1484 transaction id flowchart --- .../v2/core/transaction/transaction_id.md | 29 +++++++++++++++++++ yarn.lock | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 docs/diagrams/v2/core/transaction/transaction_id.md diff --git a/docs/diagrams/v2/core/transaction/transaction_id.md b/docs/diagrams/v2/core/transaction/transaction_id.md new file mode 100644 index 000000000..0d6666c47 --- /dev/null +++ b/docs/diagrams/v2/core/transaction/transaction_id.md @@ -0,0 +1,29 @@ +```mermaid +flowchart TD + start((Start)) + stop(((stop))) + body[/TransactionBody/] + subgraph txHash["Transaction.getTransactionHash"] + txHash_encodeHash[Blake256.of] + txHash_encodePayer[Blake2b256.of] + txHash_encode[[encode]] + txHash_payer?{gasPayer?} + txHash_payer[/gasPayer/] + txHash_encode --> txHash_encodeHash + txHash_encodeHash --> txHash_payer? + txHash_payer? -- yes --> txHash_encodePayer + txHash_payer --> txHash_encodePayer + end + subgraph id["Transaction.id()"] + id_hash[Blake2b256.of] + id_origin[/origin/] + id_txHash[[getTransactionHash]] + id_origin --> id_hash + id_txHash --> id_hash + end + start --> body + body --> txHash_encode + txHash_encodePayer --> id_txHash + txHash_payer? -- no --> id_txHash + id_hash --> stop +``` diff --git a/yarn.lock b/yarn.lock index 3eb54d34c..22ff7cb4a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3845,7 +3845,7 @@ resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz#427d5549943a9c6fce808e39ea64dbe60d4047f1" integrity sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA== -"@scure/base@^1.2.1", "@scure/base@~1.2.1": +"@scure/base@^1.1.9", "@scure/base@^1.2.1", "@scure/base@~1.2.1": version "1.2.1" resolved "https://registry.npmjs.org/@scure/base/-/base-1.2.1.tgz#dd0b2a533063ca612c17aa9ad26424a2ff5aa865" integrity sha512-DGmGtC8Tt63J5GfHgfl5CuAXh96VF/LD8K9Hr/Gv0J2lAoRGlPOMpqMpMbCTOoOJMZCk2Xt+DskdDyn6dEFdzQ== From 0d0f3e10f382db5a1185737a9f2a3aed34a7147f Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 7 Jan 2025 11:45:33 +0000 Subject: [PATCH 94/98] feat: 1484 transaction id flowchart --- docs/diagrams/v2/core/transaction/transaction_id.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/diagrams/v2/core/transaction/transaction_id.md b/docs/diagrams/v2/core/transaction/transaction_id.md index 0d6666c47..db7e390fd 100644 --- a/docs/diagrams/v2/core/transaction/transaction_id.md +++ b/docs/diagrams/v2/core/transaction/transaction_id.md @@ -14,7 +14,7 @@ flowchart TD txHash_payer? -- yes --> txHash_encodePayer txHash_payer --> txHash_encodePayer end - subgraph id["Transaction.id()"] + subgraph tx_id["Transaction.id()"] id_hash[Blake2b256.of] id_origin[/origin/] id_txHash[[getTransactionHash]] From fa6847800896baaf3733b114c83cd161543c718f Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 7 Jan 2025 16:19:51 +0000 Subject: [PATCH 95/98] feat: 1484 transaction id flowchart --- .../v2/core/transaction/transaction_id.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/docs/diagrams/v2/core/transaction/transaction_id.md b/docs/diagrams/v2/core/transaction/transaction_id.md index db7e390fd..52d1a8398 100644 --- a/docs/diagrams/v2/core/transaction/transaction_id.md +++ b/docs/diagrams/v2/core/transaction/transaction_id.md @@ -3,7 +3,15 @@ flowchart TD start((Start)) stop(((stop))) body[/TransactionBody/] - subgraph txHash["Transaction.getTransactionHash"] + subgraph origin + origin_signature[\signature\] + origin_recover[["Secp256k1.recover(txHash,signature)"]] + origin_address["Address.ofPublicKey(publicKey)"] + origin_signature --> origin_recover + origin_recover --> origin_address + + end + subgraph txHash["Transaction.getTransactionHash(gasPayer?)"] txHash_encodeHash[Blake256.of] txHash_encodePayer[Blake2b256.of] txHash_encode[[encode]] @@ -11,13 +19,13 @@ flowchart TD txHash_payer[/gasPayer/] txHash_encode --> txHash_encodeHash txHash_encodeHash --> txHash_payer? - txHash_payer? -- yes --> txHash_encodePayer + txHash_payer? -. yes .-> txHash_encodePayer txHash_payer --> txHash_encodePayer end subgraph tx_id["Transaction.id()"] id_hash[Blake2b256.of] - id_origin[/origin/] - id_txHash[[getTransactionHash]] + id_origin[["origin()"]] + id_txHash[["getTransactionHash()"]] id_origin --> id_hash id_txHash --> id_hash end @@ -26,4 +34,5 @@ flowchart TD txHash_encodePayer --> id_txHash txHash_payer? -- no --> id_txHash id_hash --> stop + origin_address --> id_origin ``` From 9bccf8d1a6b4b5e3219dbc4ab354924a749ba3c8 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 7 Jan 2025 19:49:20 +0000 Subject: [PATCH 96/98] feat: 1484 transaction id flowchart --- .../v2/core/transaction/transaction_id.md | 170 +++++++++++++++++- 1 file changed, 164 insertions(+), 6 deletions(-) diff --git a/docs/diagrams/v2/core/transaction/transaction_id.md b/docs/diagrams/v2/core/transaction/transaction_id.md index 52d1a8398..5b7ab5335 100644 --- a/docs/diagrams/v2/core/transaction/transaction_id.md +++ b/docs/diagrams/v2/core/transaction/transaction_id.md @@ -1,17 +1,44 @@ +# Transaction IDs May Collide + +The class [`Transaction`](../../../../../packages/core/src/transaction/Transaction.ts) +provides the computed property `Transaction.id()` to compute the transaction's identifier +as (l.242) + +```typescript +public get id(): Blake2b256 { + if (this.isSigned) { + return Blake2b256.of( + nc_utils.concatBytes( + this.getTransactionHash().bytes, + this.origin.bytes + ) + ); + } + throw new UnavailableTransactionField( + 'Transaction.id()', + 'not signed transaction: id unavailable', + {fieldName: 'id'} + ); +} +``` + +The following flowchart shows the inputs, methods and properties involved. + ```mermaid flowchart TD start((Start)) stop(((stop))) body[/TransactionBody/] subgraph origin + origin_txHash[["getTransactionHash()"]] origin_signature[\signature\] origin_recover[["Secp256k1.recover(txHash,signature)"]] origin_address["Address.ofPublicKey(publicKey)"] - origin_signature --> origin_recover origin_recover --> origin_address - + origin_signature --> origin_recover + end - subgraph txHash["Transaction.getTransactionHash(gasPayer?)"] + subgraph tx_hash["Transaction.getTransactionHash(gasPayer?)"] txHash_encodeHash[Blake256.of] txHash_encodePayer[Blake2b256.of] txHash_encode[[encode]] @@ -29,10 +56,141 @@ flowchart TD id_origin --> id_hash id_txHash --> id_hash end - start --> body body --> txHash_encode - txHash_encodePayer --> id_txHash - txHash_payer? -- no --> id_txHash id_hash --> stop origin_address --> id_origin + origin_txHash --> origin_recover + start --> body + txHash_encodePayer --> id_txHash + txHash_payer? -- no --> id_txHash + +``` + +## Not Delegated Transaction ID + +NCC claims + +_1. ... The transaction signature is not incorporated into the hash computation; only the transaction hash as well as +the +originator’s address are taken into account._ (p.12) + +but we observe **the origin's address is derived by the origin's signature because the computed property** +`Transaction.origin` (l.304). + +```typescript +public get origin(): Address +{ + if (this.signature !== undefined) { + return Address.ofPublicKey( + // Get the origin public key. + Secp256k1.recover( + this.getTransactionHash().bytes, + // Get the (r, s) of ECDSA digital signature without gas payer params. + this.signature.slice(0, Secp256k1.SIGNATURE_LENGTH) + ) + ); + } + throw new UnavailableTransactionField( + 'Transaction.origin()', + 'not signed transaction, no origin', + {fieldName: 'origin'} + ); +} +``` + +NCC clams + +_ ... if a transaction was signed by a signer multiple times (or in case of different +transactions with colliding getTransactionHash()), the resulting signed transactions would +have the same ID._ (p.13) + +We observe if the transaction is signed multiple times, it results the same id if the +`TransactionBody` object is equal and the origin's signature is the same. + +### Question - ask NCC + +Since the origin's address is a function of the origin's signature, **what is the difference +between to compute BLAKE2B256** + +* **from the transaction hash and the origin's signature**, and +* **from the transaction hash and the origin's address derived from its signature?** + +--- + +## Delegated Transaction ID + +NCC claims + +_2. In the case of delegated transactions, the function above also fails to take the gas +payer’s (aka delegator’s) signature and address into account._ (p.13) + +We observe the claim is true: in the `Transaction.id` computed property at l.246 + +```typescript +this.getTransactionHash().bytes ``` + +does not pass the `gasPayer` as argument, hence NCC is right to claim + +_... if a given to-be-delegated transaction were +signed by multiple different gas payers, the resulting IDs would all be equal (and would also +be equal to the ID of a non-delegated transaction)._ (p.13) + +We observe the `reserved` flag in the `Transaction` body participates in the computed hash, hence +a delegated transaction should result in a different id then a not delegated transaction, +this is the only input in the BLAKE2B256 hash to differentiate the id transactions of the same +`TransactionBody` between the cases when the transaction is delegated and when is not. Since a transaction must +include the origin signature and if is delegated, must include the `reserved` property and a gas payer's signature, +we do not think there is a real useful case to forge the `reserved` field, nevertheless we think ** + +NCC recommends + +_Consider modifying the id() function such that it includes the signer’s signature, and the +delegator’s (wrong name for the "gas payer") address and signature, if the transaction is delegated._ (p.13) + +We think this should be done, but we must evaluate what is done in Thor as well and if the Thor ID algorithm must change +following the NCC recommendations. + +NCC recommends + +_... reflect on whether the id() function should product a different digest than the +getTransactionHash() of a delegated transaction._ (p.13) + +**We think the id of delegated transaction should be different form its transaction's hash, we observe they are +different - matter of test - because the `Transaction.id` hashes the result of `Transaction.getTransactionHash` +concatenated with the transaction;s origin address.** + +--- + +### Question - ask the protocol team + +**The `gasPayer` signature or its derived address is never considered in the computation of the transaction hash!** + +* **What is the algorithm used in the protocol**? + * **Is the same algorithm implemented the in e SDK?** + * **The algorithm in the protocol does consider the `taxPayer` address and signature in the computation of the id?** + +--- + +## ID Equality + +We presume is correct to state equal +[`TransactionBody`](../../../../../packages/core/src/transaction/TransactionBody.d.ts) +instances signed by the same origin and gas payer should return the same id. +Since Thor rejects a transaction with a spent id, the above criteria should never be a problem; +Thor blockchain should never have two transaction with the same id, ids should be unique. +However, the `TransactionBody` class exposes the `nonce` property that is involved in the computation +of the transaction's hash. + +### Question - ask the protocol team + +The `Transaction.encode` method processes an object of the +[`TransactionBody`](../../../../../packages/core/src/transaction/TransactionBody.d.ts) +class, the class provides the `nonce` property +The `nonce` property should be different for each transaction even if +the other properties of the transaction are equal, however no assumption are made about `nonce`. +* **Who sets the `nonce` property?** + +--- + + From 8e167d944c4c6f38ae6a673259d46f5053ee3f9a Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 8 Jan 2025 10:36:33 +0000 Subject: [PATCH 97/98] feat: 1484 transaction id flowchart --- docs/diagrams/v2/core/transaction/transaction_id.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/diagrams/v2/core/transaction/transaction_id.md b/docs/diagrams/v2/core/transaction/transaction_id.md index 5b7ab5335..13a4c509a 100644 --- a/docs/diagrams/v2/core/transaction/transaction_id.md +++ b/docs/diagrams/v2/core/transaction/transaction_id.md @@ -170,6 +170,7 @@ concatenated with the transaction;s origin address.** * **Is the same algorithm implemented the in e SDK?** * **The algorithm in the protocol does consider the `taxPayer` address and signature in the computation of the id?** +**According to our tests, Thor and SDK produce the same id for the same transaction!** --- ## ID Equality From b5d7050b74e4a34a72c677c804650b4bb5431110 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Wed, 8 Jan 2025 11:30:50 +0000 Subject: [PATCH 98/98] feat: 1484 transaction id flowchart --- docs/diagrams/v2/core/transaction/transaction_id.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/diagrams/v2/core/transaction/transaction_id.md b/docs/diagrams/v2/core/transaction/transaction_id.md index 13a4c509a..346b8ecb9 100644 --- a/docs/diagrams/v2/core/transaction/transaction_id.md +++ b/docs/diagrams/v2/core/transaction/transaction_id.md @@ -29,7 +29,7 @@ flowchart TD start((Start)) stop(((stop))) body[/TransactionBody/] - subgraph origin + subgraph origin["Transaction.origin()"] origin_txHash[["getTransactionHash()"]] origin_signature[\signature\] origin_recover[["Secp256k1.recover(txHash,signature)"]]