Skip to content

Commit 0efa2de

Browse files
committed
enable transfers between subaccounts
1 parent 7c96bf9 commit 0efa2de

File tree

2 files changed

+85
-10
lines changed

2 files changed

+85
-10
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import asyncio
2+
import lighter
3+
from utils import default_example_setup
4+
5+
TO_ACCOUNT_INDEX = 281474976710648 # same master account
6+
7+
8+
async def main():
9+
client, api_client, _ = default_example_setup()
10+
info_api = lighter.InfoApi(api_client)
11+
12+
auth_token, err = client.create_auth_token_with_expiry()
13+
if err:
14+
raise Exception(f"Auth token failed: {err}")
15+
16+
fee_info = await info_api.transfer_fee_info(client.account_index, authorization=auth_token, auth=auth_token, to_account_index=TO_ACCOUNT_INDEX)
17+
18+
# You can find more notes on transfers in the README.md file, under `Transfer Notes`
19+
transfer_tx, response, err = await client.transfer_same_master_account(
20+
to_account_index=TO_ACCOUNT_INDEX,
21+
asset_id=client.ASSET_ID_USDC,
22+
route_from=client.ROUTE_PERP,
23+
route_to=client.ROUTE_PERP,
24+
amount=5, # decimals are added by sdk
25+
fee=fee_info.transfer_fee_usdc,
26+
memo="0x" + "00" * 32,
27+
)
28+
if err is not None:
29+
raise Exception(f"error transferring {err}")
30+
31+
print(transfer_tx, response)
32+
await client.close()
33+
await api_client.close()
34+
35+
36+
if __name__ == "__main__":
37+
asyncio.run(main())

lighter/signer_client.py

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,14 @@ class SignerClient:
212212
DEFAULT_NONCE = -1
213213
DEFAULT_API_KEY_INDEX = 255
214214

215-
USDC_TICKER_SCALE = 1e6
216215
ETH_TICKER_SCALE = 1e8
216+
USDC_TICKER_SCALE = 1e6
217+
LIT_TICKER_SCALE = 1e8
218+
LINK_TICKER_SCALE = 1e8
219+
UNI_TICKER_SCALE = 1e8
220+
AAVE_TICKER_SCALE = 1e8
221+
SKY_TICKER_SCALE = 1e8
222+
LDO_TICKER_SCALE = 1e8
217223

218224
ORDER_TYPE_LIMIT = 0
219225
ORDER_TYPE_MARKET = 1
@@ -250,8 +256,25 @@ class SignerClient:
250256
ROUTE_PERP = 0
251257
ROUTE_SPOT = 1
252258

253-
ASSET_ID_USDC = 3
254259
ASSET_ID_ETH = 1
260+
ASSET_ID_LIT = 2
261+
ASSET_ID_USDC = 3
262+
ASSET_ID_LINK = 5
263+
ASSET_ID_UNI = 6
264+
ASSET_ID_AAVE = 7
265+
ASSET_ID_SKY = 8
266+
ASSET_ID_LDO = 9
267+
268+
ASSET_TO_TICKER_SCALE = {
269+
ASSET_ID_ETH: ETH_TICKER_SCALE,
270+
ASSET_ID_LIT: LIT_TICKER_SCALE,
271+
ASSET_ID_USDC: USDC_TICKER_SCALE,
272+
ASSET_ID_LINK: LINK_TICKER_SCALE,
273+
ASSET_ID_UNI: UNI_TICKER_SCALE,
274+
ASSET_ID_AAVE: AAVE_TICKER_SCALE,
275+
ASSET_ID_SKY: SKY_TICKER_SCALE,
276+
ASSET_ID_LDO: LDO_TICKER_SCALE,
277+
}
255278

