Closed johansten closed 6 years ago
+1
It would be really nice to have, especially the trust line creation part. It would make the gateway trusting kind of like authorising a Facebook app - painelss and quick, and the wallet could actually explain the what it means to trust a gateway (in words that the user would understand).
Maybe a return URI would also be beneficial? Ie when the client app has completed the requested operation it directs the user back to a given URL/mobile app instead of remaining open and leaving the user hanging. That way the gateway/merchant who requested the transaction can either show a thank you message or let the user try again if the user cancelled the payment.
@johansten I'd love to see this proposal updated for the new stellar network.
From a slack discussion on URLs and QR code support, I think it would be helpful to gather use cases for things that a stellar protocol should be able to do.
I think having specific examples to reference would make it much easier to evaluate various proposals since you could give an example URI referencing the use case.
Here are some to get started:
Payment request
A user should be able to click a URL and be prompted to pay an amount
to an address
Import keys A user should be able to add a key or account to a wallet
Import contacts A user should be able to add an address (along with a human-friendly label) to the list of contacts in their wallet
Signing request
A user should be able to sign a message
with their private key and make the signature available to a callback URL
Add trust line
Request that a user add a trustline for an asset
and then call a callback URL
So the priority for this protocol is efficiency and its target is a machine not a human being. With that in mind, I think we should dial the priority of human readability down a notch and focus on making this an efficient protocol optimized for machine use and should be easily encodable into (and more importantly, reliably useable in) QR format.
Building on the work done by @sacarlson and @johansten I propose the following as a first concept draft open for review. It addresses the first two use cases outlined above by @zulucrypto and we can work on the others once we make some progress with this.
Proposed Stellar.org URI/QR code formats:
SIMPLE PAYMENTS REQUEST:
stellar://spmt:{d:DESTINATION_ACCOUNT_ID,n:NETWORK_CODE,a:AMOUNT,s:{c:ASSET_CODE,i:ASSET_ISSUER},m:{t:MEMO_TYPE,x:MEMO},q:FEDERATION_DOMAIN,v:VERSION}
ESCROW PAYMENTS REQUEST:
stellar://epmt:{d:DESTINATION_ACCOUNT_ID,n:NETWORK_CODE,a:AMOUNT,s:{c:ASSET_CODE,i:ASSET_ISSUER},m:{t:MEMO_TYPE,x:MEMO},q:FEDERATION_DOMAIN,u:ORDER_STATUS,b:{z:THIRD_PARTY_ACCOUNT_ID,w:EMAIL_ADDRESS,y:EXPIRY TIMESTAMP,g:STATUS_MESSAGES,f:FEE,l:WEBHOOK_URL},j:PROTOCOL,v:VERSION}
CONTACT:
stellar://acct:{i:ACCOUNT_ID,n:NETWORK_CODE,e:SURNAME;FIRSTNAME;OTHER_NAME0;OTHER_NAME1,o:COMPANY_NAME,p:WORK_TEL;MOBILE_TEL,l:WEBHOOK_URL,w:EMAIL_ADDRESS,h:DELIMITED_ADDRESS_FIELDS,j:PROTOCOL,v:VERSION}
CHALLENGE/RESPONSE:
stellar://chlg:{i:ACCOUNT_ID,m:MESSAGE,l:WEBHOOK_URL,v:VERSION}
ACCOUNT EXPORT/IMPORT:
stellar://xprt:{n:NETWORK_CODE,k:SEED,v:VERSION}
stellar://xprt:{n:NETWORK_CODE,r:ENCRYPTEDSEED,v:VERSION}
VERSION*: Protocol version number (single case-sensitive character [0-9a-zA-Z])
DESTINATION_ACCOUNT_ID* = self explanatory
NETWORK_CODE = Network is only needed if not stellar.org live network otherwise 'N'. It is the first eight hex characters of the SHA-256 hash of the network passphrase,
function getHash(passphrase) { return new StellarSdk.Network(passphrase).networkId().toString('hex').slice(0, 8); }
Examples:
Live net - "7ac33997"
Test net - "cee0302d"
AMOUNT* = self explanatory
ASSET_CODE* = Asset is only needed if not XLM otherwise 'N'
ASSET_ISSUER = this would be the trustline ID if it is needed
MEMO_TYPE = N/T/I/H/R (None/Text/ID/Hash/Return Hash)
MEMO = self explanatory
FEDERATION_DOMAIN: optional federation server domain name if it exists (eg domain.tld)
ORDER_STATUS: This will be what state the store sees this tx_tag order in, 'N' means it does not yet exist. when already paid this becomes a value of 0 - X indicating that the order has already been paid or had an error and prevents the wallet from allowing to pay more than 1 time.
THIRD_PARTY_ACCOUNT_ID: This is the 3rd party escrow agents publicID that becomes a signer in the escrow contract
EXPIRY TIMESTAMP: 1490574272 // timestamp of expire time when the store can recover it's funds with no reponse from the buyer.
STATUS_MESSAGE: Special status message state information of the excrow contract
FEE: This is the escrow service fee in XLM that is sent to the 3rd party escrow agent, this fee is optional depending on what the 3rd party wants to charge.
PROTOCOL: This is the escrow protocol version in use or in the context of CONTACT it the last revision (vcard REV), date of last update (YYYYMMDDTHHMMSSZ eg: 20171104T193000Z)
EMAIL_ADDRESS: self explanatory in the contact context/the email contact info for the 3rd party escrow agent in the payments request context
ACCOUNT_ID* = Stellar account Public Key of the contact
SURNAME: self explanatory
FIRSTNAME: self explanatory
OTHER_NAME0: Could be online handle/nickname or middle name
OTHER_NAME1: Could be online handle/nickname or middle name
COMPANY_NAME: self explanatory
AREA_CODE: Full PSTN countrycode or area code (eg: +44 or +1604 etc)
WORK_TEL: Full international PSTN local telephone number (eg: +442031234567 or +16043334444 etc)
MOBILE_TEL: local mobile number (eg: +447771234567 or +16043334444 etc)
DELIMITED_ADDRESS_FIELDS: Address delimited by ';' (content fields are in order: Post Office Address; Extended Address; Street; Locality; Region; Postal Code; Country)
MESSAGE*: Challenge response message
WEBHOOK_URL: Callback URL in the context of challenge/response, company or personal website in the context of the contact information and callback URL that the wallet will submit the escrow transaction package to after the customer confirms payment from the wallet in the context of payments request.
SEED: Standard account private key
ENCRYPTEDSEED: Encrypted account private key
*: Mandatory fields. All non-mandatory key values must be represented by 'N' if not in use
-hatter
I think we should separate the discussion of URIs and QR codes since URIs have many more uses than just QR codes. QR codes could also be optimized once we have a URI format or in some cases could just point a generic QR code reader to a website that forwards to a stellar://
URI, which would then be opened by a protocol handler on their device (aka a Stellar Wallet).
Regarding the URI format, I think we should avoid mixing JSON into the URI. That makes it necessary to do two kinds of encoding/escaping when I think standard URI libraries would already support what we need and exist for every platform.
Here's how I'd propose changing one of your examples to use a purely URI approach:
SIMPLE PAYMENTS REQUEST:
stellar://v1/payment?d=DESTINATION_ACCOUNT&n=NETWORK_CODE&a=AMOUNT&c=ASSET_CODE&i=ASSET_ISSUER&mt=MEMO_TYPE&m=MEMO&Q=FEDERATION_DOMAIN
Some reasons I like sticking with a URI-style format:
The only thing I've heard everyone agree on is that the protocol should start with stellar://
, so let's take that as our first part of the standard. :)
Ignoring QR codes for now (I think they should be a separate discussion/standard), let's see if we can get agreement on:
Should the stellar:// protocol use a plain URI format or encode fields with JSON?
@zulucrypto I have no problem with plain url format but if we needed to use the same variable type twice to refer to the variable for two different users, eg in a multi-signature environment, the nesting helps keep things cleanly separated.
Might I suggest using a hybrid with nesting as necessary. Just a thought.
-hatter
@zulucrypto can you outline how this will work with federation forward?
e.g.:
@smdwireless That's a great point and probably the biggest weakness of staying with URIs.
Although there's no standard way to encode an array in a URI the two methods I've seen are:
[]
notation: ?signer[]=G123&signer[]=G234
(supported by PHP, Rails, and Angular)?signer=G123&sigher=G234
(supported by Angular)Since (to the best of my knowledge) 1 is the most widely supported, I'd vote for that.
Example request to add two contacts in a single url
stellar://v1/add-contact?address[]=G123&label[]=Poloniex&address[]=G456&label[]=Bittrex
The protocol handler would parse the arrays in the order they appeared in the URI and then match up addresses and labels by index:
$addresses = ['G123', 'G456'];
$labels = ['Poloniex', 'Bittrex'];
// Therefore, 'Poloniex' has address 'G123'
Looks like this is the next thing to decide (if we go with URIs): How should multiple values for a single field be encoded?
@tempofr you have raised a valid point... using a plain url method would lead to collisions and ambiguities in the decoding of the data. It doesn't lend well to having urls as variables either, you will need to urlencode them which brings us right back to the issue of saving characters.
-hatter
@zulucrypto
Looks like this is the next thing to decide (if we go with URIs): How should multiple values for a single field be encoded?
Honestly it seems it will be back to key=>value pair nesting... ie: JSON notation
Otherwise the number of times you'll have to parse to get your data out will make for much more resource intensive operations than simply using the built-in JSON interpreter.
-hatter
@tempofr I believe in that case you could URL-encode the parameters and pass them as a forward
parameter in the stellar://
protocol URL.
For your example above:
Url encode the forwarding portion. forward_type=bank_account&swift=BOPBPHMM&acct=2382376
becomes forward_type%3Dbank_account%26swift%3DBOPBPHMM%26acct%3D2382376
Include this in a payment request:
// URL format:
stellar://v1/payment?d=zulucrypto*tempo.fr&forward=<url encoded data from #1>
// Final URL:
stellar://v1/payment?d=zulucrypto*tempo.fr&forward=forward_type%3Dbank_account%26swift%3DBOPBPHMM%26acct%3D2382376
When I clicked on the above URL the wallet application would see that the destination was not a stellar address and it would do a federation lookup:
stellar.toml
for tempo.fr
FEDERATION_SERVER
from stellar.toml
FEDERATION_SERVER
an adds the (decoded) forward
parameter from the stellar://
url. The final URL requested by the wallet ends up being https://FEDERATION_SERVER/federation?type=forward&forward_type=bank_account&swift=BOPBPHMM&acct=2382376
@smdwireless Could you look at my comment to tempofr RE: forwarding and see if that would work? If not, could you provide an example where there would be a collision or ambiguity?
@zulucrypto I will run some scenarios and come back with results either way. Hopefully this can work.
-hatter
@zulucrypto other than the increased character count from using the encoding, it seems to work just fine. I'm just not sure how much is saved by not using JSON notation... it seems this makes for a longer URI.
-hatter
@smdwireless Great, thanks for looking into it.
I'll start work on defining and supporting some exact URLs as part of working on my browser extension (https://galactictalk.org/d/505-comments-requested-secure-browser-extension/6).
I'd appreciate any other use cases people could add since they'd help me come up with a good API for the extension.
Everyone interested see discussion going on here: https://github.com/stellar/stellar-protocol/pull/95
https://github.com/pollen23/stellar-uri