|
1 | | -import { |
2 | | - Signature, |
3 | | - TransferableOutput, |
4 | | - TransferOutput, |
5 | | - TypeSymbols, |
6 | | - Id, |
7 | | - Credential, |
8 | | - utils as FlareUtils, |
9 | | -} from '@flarenetwork/flarejs'; |
| 1 | +import { Signature, TransferableOutput, TransferOutput, TypeSymbols, Id } from '@flarenetwork/flarejs'; |
10 | 2 | import { |
11 | 3 | BaseUtils, |
12 | 4 | Entry, |
@@ -397,158 +389,6 @@ export class Utils implements BaseUtils { |
397 | 389 | return new Id(Buffer.from(value, 'hex')); |
398 | 390 | } |
399 | 391 |
|
400 | | - /** |
401 | | - * Extract credentials from raw transaction bytes. |
402 | | - * Signed transactions have credentials appended after the transaction body. |
403 | | - * This function handles both checking for credentials and extracting them. |
404 | | - * |
405 | | - * @param rawBytes - The full raw transaction bytes |
406 | | - * @param tx - The parsed transaction (must have toBytes method) |
407 | | - * @param vmType - The VM type ('EVM' or 'PVM') to get the correct codec |
408 | | - * @returns Object with hasCredentials flag and credentials array |
409 | | - */ |
410 | | - extractCredentialsFromRawBytes( |
411 | | - rawBytes: Buffer, |
412 | | - tx: { toBytes(codec: unknown): Uint8Array }, |
413 | | - vmType: 'EVM' | 'PVM' = 'EVM' |
414 | | - ): { hasCredentials: boolean; credentials: Credential[] } { |
415 | | - try { |
416 | | - // Get the size of the transaction without credentials using the default codec |
417 | | - const codec = FlareUtils.getManagerForVM(vmType).getDefaultCodec(); |
418 | | - const txBytes = tx.toBytes(codec); |
419 | | - const txSize = txBytes.length; |
420 | | - |
421 | | - // If raw bytes are not longer than tx bytes, there are no credentials |
422 | | - if (rawBytes.length <= txSize) { |
423 | | - return { hasCredentials: false, credentials: [] }; |
424 | | - } |
425 | | - |
426 | | - // Extract credential bytes (everything after the transaction) |
427 | | - const credentialBytes = rawBytes.slice(txSize); |
428 | | - |
429 | | - // Parse credentials |
430 | | - // Format: [num_credentials: 4 bytes] [credentials...] |
431 | | - if (credentialBytes.length < 4) { |
432 | | - return { hasCredentials: false, credentials: [] }; |
433 | | - } |
434 | | - |
435 | | - const numCredentials = credentialBytes.readUInt32BE(0); |
436 | | - |
437 | | - // Check if there are credentials in raw bytes (for hasCredentials flag) |
438 | | - const hasCredentials = numCredentials > 0; |
439 | | - |
440 | | - if (numCredentials === 0) { |
441 | | - return { hasCredentials: false, credentials: [] }; |
442 | | - } |
443 | | - |
444 | | - const credentials: Credential[] = []; |
445 | | - let offset = 4; |
446 | | - |
447 | | - for (let i = 0; i < numCredentials; i++) { |
448 | | - if (offset + 8 > credentialBytes.length) { |
449 | | - break; |
450 | | - } |
451 | | - |
452 | | - // Read type ID (4 bytes) - Type ID 9 = secp256k1 credential |
453 | | - const typeId = credentialBytes.readUInt32BE(offset); |
454 | | - offset += 4; |
455 | | - |
456 | | - // Validate credential type (9 = secp256k1) |
457 | | - if (typeId !== 9) { |
458 | | - continue; // Skip unsupported credential types |
459 | | - } |
460 | | - |
461 | | - // Read number of signatures (4 bytes) |
462 | | - const numSigs = credentialBytes.readUInt32BE(offset); |
463 | | - offset += 4; |
464 | | - |
465 | | - // Parse all signatures for this credential |
466 | | - const signatures: Signature[] = []; |
467 | | - for (let j = 0; j < numSigs; j++) { |
468 | | - if (offset + 65 > credentialBytes.length) { |
469 | | - break; |
470 | | - } |
471 | | - // Each signature is 65 bytes (64 bytes signature + 1 byte recovery) |
472 | | - const sigBytes = Buffer.from(credentialBytes.slice(offset, offset + 65)); |
473 | | - signatures.push(new Signature(sigBytes)); |
474 | | - offset += 65; |
475 | | - } |
476 | | - |
477 | | - // Create credential with the parsed signatures |
478 | | - if (signatures.length > 0) { |
479 | | - credentials.push(new Credential(signatures)); |
480 | | - } |
481 | | - } |
482 | | - |
483 | | - return { hasCredentials, credentials }; |
484 | | - } catch (e) { |
485 | | - // If parsing fails, return no credentials |
486 | | - return { hasCredentials: false, credentials: [] }; |
487 | | - } |
488 | | - } |
489 | | - |
490 | | - /** |
491 | | - * Parse credentials from raw bytes at a specific offset |
492 | | - * This is useful when the standard extraction fails due to serialization differences |
493 | | - * @param rawBytes Raw transaction bytes including credentials |
494 | | - * @param offset Byte offset where credentials start |
495 | | - * @returns Array of parsed credentials |
496 | | - */ |
497 | | - parseCredentialsAtOffset(rawBytes: Buffer, offset: number): Credential[] { |
498 | | - try { |
499 | | - if (rawBytes.length <= offset + 4) { |
500 | | - return []; |
501 | | - } |
502 | | - |
503 | | - const credentialBytes = rawBytes.slice(offset); |
504 | | - const numCredentials = credentialBytes.readUInt32BE(0); |
505 | | - |
506 | | - if (numCredentials === 0) { |
507 | | - return []; |
508 | | - } |
509 | | - |
510 | | - const credentials: Credential[] = []; |
511 | | - let pos = 4; |
512 | | - |
513 | | - for (let i = 0; i < numCredentials; i++) { |
514 | | - if (pos + 8 > credentialBytes.length) { |
515 | | - break; |
516 | | - } |
517 | | - |
518 | | - // Read type ID (4 bytes) - Type ID 9 = secp256k1 credential |
519 | | - const typeId = credentialBytes.readUInt32BE(pos); |
520 | | - pos += 4; |
521 | | - |
522 | | - if (typeId !== 9) { |
523 | | - continue; |
524 | | - } |
525 | | - |
526 | | - // Read number of signatures (4 bytes) |
527 | | - const numSigs = credentialBytes.readUInt32BE(pos); |
528 | | - pos += 4; |
529 | | - |
530 | | - // Parse all signatures for this credential |
531 | | - const signatures: Signature[] = []; |
532 | | - for (let j = 0; j < numSigs; j++) { |
533 | | - if (pos + 65 > credentialBytes.length) { |
534 | | - break; |
535 | | - } |
536 | | - const sigBytes = Buffer.from(credentialBytes.slice(pos, pos + 65)); |
537 | | - signatures.push(new Signature(sigBytes)); |
538 | | - pos += 65; |
539 | | - } |
540 | | - |
541 | | - if (signatures.length > 0) { |
542 | | - credentials.push(new Credential(signatures)); |
543 | | - } |
544 | | - } |
545 | | - |
546 | | - return credentials; |
547 | | - } catch { |
548 | | - return []; |
549 | | - } |
550 | | - } |
551 | | - |
552 | 392 | /** |
553 | 393 | * FlareJS wrapper to recover signature |
554 | 394 | * @param network |
@@ -580,45 +420,6 @@ export class Utils implements BaseUtils { |
580 | 420 | throw new Error(`Failed to recover signature: ${error}`); |
581 | 421 | } |
582 | 422 | } |
583 | | - |
584 | | - /** |
585 | | - * Find and parse credentials by searching for the credential marker pattern in raw bytes. |
586 | | - * This is a more robust method that doesn't rely on calculated offsets. |
587 | | - * Credential format: [numCreds: 4 bytes][typeId: 4 bytes = 0x00000009][numSigs: 4 bytes][signatures...] |
588 | | - * @param rawBytes Raw transaction bytes including credentials |
589 | | - * @returns Array of parsed credentials |
590 | | - */ |
591 | | - findAndParseCredentials(rawBytes: Buffer): Credential[] { |
592 | | - try { |
593 | | - // Search for the pattern: 00000001 00000009 (1 credential, typeId 9) |
594 | | - // or more generally: xxxxxxxx 00000009 (any numCreds, typeId 9) |
595 | | - // TypeId 9 = secp256k1 credential |
596 | | - const typeIdPattern = Buffer.from([0x00, 0x00, 0x00, 0x09]); |
597 | | - |
598 | | - for (let i = 4; i < rawBytes.length - 12; i++) { |
599 | | - // Check if we found typeId 9 at position i |
600 | | - if (rawBytes.slice(i, i + 4).equals(typeIdPattern)) { |
601 | | - // Check if the 4 bytes before could be numCredentials (should be small positive number) |
602 | | - const numCredentials = rawBytes.readUInt32BE(i - 4); |
603 | | - |
604 | | - // Sanity check: numCredentials should be reasonable (1-10) |
605 | | - if (numCredentials > 0 && numCredentials <= 10) { |
606 | | - // Try to parse credentials from position i - 4 |
607 | | - const credResult = this.parseCredentialsAtOffset(rawBytes, i - 4); |
608 | | - |
609 | | - // Verify we got the expected number of credentials |
610 | | - if (credResult.length === numCredentials) { |
611 | | - return credResult; |
612 | | - } |
613 | | - } |
614 | | - } |
615 | | - } |
616 | | - |
617 | | - return []; |
618 | | - } catch { |
619 | | - return []; |
620 | | - } |
621 | | - } |
622 | 423 | } |
623 | 424 |
|
624 | 425 | const utils = new Utils(); |
|
0 commit comments