diff --git a/src/dto/rpc/IotaRpcSuite.ts b/src/dto/rpc/IotaRpcSuite.ts new file mode 100644 index 000000000..5fc511f8c --- /dev/null +++ b/src/dto/rpc/IotaRpcSuite.ts @@ -0,0 +1,1396 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +// Core interfaces + +export interface Milestone { + index: number + timestamp: number + milestoneId: string +} + +export interface Status { + isHealthy: boolean + latestMilestone: Milestone + confirmedMilestone: Milestone + pruningIndex: number +} + +export interface Metrics { + blocksPerSecond: number + referencedBlocksPerSecond: number + referencedRate: number +} + +export interface RentStructure { + vByteCost: number + vByteFactorData: number + vByteFactoKey: number +} + +export interface Protocol { + networkName: string + bech32Hrp: string + tokenSupply: string + version: number + minPowScore: number + belowMaxDepth: number + rentStructure: RentStructure +} + +export interface PendingProtocolParameter { + type: number + targetMilestoneIndex: number + protocolVersion: number + params: string +} + +export interface BaseToken { + name: string + tickerSymbol: string + unit: string + decimals: number + subunit: string + useMetricPrefix: boolean +} + +export interface NodeInfo { + name: string + version: string + status: Status + metrics: Metrics + supportedProtocolVersions: number[] + protocol: Protocol + pendingProtocolParameters: PendingProtocolParameter[] + baseToken: BaseToken + features: string[] +} + +export interface Block { + protocolVersion: number + parents: string[] + payload?: TransactionPayload | MilestonePayload | TaggedDataPayload | ReceiptPayload + nonce: string +} + +export interface TransactionPayload { + type: number // Set to value 6 to denote a Transaction Payload. + essence: TransactionEssence + unlocks: Array +} + +export interface TransactionEssence { + type: number + networkId: string + inputsCommitment: string + inputs: UTXOInput[] // Assume UTXOInput is an existing interface + outputs: (BasicOutput | AliasOutput | FoundryOutput | NFTOutput)[] // Assume these are existing interfaces + payload?: TaggedDataPayload // Assume TaggedDataPayload is an existing interface +} + +export interface UTXOInput { + type: number + transactionId: string + transactionOutputIndex: number +} + +export interface BasicOutput { + type: number // Set to value 3 to denote a Basic Output. + amount: string // The amount of IOTA tokens to deposit with this BasicOutput output. Plain string encoded number. + nativeTokens?: NativeToken[] // Native tokens held by the output. + unlockConditions: ( + | AddressUnlockCondition + | StorageDepositReturnUnlockCondition + | TimelockUnlockCondition + | ExpirationUnlockCondition + )[] // Unlock conditions that define how the output can be unlocked in a transaction. + features?: (SenderFeature | MetadataFeature | TagFeature)[] // Features that add utility to the output but do not impose unlocking conditions. +} + +export interface AliasOutput { + type: number + amount: string + nativeTokens?: NativeToken[] + aliasId: string + stateIndex: number + stateMetadata?: string + foundryCounter: number + unlockConditions: (StateControllerAddressUnlockCondition | GovernorAddressUnlockCondition)[] + features?: (SenderFeature | MetadataFeature)[] + immutableFeatures?: (IssuerFeature | MetadataFeature)[] +} + +export interface FoundryOutput { + type: number + amount: string + nativeTokens?: NativeToken[] + serialNumber: number + tokenScheme: SimpleTokenScheme[] + unlockConditions: ImmutableAliasAddressUnlockCondition[] + features?: MetadataFeature[] + immutableFeatures?: MetadataFeature[] +} + +export interface NFTOutput { + type: number + amount: string + nativeTokens?: NativeToken[] + nftId: string + unlockConditions: ( + | AddressUnlockCondition + | StorageDepositReturnUnlockCondition + | TimelockUnlockCondition + | ExpirationUnlockCondition + )[] + features?: (SenderFeature | IssuerFeature | MetadataFeature | TagFeature)[] + immutableFeatures?: (IssuerFeature | MetadataFeature)[] +} + +export interface NativeToken { + id: string + amount: string +} + +export interface Ed25519Address { + type: number + pubKeyHash: string +} + +export interface AliasAddress { + type: number + aliasId: string +} + +export interface NFTAddress { + type: number + nftId: string +} + +export interface AddressUnlockCondition { + type: number + address: Ed25519Address | AliasAddress | NFTAddress +} + +export interface ImmutableAliasAddressUnlockCondition { + type: number + address: AliasAddress +} + +export interface StorageDepositReturnUnlockCondition { + type: number + returnAddress: Ed25519Address | AliasAddress | NFTAddress + returnAmount: string +} + +export interface TimelockUnlockCondition { + type: number + unixTime: number +} + +export interface ExpirationUnlockCondition { + type: number + returnAddress: Ed25519Address | AliasAddress | NFTAddress + unixTime: number +} + +export interface StateControllerAddressUnlockCondition { + type: number + address: Ed25519Address | AliasAddress | NFTAddress +} + +export interface GovernorAddressUnlockCondition { + type: number + address: Ed25519Address | AliasAddress | NFTAddress +} + +export interface SenderFeature { + type: number + address: Ed25519Address | AliasAddress | NFTAddress +} + +export interface IssuerFeature { + type: number + address: Ed25519Address | AliasAddress | NFTAddress +} + +export interface MetadataFeature { + type: number + data: string +} + +export interface TagFeature { + type: number + tag: string +} + +export interface SimpleTokenScheme { + type: number + mintedTokens: string + meltedTokens: string + maxSupply: string +} + +export interface SignatureUnlock { + type: number + signature: Ed25519Signature +} + +export interface Ed25519Signature { + type: number // Set to value 0 to denote an Ed25519 Signature. + publicKey: string // The public key of the Ed25519 keypair which is used to verify the signature. Hex-encoded with 0x prefix. + signature: string // The signature signing the serialized Transaction Essence. Hex-encoded with 0x prefix. +} + +export interface ReferenceUnlock { + type: number + reference: number +} + +export interface AliasUnlock { + type: number // Set to value 2 to denote an Alias Unlock. + reference: number // Represents the index of a previous unlock. +} + +export interface NFTUnlock { + type: number + reference: number +} + +export interface MilestonePayload { + type: number + index: number + timestamp: number + protocolVersion: number + previousMilestoneId: string + parents: string[] + inclusionMerkleRoot: string + appliedMerkleRoot: string + options: (ReceiptPayload | ProtocolParamsMilestoneOpt)[] + metadata?: string + signatures: Ed25519Signature[] +} + +export interface TaggedDataPayload { + type: number + tag?: string + data?: string +} + +export interface TreasuryTransactionPayload { + type: number + input: TreasuryInput + output: TreasuryOutput +} + +export interface TreasuryInput { + type: number + milestoneId: string +} + +export interface TreasuryOutput { + type: number + amount: string +} + +export interface Peer { + id: string + multiAddresses: string[] + alias?: string + relation: 'known' | 'unknown' | 'autopeered' + connected: boolean + gossip?: Gossip +} + +export interface Gossip { + heartbeat: Heartbeat | null + metrics: Metrics +} + +export interface Heartbeat { + solidMilestoneIndex: number + prunedMilestoneIndex: number + latestMilestoneIndex: number + connectedNeighbors: number + syncedNeighbors: number +} + +export interface Metrics { + newBlocks: number + knownBlocks: number + receivedBlocks: number + receivedBlockRequests: number + receivedMilestoneRequests: number + receivedHeartbeats: number + sentBlocks: number + sentBlockRequests: number + sentMilestoneRequests: number + sentHeartbeats: number + droppedPackets: number +} + +export interface ProtocolParamsMilestoneOpt { + type: number + targetMilestoneIndex: number + protocolVersion: number + params: string +} + +export interface ReceiptTuple { + receipt: ReceiptPayload + milestoneIndex: number +} + +export interface ReceiptPayload { + type: number + migratedAt: number + final: boolean + funds: MigratedFundsEntry[] + transaction: TreasuryTransactionPayload +} + +export interface MigratedFundsEntry { + tailTransactionHash: string + address: Ed25519Address + deposit: number +} + +export interface ErrorFormat { + error: { + code: string + message: string + } +} + +export interface TipsResponse { + tips: string[] +} + +export interface SubmitBlock { + protocolVersion: number + parents?: string[] + payload?: + | TransactionPayload + | MilestonePayload + | TaggedDataPayload + | TreasuryTransactionPayload + | ReceiptPayload + nonce?: string +} + +export interface BlockIdentifier { + blockId: string +} + +export interface BlockMetadata { + blockId: string + parents: string[] + isSolid: boolean + referencedByMilestoneIndex?: number + milestoneIndex?: number + ledgerInclusionState?: 'included' | 'conflicting' | 'noTransaction' + conflictReason?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 255 + whiteFlagIndex?: number + shouldPromote?: boolean + shouldReattach?: boolean +} + +export interface OutputResponse { + metadata: OutputMetadata + output: BasicOutput | AliasOutput | FoundryOutput | NFTOutput +} + +export interface OutputMetadata { + blockId: string + transactionId: string + outputIndex: number + isSpent: boolean + milestoneIndexSpent?: number + milestoneTimestampSpent?: number + transactionIdSpent?: string + milestoneIndexBooked: number + milestoneTimestampBooked: number + ledgerIndex: number +} + +export interface ReceiptsResponse { + receipts: ReceiptTuple[] +} + +export interface TreasuryResponse { + milestoneId: string + amount: string +} + +export interface UTXOChanges { + index: number + createdOutputs: string[] + consumedOutputs: string[] +} + +export type PeerResponse = Array + +export interface AddPeerRequest { + multiAddress: string + alias?: string +} + +export interface ComputeWhiteFlagRequest { + index: number + timestamp: number + parents: string[] + previousMilestoneId: string +} + +export interface ComputedMerkleRootResult { + inclusionMerkleRoot: string + appliedMerkleRoot: string +} + +export interface PruneDatabaseRequest { + index: number + depth: number + targetDatabaseSize: string +} + +export interface PruneDatabaseResponse { + index: number +} + +export interface CreateSnapshotsRequest { + index: number +} + +export interface CreateSnapshotsResponse { + index: number + filePath: string +} + +// Indexer interfaces +export interface OutputIdResponse { + ledgerIndex: number + cursor?: string | null + items: string[] +} + +export interface OutputSearchParams { + unlockableByAddress?: string + hasNativeTokens?: boolean + minNativeTokenCount?: number + maxNativeTokenCount?: number + createdBefore?: number + createdAfter?: number + pageSize?: number + cursor?: string +} + +export interface BasicOutputSearchParams extends OutputSearchParams { + address?: string + hasStorageDepositReturn?: boolean + storageDepositReturnAddress?: string + hasTimelock?: boolean + timelockedBefore?: number + timelockedAfter?: number + hasExpiration?: boolean + expiresBefore?: number + expiresAfter?: number + expirationReturnAddress?: string + sender?: string + tag?: string +} + +export interface AliasOutputSearchParams extends OutputSearchParams { + stateController?: string + governor?: string + issuer?: string + sender?: string +} + +export interface FoundryOutputsFilterParams extends OutputSearchParams { + aliasAddress?: string +} + +export interface NftOutputSearchParams extends BasicOutputSearchParams { + issuer?: string +} + +// Explorer interfaces + +export interface Balance { + totalBalance: string + availableBalance: string + ledgerIndex: number +} + +export interface BlockChildrenResponse { + blockId: string + maxResults?: number + count?: number + children?: string[] +} + +export interface LedgerUpdate { + address: string + outputId: string + isSpent: boolean +} + +export interface LedgerUpdateList { + milestoneIndex: number + items: LedgerUpdate[] + cursor?: string +} + +export interface LedgerUpdates { + address: string + items: Array<{ + milestoneIndex: number + milestoneTimestamp: number + outputId: string + isSpent: boolean + }> + cursor?: string +} + +export interface PagedMilestones { + items: { + milestoneId: string + index: number + }[] + cursor?: string +} + +export interface PagedBlockIdsByMilestone { + blocks: { + blockId: string + payloadType?: number + }[] + cursor?: string +} + +export interface RichestAddressesStatistics { + top: { + address: Ed25519Address | AliasAddress | NFTAddress + balance: string + }[] +} + +export interface WealthDistributionStatistics { + distribution: { + range: { + start: number + end: number + } + addressCount: string + totalBalance: string + }[] +} + +export interface MilestonesParams { + startTimestamp?: number + endTimestamp?: number + sort?: string + pageSize?: number + cursor?: string +} + +export interface BlocksByMilestoneParams { + milestoneId: string + sort?: string + pageSize?: number + cursor?: string +} + +export interface BlocksByMilestoneIndexParams { + milestoneIndex: number + sort?: string + pageSize?: number + cursor?: string +} + +export interface LedgerUpdatesByAddressParams { + address: string + pageSize?: number + sort?: 'asc' | 'desc' + startMilestoneIndex?: number + cursor?: string +} + +export interface LedgerUpdatesByMilestoneParams { + milestoneId: string + pageSize?: number + cursor?: string +} + +export interface TopRichestAddressesParams { + ledgerIndex?: number + top?: number +} + +// Wasp methods + +interface AccountFoundriesResponse { + foundrySerialNumbers: number[] +} + +interface AccountListResponse { + accounts: string[] +} + +interface AccountNFTsResponse { + nftIds: string[] +} + +interface AccountNonceResponse { + nonce: string +} + +interface AddUserRequest { + password: string + permissions: string[] + username: string +} + +interface AssetsJSON { + baseTokens: string + nativeTokens: NativeTokenJSON[] + nfts: string[] +} + +interface AssetsResponse { + baseTokens: string + nativeTokens: NativeTokenJSON[] +} + +interface AuthInfoModel { + authURL: string + scheme: string +} + +interface Blob { + hash: string + size: number +} + +interface BlobInfoResponse { + fields: { + [key: string]: number + } +} + +interface BlobListResponse { + Blobs: Blob[] +} + +interface BlobValueResponse { + valueData: string +} + +interface BlockInfoResponse { + blockIndex: number + numSuccessfulRequests: number + gasFeeCharged: string + previousAliasOutput: string + gasBurned: string + totalRequests: number + numOffLedgerRequests: number + timestamp: string +} + +interface BurnRecord { + code: number + gasBurned: number +} + +interface CallTargetJSON { + contractHName: string + functionHName: string +} + +interface ChainInfoResponse { + chainOwnerId: string + metadata: PublicChainMetadata + gasLimits: Limits + chainID: string + evmChainId: number + publicURL: string + gasFeePolicy: FeePolicy + isActive: boolean +} + +interface Output { + outputType: number + raw: string +} + +interface LastMessageGovernanceTx { + txId: string +} + +interface LastMessageStateTx { + stateIndex: number + txId: string +} + +interface LastMessageTxInclusionState { + txId: string + state: string +} + +interface LastMessageOnLedgerRequest { + output: Output + outputId: string + raw: string + id: string +} + +interface LastMessageOutput { + output: Output + outputId: string +} + +interface LastMessageAliasOutput { + outputType: number + raw: string +} + +interface LastMessagePullTxInclusionState { + txId: string +} + +interface LastMessagePullOutputByID { + outputId: string +} + +export interface ChainMessageMetrics { + outPublishGovernanceTransaction: OutPublishGovernanceTransaction + outPublisherStateTransaction: OutPublisherStateTransaction + inTxInclusionState: InTxInclusionState + inOnLedgerRequest: InOnLedgerRequest + inOutput: InOutput + inAliasOutput: InAliasOutput + inStateOutput: InStateOutput + outPullTxInclusionState: OutPullTxInclusionState + outPullLatestOutput: OutPullLatestOutput + outPullOutputByID: OutPullOutputByID +} + +interface OutPublishGovernanceTransaction { + lastMessage: LastMessageGovernanceTx + messages: number + timestamp: string +} + +interface OutPublisherStateTransaction { + lastMessage: LastMessageStateTx + messages: number + timestamp: string +} + +interface InTxInclusionState { + lastMessage: LastMessageTxInclusionState + messages: number + timestamp: string +} + +interface InOnLedgerRequest { + lastMessage: LastMessageOnLedgerRequest + messages: number + timestamp: string +} + +interface InOutput { + lastMessage: LastMessageOutput + messages: number + timestamp: string +} + +interface InAliasOutput { + lastMessage: LastMessageAliasOutput + messages: number + timestamp: string +} + +interface InStateOutput { + lastMessage: LastMessageOutput + messages: number + timestamp: string +} + +interface OutPullTxInclusionState { + lastMessage: LastMessagePullTxInclusionState + messages: number + timestamp: string +} + +interface OutPullLatestOutput { + lastMessage: string + messages: number + timestamp: string +} + +interface OutPullOutputByID { + lastMessage: LastMessagePullOutputByID + messages: number + timestamp: string +} + +interface ChainRecord { + accessNodes: string[] + isActive: boolean +} + +interface CommitteeNode { + accessAPI: string + node: PeeringNodeStatusResponse +} + +interface ConsensusPipeMetrics { + eventACSMsgPipeSize: number + eventPeerLogIndexMsgPipeSize: number + eventStateTransitionMsgPipeSize: number + eventTimerMsgPipeSize: number + eventVMResultMsgPipeSize: number +} + +interface ConsensusWorkflowMetrics { + currentStateIndex: number + flagBatchProposalSent: boolean + flagConsensusBatchKnown: boolean + flagInProgress: boolean + flagStateReceived: boolean + flagTransactionFinalized: boolean + flagTransactionPosted: boolean + flagTransactionSeen: boolean + flagVMResultSigned: boolean + flagVMStarted: boolean + timeBatchProposalSent: string + timeCompleted: string + timeConsensusBatchKnown: string + timeTransactionFinalized: string + timeTransactionPosted: string + timeTransactionSeen: string + timeVMResultSigned: string + timeVMStarted: string +} + +interface ContractCallViewRequest { + arguments: JSONDict + block: string + contractHName: string + contractName: string + functionHName: string + functionName: string +} + +interface ContractInfoResponse { + hName: string + name: string + programHash: string +} + +interface ControlAddressesResponse { + governingAddress: string + sinceBlockIndex: number + stateAddress: string +} + +interface DKSharesInfo { + address: string + peerIdentities: string[] + peerIndex: number + publicKey: string + publicKeyShares: string[] + threshold: number +} + +interface DKSharesPostRequest { + peerIdentities: string[] + threshold: number + timeoutMS: number +} + +interface ErrorMessageFormatResponse { + messageFormat: string +} + +interface EstimateGasRequestOffledger { + fromAddress: string + requestBytes: string +} + +interface EstimateGasRequestOnledger { + outputBytes: string +} + +interface EventJSON { + contractID: number + payload: string + timestamp: number + topic: string +} + +interface EventsResponse { + events: EventJSON[] +} + +interface FeePolicy { + evmGasRatio: Ratio32 + gasPerToken: Ratio32 + validatorFeeShare: number +} + +interface FeePolicy { + evmGasRatio: Ratio32 + gasPerToken: Ratio32 + validatorFeeShare: number +} + +interface FoundryOutputResponse { + assets: AssetsResponse + foundryId: string +} + +interface GovAllowedStateControllerAddressesResponse { + addresses: string[] +} + +interface GovChainInfoResponse { + chainOwnerId: string + metadata: GovPublicChainMetadata + gasLimits: Limits + chainID: string + publicURL: string + gasFeePolicy: FeePolicy +} + +interface GovChainOwnerResponse { + chainOwner: string +} + +interface GovPublicChainMetadata { + description: string + evmJsonRpcURL: string + evmWebSocketURL: string + name: string + website: string +} + +interface InOutput { + output: Output + outputId: string +} + +interface InStateOutput { + output: Output + outputId: string +} + +interface InfoResponse { + peeringURL: string + l1Params: L1Params + publicKey: string + version: string +} + +interface L1Params { + protocol: Protocol + maxPayloadSize: number + baseToken: BaseToken +} + +interface Item { + key: string + value: string +} + +interface Item { + key: string + value: string +} + +interface JSONDict { + Items: Item[] +} + +interface JSONDict { + Items: Item[] +} + +interface L1Params { + baseToken: BaseToken + maxPayloadSize: number + protocol: ProtocolParameters +} + +interface Limits { + maxGasExternalViewCall: number + maxGasPerBlock: number + maxGasPerRequest: number + minGasPerRequest: number +} + +interface LoginRequest { + password: string + username: string +} + +interface LoginResponse { + error: string + jwt: string +} + +interface NFTJSON { + id: string + issuer: string + metadata: string + owner: string +} + +interface NativeTokenIDRegistryResponse { + nativeTokenRegistryIds: string[] +} + +interface NativeTokenJSON { + amount: string + id: string +} + +interface NodeMessageMetrics { + registeredChainIDs: string[] +} + +interface NodeOwnerCertificateResponse { + certificate: string +} + +interface OffLedgerRequest { + chainId: string + request: string +} + +interface Output { + outputType: number + raw: string +} + +interface PeeringNodeIdentityResponse { + isTrusted: boolean + name: string + peeringURL: string + publicKey: string +} + +interface PeeringNodeStatusResponse { + isAlive: boolean + isTrusted: boolean + name: string + numUsers: number + peeringURL: string + publicKey: string +} + +interface PeeringNodeStatusResponse { + isAlive: boolean + isTrusted: boolean + name: string + numUsers: number + peeringURL: string + publicKey: string +} + +interface PeeringNodeStatusResponse { + isAlive: boolean + isTrusted: boolean + name: string + numUsers: number + peeringURL: string + publicKey: string +} + +interface PeeringTrustRequest { + name: string + peeringURL: string + publicKey: string +} + +interface ProtocolParameters { + bech32Hrp: string + belowMaxDepth: number + minPowScore: number + networkName: string + rentStructure: RentStructure + tokenSupply: string + version: number +} + +interface PublicChainMetadata { + description: string + evmJsonRpcURL: string + evmWebSocketURL: string + name: string + website: string +} + +interface WaitForRequestParams { + chainID: string + requestID: string + timeoutSeconds?: number + waitForL1Confirmation?: boolean +} + +interface Ratio32 { + a: number + b: number +} + +interface ReceiptResponse { + blockIndex: number + errorMessage?: string + gasBudget: string + gasBurnLog: BurnRecord[] + gasBurned: string + gasFeeCharged: string + request: RequestJSON + requestIndex: number + storageDepositCharged: string + rawError?: UnresolvedVMErrorJSON +} + +interface RequestIDsResponse { + requestIds: string[] +} + +interface RequestJSON { + allowance: AssetsJSON + callTarget: CallTargetJSON + fungibleTokens: AssetsJSON + gasBudget: string + isEVM: boolean + isOffLedger: boolean + nft: NFTJSON + params: JSONDict + requestId: string + senderAccount: string + targetAddress: string +} + +interface RequestProcessedResponse { + chainId: string + isProcessed: boolean + requestId: string +} + +interface StateResponse { + state: string +} + +interface UnresolvedVMErrorJSON { + code: string + params: string[] +} + +interface UpdateUserPasswordRequest { + password: string + username: string +} + +interface UpdateUserPermissionsRequest { + permissions: string[] + username: string +} + +interface User { + permissions: string[] + username: string +} + +interface VersionResponse { + version: string +} + +interface ChainIDParam { + chainID: string +} + +interface ChainIDAndBlockParam extends ChainIDParam { + block?: string +} + +interface ChainIDAndPeerParam extends ChainIDParam { + peer: string +} + +interface ChainIDAndRequestIDParam extends ChainIDParam { + requestID: string +} + +interface ChainIDAndBlockIndexParam extends ChainIDParam { + blockIndex: number + block?: string +} + +interface ChainIDAndSerialNumberParam extends ChainIDParam { + serialNumber: number + block?: string +} + +interface ChainIDAndBlobHashParam extends ChainIDParam { + blobHash: string + fieldKey?: string + block?: string +} + +interface ChainIDAndContractHnameParam extends ChainIDParam { + contractHname: string + block?: string +} + +interface ChainIDAndAgentIDParam extends ChainIDParam { + agentID: string + block?: string +} + +interface ChainIDAndNftIDParam extends ChainIDParam { + nftID: string + block?: string +} + +export interface CallViewParamsChainId extends ChainIDParam, ContractCallViewRequest {} + +export interface StateValueParams { + chainID: string + stateKey: string +} + +export interface ChainIDAndContractHnameErrorParam extends ChainIDAndContractHnameParam { + errorID: number +} + +export interface IotaRpcSuite { + // Core methods + getNodeHealth(): Promise + getAvailableRouteGroups(): Promise + getNodeInfo(): Promise + getTips(): Promise + submitBlock(params: SubmitBlock): Promise + getBlockDataById(params: BlockIdentifier): Promise + getBlockMetadata(params: BlockIdentifier): Promise + findOutputById(outputId: string): Promise + getOutputMetadata(outputId: string): Promise + getAllReceipts(): Promise + getReceiptsByMigrationIndex(migratedAt: number): Promise + getTransactionIncludedBlock(transactionId: string): Promise + findIncludedBlockMetadata(transactionId: string): Promise + getMilestoneById(milestoneId: string): Promise + getMilestoneUtxoChangesByMilestone(milestoneId: string): Promise + lookupMilestoneByIndex(index: number): Promise + getMilestoneUtxoChangesById(index: number): Promise + computeMerkleRouteHashes(params: ComputeWhiteFlagRequest): Promise + pruneDatabase(request: PruneDatabaseRequest): Promise + createSnapshot(requestData: CreateSnapshotsRequest): Promise + getTreasuryInformation(): Promise + getPeerInfo(peerId: string): Promise + getPeers(): Promise + addPeer(peerData: AddPeerRequest): Promise + + // Indexer methods + getOutputs(params: OutputSearchParams): Promise + getBasicOutputs(params: BasicOutputSearchParams): Promise + getAliasOutputs(params: AliasOutputSearchParams): Promise + getCurrentUnspentAliasOutput(aliasId: string): Promise + getFoundryOutputs(params: FoundryOutputsFilterParams): Promise + getCurrentUnspentFoundryOutput(foundryId: string): Promise + getNftOutputs(params: NftOutputSearchParams): Promise + getCurrentNftOutput(nftId: string): Promise + + // Explorer methods + getBalanceByAddress(address: string): Promise + getBlockChildren(blockId: string): Promise + getMilestones(params: MilestonesParams): Promise + getBlocksByMilestone(params: BlocksByMilestoneParams): Promise + getBlocksByMilestoneIndex(params: BlocksByMilestoneIndexParams): Promise + getLedgerUpdatesByAddress(params: LedgerUpdatesByAddressParams): Promise + getLedgerUpdatesByMilestone(params: LedgerUpdatesByMilestoneParams): Promise + getTopRichestAddresses(params: TopRichestAddressesParams): Promise + getTokenDistribution(ledgerIndex: number): Promise + + // Wasp methods + authenticate(params: { loginRequest: LoginRequest }): Promise + authInfo(): Promise + getHealth(): Promise + getChains(): Promise + getChainInfo(params: ChainIDAndBlockParam): Promise + removeAccessNode(params: ChainIDAndPeerParam): Promise + addAccessNode(params: ChainIDAndPeerParam): Promise + activateChain(params: ChainIDParam): Promise + callView(params: CallViewParamsChainId): Promise + setChainRecord(params: ChainIDParam, chainRecord: ChainRecord): Promise + getCommitteeInfo(params: ChainIDAndBlockParam): Promise + getContracts(params: ChainIDAndBlockParam): Promise + getAccounts(params: ChainIDAndBlockParam): Promise + accountsGetAccountBalance(params: ChainIDAndAgentIDParam): Promise + accountsGetAccountFoundries(params: ChainIDAndAgentIDParam): Promise + accountsGetAccountNFTIDs(params: ChainIDAndAgentIDParam): Promise + accountsGetAccountNonce(params: ChainIDAndAgentIDParam): Promise + accountsGetFoundryOutput(params: ChainIDAndSerialNumberParam): Promise + accountsGetNFTData(params: ChainIDAndNftIDParam): Promise + accountsGetNativeTokenIDRegistry(params: ChainIDAndBlockParam): Promise + accountsGetTotalAssets(params: ChainIDAndBlockParam): Promise + blobsGetAllBlobs(params: ChainIDAndBlockParam): Promise + blobsGetBlobInfo(params: ChainIDAndBlobHashParam): Promise + blobsGetBlobValue(params: ChainIDAndBlobHashParam): Promise + blocklogGetLatestBlockInfo(params: ChainIDAndBlockParam): Promise + blocklogGetRequestReceiptsOfLatestBlock(params: ChainIDAndBlockParam): Promise + blocklogGetRequestIDsForLatestBlock(params: ChainIDAndBlockParam): Promise + blocklogGetBlockInfo(params: ChainIDAndBlockIndexParam): Promise + blocklogGetRequestReceiptsOfBlock(params: ChainIDAndBlockIndexParam): Promise + blocklogGetRequestIDsForBlock(params: ChainIDAndBlockIndexParam): Promise + blocklogGetControlAddresses(params: ChainIDAndBlockParam): Promise + blocklogGetEventsOfLatestBlock(params: ChainIDAndBlockParam): Promise + blocklogGetEventsOfBlock(params: ChainIDAndBlockIndexParam): Promise + blocklogGetEventsOfContract(params: ChainIDAndContractHnameParam): Promise + blocklogGetEventsOfRequest(params: ChainIDAndRequestIDParam): Promise + blocklogGetRequestReceipt(params: ChainIDAndRequestIDParam): Promise + blocklogGetRequestIsProcessed(params: ChainIDAndRequestIDParam): Promise + errorsGetErrorMessageFormat(params: ChainIDAndContractHnameErrorParam): Promise + getAllowedStateControllerAddresses( + params: ChainIDAndBlockParam, + ): Promise + governanceGetChainInfo(params: ChainIDAndBlockParam): Promise + governanceGetChainOwner(params: ChainIDAndBlockParam): Promise + deactivateChain(params: ChainIDParam): Promise + estimateGasOffledger( + params: ChainIDParam, + requestBody: EstimateGasRequestOffledger, + ): Promise + estimateGasOnledger(params: ChainIDParam, requestBody: EstimateGasRequestOnledger): Promise + submitJSONRPCRequest(params: ChainIDParam): Promise + getEthereumJsonRpcWebsocket(params: ChainIDParam): Promise + getMempoolContents(params: ChainIDParam): Promise + getReceipt(params: ChainIDAndRequestIDParam): Promise + waitForRequest(params: WaitForRequestParams): Promise + getStateValue(params: StateValueParams): Promise + getChainMessageMetrics(params: ChainIDParam): Promise + getChainPipeMetrics(params: ChainIDParam): Promise + getChainWorkflowMetrics(params: ChainIDParam): Promise + getNodeMessageMetrics(): Promise + getConfiguration(): Promise + generateDKS(params: DKSharesPostRequest): Promise + getDKSInfo(sharedAddress: string): Promise + getInfo(): Promise + ownerCertificate(): Promise + getAllPeers(): Promise + getPeeringIdentity(): Promise + getTrustedPeers(): Promise + trustPeer(requestBody: PeeringTrustRequest): Promise + distrustPeer(peer: string): Promise + shutdownNode(): Promise + getVersion(): Promise + offLedger(requestBody: OffLedgerRequest): Promise + getUsers(): Promise + addUser(body: AddUserRequest): Promise + deleteUser(username: string): Promise + getUser(username: string): Promise + changeUserPassword(params: UpdateUserPasswordRequest): Promise + changeUserPermissions(params: UpdateUserPermissionsRequest): Promise + connectWebSocket(): Promise +} diff --git a/src/service/rpc/evm/AbstractBeaconV1EvmRpc.ts b/src/service/rpc/evm/AbstractBeaconV1EvmRpc.ts index 50ba24181..2c7f9723b 100644 --- a/src/service/rpc/evm/AbstractBeaconV1EvmRpc.ts +++ b/src/service/rpc/evm/AbstractBeaconV1EvmRpc.ts @@ -18,11 +18,11 @@ export abstract class AbstractBeaconV1EvmRpc implements EvmBeaconV1Interface { protected abstract get(get: GetI): Promise private sendGet(path: string, params: QueryParams, prefix?: string): Promise { - const fullPath = Utils.addQueryParams( - `${prefix ?? Constant.BEACON_PREFIX}/${path}`, - Utils.camelToSnakeCase, - params, - ) + const fullPath = Utils.addQueryParams({ + basePath: `${prefix ?? Constant.BEACON_PREFIX}/${path}`, + strategy: Utils.camelToSnakeCase, + queryParams: params, + }) return this.get({ path: fullPath }) } diff --git a/src/service/rpc/other/AbstractAlgorandAlgodRpc.ts b/src/service/rpc/other/AbstractAlgorandAlgodRpc.ts index 9f25eefc5..4ae454042 100644 --- a/src/service/rpc/other/AbstractAlgorandAlgodRpc.ts +++ b/src/service/rpc/other/AbstractAlgorandAlgodRpc.ts @@ -53,7 +53,11 @@ export abstract class AbstractAlgorandAlgodRpc implements AlgorandAlgodRpcSuite queryParams?: QueryParams }): Promise { const post: PostI = { - path: Utils.addQueryParams(path, Utils.camelToDashCase, queryParams), + path: Utils.addQueryParams({ + basePath: path, + strategy: Utils.camelToDashCase, + queryParams: queryParams, + }), } if (body) { @@ -64,7 +68,13 @@ export abstract class AbstractAlgorandAlgodRpc implements AlgorandAlgodRpcSuite } private async sendGet({ path, queryParams }: { path: string; queryParams?: QueryParams }): Promise { - return this.get({ path: Utils.addQueryParams(path, Utils.camelToDashCase, queryParams) }) + return this.get({ + path: Utils.addQueryParams({ + basePath: path, + strategy: Utils.camelToDashCase, + queryParams: queryParams, + }), + }) } broadcastTransaction(params: TransactionBroadcastRequest): Promise { diff --git a/src/service/rpc/other/AbstractAlgorandIndexerRpc.ts b/src/service/rpc/other/AbstractAlgorandIndexerRpc.ts index 0855807ee..fed4f2aa0 100644 --- a/src/service/rpc/other/AbstractAlgorandIndexerRpc.ts +++ b/src/service/rpc/other/AbstractAlgorandIndexerRpc.ts @@ -49,7 +49,13 @@ export abstract class AbstractAlgorandIndexerRpc implements AlgorandIndexerRpcSu protected abstract get(get: GetI): Promise private async sendGet({ path, queryParams }: { path: string; queryParams?: QueryParams }): Promise { - return this.get({ path: Utils.addQueryParams(path, Utils.camelToDashCase, queryParams) }) + return this.get({ + path: Utils.addQueryParams({ + basePath: path, + strategy: Utils.camelToDashCase, + queryParams: queryParams, + }), + }) } getAccount(params: AccountInformationRequest): Promise { diff --git a/src/service/rpc/other/AbstractIotaRpc.ts b/src/service/rpc/other/AbstractIotaRpc.ts new file mode 100644 index 000000000..185baadcb --- /dev/null +++ b/src/service/rpc/other/AbstractIotaRpc.ts @@ -0,0 +1,248 @@ +import { Service } from 'typedi' +import { QueryParams } from '../../../dto' +import { GetI } from '../../../dto/GetI' +import { PostI } from '../../../dto/PostI' +import { + AddPeerRequest, + AliasOutputSearchParams, + Balance, + BasicOutputSearchParams, + Block, + BlockChildrenResponse, + BlockIdentifier, + BlockMetadata, + BlocksByMilestoneIndexParams, + BlocksByMilestoneParams, + ComputedMerkleRootResult, + ComputeWhiteFlagRequest, + CreateSnapshotsRequest, + CreateSnapshotsResponse, + ErrorFormat, + FoundryOutputsFilterParams, + IotaRpcSuite, + LedgerUpdateList, + LedgerUpdatesByAddressParams, + LedgerUpdatesByMilestoneParams, + Milestone, + MilestonePayload, + MilestonesParams, + NftOutputSearchParams, + NodeInfo, + OutputIdResponse, + OutputMetadata, + OutputResponse, + OutputSearchParams, + PagedBlockIdsByMilestone, + Peer, + PeerResponse, + PruneDatabaseRequest, + PruneDatabaseResponse, + ReceiptsResponse, + RichestAddressesStatistics, + SubmitBlock, + TipsResponse, + TopRichestAddressesParams, + TreasuryResponse, + UTXOChanges, + WealthDistributionStatistics, +} from '../../../dto/rpc/IotaRpcSuite' +import { Utils } from '../../../util' + +@Service() +export abstract class AbstractIotaRpc implements IotaRpcSuite { + protected abstract post(post: PostI): Promise + protected abstract get(get: GetI): Promise + + private async sendGet({ path, queryParams }: { path: string; queryParams?: QueryParams }): Promise { + return this.get({ path: Utils.addQueryParams({ basePath: path, queryParams: queryParams }) }) + } + + getNodeHealth(): Promise { + return this.get({ path: '/health' }) + } + + getAvailableRouteGroups(): Promise { + return this.get({ path: '/api/routes' }) + } + + getNodeInfo(): Promise { + return this.get({ path: '/api/core/v2/info' }) + } + + getTips(): Promise { + return this.get({ path: '/api/core/v2/tips' }) + } + + submitBlock(params: SubmitBlock): Promise { + return this.post({ path: '/api/core/v2/blocks', body: params }) + } + + getBlockDataById(params: BlockIdentifier): Promise { + return this.get({ path: `/api/core/v2/blocks/${params.blockId}` }) + } + + getBlockMetadata(params: BlockIdentifier): Promise { + return this.get({ path: `/api/core/v2/blocks/${params.blockId}/metadata` }) + } + + findOutputById(outputId: string): Promise { + return this.get({ path: `/api/core/v2/outputs/${encodeURIComponent(outputId)}` }) + } + + getOutputMetadata(outputId: string): Promise { + return this.get({ path: `/api/core/v2/outputs/${encodeURIComponent(outputId)}/metadata` }) + } + + getAllReceipts(): Promise { + return this.get({ path: `/api/core/v2/receipts` }) + } + + getReceiptsByMigrationIndex(migratedAt: number): Promise { + return this.get({ path: `/api/core/v2/receipts/${migratedAt}` }) + } + + getTransactionIncludedBlock(transactionId: string): Promise { + return this.get({ path: `/api/core/v2/transactions/${transactionId}/included-block` }) + } + + findIncludedBlockMetadata(transactionId: string): Promise { + return this.get({ path: `/api/core/v2/transactions/${transactionId}/included-block/metadata` }) + } + + getMilestoneById(milestoneId: string): Promise { + return this.get({ path: `/api/core/v2/milestones/${milestoneId}` }) + } + + getMilestoneUtxoChangesByMilestone(milestoneId: string): Promise { + return this.get({ path: `/api/core/v2/milestones/${milestoneId}/utxo-changes` }) + } + + lookupMilestoneByIndex(index: number): Promise { + return this.get({ path: `/api/core/v2/milestones/by-index/${index}` }) + } + + getMilestoneUtxoChangesById(index: number): Promise { + return this.get({ path: `/api/core/v2/milestones/by-index/${index}/utxo-changes` }) + } + + computeMerkleRouteHashes(params: ComputeWhiteFlagRequest): Promise { + return this.post({ path: '/api/core/v2/whiteflag', body: params }) + } + + pruneDatabase(request: PruneDatabaseRequest): Promise { + return this.post({ path: '/api/core/v2/control/database/prune', body: request }) + } + + createSnapshot(requestData: CreateSnapshotsRequest): Promise { + return this.post({ path: `/api/core/v2/control/snapshot/create`, body: requestData }) + } + + getTreasuryInformation(): Promise { + return this.get({ path: '/api/core/v2/treasury' }) + } + + getPeerInfo(peerId: string): Promise { + return this.get({ path: `api/core/v2/peers/${peerId}` }) + } + + getPeers(): Promise { + return this.get({ path: '/api/core/v2/peers' }) + } + + addPeer(peerData: AddPeerRequest): Promise { + return this.post({ path: '/api/core/v2/peers', body: peerData }) + } + + getOutputs(params: OutputSearchParams): Promise { + return this.sendGet({ path: '/api/indexer/v1/outputs', queryParams: params as QueryParams }) + } + + getBasicOutputs(params: BasicOutputSearchParams): Promise { + return this.sendGet({ path: '/api/indexer/v1/outputs/basic', queryParams: params as QueryParams }) + } + + getAliasOutputs(params: AliasOutputSearchParams): Promise { + return this.sendGet({ path: '/api/indexer/v1/outputs/alias', queryParams: params as QueryParams }) + } + + getCurrentUnspentAliasOutput(aliasId: string): Promise { + return this.sendGet({ path: `/api/indexer/v1/outputs/alias/${aliasId}` }) + } + + getFoundryOutputs(params: FoundryOutputsFilterParams): Promise { + return this.sendGet({ path: '/api/indexer/v1/outputs/foundry', queryParams: params as QueryParams }) + } + + getCurrentUnspentFoundryOutput(foundryId: string): Promise { + return this.sendGet({ path: `/api/indexer/v1/outputs/foundry/${foundryId}` }) + } + + getNftOutputs(params: NftOutputSearchParams): Promise { + return this.sendGet({ path: '/api/indexer/v1/outputs/nft', queryParams: params as QueryParams }) + } + + getCurrentNftOutput(nftId: string): Promise { + return this.sendGet({ path: `/api/indexer/v1/outputs/nft/${nftId}` }) + } + + async getBalanceByAddress(address: string): Promise { + return this.sendGet({ path: `/api/explorer/v2/balance/${address}` }) + } + + async getBlockChildren(blockId: string): Promise { + return this.sendGet({ path: `/api/explorer/v2/blocks/${blockId}/children` }) + } + + async getMilestones(params: MilestonesParams): Promise { + return this.sendGet({ + path: `/api/explorer/v2/milestones`, + queryParams: params as QueryParams, + }) + } + + async getBlocksByMilestone(params: BlocksByMilestoneParams): Promise { + const { milestoneId, ...rest } = params + return this.sendGet({ + path: `/api/explorer/v2/milestones/${milestoneId}/blocks`, + queryParams: rest, + }) + } + + async getBlocksByMilestoneIndex(params: BlocksByMilestoneIndexParams): Promise { + const { milestoneIndex, ...rest } = params + return this.sendGet({ + path: `/api/explorer/v2/milestones/by-index/${milestoneIndex}/blocks`, + queryParams: rest, + }) + } + + async getLedgerUpdatesByAddress(params: LedgerUpdatesByAddressParams): Promise { + const { address, ...rest } = params + return this.sendGet({ + path: `/api/explorer/v2/ledger/updates/by-address/${address}`, + queryParams: rest, + }) + } + + async getLedgerUpdatesByMilestone(params: LedgerUpdatesByMilestoneParams): Promise { + const { milestoneId, ...rest } = params + return this.sendGet({ + path: `/api/explorer/v2/ledger/updates/by-milestone/${milestoneId}`, + queryParams: rest, + }) + } + + async getTopRichestAddresses(params: TopRichestAddressesParams): Promise { + return this.sendGet({ + path: `/api/explorer/v2/ledger/richest-addresses`, + queryParams: params as QueryParams, + }) + } + + async getTokenDistribution(ledgerIndex: number): Promise { + return this.sendGet({ + path: `/api/explorer/v2/ledger/token-distribution`, + queryParams: { ledgerIndex }, + }) + } +} diff --git a/src/service/rpc/other/AbstractKadenaRpc.ts b/src/service/rpc/other/AbstractKadenaRpc.ts index e1e3a9c9d..5b388dcbe 100644 --- a/src/service/rpc/other/AbstractKadenaRpc.ts +++ b/src/service/rpc/other/AbstractKadenaRpc.ts @@ -56,7 +56,11 @@ export abstract class AbstractKadenaRpc implements KadenaRpcInterface { private prepareRequest({ path, body, queryParams, network }: RequestI): PostI { return { - path: Utils.addQueryParams(path, Utils.camelToDashCase, queryParams), + path: Utils.addQueryParams({ + basePath: path, + strategy: Utils.camelToDashCase, + queryParams: queryParams, + }), prefix: network ? this.urlWithPrefix(network) : undefined, body, } @@ -80,7 +84,11 @@ export abstract class AbstractKadenaRpc implements KadenaRpcInterface { network?: NetworkParams | ApiParams }): Promise { return this.get({ - path: Utils.addQueryParams(path, Utils.camelToDashCase, queryParams), + path: Utils.addQueryParams({ + basePath: path, + strategy: Utils.camelToDashCase, + queryParams: queryParams, + }), prefix: network ? this.urlWithPrefix(network) : undefined, }) } diff --git a/src/service/rpc/other/AbstractStellarRpc.ts b/src/service/rpc/other/AbstractStellarRpc.ts index de43d9ea0..36b3cdbc2 100644 --- a/src/service/rpc/other/AbstractStellarRpc.ts +++ b/src/service/rpc/other/AbstractStellarRpc.ts @@ -82,7 +82,13 @@ export abstract class AbstractStellarRpc implements StellarRpcSuite { private async sendGet({ path, queryParams }: { path: string; queryParams?: QueryParams }): Promise { if (queryParams && Object.keys(queryParams).length > 0) { - return this.get({ path: Utils.addQueryParams(path, Utils.camelToSnakeCase, queryParams) }) + return this.get({ + path: Utils.addQueryParams({ + basePath: path, + strategy: Utils.camelToSnakeCase, + queryParams: queryParams, + }), + }) } return this.get({ path }) @@ -102,7 +108,11 @@ export abstract class AbstractStellarRpc implements StellarRpcSuite { } if (queryParams && Object.keys(queryParams).length > 0) { - post.path = Utils.addQueryParams(path, Utils.camelToSnakeCase, queryParams) + post.path = Utils.addQueryParams({ + basePath: path, + strategy: Utils.camelToSnakeCase, + queryParams: queryParams, + }) } if (body) { diff --git a/src/service/rpc/other/AbstractTezosRpc.ts b/src/service/rpc/other/AbstractTezosRpc.ts index 6ca5d98c3..ac9af78e8 100644 --- a/src/service/rpc/other/AbstractTezosRpc.ts +++ b/src/service/rpc/other/AbstractTezosRpc.ts @@ -30,7 +30,13 @@ export abstract class AbstractTezosRpc implements TezosRpcInterface { private async sendGet({ path, queryParams }: { path: string; queryParams?: QueryParams }): Promise { if (queryParams && Object.keys(queryParams).length > 0) { - return this.get({ path: Utils.addQueryParams(path, Utils.camelToSnakeCase, queryParams) }) + return this.get({ + path: Utils.addQueryParams({ + basePath: path, + strategy: Utils.camelToSnakeCase, + queryParams: queryParams, + }), + }) } return this.get({ path }) @@ -50,7 +56,11 @@ export abstract class AbstractTezosRpc implements TezosRpcInterface { } if (queryParams && Object.keys(queryParams).length > 0) { - post.path = Utils.addQueryParams(path, Utils.camelToSnakeCase, queryParams) + post.path = Utils.addQueryParams({ + basePath: path, + strategy: Utils.camelToSnakeCase, + queryParams: queryParams, + }) } if (body) { diff --git a/src/util/util.shared.ts b/src/util/util.shared.ts index b7d3fe126..5999144df 100644 --- a/src/util/util.shared.ts +++ b/src/util/util.shared.ts @@ -660,6 +660,7 @@ export const Utils = { padWithZero: (data: string, length = 64) => data.replace('0x', '').padStart(length, '0'), camelToSnakeCase: (str: string) => str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`), camelToDashCase: (str: string) => str.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`), + identity: (x: T) => x, convertObjectWithStrategy: ( obj: object, strategy: (key: string) => string, @@ -881,17 +882,24 @@ export const Utils = { } return rpc?.nodes?.[0].url || `${Constant.TATUM_API_URL.V3}blockchain/node/${network}`.concat(path || '') }, - addQueryParams: ( - basePath: string, - strategy: (key: string) => string, - queryParams?: QueryParams, - ): string => { + addQueryParams: ({ + basePath, + strategy, + queryParams, + }: { + basePath: string + strategy?: (key: string) => string + queryParams?: QueryParams + }): string => { let queryString = '' if (queryParams) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - const query: Record = Utils.convertObjectWithStrategy(queryParams, strategy) + const query: Record = Utils.convertObjectWithStrategy( + queryParams, + strategy ?? Utils.identity, + ) const params: string[] = [] Object.entries(query).forEach(([key, value]) => {