Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions examples/ts/stablecoin/initiate-mint-order.ts
Copy link
Contributor

@zeeshanamjad-eng zeeshanamjad-eng Aug 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/**
* Initiate a Mint Order for a Stablecoin
*
* Copyright 2023, BitGo, Inc. All Rights Reserved.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Copyright 2023, BitGo, Inc. All Rights Reserved.
* Copyright 2025, BitGo, Inc. All Rights Reserved.

*/

import * as BitGoJS from 'bitgo';
import { common } from '@bitgo/sdk-core';
require('dotenv').config({ path: '../../../.env' });

/**
* Step 1. GET /assets API
* Step 2. GET /constants API
* Step 3. POST /order API
* Step 4. sendMany
*/

// Add the parameters here
const environment = 'test';
const accessToken = '';
const enterpriseId = '';
const walletId = ''; // GoAccount Wallet ID
const walletPassphrase = ''; // Wallet passphrase
const usdcoin = 'tfiatusd';
const ofcUsdCoin = 'ofctusd';
const stablecoin = 'tbsc:usd1';
const fromAmount = '3000'; // in base units, e.g., 3000 for 30 USD
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const fromAmount = '3000'; // in base units, e.g., 3000 for 30 USD
const fromAmount = '3000'; // in cents, e.g., 3000 for 30 USD

?


const bitgo = new BitGoJS.BitGo({ env: environment });
bitgo.authenticateWithAccessToken({ accessToken: accessToken });

const basecoin = bitgo.coin(ofcUsdCoin);

async function main() {
try {
// Custom API path helper function
const stablecoinUrl = (path: string) => {
return common.Environments[bitgo.getEnv()].uri + '/api/stablecoin/v1' + path;
};

// STEP - 1: Gets the list of assets
const assets = await bitgo.get(stablecoinUrl('/assets'));
console.log('assets:', assets.body);

// Finds the USD and Stablecoin assets from above response to use in initiating the mint order
const usdAsset = assets.body.find((asset: any) => asset.token === usdcoin);
const stablecoinAsset = assets.body.find((asset: any) => asset.token === stablecoin);
if (!usdAsset || !stablecoinAsset) {
throw new Error(`Asset ${usdcoin}/${stablecoin} not found`);
}

// STEP - 2: Gets the constants for the stablecoin
const constants = await bitgo.get(stablecoinUrl(`/${stablecoin}/constants`)).send();
console.log('constants:', constants.body);
// Extract the treasury account wallet ID from the constants response
const trustAccountWalletId = constants.body.trustAccountWalletId;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const trustAccountWalletId = constants.body.trustAccountWalletId;
const treasuryAccountWalletId = constants.body.trustAccountWalletId;

if (!trustAccountWalletId) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (!trustAccountWalletId) {
if (!treasuryAccountWalletId) {

throw new Error(`Trust account wallet ID not found for ${stablecoin}`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
throw new Error(`Trust account wallet ID not found for ${stablecoin}`);
throw new Error(`Treasury account wallet ID not found for ${stablecoin}`);

}

// STEP - 3: Initiates the mint order
const orderRequestBody = {
sourceWalletId: walletId,
destinationWalletId: trustAccountWalletId,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

destinationWalletId is wrong here. Fixing in the follow-up PR - #6663

destinationType: "go_account",
toAssetId: stablecoinAsset.id,
fromAssetId: usdAsset.id,
fromAmount,
type: "mint",
};
const postOrderResponse = await bitgo.post(stablecoinUrl(`/enterprise/${enterpriseId}/order`)).send(orderRequestBody);
const newOrder = postOrderResponse.body;
console.log('Order created:', newOrder);

// STEP - 4: Sends the transaction to the Treasury Account using sendMany
const walletInstance = await basecoin.wallets().get({ id: walletId });
const transaction = await walletInstance.sendMany({
recipients: [
{
address: trustAccountWalletId,
amount: fromAmount,
}
],
sequenceId: newOrder.id, // IMPORTANT: Use the order ID as the sequence ID
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As part of input sanitization, we can check for nullity of order id. Something FE can also do if not already doing.

walletPassphrase,
});
console.log('Mint order process completed successfully!');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe fetch the order once here

console.log('New Transaction:', JSON.stringify(transaction, null, 4));

const order = await bitgo.get(stablecoinUrl(`/enterprise/${enterpriseId}/orders?ids=${newOrder.id}`)).send();
console.log('Order details:', JSON.stringify(order.body, null, 4));

} catch (error) {
console.error('Error in mint order process:', error);
throw error;
}
}

main().catch((e) => console.error(e));