diff --git a/docs/ApiKey.md b/docs/ApiKey.md index 242aad1..78c8721 100644 --- a/docs/ApiKey.md +++ b/docs/ApiKey.md @@ -9,6 +9,7 @@ Name | Type | Description | Notes **api_key_index** | **int** | | **nonce** | **int** | | **public_key** | **str** | | +**key_type** | **int** | | [optional] **transaction_time** | **int** | | ## Example diff --git a/lighter/__init__.py b/lighter/__init__.py index 6c1229e..4fd9bea 100644 --- a/lighter/__init__.py +++ b/lighter/__init__.py @@ -208,4 +208,4 @@ # manual additions from lighter.ws_client import WsClient -from lighter.signer_client import SignerClient, create_api_key \ No newline at end of file +from lighter.signer_client import SignerClient, create_api_key, create_schnorr_api_key \ No newline at end of file diff --git a/lighter/models/api_key.py b/lighter/models/api_key.py index 96e9d91..3f89701 100644 --- a/lighter/models/api_key.py +++ b/lighter/models/api_key.py @@ -30,9 +30,10 @@ class ApiKey(BaseModel): api_key_index: StrictInt nonce: StrictInt public_key: StrictStr + key_type: Optional[StrictInt] = None transaction_time: StrictInt additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["account_index", "api_key_index", "nonce", "public_key", "transaction_time"] + __properties: ClassVar[List[str]] = ["account_index", "api_key_index", "nonce", "public_key", "key_type", "transaction_time"] model_config = ConfigDict( populate_by_name=True, @@ -96,6 +97,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "api_key_index": obj.get("api_key_index"), "nonce": obj.get("nonce"), "public_key": obj.get("public_key"), + "key_type": obj.get("key_type"), "transaction_time": obj.get("transaction_time") }) # store additional fields in additional_properties diff --git a/lighter/signer_client.py b/lighter/signer_client.py index eeb1c8f..f0eb229 100644 --- a/lighter/signer_client.py +++ b/lighter/signer_client.py @@ -153,6 +153,9 @@ def __populate_shared_library_functions(signer): signer.GenerateAPIKey.argtypes = [] signer.GenerateAPIKey.restype = ApiKeyResponse + signer.GenerateSchnorrAPIKey.argtypes = [] + signer.GenerateSchnorrAPIKey.restype = ApiKeyResponse + signer.CreateClient.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_int, ctypes.c_int, ctypes.c_longlong] signer.CreateClient.restype = ctypes.c_void_p @@ -162,6 +165,9 @@ def __populate_shared_library_functions(signer): signer.SignChangePubKey.argtypes = [ctypes.c_char_p, ctypes.c_uint8, ctypes.c_longlong, ctypes.c_int, ctypes.c_longlong] signer.SignChangePubKey.restype = SignedTxResponse + signer.SignChangeECDSAPubKey.argtypes = [ctypes.c_char_p, ctypes.c_uint8, ctypes.c_longlong, ctypes.c_int, ctypes.c_longlong] + signer.SignChangeECDSAPubKey.restype = SignedTxResponse + signer.SignCreateOrder.argtypes = [ctypes.c_longlong, ctypes.c_longlong, ctypes.c_longlong, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_longlong, ctypes.c_longlong, ctypes.c_int, ctypes.c_int, ctypes.c_uint8, ctypes.c_uint8, ctypes.c_uint8, ctypes.c_longlong, ctypes.c_int, ctypes.c_longlong] signer.SignCreateOrder.restype = SignedTxResponse @@ -252,6 +258,8 @@ def get_signer(): return __signer +# secp256k1 ECDSA api key: 32-byte private key, 33-byte compressed public key. Register it with +# change_api_key; the signer picks the scheme from the key length. def create_api_key(): result = lighter.signer_client.get_signer().GenerateAPIKey() private_key_str = decode_and_free(result.privateKey) @@ -260,6 +268,15 @@ def create_api_key(): return private_key_str, public_key_str, error +# Legacy Schnorr api key: 40-byte private and public keys. +def create_schnorr_api_key(): + result = lighter.signer_client.get_signer().GenerateSchnorrAPIKey() + private_key_str = decode_and_free(result.privateKey) + public_key_str = decode_and_free(result.publicKey) + error = decode_and_free(result.err) + return private_key_str, public_key_str, error + + def trim_exc(exception_body: str): return exception_body.strip().split("\n")[-1] @@ -505,6 +522,10 @@ def check_client(self): def create_api_key(self): return create_api_key() + @staticmethod + def create_schnorr_api_key(self): + return create_schnorr_api_key() + def create_auth_token_with_expiry(self, deadline: int = DEFAULT_10_MIN_AUTH_EXPIRY, *, timestamp: int = None, api_key_index: int = DEFAULT_API_KEY_INDEX): if deadline == SignerClient.DEFAULT_10_MIN_AUTH_EXPIRY: deadline = 10 * SignerClient.MINUTE @@ -517,8 +538,11 @@ def create_auth_token_with_expiry(self, deadline: int = DEFAULT_10_MIN_AUTH_EXPI error = decode_and_free(result.err) return auth, error + # 33-byte (66 hex) public keys are ECDSA and register via SignChangeECDSAPubKey (tx type 54); 40-byte ones are Schnorr def sign_change_api_key(self, eth_private_key: str, new_pubkey: str, skip_nonce: int = SKIP_NONCE_OFF, nonce: int = DEFAULT_NONCE, api_key_index: int = DEFAULT_API_KEY_INDEX) -> Union[Tuple[str, str, str, None], Tuple[None, None, None, str]]: - return self.__decode_and_sign_tx_info(eth_private_key, self.signer.SignChangePubKey( + is_ecdsa = len(new_pubkey[2:] if new_pubkey.startswith("0x") else new_pubkey) == 66 + sign = self.signer.SignChangeECDSAPubKey if is_ecdsa else self.signer.SignChangePubKey + return self.__decode_and_sign_tx_info(eth_private_key, sign( ctypes.c_char_p(new_pubkey.encode("utf-8")), skip_nonce, nonce, diff --git a/lighter/signers/lighter-signer-darwin-amd64.dylib b/lighter/signers/lighter-signer-darwin-amd64.dylib index defa95d..3608a71 100644 Binary files a/lighter/signers/lighter-signer-darwin-amd64.dylib and b/lighter/signers/lighter-signer-darwin-amd64.dylib differ diff --git a/lighter/signers/lighter-signer-darwin-amd64.h b/lighter/signers/lighter-signer-darwin-amd64.h index 7563c47..d951b78 100644 --- a/lighter/signers/lighter-signer-darwin-amd64.h +++ b/lighter/signers/lighter-signer-darwin-amd64.h @@ -160,9 +160,11 @@ extern "C" { #endif extern ApiKeyResponse GenerateAPIKey(void); +extern ApiKeyResponse GenerateSchnorrAPIKey(void); extern char* CreateClient(char* cUrl, char* cPrivateKey, int cChainId, int cApiKeyIndex, long long cAccountIndex); extern char* CheckClient(int cApiKeyIndex, long long cAccountIndex); extern SignedTxResponse SignChangePubKey(char* cPubKey, uint8_t cSkipNonce, long long cNonce, int cApiKeyIndex, long long cAccountIndex); +extern SignedTxResponse SignChangeECDSAPubKey(char* cPubKey, uint8_t cSkipNonce, long long cNonce, int cApiKeyIndex, long long cAccountIndex); extern SignedTxResponse SignCreateOrder(long long cMarketIndex, long long cClientOrderIndex, long long cBaseAmount, int cPrice, int cIsAsk, int cOrderType, int cTimeInForce, int cReduceOnly, int cTriggerPrice, long long cOrderExpiry, long long cIntegratorAccountIndex, int cIntegratorTakerFee, int cIntegratorMakerFee, uint8_t cSelfTradeBehaviorMode, uint8_t cSelfTradeEqualityMode, uint8_t cSkipNonce, long long cNonce, int cApiKeyIndex, long long cAccountIndex); extern SignedTxResponse SignCreateGroupedOrders(uint8_t cGroupingType, CreateOrderTxReq* cOrders, int cLen, long long cIntegratorAccountIndex, int cIntegratorTakerFee, int cIntegratorMakerFee, uint8_t cSelfTradeBehaviorMode, uint8_t cSelfTradeEqualityMode, uint8_t cSkipNonce, long long cNonce, int cApiKeyIndex, long long cAccountIndex); extern SignedTxResponse SignCancelOrder(long long cMarketIndex, long long cOrderIndex, uint8_t cSkipNonce, long long cNonce, int cApiKeyIndex, long long cAccountIndex); diff --git a/lighter/signers/lighter-signer-darwin-arm64.dylib b/lighter/signers/lighter-signer-darwin-arm64.dylib index a1a824b..0c9e2fb 100644 Binary files a/lighter/signers/lighter-signer-darwin-arm64.dylib and b/lighter/signers/lighter-signer-darwin-arm64.dylib differ diff --git a/lighter/signers/lighter-signer-darwin-arm64.h b/lighter/signers/lighter-signer-darwin-arm64.h index 7563c47..d951b78 100644 --- a/lighter/signers/lighter-signer-darwin-arm64.h +++ b/lighter/signers/lighter-signer-darwin-arm64.h @@ -160,9 +160,11 @@ extern "C" { #endif extern ApiKeyResponse GenerateAPIKey(void); +extern ApiKeyResponse GenerateSchnorrAPIKey(void); extern char* CreateClient(char* cUrl, char* cPrivateKey, int cChainId, int cApiKeyIndex, long long cAccountIndex); extern char* CheckClient(int cApiKeyIndex, long long cAccountIndex); extern SignedTxResponse SignChangePubKey(char* cPubKey, uint8_t cSkipNonce, long long cNonce, int cApiKeyIndex, long long cAccountIndex); +extern SignedTxResponse SignChangeECDSAPubKey(char* cPubKey, uint8_t cSkipNonce, long long cNonce, int cApiKeyIndex, long long cAccountIndex); extern SignedTxResponse SignCreateOrder(long long cMarketIndex, long long cClientOrderIndex, long long cBaseAmount, int cPrice, int cIsAsk, int cOrderType, int cTimeInForce, int cReduceOnly, int cTriggerPrice, long long cOrderExpiry, long long cIntegratorAccountIndex, int cIntegratorTakerFee, int cIntegratorMakerFee, uint8_t cSelfTradeBehaviorMode, uint8_t cSelfTradeEqualityMode, uint8_t cSkipNonce, long long cNonce, int cApiKeyIndex, long long cAccountIndex); extern SignedTxResponse SignCreateGroupedOrders(uint8_t cGroupingType, CreateOrderTxReq* cOrders, int cLen, long long cIntegratorAccountIndex, int cIntegratorTakerFee, int cIntegratorMakerFee, uint8_t cSelfTradeBehaviorMode, uint8_t cSelfTradeEqualityMode, uint8_t cSkipNonce, long long cNonce, int cApiKeyIndex, long long cAccountIndex); extern SignedTxResponse SignCancelOrder(long long cMarketIndex, long long cOrderIndex, uint8_t cSkipNonce, long long cNonce, int cApiKeyIndex, long long cAccountIndex); diff --git a/lighter/signers/lighter-signer-linux-amd64.h b/lighter/signers/lighter-signer-linux-amd64.h index e4f0f2c..45a2271 100644 --- a/lighter/signers/lighter-signer-linux-amd64.h +++ b/lighter/signers/lighter-signer-linux-amd64.h @@ -160,9 +160,11 @@ extern "C" { #endif extern ApiKeyResponse GenerateAPIKey(void); +extern ApiKeyResponse GenerateSchnorrAPIKey(void); extern char* CreateClient(char* cUrl, char* cPrivateKey, int cChainId, int cApiKeyIndex, long long int cAccountIndex); extern char* CheckClient(int cApiKeyIndex, long long int cAccountIndex); extern SignedTxResponse SignChangePubKey(char* cPubKey, uint8_t cSkipNonce, long long int cNonce, int cApiKeyIndex, long long int cAccountIndex); +extern SignedTxResponse SignChangeECDSAPubKey(char* cPubKey, uint8_t cSkipNonce, long long int cNonce, int cApiKeyIndex, long long int cAccountIndex); extern SignedTxResponse SignCreateOrder(long long int cMarketIndex, long long int cClientOrderIndex, long long int cBaseAmount, int cPrice, int cIsAsk, int cOrderType, int cTimeInForce, int cReduceOnly, int cTriggerPrice, long long int cOrderExpiry, long long int cIntegratorAccountIndex, int cIntegratorTakerFee, int cIntegratorMakerFee, uint8_t cSelfTradeBehaviorMode, uint8_t cSelfTradeEqualityMode, uint8_t cSkipNonce, long long int cNonce, int cApiKeyIndex, long long int cAccountIndex); extern SignedTxResponse SignCreateGroupedOrders(uint8_t cGroupingType, CreateOrderTxReq* cOrders, int cLen, long long int cIntegratorAccountIndex, int cIntegratorTakerFee, int cIntegratorMakerFee, uint8_t cSelfTradeBehaviorMode, uint8_t cSelfTradeEqualityMode, uint8_t cSkipNonce, long long int cNonce, int cApiKeyIndex, long long int cAccountIndex); extern SignedTxResponse SignCancelOrder(long long int cMarketIndex, long long int cOrderIndex, uint8_t cSkipNonce, long long int cNonce, int cApiKeyIndex, long long int cAccountIndex); diff --git a/lighter/signers/lighter-signer-linux-amd64.so b/lighter/signers/lighter-signer-linux-amd64.so index 29227b1..b88b4a4 100644 Binary files a/lighter/signers/lighter-signer-linux-amd64.so and b/lighter/signers/lighter-signer-linux-amd64.so differ diff --git a/lighter/signers/lighter-signer-linux-arm64.h b/lighter/signers/lighter-signer-linux-arm64.h index e4f0f2c..45a2271 100644 --- a/lighter/signers/lighter-signer-linux-arm64.h +++ b/lighter/signers/lighter-signer-linux-arm64.h @@ -160,9 +160,11 @@ extern "C" { #endif extern ApiKeyResponse GenerateAPIKey(void); +extern ApiKeyResponse GenerateSchnorrAPIKey(void); extern char* CreateClient(char* cUrl, char* cPrivateKey, int cChainId, int cApiKeyIndex, long long int cAccountIndex); extern char* CheckClient(int cApiKeyIndex, long long int cAccountIndex); extern SignedTxResponse SignChangePubKey(char* cPubKey, uint8_t cSkipNonce, long long int cNonce, int cApiKeyIndex, long long int cAccountIndex); +extern SignedTxResponse SignChangeECDSAPubKey(char* cPubKey, uint8_t cSkipNonce, long long int cNonce, int cApiKeyIndex, long long int cAccountIndex); extern SignedTxResponse SignCreateOrder(long long int cMarketIndex, long long int cClientOrderIndex, long long int cBaseAmount, int cPrice, int cIsAsk, int cOrderType, int cTimeInForce, int cReduceOnly, int cTriggerPrice, long long int cOrderExpiry, long long int cIntegratorAccountIndex, int cIntegratorTakerFee, int cIntegratorMakerFee, uint8_t cSelfTradeBehaviorMode, uint8_t cSelfTradeEqualityMode, uint8_t cSkipNonce, long long int cNonce, int cApiKeyIndex, long long int cAccountIndex); extern SignedTxResponse SignCreateGroupedOrders(uint8_t cGroupingType, CreateOrderTxReq* cOrders, int cLen, long long int cIntegratorAccountIndex, int cIntegratorTakerFee, int cIntegratorMakerFee, uint8_t cSelfTradeBehaviorMode, uint8_t cSelfTradeEqualityMode, uint8_t cSkipNonce, long long int cNonce, int cApiKeyIndex, long long int cAccountIndex); extern SignedTxResponse SignCancelOrder(long long int cMarketIndex, long long int cOrderIndex, uint8_t cSkipNonce, long long int cNonce, int cApiKeyIndex, long long int cAccountIndex); diff --git a/lighter/signers/lighter-signer-linux-arm64.so b/lighter/signers/lighter-signer-linux-arm64.so index 05753d0..6bf651b 100644 Binary files a/lighter/signers/lighter-signer-linux-arm64.so and b/lighter/signers/lighter-signer-linux-arm64.so differ diff --git a/lighter/signers/lighter-signer-windows-amd64.dll b/lighter/signers/lighter-signer-windows-amd64.dll index 3c742b8..62d8bb2 100644 Binary files a/lighter/signers/lighter-signer-windows-amd64.dll and b/lighter/signers/lighter-signer-windows-amd64.dll differ