-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of github.com:sygmaprotocol/sygma-sdk into feat/e…
…rc20-generic-handler
- Loading branch information
Showing
59 changed files
with
2,143 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
name: Publish Sygma SDK Bitcoin package to GitHub Package Registry | ||
|
||
on: | ||
push: | ||
branches: ["main"] | ||
paths: ["packages/bitcoin/**"] | ||
|
||
jobs: | ||
maybe-release: | ||
name: release | ||
runs-on: ubuntu-latest | ||
if: github.event_name == 'push' && github.ref == 'refs/heads/main' | ||
steps: | ||
# you should probably do this after your regular CI checks passes | ||
# it will analyze commits and create PR with new version and updated CHANGELOG:md file. On merging it will create github release page with changelog | ||
- uses: google-github-actions/release-please-action@v3 | ||
id: release | ||
with: | ||
command: manifest | ||
release-type: node | ||
token: ${{secrets.RELEASE_TOKEN}} | ||
config-file: "release-please/rp-bitcoin-config.json" | ||
manifest-file: "release-please/rp-bitcoin-manifest.json" | ||
monorepo-tags: true | ||
default-branch: main | ||
path: "packages/bitcoin" | ||
changelog-types: '[{"type":"feat","section":"Features","hidden":false},{"type":"fix","section":"Bug Fixes","hidden":false},{"type":"chore","section":"Miscellaneous","hidden":false},{"type":"revert","hidden":true}]' | ||
|
||
- uses: actions/checkout@v4 | ||
# these if statements ensure that a publication only occurs when | ||
# a new release is created: | ||
if: ${{ steps.release.outputs.releases_created }} | ||
|
||
- uses: actions/setup-node@v4 | ||
with: | ||
cache: "yarn" | ||
node-version: 18 | ||
registry-url: "https://registry.npmjs.org" | ||
scope: "@buildwithsygma" | ||
env: | ||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
if: ${{ steps.release.outputs.releases_created }} | ||
|
||
- name: Enable corepack | ||
run: corepack enable | ||
if: ${{ steps.release.outputs.releases_created }} | ||
|
||
- name: Install dependencies | ||
run: yarn install --immutable | ||
if: ${{ steps.release.outputs.releases_created }} | ||
|
||
- run: yarn build | ||
if: ${{ steps.release.outputs.releases_created }} | ||
|
||
- env: | ||
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} | ||
if: ${{ steps.release.outputs.releases_created }} | ||
run: | | ||
echo -e "\nnpmAuthToken: \"$NODE_AUTH_TOKEN\"" >> ./.yarnrc.yml | ||
- run: yarn workspace @buildwithsygma/bitcoin npm publish --access public | ||
if: ${{ steps.release.outputs.releases_created }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
SYGMA_ENV=testnet | ||
BLOCKSTREAM_URL="your blockstream url" | ||
DESTINATION_ADDRESS="your evm destination address" | ||
RESOURCE_ID="resource id" | ||
SOURCE_CAIPID="source domain caip id" | ||
EXPLORER_URL="your bitcoin explorer url" | ||
MNEMONIC="your 12 or 24 mnemonic" | ||
DERIVATION_PATH="your derivation path" | ||
ADDRESS="your bitcoin address to use and send change" | ||
AMOUNT="your amount to transfer" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
# Sygma SDK Bitcoin to EVM example | ||
|
||
## Sygma SDK ERC20 Example | ||
|
||
This is an example that demonstrates functionality of the protocol using Sygma SDK. The src/transfer.ts script showcases how bitcoins can transferred over to an EVM Sepolia address utilizing `@buildwithsygma/bitcoin` package. | ||
|
||
## Prerequisites | ||
|
||
Before running the script, ensure that you have the following: | ||
|
||
- Node.js | ||
- Yarn (version 3.4.1 or higher) | ||
- A development wallet with some testnet BTC | ||
- The private key of a Taproot address to sign the transaction | ||
- Valid UTXO information of your taproot address. You can get the UTXO's of your address by querying some public APIS like blockstream one and passing your address as parameter | ||
|
||
## Getting started | ||
|
||
### 1. Clone the repository | ||
|
||
To get started, clone this repository to your local machine with: | ||
|
||
```bash | ||
git clone [email protected]:sygmaprotocol/sygma-sdk.git | ||
cd sygma-sdk/ | ||
``` | ||
|
||
### 2. Install dependencies | ||
|
||
Install the project dependencies by running: | ||
|
||
```bash | ||
yarn install | ||
``` | ||
|
||
### 3. Build the sdk | ||
|
||
To start the example you need to build the sdk first with: | ||
|
||
```bash | ||
yarn build:all | ||
``` | ||
|
||
## Usage | ||
|
||
This example uses the `dotenv` module to manage private keys and also to define env variables needed for this example to work. To run the example, you will need to configure your environment variables A `.env.sample` is provided as a template. | ||
|
||
**DO NOT COMMIT PRIVATE KEYS WITH REAL FUNDS TO GITHUB. DOING SO COULD RESULT IN COMPLETE LOSS OF YOUR FUNDS.** | ||
|
||
Create a `.env` file in the btc-to-evm example folder: | ||
|
||
```bash | ||
cd examples/btc-to-evm-fungible-transfer | ||
touch .env | ||
``` | ||
|
||
Replace the values that are defined in the `.env.sample` file: | ||
|
||
```bash | ||
SYGMA_ENV=testnet | ||
BLOCKSTREAM_URL="your blockstream url" | ||
DESTINATION_ADDRESS="your evm destination address" | ||
DESTINATION_CHAIN_ID="destination domain chain id" | ||
RESOURCE_ID="resource id" | ||
SOURCE_CAIPID="source domain caip id" | ||
EXPLORER_URL="your bitcoin explorer url" | ||
MNEMONIC="your 12 or 24 mnemonic" | ||
DERIVATION_PATH="your derivation path" | ||
ADDRESS="your change address" | ||
AMOUNT="your amount to transfer" | ||
``` | ||
|
||
* `DESTINATION_ADDRESS`: your `evm` destination address where you want your funds to be relayed | ||
* `DESTINATION_CHAIN_ID`: this is the chainId of the network where you want to receive the funds | ||
* `RESOURCE_ID`: the bitcoin resource id that can be found in our `shared-config` repository | ||
* `SOURCE_CAIPID`: caipId of the bitcoin domain | ||
* `MNEMONIC`: your testnet wallet mnemonic | ||
* `DERIVATION_PATH`: derivation path for your mnemonic. Use derivation path for either P2TR address or P2WPKH one | ||
* `ADDRESS`: the address from which we get the UTXO's and to which we send the change | ||
* `AMOUNT`: the actual amount to transfer | ||
|
||
Take into consideration that a typical response when query the utxos of your address look like this: | ||
|
||
```json | ||
{ | ||
"txid": "7bdf2ce472ee3c9cba6d2944b0ca6bcdceb4b893c7d2163678a0b688a8315d74", | ||
"vout": 3, | ||
"status": { | ||
"confirmed": true, | ||
"block_height": 2869535, | ||
"block_hash": "", | ||
"block_time": 1721666904 | ||
}, | ||
"value": 936396 | ||
} | ||
``` | ||
|
||
Where `value` is the amount you have at your disposal and `vout` is the transaction output index. | ||
|
||
To send Testnet BTC to your EVM account on Sepolia using Taproot address run: | ||
|
||
```bash | ||
yarn run transfer:p2tr | ||
``` | ||
|
||
To send Testnet BTC to your EVM account on Sepolia using P2WPKH address run: | ||
|
||
```bash | ||
yarn run transfer:p2wpkh | ||
``` | ||
|
||
Replace the placeholder values in the `.env` file with your own Testnet BTC Taproot private key as well as the other env variables needed such as DESTINATION_ADDRESS, DESTINATION_DOMAIN_ID, RESOURCE_ID, DERIVATION_PATH, and SOURCE_DOMAIN_ID. | ||
|
||
## Script Functionality | ||
|
||
This example script performs the following steps: | ||
- I creates a signer to sign the Bitcoin Testnet transaction using your provider private key from your taproot address. | ||
- it gets the fee for 5 confirmations blocks. You can change that following this [reference](https://github.com/Blockstream/esplora/blob/master/API.md#get-fee-estimates) | ||
- it then encodes the provided EVM address + the destination domain id needed to relay the funds | ||
- Once you have provided with the UTXO information needed, it will calculate the fee of the transaction based on some aproximation value | ||
- it then instantiate a PSBT class to be able to provide the inputs and outputs needed to relay the assets | ||
- It signs the transaction and the broadcasted into the Bitcoin testnet network. You will get an url with the transaction id to follow the confirmation of the transaction. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
{ | ||
"name": "@buildwithsygma/sygma-sdk-bitcoin-to-evm-fungible-transfer-example", | ||
"version": "0.1.0", | ||
"type": "module", | ||
"description": "Sygma sdk examples", | ||
"sideEffects": false, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/sygmaprotocol/sygma-sdk" | ||
}, | ||
"keywords": [ | ||
"sygma", | ||
"sygmaprotocol", | ||
"buildwithsygma", | ||
"web3", | ||
"bridge", | ||
"bitcoin" | ||
], | ||
"scripts": { | ||
"transfer:p2tr": "tsx src/transfer.p2tr.ts", | ||
"transfer:p2wpkh": "tsx src/transfer.p2wpkh.ts" | ||
}, | ||
"author": "Sygmaprotocol Product Team", | ||
"license": "LGPL-3.0-or-later", | ||
"devDependencies": { | ||
"dotenv": "^16.3.1", | ||
"eslint": "8", | ||
"ts-node": "10.9.1", | ||
"typescript": "5.0.4" | ||
}, | ||
"dependencies": { | ||
"@buildwithsygma/bitcoin": "workspace:^", | ||
"@buildwithsygma/core": "workspace:^", | ||
"@buildwithsygma/utils": "workspace:^", | ||
"bip32": "^4.0.0", | ||
"bip39": "^3.1.0", | ||
"bitcoinjs-lib": "^6.1.6", | ||
"ecpair": "^2.1.0", | ||
"tiny-secp256k1": "^2.2.3", | ||
"tsx": "^4.15.4" | ||
} | ||
} |
85 changes: 85 additions & 0 deletions
85
examples/bitcoin-to-evm-fungible-transfer/src/blockstreamApi.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { TypeOfAddress } from "@buildwithsygma/bitcoin"; | ||
import type { BitcoinTransferParams } from "@buildwithsygma/bitcoin"; | ||
import type { Network, Signer } from "bitcoinjs-lib"; | ||
import { payments, Psbt } from "bitcoinjs-lib"; | ||
|
||
type SizeCalculationParams = { | ||
utxoData: BitcoinTransferParams["utxoData"]; | ||
network: Network; | ||
publicKey: Buffer; | ||
depositAddress: string; | ||
domainId: number; | ||
amount: bigint; | ||
feeValue: bigint; | ||
changeAddress: string; | ||
signer: Signer; | ||
typeOfAddress: TypeOfAddress; | ||
}; | ||
|
||
/** | ||
* Ee calculate the size of the transaction by using a tx with zero fee => input amount == output amount | ||
* Correctnes of the data is not relevant here, we need to know what's the size is going to be for the amount of inputs passed and the 4 outputs (deposit, change, fee, encoded data) we use to relay the funds | ||
*/ | ||
export const calculateSize = ({ | ||
utxoData, | ||
network, | ||
publicKey, | ||
depositAddress, | ||
domainId, | ||
amount, | ||
feeValue, | ||
changeAddress, | ||
signer, | ||
typeOfAddress, | ||
}: SizeCalculationParams): number => { | ||
const pstb = new Psbt({ network: network }); | ||
|
||
const scriptPubKey: Buffer = (typeOfAddress !== TypeOfAddress.P2TR) | ||
? payments.p2wpkh({ pubkey: publicKey, network: network }).output as Buffer | ||
: payments.p2tr({ internalPubkey: publicKey, network: network }).output as Buffer; | ||
|
||
utxoData.forEach((utxo) => { | ||
const input = { | ||
hash: utxo.utxoTxId, | ||
index: utxo.utxoOutputIndex, | ||
witnessUtxo: { | ||
value: Number(utxo.utxoAmount), | ||
script: scriptPubKey, | ||
}, | ||
}; | ||
|
||
if (typeOfAddress === TypeOfAddress.P2TR) { | ||
(input as any).tapInternalKey = publicKey; | ||
} | ||
|
||
pstb.addInput(input); | ||
}); | ||
|
||
|
||
const outputs = [ | ||
{ | ||
script: payments.embed({ | ||
data: [Buffer.from(`${depositAddress}_${domainId}`)], | ||
}).output as Buffer, | ||
value: 0, | ||
}, | ||
{ | ||
address: changeAddress, | ||
value: Number(amount), | ||
}, | ||
{ | ||
address: changeAddress, | ||
value: Number(feeValue), | ||
}, | ||
{ | ||
address: changeAddress, | ||
value: 0, | ||
} | ||
]; | ||
|
||
outputs.forEach(output => pstb.addOutput(output)); | ||
|
||
pstb.signAllInputs(signer); | ||
pstb.finalizeAllInputs(); | ||
return pstb.extractTransaction(true).virtualSize(); | ||
}; |
Oops, something went wrong.