gitmark 0.0.72 → 0.0.74
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.
- package/.claude/settings.local.json +2 -1
- package/README.md +2 -2
- package/bin/git-mark.js +9 -7
- package/index.html +10 -1
- package/og-image.png +0 -0
- package/og-image.svg +8 -0
- package/package.json +1 -1
- package/test/git-mark.test.js +16 -3
package/README.md
CHANGED
|
@@ -60,7 +60,7 @@ The chain of addresses on Bitcoin mirrors the chain of commits in git. Anyone ca
|
|
|
60
60
|
{
|
|
61
61
|
"version": "0.0.3",
|
|
62
62
|
"profile": "gitmark",
|
|
63
|
-
"
|
|
63
|
+
"pubkeyBase": "02abc...",
|
|
64
64
|
"chain": "tbtc4",
|
|
65
65
|
"states": ["a1b2c3", "e5f6a7"],
|
|
66
66
|
"txo": [
|
|
@@ -70,7 +70,7 @@ The chain of addresses on Bitcoin mirrors the chain of commits in git. Anyone ca
|
|
|
70
70
|
}
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
- **
|
|
73
|
+
- **pubkeyBase** — compressed pubkey (02/03 prefix), base for BIP-341 key chaining
|
|
74
74
|
- **states** — commit hashes (input to key derivation)
|
|
75
75
|
- **txo** — Bitcoin anchors (TXO URIs, self-contained and verifiable)
|
|
76
76
|
|
package/bin/git-mark.js
CHANGED
|
@@ -297,7 +297,7 @@ async function cmdInit(args) {
|
|
|
297
297
|
'@type': 'Blocktrail',
|
|
298
298
|
version: '0.0.3',
|
|
299
299
|
profile: 'gitmark',
|
|
300
|
-
|
|
300
|
+
pubkeyBase: pubkey,
|
|
301
301
|
chain,
|
|
302
302
|
states: [],
|
|
303
303
|
txo: []
|
|
@@ -335,6 +335,8 @@ async function cmdInit(args) {
|
|
|
335
335
|
const newTxid = await broadcastTx(rawTx, explorer);
|
|
336
336
|
|
|
337
337
|
savePrivateState({ txid: newTxid, vout: 0, amount: outputAmount }, chain);
|
|
338
|
+
const xonly = pubkey.slice(2); // 64-char x-only Nostr pubkey
|
|
339
|
+
trail['@id'] = `txo:${chain}:${newTxid}:0?amount=${outputAmount}&pubkey=${xonly}`;
|
|
338
340
|
console.log(`Funded: ${outputAmount} sats (txid: ${newTxid})`);
|
|
339
341
|
}
|
|
340
342
|
|
|
@@ -376,7 +378,7 @@ async function cmdMark(args) {
|
|
|
376
378
|
: hexToBytes(privkey);
|
|
377
379
|
|
|
378
380
|
// Derive next address (chained through all states including current)
|
|
379
|
-
const nextPub = deriveChainedPubkey(hexToBytes(trail.
|
|
381
|
+
const nextPub = deriveChainedPubkey(hexToBytes(trail.pubkeyBase), allStates);
|
|
380
382
|
const nextXonly = nextPub.slice(1);
|
|
381
383
|
const nextScript = p2trScript(nextXonly);
|
|
382
384
|
|
|
@@ -411,7 +413,7 @@ async function cmdMark(args) {
|
|
|
411
413
|
saveTrail(trail);
|
|
412
414
|
}
|
|
413
415
|
|
|
414
|
-
const address = pubkeyToAddress(trail.
|
|
416
|
+
const address = pubkeyToAddress(trail.pubkeyBase, allStates, chain);
|
|
415
417
|
console.log(`Marked: ${head.slice(0, 8)} → ${newTxid.slice(0, 16)}...`);
|
|
416
418
|
console.log(`Address: ${address}`);
|
|
417
419
|
console.log(`Balance: ${outputAmount} sats`);
|
|
@@ -426,11 +428,11 @@ async function cmdInfo() {
|
|
|
426
428
|
console.log(`Profile: ${trail.profile}`);
|
|
427
429
|
console.log(`Version: ${trail.version}`);
|
|
428
430
|
console.log(`Chain: ${trail.chain}`);
|
|
429
|
-
console.log(`Base public key: ${trail.
|
|
430
|
-
console.log(`Base address: ${pubkeyToAddress(trail.
|
|
431
|
+
console.log(`Base public key: ${trail.pubkeyBase}`);
|
|
432
|
+
console.log(`Base address: ${pubkeyToAddress(trail.pubkeyBase, [], trail.chain)}`);
|
|
431
433
|
console.log(`Marks: ${trail.states.length}`);
|
|
432
434
|
if (trail.states.length > 0) {
|
|
433
|
-
const currentAddr = pubkeyToAddress(trail.
|
|
435
|
+
const currentAddr = pubkeyToAddress(trail.pubkeyBase, trail.states, trail.chain);
|
|
434
436
|
console.log(`Current address: ${currentAddr}`);
|
|
435
437
|
console.log(`Last commit: ${trail.states[trail.states.length - 1]}`);
|
|
436
438
|
console.log(`Last TXO: ${trail.txo[trail.txo.length - 1]}`);
|
|
@@ -455,7 +457,7 @@ async function cmdVerify() {
|
|
|
455
457
|
|
|
456
458
|
for (let i = 0; i < trail.states.length; i++) {
|
|
457
459
|
const statesUpTo = trail.states.slice(0, i + 1);
|
|
458
|
-
const expectedAddr = pubkeyToAddress(trail.
|
|
460
|
+
const expectedAddr = pubkeyToAddress(trail.pubkeyBase, statesUpTo, trail.chain);
|
|
459
461
|
const txoUri = trail.txo[i];
|
|
460
462
|
const parsed = parseTxoUri(txoUri);
|
|
461
463
|
|
package/index.html
CHANGED
|
@@ -9,6 +9,13 @@
|
|
|
9
9
|
<meta property="og:description" content="Mark your git commits on Bitcoin using blocktrails key chaining. Tamper-proof history, globally verifiable.">
|
|
10
10
|
<meta property="og:type" content="website">
|
|
11
11
|
<meta property="og:url" content="https://git-mark.com">
|
|
12
|
+
<meta property="og:image" content="https://git-mark.com/og-image.png">
|
|
13
|
+
<meta property="og:image:width" content="1200">
|
|
14
|
+
<meta property="og:image:height" content="630">
|
|
15
|
+
<meta name="twitter:card" content="summary_large_image">
|
|
16
|
+
<meta name="twitter:title" content="git mark — Anchor Git Commits to Bitcoin">
|
|
17
|
+
<meta name="twitter:description" content="Mark your git commits on Bitcoin using blocktrails key chaining. Tamper-proof history, globally verifiable.">
|
|
18
|
+
<meta name="twitter:image" content="https://git-mark.com/og-image.png">
|
|
12
19
|
<style>
|
|
13
20
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
14
21
|
body { font-family: Georgia, 'Times New Roman', serif; background: #fafaf8; color: #2c2c2c; line-height: 1.7; padding: 2rem; }
|
|
@@ -89,7 +96,7 @@ git mark info</pre>
|
|
|
89
96
|
<pre>{
|
|
90
97
|
"version": "0.0.3",
|
|
91
98
|
"profile": "gitmark",
|
|
92
|
-
"
|
|
99
|
+
"pubkeyBase": "02abc...",
|
|
93
100
|
"chain": "tbtc4",
|
|
94
101
|
"states": ["a1b2c3...", "e5f6a7..."],
|
|
95
102
|
"txo": [
|
|
@@ -122,6 +129,8 @@ git mark info</pre>
|
|
|
122
129
|
<tr><td><code>git mark</code></td><td>Anchor HEAD commit to Bitcoin</td></tr>
|
|
123
130
|
<tr><td><code>git mark info</code></td><td>Show trail state, balance, addresses</td></tr>
|
|
124
131
|
<tr><td><code>git mark verify</code></td><td>Verify all marks against Bitcoin</td></tr>
|
|
132
|
+
<tr><td><code>git mark update</code></td><td>Update blocktrails.json from git notes</td></tr>
|
|
133
|
+
<tr><td><code>git mark --version</code></td><td>Show version</td></tr>
|
|
125
134
|
</table>
|
|
126
135
|
|
|
127
136
|
<h2>Related</h2>
|
package/og-image.png
ADDED
|
Binary file
|
package/og-image.svg
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="630" viewBox="0 0 1200 630">
|
|
2
|
+
<rect width="1200" height="630" fill="#1a1a2e"/>
|
|
3
|
+
<rect x="0" y="0" width="1200" height="4" fill="#f7931a"/>
|
|
4
|
+
<text x="600" y="240" text-anchor="middle" font-family="Georgia, serif" font-size="96" font-weight="bold" fill="#f7931a">git mark</text>
|
|
5
|
+
<text x="600" y="320" text-anchor="middle" font-family="Georgia, serif" font-size="36" fill="#cccccc">Anchor Git Commits to Bitcoin</text>
|
|
6
|
+
<text x="600" y="400" text-anchor="middle" font-family="'SFMono-Regular', Consolas, monospace" font-size="22" fill="#888888">Tamper-proof history via BIP-341 key chaining</text>
|
|
7
|
+
<text x="600" y="540" text-anchor="middle" font-family="Georgia, serif" font-size="24" fill="#666666">git-mark.com</text>
|
|
8
|
+
</svg>
|
package/package.json
CHANGED
package/test/git-mark.test.js
CHANGED
|
@@ -167,7 +167,7 @@ describe('Trail format', () => {
|
|
|
167
167
|
const trail = {
|
|
168
168
|
version: '0.0.3',
|
|
169
169
|
profile: 'gitmark',
|
|
170
|
-
|
|
170
|
+
pubkeyBase: pubkey,
|
|
171
171
|
chain: 'tbtc4',
|
|
172
172
|
states: [],
|
|
173
173
|
txo: []
|
|
@@ -175,8 +175,8 @@ describe('Trail format', () => {
|
|
|
175
175
|
|
|
176
176
|
assert.strictEqual(trail.version, '0.0.3');
|
|
177
177
|
assert.strictEqual(trail.profile, 'gitmark');
|
|
178
|
-
assert.strictEqual(trail.
|
|
179
|
-
assert.ok(trail.
|
|
178
|
+
assert.strictEqual(trail.pubkeyBase.length, 66); // compressed hex
|
|
179
|
+
assert.ok(trail.pubkeyBase.startsWith('02') || trail.pubkeyBase.startsWith('03'));
|
|
180
180
|
assert.ok(Array.isArray(trail.states));
|
|
181
181
|
assert.ok(Array.isArray(trail.txo));
|
|
182
182
|
});
|
|
@@ -189,6 +189,19 @@ describe('Trail format', () => {
|
|
|
189
189
|
assert.strictEqual(trail.states.length, trail.txo.length);
|
|
190
190
|
});
|
|
191
191
|
|
|
192
|
+
it('@id is valid txo URI with amount and 64-char x-only pubkey', () => {
|
|
193
|
+
const privkey = secp256k1.utils.randomPrivateKey();
|
|
194
|
+
const pubkey = bytesToHex(secp256k1.getPublicKey(privkey, true));
|
|
195
|
+
const xonly = pubkey.slice(2);
|
|
196
|
+
const txid = 'a'.repeat(64);
|
|
197
|
+
const id = `txo:tbtc4:${txid}:0?amount=14968&pubkey=${xonly}`;
|
|
198
|
+
const parsed = parseTxoUri(id);
|
|
199
|
+
assert.strictEqual(parsed.chain, 'tbtc4');
|
|
200
|
+
assert.strictEqual(parsed.txid, txid);
|
|
201
|
+
assert.strictEqual(parsed.amount, 14968);
|
|
202
|
+
assert.strictEqual(xonly.length, 64);
|
|
203
|
+
});
|
|
204
|
+
|
|
192
205
|
it('txo URIs include amount and commit params', () => {
|
|
193
206
|
const txoUri = 'txo:tbtc4:abc123:0?amount=9700&commit=deadbeef';
|
|
194
207
|
const parsed = parseTxoUri(txoUri);
|