256279
def __init__(
257280
self,
@@ -466,6 +489,9 @@ def sign_modify_order(self, market_index: int, order_index: int, base_amount: in
466489
def sign_transfer(self, eth_private_key: str, to_account_index: int, asset_id: int, route_from: int, route_to: int, usdc_amount: int, fee: int, memo: str, nonce: int = DEFAULT_NONCE, api_key_index: int = DEFAULT_API_KEY_INDEX) -> Union[Tuple[str, str, str, None], Tuple[None, None, None, str]]:
467490
return self.__decode_and_sign_tx_info(eth_private_key, self.signer.SignTransfer(to_account_index, asset_id, route_from, route_to, usdc_amount, fee, ctypes.c_char_p(memo.encode("utf-8")), nonce, api_key_index, self.account_index))
468491

492+
def sign_transfer_same_master_account(self, to_account_index: int, asset_id: int, route_from: int, route_to: int, usdc_amount: int, fee: int, memo: str, nonce: int = DEFAULT_NONCE, api_key_index: int = DEFAULT_API_KEY_INDEX) -> Union[Tuple[str, str, str, None], Tuple[None, None, None, str]]:
493+
return self.__decode_tx_info(self.signer.SignTransfer(to_account_index, asset_id, route_from, route_to, usdc_amount, fee, ctypes.c_char_p(memo.encode("utf-8")), nonce, api_key_index, self.account_index))
494+
469495
def sign_create_public_pool(self, operator_fee: int, initial_total_shares: int, min_operator_share_rate: int, nonce: int = DEFAULT_NONCE, api_key_index: int = DEFAULT_API_KEY_INDEX) -> Union[Tuple[str, str, str, None], Tuple[None, None, None, str]]:
470496
return self.__decode_tx_info(self.signer.SignCreatePublicPool(operator_fee, initial_total_shares, min_operator_share_rate, nonce, api_key_index, self.account_index))
471497

@@ -743,10 +769,8 @@ async def create_sl_limit_order(self, market_index, client_order_index, base_amo
743769

744770
@process_api_key_and_nonce
745771
async def withdraw(self, asset_id: int, route_type: int, amount: float, nonce: int = DEFAULT_NONCE, api_key_index: int = DEFAULT_API_KEY_INDEX) -> Union[Tuple[Withdraw, RespSendTx, None], Tuple[None, None, str]]:
746-
if asset_id == self.ASSET_ID_USDC:
747-
amount = int(amount * self.USDC_TICKER_SCALE)
748-
elif asset_id == self.ASSET_ID_ETH:
749-
amount = int(amount * self.ETH_TICKER_SCALE)
772+
if asset_id in self.ASSET_TO_TICKER_SCALE:
773+
amount = int(amount * self.ASSET_TO_TICKER_SCALE[asset_id])
750774
else:
751775
raise ValueError(f"Unsupported asset id: {asset_id}")
752776

@@ -796,10 +820,8 @@ async def modify_order(
796820

797821
@process_api_key_and_nonce
798822
async def transfer(self, eth_private_key: str, to_account_index: int, asset_id: int, route_from: int, route_to: int, amount: float, fee: int, memo: str, nonce: int = DEFAULT_NONCE, api_key_index: int = DEFAULT_API_KEY_INDEX):
799-
if asset_id == self.ASSET_ID_USDC:
800-
amount = int(amount * self.USDC_TICKER_SCALE)
801-
elif asset_id == self.ASSET_ID_ETH:
802-
amount = int(amount * self.ETH_TICKER_SCALE)
823+
if asset_id in self.ASSET_TO_TICKER_SCALE:
824+
amount = int(amount * self.ASSET_TO_TICKER_SCALE[asset_id])
803825
else:
804826
raise ValueError(f"Unsupported asset id: {asset_id}")
805827

@@ -812,6 +834,22 @@ async def transfer(self, eth_private_key: str, to_account_index: int, asset_id:
812834
logging.debug(f"Transfer Send. TxResponse: {api_response}")
813835
return tx_info, api_response, None
814836

837+
@process_api_key_and_nonce
838+
async def transfer_same_master_account(self, to_account_index: int, asset_id: int, route_from: int, route_to: int, amount: float, fee: int, memo: str, nonce: int = DEFAULT_NONCE, api_key_index: int = DEFAULT_API_KEY_INDEX):
839+
if asset_id in self.ASSET_TO_TICKER_SCALE:
840+
amount = int(amount * self.ASSET_TO_TICKER_SCALE[asset_id])
841+
else:
842+
raise ValueError(f"Unsupported asset id: {asset_id}")
843+
844+
tx_type, tx_info, tx_hash, error = self.sign_transfer_same_master_account(to_account_index, asset_id, route_from, route_to, amount, fee, memo, nonce, api_key_index)
845+
if error is not None:
846+
return None, None, error
847+
848+
logging.debug(f"Transfer TxHash: {tx_hash} TxInfo: {tx_info}")
849+
api_response = await self.send_tx(tx_type=tx_type, tx_info=tx_info)
850+
logging.debug(f"Transfer Send. TxResponse: {api_response}")
851+
return tx_info, api_response, None
852+
815853
@process_api_key_and_nonce
816854
async def create_public_pool(
817855
self, operator_fee, initial_total_shares, min_operator_share_rate, nonce: int = DEFAULT_NONCE, api_key_index: int = DEFAULT_API_KEY_INDEX

0 commit comments

Comments
 (0)