tristero 0.1.6__py3-none-any.whl → 0.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
tristero/permit2.py CHANGED
@@ -1,5 +1,6 @@
1
+ from dataclasses import dataclass
1
2
  import logging
2
- from typing import Any, List, Optional, TypeVar, cast
3
+ from typing import Any, List, Literal, Optional, TypeVar, Union, cast
3
4
  from eth_account import Account
4
5
  from eth_account.datastructures import SignedMessage, SignedTransaction
5
6
  from eth_account.signers.base import BaseAccount
@@ -8,11 +9,7 @@ from eth_account.types import TransactionDictType
8
9
  from pydantic import BaseModel, ConfigDict, Field, field_validator
9
10
  from pydantic.alias_generators import to_camel
10
11
  from web3 import AsyncBaseProvider, AsyncWeb3
11
- from eth_typing import Address, ChecksumAddress
12
- import time
13
- import math
14
12
  import random
15
- import web3
16
13
  from web3.contract import AsyncContract
17
14
  from functools import cache, lru_cache
18
15
  import json
@@ -22,11 +19,11 @@ from importlib import resources as impresources
22
19
  from web3 import Web3
23
20
  from web3.eth import AsyncEth
24
21
 
25
- from .api import (
26
- _WRAPPED_GAS_ADDRESSES,
27
- get_quote,
28
- _PERMIT2_CONTRACT_ADDRESSES,
29
- ChainID,
22
+ from tristero.api import get_quote
23
+
24
+ from .data import (
25
+ get_permit2_addr,
26
+ get_wrapped_gas_addr,
30
27
  )
31
28
 
32
29
  logger = logging.getLogger(__name__)
@@ -35,10 +32,10 @@ P = TypeVar("P", bound=AsyncBaseProvider)
35
32
 
36
33
  PERMIT2_ABI_FILE = impresources.files("tristero.files") / "permit2_abi.json"
37
34
  ERC20_ABI_FILE = impresources.files("tristero.files") / "erc20_abi.json"
35
+
38
36
  PERMIT2_ABI = json.loads(PERMIT2_ABI_FILE.read_text())
39
37
  ERC20_ABI = json.loads(ERC20_ABI_FILE.read_text())
40
38
 
41
-
42
39
  @lru_cache(maxsize=None)
43
40
  def get_permit2(eth: AsyncEth, permit2_address: str):
44
41
  return eth.contract(
@@ -183,13 +180,13 @@ async def prepare_data_for_signature(
183
180
  if not quote.order_data.deadline:
184
181
  raise ValueError("Deadline is required in the order_data")
185
182
 
186
- from_chain = ChainID(str(sell_data.chain_id))
183
+ from_chain = str(sell_data.chain_id)
187
184
 
188
185
  deadline = quote.order_data.deadline
189
186
 
190
187
  # Handle native token address conversion
191
188
  token_address = (
192
- _WRAPPED_GAS_ADDRESSES[from_chain]
189
+ get_wrapped_gas_addr(from_chain)
193
190
  if sell_data.token.address == "native"
194
191
  else sell_data.token.address
195
192
  )
@@ -213,7 +210,7 @@ async def prepare_data_for_signature(
213
210
  )
214
211
 
215
212
  # Get Permit2 address
216
- permit2_address = _PERMIT2_CONTRACT_ADDRESSES.get(from_chain)
213
+ permit2_address = get_permit2_addr(from_chain)
217
214
  if not permit2_address:
218
215
  raise ValueError("Permit2 not deployed on this chain.")
219
216
 
@@ -322,7 +319,7 @@ async def sign_permit2(
322
319
  async def approve_permit2(
323
320
  w3: AsyncWeb3[P],
324
321
  account: LocalAccount,
325
- chain: ChainID,
322
+ chain: str,
326
323
  token_address: str,
327
324
  required_quantity: int,
328
325
  maxGas: int = 100000,
@@ -330,7 +327,7 @@ async def approve_permit2(
330
327
  wallet_address = account.address
331
328
 
332
329
  erc20 = get_erc20_contract(w3, token_address)
333
- permit2_contract = _PERMIT2_CONTRACT_ADDRESSES.get(chain)
330
+ permit2_contract = get_permit2(chain)
334
331
  current_allowance = await erc20.functions.allowance(
335
332
  wallet_address, permit2_contract
336
333
  ).call()
@@ -351,34 +348,41 @@ async def approve_permit2(
351
348
  )
352
349
 
353
350
  # Sign and send transaction
354
- signed_tx: SignedTransaction = account.sign_transaction(tx.__dict__)
351
+ tx_data = tx if isinstance(tx, dict) else tx.__dict__
352
+ signed_tx: SignedTransaction = account.sign_transaction(tx_data)
355
353
  tx_hash = await w3.eth.send_raw_transaction(signed_tx.raw_transaction)
356
354
 
357
355
  logger.debug(f"→ Approval tx hash: {tx_hash.hex()}")
358
356
  return tx_hash.hex()
359
357
 
358
+ @dataclass
359
+ class Permit2Order:
360
+ msg: SignatureData
361
+ sig: SignedMessage
360
362
 
361
- async def create_order(
363
+ async def create_permit2_order(
362
364
  w3: AsyncWeb3[P],
363
365
  account: LocalAccount,
364
- src_chain: ChainID,
366
+ src_chain: str,
365
367
  src_token: str,
366
- dst_chain: ChainID,
368
+ dst_chain: str,
367
369
  dst_token: str,
368
370
  raw_amount: int,
369
- to_address: Optional[str] = None,
370
- ):
371
- if not to_address:
372
- to_address = account.address
371
+ dst_address: str | None = None,
372
+ ) -> Permit2Order:
373
+ if not dst_address:
374
+ dst_address = account.address
373
375
  q = await get_quote(
374
376
  account.address,
375
- to_address,
377
+ dst_address,
376
378
  src_chain,
377
379
  src_token,
378
380
  dst_chain,
379
381
  dst_token,
380
382
  raw_amount,
381
383
  )
382
- await approve_permit2(w3, account, src_chain, src_token, raw_amount)
383
- # print("Quote: ", json.dumps(q))
384
- return await sign_permit2(w3.eth, account, account.address, raw_amount, q)
384
+ if q['orderType'] == 'FEATHER':
385
+ raise Exception('Feather routes unsupported for automatic trades')
386
+ _ = await approve_permit2(w3, account, src_chain, src_token, raw_amount)
387
+ msg, sig = await sign_permit2(w3.eth, account, account.address, raw_amount, q)
388
+ return Permit2Order(msg, sig)
@@ -0,0 +1,284 @@
1
+ Metadata-Version: 2.3
2
+ Name: tristero
3
+ Version: 0.2.1
4
+ Summary: Library for trading on Tristero
5
+ Author: pty1
6
+ Author-email: pty1 <pty11@proton.me>
7
+ Requires-Dist: eth-account>=0.8.0
8
+ Requires-Dist: glom>=25.12.0
9
+ Requires-Dist: httpx>=0.23.0
10
+ Requires-Dist: pydantic>=2.0.0
11
+ Requires-Dist: tenacity>=8.0.0
12
+ Requires-Dist: web3>=6.0.0
13
+ Requires-Dist: websockets>=10.0
14
+ Requires-Python: >=3.10
15
+ Description-Content-Type: text/markdown
16
+
17
+ # Tristero
18
+ [![PyPI version](https://badge.fury.io/py/tristero.svg)](https://badge.fury.io/py/tristero)
19
+ [![Python Support](https://img.shields.io/pypi/pyversions/tristero.svg)](https://pypi.org/project/tristero/)
20
+
21
+ This repository is home to Tristero's trading library.
22
+
23
+ ### Installation
24
+ ```
25
+ pip install tristero
26
+ ```
27
+
28
+ ### Quick Start
29
+
30
+ Execute a cross-chain swap in just a few lines:
31
+
32
+ ```py
33
+ import os
34
+ from tristero.client import TokenSpec, execute_swap
35
+ from eth_account import Account
36
+ from web3 import AsyncWeb3
37
+ from tristero.api import ChainID
38
+
39
+ private_key = os.getenv("EVM_PRIVATE_KEY")
40
+ account = Account.from_key(private_key)
41
+ w3 = AsyncWeb3(AsyncWeb3.AsyncHTTPProvider("https://arbitrum-one-rpc.publicnode.com"))
42
+
43
+ result = await execute_swap(
44
+ w3=w3,
45
+ account=account,
46
+ src_t=TokenSpec(chain_id=ChainID.arbitrum, token_address="0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9"), # USDT
47
+ dst_t=TokenSpec(chain_id=ChainID.base, token_address="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"), # USDC
48
+ raw_amount=10000000 # Raw token amount (multiply by 10^decimals)
49
+ )
50
+ ```
51
+
52
+ ### Usage Examples
53
+
54
+ #### Permit2 Swap (EVM-to-EVM)
55
+
56
+ Permit2 swaps enable seamless EVM-to-EVM cross-chain token transfers with gasless approvals and EIP-712 signed orders.
57
+
58
+ ```py
59
+ import os
60
+ from tristero.client import TokenSpec, execute_permit2_swap
61
+ from eth_account import Account
62
+ from web3 import AsyncWeb3
63
+ from tristero.api import ChainID
64
+
65
+ private_key = os.getenv("EVM_PRIVATE_KEY")
66
+ account = Account.from_key(private_key)
67
+ w3 = AsyncWeb3(AsyncWeb3.AsyncHTTPProvider("https://mainnet.base.org"))
68
+
69
+ # Example: USDC on Base → USDT on Avalanche
70
+ result = await execute_permit2_swap(
71
+ w3=w3,
72
+ account=account,
73
+ src_t=TokenSpec(chain_id=ChainID.base, token_address="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"), # USDC on Base
74
+ dst_t=TokenSpec(chain_id=ChainID.avalanche, token_address="0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7"), # USDT on Avalanche
75
+ raw_amount=10 * 10**6 # 10 USDC (6 decimals)
76
+ )
77
+
78
+ print(f"Swap completed: {result}")
79
+ ```
80
+
81
+ #### Feather Swap (UTXO-to-UTXO)
82
+
83
+ Feather swaps facilitate cross-chain transfers between UTXO-based chains like Bitcoin and Monero, providing a deposit address for manual fund transfers.
84
+
85
+ ```py
86
+ import asyncio
87
+ from tristero.client import TokenSpec, start_feather_swap, wait_for_feather_completion
88
+ from tristero.api import ChainID
89
+
90
+ # Example: Bitcoin → Monero
91
+ async def btc_to_xmr_swap():
92
+ # Start the swap to get a deposit address
93
+ swap_result = await start_feather_swap(
94
+ src_t=TokenSpec(chain_id=ChainID.bitcoin, token_address="native"), # BTC
95
+ dst_t=TokenSpec(chain_id=ChainID.monero, token_address="native"), # XMR
96
+ dst_addr="YOUR_XMR_RECEIVING_ADDRESS", # Your Monero destination address
97
+ raw_amount=100000 # Amount in satoshis (0.001 BTC)
98
+ )
99
+
100
+ print(f"Send {swap_result.data['amount']} satoshis to: {swap_result.deposit_address}")
101
+
102
+ # Wait for swap completion after sending funds
103
+ result = await wait_for_feather_completion(swap_result.data['id'])
104
+ print(f"Swap completed: {result}")
105
+
106
+ # Run the swap
107
+ asyncio.run(btc_to_xmr_swap())
108
+ ```
109
+
110
+ #### Two-Step Permit2 Swap
111
+
112
+ For more control, you can separate the swap initiation from monitoring:
113
+
114
+ ```py
115
+ from tristero.client import TokenSpec, start_permit2_swap, wait_for_completion_with_retry
116
+ from eth_account import Account
117
+ from web3 import AsyncWeb3
118
+ from tristero.api import ChainID
119
+
120
+ # Step 1: Start the swap
121
+ account = Account.from_key(os.getenv("EVM_PRIVATE_KEY"))
122
+ w3 = AsyncWeb3(AsyncWeb3.AsyncHTTPProvider("https://arbitrum-one-rpc.publicnode.com"))
123
+
124
+ order_id = await start_permit2_swap(
125
+ w3=w3,
126
+ account=account,
127
+ src_t=TokenSpec(chain_id=ChainID.arbitrum, token_address="0xaf88d065e77c8cC2239327C5EDb3A432268e5831"), # USDC
128
+ dst_t=TokenSpec(chain_id=ChainID.polygon, token_address="0xc2132D05D31c914a87C6611C10748AEb04B58e8F"), # USDT
129
+ raw_amount=50 * 10**6 # 50 USDC
130
+ )
131
+
132
+ print(f"Swap initiated with order ID: {order_id}")
133
+
134
+ # Step 2: Wait for completion with retry logic
135
+ result = await wait_for_completion_with_retry(order_id, feather=False)
136
+ print(f"Swap completed successfully!")
137
+ ```
138
+
139
+ ### How it works
140
+
141
+ Tristero supports two primary swap mechanisms:
142
+
143
+ #### Permit2 Swaps (EVM-to-EVM)
144
+ - **Quote & Approve** - Request a quote and approve tokens via Permit2 (gasless approval)
145
+ - **Sign & Submit** - Sign an EIP-712 order and submit for execution
146
+ - **Monitor** - Track swap progress via WebSocket updates
147
+
148
+ #### Feather Swaps (UTXO-based)
149
+ - **Quote & Deposit** - Request a quote to receive a deposit address
150
+ - **Manual Transfer** - Send funds to the provided deposit address
151
+ - **Monitor** - Track swap completion via WebSocket updates
152
+
153
+ This library provides both high-level convenience functions and lower-level components for precise control.
154
+
155
+ ### API Reference
156
+
157
+ #### Execute Full Swap
158
+ `execute_swap` handles the entire workflow automatically: quoting, signing, submitting, and monitoring.
159
+ ```py
160
+ from tristero.client import execute_swap, TokenSpec
161
+ from web3 import AsyncWeb3
162
+ from eth_account.signers.local import LocalAccount
163
+
164
+ w3 = AsyncWeb3(...) # Your Web3 provider
165
+ account: LocalAccount = ... # Your account
166
+
167
+ result = await execute_swap(
168
+ w3=w3,
169
+ account=account,
170
+ src_t=TokenSpec(chain_id=ChainID.ethereum, token_address="0xA0b8..."),
171
+ dst_t=TokenSpec(chain_id=ChainID.arbitrum, token_address="0xaf88..."),
172
+ raw_amount=10*(10**18),
173
+ retry=True,
174
+ timeout=300.0 # 5 minutes
175
+ )
176
+ ```
177
+
178
+ #### Execute Permit2 Swap
179
+ `execute_permit2_swap` handles EVM-to-EVM swaps with Permit2 integration.
180
+ ```py
181
+ from tristero.client import execute_permit2_swap, TokenSpec
182
+ from web3 import AsyncWeb3
183
+ from eth_account.signers.local import LocalAccount
184
+
185
+ w3 = AsyncWeb3(...) # Your Web3 provider
186
+ account: LocalAccount = ... # Your account
187
+
188
+ result = await execute_permit2_swap(
189
+ w3=w3,
190
+ account=account,
191
+ src_t=TokenSpec(chain_id=ChainID.base, token_address="0x833589f..."), # USDC
192
+ dst_t=TokenSpec(chain_id=ChainID.avalanche, token_address="0x9702230..."), # USDT
193
+ raw_amount=10*(10**6), # 10 USDC (6 decimals)
194
+ retry=True,
195
+ timeout=300.0 # 5 minutes
196
+ )
197
+ ```
198
+
199
+ #### Start Feather Swap
200
+ `start_feather_swap` initiates UTXO-based swaps and returns deposit information.
201
+ ```py
202
+ from tristero.client import start_feather_swap, TokenSpec
203
+
204
+ swap_result = await start_feather_swap(
205
+ src_t=TokenSpec(chain_id=ChainID.bitcoin, token_address="native"),
206
+ dst_t=TokenSpec(chain_id=ChainID.monero, token_address="native"),
207
+ dst_addr="YOUR_DESTINATION_ADDRESS",
208
+ raw_amount=100000 # Amount in smallest unit
209
+ )
210
+
211
+ deposit_address = swap_result.deposit_address
212
+ order_id = swap_result.data['id']
213
+ ```
214
+
215
+ #### Requesting a quote
216
+
217
+ `get_quote` requests a quote for a particular swap, letting you see output amounts and gas fees.
218
+
219
+ ```py
220
+ from tristero.api import get_quote, ChainID
221
+
222
+ quote = await get_quote(
223
+ from_wallet="0x1234...", # Source wallet address
224
+ to_wallet="0x5678...", # Destination wallet address
225
+ from_chain_id=ChainID.ethereum, # Source chain
226
+ from_address="0xA0b8...", # Source token address (or "native")
227
+ to_chain_id=ChainID.arbitrum, # Destination chain
228
+ to_address="0xaf88...", # Destination token address (or "native")
229
+ amount=10*(10**18), # Amount in smallest unit (wei)
230
+ )
231
+ ```
232
+
233
+ #### Creating a signed order
234
+ `create_order` creates and signs an order without submitting to be filled.
235
+
236
+ ```py
237
+ from tristero.api import get_quote, ChainID
238
+
239
+ w3 = AsyncWeb3(...) # Your Web3 provider
240
+ account: LocalAccount = ... # Your account
241
+
242
+ data, sig = await create_order(
243
+ w3,
244
+ account,
245
+ from_chain_id=ChainID.ethereum,
246
+ from_address="0xA0b8...",
247
+ to_chain_id=ChainID.arbitrum,
248
+ to_address="0xaf88...",
249
+ raw_amount=10*(10**18),
250
+ )
251
+
252
+ ```
253
+
254
+ #### Submit order
255
+
256
+ `fill_order` submits a signed order for execution.
257
+
258
+ ```py
259
+ from tristero.api import fill_order
260
+
261
+ data, sig = ... # from earlier
262
+
263
+ response = await fill_order(
264
+ signature=str(sig.signature.to_0x_hex()),
265
+ domain=data.domain.model_dump(by_alias=True, mode="json"),
266
+ message=data.message.model_dump(by_alias=True, mode="json"),
267
+ )
268
+
269
+ order_id = response['id']
270
+ ```
271
+
272
+ #### Monitoring with Built-in Functions
273
+
274
+ For convenience, use the built-in monitoring functions:
275
+
276
+ ```py
277
+ from tristero.client import wait_for_completion_with_retry
278
+
279
+ # Monitor Permit2 swap with retry logic
280
+ result = await wait_for_completion_with_retry(order_id, feather=False)
281
+
282
+ # Monitor Feather swap with retry logic
283
+ result = await wait_for_completion_with_retry(order_id, feather=True)
284
+ ```
@@ -0,0 +1,14 @@
1
+ tristero/__init__.py,sha256=hMbay3U8ovonIAH4N45Tx_U8q1MrTkS5qLrquWz_19g,624
2
+ tristero/api.py,sha256=IuCxik9GSaekWPBuaCFalYzrVQWpliS8MO8dJn2115c,2967
3
+ tristero/client.py,sha256=BkQBxFjyQ13JSHVOYlodCMbQGXYK2a-GHxQdI_6HEso,5673
4
+ tristero/config.py,sha256=_0PP2gufvq_t-gdKqDrxht2BxoWpNiGXk4m_u57WOYY,530
5
+ tristero/data.py,sha256=gKqoLOg2KQu3shqtHg-AS4kDeb7XOFMy76sIbNBIw1w,887
6
+ tristero/files/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ tristero/files/chains.json,sha256=04jFywe_V0wrS0tcjdCUHMxIutaLJ_k5ABbbmkyZ9jY,256150
8
+ tristero/files/erc20_abi.json,sha256=jvsJ6aCwhMcmo3Yy1ajt5lPl_nTRg7tv-tGj87xzTOg,12800
9
+ tristero/files/permit2_abi.json,sha256=NV0AUUA9kqFPk56njvRRzUyjBhrBncKIMd3PrSH0LCc,17817
10
+ tristero/permit2.py,sha256=CFj6DQPC8UqCcI0HH8PJHJYk8Hba-Aspokxk229R29I,11517
11
+ tristero/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ tristero-0.2.1.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
13
+ tristero-0.2.1.dist-info/METADATA,sha256=ysDNK9nnh0L5gcEFD5wgc9nbsGcASVST1RpmLe-mzJc,9007
14
+ tristero-0.2.1.dist-info/RECORD,,
@@ -1,157 +0,0 @@
1
- Metadata-Version: 2.3
2
- Name: tristero
3
- Version: 0.1.6
4
- Summary: Library for trading on Tristero
5
- Author: pty1
6
- Author-email: pty1 <pty11@proton.me>
7
- Requires-Dist: eth-account>=0.8.0
8
- Requires-Dist: httpx>=0.23.0
9
- Requires-Dist: pydantic>=2.0.0
10
- Requires-Dist: tenacity>=8.0.0
11
- Requires-Dist: web3>=6.0.0
12
- Requires-Dist: websockets>=10.0
13
- Requires-Python: >=3.10
14
- Description-Content-Type: text/markdown
15
-
16
- # Tristero
17
- [![PyPI version](https://badge.fury.io/py/tristero.svg)](https://badge.fury.io/py/tristero)
18
- [![Python Support](https://img.shields.io/pypi/pyversions/tristero.svg)](https://pypi.org/project/tristero/)
19
-
20
- This repository is home to Tristero's trading library.
21
-
22
- ### Installation
23
- ```
24
- pip install tristero
25
- ```
26
-
27
- ### Quick Start
28
-
29
- Execute a cross-chain swap in just a few lines:
30
-
31
- ```py
32
- import os
33
- from tristero.client import TokenSpec, execute_swap
34
- from eth_account import Account
35
- from web3 import AsyncWeb3
36
- from tristero.api import ChainID
37
-
38
- private_key = os.getenv("EVM_PRIVATE_KEY")
39
- account = Account.from_key(private_key)
40
- w3 = AsyncWeb3(AsyncWeb3.AsyncHTTPProvider("https://arbitrum-one-rpc.publicnode.com"))
41
-
42
- result = await execute_swap(
43
- w3=w3,
44
- account=account,
45
- src_t=TokenSpec(chain_id=ChainID.arbitrum, token_address="0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9"), # USDT
46
- dst_t=TokenSpec(chain_id=ChainID.base, token_address="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"), # USDC
47
- raw_amount=10000000 # Raw token amount (multiply by 10^decimals)
48
- )
49
- ```
50
-
51
- ### How it works
52
-
53
- Tristero swaps happen in two steps:
54
- - **Quote & Sign** - Request a quote from the server and sign it with your private key
55
- - **Submit & Fill** - Submit the signed order to be filled at a later date
56
-
57
- This library provides both high-level convenience functions and lower-level components for precise control.
58
-
59
- ### API Reference
60
-
61
- #### Execute Full Swap
62
- `execute_swap` handles the entire workflow automatically: quoting, signing, submitting, and monitoring.
63
- ```py
64
- from tristero.swap import execute_swap, TokenSpec
65
- from web3 import AsyncWeb3
66
- from eth_account.signers.local import LocalAccount
67
-
68
- w3 = AsyncWeb3(...) # Your Web3 provider
69
- account: LocalAccount = ... # Your account
70
-
71
- result = await execute_swap(
72
- w3=w3,
73
- account=account,
74
- src_t=TokenSpec(chain_id=ChainID.ethereum, token_address="0xA0b8..."),
75
- dst_t=TokenSpec(chain_id=ChainID.arbitrum, token_address="0xaf88..."),
76
- raw_amount=10*(10**18),
77
- retry=True,
78
- timeout=300.0 # 5 minutes
79
- )
80
- ```
81
-
82
- #### Requesting a quote
83
-
84
- `get_quote` requests a quote for a particular swap, letting you see output amounts and gas fees.
85
-
86
- ```py
87
- from tristero.api import get_quote, ChainID
88
-
89
- quote = await get_quote(
90
- from_wallet="0x1234...", # Source wallet address
91
- to_wallet="0x5678...", # Destination wallet address
92
- from_chain_id=ChainID.ethereum, # Source chain
93
- from_address="0xA0b8...", # Source token address (or "native")
94
- to_chain_id=ChainID.arbitrum, # Destination chain
95
- to_address="0xaf88...", # Destination token address (or "native")
96
- amount=10*(10**18), # Amount in smallest unit (wei)
97
- )
98
- ```
99
-
100
- #### Creating a signed order
101
- `create_order` creates and signs an order without submitting to be filled.
102
-
103
- ```py
104
- from tristero.api import get_quote, ChainID
105
-
106
- w3 = AsyncWeb3(...) # Your Web3 provider
107
- account: LocalAccount = ... # Your account
108
-
109
- data, sig = await create_order(
110
- w3,
111
- account,
112
- from_chain_id=ChainID.ethereum,
113
- from_address="0xA0b8...",
114
- to_chain_id=ChainID.arbitrum,
115
- to_address="0xaf88...",
116
- raw_amount=10*(10**18),
117
- )
118
-
119
- ```
120
-
121
- #### Submit order
122
-
123
- `fill_order` submits a signed order for execution.
124
-
125
- ```py
126
- from tristero.api import fill_order
127
-
128
- data, sig = ... # from earlier
129
-
130
- response = await fill_order(
131
- signature=str(sig.signature.to_0x_hex()),
132
- domain=data.domain.model_dump(by_alias=True, mode="json"),
133
- message=data.message.model_dump(by_alias=True, mode="json"),
134
- )
135
-
136
- order_id = response['id']
137
- ```
138
-
139
- #### Subscribing for updates
140
-
141
- Orders can be monitored for changes and status live
142
-
143
- ```py
144
- from tristero.api import poll_updates
145
- import json
146
-
147
- ws = await poll_updates(order_id)
148
-
149
- async for msg in ws:
150
- update = json.loads(msg)
151
- print(f"Completed: {update['completed']}")
152
- print(f"Failed: {update['failed']}")
153
-
154
- if update["completed"] or update["failed"]:
155
- await ws.close()
156
- break
157
- ```
@@ -1,12 +0,0 @@
1
- tristero/__init__.py,sha256=Jmbdg3LwOD4rrO0eerQTmn-wO-Sr4xRZ2r_RtM4iNDg,315
2
- tristero/api.py,sha256=E5CyEbEZjeEpptJ2C5570g-ZD02PWE73USTz5v-uKss,5520
3
- tristero/client.py,sha256=nro5d9z5cAZOWSgF3s43UcFPMrTqbFk4DxIWo14u7-Y,4086
4
- tristero/config.py,sha256=_0PP2gufvq_t-gdKqDrxht2BxoWpNiGXk4m_u57WOYY,530
5
- tristero/files/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- tristero/files/erc20_abi.json,sha256=jvsJ6aCwhMcmo3Yy1ajt5lPl_nTRg7tv-tGj87xzTOg,12800
7
- tristero/files/permit2_abi.json,sha256=NV0AUUA9kqFPk56njvRRzUyjBhrBncKIMd3PrSH0LCc,17817
8
- tristero/permit2.py,sha256=9uEgwwBfYnEzkbIv0jbLybXnthdzHPrZ-gAzzg_a6j4,11338
9
- tristero/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- tristero-0.1.6.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
11
- tristero-0.1.6.dist-info/METADATA,sha256=T4Bd4sXht1JQmLFancmnJxoZ-9r44d7N-sk3DvNcTEI,4384
12
- tristero-0.1.6.dist-info/RECORD,,