URI Scheme to facilitate delegated signing
This guide is available on three different programming languages: Typescript, Kotlin and Flutter (Dart). You can change the shown version on each page via the buttons above.
The Sep-7 standard defines a way for a non-wallet application to construct a URI scheme that represents a specific transaction for an account to sign. The scheme used is web+stellar
, followed by a colon. Example: web+stellar:<operation>?<param1>=<value1>&<param2>=<value2>
Tx Operation​
The tx operation represents a request to sign a specific transaction envelope, with some configurable parameters.
- TypeScript
const sourceAccountKeyPair = "G...";
const destinationAccountKeyPair = "G...";
const txBuilder = await stellar.transaction({
sourceAddress: sourceAccountKeyPair,
});
const tx = txBuilder.createAccount(destinationAccountKeyPair).build();
const xdr = encodeURIComponent(tx.toEnvelope().toXDR().toString("base64"));
const callback = encodeURIComponent("https://example.com/callback");
const txUri = `web+stellar:tx?xdr=${xdr}&callback=${callback}`;
const uri = wallet.parseSep7Uri(txUri);
// uri can be parsed and transaction can be signed/submitted by an application that implements Sep-7
You can set replacements to be made in the xdr for specific fields by the application, these will be added in the Sep-11 transaction representation format to the URI.
- TypeScript
const uri = new Sep7Tx(txUri);
uri.addReplacement({
id: "X",
path: "sourceAccount",
hint: "account from where you want to pay fees",
});
You can assign parameters after creating the initial instance using the appropriate setter for the parameter.
- TypeScript
const sourceAccountKeyPair = "G...";
const destinationAccountKeyPair = "G...";
const txBuilder = await stellar.transaction({
sourceAddress: sourceAccountKeyPair,
});
const tx = txBuilder.createAccount(destinationAccountKeyPair).build();
const uri = wallet.Sep7Tx.forTransaction(tx);
uri.callback = "https://example.com/callback";
uri.msg = "here goes a message";
uri.toString(); // encodes everything and converts to a uri string
Pay Operation​
The pay operation represents a request to pay a specific address with a specific asset, regardless of the source asset used by the payer. You can configure parameters to build the payment operation.
- TypeScript
const destination = "G...";
const assetIssuer = "G...";
const assetCode = "USDC";
const amount = "120.1234567";
const memo = "memo";
const message = encodeURIComponent("pay me with lumens");
const originDomain = "example.com";
const payUri = `web+stellar:pay?destination=${destination}&amount=${amount}&memo=${memo}&msg=${message}&origin_domain=${originDomain}&asset_issuer=${assetIssuer}&asset_code=${assetCode}`;
const uri = parseSep7Uri(payUri);
// uri can be parsed and transaction can be built/signed/submitted by an application that implements Sep-7
You can assign parameters after creating the initial instance using the appropriate setter for the parameter.
- TypeScript
const uri = wallet.Sep7Pay.forDestination("G...");
uri.callback = "https://example.com/callback";
uri.msg = "here goes a message";
uri.assetCode = "USDC";
uri.assetIssuer = "G...";
uri.amount = "10";
uri.toString(); // encodes everything and converts to a uri string
The last step after building a Sep7Tx
or Sep7Pay
is to add a signature to your uri. This will create a payload out of the transaction and sign it with the provided keypair.
- TypeScript
const uri = wallet.Sep7Pay.forDestination("G...");
uri.originDomain = "example.com";
const keypair = wallet.stellar().account().createKeypair();
uri.addSignature(Keypair.fromSecret(keypair.secretKey));
console.log(uri.signature); // signed uri payload
The signature can then be verified by fetching the Stellar toml file from the origin domain in the uri, and using the included signing key to verify the uri signature. This is all done as part of the verifySignature
method.
- TypeScript
const passesVerification = await uri.verifySignature(); // true or false