@tapforce/pod-bridge-sdk 1.1.17 → 1.2.2

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.
@@ -1,49 +1,29 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SOURCE_CHAIN_BRIDGE_ABI = exports.POD_BRIDGE_ABI = void 0;
3
+ exports.POD_BRIDGE_ABI = exports.SOURCE_CHAIN_BRIDGE_ABI = exports.BRIDGE_ABI = void 0;
4
4
  /**
5
- * ABI for BridgeMintBurn contract on POD Chain
6
- * - Deposits burn tokens
7
- * - Claims use block number verification via precompiles
5
+ * ABI for Bridge contract on Source Chain (ETH/Sepolia)
6
+ * New architecture:
7
+ * - ETH -> Pod: deposit on ETH, auto-claim on Pod (no claim needed)
8
+ * - Pod -> ETH: deposit on Pod, claim on ETH with aggregated validator signatures
9
+ * - Only ERC20 tokens supported (no native ETH - must wrap to WETH)
8
10
  */
9
- exports.POD_BRIDGE_ABI = [
11
+ exports.BRIDGE_ABI = [
10
12
  // Events
11
- "event Deposit(uint256 indexed id, address indexed from, address indexed to, address token, uint256 amount, uint256 timestamp, uint256 blockNumber)",
12
- "event DepositNative(uint256 indexed id, address indexed from, address indexed to, uint256 amount, uint256 timestamp, uint256 blockNumber)",
13
- "event Claim(uint256 indexed id, address indexed claimer, address indexed to, address mirrorToken, address token, uint256 amount, uint256 timestamp)",
14
- "event ClaimNative(uint256 indexed id, address indexed claimer, address indexed to, uint256 amount, uint256 timestamp)",
15
- "event BurnNative(address indexed from, uint256 amount)",
16
- // Deposit functions
17
- "function deposit(address token, uint256 amount, address to) returns (uint256)",
18
- "function depositNative(address to) payable returns (uint256)",
19
- // Claim functions (use block number verification)
20
- "function claim(uint256 id, address token, uint256 blockNumber)",
21
- "function claimNative(uint256 id, uint256 blockNumber)",
13
+ "event Deposit(bytes32 indexed id, address indexed from, address indexed to, address token, uint256 amount)",
14
+ "event Claim(bytes32 indexed id, address indexed to, address token, uint256 amount)",
15
+ // Deposit function (ERC20 only)
16
+ "function deposit(address token, uint256 amount, address to) returns (bytes32)",
17
+ // Claim function with aggregated validator signatures
18
+ "function claim(address token, uint256 amount, address to, uint64 committeeEpoch, bytes aggregatedSignatures, bytes proof)",
22
19
  // View functions
23
20
  "function processedRequests(bytes32) view returns (bool)",
24
- "function bridgeContract() view returns (address)",
25
- "function SOURCE_CHAIN_ID() view returns (uint96)",
26
- "function areRequestsProcessed(uint256[] ids, address[] tokens, uint256[] amounts, address[] tos) view returns (bool[])",
27
- ];
28
- /**
29
- * ABI for BridgeDepositWithdraw contract on Source Chain (e.g., Sepolia)
30
- * - Deposits lock tokens
31
- * - Claims use POD certificates with attestations and merkle proofs
32
- */
33
- exports.SOURCE_CHAIN_BRIDGE_ABI = [
34
- // Events
35
- "event Deposit(uint256 indexed id, address indexed from, address indexed to, address token, uint256 amount, uint256 timestamp, uint256 blockNumber)",
36
- "event DepositNative(uint256 indexed id, address indexed from, address indexed to, uint256 amount, uint256 timestamp, uint256 blockNumber)",
37
- "event Claim(uint256 indexed id, address indexed claimer, address indexed to, address mirrorToken, address token, uint256 amount, uint256 timestamp)",
38
- "event ClaimNative(uint256 indexed id, address indexed claimer, address indexed to, uint256 amount, uint256 timestamp)",
39
- // Deposit functions
40
- "function deposit(address token, uint256 amount, address to) returns (uint256)",
41
- "function depositNative(address to) payable returns (uint256)",
42
- // Claim functions (use PodECDSA.CertifiedLog with certificates)
43
- "function claim(tuple(tuple(address addr, bytes32[] topics, bytes data) log, uint256 logIndex, tuple(tuple(bytes32 receiptRoot, bytes aggregateSignature, uint256[] sortedAttestationTimestamps) certifiedReceipt, bytes32 leaf, tuple(bytes32[] path) proof) certificate) certifiedLog)",
44
- "function claimNative(tuple(tuple(address addr, bytes32[] topics, bytes data) log, uint256 logIndex, tuple(tuple(bytes32 receiptRoot, bytes aggregateSignature, uint256[] sortedAttestationTimestamps) certifiedReceipt, bytes32 leaf, tuple(bytes32[] path) proof) certificate) certifiedLog)",
45
- // View functions
46
- "function processedRequests(bytes32) view returns (bool)",
47
- "function bridgeContract() view returns (address)",
48
- "function areRequestsProcessed(uint256[] ids, address[] tokens, uint256[] amounts, address[] tos) view returns (bool[])",
21
+ "function BRIDGE_CONTRACT() view returns (address)",
22
+ "function DOMAIN_SEPARATOR() view returns (bytes32)",
23
+ "function tokenData(address) view returns (uint256 minAmount, uint256 depositLimit, uint256 claimLimit, tuple(uint256 consumed, uint256 lastUpdated) depositUsage, tuple(uint256 consumed, uint256 lastUpdated) claimUsage, address mirrorToken)",
24
+ "function whitelistedTokens(uint256) view returns (address)",
25
+ "function depositIndex() view returns (uint256)",
49
26
  ];
27
+ // Legacy alias for backwards compatibility
28
+ exports.SOURCE_CHAIN_BRIDGE_ABI = exports.BRIDGE_ABI;
29
+ exports.POD_BRIDGE_ABI = exports.BRIDGE_ABI;
@@ -1,23 +1,11 @@
1
- import { CertifiedLog } from "../types/pod-bridge.types";
2
1
  /**
3
- * Convert FFI CertifiedLog to the TypeScript CertifiedLog format
2
+ * @deprecated This helper is no longer needed in the new bridge architecture.
3
+ *
4
+ * The new bridge uses aggregated validator signatures instead of certified logs.
5
+ * See signature-recovery.helper.ts for the new signature recovery utilities.
6
+ *
7
+ * New architecture:
8
+ * - ETH -> Pod: Auto-claim on Pod (no claim transaction needed)
9
+ * - Pod -> ETH: Claim with aggregated 65-byte ECDSA signatures
4
10
  */
5
- export declare const convertFFICertifiedLog: (ffi: CertifiedLog) => {
6
- log: {
7
- addr: string;
8
- topics: string[];
9
- data: string;
10
- };
11
- logIndex: bigint;
12
- certificate: {
13
- certifiedReceipt: {
14
- receiptRoot: string;
15
- aggregateSignature: string;
16
- sortedAttestationTimestamps: bigint[];
17
- };
18
- leaf: string;
19
- proof: {
20
- path: string[];
21
- };
22
- };
23
- };
11
+ export declare const convertFFICertifiedLog: (_ffi: unknown) => never;
@@ -1,28 +1,19 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.convertFFICertifiedLog = void 0;
4
2
  /**
5
- * Convert FFI CertifiedLog to the TypeScript CertifiedLog format
3
+ * @deprecated This helper is no longer needed in the new bridge architecture.
4
+ *
5
+ * The new bridge uses aggregated validator signatures instead of certified logs.
6
+ * See signature-recovery.helper.ts for the new signature recovery utilities.
7
+ *
8
+ * New architecture:
9
+ * - ETH -> Pod: Auto-claim on Pod (no claim transaction needed)
10
+ * - Pod -> ETH: Claim with aggregated 65-byte ECDSA signatures
6
11
  */
7
- const convertFFICertifiedLog = (ffi) => {
8
- return {
9
- log: {
10
- addr: ffi.log.addr,
11
- topics: ffi.log.topics,
12
- data: ffi.log.data,
13
- },
14
- logIndex: BigInt(ffi.log_index),
15
- certificate: {
16
- certifiedReceipt: {
17
- receiptRoot: ffi.certificate.certified_receipt.receipt_root,
18
- aggregateSignature: ffi.certificate.certified_receipt.aggregate_signature,
19
- sortedAttestationTimestamps: ffi.certificate.certified_receipt.sorted_attestation_timestamps.map(t => BigInt(t)),
20
- },
21
- leaf: ffi.certificate.leaf,
22
- proof: {
23
- path: ffi.certificate.proof.path,
24
- },
25
- },
26
- };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.convertFFICertifiedLog = void 0;
14
+ // Kept for backwards compatibility, but will be removed in future versions
15
+ const convertFFICertifiedLog = (_ffi) => {
16
+ console.warn('[DEPRECATED] convertFFICertifiedLog is deprecated. Use signature-recovery.helper.ts instead.');
17
+ throw new Error('CertifiedLog format is no longer supported. Use ClaimProofData with aggregated signatures.');
27
18
  };
28
19
  exports.convertFFICertifiedLog = convertFFICertifiedLog;
@@ -0,0 +1,161 @@
1
+ import { PodTransactionReceipt } from '../pod-sdk/src/types/responses';
2
+ /**
3
+ * Parse a DER-encoded ECDSA signature to extract r and s components.
4
+ *
5
+ * DER format:
6
+ * 0x30 [total-length] 0x02 [r-length] [r] 0x02 [s-length] [s]
7
+ *
8
+ * Example: 3044022020749ca9...0220292484ed...
9
+ * - 30 = SEQUENCE tag
10
+ * - 44 = total length (68 bytes)
11
+ * - 02 = INTEGER tag for r
12
+ * - 20 = r length (32 bytes)
13
+ * - [32 bytes of r]
14
+ * - 02 = INTEGER tag for s
15
+ * - 20 = s length (32 bytes)
16
+ * - [32 bytes of s]
17
+ *
18
+ * @param derSignature The DER-encoded signature as hex string
19
+ * @returns Object with r and s as 32-byte hex strings (0x prefixed)
20
+ */
21
+ export declare function parseDerSignature(derSignature: string): {
22
+ r: string;
23
+ s: string;
24
+ };
25
+ /**
26
+ * Derive Ethereum address from a public key.
27
+ *
28
+ * @param publicKey The public key (uncompressed 65 bytes with 04 prefix, or 64 bytes x||y)
29
+ * @returns The Ethereum address
30
+ */
31
+ export declare function addressFromPublicKey(publicKey: string): string;
32
+ /**
33
+ * Recover a 65-byte ECDSA signature (r,s,v) from a 64-byte compact signature.
34
+ *
35
+ * Exactly matches the Rust implementation:
36
+ * ```rust
37
+ * pub fn recover_65b_signature(
38
+ * sig: &Signature,
39
+ * msg_hash: [u8; 32],
40
+ * pubkey: &PublicKey,
41
+ * ) -> anyhow::Result<[u8; 65]> {
42
+ * let secp = Secp256k1::new();
43
+ * let msg = Message::from_digest(msg_hash);
44
+ * let sig_bytes = sig.serialize_compact();
45
+ *
46
+ * for recovery_id in [RecoveryId::Zero, RecoveryId::One] {
47
+ * let recoverable_sig = RecoverableSignature::from_compact(&sig_bytes, recovery_id)?;
48
+ * match secp.recover_ecdsa(msg, &recoverable_sig) {
49
+ * Ok(recovered_key) => {
50
+ * if recovered_key == *pubkey {
51
+ * return Ok(recoverable_sig.to_alloy().as_bytes());
52
+ * }
53
+ * }
54
+ * Err(e) => { ... }
55
+ * }
56
+ * }
57
+ * Err(anyhow!("Could not find valid recovery ID for signature"))
58
+ * }
59
+ * ```
60
+ *
61
+ * @param r The r component of the signature (32 bytes hex)
62
+ * @param s The s component of the signature (32 bytes hex)
63
+ * @param msgHash The 32-byte message hash that was signed
64
+ * @param publicKey The expected signer's public key
65
+ * @returns The 65-byte signature (r || s || v) or null if recovery fails
66
+ */
67
+ export declare function recoverSignature65B(r: string, s: string, msgHash: string, publicKey: string): string | null;
68
+ /**
69
+ * Recover multiple 65-byte signatures from concatenated 64-byte signatures.
70
+ *
71
+ * @param aggregatedSig64 Concatenated 64-byte signatures (r || s for each)
72
+ * @param msgHash The message hash that was signed
73
+ * @param publicKeys Array of expected signer public keys in order
74
+ * @returns Concatenated 65-byte signatures or null if any recovery fails
75
+ */
76
+ export declare function recoverAggregatedSignatures65B(aggregatedSig64: string | Uint8Array, msgHash: string, publicKeys: string[]): string | null;
77
+ /**
78
+ * Compute the transaction hash for a bridge deposit that needs to be signed.
79
+ * This matches the depositTxHash function in the Bridge.sol contract.
80
+ *
81
+ * @param domainSeparator The domain separator from the bridge contract
82
+ * @param bridgeContract The address of the bridge contract on the other chain
83
+ * @param token The token address
84
+ * @param amount The amount
85
+ * @param to The recipient address
86
+ * @param proof The proof (deposit TX hash)
87
+ * @returns The transaction hash to be signed
88
+ */
89
+ export declare function computeDepositTxHash(domainSeparator: string, bridgeContract: string, token: string, amount: bigint | string, to: string, proof: string): string;
90
+ /**
91
+ * Extract aggregated 65-byte signatures from Pod transaction receipt.
92
+ *
93
+ * Receipt format:
94
+ * - attested_tx.hash: The transaction hash that was signed
95
+ * - signatures: Object with numeric keys containing DER-encoded signatures
96
+ *
97
+ * @param receipt The Pod transaction receipt
98
+ * @param msgHash Optional override for the message hash (defaults to attested_tx.hash)
99
+ * @param committeePublicKeys Optional array of validator public keys for v-value recovery
100
+ * @returns Concatenated 65-byte signatures (r || s || v for each signature)
101
+ */
102
+ export declare function extractAggregatedSignatures(receipt: PodTransactionReceipt, msgHash?: string, committeePublicKeys?: string[]): string;
103
+ /**
104
+ * Recover a 65-byte signature without knowing the public key.
105
+ * Tries both v values (27 and 28) and returns the first valid recovery.
106
+ *
107
+ * WARNING: This is less secure as we can't verify the signer.
108
+ * Use recoverSignature65B with public key when possible.
109
+ *
110
+ * @param r The r component
111
+ * @param s The s component
112
+ * @param msgHash The message hash
113
+ * @returns The 65-byte signature with v=27 (tries 27 first, then 28)
114
+ */
115
+ export declare function recoverSignatureWithoutPubkey(r: string, s: string, msgHash: string): string;
116
+ /**
117
+ * Recover a 65-byte signature by checking which v-value recovers to a known validator address.
118
+ *
119
+ * @param r The r component
120
+ * @param s The s component
121
+ * @param msgHash The message hash
122
+ * @param validatorAddresses Set of known validator addresses (lowercase)
123
+ * @returns Object with signature and recovered address, or null if no validator match
124
+ */
125
+ export declare function recoverSignatureWithValidators(r: string, s: string, msgHash: string, validatorAddresses: Set<string>): {
126
+ signature: string;
127
+ recoveredAddress: string;
128
+ } | null;
129
+ /**
130
+ * Decompress a compressed secp256k1 public key (33 bytes) to uncompressed format.
131
+ * Compressed format: 02/03 prefix + 32-byte x coordinate
132
+ * Uncompressed format: 04 prefix + 32-byte x + 32-byte y
133
+ *
134
+ * @param compressedPubKey The compressed public key (66 hex chars with 02/03 prefix)
135
+ * @returns The uncompressed public key (130 hex chars with 04 prefix)
136
+ */
137
+ export declare function decompressPublicKey(compressedPubKey: string): string;
138
+ /**
139
+ * Extract aggregated 65-byte signatures using validator public keys for v-value recovery.
140
+ * Committee format: Array of [index, compressed_public_key] tuples
141
+ *
142
+ * @param receipt The Pod transaction receipt
143
+ * @param validators Array of [index, compressedPubKey] tuples from pod_getCommittee
144
+ * @param msgHash Optional override for the message hash
145
+ * @returns Concatenated 65-byte signatures (r || s || v for each signature)
146
+ */
147
+ export declare function extractAggregatedSignaturesWithValidators(receipt: PodTransactionReceipt, validators: [number, string][], msgHash?: string): string;
148
+ /**
149
+ * Extract signature info from Pod receipt for debugging/verification.
150
+ *
151
+ * @param receipt The Pod transaction receipt
152
+ * @param msgHash Optional override for the message hash
153
+ * @returns Array of signature info with recovered 65-byte signatures
154
+ */
155
+ export declare function extractSignatureInfo(receipt: PodTransactionReceipt, msgHash?: string): Array<{
156
+ index: number;
157
+ derSignature: string;
158
+ r: string;
159
+ s: string;
160
+ signature65: string;
161
+ }>;