@lifi/sdk-provider-bitcoin 4.0.1-alpha.0 → 4.0.1

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 (152) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +88 -5
  3. package/dist/cjs/BitcoinProvider.d.ts +7 -2
  4. package/dist/cjs/BitcoinProvider.js +30 -34
  5. package/dist/cjs/BitcoinProvider.js.map +1 -1
  6. package/dist/cjs/_virtual/_rolldown/runtime.js +23 -0
  7. package/dist/cjs/actions/getBitcoinBalance.d.ts +7 -2
  8. package/dist/cjs/actions/getBitcoinBalance.js +21 -24
  9. package/dist/cjs/actions/getBitcoinBalance.js.map +1 -1
  10. package/dist/cjs/actions/resolveBitcoinAddress.d.ts +5 -1
  11. package/dist/cjs/actions/resolveBitcoinAddress.js +6 -4
  12. package/dist/cjs/actions/resolveBitcoinAddress.js.map +1 -1
  13. package/dist/cjs/client/publicClient.d.ts +14 -4
  14. package/dist/cjs/client/publicClient.js +38 -42
  15. package/dist/cjs/client/publicClient.js.map +1 -1
  16. package/dist/cjs/core/BitcoinStepExecutor.d.ts +19 -0
  17. package/dist/cjs/core/BitcoinStepExecutor.js +47 -0
  18. package/dist/cjs/core/BitcoinStepExecutor.js.map +1 -0
  19. package/dist/cjs/core/tasks/BitcoinSignAndExecuteTask.d.ts +10 -0
  20. package/dist/cjs/core/tasks/BitcoinSignAndExecuteTask.js +75 -0
  21. package/dist/cjs/core/tasks/BitcoinSignAndExecuteTask.js.map +1 -0
  22. package/dist/cjs/core/tasks/BitcoinWaitForTransactionTask.d.ts +10 -0
  23. package/dist/cjs/core/tasks/BitcoinWaitForTransactionTask.js +38 -0
  24. package/dist/cjs/core/tasks/BitcoinWaitForTransactionTask.js.map +1 -0
  25. package/dist/cjs/errors/parseBitcoinErrors.d.ts +7 -2
  26. package/dist/cjs/errors/parseBitcoinErrors.js +17 -26
  27. package/dist/cjs/errors/parseBitcoinErrors.js.map +1 -1
  28. package/dist/cjs/index.d.ts +3 -3
  29. package/dist/cjs/index.js +5 -8
  30. package/dist/cjs/types.d.ts +18 -7
  31. package/dist/cjs/types.js +7 -5
  32. package/dist/cjs/types.js.map +1 -1
  33. package/dist/cjs/utils/generateRedeemScript.d.ts +10 -1
  34. package/dist/cjs/utils/generateRedeemScript.js +11 -5
  35. package/dist/cjs/utils/generateRedeemScript.js.map +1 -1
  36. package/dist/cjs/utils/isPsbtFinalized.d.ts +7 -2
  37. package/dist/cjs/utils/isPsbtFinalized.js +11 -10
  38. package/dist/cjs/utils/isPsbtFinalized.js.map +1 -1
  39. package/dist/cjs/utils/toBigmiChainId.d.ts +8 -3
  40. package/dist/cjs/utils/toBigmiChainId.js +10 -11
  41. package/dist/cjs/utils/toBigmiChainId.js.map +1 -1
  42. package/dist/cjs/utils/toXOnly.d.ts +5 -1
  43. package/dist/cjs/utils/toXOnly.js +4 -3
  44. package/dist/cjs/utils/toXOnly.js.map +1 -1
  45. package/dist/cjs/version.d.ts +6 -2
  46. package/dist/cjs/version.js +8 -5
  47. package/dist/cjs/version.js.map +1 -1
  48. package/dist/esm/BitcoinProvider.d.ts +7 -2
  49. package/dist/esm/BitcoinProvider.d.ts.map +1 -0
  50. package/dist/esm/BitcoinProvider.js +30 -32
  51. package/dist/esm/BitcoinProvider.js.map +1 -1
  52. package/dist/esm/actions/getBitcoinBalance.d.ts +7 -2
  53. package/dist/esm/actions/getBitcoinBalance.d.ts.map +1 -0
  54. package/dist/esm/actions/getBitcoinBalance.js +22 -22
  55. package/dist/esm/actions/getBitcoinBalance.js.map +1 -1
  56. package/dist/esm/actions/resolveBitcoinAddress.d.ts +5 -1
  57. package/dist/esm/actions/resolveBitcoinAddress.d.ts.map +1 -0
  58. package/dist/esm/actions/resolveBitcoinAddress.js +6 -3
  59. package/dist/esm/actions/resolveBitcoinAddress.js.map +1 -1
  60. package/dist/esm/client/publicClient.d.ts +13 -9
  61. package/dist/esm/client/publicClient.d.ts.map +1 -0
  62. package/dist/esm/client/publicClient.js +38 -46
  63. package/dist/esm/client/publicClient.js.map +1 -1
  64. package/dist/esm/core/BitcoinStepExecutor.d.ts +19 -0
  65. package/dist/esm/core/BitcoinStepExecutor.d.ts.map +1 -0
  66. package/dist/esm/core/BitcoinStepExecutor.js +46 -0
  67. package/dist/esm/core/BitcoinStepExecutor.js.map +1 -0
  68. package/dist/esm/core/tasks/BitcoinSignAndExecuteTask.d.ts +10 -0
  69. package/dist/esm/core/tasks/BitcoinSignAndExecuteTask.d.ts.map +1 -0
  70. package/dist/esm/core/tasks/BitcoinSignAndExecuteTask.js +72 -0
  71. package/dist/esm/core/tasks/BitcoinSignAndExecuteTask.js.map +1 -0
  72. package/dist/esm/core/tasks/BitcoinWaitForTransactionTask.d.ts +10 -0
  73. package/dist/esm/core/tasks/BitcoinWaitForTransactionTask.d.ts.map +1 -0
  74. package/dist/esm/core/tasks/BitcoinWaitForTransactionTask.js +37 -0
  75. package/dist/esm/core/tasks/BitcoinWaitForTransactionTask.js.map +1 -0
  76. package/dist/esm/errors/parseBitcoinErrors.d.ts +7 -2
  77. package/dist/esm/errors/parseBitcoinErrors.d.ts.map +1 -0
  78. package/dist/esm/errors/parseBitcoinErrors.js +17 -24
  79. package/dist/esm/errors/parseBitcoinErrors.js.map +1 -1
  80. package/dist/esm/index.d.ts +3 -3
  81. package/dist/esm/index.js +3 -4
  82. package/dist/esm/package.json +1 -1
  83. package/dist/esm/types.d.ts +18 -7
  84. package/dist/esm/types.d.ts.map +1 -0
  85. package/dist/esm/types.js +7 -3
  86. package/dist/esm/types.js.map +1 -1
  87. package/dist/esm/utils/generateRedeemScript.d.ts +9 -5
  88. package/dist/esm/utils/generateRedeemScript.d.ts.map +1 -0
  89. package/dist/esm/utils/generateRedeemScript.js +10 -8
  90. package/dist/esm/utils/generateRedeemScript.js.map +1 -1
  91. package/dist/esm/utils/isPsbtFinalized.d.ts +7 -2
  92. package/dist/esm/utils/isPsbtFinalized.d.ts.map +1 -0
  93. package/dist/esm/utils/isPsbtFinalized.js +11 -8
  94. package/dist/esm/utils/isPsbtFinalized.js.map +1 -1
  95. package/dist/esm/utils/toBigmiChainId.d.ts +8 -3
  96. package/dist/esm/utils/toBigmiChainId.d.ts.map +1 -0
  97. package/dist/esm/utils/toBigmiChainId.js +11 -9
  98. package/dist/esm/utils/toBigmiChainId.js.map +1 -1
  99. package/dist/esm/utils/toXOnly.d.ts +5 -1
  100. package/dist/esm/utils/toXOnly.d.ts.map +1 -0
  101. package/dist/esm/utils/toXOnly.js +5 -2
  102. package/dist/esm/utils/toXOnly.js.map +1 -1
  103. package/dist/esm/version.d.ts +6 -2
  104. package/dist/esm/version.d.ts.map +1 -0
  105. package/dist/esm/version.js +6 -2
  106. package/dist/esm/version.js.map +1 -1
  107. package/package.json +7 -6
  108. package/src/BitcoinProvider.ts +1 -1
  109. package/src/actions/getBitcoinBalance.ts +15 -3
  110. package/src/client/publicClient.ts +1 -1
  111. package/src/core/BitcoinStepExecutor.ts +100 -0
  112. package/src/core/tasks/BitcoinSignAndExecuteTask.ts +168 -0
  113. package/src/core/tasks/BitcoinWaitForTransactionTask.ts +74 -0
  114. package/src/types.ts +13 -1
  115. package/src/utils/generateRedeemScript.ts +3 -1
  116. package/src/utils/toXOnly.ts +1 -1
  117. package/src/version.ts +1 -1
  118. package/dist/cjs/BitcoinStepExecutor.d.ts +0 -12
  119. package/dist/cjs/BitcoinStepExecutor.js +0 -198
  120. package/dist/cjs/BitcoinStepExecutor.js.map +0 -1
  121. package/dist/cjs/index.js.map +0 -1
  122. package/dist/esm/BitcoinStepExecutor.d.ts +0 -12
  123. package/dist/esm/BitcoinStepExecutor.js +0 -210
  124. package/dist/esm/BitcoinStepExecutor.js.map +0 -1
  125. package/dist/esm/index.js.map +0 -1
  126. package/dist/types/BitcoinProvider.d.ts +0 -3
  127. package/dist/types/BitcoinProvider.d.ts.map +0 -1
  128. package/dist/types/BitcoinStepExecutor.d.ts +0 -13
  129. package/dist/types/BitcoinStepExecutor.d.ts.map +0 -1
  130. package/dist/types/actions/getBitcoinBalance.d.ts +0 -3
  131. package/dist/types/actions/getBitcoinBalance.d.ts.map +0 -1
  132. package/dist/types/actions/resolveBitcoinAddress.d.ts +0 -2
  133. package/dist/types/actions/resolveBitcoinAddress.d.ts.map +0 -1
  134. package/dist/types/client/publicClient.d.ts +0 -12
  135. package/dist/types/client/publicClient.d.ts.map +0 -1
  136. package/dist/types/errors/parseBitcoinErrors.d.ts +0 -3
  137. package/dist/types/errors/parseBitcoinErrors.d.ts.map +0 -1
  138. package/dist/types/index.d.ts +0 -4
  139. package/dist/types/index.d.ts.map +0 -1
  140. package/dist/types/types.d.ts +0 -10
  141. package/dist/types/types.d.ts.map +0 -1
  142. package/dist/types/utils/generateRedeemScript.d.ts +0 -7
  143. package/dist/types/utils/generateRedeemScript.d.ts.map +0 -1
  144. package/dist/types/utils/isPsbtFinalized.d.ts +0 -3
  145. package/dist/types/utils/isPsbtFinalized.d.ts.map +0 -1
  146. package/dist/types/utils/toBigmiChainId.d.ts +0 -4
  147. package/dist/types/utils/toBigmiChainId.d.ts.map +0 -1
  148. package/dist/types/utils/toXOnly.d.ts +0 -2
  149. package/dist/types/utils/toXOnly.d.ts.map +0 -1
  150. package/dist/types/version.d.ts +0 -3
  151. package/dist/types/version.d.ts.map +0 -1
  152. package/src/BitcoinStepExecutor.ts +0 -333
