uvd-x402-sdk 2.10.0 → 2.11.1

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.
Files changed (45) hide show
  1. package/dist/adapters/index.js +16 -0
  2. package/dist/adapters/index.js.map +1 -1
  3. package/dist/adapters/index.mjs +16 -0
  4. package/dist/adapters/index.mjs.map +1 -1
  5. package/dist/backend/index.js +16 -0
  6. package/dist/backend/index.js.map +1 -1
  7. package/dist/backend/index.mjs +16 -0
  8. package/dist/backend/index.mjs.map +1 -1
  9. package/dist/index.js +16 -0
  10. package/dist/index.js.map +1 -1
  11. package/dist/index.mjs +16 -0
  12. package/dist/index.mjs.map +1 -1
  13. package/dist/providers/algorand/index.d.mts +31 -10
  14. package/dist/providers/algorand/index.d.ts +31 -10
  15. package/dist/providers/algorand/index.js +125 -13
  16. package/dist/providers/algorand/index.js.map +1 -1
  17. package/dist/providers/algorand/index.mjs +125 -13
  18. package/dist/providers/algorand/index.mjs.map +1 -1
  19. package/dist/providers/evm/index.js +16 -0
  20. package/dist/providers/evm/index.js.map +1 -1
  21. package/dist/providers/evm/index.mjs +16 -0
  22. package/dist/providers/evm/index.mjs.map +1 -1
  23. package/dist/providers/near/index.js +16 -0
  24. package/dist/providers/near/index.js.map +1 -1
  25. package/dist/providers/near/index.mjs +16 -0
  26. package/dist/providers/near/index.mjs.map +1 -1
  27. package/dist/providers/solana/index.js +16 -0
  28. package/dist/providers/solana/index.js.map +1 -1
  29. package/dist/providers/solana/index.mjs +16 -0
  30. package/dist/providers/solana/index.mjs.map +1 -1
  31. package/dist/providers/stellar/index.js +16 -0
  32. package/dist/providers/stellar/index.js.map +1 -1
  33. package/dist/providers/stellar/index.mjs +16 -0
  34. package/dist/providers/stellar/index.mjs.map +1 -1
  35. package/dist/react/index.js +16 -0
  36. package/dist/react/index.js.map +1 -1
  37. package/dist/react/index.mjs +16 -0
  38. package/dist/react/index.mjs.map +1 -1
  39. package/dist/utils/index.js +16 -0
  40. package/dist/utils/index.js.map +1 -1
  41. package/dist/utils/index.mjs +16 -0
  42. package/dist/utils/index.mjs.map +1 -1
  43. package/package.json +6 -1
  44. package/src/chains/index.ts +14 -0
  45. package/src/providers/algorand/index.ts +155 -19
