diff --git a/CHANGELOG.md b/CHANGELOG.md index 6df7e5e1..4e8910a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,15 @@ # Changelog -## `v0.0.37` [breaking change] +## `v0.0.38` [breaking change] ### Features - Added `MnemonicWallet` to allow programmatic signing and broadcasting of txs without relying on a 3rd party wallet/signer (see examples directory) - Simplified wallet APIs **[breaking change]** - - `getAccount()`: reworked to `getAuthInfo()`, but consumers are no longer required to call this method to broadcast transactions - - `pollTx()`: removed and combined with `broadcastTx()` - - `estimateFee()`: second parameter now accepts the `feeMultiplier` directly (still optional) - - `broadcastTx()`: second parameter now accepts the `fee` from the result of `estimateFee()` (no longer optional) - - `broadcastTxWithFeeEstimation()`: newly added function that combines `estimateFee` and `broadcastTx` + - `getAccount()`: renamed and reworked to `getAuthInfo()`, but consumers are no longer required to call this method to broadcast transactions + - `estimateFee()`: second parameter now accepts the `feeMultiplier` directly (still optional) instead of the auth info + - `broadcastTx()`: second parameter now accepts the `fee` from the result of `estimateFee()` (no longer optional) instead of the auth info + - `broadcastTxSync()`: new function that executes `estimateFee`, `broadcastTx`, and `pollTx` sequentially - Handle account sequence mismatch errors directly in `ConnectedWallet.estimateFee()` by retrying once with the correct sequence ### Miscellaneous diff --git a/examples/mnemonic-wallet/src/index.ts b/examples/mnemonic-wallet/src/index.ts index 65519a49..a1dde5a5 100644 --- a/examples/mnemonic-wallet/src/index.ts +++ b/examples/mnemonic-wallet/src/index.ts @@ -23,7 +23,7 @@ async function main() { console.log("Signature:", signature); // Broadcast a transaction - // const res = await wallet.broadcastTxWithFeeEstimation({ ... }); + // const res = await wallet.broadcastTxSync( ... ); // console.log("Tx result:", res); } diff --git a/package.json b/package.json index 140ae3d3..93d7ce38 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cosmes", - "version": "0.0.37", + "version": "0.0.38", "private": false, "packageManager": "pnpm@8.3.0", "sideEffects": false, diff --git a/src/wallet/wallets/ConnectedWallet.ts b/src/wallet/wallets/ConnectedWallet.ts index 8b834369..dde0d363 100644 --- a/src/wallet/wallets/ConnectedWallet.ts +++ b/src/wallet/wallets/ConnectedWallet.ts @@ -144,22 +144,18 @@ export abstract class ConnectedWallet { } /** - * Signs and broadcasts the given `unsignedTx` and returns the result of the tx. + * Signs and broadcasts the given `unsignedTx`, returning the tx hash if successful. + * The `fee` parameter can (and should) be obtained by running `estimateFee` on + * the `unsignedTx` prior to calling this method. * - * - The `fee` parameter can (and should) be obtained by running `estimateFee` on - * the `unsignedTx` prior to calling this method - * - The tx result will be polled every `intervalSeconds` until it is included in - * a block or when `maxAttempts` is reached (default: 2 seconds, 64 attempts) + * **Important**: successful execution of this method does not guarantee that the + * tx was successfully included in a block. Use `pollTx` to poll for the result of + * the tx. * + * @throws if the user denies the signing of the tx. * @throws if the tx fails to broadcast. - * @throws if the tx does not have a response. - * @throws if the tx is not found after the given number of `maxAttempts`. */ - public async broadcastTx( - unsignedTx: UnsignedTx, - fee: Fee, - { maxAttempts, intervalSeconds }: PollTxOptions = {} - ): Promise>> { + public async broadcastTx(unsignedTx: UnsignedTx, fee: Fee): Promise { const { accountNumber, sequence } = await this.getAuthInfo(true); const hash = await this.signAndBroadcastTx( unsignedTx, @@ -170,30 +166,50 @@ export abstract class ConnectedWallet { // Greedily increment the sequence for the next tx. This may result in the wrong // sequence, but if `estimateFee` was called prior to this, it will be corrected this.sequence = sequence + 1n; + return hash; + } + + /** + * Polls for the tx matching the given `txHash` every `intervalSeconds` until it is + * included in a block or when `maxAttempts` is reached (default: 2s, 64 attempts). + * + * @throws if the tx is not included in a block after the given `maxAttempts`. + */ + public async pollTx( + txHash: string, + { maxAttempts, intervalSeconds }: PollTxOptions = {} + ): Promise>> { return pollTx(this.rpc, { - hash, + hash: txHash, maxAttempts, intervalSeconds, }); } /** - * Executes `estimateFee` and `broadcastTx` sequentially, returning the result of - * the tx. Use this if there is no need independently execute the two methods. + * Executes `broadcastTx` and `pollTx` sequentially, returning the result of the + * tx. If `feeOrFeeMultiplier` is `undefined` or a number, an additional call to + * `estimateFee` will be made. Use this if there is no need to independently + * execute the three methods. */ - public async broadcastTxWithFeeEstimation( + public async broadcastTxSync( unsignedTx: UnsignedTx, - feeMultiplier = 1.4, + feeOrFeeMultiplier: Fee | number = 1.4, pollOpts: PollTxOptions = {} ): Promise>> { - const fee = await this.estimateFee(unsignedTx, feeMultiplier); - return this.broadcastTx(unsignedTx, fee, pollOpts); + const fee = + typeof feeOrFeeMultiplier === "number" + ? await this.estimateFee(unsignedTx, feeOrFeeMultiplier) + : feeOrFeeMultiplier; + const txHash = await this.broadcastTx(unsignedTx, fee); + return this.pollTx(txHash, pollOpts); } /** * Signs the UTF-8 encoded `data` string. Note that some mobile wallets do not * support this method. * + * @throws if the user denies the signing of the data. * @throws if the wallet does not support signing arbitrary data. */ public abstract signArbitrary(data: string): Promise; diff --git a/src/wallet/wallets/mnemonic/MnemonicWallet.ts b/src/wallet/wallets/mnemonic/MnemonicWallet.ts index 63613425..a383f122 100644 --- a/src/wallet/wallets/mnemonic/MnemonicWallet.ts +++ b/src/wallet/wallets/mnemonic/MnemonicWallet.ts @@ -67,8 +67,12 @@ export type ConnectMnemonicWalletOptions = Prettify< * }); * console.log("Address:", wallet.address); // prints the bech32 address * + * // Sign an arbitrary message + * const { signature } = await wallet.signArbitrary("Hello from CosmES!"); + * console.log("Signature:", signature); + * * // Sign and broadcast a tx - * const res = await wallet.broadcastTxWithFeeEstimation({ ... }); // TODO + * const res = await wallet.broadcastTxSync( ... ); // TODO * console.log("Tx result:", res); * ``` */