@gibs/bridge-sdk 1.13.0 → 1.17.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.
- package/README.md +244 -18
- package/abis/package.json +6 -0
- package/bridge-limits/package.json +6 -0
- package/chain-info/package.json +6 -0
- package/chain-names/package.json +6 -0
- package/chains/package.json +6 -0
- package/claims/package.json +6 -0
- package/config/package.json +6 -0
- package/consolidated-quote/package.json +6 -0
- package/destination-calldata/package.json +6 -0
- package/dist/chain-info.d.ts +1 -1
- package/dist/chain-info.js +11 -12
- package/dist/chains.d.ts +25 -0
- package/dist/chains.js +55 -20
- package/dist/cjs/abis.d.ts +1 -0
- package/dist/cjs/abis.js +19 -0
- package/dist/cjs/bridge-limits.d.ts +103 -0
- package/dist/cjs/bridge-limits.js +89 -0
- package/dist/cjs/chain-info.d.ts +169 -0
- package/dist/cjs/chain-info.js +452 -0
- package/dist/cjs/chain-names.d.ts +160 -0
- package/dist/cjs/chain-names.js +207 -0
- package/dist/cjs/chains.d.ts +90 -0
- package/dist/cjs/chains.js +357 -0
- package/dist/cjs/claims.d.ts +198 -0
- package/dist/cjs/claims.js +182 -0
- package/dist/cjs/config.d.ts +240 -0
- package/dist/cjs/config.js +537 -0
- package/dist/cjs/consolidated-quote.d.ts +648 -0
- package/dist/cjs/consolidated-quote.js +1048 -0
- package/dist/cjs/destination-calldata.d.ts +118 -0
- package/dist/cjs/destination-calldata.js +156 -0
- package/dist/cjs/ecosystems.d.ts +217 -0
- package/dist/cjs/ecosystems.js +298 -0
- package/dist/cjs/execution.d.ts +346 -0
- package/dist/cjs/execution.js +468 -0
- package/dist/cjs/fee-type.d.ts +10 -0
- package/dist/cjs/fee-type.js +10 -0
- package/dist/cjs/hyperliquid-execution.d.ts +152 -0
- package/dist/cjs/hyperliquid-execution.js +175 -0
- package/dist/cjs/image-links.d.ts +117 -0
- package/dist/cjs/image-links.js +153 -0
- package/dist/cjs/index.d.ts +23 -0
- package/dist/cjs/index.js +39 -0
- package/dist/cjs/lifi-execution-guard.d.ts +210 -0
- package/dist/cjs/lifi-execution-guard.js +409 -0
- package/dist/cjs/near-intents-conformance.d.ts +85 -0
- package/dist/cjs/near-intents-conformance.js +337 -0
- package/dist/cjs/near-intents-route.d.ts +47 -0
- package/dist/cjs/near-intents-route.js +303 -0
- package/dist/cjs/near-intents.d.ts +524 -0
- package/dist/cjs/near-intents.js +1071 -0
- package/dist/cjs/origin-deposit.d.ts +326 -0
- package/dist/cjs/origin-deposit.js +82 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/pre-quote.d.ts +198 -0
- package/dist/cjs/pre-quote.js +180 -0
- package/dist/cjs/prices.d.ts +107 -0
- package/dist/cjs/prices.js +172 -0
- package/dist/cjs/providers.d.ts +238 -0
- package/dist/cjs/providers.js +171 -0
- package/dist/cjs/quote-fees.d.ts +102 -0
- package/dist/cjs/quote-fees.js +201 -0
- package/dist/cjs/referral.d.ts +85 -0
- package/dist/cjs/referral.js +85 -0
- package/dist/cjs/relay-currencies.d.ts +47 -0
- package/dist/cjs/relay-currencies.js +95 -0
- package/dist/cjs/relay-depository.d.ts +2 -0
- package/dist/cjs/relay-depository.js +85 -0
- package/dist/cjs/relay-quote.d.ts +301 -0
- package/dist/cjs/relay-quote.js +996 -0
- package/dist/cjs/route-steps.d.ts +138 -0
- package/dist/cjs/route-steps.js +310 -0
- package/dist/cjs/routing/amounts.d.ts +80 -0
- package/dist/cjs/routing/amounts.js +126 -0
- package/dist/cjs/routing/candidate-route.d.ts +43 -0
- package/dist/cjs/routing/candidate-route.js +50 -0
- package/dist/cjs/routing/candidate.d.ts +237 -0
- package/dist/cjs/routing/candidate.js +100 -0
- package/dist/cjs/routing/carriers/ask-answer.d.ts +77 -0
- package/dist/cjs/routing/carriers/ask-answer.js +2 -0
- package/dist/cjs/routing/carriers/omnibridge.d.ts +137 -0
- package/dist/cjs/routing/carriers/omnibridge.js +459 -0
- package/dist/cjs/routing/carriers/pulsex-paths.d.ts +80 -0
- package/dist/cjs/routing/carriers/pulsex-paths.js +97 -0
- package/dist/cjs/routing/carriers/pulsex-split.d.ts +175 -0
- package/dist/cjs/routing/carriers/pulsex-split.js +193 -0
- package/dist/cjs/routing/carriers/pulsex.d.ts +159 -0
- package/dist/cjs/routing/carriers/pulsex.js +565 -0
- package/dist/cjs/routing/carriers/wrap.d.ts +25 -0
- package/dist/cjs/routing/carriers/wrap.js +119 -0
- package/dist/cjs/routing/composed-route-quality.d.ts +125 -0
- package/dist/cjs/routing/composed-route-quality.js +144 -0
- package/dist/cjs/routing/entry-chain-anchor.d.ts +88 -0
- package/dist/cjs/routing/entry-chain-anchor.js +59 -0
- package/dist/cjs/routing/format.d.ts +31 -0
- package/dist/cjs/routing/format.js +64 -0
- package/dist/cjs/routing/index.d.ts +38 -0
- package/dist/cjs/routing/index.js +134 -0
- package/dist/cjs/routing/producers.d.ts +770 -0
- package/dist/cjs/routing/producers.js +1617 -0
- package/dist/cjs/routing/providers.d.ts +31 -0
- package/dist/cjs/routing/providers.js +48 -0
- package/dist/cjs/routing/route-data.d.ts +355 -0
- package/dist/cjs/routing/route-data.js +2 -0
- package/dist/cjs/routing/search/compose.d.ts +168 -0
- package/dist/cjs/routing/search/compose.js +104 -0
- package/dist/cjs/routing/search/graph.d.ts +668 -0
- package/dist/cjs/routing/search/graph.js +461 -0
- package/dist/cjs/routing/search/plan-route-data.d.ts +269 -0
- package/dist/cjs/routing/search/plan-route-data.js +848 -0
- package/dist/cjs/routing/search/score.d.ts +356 -0
- package/dist/cjs/routing/search/score.js +445 -0
- package/dist/cjs/routing/swap-transactions.d.ts +91 -0
- package/dist/cjs/routing/swap-transactions.js +131 -0
- package/dist/cjs/routing/usd-value.d.ts +17 -0
- package/dist/cjs/routing/usd-value.js +29 -0
- package/dist/cjs/settings.d.ts +785 -0
- package/dist/cjs/settings.js +1074 -0
- package/dist/cjs/ton-connect.d.ts +98 -0
- package/dist/cjs/ton-connect.js +206 -0
- package/dist/cjs/ton-execution.d.ts +7 -0
- package/dist/cjs/ton-execution.js +23 -0
- package/dist/cjs/ton.d.ts +37 -0
- package/dist/cjs/ton.js +83 -0
- package/dist/cjs/tron-execution.d.ts +146 -0
- package/dist/cjs/tron-execution.js +248 -0
- package/dist/cjs/types.d.ts +51 -0
- package/dist/cjs/types.js +2 -0
- package/dist/claims.d.ts +198 -0
- package/dist/claims.js +140 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.js +39 -5
- package/dist/consolidated-quote.d.ts +109 -15
- package/dist/consolidated-quote.js +310 -52
- package/dist/execution.d.ts +346 -0
- package/dist/execution.js +428 -0
- package/dist/hyperliquid-execution.js +2 -3
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/lifi-execution-guard.d.ts +13 -2
- package/dist/lifi-execution-guard.js +4 -0
- package/dist/near-intents.js +2 -3
- package/dist/pre-quote.d.ts +6 -6
- package/dist/pre-quote.js +10 -14
- package/dist/providers.d.ts +17 -0
- package/dist/providers.js +6 -0
- package/dist/referral.d.ts +12 -4
- package/dist/referral.js +12 -4
- package/dist/relay-depository.d.ts +2 -0
- package/dist/relay-depository.js +82 -0
- package/dist/relay-quote.js +2 -3
- package/dist/routing/candidate.d.ts +3 -3
- package/dist/routing/candidate.js +3 -3
- package/dist/routing/carriers/ask-answer.d.ts +19 -0
- package/dist/routing/carriers/omnibridge.js +23 -21
- package/dist/routing/carriers/pulsex-paths.d.ts +80 -0
- package/dist/routing/carriers/pulsex-paths.js +92 -0
- package/dist/routing/carriers/pulsex-split.d.ts +175 -0
- package/dist/routing/carriers/pulsex-split.js +185 -0
- package/dist/routing/carriers/pulsex.d.ts +69 -21
- package/dist/routing/carriers/pulsex.js +184 -65
- package/dist/routing/composed-route-quality.d.ts +28 -6
- package/dist/routing/composed-route-quality.js +36 -5
- package/dist/routing/entry-chain-anchor.d.ts +1 -1
- package/dist/routing/entry-chain-anchor.js +1 -1
- package/dist/routing/index.d.ts +7 -3
- package/dist/routing/index.js +7 -3
- package/dist/routing/producers.js +1 -1
- package/dist/routing/providers.d.ts +5 -0
- package/dist/routing/providers.js +5 -0
- package/dist/routing/search/graph.d.ts +29 -0
- package/dist/routing/search/plan-route-data.d.ts +25 -0
- package/dist/routing/search/plan-route-data.js +43 -7
- package/dist/routing/search/score.d.ts +33 -1
- package/dist/routing/search/score.js +41 -6
- package/dist/routing/swap-transactions.d.ts +91 -0
- package/dist/routing/swap-transactions.js +125 -0
- package/dist/settings.d.ts +94 -1
- package/dist/settings.js +95 -3
- package/dist/ton-connect.d.ts +98 -0
- package/dist/ton-connect.js +200 -0
- package/dist/ton-execution.d.ts +4 -114
- package/dist/ton-execution.js +4 -244
- package/dist/ton.d.ts +37 -0
- package/dist/ton.js +65 -0
- package/docs/examples/example-a-ether-to-pulse.ts +300 -0
- package/docs/examples/example-b-token-pulsechain-to-ethereum.ts +270 -0
- package/docs/examples/shared.ts +261 -0
- package/docs/examples/tsconfig.json +18 -0
- package/docs/integration-guide.md +617 -0
- package/ecosystems/package.json +6 -0
- package/execution/package.json +6 -0
- package/fee-type/package.json +6 -0
- package/hyperliquid-execution/package.json +6 -0
- package/image-links/package.json +6 -0
- package/lifi-execution-guard/package.json +6 -0
- package/llms.txt +234 -0
- package/near-intents/package.json +6 -0
- package/near-intents-route/package.json +6 -0
- package/origin-deposit/package.json +6 -0
- package/package.json +818 -10
- package/pre-quote/package.json +6 -0
- package/prices/package.json +6 -0
- package/providers/package.json +6 -0
- package/quote-fees/package.json +6 -0
- package/referral/package.json +6 -0
- package/relay-currencies/package.json +6 -0
- package/relay-quote/package.json +6 -0
- package/route-steps/package.json +6 -0
- package/routing/package.json +6 -0
- package/settings/package.json +6 -0
- package/ton/package.json +6 -0
- package/ton-connect/package.json +6 -0
- package/ton-execution/package.json +6 -0
- package/tron-execution/package.json +6 -0
- package/types/package.json +6 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { type Hex } from 'viem';
|
|
2
|
+
import { type SignedLeg } from '../settings.js';
|
|
3
|
+
import type { HopEdge, PlannedHop } from './search/graph.js';
|
|
4
|
+
/**
|
|
5
|
+
* The same-chain, one-signature transaction shape every sender in this file
|
|
6
|
+
* builds: a target contract, a native-coin value, and encoded calldata.
|
|
7
|
+
*/
|
|
8
|
+
export type SwapCallInputs = {
|
|
9
|
+
readonly to: Hex;
|
|
10
|
+
readonly value: bigint;
|
|
11
|
+
readonly data: Hex;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Builds a same-chain PulseX swap transaction for one planned route-search
|
|
15
|
+
* hop. The interface's section signing (`packages/ui` `state/sectionSigning.ts`)
|
|
16
|
+
* and the SDK's execution planner (`execution.ts`) both call it, so there is
|
|
17
|
+
* exactly one place that turns "swap this hop" into calldata.
|
|
18
|
+
*
|
|
19
|
+
* SIGNS THE PATH THE HOP WAS PRICED ON. The PulseX carrier picks the best of
|
|
20
|
+
* many paths through its hub tokens and records the winner on the hop's
|
|
21
|
+
* outcome; `pulseXSwapPathForHop` (`carriers/pulsex.ts`) reads it back
|
|
22
|
+
* and checks it fits the hop's edge. This never rebuilds a path: a rebuilt
|
|
23
|
+
* path is a quote on one route and a signature on another. A hop that
|
|
24
|
+
* records no path is refused. REUSES `pulseXSwapTransactionInputs` (`settings.ts`)
|
|
25
|
+
* for the encoding, never re-implements it: that function already carries the
|
|
26
|
+
* `swapRefusal` guard (refuses to build a call for a leg the screen is not
|
|
27
|
+
* looking at) and the native-in/native-out/token-token branching.
|
|
28
|
+
*
|
|
29
|
+
* SIGNS ON THE EDGE'S OWN ROUTER. A PulseX edge names the deployment it was
|
|
30
|
+
* quoted on (`pulseXRouterForEdge`: V1 or V2, each with its own pools). The
|
|
31
|
+
* caller's `routerAddress` must be that same router — it is also the router
|
|
32
|
+
* the caller approved to spend the input token — or nothing is built. A V2
|
|
33
|
+
* quote signed on V1 would trade against a different pool than the one the
|
|
34
|
+
* reader was shown.
|
|
35
|
+
*
|
|
36
|
+
* @param options - the hop to swap, the amount and slippage-adjusted
|
|
37
|
+
* minimum, who receives the output, the signing deadline, what the caller
|
|
38
|
+
* believes this signature does (`signedLeg`), the chain it executes on, and
|
|
39
|
+
* the resolved router address
|
|
40
|
+
* @returns the swap transaction inputs, or null when the hop records no
|
|
41
|
+
* PulseX swap path, names no known router, `routerAddress` is not the
|
|
42
|
+
* edge's own router, the leg on screen disagrees, or any of
|
|
43
|
+
* `pulseXSwapTransactionInputs`'s own preconditions are unmet
|
|
44
|
+
*/
|
|
45
|
+
export declare const buildPulseXSwapTransaction: (options: {
|
|
46
|
+
readonly hop: Pick<PlannedHop, "edge" | "outcome">;
|
|
47
|
+
readonly amountIn: bigint;
|
|
48
|
+
readonly minAmountOut: bigint;
|
|
49
|
+
readonly recipient: Hex | null;
|
|
50
|
+
readonly deadline: bigint;
|
|
51
|
+
readonly signedLeg: SignedLeg | null;
|
|
52
|
+
readonly chainId: number | null;
|
|
53
|
+
readonly routerAddress: Hex | null;
|
|
54
|
+
}) => SwapCallInputs | null;
|
|
55
|
+
/**
|
|
56
|
+
* Builds a native-coin wrap/unwrap transaction for one route-search graph
|
|
57
|
+
* edge — PLS<->WPLS on PulseChain, ETH<->WETH on Ethereum, or the same pair
|
|
58
|
+
* on any other chain `config.ts`'s `nativeAssetOut` names one for.
|
|
59
|
+
*
|
|
60
|
+
* A WRAP IS NOT A SWAP CALL. There is no PulseX pool for native-versus-wrapped
|
|
61
|
+
* — see `routing/carriers/wrap.ts`'s own doc — so this never touches the
|
|
62
|
+
* PulseX router: wrapping sends `amountIn` native coin to the wrapped token's
|
|
63
|
+
* own `deposit()`; unwrapping calls `withdraw(amountIn)` on it with zero
|
|
64
|
+
* value. The `edge` names which direction: its `from`/`to` addresses are
|
|
65
|
+
* checked against the zero-address sentinel, never assumed from a caller
|
|
66
|
+
* flag, so a swapped/malformed edge is refused rather than guessed at.
|
|
67
|
+
*
|
|
68
|
+
* @param options - the edge to wrap or unwrap, and the amount in the SOURCE
|
|
69
|
+
* token's base units (native units wrapping, wrapped units unwrapping —
|
|
70
|
+
* native and wrapped share decimals on every chain this carrier covers)
|
|
71
|
+
* @returns the wrap/unwrap transaction inputs, or null when `amountIn` is not
|
|
72
|
+
* positive or the edge is not exactly one native/wrapped pair
|
|
73
|
+
*/
|
|
74
|
+
export declare const buildWrapTransaction: (options: {
|
|
75
|
+
readonly edge: HopEdge;
|
|
76
|
+
readonly amountIn: bigint;
|
|
77
|
+
}) => SwapCallInputs | null;
|
|
78
|
+
/**
|
|
79
|
+
* The slippage floor a swap signs: the quoted output less the slippage
|
|
80
|
+
* allowance, rounded down. The interface's engine signing and the SDK's
|
|
81
|
+
* execution planner both read it, so the two never sign different floors for
|
|
82
|
+
* the same quote.
|
|
83
|
+
*
|
|
84
|
+
* @param options.quotedAmount - the hop's quoted output, in the output token's base units
|
|
85
|
+
* @param options.slippageBasisPoints - the allowance, in basis points (100 is 1%)
|
|
86
|
+
* @returns the minimum output the swap accepts
|
|
87
|
+
*/
|
|
88
|
+
export declare const swapMinimumOut: ({ quotedAmount, slippageBasisPoints, }: {
|
|
89
|
+
readonly quotedAmount: bigint;
|
|
90
|
+
readonly slippageBasisPoints: bigint;
|
|
91
|
+
}) => bigint;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { encodeFunctionData, isAddressEqual, parseAbi, zeroAddress } from 'viem';
|
|
2
|
+
import { pulseXSwapTransactionInputs } from '../settings.js';
|
|
3
|
+
import { pulseXRouterForEdge, pulseXSwapPathForHop } from './carriers/pulsex.js';
|
|
4
|
+
/**
|
|
5
|
+
* The minimal WETH9-style wrap/unwrap interface: `deposit()` mints the
|
|
6
|
+
* wrapped token for the native coin sent with the call, `withdraw(uint256)`
|
|
7
|
+
* burns wrapped balance and returns native coin. Every wrapped-native
|
|
8
|
+
* contract this application bridges to exposes exactly this pair — see
|
|
9
|
+
* `carriers/wrap.ts`, whose own doc records the selectors as confirmed
|
|
10
|
+
* present on WPLS by bytecode inspection (2026-09-24). Kept local rather than
|
|
11
|
+
* added to `@gibs/abis`: the interface is two standard, unchanging selectors
|
|
12
|
+
* rather than a contract-specific ABI.
|
|
13
|
+
*/
|
|
14
|
+
const wrapAbi = parseAbi(['function deposit() payable', 'function withdraw(uint256 amount)']);
|
|
15
|
+
/**
|
|
16
|
+
* Builds a same-chain PulseX swap transaction for one planned route-search
|
|
17
|
+
* hop. The interface's section signing (`packages/ui` `state/sectionSigning.ts`)
|
|
18
|
+
* and the SDK's execution planner (`execution.ts`) both call it, so there is
|
|
19
|
+
* exactly one place that turns "swap this hop" into calldata.
|
|
20
|
+
*
|
|
21
|
+
* SIGNS THE PATH THE HOP WAS PRICED ON. The PulseX carrier picks the best of
|
|
22
|
+
* many paths through its hub tokens and records the winner on the hop's
|
|
23
|
+
* outcome; `pulseXSwapPathForHop` (`carriers/pulsex.ts`) reads it back
|
|
24
|
+
* and checks it fits the hop's edge. This never rebuilds a path: a rebuilt
|
|
25
|
+
* path is a quote on one route and a signature on another. A hop that
|
|
26
|
+
* records no path is refused. REUSES `pulseXSwapTransactionInputs` (`settings.ts`)
|
|
27
|
+
* for the encoding, never re-implements it: that function already carries the
|
|
28
|
+
* `swapRefusal` guard (refuses to build a call for a leg the screen is not
|
|
29
|
+
* looking at) and the native-in/native-out/token-token branching.
|
|
30
|
+
*
|
|
31
|
+
* SIGNS ON THE EDGE'S OWN ROUTER. A PulseX edge names the deployment it was
|
|
32
|
+
* quoted on (`pulseXRouterForEdge`: V1 or V2, each with its own pools). The
|
|
33
|
+
* caller's `routerAddress` must be that same router — it is also the router
|
|
34
|
+
* the caller approved to spend the input token — or nothing is built. A V2
|
|
35
|
+
* quote signed on V1 would trade against a different pool than the one the
|
|
36
|
+
* reader was shown.
|
|
37
|
+
*
|
|
38
|
+
* @param options - the hop to swap, the amount and slippage-adjusted
|
|
39
|
+
* minimum, who receives the output, the signing deadline, what the caller
|
|
40
|
+
* believes this signature does (`signedLeg`), the chain it executes on, and
|
|
41
|
+
* the resolved router address
|
|
42
|
+
* @returns the swap transaction inputs, or null when the hop records no
|
|
43
|
+
* PulseX swap path, names no known router, `routerAddress` is not the
|
|
44
|
+
* edge's own router, the leg on screen disagrees, or any of
|
|
45
|
+
* `pulseXSwapTransactionInputs`'s own preconditions are unmet
|
|
46
|
+
*/
|
|
47
|
+
export const buildPulseXSwapTransaction = (options) => {
|
|
48
|
+
const { hop, amountIn, minAmountOut, recipient, deadline, signedLeg, chainId, routerAddress } = options;
|
|
49
|
+
const { edge } = hop;
|
|
50
|
+
const swapPath = pulseXSwapPathForHop(hop);
|
|
51
|
+
if (swapPath === null) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
const quotedRouter = pulseXRouterForEdge(edge);
|
|
55
|
+
if (quotedRouter === null || routerAddress === null || !isAddressEqual(quotedRouter, routerAddress)) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
return pulseXSwapTransactionInputs({
|
|
59
|
+
signedLeg,
|
|
60
|
+
chainId,
|
|
61
|
+
routerAddress,
|
|
62
|
+
fromTokenAddress: edge.from.address,
|
|
63
|
+
toTokenAddress: edge.to.address,
|
|
64
|
+
swapPath,
|
|
65
|
+
amountIn,
|
|
66
|
+
minAmountOut,
|
|
67
|
+
recipient,
|
|
68
|
+
deadline,
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Builds a native-coin wrap/unwrap transaction for one route-search graph
|
|
73
|
+
* edge — PLS<->WPLS on PulseChain, ETH<->WETH on Ethereum, or the same pair
|
|
74
|
+
* on any other chain `config.ts`'s `nativeAssetOut` names one for.
|
|
75
|
+
*
|
|
76
|
+
* A WRAP IS NOT A SWAP CALL. There is no PulseX pool for native-versus-wrapped
|
|
77
|
+
* — see `routing/carriers/wrap.ts`'s own doc — so this never touches the
|
|
78
|
+
* PulseX router: wrapping sends `amountIn` native coin to the wrapped token's
|
|
79
|
+
* own `deposit()`; unwrapping calls `withdraw(amountIn)` on it with zero
|
|
80
|
+
* value. The `edge` names which direction: its `from`/`to` addresses are
|
|
81
|
+
* checked against the zero-address sentinel, never assumed from a caller
|
|
82
|
+
* flag, so a swapped/malformed edge is refused rather than guessed at.
|
|
83
|
+
*
|
|
84
|
+
* @param options - the edge to wrap or unwrap, and the amount in the SOURCE
|
|
85
|
+
* token's base units (native units wrapping, wrapped units unwrapping —
|
|
86
|
+
* native and wrapped share decimals on every chain this carrier covers)
|
|
87
|
+
* @returns the wrap/unwrap transaction inputs, or null when `amountIn` is not
|
|
88
|
+
* positive or the edge is not exactly one native/wrapped pair
|
|
89
|
+
*/
|
|
90
|
+
export const buildWrapTransaction = (options) => {
|
|
91
|
+
const { edge, amountIn } = options;
|
|
92
|
+
if (amountIn <= 0n) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
const fromIsNative = edge.from.address.toLowerCase() === zeroAddress;
|
|
96
|
+
const toIsNative = edge.to.address.toLowerCase() === zeroAddress;
|
|
97
|
+
// Exactly one side must be the native sentinel — a token/token pair, or a
|
|
98
|
+
// native/native no-op, is not a wrap edge at all.
|
|
99
|
+
if (fromIsNative === toIsNative) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
if (fromIsNative) {
|
|
103
|
+
return {
|
|
104
|
+
to: edge.to.address,
|
|
105
|
+
value: amountIn,
|
|
106
|
+
data: encodeFunctionData({ abi: wrapAbi, functionName: 'deposit', args: [] }),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
to: edge.from.address,
|
|
111
|
+
value: 0n,
|
|
112
|
+
data: encodeFunctionData({ abi: wrapAbi, functionName: 'withdraw', args: [amountIn] }),
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* The slippage floor a swap signs: the quoted output less the slippage
|
|
117
|
+
* allowance, rounded down. The interface's engine signing and the SDK's
|
|
118
|
+
* execution planner both read it, so the two never sign different floors for
|
|
119
|
+
* the same quote.
|
|
120
|
+
*
|
|
121
|
+
* @param options.quotedAmount - the hop's quoted output, in the output token's base units
|
|
122
|
+
* @param options.slippageBasisPoints - the allowance, in basis points (100 is 1%)
|
|
123
|
+
* @returns the minimum output the swap accepts
|
|
124
|
+
*/
|
|
125
|
+
export const swapMinimumOut = ({ quotedAmount, slippageBasisPoints, }) => (quotedAmount * (10000n - slippageBasisPoints)) / 10000n;
|
package/dist/settings.d.ts
CHANGED
|
@@ -212,6 +212,98 @@ export declare const deliveryFee: ({ shouldDeliver, routeOffersDelivery, feeType
|
|
|
212
212
|
fixedFee: bigint | null;
|
|
213
213
|
limit: bigint | null;
|
|
214
214
|
}) => DeliveryFee;
|
|
215
|
+
/**
|
|
216
|
+
* The four-bit fee-type settings word a fee director carries.
|
|
217
|
+
*
|
|
218
|
+
* - bit 0: fixed fee mode.
|
|
219
|
+
* - bit 1: unwrap the delivered token to the native coin.
|
|
220
|
+
* - bit 2: exclude the priority fee from the delivery cost. Always set.
|
|
221
|
+
* - bit 3: percent fee mode.
|
|
222
|
+
*
|
|
223
|
+
* @param options.feeType - the delivery fee mode
|
|
224
|
+
* @param options.unwrap - whether the delivery unwraps to the native coin
|
|
225
|
+
* @returns the settings word for {@link feeDirectorStructEncoded}
|
|
226
|
+
*/
|
|
227
|
+
export declare const feeTypeSettings: ({ feeType, unwrap }: {
|
|
228
|
+
feeType: FeeType;
|
|
229
|
+
unwrap: boolean;
|
|
230
|
+
}) => bigint;
|
|
231
|
+
/**
|
|
232
|
+
* An ERC-20 allowance a transaction needs before it can run: `spender` must
|
|
233
|
+
* be allowed to pull at least `minimum` of `token` from the sender on
|
|
234
|
+
* `chainId`.
|
|
235
|
+
*/
|
|
236
|
+
export type ApprovalRequirement = {
|
|
237
|
+
chainId: number;
|
|
238
|
+
token: Hex;
|
|
239
|
+
spender: Hex;
|
|
240
|
+
minimum: bigint;
|
|
241
|
+
};
|
|
242
|
+
/**
|
|
243
|
+
* The ERC-20 `approve` call, as a target, a value and calldata. The
|
|
244
|
+
* interface's approval broadcast and the SDK's execution planner both build it
|
|
245
|
+
* here.
|
|
246
|
+
*
|
|
247
|
+
* @param options.token - the token to approve
|
|
248
|
+
* @param options.spender - the address allowed to pull it
|
|
249
|
+
* @param options.amount - the allowance to set
|
|
250
|
+
* @returns the call
|
|
251
|
+
*/
|
|
252
|
+
export declare const approveCall: ({ token, spender, amount, }: {
|
|
253
|
+
token: Hex;
|
|
254
|
+
spender: Hex;
|
|
255
|
+
amount: bigint;
|
|
256
|
+
}) => {
|
|
257
|
+
to: Hex;
|
|
258
|
+
value: bigint;
|
|
259
|
+
data: Hex;
|
|
260
|
+
};
|
|
261
|
+
/**
|
|
262
|
+
* The `approve` amounts to send, in order, so the spender may pull exactly
|
|
263
|
+
* `minimum`. Empty when the allowance on chain already covers it.
|
|
264
|
+
*
|
|
265
|
+
* EXACT, NEVER UNLIMITED. An unlimited approval lets the spender pull the
|
|
266
|
+
* reader's whole balance for as long as the approval stands, so a later fault
|
|
267
|
+
* in that contract, or a spender a compromised quote named, costs everything
|
|
268
|
+
* rather than one transfer. The owner chose exact approvals everywhere
|
|
269
|
+
* (2026-10-07); the interface and the SDK's execution planner both decide
|
|
270
|
+
* here.
|
|
271
|
+
*
|
|
272
|
+
* A SHORT, NON-ZERO ALLOWANCE IS RESET TO ZERO FIRST. Some tokens (Tether on
|
|
273
|
+
* Ethereum is the known one) revert an `approve` that changes one non-zero
|
|
274
|
+
* allowance into another. Exact approvals leave such remainders more often,
|
|
275
|
+
* because an aggregator may spend less than it was allowed. A reset first
|
|
276
|
+
* works for every token, at the cost of one extra transaction in that case.
|
|
277
|
+
*
|
|
278
|
+
* @param options.allowance - the allowance on chain now
|
|
279
|
+
* @param options.minimum - the amount the next transaction pulls
|
|
280
|
+
* @returns the amounts to approve, in order: none, `[minimum]`, or `[0n, minimum]`
|
|
281
|
+
*/
|
|
282
|
+
export declare const approvalAmounts: ({ allowance, minimum, }: {
|
|
283
|
+
allowance: bigint;
|
|
284
|
+
minimum: bigint;
|
|
285
|
+
}) => readonly bigint[];
|
|
286
|
+
/**
|
|
287
|
+
* The allowance a direct omnibridge crossing needs, or null when it needs none.
|
|
288
|
+
*
|
|
289
|
+
* Reads the SAME predicate {@link transactionInputs} uses to pick the call: a
|
|
290
|
+
* token the bridge minted ({@link interactingWithBridgeToken}) is burned by
|
|
291
|
+
* `transferAndCall` and needs no allowance, and the native coin is sent as
|
|
292
|
+
* value. Every other token is pulled by the pathway's `from` mediator through
|
|
293
|
+
* `relayTokens` or `relayTokensAndCall`.
|
|
294
|
+
*
|
|
295
|
+
* @param options.bridgePathway - the crossing's pathway
|
|
296
|
+
* @param options.assetIn - the token the crossing spends
|
|
297
|
+
* @param options.assetLink - the token's bridge link
|
|
298
|
+
* @param options.amountToBridge - the amount the crossing pulls
|
|
299
|
+
* @returns the approval the crossing needs, or null
|
|
300
|
+
*/
|
|
301
|
+
export declare const omnibridgeApproval: ({ bridgePathway, assetIn, assetLink, amountToBridge, }: {
|
|
302
|
+
bridgePathway: Pathway;
|
|
303
|
+
assetIn: Token;
|
|
304
|
+
assetLink: TokenBridgeInfo;
|
|
305
|
+
amountToBridge: bigint;
|
|
306
|
+
}) => ApprovalRequirement | null;
|
|
215
307
|
/**
|
|
216
308
|
* Calculates the reasonable fixed fee from the estimated token network cost and desired excess compensation basis points
|
|
217
309
|
* @param estimatedTokenNetworkCost - the estimated token network cost
|
|
@@ -605,7 +697,8 @@ export declare const assertCandidatePickAgrees: ({ pick, leg, sectionIndex, }: {
|
|
|
605
697
|
* the chain's native coin
|
|
606
698
|
* @param toTokenAddress - the output token address, or the zero address for
|
|
607
699
|
* the chain's native coin
|
|
608
|
-
* @param swapPath - the ordered swap path
|
|
700
|
+
* @param swapPath - the ordered swap path — for a route-search hop, the one
|
|
701
|
+
* its quote was priced along (`pulseXSwapPathForHop`),
|
|
609
702
|
* already expressed in the router's own token addresses — the wrapped-native
|
|
610
703
|
* token stands in for either native end
|
|
611
704
|
* @param amountIn - the amount to swap, in the input token's base units
|
package/dist/settings.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { concatHex, encodeAbiParameters, encodeFunctionData, getAddress, isAddress, isAddressEqual, zeroAddress, } from 'viem';
|
|
1
|
+
import { concatHex, encodeAbiParameters, encodeFunctionData, erc20Abi, getAddress, isAddress, isAddressEqual, zeroAddress, } from 'viem';
|
|
2
2
|
import * as abis from './abis.js';
|
|
3
3
|
import { isNative, nativeAssetOut, pathway } from './config.js';
|
|
4
4
|
import { FeeType } from './fee-type.js';
|
|
@@ -230,6 +230,95 @@ export const deliveryFee = ({ shouldDeliver, routeOffersDelivery, feeType, amoun
|
|
|
230
230
|
rate: percentFee,
|
|
231
231
|
};
|
|
232
232
|
};
|
|
233
|
+
/**
|
|
234
|
+
* The four-bit fee-type settings word a fee director carries.
|
|
235
|
+
*
|
|
236
|
+
* - bit 0: fixed fee mode.
|
|
237
|
+
* - bit 1: unwrap the delivered token to the native coin.
|
|
238
|
+
* - bit 2: exclude the priority fee from the delivery cost. Always set.
|
|
239
|
+
* - bit 3: percent fee mode.
|
|
240
|
+
*
|
|
241
|
+
* @param options.feeType - the delivery fee mode
|
|
242
|
+
* @param options.unwrap - whether the delivery unwraps to the native coin
|
|
243
|
+
* @returns the settings word for {@link feeDirectorStructEncoded}
|
|
244
|
+
*/
|
|
245
|
+
export const feeTypeSettings = ({ feeType, unwrap }) => {
|
|
246
|
+
const fixedBit = feeType === FeeType.FIXED ? 1n : 0n;
|
|
247
|
+
const unwrapBit = unwrap ? 1n : 0n;
|
|
248
|
+
const excludePriorityBit = 1n;
|
|
249
|
+
const percentBit = feeType === FeeType.PERCENT ? 1n : 0n;
|
|
250
|
+
return (percentBit << 3n) | (excludePriorityBit << 2n) | (unwrapBit << 1n) | fixedBit;
|
|
251
|
+
};
|
|
252
|
+
/**
|
|
253
|
+
* The ERC-20 `approve` call, as a target, a value and calldata. The
|
|
254
|
+
* interface's approval broadcast and the SDK's execution planner both build it
|
|
255
|
+
* here.
|
|
256
|
+
*
|
|
257
|
+
* @param options.token - the token to approve
|
|
258
|
+
* @param options.spender - the address allowed to pull it
|
|
259
|
+
* @param options.amount - the allowance to set
|
|
260
|
+
* @returns the call
|
|
261
|
+
*/
|
|
262
|
+
export const approveCall = ({ token, spender, amount, }) => ({
|
|
263
|
+
to: token,
|
|
264
|
+
value: 0n,
|
|
265
|
+
data: encodeFunctionData({ abi: erc20Abi, functionName: 'approve', args: [spender, amount] }),
|
|
266
|
+
});
|
|
267
|
+
/**
|
|
268
|
+
* The `approve` amounts to send, in order, so the spender may pull exactly
|
|
269
|
+
* `minimum`. Empty when the allowance on chain already covers it.
|
|
270
|
+
*
|
|
271
|
+
* EXACT, NEVER UNLIMITED. An unlimited approval lets the spender pull the
|
|
272
|
+
* reader's whole balance for as long as the approval stands, so a later fault
|
|
273
|
+
* in that contract, or a spender a compromised quote named, costs everything
|
|
274
|
+
* rather than one transfer. The owner chose exact approvals everywhere
|
|
275
|
+
* (2026-10-07); the interface and the SDK's execution planner both decide
|
|
276
|
+
* here.
|
|
277
|
+
*
|
|
278
|
+
* A SHORT, NON-ZERO ALLOWANCE IS RESET TO ZERO FIRST. Some tokens (Tether on
|
|
279
|
+
* Ethereum is the known one) revert an `approve` that changes one non-zero
|
|
280
|
+
* allowance into another. Exact approvals leave such remainders more often,
|
|
281
|
+
* because an aggregator may spend less than it was allowed. A reset first
|
|
282
|
+
* works for every token, at the cost of one extra transaction in that case.
|
|
283
|
+
*
|
|
284
|
+
* @param options.allowance - the allowance on chain now
|
|
285
|
+
* @param options.minimum - the amount the next transaction pulls
|
|
286
|
+
* @returns the amounts to approve, in order: none, `[minimum]`, or `[0n, minimum]`
|
|
287
|
+
*/
|
|
288
|
+
export const approvalAmounts = ({ allowance, minimum, }) => {
|
|
289
|
+
if (allowance >= minimum)
|
|
290
|
+
return [];
|
|
291
|
+
if (allowance === 0n)
|
|
292
|
+
return [minimum];
|
|
293
|
+
return [0n, minimum];
|
|
294
|
+
};
|
|
295
|
+
/**
|
|
296
|
+
* The allowance a direct omnibridge crossing needs, or null when it needs none.
|
|
297
|
+
*
|
|
298
|
+
* Reads the SAME predicate {@link transactionInputs} uses to pick the call: a
|
|
299
|
+
* token the bridge minted ({@link interactingWithBridgeToken}) is burned by
|
|
300
|
+
* `transferAndCall` and needs no allowance, and the native coin is sent as
|
|
301
|
+
* value. Every other token is pulled by the pathway's `from` mediator through
|
|
302
|
+
* `relayTokens` or `relayTokensAndCall`.
|
|
303
|
+
*
|
|
304
|
+
* @param options.bridgePathway - the crossing's pathway
|
|
305
|
+
* @param options.assetIn - the token the crossing spends
|
|
306
|
+
* @param options.assetLink - the token's bridge link
|
|
307
|
+
* @param options.amountToBridge - the amount the crossing pulls
|
|
308
|
+
* @returns the approval the crossing needs, or null
|
|
309
|
+
*/
|
|
310
|
+
export const omnibridgeApproval = ({ bridgePathway, assetIn, assetLink, amountToBridge, }) => {
|
|
311
|
+
if (assetIn.address === zeroAddress)
|
|
312
|
+
return null;
|
|
313
|
+
if (interactingWithBridgeToken({ assetLink, assetInAddress: assetIn.address }))
|
|
314
|
+
return null;
|
|
315
|
+
return {
|
|
316
|
+
chainId: assetIn.chainId,
|
|
317
|
+
token: assetIn.address,
|
|
318
|
+
spender: bridgePathway.from,
|
|
319
|
+
minimum: amountToBridge,
|
|
320
|
+
};
|
|
321
|
+
};
|
|
233
322
|
/**
|
|
234
323
|
* Calculates the reasonable fixed fee from the estimated token network cost and desired excess compensation basis points
|
|
235
324
|
* @param estimatedTokenNetworkCost - the estimated token network cost
|
|
@@ -358,7 +447,9 @@ export const destinationDataParam = ({ recipient, bridgePathway, assetIn, destin
|
|
|
358
447
|
if (!destinationRouter) {
|
|
359
448
|
return null;
|
|
360
449
|
}
|
|
361
|
-
|
|
450
|
+
// Only a delivery needs the fee director. A crossing without delivery sends
|
|
451
|
+
// to the recipient, whatever the fee director would have said.
|
|
452
|
+
if (bridgePathway.requiresDelivery && shouldDeliver && !feeDirectorStructEncoded) {
|
|
362
453
|
return null;
|
|
363
454
|
}
|
|
364
455
|
if (!assetLink) {
|
|
@@ -653,7 +744,8 @@ export const assertCandidatePickAgrees = ({ pick, leg, sectionIndex, }) => {
|
|
|
653
744
|
* the chain's native coin
|
|
654
745
|
* @param toTokenAddress - the output token address, or the zero address for
|
|
655
746
|
* the chain's native coin
|
|
656
|
-
* @param swapPath - the ordered swap path
|
|
747
|
+
* @param swapPath - the ordered swap path — for a route-search hop, the one
|
|
748
|
+
* its quote was priced along (`pulseXSwapPathForHop`),
|
|
657
749
|
* already expressed in the router's own token addresses — the wrapped-native
|
|
658
750
|
* token stands in for either native end
|
|
659
751
|
* @param amountIn - the amount to swap, in the input token's base units
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { TonDeposit } from './origin-deposit.js';
|
|
2
|
+
/**
|
|
3
|
+
* Executing a deposit on The Open Network, as pure data, with no TON library.
|
|
4
|
+
*
|
|
5
|
+
* This module imports nothing outside the package, so it loads anywhere: a
|
|
6
|
+
* browser, Node, or a React Native app under Hermes, with no `Buffer` and no
|
|
7
|
+
* polyfill. It uses only `atob` and `btoa`, which Hermes provides. The one TON
|
|
8
|
+
* helper that needs `@ton/core`, the TEP-467 message hash, lives in
|
|
9
|
+
* `@gibs/bridge-sdk/ton` instead.
|
|
10
|
+
*
|
|
11
|
+
* Relay describes a deposit as a list of internal messages carrying `to`,
|
|
12
|
+
* `value`, `body` and a `bounce` flag. A connected wallet, however, is driven
|
|
13
|
+
* through the TON Connect protocol, whose request shape is different in one way
|
|
14
|
+
* that silently loses money:
|
|
15
|
+
*
|
|
16
|
+
* **TON Connect has no per-message `bounce` field.** A wallet derives whether a
|
|
17
|
+
* message bounces from the FORM OF THE ADDRESS — the bounceable `EQ…` prefix or
|
|
18
|
+
* the non-bounceable `UQ…` one. Passing Relay's address through unchanged while
|
|
19
|
+
* dropping its `bounce: false` therefore sends a deposit to the bounceable form,
|
|
20
|
+
* and the depository bounces the funds straight back to the sender. The transfer
|
|
21
|
+
* looks like it succeeded and the route never fills.
|
|
22
|
+
*
|
|
23
|
+
* {@link buildTonConnectRequest} folds `bounce` into the address so the flag
|
|
24
|
+
* cannot be dropped on the way to a wallet.
|
|
25
|
+
*
|
|
26
|
+
* Kept free of transport and of clock reads so it is fully testable: nothing
|
|
27
|
+
* here signs, fetches, or calls `Date.now`. The caller supplies the deadline and
|
|
28
|
+
* performs the request.
|
|
29
|
+
*
|
|
30
|
+
* The rules encoded here are those of Relay's own wallet adapter, which is the
|
|
31
|
+
* only reference implementation of this mapping.
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* The TON Connect network identifier for mainnet. Relay bridges only mainnet, so
|
|
35
|
+
* a request is always tagged with this.
|
|
36
|
+
*/
|
|
37
|
+
export declare const tonConnectMainnetNetwork = "-239";
|
|
38
|
+
/** How long a request stays valid by default, in seconds, matching Relay's adapter. */
|
|
39
|
+
export declare const tonConnectDefaultValidForSeconds = 300;
|
|
40
|
+
/** An address split into the parts that survive a change of encoding. */
|
|
41
|
+
type ParsedTonAddress = {
|
|
42
|
+
workchain: number;
|
|
43
|
+
hash: Uint8Array;
|
|
44
|
+
/** Preserved rather than assumed: re-encoding a testnet address as mainnet would misdirect it. */
|
|
45
|
+
testOnly: boolean;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Parses either address form The Open Network uses.
|
|
49
|
+
*
|
|
50
|
+
* @param value - a friendly (`EQ…`/`UQ…`) or raw (`0:…`) address
|
|
51
|
+
* @returns the address parts, or null when it is neither form or fails its checksum
|
|
52
|
+
*/
|
|
53
|
+
export declare const parseTonAddress: (value: string) => ParsedTonAddress | null;
|
|
54
|
+
/**
|
|
55
|
+
* Re-encodes an address into the friendly form matching a bounce setting.
|
|
56
|
+
*
|
|
57
|
+
* This is the whole point of the module: the bounce flag has nowhere else to
|
|
58
|
+
* live in a TON Connect request, so it has to be carried by the address itself.
|
|
59
|
+
*
|
|
60
|
+
* @param address - the address in either form
|
|
61
|
+
* @param options.bounceable - whether the message may bounce back to the sender
|
|
62
|
+
* @returns the friendly address, or null when the input cannot be parsed
|
|
63
|
+
*/
|
|
64
|
+
export declare const encodeTonAddress: (address: string, { bounceable }: {
|
|
65
|
+
bounceable: boolean;
|
|
66
|
+
}) => string | null;
|
|
67
|
+
/** One message of a TON Connect request. Note `address`/`amount`, not `to`/`value`. */
|
|
68
|
+
export type TonConnectMessage = {
|
|
69
|
+
address: string;
|
|
70
|
+
/** Attached amount in nanotons, as a decimal string. */
|
|
71
|
+
amount: string;
|
|
72
|
+
/** Base64 bag-of-cells body, omitted when the message carries none. */
|
|
73
|
+
payload?: string;
|
|
74
|
+
};
|
|
75
|
+
/** The request handed to a wallet's TON Connect `sendTransaction` call. */
|
|
76
|
+
export type TonConnectRequest = {
|
|
77
|
+
/** Unix seconds after which a wallet must refuse the request. */
|
|
78
|
+
validUntil: number;
|
|
79
|
+
network: string;
|
|
80
|
+
/** The sending account, when the deposit names one. */
|
|
81
|
+
from?: string;
|
|
82
|
+
messages: TonConnectMessage[];
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Builds the TON Connect request for a deposit.
|
|
86
|
+
*
|
|
87
|
+
* @param deposit - the parsed origin deposit
|
|
88
|
+
* @param options.validUntil - unix seconds after which the request expires.
|
|
89
|
+
* Supplied by the caller rather than read from a clock here so the transform
|
|
90
|
+
* stays pure; {@link tonConnectDefaultValidForSeconds} is the usual offset.
|
|
91
|
+
* @returns the request, or null when the deposit carries no messages or any
|
|
92
|
+
* destination address cannot be re-encoded — never a request whose bounce
|
|
93
|
+
* setting has been silently dropped
|
|
94
|
+
*/
|
|
95
|
+
export declare const buildTonConnectRequest: (deposit: TonDeposit, { validUntil }: {
|
|
96
|
+
validUntil: number;
|
|
97
|
+
}) => TonConnectRequest | null;
|
|
98
|
+
export {};
|