Code Monkey home page Code Monkey logo

hedera-sdk-reference's Introduction

Hedera™ Hashgraph SDK

Hedera Hashgraph

This document is the primary reference for the Hedera™ Hashgraph SDKs.

This document is normative and should be taken as the official specification for semantic operation and classification of an Official Hedera™ Hashgraph SDK.

Reference

Core




Errors

Cryptography

Cryptocurrency



Smart Contract



File



Consensus Topic



System

Network

Contributing

We welcome participation from all developers!

To propose a change to the specifications, submit a pull request making the change; or, open an issue for general discussion.

Please check out contributing guide to see how you can get involved.

Code of Conduct

This project is governed by the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code of conduct. Please report unacceptable behavior to [email protected].

License

Apache License 2.0

hedera-sdk-reference's People

Contributors

janaakhterov avatar mehcode avatar simihunjan avatar sean-tedrow-lb avatar dependabot[bot] avatar dikel avatar easpaas avatar kenthejr avatar rwalworth avatar

Stargazers

Daniel David Franco Gutiérrez avatar litt avatar Giuseppe Bertone avatar Jacob Weaver avatar Richard Bair avatar

Watchers

James Cloos avatar Serg Metelin avatar Richard Bair avatar Andrei avatar Deyan Zhekov avatar Nathan Klick avatar Greg Scullard avatar Tim McHale avatar  avatar

Forkers

internetofpeers

hedera-sdk-reference's Issues

Add `AccountId.getEvmAddress()`

Problem

This feature is not currently implemented.

Solution

  • Add AccountId.getEvmAddress() to support HIP-583
  • Should return EvmAddress

Alternatives

No response

Deprecate `setAliasEvmAddress()` in `AccountCreateTransaction`

Problem

HIP-583 originally introduced setting the alias in the AccountCreateTransaction and setAliasEvmAddress() was added.

Since then the design has changed and to be sync with the latest design setAliasEvmAddress() should be deprecated and replaced with setEvmAddress().

Solution

Deprecate setAliasEvmAddress() and replace with setEvmAddress(string) (with 0x_ _ _ prefix).

  • AccountCreateTransaction

Alternatives

No response

Missing reference for AccountAllowanceDeleteTransaction

The only non-deprecated method seems to be deleteAllTokenNftAllowances.


Java - https://github.com/hashgraph/hedera-sdk-java/blob/main/sdk/src/main/java/com/hedera/hashgraph/sdk/AccountAllowanceDeleteTransaction.java#L147

AccountAllowanceDeleteTransaction deleteAllTokenNftAllowances(
  NftId nftId, 
  AccountId ownerAccountId
) { }

JavaScript - https://github.com/hashgraph/hedera-sdk-js/blob/main/src/account/AccountAllowanceDeleteTransaction.js#L121

function deleteAllTokenNftAllowances(
  nftId: NftId, 
  ownerAccountId: AccountId
): AccountAllowanceDeleteTransaction { }

Go - https://github.com/hashgraph/hedera-sdk-go/blob/main/account_allowance_delete_transaction.go#L85

func (transaction *AccountAllowanceDeleteTransaction) DeleteAllTokenNftAllowances(
  nftID NftID, 
  ownerAccountID *AccountID,
) *AccountAllowanceDeleteTransaction { }

Check documentation is up to date

Things to check per reference file:

  • Confirm documentation is up to date with the protobufs in each SDK and reference file
  • Confirm we do not have a Table of Contents
  • Confirm each link in the reference file works
  • Confirm each SDK type is linked in each reference file
  • Confirm each reference file does not begin with a # <type> heading, and instead begins with > [class|enum] <type> [extends [Query|Transaction|Key]]
  • Confirm each reference file contains example usage per language

