@lukso/transaction-decoder 1.3.7-dev.2df3eae → 1.3.7-dev.30530d6

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,6 +547,196 @@ 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
+
550
740
  // src/decoder/registry.ts
551
741
  var PluginRegistry = class {
552
742
  static {
@@ -730,123 +920,533 @@ Object.freeze(PluginRegistry.prototype);
730
920
  Object.freeze(PluginRegistry);
731
921
  var pluginRegistry = new PluginRegistry();
732
922
 
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;
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
+ };
763
957
  }
764
- return result;
765
- } catch {
766
- }
767
- }
768
- __name(customDecodeFunctionData, "customDecodeFunctionData");
769
- function createNamedArgs(args, inputs) {
770
- const array = args.map((value, index) => {
771
958
  return {
772
- name: `args${index + 1}`,
773
- ...inputs?.[index],
774
- value
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"
775
968
  };
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");
791
969
  }
792
- if (!clients[id]) {
793
- clients[id] = createPublicClient({
794
- chain,
795
- transport: http(),
796
- batch: {
797
- multicall: {
798
- batchSize: 100
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
+ }
799
1023
  }
1024
+ const result2 = {
1025
+ ...transaction,
1026
+ ...check,
1027
+ phase: phase2
1028
+ };
1029
+ return result2;
800
1030
  }
801
- });
1031
+ } catch (e) {
1032
+ console.error(e);
1033
+ }
802
1034
  }
803
- const result = clients[id];
804
- if (!result) {
805
- throw new Error(`Public client for chain ID ${id} not found`);
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
+ }
806
1044
  }
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
+ };
807
1060
  return result;
808
1061
  }
809
- __name(getPublicClient, "getPublicClient");
810
- function needsEnhancementSingle(item) {
811
- if ("sig" in item && item.sig === "0x") {
812
- return false;
813
- }
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;
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
+ }
823
1073
  }
824
- if ("children" in result && Array.isArray(result.children)) {
825
- return result.children.some((child) => {
826
- if (child.standard) {
827
- return false;
828
- }
829
- if ("sig" in child && child.sig === "0x") {
830
- return false;
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
+ }
831
1149
  }
832
- return true;
833
- });
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
+ };
834
1169
  }
835
- return false;
836
1170
  }
