@bounded-sh/client 0.0.43 → 0.0.44
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/auth/crossmint-signer-bridge.d.ts +8 -0
- package/dist/auth/providers/email-auth-provider.d.ts +1 -1
- package/dist/auth/providers/injected-evm-wallet-provider.d.ts +37 -0
- package/dist/auth/providers/injected-evm-wallet-types.d.ts +65 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +519 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +519 -25
- package/dist/index.mjs.map +1 -1
- package/dist/index.native.js +517 -23
- package/dist/index.native.js.map +1 -1
- package/dist/index.native.mjs +518 -24
- package/dist/index.native.mjs.map +1 -1
- package/package.json +128 -128
package/dist/index.js
CHANGED
|
@@ -3655,7 +3655,7 @@ function decodeJwt$2(token) {
|
|
|
3655
3655
|
// Pull the embedded-wallet identity out of the active session's id token.
|
|
3656
3656
|
// Returns null when this session has no wallet (so callers can throw the
|
|
3657
3657
|
// informative NO_EMBEDDED_WALLET error).
|
|
3658
|
-
function walletClaimsFromSession() {
|
|
3658
|
+
function walletClaimsFromSession(chain = 'solana') {
|
|
3659
3659
|
let idToken = null;
|
|
3660
3660
|
try {
|
|
3661
3661
|
idToken = core.getActiveSessionManager().getIdToken();
|
|
@@ -3667,14 +3667,17 @@ function walletClaimsFromSession() {
|
|
|
3667
3667
|
return null;
|
|
3668
3668
|
const c = decodeJwt$2(idToken);
|
|
3669
3669
|
const address = c['custom:walletAddress'];
|
|
3670
|
+
const evmAddress = c['custom:evmWalletAddress'];
|
|
3670
3671
|
const email = c['email'];
|
|
3671
|
-
if (typeof address !== 'string' || !address)
|
|
3672
|
-
return null;
|
|
3673
3672
|
if (typeof email !== 'string' || !email)
|
|
3674
3673
|
return null;
|
|
3674
|
+
if (chain === 'solana' && (typeof address !== 'string' || !address))
|
|
3675
|
+
return null;
|
|
3676
|
+
if (chain === 'evm' && (typeof evmAddress !== 'string' || !/^0x[0-9a-fA-F]{40}$/.test(evmAddress)))
|
|
3677
|
+
return null;
|
|
3675
3678
|
const envClaim = c['custom:walletEnvironment'];
|
|
3676
3679
|
const environment = envClaim === 'staging' || envClaim === 'production' ? envClaim : undefined;
|
|
3677
|
-
return { email, address, environment };
|
|
3680
|
+
return Object.assign(Object.assign(Object.assign({ email }, (typeof address === 'string' && address ? { address } : {})), (typeof evmAddress === 'string' ? { evmAddress: evmAddress.toLowerCase() } : {})), { environment });
|
|
3678
3681
|
}
|
|
3679
3682
|
async function signerPageUrl() {
|
|
3680
3683
|
const cfg = await core.getConfig();
|
|
@@ -3695,7 +3698,8 @@ async function signViaSignerPopup(action) {
|
|
|
3695
3698
|
if (!hasDOM$1()) {
|
|
3696
3699
|
throw new Error('Embedded-wallet signing is only available in the browser (popup-based).');
|
|
3697
3700
|
}
|
|
3698
|
-
const
|
|
3701
|
+
const isEvm = action.kind === 'evmTransaction';
|
|
3702
|
+
const claims = walletClaimsFromSession(isEvm ? 'evm' : 'solana');
|
|
3699
3703
|
if (!claims)
|
|
3700
3704
|
throw new Error(NO_EMBEDDED_WALLET);
|
|
3701
3705
|
const { url, origin: signerOrigin } = await signerPageUrl();
|
|
@@ -3713,7 +3717,7 @@ async function signViaSignerPopup(action) {
|
|
|
3713
3717
|
requestId,
|
|
3714
3718
|
environment: claims.environment, // may be undefined → page auto-detects
|
|
3715
3719
|
email: claims.email,
|
|
3716
|
-
address: claims.address,
|
|
3720
|
+
address: isEvm ? claims.evmAddress : claims.address,
|
|
3717
3721
|
action,
|
|
3718
3722
|
};
|
|
3719
3723
|
return await new Promise((resolve, reject) => {
|
|
@@ -3738,6 +3742,8 @@ async function signViaSignerPopup(action) {
|
|
|
3738
3742
|
const onMsg = (ev) => {
|
|
3739
3743
|
if (ev.origin !== signerOrigin)
|
|
3740
3744
|
return; // only trust the signer page origin
|
|
3745
|
+
if (ev.source !== popup)
|
|
3746
|
+
return; // only trust this signer popup window
|
|
3741
3747
|
const d = ev.data;
|
|
3742
3748
|
if (!d || typeof d !== 'object')
|
|
3743
3749
|
return;
|
|
@@ -3809,6 +3815,10 @@ function serializeTransaction(transaction) {
|
|
|
3809
3815
|
function hasEmbeddedWallet() {
|
|
3810
3816
|
return walletClaimsFromSession() != null;
|
|
3811
3817
|
}
|
|
3818
|
+
/** Whether the active email/social session carries an embedded Crossmint EVM wallet. */
|
|
3819
|
+
function hasEmbeddedEvmWallet() {
|
|
3820
|
+
return walletClaimsFromSession('evm') != null;
|
|
3821
|
+
}
|
|
3812
3822
|
/** signAndSubmitTransaction for embedded wallets: serialize + route through the
|
|
3813
3823
|
* signer popup, resolve with the on-chain transaction signature/hash. */
|
|
3814
3824
|
async function embeddedSignAndSubmit(transaction) {
|
|
@@ -3819,6 +3829,36 @@ async function embeddedSignAndSubmit(transaction) {
|
|
|
3819
3829
|
throw new Error('Signer returned no transaction hash.');
|
|
3820
3830
|
return hash;
|
|
3821
3831
|
}
|
|
3832
|
+
/** Submit a validated BoundedRuntime EVM write through the user's email signer. */
|
|
3833
|
+
async function embeddedRunEvmTransaction(transaction) {
|
|
3834
|
+
var _a, _b;
|
|
3835
|
+
if (!transaction.to || !transaction.data || !transaction.chainId)
|
|
3836
|
+
throw new Error('Incomplete embedded EVM transaction');
|
|
3837
|
+
if (!/^0x[0-9a-fA-F]{40}$/.test(transaction.to))
|
|
3838
|
+
throw new Error('Invalid embedded EVM runtime address');
|
|
3839
|
+
core.assertCanonicalBoundedRuntimeWriteCalldata(transaction.data);
|
|
3840
|
+
if (!Number.isSafeInteger(transaction.chainId) || transaction.chainId <= 0)
|
|
3841
|
+
throw new Error('Invalid embedded EVM chain id');
|
|
3842
|
+
if (transaction.nonce !== undefined)
|
|
3843
|
+
throw new Error('Server-supplied EVM nonces are not accepted');
|
|
3844
|
+
try {
|
|
3845
|
+
if (BigInt((_a = transaction.value) !== null && _a !== void 0 ? _a : '0') !== BigInt(0))
|
|
3846
|
+
throw new Error('Bounded EVM writes cannot transfer native value');
|
|
3847
|
+
}
|
|
3848
|
+
catch (error) {
|
|
3849
|
+
if (error instanceof Error && error.message.includes('cannot transfer'))
|
|
3850
|
+
throw error;
|
|
3851
|
+
throw new Error('Invalid embedded EVM transaction value');
|
|
3852
|
+
}
|
|
3853
|
+
const result = await signViaSignerPopup({
|
|
3854
|
+
kind: 'evmTransaction',
|
|
3855
|
+
transaction: { to: transaction.to, data: transaction.data, value: (_b = transaction.value) !== null && _b !== void 0 ? _b : '0', chainId: transaction.chainId },
|
|
3856
|
+
});
|
|
3857
|
+
const hash = result.hash || result.transactionId;
|
|
3858
|
+
if (!hash)
|
|
3859
|
+
throw new Error('Signer returned no EVM transaction hash.');
|
|
3860
|
+
return { transactionSignature: hash, blockNumber: 0, gasUsed: '0', data: result };
|
|
3861
|
+
}
|
|
3822
3862
|
|
|
3823
3863
|
// Web uses localStorage (WebSessionManager); React Native uses the configured
|
|
3824
3864
|
// ReactNativeSessionManager. getActiveSessionManager() picks the right one by
|
|
@@ -3853,7 +3893,10 @@ function userFromIdToken$1(idToken, fallbackEmail) {
|
|
|
3853
3893
|
const id = c['custom:userId'] || c.sub || c['custom:walletAddress'] || '';
|
|
3854
3894
|
const email = (c.email || fallbackEmail || null);
|
|
3855
3895
|
// Email logins have no wallet — address is null (the User type allows it).
|
|
3856
|
-
|
|
3896
|
+
const evmAddress = typeof c['custom:evmWalletAddress'] === 'string' && /^0x[0-9a-fA-F]{40}$/.test(c['custom:evmWalletAddress'])
|
|
3897
|
+
? c['custom:evmWalletAddress'].toLowerCase()
|
|
3898
|
+
: null;
|
|
3899
|
+
return { id, address: (c['custom:walletAddress'] || null), evmAddress, email, provider: emailProviderSingleton };
|
|
3857
3900
|
}
|
|
3858
3901
|
// ---------------------------------------------------------------------------
|
|
3859
3902
|
// provider
|
|
@@ -3887,7 +3930,17 @@ class EmailAuthProvider {
|
|
|
3887
3930
|
async signMessage(_message) {
|
|
3888
3931
|
throw new Error(hasEmbeddedWallet() ? EMBEDDED_WALLET_UNSUPPORTED : NO_WALLET);
|
|
3889
3932
|
}
|
|
3890
|
-
async runTransaction(
|
|
3933
|
+
async runTransaction(evm, sol, options) {
|
|
3934
|
+
if (evm && sol)
|
|
3935
|
+
throw new Error('A transaction cannot target EVM and Solana at the same time.');
|
|
3936
|
+
if (!evm)
|
|
3937
|
+
throw new Error(NO_WALLET);
|
|
3938
|
+
if ((options === null || options === void 0 ? void 0 : options.shouldSubmitTx) === false)
|
|
3939
|
+
throw new Error('Embedded EVM wallets sign and submit atomically; shouldSubmitTx:false is unsupported.');
|
|
3940
|
+
if (!hasEmbeddedEvmWallet())
|
|
3941
|
+
throw new Error('This login has no embedded EVM wallet. Enable auth.wallets on an app with an EVM collection and sign in again.');
|
|
3942
|
+
return embeddedRunEvmTransaction(evm);
|
|
3943
|
+
}
|
|
3891
3944
|
async signTransaction(_t) {
|
|
3892
3945
|
throw new Error(hasEmbeddedWallet() ? EMBEDDED_WALLET_UNSUPPORTED : NO_WALLET);
|
|
3893
3946
|
}
|
|
@@ -3993,31 +4046,45 @@ function defaultInjectedProvider() {
|
|
|
3993
4046
|
return null;
|
|
3994
4047
|
}
|
|
3995
4048
|
|
|
3996
|
-
const STORED_AUTH_METHOD_KEY$
|
|
4049
|
+
const STORED_AUTH_METHOD_KEY$3 = 'bounded_last_auth_method';
|
|
3997
4050
|
const INJECTED_AUTH_METHOD = 'phantom';
|
|
3998
|
-
const NO_WALLET_ERR = 'No injected Solana wallet found. Install a wallet like Phantom (phantom.app) and try again, ' +
|
|
4051
|
+
const NO_WALLET_ERR$1 = 'No injected Solana wallet found. Install a wallet like Phantom (phantom.app) and try again, ' +
|
|
3999
4052
|
'or pass config.injectedWalletConfig.getProvider to point at your wallet.';
|
|
4000
4053
|
class InjectedWalletProvider {
|
|
4001
4054
|
constructor(config = {}, networkUrl = null, configuredNetwork = null) {
|
|
4002
|
-
var _a
|
|
4055
|
+
var _a;
|
|
4003
4056
|
if (typeof window === 'undefined') {
|
|
4004
4057
|
throw new Error('InjectedWalletProvider can only be instantiated in a browser environment');
|
|
4005
4058
|
}
|
|
4059
|
+
// `config.rpcUrl` is the legacy wallet-login-local override. Normalize
|
|
4060
|
+
// it before precedence so an empty legacy value cannot shadow the
|
|
4061
|
+
// current top-level config.rpcUrl. Re-initialization must also replace
|
|
4062
|
+
// every singleton field; otherwise a previous app's provider/RPC can
|
|
4063
|
+
// survive getAuthProvider()'s config-key rotation.
|
|
4064
|
+
const resolvedNetworkUrl = (_a = normalizeSolanaRpcUrl(config.rpcUrl)) !== null && _a !== void 0 ? _a : normalizeSolanaRpcUrl(networkUrl);
|
|
4065
|
+
const localNetwork = typeof config.network === 'string' && config.network.trim() !== ''
|
|
4066
|
+
? config.network.trim()
|
|
4067
|
+
: null;
|
|
4068
|
+
const resolvedConfiguredNetwork = localNetwork !== null && localNetwork !== void 0 ? localNetwork : (typeof configuredNetwork === 'string' && configuredNetwork.trim() !== ''
|
|
4069
|
+
? configuredNetwork.trim()
|
|
4070
|
+
: null);
|
|
4006
4071
|
// Singleton so the SDK reuses one instance (mirrors the other providers).
|
|
4007
4072
|
if (InjectedWalletProvider.instance) {
|
|
4008
|
-
InjectedWalletProvider.instance.config = Object.assign(
|
|
4073
|
+
InjectedWalletProvider.instance.config = Object.assign({}, config);
|
|
4074
|
+
InjectedWalletProvider.instance.networkUrl = resolvedNetworkUrl;
|
|
4075
|
+
InjectedWalletProvider.instance.configuredNetwork = resolvedConfiguredNetwork;
|
|
4009
4076
|
return InjectedWalletProvider.instance;
|
|
4010
4077
|
}
|
|
4011
|
-
this.config = config;
|
|
4012
|
-
this.networkUrl =
|
|
4013
|
-
this.configuredNetwork =
|
|
4078
|
+
this.config = Object.assign({}, config);
|
|
4079
|
+
this.networkUrl = resolvedNetworkUrl;
|
|
4080
|
+
this.configuredNetwork = resolvedConfiguredNetwork;
|
|
4014
4081
|
InjectedWalletProvider.instance = this;
|
|
4015
4082
|
}
|
|
4016
4083
|
resolveProvider() {
|
|
4017
4084
|
var _a;
|
|
4018
4085
|
const provider = (_a = (this.config.getProvider ? this.config.getProvider() : null)) !== null && _a !== void 0 ? _a : defaultInjectedProvider();
|
|
4019
4086
|
if (!provider)
|
|
4020
|
-
throw new Error(NO_WALLET_ERR);
|
|
4087
|
+
throw new Error(NO_WALLET_ERR$1);
|
|
4021
4088
|
return provider;
|
|
4022
4089
|
}
|
|
4023
4090
|
/** Connect the injected wallet (if needed) and return its Solana address. */
|
|
@@ -4071,7 +4138,7 @@ class InjectedWalletProvider {
|
|
|
4071
4138
|
// Mark the auth method so clearIncompatibleSession() doesn't wipe this
|
|
4072
4139
|
// wallet session on the next init().
|
|
4073
4140
|
try {
|
|
4074
|
-
getPlatform().storage.setItem(STORED_AUTH_METHOD_KEY$
|
|
4141
|
+
getPlatform().storage.setItem(STORED_AUTH_METHOD_KEY$3, INJECTED_AUTH_METHOD);
|
|
4075
4142
|
}
|
|
4076
4143
|
catch ( /* no storage */_a) { /* no storage */ }
|
|
4077
4144
|
}
|
|
@@ -4226,6 +4293,406 @@ class InjectedWalletProvider {
|
|
|
4226
4293
|
}
|
|
4227
4294
|
InjectedWalletProvider.instance = null;
|
|
4228
4295
|
|
|
4296
|
+
// injected-evm-wallet-types.ts — tiny, dependency-free surface for the EVM
|
|
4297
|
+
// WALLET LOGIN path (BYO wallet via SIWE). The EVM twin of
|
|
4298
|
+
// injected-wallet-types.ts: kept separate from injected-evm-wallet-provider.ts
|
|
4299
|
+
// so the SDK entry can eagerly export the type surface + the provider-discovery
|
|
4300
|
+
// helper WITHOUT dragging the provider class into the default bundle. The
|
|
4301
|
+
// provider is lazy-loaded by getAuthProvider() when an app opts into
|
|
4302
|
+
// authMethod:'evm-wallet'.
|
|
4303
|
+
//
|
|
4304
|
+
// It rides the standard EIP-1193 injected provider a browser wallet exposes
|
|
4305
|
+
// (MetaMask / Rabby / Coinbase Wallet / any window.ethereum), discovered via
|
|
4306
|
+
// EIP-6963 (multi-wallet, collision-free) with a window.ethereum fallback. It
|
|
4307
|
+
// needs NO viem/ethers and NO React — EIP-1193 request() + hex strings suffice.
|
|
4308
|
+
// EIP-6963 is announcement-based: wallets add an `eip6963:requestProvider`
|
|
4309
|
+
// listener and synchronously dispatch `eip6963:announceProvider` in response. We
|
|
4310
|
+
// keep a persistent collector so announcements (including late ones) are
|
|
4311
|
+
// captured, and re-request on demand.
|
|
4312
|
+
const announcedProviders = [];
|
|
4313
|
+
let announceListenerAttached = false;
|
|
4314
|
+
function attachAnnounceListener() {
|
|
4315
|
+
if (announceListenerAttached || typeof window === 'undefined')
|
|
4316
|
+
return;
|
|
4317
|
+
announceListenerAttached = true;
|
|
4318
|
+
window.addEventListener('eip6963:announceProvider', (event) => {
|
|
4319
|
+
const detail = event === null || event === void 0 ? void 0 : event.detail;
|
|
4320
|
+
if (detail &&
|
|
4321
|
+
detail.provider &&
|
|
4322
|
+
typeof detail.provider.request === 'function' &&
|
|
4323
|
+
!announcedProviders.some((d) => { var _a, _b; return ((_a = d.info) === null || _a === void 0 ? void 0 : _a.uuid) === ((_b = detail.info) === null || _b === void 0 ? void 0 : _b.uuid); })) {
|
|
4324
|
+
announcedProviders.push(detail);
|
|
4325
|
+
}
|
|
4326
|
+
});
|
|
4327
|
+
}
|
|
4328
|
+
/**
|
|
4329
|
+
* Request + collect EIP-6963 providers. Dispatches `eip6963:requestProvider`
|
|
4330
|
+
* (synchronous — already-loaded wallets announce in the same tick) and returns
|
|
4331
|
+
* every wallet announced so far. Kept synchronous so it works inside a user
|
|
4332
|
+
* gesture and can be eagerly exported from the SDK entry.
|
|
4333
|
+
*/
|
|
4334
|
+
function requestEip6963Providers() {
|
|
4335
|
+
if (typeof window === 'undefined')
|
|
4336
|
+
return [];
|
|
4337
|
+
attachAnnounceListener();
|
|
4338
|
+
try {
|
|
4339
|
+
window.dispatchEvent(new Event('eip6963:requestProvider'));
|
|
4340
|
+
}
|
|
4341
|
+
catch (_a) {
|
|
4342
|
+
/* older browsers without Event constructor — fall through to window.ethereum */
|
|
4343
|
+
}
|
|
4344
|
+
return announcedProviders.slice();
|
|
4345
|
+
}
|
|
4346
|
+
/**
|
|
4347
|
+
* Default EVM provider discovery: EIP-6963 first (multi-wallet, collision-free),
|
|
4348
|
+
* then legacy `window.ethereum`. Returns null when no injected wallet is present.
|
|
4349
|
+
*/
|
|
4350
|
+
function defaultInjectedEvmProvider() {
|
|
4351
|
+
if (typeof window === 'undefined')
|
|
4352
|
+
return null;
|
|
4353
|
+
const details = requestEip6963Providers();
|
|
4354
|
+
if (details.length > 0)
|
|
4355
|
+
return details[0].provider;
|
|
4356
|
+
const eth = window.ethereum;
|
|
4357
|
+
if (eth && typeof eth.request === 'function')
|
|
4358
|
+
return eth;
|
|
4359
|
+
return null;
|
|
4360
|
+
}
|
|
4361
|
+
|
|
4362
|
+
const STORED_AUTH_METHOD_KEY$2 = 'bounded_last_auth_method';
|
|
4363
|
+
// Must equal the authMethod the registry (auth/index.ts) sets as currentAuthMethod,
|
|
4364
|
+
// so clearIncompatibleSession() keeps (not wipes) this session on the next init().
|
|
4365
|
+
const INJECTED_EVM_AUTH_METHOD = 'evm-wallet';
|
|
4366
|
+
// The /session issuer's discriminator for the SIWE (EIP-4361 secp256k1) exchange.
|
|
4367
|
+
const SIWE_SESSION_METHOD = 'siwe';
|
|
4368
|
+
const NO_WALLET_ERR = 'No injected EVM wallet found. Install a wallet like MetaMask (metamask.io) or Rabby and try again, ' +
|
|
4369
|
+
'or pass config.evmWalletConfig.getProvider to point at your wallet.';
|
|
4370
|
+
const NO_SOL_TX_ERR = 'EVM wallet login signs+submits transactions in one step (eth_sendTransaction) and has no Solana ' +
|
|
4371
|
+
'transaction surface. Use an onchain WRITE (setMany) — the worker returns a pre-built EVM tx that ' +
|
|
4372
|
+
'runTransaction submits — instead of signTransaction/signAndSubmitTransaction.';
|
|
4373
|
+
// Bounded polling for the tx receipt: ~60s at 2s cadence (L2 blocks are seconds).
|
|
4374
|
+
const RECEIPT_POLL_ATTEMPTS = 30;
|
|
4375
|
+
const RECEIPT_POLL_INTERVAL_MS = 2000;
|
|
4376
|
+
function normalizeConfig(config) {
|
|
4377
|
+
var _a;
|
|
4378
|
+
if (config.chainId !== undefined && (!Number.isSafeInteger(config.chainId) || config.chainId <= 0)) {
|
|
4379
|
+
throw new Error('EVM wallet chainId must be a positive safe integer');
|
|
4380
|
+
}
|
|
4381
|
+
let runtimeAddress;
|
|
4382
|
+
if (config.runtimeAddress !== undefined) {
|
|
4383
|
+
runtimeAddress = (_a = core.normalizeEvmAddress(config.runtimeAddress)) !== null && _a !== void 0 ? _a : undefined;
|
|
4384
|
+
if (!runtimeAddress)
|
|
4385
|
+
throw new Error('EVM wallet runtimeAddress is invalid');
|
|
4386
|
+
if (config.chainId === undefined)
|
|
4387
|
+
throw new Error('EVM wallet runtimeAddress requires an explicit chainId');
|
|
4388
|
+
}
|
|
4389
|
+
let runtimeAddresses;
|
|
4390
|
+
if (config.runtimeAddresses !== undefined) {
|
|
4391
|
+
runtimeAddresses = {};
|
|
4392
|
+
for (const [rawChainId, rawAddress] of Object.entries(config.runtimeAddresses)) {
|
|
4393
|
+
const chainId = Number(rawChainId);
|
|
4394
|
+
const address = core.normalizeEvmAddress(rawAddress);
|
|
4395
|
+
if (!Number.isSafeInteger(chainId) || chainId <= 0 || String(chainId) !== rawChainId || !address) {
|
|
4396
|
+
throw new Error(`Invalid EVM runtime allowlist entry for chain ${rawChainId}`);
|
|
4397
|
+
}
|
|
4398
|
+
runtimeAddresses[rawChainId] = address;
|
|
4399
|
+
}
|
|
4400
|
+
}
|
|
4401
|
+
return Object.assign(Object.assign({}, config), { runtimeAddress, runtimeAddresses });
|
|
4402
|
+
}
|
|
4403
|
+
class InjectedEvmWalletProvider {
|
|
4404
|
+
constructor(config = {}) {
|
|
4405
|
+
this.authenticatedAddress = null;
|
|
4406
|
+
if (typeof window === 'undefined') {
|
|
4407
|
+
throw new Error('InjectedEvmWalletProvider can only be instantiated in a browser environment');
|
|
4408
|
+
}
|
|
4409
|
+
const normalized = normalizeConfig(config);
|
|
4410
|
+
// Singleton so the SDK reuses one instance (mirrors the other providers).
|
|
4411
|
+
if (InjectedEvmWalletProvider.instance) {
|
|
4412
|
+
InjectedEvmWalletProvider.instance.config = normalized;
|
|
4413
|
+
InjectedEvmWalletProvider.instance.authenticatedAddress = null;
|
|
4414
|
+
return InjectedEvmWalletProvider.instance;
|
|
4415
|
+
}
|
|
4416
|
+
this.config = normalized;
|
|
4417
|
+
InjectedEvmWalletProvider.instance = this;
|
|
4418
|
+
}
|
|
4419
|
+
// @user.address (the Solana wallet) is null for an EVM-wallet login. User.address
|
|
4420
|
+
// is typed `string` for legacy reasons — email logins cast the same null the same
|
|
4421
|
+
// way (email-auth-provider.ts) — so the null is cast here in one place.
|
|
4422
|
+
evmUser(address) {
|
|
4423
|
+
return { id: address, address: null, evmAddress: address, provider: this };
|
|
4424
|
+
}
|
|
4425
|
+
resolveProvider() {
|
|
4426
|
+
var _a;
|
|
4427
|
+
const provider = (_a = (this.config.getProvider ? this.config.getProvider() : null)) !== null && _a !== void 0 ? _a : defaultInjectedEvmProvider();
|
|
4428
|
+
if (!provider)
|
|
4429
|
+
throw new Error(NO_WALLET_ERR);
|
|
4430
|
+
return provider;
|
|
4431
|
+
}
|
|
4432
|
+
/** Connect the injected wallet and return its canonical lowercase EVM address. */
|
|
4433
|
+
async connectAddress(provider) {
|
|
4434
|
+
const accounts = await provider.request({ method: 'eth_requestAccounts' });
|
|
4435
|
+
const raw = Array.isArray(accounts) ? accounts[0] : undefined;
|
|
4436
|
+
const address = core.normalizeEvmAddress(raw);
|
|
4437
|
+
if (!address)
|
|
4438
|
+
throw new Error('Wallet did not return a valid EVM address on connect');
|
|
4439
|
+
return address;
|
|
4440
|
+
}
|
|
4441
|
+
/** Current chain id the wallet is connected to (EIP-155 number), or null. */
|
|
4442
|
+
async currentChainId(provider) {
|
|
4443
|
+
try {
|
|
4444
|
+
const hex = await provider.request({ method: 'eth_chainId' });
|
|
4445
|
+
if (typeof hex !== 'string' || !/^0x[0-9a-fA-F]+$/.test(hex))
|
|
4446
|
+
return null;
|
|
4447
|
+
const n = Number(BigInt(hex));
|
|
4448
|
+
return Number.isSafeInteger(n) && n > 0 ? n : null;
|
|
4449
|
+
}
|
|
4450
|
+
catch (_a) {
|
|
4451
|
+
return null;
|
|
4452
|
+
}
|
|
4453
|
+
}
|
|
4454
|
+
async login() {
|
|
4455
|
+
var _a;
|
|
4456
|
+
setAuthLoading(true);
|
|
4457
|
+
try {
|
|
4458
|
+
const provider = this.resolveProvider();
|
|
4459
|
+
const address = await this.connectAddress(provider);
|
|
4460
|
+
// Reuse a still-valid session for THIS wallet.
|
|
4461
|
+
const existing = await core.getActiveSessionManager().getSession();
|
|
4462
|
+
if (existing && existing.address === address) {
|
|
4463
|
+
const user = this.evmUser(address);
|
|
4464
|
+
this.authenticatedAddress = address;
|
|
4465
|
+
setCurrentUser(user);
|
|
4466
|
+
this.markAuthMethod();
|
|
4467
|
+
return user;
|
|
4468
|
+
}
|
|
4469
|
+
// SIWE: nonce -> canonical EIP-4361 prompt -> the wallet personal_sign's it.
|
|
4470
|
+
const nonce = await core.genAuthNonce();
|
|
4471
|
+
const appId = (await core.getConfig()).appId;
|
|
4472
|
+
const chainId = (_a = this.config.chainId) !== null && _a !== void 0 ? _a : await this.currentChainId(provider);
|
|
4473
|
+
if (chainId === null)
|
|
4474
|
+
throw new Error('Could not verify the EVM wallet chain for SIWE login');
|
|
4475
|
+
const message = core.genSiweMessage(address, nonce, appId, this.resolveDomain(), this.resolveUri(), { chainId });
|
|
4476
|
+
// personal_sign(message, address) -> 0x r‖s‖v hex (the shape the
|
|
4477
|
+
// bounded-auth verifier's recoverSiweSigner consumes). The raw UTF-8
|
|
4478
|
+
// message is signed under the EIP-191 envelope the verifier hashes.
|
|
4479
|
+
const signature = await provider.request({
|
|
4480
|
+
method: 'personal_sign',
|
|
4481
|
+
params: [message, address],
|
|
4482
|
+
});
|
|
4483
|
+
const result = await core.createSessionWithSignature(address, message, signature, SIWE_SESSION_METHOD);
|
|
4484
|
+
await core.getActiveSessionManager().storeSession(address, result.accessToken, result.idToken, result.refreshToken);
|
|
4485
|
+
this.markAuthMethod();
|
|
4486
|
+
const user = this.evmUser(address);
|
|
4487
|
+
this.authenticatedAddress = address;
|
|
4488
|
+
setCurrentUser(user);
|
|
4489
|
+
return user;
|
|
4490
|
+
}
|
|
4491
|
+
finally {
|
|
4492
|
+
setAuthLoading(false);
|
|
4493
|
+
}
|
|
4494
|
+
}
|
|
4495
|
+
resolveDomain() {
|
|
4496
|
+
const actual = window.location.host.toLowerCase();
|
|
4497
|
+
if (this.config.domain && this.config.domain.toLowerCase() !== actual) {
|
|
4498
|
+
throw new Error('SIWE domain override must match the current browser origin');
|
|
4499
|
+
}
|
|
4500
|
+
return actual;
|
|
4501
|
+
}
|
|
4502
|
+
resolveUri() {
|
|
4503
|
+
const actual = window.location.origin.toLowerCase();
|
|
4504
|
+
if (this.config.uri) {
|
|
4505
|
+
let configured;
|
|
4506
|
+
try {
|
|
4507
|
+
configured = new URL(this.config.uri).origin.toLowerCase();
|
|
4508
|
+
}
|
|
4509
|
+
catch (_a) {
|
|
4510
|
+
throw new Error('SIWE URI override must be an absolute URL');
|
|
4511
|
+
}
|
|
4512
|
+
if (configured !== actual)
|
|
4513
|
+
throw new Error('SIWE URI override must match the current browser origin');
|
|
4514
|
+
}
|
|
4515
|
+
return actual;
|
|
4516
|
+
}
|
|
4517
|
+
markAuthMethod() {
|
|
4518
|
+
try {
|
|
4519
|
+
getPlatform().storage.setItem(STORED_AUTH_METHOD_KEY$2, INJECTED_EVM_AUTH_METHOD);
|
|
4520
|
+
}
|
|
4521
|
+
catch ( /* no storage */_a) { /* no storage */ }
|
|
4522
|
+
}
|
|
4523
|
+
async restoreSession() {
|
|
4524
|
+
const session = await core.getActiveSessionManager().getSession();
|
|
4525
|
+
if (!session)
|
|
4526
|
+
return null;
|
|
4527
|
+
// An EVM-wallet session stores the EVM address as its address; @user.address
|
|
4528
|
+
// (the Solana wallet) is null for this login.
|
|
4529
|
+
const address = core.normalizeEvmAddress(session.address);
|
|
4530
|
+
if (!address) {
|
|
4531
|
+
core.getActiveSessionManager().clearSession();
|
|
4532
|
+
return null;
|
|
4533
|
+
}
|
|
4534
|
+
this.authenticatedAddress = address;
|
|
4535
|
+
const user = this.evmUser(address);
|
|
4536
|
+
setCurrentUser(user);
|
|
4537
|
+
return user;
|
|
4538
|
+
}
|
|
4539
|
+
async logout() {
|
|
4540
|
+
// EIP-1193 has no standard disconnect; clearing the Bounded session is the
|
|
4541
|
+
// logout. (wallet_revokePermissions is non-standard/opt-in — skip it.)
|
|
4542
|
+
core.getActiveSessionManager().clearSession();
|
|
4543
|
+
this.authenticatedAddress = null;
|
|
4544
|
+
setCurrentUser(null);
|
|
4545
|
+
}
|
|
4546
|
+
// --- Signing surface -------------------------------------------------------
|
|
4547
|
+
/** App-facing message signing: EIP-191 personal_sign, returns 0x r‖s‖v hex. */
|
|
4548
|
+
async signMessage(message) {
|
|
4549
|
+
const provider = this.resolveProvider();
|
|
4550
|
+
const address = await this.connectAddress(provider);
|
|
4551
|
+
if (!this.authenticatedAddress || address !== this.authenticatedAddress) {
|
|
4552
|
+
throw new Error('The connected EVM wallet account changed after login. Sign in again before signing.');
|
|
4553
|
+
}
|
|
4554
|
+
return provider.request({ method: 'personal_sign', params: [message, address] });
|
|
4555
|
+
}
|
|
4556
|
+
// Solana-typed methods are structurally unsupported on an EVM wallet — the
|
|
4557
|
+
// EVM onchain write goes through runTransaction (eth_sendTransaction).
|
|
4558
|
+
async signTransaction(_transaction) {
|
|
4559
|
+
throw new Error(NO_SOL_TX_ERR);
|
|
4560
|
+
}
|
|
4561
|
+
async signAndSubmitTransaction(_transaction, _feePayer) {
|
|
4562
|
+
throw new Error(NO_SOL_TX_ERR);
|
|
4563
|
+
}
|
|
4564
|
+
/**
|
|
4565
|
+
* Onchain write path: submit the worker's PRE-BUILT EIP-1559 tx via
|
|
4566
|
+
* eth_sendTransaction (the injected wallet signs + submits in one step), then
|
|
4567
|
+
* poll for the receipt. The EVM branch of operations.ts's 202 dispatch calls
|
|
4568
|
+
* this with the pre-built payload in the EVM slot and the Solana slot undefined.
|
|
4569
|
+
*/
|
|
4570
|
+
async runTransaction(evmTransactionData, solTransactionData, options) {
|
|
4571
|
+
var _a, _b, _c;
|
|
4572
|
+
const evmTx = evmTransactionData;
|
|
4573
|
+
if (evmTx && solTransactionData) {
|
|
4574
|
+
throw new Error('A transaction cannot target EVM and Solana at the same time.');
|
|
4575
|
+
}
|
|
4576
|
+
if (!evmTx || !core.normalizeEvmAddress(evmTx.to) || typeof evmTx.data !== 'string' || !/^0x(?:[0-9a-fA-F]{2})+$/.test(evmTx.data)) {
|
|
4577
|
+
throw new Error('EVM transaction data (pre-built { to, data, chainId }) is required for an EVM onchain write');
|
|
4578
|
+
}
|
|
4579
|
+
// Exact decode, rather than a four-byte prefix check: permits the
|
|
4580
|
+
// ordinary and attested document-write entrypoints while rejecting
|
|
4581
|
+
// malformed/trailing calldata before the wallet sees a signing prompt.
|
|
4582
|
+
core.assertCanonicalBoundedRuntimeWriteCalldata(evmTx.data);
|
|
4583
|
+
if (!Number.isSafeInteger(evmTx.chainId) || evmTx.chainId <= 0) {
|
|
4584
|
+
throw new Error('EVM transaction chainId is required and must be a positive safe integer');
|
|
4585
|
+
}
|
|
4586
|
+
const chainId = evmTx.chainId;
|
|
4587
|
+
const trustedRuntime = (_b = (_a = this.config.runtimeAddresses) === null || _a === void 0 ? void 0 : _a[String(chainId)]) !== null && _b !== void 0 ? _b : (this.config.chainId === chainId ? this.config.runtimeAddress : undefined);
|
|
4588
|
+
if (!trustedRuntime)
|
|
4589
|
+
throw new Error(`No trusted BoundedRuntime address configured for EVM chain ${chainId}`);
|
|
4590
|
+
if (core.normalizeEvmAddress(evmTx.to) !== trustedRuntime) {
|
|
4591
|
+
throw new Error('EVM transaction target is not the configured BoundedRuntime');
|
|
4592
|
+
}
|
|
4593
|
+
if (evmTx.nonce !== undefined) {
|
|
4594
|
+
throw new Error('Server-supplied EVM nonces are not accepted');
|
|
4595
|
+
}
|
|
4596
|
+
try {
|
|
4597
|
+
if (BigInt((_c = evmTx.value) !== null && _c !== void 0 ? _c : '0') !== BigInt(0)) {
|
|
4598
|
+
throw new Error('BoundedRuntime.setDocuments cannot transfer native value');
|
|
4599
|
+
}
|
|
4600
|
+
}
|
|
4601
|
+
catch (error) {
|
|
4602
|
+
if (error instanceof Error && error.message.includes('cannot transfer'))
|
|
4603
|
+
throw error;
|
|
4604
|
+
throw new Error('Invalid EVM transaction value');
|
|
4605
|
+
}
|
|
4606
|
+
if ((options === null || options === void 0 ? void 0 : options.shouldSubmitTx) === false) {
|
|
4607
|
+
// Injected EVM wallets sign+submit atomically; eth_signTransaction is not
|
|
4608
|
+
// broadly supported (MetaMask removed it), so we cannot return a signed-
|
|
4609
|
+
// but-unsubmitted tx here. Fail clearly instead of silently submitting.
|
|
4610
|
+
throw new Error('shouldSubmitTx:false is unsupported for injected EVM wallets (they sign and submit atomically).');
|
|
4611
|
+
}
|
|
4612
|
+
const provider = this.resolveProvider();
|
|
4613
|
+
const from = await this.connectAddress(provider);
|
|
4614
|
+
if (!this.authenticatedAddress || from !== this.authenticatedAddress) {
|
|
4615
|
+
throw new Error('The connected EVM wallet account changed after login. Sign in again before submitting this write.');
|
|
4616
|
+
}
|
|
4617
|
+
// Chain-switch guard: the pre-built tx names the chain it MUST execute on.
|
|
4618
|
+
if (typeof evmTx.chainId === 'number') {
|
|
4619
|
+
const current = await this.currentChainId(provider);
|
|
4620
|
+
if (current === null)
|
|
4621
|
+
throw new Error('Could not verify the EVM wallet chain; refusing to submit the transaction.');
|
|
4622
|
+
if (current !== evmTx.chainId) {
|
|
4623
|
+
const targetHex = '0x' + evmTx.chainId.toString(16);
|
|
4624
|
+
try {
|
|
4625
|
+
await provider.request({
|
|
4626
|
+
method: 'wallet_switchEthereumChain',
|
|
4627
|
+
params: [{ chainId: targetHex }],
|
|
4628
|
+
});
|
|
4629
|
+
}
|
|
4630
|
+
catch (err) {
|
|
4631
|
+
throw new Error(`EVM wallet is on chain ${current} but this write targets chain ${evmTx.chainId}, ` +
|
|
4632
|
+
`and the chain switch was rejected or failed${(err === null || err === void 0 ? void 0 : err.message) ? `: ${err.message}` : ''}. ` +
|
|
4633
|
+
`Switch your wallet to chain ${evmTx.chainId} and retry.`);
|
|
4634
|
+
}
|
|
4635
|
+
const switched = await this.currentChainId(provider);
|
|
4636
|
+
if (switched !== evmTx.chainId) {
|
|
4637
|
+
throw new Error(`EVM wallet did not switch to required chain ${evmTx.chainId}; refusing to submit.`);
|
|
4638
|
+
}
|
|
4639
|
+
}
|
|
4640
|
+
}
|
|
4641
|
+
const txParams = { from, to: core.normalizeEvmAddress(evmTx.to), data: evmTx.data.toLowerCase() };
|
|
4642
|
+
txParams.value = '0x0';
|
|
4643
|
+
// Gas, fee and nonce hints come from the server and are not part of the
|
|
4644
|
+
// governed action. Deliberately omit them: the wallet estimates locally,
|
|
4645
|
+
// preventing a compromised response from forcing an abusive fee/nonce.
|
|
4646
|
+
const txHash = await provider.request({
|
|
4647
|
+
method: 'eth_sendTransaction',
|
|
4648
|
+
params: [txParams],
|
|
4649
|
+
});
|
|
4650
|
+
if (typeof txHash !== 'string' || !/^0x[0-9a-fA-F]{64}$/.test(txHash)) {
|
|
4651
|
+
throw new Error('EVM wallet returned an invalid transaction hash');
|
|
4652
|
+
}
|
|
4653
|
+
const receipt = await this.waitForReceipt(provider, txHash);
|
|
4654
|
+
if (!receipt || typeof receipt.status !== 'string' || !/^0x[0-9a-fA-F]+$/.test(receipt.status)) {
|
|
4655
|
+
throw new Error(`EVM transaction ${txHash} returned an invalid receipt status`);
|
|
4656
|
+
}
|
|
4657
|
+
if (BigInt(receipt.status) !== BigInt(1)) {
|
|
4658
|
+
throw new Error(`EVM transaction ${txHash} reverted on-chain`);
|
|
4659
|
+
}
|
|
4660
|
+
if (typeof receipt.blockNumber !== 'string' || !/^0x[0-9a-fA-F]+$/.test(receipt.blockNumber)) {
|
|
4661
|
+
throw new Error(`EVM transaction ${txHash} returned an invalid block number`);
|
|
4662
|
+
}
|
|
4663
|
+
const blockNumber = BigInt(receipt.blockNumber);
|
|
4664
|
+
if (blockNumber > BigInt(Number.MAX_SAFE_INTEGER))
|
|
4665
|
+
throw new Error('EVM receipt block number exceeds the SDK safe-integer range');
|
|
4666
|
+
if (typeof receipt.gasUsed !== 'string' || !/^0x[0-9a-fA-F]+$/.test(receipt.gasUsed)) {
|
|
4667
|
+
throw new Error(`EVM transaction ${txHash} returned invalid gas usage`);
|
|
4668
|
+
}
|
|
4669
|
+
return {
|
|
4670
|
+
transactionSignature: txHash,
|
|
4671
|
+
blockNumber: Number(blockNumber),
|
|
4672
|
+
gasUsed: BigInt(receipt.gasUsed).toString(),
|
|
4673
|
+
data: receipt,
|
|
4674
|
+
};
|
|
4675
|
+
}
|
|
4676
|
+
/** Poll eth_getTransactionReceipt until it lands (bounded retries) or throw. */
|
|
4677
|
+
async waitForReceipt(provider, txHash) {
|
|
4678
|
+
for (let attempt = 0; attempt < RECEIPT_POLL_ATTEMPTS; attempt++) {
|
|
4679
|
+
const receipt = await provider.request({
|
|
4680
|
+
method: 'eth_getTransactionReceipt',
|
|
4681
|
+
params: [txHash],
|
|
4682
|
+
});
|
|
4683
|
+
if (receipt)
|
|
4684
|
+
return receipt;
|
|
4685
|
+
await new Promise((r) => setTimeout(r, RECEIPT_POLL_INTERVAL_MS));
|
|
4686
|
+
}
|
|
4687
|
+
throw new Error(`EVM transaction ${txHash} was submitted but no receipt confirmed within ` +
|
|
4688
|
+
`${(RECEIPT_POLL_ATTEMPTS * RECEIPT_POLL_INTERVAL_MS) / 1000}s. It may still land; check the explorer.`);
|
|
4689
|
+
}
|
|
4690
|
+
async getNativeMethods() {
|
|
4691
|
+
return this.resolveProvider();
|
|
4692
|
+
}
|
|
4693
|
+
}
|
|
4694
|
+
InjectedEvmWalletProvider.instance = null;
|
|
4695
|
+
|
|
4229
4696
|
// Same message the email provider uses when a hosted (OIDC) login has no
|
|
4230
4697
|
// embedded wallet — enable `auth.wallets` in policy to get one.
|
|
4231
4698
|
const OIDC_NO_WALLET = 'This login has no embedded wallet. Enable `"auth": { "wallets": true }` in ' +
|
|
@@ -4275,6 +4742,17 @@ const oidcProviderSingleton = {
|
|
|
4275
4742
|
async signTransaction(_t) {
|
|
4276
4743
|
throw new Error(hasEmbeddedWallet() ? EMBEDDED_WALLET_UNSUPPORTED : OIDC_NO_WALLET);
|
|
4277
4744
|
},
|
|
4745
|
+
async runTransaction(evm, sol, options) {
|
|
4746
|
+
if (evm && sol)
|
|
4747
|
+
throw new Error('A transaction cannot target EVM and Solana at the same time.');
|
|
4748
|
+
if (!evm)
|
|
4749
|
+
throw new Error(OIDC_NO_WALLET);
|
|
4750
|
+
if ((options === null || options === void 0 ? void 0 : options.shouldSubmitTx) === false)
|
|
4751
|
+
throw new Error('Embedded EVM wallets sign and submit atomically; shouldSubmitTx:false is unsupported.');
|
|
4752
|
+
if (!hasEmbeddedEvmWallet())
|
|
4753
|
+
throw new Error('This login has no embedded EVM wallet. Enable auth.wallets on an app with an EVM collection and sign in again.');
|
|
4754
|
+
return embeddedRunEvmTransaction(evm);
|
|
4755
|
+
},
|
|
4278
4756
|
async signAndSubmitTransaction(transaction, _feePayer) {
|
|
4279
4757
|
if (!hasEmbeddedWallet())
|
|
4280
4758
|
throw new Error(OIDC_NO_WALLET);
|
|
@@ -4286,6 +4764,9 @@ function userFromIdToken(idToken) {
|
|
|
4286
4764
|
const id = c['custom:userId'] || c.sub || c['custom:walletAddress'] || '';
|
|
4287
4765
|
return {
|
|
4288
4766
|
id, address: (c['custom:walletAddress'] || null),
|
|
4767
|
+
evmAddress: typeof c['custom:evmWalletAddress'] === 'string' && /^0x[0-9a-fA-F]{40}$/.test(c['custom:evmWalletAddress'])
|
|
4768
|
+
? c['custom:evmWalletAddress'].toLowerCase()
|
|
4769
|
+
: null,
|
|
4289
4770
|
email: (c.email || null), provider: oidcProviderSingleton,
|
|
4290
4771
|
};
|
|
4291
4772
|
}
|
|
@@ -4789,7 +5270,7 @@ function stableConfigValue(value, seen = new WeakSet()) {
|
|
|
4789
5270
|
return String(value);
|
|
4790
5271
|
}
|
|
4791
5272
|
function authProviderConfigKey(config) {
|
|
4792
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
5273
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
4793
5274
|
return JSON.stringify({
|
|
4794
5275
|
authMethod: (_a = config.authMethod) !== null && _a !== void 0 ? _a : null,
|
|
4795
5276
|
chain: (_b = config.chain) !== null && _b !== void 0 ? _b : null,
|
|
@@ -4799,9 +5280,10 @@ function authProviderConfigKey(config) {
|
|
|
4799
5280
|
phantomConfig: stableConfigValue((_e = config.phantomConfig) !== null && _e !== void 0 ? _e : null),
|
|
4800
5281
|
walletLogin: stableConfigValue((_f = config.walletLogin) !== null && _f !== void 0 ? _f : null),
|
|
4801
5282
|
injectedWalletConfig: stableConfigValue((_g = config.injectedWalletConfig) !== null && _g !== void 0 ? _g : null),
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
5283
|
+
evmWalletConfig: stableConfigValue((_h = config.evmWalletConfig) !== null && _h !== void 0 ? _h : null),
|
|
5284
|
+
privyConfig: stableConfigValue((_j = config.privyConfig) !== null && _j !== void 0 ? _j : null),
|
|
5285
|
+
mobileWalletConfig: stableConfigValue((_k = config.mobileWalletConfig) !== null && _k !== void 0 ? _k : null),
|
|
5286
|
+
privyExpoProvider: objectIdentityKey((_l = config.privyExpoProvider) !== null && _l !== void 0 ? _l : null),
|
|
4805
5287
|
});
|
|
4806
5288
|
}
|
|
4807
5289
|
/**
|
|
@@ -4882,7 +5364,7 @@ function optionalProviderError(method) {
|
|
|
4882
5364
|
`or install/import an explicit wallet-provider entry once your app opts into "${method}".`);
|
|
4883
5365
|
}
|
|
4884
5366
|
async function getAuthProvider(config) {
|
|
4885
|
-
var _a;
|
|
5367
|
+
var _a, _b;
|
|
4886
5368
|
const nextProviderConfigKey = config ? authProviderConfigKey(config) : null;
|
|
4887
5369
|
if (currentAuthProvider && (!config || currentAuthProviderConfigKey === nextProviderConfigKey)) {
|
|
4888
5370
|
return currentAuthProvider;
|
|
@@ -4906,7 +5388,7 @@ async function getAuthProvider(config) {
|
|
|
4906
5388
|
// browser environment" deep in init(). The server build (`bounded-sh/server`)
|
|
4907
5389
|
// never resolves these methods (it signs with a keypair), so this can't fire for
|
|
4908
5390
|
// it — it only converts the cryptic browser-in-Node crash into a useful message.
|
|
4909
|
-
const browserWalletMethods = ['phantom', 'wallet', 'rainbowkit', 'coinbase-smart-wallet', 'onboard', 'mobile-wallet-adapter', 'privy'];
|
|
5391
|
+
const browserWalletMethods = ['phantom', 'wallet', 'evm-wallet', 'rainbowkit', 'coinbase-smart-wallet', 'onboard', 'mobile-wallet-adapter', 'privy'];
|
|
4910
5392
|
if (typeof window === 'undefined' && browserWalletMethods.includes(authMethod)) {
|
|
4911
5393
|
throw new Error(`bounded-sh: '${authMethod}' auth requires a browser, but no \`window\` was found ` +
|
|
4912
5394
|
`(you're likely running in Node). In server/Node code, import from 'bounded-sh/server' ` +
|
|
@@ -4941,6 +5423,18 @@ async function getAuthProvider(config) {
|
|
|
4941
5423
|
currentAuthProvider = new InjectedWalletProvider(resolveInjectedWalletConfig(config), rpcUrl, configuredNetwork);
|
|
4942
5424
|
break;
|
|
4943
5425
|
}
|
|
5426
|
+
case "evm-wallet": {
|
|
5427
|
+
// First-class EVM WALLET LOGIN (BYO Ethereum wallet via SIWE). Slim
|
|
5428
|
+
// path: rides the EIP-1193 injected provider a browser wallet exposes
|
|
5429
|
+
// (MetaMask / Rabby / Coinbase Wallet / any window.ethereum), discovered
|
|
5430
|
+
// via EIP-6963. The user's REAL EVM wallet becomes @user.evmAddress;
|
|
5431
|
+
// login = SIWE (EIP-4361 personal_sign). No viem/ethers and no React.
|
|
5432
|
+
// Selecting authMethod:'evm-wallet' IS the opt-in — pass evmWalletConfig
|
|
5433
|
+
// to point at a specific wallet or set chainId/domain.
|
|
5434
|
+
const evmWalletConfig = ((_b = config.evmWalletConfig) !== null && _b !== void 0 ? _b : {});
|
|
5435
|
+
currentAuthProvider = new InjectedEvmWalletProvider(evmWalletConfig);
|
|
5436
|
+
break;
|
|
5437
|
+
}
|
|
4944
5438
|
case "rainbowkit":
|
|
4945
5439
|
console.warn("Rainbow Kit auth is not yet supported.");
|
|
4946
5440
|
break;
|
|
@@ -5908,6 +6402,7 @@ exports.OffchainAuthProvider = OffchainAuthProvider;
|
|
|
5908
6402
|
exports.PrivyExpoProvider = PrivyExpoProvider;
|
|
5909
6403
|
exports.completeLoginFromRedirect = completeLoginFromRedirect;
|
|
5910
6404
|
exports.completeLoginInPopup = completeLoginInPopup;
|
|
6405
|
+
exports.defaultInjectedEvmProvider = defaultInjectedEvmProvider;
|
|
5911
6406
|
exports.defaultInjectedProvider = defaultInjectedProvider;
|
|
5912
6407
|
exports.deserializeTransaction = deserializeTransaction;
|
|
5913
6408
|
exports.getAuthLoading = getAuthLoading;
|
|
@@ -5923,6 +6418,7 @@ exports.loginWithRedirect = loginWithRedirect;
|
|
|
5923
6418
|
exports.logout = logout;
|
|
5924
6419
|
exports.onAuthLoadingChanged = onAuthLoadingChanged;
|
|
5925
6420
|
exports.onAuthStateChanged = onAuthStateChanged;
|
|
6421
|
+
exports.requestEip6963Providers = requestEip6963Providers;
|
|
5926
6422
|
exports.setPlatform = setPlatform;
|
|
5927
6423
|
exports.signInAnonymously = signInAnonymously;
|
|
5928
6424
|
exports.useAuth = useAuth;
|