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

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