@lifi/composer-sdk 0.4.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.
- package/README.md +98 -5
- package/dist/authoring/FlowBuilderCore.cjs +1 -5
- package/dist/authoring/FlowBuilderCore.cjs.map +1 -1
- package/dist/authoring/FlowBuilderCore.d.cts +9 -7
- package/dist/authoring/FlowBuilderCore.d.ts +9 -7
- package/dist/authoring/FlowBuilderCore.js +2 -6
- package/dist/authoring/FlowBuilderCore.js.map +1 -1
- package/dist/authoring/handles.cjs +5 -2
- package/dist/authoring/handles.cjs.map +1 -1
- package/dist/authoring/handles.d.cts +25 -6
- package/dist/authoring/handles.d.ts +25 -6
- package/dist/authoring/handles.js +3 -1
- package/dist/authoring/handles.js.map +1 -1
- package/dist/authoring/raw.cjs +6 -1
- package/dist/authoring/raw.cjs.map +1 -1
- package/dist/authoring/raw.d.cts +33 -3
- package/dist/authoring/raw.d.ts +33 -3
- package/dist/authoring/raw.js +5 -1
- package/dist/authoring/raw.js.map +1 -1
- package/dist/authoring/signatureArgs.cjs.map +1 -1
- package/dist/authoring/signatureArgs.d.cts +16 -12
- package/dist/authoring/signatureArgs.d.ts +16 -12
- package/dist/authoring/signatureArgs.js.map +1 -1
- package/dist/client.cjs +94 -58
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +61 -2
- package/dist/client.d.ts +61 -2
- package/dist/client.js +94 -58
- package/dist/client.js.map +1 -1
- package/dist/discovery.cjs.map +1 -1
- package/dist/discovery.d.cts +31 -2
- package/dist/discovery.d.ts +31 -2
- package/dist/generated/config.generated.cjs.map +1 -1
- package/dist/generated/config.generated.d.cts +35 -3
- package/dist/generated/config.generated.d.ts +35 -3
- package/dist/generated/operations.generated.cjs +9 -0
- package/dist/generated/operations.generated.cjs.map +1 -1
- package/dist/generated/operations.generated.d.cts +33 -2
- package/dist/generated/operations.generated.d.ts +33 -2
- package/dist/generated/operations.generated.js +9 -0
- package/dist/generated/operations.generated.js.map +1 -1
- package/dist/index.cjs +5 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +26 -7
- package/dist/index.d.ts +26 -7
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/{raw-IxCF_bSS.d.ts → raw-BvRghN3r.d.ts} +3 -2
- package/dist/{raw-Dj_2rBSQ.d.cts → raw-s1rer8X3.d.cts} +3 -2
- package/dist/raw.cjs +2 -0
- package/dist/raw.cjs.map +1 -1
- package/dist/raw.d.cts +1 -1
- package/dist/raw.d.ts +1 -1
- package/dist/raw.js +2 -1
- package/dist/raw.js.map +1 -1
- package/dist/routeAmount-DdbJYJyM.d.cts +55 -0
- package/dist/routeAmount-DdbJYJyM.d.ts +55 -0
- package/dist/routeAmount.cjs +38 -0
- package/dist/routeAmount.cjs.map +1 -0
- package/dist/routeAmount.d.cts +2 -0
- package/dist/routeAmount.d.ts +2 -0
- package/dist/routeAmount.js +13 -0
- package/dist/routeAmount.js.map +1 -0
- package/dist/run/inputs.cjs +14 -15
- package/dist/run/inputs.cjs.map +1 -1
- package/dist/run/inputs.d.cts +8 -0
- package/dist/run/inputs.d.ts +8 -0
- package/dist/run/inputs.js +14 -15
- package/dist/run/inputs.js.map +1 -1
- package/dist/run/simulate.cjs +5 -0
- package/dist/run/simulate.cjs.map +1 -1
- package/dist/run/simulate.d.cts +5 -2
- package/dist/run/simulate.d.ts +5 -2
- package/dist/run/simulate.js +5 -0
- package/dist/run/simulate.js.map +1 -1
- package/dist/sdk.cjs +3 -0
- package/dist/sdk.cjs.map +1 -1
- package/dist/sdk.d.cts +42 -2
- package/dist/sdk.d.ts +42 -2
- package/dist/sdk.js +3 -0
- package/dist/sdk.js.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +18 -2
- package/dist/types.d.ts +18 -2
- package/package.json +6 -13
- package/src/authoring/FlowBuilderCore.ts +13 -15
- package/src/authoring/handles.ts +41 -5
- package/src/authoring/raw.ts +39 -4
- package/src/authoring/signatureArgs.ts +17 -13
- package/src/client.ts +204 -58
- package/src/discovery.ts +31 -1
- package/src/examples/flySwap.ts +167 -0
- package/src/examples/lifiZap.ts +4 -0
- package/src/examples/lifiZapAsync.ts +88 -0
- package/src/examples/routeTokenPair.ts +58 -0
- package/src/examples/run.ts +56 -6
- package/src/examples/supportedChains.ts +122 -0
- package/src/generated/config.generated.ts +45 -3
- package/src/generated/operations.generated.ts +56 -8
- package/src/index.ts +33 -1
- package/src/raw.ts +1 -1
- package/src/routeAmount.ts +61 -0
- package/src/run/inputs.ts +30 -11
- package/src/run/simulate.ts +14 -2
- package/src/sdk.ts +47 -0
- package/src/types.ts +20 -1
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
// AUTO-GENERATED from manifest.json — do not edit by hand.
|
|
2
2
|
// Regenerate with: yarn workspace @lifi/composer-sdk generate
|
|
3
3
|
|
|
4
|
-
import type {
|
|
5
|
-
AnyBindable,
|
|
6
|
-
FlowBuilderInternal,
|
|
7
|
-
} from '../authoring/FlowBuilderCore.js';
|
|
4
|
+
import type { FlowBuilderInternal } from '../authoring/FlowBuilderCore.js';
|
|
8
5
|
import type { Bindable, OutputHandle } from '../authoring/handles.js';
|
|
9
6
|
import type {
|
|
10
7
|
CoreCallResult,
|
|
@@ -38,6 +35,7 @@ import type {
|
|
|
38
35
|
CoreSplitConfig,
|
|
39
36
|
CoreStaticCallConfig,
|
|
40
37
|
CoreTransferConfig,
|
|
38
|
+
FlySwapConfig,
|
|
41
39
|
InvariantEqConfig,
|
|
42
40
|
InvariantGtConfig,
|
|
43
41
|
InvariantGteConfig,
|
|
@@ -47,6 +45,7 @@ import type {
|
|
|
47
45
|
InvariantNumericConfig,
|
|
48
46
|
InvariantNumericInRangeConfig,
|
|
49
47
|
LifiSwapConfig,
|
|
48
|
+
LifiZapAsyncConfig,
|
|
50
49
|
LifiZapConfig,
|
|
51
50
|
MorphoBlueSupplyCollateralConfig,
|
|
52
51
|
MorphoBlueWithdrawCollateralConfig,
|
|
@@ -520,11 +519,22 @@ export interface MorphoBlueWithdrawCollateralArgs {
|
|
|
520
519
|
export interface LifiZapArgs {
|
|
521
520
|
readonly bind: {
|
|
522
521
|
readonly amountIn: Bindable<'resource'>;
|
|
522
|
+
readonly recipient?: Bindable<'address'>;
|
|
523
523
|
};
|
|
524
524
|
readonly config: LifiZapConfig;
|
|
525
525
|
readonly guards?: readonly TypedGuard<'amountOut'>[];
|
|
526
526
|
}
|
|
527
527
|
|
|
528
|
+
/** Route tokens into a DeFi protocol position whose output becomes available after the initiating transaction settles */
|
|
529
|
+
export interface LifiZapAsyncArgs {
|
|
530
|
+
readonly bind: {
|
|
531
|
+
readonly amountIn: Bindable<'resource'>;
|
|
532
|
+
readonly recipient: Bindable<'address'>;
|
|
533
|
+
};
|
|
534
|
+
readonly config: LifiZapAsyncConfig;
|
|
535
|
+
readonly guards?: readonly TypedGuard<never>[];
|
|
536
|
+
}
|
|
537
|
+
|
|
528
538
|
/** Exact-output (BUY) swap via the Paraswap/Velora Market API: produce exactly `exactAmountOut` of the destination token, pulling only the source needed and exposing the genuinely-unspent source as `unspentIn`. */
|
|
529
539
|
export interface ParaswapBuyArgs {
|
|
530
540
|
readonly bind: {
|
|
@@ -541,6 +551,15 @@ export interface CorePeekArgs {
|
|
|
541
551
|
readonly guards?: readonly TypedGuard<'result'>[];
|
|
542
552
|
}
|
|
543
553
|
|
|
554
|
+
/** Swap via Fly's DexAggregator, sized at runtime: the router calldata leaves `amountIn` unset, so an upstream op's output can feed the swap without being known at plan time. Either leg may be the chain-native coin. */
|
|
555
|
+
export interface FlySwapArgs {
|
|
556
|
+
readonly bind: {
|
|
557
|
+
readonly amountIn: Bindable<'resource'>;
|
|
558
|
+
};
|
|
559
|
+
readonly config: FlySwapConfig;
|
|
560
|
+
readonly guards?: readonly TypedGuard<'unspentIn'>[];
|
|
561
|
+
}
|
|
562
|
+
|
|
544
563
|
export interface CoreSplitOutputs {
|
|
545
564
|
readonly a: OutputHandle<'resource'>;
|
|
546
565
|
readonly b: OutputHandle<'resource'>;
|
|
@@ -629,6 +648,10 @@ export interface LifiZapOutputs {
|
|
|
629
648
|
readonly amountOut: OutputHandle<'resource'>;
|
|
630
649
|
}
|
|
631
650
|
|
|
651
|
+
export interface LifiZapAsyncOutputs {
|
|
652
|
+
readonly amountOut: OutputHandle<'resource'>;
|
|
653
|
+
}
|
|
654
|
+
|
|
632
655
|
export interface ParaswapBuyOutputs {
|
|
633
656
|
readonly amountOut: OutputHandle<'resource'>;
|
|
634
657
|
readonly unspentIn: OutputHandle<'resource'>;
|
|
@@ -638,6 +661,11 @@ export interface CorePeekOutputs {
|
|
|
638
661
|
readonly result: OutputHandle<'uint256'>;
|
|
639
662
|
}
|
|
640
663
|
|
|
664
|
+
export interface FlySwapOutputs {
|
|
665
|
+
readonly amountOut: OutputHandle<'resource'>;
|
|
666
|
+
readonly unspentIn: OutputHandle<'resource'>;
|
|
667
|
+
}
|
|
668
|
+
|
|
641
669
|
export type GeneratedOps = {
|
|
642
670
|
readonly core: {
|
|
643
671
|
/** Split a resource into two outputs by basis-point ratio — original id: "core.split" */
|
|
@@ -741,6 +769,11 @@ export type GeneratedOps = {
|
|
|
741
769
|
readonly swap: (nodeId: string, args: LifiSwapArgs) => LifiSwapOutputs;
|
|
742
770
|
/** Route tokens into a DeFi protocol position via the edge catalog — original id: "lifi.zap" */
|
|
743
771
|
readonly zap: (nodeId: string, args: LifiZapArgs) => LifiZapOutputs;
|
|
772
|
+
/** Route tokens into a DeFi protocol position whose output becomes available after the initiating transaction settles — original id: "lifi.zapAsync" */
|
|
773
|
+
readonly zapAsync: (
|
|
774
|
+
nodeId: string,
|
|
775
|
+
args: LifiZapAsyncArgs,
|
|
776
|
+
) => LifiZapAsyncOutputs;
|
|
744
777
|
};
|
|
745
778
|
readonly invariant: {
|
|
746
779
|
/** Assert that an account holds at least a minimum token balance — original id: "invariant.balanceAtLeast" */
|
|
@@ -840,6 +873,10 @@ export type GeneratedOps = {
|
|
|
840
873
|
/** Exact-output (BUY) swap via the Paraswap/Velora Market API: produce exactly `exactAmountOut` of the destination token, pulling only the source needed and exposing the genuinely-unspent source as `unspentIn`. — original id: "paraswap.buy" */
|
|
841
874
|
readonly buy: (nodeId: string, args: ParaswapBuyArgs) => ParaswapBuyOutputs;
|
|
842
875
|
};
|
|
876
|
+
readonly fly: {
|
|
877
|
+
/** Swap via Fly's DexAggregator, sized at runtime: the router calldata leaves `amountIn` unset, so an upstream op's output can feed the swap without being known at plan time. Either leg may be the chain-native coin. — original id: "fly.swap" */
|
|
878
|
+
readonly swap: (nodeId: string, args: FlySwapArgs) => FlySwapOutputs;
|
|
879
|
+
};
|
|
843
880
|
};
|
|
844
881
|
|
|
845
882
|
export const bindGeneratedOps = (
|
|
@@ -917,8 +954,8 @@ export const bindGeneratedOps = (
|
|
|
917
954
|
call: <TSig extends string>(nodeId: string, args: CoreCallArgs<TSig>) => {
|
|
918
955
|
const wire = buildCallWireFormat({
|
|
919
956
|
resource: args.resource,
|
|
920
|
-
bind: args.bind
|
|
921
|
-
config: args.config
|
|
957
|
+
bind: args.bind,
|
|
958
|
+
config: args.config,
|
|
922
959
|
guards: args.guards,
|
|
923
960
|
});
|
|
924
961
|
return builder.call(nodeId, wire.op, wire, {
|
|
@@ -933,8 +970,8 @@ export const bindGeneratedOps = (
|
|
|
933
970
|
nodeId,
|
|
934
971
|
'core.staticCall',
|
|
935
972
|
buildStaticCallWireFormat({
|
|
936
|
-
bind: args.bind
|
|
937
|
-
config: args.config
|
|
973
|
+
bind: args.bind,
|
|
974
|
+
config: args.config,
|
|
938
975
|
guards: args.guards,
|
|
939
976
|
}),
|
|
940
977
|
{ result: 'uint256' } as const,
|
|
@@ -960,6 +997,10 @@ export const bindGeneratedOps = (
|
|
|
960
997
|
builder.call(nodeId, 'lifi.zap', args, {
|
|
961
998
|
amountOut: 'resource',
|
|
962
999
|
} as const),
|
|
1000
|
+
zapAsync: (nodeId: string, args: LifiZapAsyncArgs) =>
|
|
1001
|
+
builder.call(nodeId, 'lifi.zapAsync', args, {
|
|
1002
|
+
amountOut: 'resource',
|
|
1003
|
+
} as const),
|
|
963
1004
|
},
|
|
964
1005
|
invariant: {
|
|
965
1006
|
balanceAtLeast: (nodeId: string, args: InvariantBalanceAtLeastArgs) =>
|
|
@@ -1078,4 +1119,11 @@ export const bindGeneratedOps = (
|
|
|
1078
1119
|
unspentIn: 'resource',
|
|
1079
1120
|
} as const),
|
|
1080
1121
|
},
|
|
1122
|
+
fly: {
|
|
1123
|
+
swap: (nodeId: string, args: FlySwapArgs) =>
|
|
1124
|
+
builder.call(nodeId, 'fly.swap', args, {
|
|
1125
|
+
amountOut: 'resource',
|
|
1126
|
+
unspentIn: 'resource',
|
|
1127
|
+
} as const),
|
|
1128
|
+
},
|
|
1081
1129
|
});
|
package/src/index.ts
CHANGED
|
@@ -19,9 +19,11 @@ export type {
|
|
|
19
19
|
OutputKind,
|
|
20
20
|
TypedGuard,
|
|
21
21
|
TypedRef,
|
|
22
|
+
TypedLiteral,
|
|
22
23
|
} from './types.js';
|
|
23
24
|
|
|
24
25
|
export type {
|
|
26
|
+
ChainSummary,
|
|
25
27
|
GetZapPacksOptions,
|
|
26
28
|
ZapPackEdge,
|
|
27
29
|
ZapPackOverview,
|
|
@@ -36,11 +38,15 @@ export type {
|
|
|
36
38
|
ApprovalEntry,
|
|
37
39
|
Call,
|
|
38
40
|
ComposeCompilePartialData,
|
|
41
|
+
ComposeAction,
|
|
42
|
+
ComposeFill,
|
|
43
|
+
ComposeFee,
|
|
44
|
+
ComposeUserProgramSimulation,
|
|
39
45
|
ComposeCompileRequest,
|
|
40
46
|
ComposeCompileResult,
|
|
41
47
|
ComposeCompileSuccessData,
|
|
42
|
-
ComposeContinuation,
|
|
43
48
|
ComposeErrorKind,
|
|
49
|
+
ComposeRouteRequest,
|
|
44
50
|
ComposeTransactionRequest,
|
|
45
51
|
FailedPreparedOp,
|
|
46
52
|
Flow,
|
|
@@ -50,8 +56,13 @@ export type {
|
|
|
50
56
|
Precondition,
|
|
51
57
|
PreconditionConfigOf,
|
|
52
58
|
PriceImpact,
|
|
59
|
+
ProducedResource,
|
|
53
60
|
Ref,
|
|
54
61
|
Resource,
|
|
62
|
+
RouteAmount,
|
|
63
|
+
RouteAmountAll,
|
|
64
|
+
RouteAmountExact,
|
|
65
|
+
SimulatedAmounts,
|
|
55
66
|
SimulationPolicy,
|
|
56
67
|
SimulationRevert,
|
|
57
68
|
SolType,
|
|
@@ -83,6 +94,8 @@ export { isComposeError, isComposePreparationError } from './errors.js';
|
|
|
83
94
|
|
|
84
95
|
export type {
|
|
85
96
|
Bindable,
|
|
97
|
+
RefBindable,
|
|
98
|
+
AnyRefBindable,
|
|
86
99
|
InputHandle,
|
|
87
100
|
ResourceInputHandle,
|
|
88
101
|
OutputHandle,
|
|
@@ -108,6 +121,7 @@ import * as materialisersMod from './generated/materialisers.generated.js';
|
|
|
108
121
|
import * as preconditionsMod from './generated/preconditions.generated.js';
|
|
109
122
|
import * as rawMod from './raw.js';
|
|
110
123
|
import * as resourcesMod from './resources.js';
|
|
124
|
+
import * as routeAmountMod from './routeAmount.js';
|
|
111
125
|
|
|
112
126
|
/**
|
|
113
127
|
* Guard factories for protecting operation outputs (e.g. slippage tolerance).
|
|
@@ -168,6 +182,24 @@ export const preconditions: typeof preconditionsMod = preconditionsMod;
|
|
|
168
182
|
* ```
|
|
169
183
|
*/
|
|
170
184
|
export const resources: typeof resourcesMod = resourcesMod;
|
|
185
|
+
/**
|
|
186
|
+
* Amount constructors for {@link ComposeSdk.route}. Use
|
|
187
|
+
* {@link routeAmount.exact} to spend a fixed amount of the `fromToken`, and
|
|
188
|
+
* {@link routeAmount.all} to spend the signer's whole balance.
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```ts
|
|
192
|
+
* // USDC into the Aave v3 aEthUSDC position — one routing-catalog edge.
|
|
193
|
+
* const result = await sdk.route({
|
|
194
|
+
* chainId: 1,
|
|
195
|
+
* fromToken: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
|
|
196
|
+
* toToken: '0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c',
|
|
197
|
+
* amount: routeAmount.exact(1_000_000n),
|
|
198
|
+
* signer: '0xYourAddress...',
|
|
199
|
+
* });
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
202
|
+
export const routeAmount: typeof routeAmountMod = routeAmountMod;
|
|
171
203
|
export * from './generated/config.generated.js';
|
|
172
204
|
|
|
173
205
|
/**
|
package/src/raw.ts
CHANGED
|
@@ -6,5 +6,5 @@
|
|
|
6
6
|
* For most use cases, prefer the generated operation methods on {@link FlowBuilder}
|
|
7
7
|
* (e.g. `builder.lifi.swap(...)`) and the typed guard/materialiser helpers.
|
|
8
8
|
*/
|
|
9
|
-
export { rawGuard as guard, ref } from './authoring/raw.js';
|
|
9
|
+
export { rawGuard as guard, literal, ref } from './authoring/raw.js';
|
|
10
10
|
export { materialiser } from './run/inputs.js';
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { RouteAmountAll, RouteAmountExact } from '@lifi/compose-spec';
|
|
2
|
+
|
|
3
|
+
// Constructors for the `amount` member of a `ComposeRouteRequest`. The wire
|
|
4
|
+
// union is discriminated by `type` and — deliberately, because the two variants
|
|
5
|
+
// mean different things — names its payload field differently in each variant:
|
|
6
|
+
// `amount` is the sum actually moved, `simAmount` is only a quoting stand-in for
|
|
7
|
+
// a balance resolved on-chain. These helpers keep call sites from having to
|
|
8
|
+
// remember which name goes with which discriminant.
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Spend an exact amount of the route's `fromToken`.
|
|
12
|
+
*
|
|
13
|
+
* @param amount - Amount in the token's smallest unit. `bigint` is serialised
|
|
14
|
+
* to a decimal string when the request is sent.
|
|
15
|
+
* @returns The `EXACT` member of the route amount union.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* const result = await sdk.route({
|
|
20
|
+
* chainId: 1,
|
|
21
|
+
* fromToken: NATIVE_ETH,
|
|
22
|
+
* toToken: WETH,
|
|
23
|
+
* amount: routeAmount.exact(10n ** 17n), // 0.1 ETH, wrapped
|
|
24
|
+
* signer: OWNER,
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export const exact = (amount: bigint | string): RouteAmountExact => ({
|
|
29
|
+
type: 'EXACT',
|
|
30
|
+
amount,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Spend the signer's entire `fromToken` balance, resolved on-chain at execution
|
|
35
|
+
* time.
|
|
36
|
+
*
|
|
37
|
+
* Not supported when `fromToken` is the chain's native sentinel — the server
|
|
38
|
+
* rejects it. A gas coin is sent via `msg.value`, so there is no on-chain
|
|
39
|
+
* balance to sweep; use {@link exact} for native inputs.
|
|
40
|
+
*
|
|
41
|
+
* @param simAmount - A realistic estimate of that balance, in the token's
|
|
42
|
+
* smallest unit. The server quotes and simulates against this value, so it
|
|
43
|
+
* shapes the returned quote and preconditions — but the amount actually moved
|
|
44
|
+
* is whatever the balance turns out to be.
|
|
45
|
+
* @returns The `ALL` member of the route amount union.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* const result = await sdk.route({
|
|
50
|
+
* chainId: 1,
|
|
51
|
+
* fromToken: USDC,
|
|
52
|
+
* toToken: A_ETH_USDC,
|
|
53
|
+
* amount: routeAmount.all(1_000_000n), // estimate: ~1 USDC on hand
|
|
54
|
+
* signer: OWNER,
|
|
55
|
+
* });
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export const all = (simAmount: bigint | string): RouteAmountAll => ({
|
|
59
|
+
type: 'ALL',
|
|
60
|
+
simAmount,
|
|
61
|
+
});
|
package/src/run/inputs.ts
CHANGED
|
@@ -54,6 +54,13 @@ export interface ComposeRunInput<T extends InputSchema = InputSchema> {
|
|
|
54
54
|
* result with the transaction and revert diagnostics.
|
|
55
55
|
*/
|
|
56
56
|
readonly simulationPolicy?: SimulationPolicy;
|
|
57
|
+
/**
|
|
58
|
+
* When `true`, the server also simulates the final user-facing transaction
|
|
59
|
+
* after the structured simulation succeeds; reverts honour
|
|
60
|
+
* `simulationPolicy`. On success the result is echoed back on the response as
|
|
61
|
+
* `userProgramSimulation`. Defaults to `false`.
|
|
62
|
+
*/
|
|
63
|
+
readonly simulateUserProgram?: boolean;
|
|
57
64
|
/**
|
|
58
65
|
* When `true`, the server checks on-chain ERC-20 allowances and omits
|
|
59
66
|
* approvals that are already sufficient. Defaults to `false`.
|
|
@@ -89,6 +96,21 @@ export const materialiser = (
|
|
|
89
96
|
...config,
|
|
90
97
|
});
|
|
91
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Drops the keys whose value is `undefined`, so optional fields are omitted
|
|
101
|
+
* from the wire payload rather than serialized as `null`.
|
|
102
|
+
*
|
|
103
|
+
* A local copy of `pickDefined` from `@lifi/utils`: this package is published
|
|
104
|
+
* to npm and `@lifi/utils` is a private workspace package, so it cannot be a
|
|
105
|
+
* runtime dependency here.
|
|
106
|
+
*/
|
|
107
|
+
const pickDefined = <S extends Record<string, unknown>>(
|
|
108
|
+
obj: S,
|
|
109
|
+
): Partial<{ [K in keyof S]: Exclude<S[K], undefined> }> =>
|
|
110
|
+
Object.fromEntries(
|
|
111
|
+
Object.entries(obj).filter(([, value]) => value !== undefined),
|
|
112
|
+
) as Partial<{ [K in keyof S]: Exclude<S[K], undefined> }>;
|
|
113
|
+
|
|
92
114
|
/**
|
|
93
115
|
* Assembles a {@link ComposeRun} object from individual parameters.
|
|
94
116
|
* Used internally by the SDK; prefer {@link ComposeRunInput} for external use.
|
|
@@ -105,24 +127,21 @@ export const buildRun = (run: {
|
|
|
105
127
|
maxPriceImpactBps?: number;
|
|
106
128
|
sweepTo?: SweepTo;
|
|
107
129
|
simulationPolicy?: SimulationPolicy;
|
|
130
|
+
simulateUserProgram?: boolean;
|
|
108
131
|
checkOnChainAllowances?: boolean;
|
|
109
132
|
}): ComposeRun => ({
|
|
110
133
|
inputs: run.inputs,
|
|
111
|
-
...(run.preconditions?.length && { preconditions: run.preconditions }),
|
|
112
134
|
signer: run.signer,
|
|
113
|
-
...(
|
|
114
|
-
|
|
115
|
-
|
|
135
|
+
...pickDefined({
|
|
136
|
+
// An empty precondition list is the same as none, so drop it too.
|
|
137
|
+
preconditions: run.preconditions?.length ? run.preconditions : undefined,
|
|
138
|
+
assumptions: run.assumptions,
|
|
139
|
+
referrer: run.referrer,
|
|
116
140
|
integratorFeeBps: run.integratorFeeBps,
|
|
117
|
-
}),
|
|
118
|
-
...(run.maxPriceImpactBps !== undefined && {
|
|
119
141
|
maxPriceImpactBps: run.maxPriceImpactBps,
|
|
120
|
-
|
|
121
|
-
...(run.sweepTo !== undefined && { sweepTo: run.sweepTo }),
|
|
122
|
-
...(run.simulationPolicy !== undefined && {
|
|
142
|
+
sweepTo: run.sweepTo,
|
|
123
143
|
simulationPolicy: run.simulationPolicy,
|
|
124
|
-
|
|
125
|
-
...(run.checkOnChainAllowances !== undefined && {
|
|
144
|
+
simulateUserProgram: run.simulateUserProgram,
|
|
126
145
|
checkOnChainAllowances: run.checkOnChainAllowances,
|
|
127
146
|
}),
|
|
128
147
|
});
|
package/src/run/simulate.ts
CHANGED
|
@@ -12,8 +12,11 @@ import type {
|
|
|
12
12
|
export interface BuildSimulateRequestInput {
|
|
13
13
|
/**
|
|
14
14
|
* A result from `builder.compile(...)` / `client.compile(...)`. Both
|
|
15
|
-
* `success` and `partial` results
|
|
16
|
-
*
|
|
15
|
+
* `success` and `partial` results are valid input — the helper does not
|
|
16
|
+
* discriminate on `status`. A success result for an empty compiled program
|
|
17
|
+
* (a settle-only `funding: 'external'` flow) carries no
|
|
18
|
+
* `transactionRequest`; there is nothing to simulate and this helper
|
|
19
|
+
* throws — submit the result's `actions` entries directly instead.
|
|
17
20
|
*/
|
|
18
21
|
readonly result: ComposeCompileResult;
|
|
19
22
|
/** EVM chain id. A compile result does not carry the target chain. */
|
|
@@ -65,6 +68,15 @@ export const buildSimulateRequest = (
|
|
|
65
68
|
): SimulateRequest => {
|
|
66
69
|
const { result, chainId, signer, trackedBalances, requirements, block } =
|
|
67
70
|
input;
|
|
71
|
+
// A settle-only flow authored with `funding: 'external'` compiles to an
|
|
72
|
+
// empty program: the success response carries no `transactionRequest`, so
|
|
73
|
+
// there is nothing to simulate — the required submissions are the
|
|
74
|
+
// `actions` entries, submitted directly.
|
|
75
|
+
if (result.transactionRequest === undefined) {
|
|
76
|
+
throw new Error(
|
|
77
|
+
'buildSimulateRequest: the compile result has no transactionRequest (empty compiled program — a settle-only external-funding flow); submit the `actions` entries instead of simulating',
|
|
78
|
+
);
|
|
79
|
+
}
|
|
68
80
|
return {
|
|
69
81
|
chainId,
|
|
70
82
|
from: signer,
|
package/src/sdk.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
ComposeCompileRequest,
|
|
3
3
|
ComposeCompileResult,
|
|
4
|
+
ComposeRouteRequest,
|
|
4
5
|
InputSpec,
|
|
5
6
|
SimulateRequest,
|
|
6
7
|
SimulateResult,
|
|
@@ -13,6 +14,7 @@ import {
|
|
|
13
14
|
type TypedFlow,
|
|
14
15
|
} from './authoring/FlowBuilderCore.js';
|
|
15
16
|
import { type ComposeClient, createComposeClient } from './client.js';
|
|
17
|
+
import type { ChainSummary } from './discovery.js';
|
|
16
18
|
import {
|
|
17
19
|
bindGeneratedOps,
|
|
18
20
|
type GeneratedOps,
|
|
@@ -108,6 +110,33 @@ export interface ComposeSdk {
|
|
|
108
110
|
chainId: number,
|
|
109
111
|
options: FlowOptions<T>,
|
|
110
112
|
) => FlowBuilder<T>;
|
|
113
|
+
/**
|
|
114
|
+
* Fetches the chains this Compose deployment supports, ascending by
|
|
115
|
+
* `chainId`. Thin pass-through to {@link ComposeClient.getChains}; see it
|
|
116
|
+
* for what "supported" means and for the caching caveat.
|
|
117
|
+
*
|
|
118
|
+
* Each entry pairs the `chainId` with a display `name`, so one call both
|
|
119
|
+
* gates a chain selector and labels it. Key on `chainId`; `name` is a
|
|
120
|
+
* deployment-maintained label that can change.
|
|
121
|
+
*
|
|
122
|
+
* Use it to fail fast before building a flow for a chain the server would
|
|
123
|
+
* reject.
|
|
124
|
+
*
|
|
125
|
+
* @returns The supported chains, ascending by `chainId`.
|
|
126
|
+
* @throws {@link ComposeError} on network or server errors.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```ts
|
|
130
|
+
* const chains = await sdk.getSupportedChains();
|
|
131
|
+
* if (!chains.some((c) => c.chainId === 8453)) {
|
|
132
|
+
* throw new Error('Base is not supported');
|
|
133
|
+
* }
|
|
134
|
+
* for (const { chainId, name } of chains) {
|
|
135
|
+
* console.log(`${name} (${chainId})`);
|
|
136
|
+
* }
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
readonly getSupportedChains: () => Promise<readonly ChainSummary[]>;
|
|
111
140
|
/**
|
|
112
141
|
* Builds a raw compile request without sending it. Useful for inspecting the
|
|
113
142
|
* request payload or submitting it through a custom transport.
|
|
@@ -119,6 +148,21 @@ export interface ComposeSdk {
|
|
|
119
148
|
flow: TypedFlow<T>,
|
|
120
149
|
run: ComposeRunInput<T>,
|
|
121
150
|
) => ComposeCompileRequest;
|
|
151
|
+
/**
|
|
152
|
+
* Compiles a token pair on one chain — as of today a single zap step over
|
|
153
|
+
* one routing-catalog edge. Thin pass-through to
|
|
154
|
+
* {@link ComposeClient.route}; see it for the current single-step limit,
|
|
155
|
+
* when to prefer `flow(...).compile(...)`, the `success` / `partial`
|
|
156
|
+
* discrimination, and error behaviour. Build the `amount` with
|
|
157
|
+
* `routeAmount.exact(...)` / `routeAmount.all(...)`.
|
|
158
|
+
*
|
|
159
|
+
* @param request - The from/to token pair, amount, signer, and route options.
|
|
160
|
+
* @returns A discriminated result: `status: 'success'` or `status: 'partial'`.
|
|
161
|
+
* @throws {@link ComposeError} on network, validation, or server errors.
|
|
162
|
+
*/
|
|
163
|
+
readonly route: (
|
|
164
|
+
request: ComposeRouteRequest,
|
|
165
|
+
) => Promise<ComposeCompileResult>;
|
|
122
166
|
/**
|
|
123
167
|
* Simulates a raw, pre-encoded transaction. Thin pass-through to
|
|
124
168
|
* {@link ComposeClient.simulate}; see it for the `ok` / `revert` / `error`
|
|
@@ -162,6 +206,7 @@ export const createComposeSdk = (options: ComposeSdkOptions): ComposeSdk => {
|
|
|
162
206
|
maxPriceImpactBps: run.maxPriceImpactBps,
|
|
163
207
|
sweepTo: run.sweepTo,
|
|
164
208
|
simulationPolicy: run.simulationPolicy,
|
|
209
|
+
simulateUserProgram: run.simulateUserProgram,
|
|
165
210
|
checkOnChainAllowances: run.checkOnChainAllowances,
|
|
166
211
|
}),
|
|
167
212
|
});
|
|
@@ -187,7 +232,9 @@ export const createComposeSdk = (options: ComposeSdkOptions): ComposeSdk => {
|
|
|
187
232
|
return {
|
|
188
233
|
client: composeClient,
|
|
189
234
|
flow,
|
|
235
|
+
getSupportedChains: composeClient.getChains,
|
|
190
236
|
request,
|
|
237
|
+
route: composeClient.route,
|
|
191
238
|
simulate: composeClient.simulate,
|
|
192
239
|
};
|
|
193
240
|
};
|
package/src/types.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Ref } from '@lifi/compose-spec';
|
|
1
|
+
import type { LiteralBinding, Ref } from '@lifi/compose-spec';
|
|
2
2
|
import {
|
|
3
3
|
InputSpec,
|
|
4
4
|
MaterialiserInput,
|
|
@@ -58,6 +58,25 @@ export interface TypedRef<T extends OutputKind = OutputKind> extends Ref {
|
|
|
58
58
|
readonly __outputKind?: T;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* A literal bind value carrying a phantom type parameter.
|
|
63
|
+
*
|
|
64
|
+
* The wire format accepts a constant in a bind slot as
|
|
65
|
+
* `{ kind: <solType>, value: <string> }`, alongside `$ref` pointers. Use it
|
|
66
|
+
* for a value that must be baked into the flow document rather than supplied
|
|
67
|
+
* at run time — the destination of a flow the backend stores and re-runs
|
|
68
|
+
* later (a `continuation.settle` node's `continuationFlow`) has no run to
|
|
69
|
+
* take an input from.
|
|
70
|
+
*
|
|
71
|
+
* @typeParam T - The Solidity type of the literal (e.g. `'address'`).
|
|
72
|
+
*/
|
|
73
|
+
export interface TypedLiteral<
|
|
74
|
+
T extends SolType = SolType,
|
|
75
|
+
> extends LiteralBinding {
|
|
76
|
+
readonly kind: T;
|
|
77
|
+
readonly __outputKind?: T;
|
|
78
|
+
}
|
|
79
|
+
|
|
61
80
|
/**
|
|
62
81
|
* An input declaration in a flow schema.
|
|
63
82
|
* `Resource` values become resource inputs (token amounts);
|