@upshiftfinance/sdk 0.3.0 → 0.5.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.
Files changed (61) hide show
  1. package/README.md +6 -2
  2. package/esm/index.d.mts +15 -0
  3. package/esm/index.mjs +18 -0
  4. package/lib/abis/KycRegistry.d.ts +109 -0
  5. package/lib/abis/KycRegistry.js +73 -0
  6. package/lib/abis/index.d.ts +1 -0
  7. package/lib/abis/index.js +1 -0
  8. package/lib/adapters/sui/actions.d.ts +420 -0
  9. package/lib/adapters/sui/actions.js +701 -0
  10. package/lib/adapters/sui/client.d.ts +3 -3
  11. package/lib/adapters/sui/client.js +27 -9
  12. package/lib/adapters/sui/getters.d.ts +268 -0
  13. package/lib/adapters/sui/getters.js +669 -0
  14. package/lib/adapters/sui/index.d.ts +243 -3
  15. package/lib/adapters/sui/index.js +250 -3
  16. package/lib/adapters/sui/targets.d.ts +42 -1
  17. package/lib/adapters/sui/targets.js +42 -1
  18. package/lib/core/analytics/method-taxonomy.d.ts +1 -1
  19. package/lib/core/analytics/method-taxonomy.js +9 -0
  20. package/lib/core/analytics/version.d.ts +1 -1
  21. package/lib/core/analytics/version.js +1 -1
  22. package/lib/core/constants/core.d.ts +5 -0
  23. package/lib/core/constants/core.js +5 -0
  24. package/lib/core/constants/kyc.d.ts +9 -0
  25. package/lib/core/constants/kyc.js +12 -0
  26. package/lib/core/constants/web3.d.ts +2 -2
  27. package/lib/core/constants/web3.js +9 -2
  28. package/lib/core/errors/index.d.ts +90 -1
  29. package/lib/core/errors/index.js +94 -1
  30. package/lib/core/fetcher.d.ts +5 -0
  31. package/lib/core/fetcher.js +1 -1
  32. package/lib/core/helpers/chain-support.d.ts +2 -2
  33. package/lib/core/helpers/chain-support.js +3 -3
  34. package/lib/core/helpers/kyc.d.ts +47 -0
  35. package/lib/core/helpers/kyc.js +111 -0
  36. package/lib/core/helpers/revert-decode.js +3 -2
  37. package/lib/core/index.d.ts +2 -0
  38. package/lib/core/index.js +2 -0
  39. package/lib/evm/methods/crossChainVault.js +25 -43
  40. package/lib/index.d.ts +4 -0
  41. package/lib/index.js +4 -0
  42. package/lib/main.d.ts +33 -3
  43. package/lib/main.js +32 -0
  44. package/lib/modules/api/kyc.d.ts +4 -0
  45. package/lib/modules/api/kyc.js +148 -0
  46. package/lib/modules/api/main.d.ts +63 -1
  47. package/lib/modules/api/main.js +64 -0
  48. package/lib/modules/vaults/getters.d.ts +3 -1
  49. package/lib/modules/vaults/getters.js +82 -10
  50. package/lib/modules/vaults/main.d.ts +41 -3
  51. package/lib/modules/vaults/main.js +82 -6
  52. package/lib/modules/vaults/types.d.ts +7 -1
  53. package/lib/modules/vaults/utils.js +4 -1
  54. package/lib/sdk.d.ts +16363 -14615
  55. package/lib/types/index.d.ts +1 -0
  56. package/lib/types/index.js +1 -0
  57. package/lib/types/kyc.d.ts +61 -0
  58. package/lib/types/kyc.js +3 -0
  59. package/lib/types/vaults.d.ts +2 -0
  60. package/lib/types/webserver.d.ts +5 -0
  61. package/package.json +21 -2
@@ -43,7 +43,7 @@ export declare function suiEndpointHost(url: string): string;
43
43
  *
44
44
  * @param err - What the call rejected with.
45
45
  * @returns `true` for transport failures, gRPC statuses in
