diff --git a/src/Managing.Web3Proxy/src/generated/gmxsdk/utils/callContract.ts b/src/Managing.Web3Proxy/src/generated/gmxsdk/utils/callContract.ts index f788da56..6b14ebd9 100644 --- a/src/Managing.Web3Proxy/src/generated/gmxsdk/utils/callContract.ts +++ b/src/Managing.Web3Proxy/src/generated/gmxsdk/utils/callContract.ts @@ -1,5 +1,5 @@ import {Abi, Address, encodeFunctionData, PublicClient, withRetry} from "viem"; -import {getChainName, getPrivyClient, getAuthorizationContext} from '../../../plugins/custom/privy.js'; +import {getChainName, getPrivyClient, getAuthorizationContext, getWalletIdFromAddress} from '../../../plugins/custom/privy.js'; import type {GmxSdk} from "../index.js"; import {bigMath} from "./bigmath.js"; @@ -125,6 +125,7 @@ export async function getGasLimit( export interface CallContractOpts { value?: bigint | number; gasLimit?: bigint | number; + did?: string; // Privy DID (user_id) to filter wallets } export async function callContract( @@ -236,13 +237,10 @@ export async function callContract( console.log('Method', method) console.log('Params', params) - const wallets = await privy.wallets().list(); - console.log('Wallets', wallets) - const currentWallet = wallets.data.find((wallet: any) => wallet.address === sdk.config.account); - console.log('walletId', currentWallet) + const walletId = await getWalletIdFromAddress(sdk.config.account); const response = await privy.wallets().ethereum().sendTransaction( - currentWallet.id, + walletId, { caip2: networkName, params: { diff --git a/src/Managing.Web3Proxy/src/plugins/custom/privy.ts b/src/Managing.Web3Proxy/src/plugins/custom/privy.ts index 3bd2d341..238b8781 100644 --- a/src/Managing.Web3Proxy/src/plugins/custom/privy.ts +++ b/src/Managing.Web3Proxy/src/plugins/custom/privy.ts @@ -14,7 +14,6 @@ import {getClientForAddress, getTokenDataFromTicker} from './gmx.js' import {Address, erc20Abi} from 'viem' import {Balance, Chain, Ticker} from '../../generated/ManagingApiTypes.js' import {getCachedPrivySecrets} from './privy-secrets.js' -import Token from '../../generated/gmxsdk/abis/Token.js' // Load environment variables in non-production only if (process.env.NODE_ENV !== 'production') dotenv.config() @@ -281,6 +280,44 @@ export const getAuthorizationContext = (fastify?: FastifyInstance): Authorizatio }; }; +/** + * Gets the Privy wallet ID from a wallet address + * Fetches the user by wallet address and extracts the wallet ID directly from linked_accounts + * @param address The wallet address + * @param fastify Optional Fastify instance to get Privy client + * @returns The wallet ID + */ +export const getWalletIdFromAddress = async (address: string, fastify?: FastifyInstance): Promise => { + // Get user by wallet address - the response already contains wallet info in linked_accounts + const privy = getPrivyClient(fastify); + const user = await privy.users().getByWalletAddress({ address: address }); + + if (!user) { + throw new Error(`User not found for wallet address: ${address}`); + } + + // Find the wallet matching the address in linked_accounts + const wallet = user.linked_accounts.find( + (account: any) => + account.type === 'wallet' && + account.chain_type === 'ethereum' && + account.address?.toLowerCase() === address.toLowerCase() + ); + + if (!wallet) { + throw new Error(`Wallet not found for address ${address} in user's linked accounts`); + } + + // Return the wallet ID directly from linked_accounts + // The wallet object has an 'id' field that contains the wallet ID + const walletId = (wallet as any).id; + if (!walletId) { + throw new Error(`Wallet ID not found in linked account for address ${address}`); + } + + return walletId; +}; + /** * Gets the chain name based on chain ID * @param chainId The chain ID @@ -317,8 +354,11 @@ export const signMessage = async (walletId: string, message: string, address: st const authorizationContext = getAuthorizationContext(fastify); + // Get wallet ID from address if not provided + const resolvedWalletId = walletId || await getWalletIdFromAddress(address, fastify); + const {signature} = await privy.wallets().ethereum().signMessage( - address, + resolvedWalletId, { message: message, authorization_context: authorizationContext @@ -372,9 +412,12 @@ export const approveTokenImpl = async ( const privy = getPrivyClient(fastify); const authorizationContext = getAuthorizationContext(fastify); + // Get wallet ID from address + const walletId = await getWalletIdFromAddress(walletAddress, fastify); + // Send the transaction const { hash } = await privy.wallets().ethereum().sendTransaction( - walletAddress as Address, + walletId, { caip2: networkName as string, params: { @@ -528,9 +571,12 @@ export const approveContractImpl = async ( const privy = getPrivyClient(fastify); const authorizationContext = getAuthorizationContext(fastify); + // Get wallet ID from address + const walletId = await getWalletIdFromAddress(walletAddress, fastify); + // Send the transaction const { hash } = await privy.wallets().ethereum().sendTransaction( - walletAddress as Address, + walletId, { caip2: networkName as string, params: { @@ -963,11 +1009,12 @@ export const sendTokenImpl = async ( const amountInSmallestUnit = Math.floor(amountFloat * Math.pow(10, tokenDecimals)); const amountBigInt = BigInt(amountInSmallestUnit); + const walletId = await getWalletIdFromAddress(senderAddress, fastify); if (ticker === 'ETH') { // Native ETH transfer: no allowance, no data, value is amount as hex string const { hash } = await privy.wallets().ethereum().sendTransaction( - senderAddress as Address, + walletId, { caip2: networkName as string, params: { @@ -1011,9 +1058,12 @@ export const sendTokenImpl = async ( const transferAmount = amountBigInt; // Encode the transfer function call const data = contractInterface.encodeFunctionData("transfer", [recipientAddress, transferAmount]); + + // Get wallet ID from address + // Send the transaction const { hash } = await privy.wallets().ethereum().sendTransaction( - senderAddress as Address, + walletId, { caip2: networkName as string, params: { diff --git a/src/Managing.Web3Proxy/test/plugins/close-position.test.ts b/src/Managing.Web3Proxy/test/plugins/close-position.test.ts index ea5c8838..a7d65163 100644 --- a/src/Managing.Web3Proxy/test/plugins/close-position.test.ts +++ b/src/Managing.Web3Proxy/test/plugins/close-position.test.ts @@ -1,15 +1,15 @@ import {test} from 'node:test' import assert from 'node:assert' import {closeGmxPositionImpl, getClientForAddress} from '../../src/plugins/custom/gmx' -import {TradeDirection} from '../../src/generated/ManagingApiTypes' +import {Ticker, TradeDirection} from '../../src/generated/ManagingApiTypes' test('GMX Position Closing', async (t) => { await t.test('should close position', async () => { - const sdk = await getClientForAddress('0x1aDD85ee6f327d20340A451A8210FB32c4c97504') + const sdk = await getClientForAddress('0x932167388dD9aad41149b3cA23eBD489E2E2DD78') const result = await closeGmxPositionImpl( sdk, - "XRP", + Ticker.BTC, TradeDirection.Long ) console.log('Position closing result:', result) diff --git a/src/Managing.Web3Proxy/test/plugins/open-position.test.ts b/src/Managing.Web3Proxy/test/plugins/open-position.test.ts index 84aeb543..3b335ea2 100644 --- a/src/Managing.Web3Proxy/test/plugins/open-position.test.ts +++ b/src/Managing.Web3Proxy/test/plugins/open-position.test.ts @@ -14,8 +14,8 @@ test('GMX Position Opening', async (t) => { 0.00012, // ~5.3 USDC collateral with 2x leverage (fits available balance of 5.69 USDC) 2, 87856, - undefined, // No stop-loss - undefined // No take-profit + 75000, + 100000 ) console.log('Position opening result:', result) assert.ok(result, 'Position opening result should be defined') diff --git a/src/Managing.Web3Proxy/test/plugins/swap-tokens.test.ts b/src/Managing.Web3Proxy/test/plugins/swap-tokens.test.ts index fa192f28..595950aa 100644 --- a/src/Managing.Web3Proxy/test/plugins/swap-tokens.test.ts +++ b/src/Managing.Web3Proxy/test/plugins/swap-tokens.test.ts @@ -8,18 +8,18 @@ describe('swap tokens implementation', () => { it('should swap SOL to USDC successfully', async () => { try { const testAccount = '0x932167388dD9aad41149b3cA23eBD489E2E2DD78' + const sdk = await getClientForAddress(testAccount) - console.log('Account', sdk.account) - const result = await swapGmxTokensImpl( - sdk, - Ticker.USDC, - Ticker.SOL, - 3, - 'market', - undefined, - 0.5 - ) + const result = await swapGmxTokensImpl( + sdk, + Ticker.SOL, + Ticker.USDC, + 0.0495, + 'market', + undefined, + 0.5 + ) assert.strictEqual(typeof result, 'string') assert.strictEqual(result, 'swap_order_created')