Skip to content
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

Is there a way to move crypto funds out of the trading wallet? #3948

Open
gndelia opened this issue Oct 2, 2023 · 1 comment
Open

Is there a way to move crypto funds out of the trading wallet? #3948

gndelia opened this issue Oct 2, 2023 · 1 comment

Comments

@gndelia
Copy link

gndelia commented Oct 2, 2023

The guides and the docs are very misleading about this, providing different paths and responses, and I can't get any of them to work. Is there a way to move funds out of the Trading wallet? Or only Fiat USD can be moved out?

For example:

According to the wallets overview page, these are the steps we need to follow

image

When going to the build API pages and the build guides docs, we find different expected responses.

  • According to the first one (Build API pages), the response should be just a keyDerivationPath
{
  "keyDerivationPath": "string"
}

I do not know what to do with it

According to the second one (The guide to initiate transactions), the response should

  • Getting a calendar invitation by email (to validate the identity)
  • An object with a signature among lots of other info.
image

The next step, according to this guide, should be sending the transactions (Guide about it here)

However, when actually calling the /tx/build endpoint, I get none of the responses above ☝🏽 , but a different one.

This is the Body I sent (Trying to withdraw some USDC from the trading account)

{
  "recipients": [
      {
      "address": "<public-address-of-my-bitgo-wallet>",
      "amount": "12061478"
      }
    ]
 }

and this is the response I get

{
  "payload": '{"coin":"ofcusdc","recipients":[{"address":"<public-address>","amount":"12061478"}],"fromAccount":"<walletID>","nonce":"<nonce>","timestamp":"2023-09-19T21:03:04.345Z","feeString":"0","shortCircuitBlockchainTransfer":false,"isIntraJXTransfer":false}',
  "feeInfo": { feeString: '0' },
  "coin": "ofc",
  "token": "ofcusdc"
}

This ☝🏽 is not documented anywhere. What should I do with it? There's a guide to sign transactions but there's no option that documents how to sign with the Trading Wallet

image

Unless the trading wallet is considered a Multisig cold wallet. In that case, should I use the offline Vault console? There's no mention in the OVC pages about the trading wallet

If we check the /send endpoint (linked above), there's no mention of any payload or anything. However, the screenshot with the "Transaction flow" mentions that /tx/build creates an unsigned transaction, and then in /send the user must send a half-signed transaction. How can we sign this payload? Is there a way? Just converting the payload to HEx does not work (at least for me). I just convert the payload to Hex, and send it as the txHex property the guides specify, I just get

{
  error: 'missing tx payload',
  name: 'Invalid',
  requestId: '<request-id>,
  context: {}
}

I'm testing all of this on mainnet because Bitgo support has told me that withdrawals from the Trading Account in testnet are not enabled.

I've exchanged several emails with support, with no response. I've also tried in their Discord, with no response either.

Thanks in Advance

@gndelia
Copy link
Author

gndelia commented Oct 13, 2023

I finally figured it out by downloading the code and running the signing docker image on my local machine. Their support centre was barely helpful, so I'm leaving this for anyone who needs it in the future. In order to move funds out of the trading wallet, to a given public address, you can follow these steps:

Build TX

Call the build tx endpoint.

fetch(`${bitgoUrl}/api/v2/${coin}/wallet/${tradingWalletId}/tx/build`, {
  body: {
    recipients: [
          {
            address: destinationPublicAddress, // 0x...
            amount // (for 1 usdc, use 1000000)
          }
        ]
  },
  method: 'POST'
})

This will return an object with a payload string, among other properties

{
  "payload": "<json-object-stringified>"
}

Sign the payload object

This was the step that I was missing when I created this issue. I don't know how to get the key to sign with Bitgo's endpoint, but their UI is doing so. However, what I did, and you can do too if you're using the bitgo express docker image is to call a non-documented endpoint that does all the work for you. You can see the code of this endpoint here.

fetch(`${bitgoExpressUrl}/api/v2/ofc/signPayload', {
  body: {
    payload: JSON.parse(payload), // payload is the string object we got from the previous call
    walletId: tradingWalletId
  },
  method: 'POST'
})

This will return an object with the payload (again) and the signature

{
  "payload": "<json-object-stringified>",
  "signature": "payload-signature-in-hex" 
}

This endpoint IS NOT DOCUMENTED (so use it at your own risk), but it was the key for me to solve this problem without having to load and decrypt keys.

You also keep in mind that the Bitgo Express container must be run in production mode (as withdrawals from testing env are not enabled - See how to run in production mode here. In addition to that, keep in mind that even though the docs do not mention it, you must set BITGO_ENV=production rather than NODE_ENV=production) and the passphrase for the Trading wallet must be set as an env variable. See this on how to set the passphrase (you may need to use the Bitgo login account if it does not work.. awful, but it is what it is)

Send the payload and signature

This step was documented, but incorrectly . We need to call the tx/send endpoint, but following the example below 👇🏽 because the docs are incorrect as of 10/2023

fetch(`${bitgoUrl}/api/v2/ofcusdc/wallet/${tradingWalletId}/tx/send`, {
  body: {
    halfSigned: {
      payload: '<json-object-stringified>',
      signature: 'signature-from-previous-call'
    }
  },
  method: 'POST'
})

The docs INCORRECTLY tell you to send a txHex property, either as part of the body object or inside the halfSigned property. But that did not work for me.

This will create the transfer, and if required you will get an email invitation for a video call.

Important notes

Keep in mind you may also need to whitelist the destination address as a withdrawal address - you can do so from the UI

You also be aware that all requests above require the accessToken as a Bearer authorization header, with the proper spending limits set - omitted here for simplicity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant