Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace bcoin with bitcoinjs-lib #695

Closed
8 tasks done
lukasz-zimnoch opened this issue Sep 15, 2023 · 0 comments
Closed
8 tasks done

Replace bcoin with bitcoinjs-lib #695

lukasz-zimnoch opened this issue Sep 15, 2023 · 0 comments
Assignees
Labels
🔌 typescript TypeScript library

Comments

@lukasz-zimnoch
Copy link
Member

lukasz-zimnoch commented Sep 15, 2023

As decided in #694, we aim to replace bcoin with bitcoinjs-lib. This task is capturing all the required work.

Tasks

  1. 🔌 typescript
    michalsmiarowski
  2. 🔌 typescript
    tomaszslabon
  3. 🔌 typescript
    tomaszslabon
  4. 🔌 typescript
    tomaszslabon
  5. 🔌 typescript
    tomaszslabon
  6. 🔌 typescript
    tomaszslabon
  7. 🔌 typescript
    tomaszslabon
  8. 🔌 typescript
    tomaszslabon
@lukasz-zimnoch lukasz-zimnoch added the 🔌 typescript TypeScript library label Sep 15, 2023
@lukasz-zimnoch lukasz-zimnoch self-assigned this Sep 15, 2023
@lukasz-zimnoch lukasz-zimnoch removed their assignment Sep 19, 2023
lukasz-zimnoch added a commit that referenced this issue Sep 19, 2023
Refs: #695

We use `bcrypto` to compute hashes, but since this library is a bit
problematic, here we replace it with hashing algorithms from the
`ethers` library. `ethers` has no `hash160` algorithm but under the hood
`HASH160 = RIPEMD160(SHA256(X))` so it's possible to compute `hash160`
using `ethers`.
lukasz-zimnoch added a commit that referenced this issue Sep 27, 2023
Refs: #695.

In this PR `bitcoinjs-lib`library was added to `tbtc-v2.ts`.

Since there is a node version conflict between the newest
`bitcoinjs-lib` (requires `node 16` or later) and `tbt-v2.ts` (requires
`node 14`), an older version of `bitcoinjs-lib` was added(`6.0.2`).
Once we get rid of `bcoin` we can update `bitcoinjs-lib` to its newest
version as it should be possible to use node 16 with `tbtc-v2.ts`.

I verified that the library was successfully installed.
lukasz-zimnoch added a commit that referenced this issue Sep 28, 2023
Depends on: #696.
Refs: #695.

This PR replaces the `bcoin` library with `bitcoinjs-lib` for deposit
sweep transactions.
The `bcoin` library was removed from `deposit-sweep.ts`.
After this update, deposit sweep generally works in the same way as
before.
The only difference is that transaction inputs are always added in the
same order:
 - main UTXO is added first
 - deposit inputs are added in the same order as the provided UTXOs.
 
Before this change the inputs could be rearranged by the `bcoin`
library.
lukasz-zimnoch added a commit that referenced this issue Oct 3, 2023
Refs: #695.
This PR replaces the bcoin library with bitcoinjs-lib for redemptions.
lukasz-zimnoch added a commit that referenced this issue Oct 3, 2023
Refs: #695.
This PR replaces the `bcoin` library with `bitcoinjs-lib` for deposits.
The functions generally works in the same way as before the change.

