Liquid quick patch for simplicity tapscript spends

This commit is contained in:
Mononaut
2025-07-23 10:36:21 +00:00
parent 28c668b67b
commit 1dc160bb01
6 changed files with 66 additions and 16 deletions

View File

@@ -316,6 +316,12 @@ export class TaprootAddressScriptsComponent implements OnChanges {
<div style="margin-top: 10px; border-top: 1px solid #333; padding-top: 5px; word-break: break-all; white-space: normal; font-family: monospace; font-size: 12px;">
<td>${asm} ${node.value.script.asm.length > 300 ? '...' : ''}</td>
</div>`;
} else if (node.value?.script?.type === 'inner_simplicityscript') {
const hex = node.value.script.hex.slice(0, 300);
asmContent = `
<div style="margin-top: 10px; border-top: 1px solid #333; padding-top: 5px; word-break: break-all; white-space: normal; font-family: monospace; font-size: 12px;">
<td>Simplicity tapscript: ${hex} ${node.value.script.hex.length > 300 ? '...' : ''}</td>
</div>`;
}
let hiddenScriptsMessage = '';

View File

@@ -233,20 +233,34 @@
<td style="text-align: left;" [innerHTML]="vin.inner_redeemscript_asm | asmStyler"></td>
</tr>
<tr *ngIf="vin.inner_witnessscript_asm">
<td *ngIf="vin.prevout && vin.prevout.scriptpubkey_type == 'v1_p2tr'; else p2wsh" i18n="transactions-list.p2tr-tapscript">P2TR tapscript</td>
<ng-template #p2wsh>
<td i18n="transactions-list.p2wsh-witness-script">P2WSH witness script</td>
</ng-template>
<td style="text-align: left;">
<div [innerHTML]="vin.inner_witnessscript_asm | asmStyler: (showFullScript[vindex] ? 0 : 1000)"></div>
<div *ngIf="vin.inner_witnessscript_asm.length > 1000" style="display: flex;">
<span *ngIf="!showFullScript[vindex]">...</span>
<label class="btn btn-sm btn-primary mt-2" (click)="toggleShowFullScript(vindex)" style="margin-left: auto;">
<span *ngIf="!showFullScript[vindex]" i18n="show-all">Show all</span>
<span *ngIf="showFullScript[vindex]" i18n="show-less">Show less</span>
</label>
</div>
</td>
@if (isLiquid && vin.inner_simplicityscript) {
<td i18n="transactions-list.p2tr-simplicity-tapscript">P2TR Simplicity tapscript</td>
<td style="text-align: left;">
<div [innerHTML]="showFullScript[vindex] ? vin.inner_simplicityscript : vin.inner_simplicityscript.slice(0, 1000)"></div>
<div *ngIf="vin.inner_simplicityscript.length > 1000" style="display: flex;">
<span *ngIf="!showFullScript[vindex]">...</span>
<label class="btn btn-sm btn-primary mt-2" (click)="toggleShowFullScript(vindex)" style="margin-left: auto;">
<span *ngIf="!showFullScript[vindex]" i18n="show-all">Show all</span>
<span *ngIf="showFullScript[vindex]" i18n="show-less">Show less</span>
</label>
</div>
</td>
} @else {
<td *ngIf="vin.prevout && vin.prevout.scriptpubkey_type == 'v1_p2tr'; else p2wsh" i18n="transactions-list.p2tr-tapscript">P2TR tapscript</td>
<ng-template #p2wsh>
<td i18n="transactions-list.p2wsh-witness-script">P2WSH witness script</td>
</ng-template>
<td style="text-align: left;">
<div [innerHTML]="vin.inner_witnessscript_asm | asmStyler: (showFullScript[vindex] ? 0 : 1000)"></div>
<div *ngIf="vin.inner_witnessscript_asm.length > 1000" style="display: flex;">
<span *ngIf="!showFullScript[vindex]">...</span>
<label class="btn btn-sm btn-primary mt-2" (click)="toggleShowFullScript(vindex)" style="margin-left: auto;">
<span *ngIf="!showFullScript[vindex]" i18n="show-all">Show all</span>
<span *ngIf="showFullScript[vindex]" i18n="show-less">Show less</span>
</label>
</div>
</td>
}
</tr>
<tr>
<td i18n="transactions-list.nsequence">nSequence</td>

View File

@@ -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));

View File

@@ -78,6 +78,8 @@ export interface Vin {
lazy?: boolean;
// Ord
isInscription?: boolean;
// temporary field for extracted raw simplicity scripts
inner_simplicityscript?: string;
}
interface Issuance {

View File

@@ -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

View File

@@ -152,6 +152,7 @@ export type ScriptType = 'scriptpubkey'
| 'scriptsig'
| 'inner_witnessscript'
| 'inner_redeemscript'
| 'inner_simplicityscript'
export interface ScriptTemplate {
type: string;