I'm looking at the Java docs and I can't find any way to delete every order for an account. Is there an easy way to cancel/remove all open trades/offers?
2 Answers
There isn't method for bulk cancelling.
Stellar cancels offers by setting the Amount parameter to 0. From the site
Manage Offer: Parameters [...] Amount: Amount of selling being sold. Set to 0 if you want to delete an existing offer.
So, you could loop through your open orders and update the amount to 0 (cancelling them). The code below assumes that you're trading XLM for an asset
and have an Account loaded.
KeyPair pair = account.getKeyPair();
Page<OfferResponse> openOffers = server.offers().forAccount(pair).limit(100).execute();
//Get number of open bids
int numBids = openOffers.getRecords().size();
for (int x = 0; numBids > x; x++){
long offerID = openOffers.getRecords().get(x).getId();
ManageOfferOperation deleteOffer = new ManageOfferOperation.Builder(new AssetTypeNative(), asset, "0", "1").setSourceAccount(pair).setOfferId(offerID).build();
Transaction transaction = new Transaction.Builder(account.getAccountResponse()).addOperation(deleteOffer).build();
SubmitTransactionResponse response = server.submitTransaction(transaction);
transaction.sign(pair);
}
I tested this and its a bit slow, but works (could always multithread).
-
4You can add up to 100 operations to a single transaction so it should speed this up. Commented Feb 4, 2018 at 22:31
Since there is no method for canceling all your offers in one go, you need to submit many manageOfferOp
together, one for each offer. The good news is that you can submit up to 100 of this operations in one transaction.
I included a script that does exactly this, first it retrieves the first page of offers you have open and creates a transaction to cancel all of them, then moves on the next page to cancel them and so on.
var StellarSdk = require('stellar-sdk')
StellarSdk.Network.useTestNetwork();
let server = new StellarSdk.Server('https://horizon-testnet.stellar.org')
function parseAsset(asset) {
if (asset.asset_type == 'native') {
return StellarSdk.Asset.native();
} else {
return new StellarSdk.Asset(asset.asset_code, asset.asset_issuer);
}
}
function cancelOffers(kp, account, res) {
let offers = res.records;
if (offers.length == 0) {
return;
}
let operations = offers.map(offer => {
// map offer to offer operation
let buying = parseAsset(offer.buying);
let selling = parseAsset(offer.selling);
return StellarSdk.Operation.manageOffer({
buying: buying,
selling: selling,
amount: '0',
price: offer.price_r,
offerId: offer.id,
});
});
let builder = new StellarSdk.TransactionBuilder(account);
builder.operations = operations;
let tx = builder.build();
tx.sign(kp);
server.submitTransaction(tx).then(tx_res => {
console.log(tx_res);
}).then(() => {
// if you have more than 100 offers, you need to retrieve
// the next page.
res.next().then(account, offers => cancelOffers(kp, account, offers));
});
}
// Create transaction with first signer
let kp = StellarSdk.Keypair.fromSecret('SAD6NO7EOFZX25B2TJIHQM3JXNRFRAHEDRREV5NXDZC5PN23AHXLFBCZ')
server.loadAccount(kp.publicKey()).then(account => {
server.offers('accounts', kp.publicKey()).call().then(offers => {
return cancelOffers(kp, account, offers);
});
});