837
- __name(needsEnhancement, "needsEnhancement");
838
-
839
- // src/decoder/plugins/schemaDefault.ts
840
- import {
841
- decodeData,
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");
1438
+
1439
+ // src/decoder/plugins/schemaDefault.ts
1440
+ import {
1441
+ decodeData,
842
1442
  decodeMappingKey,
843
1443
  decodePermissions,
844
1444
  decodeValueContent,
845
1445
  isDynamicKeyName
846
1446
  } from "@erc725/erc725.js";
847
- import { isHex } from "viem";
1447
+ import { isHex as isHex2 } from "viem";
848
1448
 
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
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
850
1450
  var LSP1UniversalReceiverDelegate_default = [
851
1451
  {
852
1452
  name: "LSP1UniversalReceiverDelegate",
@@ -864,7 +1464,7 @@ var LSP1UniversalReceiverDelegate_default = [
864
1464
  }
865
1465
  ];
866
1466
 
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
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
868
1468
  var LSP3ProfileMetadata_default = [
869
1469
  {
870
1470
  name: "SupportedStandards:LSP3Profile",
@@ -931,7 +1531,7 @@ var LSP3ProfileMetadata_default = [
931
1531
  }
932
1532
  ];
933
1533
 
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
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
935
1535
  var LSP4DigitalAsset_default = [
936
1536
  {
937
1537
  name: "SupportedStandards:LSP4DigitalAsset",
@@ -984,7 +1584,7 @@ var LSP4DigitalAsset_default = [
984
1584
  }
985
1585
  ];
986
1586
 
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
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
988
1588
  var LSP4DigitalAssetLegacy_default = [
989
1589
  {
990
1590
  name: "SupportedStandards:LSP4DigitalCertificate",
@@ -995,7 +1595,7 @@ var LSP4DigitalAssetLegacy_default = [
995
1595
  }
996
1596
  ];
997
1597
 
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
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
999
1599
  var LSP5ReceivedAssets_default = [
1000
1600
  {
1001
1601
  name: "LSP5ReceivedAssets[]",
@@ -1013,7 +1613,7 @@ var LSP5ReceivedAssets_default = [
1013
1613
  }
1014
1614
  ];
1015
1615
 
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
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
1017
1617
  var LSP6KeyManager_default = [
1018
1618
  {
1019
1619
  name: "AddressPermissions[]",
@@ -1045,7 +1645,7 @@ var LSP6KeyManager_default = [
1045
1645
  }
1046
1646
  ];
1047
1647
 
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
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
1049
1649
  var LSP8IdentifiableDigitalAsset_default = [
1050
1650
  {
1051
1651
  name: "LSP8TokenIdFormat",
@@ -1070,7 +1670,7 @@ var LSP8IdentifiableDigitalAsset_default = [
1070
1670
  }
1071
1671
  ];
1072
1672
 
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
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
1074
1674
  var LSP9Vault_default = [
1075
1675
  {
1076
1676
  name: "SupportedStandards:LSP9Vault",
@@ -1102,7 +1702,7 @@ var LSP9Vault_default = [
1102
1702
  }
1103
1703
  ];
1104
1704
 
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
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
1106
1706
  var LSP10ReceivedVaults_default = [
1107
1707
  {
1108
1708
  name: "LSP10VaultsMap:<address>",
@@ -1120,7 +1720,7 @@ var LSP10ReceivedVaults_default = [
1120
1720
  }
1121
1721
  ];
1122
1722
 
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
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
1124
1724
  var LSP12IssuedAssets_default = [
1125
1725
  {
1126
1726
  name: "LSP12IssuedAssets[]",
@@ -1138,7 +1738,7 @@ var LSP12IssuedAssets_default = [
1138
1738
  }
1139
1739
  ];
1140
1740
 
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
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
1142
1742
  var LSP17ContractExtension_default = [
1143
1743
  {
1144
1744
  name: "LSP17Extension:<bytes4>",
@@ -1443,7 +2043,7 @@ function decodeKeyValuePlugin(defaultSchema2, process2) {
1443
2043
  let dynamicKeyParts;
1444
2044
  if (isDynamicKeyName(schema.name)) {
1445
2045
  dynamicKeyParts = decodeMappingKey(key, schema).map(
1446
- ({ value: value2 }) => isHex(value2) ? value2.toLowerCase() : `${value2}`
2046
+ ({ value: value2 }) => isHex2(value2) ? value2.toLowerCase() : `${value2}`
1447
2047
  );
1448
2048
  }
1449
2049
  let rawData = value !== "0x" ? decodeData(
@@ -1693,38 +2293,6 @@ function standardPlugin(abi3, pluginOptions, callbacks) {
1693
2293
  }
1694
2294
  __name(standardPlugin, "standardPlugin");
1695
2295
 
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
-
1728
2296
  // src/decoder/aggregation.ts
1729
2297
  function standardAggregation(config) {
1730
2298
  return Object.freeze(config);
@@ -1741,7 +2309,7 @@ import {
1741
2309
  DecodeLogDataMismatch,
1742
2310
  DecodeLogTopicsMismatch,
1743
2311
  decodeAbiParameters as decodeAbiParameters2,
1744
- size,
2312
+ size as size2,
1745
2313
  toEventSelector
1746
2314
  } from "viem";
1747
2315
  import { formatAbiItem as formatAbiItem2 } from "viem/utils";
@@ -1813,7 +2381,7 @@ function customDecodeEventLog(parameters) {
1813
2381
  abiItem,
1814
2382
  data,
1815
2383
  params: nonIndexedInputs,
1816
- size: size(data)
2384
+ size: size2(data)
1817
2385
  });
1818
2386
  throw err;
1819
2387
  }
@@ -2467,223 +3035,82 @@ var refineAggregation = standardAggregation({
2467
3035
  count: state.count,
2468
3036
  from: stats.map(({ address }) => address),
2469
3037
  tokens: stats.flatMap(({ tokens }) => tokens),
2470
- blockRange: {
2471
- from: state.minBlock,
2472
- to: state.maxBlock
2473
- }
2474
- }
2475
- };
2476
- }, "finalize")
2477
- });
2478
- var enhanceBurntPixPlugin = standardPlugin(
2479
- RegistryAbi_default,
2480
- {
2481
- name: "burntpix",
2482
- abiName: "BurntPix",
2483
- decoderName: "@lukso/burntpix",
2484
- priority: 50
2485
- },
2486
- {
2487
- enhance: enhanceBurntPix,
2488
- decodeEvent: /* @__PURE__ */ __name(async (log, options) => {
2489
- return decodeEvent(options.chain, RegistryAbi_default, log);
2490
- }, "decodeEvent"),
2491
- aggregations: [refineAggregation]
2492
- }
2493
- );
2494
- async function enhanceBurntPix(result, pluginOptions, _options) {
2495
- if ("functionName" in result && result.functionName === "refine") {
2496
- return {
2497
- ...result,
2498
- standard: pluginOptions.abiName,
2499
- __decoder: pluginOptions.decoderName,
2500
- aggregationKeys: [createAggregationKey(pluginOptions, "refine")]
2501
- };
2502
- }
2503
- return void 0;
2504
- }
2505
- __name(enhanceBurntPix, "enhanceBurntPix");
2506
- var enhanceBurntPix_default = enhanceBurntPixPlugin;
2507
-
2508
- // src/decoder/plugins/enhanceGraffiti.ts
2509
- import { bytesToString, hexToBytes, size as size2, slice as slice2 } from "viem";
2510
- var enhanceGraffitiPlugin = Object.freeze({
2511
- enhance: /* @__PURE__ */ __name(async (result, options) => enhanceGraffiti(
2512
- result,
2513
- { abiName: "graffiti", decoderName: "graffiti" },
2514
- options
2515
- ), "enhance"),
2516
- decodeEvent: /* @__PURE__ */ __name(async (_log, _options) => void 0, "decodeEvent"),
2517
- required: true,
2518
- priority: 1e3,
2519
- name: "graffiti"
2520
- });
2521
- async function enhanceGraffiti(result, _pluginOptions, _options) {
2522
- const { input } = result;
2523
- if (input && size2(input || "0x") >= 4 && slice2(input || "0x", 0, 4) === "0x00000000") {
2524
- let graffiti = slice2(input, 4);
2525
- try {
2526
- graffiti = bytesToString(hexToBytes(graffiti));
2527
- } catch {
2528
- }
2529
- return {
2530
- ...result,
2531
- resultType: "grafitti",
2532
- sig: "0x",
2533
- functionName: "",
2534
- input,
2535
- graffiti,
2536
- __decoder: "grafitti"
2537
- };
2538
- }
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;
3038
+ blockRange: {
3039
+ from: state.minBlock,
3040
+ to: state.maxBlock
3041
+ }
2654
3042
  }
2655
- } catch (e) {
2656
- console.error(e);
2657
- }
3043
+ };
3044
+ }, "finalize")
3045
+ });
3046
+ var enhanceBurntPixPlugin = standardPlugin(
3047
+ RegistryAbi_default,
3048
+ {
3049
+ name: "burntpix",
3050
+ abiName: "BurntPix",
3051
+ decoderName: "@lukso/burntpix",
3052
+ priority: 50
3053
+ },
3054
+ {
3055
+ enhance: enhanceBurntPix,
3056
+ decodeEvent: /* @__PURE__ */ __name(async (log, options) => {
3057
+ return decodeEvent(options.chain, RegistryAbi_default, log);
3058
+ }, "decodeEvent"),
3059
+ aggregations: [refineAggregation]
2658
3060
  }
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";
3061
+ );
3062
+ async function enhanceBurntPix(result, pluginOptions, _options) {
3063
+ if ("functionName" in result && result.functionName === "refine") {
3064
+ return {
3065
+ ...result,
3066
+ standard: pluginOptions.abiName,
3067
+ __decoder: pluginOptions.decoderName,
3068
+ aggregationKeys: [createAggregationKey(pluginOptions, "refine")]
3069
+ };
3070
+ }
3071
+ return void 0;
3072
+ }
3073
+ __name(enhanceBurntPix, "enhanceBurntPix");
3074
+ var enhanceBurntPix_default = enhanceBurntPixPlugin;
3075
+
3076
+ // src/decoder/plugins/enhanceGraffiti.ts
3077
+ import { bytesToString, hexToBytes, size as size3, slice as slice3 } from "viem";
3078
+ var enhanceGraffitiPlugin = Object.freeze({
3079
+ enhance: /* @__PURE__ */ __name(async (result, options) => enhanceGraffiti(
3080
+ result,
3081
+ { abiName: "graffiti", decoderName: "graffiti" },
3082
+ options
3083
+ ), "enhance"),
3084
+ decodeEvent: /* @__PURE__ */ __name(async (_log, _options) => void 0, "decodeEvent"),
3085
+ required: true,
3086
+ priority: 1e3,
3087
+ name: "graffiti"
3088
+ });
3089
+ async function enhanceGraffiti(result, _pluginOptions, _options) {
3090
+ const { input } = result;
3091
+ if (input && size3(input || "0x") >= 4 && slice3(input || "0x", 0, 4) === "0x00000000") {
3092
+ let graffiti = slice3(input, 4);
3093
+ try {
3094
+ graffiti = bytesToString(hexToBytes(graffiti));
3095
+ } catch {
2667
3096
  }
3097
+ return {
3098
+ ...result,
3099
+ resultType: "grafitti",
3100
+ sig: "0x",
3101
+ functionName: "",
3102
+ input,
3103
+ graffiti,
3104
+ __decoder: "grafitti"
3105
+ };
2668
3106
  }
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;
3107
+ return void 0;
2685
3108
  }
2686
- __name(decodeTransaction, "decodeTransaction");
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";
2687
3114
 
2688
3115
  // src/decoder/plugins/enhanceSetData.ts
2689
3116
  async function enhanceSetData(result, pluginOptions, options) {
@@ -4585,172 +5012,14 @@ var abi2 = [
4585
5012
  stateMutability: "payable",
4586
5013
  type: "fallback"
4587
5014
  },
4588
- {
4589
- inputs: [],
4590
- name: "RENOUNCE_OWNERSHIP_CONFIRMATION_DELAY",
4591
- outputs: [
4592
- {
4593
- internalType: "uint256",
4594
- name: "",
4595
- type: "uint256"
4596
- }
4597
- ],
4598
- stateMutability: "view",
4599
- type: "function"
4600
- },
4601
- {
4602
- inputs: [],
4603
- name: "RENOUNCE_OWNERSHIP_CONFIRMATION_PERIOD",
4604
- outputs: [
4605
- {
4606
- internalType: "uint256",
4607
- name: "",
4608
- type: "uint256"
4609
- }
4610
- ],
4611
- stateMutability: "view",
4612
- type: "function"
4613
- },
4614
- {
4615
- inputs: [],
4616
- name: "VERSION",
4617
- outputs: [
4618
- {
4619
- internalType: "string",
4620
- name: "",
4621
- type: "string"
4622
- }
4623
- ],
4624
- stateMutability: "view",
4625
- type: "function"
4626
- },
4627
- {
4628
- inputs: [],
4629
- name: "acceptOwnership",
4630
- outputs: [],
4631
- stateMutability: "nonpayable",
4632
- type: "function"
4633
- },
4634
- {
4635
- inputs: [
4636
- {
4637
- internalType: "bytes[]",
4638
- name: "data",
4639
- type: "bytes[]"
4640
- }
4641
- ],
4642
- name: "batchCalls",
4643
- outputs: [
4644
- {
4645
- internalType: "bytes[]",
4646
- name: "results",
4647
- type: "bytes[]"
4648
- }
4649
- ],
4650
- stateMutability: "nonpayable",
4651
- type: "function"
4652
- },
4653
- {
4654
- inputs: [
4655
- {
4656
- internalType: "uint256",
4657
- name: "operationType",
4658
- type: "uint256"
4659
- },
4660
- {
4661
- internalType: "address",
4662
- name: "target",
4663
- type: "address"
4664
- },
4665
- {
4666
- internalType: "uint256",
4667
- name: "value",
4668
- type: "uint256"
4669
- },
4670
- {
4671
- internalType: "bytes",
4672
- name: "data",
4673
- type: "bytes"
4674
- }
4675
- ],
4676
- name: "execute",
4677
- outputs: [
4678
- {
4679
- internalType: "bytes",
4680
- name: "",
4681
- type: "bytes"
4682
- }
4683
- ],
4684
- stateMutability: "payable",
4685
- type: "function"
4686
- },
4687
- {
4688
- inputs: [
4689
- {
4690
- internalType: "uint256[]",
4691
- name: "operationsType",
4692
- type: "uint256[]"
4693
- },
4694
- {
4695
- internalType: "address[]",
4696
- name: "targets",
4697
- type: "address[]"
4698
- },
4699
- {
4700
- internalType: "uint256[]",
4701
- name: "values",
4702
- type: "uint256[]"
4703
- },
4704
- {
4705
- internalType: "bytes[]",
4706
- name: "datas",
4707
- type: "bytes[]"
4708
- }
4709
- ],
4710
- name: "executeBatch",
4711
- outputs: [
4712
- {
4713
- internalType: "bytes[]",
4714
- name: "",
4715
- type: "bytes[]"
4716
- }
4717
- ],
4718
- stateMutability: "payable",
4719
- type: "function"
4720
- },
4721
- {
4722
- inputs: [
4723
- {
4724
- internalType: "bytes32",
4725
- name: "dataKey",
4726
- type: "bytes32"
4727
- }
4728
- ],
4729
- name: "getData",
4730
- outputs: [
4731
- {
4732
- internalType: "bytes",
4733
- name: "dataValue",
4734
- type: "bytes"
4735
- }
4736
- ],
4737
- stateMutability: "view",
4738
- type: "function"
4739
- },
4740
- {
4741
- inputs: [
4742
- {
4743
- internalType: "bytes32[]",
4744
- name: "dataKeys",
4745
- type: "bytes32[]"
4746
- }
4747
- ],
4748
- name: "getDataBatch",
5015
+ {
5016
+ inputs: [],
5017
+ name: "RENOUNCE_OWNERSHIP_CONFIRMATION_DELAY",
4749
5018
  outputs: [
4750
5019
  {
4751
- internalType: "bytes[]",
4752
- name: "dataValues",
4753
- type: "bytes[]"
5020
+ internalType: "uint256",
5021
+ name: "",
5022
+ type: "uint256"
4754
5023
  }
4755
5024
  ],
4756
5025
  stateMutability: "view",
@@ -4758,12 +5027,12 @@ var abi2 = [
4758
5027
  },
4759
5028
  {
4760
5029
  inputs: [],
4761
- name: "owner",
5030
+ name: "RENOUNCE_OWNERSHIP_CONFIRMATION_PERIOD",
4762
5031
  outputs: [
4763
5032
  {
4764
- internalType: "address",
5033
+ internalType: "uint256",
4765
5034
  name: "",
4766
- type: "address"
5035
+ type: "uint256"
4767
5036
  }
4768
5037
  ],
4769
5038
  stateMutability: "view",
@@ -4771,12 +5040,12 @@ var abi2 = [
4771
5040
  },
4772
5041
  {
4773
5042
  inputs: [],
4774
- name: "pendingOwner",
5043
+ name: "VERSION",
4775
5044
  outputs: [
4776
5045
  {
4777
- internalType: "address",
5046
+ internalType: "string",
4778
5047
  name: "",
4779
- type: "address"
5048
+ type: "string"
4780
5049
  }
4781
5050
  ],
4782
5051
  stateMutability: "view",
@@ -4784,1022 +5053,711 @@ var abi2 = [
4784
5053
  },
4785
5054
  {
4786
5055
  inputs: [],
4787
- name: "renounceOwnership",
5056
+ name: "acceptOwnership",
4788
5057
  outputs: [],
4789
5058
  stateMutability: "nonpayable",
4790
5059
  type: "function"
4791
5060
  },
4792
5061
  {
4793
5062
  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
5063
  {
4818
5064
  internalType: "bytes[]",
4819
- name: "dataValues",
5065
+ name: "data",
4820
5066
  type: "bytes[]"
4821
5067
  }
4822
5068
  ],
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",
5069
+ name: "batchCalls",
4837
5070
  outputs: [
4838
5071
  {
4839
- internalType: "bool",
4840
- name: "",
4841
- type: "bool"
5072
+ internalType: "bytes[]",
5073
+ name: "results",
5074
+ type: "bytes[]"
4842
5075
  }
4843
5076
  ],
4844
- stateMutability: "view",
5077
+ stateMutability: "nonpayable",
4845
5078
  type: "function"
4846
5079
  },
4847
5080
  {
4848
5081
  inputs: [
5082
+ {
5083
+ internalType: "uint256",
5084
+ name: "operationType",
5085
+ type: "uint256"
5086
+ },
4849
5087
  {
4850
5088
  internalType: "address",
4851
- name: "newOwner",
5089
+ name: "target",
4852
5090
  type: "address"
4853
- }
4854
- ],
4855
- name: "transferOwnership",
4856
- outputs: [],
4857
- stateMutability: "nonpayable",
4858
- type: "function"
4859
- },
4860
- {
4861
- inputs: [
5091
+ },
4862
5092
  {
4863
- internalType: "bytes32",
4864
- name: "typeId",
4865
- type: "bytes32"
5093
+ internalType: "uint256",
5094
+ name: "value",
5095
+ type: "uint256"
4866
5096
  },
4867
5097
  {
4868
5098
  internalType: "bytes",
4869
- name: "receivedData",
5099
+ name: "data",
4870
5100
  type: "bytes"
4871
5101
  }
4872
5102
  ],
4873
- name: "universalReceiver",
5103
+ name: "execute",
4874
5104
  outputs: [
4875
5105
  {
4876
5106
  internalType: "bytes",
4877
- name: "returnedValues",
5107
+ name: "",
4878
5108
  type: "bytes"
4879
5109
  }
4880
5110
  ],
4881
5111
  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 };
5112
+ type: "function"
5113
+ },
5114
+ {
5115
+ inputs: [
5116
+ {
5117
+ internalType: "uint256[]",
5118
+ name: "operationsType",
5119
+ type: "uint256[]"
5120
+ },
5121
+ {
5122
+ internalType: "address[]",
5123
+ name: "targets",
5124
+ type: "address[]"
5125
+ },
5126
+ {
5127
+ internalType: "uint256[]",
5128
+ name: "values",
5129
+ type: "uint256[]"
5130
+ },
5131
+ {
5132
+ internalType: "bytes[]",
5133
+ name: "datas",
5134
+ type: "bytes[]"
5038
5135
  }
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
- }
5136
+ ],
5137
+ name: "executeBatch",
5138
+ outputs: [
5139
+ {
5140
+ internalType: "bytes[]",
5141
+ name: "",
5142
+ type: "bytes[]"
5078
5143
  }
5079
- if (!decoderVerifiedContract) {
5080
- return void 0;
5144
+ ],
5145
+ stateMutability: "payable",
5146
+ type: "function"
5147
+ },
5148
+ {
5149
+ inputs: [
5150
+ {
5151
+ internalType: "bytes32",
5152
+ name: "dataKey",
5153
+ type: "bytes32"
5081
5154
  }
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;
5155
+ ],
5156
+ name: "getData",
5157
+ outputs: [
5158
+ {
5159
+ internalType: "bytes",
5160
+ name: "dataValue",
5161
+ type: "bytes"
5086
5162
  }
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
- };
5163
+ ],
5164
+ stateMutability: "view",
5165
+ type: "function"
5166
+ },
5167
+ {
5168
+ inputs: [
5169
+ {
5170
+ internalType: "bytes32[]",
5171
+ name: "dataKeys",
5172
+ type: "bytes32[]"
5102
5173
  }
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
- }
5174
+ ],
5175
+ name: "getDataBatch",
5176
+ outputs: [
5177
+ {
5178
+ internalType: "bytes[]",
5179
+ name: "dataValues",
5180
+ type: "bytes[]"
5138
5181
  }
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;
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"
5194
+ }
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"
5207
+ }
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"
5171
5225
  },
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];
5226
+ {
5227
+ internalType: "bytes",
5228
+ name: "dataValue",
5229
+ type: "bytes"
5230
+ }
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[]"
5185
5248
  }
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
- }
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"
5227
5261
  }
