Skip to main content
This content applies to WaaS 1.0 only. We highly recommend that you upgrade to WaaS 2.0.
The main features of UTXO-based transactions are:
  • Transactions on a UTXO-based blockchain consist of inputs and outputs. Each input refers to a specific UTXO (unspent transaction output) from a previous transaction. When you create a new transaction, you use one or more UTXOs as inputs, and you can specify different destination addresses (i.e., the ‘to’ address) for the outputs.
  • When you spend a fraction of a UTXO, the remaining amount needs to be sent back to you. This is typically done by including one of your own addresses as a “change address” in the transaction. This change address receives the remaining funds that are not sent to the destination addresses.
In Custodial Wallets, transactions are initiated based on all available Unspent Transaction Outputs (UTXOs) within each wallet. Cobo will manage the corresponding logics and you are not required to construct an input address. For MPC Wallets, you have the flexibility to decide whether to initiate a transaction using all available UTXOs under each wallet or under a specified address. Additionally, you can define a change address. If none is specified, the system will automatically send the change to the ‘from’ address. In cases where the transaction originates directly from the wallet rather than a ‘from’ address, any change will be sent back to the default address of the wallet (i.e., the address that was auto generated when you first created the MPC Wallet).

Code Samples for MPC Wallets

If the transaction is initiated using all available UTXOs under an MPC Wallet:
from cobo_custody.client.mpc_client import MPCClient
from cobo_custody.config import DEVELOP_ENV
from cobo_custody.signer.local_signer import LocalSigner
import time

signer = LocalSigner("your_api_secret_here")
mpc_client = MPCClient(signer=signer, env=DEVELOP_ENV, debug=True)
response = mpc_client.create_transaction(
   coin="XTN",
   request_id=f"MPCTransaction-{int(time.time() * 1000)}",
   amount=None,
   to_address_details='[{"to_address": "2N4J1WajwKZKpRtzzUmaW9B5GEqkppqdVY9","amount": "547"},'
                       '{"to_address": "tb1qycxy8d8jgff8hql09y62smw5s5mrf3ryn2j9lk","amount": "548"}]',
   fee=10.1
)
print(response.result)

package com.cobo.custody.api.client.impl;
import com.cobo.custody.api.client.CoboApiClientFactory;
import com.cobo.custody.api.client.CoboMPCApiRestClient;
import com.cobo.custody.api.client.config.Env;
import com.cobo.custody.api.client.domain.ApiResponse;
import com.cobo.custody.api.client.domain.transaction.MPCPostTransaction;
import java.math.BigInteger;

public class CobоCustodyApiClientExample {
   private static CoboMPCApiRestClient mpcClient;
   public static void main(String[] args) {
       String apiSecret = "your_api_secret_here";
       mpcClient = CoboApiClientFactory.newInstance(
               new LocalSigner(apiSecret),
               Env.DEVELOP,
               false).newMPCRestClient();
       String coin = "BTC";
       String requestId = String.valueOf(System.currentTimeMillis());
       String fromAddr = null;
       String toAddr = null;
       BigInteger amount = null;
       String toAddressDetails = "[{\"to_address\": \"2N4J1WajwKZKpRtzzUmaW9B5GEqkppqdVY9\", \"amount\": \"547\"}, {\"to_address\": \"tb1qycxy8d8jgff8hql09y62smw5s5mrf3ryn2j9lk\",\"amount\": \"548\"}]";
       BigInteger fee = new BigInteger("10");
       BigInteger gasPrice = null;
       BigInteger gasLimit = null;
       Integer operation = null;
       String extraParameters = null;
       ApiResponse<MPCPostTransaction> response = mpcClient.createTransaction(
               coin, requestId, fromAddr,toAddr, amount, toAddressDetails, gasPrice, gasLimit, fee, operation, extraParameters
       );

       System.out.println(response.getResult());
   }
}

If the transaction is initiated using all available UTXOs under a designated address:
from cobo_custody.client.mpc_client import MPCClient
from cobo_custody.config import DEVELOP_ENV
from cobo_custody.signer.local_signer import LocalSigner
import time

signer = LocalSigner("your_api_secret_here")
mpc_client = MPCClient(signer=signer, env=DEVELOP_ENV, debug=True)

