eigerco / nebula

A soroban contract library
https://nebula.eiger.co
Apache License 2.0
7 stars 2 forks source link

Marketplace contract - trustlines creation #103

Open eloylp opened 10 months ago

eloylp commented 10 months ago

Summary

During the development of https://github.com/eigerco/nebula/issues/90 we realised that we might have to properly declare the trustline relation between the NFTs that are being sold, to the respective buyers or new owners.

As far as we know, trustlines are needed in order to one account to receive balance of an specific stellar asset contract address. This was reflected on this comment links documentation, so we proceeded to create a little script (See #101) that follows those steps and creates the NFT with the indicated trustlines.

In order to reply to this questions, some checks can be done:

Motivations

We want to provide an end to end solution for an NFT marketplace, thus this research issue will help to stablish what are the new horizons after our initial fix, that may provide more components for building a final Dapp marketplace application.

Final conclusion

Waiting for research.

geofmureithi commented 10 months ago

I did give it a try to see how to approach the specific problem. Here is some code:

const possibleReceiver = "" // ...keypair..
async function addNewTrustLine() {
  let receiver = await server.loadAccount(
    possibleReceiver.publicKey()
  );
  let transaction = new StellarSdk.TransactionBuilder(receiver, {
    networkPassphrase: StellarSdk.Networks.TESTNET,
    fee,
  }).addOperation(
    StellarSdk.Operation.changeTrust({
      asset: eigerNft,
      limit: "0.0000001",
      source: distributorKeyPair.publicKey(),
    })
  );
  transaction.sign(possibleReceiver);
  transaction.sign(distributorKeyPair);
}

This code should work but it still has the same flaws, you need both keypairs of the recipient and the distributor. Failing to sign with either gives the following error:

data: {
      type: 'https://stellar.org/horizon-errors/transaction_failed',
      title: 'Transaction Failed',
      status: 400,
      detail: 'The transaction failed when submitted to the stellar network. The `extras.result_codes` field on this response contains further details.  Descriptions of each code can be found at: https://developers.stellar.org/api/errors/http-status-codes/horizon-specific/transaction-failed/',
      extras: {
        envelope_xdr: 'AAAAAgAAAAAgIrRAsWtmz2GYHN/hk7YAMah9UShMcCQKJZP4lLVYvAAAAGQAJpjDAAAAAQAAAAEAAAAAAAAAAAAAAABlVGiqAAAAAAAAAAEAAAABAAAAAATzbT6Ypxhjvruur/FETdob/rynR2T3+eul+gfD7lbzAAAABgAAAAJFaWdlck5GVAAAAAAAAAAAhqIkQdi3QuryT3+4Zt6KJCyItppRcFF/gZWmLceGvEcAAAAAAAAAAQAAAAAAAAABlLVYvAAAAEC64KeLNX9ySrQEI3Ko2UjCV3jSoMt8J+92EBgmQKflUaBefhMC0Wym7pRdGCHhhwGA5Lyw2GC3uHxj/H6/OekM',
        result_codes: { transaction: 'tx_failed', operations: [ 'op_bad_auth' ] },
        result_xdr: 'AAAAAAAAAGT/////AAAAAf////8AAAAA'
      }
    }

Considering that this requires the recipient key pair, this is not ideal. Let me know your thoughts.

eloylp commented 10 months ago

Thanks for the test @geofmureithi . What about signing a transaction in one side (i.e the distributor) and then send it (maybe serialized) to the next party who needs to sign it and in the last step, actually submitting it to the network ?

This would be a multiparty signing process. The transaction just needs to be signed by multiple accounts, but the private keys of such accounts always remains on different machines. Its just the transaction what is needed and passed everywhere, not the private keys.

If the above works, on my mind a solution for this passes with a wallet integration. The marketplace should present the buyers a template transaction already signed by the issuer. Maybe this would be responsibility of each NFT. I dont know, this is a black box for me right now.

geofmureithi commented 10 months ago

What about signing a transaction in one side (i.e the distributor) and then send it (maybe serialized) to the next party who needs to sign it and in the last step, actually submitting it to the network ?

There is no such functionality in stellar as far as I know. The code shown only has a single operation. I don't think your approach is practical right now.