5228
- }
5229
- }
5230
- return void 0;
5231
- }, "getFunctionSignature");
5232
-
5233
- // src/decoder/plugins/enhanceRetrieveAbi.ts
5234
- var enhanceRetrieveAbiPlugin = standardPlugin(
5235
- abi2,
5262
+ ],
5263
+ name: "supportsInterface",
5264
+ outputs: [
5265
+ {
5266
+ internalType: "bool",
5267
+ name: "",
5268
+ type: "bool"
5269
+ }
5270
+ ],
5271
+ stateMutability: "view",
5272
+ type: "function"
5273
+ },
5236
5274
  {
5237
- abiName: "Internal",
5238
- decoderName: "explorer",
5239
- name: "abiRetrieve",
5240
- usesAsync: true,
5241
- priority: 0
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"
5242
5286
  },
5243
5287
  {
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;
5288
+ inputs: [
5289
+ {
5290
+ internalType: "bytes32",
5291
+ name: "typeId",
5292
+ type: "bytes32"
5293
+ },
5294
+ {
5295
+ internalType: "bytes",
5296
+ name: "receivedData",
5297
+ type: "bytes"
5251
5298
  }
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
- }
5299
+ ],
5300
+ name: "universalReceiver",
5301
+ outputs: [
5302
+ {
5303
+ internalType: "bytes",
5304
+ name: "returnedValues",
5305
+ type: "bytes"
5258
5306
  }
5259
- return void 0;
5260
- }, "decodeEvent")
5261
- }
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 {
5307
+ ],
5308
+ stateMutability: "payable",
5309
+ type: "function"
5310
+ },
5311
+ {
5312
+ stateMutability: "payable",
5313
+ type: "receive"
5284
5314
  }
