signet.js 0.0.1-beta.7 → 0.0.1-beta.9

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.
Files changed (92) hide show
  1. package/browser/index.browser.cjs +12 -0
  2. package/browser/index.browser.cjs.map +1 -0
  3. package/browser/index.browser.js +3927 -0
  4. package/browser/index.browser.js.map +1 -0
  5. package/node/index.node.cjs +19 -0
  6. package/node/index.node.cjs.map +1 -0
  7. package/node/index.node.js +4099 -0
  8. package/node/index.node.js.map +1 -0
  9. package/package.json +18 -12
  10. package/types/chains/Bitcoin/BTCRpcAdapter/BTCRpcAdapter.d.ts +10 -0
  11. package/types/chains/Bitcoin/BTCRpcAdapter/Mempool/Mempool.d.ts +15 -0
  12. package/types/chains/Bitcoin/BTCRpcAdapter/Mempool/index.d.ts +1 -0
  13. package/types/chains/Bitcoin/BTCRpcAdapter/Mempool/types.d.ts +69 -0
  14. package/types/chains/Bitcoin/BTCRpcAdapter/index.d.ts +5 -0
  15. package/types/chains/Bitcoin/Bitcoin.d.ts +42 -0
  16. package/types/chains/Bitcoin/types.d.ts +42 -0
  17. package/types/chains/Bitcoin/utils.d.ts +2 -0
  18. package/types/chains/Chain.d.ts +21 -0
  19. package/types/chains/ChainSignatureContract.d.ts +18 -0
  20. package/types/chains/Cosmos/Cosmos.d.ts +38 -0
  21. package/types/chains/Cosmos/types.d.ts +30 -0
  22. package/types/chains/Cosmos/utils.d.ts +2 -0
  23. package/types/chains/EVM/EVM.d.ts +32 -0
  24. package/types/chains/EVM/types.d.ts +5 -0
  25. package/types/chains/EVM/utils.d.ts +7 -0
  26. package/types/chains/index.d.ts +11 -0
  27. package/types/chains/types.d.ts +18 -0
  28. package/types/index.d.ts +2 -0
  29. package/types/utils/chains/index.d.ts +1 -0
  30. package/types/utils/chains/near/ChainSignatureContract.d.ts +35 -0
  31. package/types/utils/chains/near/account.d.ts +13 -0
  32. package/types/utils/chains/near/constants.d.ts +3 -0
  33. package/types/utils/chains/near/index.d.ts +3 -0
  34. package/types/utils/chains/near/relayer/index.d.ts +1 -0
  35. package/types/utils/chains/near/relayer/relayer.d.ts +3 -0
  36. package/types/utils/chains/near/relayer/types.d.ts +22 -0
  37. package/types/utils/chains/near/signAndSend/index.d.ts +1 -0
  38. package/types/utils/chains/near/signAndSend/keypair.d.ts +5 -0
  39. package/types/utils/chains/near/transactionBuilder.d.ts +26 -0
  40. package/types/utils/chains/near/types.d.ts +54 -0
  41. package/types/utils/cryptography.d.ts +3 -0
  42. package/types/utils/index.d.ts +2 -0
  43. package/.eslintrc.json +0 -55
  44. package/.prettierrc +0 -1
  45. package/babel.config.js +0 -6
  46. package/docs/pages/chain-signatures-contract.mdx +0 -56
  47. package/docs/pages/chain.mdx +0 -45
  48. package/docs/pages/chains/bitcoin/bitcoin.mdx +0 -191
  49. package/docs/pages/chains/bitcoin/btc-rpc-adapter.mdx +0 -307
  50. package/docs/pages/chains/cosmos.mdx +0 -181
  51. package/docs/pages/chains/evm.mdx +0 -189
  52. package/docs/pages/index.mdx +0 -99
  53. package/docs/snippets/contract.ts +0 -21
  54. package/docs/snippets/env.ts +0 -13
  55. package/jest.config.ts +0 -199
  56. package/src/chains/Bitcoin/BTCRpcAdapter/BTCRpcAdapter.ts +0 -11
  57. package/src/chains/Bitcoin/BTCRpcAdapter/Mempool/Mempool.ts +0 -96
  58. package/src/chains/Bitcoin/BTCRpcAdapter/Mempool/index.ts +0 -1
  59. package/src/chains/Bitcoin/BTCRpcAdapter/Mempool/types.ts +0 -72
  60. package/src/chains/Bitcoin/BTCRpcAdapter/index.ts +0 -6
  61. package/src/chains/Bitcoin/Bitcoin.ts +0 -301
  62. package/src/chains/Bitcoin/types.ts +0 -45
  63. package/src/chains/Bitcoin/utils.ts +0 -14
  64. package/src/chains/Chain.ts +0 -96
  65. package/src/chains/ChainSignatureContract.ts +0 -48
  66. package/src/chains/Cosmos/Cosmos.ts +0 -279
  67. package/src/chains/Cosmos/types.ts +0 -35
  68. package/src/chains/Cosmos/utils.ts +0 -45
  69. package/src/chains/EVM/EVM.ts +0 -180
  70. package/src/chains/EVM/types.ts +0 -7
  71. package/src/chains/EVM/utils.ts +0 -26
  72. package/src/chains/index.ts +0 -34
  73. package/src/chains/types.ts +0 -35
  74. package/src/chains/utils.ts +0 -40
  75. package/src/index.ts +0 -2
  76. package/src/utils/chains/index.ts +0 -1
  77. package/src/utils/chains/near/ChainSignatureContract.ts +0 -195
  78. package/src/utils/chains/near/account.ts +0 -42
  79. package/src/utils/chains/near/constants.ts +0 -4
  80. package/src/utils/chains/near/index.ts +0 -3
  81. package/src/utils/chains/near/relayer/index.ts +0 -1
  82. package/src/utils/chains/near/relayer/relayer.ts +0 -39
  83. package/src/utils/chains/near/relayer/types.ts +0 -24
  84. package/src/utils/chains/near/signAndSend/index.ts +0 -1
  85. package/src/utils/chains/near/signAndSend/keypair.ts +0 -180
  86. package/src/utils/chains/near/transactionBuilder.ts +0 -138
  87. package/src/utils/chains/near/types.ts +0 -67
  88. package/src/utils/index.ts +0 -1
  89. package/tsconfig.eslint.json +0 -8
  90. package/tsconfig.json +0 -116
  91. package/vite.config.ts +0 -47
  92. package/vocs.config.ts +0 -60
