@bronlabs/intents-sdk 1.0.17 → 1.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,16 @@
1
+ import { BigNumber } from 'ethers';
2
+ import { Network, TransactionData } from './index.js';
3
+ export declare class BtcNetwork implements Network {
4
+ private readonly rpcUrl;
5
+ private readonly confirmations;
6
+ private readonly nativeAssetDecimals;
7
+ readonly retryDelay: number;
8
+ constructor(rpcUrl: string, confirmations?: number);
9
+ getDecimals(tokenAddress: string): Promise<number>;
10
+ getTxData(txHash: string, tokenAddress: string, recipientAddress: string): Promise<TransactionData | undefined>;
11
+ transfer(privateKey: string, to: string, value: BigNumber, tokenAddress: string): Promise<string>;
12
+ private getFeeRate;
13
+ private getUtxos;
14
+ private getAddressFromPrivateKey;
15
+ private rpcCall;
16
+ }
@@ -0,0 +1,132 @@
1
+ import { BigNumber } from 'ethers';
2
+ import * as bitcoin from 'bitcoinjs-lib';
3
+ import { ECPairFactory } from 'ecpair';
4
+ import * as ecc from 'tiny-secp256k1';
5
+ import { log } from '../utils.js';
6
+ import { randomUUID } from 'node:crypto';
7
+ const ECPair = ECPairFactory(ecc);
8
+ export class BtcNetwork {
9
+ constructor(rpcUrl, confirmations = 6) {
10
+ this.nativeAssetDecimals = 8;
11
+ this.retryDelay = 5000;
12
+ this.rpcUrl = rpcUrl;
13
+ this.confirmations = confirmations;
14
+ }
15
+ async getDecimals(tokenAddress) {
16
+ if (tokenAddress !== "0x0") {
17
+ throw new Error("Don't support tokens for BTC network");
18
+ }
19
+ return this.nativeAssetDecimals;
20
+ }
21
+ async getTxData(txHash, tokenAddress, recipientAddress) {
22
+ if (tokenAddress !== "0x0") {
23
+ throw new Error("Don't support tokens for BTC network");
24
+ }
25
+ try {
26
+ const tx = await this.rpcCall('getrawtransaction', [txHash, true]);
27
+ if (!tx)
28
+ return;
29
+ const output = tx.vout.find(vout => vout.scriptPubKey.addresses?.includes(recipientAddress));
30
+ if (!output) {
31
+ log.warn(`Transaction ${txHash} has no output to ${recipientAddress}`);
32
+ return {
33
+ to: recipientAddress,
34
+ token: tokenAddress,
35
+ amount: BigNumber.from(0),
36
+ confirmed: tx.confirmations >= this.confirmations
37
+ };
38
+ }
39
+ log.info(`Confirmations ${txHash}: ${tx.confirmations}`);
40
+ return {
41
+ to: recipientAddress,
42
+ token: tokenAddress,
43
+ amount: BigNumber.from(Math.round(output.value * 100000000)),
44
+ confirmed: tx.confirmations >= this.confirmations
45
+ };
46
+ }
47
+ catch (error) {
48
+ log.warn(`Failed to get transaction data for ${txHash}: ${error}`);
49
+ return;
50
+ }
51
+ }
52
+ async transfer(privateKey, to, value, tokenAddress) {
53
+ if (tokenAddress !== "0x0") {
54
+ throw new Error("Don't support tokens for BTC network");
55
+ }
56
+ const keyPair = ECPair.fromWIF(privateKey);
57
+ const fromAddress = this.getAddressFromPrivateKey(privateKey);
58
+ const utxos = await this.getUtxos(fromAddress);
59
+ if (utxos.length === 0) {
60
+ throw new Error("No UTXOs available");
61
+ }
62
+ const targetAmount = value.toNumber();
63
+ const feeRate = await this.getFeeRate();
64
+ let inputAmount = 0;
65
+ const selectedUtxos = [];
66
+ for (const utxo of utxos) {
67
+ selectedUtxos.push(utxo);
68
+ inputAmount += utxo.value;
69
+ const estimatedFee = (selectedUtxos.length * 148 + 2 * 34 + 10) * feeRate;
70
+ if (inputAmount >= targetAmount + estimatedFee)
71
+ break;
72
+ }
73
+ const estimatedFee = (selectedUtxos.length * 148 + 2 * 34 + 10) * feeRate;
74
+ const changeAmount = inputAmount - targetAmount - estimatedFee;
75
+ if (inputAmount < targetAmount + estimatedFee) {
76
+ throw new Error(`Insufficient funds. Need ${targetAmount + estimatedFee}, have ${inputAmount}`);
77
+ }
78
+ const psbt = new bitcoin.Psbt();
79
+ for (const utxo of selectedUtxos) {
80
+ psbt.addInput({
81
+ hash: utxo.txid,
82
+ index: utxo.vout,
83
+ nonWitnessUtxo: Buffer.from(await this.rpcCall('getrawtransaction', [utxo.txid]), 'hex')
84
+ });
85
+ }
86
+ psbt.addOutput({ address: to, value: targetAmount });
87
+ if (changeAmount > 546) {
88
+ psbt.addOutput({ address: fromAddress, value: changeAmount });
89
+ }
90
+ selectedUtxos.forEach((_, index) => psbt.signInput(index, keyPair));
91
+ psbt.finalizeAllInputs();
92
+ return await this.rpcCall('sendrawtransaction', [psbt.extractTransaction().toHex()]);
93
+ }
94
+ async getFeeRate() {
95
+ try {
96
+ const feeEstimate = await this.rpcCall('estimatesmartfee', [6]);
97
+ return feeEstimate?.feerate ? Math.ceil(feeEstimate.feerate * 100000000 / 1000) : 10;
98
+ }
99
+ catch {
100
+ return 10;
101
+ }
102
+ }
103
+ async getUtxos(address) {
104
+ const utxos = await this.rpcCall('listunspent', [1, 9999999, [address]]);
105
+ return utxos.map((utxo) => ({
106
+ txid: utxo.txid,
107
+ vout: utxo.vout,
108
+ value: Math.round(utxo.amount * 100000000),
109
+ scriptPubKey: utxo.scriptPubKey
110
+ }));
111
+ }
112
+ getAddressFromPrivateKey(privateKey) {
113
+ return bitcoin.payments.p2pkh({ pubkey: ECPair.fromWIF(privateKey).publicKey }).address;
114
+ }
115
+ async rpcCall(method, params = []) {
116
+ const response = await fetch(this.rpcUrl, {
117
+ method: 'POST',
118
+ headers: { 'Content-Type': 'application/json' },
119
+ body: JSON.stringify({
120
+ jsonrpc: '1.0',
121
+ id: randomUUID(),
122
+ method,
123
+ params
124
+ })
125
+ });
126
+ const { result, error } = await response.json();
127
+ if (error)
128
+ throw new Error(`RPC Error: ${error.message}`);
129
+ return result;
130
+ }
131
+ }
132
+ //# sourceMappingURL=btc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"btc.js","sourceRoot":"","sources":["../../src/networks/btc.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@ export interface TransactionData {
8
8
  }
9
9
  export interface Network {
10
10
  getDecimals(tokenAddress: string): Promise<number>;
11
- getTxData(txHash: string, tokenAddress: string): Promise<TransactionData | undefined>;
11
+ getTxData(txHash: string, tokenAddress: string, recipientAddress: string): Promise<TransactionData | undefined>;
12
12
  transfer(privateKey: string, to: string, value: BigNumber, tokenAddress: string): Promise<string>;
13
13
  readonly retryDelay: number;
14
14
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bronlabs/intents-sdk",
3
- "version": "1.0.17",
3
+ "version": "1.0.18",
4
4
  "description": "SDK for Intents DeFi smart contracts",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -44,6 +44,9 @@
44
44
  "@solana/spl-token": "^0.3.11",
45
45
  "@solana/web3.js": "^1.87.6",
46
46
  "big.js": "^7.0.1",
47
+ "bitcoinjs-lib": "^6.1.7",
48
+ "ecpair": "^2.1.0",
49
+ "tiny-secp256k1": "^2.2.3",
47
50
  "bs58": "^6.0.0",
48
51
  "dotenv": "^16.5.0",
49
52
  "ethers": "^5.8.0",