@tapforce/pod-bridge-sdk 1.1.10 → 1.1.12
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/dist/clients/action/pod-to-source-chain-client.d.ts +4 -4
- package/dist/clients/action/pod-to-source-chain-client.js +4 -4
- package/dist/clients/tracker/client.d.ts +1 -8
- package/dist/clients/tracker/client.js +1 -10
- package/dist/clients/tracker/pod-tracker.service.d.ts +1 -8
- package/dist/clients/tracker/pod-tracker.service.js +5 -72
- package/dist/clients/tracker/source-chain-tracker.service.js +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/libs/helpers/convert-certified-log.helper.d.ts +23 -0
- package/dist/libs/helpers/convert-certified-log.helper.js +28 -0
- package/dist/libs/pod-sdk/src/provider/provider-builder.d.ts +26 -0
- package/dist/libs/pod-sdk/src/provider/provider-builder.js +67 -0
- package/dist/libs/pod-sdk/src/types/requests.d.ts +5 -0
- package/dist/libs/pod-sdk/src/types/requests.js +2 -0
- package/dist/libs/pod-sdk/src/types/responses.d.ts +85 -0
- package/dist/libs/pod-sdk/src/types/responses.js +2 -0
- package/dist/libs/types/pod-bridge.types.d.ts +7 -47
- package/package.json +1 -1
- package/dist/libs/helpers/certificate.helper.d.ts +0 -26
- package/dist/libs/helpers/certificate.helper.js +0 -55
- package/dist/libs/helpers/index.d.ts +0 -2
- package/dist/libs/helpers/index.js +0 -7
- package/dist/libs/helpers/merkle.helper.d.ts +0 -9
- package/dist/libs/helpers/merkle.helper.js +0 -48
|
@@ -30,8 +30,8 @@ export declare class PodToSourceChainActionClient {
|
|
|
30
30
|
from?: string;
|
|
31
31
|
}): UnsignedTransaction;
|
|
32
32
|
/**
|
|
33
|
-
* Create unsigned transaction for claiming tokens on
|
|
34
|
-
* Used for claiming on
|
|
33
|
+
* Create unsigned transaction for claiming ERC20 tokens on Source Chain (BridgeDepositWithdraw - with certificates)
|
|
34
|
+
* Used for claiming ERC20 tokens on Source Chain from POD deposits
|
|
35
35
|
* @param args.certifiedLog Certified log from POD certificate system
|
|
36
36
|
* @param args.from Optional sender address
|
|
37
37
|
* @returns Unsigned transaction template with encoded claim call
|
|
@@ -41,8 +41,8 @@ export declare class PodToSourceChainActionClient {
|
|
|
41
41
|
from?: string;
|
|
42
42
|
}): UnsignedTransaction;
|
|
43
43
|
/**
|
|
44
|
-
* Create unsigned transaction for claiming native tokens on
|
|
45
|
-
* Used for claiming native tokens on
|
|
44
|
+
* Create unsigned transaction for claiming native tokens on Source Chain (BridgeDepositWithdraw - with certificates)
|
|
45
|
+
* Used for claiming native tokens on Source Chain from POD deposits
|
|
46
46
|
* @param args.certifiedLog Certified log from POD certificate system
|
|
47
47
|
* @param args.from Optional sender address
|
|
48
48
|
* @returns Unsigned transaction template with encoded claimNative call
|
|
@@ -46,8 +46,8 @@ class PodToSourceChainActionClient {
|
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
49
|
-
* Create unsigned transaction for claiming tokens on
|
|
50
|
-
* Used for claiming on
|
|
49
|
+
* Create unsigned transaction for claiming ERC20 tokens on Source Chain (BridgeDepositWithdraw - with certificates)
|
|
50
|
+
* Used for claiming ERC20 tokens on Source Chain from POD deposits
|
|
51
51
|
* @param args.certifiedLog Certified log from POD certificate system
|
|
52
52
|
* @param args.from Optional sender address
|
|
53
53
|
* @returns Unsigned transaction template with encoded claim call
|
|
@@ -62,8 +62,8 @@ class PodToSourceChainActionClient {
|
|
|
62
62
|
};
|
|
63
63
|
}
|
|
64
64
|
/**
|
|
65
|
-
* Create unsigned transaction for claiming native tokens on
|
|
66
|
-
* Used for claiming native tokens on
|
|
65
|
+
* Create unsigned transaction for claiming native tokens on Source Chain (BridgeDepositWithdraw - with certificates)
|
|
66
|
+
* Used for claiming native tokens on Source Chain from POD deposits
|
|
67
67
|
* @param args.certifiedLog Certified log from POD certificate system
|
|
68
68
|
* @param args.from Optional sender address
|
|
69
69
|
* @returns Unsigned transaction template with encoded claimNative call
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PodBridgeConfig, BridgeRequest, BridgeRequestWithType
|
|
1
|
+
import { PodBridgeConfig, BridgeRequest, BridgeRequestWithType } from "../../libs/types/pod-bridge.types";
|
|
2
2
|
/**
|
|
3
3
|
* PodBridgeTrackerClient - Main orchestrator for bridge tracking
|
|
4
4
|
*
|
|
@@ -57,11 +57,4 @@ export declare class PodBridgeTrackerClient {
|
|
|
57
57
|
* @returns Array of boolean values
|
|
58
58
|
*/
|
|
59
59
|
areRequestsProcessed(deposits: BridgeRequest[]): Promise<boolean[]>;
|
|
60
|
-
/**
|
|
61
|
-
* Get certified log for a deposit transaction from POD
|
|
62
|
-
* This is required to claim tokens on Source Chain from POD deposits
|
|
63
|
-
* @param txHash Transaction hash of the deposit on POD
|
|
64
|
-
* @returns Certified log with attestations and merkle proof
|
|
65
|
-
*/
|
|
66
|
-
getDepositCertifiedLog(txHash: string): Promise<CertifiedLog>;
|
|
67
60
|
}
|
|
@@ -92,7 +92,7 @@ class PodBridgeTrackerClient {
|
|
|
92
92
|
else {
|
|
93
93
|
// If deposit appears in both (sent to self), mark as SENT
|
|
94
94
|
const existing = uniqueDeposits.get(key);
|
|
95
|
-
if (existing.deposit.
|
|
95
|
+
if (existing.deposit.depositor === address && existing.deposit.destination === address) {
|
|
96
96
|
uniqueDeposits.set(key, { ...existing, type: pod_bridge_types_1.DepositType.SENT });
|
|
97
97
|
}
|
|
98
98
|
}
|
|
@@ -204,14 +204,5 @@ class PodBridgeTrackerClient {
|
|
|
204
204
|
const allClaims = new Map([...podClaims, ...sourceChainClaims]);
|
|
205
205
|
return deposits.map(d => allClaims.has(d.requestId));
|
|
206
206
|
}
|
|
207
|
-
/**
|
|
208
|
-
* Get certified log for a deposit transaction from POD
|
|
209
|
-
* This is required to claim tokens on Source Chain from POD deposits
|
|
210
|
-
* @param txHash Transaction hash of the deposit on POD
|
|
211
|
-
* @returns Certified log with attestations and merkle proof
|
|
212
|
-
*/
|
|
213
|
-
async getDepositCertifiedLog(txHash) {
|
|
214
|
-
return this.podTracker.getDepositCertifiedLog(txHash);
|
|
215
|
-
}
|
|
216
207
|
}
|
|
217
208
|
exports.PodBridgeTrackerClient = PodBridgeTrackerClient;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BridgeRequest, BridgeChain, PodBridgeChainConfig
|
|
1
|
+
import { BridgeRequest, BridgeChain, PodBridgeChainConfig } from '../../libs/types/pod-bridge.types';
|
|
2
2
|
/**
|
|
3
3
|
* PodTrackerService - Handles tracking on the POD Chain
|
|
4
4
|
*
|
|
@@ -49,11 +49,4 @@ export declare class PodTrackerService {
|
|
|
49
49
|
chainId: number;
|
|
50
50
|
blockNumber: number;
|
|
51
51
|
}>>;
|
|
52
|
-
/**
|
|
53
|
-
* Get certified log for a deposit transaction from POD
|
|
54
|
-
* This is required to claim tokens on Source Chain from POD deposits
|
|
55
|
-
* @param txHash Transaction hash of the deposit on POD
|
|
56
|
-
* @returns Certified log with attestations and merkle proof
|
|
57
|
-
*/
|
|
58
|
-
getDepositCertifiedLog(txHash: string): Promise<CertifiedLog>;
|
|
59
52
|
}
|
|
@@ -4,8 +4,7 @@ exports.PodTrackerService = void 0;
|
|
|
4
4
|
const ethers_1 = require("ethers");
|
|
5
5
|
const pod_bridge_types_1 = require("../../libs/types/pod-bridge.types");
|
|
6
6
|
const bridge_abi_1 = require("../../libs/abi/bridge.abi");
|
|
7
|
-
const
|
|
8
|
-
const merkle_helper_1 = require("../../libs/helpers/merkle.helper");
|
|
7
|
+
const provider_builder_1 = require("../../libs/pod-sdk/src/provider/provider-builder");
|
|
9
8
|
/**
|
|
10
9
|
* PodTrackerService - Handles tracking on the POD Chain
|
|
11
10
|
*
|
|
@@ -21,7 +20,7 @@ class PodTrackerService {
|
|
|
21
20
|
constructor(config) {
|
|
22
21
|
this.config = config;
|
|
23
22
|
this.chainId = null;
|
|
24
|
-
this.provider = new
|
|
23
|
+
this.provider = new provider_builder_1.PodProvider(config.rpcUrl);
|
|
25
24
|
this.bridge = new ethers_1.Contract(config.contractAddress, bridge_abi_1.POD_BRIDGE_ABI, this.provider);
|
|
26
25
|
this.iface = new ethers_1.Interface(bridge_abi_1.POD_BRIDGE_ABI);
|
|
27
26
|
this.initChainId();
|
|
@@ -83,8 +82,8 @@ class PodTrackerService {
|
|
|
83
82
|
deposit: {
|
|
84
83
|
chain: pod_bridge_types_1.BridgeChain.POD,
|
|
85
84
|
txHash: log.transactionHash,
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
depositor: parsed.args.from,
|
|
86
|
+
destination: parsed.args.to,
|
|
88
87
|
token: isNative ? ethers_1.ethers.ZeroAddress : parsed.args.token,
|
|
89
88
|
amount: parsed.args.amount.toString(),
|
|
90
89
|
chainId: this.chainId,
|
|
@@ -107,7 +106,7 @@ class PodTrackerService {
|
|
|
107
106
|
*/
|
|
108
107
|
async getClaimEvents(deposits) {
|
|
109
108
|
await this.ensureChainId();
|
|
110
|
-
const uniqueRecipients = [...new Set(deposits.map(d => d.deposit.
|
|
109
|
+
const uniqueRecipients = [...new Set(deposits.map(d => d.deposit.destination))];
|
|
111
110
|
const allClaimLogs = [];
|
|
112
111
|
const allClaimNativeLogs = [];
|
|
113
112
|
for (const recipient of uniqueRecipients) {
|
|
@@ -140,71 +139,5 @@ class PodTrackerService {
|
|
|
140
139
|
}
|
|
141
140
|
return claimedMap;
|
|
142
141
|
}
|
|
143
|
-
/**
|
|
144
|
-
* Get certified log for a deposit transaction from POD
|
|
145
|
-
* This is required to claim tokens on Source Chain from POD deposits
|
|
146
|
-
* @param txHash Transaction hash of the deposit on POD
|
|
147
|
-
* @returns Certified log with attestations and merkle proof
|
|
148
|
-
*/
|
|
149
|
-
async getDepositCertifiedLog(txHash) {
|
|
150
|
-
var _a, _b;
|
|
151
|
-
// Fetch the transaction receipt with POD metadata
|
|
152
|
-
const receipt = await this.provider.getTransactionReceipt(txHash);
|
|
153
|
-
if (!receipt) {
|
|
154
|
-
throw new Error(`Transaction receipt not found for hash: ${txHash}`);
|
|
155
|
-
}
|
|
156
|
-
if (!((_a = receipt === null || receipt === void 0 ? void 0 : receipt.pod_metadata) === null || _a === void 0 ? void 0 : _a.attestations)) {
|
|
157
|
-
throw new Error(`Transaction ${txHash} does not have POD metadata with attestations`);
|
|
158
|
-
}
|
|
159
|
-
if (!((_b = receipt === null || receipt === void 0 ? void 0 : receipt.logs) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
160
|
-
throw new Error(`No logs found in transaction ${txHash}`);
|
|
161
|
-
}
|
|
162
|
-
// Find the Deposit or DepositNative event
|
|
163
|
-
const depositLog = receipt.logs.find(log => {
|
|
164
|
-
const topics = log.topics;
|
|
165
|
-
if (topics.length === 0)
|
|
166
|
-
return false;
|
|
167
|
-
const depositEventSig = ethers_1.ethers.id('Deposit(uint256,address,address,address,uint256,uint256,uint256)');
|
|
168
|
-
const depositNativeEventSig = ethers_1.ethers.id('DepositNative(uint256,address,address,uint256,uint256,uint256)');
|
|
169
|
-
return topics[0] === depositEventSig || topics[0] === depositNativeEventSig;
|
|
170
|
-
});
|
|
171
|
-
if (!depositLog) {
|
|
172
|
-
throw new Error(`No Deposit or DepositNative event found in transaction ${txHash}`);
|
|
173
|
-
}
|
|
174
|
-
// Compute receipt root (hash of receipt without pod_metadata)
|
|
175
|
-
const receiptRoot = certificate_helper_1.CertificateHelper.computeReceiptRoot(receipt);
|
|
176
|
-
// Generate aggregate signature from attestations
|
|
177
|
-
const sortedAttestations = [...receipt.pod_metadata.attestations].sort((a, b) => a.timestamp - b.timestamp);
|
|
178
|
-
const aggregateSignature = certificate_helper_1.CertificateHelper.aggregateSignatures(sortedAttestations);
|
|
179
|
-
const sortedTimestamps = sortedAttestations.map(att => BigInt(Math.floor(att.timestamp / 1000000))); // Convert microseconds to seconds
|
|
180
|
-
// Generate merkle proof for the log
|
|
181
|
-
const proof = merkle_helper_1.MerkleHelper.generateMerkleProof(receipt.logs, parseInt(depositLog.logIndex));
|
|
182
|
-
// Compute leaf hash
|
|
183
|
-
const logHash = certificate_helper_1.CertificateHelper.hashLog({
|
|
184
|
-
addr: depositLog.address,
|
|
185
|
-
topics: depositLog.topics,
|
|
186
|
-
data: depositLog.data
|
|
187
|
-
});
|
|
188
|
-
const leaf = certificate_helper_1.CertificateHelper.hashLeaf(`log_hashes[${depositLog.logIndex}]`, logHash);
|
|
189
|
-
return {
|
|
190
|
-
log: {
|
|
191
|
-
addr: depositLog.address,
|
|
192
|
-
topics: depositLog.topics,
|
|
193
|
-
data: depositLog.data
|
|
194
|
-
},
|
|
195
|
-
logIndex: BigInt(depositLog.logIndex),
|
|
196
|
-
certificate: {
|
|
197
|
-
leaf,
|
|
198
|
-
certifiedReceipt: {
|
|
199
|
-
receiptRoot,
|
|
200
|
-
aggregateSignature,
|
|
201
|
-
sortedAttestationTimestamps: sortedTimestamps
|
|
202
|
-
},
|
|
203
|
-
proof: {
|
|
204
|
-
path: proof
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
142
|
}
|
|
210
143
|
exports.PodTrackerService = PodTrackerService;
|
|
@@ -77,8 +77,8 @@ class SourceChainTrackerService {
|
|
|
77
77
|
deposit: {
|
|
78
78
|
chain: pod_bridge_types_1.BridgeChain.SOURCE_CHAIN,
|
|
79
79
|
txHash: log.transactionHash,
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
depositor: parsed.args.from,
|
|
81
|
+
destination: parsed.args.to,
|
|
82
82
|
token: isNative ? ethers_1.ethers.ZeroAddress : parsed.args.token,
|
|
83
83
|
amount: parsed.args.amount.toString(),
|
|
84
84
|
chainId: this.chainId,
|
|
@@ -101,7 +101,7 @@ class SourceChainTrackerService {
|
|
|
101
101
|
* @returns Map of requestId to claim information
|
|
102
102
|
*/
|
|
103
103
|
async getClaimEvents(deposits) {
|
|
104
|
-
const uniqueRecipients = [...new Set(deposits.map(d => d.deposit.
|
|
104
|
+
const uniqueRecipients = [...new Set(deposits.map(d => d.deposit.destination))];
|
|
105
105
|
const allClaimLogs = [];
|
|
106
106
|
const allClaimNativeLogs = [];
|
|
107
107
|
for (const recipient of uniqueRecipients) {
|
package/dist/index.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ export { PodToSourceChainActionClient } from './clients/action/pod-to-source-cha
|
|
|
2
2
|
export { SourceChainToPodActionClient } from './clients/action/source-chain-to-pod-client';
|
|
3
3
|
export { PodBridgeTrackerClient } from './clients/tracker/client';
|
|
4
4
|
export { POD_BRIDGE_ABI } from './libs/abi/bridge.abi';
|
|
5
|
-
export { PodBridgeConfig, BridgeRequest, BridgeRequestWithType, BridgeChain, DepositType, UnsignedTransaction, CertifiedLog,
|
|
5
|
+
export { PodBridgeConfig, BridgeRequest, BridgeRequestWithType, BridgeChain, DepositType, UnsignedTransaction, CertifiedLog, PodBridgeActionsClientConfig, PodBridgeChainConfig, } from './libs/types/pod-bridge.types';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { CertifiedLog } from "../types/pod-bridge.types";
|
|
2
|
+
/**
|
|
3
|
+
* Convert FFI CertifiedLog to the TypeScript CertifiedLog format
|
|
4
|
+
*/
|
|
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
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convertFFICertifiedLog = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Convert FFI CertifiedLog to the TypeScript CertifiedLog format
|
|
6
|
+
*/
|
|
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
|
+
};
|
|
27
|
+
};
|
|
28
|
+
exports.convertFFICertifiedLog = convertFFICertifiedLog;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
import { PodCommittee, PodMetrics, PodPaginatedResult, PodTransactionReceipt, PodTransactionReceiptResponse, PodTransactionResponse } from '../types/responses';
|
|
3
|
+
export declare class PodProvider extends ethers.JsonRpcProvider {
|
|
4
|
+
getCommittee(): Promise<PodCommittee>;
|
|
5
|
+
getListReceipts(params: {
|
|
6
|
+
address?: string;
|
|
7
|
+
since: bigint | number | string;
|
|
8
|
+
pagination?: {
|
|
9
|
+
cursor?: string;
|
|
10
|
+
limit?: number;
|
|
11
|
+
newest_first?: boolean;
|
|
12
|
+
};
|
|
13
|
+
}): Promise<PodPaginatedResult<PodTransactionReceipt>>;
|
|
14
|
+
getMetrics(): Promise<PodMetrics>;
|
|
15
|
+
getPastPerfectTime(): Promise<bigint>;
|
|
16
|
+
/**
|
|
17
|
+
* Override getTransactionReceipt to preserve Pod-specific fields (pod_metadata)
|
|
18
|
+
* while maintaining ethers.js TransactionReceipt compatibility
|
|
19
|
+
*/
|
|
20
|
+
getTransactionReceipt(txHash: string): Promise<PodTransactionReceiptResponse | null>;
|
|
21
|
+
/**
|
|
22
|
+
* Override getTransaction to preserve Pod-specific fields (pod_metadata)
|
|
23
|
+
* while maintaining ethers.js TransactionResponse compatibility
|
|
24
|
+
*/
|
|
25
|
+
getTransaction(txHash: string): Promise<PodTransactionResponse | null>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PodProvider = void 0;
|
|
4
|
+
const ethers_1 = require("ethers");
|
|
5
|
+
class PodProvider extends ethers_1.ethers.JsonRpcProvider {
|
|
6
|
+
async getCommittee() {
|
|
7
|
+
return await this.send('pod_getCommittee', {});
|
|
8
|
+
}
|
|
9
|
+
async getListReceipts(params) {
|
|
10
|
+
var _a;
|
|
11
|
+
return await this.send('pod_listReceipts', [
|
|
12
|
+
(_a = params === null || params === void 0 ? void 0 : params.address) !== null && _a !== void 0 ? _a : null,
|
|
13
|
+
params.since,
|
|
14
|
+
params === null || params === void 0 ? void 0 : params.pagination
|
|
15
|
+
]);
|
|
16
|
+
}
|
|
17
|
+
async getMetrics() {
|
|
18
|
+
return await this.send('pod_metrics', {});
|
|
19
|
+
}
|
|
20
|
+
async getPastPerfectTime() {
|
|
21
|
+
const hex = await this.send('eth_blockNumber', {});
|
|
22
|
+
return (0, ethers_1.toBigInt)(hex);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Override getTransactionReceipt to preserve Pod-specific fields (pod_metadata)
|
|
26
|
+
* while maintaining ethers.js TransactionReceipt compatibility
|
|
27
|
+
*/
|
|
28
|
+
async getTransactionReceipt(txHash) {
|
|
29
|
+
// Get raw response with all Pod fields in a single call
|
|
30
|
+
const rawReceipt = await this.send('eth_getTransactionReceipt', [txHash]);
|
|
31
|
+
if (!rawReceipt) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
// Store pod_metadata before ethers formatting
|
|
35
|
+
const podMetadata = rawReceipt.pod_metadata;
|
|
36
|
+
// Use ethers' internal formatter
|
|
37
|
+
const ethersReceipt = this._wrapTransactionReceipt(rawReceipt, await this.getNetwork());
|
|
38
|
+
// Attach pod_metadata to the formatted receipt
|
|
39
|
+
const podReceipt = ethersReceipt;
|
|
40
|
+
if (podMetadata) {
|
|
41
|
+
podReceipt.pod_metadata = podMetadata;
|
|
42
|
+
}
|
|
43
|
+
return podReceipt;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Override getTransaction to preserve Pod-specific fields (pod_metadata)
|
|
47
|
+
* while maintaining ethers.js TransactionResponse compatibility
|
|
48
|
+
*/
|
|
49
|
+
async getTransaction(txHash) {
|
|
50
|
+
// Get raw response with all Pod fields in a single call
|
|
51
|
+
const rawTx = await this.send('eth_getTransactionByHash', [txHash]);
|
|
52
|
+
if (!rawTx) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
// Store pod_metadata before ethers formatting
|
|
56
|
+
const podMetadata = rawTx.pod_metadata;
|
|
57
|
+
// Use ethers' internal formatter
|
|
58
|
+
const ethersTx = this._wrapTransactionResponse(rawTx, await this.getNetwork());
|
|
59
|
+
// Attach pod_metadata to the formatted transaction
|
|
60
|
+
const podTx = ethersTx;
|
|
61
|
+
if (podMetadata) {
|
|
62
|
+
podTx.pod_metadata = podMetadata;
|
|
63
|
+
}
|
|
64
|
+
return podTx;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.PodProvider = PodProvider;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
export interface PodCommittee {
|
|
3
|
+
validators: string[];
|
|
4
|
+
validator_set: Record<string, boolean>;
|
|
5
|
+
quorum_size: number;
|
|
6
|
+
}
|
|
7
|
+
export interface PodPaginatedResult<T> {
|
|
8
|
+
items: T[];
|
|
9
|
+
cursor?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface PodTransactionReceipt {
|
|
12
|
+
blockHash: string | null;
|
|
13
|
+
blockNumber: string;
|
|
14
|
+
contractAddress: null | string;
|
|
15
|
+
cumulativeGasUsed: string;
|
|
16
|
+
effectiveGasPrice: string;
|
|
17
|
+
from: string;
|
|
18
|
+
gasUsed: string;
|
|
19
|
+
logs: PodTransactionLog[];
|
|
20
|
+
logsBloom: string;
|
|
21
|
+
status: string | null;
|
|
22
|
+
to: string;
|
|
23
|
+
transactionHash: string;
|
|
24
|
+
transactionIndex: string;
|
|
25
|
+
type: string;
|
|
26
|
+
pod_metadata: PodTransactionMetadata;
|
|
27
|
+
}
|
|
28
|
+
export interface PodTransactionLog {
|
|
29
|
+
address: string;
|
|
30
|
+
blockHash: string;
|
|
31
|
+
blockNumber: string;
|
|
32
|
+
data: string;
|
|
33
|
+
logIndex: string;
|
|
34
|
+
removed: false;
|
|
35
|
+
topics: string[];
|
|
36
|
+
transactionHash: string;
|
|
37
|
+
transactionIndex: string;
|
|
38
|
+
}
|
|
39
|
+
export interface PodTransactionMetadata {
|
|
40
|
+
attestations: PodAttestationData[];
|
|
41
|
+
transaction: {
|
|
42
|
+
signature: {
|
|
43
|
+
r: string;
|
|
44
|
+
s: string;
|
|
45
|
+
v: string;
|
|
46
|
+
yParity: string;
|
|
47
|
+
};
|
|
48
|
+
signed: {
|
|
49
|
+
to: string | null;
|
|
50
|
+
value: string;
|
|
51
|
+
nonce: number;
|
|
52
|
+
access_list: ethers.AccessList;
|
|
53
|
+
chain_id?: number | null;
|
|
54
|
+
gas_limit: number;
|
|
55
|
+
input: string;
|
|
56
|
+
max_fee_per_gas: number;
|
|
57
|
+
max_priority_fee_per_gas: number;
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export interface PodAttestationData {
|
|
62
|
+
public_key: string;
|
|
63
|
+
signature: {
|
|
64
|
+
r: string;
|
|
65
|
+
s: string;
|
|
66
|
+
v: string;
|
|
67
|
+
yParity: string;
|
|
68
|
+
};
|
|
69
|
+
timestamp: number;
|
|
70
|
+
}
|
|
71
|
+
export interface PodMetrics {
|
|
72
|
+
gas_price: number;
|
|
73
|
+
latency: number;
|
|
74
|
+
throughput: number;
|
|
75
|
+
validator_uptime: number;
|
|
76
|
+
}
|
|
77
|
+
export interface PodTransactionResponse extends ethers.TransactionResponse {
|
|
78
|
+
pod_metadata?: PodTransactionMetadata;
|
|
79
|
+
}
|
|
80
|
+
export interface PodTransactionReceiptResponse extends ethers.TransactionReceipt {
|
|
81
|
+
pod_metadata: PodTransactionMetadata & {
|
|
82
|
+
attestations: PodAttestationData[];
|
|
83
|
+
receipt_attestations: PodAttestationData[];
|
|
84
|
+
};
|
|
85
|
+
}
|
|
@@ -29,8 +29,8 @@ export interface BridgeRequest {
|
|
|
29
29
|
deposit: {
|
|
30
30
|
chain: BridgeChain;
|
|
31
31
|
txHash: string;
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
depositor: string;
|
|
33
|
+
destination: string;
|
|
34
34
|
token: string;
|
|
35
35
|
amount: string;
|
|
36
36
|
chainId: number;
|
|
@@ -69,56 +69,16 @@ export interface CertifiedLog {
|
|
|
69
69
|
topics: string[];
|
|
70
70
|
data: string;
|
|
71
71
|
};
|
|
72
|
-
|
|
72
|
+
log_index: bigint | string;
|
|
73
73
|
certificate: {
|
|
74
74
|
leaf: string;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
certified_receipt: {
|
|
76
|
+
receipt_root: string;
|
|
77
|
+
aggregate_signature: string;
|
|
78
|
+
sorted_attestation_timestamps: bigint[] | string[];
|
|
79
79
|
};
|
|
80
80
|
proof: {
|
|
81
81
|
path: string[];
|
|
82
82
|
};
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
|
-
export interface PodAttestation {
|
|
86
|
-
public_key: string;
|
|
87
|
-
signature: {
|
|
88
|
-
r: string;
|
|
89
|
-
s: string;
|
|
90
|
-
v: string;
|
|
91
|
-
yParity: string;
|
|
92
|
-
};
|
|
93
|
-
timestamp: number;
|
|
94
|
-
}
|
|
95
|
-
export interface PodMetadata {
|
|
96
|
-
attestations: PodAttestation[];
|
|
97
|
-
}
|
|
98
|
-
export interface PodTransactionReceipt {
|
|
99
|
-
blockHash: string;
|
|
100
|
-
blockNumber: string;
|
|
101
|
-
contractAddress: string | null;
|
|
102
|
-
cumulativeGasUsed: string;
|
|
103
|
-
effectiveGasPrice: string;
|
|
104
|
-
from: string;
|
|
105
|
-
gasUsed: string;
|
|
106
|
-
logs: Array<{
|
|
107
|
-
address: string;
|
|
108
|
-
topics: string[];
|
|
109
|
-
data: string;
|
|
110
|
-
blockNumber: string;
|
|
111
|
-
transactionHash: string;
|
|
112
|
-
transactionIndex: string;
|
|
113
|
-
blockHash: string;
|
|
114
|
-
logIndex: string;
|
|
115
|
-
removed: boolean;
|
|
116
|
-
}>;
|
|
117
|
-
logsBloom: string;
|
|
118
|
-
pod_metadata: PodMetadata;
|
|
119
|
-
status: string;
|
|
120
|
-
to: string;
|
|
121
|
-
transactionHash: string;
|
|
122
|
-
transactionIndex: string;
|
|
123
|
-
type: string;
|
|
124
|
-
}
|
package/package.json
CHANGED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { PodTransactionReceipt } from '../types/pod-bridge.types';
|
|
2
|
-
/**
|
|
3
|
-
* Certificate and POD-specific helper functions
|
|
4
|
-
*/
|
|
5
|
-
export declare class CertificateHelper {
|
|
6
|
-
/**
|
|
7
|
-
* Compute receipt root hash
|
|
8
|
-
*/
|
|
9
|
-
static computeReceiptRoot(receipt: PodTransactionReceipt): string;
|
|
10
|
-
/**
|
|
11
|
-
* Aggregate signatures from attestations
|
|
12
|
-
*/
|
|
13
|
-
static aggregateSignatures(attestations: PodTransactionReceipt['pod_metadata']['attestations']): string;
|
|
14
|
-
/**
|
|
15
|
-
* Hash a log entry
|
|
16
|
-
*/
|
|
17
|
-
static hashLog(log: {
|
|
18
|
-
addr: string;
|
|
19
|
-
topics: string[];
|
|
20
|
-
data: string;
|
|
21
|
-
}): string;
|
|
22
|
-
/**
|
|
23
|
-
* Hash a leaf for merkle tree
|
|
24
|
-
*/
|
|
25
|
-
static hashLeaf(key: string, value: string): string;
|
|
26
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CertificateHelper = void 0;
|
|
4
|
-
const ethers_1 = require("ethers");
|
|
5
|
-
/**
|
|
6
|
-
* Certificate and POD-specific helper functions
|
|
7
|
-
*/
|
|
8
|
-
class CertificateHelper {
|
|
9
|
-
/**
|
|
10
|
-
* Compute receipt root hash
|
|
11
|
-
*/
|
|
12
|
-
static computeReceiptRoot(receipt) {
|
|
13
|
-
// Create a simplified receipt object without pod_metadata for hashing
|
|
14
|
-
const logs = receipt.logs.map(log => ({
|
|
15
|
-
address: log.address,
|
|
16
|
-
topics: log.topics,
|
|
17
|
-
data: log.data
|
|
18
|
-
}));
|
|
19
|
-
// Receipt RLP encoding fields (simplified - matches POD's receipt structure)
|
|
20
|
-
const receiptData = ethers_1.ethers.AbiCoder.defaultAbiCoder().encode(['uint8', 'uint256', 'bytes32', 'uint256', 'tuple(address,bytes32[],bytes)[]'], [
|
|
21
|
-
parseInt(receipt.status),
|
|
22
|
-
BigInt(receipt.cumulativeGasUsed),
|
|
23
|
-
receipt.logsBloom,
|
|
24
|
-
BigInt(receipt.gasUsed),
|
|
25
|
-
logs.map(log => [log.address, log.topics, log.data])
|
|
26
|
-
]);
|
|
27
|
-
return ethers_1.ethers.keccak256(receiptData);
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Aggregate signatures from attestations
|
|
31
|
-
*/
|
|
32
|
-
static aggregateSignatures(attestations) {
|
|
33
|
-
// Concatenate all signatures (r, s, v format)
|
|
34
|
-
const signatures = attestations.map(att => {
|
|
35
|
-
const r = att.signature.r.startsWith('0x') ? att.signature.r.slice(2) : att.signature.r;
|
|
36
|
-
const s = att.signature.s.startsWith('0x') ? att.signature.s.slice(2) : att.signature.s;
|
|
37
|
-
const v = att.signature.v.startsWith('0x') ? att.signature.v.slice(2) : att.signature.v;
|
|
38
|
-
return r + s + v.padStart(2, '0');
|
|
39
|
-
});
|
|
40
|
-
return '0x' + signatures.join('');
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Hash a log entry
|
|
44
|
-
*/
|
|
45
|
-
static hashLog(log) {
|
|
46
|
-
return ethers_1.ethers.keccak256(ethers_1.ethers.AbiCoder.defaultAbiCoder().encode(['address', 'bytes32[]', 'bytes'], [log.addr, log.topics, log.data]));
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Hash a leaf for merkle tree
|
|
50
|
-
*/
|
|
51
|
-
static hashLeaf(key, value) {
|
|
52
|
-
return ethers_1.ethers.keccak256(ethers_1.ethers.AbiCoder.defaultAbiCoder().encode(['bytes', 'bytes32'], [ethers_1.ethers.toUtf8Bytes(key), value]));
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
exports.CertificateHelper = CertificateHelper;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MerkleHelper = exports.CertificateHelper = void 0;
|
|
4
|
-
var certificate_helper_1 = require("./certificate.helper");
|
|
5
|
-
Object.defineProperty(exports, "CertificateHelper", { enumerable: true, get: function () { return certificate_helper_1.CertificateHelper; } });
|
|
6
|
-
var merkle_helper_1 = require("./merkle.helper");
|
|
7
|
-
Object.defineProperty(exports, "MerkleHelper", { enumerable: true, get: function () { return merkle_helper_1.MerkleHelper; } });
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MerkleHelper = void 0;
|
|
4
|
-
const ethers_1 = require("ethers");
|
|
5
|
-
const certificate_helper_1 = require("./certificate.helper");
|
|
6
|
-
/**
|
|
7
|
-
* Merkle tree helper functions
|
|
8
|
-
*/
|
|
9
|
-
class MerkleHelper {
|
|
10
|
-
/**
|
|
11
|
-
* Generate merkle proof for a log at given index
|
|
12
|
-
*/
|
|
13
|
-
static generateMerkleProof(logs, logIndex) {
|
|
14
|
-
// Hash all logs
|
|
15
|
-
const logHashes = logs.map((log, idx) => certificate_helper_1.CertificateHelper.hashLeaf(`log_hashes[${idx}]`, certificate_helper_1.CertificateHelper.hashLog({
|
|
16
|
-
addr: log.address,
|
|
17
|
-
topics: log.topics,
|
|
18
|
-
data: log.data
|
|
19
|
-
})));
|
|
20
|
-
// Build merkle tree and generate proof
|
|
21
|
-
const proof = [];
|
|
22
|
-
let currentIndex = logIndex;
|
|
23
|
-
let currentLevel = [...logHashes];
|
|
24
|
-
while (currentLevel.length > 1) {
|
|
25
|
-
const nextLevel = [];
|
|
26
|
-
for (let i = 0; i < currentLevel.length; i += 2) {
|
|
27
|
-
if (i + 1 < currentLevel.length) {
|
|
28
|
-
// Pair exists
|
|
29
|
-
const left = currentLevel[i];
|
|
30
|
-
const right = currentLevel[i + 1];
|
|
31
|
-
// Add sibling to proof if current index is in this pair
|
|
32
|
-
if (i === currentIndex || i + 1 === currentIndex) {
|
|
33
|
-
proof.push(i === currentIndex ? right : left);
|
|
34
|
-
}
|
|
35
|
-
nextLevel.push(ethers_1.ethers.keccak256(ethers_1.ethers.AbiCoder.defaultAbiCoder().encode(['bytes32', 'bytes32'], [left, right])));
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
// Odd node, promote to next level
|
|
39
|
-
nextLevel.push(currentLevel[i]);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
currentIndex = Math.floor(currentIndex / 2);
|
|
43
|
-
currentLevel = nextLevel;
|
|
44
|
-
}
|
|
45
|
-
return proof;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
exports.MerkleHelper = MerkleHelper;
|