@t2000/sdk 0.11.2 → 0.13.0

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.
@@ -160,6 +160,7 @@ interface SendResult {
160
160
  tx: string;
161
161
  amount: number;
162
162
  to: string;
163
+ contactName?: string;
163
164
  gasCost: number;
164
165
  gasCostUnit: string;
165
166
  gasMethod: GasMethod;
@@ -160,6 +160,7 @@ interface SendResult {
160
160
  tx: string;
161
161
  amount: number;
162
162
  to: string;
163
+ contactName?: string;
163
164
  gasCost: number;
164
165
  gasCostUnit: string;
165
166
  gasMethod: GasMethod;
package/dist/index.cjs CHANGED
@@ -2699,6 +2699,83 @@ var SafeguardEnforcer = class {
2699
2699
  }
2700
2700
  }
2701
2701
  };
2702
+ var RESERVED_NAMES = /* @__PURE__ */ new Set(["to", "all", "address"]);
2703
+ var ContactManager = class {
2704
+ contacts = {};
2705
+ filePath;
2706
+ dir;
2707
+ constructor(configDir) {
2708
+ this.dir = configDir ?? path.join(os.homedir(), ".t2000");
2709
+ this.filePath = path.join(this.dir, "contacts.json");
2710
+ this.load();
2711
+ }
2712
+ load() {
2713
+ try {
2714
+ if (fs.existsSync(this.filePath)) {
2715
+ this.contacts = JSON.parse(fs.readFileSync(this.filePath, "utf-8"));
2716
+ }
2717
+ } catch {
2718
+ this.contacts = {};
2719
+ }
2720
+ }
2721
+ save() {
2722
+ if (!fs.existsSync(this.dir)) fs.mkdirSync(this.dir, { recursive: true });
2723
+ fs.writeFileSync(this.filePath, JSON.stringify(this.contacts, null, 2));
2724
+ }
2725
+ add(name, address) {
2726
+ this.validateName(name);
2727
+ const normalized = validateAddress(address);
2728
+ const key = name.toLowerCase();
2729
+ const existed = key in this.contacts;
2730
+ this.contacts[key] = { name, address: normalized };
2731
+ this.save();
2732
+ return { action: existed ? "updated" : "added" };
2733
+ }
2734
+ remove(name) {
2735
+ const key = name.toLowerCase();
2736
+ if (!(key in this.contacts)) return false;
2737
+ delete this.contacts[key];
2738
+ this.save();
2739
+ return true;
2740
+ }
2741
+ get(name) {
2742
+ this.load();
2743
+ return this.contacts[name.toLowerCase()];
2744
+ }
2745
+ list() {
2746
+ this.load();
2747
+ return Object.values(this.contacts);
2748
+ }
2749
+ resolve(nameOrAddress) {
2750
+ this.load();
2751
+ if (nameOrAddress.startsWith("0x") && nameOrAddress.length >= 42) {
2752
+ return { address: validateAddress(nameOrAddress) };
2753
+ }
2754
+ const contact = this.contacts[nameOrAddress.toLowerCase()];
2755
+ if (contact) {
2756
+ return { address: contact.address, contactName: contact.name };
2757
+ }
2758
+ throw new T2000Error(
2759
+ "CONTACT_NOT_FOUND",
2760
+ `"${nameOrAddress}" is not a valid Sui address or saved contact.
2761
+ Add it: t2000 contacts add ${nameOrAddress} 0x...`
2762
+ );
2763
+ }
2764
+ validateName(name) {
2765
+ if (name.startsWith("0x")) {
2766
+ throw new T2000Error("INVALID_CONTACT_NAME", "Contact names cannot start with 0x");
2767
+ }
2768
+ if (!/^[a-zA-Z0-9_]+$/.test(name)) {
2769
+ throw new T2000Error("INVALID_CONTACT_NAME", "Contact names can only contain letters, numbers, and underscores");
2770
+ }
2771
+ if (name.length > 32) {
2772
+ throw new T2000Error("INVALID_CONTACT_NAME", "Contact names must be 32 characters or fewer");
2773
+ }
2774
+ if (RESERVED_NAMES.has(name.toLowerCase())) {
2775
+ throw new T2000Error("INVALID_CONTACT_NAME", `"${name}" is a reserved name and cannot be used as a contact`);
2776
+ }
2777
+ }
2778
+ };
2702
2779
  var DEFAULT_CONFIG_DIR = path.join(os.homedir(), ".t2000");
2703
2780
  var T2000 = class _T2000 extends eventemitter3.EventEmitter {
2704
2781
  keypair;
@@ -2706,6 +2783,7 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
2706
2783
  _address;
2707
2784
  registry;
2708
2785
  enforcer;
2786
+ contacts;
2709
2787
  constructor(keypair, client, registry, configDir) {
2710
2788
  super();
2711
2789
  this.keypair = keypair;
@@ -2714,6 +2792,7 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
2714
2792
  this.registry = registry ?? _T2000.createDefaultRegistry(client);
2715
2793
  this.enforcer = new SafeguardEnforcer(configDir);
2716
2794
  this.enforcer.load();
2795
+ this.contacts = new ContactManager(configDir);
2717
2796
  }
2718
2797
  static createDefaultRegistry(client) {
2719
2798
  const registry = new ProtocolRegistry();
@@ -2793,8 +2872,9 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
2793
2872
  if (!(asset in SUPPORTED_ASSETS)) {
2794
2873
  throw new T2000Error("ASSET_NOT_SUPPORTED", `Asset ${asset} is not supported`);
2795
2874
  }
2875
+ const resolved = this.contacts.resolve(params.to);
2796
2876
  const sendAmount = params.amount;
2797
- const sendTo = params.to;
2877
+ const sendTo = resolved.address;
2798
2878
  const gasResult = await executeWithGas(
2799
2879
  this.client,
2800
2880
  this.keypair,
@@ -2808,7 +2888,8 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
2808
2888
  success: true,
2809
2889
  tx: gasResult.digest,
2810
2890
  amount: sendAmount,
2811
- to: params.to,
2891
+ to: resolved.address,
2892
+ contactName: resolved.contactName,
2812
2893
  gasCost: gasResult.gasCostSui,
2813
2894
  gasCostUnit: "SUI",
2814
2895
  gasMethod: gasResult.gasMethod,
@@ -3917,6 +3998,7 @@ var allDescriptors = [
3917
3998
  exports.BPS_DENOMINATOR = BPS_DENOMINATOR;
3918
3999
  exports.CLOCK_ID = CLOCK_ID;
3919
4000
  exports.CetusAdapter = CetusAdapter;
4001
+ exports.ContactManager = ContactManager;
3920
4002
  exports.DEFAULT_NETWORK = DEFAULT_NETWORK;
3921
4003
  exports.DEFAULT_SAFEGUARD_CONFIG = DEFAULT_SAFEGUARD_CONFIG;
3922
4004
  exports.MIST_PER_SUI = MIST_PER_SUI;