@stellar-snaps/sdk 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -95,7 +95,29 @@ if (result.successful) {
95
95
  }
96
96
  ```
97
97
 
98
- ### 4. Create Shareable Snaps (Web App API)
98
+ ### 4. Payment flow (payment route like the web app)
99
+
100
+ Implement a **payment route** (e.g. `/s/[id]`) with the same behavior as stellar-snaps.vercel.app: fetch the snap, then run the full pay flow (Freighter connect → build tx → sign → submit) in one call.
101
+
102
+ ```typescript
103
+ import { getSnap, executeSnapPayment, getTransactionUrl } from '@stellar-snaps/sdk';
104
+
105
+ // On your /s/[id] page: load snap, then on "Pay" click:
106
+ const snap = await getSnap(id, { baseUrl: 'https://your-app.com' });
107
+ const amount = snap.amount ?? userEnteredAmount;
108
+
109
+ const result = await executeSnapPayment({ snap, amount });
110
+
111
+ if (result.successful) {
112
+ const explorerUrl = getTransactionUrl(result.hash, snap.network as 'public' | 'testnet');
113
+ console.log('Paid! View:', explorerUrl);
114
+ }
115
+ ```
116
+
117
+ - **`getAccountSequence(publicKey, network)`** – Fetches account sequence from Horizon (for building a transaction).
118
+ - **`executeSnapPayment({ snap, amount })`** – Full flow: connect Freighter, build payment tx, sign with Freighter, submit. Same behavior as the web app’s “Pay with Stellar” button. **Browser only** (requires Freighter).
119
+
120
+ ### 5. Create Shareable Snaps (Web App API)
99
121
 
100
122
  Create, fetch, list, and delete database-backed snaps—same behavior as the web dashboard. Uses `https://stellar-snaps.vercel.app` by default.
101
123
 
