@tonappchain/sdk 0.7.0-rc24-test-8 → 0.7.0-rc24-test-10

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.
Files changed (32) hide show
  1. package/dist/artifacts/dev/tac/artifacts.js +2 -2
  2. package/dist/artifacts/dev/tac/wrappers.d.ts +4 -4
  3. package/dist/artifacts/mainnet/tac/artifacts.js +2 -2
  4. package/dist/artifacts/mainnet/tac/wrappers.d.ts +4 -4
  5. package/dist/artifacts/tacTypes.d.ts +1 -1
  6. package/dist/artifacts/testnet/tac/artifacts.js +2 -2
  7. package/dist/artifacts/testnet/tac/wrappers.d.ts +4 -4
  8. package/dist/artifacts/tonTypes.d.ts +1 -1
  9. package/dist/src/adapters/contractOpener.js +3 -1
  10. package/dist/src/agnosticSdk/AbiHandler.d.ts +23 -0
  11. package/dist/src/agnosticSdk/AbiHandler.js +105 -0
  12. package/dist/src/agnosticSdk/AgnosticSdk.d.ts +47 -217
  13. package/dist/src/agnosticSdk/AgnosticSdk.js +60 -595
  14. package/dist/src/agnosticSdk/AgnosticStructs.d.ts +108 -0
  15. package/dist/src/agnosticSdk/AgnosticStructs.js +23 -0
  16. package/dist/src/agnosticSdk/DebugHelpers.d.ts +88 -0
  17. package/dist/src/agnosticSdk/DebugHelpers.js +274 -0
  18. package/dist/src/agnosticSdk/HooksHandler.d.ts +43 -0
  19. package/dist/src/agnosticSdk/HooksHandler.js +102 -0
  20. package/dist/src/agnosticSdk/ReplacementHelper.d.ts +95 -0
  21. package/dist/src/agnosticSdk/ReplacementHelper.js +233 -0
  22. package/dist/src/assets/NFT.js +3 -3
  23. package/dist/src/errors/index.d.ts +1 -1
  24. package/dist/src/index.d.ts +2 -1
  25. package/dist/src/index.js +26 -2
  26. package/dist/src/sdk/Configuration.js +5 -5
  27. package/dist/src/sdk/OperationTracker.js +37 -14
  28. package/dist/src/sdk/TONTransactionManager.js +3 -2
  29. package/dist/src/sdk/TacSdk.js +4 -37
  30. package/dist/src/structs/InternalStruct.d.ts +1 -1
  31. package/dist/src/wrappers/ContentUtils.js +0 -1
  32. package/package.json +1 -1