@@ -3,9 +3,14 @@ import { c as WalletAdapter, C as ChainConfig, P as PaymentInfo, l as X402Versio
3
3
  /**
4
4
  * uvd-x402-sdk - Algorand Provider
5
5
  *
6
- * Provides wallet connection and payment creation for Algorand via Pera Wallet.
6
+ * Provides wallet connection and payment creation for Algorand.
7
+ * Supports both Lute Wallet (desktop browser extension) and Pera Wallet (mobile).
7
8
  * Uses ASA (Algorand Standard Assets) transfers for USDC payments.
8
9
  *
10
+ * Wallet Priority:
11
+ * 1. Lute Wallet - Desktop browser extension (preferred for desktop)
12
+ * 2. Pera Wallet - Mobile via WalletConnect (fallback/mobile)
13
+ *
9
14
  * USDC ASA IDs:
10
15
  * - Mainnet: 31566704
11
16
  * - Testnet: 10458941
@@ -17,7 +22,7 @@ import { c as WalletAdapter, C as ChainConfig, P as PaymentInfo, l as X402Versio
17
22
  *
18
23
  * const algorand = new AlgorandProvider();
19
24
  *
20
- * // Connect to Pera Wallet
25
+ * // Connect to Lute (desktop) or Pera (mobile) automatically
21
26
  * const address = await algorand.connect();
22
27
  *
23
28
  * // Create Algorand payment
@@ -28,28 +33,44 @@ import { c as WalletAdapter, C as ChainConfig, P as PaymentInfo, l as X402Versio
28
33
  */
29
34
 
30
35
  /**
31
- * AlgorandProvider - Wallet adapter for Algorand via Pera Wallet
36
+ * AlgorandProvider - Wallet adapter for Algorand
32
37
  *
33
- * Supports both mainnet and testnet through chain configuration.
38
+ * Supports Lute Wallet (desktop) and Pera Wallet (mobile).
39
+ * Automatically detects and uses the best available wallet.
34
40
  */
35
41
  declare class AlgorandProvider implements WalletAdapter {
36
- readonly id = "pera";
37
- readonly name = "Pera Wallet";
42
+ readonly id = "algorand";
43
+ readonly name = "Algorand Wallet";
38
44
  readonly networkType: "algorand";
45
+ private walletType;
46
+ private luteWallet;
39
47
  private peraWallet;
40
48
  private address;
41
49
  private algodClients;
42
50
  /**
43
- * Check if Pera Wallet is available
44
- * Note: Pera works as a WalletConnect modal, so it's always "available"
51
+ * Check if any Algorand wallet is available
52
+ * Returns true if Lute extension is installed OR we can use Pera (always available via WalletConnect)
45
53
  */
46
54
  isAvailable(): boolean;
47
55
  /**
48
- * Connect to Pera Wallet
56
+ * Get the name of the currently connected wallet
57
+ */
58
+ getWalletName(): string;
59
+ /**
60
+ * Connect to Algorand wallet
61
+ * Priority: Lute (desktop extension) > Pera (mobile via WalletConnect)
49
62
  */
50
63
  connect(_chainName?: string): Promise<string>;
51
64
  /**
52
- * Disconnect from Pera Wallet
65
+ * Connect to Lute Wallet (desktop browser extension)
66
+ */
67
+ private connectLute;
68
+ /**
69
+ * Connect to Pera Wallet (mobile via WalletConnect)
70
+ */
71
+ private connectPera;
72
+ /**
73
+ * Disconnect from wallet
53
74
  */
54
75
  disconnect(): Promise<void>;
55
76
  /**
@@ -3,9 +3,14 @@ import { c as WalletAdapter, C as ChainConfig, P as PaymentInfo, l as X402Versio
3
3
  /**
4
4
  * uvd-x402-sdk - Algorand Provider
5
5
  *
6
- * Provides wallet connection and payment creation for Algorand via Pera Wallet.
6
+ * Provides wallet connection and payment creation for Algorand.
7
+ * Supports both Lute Wallet (desktop browser extension) and Pera Wallet (mobile).
7
8
  * Uses ASA (Algorand Standard Assets) transfers for USDC payments.
8
9
  *
10
+ * Wallet Priority:
11
+ * 1. Lute Wallet - Desktop browser extension (preferred for desktop)
12
+ * 2. Pera Wallet - Mobile via WalletConnect (fallback/mobile)
13
+ *
9
14
  * USDC ASA IDs:
10
15
  * - Mainnet: 31566704
11
16
  * - Testnet: 10458941
@@ -17,7 +22,7 @@ import { c as WalletAdapter, C as ChainConfig, P as PaymentInfo, l as X402Versio
17
22
  *
18
23
  * const algorand = new AlgorandProvider();
19
24
  *
20
- * // Connect to Pera Wallet
25
+ * // Connect to Lute (desktop) or Pera (mobile) automatically
21
26
  * const address = await algorand.connect();
22
27
  *
23
28
  * // Create Algorand payment
@@ -28,28 +33,44 @@ import { c as WalletAdapter, C as ChainConfig, P as PaymentInfo, l as X402Versio
28
33
  */
29
34
 
30
35
  /**
31
- * AlgorandProvider - Wallet adapter for Algorand via Pera Wallet
36
+ * AlgorandProvider - Wallet adapter for Algorand
32
37
  *
33
- * Supports both mainnet and testnet through chain configuration.
38
+ * Supports Lute Wallet (desktop) and Pera Wallet (mobile).
39
+ * Automatically detects and uses the best available wallet.
34
40
  */
35
41
  declare class AlgorandProvider implements WalletAdapter {
36
- readonly id = "pera";
37
- readonly name = "Pera Wallet";
42
+ readonly id = "algorand";
43
+ readonly name = "Algorand Wallet";
38
44
  readonly networkType: "algorand";
45
+ private walletType;
46
+ private luteWallet;
39
47
  private peraWallet;
40
48
  private address;
41
49
  private algodClients;
42
50
  /**
43
- * Check if Pera Wallet is available
44
- * Note: Pera works as a WalletConnect modal, so it's always "available"
51
+ * Check if any Algorand wallet is available
52
+ * Returns true if Lute extension is installed OR we can use Pera (always available via WalletConnect)
45
53
  */
46
54
  isAvailable(): boolean;
47
55
  /**
48
- * Connect to Pera Wallet
56
+ * Get the name of the currently connected wallet
57
+ */
58
+ getWalletName(): string;
59
+ /**
60
+ * Connect to Algorand wallet
61
+ * Priority: Lute (desktop extension) > Pera (mobile via WalletConnect)
49
62
  */
50
63
  connect(_chainName?: string): Promise<string>;
51
64
  /**
52
- * Disconnect from Pera Wallet
65
+ * Connect to Lute Wallet (desktop browser extension)
66
+ */
67
+ private connectLute;
68
+ /**
69
+ * Connect to Pera Wallet (mobile via WalletConnect)
70
+ */
71
+ private connectPera;
72
+ /**
73
+ * Disconnect from wallet
53
74
  */
54
75
  disconnect(): Promise<void>;
55
76
  /**
@@ -474,6 +474,22 @@ var SUPPORTED_CHAINS = {
474
474
  name: "USD Coin",
475
475
  version: "1"
476
476
  },
477
+ tokens: {
478
+ usdc: {
479
+ address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
480
+ // USDC SPL token mint
481
+ decimals: 6,
482
+ name: "USD Coin",
483
+ version: "1"
484
+ },
485
+ ausd: {
486
+ address: "AUSD1jCcCyPLybk1YnvPWsHQSrZ46dxwoMniN4N2UEB9",
487
+ // AUSD Token2022 mint
488
+ decimals: 6,
489
+ name: "Agora Dollar",
490
+ version: "1"
491
+ }
492
+ },
477
493
  x402: {
478
494
  facilitatorUrl: DEFAULT_FACILITATOR_URL,
479
495
  enabled: true
@@ -672,36 +688,113 @@ function uint8ArrayToBase64(bytes) {
672
688
  }
673
689
  var algosdk = null;
674
690
  var PeraWalletConnect = null;
691
+ var LuteConnect = null;
675
692
  async function loadAlgorandDeps() {
676
693
  if (!algosdk) {
677
694
  algosdk = await import('algosdk');
678
695
  }
696
+ }
697
+ async function loadPeraWallet() {
679
698
  if (!PeraWalletConnect) {
680
699
  const peraModule = await import('@perawallet/connect');
681
700
  PeraWalletConnect = peraModule.PeraWalletConnect;
682
701
  }
683
702
  }
703
+ async function loadLuteWallet() {
704
+ if (!LuteConnect) {
705
+ try {
706
+ const luteModule = await import('lute-connect');
707
+ LuteConnect = luteModule.default;
708
+ } catch {
709
+ LuteConnect = null;
710
+ }
711
+ }
712
+ }
713
+ function isLuteAvailable() {
714
+ if (typeof window === "undefined") return false;
715
+ const win = window;
716
+ return !!(win.algorand || win.lute);
717
+ }
684
718
  var AlgorandProvider = class {
685
- id = "pera";
686
- name = "Pera Wallet";
719
+ id = "algorand";
720
+ name = "Algorand Wallet";
687
721
  networkType = "algorand";
722
+ // Active wallet type
723
+ walletType = null;
724
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
725
+ luteWallet = null;
688
726
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
689
727
  peraWallet = null;
690
728
  address = null;
691
729
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
692
730
  algodClients = /* @__PURE__ */ new Map();
693
731
  /**
694
- * Check if Pera Wallet is available
695
- * Note: Pera works as a WalletConnect modal, so it's always "available"
732
+ * Check if any Algorand wallet is available
733
+ * Returns true if Lute extension is installed OR we can use Pera (always available via WalletConnect)
696
734
  */
697
735
  isAvailable() {
698
736
  return typeof window !== "undefined";
699
737
  }
700
738
  /**
701
- * Connect to Pera Wallet
739
+ * Get the name of the currently connected wallet
740
+ */
741
+ getWalletName() {
742
+ if (this.walletType === "lute") return "Lute Wallet";
743
+ if (this.walletType === "pera") return "Pera Wallet";
744
+ return "Algorand Wallet";
745
+ }
746
+ /**
747
+ * Connect to Algorand wallet
748
+ * Priority: Lute (desktop extension) > Pera (mobile via WalletConnect)
702
749
  */
703
750
  async connect(_chainName) {
704
751
  await loadAlgorandDeps();
752
+ if (isLuteAvailable()) {
753
+ try {
754
+ return await this.connectLute();
755
+ } catch (error) {
756
+ console.warn("Lute connection failed, falling back to Pera:", error);
757
+ }
758
+ }
759
+ return await this.connectPera();
760
+ }
761
+ /**
762
+ * Connect to Lute Wallet (desktop browser extension)
763
+ */
764
+ async connectLute() {
765
+ await loadLuteWallet();
766
+ if (!LuteConnect) {
767
+ throw new X402Error("Lute Wallet SDK not available", "WALLET_NOT_FOUND");
768
+ }
769
+ try {
770
+ this.luteWallet = new LuteConnect("402milly");
771
+ const genesisId = "mainnet-v1.0";
772
+ const accounts = await this.luteWallet.connect(genesisId);
773
+ if (!accounts || accounts.length === 0) {
774
+ throw new X402Error("No accounts returned from Lute Wallet", "WALLET_CONNECTION_REJECTED");
775
+ }
776
+ this.address = accounts[0];
777
+ this.walletType = "lute";
778
+ return accounts[0];
779
+ } catch (error) {
780
+ if (error instanceof X402Error) throw error;
781
+ if (error instanceof Error) {
782
+ if (error.message.includes("rejected") || error.message.includes("cancelled")) {
783
+ throw new X402Error("Connection rejected by user", "WALLET_CONNECTION_REJECTED");
784
+ }
785
+ }
786
+ throw new X402Error(
787
+ `Failed to connect Lute Wallet: ${error instanceof Error ? error.message : "Unknown error"}`,
788
+ "UNKNOWN_ERROR",
789
+ error
790
+ );
791
+ }
792
+ }
793
+ /**
794
+ * Connect to Pera Wallet (mobile via WalletConnect)
795
+ */
796
+ async connectPera() {
797
+ await loadPeraWallet();
705
798
  if (!PeraWalletConnect) {
706
799
  throw new X402Error("Failed to load Pera Wallet SDK", "WALLET_NOT_FOUND");
707
800
  }
@@ -710,6 +803,7 @@ var AlgorandProvider = class {
710
803
  const accounts = await this.peraWallet.reconnectSession();
711
804
  if (accounts.length > 0) {
712
805
  this.address = accounts[0];
806
+ this.walletType = "pera";
713
807
  return accounts[0];
714
808
  }
715
809
  const newAccounts = await this.peraWallet.connect();
@@ -717,8 +811,10 @@ var AlgorandProvider = class {
717
811
  throw new X402Error("No accounts returned from Pera Wallet", "WALLET_CONNECTION_REJECTED");
718
812
  }
719
813
  this.address = newAccounts[0];
814
+ this.walletType = "pera";
720
815
  this.peraWallet.connector?.on("disconnect", () => {
721
816
  this.address = null;
817
+ this.walletType = null;
722
818
  });
723
819
  return newAccounts[0];
724
820
  } catch (error) {
@@ -735,17 +831,21 @@ var AlgorandProvider = class {
735
831
  }
736
832
  }
737
833
  /**
738
- * Disconnect from Pera Wallet
834
+ * Disconnect from wallet
739
835
  */
740
836
  async disconnect() {
741
- if (this.peraWallet) {
837
+ if (this.walletType === "lute" && this.luteWallet) {
838
+ this.luteWallet = null;
839
+ }
840
+ if (this.walletType === "pera" && this.peraWallet) {
742
841
  try {
743
842
  await this.peraWallet.disconnect();
744
843
  } catch {
745
844
  }
845
+ this.peraWallet = null;
746
846
  }
747
- this.peraWallet = null;
748
847
  this.address = null;
848
+ this.walletType = null;
749
849
  this.algodClients.clear();
750
850
  }
751
851
  /**
@@ -789,7 +889,7 @@ var AlgorandProvider = class {
789
889
  */
790
890
  async signPayment(paymentInfo, chainConfig) {
791
891
  await loadAlgorandDeps();
792
- if (!this.peraWallet || !this.address) {
892
+ if (!this.address || !this.walletType) {
793
893
  throw new X402Error("Wallet not connected", "WALLET_NOT_CONNECTED");
794
894
  }
795
895
  if (!algosdk) {
@@ -809,11 +909,23 @@ var AlgorandProvider = class {
809
909
  suggestedParams,
810
910
  note: new TextEncoder().encode("x402 payment via uvd-x402-sdk")
811
911
  });
812
- const signedTxns = await this.peraWallet.signTransaction([[{ txn }]]);
813
- if (!signedTxns || signedTxns.length === 0) {
814
- throw new X402Error("No signed transaction returned", "SIGNATURE_REJECTED");
912
+ let signedTxn;
913
+ if (this.walletType === "lute" && this.luteWallet) {
914
+ const txnBase64 = uint8ArrayToBase64(txn.toByte());
915
+ const signedTxns = await this.luteWallet.signTxns([{ txn: txnBase64 }]);
916
+ if (!signedTxns || signedTxns.length === 0 || !signedTxns[0]) {
917
+ throw new X402Error("No signed transaction returned", "SIGNATURE_REJECTED");
918
+ }
919
+ signedTxn = Uint8Array.from(atob(signedTxns[0]), (c) => c.charCodeAt(0));
920
+ } else if (this.walletType === "pera" && this.peraWallet) {
921
+ const signedTxns = await this.peraWallet.signTransaction([[{ txn }]]);
922
+ if (!signedTxns || signedTxns.length === 0) {
923
+ throw new X402Error("No signed transaction returned", "SIGNATURE_REJECTED");
924
+ }
925
+ signedTxn = signedTxns[0];
926
+ } else {
927
+ throw new X402Error("No wallet available for signing", "WALLET_NOT_CONNECTED");
815
928
  }
816
- const signedTxn = signedTxns[0];
817
929
  const payload = {
818
930
  from: this.address,
819
931
  to: recipient,