Skip to content

Commit baa15b7

Browse files
committed
address review feedback
1 parent ae46b49 commit baa15b7

File tree

4 files changed

+82
-97
lines changed

4 files changed

+82
-97
lines changed

client/src/lib/elements.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import {formatAssetAmount} from "../views/util";
2+
3+
export const getSupply = (asset, t) => {
4+
let { chain_stats = {}, mempool_stats = {} } = asset
5+
let has_blinded_issuances =
6+
chain_stats.has_blinded_issuances || mempool_stats.has_blinded_issuances
7+
let is_native_asset = !asset.issuance_txin
8+
let circulating = is_native_asset
9+
? chain_stats.peg_in_amount +
10+
mempool_stats.peg_in_amount -
11+
chain_stats.peg_out_amount -
12+
mempool_stats.peg_out_amount -
13+
chain_stats.burned_amount -
14+
mempool_stats.burned_amount
15+
: has_blinded_issuances
16+
? null
17+
: chain_stats.issued_amount +
18+
mempool_stats.issued_amount -
19+
chain_stats.burned_amount -
20+
mempool_stats.burned_amount;
21+
22+
let totalSupply = circulating == null ? t`Confidential`
23+
: formatAssetAmount(circulating, asset.precision, t)
24+
return totalSupply
25+
}
26+
27+
28+
// Simplicity helpers (Elements only)
29+
30+
// Helper to check if witness has an annex (per BIP 341)
31+
const hasAnnex = (witness) => witness && witness.length >= 2 && witness[witness.length - 1].startsWith('50')
32+
33+
// Get the control block element from a witness stack (accounting for optional annex)
34+
const getControlBlock = witness => {
35+
if (!witness || witness.length < 3) return null
36+
const hasAnnexBlock = hasAnnex(witness)
37+
if (hasAnnexBlock) {
38+
return witness[witness.length - 2]
39+
}
40+
return witness[witness.length - 1]
41+
}
42+
43+
// Check if a vin is a P2TR Simplicity spend
44+
// A P2TR Simplicity spend has:
45+
// - 4 witness elements (or 5 with optional annex)
46+
// - Control block starts with 'be' or 'bf' (leaf version for Simplicity)
47+
export const isSimplicitySpend = (vin) => {
48+
if (!process.env.IS_ELEMENTS || !vin.witness) return false
49+
50+
const witnessLen = vin.witness.length
51+
const hasAnnexBlock = hasAnnex(vin.witness)
52+
53+
// Must be 4 elements without annex, or 5 elements with annex
54+
if (witnessLen !== 4 && !(witnessLen === 5 && hasAnnexBlock)) return false
55+
56+
const controlBlock = getControlBlock(vin.witness)
57+
return controlBlock && (controlBlock.startsWith('be') || controlBlock.startsWith('bf'))
58+
}
59+
60+
// Extract Simplicity witness components from a vin
61+
// Returns: { witnessData, program, cmr, controlBlock, annex }
62+
export const getSimplicityWitness = (vin) => {
63+
if (!isSimplicitySpend(vin)) return null
64+
65+
const witness = vin.witness
66+
const hasAnnexBlock = hasAnnex(witness)
67+
68+
return {
69+
witnessData: witness[0],
70+
program: witness[1],
71+
cmr: witness[2],
72+
controlBlock: witness[3],
73+
annex: hasAnnexBlock && witness.length === 5 ? witness[4] : null
74+
}
75+
}

client/src/views/asset-list.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import Snabbdom from 'snabbdom-pragma'
2-
import { getSupply } from './util'
2+
import { getSupply } from '../lib/elements.js'
33
import layout from './layout'
44
import loader from '../components/loading'
55

client/src/views/tx-vin.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Snabbdom from 'snabbdom-pragma'
2-
import { linkToParentOut, formatOutAmount, formatAssetAmount, formatHex, linkToAddr, formatNumber, isSimplicitySpend, getSimplicityWitness, hexToBase64 } from './util'
2+
import { linkToParentOut, formatOutAmount, formatAssetAmount, formatHex, linkToAddr, formatNumber, hexToBase64 } from './util'
3+
import { isSimplicitySpend, getSimplicityWitness } from '../lib/elements.js'
34

45
const layout = (vin, desc, body, { t, ...S }) =>
56
<div class={{ vin: true, active: isActive(vin, S), unblinded: isUnblinded(vin) }}>
@@ -115,7 +116,7 @@ const standard = (vin, { isOpen, t, ...S }, assetMeta=getAssetMeta(vin, S)) => l
115116
</div>
116117

117118
, <div className="vin-body-row">
118-
<div>{t`Simplicity program `} <br></br> {t`(base64)`}</div>
119+
<div>{t`Simplicity program`} <br></br> {t`(base64)`}</div>
119120
<div className="mono">{hexToBase64(sw.program)}</div>
120121
</div>
121122

