diff --git a/frontend/src/app/components/taproot-address-scripts/taproot-address-scripts.component.ts b/frontend/src/app/components/taproot-address-scripts/taproot-address-scripts.component.ts index 04131bdfe..cbe02d0f5 100644 --- a/frontend/src/app/components/taproot-address-scripts/taproot-address-scripts.component.ts +++ b/frontend/src/app/components/taproot-address-scripts/taproot-address-scripts.component.ts @@ -316,6 +316,12 @@ export class TaprootAddressScriptsComponent implements OnChanges {
${asm} ${node.value.script.asm.length > 300 ? '...' : ''}
`; + } else if (node.value?.script?.type === 'inner_simplicityscript') { + const hex = node.value.script.hex.slice(0, 300); + asmContent = ` +
+ Simplicity tapscript: ${hex} ${node.value.script.hex.length > 300 ? '...' : ''} +
`; } let hiddenScriptsMessage = ''; diff --git a/frontend/src/app/components/transactions-list/transactions-list.component.html b/frontend/src/app/components/transactions-list/transactions-list.component.html index 9925d5bd8..98b4465ea 100644 --- a/frontend/src/app/components/transactions-list/transactions-list.component.html +++ b/frontend/src/app/components/transactions-list/transactions-list.component.html @@ -233,20 +233,34 @@ - P2TR tapscript - - P2WSH witness script - - -
-
- ... - -
- + @if (isLiquid && vin.inner_simplicityscript) { + P2TR Simplicity tapscript + +
+
+ ... + +
+ + } @else { + P2TR tapscript + + P2WSH witness script + + +
+
+ ... + +
+ + } nSequence diff --git a/frontend/src/app/components/transactions-list/transactions-list.component.ts b/frontend/src/app/components/transactions-list/transactions-list.component.ts index b7d6eb5aa..6ce827c17 100644 --- a/frontend/src/app/components/transactions-list/transactions-list.component.ts +++ b/frontend/src/app/components/transactions-list/transactions-list.component.ts @@ -28,6 +28,7 @@ import { SighashFlag } from '../../shared/transaction.utils'; export class TransactionsListComponent implements OnInit, OnChanges, OnDestroy { network = ''; nativeAssetId = this.stateService.network === 'liquidtestnet' ? environment.nativeTestAssetId : environment.nativeAssetId; + isLiquid = this.stateService.network === 'liquid' || this.stateService.network === 'liquidtestnet'; showMoreIncrement = 1000; @Input() transactions: Transaction[]; @@ -93,7 +94,10 @@ export class TransactionsListComponent implements OnInit, OnChanges, OnDestroy { ngOnInit(): void { this.latestBlock$ = this.stateService.blocks$.pipe(map((blocks) => blocks[0])); - this.networkSubscription = this.stateService.networkChanged$.subscribe((network) => this.network = network); + this.networkSubscription = this.stateService.networkChanged$.subscribe((network) => { + this.network = network; + this.isLiquid = network === 'liquid' || network === 'liquidtestnet'; + }); this.signaturesSubscription = this.stateService.signaturesMode$.subscribe((mode) => { this.signaturesPreference = mode; @@ -331,6 +335,21 @@ export class TransactionsListComponent implements OnInit, OnChanges, OnDestroy { } } tx['_showSignatures'] = this.shouldShowSignatures(tx); + } else { // check for simplicity script spends + for (const vin of tx.vin) { + if (vin.prevout.scriptpubkey_type === 'v1_p2tr' && vin.inner_witnessscript_asm) { + const hasAnnex = vin.witness?.[vin.witness.length - 1].startsWith('50'); + // script spend + if (vin.witness.length > (hasAnnex ? 2 : 1)) { + const controlBlock = vin.witness[vin.witness.length - (hasAnnex ? 2 : 1)]; + const script = vin.witness[vin.witness.length - (hasAnnex ? 3 : 2)]; + // simplicity tapleaf version + if (controlBlock.startsWith('be') || controlBlock.startsWith('bf')) { + vin.inner_simplicityscript = script; + } + } + } + } } tx.largeInput = tx.largeInput || tx.vin.some(vin => (vin?.prevout?.value > 1000000000)); diff --git a/frontend/src/app/interfaces/electrs.interface.ts b/frontend/src/app/interfaces/electrs.interface.ts index aa2a05a2f..04fa0e21d 100644 --- a/frontend/src/app/interfaces/electrs.interface.ts +++ b/frontend/src/app/interfaces/electrs.interface.ts @@ -78,6 +78,8 @@ export interface Vin { lazy?: boolean; // Ord isInscription?: boolean; + // temporary field for extracted raw simplicity scripts + inner_simplicityscript?: string; } interface Issuance { diff --git a/frontend/src/app/shared/address-utils.ts b/frontend/src/app/shared/address-utils.ts index bc8e12981..6a53b8578 100644 --- a/frontend/src/app/shared/address-utils.ts +++ b/frontend/src/app/shared/address-utils.ts @@ -162,7 +162,15 @@ export class AddressTypeInfo { const hasAnnex = v.witness[v.witness.length - 1].startsWith('50'); const controlBlock = hasAnnex ? v.witness[v.witness.length - 2] : v.witness[v.witness.length - 1]; const scriptHex = hasAnnex ? v.witness[v.witness.length - 3] : v.witness[v.witness.length - 2]; - this.processScript(new ScriptInfo('inner_witnessscript', scriptHex, v.inner_witnessscript_asm, v.witness, controlBlock, vinIds?.[i])); + + if ((this.network === 'liquid' || this.network === 'liquidtestnet') + && (controlBlock.startsWith('be') || controlBlock.startsWith('bf')) + ) { + v.inner_simplicityscript = scriptHex; + this.processScript(new ScriptInfo('inner_simplicityscript', scriptHex, null, v.witness, controlBlock, vinIds?.[i])); + } else { + this.processScript(new ScriptInfo('inner_witnessscript', scriptHex, v.inner_witnessscript_asm, v.witness, controlBlock, vinIds?.[i])); + } } } // for single-script types, if we've seen one input we've seen them all diff --git a/frontend/src/app/shared/script.utils.ts b/frontend/src/app/shared/script.utils.ts index 85a2fe5ba..dcd81b899 100644 --- a/frontend/src/app/shared/script.utils.ts +++ b/frontend/src/app/shared/script.utils.ts @@ -152,6 +152,7 @@ export type ScriptType = 'scriptpubkey' | 'scriptsig' | 'inner_witnessscript' | 'inner_redeemscript' + | 'inner_simplicityscript' export interface ScriptTemplate { type: string;