46
- * {@link RETRYABLE_GRPC_CODES}, a bare `NOT_FOUND` (the endpoint has no Sui
46
+ * `RETRYABLE_GRPC_CODES`, a bare `NOT_FOUND` (the endpoint has no Sui
47
47
  * gRPC service at that path) and the SDK's own call timeout.
48
48
  * @internal
49
49
  */
@@ -58,8 +58,8 @@ export declare function setSuiClientFactoryForTests(factory: SuiClientFactory |
58
58
  * Run a Sui call against the first endpoint that answers.
59
59
  *
60
60
  * Endpoints are tried in order, starting with the one that last worked (for
61
- * {@link PREFERRED_ENDPOINT_TTL_MS}). An endpoint failure — see
62
- * {@link isRetryableSuiError} — moves on to the next endpoint; any other error
61
+ * `PREFERRED_ENDPOINT_TTL_MS`). An endpoint failure — see
62
+ * `isRetryableSuiError` — moves on to the next endpoint; any other error
63
63
  * is thrown at once. Each attempt is bounded by a 15 s timeout.
64
64
  *
65
65
  * Worst case: one attempt per endpoint (two with a consumer `rpcUrl`).
@@ -99,7 +99,7 @@ function suiEndpointHost(url) {
99
99
  *
100
100
  * @param err - What the call rejected with.
101
101
  * @returns `true` for transport failures, gRPC statuses in
102
- * {@link RETRYABLE_GRPC_CODES}, a bare `NOT_FOUND` (the endpoint has no Sui
102
+ * `RETRYABLE_GRPC_CODES`, a bare `NOT_FOUND` (the endpoint has no Sui
103
103
  * gRPC service at that path) and the SDK's own call timeout.
104
104
  * @internal
105
105
  */
@@ -115,14 +115,29 @@ function isRetryableSuiError(err) {
115
115
  return false;
116
116
  if (RETRYABLE_GRPC_CODES.has(code))
117
117
  return true;
118
- // A path with no gRPC service answers HTTP 404, which the transport reports
119
- // as NOT_FOUND with no message; a missing object is a different error type.
120
- return code === 'NOT_FOUND' && err.message === '';
118
+ // An endpoint with no Sui gRPC service at that path answers a bare HTTP 404
119
+ // or 400. The transport reports those as NOT_FOUND / INVALID_ARGUMENT whose
120
+ // message is the HTTP status text ('' over HTTP/2, the reason phrase over
121
+ // HTTP/1.1). Errors from the Sui service itself carry their own message.
122
+ return ((code === 'NOT_FOUND' &&
123
+ (err.message === '' || err.message === 'Not Found')) ||
124
+ (code === 'INVALID_ARGUMENT' && err.message === 'Bad Request'));
121
125
  }
122
- /** Default factory: loads `@mysten/sui/grpc` on first use. */
126
+ /**
127
+ * Default factory: loads `@mysten/sui/grpc` on first use. A failure to load
128
+ * the module is about the runtime, not the endpoint, so it is thrown as an
129
+ * SDK error that {@link withSuiClient} does not retry: in Node.js, requiring
130
+ * the ESM-only package needs `^20.19 || >=22.12`.
131
+ */
123
132
  const defaultClientFactory = async (baseUrl, network) => {
124
- const { SuiGrpcClient } = await Promise.resolve().then(() => __importStar(require('@mysten/sui/grpc')));
125
- return new SuiGrpcClient({ baseUrl, network });
133
+ let grpc;
134
+ try {
135
+ grpc = await Promise.resolve().then(() => __importStar(require('@mysten/sui/grpc')));
136
+ }
137
+ catch (err) {
138
+ throw new errors_1.UpshiftSDKError('UNKNOWN', `Sui support could not load @mysten/sui — in Node.js it needs version ^20.19 or >=22.12: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
139
+ }
140
+ return new grpc.SuiGrpcClient({ baseUrl, network });
126
141
  };
127
142
  let clientFactory = defaultClientFactory;
128
143
  const clientCache = new Map();
@@ -151,8 +166,8 @@ function clientFor(url, network) {
151
166
  * Run a Sui call against the first endpoint that answers.
152
167
  *
153
168
  * Endpoints are tried in order, starting with the one that last worked (for
154
- * {@link PREFERRED_ENDPOINT_TTL_MS}). An endpoint failure — see
155
- * {@link isRetryableSuiError} — moves on to the next endpoint; any other error
169
+ * `PREFERRED_ENDPOINT_TTL_MS`). An endpoint failure — see
170
+ * `isRetryableSuiError` — moves on to the next endpoint; any other error
156
171
  * is thrown at once. Each attempt is bounded by a 15 s timeout.
157
172
  *
158
173
  * Worst case: one attempt per endpoint (two with a consumer `rpcUrl`).
@@ -185,6 +200,9 @@ async function withSuiClient(config, call) {
185
200
  client = await clientFor(url, config.network);
186
201
  }
187
202
  catch (err) {
203
+ // The SDK could not load its Sui client at all: no endpoint can help.
204
+ if (err instanceof errors_1.UpshiftSDKError)
205
+ throw err;
188
206
  // A malformed endpoint (e.g. a typo'd consumer rpcUrl) must not disable
189
207
  // the endpoints behind it.
190
208
  lastError = err;
@@ -0,0 +1,268 @@
1
+ import { type ISuiConfig, type ISuiNetwork, type ITokenizedVault, type IVault, type IVaultAvailableRedemption } from '../../types';
2
+ import type { IVaultBaseOptions } from '../../modules/vaults/types';
3
+ /** The vault a read is for: its object ID, coin types and network. */
4
+ export interface ISuiVaultRef {
5
+ /** Vault object ID (`0x` + 64 hex chars). */
6
+ vaultId: string;
7
+ /** Move type of the deposit coin. */
8
+ assetCoinType: string;
9
+ /** Move type of the vault's share coin. */
10
+ shareCoinType: string;
11
+ /** Network the vault lives on. */
12
+ network: ISuiNetwork;
13
+ }
14
+ /**
15
+ * A vault's on-chain state. Amounts are raw base units: assets in the deposit
16
+ * coin's decimals, shares in {@link ISuiVaultState.decimals} (the contract
17
+ * requires the share coin to use the deposit coin's decimals).
18
+ */
19
+ export interface ISuiVaultState {
20
+ /** Net assets: idle + deployed AUM − collectable fees, floored at 0. */
21
+ totalAssets: bigint;
22
+ /** Minted shares, including shares escrowed in withdrawal requests. */
23
+ totalSupply: bigint;
24
+ /** Asset base units per `10^decimals` shares. */
25
+ sharePrice: bigint;
26
+ /** Share (and deposit coin) decimals. */
27
+ decimals: number;
28
+ /** Deposits, redemptions and new requests abort while paused. */
29
+ paused: boolean;
30
+ /** Whether a withdrawal queue is attached; instant `redeem` is off when it is. */
31
+ queueAttached: boolean;
32
+ /** Smallest accepted deposit, in asset base units. */
33
+ minDeposit: bigint;
34
+ /** Ceiling on total assets after a deposit, in asset base units. */
35
+ depositCap: bigint;
36
+ /** Largest single deposit, in asset base units. */
37
+ maxDepositAmount: bigint;
38
+ /** Largest single gross withdrawal, in asset base units. */
39
+ maxWithdrawalAmount: bigint;
40
+ /** Fee charged by instant `redeem`, in basis points of the gross amount. */
41
+ instantRedemptionFeeBps: number;
42
+ }
43
+ /**
44
+ * Decode a little-endian BCS unsigned integer of `size` bytes.
45
+ * @internal
46
+ */
47
+ export declare function decodeSuiUint(bytes: Uint8Array, size: number): bigint;
48
+ /**
49
+ * Decode a BCS `bool`.
50
+ * @internal
51
+ */
52
+ export declare function decodeSuiBool(bytes: Uint8Array): boolean;
53
+ /**
54
+ * Read the instant-redemption fee from the vault object's JSON fields: the fee
55
+ * sits in a nested struct that a transaction cannot return.
56
+ * @internal
57
+ */
58
+ export declare function parseInstantRedemptionFeeBps(json: unknown): number;
59
+ /**
60
+ * The `sui` config to use for a vault on `network`: the consumer's config when
61
+ * it is for that network, else the network alone (built-in endpoint and
62
+ * contract IDs). A testnet override must never serve a mainnet vault.
63
+ * @internal
64
+ */
65
+ export declare function suiConfigForNetwork(network: ISuiNetwork, sui?: ISuiConfig): ISuiConfig;
66
+ /**
67
+ * Read a vault's on-chain state.
68
+ *
69
+ * RPC cost: two requests, run in parallel: one transaction simulation and one
70
+ * object read. `getVaults` makes these two per Sui vault.
71
+ *
72
+ * @param ref - The vault and its coin types and network.
73
+ * @param sui - The SDK's `sui` config; applied only when its network matches
74
+ * `ref.network`.
75
+ * @returns The vault's state; see {@link ISuiVaultState} for units.
76
+ * @throws {@link UpshiftValidationError} (`INVALID_ADDRESS`) for a malformed
77
+ * vault ID, (`INVALID_INPUT`) when the contract IDs for the network are not
78
+ * known or the simulation aborts (wrong vault, coin types or package).
79
+ * @throws {@link UpshiftNetworkError} when every Sui endpoint fails.
80
+ * @example
81
+ * ```ts
82
+ * const state = await readSuiVaultState(
83
+ * { vaultId, assetCoinType, shareCoinType, network: 'testnet' },
84
+ * { network: 'testnet', packageId, originalPackageId, registryId },
85
+ * );
86
+ * ```
87
+ */
88
+ export declare function readSuiVaultState(ref: ISuiVaultRef, sui?: ISuiConfig): Promise<ISuiVaultState>;
89
+ /**
90
+ * Shares a deposit would mint at the current price. Limits are not checked.
91
+ *
92
+ * RPC cost: one transaction simulation.
93
+ *
94
+ * @param ref - The vault and its coin types and network.
95
+ * @param assets - Deposit amount in asset base units.
96
+ * @param sui - The SDK's `sui` config; applied only for `ref.network`.
97
+ * @returns Shares in share base units.
98
+ * @throws {@link UpshiftValidationError} for a malformed vault ID, a negative
99
+ * or out-of-range amount, unknown contract IDs or an aborted simulation.
100
+ * @throws {@link UpshiftNetworkError} when every Sui endpoint fails.
101
+ */
102
+ export declare function previewSuiDeposit(ref: ISuiVaultRef, assets: bigint, sui?: ISuiConfig): Promise<bigint>;
103
+ /**
104
+ * Assets a redemption of `shares` would pay at the current price.
105
+ *
106
+ * RPC cost: one transaction simulation.
107
+ *
108
+ * @param ref - The vault and its coin types and network.
109
+ * @param shares - Shares to redeem, in share base units.
110
+ * @param isInstant - `true` for instant `redeem` (charges the instant fee),
111
+ * `false` for a queued withdrawal (no fee).
112
+ * @param sui - The SDK's `sui` config; applied only for `ref.network`.
113
+ * @returns `gross` and `net` (after the instant fee) in asset base units.
114
+ * @throws {@link UpshiftValidationError} for a malformed vault ID, a negative
115
+ * or out-of-range amount, unknown contract IDs or an aborted simulation.
116
+ * @throws {@link UpshiftNetworkError} when every Sui endpoint fails.
117
+ */
118
+ export declare function previewSuiRedemption(ref: ISuiVaultRef, shares: bigint, isInstant: boolean, sui?: ISuiConfig): Promise<{
119
+ gross: bigint;
120
+ net: bigint;
121
+ }>;
122
+ /**
123
+ * A wallet's balance of a share coin: coin objects plus the address balance.
124
+ *
125
+ * RPC cost: one balance read.
126
+ *
127
+ * @param owner - Wallet address (`0x` + 64 hex chars).
128
+ * @param shareCoinType - Move type of the vault's share coin.
129
+ * @param network - Network to read.
130
+ * @param sui - The SDK's `sui` config; applied only for `network`.
131
+ * @returns Shares in share base units.
132
+ * @throws {@link UpshiftValidationError} (`INVALID_ADDRESS`) for a malformed
133
+ * owner.
134
+ * @throws {@link UpshiftNetworkError} when every Sui endpoint fails.
135
+ */
136
+ export declare function getSuiShareBalance(owner: string, shareCoinType: string, network: ISuiNetwork, sui?: ISuiConfig): Promise<bigint>;
137
+ /**
138
+ * A pending withdrawal request: shares escrowed in a queued vault, waiting to
139
+ * be claimed or cancelled. Times are Unix milliseconds from the chain's clock.
140
+ */
141
+ export interface ISuiWithdrawalRequest {
142
+ /** Request object ID; pass it as `request` to claim or cancel. */
143
+ request: string;
144
+ /** The wallet's numeric ID for the request on this vault (`0, 1, 2, …`). */
145
+ requestId: bigint;
146
+ /** Wallet that made the request; the only one that may cancel it. */
147
+ owner: string;
148
+ /** Escrowed shares, in share base units. Priced when the request is claimed. */
149
+ shares: bigint;
150
+ /** Address the claim pays, into its address balance. */
151
+ payout: string;
152
+ /**
153
+ * The one address besides the owner that may claim, or `null` when anyone
154
+ * may. From one day after `eligibleAtMs` anyone may claim either way.
155
+ */
156
+ finalizer: string | null;
157
+ /** When the request was made. */
158
+ requestedAtMs: number;
159
+ /** When the cooldown ends and the request can be claimed. */
160
+ eligibleAtMs: number;
161
+ /**
162
+ * When the request stops being claimable (it can still be cancelled), or
163
+ * `null` when it never expires.
164
+ */
165
+ expiresAtMs: number | null;
166
+ }
167
+ /**
168
+ * A wallet's pending withdrawal requests on a vault, oldest first.
169
+ *
170
+ * Finds the requests the SDK made (see `buildSuiRequestRedeemTransaction`),
171
+ * however old: requests made outside the SDK with non-sequential IDs are not
172
+ * listed. Claimed and cancelled requests no longer exist and are left out.
173
+ *
174
+ * RPC cost: one object read for a wallet that has made up to 23 requests on
175
+ * the vault (most wallets), one more per further 25.
176
+ *
177
+ * @param ref - The vault and its coin types and network.
178
+ * @param owner - Wallet that made the requests (`0x` + 64 hex chars).
179
+ * @param sui - The SDK's `sui` config; applied only for `ref.network`.
180
+ * @returns The pending requests; empty when there are none.
181
+ * @throws {@link UpshiftValidationError} (`INVALID_ADDRESS`) for a malformed
182
+ * vault ID or owner, (`INVALID_INPUT`) for unknown contract IDs, or a vault
183
+ * ID that is not a vault of the configured `sui.originalPackageId`.
184
+ * @throws {@link UpshiftNetworkError} when every Sui endpoint fails, or the
185
+ * node cannot answer for one of the objects.
186
+ * @example
187
+ * ```ts
188
+ * const pending = await getSuiWithdrawalRequests(ref, account.address, sdkSuiConfig);
189
+ * const now = Date.now();
190
+ * const claimable = pending.filter(
191
+ * (r) => r.eligibleAtMs <= now && (r.expiresAtMs === null || now < r.expiresAtMs),
192
+ * );
193
+ * ```
194
+ */
195
+ export declare function getSuiWithdrawalRequests(ref: ISuiVaultRef, owner: string, sui?: ISuiConfig): Promise<ISuiWithdrawalRequest[]>;
196
+ /**
197
+ * Split a wallet's withdrawal requests into position redemptions, the way
198
+ * the EVM and Solana paths do: `availableRedemptions` holds requests still in
199
+ * their cooldown or past their window (cancel-only), `pendingRedemptions` the
200
+ * ones claimable now. Each entry's `amount` is the escrowed shares; `date` is
201
+ * when it becomes claimable, `timestamp` when it was made (Unix seconds).
202
+ * @internal
203
+ */
204
+ export declare function suiPositionRedemptions(requests: readonly ISuiWithdrawalRequest[], vault: string, decimals: number, nowMs: number): {
205
+ availableRedemptions: IVaultAvailableRedemption[];
206
+ pendingRedemptions: IVaultAvailableRedemption[];
207
+ };
208
+ /**
209
+ * A wallet's withdrawal requests on a vault as position redemptions (see
210
+ * {@link suiPositionRedemptions}). Empty when the SDK has no contract IDs for
211
+ * the network: the share balance can still be read without them, so a
212
+ * position should not fail for that.
213
+ *
214
+ * RPC cost: as {@link getSuiWithdrawalRequests}; none without contract IDs.
215
+ * @internal
216
+ */
217
+ export declare function getSuiPositionRedemptions(ref: ISuiVaultRef, owner: string, decimals: number, sui?: ISuiConfig): Promise<ReturnType<typeof suiPositionRedemptions>>;
218
+ /**
219
+ * The request ID a wallet's next withdrawal request on a vault takes: the
220
+ * lowest it has never used.
221
+ *
222
+ * RPC cost: as {@link getSuiWithdrawalRequests}.
223
+ * @internal
224
+ */
225
+ export declare function nextSuiWithdrawalRequestId(ref: ISuiVaultRef, owner: string, sui?: ISuiConfig): Promise<bigint>;
226
+ /**
227
+ * The object ID of a wallet's withdrawal request: derived from the vault, the
228
+ * owner and the request ID, as the contract derives it.
229
+ *
230
+ * @param vaultId - Vault object ID.
231
+ * @param owner - Wallet that made the request.
232
+ * @param requestId - The wallet's numeric request ID on the vault.
233
+ * @param originalPackageId - The original `upshift_vault` package, which
234
+ * names the derivation key type.
235
+ * @returns The request object ID.
236
+ * @internal
237
+ */
238
+ export declare function deriveSuiWithdrawalRequestId(vaultId: string, owner: string, requestId: bigint, originalPackageId: string): Promise<string>;
239
+ /**
240
+ * The vault reference for a backend row, or `null` when the row has no usable
241
+ * `sui_vault_metadata`.
242
+ * @internal
243
+ */
244
+ export declare function suiVaultRefFromRow(row: ITokenizedVault): ISuiVaultRef | null;
245
+ /**
246
+ * Build the SDK's `IVault` for a Sui vault from its backend row and, when the
247
+ * read succeeded, its on-chain state. Without state, total assets fall back
248
+ * to the backend's `latest_reported_tvl`, supply to zero, and the vault is
249
+ * marked deposit-paused so no deposit is offered on unread state.
250
+ * @internal
251
+ */
252
+ export declare function buildSuiVault(row: ITokenizedVault, state: ISuiVaultState | null): IVault;
253
+ /**
254
+ * Build a Sui vault's `IVault` from its backend row plus on-chain state.
255
+ *
256
+ * A failed read (unknown contract IDs, every endpoint down, an aborted
257
+ * simulation) does not fail the call: the vault is built from the backend row
258
+ * alone (see `buildSuiVault`) and a warning is logged.
259
+ *
260
+ * RPC cost: as {@link readSuiVaultState}.
261
+ *
262
+ * @param row - Backend `tokenized_vault` row with `sui_vault_metadata`.
263
+ * @param options - Vault options; `options.sui` carries the SDK's `sui` config.
264
+ * @returns The vault.
265
+ * @throws {@link UpshiftValidationError} (`INVALID_INPUT`) when the row has no
266
+ * usable `sui_vault_metadata` (e.g. a legacy Ember/Gamma Sui vault).
267
+ */
268
+ export declare function getSuiVault(row: ITokenizedVault, options?: IVaultBaseOptions): Promise<IVault>;