> ## Documentation Index
> Fetch the complete documentation index at: https://developers.stellar.org/llms.txt
> Use this file to discover all available pages before exploring further.

# URI Scheme to facilitate delegated signing

> 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.

> [!NOTE]
>
> This guide is available on four different programming languages: Typescript, Kotlin, Flutter (Dart) and Swift. You can change the shown version on each page via the buttons above.

> [!CAUTION]
>
> **Important**
>
> Documentation for this language is currently work in progress. Some of information may not be applicable for this language, or missing. Code samples may be incomplete.

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**

```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
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
```

**Flutter**

```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
final sourceAccountKeyPair = PublicKeyPair.fromAccountId('G...');
final destinationAccountKeyPair = PublicKeyPair.fromAccountId('G...');
var txBuilder = await stellar.transaction(sourceAccountKeyPair);
final tx = txBuilder.createAccount(destinationAccountKeyPair).build();
final xdr = Uri.encodeComponent(tx.toEnvelopeXdrBase64());
final callback = Uri.encodeComponent('https://example.com/callback');
final txUri = 'web+stellar:tx?xdr=$xdr&callback=$callback';
final uri = wallet.parseSep7Uri(txUri);
// uri can be parsed and transaction can be signed/submitted by an application that implements Sep-7
```

**Swift**

```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
let sourceAccountKeyPair = try PublicKeyPair(accountId: "G...")
let destinationAccountKeyPair = try PublicKeyPair(accountId: "G...")
let txBuilder = try await stellar.transaction(sourceAddress: sourceAccountKeyPair)
let tx = try txBuilder.createAccount(newAccount: destinationAccountKeyPair).build()
let xdr = try tx.encodedEnvelope().addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) // url encoded
let callback = "https://example.com/callback".addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)  // url encoded
let txUri = "web+stellar:tx?xdr=\(xdr!)&callback=\(callback!)"
let uri = try wallet.parseSep7Uri(uri: 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**

```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const uri = new Sep7Tx(txUri);
uri.addReplacement({
  id: "X",
  path: "sourceAccount",
  hint: "account from where you want to pay fees",
});
```

**Flutter**

```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
final uri = wallet.parseSep7Uri(txUri);

if (uri is Sep7Tx) {
    uri.addReplacement(Sep7Replacement(
        id: 'X',
        path: 'sourceAccount',
        hint: 'account from where you want to pay fees'));
}
```

**Swift**

```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
let uri = try wallet.parseSep7Uri(uri: txUri)

if let uri = uri as? Sep7Tx {
    let replacement = Sep7Replacement(id:"X",
                                      path:"sourceAccount",
                                      hint: "account from where you want to pay fees")

    uri.addReplacement(replacement: replacement)
}
```

You can assign parameters after creating the initial instance using the appropriate setter for the parameter.

**TypeScript**

```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
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
```

**Flutter**

```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
final sourceAccountKeyPair = PublicKeyPair.fromAccountId('G...');
final destinationAccountKeyPair = PublicKeyPair.fromAccountId('G...');
var txBuilder = await stellar.transaction(sourceAccountKeyPair);
final tx = txBuilder.createAccount(destinationAccountKeyPair).build();

final uri = Sep7Tx.forTransaction(tx);
uri.setCallback('https://example.com/callback');
uri.setMsg('here goes a message');
uri.toString(); // encodes everything and converts to a uri string
```

**Swift**

```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
let sourceAccountKeyPair = try PublicKeyPair(accountId: "G...")
let destinationAccountKeyPair = try PublicKeyPair(accountId: "G...")
let txBuilder = try await stellar.transaction(sourceAddress: sourceAccountKeyPair)
let tx = try txBuilder.createAccount(newAccount: destinationAccountKeyPair).build()

let uri = try Sep7Tx(transaction: tx)
uri.setCallback(callback: "https://example.com/callback")
try uri.setMsg(msg: "here goes a message")
let uriStr = 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**

```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
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
```

**Flutter**

```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
const destination = 'G...';
const assetIssuer = 'G...';
const assetCode = 'USDC';
const amount = '120.1234567';
const memo = 'memo';
final message = Uri.encodeComponent('pay me with lumens');
const originDomain = 'example.com';
final payUri = 'web+stellar:pay?destination=$destination&amount=$amount&memo=$memo&msg=$message&origin_domain=$originDomain&asset_issuer=$assetIssuer&asset_code=$assetCode';
final uri = Sep7.parseSep7Uri(payUri);
// uri can be parsed and transaction can be built/signed/submitted by an application that implements Sep-7
```

**Swift**

```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
let destination = "G..."
let assetIssuer = "G..."
let assetCode = "USDC"
let amount = "120.1234567"
let memo = "memo"
let message = "pay me with lumens".addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) // url encoded
let originDomain = "example.com"
let payUri = "web+stellar:pay?destination=\(destination)&amount=\(amount)&memo=\(memo)&msg=\(message!)&origin_domain=\(originDomain)&asset_issuer=\(assetIssuer)&asset_code=\(assetCode)"
uri = try Sep7.parseSep7Uri(uri: 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**

```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
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
```

**Flutter**

```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
final uri = Sep7Pay.forDestination('G...');
uri.setCallback('https://example.com/callback');
uri.setMsg('here goes a message');
uri.setAssetCode('USDC');
uri.setAssetIssuer('G...');
uri.setAmount('10');
uri.toString(); // encodes everything and converts to a uri string
```

**Swift**

```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
let uri = Sep7Pay(destination: "G...")
uri.setCallback(callback: "https://example.com/callback")
try uri.setMsg(msg: "here goes a message")
uri.setAssetCode(assetCode: "USDC")
uri.setAssetIssuer(assetIssuer: "G...")
uri.setAmount(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**

```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
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
```

**Flutter**

```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
final uri = Sep7Pay.forDestination('G...');
uri.setOriginDomain('example.com');
final keypair = wallet.stellar().account().createKeyPair();
uri.addSignature(keypair);
print(uri.getSignature()); // signed uri payload
```

**Swift**

```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
uri = Sep7Pay(destination: "G..")
uri.setOriginDomain(originDomain: "example.com")
let keyPair = wallet.stellar.account.createKeyPair()
try uri.addSignature(keyPair: keyPair)
print(uri.getSignature()) // 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**

```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const passesVerification = await uri.verifySignature(); // true or false
```

**Flutter**

```dart theme={"theme":{"light":"github-light","dark":"github-dark"}}
final passesVerification = await uri.verifySignature(); // true or false
```

**Swift**

```swift theme={"theme":{"light":"github-light","dark":"github-dark"}}
let passesVerification = await uri.verifySignature() // true or false
```

[Sep-7]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0007.md

[Sep-11 transaction representation format]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0011.md

[some configurable parameters]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0007.md#operation-tx

[configure parameters]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0007.md#operation-pay

[Stellar toml file]: https://developers.stellar.org/docs/build/apps/example-application-tutorial/anchor-integration/sep1.md
