@bounded-sh/client 0.0.59 → 0.0.60
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/{email-auth-provider-N-dfsNnE.js → email-auth-provider-B5yIZe1l.js} +2 -2
- package/dist/{email-auth-provider-N-dfsNnE.js.map → email-auth-provider-B5yIZe1l.js.map} +1 -1
- package/dist/{email-auth-provider-BSw9FRjg.js → email-auth-provider-BCEdcnRu.js} +2 -2
- package/dist/{email-auth-provider-BSw9FRjg.js.map → email-auth-provider-BCEdcnRu.js.map} +1 -1
- package/dist/{email-auth-provider-deB_ADc5.mjs → email-auth-provider-BF-vvbAt.mjs} +2 -2
- package/dist/{email-auth-provider-deB_ADc5.mjs.map → email-auth-provider-BF-vvbAt.mjs.map} +1 -1
- package/dist/{email-auth-provider-DhAMOILG.mjs → email-auth-provider-nBv7mW9q.mjs} +2 -2
- package/dist/{email-auth-provider-DhAMOILG.mjs.map → email-auth-provider-nBv7mW9q.mjs.map} +1 -1
- package/dist/{guest-auth-provider-BFodq9Rc.js → guest-auth-provider-CZ-CpNhD.js} +2 -2
- package/dist/{guest-auth-provider-BFodq9Rc.js.map → guest-auth-provider-CZ-CpNhD.js.map} +1 -1
- package/dist/{guest-auth-provider-Czl48mOP.js → guest-auth-provider-CrRreOyf.js} +2 -2
- package/dist/{guest-auth-provider-Czl48mOP.js.map → guest-auth-provider-CrRreOyf.js.map} +1 -1
- package/dist/{guest-auth-provider-D9wbogwi.mjs → guest-auth-provider-DFNAHmtY.mjs} +2 -2
- package/dist/{guest-auth-provider-B78Ugfar.mjs.map → guest-auth-provider-DFNAHmtY.mjs.map} +1 -1
- package/dist/{guest-auth-provider-B78Ugfar.mjs → guest-auth-provider-DGvQgIwm.mjs} +2 -2
- package/dist/{guest-auth-provider-D9wbogwi.mjs.map → guest-auth-provider-DGvQgIwm.mjs.map} +1 -1
- package/dist/{index-SHt4VZZV.mjs → index-CQtGkKVd.mjs} +151 -43
- package/dist/index-CQtGkKVd.mjs.map +1 -0
- package/dist/{index-uu8hKP-p.js → index-iu8vB4ye.js} +152 -42
- package/dist/index-iu8vB4ye.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{index.native-D48QQ0-q.js → index.native-CDfx0N6p.js} +151 -41
- package/dist/index.native-CDfx0N6p.js.map +1 -0
- package/dist/{index.native-D-8IAEy-.mjs → index.native-Crfn_NOB.mjs} +150 -42
- package/dist/index.native-Crfn_NOB.mjs.map +1 -0
- package/dist/index.native.d.ts +2 -2
- package/dist/index.native.js +3 -1
- package/dist/index.native.js.map +1 -1
- package/dist/index.native.mjs +1 -1
- package/dist/{injected-evm-wallet-provider-CJsLX16m.mjs → injected-evm-wallet-provider-Bi9G3X35.mjs} +2 -2
- package/dist/{injected-evm-wallet-provider-CJsLX16m.mjs.map → injected-evm-wallet-provider-Bi9G3X35.mjs.map} +1 -1
- package/dist/{injected-evm-wallet-provider-HQMOL_mZ.js → injected-evm-wallet-provider-CGa692L1.js} +2 -2
- package/dist/{injected-evm-wallet-provider-HQMOL_mZ.js.map → injected-evm-wallet-provider-CGa692L1.js.map} +1 -1
- package/dist/{injected-evm-wallet-provider-UWvcy-LO.mjs → injected-evm-wallet-provider-D8lYGcM2.mjs} +2 -2
- package/dist/{injected-evm-wallet-provider-UWvcy-LO.mjs.map → injected-evm-wallet-provider-D8lYGcM2.mjs.map} +1 -1
- package/dist/{injected-evm-wallet-provider-CItxws1D.js → injected-evm-wallet-provider-LTWiACl5.js} +2 -2
- package/dist/{injected-evm-wallet-provider-CItxws1D.js.map → injected-evm-wallet-provider-LTWiACl5.js.map} +1 -1
- package/dist/{injected-wallet-provider-CNYAynIB.mjs → injected-wallet-provider-CcyA5JBS.mjs} +2 -2
- package/dist/{injected-wallet-provider-CNYAynIB.mjs.map → injected-wallet-provider-CcyA5JBS.mjs.map} +1 -1
- package/dist/{injected-wallet-provider-CVeZgfEt.js → injected-wallet-provider-DYZFxIdd.js} +2 -2
- package/dist/{injected-wallet-provider-CVeZgfEt.js.map → injected-wallet-provider-DYZFxIdd.js.map} +1 -1
- package/dist/{injected-wallet-provider-CmXqreEE.js → injected-wallet-provider-TPx8Wzvq.js} +2 -2
- package/dist/{injected-wallet-provider-CmXqreEE.js.map → injected-wallet-provider-TPx8Wzvq.js.map} +1 -1
- package/dist/{injected-wallet-provider-BihII94U.mjs → injected-wallet-provider-kx8tcMKM.mjs} +2 -2
- package/dist/{injected-wallet-provider-BihII94U.mjs.map → injected-wallet-provider-kx8tcMKM.mjs.map} +1 -1
- package/dist/onramp.d.ts +51 -9
- package/package.json +2 -2
- package/dist/index-SHt4VZZV.mjs.map +0 -1
- package/dist/index-uu8hKP-p.js.map +0 -1
- package/dist/index.native-D-8IAEy-.mjs.map +0 -1
- package/dist/index.native-D48QQ0-q.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -30,8 +30,8 @@ export type { TurnkeySignResult, TurnkeyWallet } from "./auth/turnkey-signer-bri
|
|
|
30
30
|
export { startTurnkeyEmailLogin } from "./auth/turnkey-auth";
|
|
31
31
|
export type { TurnkeyEmailLoginHandle } from "./auth/turnkey-auth";
|
|
32
32
|
export { getIdToken } from "./utils";
|
|
33
|
-
export { onramp } from "./onramp";
|
|
34
|
-
export type { OnrampOptions, OnrampResult } from "./onramp";
|
|
33
|
+
export { onramp, onrampQuote, onrampStatus } from "./onramp";
|
|
34
|
+
export type { OnrampOptions, OnrampResult, OnrampQuoteInfo, OnrampTransaction } from "./onramp";
|
|
35
35
|
export { setPlatform, getPlatform } from "./platform";
|
|
36
36
|
export type { PlatformAdapter, StorageAdapter } from "./platform";
|
|
37
37
|
export { OffchainAuthProvider, OffchainAuthProviderConfig, } from "./auth/providers/offchain-auth-provider";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-iu8vB4ye.js');
|
|
4
4
|
var core = require('@bounded-sh/core');
|
|
5
5
|
require('react');
|
|
6
6
|
|
|
@@ -40,6 +40,8 @@ exports.logout = index.logout;
|
|
|
40
40
|
exports.onAuthLoadingChanged = index.onAuthLoadingChanged;
|
|
41
41
|
exports.onAuthStateChanged = index.onAuthStateChanged;
|
|
42
42
|
exports.onramp = index.onramp;
|
|
43
|
+
exports.onrampQuote = index.onrampQuote;
|
|
44
|
+
exports.onrampStatus = index.onrampStatus;
|
|
43
45
|
exports.openBoundedWidget = index.openBoundedWidget;
|
|
44
46
|
exports.requestEip6963Providers = index.requestEip6963Providers;
|
|
45
47
|
exports.setPlatform = index.setPlatform;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { a2 as BUILD_DELEGATED_REVIEW_CAPABILITY_SCHEMA, a1 as BUILD_REVIEW_CAPABILITY_REFRESH_SCHEMA, a0 as BUILD_REVIEW_CAPABILITY_SCHEMA, W as BuildsApiError, $ as FAILURE_REASONS, X as NON_TERMINAL_STATES, S as OffchainAuthProvider, _ as PARK_REASONS, T as PrivyExpoProvider, Z as RUN_STATES, Y as TERMINAL_STATES, I as apps, V as builds, A as completeLoginFromRedirect, C as completeLoginInPopup, k as defaultInjectedEvmProvider, d as defaultInjectedProvider, J as deserializeTransaction, q as getAuthLoading, v as getAuthProvider, m as getCurrentUser, N as getIdToken, L as getOrCreateTurnkeyWallet, g as getPlatform, l as init, t as login, B as loginWithPopup, x as loginWithPrivy, z as loginWithRedirect, y as loginWithWallet, u as logout, p as onAuthLoadingChanged, o as onAuthStateChanged, O as onramp, P as onrampQuote, Q as onrampStatus, D as openBoundedWidget, U as requestEip6963Providers, R as setPlatform, w as signInAnonymously, K as signSolanaMessageViaTurnkey, M as startTurnkeyEmailLogin, F as useAuth, H as useBuildRun, G as useQuery } from './index-CQtGkKVd.mjs';
|
|
2
2
|
export * from '@bounded-sh/core';
|
|
3
3
|
export { BoundedDeclineError, DECLINE_EVENT_NAME, RATE_LIMIT_EVENT_NAME, ScopedClientReadOnlyError, aggregate, count, createClient, deriveDecline, dispatchDeclineEvent, dispatchRateLimitEvent, docId, get, getConfig, getFiles, getMany, queryAggregate, runExpression, runExpressionMany, runQuery, runQueryMany, search, set, setFile, setMany, signAndSubmitTransaction, signMessage, signTransaction, subscribe } from '@bounded-sh/core';
|
|
4
4
|
import 'react';
|
|
@@ -4474,7 +4474,7 @@ async function getAuthProvider(config) {
|
|
|
4474
4474
|
// manager as legacy email sessions. Human login should be started
|
|
4475
4475
|
// with loginWithRedirect(); this provider is kept as the restore and
|
|
4476
4476
|
// logout surface for those sessions.
|
|
4477
|
-
currentAuthProvider = new (await Promise.resolve().then(function () { return require('./email-auth-provider-
|
|
4477
|
+
currentAuthProvider = new (await Promise.resolve().then(function () { return require('./email-auth-provider-BCEdcnRu.js'); })).EmailAuthProvider();
|
|
4478
4478
|
break;
|
|
4479
4479
|
case "wallet":
|
|
4480
4480
|
case "phantom": {
|
|
@@ -4493,7 +4493,7 @@ async function getAuthProvider(config) {
|
|
|
4493
4493
|
if (!isWalletLoginEnabled(config)) {
|
|
4494
4494
|
throw walletLoginNotEnabledError(authMethod);
|
|
4495
4495
|
}
|
|
4496
|
-
const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-
|
|
4496
|
+
const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-TPx8Wzvq.js'); });
|
|
4497
4497
|
currentAuthProvider = new InjectedWalletProvider(resolveInjectedWalletConfig(config), rpcUrl, configuredNetwork);
|
|
4498
4498
|
break;
|
|
4499
4499
|
}
|
|
@@ -4506,7 +4506,7 @@ async function getAuthProvider(config) {
|
|
|
4506
4506
|
// Selecting authMethod:'evm-wallet' IS the opt-in — pass evmWalletConfig
|
|
4507
4507
|
// to point at a specific wallet or set chainId/domain.
|
|
4508
4508
|
const evmWalletConfig = ((_a = config.evmWalletConfig) !== null && _a !== void 0 ? _a : {});
|
|
4509
|
-
const { InjectedEvmWalletProvider } = await Promise.resolve().then(function () { return require('./injected-evm-wallet-provider-
|
|
4509
|
+
const { InjectedEvmWalletProvider } = await Promise.resolve().then(function () { return require('./injected-evm-wallet-provider-CGa692L1.js'); });
|
|
4510
4510
|
currentAuthProvider = new InjectedEvmWalletProvider(evmWalletConfig);
|
|
4511
4511
|
break;
|
|
4512
4512
|
}
|
|
@@ -4534,7 +4534,7 @@ async function getAuthProvider(config) {
|
|
|
4534
4534
|
break;
|
|
4535
4535
|
case "guest":
|
|
4536
4536
|
// Anonymous auth: a device-local ed25519 keypair signs the challenge.
|
|
4537
|
-
currentAuthProvider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-
|
|
4537
|
+
currentAuthProvider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-CrRreOyf.js'); })).GuestAuthProvider();
|
|
4538
4538
|
break;
|
|
4539
4539
|
}
|
|
4540
4540
|
if (!currentAuthProvider) {
|
|
@@ -4590,7 +4590,7 @@ async function signInAnonymously() {
|
|
|
4590
4590
|
// Lazy-load the guest provider so its ed25519/web3 dependencies stay out of
|
|
4591
4591
|
// the main bundle for data-only apps. Specifier is a static string literal
|
|
4592
4592
|
// so bundle-splitting can see it.
|
|
4593
|
-
const provider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-
|
|
4593
|
+
const provider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-CrRreOyf.js'); })).GuestAuthProvider();
|
|
4594
4594
|
setAuthLoading(true); // reflect "signing in…" while the guest keypair session is minted
|
|
4595
4595
|
const commit = (user) => {
|
|
4596
4596
|
// No await/interleaving inside this block: provider/method/config/marker
|
|
@@ -4775,7 +4775,7 @@ function getCurrentAuthMethod() {
|
|
|
4775
4775
|
// allowlist here: on a trusted origin we end the issuer session with a
|
|
4776
4776
|
// top-level bounce; anywhere else (custom domains, http dev) we keep the
|
|
4777
4777
|
// local-only logout instead of stranding the user on the issuer origin.
|
|
4778
|
-
function issuerLogoutBounceUrl(issuerBase) {
|
|
4778
|
+
function issuerLogoutBounceUrl(issuerBase, idTokenHint) {
|
|
4779
4779
|
if (typeof window === 'undefined' || typeof document === 'undefined')
|
|
4780
4780
|
return null; // RN/Node: no shared cookie jar to clear this way
|
|
4781
4781
|
try {
|
|
@@ -4798,12 +4798,27 @@ function issuerLogoutBounceUrl(issuerBase) {
|
|
|
4798
4798
|
if (!trusted)
|
|
4799
4799
|
return null;
|
|
4800
4800
|
const base = issuerBase.replace(/\/$/, '');
|
|
4801
|
-
|
|
4801
|
+
// #228: send the id_token_hint so the issuer can bind the post-logout redirect to this
|
|
4802
|
+
// session + app + registered origin. Without it the issuer safely falls back to its own
|
|
4803
|
+
// origin (it no longer trusts a bare suffix match), so the return-to-app bounce is a no-op.
|
|
4804
|
+
const hint = idTokenHint ? `&id_token_hint=${encodeURIComponent(idTokenHint)}` : '';
|
|
4805
|
+
return `${base}/logout?redirect_uri=${encodeURIComponent(here.href)}${hint}`;
|
|
4802
4806
|
}
|
|
4803
4807
|
catch (_b) {
|
|
4804
4808
|
return null;
|
|
4805
4809
|
}
|
|
4806
4810
|
}
|
|
4811
|
+
// #228 helper, deliberately OUTSIDE logout(): the logout body is source-guarded
|
|
4812
|
+
// against any `catch` so a revokeSession failure can never be swallowed, and a
|
|
4813
|
+
// missing id token is the one benign absence worth tolerating here.
|
|
4814
|
+
function idTokenHintOrNull(sm) {
|
|
4815
|
+
try {
|
|
4816
|
+
return sm.getIdToken();
|
|
4817
|
+
}
|
|
4818
|
+
catch (_a) {
|
|
4819
|
+
return null; /* no id token to hint with */
|
|
4820
|
+
}
|
|
4821
|
+
}
|
|
4807
4822
|
async function logout$1(options) {
|
|
4808
4823
|
// Re-initialize the provider if it was cleared by a prior logout — the exact mirror
|
|
4809
4824
|
// of login()'s self-heal above. A hosted popup/redirect login (loginWithPopup /
|
|
@@ -4828,6 +4843,9 @@ async function logout$1(options) {
|
|
|
4828
4843
|
const sm = core.getActiveSessionManager();
|
|
4829
4844
|
const refreshToken = sm.getRefreshToken();
|
|
4830
4845
|
const sessionIssuer = sm.getIssuer();
|
|
4846
|
+
// #228: capture the id token NOW, before currentAuthProvider.logout() clears the session, so we
|
|
4847
|
+
// can hand it to the issuer /logout as an id_token_hint (which binds the post-logout redirect).
|
|
4848
|
+
const idTokenHint = idTokenHintOrNull(sm);
|
|
4831
4849
|
if (refreshToken)
|
|
4832
4850
|
await core.revokeSession(refreshToken, sessionIssuer !== null && sessionIssuer !== void 0 ? sessionIssuer : undefined);
|
|
4833
4851
|
// Hosted sessions ('email' covers the whole hosted surface: email OTP +
|
|
@@ -4848,7 +4866,7 @@ async function logout$1(options) {
|
|
|
4848
4866
|
const issuerBase = sessionIssuer
|
|
4849
4867
|
|| (await core.getConfig()).humanAuthApiUrl
|
|
4850
4868
|
|| 'https://auth.bounded.sh';
|
|
4851
|
-
const bounce = issuerLogoutBounceUrl(issuerBase);
|
|
4869
|
+
const bounce = issuerLogoutBounceUrl(issuerBase, idTokenHint);
|
|
4852
4870
|
// Local state is already cleared, so even if the navigation is stopped
|
|
4853
4871
|
// (tab close, extension) the app-side logout has fully happened.
|
|
4854
4872
|
if (bounce)
|
|
@@ -5831,30 +5849,117 @@ async function deserializeTransaction(tx) {
|
|
|
5831
5849
|
// session is bound server-side to the caller's verified Bounded JWT, and the
|
|
5832
5850
|
// destination defaults to that user's embedded wallet.
|
|
5833
5851
|
//
|
|
5852
|
+
// Amount semantics:
|
|
5853
|
+
// amountUsd - exact fiat in; the fee/output breakdown comes back as `quote`.
|
|
5854
|
+
// minAmountOut - a FLOOR on crypto received. The platform quotes Coinbase's
|
|
5855
|
+
// worst-fee payment method (card) and pads by `slippagePad` (default 1%),
|
|
5856
|
+
// so cheaper methods overshoot the floor rather than undershooting it. The
|
|
5857
|
+
// floor holds unless the market moves more than the pad while the user sits
|
|
5858
|
+
// on the checkout screen - which is why completion is VERIFIED: after the
|
|
5859
|
+
// popup closes we poll the platform's status leg and resolve with the
|
|
5860
|
+
// actual filled amount when Coinbase reports it.
|
|
5861
|
+
//
|
|
5834
5862
|
// Works on Bounded-served origins (<app>.bounded.page / custom domains). On a
|
|
5835
5863
|
// local dev origin the session endpoint does not exist; we fail with a clear
|
|
5836
5864
|
// error rather than guessing a host.
|
|
5837
5865
|
function hasDOM() {
|
|
5838
5866
|
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
5839
5867
|
}
|
|
5868
|
+
async function authedFetch(path, init) {
|
|
5869
|
+
const idToken = await getIdToken();
|
|
5870
|
+
if (!idToken)
|
|
5871
|
+
throw new Error('onramp: no active session - call login() first');
|
|
5872
|
+
return fetch(`${window.location.origin}${path}`, Object.assign(Object.assign({}, init), { headers: Object.assign(Object.assign({}, init === null || init === void 0 ? void 0 : init.headers), { Authorization: `Bearer ${idToken}` }) }));
|
|
5873
|
+
}
|
|
5874
|
+
async function readError(res) {
|
|
5875
|
+
var _a;
|
|
5876
|
+
try {
|
|
5877
|
+
return (_a = (await res.json()).error) !== null && _a !== void 0 ? _a : '';
|
|
5878
|
+
}
|
|
5879
|
+
catch (_b) {
|
|
5880
|
+
return '';
|
|
5881
|
+
}
|
|
5882
|
+
}
|
|
5883
|
+
function sessionBody(options, extra) {
|
|
5884
|
+
return JSON.stringify(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (options.asset ? { asset: options.asset } : {})), (options.address ? { address: options.address } : {})), (options.amountUsd !== undefined ? { amountUsd: options.amountUsd } : {})), (options.minAmountOut !== undefined ? { minAmountOut: options.minAmountOut } : {})), (options.slippagePad !== undefined ? { slippagePad: options.slippagePad } : {})), extra));
|
|
5885
|
+
}
|
|
5886
|
+
function resolveAddress(options) {
|
|
5887
|
+
var _a, _b;
|
|
5888
|
+
const user = getCurrentUser();
|
|
5889
|
+
const address = (_b = (_a = options.address) !== null && _a !== void 0 ? _a : user === null || user === void 0 ? void 0 : user.address) !== null && _b !== void 0 ? _b : undefined;
|
|
5890
|
+
if (!address) {
|
|
5891
|
+
throw new Error(user
|
|
5892
|
+
? 'onramp: the signed-in account has no wallet address - pass { address } explicitly'
|
|
5893
|
+
: 'onramp: no signed-in user - call login() first or pass { address }');
|
|
5894
|
+
}
|
|
5895
|
+
return address;
|
|
5896
|
+
}
|
|
5897
|
+
/**
|
|
5898
|
+
* Preview a quote (fees + exact/floor output) WITHOUT opening any window or
|
|
5899
|
+
* consuming a session. Show this to the user, then call onramp() to check out.
|
|
5900
|
+
*/
|
|
5901
|
+
async function onrampQuote(options = {}) {
|
|
5902
|
+
if (!hasDOM())
|
|
5903
|
+
throw new Error('onrampQuote is web-only');
|
|
5904
|
+
resolveAddress(options);
|
|
5905
|
+
const res = await authedFetch('/__bounded/onramp/session', {
|
|
5906
|
+
method: 'POST',
|
|
5907
|
+
headers: { 'content-type': 'application/json' },
|
|
5908
|
+
body: sessionBody(options, { quoteOnly: true }),
|
|
5909
|
+
});
|
|
5910
|
+
if (!res.ok)
|
|
5911
|
+
throw new Error(`onrampQuote: failed (${res.status}${await readError(res).then((e) => (e ? `: ${e}` : ''))})`);
|
|
5912
|
+
return (await res.json());
|
|
5913
|
+
}
|
|
5914
|
+
/** The signed-in user's recent onramp transactions (newest first). */
|
|
5915
|
+
async function onrampStatus(sinceMs) {
|
|
5916
|
+
if (!hasDOM())
|
|
5917
|
+
throw new Error('onrampStatus is web-only');
|
|
5918
|
+
const res = await authedFetch(`/__bounded/onramp/status${sinceMs ? `?since=${Math.floor(sinceMs)}` : ''}`);
|
|
5919
|
+
if (!res.ok)
|
|
5920
|
+
throw new Error(`onrampStatus: failed (${res.status})`);
|
|
5921
|
+
return (await res.json()).transactions;
|
|
5922
|
+
}
|
|
5923
|
+
function isSuccess(t) {
|
|
5924
|
+
return /SUCCESS|COMPLETED/i.test(t.status);
|
|
5925
|
+
}
|
|
5926
|
+
function isPending(t) {
|
|
5927
|
+
return /PROGRESS|PENDING|CREATED/i.test(t.status);
|
|
5928
|
+
}
|
|
5929
|
+
async function verifyCompletion(openedAt, asset, timeoutMs) {
|
|
5930
|
+
const deadline = Date.now() + timeoutMs;
|
|
5931
|
+
// 60s of clock-skew slack on `since`: Coinbase stamps server-side.
|
|
5932
|
+
const since = openedAt - 60000;
|
|
5933
|
+
for (;;) {
|
|
5934
|
+
let sawPending = false;
|
|
5935
|
+
try {
|
|
5936
|
+
const txs = await onrampStatus(since);
|
|
5937
|
+
const done = txs.find((t) => isSuccess(t) && (t.asset === null || t.asset === asset));
|
|
5938
|
+
if (done)
|
|
5939
|
+
return done;
|
|
5940
|
+
sawPending = txs.some(isPending);
|
|
5941
|
+
}
|
|
5942
|
+
catch ( /* transient - keep polling until the deadline */_a) { /* transient - keep polling until the deadline */ }
|
|
5943
|
+
// No completed fill and nothing in flight: one grace poll cycle still
|
|
5944
|
+
// runs (Coinbase's record can lag the redirect), but don't burn the
|
|
5945
|
+
// full window when the user plainly abandoned checkout.
|
|
5946
|
+
if (Date.now() >= deadline)
|
|
5947
|
+
return null;
|
|
5948
|
+
if (!sawPending && Date.now() >= openedAt + 12000 && Date.now() - openedAt > timeoutMs / 2)
|
|
5949
|
+
return null;
|
|
5950
|
+
await new Promise((r) => setTimeout(r, 3000));
|
|
5951
|
+
}
|
|
5952
|
+
}
|
|
5840
5953
|
/**
|
|
5841
|
-
* Open Coinbase Onramp for the signed-in user. Resolves
|
|
5954
|
+
* Open Coinbase Onramp for the signed-in user. Resolves after the window
|
|
5955
|
+
* closes, with completion VERIFIED against Coinbase when possible.
|
|
5842
5956
|
* Call from a click handler - popup blockers require user activation.
|
|
5843
5957
|
*/
|
|
5844
5958
|
async function onramp(options = {}) {
|
|
5845
|
-
var _a
|
|
5959
|
+
var _a;
|
|
5846
5960
|
if (!hasDOM())
|
|
5847
5961
|
throw new Error('onramp() is web-only');
|
|
5848
|
-
|
|
5849
|
-
const address = (_b = (_a = options.address) !== null && _a !== void 0 ? _a : user === null || user === void 0 ? void 0 : user.address) !== null && _b !== void 0 ? _b : undefined;
|
|
5850
|
-
if (!address) {
|
|
5851
|
-
throw new Error(user
|
|
5852
|
-
? 'onramp(): the signed-in account has no wallet address - pass { address } explicitly'
|
|
5853
|
-
: 'onramp(): no signed-in user - call login() first or pass { address }');
|
|
5854
|
-
}
|
|
5855
|
-
const idToken = await getIdToken();
|
|
5856
|
-
if (!idToken)
|
|
5857
|
-
throw new Error('onramp(): no active session - call login() first');
|
|
5962
|
+
resolveAddress(options);
|
|
5858
5963
|
// Open the window synchronously so the click's user-activation window is not
|
|
5859
5964
|
// consumed by the fetch below (same hard-won pattern as loginWithPopup).
|
|
5860
5965
|
let popup = null;
|
|
@@ -5867,21 +5972,17 @@ async function onramp(options = {}) {
|
|
|
5867
5972
|
}
|
|
5868
5973
|
let session;
|
|
5869
5974
|
try {
|
|
5870
|
-
const res = await
|
|
5975
|
+
const res = await authedFetch('/__bounded/onramp/session', {
|
|
5871
5976
|
method: 'POST',
|
|
5872
|
-
headers: {
|
|
5873
|
-
body:
|
|
5977
|
+
headers: { 'content-type': 'application/json' },
|
|
5978
|
+
body: sessionBody(options),
|
|
5874
5979
|
});
|
|
5875
5980
|
if (!res.ok) {
|
|
5876
|
-
|
|
5877
|
-
try {
|
|
5878
|
-
detail = (_c = (await res.json()).error) !== null && _c !== void 0 ? _c : '';
|
|
5879
|
-
}
|
|
5880
|
-
catch ( /* keep status only */_d) { /* keep status only */ }
|
|
5981
|
+
const detail = await readError(res);
|
|
5881
5982
|
if (res.status === 404) {
|
|
5882
|
-
throw new Error('onramp
|
|
5983
|
+
throw new Error('onramp: session endpoint not found - onramp works on Bounded-served origins (your deployed app URL), not local dev servers');
|
|
5883
5984
|
}
|
|
5884
|
-
throw new Error(`onramp
|
|
5985
|
+
throw new Error(`onramp: session mint failed (${res.status}${detail ? `: ${detail}` : ''})`);
|
|
5885
5986
|
}
|
|
5886
5987
|
session = (await res.json());
|
|
5887
5988
|
}
|
|
@@ -5889,40 +5990,47 @@ async function onramp(options = {}) {
|
|
|
5889
5990
|
try {
|
|
5890
5991
|
popup === null || popup === void 0 ? void 0 : popup.close();
|
|
5891
5992
|
}
|
|
5892
|
-
catch ( /* ignore */
|
|
5993
|
+
catch ( /* ignore */_b) { /* ignore */ }
|
|
5893
5994
|
throw error;
|
|
5894
5995
|
}
|
|
5996
|
+
const openedAt = Date.now();
|
|
5997
|
+
const base = Object.assign({ address: session.address, asset: session.asset }, (session.quote ? { quote: session.quote } : {}));
|
|
5895
5998
|
if (popup) {
|
|
5896
5999
|
try {
|
|
5897
6000
|
popup.location.replace(session.url);
|
|
5898
6001
|
}
|
|
5899
|
-
catch (
|
|
6002
|
+
catch (_c) {
|
|
5900
6003
|
try {
|
|
5901
6004
|
popup.location.href = session.url;
|
|
5902
6005
|
}
|
|
5903
|
-
catch (
|
|
6006
|
+
catch (_d) {
|
|
5904
6007
|
try {
|
|
5905
6008
|
popup.close();
|
|
5906
6009
|
}
|
|
5907
|
-
catch ( /* ignore */
|
|
5908
|
-
throw new Error('onramp
|
|
6010
|
+
catch ( /* ignore */_e) { /* ignore */ }
|
|
6011
|
+
throw new Error('onramp: popup failed to navigate - retry with { newTab: true }');
|
|
5909
6012
|
}
|
|
5910
6013
|
}
|
|
5911
|
-
|
|
6014
|
+
await new Promise((resolve) => {
|
|
5912
6015
|
const timer = setInterval(() => {
|
|
5913
6016
|
if (popup.closed) {
|
|
5914
6017
|
clearInterval(timer);
|
|
5915
|
-
resolve(
|
|
6018
|
+
resolve();
|
|
5916
6019
|
}
|
|
5917
6020
|
}, 500);
|
|
5918
6021
|
});
|
|
6022
|
+
const fill = await verifyCompletion(openedAt, session.asset, (_a = options.completionTimeoutMs) !== null && _a !== void 0 ? _a : 24000);
|
|
6023
|
+
if (fill) {
|
|
6024
|
+
return Object.assign(Object.assign(Object.assign(Object.assign({}, base), { status: 'completed' }), (fill.amountOut !== null ? { actualOut: fill.amountOut } : {})), (fill.txHash ? { txHash: fill.txHash } : {}));
|
|
6025
|
+
}
|
|
6026
|
+
return Object.assign(Object.assign({}, base), { status: 'closed' });
|
|
5919
6027
|
}
|
|
5920
6028
|
// New-tab path (popup was blocked or explicitly requested): cross-origin tab
|
|
5921
|
-
// close is not observable, so resolve immediately.
|
|
6029
|
+
// close is not observable, so resolve immediately; verify via onrampStatus().
|
|
5922
6030
|
const tab = window.open(session.url, '_blank');
|
|
5923
6031
|
if (!tab)
|
|
5924
|
-
throw new Error('onramp
|
|
5925
|
-
return { status: 'opened'
|
|
6032
|
+
throw new Error('onramp: window.open was blocked - call onramp() from a click handler');
|
|
6033
|
+
return Object.assign(Object.assign({}, base), { status: 'opened' });
|
|
5926
6034
|
}
|
|
5927
6035
|
|
|
5928
6036
|
/**
|
|
@@ -6347,6 +6455,8 @@ exports.normalizeSolanaRpcUrl = normalizeSolanaRpcUrl;
|
|
|
6347
6455
|
exports.onAuthLoadingChanged = onAuthLoadingChanged;
|
|
6348
6456
|
exports.onAuthStateChanged = onAuthStateChanged;
|
|
6349
6457
|
exports.onramp = onramp;
|
|
6458
|
+
exports.onrampQuote = onrampQuote;
|
|
6459
|
+
exports.onrampStatus = onrampStatus;
|
|
6350
6460
|
exports.resolveSolanaRpcUrl = resolveSolanaRpcUrl;
|
|
6351
6461
|
exports.setAuthLoading = setAuthLoading;
|
|
6352
6462
|
exports.setCurrentUser = setCurrentUser;
|
|
@@ -6355,4 +6465,4 @@ exports.signInAnonymously = signInAnonymously;
|
|
|
6355
6465
|
exports.useAuth = useAuth;
|
|
6356
6466
|
exports.useBuildRun = useBuildRun;
|
|
6357
6467
|
exports.useQuery = useQuery;
|
|
6358
|
-
//# sourceMappingURL=index.native-
|
|
6468
|
+
//# sourceMappingURL=index.native-CDfx0N6p.js.map
|