Alcor OTC V3 SDK
Small dependency-free TypeScript SDK for wiring the OTC V3 protocol into a frontend or market-maker tool.
The SDK exposes:
- current Arbitrum WBTC/USDT and WETH/USDT market deployments;
- full ABIs for the current factory, router, account, position store, LP vault, LP vault factory, oracle fixing, price source, trade validator, and volatility oracle interface;
- typed config and package-trade shapes;
- helpers for base-asset decimal normalization;
- default portfolio config builders for WBTC/USDT and WETH/USDT.
01Usage
import {
OTC_V3_ARBITRUM_WBTC_USDT,
otcFactoryV3Abi,
otcRouterV3Abi,
otcLpVaultFactoryV3Abi,
createDefaultWbtcUsdtPortfolioConfig,
stringifyForJson,
parseBaseUnits
} from "@alcor-finance/otc-v3-sdk";
const market = OTC_V3_ARBITRUM_WBTC_USDT;
const config = createDefaultWbtcUsdtPortfolioConfig({
partyA: "0x1111111111111111111111111111111111111111",
partyB: "0x2222222222222222222222222222222222222222",
portfolioSalt:
"0x0000000000000000000000000000000000000000000000000000000000000001"
});
const jsonForConfigPanel = stringifyForJson(config);
const oneWbtcAccountAmount = parseBaseUnits("1", market.baseAsset.decimals);
Use:
market.contracts.factorywithotcFactoryV3Abi;market.contracts.routerwithotcRouterV3Abi;market.contracts.lpVaultFactorywithotcLpVaultFactoryV3Abi;- per-portfolio account/store addresses from
factory.portfolioRecord.
02Market Deployments
Available profiles:
arbitrum-wbtc-usdtarbitrum-weth-usdt
Resolve them with:
import {
getOtcV3Market,
getOtcV3MarketByChainAndPair
} from "@alcor-finance/otc-v3-sdk";
const byProfile = getOtcV3Market("arbitrum-wbtc-usdt");
const byPair = getOtcV3MarketByChainAndPair(42161, "WETH/USDT");
Each market deployment is bound to one base/quote pair. The base asset is also the collateral and premium token for that deployment.
03Unit Model
Protocol account amounts are normalized to base-WAD values. Native ERC20 transfers use the base token decimals.
For WBTC/USDT:
1 WBTC protocol/account amount = 1e18
1 WBTC native token amount = 1e8
For WETH/USDT:
1 WETH protocol/account amount = 1e18
1 WETH native token amount = 1e18
Use parseBaseUnits and formatBaseUnits for user-facing base-asset amounts.
04Direct Portfolio Flow
- Build a
PortfolioConfig. - Preview ids and addresses with
factory.computePortfolioConfigHash,factory.computePortfolioId, andfactory.predictPortfolioContracts. - Create the isolated portfolio with
factory.createPortfolio(config). - Deposit through
router.depositCollateral. - Execute RFQ/Dutch package trades through
router.executeUserSignedPackageTrade. - Settle expired expiries through
router.settleExpiredPortfolioExpiry. - Withdraw through
router.withdrawCollateral.
The router auto-settles expired positions on meaningful actions where the contract path requires a clean live state.
05LP Vault Flow
LP vaults use market.contracts.lpVaultFactory.
The owner can call createVaultAndPortfolio(curator, marketMaker, baseAsset, salt, config) to deploy a vault and create/bind its isolated portfolio in the same transaction. The resulting vault can approve package digests through ERC-1271 and route operational actions to the portfolio router.
Relevant ABIs:
otcLpVaultFactoryV3AbiotcLpVaultV3Abi
06Emergency Close
Current router/account ABIs include the mutual emergency close path:
router.proposeEmergencyClose(config, partyAReceiver, partyBReceiver, partyATokenAmount, partyBTokenAmount)router.executeEmergencyClose(config, partyAReceiver, partyBReceiver, partyATokenAmount, partyBTokenAmount)router.emergencyCloseProposal(config)
For LP vaults, use the corresponding vault functions so the vault owner can confirm the agreed split.
07Settlement Default
If an expired settlement cannot be fully paid by the losing side, the current production behavior is terminal closeout of that portfolio rather than a voluntary settlement IOU that affects later expiries. Indexers should listen for the full router ABI event set, including PortfolioSettlementDefaultClosed.