Note:
The top level task for each type refers to the reference file, not if all 3 subtasks were completed.

  • AccountBalance
    • Java
    • JS
    • Go
  • AccountBalanceQuery
    • Java
    • JS
    • Go
  • AccountCreateTransaction
    • Java
    • JS
    • Go
  • AccountDeleteTransaction
    • Java
    • JS
    • Go
  • AccountId
    • Java
    • JS
    • Go
  • AccountInfo
    • Java
    • JS
    • Go
  • AccountInfoQuery
    • Java
    • JS
    • Go
  • AccountRecordsQuery
    • Java
    • JS
    • Go
  • AccountStakersQuery
    • Java
    • JS
    • Go
  • AccountUpdateTransaction
    • Java
    • JS
    • Go
  • AssessedCustomFee
    • Java
    • JS
    • Go
  • BadEntityIdException
    • Java
    • JS
    • Go
  • BadKeyException
    • Java
    • JS
    • Go
  • BadMnemonicException
    • Java
    • JS
    • Go
  • BadMnemonicReason
    • Java
    • JS
    • Go
  • Client
    • Java
    • JS
    • Go
  • ContractByteCodeQuery
    • Java
    • JS
    • Go
  • ContractCallQuery
    • Java
    • JS
    • Go
  • ContractCreateTransaction
    • Java
    • JS
    • Go
  • ContractDeleteTransaction
    • Java
    • JS
    • Go
  • ContractExecuteTransaction
    • Java
    • JS
    • Go
  • ContractFunctionParameters
    • Java
    • JS
    • Go
  • ContractFunctionResult
    • Java
    • JS
    • Go
  • ContractFunctionSelector
    • Java
    • JS
    • Go
  • ContractId
    • Java
    • JS
    • Go
  • ContractInfo
    • Java
    • JS
    • Go
  • ContractInfoQuery
    • Java
    • JS
    • Go
  • ContractLogInfo
    • Java
    • JS
    • Go
  • ContractUpdateTransaction
    • Java
    • JS
    • Go
  • CustomFee
    • Java
    • JS
    • Go
  • CustomFixedFee
    • Java
    • JS
    • Go
  • CustomFractionalFee
    • Java
    • JS
    • Go
  • CustomRoyaltyFee
    • Java
    • JS
    • Go
  • ExchangeRate
    • Java
    • JS
    • Go
  • FeeAssessmentMethod
    • Java
    • JS
    • Go
  • FeeComponents
    • Java
    • JS
    • Go
  • FeeData
    • Java
    • JS
    • Go
  • FeeDataType
    • Java
    • JS
    • Go
  • FeeSchedule
    • Java
    • JS
    • Go
  • FeeSchedules
    • Java
    • JS
    • Go
  • FileAppendTransaction
    • Java
    • JS
    • Go
  • FileContentsQuery
    • Java
    • JS
    • Go
  • FileCreateTransaction
    • Java
    • JS
    • Go
  • FileDeleteTransaction
    • Java
    • JS
    • Go
  • FileId
    • Java
    • JS
    • Go
  • FileInfo
    • Java
    • JS
    • Go
  • FileInfoQuery
    • Java
    • JS
    • Go
  • FileUpdateTransaction
    • Java
    • JS
    • Go
  • FreezeTransaction
    • Java
    • JS
    • Go
  • Hbar
    • Java
    • JS
    • Go
  • HbarUnit
    • Java
    • JS
    • Go
  • HederaPreCheckStatusException
    • Java
    • JS
    • Go
  • HederaReceiptStatusException
    • Java
    • JS
    • Go
  • Key
    • Java
    • JS
    • Go
  • KeyList
    • Java
    • JS
    • Go
  • LiveHash
    • Java
    • JS
    • Go
  • LiveHashAddTransaction
    • Java
    • JS
    • Go
  • LiveHashDeleteTransaction
    • Java
    • JS
    • Go
  • LiveHashQuery
    • Java
    • JS
    • Go
  • MaxQueryPaymentExceededException
    • Java
    • JS
    • Go
  • Mnemonic
    • Java
    • JS
    • Go
  • NetworkName
    • Java
    • JS
    • Go
  • NetworkVersionInfo
    • Java
    • JS
    • Go
  • NetworkVersionInfoQuery
    • Java
    • JS
    • Go
  • NftId
    • Java
    • JS
    • Go
  • PrecheckStatusException
    • Java
    • JS
    • Go
  • PrivateKey
    • Java
    • JS
    • Go
  • ProxyStaker
    • Java
    • JS
    • Go
  • PublicKey
    • Java
    • JS
    • Go
  • Query
    • Java
    • JS
    • Go
  • ReceiptStatusException
    • Java
    • JS
    • Go
  • RequestType
    • Java
    • JS
    • Go
  • ScheduleCreateTransaction
    • Java
    • JS
    • Go
  • ScheduleDeleteTransaction
    • Java
    • JS
    • Go
  • ScheduleId
    • Java
    • JS
    • Go
  • ScheduleInfo
    • Java
    • JS
    • Go
  • ScheduleInfoQuery
    • Java
    • JS
    • Go
  • ScheduleSignTransaction
    • Java
    • JS
    • Go
  • SemanticVersion
    • Java
    • JS
    • Go
  • Status
    • Java
    • JS
    • Go
  • SubscriptionHandle
    • Java
    • JS
    • Go
  • SystemDeleteTransaction
    • Java
    • JS
    • Go
  • SystemUndeleteTransaction
    • Java
    • JS
    • Go
  • TokenAssociateTransaction
    • Java
    • JS
    • Go
  • TokenBurnTransaction
    • Java
    • JS
    • Go
  • TokenCreateTransaction
    • Java
    • JS
    • Go
  • TokenDeleteTransaction
    • Java
    • JS
    • Go
  • TokenDissociateTransaction
    • Java
    • JS
    • Go
  • TokenFeeScheduleUpdateTransaction
    • Java
    • JS
    • Go
  • TokenFreezeTransaction
    • Java
    • JS
    • Go
  • TokenGrantKycTransaction
    • Java
    • JS
    • Go
  • TokenId
    • Java
    • JS
    • Go
  • TokenInfo
    • Java
    • JS
    • Go
  • TokenInfoQuery
    • Java
    • JS
    • Go
  • TokenMintTransaction
    • Java
    • JS
    • Go
  • TokenNftInfo
    • Java
    • JS
    • Go
  • TokenNftInfoQuery
    • Java
    • JS
    • Go
  • TokenNftTransfer
    • Java
    • JS
    • Go
  • TokenRelationship
    • Java
    • JS
    • Go
  • TokenRevokeKycTransaction
    • Java
    • JS
    • Go
  • TokenSupplyType
    • Java
    • JS
    • Go
  • TokenType
    • Java
    • JS
    • Go
  • TokenUnfreezeTransaction
    • Java
    • JS
    • Go
  • TokenUpdateTransaction
    • Java
    • JS
    • Go
  • TokenWipeTransaction
    • Java
    • JS
    • Go
  • TopicCreateTransaction
    • Java
    • JS
    • Go
  • TopicDeleteTransaction
    • Java
    • JS
    • Go
  • TopicId
    • Java
    • JS
    • Go
  • TopicInfo
    • Java
    • JS
    • Go
  • TopicInfoQuery
    • Java
    • JS
    • Go
  • TopicMessage
    • Java
    • JS
    • Go
  • TopicMessageChunk
    • Java
    • JS
    • Go
  • TopicMessageQuery
    • Java
    • JS
    • Go
  • TopicMessageSubmitTransaction
    • Java
    • JS
    • Go
  • TopicUpdateTransaction
    • Java
    • JS
    • Go
  • Transaction
    • Java
    • JS
    • Go
  • TransactionFeeSchedule
    • Java
    • JS
    • Go
  • TransactionId
    • Java
    • JS
    • Go
  • TransactionReceipt
    • Java
    • JS
    • Go
  • TransactionReceiptQuery
    • Java
    • JS
    • Go
  • TransactionRecord
    • Java
    • JS
    • Go
  • TransactionRecordQuery
    • Java
    • JS
    • Go
  • TransactionResponse
    • Java
    • JS
    • Go
  • Transfer
    • Java
    • JS
    • Go
  • TransferTransaction
    • Java
    • JS
    • Go

