@lifi/composer-sdk 0.11.3 → 0.13.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 +3 -3
- package/dist/authoring/raw.cjs +10 -2
- package/dist/authoring/raw.cjs.map +1 -1
- package/dist/authoring/raw.d.cts +10 -2
- package/dist/authoring/raw.d.ts +10 -2
- package/dist/authoring/raw.js +10 -2
- package/dist/authoring/raw.js.map +1 -1
- package/dist/authoring/signatureArgs.cjs +10 -3
- package/dist/authoring/signatureArgs.cjs.map +1 -1
- package/dist/authoring/signatureArgs.d.cts +23 -16
- package/dist/authoring/signatureArgs.d.ts +23 -16
- package/dist/authoring/signatureArgs.js +10 -3
- package/dist/authoring/signatureArgs.js.map +1 -1
- package/dist/client.cjs +1 -1
- package/dist/client.js +1 -1
- package/dist/generated/config.generated.d.cts +6 -18
- package/dist/generated/config.generated.d.ts +6 -18
- package/dist/generated/operations.generated.cjs.map +1 -1
- package/dist/generated/operations.generated.d.cts +1 -1
- package/dist/generated/operations.generated.d.ts +1 -1
- package/dist/generated/operations.generated.js.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js.map +1 -1
- package/dist/run/inputs.cjs +0 -1
- package/dist/run/inputs.cjs.map +1 -1
- package/dist/run/inputs.d.cts +0 -8
- package/dist/run/inputs.d.ts +0 -8
- package/dist/run/inputs.js +0 -1
- package/dist/run/inputs.js.map +1 -1
- package/dist/sdk.cjs +0 -1
- package/dist/sdk.cjs.map +1 -1
- package/dist/sdk.js +0 -1
- package/dist/sdk.js.map +1 -1
- package/package.json +2 -2
- package/src/authoring/raw.ts +10 -2
- package/src/authoring/signatureArgs.ts +53 -23
- package/src/examples/continuationBridgeSettle.ts +1 -2
- package/src/examples/continuationExactInvoice.ts +341 -0
- package/src/examples/continuationSettle.ts +1 -1
- package/src/examples/run.ts +27 -0
- package/src/generated/config.generated.ts +16 -31
- package/src/generated/operations.generated.ts +1 -1
- package/src/index.ts +2 -1
- package/src/run/inputs.ts +0 -9
- package/src/sdk.ts +0 -1
- package/src/examples/swapWithFee.ts +0 -59
package/README.md
CHANGED
|
@@ -253,7 +253,6 @@ The SDK sends only the fields you set. The server applies the defaults.
|
|
|
253
253
|
|
|
254
254
|
- **`slippageBps`**: default `100` (1%). An end-to-end tolerance on the route's final output, not a per-hop one.
|
|
255
255
|
- **`maxPriceImpactBps`**: reject the route when its priced impact exceeds this. Default `500`; `0` disables the check.
|
|
256
|
-
- **`integratorFeeBps`**: your fee, taken from the input amount. Range 0 to 9000, default `0`. A non-zero value requires an integration-scoped `apiKey`.
|
|
257
256
|
- **`referrer`**: opaque tag forwarded to the underlying quote provider.
|
|
258
257
|
- **`sweepTo`**: owner of everything the route leaves behind. An address or `{ $ref: 'context.sender' }`; `context.executionAddress` is rejected. Defaults to the signer, except that a route with a swap requires it.
|
|
259
258
|
- **`checkOnChainAllowances`**: omit approvals that current allowances already cover. Default `false`.
|
|
@@ -366,7 +365,8 @@ switch (result.status) {
|
|
|
366
365
|
}
|
|
367
366
|
```
|
|
368
367
|
|
|
369
|
-
- `requirements` entries are `Erc20Balance`, `NativeBalance`, or `
|
|
368
|
+
- `requirements` entries are `Erc20Balance`, `NativeBalance`, `Erc20Allowance`, or `Permit2Allowance`. Use the zero address as a `trackedBalances` token to watch the native balance.
|
|
369
|
+
- `Permit2Allowance` (`owner`, `token`, `spender`, `amount`) lets `spender` pull `token` from `owner` through Uniswap Permit2's `transferFrom`. The simulation also grants the ERC-20 allowance `owner` → Permit2, but not the owner's balance: fund it with an `Erc20Balance`. Only the canonical Permit2 address `0x000000000022D473030F116dDEE9F6B43aC78BA3` is supported; on a chain without it, `simulate` returns `status: 'error'` with a message that names Permit2 and the chain.
|
|
370
370
|
- Amount fields accept `bigint` or decimal strings.
|
|
371
371
|
- `SIMULATE_MAX_TRACKED_BALANCES` and `SIMULATE_MAX_REQUIREMENTS` (both `40`) are exported.
|
|
372
372
|
- A `revert` is returned, not thrown. Only transport failures and HTTP 400/401/403/404/429/5xx throw `ComposeError`.
|
|
@@ -501,7 +501,6 @@ Each file in `src/examples/` is a complete flow:
|
|
|
501
501
|
- **readContractState**: compare `peek` (compile time), `staticCall` (execution time), and `balanceOf` (resource)
|
|
502
502
|
- **emitCustomEvent**: emit a custom event with `core.emitEvent2`; `bytes32` ports accept any static 32-byte handle
|
|
503
503
|
- **swapWithAllowRevert**: handle both branches of `ComposeCompileResult` under `'allow-revert'`
|
|
504
|
-
- **swapWithFee**: collect an integrator fee via `integratorFeeBps` (requires an integration-scoped `apiKey`)
|
|
505
504
|
- **transferTokens**: transfer ERC-20 tokens from the proxy to any recipient
|
|
506
505
|
- **callContract**: call an arbitrary contract (ERC-4626 redeem, reward claim) without a typed op
|
|
507
506
|
- **flySwap**: on Base, exit a Pendle PT via `lifi.zap`, then swap all proceeds to WETH with `fly.swap`
|
|
@@ -521,6 +520,7 @@ Each file in `src/examples/` is a complete flow:
|
|
|
521
520
|
- **simulateRawTransaction** / **simulateCompiledSwap**: raw and compiled simulation
|
|
522
521
|
- **continuationSettle**: swap USDC to WETH on Base, then escrow the WETH for a deferred settlement whose leg supplies it to Aave and delivers the aBasWETH position
|
|
523
522
|
- **continuationBridgeSettle**: bridge USDC from Arbitrum into a settle escrow on Base; when the delivery lands, the leg supplies it to Aave and delivers the aBasUSDC position
|
|
523
|
+
- **continuationExactInvoice**: escrow USDC on Base for an exact leg (`exact: true`) that pays a Request Network invoice through `core.call` and returns the surplus; a second builder funds the same leg from a WETH-to-USDC swap, and a third from Arbitrum ETH swapped to USDC and delivered by an exact-output `lifiIntents.order` (`exactAmountOut`) into the escrow at exactly the invoice total, with no outcome (`outcomes: []`)
|
|
524
524
|
|
|
525
525
|
## Staging channel
|
|
526
526
|
|
package/dist/authoring/raw.cjs
CHANGED
|
@@ -47,12 +47,20 @@ const ref = (path) => ({ $ref: path });
|
|
|
47
47
|
* (`continuationFlow`). The leg produces its outcome into its own proxy
|
|
48
48
|
* (`leg.context.executionAddress`) and names no recipient; the composer
|
|
49
49
|
* appends a settlement epilogue at commit that forwards the outcome to the
|
|
50
|
-
* provider's recipient and the residual to `refund`.
|
|
50
|
+
* provider's recipient and the residual to `refund`. A call argument inside
|
|
51
|
+
* the leg (the payee of an invoice the leg pays through `core.call`) is not
|
|
52
|
+
* that recipient and may be a literal.
|
|
53
|
+
*
|
|
54
|
+
* In a `core.call` / `core.staticCall` bind, `kind` must equal the parameter's
|
|
55
|
+
* Solidity type exactly, and `value` must encode as that type: a decimal or
|
|
56
|
+
* `0x` integer, `'true'` / `'false'`, a `0x` address (mixed case only with a
|
|
57
|
+
* valid checksum), or a `0x` hex byte string of the right length.
|
|
51
58
|
*
|
|
52
59
|
* @typeParam T - The Solidity type of the literal (e.g. `'address'`).
|
|
53
60
|
* @param kind - The literal's Solidity type.
|
|
54
61
|
* @param value - The literal value, as the wire format carries it: a string.
|
|
55
|
-
* @returns A {@link TypedLiteral} accepted by `Bindable<T>` slots matching `T
|
|
62
|
+
* @returns A {@link TypedLiteral} accepted by `Bindable<T>` slots matching `T`
|
|
63
|
+
* and by `core.call` / `core.staticCall` parameters of type `T`.
|
|
56
64
|
*
|
|
57
65
|
* @example
|
|
58
66
|
* ```ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raw.cjs","names":[],"sources":["../../src/authoring/raw.ts"],"sourcesContent":["import type { AppliedGuard, SolType } from '@lifi/compose-spec';\n\nimport type { OutputKind, TypedLiteral, TypedRef } from '../types.js';\n\n/**\n * Creates a typed `$ref` pointer for use in bind slots.\n *\n * This is an **escape hatch** for referencing values that the typed builder\n * API doesn't cover — for example, outputs of an `untypedOp` node or custom\n * context paths. The caller is responsible for choosing the correct type\n * parameter; no runtime validation occurs.\n *\n * Prefer typed handles (`OutputHandle`, `InputHandle`) and `builder.context`\n * whenever possible. Use `ref` only when you need to construct a `$ref` path\n * manually and want it accepted by a `Bindable<T>` slot.\n *\n * @typeParam T - The output kind this ref represents (e.g. `'address'`, `'uint256'`, `'resource'`).\n * @param path - The `$ref` path (e.g. `\"context.sender\"`, `\"myNode.result\"`).\n * @returns A {@link TypedRef} accepted by `Bindable<T>` slots matching `T`.\n *\n * @example\n * ```ts\n * import { raw } from '@lifi/composer-sdk';\n *\n * // Reference an untypedOp output in a typed operation:\n * builder.untypedOp('custom', 'some.op', {\n * bind: { x: { $ref: 'input.token' } },\n * config: {},\n * });\n * builder.core.add('sum', {\n * bind: {\n * a: raw.ref<'uint256'>('custom.result'),\n * b: someTypedHandle,\n * },\n * });\n * ```\n */\nexport const ref = <T extends OutputKind>(path: string): TypedRef<T> =>\n // The brand is phantom, so the runtime value is the bare wire ref. This is\n // the only place a `TypedRef` is minted; the cast is what the brand buys.\n ({ $ref: path }) as TypedRef<T>;\n\n/**\n * Creates a typed literal for use in bind slots: a constant baked into the\n * flow document rather than supplied at run time.\n *\n * Prefer a declared flow input and `builder.inputs.<name>` — a value the\n * caller supplies per run stays out of the document. Use a literal for a\n * constant that belongs to the document itself, such as a fixed treasury\n * address.\n *\n * Never use a literal for the payee of a `continuation.settle` leg\n * (`continuationFlow`). The leg produces its outcome into its own proxy\n * (`leg.context.executionAddress`) and names no recipient; the composer\n * appends a settlement epilogue at commit that forwards the outcome to the\n * provider's recipient and the residual to `refund
|
|
1
|
+
{"version":3,"file":"raw.cjs","names":[],"sources":["../../src/authoring/raw.ts"],"sourcesContent":["import type { AppliedGuard, SolType } from '@lifi/compose-spec';\n\nimport type { OutputKind, TypedLiteral, TypedRef } from '../types.js';\n\n/**\n * Creates a typed `$ref` pointer for use in bind slots.\n *\n * This is an **escape hatch** for referencing values that the typed builder\n * API doesn't cover — for example, outputs of an `untypedOp` node or custom\n * context paths. The caller is responsible for choosing the correct type\n * parameter; no runtime validation occurs.\n *\n * Prefer typed handles (`OutputHandle`, `InputHandle`) and `builder.context`\n * whenever possible. Use `ref` only when you need to construct a `$ref` path\n * manually and want it accepted by a `Bindable<T>` slot.\n *\n * @typeParam T - The output kind this ref represents (e.g. `'address'`, `'uint256'`, `'resource'`).\n * @param path - The `$ref` path (e.g. `\"context.sender\"`, `\"myNode.result\"`).\n * @returns A {@link TypedRef} accepted by `Bindable<T>` slots matching `T`.\n *\n * @example\n * ```ts\n * import { raw } from '@lifi/composer-sdk';\n *\n * // Reference an untypedOp output in a typed operation:\n * builder.untypedOp('custom', 'some.op', {\n * bind: { x: { $ref: 'input.token' } },\n * config: {},\n * });\n * builder.core.add('sum', {\n * bind: {\n * a: raw.ref<'uint256'>('custom.result'),\n * b: someTypedHandle,\n * },\n * });\n * ```\n */\nexport const ref = <T extends OutputKind>(path: string): TypedRef<T> =>\n // The brand is phantom, so the runtime value is the bare wire ref. This is\n // the only place a `TypedRef` is minted; the cast is what the brand buys.\n ({ $ref: path }) as TypedRef<T>;\n\n/**\n * Creates a typed literal for use in bind slots: a constant baked into the\n * flow document rather than supplied at run time.\n *\n * Prefer a declared flow input and `builder.inputs.<name>` — a value the\n * caller supplies per run stays out of the document. Use a literal for a\n * constant that belongs to the document itself, such as a fixed treasury\n * address.\n *\n * Never use a literal for the payee of a `continuation.settle` leg\n * (`continuationFlow`). The leg produces its outcome into its own proxy\n * (`leg.context.executionAddress`) and names no recipient; the composer\n * appends a settlement epilogue at commit that forwards the outcome to the\n * provider's recipient and the residual to `refund`. A call argument inside\n * the leg (the payee of an invoice the leg pays through `core.call`) is not\n * that recipient and may be a literal.\n *\n * In a `core.call` / `core.staticCall` bind, `kind` must equal the parameter's\n * Solidity type exactly, and `value` must encode as that type: a decimal or\n * `0x` integer, `'true'` / `'false'`, a `0x` address (mixed case only with a\n * valid checksum), or a `0x` hex byte string of the right length.\n *\n * @typeParam T - The Solidity type of the literal (e.g. `'address'`).\n * @param kind - The literal's Solidity type.\n * @param value - The literal value, as the wire format carries it: a string.\n * @returns A {@link TypedLiteral} accepted by `Bindable<T>` slots matching `T`\n * and by `core.call` / `core.staticCall` parameters of type `T`.\n *\n * @example\n * ```ts\n * import { raw } from '@lifi/composer-sdk';\n *\n * // A fixed fee to a treasury baked into the flow document.\n * builder.core.transfer('fee', {\n * bind: {\n * amount: builder.inputs.fee,\n * recipient: raw.literal('address', '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'),\n * },\n * config: {},\n * });\n * ```\n */\nexport const literal = <T extends SolType>(\n kind: T,\n value: string,\n): TypedLiteral<T> => ({ kind, value });\n\n/**\n * Creates a raw guard object for use in the `guards` array of an operation call.\n *\n * @param kind - The guard type (e.g. `\"slippage\"`).\n * @param config - Guard-specific configuration (e.g. `{ toleranceBps: 300 }`).\n * @returns An {@link AppliedGuard} object.\n */\nexport const rawGuard = (\n kind: string,\n config: Record<string, unknown> = {},\n): AppliedGuard => {\n if ('kind' in config) {\n throw new Error(\n `rawGuard: 'kind' must not appear in config (got \"${String(\n config.kind,\n )}\"). Pass it as the first argument instead.`,\n );\n }\n return { ...config, kind };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,MAAa,OAA6B,UAGvC,EAAE,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4ChB,MAAa,WACX,MACA,WACqB;CAAE;CAAM;AAAM;;;;;;;;AASrC,MAAa,YACX,MACA,SAAkC,CAAC,MAClB;CACjB,IAAI,UAAU,QACZ,MAAM,IAAI,MACR,oDAAoD,OAClD,OAAO,IACT,EAAE,2CACJ;CAEF,OAAO;EAAE,GAAG;EAAQ;CAAK;AAC3B"}
|
package/dist/authoring/raw.d.cts
CHANGED
|
@@ -48,12 +48,20 @@ export declare const ref: <T extends OutputKind>(path: string) => TypedRef<T>;
|
|
|
48
48
|
* (`continuationFlow`). The leg produces its outcome into its own proxy
|
|
49
49
|
* (`leg.context.executionAddress`) and names no recipient; the composer
|
|
50
50
|
* appends a settlement epilogue at commit that forwards the outcome to the
|
|
51
|
-
* provider's recipient and the residual to `refund`.
|
|
51
|
+
* provider's recipient and the residual to `refund`. A call argument inside
|
|
52
|
+
* the leg (the payee of an invoice the leg pays through `core.call`) is not
|
|
53
|
+
* that recipient and may be a literal.
|
|
54
|
+
*
|
|
55
|
+
* In a `core.call` / `core.staticCall` bind, `kind` must equal the parameter's
|
|
56
|
+
* Solidity type exactly, and `value` must encode as that type: a decimal or
|
|
57
|
+
* `0x` integer, `'true'` / `'false'`, a `0x` address (mixed case only with a
|
|
58
|
+
* valid checksum), or a `0x` hex byte string of the right length.
|
|
52
59
|
*
|
|
53
60
|
* @typeParam T - The Solidity type of the literal (e.g. `'address'`).
|
|
54
61
|
* @param kind - The literal's Solidity type.
|
|
55
62
|
* @param value - The literal value, as the wire format carries it: a string.
|
|
56
|
-
* @returns A {@link TypedLiteral} accepted by `Bindable<T>` slots matching `T
|
|
63
|
+
* @returns A {@link TypedLiteral} accepted by `Bindable<T>` slots matching `T`
|
|
64
|
+
* and by `core.call` / `core.staticCall` parameters of type `T`.
|
|
57
65
|
*
|
|
58
66
|
* @example
|
|
59
67
|
* ```ts
|
package/dist/authoring/raw.d.ts
CHANGED
|
@@ -48,12 +48,20 @@ export declare const ref: <T extends OutputKind>(path: string) => TypedRef<T>;
|
|
|
48
48
|
* (`continuationFlow`). The leg produces its outcome into its own proxy
|
|
49
49
|
* (`leg.context.executionAddress`) and names no recipient; the composer
|
|
50
50
|
* appends a settlement epilogue at commit that forwards the outcome to the
|
|
51
|
-
* provider's recipient and the residual to `refund`.
|
|
51
|
+
* provider's recipient and the residual to `refund`. A call argument inside
|
|
52
|
+
* the leg (the payee of an invoice the leg pays through `core.call`) is not
|
|
53
|
+
* that recipient and may be a literal.
|
|
54
|
+
*
|
|
55
|
+
* In a `core.call` / `core.staticCall` bind, `kind` must equal the parameter's
|
|
56
|
+
* Solidity type exactly, and `value` must encode as that type: a decimal or
|
|
57
|
+
* `0x` integer, `'true'` / `'false'`, a `0x` address (mixed case only with a
|
|
58
|
+
* valid checksum), or a `0x` hex byte string of the right length.
|
|
52
59
|
*
|
|
53
60
|
* @typeParam T - The Solidity type of the literal (e.g. `'address'`).
|
|
54
61
|
* @param kind - The literal's Solidity type.
|
|
55
62
|
* @param value - The literal value, as the wire format carries it: a string.
|
|
56
|
-
* @returns A {@link TypedLiteral} accepted by `Bindable<T>` slots matching `T
|
|
63
|
+
* @returns A {@link TypedLiteral} accepted by `Bindable<T>` slots matching `T`
|
|
64
|
+
* and by `core.call` / `core.staticCall` parameters of type `T`.
|
|
57
65
|
*
|
|
58
66
|
* @example
|
|
59
67
|
* ```ts
|
package/dist/authoring/raw.js
CHANGED
|
@@ -46,12 +46,20 @@ const ref = (path) => ({ $ref: path });
|
|
|
46
46
|
* (`continuationFlow`). The leg produces its outcome into its own proxy
|
|
47
47
|
* (`leg.context.executionAddress`) and names no recipient; the composer
|
|
48
48
|
* appends a settlement epilogue at commit that forwards the outcome to the
|
|
49
|
-
* provider's recipient and the residual to `refund`.
|
|
49
|
+
* provider's recipient and the residual to `refund`. A call argument inside
|
|
50
|
+
* the leg (the payee of an invoice the leg pays through `core.call`) is not
|
|
51
|
+
* that recipient and may be a literal.
|
|
52
|
+
*
|
|
53
|
+
* In a `core.call` / `core.staticCall` bind, `kind` must equal the parameter's
|
|
54
|
+
* Solidity type exactly, and `value` must encode as that type: a decimal or
|
|
55
|
+
* `0x` integer, `'true'` / `'false'`, a `0x` address (mixed case only with a
|
|
56
|
+
* valid checksum), or a `0x` hex byte string of the right length.
|
|
50
57
|
*
|
|
51
58
|
* @typeParam T - The Solidity type of the literal (e.g. `'address'`).
|
|
52
59
|
* @param kind - The literal's Solidity type.
|
|
53
60
|
* @param value - The literal value, as the wire format carries it: a string.
|
|
54
|
-
* @returns A {@link TypedLiteral} accepted by `Bindable<T>` slots matching `T
|
|
61
|
+
* @returns A {@link TypedLiteral} accepted by `Bindable<T>` slots matching `T`
|
|
62
|
+
* and by `core.call` / `core.staticCall` parameters of type `T`.
|
|
55
63
|
*
|
|
56
64
|
* @example
|
|
57
65
|
* ```ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raw.js","names":[],"sources":["../../src/authoring/raw.ts"],"sourcesContent":["import type { AppliedGuard, SolType } from '@lifi/compose-spec';\n\nimport type { OutputKind, TypedLiteral, TypedRef } from '../types.js';\n\n/**\n * Creates a typed `$ref` pointer for use in bind slots.\n *\n * This is an **escape hatch** for referencing values that the typed builder\n * API doesn't cover — for example, outputs of an `untypedOp` node or custom\n * context paths. The caller is responsible for choosing the correct type\n * parameter; no runtime validation occurs.\n *\n * Prefer typed handles (`OutputHandle`, `InputHandle`) and `builder.context`\n * whenever possible. Use `ref` only when you need to construct a `$ref` path\n * manually and want it accepted by a `Bindable<T>` slot.\n *\n * @typeParam T - The output kind this ref represents (e.g. `'address'`, `'uint256'`, `'resource'`).\n * @param path - The `$ref` path (e.g. `\"context.sender\"`, `\"myNode.result\"`).\n * @returns A {@link TypedRef} accepted by `Bindable<T>` slots matching `T`.\n *\n * @example\n * ```ts\n * import { raw } from '@lifi/composer-sdk';\n *\n * // Reference an untypedOp output in a typed operation:\n * builder.untypedOp('custom', 'some.op', {\n * bind: { x: { $ref: 'input.token' } },\n * config: {},\n * });\n * builder.core.add('sum', {\n * bind: {\n * a: raw.ref<'uint256'>('custom.result'),\n * b: someTypedHandle,\n * },\n * });\n * ```\n */\nexport const ref = <T extends OutputKind>(path: string): TypedRef<T> =>\n // The brand is phantom, so the runtime value is the bare wire ref. This is\n // the only place a `TypedRef` is minted; the cast is what the brand buys.\n ({ $ref: path }) as TypedRef<T>;\n\n/**\n * Creates a typed literal for use in bind slots: a constant baked into the\n * flow document rather than supplied at run time.\n *\n * Prefer a declared flow input and `builder.inputs.<name>` — a value the\n * caller supplies per run stays out of the document. Use a literal for a\n * constant that belongs to the document itself, such as a fixed treasury\n * address.\n *\n * Never use a literal for the payee of a `continuation.settle` leg\n * (`continuationFlow`). The leg produces its outcome into its own proxy\n * (`leg.context.executionAddress`) and names no recipient; the composer\n * appends a settlement epilogue at commit that forwards the outcome to the\n * provider's recipient and the residual to `refund
|
|
1
|
+
{"version":3,"file":"raw.js","names":[],"sources":["../../src/authoring/raw.ts"],"sourcesContent":["import type { AppliedGuard, SolType } from '@lifi/compose-spec';\n\nimport type { OutputKind, TypedLiteral, TypedRef } from '../types.js';\n\n/**\n * Creates a typed `$ref` pointer for use in bind slots.\n *\n * This is an **escape hatch** for referencing values that the typed builder\n * API doesn't cover — for example, outputs of an `untypedOp` node or custom\n * context paths. The caller is responsible for choosing the correct type\n * parameter; no runtime validation occurs.\n *\n * Prefer typed handles (`OutputHandle`, `InputHandle`) and `builder.context`\n * whenever possible. Use `ref` only when you need to construct a `$ref` path\n * manually and want it accepted by a `Bindable<T>` slot.\n *\n * @typeParam T - The output kind this ref represents (e.g. `'address'`, `'uint256'`, `'resource'`).\n * @param path - The `$ref` path (e.g. `\"context.sender\"`, `\"myNode.result\"`).\n * @returns A {@link TypedRef} accepted by `Bindable<T>` slots matching `T`.\n *\n * @example\n * ```ts\n * import { raw } from '@lifi/composer-sdk';\n *\n * // Reference an untypedOp output in a typed operation:\n * builder.untypedOp('custom', 'some.op', {\n * bind: { x: { $ref: 'input.token' } },\n * config: {},\n * });\n * builder.core.add('sum', {\n * bind: {\n * a: raw.ref<'uint256'>('custom.result'),\n * b: someTypedHandle,\n * },\n * });\n * ```\n */\nexport const ref = <T extends OutputKind>(path: string): TypedRef<T> =>\n // The brand is phantom, so the runtime value is the bare wire ref. This is\n // the only place a `TypedRef` is minted; the cast is what the brand buys.\n ({ $ref: path }) as TypedRef<T>;\n\n/**\n * Creates a typed literal for use in bind slots: a constant baked into the\n * flow document rather than supplied at run time.\n *\n * Prefer a declared flow input and `builder.inputs.<name>` — a value the\n * caller supplies per run stays out of the document. Use a literal for a\n * constant that belongs to the document itself, such as a fixed treasury\n * address.\n *\n * Never use a literal for the payee of a `continuation.settle` leg\n * (`continuationFlow`). The leg produces its outcome into its own proxy\n * (`leg.context.executionAddress`) and names no recipient; the composer\n * appends a settlement epilogue at commit that forwards the outcome to the\n * provider's recipient and the residual to `refund`. A call argument inside\n * the leg (the payee of an invoice the leg pays through `core.call`) is not\n * that recipient and may be a literal.\n *\n * In a `core.call` / `core.staticCall` bind, `kind` must equal the parameter's\n * Solidity type exactly, and `value` must encode as that type: a decimal or\n * `0x` integer, `'true'` / `'false'`, a `0x` address (mixed case only with a\n * valid checksum), or a `0x` hex byte string of the right length.\n *\n * @typeParam T - The Solidity type of the literal (e.g. `'address'`).\n * @param kind - The literal's Solidity type.\n * @param value - The literal value, as the wire format carries it: a string.\n * @returns A {@link TypedLiteral} accepted by `Bindable<T>` slots matching `T`\n * and by `core.call` / `core.staticCall` parameters of type `T`.\n *\n * @example\n * ```ts\n * import { raw } from '@lifi/composer-sdk';\n *\n * // A fixed fee to a treasury baked into the flow document.\n * builder.core.transfer('fee', {\n * bind: {\n * amount: builder.inputs.fee,\n * recipient: raw.literal('address', '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'),\n * },\n * config: {},\n * });\n * ```\n */\nexport const literal = <T extends SolType>(\n kind: T,\n value: string,\n): TypedLiteral<T> => ({ kind, value });\n\n/**\n * Creates a raw guard object for use in the `guards` array of an operation call.\n *\n * @param kind - The guard type (e.g. `\"slippage\"`).\n * @param config - Guard-specific configuration (e.g. `{ toleranceBps: 300 }`).\n * @returns An {@link AppliedGuard} object.\n */\nexport const rawGuard = (\n kind: string,\n config: Record<string, unknown> = {},\n): AppliedGuard => {\n if ('kind' in config) {\n throw new Error(\n `rawGuard: 'kind' must not appear in config (got \"${String(\n config.kind,\n )}\"). Pass it as the first argument instead.`,\n );\n }\n return { ...config, kind };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,MAAa,OAA6B,UAGvC,EAAE,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4ChB,MAAa,WACX,MACA,WACqB;CAAE;CAAM;AAAM;;;;;;;;AASrC,MAAa,YACX,MACA,SAAkC,CAAC,MAClB;CACjB,IAAI,UAAU,QACZ,MAAM,IAAI,MACR,oDAAoD,OAClD,OAAO,IACT,EAAE,2CACJ;CAEF,OAAO;EAAE,GAAG;EAAQ;CAAK;AAC3B"}
|
|
@@ -28,8 +28,15 @@ const toBindRef = (bindable) => {
|
|
|
28
28
|
return bindable;
|
|
29
29
|
};
|
|
30
30
|
/**
|
|
31
|
+
* Converts one signature-derived bind to its positional `config.args` entry: a
|
|
32
|
+
* ref-resolving bindable becomes `{ $ref }`; a literal becomes its `value`
|
|
33
|
+
* verbatim, which the backend encodes against the parameter's ABI type (a
|
|
34
|
+
* decimal or hex integer, a hex address or byte string, `'true'`/`'false'`).
|
|
35
|
+
*/
|
|
36
|
+
const toPositionalArg = (bindable) => "kind" in bindable ? bindable.value : toBindRef(bindable);
|
|
37
|
+
/**
|
|
31
38
|
* Parses a function signature from `config`, validates bind keys against it,
|
|
32
|
-
* and converts named binds to positional
|
|
39
|
+
* and converts named binds to positional args.
|
|
33
40
|
*/
|
|
34
41
|
const resolvePositionalArgs = (label, bind, config) => {
|
|
35
42
|
const functionSignature = config.functionSignature;
|
|
@@ -44,7 +51,7 @@ const resolvePositionalArgs = (label, bind, config) => {
|
|
|
44
51
|
return paramNames.map((name) => {
|
|
45
52
|
const bindable = bind[name];
|
|
46
53
|
if (bindable === void 0) throw new Error(`${label}: bind value for parameter "${name}" is undefined`);
|
|
47
|
-
return
|
|
54
|
+
return toPositionalArg(bindable);
|
|
48
55
|
});
|
|
49
56
|
};
|
|
50
57
|
/**
|
|
@@ -52,7 +59,7 @@ const resolvePositionalArgs = (label, bind, config) => {
|
|
|
52
59
|
* format that the backend expects:
|
|
53
60
|
* - With resource: `core.call` with `bind: { input: <resourceRef> }`
|
|
54
61
|
* - Without resource: `core.invoke` with `bind: {}`
|
|
55
|
-
* - `config: { ...userConfig, args: [positional refs...] }`
|
|
62
|
+
* - `config: { ...userConfig, args: [positional refs and literal values...] }`
|
|
56
63
|
*/
|
|
57
64
|
const buildCallWireFormat = (args) => {
|
|
58
65
|
const positionalArgs = resolvePositionalArgs("core.call", args.bind, args.config);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signatureArgs.cjs","names":["parseAbiItem","handleToRef"],"sources":["../../src/authoring/signatureArgs.ts"],"sourcesContent":["import type { Ref } from '@lifi/compose-spec';\nimport { type ParseAbiItem, parseAbiItem } from 'abitype';\n\nimport type { AbiTypeToOutputKind, TypedGuard } from '../types.js';\n\nimport type { CallArgs } from './FlowBuilderCore.js';\nimport type { AnyRefBindable, OutputHandle, RefBindable } from './handles.js';\nimport { handleToRef } from './handles.js';\n\n/**\n * Type-level extraction of named bind keys from a function signature string.\n * When `TSig` is a string literal matching a Solidity function signature,\n * resolves to a record whose keys are the parameter names and values are\n * `RefBindable<kind>` where the kind is derived from each parameter's Solidity\n * type via `AbiTypeToOutputKind`. For recognised `SolType` parameters\n * (e.g. `uint256`, `address`, `uint128`) the bind slot is precisely typed;\n * for other Solidity types (e.g. tuples) the slot accepts any scalar handle.\n * Falls back to `Record<string, AnyRefBindable>` for non-literal strings.\n *\n * These slots are lowered into `config.args`, which is positional calldata\n * rather than a node `bind` record, so a literal is not accepted here: only\n * values that resolve to a `$ref`.\n */\nexport type SignatureBind<TSig extends string> = string extends TSig\n ? Record<string, AnyRefBindable>\n : ParseAbiItem<TSig> extends {\n type: 'function';\n inputs: infer I extends readonly { name: string; type: string }[];\n }\n ? {\n readonly [P in I[number] as P['name']]: RefBindable<\n AbiTypeToOutputKind<P['type']>\n >;\n }\n : Record<string, AnyRefBindable>;\n\n// ---------------------------------------------------------------------------\n// Return-type inference from function signatures\n// ---------------------------------------------------------------------------\n\n/**\n * Describes the output type(s) of a parsed function signature as a\n * human-readable string for inclusion in type-level error messages.\n */\ntype DescribeOutputs<O extends readonly { type: string }[]> =\n O extends readonly [{ type: infer T extends string }] ? T : 'multiple values';\n\n/**\n * A string-literal type that surfaces a clear error when the user provides a\n * function signature whose return type is not supported by core.call.\n * The message is visible in IDE tooltips and compiler diagnostics.\n */\ntype UnsupportedReturnTypeError<TLabel extends string, TSig extends string> =\n ParseAbiItem<TSig> extends {\n type: 'function';\n outputs: infer O extends readonly { type: string }[];\n }\n ? `[TypeError] ${TLabel}: return type '${DescribeOutputs<O>}' is not supported — only 'uint256' or void signatures are allowed`\n : `[TypeError] ${TLabel}: unable to parse return type from signature`;\n\n/**\n * Conditional output type for `core.call` based on the function signature's\n * return type:\n *\n * - `returns (uint256)` → `{ result: OutputHandle }`\n * - No returns clause → `{ result: undefined }`\n * - Anything else → `{ result: \"[TypeError] ...\" }` (compile-time error)\n *\n * When `TSig` is a non-literal `string` (e.g. a variable, not a string\n * constant), the type falls back to `{ result: OutputHandle | undefined }`\n * so that both void and uint256 call sites remain assignable.\n */\nexport type CoreCallResult<TSig extends string> = string extends TSig\n ? { readonly result: OutputHandle<'uint256'> | undefined }\n : ParseAbiItem<TSig> extends { type: 'function'; outputs: readonly [] }\n ? { readonly result: undefined }\n : ParseAbiItem<TSig> extends {\n type: 'function';\n outputs: readonly [{ type: 'uint256' }];\n }\n ? { readonly result: OutputHandle<'uint256'> }\n : { readonly result: UnsupportedReturnTypeError<'core.call', TSig> };\n\n/**\n * Conditional output type for `core.staticCall`. staticCall always reads a\n * value, so void signatures are also rejected:\n *\n * - `returns (uint256)` → `{ result: OutputHandle }`\n * - No returns / other → `{ result: \"[TypeError] ...\" }` (compile-time error)\n */\nexport type StaticCallResult<TSig extends string> = string extends TSig\n ? { readonly result: OutputHandle<'uint256'> }\n : ParseAbiItem<TSig> extends {\n type: 'function';\n outputs: readonly [{ type: 'uint256' }];\n }\n ? { readonly result: OutputHandle<'uint256'> }\n : ParseAbiItem<TSig> extends { type: 'function'; outputs: readonly [] }\n ? {\n readonly result: `[TypeError] core.staticCall: function has no return value — staticCall requires a 'returns (uint256)' signature`;\n }\n : {\n readonly result: UnsupportedReturnTypeError<'core.staticCall', TSig>;\n };\n\n/**\n * Parses a Solidity function signature and returns parameter names in order.\n * Delegates to abitype's runtime `parseAbiItem` — the same parser that powers\n * the compile-time `ParseAbiItem<TSig>` type — so runtime and type-level\n * parsing can never diverge.\n *\n * @throws if the signature is not a valid function signature or a parameter is unnamed\n */\nexport const parseFunctionParams = (functionSignature: string): string[] => {\n const parsed = parseAbiItem(functionSignature);\n if (parsed.type !== 'function') {\n throw new Error(\n `core.call: expected a function signature, got \"${parsed.type}\": \"${functionSignature}\"`,\n );\n }\n\n return parsed.inputs.map((input, index) => {\n if (!input.name) {\n throw new Error(\n `core.call: parameter at index ${index} in signature has no name. All parameters must be named for named binds to work.`,\n );\n }\n return input.name;\n });\n};\n\n/**\n * Converts a ref-resolving bindable to a `Ref` (`{ $ref: string }`).\n * Handles carry a `_tag` property and are converted via `handleToRef`;\n * `Ref` objects pass through as-is.\n */\nexport const toBindRef = (bindable: AnyRefBindable): Ref => {\n if ('_tag' in bindable) return handleToRef(bindable);\n return bindable;\n};\n\nexport interface BuildCallWireFormatInput {\n readonly resource?: AnyRefBindable;\n readonly bind: Record<string, AnyRefBindable>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly TypedGuard[];\n}\n\nexport interface CallWireResult {\n readonly op: 'core.call' | 'core.invoke';\n readonly bind: Record<string, Ref>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly TypedGuard[];\n}\n\n/**\n * Parses a function signature from `config`, validates bind keys against it,\n * and converts named binds to positional `$ref` args.\n */\nconst resolvePositionalArgs = (\n label: string,\n bind: Record<string, AnyRefBindable>,\n config: Record<string, unknown>,\n): Ref[] => {\n const functionSignature = config.functionSignature;\n if (typeof functionSignature !== 'string') {\n throw new Error(\n `${label}: config.functionSignature is required and must be a string`,\n );\n }\n\n const paramNames = parseFunctionParams(functionSignature);\n const paramSet = new Set(paramNames);\n const bindKeys = Object.keys(bind);\n const bindSet = new Set(bindKeys);\n\n const missing = paramNames.filter((n) => !bindSet.has(n));\n const extra = bindKeys.filter((k) => !paramSet.has(k));\n\n if (missing.length > 0 || extra.length > 0) {\n throw new Error(\n `${label}: bind keys [${bindKeys.join(\n ', ',\n )}] do not match signature parameters [${paramNames.join(\n ', ',\n )}]. Missing: ${missing.join(', ') || '(none)'}. Extra: ${\n extra.join(', ') || '(none)'\n }.`,\n );\n }\n\n return paramNames.map((name) => {\n const bindable = bind[name];\n if (bindable === undefined) {\n throw new Error(\n `${label}: bind value for parameter \"${name}\" is undefined`,\n );\n }\n return toBindRef(bindable);\n });\n};\n\n/**\n * Transforms the user-facing `resource` + named `bind` API into the wire\n * format that the backend expects:\n * - With resource: `core.call` with `bind: { input: <resourceRef> }`\n * - Without resource: `core.invoke` with `bind: {}`\n * - `config: { ...userConfig, args: [positional refs...] }`\n */\nexport const buildCallWireFormat = (\n args: BuildCallWireFormatInput,\n): CallWireResult => {\n const positionalArgs = resolvePositionalArgs(\n 'core.call',\n args.bind,\n args.config,\n );\n const hasResource = args.resource !== undefined;\n\n return {\n op: hasResource ? 'core.call' : 'core.invoke',\n bind: hasResource ? { input: toBindRef(args.resource) } : {},\n config: { ...args.config, args: positionalArgs },\n ...(args.guards && args.guards.length > 0 && { guards: args.guards }),\n };\n};\n\nexport interface BuildStaticCallWireFormatInput {\n readonly bind: Record<string, AnyRefBindable>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly TypedGuard[];\n}\n\n/**\n * Transforms the user-facing named `bind` API into the wire format that the\n * backend expects for `core.staticCall`. Same as `buildCallWireFormat` but\n * with no `resource` field — staticCall has no resource inputs.\n */\nexport const buildStaticCallWireFormat = (\n args: BuildStaticCallWireFormatInput,\n): CallArgs => {\n const positionalArgs = resolvePositionalArgs(\n 'core.staticCall',\n args.bind,\n args.config,\n );\n\n return {\n bind: {},\n config: { ...args.config, args: positionalArgs },\n ...(args.guards && args.guards.length > 0 && { guards: args.guards }),\n };\n};\n"],"mappings":";;;;;;;;;;;;AAiHA,MAAa,uBAAuB,sBAAwC;CAC1E,MAAM,UAAA,GAASA,QAAAA,aAAAA,CAAa,iBAAiB;CAC7C,IAAI,OAAO,SAAS,YAClB,MAAM,IAAI,MACR,kDAAkD,OAAO,KAAK,MAAM,kBAAkB,EACxF;CAGF,OAAO,OAAO,OAAO,KAAK,OAAO,UAAU;EACzC,IAAI,CAAC,MAAM,MACT,MAAM,IAAI,MACR,iCAAiC,MAAM,iFACzC;EAEF,OAAO,MAAM;CACf,CAAC;AACH;;;;;;AAOA,MAAa,aAAa,aAAkC;CAC1D,IAAI,UAAU,UAAU,OAAOC,0BAAAA,YAAY,QAAQ;CACnD,OAAO;AACT;;;;;AAoBA,MAAM,yBACJ,OACA,MACA,WACU;CACV,MAAM,oBAAoB,OAAO;CACjC,IAAI,OAAO,sBAAsB,UAC/B,MAAM,IAAI,MACR,GAAG,MAAM,4DACX;CAGF,MAAM,aAAa,oBAAoB,iBAAiB;CACxD,MAAM,WAAW,IAAI,IAAI,UAAU;CACnC,MAAM,WAAW,OAAO,KAAK,IAAI;CACjC,MAAM,UAAU,IAAI,IAAI,QAAQ;CAEhC,MAAM,UAAU,WAAW,QAAQ,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;CACxD,MAAM,QAAQ,SAAS,QAAQ,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;CAErD,IAAI,QAAQ,SAAS,KAAK,MAAM,SAAS,GACvC,MAAM,IAAI,MACR,GAAG,MAAM,eAAe,SAAS,KAC/B,IACF,EAAE,uCAAuC,WAAW,KAClD,IACF,EAAE,cAAc,QAAQ,KAAK,IAAI,KAAK,SAAS,WAC7C,MAAM,KAAK,IAAI,KAAK,SACrB,EACH;CAGF,OAAO,WAAW,KAAK,SAAS;EAC9B,MAAM,WAAW,KAAK;EACtB,IAAI,aAAa,KAAA,GACf,MAAM,IAAI,MACR,GAAG,MAAM,8BAA8B,KAAK,eAC9C;EAEF,OAAO,UAAU,QAAQ;CAC3B,CAAC;AACH;;;;;;;;AASA,MAAa,uBACX,SACmB;CACnB,MAAM,iBAAiB,sBACrB,aACA,KAAK,MACL,KAAK,MACP;CACA,MAAM,cAAc,KAAK,aAAa,KAAA;CAEtC,OAAO;EACL,IAAI,cAAc,cAAc;EAChC,MAAM,cAAc,EAAE,OAAO,UAAU,KAAK,QAAQ,EAAE,IAAI,CAAC;EAC3D,QAAQ;GAAE,GAAG,KAAK;GAAQ,MAAM;EAAe;EAC/C,GAAI,KAAK,UAAU,KAAK,OAAO,SAAS,KAAK,EAAE,QAAQ,KAAK,OAAO;CACrE;AACF;;;;;;AAaA,MAAa,6BACX,SACa;CACb,MAAM,iBAAiB,sBACrB,mBACA,KAAK,MACL,KAAK,MACP;CAEA,OAAO;EACL,MAAM,CAAC;EACP,QAAQ;GAAE,GAAG,KAAK;GAAQ,MAAM;EAAe;EAC/C,GAAI,KAAK,UAAU,KAAK,OAAO,SAAS,KAAK,EAAE,QAAQ,KAAK,OAAO;CACrE;AACF"}
|
|
1
|
+
{"version":3,"file":"signatureArgs.cjs","names":["parseAbiItem","handleToRef"],"sources":["../../src/authoring/signatureArgs.ts"],"sourcesContent":["import type { Ref, SolType } from '@lifi/compose-spec';\nimport { type ParseAbiItem, parseAbiItem } from 'abitype';\n\nimport type {\n AbiTypeToOutputKind,\n TypedGuard,\n TypedLiteral,\n} from '../types.js';\n\nimport type { CallArgs } from './FlowBuilderCore.js';\nimport type { AnyRefBindable, OutputHandle, RefBindable } from './handles.js';\nimport { handleToRef } from './handles.js';\n\n/**\n * Any value a signature-derived bind slot accepts, with no per-slot type\n * constraint: a ref-resolving bindable or a typed literal.\n */\ntype AnySignatureBindable = AnyRefBindable | TypedLiteral;\n\n// The literal arm of a signature-derived slot. A positional arg is encoded by\n// its parameter's ABI type, not by the literal's `kind`, so the kind must equal\n// that type exactly: the `bytes32` widening `Bindable<T>` applies would admit an\n// `address` literal the encoder then rejects. A parameter whose ABI type is no\n// `SolType` (a tuple, an array, `uint24`) has no literal kind to name, so its\n// slot stays ref-only.\ntype SignatureLiteral<TAbiType extends string> = TAbiType extends SolType\n ? TypedLiteral<TAbiType>\n : never;\n\n/**\n * Type-level extraction of named bind keys from a function signature string.\n * When `TSig` is a string literal matching a Solidity function signature,\n * resolves to a record whose keys are the parameter names and whose values are\n * `RefBindable<kind>`, where the kind is derived from each parameter's Solidity\n * type via `AbiTypeToOutputKind`, or a `TypedLiteral` (`raw.literal`) of that\n * exact Solidity type. For recognised `SolType` parameters (e.g. `uint256`,\n * `address`, `bytes`) the slot is precisely typed; other Solidity types (e.g.\n * tuples) accept any scalar handle and no literal.\n * Falls back to `Record<string, AnySignatureBindable>` for non-literal strings.\n *\n * These slots are lowered into `config.args`, positional calldata: a ref\n * becomes `{ $ref }` and a literal becomes its `value` string, which the\n * backend encodes against the parameter's type.\n */\nexport type SignatureBind<TSig extends string> = string extends TSig\n ? Record<string, AnySignatureBindable>\n : ParseAbiItem<TSig> extends {\n type: 'function';\n inputs: infer I extends readonly { name: string; type: string }[];\n }\n ? {\n readonly [P in I[number] as P['name']]:\n | RefBindable<AbiTypeToOutputKind<P['type']>>\n | SignatureLiteral<P['type']>;\n }\n : Record<string, AnySignatureBindable>;\n\n// ---------------------------------------------------------------------------\n// Return-type inference from function signatures\n// ---------------------------------------------------------------------------\n\n/**\n * Describes the output type(s) of a parsed function signature as a\n * human-readable string for inclusion in type-level error messages.\n */\ntype DescribeOutputs<O extends readonly { type: string }[]> =\n O extends readonly [{ type: infer T extends string }] ? T : 'multiple values';\n\n/**\n * A string-literal type that surfaces a clear error when the user provides a\n * function signature whose return type is not supported by core.call.\n * The message is visible in IDE tooltips and compiler diagnostics.\n */\ntype UnsupportedReturnTypeError<TLabel extends string, TSig extends string> =\n ParseAbiItem<TSig> extends {\n type: 'function';\n outputs: infer O extends readonly { type: string }[];\n }\n ? `[TypeError] ${TLabel}: return type '${DescribeOutputs<O>}' is not supported — only 'uint256' or void signatures are allowed`\n : `[TypeError] ${TLabel}: unable to parse return type from signature`;\n\n/**\n * Conditional output type for `core.call` based on the function signature's\n * return type:\n *\n * - `returns (uint256)` → `{ result: OutputHandle }`\n * - No returns clause → `{ result: undefined }`\n * - Anything else → `{ result: \"[TypeError] ...\" }` (compile-time error)\n *\n * When `TSig` is a non-literal `string` (e.g. a variable, not a string\n * constant), the type falls back to `{ result: OutputHandle | undefined }`\n * so that both void and uint256 call sites remain assignable.\n */\nexport type CoreCallResult<TSig extends string> = string extends TSig\n ? { readonly result: OutputHandle<'uint256'> | undefined }\n : ParseAbiItem<TSig> extends { type: 'function'; outputs: readonly [] }\n ? { readonly result: undefined }\n : ParseAbiItem<TSig> extends {\n type: 'function';\n outputs: readonly [{ type: 'uint256' }];\n }\n ? { readonly result: OutputHandle<'uint256'> }\n : { readonly result: UnsupportedReturnTypeError<'core.call', TSig> };\n\n/**\n * Conditional output type for `core.staticCall`. staticCall always reads a\n * value, so void signatures are also rejected:\n *\n * - `returns (uint256)` → `{ result: OutputHandle }`\n * - No returns / other → `{ result: \"[TypeError] ...\" }` (compile-time error)\n */\nexport type StaticCallResult<TSig extends string> = string extends TSig\n ? { readonly result: OutputHandle<'uint256'> }\n : ParseAbiItem<TSig> extends {\n type: 'function';\n outputs: readonly [{ type: 'uint256' }];\n }\n ? { readonly result: OutputHandle<'uint256'> }\n : ParseAbiItem<TSig> extends { type: 'function'; outputs: readonly [] }\n ? {\n readonly result: `[TypeError] core.staticCall: function has no return value — staticCall requires a 'returns (uint256)' signature`;\n }\n : {\n readonly result: UnsupportedReturnTypeError<'core.staticCall', TSig>;\n };\n\n/**\n * Parses a Solidity function signature and returns parameter names in order.\n * Delegates to abitype's runtime `parseAbiItem` — the same parser that powers\n * the compile-time `ParseAbiItem<TSig>` type — so runtime and type-level\n * parsing can never diverge.\n *\n * @throws if the signature is not a valid function signature or a parameter is unnamed\n */\nexport const parseFunctionParams = (functionSignature: string): string[] => {\n const parsed = parseAbiItem(functionSignature);\n if (parsed.type !== 'function') {\n throw new Error(\n `core.call: expected a function signature, got \"${parsed.type}\": \"${functionSignature}\"`,\n );\n }\n\n return parsed.inputs.map((input, index) => {\n if (!input.name) {\n throw new Error(\n `core.call: parameter at index ${index} in signature has no name. All parameters must be named for named binds to work.`,\n );\n }\n return input.name;\n });\n};\n\n/**\n * Converts a ref-resolving bindable to a `Ref` (`{ $ref: string }`).\n * Handles carry a `_tag` property and are converted via `handleToRef`;\n * `Ref` objects pass through as-is.\n */\nexport const toBindRef = (bindable: AnyRefBindable): Ref => {\n if ('_tag' in bindable) return handleToRef(bindable);\n return bindable;\n};\n\n/**\n * Converts one signature-derived bind to its positional `config.args` entry: a\n * ref-resolving bindable becomes `{ $ref }`; a literal becomes its `value`\n * verbatim, which the backend encodes against the parameter's ABI type (a\n * decimal or hex integer, a hex address or byte string, `'true'`/`'false'`).\n */\nconst toPositionalArg = (bindable: AnySignatureBindable): Ref | string =>\n 'kind' in bindable ? bindable.value : toBindRef(bindable);\n\nexport interface BuildCallWireFormatInput {\n readonly resource?: AnyRefBindable;\n readonly bind: Record<string, AnySignatureBindable>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly TypedGuard[];\n}\n\nexport interface CallWireResult {\n readonly op: 'core.call' | 'core.invoke';\n readonly bind: Record<string, Ref>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly TypedGuard[];\n}\n\n/**\n * Parses a function signature from `config`, validates bind keys against it,\n * and converts named binds to positional args.\n */\nconst resolvePositionalArgs = (\n label: string,\n bind: Record<string, AnySignatureBindable>,\n config: Record<string, unknown>,\n): (Ref | string)[] => {\n const functionSignature = config.functionSignature;\n if (typeof functionSignature !== 'string') {\n throw new Error(\n `${label}: config.functionSignature is required and must be a string`,\n );\n }\n\n const paramNames = parseFunctionParams(functionSignature);\n const paramSet = new Set(paramNames);\n const bindKeys = Object.keys(bind);\n const bindSet = new Set(bindKeys);\n\n const missing = paramNames.filter((n) => !bindSet.has(n));\n const extra = bindKeys.filter((k) => !paramSet.has(k));\n\n if (missing.length > 0 || extra.length > 0) {\n throw new Error(\n `${label}: bind keys [${bindKeys.join(\n ', ',\n )}] do not match signature parameters [${paramNames.join(\n ', ',\n )}]. Missing: ${missing.join(', ') || '(none)'}. Extra: ${\n extra.join(', ') || '(none)'\n }.`,\n );\n }\n\n return paramNames.map((name) => {\n const bindable = bind[name];\n if (bindable === undefined) {\n throw new Error(\n `${label}: bind value for parameter \"${name}\" is undefined`,\n );\n }\n return toPositionalArg(bindable);\n });\n};\n\n/**\n * Transforms the user-facing `resource` + named `bind` API into the wire\n * format that the backend expects:\n * - With resource: `core.call` with `bind: { input: <resourceRef> }`\n * - Without resource: `core.invoke` with `bind: {}`\n * - `config: { ...userConfig, args: [positional refs and literal values...] }`\n */\nexport const buildCallWireFormat = (\n args: BuildCallWireFormatInput,\n): CallWireResult => {\n const positionalArgs = resolvePositionalArgs(\n 'core.call',\n args.bind,\n args.config,\n );\n const hasResource = args.resource !== undefined;\n\n return {\n op: hasResource ? 'core.call' : 'core.invoke',\n bind: hasResource ? { input: toBindRef(args.resource) } : {},\n config: { ...args.config, args: positionalArgs },\n ...(args.guards && args.guards.length > 0 && { guards: args.guards }),\n };\n};\n\nexport interface BuildStaticCallWireFormatInput {\n readonly bind: Record<string, AnySignatureBindable>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly TypedGuard[];\n}\n\n/**\n * Transforms the user-facing named `bind` API into the wire format that the\n * backend expects for `core.staticCall`. Same as `buildCallWireFormat` but\n * with no `resource` field — staticCall has no resource inputs.\n */\nexport const buildStaticCallWireFormat = (\n args: BuildStaticCallWireFormatInput,\n): CallArgs => {\n const positionalArgs = resolvePositionalArgs(\n 'core.staticCall',\n args.bind,\n args.config,\n );\n\n return {\n bind: {},\n config: { ...args.config, args: positionalArgs },\n ...(args.guards && args.guards.length > 0 && { guards: args.guards }),\n };\n};\n"],"mappings":";;;;;;;;;;;;AAsIA,MAAa,uBAAuB,sBAAwC;CAC1E,MAAM,UAAA,GAASA,QAAAA,aAAAA,CAAa,iBAAiB;CAC7C,IAAI,OAAO,SAAS,YAClB,MAAM,IAAI,MACR,kDAAkD,OAAO,KAAK,MAAM,kBAAkB,EACxF;CAGF,OAAO,OAAO,OAAO,KAAK,OAAO,UAAU;EACzC,IAAI,CAAC,MAAM,MACT,MAAM,IAAI,MACR,iCAAiC,MAAM,iFACzC;EAEF,OAAO,MAAM;CACf,CAAC;AACH;;;;;;AAOA,MAAa,aAAa,aAAkC;CAC1D,IAAI,UAAU,UAAU,OAAOC,0BAAAA,YAAY,QAAQ;CACnD,OAAO;AACT;;;;;;;AAQA,MAAM,mBAAmB,aACvB,UAAU,WAAW,SAAS,QAAQ,UAAU,QAAQ;;;;;AAoB1D,MAAM,yBACJ,OACA,MACA,WACqB;CACrB,MAAM,oBAAoB,OAAO;CACjC,IAAI,OAAO,sBAAsB,UAC/B,MAAM,IAAI,MACR,GAAG,MAAM,4DACX;CAGF,MAAM,aAAa,oBAAoB,iBAAiB;CACxD,MAAM,WAAW,IAAI,IAAI,UAAU;CACnC,MAAM,WAAW,OAAO,KAAK,IAAI;CACjC,MAAM,UAAU,IAAI,IAAI,QAAQ;CAEhC,MAAM,UAAU,WAAW,QAAQ,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;CACxD,MAAM,QAAQ,SAAS,QAAQ,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;CAErD,IAAI,QAAQ,SAAS,KAAK,MAAM,SAAS,GACvC,MAAM,IAAI,MACR,GAAG,MAAM,eAAe,SAAS,KAC/B,IACF,EAAE,uCAAuC,WAAW,KAClD,IACF,EAAE,cAAc,QAAQ,KAAK,IAAI,KAAK,SAAS,WAC7C,MAAM,KAAK,IAAI,KAAK,SACrB,EACH;CAGF,OAAO,WAAW,KAAK,SAAS;EAC9B,MAAM,WAAW,KAAK;EACtB,IAAI,aAAa,KAAA,GACf,MAAM,IAAI,MACR,GAAG,MAAM,8BAA8B,KAAK,eAC9C;EAEF,OAAO,gBAAgB,QAAQ;CACjC,CAAC;AACH;;;;;;;;AASA,MAAa,uBACX,SACmB;CACnB,MAAM,iBAAiB,sBACrB,aACA,KAAK,MACL,KAAK,MACP;CACA,MAAM,cAAc,KAAK,aAAa,KAAA;CAEtC,OAAO;EACL,IAAI,cAAc,cAAc;EAChC,MAAM,cAAc,EAAE,OAAO,UAAU,KAAK,QAAQ,EAAE,IAAI,CAAC;EAC3D,QAAQ;GAAE,GAAG,KAAK;GAAQ,MAAM;EAAe;EAC/C,GAAI,KAAK,UAAU,KAAK,OAAO,SAAS,KAAK,EAAE,QAAQ,KAAK,OAAO;CACrE;AACF;;;;;;AAaA,MAAa,6BACX,SACa;CACb,MAAM,iBAAiB,sBACrB,mBACA,KAAK,MACL,KAAK,MACP;CAEA,OAAO;EACL,MAAM,CAAC;EACP,QAAQ;GAAE,GAAG,KAAK;GAAQ,MAAM;EAAe;EAC/C,GAAI,KAAK,UAAU,KAAK,OAAO,SAAS,KAAK,EAAE,QAAQ,KAAK,OAAO;CACrE;AACF"}
|
|
@@ -1,30 +1,37 @@
|
|
|
1
|
-
import { AbiTypeToOutputKind, TypedGuard } from "../types.cjs";
|
|
1
|
+
import { AbiTypeToOutputKind, TypedGuard, TypedLiteral } from "../types.cjs";
|
|
2
2
|
import { AnyRefBindable, OutputHandle, RefBindable } from "./handles.cjs";
|
|
3
3
|
import { CallArgs } from "./FlowBuilderCore.cjs";
|
|
4
|
-
import { Ref } from "@lifi/compose-spec";
|
|
4
|
+
import { Ref, SolType } from "@lifi/compose-spec";
|
|
5
5
|
import { ParseAbiItem } from "abitype";
|
|
6
6
|
//#region src/authoring/signatureArgs.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Any value a signature-derived bind slot accepts, with no per-slot type
|
|
9
|
+
* constraint: a ref-resolving bindable or a typed literal.
|
|
10
|
+
*/
|
|
11
|
+
type AnySignatureBindable = AnyRefBindable | TypedLiteral;
|
|
12
|
+
type SignatureLiteral<TAbiType extends string> = TAbiType extends SolType ? TypedLiteral<TAbiType> : never;
|
|
7
13
|
/**
|
|
8
14
|
* Type-level extraction of named bind keys from a function signature string.
|
|
9
15
|
* When `TSig` is a string literal matching a Solidity function signature,
|
|
10
|
-
* resolves to a record whose keys are the parameter names and values are
|
|
11
|
-
* `RefBindable<kind
|
|
12
|
-
* type via `AbiTypeToOutputKind
|
|
13
|
-
* (e.g. `uint256`,
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
+
* resolves to a record whose keys are the parameter names and whose values are
|
|
17
|
+
* `RefBindable<kind>`, where the kind is derived from each parameter's Solidity
|
|
18
|
+
* type via `AbiTypeToOutputKind`, or a `TypedLiteral` (`raw.literal`) of that
|
|
19
|
+
* exact Solidity type. For recognised `SolType` parameters (e.g. `uint256`,
|
|
20
|
+
* `address`, `bytes`) the slot is precisely typed; other Solidity types (e.g.
|
|
21
|
+
* tuples) accept any scalar handle and no literal.
|
|
22
|
+
* Falls back to `Record<string, AnySignatureBindable>` for non-literal strings.
|
|
16
23
|
*
|
|
17
|
-
* These slots are lowered into `config.args`,
|
|
18
|
-
*
|
|
19
|
-
*
|
|
24
|
+
* These slots are lowered into `config.args`, positional calldata: a ref
|
|
25
|
+
* becomes `{ $ref }` and a literal becomes its `value` string, which the
|
|
26
|
+
* backend encodes against the parameter's type.
|
|
20
27
|
*/
|
|
21
|
-
export type SignatureBind<TSig extends string> = string extends TSig ? Record<string,
|
|
28
|
+
export type SignatureBind<TSig extends string> = string extends TSig ? Record<string, AnySignatureBindable> : ParseAbiItem<TSig> extends {
|
|
22
29
|
type: "function";
|
|
23
30
|
inputs: infer I extends readonly {
|
|
24
31
|
name: string;
|
|
25
32
|
type: string;
|
|
26
33
|
}[];
|
|
27
|
-
} ? { readonly [P in I[number] as P["name"]]: RefBindable<AbiTypeToOutputKind<P["type"]
|
|
34
|
+
} ? { readonly [P in I[number] as P["name"]]: RefBindable<AbiTypeToOutputKind<P["type"]>> | SignatureLiteral<P["type"]>; } : Record<string, AnySignatureBindable>;
|
|
28
35
|
/**
|
|
29
36
|
* Describes the output type(s) of a parsed function signature as a
|
|
30
37
|
* human-readable string for inclusion in type-level error messages.
|
|
@@ -115,7 +122,7 @@ export declare const parseFunctionParams: (functionSignature: string) => string[
|
|
|
115
122
|
export declare const toBindRef: (bindable: AnyRefBindable) => Ref;
|
|
116
123
|
export interface BuildCallWireFormatInput {
|
|
117
124
|
readonly resource?: AnyRefBindable;
|
|
118
|
-
readonly bind: Record<string,
|
|
125
|
+
readonly bind: Record<string, AnySignatureBindable>;
|
|
119
126
|
readonly config: Record<string, unknown>;
|
|
120
127
|
readonly guards?: readonly TypedGuard[];
|
|
121
128
|
}
|
|
@@ -130,11 +137,11 @@ export interface CallWireResult {
|
|
|
130
137
|
* format that the backend expects:
|
|
131
138
|
* - With resource: `core.call` with `bind: { input: <resourceRef> }`
|
|
132
139
|
* - Without resource: `core.invoke` with `bind: {}`
|
|
133
|
-
* - `config: { ...userConfig, args: [positional refs...] }`
|
|
140
|
+
* - `config: { ...userConfig, args: [positional refs and literal values...] }`
|
|
134
141
|
*/
|
|
135
142
|
export declare const buildCallWireFormat: (args: BuildCallWireFormatInput) => CallWireResult;
|
|
136
143
|
export interface BuildStaticCallWireFormatInput {
|
|
137
|
-
readonly bind: Record<string,
|
|
144
|
+
readonly bind: Record<string, AnySignatureBindable>;
|
|
138
145
|
readonly config: Record<string, unknown>;
|
|
139
146
|
readonly guards?: readonly TypedGuard[];
|
|
140
147
|
}
|
|
@@ -1,30 +1,37 @@
|
|
|
1
|
-
import { AbiTypeToOutputKind, TypedGuard } from "../types.js";
|
|
1
|
+
import { AbiTypeToOutputKind, TypedGuard, TypedLiteral } from "../types.js";
|
|
2
2
|
import { AnyRefBindable, OutputHandle, RefBindable } from "./handles.js";
|
|
3
3
|
import { CallArgs } from "./FlowBuilderCore.js";
|
|
4
|
-
import { Ref } from "@lifi/compose-spec";
|
|
4
|
+
import { Ref, SolType } from "@lifi/compose-spec";
|
|
5
5
|
import { ParseAbiItem } from "abitype";
|
|
6
6
|
//#region src/authoring/signatureArgs.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Any value a signature-derived bind slot accepts, with no per-slot type
|
|
9
|
+
* constraint: a ref-resolving bindable or a typed literal.
|
|
10
|
+
*/
|
|
11
|
+
type AnySignatureBindable = AnyRefBindable | TypedLiteral;
|
|
12
|
+
type SignatureLiteral<TAbiType extends string> = TAbiType extends SolType ? TypedLiteral<TAbiType> : never;
|
|
7
13
|
/**
|
|
8
14
|
* Type-level extraction of named bind keys from a function signature string.
|
|
9
15
|
* When `TSig` is a string literal matching a Solidity function signature,
|
|
10
|
-
* resolves to a record whose keys are the parameter names and values are
|
|
11
|
-
* `RefBindable<kind
|
|
12
|
-
* type via `AbiTypeToOutputKind
|
|
13
|
-
* (e.g. `uint256`,
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
+
* resolves to a record whose keys are the parameter names and whose values are
|
|
17
|
+
* `RefBindable<kind>`, where the kind is derived from each parameter's Solidity
|
|
18
|
+
* type via `AbiTypeToOutputKind`, or a `TypedLiteral` (`raw.literal`) of that
|
|
19
|
+
* exact Solidity type. For recognised `SolType` parameters (e.g. `uint256`,
|
|
20
|
+
* `address`, `bytes`) the slot is precisely typed; other Solidity types (e.g.
|
|
21
|
+
* tuples) accept any scalar handle and no literal.
|
|
22
|
+
* Falls back to `Record<string, AnySignatureBindable>` for non-literal strings.
|
|
16
23
|
*
|
|
17
|
-
* These slots are lowered into `config.args`,
|
|
18
|
-
*
|
|
19
|
-
*
|
|
24
|
+
* These slots are lowered into `config.args`, positional calldata: a ref
|
|
25
|
+
* becomes `{ $ref }` and a literal becomes its `value` string, which the
|
|
26
|
+
* backend encodes against the parameter's type.
|
|
20
27
|
*/
|
|
21
|
-
export type SignatureBind<TSig extends string> = string extends TSig ? Record<string,
|
|
28
|
+
export type SignatureBind<TSig extends string> = string extends TSig ? Record<string, AnySignatureBindable> : ParseAbiItem<TSig> extends {
|
|
22
29
|
type: "function";
|
|
23
30
|
inputs: infer I extends readonly {
|
|
24
31
|
name: string;
|
|
25
32
|
type: string;
|
|
26
33
|
}[];
|
|
27
|
-
} ? { readonly [P in I[number] as P["name"]]: RefBindable<AbiTypeToOutputKind<P["type"]
|
|
34
|
+
} ? { readonly [P in I[number] as P["name"]]: RefBindable<AbiTypeToOutputKind<P["type"]>> | SignatureLiteral<P["type"]>; } : Record<string, AnySignatureBindable>;
|
|
28
35
|
/**
|
|
29
36
|
* Describes the output type(s) of a parsed function signature as a
|
|
30
37
|
* human-readable string for inclusion in type-level error messages.
|
|
@@ -115,7 +122,7 @@ export declare const parseFunctionParams: (functionSignature: string) => string[
|
|
|
115
122
|
export declare const toBindRef: (bindable: AnyRefBindable) => Ref;
|
|
116
123
|
export interface BuildCallWireFormatInput {
|
|
117
124
|
readonly resource?: AnyRefBindable;
|
|
118
|
-
readonly bind: Record<string,
|
|
125
|
+
readonly bind: Record<string, AnySignatureBindable>;
|
|
119
126
|
readonly config: Record<string, unknown>;
|
|
120
127
|
readonly guards?: readonly TypedGuard[];
|
|
121
128
|
}
|
|
@@ -130,11 +137,11 @@ export interface CallWireResult {
|
|
|
130
137
|
* format that the backend expects:
|
|
131
138
|
* - With resource: `core.call` with `bind: { input: <resourceRef> }`
|
|
132
139
|
* - Without resource: `core.invoke` with `bind: {}`
|
|
133
|
-
* - `config: { ...userConfig, args: [positional refs...] }`
|
|
140
|
+
* - `config: { ...userConfig, args: [positional refs and literal values...] }`
|
|
134
141
|
*/
|
|
135
142
|
export declare const buildCallWireFormat: (args: BuildCallWireFormatInput) => CallWireResult;
|
|
136
143
|
export interface BuildStaticCallWireFormatInput {
|
|
137
|
-
readonly bind: Record<string,
|
|
144
|
+
readonly bind: Record<string, AnySignatureBindable>;
|
|
138
145
|
readonly config: Record<string, unknown>;
|
|
139
146
|
readonly guards?: readonly TypedGuard[];
|
|
140
147
|
}
|
|
@@ -27,8 +27,15 @@ const toBindRef = (bindable) => {
|
|
|
27
27
|
return bindable;
|
|
28
28
|
};
|
|
29
29
|
/**
|
|
30
|
+
* Converts one signature-derived bind to its positional `config.args` entry: a
|
|
31
|
+
* ref-resolving bindable becomes `{ $ref }`; a literal becomes its `value`
|
|
32
|
+
* verbatim, which the backend encodes against the parameter's ABI type (a
|
|
33
|
+
* decimal or hex integer, a hex address or byte string, `'true'`/`'false'`).
|
|
34
|
+
*/
|
|
35
|
+
const toPositionalArg = (bindable) => "kind" in bindable ? bindable.value : toBindRef(bindable);
|
|
36
|
+
/**
|
|
30
37
|
* Parses a function signature from `config`, validates bind keys against it,
|
|
31
|
-
* and converts named binds to positional
|
|
38
|
+
* and converts named binds to positional args.
|
|
32
39
|
*/
|
|
33
40
|
const resolvePositionalArgs = (label, bind, config) => {
|
|
34
41
|
const functionSignature = config.functionSignature;
|
|
@@ -43,7 +50,7 @@ const resolvePositionalArgs = (label, bind, config) => {
|
|
|
43
50
|
return paramNames.map((name) => {
|
|
44
51
|
const bindable = bind[name];
|
|
45
52
|
if (bindable === void 0) throw new Error(`${label}: bind value for parameter "${name}" is undefined`);
|
|
46
|
-
return
|
|
53
|
+
return toPositionalArg(bindable);
|
|
47
54
|
});
|
|
48
55
|
};
|
|
49
56
|
/**
|
|
@@ -51,7 +58,7 @@ const resolvePositionalArgs = (label, bind, config) => {
|
|
|
51
58
|
* format that the backend expects:
|
|
52
59
|
* - With resource: `core.call` with `bind: { input: <resourceRef> }`
|
|
53
60
|
* - Without resource: `core.invoke` with `bind: {}`
|
|
54
|
-
* - `config: { ...userConfig, args: [positional refs...] }`
|
|
61
|
+
* - `config: { ...userConfig, args: [positional refs and literal values...] }`
|
|
55
62
|
*/
|
|
56
63
|
const buildCallWireFormat = (args) => {
|
|
57
64
|
const positionalArgs = resolvePositionalArgs("core.call", args.bind, args.config);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signatureArgs.js","names":[],"sources":["../../src/authoring/signatureArgs.ts"],"sourcesContent":["import type { Ref } from '@lifi/compose-spec';\nimport { type ParseAbiItem, parseAbiItem } from 'abitype';\n\nimport type { AbiTypeToOutputKind, TypedGuard } from '../types.js';\n\nimport type { CallArgs } from './FlowBuilderCore.js';\nimport type { AnyRefBindable, OutputHandle, RefBindable } from './handles.js';\nimport { handleToRef } from './handles.js';\n\n/**\n * Type-level extraction of named bind keys from a function signature string.\n * When `TSig` is a string literal matching a Solidity function signature,\n * resolves to a record whose keys are the parameter names and values are\n * `RefBindable<kind>` where the kind is derived from each parameter's Solidity\n * type via `AbiTypeToOutputKind`. For recognised `SolType` parameters\n * (e.g. `uint256`, `address`, `uint128`) the bind slot is precisely typed;\n * for other Solidity types (e.g. tuples) the slot accepts any scalar handle.\n * Falls back to `Record<string, AnyRefBindable>` for non-literal strings.\n *\n * These slots are lowered into `config.args`, which is positional calldata\n * rather than a node `bind` record, so a literal is not accepted here: only\n * values that resolve to a `$ref`.\n */\nexport type SignatureBind<TSig extends string> = string extends TSig\n ? Record<string, AnyRefBindable>\n : ParseAbiItem<TSig> extends {\n type: 'function';\n inputs: infer I extends readonly { name: string; type: string }[];\n }\n ? {\n readonly [P in I[number] as P['name']]: RefBindable<\n AbiTypeToOutputKind<P['type']>\n >;\n }\n : Record<string, AnyRefBindable>;\n\n// ---------------------------------------------------------------------------\n// Return-type inference from function signatures\n// ---------------------------------------------------------------------------\n\n/**\n * Describes the output type(s) of a parsed function signature as a\n * human-readable string for inclusion in type-level error messages.\n */\ntype DescribeOutputs<O extends readonly { type: string }[]> =\n O extends readonly [{ type: infer T extends string }] ? T : 'multiple values';\n\n/**\n * A string-literal type that surfaces a clear error when the user provides a\n * function signature whose return type is not supported by core.call.\n * The message is visible in IDE tooltips and compiler diagnostics.\n */\ntype UnsupportedReturnTypeError<TLabel extends string, TSig extends string> =\n ParseAbiItem<TSig> extends {\n type: 'function';\n outputs: infer O extends readonly { type: string }[];\n }\n ? `[TypeError] ${TLabel}: return type '${DescribeOutputs<O>}' is not supported — only 'uint256' or void signatures are allowed`\n : `[TypeError] ${TLabel}: unable to parse return type from signature`;\n\n/**\n * Conditional output type for `core.call` based on the function signature's\n * return type:\n *\n * - `returns (uint256)` → `{ result: OutputHandle }`\n * - No returns clause → `{ result: undefined }`\n * - Anything else → `{ result: \"[TypeError] ...\" }` (compile-time error)\n *\n * When `TSig` is a non-literal `string` (e.g. a variable, not a string\n * constant), the type falls back to `{ result: OutputHandle | undefined }`\n * so that both void and uint256 call sites remain assignable.\n */\nexport type CoreCallResult<TSig extends string> = string extends TSig\n ? { readonly result: OutputHandle<'uint256'> | undefined }\n : ParseAbiItem<TSig> extends { type: 'function'; outputs: readonly [] }\n ? { readonly result: undefined }\n : ParseAbiItem<TSig> extends {\n type: 'function';\n outputs: readonly [{ type: 'uint256' }];\n }\n ? { readonly result: OutputHandle<'uint256'> }\n : { readonly result: UnsupportedReturnTypeError<'core.call', TSig> };\n\n/**\n * Conditional output type for `core.staticCall`. staticCall always reads a\n * value, so void signatures are also rejected:\n *\n * - `returns (uint256)` → `{ result: OutputHandle }`\n * - No returns / other → `{ result: \"[TypeError] ...\" }` (compile-time error)\n */\nexport type StaticCallResult<TSig extends string> = string extends TSig\n ? { readonly result: OutputHandle<'uint256'> }\n : ParseAbiItem<TSig> extends {\n type: 'function';\n outputs: readonly [{ type: 'uint256' }];\n }\n ? { readonly result: OutputHandle<'uint256'> }\n : ParseAbiItem<TSig> extends { type: 'function'; outputs: readonly [] }\n ? {\n readonly result: `[TypeError] core.staticCall: function has no return value — staticCall requires a 'returns (uint256)' signature`;\n }\n : {\n readonly result: UnsupportedReturnTypeError<'core.staticCall', TSig>;\n };\n\n/**\n * Parses a Solidity function signature and returns parameter names in order.\n * Delegates to abitype's runtime `parseAbiItem` — the same parser that powers\n * the compile-time `ParseAbiItem<TSig>` type — so runtime and type-level\n * parsing can never diverge.\n *\n * @throws if the signature is not a valid function signature or a parameter is unnamed\n */\nexport const parseFunctionParams = (functionSignature: string): string[] => {\n const parsed = parseAbiItem(functionSignature);\n if (parsed.type !== 'function') {\n throw new Error(\n `core.call: expected a function signature, got \"${parsed.type}\": \"${functionSignature}\"`,\n );\n }\n\n return parsed.inputs.map((input, index) => {\n if (!input.name) {\n throw new Error(\n `core.call: parameter at index ${index} in signature has no name. All parameters must be named for named binds to work.`,\n );\n }\n return input.name;\n });\n};\n\n/**\n * Converts a ref-resolving bindable to a `Ref` (`{ $ref: string }`).\n * Handles carry a `_tag` property and are converted via `handleToRef`;\n * `Ref` objects pass through as-is.\n */\nexport const toBindRef = (bindable: AnyRefBindable): Ref => {\n if ('_tag' in bindable) return handleToRef(bindable);\n return bindable;\n};\n\nexport interface BuildCallWireFormatInput {\n readonly resource?: AnyRefBindable;\n readonly bind: Record<string, AnyRefBindable>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly TypedGuard[];\n}\n\nexport interface CallWireResult {\n readonly op: 'core.call' | 'core.invoke';\n readonly bind: Record<string, Ref>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly TypedGuard[];\n}\n\n/**\n * Parses a function signature from `config`, validates bind keys against it,\n * and converts named binds to positional `$ref` args.\n */\nconst resolvePositionalArgs = (\n label: string,\n bind: Record<string, AnyRefBindable>,\n config: Record<string, unknown>,\n): Ref[] => {\n const functionSignature = config.functionSignature;\n if (typeof functionSignature !== 'string') {\n throw new Error(\n `${label}: config.functionSignature is required and must be a string`,\n );\n }\n\n const paramNames = parseFunctionParams(functionSignature);\n const paramSet = new Set(paramNames);\n const bindKeys = Object.keys(bind);\n const bindSet = new Set(bindKeys);\n\n const missing = paramNames.filter((n) => !bindSet.has(n));\n const extra = bindKeys.filter((k) => !paramSet.has(k));\n\n if (missing.length > 0 || extra.length > 0) {\n throw new Error(\n `${label}: bind keys [${bindKeys.join(\n ', ',\n )}] do not match signature parameters [${paramNames.join(\n ', ',\n )}]. Missing: ${missing.join(', ') || '(none)'}. Extra: ${\n extra.join(', ') || '(none)'\n }.`,\n );\n }\n\n return paramNames.map((name) => {\n const bindable = bind[name];\n if (bindable === undefined) {\n throw new Error(\n `${label}: bind value for parameter \"${name}\" is undefined`,\n );\n }\n return toBindRef(bindable);\n });\n};\n\n/**\n * Transforms the user-facing `resource` + named `bind` API into the wire\n * format that the backend expects:\n * - With resource: `core.call` with `bind: { input: <resourceRef> }`\n * - Without resource: `core.invoke` with `bind: {}`\n * - `config: { ...userConfig, args: [positional refs...] }`\n */\nexport const buildCallWireFormat = (\n args: BuildCallWireFormatInput,\n): CallWireResult => {\n const positionalArgs = resolvePositionalArgs(\n 'core.call',\n args.bind,\n args.config,\n );\n const hasResource = args.resource !== undefined;\n\n return {\n op: hasResource ? 'core.call' : 'core.invoke',\n bind: hasResource ? { input: toBindRef(args.resource) } : {},\n config: { ...args.config, args: positionalArgs },\n ...(args.guards && args.guards.length > 0 && { guards: args.guards }),\n };\n};\n\nexport interface BuildStaticCallWireFormatInput {\n readonly bind: Record<string, AnyRefBindable>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly TypedGuard[];\n}\n\n/**\n * Transforms the user-facing named `bind` API into the wire format that the\n * backend expects for `core.staticCall`. Same as `buildCallWireFormat` but\n * with no `resource` field — staticCall has no resource inputs.\n */\nexport const buildStaticCallWireFormat = (\n args: BuildStaticCallWireFormatInput,\n): CallArgs => {\n const positionalArgs = resolvePositionalArgs(\n 'core.staticCall',\n args.bind,\n args.config,\n );\n\n return {\n bind: {},\n config: { ...args.config, args: positionalArgs },\n ...(args.guards && args.guards.length > 0 && { guards: args.guards }),\n };\n};\n"],"mappings":";;;;;;;;;;;AAiHA,MAAa,uBAAuB,sBAAwC;CAC1E,MAAM,SAAS,aAAa,iBAAiB;CAC7C,IAAI,OAAO,SAAS,YAClB,MAAM,IAAI,MACR,kDAAkD,OAAO,KAAK,MAAM,kBAAkB,EACxF;CAGF,OAAO,OAAO,OAAO,KAAK,OAAO,UAAU;EACzC,IAAI,CAAC,MAAM,MACT,MAAM,IAAI,MACR,iCAAiC,MAAM,iFACzC;EAEF,OAAO,MAAM;CACf,CAAC;AACH;;;;;;AAOA,MAAa,aAAa,aAAkC;CAC1D,IAAI,UAAU,UAAU,OAAO,YAAY,QAAQ;CACnD,OAAO;AACT;;;;;AAoBA,MAAM,yBACJ,OACA,MACA,WACU;CACV,MAAM,oBAAoB,OAAO;CACjC,IAAI,OAAO,sBAAsB,UAC/B,MAAM,IAAI,MACR,GAAG,MAAM,4DACX;CAGF,MAAM,aAAa,oBAAoB,iBAAiB;CACxD,MAAM,WAAW,IAAI,IAAI,UAAU;CACnC,MAAM,WAAW,OAAO,KAAK,IAAI;CACjC,MAAM,UAAU,IAAI,IAAI,QAAQ;CAEhC,MAAM,UAAU,WAAW,QAAQ,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;CACxD,MAAM,QAAQ,SAAS,QAAQ,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;CAErD,IAAI,QAAQ,SAAS,KAAK,MAAM,SAAS,GACvC,MAAM,IAAI,MACR,GAAG,MAAM,eAAe,SAAS,KAC/B,IACF,EAAE,uCAAuC,WAAW,KAClD,IACF,EAAE,cAAc,QAAQ,KAAK,IAAI,KAAK,SAAS,WAC7C,MAAM,KAAK,IAAI,KAAK,SACrB,EACH;CAGF,OAAO,WAAW,KAAK,SAAS;EAC9B,MAAM,WAAW,KAAK;EACtB,IAAI,aAAa,KAAA,GACf,MAAM,IAAI,MACR,GAAG,MAAM,8BAA8B,KAAK,eAC9C;EAEF,OAAO,UAAU,QAAQ;CAC3B,CAAC;AACH;;;;;;;;AASA,MAAa,uBACX,SACmB;CACnB,MAAM,iBAAiB,sBACrB,aACA,KAAK,MACL,KAAK,MACP;CACA,MAAM,cAAc,KAAK,aAAa,KAAA;CAEtC,OAAO;EACL,IAAI,cAAc,cAAc;EAChC,MAAM,cAAc,EAAE,OAAO,UAAU,KAAK,QAAQ,EAAE,IAAI,CAAC;EAC3D,QAAQ;GAAE,GAAG,KAAK;GAAQ,MAAM;EAAe;EAC/C,GAAI,KAAK,UAAU,KAAK,OAAO,SAAS,KAAK,EAAE,QAAQ,KAAK,OAAO;CACrE;AACF;;;;;;AAaA,MAAa,6BACX,SACa;CACb,MAAM,iBAAiB,sBACrB,mBACA,KAAK,MACL,KAAK,MACP;CAEA,OAAO;EACL,MAAM,CAAC;EACP,QAAQ;GAAE,GAAG,KAAK;GAAQ,MAAM;EAAe;EAC/C,GAAI,KAAK,UAAU,KAAK,OAAO,SAAS,KAAK,EAAE,QAAQ,KAAK,OAAO;CACrE;AACF"}
|
|
1
|
+
{"version":3,"file":"signatureArgs.js","names":[],"sources":["../../src/authoring/signatureArgs.ts"],"sourcesContent":["import type { Ref, SolType } from '@lifi/compose-spec';\nimport { type ParseAbiItem, parseAbiItem } from 'abitype';\n\nimport type {\n AbiTypeToOutputKind,\n TypedGuard,\n TypedLiteral,\n} from '../types.js';\n\nimport type { CallArgs } from './FlowBuilderCore.js';\nimport type { AnyRefBindable, OutputHandle, RefBindable } from './handles.js';\nimport { handleToRef } from './handles.js';\n\n/**\n * Any value a signature-derived bind slot accepts, with no per-slot type\n * constraint: a ref-resolving bindable or a typed literal.\n */\ntype AnySignatureBindable = AnyRefBindable | TypedLiteral;\n\n// The literal arm of a signature-derived slot. A positional arg is encoded by\n// its parameter's ABI type, not by the literal's `kind`, so the kind must equal\n// that type exactly: the `bytes32` widening `Bindable<T>` applies would admit an\n// `address` literal the encoder then rejects. A parameter whose ABI type is no\n// `SolType` (a tuple, an array, `uint24`) has no literal kind to name, so its\n// slot stays ref-only.\ntype SignatureLiteral<TAbiType extends string> = TAbiType extends SolType\n ? TypedLiteral<TAbiType>\n : never;\n\n/**\n * Type-level extraction of named bind keys from a function signature string.\n * When `TSig` is a string literal matching a Solidity function signature,\n * resolves to a record whose keys are the parameter names and whose values are\n * `RefBindable<kind>`, where the kind is derived from each parameter's Solidity\n * type via `AbiTypeToOutputKind`, or a `TypedLiteral` (`raw.literal`) of that\n * exact Solidity type. For recognised `SolType` parameters (e.g. `uint256`,\n * `address`, `bytes`) the slot is precisely typed; other Solidity types (e.g.\n * tuples) accept any scalar handle and no literal.\n * Falls back to `Record<string, AnySignatureBindable>` for non-literal strings.\n *\n * These slots are lowered into `config.args`, positional calldata: a ref\n * becomes `{ $ref }` and a literal becomes its `value` string, which the\n * backend encodes against the parameter's type.\n */\nexport type SignatureBind<TSig extends string> = string extends TSig\n ? Record<string, AnySignatureBindable>\n : ParseAbiItem<TSig> extends {\n type: 'function';\n inputs: infer I extends readonly { name: string; type: string }[];\n }\n ? {\n readonly [P in I[number] as P['name']]:\n | RefBindable<AbiTypeToOutputKind<P['type']>>\n | SignatureLiteral<P['type']>;\n }\n : Record<string, AnySignatureBindable>;\n\n// ---------------------------------------------------------------------------\n// Return-type inference from function signatures\n// ---------------------------------------------------------------------------\n\n/**\n * Describes the output type(s) of a parsed function signature as a\n * human-readable string for inclusion in type-level error messages.\n */\ntype DescribeOutputs<O extends readonly { type: string }[]> =\n O extends readonly [{ type: infer T extends string }] ? T : 'multiple values';\n\n/**\n * A string-literal type that surfaces a clear error when the user provides a\n * function signature whose return type is not supported by core.call.\n * The message is visible in IDE tooltips and compiler diagnostics.\n */\ntype UnsupportedReturnTypeError<TLabel extends string, TSig extends string> =\n ParseAbiItem<TSig> extends {\n type: 'function';\n outputs: infer O extends readonly { type: string }[];\n }\n ? `[TypeError] ${TLabel}: return type '${DescribeOutputs<O>}' is not supported — only 'uint256' or void signatures are allowed`\n : `[TypeError] ${TLabel}: unable to parse return type from signature`;\n\n/**\n * Conditional output type for `core.call` based on the function signature's\n * return type:\n *\n * - `returns (uint256)` → `{ result: OutputHandle }`\n * - No returns clause → `{ result: undefined }`\n * - Anything else → `{ result: \"[TypeError] ...\" }` (compile-time error)\n *\n * When `TSig` is a non-literal `string` (e.g. a variable, not a string\n * constant), the type falls back to `{ result: OutputHandle | undefined }`\n * so that both void and uint256 call sites remain assignable.\n */\nexport type CoreCallResult<TSig extends string> = string extends TSig\n ? { readonly result: OutputHandle<'uint256'> | undefined }\n : ParseAbiItem<TSig> extends { type: 'function'; outputs: readonly [] }\n ? { readonly result: undefined }\n : ParseAbiItem<TSig> extends {\n type: 'function';\n outputs: readonly [{ type: 'uint256' }];\n }\n ? { readonly result: OutputHandle<'uint256'> }\n : { readonly result: UnsupportedReturnTypeError<'core.call', TSig> };\n\n/**\n * Conditional output type for `core.staticCall`. staticCall always reads a\n * value, so void signatures are also rejected:\n *\n * - `returns (uint256)` → `{ result: OutputHandle }`\n * - No returns / other → `{ result: \"[TypeError] ...\" }` (compile-time error)\n */\nexport type StaticCallResult<TSig extends string> = string extends TSig\n ? { readonly result: OutputHandle<'uint256'> }\n : ParseAbiItem<TSig> extends {\n type: 'function';\n outputs: readonly [{ type: 'uint256' }];\n }\n ? { readonly result: OutputHandle<'uint256'> }\n : ParseAbiItem<TSig> extends { type: 'function'; outputs: readonly [] }\n ? {\n readonly result: `[TypeError] core.staticCall: function has no return value — staticCall requires a 'returns (uint256)' signature`;\n }\n : {\n readonly result: UnsupportedReturnTypeError<'core.staticCall', TSig>;\n };\n\n/**\n * Parses a Solidity function signature and returns parameter names in order.\n * Delegates to abitype's runtime `parseAbiItem` — the same parser that powers\n * the compile-time `ParseAbiItem<TSig>` type — so runtime and type-level\n * parsing can never diverge.\n *\n * @throws if the signature is not a valid function signature or a parameter is unnamed\n */\nexport const parseFunctionParams = (functionSignature: string): string[] => {\n const parsed = parseAbiItem(functionSignature);\n if (parsed.type !== 'function') {\n throw new Error(\n `core.call: expected a function signature, got \"${parsed.type}\": \"${functionSignature}\"`,\n );\n }\n\n return parsed.inputs.map((input, index) => {\n if (!input.name) {\n throw new Error(\n `core.call: parameter at index ${index} in signature has no name. All parameters must be named for named binds to work.`,\n );\n }\n return input.name;\n });\n};\n\n/**\n * Converts a ref-resolving bindable to a `Ref` (`{ $ref: string }`).\n * Handles carry a `_tag` property and are converted via `handleToRef`;\n * `Ref` objects pass through as-is.\n */\nexport const toBindRef = (bindable: AnyRefBindable): Ref => {\n if ('_tag' in bindable) return handleToRef(bindable);\n return bindable;\n};\n\n/**\n * Converts one signature-derived bind to its positional `config.args` entry: a\n * ref-resolving bindable becomes `{ $ref }`; a literal becomes its `value`\n * verbatim, which the backend encodes against the parameter's ABI type (a\n * decimal or hex integer, a hex address or byte string, `'true'`/`'false'`).\n */\nconst toPositionalArg = (bindable: AnySignatureBindable): Ref | string =>\n 'kind' in bindable ? bindable.value : toBindRef(bindable);\n\nexport interface BuildCallWireFormatInput {\n readonly resource?: AnyRefBindable;\n readonly bind: Record<string, AnySignatureBindable>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly TypedGuard[];\n}\n\nexport interface CallWireResult {\n readonly op: 'core.call' | 'core.invoke';\n readonly bind: Record<string, Ref>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly TypedGuard[];\n}\n\n/**\n * Parses a function signature from `config`, validates bind keys against it,\n * and converts named binds to positional args.\n */\nconst resolvePositionalArgs = (\n label: string,\n bind: Record<string, AnySignatureBindable>,\n config: Record<string, unknown>,\n): (Ref | string)[] => {\n const functionSignature = config.functionSignature;\n if (typeof functionSignature !== 'string') {\n throw new Error(\n `${label}: config.functionSignature is required and must be a string`,\n );\n }\n\n const paramNames = parseFunctionParams(functionSignature);\n const paramSet = new Set(paramNames);\n const bindKeys = Object.keys(bind);\n const bindSet = new Set(bindKeys);\n\n const missing = paramNames.filter((n) => !bindSet.has(n));\n const extra = bindKeys.filter((k) => !paramSet.has(k));\n\n if (missing.length > 0 || extra.length > 0) {\n throw new Error(\n `${label}: bind keys [${bindKeys.join(\n ', ',\n )}] do not match signature parameters [${paramNames.join(\n ', ',\n )}]. Missing: ${missing.join(', ') || '(none)'}. Extra: ${\n extra.join(', ') || '(none)'\n }.`,\n );\n }\n\n return paramNames.map((name) => {\n const bindable = bind[name];\n if (bindable === undefined) {\n throw new Error(\n `${label}: bind value for parameter \"${name}\" is undefined`,\n );\n }\n return toPositionalArg(bindable);\n });\n};\n\n/**\n * Transforms the user-facing `resource` + named `bind` API into the wire\n * format that the backend expects:\n * - With resource: `core.call` with `bind: { input: <resourceRef> }`\n * - Without resource: `core.invoke` with `bind: {}`\n * - `config: { ...userConfig, args: [positional refs and literal values...] }`\n */\nexport const buildCallWireFormat = (\n args: BuildCallWireFormatInput,\n): CallWireResult => {\n const positionalArgs = resolvePositionalArgs(\n 'core.call',\n args.bind,\n args.config,\n );\n const hasResource = args.resource !== undefined;\n\n return {\n op: hasResource ? 'core.call' : 'core.invoke',\n bind: hasResource ? { input: toBindRef(args.resource) } : {},\n config: { ...args.config, args: positionalArgs },\n ...(args.guards && args.guards.length > 0 && { guards: args.guards }),\n };\n};\n\nexport interface BuildStaticCallWireFormatInput {\n readonly bind: Record<string, AnySignatureBindable>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly TypedGuard[];\n}\n\n/**\n * Transforms the user-facing named `bind` API into the wire format that the\n * backend expects for `core.staticCall`. Same as `buildCallWireFormat` but\n * with no `resource` field — staticCall has no resource inputs.\n */\nexport const buildStaticCallWireFormat = (\n args: BuildStaticCallWireFormatInput,\n): CallArgs => {\n const positionalArgs = resolvePositionalArgs(\n 'core.staticCall',\n args.bind,\n args.config,\n );\n\n return {\n bind: {},\n config: { ...args.config, args: positionalArgs },\n ...(args.guards && args.guards.length > 0 && { guards: args.guards }),\n };\n};\n"],"mappings":";;;;;;;;;;;AAsIA,MAAa,uBAAuB,sBAAwC;CAC1E,MAAM,SAAS,aAAa,iBAAiB;CAC7C,IAAI,OAAO,SAAS,YAClB,MAAM,IAAI,MACR,kDAAkD,OAAO,KAAK,MAAM,kBAAkB,EACxF;CAGF,OAAO,OAAO,OAAO,KAAK,OAAO,UAAU;EACzC,IAAI,CAAC,MAAM,MACT,MAAM,IAAI,MACR,iCAAiC,MAAM,iFACzC;EAEF,OAAO,MAAM;CACf,CAAC;AACH;;;;;;AAOA,MAAa,aAAa,aAAkC;CAC1D,IAAI,UAAU,UAAU,OAAO,YAAY,QAAQ;CACnD,OAAO;AACT;;;;;;;AAQA,MAAM,mBAAmB,aACvB,UAAU,WAAW,SAAS,QAAQ,UAAU,QAAQ;;;;;AAoB1D,MAAM,yBACJ,OACA,MACA,WACqB;CACrB,MAAM,oBAAoB,OAAO;CACjC,IAAI,OAAO,sBAAsB,UAC/B,MAAM,IAAI,MACR,GAAG,MAAM,4DACX;CAGF,MAAM,aAAa,oBAAoB,iBAAiB;CACxD,MAAM,WAAW,IAAI,IAAI,UAAU;CACnC,MAAM,WAAW,OAAO,KAAK,IAAI;CACjC,MAAM,UAAU,IAAI,IAAI,QAAQ;CAEhC,MAAM,UAAU,WAAW,QAAQ,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;CACxD,MAAM,QAAQ,SAAS,QAAQ,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;CAErD,IAAI,QAAQ,SAAS,KAAK,MAAM,SAAS,GACvC,MAAM,IAAI,MACR,GAAG,MAAM,eAAe,SAAS,KAC/B,IACF,EAAE,uCAAuC,WAAW,KAClD,IACF,EAAE,cAAc,QAAQ,KAAK,IAAI,KAAK,SAAS,WAC7C,MAAM,KAAK,IAAI,KAAK,SACrB,EACH;CAGF,OAAO,WAAW,KAAK,SAAS;EAC9B,MAAM,WAAW,KAAK;EACtB,IAAI,aAAa,KAAA,GACf,MAAM,IAAI,MACR,GAAG,MAAM,8BAA8B,KAAK,eAC9C;EAEF,OAAO,gBAAgB,QAAQ;CACjC,CAAC;AACH;;;;;;;;AASA,MAAa,uBACX,SACmB;CACnB,MAAM,iBAAiB,sBACrB,aACA,KAAK,MACL,KAAK,MACP;CACA,MAAM,cAAc,KAAK,aAAa,KAAA;CAEtC,OAAO;EACL,IAAI,cAAc,cAAc;EAChC,MAAM,cAAc,EAAE,OAAO,UAAU,KAAK,QAAQ,EAAE,IAAI,CAAC;EAC3D,QAAQ;GAAE,GAAG,KAAK;GAAQ,MAAM;EAAe;EAC/C,GAAI,KAAK,UAAU,KAAK,OAAO,SAAS,KAAK,EAAE,QAAQ,KAAK,OAAO;CACrE;AACF;;;;;;AAaA,MAAa,6BACX,SACa;CACb,MAAM,iBAAiB,sBACrB,mBACA,KAAK,MACL,KAAK,MACP;CAEA,OAAO;EACL,MAAM,CAAC;EACP,QAAQ;GAAE,GAAG,KAAK;GAAQ,MAAM;EAAe;EAC/C,GAAI,KAAK,UAAU,KAAK,OAAO,SAAS,KAAK,EAAE,QAAQ,KAAK,OAAO;CACrE;AACF"}
|
package/dist/client.cjs
CHANGED
|
@@ -3,7 +3,7 @@ const require_responseSchemas = require("./responseSchemas.cjs");
|
|
|
3
3
|
const require_errors = require("./errors.cjs");
|
|
4
4
|
let _lifi_compose_spec = require("@lifi/compose-spec");
|
|
5
5
|
//#region src/client.ts
|
|
6
|
-
const SDK_VERSION = "0.
|
|
6
|
+
const SDK_VERSION = "0.13.0";
|
|
7
7
|
const SDK_VERSION_TRIPLE = (0, _lifi_compose_spec.parseVersion)(SDK_VERSION);
|
|
8
8
|
/**
|
|
9
9
|
* `JSON.stringify` replacer that renders `bigint` amounts as decimal strings.
|
package/dist/client.js
CHANGED
|
@@ -2,7 +2,7 @@ import { parseCompilePartialEnvelope, parseSimulateResult } from "./responseSche
|
|
|
2
2
|
import { ComposeError, errorFromHttpResponse } from "./errors.js";
|
|
3
3
|
import { COMPOSER_SDK_VERSION_HEADER, COMPOSE_VERSION_HEADER, checkCompatibility, parseVersion } from "@lifi/compose-spec";
|
|
4
4
|
//#region src/client.ts
|
|
5
|
-
const SDK_VERSION = "0.
|
|
5
|
+
const SDK_VERSION = "0.13.0";
|
|
6
6
|
const SDK_VERSION_TRIPLE = parseVersion(SDK_VERSION);
|
|
7
7
|
/**
|
|
8
8
|
* `JSON.stringify` replacer that renders `bigint` amounts as decimal strings.
|
|
@@ -845,7 +845,7 @@ export interface ParaswapBuyConfig {
|
|
|
845
845
|
*/
|
|
846
846
|
partnerAddress?: string;
|
|
847
847
|
/**
|
|
848
|
-
*
|
|
848
|
+
* Paraswap partner fee in basis points; non-negative integer string capped at 9000.
|
|
849
849
|
*/
|
|
850
850
|
partnerFeeBps?: string;
|
|
851
851
|
}
|
|
@@ -885,21 +885,7 @@ export interface FlySwapConfig {
|
|
|
885
885
|
*/
|
|
886
886
|
export type Between86400000000000008640000000000000 = number;
|
|
887
887
|
export interface ContinuationSettleConfig {
|
|
888
|
-
|
|
889
|
-
* @minItems 1
|
|
890
|
-
*/
|
|
891
|
-
outcomes: [{
|
|
892
|
-
/**
|
|
893
|
-
* EVM address: 0x followed by 40 hex characters
|
|
894
|
-
*/
|
|
895
|
-
token: Address;
|
|
896
|
-
minAmount?: IntegerStringInput;
|
|
897
|
-
/**
|
|
898
|
-
* EVM address: 0x followed by 40 hex characters
|
|
899
|
-
*/
|
|
900
|
-
destination: Address;
|
|
901
|
-
chainId: Positive;
|
|
902
|
-
}, ...{
|
|
888
|
+
outcomes: {
|
|
903
889
|
/**
|
|
904
890
|
* EVM address: 0x followed by 40 hex characters
|
|
905
891
|
*/
|
|
@@ -910,18 +896,18 @@ export interface ContinuationSettleConfig {
|
|
|
910
896
|
*/
|
|
911
897
|
destination: Address;
|
|
912
898
|
chainId: Positive;
|
|
913
|
-
}[]
|
|
899
|
+
}[];
|
|
914
900
|
continuationFlow?: Flow;
|
|
915
901
|
validity: {
|
|
916
902
|
expiresAtMs: Between86400000000000008640000000000000;
|
|
917
903
|
};
|
|
918
|
-
perpetual?: boolean;
|
|
919
904
|
provider?: string;
|
|
920
905
|
funding?: "inline" | "external";
|
|
921
906
|
/**
|
|
922
907
|
* EVM address: 0x followed by 40 hex characters
|
|
923
908
|
*/
|
|
924
909
|
refund?: Address;
|
|
910
|
+
exact?: boolean;
|
|
925
911
|
}
|
|
926
912
|
export interface UniswapV2AddLiquidityConfig {
|
|
927
913
|
/**
|
|
@@ -1023,6 +1009,7 @@ export interface LifiIntentsOrderConfig {
|
|
|
1023
1009
|
slippage?: LessThan1;
|
|
1024
1010
|
validitySeconds?: Between1300;
|
|
1025
1011
|
exclusiveSeconds?: Between0120;
|
|
1012
|
+
exactAmountOut?: string;
|
|
1026
1013
|
}
|
|
1027
1014
|
export interface LifiIntentsRefundConfig {
|
|
1028
1015
|
/**
|
|
@@ -1074,6 +1061,7 @@ export type DirectDepositMaterialiserConfig = {
|
|
|
1074
1061
|
} | {
|
|
1075
1062
|
allowNonExact: true;
|
|
1076
1063
|
simAmount?: string;
|
|
1064
|
+
minAmount?: IntegerStringInput;
|
|
1077
1065
|
};
|
|
1078
1066
|
export interface CallMaterialiserConfig {
|
|
1079
1067
|
/**
|