Skip to content

Commit 0e02260

Browse files
committed
fix: resolve all merge conflict markers from multisig escrow branch
Kept HEAD (master) versions which include requireMultisigAuth security checks in all escrow routes.
1 parent 2973a02 commit 0e02260

File tree

16 files changed

+0
-280
lines changed

16 files changed

+0
-280
lines changed

src/app/api/escrow/multisig/[id]/broadcast/route.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@ import {
1111
broadcastTransaction,
1212
broadcastTransactionSchema,
1313
} from '@/lib/multisig';
14-
<<<<<<< HEAD
1514
import { requireMultisigAuth } from '../../auth';
16-
=======
17-
>>>>>>> feat/multisig-escrow
1815

1916
function getSupabase() {
2017
const url = process.env.NEXT_PUBLIC_SUPABASE_URL;
@@ -28,12 +25,9 @@ export async function POST(
2825
{ params }: { params: Promise<{ id: string }> },
2926
) {
3027
try {
31-
<<<<<<< HEAD
3228
const auth = await requireMultisigAuth(request);
3329
if (!auth.ok) return auth.response;
3430

35-
=======
36-
>>>>>>> feat/multisig-escrow
3731
const { id: escrowId } = await params;
3832
const supabase = getSupabase();
3933
const body = await request.json();
@@ -60,11 +54,8 @@ export async function POST(
6054
return NextResponse.json({
6155
tx_hash: result.tx_hash,
6256
proposal: result.proposal,
63-
<<<<<<< HEAD
6457
broadcasted: result.broadcasted === true,
6558
stage: result.stage!,
66-
=======
67-
>>>>>>> feat/multisig-escrow
6859
});
6960
} catch (error) {
7061
console.error('Failed to broadcast transaction:', error);

src/app/api/escrow/multisig/[id]/dispute/route.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@ import {
1212
disputeMultisigEscrow,
1313
disputeSchema,
1414
} from '@/lib/multisig';
15-
<<<<<<< HEAD
1615
import { requireMultisigAuth } from '../../auth';
17-
=======
18-
>>>>>>> feat/multisig-escrow
1916

2017
function getSupabase() {
2118
const url = process.env.NEXT_PUBLIC_SUPABASE_URL;
@@ -29,12 +26,9 @@ export async function POST(
2926
{ params }: { params: Promise<{ id: string }> },
3027
) {
3128
try {
32-
<<<<<<< HEAD
3329
const auth = await requireMultisigAuth(request);
3430
if (!auth.ok) return auth.response;
3531

36-
=======
37-
>>>>>>> feat/multisig-escrow
3832
const { id: escrowId } = await params;
3933
const supabase = getSupabase();
4034
const body = await request.json();

src/app/api/escrow/multisig/[id]/sign/route.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@ import {
1212
signProposal,
1313
signProposalSchema,
1414
} from '@/lib/multisig';
15-
<<<<<<< HEAD
1615
import { requireMultisigAuth } from '../../auth';
17-
=======
18-
>>>>>>> feat/multisig-escrow
1916

2017
function getSupabase() {
2118
const url = process.env.NEXT_PUBLIC_SUPABASE_URL;
@@ -29,12 +26,9 @@ export async function POST(
2926
{ params }: { params: Promise<{ id: string }> },
3027
) {
3128
try {
32-
<<<<<<< HEAD
3329
const auth = await requireMultisigAuth(request);
3430
if (!auth.ok) return auth.response;
3531

36-
=======
37-
>>>>>>> feat/multisig-escrow
3832
const { id: escrowId } = await params;
3933
const supabase = getSupabase();
4034
const body = await request.json();

src/app/api/escrow/multisig/route.ts

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,13 @@
88

99
import { NextRequest, NextResponse } from 'next/server';
1010
import { createClient } from '@supabase/supabase-js';
11-
<<<<<<< HEAD
12-
=======
13-
import { authenticateRequest } from '@/lib/auth/middleware';
14-
>>>>>>> feat/multisig-escrow
1511
import {
1612
createMultisigEscrow,
1713
getMultisigEscrow,
1814
createMultisigEscrowSchema,
1915
isMultisigEnabled,
2016
} from '@/lib/multisig';
21-
<<<<<<< HEAD
2217
import { requireMultisigAuth } from './auth';
23-
=======
24-
>>>>>>> feat/multisig-escrow
2518

2619
function getSupabase() {
2720
const url = process.env.NEXT_PUBLIC_SUPABASE_URL;
@@ -43,41 +36,10 @@ export async function POST(request: NextRequest) {
4336
);
4437
}
4538

46-
<<<<<<< HEAD
4739
const auth = await requireMultisigAuth(request);
4840
if (!auth.ok) return auth.response;
4941

5042
const supabase = getSupabase();
51-
=======
52-
const supabase = getSupabase();
53-
54-
// Authentication required
55-
const authHeader = request.headers.get('authorization');
56-
const apiKeyHeader = request.headers.get('x-api-key');
57-
58-
if (!authHeader && !apiKeyHeader) {
59-
return NextResponse.json(
60-
{ error: 'Authentication required. Provide Authorization header or X-API-Key.' },
61-
{ status: 401 },
62-
);
63-
}
64-
65-
try {
66-
const authResult = await authenticateRequest(supabase, authHeader || apiKeyHeader);
67-
if (!authResult.success) {
68-
return NextResponse.json(
69-
{ error: 'Invalid or expired authentication' },
70-
{ status: 401 },
71-
);
72-
}
73-
} catch {
74-
return NextResponse.json(
75-
{ error: 'Authentication failed' },
76-
{ status: 401 },
77-
);
78-
}
79-
80-
>>>>>>> feat/multisig-escrow
8143
const body = await request.json();
8244

8345
// Validate input

src/lib/multisig/adapters/btc-multisig.test.ts

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,8 @@
55
*/
66

77
import { describe, it, expect, beforeEach } from 'vitest';
8-
<<<<<<< HEAD
98
import * as bitcoin from 'bitcoinjs-lib';
109
import * as secp256k1 from 'tiny-secp256k1';
11-
=======
12-
>>>>>>> feat/multisig-escrow
1310
import { BtcMultisigAdapter } from './btc-multisig';
1411

1512
// Sample compressed public keys (33 bytes hex)
@@ -142,7 +139,6 @@ describe('BtcMultisigAdapter', () => {
142139
});
143140

144141
describe('verifySignature', () => {
145-
<<<<<<< HEAD
146142
it('should verify a valid secp256k1 signature against tx_hash_to_sign', async () => {
147143
const privkey = Buffer.alloc(32, 1);
148144
const pubkey = Buffer.from(secp256k1.pointFromScalar(privkey, true)!);
@@ -194,26 +190,6 @@ describe('BtcMultisigAdapter', () => {
194190
'BTC',
195191
{ witness_script: 'abcdef', pubkeys: [PUB_KEY_2], tx_hash_to_sign: msgHash },
196192
'aa'.repeat(64),
197-
=======
198-
it('should validate signature format', async () => {
199-
// 64-byte signature (128 hex chars)
200-
const validSig = 'aa'.repeat(64);
201-
const valid = await adapter.verifySignature(
202-
'BTC',
203-
{ witness_script: 'abcdef', pubkeys: [PUB_KEY_1] },
204-
validSig,
205-
PUB_KEY_1,
206-
);
207-
expect(valid).toBe(true);
208-
});
209-
210-
it('should reject unknown pubkey', async () => {
211-
const validSig = 'aa'.repeat(64);
212-
const valid = await adapter.verifySignature(
213-
'BTC',
214-
{ witness_script: 'abcdef', pubkeys: [PUB_KEY_2] },
215-
validSig,
216-
>>>>>>> feat/multisig-escrow
217193
PUB_KEY_1, // not in pubkeys list
218194
);
219195
expect(valid).toBe(false);

src/lib/multisig/adapters/btc-multisig.ts

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@
1919
*/
2020

2121
import * as bitcoin from 'bitcoinjs-lib';
22-
<<<<<<< HEAD
2322
import * as secp256k1 from 'tiny-secp256k1';
24-
=======
25-
>>>>>>> feat/multisig-escrow
2623
import type { ChainAdapter } from './interface';
2724
import type {
2825
MultisigChain,
@@ -245,26 +242,14 @@ export class BtcMultisigAdapter implements ChainAdapter {
245242
): Promise<boolean> {
246243
try {
247244
const pubkeyBuf = parsePubkey(signerPubkey);
248-
<<<<<<< HEAD
249245
const txHash = txData.tx_hash_to_sign as string | undefined;
250246

251247
// Check that the pubkey is one of the expected participants when provided.
252-
=======
253-
const sigBuf = Buffer.from(signature, 'hex');
254-
255-
// Verify the hash matches the pubkey and signature
256-
// In production, this would verify the actual PSBT input signature
257-
const witnessScript = txData.witness_script as string;
258-
if (!witnessScript) return false;
259-
260-
// Check that the pubkey is one of the multisig participants
261-
>>>>>>> feat/multisig-escrow
262248
const pubkeys = txData.pubkeys as string[] | undefined;
263249
if (pubkeys && !pubkeys.includes(signerPubkey)) {
264250
return false;
265251
}
266252

267-
<<<<<<< HEAD
268253
// tx_hash_to_sign is required for cryptographic verification.
269254
// Fail closed when missing/malformed.
270255
if (!txHash || txHash.length !== 64) {
@@ -289,10 +274,6 @@ export class BtcMultisigAdapter implements ChainAdapter {
289274
if (sigBuf.length !== 64) return false;
290275
return secp256k1.verify(msgHash, pubkeyBuf, sigBuf);
291276
}
292-
=======
293-
// Basic signature format validation (DER-encoded or Schnorr)
294-
return sigBuf.length >= 64 && pubkeyBuf.length >= 33;
295-
>>>>>>> feat/multisig-escrow
296277
} catch {
297278
return false;
298279
}
@@ -312,11 +293,7 @@ export class BtcMultisigAdapter implements ChainAdapter {
312293
}
313294

314295
if (signatures.length < 2) {
315-
<<<<<<< HEAD
316296
return { tx_hash: '', success: false, broadcasted: false };
317-
=======
318-
return { tx_hash: '', success: false };
319-
>>>>>>> feat/multisig-escrow
320297
}
321298

322299
// In production:
@@ -334,10 +311,7 @@ export class BtcMultisigAdapter implements ChainAdapter {
334311
return {
335312
tx_hash: txid,
336313
success: true,
337-
<<<<<<< HEAD
338314
broadcasted: false,
339-
=======
340-
>>>>>>> feat/multisig-escrow
341315
};
342316
}
343317
}

src/lib/multisig/adapters/evm-safe.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -214,19 +214,11 @@ export class EvmSafeAdapter implements ChainAdapter {
214214
ethers.ZeroAddress, // paymentReceiver
215215
]);
216216

217-
<<<<<<< HEAD
218217
// Generate deterministic salt from stable multisig parameters
219218
const saltNonce = BigInt(ethers.keccak256(
220219
ethers.solidityPacked(
221220
['address', 'address', 'address', 'uint256'],
222221
[owners[0], owners[1], owners[2], threshold],
223-
=======
224-
// Generate deterministic salt from participants
225-
const saltNonce = BigInt(ethers.keccak256(
226-
ethers.solidityPacked(
227-
['address', 'address', 'address', 'uint256'],
228-
[owners[0], owners[1], owners[2], Date.now()],
229-
>>>>>>> feat/multisig-escrow
230222
),
231223
));
232224

@@ -407,19 +399,12 @@ export class EvmSafeAdapter implements ChainAdapter {
407399
packedSignatures,
408400
]);
409401

410-
<<<<<<< HEAD
411402
// Return a deterministic id for the prepared payload.
412403
// NOTE: this does NOT broadcast to chain yet.
413404
return {
414405
tx_hash: ethers.keccak256(execData),
415406
success: true,
416407
broadcasted: false,
417-
=======
418-
// Return the prepared transaction for relay/execution
419-
return {
420-
tx_hash: ethers.keccak256(execData),
421-
success: true,
422-
>>>>>>> feat/multisig-escrow
423408
};
424409
}
425410
}

src/lib/multisig/adapters/solana-multisig.test.ts

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,8 @@
55
*/
66

77
import { describe, it, expect, beforeEach } from 'vitest';
8-
<<<<<<< HEAD
98
import nacl from 'tweetnacl';
109
import bs58 from 'bs58';
11-
=======
12-
>>>>>>> feat/multisig-escrow
1310
import { SolanaMultisigAdapter } from './solana-multisig';
1411

1512
// Valid Solana base58 public keys (system program and well-known program addresses)
@@ -108,7 +105,6 @@ describe('SolanaMultisigAdapter', () => {
108105
});
109106

110107
describe('verifySignature', () => {
111-
<<<<<<< HEAD
112108
it('should verify a valid Ed25519 signature against tx_hash_to_sign', async () => {
113109
const keypair = nacl.sign.keyPair();
114110
const signerPubkey = bs58.encode(Buffer.from(keypair.publicKey));
@@ -153,26 +149,6 @@ describe('SolanaMultisigAdapter', () => {
153149
{ members: [SOL_PK_2], tx_hash_to_sign: msgHash.toString('hex') },
154150
Buffer.from(signature).toString('hex'),
155151
signerPubkey,
156-
=======
157-
it('should accept valid Ed25519 signature format (64 bytes)', async () => {
158-
const sig64bytes = 'aa'.repeat(64); // 64 bytes as hex
159-
const valid = await adapter.verifySignature(
160-
'SOL',
161-
{ members: [SOL_PK_1] },
162-
sig64bytes,
163-
SOL_PK_1,
164-
);
165-
expect(valid).toBe(true);
166-
});
167-
168-
it('should reject signer not in members list', async () => {
169-
const sig64bytes = 'aa'.repeat(64);
170-
const valid = await adapter.verifySignature(
171-
'SOL',
172-
{ members: [SOL_PK_2] },
173-
sig64bytes,
174-
SOL_PK_1, // not in members
175-
>>>>>>> feat/multisig-escrow
176152
);
177153
expect(valid).toBe(false);
178154
});

0 commit comments

Comments
 (0)