1

Sorry for the newbie question...

When a user subscribes to my service, I would like to:

  1. Create a new stellar account for the subscriber
  2. Seed it with 1.5 XLM (to activate it)
  3. Create a Trustline and then
  4. Send it a custom asset

How can I do this?

TIA!

1

1) You need a core + horizon server to have access to the stellar network but for the beginning you can simply start with the public ones provided by SDF (Stellar Development Foundation).

2) Pick a sdk for the language of your choice, it's api will give you all methods you need to query stellar accounts and create transactions.

3) Learn what you need to know about stellar transactions. In a nutshell: A transaction has a source account which is going to take the network transaction fees. It wraps one or more operations like payments or changing trustlines. By default operations apply to the transactions source account but you can define a different source account for each operation as well. This means you can complete your use case in a single transaction:

  • Generate a keypair for your new user
  • Create transaction from a well funded account
    • Add Operation: Create user account with starting balance of 1.5 XLM
    • Add Operation: Create a trustline from user to your asset
    • Add Operation: Send asset tokens to user
  • Sign tx with your own keypair (keypairs, if different accounts involved)
  • Sign tx with the new users keypair
  • Submit it to the network.

An easy way to get used to transactions is playing around with Stellar Laboratory Transaction Builder

4) Implement it, here is an example in javascript:

const StellarSdk = require('stellar-sdk');

(async () => {

    try {
        StellarSdk.Network.useTestNetwork();
        const horizon = new StellarSdk.Server('https://horizon-testnet.stellar.org');

        // Generate keypair for a new account
        // You might want to do this on the client side so new users
        // would not expose their secret keys
        const newAccountKeypair = StellarSdk.Keypair.random();

        // This account creates the tx and funds the new account
        const txCreatorKeypair = StellarSdk.Keypair.fromSecret(
            'SBUBZYQPOYPCKCMGEZ6OPFIJSL4DCOK6VDP6I2SWF7VKFRHASKLVPDV4'
        );

        // This is the asset issuers account
        const assetIssuerKeypair = StellarSdk.Keypair.fromSecret(
            'SDSAMCM7PVBMLTRINCTCXOKHK2V7H42OFWDMAD7GUEM2P4FWTYYBBJHX'
        );

        // Our custom asset is defined by its asset code and the issuers accountID
        const asset = new StellarSdk.Asset(
            'GUINEAPIGS',
            assetIssuerKeypair.publicKey()
        );

        // Load account, cause tx needs its sequence number + 1
        const account = await horizon.loadAccount(txCreatorKeypair.publicKey());

        // Build a transaction...
        const transaction = await new StellarSdk.TransactionBuilder(account)

            .setTimeout(5000)

            // ... with a createAccount operation for the new acc
            .addOperation(StellarSdk.Operation.createAccount({
                startingBalance: '1.5',
                destination: newAccountKeypair.publicKey()
            }))

            // ... create a trustline
            .addOperation(StellarSdk.Operation.changeTrust({
                asset: asset,
                source: newAccountKeypair.publicKey()
            }))

            // ... send 100 fresh minted tokens from issuer
            .addOperation(StellarSdk.Operation.payment({
                asset: asset,
                destination: newAccountKeypair.publicKey(),
                amount: '100',
                source: assetIssuerKeypair.publicKey(),
            }))
            .build();

        // Needs to sign because its creating tx and funding XLM
        transaction.sign(txCreatorKeypair);

        // Needs to sign because funding custom asset
        transaction.sign(assetIssuerKeypair);

        console.log("==========================");
        console.log('This is the transaction signed by creator + issuer: ' + transaction.toEnvelope().toXDR('base64') );
        console.log("==========================");

        // Needs to sign because it gets a trustline created
        // Needs to be done on client side if secret is not shared.
        transaction.sign(newAccountKeypair);

        console.log("Submitting to network...");
        const result = await horizon.submitTransaction(transaction);

        console.log("Transaction successfully sent and recorded in ledger " + result.ledger);
        console.log("txhash = " + result.hash);
        console.log("New account public: " + newAccountKeypair.publicKey() );
        console.log("New account secret: " + newAccountKeypair.secret() );

    } catch (e) {
        console.log(e);
    }

})();

  • Thanks sui! Will try this now and let you know. – TKT Feb 26 at 22:02
  • One thing to note is that you can't open a trustline for your users, they will have trust your asset themselves. They can do so by submitting a transaction from the Stellar Laboratory. – Carl Vitullo Feb 28 at 23:46
  • There's a core advancement proposal to change this behavior, but it's still a draft github.com/stellar/stellar-protocol/blob/master/core/… – Carl Vitullo Feb 28 at 23:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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