response = mpc_client.create_transaction(
   coin="XTN",
   request_id=f"MPCTransaction-{int(time.time() * 1000)}",
   amount="10000",
   from_addr="tb1qtxkz0v063lgu0crqqnc2llarfg27lkyqq5l4mv",
   to_addr="tb1q0dr4tfw8eguswrpc2rrc5mg6af0k42jhu7rgyg",
)
print(response.result)

package com.cobo.custody.api.client.impl;
import java.math.BigDecimal;
import java.math.BigInteger;
import com.cobo.custody.api.client.CoboApiClientFactory;
import com.cobo.custody.api.client.CoboMPCApiRestClient;
import com.cobo.custody.api.client.config.Env;
import com.cobo.custody.api.client.domain.ApiResponse;
import com.cobo.custody.api.client.domain.transaction.MPCPostTransaction;
public class CobоCustodyApiClientExample {
    public static void main(String[] args) {
        String apiSecret = "1795cd4c0184a6205130a3ecd5d6317c35214b9a9730c5599872cdf33ce30ab5";  // your wallet api secret
        String coin = "XTN";  // your target coin
        String requestId = String.valueOf(System.currentTimeMillis());  // your custom request_id
        String fromAddr = "tb1qtxkz0v063lgu0crqqnc2llarfg27lkyqq5l4mv";  // your mpc wallet address
        String toAddr = "tb1q0dr4tfw8eguswrpc2rrc5mg6af0k42jhu7rgyg";  // your address
        BigInteger withdraw_amount = new BigInteger("1000");  // withdraw amount:0.01GETH
        String toAddressDetails = null;
        BigDecimal fee = null;
        BigInteger gasPrice = null;
        BigInteger gasLimit = null;
        Integer operation = null;
        String extraParameters = null;
        // init client
        CoboMPCApiRestClient mpcClient = CoboApiClientFactory.newInstance(
                new LocalSigner(apiSecret),
                Env.DEVELOP,
                false).newMPCRestClient();

        ApiResponse<MPCPostTransaction> createTransactionResponse = mpcClient.createTransaction(coin, requestId, withdraw_amount, fromAddr, toAddr,
                toAddressDetails, fee, gasPrice, gasLimit, operation, extraParameters, null, null, null);
        System.out.println("Withdraw: " + createTransactionResponse.getResult());
    }
}

Code Samples for Custodial Wallets

The transaction is initiated using all UTXOs under a Custodial Wallet:
from cobo_custody.client import Client
from cobo_custody.config import DEVELOP_ENV
from cobo_custody.signer.local_signer import LocalSigner
import time


api_secret = "your_api_secret"  # your wallet api secret
chain_code = "BTC"  # your target chain
coin_code = "BTC"  # your target coin
amount = 1000  # withdraw amount
to_address = "your address"  # your address


# init cobo client
client = Client(signer=LocalSigner(api_secret), env=DEVELOP_ENV, debug=False)

request_id = f"ApiTransaction-{int(time.time() * 1000)}"    # your custom request_id
response = client.withdraw(
   coin=coin_code,
   request_id=request_id,
   amount=amount,
   address=to_address,
)
print(f"Withdraw: {response.result}")

package com.cobo.custody.api.client.impl;
import java.math.BigInteger;
import com.cobo.custody.api.client.CoboApiClientFactory;
import com.cobo.custody.api.client.CoboApiRestClient;
import com.cobo.custody.api.client.config.Env;
import com.cobo.custody.api.client.domain.ApiResponse;

public class CoboApiExample {
public static void main(String[] args) {
String apiSecret = "your_api_secret"; // your wallet api secret
String coin = "XTN"; // your target coin
String requestId = String.valueOf(System.currentTimeMillis()); // your custom request_id
String toAddr = "your_address"; // your address
BigInteger withdraw_amount = new BigInteger("1000000000"); // withdraw amount

// init cobo client
CoboApiRestClient client = CoboApiClientFactory.newInstance(
new LocalSigner(apiSecret),
Env.DEVELOP,
false).newRestClient();

ApiResponse<String> withdraw = client.withdraw(
coin,
requestId,
toAddr,
withdraw_amount,
null,
null,
null
);
System.out.println("response data: withdraw" + withdraw.getResult());

}
}