Use this file to discover all available pages before exploring further.
Try Cobo WaaS Skill in your AI coding assistant (Claude Code, Cursor, etc.). Describe your needs in natural language to auto-generate production-ready SDK code and debug faster 🚀
For certain low-risk, high-frequency transactions, bypassing the multi-signature requirement can help streamline operations, especially when tasks are time-sensitive or require frequent interaction. Cobo’s Smart Contract Wallets (Safe{Wallet}) provide an efficient solution by allowing you to authorize a Delegate—either an address from your MPC Wallet or an external EOA wallet—to initiate these actions with a single signature, simplifying execution without compromising control.In this guide, we’ll demonstrate how to configure both an MPC Wallet and an external EOA wallet to claim farming rewards automatically.
Assume you have a Safe{Wallet} on the Base chain with ETH deposited in the Stargate protocol for yield farming. You can use an MPC Wallet to perform automated, scheduled reward collection by using the WaaS API.
Before you start, refer to Get started with Smart Contract Wallets to complete the initial setup, including installing the WaaS SDK and importing the Safe{Wallet} to Cobo Portal.
Configure an on-chain risk control policy to approve the claim method initiated via the MPC Wallet address automatically.
Select the MPC Wallet address as the Delegate.
Set Condition as Custom Contract Calls.
Select Method-Level.
Enter the address of the Stargate staking contract as the target contract, and select claim as the method.
Click Submit to initiate a multi-sig transaction. Ask the Safe{Wallet} signers for confirmation.
Execute the following code to claim rewards daily at 9 a.m. The sample code uses the Call smart contract operation to interact with the Stargate contract.
Sample code in Python
import scheduleimport timefrom web3 import Web3import cobo_waas2# Specify the Stargate contract addressSTG_CLAIM_CONTRACT = "0xdfc47dcef7e8f9ab19a1b8af3eecf000c7ea0b80"# Get the ABI from EtherscanSTG_CLAIM_ABI = []# Specify the Stargate pool addressSTG_ETH_POOL = "0x98fB8522d891F43B771e2d27367b41Ba138D0B80"w3 = Web3(Web3.HTTPProvider("<RPC_URL>")) contract = w3.eth.contract(address=STG_CLAIM_CONTRACT, abi=STG_CLAIM_ABI)data = contract.encodeABI("claim", [[STG_ETH_POOL]])def get_delegate(wallet_id, request: cobo_waas2.SafeWalletDelegates):# Enter a context with an instance of the API client with cobo_waas2.ApiClient(configuration) as api_client: # Create an instance of the API class wallet_api_instance = cobo_waas2.WalletsSmartContractWalletsApi(api_client) try: # Call the List Delegates operation to retrieve available Delegates api_response = wallet_api_instance.list_safe_wallet_delegates( wallet_id=wallet_id, safe_wallet_delegates=request ) if not api_response: raise Exception("No delegate found") print("The response of WalletsApi->list_safe_wallet_delegates:") print(json.dumps(api_response[0].to_dict(), indent=2)) return api_response[0] except Exception as e: print("Exception when calling WalletsApi: %s\n", e)def get_wallet(wallet_id) -> cobo_waas2.SafeWallet: with cobo_waas2.ApiClient(configuration) as api_client: # Create an instance of the API class wallet_api_instance = cobo_waas2.WalletsApi(api_client) try: # Call the Get wallet information operation to retrieve the wallet information, including the wallet address api_response = wallet_api_instance.get_wallet_by_id( wallet_id=wallet_id ) print("The response of WalletsApi->get_wallet_by_id:") print(json.dumps(api_response.to_dict(), indent=2)) return api_response.actual_instance.actual_instance except Exception as e: print("Exception when calling WalletsApi: %s\n", e)def contract_call(wallet_id, contract_address, data, value): contract_call_request = cobo_waas2.SafeWalletDelegates( actual_instance=cobo_waas2.SafeWalletDelegatesContractCall( request_type=cobo_waas2.EstimateFeeRequestType.CONTRACTCALL, address=contract_address, calldata=data, value=value, ) ) delegate = get_delegate(wallet_id, contract_call_request) wallet = get_wallet(wallet_id) with cobo_waas2.ApiClient(configuration) as api_client: wallet_api_instance = cobo_waas2.TransactionsApi(api_client) try: # Use the Call smart contract operation to interact with the Stargate contract api_response = wallet_api_instance.create_contract_call_transaction( cobo_waas2.ContractCallParams( request_id=str(uuid.uuid4()), chain_id=wallet.chain_id, source=cobo_waas2.ContractCallSource( actual_instance=cobo_waas2.SafeContractCallSource( source_type=cobo_waas2.ContractCallSourceType.SAFE_WALLET, wallet_id=wallet_id, address=wallet.safe_address, delegate=delegate, ) ), destination=cobo_waas2.ContractCallDestination( actual_instance=cobo_waas2.EvmContractCallDestination( destination_type=cobo_waas2.ContractCallDestinationType.EVM_CONTRACT, address=contract_address, calldata=data, value=value, ), ), category_names=["<CATEGORY_NAME>"], description="<DESCRIPTION>", ) ) print("The response of TransactionsApi->create_contract_call_transaction:") print(json.dumps(api_response.to_dict(), indent=2)) except Exception as e: print("Exception when calling TransactionsApi: %s\n", e)def daily_contract_call(): print("claim stargate") contract_call( wallet_id=wallet_id, contract_address=STG_CLAIM_CONTRACT, data=data, value="0", )# Schedule the contract call to run every day at 9:00 a.m.schedule.every().day.at("09:00").do(daily_contract_call)# Keep the script runningwhile True: schedule.run_pending() time.sleep(1)
You can also use external EOA wallets that are not created through Cobo Portal to claim rewards. The initial steps are similar to those for MPC Wallets, but you will set the EOA wallet address as the Delegate and adjust the on-chain risk control policy accordingly.Instead of using the WaaS API, the EOA wallet interacts with Safe{Wallet} by using functions provided by Cobo Safe. The process can be outlined in the following steps:
Build a claim transaction to collect farming rewards from Stargate.
Wrap the claim transaction within a Cobo Safe transaction.
Initiate the Cobo Safe transaction via the EOA wallet.
Use the EOA wallet to sign the transaction and send it to the network.
Sample code in Python
import jsonfrom web3 import Web3import cobo_waas2import osfrom eth_account import Account# Get the private key from the environment variablePRIVATE_KEY = os.getenv('ETH_PRIVATE_KEY')# Create the account objectaccount = Account.from_key(PRIVATE_KEY)w3 = Web3(Web3.HTTPProvider("<RPC_URL>")) def get_wallet(wallet_id) -> cobo_waas2.SafeWallet: with cobo_waas2.ApiClient(configuration) as api_client: # Create an instance of the API class wallet_api_instance = cobo_waas2.WalletsApi(api_client) try: # Call the Get wallet information operation to retrieve the wallet information, including the wallet address api_response = wallet_api_instance.get_wallet_by_id( wallet_id=wallet_id ) print("The response of WalletsApi->get_wallet_by_id:") print(json.dumps(api_response.to_dict(), indent=2)) return api_response.actual_instance.actual_instance except Exception as e: print("Exception when calling WalletsApi: %s\n", e)# Enter the wallet ID found in Cobo Portal wallet = get_wallet("<YOUR_WALLET_ID>")# Get the address of Cobo Safecobo_safe_address = wallet.cobo_safe_address# Get the ABI from EtherscanCOBO_SAFE_ABI = [] # Specify the Stargate contract address STG_CLAIM_CONTRACT = "0xdfc47dcef7e8f9ab19a1b8af3eecf000c7ea0b80"# Get the ABI from EtherscanSTG_CLAIM_ABI = []STG_ETH_POOL = "0x98fB8522d891F43B771e2d27367b41Ba138D0B80"stg_contract = w3.eth.contract(address=STG_CLAIM_CONTRACT, abi=STG_CLAIM_ABI)# Build Starget claim transactiondata = stg_contract.encodeABI("claim", [[STG_ETH_POOL]])# Build a Cobo Safe transactioncobo_safe_contract = w3.eth.contract(address=cobo_safe_address, abi=COBO_SAFE_ABI)call_datas = [ [ 0, Web3.to_checksum_address(STARGATE_STAKING), 0, Web3.to_bytes(hexstr=data), b"", b"", ]]# Build the transaction for the EOA wallet. The transaction initiates a Cobo Safe transaction via the EOA account. transaction = cobo_safe_contract.functions.execTransactions(call_datas).build_transaction({ 'from': account.address, 'nonce': w3.eth.get_transaction_count(account.address), # Set a gas fee limit 'gas': 200000, 'gasPrice': w3.eth.gas_price,})# Sign the transactionsigned_tx = account.sign_transaction(transaction)# Send the transaction tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash)print(f"Transaction sent with hash: {tx_hash.hex()}")