@@ -0,0 +1,108 @@
1
+ /**
2
+ * NFTData is a struct that contains the nft, id, and amount of the nft
3
+ * @param nft - The address of the nft
4
+ * @param id - The id of the nft
5
+ * @param amount - The amount of the nft to transfer(for ERC1155, but currently supported only ERC721)
6
+ */
7
+ export interface NFTData {
8
+ nft: string;
9
+ id: bigint;
10
+ amount: bigint;
11
+ }
12
+ /**
13
+ * BridgeData is a struct that contains the tokens, nfts, and isRequired of the bridge data
14
+ * @param tokens - The addresses of the tokens to bridge
15
+ * @param nfts - The nfts to bridge
16
+ * @param isRequired - Whether the bridge is required
17
+ */
18
+ export interface BridgeData {
19
+ tokens: string[];
20
+ nfts: NFTData[];
21
+ isRequired: boolean;
22
+ }
23
+ /**
24
+ * HookType is an enum that contains the type of the hook
25
+ * @param Custom - The custom hook
26
+ * @param FullBalanceApprove - The full balance approve hook
27
+ * @param FullBalanceTransfer - The full balance transfer hook
28
+ */
29
+ export declare enum HookType {
30
+ Custom = 0,
31
+ FullBalanceApprove = 1,
32
+ FullBalanceTransfer = 2
33
+ }
34
+ /**
35
+ * ReplacementType is an enum that contains the type of the replacement
36
+ * @param Amount - The amount replacement
37
+ */
38
+ export declare enum ReplacementType {
39
+ Amount = 0
40
+ }
41
+ /**
42
+ * AmountChange is a struct that contains the position, length, token, and balance address of the amount change
43
+ * @param position - The position of the amount change(position of the parameter in the function call)
44
+ * @param len - The length of the amount change(length of the parameter in the function call)
45
+ * @param token - The token of the amount change
46
+ * @param balanceAddress - The balance address of the amount change(address to check balance for)
47
+ */
48
+ export interface AmountChange {
49
+ position: number;
50
+ len: number;
51
+ token: string;
52
+ balanceAddress: string;
53
+ }
54
+ /**
55
+ * CustomHookData is a struct that contains the isFromSAPerspective, contractAddress, value, data, and improvedMissionInfo of the custom hook
56
+ * @param isFromSAPerspective - Whether the hook is from the smart account perspective or from proxy perspective
57
+ * @param contractAddress - The address of the contract to call
58
+ * @param value - The value of the hook
59
+ * @param data - The data of the hook
60
+ * @param improvedMissionInfo - The improved mission info of the hook
61
+ */
62
+ export interface CustomHookData {
63
+ isFromSAPerspective: boolean;
64
+ contractAddress: string;
65
+ value: bigint;
66
+ data: string;
67
+ improvedMissionInfo: string;
68
+ }
69
+ /**
70
+ * ApproveHookData is a struct that contains the token, to, and isFromSAPerspective of the approve hook
71
+ * @param token - The token to approve
72
+ * @param to - The address to approve to
73
+ * @param isFromSAPerspective - Whether the hook is from the smart account perspective or from proxy perspective
74
+ */
75
+ export interface ApproveHookData {
76
+ token: string;
77
+ to: string;
78
+ isFromSAPerspective: boolean;
79
+ }
80
+ /**
81
+ * TransferHookData is a struct that contains the token, to, and isFromSAPerspective of the transfer hook
82
+ * @param token - The token to transfer
83
+ * @param to - The address to transfer to
84
+ * @param isFromSAPerspective - Whether the hook is from the smart account perspective or from proxy perspective
85
+ */
86
+ export interface TransferHookData {
87
+ token: string;
88
+ to: string;
89
+ isFromSAPerspective: boolean;
90
+ }
91
+ /**
92
+ * Hook is a struct that contains the hookType and hookData of the hook
93
+ * @param hookType - The type of the hook
94
+ * @param hookData - The data of the hook
95
+ */
96
+ export interface Hook {
97
+ hookType: HookType;
98
+ hookData: string;
99
+ }
100
+ /**
101
+ * ZapCall is a struct that contains the hooks and bridgeData of the zap call
102
+ * @param hooks - The hooks of the zap call
103
+ * @param bridgeData - The bridge data of the zap call
104
+ */
105
+ export interface ZapCall {
106
+ hooks: Hook[];
107
+ bridgeData: BridgeData;
108
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ReplacementType = exports.HookType = void 0;
4
+ /**
5
+ * HookType is an enum that contains the type of the hook
6
+ * @param Custom - The custom hook
7
+ * @param FullBalanceApprove - The full balance approve hook
8
+ * @param FullBalanceTransfer - The full balance transfer hook
9
+ */
10
+ var HookType;
11
+ (function (HookType) {
12
+ HookType[HookType["Custom"] = 0] = "Custom";
13
+ HookType[HookType["FullBalanceApprove"] = 1] = "FullBalanceApprove";
14
+ HookType[HookType["FullBalanceTransfer"] = 2] = "FullBalanceTransfer";
15
+ })(HookType || (exports.HookType = HookType = {}));
16
+ /**
17
+ * ReplacementType is an enum that contains the type of the replacement
18
+ * @param Amount - The amount replacement
19
+ */
20
+ var ReplacementType;
21
+ (function (ReplacementType) {
22
+ ReplacementType[ReplacementType["Amount"] = 0] = "Amount";
23
+ })(ReplacementType || (exports.ReplacementType = ReplacementType = {}));
@@ -0,0 +1,88 @@
1
+ import { Interface } from 'ethers';
2
+ import { Hook, NFTData, ZapCall } from './AgnosticStructs';
3
+ export declare class DebugHelpers {
4
+ /**
5
+ * Build a complete ZapCall
6
+ * @param hooks - The hooks of the zap call
7
+ * @param bridgeTokens - The tokens to bridge
8
+ * @param bridgeNFTs - The nfts to bridge
9
+ * @returns The zap call
10
+ */
11
+ buildZapCall(hooks: Hook[], bridgeTokens?: string[], bridgeNFTs?: NFTData[]): ZapCall;
12
+ /**
13
+ * Debug helper: Decode hook data back to readable format
14
+ * @param hook - The hook to decode
15
+ * @returns The decoded hook
16
+ */
17
+ decodeHookData(hook: Hook): any;
18
+ /**
19
+ * Debug helper: Get estimated gas for a ZapCall
20
+ * @param zapCall - The zap call to estimate the gas usage for
21
+ * @returns The estimated gas usage
22
+ */
23
+ estimateGasUsage(zapCall: ZapCall): number;
24
+ /**
25
+ * Visualize ZapCall chain - Human readable description of all operations
26
+ * @param zapCall - The zap call to visualize
27
+ */
28
+ visualizeZapCall(zapCall: ZapCall, contractInterfaces: Map<string, Interface>): void;
29
+ /**
30
+ * Private helper to describe individual hooks
31
+ * @param hook - The hook to describe
32
+ * @returns The description of the hook
33
+ */
34
+ private _describeHook;
35
+ /**
36
+ * Describe custom hook with function details
37
+ * @param hook - The hook to describe
38
+ * @returns The description of the hook
39
+ */
40
+ private _describeCustomHook;
41
+ /**
42
+ * Describe approve hook
43
+ * @param hook - The hook to describe
44
+ * @returns The description of the hook
45
+ */
46
+ private _describeApproveHook;
47
+ /**
48
+ * Describe transfer hook
49
+ * @param hook - The hook to describe
50
+ * @returns The description of the hook
51
+ */
52
+ private _describeTransferHook;
53
+ /**
54
+ * Format address for display (show first 6 and last 4 characters)
55
+ * @param address - The address to format
56
+ * @returns The formatted address
57
+ */
58
+ private _formatAddress;
59
+ /**
60
+ * Get a detailed breakdown of a ZapCall for logging
61
+ * @param zapCall - The zap call to get the breakdown for
62
+ * @returns The breakdown of the zap call
63
+ */
64
+ getZapCallBreakdown(zapCall: ZapCall, contractInterfaces: Map<string, Interface>): {
65
+ totalHooks: number;
66
+ hookTypes: {
67
+ [key: string]: number;
68
+ };
69
+ gasEstimate: number;
70
+ encodedSize: number;
71
+ bridgeRequired: boolean;
72
+ hookDescriptions: string[];
73
+ };
74
+ /**
75
+ * Compare two ZapCalls and show differences
76
+ * @param zapCall1 - The first zap call to compare
77
+ * @param zapCall2 - The second zap call to compare
78
+ * @param label1 - The label of the first zap call
79
+ * @param label2 - The label of the second zap call
80
+ */
81
+ compareZapCalls(zapCall1: ZapCall, zapCall2: ZapCall, label1: string | undefined, label2: string | undefined, contractInterfaces: Map<string, Interface>): void;
82
+ /**
83
+ * Encode ZapCall for transaction
84
+ * @param zapCall - The zap call to encode
85
+ * @returns The encoded zap call that can be used as calldata in tac sdk
86
+ */
87
+ encodeZapCall(zapCall: ZapCall): string;
88
+ }
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DebugHelpers = void 0;
4
+ const ethers_1 = require("ethers");
5
+ const AgnosticStructs_1 = require("./AgnosticStructs");
6
+ class DebugHelpers {
7
+ /**
8
+ * Build a complete ZapCall
9
+ * @param hooks - The hooks of the zap call
10
+ * @param bridgeTokens - The tokens to bridge
11
+ * @param bridgeNFTs - The nfts to bridge
12
+ * @returns The zap call
13
+ */
14
+ buildZapCall(hooks, bridgeTokens = [], bridgeNFTs = []) {
15
+ return {
16
+ hooks,
17
+ bridgeData: {
18
+ tokens: bridgeTokens,
19
+ nfts: bridgeNFTs,
20
+ isRequired: bridgeTokens.length > 0 || bridgeNFTs.length > 0 ? true : false,
21
+ },
22
+ };
23
+ }
24
+ /**
25
+ * Debug helper: Decode hook data back to readable format
26
+ * @param hook - The hook to decode
27
+ * @returns The decoded hook
28
+ */
29
+ decodeHookData(hook) {
30
+ try {
31
+ switch (hook.hookType) {
32
+ case AgnosticStructs_1.HookType.Custom:
33
+ return ethers_1.ethers.AbiCoder.defaultAbiCoder().decode(['tuple(bool,address,uint256,bytes,bytes)'], hook.hookData)[0];
34
+ case AgnosticStructs_1.HookType.FullBalanceApprove:
35
+ return ethers_1.ethers.AbiCoder.defaultAbiCoder().decode(['tuple(address,address,bool)'], hook.hookData)[0];
36
+ case AgnosticStructs_1.HookType.FullBalanceTransfer:
37
+ return ethers_1.ethers.AbiCoder.defaultAbiCoder().decode(['tuple(address,address,bool)'], hook.hookData)[0];
38
+ default:
39
+ throw new Error(`Unknown hook type: ${hook.hookType}`);
40
+ }
41
+ }
42
+ catch (error) {
43
+ throw new Error(`Failed to decode hook data: ${error}`);
44
+ }
45
+ }
46
+ /**
47
+ * Debug helper: Get estimated gas for a ZapCall
48
+ * @param zapCall - The zap call to estimate the gas usage for
49
+ * @returns The estimated gas usage
50
+ */
51
+ estimateGasUsage(zapCall) {
52
+ // Rough estimation based on hook types and operations
53
+ let gasEstimate = 50000; // Base gas
54
+ zapCall.hooks.forEach((hook) => {
55
+ switch (hook.hookType) {
56
+ case AgnosticStructs_1.HookType.Custom:
57
+ gasEstimate += 100000; // Custom calls can vary widely
58
+ break;
59
+ case AgnosticStructs_1.HookType.FullBalanceApprove:
60
+ gasEstimate += 50000; // ERC20 approve
61
+ break;
62
+ case AgnosticStructs_1.HookType.FullBalanceTransfer:
63
+ gasEstimate += 65000; // ERC20 transfer
64
+ break;
65
+ }
66
+ });
67
+ if (zapCall.bridgeData.isRequired) {
68
+ gasEstimate += 200000; // Bridge operations
69
+ }
70
+ return gasEstimate;
71
+ }
72
+ /**
73
+ * Visualize ZapCall chain - Human readable description of all operations
74
+ * @param zapCall - The zap call to visualize
75
+ */
76
+ visualizeZapCall(zapCall, contractInterfaces) {
77
+ console.log('🔗 ZapCall Chain Visualization');
78
+ console.log('================================');
79
+ if (zapCall.hooks.length === 0) {
80
+ console.log('❌ No hooks in this ZapCall');
81
+ return;
82
+ }
83
+ zapCall.hooks.forEach((hook, index) => {
84
+ const stepNumber = (index + 1).toString().padStart(2, ' ');
85
+ console.log(`\n${stepNumber}. ${this._describeHook(hook, contractInterfaces)}`);
86
+ });
87
+ // Bridge information
88
+ if (zapCall.bridgeData.isRequired) {
89
+ console.log('\n🌉 Bridge Operations:');
90
+ if (zapCall.bridgeData.tokens.length > 0) {
91
+ console.log(` 📤 Bridge tokens: ${zapCall.bridgeData.tokens.map((t) => this._formatAddress(t)).join(', ')}`);
92
+ }
93
+ if (zapCall.bridgeData.nfts.length > 0) {
94
+ console.log(` 🖼️ Bridge NFTs: ${zapCall.bridgeData.nfts.length} NFT(s)`);
95
+ zapCall.bridgeData.nfts.forEach((nft, i) => {
96
+ console.log(` ${i + 1}. ${this._formatAddress(nft.nft)} #${nft.id} (amount: ${nft.amount})`);
97
+ });
98
+ }
99
+ }
100
+ else {
101
+ console.log('\n🚫 No bridge operations required');
102
+ }
103
+ // Summary
104
+ console.log('\n📊 Summary:');
105
+ console.log(` Total hooks: ${zapCall.hooks.length}`);
106
+ console.log(` Estimated gas: ${this.estimateGasUsage(zapCall).toLocaleString()}`);
107
+ console.log(` Bridge required: ${zapCall.bridgeData.isRequired ? 'Yes' : 'No'}`);
108
+ console.log('================================');
109
+ }
110
+ /**
111
+ * Private helper to describe individual hooks
112
+ * @param hook - The hook to describe
113
+ * @returns The description of the hook
114
+ */
115
+ _describeHook(hook, contractInterfaces) {
116
+ try {
117
+ switch (hook.hookType) {
118
+ case AgnosticStructs_1.HookType.Custom:
119
+ return this._describeCustomHook(hook, contractInterfaces);
120
+ case AgnosticStructs_1.HookType.FullBalanceApprove:
121
+ return this._describeApproveHook(hook);
122
+ case AgnosticStructs_1.HookType.FullBalanceTransfer:
123
+ return this._describeTransferHook(hook);
124
+ default:
125
+ return `❓ Unknown hook type: ${hook.hookType}`;
126
+ }
127
+ }
128
+ catch (error) {
129
+ return `❌ Error describing hook: ${error}`;
130
+ }
131
+ }
132
+ /**
133
+ * Describe custom hook with function details
134
+ * @param hook - The hook to describe
135
+ * @returns The description of the hook
136
+ */
137
+ _describeCustomHook(hook, contractInterfaces) {
138
+ const decoded = this.decodeHookData(hook);
139
+ const [isFromSA, contractAddress, value, data, improvedMissionInfo] = decoded;
140
+ // Try to decode function name from data
141
+ let functionDescription = 'unknown function';
142
+ let hasReplacements = false;
143
+ if (data && data.length >= 10) {
144
+ // At least 4 bytes for selector + some data
145
+ const selector = data.slice(0, 10); // "0x" + 8 hex chars
146
+ // Try to find function name from registered interfaces
147
+ for (const [address, contractInterface] of contractInterfaces) {
148
+ if (address === contractAddress.toLowerCase()) {
149
+ try {
150
+ const fragment = contractInterface.getFunction(selector);
151
+ if (fragment) {
152
+ functionDescription = `${fragment.name}(${fragment.inputs.map((input) => input.type).join(', ')})`;
153
+ break;
154
+ }
155
+ }
156
+ catch {
157
+ // Function not found in this interface
158
+ }
159
+ }
160
+ }
161
+ // If not found in registered interfaces, just show selector
162
+ if (functionDescription === 'unknown function') {
163
+ functionDescription = `function with selector ${selector}`;
164
+ }
165
+ }
166
+ // Check for dynamic replacements
167
+ if (improvedMissionInfo && improvedMissionInfo !== '0x' && improvedMissionInfo.length > 2) {
168
+ hasReplacements = true;
169
+ }
170
+ const perspective = isFromSA ? 'Smart Account' : 'Proxy Contract';
171
+ const valueStr = value > 0n ? ` (sending ${ethers_1.ethers.formatEther(value)} ETH)` : '';
172
+ const replacementStr = hasReplacements ? ' 🔄 [with dynamic value replacement]' : '';
173
+ return `📞 Custom call to ${this._formatAddress(contractAddress)} from ${perspective}${valueStr}
174
+ Function: ${functionDescription}${replacementStr}`;
175
+ }
176
+ /**
177
+ * Describe approve hook
178
+ * @param hook - The hook to describe
179
+ * @returns The description of the hook
180
+ */
181
+ _describeApproveHook(hook) {
182
+ const decoded = this.decodeHookData(hook);
183
+ const [token, to, isFromSA] = decoded;
184
+ const perspective = isFromSA ? 'Smart Account' : 'Proxy Contract';
185
+ return `✅ Approve full balance of ${this._formatAddress(token)} to ${this._formatAddress(to)} from ${perspective}`;
186
+ }
187
+ /**
188
+ * Describe transfer hook
189
+ * @param hook - The hook to describe
190
+ * @returns The description of the hook
191
+ */
192
+ _describeTransferHook(hook) {
193
+ const decoded = this.decodeHookData(hook);
194
+ const [token, to, isFromSA] = decoded;
195
+ const perspective = isFromSA ? 'Smart Account' : 'Proxy Contract';
196
+ return `💸 Transfer full balance of ${this._formatAddress(token)} to ${this._formatAddress(to)} from ${perspective}`;
197
+ }
198
+ /**
199
+ * Format address for display (show first 6 and last 4 characters)
200
+ * @param address - The address to format
201
+ * @returns The formatted address
202
+ */
203
+ _formatAddress(address) {
204
+ if (!address || address.length < 10)
205
+ return address;
206
+ return `${address.slice(0, 6)}...${address.slice(-4)}`;
207
+ }
208
+ /**
209
+ * Get a detailed breakdown of a ZapCall for logging
210
+ * @param zapCall - The zap call to get the breakdown for
211
+ * @returns The breakdown of the zap call
212
+ */
213
+ getZapCallBreakdown(zapCall, contractInterfaces) {
214
+ const hookTypes = {};
215
+ const hookDescriptions = [];
216
+ zapCall.hooks.forEach((hook, index) => {
217
+ const typeName = AgnosticStructs_1.HookType[hook.hookType];
218
+ hookTypes[typeName] = (hookTypes[typeName] || 0) + 1;
219
+ hookDescriptions.push(`${index + 1}. ${this._describeHook(hook, contractInterfaces)}`);
220
+ });
221
+ return {
222
+ totalHooks: zapCall.hooks.length,
223
+ hookTypes,
224
+ gasEstimate: this.estimateGasUsage(zapCall),
225
+ encodedSize: this.encodeZapCall(zapCall).length / 2, // bytes
226
+ bridgeRequired: zapCall.bridgeData.isRequired,
227
+ hookDescriptions,
228
+ };
229
+ }
230
+ /**
231
+ * Compare two ZapCalls and show differences
232
+ * @param zapCall1 - The first zap call to compare
233
+ * @param zapCall2 - The second zap call to compare
234
+ * @param label1 - The label of the first zap call
235
+ * @param label2 - The label of the second zap call
236
+ */
237
+ compareZapCalls(zapCall1, zapCall2, label1 = 'ZapCall 1', label2 = 'ZapCall 2', contractInterfaces) {
238
+ console.log(`🔄 Comparing ${label1} vs ${label2}`);
239
+ console.log('='.repeat(50));
240
+ const breakdown1 = this.getZapCallBreakdown(zapCall1, contractInterfaces);
241
+ const breakdown2 = this.getZapCallBreakdown(zapCall2, contractInterfaces);
242
+ console.log(`📊 ${label1}:`);
243
+ console.log(` Hooks: ${breakdown1.totalHooks}, Gas: ${breakdown1.gasEstimate.toLocaleString()}, Size: ${breakdown1.encodedSize} bytes`);
244
+ console.log(`📊 ${label2}:`);
245
+ console.log(` Hooks: ${breakdown2.totalHooks}, Gas: ${breakdown2.gasEstimate.toLocaleString()}, Size: ${breakdown2.encodedSize} bytes`);
246
+ console.log('\n📈 Differences:');
247
+ console.log(` Hooks: ${breakdown2.totalHooks - breakdown1.totalHooks > 0 ? '+' : ''}${breakdown2.totalHooks - breakdown1.totalHooks}`);
248
+ console.log(` Gas: ${breakdown2.gasEstimate - breakdown1.gasEstimate > 0 ? '+' : ''}${(breakdown2.gasEstimate - breakdown1.gasEstimate).toLocaleString()}`);
249
+ console.log(` Size: ${breakdown2.encodedSize - breakdown1.encodedSize > 0 ? '+' : ''}${breakdown2.encodedSize - breakdown1.encodedSize} bytes`);
250
+ }
251
+ /**
252
+ * Encode ZapCall for transaction
253
+ * @param zapCall - The zap call to encode
254
+ * @returns The encoded zap call that can be used as calldata in tac sdk
255
+ */
256
+ encodeZapCall(zapCall) {
257
+ return ethers_1.ethers.AbiCoder.defaultAbiCoder().encode([
258
+ 'tuple(' +
259
+ 'tuple(uint8,bytes)[],' + // hooks: only hookType and hookData
260
+ 'tuple(address[],tuple(address,uint256,uint256)[],bool)' + // bridgeData
261
+ ')',
262
+ ], [
263
+ [
264
+ zapCall.hooks.map((hook) => [hook.hookType, hook.hookData]),
265
+ [
266
+ zapCall.bridgeData.tokens,
267
+ zapCall.bridgeData.nfts.map((nft) => [nft.nft, nft.id, nft.amount]),
268
+ zapCall.bridgeData.isRequired,
269
+ ],
270
+ ],
271
+ ]);
272
+ }
273
+ }
274
+ exports.DebugHelpers = DebugHelpers;
@@ -0,0 +1,43 @@
1
+ import { Interface } from 'ethers';
2
+ import { AmountChange, Hook } from './AgnosticStructs';
3
+ export declare class HooksHandler {
4
+ /**
5
+ * Create a custom hook with optional dynamic value replacement
6
+ * @param contractAddress - The address of the contract to call
7
+ * @param functionName - The name of the function to call
8
+ * @param params - The parameters of the function to call
9
+ * @param options - The options of the custom hook
10
+ * @returns The custom hook
11
+ */
12
+ createCustomHook(contractAddress: string, functionName: string, params: any[], contractInterfaces: Map<string, Interface>, options?: {
13
+ isFromSAPerspective?: boolean;
14
+ value?: bigint;
15
+ dynamicReplacements?: AmountChange[];
16
+ }): Hook;
17
+ /**
18
+ * Create a full balance approve hook
19
+ * @param token - The token to approve
20
+ * @param to - The address to approve to
21
+ * @param isFromSAPerspective - Whether the hook is from the smart account perspective or from proxy perspective
22
+ * @returns The full balance approve hook
23
+ */
24
+ createFullBalanceApproveHook(token: string, to: string, isFromSAPerspective?: boolean): Hook;
25
+ /**
26
+ * Create a full balance transfer hook
27
+ * @param token - The token to transfer
28
+ * @param to - The address to transfer to
29
+ * @param isFromSAPerspective - Whether the hook is from the smart account perspective or from proxy perspective
30
+ * @returns The full balance transfer hook
31
+ */
32
+ createFullBalanceTransferHook(token: string, to: string, isFromSAPerspective?: boolean): Hook;
33
+ /**
34
+ * Utility: Create multiple approve hooks at once
35
+ * @param approvals - The approvals to create
36
+ * @returns The multiple approve hooks
37
+ */
38
+ createMultipleApproves(approvals: {
39
+ token: string;
40
+ spender: string;
41
+ isFromSA?: boolean;
42
+ }[]): Hook[];
43
+ }
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HooksHandler = void 0;
4
+ const ethers_1 = require("ethers");
5
+ const AgnosticStructs_1 = require("./AgnosticStructs");
6
+ class HooksHandler {
7
+ /**
8
+ * Create a custom hook with optional dynamic value replacement
9
+ * @param contractAddress - The address of the contract to call
10
+ * @param functionName - The name of the function to call
11
+ * @param params - The parameters of the function to call
12
+ * @param options - The options of the custom hook
13
+ * @returns The custom hook
14
+ */
15
+ createCustomHook(contractAddress, functionName, params, contractInterfaces, options = {}) {
16
+ const { isFromSAPerspective = true, value = 0n, dynamicReplacements } = options;
17
+ const contractInterface = contractInterfaces.get(contractAddress.toLowerCase());
18
+ if (!contractInterface) {
19
+ throw new Error(`Contract interface not found for address: ${contractAddress}`);
20
+ }
21
+ const data = contractInterface.encodeFunctionData(functionName, params);
22
+ let improvedMissionInfo = '0x';
23
+ // If dynamic replacements are specified, encode them
24
+ if (dynamicReplacements && dynamicReplacements.length > 0) {
25
+ // For now, support single replacement (can be extended)
26
+ const replacement = dynamicReplacements[0];
27
+ const replacementData = ethers_1.ethers.AbiCoder.defaultAbiCoder().encode(['tuple(uint16,uint16,address,address)'], [[replacement.position, replacement.len, replacement.token, replacement.balanceAddress]]);
28
+ // Encode as ReplacementType.Amount with the replacement data
29
+ improvedMissionInfo = ethers_1.ethers.AbiCoder.defaultAbiCoder().encode(['uint8', 'bytes'], [AgnosticStructs_1.ReplacementType.Amount, replacementData]);
30
+ }
31
+ const customHookData = {
32
+ isFromSAPerspective,
33
+ contractAddress,
34
+ value,
35
+ data,
36
+ improvedMissionInfo,
37
+ };
38
+ // Encode only the CustomHookData
39
+ const encodedHookData = ethers_1.ethers.AbiCoder.defaultAbiCoder().encode(['tuple(bool,address,uint256,bytes,bytes)'], [
40
+ [
41
+ customHookData.isFromSAPerspective,
42
+ customHookData.contractAddress,
43
+ customHookData.value,
44
+ customHookData.data,
45
+ customHookData.improvedMissionInfo,
46
+ ],
47
+ ]);
48
+ return {
49
+ hookType: AgnosticStructs_1.HookType.Custom,
50
+ hookData: encodedHookData,
51
+ };
52
+ }
53
+ /**
54
+ * Create a full balance approve hook
55
+ * @param token - The token to approve
56
+ * @param to - The address to approve to
57
+ * @param isFromSAPerspective - Whether the hook is from the smart account perspective or from proxy perspective
58
+ * @returns The full balance approve hook
59
+ */
60
+ createFullBalanceApproveHook(token, to, isFromSAPerspective = true) {
61
+ const approveHookData = {
62
+ token,
63
+ to,
64
+ isFromSAPerspective,
65
+ };
66
+ // Encode only the ApproveHookData
67
+ const encodedHookData = ethers_1.ethers.AbiCoder.defaultAbiCoder().encode(['tuple(address,address,bool)'], [[approveHookData.token, approveHookData.to, approveHookData.isFromSAPerspective]]);
68
+ return {
69
+ hookType: AgnosticStructs_1.HookType.FullBalanceApprove,
70
+ hookData: encodedHookData,
71
+ };
72
+ }
73
+ /**
74
+ * Create a full balance transfer hook
75
+ * @param token - The token to transfer
76
+ * @param to - The address to transfer to
77
+ * @param isFromSAPerspective - Whether the hook is from the smart account perspective or from proxy perspective
78
+ * @returns The full balance transfer hook
79
+ */
80
+ createFullBalanceTransferHook(token, to, isFromSAPerspective = true) {
81
+ const transferHookData = {
82
+ token,
83
+ to,
84
+ isFromSAPerspective,
85
+ };
86
+ // Encode only the TransferHookData
87
+ const encodedHookData = ethers_1.ethers.AbiCoder.defaultAbiCoder().encode(['tuple(address,address,bool)'], [[transferHookData.token, transferHookData.to, transferHookData.isFromSAPerspective]]);
88
+ return {
89
+ hookType: AgnosticStructs_1.HookType.FullBalanceTransfer,
90
+ hookData: encodedHookData,
91
+ };
92
+ }
93
+ /**
94
+ * Utility: Create multiple approve hooks at once
95
+ * @param approvals - The approvals to create
96
+ * @returns The multiple approve hooks
97
+ */
98
+ createMultipleApproves(approvals) {
99
+ return approvals.map((approval) => this.createFullBalanceApproveHook(approval.token, approval.spender, approval.isFromSA ?? true));
100
+ }
101
+ }
102
+ exports.HooksHandler = HooksHandler;