@naviprotocol/wallet-client 2.0.5 → 2.0.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.
Files changed (46) hide show
  1. package/dist/client.d.ts +3 -3
  2. package/dist/client.js +160 -0
  3. package/dist/client.js.map +1 -0
  4. package/dist/index.d.ts +3 -3
  5. package/dist/index.js +8 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/modules/balanceModule/index.d.ts +4 -4
  8. package/dist/modules/balanceModule/index.js +214 -0
  9. package/dist/modules/balanceModule/index.js.map +1 -0
  10. package/dist/modules/balanceModule/portfolio.js +105 -0
  11. package/dist/modules/balanceModule/portfolio.js.map +1 -0
  12. package/dist/modules/haedalModule/index.d.ts +2 -2
  13. package/dist/modules/haedalModule/index.js +114 -0
  14. package/dist/modules/haedalModule/index.js.map +1 -0
  15. package/dist/modules/index.d.ts +5 -5
  16. package/dist/modules/index.js +21 -0
  17. package/dist/modules/index.js.map +1 -0
  18. package/dist/modules/lendingModule/index.d.ts +5 -5
  19. package/dist/modules/lendingModule/index.js +410 -0
  20. package/dist/modules/lendingModule/index.js.map +1 -0
  21. package/dist/modules/lendingModule/migrate.js +225 -0
  22. package/dist/modules/lendingModule/migrate.js.map +1 -0
  23. package/dist/modules/lendingModule/protocols/navi.d.ts +1 -1
  24. package/dist/modules/lendingModule/protocols/navi.js +37 -0
  25. package/dist/modules/lendingModule/protocols/navi.js.map +1 -0
  26. package/dist/modules/lendingModule/protocols/suilend.d.ts +1 -1
  27. package/dist/{suilend-CWugUjwd.js → modules/lendingModule/protocols/suilend.js} +1 -1
  28. package/dist/{suilend-CWugUjwd.js.map → modules/lendingModule/protocols/suilend.js.map} +1 -1
  29. package/dist/modules/module.d.ts +1 -1
  30. package/dist/modules/module.js +46 -0
  31. package/dist/modules/module.js.map +1 -0
  32. package/dist/modules/swapModule/index.d.ts +2 -2
  33. package/dist/modules/swapModule/index.js +159 -0
  34. package/dist/modules/swapModule/index.js.map +1 -0
  35. package/dist/modules/voloModule/index.d.ts +2 -2
  36. package/dist/modules/voloModule/index.js +128 -0
  37. package/dist/modules/voloModule/index.js.map +1 -0
  38. package/dist/signer.d.ts +1 -1
  39. package/dist/signer.js +102 -0
  40. package/dist/signer.js.map +1 -0
  41. package/dist/transaction-result.d.ts +1 -1
  42. package/dist/transaction-result.js +59 -0
  43. package/dist/transaction-result.js.map +1 -0
  44. package/package.json +7 -7
  45. package/dist/index.esm.js +0 -1686
  46. package/dist/index.esm.js.map +0 -1
package/dist/client.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { Signer } from '@mysten/sui/cryptography';
2
2
  import { Emitter } from 'mitt';
3
- import { Module, ModuleConfig } from './modules/module';
4
- import { modules, ModuleName, ModuleEvents } from './modules';
3
+ import { Module, ModuleConfig } from './modules/module.js';
4
+ import { modules, ModuleName, ModuleEvents } from './modules/index.js';
5
5
  import { Transaction } from '@mysten/sui/transactions';
6
- import { DryRunOptions, NaviTransactionExecutionOptions, NaviWalletTransactionResult } from './types';
6
+ import { DryRunOptions, NaviTransactionExecutionOptions, NaviWalletTransactionResult } from './types.js';
7
7
  import { NaviCoreClient, NaviJsonRpcCompatClient, NaviSdkServiceOptions, NaviSuiClientBundle, NaviSuiClientOptions, NaviSuiLegacyJsonRpcOptions, NaviSuiNetwork } from '@naviprotocol/lending';
8
8
 