@@ -148,7 +170,7 @@ openSnapModal(url, {
148
170
  // User sees the same payment UI as stellar-snaps.vercel.app/s/xxx in an overlay
149
171
  ```
150
172
 
151
- ### 5. Host Your Own Snap Endpoints
173
+ ### 6. Host Your Own Snap Endpoints
152
174
 
153
175
  Create a discovery file to enable the browser extension to find your snaps:
154
176
 
@@ -166,6 +188,40 @@ const discovery = createDiscoveryFile({
166
188
  // Save as: public/.well-known/stellar-snap.json
167
189
  ```
168
190
 
191
+ ### 7. Build your own project (full flow)
192
+
193
+ Everything in the stellar-snaps web app can be built in **your own project** using only this SDK. Use the same APIs and flows so creators can create snaps, share URLs, and payers can pay from your domain.
194
+
195
+ **1. Backend (your server or serverless)**
196
+
197
+ | Endpoint | Purpose | SDK usage |
198
+ |----------|---------|-----------|
199
+ | `POST /api/snaps` | Create snap, return `{ id, ... }` | Store snap in your DB; return `id`. Use `validateSnapInput`, `createSnapObject`, `generateSnapId` from SDK. |
200
+ | `GET /api/snap/[id]` | Get full snap | Return snap from DB. |
201
+ | `GET /api/metadata/[id]` | Snap metadata for extension | Same as above; return flat object: `id`, `title`, `destination`, `amount`, `assetCode`, `assetIssuer`, `memo`, `memoType`, `network`. |
202
+ | `POST /api/build-tx` | Build XDR for extension | `buildPaymentXdrFromPayload(req.body)` → return `{ xdr }`. Extension calls this when user clicks "Pay with Stellar" on your snap links. |
203
+ | `DELETE /api/snaps?id=...&creator=...` | Delete snap | Optional; enforce creator ownership. |
204
+
205
+ **2. Payment page (e.g. `/s/[id]`)**
206
+
207
+ - Load snap: `getSnap(id, { baseUrl: 'https://your-app.com' })`.
208
+ - On "Pay" click: `executeSnapPayment({ snap, amount })` (browser only; requires Freighter).
209
+ - Show success: `getTransactionUrl(result.hash, snap.network)`.
210
+
211
+ **3. Discovery file**
212
+
213
+ - Host `/.well-known/stellar-snap.json` with rules mapping your snap path to your metadata API, e.g. `pathPattern: "/s/*"`, `apiPath: "/api/metadata/$1"`. Use `createDiscoveryFile` from the SDK.
214
+
215
+ **4. Extension and registry**
216
+
217
+ - Add your domain to the Stellar Snaps registry (or the registry your extension uses) so the extension shows snap cards for links to your domain.
218
+
219
+ **5. Create snap from your app**
220
+
221
+ - Call `createSnap({ creator, title, destination, ..., baseUrl: 'https://your-app.com' })` from the SDK; use the returned `url` (e.g. `https://your-app.com/s/abc123`) as the shareable link.
222
+
223
+ End-to-end: **create snap** (SDK + your API) → **share URL** → **payer opens `/s/[id]`** (your payment page using `executeSnapPayment`) or **payer sees link on Twitter** → extension fetches metadata and build-tx from your API → **pay with Stellar**. All of this works in your own project using only the library.
224
+
169
225
  ## API Reference
170
226
 
171
227
  ### Shareable Snap API (Web App)
@@ -346,6 +402,42 @@ const xlm = createAsset('XLM');
346
402
  const usdc = createAsset('USDC', 'GA5ZS...');
347
403
  ```
348
404
 
405
+ #### `buildPaymentXdrFromPayload(payload)`
406
+
407
+ Builds payment XDR from the same payload the browser extension sends to `POST /api/build-tx`. Use in your server handler so the extension can build transactions when users click "Pay with Stellar" on your snap links.
408
+
409
+ ```typescript
410
+ // In your POST /api/build-tx handler:
411
+ const xdr = buildPaymentXdrFromPayload(req.body);
412
+ res.json({ xdr });
413
+ ```
414
+
415
+ Payload: `{ source, sequence, destination, amount, assetCode?, assetIssuer?, memo?, memoType?, network? }`. Returns the transaction XDR string.
416
+
417
+ ### Payment Flow (Web App–Style Pay-with-Snap)
418
+
419
+ #### `getAccountSequence(publicKey, network)`
420
+
421
+ Fetches the account's current sequence from Horizon (for building a transaction). Use in browser or Node; requires network access.
422
+
423
+ ```typescript
424
+ const sequence = await getAccountSequence(publicKey, 'testnet');
425
+ ```
426
+
427
+ #### `executeSnapPayment(options)`
428
+
429
+ Runs the full payment flow for a snap: connect Freighter, build payment transaction, sign with Freighter, submit to the network. Same behavior as the web app's "Pay with Stellar" button on `/s/[id]`. **Browser only** (requires Freighter).
430
+
431
+ ```typescript
432
+ const result = await executeSnapPayment({
433
+ snap: await getSnap(id, { baseUrl: 'https://your-app.com' }),
434
+ amount: '10',
435
+ });
436
+ // => { hash: '...', successful: true, ledger?: number }
437
+ ```
438
+
439
+ Use this to implement a payment route (e.g. `/s/[id]`) with the same functionality as stellar-snaps.vercel.app.
440
+
349
441
  ### Freighter Wallet Integration
350
442
 
351
443
  #### `connectFreighter()`
package/dist/index.d.mts CHANGED
@@ -534,6 +534,38 @@ declare function createAsset(code: string, issuer?: string): StellarSdk.Asset;
534
534
  * ```
535
535
  */
536
536
  declare function buildPaymentTransaction(options: BuildPaymentOptions): string;
537
+ /**
538
+ * Payload shape sent by the browser extension to POST /api/build-tx.
539
+ * Use this to implement the build-tx endpoint so the extension can build
540
+ * transactions when users pay from your domain.
541
+ */
542
+ interface BuildTxPayload {
543
+ source: string;
544
+ sequence: string;
545
+ destination: string;
546
+ amount: string;
547
+ assetCode?: string;
548
+ assetIssuer?: string;
549
+ memo?: string;
550
+ memoType?: string;
551
+ network?: Network;
552
+ }
553
+ /**
554
+ * Builds payment transaction XDR from the same payload the browser extension
555
+ * sends to POST /api/build-tx. Use in your server handler so the extension
556
+ * can build transactions when users click "Pay with Stellar" on your snap links.
557
+ *
558
+ * @param payload - Request body: source, sequence, destination, amount, assetCode?, assetIssuer?, memo?, memoType?, network?
559
+ * @returns Transaction XDR string
560
+ *
561
+ * @example
562
+ * ```typescript
563
+ * // In your POST /api/build-tx handler:
564
+ * const xdr = buildPaymentXdrFromPayload(req.body);
565
+ * res.json({ xdr });
566
+ * ```
567
+ */
568
+ declare function buildPaymentXdrFromPayload(payload: BuildTxPayload): string;
537
569
 
538
570
  /**
539
571
  * Result of connecting to Freighter wallet.
@@ -640,6 +672,52 @@ declare function signWithFreighter(xdr: string, network: Network): Promise<strin
640
672
  */
641
673
  declare function submitTransaction(signedXdr: string, network: Network): Promise<TransactionSubmitResult>;
642
674
 
675
+ /**
676
+ * Payment Flow
677
+ *
678
+ * Full "pay with snap" flow matching the web app: connect Freighter,
679
+ * build payment transaction, sign, submit. Use this to implement a
680
+ * payment route (e.g. /s/[id]) with the same behavior as stellar-snaps.vercel.app.
681
+ */
682
+
683
+ interface ExecuteSnapPaymentOptions {
684
+ /** Snap from getSnap(id, { baseUrl }) */
685
+ snap: Snap$1;
686
+ /** Amount to send (use snap.amount for fixed-amount snaps) */
687
+ amount: string;
688
+ }
689
+ /**
690
+ * Fetches the current account sequence from Horizon (for building a transaction).
691
+ * Use in browser or Node; requires network access.
692
+ *
693
+ * @param publicKey - Stellar account public key
694
+ * @param network - 'public' or 'testnet'
695
+ * @returns The account's sequence number as string
696
+ */
697
+ declare function getAccountSequence(publicKey: string, network: Network): Promise<string>;
698
+ /**
699
+ * Executes the full payment flow for a snap: connect Freighter, build payment tx,
700
+ * sign with Freighter, submit to the network. Same behavior as the web app's
701
+ * "Pay with Stellar" button on /s/[id].
702
+ *
703
+ * Call this from your payment page when the user clicks Pay. Requires browser
704
+ * with Freighter installed.
705
+ *
706
+ * @param options - { snap, amount }
707
+ * @returns Transaction result (hash, successful, ledger)
708
+ *
709
+ * @example
710
+ * ```typescript
711
+ * const snap = await getSnap(id, { baseUrl: 'https://your-app.com' });
712
+ * const amount = snap.amount ?? userEnteredAmount;
713
+ * const result = await executeSnapPayment({ snap, amount });
714
+ * if (result.successful) {
715
+ * console.log('Paid! TX:', result.hash);
716
+ * }
717
+ * ```
718
+ */
719
+ declare function executeSnapPayment(options: ExecuteSnapPaymentOptions): Promise<TransactionSubmitResult>;
720
+
643
721
  /**
644
722
  * A rule for matching URL paths to API endpoints.
645
723
  */
@@ -1213,4 +1291,4 @@ declare class SnapApiError extends StellarSnapError {
1213
1291
  constructor(message: string, statusCode?: number | undefined);
1214
1292
  }
1215
1293
 
1216
- export { type ApiResponse, type BuildPaymentOptions, CACHE_HEADERS, CORS_HEADERS, type CreateDiscoveryFileOptions, type CreateSnapInput, type CreateSnapOptions, type CreateSnapResult, type DiscoveryFile, type DiscoveryRule, type DomainEntry, type DomainStatus, EXPLORER_URLS, type ExplorerType, type FreighterConnectionResult, HORIZON_URLS, InvalidAddressError, InvalidAmountError, InvalidAssetError, InvalidUriError, type MemoType, type MetaTags, NETWORK_PASSPHRASES, type Network, type OpenSnapModalOptions, POSTGRES_SCHEMA, type ParsedSnap, type PaymentSnapOptions, type PaymentSnapResult, type RateLimitBucket, type Registry, type ResolvedUrl, SHORTENER_DOMAINS, SQLITE_SCHEMA, type Snap$1 as Snap, SnapApiError, type SnapMetadata, SnapNotFoundError, type Snap as SnapRecord, SnapUnauthorizedError, StellarSnapError, type TransactionSnapOptions, type TransactionSnapResult, type TransactionSubmitResult, type UpdateSnapInput, addDomain, buildPaymentTransaction, buildUrl, closeSnapModal, connectFreighter, createAsset, createDiscoveryFile, createPaymentSnap, createRateLimiter, createRegistry, createSnap, createSnapObject, createTransactionSnap, deleteSnap, errorResponse, extractDomain, extractPath, extractSnapId, generateJsonLd, generateMetaTags, generateSnapId, getAccountUrl, getAssetUrl, getBlockedDomains, getDomainStatus, getFreighterNetwork, getOperationUrl, getSnap, getTransactionUrl, getVerifiedDomains, isDomainBlocked, isDomainVerified, isFreighterConnected, isShortenerUrl, isValidAmount, isValidAssetCode, isValidSnapId, isValidStellarAddress, listSnaps, matchUrlToRule, metaTagsToHtml, openSnapModal, parseAddress, parseQueryParams, parseSnapUri, removeDomain, resolveUrl, resolveUrls, signWithFreighter, submitTransaction, successResponse, validateDiscoveryFile, validateRegistry, validateRequired, validateSnapInput };
1294
+ export { type ApiResponse, type BuildPaymentOptions, type BuildTxPayload, CACHE_HEADERS, CORS_HEADERS, type CreateDiscoveryFileOptions, type CreateSnapInput, type CreateSnapOptions, type CreateSnapResult, type DiscoveryFile, type DiscoveryRule, type DomainEntry, type DomainStatus, EXPLORER_URLS, type ExecuteSnapPaymentOptions, type ExplorerType, type FreighterConnectionResult, HORIZON_URLS, InvalidAddressError, InvalidAmountError, InvalidAssetError, InvalidUriError, type MemoType, type MetaTags, NETWORK_PASSPHRASES, type Network, type OpenSnapModalOptions, POSTGRES_SCHEMA, type ParsedSnap, type PaymentSnapOptions, type PaymentSnapResult, type RateLimitBucket, type Registry, type ResolvedUrl, SHORTENER_DOMAINS, SQLITE_SCHEMA, type Snap$1 as Snap, SnapApiError, type SnapMetadata, SnapNotFoundError, type Snap as SnapRecord, SnapUnauthorizedError, StellarSnapError, type TransactionSnapOptions, type TransactionSnapResult, type TransactionSubmitResult, type UpdateSnapInput, addDomain, buildPaymentTransaction, buildPaymentXdrFromPayload, buildUrl, closeSnapModal, connectFreighter, createAsset, createDiscoveryFile, createPaymentSnap, createRateLimiter, createRegistry, createSnap, createSnapObject, createTransactionSnap, deleteSnap, errorResponse, executeSnapPayment, extractDomain, extractPath, extractSnapId, generateJsonLd, generateMetaTags, generateSnapId, getAccountSequence, getAccountUrl, getAssetUrl, getBlockedDomains, getDomainStatus, getFreighterNetwork, getOperationUrl, getSnap, getTransactionUrl, getVerifiedDomains, isDomainBlocked, isDomainVerified, isFreighterConnected, isShortenerUrl, isValidAmount, isValidAssetCode, isValidSnapId, isValidStellarAddress, listSnaps, matchUrlToRule, metaTagsToHtml, openSnapModal, parseAddress, parseQueryParams, parseSnapUri, removeDomain, resolveUrl, resolveUrls, signWithFreighter, submitTransaction, successResponse, validateDiscoveryFile, validateRegistry, validateRequired, validateSnapInput };
package/dist/index.d.ts CHANGED
@@ -534,6 +534,38 @@ declare function createAsset(code: string, issuer?: string): StellarSdk.Asset;
534
534
  * ```
535
535
  */
536
536
  declare function buildPaymentTransaction(options: BuildPaymentOptions): string;
537
+ /**
538
+ * Payload shape sent by the browser extension to POST /api/build-tx.
539
+ * Use this to implement the build-tx endpoint so the extension can build
540
+ * transactions when users pay from your domain.
541
+ */
542
+ interface BuildTxPayload {
543
+ source: string;
544
+ sequence: string;
545
+ destination: string;
546
+ amount: string;
547
+ assetCode?: string;
548
+ assetIssuer?: string;
549
+ memo?: string;
550
+ memoType?: string;
551
+ network?: Network;
552
+ }
553
+ /**
554
+ * Builds payment transaction XDR from the same payload the browser extension
555
+ * sends to POST /api/build-tx. Use in your server handler so the extension
556
+ * can build transactions when users click "Pay with Stellar" on your snap links.
557
+ *
558
+ * @param payload - Request body: source, sequence, destination, amount, assetCode?, assetIssuer?, memo?, memoType?, network?
559
+ * @returns Transaction XDR string
560
+ *
561
+ * @example
562
+ * ```typescript
563
+ * // In your POST /api/build-tx handler:
564
+ * const xdr = buildPaymentXdrFromPayload(req.body);
565
+ * res.json({ xdr });
566
+ * ```
567
+ */
568
+ declare function buildPaymentXdrFromPayload(payload: BuildTxPayload): string;
537
569
 
538
570
  /**
539
571
  * Result of connecting to Freighter wallet.
@@ -640,6 +672,52 @@ declare function signWithFreighter(xdr: string, network: Network): Promise<strin
640
672
  */
641
673
  declare function submitTransaction(signedXdr: string, network: Network): Promise<TransactionSubmitResult>;
642
674
 
675
+ /**
676
+ * Payment Flow
677
+ *
678
+ * Full "pay with snap" flow matching the web app: connect Freighter,
679
+ * build payment transaction, sign, submit. Use this to implement a
680
+ * payment route (e.g. /s/[id]) with the same behavior as stellar-snaps.vercel.app.
681
+ */
682
+
683
+ interface ExecuteSnapPaymentOptions {
684
+ /** Snap from getSnap(id, { baseUrl }) */
685
+ snap: Snap$1;
686
+ /** Amount to send (use snap.amount for fixed-amount snaps) */
687
+ amount: string;
688
+ }
689
+ /**
690
+ * Fetches the current account sequence from Horizon (for building a transaction).
691
+ * Use in browser or Node; requires network access.
692
+ *
693
+ * @param publicKey - Stellar account public key
694
+ * @param network - 'public' or 'testnet'
695
+ * @returns The account's sequence number as string
696
+ */
697
+ declare function getAccountSequence(publicKey: string, network: Network): Promise<string>;
698
+ /**
699
+ * Executes the full payment flow for a snap: connect Freighter, build payment tx,
700
+ * sign with Freighter, submit to the network. Same behavior as the web app's
701
+ * "Pay with Stellar" button on /s/[id].
702
+ *
703
+ * Call this from your payment page when the user clicks Pay. Requires browser
704
+ * with Freighter installed.
705
+ *
706
+ * @param options - { snap, amount }
707
+ * @returns Transaction result (hash, successful, ledger)
708
+ *
709
+ * @example
710
+ * ```typescript
711
+ * const snap = await getSnap(id, { baseUrl: 'https://your-app.com' });
712
+ * const amount = snap.amount ?? userEnteredAmount;
713
+ * const result = await executeSnapPayment({ snap, amount });
714
+ * if (result.successful) {
715
+ * console.log('Paid! TX:', result.hash);
716
+ * }
717
+ * ```
718
+ */
719
+ declare function executeSnapPayment(options: ExecuteSnapPaymentOptions): Promise<TransactionSubmitResult>;
720
+
643
721
  /**
644
722
  * A rule for matching URL paths to API endpoints.
645
723
  */
@@ -1213,4 +1291,4 @@ declare class SnapApiError extends StellarSnapError {
1213
1291
  constructor(message: string, statusCode?: number | undefined);
1214
1292
  }
1215
1293
 
1216
- export { type ApiResponse, type BuildPaymentOptions, CACHE_HEADERS, CORS_HEADERS, type CreateDiscoveryFileOptions, type CreateSnapInput, type CreateSnapOptions, type CreateSnapResult, type DiscoveryFile, type DiscoveryRule, type DomainEntry, type DomainStatus, EXPLORER_URLS, type ExplorerType, type FreighterConnectionResult, HORIZON_URLS, InvalidAddressError, InvalidAmountError, InvalidAssetError, InvalidUriError, type MemoType, type MetaTags, NETWORK_PASSPHRASES, type Network, type OpenSnapModalOptions, POSTGRES_SCHEMA, type ParsedSnap, type PaymentSnapOptions, type PaymentSnapResult, type RateLimitBucket, type Registry, type ResolvedUrl, SHORTENER_DOMAINS, SQLITE_SCHEMA, type Snap$1 as Snap, SnapApiError, type SnapMetadata, SnapNotFoundError, type Snap as SnapRecord, SnapUnauthorizedError, StellarSnapError, type TransactionSnapOptions, type TransactionSnapResult, type TransactionSubmitResult, type UpdateSnapInput, addDomain, buildPaymentTransaction, buildUrl, closeSnapModal, connectFreighter, createAsset, createDiscoveryFile, createPaymentSnap, createRateLimiter, createRegistry, createSnap, createSnapObject, createTransactionSnap, deleteSnap, errorResponse, extractDomain, extractPath, extractSnapId, generateJsonLd, generateMetaTags, generateSnapId, getAccountUrl, getAssetUrl, getBlockedDomains, getDomainStatus, getFreighterNetwork, getOperationUrl, getSnap, getTransactionUrl, getVerifiedDomains, isDomainBlocked, isDomainVerified, isFreighterConnected, isShortenerUrl, isValidAmount, isValidAssetCode, isValidSnapId, isValidStellarAddress, listSnaps, matchUrlToRule, metaTagsToHtml, openSnapModal, parseAddress, parseQueryParams, parseSnapUri, removeDomain, resolveUrl, resolveUrls, signWithFreighter, submitTransaction, successResponse, validateDiscoveryFile, validateRegistry, validateRequired, validateSnapInput };
1294
+ export { type ApiResponse, type BuildPaymentOptions, type BuildTxPayload, CACHE_HEADERS, CORS_HEADERS, type CreateDiscoveryFileOptions, type CreateSnapInput, type CreateSnapOptions, type CreateSnapResult, type DiscoveryFile, type DiscoveryRule, type DomainEntry, type DomainStatus, EXPLORER_URLS, type ExecuteSnapPaymentOptions, type ExplorerType, type FreighterConnectionResult, HORIZON_URLS, InvalidAddressError, InvalidAmountError, InvalidAssetError, InvalidUriError, type MemoType, type MetaTags, NETWORK_PASSPHRASES, type Network, type OpenSnapModalOptions, POSTGRES_SCHEMA, type ParsedSnap, type PaymentSnapOptions, type PaymentSnapResult, type RateLimitBucket, type Registry, type ResolvedUrl, SHORTENER_DOMAINS, SQLITE_SCHEMA, type Snap$1 as Snap, SnapApiError, type SnapMetadata, SnapNotFoundError, type Snap as SnapRecord, SnapUnauthorizedError, StellarSnapError, type TransactionSnapOptions, type TransactionSnapResult, type TransactionSubmitResult, type UpdateSnapInput, addDomain, buildPaymentTransaction, buildPaymentXdrFromPayload, buildUrl, closeSnapModal, connectFreighter, createAsset, createDiscoveryFile, createPaymentSnap, createRateLimiter, createRegistry, createSnap, createSnapObject, createTransactionSnap, deleteSnap, errorResponse, executeSnapPayment, extractDomain, extractPath, extractSnapId, generateJsonLd, generateMetaTags, generateSnapId, getAccountSequence, getAccountUrl, getAssetUrl, getBlockedDomains, getDomainStatus, getFreighterNetwork, getOperationUrl, getSnap, getTransactionUrl, getVerifiedDomains, isDomainBlocked, isDomainVerified, isFreighterConnected, isShortenerUrl, isValidAmount, isValidAssetCode, isValidSnapId, isValidStellarAddress, listSnaps, matchUrlToRule, metaTagsToHtml, openSnapModal, parseAddress, parseQueryParams, parseSnapUri, removeDomain, resolveUrl, resolveUrls, signWithFreighter, submitTransaction, successResponse, validateDiscoveryFile, validateRegistry, validateRequired, validateSnapInput };
package/dist/index.js CHANGED
@@ -613,6 +613,21 @@ function buildPaymentTransaction(options) {
613
613
  const transaction = builder.build();
614
614
  return transaction.toXDR();
615
615
  }
616
+ function buildPaymentXdrFromPayload(payload) {
617
+ const network = payload.network === "public" ? "public" : "testnet";
618
+ return buildPaymentTransaction({
619
+ source: payload.source,
620
+ sequence: payload.sequence,
621
+ destination: payload.destination,
622
+ amount: payload.amount,
623
+ asset: payload.assetCode && payload.assetCode !== "XLM" && payload.assetIssuer ? { code: payload.assetCode, issuer: payload.assetIssuer } : void 0,
624
+ memo: payload.memo != null ? {
625
+ type: payload.memoType ?? "MEMO_TEXT",
626
+ value: payload.memo
627
+ } : void 0,
628
+ network
629
+ });
630
+ }
616
631
  async function isFreighterConnected() {
617
632
  try {
618
633
  const connected = await freighterApi.isConnected();
@@ -729,6 +744,47 @@ async function submitTransaction(signedXdr, network) {
729
744
  }
730
745
  }
731
746
 
747
+ // src/payment-flow.ts
748
+ async function getAccountSequence(publicKey, network) {
749
+ const horizonUrl = HORIZON_URLS[network];
750
+ const response = await fetch(`${horizonUrl}/accounts/${publicKey}`);
751
+ if (!response.ok) {
752
+ if (response.status === 404) {
753
+ throw new Error("Account not found. Fund the account first.");
754
+ }
755
+ throw new Error(`Failed to load account: ${response.status}`);
756
+ }
757
+ const data = await response.json();
758
+ return String(data.sequence);
759
+ }
760
+ async function executeSnapPayment(options) {
761
+ const { snap, amount } = options;
762
+ if (!amount || Number(amount) <= 0) {
763
+ throw new Error("Please enter a valid amount");
764
+ }
765
+ const network = snap.network === "public" ? "public" : "testnet";
766
+ const { publicKey } = await connectFreighter();
767
+ const currentNetwork = await getFreighterNetwork();
768
+ if (currentNetwork !== network) {
769
+ throw new Error(`Please switch Freighter to ${network}. Currently on ${currentNetwork}.`);
770
+ }
771
+ const sequence = await getAccountSequence(publicKey, network);
772
+ const xdr = buildPaymentTransaction({
773
+ source: publicKey,
774
+ sequence,
775
+ destination: snap.destination,
776
+ amount,
777
+ asset: snap.assetCode && snap.assetCode !== "XLM" && snap.assetIssuer ? { code: snap.assetCode, issuer: snap.assetIssuer } : void 0,
778
+ memo: snap.memo ? {
779
+ type: snap.memoType ?? "MEMO_TEXT",
780
+ value: snap.memo
781
+ } : void 0,
782
+ network
783
+ });
784
+ const signedXdr = await signWithFreighter(xdr, network);
785
+ return submitTransaction(signedXdr, network);
786
+ }
787
+
732
788
  // src/discovery.ts
733
789
  function createDiscoveryFile(options) {
734
790
  const { name, description, icon, rules } = options;
@@ -1272,6 +1328,7 @@ exports.SnapUnauthorizedError = SnapUnauthorizedError;
1272
1328
  exports.StellarSnapError = StellarSnapError;
1273
1329
  exports.addDomain = addDomain;
1274
1330
  exports.buildPaymentTransaction = buildPaymentTransaction;
1331
+ exports.buildPaymentXdrFromPayload = buildPaymentXdrFromPayload;
1275
1332
  exports.buildUrl = buildUrl;
1276
1333
  exports.closeSnapModal = closeSnapModal;
1277
1334
  exports.connectFreighter = connectFreighter;
@@ -1285,12 +1342,14 @@ exports.createSnapObject = createSnapObject;
1285
1342
  exports.createTransactionSnap = createTransactionSnap;
1286
1343
  exports.deleteSnap = deleteSnap;
1287
1344
  exports.errorResponse = errorResponse;
1345
+ exports.executeSnapPayment = executeSnapPayment;
1288
1346
  exports.extractDomain = extractDomain;
1289
1347
  exports.extractPath = extractPath;
1290
1348
  exports.extractSnapId = extractSnapId;
1291
1349
  exports.generateJsonLd = generateJsonLd;
1292
1350
  exports.generateMetaTags = generateMetaTags;
1293
1351
  exports.generateSnapId = generateSnapId;
1352
+ exports.getAccountSequence = getAccountSequence;
1294
1353
  exports.getAccountUrl = getAccountUrl;
1295
1354
  exports.getAssetUrl = getAssetUrl;
1296
1355
  exports.getBlockedDomains = getBlockedDomains;