UNPKG

@d8x/perpetuals-sdk

Version:

Node TypeScript SDK for D8X Perpetual Futures

90 lines (87 loc) 2.95 kB
import { Buffer } from "buffer"; import { AbiCoder, BigNumberish, concat, keccak256, toUtf8Bytes } from "ethers"; import { type SmartContractOrder } from "./nodeSDKTypes"; export default class TraderDigests { /** * Creates an order-id from the digest. Order-id is the 'digest' used in the smart contract. * @param digest created with _createDigest * @returns orderId string * @ignore */ public createOrderId(digest: string): string { let digestBuffer = Buffer.from(digest.substring(2, digest.length), "hex"); const messagePrefix = "\x19Ethereum Signed Message:\n"; let tmp = concat([toUtf8Bytes(messagePrefix), toUtf8Bytes(String(digestBuffer.length)), digestBuffer]); // see: https://github.com/ethers-io/ethers.js/blob/c80fcddf50a9023486e9f9acb1848aba4c19f7b6/packages/hash/src.ts/message.ts#L7 return keccak256(tmp); } /** * Creates a digest (order-id) * @param order smart-contract-type order * @param chainId chainId of network * @param isNewOrder true unless we cancel * @param signer ethereum-type wallet * @param proxyAddress address of the contract * @returns digest * @ignore */ public createDigest( order: SmartContractOrder, chainId: BigNumberish, isNewOrder: boolean, proxyAddress: string ): string { const NAME = "Perpetual Trade Manager"; const DOMAIN_TYPEHASH = keccak256( Buffer.from("EIP712Domain(string name,uint256 chainId,address verifyingContract)") ); const defaultAbiCoder = new AbiCoder(); let domainSeparator = keccak256( defaultAbiCoder.encode( ["bytes32", "bytes32", "uint256", "address"], [DOMAIN_TYPEHASH, keccak256(Buffer.from(NAME)), chainId, proxyAddress] ) ); const TRADE_ORDER_TYPEHASH = keccak256( Buffer.from( "Order(uint24 iPerpetualId,uint16 brokerFeeTbps,address traderAddr,address brokerAddr,int128 fAmount,int128 fLimitPrice,int128 fTriggerPrice,uint32 iDeadline,uint32 flags,uint16 leverageTDR,uint32 executionTimestamp)" ) ); let structHash = keccak256( defaultAbiCoder.encode( [ "bytes32", "uint24", "uint16", "address", "address", "int128", "int128", "int128", "uint64", "uint32", "uint16", "uint64", ], [ TRADE_ORDER_TYPEHASH, order.iPerpetualId, order.brokerFeeTbps, order.traderAddr, order.brokerAddr, order.fAmount, order.fLimitPrice, order.fTriggerPrice, order.iDeadline, order.flags, order.leverageTDR, order.executionTimestamp, ] ) ); let digest = keccak256( defaultAbiCoder.encode(["bytes32", "bytes32", "bool"], [domainSeparator, structHash, isNewOrder]) ); return digest; } }