5285
- return void 0;
5286
- }
5287
- __name(enhanceRetrieveAbi, "enhanceRetrieveAbi");
5288
- var enhanceRetrieveAbi_default = enhanceRetrieveAbiPlugin;
5315
+ ];
5289
5316
 
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
- }
5317
- }
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
- });
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";
5334
5327
 
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;
5328
+ // src/decoder/lruCache.ts
5329
+ import { LRUCache as LRUCache3 } from "lru-cache";
5330
+ var LRUDecoderCache = class {
5331
+ static {
5332
+ __name(this, "LRUDecoderCache");
5333
+ }
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();
5347
+ }
5348
+ async get(key) {
5349
+ const entry = this.cache.get(key);
5350
+ if (!entry) {
5351
+ return void 0;
5353
5352
  }
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
- }
5353
+ if (entry.expires && Date.now() > entry.expires) {
5354
+ this.cache.delete(key);
5355
+ return void 0;
5372
5356
  }
5373
- results.push(result);
5357
+ return entry;
5374
5358
  }
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
- }
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;
5390
5371
  }
5372
+ this.cache.set(key, entry);
5391
5373
  }
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
- }
5374
+ async delete(key) {
5375
+ this.cache.delete(key);
5376
+ }
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);
5408
5383
  }
5409
5384
  }