Refactor key derivation

There are problems with how key derivations are currently implemented. This issue is for discussing the best solution to the existing problems, and settling on a course of action.

Background

Proposal (will be updated as discussion occurs)

Converting Mnemonics to Private Keys

  1. Mnemonic.toStandardEd25519PrivateKey(passphrase="", index=0)
    • returns the child key at derivation path m/44'/3030'/0'/0'/index'
    • this function automatically hardens index. Passing in a pre-hardened index should fail
  2. Mnemonic.toStandardECDSAsecp256k1PrivateKey(passphrase="", index=0)
    • returns the child key at derivation path m/44'/3030'/0'/0/index
    • if the user wants a hardened child, they must manually harden index
  3. Mnemonic.toLegacyPrivateKey() returns an Ed25519 private key
    • this function should choose the type of legacy derivation based on mnemonic word count / composition
      • 22 words from the non-standard list means legacy derivation v1
      • 24 words from the standard list means legacy derivation v2

Deriving Child Keys

  1. PrivateKey.derive(index)
    • returns the child key at index
    • if PrivateKey is an Ed25519 key, index is automatically hardened. passing in a pre-hardened index should fail
    • if PrivateKey is an ECDSA key, index must be manually hardened, if desired
  2. PrivateKey.legacyDerive(index)
    • returns the child key at index, using the legacy algorithm
    • only valid for Ed25519 keys. Calling this on an ECDSA key should fail

