-
Notifications
You must be signed in to change notification settings - Fork 527
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
python web3 to interact with gmx #109
Comments
figured out...format issue. this works: |
txn was mined but still got error: to use 10 usdc to open long eth position |
@vianiGa can you take a look? |
bump did you figure this out? Trying to essentially do the same on web3 python. I'm running into def increase_position(base_address, quote_address, direction, amount, slippage=0.5):
# normalize direction param
direction = str.lower(direction)
create_increase_position_abi = abi.arb.gmx.positionRouter.abi # ABI for the `createIncreasePosition` function
position_router_contract = w3.eth.contract(address=abi.arb.gmx.positionRouter.address, abi=create_increase_position_abi)
acceptable_price = 0
try:
for s in fetch_tickers([base_address, quote_address]):
if s.get('tokenAddress') == base_address:
acceptable_price = int(float(s.get('maxPrice')) * (1 + slippage/100))
except Exception as e:
print('failed to fetch tickers, aborting', print(e))
return None
params = {
'_path': [quote_address], # Make sure this is a list.
'_indexToken': base_address,
'_amountIn': w3.to_wei(amount, 'mwei'),
'_minOut': 0,
'_sizeDelta': int(amount * (10 ** 30)),
'_isLong': True if direction == 'long' else False, # Convert this directly to a bool here
'_acceptablePrice': acceptable_price,
'_executionFee': position_router_contract.functions.minExecutionFee().call(),
'_referralCode': w3.to_bytes(text='0').rjust(32, b'\0'),
'_callbackTarget': '0x0000000000000000000000000000000000000000'
}
tx = position_router_contract.functions.createIncreasePosition(
params['_path'],
params['_indexToken'],
params['_amountIn'],
params['_minOut'],
params['_sizeDelta'],
params['_isLong'],
params['_acceptablePrice'],
params['_executionFee'],
params['_referralCode'],
params['_callbackTarget']
)
estimated_gas = tx.estimate_gas({
'from': MY_ADDRESS
})
buffered_gas = int(estimated_gas * 1.20)
tx.build_transaction({
'chainId': 42161,
'gas': buffered_gas,
'gasPrice': w3.eth.gas_price,
'nonce': w3.eth.get_transaction_count(MY_ADDRESS),
})
signed_tx = w3.eth.account.sign_transaction(tx, MY_PRIVATE_KEY)
return w3.eth.send_raw_transaction(signed_tx.rawTransaction).hex()
if __name__ == '__main__':
receipt = increase_position(base_address=token_contracts.arbitrum.ARB, # token_contracts.arbitrum.ARB,
quote_address=token_contracts.arbitrum.USDC, # token_contracts.arbitrum.USDC,
direction='long',
amount=5) |
According to the contract, you need to send the _executionFee amount as the transaction value. So if _executionFee is 180000000000000, you'd need to send that amount of ETH. You can check the contract here. Look in PositionRouter.sol on line 306. I think you would just add 'value': 180000000000000 to your estimate_gas dict. |
Thanks. Putting that in the dictionary did get me passed that error. But now its also erroring
|
Here's me trying to approve a token to the maxuint256, getting
|
I think you're doing it backwards? Your token_contract is being set to the position router, when it should be the address of whatever token. Then you should be approving the position router as a spender for the token. I'm not sure if your approve abi is correct either, not sure how you have that defined but it appears to be the abi of the position router? |
Ah yea that was a chicken scratch mistake-- with labeling things incorrectly. I've fixed it but now you got me a bit confused.. Is it my wallet address or the position router contract's address passed for approve functions second argument? I am using the approve function from the positionRouter contract. You can see the function signature on arbiscan and says the "spender" is the second argument. The def approve_router(token_address):
approve_abi = abi.arb.gmx.positionRouter.abi
position_router_contract = w3.eth.contract(address=abi.arb.gmx.positionRouter.address, abi=approve_abi)
tx = position_router_contract.functions.approve(token_address, abi.arb.gmx.positionRouter.address, 2**256 - 1)
estimated_gas = tx.estimate_gas({'from': MY_ADDRESS})
buffered_gas = int(estimated_gas * 1.20)
tx = tx.build_transaction({
'chainId': 42161,
'gas': buffered_gas,
'gasPrice': w3.eth.gas_price,
'nonce': w3.eth.get_transaction_count(MY_ADDRESS),
})
signed_tx = w3.eth.account.sign_transaction(tx, MY_PRIVATE_KEY)
return w3.eth.send_raw_transaction(signed_tx.rawTransaction).hex()
receipt = approve_router(token_contracts.arbitrum.ETH) I was able to allow plugins successfully, targeting the position router contract as the target and the code below. def approve_plugin():
approve_plugin_abi = abi.arb.gmx.router.abi # ABI for the `approvePlugin` function
position_router_contract = w3.eth.contract(address=abi.arb.gmx.router.address, abi=approve_plugin_abi)
tx = position_router_contract.functions.approvePlugin(abi.arb.gmx.positionRouter.address)
estimated_gas = tx.estimate_gas({'from': MY_ADDRESS})
buffered_gas = int(estimated_gas * 1.20)
tx = tx.build_transaction({
'chainId': 42161,
'gas': buffered_gas,
'gasPrice': w3.eth.gas_price,
'nonce': w3.eth.get_transaction_count(MY_ADDRESS),
})
signed_tx = w3.eth.account.sign_transaction(tx, MY_PRIVATE_KEY)
return w3.eth.send_raw_transaction(signed_tx.rawTransaction).hex() Not sure what I'm doing wrong to allow spending ** shrug ** |
It's the approve that's wrong, it's still backwards. Above, you are calling approve on the router contract. You need to do the opposite. You need to call approve on the token contract, and pass the router address in as the first argument, and the amount as the second. Would look something like this:
|
Thank you for the guidance. I apologize I'm still a little new to web3 / smart contracts with python. I didn't think the token_address would have an ABI since upon viewing the contracts on arbiscan I could see there were basically 0 read/write functions for that token itself. I was unaware of native abi methods from erc20 standard. I'm still running into another issue while trying to open positions :( I found this position manager library from a community member from def send_tx(pk, addy, tx):
signed_tx = w3.eth.account.sign_transaction(tx, pk)
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
print(w3.to_hex(tx_hash))
def marketLong(coin, collateral, leverage, amount_in, price, slippage):
print("Longboi")
nonce = w3.eth.get_transaction_count(MY_ADDRESS)
path = long_collateral_path(coin, collateral)
execution_price = Web3.to_wei(str(price * (1.0 + slippage / 100.0)), "tether")
is_long = True
executionFee = Web3.to_wei( 300000, "gwei")
referral = "0x0000000000000000000000000000000000000000000000000000000000000000"
create_increase_position_abi = abi.arb.gmx.positionRouter.abi # ABI for the `createIncreasePosition` function
position_router_contract = w3.eth.contract(address=abi.arb.gmx.positionRouter.address, abi=create_increase_position_abi)
if (coin == "eth" and collateral == "weth"):
index_token = Web3.to_checksum_address(token_contracts.arbitrum.WETH.lower())
min_out = 0
amountIn = Web3.to_wei(amount_in, 'ether')
size_delta = Web3.to_wei(str(leverage * amount_in * price * (1.0 + slippage / 100.0)), 'tether')
print(path, ", ",index_token, ", ", ",", min_out, ", ", size_delta, ", ", is_long, ", ", execution_price, ", ", )
longboi = position_router_contract.functions.createIncreasePosition(path, index_token, amountIn, min_out, size_delta, is_long, execution_price, executionFee, referral, token_contracts.arbitrum.ADDRESS_ZERO).build_transaction({'chainId': 42161, 'nonce': nonce, 'value' : executionFee,'gasPrice': Web3.to_wei('1', 'gwei')})
send_tx(MY_PRIVATE_KEY, position_router_contract, longboi)
elif (coin == "eth" and (collateral == "usdt" or collateral == "usdc")):
index_token = Web3.to_checksum_address(token_contracts.arbitrum.WETH.lower())
min_out = Web3.to_wei(amount_in / (price * (1.0 + slippage / 100.0)) , 'ether')
amountIn = Web3.to_wei(amount_in , 'mwei')
size_delta = Web3.to_wei(str(leverage * amount_in * (1.0 + slippage / 100.0)), 'tether')
print(path, ", ",index_token, ", ", ",", min_out, ", ", size_delta, ", ", is_long, ", ", execution_price, ", ", )
longboi = position_router_contract.functions.createIncreasePosition(path, index_token, amountIn, min_out, size_delta, is_long, execution_price, executionFee, referral, token_contracts.arbitrum.ADDRESS_ZERO).build_transaction({'chainId': 42161, 'nonce': nonce, 'value' : executionFee,'gasPrice': Web3.to_wei('1', 'gwei')})
send_tx(MY_PRIVATE_KEY, position_router_contract, longboi)
elif (coin == "btc" and collateral == "btc"):
index_token = Web3.to_checksum_address(token_contracts.arbitrum.BTC.lower())
min_out = 0
amountIn = Web3.to_wei(amount_in * 100, 'mwei')
size_delta = Web3.to_wei(str(leverage * amount_in * price * (1.0 + slippage / 100.0)), 'tether')
print(path, ", ",index_token, ", ", ",", min_out, ", ", size_delta, ", ", is_long, ", ", execution_price, ", ", )
longboi = position_router_contract.functions.createIncreasePosition(path, index_token, amountIn, min_out, size_delta, is_long, execution_price, executionFee, referral, token_contracts.arbitrum.ADDRESS_ZERO).build_transaction({'chainId': 42161, 'nonce': nonce, 'value' : executionFee,'gasPrice': Web3.to_wei('1', 'gwei')})
send_tx(MY_PRIVATE_KEY, position_router_contract, longboi)
elif (coin == "btc" and (collateral == "usdt" or collateral == "usdc")):
index_token = Web3.to_checksum_address(token_contracts.arbitrum.BTC.lower())
min_out = Web3.to_wei(amount_in / (price * (1.0 + slippage / 100.0)) * 100, 'mwei')
amountIn = Web3.to_wei(amount_in , 'mwei')
size_delta = Web3.to_wei(str(leverage * amount_in * (1.0 + slippage / 100.0)), 'tether')
print(path, ", ",index_token, ", ", ",", min_out, ", ", size_delta, ", ", is_long, ", ", execution_price, ", ", )
longboi = position_router_contract.functions.createIncreasePosition(path, index_token, amountIn, min_out, size_delta, is_long, execution_price, executionFee, referral, token_contracts.arbitrum.ADDRESS_ZERO).build_transaction({'chainId': 42161, 'nonce': nonce, 'value' : executionFee,'gasPrice': Web3.to_wei('1', 'gwei')})
send_tx(MY_PRIVATE_KEY, position_router_contract, longboi) When running script with I've already called |
i tried to use python web3 to open long position on gmx, but keep getting errors about format:
the gmx.usdc etc are the usdc address on arbitrum and i downloaded the ABIs.
gmx_position_router_contract.functions.createIncreasePosition(
_path = [gmx.usdc, gmx.weth],
_indexToken = gmx.weth,
_amountIn = 910**6,
_minOut = 0,
_sizeDelta = 181030,
_isLong = True,
_acceptablePrice = 1670*1030,
_executionFee = 1*10**14,
_referralCode = bytes(0),
_callbackTarget = '0x0').buildTransaction(....)
web3.exceptions.ValidationError:
Could not identify the intended function with name
createIncreasePosition
, positional argument(s) of type()
and keyword argument(s) of type{'_path': <class 'list'>, '_indexToken': <class 'str'>, '_amountIn': <class 'int'>, '_minOut': <class 'int'>, '_sizeDelta': <class 'int'>, '_isLong': <class 'bool'>, '_acceptablePrice': <class 'int'>, '_executionFee': <class 'int'>, '_referralCode': <class 'bytes'>, '_callbackTarget': <class 'str'>}
.Found 1 function(s) with the name
createIncreasePosition
: ['createIncreasePosition(address[],address,uint256,uint256,uint256,bool,uint256,uint256,bytes32,address)']Function invocation failed due to no matching argument types.
is there any python example to do this:
https://gmxio.gitbook.io/gmx/contracts#opening-increasing-a-position
The text was updated successfully, but these errors were encountered: