@t2000/engine 0.5.6 → 0.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -798,10 +798,19 @@ declare const healthCheckTool: Tool<{}, {
798
798
 
799
799
  declare const ratesInfoTool: Tool<{}, _t2000_sdk.RatesResult>;
800
800
 
801
+ interface TxRecord {
802
+ digest: string;
803
+ action: string;
804
+ amount?: number;
805
+ asset?: string;
806
+ recipient?: string;
807
+ timestamp: number;
808
+ gasCost?: number;
809
+ }
801
810
  declare const transactionHistoryTool: Tool<{
802
811
  limit?: number | undefined;
803
812
  }, {
804
- transactions: _t2000_sdk.TransactionRecord[];
813
+ transactions: TxRecord[];
805
814
  count: number;
806
815
  }>;
807
816
 
package/dist/index.js CHANGED
@@ -866,6 +866,97 @@ var ratesInfoTool = buildTool({
866
866
  };
867
867
  }
868
868
  });
869
+ var SUI_TYPE = "0x2::sui::SUI";
870
+ var KNOWN_TARGETS = [
871
+ [/::suilend|::obligation/, "lending"],
872
+ [/::navi|::incentive_v\d+|::oracle_pro/, "lending"],
873
+ [/::cetus|::pool/, "swap"],
874
+ [/::deepbook/, "swap"],
875
+ [/::transfer::public_transfer/, "send"]
876
+ ];
877
+ function resolveOwner(owner) {
878
+ if (typeof owner === "object" && owner.AddressOwner) return owner.AddressOwner;
879
+ if (typeof owner === "string") return owner;
880
+ return null;
881
+ }
882
+ function classifyAction(targets, commandTypes) {
883
+ for (const target of targets) {
884
+ for (const [pattern, label] of KNOWN_TARGETS) {
885
+ if (pattern.test(target)) return label;
886
+ }
887
+ }
888
+ if (commandTypes.includes("TransferObjects") && !commandTypes.includes("MoveCall")) return "send";
889
+ return "transaction";
890
+ }
891
+ function parseRpcTx(tx, address) {
892
+ const gasUsed = tx.effects?.gasUsed;
893
+ const gasCost = gasUsed ? (Number(gasUsed.computationCost) + Number(gasUsed.storageCost) - Number(gasUsed.storageRebate)) / 1e9 : void 0;
894
+ const moveCallTargets = [];
895
+ const commandTypes = [];
896
+ try {
897
+ const data = tx.transaction?.data;
898
+ const inner = data?.transaction;
899
+ const commands = inner?.commands;
900
+ if (commands) {
901
+ for (const cmd of commands) {
902
+ if (cmd.MoveCall) {
903
+ const mc = cmd.MoveCall;
904
+ moveCallTargets.push(`${mc.package}::${mc.module}::${mc.function}`);
905
+ commandTypes.push("MoveCall");
906
+ } else if (cmd.TransferObjects) {
907
+ commandTypes.push("TransferObjects");
908
+ }
909
+ }
910
+ }
911
+ } catch {
912
+ }
913
+ const changes = tx.balanceChanges ?? [];
914
+ const outflows = changes.filter((c) => resolveOwner(c.owner) === address && BigInt(c.amount) < 0n);
915
+ const inflows = changes.filter((c) => resolveOwner(c.owner) !== address && BigInt(c.amount) > 0n);
916
+ const primaryOutflow = outflows.filter((c) => c.coinType !== SUI_TYPE).sort((a, b) => Number(BigInt(a.amount) - BigInt(b.amount)))[0] ?? outflows[0];
917
+ let amount;
918
+ let asset;
919
+ let recipient;
920
+ if (primaryOutflow) {
921
+ const coinType = primaryOutflow.coinType;
922
+ const decimals = coinType.includes("::usdc::") ? 6 : 9;
923
+ amount = Math.abs(Number(BigInt(primaryOutflow.amount))) / 10 ** decimals;
924
+ asset = coinType === SUI_TYPE ? "SUI" : coinType.includes("::usdc::") ? "USDC" : coinType.split("::").pop() ?? "unknown";
925
+ const recipientChange = inflows.find((c) => c.coinType === coinType);
926
+ recipient = recipientChange ? resolveOwner(recipientChange.owner) ?? void 0 : void 0;
927
+ }
928
+ return {
929
+ digest: tx.digest,
930
+ action: classifyAction(moveCallTargets, commandTypes),
931
+ amount,
932
+ asset,
933
+ recipient,
934
+ timestamp: Number(tx.timestampMs ?? 0),
935
+ gasCost
936
+ };
937
+ }
938
+ async function queryHistoryRpc(rpcUrl, address, limit) {
939
+ const res = await fetch(rpcUrl, {
940
+ method: "POST",
941
+ headers: { "Content-Type": "application/json" },
942
+ body: JSON.stringify({
943
+ jsonrpc: "2.0",
944
+ id: 1,
945
+ method: "suix_queryTransactionBlocks",
946
+ params: [
947
+ { filter: { FromAddress: address }, options: { showEffects: true, showInput: true, showBalanceChanges: true } },
948
+ null,
949
+ limit,
950
+ true
951
+ ]
952
+ }),
953
+ signal: AbortSignal.timeout(1e4)
954
+ });
955
+ if (!res.ok) throw new Error(`Sui RPC error: ${res.status}`);
956
+ const json = await res.json();
957
+ if (json.error) throw new Error(`RPC error: ${json.error.message}`);
958
+ return (json.result?.data ?? []).map((tx) => parseRpcTx(tx, address));
959
+ }
869
960
  var transactionHistoryTool = buildTool({
870
961
  name: "transaction_history",
871
962
  description: "Retrieve recent transaction history: past sends, saves, withdrawals, borrows, repayments, and rewards claims. Optionally limit the number of results.",
@@ -883,13 +974,21 @@ var transactionHistoryTool = buildTool({
883
974
  },
884
975
  isReadOnly: true,
885
976
  async call(input, context) {
886
- const agent = requireAgent(context);
887
- const records = await agent.history({ limit: input.limit ?? 10 });
977
+ const limit = input.limit ?? 10;
978
+ if (context.agent) {
979
+ const agent = requireAgent(context);
980
+ const records2 = await agent.history({ limit });
981
+ return {
982
+ data: { transactions: records2, count: records2.length },
983
+ displayText: `${records2.length} recent transaction(s)`
984
+ };
985
+ }
986
+ if (!context.walletAddress || !context.suiRpcUrl) {
987
+ throw new Error("Transaction history requires a wallet address");
988
+ }
989
+ const records = await queryHistoryRpc(context.suiRpcUrl, context.walletAddress, limit);
888
990
  return {
889
- data: {
890
- transactions: records,
891
- count: records.length
892
- },
991
+ data: { transactions: records, count: records.length },
893
992
  displayText: `${records.length} recent transaction(s)`
894
993
  };
895
994
  }