<p align="center">
<img height="80px" width="80px" src="https://ipor.io/images/ipor-fusion.svg" alt="IPOR Fusion Python SDK"/>
<h1 align="center">IPOR Fusion Python SDK</h1>
</p>
`ipor_fusion` package is the official IPOR Fusion Software Development Kit (SDK) for Python. It allows Python
developers to
write software, that interacts with **IPOR Fusion Plasma Vaults** smart contracts deployed on Ethereum Virtual
Machine (EVM) blockchains.
`ipor-fusion.py` repository is maintained by <a href="https://ipor.io">IPOR Labs AG</a>.
<table>
<tr>
<td><strong>Workflow</strong></td>
<td>
<a href="https://github.com/IPOR-Labs/ipor-fusion.py/actions/workflows/ci.yml">
<img src="https://github.com/IPOR-Labs/ipor-fusion.py/actions/workflows/ci.yml/badge.svg" alt="CI">
</a>
<a href="https://github.com/IPOR-Labs/ipor-fusion.py/actions/workflows/cd.yml">
<img src="https://github.com/IPOR-Labs/ipor-fusion.py/actions/workflows/cd.yml/badge.svg" alt="CD">
</a>
</td>
</tr>
<tr>
<td><strong>Social</strong></td>
<td>
<a href="https://discord.com/invite/bSKzq6UMJ3">
<img alt="Chat on Discord" src="https://img.shields.io/discord/832532271734587423?logo=discord&logoColor=white">
</a>
<a href="https://x.com/ipor_io">
<img alt="X (formerly Twitter) URL" src="https://img.shields.io/twitter/url?url=https%3A%2F%2Fx.com%2Fipor_io&style=flat&logo=x&label=%40ipor_io&color=green">
</a>
<a href="https://t.me/IPOR_official_broadcast">
<img alt="IPOR Official Broadcast" src="https://img.shields.io/badge/-t?logo=telegram&logoColor=white&logoSize=%3D&label=ipor">
</a>
</td>
</tr>
<tr>
<td><strong>Code</strong></td>
<td>
<a href="https://pypi.org/project/ipor-fusion">
<img alt="PyPI version" src="https://img.shields.io/pypi/v/ipor-fusion?color=blue">
</a>
<a href="https://github.com/IPOR-Labs/ipor-fusion.py/blob/main/LICENSE">
<img alt="GitHub License" src="https://img.shields.io/github/license/IPOR-Labs/ipor-fusion?color=blue">
</a>
<a href="https://github.com/IPOR-Labs/ipor-fusion.py/blob/main/pyproject.toml">
<img alt="Python Version" src="https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2FIPOR-Labs%2Fipor-fusion.py%2Frefs%2Fheads%2Fmain%2Fpyproject.toml">
</a>
<a href="https://github.com/IPOR-Labs/ipor-fusion.py/blob/main/pyproject.toml">
<img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg">
</a>
</td>
</tr>
</table>
#### Install dependencies
```bash
poetry install
```
#### Setup ARBITRUM_PROVIDER_URL environment variable
Some node providers are not supported. It's working with QuickNode but not with Alchemy.
```bash
export ARBITRUM_PROVIDER_URL="https://..."
```
#### Run tests
```bash
poetry run pytest -v -s
```
#### Run pylint
```bash
poetry run pylint --rcfile=pylintrc.toml --verbose --recursive=y .
```
#### Run black
```bash
poetry run black ./
```
## Example of usage
```python
ALPHA_WALLET="0x..."
uniswap_v3_swap_fuse = UniswapV3SwapFuse(ARBITRUM.PILOT.V5.UNISWAP_V3_SWAP_FUSE)
ramses_v2_new_position_fuse = RamsesV2NewPositionFuse(ARBITRUM.PILOT.V5.RAMSES_V2_NEW_POSITION_FUSE)
ramses_claim_fuse = RamsesClaimFuse(ARBITRUM.PILOT.V5.RAMSES_CLAIM_FUSE)
plasma_vault = PlasmaVault(ARBITRUM.PILOT.V5.PLASMA_VAULT)
rewards_claim_manager = RewardsClaimManager(ARBITRUM.PILOT.V5.REWARDS_CLAIM_MANAGER)
swap = uniswap_v3_swap_fuse.swap(
token_in_address=ARBITRUM.USDC,
token_out_address=ARBITRUM.USDT,
fee=100,
token_in_amount=int(500e6),
min_out_amount=0,
)
new_position = ramses_v2_new_position_fuse.new_position(
token0=ARBITRUM.USDC,
token1=ARBITRUM.USDT,
fee=50,
tick_lower=-100,
tick_upper=100,
amount0_desired=int(499e6),
amount1_desired=int(499e6),
amount0_min=0,
amount1_min=0,
deadline=int(time.time()) + 100,
ve_ram_token_id=0,
)
tx_result = plasma_vault.execute([swap, new_position])
(_, new_token_id, _, _, _, _, _, _, _, _,) = ramses_v2_new_position_fuse.extract_data_form_new_position_enter_event(
tx_result
)
claim_action = ramses_claim_fuse.claim(
token_ids=[new_token_id],
token_rewards=[[ARBITRUM.RAMSES.V2.RAM, ARBITRUM.RAMSES.V2.X_REM]],
)
# some time later ... claim RAM rewards
rewards_claim_manager.claim_rewards([claim_action])
ram_after_claim = rewards_claim_manager.balance_of(ARBITRUM.RAMSES.V2.RAM)
assert ram_after_claim > 0
# Transfer REM to ALPHA wallet
rewards_claim_manager.transfer(
ARBITRUM.RAMSES.V2.RAM, ALPHA_WALLET, ram_after_claim
)
ram_after_transfer = ram.balance_of(ALPHA_WALLET)
assert ram_after_transfer > 0
usdc_before_swap_ram = usdc.balance_of(ALPHA_WALLET)
# swap RAM -> USDC
path = [ARBITRUM.RAMSES.V2.RAM, 10000, ARBITRUM.WETH, 500, ARBITRUM.USDC]
uniswap_v3_universal_router.swap(ARBITRUM.RAMSES.V2.RAM, path, ram_after_transfer)
usdc_after_swap_ram = usdc.balance_of(ALPHA_WALLET)
rewards_in_usdc = usdc_after_swap_ram - usdc_before_swap_ram
assert rewards_in_usdc > 0
# Transfer USDC to rewards_claim_manager
usdc.transfer(to=ARBITRUM.PILOT.V5.REWARDS_CLAIM_MANAGER, amount=rewards_in_usdc)
usdc_after_transfer = usdc.balance_of(ALPHA_WALLET)
assert usdc_after_transfer == 0
# Update balance on rewards_claim_manager
rewards_claim_manager.update_balance()
rewards_claim_manager_balance_before_vesting = rewards_claim_manager.balance_of(
ARBITRUM.USDC
)
assert rewards_claim_manager_balance_before_vesting > 0
rewards_claim_manager.update_balance()
# One month later
anvil.move_time(DAY)
rewards_claim_manager.update_balance()
rewards_claim_manager_balance_after_vesting = rewards_claim_manager.balance_of(
ARBITRUM.USDC
)
assert rewards_claim_manager_balance_after_vesting == 0
```
Raw data
{
"_id": null,
"home_page": "https://ipor.io",
"name": "ipor-fusion",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.10",
"maintainer_email": null,
"keywords": "ethereum, solidity, testing, development, framework",
"author": "Adam Mydlarz",
"author_email": "amydlarz@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/e8/55/4a384e447b42c1994e1c665016f53febd4f8d6a9ed27d1e51bb6f6bee7bb/ipor_fusion-0.1.0.tar.gz",
"platform": null,
"description": "<p align=\"center\">\n <img height=\"80px\" width=\"80px\" src=\"https://ipor.io/images/ipor-fusion.svg\" alt=\"IPOR Fusion Python SDK\"/>\n <h1 align=\"center\">IPOR Fusion Python SDK</h1>\n</p>\n\n`ipor_fusion` package is the official IPOR Fusion Software Development Kit (SDK) for Python. It allows Python \ndevelopers to \nwrite software, that interacts with **IPOR Fusion Plasma Vaults** smart contracts deployed on Ethereum Virtual \nMachine (EVM) blockchains.\n\n`ipor-fusion.py` repository is maintained by <a href=\"https://ipor.io\">IPOR Labs AG</a>.\n\n<table>\n <tr>\n <td><strong>Workflow</strong></td>\n <td>\n <a href=\"https://github.com/IPOR-Labs/ipor-fusion.py/actions/workflows/ci.yml\">\n <img src=\"https://github.com/IPOR-Labs/ipor-fusion.py/actions/workflows/ci.yml/badge.svg\" alt=\"CI\">\n </a>\n <a href=\"https://github.com/IPOR-Labs/ipor-fusion.py/actions/workflows/cd.yml\">\n <img src=\"https://github.com/IPOR-Labs/ipor-fusion.py/actions/workflows/cd.yml/badge.svg\" alt=\"CD\">\n </a>\n </td>\n </tr>\n <tr>\n <td><strong>Social</strong></td>\n <td>\n <a href=\"https://discord.com/invite/bSKzq6UMJ3\">\n <img alt=\"Chat on Discord\" src=\"https://img.shields.io/discord/832532271734587423?logo=discord&logoColor=white\">\n </a>\n <a href=\"https://x.com/ipor_io\">\n <img alt=\"X (formerly Twitter) URL\" src=\"https://img.shields.io/twitter/url?url=https%3A%2F%2Fx.com%2Fipor_io&style=flat&logo=x&label=%40ipor_io&color=green\">\n </a>\n <a href=\"https://t.me/IPOR_official_broadcast\">\n <img alt=\"IPOR Official Broadcast\" src=\"https://img.shields.io/badge/-t?logo=telegram&logoColor=white&logoSize=%3D&label=ipor\">\n </a>\n </td>\n </tr>\n <tr>\n <td><strong>Code</strong></td>\n <td>\n <a href=\"https://pypi.org/project/ipor-fusion\">\n <img alt=\"PyPI version\" src=\"https://img.shields.io/pypi/v/ipor-fusion?color=blue\">\n </a>\n <a href=\"https://github.com/IPOR-Labs/ipor-fusion.py/blob/main/LICENSE\">\n <img alt=\"GitHub License\" src=\"https://img.shields.io/github/license/IPOR-Labs/ipor-fusion?color=blue\">\n </a>\n <a href=\"https://github.com/IPOR-Labs/ipor-fusion.py/blob/main/pyproject.toml\">\n <img alt=\"Python Version\" src=\"https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2FIPOR-Labs%2Fipor-fusion.py%2Frefs%2Fheads%2Fmain%2Fpyproject.toml\">\n </a>\n <a href=\"https://github.com/IPOR-Labs/ipor-fusion.py/blob/main/pyproject.toml\">\n <img alt=\"Code style: black\" src=\"https://img.shields.io/badge/code%20style-black-000000.svg\">\n </a>\n </td>\n </tr>\n</table>\n\n#### Install dependencies\n\n```bash\npoetry install\n```\n\n#### Setup ARBITRUM_PROVIDER_URL environment variable\n\nSome node providers are not supported. It's working with QuickNode but not with Alchemy.\n\n```bash\nexport ARBITRUM_PROVIDER_URL=\"https://...\"\n```\n\n#### Run tests\n\n```bash\npoetry run pytest -v -s\n```\n\n#### Run pylint\n\n```bash \npoetry run pylint --rcfile=pylintrc.toml --verbose --recursive=y .\n```\n\n#### Run black\n\n```bash \npoetry run black ./\n```\n\n## Example of usage\n\n```python\nALPHA_WALLET=\"0x...\"\n\nuniswap_v3_swap_fuse = UniswapV3SwapFuse(ARBITRUM.PILOT.V5.UNISWAP_V3_SWAP_FUSE)\nramses_v2_new_position_fuse = RamsesV2NewPositionFuse(ARBITRUM.PILOT.V5.RAMSES_V2_NEW_POSITION_FUSE)\nramses_claim_fuse = RamsesClaimFuse(ARBITRUM.PILOT.V5.RAMSES_CLAIM_FUSE)\nplasma_vault = PlasmaVault(ARBITRUM.PILOT.V5.PLASMA_VAULT)\nrewards_claim_manager = RewardsClaimManager(ARBITRUM.PILOT.V5.REWARDS_CLAIM_MANAGER)\n\nswap = uniswap_v3_swap_fuse.swap(\n token_in_address=ARBITRUM.USDC,\n token_out_address=ARBITRUM.USDT,\n fee=100,\n token_in_amount=int(500e6),\n min_out_amount=0,\n)\n\nnew_position = ramses_v2_new_position_fuse.new_position(\n token0=ARBITRUM.USDC,\n token1=ARBITRUM.USDT,\n fee=50,\n tick_lower=-100,\n tick_upper=100,\n amount0_desired=int(499e6),\n amount1_desired=int(499e6),\n amount0_min=0,\n amount1_min=0,\n deadline=int(time.time()) + 100,\n ve_ram_token_id=0,\n)\n\ntx_result = plasma_vault.execute([swap, new_position])\n\n(_, new_token_id, _, _, _, _, _, _, _, _,) = ramses_v2_new_position_fuse.extract_data_form_new_position_enter_event(\n tx_result\n)\n\nclaim_action = ramses_claim_fuse.claim(\n token_ids=[new_token_id],\n token_rewards=[[ARBITRUM.RAMSES.V2.RAM, ARBITRUM.RAMSES.V2.X_REM]],\n)\n\n# some time later ... claim RAM rewards\nrewards_claim_manager.claim_rewards([claim_action])\n\nram_after_claim = rewards_claim_manager.balance_of(ARBITRUM.RAMSES.V2.RAM)\n\nassert ram_after_claim > 0\n\n# Transfer REM to ALPHA wallet\nrewards_claim_manager.transfer(\n ARBITRUM.RAMSES.V2.RAM, ALPHA_WALLET, ram_after_claim\n)\n\nram_after_transfer = ram.balance_of(ALPHA_WALLET)\nassert ram_after_transfer > 0\n\nusdc_before_swap_ram = usdc.balance_of(ALPHA_WALLET)\n\n# swap RAM -> USDC\npath = [ARBITRUM.RAMSES.V2.RAM, 10000, ARBITRUM.WETH, 500, ARBITRUM.USDC]\nuniswap_v3_universal_router.swap(ARBITRUM.RAMSES.V2.RAM, path, ram_after_transfer)\n\nusdc_after_swap_ram = usdc.balance_of(ALPHA_WALLET)\n\nrewards_in_usdc = usdc_after_swap_ram - usdc_before_swap_ram\nassert rewards_in_usdc > 0\n\n# Transfer USDC to rewards_claim_manager\nusdc.transfer(to=ARBITRUM.PILOT.V5.REWARDS_CLAIM_MANAGER, amount=rewards_in_usdc)\n\nusdc_after_transfer = usdc.balance_of(ALPHA_WALLET)\nassert usdc_after_transfer == 0\n\n# Update balance on rewards_claim_manager\nrewards_claim_manager.update_balance()\nrewards_claim_manager_balance_before_vesting = rewards_claim_manager.balance_of(\n ARBITRUM.USDC\n)\nassert rewards_claim_manager_balance_before_vesting > 0\n\nrewards_claim_manager.update_balance()\n\n# One month later\nanvil.move_time(DAY)\nrewards_claim_manager.update_balance()\n\nrewards_claim_manager_balance_after_vesting = rewards_claim_manager.balance_of(\n ARBITRUM.USDC\n)\n\nassert rewards_claim_manager_balance_after_vesting == 0\n```\n",
"bugtrack_url": null,
"license": "BSD-3",
"summary": "The IPOR Fusion SDK for Python",
"version": "0.1.0",
"project_urls": {
"Documentation": "https://docs.ipor.io/ipor-fusion/fusion-introduction",
"Homepage": "https://ipor.io",
"Repository": "https://github.com/IPOR-Labs/ipor-fusion.py"
},
"split_keywords": [
"ethereum",
" solidity",
" testing",
" development",
" framework"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "7c86bc07b3e053c84d3a7fbac1635666b38693783467033fd1b5897909d38628",
"md5": "4b91a92ea0f21817f66f3549d75b29f5",
"sha256": "63672187a6b29ed59f01d96d6743ddaaf445f12e6a1acc254984fe15f451f064"
},
"downloads": -1,
"filename": "ipor_fusion-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "4b91a92ea0f21817f66f3549d75b29f5",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.10",
"size": 25060,
"upload_time": "2024-10-29T03:26:21",
"upload_time_iso_8601": "2024-10-29T03:26:21.030412Z",
"url": "https://files.pythonhosted.org/packages/7c/86/bc07b3e053c84d3a7fbac1635666b38693783467033fd1b5897909d38628/ipor_fusion-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "e8554a384e447b42c1994e1c665016f53febd4f8d6a9ed27d1e51bb6f6bee7bb",
"md5": "a08df7d5fbad4e27407efc79eef49489",
"sha256": "db5ac42f6b09df310501fe5255dc05c50a877b3a94369810f9fcdc7886fb5afc"
},
"downloads": -1,
"filename": "ipor_fusion-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "a08df7d5fbad4e27407efc79eef49489",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.10",
"size": 15042,
"upload_time": "2024-10-29T03:26:22",
"upload_time_iso_8601": "2024-10-29T03:26:22.729482Z",
"url": "https://files.pythonhosted.org/packages/e8/55/4a384e447b42c1994e1c665016f53febd4f8d6a9ed27d1e51bb6f6bee7bb/ipor_fusion-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-29 03:26:22",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "IPOR-Labs",
"github_project": "ipor-fusion.py",
"github_not_found": true,
"lcname": "ipor-fusion"
}