11import assert from 'assert' ;
22
33import {
4+ BaseCoin ,
45 HalfSignedUtxoTransaction ,
56 IInscriptionBuilder ,
67 IWallet ,
78 KeyIndices ,
89 PrebuildTransactionResult ,
910 PreparedInscriptionRevealData ,
1011 SubmitTransactionResponse ,
12+ Triple ,
1113 xprvToRawPrv ,
12- xpubToCompressedPub ,
1314} from '@bitgo/sdk-core' ;
14- import * as utxolib from '@bitgo/utxo-lib ' ;
15+ import { bip32 } from '@bitgo/secp256k1 ' ;
1516import {
1617 createPsbtForSingleInscriptionPassingTransaction ,
1718 DefaultInscriptionConstraints ,
@@ -23,10 +24,24 @@ import {
2324 findOutputLayoutForWalletUnspents ,
2425 MAX_UNSPENTS_FOR_OUTPUT_LAYOUT ,
2526 SatPoint ,
27+ WalletUnspent ,
28+ type TapLeafScript ,
2629} from '@bitgo/utxo-ord' ;
30+ import { fixedScriptWallet } from '@bitgo/wasm-utxo' ;
2731
28- import { AbstractUtxoCoin , RootWalletKeys } from '../../abstractUtxoCoin' ;
29- import { getWalletKeys } from '../../recovery/crossChainRecovery' ;
32+ import { AbstractUtxoCoin } from '../../abstractUtxoCoin' ;
33+ import { fetchKeychains } from '../../keychains' ;
34+
35+ /** Key identifier for signing */
36+ type SignerKey = 'user' | 'backup' | 'bitgo' ;
37+
38+ /** Unspent from wallet API (value may be number or bigint) */
39+ type WalletUnspentLike = {
40+ id : string ;
41+ value : number | bigint ;
42+ chain : number ;
43+ index : number ;
44+ } ;
3045
3146const SUPPLEMENTARY_UNSPENTS_MIN_VALUE_SATS = [ 0 , 20_000 , 200_000 ] ;
3247
@@ -43,11 +58,26 @@ export class InscriptionBuilder implements IInscriptionBuilder {
4358 const user = await this . wallet . baseCoin . keychains ( ) . get ( { id : this . wallet . keyIds ( ) [ KeyIndices . USER ] } ) ;
4459 assert ( user . pub ) ;
4560
46- const derived = this . coin . deriveKeyWithSeed ( { key : user . pub , seed : inscriptionData . toString ( ) } ) ;
47- const compressedPublicKey = xpubToCompressedPub ( derived . key ) ;
48- const xOnlyPublicKey = utxolib . bitgo . outputScripts . toXOnlyPublicKey ( Buffer . from ( compressedPublicKey , 'hex' ) ) ;
61+ const userKey = bip32 . fromBase58 ( user . pub ) ;
62+ const { key : derivedKey } = BaseCoin . deriveKeyWithSeedBip32 ( userKey , inscriptionData . toString ( ) ) ;
63+
64+ const result = inscriptions . createInscriptionRevealData (
65+ derivedKey . publicKey ,
66+ contentType ,
67+ inscriptionData ,
68+ this . coin . name
69+ ) ;
4970
50- return inscriptions . createInscriptionRevealData ( xOnlyPublicKey , contentType , inscriptionData , this . coin . network ) ;
71+ // Convert TapLeafScript to utxolib format for backwards compatibility
72+ return {
73+ address : result . address ,
74+ revealTransactionVSize : result . revealTransactionVSize ,
75+ tapLeafScript : {
76+ controlBlock : Buffer . from ( result . tapLeafScript . controlBlock ) ,
77+ script : Buffer . from ( result . tapLeafScript . script ) ,
78+ leafVersion : result . tapLeafScript . leafVersion ,
79+ } ,
80+ } ;
5181 }
5282
5383 private async prepareTransferWithExtraInputs (
@@ -59,38 +89,43 @@ export class InscriptionBuilder implements IInscriptionBuilder {
5989 inscriptionConstraints,
6090 txFormat,
6191 } : {
62- signer : utxolib . bitgo . KeyName ;
63- cosigner : utxolib . bitgo . KeyName ;
92+ signer : SignerKey ;
93+ cosigner : SignerKey ;
6494 inscriptionConstraints : {
6595 minChangeOutput ?: bigint ;
6696 minInscriptionOutput ?: bigint ;
6797 maxInscriptionOutput ?: bigint ;
6898 } ;
6999 txFormat ?: 'psbt' | 'legacy' ;
70100 } ,
71- rootWalletKeys : RootWalletKeys ,
101+ walletXpubs : Triple < string > ,
72102 outputs : InscriptionOutputs ,
73- inscriptionUnspents : utxolib . bitgo . WalletUnspent < bigint > [ ] ,
103+ inscriptionUnspents : WalletUnspent [ ] ,
74104 supplementaryUnspentsMinValue : number
75105 ) : Promise < PrebuildTransactionResult > {
76- let supplementaryUnspents : utxolib . bitgo . WalletUnspent < bigint > [ ] = [ ] ;
106+ let supplementaryUnspents : WalletUnspent [ ] = [ ] ;
77107 if ( supplementaryUnspentsMinValue > 0 ) {
78108 const response = await this . wallet . unspents ( {
79109 minValue : supplementaryUnspentsMinValue ,
80110 } ) ;
81111 // Filter out the inscription unspent from the supplementary unspents
82112 supplementaryUnspents = response . unspents
83- . filter ( ( unspent ) => unspent . id !== inscriptionUnspents [ 0 ] . id )
113+ . filter ( ( unspent : { id : string } ) => unspent . id !== inscriptionUnspents [ 0 ] . id )
84114 . slice ( 0 , MAX_UNSPENTS_FOR_OUTPUT_LAYOUT - 1 )
85- . map ( ( unspent ) => {
86- unspent . value = BigInt ( unspent . value ) ;
87- return unspent ;
88- } ) ;
115+ . map (
116+ ( unspent : WalletUnspentLike ) : WalletUnspent => ( {
117+ id : unspent . id ,
118+ value : BigInt ( unspent . value ) ,
119+ chain : unspent . chain ,
120+ index : unspent . index ,
121+ } )
122+ ) ;
89123 }
124+
90125 const psbt = createPsbtForSingleInscriptionPassingTransaction (
91- this . coin . network ,
126+ this . coin . name ,
92127 {
93- walletKeys : rootWalletKeys ,
128+ walletKeys : walletXpubs ,
94129 signer,
95130 cosigner,
96131 } ,
@@ -117,7 +152,7 @@ export class InscriptionBuilder implements IInscriptionBuilder {
117152 }
118153 return {
119154 walletId : this . wallet . id ( ) ,
120- txHex : txFormat === 'psbt' ? psbt . toHex ( ) : psbt . getUnsignedTx ( ) . toHex ( ) ,
155+ txHex : Buffer . from ( psbt . serialize ( ) ) . toString ( 'hex' ) ,
121156 txInfo : { unspents : allUnspents } ,
122157 feeInfo : { fee : Number ( outputLayout . layout . feeOutput ) , feeString : outputLayout . layout . feeOutput . toString ( ) } ,
123158 } ;
@@ -146,27 +181,37 @@ export class InscriptionBuilder implements IInscriptionBuilder {
146181 changeAddressType = 'p2wsh' ,
147182 txFormat = 'psbt' ,
148183 } : {
149- signer ?: utxolib . bitgo . KeyName ;
150- cosigner ?: utxolib . bitgo . KeyName ;
184+ signer ?: SignerKey ;
185+ cosigner ?: SignerKey ;
151186 inscriptionConstraints ?: {
152187 minChangeOutput ?: bigint ;
153188 minInscriptionOutput ?: bigint ;
154189 maxInscriptionOutput ?: bigint ;
155190 } ;
156- changeAddressType ?: utxolib . bitgo . outputScripts . ScriptType2Of3 ;
191+ changeAddressType ?: 'p2sh' | 'p2shP2wsh' | 'p2wsh' | 'p2tr' | 'p2trMusig2' ;
157192 txFormat ?: 'psbt' | 'legacy' ;
158193 }
159194 ) : Promise < PrebuildTransactionResult > {
160195 assert ( isSatPoint ( satPoint ) ) ;
161196
162- const rootWalletKeys = await getWalletKeys ( this . coin , this . wallet ) ;
197+ const keychains = await fetchKeychains ( this . coin , this . wallet ) ;
198+ const walletXpubs : Triple < string > = [ keychains . user . pub , keychains . backup . pub , keychains . bitgo . pub ] ;
163199 const parsedSatPoint = parseSatPoint ( satPoint ) ;
164200 const transaction = await this . wallet . getTransaction ( { txHash : parsedSatPoint . txid } ) ;
165- const unspents : utxolib . bitgo . WalletUnspent < bigint > [ ] = [ transaction . outputs [ parsedSatPoint . vout ] ] ;
166- unspents [ 0 ] . value = BigInt ( unspents [ 0 ] . value ) ;
201+ const output = transaction . outputs [ parsedSatPoint . vout ] ;
202+ const unspents : WalletUnspent [ ] = [
203+ {
204+ id : `${ parsedSatPoint . txid } :${ parsedSatPoint . vout } ` ,
205+ value : BigInt ( output . value ) ,
206+ chain : output . chain ,
207+ index : output . index ,
208+ } ,
209+ ] ;
210+
211+ const changeChain = fixedScriptWallet . ChainCode . value ( changeAddressType , 'internal' ) ;
167212
168213 const changeAddress = await this . wallet . createAddress ( {
169- chain : utxolib . bitgo . getInternalChainCode ( changeAddressType ) ,
214+ chain : changeChain ,
170215 } ) ;
171216 const outputs : InscriptionOutputs = {
172217 inscriptionRecipient : recipient ,
@@ -182,7 +227,7 @@ export class InscriptionBuilder implements IInscriptionBuilder {
182227 satPoint ,
183228 feeRateSatKB ,
184229 { signer, cosigner, inscriptionConstraints, txFormat } ,
185- rootWalletKeys ,
230+ walletXpubs ,
186231 outputs ,
187232 unspents ,
188233 supplementaryUnspentsMinValue
@@ -209,10 +254,10 @@ export class InscriptionBuilder implements IInscriptionBuilder {
209254 */
210255 async signAndSendReveal (
211256 walletPassphrase : string ,
212- tapLeafScript : utxolib . bitgo . TapLeafScript ,
257+ tapLeafScript : TapLeafScript ,
213258 commitAddress : string ,
214259 unsignedCommitTx : Buffer ,
215- commitTransactionUnspents : utxolib . bitgo . WalletUnspent [ ] ,
260+ commitTransactionUnspents : WalletUnspentLike [ ] ,
216261 recipientAddress : string ,
217262 inscriptionData : Buffer
218263 ) : Promise < SubmitTransactionResponse > {
@@ -230,19 +275,19 @@ export class InscriptionBuilder implements IInscriptionBuilder {
230275 const derived = this . coin . deriveKeyWithSeed ( { key : xprv , seed : inscriptionData . toString ( ) } ) ;
231276 const prv = xprvToRawPrv ( derived . key ) ;
232277
233- const fullySignedRevealTransaction = await inscriptions . signRevealTransaction (
278+ const fullySignedRevealTransaction = inscriptions . signRevealTransaction (
234279 Buffer . from ( prv , 'hex' ) ,
235280 tapLeafScript ,
236281 commitAddress ,
237282 recipientAddress ,
238283 Buffer . from ( halfSignedCommitTransaction . txHex , 'hex' ) ,
239- this . coin . network
284+ this . coin . name
240285 ) ;
241286
242287 return this . wallet . submitTransaction ( {
243288 halfSigned : {
244289 txHex : halfSignedCommitTransaction . txHex ,
245- signedChildPsbt : fullySignedRevealTransaction . toHex ( ) ,
290+ signedChildPsbt : Buffer . from ( fullySignedRevealTransaction ) . toString ( 'hex' ) ,
246291 } ,
247292 } ) ;
248293 }
0 commit comments