# OrangeKit Smart Account

## Overview

### Purpose

The OrangeKit Smart Account is designed to work with a transaction
relayer/ERC4337 bundler/paymaste to facilitate lazy initialization of a Bitcoin
wallet's associated account upon the first transaction. This setup ensures that
the associated EVM account does not need to pay gas unless it is funded. The
OrangeKit Smart Account primarily mediates between contracts and Bitcoin wallets
and manages the relayer/bundler/paymaster logic required for gasless operation
of the EVM smart account from the Bitcoin wallet.

Notably, it does not handle interactions with the wallets themselves; this is
managed by the OrangeKit package.

### Key Features

- **Safe Creation**
- **Transaction Signing**
- **Transaction Relaying**

### Architecture

The main entry point for interacting with the OrangeKit Smart Account is the
`OrangeKitSmartAccount` class, found in `index.ts`
(typescript/orangekit-smart-account/src/lib/utils/index.ts). This class contains
the logic for creating a safe for a given Bitcoin address and signing
transactions on behalf of that safe. The actual sending of the transaction is
abstracted using the `TransactionSender` interface.

In the `utils` directory, there are various utility functions for interacting
with the OrangeKit Smart Account, as well as the `TransactionSender` interface
and its two implementations:

- `LocalTransactionSender`: Used for testing, interacting with the local Hardhat
  node.
- `GelatoTransactionSender`: Utilizes the Gelato Relay network to send
  transactions, allowing them to be sponsored for gasless user experience.

The `bitcoin` and `ethereum` directories contain the logic and utility functions
for interacting with the respective blockchains.

## Getting Started

Although it is possible to use methods from the orangekit-smart-pakage directly,
it is primarily intended to be used through the OrangeKit package. See the
`example` directory for a simple example dApp that uses the OrangeKit.

## Publishing npm package

We publish the npm package manually. In the future we want to release and
publish npm package using GitHub Actions.

Make sure you have an npm account and you are in the `orangekit` organization to
publish npm package.

### Publishing the package from the main branch

To publish OrangeKit OrangeKit Smart Account package follow these steps:

1. Checkout to `main` branch.
2. Make sure the version in the `package.json` file is correct. The version on
   the `main` branch should point to the next version. For example, if the
   version under `latest` tag is `1.0.0-beta.10`, the version on `main` branch
   should be `1.0.0-beta.11`.
3. Update version of the
   [`@mezo-org/orangekit-solidity`](https://www.npmjs.com/package/@mezo-org/orangekit-solidity)
   dependency to the latest version.
4. Remove `dist` and `node_modules` directories.
5. Run `pnpm install`.
6. Note: Before running `pnpm build` you should comment out the
   `OrangeKitSafeFactoryLocalhostArtifact` import in
   [safe-factory.ts](https://github.com/thesis/orangekit/blob/main/typescript/orangekit-smart-account/src/lib/ethereum/safe-factory.ts)
   and the `localhost` case in the switch placed in the constructor. Otherwise,
   you will encounter `Cannot find module` error.
7. Run `pnpm build`.
8. If you need to log in to npm - run `npm adduser`
9. Run `npm publish --access public` and follow the steps in terminal. The new
   version will be available under `latest` tag.
10. Create a tag with the latest version number and push it:

```
git tag -a orangekit-smart-account/1.0.0-beta.<version> -m "orangekit-smart-account/1.0.0-beta.<version>"
git push origin --tags
```

After the successful release bump the beta version in `package.json` file to one
point higher than the one you just released and add `-dev.0` suffix to it. Then,
set the `@mezo-org/orangekit-solidity` dependency back to `workspace:*` and open
a PR.

Additional steps in GitHub:

1. Create [release notes](https://github.com/thesis/orangekit/releases). Use
   previous releases as an example. Remember to choose correct tag and paste
   link to closed issues in this version milestone. Optionally you can also
   briefly describe what changes were made in this release.
2. Close the current milestone and open a new one in
   [https://github.com/thesis/orangekit/milestones](https://github.com/thesis/orangekit/milestones)
   with one version higher than the one you just released. If there are any open
   issues/PRs in this milestone that did not make it to the current version,
   just move them to the next milestone.

### Publishing the package from the feature branch

To test out the package in the dApp we still have to publish it manually, but
with `-dev.x` suffix added to the version, where `x` is the next available
version (started from 0). This should indicate that such package is not released
from the `main` branch.

1. Checkout to the correct branch related to a given PR
2. Make sure the version in the `package.json` file is correct. The version on
   the feature branch should have `-dev.x` suffix bumped to the next version.
   For example, if the newest version is `1.0.0-beta.29-dev.0`, the version on
   the branch should be `1.0.0-beta.29-dev.1`. If the beta version is already
   released without dev suffix we should bump the beta version and start from
   `-dev.0` again.

   For example:

   If the newest version is `1.0.0-beta.29-dev.0`, the version on the branch
   should be `1.0.0-beta.29-dev.1`.

   If the newest version is `1.0.0-beta.29` the version on the branch should be
   `1.0.0-beta.30-dev.0`

3. Update version of the
   [`@mezo-org/orangekit-solidity`](https://www.npmjs.com/package/@mezo-org/orangekit-solidity)
   dependency to the latest version.
4. Remove `dist` and `node_modules` directories.
5. Run `pnpm install`.
6. Run `pnpm build`.
7. If you need to log in to npm - run `npm adduser`
8. Run `npm publish --access public --tag development` and follow the steps in
   terminal. The new version will be available under `development` tag.

Note: You don't have to create a tag for dev version.