package/.eslintrc.json DELETED
@@ -1,55 +0,0 @@
1
- {
2
- "env": {
3
- "browser": true,
4
- "es2021": true
5
- },
6
- "extends": [
7
- "standard-with-typescript",
8
- "plugin:import/typescript",
9
- "plugin:prettier/recommended"
10
- ],
11
- "parserOptions": {
12
- "project": ["./tsconfig.json", "./tsconfig.eslint.json"]
13
- },
14
- "rules": {
15
- "@typescript-eslint/strict-boolean-expressions": "off",
16
- "@typescript-eslint/prefer-nullish-coalescing": "off",
17
- "import/order": [
18
- "error",
19
- {
20
- "groups": [
21
- "builtin",
22
- "external",
23
- "internal",
24
- "parent",
25
- "sibling",
26
- "index"
27
- ],
28
- "pathGroups": [
29
- {
30
- "pattern": "@chains",
31
- "group": "internal"
32
- },
33
- {
34
- "pattern": "@chains/**",
35
- "group": "internal"
36
- },
37
- {
38
- "pattern": "@utils",
39
- "group": "internal"
40
- },
41
- {
42
- "pattern": "@utils/**",
43
- "group": "internal"
44
- }
45
- ],
46
- "pathGroupsExcludedImportTypes": ["builtin"],
47
- "newlines-between": "always",
48
- "alphabetize": {
49
- "order": "asc",
50
- "caseInsensitive": true
51
- }
52
- }
53
- ]
54
- }
55
- }
package/.prettierrc DELETED
@@ -1 +0,0 @@
1
- { "singleQuote": true, "trailingComma": "es5", "semi": false }
package/babel.config.js DELETED
@@ -1,6 +0,0 @@
1
- module.exports = {
2
- presets: [
3
- ['@babel/preset-env', { targets: { node: 'current' } }],
4
- '@babel/preset-typescript',
5
- ],
6
- }
@@ -1,56 +0,0 @@
1
- # Implementing a Custom Chain Signature Contract
2
-
3
- This guide explains how to implement a custom Chain Signature Contract to provide as argument when instantiating a Chain instance.
4
-
5
- ## Overview
6
-
7
- The `ChainSignatureContract` is an abstract class that defines the interface for interacting with the Sig Network infrastructure.
8
-
9
- - Key Derivation: Derive the child key from the root key using Sig Network key derivation function
10
- - Sign: Sigs the given payload using Sig Network MPC
11
- - Current Fee: Gets the current signature deposit that handles network congestion
12
-
13
- While the library includes a default implementation for the NEAR protocol, you have the flexibility to implement your own contract for other blockchain networks.
14
-
15
- ## Using the NEAR Implementation
16
-
17
- ```ts twoslash
18
- // [!include ~/snippets/env.ts]
19
- // ---cut---
20
- import { utils, EVM } from 'signet.js'
21
-
22
- const contract = new utils.chains.near.ChainSignatureContract({
23
- networkId: 'testnet',
24
- contractId: 'v1.signer-prod.testnet',
25
- accountId,
26
- keypair,
27
- })
28
-
29
- const evmChain = new EVM({
30
- rpcUrl: 'https://mainnet.infura.io/v3/YOUR-PROJECT-ID',
31
- contract,
32
- })
33
- ```
34
-
35
- Currently the contracts are available on the following Near addresses:
36
-
37
- - Mainnet:
38
- - `v1.signer`
39
- - Testnet:
40
- - `v1.signer-prod.testnet`
41
-
42
- ## Implementing a Custom Chain Signature Contract
43
-
44
- To create your own implementation, your contract must implement the `ChainSignatureContract` interface.
45
-
46
- ```ts twoslash
47
- // [!include ~/../src/chains/ChainSignatureContract.ts]
48
- ```
49
-
50
- ### Example: NEAR Implementation
51
-
52
- Below is the reference implementation for the NEAR, which you can use as a guide for implementing your own chain signature contract:
53
-
54
- ```ts twoslash
55
- // [!include ~/../src/utils/chains/near/ChainSignatureContract.ts]
56
- ```
@@ -1,45 +0,0 @@
1
- # Chain
2
-
3
- Chain is the most basic interface of the signet.js library. It provides a standard set of methods that all chains must implement.
4
-
5
- With this interface you will be able to interact with Sig Network smart contracts in a standard way to:
6
-
7
- - getBalance
8
- - deriveAddressAndPublicKey
9
- - setTransaction
10
- - getTransaction
11
- - getMPCPayloadAndTransaction
12
- - addSignature
13
- - broadcastTx
14
-
15
- If you wanna have a look this is the chain interface with a brief description of each method:
16
-
17
- ```ts twoslash
18
- // [!include ~/../src/chains/Chain.ts]
19
- ```
20
-
21
- # Implementing a New Chain
22
-
23
- This guide explains how to implement support for a new blockchain network in the signet.js library.
24
-
25
- ## Overview
26
-
27
- To add support for a new blockchain, you need to implement the `Chain` interface:
28
-
29
- ## Step-by-Step Guide
30
-
31
- ### 1. Create the Chain Types
32
-
33
- First, define the transaction types for your chain:
34
-
35
- ```ts twoslash
36
- // [!include ~/../src/chains/EVM/types.ts]
37
- ```
38
-
39
- ### 2. Implement the Chain Interface
40
-
41
- Create a new class that implements the `Chain` interface:
42
-
43
- ```ts twoslash
44
- // [!include ~/../src/chains/EVM/EVM.ts]
45
- ```
@@ -1,191 +0,0 @@
1
- # Bitcoin Chain Implementation
2
-
3
- The Bitcoin chain implementation supports both Bitcoin mainnet and testnet networks, with a focus on P2WPKH (Native SegWit) transactions.
4
-
5
- ## Configuration
6
-
7
- ```ts twoslash filename="base.ts"
8
- // [!include ~/snippets/contract.ts]
9
- // ---cut---
10
- import { Bitcoin, BTCRpcAdapters } from 'signet.js'
11
-
12
- // Initialize the RPC adapter using Mempool
13
- const btcRpcAdapter = new BTCRpcAdapters.Mempool('https://mempool.space/api')
14
-
15
- // Initialize the chain
16
- const bitcoinChain = new Bitcoin({
17
- network: 'testnet', // 'mainnet' | 'testnet' | 'regtest'
18
- contract,
19
- btcRpcAdapter,
20
- })
21
- ```
22
-
23
- ## RPC Adapter
24
-
25
- The RPC adapter is a class that provides an interface for interacting with the Bitcoin network. It handles essential operations such as:
26
-
27
- - Fetching UTXOs (Unspent Transaction Outputs)
28
- - Retrieving transaction details
29
- - Getting current network fees
30
- - Broadcasting transactions
31
- - Querying address balances
32
-
33
- The adapter abstracts away the complexity of different Bitcoin API providers, allowing you to easily switch between services like Mempool.space, BlockCypher, or your own Bitcoin node.
34
-
35
- For detailed implementation and configuration options, see the [RPC Adapter](./btc-rpc-adapter) documentation.
36
-
37
- ## Methods
38
-
39
- ### getBalance
40
-
41
- Gets the BTC balance of an address.
42
-
43
- ```ts twoslash
44
- // [!include base.ts]
45
- // ---cut---
46
- const balance = await bitcoinChain.getBalance(
47
- 'bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh'
48
- )
49
- ```
50
-
51
- **Parameters:**
52
-
53
- - `address`: The Bitcoin address to check
54
-
55
- **Returns:**
56
-
57
- - The balance in BTC as a string
58
-
59
- ### deriveAddressAndPublicKey
60
-
61
- Derives a Bitcoin address and public key for a given path.
62
-
63
- ```ts twoslash
64
- // [!include base.ts]
65
- // ---cut---
66
- const { address, publicKey } = await bitcoinChain.deriveAddressAndPublicKey(
67
- 'predecessor_id',
68
- 'any_string'
69
- )
70
- ```
71
-
72
- **Parameters:**
73
-
74
- - `predecessor`: The ID of the signer to derive from
75
- - `path`: The derivation path to use
76
-
77
- **Returns:**
78
-
79
- - Object containing:
80
- - `address`: The derived Bitcoin P2WPKH address
81
- - `publicKey`: The corresponding compressed public key
82
-
83
- ### getMPCPayloadAndTransaction
84
-
85
- Prepares a transaction for MPC signing.
86
-
87
- ```ts twoslash filename="unsigned-transaction.ts"
88
- // [!include base.ts]
89
- // ---cut---
90
- import { BTCTransactionRequest } from 'signet.js'
91
-
92
- // Simple transfer format
93
- const transactionRequest: BTCTransactionRequest = {
94
- from: 'bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh',
95
- to: 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4',
96
- value: '0.001', // 0.001 BTC
97
- publicKey: '0235a3...',
98
- }
99
-
100
- const { transaction: unsignedTransaction, mpcPayloads } =
101
- await bitcoinChain.getMPCPayloadAndTransaction(transactionRequest)
102
- ```
103
-
104
- **Parameters:**
105
-
106
- - `transactionRequest`: Either:
107
- - Simple format:
108
- ```ts
109
- {
110
- from: string // Source address
111
- to: string // Destination address
112
- value: string // Amount in BTC
113
- publicKey: string // Signer's public key
114
- }
115
- ```
116
- - Advanced format (manual UTXO selection):
117
- ```ts
118
- {
119
- inputs: BTCInput[] // Selected UTXOs
120
- outputs: BTCOutput[] // Transaction outputs
121
- publicKey: string // Signer's public key
122
- }
123
- ```
124
-
125
- **Returns:**
126
-
127
- - Object containing:
128
- - `transaction`: The unsigned transaction with PSBT
129
- - `mpcPayloads`: Array of payloads to be signed
130
-
131
- ### addSignature
132
-
133
- Adds signatures to a PSBT.
134
-
135
- ```ts twoslash filename="add-signature.ts"
136
- // [!include unsigned-transaction.ts]
137
- // ---cut---
138
- import { RSVSignature } from 'signet.js'
139
-
140
- // Ideally it would be a request to the Sig Network Smart Contract
141
- const mpcSignatures: RSVSignature[] = [
142
- {
143
- r: '0x...',
144
- s: '0x...',
145
- v: 27,
146
- },
147
- ]
148
-
149
- const signedTx = bitcoinChain.addSignature({
150
- transaction: unsignedTransaction,
151
- mpcSignatures,
152
- })
153
- ```
154
-
155
- **Parameters:**
156
-
157
- - `transaction`: The unsigned transaction with PSBT
158
- - `mpcSignatures`: Array of RSV signatures from MPC
159
-
160
- **Returns:**
161
-
162
- - The serialized signed transaction in hex format
163
-
164
- ### broadcastTx
165
-
166
- Broadcasts a signed transaction to the network.
167
-
168
- ```ts twoslash filename="broadcast-tx.ts"
169
- // [!include add-signature.ts]
170
- // ---cut---
171
- const txid = await bitcoinChain.broadcastTx(signedTx)
172
- ```
173
-
174
- **Parameters:**
175
-
176
- - `txSerialized`: The serialized transaction in hex format
177
-
178
- **Returns:**
179
-
180
- - The transaction ID (txid)
181
-
182
- ## Technical Details
183
-
184
- The implementation:
185
-
186
- - Uses `bitcoinjs-lib` for transaction handling
187
- - Supports P2WPKH (Native SegWit) addresses
188
- - Handles automatic UTXO selection and change outputs
189
- - Supports custom fee rates through the RPC adapter
190
- - Uses PSBT (Partially Signed Bitcoin Transactions)
191
- - Supports both mainnet and testnet networks
@@ -1,307 +0,0 @@
1
- # Implementing a Bitcoin RPC Adapter
2
-
3
- This guide explains how to implement a custom RPC adapter for interacting with Bitcoin nodes or services.
4
-
5
- ## Overview
6
-
7
- The `BTCRpcAdapter` provides an abstraction layer for Bitcoin-specific operations like UTXO management, balance queries, and transaction broadcasting. You might want to implement a custom adapter when:
8
-
9
- - Using a different Bitcoin node implementation
10
- - Integrating with a specific blockchain service
11
- - Adding support for custom transaction types
12
- - Implementing specialized UTXO selection strategies
13
-
14
- ## Step-by-Step Guide
15
-
16
- ### 1. Define the Required Types
17
-
18
- First, ensure you have the necessary types defined:
19
-
20
- ```typescript
21
- interface BTCInput {
22
- txid: string
23
- vout: number
24
- value: number
25
- address: string
26
- scriptPubKey: string
27
- }
28
-
29
- interface BTCOutput {
30
- address: string
31
- value: number
32
- }
33
-
34
- interface BTCTransaction {
35
- txid: string
36
- vout: Array<{
37
- scriptpubkey: string
38
- value: number
39
- }>
40
- }
41
- ```
42
-
43
- ### 2. Implement the BTCRpcAdapter
44
-
45
- Create a new class that extends the `BTCRpcAdapter` abstract class:
46
-
47
- ```typescript
48
- import { BTCRpcAdapter } from '../BTCRpcAdapter'
49
- import { BTCInput, BTCOutput, BTCTransaction } from '../types'
50
-
51
- export class CustomBTCAdapter extends BTCRpcAdapter {
52
- constructor(
53
- private readonly config: {
54
- url: string
55
- apiKey?: string
56
- }
57
- ) {
58
- super()
59
- }
60
-
61
- async getBalance(address: string): Promise<number> {
62
- // Implement balance fetching
63
- const response = await fetch(
64
- `${this.config.url}/address/${address}/balance`,
65
- {
66
- headers: this.getHeaders(),
67
- }
68
- )
69
-
70
- if (!response.ok) {
71
- throw new Error(`Failed to fetch balance: ${await response.text()}`)
72
- }
73
-
74
- const data = await response.json()
75
- return data.balance // Return balance in satoshis
76
- }
77
-
78
- async getTransaction(txid: string): Promise<BTCTransaction> {
79
- // Implement transaction fetching
80
- const response = await fetch(`${this.config.url}/tx/${txid}`, {
81
- headers: this.getHeaders(),
82
- })
83
-
84
- if (!response.ok) {
85
- throw new Error(`Failed to fetch transaction: ${await response.text()}`)
86
- }
87
-
88
- return await response.json()
89
- }
90
-
91
- async selectUTXOs(
92
- from: string,
93
- outputs: BTCOutput[],
94
- confirmationTarget = 6
95
- ): Promise<{
96
- inputs: BTCInput[]
97
- outputs: BTCOutput[]
98
- }> {
99
- // 1. Fetch available UTXOs
100
- const utxos = await this.fetchUTXOs(from)
101
-
102
- // 2. Get current fee rate
103
- const feeRate = await this.getFeeRate(confirmationTarget)
104
-
105
- // 3. Use coinselect for UTXO selection
106
- const { inputs, outputs } = coinselect(utxos, outputs, feeRate)
107
-
108
- if (!inputs || !outputs) {
109
- throw new Error('Failed to select UTXOs')
110
- }
111
-
112
- return { inputs, outputs }
113
- }
114
-
115
- async broadcastTransaction(txHex: string): Promise<string> {
116
- // Implement transaction broadcasting
117
- const response = await fetch(`${this.config.url}/tx`, {
118
- method: 'POST',
119
- headers: this.getHeaders(),
120
- body: txHex,
121
- })
122
-
123
- if (!response.ok) {
124
- throw new Error(
125
- `Failed to broadcast transaction: ${await response.text()}`
126
- )
127
- }
128
-
129
- return await response.text() // Return txid
130
- }
131
-
132
- // Helper methods
133
- private getHeaders(): Record<string, string> {
134
- const headers: Record<string, string> = {
135
- 'Content-Type': 'application/json',
136
- }
137
-
138
- if (this.config.apiKey) {
139
- headers['Authorization'] = `Bearer ${this.config.apiKey}`
140
- }
141
-
142
- return headers
143
- }
144
-
145
- private async fetchUTXOs(address: string): Promise<BTCInput[]> {
146
- const response = await fetch(`${this.config.url}/address/${address}/utxo`, {
147
- headers: this.getHeaders(),
148
- })
149
-
150
- if (!response.ok) {
151
- throw new Error(`Failed to fetch UTXOs: ${await response.text()}`)
152
- }
153
-
154
- return await response.json()
155
- }
156
-
157
- private async getFeeRate(confirmationTarget: number): Promise<number> {
158
- const response = await fetch(`${this.config.url}/fees/recommended`, {
159
- headers: this.getHeaders(),
160
- })
161
-
162
- if (!response.ok) {
163
- throw new Error(`Failed to fetch fee rate: ${await response.text()}`)
164
- }
165
-
166
- const fees = await response.json()
167
- return fees[`${confirmationTarget}BlockFee`]
168
- }
169
- }
170
- ```
171
-
172
- ### 3. Implement Error Handling
173
-
174
- Add proper error handling for your adapter:
175
-
176
- ```typescript
177
- class BTCAdapterError extends Error {
178
- constructor(
179
- message: string,
180
- public readonly code: string,
181
- public readonly httpStatus?: number
182
- ) {
183
- super(message)
184
- this.name = 'BTCAdapterError'
185
- }
186
- }
187
-
188
- // Usage in adapter methods
189
- private async handleResponse<T>(
190
- response: Response,
191
- errorContext: string
192
- ): Promise<T> {
193
- if (!response.ok) {
194
- throw new BTCAdapterError(
195
- `${errorContext}: ${await response.text()}`,
196
- 'API_ERROR',
197
- response.status
198
- )
199
- }
200
-
201
- return await response.json()
202
- }
203
- ```
204
-
205
- ### 4. Add UTXO Selection Strategy
206
-
207
- Implement a custom UTXO selection strategy if needed:
208
-
209
- ```typescript
210
- interface UTXOSelectionStrategy {
211
- select(
212
- utxos: BTCInput[],
213
- outputs: BTCOutput[],
214
- feeRate: number
215
- ): {
216
- inputs: BTCInput[]
217
- outputs: BTCOutput[]
218
- }
219
- }
220
-
221
- class LargestFirstStrategy implements UTXOSelectionStrategy {
222
- select(
223
- utxos: BTCInput[],
224
- outputs: BTCOutput[],
225
- feeRate: number
226
- ): {
227
- inputs: BTCInput[]
228
- outputs: BTCOutput[]
229
- } {
230
- // Sort UTXOs by value (largest first)
231
- const sortedUtxos = [...utxos].sort((a, b) => b.value - a.value)
232
-
233
- // Implement selection logic
234
- // ...
235
-
236
- return { inputs, outputs }
237
- }
238
- }
239
- ```
240
-
241
- ## Example Usage
242
-
243
- ```typescript
244
- // Initialize the adapter
245
- const btcAdapter = new CustomBTCAdapter({
246
- url: 'https://api.bitcoin-service.com',
247
- apiKey: 'your-api-key',
248
- })
249
-
250
- // Use in Bitcoin chain implementation
251
- const bitcoinChain = new Bitcoin({
252
- network: 'mainnet',
253
- contract: new ChainSignatureContract(...),
254
- btcRpcAdapter: btcAdapter,
255
- })
256
-
257
- // Direct usage
258
- const balance = await btcAdapter.getBalance('bc1...')
259
-
260
- const { inputs, outputs } = await btcAdapter.selectUTXOs(
261
- 'bc1...',
262
- [{ address: 'bc1...', value: 100000 }]
263
- )
264
-
265
- const txid = await btcAdapter.broadcastTransaction(signedTxHex)
266
- ```
267
-
268
- ## Testing
269
-
270
- Create comprehensive tests for your adapter:
271
-
272
- ```typescript
273
- describe('CustomBTCAdapter', () => {
274
- let adapter: CustomBTCAdapter
275
- let mockFetch: jest.Mock
276
-
277
- beforeEach(() => {
278
- mockFetch = jest.fn()
279
- global.fetch = mockFetch
280
- adapter = new CustomBTCAdapter({
281
- url: 'https://test.api',
282
- apiKey: 'test-key',
283
- })
284
- })
285
-
286
- describe('getBalance', () => {
287
- it('should return balance in satoshis', async () => {
288
- mockFetch.mockResolvedValueOnce({
289
- ok: true,
290
- json: () => Promise.resolve({ balance: 100000 }),
291
- })
292
-
293
- const balance = await adapter.getBalance('bc1...')
294
- expect(balance).toBe(100000)
295
- })
296
-
297
- it('should handle errors', async () => {
298
- mockFetch.mockResolvedValueOnce({
299
- ok: false,
300
- text: () => Promise.resolve('API Error'),
301
- })
302
-
303
- await expect(adapter.getBalance('bc1...')).rejects.toThrow()
304
- })
305
- })
306
- })
307
- ```