9
9
  /**
package/dist/client.js ADDED
@@ -0,0 +1,160 @@
1
+ import p from "mitt";
2
+ import { modules as w } from "./modules/index.js";
3
+ import { Transaction as l } from "@mysten/sui/transactions";
4
+ import { fromBase64 as C } from "@mysten/sui/utils";
5
+ import { normalizeTransactionResult as o, mergeTransactionResponseOptions as f } from "./transaction-result.js";
6
+ import { PUBLIC_MAINNET_GRPC_URL as R, createNaviSuiClientBundle as T, createNaviLegacyJsonRpcClient as J } from "@naviprotocol/lending";
7
+ function d(n) {
8
+ const e = f(n);
9
+ return {
10
+ effects: e.showEffects,
11
+ events: e.showEvents,
12
+ balanceChanges: e.showBalanceChanges,
13
+ objectTypes: e.showObjectChanges
14
+ };
15
+ }
16
+ function g(n) {
17
+ return n.core;
18
+ }
19
+ function x(n) {
20
+ return "grpc" in n;
21
+ }
22
+ function B(n) {
23
+ if (x(n))
24
+ return T(n);
25
+ const e = n.network ?? "mainnet", t = J(e, n.legacyJsonRpc);
26
+ return {
27
+ network: e,
28
+ coreClient: t,
29
+ grpc: t,
30
+ legacyJsonRpc: t,
31
+ services: n.services
32
+ };
33
+ }
34
+ class O {
35
+ /**
36
+ * Creates a new wallet client instance
37
+ * @param options - Configuration options for the wallet client
38
+ */
39
+ constructor(e) {
40
+ this.modules = w, this.userConfigs = {}, this.events = p();
41
+ const t = e.client ?? {
42
+ network: "mainnet",
43
+ grpc: { url: R }
44
+ };
45
+ this.clientBundle = B(t), this.client = this.clientBundle.coreClient, this.clientUrl = "grpc" in t ? t.legacyJsonRpc && "url" in t.legacyJsonRpc ? t.legacyJsonRpc.url : void 0 : "url" in t.legacyJsonRpc ? t.legacyJsonRpc.url : void 0, this.signer = e.signer, this.userConfigs = e.configs || {}, Object.entries(this.modules).forEach(([s, i]) => {
46
+ if (s !== i.name)
47
+ throw new Error(`Module name ${s} does not match module name ${i.name}`);
48
+ i.install(this);
49
+ });
50
+ }
51
+ get lending() {
52
+ return this.modules.lending;
53
+ }
54
+ get balance() {
55
+ return this.modules.balance;
56
+ }
57
+ get volo() {
58
+ return this.modules.volo;
59
+ }
60
+ get swap() {
61
+ return this.modules.swap;
62
+ }
63
+ get haedal() {
64
+ return this.modules.haedal;
65
+ }
66
+ /**
67
+ * Signs and executes a transaction block
68
+ * @param options - Transaction execution options including dry run support
69
+ * @returns Promise with transaction execution result
70
+ */
71
+ async signExecuteTransaction(e) {
72
+ const { dryRun: t = !1, ...s } = e;
73
+ if (t) {
74
+ const r = g(this.client);
75
+ if (typeof r?.simulateTransaction == "function") {
76
+ e.transaction instanceof l && e.transaction.setSenderIfNotSet(this.address);
77
+ const y = await r.simulateTransaction({
78
+ transaction: e.transaction,
79
+ include: d(s.options)
80
+ });
81
+ return o("dryRun", y);
82
+ }
83
+ const c = this.clientBundle.legacyJsonRpc;
84
+ if (!c)
85
+ throw new Error(
86
+ "WalletClient dry-run requires core.simulateTransaction or an explicit legacyJsonRpc client"
87
+ );
88
+ let a;
89
+ e.transaction instanceof l ? (e.transaction.setSenderIfNotSet(this.address), a = await e.transaction.build({
90
+ client: c
91
+ })) : a = e.transaction;
92
+ const m = await c.dryRunTransactionBlock({
93
+ transactionBlock: a
94
+ });
95
+ return o("dryRun", m);
96
+ }
97
+ const i = g(this.client);
98
+ if (typeof i?.executeTransaction == "function") {
99
+ let r;
100
+ e.transaction instanceof l ? (e.transaction.setSenderIfNotSet(this.address), r = await e.transaction.build({
101
+ client: this.client
102
+ })) : r = e.transaction;
103
+ const c = await this.signer.signTransaction(r), a = await i.executeTransaction({
104
+ transaction: C(c.bytes),
105
+ signatures: [c.signature],
106
+ include: d(s.options)
107
+ });
108
+ return o("execute", a);
109
+ }
110
+ const u = this.clientBundle.legacyJsonRpc;
111
+ if (!u)
112
+ throw new Error(
113
+ "WalletClient execution requires core.executeTransaction or an explicit legacyJsonRpc client"
114
+ );
115
+ const h = await u.signAndExecuteTransaction({
116
+ ...s,
117
+ options: f(s.options),
118
+ signer: this.signer
119
+ });
120
+ return o("execute", h);
121
+ }
122
+ /**
123
+ * Gets the wallet address from the signer's public key
124
+ * @returns The wallet address as a string
125
+ */
126
+ get address() {
127
+ return this.signer.getPublicKey().toSuiAddress();
128
+ }
129
+ /**
130
+ * Gets a specific module by name
131
+ * @param name - The name of the module to retrieve
132
+ * @returns The requested module instance
133
+ */
134
+ module(e) {
135
+ return this.modules[e];
136
+ }
137
+ /**
138
+ * Gets the configuration for a specific module
139
+ * @param name - The name of the module
140
+ * @returns The merged configuration (default + user config)
141
+ */
142
+ config(e) {
143
+ return {
144
+ ...this.modules[e].defaultConfig,
145
+ ...this.userConfigs[e]
146
+ };
147
+ }
148
+ /**
149
+ * Checks if a module is available
150
+ * @param name - The name of the module to check
151
+ * @returns True if the module exists, false otherwise
152
+ */
153
+ hasModule(e) {
154
+ return e in this.modules;
155
+ }
156
+ }
157
+ export {
158
+ O as WalletClient
159
+ };
160
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sources":["../src/client.ts"],"sourcesContent":["/**\n * Wallet Client - Core Client Implementation\n *\n * This module provides the main wallet client for interacting with the Sui blockchain.\n * It manages transaction signing, module integration, and provides a unified interface\n * for various DeFi operations including swaps, lending, and balance management.\n *\n * @module WalletClient\n */\n\nimport { Signer } from '@mysten/sui/cryptography'\nimport mitt, { Emitter } from 'mitt'\nimport { Module, ModuleConfig } from './modules/module'\nimport { modules, ModuleName, ModuleEvents } from './modules'\nimport { Transaction } from '@mysten/sui/transactions'\nimport { fromBase64 } from '@mysten/sui/utils'\nimport {\n DryRunOptions,\n NaviTransactionExecutionOptions,\n NaviWalletTransactionResult\n} from './types'\nimport { mergeTransactionResponseOptions, normalizeTransactionResult } from './transaction-result'\nimport {\n createNaviLegacyJsonRpcClient,\n createNaviSuiClientBundle,\n type NaviCoreClient,\n type NaviJsonRpcCompatClient,\n type NaviSdkServiceOptions,\n type NaviSuiClientBundle,\n type NaviSuiClientOptions,\n type NaviSuiLegacyJsonRpcOptions,\n type NaviSuiNetwork,\n PUBLIC_MAINNET_GRPC_URL\n} from '@naviprotocol/lending'\n\n/**\n * Extracts the configuration type from a module\n */\ntype ExtractModuleConfig<T> = T extends Module<infer TConfig, any> ? TConfig : never\n\n/**\n * User configuration type for all modules\n */\nexport type UserConfigs = {\n [K in ModuleName]: Partial<ExtractModuleConfig<(typeof modules)[K]>>\n}\n\n/**\n * Options for initializing the wallet client\n */\nexport type WalletClientOptions = {\n /** The signer for transaction signing */\n signer: Signer\n /** Optional module-specific configurations */\n configs?: Partial<UserConfigs>\n /**\n * Sui v2 client configuration. Optional (v1 parity): when omitted, a public\n * mainnet gRPC client is used — fine for development and low volume;\n * production should pass its own client (private endpoint / auth headers).\n */\n client?: NaviSuiClientOptions | WalletLegacyJsonRpcClientOptions\n}\n\nexport type WalletLegacyJsonRpcClientOptions = {\n network?: NaviSuiNetwork\n /**\n * @deprecated JSON-RPC is a short-lived compatibility transport. New paths must use `grpc`.\n */\n legacyJsonRpc: NaviSuiLegacyJsonRpcOptions\n services?: NaviSdkServiceOptions\n}\n\nfunction transactionIncludeOptions(options?: NaviTransactionExecutionOptions['options']) {\n const merged = mergeTransactionResponseOptions(options)\n return {\n effects: merged.showEffects,\n events: merged.showEvents,\n balanceChanges: merged.showBalanceChanges,\n objectTypes: merged.showObjectChanges\n }\n}\n\nfunction getCoreTransactionClient(client: unknown) {\n return (client as { core?: unknown }).core as\n | {\n simulateTransaction?(options: any): Promise<any>\n executeTransaction?(options: any): Promise<any>\n }\n | undefined\n}\n\nfunction isNaviSuiClientOptions(\n options: NaviSuiClientOptions | WalletLegacyJsonRpcClientOptions\n): options is NaviSuiClientOptions {\n return 'grpc' in options\n}\n\nfunction createWalletClientBundle(\n options: NaviSuiClientOptions | WalletLegacyJsonRpcClientOptions\n): NaviSuiClientBundle {\n if (isNaviSuiClientOptions(options)) {\n return createNaviSuiClientBundle(options)\n }\n const network = options.network ?? 'mainnet'\n const legacyJsonRpc = createNaviLegacyJsonRpcClient(network, options.legacyJsonRpc)\n return {\n network,\n coreClient: legacyJsonRpc,\n grpc: legacyJsonRpc,\n legacyJsonRpc,\n services: options.services\n }\n}\n\n/**\n * Main wallet client class that provides unified access to blockchain operations\n *\n * This class integrates various modules (swap, lending, balance, etc.) and provides\n * a consistent interface for interacting with the Sui blockchain. It handles\n * transaction signing, module management, and event emission.\n */\nexport class WalletClient {\n /** The signer instance for transaction signing */\n public readonly signer: Signer\n\n /** Available modules for different functionalities */\n private readonly modules = modules\n\n /** User-provided module configurations */\n private readonly userConfigs: Partial<UserConfigs> = {}\n\n /** Event emitter for module events */\n public readonly events: Emitter<ModuleEvents> = mitt()\n\n /** The Sui client instance */\n public readonly client: NaviCoreClient & Partial<NaviJsonRpcCompatClient>\n\n /** Normalized transport bundle for modules that need transport-specific clients. */\n public readonly clientBundle: NaviSuiClientBundle\n\n /** URL used by the default JSON-RPC client, when available. */\n public readonly clientUrl?: string\n\n public get lending() {\n return this.modules.lending\n }\n\n public get balance() {\n return this.modules.balance\n }\n\n public get volo() {\n return this.modules.volo\n }\n\n public get swap() {\n return this.modules.swap\n }\n\n public get haedal() {\n return this.modules.haedal\n }\n\n /**\n * Creates a new wallet client instance\n * @param options - Configuration options for the wallet client\n */\n constructor(options: WalletClientOptions) {\n // v1 parity: default to the public mainnet node when no client is given.\n const clientOptions = options.client ?? {\n network: 'mainnet' as const,\n grpc: { url: PUBLIC_MAINNET_GRPC_URL }\n }\n this.clientBundle = createWalletClientBundle(clientOptions)\n this.client = this.clientBundle.coreClient as NaviCoreClient & Partial<NaviJsonRpcCompatClient>\n this.clientUrl =\n 'grpc' in clientOptions\n ? clientOptions.legacyJsonRpc && 'url' in clientOptions.legacyJsonRpc\n ? clientOptions.legacyJsonRpc.url\n : undefined\n : 'url' in clientOptions.legacyJsonRpc\n ? clientOptions.legacyJsonRpc.url\n : undefined\n this.signer = options.signer\n this.userConfigs = options.configs || {}\n\n // Install all modules and validate their names\n Object.entries(this.modules).forEach(([name, module]) => {\n if (name !== module.name) {\n throw new Error(`Module name ${name} does not match module name ${module.name}`)\n }\n module.install(this)\n })\n }\n\n /**\n * Signs and executes a transaction block\n * @param options - Transaction execution options including dry run support\n * @returns Promise with transaction execution result\n */\n async signExecuteTransaction(\n options: {\n transaction: Uint8Array | Transaction\n } & NaviTransactionExecutionOptions &\n Partial<DryRunOptions>\n ): Promise<NaviWalletTransactionResult<boolean>> {\n const { dryRun = false, ...rest } = options\n\n if (dryRun) {\n const core = getCoreTransactionClient(this.client)\n if (typeof core?.simulateTransaction === 'function') {\n if (options.transaction instanceof Transaction) {\n options.transaction.setSenderIfNotSet(this.address)\n }\n const result = await core.simulateTransaction({\n transaction: options.transaction,\n include: transactionIncludeOptions(rest.options)\n })\n return normalizeTransactionResult('dryRun', result)\n }\n\n const legacyJsonRpc = this.clientBundle.legacyJsonRpc\n if (!legacyJsonRpc) {\n throw new Error(\n 'WalletClient dry-run requires core.simulateTransaction or an explicit legacyJsonRpc client'\n )\n }\n // Handle dry run mode for transaction simulation\n let txBytes\n if (options.transaction instanceof Transaction) {\n options.transaction.setSenderIfNotSet(this.address)\n txBytes = await options.transaction.build({\n client: legacyJsonRpc as any\n })\n } else {\n txBytes = options.transaction\n }\n const result = await legacyJsonRpc.dryRunTransactionBlock({\n transactionBlock: txBytes\n })\n return normalizeTransactionResult('dryRun', result)\n }\n\n const core = getCoreTransactionClient(this.client)\n if (typeof core?.executeTransaction === 'function') {\n let txBytes: Uint8Array\n if (options.transaction instanceof Transaction) {\n options.transaction.setSenderIfNotSet(this.address)\n txBytes = await options.transaction.build({\n client: this.client as any\n })\n } else {\n txBytes = options.transaction\n }\n const signed = await this.signer.signTransaction(txBytes)\n const result = await core.executeTransaction({\n transaction: fromBase64(signed.bytes),\n signatures: [signed.signature],\n include: transactionIncludeOptions(rest.options)\n })\n return normalizeTransactionResult('execute', result)\n }\n\n const legacyJsonRpc = this.clientBundle.legacyJsonRpc\n if (!legacyJsonRpc) {\n throw new Error(\n 'WalletClient execution requires core.executeTransaction or an explicit legacyJsonRpc client'\n )\n }\n // Execute the actual transaction\n const result = await legacyJsonRpc.signAndExecuteTransaction({\n ...rest,\n options: mergeTransactionResponseOptions(rest.options),\n signer: this.signer\n } as any)\n return normalizeTransactionResult('execute', result)\n }\n\n /**\n * Gets the wallet address from the signer's public key\n * @returns The wallet address as a string\n */\n get address(): string {\n return this.signer.getPublicKey().toSuiAddress()\n }\n\n /**\n * Gets a specific module by name\n * @param name - The name of the module to retrieve\n * @returns The requested module instance\n */\n module<TName extends ModuleName>(name: TName): (typeof modules)[TName] {\n return this.modules[name]\n }\n\n /**\n * Gets the configuration for a specific module\n * @param name - The name of the module\n * @returns The merged configuration (default + user config)\n */\n config<TName extends ModuleName>(name: TName): ExtractModuleConfig<(typeof modules)[TName]> {\n const mergedConfig = {\n ...this.modules[name].defaultConfig,\n ...this.userConfigs[name]\n }\n return mergedConfig as ExtractModuleConfig<(typeof modules)[TName]>\n }\n\n /**\n * Checks if a module is available\n * @param name - The name of the module to check\n * @returns True if the module exists, false otherwise\n */\n hasModule(name: ModuleName): boolean {\n return name in this.modules\n }\n}\n\nexport type { ModuleConfig }\n"],"names":["transactionIncludeOptions","options","merged","mergeTransactionResponseOptions","getCoreTransactionClient","client","isNaviSuiClientOptions","createWalletClientBundle","createNaviSuiClientBundle","network","legacyJsonRpc","createNaviLegacyJsonRpcClient","WalletClient","modules","mitt","clientOptions","PUBLIC_MAINNET_GRPC_URL","name","module","dryRun","rest","core","Transaction","result","normalizeTransactionResult","txBytes","signed","fromBase64"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * @module WalletClient
8
8
  */
9
- export * from './client';
10
- export * from './types';
11
- export * from './signer';
9
+ export * from './client.js';
10
+ export * from './types.js';
11
+ export * from './signer.js';
12
12
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ import { WalletClient as t } from "./client.js";
2
+ import { WatchSigner as i, WebSigner as l } from "./signer.js";
3
+ export {
4
+ t as WalletClient,
5
+ i as WatchSigner,
6
+ l as WebSigner
7
+ };
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
@@ -1,8 +1,8 @@
1
- import { Module } from '../module';
1
+ import { Module } from '../module.js';
2
2
  import { CoinStruct } from '@mysten/sui/jsonRpc';
3
- import { WalletClient } from '../../client';
4
- import { UserPortfolio } from './portfolio';
5
- import { NaviWalletTransactionResult } from '../../types';
3
+ import { WalletClient } from '../../client.js';
4
+ import { UserPortfolio } from './portfolio.js';
5
+ import { NaviWalletTransactionResult } from '../../types.js';
6
6
 
7
7
  /**
8
8
  * Configuration options for the balance module
@@ -0,0 +1,214 @@
1
+ import { Module as m } from "../module.js";
2
+ import { withSingleton as p, getCoins as b, mergeCoinsPTB as C, listAddressBalances as B } from "@naviprotocol/lending";
3
+ import { UserPortfolio as f } from "./portfolio.js";
4
+ import P from "bignumber.js";
5
+ import { Transaction as u } from "@mysten/sui/transactions";
6
+ import { normalizeStructTag as w } from "@mysten/sui/utils";
7
+ class v extends m {
8
+ constructor() {
9
+ super(...arguments), this.name = "balance", this.defaultConfig = {
10
+ coinPollingInterval: 6e3,
11
+ disableCoinPolling: !1
12
+ }, this.updatePortfolio = p(async () => {
13
+ if (!this.walletClient)
14
+ throw new Error("Wallet client not found");
15
+ this._coins = await b(this.walletClient.address, {
16
+ client: this.walletClient.client
17
+ });
18
+ const t = await this.getAddressBalanceMap();
19
+ this._portfolio = new f(this._coins, t), this.emit("balance:portfolio-updated", {});
20
+ }), this._coins = [], this._portfolio = new f(), this.pollingTimer = null, this._updatePromise = null;
21
+ }
22
+ /**
23
+ * Gets the current coin objects from the wallet
24
+ *
25
+ * @returns Array of coin objects owned by the wallet
26
+ */
27
+ get coins() {
28
+ return this._coins;
29
+ }
30
+ /**
31
+ * Gets the current portfolio information
32
+ *
33
+ * @returns UserPortfolio instance with current balance information
34
+ */
35
+ get portfolio() {
36
+ return this._portfolio;
37
+ }
38
+ /**
39
+ * Waits for the next portfolio update to complete
40
+ *
41
+ * @returns Promise that resolves when the portfolio is updated
42
+ * @throws Error if no update promise is available
43
+ */
44
+ async waitForUpdate() {
45
+ if (!this._updatePromise)
46
+ throw new Error("Update promise not found");
47
+ return await this._updatePromise;
48
+ }
49
+ /**
50
+ * Sends a single coin to a recipient
51
+ *
52
+ * @param coinType - Type of coin to send
53
+ * @param recipient - Recipient address
54
+ * @param amount - Amount to send
55
+ * @param options - Optional parameters including dry run mode
56
+ * @returns Transaction response or dry run response
57
+ */
58
+ async sendCoin(t, e, n, s) {
59
+ return this.sendCoinBatch(t, [e], [n], s);
60
+ }
61
+ /**
62
+ * Sends coins to multiple recipients in a single transaction
63
+ *
64
+ * @param coinType - Type of coin to send
65
+ * @param recipients - Array of recipient addresses
66
+ * @param amounts - Array of amounts to send (must match recipients length)
67
+ * @param options - Optional parameters including dry run mode
68
+ * @returns Transaction response or dry run response
69
+ */
70
+ async sendCoinBatch(t, e, n, s) {
71
+ if (!this.walletClient)
72
+ throw new Error("Wallet client not found");
73
+ if (e.length !== n.length)
74
+ throw new Error("Recipients and amounts must have the same length");
75
+ await this.waitForUpdate();
76
+ const o = this.portfolio.getBalance(t), i = w(t) === w("0x2::sui::SUI"), c = i ? o.amount : this.portfolio.combinedBalanceOf(t), d = n.reduce((r, l) => r.plus(l), P(0));
77
+ if (c.lt(d))
78
+ throw new Error("Insufficient balance");
79
+ const a = new u();
80
+ if (i) {
81
+ const r = a.splitCoins(a.gas, n);
82
+ e.forEach((l, h) => {
83
+ a.transferObjects([r[h]], l);
84
+ });
85
+ } else {
86
+ const r = C(a, o.coins, {
87
+ balance: d.toNumber(),
88
+ addressBalance: o.addressBalance.toFixed(0),
89
+ coinType: t
90
+ });
91
+ if (e.length === 1)
92
+ a.transferObjects([r], e[0]);
93
+ else {
94
+ const l = a.splitCoins(r, n.slice(0, -1));
95
+ e.slice(0, -1).forEach((h, g) => {
96
+ a.transferObjects([l[g]], h);
97
+ }), a.transferObjects([r], e[e.length - 1]);
98
+ }
99
+ }
100
+ return await this.walletClient.signExecuteTransaction({
101
+ transaction: a,
102
+ dryRun: s?.dryRun ?? !1
103
+ });
104
+ }
105
+ /**
106
+ * Transfers a single object to a recipient
107
+ *
108
+ * @param object - Object ID to transfer
109
+ * @param recipient - Recipient address
110
+ * @param options - Optional parameters including dry run mode
111
+ * @returns Transaction response or dry run response
112
+ */
113
+ async transferObject(t, e, n) {
114
+ return this.transferObjectBatch([t], [e], n);
115
+ }
116
+ /**
117
+ * Transfers multiple objects to their respective recipients in a single transaction
118
+ *
119
+ * Each object is transferred to its corresponding recipient by index
120
+ * (first object → first recipient, second object → second recipient, etc.)
121
+ *
122
+ * @param objects - Object IDs to transfer
123
+ * @param recipients - Recipient addresses (must match objects array length)
124
+ * @param options - Optional parameters including dry run mode
125
+ * @returns Transaction response or dry run response
126
+ */
127
+ async transferObjectBatch(t, e, n) {
128
+ if (!this.walletClient)
129
+ throw new Error("Wallet client not found");
130
+ if (t.length !== e.length)
131
+ throw new Error("Objects and recipients must have the same length");
132
+ await this.waitForUpdate();
133
+ const s = new u();
134
+ return t.forEach((i, c) => {
135
+ s.transferObjects([s.object(i)], e[c]);
136
+ }), await this.walletClient.signExecuteTransaction({
137
+ transaction: s,
138
+ dryRun: n?.dryRun ?? !1
139
+ });
140
+ }
141
+ /**
142
+ * Builds a map of coin type to address-level balance (v2 address balances).
143
+ *
144
+ * Feature-detects the v2 Core balance API on the injected client; when it is
145
+ * unavailable (legacy JSON-RPC only), returns an empty map so the portfolio
146
+ * falls back to coin-object-only behavior.
147
+ *
148
+ * @returns Map of normalized coin type to address balance (atomic units)
149
+ */
150
+ async getAddressBalanceMap() {
151
+ const t = {};
152
+ if (!this.walletClient)
153
+ return t;
154
+ const e = this.walletClient.client.core;
155
+ if (typeof e?.listBalances != "function" || typeof e?.getBalance != "function")
156
+ return t;
157
+ try {
158
+ let n = null;
159
+ do {
160
+ const { balances: s, nextCursor: o } = await B(this.walletClient.client, {
161
+ owner: this.walletClient.address,
162
+ cursor: n,
163
+ limit: 100
164
+ });
165
+ for (const i of s)
166
+ i.addressBalance && i.addressBalance !== "0" && (t[i.coinType] = i.addressBalance);
167
+ n = o;
168
+ } while (n);
169
+ } catch (n) {
170
+ console.error(n);
171
+ }
172
+ return t;
173
+ }
174
+ /**
175
+ * Starts polling for portfolio updates
176
+ *
177
+ * This method recursively schedules itself to run at the configured
178
+ * interval, ensuring regular balance updates.
179
+ */
180
+ async startPolling() {
181
+ if (!this.config.disableCoinPolling)
182
+ try {
183
+ await this.updatePortfolio();
184
+ } catch (t) {
185
+ console.error(t);
186
+ } finally {
187
+ this.pollingTimer = setTimeout(this.startPolling, this.config.coinPollingInterval);
188
+ }
189
+ }
190
+ /**
191
+ * Installs the balance module into a wallet client
192
+ *
193
+ * @param walletClient - The wallet client instance to install into
194
+ */
195
+ install(t) {
196
+ super.install(t), this.startPolling = this.startPolling.bind(this), this.startPolling(), this._updatePromise = new Promise((e) => {
197
+ t.events.on("balance:portfolio-updated", () => {
198
+ e();
199
+ });
200
+ });
201
+ }
202
+ /**
203
+ * Uninstalls the balance module from the wallet client
204
+ *
205
+ * This method cleans up timers and stops polling to prevent memory leaks.
206
+ */
207
+ uninstall() {
208
+ super.uninstall(), this.pollingTimer && (clearTimeout(this.pollingTimer), this.pollingTimer = null);
209
+ }
210
+ }
211
+ export {
212
+ v as BalanceModule
213
+ };
214
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../src/modules/balanceModule/index.ts"],"sourcesContent":["/**\n * Balance Module Implementation\n *\n * This module provides comprehensive balance management functionality for the wallet client.\n * It handles coin tracking, portfolio management, coin transfers, and automatic balance updates\n * through polling mechanisms.\n *\n * @module BalanceModule\n */\n\nimport { Module } from '../module'\nimport { getCoins, mergeCoinsPTB, withSingleton, listAddressBalances } from '@naviprotocol/lending'\nimport type { CoinStruct } from '@mysten/sui/jsonRpc'\nimport type { WalletClient } from '../../client'\nimport { UserPortfolio } from './portfolio'\nimport BigNumber from 'bignumber.js'\nimport { Transaction } from '@mysten/sui/transactions'\nimport type { NaviWalletTransactionResult } from '../../types'\nimport { normalizeStructTag } from '@mysten/sui/utils'\n\n/**\n * Configuration options for the balance module\n */\nexport interface BalanceModuleConfig {\n /** Interval in milliseconds for polling coin balances */\n coinPollingInterval: number\n /** Whether to disable coin polling */\n disableCoinPolling: boolean\n}\n\n/**\n * Events emitted by the balance module\n */\nexport type Events = {\n /** Emitted when the portfolio is updated with new balance information */\n 'balance:portfolio-updated': {}\n}\n\n/**\n * Balance management module for wallet operations\n *\n * This module provides functionality for:\n * - Tracking coin balances and portfolio information\n * - Sending coins to recipients\n * - Transferring objects\n * - Automatic balance updates through polling\n * - Portfolio management and balance queries\n */\nexport class BalanceModule extends Module<BalanceModuleConfig, Events> {\n /** Module name identifier */\n readonly name = 'balance'\n\n /** Default configuration values */\n readonly defaultConfig = {\n coinPollingInterval: 6000,\n disableCoinPolling: false\n }\n\n /**\n * Gets the current coin objects from the wallet\n *\n * @returns Array of coin objects owned by the wallet\n */\n public get coins() {\n return this._coins\n }\n\n /**\n * Gets the current portfolio information\n *\n * @returns UserPortfolio instance with current balance information\n */\n public get portfolio() {\n return this._portfolio\n }\n\n /**\n * Waits for the next portfolio update to complete\n *\n * @returns Promise that resolves when the portfolio is updated\n * @throws Error if no update promise is available\n */\n public async waitForUpdate() {\n if (!this._updatePromise) {\n throw new Error('Update promise not found')\n }\n return await this._updatePromise\n }\n\n /**\n * Sends a single coin to a recipient\n *\n * @param coinType - Type of coin to send\n * @param recipient - Recipient address\n * @param amount - Amount to send\n * @param options - Optional parameters including dry run mode\n * @returns Transaction response or dry run response\n */\n public async sendCoin<T extends boolean = false>(\n coinType: string,\n recipient: string,\n amount: number,\n options?: { dryRun: T }\n ): Promise<NaviWalletTransactionResult<T>> {\n return this.sendCoinBatch(coinType, [recipient], [amount], options)\n }\n\n /**\n * Sends coins to multiple recipients in a single transaction\n *\n * @param coinType - Type of coin to send\n * @param recipients - Array of recipient addresses\n * @param amounts - Array of amounts to send (must match recipients length)\n * @param options - Optional parameters including dry run mode\n * @returns Transaction response or dry run response\n */\n public async sendCoinBatch<T extends boolean = false>(\n coinType: string,\n recipients: string[],\n amounts: number[],\n options?: { dryRun: T }\n ): Promise<NaviWalletTransactionResult<T>> {\n if (!this.walletClient) {\n throw new Error('Wallet client not found')\n }\n if (recipients.length !== amounts.length) {\n throw new Error('Recipients and amounts must have the same length')\n }\n\n // Wait for latest portfolio update\n await this.waitForUpdate()\n\n // Check if sufficient balance is available. SUI is funded from the gas coin\n // below (address balance is not spendable on that path), so its sufficiency\n // counts coin objects only; other coins can redeem the address balance via\n // mergeCoinsPTB, so they count the combined total.\n const coinBalance = this.portfolio.getBalance(coinType)\n const isSui = normalizeStructTag(coinType) === normalizeStructTag('0x2::sui::SUI')\n const spendable = isSui ? coinBalance.amount : this.portfolio.combinedBalanceOf(coinType)\n const totalAmount = amounts.reduce((acc, curr) => acc.plus(curr), BigNumber(0))\n if (spendable.lt(totalAmount)) {\n throw new Error('Insufficient balance')\n }\n\n // Build transaction\n const tx = new Transaction()\n\n if (isSui) {\n // SUI: split each share from the gas coin; the leftover stays on the gas\n // coin, so there is no dangling zero-balance result.\n const shares = tx.splitCoins(tx.gas, amounts)\n recipients.forEach((address, index) => {\n tx.transferObjects([shares[index]], address)\n })\n } else {\n // Non-SUI: mergeCoinsPTB returns a coin holding EXACTLY totalAmount. It may\n // be a redeem_funds result (address balance) with no owned object to\n // absorb leftover, so a plain splitCoins of every share would leave the\n // source at zero balance and unused (Coin has no `drop` ability → PTB\n // fails). Instead split the first n-1 shares and transfer the source coin\n // itself as the last share, fully consuming it.\n const mergedCoin = mergeCoinsPTB(tx, coinBalance.coins, {\n balance: totalAmount.toNumber(),\n addressBalance: coinBalance.addressBalance.toFixed(0),\n coinType\n })\n if (recipients.length === 1) {\n tx.transferObjects([mergedCoin], recipients[0])\n } else {\n const headShares = tx.splitCoins(mergedCoin, amounts.slice(0, -1))\n recipients.slice(0, -1).forEach((address, index) => {\n tx.transferObjects([headShares[index]], address)\n })\n tx.transferObjects([mergedCoin], recipients[recipients.length - 1])\n }\n }\n\n // Execute transaction\n const result = await this.walletClient.signExecuteTransaction({\n transaction: tx,\n dryRun: options?.dryRun ?? false\n })\n\n return result as any\n }\n\n /**\n * Transfers a single object to a recipient\n *\n * @param object - Object ID to transfer\n * @param recipient - Recipient address\n * @param options - Optional parameters including dry run mode\n * @returns Transaction response or dry run response\n */\n async transferObject<T extends boolean = false>(\n object: string,\n recipient: string,\n options?: { dryRun: T }\n ): Promise<NaviWalletTransactionResult<T>> {\n return this.transferObjectBatch([object], [recipient], options)\n }\n\n /**\n * Transfers multiple objects to their respective recipients in a single transaction\n *\n * Each object is transferred to its corresponding recipient by index\n * (first object → first recipient, second object → second recipient, etc.)\n *\n * @param objects - Object IDs to transfer\n * @param recipients - Recipient addresses (must match objects array length)\n * @param options - Optional parameters including dry run mode\n * @returns Transaction response or dry run response\n */\n async transferObjectBatch<T extends boolean = false>(\n objects: string[],\n recipients: string[],\n options?: { dryRun: T }\n ): Promise<NaviWalletTransactionResult<T>> {\n if (!this.walletClient) {\n throw new Error('Wallet client not found')\n }\n\n if (objects.length !== recipients.length) {\n throw new Error('Objects and recipients must have the same length')\n }\n\n // Wait for latest portfolio update\n await this.waitForUpdate()\n\n // Build transaction\n const tx = new Transaction()\n\n // Transfer objects to recipients\n objects.forEach((object, index) => {\n tx.transferObjects([tx.object(object)], recipients[index])\n })\n\n // Execute transaction\n const result = await this.walletClient.signExecuteTransaction({\n transaction: tx,\n dryRun: options?.dryRun ?? false\n })\n\n return result as any\n }\n\n /**\n * Updates the portfolio with current coin information\n *\n * This function is wrapped with singleton behavior to prevent\n * concurrent updates and ensure data consistency.\n */\n updatePortfolio = withSingleton(async () => {\n if (!this.walletClient) {\n throw new Error('Wallet client not found')\n }\n\n // Fetch current coins from the wallet\n this._coins = await getCoins(this.walletClient.address, {\n client: this.walletClient.client\n })\n\n // Also fetch funds held at the address level (v2 address balances). Coin\n // objects only cover `Coin<T>` objects, so this map lets sufficiency checks\n // and coin selection see the full spendable total.\n const addressBalances = await this.getAddressBalanceMap()\n\n // Update portfolio with new coin data\n this._portfolio = new UserPortfolio(this._coins, addressBalances)\n\n // Emit portfolio update event\n this.emit('balance:portfolio-updated', {})\n })\n\n /**\n * Builds a map of coin type to address-level balance (v2 address balances).\n *\n * Feature-detects the v2 Core balance API on the injected client; when it is\n * unavailable (legacy JSON-RPC only), returns an empty map so the portfolio\n * falls back to coin-object-only behavior.\n *\n * @returns Map of normalized coin type to address balance (atomic units)\n */\n private async getAddressBalanceMap(): Promise<{ [key in string]?: string }> {\n const map: { [key in string]?: string } = {}\n if (!this.walletClient) {\n return map\n }\n const core = (this.walletClient.client as { core?: Record<string, unknown> }).core\n if (typeof core?.listBalances !== 'function' || typeof core?.getBalance !== 'function') {\n return map\n }\n try {\n let cursor: string | null | undefined = null\n do {\n const { balances, nextCursor } = await listAddressBalances(this.walletClient.client, {\n owner: this.walletClient.address,\n cursor,\n limit: 100\n })\n for (const balance of balances) {\n // Only track coin types that actually hold funds at the address level\n // to avoid creating empty portfolio entries.\n if (balance.addressBalance && balance.addressBalance !== '0') {\n map[balance.coinType] = balance.addressBalance\n }\n }\n cursor = nextCursor\n } while (cursor)\n } catch (error) {\n console.error(error)\n }\n return map\n }\n\n /** Current coin objects from the wallet */\n private _coins: CoinStruct[] = []\n\n /** Current portfolio information */\n private _portfolio: UserPortfolio = new UserPortfolio()\n\n /** Timer for polling balance updates */\n private pollingTimer: NodeJS.Timeout | null = null\n\n /** Promise for waiting on portfolio updates */\n private _updatePromise: Promise<void> | null = null\n\n /**\n * Starts polling for portfolio updates\n *\n * This method recursively schedules itself to run at the configured\n * interval, ensuring regular balance updates.\n */\n private async startPolling() {\n if (this.config.disableCoinPolling) {\n return\n }\n\n try {\n await this.updatePortfolio()\n } catch (error) {\n console.error(error)\n } finally {\n this.pollingTimer = setTimeout(this.startPolling, this.config.coinPollingInterval)\n }\n }\n\n /**\n * Installs the balance module into a wallet client\n *\n * @param walletClient - The wallet client instance to install into\n */\n install(walletClient: WalletClient) {\n super.install(walletClient)\n\n // Bind the polling method and start polling\n this.startPolling = this.startPolling.bind(this)\n this.startPolling()\n\n // Create update promise for waiting on portfolio updates\n this._updatePromise = new Promise((resolve) => {\n walletClient.events.on('balance:portfolio-updated', () => {\n resolve()\n })\n })\n }\n\n /**\n * Uninstalls the balance module from the wallet client\n *\n * This method cleans up timers and stops polling to prevent memory leaks.\n */\n uninstall() {\n super.uninstall()\n if (this.pollingTimer) {\n clearTimeout(this.pollingTimer)\n this.pollingTimer = null\n }\n }\n}\n"],"names":["BalanceModule","Module","withSingleton","getCoins","addressBalances","UserPortfolio","coinType","recipient","amount","options","recipients","amounts","coinBalance","isSui","normalizeStructTag","spendable","totalAmount","acc","curr","BigNumber","tx","Transaction","shares","address","index","mergedCoin","mergeCoinsPTB","headShares","object","objects","map","core","cursor","balances","nextCursor","listAddressBalances","balance","error","walletClient","resolve"],"mappings":"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"}
@@ -0,0 +1,105 @@
1
+ import { BigNumber as s } from "bignumber.js";
2
+ import { normalizeStructTag as l } from "@mysten/sui/utils";
3
+ class i {
4
+ /**
5
+ * Creates a new user portfolio
6
+ *
7
+ * @param coins - Array of coin objects or existing portfolio to copy from
8
+ * @param addressBalances - Optional map of normalized coin type to funds held
9
+ * directly at the address level (v2 address balances). Coin objects only
10
+ * account for `Coin<T>` objects, so this carries the balance that lives at
11
+ * the address and is not represented by any object. Defaults to empty,
12
+ * which preserves legacy coin-object-only behavior.
13
+ */
14
+ constructor(a, o) {
15
+ if (a instanceof i)
16
+ this.balances = JSON.parse(JSON.stringify(a.balances)), Object.values(this.balances).forEach((n) => {
17
+ n.amount = s(n.amount), n.addressBalance = s(n.addressBalance ?? 0);
18
+ });
19
+ else {
20
+ const n = {};
21
+ a?.forEach((t) => {
22
+ if (!t.coinType || t.balance === void 0 || t.balance === null)
23
+ return;
24
+ const c = l(t.coinType);
25
+ let e = n[c];
26
+ e || (e = {
27
+ coinType: c,
28
+ amount: s(0),
29
+ addressBalance: s(0),
30
+ coins: []
31
+ }, n[c] = e), e.coins.push(t), e.amount = e.amount.plus(t.balance);
32
+ }), o && Object.entries(o).forEach(([t, c]) => {
33
+ if (c == null)
34
+ return;
35
+ const e = l(t);
36
+ let r = n[e];
37
+ r || (r = {
38
+ coinType: e,
39
+ amount: s(0),
40
+ addressBalance: s(0),
41
+ coins: []
42
+ }, n[e] = r), r.addressBalance = s(c);
43
+ }), this.balances = n;
44
+ }
45
+ }
46
+ /**
47
+ * Gets balance information for a specific coin type
48
+ *
49
+ * @param coinType - The coin type to query
50
+ * @returns UserCoinBalance object with coin type, total amount, and coin objects
51
+ */
52
+ getBalance(a) {
53
+ return a = l(a), this.balances[a] || {
54
+ coinType: a,
55
+ amount: s(0),
56
+ addressBalance: s(0),
57
+ coins: []
58
+ };
59
+ }
60
+ /**
61
+ * Gets the combined total balance for a coin type: the sum of coin objects
62
+ * (`amount`) plus funds held at the address level (`addressBalance`). Use
63
+ * this for sufficiency checks; use `.amount` when you specifically need the
64
+ * coin-object-only sum.
65
+ *
66
+ * @param coinType - The coin type to query
67
+ * @returns BigNumber representing the combined total balance
68
+ */
69
+ combinedBalanceOf(a) {
70
+ const o = this.getBalance(a);
71
+ return o.amount.plus(o.addressBalance ?? 0);
72
+ }
73
+ /**
74
+ * Gets all coin types in the portfolio
75
+ *
76
+ * @returns Array of coin type strings
77
+ */
78
+ getCoinTypes() {
79
+ return Object.values(this.balances).map((a) => a.coinType);
80
+ }
81
+ /**
82
+ * Gets the total balance amount for a specific coin type
83
+ *
84
+ * @param coinType - The coin type to query
85
+ * @returns BigNumber representing the total balance
86
+ */
87
+ balanceOf(a) {
88
+ return a = l(a), this.getBalance(a)?.amount || s(0);
89
+ }
90
+ /**
91
+ * Creates a deep copy of the portfolio
92
+ *
93
+ * This method creates a completely independent copy of the portfolio
94
+ * that can be modified without affecting the original.
95
+ *
96
+ * @returns New UserPortfolio instance with copied data
97
+ */
98
+ clone() {
99
+ return new i(this);
100
+ }
101
+ }
102
+ export {
103
+ i as UserPortfolio
104
+ };
105
+ //# sourceMappingURL=portfolio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"portfolio.js","sources":["../../../src/modules/balanceModule/portfolio.ts"],"sourcesContent":["/**\n * User Portfolio Management\n *\n * This module provides portfolio management functionality for tracking\n * user coin balances across different token types. It aggregates coin\n * objects by type and provides convenient methods for balance queries\n * and portfolio operations.\n *\n * @module UserPortfolio\n */\n\nimport type { CoinStruct } from '@mysten/sui/jsonRpc'\nimport { BigNumber } from 'bignumber.js'\nimport { normalizeStructTag } from '@mysten/sui/utils'\n\n/**\n * User portfolio for managing coin balances\n *\n * This class provides functionality to:\n * - Aggregate coins by type and calculate total balances\n * - Query balances for specific coin types\n * - Clone portfolio state for safe operations\n * - Normalize coin types for consistent comparison\n */\nexport class UserPortfolio {\n /** Mapping of coin types to their balance information */\n balances: { [key in string]: UserCoinBalance }\n\n /**\n * Creates a new user portfolio\n *\n * @param coins - Array of coin objects or existing portfolio to copy from\n * @param addressBalances - Optional map of normalized coin type to funds held\n * directly at the address level (v2 address balances). Coin objects only\n * account for `Coin<T>` objects, so this carries the balance that lives at\n * the address and is not represented by any object. Defaults to empty,\n * which preserves legacy coin-object-only behavior.\n */\n constructor(\n coins?: CoinStruct[] | UserPortfolio,\n addressBalances?: { [key in string]?: BigNumber.Value }\n ) {\n if (coins instanceof UserPortfolio) {\n // Copy from existing portfolio\n this.balances = JSON.parse(JSON.stringify(coins.balances))\n // JSON round-trips BigNumber to string, so rehydrate BigNumber fields.\n Object.values(this.balances).forEach((balance) => {\n balance.amount = BigNumber(balance.amount)\n balance.addressBalance = BigNumber(balance.addressBalance ?? 0)\n })\n } else {\n // Build portfolio from coin objects\n const balances: { [key in string]: UserCoinBalance } = {}\n\n coins?.forEach((item) => {\n if (!item.coinType || item.balance === undefined || item.balance === null) {\n return\n }\n // Normalize coin type for consistent key usage\n const normalizedCoinType = normalizeStructTag(item.coinType)\n let existPofolio = balances[normalizedCoinType]\n\n // Create new balance entry if it doesn't exist\n if (!existPofolio) {\n existPofolio = {\n coinType: normalizedCoinType,\n amount: BigNumber(0),\n addressBalance: BigNumber(0),\n coins: []\n }\n balances[normalizedCoinType] = existPofolio\n }\n\n // Add coin to balance and update total amount\n existPofolio.coins.push(item)\n existPofolio.amount = existPofolio.amount.plus(item.balance)\n })\n\n // Merge in address-level balances (v2). A coin type may have an address\n // balance without any coin objects, so create entries as needed.\n if (addressBalances) {\n Object.entries(addressBalances).forEach(([coinType, value]) => {\n if (value === undefined || value === null) {\n return\n }\n const normalizedCoinType = normalizeStructTag(coinType)\n let existPofolio = balances[normalizedCoinType]\n if (!existPofolio) {\n existPofolio = {\n coinType: normalizedCoinType,\n amount: BigNumber(0),\n addressBalance: BigNumber(0),\n coins: []\n }\n balances[normalizedCoinType] = existPofolio\n }\n existPofolio.addressBalance = BigNumber(value)\n })\n }\n\n this.balances = balances\n }\n }\n\n /**\n * Gets balance information for a specific coin type\n *\n * @param coinType - The coin type to query\n * @returns UserCoinBalance object with coin type, total amount, and coin objects\n */\n getBalance(coinType: string): UserCoinBalance {\n coinType = normalizeStructTag(coinType)\n return (\n this.balances[coinType] || {\n coinType,\n amount: BigNumber(0),\n addressBalance: BigNumber(0),\n coins: []\n }\n )\n }\n\n /**\n * Gets the combined total balance for a coin type: the sum of coin objects\n * (`amount`) plus funds held at the address level (`addressBalance`). Use\n * this for sufficiency checks; use `.amount` when you specifically need the\n * coin-object-only sum.\n *\n * @param coinType - The coin type to query\n * @returns BigNumber representing the combined total balance\n */\n combinedBalanceOf(coinType: string) {\n const balance = this.getBalance(coinType)\n return balance.amount.plus(balance.addressBalance ?? 0)\n }\n\n /**\n * Gets all coin types in the portfolio\n *\n * @returns Array of coin type strings\n */\n getCoinTypes() {\n return Object.values(this.balances).map((item) => {\n return item.coinType\n })\n }\n\n /**\n * Gets the total balance amount for a specific coin type\n *\n * @param coinType - The coin type to query\n * @returns BigNumber representing the total balance\n */\n balanceOf(coinType: string) {\n coinType = normalizeStructTag(coinType)\n const balance = this.getBalance(coinType)\n return balance?.amount || BigNumber(0)\n }\n\n /**\n * Creates a deep copy of the portfolio\n *\n * This method creates a completely independent copy of the portfolio\n * that can be modified without affecting the original.\n *\n * @returns New UserPortfolio instance with copied data\n */\n clone() {\n // Reuse the copy constructor, which deep-copies and rehydrates the\n // BigNumber fields (amount / addressBalance). Assigning JSON-parsed\n // balances directly would leave them as plain strings and break `.plus` /\n // `.toFixed` on the clone.\n return new UserPortfolio(this)\n }\n}\n\n/**\n * Balance information for a specific coin type\n *\n * This type represents the aggregated balance information for all\n * coins of a particular type in the user's portfolio.\n */\nexport type UserCoinBalance = {\n /** Normalized coin type string */\n coinType: string\n /** Total balance across all coin objects (`Coin<T>`) of this type */\n amount: BigNumber\n /**\n * Funds held directly at the address level (v2 address balances) for this\n * coin type. Not represented by any coin object. Defaults to `0`. The\n * combined spendable total is `amount + addressBalance`.\n */\n addressBalance: BigNumber\n /** Array of individual coin objects */\n coins: CoinStruct[]\n}\n"],"names":["UserPortfolio","coins","addressBalances","balance","BigNumber","balances","item","normalizedCoinType","normalizeStructTag","existPofolio","coinType","value"],"mappings":";;AAwBO,MAAMA,EAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAczB,YACEC,GACAC,GACA;AACA,QAAID,aAAiBD;AAEnB,WAAK,WAAW,KAAK,MAAM,KAAK,UAAUC,EAAM,QAAQ,CAAC,GAEzD,OAAO,OAAO,KAAK,QAAQ,EAAE,QAAQ,CAACE,MAAY;AAChD,QAAAA,EAAQ,SAASC,EAAUD,EAAQ,MAAM,GACzCA,EAAQ,iBAAiBC,EAAUD,EAAQ,kBAAkB,CAAC;AAAA,MAChE,CAAC;AAAA,SACI;AAEL,YAAME,IAAiD,CAAA;AAEvD,MAAAJ,GAAO,QAAQ,CAACK,MAAS;AACvB,YAAI,CAACA,EAAK,YAAYA,EAAK,YAAY,UAAaA,EAAK,YAAY;AACnE;AAGF,cAAMC,IAAqBC,EAAmBF,EAAK,QAAQ;AAC3D,YAAIG,IAAeJ,EAASE,CAAkB;AAG9C,QAAKE,MACHA,IAAe;AAAA,UACb,UAAUF;AAAA,UACV,QAAQH,EAAU,CAAC;AAAA,UACnB,gBAAgBA,EAAU,CAAC;AAAA,UAC3B,OAAO,CAAA;AAAA,QAAC,GAEVC,EAASE,CAAkB,IAAIE,IAIjCA,EAAa,MAAM,KAAKH,CAAI,GAC5BG,EAAa,SAASA,EAAa,OAAO,KAAKH,EAAK,OAAO;AAAA,MAC7D,CAAC,GAIGJ,KACF,OAAO,QAAQA,CAAe,EAAE,QAAQ,CAAC,CAACQ,GAAUC,CAAK,MAAM;AAC7D,YAA2BA,KAAU;AACnC;AAEF,cAAMJ,IAAqBC,EAAmBE,CAAQ;AACtD,YAAID,IAAeJ,EAASE,CAAkB;AAC9C,QAAKE,MACHA,IAAe;AAAA,UACb,UAAUF;AAAA,UACV,QAAQH,EAAU,CAAC;AAAA,UACnB,gBAAgBA,EAAU,CAAC;AAAA,UAC3B,OAAO,CAAA;AAAA,QAAC,GAEVC,EAASE,CAAkB,IAAIE,IAEjCA,EAAa,iBAAiBL,EAAUO,CAAK;AAAA,MAC/C,CAAC,GAGH,KAAK,WAAWN;AAAA,IAClB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,WAAWK,GAAmC;AAC5C,WAAAA,IAAWF,EAAmBE,CAAQ,GAEpC,KAAK,SAASA,CAAQ,KAAK;AAAA,MACzB,UAAAA;AAAA,MACA,QAAQN,EAAU,CAAC;AAAA,MACnB,gBAAgBA,EAAU,CAAC;AAAA,MAC3B,OAAO,CAAA;AAAA,IAAC;AAAA,EAGd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,kBAAkBM,GAAkB;AAClC,UAAMP,IAAU,KAAK,WAAWO,CAAQ;AACxC,WAAOP,EAAQ,OAAO,KAAKA,EAAQ,kBAAkB,CAAC;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eAAe;AACb,WAAO,OAAO,OAAO,KAAK,QAAQ,EAAE,IAAI,CAACG,MAChCA,EAAK,QACb;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,UAAUI,GAAkB;AAC1B,WAAAA,IAAWF,EAAmBE,CAAQ,GACtB,KAAK,WAAWA,CAAQ,GACxB,UAAUN,EAAU,CAAC;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,QAAQ;AAKN,WAAO,IAAIJ,EAAc,IAAI;AAAA,EAC/B;AACF;"}
@@ -1,7 +1,7 @@
1
1
  import { CoinObject, NaviSdkServiceOptions } from '@naviprotocol/lending';
2
2
  import { Transaction } from '@mysten/sui/transactions';
3
- import { Module } from '../module';
4
- import { NaviWalletTransactionResult } from '../../types';
3
+ import { Module } from '../module.js';
4
+ import { NaviWalletTransactionResult } from '../../types.js';
5
5
 
6
6
  /**
7
7
  * Configuration for the Haedal module