One difference is that UTXOs for funding the transaction and the value
of fee are passed into the function as arguments.
In the future, we could consider using
[coinselect](https://github.com/bitcoinjs/coinselect) for calculating
fee and selecting UTXOs.

Another difference is that only one type of funding UTXO is allowed
(P2WPKH). Other types should be added along with unit tests.
lukasz-zimnoch added a commit that referenced this issue Oct 3, 2023
Refs: #695.
This PR replaces the bcoin library with bitcoinjs-lib for deposit
refunds.
lukasz-zimnoch added a commit that referenced this issue Oct 6, 2023
Refs: #695.
This PR replaces all the remaining usage of `bcoin` with
`bitcoinjs-lib`:
- `bcoin` is completely removed from our code, including lib
installation
- `decodeBitcoinAddress ` function now has additional argument (Bitcoin
network)
- `createOutputScriptFromAddress` function now has additional argument
(Bitcoin network)
- unit tests now use a newly added `txToJSON` function which is based on
`bitcoinjs-lib`
- we no longer check input's address in unit tests
- transaction decomposition now uses `bitcoinjs-lib`
lukasz-zimnoch added a commit that referenced this issue Oct 6, 2023
Refs: #695.
This PR updates the version of `bitcoinjs-lib` to `6.1.5`.
Note that that version of `bitcoinjs-lib` requires node in version
`>=16`.
@lukasz-zimnoch lukasz-zimnoch added this to the typescript/v1.4.0 milestone Oct 16, 2023
tomaszslabon added a commit that referenced this issue Oct 16, 2023
Closes: #698

Here we present a comprehensive refactoring of the tBTC v2 typescript
library (a.k.a. typescript SDK). So far, the library was basically a bag
of various utility functions, and the responsibility of using them
correctly was on the library clients' side. This approach was enough for
the first phases of protocol development where the library was used
mainly for internal purposes. However, as the protocol becomes more
mature, it makes sense to encourage external integrators. This, in turn,
requires us to improve the developer experience provided by the SDK and
reduce the overhead for users. This pull request aims to achieve that
goal.

The initial plan was to open several PRs one after another but, given
the fact that #695 was
happening simultaneously and had precedence, it was easier to track
progress and resolve conflicts within a single pull request. Because of
the size, I strongly recommend reviewing commit by commit. The history
of changes clearly shows all the steps that were taken. Worth noting
that there are very few changes in the logic itself. Most of them are
file/directory structure changes, renames, and public API improvements.
Here is a detailed description of specific steps:

### Rework of the file and directory structure

So far, the file structure of the library was flat and grouped related
functions into files like `bitcoin.ts` or `deposit.ts`. This quickly led
to poor readability and encapsulation. The new approach uses a
hierarchical approach dividing code into two distinct categories:
- Shared libraries living under `lib` directory
- Feature services living under `services` directory

#### Shared libraries

This category groups all code components that are used across different
features. Specific modules are:
- `lib/bitcoin`: Contains all interfaces and utilities necessary to
interact with the Bitcoin chain
- `lib/contracts`: Provides chain-agnostic interfaces allowing to
interact with tBTC v2 smart contracts
- `lib/electrum`: Contains an Electrum-based implementation of the
Bitcoin client
- `lib/ethereum`: Provides implementations of tBTC v2 smart contract
interfaces for Ethereum chain
- `lib/utils`: Holds some general utility functions

Each aforementioned module contains an `index.ts` file that re-exports
components from specific sub-modules in order to flatten import paths
used by library clients.

#### Feature services

This category holds services providing access to specific features of
the tBTC v2 system:
- `services/deposits`: Provides access to the tBTC v2 deposit flow for
BTC depositors through the `DepositsService` component
- `services/redemptions`: Provides access to the tBTC v2 redemption flow
for TBTC redeemers through the `RedemptionsService` component
- `services/maintenance`: Provides access to authorized maintenance
actions for maintainers (e.g. optimistic minting guardians) through the
`MaintenanceService` component

Just as for shared libraries, each module contains an `index.ts` that
re-exports all exported components from specific sub-modules.

### Provide a simple entry point with embedded chain configurations

So far, the library has not provided any unified entry point that could
be used by external clients. The root `index.ts` just exported the most
important components without any further guidance. Here we aim to change
that by introducing the `TBTC` entry point class. The main purpose of it
is to provide some static functions allowing to quickly initialize the
SDK and expose specific feature services in a simple way. As for now,
the `TBTC` component can be initialized using the following functions:
- `initializeMainnet` which initializes the SDK to point tBTC v2
contracts on Ethereum and use mainnet as Bitcoin network
- `initializeGoerli` which initializes the SDK to point tBTC v2
contracts on Goerli and use testnet as Bitcoin network
- `initializeCustom` which allows using custom tBTC v2 contracts (e.g.
local) and use an arbitrary Bitcoin network (e.g. regtest or simnet)

Once initialized, the `TBTC` component provides easy access to specific
feature services. To address unforeseen needs, it also gives low-level
direct access to the underlying tBTC v2 smart contracts and the Bitcoin
client:

```
// Initialize SDK
const signer = (...) 
const sdk = await TBTC.initializeMainnet(signer) 

// Access feature services
sdk.deposits.(...)
sdk.redemptions.(...)

// Access tBTC v2 smart contracts and Bitcoin client directly
sdk.tbtcContracts.bridge.(...)
sdk.bitcoinClient.(...)
```

### Other changes

Apart from the ones mentioned above, there were other important changes
that had to be made. First and foremost, this PR integrates `bcoin`
removal done as part of
#695. The integration was
achieved by applying changes from specific PRs in separate commits here.
Secondly, the unit tests file structure was adjusted to reflect the new
approach with `lib` and `services` top-level directories.

### Usage examples

Changes made as part of this work greatly facilitated access to the two
core use cases of the tBTC v2 system: depositing and redeeming. Here are
some examples of how it looks like now:
```
// Initialize SDK
const signer = (...) 
const sdk = await TBTC.initializeMainnet(signer) 

// Deposit flow
const bitcoinRecoveryAddress = "" // take this from user input
const deposit = await sdk.deposits.initiateDeposit(bitcoinRecoveryAddress)
const depositAddress = await deposit.getBitcoinAddress() // present that to the user
await deposit.initiateMinting() // this will initiate minting if BTC were sent to the deposit address

// Redemption flow
const bitcoinRedeemerAddress = "" // take this from user input
const amount = "" // take this from user input
await sdk.redemptions.requestRedemption(bitcoinRedeemerAddress, amount)
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔌 typescript TypeScript library
Projects
None yet
Development

No branches or pull requests

2 participants