@@ -130,7 +131,7 @@ const standard = (vin, { isOpen, t, ...S }, assetMeta=getAssetMeta(vin, S)) => l
130131
</div>
131132

132133
, sw.annex && <div className="vin-body-row">
133-
<div>{t`Annex`}</div>
134+
<div>{t`Taproot Annex`}</div>
134135
<div className="mono">{sw.annex}</div>
135136
</div>
136137
])() }

client/src/views/util.js

Lines changed: 2 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -97,101 +97,10 @@ export const formatVMB = bytes =>
9797
: '< 0.01 vMB'
9898

9999

100-
export const getSupply = (asset, t) => {
101-
let { chain_stats = {}, mempool_stats = {} } = asset
102-
let has_blinded_issuances =
103-
chain_stats.has_blinded_issuances || mempool_stats.has_blinded_issuances
104-
let is_native_asset = !asset.issuance_txin
105-
let circulating = is_native_asset
106-
? chain_stats.peg_in_amount +
107-
mempool_stats.peg_in_amount -
108-
chain_stats.peg_out_amount -
109-
mempool_stats.peg_out_amount -
110-
chain_stats.burned_amount -
111-
mempool_stats.burned_amount
112-
: has_blinded_issuances
113-
? null
114-
: chain_stats.issued_amount +
115-
mempool_stats.issued_amount -
116-
chain_stats.burned_amount -
117-
mempool_stats.burned_amount;
118-
119-
let totalSupply = circulating == null ? t`Confidential`
120-
: formatAssetAmount(circulating, asset.precision, t)
121-
return totalSupply
122-
}
123-
124100
export const strTruncate = (str) => str.substr(0, 10) + '...' + str.substr(str.length-4, str.length);
125101

126102

127-
// Simplicity helpers (Elements only)
128-
129-
// Helper to check if witness has an annex (per BIP 341)
130-
const hasAnnex = (witness) => witness && witness.length >= 2 && witness[witness.length - 1].startsWith('50')
131-
132-
// Get the control block element from a witness stack (accounting for optional annex)
133-
const getControlBlock = witness => {
134-
if (!witness || witness.length < 3) return null
135-
const hasAnnexBlock = hasAnnex(witness)
136-
if (hasAnnexBlock) {
137-
return witness[witness.length - 2]
138-
}
139-
return witness[witness.length - 1]
140-
}
141-
142-
// Check if a vin is a P2TR Simplicity spend
143-
// A P2TR Simplicity spend has:
144-
// - 4 witness elements (or 5 with optional annex)
145-
// - Control block starts with 'be' or 'bf' (leaf version for Simplicity)
146-
export const isSimplicitySpend = vin => {
147-
if (!process.env.IS_ELEMENTS || !vin.witness) return false
148-
149-
const witnessLen = vin.witness.length
150-
const hasAnnexBlock = hasAnnex(vin.witness)
151-
152-
// Must be 4 elements without annex, or 5 elements with annex
153-
if (witnessLen !== 4 && !(witnessLen === 5 && hasAnnexBlock)) return false
154-
155-
const controlBlock = getControlBlock(vin.witness)
156-
return controlBlock && (controlBlock.startsWith('be') || controlBlock.startsWith('bf'))
157-
}
158-
159-
// Extract Simplicity witness components from a vin
160-
// Returns: { witnessData, program, cmr, controlBlock, annex }
161-
export const getSimplicityWitness = vin => {
162-
if (!isSimplicitySpend(vin)) return null
163-
164-
const witness = vin.witness
165-
const hasAnnexBlock = hasAnnex(witness)
166-
167-
if (hasAnnexBlock && witness.length === 5) {
168-
return {
169-
witnessData: witness[0],
170-
program: witness[1],
171-
cmr: witness[2],
172-
controlBlock: witness[3],
173-
annex: witness[4]
174-
}
175-
}
176-
177-
return {
178-
witnessData: witness[0],
179-
program: witness[1],
180-
cmr: witness[2],
181-
controlBlock: witness[3],
182-
annex: null
183-
}
184-
}
185-
186103
// Convert hex string to base64
187-
export const hexToBase64 = hex => {
188-
if (process.browser) {
189-
// Browser environment
190-
const bytes = hex.match(/.{1,2}/g).map(byte => parseInt(byte, 16))
191-
const binary = String.fromCharCode(...bytes)
192-
return btoa(binary)
193-
} else {
194-
// Node environment (for pre-rendering)
195-
return Buffer.from(hex, 'hex').toString('base64')
196-
}
104+
export const hexToBase64 = (hex) => {
105+
return Buffer.from(hex, 'hex').toString('base64')
197106
}

0 commit comments

Comments
 (0)