Compiling reads no network, and the result is the same in Node and in a browser. In a browser, call
ready() once first.
routes.compileSauceProgram
Compiles a program for one chain.Import
Usage
compile-program.ts
function main(...), or a script whose top-level statements run as the entry. A script cannot return, so a program that returns a value declares main. The program reads the chain’s names with no import: token symbols (USDC), protocol namespaces (UniswapV3.Factory), chainId, and the @sauce/token functions. One source therefore compiles unchanged for every chain where its names exist.
Signature
Parameters
Returns
CompiledSauceProgram:
Throws
- An unknown chain:
Unknown chain 'not-a-chain' (known slugs: ethereum, optimism, …). - A use of a protocol name the chain lacks, outside a test of it:
compileSauceRoute: `Aerodrome.Router` is not deployed on ethereum. A contract the chain lacks is zero there, and only a test of it may use it: `if (Aerodrome.Router) { … }` compiles the branch only where the chain has it. It is deployed on base. - A compile error, with source locations. See Compile errors.
Bind arguments at compile time
options.args fixes main’s arguments in the bytecode. The result is a different program, specialised to those values, that takes no arguments at run time.
compile-bound.ts
entryParams is empty, and its entrySignature still lists both parameters. To compile once and pass values per cook, leave args out and encode the values with routes.encodeEntryArguments.
A bound argument binds main’s parameter and nothing else. With args: [5n], this program returned 30005 from a cook on a local fork of Base at block 52991146 with the current contracts: fee() read the module’s FEE, 30, and main read its bound parameter, 5:
Programs that import a library
compileSauceProgram resolves the @sauce/* libraries with no option: @sauce/router, the @sauce/token it imports and the pool ABIs it binds. This compiles the @sauce/router fallback swap, swap-fallback.sauce.ts, for two chains:
router-compile.mts
routes.compileSauceRoute and the actions package resolve the libraries the same way; the raw compile resolves them only through resolveSdkModule and resolveSdkPackage, under “The SDK’s modules” below.
routes.compileSauceRoute
Compiles a program and builds the one cook call that runs it on a Pot, in a single step.Import
Usage
compile-route.ts
source shows the SDK’s rewrite: pot.USDC became a balanceOf call on the chain’s USDC.
Signature
Parameters
On Solana,
execution names a staged code account, and the call it builds is not one the released Solana engine accepts. Build Solana cooks with the Kitchen client; see Solana.
Returns
CompiledSauceRoute:
calls: one call,{ to, target, data, value }.tois the Pot’s checksummed address,targetthe same Pot as a 32-byte, left-padded address, andvaluetheexecution.valueyou passed, as abigint.compiled.bytecode: aUint8Array[]holding one segment, the program.compiled.warnings: always an empty array. A failed compile throws.source: the source after the SDK’s rewrites.
How it differs from compileSauceProgram
- It takes no run-time arguments:
callscarries the bytecode with nothing appended. - Its result has no
entryParams,entryEncoding,isaRevisionor Solanamanifest. - It supplies no
chainId: a program that readschainIdfails to compile with`chainId` is not a declared variable. - It supplies no ambient
@sauce/tokenfunctions. Import them in the program, or passambient: ["@sauce/token"]:
compile-route-ambient.ts
compileSauceProgram when you need main’s parameters or a Solana manifest.
compile
The raw compiler. It resolves nothing: no chain names, no token syntax, no SDK modules unless your resolver serves them. Use it for full control over modules and compiler settings, for a closure entry, or for the reports of nested programs.Import
Usage
raw-compile.ts
resolve.
Signature
Parameters
Returns
CompileResult:
bytecode: the program, with no argument values in it.isaRevision: the instruction-set label,"stack-v3". It is a label, not a compatibility check: a program runs on the engine release paired with the compiler version the SDK pins, whichV12_RELEASE_SETSin/deploymentsrecords.entryEncoding: always"abi-v1".entryParams:main’s run-time parameters as an ABI parameter list, in the JSON shape viem and Solidity use. A top-level tuple of fixed size carriesindirect: true:mainreads it behind an offset word. Entry arguments shows how to encode for it. On Solana,Accountparameters are absent; the manifest lists them.entrySignature:main’s parameters in SauceScript’s own type names (Uint256,Int256,Address, records written out), each with itsabientry, andreturns, the declared return type. It keeps parameters bound throughargsand SolanaAccountparameters.programs: oneProgramReportper closure compiled as a program of its own withprogram(closure, ...args), inner programs first.manifest: on Solana, the accountsmaintakes, by index and role. Absent on EVM.chain: thechainoption echoed back, when one was given.
Account parameter:
raw-compile-svm.ts
Throws
A compile error, a resolve error or an invalid option. See Compile errors.Closure entries and bound arguments
WithentryKind: "closure", the entry is one arrow or function expression, exactly as Function.prototype.toString prints it. Its parameters and return type are main’s, and a concise body is main’s return. Diagnostics point into the closure text. args then compiles main’s scalar arguments in as known values, so the program takes none at run time:
closure-args.ts
require(amount >= minimum) while compiling. Its entryParams is empty, and entrySignature still lists both parameters. The closure is SauceScript text: the compiler does not run it as JavaScript or capture host variables.
Each args value is one word: a bool, or a non-negative integer below 2^256 as a bigint or a decimal or 0x string. The raw option takes no bytes, arrays or records, and refuses -10n (not a valid integer literal); pass a negative Int256 as its two’s-complement word, (1n << 256n) - 10n. compileSauceProgram’s args takes -10n for an Int256 parameter.
Nested programs
A program can compile a closure as a program of its own withprogram(closure, ...args). Each one appears in programs, with the names it captures from the program around it:
programs-report.ts
path lists the programs a nested program sits in, outermost first, and captures lists the words its args carry, in order. Inside the program, program() returns { code, args }; the captured values and the closure’s parameters are read-only.
The SDK’s modules
resolveSdkModule and resolveSdkPackage serve, from memory, the files compileSauceProgram serves without being asked: the @sauce/token and @sauce/router libraries, ./artifacts/IERC20.json, ./artifacts/ISauceRouter.json and every ./protocols/<slug>/<Export>.json. Fall back to them from your resolver:
raw-compile-sdk-modules.ts
sdk/dist/std/token/ and sdk/dist/std/router/ (one .evm.js and one .svm.js arm each, and the ABIs they bind) for a toolchain that resolves packages from disk. The compiler picks the arm by target.
ready
Initializes the compiler’s WebAssembly where the environment needs it. In Node it resolves at once and ignoressource; in a browser, every compile throws until it has resolved.
Import
Usage
ready.ts
Signature
Parameters
Returns
A promise that resolves once the compiler can run. Callingready() again is harmless, and a failed attempt is not remembered, so a later call tries again. The overview shows a browser entry that passes a URL.
Compile errors
All three functions throw on a compile error. A located source error, such as the undeclared variable below, has three headlines with ANSI bold codes; the source line and caret are plain. An error from a failed import has more headlines, so do not rely on a fixed count. The codes are always emitted, so strip them (stripVTControlCharacters from node:util) before matching or logging the text. Its diagnostics array places each source error.
compileSauceProgram and compileSauceRoute can also throw a parse SyntaxError with no ANSI codes and no diagnostics. The raw compile reports a parse error through the compiler’s error report instead.
compile-error.ts
{ path, message, start, end, secondary?, code? }:
path: the module asresolvewas asked for it. An error in an imported module names the import.start,end:{ offset, line, column }. Lines and columns start at 1, and counts are UTF-16 code units, sosource.slice(start.offset, end.offset)is the span.secondary: a second location with its own note, where there is one.code: the error’s stable name, such asUnknownIdentifier,UnknownFunctionorTypeMismatch. Match on it rather than onmessage. A parse or subset error has none.
diagnostics array. A message your resolver throws is kept. compileSauceProgram and compileSauceRoute compile the rewritten source as main.js, so their diagnostics name main.js. The /compiler subpath does not export a type for the error; narrow it as the example does.
Next steps
- Entry arguments: encode
main’s arguments for a compiled program. - Cook transactions: turn a compiled program into a transaction.
- sauce compile: the same compile from a terminal.
- Bytecode: what the compiler emits.
- @eco-incorp/sauce-compiler reference: the compiler package’s API.
