uvd-x402-sdk 2.11.1 → 2.13.0
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/dist/adapters/index.d.mts +1 -1
- package/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/index.mjs.map +1 -1
- package/dist/backend/index.d.mts +1 -1
- package/dist/backend/index.d.ts +1 -1
- package/dist/backend/index.js.map +1 -1
- package/dist/backend/index.mjs.map +1 -1
- package/dist/{index-C60c_e5z.d.mts → index-C6Vxnneo.d.mts} +1 -1
- package/dist/{index-VIOUicmO.d.ts → index-DmJGKD9r.d.ts} +1 -1
- package/dist/{index-D-dO_FoP.d.mts → index-fIhvHqCQ.d.mts} +18 -22
- package/dist/{index-D-dO_FoP.d.ts → index-fIhvHqCQ.d.ts} +18 -22
- package/dist/index.d.mts +56 -2
- package/dist/index.d.ts +56 -2
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +58 -1
- package/dist/index.mjs.map +1 -1
- package/dist/providers/algorand/index.d.mts +11 -5
- package/dist/providers/algorand/index.d.ts +11 -5
- package/dist/providers/algorand/index.js +142 -27
- package/dist/providers/algorand/index.js.map +1 -1
- package/dist/providers/algorand/index.mjs +142 -27
- package/dist/providers/algorand/index.mjs.map +1 -1
- package/dist/providers/evm/index.d.mts +1 -1
- package/dist/providers/evm/index.d.ts +1 -1
- package/dist/providers/evm/index.js.map +1 -1
- package/dist/providers/evm/index.mjs.map +1 -1
- package/dist/providers/near/index.d.mts +1 -1
- package/dist/providers/near/index.d.ts +1 -1
- package/dist/providers/near/index.js.map +1 -1
- package/dist/providers/near/index.mjs.map +1 -1
- package/dist/providers/solana/index.d.mts +1 -1
- package/dist/providers/solana/index.d.ts +1 -1
- package/dist/providers/solana/index.js.map +1 -1
- package/dist/providers/solana/index.mjs.map +1 -1
- package/dist/providers/stellar/index.d.mts +1 -1
- package/dist/providers/stellar/index.d.ts +1 -1
- package/dist/providers/stellar/index.js.map +1 -1
- package/dist/providers/stellar/index.mjs.map +1 -1
- package/dist/react/index.d.mts +3 -3
- package/dist/react/index.d.ts +3 -3
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs.map +1 -1
- package/dist/utils/index.d.mts +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/facilitator.ts +106 -0
- package/src/index.ts +4 -0
- package/src/providers/algorand/index.ts +122 -32
- package/src/types/index.ts +18 -22
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as WalletAdapter, C as ChainConfig, P as PaymentInfo, l as X402Version } from '../../index-
|
|
1
|
+
import { c as WalletAdapter, C as ChainConfig, P as PaymentInfo, l as X402Version } from '../../index-fIhvHqCQ.mjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* uvd-x402-sdk - Algorand Provider
|
|
@@ -82,13 +82,19 @@ declare class AlgorandProvider implements WalletAdapter {
|
|
|
82
82
|
*/
|
|
83
83
|
getBalance(chainConfig: ChainConfig): Promise<string>;
|
|
84
84
|
/**
|
|
85
|
-
* Create Algorand
|
|
85
|
+
* Create Algorand atomic group payment (GoPlausible x402-avm spec)
|
|
86
86
|
*
|
|
87
|
-
* Transaction structure:
|
|
88
|
-
*
|
|
89
|
-
*
|
|
87
|
+
* Transaction structure (atomic group):
|
|
88
|
+
* - Transaction 0: Fee payment (UNSIGNED) - facilitator -> facilitator, covers all fees
|
|
89
|
+
* - Transaction 1: ASA transfer (SIGNED) - client -> merchant
|
|
90
|
+
*
|
|
91
|
+
* The facilitator signs transaction 0 and submits the complete atomic group.
|
|
90
92
|
*/
|
|
91
93
|
signPayment(paymentInfo: PaymentInfo, chainConfig: ChainConfig): Promise<string>;
|
|
94
|
+
/**
|
|
95
|
+
* Decode signed transaction from wallet response (handles various formats)
|
|
96
|
+
*/
|
|
97
|
+
private decodeSignedTxn;
|
|
92
98
|
/**
|
|
93
99
|
* Encode Algorand payment as X-PAYMENT header
|
|
94
100
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as WalletAdapter, C as ChainConfig, P as PaymentInfo, l as X402Version } from '../../index-
|
|
1
|
+
import { c as WalletAdapter, C as ChainConfig, P as PaymentInfo, l as X402Version } from '../../index-fIhvHqCQ.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* uvd-x402-sdk - Algorand Provider
|
|
@@ -82,13 +82,19 @@ declare class AlgorandProvider implements WalletAdapter {
|
|
|
82
82
|
*/
|
|
83
83
|
getBalance(chainConfig: ChainConfig): Promise<string>;
|
|
84
84
|
/**
|
|
85
|
-
* Create Algorand
|
|
85
|
+
* Create Algorand atomic group payment (GoPlausible x402-avm spec)
|
|
86
86
|
*
|
|
87
|
-
* Transaction structure:
|
|
88
|
-
*
|
|
89
|
-
*
|
|
87
|
+
* Transaction structure (atomic group):
|
|
88
|
+
* - Transaction 0: Fee payment (UNSIGNED) - facilitator -> facilitator, covers all fees
|
|
89
|
+
* - Transaction 1: ASA transfer (SIGNED) - client -> merchant
|
|
90
|
+
*
|
|
91
|
+
* The facilitator signs transaction 0 and submits the complete atomic group.
|
|
90
92
|
*/
|
|
91
93
|
signPayment(paymentInfo: PaymentInfo, chainConfig: ChainConfig): Promise<string>;
|
|
94
|
+
/**
|
|
95
|
+
* Decode signed transaction from wallet response (handles various formats)
|
|
96
|
+
*/
|
|
97
|
+
private decodeSignedTxn;
|
|
92
98
|
/**
|
|
93
99
|
* Encode Algorand payment as X-PAYMENT header
|
|
94
100
|
*
|
|
@@ -678,6 +678,50 @@ function chainToCAIP2(chainName) {
|
|
|
678
678
|
return chainName;
|
|
679
679
|
}
|
|
680
680
|
|
|
681
|
+
// src/facilitator.ts
|
|
682
|
+
var FACILITATOR_ADDRESSES = {
|
|
683
|
+
/**
|
|
684
|
+
* Solana facilitator address (fee payer)
|
|
685
|
+
* Used for: Paying transaction fees on Solana
|
|
686
|
+
*/
|
|
687
|
+
solana: "F742C4VfFLQ9zRQyithoj5229ZgtX2WqKCSFKgH2EThq",
|
|
688
|
+
/**
|
|
689
|
+
* Algorand facilitator address (fee payer)
|
|
690
|
+
* Used for: Signing Transaction 0 (fee tx) in atomic groups
|
|
691
|
+
* Note: This is derived from the facilitator's Algorand mnemonic
|
|
692
|
+
*/
|
|
693
|
+
algorand: "SXHRBXS22SKKXHXK44DTQMWN2SXK3SFJWBDAQZGF4DRPW7PNFAUM2GYFAQ",
|
|
694
|
+
/**
|
|
695
|
+
* Algorand testnet facilitator address
|
|
696
|
+
*/
|
|
697
|
+
"algorand-testnet": "SXHRBXS22SKKXHXK44DTQMWN2SXK3SFJWBDAQZGF4DRPW7PNFAUM2GYFAQ",
|
|
698
|
+
/**
|
|
699
|
+
* EVM facilitator address
|
|
700
|
+
* Used for: Submitting EIP-3009 transferWithAuthorization transactions
|
|
701
|
+
* Note: Same address across all EVM chains
|
|
702
|
+
*/
|
|
703
|
+
evm: "0x7c5F3AdB0C7775968Bc7e7cF61b27fECf2e2b500",
|
|
704
|
+
/**
|
|
705
|
+
* Stellar facilitator address
|
|
706
|
+
* Used for: Signing soroban authorization entries
|
|
707
|
+
*/
|
|
708
|
+
stellar: "GDUTDNV53WQPOB2JUZPO6SXH4LVT7CJSLCMLFQ7W4CNAXGIX7XYMCNP2",
|
|
709
|
+
/**
|
|
710
|
+
* NEAR facilitator address
|
|
711
|
+
* Used for: Relaying meta-transactions
|
|
712
|
+
*/
|
|
713
|
+
near: "uvd-facilitator.near"
|
|
714
|
+
};
|
|
715
|
+
function getFacilitatorAddress(chainName, networkType) {
|
|
716
|
+
const exactMatch = FACILITATOR_ADDRESSES[chainName];
|
|
717
|
+
if (exactMatch) {
|
|
718
|
+
return exactMatch;
|
|
719
|
+
}
|
|
720
|
+
{
|
|
721
|
+
return FACILITATOR_ADDRESSES.algorand;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
|
|
681
725
|
// src/providers/algorand/index.ts
|
|
682
726
|
function uint8ArrayToBase64(bytes) {
|
|
683
727
|
let binary = "";
|
|
@@ -881,11 +925,13 @@ var AlgorandProvider = class {
|
|
|
881
925
|
}
|
|
882
926
|
}
|
|
883
927
|
/**
|
|
884
|
-
* Create Algorand
|
|
928
|
+
* Create Algorand atomic group payment (GoPlausible x402-avm spec)
|
|
929
|
+
*
|
|
930
|
+
* Transaction structure (atomic group):
|
|
931
|
+
* - Transaction 0: Fee payment (UNSIGNED) - facilitator -> facilitator, covers all fees
|
|
932
|
+
* - Transaction 1: ASA transfer (SIGNED) - client -> merchant
|
|
885
933
|
*
|
|
886
|
-
*
|
|
887
|
-
* 1. ASA Transfer from user to recipient
|
|
888
|
-
* 2. Facilitator pays transaction fees
|
|
934
|
+
* The facilitator signs transaction 0 and submits the complete atomic group.
|
|
889
935
|
*/
|
|
890
936
|
async signPayment(paymentInfo, chainConfig) {
|
|
891
937
|
await loadAlgorandDeps();
|
|
@@ -898,40 +944,86 @@ var AlgorandProvider = class {
|
|
|
898
944
|
const algodClient = await this.getAlgodClient(chainConfig);
|
|
899
945
|
const recipient = paymentInfo.recipients?.algorand || paymentInfo.recipient;
|
|
900
946
|
const assetId = parseInt(chainConfig.usdc.address, 10);
|
|
947
|
+
const chainName = chainConfig?.name || "algorand";
|
|
948
|
+
const facilitatorAddress = paymentInfo.facilitator || getFacilitatorAddress(chainName);
|
|
949
|
+
if (!facilitatorAddress) {
|
|
950
|
+
throw new X402Error(
|
|
951
|
+
"Facilitator address not configured for Algorand",
|
|
952
|
+
"PAYMENT_FAILED"
|
|
953
|
+
);
|
|
954
|
+
}
|
|
901
955
|
const amount = Math.floor(parseFloat(paymentInfo.amount) * 1e6);
|
|
902
956
|
try {
|
|
903
957
|
const suggestedParams = await algodClient.getTransactionParams().do();
|
|
904
|
-
const
|
|
958
|
+
const feeTxn = algosdk.makePaymentTxnWithSuggestedParamsFromObject({
|
|
959
|
+
sender: facilitatorAddress,
|
|
960
|
+
receiver: facilitatorAddress,
|
|
961
|
+
// self-transfer
|
|
962
|
+
amount: 0,
|
|
963
|
+
suggestedParams: {
|
|
964
|
+
...suggestedParams,
|
|
965
|
+
fee: 2e3,
|
|
966
|
+
// Covers both transactions (1000 each)
|
|
967
|
+
flatFee: true
|
|
968
|
+
}
|
|
969
|
+
});
|
|
970
|
+
const paymentTxn = algosdk.makeAssetTransferTxnWithSuggestedParamsFromObject({
|
|
905
971
|
sender: this.address,
|
|
906
972
|
receiver: recipient,
|
|
907
973
|
amount: BigInt(amount),
|
|
908
974
|
assetIndex: assetId,
|
|
909
|
-
suggestedParams
|
|
975
|
+
suggestedParams: {
|
|
976
|
+
...suggestedParams,
|
|
977
|
+
fee: 0,
|
|
978
|
+
// Fee paid by transaction 0
|
|
979
|
+
flatFee: true
|
|
980
|
+
},
|
|
910
981
|
note: new TextEncoder().encode("x402 payment via uvd-x402-sdk")
|
|
911
982
|
});
|
|
912
|
-
|
|
983
|
+
const txnGroup = algosdk.assignGroupID([feeTxn, paymentTxn]);
|
|
984
|
+
const unsignedFeeTxnBytes = algosdk.encodeUnsignedTransaction(txnGroup[0]);
|
|
985
|
+
const unsignedFeeTxnBase64 = uint8ArrayToBase64(unsignedFeeTxnBytes);
|
|
986
|
+
let signedPaymentTxnBytes;
|
|
913
987
|
if (this.walletType === "lute" && this.luteWallet) {
|
|
914
|
-
const
|
|
915
|
-
const
|
|
916
|
-
|
|
988
|
+
const feeTxnBase64 = uint8ArrayToBase64(txnGroup[0].toByte());
|
|
989
|
+
const paymentTxnBase64 = uint8ArrayToBase64(txnGroup[1].toByte());
|
|
990
|
+
const signedTxns = await this.luteWallet.signTxns([
|
|
991
|
+
{ txn: feeTxnBase64, signers: [] },
|
|
992
|
+
// Don't sign - facilitator will
|
|
993
|
+
{ txn: paymentTxnBase64 }
|
|
994
|
+
// Sign this one
|
|
995
|
+
]);
|
|
996
|
+
if (!signedTxns || signedTxns.length < 2 || !signedTxns[1]) {
|
|
917
997
|
throw new X402Error("No signed transaction returned", "SIGNATURE_REJECTED");
|
|
918
998
|
}
|
|
919
|
-
|
|
999
|
+
const signedResult = signedTxns[1];
|
|
1000
|
+
signedPaymentTxnBytes = this.decodeSignedTxn(signedResult);
|
|
920
1001
|
} else if (this.walletType === "pera" && this.peraWallet) {
|
|
921
|
-
const signedTxns = await this.peraWallet.signTransaction([
|
|
922
|
-
|
|
1002
|
+
const signedTxns = await this.peraWallet.signTransaction([
|
|
1003
|
+
[
|
|
1004
|
+
{ txn: txnGroup[0], signers: [] },
|
|
1005
|
+
// Don't sign - facilitator will
|
|
1006
|
+
{ txn: txnGroup[1] }
|
|
1007
|
+
// Sign this one
|
|
1008
|
+
]
|
|
1009
|
+
]);
|
|
1010
|
+
if (!signedTxns || signedTxns.length < 2 || !signedTxns[1]) {
|
|
923
1011
|
throw new X402Error("No signed transaction returned", "SIGNATURE_REJECTED");
|
|
924
1012
|
}
|
|
925
|
-
|
|
1013
|
+
signedPaymentTxnBytes = signedTxns[1];
|
|
926
1014
|
} else {
|
|
927
1015
|
throw new X402Error("No wallet available for signing", "WALLET_NOT_CONNECTED");
|
|
928
1016
|
}
|
|
1017
|
+
const signedPaymentTxnBase64 = uint8ArrayToBase64(signedPaymentTxnBytes);
|
|
929
1018
|
const payload = {
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
1019
|
+
paymentIndex: 1,
|
|
1020
|
+
// Index of the payment transaction in the group
|
|
1021
|
+
paymentGroup: [
|
|
1022
|
+
unsignedFeeTxnBase64,
|
|
1023
|
+
// Transaction 0: unsigned fee tx
|
|
1024
|
+
signedPaymentTxnBase64
|
|
1025
|
+
// Transaction 1: signed payment tx
|
|
1026
|
+
]
|
|
935
1027
|
};
|
|
936
1028
|
return JSON.stringify(payload);
|
|
937
1029
|
} catch (error) {
|
|
@@ -950,6 +1042,29 @@ var AlgorandProvider = class {
|
|
|
950
1042
|
);
|
|
951
1043
|
}
|
|
952
1044
|
}
|
|
1045
|
+
/**
|
|
1046
|
+
* Decode signed transaction from wallet response (handles various formats)
|
|
1047
|
+
*/
|
|
1048
|
+
decodeSignedTxn(signedResult) {
|
|
1049
|
+
if (signedResult instanceof Uint8Array) {
|
|
1050
|
+
return signedResult;
|
|
1051
|
+
} else if (typeof signedResult === "string") {
|
|
1052
|
+
try {
|
|
1053
|
+
return Uint8Array.from(atob(signedResult), (c) => c.charCodeAt(0));
|
|
1054
|
+
} catch {
|
|
1055
|
+
const standardBase64 = signedResult.replace(/-/g, "+").replace(/_/g, "/");
|
|
1056
|
+
return Uint8Array.from(atob(standardBase64), (c) => c.charCodeAt(0));
|
|
1057
|
+
}
|
|
1058
|
+
} else if (ArrayBuffer.isView(signedResult)) {
|
|
1059
|
+
return new Uint8Array(
|
|
1060
|
+
signedResult.buffer,
|
|
1061
|
+
signedResult.byteOffset,
|
|
1062
|
+
signedResult.byteLength
|
|
1063
|
+
);
|
|
1064
|
+
} else {
|
|
1065
|
+
throw new X402Error("Unexpected signed transaction format", "PAYMENT_FAILED");
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
953
1068
|
/**
|
|
954
1069
|
* Encode Algorand payment as X-PAYMENT header
|
|
955
1070
|
*
|
|
@@ -960,14 +1075,15 @@ var AlgorandProvider = class {
|
|
|
960
1075
|
*/
|
|
961
1076
|
encodePaymentHeader(paymentPayload, chainConfig, version = 1) {
|
|
962
1077
|
const payload = JSON.parse(paymentPayload);
|
|
963
|
-
|
|
1078
|
+
let networkName;
|
|
1079
|
+
if (chainConfig?.name === "algorand-testnet") {
|
|
1080
|
+
networkName = "algorand-testnet";
|
|
1081
|
+
} else {
|
|
1082
|
+
networkName = "algorand-mainnet";
|
|
1083
|
+
}
|
|
964
1084
|
const payloadData = {
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
amount: payload.amount,
|
|
968
|
-
assetId: payload.assetId,
|
|
969
|
-
signedTxn: payload.signedTxn,
|
|
970
|
-
...payload.note && { note: payload.note }
|
|
1085
|
+
paymentIndex: payload.paymentIndex,
|
|
1086
|
+
paymentGroup: payload.paymentGroup
|
|
971
1087
|
};
|
|
972
1088
|
const x402Payload = version === 2 ? {
|
|
973
1089
|
x402Version: 2,
|
|
@@ -979,7 +1095,6 @@ var AlgorandProvider = class {
|
|
|
979
1095
|
x402Version: 1,
|
|
980
1096
|
scheme: "exact",
|
|
981
1097
|
network: networkName,
|
|
982
|
-
// Plain chain name for v1
|
|
983
1098
|
payload: payloadData
|
|
984
1099
|
};
|
|
985
1100
|
return btoa(JSON.stringify(x402Payload));
|