5385
+ return result;
5410
5386
  }
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;
5387
+ async setMany(entries) {
5388
+ for (const { key, value, options } of entries) {
5389
+ await this.set(key, value, options);
5415
5390
  }
5416
- if (obj && typeof obj === "object") {
5417
- visited.add(obj);
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;
5418
5401
  }
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;
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;
5439
5413
  }
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
- }
5414
+ const existingPromise = this.promises.get(key);
5415
+ if (existingPromise) {
5416
+ return existingPromise;
5453
5417
  }
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;
5454
5433
  }
5455
- __name(collect, "collect");
5456
- collect(data);
5457
- return Array.from(addresses);
5434
+ };
5435
+ function createLRUCache(options) {
5436
+ return new LRUDecoderCache(options);
5458
5437
  }
5459
- __name(collectDataKeys, "collectDataKeys");
5438
+ __name(createLRUCache, "createLRUCache");
5460
5439
 
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
- }
5470
- }
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);
5545
- }
5546
- }
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
- };
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}`);
5566
5453
  }
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");
5567
5470
  }
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
- };
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;
5504
+ }
5505
+ }
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
+ );
5578
5534
  }
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) {
5535
+ __name(fetchAbi, "fetchAbi");
5536
+ var getFunctionSignature = /* @__PURE__ */ __name(async (chain, input, to, preferError = false, options) => {
5537
+ if (to && isAddress2(to) && isAddressEqual2(to, zeroAddress2)) {
5601
5538
  return {
5602
- results
5539
+ __decoder: "none",
5540
+ standard: "unknown",
5541
+ to,
5542
+ input,
5543
+ resultType: "raw"
5603
5544
  };
5604
5545
  }
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;
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
+ }
5627
5565
  }
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;
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
+ }
5646
5582
  }
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;
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";
5670
5634
  }
5671
- newResults[i].addresses = collectDataKeys(enhanced);
5672
- newResults[i].phase = "enhanced";
5673
- } else if (immediateResults[i] && !needsEnhancement(immediateResults[i])) {
5674
- newResults[i].phase = "enhanced";
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
+ };
5675
5651
  }
5676
- });
5677
- } catch (error) {
5678
- console.error("Batch enhancement failed:", error);
5652
+ } catch (_error) {
5653
+ }
5679
5654
  }
5680
5655
  }
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);
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;
5689
5678
  }
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
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
+ }
5685
+ }
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
5705
5708
  };
5706
- });
5707
- return {
5708
- results
5709
- };
5709
+ }
5710
+ } catch {
5710
5711
  }
5712
+ return void 0;
5711
5713
  }
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");
5714
+ __name(enhanceRetrieveAbi, "enhanceRetrieveAbi");
5715
+ var enhanceRetrieveAbi_default = enhanceRetrieveAbiPlugin;
5724
5716
 
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
- };
5740
- }
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
- });
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;
5767
5741
  }
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);
5742
+ } catch {
5780
5743
  }
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
- };
5790
5744
  }
5745
+ return void 0;
5791
5746
  }
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");
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
+ });
5803
5761
 
5804
5762
  // src/server/index.ts
5805
5763
  function createServerDecoder(config) {
@@ -5850,14 +5808,6 @@ function createServerDecoder(config) {
5850
5808
  },
5851
5809
  async resolveAddresses(addresses, timeoutMs = 3e3) {
5852
5810
  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);
5861
5811
  }
5862
5812
  };
5863
5813
  }
@@ -5866,7 +5816,6 @@ export {
5866
5816
  ServerAddressResolver,
5867
5817
  ServerDecoderCaches,
5868
5818
  createServerDecoder,
5869
- decodeEventLogs,
5870
5819
  decodeTransactionSync,
5871
5820
  decodeTransactionsBatch
5872
5821
  };