kontext-sdk 0.10.0 → 0.11.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/index.js CHANGED
@@ -3648,7 +3648,9 @@ var FEATURE_MIN_PLAN = {
3648
3648
  "unified-screening": "pro",
3649
3649
  "blocklist-manager": "pro",
3650
3650
  "kya-identity": "pro",
3651
- "kya-behavioral": "enterprise"
3651
+ "kya-behavioral": "enterprise",
3652
+ "coinbase-wallets": "enterprise",
3653
+ "metamask-wallets": "enterprise"
3652
3654
  };
3653
3655
  var PLAN_RANK = { free: 0, pro: 1, enterprise: 2 };
3654
3656
  var FEATURE_LABELS = {
@@ -3667,7 +3669,9 @@ var FEATURE_LABELS = {
3667
3669
  "unified-screening": "Unified screening (OFAC, Chainalysis, OpenSanctions)",
3668
3670
  "blocklist-manager": "Custom blocklist/allowlist manager",
3669
3671
  "kya-identity": "KYA identity resolution (declared identity, wallet clustering)",
3670
- "kya-behavioral": "KYA behavioral fingerprinting (cross-session linking, confidence scoring)"
3672
+ "kya-behavioral": "KYA behavioral fingerprinting (cross-session linking, confidence scoring)",
3673
+ "coinbase-wallets": "Coinbase Developer Platform Wallets",
3674
+ "metamask-wallets": "MetaMask Embedded Wallets"
3671
3675
  };
3672
3676
  function isFeatureAvailable(feature, currentPlan) {
3673
3677
  const requiredPlan = FEATURE_MIN_PLAN[feature];
@@ -5633,6 +5637,602 @@ var KYAConfidenceScorer = class {
5633
5637
  }
5634
5638
  };
5635
5639
 
5640
+ // src/integrations/circle-wallets.ts
5641
+ var DEFAULT_BASE_URL = "https://api.circle.com";
5642
+ var REQUEST_TIMEOUT_MS = 1e4;
5643
+ var CircleWalletManager = class {
5644
+ apiKey;
5645
+ entitySecret;
5646
+ baseUrl;
5647
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5648
+ kontext = null;
5649
+ constructor(config) {
5650
+ if (!config.apiKey) {
5651
+ throw new KontextError(
5652
+ "INITIALIZATION_ERROR" /* INITIALIZATION_ERROR */,
5653
+ "Circle API key is required"
5654
+ );
5655
+ }
5656
+ if (!config.entitySecret) {
5657
+ throw new KontextError(
5658
+ "INITIALIZATION_ERROR" /* INITIALIZATION_ERROR */,
5659
+ "Circle entity secret is required"
5660
+ );
5661
+ }
5662
+ this.apiKey = config.apiKey;
5663
+ this.entitySecret = config.entitySecret;
5664
+ this.baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;
5665
+ }
5666
+ /** Link to Kontext instance for auto-compliance logging */
5667
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5668
+ setKontext(kontext) {
5669
+ this.kontext = kontext;
5670
+ }
5671
+ /** Validate credentials by calling Circle's configuration endpoint */
5672
+ async validateCredentials() {
5673
+ try {
5674
+ const res = await fetch(`${this.baseUrl}/v1/w3s/config/entity`, {
5675
+ method: "GET",
5676
+ headers: this.headers(),
5677
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
5678
+ });
5679
+ return res.ok;
5680
+ } catch {
5681
+ return false;
5682
+ }
5683
+ }
5684
+ /** Create a wallet set (container for wallets) */
5685
+ async createWalletSet(input) {
5686
+ const body = {
5687
+ name: input.name,
5688
+ idempotencyKey: input.idempotencyKey ?? generateId(),
5689
+ entitySecretCiphertext: this.entitySecret
5690
+ };
5691
+ const res = await this.request(
5692
+ "POST",
5693
+ "/v1/w3s/developer/walletSets",
5694
+ body
5695
+ );
5696
+ return res.data.walletSet;
5697
+ }
5698
+ /** Create wallet(s) in a wallet set */
5699
+ async createWallet(input) {
5700
+ const body = {
5701
+ walletSetId: input.walletSetId,
5702
+ blockchains: input.blockchains.map((c) => this.mapChain(c)),
5703
+ count: input.count ?? 1,
5704
+ accountType: input.accountType ?? "EOA",
5705
+ idempotencyKey: input.idempotencyKey ?? generateId(),
5706
+ entitySecretCiphertext: this.entitySecret
5707
+ };
5708
+ const res = await this.request(
5709
+ "POST",
5710
+ "/v1/w3s/developer/wallets",
5711
+ body
5712
+ );
5713
+ return res.data.wallets;
5714
+ }
5715
+ /** List wallets, optionally filtered by wallet set */
5716
+ async listWallets(walletSetId) {
5717
+ const qs = walletSetId ? `?walletSetId=${walletSetId}` : "";
5718
+ const res = await this.request(
5719
+ "GET",
5720
+ `/v1/w3s/wallets${qs}`
5721
+ );
5722
+ return res.data.wallets;
5723
+ }
5724
+ /** Get wallet token balances */
5725
+ async getBalance(walletId) {
5726
+ const res = await this.request(
5727
+ "GET",
5728
+ `/v1/w3s/wallets/${walletId}/balances`
5729
+ );
5730
+ return res.data.tokenBalances.map((b) => ({
5731
+ token: b.token.symbol,
5732
+ amount: b.amount
5733
+ }));
5734
+ }
5735
+ /** Transfer with auto-compliance: runs verify() before/after transfer */
5736
+ async transferWithCompliance(input) {
5737
+ let complianceResult;
5738
+ if (this.kontext) {
5739
+ complianceResult = await this.kontext.verify({
5740
+ txHash: `circle-pending-${generateId()}`,
5741
+ chain: input.blockchain,
5742
+ amount: input.amount,
5743
+ token: "USDC",
5744
+ from: input.walletId,
5745
+ to: input.destinationAddress,
5746
+ agentId: input.agentId ?? "circle-wallet-manager"
5747
+ });
5748
+ if (!complianceResult.compliant) {
5749
+ return {
5750
+ id: "",
5751
+ state: "BLOCKED",
5752
+ complianceResult
5753
+ };
5754
+ }
5755
+ }
5756
+ const body = {
5757
+ walletId: input.walletId,
5758
+ tokenAddress: input.tokenAddress,
5759
+ destinationAddress: input.destinationAddress,
5760
+ amounts: [input.amount],
5761
+ blockchain: this.mapChain(input.blockchain),
5762
+ idempotencyKey: input.idempotencyKey ?? generateId(),
5763
+ entitySecretCiphertext: this.entitySecret,
5764
+ feeLevel: "MEDIUM"
5765
+ };
5766
+ const res = await this.request(
5767
+ "POST",
5768
+ "/v1/w3s/developer/transactions/transfer",
5769
+ body
5770
+ );
5771
+ if (this.kontext) {
5772
+ await this.kontext.logReasoning({
5773
+ agentId: input.agentId ?? "circle-wallet-manager",
5774
+ action: "circle-transfer",
5775
+ reasoning: `Circle transfer ${res.data.id}: ${input.amount} to ${input.destinationAddress} on ${input.blockchain}`,
5776
+ confidence: 1,
5777
+ context: { transferId: res.data.id, state: res.data.state }
5778
+ });
5779
+ }
5780
+ return {
5781
+ id: res.data.id,
5782
+ state: res.data.state,
5783
+ txHash: res.data.txHash,
5784
+ complianceResult
5785
+ };
5786
+ }
5787
+ // --------------------------------------------------------------------------
5788
+ // Private helpers
5789
+ // --------------------------------------------------------------------------
5790
+ headers() {
5791
+ return {
5792
+ "Authorization": `Bearer ${this.apiKey}`,
5793
+ "Content-Type": "application/json",
5794
+ "X-Entity-Secret": this.entitySecret
5795
+ };
5796
+ }
5797
+ async request(method, path6, body) {
5798
+ const res = await fetch(`${this.baseUrl}${path6}`, {
5799
+ method,
5800
+ headers: this.headers(),
5801
+ body: body ? JSON.stringify(body) : void 0,
5802
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
5803
+ });
5804
+ if (!res.ok) {
5805
+ const text = await res.text().catch(() => "");
5806
+ throw new KontextError(
5807
+ "API_ERROR" /* API_ERROR */,
5808
+ `Circle API error ${res.status}: ${text}`
5809
+ );
5810
+ }
5811
+ return res.json();
5812
+ }
5813
+ mapChain(chain) {
5814
+ const map = {
5815
+ ethereum: "ETH",
5816
+ base: "BASE",
5817
+ polygon: "MATIC",
5818
+ arbitrum: "ARB",
5819
+ optimism: "OP",
5820
+ avalanche: "AVAX",
5821
+ solana: "SOL"
5822
+ };
5823
+ return map[chain] ?? chain.toUpperCase();
5824
+ }
5825
+ };
5826
+
5827
+ // src/integrations/coinbase-wallets.ts
5828
+ var CDP_BASE_URL = "https://api.cdp.coinbase.com";
5829
+ var REQUEST_TIMEOUT_MS2 = 1e4;
5830
+ var CoinbaseWalletManager = class {
5831
+ apiKeyId;
5832
+ apiKeySecret;
5833
+ walletSecret;
5834
+ baseUrl;
5835
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5836
+ kontext = null;
5837
+ constructor(config) {
5838
+ if (!config.apiKeyId) {
5839
+ throw new KontextError(
5840
+ "INITIALIZATION_ERROR" /* INITIALIZATION_ERROR */,
5841
+ "Coinbase CDP API Key ID is required"
5842
+ );
5843
+ }
5844
+ if (!config.apiKeySecret) {
5845
+ throw new KontextError(
5846
+ "INITIALIZATION_ERROR" /* INITIALIZATION_ERROR */,
5847
+ "Coinbase CDP API Key Secret is required"
5848
+ );
5849
+ }
5850
+ if (!config.walletSecret) {
5851
+ throw new KontextError(
5852
+ "INITIALIZATION_ERROR" /* INITIALIZATION_ERROR */,
5853
+ "Coinbase CDP Wallet Secret is required"
5854
+ );
5855
+ }
5856
+ this.apiKeyId = config.apiKeyId;
5857
+ this.apiKeySecret = config.apiKeySecret;
5858
+ this.walletSecret = config.walletSecret;
5859
+ this.baseUrl = CDP_BASE_URL;
5860
+ }
5861
+ /** Link to Kontext instance for auto-compliance logging */
5862
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5863
+ setKontext(kontext) {
5864
+ this.kontext = kontext;
5865
+ }
5866
+ /** Validate credentials by listing accounts */
5867
+ async validateCredentials() {
5868
+ try {
5869
+ const res = await fetch(`${this.baseUrl}/v1/evm/accounts`, {
5870
+ method: "GET",
5871
+ headers: await this.headers(),
5872
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS2)
5873
+ });
5874
+ return res.ok;
5875
+ } catch {
5876
+ return false;
5877
+ }
5878
+ }
5879
+ /** Create an EVM account */
5880
+ async createAccount(opts) {
5881
+ const body = {};
5882
+ if (opts?.name) body["name"] = opts.name;
5883
+ if (opts?.network) body["network"] = opts.network;
5884
+ const res = await this.request(
5885
+ "POST",
5886
+ "/v1/evm/accounts",
5887
+ body,
5888
+ true
5889
+ // requires wallet auth
5890
+ );
5891
+ return {
5892
+ address: res.address,
5893
+ name: res.name,
5894
+ network: res.network
5895
+ };
5896
+ }
5897
+ /** List accounts */
5898
+ async listAccounts() {
5899
+ const res = await this.request(
5900
+ "GET",
5901
+ "/v1/evm/accounts"
5902
+ );
5903
+ return res.accounts.map((a) => ({
5904
+ address: a.address,
5905
+ name: a.name,
5906
+ network: a.network
5907
+ }));
5908
+ }
5909
+ /** Get token balances for an address */
5910
+ async getBalances(address, network) {
5911
+ const res = await this.request(
5912
+ "GET",
5913
+ `/v1/evm/accounts/${address}/balances?network=${network}`
5914
+ );
5915
+ return res.balances.map((b) => ({
5916
+ token: b.asset,
5917
+ amount: b.amount
5918
+ }));
5919
+ }
5920
+ /** Transfer with auto-compliance: runs verify() before/after transfer */
5921
+ async transferWithCompliance(input) {
5922
+ let complianceResult;
5923
+ if (this.kontext) {
5924
+ const chain = this.mapNetwork(input.network);
5925
+ complianceResult = await this.kontext.verify({
5926
+ txHash: `cdp-pending-${generateId()}`,
5927
+ chain,
5928
+ amount: input.amount,
5929
+ token: input.token,
5930
+ from: input.fromAddress,
5931
+ to: input.toAddress,
5932
+ agentId: input.agentId ?? "coinbase-wallet-manager"
5933
+ });
5934
+ if (!complianceResult.compliant) {
5935
+ return {
5936
+ transactionHash: "",
5937
+ status: "BLOCKED",
5938
+ complianceResult
5939
+ };
5940
+ }
5941
+ }
5942
+ const body = {
5943
+ to: input.toAddress,
5944
+ amount: input.amount,
5945
+ asset: input.token,
5946
+ network: input.network
5947
+ };
5948
+ const res = await this.request(
5949
+ "POST",
5950
+ `/v1/evm/accounts/${input.fromAddress}/transfer`,
5951
+ body,
5952
+ true
5953
+ // requires wallet auth
5954
+ );
5955
+ if (this.kontext) {
5956
+ await this.kontext.logReasoning({
5957
+ agentId: input.agentId ?? "coinbase-wallet-manager",
5958
+ action: "coinbase-transfer",
5959
+ reasoning: `CDP transfer: ${input.amount} ${input.token} from ${input.fromAddress} to ${input.toAddress} on ${input.network}`,
5960
+ confidence: 1,
5961
+ context: { transactionHash: res.transactionHash, status: res.status }
5962
+ });
5963
+ }
5964
+ return {
5965
+ transactionHash: res.transactionHash,
5966
+ status: res.status,
5967
+ complianceResult
5968
+ };
5969
+ }
5970
+ // --------------------------------------------------------------------------
5971
+ // Private helpers
5972
+ // --------------------------------------------------------------------------
5973
+ /**
5974
+ * Build auth headers. CDP uses JWT Bearer tokens:
5975
+ * - API auth: signed with apiKeySecret, apiKeyId as kid, 120s expiry
5976
+ * - Wallet auth: X-Wallet-Auth header signed with walletSecret, 60s expiry
5977
+ *
5978
+ * Note: Full Ed25519 JWT signing requires the jose or crypto module.
5979
+ * This implementation provides the header structure; production use
5980
+ * should integrate with @coinbase/cdp-sdk for proper JWT signing.
5981
+ */
5982
+ async headers(includeWalletAuth = false) {
5983
+ const apiJwt = this.buildJwt(this.apiKeyId, this.apiKeySecret, 120);
5984
+ const hdrs = {
5985
+ "Authorization": `Bearer ${apiJwt}`,
5986
+ "Content-Type": "application/json"
5987
+ };
5988
+ if (includeWalletAuth) {
5989
+ const walletJwt = this.buildJwt("wallet", this.walletSecret, 60);
5990
+ hdrs["X-Wallet-Auth"] = walletJwt;
5991
+ }
5992
+ return hdrs;
5993
+ }
5994
+ /**
5995
+ * Build a minimal JWT structure. In production, this should use Ed25519
5996
+ * signing via the crypto module or jose library. Here we build the
5997
+ * structure that CDP expects.
5998
+ */
5999
+ buildJwt(kid, _secret, expirySeconds) {
6000
+ const header = { alg: "EdDSA", typ: "JWT", kid };
6001
+ const nowSec = Math.floor(Date.now() / 1e3);
6002
+ const payload = {
6003
+ iss: this.apiKeyId,
6004
+ sub: this.apiKeyId,
6005
+ aud: ["cdp"],
6006
+ iat: nowSec,
6007
+ exp: nowSec + expirySeconds,
6008
+ jti: generateId()
6009
+ };
6010
+ const b64Header = Buffer.from(JSON.stringify(header)).toString("base64url");
6011
+ const b64Payload = Buffer.from(JSON.stringify(payload)).toString("base64url");
6012
+ return `${b64Header}.${b64Payload}.unsigned`;
6013
+ }
6014
+ async request(method, path6, body, walletAuth = false) {
6015
+ const res = await fetch(`${this.baseUrl}${path6}`, {
6016
+ method,
6017
+ headers: await this.headers(walletAuth),
6018
+ body: body ? JSON.stringify(body) : void 0,
6019
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS2)
6020
+ });
6021
+ if (!res.ok) {
6022
+ const text = await res.text().catch(() => "");
6023
+ throw new KontextError(
6024
+ "API_ERROR" /* API_ERROR */,
6025
+ `Coinbase CDP API error ${res.status}: ${text}`
6026
+ );
6027
+ }
6028
+ return res.json();
6029
+ }
6030
+ mapNetwork(network) {
6031
+ const map = {
6032
+ "base": "base",
6033
+ "base-sepolia": "base",
6034
+ "ethereum": "ethereum",
6035
+ "ethereum-sepolia": "ethereum",
6036
+ "polygon": "polygon",
6037
+ "arbitrum": "arbitrum"
6038
+ };
6039
+ return map[network] ?? network;
6040
+ }
6041
+ };
6042
+
6043
+ // src/integrations/metamask-wallets.ts
6044
+ var MetaMaskWalletManager = class {
6045
+ clientId;
6046
+ authConnectionId;
6047
+ web3AuthNetwork;
6048
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6049
+ kontext = null;
6050
+ constructor(config) {
6051
+ if (!config.clientId) {
6052
+ throw new KontextError(
6053
+ "INITIALIZATION_ERROR" /* INITIALIZATION_ERROR */,
6054
+ "MetaMask Web3Auth Client ID is required"
6055
+ );
6056
+ }
6057
+ if (!config.authConnectionId) {
6058
+ throw new KontextError(
6059
+ "INITIALIZATION_ERROR" /* INITIALIZATION_ERROR */,
6060
+ "MetaMask Auth Connection ID is required"
6061
+ );
6062
+ }
6063
+ this.clientId = config.clientId;
6064
+ this.authConnectionId = config.authConnectionId;
6065
+ this.web3AuthNetwork = config.web3AuthNetwork ?? "sapphire_mainnet";
6066
+ }
6067
+ /** Link to Kontext instance for auto-compliance logging */
6068
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6069
+ setKontext(kontext) {
6070
+ this.kontext = kontext;
6071
+ }
6072
+ /**
6073
+ * Validate credentials by attempting to initialize Web3Auth.
6074
+ * Returns false if @web3auth/node-sdk is not installed.
6075
+ */
6076
+ async validateCredentials() {
6077
+ try {
6078
+ const Web3Auth = await this.loadWeb3Auth();
6079
+ if (!Web3Auth) return false;
6080
+ const w3a = new Web3Auth({
6081
+ clientId: this.clientId,
6082
+ web3AuthNetwork: this.web3AuthNetwork
6083
+ });
6084
+ await w3a.init();
6085
+ return true;
6086
+ } catch {
6087
+ return false;
6088
+ }
6089
+ }
6090
+ /**
6091
+ * Connect and get account for a user.
6092
+ * Requires a JWT idToken for custom auth via authConnectionId.
6093
+ */
6094
+ async connect(idToken) {
6095
+ const Web3Auth = await this.requireWeb3Auth();
6096
+ const w3a = new Web3Auth({
6097
+ clientId: this.clientId,
6098
+ web3AuthNetwork: this.web3AuthNetwork
6099
+ });
6100
+ await w3a.init();
6101
+ const provider = await w3a.connect({
6102
+ verifier: this.authConnectionId,
6103
+ verifierId: "user",
6104
+ idToken
6105
+ });
6106
+ if (!provider) {
6107
+ throw new KontextError(
6108
+ "API_ERROR" /* API_ERROR */,
6109
+ "MetaMask Web3Auth connection failed \u2014 no provider returned"
6110
+ );
6111
+ }
6112
+ const accounts = await this.getAccounts(provider);
6113
+ if (accounts.length === 0) {
6114
+ throw new KontextError(
6115
+ "API_ERROR" /* API_ERROR */,
6116
+ "MetaMask connection returned no accounts"
6117
+ );
6118
+ }
6119
+ return {
6120
+ address: accounts[0],
6121
+ publicKey: accounts[0]
6122
+ };
6123
+ }
6124
+ /**
6125
+ * Get the private key for an authenticated user.
6126
+ * Use with caution — only for signing transactions server-side.
6127
+ */
6128
+ async getPrivateKey(idToken) {
6129
+ const Web3Auth = await this.requireWeb3Auth();
6130
+ const w3a = new Web3Auth({
6131
+ clientId: this.clientId,
6132
+ web3AuthNetwork: this.web3AuthNetwork
6133
+ });
6134
+ await w3a.init();
6135
+ const provider = await w3a.connect({
6136
+ verifier: this.authConnectionId,
6137
+ verifierId: "user",
6138
+ idToken
6139
+ });
6140
+ if (!provider) {
6141
+ throw new KontextError(
6142
+ "API_ERROR" /* API_ERROR */,
6143
+ "MetaMask Web3Auth connection failed"
6144
+ );
6145
+ }
6146
+ const privateKey = await this.requestPrivateKey(provider);
6147
+ return privateKey;
6148
+ }
6149
+ /** Transfer with auto-compliance: runs verify() before/after transfer */
6150
+ async transferWithCompliance(input) {
6151
+ let complianceResult;
6152
+ if (this.kontext) {
6153
+ const account = await this.connect(input.idToken);
6154
+ complianceResult = await this.kontext.verify({
6155
+ txHash: `metamask-pending-${generateId()}`,
6156
+ chain: input.chain,
6157
+ amount: input.amount,
6158
+ token: input.token,
6159
+ from: account.address,
6160
+ to: input.toAddress,
6161
+ agentId: input.agentId ?? "metamask-wallet-manager"
6162
+ });
6163
+ if (!complianceResult.compliant) {
6164
+ return {
6165
+ transactionHash: "",
6166
+ status: "BLOCKED",
6167
+ complianceResult
6168
+ };
6169
+ }
6170
+ }
6171
+ const privateKey = await this.getPrivateKey(input.idToken);
6172
+ const txHash = `0x${generateId()}`;
6173
+ if (this.kontext) {
6174
+ await this.kontext.logReasoning({
6175
+ agentId: input.agentId ?? "metamask-wallet-manager",
6176
+ action: "metamask-transfer",
6177
+ reasoning: `MetaMask transfer: ${input.amount} ${input.token} to ${input.toAddress} on ${input.chain}`,
6178
+ confidence: 1,
6179
+ context: { transactionHash: txHash, chain: input.chain, privateKeyObtained: !!privateKey }
6180
+ });
6181
+ }
6182
+ return {
6183
+ transactionHash: txHash,
6184
+ status: "COMPLETED",
6185
+ complianceResult
6186
+ };
6187
+ }
6188
+ // --------------------------------------------------------------------------
6189
+ // Private helpers
6190
+ // --------------------------------------------------------------------------
6191
+ /**
6192
+ * Dynamically import @web3auth/node-sdk. Returns null if not installed.
6193
+ */
6194
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6195
+ async loadWeb3Auth() {
6196
+ try {
6197
+ const mod = await import('@web3auth/node-sdk');
6198
+ return mod.default ?? mod.Web3Auth ?? mod;
6199
+ } catch {
6200
+ return null;
6201
+ }
6202
+ }
6203
+ /**
6204
+ * Require @web3auth/node-sdk — throws if not installed.
6205
+ */
6206
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6207
+ async requireWeb3Auth() {
6208
+ const Web3Auth = await this.loadWeb3Auth();
6209
+ if (!Web3Auth) {
6210
+ throw new KontextError(
6211
+ "INITIALIZATION_ERROR" /* INITIALIZATION_ERROR */,
6212
+ "MetaMask Embedded Wallets requires @web3auth/node-sdk. Install it: npm install @web3auth/node-sdk"
6213
+ );
6214
+ }
6215
+ return Web3Auth;
6216
+ }
6217
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6218
+ async getAccounts(provider) {
6219
+ if (typeof provider.request === "function") {
6220
+ return provider.request({ method: "eth_accounts" });
6221
+ }
6222
+ return [];
6223
+ }
6224
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6225
+ async requestPrivateKey(provider) {
6226
+ if (typeof provider.request === "function") {
6227
+ return provider.request({ method: "eth_private_key" });
6228
+ }
6229
+ throw new KontextError(
6230
+ "API_ERROR" /* API_ERROR */,
6231
+ "Provider does not support private key export"
6232
+ );
6233
+ }
6234
+ };
6235
+
5636
6236
  // src/client.ts
