@lukso/transaction-decoder 1.3.7 → 1.3.8-dev.169c8ba

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/server.cjs CHANGED
@@ -547,196 +547,6 @@ var ServerDecoderCaches = class {
547
547
  }
548
548
  };
549
549
 
550
- // src/core/addressCollector.ts
551
- import { isHex, size } from "viem";
552
-
553
- // src/decoder/utils.ts
554
- import {
555
- AbiFunctionSignatureNotFoundError,
556
- createPublicClient,
557
- decodeAbiParameters,
558
- http,
559
- slice,
560
- toFunctionSelector
561
- } from "viem";
562
- import { formatAbiItem } from "viem/utils";
563
- function customDecodeFunctionData(parameters, preferError) {
564
- try {
565
- const { abi: abi3, data } = parameters;
566
- const signature = slice(data, 0, 4);
567
- const description = abi3.find(
568
- (x) => x.type === (preferError ? "error" : "function") && signature === toFunctionSelector(formatAbiItem(x))
569
- ) || void 0;
570
- if (!description)
571
- throw new AbiFunctionSignatureNotFoundError(signature, {
572
- docsPath: "/docs/contract/decodeFunctionData"
573
- });
574
- const args = "inputs" in description && description.inputs && description.inputs.length > 0 ? decodeAbiParameters(description.inputs, slice(data, 4)) : void 0;
575
- const result = {
576
- functionName: description.name,
577
- sig: signature,
578
- input: data
579
- };
580
- if (args) {
581
- const { args: namedArgs } = createNamedArgs(args, description.inputs);
582
- result.args = namedArgs;
583
- }
584
- return result;
585
- } catch {
586
- }
587
- }
588
- __name(customDecodeFunctionData, "customDecodeFunctionData");
589
- function createNamedArgs(args, inputs) {
590
- const array = args.map((value, index) => {
591
- return {
592
- name: `args${index + 1}`,
593
- ...inputs?.[index],
594
- value
595
- };
596
- });
597
- return { args: array };
598
- }
599
- __name(createNamedArgs, "createNamedArgs");
600
- function getArgByName(args, name) {
601
- if (!args) return void 0;
602
- const arg = args.find((arg2) => arg2.name === name);
603
- return arg?.value;
604
- }
605
- __name(getArgByName, "getArgByName");
606
- var clients = {};
607
- function getPublicClient(chain) {
608
- const { id } = chain;
609
- if (!id) {
610
- throw new Error("Chain ID is required to create a public client");
611
- }
612
- if (!clients[id]) {
613
- clients[id] = createPublicClient({
614
- chain,
615
- transport: http(),
616
- batch: {
617
- multicall: {
618
- batchSize: 100
619
- }
620
- }
621
- });
622
- }
623
- const result = clients[id];
624
- if (!result) {
625
- throw new Error(`Public client for chain ID ${id} not found`);
626
- }
627
- return result;
628
- }
629
- __name(getPublicClient, "getPublicClient");
630
- function needsEnhancementSingle(item) {
631
- if ("sig" in item && item.sig === "0x") {
632
- return false;
633
- }
634
- if (item.standard) {
635
- return false;
636
- }
637
- return true;
638
- }
639
- __name(needsEnhancementSingle, "needsEnhancementSingle");
640
- function needsEnhancement(result) {
641
- if (needsEnhancementSingle(result)) {
642
- return true;
643
- }
644
- if ("children" in result && Array.isArray(result.children)) {
645
- return result.children.some((child) => {
646
- if (child.standard) {
647
- return false;
648
- }
649
- if ("sig" in child && child.sig === "0x") {
650
- return false;
651
- }
652
- return true;
653
- });
654
- }
655
- return false;
656
- }
657
- __name(needsEnhancement, "needsEnhancement");
658
-
659
- // src/core/addressCollector.ts
660
- function collectDataKeys(data, skipGqlTypes = true, existingKeys) {
661
- const addresses = /* @__PURE__ */ new Set();
662
- if (existingKeys) {
663
- for (const key of existingKeys) {
664
- if (typeof key === "string") {
665
- addresses.add(key);
666
- } else {
667
- addresses.add(JSON.stringify(key));
668
- }
669
- }
670
- }
671
- function collectLSP8Tokens(obj) {
672
- if (obj.standard !== "LSP8IdentifiableDigitalAsset" || !obj.to || !obj.args) {
673
- return;
674
- }
675
- const contractAddress = obj.to;
676
- const args = obj.args;
677
- const tokenId = getArgByName(args, "tokenId");
678
- if (tokenId && tokenId !== null && tokenId !== "0x") {
679
- addresses.add(`${contractAddress}:${tokenId}`);
680
- }
681
- const tokenIds = getArgByName(args, "tokenIds");
682
- if (Array.isArray(tokenIds)) {
683
- for (const tokenId2 of tokenIds) {
684
- if (tokenId2 && tokenId2 !== null && tokenId2 !== "0x") {
685
- addresses.add(`${contractAddress}:${tokenId2}`);
686
- }
687
- }
688
- }
689
- }
690
- __name(collectLSP8Tokens, "collectLSP8Tokens");
691
- function collect(obj, parent, visited = /* @__PURE__ */ new WeakSet(), path = []) {
692
- if (obj && typeof obj === "object" && visited.has(obj)) {
693
- return;
694
- }
695
- if (obj && typeof obj === "object") {
696
- visited.add(obj);
697
- }
698
- if (typeof obj === "string" && obj.startsWith("0x")) {
699
- if (obj.includes(":")) {
700
- const [addressPart, tokenIdPart] = obj.split(":");
701
- if (addressPart.startsWith("0x") && tokenIdPart.startsWith("0x") && isHex(addressPart) && size(addressPart) === 20) {
702
- addresses.add(obj);
703
- return;
704
- }
705
- }
706
- const isPaddedAddress = /^0x0*([a-fA-F0-9]{40})$/.test(obj);
707
- if (isPaddedAddress || isHex(obj) && size(obj) === 20) {
708
- if (parent && skipGqlTypes && "__gqltype" in parent) {
709
- return;
710
- }
711
- const address = isPaddedAddress ? obj.replace(/^0x0*([a-fA-F0-9]{40})$/, "0x$1") : obj;
712
- if (address.slice(2).split("").filter((c) => c === "0").length > 10) {
713
- return;
714
- }
715
- addresses.add(address);
716
- }
717
- return;
718
- }
719
- if (!obj || typeof obj !== "object") return;
720
- if (Array.isArray(obj)) {
721
- for (let i = 0; i < obj.length; i++) {
722
- collect(obj[i], parent, visited, [...path, `[${i}]`]);
723
- }
724
- } else {
725
- const record = obj;
726
- if ("standard" in record && "to" in record && "args" in record) {
727
- collectLSP8Tokens(record);
728
- }
729
- for (const [key, value] of Object.entries(record)) {
730
- collect(value, record, visited, [...path, key]);
731
- }
732
- }
733
- }
734
- __name(collect, "collect");
735
- collect(data);
736
- return Array.from(addresses);
737
- }
738
- __name(collectDataKeys, "collectDataKeys");
739
-
740
550
  // src/decoder/registry.ts
