@inco/js to @inco/lightning-js for v1. This guide covers the package rename plus the breaking API changes when upgrading from @inco/js 0.7.x.
Update every import —
@inco/js → @inco/lightning-js and @inco/js/lite → @inco/lightning-js/lite — then reinstall. The old @inco/js package is no longer updated.Install
Instantiating the SDK
v1 adds explicit per-network factories —Lightning.baseSepoliaTestnet() and Lightning.baseMainnet() — which take no pepper or chainId. Prefer them over the v0.7 Lightning.latest(...) call:
hostChainRpcUrls (recommended — otherwise the SDK falls back to viem’s public RPC endpoints):
Lightning.latest(pepper, chainId) still works for advanced cases, but the network factories are the recommended entry point.
Breaking Changes
1. Keypair generation: generateSecp256k1Keypair removed
generateSecp256k1Keypair was used for reencryption in attested decrypt calls. It has been replaced by generateXwingKeypair, a post-quantum X-Wing keypair. The new function is async.
encodePublicKey() for use in attested decrypt calls.
Session keys are unaffected — they use a plain viem
PrivateKeyAccount (via privateKeyToAccount(generatePrivateKey())), not an X-Wing keypair.2. Attested methods: positional args replaced by an opts object
All attested methods (attestedDecrypt, attestedCompute, attestedDecryptWithVoucher, attestedComputeWithVoucher) previously accepted reencryption keys as extra positional arguments. They now use a typed opts object as the last parameter.
attestedDecrypt — reencrypt for a delegate
attestedDecrypt — reencrypt and decrypt locally
attestedCompute — reencrypt for a delegate
No-opts calls are unchanged
If you were callingattestedDecrypt or attestedCompute without any reencryption options (plain decryption), no change is needed — the default behaviour is still to return plaintext directly.
3. Session key methods: reencryption options moved into an opts object
The session key is still a plain viem PrivateKeyAccount, and attestedDecryptWithVoucher / attestedComputeWithVoucher keep their positional arguments. What changed is that reencryption keys moved out of positional arguments and into a trailing opts object (the same change as section 2).
4. BackoffConfig field renames
ThebackoffConfig object passed to attested methods has two renamed fields, and is now passed inside the opts object.
| Old field | New field | Notes |
|---|---|---|
initialDelay | baseDelayInMs | Renamed |
maxDelay | (removed) | Replaced by backoffFactor |
| (n/a) | backoffFactor | Multiplier applied each retry |
5. AllowanceVoucher: warning field is first and enforced on-chain (EIP-712 digest change)
The AllowanceVoucher EIP-712 struct includes a string warning field that is now first in the struct. This ensures wallets display it before the opaque byte fields. The field order is part of the EIP-712 type hash, so any voucher signed with the old field order produces a different digest and will fail verification.
Additionally, isAllowedWithProof now enforces the exact warning text on-chain — it reverts with InvalidVoucherWarning if the voucher’s warning does not match REQUIRED_ALLOWANCE_VOUCHER_WARNING exactly. Passing an empty string, a custom message, or the old warning text will be rejected.
If you use grantSessionKeyAllowanceVoucher or grantCustomSessionKeyAllowanceVoucher (the Lightning methods), no change is needed — the correct warning is populated automatically.
Always create vouchers through the SDK, which sets the correct warning for you:
grantCustomSessionKeyAllowanceVoucher(walletClient, sessionVerifierAddress, sharerArgData) instead — it also sets the warning automatically.
New Features
Multiple RPC endpoints with automatic fallback
All Lightning factory methods now accept an optionalhostChainRpcUrls array. When multiple URLs are provided the SDK uses viem’s fallback() transport internally — it tries providers in order and moves to the next on failure.
baseSepoliaTestnet() and baseMainnet() are the recommended way to initialize the SDK. Passing your own hostChainRpcUrls is recommended — without it the SDK falls back to viem’s public RPC endpoints. A single URL also works.