I want to send non-native assets to new stellar accounts. To do this, I understand that I need to create a new account by funding it with XLM (1 XLM minimum), add a trust line to the asset issuer and then transfer the asset from my account to the new account. I want to do this in one transaction. This is what I have so far:

var sourceKeys = StellarSdk.Keypair.fromSecret(sourceaccountkey);
let builder = new StellarSdk.TransactionBuilder(sourceAccount);
builder.addOperation(StellarSdk.Operation.createAccount({
    destination: destinationId,
    startingBalance: sendamount
}));

// This operation needs to be done on the receiver account, but the builder object belongs to the source account
builder.addOperation(
    StellarSdk.Operation.changeTrust({
        asset: new StellarSDK.Asset(assetcode, assetissueraddress)
    })
);

// Assuming the above is even possible, how do I sign with both source and receiver account keys?
transaction.sign(sourceKeys);

Any help is much appreciated. Thanks.

up vote 2 down vote accepted

1. Prepare keypairs for all participating accounts - source account and destination account.

let source = StellarSdk.Keypair.fromSecret(sourceAccountSecretKey)
let dest = StellarSdk.Keypair.fromSecret(destinationAccountSecretKey)

Keypair for the destination account can be generated using StellarSdk.Keypair.random().

2. Load current source account state from Horizon server

let sourceAccount = await horizon.loadAccount(source.publicKey())

3. Create a transaction builder

let builder = new StellarSdk.TransactionBuilder(sourceAccount)

4. Add CREATE_ACCOUNT operation

builder.addOperation(StellarSdk.Operation.createAccount({
     destination: dest.publicKey(),
     startingBalance: '1.6'
}))

The starting balance should be enough to satisfy the minimum account balance requirement(1 XLM), trustline reserve (0.5 XLM), and a few more stroops to pay transaction fees (0.1 XLM).

5. Add CHANGE_TRUST operation to establish trustline

builder.addOperation(StellarSdk.Operation.changeTrust({ 
    asset: new StellarSDK.Asset(assetCode, assetIssuerAddress),
    source: dest.publicKey()
}))

Note that source parameter contains a public key of our destination account because we perform this operation on behalf of the destination account.

6. Add PAYMENT operation to transfer your custom asset

builder.addOperation(StellarSdk.Operation.payment({ 
    destination: dest.publicKey(),
    asset: new StellarSDK.Asset(assetCode, assetIssuerAddress),
    amount: '100'
}))

7. Build and sign transaction with both source and destination keypairs

let tx = builder.build()

tx.sign(source)
tx.sign(dest)

8. Submit transaction to network

let txResult = await horizon.submitTransaction(tx)

Also check the detailed walkthrough describing the basic account creation process.

  • Wow!!! Thank you much. My main confusion was in step 5. I didn't know anyone can add a trust line to anyone' account. Thanks. Also, since the sender account pays for the transaction fees, is it really necessary to create an account with 1.6 XLM? Wouldn't 1.5 XLM be sufficient? – NBC Oct 9 at 0:35
  • In order to submit an operation on behalf of another account, you just need to sign the tx with both keypairs. The signature itself is a proof of permission from the account. – Orbit Lens Oct 9 at 1:03
  • 1.5 XLM won't be sufficient because the account you created will be unable to submit any transactions (payments, trades, whatever) because the account balance can't be lower than the minimum required balance (1.5XLM) in this case. So the destination account will be effectively blocked, unless the the user will fund it itself. You can create an account with 1.51 XLM, it will be enough top pay tx fees for 100 transactions with current base_fee level. – Orbit Lens Oct 9 at 1:09
  • Thank you much. – NBC Oct 9 at 3:36

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.