@b3dotfun/sdk 0.1.68 → 0.1.69-alpha.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/cjs/anyspend/platform/client.d.ts +35 -0
- package/dist/cjs/anyspend/platform/client.js +158 -0
- package/dist/cjs/anyspend/platform/errors.d.ts +38 -0
- package/dist/cjs/anyspend/platform/errors.js +77 -0
- package/dist/cjs/anyspend/platform/index.d.ts +87 -0
- package/dist/cjs/anyspend/platform/index.js +85 -0
- package/dist/cjs/anyspend/platform/resources/analytics.d.ts +7 -0
- package/dist/cjs/anyspend/platform/resources/analytics.js +12 -0
- package/dist/cjs/anyspend/platform/resources/checkout-sessions.d.ts +17 -0
- package/dist/cjs/anyspend/platform/resources/checkout-sessions.js +27 -0
- package/dist/cjs/anyspend/platform/resources/customers.d.ts +19 -0
- package/dist/cjs/anyspend/platform/resources/customers.js +34 -0
- package/dist/cjs/anyspend/platform/resources/discount-codes.d.ts +29 -0
- package/dist/cjs/anyspend/platform/resources/discount-codes.js +31 -0
- package/dist/cjs/anyspend/platform/resources/events.d.ts +14 -0
- package/dist/cjs/anyspend/platform/resources/events.js +16 -0
- package/dist/cjs/anyspend/platform/resources/notifications.d.ts +18 -0
- package/dist/cjs/anyspend/platform/resources/notifications.js +27 -0
- package/dist/cjs/anyspend/platform/resources/organization.d.ts +17 -0
- package/dist/cjs/anyspend/platform/resources/organization.js +15 -0
- package/dist/cjs/anyspend/platform/resources/payment-links.d.ts +21 -0
- package/dist/cjs/anyspend/platform/resources/payment-links.js +49 -0
- package/dist/cjs/anyspend/platform/resources/products.d.ts +27 -0
- package/dist/cjs/anyspend/platform/resources/products.js +31 -0
- package/dist/cjs/anyspend/platform/resources/transactions.d.ts +11 -0
- package/dist/cjs/anyspend/platform/resources/transactions.js +25 -0
- package/dist/cjs/anyspend/platform/resources/webhooks.d.ts +14 -0
- package/dist/cjs/anyspend/platform/resources/webhooks.js +33 -0
- package/dist/cjs/anyspend/platform/resources/widgets.d.ts +38 -0
- package/dist/cjs/anyspend/platform/resources/widgets.js +31 -0
- package/dist/cjs/anyspend/platform/types.d.ts +478 -0
- package/dist/cjs/anyspend/platform/types.js +5 -0
- package/dist/cjs/anyspend/platform/utils/idempotency.d.ts +4 -0
- package/dist/cjs/anyspend/platform/utils/idempotency.js +17 -0
- package/dist/cjs/anyspend/platform/utils/pagination.d.ts +12 -0
- package/dist/cjs/anyspend/platform/utils/pagination.js +22 -0
- package/dist/cjs/anyspend/react/components/AnySpend.d.ts +5 -1
- package/dist/cjs/anyspend/react/components/AnySpend.js +127 -16
- package/dist/cjs/anyspend/react/components/AnySpendCustom.js +4 -4
- package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.js +2 -2
- package/dist/cjs/anyspend/react/components/checkout/AnySpendCheckout.d.ts +14 -6
- package/dist/cjs/anyspend/react/components/checkout/AnySpendCheckout.js +55 -8
- package/dist/cjs/anyspend/react/components/checkout/AnySpendCheckoutTrigger.d.ts +3 -1
- package/dist/cjs/anyspend/react/components/checkout/AnySpendCheckoutTrigger.js +2 -2
- package/dist/cjs/anyspend/react/components/checkout/CheckoutPaymentPanel.d.ts +5 -1
- package/dist/cjs/anyspend/react/components/checkout/CheckoutPaymentPanel.js +2 -2
- package/dist/cjs/anyspend/react/components/checkout/CryptoPayPanel.js +1 -1
- package/dist/cjs/anyspend/react/components/checkout/FiatCheckoutPanel.d.ts +5 -1
- package/dist/cjs/anyspend/react/components/checkout/FiatCheckoutPanel.js +48 -16
- package/dist/cjs/anyspend/react/components/checkout/KycGate.d.ts +11 -0
- package/dist/cjs/anyspend/react/components/checkout/KycGate.js +203 -0
- package/dist/cjs/anyspend/react/components/checkout/VariablePricingInput.d.ts +17 -0
- package/dist/cjs/anyspend/react/components/checkout/VariablePricingInput.js +145 -0
- package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +1 -1
- package/dist/cjs/anyspend/react/components/common/FeeDetailPanel.js +1 -1
- package/dist/cjs/anyspend/react/components/common/FiatPaymentMethod.js +2 -2
- package/dist/cjs/anyspend/react/components/common/OrderDetails.js +1 -1
- package/dist/cjs/anyspend/react/components/common/PointsDetailPanel.js +1 -1
- package/dist/cjs/anyspend/react/components/common/RecipientSelection.js +1 -1
- package/dist/cjs/anyspend/react/components/index.d.ts +1 -1
- package/dist/cjs/anyspend/react/hooks/index.d.ts +1 -0
- package/dist/cjs/anyspend/react/hooks/index.js +1 -0
- package/dist/cjs/anyspend/react/hooks/useAnyspendCreateOnrampOrder.d.ts +2 -0
- package/dist/cjs/anyspend/react/hooks/useAnyspendCreateOnrampOrder.js +14 -0
- package/dist/cjs/anyspend/react/hooks/useKycStatus.d.ts +47 -0
- package/dist/cjs/anyspend/react/hooks/useKycStatus.js +124 -0
- package/dist/cjs/anyspend/services/anyspend.d.ts +4 -1
- package/dist/cjs/anyspend/services/anyspend.js +3 -1
- package/dist/cjs/global-account/react/components/B3DynamicModal.js +1 -1
- package/dist/cjs/global-account/react/components/ManageAccount/BottomNavigation.js +3 -3
- package/dist/cjs/global-account/react/components/ManageAccount/HomeActions.js +1 -1
- package/dist/cjs/global-account/react/components/ManageAccount/channels/TelegramChannel.js +1 -1
- package/dist/cjs/global-account/react/components/SignInWithB3/SignIn.js +1 -1
- package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +13 -5
- package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Privy.js +1 -1
- package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStep.d.ts +1 -1
- package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStep.js +21 -24
- package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStepCustom.js +1 -1
- package/dist/cjs/global-account/react/hooks/useAuth.js +1 -1
- package/dist/cjs/global-account/react/hooks/useAuthentication.d.ts +3 -1
- package/dist/cjs/global-account/react/hooks/useAuthentication.js +94 -24
- package/dist/cjs/global-account/react/hooks/useGetAllTWSigners.js +2 -1
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +4 -0
- package/dist/cjs/global-account/react/stores/useModalStore.js +2 -0
- package/dist/cjs/global-account/react/utils/createWagmiConfig.d.ts +18 -0
- package/dist/cjs/global-account/react/utils/createWagmiConfig.js +17 -0
- package/dist/esm/anyspend/platform/client.d.ts +35 -0
- package/dist/esm/anyspend/platform/client.js +153 -0
- package/dist/esm/anyspend/platform/errors.d.ts +38 -0
- package/dist/esm/anyspend/platform/errors.js +67 -0
- package/dist/esm/anyspend/platform/index.d.ts +87 -0
- package/dist/esm/anyspend/platform/index.js +75 -0
- package/dist/esm/anyspend/platform/resources/analytics.d.ts +7 -0
- package/dist/esm/anyspend/platform/resources/analytics.js +8 -0
- package/dist/esm/anyspend/platform/resources/checkout-sessions.d.ts +17 -0
- package/dist/esm/anyspend/platform/resources/checkout-sessions.js +23 -0
- package/dist/esm/anyspend/platform/resources/customers.d.ts +19 -0
- package/dist/esm/anyspend/platform/resources/customers.js +30 -0
- package/dist/esm/anyspend/platform/resources/discount-codes.d.ts +29 -0
- package/dist/esm/anyspend/platform/resources/discount-codes.js +27 -0
- package/dist/esm/anyspend/platform/resources/events.d.ts +14 -0
- package/dist/esm/anyspend/platform/resources/events.js +12 -0
- package/dist/esm/anyspend/platform/resources/notifications.d.ts +18 -0
- package/dist/esm/anyspend/platform/resources/notifications.js +23 -0
- package/dist/esm/anyspend/platform/resources/organization.d.ts +17 -0
- package/dist/esm/anyspend/platform/resources/organization.js +11 -0
- package/dist/esm/anyspend/platform/resources/payment-links.d.ts +21 -0
- package/dist/esm/anyspend/platform/resources/payment-links.js +45 -0
- package/dist/esm/anyspend/platform/resources/products.d.ts +27 -0
- package/dist/esm/anyspend/platform/resources/products.js +27 -0
- package/dist/esm/anyspend/platform/resources/transactions.d.ts +11 -0
- package/dist/esm/anyspend/platform/resources/transactions.js +21 -0
- package/dist/esm/anyspend/platform/resources/webhooks.d.ts +14 -0
- package/dist/esm/anyspend/platform/resources/webhooks.js +29 -0
- package/dist/esm/anyspend/platform/resources/widgets.d.ts +38 -0
- package/dist/esm/anyspend/platform/resources/widgets.js +27 -0
- package/dist/esm/anyspend/platform/types.d.ts +478 -0
- package/dist/esm/anyspend/platform/types.js +4 -0
- package/dist/esm/anyspend/platform/utils/idempotency.d.ts +4 -0
- package/dist/esm/anyspend/platform/utils/idempotency.js +14 -0
- package/dist/esm/anyspend/platform/utils/pagination.d.ts +12 -0
- package/dist/esm/anyspend/platform/utils/pagination.js +19 -0
- package/dist/esm/anyspend/react/components/AnySpend.d.ts +5 -1
- package/dist/esm/anyspend/react/components/AnySpend.js +128 -17
- package/dist/esm/anyspend/react/components/AnySpendCustom.js +4 -4
- package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.js +2 -2
- package/dist/esm/anyspend/react/components/checkout/AnySpendCheckout.d.ts +14 -6
- package/dist/esm/anyspend/react/components/checkout/AnySpendCheckout.js +55 -8
- package/dist/esm/anyspend/react/components/checkout/AnySpendCheckoutTrigger.d.ts +3 -1
- package/dist/esm/anyspend/react/components/checkout/AnySpendCheckoutTrigger.js +2 -2
- package/dist/esm/anyspend/react/components/checkout/CheckoutPaymentPanel.d.ts +5 -1
- package/dist/esm/anyspend/react/components/checkout/CheckoutPaymentPanel.js +2 -2
- package/dist/esm/anyspend/react/components/checkout/CryptoPayPanel.js +1 -1
- package/dist/esm/anyspend/react/components/checkout/FiatCheckoutPanel.d.ts +5 -1
- package/dist/esm/anyspend/react/components/checkout/FiatCheckoutPanel.js +50 -18
- package/dist/esm/anyspend/react/components/checkout/KycGate.d.ts +11 -0
- package/dist/esm/anyspend/react/components/checkout/KycGate.js +167 -0
- package/dist/esm/anyspend/react/components/checkout/VariablePricingInput.d.ts +17 -0
- package/dist/esm/anyspend/react/components/checkout/VariablePricingInput.js +142 -0
- package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +1 -1
- package/dist/esm/anyspend/react/components/common/FeeDetailPanel.js +1 -1
- package/dist/esm/anyspend/react/components/common/FiatPaymentMethod.js +2 -2
- package/dist/esm/anyspend/react/components/common/OrderDetails.js +1 -1
- package/dist/esm/anyspend/react/components/common/PointsDetailPanel.js +1 -1
- package/dist/esm/anyspend/react/components/common/RecipientSelection.js +1 -1
- package/dist/esm/anyspend/react/components/index.d.ts +1 -1
- package/dist/esm/anyspend/react/hooks/index.d.ts +1 -0
- package/dist/esm/anyspend/react/hooks/index.js +1 -0
- package/dist/esm/anyspend/react/hooks/useAnyspendCreateOnrampOrder.d.ts +2 -0
- package/dist/esm/anyspend/react/hooks/useAnyspendCreateOnrampOrder.js +14 -0
- package/dist/esm/anyspend/react/hooks/useKycStatus.d.ts +47 -0
- package/dist/esm/anyspend/react/hooks/useKycStatus.js +117 -0
- package/dist/esm/anyspend/services/anyspend.d.ts +4 -1
- package/dist/esm/anyspend/services/anyspend.js +3 -1
- package/dist/esm/global-account/react/components/B3DynamicModal.js +1 -1
- package/dist/esm/global-account/react/components/ManageAccount/BottomNavigation.js +3 -3
- package/dist/esm/global-account/react/components/ManageAccount/HomeActions.js +1 -1
- package/dist/esm/global-account/react/components/ManageAccount/channels/TelegramChannel.js +1 -1
- package/dist/esm/global-account/react/components/SignInWithB3/SignIn.js +1 -1
- package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +13 -5
- package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Privy.js +1 -1
- package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStep.d.ts +1 -1
- package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStep.js +21 -24
- package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStepCustom.js +1 -1
- package/dist/esm/global-account/react/hooks/useAuth.js +2 -2
- package/dist/esm/global-account/react/hooks/useAuthentication.d.ts +3 -1
- package/dist/esm/global-account/react/hooks/useAuthentication.js +94 -24
- package/dist/esm/global-account/react/hooks/useGetAllTWSigners.js +2 -1
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +4 -0
- package/dist/esm/global-account/react/stores/useModalStore.js +2 -0
- package/dist/esm/global-account/react/utils/createWagmiConfig.d.ts +18 -0
- package/dist/esm/global-account/react/utils/createWagmiConfig.js +16 -0
- package/dist/styles/index.css +1 -1
- package/dist/types/anyspend/platform/client.d.ts +35 -0
- package/dist/types/anyspend/platform/errors.d.ts +38 -0
- package/dist/types/anyspend/platform/index.d.ts +87 -0
- package/dist/types/anyspend/platform/resources/analytics.d.ts +7 -0
- package/dist/types/anyspend/platform/resources/checkout-sessions.d.ts +17 -0
- package/dist/types/anyspend/platform/resources/customers.d.ts +19 -0
- package/dist/types/anyspend/platform/resources/discount-codes.d.ts +29 -0
- package/dist/types/anyspend/platform/resources/events.d.ts +14 -0
- package/dist/types/anyspend/platform/resources/notifications.d.ts +18 -0
- package/dist/types/anyspend/platform/resources/organization.d.ts +17 -0
- package/dist/types/anyspend/platform/resources/payment-links.d.ts +21 -0
- package/dist/types/anyspend/platform/resources/products.d.ts +27 -0
- package/dist/types/anyspend/platform/resources/transactions.d.ts +11 -0
- package/dist/types/anyspend/platform/resources/webhooks.d.ts +14 -0
- package/dist/types/anyspend/platform/resources/widgets.d.ts +38 -0
- package/dist/types/anyspend/platform/types.d.ts +478 -0
- package/dist/types/anyspend/platform/utils/idempotency.d.ts +4 -0
- package/dist/types/anyspend/platform/utils/pagination.d.ts +12 -0
- package/dist/types/anyspend/react/components/AnySpend.d.ts +5 -1
- package/dist/types/anyspend/react/components/checkout/AnySpendCheckout.d.ts +14 -6
- package/dist/types/anyspend/react/components/checkout/AnySpendCheckoutTrigger.d.ts +3 -1
- package/dist/types/anyspend/react/components/checkout/CheckoutPaymentPanel.d.ts +5 -1
- package/dist/types/anyspend/react/components/checkout/FiatCheckoutPanel.d.ts +5 -1
- package/dist/types/anyspend/react/components/checkout/KycGate.d.ts +11 -0
- package/dist/types/anyspend/react/components/checkout/VariablePricingInput.d.ts +17 -0
- package/dist/types/anyspend/react/components/index.d.ts +1 -1
- package/dist/types/anyspend/react/hooks/index.d.ts +1 -0
- package/dist/types/anyspend/react/hooks/useAnyspendCreateOnrampOrder.d.ts +2 -0
- package/dist/types/anyspend/react/hooks/useKycStatus.d.ts +47 -0
- package/dist/types/anyspend/services/anyspend.d.ts +4 -1
- package/dist/types/global-account/react/components/SignInWithB3/steps/LoginStep.d.ts +1 -1
- package/dist/types/global-account/react/hooks/useAuthentication.d.ts +3 -1
- package/dist/types/global-account/react/stores/useModalStore.d.ts +4 -0
- package/dist/types/global-account/react/utils/createWagmiConfig.d.ts +18 -0
- package/package.json +7 -1
- package/src/anyspend/docs/checkout-sessions.md +20 -3
- package/src/anyspend/platform/client.ts +198 -0
- package/src/anyspend/platform/errors.ts +92 -0
- package/src/anyspend/platform/index.ts +129 -0
- package/src/anyspend/platform/resources/analytics.ts +10 -0
- package/src/anyspend/platform/resources/checkout-sessions.ts +36 -0
- package/src/anyspend/platform/resources/customers.ts +54 -0
- package/src/anyspend/platform/resources/discount-codes.ts +63 -0
- package/src/anyspend/platform/resources/events.ts +22 -0
- package/src/anyspend/platform/resources/notifications.ts +37 -0
- package/src/anyspend/platform/resources/organization.ts +24 -0
- package/src/anyspend/platform/resources/payment-links.ts +74 -0
- package/src/anyspend/platform/resources/products.ts +59 -0
- package/src/anyspend/platform/resources/transactions.ts +33 -0
- package/src/anyspend/platform/resources/webhooks.ts +47 -0
- package/src/anyspend/platform/resources/widgets.ts +63 -0
- package/src/anyspend/platform/types.ts +532 -0
- package/src/anyspend/platform/utils/idempotency.ts +15 -0
- package/src/anyspend/platform/utils/pagination.ts +32 -0
- package/src/anyspend/react/components/AnySpend.tsx +152 -18
- package/src/anyspend/react/components/AnySpendCustom.tsx +4 -4
- package/src/anyspend/react/components/AnySpendCustomExactIn.tsx +2 -2
- package/src/anyspend/react/components/checkout/AnySpendCheckout.tsx +81 -18
- package/src/anyspend/react/components/checkout/AnySpendCheckoutTrigger.tsx +4 -0
- package/src/anyspend/react/components/checkout/CheckoutPaymentPanel.tsx +8 -0
- package/src/anyspend/react/components/checkout/CryptoPayPanel.tsx +4 -13
- package/src/anyspend/react/components/checkout/FiatCheckoutPanel.tsx +86 -17
- package/src/anyspend/react/components/checkout/KycGate.tsx +387 -0
- package/src/anyspend/react/components/checkout/VariablePricingInput.tsx +247 -0
- package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +1 -1
- package/src/anyspend/react/components/common/FeeDetailPanel.tsx +1 -1
- package/src/anyspend/react/components/common/FiatPaymentMethod.tsx +2 -2
- package/src/anyspend/react/components/common/OrderDetails.tsx +1 -1
- package/src/anyspend/react/components/common/PointsDetailPanel.tsx +1 -1
- package/src/anyspend/react/components/common/RecipientSelection.tsx +1 -1
- package/src/anyspend/react/components/index.ts +1 -0
- package/src/anyspend/react/hooks/index.ts +1 -0
- package/src/anyspend/react/hooks/useAnyspendCreateOnrampOrder.ts +17 -0
- package/src/anyspend/react/hooks/useKycStatus.ts +150 -0
- package/src/anyspend/services/anyspend.ts +7 -0
- package/src/global-account/react/components/B3DynamicModal.tsx +0 -2
- package/src/global-account/react/components/ManageAccount/BottomNavigation.tsx +7 -7
- package/src/global-account/react/components/ManageAccount/HomeActions.tsx +2 -2
- package/src/global-account/react/components/ManageAccount/ManageAccount.tsx +7 -7
- package/src/global-account/react/components/ManageAccount/channels/TelegramChannel.tsx +1 -1
- package/src/global-account/react/components/SignInWithB3/SignIn.tsx +1 -1
- package/src/global-account/react/components/SignInWithB3/SignInWithB3Flow.tsx +13 -5
- package/src/global-account/react/components/SignInWithB3/SignInWithB3Privy.tsx +1 -1
- package/src/global-account/react/components/SignInWithB3/steps/LoginStep.tsx +35 -25
- package/src/global-account/react/components/SignInWithB3/steps/LoginStepCustom.tsx +1 -1
- package/src/global-account/react/hooks/useAuth.ts +2 -2
- package/src/global-account/react/hooks/useAuthentication.ts +92 -27
- package/src/global-account/react/hooks/useGetAllTWSigners.tsx +2 -1
- package/src/global-account/react/stores/useModalStore.ts +6 -0
- package/src/global-account/react/utils/createWagmiConfig.tsx +18 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Wallet } from "thirdweb/wallets";
|
|
2
2
|
import { preAuthenticate } from "thirdweb/wallets/in-app";
|
|
3
|
-
export declare function useAuthentication(partnerId: string
|
|
3
|
+
export declare function useAuthentication(partnerId: string, { skipAutoConnect }?: {
|
|
4
|
+
skipAutoConnect?: boolean;
|
|
5
|
+
}): {
|
|
4
6
|
logout: (callback?: () => void) => Promise<void>;
|
|
5
7
|
isAuthenticated: boolean;
|
|
6
8
|
isReady: boolean;
|
|
@@ -21,11 +21,26 @@ const createWagmiConfig_1 = require("../utils/createWagmiConfig");
|
|
|
21
21
|
const useTWAuth_1 = require("./useTWAuth");
|
|
22
22
|
const useUserQuery_1 = require("./useUserQuery");
|
|
23
23
|
const debug = (0, debug_1.debugB3React)("useAuthentication");
|
|
24
|
-
function useAuthentication(partnerId) {
|
|
24
|
+
function useAuthentication(partnerId, { skipAutoConnect = false } = {}) {
|
|
25
25
|
const { onConnectCallback, onLogoutCallback } = (0, react_2.useContext)(LocalSDKProvider_1.LocalSDKContext);
|
|
26
26
|
const { disconnect } = (0, react_3.useDisconnect)();
|
|
27
27
|
const wallets = (0, react_3.useConnectedWallets)();
|
|
28
|
+
// Keep refs so logout() always disconnects current wallets, not stale closure values.
|
|
29
|
+
// autoConnectCore captures onConnect (and thus logout) from the first render before wallets
|
|
30
|
+
// are populated — without these refs, logout() would capture wallets=[] and disconnect nothing.
|
|
31
|
+
const walletsRef = (0, react_2.useRef)(wallets);
|
|
32
|
+
(0, react_2.useEffect)(() => {
|
|
33
|
+
walletsRef.current = wallets;
|
|
34
|
+
}, [wallets]);
|
|
28
35
|
const activeWallet = (0, react_3.useActiveWallet)();
|
|
36
|
+
// Track the active wallet by ref so logout() can disconnect the exact reference
|
|
37
|
+
// stored in thirdweb's activeWalletStore. walletsRef.current (from useConnectedWallets)
|
|
38
|
+
// may hold a different object reference than what thirdweb considers "active",
|
|
39
|
+
// causing the identity check in onWalletDisconnect to fail silently.
|
|
40
|
+
const activeWalletRef = (0, react_2.useRef)(activeWallet);
|
|
41
|
+
(0, react_2.useEffect)(() => {
|
|
42
|
+
activeWalletRef.current = activeWallet;
|
|
43
|
+
}, [activeWallet]);
|
|
29
44
|
const isAuthenticated = (0, react_1.useAuthStore)(state => state.isAuthenticated);
|
|
30
45
|
const setIsAuthenticated = (0, react_1.useAuthStore)(state => state.setIsAuthenticated);
|
|
31
46
|
const setIsConnected = (0, react_1.useAuthStore)(state => state.setIsConnected);
|
|
@@ -132,21 +147,37 @@ function useAuthentication(partnerId) {
|
|
|
132
147
|
}
|
|
133
148
|
}, [activeWallet, partnerId, authenticate, setIsAuthenticated, setIsAuthenticating, setUser, setHasStartedConnecting]);
|
|
134
149
|
const logout = (0, react_2.useCallback)(async (callback) => {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
150
|
+
// Disconnect ecosystem/smart wallets from the connected wallets list.
|
|
151
|
+
// EOA wallets (MetaMask, Coinbase Wallet) are left in the list so they can
|
|
152
|
+
// auto-reconnect on next login without requiring a new approval popup.
|
|
153
|
+
// Use walletsRef.current (not the stale closure value) so we always get current wallets —
|
|
154
|
+
// autoConnectCore captures logout from the first render when wallets is still [].
|
|
155
|
+
walletsRef.current.forEach(wallet => {
|
|
156
|
+
debug("@@logout:wallet", wallet.id);
|
|
157
|
+
if (wallet.id.startsWith("ecosystem.") || wallet.id === "smart") {
|
|
158
|
+
disconnect(wallet);
|
|
159
|
+
}
|
|
144
160
|
});
|
|
145
|
-
//
|
|
146
|
-
//
|
|
161
|
+
// Unconditionally disconnect the active wallet to clear thirdweb's activeAccountStore.
|
|
162
|
+
// This is separate from the loop above: even if the active wallet is an EOA (e.g.
|
|
163
|
+
// Coinbase Wallet), we must disconnect it so activeAccount becomes undefined.
|
|
164
|
+
// Without this, ConnectEmbed renders show=false (blank modal) because it checks
|
|
165
|
+
// show = !activeAccount. Note: thirdweb's disconnect() is idempotent — calling it
|
|
166
|
+
// on an already-disconnected wallet (from the loop above) is a no-op.
|
|
167
|
+
// We use the exact reference from activeWalletRef because thirdweb's
|
|
168
|
+
// onWalletDisconnect uses strict identity (===) to decide whether to clear
|
|
169
|
+
// activeAccountStore.
|
|
170
|
+
// Tradeoff: EOA wallets (MetaMask, Coinbase Wallet) will be removed from
|
|
171
|
+
// connectedWallets and require a new approval popup on next login.
|
|
172
|
+
// This is acceptable because a working login form is more critical than
|
|
173
|
+
// skipping one wallet approval step.
|
|
174
|
+
if (activeWalletRef.current) {
|
|
175
|
+
debug("@@logout:disconnecting active wallet", activeWalletRef.current.id);
|
|
176
|
+
disconnect(activeWalletRef.current);
|
|
177
|
+
}
|
|
178
|
+
// Clear user-specific storage (auth tokens, cached user data).
|
|
179
|
+
// Thirdweb's wallet connection state is managed separately via disconnect() above.
|
|
147
180
|
if (typeof localStorage !== "undefined") {
|
|
148
|
-
localStorage.removeItem("thirdweb:connected-wallet-ids");
|
|
149
|
-
localStorage.removeItem("wagmi.store");
|
|
150
181
|
localStorage.removeItem("lastAuthProvider");
|
|
151
182
|
localStorage.removeItem("b3-user");
|
|
152
183
|
}
|
|
@@ -154,33 +185,62 @@ function useAuthentication(partnerId) {
|
|
|
154
185
|
debug("@@logout:loggedOut");
|
|
155
186
|
setIsAuthenticated(false);
|
|
156
187
|
setIsConnected(false);
|
|
188
|
+
// Reset isAuthenticating so any in-flight page-load auto-connect that set it true
|
|
189
|
+
// does not keep the login modal spinner stuck after logout() is called.
|
|
190
|
+
setIsAuthenticating(false);
|
|
157
191
|
setUser();
|
|
158
192
|
callback?.();
|
|
159
193
|
if (onLogoutCallback) {
|
|
160
194
|
await onLogoutCallback();
|
|
161
195
|
}
|
|
162
|
-
},
|
|
196
|
+
},
|
|
197
|
+
// wallets intentionally omitted — we use walletsRef.current so this callback stays stable
|
|
198
|
+
// and always operates on current wallets even when captured in stale closures.
|
|
199
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
200
|
+
[disconnect, setIsAuthenticated, setIsAuthenticating, setUser, setIsConnected, onLogoutCallback]);
|
|
163
201
|
const onConnect = (0, react_2.useCallback)(async (_walleAutoConnectedWith, allConnectedWallets) => {
|
|
164
202
|
debug("@@useAuthentication:onConnect", { _walleAutoConnectedWith, allConnectedWallets });
|
|
203
|
+
const connectedEcosystemWallet = allConnectedWallets.find(w => w.id.startsWith("ecosystem."));
|
|
165
204
|
try {
|
|
166
|
-
|
|
167
|
-
if (!wallet) {
|
|
205
|
+
if (!connectedEcosystemWallet) {
|
|
168
206
|
throw new Error("No smart wallet found during auto-connect");
|
|
169
207
|
}
|
|
170
|
-
debug("@@useAuthentication:onConnect", { wallet });
|
|
208
|
+
debug("@@useAuthentication:onConnect", { wallet: connectedEcosystemWallet });
|
|
171
209
|
setHasStartedConnecting(true);
|
|
172
210
|
setIsConnected(true);
|
|
173
211
|
setIsAuthenticating(true);
|
|
174
|
-
await setActiveWallet(
|
|
175
|
-
const userAuth = await authenticateUser(
|
|
212
|
+
await setActiveWallet(connectedEcosystemWallet);
|
|
213
|
+
const userAuth = await authenticateUser(connectedEcosystemWallet);
|
|
176
214
|
if (userAuth && onConnectCallback) {
|
|
177
|
-
await onConnectCallback(
|
|
215
|
+
await onConnectCallback(connectedEcosystemWallet, userAuth.accessToken);
|
|
178
216
|
}
|
|
179
217
|
}
|
|
180
218
|
catch (error) {
|
|
181
219
|
debug("@@useAuthentication:onConnect:failed", { error });
|
|
182
220
|
setIsAuthenticated(false);
|
|
183
221
|
setUser(undefined);
|
|
222
|
+
// Directly disconnect the ecosystem wallet we set active above.
|
|
223
|
+
// We can't rely on logout()'s activeWalletRef here because it's updated
|
|
224
|
+
// via useEffect (deferred until after paint), but this callback may run
|
|
225
|
+
// entirely within a single React commit cycle — before the ref updates.
|
|
226
|
+
// Note: logout() below may also call disconnect() on the same wallet via
|
|
227
|
+
// activeWalletRef — thirdweb's disconnect() is idempotent so this is safe.
|
|
228
|
+
if (connectedEcosystemWallet) {
|
|
229
|
+
debug("@@useAuthentication:onConnect:disconnecting ecosystem wallet", connectedEcosystemWallet.id);
|
|
230
|
+
disconnect(connectedEcosystemWallet);
|
|
231
|
+
}
|
|
232
|
+
// Also disconnect the wallet that autoConnectCore set as active.
|
|
233
|
+
// When only a non-ecosystem wallet (e.g. MetaMask) auto-reconnects,
|
|
234
|
+
// connectedEcosystemWallet is undefined, so the block above is skipped.
|
|
235
|
+
// But autoConnectCore already set this wallet as thirdweb's activeWallet,
|
|
236
|
+
// leaving activeAccount set. ConnectEmbed checks show = !activeAccount,
|
|
237
|
+
// so if we don't clear it, the login form renders blank.
|
|
238
|
+
// Uses object identity (===) which is safe because thirdweb returns
|
|
239
|
+
// stable references for connected wallet instances.
|
|
240
|
+
if (_walleAutoConnectedWith && _walleAutoConnectedWith !== connectedEcosystemWallet) {
|
|
241
|
+
debug("@@useAuthentication:onConnect:disconnecting auto-connected wallet", _walleAutoConnectedWith.id);
|
|
242
|
+
disconnect(_walleAutoConnectedWith);
|
|
243
|
+
}
|
|
184
244
|
await logout();
|
|
185
245
|
}
|
|
186
246
|
finally {
|
|
@@ -195,6 +255,7 @@ function useAuthentication(partnerId) {
|
|
|
195
255
|
isAuthenticated,
|
|
196
256
|
isAuthenticating,
|
|
197
257
|
isConnected,
|
|
258
|
+
disconnect,
|
|
198
259
|
setHasStartedConnecting,
|
|
199
260
|
setIsConnected,
|
|
200
261
|
setIsAuthenticating,
|
|
@@ -207,23 +268,32 @@ function useAuthentication(partnerId) {
|
|
|
207
268
|
]);
|
|
208
269
|
const { isLoading: useAutoConnectLoading } = (0, react_3.useAutoConnect)({
|
|
209
270
|
client: thirdweb_1.client,
|
|
210
|
-
|
|
271
|
+
// When skipAutoConnect is true (e.g. LoginStepContent, SignInWithB3Flow), pass an empty
|
|
272
|
+
// wallets array so useAutoConnect completes immediately without firing onConnect.
|
|
273
|
+
// Only AuthenticationProvider (the primary instance) should own auto-connect.
|
|
274
|
+
wallets: skipAutoConnect ? [] : [wallet],
|
|
211
275
|
onConnect,
|
|
212
276
|
onTimeout: () => {
|
|
277
|
+
if (skipAutoConnect)
|
|
278
|
+
return;
|
|
213
279
|
logout().catch(error => {
|
|
214
280
|
debug("@@useAuthentication:logout on timeout failed", { error });
|
|
215
281
|
});
|
|
216
282
|
},
|
|
217
283
|
});
|
|
218
284
|
/**
|
|
219
|
-
* useAutoConnectLoading starts as false
|
|
285
|
+
* useAutoConnectLoading starts as false.
|
|
286
|
+
* Only the primary (non-skip) instance manages isAuthenticating via this effect
|
|
287
|
+
* to avoid race conditions when multiple useAuthentication instances are mounted.
|
|
220
288
|
*/
|
|
221
289
|
(0, react_2.useEffect)(() => {
|
|
290
|
+
if (skipAutoConnect)
|
|
291
|
+
return;
|
|
222
292
|
if (!useAutoConnectLoading && useAutoConnectLoadingPrevious.current && !hasStartedConnecting) {
|
|
223
293
|
setIsAuthenticating(false);
|
|
224
294
|
}
|
|
225
295
|
useAutoConnectLoadingPrevious.current = useAutoConnectLoading;
|
|
226
|
-
}, [useAutoConnectLoading, hasStartedConnecting, setIsAuthenticating]);
|
|
296
|
+
}, [useAutoConnectLoading, hasStartedConnecting, setIsAuthenticating, skipAutoConnect]);
|
|
227
297
|
const isReady = isAuthenticated && !isAuthenticating;
|
|
228
298
|
return {
|
|
229
299
|
logout,
|
|
@@ -68,7 +68,8 @@ function useGetAllTWSigners({ chain, accountAddress, queryOptions }) {
|
|
|
68
68
|
});
|
|
69
69
|
return result;
|
|
70
70
|
},
|
|
71
|
-
enabled
|
|
71
|
+
// Respect queryOptions.enabled if explicitly set (e.g. signersEnabled=false from SignInWithB3Flow)
|
|
72
|
+
enabled: queryOptions?.enabled !== false && Boolean(chain && accountAddress),
|
|
72
73
|
refetchOnMount: true,
|
|
73
74
|
refetchOnWindowFocus: true,
|
|
74
75
|
refetchOnReconnect: true,
|
|
@@ -657,6 +657,10 @@ interface ModalState {
|
|
|
657
657
|
setLinkingState: (isLinking: boolean, method?: string | null) => void;
|
|
658
658
|
/** Function to update closable property of current content without adding to history */
|
|
659
659
|
setClosable: (closable: boolean) => void;
|
|
660
|
+
/** Whether a third-party iframe (e.g. Persona KYC) is currently active over the modal */
|
|
661
|
+
personaActive: boolean;
|
|
662
|
+
/** Function to mark a third-party iframe as active/inactive */
|
|
663
|
+
setPersonaActive: (active: boolean) => void;
|
|
660
664
|
}
|
|
661
665
|
/**
|
|
662
666
|
* Zustand store for managing modal state
|
|
@@ -39,4 +39,6 @@ exports.useModalStore = (0, zustand_1.create)(set => ({
|
|
|
39
39
|
setClosable: (closable) => set(state => ({
|
|
40
40
|
contentType: state.contentType ? { ...state.contentType, closable } : null,
|
|
41
41
|
})),
|
|
42
|
+
personaActive: false,
|
|
43
|
+
setPersonaActive: (active) => set({ personaActive: active }),
|
|
42
44
|
}));
|
|
@@ -25,3 +25,21 @@ export declare function createWagmiConfig(options: CreateWagmiConfigOptions): im
|
|
|
25
25
|
}, {
|
|
26
26
|
"thirdweb:lastChainId": number;
|
|
27
27
|
}>)[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Returns a cached wagmi config for the given partnerId.
|
|
30
|
+
* Use this instead of calling createWagmiConfig() directly inside React components or hooks
|
|
31
|
+
* to avoid registering duplicate EventEmitter listeners on every render.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getCachedWagmiConfig(options: CreateWagmiConfigOptions): import("wagmi").Config<readonly [import("viem").Chain, ...import("viem").Chain[]], {
|
|
34
|
+
[k: string]: import("viem").HttpTransport<undefined, false>;
|
|
35
|
+
}, (CreateConnectorFn | CreateConnectorFn<import("thirdweb/dist/types/adapters/eip1193").EIP1193Provider | undefined, {
|
|
36
|
+
connect<withCapabilities extends boolean = false>(parameters?: import("@thirdweb-dev/wagmi-adapter").ConnectionOptions<withCapabilities> | undefined): Promise<{
|
|
37
|
+
accounts: withCapabilities extends true ? readonly {
|
|
38
|
+
address: `0x${string}`;
|
|
39
|
+
capabilities: Record<string, unknown>;
|
|
40
|
+
}[] : readonly `0x${string}`[];
|
|
41
|
+
chainId: number;
|
|
42
|
+
}>;
|
|
43
|
+
}, {
|
|
44
|
+
"thirdweb:lastChainId": number;
|
|
45
|
+
}>)[]>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createWagmiConfig = createWagmiConfig;
|
|
4
|
+
exports.getCachedWagmiConfig = getCachedWagmiConfig;
|
|
4
5
|
const constants_1 = require("../../../shared/constants");
|
|
5
6
|
const supported_1 = require("../../../shared/constants/chains/supported");
|
|
6
7
|
const thirdweb_1 = require("../../../shared/utils/thirdweb");
|
|
@@ -30,3 +31,19 @@ function createWagmiConfig(options) {
|
|
|
30
31
|
connectors: finalConnectors,
|
|
31
32
|
});
|
|
32
33
|
}
|
|
34
|
+
/** Module-level cache — wagmi configs must not be recreated on every render. */
|
|
35
|
+
const wagmiConfigCache = new Map();
|
|
36
|
+
/**
|
|
37
|
+
* Returns a cached wagmi config for the given partnerId.
|
|
38
|
+
* Use this instead of calling createWagmiConfig() directly inside React components or hooks
|
|
39
|
+
* to avoid registering duplicate EventEmitter listeners on every render.
|
|
40
|
+
*/
|
|
41
|
+
function getCachedWagmiConfig(options) {
|
|
42
|
+
const key = options.partnerId;
|
|
43
|
+
let config = wagmiConfigCache.get(key);
|
|
44
|
+
if (!config) {
|
|
45
|
+
config = createWagmiConfig(options);
|
|
46
|
+
wagmiConfigCache.set(key, config);
|
|
47
|
+
}
|
|
48
|
+
return config;
|
|
49
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core HTTP client for the AnySpend Platform API.
|
|
3
|
+
* Handles authentication, retries, error parsing, and idempotency.
|
|
4
|
+
*/
|
|
5
|
+
export interface ClientConfig {
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
timeout?: number;
|
|
8
|
+
maxRetries?: number;
|
|
9
|
+
idempotencyKeyGenerator?: () => string;
|
|
10
|
+
}
|
|
11
|
+
export declare const DEFAULT_BASE_URL = "https://platform-api.anyspend.com/api/v1";
|
|
12
|
+
export declare class HttpClient {
|
|
13
|
+
private apiKey;
|
|
14
|
+
private baseUrl;
|
|
15
|
+
private timeout;
|
|
16
|
+
private maxRetries;
|
|
17
|
+
private generateIdempotencyKey;
|
|
18
|
+
constructor(apiKey: string, config?: ClientConfig);
|
|
19
|
+
get<T>(path: string, params?: object): Promise<T>;
|
|
20
|
+
post<T>(path: string, body?: object): Promise<T>;
|
|
21
|
+
patch<T>(path: string, body: object): Promise<T>;
|
|
22
|
+
delete<T>(path: string, body?: object): Promise<T>;
|
|
23
|
+
postFormData<T>(path: string, formData: FormData): Promise<T>;
|
|
24
|
+
private buildUrl;
|
|
25
|
+
private request;
|
|
26
|
+
private requestRaw;
|
|
27
|
+
private executeWithRetry;
|
|
28
|
+
private sleep;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Static HTTP client for unauthenticated requests (quick-pay).
|
|
32
|
+
*/
|
|
33
|
+
export declare class StaticHttpClient {
|
|
34
|
+
static post<T>(baseUrl: string, path: string, body: Record<string, unknown>): Promise<T>;
|
|
35
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core HTTP client for the AnySpend Platform API.
|
|
3
|
+
* Handles authentication, retries, error parsing, and idempotency.
|
|
4
|
+
*/
|
|
5
|
+
import { parseApiError } from "./errors.js";
|
|
6
|
+
import { generateIdempotencyKey } from "./utils/idempotency.js";
|
|
7
|
+
export const DEFAULT_BASE_URL = "https://platform-api.anyspend.com/api/v1";
|
|
8
|
+
const DEFAULT_TIMEOUT = 30000;
|
|
9
|
+
const DEFAULT_MAX_RETRIES = 3;
|
|
10
|
+
export class HttpClient {
|
|
11
|
+
constructor(apiKey, config = {}) {
|
|
12
|
+
this.apiKey = apiKey;
|
|
13
|
+
this.baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
14
|
+
this.timeout = config.timeout || DEFAULT_TIMEOUT;
|
|
15
|
+
this.maxRetries = config.maxRetries || DEFAULT_MAX_RETRIES;
|
|
16
|
+
this.generateIdempotencyKey = config.idempotencyKeyGenerator || generateIdempotencyKey;
|
|
17
|
+
}
|
|
18
|
+
async get(path, params) {
|
|
19
|
+
const url = this.buildUrl(path, params);
|
|
20
|
+
return this.request("GET", url);
|
|
21
|
+
}
|
|
22
|
+
async post(path, body) {
|
|
23
|
+
const url = this.buildUrl(path);
|
|
24
|
+
return this.request("POST", url, body);
|
|
25
|
+
}
|
|
26
|
+
async patch(path, body) {
|
|
27
|
+
const url = this.buildUrl(path);
|
|
28
|
+
return this.request("PATCH", url, body);
|
|
29
|
+
}
|
|
30
|
+
async delete(path, body) {
|
|
31
|
+
const url = this.buildUrl(path);
|
|
32
|
+
return this.request("DELETE", url, body);
|
|
33
|
+
}
|
|
34
|
+
async postFormData(path, formData) {
|
|
35
|
+
const url = this.buildUrl(path);
|
|
36
|
+
return this.requestRaw("POST", url, formData);
|
|
37
|
+
}
|
|
38
|
+
buildUrl(path, params) {
|
|
39
|
+
const url = new URL(`${this.baseUrl}${path}`);
|
|
40
|
+
if (params) {
|
|
41
|
+
for (const [key, value] of Object.entries(params)) {
|
|
42
|
+
if (value !== undefined && value !== null)
|
|
43
|
+
url.searchParams.set(key, String(value));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return url.toString();
|
|
47
|
+
}
|
|
48
|
+
async request(method, url, body) {
|
|
49
|
+
const headers = {
|
|
50
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
51
|
+
"Content-Type": "application/json",
|
|
52
|
+
};
|
|
53
|
+
// Auto-generate idempotency key for POST/PATCH
|
|
54
|
+
if (method === "POST" || method === "PATCH") {
|
|
55
|
+
headers["Idempotency-Key"] = this.generateIdempotencyKey();
|
|
56
|
+
}
|
|
57
|
+
return this.executeWithRetry(method, url, headers, body ? JSON.stringify(body) : undefined);
|
|
58
|
+
}
|
|
59
|
+
async requestRaw(method, url, body) {
|
|
60
|
+
const headers = {
|
|
61
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
62
|
+
};
|
|
63
|
+
return this.executeWithRetry(method, url, headers, body);
|
|
64
|
+
}
|
|
65
|
+
async executeWithRetry(method, url, headers, body) {
|
|
66
|
+
let lastError;
|
|
67
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
68
|
+
try {
|
|
69
|
+
const controller = new AbortController();
|
|
70
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
71
|
+
const response = await fetch(url, {
|
|
72
|
+
method,
|
|
73
|
+
headers,
|
|
74
|
+
body,
|
|
75
|
+
signal: controller.signal,
|
|
76
|
+
});
|
|
77
|
+
clearTimeout(timeoutId);
|
|
78
|
+
if (response.ok) {
|
|
79
|
+
// Handle CSV/text responses
|
|
80
|
+
const contentType = response.headers.get("Content-Type") || "";
|
|
81
|
+
if (contentType.includes("text/csv")) {
|
|
82
|
+
return (await response.text());
|
|
83
|
+
}
|
|
84
|
+
return (await response.json());
|
|
85
|
+
}
|
|
86
|
+
// Parse error response
|
|
87
|
+
const errorBody = (await response.json().catch(() => ({
|
|
88
|
+
error: { type: "api_error", code: "internal_error", message: "Unknown error" },
|
|
89
|
+
})));
|
|
90
|
+
const error = parseApiError(response.status, errorBody, response.headers);
|
|
91
|
+
// Don't retry 4xx errors (except 429 rate limits)
|
|
92
|
+
if (response.status < 500 && response.status !== 429) {
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
// For 429, wait the specified retry-after time
|
|
96
|
+
if (response.status === 429) {
|
|
97
|
+
const retryAfter = parseInt(response.headers.get("Retry-After") || "1", 10);
|
|
98
|
+
await this.sleep(retryAfter * 1000);
|
|
99
|
+
lastError = error;
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
// For 5xx, retry with exponential backoff
|
|
103
|
+
lastError = error;
|
|
104
|
+
if (attempt < this.maxRetries) {
|
|
105
|
+
await this.sleep(Math.pow(2, attempt) * 1000);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
110
|
+
lastError = new Error(`Request timed out after ${this.timeout}ms`);
|
|
111
|
+
}
|
|
112
|
+
else if (err instanceof Error && "type" in err) {
|
|
113
|
+
// Already a parsed ApiError, re-throw
|
|
114
|
+
throw err;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
118
|
+
}
|
|
119
|
+
if (attempt < this.maxRetries) {
|
|
120
|
+
await this.sleep(Math.pow(2, attempt) * 1000);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
throw lastError || new Error("Request failed after retries");
|
|
125
|
+
}
|
|
126
|
+
sleep(ms) {
|
|
127
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Static HTTP client for unauthenticated requests (quick-pay).
|
|
132
|
+
*/
|
|
133
|
+
export class StaticHttpClient {
|
|
134
|
+
static async post(baseUrl, path, body) {
|
|
135
|
+
const url = `${baseUrl.replace(/\/$/, "")}${path}`;
|
|
136
|
+
const controller = new AbortController();
|
|
137
|
+
const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT);
|
|
138
|
+
const response = await fetch(url, {
|
|
139
|
+
method: "POST",
|
|
140
|
+
headers: { "Content-Type": "application/json" },
|
|
141
|
+
body: JSON.stringify(body),
|
|
142
|
+
signal: controller.signal,
|
|
143
|
+
});
|
|
144
|
+
clearTimeout(timeoutId);
|
|
145
|
+
if (response.ok) {
|
|
146
|
+
return (await response.json());
|
|
147
|
+
}
|
|
148
|
+
const errorBody = (await response.json().catch(() => ({
|
|
149
|
+
error: { type: "api_error", code: "internal_error", message: "Unknown error" },
|
|
150
|
+
})));
|
|
151
|
+
throw parseApiError(response.status, errorBody, response.headers);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed error classes for the AnySpend Platform API client.
|
|
3
|
+
*/
|
|
4
|
+
export interface ApiErrorResponse {
|
|
5
|
+
error: {
|
|
6
|
+
type: string;
|
|
7
|
+
code: string;
|
|
8
|
+
message: string;
|
|
9
|
+
param?: string;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export declare class ApiError extends Error {
|
|
13
|
+
readonly type: string;
|
|
14
|
+
readonly code: string;
|
|
15
|
+
readonly status: number;
|
|
16
|
+
readonly param?: string;
|
|
17
|
+
constructor(status: number, body: ApiErrorResponse);
|
|
18
|
+
}
|
|
19
|
+
export declare class AuthenticationError extends ApiError {
|
|
20
|
+
constructor(status: number, body: ApiErrorResponse);
|
|
21
|
+
}
|
|
22
|
+
export declare class PermissionError extends ApiError {
|
|
23
|
+
constructor(status: number, body: ApiErrorResponse);
|
|
24
|
+
}
|
|
25
|
+
export declare class RateLimitError extends ApiError {
|
|
26
|
+
readonly retryAfter: number;
|
|
27
|
+
constructor(status: number, body: ApiErrorResponse, retryAfter: number);
|
|
28
|
+
}
|
|
29
|
+
export declare class NotFoundError extends ApiError {
|
|
30
|
+
constructor(status: number, body: ApiErrorResponse);
|
|
31
|
+
}
|
|
32
|
+
export declare class IdempotencyError extends ApiError {
|
|
33
|
+
constructor(status: number, body: ApiErrorResponse);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Parse an API error response into the appropriate typed error class.
|
|
37
|
+
*/
|
|
38
|
+
export declare function parseApiError(status: number, body: ApiErrorResponse, headers?: Headers): ApiError;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed error classes for the AnySpend Platform API client.
|
|
3
|
+
*/
|
|
4
|
+
export class ApiError extends Error {
|
|
5
|
+
constructor(status, body) {
|
|
6
|
+
super(body.error.message);
|
|
7
|
+
this.name = "ApiError";
|
|
8
|
+
this.type = body.error.type;
|
|
9
|
+
this.code = body.error.code;
|
|
10
|
+
this.status = status;
|
|
11
|
+
this.param = body.error.param;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class AuthenticationError extends ApiError {
|
|
15
|
+
constructor(status, body) {
|
|
16
|
+
super(status, body);
|
|
17
|
+
this.name = "AuthenticationError";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class PermissionError extends ApiError {
|
|
21
|
+
constructor(status, body) {
|
|
22
|
+
super(status, body);
|
|
23
|
+
this.name = "PermissionError";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export class RateLimitError extends ApiError {
|
|
27
|
+
constructor(status, body, retryAfter) {
|
|
28
|
+
super(status, body);
|
|
29
|
+
this.name = "RateLimitError";
|
|
30
|
+
this.retryAfter = retryAfter;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export class NotFoundError extends ApiError {
|
|
34
|
+
constructor(status, body) {
|
|
35
|
+
super(status, body);
|
|
36
|
+
this.name = "NotFoundError";
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export class IdempotencyError extends ApiError {
|
|
40
|
+
constructor(status, body) {
|
|
41
|
+
super(status, body);
|
|
42
|
+
this.name = "IdempotencyError";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Parse an API error response into the appropriate typed error class.
|
|
47
|
+
*/
|
|
48
|
+
export function parseApiError(status, body, headers) {
|
|
49
|
+
const type = body.error?.type;
|
|
50
|
+
if (status === 401 || type === "authentication_error") {
|
|
51
|
+
return new AuthenticationError(status, body);
|
|
52
|
+
}
|
|
53
|
+
if (status === 403 || type === "permission_error") {
|
|
54
|
+
return new PermissionError(status, body);
|
|
55
|
+
}
|
|
56
|
+
if (status === 429 || type === "rate_limit_error") {
|
|
57
|
+
const retryAfter = parseInt(headers?.get("Retry-After") || "60", 10);
|
|
58
|
+
return new RateLimitError(status, body, retryAfter);
|
|
59
|
+
}
|
|
60
|
+
if (status === 404 || type === "not_found_error") {
|
|
61
|
+
return new NotFoundError(status, body);
|
|
62
|
+
}
|
|
63
|
+
if (type === "idempotency_error") {
|
|
64
|
+
return new IdempotencyError(status, body);
|
|
65
|
+
}
|
|
66
|
+
return new ApiError(status, body);
|
|
67
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AnySpend Platform API Client
|
|
3
|
+
*
|
|
4
|
+
* A headless TypeScript client for the AnySpend Platform REST API.
|
|
5
|
+
* Works in any runtime with `fetch` (Node.js, browsers, Cloudflare Workers, Deno, Bun).
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { AnySpendPlatformClient } from '../../anyspend/platform';
|
|
10
|
+
*
|
|
11
|
+
* const platform = new AnySpendPlatformClient('asp_your_api_key_here');
|
|
12
|
+
*
|
|
13
|
+
* // Create a payment link
|
|
14
|
+
* const link = await platform.paymentLinks.create({
|
|
15
|
+
* name: 'Summer Sale',
|
|
16
|
+
* amount: '10000000',
|
|
17
|
+
* token_address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
|
18
|
+
* chain_id: 8453,
|
|
19
|
+
* recipient_address: '0x...',
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // Quick pay (no API key needed)
|
|
23
|
+
* const quickLink = await AnySpendPlatformClient.quickPay({
|
|
24
|
+
* recipient_address: '0x...',
|
|
25
|
+
* amount: '5000000',
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
import { type ClientConfig } from "./client";
|
|
30
|
+
import { PaymentLinksResource } from "./resources/payment-links";
|
|
31
|
+
import { ProductsResource } from "./resources/products";
|
|
32
|
+
import { CustomersResource } from "./resources/customers";
|
|
33
|
+
import { TransactionsResource } from "./resources/transactions";
|
|
34
|
+
import { CheckoutSessionsResource } from "./resources/checkout-sessions";
|
|
35
|
+
import { WebhooksResource } from "./resources/webhooks";
|
|
36
|
+
import { DiscountCodesResource } from "./resources/discount-codes";
|
|
37
|
+
import { NotificationsResource } from "./resources/notifications";
|
|
38
|
+
import { WidgetsResource } from "./resources/widgets";
|
|
39
|
+
import { OrganizationResource } from "./resources/organization";
|
|
40
|
+
import { AnalyticsResource } from "./resources/analytics";
|
|
41
|
+
import { EventsResource } from "./resources/events";
|
|
42
|
+
import type { QuickPayParams, PaymentLink } from "./types";
|
|
43
|
+
export declare class AnySpendPlatformClient {
|
|
44
|
+
private client;
|
|
45
|
+
/** Payment Links - Create, manage, and track payment links */
|
|
46
|
+
readonly paymentLinks: PaymentLinksResource;
|
|
47
|
+
/** Products - Manage your product catalog */
|
|
48
|
+
readonly products: ProductsResource;
|
|
49
|
+
/** Customers - Manage customer records */
|
|
50
|
+
readonly customers: CustomersResource;
|
|
51
|
+
/** Transactions - View transaction history and stats */
|
|
52
|
+
readonly transactions: TransactionsResource;
|
|
53
|
+
/** Checkout Sessions - Server-side checkout management */
|
|
54
|
+
readonly checkoutSessions: CheckoutSessionsResource;
|
|
55
|
+
/** Webhooks - Configure webhook endpoints */
|
|
56
|
+
readonly webhooks: WebhooksResource;
|
|
57
|
+
/** Discount Codes - Create and validate discounts */
|
|
58
|
+
readonly discountCodes: DiscountCodesResource;
|
|
59
|
+
/** Notifications - Email and Telegram settings */
|
|
60
|
+
readonly notifications: NotificationsResource;
|
|
61
|
+
/** Widgets - Embeddable widget configurations */
|
|
62
|
+
readonly widgets: WidgetsResource;
|
|
63
|
+
/** Organization - Org settings and defaults */
|
|
64
|
+
readonly organization: OrganizationResource;
|
|
65
|
+
/** Analytics - Revenue and conversion analytics */
|
|
66
|
+
readonly analytics: AnalyticsResource;
|
|
67
|
+
/** Events - API audit trail */
|
|
68
|
+
readonly events: EventsResource;
|
|
69
|
+
/**
|
|
70
|
+
* Create a new AnySpend Platform API client.
|
|
71
|
+
*
|
|
72
|
+
* @param apiKey - Your API key (starts with `asp_`)
|
|
73
|
+
* @param config - Optional configuration
|
|
74
|
+
*/
|
|
75
|
+
constructor(apiKey: string, config?: ClientConfig);
|
|
76
|
+
/**
|
|
77
|
+
* Create a quick payment link without authentication.
|
|
78
|
+
* Rate limited to 5 requests per minute per IP.
|
|
79
|
+
*
|
|
80
|
+
* @param params - Quick pay parameters
|
|
81
|
+
* @param baseUrl - Optional API base URL (defaults to production)
|
|
82
|
+
*/
|
|
83
|
+
static quickPay(params: QuickPayParams, baseUrl?: string): Promise<PaymentLink>;
|
|
84
|
+
}
|
|
85
|
+
export type { ClientConfig } from "./client";
|
|
86
|
+
export { ApiError, AuthenticationError, PermissionError, RateLimitError, NotFoundError, IdempotencyError, } from "./errors";
|
|
87
|
+
export type * from "./types";
|