Bullish Enterprise Administration and Wallet Operations on BitGo
Bullish Enterprise Administration and Wallet Operations on BitGo
Problem
Bullish, a regulated digital asset exchange operating across multiple jurisdictions (Gibraltar, Hong Kong, Germany, US), maintains numerous BitGo enterprises and wallets. Their support requests span a recurring set of operational needs: wallet policy unlock/update requests requiring video verification, enabling MPC key generation or gated assets for user accounts, resolving wallet permission issues (e.g., missing Spender role), investigating transaction failures or stuck transactions, enterprise name changes, enterprise listing, and addressing UI or balance display issues. These requests typically come through the premium support channel and require coordinated handling involving video identity verification, engineering escalations, and enterprise-level configuration changes.
Diagnostics
- Identify the enterprise(s) involved: Bullish operates many enterprises. Confirm the enterprise ID and name (e.g., "Bullish (GI) Limited," "BTH - TD," "Bullish HK Custody Limited," "Bullish DE Custody GmbH," "Bullish US Operations LLC," "Bullish US Operations LLC (NY)," "Bullish Europe GmbH House," "Bullish GI Limited House"). Use BGA to look up enterprise details.
- Confirm the requester's identity and authorization: Check whether the requester is a video-verified user on the relevant enterprise. Look up the enterprise's video-verified user list via BGA. If the requester is not video-verified, they must bring an already-verified user to the video call.
- For policy unlock requests: Identify the wallet ID(s) and current policy version. Use
bga w <wallet_id>to inspect wallet details, policy rules, user roles, and mutable status. - For permission/access issues: Use BGA to inspect the user's permissions array on the wallet. Check whether the user has
[admin, view]only vs.[admin, view, spender]. Note that the Spender role is not granted by default when adding a user as Admin. - For transaction failures: Use
bga t <txid>andbga coin <coin>to check on-chain status, send queue state, and wallet transfer records. Check TAT (Transaction Analysis Tool) for broadcast errors. Check https://status.bitgo.com/ for any ongoing coin-specific issues. - For balance discrepancies (spendable = 0 with non-zero balance): Check for pending approvals or pending transactions that may be locking the spendable balance. Use BGA to list pending approvals on the wallet.
- For gated asset errors: Look for the
CoinDisablederror with message "To enable for your account, contact support@bitgo.com." Confirm the user accounts that need ungating. - For MPC KeyGen enablement: Confirm the enterprise ID(s) and which key types are needed (EdDSA MPC Key, ECDSA MPC Key). Determine if enablement is enterprise-gated or user-gated.
- For enterprise configuration requests (name changes, enterprise lists, migrations): Verify the requester is an authorized contact (owner or primary contact) on the enterprise.
Resolution
Scenario: bullish-commission-regulated-financial#policy-unlock-video-verification
Trigger: Customer requests to unlock wallet policy to update address whitelisting or modify policies, and a video verification call is required.
Signals: policy unlock, wallet unlock, whitelist update, address whitelisting, video verification, Calendly, video conference
Steps:
- Acknowledge the request and confirm the wallet ID(s) and enterprise involved.
- Look up the enterprise's video-verified users list via BGA.
- Send the customer the Calendly scheduling link: https://calendly.com/bitgo-client-delivery/videoid
- Instruct the customer to have their government-issued photo ID ready and to reference the ticket number when scheduling.
- If the requester is not video-verified for that enterprise, inform them that an existing video-verified user must join the call: "Also, you are not yet verified for this enterprise. Please bring a existing video id user on the call for the policy unlock."
- During the video call, verify identity and confirm the unlock request.
- After verification, unlock the policy for the requested duration (typically 24–72 hours) using
bganew policy setmutablev2. - Confirm the unlock to the customer via email, stating the unlock duration.
Notes: Unlock durations observed in tickets: 24 hours, 48 hours, 72 hours. If video recording has technical issues (frozen video/audio), ask the customer to rejoin for recapture. The customer can also be offered an ad-hoc Google Meet link if scheduling is not needed.
"We have received your request to unlock your wallet policy. For security purposes, we will need to schedule a video conference to verify your Identification. Please use the following link to schedule a time to meet with us and verify the request: https://calendly.com/bitgo-client-delivery/videoid" "We have completed the unlock of policies for the next 24 hours as requested. Can I ask you to rejoin the meeting link? When I went to save the video to our archives, there was a few seconds of active video, then the image and audio frozen."
Scenario: bullish-commission-regulated-financial#wallet-admin-missing-spender-role
Trigger: Wallet admin users report the withdraw button is greyed out despite having admin permissions on the wallet.
Signals: withdraw greyed out, admin unable to withdraw, spender role missing, permissions admin view, cannot withdraw
Steps:
- Use BGA to inspect the user's permissions on the specific wallet:
bga w <wallet_id>. - Confirm whether the affected users show
[admin, view]withoutspenderin their permissions array. - Inform the customer: "When you add user as an admin to the wallet. Spender role is not given to those users by default. You need to check mark both the boxes to invite the users as an admin and spender if you want the users to withdraw as well."
- Instruct the customer to remove the affected users from the wallet and re-invite them with both Admin and Spender roles selected.
- Confirm the issue is resolved after the re-invite.
Notes: This applies to users added via the UI. When adding a user, both the Admin and Spender checkboxes must be selected for withdrawal capability. This is a common misunderstanding for new enterprise setups.
"It looks like both the users in question here are missing Spender role on the wallet... When you add user as an admin to the wallet. Spender role is not given to those users by default. You need to check mark both the boxes to invite the users as an admin and spender if you want the users to withdraw as well."
Scenario: bullish-commission-regulated-financial#enable-mpc-keygen
Trigger: Customer requests enablement of MPC key generation options (EdDSA MPC Key and/or ECDSA MPC Key) for specific enterprises or users.
Signals: MPC KeyGen, Generate EdDSA MPC Key, Generate ECDSA MPC Key, enable MPC, enterprise feature gate
Steps:
- Confirm the enterprise ID(s) and the specific key types requested (EdDSA, ECDSA, or both).
- Confirm the user accounts if the feature is user-gated.
- Escalate to engineering team to enable the requested MPC KeyGen options on the specified enterprises/users.
- Once engineering confirms enablement, reply to the customer asking them to verify the feature is available.
Notes: This request requires engineering team involvement. May be enterprise-gated or user-gated depending on configuration.
Scenario: bullish-commission-regulated-financial#ungate-asset-for-users
Trigger: Customer encounters a CoinDisabled error when attempting to use a gated asset (e.g., RLUSD, EUROC, RENDER) and requests ungating for specific user accounts.
Signals: CoinDisabled, ungate, gated asset, RLUSD, EUROC, RENDER, "To enable rlusd for your account, contact support@bitgo.com"
Steps:
- Confirm the list of user accounts and the assets to be ungated.
- Enable the requested coins on the specified user accounts via the admin tooling.
- If the customer reports the error persists after initial ungating, re-check the specific user account and retry the ungating operation.
- Confirm resolution with the customer once the
CoinDisablederror is no longer returned.
Notes: The error message reads: "To enable rlusd for your account, contact support@bitgo.com." with error name CoinDisabled. After ungating, the customer should retry the operation to confirm the fix.
"{"error":"To enable rlusd for your account, contact support@bitgo.com.","name":"CoinDisabled","requestId":"cm88cktqw0oqm0e394mwg9j0b","context":{},"message":"To enable rlusd for your account, contact support@bitgo.com.","bitgoJsVersion":"39.16.0","bitgoExpressVersion":"10.5.7"}"
Scenario: bullish-commission-regulated-financial#spendable-balance-zero-pending-approval
Trigger: Customer reports wallet shows a non-zero balance but spendable balance is 0, preventing withdrawals.
Signals: spendable balance 0, unable to withdraw, balance discrepancy, pending approval, ETH spendable
Steps:
- Use BGA to inspect the wallet:
bga w <wallet_id>. Note the Balance vs. Spendable fields. - Check for any old or stale pending approvals on the wallet that may be locking the spendable balance.
- Inform the customer: "We see this is because the wallet has a pending approval for a [amount] withdrawal that was created [date]. If no longer required, please cancel this pending approval to release available balance for the wallet."
- If the customer cannot find or cancel the pending approval, offer to cancel it from the support side.
- If cancelling the pending approval does not resolve the discrepancy, escalate to engineering to run a balance correction job.
- Confirm the spendable balance is corrected after the fix.
Notes: In one case, engineering ran a job to fix the spendable balance after the pending approval issue was identified. An RCA ticket may be created (e.g., WIN-7335).
"We see this is because the wallet has a pending approval for a 0.0275 ETH withdrawal that was created in May 2023... If no longer required, please cancel this pending approval to release available balance for the wallet." "We have ran a job to fixed this and the wallet's spendable balance should be correct now."
Scenario: bullish-commission-regulated-financial#share-keys-rate-limit
Trigger: Customer reports "Share Keys" functionality is failing or timing out when attempting to share keys across multiple wallets in an enterprise.
Signals: share keys not working, rate limit, throttling, cannot share keys, wallet key sharing failure
Steps:
- Confirm the enterprise and the number of wallets involved.
- Ask the customer to verify they are using the correct wallet password (not login password). Note: "Using the wrong password gives a password error" is a different symptom.
- If the customer suspects throttling (e.g., operation works for some wallets but fails for many), escalate to engineering to check rate limits on the user account.
- Engineering can increase the rate limit using:
bga user setratelimit -w 60 -n 1200. - After the rate limit is increased, ask the customer to retry the share keys operation.
Notes: This issue was caused by rate limit constraints when sharing keys across a large number of wallets (e.g., 26 wallets). Quadrupling the rate limit resolved the issue.
"It appears you were running into rate limit constraints. We've now quadrupled the rate limit on your user account. Could you please try sharing the keys again and let us know if you encounter any further issues?"
Scenario: bullish-commission-regulated-financial#user-access-removed-ums-sync
Trigger: Customer reports that wallet access was mysteriously removed for users without any action from their side.
Signals: access removed, wallet access lost, removeWalletUser, UMS sync, user removed mysteriously
Steps:
- Immediately investigate via BGA to confirm the user's current permissions on the enterprise and wallets.
- Check audit logs for
removeWalletUseractions and timestamps. - Escalate to engineering urgently — this may be caused by an internal issue (e.g., UMS/WP synchronization problem).
- Keep the customer updated via shared Slack channel and email.
- Engineering will determine the root cause and implement corrective measures, including an RCA.
- Once corrected, confirm with the customer that access is restored.
Notes: In one case, engineering determined the issue was caused by a UMS-to-WP sync problem. This was treated as a potential Code Red situation. Provide the customer with an RCA once available.
"engineering determined this was an issue caused by them when syncing UMS with WP... Engineering is determined the best correct measure for this and assembling an RCA"
Scenario: bullish-commission-regulated-financial#enterprise-name-change
Trigger: Customer requests an enterprise name change, providing a certificate of name change.
Signals: name change, enterprise rename, certificate of name change
Steps:
- Acknowledge receipt of the name change request and any attached documentation (e.g., certificate of name change).
- Forward the request to the internal team responsible for enterprise configuration changes.
- Once the name change is completed, confirm with the customer.
Notes: No video verification is mentioned for name changes in the tickets; the request was forwarded and processed internally.
Scenario: bullish-commission-regulated-financial#enterprise-migration-not-possible
Trigger: Customer asks whether an enterprise can be migrated from one organization to another.
Signals: migrate enterprise, move enterprise, enterprise between organizations
Steps:
- Inform the customer: "Unfortunately, it is not possible to migrate Enterprises between Organizations."
- If the customer needs further organizational restructuring, advise them to discuss options with their account manager.
"Unfortunately, it is not possible to migrate Enterprises between Organizations."
Scenario: bullish-commission-regulated-financial#remove-video-verifier-access
Trigger: Customer requests removal of a departing employee as a video verifier across all enterprises.
Signals: remove video verifier, employee departure, remove video verified user, offboarding
Steps:
- Identify all enterprises where the departing user is listed as a video-verified user. Use BGA to check each enterprise.
- Also check if the user has multiple accounts (e.g., different email addresses on different enterprises).
- A video verification call with an existing video-verified user on each enterprise is required to authorize the removal.
- Send the Calendly scheduling link: https://calendly.com/bitgo-client-delivery/videoid
- During the call, verify identity and confirm the removal request.
- After verification, remove the user as a video-verified user from the specified enterprises.
- Check if the departing user was listed as the primary contact on any enterprises. If so, coordinate with the customer to update the primary contact to another authorized user (e.g., an enterprise owner).
- If the internal removal tool encounters issues, escalate to engineering to run a database job to complete the removal.
Notes: Removing a video verifier may require engineering intervention if standard tooling does not support the operation. Also verify whether the user needs to be removed from a separate enterprise under a different email address. Primary contact changes should be handled as part of the same offboarding process.
"Furthermore, we need to update the primary contact for Bullish (GI) Limited, Bullish HK Custody Limited, and Bullish DE Custody GmbH as Priyesh was listed as primary contact." "Our Engineering team is asking permission from Bullish if they may use your Enterprise to apply the fix by running a database job to remove the unwanted user."
Scenario: bullish-commission-regulated-financial#stuck-or-failed-transaction
Trigger: Customer reports a transaction that is stuck in "pending confirmation" or has failed, and it cannot be found in the BitGo UI.
Signals: stuck transaction, failed transaction, pending confirmation, DUP_TRANSACTION_ERROR, transaction not found, rebalance stuck
Steps:
- Obtain the transaction reference, sequence ID, wallet ID, and coin type from the customer.
- Use
bga coin <coin>thenbga t <txid>to check the transaction status in the BitGo system (blockchain status, send queue, wallet transfer records). - If the transaction is not found in the system, ask the customer for the full API response or any additional identifiers (wallet ID, sequence ID).
- Check https://status.bitgo.com/ for any ongoing issues with the specific coin.
- If the transaction failed during signing/broadcast (e.g., DUP_TRANSACTION_ERROR), inform the customer they can re-submit the transaction with the same sequence ID, which will attempt signing and broadcast again on a new transfer.
- For Tron token transactions specifically: concurrent token transactions that are successfully built may fail on-chain because the system does not currently check if the total of existing pending transactions exceeds the spendable balance. This check is planned for implementation.
- Escalate to engineering if the root cause is unclear.
Notes: For BTC transactions, check https://mempool.space/ for on-chain status. For TRX tokens, failed transactions due to insufficient balance from concurrent sends are a known limitation. Transfers have unique sequenceIds; to allow reuse, BitGo deletes failed transfers rather than keeping them in a failed state.
"Yes, your team can re-submit the tx with the same sequence ID and it will attempt signing + broadcast again on a new transfer. Transfers have a unique sequenceId, so in order to allow clients to reuse their sequenceId we prefer deleting the transfers completely." "Currently, for Tron tokens only, we don't check if the total of existing pending transactions exceeds the spendable balance. Hence, concurrent token transactions successfully built could fail on-chain."
Scenario: bullish-commission-regulated-financial#opeth-deposit-not-reflected
Trigger: Customer reports deposits (e.g., opETH) are confirmed on-chain but not reflected in the BitGo portal or wallet balance.
Signals: deposit not reflected, opeth, gas tank, balance not showing, indexer issue, on-chain confirmed not in portal
Steps:
- Confirm the TXID, coin type, and wallet ID.
- Use
bga coin <coin>andbga t <txid>to check if the transaction is tracked in the BitGo system. - If the transaction shows "not in block chain / not in send queue / no wallet tx records" in BGA despite being confirmed on-chain (verified via block explorer), this indicates an indexing issue.
- Check https://status.bitgo.com/ for ongoing issues with the specific coin.
- If an indexer issue is confirmed, attempt to manually trigger re-indexing:
bga indexer execute INDEX_TRANSACTION <txid>. - If the issue is part of a broader platform outage, inform the customer and monitor the status page for resolution.
- Once engineering resolves the indexer issue, confirm with the customer that the balance is now reflected.
Notes: This was observed with opeth (Optimism ETH) during a known platform issue. The engineering fix resolved the indexing, and balances were subsequently updated.
Scenario: bullish-commission-regulated-financial#trx-wallet-initialization
Trigger: Customer reports a TRX custodial wallet cannot be initialized despite having funds deposited.
Signals: TRX wallet, uninitialised, not initialized, TRON wallet creation, 100 TRX, root address
Steps:
- Confirm the wallet ID and use BGA to identify the root address:
bga w <wallet_id>. - Verify whether the customer deposited the minimum 100 TRX to the root address (not a non-root/sub address).
- The UI may display a non-root address as the wallet initialization address, which is a known bug. Inform the customer of the correct root address from BGA.
- Instruct the customer to deposit minimum 100 TRX to the root address to initialize the wallet.
- Remind the customer that TRON accounts must maintain a minimum balance of 0.1 TRX to remain active.
- Reference API documentation: https://developers.bitgo.com/coins/tron
Notes: A known UI issue showed a non-root address as the wallet initialization address. The root address from BGA is authoritative. Engineering fixed this display issue.
"For TRON wallet, the deposit needs to be to the root address to initialise the wallet... the one that is present in the shared screenshot is a non-root address of the same wallet."
Scenario: bullish-commission-regulated-financial#account-frozen-2fa-video-id
Trigger: Customer's account is frozen due to too many failed 2FA reset attempts and they need a video verification call to unfreeze.
Signals: account frozen, 2FA reset, frozen account, video ID, failed attempts, camera unable to capture
Steps:
- Confirm the user's account status and the enterprise they belong to.
- Inform the customer: "Your account has been Frozen due to too many failed attempts to reset your 2FA."
- Send the Calendly scheduling link: https://calendly.com/bitgo-client-delivery/videoid
- Instruct the customer to have government-issued photo ID ready and reference the ticket number.
- If the customer is not initially verified by BitGo, they must bring an already-verified user from the enterprise to the call.
- After successful video verification, unfreeze the account and reset 2FA.
- Instruct the customer to log back in and set up 2FA again.
Notes: If the customer joins the call alone but is not video-verified, the call cannot proceed. They must reschedule with a verified user present.
"Note: If you are not initially verified by BitGo, please bring the person on the call who has already verified and can authorize your identity. For this Enterprise it would be either (Mick, Paul, Priyesh or Tarun)"
Scenario: bullish-commission-regulated-financial#whitelist-cooldown-duration-policy
Trigger: Customer asks about the "Whitelist Cooldown Duration" policy condition and how it works.
Signals: whitelist cooldown duration, policy condition, newly whitelisted address, cooldown
Steps:
- Explain to the customer: "This condition allows withdrawals to be handled differently when the withdrawal address has been newly whitelisted."
- Clarify: "If an address was added within the last X days, hours, or minutes, you can apply temporary controls such as withdrawal limits, additional approval requirements, or rejection of withdrawals."
- Confirm: "Once the address is no longer considered newly whitelisted, the policy no longer applies and withdrawals follow normal behavior."
"This condition allows withdrawals to be handled differently when the withdrawal address has been newly whitelisted. If an address was added within the last X days, hours, or minutes, you can apply temporary controls such as withdrawal limits, additional approval requirements, or rejection of withdrawals."
Scenario: bullish-commission-regulated-financial#pending-approval-type-api
Trigger: Customer asks when to use transactionRequest versus transactionRequestFull as the approval type for the pendingApprovals API.
Signals: transactionRequest, transactionRequestFull, pendingApprovals, approval type, multisigType
Steps:
- Explain the distinction:
- Wallets with
multisigTypeasundefinedoronchainusetransactionRequestfor withdrawals. - Wallets with
multisigTypeastssthat create transaction requests usingapiVersion=litealso usetransactionRequest(only applicable to hot EdDSA MPC wallets). - All other TSS wallets use
transactionRequestFull.
- Wallets with
- Reference: https://developers.bitgo.com/api/v2.approval.update
"Wallets that have a multisigType as undefined or onchain will use transactionRequest for withdrawals. Wallets that have a multisigType as tss and create transaction requests using the apiVersion=lite also use transactionRequest (only applicable to hot eddsa mpc wallets)"
Scenario: bullish-commission-regulated-financial#wallet-password-update
Trigger: Customer asks how to update their wallet password after changing their login password.
Signals: wallet password, login password, update wallet password, password management
Steps:
- If the customer is the wallet creator: they can change the wallet password from Wallet > Settings > Update Wallet Password. The wallet keycard information is required.
- Reference: https://bitgo.my.site.com/ResourceCenter/s/article/Password-Management-1677400103617
- If the customer is not the wallet creator (was invited to the wallet): the wallet admin should remove and re-add them as a wallet user.
- Reference: https://bitgo.my.site.com/ResourceCenter/s/article/Add-Users-to-Enterprise-and-Wallets-1677400103529
- For newly added wallets after a login password change: no re-invite is necessary. The new wallets will use the updated login password.
"If you are the wallet creator, you can change the wallet password from Wallet > Settings > Update Wallet Password. You will require the wallet keycard information to proceed." "No re-invite is necessary; the newly added wallet will use the same login password that you just updated."
Scenario: bullish-commission-regulated-financial#enterprise-list-request
Trigger: Customer requests a list of all mainnet enterprises and organizations owned/registered by their company.
Signals: enterprise list, list enterprises, organizations owned, mainnet enterprises
Steps:
- Check internally with the Product Operations team to compile the full list of enterprises associated with the customer's organization.
- For each enterprise, provide: Enterprise ID, custodian (BitGo Inc / BitGo Trust), plan type, primary contact, and owners.
- For enterprises with no owners or that appear unused, check the last activity date.
- Inform the customer that unused enterprises without owners can be frozen indefinitely upon request, but BitGo does not have the option to fully remove enterprises.
Notes: Enterprises cannot be deleted, only frozen. Customers may request freezing for inactive/unused enterprises.
"For those Ent without owners this be frozen as we dont have the option to remove any Enterprises. The last time those Enterprise was used was between 2021-2024... You may request to have the listed Enterprise be frozen indefinitely"
Scenario: bullish-commission-regulated-financial#ui-policy-page-not-loading
Trigger: Customer reports the enterprise policy page briefly loads and then auto-redirects to the assets page, or other UI display issues.
Signals: policy page not loading, UI bug, auto redirect, truncated labels, browser issue
Steps:
- Attempt to reproduce the issue by spoofing the customer's account.
- If unable to reproduce, advise the customer to clear browser cache and retry.
- If the issue persists, ask them to test on a different device/browser.
- If reproducible, escalate to the backend/frontend engineering team with details and screenshots.
Notes: UI display issues (e.g., truncated wallet labels) are escalated to the backend team. These may not have immediate fixes and are tracked in internal JIRA tickets.
Related
- custody-withdrawals — Covers withdrawal security layers, video verification, and policy-based controls relevant to policy unlock workflows.
- bitgo-global-regulated-entities — Reference for BitGo entity structures (BitGo Inc, BitGo Trust, BitGo Europe GmbH with BaFin licensing) relevant to enterprise configuration.
- go-account-overview — Related context for qualified custody accounts and enterprise-level asset management.