Skip to content

Commit e4ae516

Browse files
Maya trade accounts (#1509)
* feat(mayanode): regenerate API types with trade endpoints Regenerated Maya API types from stagenet OpenAPI spec to include: - TradeAccountApi and TradeAccountsApi for individual/all trade accounts - TradeUnitApi and TradeUnitsApi for trade asset units - Related interfaces and types for trade functionality * feat(mayachain-query): add trade query functionality - Add trade-related types to support trade accounts and units - Integrate generated trade API clients into Mayanode utility - Implement trade query methods (already existed in MayachainQuery) - Support querying trade accounts by address or asset - Support querying trade asset units * test(mayachain-query): add trade query tests and mocks - Add mock responses for trade accounts and trade units - Add unit tests for trade query functionality - Add e2e tests for trade operations - Update mock API to handle trade endpoints * feat(mayachain-amm): add trade asset swap validation - Import isTradeAsset and eqAsset utilities from xchain-util - Add validation logic to prevent invalid trade asset swaps - Validate swaps from non-trade to trade assets (require TRADE+) - Validate swaps from trade to non-trade assets (require TRADE-) - Use AssetCacao as the native asset for validation (instead of Rune) * test(mayachain-amm): add comprehensive trade tests - Add unit tests for trade account operations (add/withdraw) - Add validation tests for trade asset swaps - Add estimate swap test to verify quote functionality - Add e2e tests matching THORChain's test pattern - Update mocks to support trade functionality * docs: update READMEs with trade functionality examples - Add trade account operation examples to mayachain-amm README - Add trade query examples to mayachain-query README - Document TRADE+ and TRADE- memo formats - Include code examples for all trade operations * fix: resolve lint and formatting issues - Remove unused Network import from trade.test.ts - Fix prettier formatting issues across all trade files - Ensure consistent code style with project standards * fix: address CodeRabbit review comments - Extract duplicate asset type conversion logic into reusable method - Add validation for negative withdrawal amounts - Add missing newlines at end of files - Update wallet.getAddress calls to include walletIndex parameter - Add comment to clarify stub mock purpose * fix: resolve TypeScript build errors - Revert to inline asset type conversion to avoid type conflicts - Maintain the same functionality without extracted method - Fixes CI/CD build pipeline failure * Changeset * fix: improve regex patterns for mock endpoints - Update trade unit endpoint regex to require asset parameter - Add terminal anchor to trade units endpoint to prevent false matches - Update trade account endpoints to require parameters - Addresses CodeRabbit review comment about regex specificity * Add missing trade logic for mayachain package * changeset for xchain-mayachain * Update packages/xchain-mayachain-amm/TRADE_OPERATIONS.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update packages/xchain-mayachain-amm/src/types.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
1 parent cf87eec commit e4ae516

File tree

34 files changed

+2866
-110
lines changed

34 files changed

+2866
-110
lines changed

.changeset/rich-baboons-itch.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@xchainjs/xchain-mayachain-query': minor
3+
'@xchainjs/xchain-mayachain-amm': minor
4+
'@xchainjs/xchain-mayanode': minor
5+
---
6+
7+
Trade accounts functionality was added

.changeset/ten-grapes-move.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@xchainjs/xchain-mayachain': major
3+
---
4+
5+
Add trade account support
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# Manual Deposit Transaction Example
2+
3+
This example shows how to create a deposit transaction manually using the `@xchainjs/xchain-mayachain` package directly.
4+
5+
## Example Code
6+
7+
```typescript
8+
import { Client as MayaClient } from '@xchainjs/xchain-mayachain'
9+
import { Network } from '@xchainjs/xchain-client'
10+
import { assetToBase, assetAmount, baseAmount } from '@xchainjs/xchain-util'
11+
12+
async function createManualDepositTx() {
13+
// Initialize Maya client with phrase
14+
const phrase = 'your twelve word mnemonic phrase here'
15+
16+
const mayaClient = new MayaClient({
17+
phrase,
18+
network: Network.Mainnet,
19+
// Optional: specify custom RPC endpoints if needed
20+
// clientUrls: {
21+
// [Network.Mainnet]: ['https://tendermint.mayachain.info']
22+
// }
23+
})
24+
25+
try {
26+
// Get your Maya address
27+
const address = await mayaClient.getAddressAsync()
28+
console.log('Your Maya address:', address)
29+
30+
// Create deposit parameters
31+
const depositParams = {
32+
walletIndex: 0,
33+
asset: assetFromStringEx('ETH.ETH'), // The asset you're depositing
34+
amount: assetToBase(assetAmount('0.1', 8)), // Amount in base units
35+
memo: 'TRADE+:maya1youraddress', // Your trade memo
36+
}
37+
38+
// Make the deposit transaction
39+
const txHash = await mayaClient.deposit(depositParams)
40+
console.log('Transaction hash:', txHash)
41+
42+
// Get transaction URL
43+
const txUrl = await mayaClient.getExplorerTxUrl(txHash)
44+
console.log('Transaction URL:', txUrl)
45+
46+
} catch (error) {
47+
console.error('Error creating deposit:', error)
48+
}
49+
}
50+
51+
// Alternative: Using transfer method directly
52+
async function createManualTransferTx() {
53+
const phrase = 'your twelve word mnemonic phrase here'
54+
55+
const mayaClient = new MayaClient({
56+
phrase,
57+
network: Network.Mainnet,
58+
})
59+
60+
try {
61+
const address = await mayaClient.getAddressAsync()
62+
63+
// For TRADE+ operations, you typically send to the same address with a memo
64+
const txParams = {
65+
walletIndex: 0,
66+
asset: assetFromStringEx('MAYA.CACAO'), // Native asset
67+
amount: assetToBase(assetAmount('1', 10)), // 1 CACAO (10 decimals)
68+
recipient: address, // Send to yourself for trade operations
69+
memo: 'TRADE+:maya1youraddress', // Trade memo
70+
}
71+
72+
const txHash = await mayaClient.transfer(txParams)
73+
console.log('Transaction hash:', txHash)
74+
75+
} catch (error) {
76+
console.error('Error creating transfer:', error)
77+
}
78+
}
79+
80+
// For checking balances before operation
81+
async function checkBalance() {
82+
const mayaClient = new MayaClient({
83+
network: Network.Mainnet,
84+
// No phrase needed for read-only operations
85+
})
86+
87+
const address = 'maya1youraddress'
88+
const balances = await mayaClient.getBalance(address)
89+
90+
balances.forEach(balance => {
91+
console.log(`${balance.asset.symbol}: ${balance.amount.amount().toString()}`)
92+
})
93+
}
94+
```
95+
96+
## Important Notes
97+
98+
1. **Mnemonic Phrase**: The client MUST be initialized with a mnemonic phrase to sign transactions. Without it, you'll get "No clients available" error.
99+
100+
2. **Network**: Make sure the network matches your intended target (Mainnet, Stagenet).
101+
102+
3. **Memo Format**: For trade operations:
103+
- Add to trade: `TRADE+:address`
104+
- Withdraw from trade: `TRADE-:address`
105+
106+
4. **Asset Format**: Use the correct asset format:
107+
- Native: `MAYA.CACAO`
108+
- Trade assets: `ETH~ETH`, `BTC~BTC`, etc.
109+
110+
5. **Error Handling**: The client will throw errors if:
111+
- No RPC endpoints are available
112+
- Invalid memo format
113+
- Insufficient balance
114+
- Network issues
115+
116+
## Debugging Connection Issues
117+
118+
If you're getting "No clients available" errors:
119+
120+
```typescript
121+
// Test connection to RPC endpoints
122+
async function testConnection() {
123+
const mayaClient = new MayaClient({
124+
phrase: 'your phrase',
125+
network: Network.Mainnet,
126+
})
127+
128+
try {
129+
// Try to get network info
130+
const network = mayaClient.getNetwork()
131+
console.log('Network:', network)
132+
133+
// Try to get address (requires working client)
134+
const address = await mayaClient.getAddressAsync()
135+
console.log('Address:', address)
136+
137+
// Try to get balance (requires RPC connection)
138+
const balances = await mayaClient.getBalance(address)
139+
console.log('Balance check successful')
140+
141+
} catch (error) {
142+
console.error('Connection test failed:', error)
143+
}
144+
}
145+
```

packages/xchain-mayachain-amm/README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,19 @@ Otherwise, if you want to be able make actions the protocol needs you to sign, y
4545
import { MayachainAMM } from '@xchainjs/xchain-mayachain-amm'
4646
import { MayachainQuery } from '@xchainjs/xchain-mayachain-query'
4747
import { Wallet } from '@xchainjs/xchain-wallet'
48+
import { Client as MayaClient } from '@xchainjs/xchain-mayachain'
4849

50+
const phrase = 'your mnemonic phrase here'
4951
const mayaChainQuery = new MayachainQuery()
5052
const wallet = new Wallet({
51-
// Your XChainJS clients
53+
MAYA: new MayaClient({ phrase, network: Network.Mainnet }),
54+
// Add other clients with phrases as needed
5255
})
5356
const mayachainAmm = new MayachainAMM(mayaChainQuery, wallet)
5457
```
5558

59+
**Important**: All clients in the wallet MUST be initialized with a mnemonic phrase to sign transactions. Without a phrase, you'll get the error: "No clients available. Can not sign and broadcast transaction"
60+
5661
## Features
5762

5863
Using MAYAChain AMM package, you could easily implement the following features
@@ -68,6 +73,12 @@ Using MAYAChain AMM package, you could easily implement the following features
6873
- Get MAYAName details
6974
- Get MAYANames by owner
7075

76+
### Trade Accounts
77+
78+
- Add assets to trade accounts
79+
- Withdraw assets from trade accounts
80+
- Estimate add/withdraw operations
81+
7182
## Examples
7283

7384
You can find examples using the MAYAChain AMM package in the [mayachain-amm](https://github.com/xchainjs/xchainjs-lib/tree/master/examples/mayachain-amm) examples folder.
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Trade Account Operations Guide
2+
3+
## Important: Wallet Initialization for Trade Operations
4+
5+
When performing trade operations that require broadcasting transactions (addToTradeAccount, withdrawFromTradeAccount), you MUST initialize the wallet with a mnemonic phrase. Without a phrase, the client cannot sign transactions and will throw the error: "No clients available. Can not sign and broadcast deposit transaction".
6+
7+
### Correct Initialization for Trade Operations
8+
9+
import { MayachainAMM } from '@xchainjs/xchain-mayachain-amm'
10+
import { MayachainQuery } from '@xchainjs/xchain-mayachain-query'
11+
import { Wallet } from '@xchainjs/xchain-wallet'
12+
import { Client as EthClient, defaultEthParams } from '@xchainjs/xchain-ethereum'
13+
import { Client as MayaClient } from '@xchainjs/xchain-mayachain'
14+
import { Network } from '@xchainjs/xchain-client'
15+
import {
16+
assetToBase,
17+
assetAmount,
18+
assetFromStringEx,
19+
AssetCryptoAmount,
20+
} from '@xchainjs/xchain-util'
21+
// Your mnemonic phrase (keep this secure!)
22+
const phrase = 'your twelve word mnemonic phrase here ...'
23+
24+
// Initialize MayaChain query
25+
const mayachainQuery = new MayachainQuery()
26+
27+
// Initialize wallet with clients that have the phrase
28+
const wallet = new Wallet({
29+
ETH: new EthClient({
30+
...defaultEthParams,
31+
phrase, // IMPORTANT: Include phrase for signing
32+
network: Network.Mainnet
33+
}),
34+
MAYA: new MayaClient({
35+
phrase, // IMPORTANT: Include phrase for signing
36+
network: Network.Mainnet
37+
}),
38+
// Add other clients as needed with their phrases
39+
})
40+
41+
// Initialize MayachainAMM
42+
const mayachainAmm = new MayachainAMM(mayachainQuery, wallet)
43+
44+
// Now you can perform trade operations
45+
async function addToTradeAccount() {
46+
try {
47+
const result = await mayachainAmm.addToTradeAccount({
48+
amount: new AssetCryptoAmount(
49+
assetToBase(assetAmount('0.1')),
50+
assetFromStringEx('ETH.ETH')
51+
),
52+
address: 'maya1...', // Your Maya address
53+
})
54+
console.log('Transaction hash:', result.hash)
55+
} catch (error) {
56+
console.error('Error:', error.message)
57+
}
58+
}
59+
```
60+
61+
### Read-Only Operations (No Phrase Required)
62+
63+
For read-only operations like estimating trades, you can use the default initialization:
64+
65+
```typescript
66+
const mayachainAmm = new MayachainAMM()
67+
68+
// Estimate operations work without a phrase
69+
const estimate = await mayachainAmm.estimateAddToTradeAccount({
70+
amount: new AssetCryptoAmount(
71+
assetToBase(assetAmount('0.1')),
72+
assetFromStringEx('ETH.ETH')
73+
),
74+
address: 'maya1...',
75+
})
76+
```
77+
78+
## Common Issues
79+
80+
1. **"No clients available" Error**: This occurs when trying to broadcast a transaction without providing a mnemonic phrase to the client.
81+
82+
2. **Network Mismatch**: Ensure all clients are initialized with the same network (Mainnet, Stagenet, etc.)
83+
84+
3. **Missing Client**: Make sure the wallet has a client for the chain you're trying to trade (e.g., ETH client for ETH trades)
85+
86+
## Best Practices
87+
88+
1. Never hardcode your mnemonic phrase in production code
89+
2. Use environment variables or secure key management systems
90+
3. Always validate addresses before performing operations
91+
4. Check operation estimates before executing trades
92+
5. Handle errors gracefully and provide meaningful feedback to users

0 commit comments

Comments
 (0)