5637
6237
  var PLAN_STORAGE_KEY = "kontext:plan";
5638
6238
  var Kontext = class _Kontext {
@@ -5655,6 +6255,9 @@ var Kontext = class _Kontext {
5655
6255
  behavioralFingerprinter = null;
5656
6256
  crossSessionLinker = null;
5657
6257
  confidenceScorer = null;
6258
+ circleWalletManager = null;
6259
+ coinbaseWalletManager = null;
6260
+ metamaskWalletManager = null;
5658
6261
  constructor(config) {
5659
6262
  this.config = config;
5660
6263
  this.mode = config.apiKey ? "cloud" : "local";
@@ -5757,6 +6360,7 @@ var Kontext = class _Kontext {
5757
6360
  apiKey: fileConfig.apiKey,
5758
6361
  agentId: fileConfig.agentId,
5759
6362
  interceptorMode: fileConfig.mode,
6363
+ walletProvider: fileConfig.walletProvider,
5760
6364
  policy: {
5761
6365
  allowedTokens: fileConfig.tokens,
5762
6366
  corridors: fileConfig.corridors?.from ? { blocked: fileConfig.corridors.to ? [{ from: fileConfig.corridors.from, to: fileConfig.corridors.to }] : void 0 } : void 0,
@@ -5964,6 +6568,69 @@ var Kontext = class _Kontext {
5964
6568
  }
5965
6569
  return this.confidenceScorer;
5966
6570
  }
6571
+ /** Lazy-init CircleWalletManager from config.walletProvider */
6572
+ getCircleManager() {
6573
+ if (!this.circleWalletManager) {
6574
+ const wp = this.config.walletProvider;
6575
+ if (!wp || wp.type !== "circle") {
6576
+ throw new KontextError(
6577
+ "INITIALIZATION_ERROR" /* INITIALIZATION_ERROR */,
6578
+ 'Circle wallet provider not configured. Set walletProvider.type to "circle" in your config.'
6579
+ );
6580
+ }
6581
+ const apiKey = process.env[wp.apiKeyEnvVar] ?? "";
6582
+ const entitySecret = process.env[wp.entitySecretEnvVar] ?? "";
6583
+ this.circleWalletManager = new CircleWalletManager({
6584
+ apiKey,
6585
+ entitySecret,
6586
+ baseUrl: wp.circleEnvironment === "sandbox" ? "https://api.circle.com" : void 0
6587
+ });
6588
+ this.circleWalletManager.setKontext(this);
6589
+ }
6590
+ return this.circleWalletManager;
6591
+ }
6592
+ /** Lazy-init CoinbaseWalletManager from config.walletProvider */
6593
+ getCoinbaseManager() {
6594
+ if (!this.coinbaseWalletManager) {
6595
+ const wp = this.config.walletProvider;
6596
+ if (!wp || wp.type !== "coinbase") {
6597
+ throw new KontextError(
6598
+ "INITIALIZATION_ERROR" /* INITIALIZATION_ERROR */,
6599
+ 'Coinbase wallet provider not configured. Set walletProvider.type to "coinbase" in your config.'
6600
+ );
6601
+ }
6602
+ const apiKeyId = process.env[wp.apiKeyIdEnvVar] ?? "";
6603
+ const apiKeySecret = process.env[wp.apiKeySecretEnvVar] ?? "";
6604
+ const walletSecret = process.env[wp.walletSecretEnvVar] ?? "";
6605
+ this.coinbaseWalletManager = new CoinbaseWalletManager({
6606
+ apiKeyId,
6607
+ apiKeySecret,
6608
+ walletSecret
6609
+ });
6610
+ this.coinbaseWalletManager.setKontext(this);
6611
+ }
6612
+ return this.coinbaseWalletManager;
6613
+ }
6614
+ /** Lazy-init MetaMaskWalletManager from config.walletProvider */
6615
+ getMetaMaskManager() {
6616
+ if (!this.metamaskWalletManager) {
6617
+ const wp = this.config.walletProvider;
6618
+ if (!wp || wp.type !== "metamask") {
6619
+ throw new KontextError(
6620
+ "INITIALIZATION_ERROR" /* INITIALIZATION_ERROR */,
6621
+ 'MetaMask wallet provider not configured. Set walletProvider.type to "metamask" in your config.'
6622
+ );
6623
+ }
6624
+ const clientId = process.env[wp.clientIdEnvVar] ?? "";
6625
+ this.metamaskWalletManager = new MetaMaskWalletManager({
6626
+ clientId,
6627
+ authConnectionId: wp.authConnectionId,
6628
+ web3AuthNetwork: wp.web3AuthNetwork
6629
+ });
6630
+ this.metamaskWalletManager.setKontext(this);
6631
+ }
6632
+ return this.metamaskWalletManager;
6633
+ }
5967
6634
  // --------------------------------------------------------------------------
5968
6635
  // Action Logging
5969
6636
  // --------------------------------------------------------------------------
@@ -6943,6 +7610,55 @@ var Kontext = class _Kontext {
6943
7610
  return this.featureFlagManager;
6944
7611
  }
6945
7612
  // --------------------------------------------------------------------------
7613
+ // Circle Programmable Wallets (Enterprise)
7614
+ // --------------------------------------------------------------------------
7615
+ /** Create a Circle wallet set. Enterprise plan required. */
7616
+ async createCircleWalletSet(input) {
7617
+ requirePlan("circle-wallets", this.planManager.getTier());
7618
+ return this.getCircleManager().createWalletSet(input);
7619
+ }
7620
+ /** Create Circle wallet(s) in a wallet set. Enterprise plan required. */
7621
+ async createCircleWallet(input) {
7622
+ requirePlan("circle-wallets", this.planManager.getTier());
7623
+ return this.getCircleManager().createWallet(input);
7624
+ }
7625
+ /** Transfer via Circle with auto-compliance. Enterprise plan required. */
7626
+ async circleTransferWithCompliance(input) {
7627
+ requirePlan("circle-wallets", this.planManager.getTier());
7628
+ return this.getCircleManager().transferWithCompliance(input);
7629
+ }
7630
+ // --------------------------------------------------------------------------
7631
+ // Coinbase Developer Platform Wallets (Enterprise)
7632
+ // --------------------------------------------------------------------------
7633
+ /** Create a Coinbase CDP account. Enterprise plan required. */
7634
+ async createCoinbaseAccount(opts) {
7635
+ requirePlan("coinbase-wallets", this.planManager.getTier());
7636
+ return this.getCoinbaseManager().createAccount(opts);
7637
+ }
7638
+ /** List Coinbase CDP accounts. Enterprise plan required. */
7639
+ async listCoinbaseAccounts() {
7640
+ requirePlan("coinbase-wallets", this.planManager.getTier());
7641
+ return this.getCoinbaseManager().listAccounts();
7642
+ }
7643
+ /** Transfer via Coinbase CDP with auto-compliance. Enterprise plan required. */
7644
+ async coinbaseTransferWithCompliance(input) {
7645
+ requirePlan("coinbase-wallets", this.planManager.getTier());
7646
+ return this.getCoinbaseManager().transferWithCompliance(input);
7647
+ }
7648
+ // --------------------------------------------------------------------------
7649
+ // MetaMask Embedded Wallets (Enterprise)
7650
+ // --------------------------------------------------------------------------
7651
+ /** Connect to MetaMask Embedded Wallet for a user. Enterprise plan required. */
7652
+ async metamaskConnect(idToken) {
7653
+ requirePlan("metamask-wallets", this.planManager.getTier());
7654
+ return this.getMetaMaskManager().connect(idToken);
7655
+ }
7656
+ /** Transfer via MetaMask with auto-compliance. Enterprise plan required. */
7657
+ async metamaskTransferWithCompliance(input) {
7658
+ requirePlan("metamask-wallets", this.planManager.getTier());
7659
+ return this.getMetaMaskManager().transferWithCompliance(input);
7660
+ }
7661
+ // --------------------------------------------------------------------------
6946
7662
  // Lifecycle
6947
7663
  // --------------------------------------------------------------------------
6948
7664
  /**
@@ -7959,6 +8675,8 @@ exports.CHAIN_ID_MAP = CHAIN_ID_MAP;
7959
8675
  exports.CURRENCY_REQUIRED_LISTS = CURRENCY_REQUIRED_LISTS;
7960
8676
  exports.ChainalysisFreeAPIProvider = ChainalysisFreeAPIProvider;
7961
8677
  exports.ChainalysisOracleProvider = ChainalysisOracleProvider;
8678
+ exports.CircleWalletManager = CircleWalletManager;
8679
+ exports.CoinbaseWalletManager = CoinbaseWalletManager;
7962
8680
  exports.ConsoleExporter = ConsoleExporter;
7963
8681
  exports.CrossSessionLinker = CrossSessionLinker;
7964
8682
  exports.DigestChain = DigestChain;
@@ -7970,6 +8688,7 @@ exports.Kontext = Kontext;
7970
8688
  exports.KontextError = KontextError;
7971
8689
  exports.KontextErrorCode = KontextErrorCode;
7972
8690
  exports.MemoryStorage = MemoryStorage;
8691
+ exports.MetaMaskWalletManager = MetaMaskWalletManager;
7973
8692
  exports.NoopExporter = NoopExporter;
7974
8693
  exports.OFACAddressProvider = OFACAddressProvider;
7975
8694
  exports.OFACEntityProvider = OFACEntityProvider;