@@ -1,12 +0,0 @@
1
- import { type Account, type Chain, type Client, type FallbackTransport, type HttpTransport, type PublicActions, type UTXOSchema, type WalletActions } from '@bigmi/core';
2
- import type { SDKClient } from '@lifi/sdk';
3
- type PublicClient = Client<FallbackTransport<readonly HttpTransport[]>, Chain, Account | undefined, UTXOSchema, PublicActions & WalletActions>;
4
- /**
5
- * Get an instance of a provider for a specific chain
6
- * @param client - The SDK client
7
- * @param chainId - Id of the chain the provider is for
8
- * @returns The public client for the given chain
9
- */
10
- export declare const getBitcoinPublicClient: (client: SDKClient, chainId: number) => Promise<PublicClient>;
11
- export {};
12
- //# sourceMappingURL=publicClient.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"publicClient.d.ts","sourceRoot":"","sources":["../../../src/client/publicClient.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EAGZ,KAAK,KAAK,EACV,KAAK,MAAM,EAEX,KAAK,iBAAiB,EAEtB,KAAK,aAAa,EAGlB,KAAK,aAAa,EAGlB,KAAK,UAAU,EACf,KAAK,aAAa,EAEnB,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAG1C,KAAK,YAAY,GAAG,MAAM,CACxB,iBAAiB,CAAC,SAAS,aAAa,EAAE,CAAC,EAC3C,KAAK,EACL,OAAO,GAAG,SAAS,EACnB,UAAU,EACV,aAAa,GAAG,aAAa,CAC9B,CAAA;AAKD;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GACjC,QAAQ,SAAS,EACjB,SAAS,MAAM,KACd,OAAO,CAAC,YAAY,CA0CtB,CAAA"}
@@ -1,3 +0,0 @@
1
- import { type ExecutionAction, type LiFiStep, SDKError } from '@lifi/sdk';
2
- export declare const parseBitcoinErrors: (e: Error, step?: LiFiStep, action?: ExecutionAction) => Promise<SDKError>;
3
- //# sourceMappingURL=parseBitcoinErrors.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"parseBitcoinErrors.d.ts","sourceRoot":"","sources":["../../../src/errors/parseBitcoinErrors.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,eAAe,EAEpB,KAAK,QAAQ,EACb,QAAQ,EAGT,MAAM,WAAW,CAAA;AAElB,eAAO,MAAM,kBAAkB,GAC7B,GAAG,KAAK,EACR,OAAO,QAAQ,EACf,SAAS,eAAe,KACvB,OAAO,CAAC,QAAQ,CAUlB,CAAA"}
@@ -1,4 +0,0 @@
1
- export { BitcoinProvider } from './BitcoinProvider.js';
2
- export type { BitcoinProviderOptions, BitcoinSDKProvider } from './types.js';
3
- export { isBitcoinProvider } from './types.js';
4
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,YAAY,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA"}
@@ -1,10 +0,0 @@
1
- import type { Client } from '@bigmi/core';
2
- import { type SDKProvider } from '@lifi/sdk';
3
- export interface BitcoinProviderOptions {
4
- getWalletClient?: () => Promise<Client>;
5
- }
6
- export interface BitcoinSDKProvider extends SDKProvider {
7
- setOptions(options: BitcoinProviderOptions): void;
8
- }
9
- export declare function isBitcoinProvider(provider: SDKProvider): provider is BitcoinSDKProvider;
10
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AAEvD,MAAM,WAAW,sBAAsB;IACrC,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;CACxC;AAED,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,UAAU,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI,CAAA;CAClD;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,WAAW,GACpB,QAAQ,IAAI,kBAAkB,CAEhC"}
@@ -1,7 +0,0 @@
1
- /**
2
- * Generate redeem script for P2SH addresses
3
- * @param publicKey
4
- * @returns redeem script
5
- */
6
- export declare const generateRedeemScript: (publicKey: Uint8Array) => Uint8Array<ArrayBufferLike> | undefined;
7
- //# sourceMappingURL=generateRedeemScript.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generateRedeemScript.d.ts","sourceRoot":"","sources":["../../../src/utils/generateRedeemScript.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,WAAW,UAAU,4CAEX,CAAA"}
@@ -1,3 +0,0 @@
1
- import type { Psbt } from 'bitcoinjs-lib';
2
- export declare function isPsbtFinalized(psbt: Psbt): boolean;
3
- //# sourceMappingURL=isPsbtFinalized.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"isPsbtFinalized.d.ts","sourceRoot":"","sources":["../../../src/utils/isPsbtFinalized.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAEzC,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAOnD"}
@@ -1,4 +0,0 @@
1
- import { ChainId as BigmiChainId } from '@bigmi/core';
2
- import { ChainId } from '@lifi/sdk';
3
- export declare const toBigmiChainId: (chainId: ChainId) => BigmiChainId;
4
- //# sourceMappingURL=toBigmiChainId.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"toBigmiChainId.d.ts","sourceRoot":"","sources":["../../../src/utils/toBigmiChainId.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,eAAO,MAAM,cAAc,GAAI,SAAS,OAAO,KAAG,YAOjD,CAAA"}
@@ -1,2 +0,0 @@
1
- export declare const toXOnly: (pubKey: Uint8Array) => Uint8Array<ArrayBufferLike>;
2
- //# sourceMappingURL=toXOnly.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"toXOnly.d.ts","sourceRoot":"","sources":["../../../src/utils/toXOnly.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,OAAO,GAAI,QAAQ,UAAU,gCACc,CAAA"}
@@ -1,3 +0,0 @@
1
- export declare const name = "@lifi/sdk-provider-bitcoin";
2
- export declare const version = "4.0.1-alpha.0";
3
- //# sourceMappingURL=version.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,+BAA+B,CAAA;AAChD,eAAO,MAAM,OAAO,kBAAkB,CAAA"}
@@ -1,333 +0,0 @@
1
- import type { Client, ReplacementReason } from '@bigmi/core'
2
- import {
3
- AddressType,
4
- getAddressInfo,
5
- hexToUnit8Array,
6
- signPsbt,
7
- waitForTransaction,
8
- withTimeout,
9
- } from '@bigmi/core'
10
- import * as ecc from '@bitcoinerlab/secp256k1'
11
- import {
12
- BaseStepExecutor,
13
- ChainId,
14
- checkBalance,
15
- getStepTransaction,
16
- LiFiErrorCode,
17
- type LiFiStepExtended,
18
- type SDKClient,
19
- type StepExecutorOptions,
20
- stepComparison,
21
- TransactionError,
22
- type TransactionParameters,
23
- waitForDestinationChainTransaction,
24
- } from '@lifi/sdk'
25
- import { address, initEccLib, networks, Psbt } from 'bitcoinjs-lib'
26
- import { getBitcoinPublicClient } from './client/publicClient.js'
27
- import { parseBitcoinErrors } from './errors/parseBitcoinErrors.js'
28
- import { generateRedeemScript } from './utils/generateRedeemScript.js'
29
- import { isPsbtFinalized } from './utils/isPsbtFinalized.js'
30
- import { toXOnly } from './utils/toXOnly.js'
31
-
32
- interface BitcoinStepExecutorOptions extends StepExecutorOptions {
33
- client: Client
34
- }
35
-
36
- export class BitcoinStepExecutor extends BaseStepExecutor {
37
- private client: Client
38
-
39
- constructor(options: BitcoinStepExecutorOptions) {
40
- super(options)
41
- this.client = options.client
42
- }
43
-
44
- checkClient = (step: LiFiStepExtended) => {
45
- // TODO: check chain and possibly implement chain switch?
46
- // Prevent execution of the quote by wallet different from the one which requested the quote
47
- if (this.client.account?.address !== step.action.fromAddress) {
48
- throw new TransactionError(
49
- LiFiErrorCode.WalletChangedDuringExecution,
50
- 'The wallet address that requested the quote does not match the wallet address attempting to sign the transaction.'
51
- )
52
- }
53
- }
54
-
55
- executeStep = async (
56
- client: SDKClient,
57
- step: LiFiStepExtended
58
- ): Promise<LiFiStepExtended> => {
59
- step.execution = this.statusManager.initExecutionObject(step)
60
-
61
- const fromChain = await client.getChainById(step.action.fromChainId)
62
- const toChain = await client.getChainById(step.action.toChainId)
63
-
64
- const isBridgeExecution = fromChain.id !== toChain.id
65
- const currentActionType = isBridgeExecution ? 'CROSS_CHAIN' : 'SWAP'
66
-
67
- let action = this.statusManager.findOrCreateAction({
68
- step,
69
- type: currentActionType,
70
- chainId: fromChain.id,
71
- })
72
-
73
- const publicClient = await getBitcoinPublicClient(client, ChainId.BTC)
74
-
75
- if (action.status !== 'DONE') {
76
- try {
77
- let txHash: string
78
- let txHex: string
79
- if (action.txHash) {
80
- // Make sure that the chain is still correct
81
- this.checkClient(step)
82
-
83
- // Wait for exiting transaction
84
- txHash = action.txHash
85
- txHex = action.txHex
86
- } else {
87
- action = this.statusManager.updateAction(step, action.type, 'STARTED')
88
-
89
- // Check balance
90
- await checkBalance(client, this.client.account!.address, step)
91
-
92
- // Create new transaction
93
- if (!step.transactionRequest) {
94
- const { execution, ...stepBase } = step
95
- const updatedStep = await getStepTransaction(client, stepBase)
96
- const comparedStep = await stepComparison(
97
- this.statusManager,
98
- step,
99
- updatedStep,
100
- this.allowUserInteraction,
101
- this.executionOptions
102
- )
103
- Object.assign(step, {
104
- ...comparedStep,
105
- execution: step.execution,
106
- })
107
- }
108
-
109
- if (!step.transactionRequest?.data) {
110
- throw new TransactionError(
111
- LiFiErrorCode.TransactionUnprepared,
112
- 'Unable to prepare transaction.'
113
- )
114
- }
115
-
116
- action = this.statusManager.updateAction(
117
- step,
118
- action.type,
119
- 'ACTION_REQUIRED'
120
- )
121
-
122
- if (!this.allowUserInteraction) {
123
- return step
124
- }
125
-
126
- let transactionRequest: TransactionParameters = {
127
- data: step.transactionRequest.data,
128
- }
129
-
130
- if (this.executionOptions?.updateTransactionRequestHook) {
131
- const customizedTransactionRequest: TransactionParameters =
132
- await this.executionOptions.updateTransactionRequestHook({
133
- requestType: 'transaction',
134
- ...transactionRequest,
135
- })
136
-
137
- transactionRequest = {
138
- ...transactionRequest,
139
- ...customizedTransactionRequest,
140
- }
141
- }
142
-
143
- if (!transactionRequest.data) {
144
- throw new TransactionError(
145
- LiFiErrorCode.TransactionUnprepared,
146
- 'Unable to prepare transaction.'
147
- )
148
- }
149
-
150
- this.checkClient(step)
151
-
152
- const psbtHex = transactionRequest.data
153
-
154
- // Initialize ECC library required for Taproot operations
155
- // https://github.com/bitcoinjs/bitcoinjs-lib?tab=readme-ov-file#using-taproot
156
- initEccLib(ecc)
157
-
158
- const psbt = Psbt.fromHex(psbtHex, { network: networks.bitcoin })
159
-
160
- psbt.data.inputs.forEach((input, index) => {
161
- const accountAddress = input.witnessUtxo
162
- ? address.fromOutputScript(
163
- input.witnessUtxo.script,
164
- networks.bitcoin
165
- )
166
- : (this.client.account?.address as string)
167
- const addressInfo = getAddressInfo(accountAddress)
168
- if (addressInfo.type === AddressType.p2tr) {
169
- // Taproot (P2TR) addresses require specific PSBT fields for proper signing
170
-
171
- // tapInternalKey: Required for Taproot key-path spending
172
- // Most wallets / libraries usually handle this already
173
- if (!input.tapInternalKey) {
174
- const pubKey = this.client.account?.publicKey
175
- if (pubKey) {
176
- const tapInternalKey = toXOnly(hexToUnit8Array(pubKey))
177
- psbt.updateInput(index, {
178
- tapInternalKey,
179
- })
180
- }
181
- }
182
- // sighashType: Required by bitcoinjs-lib even though the bitcoin protocol allows defaults
183
- // check if sighashType is default (0) or not set (undefined)
184
- if (!input.sighashType) {
185
- psbt.updateInput(index, {
186
- sighashType: 1, // Default to Transaction.SIGHASH_ALL - 1
187
- })
188
- }
189
- }
190
- // redeemScript: Required by Pay-to-Script-Hash (P2SH) addresses for proper spending
191
- if (addressInfo.type === AddressType.p2sh) {
192
- if (!input.redeemScript) {
193
- const pubKey = this.client.account?.publicKey
194
- if (pubKey) {
195
- psbt.updateInput(index, {
196
- redeemScript: generateRedeemScript(hexToUnit8Array(pubKey)),
197
- })
198
- }
199
- }
200
- }
201
- })
202
-
203
- const inputsToSign = Array.from(
204
- psbt.data.inputs
205
- .reduce((map, input, index) => {
206
- const accountAddress = input.witnessUtxo
207
- ? address.fromOutputScript(
208
- input.witnessUtxo.script,
209
- networks.bitcoin
210
- )
211
- : (this.client.account?.address as string)
212
- if (map.has(accountAddress)) {
213
- map.get(accountAddress).signingIndexes.push(index)
214
- } else {
215
- map.set(accountAddress, {
216
- address: accountAddress,
217
- sigHash: 1, // Default to Transaction.SIGHASH_ALL - 1
218
- signingIndexes: [index],
219
- })
220
- }
221
- return map
222
- }, new Map())
223
- .values()
224
- )
225
-
226
- // We give users 10 minutes to sign the transaction or it should be considered expired
227
- const signedPsbtHex = await withTimeout(
228
- () =>
229
- signPsbt(this.client, {
230
- psbt: psbt.toHex(),
231
- inputsToSign: inputsToSign,
232
- finalize: false,
233
- }),
234
- {
235
- timeout: 600_000,
236
- errorInstance: new TransactionError(
237
- LiFiErrorCode.TransactionExpired,
238
- 'Transaction has expired.'
239
- ),
240
- }
241
- )
242
-
243
- const signedPsbt = Psbt.fromHex(signedPsbtHex)
244
-
245
- if (!isPsbtFinalized(signedPsbt)) {
246
- signedPsbt.finalizeAllInputs()
247
- }
248
-
249
- txHex = signedPsbt.extractTransaction().toHex()
250
-
251
- txHash = await publicClient.sendUTXOTransaction({
252
- hex: txHex,
253
- })
254
-
255
- action = this.statusManager.updateAction(
256
- step,
257
- action.type,
258
- 'PENDING',
259
- {
260
- txHash: txHash,
261
- txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${txHash}`,
262
- txHex,
263
- }
264
- )
265
- }
266
-
267
- let replacementReason: ReplacementReason | undefined
268
- const transaction = await waitForTransaction(publicClient, {
269
- txId: txHash,
270
- txHex,
271
- senderAddress: this.client.account?.address,
272
- onReplaced: (response) => {
273
- replacementReason = response.reason
274
- action = this.statusManager.updateAction(
275
- step,
276
- action.type,
277
- 'PENDING',
278
- {
279
- txHash: response.transaction.txid,
280
- txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${response.transaction.txid}`,
281
- }
282
- )
283
- },
284
- })
285
-
286
- if (replacementReason === 'cancelled') {
287
- throw new TransactionError(
288
- LiFiErrorCode.TransactionCanceled,
289
- 'User canceled transaction.'
290
- )
291
- }
292
-
293
- if (transaction.txid !== txHash) {
294
- action = this.statusManager.updateAction(
295
- step,
296
- action.type,
297
- 'PENDING',
298
- {
299
- txHash: transaction.txid,
300
- txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${transaction.txid}`,
301
- }
302
- )
303
- }
304
-
305
- if (isBridgeExecution) {
306
- action = this.statusManager.updateAction(step, action.type, 'DONE')
307
- }
308
- } catch (e: any) {
309
- const error = await parseBitcoinErrors(e, step, action)
310
- action = this.statusManager.updateAction(step, action.type, 'FAILED', {
311
- error: {
312
- message: error.cause.message,
313
- code: error.code,
314
- },
315
- })
316
- throw error
317
- }
318
- }
319
-
320
- await waitForDestinationChainTransaction(
321
- client,
322
- step,
323
- action,
324
- fromChain,
325
- toChain,
326
- this.statusManager,
327
- 10_000
328
- )
329
-
330
- // DONE
331
- return step
332
- }
333
- }