@rhea-finance/confidential-swap 0.2.1 → 0.2.2

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/README.md CHANGED
@@ -69,7 +69,7 @@ const result = await client.execute(plan, {
69
69
 
70
70
  The example assumes the application's existing wallet, asset, funding adapter and progress objects. The SDK does not connect wallets or manage UI. Connect and choose those objects in the application; do not pass private keys into the SDK. Quote plans have a default maximum age of 10 minutes, bounded by any earlier service-provided deadline; configure `maxQuoteAgeMs` when a different review window is required.
71
71
 
72
- `Token.assetId` identifies the registry asset. `blockchain` names its chain. `contractAddress` identifies its actual on-chain token. For numeric EVM funding identities supply the matching token `swapChain` (e.g. `"1"`); `swapAddress` explicitly maps an asset to the aggregation SDK's token address/native sentinel. No arbitrary EVM chain is guessed from `evm` kind alone.
72
+ `Token.assetId` identifies the registry asset. `blockchain` names its chain. `contractAddress` identifies its actual on-chain token. For numeric EVM funding identities supply the matching token `swapChain` (e.g. `"1"`); `swapAddress` explicitly maps an asset to the funding swap token address/native sentinel used by the injected `FundingSwapAdapter`. No arbitrary EVM chain is guessed from `evm` kind alone.
73
73
 
74
74
  `preview` accepts an optional linking identity and returns `executable: false`. A placeholder identity is display-only. Preview/quote may allocate deposit addresses on the backend, but neither signs nor broadcasts funds. `quote` requires a real linking identity. Default withdrawal fees match the reference app: 2 bps to `dcl0001.near`, referral `rhea`. App fees are attached only to withdrawal quotes; funding deposit quotes do not include them. Configured `appFees` must contain at least one valid NEAR recipient and an integer fee from 1 to 10000.
75
75
 
@@ -77,7 +77,7 @@ The example assumes the application's existing wallet, asset, funding adapter an
77
77
 
78
78
  `FundingAdapter.getIdentity` returns `{ kind, accountId, chain }`. Its `validate` checks capability and the source chain without sending funds. Its `transfer` receives the real source token, smallest-unit amount, deposit address, optional memo and stable execution ID. Return a source transaction hash. Implement chain-specific transfer logic with the application's existing wallet SDK; an adapter must check identity again immediately before signing/broadcasting.
79
79
 
80
- For non-DIRECT funding, the funding adapter still validates the source wallet and chain, while `FundingSwapAdapter` performs quote/build/execute/report/status. Its quote data must be public and JSON-serializable. Its executor must use exactly the supplied source identity, chain and deposit recipient.
80
+ For non-DIRECT funding, the funding adapter still validates the source wallet and chain, while `FundingSwapAdapter` performs quote/build/execute/report/status. Its quote data must be public and JSON-serializable. Its executor must use exactly the supplied source identity, chain and deposit recipient. The application owns the swap/bridge implementation; this package does not depend on a specific aggregation SDK.
81
81
 
82
82
  | Path | Waiting sequence |
83
83
  | --- | --- |
@@ -85,38 +85,12 @@ For non-DIRECT funding, the funding adapter still validates the source wallet an
85
85
  | SAME_CHAIN_SWAP | Swap to FLEX_INPUT, report, wait only for confidential deposit and balance |
86
86
  | CROSS_CHAIN_SWAP | Swap to FLEX_INPUT, report, wait for swap record success, then deposit and balance |
87
87
 
88
- All paths authorize the linking identity before sending source funds. Routing prefers registered direct assets, then same-chain USDC/USDT/USDT0, then a NEAR asset or another registry asset. Native NEAR maps to wNEAR. FLEX minimum input is checked against the final aggregation minimum output, with bounded requotes.
88
+ All paths authorize the linking identity before sending source funds. Routing prefers registered direct assets, then same-chain USDC/USDT/USDT0, then a NEAR asset or another registry asset. Native NEAR maps to wNEAR. FLEX minimum input is checked against the final funding-swap minimum output, with bounded requotes.
89
89
 
90
90
  `fundingSource: 'balance'` spends only the requested amount from an existing registered confidential balance, without a source transaction. These balance withdrawals are checkpointed in process memory only and are never written to the configured `executionStore`, so they are not recoverable after reload. `mode: 'TRANSFER'` requires the same funding and destination asset; otherwise mode defaults to `SWAP`. A batch has 1-10 unique recipients on one destination chain and asset. Randomized positive shares preserve the exact raw total with roughly 80-120 percent equal-share bounds, allowing integer rounding. The frozen random fractions are stored in the plan and reused after re-quoting or recovery against the actual credited amount.
91
91
 
92
92
  Supply `addressValidator` for BTC/Zcash or unsupported destination chains, using an established chain library. Known EVM, NEAR, Solana, Tron, Aptos and Sui address formats are checked by default. Case-sensitive addresses are never lowercased or silently truncated.
93
93
 
94
- ## Aggregation bridge
95
-
96
- The optional `@rhea-finance/confidential-swap/aggregation` entry exposes `createAggregationFundingAdapter` and `HttpFundingReporter`. Install the optional peer `@rhea-finance/cross-chain-aggregation-dex@^2.0.6` when using its bridge/types.
97
-
98
- ```ts
99
- import { SwapClient } from '@rhea-finance/cross-chain-aggregation-dex';
100
- import {
101
- createAggregationFundingAdapter,
102
- HttpFundingReporter,
103
- } from '@rhea-finance/confidential-swap/aggregation';
104
-
105
- const swapClient = new SwapClient({
106
- baseUrl: indexerUrl,
107
- apiKey: configuredApiToken,
108
- reportMode: 'manual', // no duplicate automatic reports
109
- executors: sourceChainExecutors,
110
- });
111
- const fundingSwapAdapter = createAggregationFundingAdapter({
112
- client: swapClient,
113
- reporter: new HttpFundingReporter({ baseUrl: indexerUrl, bearerToken: configuredApiToken }),
114
- mapAsset: token => ({ chain: mapSwapChain(token), address: mapSwapAddress(token) }),
115
- });
116
- ```
117
-
118
- Unlike the aggregation SDK's ordinary order query, advanced funding status uses `/api/swap/order-status?recordId=...`. The reporter sends `confidentiality: 'advanced'`. API credentials must be provided by the application, not copied from the reference repository.
119
-
120
94
  ## Intent protocol boundary
121
95
 
122
96
  Withdrawal payloads are signed as returned by `/generate-intent`, matching the reference implementation. The SDK does not enforce a local transfer format or compare intent tokens and amounts against the quote. Signers, standards, nonces, deadlines and signatures are independently validated. NEP-413 withdrawal recipients are signed exactly as returned; authorization still requires the configured verifier. NEP-413 nonces accept Base64 or Base64URL and must decode to 32 bytes.
@@ -143,7 +117,7 @@ This is confidential-account orchestration, not a guarantee of end-to-end anonym
143
117
 
144
118
  ## Verification status
145
119
 
146
- Local tests exercise actual cryptographic signatures, the three-path/four-linking-kind matrix, source wallet separation, randomized integer bounds, HTTP fixtures, session recovery, ambiguous writes, partial statuses, price re-review and the published aggregation SDK client with mocked transport/execution. Packed ESM/CJS and consumer declarations are checked without React, wallet SDKs or the aggregation peer installed.
120
+ Local tests exercise actual cryptographic signatures, the three-path/four-linking-kind matrix, source wallet separation, randomized integer bounds, HTTP fixtures, session recovery, ambiguous writes, partial statuses and price re-review. Packed ESM/CJS and consumer declarations are checked without React or wallet SDKs installed.
147
121
 
148
122
  Signature domain implementations follow the primary [NEAR NEP-413 specification](https://github.com/near/NEPs/blob/master/neps/nep-0413.md) and [TronWeb message implementation](https://github.com/tronprotocol/tronweb/blob/master/src/utils/message.ts).
149
123
 
@@ -1,5 +1,4 @@
1
- import { H as HttpConfidentialApi } from '../api-DfwMJoId.cjs';
2
- import { S as SigningAdapter } from '../types-DiDsRTKv.cjs';
1
+ import { S as SigningAdapter, H as HttpConfidentialApi } from '../api-QSK8yzxM.cjs';
3
2
 
4
3
  interface EvmMessageSigner {
5
4
  getAddress(): Promise<string>;
@@ -1,5 +1,4 @@
1
- import { H as HttpConfidentialApi } from '../api-Cs0IyUJf.js';
2
- import { S as SigningAdapter } from '../types-DiDsRTKv.js';
1
+ import { S as SigningAdapter, H as HttpConfidentialApi } from '../api-QSK8yzxM.js';
3
2
 
4
3
  interface EvmMessageSigner {
5
4
  getAddress(): Promise<string>;
@@ -292,4 +292,55 @@ interface ExecuteOptions {
292
292
  onSignatureProgress?: (progress: SignatureProgress) => void;
293
293
  }
294
294
 
295
- export type { AppFeeEstimate as A, Balance as B, ConfidentialApi as C, ExecutionSnapshot as E, FundingSwapAdapter as F, LinkingKind as L, OrderPage as O, PollingOptions as P, QuotePlan as Q, SigningAdapter as S, Token as T, UnsignedData as U, WalletKind as W, LinkingIdentity as a, FundingIdentity as b, SigningStandard as c, FundingRoute as d, FundingAdapter as e, SessionStore as f, ExecutionStore as g, QuoteResponse as h, QuoteRequest as i, Login as j, ExecuteOptions as k, ExecutionStage as l, FundingReceipt as m, FundingRouteKind as n, FundingSwapQuote as o, PrivateOrder as p, PrivateWithdrawRequest as q, PrivateWithdrawRow as r, QuoteParams as s, Session as t, SignatureProgress as u, SignedData as v, StatusResponse as w, SwapFundingRequest as x, WithdrawPreview as y, WithdrawProgress as z };
295
+ interface AppFee {
296
+ recipient: string;
297
+ fee: number;
298
+ }
299
+ interface HttpApiConfig {
300
+ /** Full /v0 URL; balances are sent here, never to the proxy. */
301
+ directUrl: string;
302
+ /** Full /proxy/1click/v0 URL. */
303
+ proxyUrl: string;
304
+ /** Indexer root URL. */
305
+ indexerUrl: string;
306
+ nearRpcUrl: string;
307
+ intentsContract?: string;
308
+ fetch?: typeof fetch;
309
+ now?: () => number;
310
+ randomBytes?: (length: number) => Uint8Array;
311
+ /** Reference implementation submits signed payloads without Bearer. */
312
+ withdrawAuthorization?: "signed-payload" | "bearer";
313
+ referral?: string;
314
+ appFees?: AppFee[];
315
+ requestTimeoutMs?: number;
316
+ }
317
+ declare class HttpConfidentialApi implements ConfidentialApi {
318
+ private readonly config;
319
+ readonly environment: string;
320
+ readonly intentsContract: string;
321
+ private readonly fetcher;
322
+ private readonly now;
323
+ private readonly direct;
324
+ private readonly proxy;
325
+ private readonly indexer;
326
+ private readonly appFees;
327
+ constructor(config: HttpApiConfig);
328
+ private request;
329
+ viewIntents<T>(method: string, args: Record<string, unknown>, signal?: AbortSignal): Promise<T>;
330
+ createAuthPayload(signerId: string, standard: SigningStandard, signal?: AbortSignal): Promise<UnsignedData>;
331
+ private session;
332
+ authenticate(data: SignedData, signal?: AbortSignal): Promise<Session>;
333
+ refresh(session: Session, signal?: AbortSignal): Promise<Session>;
334
+ getTokens(signal?: AbortSignal): Promise<Token[]>;
335
+ getBalances(token: string, signal?: AbortSignal): Promise<Balance[]>;
336
+ estimateWithdrawalAppFee(amount: string, assetId: string): AppFeeEstimate;
337
+ quote(params: QuoteParams, signal?: AbortSignal): Promise<QuoteResponse>;
338
+ generateIntent(signerId: string, address: string, standard: SigningStandard, signal?: AbortSignal): Promise<UnsignedData>;
339
+ submitIntent(signedData: SignedData, signal?: AbortSignal): Promise<string>;
340
+ private privateRequest;
341
+ submitWithdraws(request: PrivateWithdrawRequest, token: string, signal?: AbortSignal): Promise<string>;
342
+ getStatus(address: string, memo?: string, signal?: AbortSignal): Promise<StatusResponse>;
343
+ getOrders(token: string, signerId: string, limit: number, offset: number, signal?: AbortSignal): Promise<OrderPage>;
344
+ }
345
+
346
+ export { type AppFee as A, type Balance as B, type ConfidentialApi as C, type WithdrawPreview as D, type ExecutionStore as E, type FundingIdentity as F, type WithdrawProgress as G, HttpConfidentialApi as H, type LinkingKind as L, type OrderPage as O, type PollingOptions as P, type QuotePlan as Q, type SigningAdapter as S, type Token as T, type UnsignedData as U, type WalletKind as W, type LinkingIdentity as a, type SigningStandard as b, type FundingRoute as c, type FundingAdapter as d, type FundingSwapAdapter as e, type SessionStore as f, type QuoteResponse as g, type QuoteRequest as h, type Login as i, type ExecutionSnapshot as j, type ExecuteOptions as k, type AppFeeEstimate as l, type ExecutionStage as m, type FundingReceipt as n, type FundingRouteKind as o, type FundingSwapQuote as p, type HttpApiConfig as q, type PrivateOrder as r, type PrivateWithdrawRequest as s, type PrivateWithdrawRow as t, type QuoteParams as u, type Session as v, type SignatureProgress as w, type SignedData as x, type StatusResponse as y, type SwapFundingRequest as z };
@@ -292,4 +292,55 @@ interface ExecuteOptions {
292
292
  onSignatureProgress?: (progress: SignatureProgress) => void;
293
293
  }
294
294
 
295
- export type { AppFeeEstimate as A, Balance as B, ConfidentialApi as C, ExecutionSnapshot as E, FundingSwapAdapter as F, LinkingKind as L, OrderPage as O, PollingOptions as P, QuotePlan as Q, SigningAdapter as S, Token as T, UnsignedData as U, WalletKind as W, LinkingIdentity as a, FundingIdentity as b, SigningStandard as c, FundingRoute as d, FundingAdapter as e, SessionStore as f, ExecutionStore as g, QuoteResponse as h, QuoteRequest as i, Login as j, ExecuteOptions as k, ExecutionStage as l, FundingReceipt as m, FundingRouteKind as n, FundingSwapQuote as o, PrivateOrder as p, PrivateWithdrawRequest as q, PrivateWithdrawRow as r, QuoteParams as s, Session as t, SignatureProgress as u, SignedData as v, StatusResponse as w, SwapFundingRequest as x, WithdrawPreview as y, WithdrawProgress as z };
295
+ interface AppFee {
296
+ recipient: string;
297
+ fee: number;
298
+ }
299
+ interface HttpApiConfig {
300
+ /** Full /v0 URL; balances are sent here, never to the proxy. */
301
+ directUrl: string;
302
+ /** Full /proxy/1click/v0 URL. */
303
+ proxyUrl: string;
304
+ /** Indexer root URL. */
305
+ indexerUrl: string;
306
+ nearRpcUrl: string;
307
+ intentsContract?: string;
308
+ fetch?: typeof fetch;
309
+ now?: () => number;
310
+ randomBytes?: (length: number) => Uint8Array;
311
+ /** Reference implementation submits signed payloads without Bearer. */
312
+ withdrawAuthorization?: "signed-payload" | "bearer";
313
+ referral?: string;
314
+ appFees?: AppFee[];
315
+ requestTimeoutMs?: number;
316
+ }
317
+ declare class HttpConfidentialApi implements ConfidentialApi {
318
+ private readonly config;
319
+ readonly environment: string;
320
+ readonly intentsContract: string;
321
+ private readonly fetcher;
322
+ private readonly now;
323
+ private readonly direct;
324
+ private readonly proxy;
325
+ private readonly indexer;
326
+ private readonly appFees;
327
+ constructor(config: HttpApiConfig);
328
+ private request;
329
+ viewIntents<T>(method: string, args: Record<string, unknown>, signal?: AbortSignal): Promise<T>;
330
+ createAuthPayload(signerId: string, standard: SigningStandard, signal?: AbortSignal): Promise<UnsignedData>;
331
+ private session;
332
+ authenticate(data: SignedData, signal?: AbortSignal): Promise<Session>;
333
+ refresh(session: Session, signal?: AbortSignal): Promise<Session>;
334
+ getTokens(signal?: AbortSignal): Promise<Token[]>;
335
+ getBalances(token: string, signal?: AbortSignal): Promise<Balance[]>;
336
+ estimateWithdrawalAppFee(amount: string, assetId: string): AppFeeEstimate;
337
+ quote(params: QuoteParams, signal?: AbortSignal): Promise<QuoteResponse>;
338
+ generateIntent(signerId: string, address: string, standard: SigningStandard, signal?: AbortSignal): Promise<UnsignedData>;
339
+ submitIntent(signedData: SignedData, signal?: AbortSignal): Promise<string>;
340
+ private privateRequest;
341
+ submitWithdraws(request: PrivateWithdrawRequest, token: string, signal?: AbortSignal): Promise<string>;
342
+ getStatus(address: string, memo?: string, signal?: AbortSignal): Promise<StatusResponse>;
343
+ getOrders(token: string, signerId: string, limit: number, offset: number, signal?: AbortSignal): Promise<OrderPage>;
344
+ }
345
+
346
+ export { type AppFee as A, type Balance as B, type ConfidentialApi as C, type WithdrawPreview as D, type ExecutionStore as E, type FundingIdentity as F, type WithdrawProgress as G, HttpConfidentialApi as H, type LinkingKind as L, type OrderPage as O, type PollingOptions as P, type QuotePlan as Q, type SigningAdapter as S, type Token as T, type UnsignedData as U, type WalletKind as W, type LinkingIdentity as a, type SigningStandard as b, type FundingRoute as c, type FundingAdapter as d, type FundingSwapAdapter as e, type SessionStore as f, type QuoteResponse as g, type QuoteRequest as h, type Login as i, type ExecutionSnapshot as j, type ExecuteOptions as k, type AppFeeEstimate as l, type ExecutionStage as m, type FundingReceipt as n, type FundingRouteKind as o, type FundingSwapQuote as p, type HttpApiConfig as q, type PrivateOrder as r, type PrivateWithdrawRequest as s, type PrivateWithdrawRow as t, type QuoteParams as u, type Session as v, type SignatureProgress as w, type SignedData as x, type StatusResponse as y, type SwapFundingRequest as z };
package/dist/index.cjs CHANGED
@@ -310,6 +310,10 @@ function buildFundingRouteCandidates(source, destination, preferred, registry, o
310
310
  for (const mid of midCandidates()) add(routeKindFor(mid), mid);
311
311
  return routes;
312
312
  }
313
+ if (sourceChain === "sui" || sourceChain === "tron") {
314
+ add(routeKindFor(destination), destination);
315
+ return routes;
316
+ }
313
317
  for (const mid of midCandidates()) add(routeKindFor(mid), mid);
314
318
  if (routes.length === 0) return [preferred];
315
319
  return routes;