741
551
  var PluginRegistry = class {
742
552
  static {
@@ -920,521 +730,111 @@ Object.freeze(PluginRegistry.prototype);
920
730
  Object.freeze(PluginRegistry);
921
731
  var pluginRegistry = new PluginRegistry();
922
732
 
923
- // src/decoder/transaction.ts
924
- import { isAddress, isAddressEqual, slice as slice2, zeroAddress } from "viem";
925
- async function decodeTransaction(fullTransaction, options) {
926
- const { preferError } = options;
927
- const {
928
- to,
929
- from,
930
- value,
931
- input: rawInput,
932
- data: rawData,
933
- ...restTransaction
934
- } = fullTransaction;
935
- const { logs, ...transaction } = {
936
- ...restTransaction,
937
- to,
938
- from,
939
- value,
940
- input: rawInput || rawData
941
- };
942
- const data = rawInput || rawData;
943
- if (!data || data === "0x") {
944
- if (preferError) {
945
- return {
946
- ...transaction,
947
- isDecoded: true,
948
- functionName: void 0,
949
- __decoder: void 0,
950
- sig: slice2(data || "0x", 0, 4),
951
- resultType: "error",
952
- errorType: "INVALID" /* INVALID */,
953
- ...createNamedArgs([], []),
954
- standard: void 0,
955
- phase: "enhanced"
956
- };
733
+ // src/decoder/utils.ts
734
+ import {
735
+ AbiFunctionSignatureNotFoundError,
736
+ createPublicClient,
737
+ decodeAbiParameters,
738
+ http,
739
+ slice,
740
+ toFunctionSelector
741
+ } from "viem";
742
+ import { formatAbiItem } from "viem/utils";
743
+ function customDecodeFunctionData(parameters, preferError) {
744
+ try {
745
+ const { abi: abi3, data } = parameters;
746
+ const signature = slice(data, 0, 4);
747
+ const description = abi3.find(
748
+ (x) => x.type === (preferError ? "error" : "function") && signature === toFunctionSelector(formatAbiItem(x))
749
+ ) || void 0;
750
+ if (!description)
751
+ throw new AbiFunctionSignatureNotFoundError(signature, {
752
+ docsPath: "/docs/contract/decodeFunctionData"
753
+ });
754
+ const args = "inputs" in description && description.inputs && description.inputs.length > 0 ? decodeAbiParameters(description.inputs, slice(data, 4)) : void 0;
755
+ const result = {
756
+ functionName: description.name,
757
+ sig: signature,
758
+ input: data
759
+ };
760
+ if (args) {
761
+ const { args: namedArgs } = createNamedArgs(args, description.inputs);
762
+ result.args = namedArgs;
957
763
  }
764
+ return result;
765
+ } catch {
766
+ }
767
+ }
768
+ __name(customDecodeFunctionData, "customDecodeFunctionData");
769
+ function createNamedArgs(args, inputs) {
770
+ const array = args.map((value, index) => {
958
771
  return {
959
- ...transaction,
960
- isDecoded: true,
961
- functionName: void 0,
962
- __decoder: void 0,
963
- standard: void 0,
964
- sig: slice2(data || "0x", 0, 4),
965
- ...createNamedArgs([], []),
966
- resultType: "execute",
967
- phase: "enhanced"
772
+ name: `args${index + 1}`,
773
+ ...inputs?.[index],
774
+ value
968
775
  };
776
+ });
777
+ return { args: array };
778
+ }
779
+ __name(createNamedArgs, "createNamedArgs");
780
+ function getArgByName(args, name) {
781
+ if (!args) return void 0;
782
+ const arg = args.find((arg2) => arg2.name === name);
783
+ return arg?.value;
784
+ }
785
+ __name(getArgByName, "getArgByName");
786
+ var clients = {};
787
+ function getPublicClient(chain) {
788
+ const { id } = chain;
789
+ if (!id) {
790
+ throw new Error("Chain ID is required to create a public client");
969
791
  }
970
- let _lastError;
971
- const activePlugins = options.plugins;
972
- for (const plugin of activePlugins) {
973
- if (to && isAddress(to) && isAddressEqual(to, zeroAddress)) {
974
- return {
975
- ...transaction,
976
- isDecoded: true,
977
- ...createNamedArgs([], []),
978
- resultType: "create",
979
- to,
980
- from,
981
- value,
982
- logs,
983
- phase: "immediate"
984
- };
985
- }
986
- try {
987
- const check = await plugin.enhance(transaction, options);
988
- if (check) {
989
- const output = [];
990
- if (logs) {
991
- for (const log of logs) {
992
- const data2 = await plugin.decodeEvent(log, options);
993
- if (data2) {
994
- output.push(data2);
995
- continue;
996
- }
997
- let done = false;
998
- for (const eventPlugin of activePlugins) {
999
- if (eventPlugin !== plugin) {
1000
- const data3 = await eventPlugin.decodeEvent(log, options);
1001
- if (data3) {
1002
- output.push(data3);
1003
- done = true;
1004
- break;
1005
- }
1006
- }
1007
- }
1008
- if (!done) {
1009
- output.push(log);
1010
- }
1011
- }
1012
- check.logs = output;
1013
- }
1014
- let phase2 = plugin.usesAsync || "functionName" in check && check.functionName && check.standard || check.input === "0x" || !check.input ? "enhanced" : "immediate";
1015
- const resultWithChildren = check;
1016
- if (phase2 === "enhanced" && resultWithChildren.children && Array.isArray(resultWithChildren.children) && resultWithChildren.children.length > 0) {
1017
- const allChildrenEnhanced = resultWithChildren.children.every(
1018
- (child) => child.phase === "enhanced"
1019
- );
1020
- if (!allChildrenEnhanced) {
1021
- phase2 = "immediate";
1022
- }
792
+ if (!clients[id]) {
793
+ clients[id] = createPublicClient({
794
+ chain,
795
+ transport: http(),
796
+ batch: {
797
+ multicall: {
798
+ batchSize: 100
1023
799
  }
1024
- const result2 = {
1025
- ...transaction,
1026
- ...check,
1027
- phase: phase2
1028
- };
1029
- return result2;
1030
800
  }
1031
- } catch (e) {
1032
- console.error(e);
1033
- }
801
+ });
1034
802
  }
1035
- let phase = "functionName" in transaction && transaction.functionName && transaction.standard || transaction.input === "0x" || !transaction.input ? "enhanced" : "immediate";
1036
- const transactionWithChildren = transaction;
1037
- if (phase === "enhanced" && transactionWithChildren.children && Array.isArray(transactionWithChildren.children) && transactionWithChildren.children.length > 0) {
1038
- const allChildrenEnhanced = transactionWithChildren.children.every(
1039
- (child) => child.phase === "enhanced"
1040
- );
1041
- if (!allChildrenEnhanced) {
1042
- phase = "immediate";
1043
- }
803
+ const result = clients[id];
804
+ if (!result) {
805
+ throw new Error(`Public client for chain ID ${id} not found`);
1044
806
  }
1045
- const result = {
1046
- ...transaction,
1047
- standard: void 0,
1048
- __decoder: void 0,
1049
- resultType: "raw",
1050
- phase,
1051
- sig: slice2(
1052
- fullTransaction.input || "data" in fullTransaction && fullTransaction.data || "0x",
1053
- 0,
1054
- 4
1055
- ),
1056
- ...createNamedArgs([], []),
1057
- ...options.wrappers.length ? { wrappers: options.wrappers } : {},
1058
- logs
1059
- };
1060
807
  return result;
1061
808
  }
1062
- __name(decodeTransaction, "decodeTransaction");
1063
-
1064
- // src/server/decodeTransactionSync.ts
1065
- async function decodeTransactionSync(transaction, options, caches2) {
1066
- const startTime = Date.now();
1067
- const { timeoutMs = 800, enableEnhancement = true, chain } = options;
1068
- if (transaction.hash) {
1069
- const cached = caches2.getTransaction(transaction.hash);
1070
- if (cached) {
1071
- return cached;
1072
- }
809
+ __name(getPublicClient, "getPublicClient");
810
+ function needsEnhancementSingle(item) {
811
+ if ("sig" in item && item.sig === "0x") {
812
+ return false;
1073
813
  }
1074
- try {
1075
- const phase1Start = Date.now();
1076
- const plugins = await pluginRegistry.getAll({ syncOnly: true });
1077
- const schemaPlugins = pluginRegistry.getAllSchema();
1078
- const immediateOptions = {
1079
- chain,
1080
- plugins,
1081
- schemaPlugins,
1082
- wrappers: [],
1083
- async: false
1084
- };
1085
- const immediateResult = await decodeTransaction(
1086
- transaction,
1087
- immediateOptions
1088
- );
1089
- if (!immediateResult) {
1090
- return {
1091
- ...createErrorResult(transaction),
1092
- phase: "immediate",
1093
- cached: false,
1094
- timeTaken: Date.now() - startTime
1095
- };
1096
- }
1097
- let currentResult = immediateResult;
1098
- let phase = "immediate";
1099
- if (immediateOptions.wrappers.length > 0) {
1100
- ;
1101
- currentResult.wrappers = immediateOptions.wrappers;
1102
- }
1103
- const addresses = collectDataKeys(currentResult);
1104
- currentResult.addresses = addresses;
1105
- const phase1Time = Date.now() - phase1Start;
1106
- if (enableEnhancement && phase1Time < timeoutMs * 0.6) {
1107
- if (!needsEnhancement(currentResult)) {
1108
- phase = "enhanced";
1109
- } else {
1110
- try {
1111
- const allPlugins = await pluginRegistry.getAll();
1112
- const enhancedOptions = {
1113
- chain,
1114
- plugins: allPlugins,
1115
- schemaPlugins,
1116
- wrappers: [],
1117
- async: true
1118
- };
1119
- const enhancedResult = await Promise.race([
1120
- decodeTransaction(transaction, enhancedOptions),
1121
- // Timeout for phase 2
1122
- new Promise(
1123
- (resolve) => setTimeout(() => resolve(null), timeoutMs * 0.6 - phase1Time)
1124
- )
1125
- ]);
1126
- if (enhancedResult) {
1127
- currentResult = enhancedResult;
1128
- phase = "enhanced";
1129
- const allWrappers = [
1130
- ...immediateOptions.wrappers || [],
1131
- ...enhancedOptions.wrappers || []
1132
- ].filter(
1133
- (w, i, arr) => (
1134
- // Deduplicate by checking if this is the first occurrence
1135
- arr.findIndex(
1136
- (x) => JSON.stringify(x) === JSON.stringify(w)
1137
- ) === i
1138
- )
1139
- );
1140
- if (allWrappers.length > 0) {
1141
- ;
1142
- currentResult.wrappers = allWrappers;
1143
- }
1144
- currentResult.addresses = collectDataKeys(currentResult);
1145
- }
1146
- } catch (error) {
1147
- console.error("Enhancement failed:", error);
1148
- }
814
+ if (item.standard) {
815
+ return false;
816
+ }
817
+ return true;
818
+ }
819
+ __name(needsEnhancementSingle, "needsEnhancementSingle");
820
+ function needsEnhancement(result) {
821
+ if (needsEnhancementSingle(result)) {
822
+ return true;
823
+ }
824
+ if ("children" in result && Array.isArray(result.children)) {
825
+ return result.children.some((child) => {
826
+ if (child.standard) {
827
+ return false;
1149
828
  }
1150
- }
1151
- const result = {
1152
- ...currentResult,
1153
- phase,
1154
- cached: false,
1155
- timeTaken: Date.now() - startTime
1156
- };
1157
- if (transaction.hash) {
1158
- caches2.setTransaction(transaction.hash, result);
1159
- }
1160
- return result;
1161
- } catch (error) {
1162
- console.error("Failed to decode transaction:", error);
1163
- return {
1164
- ...createErrorResult(transaction),
1165
- phase: "immediate",
1166
- cached: false,
1167
- timeTaken: Date.now() - startTime
1168
- };
829
+ if ("sig" in child && child.sig === "0x") {
830
+ return false;
831
+ }
832
+ return true;
833
+ });
1169
834
  }
835
+ return false;
1170
836
  }
1171
- __name(decodeTransactionSync, "decodeTransactionSync");
1172
- function createErrorResult(transaction) {
1173
- return {
1174
- ...transaction,
1175
- isDecoded: false,
1176
- resultType: "error",
1177
- errorType: "UNKNOWN",
1178
- sig: "0x",
1179
- addresses: []
1180
- };
1181
- }
1182
- __name(createErrorResult, "createErrorResult");
1183
-
1184
- // src/server/decodeTransactionsBatch.ts
1185
- async function decodeTransactionsBatch(transactions, options, caches2) {
1186
- const startTime = Date.now();
1187
- const { timeoutMs = 800, enableEnhancement = true, chain } = options;
1188
- const results = transactions.map((tx) => {
1189
- if (tx.transactionHash) {
1190
- const cached = caches2.getTransaction(tx.transactionHash);
1191
- if (cached) return cached;
1192
- }
1193
- return null;
1194
- });
1195
- const uncachedIndexes = [];
1196
- const uncachedTransactions = [];
1197
- results.forEach((result, index) => {
1198
- if (!result) {
1199
- uncachedIndexes.push(index);
1200
- uncachedTransactions.push(transactions[index]);
1201
- }
1202
- });
1203
- if (uncachedTransactions.length === 0) {
1204
- return {
1205
- results
1206
- };
1207
- }
1208
- try {
1209
- const syncPlugins = await pluginRegistry.getAll({ syncOnly: true });
1210
- const allPlugins = await pluginRegistry.getAll();
1211
- const schemaPlugins = pluginRegistry.getAllSchema();
1212
- const phase1Start = Date.now();
1213
- const immediateOptionsArray = uncachedTransactions.map(() => ({
1214
- chain,
1215
- plugins: syncPlugins,
1216
- schemaPlugins,
1217
- wrappers: [],
1218
- async: false
1219
- }));
1220
- const immediateResults = (await Promise.all(
1221
- uncachedTransactions.map(async (tx, i) => {
1222
- return await decodeTransaction(tx, immediateOptionsArray[i]);
1223
- })
1224
- )).filter(Boolean);
1225
- const newResults = immediateResults.map((result, i) => {
1226
- const data = result || createErrorResult2(uncachedTransactions[i]);
1227
- if (immediateOptionsArray[i].wrappers.length > 0) {
1228
- ;
1229
- data.wrappers = immediateOptionsArray[i].wrappers;
1230
- }
1231
- data.addresses = collectDataKeys(data);
1232
- data.timeTaken = Date.now() - startTime;
1233
- return data;
1234
- }).filter(Boolean);
1235
- const phase1Time = Date.now() - phase1Start;
1236
- if (enableEnhancement && phase1Time < timeoutMs * 0.6) {
1237
- try {
1238
- const enhancedOptionsArray = uncachedTransactions.map(() => ({
1239
- chain,
1240
- plugins: allPlugins,
1241
- schemaPlugins,
1242
- wrappers: [],
1243
- async: true
1244
- }));
1245
- const enhancePromises = uncachedTransactions.map((tx, i) => {
1246
- if (!immediateResults[i]) return null;
1247
- if (!needsEnhancement(immediateResults[i])) {
1248
- return null;
1249
- }
1250
- return decodeTransaction(tx, enhancedOptionsArray[i]);
1251
- });
1252
- const _remainingTime = timeoutMs * 0.6 - phase1Time;
1253
- const enhancedResults = await Promise.all(enhancePromises);
1254
- enhancedResults.forEach((enhanced, i) => {
1255
- if (enhanced) {
1256
- const immediateWrappers = immediateOptionsArray[i].wrappers || [];
1257
- const enhancedWrappers = enhancedOptionsArray[i].wrappers || [];
1258
- const allWrappers = [
1259
- ...immediateWrappers,
1260
- ...enhancedWrappers
1261
- ].filter(
1262
- (w, idx, arr) => (
1263
- // Deduplicate by checking if this is the first occurrence
1264
- arr.findIndex(
1265
- (x) => JSON.stringify(x) === JSON.stringify(w)
1266
- ) === idx
1267
- )
1268
- );
1269
- newResults[i] = enhanced;
1270
- if (allWrappers.length > 0) {
1271
- ;
1272
- newResults[i].wrappers = allWrappers;
1273
- }
1274
- newResults[i].addresses = collectDataKeys(enhanced);
1275
- newResults[i].phase = "enhanced";
1276
- } else if (immediateResults[i] && !needsEnhancement(immediateResults[i])) {
1277
- newResults[i].phase = "enhanced";
1278
- }
1279
- });
1280
- } catch (error) {
1281
- console.error("Batch enhancement failed:", error);
1282
- }
1283
- }
1284
- const totalTime = Date.now() - startTime;
1285
- newResults.forEach((result) => {
1286
- result.timeTaken = totalTime;
1287
- });
1288
- newResults.forEach((result, i) => {
1289
- const tx = uncachedTransactions[i];
1290
- if (tx.hash) {
1291
- caches2.setTransaction(tx.hash, result);
1292
- }
1293
- });
1294
- uncachedIndexes.forEach((originalIndex, i) => {
1295
- results[originalIndex] = newResults[i];
1296
- });
1297
- return {
1298
- results
1299
- };
1300
- } catch (error) {
1301
- console.error("Batch decode failed:", error);
1302
- uncachedIndexes.forEach((originalIndex) => {
1303
- results[originalIndex] = {
1304
- ...createErrorResult2(transactions[originalIndex]),
1305
- phase: "immediate",
1306
- cached: false,
1307
- timeTaken: Date.now() - startTime
1308
- };
1309
- });
1310
- return {
1311
- results
1312
- };
1313
- }
1314
- }
1315
- __name(decodeTransactionsBatch, "decodeTransactionsBatch");
1316
- function createErrorResult2(transaction) {
1317
- return {
1318
- ...transaction,
1319
- isDecoded: false,
1320
- resultType: "error",
1321
- errorType: "UNKNOWN",
1322
- sig: "0x",
1323
- addresses: []
1324
- };
1325
- }
1326
- __name(createErrorResult2, "createErrorResult");
1327
-
1328
- // src/utils/debug.ts
1329
- var debugInstances = /* @__PURE__ */ new Map();
1330
- function createDebug(namespace) {
1331
- const DEBUG = typeof process !== "undefined" && process.env?.DEBUG || "";
1332
- const isEnabled = /* @__PURE__ */ __name(() => {
1333
- if (!DEBUG) return false;
1334
- if (DEBUG === "*") return true;
1335
- const patterns = DEBUG.split(",").map((p) => p.trim());
1336
- for (const pattern of patterns) {
1337
- if (pattern === namespace) return true;
1338
- if (pattern.endsWith("*") && namespace.startsWith(pattern.slice(0, -1)))
1339
- return true;
1340
- if (pattern.startsWith("-")) {
1341
- const negPattern = pattern.slice(1);
1342
- if (negPattern === namespace) return false;
1343
- if (negPattern.endsWith("*") && namespace.startsWith(negPattern.slice(0, -1)))
1344
- return false;
1345
- }
1346
- }
1347
- return false;
1348
- }, "isEnabled");
1349
- debugInstances.set(namespace, isEnabled());
1350
- return (...args) => {
1351
- if (!debugInstances.get(namespace)) return;
1352
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
1353
- const prefix = `[${timestamp}] ${namespace}`;
1354
- console.log(prefix, ...args);
1355
- };
1356
- }
1357
- __name(createDebug, "createDebug");
1358
- var debug_default = createDebug;
1359
-
1360
- // src/server/finishDecoding.ts
1361
- var _debug = createDebug("decoder:finishDecoding");
1362
- async function finishDecoding(transaction, options, caches2) {
1363
- const startTime = Date.now();
1364
- const { chain } = options;
1365
- try {
1366
- const txHash = transaction.hash || transaction.transactionHash;
1367
- if (txHash) {
1368
- const cached = caches2.getTransaction(txHash);
1369
- if (cached?.enhancementAttempted) {
1370
- return {
1371
- ...cached,
1372
- cached: true,
1373
- timeTaken: 0
1374
- };
1375
- }
1376
- }
1377
- const allPlugins = await pluginRegistry.getAll();
1378
- const schemaPlugins = pluginRegistry.getAllSchema();
1379
- const enhancedOptions = {
1380
- chain,
1381
- plugins: allPlugins,
1382
- schemaPlugins,
1383
- wrappers: [],
1384
- async: true
1385
- };
1386
- const {
1387
- wrappers,
1388
- children: _children,
1389
- addresses: _addresses,
1390
- ...transactionWithoutWrappers
1391
- } = transaction;
1392
- const enhancedResult = await decodeTransaction(
1393
- transactionWithoutWrappers,
1394
- enhancedOptions
1395
- );
1396
- if (!enhancedResult) {
1397
- if (txHash) {
1398
- caches2.setTransaction(txHash, {
1399
- ...transaction,
1400
- enhancementAttempted: true
1401
- });
1402
- }
1403
- return transaction;
1404
- }
1405
- const result = {
1406
- ...enhancedResult,
1407
- // Only add wrappers if there are any
1408
- ...(wrappers?.length || 0) > 0 ? { wrappers } : {},
1409
- cached: false,
1410
- timeTaken: Date.now() - startTime,
1411
- enhancementAttempted: true
1412
- };
1413
- if (txHash) {
1414
- caches2.setTransaction(txHash, result);
1415
- }
1416
- return result;
1417
- } catch (error) {
1418
- console.error("Failed to finish decoding transaction:", error);
1419
- return {
1420
- ...createErrorResult3(transaction),
1421
- phase: "immediate",
1422
- cached: false,
1423
- timeTaken: Date.now() - startTime
1424
- };
1425
- }
1426
- }
1427
- __name(finishDecoding, "finishDecoding");
1428
- function createErrorResult3(transaction) {
1429
- return {
1430
- ...transaction,
1431
- resultType: "error",
1432
- errorType: "UNKNOWN",
1433
- sig: "0x",
1434
- addresses: []
1435
- };
1436
- }
1437
- __name(createErrorResult3, "createErrorResult");
837
+ __name(needsEnhancement, "needsEnhancement");
1438
838
 
1439
839
  // src/decoder/plugins/schemaDefault.ts
1440
840
  import {
@@ -1444,9 +844,9 @@ import {
1444
844
  decodeValueContent,
1445
845
  isDynamicKeyName
1446
846
  } from "@erc725/erc725.js";
1447
- import { isHex as isHex2 } from "viem";
847
+ import { isHex } from "viem";
1448
848
 
1449
- // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.1.13/node_modules/@erc725/erc725.js/schemas/LSP1UniversalReceiverDelegate.json
849
+ // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.3.6/node_modules/@erc725/erc725.js/schemas/LSP1UniversalReceiverDelegate.json
1450
850
  var LSP1UniversalReceiverDelegate_default = [
1451
851
  {
1452
852
  name: "LSP1UniversalReceiverDelegate",
@@ -1464,7 +864,7 @@ var LSP1UniversalReceiverDelegate_default = [
1464
864
  }
1465
865
  ];
1466
866
 
1467
- // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.1.13/node_modules/@erc725/erc725.js/schemas/LSP3ProfileMetadata.json
867
+ // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.3.6/node_modules/@erc725/erc725.js/schemas/LSP3ProfileMetadata.json
1468
868
  var LSP3ProfileMetadata_default = [
1469
869
  {
1470
870
  name: "SupportedStandards:LSP3Profile",
@@ -1531,7 +931,7 @@ var LSP3ProfileMetadata_default = [
1531
931
  }
1532
932
  ];
1533
933
 
1534
- // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.1.13/node_modules/@erc725/erc725.js/schemas/LSP4DigitalAsset.json
934
+ // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.3.6/node_modules/@erc725/erc725.js/schemas/LSP4DigitalAsset.json
1535
935
  var LSP4DigitalAsset_default = [
1536
936
  {
1537
937
  name: "SupportedStandards:LSP4DigitalAsset",
@@ -1584,7 +984,7 @@ var LSP4DigitalAsset_default = [
1584
984
  }
1585
985
  ];
1586
986
 
1587
- // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.1.13/node_modules/@erc725/erc725.js/schemas/LSP4DigitalAssetLegacy.json
987
+ // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.3.6/node_modules/@erc725/erc725.js/schemas/LSP4DigitalAssetLegacy.json
1588
988
  var LSP4DigitalAssetLegacy_default = [
1589
989
  {
1590
990
  name: "SupportedStandards:LSP4DigitalCertificate",
@@ -1595,7 +995,7 @@ var LSP4DigitalAssetLegacy_default = [
1595
995
  }
1596
996
  ];
1597
997
 
1598
- // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.1.13/node_modules/@erc725/erc725.js/schemas/LSP5ReceivedAssets.json
998
+ // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.3.6/node_modules/@erc725/erc725.js/schemas/LSP5ReceivedAssets.json
1599
999
  var LSP5ReceivedAssets_default = [
1600
1000
  {
1601
1001
  name: "LSP5ReceivedAssets[]",
@@ -1613,7 +1013,7 @@ var LSP5ReceivedAssets_default = [
1613
1013
  }
1614
1014
  ];
1615
1015
 
1616
- // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.1.13/node_modules/@erc725/erc725.js/schemas/LSP6KeyManager.json
1016
+ // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.3.6/node_modules/@erc725/erc725.js/schemas/LSP6KeyManager.json
1617
1017
  var LSP6KeyManager_default = [
1618
1018
  {
1619
1019
  name: "AddressPermissions[]",
@@ -1645,7 +1045,7 @@ var LSP6KeyManager_default = [
1645
1045
  }
1646
1046
  ];
1647
1047
 
1648
- // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.1.13/node_modules/@erc725/erc725.js/schemas/LSP8IdentifiableDigitalAsset.json
1048
+ // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.3.6/node_modules/@erc725/erc725.js/schemas/LSP8IdentifiableDigitalAsset.json
1649
1049
  var LSP8IdentifiableDigitalAsset_default = [
1650
1050
  {
1651
1051
  name: "LSP8TokenIdFormat",
@@ -1670,7 +1070,7 @@ var LSP8IdentifiableDigitalAsset_default = [
1670
1070
  }
1671
1071
  ];
1672
1072
 
1673
- // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.1.13/node_modules/@erc725/erc725.js/schemas/LSP9Vault.json
1073
+ // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.3.6/node_modules/@erc725/erc725.js/schemas/LSP9Vault.json
1674
1074
  var LSP9Vault_default = [
1675
1075
  {
1676
1076
  name: "SupportedStandards:LSP9Vault",
@@ -1702,7 +1102,7 @@ var LSP9Vault_default = [
1702
1102
  }
1703
1103
  ];
1704
1104
 
1705
- // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.1.13/node_modules/@erc725/erc725.js/schemas/LSP10ReceivedVaults.json
1105
+ // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.3.6/node_modules/@erc725/erc725.js/schemas/LSP10ReceivedVaults.json
1706
1106
  var LSP10ReceivedVaults_default = [
1707
1107
  {
1708
1108
  name: "LSP10VaultsMap:<address>",
@@ -1720,7 +1120,7 @@ var LSP10ReceivedVaults_default = [
1720
1120
  }
1721
1121
  ];
1722
1122
 
1723
- // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.1.13/node_modules/@erc725/erc725.js/schemas/LSP12IssuedAssets.json
1123
+ // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.3.6/node_modules/@erc725/erc725.js/schemas/LSP12IssuedAssets.json
1724
1124
  var LSP12IssuedAssets_default = [
1725
1125
  {
1726
1126
  name: "LSP12IssuedAssets[]",
@@ -1738,7 +1138,7 @@ var LSP12IssuedAssets_default = [
1738
1138
  }
1739
1139
  ];
1740
1140
 
1741
- // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.1.13/node_modules/@erc725/erc725.js/schemas/LSP17ContractExtension.json
1141
+ // ../../node_modules/.pnpm/@erc725+erc725.js@0.28.2_bufferutil@4.0.9_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.3.6/node_modules/@erc725/erc725.js/schemas/LSP17ContractExtension.json
1742
1142
  var LSP17ContractExtension_default = [
1743
1143
  {
1744
1144
  name: "LSP17Extension:<bytes4>",
@@ -2043,7 +1443,7 @@ function decodeKeyValuePlugin(defaultSchema2, process2) {
2043
1443
  let dynamicKeyParts;
2044
1444
  if (isDynamicKeyName(schema.name)) {
2045
1445
  dynamicKeyParts = decodeMappingKey(key, schema).map(
2046
- ({ value: value2 }) => isHex2(value2) ? value2.toLowerCase() : `${value2}`
1446
+ ({ value: value2 }) => isHex(value2) ? value2.toLowerCase() : `${value2}`
2047
1447
  );
2048
1448
  }
2049
1449
  let rawData = value !== "0x" ? decodeData(
@@ -2293,6 +1693,38 @@ function standardPlugin(abi3, pluginOptions, callbacks) {
2293
1693
  }
2294
1694
  __name(standardPlugin, "standardPlugin");
2295
1695
 
1696
+ // src/utils/debug.ts
1697
+ var debugInstances = /* @__PURE__ */ new Map();
1698
+ function createDebug(namespace) {
1699
+ const DEBUG = typeof process !== "undefined" && process.env?.DEBUG || "";
1700
+ const isEnabled = /* @__PURE__ */ __name(() => {
1701
+ if (!DEBUG) return false;
1702
+ if (DEBUG === "*") return true;
1703
+ const patterns = DEBUG.split(",").map((p) => p.trim());
1704
+ for (const pattern of patterns) {
1705
+ if (pattern === namespace) return true;
1706
+ if (pattern.endsWith("*") && namespace.startsWith(pattern.slice(0, -1)))
1707
+ return true;
1708
+ if (pattern.startsWith("-")) {
1709
+ const negPattern = pattern.slice(1);
1710
+ if (negPattern === namespace) return false;
1711
+ if (negPattern.endsWith("*") && namespace.startsWith(negPattern.slice(0, -1)))
1712
+ return false;
1713
+ }
1714
+ }
1715
+ return false;
1716
+ }, "isEnabled");
1717
+ debugInstances.set(namespace, isEnabled());
1718
+ return (...args) => {
1719
+ if (!debugInstances.get(namespace)) return;
1720
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
1721
+ const prefix = `[${timestamp}] ${namespace}`;
1722
+ console.log(prefix, ...args);
1723
+ };
1724
+ }
1725
+ __name(createDebug, "createDebug");
1726
+ var debug_default = createDebug;
1727
+
2296
1728
  // src/decoder/aggregation.ts
2297
1729
  function standardAggregation(config) {
2298
1730
  return Object.freeze(config);
@@ -2309,7 +1741,7 @@ import {
2309
1741
  DecodeLogDataMismatch,
2310
1742
  DecodeLogTopicsMismatch,
2311
1743
  decodeAbiParameters as decodeAbiParameters2,
2312
- size as size2,
1744
+ size,
2313
1745
  toEventSelector
2314
1746
  } from "viem";
2315
1747
  import { formatAbiItem as formatAbiItem2 } from "viem/utils";
@@ -2381,7 +1813,7 @@ function customDecodeEventLog(parameters) {
2381
1813
  abiItem,
2382
1814
  data,
2383
1815
  params: nonIndexedInputs,
2384
- size: size2(data)
1816
+ size: size(data)
2385
1817
  });
2386
1818
  throw err;
2387
1819
  }
@@ -3074,7 +2506,7 @@ __name(enhanceBurntPix, "enhanceBurntPix");
3074
2506
  var enhanceBurntPix_default = enhanceBurntPixPlugin;
3075
2507
 
3076
2508
  // src/decoder/plugins/enhanceGraffiti.ts
3077
- import { bytesToString, hexToBytes, size as size3, slice as slice3 } from "viem";
2509
+ import { bytesToString, hexToBytes, size as size2, slice as slice2 } from "viem";
3078
2510
  var enhanceGraffitiPlugin = Object.freeze({
3079
2511
  enhance: /* @__PURE__ */ __name(async (result, options) => enhanceGraffiti(
3080
2512
  result,
@@ -3088,8 +2520,8 @@ var enhanceGraffitiPlugin = Object.freeze({
3088
2520
  });
3089
2521
  async function enhanceGraffiti(result, _pluginOptions, _options) {
3090
2522
  const { input } = result;
3091
- if (input && size3(input || "0x") >= 4 && slice3(input || "0x", 0, 4) === "0x00000000") {
3092
- let graffiti = slice3(input, 4);
2523
+ if (input && size2(input || "0x") >= 4 && slice2(input || "0x", 0, 4) === "0x00000000") {
2524
+ let graffiti = slice2(input, 4);
3093
2525
  try {
3094
2526
  graffiti = bytesToString(hexToBytes(graffiti));
3095
2527
  } catch {
@@ -3104,13 +2536,154 @@ async function enhanceGraffiti(result, _pluginOptions, _options) {
3104
2536
  __decoder: "grafitti"
3105
2537
  };
3106
2538
  }
3107
- return void 0;
2539
+ return void 0;
2540
+ }
2541
+ __name(enhanceGraffiti, "enhanceGraffiti");
2542
+ var enhanceGraffiti_default = enhanceGraffitiPlugin;
2543
+
2544
+ // src/decoder/plugins/enhanceLSP0ERC725Account.ts
2545
+ import { universalProfileAbi as UniversalProfile } from "@lukso/universalprofile-contracts/abi";
2546
+
2547
+ // src/decoder/transaction.ts
2548
+ import { isAddress, isAddressEqual, slice as slice3, zeroAddress } from "viem";
2549
+ async function decodeTransaction(fullTransaction, options) {
2550
+ const { preferError } = options;
2551
+ const {
2552
+ to,
2553
+ from,
2554
+ value,
2555
+ input: rawInput,
2556
+ data: rawData,
2557
+ ...restTransaction
2558
+ } = fullTransaction;
2559
+ const { logs, ...transaction } = {
2560
+ ...restTransaction,
2561
+ to,
2562
+ from,
2563
+ value,
2564
+ input: rawInput || rawData
2565
+ };
2566
+ const data = rawInput || rawData;
2567
+ if (!data || data === "0x") {
2568
+ if (preferError) {
2569
+ return {
2570
+ ...transaction,
2571
+ isDecoded: true,
2572
+ functionName: void 0,
2573
+ __decoder: void 0,
2574
+ sig: slice3(data || "0x", 0, 4),
2575
+ resultType: "error",
2576
+ errorType: "INVALID" /* INVALID */,
2577
+ ...createNamedArgs([], []),
2578
+ standard: void 0,
2579
+ phase: "enhanced"
2580
+ };
2581
+ }
2582
+ return {
2583
+ ...transaction,
2584
+ isDecoded: true,
2585
+ functionName: void 0,
2586
+ __decoder: void 0,
2587
+ standard: void 0,
2588
+ sig: slice3(data || "0x", 0, 4),
2589
+ ...createNamedArgs([], []),
2590
+ resultType: "execute",
2591
+ phase: "enhanced"
2592
+ };
2593
+ }
2594
+ let _lastError;
2595
+ const activePlugins = options.plugins;
2596
+ for (const plugin of activePlugins) {
2597
+ if (to && isAddress(to) && isAddressEqual(to, zeroAddress)) {
2598
+ return {
2599
+ ...transaction,
2600
+ isDecoded: true,
2601
+ ...createNamedArgs([], []),
2602
+ resultType: "create",
2603
+ to,
2604
+ from,
2605
+ value,
2606
+ logs,
2607
+ phase: "immediate"
2608
+ };
2609
+ }
2610
+ try {
2611
+ const check = await plugin.enhance(transaction, options);
2612
+ if (check) {
2613
+ const output = [];
2614
+ if (logs) {
2615
+ for (const log of logs) {
2616
+ const data2 = await plugin.decodeEvent(log, options);
2617
+ if (data2) {
2618
+ output.push(data2);
2619
+ continue;
2620
+ }
2621
+ let done = false;
2622
+ for (const eventPlugin of activePlugins) {
2623
+ if (eventPlugin !== plugin) {
2624
+ const data3 = await eventPlugin.decodeEvent(log, options);
2625
+ if (data3) {
2626
+ output.push(data3);
2627
+ done = true;
2628
+ break;
2629
+ }
2630
+ }
2631
+ }
2632
+ if (!done) {
2633
+ output.push(log);
2634
+ }
2635
+ }
2636
+ check.logs = output;
2637
+ }
2638
+ let phase2 = plugin.usesAsync || "functionName" in check && check.functionName && check.standard || check.input === "0x" || !check.input ? "enhanced" : "immediate";
2639
+ const resultWithChildren = check;
2640
+ if (phase2 === "enhanced" && resultWithChildren.children && Array.isArray(resultWithChildren.children) && resultWithChildren.children.length > 0) {
2641
+ const allChildrenEnhanced = resultWithChildren.children.every(
2642
+ (child) => child.phase === "enhanced"
2643
+ );
2644
+ if (!allChildrenEnhanced) {
2645
+ phase2 = "immediate";
2646
+ }
2647
+ }
2648
+ const result2 = {
2649
+ ...transaction,
2650
+ ...check,
2651
+ phase: phase2
2652
+ };
2653
+ return result2;
2654
+ }
2655
+ } catch (e) {
2656
+ console.error(e);
2657
+ }
2658
+ }
2659
+ let phase = "functionName" in transaction && transaction.functionName && transaction.standard || transaction.input === "0x" || !transaction.input ? "enhanced" : "immediate";
2660
+ const transactionWithChildren = transaction;
2661
+ if (phase === "enhanced" && transactionWithChildren.children && Array.isArray(transactionWithChildren.children) && transactionWithChildren.children.length > 0) {
2662
+ const allChildrenEnhanced = transactionWithChildren.children.every(
2663
+ (child) => child.phase === "enhanced"
2664
+ );
2665
+ if (!allChildrenEnhanced) {
2666
+ phase = "immediate";
2667
+ }
2668
+ }
2669
+ const result = {
2670
+ ...transaction,
2671
+ standard: void 0,
2672
+ __decoder: void 0,
2673
+ resultType: "raw",
2674
+ phase,
2675
+ sig: slice3(
2676
+ fullTransaction.input || "data" in fullTransaction && fullTransaction.data || "0x",
2677
+ 0,
2678
+ 4
2679
+ ),
2680
+ ...createNamedArgs([], []),
2681
+ ...options.wrappers.length ? { wrappers: options.wrappers } : {},
2682
+ logs
2683
+ };
2684
+ return result;
3108
2685
  }
3109
- __name(enhanceGraffiti, "enhanceGraffiti");
3110
- var enhanceGraffiti_default = enhanceGraffitiPlugin;
3111
-
3112
- // src/decoder/plugins/enhanceLSP0ERC725Account.ts
3113
- import { universalProfileAbi as UniversalProfile } from "@lukso/universalprofile-contracts/abi";
2686
+ __name(decodeTransaction, "decodeTransaction");
3114
2687
 
3115
2688
  // src/decoder/plugins/enhanceSetData.ts
3116
2689
  async function enhanceSetData(result, pluginOptions, options) {
@@ -5171,593 +4744,1062 @@ var abi2 = [
5171
4744
  name: "dataKeys",
5172
4745
  type: "bytes32[]"
5173
4746
  }
5174
- ],
5175
- name: "getDataBatch",
5176
- outputs: [
5177
- {
5178
- internalType: "bytes[]",
5179
- name: "dataValues",
5180
- type: "bytes[]"
4747
+ ],
4748
+ name: "getDataBatch",
4749
+ outputs: [
4750
+ {
4751
+ internalType: "bytes[]",
4752
+ name: "dataValues",
4753
+ type: "bytes[]"
4754
+ }
4755
+ ],
4756
+ stateMutability: "view",
4757
+ type: "function"
4758
+ },
4759
+ {
4760
+ inputs: [],
4761
+ name: "owner",
4762
+ outputs: [
4763
+ {
4764
+ internalType: "address",
4765
+ name: "",
4766
+ type: "address"
4767
+ }
4768
+ ],
4769
+ stateMutability: "view",
4770
+ type: "function"
4771
+ },
4772
+ {
4773
+ inputs: [],
4774
+ name: "pendingOwner",
4775
+ outputs: [
4776
+ {
4777
+ internalType: "address",
4778
+ name: "",
4779
+ type: "address"
4780
+ }
4781
+ ],
4782
+ stateMutability: "view",
4783
+ type: "function"
4784
+ },
4785
+ {
4786
+ inputs: [],
4787
+ name: "renounceOwnership",
4788
+ outputs: [],
4789
+ stateMutability: "nonpayable",
4790
+ type: "function"
4791
+ },
4792
+ {
4793
+ inputs: [
4794
+ {
4795
+ internalType: "bytes32",
4796
+ name: "dataKey",
4797
+ type: "bytes32"
4798
+ },
4799
+ {
4800
+ internalType: "bytes",
4801
+ name: "dataValue",
4802
+ type: "bytes"
4803
+ }
4804
+ ],
4805
+ name: "setData",
4806
+ outputs: [],
4807
+ stateMutability: "payable",
4808
+ type: "function"
4809
+ },
4810
+ {
4811
+ inputs: [
4812
+ {
4813
+ internalType: "bytes32[]",
4814
+ name: "dataKeys",
4815
+ type: "bytes32[]"
4816
+ },
4817
+ {
4818
+ internalType: "bytes[]",
4819
+ name: "dataValues",
4820
+ type: "bytes[]"
4821
+ }
4822
+ ],
4823
+ name: "setDataBatch",
4824
+ outputs: [],
4825
+ stateMutability: "payable",
4826
+ type: "function"
4827
+ },
4828
+ {
4829
+ inputs: [
4830
+ {
4831
+ internalType: "bytes4",
4832
+ name: "interfaceId",
4833
+ type: "bytes4"
4834
+ }
4835
+ ],
4836
+ name: "supportsInterface",
4837
+ outputs: [
4838
+ {
4839
+ internalType: "bool",
4840
+ name: "",
4841
+ type: "bool"
4842
+ }
4843
+ ],
4844
+ stateMutability: "view",
4845
+ type: "function"
4846
+ },
4847
+ {
4848
+ inputs: [
4849
+ {
4850
+ internalType: "address",
4851
+ name: "newOwner",
4852
+ type: "address"
4853
+ }
4854
+ ],
4855
+ name: "transferOwnership",
4856
+ outputs: [],
4857
+ stateMutability: "nonpayable",
4858
+ type: "function"
4859
+ },
4860
+ {
4861
+ inputs: [
4862
+ {
4863
+ internalType: "bytes32",
4864
+ name: "typeId",
4865
+ type: "bytes32"
4866
+ },
4867
+ {
4868
+ internalType: "bytes",
4869
+ name: "receivedData",
4870
+ type: "bytes"
4871
+ }
4872
+ ],
4873
+ name: "universalReceiver",
4874
+ outputs: [
4875
+ {
4876
+ internalType: "bytes",
4877
+ name: "returnedValues",
4878
+ type: "bytes"
4879
+ }
4880
+ ],
4881
+ stateMutability: "payable",
4882
+ type: "function"
4883
+ },
4884
+ {
4885
+ stateMutability: "payable",
4886
+ type: "receive"
4887
+ }
4888
+ ];
4889
+
4890
+ // src/decoder/functionSignature.ts
4891
+ import {
4892
+ decodeAbiParameters as decodeAbiParameters4,
4893
+ encodeAbiParameters as encodeAbiParameters2,
4894
+ getAddress as getAddress2,
4895
+ isAddress as isAddress2,
4896
+ isAddressEqual as isAddressEqual2,
4897
+ parseAbiParameters,
4898
+ zeroAddress as zeroAddress2
4899
+ } from "viem";
4900
+
4901
+ // src/decoder/lruCache.ts
4902
+ import { LRUCache as LRUCache3 } from "lru-cache";
4903
+ var LRUDecoderCache = class {
4904
+ static {
4905
+ __name(this, "LRUDecoderCache");
4906
+ }
4907
+ cache;
4908
+ promises;
4909
+ defaultTTL;
4910
+ defaultErrorTTL;
4911
+ defaultStaleWhileRevalidate;
4912
+ constructor(options = {}) {
4913
+ this.defaultTTL = options.ttl ?? 5 * 60 * 1e3;
4914
+ this.defaultErrorTTL = options.errorTTL ?? 30 * 1e3;
4915
+ this.defaultStaleWhileRevalidate = options.staleWhileRevalidate;
4916
+ this.cache = new LRUCache3({
4917
+ max: options.max ?? 1e3
4918
+ });
4919
+ this.promises = /* @__PURE__ */ new Map();
4920
+ }
4921
+ async get(key) {
4922
+ const entry = this.cache.get(key);
4923
+ if (!entry) {
4924
+ return void 0;
4925
+ }
4926
+ if (entry.expires && Date.now() > entry.expires) {
4927
+ this.cache.delete(key);
4928
+ return void 0;
4929
+ }
4930
+ return entry;
4931
+ }
4932
+ async set(key, value, options) {
4933
+ const now = Date.now();
4934
+ const ttl = options?.ttl ?? (options?.errorTTL ? options.errorTTL : this.defaultTTL);
4935
+ const isError = options?.errorTTL !== void 0;
4936
+ const entry = {
4937
+ value,
4938
+ expires: now + ttl,
4939
+ isError
4940
+ };
4941
+ const staleWhileRevalidate = options?.staleWhileRevalidate ?? this.defaultStaleWhileRevalidate;
4942
+ if (staleWhileRevalidate) {
4943
+ entry.stale = now + ttl + staleWhileRevalidate;
4944
+ }
4945
+ this.cache.set(key, entry);
4946
+ }
4947
+ async delete(key) {
4948
+ this.cache.delete(key);
4949
+ }
4950
+ async getMany(keys) {
4951
+ const result = /* @__PURE__ */ new Map();
4952
+ for (const key of keys) {
4953
+ const entry = await this.get(key);
4954
+ if (entry) {
4955
+ result.set(key, entry);
4956
+ }
4957
+ }
4958
+ return result;
4959
+ }
4960
+ async setMany(entries) {
4961
+ for (const { key, value, options } of entries) {
4962
+ await this.set(key, value, options);
4963
+ }
4964
+ }
4965
+ async clear() {
4966
+ this.cache.clear();
4967
+ this.promises.clear();
4968
+ }
4969
+ async getOrSet(key, factory, options) {
4970
+ const cached = await this.get(key);
4971
+ const now = Date.now();
4972
+ if (cached && (!cached.expires || now < cached.expires)) {
4973
+ return cached.value;
4974
+ }
4975
+ if (cached?.stale && now < cached.stale && !this.promises.has(key)) {
4976
+ const backgroundPromise = factory(options?.signal).then(async (fresh) => {
4977
+ await this.set(key, fresh, options);
4978
+ return fresh;
4979
+ }).catch(() => {
4980
+ return cached.value;
4981
+ }).finally(() => {
4982
+ this.promises.delete(key);
4983
+ });
4984
+ this.promises.set(key, backgroundPromise);
4985
+ return cached.value;
4986
+ }
4987
+ const existingPromise = this.promises.get(key);
4988
+ if (existingPromise) {
4989
+ return existingPromise;
4990
+ }
4991
+ const promise = factory(options?.signal).then(async (value) => {
4992
+ await this.set(key, value, options);
4993
+ return value;
4994
+ }).catch(async (error) => {
4995
+ await this.set(key, error, {
4996
+ ...options,
4997
+ ttl: options?.errorTTL ?? this.defaultErrorTTL,
4998
+ errorTTL: options?.errorTTL ?? this.defaultErrorTTL
4999
+ });
5000
+ throw error;
5001
+ }).finally(() => {
5002
+ this.promises.delete(key);
5003
+ });
5004
+ this.promises.set(key, promise);
5005
+ return promise;
5006
+ }
5007
+ };
5008
+ function createLRUCache(options) {
5009
+ return new LRUDecoderCache(options);
5010
+ }
5011
+ __name(createLRUCache, "createLRUCache");
5012
+
5013
+ // src/decoder/functionSignature.ts
5014
+ var defaultCache = createLRUCache({
5015
+ max: 500,
5016
+ ttl: 60 * 1e3,
5017
+ // 1 minute
5018
+ errorTTL: 30 * 1e3
5019
+ // 30 seconds
5020
+ });
5021
+ function generateNamedAbiParameters(signature) {
5022
+ const start = signature.indexOf("(");
5023
+ const end = signature.lastIndexOf(")");
5024
+ if (start === -1 || end === -1 || end <= start) {
5025
+ throw new Error(`Invalid signature: ${signature}`);
5026
+ }
5027
+ const paramString = signature.slice(start + 1, end);
5028
+ const rawParams = parseAbiParameters(paramString);
5029
+ const assignNames = /* @__PURE__ */ __name((params, prefix) => {
5030
+ return params.map((param, index) => {
5031
+ const name = `${prefix}${index + 1}`;
5032
+ if (param.type === "tuple" && "components" in param) {
5033
+ const components = assignNames(
5034
+ param.components,
5035
+ `${name}_`
5036
+ );
5037
+ return { ...param, name, components };
5038
+ }
5039
+ return { ...param, name };
5040
+ });
5041
+ }, "assignNames");
5042
+ return assignNames(rawParams, "arg");
5043
+ }
5044
+ __name(generateNamedAbiParameters, "generateNamedAbiParameters");
5045
+ async function fetchAbi(chain, address, options) {
5046
+ const explorer = chain.blockExplorers?.default?.apiUrl;
5047
+ if (!explorer) return void 0;
5048
+ const cache = options?.cache ?? defaultCache;
5049
+ let key = getAddress2(address);
5050
+ const cacheKey = makeCacheKey("abi" /* ABI */, key, String(chain.id));
5051
+ return cache.getOrSet(
5052
+ cacheKey,
5053
+ async (signal) => {
5054
+ let isProxy = false;
5055
+ let decoderVerifiedContract = false;
5056
+ let factoryName;
5057
+ const _originalKey = key;
5058
+ const addressUrl = new URL(`/api/v2/addresses/${key}`, explorer);
5059
+ const addressRes = await fetch(addressUrl, { signal });
5060
+ if (addressRes.ok) {
5061
+ const data = await addressRes.json();
5062
+ const {
5063
+ implementations: [
5064
+ { address: _address, address_hash: _addressHash } = {}
5065
+ ] = [],
5066
+ is_contract,
5067
+ is_verified: __decoderVerifiedContract,
5068
+ proxy_type,
5069
+ name: __factoryName
5070
+ } = data;
5071
+ const address2 = _address || _addressHash;
5072
+ factoryName = __factoryName;
5073
+ decoderVerifiedContract = Boolean(__decoderVerifiedContract || false);
5074
+ if (address2 && is_contract && proxy_type !== "null" && proxy_type != null) {
5075
+ key = address2;
5076
+ isProxy = true;
5077
+ }
5181
5078
  }
5182
- ],
5183
- stateMutability: "view",
5184
- type: "function"
5185
- },
5186
- {
5187
- inputs: [],
5188
- name: "owner",
5189
- outputs: [
5190
- {
5191
- internalType: "address",
5192
- name: "",
5193
- type: "address"
5079
+ if (!decoderVerifiedContract) {
5080
+ return void 0;
5194
5081
  }
5195
- ],
5196
- stateMutability: "view",
5197
- type: "function"
5198
- },
5199
- {
5200
- inputs: [],
5201
- name: "pendingOwner",
5202
- outputs: [
5203
- {
5204
- internalType: "address",
5205
- name: "",
5206
- type: "address"
5082
+ const url = new URL(`/api/v2/smart-contracts/${key}`, explorer);
5083
+ const res = await fetch(url, { signal });
5084
+ if (!res.ok) {
5085
+ return void 0;
5207
5086
  }
5208
- ],
5209
- stateMutability: "view",
5210
- type: "function"
5211
- },
5212
- {
5213
- inputs: [],
5214
- name: "renounceOwnership",
5215
- outputs: [],
5216
- stateMutability: "nonpayable",
5217
- type: "function"
5218
- },
5219
- {
5220
- inputs: [
5221
- {
5222
- internalType: "bytes32",
5223
- name: "dataKey",
5224
- type: "bytes32"
5225
- },
5226
- {
5227
- internalType: "bytes",
5228
- name: "dataValue",
5229
- type: "bytes"
5087
+ const result = await res.json();
5088
+ const {
5089
+ name = factoryName || "UnknownName",
5090
+ abi: abi3,
5091
+ is_verified
5092
+ } = result || {};
5093
+ if (abi3 && is_verified) {
5094
+ return {
5095
+ abi: abi3,
5096
+ __decoderVerifiedContract: decoderVerifiedContract,
5097
+ // If we have an ABI, treat it as verified
5098
+ __decoderIsProxy: isProxy,
5099
+ name,
5100
+ explorer
5101
+ };
5230
5102
  }
5231
- ],
5232
- name: "setData",
5233
- outputs: [],
5234
- stateMutability: "payable",
5235
- type: "function"
5236
- },
5237
- {
5238
- inputs: [
5239
- {
5240
- internalType: "bytes32[]",
5241
- name: "dataKeys",
5242
- type: "bytes32[]"
5243
- },
5244
- {
5245
- internalType: "bytes[]",
5246
- name: "dataValues",
5247
- type: "bytes[]"
5103
+ return void 0;
5104
+ },
5105
+ { signal: options?.signal }
5106
+ );
5107
+ }
5108
+ __name(fetchAbi, "fetchAbi");
5109
+ var getFunctionSignature = /* @__PURE__ */ __name(async (chain, input, to, preferError = false, options) => {
5110
+ if (to && isAddress2(to) && isAddressEqual2(to, zeroAddress2)) {
5111
+ return {
5112
+ __decoder: "none",
5113
+ standard: "unknown",
5114
+ to,
5115
+ input,
5116
+ resultType: "raw"
5117
+ };
5118
+ }
5119
+ const data = input?.slice(2);
5120
+ const selector = data.slice(0, 8);
5121
+ if (selector) {
5122
+ if (to) {
5123
+ const info = await fetchAbi(chain, to, options);
5124
+ if (info) {
5125
+ const decoded = customDecodeFunctionData({
5126
+ abi: info.abi,
5127
+ data: input || "0x"
5128
+ });
5129
+ if (decoded) {
5130
+ return {
5131
+ ...decoded,
5132
+ __decoder: info.explorer,
5133
+ __decoderVerifiedContract: info.__decoderVerifiedContract,
5134
+ __decoderIsProxy: info.__decoderIsProxy,
5135
+ standard: info.name
5136
+ };
5137
+ }
5248
5138
  }
5249
- ],
5250
- name: "setDataBatch",
5251
- outputs: [],
5252
- stateMutability: "payable",
5253
- type: "function"
5254
- },
5255
- {
5256
- inputs: [
5257
- {
5258
- internalType: "bytes4",
5259
- name: "interfaceId",
5260
- type: "bytes4"
5139
+ }
5140
+ const cache = options?.cache ?? defaultCache;
5141
+ const cacheKey = makeCacheKey("sig" /* FUNCTION_SIGNATURE */, selector);
5142
+ const signatureEntry = cache.getOrSet(
5143
+ cacheKey,
5144
+ async (signal) => {
5145
+ const url = `${OPENCHAIN_DICTIONARY_URL}?function=0x${selector}`;
5146
+ let __decoder = new URL(OPENCHAIN_DICTIONARY_URL).hostname;
5147
+ try {
5148
+ const res = await fetch(url, { signal });
5149
+ if (res.ok) {
5150
+ const result = await res.json();
5151
+ if (result) {
5152
+ result.__decoder = __decoder;
5153
+ return result;
5154
+ }
5155
+ }
5156
+ } catch {
5157
+ }
5158
+ __decoder = new URL(FUNCTION_DICTIONARY_URL).hostname;
5159
+ const fallbackRes = await fetch(
5160
+ `${FUNCTION_DICTIONARY_URL}/${selector}`,
5161
+ { signal }
5162
+ );
5163
+ if (!fallbackRes.ok) {
5164
+ return void 0;
5165
+ }
5166
+ const fallbackResult = await fallbackRes.json();
5167
+ if (fallbackResult) {
5168
+ fallbackResult.__decoder = __decoder;
5169
+ }
5170
+ return fallbackResult;
5171
+ },
5172
+ { signal: options?.signal }
5173
+ );
5174
+ const methods = await signatureEntry;
5175
+ if (methods?.results?.length > 0) {
5176
+ let search = methods.results.reverse();
5177
+ if (preferError) {
5178
+ const withError = search.filter(
5179
+ (result) => /Error/.test(result.text_signature)
5180
+ );
5181
+ const withoutError = search.filter(
5182
+ (result) => !/Error/.test(result.text_signature)
5183
+ );
5184
+ search = [...withError, ...withoutError];
5261
5185
  }
5262
- ],
5263
- name: "supportsInterface",
5264
- outputs: [
5265
- {
5266
- internalType: "bool",
5267
- name: "",
5268
- type: "bool"
5186
+ for (const result of search) {
5187
+ try {
5188
+ const params = generateNamedAbiParameters(
5189
+ result.text_signature || result.name
5190
+ );
5191
+ const args = decodeAbiParameters4(params, `0x${data.slice(8)}`);
5192
+ const encodeArgs = Array.from({ length: params.length }).map(
5193
+ (_val, index) => {
5194
+ if (params[index].type === "bool") {
5195
+ const val = args[`${index}`];
5196
+ if (val !== 1 && val !== 0 && val !== true && val !== false) {
5197
+ throw new Error("Invalid boolean value");
5198
+ }
5199
+ }
5200
+ if (params[index].type === "address") {
5201
+ const val = args[`${index}`];
5202
+ if (!isAddress2(val)) {
5203
+ throw new Error(`Invalid address value ${val}`);
5204
+ }
5205
+ }
5206
+ return args[`${index}`] ?? "0x";
5207
+ }
5208
+ );
5209
+ const newData = encodeAbiParameters2(
5210
+ params,
5211
+ encodeArgs
5212
+ ).slice(2);
5213
+ if (data.slice(8) === newData) {
5214
+ return {
5215
+ resultType: "execute",
5216
+ standard: "unknown",
5217
+ sig: `0x${selector}`,
5218
+ functionName: result.text_signature.replace(/\(.*$/, ""),
5219
+ ...args ? {
5220
+ ...createNamedArgs(encodeArgs, params)
5221
+ } : {},
5222
+ __decoder: methods.__decoder || FUNCTION_DICTIONARY_URL
5223
+ };
5224
+ }
5225
+ } catch (_error) {
5226
+ }
5269
5227
  }
5270
- ],
5271
- stateMutability: "view",
5272
- type: "function"
5273
- },
5228
+ }
5229
+ }
5230
+ return void 0;
5231
+ }, "getFunctionSignature");
5232
+
5233
+ // src/decoder/plugins/enhanceRetrieveAbi.ts
5234
+ var enhanceRetrieveAbiPlugin = standardPlugin(
5235
+ abi2,
5274
5236
  {
5275
- inputs: [
5276
- {
5277
- internalType: "address",
5278
- name: "newOwner",
5279
- type: "address"
5280
- }
5281
- ],
5282
- name: "transferOwnership",
5283
- outputs: [],
5284
- stateMutability: "nonpayable",
5285
- type: "function"
5237
+ abiName: "Internal",
5238
+ decoderName: "explorer",
5239
+ name: "abiRetrieve",
5240
+ usesAsync: true,
5241
+ priority: 0
5286
5242
  },
5287
5243
  {
5288
- inputs: [
5289
- {
5290
- internalType: "bytes32",
5291
- name: "typeId",
5292
- type: "bytes32"
5293
- },
5294
- {
5295
- internalType: "bytes",
5296
- name: "receivedData",
5297
- type: "bytes"
5244
+ enhance: /* @__PURE__ */ __name(async () => {
5245
+ return void 0;
5246
+ }, "enhance"),
5247
+ overrideEnhance: enhanceRetrieveAbi,
5248
+ decodeEvent: /* @__PURE__ */ __name(async (log, options) => {
5249
+ if (!log) {
5250
+ return void 0;
5298
5251
  }
5299
- ],
5300
- name: "universalReceiver",
5301
- outputs: [
5302
- {
5303
- internalType: "bytes",
5304
- name: "returnedValues",
5305
- type: "bytes"
5252
+ const info = await fetchAbi(options.chain, log.address);
5253
+ if (info) {
5254
+ const result = decodeEvent(options.chain, info.abi, log);
5255
+ if (result) {
5256
+ return { ...result, __decoder: info.explorer };
5257
+ }
5306
5258
  }
5307
- ],
5308
- stateMutability: "payable",
5309
- type: "function"
5310
- },
5311
- {
5312
- stateMutability: "payable",
5313
- type: "receive"
5259
+ return void 0;
5260
+ }, "decodeEvent")
5314
5261
  }
5315
- ];
5316
-
5317
- // src/decoder/functionSignature.ts
5318
- import {
5319
- decodeAbiParameters as decodeAbiParameters4,
5320
- encodeAbiParameters as encodeAbiParameters2,
5321
- getAddress as getAddress2,
5322
- isAddress as isAddress2,
5323
- isAddressEqual as isAddressEqual2,
5324
- parseAbiParameters,
5325
- zeroAddress as zeroAddress2
5326
- } from "viem";
5327
-
5328
- // src/decoder/lruCache.ts
5329
- import { LRUCache as LRUCache3 } from "lru-cache";
5330
- var LRUDecoderCache = class {
5331
- static {
5332
- __name(this, "LRUDecoderCache");
5262
+ );
5263
+ async function enhanceRetrieveAbi(result, _pluginOptions, options) {
5264
+ const { input, to, from, value } = result;
5265
+ try {
5266
+ const decoded = await getFunctionSignature(
5267
+ options.chain,
5268
+ input,
5269
+ to || void 0,
5270
+ options.preferError
5271
+ );
5272
+ if (decoded) {
5273
+ return {
5274
+ ...result,
5275
+ ...decoded,
5276
+ resultType: "execute",
5277
+ to,
5278
+ from,
5279
+ value,
5280
+ input
5281
+ };
5282
+ }
5283
+ } catch {
5333
5284
  }
5334
- cache;
5335
- promises;
5336
- defaultTTL;
5337
- defaultErrorTTL;
5338
- defaultStaleWhileRevalidate;
5339
- constructor(options = {}) {
5340
- this.defaultTTL = options.ttl ?? 5 * 60 * 1e3;
5341
- this.defaultErrorTTL = options.errorTTL ?? 30 * 1e3;
5342
- this.defaultStaleWhileRevalidate = options.staleWhileRevalidate;
5343
- this.cache = new LRUCache3({
5344
- max: options.max ?? 1e3
5345
- });
5346
- this.promises = /* @__PURE__ */ new Map();
5285
+ return void 0;
5286
+ }
5287
+ __name(enhanceRetrieveAbi, "enhanceRetrieveAbi");
5288
+ var enhanceRetrieveAbi_default = enhanceRetrieveAbiPlugin;
5289
+
5290
+ // src/decoder/plugins/index.ts
5291
+ [enhanceLSP0ERC725Account_default, enhanceLSP6KeyManager_default, enhanceLSP7DigitalAsset_default, enhanceLSP8IdentifiableDigitalAsset_default, enhanceLSP9Vault_default, enhanceLSP26FollowerSystem_default, enhanceBurntPix_default].forEach((p) => {
5292
+ p;
5293
+ });
5294
+ var defaultPlugins = Object.freeze([
5295
+ enhanceGraffiti_default,
5296
+ enhanceLSP6KeyManager_default,
5297
+ enhanceLSP0ERC725Account_default,
5298
+ enhanceLSP7DigitalAsset_default,
5299
+ enhanceLSP8IdentifiableDigitalAsset_default,
5300
+ enhanceLSP9Vault_default,
5301
+ enhanceLSP26FollowerSystem_default,
5302
+ enhanceRetrieveAbi_default,
5303
+ enhanceBurntPix_default
5304
+ ]);
5305
+ var defaultSchemaPlugins = Object.freeze([
5306
+ schemaDefault_default
5307
+ ]);
5308
+ async function decodeKeyValueRaw(key, value, options) {
5309
+ for (const schemaPlugin of options.schemaPlugins) {
5310
+ try {
5311
+ const output = await schemaPlugin(key, value);
5312
+ if (output) {
5313
+ return output;
5314
+ }
5315
+ } catch {
5316
+ }
5347
5317
  }
5348
- async get(key) {
5349
- const entry = this.cache.get(key);
5350
- if (!entry) {
5351
- return void 0;
5318
+ return void 0;
5319
+ }
5320
+ __name(decodeKeyValueRaw, "decodeKeyValueRaw");
5321
+ pluginRegistry.register("graffiti", enhanceGraffiti_default, {
5322
+ priority: 100,
5323
+ required: false
5324
+ });
5325
+ pluginRegistry.register("abiRetrieve", enhanceRetrieveAbi_default, {
5326
+ priority: 1,
5327
+ required: false,
5328
+ usesAsync: true
5329
+ });
5330
+ pluginRegistry.registerSchema("default-schema", schemaDefault_default, {
5331
+ priority: 100,
5332
+ required: false
5333
+ });
5334
+
5335
+ // src/server/decodeEventLogs.ts
5336
+ async function decodeEventLogs(logs, options, _caches) {
5337
+ const { chain } = options;
5338
+ const plugins = await pluginRegistry.getAll({ syncOnly: true });
5339
+ const schemaPlugins = pluginRegistry.getAllSchema();
5340
+ const decoderOptions = {
5341
+ chain,
5342
+ plugins,
5343
+ schemaPlugins,
5344
+ wrappers: [],
5345
+ async: false
5346
+ };
5347
+ const results = [];
5348
+ for (const log of logs) {
5349
+ let decoded;
5350
+ for (const plugin of plugins) {
5351
+ decoded = await plugin.decodeEvent(log, decoderOptions);
5352
+ if (decoded) break;
5352
5353
  }
5353
- if (entry.expires && Date.now() > entry.expires) {
5354
- this.cache.delete(key);
5355
- return void 0;
5354
+ const result = decoded ?? log;
5355
+ if (result?.eventName === "DataChanged" && result.args) {
5356
+ try {
5357
+ const dataKey = result.args.find((a) => a.name === "dataKey")?.value;
5358
+ const dataValue = result.args.find((a) => a.name === "dataValue")?.value;
5359
+ if (dataKey) {
5360
+ const info = await decodeKeyValueRaw(
5361
+ dataKey,
5362
+ dataValue ?? "0x",
5363
+ decoderOptions
5364
+ );
5365
+ if (info) {
5366
+ ;
5367
+ result.info = info;
5368
+ }
5369
+ }
5370
+ } catch {
5371
+ }
5356
5372
  }
5357
- return entry;
5373
+ results.push(result);
5358
5374
  }
5359
- async set(key, value, options) {
5360
- const now = Date.now();
5361
- const ttl = options?.ttl ?? (options?.errorTTL ? options.errorTTL : this.defaultTTL);
5362
- const isError = options?.errorTTL !== void 0;
5363
- const entry = {
5364
- value,
5365
- expires: now + ttl,
5366
- isError
5367
- };
5368
- const staleWhileRevalidate = options?.staleWhileRevalidate ?? this.defaultStaleWhileRevalidate;
5369
- if (staleWhileRevalidate) {
5370
- entry.stale = now + ttl + staleWhileRevalidate;
5375
+ return results;
5376
+ }
5377
+ __name(decodeEventLogs, "decodeEventLogs");
5378
+
5379
+ // src/core/addressCollector.ts
5380
+ import { isHex as isHex2, size as size3 } from "viem";
5381
+ function collectDataKeys(data, skipGqlTypes = true, existingKeys) {
5382
+ const addresses = /* @__PURE__ */ new Set();
5383
+ if (existingKeys) {
5384
+ for (const key of existingKeys) {
5385
+ if (typeof key === "string") {
5386
+ addresses.add(key);
5387
+ } else {
5388
+ addresses.add(JSON.stringify(key));
5389
+ }
5371
5390
  }
5372
- this.cache.set(key, entry);
5373
- }
5374
- async delete(key) {
5375
- this.cache.delete(key);
5376
5391
  }
5377
- async getMany(keys) {
5378
- const result = /* @__PURE__ */ new Map();
5379
- for (const key of keys) {
5380
- const entry = await this.get(key);
5381
- if (entry) {
5382
- result.set(key, entry);
5392
+ function collectLSP8Tokens(obj) {
5393
+ if (obj.standard !== "LSP8IdentifiableDigitalAsset" || !obj.to || !obj.args) {
5394
+ return;
5395
+ }
5396
+ const contractAddress = obj.to;
5397
+ const args = obj.args;
5398
+ const tokenId = getArgByName(args, "tokenId");
5399
+ if (tokenId && tokenId !== null && tokenId !== "0x") {
5400
+ addresses.add(`${contractAddress}:${tokenId}`);
5401
+ }
5402
+ const tokenIds = getArgByName(args, "tokenIds");
5403
+ if (Array.isArray(tokenIds)) {
5404
+ for (const tokenId2 of tokenIds) {
5405
+ if (tokenId2 && tokenId2 !== null && tokenId2 !== "0x") {
5406
+ addresses.add(`${contractAddress}:${tokenId2}`);
5407
+ }
5383
5408
  }
5384
5409
  }
5385
- return result;
5386
5410
  }
5387
- async setMany(entries) {
5388
- for (const { key, value, options } of entries) {
5389
- await this.set(key, value, options);
5411
+ __name(collectLSP8Tokens, "collectLSP8Tokens");
5412
+ function collect(obj, parent, visited = /* @__PURE__ */ new WeakSet(), path = []) {
5413
+ if (obj && typeof obj === "object" && visited.has(obj)) {
5414
+ return;
5390
5415
  }
5391
- }
5392
- async clear() {
5393
- this.cache.clear();
5394
- this.promises.clear();
5395
- }
5396
- async getOrSet(key, factory, options) {
5397
- const cached = await this.get(key);
5398
- const now = Date.now();
5399
- if (cached && (!cached.expires || now < cached.expires)) {
5400
- return cached.value;
5416
+ if (obj && typeof obj === "object") {
5417
+ visited.add(obj);
5401
5418
  }
5402
- if (cached?.stale && now < cached.stale && !this.promises.has(key)) {
5403
- const backgroundPromise = factory(options?.signal).then(async (fresh) => {
5404
- await this.set(key, fresh, options);
5405
- return fresh;
5406
- }).catch(() => {
5407
- return cached.value;
5408
- }).finally(() => {
5409
- this.promises.delete(key);
5410
- });
5411
- this.promises.set(key, backgroundPromise);
5412
- return cached.value;
5419
+ if (typeof obj === "string" && obj.startsWith("0x")) {
5420
+ if (obj.includes(":")) {
5421
+ const [addressPart, tokenIdPart] = obj.split(":");
5422
+ if (addressPart.startsWith("0x") && tokenIdPart.startsWith("0x") && isHex2(addressPart) && size3(addressPart) === 20) {
5423
+ addresses.add(obj);
5424
+ return;
5425
+ }
5426
+ }
5427
+ const isPaddedAddress = /^0x0*([a-fA-F0-9]{40})$/.test(obj);
5428
+ if (isPaddedAddress || isHex2(obj) && size3(obj) === 20) {
5429
+ if (parent && skipGqlTypes && "__gqltype" in parent) {
5430
+ return;
5431
+ }
5432
+ const address = isPaddedAddress ? obj.replace(/^0x0*([a-fA-F0-9]{40})$/, "0x$1") : obj;
5433
+ if (address.slice(2).split("").filter((c) => c === "0").length > 10) {
5434
+ return;
5435
+ }
5436
+ addresses.add(address);
5437
+ }
5438
+ return;
5413
5439
  }
5414
- const existingPromise = this.promises.get(key);
5415
- if (existingPromise) {
5416
- return existingPromise;
5440
+ if (!obj || typeof obj !== "object") return;
5441
+ if (Array.isArray(obj)) {
5442
+ for (let i = 0; i < obj.length; i++) {
5443
+ collect(obj[i], parent, visited, [...path, `[${i}]`]);
5444
+ }
5445
+ } else {
5446
+ const record = obj;
5447
+ if ("standard" in record && "to" in record && "args" in record) {
5448
+ collectLSP8Tokens(record);
5449
+ }
5450
+ for (const [key, value] of Object.entries(record)) {
5451
+ collect(value, record, visited, [...path, key]);
5452
+ }
5417
5453
  }
5418
- const promise = factory(options?.signal).then(async (value) => {
5419
- await this.set(key, value, options);
5420
- return value;
5421
- }).catch(async (error) => {
5422
- await this.set(key, error, {
5423
- ...options,
5424
- ttl: options?.errorTTL ?? this.defaultErrorTTL,
5425
- errorTTL: options?.errorTTL ?? this.defaultErrorTTL
5426
- });
5427
- throw error;
5428
- }).finally(() => {
5429
- this.promises.delete(key);
5430
- });
5431
- this.promises.set(key, promise);
5432
- return promise;
5433
5454
  }
5434
- };
5435
- function createLRUCache(options) {
5436
- return new LRUDecoderCache(options);
5455
+ __name(collect, "collect");
5456
+ collect(data);
5457
+ return Array.from(addresses);
5437
5458
  }
5438
- __name(createLRUCache, "createLRUCache");
5459
+ __name(collectDataKeys, "collectDataKeys");
5439
5460
 
5440
- // src/decoder/functionSignature.ts
5441
- var defaultCache = createLRUCache({
5442
- max: 500,
5443
- ttl: 60 * 1e3,
5444
- // 1 minute
5445
- errorTTL: 30 * 1e3
5446
- // 30 seconds
5447
- });
5448
- function generateNamedAbiParameters(signature) {
5449
- const start = signature.indexOf("(");
5450
- const end = signature.lastIndexOf(")");
5451
- if (start === -1 || end === -1 || end <= start) {
5452
- throw new Error(`Invalid signature: ${signature}`);
5461
+ // src/server/decodeTransactionSync.ts
5462
+ async function decodeTransactionSync(transaction, options, caches2) {
5463
+ const startTime = Date.now();
5464
+ const { timeoutMs = 800, enableEnhancement = true, chain } = options;
5465
+ if (transaction.hash) {
5466
+ const cached = caches2.getTransaction(transaction.hash);
5467
+ if (cached) {
5468
+ return cached;
5469
+ }
5453
5470
  }
5454
- const paramString = signature.slice(start + 1, end);
5455
- const rawParams = parseAbiParameters(paramString);
5456
- const assignNames = /* @__PURE__ */ __name((params, prefix) => {
5457
- return params.map((param, index) => {
5458
- const name = `${prefix}${index + 1}`;
5459
- if (param.type === "tuple" && "components" in param) {
5460
- const components = assignNames(
5461
- param.components,
5462
- `${name}_`
5463
- );
5464
- return { ...param, name, components };
5465
- }
5466
- return { ...param, name };
5467
- });
5468
- }, "assignNames");
5469
- return assignNames(rawParams, "arg");
5470
- }
5471
- __name(generateNamedAbiParameters, "generateNamedAbiParameters");
5472
- async function fetchAbi(chain, address, options) {
5473
- const explorer = chain.blockExplorers?.default?.apiUrl;
5474
- if (!explorer) return void 0;
5475
- const cache = options?.cache ?? defaultCache;
5476
- let key = getAddress2(address);
5477
- const cacheKey = makeCacheKey("abi" /* ABI */, key, String(chain.id));
5478
- return cache.getOrSet(
5479
- cacheKey,
5480
- async (signal) => {
5481
- let isProxy = false;
5482
- let decoderVerifiedContract = false;
5483
- let factoryName;
5484
- const _originalKey = key;
5485
- const addressUrl = new URL(`/api/v2/addresses/${key}`, explorer);
5486
- const addressRes = await fetch(addressUrl, { signal });
5487
- if (addressRes.ok) {
5488
- const data = await addressRes.json();
5489
- const {
5490
- implementations: [
5491
- { address: _address, address_hash: _addressHash } = {}
5492
- ] = [],
5493
- is_contract,
5494
- is_verified: __decoderVerifiedContract,
5495
- proxy_type,
5496
- name: __factoryName
5497
- } = data;
5498
- const address2 = _address || _addressHash;
5499
- factoryName = __factoryName;
5500
- decoderVerifiedContract = Boolean(__decoderVerifiedContract || false);
5501
- if (address2 && is_contract && proxy_type !== "null" && proxy_type != null) {
5502
- key = address2;
5503
- isProxy = true;
5471
+ try {
5472
+ const phase1Start = Date.now();
5473
+ const plugins = await pluginRegistry.getAll({ syncOnly: true });
5474
+ const schemaPlugins = pluginRegistry.getAllSchema();
5475
+ const immediateOptions = {
5476
+ chain,
5477
+ plugins,
5478
+ schemaPlugins,
5479
+ wrappers: [],
5480
+ async: false
5481
+ };
5482
+ const immediateResult = await decodeTransaction(
5483
+ transaction,
5484
+ immediateOptions
5485
+ );
5486
+ if (!immediateResult) {
5487
+ return {
5488
+ ...createErrorResult(transaction),
5489
+ phase: "immediate",
5490
+ cached: false,
5491
+ timeTaken: Date.now() - startTime
5492
+ };
5493
+ }
5494
+ let currentResult = immediateResult;
5495
+ let phase = "immediate";
5496
+ if (immediateOptions.wrappers.length > 0) {
5497
+ ;
5498
+ currentResult.wrappers = immediateOptions.wrappers;
5499
+ }
5500
+ const addresses = collectDataKeys(currentResult);
5501
+ currentResult.addresses = addresses;
5502
+ const phase1Time = Date.now() - phase1Start;
5503
+ if (enableEnhancement && phase1Time < timeoutMs * 0.6) {
5504
+ if (!needsEnhancement(currentResult)) {
5505
+ phase = "enhanced";
5506
+ } else {
5507
+ try {
5508
+ const allPlugins = await pluginRegistry.getAll();
5509
+ const enhancedOptions = {
5510
+ chain,
5511
+ plugins: allPlugins,
5512
+ schemaPlugins,
5513
+ wrappers: [],
5514
+ async: true
5515
+ };
5516
+ const enhancedResult = await Promise.race([
5517
+ decodeTransaction(transaction, enhancedOptions),
5518
+ // Timeout for phase 2
5519
+ new Promise(
5520
+ (resolve) => setTimeout(() => resolve(null), timeoutMs * 0.6 - phase1Time)
5521
+ )
5522
+ ]);
5523
+ if (enhancedResult) {
5524
+ currentResult = enhancedResult;
5525
+ phase = "enhanced";
5526
+ const allWrappers = [
5527
+ ...immediateOptions.wrappers || [],
5528
+ ...enhancedOptions.wrappers || []
5529
+ ].filter(
5530
+ (w, i, arr) => (
5531
+ // Deduplicate by checking if this is the first occurrence
5532
+ arr.findIndex(
5533
+ (x) => JSON.stringify(x) === JSON.stringify(w)
5534
+ ) === i
5535
+ )
5536
+ );
5537
+ if (allWrappers.length > 0) {
5538
+ ;
5539
+ currentResult.wrappers = allWrappers;
5540
+ }
5541
+ currentResult.addresses = collectDataKeys(currentResult);
5542
+ }
5543
+ } catch (error) {
5544
+ console.error("Enhancement failed:", error);
5504
5545
  }
5505
5546
  }
5506
- if (!decoderVerifiedContract) {
5507
- return void 0;
5508
- }
5509
- const url = new URL(`/api/v2/smart-contracts/${key}`, explorer);
5510
- const res = await fetch(url, { signal });
5511
- if (!res.ok) {
5512
- return void 0;
5513
- }
5514
- const result = await res.json();
5515
- const {
5516
- name = factoryName || "UnknownName",
5517
- abi: abi3,
5518
- is_verified
5519
- } = result || {};
5520
- if (abi3 && is_verified) {
5521
- return {
5522
- abi: abi3,
5523
- __decoderVerifiedContract: decoderVerifiedContract,
5524
- // If we have an ABI, treat it as verified
5525
- __decoderIsProxy: isProxy,
5526
- name,
5527
- explorer
5528
- };
5529
- }
5530
- return void 0;
5531
- },
5532
- { signal: options?.signal }
5533
- );
5547
+ }
5548
+ const result = {
5549
+ ...currentResult,
5550
+ phase,
5551
+ cached: false,
5552
+ timeTaken: Date.now() - startTime
5553
+ };
5554
+ if (transaction.hash) {
5555
+ caches2.setTransaction(transaction.hash, result);
5556
+ }
5557
+ return result;
5558
+ } catch (error) {
5559
+ console.error("Failed to decode transaction:", error);
5560
+ return {
5561
+ ...createErrorResult(transaction),
5562
+ phase: "immediate",
5563
+ cached: false,
5564
+ timeTaken: Date.now() - startTime
5565
+ };
5566
+ }
5534
5567
  }
5535
- __name(fetchAbi, "fetchAbi");
5536
- var getFunctionSignature = /* @__PURE__ */ __name(async (chain, input, to, preferError = false, options) => {
5537
- if (to && isAddress2(to) && isAddressEqual2(to, zeroAddress2)) {
5568
+ __name(decodeTransactionSync, "decodeTransactionSync");
5569
+ function createErrorResult(transaction) {
5570
+ return {
5571
+ ...transaction,
5572
+ isDecoded: false,
5573
+ resultType: "error",
5574
+ errorType: "UNKNOWN",
5575
+ sig: "0x",
5576
+ addresses: []
5577
+ };
5578
+ }
5579
+ __name(createErrorResult, "createErrorResult");
5580
+
5581
+ // src/server/decodeTransactionsBatch.ts
5582
+ async function decodeTransactionsBatch(transactions, options, caches2) {
5583
+ const startTime = Date.now();
5584
+ const { timeoutMs = 800, enableEnhancement = true, chain } = options;
5585
+ const results = transactions.map((tx) => {
5586
+ if (tx.transactionHash) {
5587
+ const cached = caches2.getTransaction(tx.transactionHash);
5588
+ if (cached) return cached;
5589
+ }
5590
+ return null;
5591
+ });
5592
+ const uncachedIndexes = [];
5593
+ const uncachedTransactions = [];
5594
+ results.forEach((result, index) => {
5595
+ if (!result) {
5596
+ uncachedIndexes.push(index);
5597
+ uncachedTransactions.push(transactions[index]);
5598
+ }
5599
+ });
5600
+ if (uncachedTransactions.length === 0) {
5538
5601
  return {
5539
- __decoder: "none",
5540
- standard: "unknown",
5541
- to,
5542
- input,
5543
- resultType: "raw"
5602
+ results
5544
5603
  };
5545
5604
  }
5546
- const data = input?.slice(2);
5547
- const selector = data.slice(0, 8);
5548
- if (selector) {
5549
- if (to) {
5550
- const info = await fetchAbi(chain, to, options);
5551
- if (info) {
5552
- const decoded = customDecodeFunctionData({
5553
- abi: info.abi,
5554
- data: input || "0x"
5555
- });
5556
- if (decoded) {
5557
- return {
5558
- ...decoded,
5559
- __decoder: info.explorer,
5560
- __decoderVerifiedContract: info.__decoderVerifiedContract,
5561
- __decoderIsProxy: info.__decoderIsProxy,
5562
- standard: info.name
5563
- };
5564
- }
5605
+ try {
5606
+ const syncPlugins = await pluginRegistry.getAll({ syncOnly: true });
5607
+ const allPlugins = await pluginRegistry.getAll();
5608
+ const schemaPlugins = pluginRegistry.getAllSchema();
5609
+ const phase1Start = Date.now();
5610
+ const immediateOptionsArray = uncachedTransactions.map(() => ({
5611
+ chain,
5612
+ plugins: syncPlugins,
5613
+ schemaPlugins,
5614
+ wrappers: [],
5615
+ async: false
5616
+ }));
5617
+ const immediateResults = (await Promise.all(
5618
+ uncachedTransactions.map(async (tx, i) => {
5619
+ return await decodeTransaction(tx, immediateOptionsArray[i]);
5620
+ })
5621
+ )).filter(Boolean);
5622
+ const newResults = immediateResults.map((result, i) => {
5623
+ const data = result || createErrorResult2(uncachedTransactions[i]);
5624
+ if (immediateOptionsArray[i].wrappers.length > 0) {
5625
+ ;
5626
+ data.wrappers = immediateOptionsArray[i].wrappers;
5565
5627
  }
5566
- }
5567
- const cache = options?.cache ?? defaultCache;
5568
- const cacheKey = makeCacheKey("sig" /* FUNCTION_SIGNATURE */, selector);
5569
- const signatureEntry = cache.getOrSet(
5570
- cacheKey,
5571
- async (signal) => {
5572
- const url = `${OPENCHAIN_DICTIONARY_URL}?function=0x${selector}`;
5573
- let __decoder = new URL(OPENCHAIN_DICTIONARY_URL).hostname;
5574
- try {
5575
- const res = await fetch(url, { signal });
5576
- if (res.ok) {
5577
- const result = await res.json();
5578
- if (result) {
5579
- result.__decoder = __decoder;
5580
- return result;
5581
- }
5628
+ data.addresses = collectDataKeys(data);
5629
+ data.timeTaken = Date.now() - startTime;
5630
+ return data;
5631
+ }).filter(Boolean);
5632
+ const phase1Time = Date.now() - phase1Start;
5633
+ if (enableEnhancement && phase1Time < timeoutMs * 0.6) {
5634
+ try {
5635
+ const enhancedOptionsArray = uncachedTransactions.map(() => ({
5636
+ chain,
5637
+ plugins: allPlugins,
5638
+ schemaPlugins,
5639
+ wrappers: [],
5640
+ async: true
5641
+ }));
5642
+ const enhancePromises = uncachedTransactions.map((tx, i) => {
5643
+ if (!immediateResults[i]) return null;
5644
+ if (!needsEnhancement(immediateResults[i])) {
5645
+ return null;
5582
5646
  }
5583
- } catch {
5584
- }
5585
- __decoder = new URL(FUNCTION_DICTIONARY_URL).hostname;
5586
- const fallbackRes = await fetch(
5587
- `${FUNCTION_DICTIONARY_URL}/${selector}`,
5588
- { signal }
5589
- );
5590
- if (!fallbackRes.ok) {
5591
- return void 0;
5592
- }
5593
- const fallbackResult = await fallbackRes.json();
5594
- if (fallbackResult) {
5595
- fallbackResult.__decoder = __decoder;
5596
- }
5597
- return fallbackResult;
5598
- },
5599
- { signal: options?.signal }
5600
- );
5601
- const methods = await signatureEntry;
5602
- if (methods?.results?.length > 0) {
5603
- let search = methods.results.reverse();
5604
- if (preferError) {
5605
- const withError = search.filter(
5606
- (result) => /Error/.test(result.text_signature)
5607
- );
5608
- const withoutError = search.filter(
5609
- (result) => !/Error/.test(result.text_signature)
5610
- );
5611
- search = [...withError, ...withoutError];
5612
- }
5613
- for (const result of search) {
5614
- try {
5615
- const params = generateNamedAbiParameters(
5616
- result.text_signature || result.name
5617
- );
5618
- const args = decodeAbiParameters4(params, `0x${data.slice(8)}`);
5619
- const encodeArgs = Array.from({ length: params.length }).map(
5620
- (_val, index) => {
5621
- if (params[index].type === "bool") {
5622
- const val = args[`${index}`];
5623
- if (val !== 1 && val !== 0 && val !== true && val !== false) {
5624
- throw new Error("Invalid boolean value");
5625
- }
5626
- }
5627
- if (params[index].type === "address") {
5628
- const val = args[`${index}`];
5629
- if (!isAddress2(val)) {
5630
- throw new Error(`Invalid address value ${val}`);
5631
- }
5632
- }
5633
- return args[`${index}`] ?? "0x";
5647
+ return decodeTransaction(tx, enhancedOptionsArray[i]);
5648
+ });
5649
+ const _remainingTime = timeoutMs * 0.6 - phase1Time;
5650
+ const enhancedResults = await Promise.all(enhancePromises);
5651
+ enhancedResults.forEach((enhanced, i) => {
5652
+ if (enhanced) {
5653
+ const immediateWrappers = immediateOptionsArray[i].wrappers || [];
5654
+ const enhancedWrappers = enhancedOptionsArray[i].wrappers || [];
5655
+ const allWrappers = [
5656
+ ...immediateWrappers,
5657
+ ...enhancedWrappers
5658
+ ].filter(
5659
+ (w, idx, arr) => (
5660
+ // Deduplicate by checking if this is the first occurrence
5661
+ arr.findIndex(
5662
+ (x) => JSON.stringify(x) === JSON.stringify(w)
5663
+ ) === idx
5664
+ )
5665
+ );
5666
+ newResults[i] = enhanced;
5667
+ if (allWrappers.length > 0) {
5668
+ ;
5669
+ newResults[i].wrappers = allWrappers;
5634
5670
  }
5635
- );
5636
- const newData = encodeAbiParameters2(
5637
- params,
5638
- encodeArgs
5639
- ).slice(2);
5640
- if (data.slice(8) === newData) {
5641
- return {
5642
- resultType: "execute",
5643
- standard: "unknown",
5644
- sig: `0x${selector}`,
5645
- functionName: result.text_signature.replace(/\(.*$/, ""),
5646
- ...args ? {
5647
- ...createNamedArgs(encodeArgs, params)
5648
- } : {},
5649
- __decoder: methods.__decoder || FUNCTION_DICTIONARY_URL
5650
- };
5671
+ newResults[i].addresses = collectDataKeys(enhanced);
5672
+ newResults[i].phase = "enhanced";
5673
+ } else if (immediateResults[i] && !needsEnhancement(immediateResults[i])) {
5674
+ newResults[i].phase = "enhanced";
5651
5675
  }
5652
- } catch (_error) {
5653
- }
5676
+ });
5677
+ } catch (error) {
5678
+ console.error("Batch enhancement failed:", error);
5654
5679
  }
5655
5680
  }
5656
- }
5657
- return void 0;
5658
- }, "getFunctionSignature");
5659
-
5660
- // src/decoder/plugins/enhanceRetrieveAbi.ts
5661
- var enhanceRetrieveAbiPlugin = standardPlugin(
5662
- abi2,
5663
- {
5664
- abiName: "Internal",
5665
- decoderName: "explorer",
5666
- name: "abiRetrieve",
5667
- usesAsync: true,
5668
- priority: 0
5669
- },
5670
- {
5671
- enhance: /* @__PURE__ */ __name(async () => {
5672
- return void 0;
5673
- }, "enhance"),
5674
- overrideEnhance: enhanceRetrieveAbi,
5675
- decodeEvent: /* @__PURE__ */ __name(async (log, options) => {
5676
- if (!log) {
5677
- return void 0;
5678
- }
5679
- const info = await fetchAbi(options.chain, log.address);
5680
- if (info) {
5681
- const result = decodeEvent(options.chain, info.abi, log);
5682
- if (result) {
5683
- return { ...result, __decoder: info.explorer };
5684
- }
5681
+ const totalTime = Date.now() - startTime;
5682
+ newResults.forEach((result) => {
5683
+ result.timeTaken = totalTime;
5684
+ });
5685
+ newResults.forEach((result, i) => {
5686
+ const tx = uncachedTransactions[i];
5687
+ if (tx.hash) {
5688
+ caches2.setTransaction(tx.hash, result);
5685
5689
  }
5686
- return void 0;
5687
- }, "decodeEvent")
5688
- }
5689
- );
5690
- async function enhanceRetrieveAbi(result, _pluginOptions, options) {
5691
- const { input, to, from, value } = result;
5692
- try {
5693
- const decoded = await getFunctionSignature(
5694
- options.chain,
5695
- input,
5696
- to || void 0,
5697
- options.preferError
5698
- );
5699
- if (decoded) {
5700
- return {
5701
- ...result,
5702
- ...decoded,
5703
- resultType: "execute",
5704
- to,
5705
- from,
5706
- value,
5707
- input
5690
+ });
5691
+ uncachedIndexes.forEach((originalIndex, i) => {
5692
+ results[originalIndex] = newResults[i];
5693
+ });
5694
+ return {
5695
+ results
5696
+ };
5697
+ } catch (error) {
5698
+ console.error("Batch decode failed:", error);
5699
+ uncachedIndexes.forEach((originalIndex) => {
5700
+ results[originalIndex] = {
5701
+ ...createErrorResult2(transactions[originalIndex]),
5702
+ phase: "immediate",
5703
+ cached: false,
5704
+ timeTaken: Date.now() - startTime
5708
5705
  };
5709
- }
5710
- } catch {
5706
+ });
5707
+ return {
5708
+ results
5709
+ };
5711
5710
  }
5712
- return void 0;
5713
5711
  }
5714
- __name(enhanceRetrieveAbi, "enhanceRetrieveAbi");
5715
- var enhanceRetrieveAbi_default = enhanceRetrieveAbiPlugin;
5712
+ __name(decodeTransactionsBatch, "decodeTransactionsBatch");
5713
+ function createErrorResult2(transaction) {
5714
+ return {
5715
+ ...transaction,
5716
+ isDecoded: false,
5717
+ resultType: "error",
5718
+ errorType: "UNKNOWN",
5719
+ sig: "0x",
5720
+ addresses: []
5721
+ };
5722
+ }
5723
+ __name(createErrorResult2, "createErrorResult");
5716
5724
 
5717
- // src/decoder/plugins/index.ts
5718
- [enhanceLSP0ERC725Account_default, enhanceLSP6KeyManager_default, enhanceLSP7DigitalAsset_default, enhanceLSP8IdentifiableDigitalAsset_default, enhanceLSP9Vault_default, enhanceLSP26FollowerSystem_default, enhanceBurntPix_default].forEach((p) => {
5719
- p;
5720
- });
5721
- var defaultPlugins = Object.freeze([
5722
- enhanceGraffiti_default,
5723
- enhanceLSP6KeyManager_default,
5724
- enhanceLSP0ERC725Account_default,
5725
- enhanceLSP7DigitalAsset_default,
5726
- enhanceLSP8IdentifiableDigitalAsset_default,
5727
- enhanceLSP9Vault_default,
5728
- enhanceLSP26FollowerSystem_default,
5729
- enhanceRetrieveAbi_default,
5730
- enhanceBurntPix_default
5731
- ]);
5732
- var defaultSchemaPlugins = Object.freeze([
5733
- schemaDefault_default
5734
- ]);
5735
- async function decodeKeyValueRaw(key, value, options) {
5736
- for (const schemaPlugin of options.schemaPlugins) {
5737
- try {
5738
- const output = await schemaPlugin(key, value);
5739
- if (output) {
5740
- return output;
5725
+ // src/server/finishDecoding.ts
5726
+ var _debug = createDebug("decoder:finishDecoding");
5727
+ async function finishDecoding(transaction, options, caches2) {
5728
+ const startTime = Date.now();
5729
+ const { chain } = options;
5730
+ try {
5731
+ const txHash = transaction.hash || transaction.transactionHash;
5732
+ if (txHash) {
5733
+ const cached = caches2.getTransaction(txHash);
5734
+ if (cached?.enhancementAttempted) {
5735
+ return {
5736
+ ...cached,
5737
+ cached: true,
5738
+ timeTaken: 0
5739
+ };
5741
5740
  }
5742
- } catch {
5743
5741
  }
5742
+ const allPlugins = await pluginRegistry.getAll();
5743
+ const schemaPlugins = pluginRegistry.getAllSchema();
5744
+ const enhancedOptions = {
5745
+ chain,
5746
+ plugins: allPlugins,
5747
+ schemaPlugins,
5748
+ wrappers: [],
5749
+ async: true
5750
+ };
5751
+ const {
5752
+ wrappers,
5753
+ children: _children,
5754
+ addresses: _addresses,
5755
+ ...transactionWithoutWrappers
5756
+ } = transaction;
5757
+ const enhancedResult = await decodeTransaction(
5758
+ transactionWithoutWrappers,
5759
+ enhancedOptions
5760
+ );
5761
+ if (!enhancedResult) {
5762
+ if (txHash) {
5763
+ caches2.setTransaction(txHash, {
5764
+ ...transaction,
5765
+ enhancementAttempted: true
5766
+ });
5767
+ }
5768
+ return transaction;
5769
+ }
5770
+ const result = {
5771
+ ...enhancedResult,
5772
+ // Only add wrappers if there are any
5773
+ ...(wrappers?.length || 0) > 0 ? { wrappers } : {},
5774
+ cached: false,
5775
+ timeTaken: Date.now() - startTime,
5776
+ enhancementAttempted: true
5777
+ };
5778
+ if (txHash) {
5779
+ caches2.setTransaction(txHash, result);
5780
+ }
5781
+ return result;
5782
+ } catch (error) {
5783
+ console.error("Failed to finish decoding transaction:", error);
5784
+ return {
5785
+ ...createErrorResult3(transaction),
5786
+ phase: "immediate",
5787
+ cached: false,
5788
+ timeTaken: Date.now() - startTime
5789
+ };
5744
5790
  }
5745
- return void 0;
5746
5791
  }
5747
- __name(decodeKeyValueRaw, "decodeKeyValueRaw");
5748
- pluginRegistry.register("graffiti", enhanceGraffiti_default, {
5749
- priority: 100,
5750
- required: false
5751
- });
5752
- pluginRegistry.register("abiRetrieve", enhanceRetrieveAbi_default, {
5753
- priority: 1,
5754
- required: false,
5755
- usesAsync: true
5756
- });
5757
- pluginRegistry.registerSchema("default-schema", schemaDefault_default, {
5758
- priority: 100,
5759
- required: false
5760
- });
5792
+ __name(finishDecoding, "finishDecoding");
5793
+ function createErrorResult3(transaction) {
5794
+ return {
5795
+ ...transaction,
5796
+ resultType: "error",
5797
+ errorType: "UNKNOWN",
5798
+ sig: "0x",
5799
+ addresses: []
5800
+ };
5801
+ }
5802
+ __name(createErrorResult3, "createErrorResult");
5761
5803
 
5762
5804
  // src/server/index.ts
5763
5805
  function createServerDecoder(config) {
@@ -5808,6 +5850,14 @@ function createServerDecoder(config) {
5808
5850
  },
5809
5851
  async resolveAddresses(addresses, timeoutMs = 3e3) {
5810
5852
  return addressResolver.resolveAddressesWithTimeout(addresses, timeoutMs);
5853
+ },
5854
+ async decodeEventLogs(logs, options) {
5855
+ const opts = {
5856
+ chain: config.defaultChain,
5857
+ timeoutMs: config.defaultTimeout,
5858
+ ...options
5859
+ };
5860
+ return decodeEventLogs(logs, opts, caches2);
5811
5861
  }
5812
5862
  };
5813
5863
  }
@@ -5816,6 +5866,7 @@ export {
5816
5866
  ServerAddressResolver,
5817
5867
  ServerDecoderCaches,
5818
5868
  createServerDecoder,
5869
+ decodeEventLogs,
5819
5870
  decodeTransactionSync,
5820
5871
  decodeTransactionsBatch
5821
5872
  };