Deprecated Functions (including but not necessarily limited to)

  1. Mnemonic.toEd25519PrivateKey(passphrase = "", path = ...)
    • since using the default path returns a key that shouldn't be used
  2. Mnemonic.toECDSAPrivateKey(passphrase = "", path = ...)
    • since the default path is entirely wrong, and returns a non-standard key (JS only)

Tests

  1. All test vectors described in SLIP10, BIP32, and BIP39 should be checked for all key types
    • Some refactoring will be necessary to support test vectors from seed
    • BIP-32 test requirement removed for now, since base58 extended key encoding isn't supported
  2. The following test vectors should be created and standardized across SDKs
    • legacyMnemonicV1
      • mnemonic to key
      • legacy derivation (if applicable, see question # 1 below)
    • legacyMnemonicV2
      • mnemonic to key
      • legacy derivation (if applicable, see question # 1 below)
    • toStandardEd25519PrivateKey
      • mnemonic to key with no passphrase and index 0
      • mnemonic to key with passphrase and index 0
      • mnemonic to key with passphrase and index max
    • toStandardECDSAsecp256k1PrivateKey
      • mnemonic to key with no passphrase and index 0
      • mnemonic to key with no passphrase and index 0'
      • mnemonic to key with passphrase and index 0
      • mnemonic to key with passphrase and index 0'
      • mnemonic to key with passphrase and index max
      • mnemonic to key with passphrase and index max'

Possible future functionality (not included in the current proposal)

  1. Functions that allow the user to explicitly define a full derivation path
    • The functions that do this are being deprecated
    • Since this is presumably not a commonly used feature, it doesn't need to be added urgently
  2. Public key derivation
    • inherently not possible with Ed25519
    • should eventually be implemented for ECDSA

Questions

  1. When is PrivateKey.legacyDerive(index) actually needed? Is this just for one of the legacy versions, or both?
    • this needs to be figured out and documented
  2. Can we remove the isLegacy flag from Mnemonic?
    • There currently exists some functionality to construct a mnemonic with an isLegacy flag, or to infer isLegacy based on word count
    • I personally don't like this at all. Not all SDKs do this the same way, and isLegacy actually seems to mean "is legacy v1", since legacy v2 mnemonics are notably not isLegacy
    • IMO we should rip this confusing bandaid off now, and just require the wallet implementor to explicitly call toLegacyPrivateKey, rather than inconsistently and imperfectly inferring isLegacy
  3. Should we specify the curve in the ECDSA function names? (see below for details)

Introduce branch protection of main branch to require PR reviews

At present it appears that a PR author can merge their PR into a repo with no review from another reviewer. We should require that all PRs be reviewed by at least one additional engineer, and that this should be more than a rubber-stamping exercise - we should expect an adequate amount of time be allocated to ensuring correctness of implementation and API, before the approval is made.

To make this be an enforced expectation, we should introduce branch protection in all of the SDK repos.

Can we remove the requirement for specifying a node in a transaction?

Problem

The current SDK algorithm for signing transactions is to sign a transaction multiple times for the chosen healthy nodes to rely on for executing the transaction. For WEB and NATIVE until now, this signature was only one, because we’ve got only one node in the list.

This will affect the users with Hardware Wallets, which will be prompted to sign a transaction for every node (unfortunately this is by the current workflow of the SDK).

We can think about a potential fix for this as follows: We can sign a transaction only for a node that the SDK will try to execute the transaction through it. BUT If this node fails, the transaction needs to be re-signed again. What is different than the previous approach? The difference is that the user will be prompted to re-sign the transaction only if this node fails and another is chosen for processing the transaction.

One workaround that the Hashpack team asked me about and I’ve provided to them is to specify with the 1setNodeAccountIds1 a single node, when a hardware wallet is used.

The question is how we want the SDK to behave, should we sign the transactions one time for the multiple nodeAccountIds, or do we want to re-sign them every time the node failed to execute a transaction?

Solution

TBD

Alternatives

No response

Rename ScheduleInfo#memo to ScheduleInfo#scheduleMemo

`Query.[from|to]Bytes()`

Original Issue: hashgraph/hedera-sdk-js#922

However, the larger issue at hand here is that JS has implemented Query.[from|to]Bytes() while the other SDKs have not. This was a mistake originally, but later was required due to the signature providers feature. With that said, what should we do going forward?

  • Should we implement the current unstable implementation in the other SDKs.
  • Should we do nothing in the other SDKs?
  • Should we figure out a stable implementation and update all SDKs to use that (Note this would break signature provider dApps.)

Develop guidelines on best practices

We should develop guidelines that outline our goals and the best practices we as a team wish to adhere to. Topics that should be included in these guidelines include (but is not limited to) the following:

  • Semantic versioning:
    • Deprecation and removal of API.
    • The introduction of new API.
    • Cross-language versioning consistency versus each language versioning at its own pace.
  • Breaking change policy and the introduction of tooling to prevent any accidental (or intentional-without-prior-approval) changes.
  • Build tooling and expectations - minimum levels of code coverage, getting code linters (e.g. spotbugs, etc) issues to zero.
  • Documentation expectations - how often we should generate the actual reference output and review it for quality, missing samples, etc.
  • Repository expectations:
    • Pull requests needing to be reviewed / approved by another developer.
  • Common design patterns

Add `AccountId.fromEvmPublicAddress()`

Problem

This feature is not currently implemented.

  • JS SDK
  • Go SDK

Solution

  • Add AccountId.fromEvmPublicAddress() to support HIP-583.
  • Should accept only EvmAddress

Alternatives

No response

The difference between `KeyList` and `ThresholdKey` is ambiguous and poorly documented

At some point, the decision was made to combine KeyList and ThresholdKey objects, such that if a threshold value is set, then a ThresholdKey protobuf is produced, otherwise producing a KeyList protobuf

This invites misuse: a KeyList is intended to have specialized behavior related to files. It isn't just a ThresholdKey where N of N keys are required to sign.

  1. If a developer wants the special KeyList behavior, but sets a threshold value without understanding the implications, they might not know that suddenly they no longer have a KeyList at all
  2. If a developer doesn't know anything about the specialized file related behavior of a KeyList, and assumes setting no threshold == requiring N of N signatures (logical, IMO), they could get be blindsided by specialized KeyList behavior

Add examples to demonstrate all the ways to create the different Hedera addresses

Problem

There are many ways an account can be identified.

  • An account can have an account ID in shard.realm.accountNumber format (0.0.10)
  • An account can have a public key alias in 0.0.CIQNOWUYAGBLCCVX2VF75U6JMQDTUDXBOLZ5VJRDEWXQEGTI64DVCGQ format
  • An account can have an AccountId that is represented in 0x000000000000000000000000000000000000000a (for account ID 0.0.10) long zero format
  • An account have be represented by an Ethereum public address 0xb794f5ea0ba39494ce839613fffba74279579268

Solution

Add one example that demonstrates how to create each of the different account addresses.

Alternatives

No response

Decide on a convention for language SDKs where a type needs to be deserialized without fore-knowledge

Context

In Java, Go, and JavaScript, we can say Transaction.fromBytes or CustomFee.fromBytes and the actual class that gets returned is a derived type (e.g., TransferTransaction or CustomFixedFee). This is not possible in Rust or Swift.

Proposal

Introduce a new data-attached enum type, AnyX, that is used when a type hierarchy needs to be deserialized.

Use cases:

  • AnyTransaction is an enum of all transaction types. You may deserialize from bytes (protobuf) or json into this type. You would then match to extract the actual transaction type.
  • AnyQuery
  • AnyRequest (Transaction or Query)
  • AnyCustomFee

Exceptions

  • Key is already a data-attached enum as we need to distinguish between "contract keys" and "delegatable contract keys". Therefore a user can deserialize into Key.

Scope

This would only be required to affect Rust and Swift. There is little benefit in the others as OOP is more central to the language. It could be added to the others for consistency.

Alternatives

  • The type hierarchy could be defined in terms of the enumeration instead. In other words, the Transaction type would be a enum instead of a "base type". This is not ideal because the user would need to match on the type of transaction in order to act on it.

  • We could not allow deserialization. This affects some core features so likely not possible.

Add stats for transaction failures

Problem

There are times when transactions fail with INVALID_NODE_ACCOUNT_ID, TRANSACTION_EXPIRED, or other errors where transactions do not succeed. In order to debug these transaction failures the SDK needs to provide some stats.

Solution

Log the transactions that were submitted in the last 30 minutes.

Stored locally and default is not enabled.

This should include:

  • Transaction ID
  • Node the transaction was submitted to from transaction receipt
  • Network response (either the network error or success response)
  • The network is was submitted to (mainnet, testnet, previewnet)
  • Transaction body (json format TBD)

Tasks

  • Design the APIs
  • Approval from SDK API review team
  • Implement the APIs
  • Test the APIs when transactions fail
  • Validate the API works as intended
  • Release the API

Alternatives

No response

HCS Fragmentation & Reassembly

  • Java
  • Javascript
  • Go

Functionality

  • Fragmentation of larger HCS messages
  • Fragment headers
  • Reassemble messages
  • Private topics only

Deprecate `PublicKey.toEthereumAddress()`

Problem

  • publicKey.toEthereumAddress() is currently supported in the SDKs
  • Deprecate publicKey.toEthereumAddress() and replace with publicKey.toEvmAddress()

Solution

  • Deprecate publicKey.toEthereumAddress() and replace with publicKey.toEvmAddress()

Alternatives

No response

v3 SDK feature requests

Problem

There may be some feature requests that will require a new version of the SDKs. This issue will capture the feature requests that should be taken into consideration when creating the next version of the SDK.

Solution

Captures the feature requests in this issue.

Features

  • The transaction fee payer (client operator) should be able to support a multi key account
  • The SDK should represent the Hedera network as whole offering a complete experience between the different products and services
  • Includes mirror node rest API support, JSON-RPC relay, local node etc
  • Operator ID is a strange name to use for an account that we specify to pay for transaction fees. This should be named something like transaction fee payer that is more intuitive for the developer to understand what this is

Alternatives

No response

Create a smooth developer experience

There are four parts to this goal that I think we should strive to accomplish:

  1. Clearly show which dependencies are required. At the moment Java and JS have a few lines that indicate which dependencies are used, but ideally this would be much more obvious.

  2. Unify the building process for the SDKs; meaning the same command builds any SDK. The v3 SDK and the JS SDK use just, and so far I’m happy with it. We need to update the Java SDK and Go SDK to use just as well. Then we’d be able to run just build in any SDK directory and it’d just work; intended. We might also be able to make just build error nicely if dependencies aren’t installed.

  3. Improve performance of building, linting, and testing in the SDKs. This means that the Java SDK, just build should not run all the unit tests since that’s a separate step. As for JS, running just build takes ~40s to complete on my home and work PCs; the majority of that time is eslint.

  4. Support Linux, MacOS, Windows, and maybe MacOS arm64. At the moment all of our developers are on MacOS or Linux which is great, but as the SDKs are OSS we really should support as many operating systems as we can.

SDK Technology compatibility kit (TCK)

Problem

Tasks

  • #90
  • Define a Hedera SDK TCK Program
  • The Hedera SDK TCK program would be a program that provides recognition for an SDK that passes the TCK test. Developers will need a way to submit their SDK for this recognition and way for Hedera to provide the stamp of approval. This may include a duration in which the certification is required to be renewed.

Solution

Develop and implement a TCK.

Alternatives

No response

Add CODEOWNERS file for all SDK repos

We should add a codeowners file to every SDK. More details about what codeowners does (and how it works) is available here: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners

In short though, it is a way of automatically assigning reviewers or owners to pull requests and issues. This means we will less frequently encounter newly-filed issues or pull requests that are ignored, because a default recipient will be allocated (and it should be their responsibility to triage as appropriate).

HCS Encryption

  • Java
  • Javascript
  • Go

Functionality

  • Key management
  • Key rotation
  • Key distribution
  • Encryption
  • Decryption

Add method `addSigner` to `Transaction` and deprecate `sign` and `signWith`

Existing

public final T sign(PrivateKey privateKey);
public final T signWith(PublicKey publicKey, Function<byte[], byte[]> transactionSigner);

Issues

  • The names of these methods are very confusing. The SDKs do not sign anything when these methods are invoked. The signing method is added to a list that eventually signs a transaction when executed.
  • The signWith method has two arguments, one for publicKey and one for transactionSigner. This is very problematic when integrating with injected wallet software as the second argument can dynamically adapt to a new key but the first argument is static.
  • It's not possible in Java to have remote/hardware signing because the interface for signing is synchronous. The JavaScript has a non-standard version of the API that returns a promise.

Proposal

  • Remove freeze requirement for the new signer method (no signing actually takes place)
  • Deprecate sign and signWith
  • Introduce SignaturePair (name taken from header services) which is a simple type that holds a byte[] signature and PublicKey publicKey
  • Introduce TransactionSigner and AsyncTransactionSigner interfaces
  • Add addSigner and addAsyncSigner methods to Transaction
  • Implement TransactionSigner for PrivateKey
interface AsyncTransactionSigner {
  CompletableFuture<SignaturePair> signTransactionAsync(byte[] transactionBody);
}

@FunctionalInterface
interface TransactionSigner {
  SignaturePair signTransaction(byte[] transactionBody);
}
abstract class Transaction<T> {
  public T addSigner(TransactionSigner signer);
  public T addAsyncSigner(AsyncTransactionSigner signer);
}

Migration

Taken from an example in the Java SDK

// Existing
        new TokenAssociateTransaction()
            .setNodeAccountIds(Collections.singletonList(response.nodeId))
            .setAccountId(accountId1)
            .setTokenIds(Collections.singletonList(tokenId))
            .freezeWith(client)
            .sign(OPERATOR_KEY)
            .sign(key1)
            .execute(client)

// New
        new TokenAssociateTransaction()
            .setNodeAccountIds(Collections.singletonList(response.nodeId))
            .setAccountId(accountId1)
            .setTokenIds(Collections.singletonList(tokenId))
            .addSigner(OPERATOR_KEY)
            .addSigner(key1)
            .execute(client)

Majority of uses in the public use .sign. A signWith conversion is a bit more involved:

// Existing
        new TokenAssociateTransaction()
            .setNodeAccountIds(Collections.singletonList(response.nodeId))
            .setAccountId(accountId1)
            .setTokenIds(Collections.singletonList(tokenId))
            .freezeWith(client)
            .signWith(remotePublicKey, (bodyBytes) -> remoteSign(bodyBytes))
            .execute(client)

// New
        new TokenAssociateTransaction()
            .setNodeAccountIds(Collections.singletonList(response.nodeId))
            .setAccountId(accountId1)
            .setTokenIds(Collections.singletonList(tokenId))
            .freezeWith(client)
            .addSigner((bodyBytes) -> {
              var signature = remoteSign(bodyBytes);
              var publicKey = remotePublicKey();

              return new SignaturePair(publicKey, signature);
            })
            .execute(client)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.